extra fix for IDEA-139797 - focusable history button
[idea/community.git] / platform / xdebugger-impl / src / com / intellij / xdebugger / impl / evaluate / ExpressionInputComponent.java
1 /*
2  * Copyright 2000-2015 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.xdebugger.impl.evaluate;
17
18 import com.intellij.codeInsight.lookup.LookupManager;
19 import com.intellij.icons.AllIcons;
20 import com.intellij.openapi.actionSystem.AnAction;
21 import com.intellij.openapi.actionSystem.AnActionEvent;
22 import com.intellij.openapi.actionSystem.CustomShortcutSet;
23 import com.intellij.openapi.editor.ex.util.EditorUtil;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.ui.FixedSizeButton;
26 import com.intellij.openapi.ui.popup.PopupStep;
27 import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
28 import com.intellij.ui.ColoredListCellRenderer;
29 import com.intellij.ui.components.JBLabel;
30 import com.intellij.ui.popup.list.ListPopupImpl;
31 import com.intellij.util.ui.JBUI;
32 import com.intellij.util.ui.UIUtil;
33 import com.intellij.xdebugger.XDebuggerBundle;
34 import com.intellij.xdebugger.XExpression;
35 import com.intellij.xdebugger.XSourcePosition;
36 import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
37 import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
38 import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
39 import com.intellij.xdebugger.impl.ui.XDebuggerExpressionEditor;
40 import org.jetbrains.annotations.NotNull;
41 import org.jetbrains.annotations.Nullable;
42
43 import javax.swing.*;
44 import java.awt.*;
45 import java.awt.event.ActionEvent;
46 import java.awt.event.ActionListener;
47 import java.util.List;
48
49 /**
50  * @author nik
51  */
52 public class ExpressionInputComponent extends EvaluationInputComponent {
53   private final XDebuggerExpressionEditor myExpressionEditor;
54   private final JPanel myMainPanel;
55
56   public ExpressionInputComponent(final @NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, final @Nullable XSourcePosition sourcePosition,
57                                   @Nullable XExpression expression) {
58     super(XDebuggerBundle.message("xdebugger.dialog.title.evaluate.expression"));
59     myMainPanel = new JPanel(new BorderLayout());
60     //myMainPanel.add(new JLabel(XDebuggerBundle.message("xdebugger.evaluate.label.expression")), BorderLayout.WEST);
61     myExpressionEditor = new XDebuggerExpressionEditor(project, editorsProvider, "evaluateExpression", sourcePosition,
62                                                        expression != null ? expression : XExpressionImpl.EMPTY_EXPRESSION, false);
63     myMainPanel.add(myExpressionEditor.getComponent(), BorderLayout.CENTER);
64     JButton historyButton = new FixedSizeButton(myExpressionEditor.getComponent());
65     historyButton.setFocusable(true);
66     historyButton.setIcon(AllIcons.General.MessageHistory);
67     historyButton.setToolTipText(XDebuggerBundle.message("xdebugger.evaluate.history.hint"));
68     historyButton.addActionListener(new ActionListener() {
69       @Override
70       public void actionPerformed(ActionEvent e) {
71         showHistory();
72       }
73     });
74     myMainPanel.add(historyButton, BorderLayout.EAST);
75     final JBLabel help = new JBLabel(XDebuggerBundle.message("xdebugger.evaluate.addtowatches.hint"), SwingConstants.RIGHT);
76     help.setBorder(JBUI.Borders.empty(2, 0, 6, 0));
77     help.setComponentStyle(UIUtil.ComponentStyle.SMALL);
78     help.setFontColor(UIUtil.FontColor.BRIGHTER);
79     myMainPanel.add(help, BorderLayout.SOUTH);
80     if (expression != null) {
81       myExpressionEditor.setExpression(expression);
82     }
83     myExpressionEditor.selectAll();
84
85     new AnAction("XEvaluateDialog.ShowHistory") {
86       @Override
87       public void actionPerformed(AnActionEvent e) {
88         showHistory();
89       }
90
91       @Override
92       public void update(AnActionEvent e) {
93         e.getPresentation().setEnabled(LookupManager.getActiveLookup(myExpressionEditor.getEditor()) == null);
94       }
95     }.registerCustomShortcutSet(CustomShortcutSet.fromString("DOWN"), myMainPanel);
96   }
97
98   private void showHistory() {
99     List<XExpression> expressions = myExpressionEditor.getRecentExpressions();
100     if (!expressions.isEmpty()) {
101       ListPopupImpl popup = new ListPopupImpl(new BaseListPopupStep<XExpression>(null, expressions) {
102         @Override
103         public PopupStep onChosen(XExpression selectedValue, boolean finalChoice) {
104           myExpressionEditor.setExpression(selectedValue);
105           myExpressionEditor.requestFocusInEditor();
106           return FINAL_CHOICE;
107         }
108       }) {
109         @Override
110         protected ListCellRenderer getListElementRenderer() {
111           return new ColoredListCellRenderer<XExpression>() {
112             @Override
113             protected void customizeCellRenderer(JList list, XExpression value, int index, boolean selected, boolean hasFocus) {
114               append(value.getExpression());
115             }
116           };
117         }
118       };
119       popup.getList().setFont(EditorUtil.getEditorFont());
120       popup.showUnderneathOf(myExpressionEditor.getEditorComponent());
121     }
122   }
123
124   @Override
125   public void addComponent(JPanel contentPanel, JPanel resultPanel) {
126     contentPanel.add(resultPanel, BorderLayout.CENTER);
127     contentPanel.add(myMainPanel, BorderLayout.NORTH);
128   }
129
130   @NotNull
131   protected XDebuggerEditorBase getInputEditor() {
132     return myExpressionEditor;
133   }
134 }