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