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