diff options
Diffstat (limited to 'src/plugins/coreplugin')
-rw-r--r-- | src/plugins/coreplugin/coreimpl.cpp | 5 | ||||
-rw-r--r-- | src/plugins/coreplugin/coreimpl.h | 1 | ||||
-rw-r--r-- | src/plugins/coreplugin/coreplugin.pro | 7 | ||||
-rw-r--r-- | src/plugins/coreplugin/helpmanager.cpp | 321 | ||||
-rw-r--r-- | src/plugins/coreplugin/helpmanager.h | 96 | ||||
-rw-r--r-- | src/plugins/coreplugin/icore.h | 2 | ||||
-rw-r--r-- | src/plugins/coreplugin/mainwindow.cpp | 10 | ||||
-rw-r--r-- | src/plugins/coreplugin/mainwindow.h | 3 |
8 files changed, 443 insertions, 2 deletions
diff --git a/src/plugins/coreplugin/coreimpl.cpp b/src/plugins/coreplugin/coreimpl.cpp index d072e8df09..99d76f3539 100644 --- a/src/plugins/coreplugin/coreimpl.cpp +++ b/src/plugins/coreplugin/coreimpl.cpp @@ -144,6 +144,11 @@ MimeDatabase *CoreImpl::mimeDatabase() const return m_mainwindow->mimeDatabase(); } +HelpManager *CoreImpl::helpManager() const +{ + return m_mainwindow->helpManager(); +} + QSettings *CoreImpl::settings(QSettings::Scope scope) const { return m_mainwindow->settings(scope); diff --git a/src/plugins/coreplugin/coreimpl.h b/src/plugins/coreplugin/coreimpl.h index 50a8a673fb..efd971f3b6 100644 --- a/src/plugins/coreplugin/coreimpl.h +++ b/src/plugins/coreplugin/coreimpl.h @@ -67,6 +67,7 @@ public: VCSManager *vcsManager() const; ModeManager *modeManager() const; MimeDatabase *mimeDatabase() const; + HelpManager *helpManager() const; QSettings *settings(QSettings::Scope scope = QSettings::UserScope) const; SettingsDatabase *settingsDatabase() const; diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro index d5b3064713..3b607d037b 100644 --- a/src/plugins/coreplugin/coreplugin.pro +++ b/src/plugins/coreplugin/coreplugin.pro @@ -6,6 +6,7 @@ QT += xml \ script \ svg \ sql +CONFIG += help include(../../qtcreatorplugin.pri) include(../../libs/utils/utils.pri) include(../../shared/scriptwrapper/scriptwrapper.pri) @@ -86,7 +87,8 @@ SOURCES += mainwindow.cpp \ editortoolbar.cpp \ ssh/ne7sshobject.cpp \ ssh/sshconnection.cpp \ - ssh/sshkeygenerator.cpp + ssh/sshkeygenerator.cpp \ + helpmanager.cpp HEADERS += mainwindow.h \ editmode.h \ @@ -171,7 +173,8 @@ HEADERS += mainwindow.h \ editortoolbar.h \ ssh/ne7sshobject.h \ ssh/sshconnection.h \ - ssh/sshkeygenerator.h + ssh/sshkeygenerator.h \ + helpmanager.h FORMS += dialogs/newdialog.ui \ actionmanager/commandmappings.ui \ diff --git a/src/plugins/coreplugin/helpmanager.cpp b/src/plugins/coreplugin/helpmanager.cpp new file mode 100644 index 0000000000..85cf89a1a5 --- /dev/null +++ b/src/plugins/coreplugin/helpmanager.cpp @@ -0,0 +1,321 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "helpmanager.h" + +#include "icore.h" + +#include <QtCore/QDebug> +#include <QtCore/QDir> +#include <QtCore/QFileInfo> +#include <QtCore/QStringList> + +#include <QtHelp/QHelpEngineCore> + +#include <QtSql/QSqlDatabase> +#include <QtSql/QSqlDriver> +#include <QtSql/QSqlError> +#include <QtSql/QSqlQuery> + +namespace Core { + +HelpManager *HelpManager::m_instance = 0; + +static const char linksForKeyQuery[] = "SELECT d.Title, f.Name, e.Name, " + "d.Name, a.Anchor FROM IndexTable a, FileNameTable d, FolderTable e, " + "NamespaceTable f WHERE a.FileId=d.FileId AND d.FolderId=e.Id AND " + "a.NamespaceId=f.Id AND a.Name='%1'"; + +// -- DbCleaner + +struct DbCleaner { + DbCleaner(const QString &dbName) + : name(dbName) {} + ~DbCleaner() { + QSqlDatabase::removeDatabase(name); + } + QString name; +}; + +// -- HelpManager + +HelpManager::HelpManager(QObject *parent) + : QObject(parent) + , m_needsSetup(true) + , m_helpEngine(0) +{ + Q_ASSERT(!m_instance); + m_instance = this; + + connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, + SLOT(setupHelpManager())); +} + +HelpManager::~HelpManager() +{ + delete m_helpEngine; + m_helpEngine = 0; + + m_instance = 0; +} + +HelpManager* HelpManager::instance() +{ + Q_ASSERT(m_instance); + return m_instance; +} + +QString HelpManager::collectionFilePath() +{ + const QFileInfo fi(Core::ICore::instance()->settings()->fileName()); + const QDir directory(fi.absolutePath() + QLatin1String("/qtcreator")); + if (!directory.exists()) + directory.mkpath(directory.absolutePath()); + return QDir::cleanPath(directory.absolutePath() + QLatin1String("/helpcollection.qhc")); +} + +void HelpManager::registerDocumentation(const QStringList &files) +{ + if (m_needsSetup) { + m_filesToRegister.append(files); + return; + } + + bool docsChanged = false; + foreach (const QString &file, files) { + const QString &nameSpace = m_helpEngine->namespaceName(file); + if (nameSpace.isEmpty()) + continue; + if (!m_helpEngine->registeredDocumentations().contains(nameSpace)) { + if (m_helpEngine->registerDocumentation(file)) { + docsChanged = true; + } else { + qWarning() << "Error registering namespace '" << nameSpace + << "' from file '" << file << "':" << m_helpEngine->error(); + } + } + } + if (docsChanged) + emit documentationChanged(); +} + +void HelpManager::unregisterDocumentation(const QStringList &nameSpaces) +{ + if (m_needsSetup) { + m_nameSpacesToUnregister.append(nameSpaces); + return; + } + + bool docsChanged = false; + foreach (const QString &nameSpace, nameSpaces) { + if (m_helpEngine->unregisterDocumentation(nameSpace)) { + docsChanged = true; + } else { + qWarning() << "Error unregistering namespace '" << nameSpace + << "' from file '" << m_helpEngine->documentationFileName(nameSpace) + << "': " << m_helpEngine->error(); + } + } + if (docsChanged) + emit documentationChanged(); +} + +QUrl buildQUrl(const QString &nameSpace, const QString &folder, + const QString &relFileName, const QString &anchor) +{ + QUrl url; + url.setScheme(QLatin1String("qthelp")); + url.setAuthority(nameSpace); + url.setPath(folder + QLatin1Char('/') + relFileName); + url.setFragment(anchor); + return url; +} + +// This should go into Qt 4.8 once we start using it for Qt Creator +QMap<QString, QUrl> HelpManager::linksForKeyword(const QString &key) const +{ + QMap<QString, QUrl> links; + if (m_needsSetup) + return links; + + const QLatin1String sqlite("QSQLITE"); + const QLatin1String name("HelpManager::linksForKeyword"); + + DbCleaner cleaner(name); + QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); + if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { + const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations(); + foreach (const QString &nameSpace, registeredDocs) { + db.setDatabaseName(m_helpEngine->documentationFileName(nameSpace)); + if (db.open()) { + QSqlQuery query = QSqlQuery(db); + query.setForwardOnly(true); + query.exec(QString::fromLatin1(linksForKeyQuery).arg(key)); + while (query.next()) { + QString title = query.value(0).toString(); + if (title.isEmpty()) // generate a title + corresponding path + title = key + QLatin1String(" : ") + query.value(3).toString(); + links.insertMulti(title, buildQUrl(query.value(1).toString(), + query.value(2).toString(), query.value(3).toString(), + query.value(4).toString())); + } + } + } + } + return links; +} + +QMap<QString, QUrl> HelpManager::linksForIdentifier(const QString &id) const +{ + if (m_needsSetup) + return QMap<QString, QUrl>(); + return m_helpEngine->linksForIdentifier(id); +} + +// This should go into Qt 4.8 once we start using it for Qt Creator +QStringList HelpManager::findKeywords(const QString &key, int maxHits) const +{ + QStringList keywords; + if (m_needsSetup) + return keywords; + + const QLatin1String sqlite("QSQLITE"); + const QLatin1String name("HelpManager::findKeywords"); + + DbCleaner cleaner(name); + QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); + if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { + const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations(); + foreach (const QString &nameSpace, registeredDocs) { + db.setDatabaseName(m_helpEngine->documentationFileName(nameSpace)); + if (db.open()) { + QSqlQuery query = QSqlQuery(db); + query.setForwardOnly(true); + query.exec(QString::fromLatin1("SELECT DISTINCT Name FROM " + "IndexTable WHERE Name LIKE '%%1%'").arg(key)); + while (query.next()) { + const QString &key = query.value(0).toString(); + if (!key.isEmpty()) { + keywords.append(key); + if (keywords.count() == maxHits) + return keywords; + } + } + } + } + } + return keywords; +} + +QUrl HelpManager::findFile(const QUrl &url) const +{ + if (m_needsSetup) + return QUrl(); + return m_helpEngine->findFile(url); +} + +void HelpManager::handleHelpRequest(const QString &url) +{ + emit helpRequested(QUrl(url)); +} + +QStringList HelpManager::registeredNamespaces() const +{ + if (m_needsSetup) + return QStringList(); + return m_helpEngine->registeredDocumentations(); +} + +QString HelpManager::namespaceFromFile(const QString &file) const +{ + if (m_needsSetup) + return QString(); + return m_helpEngine->namespaceName(file); +} + +QString HelpManager::fileFromNamespace(const QString &nameSpace) const +{ + if (m_needsSetup) + return QString(); + return m_helpEngine->documentationFileName(nameSpace); +} + +// -- private slots + +void HelpManager::setupHelpManager() +{ + if (!m_needsSetup) + return; + m_needsSetup = false; + + m_helpEngine = new QHelpEngineCore(collectionFilePath(), this); + m_helpEngine->setAutoSaveFilter(false); + m_helpEngine->setCurrentFilter(tr("Unfiltered")); + m_helpEngine->setupData(); + + verifyDocumenation(); + + if (!m_nameSpacesToUnregister.isEmpty()) { + unregisterDocumentation(m_nameSpacesToUnregister); + m_nameSpacesToUnregister.clear(); + } + + // this might come from the installer + const QLatin1String key("AddedDocs"); + const QString &addedDocs = m_helpEngine->customValue(key).toString(); + if (!addedDocs.isEmpty()) { + m_helpEngine->removeCustomValue(key); + m_filesToRegister += addedDocs.split(QLatin1Char(';')); + } + + if (!m_filesToRegister.isEmpty()) { + registerDocumentation(m_filesToRegister); + m_filesToRegister.clear(); + } + + emit setupFinished(); +} + +// -- private + +void HelpManager::verifyDocumenation() +{ + QStringList nameSpacesToUnregister; + const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations(); + foreach (const QString &nameSpace, registeredDocs) { + const QString &file = m_helpEngine->documentationFileName(nameSpace); + if (!QFileInfo(file).exists()) + nameSpacesToUnregister.append(nameSpace); + } + + if (!nameSpacesToUnregister.isEmpty()) + unregisterDocumentation(nameSpacesToUnregister); +} + +} // Core diff --git a/src/plugins/coreplugin/helpmanager.h b/src/plugins/coreplugin/helpmanager.h new file mode 100644 index 0000000000..7df6c55659 --- /dev/null +++ b/src/plugins/coreplugin/helpmanager.h @@ -0,0 +1,96 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef HELPMANAGER_H +#define HELPMANAGER_H + +#include "core_global.h" + +#include <QtCore/QMap> +#include <QtCore/QObject> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QUrl> +#include <QtCore/QVariant> + +QT_FORWARD_DECLARE_CLASS(QHelpEngineCore) +QT_FORWARD_DECLARE_CLASS(QSqlQuery) + +namespace Core { + +class CORE_EXPORT HelpManager : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(HelpManager) + +public: + explicit HelpManager(QObject *parent = 0); + virtual ~HelpManager(); + + static HelpManager* instance(); + static QString collectionFilePath(); + + void registerDocumentation(const QStringList &fileNames); + void unregisterDocumentation(const QStringList &nameSpaces); + + QMap<QString, QUrl> linksForKeyword(const QString &key) const; + QMap<QString, QUrl> linksForIdentifier(const QString &id) const; + QStringList findKeywords(const QString &key, int maxHits = INT_MAX) const; + + QUrl findFile(const QUrl &url) const; + void handleHelpRequest(const QString &url); + + QStringList registeredNamespaces() const; + QString namespaceFromFile(const QString &file) const; + QString fileFromNamespace(const QString &nameSpace) const; + +signals: + void setupFinished(); + void documentationChanged(); + void helpRequested(const QUrl &url); + +private slots: + void setupHelpManager(); + +private: + void verifyDocumenation(); + +private: + bool m_needsSetup; + QHelpEngineCore *m_helpEngine; + + QStringList m_filesToRegister; + QStringList m_nameSpacesToUnregister; + + static HelpManager *m_instance; +}; + +} // Core + +#endif // HELPMANAGER_H diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index cae3da1b4d..4eb3c89718 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -50,6 +50,7 @@ namespace Core { class ActionManager; class EditorManager; class FileManager; +class HelpManager; class IContext; class MessageManager; class MimeDatabase; @@ -96,6 +97,7 @@ public: virtual VCSManager *vcsManager() const = 0; virtual ModeManager *modeManager() const = 0; virtual MimeDatabase *mimeDatabase() const = 0; + virtual HelpManager *helpManager() const = 0; virtual QSettings *settings(QSettings::Scope scope = QSettings::UserScope) const = 0; virtual SettingsDatabase *settingsDatabase() const = 0; diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index ed1d48afb8..1555395c74 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -37,6 +37,7 @@ #include "fancytabwidget.h" #include "filemanager.h" #include "generalsettings.h" +#include "helpmanager.h" #include "ifilefactory.h" #include "messagemanager.h" #include "modemanager.h" @@ -132,6 +133,7 @@ MainWindow::MainWindow() : m_statusBarManager(0), m_modeManager(0), m_mimeDatabase(new MimeDatabase), + m_helpManager(new HelpManager), m_navigationWidget(0), m_rightPaneWidget(0), m_versionDialog(0), @@ -288,6 +290,9 @@ MainWindow::~MainWindow() m_modeManager = 0; delete m_mimeDatabase; m_mimeDatabase = 0; + + delete m_helpManager; + m_helpManager = 0; } bool MainWindow::init(QString *errorMessage) @@ -1011,6 +1016,11 @@ MimeDatabase *MainWindow::mimeDatabase() const return m_mimeDatabase; } +HelpManager *MainWindow::helpManager() const +{ + return m_helpManager; +} + IContext *MainWindow::contextObject(QWidget *widget) { return m_contextWidgets.value(widget); diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 60b911ba1d..3b890439b0 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -52,6 +52,7 @@ class ActionManager; class StatusBarWidget; class EditorManager; class FileManager; +class HelpManager; class IContext; class IWizard; class MessageManager; @@ -107,6 +108,7 @@ public: Core::VariableManager *variableManager() const; Core::ModeManager *modeManager() const; Core::MimeDatabase *mimeDatabase() const; + Core::HelpManager *helpManager() const; VCSManager *vcsManager() const; QSettings *settings(QSettings::Scope scope) const; @@ -193,6 +195,7 @@ private: StatusBarManager *m_statusBarManager; ModeManager *m_modeManager; MimeDatabase *m_mimeDatabase; + HelpManager *m_helpManager; FancyTabWidget *m_modeStack; NavigationWidget *m_navigationWidget; RightPaneWidget *m_rightPaneWidget; |