blob: b1b61e3e3329db3a4b7aced87a456026273293bd [file] [log] [blame]
/*******************************************************************************
* 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();
}
}
}