KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > views > markers > internal > TableView


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Sebastian Davids <sdavids@gmx.de> - 26823 [Markers] cannot reorder columns in task list
11  *******************************************************************************/

12
13 package org.eclipse.ui.views.markers.internal;
14
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.NullProgressMonitor;
19 import org.eclipse.jface.action.IAction;
20 import org.eclipse.jface.action.IMenuListener;
21 import org.eclipse.jface.action.IMenuManager;
22 import org.eclipse.jface.action.IToolBarManager;
23 import org.eclipse.jface.action.MenuManager;
24 import org.eclipse.jface.dialogs.IDialogSettings;
25 import org.eclipse.jface.operation.IRunnableWithProgress;
26 import org.eclipse.jface.viewers.ColumnLayoutData;
27 import org.eclipse.jface.viewers.ColumnPixelData;
28 import org.eclipse.jface.viewers.IOpenListener;
29 import org.eclipse.jface.viewers.ISelectionChangedListener;
30 import org.eclipse.jface.viewers.ISelectionProvider;
31 import org.eclipse.jface.viewers.IStructuredSelection;
32 import org.eclipse.jface.viewers.OpenEvent;
33 import org.eclipse.jface.viewers.SelectionChangedEvent;
34 import org.eclipse.jface.viewers.TableLayout;
35 import org.eclipse.jface.viewers.TreeViewer;
36 import org.eclipse.jface.viewers.TreeViewerColumn;
37 import org.eclipse.jface.viewers.Viewer;
38 import org.eclipse.jface.viewers.ViewerComparator;
39 import org.eclipse.swt.SWT;
40 import org.eclipse.swt.custom.BusyIndicator;
41 import org.eclipse.swt.events.KeyAdapter;
42 import org.eclipse.swt.events.KeyEvent;
43 import org.eclipse.swt.events.SelectionAdapter;
44 import org.eclipse.swt.events.SelectionEvent;
45 import org.eclipse.swt.events.SelectionListener;
46 import org.eclipse.swt.layout.FillLayout;
47 import org.eclipse.swt.widgets.Composite;
48 import org.eclipse.swt.widgets.Menu;
49 import org.eclipse.swt.widgets.ScrollBar;
50 import org.eclipse.swt.widgets.Scrollable;
51 import org.eclipse.swt.widgets.Tree;
52 import org.eclipse.swt.widgets.TreeColumn;
53 import org.eclipse.ui.IActionBars;
54 import org.eclipse.ui.IMemento;
55 import org.eclipse.ui.IViewSite;
56 import org.eclipse.ui.PartInitException;
57 import org.eclipse.ui.PlatformUI;
58 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
59 import org.eclipse.ui.part.ViewPart;
60 import org.eclipse.ui.preferences.ViewPreferencesAction;
61 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
62
63 /**
64  * The TableView is a view that generically implements views with tables.
65  *
66  */

