From 2f9dd400868f7de34581d12554ca79ea143ce4f3 Mon Sep 17 00:00:00 2001 From: Jerzy Kozera Date: Sat, 8 Oct 2016 05:42:27 +0200 Subject: [PATCH 1/8] qmake: Fix missing defines causing memory corruption (fixes #595) (#616) Missing USE_APPINDICATOR in libs/core/ was causing the MainWindow class declaration to be truncated, thus causing memory corruption when later used with the full definition in libs/ui/. --- qmake/common.pri | 7 +++++++ src/libs/ui/ui.pri | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/qmake/common.pri b/qmake/common.pri index 4e26c76b..ac08e59f 100644 --- a/qmake/common.pri +++ b/qmake/common.pri @@ -63,3 +63,10 @@ CONFIG(zeal_portable) { unix:!macx { isEmpty(PREFIX): PREFIX = /usr } + +unix:!macx:packagesExist(appindicator-0.1) { + CONFIG += link_pkgconfig + PKGCONFIG += appindicator-0.1 gtk+-2.0 + DEFINES += USE_APPINDICATOR + message("AppIndicator support: Yes.") +} diff --git a/src/libs/ui/ui.pri b/src/libs/ui/ui.pri index e3933b07..ca5169df 100644 --- a/src/libs/ui/ui.pri +++ b/src/libs/ui/ui.pri @@ -2,13 +2,6 @@ ZEAL_LIB_NAME = Ui QT += widgets -unix:!macx:packagesExist(appindicator-0.1) { - CONFIG += link_pkgconfig - PKGCONFIG += appindicator-0.1 gtk+-2.0 - DEFINES += USE_APPINDICATOR - message("AppIndicator support: Yes.") -} - # QxtGlobalShortcut dependencies unix:!macx { QT += x11extras From caff8628059ef872961a7868a5eef19ba87a5cbf Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Sun, 9 Oct 2016 01:01:04 -0400 Subject: [PATCH 2/8] core: Reject no-scheme URLs on a local file system (fixes #532) (#620) This change adds back a custom network access manager, that was removed as a fix for #474. Although this time URL validation is much more simple. --- src/libs/core/application.cpp | 4 +-- src/libs/core/networkaccessmanager.cpp | 44 +++++++++++++++++++++++++ src/libs/core/networkaccessmanager.h | 45 ++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 src/libs/core/networkaccessmanager.cpp create mode 100644 src/libs/core/networkaccessmanager.h diff --git a/src/libs/core/application.cpp b/src/libs/core/application.cpp index c2f500c5..d39d9033 100644 --- a/src/libs/core/application.cpp +++ b/src/libs/core/application.cpp @@ -23,6 +23,7 @@ #include "application.h" #include "extractor.h" +#include "networkaccessmanager.h" #include "settings.h" #include @@ -35,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -59,7 +59,7 @@ Application::Application(QObject *parent) : m_instance = this; m_settings = new Settings(this); - m_networkManager = new QNetworkAccessManager(this); + m_networkManager = new NetworkAccessManager(this); // Extractor setup m_extractorThread = new QThread(this); diff --git a/src/libs/core/networkaccessmanager.cpp b/src/libs/core/networkaccessmanager.cpp new file mode 100644 index 00000000..df1bd0a2 --- /dev/null +++ b/src/libs/core/networkaccessmanager.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Oleg Shparber +** Contact: https://go.zealdocs.org/l/contact +** +** This file is part of Zeal. +** +** Zeal is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** Zeal is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Zeal. If not, see . +** +****************************************************************************/ + +#include "networkaccessmanager.h" + +#include + +using namespace Zeal::Core; + +NetworkAccessManager::NetworkAccessManager(QObject *parent) + : QNetworkAccessManager(parent) +{ +} + +QNetworkReply *NetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, + const QNetworkRequest &request, + QIODevice *outgoingData) +{ + // Detect URLs without schema, and prevent them from being requested on a local filesytem. + const QUrl url = request.url(); + if (url.scheme() == QLatin1String("file") && !url.host().isEmpty()) + return QNetworkAccessManager::createRequest(GetOperation, QNetworkRequest(), outgoingData); + + return QNetworkAccessManager::createRequest(op, request, outgoingData); +} diff --git a/src/libs/core/networkaccessmanager.h b/src/libs/core/networkaccessmanager.h new file mode 100644 index 00000000..ec11ad6c --- /dev/null +++ b/src/libs/core/networkaccessmanager.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Oleg Shparber +** Contact: https://go.zealdocs.org/l/contact +** +** This file is part of Zeal. +** +** Zeal is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** Zeal is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Zeal. If not, see . +** +****************************************************************************/ + +#ifndef ZEAL_CORE_NETWORKACCESSMANAGER_H +#define ZEAL_CORE_NETWORKACCESSMANAGER_H + +#include + +namespace Zeal { +namespace Core { + +class NetworkAccessManager : public QNetworkAccessManager +{ + Q_OBJECT +public: + NetworkAccessManager(QObject *parent = nullptr); + +protected: + QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, + QIODevice *outgoingData = nullptr) override; +}; + +} // namespace Core +} // namespace Zeal + +#endif // ZEAL_CORE_NETWORKACCESSMANAGER_H From dd5ebd2d0a228715ef412abeab0e6bd18e781690 Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Sun, 9 Oct 2016 11:24:25 -0400 Subject: [PATCH 3/8] doc: Fix menu path to the docset manager --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05b87eae..65b67471 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Get binary builds for Windows and Linux from the [download page](https://zealdoc ## How to use -After installing Zeal, you need to download docsets. Go to *File->Options->Docsets*, select the ones you want, and click the *Download* button. +After installing Zeal, you need to download docsets. Go to *Tools->Docsets*, select the ones you want, and click the *Download* button. ## How to compile From ba8c3ad00efc3593f50ba805be400b7e8518e4f5 Mon Sep 17 00:00:00 2001 From: Jerzy Kozera Date: Sun, 9 Oct 2016 19:38:08 +0200 Subject: [PATCH 4/8] ui: Fix docset removal on Windows (fixes #621) (#623) Docsets need to be removed from the registry first, to avoid rename() failing when files are in use. --- src/libs/ui/docsetsdialog.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libs/ui/docsetsdialog.cpp b/src/libs/ui/docsetsdialog.cpp index bd869e15..a034418f 100644 --- a/src/libs/ui/docsetsdialog.cpp +++ b/src/libs/ui/docsetsdialog.cpp @@ -693,12 +693,20 @@ void DocsetsDialog::removeDocset(const QString &name) const QString tmpPath = docsetPath + QLatin1String(".deleteme.") + QString::number(QDateTime::currentMSecsSinceEpoch()); - // Rename first to allow simultaneous installation. - // TODO: Check for error - QDir().rename(docsetPath, tmpPath); - + // Remove from registry first to avoid renaming files in use on Windows. m_docsetRegistry->remove(name); + // Rename first to allow simultaneous installation. + if (!QDir().rename(docsetPath, tmpPath)) { + const QString error = tr("Cannot delete docset %1! Please try closing other " + "applications first, as they may be accessing the docset " + "files.").arg(title); + QMessageBox::warning(this, QStringLiteral("Zeal"), error); + m_docsetsBeingDeleted.removeOne(name); + m_docsetRegistry->addDocset(docsetPath); + return; + } + QFuture future = QtConcurrent::run([tmpPath] { return QDir(tmpPath).removeRecursively(); }); From 2d2a561c419bd118d0e5060bd26cde6749a3dd7c Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Sun, 9 Oct 2016 15:38:19 -0400 Subject: [PATCH 5/8] ui: Fix a race condition when removing docsets (#624) --- src/libs/ui/docsetsdialog.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libs/ui/docsetsdialog.cpp b/src/libs/ui/docsetsdialog.cpp index a034418f..c35ee9bb 100644 --- a/src/libs/ui/docsetsdialog.cpp +++ b/src/libs/ui/docsetsdialog.cpp @@ -707,12 +707,7 @@ void DocsetsDialog::removeDocset(const QString &name) return; } - QFuture future = QtConcurrent::run([tmpPath] { - return QDir(tmpPath).removeRecursively(); - }); - QFutureWatcher *watcher = new QFutureWatcher(); - watcher->setFuture(future); connect(watcher, &QFutureWatcher::finished, [=] { if (!watcher->result()) { QMessageBox::warning(this, QStringLiteral("Zeal"), @@ -727,6 +722,10 @@ void DocsetsDialog::removeDocset(const QString &name) m_docsetsBeingDeleted.removeOne(name); }); + + watcher->setFuture(QtConcurrent::run([tmpPath] { + return QDir(tmpPath).removeRecursively(); + })); } void DocsetsDialog::updateCombinedProgress() From ac0d19e5fea15a2ac8c1e78bab58802ba938e5bd Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Sun, 9 Oct 2016 18:52:02 -0400 Subject: [PATCH 6/8] ui: Fix 'Select All' selection in the docset manager (#625) This fixes duplicated items in selection models because of multiple columns. --- src/libs/ui/docsetsdialog.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/ui/docsetsdialog.cpp b/src/libs/ui/docsetsdialog.cpp index c35ee9bb..a0a8a0e6 100644 --- a/src/libs/ui/docsetsdialog.cpp +++ b/src/libs/ui/docsetsdialog.cpp @@ -98,7 +98,7 @@ DocsetsDialog::DocsetsDialog(Core::Application *app, QWidget *parent) : [this, selectionModel]() { ui->removeDocsetsButton->setEnabled(selectionModel->hasSelection()); - for (const QModelIndex &index : selectionModel->selectedIndexes()) { + for (const QModelIndex &index : selectionModel->selectedRows()) { if (index.data(ListModel::UpdateAvailableRole).toBool()) { ui->updateSelectedDocsetsButton->setEnabled(true); return; @@ -135,7 +135,7 @@ DocsetsDialog::DocsetsDialog(Core::Application *app, QWidget *parent) : selectionModel = ui->availableDocsetList->selectionModel(); connect(selectionModel, &QItemSelectionModel::selectionChanged, [this, selectionModel]() { - for (const QModelIndex &index : selectionModel->selectedIndexes()) { + for (const QModelIndex &index : selectionModel->selectedRows()) { if (!index.data(ProgressItemDelegate::ShowProgressRole).toBool()) { ui->downloadDocsetsButton->setEnabled(true); return; @@ -217,7 +217,7 @@ void DocsetsDialog::addDashFeed() void DocsetsDialog::updateSelectedDocsets() { - for (const QModelIndex &index : ui->installedDocsetList->selectionModel()->selectedIndexes()) { + for (const QModelIndex &index : ui->installedDocsetList->selectionModel()->selectedRows()) { if (!index.data(Registry::ListModel::UpdateAvailableRole).toBool()) continue; @@ -245,7 +245,7 @@ void DocsetsDialog::removeSelectedDocsets() int ret; - const QModelIndexList selectedIndexes = selectonModel->selectedIndexes(); + const QModelIndexList selectedIndexes = selectonModel->selectedRows(); if (selectedIndexes.size() == 1) { const QString docsetTitle = selectedIndexes.first().data().toString(); ret = QMessageBox::question(this, QStringLiteral("Zeal"), @@ -286,7 +286,7 @@ void DocsetsDialog::updateDocsetFilter(const QString &filterString) void DocsetsDialog::downloadSelectedDocsets() { QItemSelectionModel *selectionModel = ui->availableDocsetList->selectionModel(); - for (const QModelIndex &index : selectionModel->selectedIndexes()) { + for (const QModelIndex &index : selectionModel->selectedRows()) { selectionModel->select(index, QItemSelectionModel::Deselect); // Do nothing if a download is already in progress. @@ -756,7 +756,7 @@ void DocsetsDialog::resetProgress() ui->addFeedButton->setEnabled(true); QItemSelectionModel *selectionModel = ui->installedDocsetList->selectionModel(); bool hasSelectedUpdates = false; - for (const QModelIndex &index : selectionModel->selectedIndexes()) { + for (const QModelIndex &index : selectionModel->selectedRows()) { if (index.data(Registry::ListModel::UpdateAvailableRole).toBool()) { hasSelectedUpdates = true; break; From 6b8ac9de88373180133a33db4497e635fa62e4bf Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Mon, 10 Oct 2016 01:39:20 -0400 Subject: [PATCH 7/8] ui: Add changes to DocsetsDialog missing from #625 Missing from ac0d19e5fea15a2ac8c1e78bab58802ba938e5bd. --- src/libs/ui/forms/docsetsdialog.ui | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libs/ui/forms/docsetsdialog.ui b/src/libs/ui/forms/docsetsdialog.ui index c3ba0bbe..cd32e279 100644 --- a/src/libs/ui/forms/docsetsdialog.ui +++ b/src/libs/ui/forms/docsetsdialog.ui @@ -32,6 +32,9 @@ QAbstractItemView::ExtendedSelection + + QAbstractItemView::SelectRows + 16 @@ -116,6 +119,9 @@ QAbstractItemView::ExtendedSelection + + QAbstractItemView::SelectRows + 16 From 783fb12ae81bb6358d1accf839ef58718f1ae894 Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Mon, 10 Oct 2016 01:40:05 -0400 Subject: [PATCH 8/8] Bump version to 0.3.1 --- qmake/common.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/common.pri b/qmake/common.pri index ac08e59f..60c5e73b 100644 --- a/qmake/common.pri +++ b/qmake/common.pri @@ -30,7 +30,7 @@ RCC_DIR = $$BUILD_ROOT/.rcc UI_DIR = $$BUILD_ROOT/.ui # Application version -VERSION = 0.3.0 +VERSION = 0.3.1 DEFINES += ZEAL_VERSION=\\\"$${VERSION}\\\" # Browser engine