blob: 787fffeb8204d5b1a36294e544133db2b4e8689d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2015 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.ui.internal.navigator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.ui.internal.navigator.filters.CommonFilterDescriptor;
import org.eclipse.ui.internal.navigator.filters.CommonFilterDescriptorManager;
import org.eclipse.ui.internal.navigator.filters.SkeletonViewerFilter;
import org.eclipse.ui.navigator.ICommonFilterDescriptor;
import org.eclipse.ui.navigator.INavigatorFilterService;
/**
* @since 3.2
*
*/
public class NavigatorFilterService implements INavigatorFilterService {
private static final ViewerFilter[] NO_FILTERS = new ViewerFilter[0];
private static final String ACTIVATION_KEY = ".filterActivation"; //$NON-NLS-1$
private static final String DELIM = ":"; //$NON-NLS-1$
private final NavigatorContentService contentService;
/* Map of (ICommonFilterDescriptor, ViewerFilter)-pairs */
private final Map<ICommonFilterDescriptor, ViewerFilter> declaredViewerFilters = new HashMap<ICommonFilterDescriptor, ViewerFilter>();
/* Set of ViewerFilters enforced from visible/active content extensions */
private final Set enforcedViewerFilters = new HashSet();
/* A set of active filter String ids */
private final Set<String> activeFilters = new HashSet<String>();
/**
* @param aContentService
* The corresponding content service
*/
public NavigatorFilterService(NavigatorContentService aContentService) {
contentService = aContentService;
restoreFilterActivation();
}
private synchronized void restoreFilterActivation() {
SafeRunner.run(new NavigatorSafeRunnable() {
@Override
public void run() throws Exception {
IEclipsePreferences prefs = NavigatorContentService.getPreferencesRoot();
if (prefs.get(getFilterActivationPreferenceKey(), null) != null) {
String activatedFiltersPreferenceValue = prefs.get(
getFilterActivationPreferenceKey(), null);
String[] activeFilterIds = activatedFiltersPreferenceValue.split(DELIM);
for (String activeFilterId : activeFilterIds) {
activeFilters.add(activeFilterId);
}
} else {
ICommonFilterDescriptor[] visibleFilterDescriptors = getVisibleFilterDescriptors();
for (ICommonFilterDescriptor visibleFilterDescriptor : visibleFilterDescriptors) {
if (visibleFilterDescriptor.isActiveByDefault()) {
activeFilters.add(visibleFilterDescriptor.getId());
}
}
}
}
});
}
@Override
public void persistFilterActivationState() {
synchronized (activeFilters) {
CommonFilterDescriptorManager dm = CommonFilterDescriptorManager
.getInstance();
/*
* by creating a StringBuffer with DELIM, we ensure the string is
* not empty when persisted.
*/
StringBuffer activatedFiltersPreferenceValue = new StringBuffer(DELIM);
for (String id : activeFilters) {
if (!dm.getFilterById(id).isVisibleInUi())
continue;
activatedFiltersPreferenceValue.append(id).append(DELIM);
}
IEclipsePreferences prefs = NavigatorContentService.getPreferencesRoot();
prefs.put(getFilterActivationPreferenceKey(), activatedFiltersPreferenceValue.toString());
NavigatorContentService.flushPreferences(prefs);
}
}
/**
* Used for the tests
*/
public void resetFilterActivationState() {
IEclipsePreferences prefs = NavigatorContentService.getPreferencesRoot();
prefs.remove(getFilterActivationPreferenceKey());
NavigatorContentService.flushPreferences(prefs);
}
/**
* @return The correct filter activation preference key for the
* corresponding content service.
*/
private String getFilterActivationPreferenceKey() {
return contentService.getViewerId() + ACTIVATION_KEY;
}
@Override
public ViewerFilter[] getVisibleFilters(boolean toReturnOnlyActiveFilters) {
CommonFilterDescriptor[] descriptors = CommonFilterDescriptorManager
.getInstance().findVisibleFilters(contentService);
List<ViewerFilter> filters = new ArrayList<ViewerFilter>();
ViewerFilter instance;
for (CommonFilterDescriptor descriptor : descriptors) {
if (!toReturnOnlyActiveFilters || isActive(descriptor.getId())) {
instance = getViewerFilter(descriptor);
if (instance != null) {
filters.add(instance);
}
}
}
/* return the enforced viewer filters always */
filters.addAll(enforcedViewerFilters);
if (filters.size() == 0) {
return NO_FILTERS;
}
return filters
.toArray(new ViewerFilter[filters.size()]);
}
/**
* @param descriptor
* A key into the viewerFilters map.
* @return A non-null ViewerFilter from the extension (or
* {@link SkeletonViewerFilter#INSTANCE}).
*/
@Override
public ViewerFilter getViewerFilter(ICommonFilterDescriptor descriptor) {
ViewerFilter filter = null;
synchronized (declaredViewerFilters) {
filter = declaredViewerFilters.get(descriptor);
if (filter == null) {
declaredViewerFilters.put(descriptor,
(filter = ((CommonFilterDescriptor) descriptor)
.createFilter()));
}
}
return filter;
}
@Override
public ICommonFilterDescriptor[] getVisibleFilterDescriptors() {
return CommonFilterDescriptorManager.getInstance().findVisibleFilters(
contentService);
}
/**
* @return the visible filter descriptors for the UI
*/
public ICommonFilterDescriptor[] getVisibleFilterDescriptorsForUI() {
return CommonFilterDescriptorManager.getInstance().findVisibleFilters(
contentService, CommonFilterDescriptorManager.FOR_UI);
}
@Override
public boolean isActive(String aFilterId) {
synchronized (activeFilters) {
return activeFilters.contains(aFilterId);
}
}
@Override
public void setActiveFilterIds(String[] theFilterIds) {
Assert.isNotNull(theFilterIds);
synchronized (activeFilters) {
activeFilters.clear();
activeFilters.addAll(Arrays.asList(theFilterIds));
}
}
@Override
public void activateFilterIdsAndUpdateViewer(String[] filterIdsToActivate) {
boolean updateFilterActivation = false;
// we sort the array in order to use Array.binarySearch();
Arrays.sort(filterIdsToActivate);
CommonFilterDescriptor[] visibleFilterDescriptors = (CommonFilterDescriptor[]) getVisibleFilterDescriptors();
int indexofFilterIdToBeActivated;
List<String> nonUiVisible = null;
/* is there a delta? */
for (int i = 0; i < visibleFilterDescriptors.length; i++) {
indexofFilterIdToBeActivated = Arrays.binarySearch(filterIdsToActivate,
visibleFilterDescriptors[i].getId());
/*
* Either we have a filter that should be active that isn't XOR a
* filter that shouldn't be active that is currently
*/
if (indexofFilterIdToBeActivated >= 0 ^ isActive(visibleFilterDescriptors[i].getId())) {
updateFilterActivation = true;
}
// We don't turn of non-UI visible filters here, they have to be manipulated explicitly
if (!visibleFilterDescriptors[i].isVisibleInUi()) {
if (nonUiVisible == null)
nonUiVisible = new ArrayList<String>();
nonUiVisible.add(visibleFilterDescriptors[i].getId());
}
}
/* If so, update */
if (updateFilterActivation) {
if (nonUiVisible != null) {
for (String filterIdToActivate : filterIdsToActivate)
nonUiVisible.add(filterIdToActivate);
filterIdsToActivate = nonUiVisible.toArray(new String[]{});
}
setActiveFilterIds(filterIdsToActivate);
persistFilterActivationState();
updateViewer();
// the action providers may no longer be enabled, so we
// reset the selection.
StructuredViewer commonViewer = (StructuredViewer) contentService.getViewer();
commonViewer.setSelection(StructuredSelection.EMPTY);
}
}
/**
* Updates the viewer filters to match the active filters.
*/
public void updateViewer() {
StructuredViewer commonViewer = (StructuredViewer) contentService.getViewer();
ViewerFilter[] visibleFilters = getVisibleFilters(true);
commonViewer.setFilters(visibleFilters);
}
/**
* Activate the given array without disabling all other filters.
*
* @param theFilterIds
* The filter ids to activate.
*/
public void addActiveFilterIds(String[] theFilterIds) {
Assert.isNotNull(theFilterIds);
synchronized (activeFilters) {
activeFilters.addAll(Arrays.asList(theFilterIds));
}
}
/**
*
* @param aFilterId The id of the filter to activate or deactivate
* @param toMakeActive True to make the filter active, false to make the filter inactive
*/
public void setActive(String aFilterId, boolean toMakeActive) {
synchronized (activeFilters) {
boolean isActive = activeFilters.contains(aFilterId);
if(isActive ^ toMakeActive) {
if(toMakeActive)
activeFilters.add(aFilterId);
else
activeFilters.remove(aFilterId);
}
}
}
}