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 <jaroslaw.kobus@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2019-10-04 16:01:36 +02:00
parent ab355bb157
commit 91d785a123
6 changed files with 81 additions and 29 deletions

View File

@@ -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<QString, QUrl> linksForIdentifier(const QString &id)
{
return checkInstance() ? m_instance->linksForIdentifier(id) : QMap<QString, QUrl>();

View File

@@ -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<QString, QUrl> linksForIdentifier(const QString &id);
CORE_EXPORT QMap<QString, QUrl> linksForKeyword(const QString &id);

View File

@@ -39,6 +39,7 @@ protected:
public:
virtual void registerDocumentation(const QStringList &fileNames) = 0;
virtual void unregisterDocumentation(const QStringList &fileNames) = 0;
virtual QMap<QString, QUrl> linksForIdentifier(const QString &id) = 0;
virtual QMap<QString, QUrl> linksForKeyword(const QString &keyword) = 0;
virtual QByteArray fileData(const QUrl &url) = 0;

View File

@@ -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<bool> &futureInterface,

View File

@@ -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);

View File

@@ -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<BaseQtVersion *> &added,
const QList<BaseQtVersion *> &removed = {},
const QList<BaseQtVersion *> &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) {
for (const QString &docPath : docPaths) {
const QDir versionHelpDir(docPath);
foreach (const QString &helpFile,
versionHelpDir.entryList(QStringList("*.qch"), QDir::Files))
files << docPath + helpFile;
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<BaseQtVersion *> &vs)
{
QStringList files;
for (BaseQtVersion *v : vs)
files += documentationFiles(v);
return files;
}
static void updateDocumentation(const QList<BaseQtVersion *> &added,
const QList<BaseQtVersion *> &removed,
const QList<BaseQtVersion *> &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<BaseQtVersion *> newVersions)
QList<BaseQtVersion *> sortedNewVersions = newVersions;
Utils::sort(sortedNewVersions, &BaseQtVersion::uniqueId);
QList<int> addedVersions;
QList<int> removedVersions;
QList<int> changedVersions;
QList<BaseQtVersion *> addedVersions;
QList<BaseQtVersion *> removedVersions;
QList<std::pair<BaseQtVersion *, BaseQtVersion *>> 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<BaseQtVersion *> 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<BaseQtVersion *> changedOldVersions
= Utils::transform(changedVersions, &std::pair<BaseQtVersion *, BaseQtVersion *>::first);
const QList<BaseQtVersion *> changedNewVersions
= Utils::transform(changedVersions,
&std::pair<BaseQtVersion *, BaseQtVersion *>::second);
updateDocumentation(addedVersions + changedNewVersions,
removedVersions + changedOldVersions,
sortedNewVersions);
}
const QList<int> addedIds = Utils::transform(addedVersions, &BaseQtVersion::uniqueId);
const QList<int> removedIds = Utils::transform(removedVersions, &BaseQtVersion::uniqueId);
const QList<int> changedIds = Utils::transform(changedVersions,
[](std::pair<BaseQtVersion *, BaseQtVersion *> 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