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