ea4ea5d4f37b58b391356ab42d1e106438fbe2b3
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / actionSystem / impl / ActionMenu.java
blobea4ea5d4f37b58b391356ab42d1e106438fbe2b3
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 final 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 addNotify() {
74 super.addNotify();
75 installSynchronizer();
78 private void installSynchronizer() {
79 if (myMenuItemSynchronizer == null) {
80 myMenuItemSynchronizer = new MenuItemSynchronizer();
81 myGroup.addPropertyChangeListener(myMenuItemSynchronizer);
82 myPresentation.addPropertyChangeListener(myMenuItemSynchronizer);
86 public void removeNotify() {
87 if (myMenuItemSynchronizer != null) {
88 myGroup.removePropertyChangeListener(myMenuItemSynchronizer);
89 myPresentation.removePropertyChangeListener(myMenuItemSynchronizer);
90 myMenuItemSynchronizer = null;
92 super.removeNotify();
95 public void updateUI() {
96 JPopupMenu popupMenu = getPopupMenu();
97 if (popupMenu != null) {
98 popupMenu.updateUI();
100 if (UIUtil.isStandardMenuLAF()) {
101 setUI((MenuItemUI)UIManager.getUI(this));
103 else {
104 setUI(IdeaMenuUI.createUI(this));
105 setFont(UIUtil.getMenuFont());
109 private void init() {
110 boolean macSystemMenu = SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU;
112 myStubItem = macSystemMenu ? null : new StubItem();
113 addStubItem();
114 addMenuListener(new MenuListenerImpl());
115 setBorderPainted(false);
117 setVisible(myPresentation.isVisible());
118 setEnabled(myPresentation.isEnabled());
119 setText(myPresentation.getText());
120 updateIcon();
122 setMnemonicEnabled(myMnemonicEnabled);
125 private void addStubItem() {
126 if (myStubItem != null) {
127 add(myStubItem);
131 public void setMnemonicEnabled(boolean enable) {
132 myMnemonicEnabled = enable;
133 setMnemonic(myPresentation.getMnemonic());
134 setDisplayedMnemonicIndex(myPresentation.getDisplayedMnemonicIndex());
137 @Override
138 public void setDisplayedMnemonicIndex(final int index) throws IllegalArgumentException {
139 super.setDisplayedMnemonicIndex(myMnemonicEnabled ? index : -1);
142 public void setMnemonic(int mnemonic) {
143 super.setMnemonic(myMnemonicEnabled ? mnemonic : 0);
146 private void updateIcon() {
147 Presentation presentation = myPresentation;
148 Icon icon = presentation.getIcon();
149 setIcon(icon);
150 if (presentation.getDisabledIcon() != null) {
151 setDisabledIcon(presentation.getDisabledIcon());
153 else {
154 setDisabledIcon(IconLoader.getDisabledIcon(icon));
158 public void menuSelectionChanged(boolean isIncluded) {
159 super.menuSelectionChanged(isIncluded);
160 showDescriptionInStatusBar(isIncluded, this, myPresentation.getDescription());
163 public static void showDescriptionInStatusBar(boolean isIncluded, Component component, String description) {
164 IdeFrameImpl frame = component instanceof IdeFrameImpl ? (IdeFrameImpl)component :
165 (IdeFrameImpl)SwingUtilities.getAncestorOfClass(IdeFrameImpl.class, component);
166 if (frame != null) {
167 StatusBar statusBar = frame.getStatusBar();
168 if (isIncluded) {
169 statusBar.setInfo(description);
171 else {
172 statusBar.setInfo(null);
177 private class MenuListenerImpl implements MenuListener {
178 public void menuCanceled(MenuEvent e) {
179 clearItems();
180 addStubItem();
183 public void menuDeselected(MenuEvent e) {
184 clearItems();
185 addStubItem();
189 public void menuSelected(MenuEvent e) {
190 fillMenu();
194 private void clearItems() {
195 if (SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU) {
196 for (Component menuComponent : getMenuComponents()) {
197 if (menuComponent instanceof ActionMenu) {
198 ((ActionMenu)menuComponent).clearItems();
200 else if (menuComponent instanceof ActionMenuItem) {
201 ((ActionMenuItem)menuComponent).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F24, 0));
206 removeAll();
207 validate();
210 private void fillMenu() {
211 DataContext context = myContext != null ? myContext : DataManager.getInstance().getDataContext();
212 Utils.fillMenu(myGroup, this, myMnemonicEnabled, myPresentationFactory, context, myPlace, true);
215 private class MenuItemSynchronizer implements PropertyChangeListener {
216 public void propertyChange(PropertyChangeEvent e) {
217 String name = e.getPropertyName();
218 if (Presentation.PROP_VISIBLE.equals(name)) {
219 setVisible(myPresentation.isVisible());
220 if (SystemInfo.isMacSystemMenu && myPlace == ActionPlaces.MAIN_MENU) {
221 validateTree();
224 else if (Presentation.PROP_ENABLED.equals(name)) {
225 setEnabled(myPresentation.isEnabled());
227 else if (Presentation.PROP_MNEMONIC_KEY.equals(name)) {
228 setMnemonic(myPresentation.getMnemonic());
230 else if (Presentation.PROP_MNEMONIC_INDEX.equals(name)) {
231 setDisplayedMnemonicIndex(myPresentation.getDisplayedMnemonicIndex());
233 else if (Presentation.PROP_TEXT.equals(name)) {
234 setText(myPresentation.getText());
236 else if (Presentation.PROP_ICON.equals(name) || Presentation.PROP_DISABLED_ICON.equals(name)) {
237 updateIcon();