| /******************************************************************************* |
| * Copyright (c) 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.wst.sse.ui.views.contentoutline; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.viewers.StructuredViewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.wst.sse.ui.internal.filter.OutlineCustomFiltersDialog; |
| import org.eclipse.wst.sse.ui.internal.filter.OutlineFilterDescriptor; |
| import org.eclipse.wst.sse.ui.internal.filter.OutlineNamePatternFilter; |
| |
| /** |
| * Action group to add the filter action to a view part's tool bar menu. |
| * <p> |
| * This class may be instantiated; it is not intended to be subclassed. |
| * </p> |
| * |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class ContentOutlineFilterProcessor { |
| |
| private static final String SEPARATOR = ","; //$NON-NLS-1$ |
| private final String TAG_USER_DEFINED_PATTERNS_ENABLED = "userDefinedPatternsEnabled"; //$NON-NLS-1$ |
| private final String TAG_USER_DEFINED_PATTERNS = "userDefinedPatterns"; //$NON-NLS-1$ |
| |
| private static class FilterItem { |
| boolean enabled; |
| boolean previouslyEnabled; |
| OutlineFilterDescriptor descriptor; |
| String id; |
| |
| private ViewerFilter filterInstance = null; |
| |
| public FilterItem(OutlineFilterDescriptor descriptor) { |
| this.descriptor = descriptor; |
| this.id = descriptor.getId(); |
| this.previouslyEnabled = false; |
| this.enabled = descriptor.isEnabled(); |
| } |
| |
| public ViewerFilter getFilterInstance() { |
| if (filterInstance == null) { |
| filterInstance = descriptor.createViewerFilter(); |
| } |
| return filterInstance; |
| |
| } |
| } |
| |
| private final StructuredViewer fViewer; |
| private final OutlineNamePatternFilter fPatternFilter; |
| |
| private boolean fUserDefinedPatternsEnabled; |
| private String[] fUserDefinedPatterns; |
| |
| private String[] fPreviousPatterns; |
| |
| private final Map fFilterItems; |
| |
| private final String fTargetId; |
| private IPreferenceStore fStore; |
| |
| /** |
| * Creates a new <code>CustomFilterAction</code>. |
| * |
| * @param store |
| * the preference Store |
| * @param ownerId |
| * the id of this action group's owner |
| * @param viewer |
| * the viewer to be filtered |
| */ |
| public ContentOutlineFilterProcessor(IPreferenceStore store, String ownerId, StructuredViewer viewer) { |
| Assert.isNotNull(ownerId); |
| Assert.isNotNull(viewer); |
| fStore = store; |
| fTargetId = ownerId; |
| fViewer = viewer; |
| fPatternFilter = new OutlineNamePatternFilter(); |
| |
| fUserDefinedPatterns = new String[0]; |
| fUserDefinedPatternsEnabled = false; |
| fPreviousPatterns = new String[0]; |
| |
| fFilterItems = new HashMap(); |
| OutlineFilterDescriptor[] filterDescriptors = OutlineFilterDescriptor.getFilterDescriptors(fTargetId); |
| for (int i = 0; i < filterDescriptors.length; i++) { |
| FilterItem item = new FilterItem(filterDescriptors[i]); |
| fFilterItems.put(item.id, item); |
| |
| } |
| |
| initializeWithViewDefaults(); |
| |
| updateViewerFilters(); |
| |
| } |
| |
| /* |
| * @see org.eclipse.jface.action.IContributionItem#isDynamic() |
| */ |
| public boolean isDynamic() { |
| return true; |
| } |
| |
| /** |
| * Returns a list of currently enabled filters. The filter is identified by |
| * its id. |
| * <p> |
| * This method is for internal use only and should not be called by clients |
| * outside of JDT/UI. |
| * </p> |
| * |
| * @return a list of currently enabled filters |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public String[] internalGetEnabledFilterIds() { |
| ArrayList enabledFilterIds = new ArrayList(); |
| for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { |
| FilterItem item = (FilterItem) iterator.next(); |
| if (item.enabled) { |
| enabledFilterIds.add(item.id); |
| } |
| } |
| return (String[]) enabledFilterIds.toArray(new String[enabledFilterIds.size()]); |
| } |
| |
| private void setEnabledFilterIds(String[] enabledIds) { |
| // set all to false |
| fUserDefinedPatternsEnabled = false; |
| for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { |
| FilterItem item = (FilterItem) iterator.next(); |
| item.enabled = false; |
| } |
| // set enabled to true |
| for (int i = 0; i < enabledIds.length; i++) { |
| FilterItem item = (FilterItem) fFilterItems.get(enabledIds[i]); |
| if (item != null) { |
| item.enabled = true; |
| } |
| if (fPatternFilter.getClass().getName().equals(enabledIds[i])) |
| fUserDefinedPatternsEnabled = true; |
| } |
| } |
| |
| private void setUserDefinedPatterns(String[] patterns) { |
| fUserDefinedPatterns = patterns; |
| } |
| |
| private boolean areUserDefinedPatternsEnabled() { |
| return fUserDefinedPatternsEnabled; |
| } |
| |
| private void setUserDefinedPatternsEnabled(boolean state) { |
| fUserDefinedPatternsEnabled = state; |
| } |
| |
| // ---------- viewer filter handling ---------- |
| |
| private boolean updateViewerFilters() { |
| ViewerFilter[] installedFilters = fViewer.getFilters(); |
| ArrayList viewerFilters = new ArrayList(installedFilters.length); |
| |
| HashSet patterns = new HashSet(); |
| |
| boolean hasChange = false; |
| boolean patternChange = false; |
| |
| for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { |
| FilterItem item = (FilterItem) iterator.next(); |
| if (item.descriptor.isCustomFilter()) { |
| if (item.enabled != item.previouslyEnabled) { |
| hasChange = true; |
| } |
| if (item.enabled) { |
| ViewerFilter filter = item.getFilterInstance(); // only |
| // create |
| // when |
| // changed |
| if (filter != null) { |
| viewerFilters.add(filter); |
| } |
| } |
| } else if (item.descriptor.isPatternFilter()) { |
| if (item.enabled) { |
| patterns.add(item.descriptor.getPattern()); |
| } |
| patternChange |= (item.enabled != item.previouslyEnabled); |
| } |
| item.previouslyEnabled = item.enabled; |
| } |
| |
| if (areUserDefinedPatternsEnabled()) { |
| for (int i = 0; i < fUserDefinedPatterns.length; i++) { |
| patterns.add(fUserDefinedPatterns[i]); |
| } |
| } |
| if (!patternChange) { // no pattern change so far, test if the user |
| // patterns made a difference |
| patternChange = hasChanges(patterns, fPreviousPatterns); |
| } |
| |
| fPreviousPatterns = (String[]) patterns.toArray(new String[patterns.size()]); |
| if (patternChange || hasChange) { |
| fPatternFilter.setPatterns(fPreviousPatterns); |
| if (patterns.isEmpty()) { |
| viewerFilters.remove(fPatternFilter); |
| } else if (!viewerFilters.contains(fPatternFilter)) { |
| boolean contains = false; |
| for (int i = 0; i < viewerFilters.size(); i++) { |
| if (viewerFilters.get(i) instanceof OutlineNamePatternFilter) { |
| OutlineNamePatternFilter filter = (OutlineNamePatternFilter) viewerFilters.get(i); |
| String[] a1 = filter.getPatterns(); |
| String[] a2 = fPatternFilter.getPatterns(); |
| if (a1[0].equals(a2[0])) |
| contains = true; |
| else { |
| viewerFilters.remove(i); |
| } |
| break; |
| } |
| } |
| if (!contains) |
| viewerFilters.add(fPatternFilter); |
| } |
| hasChange = true; |
| } |
| if (hasChange) { |
| fViewer.setFilters((ViewerFilter[]) viewerFilters.toArray(new ViewerFilter[viewerFilters.size()])); // will |
| // refresh |
| } |
| return hasChange; |
| } |
| |
| private boolean hasChanges(HashSet patterns, String[] oldPatterns) { |
| HashSet copy = (HashSet) patterns.clone(); |
| for (int i = 0; i < oldPatterns.length; i++) { |
| boolean found = copy.remove(oldPatterns[i]); |
| if (!found) |
| return true; |
| } |
| return !copy.isEmpty(); |
| } |
| |
| // ---------- view kind/defaults persistency ---------- |
| |
| private void initializeWithViewDefaults() { |
| // get default values for view |
| |
| fUserDefinedPatternsEnabled = fStore.getBoolean(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED)); |
| setUserDefinedPatterns(OutlineCustomFiltersDialog.convertFromString(fStore.getString(getPreferenceKey(TAG_USER_DEFINED_PATTERNS)), SEPARATOR)); |
| |
| for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { |
| FilterItem item = (FilterItem) iterator.next(); |
| String id = item.id; |
| // set default to value from plugin contributions (fixes |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=73991 ): |
| fStore.setDefault(id, item.descriptor.isEnabled()); |
| item.enabled = fStore.getBoolean(id); |
| } |
| |
| } |
| |
| private void storeViewDefaults() { |
| // get default values for view |
| |
| fStore.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED), fUserDefinedPatternsEnabled); |
| fStore.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS), OutlineCustomFiltersDialog.convertToString(fUserDefinedPatterns, SEPARATOR)); |
| |
| boolean fFilterSelected = false; |
| for (Iterator iterator = fFilterItems.values().iterator(); iterator.hasNext();) { |
| FilterItem item = (FilterItem) iterator.next(); |
| fStore.setValue(item.id, item.enabled); |
| if (item.enabled) |
| fFilterSelected = true; |
| } |
| |
| fStore.setValue(fTargetId, fUserDefinedPatternsEnabled || fFilterSelected); |
| |
| } |
| |
| private String getPreferenceKey(String tag) { |
| return "CustomFiltersActionGroup." + fTargetId + '.' + tag; //$NON-NLS-1$ |
| } |
| |
| public void openDialog() { |
| OutlineCustomFiltersDialog dialog = new OutlineCustomFiltersDialog(fViewer.getControl().getShell(), fTargetId, areUserDefinedPatternsEnabled(), fUserDefinedPatterns, internalGetEnabledFilterIds()); |
| |
| if (dialog.open() == Window.OK) { |
| |
| setEnabledFilterIds(dialog.getEnabledFilterIds()); |
| setUserDefinedPatternsEnabled(dialog.areUserDefinedPatternsEnabled()); |
| setUserDefinedPatterns(dialog.getUserDefinedPatterns()); |
| storeViewDefaults(); |
| |
| updateViewerFilters(); |
| } else { |
| storeViewDefaults(); |
| } |
| } |
| } |