summaryrefslogtreecommitdiff
path: root/src/plugins/coreplugin
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/coreplugin')
-rw-r--r--src/plugins/coreplugin/coreimpl.cpp5
-rw-r--r--src/plugins/coreplugin/coreimpl.h1
-rw-r--r--src/plugins/coreplugin/coreplugin.pro7
-rw-r--r--src/plugins/coreplugin/helpmanager.cpp321
-rw-r--r--src/plugins/coreplugin/helpmanager.h96
-rw-r--r--src/plugins/coreplugin/icore.h2
-rw-r--r--src/plugins/coreplugin/mainwindow.cpp10
-rw-r--r--src/plugins/coreplugin/mainwindow.h3
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 &registeredDocs = 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 &registeredDocs = 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 &registeredDocs = 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;