Project

General

Profile

Download (12.3 KB) Statistics
| Branch: | Tag: | Revision:
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
import java.util.UUID;
15

    
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;
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.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;
40

    
41
/**
42
 *
43
 * Generates the tabbed editor with <code>TaxonNameEditor</code> on top and tabs for
44
 *  "Descriptions", "Concepts", "Geography", etc.
45
 *
46
 * @author p.ciardelli
47
 * @author n.hoffmann
48
 * @created 15.05.2008
49
 * @version 1.0
50
 */
51
public class MultiPageTaxonEditor extends FormEditor implements IConversationEnabled, IPostOperationEnabled, IDirtyMarkableSelectionProvider, IPartContentHasDetails {	
52

    
53
	/** Constant <code>ID="eu.etaxonomy.taxeditor.editor.taxon"{trunked}</code> */
54
	public static final String ID = "eu.etaxonomy.taxeditor.editor.taxon";
55

    
56
	private boolean dirty;
57

    
58
	private ConversationHolder conversation;
59
	private IDataChangeBehavior dataChangeBehavior;
60
	private IUndoContext undoContext;
61

    
62
	private TaxonEditorInput input;
63
	
64
	/**
65
	 * <p>Constructor for MultiPageTaxonEditor.</p>
66
	 */
67
	public MultiPageTaxonEditor() {
68
		super();		
69
		undoContext = new UndoContext();
70
	}
71
	
72
	/** {@inheritDoc} */
73
	@Override
74
	public void dispose() {
75
		conversation.unregisterForDataStoreChanges(this);
76
		conversation.close();
77
		super.dispose();		
78
	}
79

    
80
	/* (non-Javadoc)
81
	 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
82
	 */
83
	/** {@inheritDoc} */
84
	@Override
85
	protected void addPages() {
86
		input = (TaxonEditorInput) getEditorInput();
87
		conversation = input.getConversationHolder();
88
		conversation.registerForDataStoreChanges(this);
89
		
90
		try {
91
			addPage(Page.NAME.getIndex(), new TaxonNameEditor(this), getEditorInput());
92
//			setPageText(Page.NAME.getIndex(), Page.NAME.getTitle());
93
			
94
			// TODO lazy create
95
//			addPage(Page.DESCRIPTIVE.getIndex(), new TaxonDescriptionTreeEditor(this), getEditorInput());
96
//			setPageText(Page.DESCRIPTIVE.getIndex(), Page.DESCRIPTIVE.getTitle());
97
			
98
//			EditorUtil.showPropertySheet();
99
					
100
		} catch (PartInitException e) {
101
			EditorUtil.error(getClass(), e);
102
		}
103
	}
104
	
105
	
106
	/** {@inheritDoc} */
107
	@Override
108
	public void doSave(IProgressMonitor monitor) {
109
		monitor.beginTask("Saving Editor", 4);
110
		try{
111
			if( ! conversation.isBound()){
112
				conversation.bind();
113
			}
114
			monitor.worked(1);
115
			
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.");
121
						return;
122
					}
123
				}
124
	
125
				editorPage.doSave(monitor);
126
				monitor.worked(1);
127
			}
128
			
129
			// commit the conversation and start a new transaction immediately
130
			conversation.commit(true);
131
			monitor.worked(1);
132
			
133
			this.setDirty(false);
134
			monitor.worked(1);
135
		}finally{
136
			monitor.done();
137
		}
138
	}
139

    
140

    
141
	private void setDirty(boolean dirty) {
142
		this.dirty = dirty;
143
		firePropertyChange(PROP_DIRTY);
144
	}
145
	
146
	/* (non-Javadoc)
147
	 * @see org.eclipse.ui.part.MultiPageEditorPart#isDirty()
148
	 */
149
	/**
150
	 * <p>isDirty</p>
151
	 *
152
	 * @return a boolean.
153
	 */
154
	public boolean isDirty() {
155
		return dirty;
156
	}
157

    
158
	/* (non-Javadoc)
159
	 * @see org.eclipse.ui.forms.editor.FormEditor#editorDirtyStateChanged()
160
	 */
