Merge branch 'release/4.11.0'
[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.Collection;
13 import java.util.UUID;
14
15 import org.eclipse.core.commands.ExecutionEvent;
16 import org.eclipse.core.commands.operations.IOperationHistory;
17 import org.eclipse.core.commands.operations.IUndoContext;
18 import org.eclipse.e4.ui.model.application.MApplication;
19 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
20 import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
21 import org.eclipse.e4.ui.workbench.modeling.EModelService;
22 import org.eclipse.e4.ui.workbench.modeling.EPartService;
23 import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
24 import org.eclipse.jface.dialogs.MessageDialog;
25 import org.eclipse.jface.viewers.ISelection;
26 import org.eclipse.jface.viewers.IStructuredSelection;
27 import org.eclipse.jface.viewers.TreeNode;
28 import org.eclipse.swt.widgets.Shell;
29 import org.eclipse.ui.IEditorPart;
30 import org.eclipse.ui.PartInitException;
31 import org.eclipse.ui.handlers.HandlerUtil;
32
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.e4.TaxonEditorInputE4;
40 import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
41 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
42 import eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4;
43 import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView;
44 import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateViewEditorInput;
45 import eu.etaxonomy.taxeditor.model.AbstractUtility;
46 import eu.etaxonomy.taxeditor.model.MessagingUtils;
47 import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
48
49 /**
50 * Utility for the editor package
51 *
52 * @author n.hoffmann
53 * @created 20.01.2009
54 * @version 1.0
55 */
56 public class EditorUtil extends AbstractUtility {
57
58 private static final String NAME_EDITOR_ID = "eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4";
59 private static boolean isSaving = false;
60
61 /**
62 * Opens a new {@link DataImportEditor} for the given input
63 * @param input a {@link DataImportEditorInput}
64 * @throws PartInitException
65 */
66 // public static void open(DataImportEditorInput<?> input)
67 // throws PartInitException {
68 // if(input instanceof BioCaseEditorInput){
69 // open(input, SpecimenImportEditor.ID);
70 // }
71 // else if(input instanceof GbifImportEditorInput){
72 // open(input, GbifImportEditor.ID);
73 // }
74 // }
75
76 public static void openSpecimenEditor(DerivateViewEditorInput input, EModelService modelService, EPartService partService, MApplication application){
77 MPart part = partService.createPart(AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DERIVATE_DERIVATEVIEW);
78 MPartStack editorAreaPartStack = WorkbenchUtility.getEditorAreaPartStack(application, modelService);
79 if(editorAreaPartStack!=null){
80 editorAreaPartStack.getChildren().add(part);
81 }
82 part = partService.showPart(part, PartState.ACTIVATE);
83 DerivateView derivateView = (DerivateView) part.getObject();
84 derivateView.init(input);
85 }
86
87 public static void openTaxonNodeE4(UUID taxonNodeUuid, EModelService modelService, EPartService partService, MApplication application) {
88 TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstance(taxonNodeUuid);
89 openNameEditor_internal(input, modelService, partService, application);
90 }
91
92 public static void openTaxonBaseE4(UUID taxonBaseUuid, EModelService modelService, EPartService partService, MApplication application) {
93 TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(taxonBaseUuid);
94 openNameEditor_internal(input, modelService, partService, application);
95 }
96
97 public static void openTaxonBaseE4(UUID taxonBaseUuid) {
98 //FIXME E4 this can probably be removed when fully migrated
99 TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(taxonBaseUuid);
100
101 EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
102 EModelService modelService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EModelService.class);
103 openNameEditor_internal(input, modelService, partService, null);
104 }
105
106 private static void openNameEditor_internal(TaxonEditorInputE4 input, EModelService modelService, EPartService partService, MApplication application) {
107 TaxonBase taxonBase = input.getTaxon();
108 if(taxonBase==null){
109 return;
110 }
111 if (taxonBase.isOrphaned()) {
112 if(taxonBase.isInstanceOf(Synonym.class)){
113 MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON_MESSAGE);
114 return;
115 }
116 else{
117 MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_TAXON_MESSAGE);
118 return;
119 }
120 }
121
122 Collection<MPart> parts = partService.getParts();
123 //check if part is already opened
124 for (MPart part : parts) {
125 if(part.getObject() instanceof TaxonNameEditorE4
126 && ((TaxonNameEditorE4) part.getObject()).getTaxon()!=null
127 && ((TaxonNameEditorE4) part.getObject()).getTaxon().equals(input.getTaxon())){
128 //close part to invoke refresh for new part
129 partService.hidePart(part);
130 break;
131 }
132 }
133 MPart part = partService.createPart(NAME_EDITOR_ID);
134
135 MPartStack editorAreaPartStack = WorkbenchUtility.getEditorAreaPartStack(application, modelService);
136 if(editorAreaPartStack!=null){
137 editorAreaPartStack.getChildren().add(part);
138 }
139 part = partService.showPart(part, PartState.ACTIVATE);
140
141 TaxonNameEditorE4 editor = (TaxonNameEditorE4) part.getObject();
142 editor.init(input);
143 }
144
145 /**
146 * An uninitialized taxon is one that hasn't been saved yet. As such, it
147 * should appear in neither the list of recent names nor in the taxonomic
148 * tree when opened.
149 *
150 * @param parentNodeUuid
151 * a {@link java.util.UUID} object.
152 */
153 public static void openEmptyE4(UUID parentNodeUuid) {
154 TaxonEditorInputE4 input = TaxonEditorInputE4
155 .NewEmptyInstance(parentNodeUuid);
156 EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
157 MPart part = partService.createPart(NAME_EDITOR_ID);
158 part = partService.showPart(part, PartState.ACTIVATE);
159 TaxonNameEditorE4 editor = (TaxonNameEditorE4) part.getObject();
160 editor.init(input);
161 }
162
163 /**
164 * <p>
165 * setSaving
166 * </p>
167 *
168 * @param isSaving
169 * a boolean.
170 */
171 public static void setSaving(boolean isSaving) {
172 EditorUtil.isSaving = isSaving;
173 }
174
175 /**
176 * <p>
177 * isSaving
178 * </p>
179 *
180 * @return a boolean.
181 */
182 public static boolean isSaving() {
183 return isSaving;
184 }
185
186 /**
187 * <p>
188 * getUndoContext
189 * </p>
190 *
191 * @return a {@link org.eclipse.core.commands.operations.IUndoContext}
192 * object.
193 */
194 public static IUndoContext getUndoContext() {
195 return IOperationHistory.GLOBAL_UNDO_CONTEXT;
196 }
197
198 /**
199 * <p>
200 * forceUserSave
201 * </p>
202 *
203 * @param editor
204 * a {@link org.eclipse.ui.IEditorPart} object.
205 * @param shell
206 * a {@link org.eclipse.swt.widgets.Shell} object.
207 * @return a boolean.
208 */
209 public static boolean forceUserSave(IEditorPart editor, Shell shell) {
210 if (editor.isDirty()) {
211
212 boolean doSave = MessageDialog
213 .openConfirm(shell, Messages.EditorUtil_COMFIRM_SAVE,
214 Messages.EditorUtil_CONFIRM_SAVE_MESSAGE);
215
216 if (!doSave) {
217 return false;
218 }
219
220 editor.doSave(AbstractUtility.getMonitor());
221 }
222 return true;
223 }
224
225 public static boolean forceUserSaveE4Editor(TaxonNameEditorE4 editor, Shell shell) {
226 if (editor.isDirty()) {
227
228 boolean doSave = MessageDialog
229 .openConfirm(shell, Messages.EditorUtil_COMFIRM_SAVE,
230 Messages.EditorUtil_CONFIRM_SAVE_MESSAGE);
231
232 if (!doSave) {
233 return false;
234 }
235
236 editor.save(AbstractUtility.getMonitor());
237 }
238 return true;
239 }
240
241 /**
242 * <p>
243 * getSelection
244 * </p>
245 *
246 * @param event
247 * a {@link org.eclipse.core.commands.ExecutionEvent} object.
248 * @return a {@link org.eclipse.jface.viewers.IStructuredSelection} object.
249 */
250 public static IStructuredSelection getSelection(ExecutionEvent event) {
251 IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
252
253 return (IStructuredSelection) activeEditor.getSite()
254 .getSelectionProvider().getSelection();
255 }
256
257 /**
258 * <p>
259 * getPluginId
260 * </p>
261 *
262 * @return a {@link java.lang.String} object.
263 */
264 public static String getPluginId() {
265 return TaxeditorEditorPlugin.PLUGIN_ID;
266 }
267
268 /**
269 * Iterates recursively over all originals having the given specimen as a derivate.
270 * The first {@link DerivedUnit} with no more originals or the first {@link FieldUnit} is returned
271 * @param specimen the start element for which the originals are iterated recursively
272 * @return either a FieldUnit or a the topmost DerivedUnit (which can be itself)
273 */
274 public static SpecimenOrObservationBase<?> getTopMostDerivate(SpecimenOrObservationBase<?> specimen){
275 if(specimen.isInstanceOf(FieldUnit.class)){
276 return specimen;
277 }
278 else if(specimen instanceof DerivedUnit
279 && ((DerivedUnit) specimen).getOriginals()!=null
280 && !((DerivedUnit) specimen).getOriginals().isEmpty()){
281 for(SpecimenOrObservationBase<?> original:((DerivedUnit) specimen).getOriginals()){
282 return getTopMostDerivate(original);
283 }
284 //needed to add this for compilation although this is unreachable
285 return specimen;
286 }
287 else{
288 return specimen;
289 }
290 }
291
292 /**
293 * If the current selection is a single {@link TreeNode} it will be returned.
294 * @param selection the selection to check
295 * @return the selected TreeNode or <code>null</code> if no TreeNode selected
296 */
297 public static TreeNode getTreeNodeOfSelection(ISelection selection){
298 if(selection instanceof IStructuredSelection
299 && ((IStructuredSelection) selection).size()==1
300 && ((IStructuredSelection) selection).getFirstElement() instanceof TreeNode){
301 return (TreeNode) ((IStructuredSelection) selection).getFirstElement();
302
303 }
304 return null;
305 }
306
307 public static void closeObsoleteEditor(TaxonNode taxonNode, EPartService partService){
308 String treeIndex = taxonNode.treeIndex();
309 Collection<MPart> parts = partService.getParts();
310 for (MPart part : parts) {
311 Object object = part.getObject();
312 if(object instanceof TaxonNameEditorE4){
313 TaxonNameEditorE4 taxonEditor = (TaxonNameEditorE4)object;
314 TaxonNode node = taxonEditor.getEditorInput().getTaxonNode();
315 if(node.treeIndex().startsWith(treeIndex)){
316 partService.hidePart(part, true);
317 }
318 }
319 }
320 }
321 }