2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.openapi.actionSystem;
18 import com.intellij.ide.ui.UISettings;
19 import com.intellij.openapi.util.Comparing;
20 import com.intellij.util.SmartFMap;
21 import com.intellij.util.ui.UIUtil;
22 import org.jetbrains.annotations.NonNls;
23 import org.jetbrains.annotations.NotNull;
24 import org.jetbrains.annotations.Nullable;
27 import java.beans.PropertyChangeListener;
28 import java.beans.PropertyChangeSupport;
31 * The presentation of an action in a specific place in the user interface.
36 public final class Presentation implements Cloneable {
37 private SmartFMap<String, Object> myUserMap = SmartFMap.emptyMap();
40 * Defines tool tip for button at tool bar or text for element at menu
43 @NonNls public static final String PROP_TEXT = "text";
47 @NonNls public static final String PROP_MNEMONIC_KEY = "mnemonicKey";
51 @NonNls public static final String PROP_MNEMONIC_INDEX = "mnemonicIndex";
55 @NonNls public static final String PROP_DESCRIPTION = "description";
59 @NonNls public static final String PROP_ICON = "icon";
63 @NonNls public static final String PROP_DISABLED_ICON = "disabledIcon";
67 @NonNls public static final String PROP_SELECTED_ICON = "selectedIcon";
71 @NonNls public static final String PROP_HOVERED_ICON = "hoveredIcon";
75 @NonNls public static final String PROP_VISIBLE = "visible";
77 * The actual value is a Boolean.
79 @NonNls public static final String PROP_ENABLED = "enabled";
81 public static final double DEFAULT_WEIGHT = 0;
82 public static final double HIGHER_WEIGHT = 42;
83 public static final double EVEN_HIGHER_WEIGHT = 239;
85 private final PropertyChangeSupport myChangeSupport = new PropertyChangeSupport(this);
86 private String myText;
87 private String myDescription;
89 private Icon myDisabledIcon;
90 private Icon myHoveredIcon;
91 private Icon mySelectedIcon;
92 private int myMnemonic;
93 private int myDisplayedMnemonicIndex = -1;
94 private boolean myVisible = true;
95 private boolean myEnabled = true;
96 private double myWeight = DEFAULT_WEIGHT;
98 public Presentation() {
101 public Presentation(String text) {
105 public void addPropertyChangeListener(PropertyChangeListener l) {
106 myChangeSupport.addPropertyChangeListener(l);
109 public void removePropertyChangeListener(PropertyChangeListener l) {
110 myChangeSupport.removePropertyChangeListener(l);
114 public String getText() {
118 public void setText(@Nullable String text, boolean mayContainMnemonic) {
119 int oldMnemonic = myMnemonic;
120 int oldDisplayedMnemonicIndex = myDisplayedMnemonicIndex;
121 String oldText = myText;
123 myDisplayedMnemonicIndex = -1;
126 if (text.indexOf(UIUtil.MNEMONIC) >= 0) {
127 text = text.replace(UIUtil.MNEMONIC, '&');
130 if (mayContainMnemonic) {
131 StringBuilder plainText = new StringBuilder();
132 for (int i = 0; i < text.length(); i++) {
133 char ch = text.charAt(i);
134 if (myMnemonic == 0 && (ch == '_' || ch == '&')) {
135 //noinspection AssignmentToForLoopParameter
137 if (i >= text.length()) break;
139 if (ch != '_' && ch != '&') {
140 if (UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) {
142 myDisplayedMnemonicIndex = -1;
145 myMnemonic = Character.toUpperCase(ch); // mnemonics are case insensitive
146 myDisplayedMnemonicIndex = i - 1;
150 plainText.append(ch);
152 myText = plainText.length() == 0 ? "" : plainText.toString();
155 myText = text.isEmpty() ? "" : text;
162 myChangeSupport.firePropertyChange(PROP_TEXT, oldText, myText);
163 if (myMnemonic != oldMnemonic) {
164 myChangeSupport.firePropertyChange(PROP_MNEMONIC_KEY, new Integer(oldMnemonic), new Integer(myMnemonic));
166 if (myDisplayedMnemonicIndex != oldDisplayedMnemonicIndex) {
167 myChangeSupport.firePropertyChange(PROP_MNEMONIC_INDEX, new Integer(oldDisplayedMnemonicIndex), new Integer(myDisplayedMnemonicIndex));
171 public void setText(String text) {
175 public String getTextWithMnemonic() {
176 if (myText != null && myDisplayedMnemonicIndex > -1) {
177 return myText.substring(0, myDisplayedMnemonicIndex) + "_" + myText.substring(myDisplayedMnemonicIndex);
182 public void restoreTextWithMnemonic(Presentation presentation) {
183 setText(presentation.getTextWithMnemonic());
186 public static String restoreTextWithMnemonic(@Nullable String text, final int mnemonic) {
190 for (int i = 0; i < text.length(); i++) {
191 if (Character.toUpperCase(text.charAt(i)) == mnemonic) {
192 return text.substring(0, i) + "_" + text.substring(i);
198 public String getDescription() {
199 return myDescription;
202 public void setDescription(String description) {
203 String oldDescription = myDescription;
204 myDescription = description;
205 myChangeSupport.firePropertyChange(PROP_DESCRIPTION, oldDescription, myDescription);
208 public Icon getIcon() {
212 public void setIcon(@Nullable Icon icon) {
213 Icon oldIcon = myIcon;
214 if (oldIcon == icon) return;
217 myChangeSupport.firePropertyChange(PROP_ICON, oldIcon, myIcon);
220 public Icon getDisabledIcon() {
221 return myDisabledIcon;
224 public void setDisabledIcon(@Nullable Icon icon) {
225 Icon oldDisabledIcon = myDisabledIcon;
226 myDisabledIcon = icon;
227 myChangeSupport.firePropertyChange(PROP_DISABLED_ICON, oldDisabledIcon, myDisabledIcon);
230 public Icon getHoveredIcon() {
231 return myHoveredIcon;
234 public void setHoveredIcon(@Nullable final Icon hoveredIcon) {
235 Icon old = myHoveredIcon;
236 myHoveredIcon = hoveredIcon;
237 myChangeSupport.firePropertyChange(PROP_HOVERED_ICON, old, myHoveredIcon);
240 public Icon getSelectedIcon() {
241 return mySelectedIcon;
244 public void setSelectedIcon(Icon selectedIcon) {
245 Icon old = mySelectedIcon;
246 mySelectedIcon = selectedIcon;
247 myChangeSupport.firePropertyChange(PROP_SELECTED_ICON, old, mySelectedIcon);
250 public int getMnemonic() {
254 public int getDisplayedMnemonicIndex() {
255 return myDisplayedMnemonicIndex;
258 public boolean isVisible() {
262 public void setVisible(boolean visible) {
263 boolean oldVisible = myVisible;
265 firePropertyChange(PROP_VISIBLE, oldVisible, myVisible);
269 * Returns the state of this action.
271 * @return <code>true</code> if action is enabled, <code>false</code> otherwise
273 public boolean isEnabled() {
278 * Sets whether the action enabled or not. If an action is disabled, {@link AnAction#actionPerformed}
279 * won't be called. In case when action represents a button or a menu item, the
280 * representing button or item will be greyed out.
282 * @param enabled <code>true</code> if you want to enable action, <code>false</code> otherwise
284 public void setEnabled(boolean enabled) {
285 boolean oldEnabled = myEnabled;
287 firePropertyChange(PROP_ENABLED, oldEnabled, myEnabled);
290 public final void setEnabledAndVisible(boolean enabled) {
295 void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
296 myChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
300 public Presentation clone() {
301 Presentation presentation = new Presentation();
302 presentation.copyFrom(this);
306 public void copyFrom(Presentation presentation) {
307 setText(presentation.getTextWithMnemonic(), presentation.myDisplayedMnemonicIndex > -1);
308 setDescription(presentation.getDescription());
309 setIcon(presentation.getIcon());
310 setDisabledIcon(presentation.getDisabledIcon());
311 setVisible(presentation.isVisible());
312 setEnabled(presentation.isEnabled());
316 public Object getClientProperty(@NonNls @NotNull String key) {
317 return myUserMap.get(key);
320 public void putClientProperty(@NonNls @NotNull String key, @Nullable Object value) {
321 Object oldValue = myUserMap.get(key);
322 if (Comparing.equal(oldValue, value)) return;
323 myUserMap = value == null ? myUserMap.minus(key) : myUserMap.plus(key, value);
324 myChangeSupport.firePropertyChange(key, oldValue, value);
327 public double getWeight() {
332 * Some action groups (like 'New...') may filter out actions with non-highest priority.
333 * @param weight please use {@link #HIGHER_WEIGHT} or {@link #EVEN_HIGHER_WEIGHT}
335 public void setWeight(double weight) {
340 public String toString() {
341 return myText + " (" + myDescription + ")";
344 public boolean isEnabledAndVisible() {
345 return isEnabled() && isVisible();