KickJava   Java API By Example, From Geeks To Geeks.

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


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  *******************************************************************************/

11
12 package org.eclipse.ui.views.markers.internal;
13
14 import java.io.IOException JavaDoc;
15 import java.io.StringReader JavaDoc;
16 import java.io.StringWriter JavaDoc;
17 import java.text.MessageFormat JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24
25 import org.eclipse.core.commands.operations.IUndoContext;
26 import org.eclipse.core.resources.IFile;
27 import org.eclipse.core.resources.IMarker;
28 import org.eclipse.core.resources.IResource;
29 import org.eclipse.core.resources.IResourceChangeEvent;
30 import org.eclipse.core.resources.IResourceChangeListener;
31 import org.eclipse.core.resources.ResourcesPlugin;
32 import org.eclipse.core.resources.mapping.ResourceMapping;
33 import org.eclipse.core.resources.mapping.ResourceMappingContext;
34 import org.eclipse.core.resources.mapping.ResourceTraversal;
35 import org.eclipse.core.runtime.CoreException;
36 import org.eclipse.core.runtime.IAdaptable;
37 import org.eclipse.core.runtime.IProgressMonitor;
38 import org.eclipse.core.runtime.IStatus;
39 import org.eclipse.core.runtime.NullProgressMonitor;
40 import org.eclipse.core.runtime.Status;
41 import org.eclipse.core.runtime.jobs.IJobChangeListener;
42 import org.eclipse.core.runtime.jobs.Job;
43 import org.eclipse.help.HelpSystem;
44 import org.eclipse.help.IContext;
45 import org.eclipse.help.IContextProvider;
46 import org.eclipse.jface.action.IMenuManager;
47 import org.eclipse.jface.action.IToolBarManager;
48 import org.eclipse.jface.action.MenuManager;
49 import org.eclipse.jface.action.Separator;
50 import org.eclipse.jface.dialogs.Dialog;
51 import org.eclipse.jface.dialogs.IDialogSettings;
52 import org.eclipse.jface.preference.IPreferenceStore;
53 import org.eclipse.jface.util.IPropertyChangeListener;
54 import org.eclipse.jface.util.PropertyChangeEvent;
55 import org.eclipse.jface.viewers.AbstractTreeViewer;
56 import org.eclipse.jface.viewers.ISelection;
57 import org.eclipse.jface.viewers.IStructuredSelection;
58 import org.eclipse.jface.viewers.OpenEvent;
59 import org.eclipse.jface.viewers.StructuredSelection;
60 import org.eclipse.jface.viewers.TreeViewer;
61 import org.eclipse.jface.window.Window;
62 import org.eclipse.osgi.util.NLS;
63 import org.eclipse.swt.dnd.Clipboard;
64 import org.eclipse.swt.dnd.DND;
65 import org.eclipse.swt.dnd.DragSourceAdapter;
66 import org.eclipse.swt.dnd.DragSourceEvent;
67 import org.eclipse.swt.dnd.DragSourceListener;
68 import org.eclipse.swt.dnd.TextTransfer;
69 import org.eclipse.swt.dnd.Transfer;
70 import org.eclipse.swt.events.HelpEvent;
71 import org.eclipse.swt.events.HelpListener;
72 import org.eclipse.swt.events.KeyEvent;
73 import org.eclipse.swt.events.TreeAdapter;
74 import org.eclipse.swt.events.TreeEvent;
75 import org.eclipse.swt.widgets.Composite;
76 import org.eclipse.swt.widgets.Tree;
77 import org.eclipse.ui.IActionBars;
78 import org.eclipse.ui.IEditorInput;
79 import org.eclipse.ui.IEditorPart;
80 import org.eclipse.ui.IMemento;
81 import org.eclipse.ui.ISelectionListener;
82 import org.eclipse.ui.IViewSite;
83 import org.eclipse.ui.IWorkbenchActionConstants;
84 import org.eclipse.ui.IWorkbenchPart;
85 import org.eclipse.ui.PartInitException;
86 import org.eclipse.ui.PlatformUI;
87 import org.eclipse.ui.WorkbenchException;
88 import org.eclipse.ui.XMLMemento;
89 import org.eclipse.ui.actions.ActionFactory;
90 import org.eclipse.ui.actions.ContributionItemFactory;
91 import org.eclipse.ui.actions.SelectionProviderAction;
92 import org.eclipse.ui.ide.IDE;
93 import org.eclipse.ui.ide.ResourceUtil;
94 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
95 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
96 import org.eclipse.ui.keys.IBindingService;
97 import org.eclipse.ui.operations.RedoActionHandler;
98 import org.eclipse.ui.operations.UndoActionHandler;
99 import org.eclipse.ui.part.IShowInSource;
100 import org.eclipse.ui.part.MarkerTransfer;
101 import org.eclipse.ui.part.ShowInContext;
102 import org.eclipse.ui.preferences.ViewPreferencesAction;
103 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
104 import org.eclipse.ui.progress.WorkbenchJob;
105 import org.eclipse.ui.views.markers.internal.MarkerAdapter.MarkerCategory;
106 import org.eclipse.ui.views.tasklist.ITaskListResourceAdapter;
107
108 /**
109  * MarkerView is the abstract super class of the marker based views.
110  *
111  */

