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 for
44 * "Descriptions", "Concepts", "Geography", etc.
51 public class MultiPageTaxonEditor
extends FormEditor
implements IConversationEnabled
, IPostOperationEnabled
, IDirtyMarkableSelectionProvider
, IPartContentHasDetails
{
53 /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.taxon"{trunked}</code> */
54 public static final String ID
= "eu.etaxonomy.taxeditor.editor.taxon";
56 private boolean dirty
;
58 private ConversationHolder conversation
;
59 private IDataChangeBehavior dataChangeBehavior
;
60 private IUndoContext undoContext
;
62 private TaxonEditorInput input
;
65 * <p>Constructor for MultiPageTaxonEditor.</p>
67 public MultiPageTaxonEditor() {
69 undoContext
= new UndoContext();
74 public void dispose() {
75 conversation
.unregisterForDataStoreChanges(this);
81 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
85 protected void addPages() {
86 input
= (TaxonEditorInput
) getEditorInput();
87 conversation
= input
.getConversationHolder();
88 conversation
.registerForDataStoreChanges(this);
91 addPage(Page
.NAME
.getIndex(), new TaxonNameEditor(this), getEditorInput());
92 // setPageText(Page.NAME.getIndex(), Page.NAME.getTitle());
95 // addPage(Page.DESCRIPTIVE.getIndex(), new TaxonDescriptionTreeEditor(this), getEditorInput());
96 // setPageText(Page.DESCRIPTIVE.getIndex(), Page.DESCRIPTIVE.getTitle());
98 // EditorUtil.showPropertySheet();
100 } catch (PartInitException e
) {
101 EditorUtil
.error(getClass(), e
);
108 public void doSave(IProgressMonitor monitor
) {
109 monitor
.beginTask("Saving Editor", 4);
111 if( ! conversation
.isBound()){
116 for(IEditorPart editorPage
: getPages()){
117 if(editorPage
instanceof TaxonNameEditor
){
118 if(((TaxonNameEditor
) editorPage
).checkForEmptyNames()){
119 MessageDialog
.openWarning(EditorUtil
.getShell(), "No Name Specified", "An attempt was made to save a taxon or synonym with " +
120 "an empty name. Operation was cancelled.");
125 editorPage
.doSave(monitor
);
129 // commit the conversation and start a new transaction immediately
130 conversation
.commit(true);
133 this.setDirty(false);
141 private void setDirty(boolean dirty
) {
143 firePropertyChange(PROP_DIRTY
);
147 * @see org.eclipse.ui.part.MultiPageEditorPart#isDirty()
154 public boolean isDirty() {
159 * @see org.eclipse.ui.forms.editor.FormEditor#editorDirtyStateChanged()
163 public void editorDirtyStateChanged() {
165 super.editorDirtyStateChanged();
172 * Checks whether nested editors are calling <code>firePropertyChange(PROP_DIRTY)</code>
173 * to signal an edit has taken place before passing property change along to
174 * <code>super.handlePropertyChange(int propertyId)</code>.
177 * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
179 protected void handlePropertyChange(int propertyId
) {
180 if (propertyId
== PROP_DIRTY
) {
183 super.handlePropertyChange(propertyId
);
188 public void doSaveAs() {}
192 public boolean isSaveAsAllowed() {
198 public void init(IEditorSite site
, IEditorInput input
) throws PartInitException
{
200 if (!(input
instanceof TaxonEditorInput
))
201 throw new PartInitException(
202 "Invalid Input: Must be TaxonEditorInput");
204 this.input
= (TaxonEditorInput
) input
;
207 // // Listen for name changes,
208 // // change tab for this taxon editor accordingly
209 // getTaxon().addPropertyChangeListener("name",
210 // new PropertyChangeListener() {
211 // public void propertyChange(PropertyChangeEvent e) {
215 // } catch (NullPointerException e) {
216 // EditorUtil.warn(getClass(), "Caught an NPE while initing an editor. This is most " +
217 // "likely due to the unsuccesful attempt to restore the former " +
218 // "state of the application. We ignore this because the workbench " +
219 // "will simply be reset.");
223 super.init(site
, input
);
227 * Calls <code>MultiPageEditorPart.setPartName(String partName)</code>
228 * with text appropriate to the state of the taxon: any taxon that has
229 * been saved will by necessity have a name to display; a new taxon
230 * should display "New taxon" in the editor tab.
232 protected void setPartName() {
234 String partName
= null;
235 TaxonNameBase
<?
, ?
> name
= getTaxon().getName();
238 partName
= name
.getTitleCache();
241 if (partName
== null || partName
.equals("")) {
242 partName
= ("New taxon");
245 setPartName(partName
);
251 * Editor pages call this in their postOperation to notify the MultiPageTaxonEditor
254 public void changed(Object element
) {
257 super.editorDirtyStateChanged();
258 if(element
instanceof TaxonBase
){
259 TaxonNameEditor page
= (TaxonNameEditor
) getPage(Page
.NAME
);
260 AbstractGroupedContainer container
= page
.getContainer((TaxonBase
) element
);
261 if(container
!= null){
268 * The accepted taxon that is the input for this editor
270 * @return the accepted taxon
272 public Taxon
getTaxon(){
273 return input
.getTaxon();
278 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
281 * <p>getConversationHolder</p>
283 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
285 public ConversationHolder
getConversationHolder() {
290 * <p>setConversationHolder</p>
292 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
294 public void setConversationHolder(ConversationHolder conversation
){
295 this.conversation
= conversation
;
300 * <p>Getter for the field <code>undoContext</code>.</p>
302 * @return a {@link org.eclipse.core.commands.operations.IUndoContext} object.
304 public IUndoContext
getUndoContext() {
309 * <p>Setter for the field <code>undoContext</code>.</p>
311 * @param undoContext a {@link org.eclipse.core.commands.operations.IUndoContext} object.
313 public void setUndoContext(IUndoContext undoContext
) {
314 this.undoContext
= undoContext
;
319 public void setFocus(){
320 //logger.warn("Setting focus to editor");
321 // bind the conversation
322 getConversationHolder().bind();
323 // pass focus to the active editor page
324 getActiveEditor().setFocus();
329 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
332 public void update(CdmDataChangeMap events
) {
333 if(dataChangeBehavior
== null){
334 dataChangeBehavior
= new MultiPageTaxonEditorDataChangeBehaviour(this);
337 DataChangeBridge
.handleDataChange(events
, dataChangeBehavior
);
343 * @see eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation()
346 public boolean postOperation(CdmBase objectAffectedByOperation
) {
349 for(IEditorPart editor
: this.getPages()){
350 if (editor
instanceof IPostOperationEnabled
) {
351 ((IPostOperationEnabled
) editor
).postOperation(objectAffectedByOperation
);
353 EditorUtil
.warn(getClass(), "postOperation not enabled for editor " + editor
);
356 EditorUtil
.warn(getClass(), "postOperation called on MultiPageTaxonEditor. Can you make it more specific?");
362 * Returns an <code>IEditorPart</code> implementation by type
364 * @param page the page type
365 * @return a {@link eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage} object.
367 public IMultiPageTaxonEditorPage
getPage(Page page
){
368 for(IEditorPart editor
: this.getPages()){
369 if(editor
.getClass().equals(page
.getClazz())){
370 return (IMultiPageTaxonEditorPage
) editor
;
377 * Return a list of <code>AbstractTaxonEditor</code>s registered with this
378 * <code>MultiPageTaxonEditor</code>.
380 * @return a {@link java.util.List} object.
382 public List
<IMultiPageTaxonEditorPage
> getPages(){
383 ArrayList
<IMultiPageTaxonEditorPage
> editors
= new ArrayList
<IMultiPageTaxonEditorPage
>();
384 for(int i
= 0; i
< this.getPageCount(); i
++){
386 editors
.add((IMultiPageTaxonEditorPage
) this.getEditor(i
));
392 * Refreshes a certain page of the MultipageTaxonEditor
394 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
397 public boolean redraw(Page page
){
398 return redraw(page
, true);
402 * Refreshes a certain page of the MultipageTaxonEditor and
403 * sets focus to that page
405 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
406 * @param focus a boolean.
409 public boolean redraw(Page page
, boolean focus
){
410 IMultiPageTaxonEditorPage editorPage
= getPage(page
);
411 return editorPage
!= null && editorPage
.redraw(focus
);
419 public boolean onComplete() {
424 * Reloads the data for this
426 public void reload() {
428 EditorUtil
.warningDialog("Editor has unsaved data", getClass(), "This editor can not be " +
429 "refreshed because it contains unsaved data. Refreshing " +
430 "this editor would discard the changes. Please save this editor, " +
431 "close and reopen it manually in order to get the latest content");
433 TaxonEditorInput input
= (TaxonEditorInput
) getEditorInput();
435 UUID uuid
= input
.getTaxonNode().getUuid();
437 conversation
.clear();
440 TaxonEditorInput newInput
= TaxonEditorInput
.NewInstance(uuid
);
442 for(IMultiPageTaxonEditorPage editorPart
: getPages()){
445 } catch (Exception e
) {
446 EditorUtil
.errorDialog("Error refreshing editor", getClass(), "Could not refresh this editor", e
);