From 91d785a1236aa749a9807faad62cf828e17dacd3 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 4 Oct 2019 16:01:36 +0200 Subject: [PATCH] Help: Unregister documentation when unregistering Qt versions While doing we must take care that we do not remove documentation that is used by other, still registered Qt versions (since for example desktop & mobile Qt versions share the same documentation). Fixes: QTCREATORBUG-16631 Change-Id: I77a38c89698cb3050d4a0a6963ab12d3238e2068 Reviewed-by: Jarek Kobus Reviewed-by: David Schulz --- src/plugins/coreplugin/helpmanager.cpp | 6 ++ src/plugins/coreplugin/helpmanager.h | 1 + .../coreplugin/helpmanager_implementation.h | 1 + src/plugins/help/helpmanager.cpp | 16 +++- src/plugins/help/helpmanager.h | 1 + src/plugins/qtsupport/qtversionmanager.cpp | 85 +++++++++++++------ 6 files changed, 81 insertions(+), 29 deletions(-) diff --git a/src/plugins/coreplugin/helpmanager.cpp b/src/plugins/coreplugin/helpmanager.cpp index 357adf13121..3e8e5b40037 100644 --- a/src/plugins/coreplugin/helpmanager.cpp +++ b/src/plugins/coreplugin/helpmanager.cpp @@ -80,6 +80,12 @@ void registerDocumentation(const QStringList &files) m_instance->registerDocumentation(files); } +void unregisterDocumentation(const QStringList &fileNames) +{ + if (checkInstance()) + m_instance->unregisterDocumentation(fileNames); +} + QMap linksForIdentifier(const QString &id) { return checkInstance() ? m_instance->linksForIdentifier(id) : QMap(); diff --git a/src/plugins/coreplugin/helpmanager.h b/src/plugins/coreplugin/helpmanager.h index 12a3ac7b1e7..7b7e4f052e7 100644 --- a/src/plugins/coreplugin/helpmanager.h +++ b/src/plugins/coreplugin/helpmanager.h @@ -61,6 +61,7 @@ enum HelpViewerLocation { CORE_EXPORT QString documentationPath(); CORE_EXPORT void registerDocumentation(const QStringList &fileNames); +CORE_EXPORT void unregisterDocumentation(const QStringList &fileNames); CORE_EXPORT QMap linksForIdentifier(const QString &id); CORE_EXPORT QMap linksForKeyword(const QString &id); diff --git a/src/plugins/coreplugin/helpmanager_implementation.h b/src/plugins/coreplugin/helpmanager_implementation.h index 89296691eed..9af4a499380 100644 --- a/src/plugins/coreplugin/helpmanager_implementation.h +++ b/src/plugins/coreplugin/helpmanager_implementation.h @@ -39,6 +39,7 @@ protected: public: virtual void registerDocumentation(const QStringList &fileNames) = 0; + virtual void unregisterDocumentation(const QStringList &fileNames) = 0; virtual QMap linksForIdentifier(const QString &id) = 0; virtual QMap linksForKeyword(const QString &keyword) = 0; virtual QByteArray fileData(const QUrl &url) = 0; diff --git a/src/plugins/help/helpmanager.cpp b/src/plugins/help/helpmanager.cpp index 6d41b79ff3d..3c40e187020 100644 --- a/src/plugins/help/helpmanager.cpp +++ b/src/plugins/help/helpmanager.cpp @@ -136,8 +136,20 @@ void HelpManager::registerDocumentation(const QStringList &files) emit Core::HelpManager::Signals::instance()->documentationChanged(); } }); - ProgressManager::addTask(future, tr("Update Documentation"), - kUpdateDocumentationTask); + ProgressManager::addTask(future, tr("Update Documentation"), kUpdateDocumentationTask); +} + +void HelpManager::unregisterDocumentation(const QStringList &fileNames) +{ + if (fileNames.isEmpty()) + return; + const auto getNamespaces = [](const QStringList &fileNames) { + QMutexLocker locker(&d->m_helpengineMutex); + return Utils::transform(fileNames, [](const QString &filePath) { + return d->m_helpEngine->namespaceName(filePath); + }); + }; + unregisterNamespaces(getNamespaces(fileNames)); } void HelpManager::registerDocumentationNow(QFutureInterface &futureInterface, diff --git a/src/plugins/help/helpmanager.h b/src/plugins/help/helpmanager.h index 49ca60f4684..bcde6b794cd 100644 --- a/src/plugins/help/helpmanager.h +++ b/src/plugins/help/helpmanager.h @@ -49,6 +49,7 @@ public: static QString collectionFilePath(); void registerDocumentation(const QStringList &fileNames) override; + void unregisterDocumentation(const QStringList &fileNames) override; static void unregisterNamespaces(const QStringList &nameSpaces); diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index cbf44af8eff..50f85b8760a 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -94,8 +94,9 @@ bool qtVersionNumberCompare(BaseQtVersion *a, BaseQtVersion *b) static bool restoreQtVersions(); static void findSystemQt(); static void saveQtVersions(); -static void updateDocumentation(); - +static void updateDocumentation(const QList &added, + const QList &removed = {}, + const QList &allNew = {}); // -------------------------------------------------------------------------- // QtVersionManager @@ -143,7 +144,7 @@ void QtVersionManager::triggerQtVersionRestore() FileSystemWatcher::WatchModifiedDate); } // exists - updateDocumentation(); + updateDocumentation(m_versions.values()); } bool QtVersionManager::isLoaded() @@ -465,20 +466,37 @@ void QtVersionManager::removeVersion(BaseQtVersion *version) delete version; } -static void updateDocumentation() +static QStringList documentationFiles(BaseQtVersion *v) { QStringList files; - foreach (BaseQtVersion *v, m_versions) { - const QStringList docPaths = QStringList( - {v->docsPath().toString() + QChar('/'), v->docsPath().toString() + "/qch/"}); - foreach (const QString &docPath, docPaths) { - const QDir versionHelpDir(docPath); - foreach (const QString &helpFile, - versionHelpDir.entryList(QStringList("*.qch"), QDir::Files)) - files << docPath + helpFile; - } + const QStringList docPaths = QStringList( + {v->docsPath().toString() + QChar('/'), v->docsPath().toString() + "/qch/"}); + for (const QString &docPath : docPaths) { + const QDir versionHelpDir(docPath); + for (const QString &helpFile : versionHelpDir.entryList(QStringList("*.qch"), QDir::Files)) + files.append(docPath + helpFile); } - Core::HelpManager::registerDocumentation(files); + return files; +} + +static QStringList documentationFiles(const QList &vs) +{ + QStringList files; + for (BaseQtVersion *v : vs) + files += documentationFiles(v); + return files; +} +static void updateDocumentation(const QList &added, + const QList &removed, + const QList &allNew) +{ + const QStringList docsOfAll = documentationFiles(allNew); + const QStringList docsToRemove = Utils::filtered(documentationFiles(removed), + [&docsOfAll](const QString &f) { + return !docsOfAll.contains(f); + }); + Core::HelpManager::unregisterDocumentation(docsToRemove); + Core::HelpManager::registerDocumentation(documentationFiles(added)); } int QtVersionManager::getUniqueId() @@ -530,9 +548,9 @@ void QtVersionManager::setNewQtVersions(QList newVersions) QList sortedNewVersions = newVersions; Utils::sort(sortedNewVersions, &BaseQtVersion::uniqueId); - QList addedVersions; - QList removedVersions; - QList changedVersions; + QList addedVersions; + QList removedVersions; + QList> changedVersions; // So we trying to find the minimal set of changed versions, // iterate over both sorted list @@ -548,41 +566,54 @@ void QtVersionManager::setNewQtVersions(QList newVersions) int nid = (*nit)->uniqueId(); int oid = (*oit)->uniqueId(); if (nid < oid) { - addedVersions.push_back(nid); + addedVersions.push_back(*nit); ++nit; } else if (oid < nid) { - removedVersions.push_back(oid); + removedVersions.push_back(*oit); ++oit; } else { if (!equals(*oit, *nit)) - changedVersions.push_back(oid); + changedVersions.push_back({*oit, *nit}); ++oit; ++nit; } } while (nit != nend) { - addedVersions.push_back((*nit)->uniqueId()); + addedVersions.push_back(*nit); ++nit; } while (oit != oend) { - removedVersions.push_back((*oit)->uniqueId()); + removedVersions.push_back(*oit); ++oit; } + if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty()) { + const QList changedOldVersions + = Utils::transform(changedVersions, &std::pair::first); + const QList changedNewVersions + = Utils::transform(changedVersions, + &std::pair::second); + updateDocumentation(addedVersions + changedNewVersions, + removedVersions + changedOldVersions, + sortedNewVersions); + } + const QList addedIds = Utils::transform(addedVersions, &BaseQtVersion::uniqueId); + const QList removedIds = Utils::transform(removedVersions, &BaseQtVersion::uniqueId); + const QList changedIds = Utils::transform(changedVersions, + [](std::pair v) { + return v.first->uniqueId(); + }); + qDeleteAll(m_versions); m_versions.clear(); foreach (BaseQtVersion *v, sortedNewVersions) m_versions.insert(v->uniqueId(), v); - - if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty()) - updateDocumentation(); - saveQtVersions(); if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty()) - emit m_instance->qtVersionsChanged(addedVersions, removedVersions, changedVersions); + emit m_instance->qtVersionsChanged(addedIds, removedIds, changedIds); } } // namespace QtVersion