112 public abstract class MarkerView extends TableView {
113
114     private static final String JavaDoc TAG_SELECTION = "selection"; //$NON-NLS-1$
115

116     private static final String JavaDoc TAG_MARKER = "marker"; //$NON-NLS-1$
117

118     private static final String JavaDoc TAG_RESOURCE = "resource"; //$NON-NLS-1$
119

120     private static final String JavaDoc TAG_ID = "id"; //$NON-NLS-1$
121

122     private static final String JavaDoc TAG_FILTERS_SECTION = "filters"; //$NON-NLS-1$
123

124     private static final String JavaDoc TAG_FILTER_ENTRY = "filter"; //$NON-NLS-1$
125

126     private static final String JavaDoc MENU_FILTERS_GROUP = "group.filter";//$NON-NLS-1$
127

128     private static final String JavaDoc MENU_SHOW_IN_GROUP = "group.showIn";//$NON-NLS-1$
129

130     // Section from a 3.1 or earlier workbench
131
private static final String JavaDoc OLD_FILTER_SECTION = "filter"; //$NON-NLS-1$
132

133     static final Object JavaDoc MARKER_UPDATE_FAMILY = new Object JavaDoc();
134
135     class MarkerProcessJob extends Job {
136
137         /**
138          * Create a new instance of the receiver.
139          */

140         MarkerProcessJob() {
141             super(MarkerMessages.MarkerView_processUpdates);
142             setSystem(true);
143         }
144
145         /*
146          * (non-Javadoc)
147          *
148          * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
149          */

150         protected IStatus run(IProgressMonitor monitor) {
151             updateForContentsRefresh(monitor);
152             return Status.OK_STATUS;
153
154         }
155
156         /*
157          * (non-Javadoc)
158          *
159          * @see org.eclipse.ui.progress.WorkbenchJob#shouldRun()
160          */

161         public boolean shouldRun() {
162             // Do not run if the change came in before there is a viewer
163
return PlatformUI.isWorkbenchRunning();
164         }
165
166         /*
167          * (non-Javadoc)
168          *
169          * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object)
170          */

171         public boolean belongsTo(Object JavaDoc family) {
172             return MARKER_UPDATE_FAMILY == family;
173         }
174
175     }
176
177     MarkerProcessJob markerProcessJob = new MarkerProcessJob();
178
179     private class UpdateJob extends WorkbenchJob {
180
181         private class MarkerDescriptor {
182             String JavaDoc description;
183
184             String JavaDoc folder;
185
186             String JavaDoc resource;
187
188             int line;
189
190             MarkerDescriptor(ConcreteMarker marker) {
191                 description = marker.getDescription();
192                 folder = marker.getFolder();
193                 resource = marker.getResourceName();
194                 line = marker.getLine();
195             }
196
197             boolean isEquivalentTo(ConcreteMarker marker) {
198                 return marker.getDescription().equals(description)
199                         && marker.getFolder().equals(folder)
200                         && marker.getResourceName().equals(resource)
201                         && marker.getLine() == line;
202             }
203
204         }
205
206         private Collection JavaDoc categoriesToExpand = new HashSet JavaDoc();
207
208         private Collection JavaDoc preservedSelection = new ArrayList JavaDoc();
209
210         UpdateJob() {
211             super(MarkerMessages.MarkerView_queueing_updates);
212             setSystem(true);
213         }
214
215         /*
216          * (non-Javadoc)
217          *
218          * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
219          */

220         public IStatus runInUIThread(IProgressMonitor monitor) {
221
222             if (getViewer().getControl().isDisposed()) {
223                 return Status.CANCEL_STATUS;
224             }
225
226             if (monitor.isCanceled())
227                 return Status.CANCEL_STATUS;
228
229             getViewer().refresh(true);
230
231             Tree tree = getTree();
232
233             if (tree != null && !tree.isDisposed()) {
234                 updateStatusMessage();
235                 updateTitle();
236                 // Expand all if the list is small
237
if (getCurrentMarkers().getSize() < 20) {
238                     getViewer().expandAll();
239                 } else {// Reexpand the old categories
240
MarkerCategory[] categories = getMarkerAdapter()
241                             .getCategories();
242                     if (categories == null)
243                         categoriesToExpand.clear();
244                     else {
245                         if (categories.length == 1) {// Expand if there is
246
// only
247
// one
248
getViewer().expandAll();
249                             categoriesToExpand.clear();
250                             if (monitor.isCanceled())
251                                 return Status.CANCEL_STATUS;
252                             categoriesToExpand.add(categories[0].getName());
253                         } else {
254                             Collection JavaDoc newCategories = new HashSet JavaDoc();
255                             for (int i = 0; i < categories.length; i++) {
256                                 if (monitor.isCanceled())
257                                     return Status.CANCEL_STATUS;
258                                 MarkerCategory category = categories[i];
259                                 if (categoriesToExpand.contains(category
260                                         .getName())) {
261                                     getViewer().expandToLevel(category,
262                                             AbstractTreeViewer.ALL_LEVELS);
263                                     newCategories.add(category.getName());
264                                 }
265
266                             }
267                             categoriesToExpand = newCategories;
268                         }
269                     }
270
271                 }
272             }
273
274             if (preservedSelection.size() > 0) {
275
276                 Collection JavaDoc newSelection = new ArrayList JavaDoc();
277                 ConcreteMarker[] markers = getCurrentMarkers().toArray();
278
279                 for (int i = 0; i < markers.length; i++) {
280                     Iterator JavaDoc preserved = preservedSelection.iterator();
281                     while (preserved.hasNext()) {
282                         MarkerDescriptor next = (MarkerDescriptor) preserved
283                                 .next();
284                         if (next.isEquivalentTo(markers[i])) {
285                             newSelection.add(markers[i]);
286                             continue;
287                         }
288                     }
289                 }
290
291                 getViewer().setSelection(
292                         new StructuredSelection(newSelection.toArray()), true);
293                 preservedSelection.clear();
294             }
295             if (getViewer().getTree().getItemCount() > 0)
296                 getViewer().getTree().setTopItem(
297                         getViewer().getTree().getItem(0));
298
299             return Status.OK_STATUS;
300         }
301
302         /**
303          * Add the category to the list of expanded categories.
304          *
305          * @param category
306          */

307         public void addExpandedCategory(MarkerCategory category) {
308             categoriesToExpand.add(category.getName());
309
310         }
311
312         /**
313          * Remove the category from the list of expanded ones.
314          *
315          * @param category
316          */

317         public void removeExpandedCategory(MarkerCategory category) {
318             categoriesToExpand.remove(category.getName());
319
320         }
321
322         /*
323          * (non-Javadoc)
324          *
325          * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object)
326          */

327         public boolean belongsTo(Object JavaDoc family) {
328             return family == MARKER_UPDATE_FAMILY;
329         }
330
331         /**
332          * Preserve the selection for reselection after the next update.
333          *
334          * @param selection
335          */

336         public void saveSelection(ISelection selection) {
337             preservedSelection.clear();
338             if (selection instanceof IStructuredSelection) {
339                 IStructuredSelection structured = (IStructuredSelection) selection;
340                 Iterator JavaDoc iterator = structured.iterator();
341                 while (iterator.hasNext()) {
342                     MarkerNode next = (MarkerNode) iterator.next();
343                     if (next.isConcrete()) {
344                         preservedSelection.add(new MarkerDescriptor(next
345                                 .getConcreteRepresentative()));
346                     }
347                 }
348             }
349
350         }
351
352         /*
353          * (non-Javadoc)
354          *
355          * @see org.eclipse.ui.progress.WorkbenchJob#shouldRun()
356          */

357         public boolean shouldRun() {
358             return !getMarkerAdapter().isBuilding();
359         }
360
361     }
362
363     private UpdateJob updateJob = new UpdateJob();
364
365     // A private field for keeping track of the number of markers
366
// before the busy testing started
367
private int preBusyMarkers = 0;
368
369     protected Object JavaDoc[] focusElements;
370
371     private Clipboard clipboard;
372
373     IResourceChangeListener markerUpdateListener = new IResourceChangeListener() {
374
375         /*
376          * (non-Javadoc)
377          *
378          * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
379          */

380         public void resourceChanged(IResourceChangeEvent event) {
381             if (!hasMarkerDelta(event))
382                 return;
383
384             if (event.getType() == IResourceChangeEvent.POST_BUILD) {
385                 scheduleMarkerUpdate(Util.SHORT_DELAY);
386                 return;
387             }
388
389             // After 30 seconds do updates anyways
390

391             IWorkbenchSiteProgressService progressService = getProgressService();
392             if (progressService == null)
393                 markerProcessJob.schedule(Util.LONG_DELAY);
394             else
395                 getProgressService()
396                         .schedule(markerProcessJob, Util.LONG_DELAY);
397
398         }
399
400         /**
401          * Returns whether or not the given even contains marker deltas for this
402          * view.
403          *
404          * @param event
405          * the resource change event
406          * @return <code>true</code> if the event contains at least one
407          * relevant marker delta
408          * @since 3.3
409          */

410         private boolean hasMarkerDelta(IResourceChangeEvent event) {
411             String JavaDoc[] markerTypes = getMarkerTypes();
412             for (int i = 0; i < markerTypes.length; i++) {
413                 if (event.findMarkerDeltas(markerTypes[i], true).length > 0) {
414                     return true;
415                 }
416             }
417             return false;
418         }
419
420     };
421
422     private class ContextProvider implements IContextProvider {
423         public int getContextChangeMask() {
424             return SELECTION;
425         }
426
427         public IContext getContext(Object JavaDoc target) {
428             String JavaDoc contextId = null;
429             // See if there is a context registered for the current selection
430
ConcreteMarker marker = getSelectedConcreteMarker();
431             if (marker != null) {
432                 contextId = IDE.getMarkerHelpRegistry().getHelp(
433                         marker.getMarker());
434             }
435
436             if (contextId == null) {
437                 contextId = getStaticContextId();
438             }
439             return HelpSystem.getContext(contextId);
440         }
441
442         /**
443          * Return the currently selected concrete marker or <code>null</code>
444          * if there isn't one.
445          *
446          * @return ConcreteMarker
447          */

448         private ConcreteMarker getSelectedConcreteMarker() {
449
450             IStructuredSelection selection = (IStructuredSelection) getViewer()
451                     .getSelection();
452             if (selection.isEmpty())
453                 return null;
454
455             if (selection.getFirstElement() instanceof ConcreteMarker)
456                 return (ConcreteMarker) selection.getFirstElement();
457             return null;
458         }
459
460         /*
461          * (non-Javadoc)
462          *
463          * @see org.eclipse.help.IContextProvider#getSearchExpression(java.lang.Object)
464          */

465         public String JavaDoc getSearchExpression(Object JavaDoc target) {
466             return null;
467         }
468     }
469
470     private ContextProvider contextProvider = new ContextProvider();
471
472     protected ActionCopyMarker copyAction;
473
474     protected ActionPasteMarker pasteAction;
475
476     protected SelectionProviderAction revealAction;
477
478     protected SelectionProviderAction openAction;
479
480     protected SelectionProviderAction deleteAction;
481
482     protected SelectionProviderAction selectAllAction;
483
484     protected SelectionProviderAction propertiesAction;
485
486     protected UndoActionHandler undoAction;
487
488     protected RedoActionHandler redoAction;
489
490     private ISelectionListener focusListener = new ISelectionListener() {
491         public void selectionChanged(IWorkbenchPart part, ISelection selection) {
492             MarkerView.this.focusSelectionChanged(part, selection);
493         }
494     };
495
496     private int totalMarkers = 0;
497
498     private MarkerFilter[] markerFilters = new MarkerFilter[0];
499
500     // A cache of the enabled filters
501
private MarkerFilter[] enabledFilters = null;
502
503     private MenuManager filtersMenu;
504
505     private MenuManager showInMenu;
506
507     private IPropertyChangeListener workingSetListener;
508
509     private MarkerAdapter adapter;
510
511     private IPropertyChangeListener preferenceListener;
512
513     /**
514      * Create a new instance of the receiver,
515      */

516     public MarkerView() {
517         super();
518         preferenceListener = new IPropertyChangeListener() {
519             /*
520              * (non-Javadoc)
521              *
522              * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
523              */

524             public void propertyChange(PropertyChangeEvent event) {
525                 if (event.getProperty().equals(getFiltersPreferenceName())) {
526                     loadFiltersPreferences();
527                     clearEnabledFilters();
528                     refreshForFocusUpdate();
529                 }
530             }
531         };
532         IDEWorkbenchPlugin.getDefault().getPreferenceStore()
533                 .addPropertyChangeListener(preferenceListener);
534     }
535
536     /**
537      * Get the current markers for the receiver.
538      *
539      * @return MarkerList
540      */

541     public MarkerList getCurrentMarkers() {
542         return getMarkerAdapter().getCurrentMarkers();
543     }
544
545     /**
546      * Get the marker adapter for the receiver.
547      *
548      * @return MarkerAdapter
549      */

550     protected MarkerAdapter getMarkerAdapter() {
551         return adapter;
552     }
553
554     /**
555      * Update for the change in the contents.
556      *
557      * @param monitor
558      */

559     public void updateForContentsRefresh(IProgressMonitor monitor) {
560         updateJob.cancel();
561         getMarkerAdapter().buildAllMarkers(monitor);
562         getProgressService().schedule(updateJob);
563     }
564
565     /*
566      * (non-Javadoc)
567      *
568      * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite,
569      * org.eclipse.ui.IMemento)
570      */

571     public void init(IViewSite site, IMemento memento) throws PartInitException {
572         super.init(site, memento);
573         IWorkbenchSiteProgressService progressService = getProgressService();
574         if (progressService != null) {
575             getProgressService().showBusyForFamily(
576                     ResourcesPlugin.FAMILY_MANUAL_BUILD);
577             getProgressService().showBusyForFamily(
578                     ResourcesPlugin.FAMILY_AUTO_BUILD);
579             getProgressService().showBusyForFamily(MARKER_UPDATE_FAMILY);
580         }
581         loadFiltersPreferences();
582
583     }
584
585     /**
586      * Load the filters preference.
587      */

588     private void loadFiltersPreferences() {
589
590         String JavaDoc preference = IDEWorkbenchPlugin.getDefault()
591                 .getPreferenceStore().getString(getFiltersPreferenceName());
592
593         if (preference.equals(IPreferenceStore.STRING_DEFAULT_DEFAULT)) {
594             createDefaultFilter();
595             return;
596         }
597
598         StringReader JavaDoc reader = new StringReader JavaDoc(preference);
599         try {
600             restoreFilters(XMLMemento.createReadRoot(reader));
601         } catch (WorkbenchException e) {
602             IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
603         }
604
605     }
606
607     /**
608      * Update for filter changes. Save the preference and clear the enabled
609      * cache.
610      */

611     void updateForFilterChanges() {
612
613         XMLMemento memento = XMLMemento.createWriteRoot(TAG_FILTERS_SECTION);
614
615         writeFiltersSettings(memento);
616
617         StringWriter JavaDoc writer = new StringWriter JavaDoc();
618         try {
619             memento.save(writer);
620         } catch (IOException JavaDoc e) {
621             IDEWorkbenchPlugin.getDefault().getLog().log(Util.errorStatus(e));
622         }
623
624         IDEWorkbenchPlugin.getDefault().getPreferenceStore().putValue(
625                 getFiltersPreferenceName(), writer.toString());
626         IDEWorkbenchPlugin.getDefault().savePluginPreferences();
627
628         clearEnabledFilters();
629         refreshFilterMenu();
630         refreshViewer();
631     }
632
633     /**
634      * Write the filter settings to the memento.
635      *
636      * @param memento
637      */

638     protected void writeFiltersSettings(XMLMemento memento) {
639         MarkerFilter[] filters = getUserFilters();
640         for (int i = 0; i < filters.length; i++) {
641             IMemento child = memento.createChild(TAG_FILTER_ENTRY, filters[i]
642                     .getName());
643             filters[i].saveFilterSettings(child);
644         }
645     }
646
647     /**
648      * Get the name of the filters preference for instances of the receiver.
649      *
650      * @return String
651      */

652     abstract String JavaDoc getFiltersPreferenceName();
653
654     /**
655      * Restore the filters from the mimento.
656      *
657      * @param memento
658      */

659     void restoreFilters(IMemento memento) {
660
661         IMemento[] sections = null;
662         if (memento != null) {
663             sections = memento.getChildren(TAG_FILTER_ENTRY);
664         }
665
666         if (sections == null) {
667             // Check if we have an old filter setting around
668
IDialogSettings mainSettings = getDialogSettings();
669             IDialogSettings filtersSection = mainSettings
670                     .getSection(OLD_FILTER_SECTION);
671             if (filtersSection != null) {
672                 MarkerFilter markerFilter = createFilter(MarkerMessages.MarkerFilter_defaultFilterName);
673                 markerFilter.restoreFilterSettings(filtersSection);
674                 setFilters(new MarkerFilter[] { markerFilter });
675             }
676
677         } else {
678             MarkerFilter[] newFilters = new MarkerFilter[sections.length];
679
680             for (int i = 0; i < sections.length; i++) {
681                 newFilters[i] = createFilter(sections[i].getID());
682                 newFilters[i].restoreState(sections[i]);
683             }
684             setFilters(newFilters);
685         }
686
687         if (markerFilters.length == 0) {// Make sure there is at least a default
688
createDefaultFilter();
689         }
690
691     }
692
693     /**
694      * Create a default filter for the receiver.
695      *
696      */

697     private void createDefaultFilter() {
698         MarkerFilter filter = createFilter(MarkerMessages.MarkerFilter_defaultFilterName);
699         setFilters(new MarkerFilter[] { filter });
700     }
701
702     /**
703      * Create a filter called name.
704      *
705      * @param name
706      * @return MarkerFilter
707      */

708     protected abstract MarkerFilter createFilter(String JavaDoc name);
709
710     /**
711      * Return the memento tag for the receiver.
712      *
713      * @return String
714      */

715     protected abstract String JavaDoc getSectionTag();
716
717     /*
718      * (non-Javadoc)
719      *
720      * @see org.eclipse.ui.views.internal.tableview.TableView#createPartControl(org.eclipse.swt.widgets.Composite)
721      */

722     public void createPartControl(Composite parent) {
723
724         clipboard = new Clipboard(parent.getDisplay());
725         super.createPartControl(parent);
726
727         initDragAndDrop();
728
729         getSite().getPage().addSelectionListener(focusListener);
730         focusSelectionChanged(getSite().getPage().getActivePart(), getSite()
731                 .getPage().getSelection());
732         PlatformUI.getWorkbench().getWorkingSetManager()
733                 .addPropertyChangeListener(getWorkingSetListener());
734
735         // Set help on the view itself
736
getViewer().getControl().addHelpListener(new HelpListener() {
737             /*
738              * (non-Javadoc)
739              *
740              * @see org.eclipse.swt.events.HelpListener#helpRequested(org.eclipse.swt.events.HelpEvent)
741              */

742             public void helpRequested(HelpEvent e) {
743                 IContext context = contextProvider.getContext(getViewer()
744                         .getControl());
745                 PlatformUI.getWorkbench().getHelpSystem().displayHelp(context);
746             }
747         });
748
749         // Hook up to the resource changes after all widget have been created
750
ResourcesPlugin.getWorkspace().addResourceChangeListener(
751                 markerUpdateListener,
752                 IResourceChangeEvent.POST_CHANGE
753                         | IResourceChangeEvent.PRE_BUILD
754                         | IResourceChangeEvent.POST_BUILD);
755     }
756
757     /*
758      * (non-Javadoc)
759      *
760      * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
761      */

762     public Object JavaDoc getAdapter(Class JavaDoc adaptable) {
763         if (adaptable.equals(IContextProvider.class)) {
764             return contextProvider;
765         }
766         if (adaptable.equals(IShowInSource.class)) {
767             return new IShowInSource() {
768                 public ShowInContext getShowInContext() {
769                     ISelection selection = getViewer().getSelection();
770                     if (!(selection instanceof IStructuredSelection)) {
771                         return null;
772                     }
773                     IStructuredSelection structured = (IStructuredSelection) selection;
774                     Iterator JavaDoc markerIterator = structured.iterator();
775                     List JavaDoc newSelection = new ArrayList JavaDoc();
776                     while (markerIterator.hasNext()) {
777                         ConcreteMarker element = (ConcreteMarker) markerIterator
778                                 .next();
779                         newSelection.add(element.getResource());
780                     }
781                     return new ShowInContext(getViewer().getInput(),
782                             new StructuredSelection(newSelection));
783                 }
784
785             };
786         }
787         return super.getAdapter(adaptable);
788     }
789
790     /*
791      * (non-Javadoc)
792      *
793      * @see org.eclipse.ui.views.markers.internal.TableView#viewerSelectionChanged(org.eclipse.jface.viewers.IStructuredSelection)
794      */

795     protected void viewerSelectionChanged(IStructuredSelection selection) {
796
797         Object JavaDoc[] rawSelection = selection.toArray();
798
799         List JavaDoc markers = new ArrayList JavaDoc();
800
801         for (int idx = 0; idx < rawSelection.length; idx++) {
802
803             if (rawSelection[idx] instanceof ConcreteMarker)
804                 markers.add(((ConcreteMarker) rawSelection[idx]).getMarker());
805         }
806
807         setSelection(new StructuredSelection(markers));
808
809         updateStatusMessage(selection);
810     }
811
812     /*
813      * (non-Javadoc)
814      *
815      * @see org.eclipse.ui.views.internal.tableview.TableView#dispose()
816      */

817     public void dispose() {
818         super.dispose();
819         cancelJobs();
820
821         ResourcesPlugin.getWorkspace().removeResourceChangeListener(
822                 markerUpdateListener);
823         PlatformUI.getWorkbench().getWorkingSetManager()
824                 .removePropertyChangeListener(workingSetListener);
825         IDEWorkbenchPlugin.getDefault().getPreferenceStore()
826                 .removePropertyChangeListener(preferenceListener);
827         getSite().getPage().removeSelectionListener(focusListener);
828
829         // dispose of selection provider actions (may not have been created yet
830
// if createPartControls was never called)
831
if (openAction != null) {
832             openAction.dispose();
833             copyAction.dispose();
834             selectAllAction.dispose();
835             deleteAction.dispose();
836             revealAction.dispose();
837             propertiesAction.dispose();
838             undoAction.dispose();
839             redoAction.dispose();
840             clipboard.dispose();
841         }
842         if (showInMenu != null) {
843             showInMenu.dispose();
844         }
845     }
846
847     /*
848      * (non-Javadoc)
849      *
850      * @see org.eclipse.ui.views.internal.tableview.TableView#createActions()
851      */

852     protected void createActions() {
853         revealAction = new ActionRevealMarker(this, getViewer());
854         openAction = new ActionOpenMarker(this, getViewer());
855         copyAction = new ActionCopyMarker(this, getViewer());
856         copyAction.setClipboard(clipboard);
857         copyAction.setProperties(getSortingFields());
858         pasteAction = new ActionPasteMarker(this, getViewer(), getMarkerName());
859         pasteAction.setClipboard(clipboard);
860         pasteAction.setPastableTypes(getMarkerTypes());
861         deleteAction = new ActionRemoveMarker(this, getViewer(),
862                 getMarkerName());
863         selectAllAction = new ActionSelectAll(this);
864         propertiesAction = new ActionMarkerProperties(this, getViewer(),
865                 getMarkerName());
866
867         IUndoContext undoContext = getUndoContext();
868         undoAction = new UndoActionHandler(getSite(), undoContext);
869         redoAction = new RedoActionHandler(getSite(), undoContext);
870
871         super.createActions();
872
873         setFilterAction(new FiltersAction(this));
874
875         setPreferencesAction(new ViewPreferencesAction() {
876             /*
877              * (non-Javadoc)
878              *
879              * @see org.eclipse.ui.preferences.ViewPreferencesAction#openViewPreferencesDialog()
880              */

881             public void openViewPreferencesDialog() {
882                 openPreferencesDialog(getMarkerEnablementPreferenceName(),
883                         getMarkerLimitPreferenceName());
884
885             }
886
887         });
888     }
889
890     /**
891      * Open a dialog to set the preferences.
892      *
893      * @param markerEnablementPreferenceName
894      * @param markerLimitPreferenceName
895      */

896     private void openPreferencesDialog(String JavaDoc markerEnablementPreferenceName,
897             String JavaDoc markerLimitPreferenceName) {
898
899         Dialog dialog = new MarkerViewPreferenceDialog(getSite()
900                 .getWorkbenchWindow().getShell(),
901                 markerEnablementPreferenceName, markerLimitPreferenceName,
902                 MarkerMessages.MarkerPreferences_DialogTitle);
903         if (dialog.open() == Window.OK) {
904             refreshViewer();
905         }
906
907     }
908
909     /**
910      * Get the name of the marker enablement preference.
911      *
912      * @return String
913      */

914     abstract String JavaDoc getMarkerLimitPreferenceName();
915
916     abstract String JavaDoc[] getMarkerTypes();
917
918     /*
919      * (non-Javadoc)
920      *
921      * @see org.eclipse.ui.views.internal.tableview.TableView#initToolBar(org.eclipse.jface.action.IToolBarManager)
922      */

923     protected void initToolBar(IToolBarManager tbm) {
924         tbm.add(deleteAction);
925         tbm.add(getFilterAction());
926         tbm.update(false);
927     }
928
929     /*
930      * (non-Javadoc)
931      *
932      * @see org.eclipse.ui.views.internal.tableview.TableView#registerGlobalActions(org.eclipse.ui.IActionBars)
933      */

934     protected void registerGlobalActions(IActionBars actionBars) {
935         actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
936                 copyAction);
937         actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(),
938                 pasteAction);
939         actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),
940                 deleteAction);
941         actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
942                 selectAllAction);
943         actionBars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(),
944                 propertiesAction);
945         actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(),
946                 undoAction);
947         actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(),
948                 redoAction);
949
950         copyAction.setActionDefinitionId("org.eclipse.ui.edit.copy"); //$NON-NLS-1$
951
pasteAction.setActionDefinitionId("org.eclipse.ui.edit.paste"); //$NON-NLS-1$
952
deleteAction.setActionDefinitionId("org.eclipse.ui.edit.delete"); //$NON-NLS-1$
953
selectAllAction.setActionDefinitionId("org.eclipse.ui.edit.selectAll"); //$NON-NLS-1$
954
propertiesAction
955                 .setActionDefinitionId("org.eclipse.ui.file.properties"); //$NON-NLS-1$
956
undoAction.setActionDefinitionId("org.eclipse.ui.edit.undo"); //$NON-NLS-1$
957
redoAction.setActionDefinitionId("org.eclipse.ui.edit.redo"); //$NON-NLS-1$
958
}
959
960     protected void initDragAndDrop() {
961         int operations = DND.DROP_COPY;
962         Transfer[] transferTypes = new Transfer[] {
963                 MarkerTransfer.getInstance(), TextTransfer.getInstance() };
964         DragSourceListener listener = new DragSourceAdapter() {
965             public void dragSetData(DragSourceEvent event) {
966                 performDragSetData(event);
967             }
968
969             public void dragFinished(DragSourceEvent event) {
970             }
971         };
972
973         getViewer().addDragSupport(operations, transferTypes, listener);
974     }
975
976     /**
977      * The user is attempting to drag marker data. Add the appropriate data to
978      * the event depending on the transfer type.
979      */

