VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIGuestControlConsole.cpp@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: UIGuestControlConsole.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIGuestControlConsole class implementation.
4 */
5
6/*
7 * Copyright (C) 2016-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifdef VBOX_WITH_PRECOMPILED_HEADERS
19# include <precomp.h>
20#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
21
22/* Qt includes: */
23# include <QVBoxLayout>
24# include <QApplication>
25# include <QTextBlock>
26
27/* GUI includes: */
28# include "UIGuestControlConsole.h"
29
30#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
31
32UIGuestControlConsole::UIGuestControlConsole(QWidget* parent /* = 0 */)
33 :QPlainTextEdit(parent)
34 , m_strGreet("Welcome to 'Guest Control Console'. Type 'help' for help\n")
35 , m_strPrompt("$>")
36 , m_uCommandHistoryIndex(0)
37{
38 /* Configure this: */
39 setUndoRedoEnabled(false);
40 setWordWrapMode(QTextOption::NoWrap);
41 reset();
42
43 m_tabDictinary.insert("username", 0);
44 m_tabDictinary.insert("createsession", 0);
45 m_tabDictinary.insert("exe", 0);
46 m_tabDictinary.insert("sessionid", 0);
47 m_tabDictinary.insert("sessionname", 0);
48 m_tabDictinary.insert("timeout", 0);
49 m_tabDictinary.insert("password", 0);
50 m_tabDictinary.insert("start", 0);
51 m_tabDictinary.insert("ls", 0);
52 m_tabDictinary.insert("stat", 0);
53}
54
55void UIGuestControlConsole::reset()
56{
57 clear();
58 startNextLine();
59 insertPlainText(m_strGreet);
60 startNextLine();
61}
62
63void UIGuestControlConsole::startNextLine()
64{
65 moveCursor(QTextCursor::End);
66 insertPlainText(m_strPrompt);
67 moveCursor(QTextCursor::End);
68}
69
70
71void UIGuestControlConsole::putOutput(const QString &strOutput)
72{
73 if (strOutput.isNull() || strOutput.length() <= 0)
74 return;
75
76 bool newLineNeeded = getCommandString().isEmpty();
77
78 QString strOwn("\n");
79 strOwn.append(strOutput);
80 moveCursor(QTextCursor::End);
81 insertPlainText(strOwn);
82 moveCursor(QTextCursor::End);
83
84 if (newLineNeeded)
85 {
86 insertPlainText("\n");
87 startNextLine();
88 }
89 }
90
91void UIGuestControlConsole::keyPressEvent(QKeyEvent *pEvent)
92{
93 /* Check if we at the bottom most line.*/
94 bool lastLine = blockCount() == (textCursor().blockNumber() +1);
95
96 switch (pEvent->key()) {
97 case Qt::Key_PageUp:
98 case Qt::Key_Up:
99 {
100 replaceLineContent(getPreviousCommandFromHistory(getCommandString()));
101 break;
102 }
103 case Qt::Key_PageDown:
104 case Qt::Key_Down:
105 {
106 replaceLineContent(getNextCommandFromHistory(getCommandString()));
107 break;
108 }
109 case Qt::Key_Backspace:
110 {
111 QTextCursor cursor = textCursor();
112 if (lastLine && cursor.positionInBlock() > m_strPrompt.length())
113 cursor.deletePreviousChar();
114 break;
115 }
116 case Qt::Key_Left:
117 case Qt::Key_Right:
118 {
119 if (textCursor().positionInBlock() > m_strPrompt.length()-1)
120 QPlainTextEdit::keyPressEvent(pEvent);
121 break;
122 }
123 case Qt::Key_Return:
124 case Qt::Key_Enter:
125 {
126 if (lastLine)
127 {
128 QString strCommand(getCommandString());
129 if (!strCommand.isEmpty())
130 {
131 emit commandEntered(strCommand);
132 if (!m_tCommandHistory.contains(strCommand))
133 m_tCommandHistory.push_back(strCommand);
134 m_uCommandHistoryIndex = m_tCommandHistory.size()-1;
135 moveCursor(QTextCursor::End);
136 QPlainTextEdit::keyPressEvent(pEvent);
137 startNextLine();
138 }
139 }
140 break;
141 }
142 case Qt::Key_Home:
143 {
144 QTextCursor cursor = textCursor();
145 cursor.movePosition(QTextCursor::StartOfLine);
146 cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, m_strPrompt.length());
147 setTextCursor(cursor);
148 break;
149 }
150 case Qt::Key_Tab:
151 completeByTab();
152 break;
153 default:
154 {
155 if (pEvent->modifiers() == Qt::ControlModifier && pEvent->key() == Qt::Key_C)
156 {
157 QPlainTextEdit::keyPressEvent(pEvent);
158 }
159 else
160 {
161 if (lastLine)
162 QPlainTextEdit::keyPressEvent(pEvent);
163 }
164 }
165 break;
166 }
167}
168
169void UIGuestControlConsole::mousePressEvent(QMouseEvent *pEvent)
170{
171 // Q_UNUSED(pEvent);
172 // setFocus();
173 QPlainTextEdit::mousePressEvent(pEvent);
174}
175
176void UIGuestControlConsole::mouseDoubleClickEvent(QMouseEvent *pEvent)
177{
178 //Q_UNUSED(pEvent);
179 QPlainTextEdit::mouseDoubleClickEvent(pEvent);
180}
181
182void UIGuestControlConsole::contextMenuEvent(QContextMenuEvent *pEvent)
183{
184 Q_UNUSED(pEvent);
185 //QPlainTextEdit::contextMenuEvent(pEvent);
186}
187
188QString UIGuestControlConsole::getCommandString()
189{
190 QTextDocument* pDocument = document();
191 if (!pDocument)
192 return QString();
193 QTextBlock block = pDocument->lastBlock();//findBlockByLineNumber(pDocument->lineCount()-1);
194 if (!block.isValid())
195 return QString();
196 QString lineStr = block.text();
197 if (lineStr.isNull() || lineStr.length() <= 1)
198 return QString();
199 /* Remove m_strPrompt from the line string: */
200 return (lineStr.right(lineStr.length()-m_strPrompt.length()));
201}
202
203void UIGuestControlConsole::replaceLineContent(const QString &stringNewContent)
204{
205 moveCursor(QTextCursor::End);
206 QTextCursor cursor = textCursor();
207 cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
208 cursor.removeSelectedText();
209
210 QString newString(m_strPrompt);
211 newString.append(stringNewContent);
212 insertPlainText(newString);
213 moveCursor(QTextCursor::End);
214}
215
216QString UIGuestControlConsole::getNextCommandFromHistory(const QString &originalString /* = QString() */)
217{
218 if (m_tCommandHistory.empty())
219 return originalString;
220
221 if (m_uCommandHistoryIndex == (unsigned)(m_tCommandHistory.size() - 1))
222 m_uCommandHistoryIndex = 0;
223 else
224 ++m_uCommandHistoryIndex;
225
226 return m_tCommandHistory.at(m_uCommandHistoryIndex);
227}
228
229
230QString UIGuestControlConsole::getPreviousCommandFromHistory(const QString &originalString /* = QString() */)
231{
232 if (m_tCommandHistory.empty())
233 return originalString;
234 if (m_uCommandHistoryIndex == 0)
235 m_uCommandHistoryIndex = m_tCommandHistory.size() - 1;
236 else
237 --m_uCommandHistoryIndex;
238
239 return m_tCommandHistory.at(m_uCommandHistoryIndex);
240}
241
242void UIGuestControlConsole::completeByTab()
243{
244 bool lastLine = blockCount() == (textCursor().blockNumber() +1);
245 if (!lastLine)
246 return;
247 /* Save whatever we have currently on this line: */
248 QString currentCommand = getCommandString();
249
250 QTextCursor cursor = textCursor();
251 /* Save the cursor's position within the line */
252 int cursorBlockPosition = cursor.positionInBlock();
253
254 /* Find out on which word the cursor is. This is the word we will
255 complete: */
256 cursor.select(QTextCursor::WordUnderCursor);
257 QString currentWord = cursor.selectedText();
258
259 const QList<QString> &matches = matchedWords(currentWord);
260 /* If there are no matches do nothing: */
261 if (matches.empty())
262 return;
263 /* if there are more than one match list them all and
264 reprint the line: */
265 if (matches.size() > 1)
266 {
267 moveCursor(QTextCursor::End);
268 QString strMatches;
269 for (int i = 0; i < matches.size(); ++i)
270 {
271 strMatches.append(matches.at(i));
272 strMatches.append(" ");
273 }
274 appendPlainText(strMatches);
275 insertPlainText(QString("\n").append(m_strPrompt));
276 insertPlainText(currentCommand);
277 /* Put the cursor in its previous position within the line: */
278 int blockPosition = textCursor().block().position();
279 QTextCursor nCursor = textCursor();
280 nCursor.setPosition(blockPosition + cursorBlockPosition);
281 setTextCursor(nCursor);
282 return;
283 }
284 /* if there is only one word just complete: */
285 /* some sanity checks */
286 if (matches.at(0).length() > currentWord.length())
287 insertPlainText(matches.at(0).right(matches.at(0).length() - currentWord.length()));
288}
289
290
291QList<QString> UIGuestControlConsole::matchedWords(const QString &strSearch) const
292{
293 QList<QString> list;
294 /* Go thru the map and find which of its elements start with @pstrSearch: */
295 for (TabDictionary::const_iterator iterator = m_tabDictinary.begin();
296 iterator != m_tabDictinary.end(); ++iterator)
297 {
298 const QString &strMap = iterator.key();
299 if (strMap.startsWith(strSearch))
300 list.push_back(strMap);
301 }
302 return list;
303}
304
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette