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.
17 package com.intellij.ide.actions;
19 import com.intellij.featureStatistics.FeatureUsageTracker;
20 import com.intellij.ide.DataManager;
21 import com.intellij.ide.ui.search.BooleanOptionDescription;
22 import com.intellij.ide.ui.search.OptionDescription;
23 import com.intellij.ide.util.gotoByName.ChooseByNamePopup;
24 import com.intellij.ide.util.gotoByName.GotoActionItemProvider;
25 import com.intellij.ide.util.gotoByName.GotoActionModel;
26 import com.intellij.openapi.Disposable;
27 import com.intellij.openapi.actionSystem.*;
28 import com.intellij.openapi.actionSystem.ex.ActionUtil;
29 import com.intellij.openapi.application.ApplicationManager;
30 import com.intellij.openapi.application.ModalityState;
31 import com.intellij.openapi.editor.Editor;
32 import com.intellij.openapi.keymap.KeymapUtil;
33 import com.intellij.openapi.progress.util.ProgressWindow;
34 import com.intellij.openapi.project.DumbAware;
35 import com.intellij.openapi.project.Project;
36 import com.intellij.openapi.ui.popup.JBPopupFactory;
37 import com.intellij.openapi.ui.popup.ListPopup;
38 import com.intellij.openapi.util.Disposer;
39 import com.intellij.openapi.util.Pair;
40 import com.intellij.psi.PsiFile;
41 import org.jetbrains.annotations.NotNull;
42 import org.jetbrains.annotations.Nullable;
45 import javax.swing.event.ListSelectionEvent;
46 import javax.swing.event.ListSelectionListener;
48 import java.awt.event.InputEvent;
49 import java.awt.event.KeyEvent;
50 import java.awt.event.MouseAdapter;
51 import java.awt.event.MouseEvent;
54 public class GotoActionAction extends GotoActionBase implements DumbAware {
57 public void gotoActionPerformed(@NotNull final AnActionEvent e) {
58 final Project project = e.getData(CommonDataKeys.PROJECT);
59 final Component component = e.getData(PlatformDataKeys.CONTEXT_COMPONENT);
60 Editor editor = e.getData(CommonDataKeys.EDITOR);
61 PsiFile file = e.getData(CommonDataKeys.PSI_FILE);
63 FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.action");
64 GotoActionModel model = new GotoActionModel(project, component, editor, file);
65 GotoActionCallback<Object> callback = new GotoActionCallback<Object>() {
67 public void elementChosen(@NotNull ChooseByNamePopup popup, @NotNull Object element) {
68 String enteredText = popup.getTrimmedText();
69 openOptionOrPerformAction(((GotoActionModel.MatchedValue)element).value, enteredText, project, component, e);
73 Pair<String, Integer> start = getInitialText(false, e);
74 showNavigationPopup(callback, null, createPopup(project, model, start.first, start.second, component, e), false);
78 private static ChooseByNamePopup createPopup(@Nullable Project project,
79 @NotNull final GotoActionModel model,
82 final Component component,
83 final AnActionEvent e) {
84 ChooseByNamePopup oldPopup = project == null ? null : project.getUserData(ChooseByNamePopup.CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY);
85 if (oldPopup != null) {
86 oldPopup.close(false);
88 final ChooseByNamePopup popup = new ChooseByNamePopup(project, model, new GotoActionItemProvider(model), oldPopup, initialText, false, initialIndex) {
90 protected void initUI(Callback callback, ModalityState modalityState, boolean allowMultipleSelection) {
91 super.initUI(callback, modalityState, allowMultipleSelection);
92 myList.addListSelectionListener(new ListSelectionListener() {
94 public void valueChanged(ListSelectionEvent e) {
95 Object value = myList.getSelectedValue();
96 String text = getText(value);
97 if (text != null && myDropdownPopup != null) {
98 myDropdownPopup.setAdText(text, SwingConstants.LEFT);
103 private String getText(@Nullable Object o) {
104 if (o instanceof GotoActionModel.MatchedValue) {
105 GotoActionModel.MatchedValue mv = (GotoActionModel.MatchedValue)o;
106 if (mv.value instanceof BooleanOptionDescription ||
107 mv.value instanceof GotoActionModel.ActionWrapper && ((GotoActionModel.ActionWrapper)mv.value).getAction() instanceof ToggleAction) {
108 return "Press " + KeymapUtil.getKeystrokeText(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)) + " to toggle option";
118 protected Set<Object> filter(@NotNull Set<Object> elements) {
119 return super.filter(model.sort(elements));
123 protected boolean closeForbidden(boolean ok) {
124 if (!ok) return false;
125 Object element = getChosenElement();
126 return element instanceof GotoActionModel.MatchedValue && processOptionInplace(((GotoActionModel.MatchedValue)element).value, this, component, e)
127 || super.closeForbidden(true);
131 ApplicationManager.getApplication().getMessageBus().connect().subscribe(ProgressWindow.TOPIC, new ProgressWindow.Listener() {
133 public void created(ProgressWindow pw) {
134 Disposer.register(pw, new Disposable() {
136 public void dispose() {
137 if (!popup.checkDisposed()) {
145 if (project != null) {
146 project.putUserData(ChooseByNamePopup.CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY, popup);
148 popup.addMouseClickListener(new MouseAdapter() {
150 public void mouseClicked(@NotNull MouseEvent me) {
151 Object element = popup.getSelectionByPoint(me.getPoint());
152 if (element instanceof GotoActionModel.MatchedValue) {
153 if (processOptionInplace(((GotoActionModel.MatchedValue)element).value, popup, component, e)) {
162 private static boolean processOptionInplace(Object value, ChooseByNamePopup popup, Component component, AnActionEvent e) {
163 if (value instanceof BooleanOptionDescription) {
164 BooleanOptionDescription option = (BooleanOptionDescription)value;
165 option.setOptionState(!option.isOptionEnabled());
169 else if (value instanceof GotoActionModel.ActionWrapper) {
170 AnAction action = ((GotoActionModel.ActionWrapper)value).getAction();
171 if (action instanceof ToggleAction) {
172 performAction(action, component, e);
180 private static void repaint(@Nullable ChooseByNamePopup popup) {
186 public static void openOptionOrPerformAction(@NotNull Object element,
187 final String enteredText,
188 final Project project,
190 @Nullable AnActionEvent e) {
191 if (element instanceof OptionDescription) {
192 final String configurableId = ((OptionDescription)element).getConfigurableId();
193 ApplicationManager.getApplication().invokeLater(new Runnable() {
196 ShowSettingsUtilImpl.showSettingsDialog(project, configurableId, enteredText);
201 performAction(element, component, e);
205 public static void performAction(Object element, @Nullable final Component component, @Nullable final AnActionEvent e) {
206 // element could be AnAction (SearchEverywhere)
207 final AnAction action = element instanceof AnAction ? (AnAction)element : ((GotoActionModel.ActionWrapper)element).getAction();
208 if (action != null) {
209 ApplicationManager.getApplication().invokeLater(new Runnable() {
212 if (component == null) return;
213 DataManager instance = DataManager.getInstance();
214 DataContext context = instance != null ? instance.getDataContext(component) : DataContext.EMPTY_CONTEXT;
215 InputEvent inputEvent = e == null ? null : e.getInputEvent();
216 AnActionEvent event = AnActionEvent.createFromAnAction(action, inputEvent, ActionPlaces.ACTION_SEARCH, context);
218 if (ActionUtil.lastUpdateAndCheckDumb(action, event, false)) {
219 if (action instanceof ActionGroup && ((ActionGroup)action).getChildren(event).length > 0) {
220 ListPopup popup = JBPopupFactory.getInstance().createActionGroupPopup(
221 event.getPresentation().getText(), (ActionGroup)action, context, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false);
222 Window window = SwingUtilities.getWindowAncestor(component);
223 if (window != null) {
224 popup.showInCenterOf(window);
227 popup.showInFocusCenter();
231 ActionUtil.performActionDumbAware(action, event);
235 }, ModalityState.NON_MODAL);
240 protected boolean requiresProject() {