1 11 package org.eclipse.jdt.ui.actions; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.Map ; 19 import java.util.SortedSet ; 20 import java.util.Stack ; 21 import java.util.StringTokenizer ; 22 import java.util.TreeSet ; 23 24 import org.eclipse.core.runtime.Assert; 25 26 import org.eclipse.swt.SWT; 27 import org.eclipse.swt.events.SelectionAdapter; 28 import org.eclipse.swt.events.SelectionEvent; 29 import org.eclipse.swt.widgets.Menu; 30 import org.eclipse.swt.widgets.MenuItem; 31 32 import org.eclipse.jface.action.Action; 33 import org.eclipse.jface.action.ContributionItem; 34 import org.eclipse.jface.action.GroupMarker; 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.IToolBarManager; 39 import org.eclipse.jface.action.Separator; 40 import org.eclipse.jface.preference.IPreferenceStore; 41 import org.eclipse.jface.viewers.IContentProvider; 42 import org.eclipse.jface.viewers.ITreeContentProvider; 43 import org.eclipse.jface.viewers.StructuredViewer; 44 import org.eclipse.jface.viewers.ViewerFilter; 45 import org.eclipse.jface.window.Window; 46 47 import org.eclipse.ui.IActionBars; 48 import org.eclipse.ui.IMemento; 49 import org.eclipse.ui.IViewPart; 50 import org.eclipse.ui.actions.ActionGroup; 51 52 import org.eclipse.jdt.core.IJavaModel; 53 54 import org.eclipse.jdt.internal.ui.JavaPlugin; 55 import org.eclipse.jdt.internal.ui.JavaPluginImages; 56 import org.eclipse.jdt.internal.ui.filters.CustomFiltersDialog; 57 import org.eclipse.jdt.internal.ui.filters.FilterDescriptor; 58 import org.eclipse.jdt.internal.ui.filters.FilterMessages; 59 import org.eclipse.jdt.internal.ui.filters.NamePatternFilter; 60 61 70 public class CustomFiltersActionGroup extends ActionGroup { 71 72 private static final String TAG_DUMMY_TO_TEST_EXISTENCE= "TAG_DUMMY_TO_TEST_EXISTENCE"; 74 class ShowFilterDialogAction extends Action { 75 ShowFilterDialogAction() { 76 setText(FilterMessages.OpenCustomFiltersDialogAction_text); 77 setImageDescriptor(JavaPluginImages.DESC_ELCL_FILTER); 78 setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_FILTER); 79 } 80 81 public void run() { 82 openDialog(); 83 } 84 } 85 86 91 class FilterActionMenuContributionItem extends ContributionItem { 92 93 private int fItemNumber; 94 private boolean fState; 95 private String fFilterId; 96 private String fFilterName; 97 private CustomFiltersActionGroup fActionGroup; 98 99 108 public FilterActionMenuContributionItem(CustomFiltersActionGroup actionGroup, String filterId, String filterName, boolean state, int itemNumber) { 109 super(filterId); 110 Assert.isNotNull(actionGroup); 111 Assert.isNotNull(filterId); 112 Assert.isNotNull(filterName); 113 fActionGroup= actionGroup; 114 fFilterId= filterId; 115 fFilterName= filterName; 116 fState= state; 117 fItemNumber= itemNumber; 118 } 119 120 123 public void fill(Menu menu, int index) { 124 MenuItem mi= new MenuItem(menu, SWT.CHECK, index); 125 mi.setText("&" + fItemNumber + " " + fFilterName); 130 mi.setSelection(fState); 132 mi.addSelectionListener(new SelectionAdapter() { 133 public void widgetSelected(SelectionEvent e) { 134 fState= !fState; 135 fActionGroup.setFilter(fFilterId, fState); 136 } 137 }); 138 } 139 140 143 public boolean isDynamic() { 144 return true; 145 } 146 } 147 148 private static final String TAG_CUSTOM_FILTERS = "customFilters"; private static final String TAG_USER_DEFINED_PATTERNS_ENABLED= "userDefinedPatternsEnabled"; private static final String TAG_USER_DEFINED_PATTERNS= "userDefinedPatterns"; private static final String TAG_XML_DEFINED_FILTERS= "xmlDefinedFilters"; private static final String TAG_LRU_FILTERS = "lastRecentlyUsedFilters"; 154 private static final String TAG_CHILD= "child"; private static final String TAG_PATTERN= "pattern"; private static final String TAG_FILTER_ID= "filterId"; private static final String TAG_IS_ENABLED= "isEnabled"; 159 private static final String SEPARATOR= ","; 161 private static final int MAX_FILTER_MENU_ENTRIES= 3; 162 private static final String RECENT_FILTERS_GROUP_NAME= "recentFiltersGroup"; 164 private static class FilterItem { 165 boolean enabled; 166 boolean previouslyEnabled; 167 FilterDescriptor descriptor; 168 String id; 169 170 private ViewerFilter filterInstance= null; 171 172 public FilterItem(FilterDescriptor descriptor) { 173 this.descriptor= descriptor; 174 this.id= descriptor.getId(); 175 this.previouslyEnabled= false; 176 this.enabled= descriptor.isEnabled(); 177 } 178 179 public ViewerFilter getFilterInstance() { 180 if (filterInstance == null) { 181 filterInstance= descriptor.createViewerFilter(); 182 } 183 return filterInstance; 184 185 } 186 } 187 188 189 private final StructuredViewer fViewer; 190 private final NamePatternFilter fPatternFilter; 191 192 private boolean fUserDefinedPatternsEnabled; 193 private String [] fUserDefinedPatterns; 194 195 private String [] fPreviousPatterns; 196 197 private final Map fFilterItems; 198 199 204 private Stack fLRUFilterIdsStack; 205 211 private IMenuManager fMenuManager; 212 218 private IMenuListener fMenuListener; 219 224 private String [] fFilterIdsUsedInLastViewMenu; 225 226 private final String fTargetId; 227 228 234 public CustomFiltersActionGroup(IViewPart part, StructuredViewer viewer) { 235 this(part.getViewSite().getId(), viewer); 236 } 237 238 244 public CustomFiltersActionGroup(String ownerId, StructuredViewer viewer) { 245 Assert.isNotNull(ownerId); 246 Assert.isNotNull(viewer); 247 fTargetId= ownerId; 248 fViewer= viewer; 249 fPatternFilter= new NamePatternFilter(); 250 251 fLRUFilterIdsStack= new Stack (); 252 253 fUserDefinedPatterns= new String [0]; 254 fUserDefinedPatternsEnabled= false; 255 fPreviousPatterns= new String [0]; 256 257 fFilterItems= new HashMap (); 258 FilterDescriptor[] filterDescriptors= FilterDescriptor.getFilterDescriptors(fTargetId); 259 for (int i= 0; i < filterDescriptors.length; i++) { 260 FilterItem item= new FilterItem(filterDescriptors[i]); 261 Object existing= fFilterItems.put(item.id, item); 262 if (existing != null) { 263 JavaPlugin.logErrorMessage("WARNING: Duplicate id for extension-point \"org.eclipse.jdt.ui.javaElementFilters\" in " + ownerId); } 265 } 266 267 initializeWithViewDefaults(); 268 269 updateViewerFilters(); 270 } 271 272 275 public void fillActionBars(IActionBars actionBars) { 276 fillToolBar(actionBars.getToolBarManager()); 277 fillViewMenu(actionBars.getMenuManager()); 278 } 279 280 292 public String [] internalGetEnabledFilterIds() { 293 ArrayList enabledFilterIds= new ArrayList (); 294 for (Iterator iterator= fFilterItems.values().iterator(); iterator.hasNext();) { 295 FilterItem item= (FilterItem) iterator.next(); 296 if (item.enabled) { 297 enabledFilterIds.add(item.id); 298 } 299 } 300 return (String [])enabledFilterIds.toArray(new String [enabledFilterIds.size()]); 301 } 302 303 313 public String [] removeFiltersFor(Object parent, Object element, IContentProvider contentProvider) { 314 ArrayList newFilters= new ArrayList (); 315 for (Iterator iterator= fFilterItems.values().iterator(); iterator.hasNext();) { 316 FilterItem item= (FilterItem) iterator.next(); 317 if (item.enabled) { 318 ViewerFilter filter= item.getFilterInstance(); 319 if (filter != null && isSelected(parent, element, contentProvider, filter)) 320 newFilters.add(item.id); 321 } 322 } 323 return (String [])newFilters.toArray(new String [newFilters.size()]); 324 } 325 326 331 public void setFilters(String [] newFilters) { 332 setEnabledFilterIds(newFilters); 333 updateViewerFilters(); 334 } 335 336 private boolean isSelected(Object parent, Object element, IContentProvider contentProvider, ViewerFilter filter) { 337 if (contentProvider instanceof ITreeContentProvider) { 338 ITreeContentProvider provider = (ITreeContentProvider) contentProvider; 340 while (element != null && !(element instanceof IJavaModel)) { 341 if (!filter.select(fViewer, parent, element)) 342 return false; 343 element= provider.getParent( element); 344 } 345 return true; 346 } 347 return filter.select(fViewer, parent, element); 348 } 349 350 356 private void setFilter(String filterId, boolean state) { 357 fLRUFilterIdsStack.remove(filterId); 359 fLRUFilterIdsStack.add(0, filterId); 360 361 FilterItem item= (FilterItem) fFilterItems.get(filterId); 362 if (item != null) { 363 item.enabled= state; 364 storeViewDefaults(); 365 366 updateViewerFilters(); 367 } 368 } 369 370 private void setEnabledFilterIds(String [] enabledIds) { 371 for (Iterator iterator= fFilterItems.values().iterator(); iterator.hasNext();) { 373 FilterItem item= (FilterItem) iterator.next(); 374 item.enabled= false; 375 } 376 for (int i= 0; i < enabledIds.length; i++) { 378 FilterItem item= (FilterItem) fFilterItems.get(enabledIds[i]); 379 if (item != null) { 380 item.enabled= true; 381 } 382 } 383 } 384 385 private void setUserDefinedPatterns(String [] patterns) { 386 fUserDefinedPatterns= patterns; 387 } 388 389 395 private void setRecentlyChangedFilters(Stack changeHistory) { 396 Stack oldestFirstStack= new Stack (); 397 398 int length= Math.min(changeHistory.size(), MAX_FILTER_MENU_ENTRIES); 399 for (int i= 0; i < length; i++) 400 oldestFirstStack.push(((FilterDescriptor)changeHistory.pop()).getId()); 401 402 length= Math.min(fLRUFilterIdsStack.size(), MAX_FILTER_MENU_ENTRIES - oldestFirstStack.size()); 403 int NEWEST= 0; 404 for (int i= 0; i < length; i++) { 405 Object filter= fLRUFilterIdsStack.remove(NEWEST); 406 if (!oldestFirstStack.contains(filter)) 407 oldestFirstStack.push(filter); 408 } 409 fLRUFilterIdsStack= oldestFirstStack; 410 } 411 412 private boolean areUserDefinedPatternsEnabled() { 413 return fUserDefinedPatternsEnabled; 414 } 415 416 private void setUserDefinedPatternsEnabled(boolean state) { 417 fUserDefinedPatternsEnabled= state; 418 } 419 420 private void fillToolBar(IToolBarManager tooBar) { 421 } 422 423 429 public void fillViewMenu(IMenuManager viewMenu) { 430 435 viewMenu.add(new Separator("filters")); viewMenu.add(new GroupMarker(RECENT_FILTERS_GROUP_NAME)); 437 viewMenu.add(new ShowFilterDialogAction()); 438 439 fMenuManager= viewMenu; 440 fMenuListener= new IMenuListener() { 441 public void menuAboutToShow(IMenuManager manager) { 442 removePreviousLRUFilterActions(manager); 443 addLRUFilterActions(manager); 444 } 445 }; 446 fMenuManager.addMenuListener(fMenuListener); 447 } 448 449 private void removePreviousLRUFilterActions(IMenuManager mm) { 450 if (fFilterIdsUsedInLastViewMenu == null) 451 return; 452 453 for (int i= 0; i < fFilterIdsUsedInLastViewMenu.length; i++) 454 mm.remove(fFilterIdsUsedInLastViewMenu[i]); 455 } 456 457 private void addLRUFilterActions(IMenuManager mm) { 458 if (fLRUFilterIdsStack.isEmpty()) { 459 fFilterIdsUsedInLastViewMenu= null; 460 return; 461 } 462 463 SortedSet sortedFilters= new TreeSet (fLRUFilterIdsStack); 464 String [] recentlyChangedFilterIds= (String [])sortedFilters.toArray(new String [sortedFilters.size()]); 465 466 fFilterIdsUsedInLastViewMenu= new String [recentlyChangedFilterIds.length]; 467 for (int i= 0; i < recentlyChangedFilterIds.length; i++) { 468 String id= recentlyChangedFilterIds[i]; 469 fFilterIdsUsedInLastViewMenu[i]= id; 470 FilterItem filterItem= (FilterItem) fFilterItems.get(id); 471 if (filterItem != null) { 472 IContributionItem item= new FilterActionMenuContributionItem(this, id, filterItem.descriptor.getName(), filterItem.enabled, i+1); 473 mm.insertBefore(RECENT_FILTERS_GROUP_NAME, item); 474 } 475 } 476 } 477 478 481 public void dispose() { 482 if (fMenuManager != null) 483 fMenuManager.removeMenuListener(fMenuListener); 484 fFilterItems.clear(); 485 super.dispose(); 486 } 487 488 490 private boolean updateViewerFilters() { 491 ViewerFilter[] installedFilters= fViewer.getFilters(); 492 ArrayList viewerFilters= new ArrayList (Arrays.asList(installedFilters)); 493 HashSet patterns= new HashSet (); 494 495 boolean hasChange= false; 496 boolean patternChange= false; 497 498 for (Iterator iterator= fFilterItems.values().iterator(); iterator.hasNext();) { 499 FilterItem item= (FilterItem) iterator.next(); 500 if (item.descriptor.isCustomFilter()) { 501 if (item.enabled != item.previouslyEnabled) { 502 ViewerFilter filter= item.getFilterInstance(); if (filter != null) { 504 if (item.enabled) { 505 viewerFilters.add(filter); 506 } else { 507 viewerFilters.remove(filter); 508 } 509 hasChange= true; 510 } 511 } 512 } else if (item.descriptor.isPatternFilter()) { 513 if (item.enabled) { 514 patterns.add(item.descriptor.getPattern()); 515 } 516 patternChange |= (item.enabled != item.previouslyEnabled); 517 } 518 item.previouslyEnabled= item.enabled; 519 } 520 521 if (areUserDefinedPatternsEnabled()) { 522 for (int i= 0; i < fUserDefinedPatterns.length; i++) { 523 patterns.add(fUserDefinedPatterns[i]); 524 } 525 } 526 if (!patternChange) { patternChange= hasChanges(patterns, fPreviousPatterns); 528 } 529 530 fPreviousPatterns= (String []) patterns.toArray(new String [patterns.size()]); 531 if (patternChange) { 532 fPatternFilter.setPatterns(fPreviousPatterns); 533 if (patterns.isEmpty()) { 534 viewerFilters.remove(fPatternFilter); 535 } else if (!viewerFilters.contains(fPatternFilter)) { 536 viewerFilters.add(fPatternFilter); 537 } 538 hasChange= true; 539 } 540 if (hasChange) { 541 fViewer.setFilters((ViewerFilter[]) viewerFilters.toArray(new ViewerFilter[viewerFilters.size()])); } 543 return hasChange; 544 } 545 546 private boolean hasChanges(HashSet patterns, String [] oldPatterns) { 547 HashSet copy= (HashSet ) patterns.clone(); 548 for (int i= 0; i < oldPatterns.length; i++) { 549 boolean found= copy.remove(oldPatterns[i]); 550 if (!found) 551 return true; 552 } 553 return !copy.isEmpty(); 554 } 555 556 558 private void initializeWithViewDefaults() { 559 IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); 561 562 if (!store.contains(getPreferenceKey(TAG_DUMMY_TO_TEST_EXISTENCE))) 564 return; 565 566 fUserDefinedPatternsEnabled= store.getBoolean(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED)); 567 setUserDefinedPatterns(CustomFiltersDialog.convertFromString(store.getString(getPreferenceKey(TAG_USER_DEFINED_PATTERNS)), SEPARATOR)); 568 569 for (Iterator iterator= fFilterItems.values().iterator(); iterator.hasNext();) { 570 FilterItem item= (FilterItem) iterator.next(); 571 String id= item.id; 572 store.setDefault(id, item.descriptor.isEnabled()); 574 item.enabled= store.getBoolean(id); 575 } 576 577 fLRUFilterIdsStack.clear(); 578 String lruFilterIds= store.getString(TAG_LRU_FILTERS); 579 StringTokenizer tokenizer= new StringTokenizer (lruFilterIds, SEPARATOR); 580 while (tokenizer.hasMoreTokens()) { 581 String id= tokenizer.nextToken(); 582 if (fFilterItems.containsKey(id) && !fLRUFilterIdsStack.contains(id)) 583 fLRUFilterIdsStack.push(id); 584 } 585 } 586 587 private void storeViewDefaults() { 588 IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); 590 591 store.setValue(getPreferenceKey(TAG_DUMMY_TO_TEST_EXISTENCE), "storedViewPreferences"); 594 store.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED), fUserDefinedPatternsEnabled); 595 store.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS), CustomFiltersDialog.convertToString(fUserDefinedPatterns ,SEPARATOR)); 596 597 for (Iterator iterator= fFilterItems.values().iterator(); iterator.hasNext();) { 598 FilterItem item= (FilterItem) iterator.next(); 599 store.setValue(item.id, item.enabled); 600 } 601 602 StringBuffer buf= new StringBuffer (fLRUFilterIdsStack.size() * 20); 603 Iterator iter= fLRUFilterIdsStack.iterator(); 604 while (iter.hasNext()) { 605 buf.append((String )iter.next()); 606 buf.append(SEPARATOR); 607 } 608 store.setValue(TAG_LRU_FILTERS, buf.toString()); 609 } 610 611 private String getPreferenceKey(String tag) { 612 return "CustomFiltersActionGroup." + fTargetId + '.' + tag; } 614 615 617 622 public void saveState(IMemento memento) { 623 IMemento customFilters= memento.createChild(TAG_CUSTOM_FILTERS); 624 customFilters.putString(TAG_USER_DEFINED_PATTERNS_ENABLED, Boolean.toString(fUserDefinedPatternsEnabled)); 625 saveUserDefinedPatterns(customFilters); 626 saveXmlDefinedFilters(customFilters); 627 saveLRUFilters(customFilters); 628 } 629 630 private void saveXmlDefinedFilters(IMemento memento) { 631 IMemento xmlDefinedFilters= memento.createChild(TAG_XML_DEFINED_FILTERS); 632 633 for (Iterator iterator= fFilterItems.values().iterator(); iterator.hasNext();) { 634 FilterItem item= (FilterItem) iterator.next(); 635 636 IMemento child= xmlDefinedFilters.createChild(TAG_CHILD); 637 child.putString(TAG_FILTER_ID, item.id); 638 child.putString(TAG_IS_ENABLED, String.valueOf(item.enabled)); 639 } 640 } 641 648 private void saveLRUFilters(IMemento memento) { 649 if(fLRUFilterIdsStack != null && !fLRUFilterIdsStack.isEmpty()) { 650 IMemento lruFilters= memento.createChild(TAG_LRU_FILTERS); 651 Iterator iter= fLRUFilterIdsStack.iterator(); 652 while (iter.hasNext()) { 653 String id= (String )iter.next(); 654 IMemento child= lruFilters.createChild(TAG_CHILD); 655 child.putString(TAG_FILTER_ID, id); 656 } 657 } 658 } 659 660 private void saveUserDefinedPatterns(IMemento memento) { 661 if(fUserDefinedPatterns != null && fUserDefinedPatterns.length > 0) { 662 IMemento userDefinedPatterns= memento.createChild(TAG_USER_DEFINED_PATTERNS); 663 for (int i= 0; i < fUserDefinedPatterns.length; i++) { 664 IMemento child= userDefinedPatterns.createChild(TAG_CHILD); 665 child.putString(TAG_PATTERN, fUserDefinedPatterns[i]); 666 } 667 } 668 } 669 670 678 public void restoreState(IMemento memento) { 679 if (memento == null) 680 return; 681 IMemento customFilters= memento.getChild(TAG_CUSTOM_FILTERS); 682 if (customFilters == null) 683 return; 684 String userDefinedPatternsEnabled= customFilters.getString(TAG_USER_DEFINED_PATTERNS_ENABLED); 685 if (userDefinedPatternsEnabled == null) 686 return; 687 688 fUserDefinedPatternsEnabled= Boolean.valueOf(userDefinedPatternsEnabled).booleanValue(); 689 restoreUserDefinedPatterns(customFilters); 690 restoreXmlDefinedFilters(customFilters); 691 restoreLRUFilters(customFilters); 692 693 updateViewerFilters(); 694 } 695 696 private void restoreUserDefinedPatterns(IMemento memento) { 697 IMemento userDefinedPatterns= memento.getChild(TAG_USER_DEFINED_PATTERNS); 698 if(userDefinedPatterns != null) { 699 IMemento children[]= userDefinedPatterns.getChildren(TAG_CHILD); 700 String [] patterns= new String [children.length]; 701 for (int i = 0; i < children.length; i++) 702 patterns[i]= children[i].getString(TAG_PATTERN); 703 704 setUserDefinedPatterns(patterns); 705 } else 706 setUserDefinedPatterns(new String [0]); 707 } 708 709 private void restoreXmlDefinedFilters(IMemento memento) { 710 IMemento xmlDefinedFilters= memento.getChild(TAG_XML_DEFINED_FILTERS); 711 if(xmlDefinedFilters != null) { 712 IMemento[] children= xmlDefinedFilters.getChildren(TAG_CHILD); 713 for (int i= 0; i < children.length; i++) { 714 String id= children[i].getString(TAG_FILTER_ID); 715 Boolean isEnabled= Boolean.valueOf(children[i].getString(TAG_IS_ENABLED)); 716 FilterItem item= (FilterItem) fFilterItems.get(id); 717 if (item != null) { 718 item.enabled= isEnabled.booleanValue(); 719 } 720 } 721 } 722 } 723 724 private void restoreLRUFilters(IMemento memento) { 725 IMemento lruFilters= memento.getChild(TAG_LRU_FILTERS); 726 fLRUFilterIdsStack.clear(); 727 if(lruFilters != null) { 728 IMemento[] children= lruFilters.getChildren(TAG_CHILD); 729 for (int i= 0; i < children.length; i++) { 730 String id= children[i].getString(TAG_FILTER_ID); 731 if (fFilterItems.containsKey(id) && !fLRUFilterIdsStack.contains(id)) 732 fLRUFilterIdsStack.push(id); 733 } 734 } 735 } 736 737 739 private void openDialog() { 740 CustomFiltersDialog dialog= new CustomFiltersDialog( 741 fViewer.getControl().getShell(), 742 fTargetId, 743 areUserDefinedPatternsEnabled(), 744 fUserDefinedPatterns, 745 internalGetEnabledFilterIds()); 746 747 if (dialog.open() == Window.OK) { 748 setEnabledFilterIds(dialog.getEnabledFilterIds()); 749 setUserDefinedPatternsEnabled(dialog.areUserDefinedPatternsEnabled()); 750 setUserDefinedPatterns(dialog.getUserDefinedPatterns()); 751 setRecentlyChangedFilters(dialog.getFilterDescriptorChangeHistory()); 752 753 storeViewDefaults(); 754 755 updateViewerFilters(); 756 } 757 } 758 } 759 | Popular Tags |