980     private void performDragSetData(DragSourceEvent event) {
981         if (MarkerTransfer.getInstance().isSupportedType(event.dataType)) {
982
983             event.data = getSelectedMarkers();
984             return;
985         }
986         if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
987             List JavaDoc selection = ((IStructuredSelection) getViewer().getSelection())
988                     .toList();
989             try {
990                 IMarker[] markers = new IMarker[selection.size()];
991                 selection.toArray(markers);
992                 if (markers != null) {
993                     event.data = copyAction.createMarkerReport(markers);
994                 }
995             } catch (ArrayStoreException JavaDoc e) {
996             }
997         }
998     }
999
1000    /**
1001     * Get the array of selected markers.
1002     *
1003     * @return IMarker[]
1004     */

1005    private IMarker[] getSelectedMarkers() {
1006        Object JavaDoc[] selection = ((IStructuredSelection) getViewer().getSelection())
1007                .toArray();
1008        ArrayList JavaDoc markers = new ArrayList JavaDoc();
1009        for (int i = 0; i < selection.length; i++) {
1010            if (selection[i] instanceof ConcreteMarker) {
1011                markers.add(((ConcreteMarker) selection[i]).getMarker());
1012            }
1013        }
1014        return (IMarker[]) markers.toArray(new IMarker[markers.size()]);
1015    }
1016
1017    /*
1018     * (non-Javadoc)
1019     *
1020     * @see org.eclipse.ui.views.internal.tableview.TableView#fillContextMenu(org.eclipse.jface.action.IMenuManager)
1021     */

