d1f6ecd3c4f4b57560f15b88155ea5804881a5cd
[idea/community.git] / platform / platform-impl / src / com / intellij / openapi / wm / impl / welcomeScreen / WelcomePopupAction.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.openapi.wm.impl.welcomeScreen;
17
18 import com.intellij.openapi.actionSystem.*;
19 import com.intellij.openapi.project.DumbAware;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.ui.popup.JBPopupFactory;
22 import com.intellij.openapi.ui.popup.ListPopup;
23 import com.intellij.openapi.wm.ex.WindowManagerEx;
24
25 import javax.swing.*;
26 import java.awt.*;
27 import java.awt.event.InputEvent;
28 import java.awt.event.MouseEvent;
29
30 /**
31  * @author Vladislav.Kaznacheev
32  */
33 public abstract class WelcomePopupAction extends AnAction implements DumbAware {
34
35   protected abstract void fillActions(DefaultActionGroup group);
36
37   protected abstract String getTextForEmpty();
38
39   protected abstract String getCaption();
40
41   /**
42    * When there is only one option to choose from, this method is called to determine whether
43    * the popup should still be shown or that the option should be chosen silently.
44    *
45    * @return true to choose single option silently
46    *         false otherwise
47    */
48   protected abstract boolean isSilentlyChooseSingleOption();
49
50   public void actionPerformed(final AnActionEvent e) {
51     showPopup(e);
52   }
53
54   private void showPopup(final AnActionEvent e) {
55     final DefaultActionGroup group = new DefaultActionGroup();
56     fillActions(group);
57
58     if (group.getChildrenCount() == 1 && isSilentlyChooseSingleOption()) {
59       final AnAction[] children = group.getChildren(null);
60       children[0].actionPerformed(e);
61       return;
62     }
63
64
65     if (group.getChildrenCount() == 0) {
66       group.add(new AnAction(getTextForEmpty()) {
67         public void actionPerformed(AnActionEvent e) {
68           group.setPopup(false);
69         }
70       } );
71     }
72
73     final DataContext context = e.getDataContext();
74     final ListPopup popup = JBPopupFactory.getInstance()
75       .createActionGroupPopup(getCaption(),
76                               group,
77                               context,
78                               JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
79                               true);
80
81     JComponent contextComponent = null;
82     InputEvent inputEvent = e.getInputEvent();
83     if (inputEvent instanceof MouseEvent) {
84       if (inputEvent.getSource() instanceof JComponent) {
85         contextComponent = (JComponent)inputEvent.getSource();
86       }
87     }
88
89     showPopup(context, popup, contextComponent);
90   }
91
92   protected void showPopup(DataContext context, ListPopup popup, JComponent contextComponent) {
93     Component focusedComponent = contextComponent != null ? contextComponent : PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
94     if (focusedComponent != null) {
95       popup.showUnderneathOf(focusedComponent);
96     }
97     else {
98       Rectangle r;
99       int x;
100       int y;
101       focusedComponent = WindowManagerEx.getInstanceEx().getFocusedComponent((Project)null);
102       r = WindowManagerEx.getInstanceEx().getScreenBounds();
103       x = r.x + r.width / 2;
104       y = r.y + r.height / 2;
105       Point point = new Point(x, y);
106       SwingUtilities.convertPointToScreen(point, focusedComponent.getParent());
107
108       popup.showInScreenCoordinates(focusedComponent.getParent(), point);
109     }
110   }
111 }