blob: 692f5b6127c747371d3ddc172d2154e636c641a8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 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;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
import org.eclipse.ui.services.IServiceLocator;
/**
* Maintains a reference counted set of action sets, with a visibility mask.
* This is used to determine the visibility of actions in a workbench page. In a
* workbench page, there may be may be many conditions that can cause an action
* set to become visible (such as the active part, the active editor, the
* default visibility of the action, the properties of the perspective, etc.)
* The user can also explicitly mask off particular action sets in each
* perspective.
* <p>
* The reference count indicates how many conditions have requested that the
* actions be active and the mask indicates whether or not the set was disabled
* by the user.
* </p>
*
*/
public class ActionSetManager {
private static class ActionSetRec {
int showCount;
int maskCount;
public boolean isVisible() {
return maskCount == 0 && showCount > 0;
}
public boolean isEmpty() {
return maskCount == 0 && showCount == 0;
}
}
private HashMap actionSets = new HashMap();
private HashSet visibleItems = new HashSet();
public static final int PROP_VISIBLE = 0;
public static final int PROP_HIDDEN = 1;
public static final int CHANGE_MASK = 0;
public static final int CHANGE_UNMASK = 1;
public static final int CHANGE_SHOW = 2;
public static final int CHANGE_HIDE = 3;
private ListenerList listeners = new ListenerList();
private IPropertyListener contextListener;
private Map activationsById = new HashMap();
private IContextService contextService;
public ActionSetManager(IServiceLocator locator) {
contextService = (IContextService) locator.getService(IContextService.class);
addListener(getContextListener());
}
/**
* @return
*/
private IPropertyListener getContextListener() {
if (contextListener == null) {
contextListener = new IPropertyListener() {
public void propertyChanged(Object source, int propId) {
if (source instanceof IActionSetDescriptor) {
IActionSetDescriptor desc = (IActionSetDescriptor) source;
String id = desc.getId();
if (propId == PROP_VISIBLE) {
activationsById.put(id, contextService
.activateContext(id));
} else if (propId == PROP_HIDDEN) {
IContextActivation act = (IContextActivation) activationsById
.remove(id);
if (act != null) {
contextService.deactivateContext(act);
}
}
}
}
};
}
return contextListener;
}
public void addListener(IPropertyListener l) {
listeners.add(l);
}
public void removeListener(IPropertyListener l) {
listeners.remove(l);
}
private void firePropertyChange(IActionSetDescriptor descriptor, int id) {
Object[] l = listeners.getListeners();
for (int i=0; i<l.length; i++) {
IPropertyListener listener = (IPropertyListener) l[i];
listener.propertyChanged(descriptor, id);
}
}
private ActionSetRec getRec(IActionSetDescriptor descriptor) {
ActionSetRec rec = (ActionSetRec)actionSets.get(descriptor);
if (rec == null) {
rec = new ActionSetRec();
actionSets.put(descriptor, rec);
}
return rec;
}
public void showAction(IActionSetDescriptor descriptor) {
ActionSetRec rec = getRec(descriptor);
boolean wasVisible = rec.isVisible();
rec.showCount++;
if (!wasVisible && rec.isVisible()) {
visibleItems.add(descriptor);
firePropertyChange(descriptor, PROP_VISIBLE);
if (rec.isEmpty()) {
actionSets.remove(descriptor);
}
}
}
public void hideAction(IActionSetDescriptor descriptor) {
ActionSetRec rec = getRec(descriptor);
boolean wasVisible = rec.isVisible();
rec.showCount--;
if (wasVisible && !rec.isVisible()) {
visibleItems.remove(descriptor);
firePropertyChange(descriptor, PROP_HIDDEN);
if (rec.isEmpty()) {
actionSets.remove(descriptor);
}
}
}
public void maskAction(IActionSetDescriptor descriptor) {
ActionSetRec rec = getRec(descriptor);
boolean wasVisible = rec.isVisible();
rec.maskCount++;
if (wasVisible && !rec.isVisible()) {
visibleItems.remove(descriptor);
firePropertyChange(descriptor, PROP_HIDDEN);
if (rec.isEmpty()) {
actionSets.remove(descriptor);
}
}
}
public void unmaskAction(IActionSetDescriptor descriptor) {
ActionSetRec rec = getRec(descriptor);
boolean wasVisible = rec.isVisible();
rec.maskCount--;
if (!wasVisible && rec.isVisible()) {
visibleItems.add(descriptor);
firePropertyChange(descriptor, PROP_VISIBLE);
if (rec.isEmpty()) {
actionSets.remove(descriptor);
}
}
}
public Collection getVisibleItems() {
return visibleItems;
}
public void change(IActionSetDescriptor descriptor, int changeType) {
switch(changeType) {
case CHANGE_SHOW:
showAction(descriptor); break;
case CHANGE_HIDE:
hideAction(descriptor); break;
case CHANGE_MASK:
maskAction(descriptor); break;
case CHANGE_UNMASK:
unmaskAction(descriptor); break;
}
}
}