Fix #1005 - Display property sheet values in the correct order in Bulk Editor
[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 java.beans.PropertyChangeEvent;
14 import java.beans.PropertyChangeListener;
15
16 import org.apache.log4j.Logger;
17 import org.eclipse.jface.action.IMenuManager;
18 import org.eclipse.jface.action.IStatusLineManager;
19 import org.eclipse.jface.action.IToolBarManager;
20 import org.eclipse.jface.dialogs.MessageDialog;
21 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
22 import org.eclipse.jface.preference.IPreferenceStore;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.source.Annotation;
25 import org.eclipse.jface.text.source.AnnotationModel;
26 import org.eclipse.jface.text.source.ISourceViewer;
27 import org.eclipse.jface.text.source.IVerticalRuler;
28 import org.eclipse.jface.window.Window;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.custom.StyledText;
31 import org.eclipse.swt.events.MouseAdapter;
32 import org.eclipse.swt.events.MouseEvent;
33 import org.eclipse.swt.layout.GridData;
34 import org.eclipse.swt.layout.GridLayout;
35 import org.eclipse.swt.widgets.Composite;
36 import org.eclipse.swt.widgets.Control;
37 import org.eclipse.swt.widgets.Tree;
38 import org.eclipse.ui.IEditorInput;
39 import org.eclipse.ui.IEditorSite;
40 import org.eclipse.ui.PartInitException;
41 import org.eclipse.ui.views.properties.IPropertySheetEntry;
42 import org.eclipse.ui.views.properties.IPropertySheetPage;
43 import org.eclipse.ui.views.properties.PropertySheetPage;
44 import org.eclipse.ui.views.properties.PropertySheetSorter;
45
46 import eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor;
47 import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation;
48 import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotationModel;
49 import eu.etaxonomy.taxeditor.bulkeditor.input.BulkEditorInput;
50 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
51 import eu.etaxonomy.taxeditor.propertysheet.EditorPropertySheetEntry;
52 import eu.etaxonomy.taxeditor.propertysheet.PropertySheetUtil;
53
54 /**
55 * @author p.ciardelli
56 * @created 07.07.2009
57 * @version 1.0
58 */
59 public class BulkEditor extends AnnotatedLineEditor implements PropertyChangeListener {
60 private static final Logger logger = Logger.getLogger(BulkEditor.class);
61
62 public static final String ID = "bulkeditor.editor";
63
64 private boolean isInitialFocus = true;
65
66 /**
67 *
68 */
69 public BulkEditor() {
70 super();
71
72 /**
73 * see AbstractTextEditor javadoc for explanation of context menu ids
74 */
75 setEditorContextMenuId("#BulkEditorContext");
76
77 setEntityCreatorService(new BulkEditorEntityCreatorService());
78
79 setPersistenceService(new BulkEditorPersistenceService());
80
81 setLineDisplayStrategy(new BulkEditorLineDisplay(this));
82 }
83
84 /* (non-Javadoc)
85 * @see eu.etaxonomy.taxeditor.bulkeditor.ListEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
86 */
87 protected ISourceViewer createSourceViewer(Composite parent,
88 IVerticalRuler ruler, int styles) {
89 ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
90 addToggleMergeCandidateListener(ruler.getControl());
91 return viewer;
92 }
93
94 /* (non-Javadoc)
95 * @see eu.etaxonomy.taxeditor.bulkeditor.AnnotatedLineEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
96 */
97 @Override
98 public void init(IEditorSite site, IEditorInput input)
99 throws PartInitException {
100
101 if (!(input instanceof BulkEditorInput)) {
102 throw new PartInitException("Invalid Input: Must be BulkEditorInput");
103 }
104
105 super.init(site, input);
106
107 ((BulkEditorInput) input).addPropertyChangeListener(this);
108 }
109
110 /* (non-Javadoc)
111 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
112 */
113 @Override
114 public void createPartControl(Composite parent) {
115
116 GridLayout gridLayout = new GridLayout();
117 parent.setLayout(gridLayout);
118
119 BulkEditorSearchComposite searchBar = new BulkEditorSearchComposite(this, parent, SWT.NONE);
120 searchBar.getParent().setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
121
122 super.createPartControl(parent);
123
124 // Set viewer composite to fill grid
125 for (Control control : parent.getChildren()) {
126 if (control instanceof Composite && !(control instanceof BulkEditorSearchComposite)) {
127 control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
128 }
129 }
130 }
131
132 /* (non-Javadoc)
133 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isEditable()
134 */
135 @Override
136 public boolean isEditable() {
137 return false;
138 }
139
140 /* (non-Javadoc)
141 * @see eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor#setFocus()
142 */
143 @Override
144 public void setFocus() {
145 super.setFocus();
146
147 // TODO find a better place to put this - this dialog should be shown after initial contents of
148 // Editor are displayed
149 if (isInitialFocus) {
150 displayWarningDialog();
151 isInitialFocus = false;
152 }
153 }
154
155 /**
156 *
157 */
158 private void displayWarningDialog() {
159 IPreferenceStore prefs = PreferencesUtil.getPreferenceStore();
160 if (!prefs.getBoolean(PreferencesUtil.HIDE_BULKEDITOR_INFO)) {
161 String msg = "The Bulk Editor allows you to edit objects used to reference other objects, such as names, references, and authors.\n\n" +
162 "Any changes you make to an object in the Bulk Editor will be displayed wherever the object is used.\n\n" +
163 "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.";
164 MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm
165 (getSite().getShell(), "Bulk Editor", msg, "Do not show this message again",
166 false, null, PreferencesUtil.HIDE_BULKEDITOR_INFO);
167 if (dialog.getReturnCode() == Window.OK) {
168 prefs.setValue(PreferencesUtil.HIDE_BULKEDITOR_INFO, dialog.getToggleState());
169 }
170 }
171 }
172
173 /**
174 * @param control
175 */
176 private void addToggleMergeCandidateListener(Control control) {
177 control.addMouseListener(new MouseAdapter() {
178 @Override
179 public void mouseDoubleClick(MouseEvent e) {
180 StyledText textWidget = getSourceViewer().getTextWidget();
181 int line = textWidget.getLineIndex(e.y);
182 toggleMergeCandidateAnnotation(line);
183 }
184 });
185 }
186
187 /**
188 * @param line
189 */
190 public void toggleMergeCandidateAnnotation(int line) {
191 // TODO merge this with duplicate code in SetMergeCandidateHandler
192 IDocument document = getSourceViewer().getDocument();
193 LineAnnotationModel model =
194 (LineAnnotationModel) getSourceViewer().getAnnotationModel();
195
196 Annotation annotation = model.getAnnotationAtLine(line, document);
197
198 if (annotation != null) {
199 if (annotation.getType().equals(IBulkEditorConstants.TYPE_MERGE_CANDIDATE)) {
200 model.changeAnnotationType(
201 annotation, LineAnnotation.TYPE_GENERIC);
202 } else {
203 model.changeAnnotationType(
204 annotation, IBulkEditorConstants.TYPE_MERGE_CANDIDATE);
205 }
206 }
207 }
208
209 /* (non-Javadoc)
210 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
211 */
212 public void propertyChange(PropertyChangeEvent evt) {
213 if (evt.getPropertyName().equals(BulkEditorInput.QUERY_CHANGED)) {
214
215 // TODO check if dirty, prompt save
216 if (isDirty()) {
217 boolean proceed = MessageDialog.openQuestion(getEditorSite().getShell(),
218 "Save changes", "You have made changes that must be saved before this query can be executed. Would you like to proceed?");
219 if (proceed) {
220 doSave(null);
221 } else {
222 return;
223 }
224 }
225 ((AnnotationModel) getDocumentProvider().getAnnotationModel(getEditorInput())).removeAllAnnotations();
226 setInput(getEditorInput());
227 }
228 }
229
230 @SuppressWarnings("unchecked")
231 public Object getAdapter(Class type) {
232 if (type == IPropertySheetPage.class) {
233 PropertySheetPage page = new EditorPropertySheetPage();
234 return page;
235 }
236 return super.getAdapter(type);
237 }
238
239 class EditorPropertySheetPage extends PropertySheetPage {
240
241 EditorPropertySheetPage() {
242 super();
243
244 // Override sorter to simply display names as first-in-first-out
245 setSorter(new PropertySheetSorter() {
246 public int compare(IPropertySheetEntry entryA, IPropertySheetEntry entryB) {
247 return 0;
248 }
249 public int compareCategories(String categoryA, String categoryB) {
250 return 0;
251 }
252 public void sort(IPropertySheetEntry[] entries) {
253 // do nothing
254 }
255 });
256 }
257
258 public void makeContributions(IMenuManager menuManager,
259 IToolBarManager toolBarManager, IStatusLineManager statusLineManager) {
260 super.makeContributions(menuManager, toolBarManager, statusLineManager);
261
262 // Remove "Show categories", "Show advanced properties", "Restore default value"
263 toolBarManager.removeAll();
264 menuManager.removeAll();
265 }
266 }
267 }