1022    protected void fillContextMenu(IMenuManager manager) {
1023        if (manager == null) {
1024            return;
1025        }
1026        manager.add(openAction);
1027        createShowInMenu(manager);
1028        manager.add(new Separator());
1029        manager.add(copyAction);
1030        pasteAction.updateEnablement();
1031        manager.add(pasteAction);
1032
1033        if (canBeEditable()) {
1034            manager.add(deleteAction);
1035        }
1036        manager.add(selectAllAction);
1037        fillContextMenuAdditions(manager);
1038        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
1039        manager.add(new Separator());
1040        manager.add(propertiesAction);
1041    }
1042
1043    /**
1044     * Return whether or not any of the types in the receiver can be editable.
1045     *
1046     * @return <code>true</code> if it is possible to have an editable marker
1047     * in this view.
1048     */

1049    boolean canBeEditable() {
1050        return true;
1051    }
1052
1053    /**
1054     * Fill the context menu for the receiver.
1055     *
1056     * @param manager
1057     */

1058    abstract void fillContextMenuAdditions(IMenuManager manager);
1059
1060    /**
1061     * Get the filters for the receiver.
1062     *
1063     * @return MarkerFilter[]
1064     */

1065    protected final MarkerFilter[] getUserFilters() {
1066        return markerFilters;
1067    }
1068
1069    /*
1070     * (non-Javadoc)
1071     *
1072     * @see org.eclipse.ui.views.internal.tableview.TableView#handleKeyPressed(org.eclipse.swt.events.KeyEvent)
1073     */

