1 /******************************************************************************* 2 * Copyright (c) 2005, 2016 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Lars Vogel <Lars.Vogel@gmail.com> - Bug 440810 14 *******************************************************************************/ 15 package org.eclipse.ui.internal; 16 17 import java.util.Collection; 18 import java.util.HashMap; 19 import java.util.HashSet; 20 import java.util.Map; 21 import org.eclipse.core.runtime.ListenerList; 22 import org.eclipse.ui.IPropertyListener; 23 import org.eclipse.ui.contexts.IContextActivation; 24 import org.eclipse.ui.contexts.IContextService; 25 import org.eclipse.ui.internal.registry.IActionSetDescriptor; 26 import org.eclipse.ui.services.IServiceLocator; 27 28 /** 29 * Maintains a reference counted set of action sets, with a visibility mask. 30 * This is used to determine the visibility of actions in a workbench page. In a 31 * workbench page, there may be may be many conditions that can cause an action 32 * set to become visible (such as the active part, the active editor, the 33 * default visibility of the action, the properties of the perspective, etc.) 34 * The user can also explicitly mask off particular action sets in each 35 * perspective. 36 * <p> 37 * The reference count indicates how many conditions have requested that the 38 * actions be active and the mask indicates whether or not the set was disabled 39 * by the user. 40 * </p> 41 * 42 * @since 3.1 43 */ 44 public class ActionSetManager { 45 46 private static class ActionSetRec { 47 int showCount; 48 49 int maskCount; 50 isVisible()51 public boolean isVisible() { 52 return maskCount == 0 && showCount > 0; 53 } 54 isEmpty()55 public boolean isEmpty() { 56 return maskCount == 0 && showCount == 0; 57 } 58 } 59 60 private HashMap actionSets = new HashMap(); 61 private HashSet visibleItems = new HashSet(); 62 63 public static final int PROP_VISIBLE = 0; 64 public static final int PROP_HIDDEN = 1; 65 public static final int CHANGE_MASK = 0; 66 public static final int CHANGE_UNMASK = 1; 67 public static final int CHANGE_SHOW = 2; 68 public static final int CHANGE_HIDE = 3; 69 70 private ListenerList<IPropertyListener> listeners = new ListenerList<>(); 71 private IPropertyListener contextListener; 72 private Map activationsById = new HashMap(); 73 private IContextService contextService; 74 ActionSetManager(IServiceLocator locator)75 public ActionSetManager(IServiceLocator locator) { 76 contextService = locator.getService(IContextService.class); 77 addListener(getContextListener()); 78 } 79 80 /** 81 * @return 82 */ getContextListener()83 private IPropertyListener getContextListener() { 84 if (contextListener == null) { 85 contextListener = (source, propId) -> { 86 if (source instanceof IActionSetDescriptor) { 87 IActionSetDescriptor desc = (IActionSetDescriptor) source; 88 String id = desc.getId(); 89 if (propId == PROP_VISIBLE) { 90 activationsById.put(id, contextService.activateContext(id)); 91 } else if (propId == PROP_HIDDEN) { 92 IContextActivation act = (IContextActivation) activationsById.remove(id); 93 if (act != null) { 94 contextService.deactivateContext(act); 95 } 96 } 97 } 98 }; 99 } 100 return contextListener; 101 } 102 addListener(IPropertyListener l)103 public void addListener(IPropertyListener l) { 104 listeners.add(l); 105 } 106 removeListener(IPropertyListener l)107 public void removeListener(IPropertyListener l) { 108 listeners.remove(l); 109 } 110 firePropertyChange(IActionSetDescriptor descriptor, int id)111 private void firePropertyChange(IActionSetDescriptor descriptor, int id) { 112 for (IPropertyListener listener : listeners) { 113 listener.propertyChanged(descriptor, id); 114 } 115 } 116 getRec(IActionSetDescriptor descriptor)117 private ActionSetRec getRec(IActionSetDescriptor descriptor) { 118 ActionSetRec rec = (ActionSetRec) actionSets.get(descriptor); 119 120 if (rec == null) { 121 rec = new ActionSetRec(); 122 actionSets.put(descriptor, rec); 123 } 124 125 return rec; 126 } 127 showAction(IActionSetDescriptor descriptor)128 public void showAction(IActionSetDescriptor descriptor) { 129 ActionSetRec rec = getRec(descriptor); 130 131 boolean wasVisible = rec.isVisible(); 132 rec.showCount++; 133 if (!wasVisible && rec.isVisible()) { 134 visibleItems.add(descriptor); 135 firePropertyChange(descriptor, PROP_VISIBLE); 136 if (rec.isEmpty()) { 137 actionSets.remove(descriptor); 138 } 139 } 140 } 141 hideAction(IActionSetDescriptor descriptor)142 public void hideAction(IActionSetDescriptor descriptor) { 143 ActionSetRec rec = getRec(descriptor); 144 145 boolean wasVisible = rec.isVisible(); 146 rec.showCount--; 147 if (wasVisible && !rec.isVisible()) { 148 visibleItems.remove(descriptor); 149 firePropertyChange(descriptor, PROP_HIDDEN); 150 if (rec.isEmpty()) { 151 actionSets.remove(descriptor); 152 } 153 } 154 } 155 maskAction(IActionSetDescriptor descriptor)156 public void maskAction(IActionSetDescriptor descriptor) { 157 ActionSetRec rec = getRec(descriptor); 158 159 boolean wasVisible = rec.isVisible(); 160 rec.maskCount++; 161 if (wasVisible && !rec.isVisible()) { 162 visibleItems.remove(descriptor); 163 firePropertyChange(descriptor, PROP_HIDDEN); 164 if (rec.isEmpty()) { 165 actionSets.remove(descriptor); 166 } 167 } 168 } 169 unmaskAction(IActionSetDescriptor descriptor)170 public void unmaskAction(IActionSetDescriptor descriptor) { 171 ActionSetRec rec = getRec(descriptor); 172 173 boolean wasVisible = rec.isVisible(); 174 rec.maskCount--; 175 if (!wasVisible && rec.isVisible()) { 176 visibleItems.add(descriptor); 177 firePropertyChange(descriptor, PROP_VISIBLE); 178 if (rec.isEmpty()) { 179 actionSets.remove(descriptor); 180 } 181 } 182 } 183 getVisibleItems()184 public Collection getVisibleItems() { 185 return visibleItems; 186 } 187 change(IActionSetDescriptor descriptor, int changeType)188 public void change(IActionSetDescriptor descriptor, int changeType) { 189 switch (changeType) { 190 case CHANGE_SHOW: 191 showAction(descriptor); 192 break; 193 case CHANGE_HIDE: 194 hideAction(descriptor); 195 break; 196 case CHANGE_MASK: 197 maskAction(descriptor); 198 break; 199 case CHANGE_UNMASK: 200 unmaskAction(descriptor); 201 break; 202 } 203 } 204 } 205