161
	/** {@inheritDoc} */
162
	@Override
163
	public void editorDirtyStateChanged() {
164
		dirty = true;
165
		super.editorDirtyStateChanged();
166
	}
167
	
168
	
169
	/**
170
	 * {@inheritDoc}
171
	 *
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>.
175
	 */
176
	/* (non-Javadoc)
177
	 * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int)
178
	 */
179
	protected void handlePropertyChange(int propertyId) {
180
		if (propertyId == PROP_DIRTY) {
181
			setDirty(true);
182
		}
183
		super.handlePropertyChange(propertyId);
184
	}
185
	
186
	/** {@inheritDoc} */
187
	@Override
188
	public void doSaveAs() {}
189

    
190
	/** {@inheritDoc} */
191
	@Override
192
	public boolean isSaveAsAllowed() {
193
		return false;
194
	}
195

    
196
	/** {@inheritDoc} */
197
	@Override
198
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
199
		
200
		if (!(input instanceof TaxonEditorInput))
201
			throw new PartInitException(
202
					"Invalid Input: Must be TaxonEditorInput");
203
		
204
		this.input = (TaxonEditorInput) input;
205

    
206
//		try {
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) {
212
//							setPartName();
213
//						}
214
//					});
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.");
220
//		}
221
		setPartName();
222
		
223
		super.init(site, input);
224
	}
225
		
226
    /**
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.
231
     */
232
    protected void setPartName() {
233
        
234
    	String partName = null; 
235
//    	TaxonNameBase<?, ?> name = getTaxon().getName();
236
//    	
237
//    	if (name != null) {
238
//    		partName = name.getTitleCache();
239
//    	}
240
    	
241
    	if (partName == null || partName.equals("")) {
242
    		partName = ("New taxon");
243
    	}
244

    
245
        setPartName(partName);
246
    }
247
    
248
    /**
249
     * {@inheritDoc}
250
     *
251
     * Editor pages call this in their postOperation to notify the MultiPageTaxonEditor
252
     * of unsaved changes
253
     */
254
    public void changed(Object element) {
255
//    	setDirty(true);
256
		dirty = true;
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){
262
				container.refresh();
263
			}
264
		}
265
    }
266
    
267
    /**
268
     * The accepted taxon that is the input for this editor
269
     *
270
     * @return the accepted taxon
271
     */
272
    public Taxon getTaxon(){
273
    	return input.getTaxon();
274
    }
275

    
276
    /*
277
     * (non-Javadoc)
278
     * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
279
     */
280
	/**
281
	 * <p>getConversationHolder</p>
282
	 *
283
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
284
	 */
285
	public ConversationHolder getConversationHolder() {
286
		return conversation;
287
	}
288
	
289
	/**
290
	 * <p>setConversationHolder</p>
291
	 *
292
	 * @param conversation a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
293
	 */
294
	public void setConversationHolder(ConversationHolder conversation){
295
		this.conversation = conversation;
296
	}
297

    
298

    
299
	/**
300
	 * <p>Getter for the field <code>undoContext</code>.</p>
301
	 *
302
	 * @return a {@link org.eclipse.core.commands.operations.IUndoContext} object.
303
	 */
304
	public IUndoContext getUndoContext() {
305
		return undoContext;
306
	}
307

    
308
	/**
309
	 * <p>Setter for the field <code>undoContext</code>.</p>
310
	 *
311
	 * @param undoContext a {@link org.eclipse.core.commands.operations.IUndoContext} object.
312
	 */
313
	public void setUndoContext(IUndoContext undoContext) {
314
		this.undoContext = undoContext;
315
	}
316
	
317
	/** {@inheritDoc} */
318
	@Override
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();
325
	}
326

    
327
	/*
328
	 * (non-Javadoc)
329
	 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostCrudObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
330
	 */
331
	/** {@inheritDoc} */
332
	public void update(CdmDataChangeMap events) {
333
		if(dataChangeBehavior == null){
334
			dataChangeBehavior = new MultiPageTaxonEditorDataChangeBehaviour(this);
335
		}
336
		
337
		DataChangeBridge.handleDataChange(events, dataChangeBehavior);
338
	}
