2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.taxeditor
.bulkeditor
;
12 import org
.eclipse
.core
.commands
.operations
.IUndoContext
;
13 import org
.eclipse
.core
.commands
.operations
.UndoContext
;
14 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
15 import org
.eclipse
.jface
.action
.GroupMarker
;
16 import org
.eclipse
.jface
.action
.IMenuManager
;
17 import org
.eclipse
.jface
.action
.MenuManager
;
18 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
19 import org
.eclipse
.jface
.dialogs
.MessageDialogWithToggle
;
20 import org
.eclipse
.jface
.preference
.IPreferenceStore
;
21 import org
.eclipse
.jface
.text
.IDocument
;
22 import org
.eclipse
.jface
.text
.ITextSelection
;
23 import org
.eclipse
.jface
.text
.TextSelection
;
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
.util
.IPropertyChangeListener
;
29 import org
.eclipse
.jface
.window
.Window
;
30 import org
.eclipse
.swt
.SWT
;
31 import org
.eclipse
.swt
.custom
.StyledText
;
32 import org
.eclipse
.swt
.events
.MouseAdapter
;
33 import org
.eclipse
.swt
.events
.MouseEvent
;
34 import org
.eclipse
.swt
.layout
.GridData
;
35 import org
.eclipse
.swt
.layout
.GridLayout
;
36 import org
.eclipse
.swt
.widgets
.Composite
;
37 import org
.eclipse
.swt
.widgets
.Control
;
38 import org
.eclipse
.swt
.widgets
.Menu
;
39 import org
.eclipse
.ui
.IEditorInput
;
40 import org
.eclipse
.ui
.IEditorSite
;
41 import org
.eclipse
.ui
.IWorkbenchActionConstants
;
42 import org
.eclipse
.ui
.PartInitException
;
43 import org
.eclipse
.ui
.texteditor
.ITextEditorActionConstants
;
45 import eu
.etaxonomy
.taxeditor
.annotatedlineeditor
.AnnotatedLineDocumentProvider
;
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
.AbstractBulkEditorInput
;
50 import eu
.etaxonomy
.taxeditor
.bulkeditor
.input
.OccurrenceEditorInput
;
51 import eu
.etaxonomy
.taxeditor
.bulkeditor
.input
.TaxonEditorInput
;
52 import eu
.etaxonomy
.taxeditor
.model
.IDerivedUnitFacadePart
;
53 import eu
.etaxonomy
.taxeditor
.model
.IDirtyMarkable
;
54 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasDetails
;
55 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasFactualData
;
56 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasMedia
;
57 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasSupplementalData
;
58 import eu
.etaxonomy
.taxeditor
.preference
.IPreferenceKeys
;
59 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
60 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
67 public class BulkEditor
extends AnnotatedLineEditor
implements IPartContentHasDetails
, IPartContentHasSupplementalData
,
68 IDirtyMarkable
, IDerivedUnitFacadePart
, IPartContentHasFactualData
, IPartContentHasMedia
{
70 /** Constant <code>ID="bulkeditor.editor"</code> */
71 public static final String ID
= "bulkeditor.editor";
73 private boolean isInitialFocus
= true;
75 private BulkEditorSearch searchBar
= null;
77 private IPropertyChangeListener markerPreferenceListener
;
79 private boolean isDirty
;
81 private IUndoContext undoContext
;
84 super(CdmStore
.createConversation());
85 undoContext
= new UndoContext();
90 protected void initializeEditor() {
91 super.initializeEditor();
93 // setEntityCreatorService(new BulkEditorEntityCreatorService());
95 setLineDisplayStrategy(new BulkEditorLineDisplay(this));
97 setSourceViewerConfiguration(new BulkEditorViewerConfiguration(lineDisplayStrategy
));
103 protected ISourceViewer
createSourceViewer(Composite parent
,
104 IVerticalRuler ruler
, int styles
) {
105 ISourceViewer viewer
= super.createSourceViewer(parent
, ruler
, styles
);
106 if (getEditorInput().isMergingEnabled()) {
107 addToggleMergeCandidateListener(ruler
.getControl());
114 public void init(IEditorSite site
, IEditorInput input
)
115 throws PartInitException
{
117 if (!(input
instanceof AbstractBulkEditorInput
)) {
118 throw new PartInitException("Invalid Input: Must be BulkEditorInput");
121 AbstractBulkEditorInput
<?
> bulkEditorInput
= (AbstractBulkEditorInput
<?
>)input
;
122 if(bulkEditorInput
.getEntityUuid()!=null){
123 bulkEditorInput
.performSearch(new BulkEditorQuery(bulkEditorInput
.getEntityUuid().toString(), null));
126 super.init(site
, input
);
131 public void createPartControl(Composite parent
) {
133 parent
.setLayout(new GridLayout());
135 Composite layoutComposite
= new Composite(parent
, SWT
.NONE
);
136 layoutComposite
.setLayout(new GridLayout());
138 GridData gridData
= new GridData(SWT
.FILL
, SWT
.TOP
, true, false);
139 layoutComposite
.setLayoutData(gridData
);
141 // layoutComposite.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
144 searchBar
= new BulkEditorSearch(this, layoutComposite
, SWT
.NONE
);
145 // layoutComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
147 super.createPartControl(parent
);
149 // Set viewer composite to fill grid. Unfortunately it is private and we have to do a little hack here.
150 for (Control control
: parent
.getChildren()) {
151 if (control
instanceof Composite
&&
152 !(control
.equals(layoutComposite
))) {
153 control
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
157 //create context menu
158 MenuManager menuManager
= new MenuManager();
159 menuManager
.setRemoveAllWhenShown(true);
160 menuManager
.add(new GroupMarker(IWorkbenchActionConstants
.MB_ADDITIONS
));
161 getSite().registerContextMenu(menuManager
, getSelectionProvider());
162 Menu menu
= menuManager
.createContextMenu(this.getSourceViewer().getTextWidget());
163 this.getSourceViewer().getTextWidget().setMenu(menu
);
169 public void dispose() {
170 if (markerPreferenceListener
!= null ) {
171 PreferencesUtil
.getPreferenceStore().removePropertyChangeListener(markerPreferenceListener
);
179 public boolean isEditable() {
185 public void setFocus() {
188 // TODO find a better place to put this - this dialog should be shown after initial contents of
189 // Editor are displayed
190 if (isInitialFocus
) {
191 displayWarningDialog();
192 isInitialFocus
= false;
195 searchBar
.setFocus();
199 * @return the searchBar
201 public BulkEditorSearch
getSearchBar() {
205 private void displayWarningDialog() {
206 IPreferenceStore prefs
= PreferencesUtil
.getPreferenceStore();
207 if (!prefs
.getBoolean(IPreferenceKeys
.HIDE_BULKEDITOR_INFO
)) {
208 String msg
= "The Bulk Editor allows you to edit objects used to reference other objects, such as names, references, and authors.\n\n" +
209 "Any changes you make to an object in the Bulk Editor will be displayed wherever the object is used.\n\n" +
210 "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.";
211 MessageDialogWithToggle dialog
= MessageDialogWithToggle
.openOkCancelConfirm
212 (getSite().getShell(), "Bulk Editor", msg
, "Do not show this message again",
213 false, null, IPreferenceKeys
.HIDE_BULKEDITOR_INFO
);
214 if (dialog
.getReturnCode() == Window
.OK
) {
215 prefs
.setValue(IPreferenceKeys
.HIDE_BULKEDITOR_INFO
, dialog
.getToggleState());
220 private void addToggleMergeCandidateListener(Control control
) {
221 control
.addMouseListener(new MouseAdapter() {
223 public void mouseDoubleClick(MouseEvent e
) {
224 StyledText textWidget
= getSourceViewer().getTextWidget();
225 int line
= textWidget
.getLineIndex(e
.y
);
226 toggleMergeCandidateAnnotation(line
);
231 public void toggleMergeCandidateAnnotation(int line
) {
233 IDocument document
= getSourceViewer().getDocument();
234 LineAnnotationModel model
=
235 (LineAnnotationModel
) getSourceViewer().getAnnotationModel();
238 Annotation annotation
= model
.getAnnotationAtLine(line
, document
);
240 if (annotation
!= null) {
241 if (annotation
.getType().equals(IBulkEditorConstants
.TYPE_MERGE_CANDIDATE
)) {
242 model
.changeAnnotationType(
243 annotation
, LineAnnotation
.TYPE_GENERIC
);
245 model
.changeAnnotationType(
246 annotation
, IBulkEditorConstants
.TYPE_MERGE_CANDIDATE
);
253 public boolean isDirty() {
258 return super.isDirty();
263 public void forceDirty(){
265 firePropertyChange(PROP_DIRTY
);
270 public void doSave(IProgressMonitor progressMonitor
) {
273 super.doSave(progressMonitor
);
275 this.searchBar
.updateEditorInput();
278 getSourceViewer().getTextWidget().setFocus();
284 public void changed(Object object
) {
285 // this.dirty = dirty;
286 AnnotatedLineDocumentProvider p
= (AnnotatedLineDocumentProvider
) getDocumentProvider();
288 // firePropertyChange(PROP_DIRTY);
292 public void performSearch(BulkEditorQuery query
) {
295 // TODO check if dirty, prompt save
297 String
[] labels
= {"Save (and Search)", "Don't save (and Search)","Cancel"};
298 MessageDialog dialog
=new MessageDialog(getEditorSite().getShell(), "Save changes", null, "You have made changes that must be saved before this query can be executed. Would you like to proceed?", MessageDialog
.QUESTION
,labels
, 0);
299 int result
= dialog
.open();
300 //MessageDialog.openQuestion(getEditorSite().getShell(),
301 //"Save changes", "You have made changes that must be saved before this query can be executed. Would you like to proceed?");
304 } else if (result
== 2){
308 //conversation.clear();
309 //conversation.commit(true);
311 getEditorInput().dispose();
312 getEditorInput().bind();
313 getEditorInput().performSearch(query
);
319 getSourceViewer().getTextWidget().setFocus();
323 private void selectFirstItem() {
324 ITextSelection selection
= new TextSelection(0, 0);
325 getSelectionProvider().setSelection(selection
);
328 public void refresh() {
329 if(getDocumentProvider().getAnnotationModel(getEditorInput()) != null){
330 ((AnnotationModel
) getDocumentProvider().getAnnotationModel(getEditorInput())).removeAllAnnotations();
333 setInput(getEditorInput());
338 public AbstractBulkEditorInput
getEditorInput() {
339 return (AbstractBulkEditorInput
) super.getEditorInput();
343 protected void editorContextMenuAboutToShow(IMenuManager menu
) {
344 super.editorContextMenuAboutToShow(menu
);
345 menu
.remove(ITextEditorActionConstants
.SHIFT_RIGHT
);
346 menu
.remove(ITextEditorActionConstants
.SHIFT_LEFT
);
347 menu
.remove(ITextEditorActionConstants
.CONTEXT_PREFERENCES
);
351 public boolean canAttachMedia() {
352 return (getEditorInput() instanceof TaxonEditorInput
|| getEditorInput() instanceof OccurrenceEditorInput
) ?
true:false;
355 public IUndoContext
getUndoContext() {