fixes a bug that led to strange behavior when adding synonyms to a taxon
[taxeditor.git] / taxeditor-editor / src / main / java / eu / etaxonomy / taxeditor / editor / MultiPageTaxonEditor.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.taxeditor.editor;
11
12 import java.beans.PropertyChangeEvent;
13 import java.beans.PropertyChangeListener;
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.apache.log4j.Logger;
18 import org.eclipse.core.commands.operations.IUndoContext;
19 import org.eclipse.core.commands.operations.UndoContext;
20 import org.eclipse.core.runtime.IProgressMonitor;
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;
26
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.persistence.hibernate.CdmDataChangeMap;
33 import eu.etaxonomy.taxeditor.editor.descriptiontree.TaxonDescriptionTreeEditor;
34 import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;
35 import eu.etaxonomy.taxeditor.model.DataChangeBridge;
36 import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
37 import eu.etaxonomy.taxeditor.operations.IPostOperationEnabled;
38
39 /**
40 *
41 * Generates the tabbed editor with <code>TaxonNameEditor</code> on top and tabs for
42 * "Descriptions", "Concepts", "Geography", etc.
43 *
44 * @author p.ciardelli
45 * @author n.hoffmann
46 * @created 15.05.2008
47 * @version 1.0
48 */
49 //public class MultiPageTaxonEditor extends MultiPageEditorPart implements IConversationEnabled, IPostOperationEnabled {
50 public class MultiPageTaxonEditor extends FormEditor implements IConversationEnabled, IPostOperationEnabled {
51 private static final Logger logger = Logger.getLogger(MultiPageTaxonEditor.class);
52
53 public static final String ID = "eu.etaxonomy.taxeditor.editor.multipagetaxonview";
54
55 private boolean dirty;
56
57 private ConversationHolder conversation;
58 private IDataChangeBehavior dataChangeBehavior;
59 private IUndoContext undoContext;
60
61 private TaxonEditorInput input;
62
63 public MultiPageTaxonEditor() {
64 super();
65 undoContext = new UndoContext();
66 }
67
68
69
70 @Override
71 public void dispose() {
72 super.dispose();
73 // EditorUtil.checkHidePropertySheet();
74 }
75
76
77
78
79 /* (non-Javadoc)
80 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
81 */
82 @Override
83 protected void addPages() {
84 input = (TaxonEditorInput) getEditorInput();
85 conversation = input.getConversationHolder();
86 conversation.registerForDataStoreChanges(this);
87
88 try {
89 addPage(Page.NAME.getIndex(), new TaxonNameEditor(this), getEditorInput());
90 setPageText(Page.NAME.getIndex(), Page.NAME.getTitle());
91
92 // // TODO lazy create
93 // addPage(Page.DESCRIPTIVE.getIndex(), new TaxonDescriptionEditor(this), getEditorInput());
94 // setPageText(Page.DESCRIPTIVE.getIndex(), Page.DESCRIPTIVE.getTitle());
95
96 // // TODO lazy create
97 // addPage(Page.IMAGE.getIndex(), new TaxonImageEditor(this), getEditorInput());
98 // setPageText(Page.IMAGE.getIndex(), Page.IMAGE.getTitle());
99
100 // TODO lazy create
101 addPage(Page.DESCRIPTIVE.getIndex(), new TaxonDescriptionTreeEditor(this), getEditorInput());
102 // addPage(Page.DESCRIPTIVE_NEW.getIndex(), new TaxonDescriptionTreeEditor(this));
103 setPageText(Page.DESCRIPTIVE.getIndex(), Page.DESCRIPTIVE.getTitle());
104
105 EditorUtil.showPropertySheet();
106
107 } catch (PartInitException e) {
108 logger.error("Could not create MultiPageTaxonEditor.", e);
109 }
110 }
111
112 // @Override
113 // protected void createPages() {
114 //
115 //
116 // }
117
118 @Override
119 public void doSave(IProgressMonitor monitor) {
120
121 if( ! conversation.isBound()){
122 conversation.bind();
123 }
124
125 for(IEditorPart editorPage : getPages()){
126 if(editorPage instanceof TaxonNameEditor){
127 if(((TaxonNameEditor) editorPage).checkForEmptyNames()){
128 // abort
129 return;
130 }
131 }
132 editorPage.doSave(monitor);
133 }
134
135 // commit the conversation and start a new transaction immediately
136 conversation.commit(true);
137
138 this.setDirty(false);
139 }
140
141
142 private void setDirty(boolean dirty) {
143 this.dirty = dirty;
144 firePropertyChange(PROP_DIRTY);
145 }
146
147 /* (non-Javadoc)
148 * @see org.eclipse.ui.part.MultiPageEditorPart#isDirty()
149 */
150 public boolean isDirty() {
151 return dirty;
152 }
153
154 /* (non-Javadoc)
155 * @see org.eclipse.ui.forms.editor.FormEditor#editorDirtyStateChanged()
156 */
157 @Override
158 public void editorDirtyStateChanged() {
159 dirty = true;
160 super.editorDirtyStateChanged();
161 }
162
163 /**
164 * Checks whether nested editors are calling <code>firePropertyChange(PROP_DIRTY)</code>
165 * to signal an edit has taken place before passing property change along to
166 * <code>super.handlePropertyChange(int propertyId)</code>.
167 */
168 /* (non-Javadoc)
169 * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
170 */
171 protected void handlePropertyChange(int propertyId) {
172 if (propertyId == PROP_DIRTY) {
173 setDirty(true);
174 }
175 super.handlePropertyChange(propertyId);
176 }
177
178 @Override
179 public void doSaveAs() {}
180
181 @Override
182 public boolean isSaveAsAllowed() {
183 return false;
184 }
185
186 @Override
187 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
188
189 if (!(input instanceof TaxonEditorInput))
190 throw new PartInitException(
191 "Invalid Input: Must be TaxonEditorInput");
192
193 // FIXME looks like we do it differently now
194 // Get taxon from editor input
195 // if (input.getAdapter(Taxon.class) != null) {
196 // taxon = (Taxon) input.getAdapter(Taxon.class);
197 // } else {
198 // taxon = null;
199 // }
200
201 this.input = (TaxonEditorInput) input;
202
203 try {
204 // Listen for name changes,
205 // change tab for this taxon editor accordingly
206 getTaxon().addPropertyChangeListener("name",
207 new PropertyChangeListener() {
208 public void propertyChange(PropertyChangeEvent e) {
209 setPartName();
210 }
211 });
212 } catch (NullPointerException e) {
213 logger.warn("Caught an NPE while initing an editor. This is most " +
214 "likely due to the unsuccesful attempt to restore the former " +
215 "state of the application. We ignore this because the workbench " +
216 "will simply be reset.");
217 }
218 setPartName();
219
220 super.init(site, input);
221 }
222
223 /**
224 * Calls <code>MultiPageEditorPart.setPartName(String partName)</code>
225 * with text appropriate to the state of the taxon: any taxon that has
226 * been saved will by necessity have a name to display; a new taxon
227 * should display "New taxon" in the editor tab.
228 */
229 protected void setPartName() {
230
231 String partName = null;
232 TaxonNameBase<?, ?> name = getTaxon().getName();
233
234 if (name != null) {
235 partName = name.getTitleCache();
236 }
237
238 if (partName == null || partName.equals("")) {
239 partName = ("New taxon");
240 }
241
242 setPartName(partName);
243 }
244
245 /**
246 * Editor pages call this in their postOperation to notify the MultiPageTaxonEditor
247 * of unsaved changes
248 */
249 public void setDirty() {
250 setDirty(true);
251 }
252
253 public Taxon getTaxon(){
254 return input.getTaxon();
255 }
256
257 /*
258 * (non-Javadoc)
259 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
260 */
261 public ConversationHolder getConversationHolder() {
262 return conversation;
263 }
264
265 public void setConversationHolder(ConversationHolder conversation){
266 this.conversation = conversation;
267 }
268
269
270 public IUndoContext getUndoContext() {
271 return undoContext;
272 }
273
274 public void setUndoContext(IUndoContext undoContext) {
275 this.undoContext = undoContext;
276 }
277
278 @Override
279 public void setFocus(){
280 logger.warn("");
281 // bind the conversation
282 getConversationHolder().bind();
283 // pass focus to the active editor page
284 getActiveEditor().setFocus();
285 }
286
287 /*
288 * (non-Javadoc)
289 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
290 */
291 public void update(CdmDataChangeMap events) {
292 if(dataChangeBehavior == null){
293 dataChangeBehavior = new MultiPageTaxonEditorDataChangeBehaviour(this);
294 }
295
296 DataChangeBridge.handleDataChange(events, dataChangeBehavior);
297 }
298
299
300 /*
301 * (non-Javadoc)
302 * @see eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation()
303 */
304 public boolean postOperation(CdmBase objectAffectedByOperation) {
305 setDirty(true);
306
307 for(IEditorPart editor : this.getPages()){
308 if (editor instanceof IPostOperationEnabled) {
309 ((IPostOperationEnabled) editor).postOperation(objectAffectedByOperation);
310 } else {
311 logger.warn("postOperation not enabled for editor " + editor);
312 }
313 }
314 logger.warn("postOperation called on MultiPageTaxonEditor. Can you make it more specific?");
315
316 return false;
317 }
318
319 /**
320 * Returns an <code>AbstractTaxonEditor</code> implementation by type
321 *
322 * @param page the page type
323 * @return
324 */
325 public IEditorPart getPage(Page page){
326 for(IEditorPart editor : this.getPages()){
327 if(editor.getClass().equals(page.getClazz())){
328 return editor;
329 }
330 }
331 return null;
332 }
333
334 /**
335 * Return a list of <code>AbstractTaxonEditor</code>s registered with this
336 * <code>MultiPageTaxonEditor</code>.
337 *
338 * @return
339 */
340 public List<IEditorPart> getPages(){
341 ArrayList<IEditorPart> editors = new ArrayList<IEditorPart>();
342 for(int i = 0; i < this.getPageCount(); i++){
343 editors.add(this.getEditor(i));
344 }
345 return editors;
346 }
347 }