Option to run python process in a terminal emulation mode (PY-22487)
[idea/community.git] / platform / platform-impl / src / com / intellij / terminal / JBTerminalWidget.java
1 /*
2  * Copyright 2000-2016 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.terminal;
17
18 import com.google.common.base.Predicate;
19 import com.intellij.openapi.Disposable;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.util.Disposer;
22 import com.intellij.openapi.wm.ToolWindowManager;
23 import com.intellij.ui.SearchTextField;
24 import com.intellij.ui.components.JBScrollBar;
25 import com.intellij.ui.components.JBScrollPane;
26 import com.intellij.util.ui.JBSwingUtilities;
27 import com.intellij.util.ui.RegionPainter;
28 import com.jediterm.terminal.SubstringFinder;
29 import com.jediterm.terminal.TerminalStarter;
30 import com.jediterm.terminal.TtyConnector;
31 import com.jediterm.terminal.model.JediTerminal;
32 import com.jediterm.terminal.model.StyleState;
33 import com.jediterm.terminal.model.TerminalTextBuffer;
34 import com.jediterm.terminal.ui.JediTermWidget;
35 import com.jediterm.terminal.ui.TerminalAction;
36 import com.jediterm.terminal.ui.settings.SettingsProvider;
37 import org.jetbrains.annotations.NotNull;
38
39 import javax.swing.*;
40 import javax.swing.event.DocumentListener;
41 import java.awt.*;
42 import java.awt.event.KeyEvent;
43 import java.awt.event.KeyListener;
44 import java.util.List;
45
46 public class JBTerminalWidget extends JediTermWidget implements Disposable {
47
48   private final Project myProject;
49   private final JBTerminalSystemSettingsProviderBase mySettingsProvider;
50
51   public JBTerminalWidget(Project project, JBTerminalSystemSettingsProviderBase settingsProvider, Disposable parent) {
52     this(project, 80, 24, settingsProvider, parent);
53   }
54
55   public JBTerminalWidget(Project project, int columns, int lines, JBTerminalSystemSettingsProviderBase settingsProvider, Disposable parent) {
56     super(columns, lines, settingsProvider);
57     myProject = project;
58     mySettingsProvider = settingsProvider;
59
60     setName("terminal");
61
62     Disposer.register(parent, this);
63   }
64
65   @Override
66   protected JBTerminalPanel createTerminalPanel(@NotNull SettingsProvider settingsProvider,
67                                                 @NotNull StyleState styleState,
68                                                 @NotNull TerminalTextBuffer textBuffer) {
69     JBTerminalPanel panel = new JBTerminalPanel((JBTerminalSystemSettingsProviderBase)settingsProvider, textBuffer, styleState);
70
71     Disposer.register(this, panel);
72     return panel;
73   }
74
75   @Override
76   protected Graphics getComponentGraphics(Graphics graphics) {
77     return JBSwingUtilities.runGlobalCGTransform(this, super.getComponentGraphics(graphics));
78   }
79
80   @Override
81   protected TerminalStarter createTerminalStarter(JediTerminal terminal, TtyConnector connector) {
82     return new JBTerminalStarter(terminal, connector);
83   }
84
85   @Override
86   protected JScrollBar createScrollBar() {
87     JBScrollBar bar = new JBScrollBar();
88     bar.putClientProperty(JBScrollPane.Alignment.class, JBScrollPane.Alignment.RIGHT);
89     bar.putClientProperty(JBScrollBar.TRACK, new RegionPainter<Object>() {
90       @Override
91       public void paint(Graphics2D g, int x, int y, int width, int height, Object object) {
92         SubstringFinder.FindResult result = myTerminalPanel.getFindResult();
93         if (result != null) {
94           int modelHeight = bar.getModel().getMaximum() - bar.getModel().getMinimum();
95           int anchorHeight = Math.max(2, height / modelHeight);
96
97           Color color = mySettingsProvider.getTerminalColorPalette()
98             .getColor(mySettingsProvider.getFoundPatternColor().getBackground());
99           g.setColor(color);
100           for (SubstringFinder.FindResult.FindItem r : result.getItems()) {
101             int where = height * r.getStart().y / modelHeight;
102             g.fillRect(x, y + where, width, anchorHeight);
103           }
104         }
105       }
106     });
107     return bar;
108   }
109
110   @Override
111   public List<TerminalAction> getActions() {
112      List<TerminalAction> actions = super.getActions();
113      if (!mySettingsProvider.overrideIdeShortcuts()) {
114        actions
115          .add(new TerminalAction("EditorEscape", new KeyStroke[]{KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)}, new Predicate<KeyEvent>() {
116            @Override
117            public boolean apply(KeyEvent input) {
118              if (!myTerminalPanel.getTerminalTextBuffer().isUsingAlternateBuffer()) {
119                ToolWindowManager.getInstance(myProject).activateEditorComponent();
120                return true;
121              }
122              else {
123                return false;
124              }
125            }
126          }).withHidden(true));
127      }
128      return actions;
129   };
130
131   @Override
132   public void dispose() {
133   }
134
135   @Override
136   protected SearchComponent createSearchComponent() {
137     return new SearchComponent() {
138       private final SearchTextField myTextField = new SearchTextField(false);
139
140       @Override
141       public String getText() {
142         return myTextField.getText();
143       }
144
145       @Override
146       public JComponent getComponent() {
147         myTextField.setOpaque(false);
148         return myTextField;
149       }
150
151       @Override
152       public void addDocumentChangeListener(DocumentListener listener) {
153         myTextField.addDocumentListener(listener);
154       }
155
156       @Override
157       public void addKeyListener(KeyListener listener) {
158         myTextField.addKeyboardListener(listener);
159       }
160
161       @Override
162       public void onResultUpdated(SubstringFinder.FindResult result) {
163       }
164
165       @Override
166       public void nextFindResultItem(SubstringFinder.FindResult.FindItem item) {
167       }
168
169       @Override
170       public void prevFindResultItem(SubstringFinder.FindResult.FindItem item) {
171       }
172     };
173   }
174 }