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