PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/platform/platform-impl/src/com/intellij/ui/EditorComboBox.java

http://github.com/JetBrains/intellij-community
Java | 340 lines | 287 code | 52 blank | 1 comment | 52 complexity | 31fbb8d3bf548f7109b9b20f4e0854e9 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, MPL-2.0-no-copyleft-exception, MIT, EPL-1.0, AGPL-1.0
  1. // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
  2. package com.intellij.ui;
  3. import com.intellij.openapi.application.ApplicationManager;
  4. import com.intellij.openapi.command.CommandProcessor;
  5. import com.intellij.openapi.editor.CaretModel;
  6. import com.intellij.openapi.editor.Document;
  7. import com.intellij.openapi.editor.Editor;
  8. import com.intellij.openapi.editor.EditorFactory;
  9. import com.intellij.openapi.editor.event.DocumentEvent;
  10. import com.intellij.openapi.editor.event.DocumentListener;
  11. import com.intellij.openapi.editor.ex.EditorEx;
  12. import com.intellij.openapi.fileTypes.FileType;
  13. import com.intellij.openapi.fileTypes.FileTypes;
  14. import com.intellij.openapi.project.Project;
  15. import com.intellij.openapi.ui.ComboBox;
  16. import com.intellij.openapi.ui.TextComponentAccessor;
  17. import com.intellij.util.ArrayUtil;
  18. import com.intellij.util.containers.ContainerUtil;
  19. import com.intellij.util.ui.JBInsets;
  20. import com.intellij.util.ui.StartupUiUtil;
  21. import com.intellij.util.ui.UIUtil;
  22. import org.jetbrains.annotations.NotNull;
  23. import javax.swing.*;
  24. import java.awt.*;
  25. import java.awt.event.*;
  26. import java.util.ArrayList;
  27. import java.util.List;
  28. public class EditorComboBox extends ComboBox implements DocumentListener {
  29. public static TextComponentAccessor<EditorComboBox> COMPONENT_ACCESSOR = new TextComponentAccessor<EditorComboBox>() {
  30. @Override
  31. public String getText(EditorComboBox component) {
  32. return component.getText();
  33. }
  34. @Override
  35. public void setText(EditorComboBox component, @NotNull String text) {
  36. component.setText(text);
  37. }
  38. };
  39. private Document myDocument;
  40. private final Project myProject;
  41. private EditorTextField myEditorField = null;
  42. private final List<DocumentListener> myDocumentListeners = ContainerUtil.createLockFreeCopyOnWriteList();
  43. private boolean myIsListenerInstalled = false;
  44. private boolean myInheritSwingFont = true;
  45. private final FileType myFileType;
  46. private final boolean myIsViewer;
  47. public EditorComboBox(String text) {
  48. this(EditorFactory.getInstance().createDocument(text), null, FileTypes.PLAIN_TEXT);
  49. }
  50. public EditorComboBox(String text, Project project, FileType fileType) {
  51. this(EditorFactory.getInstance().createDocument(text), project, fileType, false);
  52. }
  53. public EditorComboBox(Document document, Project project, FileType fileType) {
  54. this(document, project, fileType, false);
  55. }
  56. public EditorComboBox(Document document, Project project, FileType fileType, boolean isViewer) {
  57. myFileType = fileType;
  58. myIsViewer = isViewer;
  59. setDocument(document);
  60. myProject = project;
  61. enableEvents(AWTEvent.KEY_EVENT_MASK);
  62. addActionListener(new ActionListener() {
  63. @Override
  64. public void actionPerformed(ActionEvent e) {
  65. final Editor editor = myEditorField != null ? myEditorField.getEditor() : null;
  66. if (editor != null) {
  67. editor.getSelectionModel().removeSelection();
  68. }
  69. }
  70. });
  71. setHistory(new String[]{""});
  72. setEditable(true);
  73. }
  74. public void setFontInheritedFromLAF(boolean b) {
  75. myInheritSwingFont = b;
  76. setDocument(myDocument); // reinit editor.
  77. }
  78. public String getText() {
  79. return myDocument.getText();
  80. }
  81. public void addDocumentListener(DocumentListener listener) {
  82. myDocumentListeners.add(listener);
  83. installDocumentListener();
  84. }
  85. public void removeDocumentListener(DocumentListener listener) {
  86. myDocumentListeners.remove(listener);
  87. uninstallDocumentListener(false);
  88. }
  89. @Override
  90. public void beforeDocumentChange(@NotNull DocumentEvent event) {
  91. for (DocumentListener documentListener : myDocumentListeners) {
  92. documentListener.beforeDocumentChange(event);
  93. }
  94. }
  95. @Override
  96. public void documentChanged(@NotNull DocumentEvent event) {
  97. for (DocumentListener documentListener : myDocumentListeners) {
  98. documentListener.documentChanged(event);
  99. }
  100. }
  101. public Project getProject() {
  102. return myProject;
  103. }
  104. public Document getDocument() {
  105. return myDocument;
  106. }
  107. public void setDocument(Document document) {
  108. if (myDocument != null) {
  109. uninstallDocumentListener(true);
  110. }
  111. myDocument = document;
  112. installDocumentListener();
  113. if (myEditorField == null) return;
  114. myEditorField.setDocument(document);
  115. }
  116. private void installDocumentListener() {
  117. if (myDocument != null && !myDocumentListeners.isEmpty() && !myIsListenerInstalled) {
  118. myIsListenerInstalled = true;
  119. myDocument.addDocumentListener(this);
  120. }
  121. }
  122. private void uninstallDocumentListener(boolean force) {
  123. if (myDocument != null && myIsListenerInstalled && (force || myDocumentListeners.isEmpty())) {
  124. myIsListenerInstalled = false;
  125. myDocument.removeDocumentListener(this);
  126. }
  127. }
  128. public void setText(final String text) {
  129. ApplicationManager.getApplication().runWriteAction(() -> CommandProcessor.getInstance().executeCommand(getProject(), () -> {
  130. myDocument.replaceString(0, myDocument.getTextLength(), text);
  131. if (myEditorField != null && myEditorField.getEditor() != null) {
  132. myEditorField.getCaretModel().moveToOffset(myDocument.getTextLength());
  133. }
  134. }, null, myDocument));
  135. }
  136. public void removeSelection() {
  137. if (myEditorField != null) {
  138. final Editor editor = myEditorField.getEditor();
  139. if (editor != null) {
  140. editor.getSelectionModel().removeSelection();
  141. }
  142. }
  143. }
  144. public CaretModel getCaretModel() {
  145. return myEditorField.getCaretModel();
  146. }
  147. public void setHistory(final String[] history) {
  148. setModel(new DefaultComboBoxModel(history));
  149. }
  150. public void prependItem(String item) {
  151. ArrayList<Object> objects = new ArrayList<>();
  152. objects.add(item);
  153. int count = getItemCount();
  154. for (int i = 0; i < count; i++) {
  155. final Object itemAt = getItemAt(i);
  156. if (!item.equals(itemAt)) {
  157. objects.add(itemAt);
  158. }
  159. }
  160. setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(objects)));
  161. }
  162. public void appendItem(String item) {
  163. ArrayList<Object> objects = new ArrayList<>();
  164. int count = getItemCount();
  165. for (int i = 0; i < count; i++) {
  166. objects.add(getItemAt(i));
  167. }
  168. if (!objects.contains(item)) {
  169. objects.add(item);
  170. }
  171. setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(objects)));
  172. }
  173. private class MyEditor implements ComboBoxEditor {
  174. @Override
  175. public void addActionListener(ActionListener l) {
  176. }
  177. @Override
  178. public Component getEditorComponent() {
  179. return myEditorField;
  180. }
  181. @Override
  182. public Object getItem() {
  183. return myDocument.getText();
  184. }
  185. @Override
  186. public void removeActionListener(ActionListener l) {
  187. }
  188. @Override
  189. public void selectAll() {
  190. if (myEditorField != null) {
  191. final Editor editor = myEditorField.getEditor();
  192. if (editor != null) {
  193. editor.getSelectionModel().setSelection(0, myDocument.getTextLength());
  194. }
  195. }
  196. }
  197. @Override
  198. public void setItem(Object anObject) {
  199. if (anObject != null) {
  200. EditorComboBox.this.setText(anObject.toString());
  201. } else {
  202. EditorComboBox.this.setText("");
  203. }
  204. }
  205. }
  206. @Override
  207. public void addNotify() {
  208. releaseEditor();
  209. setEditor();
  210. super.addNotify();
  211. myEditorField.getFocusTarget().addFocusListener(new FocusAdapter() {
  212. @Override
  213. public void focusGained(FocusEvent e) {
  214. EditorComboBox.this.repaint();
  215. }
  216. @Override
  217. public void focusLost(FocusEvent e) {
  218. EditorComboBox.this.repaint();
  219. }
  220. });
  221. }
  222. private void setEditor() {
  223. myEditorField = createEditorTextField(myDocument, myProject, myFileType, myIsViewer);
  224. final ComboBoxEditor editor = new MyEditor();
  225. setEditor(editor);
  226. setRenderer(new EditorComboBoxRenderer(editor));
  227. }
  228. protected ComboboxEditorTextField createEditorTextField(Document document, Project project, FileType fileType, boolean isViewer) {
  229. return new ComboboxEditorTextField(document, project, fileType, isViewer);
  230. }
  231. @Override
  232. public void removeNotify() {
  233. super.removeNotify();
  234. releaseEditor();
  235. myEditorField = null;
  236. }
  237. private void releaseEditor() {
  238. if (myEditorField != null) {
  239. myEditorField.releaseEditorLater();
  240. }
  241. }
  242. @Override
  243. public void setFont(Font font) {
  244. super.setFont(font);
  245. if (myEditorField != null && myEditorField.getEditor() != null) {
  246. setupEditorFont((EditorEx)myEditorField.getEditor());
  247. }
  248. }
  249. private void setupEditorFont(final EditorEx editor) {
  250. if (myInheritSwingFont) {
  251. editor.getColorsScheme().setEditorFontName(getFont().getFontName());
  252. editor.getColorsScheme().setEditorFontSize(getFont().getSize());
  253. }
  254. }
  255. protected boolean shouldHaveBorder() {
  256. return true;
  257. }
  258. @Override
  259. public void setEnabled(boolean enabled) {
  260. super.setEnabled(enabled);
  261. if (myEditorField == null) {
  262. return;
  263. }
  264. myEditorField.setEnabled(enabled);
  265. }
  266. @Override
  267. public Dimension getPreferredSize() {
  268. if (UIUtil.isUnderIntelliJLaF() || StartupUiUtil.isUnderDarcula()) {
  269. return super.getPreferredSize();
  270. }
  271. if (myEditorField != null) {
  272. final Dimension preferredSize = new Dimension(myEditorField.getComponent().getPreferredSize());
  273. JBInsets.addTo(preferredSize, getInsets());
  274. return preferredSize;
  275. }
  276. return new Dimension(100, 20);
  277. }
  278. @Override
  279. protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
  280. if (!((EditorEx)myEditorField.getEditor()).processKeyTyped(e)) {
  281. return super.processKeyBinding(ks, e, condition, pressed);
  282. }
  283. return true;
  284. }
  285. public EditorEx getEditorEx() {
  286. return myEditorField != null ? (EditorEx)myEditorField.getEditor() : null;
  287. }
  288. }