3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.taxeditor
.bulkeditor
;
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
;
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
;
53 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
54 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
65 public class BulkEditor
extends AnnotatedLineEditor
implements IPartContentHasDetails
,
66 IDirtyMarkable
, IDerivedUnitFacadePart
, IPartContentHasFactualData
{
68 /** Constant <code>ID="bulkeditor.editor"</code> */
69 public static final String ID
= "bulkeditor.editor";
71 private boolean isInitialFocus
= true;
73 private BulkEditorSearch searchBar
= null;
75 private IPropertyChangeListener markerPreferenceListener
;
77 private boolean isDirty
;
80 * <p>Constructor for BulkEditor.</p>
83 super(CdmStore
.createConversation());
87 * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
91 protected void initializeEditor() {
92 super.initializeEditor();
95 * see AbstractTextEditor javadoc for explanation of context menu ids
97 setEditorContextMenuId("#BulkEditorContext");
99 // setEntityCreatorService(new BulkEditorEntityCreatorService());
101 setLineDisplayStrategy(new BulkEditorLineDisplay(this));
103 setSourceViewerConfiguration(new BulkEditorViewerConfiguration(lineDisplayStrategy
));
107 * @see eu.etaxonomy.taxeditor.bulkeditor.ListEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
111 protected ISourceViewer
createSourceViewer(Composite parent
,
112 IVerticalRuler ruler
, int styles
) {
113 ISourceViewer viewer
= super.createSourceViewer(parent
, ruler
, styles
);
114 if (getEditorInput().isMergingEnabled()) {
115 addToggleMergeCandidateListener(ruler
.getControl());
121 * @see eu.etaxonomy.taxeditor.bulkeditor.AnnotatedLineEditor#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
125 public void init(IEditorSite site
, IEditorInput input
)
126 throws PartInitException
{
128 if (!(input
instanceof AbstractBulkEditorInput
)) {
129 throw new PartInitException("Invalid Input: Must be BulkEditorInput");
132 super.init(site
, input
);
136 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
140 public void createPartControl(Composite parent
) {
142 parent
.setLayout(new GridLayout());
144 Composite layoutComposite
= new Composite(parent
, SWT
.NONE
);
145 layoutComposite
.setLayout(new GridLayout());
147 GridData gridData
= new GridData(SWT
.FILL
, SWT
.TOP
, true, false);
148 layoutComposite
.setLayoutData(gridData
);
150 // layoutComposite.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
153 searchBar
= new BulkEditorSearch(this, layoutComposite
, SWT
.NONE
);
154 // layoutComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
156 super.createPartControl(parent
);
158 // Set viewer composite to fill grid. Unfortunately it is private and we have to do a little hack here.
159 for (Control control
: parent
.getChildren()) {
160 if (control
instanceof Composite
&&
161 !(control
.equals(layoutComposite
))) {
162 control
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
168 * @see org.eclipse.ui.editors.text.TextEditor#dispose()
172 public void dispose() {
173 if (markerPreferenceListener
!= null ) {
174 PreferencesUtil
.getPreferenceStore().removePropertyChangeListener(markerPreferenceListener
);
181 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isEditable()
185 public boolean isEditable() {
190 * @see eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor#setFocus()
194 public void setFocus() {
195 searchBar
.setFocus();
197 // TODO find a better place to put this - this dialog should be shown after initial contents of
198 // Editor are displayed
199 if (isInitialFocus
) {
200 displayWarningDialog();
201 isInitialFocus
= false;
208 private void displayWarningDialog() {
209 IPreferenceStore prefs
= PreferencesUtil
.getPreferenceStore();
210 if (!prefs
.getBoolean(PreferencesUtil
.HIDE_BULKEDITOR_INFO
)) {
211 String msg
= "The Bulk Editor allows you to edit objects used to reference other objects, such as names, references, and authors.\n\n" +
212 "Any changes you make to an object in the Bulk Editor will be displayed wherever the object is used.\n\n" +
213 "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.";
214 MessageDialogWithToggle dialog
= MessageDialogWithToggle
.openOkCancelConfirm
215 (getSite().getShell(), "Bulk Editor", msg
, "Do not show this message again",
216 false, null, PreferencesUtil
.HIDE_BULKEDITOR_INFO
);
217 if (dialog
.getReturnCode() == Window
.OK
) {
218 prefs
.setValue(PreferencesUtil
.HIDE_BULKEDITOR_INFO
, dialog
.getToggleState());
226 private void addToggleMergeCandidateListener(Control control
) {
227 control
.addMouseListener(new MouseAdapter() {
229 public void mouseDoubleClick(MouseEvent e
) {
230 StyledText textWidget
= getSourceViewer().getTextWidget();
231 int line
= textWidget
.getLineIndex(e
.y
);
232 toggleMergeCandidateAnnotation(line
);
238 * <p>toggleMergeCandidateAnnotation</p>
242 public void toggleMergeCandidateAnnotation(int line
) {
244 IDocument document
= getSourceViewer().getDocument();
245 LineAnnotationModel model
=
246 (LineAnnotationModel
) getSourceViewer().getAnnotationModel();
249 Annotation annotation
= model
.getAnnotationAtLine(line
, document
);
251 if (annotation
!= null) {
252 if (annotation
.getType().equals(IBulkEditorConstants
.TYPE_MERGE_CANDIDATE
)) {
253 model
.changeAnnotationType(
254 annotation
, LineAnnotation
.TYPE_GENERIC
);
256 model
.changeAnnotationType(
257 annotation
, IBulkEditorConstants
.TYPE_MERGE_CANDIDATE
);
264 * @see eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor#isDirty()
267 public boolean isDirty() {
272 return super.isDirty();
277 public void forceDirty(){
279 firePropertyChange(PROP_DIRTY
);
283 * @see eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor#doSave(org.eclipse.core.runtime.IProgressMonitor)
286 public void doSave(IProgressMonitor progressMonitor
) {
288 IViewPart part
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getActivePage()
289 .findView("eu.etaxonomy.taxeditor.bulkeditor.view.referencingobjects");
291 ((ReferencingObjectsView
)part
).dispose();
293 super.doSave(progressMonitor
);
297 ((ReferencingObjectsView
)part
).refresh();
300 getSourceViewer().getTextWidget().setFocus();
306 public void changed(Object object
) {
307 // this.dirty = dirty;
308 AnnotatedLineDocumentProvider p
= (AnnotatedLineDocumentProvider
) getDocumentProvider();
310 // firePropertyChange(PROP_DIRTY);
314 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
317 public void performSearch(BulkEditorQuery query
) {
320 // TODO check if dirty, prompt save
322 boolean proceed
= MessageDialog
.openQuestion(getEditorSite().getShell(),
323 "Save changes", "You have made changes that must be saved before this query can be executed. Would you like to proceed?");
331 getEditorInput().performSearch(query
);
337 getSourceViewer().getTextWidget().setFocus();
341 private void selectFirstItem() {
342 ITextSelection selection
= new TextSelection(0, 0);
343 getSelectionProvider().setSelection(selection
);
349 public void refresh() {
350 if(getDocumentProvider().getAnnotationModel(getEditorInput()) != null){
351 ((AnnotationModel
) getDocumentProvider().getAnnotationModel(getEditorInput())).removeAllAnnotations();
354 setInput(getEditorInput());
359 public AbstractBulkEditorInput
getEditorInput() {
360 return (AbstractBulkEditorInput
) super.getEditorInput();
364 protected void editorContextMenuAboutToShow(IMenuManager menu
) {
365 super.editorContextMenuAboutToShow(menu
);
366 menu
.remove(ITextEditorActionConstants
.SHIFT_RIGHT
);
367 menu
.remove(ITextEditorActionConstants
.SHIFT_LEFT
);
368 menu
.remove(ITextEditorActionConstants
.CONTEXT_PREFERENCES
);