2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.taxeditor
;
12 import java
.util
.HashMap
;
13 import java
.util
.HashSet
;
14 import java
.util
.List
;
17 import java
.util
.SortedSet
;
19 import org
.apache
.log4j
.Logger
;
20 import org
.eclipse
.core
.commands
.operations
.IOperationHistory
;
21 import org
.eclipse
.core
.commands
.operations
.IUndoContext
;
22 import org
.eclipse
.core
.commands
.operations
.OperationHistoryFactory
;
23 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
24 import org
.eclipse
.core
.runtime
.Status
;
25 import org
.eclipse
.jface
.action
.IStatusLineManager
;
26 import org
.eclipse
.swt
.graphics
.Color
;
27 import org
.eclipse
.swt
.widgets
.Shell
;
28 import org
.eclipse
.swt
.widgets
.Tree
;
29 import org
.eclipse
.swt
.widgets
.TreeItem
;
30 import org
.eclipse
.ui
.IActionBars
;
31 import org
.eclipse
.ui
.IEditorInput
;
32 import org
.eclipse
.ui
.IEditorPart
;
33 import org
.eclipse
.ui
.IEditorReference
;
34 import org
.eclipse
.ui
.IPageLayout
;
35 import org
.eclipse
.ui
.IViewPart
;
36 import org
.eclipse
.ui
.IViewReference
;
37 import org
.eclipse
.ui
.IWorkbench
;
38 import org
.eclipse
.ui
.IWorkbenchPage
;
39 import org
.eclipse
.ui
.PartInitException
;
40 import org
.eclipse
.ui
.operations
.IWorkbenchOperationSupport
;
41 import org
.eclipse
.ui
.views
.properties
.PropertySheet
;
42 import org
.eclipse
.ui
.views
.properties
.PropertySheetPage
;
44 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
45 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
46 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
47 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
49 import eu
.etaxonomy
.taxeditor
.actions
.cdm
.SaveTaxonAction
;
50 import eu
.etaxonomy
.taxeditor
.datasource
.CdmTransactionController
;
51 import eu
.etaxonomy
.taxeditor
.editor
.MultiPageTaxonEditor
;
52 import eu
.etaxonomy
.taxeditor
.editor
.name
.CdmParserController
;
53 import eu
.etaxonomy
.taxeditor
.editor
.name
.TaxonNameEditor
;
54 import eu
.etaxonomy
.taxeditor
.model
.CdmSessionDataRepository
;
55 import eu
.etaxonomy
.taxeditor
.model
.NameEditorInput
;
56 import eu
.etaxonomy
.taxeditor
.navigation
.SearchResult
;
57 import eu
.etaxonomy
.taxeditor
.navigation
.SearchResultView
;
58 import eu
.etaxonomy
.taxeditor
.navigation
.RecentNamesView
;
59 import eu
.etaxonomy
.taxeditor
.navigation
.TaxonomicTreeView
;
60 import eu
.etaxonomy
.taxeditor
.navigation
.TaxonomicTreeViewer
;
61 import eu
.etaxonomy
.taxeditor
.propertysheet
.CustomSortPropertySheetEntry
;
64 * A collection of useful methods related to the UI.
71 private static final Logger logger
= Logger
.getLogger(UiUtil
.class);
73 public static Set
<Feature
> preferredFeatureSet
;
74 public static Set
<Rank
> preferredRankSet
;
75 private static IViewPart treeView
;
77 private static IOperationHistory operationHistory
;
79 public static IViewPart
getPropertySheet() {
80 for (IViewReference reference
: getActivePage().getViewReferences()) {
81 if (reference
.getId().equals(IPageLayout
.ID_PROP_SHEET
)) {
82 logger
.warn(reference
.getView(false).getSite().getPart().getTitle());
83 return reference
.getView(false);
90 * By default, property sheet has buttons in the toolbar for
91 * "Show advanced properties" and "Show categories".
93 * This is confusing for the user, hence a method to remove them
94 * until such time as advanced properties or categories are implemented.
96 public static void hidePropertySheetToolbar() {
97 PropertySheet propertySheet
= (PropertySheet
) getPropertySheet();
98 IActionBars actionBars
= propertySheet
.getViewSite().getActionBars();
99 actionBars
.getToolBarManager().removeAll();
100 actionBars
.getMenuManager().removeAll();
104 * The property sheet listener ensures only property sheets
105 * with data cause the Property Sheet to be updated.
107 public static void addPropertySheetInputListener() {
108 IViewPart propertySheet
= getPropertySheet();
110 PropertySheet ps
= (PropertySheet
) propertySheet
;
111 // ps.addPartPropertyListener(listener)
112 // ps.addPropertyListener(l)
115 public static void saveAll(){
118 // Get all open windows
119 for (IEditorPart taxonEditor
: getOpenTaxonEditors()) {
121 // Save the dirty ones
122 if (taxonEditor
.isDirty()) {
125 IEditorInput input
= taxonEditor
.getEditorInput();
126 if (input
.getAdapter(Taxon
.class) != null) {
127 Taxon taxon
= (Taxon
) input
.getAdapter(Taxon
.class);
128 CdmSessionDataRepository
.getDefault().saveTaxon(taxon
);
129 if (taxonEditor
instanceof MultiPageTaxonEditor
) {
130 ((MultiPageTaxonEditor
) taxonEditor
).setDirtyExtern(false);
136 // Commit the transaction
137 CdmTransactionController
.commitTransaction();
139 // Force library objects to be associated with new transaction
140 CdmSessionDataRepository
.getDefault().clearNonTaxonData();
142 // Start a new transaction
143 CdmTransactionController
.startTransaction();
145 // Put all open taxa in the new transaction
146 CdmTransactionController
.addSessionTaxaToTransaction();
149 // TODO: delete undoHistory
152 //public void deleteTaxon()
157 * @throws PartInitException
159 public static IEditorPart
getEditorByInput(IEditorInput input
)
160 throws PartInitException
{
161 for (IEditorReference reference
: getActivePage().getEditorReferences()) {
162 if (reference
.getEditorInput().equals(input
)) {
163 IEditorPart editor
= reference
.getEditor(false);
171 * Returns a set of all currently open
172 * <code>MultiPageTaxonEditor</code>s.
176 public static Set
<IEditorPart
> getOpenTaxonEditors() {
178 Set
<IEditorPart
> taxonEditors
= new HashSet
<IEditorPart
>();
180 for (IEditorReference reference
: getActivePage().getEditorReferences()) {
181 IEditorPart editor
= reference
.getEditor(false);
182 if (editor
instanceof MultiPageTaxonEditor
) {
183 taxonEditors
.add(editor
);
189 public static boolean closeOpenTaxonEditors() {
190 for (IEditorPart editor
: getOpenTaxonEditors()) {
191 if (!getActivePage().closeEditor(editor
, true)) {
198 public static IEditorPart
getEditorByTaxon(Taxon taxon
)
199 throws PartInitException
{
200 IEditorInput input
= new NameEditorInput(taxon
);
201 return getEditorByInput(input
);
207 public static IWorkbenchPage
getActivePage() {
208 return TaxEditorPlugin
.getDefault().getWorkbench()
209 .getActiveWorkbenchWindow().getActivePage();
215 public static Shell
getShell() {
216 return TaxEditorPlugin
.getDefault().getWorkbench()
217 .getActiveWorkbenchWindow().getShell();
224 * @throws PartInitException
226 public static IEditorPart
openEditor(IEditorInput input
, String editorId
)
227 throws PartInitException
{
228 return getActivePage().openEditor(input
, editorId
);
232 * Open an emtpy taxon editor
235 * @throws PartInitException
237 public static IEditorPart
openTaxonEditor()
238 throws PartInitException
{
239 return openTaxonEditor(null);
243 * Open a taxon editor for the given taxon
247 * @throws PartInitException
249 public static IEditorPart
openTaxonEditor(Taxon taxon
)
250 throws PartInitException
{
252 TaxonNameBase name
= CdmParserController
.parseFullReference("", null, null);
253 name
.setFullTitleCache("", false);
254 name
.setTitleCache("", false);
255 taxon
= Taxon
.NewInstance(name
,
256 CdmSessionDataRepository
.getDefault().getDefaultSec());
258 // If this taxon is not visible in the tree, open node
259 TaxonomicTreeViewer treeViewer
= getTreeViewer();
260 if (treeViewer
!= null) {
261 treeViewer
.revealTaxon(taxon
);
264 // Add to recent names list
265 RecentNamesView
.addRecentName(taxon
);
268 IEditorInput input
= new NameEditorInput(taxon
);
269 return openEditor(input
, MultiPageTaxonEditor
.ID
);
273 * Redraws an open editor if it exists for the given taxon
278 public static boolean redrawEditor(Taxon taxon
){
280 TaxonNameEditor editor
= UiUtil
.getTaxonNameEditor(taxon
);
282 if(editor
== null || editor
.redraw()){
284 // Mark editor as changed and unsaved
295 * @throws PartInitException
297 public static void closeEditor(Taxon taxon
, boolean save
)
298 throws PartInitException
{
299 IEditorPart editor
= getEditorByTaxon(taxon
);
300 closeEditor(editor
, save
);
306 * @throws PartInitException
308 public static void closeEditor(IEditorInput input
, boolean save
)
309 throws PartInitException
{
310 IEditorPart editor
= getEditorByInput(input
);
311 closeEditor(editor
, save
);
317 * @throws PartInitException
319 public static void closeEditor(IEditorPart editor
, boolean save
)
320 throws PartInitException
{
321 if (editor
!= null) {
322 getActivePage().closeEditor(editor
, save
);
326 public static IViewPart
getViewById(String id
) {
327 return TaxEditorPlugin
.getDefault().getWorkbench().getActiveWorkbenchWindow().
328 getActivePage().findView(id
);
333 * Returns the <code>TaxonomicTreeViewer</code> used for navigation. Not to
334 * be confused with the window that contains it, <code>TaxonomicTreeView</code>.
338 public static TaxonomicTreeViewer
getTreeViewer() {
339 TaxonomicTreeView view
= getTreeView();
343 return view
.getTreeViewer();
347 * @see eu.etaxonomy.taxeditor.navigation.TaxonomicTreeView#createTreeViewer()
351 public static TaxonomicTreeViewer
createTreeViewer() {
352 TaxonomicTreeView view
= getTreeView();
356 return view
.createTreeViewer();
360 * Returns the <code>TaxonomicTreeView</code> containing the
361 * <code>TaxonomicTreeViewer</code> used for navigation.
365 public static TaxonomicTreeView
getTreeView() {
366 if (treeView
== null) {
367 treeView
= getViewById(TaxonomicTreeView
.ID
);
368 if (!(treeView
instanceof TaxonomicTreeView
)) {
372 return (TaxonomicTreeView
) treeView
;
376 public static IWorkbenchOperationSupport
getOperationSupport() {
377 IWorkbench workbench
= TaxEditorPlugin
.getDefault().getWorkbench();
378 return workbench
.getOperationSupport();
381 public static IOperationHistory
getOperationHistory() {
382 // if (operationHistory == null) {
383 //// operationHistory = getOperationSupport().getOperationHistory();
384 // operationHistory = OperationHistoryFactory.getOperationHistory();
386 // return operationHistory;
387 return getOperationSupport().getOperationHistory();
390 public static IUndoContext
getWorkbenchUndoContext() {
391 // TODO make this more specific than GLOBAL_UNDO_CONTEXT
392 // return getOperationSupport().getUndoContext();
393 return IOperationHistory
.GLOBAL_UNDO_CONTEXT
;
396 public static void doEditorSave(Taxon taxon
, boolean confirm
) {
397 IEditorPart editor
= null;
399 editor
= getEditorByTaxon(taxon
);
400 } catch (PartInitException e
) {
401 // TODO Auto-generated catch block
404 if (editor
!= null) {
405 getActivePage().saveEditor(editor
, confirm
);
410 // public static EditorGroupComposite getMisappliedNameGroupComposite(
411 // IManagedForm managedForm) {
413 // // Iterate through parent's children until we find a composite which has a data field
414 // // for MISAPPLIED_NAME
415 // Composite parent = managedForm.getForm().getBody();
416 // for (Control groupComposite : parent.getChildren()) {
417 // if (groupComposite instanceof EditorGroupComposite) {
418 // if (groupComposite.getData(ITaxEditorConstants.MISAPPLIED_NAME) != null) {
419 // return (EditorGroupComposite) groupComposite;
426 // public static EditorGroupComposite createMisappliedNameGroupComposite(
427 // IManagedForm managedForm) {
429 // Composite parent = managedForm.getForm().getBody();
431 // EditorGroupComposite composite = new EditorGroupComposite(parent, managedForm);
432 // composite.setData(ITaxEditorConstants.MISAPPLIED_NAME,"");
433 // new CompositeBorderDecorator(composite, managedForm);
437 public static void setStatusMessage(String msg
) {
438 getPropertySheet().getViewSite().getActionBars().getStatusLineManager().setMessage(msg
);
441 public static void setPropertySheetTree(Tree tree
) {
442 TaxEditorPlugin
.getDefault().setPropertySheetTree(tree
);
445 public static Tree
getPropertySheetTree() {
446 return TaxEditorPlugin
.getDefault().getPropertySheetTree();
449 public static void setPropertySheetPage(PropertySheetPage page
) {
450 TaxEditorPlugin
.getDefault().setPropertySheetPage(page
);
453 public static PropertySheetPage
getPropertySheetPage() {
454 return TaxEditorPlugin
.getDefault().getPropertySheetPage();
458 * UiUtil.paintPropertySheetRow(P_DATEPUBLISHED, new Color(Display.getDefault(), WarningAnnotation.WARNING_RGB), true);
459 * UiUtil.unpaintPropertySheetRow(P_DATEPUBLISHED);
463 * @param doPaintChildren
465 public static void paintPropertySheetRow(String id
, Color color
, boolean doPaintChildren
) {
467 // Catch null property sheet name
472 // Catch uninit'ed property sheet tree
473 if (getPropertySheetTree() == null) {
477 paintPropertySheetRow(id
, color
, doPaintChildren
, getPropertySheetTree());
480 private static void paintPropertySheetRow(String id
, Color color
, boolean doPaintChildren
, Object treeOrItem
) {
482 // Init items w zero-length array
483 TreeItem
[] items
= new TreeItem
[]{};
485 // Get child items depending to class
486 if (treeOrItem
instanceof Tree
) {
487 items
= ((Tree
) treeOrItem
).getItems();
489 if (treeOrItem
instanceof TreeItem
) {
490 items
= ((TreeItem
) treeOrItem
).getItems();
493 // If array hasn't been populated by the above, return
494 if (items
.length
== 0) {
498 // Prop. sheet id's take the form "01:xxxx" for sorting - truncate
499 id
= CustomSortPropertySheetEntry
.truncateDisplayName(id
);
501 // Iterate through child items
502 for (TreeItem item
: items
) {
504 // Item found, paint it
505 if (id
.equals(item
.getText())) {
506 paintItem(item
, color
, doPaintChildren
);
510 // Recursively search for item to paint in child items
511 if (item
.getItemCount() > 0) {
512 paintPropertySheetRow(id
, color
, doPaintChildren
, item
);
518 * Note: children are only painted if submenu has already been created, i.e. opened once.
522 * @param doPaintChildren
524 private static void paintItem(TreeItem item
, Color color
, boolean doPaintChildren
) {
527 item
.setBackground(color
);
529 // Recursively paint child items if requested
530 if (doPaintChildren
) {
531 for (TreeItem childItem
: item
.getItems()) {
532 paintItem(childItem
, color
, doPaintChildren
);
537 public static void unpaintPropertySheetRow(String id
) {
539 // Catch uninit'ed property sheet tree
540 if (getPropertySheetTree() == null) {
544 // Get tree's background color to "unpaint"
545 Color color
= getPropertySheetTree().getBackground();
547 paintPropertySheetRow(id
, color
, true);
551 * Get the name out of the session's name relations vocabulary, not directly
557 public static String
getNameRelationLabelType(NameRelationshipType type
) {
558 SortedSet
<NameRelationshipType
> vocab
=
559 CdmSessionDataRepository
.getDefault().getNameRelationshipTypes();
560 for (NameRelationshipType type1
: vocab
) {
561 if (type1
.equals(type
)) {
562 return type1
.getLabel();
568 static boolean isSaving
= false;
570 private static IStatusLineManager statusLineManager
;
572 private static Map
<Taxon
, TaxonNameEditor
> taxonNameEditors
;
574 public static void setIsSaving(boolean isSavin
) {
578 public static boolean getIsSaving() {
582 public static void setStatusLineManager(IStatusLineManager manager
) {
583 statusLineManager
= manager
;
586 public static void setStatusLine(String message
) {
587 statusLineManager
.setMessage(message
);
590 public static IProgressMonitor
getStatusLineProgressMonitor() {
591 statusLineManager
.setCancelEnabled(false);
592 return statusLineManager
.getProgressMonitor();
595 public static void addTaxonNameEditor(
596 Taxon taxon
, TaxonNameEditor taxonNameEditor
) {
597 if (taxonNameEditors
== null) {
598 taxonNameEditors
= new HashMap
<Taxon
, TaxonNameEditor
>();
600 taxonNameEditors
.put(taxon
, taxonNameEditor
);
603 public static TaxonNameEditor
getTaxonNameEditor(Taxon taxon
) {
604 if (taxonNameEditors
== null) {
607 return taxonNameEditors
.get(taxon
);
610 public static IUndoContext
getTaxonNameEditorUndoContext(Taxon taxon
) {
611 // TODO make this taxon name editor specific
612 // return getTaxonNameEditor(taxon).getUndoContext();
613 return IOperationHistory
.GLOBAL_UNDO_CONTEXT
;
616 static String srv
= "";
618 public static void openSearchResultsView(SearchResult searchResult
) {
620 logger
.warn("opening search results window " + srv
);
622 IViewPart resultsView
= getActivePage().showView(SearchResultView
.ID
,
623 srv
, IWorkbenchPage
.VIEW_VISIBLE
);
624 ((SearchResultView
) resultsView
).setResult(searchResult
);
625 } catch (PartInitException e
) {
626 // TODO Auto-generated catch block