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
assistantclient.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include <QtCore/qstring.h>
7#include <QtCore/qprocess.h>
8#include <QtCore/qdir.h>
9#include <QtCore/qlibraryinfo.h>
10#include <QtCore/qdebug.h>
11#include <QtCore/qfileinfo.h>
12#include <QtCore/qobject.h>
13#include <QtCore/qtextstream.h>
14#include <QtCore/qcoreapplication.h>
15
17
18using namespace Qt::StringLiterals;
19
21
22AssistantClient::AssistantClient() = default;
23
25{
26 if (isRunning()) {
27 m_process->terminate();
28 m_process->waitForFinished();
29 }
30 delete m_process;
31}
32
33bool AssistantClient::showPage(const QString &path, QString *errorMessage)
34{
35 const QString cmd = "SetSource "_L1 + path;
36 return sendCommand(cmd, errorMessage);
37}
38
39bool AssistantClient::activateIdentifier(const QString &identifier, QString *errorMessage)
40{
41 const QString cmd = "ActivateIdentifier "_L1 + identifier;
42 return sendCommand(cmd, errorMessage);
43}
44
45bool AssistantClient::activateKeyword(const QString &keyword, QString *errorMessage)
46{
47 const QString cmd = "ActivateKeyword "_L1 + keyword;
48 return sendCommand(cmd, errorMessage);
49}
50
51bool AssistantClient::sendCommand(const QString &cmd, QString *errorMessage)
52{
54 qDebug() << "sendCommand " << cmd;
55 if (!ensureRunning(errorMessage))
56 return false;
57 if (!m_process->isWritable() || m_process->bytesToWrite() > 0) {
58 *errorMessage = QCoreApplication::translate("AssistantClient", "Unable to send request: Assistant is not responding.");
59 return false;
60 }
61 QTextStream str(m_process);
62 str << cmd << "\n\n";
63 return true;
64}
65
67{
68 return m_process && m_process->state() != QProcess::NotRunning;
69}
70
71QString AssistantClient::binary()
72{
73 QString app = QLibraryInfo::path(QLibraryInfo::BinariesPath) + QDir::separator();
74#if !defined(Q_OS_MACOS)
75 app += "assistant"_L1;
76#else
77 app += "Assistant.app/Contents/MacOS/Assistant"_L1;
78#endif
79
80#if defined(Q_OS_WIN)
81 app += ".exe"_L1;
82#endif
83
84 return app;
85}
86
87void AssistantClient::readyReadStandardError()
88{
89 qWarning("%s: %s",
90 qPrintable(QDir::toNativeSeparators(m_process->program())),
91 m_process->readAllStandardError().constData());
92}
93
94void AssistantClient::processTerminated(int exitCode, QProcess::ExitStatus exitStatus)
95{
96 const QString binary = QDir::toNativeSeparators(m_process->program());
97 if (exitStatus != QProcess::NormalExit)
98 qWarning("%s: crashed.", qPrintable(binary));
99 else if (exitCode != 0)
100 qWarning("%s: terminated with exit code %d.", qPrintable(binary), exitCode);
101}
102
103bool AssistantClient::ensureRunning(QString *errorMessage)
104{
105 if (isRunning())
106 return true;
107
108 if (!m_process) {
109 m_process = new QProcess;
110 QObject::connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
111 this, &AssistantClient::processTerminated);
112 QObject::connect(m_process, &QProcess::readyReadStandardError,
113 this, &AssistantClient::readyReadStandardError);
114 }
115
116 const QString app = binary();
117 if (!QFileInfo(app).isFile()) {
118 *errorMessage = QCoreApplication::translate("AssistantClient", "The binary '%1' does not exist.").arg(app);
119 return false;
120 }
122 qDebug() << "Running " << app;
123 // run
124 QStringList args{u"-enableRemoteControl"_s};
125 m_process->start(app, args);
126 if (!m_process->waitForStarted()) {
127 *errorMessage = QCoreApplication::translate("AssistantClient", "Unable to launch assistant (%1).").arg(app);
128 return false;
129 }
130 return true;
131}
132
133QString AssistantClient::documentUrl(const QString &module, int qtVersion)
134{
135 if (qtVersion == 0)
136 qtVersion = QT_VERSION;
137 QString rc;
138 QTextStream(&rc) << "qthelp://org.qt-project." << module << '.'
139 << (qtVersion >> 16) << ((qtVersion >> 8) & 0xFF) << (qtVersion & 0xFF)
140 << '/' << module << '/';
141 return rc;
142}
143
144QString AssistantClient::designerManualUrl(int qtVersion)
145{
146 return documentUrl(u"qtdesigner"_s, qtVersion);
147}
148
150{
151 return documentUrl(u"qtdoc"_s, qtVersion);
152}
153
154QT_END_NAMESPACE
@ debugAssistantClient
bool activateIdentifier(const QString &identifier, QString *errorMessage)
bool isRunning() const
bool showPage(const QString &path, QString *errorMessage)
static QString qtReferenceManualUrl(int qtVersion=0)
static QString designerManualUrl(int qtVersion=0)
static QString documentUrl(const QString &prefix, int qtVersion=0)
bool activateKeyword(const QString &keyword, QString *errorMessage)
Combined button and popup list for selecting options.