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