refactoring actions in the treeviewer
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / UiUtil.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;
11
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.Map;
15 import java.util.Set;
16 import java.util.SortedSet;
17
18 import org.apache.log4j.Logger;
19 import org.eclipse.core.commands.operations.IOperationHistory;
20 import org.eclipse.core.commands.operations.IUndoContext;
21 import org.eclipse.core.commands.operations.OperationHistoryFactory;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.jface.action.IStatusLineManager;
24 import org.eclipse.swt.graphics.Color;
25 import org.eclipse.swt.widgets.Shell;
26 import org.eclipse.swt.widgets.Tree;
27 import org.eclipse.swt.widgets.TreeItem;
28 import org.eclipse.ui.IActionBars;
29 import org.eclipse.ui.IEditorInput;
30 import org.eclipse.ui.IEditorPart;
31 import org.eclipse.ui.IEditorReference;
32 import org.eclipse.ui.IPageLayout;
33 import org.eclipse.ui.IViewPart;
34 import org.eclipse.ui.IViewReference;
35 import org.eclipse.ui.IWorkbench;
36 import org.eclipse.ui.IWorkbenchPage;
37 import org.eclipse.ui.PartInitException;
38 import org.eclipse.ui.operations.IWorkbenchOperationSupport;
39 import org.eclipse.ui.views.properties.PropertySheet;
40 import org.eclipse.ui.views.properties.PropertySheetPage;
41
42 import eu.etaxonomy.cdm.model.description.Feature;
43 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
44 import eu.etaxonomy.cdm.model.name.Rank;
45 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
46 import eu.etaxonomy.cdm.model.taxon.Taxon;
47 import eu.etaxonomy.taxeditor.actions.cdm.SaveTaxonAction;
48 import eu.etaxonomy.taxeditor.datasource.CdmTransactionController;
49 import eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor;
50 import eu.etaxonomy.taxeditor.editor.name.CdmParserController;
51 import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;
52 import eu.etaxonomy.taxeditor.model.CdmSessionDataRepository;
53 import eu.etaxonomy.taxeditor.model.NameEditorInput;
54 import eu.etaxonomy.taxeditor.navigation.RecentNamesView;
55 import eu.etaxonomy.taxeditor.navigation.TaxonomicTreeView;
56 import eu.etaxonomy.taxeditor.navigation.TaxonomicTreeViewer;
57 import eu.etaxonomy.taxeditor.propertysheet.CustomSortPropertySheetEntry;
58
59 /**
60 * A collection of useful methods related to the UI.
61 *
62 * @author p.ciardelli
63 * @created 27.05.2008
64 * @version 1.0
65 */
66 public class UiUtil {
67 private static final Logger logger = Logger.getLogger(UiUtil.class);
68
69 public static Set<Feature> preferredFeatureSet;
70 public static Set<Rank> preferredRankSet;
71 private static IViewPart treeView;
72
73 private static IOperationHistory operationHistory;
74
75 public static IViewPart getPropertySheet() {
76 for (IViewReference reference : getActivePage().getViewReferences()) {
77 if (reference.getId().equals(IPageLayout.ID_PROP_SHEET)) {
78 logger.warn(reference.getView(false).getSite().getPart().getTitle());
79 return reference.getView(false);
80 }
81 }
82 return null;
83 }
84
85 /**
86 * By default, property sheet has buttons in the toolbar for
87 * "Show advanced properties" and "Show categories".
88 * <p>
89 * This is confusing for the user, hence a method to remove them
90 * until such time as advanced properties or categories are implemented.
91 */
92 public static void hidePropertySheetToolbar() {
93 PropertySheet propertySheet = (PropertySheet) getPropertySheet();
94 IActionBars actionBars = propertySheet.getViewSite().getActionBars();
95 actionBars.getToolBarManager().removeAll();
96 actionBars.getMenuManager().removeAll();
97 }
98
99 /**
100 * The property sheet listener ensures only property sheets
101 * with data cause the Property Sheet to be updated.
102 */
103 public static void addPropertySheetInputListener() {
104 IViewPart propertySheet = getPropertySheet();
105 // propertySheet.get
106 PropertySheet ps = (PropertySheet) propertySheet;
107 // ps.addPartPropertyListener(listener)
108 // ps.addPropertyListener(l)
109 }
110
111 public static void saveAll(){
112 setIsSaving(true);
113
114 // Get all open windows
115 for (IEditorPart taxonEditor : getOpenTaxonEditors()) {
116
117 // Save the dirty ones
118 if (taxonEditor.isDirty()) {
119
120
121 IEditorInput input = taxonEditor.getEditorInput();
122 if (input.getAdapter(Taxon.class) != null) {
123 Taxon taxon = (Taxon) input.getAdapter(Taxon.class);
124 CdmSessionDataRepository.getDefault().saveTaxon(taxon);
125 if (taxonEditor instanceof MultiPageTaxonEditor) {
126 ((MultiPageTaxonEditor) taxonEditor).setDirtyExtern(false);
127 }
128 }
129 }
130 }
131
132 // Commit the transaction
133 CdmTransactionController.commitTransaction();
134
135 // Force library objects to be associated with new transaction
136 CdmSessionDataRepository.getDefault().clearNonTaxonData();
137
138 // Start a new transaction
139 CdmTransactionController.startTransaction();
140
141 // Put all open taxa in the new transaction
142 CdmTransactionController.addSessionTaxaToTransaction();
143
144 setIsSaving(false);
145 // TODO: delete undoHistory
146 }
147
148 //public void deleteTaxon()
149
150 /**
151 * @param input
152 * @return
153 * @throws PartInitException
154 */
155 public static IEditorPart getEditorByInput(IEditorInput input)
156 throws PartInitException {
157 for (IEditorReference reference : getActivePage().getEditorReferences()) {
158 if (reference.getEditorInput().equals(input)) {
159 IEditorPart editor = reference.getEditor(false);
160 return editor;
161 }
162 }
163 return null;
164 }
165
166 /**
167 * Returns a set of all currently open
168 * <code>MultiPageTaxonEditor</code>s.
169 *
170 * @return
171 */
172 public static Set<IEditorPart> getOpenTaxonEditors() {
173
174 Set<IEditorPart> taxonEditors = new HashSet<IEditorPart>();
175
176 for (IEditorReference reference : getActivePage().getEditorReferences()) {
177 IEditorPart editor = reference.getEditor(false);
178 if (editor instanceof MultiPageTaxonEditor) {
179 taxonEditors.add(editor);
180 }
181 }
182 return taxonEditors;
183 }
184
185 public static boolean closeOpenTaxonEditors() {
186 for (IEditorPart editor : getOpenTaxonEditors()) {
187 if (!getActivePage().closeEditor(editor, true)) {
188 return false;
189 }
190 }
191 return true;
192 }
193
194 public static IEditorPart getEditorByTaxon(Taxon taxon)
195 throws PartInitException {
196 IEditorInput input = new NameEditorInput(taxon);
197 return getEditorByInput(input);
198 }
199
200 /**
201 * @return
202 */
203 public static IWorkbenchPage getActivePage() {
204 return TaxEditorPlugin.getDefault().getWorkbench()
205 .getActiveWorkbenchWindow().getActivePage();
206 }
207
208 /**
209 * @return
210 */
211 public static Shell getShell() {
212 return TaxEditorPlugin.getDefault().getWorkbench()
213 .getActiveWorkbenchWindow().getShell();
214 }
215
216 /**
217 * @param input
218 * @param editorId
219 * @return
220 * @throws PartInitException
221 */
222 public static IEditorPart openEditor(IEditorInput input, String editorId)
223 throws PartInitException {
224 return getActivePage().openEditor(input, editorId);
225 }
226
227 /**
228 * Open an emtpy taxon editor
229 *
230 * @return
231 * @throws PartInitException
232 */
233 public static IEditorPart openTaxonEditor()
234 throws PartInitException{
235 return openTaxonEditor(null);
236 }
237
238 /**
239 * Open a taxon editor for the given taxon
240 *
241 * @param taxon
242 * @return
243 * @throws PartInitException
244 */
245 public static IEditorPart openTaxonEditor(Taxon taxon)
246 throws PartInitException{
247 if(taxon == null){
248 TaxonNameBase name = CdmParserController.parseFullReference("", null, null);
249 name.setFullTitleCache("", false);
250 name.setTitleCache("", false);
251 taxon = Taxon.NewInstance(name,
252 CdmSessionDataRepository.getDefault().getDefaultSec());
253 }else{
254 // If this taxon is not visible in the tree, open node
255 TaxonomicTreeViewer treeViewer = getTreeViewer();
256 if (treeViewer != null) {
257 treeViewer.revealTaxon(taxon);
258 }
259
260 // Add to recent names list
261 RecentNamesView.addRecentName(taxon);
262 }
263
264 IEditorInput input = new NameEditorInput(taxon);
265 return openEditor(input, MultiPageTaxonEditor.ID);
266 }
267
268 /**
269 * @param taxon
270 * @param save
271 * @throws PartInitException
272 */
273 public static void closeEditor(Taxon taxon, boolean save)
274 throws PartInitException {
275 IEditorPart editor = getEditorByTaxon(taxon);
276 closeEditor(editor, save);
277 }
278
279 /**
280 * @param input
281 * @param save
282 * @throws PartInitException
283 */
284 public static void closeEditor(IEditorInput input, boolean save)
285 throws PartInitException {
286 IEditorPart editor = getEditorByInput(input);
287 closeEditor(editor, save);
288 }
289
290 /**
291 * @param editor
292 * @param save
293 * @throws PartInitException
294 */
295 public static void closeEditor(IEditorPart editor, boolean save)
296 throws PartInitException {
297 if (editor != null) {
298 getActivePage().closeEditor(editor, save);
299 }
300 }
301
302 public static IViewPart getViewById(String id) {
303 return TaxEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().
304 getActivePage().findView(id);
305 }
306
307
308 /**
309 * Returns the <code>TaxonomicTreeViewer</code> used for navigation. Not to
310 * be confused with the window that contains it, <code>TaxonomicTreeView</code>.
311 *
312 * @return
313 */
314 public static TaxonomicTreeViewer getTreeViewer() {
315 TaxonomicTreeView view = getTreeView();
316 if (view == null) {
317 return null;
318 }
319 return view.getTreeViewer();
320 }
321
322 /**
323 * @see eu.etaxonomy.taxeditor.navigation.TaxonomicTreeView#createTreeViewer()
324 *
325 * @return
326 */
327 public static TaxonomicTreeViewer createTreeViewer() {
328 TaxonomicTreeView view = getTreeView();
329 if (view == null) {
330 return null;
331 }
332 return view.createTreeViewer();
333 }
334
335 /**
336 * Returns the <code>TaxonomicTreeView</code> containing the
337 * <code>TaxonomicTreeViewer</code> used for navigation.
338 *
339 * @return
340 */
341 public static TaxonomicTreeView getTreeView() {
342 if (treeView == null) {
343 treeView = getViewById(TaxonomicTreeView.ID);
344 if (!(treeView instanceof TaxonomicTreeView)) {
345 treeView = null;
346 }
347 }
348 return (TaxonomicTreeView) treeView;
349 }
350
351
352 public static IWorkbenchOperationSupport getOperationSupport() {
353 IWorkbench workbench = TaxEditorPlugin.getDefault().getWorkbench();
354 return workbench.getOperationSupport();
355 }
356
357 public static IOperationHistory getOperationHistory() {
358 // if (operationHistory == null) {
359 //// operationHistory = getOperationSupport().getOperationHistory();
360 // operationHistory = OperationHistoryFactory.getOperationHistory();
361 // }
362 // return operationHistory;
363 return getOperationSupport().getOperationHistory();
364 }
365
366 public static IUndoContext getWorkbenchUndoContext() {
367 // TODO make this more specific than GLOBAL_UNDO_CONTEXT
368 // return getOperationSupport().getUndoContext();
369 return IOperationHistory.GLOBAL_UNDO_CONTEXT;
370 }
371
372 public static void doEditorSave(Taxon taxon, boolean confirm) {
373 IEditorPart editor = null;
374 try {
375 editor = getEditorByTaxon(taxon);
376 } catch (PartInitException e) {
377 // TODO Auto-generated catch block
378 e.printStackTrace();
379 }
380 if (editor != null) {
381 getActivePage().saveEditor(editor, confirm);
382 }
383 }
384
385
386 // public static EditorGroupComposite getMisappliedNameGroupComposite(
387 // IManagedForm managedForm) {
388 //
389 // // Iterate through parent's children until we find a composite which has a data field
390 // // for MISAPPLIED_NAME
391 // Composite parent = managedForm.getForm().getBody();
392 // for (Control groupComposite : parent.getChildren()) {
393 // if (groupComposite instanceof EditorGroupComposite) {
394 // if (groupComposite.getData(ITaxEditorConstants.MISAPPLIED_NAME) != null) {
395 // return (EditorGroupComposite) groupComposite;
396 // }
397 // }
398 // }
399 // return null;
400 // }
401
402 // public static EditorGroupComposite createMisappliedNameGroupComposite(
403 // IManagedForm managedForm) {
404 //
405 // Composite parent = managedForm.getForm().getBody();
406 //
407 // EditorGroupComposite composite = new EditorGroupComposite(parent, managedForm);
408 // composite.setData(ITaxEditorConstants.MISAPPLIED_NAME,"");
409 // new CompositeBorderDecorator(composite, managedForm);
410 // return composite;
411 // }
412
413 public static void setStatusMessage(String msg) {
414 getPropertySheet().getViewSite().getActionBars().getStatusLineManager().setMessage(msg);
415 }
416
417 public static void setPropertySheetTree(Tree tree) {
418 TaxEditorPlugin.getDefault().setPropertySheetTree(tree);
419 }
420
421 public static Tree getPropertySheetTree() {
422 return TaxEditorPlugin.getDefault().getPropertySheetTree();
423 }
424
425 public static void setPropertySheetPage(PropertySheetPage page) {
426 TaxEditorPlugin.getDefault().setPropertySheetPage(page);
427 }
428
429 public static PropertySheetPage getPropertySheetPage() {
430 return TaxEditorPlugin.getDefault().getPropertySheetPage();
431 }
432
433 /**
434 * UiUtil.paintPropertySheetRow(P_DATEPUBLISHED, new Color(Display.getDefault(), WarningAnnotation.WARNING_RGB), true);
435 * UiUtil.unpaintPropertySheetRow(P_DATEPUBLISHED);
436 *
437 * @param id
438 * @param color
439 * @param doPaintChildren
440 */
441 public static void paintPropertySheetRow(String id, Color color, boolean doPaintChildren) {
442
443 // Catch null property sheet name
444 if (id == null) {
445 return;
446 }
447
448 // Catch uninit'ed property sheet tree
449 if (getPropertySheetTree() == null) {
450 return;
451 }
452
453 paintPropertySheetRow(id, color, doPaintChildren, getPropertySheetTree());
454 }
455
456 private static void paintPropertySheetRow(String id, Color color, boolean doPaintChildren, Object treeOrItem) {
457
458 // Init items w zero-length array
459 TreeItem[] items = new TreeItem[]{};
460
461 // Get child items depending to class
462 if (treeOrItem instanceof Tree) {
463 items = ((Tree) treeOrItem).getItems();
464 }
465 if (treeOrItem instanceof TreeItem) {
466 items = ((TreeItem) treeOrItem).getItems();
467 }
468
469 // If array hasn't been populated by the above, return
470 if (items.length == 0) {
471 return;
472 }
473
474 // Prop. sheet id's take the form "01:xxxx" for sorting - truncate
475 id = CustomSortPropertySheetEntry.truncateDisplayName(id);
476
477 // Iterate through child items
478 for (TreeItem item : items) {
479
480 // Item found, paint it
481 if (id.equals(item.getText())) {
482 paintItem(item, color, doPaintChildren);
483 return;
484 }
485
486 // Recursively search for item to paint in child items
487 if (item.getItemCount() > 0) {
488 paintPropertySheetRow(id, color, doPaintChildren, item);
489 }
490 }
491 }
492
493 /**
494 * Note: children are only painted if submenu has already been created, i.e. opened once.
495 *
496 * @param item
497 * @param color
498 * @param doPaintChildren
499 */
500 private static void paintItem(TreeItem item, Color color, boolean doPaintChildren) {
501
502 // Paint the item
503 item.setBackground(color);
504
505 // Recursively paint child items if requested
506 if (doPaintChildren) {
507 for (TreeItem childItem : item.getItems()) {
508 paintItem(childItem, color, doPaintChildren);
509 }
510 }
511 }
512
513 public static void unpaintPropertySheetRow(String id) {
514
515 // Catch uninit'ed property sheet tree
516 if (getPropertySheetTree() == null) {
517 return;
518 }
519
520 // Get tree's background color to "unpaint"
521 Color color = getPropertySheetTree().getBackground();
522
523 paintPropertySheetRow(id, color, true);
524 }
525
526 /**
527 * Get the name out of the session's name relations vocabulary, not directly
528 * from the object.
529 *
530 * @param type
531 * @return
532 */
533 public static String getNameRelationLabelType(NameRelationshipType type) {
534 SortedSet<NameRelationshipType> vocab =
535 CdmSessionDataRepository.getDefault().getNameRelationshipTypes();
536 for (NameRelationshipType type1 : vocab) {
537 if (type1.equals(type)) {
538 return type1.getLabel();
539 }
540 }
541 return "";
542 }
543
544 static boolean isSaving = false;
545
546 private static IStatusLineManager statusLineManager;
547
548 private static Map<Taxon, TaxonNameEditor> taxonNameEditors;
549
550 public static void setIsSaving(boolean isSavin) {
551 isSaving = isSavin;
552 }
553
554 public static boolean getIsSaving() {
555 return isSaving;
556 }
557
558 public static void setStatusLineManager(IStatusLineManager manager) {
559 statusLineManager = manager;
560 }
561
562 public static void setStatusLine(String message) {
563 statusLineManager.setMessage(message);
564 }
565
566 public static IProgressMonitor getStatusLineProgressMonitor() {
567 statusLineManager.setCancelEnabled(false);
568 return statusLineManager.getProgressMonitor();
569 }
570
571 public static void addTaxonNameEditor(
572 Taxon taxon, TaxonNameEditor taxonNameEditor) {
573 if (taxonNameEditors == null) {
574 taxonNameEditors = new HashMap<Taxon, TaxonNameEditor>();
575 }
576 taxonNameEditors.put(taxon, taxonNameEditor);
577 }
578
579 public static TaxonNameEditor getTaxonNameEditor(Taxon taxon) {
580 if (taxonNameEditors == null) {
581 return null;
582 }
583 return taxonNameEditors.get(taxon);
584 }
585
586 public static IUndoContext getTaxonNameEditorUndoContext(Taxon taxon) {
587 // TODO make this taxon name editor specific
588 // return getTaxonNameEditor(taxon).getUndoContext();
589 return IOperationHistory.GLOBAL_UNDO_CONTEXT;
590 }
591 }