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.IPreferenceKeys;
47 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
48 import eu.etaxonomy.taxeditor.store.CdmStore;
49
50 /**
51 * <p>BulkEditor class.</p>
52 *
53 * @author p.ciardelli
54 * @created 07.07.2009
55 * @version 1.0
56 */
57 public class BulkEditor extends AnnotatedLineEditor implements IPartContentHasDetails, IDirtyMarkableSelectionProvider{
58
59 /** Constant <code>ID="bulkeditor.editor"</code> */
60 public static final String ID = "bulkeditor.editor";
61
62 private boolean isInitialFocus = true;
63
64 private BulkEditorSearch searchBar = null;
65
66 private IPropertyChangeListener markerPreferenceListener;
67
68 /**
69 * <p>Constructor for BulkEditor.</p>
70 */
71 public BulkEditor() {
72 super(CdmStore.createConversation());
73 }
74
75 /* (non-Javadoc)
76 * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
77 */
78 /** {@inheritDoc} */
79 @Override
80 protected void initializeEditor() {
81 super.initializeEditor();
82
83 /**
84 * see AbstractTextEditor javadoc for explanation of context menu ids
85 */
86 setEditorContextMenuId("#BulkEditorContext");
87
88 // setEntityCreatorService(new BulkEditorEntityCreatorService());
89
90 setLineDisplayStrategy(new BulkEditorLineDisplay(this));
91
92 setSourceViewerConfiguration(new BulkEditorViewerConfiguration(lineDisplayStrategy));
93 }
94
95 /* (non-Javadoc)
96 * @see eu.etaxonomy.taxeditor.bulkeditor.ListEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
97 */
98 /** {@inheritDoc} */
99 @Override
100 protected ISourceViewer createSourceViewer(Composite parent,
101 IVerticalRuler ruler, int styles) {
102 ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
103 if (getEditorInput().isMergingEnabled()) {
104 addToggleMergeCandidateListener(ruler.getControl());
105 }
106 return viewer;
107 }
108
109 /* (non-Javadoc)
110 * @see eu.etaxonomy.taxeditor.bulkeditor.AnnotatedLineEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
111 */
112 /** {@inheritDoc} */
113 @Override
114 public void init(IEditorSite site, IEditorInput input)
115 throws PartInitException {
116
117 if (!(input instanceof AbstractBulkEditorInput)) {
118 throw new PartInitException("Invalid Input: Must be BulkEditorInput");
119 }
120
121 super.init(site, input);
122 }
123
124 /* (non-Javadoc)
125 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
126 */
127 /** {@inheritDoc} */
128 @Override
129 public void createPartControl(Composite parent) {
130
131 parent.setLayout(new GridLayout());
132
133 Composite layoutComposite = new Composite(parent, SWT.NONE);
134 layoutComposite.setLayout(new GridLayout());
135
136 GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
137 layoutComposite.setLayoutData(gridData);
138
139 // layoutComposite.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
140
141
142 searchBar = new BulkEditorSearch(this, layoutComposite, SWT.NONE);
143 // layoutComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
144
145 super.createPartControl(parent);
146
147 // Set viewer composite to fill grid. Unfortunately it is private and we have to do a little hack here.
148 for (Control control : parent.getChildren()) {
149 if (control instanceof Composite &&
150 !(control.equals(layoutComposite))) {
151 control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
152 }
153 }
154 }
155
156 /* (non-Javadoc)
157 * @see org.eclipse.ui.editors.text.TextEditor#dispose()
158 */
159 /** {@inheritDoc} */
160 @Override
161 public void dispose() {
162 if (markerPreferenceListener != null ) {
163 PreferencesUtil.getPreferenceStore().removePropertyChangeListener(markerPreferenceListener);
164 }
165 super.dispose();
166 }
167
168 /* (non-Javadoc)
169 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isEditable()
170 */
171 /** {@inheritDoc} */
172 @Override
173 public boolean isEditable() {
174 return false;
175 }
176
177 /* (non-Javadoc)
178 * @see eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor#setFocus()
179 */
180 /** {@inheritDoc} */
181 @Override
182 public void setFocus() {
183 searchBar.setFocus();
184
185 // TODO find a better place to put this - this dialog should be shown after initial contents of
186 // Editor are displayed
187 if (isInitialFocus) {
188 displayWarningDialog();
189 isInitialFocus = false;
190 }
191 }
192
193 /**
194 *
195 */
196 private void displayWarningDialog() {
197 IPreferenceStore prefs = PreferencesUtil.getPreferenceStore();
198 if (!prefs.getBoolean(IPreferenceKeys.HIDE_BULKEDITOR_INFO)) {
199 String msg = "The Bulk Editor allows you to edit objects used to reference other objects, such as names, references, and authors.\n\n" +
200 "Any changes you make to an object in the Bulk Editor will be displayed wherever the object is used.\n\n" +
201 "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.";
202 MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm
203 (getSite().getShell(), "Bulk Editor", msg, "Do not show this message again",
204 false, null, IPreferenceKeys.HIDE_BULKEDITOR_INFO);
205 if (dialog.getReturnCode() == Window.OK) {
206 prefs.setValue(IPreferenceKeys.HIDE_BULKEDITOR_INFO, dialog.getToggleState());
207 }
208 }
209 }
210
211 /**
212 * @param control
213 */
214 private void addToggleMergeCandidateListener(Control control) {
215 control.addMouseListener(new MouseAdapter() {
216 @Override
217 public void mouseDoubleClick(MouseEvent e) {
218 StyledText textWidget = getSourceViewer().getTextWidget();
219 int line = textWidget.getLineIndex(e.y);
220 toggleMergeCandidateAnnotation(line);
221 }
222 });
223 }
224
225 /**
226 * <p>toggleMergeCandidateAnnotation</p>
227 *
228 * @param line a int.
229 */
230 public void toggleMergeCandidateAnnotation(int line) {
231
232 IDocument document = getSourceViewer().getDocument();
233 LineAnnotationModel model =
234 (LineAnnotationModel) getSourceViewer().getAnnotationModel();
235
236 if(model != null){
237 Annotation annotation = model.getAnnotationAtLine(line, document);
238
239 if (annotation != null) {
240 if (annotation.getType().equals(IBulkEditorConstants.TYPE_MERGE_CANDIDATE)) {
241 model.changeAnnotationType(
242 annotation, LineAnnotation.TYPE_GENERIC);
243 } else {
244 model.changeAnnotationType(
245 annotation, IBulkEditorConstants.TYPE_MERGE_CANDIDATE);
246 }
247 }
248 }
249 }
250
251 /** {@inheritDoc} */
252 @Override
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 @Override
311 protected void editorContextMenuAboutToShow(IMenuManager menu) {
312 super.editorContextMenuAboutToShow(menu);
313 menu.remove(ITextEditorActionConstants.SHIFT_RIGHT);
314 menu.remove(ITextEditorActionConstants.SHIFT_LEFT);
315 menu.remove(ITextEditorActionConstants.CONTEXT_PREFERENCES);
316 }
317 }