Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmldebugconsole.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
7
8#include <iostream>
9
10QT_BEGIN_NAMESPACE
11
12using namespace Qt::StringLiterals;
13
15{
16 registerCommand({ "help"_L1, "h"_L1 }, {}, tr("Show the list of available commands."),
17 [this](const QStringList &) {
18 printHelp();
19 prompt();
20 });
21}
22
27
28void QQmlDebugConsole::registerCommand(const QStringList &names, const QString &argsHint,
29 const QString &description, CommandHandler handler)
30{
31 m_commands.append(Command{ names, argsHint, description, std::move(handler) });
32}
33
35{
36 Q_ASSERT(!m_listenerThread.isRunning());
37
38 m_listener = new QQmlDebugCommandListener;
39 m_listener->moveToThread(&m_listenerThread);
40 connect(m_listener, &QQmlDebugCommandListener::command, this, &QQmlDebugConsole::handleLine);
41 connect(m_listener, &QQmlDebugCommandListener::endOfInput, this, &QQmlDebugConsole::endOfInput);
42 connect(this, &QQmlDebugConsole::requestCommand, m_listener,
43 &QQmlDebugCommandListener::readCommand);
44
45 m_listenerThread.start();
46}
47
49{
50 // The listener thread is idle in its event loop between commands, so quitting
51 // it from here (after the last command has been processed) unblocks wait().
52 if (m_listenerThread.isRunning()) {
53 m_listenerThread.quit();
54 m_listenerThread.wait();
55 }
56
57 delete std::exchange(m_listener, nullptr);
58}
59
60void QQmlDebugConsole::prompt(const QString &message, bool ready)
61{
62 if (!message.isEmpty())
63 std::cerr << qPrintable(message) << std::endl;
64 std::cerr << "> ";
65 if (ready)
66 emit requestCommand();
67}
68
69void QQmlDebugConsole::printLine(const QString &message)
70{
71 std::cerr << qPrintable(message) << std::endl;
72}
73
74void QQmlDebugConsole::askConfirmation(const QString &question, std::function<void()> onConfirmed,
75 std::function<void()> onDeclined)
76{
77 m_pendingQuestion = question;
78 m_onConfirmed = std::move(onConfirmed);
79 m_onDeclined = std::move(onDeclined);
80 prompt(question);
81}
82
83void QQmlDebugConsole::handleLine(const QString &line)
84{
85 const QStringList args = line.split(QChar::Space, Qt::SkipEmptyParts);
86 if (args.isEmpty()) {
87 prompt();
88 return;
89 }
90
91 const QString keyword = args.first().toLower();
92 const QStringList rest = args.mid(1);
93
94 if (!m_pendingQuestion.isEmpty()) {
95 if (keyword == "y"_L1 || keyword == "yes"_L1) {
96 m_pendingQuestion.clear();
97 m_onDeclined = {};
98 if (auto onConfirmed = std::exchange(m_onConfirmed, {}))
99 onConfirmed();
100 } else if (keyword == "n"_L1 || keyword == "no"_L1) {
101 m_pendingQuestion.clear();
102 m_onConfirmed = {};
103 if (auto onDeclined = std::exchange(m_onDeclined, {}))
104 onDeclined();
105 else
106 prompt();
107 } else {
108 prompt(m_pendingQuestion);
109 }
110 return;
111 }
112
113 for (const Command &cmd : std::as_const(m_commands)) {
114 if (cmd.names.contains(keyword)) {
115 cmd.handler(rest);
116 return;
117 }
118 }
119
120 printHelp();
121 prompt();
122}
123
124void QQmlDebugConsole::printHelp()
125{
126 printLine(tr("The following commands are available:"));
127 for (const Command &cmd : std::as_const(m_commands)) {
128 QStringList quoted;
129 quoted.reserve(cmd.names.size());
130 for (const QString &name : cmd.names)
131 quoted << u'\'' + name + u'\'';
132 QString header = quoted.join(", "_L1);
133 if (!cmd.argsHint.isEmpty())
134 header += u' ' + cmd.argsHint;
135 printLine(header);
136 printLine(" "_L1 + cmd.description);
137 }
138}
139
140QT_END_NAMESPACE
141
142#include "moc_qqmldebugconsole_p.cpp"
void askConfirmation(const QString &question, std::function< void()> onConfirmed, std::function< void()> onDeclined={})
QQmlDebugConsole(QObject *parent=nullptr)
void printLine(const QString &message)
void registerCommand(const QStringList &names, const QString &argsHint, const QString &description, CommandHandler handler)
void prompt(const QString &message=QString(), bool ready=true)