There now exists a dummy delete entry in the bulk editors context menu. It is also...
[taxeditor.git] / taxeditor-bulkeditor / src / main / java / eu / etaxonomy / taxeditor / bulkeditor / BulkEditor.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.bulkeditor;
12
13 import org.eclipse.jface.action.IMenuManager;
14 import org.eclipse.jface.dialogs.MessageDialog;
15 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
16 import org.eclipse.jface.preference.IPreferenceStore;
17 import org.eclipse.jface.text.IDocument;
18 import org.eclipse.jface.text.source.Annotation;
19 import org.eclipse.jface.text.source.AnnotationModel;
20 import org.eclipse.jface.text.source.ISourceViewer;
21 import org.eclipse.jface.text.source.IVerticalRuler;
22 import org.eclipse.jface.util.IPropertyChangeListener;
23 import org.eclipse.jface.window.Window;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.custom.StyledText;
26 import org.eclipse.swt.events.MouseAdapter;
27 import org.eclipse.swt.events.MouseEvent;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Control;
32 import org.eclipse.ui.IEditorInput;
33 import org.eclipse.ui.IEditorSite;
34 import org.eclipse.ui.PartInitException;
35 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
36
37 import eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineDocumentProvider;
38 import eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor;
39 import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation;
40 import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotationModel;
41 import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
42 import eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider;
43 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
44 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
45 import eu.etaxonomy.taxeditor.store.CdmStore;
46
47 /**
48 * <p>BulkEditor class.</p>
49 *
50 * @author p.ciardelli
51 * @created 07.07.2009
52 * @version 1.0
53 */
54 public class BulkEditor extends AnnotatedLineEditor implements IPartContentHasDetails, IDirtyMarkableSelectionProvider{
55
56 /** Constant <code>ID="bulkeditor.editor"</code> */
57 public static final String ID = "bulkeditor.editor";
58
59 private boolean isInitialFocus = true;
60
61 private BulkEditorSearch searchBar = null;
62
63 private IPropertyChangeListener markerPreferenceListener;
64
65 /**
66 * <p>Constructor for BulkEditor.</p>
67 */
68 public BulkEditor() {
69 super(CdmStore.createConversation());
70 }
71
72 /* (non-Javadoc)
73 * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
74 */
75 /** {@inheritDoc} */
76 @Override
77 protected void initializeEditor() {
78 super.initializeEditor();
79
80 /**
81 * see AbstractTextEditor javadoc for explanation of context menu ids
82 */
83 setEditorContextMenuId("#BulkEditorContext");
84
85 // setEntityCreatorService(new BulkEditorEntityCreatorService());
86
87 setLineDisplayStrategy(new BulkEditorLineDisplay(this));
88
89 setSourceViewerConfiguration(new BulkEditorViewerConfiguration(lineDisplayStrategy));
90 }
91
92 /* (non-Javadoc)
93 * @see eu.etaxonomy.taxeditor.bulkeditor.ListEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
94 */
95 /** {@inheritDoc} */
96 protected ISourceViewer createSourceViewer(Composite parent,
97 IVerticalRuler ruler, int styles) {
98 ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
99 if (((AbstractBulkEditorInput) getEditorInput()).isMergingEnabled()) {
100 addToggleMergeCandidateListener(ruler.getControl());
101 }
102 return viewer;
103 }
104
105 /* (non-Javadoc)
106 * @see eu.etaxonomy.taxeditor.bulkeditor.AnnotatedLineEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
107 */
108 /** {@inheritDoc} */
109 @Override
110 public void init(IEditorSite site, IEditorInput input)
111 throws PartInitException {
112
113 if (!(input instanceof AbstractBulkEditorInput)) {
114 throw new PartInitException("Invalid Input: Must be BulkEditorInput");
115 }
116
117 super.init(site, input);
118 }
119
120 /* (non-Javadoc)
121 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
122 */
123 /** {@inheritDoc} */
124 @Override
125 public void createPartControl(Composite parent) {
126
127 parent.setLayout(new GridLayout());
128
129 Composite layoutComposite = new Composite(parent, SWT.NONE);
130 layoutComposite.setLayout(new GridLayout());
131
132 GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
133 layoutComposite.setLayoutData(gridData);
134
135 // layoutComposite.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
136
137
138 searchBar = new BulkEditorSearch(this, layoutComposite, SWT.NONE);
139 // layoutComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
140
141 super.createPartControl(parent);
142
143 // Set viewer composite to fill grid. Unfortunately it is private and we have to do a little hack here.
144 for (Control control : parent.getChildren()) {
145 if (control instanceof Composite &&
146 !(control.equals(layoutComposite))) {
147 control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
148 }
149 }
150 }
151
152 /* (non-Javadoc)
153 * @see org.eclipse.ui.editors.text.TextEditor#dispose()
154 */
155 /** {@inheritDoc} */
156 @Override
157 public void dispose() {
158 if (markerPreferenceListener != null ) {
159 PreferencesUtil.getPreferenceStore().removePropertyChangeListener(markerPreferenceListener);
160 }
161 super.dispose();
162 }
163
164 /* (non-Javadoc)
165 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isEditable()
166 */
167 /** {@inheritDoc} */
168 @Override
169 public boolean isEditable() {
170 return false;
171 }
172
173 /* (non-Javadoc)
174 * @see eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor#setFocus()
175 */
176 /** {@inheritDoc} */
177 @Override
178 public void setFocus() {
179 searchBar.setFocus();
180
181 // TODO find a better place to put this - this dialog should be shown after initial contents of
182 // Editor are displayed
183 if (isInitialFocus) {
184 displayWarningDialog();
185 isInitialFocus = false;
186 }
187 }
188
189 /**
190 *
191 */
192 private void displayWarningDialog() {
193 IPreferenceStore prefs = PreferencesUtil.getPreferenceStore();
194 if (!prefs.getBoolean(PreferencesUtil.HIDE_BULKEDITOR_INFO)) {
195 String msg = "The Bulk Editor allows you to edit objects used to reference other objects, such as names, references, and authors.\n\n" +
196 "Any changes you make to an object in the Bulk Editor will be displayed wherever the object is used.\n\n" +
197 "For instance, a reference may be displayed with both a name and a descriptive element. If the reference name is changed here, the display of both the name and the descriptive element will be affected.";
198 MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm
199 (getSite().getShell(), "Bulk Editor", msg, "Do not show this message again",
200 false, null, PreferencesUtil.HIDE_BULKEDITOR_INFO);
201 if (dialog.getReturnCode() == Window.OK) {
202 prefs.setValue(PreferencesUtil.HIDE_BULKEDITOR_INFO, dialog.getToggleState());
203 }
204 }
205 }
206
207 /**
208 * @param control
209 */
210 private void addToggleMergeCandidateListener(Control control) {
211 control.addMouseListener(new MouseAdapter() {
212 @Override
213 public void mouseDoubleClick(MouseEvent e) {
214 StyledText textWidget = getSourceViewer().getTextWidget();
215 int line = textWidget.getLineIndex(e.y);
216 toggleMergeCandidateAnnotation(line);
217 }
218 });
219 }
220
221 /**
222 * <p>toggleMergeCandidateAnnotation</p>
223 *
224 * @param line a int.
225 */
226 public void toggleMergeCandidateAnnotation(int line) {
227
228 IDocument document = getSourceViewer().getDocument();
229 LineAnnotationModel model =
230 (LineAnnotationModel) getSourceViewer().getAnnotationModel();
231
232 if(model != null){
233 Annotation annotation = model.getAnnotationAtLine(line, document);
234
235 if (annotation != null) {
236 if (annotation.getType().equals(IBulkEditorConstants.TYPE_MERGE_CANDIDATE)) {
237 model.changeAnnotationType(
238 annotation, LineAnnotation.TYPE_GENERIC);
239 } else {
240 model.changeAnnotationType(
241 annotation, IBulkEditorConstants.TYPE_MERGE_CANDIDATE);
242 }
243 }
244 }
245 }
246
247 /** {@inheritDoc} */
248 public void changed(Object object) {
249 // this.dirty = dirty;
250 AnnotatedLineDocumentProvider p = (AnnotatedLineDocumentProvider) getDocumentProvider();
251 p.changed(object);
252 // firePropertyChange(PROP_DIRTY);
253 }
254
255 /* (non-Javadoc)
256 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
257 */
258 /** {@inheritDoc} */
259 public void performSearch(BulkEditorQuery query) {
260 if (query != null) {
261
262 // TODO check if dirty, prompt save
263 if (isDirty()) {
264 boolean proceed = MessageDialog.openQuestion(getEditorSite().getShell(),
265 "Save changes", "You have made changes that must be saved before this query can be executed. Would you like to proceed?");
266 if (proceed) {
267 doSave(null);
268 } else {
269 return;
270 }
271 }
272
273 getEditorInput().performSearch(query);
274
275 refresh();
276 }
277 }
278
279 /**
280 *
281 */
282 public void refresh() {
283 if(getDocumentProvider().getAnnotationModel(getEditorInput()) != null){
284 ((AnnotationModel) getDocumentProvider().getAnnotationModel(getEditorInput())).removeAllAnnotations();
285 }
286
287 setInput(getEditorInput());
288 }
289
290 /** {@inheritDoc} */
291 @Override
292 public AbstractBulkEditorInput getEditorInput() {
293 return (AbstractBulkEditorInput) super.getEditorInput();
294 }
295
296 protected void editorContextMenuAboutToShow(IMenuManager menu) {
297 super.editorContextMenuAboutToShow(menu);
298 menu.remove(ITextEditorActionConstants.SHIFT_RIGHT);
299 menu.remove(ITextEditorActionConstants.SHIFT_LEFT);
300 menu.remove(ITextEditorActionConstants.CONTEXT_PREFERENCES);
301 }
302 }