fixes 777
[taxeditor.git] / taxeditor-navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / NavigationUtil.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.navigation;
11
12 import java.util.HashSet;
13 import java.util.Set;
14 import java.util.UUID;
15
16 import org.apache.log4j.Logger;
17 import org.eclipse.core.commands.ExecutionEvent;
18 import org.eclipse.core.commands.ExecutionException;
19 import org.eclipse.core.commands.operations.IOperationHistory;
20 import org.eclipse.core.commands.operations.IUndoContext;
21 import org.eclipse.core.commands.operations.IUndoableOperation;
22 import org.eclipse.core.commands.operations.UndoContext;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Status;
26 import org.eclipse.jface.action.IStatusLineManager;
27 import org.eclipse.jface.viewers.ISelection;
28 import org.eclipse.jface.viewers.StructuredSelection;
29 import org.eclipse.jface.viewers.TreeSelection;
30 import org.eclipse.swt.widgets.Shell;
31 import org.eclipse.ui.IEditorReference;
32 import org.eclipse.ui.IWorkbenchWindow;
33 import org.eclipse.ui.PartInitException;
34 import org.eclipse.ui.handlers.HandlerUtil;
35 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
36 import org.eclipse.ui.navigator.CommonViewer;
37
38 import eu.etaxonomy.cdm.model.taxon.Synonym;
39 import eu.etaxonomy.cdm.model.taxon.Taxon;
40 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
41 import eu.etaxonomy.taxeditor.editor.EditorUtil;
42 import eu.etaxonomy.taxeditor.editor.TaxonEditorInput;
43 import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
44 import eu.etaxonomy.taxeditor.model.AbstractUtility;
45 import eu.etaxonomy.taxeditor.navigation.internal.TaxeditorNavigationPlugin;
46 import eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator;
47
48 /**
49 * @author n.hoffmann
50 * @created 24.03.2009
51 * @version 1.0
52 */
53 public class NavigationUtil extends AbstractUtility{
54 private static final Logger logger = Logger.getLogger(NavigationUtil.class);
55 private static IStatusLineManager statusLineManager;
56 private static IUndoContext defaultUndoContext;
57
58 /**
59 * FIXME Introduces a dependency on eu.etaxonomy.taxeditor.editor. This is highly undesirable.
60 *
61 * It is not clear at the moment by what mechanics we are going to open the
62 * editor. I would prefer some sort of resource model that has the editor linked
63 * to the resource type of taxonbase. Another reason to switch to CommonNavigatorFamework
64 *
65 * @param uuid
66 */
67 public static void openEditor(TaxonNode selection) {
68 try {
69 UUID entityUuid = selection.getUuid();
70 EditorUtil.open(entityUuid);
71 } catch (PartInitException e) {
72 logger.error("Error opening the editor", e);
73 }
74 }
75
76 public static Shell getShell() {
77 return getActiveWindow().getShell();
78 }
79
80 public static IWorkbenchWindow getActiveWindow() {
81 return TaxeditorNavigationPlugin.getDefault().getWorkbench().
82 getActiveWorkbenchWindow();
83 }
84
85 public static void openEmpty(TaxonNode parentTaxonNode) {
86 try {
87 UUID parentTaxonNodeUuid = parentTaxonNode == null ? null : parentTaxonNode.getUuid();
88
89 EditorUtil.openEmpty(parentTaxonNodeUuid);
90 } catch (PartInitException e) {
91 logger.error("Error opening the editor", e);
92 }
93 }
94
95 public static IOperationHistory getWorkbenchOperationHistory() {
96 return TaxeditorEditorPlugin.getDefault().getWorkbench().
97 getOperationSupport().getOperationHistory();
98 }
99
100 public static IUndoContext getWorkbenchUndoContext() {
101 return TaxeditorEditorPlugin.getDefault().getWorkbench().
102 getOperationSupport().getUndoContext();
103 }
104
105 public static void executeOperation(IUndoableOperation operation){
106 try {
107 IStatus status = getWorkbenchOperationHistory().execute(operation, getMonitor(),
108 WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
109 String statusString = status.equals(Status.OK_STATUS) ? "completed" : "cancelled";
110 setStatusLine(operation.getLabel() + " " + statusString + ".");
111 } catch (ExecutionException e) {
112 logger.error("Error executing operation: " + operation.getLabel(), e);
113 }
114 }
115
116 private static IProgressMonitor getMonitor() {
117 statusLineManager.setCancelEnabled(false);
118 return statusLineManager.getProgressMonitor();
119 }
120
121 public static void setStatusLineManager(IStatusLineManager manager) {
122 statusLineManager = manager;
123 }
124
125 public static void setStatusLine(String message) {
126 statusLineManager.setMessage(message);
127 }
128
129
130 /**
131 * Returns the selected taxon for referencing in context menus
132 *
133 * @param event
134 * @return
135 */
136 public static TaxonNode getCurrentSelection(ExecutionEvent event){
137
138 ISelection menuSelection = HandlerUtil.getActiveMenuSelection(event);
139
140 // The selection should always be a tree selection since we are in the
141 // taxonomic tree view. Just in case this will be used in another spot.
142 if(menuSelection instanceof TreeSelection){
143 TaxonNode taxonNode = (TaxonNode) ((TreeSelection) menuSelection).getFirstElement();
144 logger.debug("Selected taxon: " + taxonNode);
145 return taxonNode;
146 }
147 return null;
148 }
149
150 public static IUndoContext getUndoContext() {
151 // FIXME this has to be more specific. Every widget has to have its own undo context
152 // return IOperationHistory.GLOBAL_UNDO_CONTEXT;
153
154 // Plug-ins that wish their operations to be undoable from workbench views
155 // such as the Navigator or Package Explorer should assign the workbench
156 // undo context to their operations.
157 if (defaultUndoContext == null) {
158 defaultUndoContext = new UndoContext();
159 }
160 return defaultUndoContext;
161 }
162
163 /**
164 * Whether a taxonNode has unsaved changes.
165 *
166 * @param taxonNode
167 * @return
168 */
169 public static boolean isDirty(TaxonNode taxonNode){
170
171 for (IEditorReference reference : getActivePage().getEditorReferences()) {
172 TaxonEditorInput editorInput;
173 try {
174 editorInput = (TaxonEditorInput) reference.getEditorInput();
175 if(editorInput.getTaxonNode().equals(taxonNode) && reference.isDirty()){
176 return true;
177 }
178 } catch (PartInitException e) {
179 e.printStackTrace();
180 }
181 }
182 return false;
183 }
184
185 /**
186 *
187 * @param element
188 * @param parentElement
189 */
190 public static void selectInNavigator(Object element, Object parentElement) {
191 TaxonNavigator navigator = (TaxonNavigator) TaxeditorEditorPlugin.getDefault().getWorkbench().
192 getActiveWorkbenchWindow().getActivePage().findView(TaxonNavigator.ID);
193 if (navigator != null) {
194 CommonViewer viewer = navigator.getCommonViewer();
195 if (viewer != null) {
196 if (parentElement != null) {
197 viewer.setExpandedState(parentElement, true);
198 }
199 viewer.setSelection(new StructuredSelection((TaxonNode) element));
200 }
201 }
202 }
203
204 /**
205 * @param selection
206 */
207 public static void openSearch(Object selection) {
208 if(selection instanceof Taxon){
209 Taxon taxon = (Taxon) selection;
210
211 handleOpeningOfMultipleTaxonNodes(taxon.getTaxonNodes());
212
213 }else if(selection instanceof Synonym){
214 Synonym synonym = (Synonym) selection;
215
216 Set<TaxonNode> taxonNodes = new HashSet<TaxonNode>();
217 for (Taxon taxon : synonym.getAcceptedTaxa()){
218 taxonNodes.addAll(taxon.getTaxonNodes());
219 }
220 handleOpeningOfMultipleTaxonNodes(taxonNodes);
221
222 }else{
223 warningDialog("You chose to open a name that has no connection to a taxa. The Editor does not support editing of such a content type at the moment.");
224 logger.warn("Could not open editor for selection. Selection was of type: " + selection.getClass().getSimpleName());
225 }
226
227 }
228
229 /**
230 * @param taxonNodes
231 */
232 private static void handleOpeningOfMultipleTaxonNodes(
233 Set<TaxonNode> taxonNodes) {
234
235 if(taxonNodes.size() == 1){
236 openEditor(taxonNodes.iterator().next());
237 }else{
238 // FIXME implement a dialog that shows all possible taxa and let the user choose which he wants to open.
239 warningDialog("The accepted taxon is either in multiple taxonmoic views or the synonym has" +
240 " more than one accepted taxon. This case is not handled yet by the software.");
241 }
242 }
243 }