KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > actions > CategoryFilterActionGroup


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 package org.eclipse.jdt.internal.ui.actions;
12
13 import com.ibm.icu.text.Collator;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.Collections JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.LinkedHashMap JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.eclipse.core.runtime.Assert;
24
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.custom.BusyIndicator;
27 import org.eclipse.swt.graphics.Image;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Control;
32 import org.eclipse.swt.widgets.Shell;
33
34 import org.eclipse.jface.action.Action;
35 import org.eclipse.jface.action.IContributionItem;
36 import org.eclipse.jface.action.IMenuListener;
37 import org.eclipse.jface.action.IMenuManager;
38 import org.eclipse.jface.action.Separator;
39 import org.eclipse.jface.dialogs.Dialog;
40 import org.eclipse.jface.preference.IPreferenceStore;
41 import org.eclipse.jface.viewers.ILabelProvider;
42 import org.eclipse.jface.viewers.ILabelProviderListener;
43 import org.eclipse.jface.viewers.StructuredViewer;
44 import org.eclipse.jface.viewers.Viewer;
45 import org.eclipse.jface.viewers.ViewerComparator;
46 import org.eclipse.jface.viewers.ViewerFilter;
47 import org.eclipse.jface.window.Window;
48
49 import org.eclipse.ui.actions.ActionGroup;
50 import org.eclipse.ui.dialogs.SelectionStatusDialog;
51
52 import org.eclipse.jdt.core.IClassFile;
53 import org.eclipse.jdt.core.ICompilationUnit;
54 import org.eclipse.jdt.core.IJavaElement;
55 import org.eclipse.jdt.core.IJavaModel;
56 import org.eclipse.jdt.core.IJavaProject;
57 import org.eclipse.jdt.core.IMember;
58 import org.eclipse.jdt.core.IPackageFragment;
59 import org.eclipse.jdt.core.IPackageFragmentRoot;
60 import org.eclipse.jdt.core.JavaModelException;
61
62 import org.eclipse.jdt.internal.ui.JavaPlugin;
63 import org.eclipse.jdt.internal.ui.JavaPluginImages;
64 import org.eclipse.jdt.internal.ui.wizards.dialogfields.CheckedListDialogField;
65 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
66 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter;
67 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
68 import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
69
70 public class CategoryFilterActionGroup extends ActionGroup {
71
72     private class CategoryFilter extends ViewerFilter {
73
74         /**
75          * {@inheritDoc}
76          */

77         public boolean select(Viewer viewer, Object JavaDoc parentElement, Object JavaDoc element) {
78             if (element instanceof IMember) {
79                 IMember member= (IMember)element;
80                 try {
81                     String JavaDoc[] categories= member.getCategories();
82                     if (categories.length == 0)
83                         return !fFilterUncategorizedMembers;
84                     
85                     for (int i= 0; i < categories.length; i++) {
86                         if (!fFilteredCategories.contains(categories[i]))
87                             return true;
88                     }
89                     return false;
90                 } catch (JavaModelException e) {
91                     JavaPlugin.log(e);
92                 }
93             }
94             return true;
95         }
96         
97     }
98     
99     private class CategoryFilterSelectionDialog extends SelectionStatusDialog implements IListAdapter {
100         
101         private static final int SELECT_ALL= 0;
102         private static final int DESELECT_ALL= 1;
103
104         private final CheckedListDialogField fCategoryList;
105
106         public CategoryFilterSelectionDialog(Shell parent, List JavaDoc categories, List JavaDoc selectedCategories) {
107             super(parent);
108             
109             setTitle(ActionMessages.CategoryFilterActionGroup_JavaCategoryFilter_title);
110             
111             String JavaDoc[] buttons= {
112                     ActionMessages.CategoryFilterActionGroup_SelectAllCategories,
113                     ActionMessages.CategoryFilterActionGroup_DeselectAllCategories
114                     };
115             
116             fCategoryList= new CheckedListDialogField(this, buttons, new ILabelProvider() {
117                             public Image getImage(Object JavaDoc element) {return null;}
118                             public String JavaDoc getText(Object JavaDoc element) {return (String JavaDoc)element;}
119                             public void addListener(ILabelProviderListener listener) {}
120                             public void dispose() {}
121                             public boolean isLabelProperty(Object JavaDoc element, String JavaDoc property) {return false;}
122                             public void removeListener(ILabelProviderListener listener) {}
123                         });
124             fCategoryList.addElements(categories);
125             fCategoryList.setViewerComparator(new ViewerComparator());
126             fCategoryList.setLabelText(ActionMessages.CategoryFilterActionGroup_SelectCategoriesDescription);
127             fCategoryList.checkAll(true);
128             for (Iterator JavaDoc iter= selectedCategories.iterator(); iter.hasNext();) {
129                 String JavaDoc selected= (String JavaDoc)iter.next();
130                 fCategoryList.setChecked(selected, false);
131             }
132             if (categories.size() == 0) {
133                 fCategoryList.setEnabled(false);
134             }
135         }
136         
137         /**
138          * {@inheritDoc}
139          */

140         protected Control createDialogArea(Composite parent) {
141             Composite composite= new Composite(parent, SWT.NONE);
142             composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
143             composite.setLayout(new GridLayout(1, true));
144             composite.setFont(parent.getFont());
145             
146             Composite list= new Composite(composite, SWT.NONE);
147             list.setFont(composite.getFont());
148             LayoutUtil.doDefaultLayout(list, new DialogField[] { fCategoryList }, true);
149             LayoutUtil.setHorizontalGrabbing(fCategoryList.getListControl(null));
150             Dialog.applyDialogFont(composite);
151             
152             setHelpAvailable(false);
153             
154             return composite;
155         }
156
157         /**
158          * {@inheritDoc}
159          */

160         protected void computeResult() {
161             setResult(fCategoryList.getCheckedElements());
162         }
163
164         /**
165          * {@inheritDoc}
166          */

167         public void customButtonPressed(ListDialogField field, int index) {
168             if (index == SELECT_ALL) {
169                 fCategoryList.checkAll(true);
170                 fCategoryList.refresh();
171             } else if (index == DESELECT_ALL) {
172                 fCategoryList.checkAll(false);
173                 fCategoryList.refresh();
174             }
175         }
176
177         public void doubleClicked(ListDialogField field) {
178             List JavaDoc selectedElements= field.getSelectedElements();
179             if (selectedElements.size() == 1) {
180                 Object JavaDoc selected= selectedElements.get(0);
181                 fCategoryList.setChecked(selected, !fCategoryList.isChecked(selected));
182             }
183         }
184         public void selectionChanged(ListDialogField field) {}
185     }
186     
187     private class CategoryFilterMenuAction extends Action {
188         
189         public CategoryFilterMenuAction() {
190             setDescription(ActionMessages.CategoryFilterActionGroup_ShowCategoriesActionDescription);
191             setToolTipText(ActionMessages.CategoryFilterActionGroup_ShowCategoriesToolTip);
192             setText(ActionMessages.CategoryFilterActionGroup_ShowCategoriesLabel);
193             JavaPluginImages.setLocalImageDescriptors(this, "category_menu.gif"); //$NON-NLS-1$
194
}
195         
196         /**
197          * {@inheritDoc}
198          */

199         public void run() {
200             showCategorySelectionDialog(fInputElement);
201         }
202
203     }
204         
205     private class CategoryFilterAction extends Action {
206         
207         private final String JavaDoc fCategory;
208
209         public CategoryFilterAction(String JavaDoc category, int count) {
210             fCategory= category;
211             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
212             buf.append('&').append(count).append(' ').append(fCategory);
213             setText(buf.toString());
214             setChecked(!fFilteredCategories.contains(fCategory));
215             setId(FILTER_CATEGORY_ACTION_ID);
216         }
217
218         /**
219          * {@inheritDoc}
220          */

221         public void run() {
222             super.run();
223             if (fFilteredCategories.contains(fCategory)) {
224                 fFilteredCategories.remove(fCategory);
225             } else {
226                 fFilteredCategories.add(fCategory);
227             }
228             fLRUList.put(fCategory, fCategory);
229             storeSettings();
230             fireSelectionChange();
231         }
232
233     }
234     
235     private class FilterUncategorizedMembersAction extends Action {
236
237         public FilterUncategorizedMembersAction() {
238             setText(ActionMessages.CategoryFilterActionGroup_ShowUncategorizedMembers);
239             setChecked(!fFilterUncategorizedMembers);
240             setId(FILTER_CATEGORY_ACTION_ID);
241         }
242         
243         /**
244          * {@inheritDoc}
245          */

246         public void run() {
247             fFilterUncategorizedMembers= !fFilterUncategorizedMembers;
248             storeSettings();
249             fireSelectionChange();
250         }
251     }
252     
253     private interface IResultCollector {
254         public boolean accept(String JavaDoc[] category);
255     }
256     
257     private static int COUNTER= 0;//WORKAROUND for Bug 132669 https://bugs.eclipse.org/bugs/show_bug.cgi?id=132669
258

259     private static final String JavaDoc FILTER_CATEGORY_ACTION_ID= "FilterCategoryActionId"; //$NON-NLS-1$
260
private final String JavaDoc CATEGORY_MENU_GROUP_NAME= "CategoryMenuGroup" + (COUNTER++); //$NON-NLS-1$
261
private static final int MAX_NUMBER_OF_CATEGORIES_IN_MENU= 5;
262
263     private final StructuredViewer fViewer;
264     private final String JavaDoc fViewerId;
265     private final CategoryFilter fFilter;
266     private final HashSet JavaDoc fFilteredCategories;
267     private IJavaElement[] fInputElement;
268     private final CategoryFilterMenuAction fMenuAction;
269     private IMenuManager fMenuManager;
270     private IMenuListener fMenuListener;
271     private final LinkedHashMap JavaDoc fLRUList;
272     private boolean fFilterUncategorizedMembers;
273
274     public CategoryFilterActionGroup(final StructuredViewer viewer, final String JavaDoc viewerId, IJavaElement[] input) {
275         Assert.isLegal(viewer != null);
276         Assert.isLegal(viewerId != null);
277         Assert.isLegal(input != null);
278         
279         fLRUList= new LinkedHashMap JavaDoc(MAX_NUMBER_OF_CATEGORIES_IN_MENU * 2, 0.75f, true) {
280             private static final long serialVersionUID= 1L;
281             protected boolean removeEldestEntry(Map.Entry JavaDoc eldest) {
282                 return size() > MAX_NUMBER_OF_CATEGORIES_IN_MENU;
283             }
284         };
285         fViewer= viewer;
286         fViewerId= viewerId;
287         fInputElement= input;
288         
289         fFilter= new CategoryFilter();
290         
291         fFilteredCategories= new HashSet JavaDoc();
292         loadSettings();
293
294         fMenuAction= new CategoryFilterMenuAction();
295         
296         fViewer.addFilter(fFilter);
297     }
298     
299     public void setInput(IJavaElement[] input) {
300         Assert.isLegal(input != null);
301         fInputElement= input;
302     }
303     
304     private void loadSettings() {
305         fFilteredCategories.clear();
306         IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
307         String JavaDoc string= store.getString(getPreferenceKey());
308         if (string != null && string.length() > 0) {
309             String JavaDoc[] categories= string.split(";"); //$NON-NLS-1$
310
for (int i= 0; i < categories.length; i++) {
311                 fFilteredCategories.add(categories[i]);
312             }
313         }
314         string= store.getString(getPreferenceKey()+".LRU"); //$NON-NLS-1$
315
if (string != null && string.length() > 0) {
316             String JavaDoc[] categories= string.split(";"); //$NON-NLS-1$
317
for (int i= categories.length - 1; i >= 0; i--) {
318                 fLRUList.put(categories[i], categories[i]);
319             }
320         }
321         fFilterUncategorizedMembers= store.getBoolean(getPreferenceKey()+".FilterUncategorized"); //$NON-NLS-1$
322
}
323
324     private void storeSettings() {
325         IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
326         if (fFilteredCategories.size() == 0) {
327             store.setValue(getPreferenceKey(), ""); //$NON-NLS-1$
328
} else {
329             StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
330             Iterator JavaDoc iter= fFilteredCategories.iterator();
331             String JavaDoc element= (String JavaDoc)iter.next();
332             buf.append(element);
333             while (iter.hasNext()) {
334                 element= (String JavaDoc)iter.next();
335                 buf.append(';');
336                 buf.append(element);
337             }
338             store.setValue(getPreferenceKey(), buf.toString());
339             buf= new StringBuffer JavaDoc();
340             iter= fLRUList.values().iterator();
341             element= (String JavaDoc)iter.next();
342             buf.append(element);
343             while (iter.hasNext()) {
344                 element= (String JavaDoc)iter.next();
345                 buf.append(';');
346                 buf.append(element);
347             }
348             store.setValue(getPreferenceKey()+".LRU", buf.toString()); //$NON-NLS-1$
349
store.setValue(getPreferenceKey()+".FilterUncategorized", fFilterUncategorizedMembers); //$NON-NLS-1$
350
}
351     }
352     
353     public void contributeToViewMenu(IMenuManager menuManager) {
354         menuManager.add(new Separator(CATEGORY_MENU_GROUP_NAME));
355         menuManager.appendToGroup(CATEGORY_MENU_GROUP_NAME, fMenuAction);
356         fMenuListener= new IMenuListener() {
357                     public void menuAboutToShow(IMenuManager manager) {
358                         if (!manager.isVisible())
359                             return;
360                         updateMenu(manager);
361                     }
362                 };
363         menuManager.addMenuListener(fMenuListener);
364         fMenuManager= menuManager;
365     }
366     
367     /**
368      * {@inheritDoc}
369      */

370     public void dispose() {
371         super.dispose();
372         if (fMenuManager != null) {
373             fMenuManager.removeMenuListener(fMenuListener);
374             fMenuManager= null;
375             fMenuListener= null;
376         }
377     }
378
379     private void updateMenu(IMenuManager manager) {
380         IContributionItem[] items= manager.getItems();
381         if (items != null) {
382             for (int i= 0; i < items.length; i++) {
383                 IContributionItem item= items[i];
384                 if (item != null && item.getId() != null && item.getId().equals(FILTER_CATEGORY_ACTION_ID)) {
385                     IContributionItem removed= manager.remove(item);
386                     if (removed != null) {
387                         item.dispose();
388                     }
389                 }
390             }
391         }
392         List JavaDoc menuEntries= new ArrayList JavaDoc();
393         boolean hasUncategorizedMembers= getMenuCategories(menuEntries);
394         Collections.sort(menuEntries, Collator.getInstance());
395         
396         if (menuEntries.size() > 0 && hasUncategorizedMembers)
397             manager.appendToGroup(CATEGORY_MENU_GROUP_NAME, new FilterUncategorizedMembersAction());
398         
399         int count= 0;
400         for (Iterator JavaDoc iter= menuEntries.iterator(); iter.hasNext();) {
401             String JavaDoc category= (String JavaDoc)iter.next();
402             manager.appendToGroup(CATEGORY_MENU_GROUP_NAME, new CategoryFilterAction(category, count + 1));
403             count++;
404         }
405     }
406
407     private boolean getMenuCategories(List JavaDoc result) {
408         final HashSet JavaDoc/*<String>*/ categories= new HashSet JavaDoc();
409         final HashSet JavaDoc/*<String>*/ foundLRUCategories= new HashSet JavaDoc();
410         final boolean hasUncategorizedMember[]= new boolean[] {false};
411         for (int i= 0; i < fInputElement.length && !(hasUncategorizedMember[0] && foundLRUCategories.size() >= MAX_NUMBER_OF_CATEGORIES_IN_MENU); i++) {
412             collectCategories(fInputElement[i], new IResultCollector() {
413                 public boolean accept(String JavaDoc[] cats) {
414                     if (cats.length > 0) {
415                         for (int j= 0; j < cats.length; j++) {
416                             String JavaDoc category= cats[j];
417                             categories.add(category);
418                             if (fLRUList.containsKey(category)) {
419                                 foundLRUCategories.add(category);
420                             }
421                         }
422                     } else {
423                         hasUncategorizedMember[0]= true;
424                     }
425                     return hasUncategorizedMember[0] && foundLRUCategories.size() >= MAX_NUMBER_OF_CATEGORIES_IN_MENU;
426                 }
427             });
428         }
429         int count= 0;
430         for (Iterator JavaDoc iter= foundLRUCategories.iterator(); iter.hasNext();) {
431             String JavaDoc element= (String JavaDoc)iter.next();
432             result.add(element);
433             count++;
434         }
435         if (count < MAX_NUMBER_OF_CATEGORIES_IN_MENU) {
436             List JavaDoc sortedCategories= new ArrayList JavaDoc(categories);
437             Collections.sort(sortedCategories, Collator.getInstance());
438             for (Iterator JavaDoc iter= sortedCategories.iterator(); iter.hasNext() && count < MAX_NUMBER_OF_CATEGORIES_IN_MENU;) {
439                 String JavaDoc element= (String JavaDoc)iter.next();
440                 if (!foundLRUCategories.contains(element)) {
441                     result.add(element);
442                     count++;
443                 }
444             }
445         }
446         return hasUncategorizedMember[0];
447     }
448
449     private boolean collectCategories(IJavaElement element, IResultCollector collector) {//HashSet result, int max, LinkedHashMap lruList) {
450
try {
451             if (element instanceof IMember) {
452                 IMember member= (IMember)element;
453                 collector.accept(member.getCategories());
454                 return processChildren(member.getChildren(), collector);
455             } else if (element instanceof ICompilationUnit) {
456                 return processChildren(((ICompilationUnit)element).getChildren(), collector);
457             } else if (element instanceof IClassFile) {
458                 return processChildren(((IClassFile)element).getChildren(), collector);
459             } else if (element instanceof IJavaModel) {
460                 return processChildren(((IJavaModel)element).getChildren(), collector);
461             } else if (element instanceof IJavaProject) {
462                 return processChildren(((IJavaProject)element).getChildren(), collector);
463             } else if (element instanceof IPackageFragment) {
464                 return processChildren(((IPackageFragment)element).getChildren(), collector);
465             } else if (element instanceof IPackageFragmentRoot) {
466                 return processChildren(((IPackageFragmentRoot)element).getChildren(), collector);
467             }
468             return false;
469         } catch (JavaModelException e) {
470             JavaPlugin.log(e);
471             return true;
472         }
473     }
474
475     private boolean processChildren(IJavaElement[] children, IResultCollector collector) {
476         for (int i= 0; i < children.length; i++) {
477             if (collectCategories(children[i], collector))
478                 return true;
479         }
480         return false;
481     }
482
483     private void fireSelectionChange() {
484         fViewer.getControl().setRedraw(false);
485         BusyIndicator.showWhile(fViewer.getControl().getDisplay(), new Runnable JavaDoc() {
486             public void run() {
487                 fViewer.refresh();
488             }
489         });
490         fViewer.getControl().setRedraw(true);
491     }
492     
493     private String JavaDoc getPreferenceKey() {
494         return "CategoryFilterActionGroup." + fViewerId; //$NON-NLS-1$
495
}
496     
497     private void showCategorySelectionDialog(IJavaElement[] input) {
498         final HashSet JavaDoc/*<String>*/ categories= new HashSet JavaDoc();
499         for (int i= 0; i < input.length; i++) {
500             collectCategories(input[i], new IResultCollector() {
501                 public boolean accept(String JavaDoc[] cats) {
502                     for (int j= 0; j < cats.length; j++) {
503                         categories.add(cats[j]);
504                     }
505                     return false;
506                 }
507             });
508         }
509         CategoryFilterSelectionDialog dialog= new CategoryFilterSelectionDialog(fViewer.getControl().getShell(), new ArrayList JavaDoc(categories), new ArrayList JavaDoc(fFilteredCategories));
510         if (dialog.open() == Window.OK) {
511             Object JavaDoc[] selected= dialog.getResult();
512             for (Iterator JavaDoc iter= categories.iterator(); iter.hasNext();) {
513                 String JavaDoc category= (String JavaDoc)iter.next();
514                 if (contains(selected, category)) {
515                     if (fFilteredCategories.remove(category))
516                         fLRUList.put(category, category);
517                 } else {
518                     if (fFilteredCategories.add(category))
519                         fLRUList.put(category, category);
520                 }
521             }
522             storeSettings();
523             fireSelectionChange();
524         }
525     }
526     
527     private boolean contains(Object JavaDoc[] selected, String JavaDoc category) {
528         for (int i= 0; i < selected.length; i++) {
529             if (selected[i].equals(category))
530                 return true;
531         }
532         return false;
533     }
534
535 }
536
Popular Tags