Merge branch 'release/5.10.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.HashSet;
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.MApplication;
20 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
21 import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
22 import org.eclipse.e4.ui.workbench.modeling.EModelService;
23 import org.eclipse.e4.ui.workbench.modeling.EPartService;
24 import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
25 import org.eclipse.jface.dialogs.MessageDialog;
26 import org.eclipse.jface.viewers.ISelection;
27 import org.eclipse.jface.viewers.IStructuredSelection;
28 import org.eclipse.jface.viewers.TreeNode;
29 import org.eclipse.swt.widgets.Shell;
30 import org.eclipse.ui.IEditorPart;
31 import org.eclipse.ui.handlers.HandlerUtil;
32
33 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
34 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
35 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
36 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
37 import eu.etaxonomy.cdm.model.taxon.Synonym;
38 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
39 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
40 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
41 import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
42 import eu.etaxonomy.taxeditor.bulkeditor.input.TaxonEditorInput;
43 import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.DescriptiveDataSetEditor;
44 import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix.CharacterMatrixPart;
45 import eu.etaxonomy.taxeditor.editor.e4.TaxonEditorInputE4;
46 import eu.etaxonomy.taxeditor.editor.group.authority.CdmAuthorityEditorInput;
47 import eu.etaxonomy.taxeditor.editor.group.authority.e4.CdmAuthorityEditorE4;
48 import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
49 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
50 import eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4;
51 import eu.etaxonomy.taxeditor.editor.view.checklist.e4.DistributionEditorPart;
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.workbench.WorkbenchUtility;
57 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
58
59 /**
60 * Utility for the editor package
61 *
62 * @author n.hoffmann
63 * @created 20.01.2009
64 * @version 1.0
65 */
66 public class EditorUtil extends AbstractUtility {
67
68 private static final String NAME_EDITOR_ID = "eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4";
69
70 private static boolean factsVisible = true;
71
72 private static boolean mediaVisible = true;
73
74 public static void openDescriptiveDataSetEditor(UUID descriptiveDataSetUuid, EModelService modelService, EPartService partService, MApplication application){
75 Collection<MPart> parts = partService.getParts();
76 for (MPart part : parts) {
77 if(part.getObject() instanceof DescriptiveDataSetEditor
78 && ((DescriptiveDataSetEditor) part.getObject()).getDescriptiveDataSet().getUuid().equals(descriptiveDataSetUuid)){
79 partService.showPart(part, PartState.ACTIVATE);
80 return;
81 }
82 }
83 String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVEDATASET_DESCRIPTIVEDATASETEDITOR;
84 MPart part = showPart(partId, modelService, partService, application);
85 DescriptiveDataSetEditor editor = (DescriptiveDataSetEditor) part.getObject();
86 editor.init(descriptiveDataSetUuid);
87 }
88
89 public static void openCharacterMatrix(UUID descriptiveDataSetUuid, EModelService modelService, EPartService partService, MApplication application){
90 Collection<MPart> parts = partService.getParts();
91 for (MPart part : parts) {
92 if(part.getObject() instanceof CharacterMatrixPart
93 && ((CharacterMatrixPart) part.getObject()).getDescriptiveDataSet().getUuid().equals(descriptiveDataSetUuid)){
94 partService.showPart(part, PartState.ACTIVATE);
95 return;
96 }
97 }
98 String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_DESCRIPTIVEDATASET_MATRIX_CHARACTERMATRIXPART;
99 MPart part = showPart(partId, modelService, partService, application);
100 CharacterMatrixPart editor = (CharacterMatrixPart) part.getObject();
101 editor.init(descriptiveDataSetUuid, true);
102 }
103
104 public static void openDistributionEditor(UUID parentTaxonUuid, EModelService modelService, EPartService partService, MApplication application){
105 Collection<MPart> parts = partService.getParts();
106 String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_CHECKLIST_E4_DISTRIBUTIONEDITORPART;
107 String partIdFactualData = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4;
108 String partIdMedia = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4;
109 MPart part1 = partService.findPart(AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4);
110 if (part1.getWidget() != null){
111 factsVisible = true;
112 }else{
113 factsVisible = false;
114 }
115 part1 = partService.findPart(AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4);
116 if (part1.getWidget() != null){
117 mediaVisible = true;
118 }else{
119 mediaVisible = false;
120 }
121 closePart(partIdMedia, partService);
122 closePart(partIdFactualData, partService);
123 MPart part = showPart(partId, modelService, partService, application);
124 DistributionEditorPart editor = (DistributionEditorPart) part.getObject();
125 editor.init(parentTaxonUuid);
126 }
127
128
129 public static void openSpecimenEditor(DerivateViewEditorInput input, EModelService modelService, EPartService partService, MApplication application){
130 String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DERIVATE_DERIVATEVIEW;
131 MPart part = showPart(partId, modelService, partService, application);
132 DerivateView derivateView = (DerivateView) part.getObject();
133 derivateView.init(input);
134 }
135
136 public static void openRightsEditor(CdmAuthorityEditorInput input, EModelService modelService, EPartService partService, MApplication application){
137 Collection<MPart> parts = partService.getParts();
138 for (MPart part : parts) {
139 if(part.getObject() instanceof CdmAuthorityEditorE4
140 && ((CdmAuthorityEditorE4) part.getObject()).getInput().getGroup().equals(input.getGroup())){
141 partService.showPart(part, PartState.ACTIVATE);
142 return;
143 }
144 }
145 String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_GROUP_AUTHORITY_E4_CDMAUTHORITYEDITORE4;
146 MPart part = showPart(partId, modelService, partService, application);
147 CdmAuthorityEditorE4 authorityView = (CdmAuthorityEditorE4) part.getObject();
148 authorityView.init(input);
149 }
150
151 public static MPart showPart(String partId, EModelService modelService, EPartService partService, MApplication application){
152 MPart part = partService.findPart(partId);
153 if(part==null || modelService.getPartDescriptor(partId).isAllowMultiple()){
154 part = partService.createPart(partId);
155 }
156 MPartStack editorAreaPartStack = WorkbenchUtility.getEditorAreaPartStack(application, modelService);
157 if(editorAreaPartStack!=null){
158 editorAreaPartStack.getChildren().add(part);
159 }
160 return partService.showPart(part, PartState.ACTIVATE);
161 }
162
163 public static MPart showPart(String partId, EModelService modelService, EPartService partService){
164 MPart part = partService.findPart(partId);
165 if(part==null || modelService.getPartDescriptor(partId).isAllowMultiple()){
166 part = partService.createPart(partId);
167 partService.activate(part);
168 }else{
169 partService.activate(part);
170 }
171
172 return part;
173 }
174
175 public static void openTaxonNodeE4(UUID taxonNodeUuid, EModelService modelService, EPartService partService, MApplication application) {
176 TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstance(taxonNodeUuid);
177 openNameEditor_internal(input, modelService, partService, application);
178 }
179
180 public static void openTaxonBaseE4(UUID taxonBaseUuid, EModelService modelService, EPartService partService, MApplication application) {
181 TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(taxonBaseUuid);
182 openNameEditor_internal(input, modelService, partService, application);
183 }
184
185 public static void openTaxonBaseE4(UUID taxonBaseUuid) {
186 //FIXME E4 this can probably be removed when fully migrated
187 TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(taxonBaseUuid);
188
189 EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
190 EModelService modelService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EModelService.class);
191 openNameEditor_internal(input, modelService, partService, null);
192 }
193
194 private static void openNameEditor_internal(TaxonEditorInputE4 input, EModelService modelService, EPartService partService, MApplication application) {
195 TaxonBase taxonBase = input.getTaxon();
196 if(taxonBase==null){
197 return;
198 }
199 if (taxonBase.isOrphaned()) {
200 if(taxonBase.isInstanceOf(Synonym.class)){
201 MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON_MESSAGE);
202 return;
203 }
204 else{
205 MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_TAXON_MESSAGE);
206 return;
207 }
208 }
209
210 Collection<MPart> parts = partService.getParts();
211 //check if part is already opened
212 for (MPart part : parts) {
213 if(part.getObject() instanceof TaxonNameEditorE4
214 && ((TaxonNameEditorE4) part.getObject()).getTaxon()!=null
215 && ((TaxonNameEditorE4) part.getObject()).getTaxon().getUuid().equals(input.getTaxon().getUuid())){
216 if (part.isDirty()){
217 forceUserSaveE4Editor(((TaxonNameEditorE4) part.getObject()), getShell());
218 }
219 partService.hidePart(part);
220 break;
221 }
222 }
223 MPart part = showPart(NAME_EDITOR_ID, modelService, partService, application);
224
225 TaxonNameEditorE4 editor = (TaxonNameEditorE4) part.getObject();
226 editor.init(input);
227 MPart part1 = partService.findPart(AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4);
228 if (factsVisible){
229 String partIdFactualData = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4;
230 showPart(partIdFactualData, modelService, partService);
231 factsVisible = false;
232 }
233 part1 = partService.findPart(AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4);
234 if (mediaVisible){
235 String partIdFactualData = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4;
236 showPart(partIdFactualData, modelService, partService);
237 mediaVisible = false;
238 }
239 // String partIdFactualData = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4;
240 // String partIdMedia = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4;
241 // showPart(partIdMedia, modelService, partService);
242 // showPart(partIdFactualData, modelService, partService);
243 editor.setFocus();
244 }
245
246 public static Collection<MPart> checkForChanges(UUID taxonUUID, EPartService partService ){
247 Collection<MPart> parts = partService.getParts();
248 Collection<MPart> dirtyParts = new HashSet();
249 //check if part is already opened
250 boolean isDirty = false;
251 for (MPart part : parts) {
252 if(part.getObject() instanceof TaxonNameEditorE4
253 && ((TaxonNameEditorE4) part.getObject()).getTaxon()!=null
254 && ((TaxonNameEditorE4) part.getObject()).getTaxon().getUuid().equals(taxonUUID)){
255 if (part.isDirty()){
256 dirtyParts.add(part);
257 }
258
259 break;
260 }else if (taxonUUID == null){
261 if (part.isDirty()){
262 dirtyParts.add(part);
263 }
264 }
265 }
266 return dirtyParts;
267 }
268
269 public static Collection<IE4SavablePart> checkForTaxonChanges(UUID taxonUUID, EPartService partService ){
270 Collection<MPart> parts = partService.getParts();
271 Collection<IE4SavablePart> dirtyParts = new HashSet<>();
272 //check if part is already opened
273 for (MPart part : parts) {
274 if(part.getObject() instanceof TaxonNameEditorE4
275 && ((TaxonNameEditorE4) part.getObject()).getTaxon()!=null
276 && ((TaxonNameEditorE4) part.getObject()).getTaxon().getUuid().equals(taxonUUID)){
277 if (part.isDirty()){
278 dirtyParts.add((IE4SavablePart) part);
279 }
280
281 break;
282 }else if (taxonUUID == null){
283 if (part.isDirty() && (part.getObject() instanceof TaxonNameEditorE4 || (part.getObject() instanceof BulkEditorE4 && ((BulkEditorE4)part.getObject()).getEditorInput() instanceof TaxonEditorInput))){
284 dirtyParts.add((IE4SavablePart) part);
285 }
286 }
287 }
288 return dirtyParts;
289 }
290
291 /**
292 * An uninitialized taxon is one that hasn't been saved yet. As such, it
293 * should appear in neither the list of recent names nor in the taxonomic
294 * tree when opened.
295 *
296 * @param parentNodeUuid
297 * a {@link java.util.UUID} object.
298 */
299 public static void openEmptyE4(UUID parentNodeUuid) {
300 TaxonEditorInputE4 input = TaxonEditorInputE4
301 .NewEmptyInstance(parentNodeUuid);
302 EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
303 MPart part = partService.createPart(NAME_EDITOR_ID);
304 part = partService.showPart(part, PartState.ACTIVATE);
305 TaxonNameEditorE4 editor = (TaxonNameEditorE4) part.getObject();
306 editor.init(input);
307 }
308
309 /**
310 * <p>
311 * getUndoContext
312 * </p>
313 *
314 * @return a {@link org.eclipse.core.commands.operations.IUndoContext}
315 * object.
316 */
317 public static IUndoContext getUndoContext() {
318 return IOperationHistory.GLOBAL_UNDO_CONTEXT;
319 }
320
321 /**
322 * <p>
323 * forceUserSave
324 * </p>
325 *
326 * @param editor
327 * a {@link org.eclipse.ui.IEditorPart} object.
328 * @param shell
329 * a {@link org.eclipse.swt.widgets.Shell} object.
330 * @return a boolean.
331 */
332 public static boolean forceUserSave(IEditorPart editor, Shell shell) {
333 if (editor.isDirty()) {
334
335 boolean doSave = MessageDialog
336 .openConfirm(shell, Messages.EditorUtil_COMFIRM_SAVE,
337 Messages.EditorUtil_CONFIRM_SAVE_MESSAGE);
338
339 if (!doSave) {
340 return false;
341 }
342
343 editor.doSave(AbstractUtility.getMonitor());
344 }
345 return true;
346 }
347
348 public static boolean forceUserSaveE4Editor(TaxonNameEditorE4 editor, Shell shell) {
349 if (editor.isDirty()) {
350
351 boolean doSave = MessageDialog
352 .openConfirm(shell, Messages.EditorUtil_COMFIRM_SAVE,
353 Messages.EditorUtil_CONFIRM_SAVE_MESSAGE);
354
355 if (!doSave) {
356 return false;
357 }
358
359 editor.save(AbstractUtility.getMonitor());
360 }
361 return true;
362 }
363
364 /**
365 * <p>
366 * getSelection
367 * </p>
368 *
369 * @param event
370 * a {@link org.eclipse.core.commands.ExecutionEvent} object.
371 * @return a {@link org.eclipse.jface.viewers.IStructuredSelection} object.
372 */
373 public static IStructuredSelection getSelection(ExecutionEvent event) {
374 IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
375
376 return (IStructuredSelection) activeEditor.getSite()
377 .getSelectionProvider().getSelection();
378 }
379
380 /**
381 * <p>
382 * getPluginId
383 * </p>
384 *
385 * @return a {@link java.lang.String} object.
386 */
387 public static String getPluginId() {
388 return TaxeditorEditorPlugin.PLUGIN_ID;
389 }
390
391 /**
392 * Iterates recursively over all originals having the given specimen as a derivate.
393 * The first {@link DerivedUnit} with no more originals or the first {@link FieldUnit} is returned
394 * @param specimen the start element for which the originals are iterated recursively
395 * @return either a FieldUnit or a the topmost DerivedUnit (which can be itself)
396 */
397 public static SpecimenOrObservationBase<?> getTopMostDerivate(SpecimenOrObservationBase<?> specimen){
398 if(specimen==null){
399 return null;
400 }
401 if(specimen.isInstanceOf(FieldUnit.class)){
402 return specimen;
403 }
404 else if(specimen.isInstanceOf(DerivedUnit.class)){
405 DerivedUnit derivedUnit = HibernateProxyHelper.deproxy(specimen, DerivedUnit.class);
406 if(derivedUnit.getOriginals()!=null
407 && !(derivedUnit.getOriginals().isEmpty())){
408 for(SpecimenOrObservationBase<?> original:((DerivedUnit) specimen).getOriginals()){
409 return getTopMostDerivate(original);
410 }
411 }
412 }
413 return specimen;
414 }
415
416 /**
417 * If the current selection is a single {@link TreeNode} it will be returned.
418 * @param selection the selection to check
419 * @return the selected TreeNode or <code>null</code> if no TreeNode selected
420 */
421 public static TreeNode getTreeNodeOfSelection(ISelection selection){
422 if(selection instanceof IStructuredSelection
423 && ((IStructuredSelection) selection).size()==1
424 && ((IStructuredSelection) selection).getFirstElement() instanceof TreeNode){
425 return (TreeNode) ((IStructuredSelection) selection).getFirstElement();
426
427 }
428 return null;
429 }
430
431 public static void closeObsoleteEditor(TaxonNodeDto taxonNode, EPartService partService){
432 String treeIndex = taxonNode.getTreeIndex();
433 Collection<MPart> parts = partService.getParts();
434 for (MPart part : parts) {
435 Object object = part.getObject();
436 if(object instanceof TaxonNameEditorE4){
437 TaxonNameEditorE4 taxonEditor = (TaxonNameEditorE4)object;
438 TaxonNode node = taxonEditor.getEditorInput().getTaxonNode();
439 if (node.treeIndex()!= null){
440 if(node.treeIndex().startsWith(treeIndex)){
441 if (part.isDirty()){
442 forceUserSaveE4Editor(taxonEditor, getShell());
443 }
444 partService.hidePart(part);
445 }
446 }else{
447 logger.debug("The taxonnode of taxon " + node.getTaxon().getTitleCache() + " uuid: " + node.getUuid() + " has no treeindex");;
448 }
449 }
450 }
451 }
452
453
454 public static void closePart(String partID, EPartService partService){
455
456 Collection<MPart> parts = partService.getParts();
457 for (MPart part : parts) {
458 String elementId = part.getElementId();
459 if (elementId.equals(partID)){
460 partService.hidePart(part);
461 }
462 }
463 }
464
465 public static void updateEditor(TaxonNode taxonNode, TaxonNameEditorE4 editor){
466 String treeIndex = taxonNode.treeIndex();
467 TaxonNode node = editor.getEditorInput().getTaxonNode();
468 if(node.treeIndex().equals(treeIndex)){
469 TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstance(node.getUuid());
470 editor.init(input);
471
472
473 }
474 }
475
476 }