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