67 public abstract class TableView extends ViewPart {
68
69     private static final String JavaDoc TAG_COLUMN_WIDTH = "columnWidth"; //$NON-NLS-1$
70

71     private static final String JavaDoc TAG_COLUMN_ORDER = "columnOrder"; //$NON-NLS-1$
72

73     private static final String JavaDoc TAG_COLUMN_ORDER_INDEX = "columnOrderIndex"; //$NON-NLS-1$
74

75     private static final String JavaDoc TAG_VERTICAL_POSITION = "verticalPosition"; //$NON-NLS-1$
76

77     private static final String JavaDoc TAG_HORIZONTAL_POSITION = "horizontalPosition"; //$NON-NLS-1$
78

79     private TreeViewer viewer;
80
81     private IMemento memento;
82
83     private IAction sortAction;
84
85     private IAction filtersAction;
86
87     private IAction preferencesAction;
88
89     private MarkerTreeContentProvider contentProvider;
90
91     private ISelectionProvider selectionProvider = new MarkerSelectionProviderAdapter();
92
93     /*
94      * (non-Javadoc) Method declared on IViewPart.
95      */

96     public void init(IViewSite site, IMemento memento) throws PartInitException {
97         super.init(site, memento);
98         this.memento = memento;
99     }
100
101     /**
102      *
103      */

104     // void haltTableUpdates() {
105
// content.cancelPendingChanges();
106
// }
107
// void change(Collection toRefresh) {
108
// content.change(toRefresh);
109
// }
110
// void setContents(Collection contents, IProgressMonitor mon) {
111
// content.set(contents, mon);
112
// }
113
abstract protected void viewerSelectionChanged(
114             IStructuredSelection selection);
115
116     /*
117      * (non-Javadoc)
118      *
119      * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
120      */

121     public void createPartControl(Composite parent) {
122         parent.setLayout(new FillLayout());
123
124         viewer = new TreeViewer(createTree(parent));
125         createColumns(viewer.getTree());
126         
127         viewer.setComparator(buildComparator());
128         setSortIndicators();
129
130         contentProvider = new MarkerTreeContentProvider();
131
132         viewer.setContentProvider(contentProvider);
133
134         viewer.addSelectionChangedListener(new ISelectionChangedListener() {
135             public void selectionChanged(SelectionChangedEvent event) {
136                 IStructuredSelection selection = (IStructuredSelection) event
137                         .getSelection();
138                 viewerSelectionChanged(selection);
139             }
140         });
141
142
143         // create the actions before the input is set on the viewer but after
144
// the
145
// sorter and filter are set so the actions will be enabled correctly.
146
createActions();
147
148         viewer.setInput(createViewerInput());
149
150         Scrollable scrollable = (Scrollable) viewer.getControl();
151         ScrollBar bar = scrollable.getVerticalBar();
152         if (bar != null) {
153             bar.setSelection(restoreVerticalScrollBarPosition(memento));
154         }
155         bar = scrollable.getHorizontalBar();
156         if (bar != null) {
157             bar.setSelection(restoreHorizontalScrollBarPosition(memento));
158         }
159
160         MenuManager mgr = initContextMenu();
161         Menu menu = mgr.createContextMenu(viewer.getControl());
162         viewer.getControl().setMenu(menu);
163         getSite().registerContextMenu(mgr, selectionProvider);
164
165         getSite().setSelectionProvider(selectionProvider);
166
167         IActionBars actionBars = getViewSite().getActionBars();
168         initMenu(actionBars.getMenuManager());
169         initToolBar(actionBars.getToolBarManager());
170
171         registerGlobalActions(getViewSite().getActionBars());
172
173         viewer.addOpenListener(new IOpenListener() {
174             public void open(OpenEvent event) {
175                 handleOpenEvent(event);
176             }
177         });
178         viewer.getControl().addKeyListener(new KeyAdapter() {
179             public void keyPressed(KeyEvent e) {
180                 handleKeyPressed(e);
181             }
182         });
183     }
184
185
186     /**
187      * Create the viewer input for the receiver.
188      *
189      * @return Object
190      */

191     abstract Object JavaDoc createViewerInput();
192
193     /**
194      * Set the comparator to be the new comparator. This should only
195      * be called if the viewer has been created.
196      *
197      * @param comparator
198      */

199     void setComparator(TableComparator comparator) {
200         viewer.setComparator(comparator);
201         updateForNewComparator(comparator);
202     }
203
204     /**
205      * Update the viewer for comparator updates
206      *
207      * @param comparator
208      */

209     void updateForNewComparator(TableComparator comparator) {
210         comparator.saveState(getDialogSettings());
211         viewer.refresh();
212         setSortIndicators();
213     }
214
215     /**
216      * Create the main tree control
217      *
218      * @param parent
219      * @return Tree
220      */

221     protected Tree createTree(Composite parent) {
222         Tree tree = new Tree(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
223                 | SWT.FULL_SELECTION);
224         tree.setLinesVisible(true);
225         return tree;
226     }
227
228     /**
229      * Get the pixel data for the columns.
230      *
231      * @return ColumnPixelData[]
232      */

233     public ColumnPixelData[] getSavedColumnData() {
234         ColumnPixelData[] defaultData = getDefaultColumnLayouts();
235
236         ColumnPixelData[] result = new ColumnPixelData[defaultData.length];
237         for (int i = 0; i < defaultData.length; i++) {
238             
239             ColumnPixelData defaultPixelData = defaultData[i];
240             boolean addTrim = defaultPixelData.addTrim;
241             int width = defaultPixelData.width;
242             // non-resizable columns are always left at their default width
243
if (defaultPixelData.resizable) {
244                 if (memento != null) {
245                     Integer JavaDoc widthInt = memento.getInteger(TAG_COLUMN_WIDTH + i);
246
247                     if (widthInt != null && widthInt.intValue() > 0) {
248                         width = widthInt.intValue();
249                         addTrim = false;
250                     }
251                 }
252             }
253
254             result[i] = new ColumnPixelData(width, defaultPixelData.resizable,
255                     addTrim);
256         }
257
258         return result;
259     }
260
261     /**
262      * Return the column sizes from the actual widget. Returns the saved column
263      * sizes if the widget hasn't been created yet or its columns haven't been
264      * initialized yet. (Note that TableLayout only initializes the column
265      * widths after the first layout, so it is possible for the widget to exist
266      * but have all its columns incorrectly set to zero width - see bug 86329)
267      *
268      * @return ColumnPixelData
269      */

270     public ColumnPixelData[] getColumnData() {
271         ColumnPixelData[] defaultData = getSavedColumnData();
272
273         Tree tree = getTree();
274
275         if (tree != null && (tree.isDisposed() || tree.getBounds().width == 0)) {
276             tree = null;
277         }
278
279         TreeColumn[] column = null;
280         if (tree != null) {
281             column = tree.getColumns();
282         }
283
284         ColumnPixelData[] result = new ColumnPixelData[defaultData.length];
285         for (int i = 0; i < defaultData.length; i++) {
286             ColumnPixelData defaultPixelData = defaultData[i];
287             int width = defaultData[i].width;
288
289             if (column != null && i < column.length) {
290                 TreeColumn col = column[i];
291
292                 if (col.getWidth() > 0) {
293                     width = col.getWidth();
294                 }
295             }
296
297             result[i] = new ColumnPixelData(width, defaultPixelData.resizable,
298                     defaultPixelData.addTrim);
299         }
300
301         return result;
302     }
303
304     /**
305      * Create the columns in the tree.
306      *
307      * @param tree
308      */

309     protected void createColumns(final Tree tree) {
310         TableLayout layout = new TableLayout();
311         tree.setLayout(layout);
312         tree.setHeaderVisible(true);
313
314         final IField[] fields = getAllFields();
315         ColumnLayoutData[] columnWidths = getSavedColumnData();
316         for (int i = 0; i < fields.length; i++) {
317             layout.addColumnData(columnWidths[i]);
318             TreeColumn tc = new TreeColumn(tree, SWT.NONE, i);
319             IField field = fields[i];
320             tc.setText(field.getColumnHeaderText());
321             tc.setImage(field.getColumnHeaderImage());
322             tc.setResizable(columnWidths[i].resizable);
323             tc.setMoveable(true);
324             tc.addSelectionListener(getHeaderListener());
325             tc.setData(field);
326             TreeViewerColumn viewerColumn = new TreeViewerColumn(viewer, tc);
327             viewerColumn.setLabelProvider(new MarkerViewLabelProvider(field));
328         }
329
330         int[] order = restoreColumnOrder(memento);
331         if (order != null && order.length == fields.length) {
332             tree.setColumnOrder(order);
333         }
334     }
335
336     /**
337      * Create the actions for the receiver.
338      */

339     protected void createActions() {
340         if (getSortDialog() != null) {
341             sortAction = new TableSortAction(this, getSortDialog());
342         }
343     }
344
345     protected MenuManager initContextMenu() {
346         MenuManager mgr = new MenuManager();
347         mgr.setRemoveAllWhenShown(true);
348         mgr.addMenuListener(new IMenuListener() {
349             public void menuAboutToShow(IMenuManager mgr) {
350
351                 getViewer().cancelEditing();
352                 fillContextMenu(mgr);
353             }
354         });
355         return mgr;
356     }
357
358     protected abstract void initToolBar(IToolBarManager tbm);
359
360     /**
361      * Init the menu for the receiver.
362      *
363      * @param menu
364      */

365     protected void initMenu(IMenuManager menu) {
366         if (sortAction != null) {
367             menu.add(sortAction);
368         }
369         addDropDownContributions(menu);
370         if (filtersAction != null) {
371             menu.add(filtersAction);
372         }
373         if (preferencesAction != null) {
374             menu.add(preferencesAction);
375         }
376     }
377
378     /**
379      * Add any extra contributions to the drop down.
380      *
381      * @param menu
382      */

383     void addDropDownContributions(IMenuManager menu) {
384         // Do nothing by default.
385
}
386
387     protected abstract void registerGlobalActions(IActionBars actionBars);
388
389     protected abstract void fillContextMenu(IMenuManager manager);
390
391     /*
392      * (non-Javadoc)
393      *
394      * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
395      */

396     public void setFocus() {
397         Viewer viewer = getViewer();
398         if (viewer != null && !viewer.getControl().isDisposed()) {
399
400             viewer.getControl().setFocus();
401         }
402     }
403
404     /**
405      * Build a comparator from the default settings.
406      *
407      * @return ViewerComparator
408      */

409     protected ViewerComparator buildComparator() {
410
411         return createTableComparator();
412     }
413
414     /**
415      * Create a TableComparator for the receiver.
416      *
417      * @return TableComparator
418      */

419     TableComparator createTableComparator() {
420         TableComparator sorter = TableComparator
421                 .createTableSorter(getSortingFields());
422         sorter.restoreState(getDialogSettings());
423         return sorter;
424     }
425
426     // protected abstract ITableViewContentProvider getContentProvider();
427

428     protected abstract IField[] getSortingFields();
429
430     protected abstract IField[] getAllFields();
431
432     protected abstract IDialogSettings getDialogSettings();
433
434     /**
435      * Return the viewer.
436      *
437      * @return TreeViewer
438      */

439     protected TreeViewer getViewer() {
440         return viewer;
441     }
442
443     /**
444      * Return the tree for the receiver.
445      *
446      * @return Tree
447      */

448     protected Tree getTree() {
449         return getViewer().getTree();
450     }
451
452     protected SelectionListener getHeaderListener() {
453         return new SelectionAdapter() {
454             /**
455              * Handles the case of user selecting the header area.
456              */

457             public void widgetSelected(SelectionEvent e) {
458
459                 final TreeColumn column = (TreeColumn) e.widget;
460                 final IField field = (IField) column.getData();
461
462                 try {
463                     IWorkbenchSiteProgressService progressService = getProgressService();
464                     if (progressService == null)
465                         BusyIndicator.showWhile(getSite().getShell()
466                                 .getDisplay(), new Runnable JavaDoc() {
467                             /*
468                              * (non-Javadoc)
469                              *
470                              * @see java.lang.Runnable#run()
471                              */

472                             public void run() {
473                                 resortTable(column, field,
474                                         new NullProgressMonitor());
475
476                             }
477                         });
478                     else
479                         getProgressService().busyCursorWhile(
480                                 new IRunnableWithProgress() {
481                                     /*
482                                      * (non-Javadoc)
483                                      *
484                                      * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
485                                      */

486                                     public void run(IProgressMonitor monitor) {
487                                         resortTable(column, field, monitor);
488                                     }
489                                 });
490                 } catch (InvocationTargetException JavaDoc e1) {
491                     IDEWorkbenchPlugin.getDefault().getLog().log(
492                             Util.errorStatus(e1));
493                 } catch (InterruptedException JavaDoc e1) {
494                     return;
495                 }
496
497             }
498
499             /**
500              * Resort the table based on field.
501              *
502              * @param column
503              * the column being updated
504              * @param field
505              * @param monitor
506              */

507             private void resortTable(final TreeColumn column,
508                     final IField field, IProgressMonitor monitor) {
509                 TableComparator sorter = getTableSorter();
510
511                 monitor.beginTask(MarkerMessages.sortDialog_title, 100);
512                 monitor.worked(10);
513                 if (field.equals(sorter.getTopField()))
514                     sorter.reverseTopPriority();
515                 else
516                     sorter.setTopPriority(field);
517
518                 monitor.worked(15);
519                 PlatformUI.getWorkbench().getDisplay().asyncExec(
520                         new Runnable JavaDoc() {
521                             /*
522                              * (non-Javadoc)
523                              *
524                              * @see java.lang.Runnable#run()
525                              */

526                             public void run() {
527                                 viewer.refresh();
528                                 updateDirectionIndicator(column);
529                             }
530                         });
531
532                 monitor.done();
533             }
534         };
535     }
536
537     /*
538      * (non-Javadoc)
539      *
540      * @see org.eclipse.ui.views.markers.internal.TableView#getDefaultColumnLayouts()
541      */

542     protected ColumnPixelData[] getDefaultColumnLayouts() {
543
544         IField[] fields = getAllFields();
545         ColumnPixelData[] datas = new ColumnPixelData[fields.length];
546
547         for (int i = 0; i < fields.length; i++) {
548             int width = getWidth(fields[i]);
549             boolean resizable = width > 0;
550             datas[i] = new ColumnPixelData(width, resizable, resizable);
551         }
552         return datas;
553     }
554
555     /**
556      * Return the width of the field to display.
557      *
558      * @param field
559      * @return int
560      */

561     private int getWidth(IField field) {
562         if (!field.isShowing()) {
563             return 0;
564         }
565         return field.getPreferredWidth();
566     }
567
568     /**
569      * Return a sort dialog for the receiver.
570      *
571      * @return TableSortDialog
572      */

573     protected TableSortDialog getSortDialog() {
574         return new TableSortDialog(getSite(), getTableSorter());
575
576     }
577
578     /**
579      * Return the table sorter portion of the sorter.
580      *
581      * @return TableSorter
582      */

583     TableComparator getTableSorter() {
584         return (TableComparator) viewer.getComparator();
585     }
586
587     protected abstract void handleKeyPressed(KeyEvent event);
588
589     protected abstract void handleOpenEvent(OpenEvent event);
590
591     /*
592      * (non-Javadoc)
593      *
594      * @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento)
595      */

596     public void saveState(IMemento memento) {
597         super.saveState(memento);
598
599         ColumnPixelData[] data = getColumnData();
600
601         for (int i = 0; i < data.length; i++) {
602             ColumnPixelData data2 = data[i];
603             memento.putInteger(TAG_COLUMN_WIDTH + i, data2.width);
604         }
605         // save column order
606
Tree tree = getTree();
607         int[] columnOrder = tree.getColumnOrder();
608         for (int i = 0; i < columnOrder.length; i++) {
609             IMemento child = memento.createChild(TAG_COLUMN_ORDER);
610             child.putInteger(TAG_COLUMN_ORDER_INDEX, columnOrder[i]);
611         }
612         // save vertical position
613
Scrollable scrollable = (Scrollable) viewer.getControl();
614         ScrollBar bar = scrollable.getVerticalBar();
615         int position = (bar != null) ? bar.getSelection() : 0;
616         memento.putInteger(TAG_VERTICAL_POSITION, position);
617         // save horizontal position
618
bar = scrollable.getHorizontalBar();
619         position = (bar != null) ? bar.getSelection() : 0;
620         memento.putInteger(TAG_HORIZONTAL_POSITION, position);
621     }
622
623     private int[] restoreColumnOrder(IMemento memento) {
624         if (memento == null) {
625             return null;
626         }
627         IMemento children[] = memento.getChildren(TAG_COLUMN_ORDER);
628         if (children != null) {
629             int n = children.length;
630             int[] values = new int[n];
631             for (int i = 0; i < n; i++) {
632                 Integer JavaDoc val = children[i].getInteger(TAG_COLUMN_ORDER_INDEX);
633                 if (val != null) {
634                     values[i] = val.intValue();
635                 } else {
636                     // invalid entry so use default column order
637
return null;
638                 }
639             }
640             return values;
641         }
642         return null;
643     }
644
645     private int restoreVerticalScrollBarPosition(IMemento memento) {
646         if (memento == null) {
647             return 0;
648         }
649         Integer JavaDoc position = memento.getInteger(TAG_VERTICAL_POSITION);
650         return (position == null) ? 0 : position.intValue();
651     }
652
653     private int restoreHorizontalScrollBarPosition(IMemento memento) {
654         if (memento == null) {
655             return 0;
656         }
657         Integer JavaDoc position = memento.getInteger(TAG_HORIZONTAL_POSITION);
658         return (position == null) ? 0 : position.intValue();
659     }
660
661     /**
662      * Get the IWorkbenchSiteProgressService for the receiver.
663      *
664      * @return IWorkbenchSiteProgressService or <code>null</code>.
665      */

666     protected IWorkbenchSiteProgressService getProgressService() {
667         IWorkbenchSiteProgressService service = null;
668         Object JavaDoc siteService = getSite().getAdapter(
669                 IWorkbenchSiteProgressService.class);
670         if (siteService != null) {
671             service = (IWorkbenchSiteProgressService) siteService;
672         }
673         return service;
674     }
675
676     /**
677      * Set the filters action.
678      *
679      * @param action
680      */

681     void setFilterAction(FiltersAction action) {
682         filtersAction = action;
683
684     }
685
686     /**
687      * Return the filter action for the receiver.
688      *
689      * @return IAction
690      */

691     IAction getFilterAction() {
692         return filtersAction;
693     }
694
695     /**
696      * Return the preferences action.
697      *
698      * @return IAction
699      */

700     IAction getPreferencesAction() {
701         return preferencesAction;
702     }
703
704     /**
705      * Set the preferences action.
706      *
707      * @param preferencesAction
708      */

709     void setPreferencesAction(ViewPreferencesAction preferencesAction) {
710         this.preferencesAction = preferencesAction;
711     }
712
713     /**
714      * Get the content provider
715      *
716      * @return MarkerTreeContentProvider
717      */

718     MarkerTreeContentProvider getContentProvider() {
719         return contentProvider;
720     }
721
722     /**
723      * Return the input to the viewer.
724      *
725      * @return Object
726      */

727     public Object JavaDoc getViewerInput() {
728         return getViewer().getInput();
729     }
730
731     /*
732      * (non-Javadoc)
733      *
734      * @see org.eclipse.ui.views.markers.internal.TableView#setSortIndicators()
735      */

736     void setSortIndicators() {
737         IField top = getTableSorter().getTopField();
738         TreeColumn[] columns = getViewer().getTree().getColumns();
739         for (int i = 0; i < columns.length; i++) {
740             TreeColumn column = columns[i];
741             if (column.getData().equals(top)) {
742                 updateDirectionIndicator(column);
743                 return;
744             }
745         }
746     }
747
748     /**
749      * Update the direction indicator as column is now the primary column.
750      *
751      * @param column
752      */

753     void updateDirectionIndicator(TreeColumn column) {
754         getViewer().getTree().setSortColumn(column);
755         if (getTableSorter().getTopPriorityDirection() == TableComparator.ASCENDING)
756             getViewer().getTree().setSortDirection(SWT.UP);
757         else
758             getViewer().getTree().setSortDirection(SWT.DOWN);
759     }
760
761     /**
762      * Set the selection of the receiver.
763      *
764      * @param selection
765      */

766     protected void setSelection(IStructuredSelection selection) {
767         selectionProvider.setSelection(selection);
768     }
769 }
770
Popular Tags