call addCurrentTextToHistory() directly because it can be overridden (IDEA-CR-3607)
[idea/community.git] / platform / platform-api / src / com / intellij / ui / TextFieldWithHistory.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.ui;
17
18 import com.intellij.openapi.fileChooser.FileTextField;
19 import com.intellij.openapi.ui.ComboBox;
20
21 import javax.swing.*;
22 import javax.swing.event.DocumentListener;
23 import java.awt.event.KeyEvent;
24 import java.awt.event.KeyListener;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 public class TextFieldWithHistory extends ComboBox {
29   private int myHistorySize = 5;
30   private final MyModel myModel;
31
32   public TextFieldWithHistory() {
33     myModel = new MyModel();
34     setModel(myModel);
35     setEditable(true);
36   }
37
38   // API compatibility with 7.0.1
39   @SuppressWarnings({"UnusedDeclaration"})
40   public TextFieldWithHistory(boolean cropList) {
41     this();
42   }
43
44   public void addDocumentListener(DocumentListener listener) {
45     getTextEditor().getDocument().addDocumentListener(listener);
46   }
47
48   public void removeDocumentListener(DocumentListener listener) {
49     getTextEditor().getDocument().removeDocumentListener(listener);
50   }
51
52   public void addKeyboardListener(final KeyListener listener) {
53     getTextEditor().addKeyListener(listener);
54   }
55
56   /**
57    * @param aHistorySize -1 means unbounded
58    */
59   public void setHistorySize(int aHistorySize) {
60     myHistorySize = aHistorySize;
61   }
62
63   public void setHistory(List<String> aHistory) {
64     myModel.setItems(aHistory);
65   }
66
67   public List<String> getHistory() {
68     final int itemsCount = myModel.getSize();
69     List<String> history = new ArrayList<String>(itemsCount);
70     for (int i = 0; i < itemsCount; i++) {
71       history.add((String)myModel.getElementAt(i));
72     }
73     return history;
74   }
75
76   public void setText(String aText) {
77     getTextEditor().setText(aText);
78   }
79
80   public String getText() {
81     return getTextEditor().getText();
82   }
83
84   public void removeNotify() {
85     super.removeNotify();
86     hidePopup();
87   }
88
89   public void setTextAndAddToHistory(String text) {
90     setText(text);
91     addCurrentTextToHistory();
92   }
93
94   public void addCurrentTextToHistory() {
95     final String item = getText();
96     myModel.addElement(item);
97   }
98
99   public void selectText() {
100     getTextEditor().selectAll();
101   }
102
103   public JTextField getTextEditor() {
104     return (JTextField)getEditor().getEditorComponent();
105   }
106
107   @Override
108   public void setPopupVisible(boolean v) {
109     if (v) {
110       final FileTextField fileTextField = (FileTextField)getTextEditor().getClientProperty(FileTextField.KEY);
111       // don't allow showing combobox popup when file completion popup is displayed (IDEA-68711)
112       if (fileTextField != null && fileTextField.isPopupDisplayed()) {
113         return;
114       }
115     }
116     super.setPopupVisible(v);
117   }
118
119   public class MyModel extends AbstractListModel implements ComboBoxModel{
120     private List<String> myFullList = new ArrayList<String>();
121
122     private Object mySelectedItem;
123
124     public Object getElementAt(int index) {
125       return myFullList.get(index);
126     }
127
128     public int getSize() {
129       return Math.min(myHistorySize == -1 ? Integer.MAX_VALUE : myHistorySize, myFullList.size());
130     }
131
132     public void addElement(Object obj) {
133       String newItem = ((String)obj).trim();
134
135       if (0 == newItem.length()) {
136         return;
137       }
138
139       if (!contains(newItem)) {
140         // set newly added item as selected.
141         // otherwise current selection will be set to editor
142         mySelectedItem = newItem;
143         insertElementAt(newItem, 0);
144       }
145     }
146
147     public void insertElementAt(Object obj, int index) {
148       myFullList.add(index, (String)obj);
149       fireContentsChanged();
150     }
151
152     public Object getSelectedItem() {
153       return mySelectedItem;
154     }
155
156     public void setSelectedItem(Object anItem) {
157       mySelectedItem = anItem;
158       fireContentsChanged();
159     }
160
161     public void fireContentsChanged() {
162       fireContentsChanged(this, -1, -1);
163     }
164
165     public boolean contains(String aNewValue) {
166       return myFullList.contains(aNewValue);
167     }
168
169     public void setItems(List<String> aList) {
170       myFullList = new ArrayList<String>(aList);
171       fireContentsChanged();
172     }
173   }
174
175   protected static class TextFieldWithProcessing extends JTextField {
176     public void processKeyEvent(KeyEvent e) {
177       super.processKeyEvent(e);
178     }
179   }
180 }