mock filetype manager if no application allows running lexer suites.
[fedora-idea.git] / platform-api / src / com / intellij / ui / SearchTextField.java
blobae9709063fa1ca1ebc68cc9fc7894532dd091a7f
1 /*
2 * @author max
3 */
4 package com.intellij.ui;
6 import com.intellij.ide.ui.LafManager;
7 import com.intellij.openapi.actionSystem.ActionManager;
8 import com.intellij.openapi.actionSystem.AnAction;
9 import com.intellij.openapi.actionSystem.CommonShortcuts;
10 import com.intellij.openapi.actionSystem.IdeActions;
11 import com.intellij.openapi.ui.popup.JBPopup;
12 import com.intellij.openapi.ui.popup.JBPopupFactory;
13 import com.intellij.openapi.util.IconLoader;
14 import com.intellij.openapi.util.SystemInfo;
15 import com.intellij.util.ui.UIUtil;
17 import javax.swing.*;
18 import javax.swing.border.Border;
19 import javax.swing.border.CompoundBorder;
20 import javax.swing.event.DocumentListener;
21 import java.awt.*;
22 import java.awt.event.*;
23 import java.util.ArrayList;
25 public class SearchTextField extends JPanel {
26 private int myHistorySize = 5;
27 private final MyModel myModel;
28 private final TextFieldWithProcessing myTextField;
30 private JBPopup myPopup;
31 private JLabel myClearFieldLabel;
32 private JLabel myToggleHistoryLabel;
33 private JPopupMenu myNativeSearchPopup;
35 private KeyListener myListener = null;
36 private JMenuItem myNoItems;
38 public SearchTextField() {
39 this(true);
42 public SearchTextField(boolean historyEnabled) {
43 super(new BorderLayout());
45 myModel = new MyModel();
47 myTextField = new TextFieldWithProcessing() {
48 @Override
49 public void processKeyEvent(final KeyEvent e) {
50 if (preprocessEventForTextField(e)) return;
51 super.processKeyEvent(e);
54 @Override
55 public void setBackground(final Color bg) {
56 super.setBackground(bg);
57 if (myClearFieldLabel != null) {
58 myClearFieldLabel.setBackground(bg);
61 if (myToggleHistoryLabel != null) {
62 myToggleHistoryLabel.setBackground(bg);
66 myTextField.setColumns(15);
67 add(myTextField, BorderLayout.CENTER);
69 if (hasNativeLeopardSearchControl()) {
70 myTextField.putClientProperty("JTextField.variant", "search");
71 myNativeSearchPopup = new JPopupMenu();
72 myNoItems = new JMenuItem("No recent searches");
73 myNoItems.setEnabled(false);
75 updateMenu();
76 if (historyEnabled) {
77 myTextField.putClientProperty("JTextField.Search.FindPopup", myNativeSearchPopup);
80 else {
81 myToggleHistoryLabel = new JLabel(IconLoader.findIcon("/actions/search.png"));
82 myToggleHistoryLabel.setOpaque(true);
83 myToggleHistoryLabel.setBackground(myTextField.getBackground());
84 myToggleHistoryLabel.addMouseListener(new MouseAdapter() {
85 public void mousePressed(MouseEvent e) {
86 togglePopup();
88 });
89 if (historyEnabled) {
90 add(myToggleHistoryLabel, BorderLayout.WEST);
93 myClearFieldLabel = new JLabel(IconLoader.findIcon("/actions/cleanLight.png"));
94 myClearFieldLabel.setOpaque(true);
95 myClearFieldLabel.setBackground(myTextField.getBackground());
96 add(myClearFieldLabel, BorderLayout.EAST);
97 myClearFieldLabel.addMouseListener(new MouseAdapter() {
98 public void mousePressed(MouseEvent e) {
99 myTextField.setText("");
103 final Border originalBorder;
104 if (SystemInfo.isMac) {
105 originalBorder = BorderFactory.createLoweredBevelBorder();
107 else {
108 originalBorder = myTextField.getBorder();
111 setBorder(new CompoundBorder(IdeBorderFactory.createEmptyBorder(4, 0, 4, 0), originalBorder));
113 myTextField.setOpaque(true);
114 myTextField.setBorder(IdeBorderFactory.createEmptyBorder(0, 5, 0, 5));
117 final ActionManager actionManager = ActionManager.getInstance();
118 if (actionManager != null) {
119 final AnAction clearTextAction = actionManager.getAction(IdeActions.ACTION_CLEAR_TEXT);
120 if (clearTextAction.getShortcutSet().getShortcuts().length == 0) {
121 clearTextAction.registerCustomShortcutSet(CommonShortcuts.ESCAPE, this);
126 private void updateMenu() {
127 if (myNativeSearchPopup != null) {
128 myNativeSearchPopup.removeAll();
129 final int itemsCount = myModel.getSize();
130 if (itemsCount == 0) {
131 myNativeSearchPopup.add(myNoItems);
133 else {
134 for (int i = 0; i < itemsCount; i++) {
135 String item = (String)myModel.getElementAt(i);
136 addMenuItem(item);
142 private static boolean hasNativeLeopardSearchControl() {
143 return SystemInfo.isMacOSLeopard && LafManager.getInstance().isUnderAquaLookAndFeel();
146 public void addDocumentListener(DocumentListener listener) {
147 getTextEditor().getDocument().addDocumentListener(listener);
150 public void removeDocumentListener(DocumentListener listener) {
151 getTextEditor().getDocument().removeDocumentListener(listener);
154 public void addKeyboardListener(final KeyListener listener) {
155 getTextEditor().addKeyListener(listener);
158 public void setEnabled(boolean enabled) {
159 super.setEnabled(enabled);
160 if (myToggleHistoryLabel != null) {
161 final Color bg = enabled ? UIUtil.getTextFieldBackground() : UIUtil.getPanelBackground();
162 myToggleHistoryLabel.setBackground(bg);
163 myClearFieldLabel.setBackground(bg);
167 public void setHistorySize(int aHistorySize) {
168 myHistorySize = aHistorySize;
171 public void setHistory(java.util.List<String> aHistory) {
172 myModel.setItems(aHistory);
175 public java.util.List<String> getHistory() {
176 final int itemsCount = myModel.getSize();
177 java.util.List<String> history = new ArrayList<String>(itemsCount);
178 for (int i = 0; i < itemsCount; i++) {
179 history.add((String)myModel.getElementAt(i));
181 return history;
184 public void setText(String aText) {
185 getTextEditor().setText(aText);
188 public String getText() {
189 return getTextEditor().getText();
192 public void removeNotify() {
193 super.removeNotify();
194 hidePopup();
197 public void addCurrentTextToHistory() {
198 final String item = getText();
199 myModel.addElement(item);
202 private void addMenuItem(final String item) {
203 if (myNativeSearchPopup != null) {
204 myNativeSearchPopup.remove(myNoItems);
205 final JMenuItem menuItem = new JMenuItem(item);
206 myNativeSearchPopup.add(menuItem);
207 menuItem.addActionListener(new ActionListener() {
208 public void actionPerformed(final ActionEvent e) {
209 myTextField.setText(item);
215 public void selectText() {
216 getTextEditor().selectAll();
219 public JTextField getTextEditor() {
220 return myTextField;
223 public boolean requestFocusInWindow() {
224 return myTextField.requestFocusInWindow();
227 public void requestFocus() {
228 getTextEditor().requestFocus();
231 public class MyModel extends AbstractListModel {
232 private java.util.List<String> myFullList = new ArrayList<String>();
234 private Object mySelectedItem;
236 public Object getElementAt(int index) {
237 return myFullList.get(index);
240 public int getSize() {
241 return Math.min(myHistorySize, myFullList.size());
244 public void addElement(Object obj) {
245 String newItem = ((String)obj).trim();
247 if (0 == newItem.length()) {
248 return;
251 if (!contains(newItem)) {
252 insertElementAt(newItem, 0);
256 public void insertElementAt(Object obj, int index) {
257 myFullList.add(index, (String)obj);
258 fireContentsChanged();
261 public Object getSelectedItem() {
262 return mySelectedItem;
265 public void setSelectedItem(Object anItem) {
266 mySelectedItem = anItem;
269 public void fireContentsChanged() {
270 fireContentsChanged(this, -1, -1);
271 updateMenu();
274 public boolean contains(String aNewValue) {
275 return myFullList.contains(aNewValue);
278 public void setItems(java.util.List<String> aList) {
279 myFullList = new ArrayList<String>(aList);
280 fireContentsChanged();
284 private void hidePopup() {
285 if (myPopup != null) {
286 myPopup.cancel();
287 myPopup = null;
291 private void showPopup() {
292 if (myPopup == null) {
293 final JList list = new JList(myModel);
294 if (myListener != null) {
295 removeKeyListener(myListener);
297 final Runnable chooseRunnable = new Runnable() {
298 public void run() {
299 final String value = (String)list.getSelectedValue();
300 getTextEditor().setText(value != null ? value : "");
301 if (myPopup != null) {
302 myPopup.cancel();
303 myPopup = null;
307 myListener = new KeyAdapter() {
308 public void keyPressed(KeyEvent e) {
309 if (e.getKeyCode() == KeyEvent.VK_DOWN) {
310 if (list.getSelectedIndex() < list.getModel().getSize() - 1) {
311 list.setSelectedIndex(list.getSelectedIndex() + 1);
314 else if (e.getKeyCode() == KeyEvent.VK_UP) {
315 if (list.getSelectedIndex() > 0) {
316 list.setSelectedIndex(list.getSelectedIndex() - 1);
319 else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
320 if (list.getSelectedIndex() > -1) {
321 chooseRunnable.run();
326 addKeyboardListener(myListener);
327 myPopup = JBPopupFactory.getInstance().createListPopupBuilder(list)
328 .setMovable(false)
329 .setRequestFocus(false)
330 .setItemChoosenCallback(chooseRunnable).createPopup();
332 if (isShowing()) myPopup.showUnderneathOf(this);
336 private void togglePopup() {
337 if (myPopup == null) {
338 showPopup();
340 else {
341 hidePopup();
345 public void setSelectedItem(final String s) {
346 getTextEditor().setText(s);
349 public int getSelectedIndex() {
350 return myModel.myFullList.indexOf(getText());
353 protected static class TextFieldWithProcessing extends JTextField {
354 public void processKeyEvent(KeyEvent e) {
355 super.processKeyEvent(e);
359 public final void keyEventToTextField(KeyEvent e) {
360 myTextField.processKeyEvent(e);
363 protected boolean preprocessEventForTextField(KeyEvent e) {
364 return false;