1074    protected void handleKeyPressed(KeyEvent event) {
1075        // Default is do nothing.
1076
}
1077
1078    /*
1079     * (non-Javadoc)
1080     *
1081     * @see org.eclipse.ui.views.internal.tableview.TableView#handleOpenEvent(org.eclipse.jface.viewers.OpenEvent)
1082     */

1083    protected void handleOpenEvent(OpenEvent event) {
1084        if (openAction.isEnabled()) {
1085            openAction.run();
1086        }
1087    }
1088
1089    /*
1090     * (non-Javadoc)
1091     *
1092     * @see org.eclipse.ui.views.internal.tableview.TableView#saveSelection(org.eclipse.ui.IMemento)
1093     */

1094    protected void saveSelection(IMemento memento) {
1095        IStructuredSelection selection = (IStructuredSelection) getViewer()
1096                .getSelection();
1097        IMemento selectionMem = memento.createChild(TAG_SELECTION);
1098        for (Iterator JavaDoc iterator = selection.iterator(); iterator.hasNext();) {
1099            Object JavaDoc next = iterator.next();
1100            if (!(next instanceof ConcreteMarker)) {
1101                continue;
1102            }
1103            ConcreteMarker marker = (ConcreteMarker) next;
1104            IMemento elementMem = selectionMem.createChild(TAG_MARKER);
1105            elementMem.putString(TAG_RESOURCE, marker.getMarker().getResource()
1106                    .getFullPath().toString());
1107            elementMem.putString(TAG_ID, String.valueOf(marker.getMarker()
1108                    .getId()));
1109        }
1110    }
1111
1112    protected abstract String JavaDoc[] getRootTypes();
1113
1114    /**
1115     * @param part
1116     * @param selection
1117     */

