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