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
.editor
;
12 import java
.util
.ArrayList
;
13 import java
.util
.List
;
14 import java
.util
.UUID
;
16 import org
.eclipse
.core
.commands
.operations
.IUndoContext
;
17 import org
.eclipse
.core
.commands
.operations
.UndoContext
;
18 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
19 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
20 import org
.eclipse
.ui
.IEditorInput
;
21 import org
.eclipse
.ui
.IEditorPart
;
22 import org
.eclipse
.ui
.IEditorSite
;
23 import org
.eclipse
.ui
.PartInitException
;
24 import org
.eclipse
.ui
.forms
.editor
.FormEditor
;
26 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
27 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
28 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
29 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
30 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
31 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
32 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.CdmDataChangeMap
;
33 import eu
.etaxonomy
.taxeditor
.editor
.name
.TaxonNameEditor
;
34 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.AbstractGroupedContainer
;
35 import eu
.etaxonomy
.taxeditor
.model
.DataChangeBridge
;
36 import eu
.etaxonomy
.taxeditor
.model
.IDataChangeBehavior
;
37 import eu
.etaxonomy
.taxeditor
.model
.IDirtyMarkableSelectionProvider
;
38 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasDetails
;
39 import eu
.etaxonomy
.taxeditor
.operation
.IPostOperationEnabled
;
43 * Generates the tabbed editor with <code>TaxonNameEditor</code> on top and tabs
44 * for "Descriptions", "Concepts", "Geography", etc.
51 public class MultiPageTaxonEditor
extends FormEditor
implements
52 IConversationEnabled
, IPostOperationEnabled
,
53 IDirtyMarkableSelectionProvider
, IPartContentHasDetails
{
55 /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.taxon"{trunked}</code> */
56 public static final String ID
= "eu.etaxonomy.taxeditor.editor.taxon";
58 private boolean dirty
;
60 private ConversationHolder conversation
;
61 private IDataChangeBehavior dataChangeBehavior
;
62 private IUndoContext undoContext
;
64 private TaxonEditorInput input
;
68 * Constructor for MultiPageTaxonEditor.
71 public MultiPageTaxonEditor() {
73 undoContext
= new UndoContext();
78 public void dispose() {
79 conversation
.unregisterForDataStoreChanges(this);
87 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
91 protected void addPages() {
92 input
= (TaxonEditorInput
) getEditorInput();
93 conversation
= input
.getConversationHolder();
94 conversation
.registerForDataStoreChanges(this);
97 addPage(Page
.NAME
.getIndex(), new TaxonNameEditor(this),
99 // setPageText(Page.NAME.getIndex(), Page.NAME.getTitle());
102 // addPage(Page.DESCRIPTIVE.getIndex(), new
103 // TaxonDescriptionTreeEditor(this), getEditorInput());
104 // setPageText(Page.DESCRIPTIVE.getIndex(),
105 // Page.DESCRIPTIVE.getTitle());
107 // EditorUtil.showPropertySheet();
109 } catch (PartInitException e
) {
110 EditorUtil
.error(getClass(), e
);
116 public void doSave(IProgressMonitor monitor
) {
117 monitor
.beginTask("Saving Editor", 4);
119 if (!conversation
.isBound()) {
124 for (IEditorPart editorPage
: getPages()) {
125 if (editorPage
instanceof TaxonNameEditor
) {
126 if (((TaxonNameEditor
) editorPage
).checkForEmptyNames()) {
129 EditorUtil
.getShell(),
131 "An attempt was made to save a taxon or synonym with "
132 + "an empty name. Operation was cancelled.");
137 editorPage
.doSave(monitor
);
141 // commit the conversation and start a new transaction immediately
142 conversation
.commit(true);
145 this.setDirty(false);
147 } catch (Exception e
) {
151 "An error occurred while saving",
153 "An error occurred while saving the editor. Please close and reopen the taxon again.",
161 private void disableEditor() {
162 for (IMultiPageTaxonEditorPage editorPage
: getPages()) {
163 editorPage
.setDisabled();
165 conversation
.unregisterForDataStoreChanges(this);
166 conversation
.close();
170 private void setDirty(boolean dirty
) {
172 firePropertyChange(PROP_DIRTY
);
178 * @see org.eclipse.ui.part.MultiPageEditorPart#isDirty()
187 public boolean isDirty() {
194 * @see org.eclipse.ui.forms.editor.FormEditor#editorDirtyStateChanged()
198 public void editorDirtyStateChanged() {
200 super.editorDirtyStateChanged();
206 * Checks whether nested editors are calling
207 * <code>firePropertyChange(PROP_DIRTY)</code> to signal an edit has taken
208 * place before passing property change along to
209 * <code>super.handlePropertyChange(int propertyId)</code>.
214 * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
216 protected void handlePropertyChange(int propertyId
) {
217 if (propertyId
== PROP_DIRTY
) {
220 super.handlePropertyChange(propertyId
);
225 public void doSaveAs() {
230 public boolean isSaveAsAllowed() {
236 public void init(IEditorSite site
, IEditorInput input
)
237 throws PartInitException
{
239 if (!(input
instanceof TaxonEditorInput
))
240 throw new PartInitException(
241 "Invalid Input: Must be TaxonEditorInput");
243 this.input
= (TaxonEditorInput
) input
;
246 // // Listen for name changes,
247 // // change tab for this taxon editor accordingly
248 // getTaxon().addPropertyChangeListener("name",
249 // new PropertyChangeListener() {
250 // public void propertyChange(PropertyChangeEvent e) {
254 // } catch (NullPointerException e) {
255 // EditorUtil.warn(getClass(),
256 // "Caught an NPE while initing an editor. This is most " +
257 // "likely due to the unsuccesful attempt to restore the former " +
258 // "state of the application. We ignore this because the workbench " +
259 // "will simply be reset.");
263 super.init(site
, input
);
267 * Calls <code>MultiPageEditorPart.setPartName(String partName)</code> with
268 * text appropriate to the state of the taxon: any taxon that has been saved
269 * will by necessity have a name to display; a new taxon should display
270 * "New taxon" in the editor tab.
272 protected void setPartName() {
274 String partName
= null;
275 TaxonNameBase
<?
, ?
> name
= getTaxon().getName();
278 partName
= name
.getTitleCache();
281 if (partName
== null || partName
.equals("")) {
282 partName
= ("New taxon");
285 setPartName(partName
);
291 * Editor pages call this in their postOperation to notify the
292 * MultiPageTaxonEditor of unsaved changes
294 public void changed(Object element
) {
297 super.editorDirtyStateChanged();
298 if (element
instanceof TaxonBase
) {
299 TaxonNameEditor page
= (TaxonNameEditor
) getPage(Page
.NAME
);
300 AbstractGroupedContainer container
= page
301 .getContainer((TaxonBase
) element
);
302 if (container
!= null) {
309 * The accepted taxon that is the input for this editor
311 * @return the accepted taxon
313 public Taxon
getTaxon() {
314 return input
.getTaxon();
321 * eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder
326 * getConversationHolder
329 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
332 public ConversationHolder
getConversationHolder() {
338 * setConversationHolder
341 * @param conversation
342 * a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
345 public void setConversationHolder(ConversationHolder conversation
) {
346 this.conversation
= conversation
;
351 * Getter for the field <code>undoContext</code>.
354 * @return a {@link org.eclipse.core.commands.operations.IUndoContext}
357 public IUndoContext
getUndoContext() {
363 * Setter for the field <code>undoContext</code>.
367 * a {@link org.eclipse.core.commands.operations.IUndoContext}
370 public void setUndoContext(IUndoContext undoContext
) {
371 this.undoContext
= undoContext
;
376 public void setFocus() {
377 // logger.warn("Setting focus to editor");
378 // bind the conversation
379 getConversationHolder().bind();
380 // pass focus to the active editor page
381 getActiveEditor().setFocus();
388 * eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu
389 * .etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
392 public void update(CdmDataChangeMap events
) {
393 if (dataChangeBehavior
== null) {
394 dataChangeBehavior
= new MultiPageTaxonEditorDataChangeBehaviour(
398 DataChangeBridge
.handleDataChange(events
, dataChangeBehavior
);
405 * eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation
409 public boolean postOperation(CdmBase objectAffectedByOperation
) {
412 for (IEditorPart editor
: this.getPages()) {
413 if (editor
instanceof IPostOperationEnabled
) {
414 ((IPostOperationEnabled
) editor
)
415 .postOperation(objectAffectedByOperation
);
417 EditorUtil
.warn(getClass(),
418 "postOperation not enabled for editor " + editor
);
423 "postOperation called on MultiPageTaxonEditor. Can you make it more specific?");
429 * Returns an <code>IEditorPart</code> implementation by type
433 * @return a {@link eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage}
436 public IMultiPageTaxonEditorPage
getPage(Page page
) {
437 for (IEditorPart editor
: this.getPages()) {
438 if (editor
.getClass().equals(page
.getClazz())) {
439 return (IMultiPageTaxonEditorPage
) editor
;
446 * Return a list of <code>AbstractTaxonEditor</code>s registered with this
447 * <code>MultiPageTaxonEditor</code>.
449 * @return a {@link java.util.List} object.
451 public List
<IMultiPageTaxonEditorPage
> getPages() {
452 ArrayList
<IMultiPageTaxonEditorPage
> editors
= new ArrayList
<IMultiPageTaxonEditorPage
>();
453 for (int i
= 0; i
< this.getPageCount(); i
++) {
455 editors
.add((IMultiPageTaxonEditorPage
) this.getEditor(i
));
461 * Refreshes a certain page of the MultipageTaxonEditor
464 * a {@link eu.etaxonomy.taxeditor.editor.Page} object.
467 public boolean redraw(Page page
) {
468 return redraw(page
, true);
472 * Refreshes a certain page of the MultipageTaxonEditor and sets focus to
476 * a {@link eu.etaxonomy.taxeditor.editor.Page} object.
481 public boolean redraw(Page page
, boolean focus
) {
482 IMultiPageTaxonEditorPage editorPage
= getPage(page
);
483 return editorPage
!= null && editorPage
.redraw(focus
);
493 public boolean onComplete() {
498 * Reloads the data for this
500 public void reload() {
504 "Editor has unsaved data",
506 "This editor can not be "
507 + "refreshed because it contains unsaved data. Refreshing "
508 + "this editor would discard the changes. Please save this editor, "
509 + "close and reopen it manually in order to get the latest content");
511 TaxonEditorInput input
= (TaxonEditorInput
) getEditorInput();
513 UUID uuid
= input
.getTaxonNode().getUuid();
515 conversation
.clear();
518 TaxonEditorInput newInput
= TaxonEditorInput
.NewInstance(uuid
);
520 for (IMultiPageTaxonEditorPage editorPart
: getPages()) {
523 } catch (Exception e
) {
524 EditorUtil
.errorDialog("Error refreshing editor", getClass(),
525 "Could not refresh this editor", e
);
531 public String
toString() {
532 return String
.format("%s[%s]", this.getClass().getSimpleName(), getEditorInput());