Commit 877d482c authored by Eike Ziller's avatar Eike Ziller

Help: Clean up automatically registered documentation

It would keep documentation registered as long as the files are still
there, but that is actually not what is wanted. If you remove a Qt
version from Qt Creator, or switch between different Qt Creator
installations with different auto-detected Qt versions, the registered
documentation should be updated.
This also reduces the number of open files in these cases.

We keep a list of manually added documentation in the settings and treat
all other documentation as automatically managed.

Change-Id: I542f9aee0e62cab70db5afc5c6d6764d84cb253d
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@theqtcompany.com>
Reviewed-by: default avatarLeena Miettinen <riitta-leena.miettinen@theqtcompany.com>
parent a1f8be44
......@@ -48,6 +48,8 @@
#include <QSqlError>
#include <QSqlQuery>
static const char kUserDocumentationKey[] = "Help/UserDocumentation";
namespace Core {
struct HelpManagerPrivate
......@@ -57,14 +59,20 @@ struct HelpManagerPrivate
{}
QStringList documentationFromInstaller();
void readSettings();
void writeSettings();
void cleanUpDocumentation();
bool m_needsSetup;
QHelpEngineCore *m_helpEngine;
Utils::FileSystemWatcher *m_collectionWatcher;
QStringList m_filesToRegister;
QStringList m_nameSpacesToUnregister;
// data for delayed initialization
QSet<QString> m_filesToRegister;
QSet<QString> m_nameSpacesToUnregister;
QHash<QString, QVariant> m_customValues;
QSet<QString> m_userRegisteredFiles;
};
static HelpManager *m_instance = 0;
......@@ -96,6 +104,7 @@ HelpManager::HelpManager(QObject *parent) :
HelpManager::~HelpManager()
{
d->writeSettings();
delete d->m_helpEngine;
d->m_helpEngine = 0;
m_instance = 0;
......@@ -117,7 +126,8 @@ QString HelpManager::collectionFilePath()
void HelpManager::registerDocumentation(const QStringList &files)
{
if (d->m_needsSetup) {
d->m_filesToRegister.append(files);
foreach (const QString &filePath, files)
d->m_filesToRegister.insert(filePath);
return;
}
......@@ -154,17 +164,20 @@ void HelpManager::registerDocumentation(const QStringList &files)
void HelpManager::unregisterDocumentation(const QStringList &nameSpaces)
{
if (d->m_needsSetup) {
d->m_nameSpacesToUnregister.append(nameSpaces);
foreach (const QString &name, nameSpaces)
d->m_nameSpacesToUnregister.insert(name);
return;
}
bool docsChanged = false;
foreach (const QString &nameSpace, nameSpaces) {
const QString filePath = d->m_helpEngine->documentationFileName(nameSpace);
if (d->m_helpEngine->unregisterDocumentation(nameSpace)) {
docsChanged = true;
d->m_userRegisteredFiles.remove(filePath);
} else {
qWarning() << "Error unregistering namespace '" << nameSpace
<< "' from file '" << d->m_helpEngine->documentationFileName(nameSpace)
<< "' from file '" << filePath
<< "': " << d->m_helpEngine->error();
}
}
......@@ -172,6 +185,18 @@ void HelpManager::unregisterDocumentation(const QStringList &nameSpaces)
emit m_instance->documentationChanged();
}
void HelpManager::registerUserDocumentation(const QStringList &filePaths)
{
foreach (const QString &filePath, filePaths)
d->m_userRegisteredFiles.insert(filePath);
registerDocumentation(filePaths);
}
QSet<QString> HelpManager::userDocumentationPaths()
{
return d->m_userRegisteredFiles;
}
static QUrl buildQUrl(const QString &ns, const QString &folder,
const QString &relFileName, const QString &anchor)
{
......@@ -398,21 +423,26 @@ void HelpManager::setupHelpManager()
return;
d->m_needsSetup = false;
d->readSettings();
// create the help engine
d->m_helpEngine = new QHelpEngineCore(collectionFilePath(), m_instance);
d->m_helpEngine->setAutoSaveFilter(false);
d->m_helpEngine->setCurrentFilter(tr("Unfiltered"));
d->m_helpEngine->setupData();
verifyDocumenation();
foreach (const QString &filePath, d->documentationFromInstaller())
d->m_filesToRegister.insert(filePath);
d->cleanUpDocumentation();
if (!d->m_nameSpacesToUnregister.isEmpty()) {
unregisterDocumentation(d->m_nameSpacesToUnregister);
unregisterDocumentation(d->m_nameSpacesToUnregister.toList());
d->m_nameSpacesToUnregister.clear();
}
d->m_filesToRegister << d->documentationFromInstaller();
if (!d->m_filesToRegister.isEmpty()) {
registerDocumentation(d->m_filesToRegister);
registerDocumentation(d->m_filesToRegister.toList());
d->m_filesToRegister.clear();
}
......@@ -425,12 +455,18 @@ void HelpManager::setupHelpManager()
// -- private
void HelpManager::verifyDocumenation()
void HelpManagerPrivate::cleanUpDocumentation()
{
const QStringList &registeredDocs = d->m_helpEngine->registeredDocumentations();
// mark documentation for removal for which there is no documentation file anymore
// mark documentation for removal that is neither user registered, nor marked for registration
const QStringList &registeredDocs = m_helpEngine->registeredDocumentations();
foreach (const QString &nameSpace, registeredDocs) {
if (!QFileInfo::exists(d->m_helpEngine->documentationFileName(nameSpace)))
d->m_nameSpacesToUnregister.append(nameSpace);
const QString filePath = m_helpEngine->documentationFileName(nameSpace);
if (!QFileInfo::exists(filePath)
|| (!m_filesToRegister.contains(filePath)
&& !m_userRegisteredFiles.contains(filePath))) {
m_nameSpacesToUnregister.insert(nameSpace);
}
}
}
......@@ -455,4 +491,16 @@ QStringList HelpManagerPrivate::documentationFromInstaller()
return documentationFiles;
}
void HelpManagerPrivate::readSettings()
{
m_userRegisteredFiles = ICore::settings()->value(QLatin1String(kUserDocumentationKey))
.toStringList().toSet();
}
void HelpManagerPrivate::writeSettings()
{
const QStringList list = m_userRegisteredFiles.toList();
ICore::settings()->setValue(QLatin1String(kUserDocumentationKey), list);
}
} // Core
......@@ -69,6 +69,9 @@ public:
static void registerDocumentation(const QStringList &fileNames);
static void unregisterDocumentation(const QStringList &nameSpaces);
static void registerUserDocumentation(const QStringList &filePaths);
static QSet<QString> userDocumentationPaths();
static QMap<QString, QUrl> linksForKeyword(const QString &key);
static QMap<QString, QUrl> linksForIdentifier(const QString &id);
static QStringList findKeywords(const QString &key,
......@@ -109,7 +112,6 @@ private:
~HelpManager();
static void setupHelpManager();
static void verifyDocumenation();
friend class Core::Internal::CorePlugin; // setupHelpManager
friend class Core::Internal::MainWindow; // constructor/destructor
};
......
......@@ -63,9 +63,13 @@ QWidget *DocSettingsPage::widget()
m_ui.docsListWidget->installEventFilter(this);
const QStringList nameSpaces = HelpManager::registeredNamespaces();
const QSet<QString> userDocumentationPaths = HelpManager::userDocumentationPaths();
foreach (const QString &nameSpace, nameSpaces) {
addItem(nameSpace, HelpManager::fileFromNamespace(nameSpace));
m_filesToRegister.insert(nameSpace, HelpManager::fileFromNamespace(nameSpace));
const QString filePath = HelpManager::fileFromNamespace(nameSpace);
bool user = userDocumentationPaths.contains(filePath);
addItem(nameSpace, filePath, user);
m_filesToRegister.insert(nameSpace, filePath);
m_filesToRegisterUserManaged.insert(nameSpace, user);
}
m_filesToUnregister.clear();
......@@ -98,8 +102,9 @@ void DocSettingsPage::addDocumentation()
continue;
}
addItem(nameSpace, file);
addItem(nameSpace, file, true/*user managed*/);
m_filesToRegister.insert(nameSpace, QDir::toNativeSeparators(filePath));
m_filesToRegisterUserManaged.insert(nameSpace, true/*user managed*/);
// If the files to unregister contains the namespace, grab a copy of all paths added and try to
// remove the current file path. Afterwards remove the whole entry and add the clean list back.
......@@ -150,7 +155,14 @@ void DocSettingsPage::removeDocumentation()
void DocSettingsPage::apply()
{
HelpManager::unregisterDocumentation(m_filesToUnregister.keys());
HelpManager::registerDocumentation(m_filesToRegister.values());
QStringList files;
auto it = m_filesToRegisterUserManaged.constBegin();
while (it != m_filesToRegisterUserManaged.constEnd()) {
if (it.value()/*userManaged*/)
files << m_filesToRegister.value(it.key());
++it;
}
HelpManager::registerUserDocumentation(files);
m_filesToUnregister.clear();
}
......@@ -185,9 +197,10 @@ void DocSettingsPage::removeDocumentation(const QList<QListWidgetItem*> &items)
int row = 0;
foreach (QListWidgetItem* item, items) {
const QString nameSpace = item->text();
const QString nameSpace = item->data(Qt::UserRole).toString();
m_filesToRegister.remove(nameSpace);
m_filesToRegisterUserManaged.remove(nameSpace);
m_filesToUnregister.insertMulti(nameSpace, QDir::cleanPath(HelpManager::fileFromNamespace(nameSpace)));
row = m_ui.docsListWidget->row(item);
......@@ -198,9 +211,11 @@ void DocSettingsPage::removeDocumentation(const QList<QListWidgetItem*> &items)
QItemSelectionModel::ClearAndSelect);
}
void DocSettingsPage::addItem(const QString &nameSpace, const QString &fileName)
void DocSettingsPage::addItem(const QString &nameSpace, const QString &fileName, bool userManaged)
{
QListWidgetItem* item = new QListWidgetItem(nameSpace);
const QString name = userManaged ? nameSpace : tr("%1 (auto-detected)").arg(nameSpace);
QListWidgetItem* item = new QListWidgetItem(name);
item->setToolTip(fileName);
item->setData(Qt::UserRole, nameSpace);
m_ui.docsListWidget->addItem(item);
}
......@@ -57,7 +57,7 @@ private slots:
private:
bool eventFilter(QObject *object, QEvent *event);
void removeDocumentation(const QList<QListWidgetItem *> &items);
void addItem(const QString &nameSpace, const QString &fileName);
void addItem(const QString &nameSpace, const QString &fileName, bool userManaged);
private:
Ui::DocSettingsPage m_ui;
......@@ -67,6 +67,7 @@ private:
typedef QHash<QString, QString> NameSpaceToPathHash;
NameSpaceToPathHash m_filesToRegister;
QHash<QString, bool> m_filesToRegisterUserManaged;
NameSpaceToPathHash m_filesToUnregister;
};
......
......@@ -170,8 +170,6 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error)
SLOT(setupHelpEngineIfNeeded()));
connect(HelpManager::instance(), SIGNAL(collectionFileChanged()), this,
SLOT(setupHelpEngineIfNeeded()));
connect(HelpManager::instance(), SIGNAL(setupFinished()), this,
SLOT(unregisterOldQtCreatorDocumentation()));
Command *cmd;
QAction *action;
......@@ -265,22 +263,6 @@ ExtensionSystem::IPlugin::ShutdownFlag HelpPlugin::aboutToShutdown()
return SynchronousShutdown;
}
void HelpPlugin::unregisterOldQtCreatorDocumentation()
{
const QString &nsInternal = QString::fromLatin1("org.qt-project.qtcreator.%1%2%3")
.arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR).arg(IDE_VERSION_RELEASE);
QStringList documentationToUnregister;
foreach (const QString &ns, HelpManager::registeredNamespaces()) {
if (ns.startsWith(QLatin1String("org.qt-project.qtcreator."))
&& ns != nsInternal) {
documentationToUnregister << ns;
}
}
if (!documentationToUnregister.isEmpty())
HelpManager::unregisterDocumentation(documentationToUnregister);
}
void HelpPlugin::resetFilter()
{
const QString &filterInternal = QString::fromLatin1("Qt Creator %1.%2.%3")
......
......@@ -85,8 +85,6 @@ public:
static HelpViewer *createHelpViewer(qreal zoom);
private slots:
void unregisterOldQtCreatorDocumentation();
void modeChanged(Core::IMode *mode, Core::IMode *old);
void showContextHelp();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment