update menu items on app activation fix
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / actionSystem / impl / ActionMenu.java
blob8526d8f6fdda1d54f24d33dca4a16a2ee388d1df
1 /*
2 * Copyright 2000-2009 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.impl;
18 import com.intellij.ide.DataManager;
19 import com.intellij.openapi.actionSystem.ActionGroup;
20 import com.intellij.openapi.actionSystem.ActionPlaces;
21 import com.intellij.openapi.actionSystem.DataContext;
22 import com.intellij.openapi.actionSystem.Presentation;
23 import com.intellij.openapi.util.IconLoader;
24 import com.intellij.openapi.util.SystemInfo;
25 import com.intellij.openapi.wm.StatusBar;
26 import com.intellij.openapi.wm.impl.IdeFrameImpl;
27 import com.intellij.ui.plaf.beg.IdeaMenuUI;
28 import com.intellij.util.ui.UIUtil;
30 import javax.swing.*;
31 import javax.swing.event.MenuEvent;
32 import javax.swing.event.MenuListener;
33 import javax.swing.plaf.MenuItemUI;
34 import java.awt.*;
35 import java.awt.event.KeyEvent;
36 import java.beans.PropertyChangeEvent;
37 import java.beans.PropertyChangeListener;
39 public final class ActionMenu extends JMenu {
40 private final String myPlace;
41 private DataContext myContext;
42 private final ActionGroup myGroup;
43 private final PresentationFactory myPresentationFactory;
44 private final Presentation myPresentation;
45 /**
46 * Defines whether menu shows its mnemonic or not.
48 private boolean myMnemonicEnabled;
49 private MenuItemSynchronizer myMenuItemSynchronizer;
50 /**
51 * This is PATCH!!!
52 * Do not remove this STUPID code. Otherwise you will lose all keyboard navigation
53 * at JMenuBar.
55 private StubItem myStubItem;
57 public ActionMenu(DataContext context, String place, ActionGroup group, PresentationFactory presentationFactory, final boolean enableMnemonics) {
58 myContext = context;
59 myPlace = place;
60 myGroup = group;
61 myPresentationFactory = presentationFactory;
62 myPresentation = myPresentationFactory.getPresentation(group);
63 myMnemonicEnabled = enableMnemonics;
65 init();
67 // addNotify won't be called for menus in MacOS system menu
68 if (SystemInfo.isMacSystemMenu) {
69 installSynchronizer();
73 public void updateContext(DataContext context) {
74 myContext = context;
77 public void addNotify() {
78 super.addNotify();
79 installSynchronizer();
82 private void installSynchronizer() {
83 if (myMenuItemSynchronizer == null) {
84 myMenuItemSynchronizer = new MenuItemSynchronizer();
85 myGroup.addPropertyChangeListener(myMenuItemSynchronizer);
86 myPresentation.addPropertyChangeListener(myMenuItemSynchronizer);
90 public void removeNotify() {
91 if (myMenuItemSynchronizer != null) {
92 myGroup.removePropertyChangeListener(myMenuItemSynchronizer);
93 myPresentation.removePropertyChangeListener(myMenuItemSynchronizer);
94 myMenuItemSynchronizer = null;
96 super.removeNotify();
99 public void updateUI() {
100 JPopupMenu popupMenu = getPopupMenu();
101 if (popupMenu != null) {
102 popupMenu.updateUI();
104 if (UIUtil.isStandardMenuLAF()) {
105 setUI((MenuItemUI)UIManager.getUI(this));
107 else {
108 setUI(IdeaMenuUI.createUI(this));
109 setFont(UIUtil.getMenuFont());
113 private void init() {
114 boolean macSystemMenu = SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU;
116 myStubItem = macSystemMenu ? null : new StubItem();
117 addStubItem();
118 addMenuListener(new MenuListenerImpl());
119 setBorderPainted(false);
121 setVisible(myPresentation.isVisible());
122 setEnabled(myPresentation.isEnabled());
123 setText(myPresentation.getText());
124 updateIcon();
126 setMnemonicEnabled(myMnemonicEnabled);
129 private void addStubItem() {
130 if (myStubItem != null) {
131 add(myStubItem);
135 public void setMnemonicEnabled(boolean enable) {
136 myMnemonicEnabled = enable;
137 setMnemonic(myPresentation.getMnemonic());
138 setDisplayedMnemonicIndex(myPresentation.getDisplayedMnemonicIndex());
141 @Override
142 public void setDisplayedMnemonicIndex(final int index) throws IllegalArgumentException {
143 super.setDisplayedMnemonicIndex(myMnemonicEnabled ? index : -1);
146 public void setMnemonic(int mnemonic) {
147 super.setMnemonic(myMnemonicEnabled ? mnemonic : 0);
150 private void updateIcon() {
151 Presentation presentation = myPresentation;
152 Icon icon = presentation.getIcon();
153 setIcon(icon);
154 if (presentation.getDisabledIcon() != null) {
155 setDisabledIcon(presentation.getDisabledIcon());
157 else {
158 setDisabledIcon(IconLoader.getDisabledIcon(icon));
162 public void menuSelectionChanged(boolean isIncluded) {
163 super.menuSelectionChanged(isIncluded);
164 showDescriptionInStatusBar(isIncluded, this, myPresentation.getDescription());
167 public static void showDescriptionInStatusBar(boolean isIncluded, Component component, String description) {
168 IdeFrameImpl frame = component instanceof IdeFrameImpl ? (IdeFrameImpl)component :
169 (IdeFrameImpl)SwingUtilities.getAncestorOfClass(IdeFrameImpl.class, component);
170 if (frame != null) {
171 StatusBar statusBar = frame.getStatusBar();
172 if (isIncluded) {
173 statusBar.setInfo(description);
175 else {
176 statusBar.setInfo(null);
182 private class MenuListenerImpl implements MenuListener {
183 public void menuCanceled(MenuEvent e) {
184 clearItems();
185 addStubItem();
188 public void menuDeselected(MenuEvent e) {
189 clearItems();
190 addStubItem();
194 public void menuSelected(MenuEvent e) {
195 fillMenu();
199 private void clearItems() {
200 if (SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU) {
201 for (Component menuComponent : getMenuComponents()) {
202 if (menuComponent instanceof ActionMenu) {
203 ((ActionMenu)menuComponent).clearItems();
205 else if (menuComponent instanceof ActionMenuItem) {
206 ((ActionMenuItem)menuComponent).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F24, 0));
211 removeAll();
212 validate();
215 private void fillMenu() {
216 DataContext context = myContext != null ? myContext : DataManager.getInstance().getDataContext();
217 Utils.fillMenu(myGroup, this, myMnemonicEnabled, myPresentationFactory, context, myPlace, true);
220 private class MenuItemSynchronizer implements PropertyChangeListener {
221 public void propertyChange(PropertyChangeEvent e) {
222 String name = e.getPropertyName();
223 if (Presentation.PROP_VISIBLE.equals(name)) {
224 setVisible(myPresentation.isVisible());
225 if (SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU) {
226 validateTree();
229 else if (Presentation.PROP_ENABLED.equals(name)) {
230 setEnabled(myPresentation.isEnabled());
232 else if (Presentation.PROP_MNEMONIC_KEY.equals(name)) {
233 setMnemonic(myPresentation.getMnemonic());
235 else if (Presentation.PROP_MNEMONIC_INDEX.equals(name)) {
236 setDisplayedMnemonicIndex(myPresentation.getDisplayedMnemonicIndex());
238 else if (Presentation.PROP_TEXT.equals(name)) {
239 setText(myPresentation.getText());
241 else if (Presentation.PROP_ICON.equals(name) || Presentation.PROP_DISABLED_ICON.equals(name)) {
242 updateIcon();