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