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