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
;
31 import javax
.swing
.event
.MenuEvent
;
32 import javax
.swing
.event
.MenuListener
;
33 import javax
.swing
.plaf
.MenuItemUI
;
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
;
46 * Defines whether menu shows its mnemonic or not.
48 private boolean myMnemonicEnabled
;
49 private MenuItemSynchronizer myMenuItemSynchronizer
;
52 * Do not remove this STUPID code. Otherwise you will lose all keyboard navigation
55 private StubItem myStubItem
;
57 public ActionMenu(DataContext context
, String place
, ActionGroup group
, PresentationFactory presentationFactory
, final boolean enableMnemonics
) {
61 myPresentationFactory
= presentationFactory
;
62 myPresentation
= myPresentationFactory
.getPresentation(group
);
63 myMnemonicEnabled
= enableMnemonics
;
67 // addNotify won't be called for menus in MacOS system menu
68 if (SystemInfo
.isMacSystemMenu
) {
69 installSynchronizer();
73 public void 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;
95 public void updateUI() {
96 JPopupMenu popupMenu
= getPopupMenu();
97 if (popupMenu
!= null) {
100 if (UIUtil
.isStandardMenuLAF()) {
101 setUI((MenuItemUI
)UIManager
.getUI(this));
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();
114 addMenuListener(new MenuListenerImpl());
115 setBorderPainted(false);
117 setVisible(myPresentation
.isVisible());
118 setEnabled(myPresentation
.isEnabled());
119 setText(myPresentation
.getText());
122 setMnemonicEnabled(myMnemonicEnabled
);
125 private void addStubItem() {
126 if (myStubItem
!= null) {
131 public void setMnemonicEnabled(boolean enable
) {
132 myMnemonicEnabled
= enable
;
133 setMnemonic(myPresentation
.getMnemonic());
134 setDisplayedMnemonicIndex(myPresentation
.getDisplayedMnemonicIndex());
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();
150 if (presentation
.getDisabledIcon() != null) {
151 setDisabledIcon(presentation
.getDisabledIcon());
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
);
167 StatusBar statusBar
= frame
.getStatusBar();
169 statusBar
.setInfo(description
);
172 statusBar
.setInfo(null);
177 private class MenuListenerImpl
implements MenuListener
{
178 public void menuCanceled(MenuEvent e
) {
183 public void menuDeselected(MenuEvent e
) {
189 public void menuSelected(MenuEvent e
) {
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));
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
) {
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
)) {