3f893ddf3a6f32e0b60f2b853013734d5ca7b882
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / EditorUtil.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.HashSet;
13 import java.util.Set;
14 import java.util.UUID;
15
16 import org.eclipse.core.commands.ExecutionEvent;
17 import org.eclipse.core.commands.operations.IOperationHistory;
18 import org.eclipse.core.commands.operations.IUndoContext;
19 import org.eclipse.jface.dialogs.MessageDialog;
20 import org.eclipse.jface.viewers.ISelection;
21 import org.eclipse.jface.viewers.IStructuredSelection;
22 import org.eclipse.jface.viewers.TreeNode;
23 import org.eclipse.swt.widgets.Shell;
24 import org.eclipse.ui.IEditorInput;
25 import org.eclipse.ui.IEditorPart;
26 import org.eclipse.ui.IEditorReference;
27 import org.eclipse.ui.IWorkbenchPage;
28 import org.eclipse.ui.PartInitException;
29 import org.eclipse.ui.handlers.HandlerUtil;
30
31 import eu.etaxonomy.cdm.api.service.ITaxonService;
32 import eu.etaxonomy.cdm.model.common.ITreeNode;
33 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
34 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
35 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
36 import eu.etaxonomy.cdm.model.taxon.Synonym;
37 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
38 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
39 import eu.etaxonomy.taxeditor.editor.group.authority.CdmAuthorityEditor;
40 import eu.etaxonomy.taxeditor.editor.group.authority.CdmAuthorityEditorInput;
41 import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
42 import eu.etaxonomy.taxeditor.editor.key.KeyEditor;
43 import eu.etaxonomy.taxeditor.editor.key.polytomous.PolytomousKeyEditorInput;
44 import eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditor;
45 import eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditorInput;
46 //import eu.etaxonomy.taxeditor.store.view.dataimport.BioCaseEditorInput;
47 //import eu.etaxonomy.taxeditor.view.dataimport.DataImportEditor;
48 //import eu.etaxonomy.taxeditor.view.dataimport.DataImportEditorInput;
49 //import eu.etaxonomy.taxeditor.view.dataimport.GbifImportEditor;
50 //import eu.etaxonomy.taxeditor.view.dataimport.GbifImportEditorInput;
51 //import eu.etaxonomy.taxeditor.view.dataimport.SpecimenImportEditor;
52 import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView;
53 import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateViewEditorInput;
54 import eu.etaxonomy.taxeditor.model.AbstractUtility;
55 import eu.etaxonomy.taxeditor.model.MessagingUtils;
56 import eu.etaxonomy.taxeditor.store.CdmStore;
57
58 /**
59 * Utility for the editor package
60 *
61 * @author n.hoffmann
62 * @created 20.01.2009
63 * @version 1.0
64 */
65 public class EditorUtil extends AbstractUtility {
66
67 private static boolean isSaving = false;
68
69 /**
70 * Opens a new editor window with the given input
71 *
72 * @param input
73 * @param editorId
74 * @return
75 * @return
76 * @throws PartInitException
77 */
78 private static IEditorPart open(final IEditorInput input,
79 final String editorId) throws PartInitException {
80 IEditorPart editor = getActivePage().openEditor(input, editorId);
81 if(input != null &&
82 editor.getEditorInput() != null &&
83 input != editor.getEditorInput() &&
84 input instanceof CdmEntitySessionInput) {
85 ((CdmEntitySessionInput)input).dispose();
86 }
87 return editor;
88 }
89
90 /**
91 * Opens a new editor window with the given TaxonEditorInput
92 *
93 * @param input
94 * a {@link eu.etaxonomy.taxeditor.editor.TaxonEditorInput}
95 * object.
96 * @throws org.eclipse.ui.PartInitException
97 * if any.
98 */
99 public static void open(TaxonEditorInput input) throws PartInitException {
100 open(input, MultiPageTaxonEditor.ID);
101 }
102
103 public static void open(PolytomousKeyEditorInput input)
104 throws PartInitException {
105 open(input, KeyEditor.ID);
106 }
107
108 public static void open(CdmAuthorityEditorInput input)
109 throws PartInitException {
110 open(input, CdmAuthorityEditor.ID);
111 }
112
113 /**
114 * Opens a new DerivateView for the given input
115 * @param input a {@link DerivateViewEditorInput} representing the selected derivate
116 * @throws PartInitException
117 */
118 public static void open(DerivateViewEditorInput input)
119 throws PartInitException {
120 open(input, DerivateView.ID);
121 }
122
123
124 /**
125 * Opens a new ChecklistView for the given input
126 * @param input a {@link ChecklistEditorInput} representing the selected checklist
127 * @throws PartInitException
128 */
129 public static void open(ChecklistEditorInput input)
130 throws PartInitException {
131 open(input, ChecklistEditor.ID);
132 }
133
134 /**
135 * Opens a new {@link DataImportEditor} for the given input
136 * @param input a {@link DataImportEditorInput}
137 * @throws PartInitException
138 */
139 // public static void open(DataImportEditorInput<?> input)
140 // throws PartInitException {
141 // if(input instanceof BioCaseEditorInput){
142 // open(input, SpecimenImportEditor.ID);
143 // }
144 // else if(input instanceof GbifImportEditorInput){
145 // open(input, GbifImportEditor.ID);
146 // }
147 // }
148
149 /**
150 * Taxon Editors may be opened by supplying a taxon node uuid. Session gets
151 * initialised here and is passed to the editor
152 *
153 * @param taxonNodeUuid
154 * a {@link java.util.UUID} object.
155 * @throws java.lang.Exception
156 * if any.
157 */
158 public static void openTaxonNode(UUID taxonNodeUuid) throws Exception {
159 TaxonEditorInput input = TaxonEditorInput.NewInstance(taxonNodeUuid);
160 open(input);
161 }
162
163 /**
164 * <p>
165 * openTaxonBase
166 * </p>
167 *
168 * @param taxonBaseUuid
169 * a {@link java.util.UUID} object.
170 * @throws org.eclipse.ui.PartInitException
171 * if any.
172 */
173 public static void openTaxonBase(UUID taxonBaseUuid)
174 throws PartInitException {
175 TaxonBase taxonBase = CdmStore.getService(ITaxonService.class).find(taxonBaseUuid);
176 if (taxonBase != null && taxonBase.isOrphaned()) {
177 if(taxonBase.isInstanceOf(Synonym.class)){
178 MessagingUtils.warningDialog("Orphaned accepted taxon", TaxonEditorInput.class, "The accepted "
179 + "taxon of this synonym is not part of any classification. Editing with the "
180 + "name editor is currently not implemented. Try to edit the taxon with the bulk editor.");
181 return;
182 }
183 else{
184 MessagingUtils.warningDialog("Orphaned Taxon", TaxonEditorInput.class, "This is an orphaned taxon "
185 + "i.e. a taxon that is not connected to a classification and not having any taxonomic "
186 + "relationships. Editing of orphaned taxa in the name editor is currently not supported. "
187 + "Try editing with the bulk editor");
188 return;
189 }
190 }
191 TaxonEditorInput input = TaxonEditorInput
192 .NewInstanceFromTaxonBase(taxonBaseUuid);
193 if(input!=null){
194 open(input);
195 }
196 }
197
198 /**
199 * <p>
200 * findEditorByTaxonNodeUuid
201 * </p>
202 *
203 * @param taxonNodeUuid
204 * a {@link java.util.UUID} object.
205 * @return a {@link org.eclipse.ui.IEditorPart} object.
206 * @throws java.lang.Exception
207 * if any.
208 */
209 public static IEditorPart findEditorByTaxonNodeUuid(UUID taxonNodeUuid)
210 throws Exception {
211 IEditorInput input = TaxonEditorInput.NewInstance(taxonNodeUuid);
212 return getActivePage().findEditor(input);
213 }
214
215 /**
216 * An uninitialized taxon is one that hasn't been saved yet. As such, it
217 * should appear in neither the list of recent names nor in the taxonomic
218 * tree when opened.
219 *
220 * @throws org.eclipse.ui.PartInitException
221 * if any.
222 * @param parentNodeUuid
223 * a {@link java.util.UUID} object.
224 */
225 public static void openEmpty(UUID parentNodeUuid) throws PartInitException {
226 TaxonEditorInput input = TaxonEditorInput
227 .NewEmptyInstance(parentNodeUuid);
228 open(input, MultiPageTaxonEditor.ID);
229
230 getActiveMultiPageTaxonEditor().changed(null);
231
232 }
233
234 /**
235 * <p>
236 * setSaving
237 * </p>
238 *
239 * @param isSaving
240 * a boolean.
241 */
242 public static void setSaving(boolean isSaving) {
243 EditorUtil.isSaving = isSaving;
244 }
245
246 /**
247 * <p>
248 * isSaving
249 * </p>
250 *
251 * @return a boolean.
252 */
253 public static boolean isSaving() {
254 return isSaving;
255 }
256
257 /**
258 * Returns a set of all currently open <code>MultiPageTaxonEditor</code>s.
259 *
260 * @return a {@link java.util.Set} object.
261 */
262 public static Set<IEditorPart> getOpenEditors() {
263 Set<IEditorPart> taxonEditors = new HashSet<IEditorPart>();
264
265 if (getActivePage() != null) {
266 for (IEditorReference reference : getActivePage()
267 .getEditorReferences()) {
268 IEditorPart editor = reference.getEditor(false);
269 if (editor instanceof MultiPageTaxonEditor) {
270 taxonEditors.add(editor);
271 }
272 }
273 }
274
275 return taxonEditors;
276 }
277
278 /**
279 * Returns the currently active taxon editor
280 *
281 * @return the taxon editor that has focus
282 */
283 public static MultiPageTaxonEditor getActiveMultiPageTaxonEditor() {
284 IEditorPart editorPart = getActiveEditor();
285 if (editorPart != null && editorPart instanceof MultiPageTaxonEditor) {
286 MultiPageTaxonEditor editor = (MultiPageTaxonEditor) editorPart;
287 editor.getConversationHolder().bind();
288 return editor;
289 }
290 return null;
291 }
292
293 /**
294 * <p>
295 * getActiveEditorPage
296 * </p>
297 *
298 * @param page
299 * a {@link eu.etaxonomy.taxeditor.editor.Page} object.
300 * @return a {@link org.eclipse.ui.IEditorPart} object.
301 */
302 public static IEditorPart getActiveEditorPage(Page page) {
303 MultiPageTaxonEditor editor = getActiveMultiPageTaxonEditor();
304
305 return editor != null ? editor.getPage(page) : null;
306 }
307
308 /**
309 * Returns the selection of the currently active taxon editor
310 *
311 * @return a {@link org.eclipse.jface.viewers.ISelection} object.
312 */
313 public static ISelection getCurrentSelection() {
314 if (getActiveMultiPageTaxonEditor() == null) {
315 return null;
316 } else {
317 return getActiveMultiPageTaxonEditor().getSite()
318 .getSelectionProvider().getSelection();
319 }
320 }
321
322 /**
323 * <p>
324 * getUndoContext
325 * </p>
326 *
327 * @param editor
328 * a {@link eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor}
329 * object.
330 * @return a {@link org.eclipse.core.commands.operations.IUndoContext}
331 * object.
332 */
333 public static IUndoContext getUndoContext(MultiPageTaxonEditor editor) {
334 return editor.getUndoContext();
335 }
336
337 /**
338 * <p>
339 * getUndoContext
340 * </p>
341 *
342 * @return a {@link org.eclipse.core.commands.operations.IUndoContext}
343 * object.
344 */
345 public static IUndoContext getUndoContext() {
346 return IOperationHistory.GLOBAL_UNDO_CONTEXT;
347 }
348
349 /**
350 * <p>
351 * forceUserSave
352 * </p>
353 *
354 * @param editor
355 * a {@link org.eclipse.ui.IEditorPart} object.
356 * @param shell
357 * a {@link org.eclipse.swt.widgets.Shell} object.
358 * @return a boolean.
359 */
360 public static boolean forceUserSave(IEditorPart editor, Shell shell) {
361 if (editor.isDirty()) {
362
363 boolean doSave = MessageDialog
364 .openConfirm(shell, "Confirm save",
365 "Warning - this operation will save the editor. This will also save all other unsaved changes " +
366 "in your working editor to the database. Please 'Cancel' if you are not ready to do this.");
367
368 if (!doSave) {
369 return false;
370 }
371
372 editor.doSave(AbstractUtility.getMonitor());
373 }
374 return true;
375 }
376
377 /**
378 * <p>
379 * getSelection
380 * </p>
381 *
382 * @param event
383 * a {@link org.eclipse.core.commands.ExecutionEvent} object.
384 * @return a {@link org.eclipse.jface.viewers.IStructuredSelection} object.
385 */
386 public static IStructuredSelection getSelection(ExecutionEvent event) {
387 IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
388
389 return (IStructuredSelection) activeEditor.getSite()
390 .getSelectionProvider().getSelection();
391 }
392
393 /**
394 * <p>
395 * getPluginId
396 * </p>
397 *
398 * @return a {@link java.lang.String} object.
399 */
400 public static String getPluginId() {
401 return TaxeditorEditorPlugin.PLUGIN_ID;
402 }
403
404 public static void openPolytomousKey(UUID polytomousKeyUuid)
405 throws Exception {
406 PolytomousKeyEditorInput input = PolytomousKeyEditorInput
407 .NewInstance(polytomousKeyUuid);
408 open(input);
409 }
410
411 // public static void openPolytomousKeyEditor(UUID polytomousKeyUuid, String name)
412 // throws Exception {
413 // PolytomousKeyEditorInput input = new PolytomousKeyEditorInput(polytomousKeyUuid, name);
414 // open(input);
415 // }
416
417 public static void openCdmAuthorities(UUID groupUuid)
418 throws Exception {
419 CdmAuthorityEditorInput input = CdmAuthorityEditorInput.NewInstance(groupUuid);
420 open(input);
421 }
422
423 /**
424 * Iterates recursively over all originals having the given specimen as a derivate.
425 * The first {@link DerivedUnit} with no more originals or the first {@link FieldUnit} is returned
426 * @param specimen the start element for which the originals are iterated recursively
427 * @return either a FieldUnit or a the topmost DerivedUnit (which can be itself)
428 */
429 public static SpecimenOrObservationBase<?> getTopMostDerivate(SpecimenOrObservationBase<?> specimen){
430 if(specimen.isInstanceOf(FieldUnit.class)){
431 return specimen;
432 }
433 else if(specimen instanceof DerivedUnit
434 && ((DerivedUnit) specimen).getOriginals()!=null
435 && !((DerivedUnit) specimen).getOriginals().isEmpty()){
436 for(SpecimenOrObservationBase<?> original:((DerivedUnit) specimen).getOriginals()){
437 return getTopMostDerivate(original);
438 }
439 //needed to add this for compilation although this is unreachable
440 return specimen;
441 }
442 else{
443 return specimen;
444 }
445 }
446
447 /**
448 * If the current selection is a single {@link TreeNode} it will be returned.
449 * @param selection the selection to check
450 * @return the selected TreeNode or <code>null</code> if no TreeNode selected
451 */
452 public static TreeNode getTreeNodeOfSelection(ISelection selection){
453 if(selection instanceof IStructuredSelection
454 && ((IStructuredSelection) selection).size()==1
455 && ((IStructuredSelection) selection).getFirstElement() instanceof TreeNode){
456 return (TreeNode) ((IStructuredSelection) selection).getFirstElement();
457
458 }
459 return null;
460 }
461
462 /**
463 * Opens a taxon editor for the given object if the given object is a valid input.
464 * @param object the object for which the editor will be opened
465 * @throws PartInitException
466 */
467 public static void openTaxonEditor(Object object) throws PartInitException {
468 if(object instanceof TaxonBase<?>){
469 openTaxonBase(((TaxonBase<?>) object).getUuid());
470 }
471 }
472
473 public static boolean closeObsoleteEditor(TaxonNode taxonNode, IWorkbenchPage activePage){
474 boolean result = true;
475 for (IEditorReference ref : activePage.getEditorReferences()) {
476 try {
477 String treeIndex = ((ITreeNode)taxonNode).treeIndex();
478
479
480 IEditorInput input = ref.getEditorInput();
481 if (input instanceof TaxonEditorInput) {
482 TaxonNode node = ((TaxonEditorInput) input).getTaxonNode();
483 //if node is a child of taxonNode then close the editor
484 if( ((ITreeNode) node).treeIndex().startsWith(treeIndex)){
485 //if (taxonNode.equals(node)) {
486 result &= activePage.closeEditor(ref.getEditor(false), true);
487
488 }
489 }
490 } catch (PartInitException e) {
491 continue;
492 }
493 }
494 return result;
495 }
496 }