1118    protected void focusSelectionChanged(IWorkbenchPart part,
1119            ISelection selection) {
1120
1121        List JavaDoc selectedElements = new ArrayList JavaDoc();
1122        if (part instanceof IEditorPart) {
1123            IEditorPart editor = (IEditorPart) part;
1124            IFile file = ResourceUtil.getFile(editor.getEditorInput());
1125            if (file == null) {
1126                IEditorInput editorInput = editor.getEditorInput();
1127                if (editorInput != null) {
1128                    Object JavaDoc mapping = editorInput
1129                            .getAdapter(ResourceMapping.class);
1130                    if (mapping != null) {
1131                        selectedElements.add(mapping);
1132                    }
1133                }
1134            } else {
1135                selectedElements.add(file);
1136            }
1137        } else {
1138            if (selection instanceof IStructuredSelection) {
1139                for (Iterator JavaDoc iterator = ((IStructuredSelection) selection)
1140                        .iterator(); iterator.hasNext();) {
1141                    Object JavaDoc object = iterator.next();
1142                    if (object instanceof IAdaptable) {
1143                        ITaskListResourceAdapter taskListResourceAdapter;
1144                        Object JavaDoc adapter = ((IAdaptable) object)
1145                                .getAdapter(ITaskListResourceAdapter.class);
1146                        if (adapter != null
1147                                && adapter instanceof ITaskListResourceAdapter) {
1148                            taskListResourceAdapter = (ITaskListResourceAdapter) adapter;
1149                        } else {
1150                            taskListResourceAdapter = DefaultMarkerResourceAdapter
1151                                    .getDefault();
1152                        }
1153
1154                        IResource resource = taskListResourceAdapter
1155                                .getAffectedResource((IAdaptable) object);
1156                        if (resource == null) {
1157                            Object JavaDoc mapping = ((IAdaptable) object)
1158                                    .getAdapter(ResourceMapping.class);
1159                            if (mapping != null) {
1160                                selectedElements.add(mapping);
1161                            }
1162                        } else {
1163                            selectedElements.add(resource);
1164                        }
1165                    }
1166                }
1167            }
1168        }
1169        updateFocusMarkers(selectedElements.toArray());
1170    }
1171
1172    /**
1173     * Update the focus resources of the filters.
1174     *
1175     * @param elements
1176     */

1177    protected final void updateFilterSelection(Object JavaDoc[] elements) {
1178
1179        Collection JavaDoc resourceCollection = new ArrayList JavaDoc();
1180        for (int i = 0; i < elements.length; i++) {
1181            if (elements[i] instanceof IResource) {
1182                resourceCollection.add(elements[i]);
1183            } else {
1184                addResources(resourceCollection,
1185                        ((ResourceMapping) elements[i]));
1186            }
1187        }
1188
1189        IResource[] resources = new IResource[resourceCollection.size()];
1190        resourceCollection.toArray(resources);
1191
1192        for (int i = 0; i < markerFilters.length; i++) {
1193            markerFilters[i].setFocusResource(resources);
1194        }
1195
1196        Iterator JavaDoc systemFilters = MarkerSupportRegistry.getInstance()
1197                .getRegisteredFilters().iterator();
1198
1199        while (systemFilters.hasNext()) {
1200            MarkerFilter filter = (MarkerFilter) systemFilters.next();
1201            filter.setFocusResource(resources);
1202
1203        }
1204
1205    }
1206
1207    /**
1208     * Add the resources for the mapping to resources.
1209     *
1210     * @param resources
1211     * @param mapping
1212     */

1213    private void addResources(Collection JavaDoc resources, ResourceMapping mapping) {
1214        try {
1215            ResourceTraversal[] traversals = mapping.getTraversals(
1216                    ResourceMappingContext.LOCAL_CONTEXT,
1217                    new NullProgressMonitor());
1218            for (int i = 0; i < traversals.length; i++) {
1219                ResourceTraversal traversal = traversals[i];
1220                IResource[] result = traversal.getResources();
1221                for (int j = 0; j < result.length; j++) {
1222                    resources.add(result[j]);
1223                }
1224            }
1225        } catch (CoreException e) {
1226            Util.log(e);
1227            return;
1228        }
1229
1230    }
1231
1232    protected abstract String JavaDoc getStaticContextId();
1233
1234    /**
1235     * Update the focus markers for the supplied elements.
1236     *
1237     * @param elements
1238     */

1239    void updateFocusMarkers(Object JavaDoc[] elements) {
1240        boolean updateNeeded = updateNeeded(focusElements, elements);
1241        if (updateNeeded) {
1242            focusElements = elements;
1243            refreshForFocusUpdate();
1244        }
1245    }
1246
1247    private boolean updateNeeded(Object JavaDoc[] oldElements, Object JavaDoc[] newElements) {
1248        // determine if an update if refiltering is required
1249
MarkerFilter[] filters = getEnabledFilters();
1250        boolean updateNeeded = false;
1251
1252        for (int i = 0; i < filters.length; i++) {
1253            MarkerFilter filter = filters[i];
1254            if (!filter.isEnabled()) {
1255                continue;
1256            }
1257
1258            int onResource = filter.getOnResource();
1259            if (onResource == MarkerFilter.ON_ANY
1260                    || onResource == MarkerFilter.ON_WORKING_SET) {
1261                continue;
1262            }
1263            if (newElements == null || newElements.length < 1) {
1264                continue;
1265            }
1266            if (oldElements == null || oldElements.length < 1) {
1267                return true;
1268            }
1269            if (Arrays.equals(oldElements, newElements)) {
1270                continue;
1271            }
1272            if (onResource == MarkerFilter.ON_ANY_IN_SAME_CONTAINER) {
1273                Collection JavaDoc oldProjects = MarkerFilter
1274                        .getProjectsAsCollection(oldElements);
1275                Collection JavaDoc newProjects = MarkerFilter
1276                        .getProjectsAsCollection(newElements);
1277
1278                if (oldProjects.size() == newProjects.size()) {
1279                    if (newProjects.containsAll(oldProjects)) {
1280                        continue;
1281                    }
1282                }
1283
1284                return true;
1285            }
1286            updateNeeded = true;// We are updating as there is nothing to stop
1287
// us
1288
}
1289
1290        return updateNeeded;
1291    }
1292
1293    void updateTitle() {
1294        String JavaDoc status = Util.EMPTY_STRING;
1295        int filteredCount = getCurrentMarkers().getItemCount();
1296        int totalCount = getTotalMarkers();
1297        if (filteredCount == totalCount) {
1298            status = NLS.bind(MarkerMessages.filter_itemsMessage, new Integer JavaDoc(
1299                    totalCount));
1300        } else {
1301            status = NLS.bind(MarkerMessages.filter_matchedMessage,
1302                    new Integer JavaDoc(filteredCount), new Integer JavaDoc(totalCount));
1303        }
1304        setContentDescription(status);
1305    }
1306
1307    /**
1308     * Updates the message displayed in the status line. This method is invoked
1309     * in the following cases:
1310     * <ul>
1311     * <li>when this view is first created</li>
1312     * <li>when new elements are added</li>
1313     * <li>when something is deleted</li>
1314     * <li>when the filters change</li>
1315     * </ul>
1316     * <p>
1317     * By default, this method calls
1318     * <code>updateStatusMessage(IStructuredSelection)</code> with the current
1319     * selection or <code>null</code>. Classes wishing to override this
1320     * functionality, should just override the method
1321     * <code>updateStatusMessage(IStructuredSelection)</code>.
1322     * </p>
1323     */

