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
.jface
.viewers
.StructuredSelection
;
21 import org
.eclipse
.ui
.IEditorInput
;
22 import org
.eclipse
.ui
.IEditorPart
;
23 import org
.eclipse
.ui
.IEditorSite
;
24 import org
.eclipse
.ui
.PartInitException
;
25 import org
.eclipse
.ui
.forms
.editor
.FormEditor
;
27 import eu
.etaxonomy
.cdm
.api
.conversation
.ConversationHolder
;
28 import eu
.etaxonomy
.cdm
.api
.conversation
.IConversationEnabled
;
29 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
30 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
31 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
32 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
33 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.CdmDataChangeMap
;
34 import eu
.etaxonomy
.taxeditor
.editor
.name
.TaxonNameEditor
;
35 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.AbstractGroupedContainer
;
36 import eu
.etaxonomy
.taxeditor
.model
.DataChangeBridge
;
37 import eu
.etaxonomy
.taxeditor
.model
.IDataChangeBehavior
;
38 import eu
.etaxonomy
.taxeditor
.model
.IDirtyMarkableSelectionProvider
;
39 import eu
.etaxonomy
.taxeditor
.model
.IPartContentHasDetails
;
40 import eu
.etaxonomy
.taxeditor
.operation
.IPostOperationEnabled
;
44 * Generates the tabbed editor with <code>TaxonNameEditor</code> on top and tabs for
45 * "Descriptions", "Concepts", "Geography", etc.
52 public class MultiPageTaxonEditor
extends FormEditor
implements IConversationEnabled
, IPostOperationEnabled
, IDirtyMarkableSelectionProvider
, IPartContentHasDetails
{
54 /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.taxon"{trunked}</code> */
55 public static final String ID
= "eu.etaxonomy.taxeditor.editor.taxon";
57 private boolean dirty
;
59 private ConversationHolder conversation
;
60 private IDataChangeBehavior dataChangeBehavior
;
61 private IUndoContext undoContext
;
63 private TaxonEditorInput input
;
66 * <p>Constructor for MultiPageTaxonEditor.</p>
68 public MultiPageTaxonEditor() {
70 undoContext
= new UndoContext();
75 public void dispose() {
76 conversation
.unregisterForDataStoreChanges(this);
82 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
86 protected void addPages() {
87 input
= (TaxonEditorInput
) getEditorInput();
88 conversation
= input
.getConversationHolder();
89 conversation
.registerForDataStoreChanges(this);
92 addPage(Page
.NAME
.getIndex(), new TaxonNameEditor(this), getEditorInput());
93 // setPageText(Page.NAME.getIndex(), Page.NAME.getTitle());
96 // addPage(Page.DESCRIPTIVE.getIndex(), new TaxonDescriptionTreeEditor(this), getEditorInput());
97 // setPageText(Page.DESCRIPTIVE.getIndex(), Page.DESCRIPTIVE.getTitle());
99 // EditorUtil.showPropertySheet();
101 } catch (PartInitException e
) {
102 EditorUtil
.error(getClass(), e
);
109 public void doSave(IProgressMonitor monitor
) {
110 monitor
.beginTask("Saving Editor", 4);
112 if( ! conversation
.isBound()){
117 for(IEditorPart editorPage
: getPages()){
118 if(editorPage
instanceof TaxonNameEditor
){
119 if(((TaxonNameEditor
) editorPage
).checkForEmptyNames()){
120 MessageDialog
.openWarning(EditorUtil
.getShell(), "No Name Specified", "An attempt was made to save a taxon or synonym with " +
121 "an empty name. Operation was cancelled.");
126 editorPage
.doSave(monitor
);
130 // commit the conversation and start a new transaction immediately
131 conversation
.commit(true);
134 this.setDirty(false);
137 EditorUtil
.errorDialog("An error occurred while saving", getClass(), "An error occurred while saving the editor. Please close and reopen the taxon again.", e
);
145 private void disableEditor() {
146 for(IMultiPageTaxonEditorPage editorPage
: getPages()){
147 editorPage
.setDisabled();
150 getSite().getSelectionProvider().setSelection(new StructuredSelection());
151 getSite().setSelectionProvider(null);
154 private void setDirty(boolean dirty
) {
156 firePropertyChange(PROP_DIRTY
);
160 * @see org.eclipse.ui.part.MultiPageEditorPart#isDirty()
167 public boolean isDirty() {
172 * @see org.eclipse.ui.forms.editor.FormEditor#editorDirtyStateChanged()
176 public void editorDirtyStateChanged() {
178 super.editorDirtyStateChanged();
185 * Checks whether nested editors are calling <code>firePropertyChange(PROP_DIRTY)</code>
186 * to signal an edit has taken place before passing property change along to
187 * <code>super.handlePropertyChange(int propertyId)</code>.
190 * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
192 protected void handlePropertyChange(int propertyId
) {
193 if (propertyId
== PROP_DIRTY
) {
196 super.handlePropertyChange(propertyId
);
201 public void doSaveAs() {}
205 public boolean isSaveAsAllowed() {
211 public void init(IEditorSite site
, IEditorInput input
) throws PartInitException
{
213 if (!(input
instanceof TaxonEditorInput
))
214 throw new PartInitException(
215 "Invalid Input: Must be TaxonEditorInput");
217 this.input
= (TaxonEditorInput
) input
;
220 // // Listen for name changes,
221 // // change tab for this taxon editor accordingly
222 // getTaxon().addPropertyChangeListener("name",
223 // new PropertyChangeListener() {
224 // public void propertyChange(PropertyChangeEvent e) {
228 // } catch (NullPointerException e) {
229 // EditorUtil.warn(getClass(), "Caught an NPE while initing an editor. This is most " +
230 // "likely due to the unsuccesful attempt to restore the former " +
231 // "state of the application. We ignore this because the workbench " +
232 // "will simply be reset.");
236 super.init(site
, input
);
240 * Calls <code>MultiPageEditorPart.setPartName(String partName)</code>
241 * with text appropriate to the state of the taxon: any taxon that has
242 * been saved will by necessity have a name to display; a new taxon
243 * should display "New taxon" in the editor tab.
245 protected void setPartName() {
247 String partName
= null;
248 TaxonNameBase
<?
, ?
> name
= getTaxon().getName();
251 partName
= name
.getTitleCache();
254 if (partName
== null || partName
.equals("")) {
255 partName
= ("New taxon");
258 setPartName(partName
);
264 * Editor pages call this in their postOperation to notify the MultiPageTaxonEditor
267 public void changed(Object element
) {
270 super.editorDirtyStateChanged();
271 if(element
instanceof TaxonBase
){
272 TaxonNameEditor page
= (TaxonNameEditor
) getPage(Page
.NAME
);
273 AbstractGroupedContainer container
= page
.getContainer((TaxonBase
) element
);
274 if(container
!= null){
281 * The accepted taxon that is the input for this editor
283 * @return the accepted taxon
285 public Taxon
getTaxon(){
286 return input
.getTaxon();
291 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
294 * <p>getConversationHolder</p>
296 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
298 public ConversationHolder
getConversationHolder() {
303 * <p>setConversationHolder</p>
305 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
307 public void setConversationHolder(ConversationHolder conversation
){
308 this.conversation
= conversation
;
313 * <p>Getter for the field <code>undoContext</code>.</p>
315 * @return a {@link org.eclipse.core.commands.operations.IUndoContext} object.
317 public IUndoContext
getUndoContext() {
322 * <p>Setter for the field <code>undoContext</code>.</p>
324 * @param undoContext a {@link org.eclipse.core.commands.operations.IUndoContext} object.
326 public void setUndoContext(IUndoContext undoContext
) {
327 this.undoContext
= undoContext
;
332 public void setFocus(){
333 //logger.warn("Setting focus to editor");
334 // bind the conversation
335 getConversationHolder().bind();
336 // pass focus to the active editor page
337 getActiveEditor().setFocus();
342 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
345 public void update(CdmDataChangeMap events
) {
346 if(dataChangeBehavior
== null){
347 dataChangeBehavior
= new MultiPageTaxonEditorDataChangeBehaviour(this);
350 DataChangeBridge
.handleDataChange(events
, dataChangeBehavior
);
356 * @see eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation()
359 public boolean postOperation(CdmBase objectAffectedByOperation
) {
362 for(IEditorPart editor
: this.getPages()){
363 if (editor
instanceof IPostOperationEnabled
) {
364 ((IPostOperationEnabled
) editor
).postOperation(objectAffectedByOperation
);
366 EditorUtil
.warn(getClass(), "postOperation not enabled for editor " + editor
);
369 EditorUtil
.warn(getClass(), "postOperation called on MultiPageTaxonEditor. Can you make it more specific?");
375 * Returns an <code>IEditorPart</code> implementation by type
377 * @param page the page type
378 * @return a {@link eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage} object.
380 public IMultiPageTaxonEditorPage
getPage(Page page
){
381 for(IEditorPart editor
: this.getPages()){
382 if(editor
.getClass().equals(page
.getClazz())){
383 return (IMultiPageTaxonEditorPage
) editor
;
390 * Return a list of <code>AbstractTaxonEditor</code>s registered with this
391 * <code>MultiPageTaxonEditor</code>.
393 * @return a {@link java.util.List} object.
395 public List
<IMultiPageTaxonEditorPage
> getPages(){
396 ArrayList
<IMultiPageTaxonEditorPage
> editors
= new ArrayList
<IMultiPageTaxonEditorPage
>();
397 for(int i
= 0; i
< this.getPageCount(); i
++){
399 editors
.add((IMultiPageTaxonEditorPage
) this.getEditor(i
));
405 * Refreshes a certain page of the MultipageTaxonEditor
407 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
410 public boolean redraw(Page page
){
411 return redraw(page
, true);
415 * Refreshes a certain page of the MultipageTaxonEditor and
416 * sets focus to that page
418 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
419 * @param focus a boolean.
422 public boolean redraw(Page page
, boolean focus
){
423 IMultiPageTaxonEditorPage editorPage
= getPage(page
);
424 return editorPage
!= null && editorPage
.redraw(focus
);
432 public boolean onComplete() {
437 * Reloads the data for this
439 public void reload() {
441 EditorUtil
.warningDialog("Editor has unsaved data", getClass(), "This editor can not be " +
442 "refreshed because it contains unsaved data. Refreshing " +
443 "this editor would discard the changes. Please save this editor, " +
444 "close and reopen it manually in order to get the latest content");
446 TaxonEditorInput input
= (TaxonEditorInput
) getEditorInput();
448 UUID uuid
= input
.getTaxonNode().getUuid();
450 conversation
.clear();
453 TaxonEditorInput newInput
= TaxonEditorInput
.NewInstance(uuid
);
455 for(IMultiPageTaxonEditorPage editorPart
: getPages()){
458 } catch (Exception e
) {
459 EditorUtil
.errorDialog("Error refreshing editor", getClass(), "Could not refresh this editor", e
);