d521cb585f24b6e965419b40c5bb6eacaa439101
[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.IEditorSite;
23 import org.eclipse.ui.PartInitException;
24 import org.eclipse.ui.part.MultiPageEditorPart;
25
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.persistence.hibernate.CdmDataChangeMap;
32 import eu.etaxonomy.taxeditor.editor.description.TaxonDescriptionEditor;
33 import eu.etaxonomy.taxeditor.editor.images.TaxonImageEditor;
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 private static final Logger logger = Logger.getLogger(MultiPageTaxonEditor.class);
51
52 public static final String ID = "eu.etaxonomy.taxeditor.editor.multipagetaxonview";
53
54 private boolean dirty;
55
56 private ConversationHolder conversation;
57 private IDataChangeBehavior dataChangeBehavior;
58 private IUndoContext undoContext;
59
60 private TaxonEditorInput input;
61
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 @Override
77 protected void createPages() {
78
79 input = (TaxonEditorInput) getEditorInput();
80 conversation = input.getConversationHolder();
81 conversation.registerForDataStoreChanges(this);
82
83 try {
84 addPage(Page.NAME.getIndex(), new TaxonNameEditor(this), getEditorInput());
85 setPageText(Page.NAME.getIndex(), Page.NAME.getTitle());
86
87 // TODO lazy create
88 addPage(Page.DESCRIPTIVE.getIndex(), new TaxonDescriptionEditor(this), getEditorInput());
89 setPageText(Page.DESCRIPTIVE.getIndex(), Page.DESCRIPTIVE.getTitle());
90
91 // TODO lazy create
92 addPage(Page.IMAGE.getIndex(), new TaxonImageEditor(this), getEditorInput());
93 setPageText(Page.IMAGE.getIndex(), Page.IMAGE.getTitle());
94
95 // EditorUtil.showPropertySheet();
96
97 } catch (PartInitException e) {
98 logger.error("Could not create MultiPageTaxonEditor.", e);
99 }
100 }
101
102 @Override
103 public void doSave(IProgressMonitor monitor) {
104
105 if( ! conversation.isBound()){
106 conversation.bind();
107 }
108
109 // commit the conversation and start a new transaction immediately
110 conversation.commit(true);
111
112 this.setDirty(false);
113 }
114
115 private void setDirty(boolean dirty) {
116 this.dirty = dirty;
117 firePropertyChange(PROP_DIRTY);
118 }
119
120 /* (non-Javadoc)
121 * @see org.eclipse.ui.part.MultiPageEditorPart#isDirty()
122 */
123 public boolean isDirty() {
124 return dirty;
125 }
126
127 /**
128 * Checks whether nested editors are calling <code>firePropertyChange(PROP_DIRTY)</code>
129 * to signal an edit has taken place before passing property change along to
130 * <code>super.handlePropertyChange(int propertyId)</code>.
131 */
132 /* (non-Javadoc)
133 * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
134 */
135 protected void handlePropertyChange(int propertyId) {
136 if (propertyId == PROP_DIRTY) {
137 setDirty(true);
138 }
139 super.handlePropertyChange(propertyId);
140 }
141
142 @Override
143 public void doSaveAs() {}
144
145 @Override
146 public boolean isSaveAsAllowed() {
147 return false;
148 }
149
150 @Override
151 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
152
153 if (!(input instanceof TaxonEditorInput))
154 throw new PartInitException(
155 "Invalid Input: Must be TaxonEditorInput");
156
157 // FIXME looks like we do it differently now
158 // Get taxon from editor input
159 // if (input.getAdapter(Taxon.class) != null) {
160 // taxon = (Taxon) input.getAdapter(Taxon.class);
161 // } else {
162 // taxon = null;
163 // }
164
165 this.input = (TaxonEditorInput) input;
166
167 try {
168 // Listen for name changes,
169 // change tab for this taxon editor accordingly
170 getTaxon().addPropertyChangeListener("name",
171 new PropertyChangeListener() {
172 public void propertyChange(PropertyChangeEvent e) {
173 setPartName();
174 }
175 });
176 } catch (NullPointerException e) {
177 logger.warn("Caught an NPE while initing an editor. This is most " +
178 "likely due to the unsuccesful attempt to restore the former " +
179 "state of the application. We ignore this because the workbench " +
180 "will simply be reset.");
181 }
182 setPartName();
183
184 super.init(site, input);
185 }
186
187 /**
188 * Calls <code>MultiPageEditorPart.setPartName(String partName)</code>
189 * with text appropriate to the state of the taxon: any taxon that has
190 * been saved will by necessity have a name to display; a new taxon
191 * should display "New taxon" in the editor tab.
192 */
193 protected void setPartName() {
194
195 String partName = null;
196 TaxonNameBase<?, ?> name = getTaxon().getName();
197
198 if (name != null) {
199 partName = name.getTitleCache();
200 }
201
202 if (partName == null || partName.equals("")) {
203 partName = ("New taxon");
204 }
205
206 setPartName(partName);
207 }
208
209 /**
210 * Editor pages call this in their postOperation to notify the MultiPageTaxonEditor
211 * of unsaved changes
212 */
213 public void setDirty() {
214 setDirty(true);
215 }
216
217 public Taxon getTaxon(){
218 return input.getTaxon();
219 }
220
221 /*
222 * (non-Javadoc)
223 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
224 */
225 public ConversationHolder getConversationHolder() {
226 return conversation;
227 }
228
229 public void setConversationHolder(ConversationHolder conversation){
230 this.conversation = conversation;
231 }
232
233
234 public IUndoContext getUndoContext() {
235 return undoContext;
236 }
237
238 public void setUndoContext(IUndoContext undoContext) {
239 this.undoContext = undoContext;
240 }
241
242 @Override
243 public void setFocus(){
244 // bind the conversation
245 getConversationHolder().bind();
246 // pass focus to the active editor page
247 getActiveEditorPage().setFocus();
248 }
249
250 public AbstractTaxonEditor getActiveEditorPage(){
251 return (AbstractTaxonEditor) getEditor(getActivePage());
252 }
253
254 /*
255 * (non-Javadoc)
256 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
257 */
258 public void update(CdmDataChangeMap events) {
259 if(dataChangeBehavior == null){
260 dataChangeBehavior = new MultiPageTaxonEditorDataChangeBehaviour(this);
261 }
262
263 DataChangeBridge.handleDataChange(events, dataChangeBehavior);
264 }
265
266
267 /*
268 * (non-Javadoc)
269 * @see eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation()
270 */
271 public boolean postOperation(CdmBase objectAffectedByOperation) {
272 setDirty(true);
273
274 for(AbstractTaxonEditor editor : this.getPages()){
275 editor.postOperation(objectAffectedByOperation);
276 }
277 logger.warn("postOperation called on MultiPageTaxonEditor. Can you make it more specific?");
278
279 return false;
280 }
281
282 /**
283 * Returns an <code>AbstractTaxonEditor</code> implementation by type
284 *
285 * @param page the page type
286 * @return
287 */
288 public AbstractTaxonEditor getPage(Page page){
289 for(AbstractTaxonEditor editor : this.getPages()){
290 if(editor.getClass().equals(page.getClazz())){
291 return editor;
292 }
293 }
294 return null;
295 }
296
297 /**
298 * Return a list of <code>AbstractTaxonEditor</code>s registered with this
299 * <code>MultiPageTaxonEditor</code>.
300 *
301 * @return
302 */
303 public List<AbstractTaxonEditor> getPages(){
304 ArrayList<AbstractTaxonEditor> editors = new ArrayList<AbstractTaxonEditor>();
305 for(int i = 0; i < this.getPageCount(); i++){
306 editors.add((AbstractTaxonEditor) this.getEditor(i));
307 }
308 return editors;
309 }
310 }