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