1324    protected void updateStatusMessage() {
1325        ISelection selection = getViewer().getSelection();
1326
1327        if (selection instanceof IStructuredSelection) {
1328            updateStatusMessage((IStructuredSelection) selection);
1329        } else {
1330            updateStatusMessage(null);
1331        }
1332    }
1333
1334    /**
1335     * Updates that message displayed in the status line. If the selection
1336     * parameter is <code>null</code> or its size is 0, the status area is
1337     * blanked out. If only 1 marker is selected, the status area is updated
1338     * with the contents of the message attribute of this marker. In other cases
1339     * (more than one marker is selected) the status area indicates how many
1340     * items have been selected.
1341     * <p>
1342     * This method may be overwritten.
1343     * </p>
1344     * <p>
1345     * This method is called whenever a selection changes in this view.
1346     * </p>
1347     *
1348     * @param selection
1349     * a valid selection or <code>null</code>
1350     */

1351    protected void updateStatusMessage(IStructuredSelection selection) {
1352        String JavaDoc message = ""; //$NON-NLS-1$
1353

1354        if (selection == null || selection.size() == 0) {
1355            // Show stats on all items in the view
1356
message = updateSummaryVisible();
1357        } else if (selection.size() == 1) {
1358            // Use the Message attribute of the marker
1359
Object JavaDoc first = selection.getFirstElement();
1360            if (first instanceof ConcreteMarker) {
1361                message = ((ConcreteMarker) first).getDescription();
1362            }
1363        } else if (selection.size() > 1) {
1364            // Show stats on only those items in the selection
1365
message = updateSummarySelected(selection);
1366        }
1367        getViewSite().getActionBars().getStatusLineManager()
1368                .setMessage(message);
1369    }
1370
1371    /**
1372     * @param selection
1373     * @return the summary status message
1374     */

1375    protected String JavaDoc updateSummarySelected(IStructuredSelection selection) {
1376        // Show how many items selected
1377
return MessageFormat.format(
1378                MarkerMessages.marker_statusSummarySelected,
1379                new Object JavaDoc[] { new Integer JavaDoc(selection.size()) });
1380    }
1381
1382    /**
1383     * @return the update summary
1384     */

1385    protected String JavaDoc updateSummaryVisible() {
1386        return ""; //$NON-NLS-1$
1387
}
1388
1389    /**
1390     * Open a dialog on the filters
1391     *
1392     */

1393    public final void openFiltersDialog() {
1394
1395        DialogMarkerFilter dialog = createFiltersDialog();
1396
1397        if (dialog.open() == Window.OK) {
1398
1399            MarkerFilter[] result = dialog.getFilters();
1400            if (result == null) {
1401                return;
1402            }
1403            if (result.length == 0) {
1404                setFilters(new MarkerFilter[] { createFilter(MarkerMessages.MarkerFilter_defaultFilterName) });
1405            } else {
1406                setFilters(result);
1407            }
1408
1409            updateForFilterChanges();
1410        }
1411    }
1412
1413    /**
1414     * Refresh the contents of the viewer.
1415     */

1416    public void refreshViewer() {
1417        scheduleMarkerUpdate(Util.SHORT_DELAY);
1418    }
1419
1420    /**
1421     * Set the filters to newFilters.
1422     *
1423     * @param newFilters
1424     */

1425    void setFilters(MarkerFilter[] newFilters) {
1426        markerFilters = newFilters;
1427    }
1428
1429    /**
1430     * Clear the cache of enabled filters.
1431     *
1432     */

1433    void clearEnabledFilters() {
1434        enabledFilters = null;
1435    }
1436
1437    /**
1438     * Refresh the contents of the filter sub menu.
1439     */

1440    private void refreshFilterMenu() {
1441        if (filtersMenu == null) {
1442            return;
1443        }
1444        filtersMenu.removeAll();
1445        MarkerFilter[] filters = getAllFilters();
1446        for (int i = 0; i < filters.length; i++) {
1447            filtersMenu.add(new FilterEnablementAction(filters[i], this));
1448        }
1449
1450    }
1451
1452    /**
1453     * Open a filter dialog on the receiver.
1454     */

1455    protected abstract DialogMarkerFilter createFiltersDialog();
1456
1457    /**
1458     * Given a selection of IMarker, reveals the corresponding elements in the
1459     * viewer
1460     *
1461     * @param structuredSelection
1462     * @param reveal
1463     */

1464    public void setSelection(IStructuredSelection structuredSelection,
1465            boolean reveal) {
1466        TreeViewer viewer = getViewer();
1467
1468        List JavaDoc newSelection = new ArrayList JavaDoc(structuredSelection.size());
1469
1470        for (Iterator JavaDoc i = structuredSelection.iterator(); i.hasNext();) {
1471            Object JavaDoc next = i.next();
1472            if (next instanceof IMarker) {
1473                ConcreteMarker marker = getCurrentMarkers().getMarker(
1474                        (IMarker) next);
1475                if (marker != null) {
1476                    newSelection.add(marker);
1477                }
1478            }
1479        }
1480
1481        if (viewer != null) {
1482            viewer.setSelection(new StructuredSelection(newSelection), reveal);
1483        }
1484    }
1485
1486    protected MarkerList getVisibleMarkers() {
1487        return getCurrentMarkers();
1488    }
1489
1490    /**
1491     * Returns the total number of markers. Should not be called while the
1492     * marker list is still updating.
1493     *
1494     * @return the total number of markers in the workspace (including
1495     * everything that doesn't pass the filters)
1496     */

1497    int getTotalMarkers() {
1498        // The number of visible markers should never exceed the total number of
1499
// markers in
1500
// the workspace. If this assertation fails, it probably indicates some
1501
// sort of concurrency problem
1502
// (most likely, getTotalMarkers was called while we were still
1503
// computing the marker lists)
1504
// Assert.isTrue(totalMarkers >= currentMarkers.getItemCount());
1505

1506        return totalMarkers;
1507    }
1508
1509    /*
1510     * (non-Javadoc)
1511     *
1512     * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
1513     */

1514    public void showBusy(boolean busy) {
1515        super.showBusy(busy);
1516
1517        if (busy) {
1518            preBusyMarkers = totalMarkers;
1519        } else {// Only bold if there has been a change in count
1520
if (totalMarkers != preBusyMarkers) {
1521                getProgressService().warnOfContentChange();
1522            }
1523        }
1524
1525    }
1526
1527    /**
1528     * Get the filters that are currently enabled.
1529     *
1530     * @return MarkerFilter[]
1531     */

1532    MarkerFilter[] getEnabledFilters() {
1533
1534        if (enabledFilters == null) {
1535            Collection JavaDoc filters = findEnabledFilters();
1536
1537            enabledFilters = new MarkerFilter[filters.size()];
1538            filters.toArray(enabledFilters);
1539        }
1540        return enabledFilters;
1541
1542    }
1543
1544    /**
1545     * Find the filters enabled in the view.
1546     *
1547     * @return Collection of MarkerFilter
1548     */

1549    protected Collection JavaDoc findEnabledFilters() {
1550        MarkerFilter[] allFilters = getAllFilters();
1551        ArrayList JavaDoc filters = new ArrayList JavaDoc(0);
1552        for (int i = 0; i < allFilters.length; i++) {
1553            if (allFilters[i].isEnabled()) {
1554                filters.add(allFilters[i]);
1555            }
1556        }
1557        return filters;
1558    }
1559
1560    /**
1561     * Get all of the filters applied to the receiver.
1562     *
1563     * @return MarkerFilter[]
1564     */

