1 11 package org.eclipse.jdt.internal.ui.actions; 12 13 import com.ibm.icu.text.Collator; 14 15 import java.util.ArrayList ; 16 import java.util.Collections ; 17 import java.util.HashSet ; 18 import java.util.Iterator ; 19 import java.util.LinkedHashMap ; 20 import java.util.List ; 21 import java.util.Map ; 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 77 public boolean select(Viewer viewer, Object parentElement, Object element) { 78 if (element instanceof IMember) { 79 IMember member= (IMember)element; 80 try { 81 String [] 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 categories, List selectedCategories) { 107 super(parent); 108 109 setTitle(ActionMessages.CategoryFilterActionGroup_JavaCategoryFilter_title); 110 111 String [] buttons= { 112 ActionMessages.CategoryFilterActionGroup_SelectAllCategories, 113 ActionMessages.CategoryFilterActionGroup_DeselectAllCategories 114 }; 115 116 fCategoryList= new CheckedListDialogField(this, buttons, new ILabelProvider() { 117 public Image getImage(Object element) {return null;} 118 public String getText(Object element) {return (String )element;} 119 public void addListener(ILabelProviderListener listener) {} 120 public void dispose() {} 121 public boolean isLabelProperty(Object element, String 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 iter= selectedCategories.iterator(); iter.hasNext();) { 129 String selected= (String )iter.next(); 130 fCategoryList.setChecked(selected, false); 131 } 132 if (categories.size() == 0) { 133 fCategoryList.setEnabled(false); 134 } 135 } 136 137 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 160 protected void computeResult() { 161 setResult(fCategoryList.getCheckedElements()); 162 } 163 164 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 selectedElements= field.getSelectedElements(); 179 if (selectedElements.size() == 1) { 180 Object 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"); } 195 196 199 public void run() { 200 showCategorySelectionDialog(fInputElement); 201 } 202 203 } 204 205 private class CategoryFilterAction extends Action { 206 207 private final String fCategory; 208 209 public CategoryFilterAction(String category, int count) { 210 fCategory= category; 211 StringBuffer buf = new StringBuffer (); 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 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 246 public void run() { 247 fFilterUncategorizedMembers= !fFilterUncategorizedMembers; 248 storeSettings(); 249 fireSelectionChange(); 250 } 251 } 252 253 private interface IResultCollector { 254 public boolean accept(String [] category); 255 } 256 257 private static int COUNTER= 0; 259 private static final String FILTER_CATEGORY_ACTION_ID= "FilterCategoryActionId"; private final String CATEGORY_MENU_GROUP_NAME= "CategoryMenuGroup" + (COUNTER++); private static final int MAX_NUMBER_OF_CATEGORIES_IN_MENU= 5; 262 263 private final StructuredViewer fViewer; 264 private final String fViewerId; 265 private final CategoryFilter fFilter; 266 private final HashSet fFilteredCategories; 267 private IJavaElement[] fInputElement; 268 private final CategoryFilterMenuAction fMenuAction; 269 private IMenuManager fMenuManager; 270 private IMenuListener fMenuListener; 271 private final LinkedHashMap fLRUList; 272 private boolean fFilterUncategorizedMembers; 273 274 public CategoryFilterActionGroup(final StructuredViewer viewer, final String viewerId, IJavaElement[] input) { 275 Assert.isLegal(viewer != null); 276 Assert.isLegal(viewerId != null); 277 Assert.isLegal(input != null); 278 279 fLRUList= new LinkedHashMap (MAX_NUMBER_OF_CATEGORIES_IN_MENU * 2, 0.75f, true) { 280 private static final long serialVersionUID= 1L; 281 protected boolean removeEldestEntry(Map.Entry 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 (); 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 string= store.getString(getPreferenceKey()); 308 if (string != null && string.length() > 0) { 309 String [] categories= string.split(";"); for (int i= 0; i < categories.length; i++) { 311 fFilteredCategories.add(categories[i]); 312 } 313 } 314 string= store.getString(getPreferenceKey()+".LRU"); if (string != null && string.length() > 0) { 316 String [] categories= string.split(";"); for (int i= categories.length - 1; i >= 0; i--) { 318 fLRUList.put(categories[i], categories[i]); 319 } 320 } 321 fFilterUncategorizedMembers= store.getBoolean(getPreferenceKey()+".FilterUncategorized"); } 323 324 private void storeSettings() { 325 IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); 326 if (fFilteredCategories.size() == 0) { 327 store.setValue(getPreferenceKey(), ""); } else { 329 StringBuffer buf= new StringBuffer (); 330 Iterator iter= fFilteredCategories.iterator(); 331 String element= (String )iter.next(); 332 buf.append(element); 333 while (iter.hasNext()) { 334 element= (String )iter.next(); 335 buf.append(';'); 336 buf.append(element); 337 } 338 store.setValue(getPreferenceKey(), buf.toString()); 339 buf= new StringBuffer (); 340 iter= fLRUList.values().iterator(); 341 element= (String )iter.next(); 342 buf.append(element); 343 while (iter.hasNext()) { 344 element= (String )iter.next(); 345 buf.append(';'); 346 buf.append(element); 347 } 348 store.setValue(getPreferenceKey()+".LRU", buf.toString()); store.setValue(getPreferenceKey()+".FilterUncategorized", fFilterUncategorizedMembers); } 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 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 menuEntries= new ArrayList (); 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 iter= menuEntries.iterator(); iter.hasNext();) { 401 String category= (String )iter.next(); 402 manager.appendToGroup(CATEGORY_MENU_GROUP_NAME, new CategoryFilterAction(category, count + 1)); 403 count++; 404 } 405 } 406 407 private boolean getMenuCategories(List result) { 408 final HashSet categories= new HashSet (); 409 final HashSet foundLRUCategories= new HashSet (); 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 [] cats) { 414 if (cats.length > 0) { 415 for (int j= 0; j < cats.length; j++) { 416 String 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 iter= foundLRUCategories.iterator(); iter.hasNext();) { 431 String element= (String )iter.next(); 432 result.add(element); 433 count++; 434 } 435 if (count < MAX_NUMBER_OF_CATEGORIES_IN_MENU) { 436 List sortedCategories= new ArrayList (categories); 437 Collections.sort(sortedCategories, Collator.getInstance()); 438 for (Iterator iter= sortedCategories.iterator(); iter.hasNext() && count < MAX_NUMBER_OF_CATEGORIES_IN_MENU;) { 439 String element= (String )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) { 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 () { 486 public void run() { 487 fViewer.refresh(); 488 } 489 }); 490 fViewer.getControl().setRedraw(true); 491 } 492 493 private String getPreferenceKey() { 494 return "CategoryFilterActionGroup." + fViewerId; } 496 497 private void showCategorySelectionDialog(IJavaElement[] input) { 498 final HashSet categories= new HashSet (); 499 for (int i= 0; i < input.length; i++) { 500 collectCategories(input[i], new IResultCollector() { 501 public boolean accept(String [] 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 (categories), new ArrayList (fFilteredCategories)); 510 if (dialog.open() == Window.OK) { 511 Object [] selected= dialog.getResult(); 512 for (Iterator iter= categories.iterator(); iter.hasNext();) { 513 String category= (String )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 [] selected, String 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 |