File indexing completed on 2024-12-15 03:45:03

0001 /*
0002     SPDX-FileCopyrightText: 2017 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #include <kuserfeedback_version.h>
0008 
0009 #include "helpcontroller.h"
0010 
0011 #include <QByteArray>
0012 #include <QCoreApplication>
0013 #include <QDebug>
0014 #include <QDir>
0015 #include <QFileInfo>
0016 #include <QLibraryInfo>
0017 #include <QProcess>
0018 #include <QStandardPaths>
0019 
0020 namespace KUserFeedback {
0021 namespace Console {
0022 struct HelpControllerPrivate
0023 {
0024     HelpControllerPrivate()
0025         : proc(nullptr) {}
0026 
0027     void startProcess();
0028     void sendCommand(const QByteArray &cmd);
0029 
0030     QString assistantPath;
0031     QString qhcPath;
0032     QProcess *proc;
0033 };
0034 }}
0035 
0036 using namespace KUserFeedback::Console;
0037 
0038 void HelpControllerPrivate::startProcess()
0039 {
0040     if (proc)
0041         return;
0042 
0043     proc = new QProcess(QCoreApplication::instance());
0044     proc->setProcessChannelMode(QProcess::ForwardedChannels);
0045     QObject::connect(proc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), [this]() {
0046         proc->deleteLater();
0047         proc = nullptr;
0048     });
0049     proc->setProgram(assistantPath);
0050     proc->setArguments({ QLatin1String("-collectionFile"), qhcPath, QLatin1String("-enableRemoteControl") });
0051     proc->start();
0052     proc->waitForStarted();
0053     sendCommand("expandToc 2;");
0054 }
0055 
0056 void HelpControllerPrivate::sendCommand(const QByteArray &cmd)
0057 {
0058     if (!proc)
0059         return;
0060     proc->write(cmd);
0061 }
0062 
0063 Q_GLOBAL_STATIC(HelpControllerPrivate, s_helpController)
0064 
0065 bool HelpController::isAvailable()
0066 {
0067     auto d = s_helpController();
0068     if (!d->assistantPath.isEmpty() && !d->qhcPath.isEmpty())
0069         return true;
0070 
0071     d->assistantPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator() + QStringLiteral("assistant");
0072     QFileInfo assistFile(d->assistantPath);
0073     if (!assistFile.isExecutable()) {
0074         d->assistantPath = QStandardPaths::findExecutable(QStringLiteral("assistant"));
0075         if (d->assistantPath.isEmpty()) {
0076             qDebug() << "Qt Assistant not found, help not available.";
0077             return false;
0078         }
0079     }
0080 
0081     const QString qhcPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, QLatin1String("user-feedback.qhc"));
0082     if (QFileInfo::exists(qhcPath)) {
0083         d->qhcPath = qhcPath;
0084         return true;
0085     }
0086     qDebug() << "user-feedback.qhc not found - help not available";
0087     return false;
0088 }
0089 
0090 #define STRINGIFY(x) #x
0091 #define INT2STR(x) STRINGIFY(x)
0092 
0093 void HelpController::openContents()
0094 {
0095     Q_ASSERT(isAvailable());
0096     auto d = s_helpController();
0097     d->startProcess();
0098     d->sendCommand("setSource qthelp://org.kde.UserFeedback." INT2STR(KUSERFEEDBACK_VERSION_MAJOR) "." INT2STR(KUSERFEEDBACK_VERSION_MINOR) "/userfeedback/index.html;syncContents\n");
0099 }
0100 
0101 void HelpController::openPage(const QString &page)
0102 {
0103     Q_ASSERT(isAvailable());
0104     auto d = s_helpController();
0105     d->startProcess();
0106     d->sendCommand(QByteArray("setSource qthelp://org.kde.UserFeedback." INT2STR(KUSERFEEDBACK_VERSION_MAJOR) "." INT2STR(KUSERFEEDBACK_VERSION_MINOR) "/") + page.toUtf8() + ";syncContents\n");
0107 }
0108 
0109 #undef STRINGIFY
0110 #undef INT2STR