1 /*=========================================================================
2 
3   Library:   CTK
4 
5   Copyright (c) Kitware Inc.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11       http://www.apache.org/licenses/LICENSE-2.0.txt
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 =========================================================================*/
20 
21 #ifndef __ctkConsole_p_h
22 #define __ctkConsole_p_h
23 
24 // Qt includes
25 #include <QTextEdit>
26 #include <QPointer>
27 #include <QEventLoop>
28 
29 // CTK includes
30 #include "ctkConsole.h"
31 #include "ctkWidgetsExport.h"
32 
33 class QPushButton;
34 
35 /// \ingroup Widgets
36 class CTK_WIDGETS_EXPORT ctkConsolePrivate : public QTextEdit
37 {
38   Q_OBJECT
39   Q_DECLARE_PUBLIC(ctkConsole);
40 protected:
41   ctkConsole* const q_ptr;
42 public:
43 
44   ctkConsolePrivate(ctkConsole& object);
45   typedef QTextEdit Superclass;
46 
47   void init();
48 
49   static bool isMoveLeftWithinLine(QKeyEvent* e, QTextCursor::MoveOperation &moveOperation, QTextCursor::MoveMode &moveMode);
50 
51   static bool isMoveRighttWithinLine(QKeyEvent* e, QTextCursor::MoveOperation &moveOperation, QTextCursor::MoveMode &moveMode);
52 
53   virtual void keyPressEvent(QKeyEvent* e);
54 
55   void switchToUserInputTextColor(QTextCursor* textCursorToUpdate = 0);
56 
57   /// Returns the end of the document
58   int documentEnd() const;
59 
60   /// Returns the end of the commandLine
61   int commandEnd() const;
62 
63   virtual void focusOutEvent(QFocusEvent *e);
64 
65   virtual void resizeEvent(QResizeEvent * e);
66 
67   /// Force the scrollbar to be all the way down
68   void scrollToBottom();
69 
70   void updateCompleterIfVisible();
71 
72   /// If there is exactly 1 completion, insert it and hide the completer,
73   /// else do nothing.
74   void selectCompletion();
75 
76   void setCompleter(ctkConsoleCompleter* completer);
77 
78   void updateCompleter();
79 
80   /// Update the contents of the command buffer from the contents of the widget.
81   /// If \a commandLength is specified, buffer is updated limiting the content
82   /// of the widget.
83   void updateCommandBuffer(int commandLength = -1);
84 
85   /// Replace the contents of the command buffer, updating the display
86   void replaceCommandBuffer(const QString& text);
87 
88   /// References the buffer where the current un-executed command is stored
89   QString& commandBuffer();
90 
91   /// Implements command-execution
92   void internalExecuteCommand();
93 
94   void processInput();
95 
96   /// Writes the supplied text to the console
97   void printString(const QString& text);
98 
99   /// Updates the current command.
100   /// Unlike printMessage(), this will affect the current command being typed.
101   void printCommand(const QString& cmd);
102 
103   /// Puts out an input accepting promp using either ps1 or ps2.
104   /// ps2 will be used if MultilineStatement is True
105   /// \sa ctkConsole::ps1(), ctkConsole::ps2()
106   void promptForInput(const QString& indent = QString());
107 
108   /// Puts out an input accepting prompt.
109   /// It is recommended that one uses prompt instead of printMessage() to print
110   /// an input prompt since this call ensures that the prompt is shown on a new
111   /// line.
112   void prompt(const QString& text);
113 
114   /// Print welcome message
115   virtual void printWelcomeMessage();
116 
117 public Q_SLOTS:
118 
119   /// Inserts the given completion string at the cursor.
120   /// 2 Different ways of completion are established by \sa ctkConsolePrivate::insertCompletionMethod:
121   ///  TRUE  - Replace the current word that the cursor is touching with the given text.
122   ///          Determines the word using QTextCursor::StartOfWord, EndOfWord.
123   ///  FALSE - Just insert the word replacing only the text from the current position until StartOfWord
124   void insertCompletion(const QString& text);
125 
126   /// Print a message
127   /// \sa ctkConsole::outputTextColor
128   void printOutputMessage(const QString& text);
129 
130   /// Print a message
131   /// \sa ctkConsole::errorTextColor
132   void printErrorMessage(const QString& text);
133 
134   /// Update the value of ScrollbarAtBottom given the current position of the scollbar
135   void onScrollBarValueChanged(int value);
136 
137   /// Ensure the interactive line is visible (even when it is split on 2 lines)
138   /// \sa onScrollBarValueChanged()
139   void onTextChanged();
140 
141 protected:
142   /// Return true if the cursor position is in the history area
143   /// false if it is after the InteractivePosition.
144   bool isCursorInHistoryArea()const;
145 
146   /// Return true if the cursor position is in the message output area
147   /// false if it is before the end of the commandLine.
148   bool isCursorInMessageOutputArea()const;
149 
150   /// Reimplemented to make sure there is no text added into the
151   /// history logs.
152   virtual void insertFromMimeData(const QMimeData* source);
153 
154   /// Paste text at the current text cursor position.
155   void pasteText(const QString& text);
156 public:
157 
158   /// A custom completer
159   QPointer<ctkConsoleCompleter> Completer;
160 
161   /// Stores the beginning of the area of interactive input, outside which
162   /// changes can't be made to the text edit contents
163   int InteractivePosition;
164 
165   /// Stores the size of the message output area from the end of document
166   /// until the end of the command
167   int MessageOutputSize;
168 
169   /// Indicates if the last statement processes was incomplete.
170   bool MultilineStatement;
171 
172   /// Stores command-history, plus the current command buffer
173   QStringList CommandHistory;
174 
175   /// Stores the current position in the command-history
176   int CommandPosition;
177 
178   /// Prompt  color
179   QColor PromptColor;
180 
181   /// Output text color
182   QColor OutputTextColor;
183 
184   /// Message Output text color (every message displayed during autocompletion)
185   QColor MessageOutputColor;
186 
187   /// Error text color
188   QColor ErrorTextColor;
189 
190   /// Standard input text color.
191   QColor StdinTextColor;
192 
193   /// Command text color
194   QColor CommandTextColor;
195 
196   /// Welcome text color
197   QColor WelcomeTextColor;
198 
199   /// Primary prompt
200   QString Ps1;
201 
202   /// Secondary prompt
203   QString Ps2;
204 
205   /// Method to insert the completion word:
206   ///   TRUE  - Replace the whole word under the cursor
207   ///   FALSE - Insert the word and replace only from the cursor until the StartOfWord
208   bool insertCompletionMethod;
209 
210   ctkConsole::EditorHints EditorHints;
211 
212   bool ScrollbarAtBottom;
213 
214   QPointer<QEventLoop> InputEventLoop;
215 
216   QList<QKeySequence> CompleterShortcuts;
217 
218   ctkConsole::RunFileOptions RunFileOptions;
219 
220   QPushButton* RunFileButton;
221   QAction* RunFileAction;
222 };
223 
224 
225 #endif
226 
227