339

    
340

    
341
	/*
342
	 * (non-Javadoc)
343
	 * @see eu.etaxonomy.taxeditor.store.operations.IPostOperationEnabled#postOperation()
344
	 */
345
	/** {@inheritDoc} */
346
	public boolean postOperation(CdmBase objectAffectedByOperation) {
347
		setDirty(true);
348
		
349
		for(IEditorPart editor : this.getPages()){
350
			if (editor instanceof IPostOperationEnabled) {
351
				((IPostOperationEnabled) editor).postOperation(objectAffectedByOperation);
352
			} else {
353
				EditorUtil.warn(getClass(), "postOperation not enabled for editor " + editor);
354
			}
355
		}
356
		EditorUtil.warn(getClass(), "postOperation called on MultiPageTaxonEditor. Can you make it more specific?");
357
		
358
		return false;
359
	}
360
	
361
	/**
362
	 * Returns an <code>IEditorPart</code> implementation by type
363
	 *
364
	 * @param page the page type
365
	 * @return a {@link eu.etaxonomy.taxeditor.editor.IMultiPageTaxonEditorPage} object.
366
	 */
367
	public IMultiPageTaxonEditorPage getPage(Page page){
368
		for(IEditorPart editor : this.getPages()){
369
		 	if(editor.getClass().equals(page.getClazz())){
370
		 		return (IMultiPageTaxonEditorPage) editor;
371
		 	}
372
		}
373
		return null;
374
	}
375
	
376
	/**
377
	 * Return a list of <code>AbstractTaxonEditor</code>s registered with this
378
	 * <code>MultiPageTaxonEditor</code>.
379
	 *
380
	 * @return a {@link java.util.List} object.
381
	 */
382
	public List<IMultiPageTaxonEditorPage> getPages(){
383
		ArrayList<IMultiPageTaxonEditorPage> editors = new ArrayList<IMultiPageTaxonEditorPage>();
384
		for(int i = 0; i < this.getPageCount(); i++){
385
			
386
		 	editors.add((IMultiPageTaxonEditorPage) this.getEditor(i));
387
		}
388
		return editors;
389
	}
390
	
391
	/**
392
	 * Refreshes a certain page of the MultipageTaxonEditor
393
	 *
394
	 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
395
	 * @return a boolean.
396
	 */
397
	public boolean redraw(Page page){
398
		return redraw(page, true);
399
	}
400
	
401
	/**
402
	 * Refreshes a certain page of the MultipageTaxonEditor and
403
	 * sets focus to that page
404
	 *
405
	 * @param page a {@link eu.etaxonomy.taxeditor.editor.Page} object.
406
	 * @param focus a boolean.
407
	 * @return a boolean.
408
	 */
409
	public boolean redraw(Page page, boolean focus){
410
		IMultiPageTaxonEditorPage editorPage = getPage(page);
411
		return editorPage != null && editorPage.redraw(focus);
412
	}
413

    
414
	/**
415
	 * <p>onComplete</p>
416
	 *
417
	 * @return a boolean.
418
	 */
419
	public boolean onComplete() {
420
		return false;
421
	}
422

    
423
	/**
424
	 * Reloads the data for this 
425
	 */
426
	public void reload() {
427
		if(isDirty()){
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");
432
		}else{
433
			TaxonEditorInput input = (TaxonEditorInput) getEditorInput();
434
			
435
			UUID uuid = input.getTaxonNode().getUuid();
436
			
437
			conversation.clear();
438
			
439
			try {
440
				TaxonEditorInput newInput = TaxonEditorInput.NewInstance(uuid);
441
				setInput(newInput);
442
				for(IMultiPageTaxonEditorPage editorPart : getPages()){
443
					editorPart.redraw();
444
				}
445
			} catch (Exception e) {
446
				EditorUtil.errorDialog("Error refreshing editor", getClass(), "Could not refresh this editor", e);
447
			}
448
		}
449
	}
450
}
(6-6/15)