File indexing completed on 2024-05-19 08:31:41
0001 /* 0002 SPDX-FileCopyrightText: 2009 Aleix Pol <aleixpol@kde.org> 0003 SPDX-FileCopyrightText: 2009 David Nolden <david.nolden.kdevelop@art-master.de> 0004 SPDX-FileCopyrightText: 2010 Benjamin Port <port.benjamin@gmail.com> 0005 SPDX-FileCopyrightText: 2016 Andreas Cord-Landwehr <cordlandwehr@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #include "qthelpqtdoc.h" 0011 #include "debug.h" 0012 0013 #include <QDir> 0014 #include <QIcon> 0015 #include <QStandardPaths> 0016 0017 #include <KLocalizedString> 0018 #include <QProcess> 0019 0020 #include <algorithm> 0021 0022 namespace { 0023 0024 QString qmakeCandidate() 0025 { 0026 // return the first qmake executable we can find 0027 const QStringList candidates { 0028 QStringLiteral("qmake"), 0029 QStringLiteral("qmake-qt4"), 0030 QStringLiteral("qmake-qt5") 0031 }; 0032 auto it = std::find_if(candidates.constBegin(), candidates.constEnd(), [](const QString& candidate) { 0033 return !QStandardPaths::findExecutable(candidate).isEmpty(); 0034 }); 0035 return it != candidates.constEnd() ? *it : QString(); 0036 } 0037 0038 } 0039 0040 QtHelpQtDoc::QtHelpQtDoc(QObject *parent, const QVariantList &args) 0041 : QtHelpProviderAbstract(parent, QStringLiteral("qthelpcollection.qhc"), args) 0042 , m_path(QString()) 0043 { 0044 Q_UNUSED(args); 0045 registerDocumentations(); 0046 } 0047 0048 QtHelpQtDoc::~QtHelpQtDoc() = default; 0049 0050 void QtHelpQtDoc::registerDocumentations() 0051 { 0052 Q_ASSERT(!m_isInitialized); 0053 const QString qmake = qmakeCandidate(); 0054 if (!qmake.isEmpty()) { 0055 auto* p = new QProcess(this); 0056 p->setProcessChannelMode(QProcess::MergedChannels); 0057 p->setProgram(qmake); 0058 p->setArguments({QLatin1String("-query"), QLatin1String("QT_INSTALL_DOCS")}); 0059 connect(p, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this, p](int code) { 0060 if (code == QProcess::NormalExit) { 0061 m_path = QDir::fromNativeSeparators(QString::fromLatin1(p->readAllStandardOutput().trimmed())); 0062 qCDebug(QTHELP) << "Detected doc path:" << m_path; 0063 } else { 0064 qCCritical(QTHELP) << "qmake query returned error:" << QString::fromLatin1(p->readAllStandardError()); 0065 qCDebug(QTHELP) << "last standard output was:" << QString::fromLatin1(p->readAllStandardOutput()); 0066 } 0067 0068 p->deleteLater(); 0069 m_isInitialized = true; 0070 }); 0071 p->start(); 0072 } else { 0073 m_isInitialized = true; 0074 } 0075 } 0076 0077 void QtHelpQtDoc::loadDocumentation() 0078 { 0079 if(m_path.isEmpty()) { 0080 return; 0081 } 0082 0083 const QStringList files = qchFiles(); 0084 if(files.isEmpty()) { 0085 qCWarning(QTHELP) << "could not find QCH file in directory" << m_path; 0086 return; 0087 } 0088 0089 for (const QString& fileName : files) { 0090 QString fileNamespace = QHelpEngineCore::namespaceName(fileName); 0091 if (!fileNamespace.isEmpty() && !m_engine.registeredDocumentations().contains(fileNamespace)) { 0092 qCDebug(QTHELP) << "loading doc" << fileName << fileNamespace; 0093 if(!m_engine.registerDocumentation(fileName)) 0094 qCCritical(QTHELP) << "error >> " << fileName << m_engine.error(); 0095 } 0096 } 0097 } 0098 0099 void QtHelpQtDoc::unloadDocumentation() 0100 { 0101 const auto fileNames = qchFiles(); 0102 for (const QString& fileName : fileNames) { 0103 QString fileNamespace = QHelpEngineCore::namespaceName(fileName); 0104 if(!fileName.isEmpty() && m_engine.registeredDocumentations().contains(fileNamespace)) { 0105 m_engine.unregisterDocumentation(fileName); 0106 } 0107 } 0108 } 0109 0110 QStringList QtHelpQtDoc::qchFiles() const 0111 { 0112 QStringList files; 0113 0114 const QVector<QString> paths{ // test directories 0115 m_path, 0116 m_path + QLatin1String("/qch/"), 0117 }; 0118 0119 for (const auto& path : paths) { 0120 QDir d(path); 0121 if(path.isEmpty() || !d.exists()) { 0122 continue; 0123 } 0124 const auto fileInfos = d.entryInfoList(QDir::Files); 0125 for (const auto& file : fileInfos) { 0126 files << file.absoluteFilePath(); 0127 } 0128 } 0129 if (files.isEmpty()) { 0130 qCDebug(QTHELP) << "no QCH file found at all"; 0131 } 0132 return files; 0133 } 0134 0135 QIcon QtHelpQtDoc::icon() const 0136 { 0137 return QIcon::fromTheme(QStringLiteral("qtlogo")); 0138 } 0139 0140 QString QtHelpQtDoc::name() const 0141 { 0142 return i18n("QtHelp"); 0143 } 0144 0145 #include "moc_qthelpqtdoc.cpp"