001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal;
011:
012: import java.util.Collection;
013: import java.util.HashMap;
014: import java.util.HashSet;
015: import java.util.Map;
016:
017: import org.eclipse.core.runtime.ListenerList;
018: import org.eclipse.ui.IPropertyListener;
019: import org.eclipse.ui.contexts.IContextActivation;
020: import org.eclipse.ui.contexts.IContextService;
021: import org.eclipse.ui.internal.registry.IActionSetDescriptor;
022: import org.eclipse.ui.services.IServiceLocator;
023:
024: /**
025: * Maintains a reference counted set of action sets, with a visibility mask.
026: * This is used to determine the visibility of actions in a workbench page. In a
027: * workbench page, there may be may be many conditions that can cause an action
028: * set to become visible (such as the active part, the active editor, the
029: * default visibility of the action, the properties of the perspective, etc.)
030: * The user can also explicitly mask off particular action sets in each
031: * perspective.
032: * <p>
033: * The reference count indicates how many conditions have requested that the
034: * actions be active and the mask indicates whether or not the set was disabled
035: * by the user.
036: * </p>
037: *
038: * @since 3.1
039: */
040: public class ActionSetManager {
041:
042: private static class ActionSetRec {
043: int showCount;
044:
045: int maskCount;
046:
047: public boolean isVisible() {
048: return maskCount == 0 && showCount > 0;
049: }
050:
051: public boolean isEmpty() {
052: return maskCount == 0 && showCount == 0;
053: }
054: }
055:
056: private HashMap actionSets = new HashMap();
057: private HashSet visibleItems = new HashSet();
058:
059: public static final int PROP_VISIBLE = 0;
060: public static final int PROP_HIDDEN = 1;
061: public static final int CHANGE_MASK = 0;
062: public static final int CHANGE_UNMASK = 1;
063: public static final int CHANGE_SHOW = 2;
064: public static final int CHANGE_HIDE = 3;
065:
066: private ListenerList listeners = new ListenerList();
067: private IPropertyListener contextListener;
068: private Map activationsById = new HashMap();
069: private IContextService contextService;
070:
071: public ActionSetManager(IServiceLocator locator) {
072: contextService = (IContextService) locator
073: .getService(IContextService.class);
074: addListener(getContextListener());
075: }
076:
077: /**
078: * @return
079: */
080: private IPropertyListener getContextListener() {
081: if (contextListener == null) {
082: contextListener = new IPropertyListener() {
083: public void propertyChanged(Object source, int propId) {
084: if (source instanceof IActionSetDescriptor) {
085: IActionSetDescriptor desc = (IActionSetDescriptor) source;
086: String id = desc.getId();
087: if (propId == PROP_VISIBLE) {
088: activationsById.put(id, contextService
089: .activateContext(id));
090: } else if (propId == PROP_HIDDEN) {
091: IContextActivation act = (IContextActivation) activationsById
092: .remove(id);
093: if (act != null) {
094: contextService.deactivateContext(act);
095: }
096: }
097: }
098: }
099: };
100: }
101: return contextListener;
102: }
103:
104: public void addListener(IPropertyListener l) {
105: listeners.add(l);
106: }
107:
108: public void removeListener(IPropertyListener l) {
109: listeners.remove(l);
110: }
111:
112: private void firePropertyChange(IActionSetDescriptor descriptor,
113: int id) {
114: Object[] l = listeners.getListeners();
115: for (int i = 0; i < l.length; i++) {
116: IPropertyListener listener = (IPropertyListener) l[i];
117: listener.propertyChanged(descriptor, id);
118: }
119: }
120:
121: private ActionSetRec getRec(IActionSetDescriptor descriptor) {
122: ActionSetRec rec = (ActionSetRec) actionSets.get(descriptor);
123:
124: if (rec == null) {
125: rec = new ActionSetRec();
126: actionSets.put(descriptor, rec);
127: }
128:
129: return rec;
130: }
131:
132: public void showAction(IActionSetDescriptor descriptor) {
133: ActionSetRec rec = getRec(descriptor);
134:
135: boolean wasVisible = rec.isVisible();
136: rec.showCount++;
137: if (!wasVisible && rec.isVisible()) {
138: visibleItems.add(descriptor);
139: firePropertyChange(descriptor, PROP_VISIBLE);
140: if (rec.isEmpty()) {
141: actionSets.remove(descriptor);
142: }
143: }
144: }
145:
146: public void hideAction(IActionSetDescriptor descriptor) {
147: ActionSetRec rec = getRec(descriptor);
148:
149: boolean wasVisible = rec.isVisible();
150: rec.showCount--;
151: if (wasVisible && !rec.isVisible()) {
152: visibleItems.remove(descriptor);
153: firePropertyChange(descriptor, PROP_HIDDEN);
154: if (rec.isEmpty()) {
155: actionSets.remove(descriptor);
156: }
157: }
158: }
159:
160: public void maskAction(IActionSetDescriptor descriptor) {
161: ActionSetRec rec = getRec(descriptor);
162:
163: boolean wasVisible = rec.isVisible();
164: rec.maskCount++;
165: if (wasVisible && !rec.isVisible()) {
166: visibleItems.remove(descriptor);
167: firePropertyChange(descriptor, PROP_HIDDEN);
168: if (rec.isEmpty()) {
169: actionSets.remove(descriptor);
170: }
171: }
172: }
173:
174: public void unmaskAction(IActionSetDescriptor descriptor) {
175: ActionSetRec rec = getRec(descriptor);
176:
177: boolean wasVisible = rec.isVisible();
178: rec.maskCount--;
179: if (!wasVisible && rec.isVisible()) {
180: visibleItems.add(descriptor);
181: firePropertyChange(descriptor, PROP_VISIBLE);
182: if (rec.isEmpty()) {
183: actionSets.remove(descriptor);
184: }
185: }
186: }
187:
188: public Collection getVisibleItems() {
189: return visibleItems;
190: }
191:
192: public void change(IActionSetDescriptor descriptor, int changeType) {
193: switch (changeType) {
194: case CHANGE_SHOW:
195: showAction(descriptor);
196: break;
197: case CHANGE_HIDE:
198: hideAction(descriptor);
199: break;
200: case CHANGE_MASK:
201: maskAction(descriptor);
202: break;
203: case CHANGE_UNMASK:
204: unmaskAction(descriptor);
205: break;
206: }
207: }
208: }
|