1565    MarkerFilter[] getAllFilters() {
1566        return getUserFilters();
1567    }
1568
1569    /*
1570     * (non-Javadoc)
1571     *
1572     * @see org.eclipse.ui.views.markers.internal.TableView#addDropDownContributions(org.eclipse.jface.action.IMenuManager)
1573     */

1574    void addDropDownContributions(IMenuManager menu) {
1575        super.addDropDownContributions(menu);
1576
1577        menu.add(new Separator(MENU_FILTERS_GROUP));
1578        // Don't add in the filters until they are set
1579
filtersMenu = new MenuManager(MarkerMessages.filtersSubMenu_title);
1580        refreshFilterMenu();
1581        menu.appendToGroup(MENU_FILTERS_GROUP, filtersMenu);
1582    }
1583
1584    /**
1585     * Create the show in menu if there is a single selection.
1586     *
1587     * @param menu
1588     */

1589    void createShowInMenu(IMenuManager menu) {
1590        ISelection selection = getViewer().getSelection();
1591        if (!(selection instanceof IStructuredSelection)) {
1592            return;
1593        }
1594
1595        IStructuredSelection structured = (IStructuredSelection) selection;
1596        if (!Util.isSingleConcreteSelection(structured)) {
1597            return;
1598        }
1599
1600        menu.add(new Separator(MENU_SHOW_IN_GROUP));
1601        // Don't add in the filters until they are set
1602

1603        String JavaDoc showInLabel = IDEWorkbenchMessages.Workbench_showIn;
1604        IBindingService bindingService = (IBindingService) PlatformUI
1605                .getWorkbench().getAdapter(IBindingService.class);
1606        if (bindingService != null) {
1607            String JavaDoc keyBinding = bindingService
1608                    .getBestActiveBindingFormattedFor("org.eclipse.ui.navigate.showInQuickMenu"); //$NON-NLS-1$
1609
if (keyBinding != null) {
1610                showInLabel += '\t' + keyBinding;
1611            }
1612        }
1613        showInMenu = new MenuManager(showInLabel);
1614        showInMenu.add(ContributionItemFactory.VIEWS_SHOW_IN
1615                .create(getViewSite().getWorkbenchWindow()));
1616
1617        menu.appendToGroup(MENU_SHOW_IN_GROUP, showInMenu);
1618
1619    }
1620
1621    /**
1622     * Refresh the marker counts
1623     *
1624     * @param monitor
1625     */

1626    void refreshMarkerCounts(IProgressMonitor monitor) {
1627        monitor.subTask(MarkerMessages.MarkerView_refreshing_counts);
1628        try {
1629            totalMarkers = MarkerList.compute(getMarkerTypes()).length;
1630        } catch (CoreException e) {
1631            Util.log(e);
1632            return;
1633        }
1634
1635    }
1636
1637    /**
1638     * Returns the marker limit or -1 if unlimited
1639     *
1640     * @return int
1641     */

1642    int getMarkerLimit() {
1643
1644        // If limits are enabled return it. Otherwise return -1
1645
if (IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(
1646                getMarkerEnablementPreferenceName())) {
1647            return IDEWorkbenchPlugin.getDefault().getPreferenceStore().getInt(
1648                    getMarkerLimitPreferenceName());
1649
1650        }
1651        return -1;
1652
1653    }
1654
1655    /**
1656     * Get the name of the marker limit preference.
1657     *
1658     * @return String
1659     */

1660    abstract String JavaDoc getMarkerEnablementPreferenceName();
1661
1662    /*
1663     * (non-Javadoc)
1664     *
1665     * @see org.eclipse.ui.views.markers.internal.TableView#createViewerInput()
1666     */

1667    Object JavaDoc createViewerInput() {
1668        adapter = new MarkerAdapter(this);
1669        return adapter;
1670    }
1671
1672    /**
1673     * Add a listener for the end of the update.
1674     *
1675     * @param listener
1676     */

1677    public void addUpdateFinishListener(IJobChangeListener listener) {
1678        updateJob.addJobChangeListener(listener);
1679
1680    }
1681
1682    /**
1683     * Remove a listener for the end of the update.
1684     *
1685     * @param listener
1686     */

1687    public void removeUpdateFinishListener(IJobChangeListener listener) {
1688        updateJob.removeJobChangeListener(listener);
1689
1690    }
1691
1692    /**
1693     * Create a listener for working set changes.
1694     *
1695     * @return IPropertyChangeListener
1696     */

1697    private IPropertyChangeListener getWorkingSetListener() {
1698        workingSetListener = new IPropertyChangeListener() {
1699            /*
1700             * (non-Javadoc)
1701             *
1702             * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
1703             */

1704            public void propertyChange(PropertyChangeEvent event) {
1705                clearEnabledFilters();
1706                refreshViewer();
1707
1708            }
1709        };
1710        return workingSetListener;
1711    }
1712
1713    /**
1714     * Schedule an update of the markers with a delay of time
1715     *
1716     * @param time
1717     */

1718    void scheduleMarkerUpdate(int time) {
1719        cancelJobs();
1720        getProgressService().schedule(markerProcessJob, time);
1721    }
1722
1723    /**
1724     * Cancel the pending jobs in the receiver.
1725     */

1726    private void cancelJobs() {
1727        markerProcessJob.cancel();
1728        updateJob.cancel();
1729    }
1730
1731    /*
1732     * (non-Javadoc)
1733     *
1734     * @see org.eclipse.ui.views.markers.internal.TableView#createTree(org.eclipse.swt.widgets.Composite)
1735     */

1736    protected Tree createTree(Composite parent) {
1737        Tree tree = super.createTree(parent);
1738        tree.addTreeListener(new TreeAdapter() {
1739            /*
1740             * (non-Javadoc)
1741             *
1742             * @see org.eclipse.swt.events.TreeAdapter#treeCollapsed(org.eclipse.swt.events.TreeEvent)
1743             */

1744            public void treeCollapsed(TreeEvent e) {
1745                updateJob.removeExpandedCategory((MarkerCategory) e.item
1746                        .getData());
1747            }
1748
1749            /*
1750             * (non-Javadoc)
1751             *
1752             * @see org.eclipse.swt.events.TreeAdapter#treeExpanded(org.eclipse.swt.events.TreeEvent)
1753             */

1754            public void treeExpanded(TreeEvent e) {
1755                updateJob
1756                        .addExpandedCategory((MarkerCategory) e.item.getData());
1757            }
1758        });
1759
1760        return tree;
1761    }
1762
1763    /**
1764     * The focus elements have changed. Update accordingly.
1765     */

1766    private void refreshForFocusUpdate() {
1767        if (focusElements != null) {
1768            updateFilterSelection(focusElements);
1769            refreshViewer();
1770        }
1771    }
1772
1773    /**
1774     * Save the current selection in the update for reselection after update.
1775     */

1776    protected void preserveSelection() {
1777        updateJob.saveSelection(getViewer().getSelection());
1778
1779    }
1780
1781    /**
1782     * Return the string name of the specific type of marker shown in this view.
1783     */

1784    protected abstract String JavaDoc getMarkerName();
1785
1786    /**
1787     * Return the undo context associated with operations performed in this
1788     * view. By default, return the workspace undo context. Subclasses should
1789     * override if a more specific undo context should be used.
1790     */

1791    protected IUndoContext getUndoContext() {
1792        return (IUndoContext) ResourcesPlugin.getWorkspace().getAdapter(
1793                IUndoContext.class);
1794    }
1795
1796}
1797
Popular Tags