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