148f0eef2a8b5f4320324d56fb8d6f4b5278239e
[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.util.ArrayList;
13 import java.util.List;
14
15 import org.eclipse.core.commands.operations.IUndoContext;
16 import org.eclipse.core.commands.operations.UndoContext;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.ui.IEditorInput;
19 import org.eclipse.ui.IEditorPart;
20 import org.eclipse.ui.IEditorSite;
21 import org.eclipse.ui.PartInitException;
22 import org.eclipse.ui.forms.editor.FormEditor;
23
24 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
25 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
26 import eu.etaxonomy.cdm.model.common.CdmBase;
27 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
28 import eu.etaxonomy.cdm.model.taxon.Taxon;
29 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
30 import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;
31 import eu.etaxonomy.taxeditor.model.DataChangeBridge;
32 import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
33 import eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider;
34 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
35 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
36
37 /**
38 *
39 * Generates the tabbed editor with <code>TaxonNameEditor</code> on top and tabs for
40 * "Descriptions", "Concepts", "Geography", etc.
41 *
42 * @author p.ciardelli
43 * @author n.hoffmann
44 * @created 15.05.2008
45 * @version 1.0
46 */
47 public class MultiPageTaxonEditor extends FormEditor implements IConversationEnabled, IPostOperationEnabled, IDirtyMarkableSelectionProvider, IPartContentHasDetails {
48
49 /** Constant <code>ID="eu.etaxonomy.taxeditor.editor.multipage"{trunked}</code> */
50 public static final String ID = "eu.etaxonomy.taxeditor.editor.multipagetaxonview";
51
52 private boolean dirty;
53
54 private ConversationHolder conversation;
55 private IDataChangeBehavior dataChangeBehavior;
56 private IUndoContext undoContext;
57
58 private TaxonEditorInput input;
59
60 /**
61 * <p>Constructor for MultiPageTaxonEditor.</p>
62 */
63 public MultiPageTaxonEditor() {
64 super();
65 undoContext = new UndoContext();
66 }
67
68 /** {@inheritDoc} */
69 @Override
70 public void dispose() {
71 conversation.unregisterForDataStoreChanges(this);
72 conversation.close();
73 super.dispose();
74 }
75
76 /* (non-Javadoc)
77 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
78 */
79 /** {@inheritDoc} */
80 @Override
81 protected void addPages() {
82 input = (TaxonEditorInput) getEditorInput();
83 conversation = input.getConversationHolder();
84 conversation.registerForDataStoreChanges(this);
85
86 try {
87 addPage(Page.NAME.getIndex(), new TaxonNameEditor(this), getEditorInput());
88 // setPageText(Page.NAME.getIndex(), Page.NAME.getTitle());
89
90 // TODO lazy create
91 // addPage(Page.DESCRIPTIVE.getIndex(), new TaxonDescriptionTreeEditor(this), getEditorInput());
92 // setPageText(Page.DESCRIPTIVE.getIndex(), Page.DESCRIPTIVE.getTitle());
93
94 // EditorUtil.showPropertySheet();
95
96 } catch (PartInitException e) {
97 EditorUtil.error(getClass(), e);
98 }
99 }
100
101
102 /** {@inheritDoc} */
103 @Override
104 public void doSave(IProgressMonitor monitor) {
105 monitor.beginTask("Saving Editor", 4);
106 try{
107 if( ! conversation.isBound()){
108 conversation.bind();
109 }
110 monitor.worked(1);
111
112 for(IEditorPart editorPage : getPages()){
113 if(editorPage instanceof TaxonNameEditor){
114 if(((TaxonNameEditor) editorPage).checkForEmptyNames()){
115 // abort
116 return;
117 }
118 }
119
120 editorPage.doSave(monitor);
121 monitor.worked(1);
122 }
123
124 // commit the conversation and start a new transaction immediately
125 conversation.commit(true);
126 monitor.worked(1);
127
128 this.setDirty(false);
129 monitor.worked(1);
130 }finally{
131 monitor.done();
132 }
133 }
134
135
136 private void setDirty(boolean dirty) {
137 this.dirty = dirty;
138 firePropertyChange(PROP_DIRTY);
139 }
140
141 /* (non-Javadoc)
142 * @see org.eclipse.ui.part.MultiPageEditorPart#isDirty()
143 */
144 /**
145 * <p>isDirty</p>
146 *
147 * @return a boolean.
148 */
149 public boolean isDirty() {
150 return dirty;
151 }
152
153 /* (non-Javadoc)
154 * @see org.eclipse.ui.forms.editor.FormEditor#editorDirtyStateChanged()
155 */
156 /** {@inheritDoc} */
157 @Override
158 public void editorDirtyStateChanged() {
159 dirty = true;
160 super.editorDirtyStateChanged();
161 }
162
163
164 /**
165 * {@inheritDoc}
166 *
167 * Checks whether nested editors are calling <code>firePropertyChange(PROP_DIRTY)</code>
168 * to signal an edit has taken place before passing property change along to
169 * <code>super.handlePropertyChange(int propertyId)</code>.
170 */
171 /* (non-Javadoc)
172 * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
173 */
174 protected void handlePropertyChange(int propertyId) {
175 if (propertyId == PROP_DIRTY) {
176 setDirty(true);
177 }
178 super.handlePropertyChange(propertyId);
179 }
180
181 /** {@inheritDoc} */
182 @Override
183 public void doSaveAs() {}
184
185 /** {@inheritDoc} */
186 @Override
187 public boolean isSaveAsAllowed() {
188 return false;
189 }
190
191 /** {@inheritDoc} */
192 @Override
193 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
194
195 if (!(input instanceof TaxonEditorInput))
196 throw new PartInitException(
197 "Invalid Input: Must be TaxonEditorInput");
198
199 this.input = (TaxonEditorInput) input;
200
201 // try {
202 // // Listen for name changes,
203 // // change tab for this taxon editor accordingly
204 // getTaxon().addPropertyChangeListener("name",
205 // new PropertyChangeListener() {
206 // public void propertyChange(PropertyChangeEvent e) {
207 // setPartName();
208 // }
209 // });
210 // } catch (NullPointerException e) {
211 // EditorUtil.warn(getClass(), "Caught an NPE while initing an editor. This is most " +
212 // "likely due to the unsuccesful attempt to restore the former " +
213 // "state of the application. We ignore this because the workbench " +
214 // "will simply be reset.");
215 // }
216 setPartName();
217
218 super.init(site, input);
219 }
220
221 /**
222 * Calls <code>MultiPageEditorPart.setPartName(String partName)</code>
223 * with text appropriate to the state of the taxon: any taxon that has
224 * been saved will by necessity have a name to display; a new taxon
225 * should display "New taxon" in the editor tab.
226 */
227 protected void setPartName() {
228
229 String partName = null;
230 TaxonNameBase<?, ?> name = getTaxon().getName();
231
232 if (name != null) {
233 partName = name.getTitleCache();
234 }
235
236 if (partName == null || partName.equals("")) {
237 partName = ("New taxon");
238 }
239
240 setPartName(partName);
241 }
242
243 /**
244 * {@inheritDoc}
245 *
246 * Editor pages call this in their postOperation to notify the MultiPageTaxonEditor
247 * of unsaved changes
248 */
249 public void changed(Object element) {
250 // setDirty(true);
251 dirty = true;
252 super.editorDirtyStateChanged();
253 TaxonNameEditor page = (TaxonNameEditor) getPage(Page.NAME);
254 page.getSelectedObject().refresh();
255 }
256
257 /**
258 * The accepted taxon that is the input for this editor
259 *
260 * @return the accepted taxon
261 */
262 public Taxon getTaxon(){
263 return input.getTaxon();
264 }
265
266 /*
267 * (non-Javadoc)
268 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
269 */
270 /**
271 * <p>getConversationHolder</p>
272 *
273 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
274 */
275 public ConversationHolder getConversationHolder() {
276 return conversation;
277 }
278
279 /**
280 * <p>setConversationHolder</p>
281 *
282 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
283 */
284 public void setConversationHolder(ConversationHolder conversation){
285 this.conversation = conversation;
286 }
287
288
289 /**
290 * <p>Getter for the field <code>undoContext</code>.</p>
291 *
292 * @return a {@link org.eclipse.core.commands.operations.IUndoContext} object.
293 */
294 public IUndoContext getUndoContext() {
295 return undoContext;
296 }
297
298 /**
299 * <p>Setter for the field <code>undoContext</code>.</p>
300 *
301 * @param undoContext a {@link org.eclipse.core.commands.operations.IUndoContext} object.
302 */
303 public void setUndoContext(IUndoContext undoContext) {
304 this.undoContext = undoContext;
305 }
306
307 /** {@inheritDoc} */
308 @Override
309 public void setFocus(){
310 //logger.warn("Setting focus to editor");
311 // bind the conversation
312 getConversationHolder().bind();
313 // pass focus to the active editor page
314 getActiveEditor().setFocus();
315 }
316
317 /*
318 * (non-Javadoc)
319 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
320 */
321 /** {@inheritDoc} */
322 public void update(CdmDataChangeMap events) {
323 if(dataChangeBehavior == null){
324 dataChangeBehavior = new MultiPageTaxonEditorDataChangeBehaviour(this);
325 }
326
327 DataChangeBridge.handleDataChange(events, dataChangeBehavior);
328 }
329
330
331 /*
332 * (non-Javadoc)
333 * @see eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation()
334 */
335 /** {@inheritDoc} */
336 public boolean postOperation(CdmBase objectAffectedByOperation) {
337 setDirty(true);
338
339 for(IEditorPart editor : this.getPages()){
340 if (editor instanceof IPostOperationEnabled) {
341 ((IPostOperationEnabled) editor).postOperation(objectAffectedByOperation);
342 } else {
343 EditorUtil.warn(getClass(), "postOperation not enabled for editor " + editor);
344 }
345 }
346 EditorUtil.warn(getClass(), "postOperation called on MultiPageTaxonEditor. Can you make it more specific?");
347
348 return false;
349 }
350
351 /**
352 * Returns an <code>IEditorPart</code> implementation by type
353 *
354 * @param page the page type
355 * @return a {@link eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage} object.
356 */
357 public IMultiPageTaxonEditorPage getPage(Page page){
358 for(IEditorPart editor : this.getPages()){
359 if(editor.getClass().equals(page.getClazz())){
360 return (IMultiPageTaxonEditorPage) editor;
361 }
362 }
363 return null;
364 }
365
366 /**
367 * Return a list of <code>AbstractTaxonEditor</code>s registered with this
368 * <code>MultiPageTaxonEditor</code>.
369 *
370 * @return a {@link java.util.List} object.
371 */
372 public List<IEditorPart> getPages(){
373 ArrayList<IEditorPart> editors = new ArrayList<IEditorPart>();
374 for(int i = 0; i < this.getPageCount(); i++){
375 editors.add(this.getEditor(i));
376 }
377 return editors;
378 }
379
380 /**
381 * Refreshes a certain page of the MultipageTaxonEditor
382 *
383 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
384 * @return a boolean.
385 */
386 public boolean redraw(Page page){
387 return redraw(page, true);
388 }
389
390 /**
391 * Refreshes a certain page of the MultipageTaxonEditor and
392 * sets focus to that page
393 *
394 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
395 * @param focus a boolean.
396 * @return a boolean.
397 */
398 public boolean redraw(Page page, boolean focus){
399 IMultiPageTaxonEditorPage editorPage = getPage(page);
400 return editorPage != null && editorPage.redraw(focus);
401 }
402
403 /**
404 * <p>onComplete</p>
405 *
406 * @return a boolean.
407 */
408 public boolean onComplete() {
409 // TODO Auto-generated method stub
410 return false;
411 }
412 }