An error occurred while loading the file. Please try again.
-
Jocelyn Turcotte authored
To match other modules example directory structures we should deploy our examples in a directory matching the module name, webengine and webenginewidgets in our case. qmake uses the relative directory of each example up to the upper "examples" directory to decide where they will be deployed when running the sources install target. Change-Id: I59ce7ff8a30f98fad20064c7eecf72b784f1d275 Reviewed-by:
Pierre Rossi <pierre.rossi@gmail.com>
482a89fb
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Assistant of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qhelpcollectionhandler_p.h"
#include "qhelp_global.h"
#include "qhelpdbreader_p.h"
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
#include <QtSql/QSqlError>
#include <QtSql/QSqlDriver>
QT_BEGIN_NAMESPACE
QHelpCollectionHandler::QHelpCollectionHandler(const QString &collectionFile, QObject *parent)
: QObject(parent)
, m_dbOpened(false)
, m_collectionFile(collectionFile)
, m_connectionName(QString())
{
QFileInfo fi(m_collectionFile);
if (!fi.isAbsolute())
m_collectionFile = fi.absoluteFilePath();
m_query.clear();
}
QHelpCollectionHandler::~QHelpCollectionHandler()
{
m_query.clear();
if (m_dbOpened)
QSqlDatabase::removeDatabase(m_connectionName);
}
bool QHelpCollectionHandler::isDBOpened()
{
if (m_dbOpened)
return true;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
emit error(tr("The collection file '%1' is not set up yet.").
arg(m_collectionFile));
return false;
}
QString QHelpCollectionHandler::collectionFile() const
{
return m_collectionFile;
}
bool QHelpCollectionHandler::openCollectionFile()
{
if (m_dbOpened)
return m_dbOpened;
m_connectionName = QHelpGlobal::uniquifyConnectionName(
QLatin1String("QHelpCollectionHandler"), this);
bool openingOk = true;
{
QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"),
m_connectionName);
if (db.driver()
&& db.driver()->lastError().type() == QSqlError::ConnectionError) {
emit error(tr("Cannot load sqlite database driver."));
return false;
}
db.setDatabaseName(collectionFile());
openingOk = db.open();
if (openingOk)
m_query = QSqlQuery(db);
}
if (!openingOk) {
QSqlDatabase::removeDatabase(m_connectionName);
emit error(tr("Cannot open collection file: %1").arg(collectionFile()));
return false;
}
m_query.exec(QLatin1String("PRAGMA synchronous=OFF"));
m_query.exec(QLatin1String("PRAGMA cache_size=3000"));
m_query.exec(QLatin1String("SELECT COUNT(*) FROM sqlite_master WHERE TYPE=\'table\'"
"AND Name=\'NamespaceTable\'"));
m_query.next();
if (m_query.value(0).toInt() < 1) {
if (!createTables(&m_query)) {
emit error(tr("Cannot create tables in file %1.").arg(collectionFile()));
return false;
}
}
m_dbOpened = true;
return m_dbOpened;
}
bool QHelpCollectionHandler::copyCollectionFile(const QString &fileName)
{
if (!m_dbOpened)
return false;
QFileInfo fi(fileName);
if (fi.exists()) {
emit error(tr("The collection file '%1' already exists.").
arg(fileName));
return false;
}
if (!fi.absoluteDir().exists() && !QDir().mkpath(fi.absolutePath())) {
emit error(tr("Cannot create directory: %1").arg(fi.absolutePath()));
return false;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
}
QString colFile = fi.absoluteFilePath();
QString connectionName = QHelpGlobal::uniquifyConnectionName(
QLatin1String("QHelpCollectionHandlerCopy"), this);
QSqlQuery *copyQuery = 0;
bool openingOk = true;
{
QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), connectionName);
db.setDatabaseName(colFile);
openingOk = db.open();
if (openingOk)
copyQuery = new QSqlQuery(db);
}
if (!openingOk) {
emit error(tr("Cannot open collection file: %1").arg(colFile));
return false;
}
copyQuery->exec(QLatin1String("PRAGMA synchronous=OFF"));
copyQuery->exec(QLatin1String("PRAGMA cache_size=3000"));
if (!createTables(copyQuery)) {
emit error(tr("Cannot copy collection file: %1").arg(colFile));
return false;
}
QString oldBaseDir = QFileInfo(collectionFile()).absolutePath();
QString oldFilePath;
QFileInfo newColFi(colFile);
m_query.exec(QLatin1String("SELECT Name, FilePath FROM NamespaceTable"));
while (m_query.next()) {
copyQuery->prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?, ?)"));
copyQuery->bindValue(0, m_query.value(0).toString());
oldFilePath = m_query.value(1).toString();
if (!QDir::isAbsolutePath(oldFilePath))
oldFilePath = oldBaseDir + QDir::separator() + oldFilePath;
copyQuery->bindValue(1, newColFi.absoluteDir().relativeFilePath(oldFilePath));
copyQuery->exec();
}
m_query.exec(QLatin1String("SELECT NamespaceId, Name FROM FolderTable"));
while (m_query.next()) {
copyQuery->prepare(QLatin1String("INSERT INTO FolderTable VALUES(NULL, ?, ?)"));
copyQuery->bindValue(0, m_query.value(0).toString());
copyQuery->bindValue(1, m_query.value(1).toString());
copyQuery->exec();
}
m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
while (m_query.next()) {
copyQuery->prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
copyQuery->bindValue(0, m_query.value(0).toString());
copyQuery->exec();
}
m_query.exec(QLatin1String("SELECT Name FROM FilterNameTable"));
while (m_query.next()) {
copyQuery->prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
copyQuery->bindValue(0, m_query.value(0).toString());
copyQuery->exec();
}
m_query.exec(QLatin1String("SELECT NameId, FilterAttributeId FROM FilterTable"));
while (m_query.next()) {
copyQuery->prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
copyQuery->bindValue(0, m_query.value(0).toInt());
copyQuery->bindValue(1, m_query.value(1).toInt());
copyQuery->exec();
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
}
m_query.exec(QLatin1String("SELECT Key, Value FROM SettingsTable"));
while (m_query.next()) {
if (m_query.value(0).toString() == QLatin1String("CluceneSearchNamespaces"))
continue;
copyQuery->prepare(QLatin1String("INSERT INTO SettingsTable VALUES(?, ?)"));
copyQuery->bindValue(0, m_query.value(0).toString());
copyQuery->bindValue(1, m_query.value(1));
copyQuery->exec();
}
copyQuery->clear();
delete copyQuery;
QSqlDatabase::removeDatabase(connectionName);
return true;
}
bool QHelpCollectionHandler::createTables(QSqlQuery *query)
{
QStringList tables;
tables << QLatin1String("CREATE TABLE NamespaceTable ("
"Id INTEGER PRIMARY KEY, "
"Name TEXT, "
"FilePath TEXT )")
<< QLatin1String("CREATE TABLE FolderTable ("
"Id INTEGER PRIMARY KEY, "
"NamespaceId INTEGER, "
"Name TEXT )")
<< QLatin1String("CREATE TABLE FilterAttributeTable ("
"Id INTEGER PRIMARY KEY, "
"Name TEXT )")
<< QLatin1String("CREATE TABLE FilterNameTable ("
"Id INTEGER PRIMARY KEY, "
"Name TEXT )")
<< QLatin1String("CREATE TABLE FilterTable ("
"NameId INTEGER, "
"FilterAttributeId INTEGER )")
<< QLatin1String("CREATE TABLE SettingsTable ("
"Key TEXT PRIMARY KEY, "
"Value BLOB )");
foreach (const QString &q, tables) {
if (!query->exec(q))
return false;
}
return true;
}
QStringList QHelpCollectionHandler::customFilters() const
{
QStringList list;
if (m_dbOpened) {
m_query.exec(QLatin1String("SELECT Name FROM FilterNameTable"));
while (m_query.next())
list.append(m_query.value(0).toString());
}
return list;
}
bool QHelpCollectionHandler::removeCustomFilter(const QString &filterName)
{
if (!isDBOpened() || filterName.isEmpty())
return false;
int filterNameId = -1;
m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
m_query.bindValue(0, filterName);
m_query.exec();
if (m_query.next())
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
filterNameId = m_query.value(0).toInt();
if (filterNameId < 0) {
emit error(tr("Unknown filter '%1'.").arg(filterName));
return false;
}
m_query.prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
m_query.bindValue(0, filterNameId);
m_query.exec();
m_query.prepare(QLatin1String("DELETE FROM FilterNameTable WHERE Id=?"));
m_query.bindValue(0, filterNameId);
m_query.exec();
return true;
}
bool QHelpCollectionHandler::addCustomFilter(const QString &filterName,
const QStringList &attributes)
{
if (!isDBOpened() || filterName.isEmpty())
return false;
int nameId = -1;
m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
m_query.bindValue(0, filterName);
m_query.exec();
if (m_query.next())
nameId = m_query.value(0).toInt();
m_query.exec(QLatin1String("SELECT Id, Name FROM FilterAttributeTable"));
QStringList idsToInsert = attributes;
QMap<QString, int> attributeMap;
while (m_query.next()) {
attributeMap.insert(m_query.value(1).toString(),
m_query.value(0).toInt());
if (idsToInsert.contains(m_query.value(1).toString()))
idsToInsert.removeAll(m_query.value(1).toString());
}
foreach (const QString &id, idsToInsert) {
m_query.prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
m_query.bindValue(0, id);
m_query.exec();
attributeMap.insert(id, m_query.lastInsertId().toInt());
}
if (nameId < 0) {
m_query.prepare(QLatin1String("INSERT INTO FilterNameTable VALUES(NULL, ?)"));
m_query.bindValue(0, filterName);
if (m_query.exec())
nameId = m_query.lastInsertId().toInt();
}
if (nameId < 0) {
emit error(tr("Cannot register filter %1.").arg(filterName));
return false;
}
m_query.prepare(QLatin1String("DELETE FROM FilterTable WHERE NameId=?"));
m_query.bindValue(0, nameId);
m_query.exec();
foreach (const QString &att, attributes) {
m_query.prepare(QLatin1String("INSERT INTO FilterTable VALUES(?, ?)"));
m_query.bindValue(0, nameId);
m_query.bindValue(1, attributeMap[att]);
if (!m_query.exec())
return false;
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
}
return true;
}
QHelpCollectionHandler::DocInfoList QHelpCollectionHandler::registeredDocumentations() const
{
DocInfoList list;
if (m_dbOpened) {
m_query.exec(QLatin1String("SELECT a.Name, a.FilePath, b.Name "
"FROM NamespaceTable a, FolderTable b WHERE a.Id=b.NamespaceId"));
while (m_query.next()) {
DocInfo info;
info.fileName = m_query.value(1).toString();
info.folderName = m_query.value(2).toString();
info.namespaceName = m_query.value(0).toString();
list.append(info);
}
}
return list;
}
bool QHelpCollectionHandler::registerDocumentation(const QString &fileName)
{
if (!isDBOpened())
return false;
QHelpDBReader reader(fileName, QHelpGlobal::uniquifyConnectionName(
QLatin1String("QHelpCollectionHandler"), this), 0);
if (!reader.init()) {
emit error(tr("Cannot open documentation file %1.").arg(fileName));
return false;
}
QString ns = reader.namespaceName();
if (ns.isEmpty()) {
emit error(tr("Invalid documentation file '%1'.").arg(fileName));
return false;
}
int nsId = registerNamespace(ns, fileName);
if (nsId < 1)
return false;
if (!registerVirtualFolder(reader.virtualFolder(), nsId))
return false;
addFilterAttributes(reader.filterAttributes());
foreach (const QString &filterName, reader.customFilters())
addCustomFilter(filterName, reader.filterAttributes(filterName));
optimizeDatabase(fileName);
return true;
}
bool QHelpCollectionHandler::unregisterDocumentation(const QString &namespaceName)
{
if (!isDBOpened())
return false;
m_query.prepare(QLatin1String("SELECT Id FROM NamespaceTable WHERE Name=?"));
m_query.bindValue(0, namespaceName);
m_query.exec();
int nsId = -1;
if (m_query.next())
nsId = m_query.value(0).toInt();
if (nsId < 0) {
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
emit error(tr("The namespace %1 was not registered.").arg(namespaceName));
return false;
}
m_query.prepare(QLatin1String("DELETE FROM NamespaceTable WHERE Id=?"));
m_query.bindValue(0, nsId);
m_query.exec();
m_query.prepare(QLatin1String("DELETE FROM FolderTable WHERE NamespaceId=?"));
m_query.bindValue(0, nsId);
return m_query.exec();
}
bool QHelpCollectionHandler::removeCustomValue(const QString &key)
{
if (!isDBOpened())
return false;
m_query.prepare(QLatin1String("DELETE FROM SettingsTable WHERE Key=?"));
m_query.bindValue(0, key);
return m_query.exec();
}
QVariant QHelpCollectionHandler::customValue(const QString &key,
const QVariant &defaultValue) const
{
QVariant value = defaultValue;
if (m_dbOpened) {
m_query.prepare(QLatin1String("SELECT COUNT(Key) FROM SettingsTable WHERE Key=?"));
m_query.bindValue(0, key);
if (!m_query.exec() || !m_query.next() || !m_query.value(0).toInt()) {
m_query.clear();
return defaultValue;
}
m_query.clear();
m_query.prepare(QLatin1String("SELECT Value FROM SettingsTable WHERE Key=?"));
m_query.bindValue(0, key);
if (m_query.exec() && m_query.next())
value = m_query.value(0);
m_query.clear();
}
return value;
}
bool QHelpCollectionHandler::setCustomValue(const QString &key,
const QVariant &value)
{
if (!isDBOpened())
return false;
m_query.prepare(QLatin1String("SELECT Value FROM SettingsTable WHERE Key=?"));
m_query.bindValue(0, key);
m_query.exec();
if (m_query.next()) {
m_query.prepare(QLatin1String("UPDATE SettingsTable SET Value=? where Key=?"));
m_query.bindValue(0, value);
m_query.bindValue(1, key);
}
else {
m_query.prepare(QLatin1String("INSERT INTO SettingsTable VALUES(?, ?)"));
m_query.bindValue(0, key);
m_query.bindValue(1, value);
}
return m_query.exec();
}
bool QHelpCollectionHandler::addFilterAttributes(const QStringList &attributes)
{
if (!isDBOpened())
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
return false;
m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
QSet<QString> atts;
while (m_query.next())
atts.insert(m_query.value(0).toString());
foreach (const QString &s, attributes) {
if (!atts.contains(s)) {
m_query.prepare(QLatin1String("INSERT INTO FilterAttributeTable VALUES(NULL, ?)"));
m_query.bindValue(0, s);
m_query.exec();
}
}
return true;
}
QStringList QHelpCollectionHandler::filterAttributes() const
{
QStringList list;
if (m_dbOpened) {
m_query.exec(QLatin1String("SELECT Name FROM FilterAttributeTable"));
while (m_query.next())
list.append(m_query.value(0).toString());
}
return list;
}
QStringList QHelpCollectionHandler::filterAttributes(const QString &filterName) const
{
QStringList list;
if (m_dbOpened) {
m_query.prepare(QLatin1String("SELECT a.Name FROM FilterAttributeTable a, "
"FilterTable b, FilterNameTable c WHERE a.Id=b.FilterAttributeId "
"AND b.NameId=c.Id AND c.Name=?"));
m_query.bindValue(0, filterName);
m_query.exec();
while (m_query.next())
list.append(m_query.value(0).toString());
}
return list;
}
int QHelpCollectionHandler::registerNamespace(const QString &nspace, const QString &fileName)
{
m_query.prepare(QLatin1String("SELECT COUNT(Id) FROM NamespaceTable WHERE Name=?"));
m_query.bindValue(0, nspace);
m_query.exec();
while (m_query.next()) {
if (m_query.value(0).toInt() > 0) {
emit error(tr("Namespace %1 already exists.").arg(nspace));
return -1;
}
}
QFileInfo fi(m_collectionFile);
m_query.prepare(QLatin1String("INSERT INTO NamespaceTable VALUES(NULL, ?, ?)"));
m_query.bindValue(0, nspace);
m_query.bindValue(1, fi.absoluteDir().relativeFilePath(fileName));
int namespaceId = -1;
if (m_query.exec())
namespaceId = m_query.lastInsertId().toInt();
if (namespaceId < 1) {
emit error(tr("Cannot register namespace '%1'.").arg(nspace));
return -1;
}
return namespaceId;
}
bool QHelpCollectionHandler::registerVirtualFolder(const QString &folderName, int namespaceId)
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
{
m_query.prepare(QLatin1String("INSERT INTO FolderTable VALUES(NULL, ?, ?)"));
m_query.bindValue(0, namespaceId);
m_query.bindValue(1, folderName);
return m_query.exec();
}
void QHelpCollectionHandler::optimizeDatabase(const QString &fileName)
{
if (!QFile::exists(fileName))
return;
{ // according to removeDatabase() documentation
QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), QLatin1String("optimize"));
db.setDatabaseName(fileName);
if (!db.open()) {
QSqlDatabase::removeDatabase(QLatin1String("optimize"));
emit error(tr("Cannot open database '%1' to optimize.").arg(fileName));
return;
}
QSqlQuery query(db);
db.exec(QLatin1String("PRAGMA synchronous=OFF"));
db.exec(QLatin1String("PRAGMA cache_size=3000"));
db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS NameIndex ON IndexTable(Name)"));
db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS FileNameIndex ON FileNameTable(Name)"));
db.exec(QLatin1String("CREATE INDEX IF NOT EXISTS FileIdIndex ON FileNameTable(FileId)"));
db.close();
}
QSqlDatabase::removeDatabase(QLatin1String("optimize"));
}
QT_END_NAMESPACE