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