diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ebc6829a..26146a312 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,6 +281,11 @@ elseif(OS2 AND ${ENABLE_OS2_RC}) ) endif(WIN32) +# Set special linker flag for Windows XP & MSVC++ 2013 support. +if(WIN32 AND MSVC) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,5.01" ) +endif(WIN32 AND MSVC) + # Compile application icon if compiling with MinGW on WIN32 or with OS2. if(MINGW AND WIN32) enable_language(RC) diff --git a/resources/graphics/icons/mini-kfaenza/download-manager.png b/resources/graphics/icons/mini-kfaenza/download-manager.png index 3bb5db679..14a89fc42 100644 Binary files a/resources/graphics/icons/mini-kfaenza/download-manager.png and b/resources/graphics/icons/mini-kfaenza/download-manager.png differ diff --git a/resources/misc/db_init_mysql.sql b/resources/misc/db_init_mysql.sql index 78dbffddb..507b3f830 100644 --- a/resources/misc/db_init_mysql.sql +++ b/resources/misc/db_init_mysql.sql @@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS Information ( inf_value TEXT NOT NULL ); -- ! -INSERT INTO Information VALUES (1, 'schema_version', '0.0.2'); +INSERT INTO Information VALUES (1, 'schema_version', '2'); -- ! DROP TABLE IF EXISTS Categories; -- ! @@ -68,7 +68,7 @@ CREATE TABLE IF NOT EXISTS Messages ( author TEXT NOT NULL, date_created BIGINT NOT NULL CHECK (date_created != 0), contents TEXT, - is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1), + is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1), FOREIGN KEY (feed) REFERENCES Feeds (id) ); diff --git a/resources/misc/db_init_sqlite.sql b/resources/misc/db_init_sqlite.sql index 34e6b6f98..497a0d995 100644 --- a/resources/misc/db_init_sqlite.sql +++ b/resources/misc/db_init_sqlite.sql @@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS Information ( inf_value TEXT NOT NULL ); -- ! -INSERT INTO Information VALUES (1, 'schema_version', '0.0.2'); +INSERT INTO Information VALUES (1, 'schema_version', '2'); -- ! DROP TABLE IF EXISTS Categories; -- ! @@ -62,7 +62,7 @@ CREATE TABLE IF NOT EXISTS Messages ( author TEXT NOT NULL, date_created INTEGER NOT NULL CHECK (date_created != 0), contents TEXT, - is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1), + is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1), FOREIGN KEY (feed) REFERENCES Feeds (id) ); diff --git a/resources/misc/db_init_sqlite_memory.sql b/resources/misc/db_init_sqlite_memory.sql index acc7a51c5..3fcabe681 100644 --- a/resources/misc/db_init_sqlite_memory.sql +++ b/resources/misc/db_init_sqlite_memory.sql @@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS Information ( inf_value TEXT NOT NULL ); -- ! -INSERT INTO Information VALUES (1, 'schema_version', '0.0.2'); +INSERT INTO Information VALUES (1, 'schema_version', '2'); -- ! DROP TABLE IF EXISTS Categories; -- ! @@ -62,7 +62,7 @@ CREATE TABLE IF NOT EXISTS Messages ( author TEXT NOT NULL, date_created INTEGER NOT NULL CHECK (date_created != 0), contents TEXT, - is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1), + is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1), FOREIGN KEY (feed) REFERENCES Feeds (id) ); \ No newline at end of file diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG index 5b354aacb..122bfaede 100644 --- a/resources/text/CHANGELOG +++ b/resources/text/CHANGELOG @@ -9,6 +9,7 @@ Fixed: Added:
diff --git a/src/gui/formsettings.cpp b/src/gui/formsettings.cpp index 5b3a2240d..cbf50e015 100755 --- a/src/gui/formsettings.cpp +++ b/src/gui/formsettings.cpp @@ -130,6 +130,7 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form connect(m_ui->m_txtMysqlUsername->lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(onMysqlDataStorageEdited())); connect(m_ui->m_cmbSelectToolBar, SIGNAL(currentIndexChanged(int)), m_ui->m_stackedToolbars, SLOT(setCurrentIndex(int))); connect(m_ui->m_cmbDatabaseDriver, SIGNAL(currentIndexChanged(int)), this, SLOT(selectSqlBackend(int))); + connect(m_ui->m_btnDownloadsTargetDirectory, SIGNAL(clicked()), this, SLOT(selectDownloadsDirectory())); // Load all settings. loadGeneral(); @@ -140,6 +141,7 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form loadBrowser(); loadLanguage(); loadFeedsMessages(); + loadDownloads(); } FormSettings::~FormSettings() { @@ -163,6 +165,30 @@ void FormSettings::onSkinSelected(QTreeWidgetItem *current, } } +void FormSettings::loadDownloads() { + m_ui->m_txtDownloadsTargetDirectory->setText(qApp->settings()->value(GROUP(Downloads), + SETTING(Downloads::TargetDirectory)).toString()); + m_ui->m_rbDownloadsAskEachFile->setChecked(qApp->settings()->value(GROUP(Downloads), + SETTING(Downloads::AlwaysPromptForFilename)).toBool()); +} + +void FormSettings::saveDownloads() { + qApp->settings()->setValue(GROUP(Downloads), Downloads::TargetDirectory, m_ui->m_txtDownloadsTargetDirectory->text()); + qApp->settings()->setValue(GROUP(Downloads), Downloads::AlwaysPromptForFilename, + m_ui->m_rbDownloadsAskEachFile->isChecked()); +} + +void FormSettings::selectDownloadsDirectory() { + QString target_directory = QFileDialog::getExistingDirectory(this, + tr("Select downloads target directory"), + m_ui->m_txtDownloadsTargetDirectory->text() + ); + + if (!target_directory.isEmpty()) { + m_ui->m_txtDownloadsTargetDirectory->setText(QDir::toNativeSeparators(target_directory)); + } +} + void FormSettings::selectBrowserExecutable() { QString executable_file = QFileDialog::getOpenFileName(this, tr("Select web browser executable"), @@ -312,6 +338,7 @@ void FormSettings::saveSettings() { saveBrowser(); saveLanguage(); saveFeedsMessages(); + saveDownloads(); qApp->settings()->checkSettings(); promptForRestart(); diff --git a/src/gui/formsettings.h b/src/gui/formsettings.h index 2f2148791..200bca3fb 100644 --- a/src/gui/formsettings.h +++ b/src/gui/formsettings.h @@ -62,6 +62,10 @@ class FormSettings : public QDialog { void saveInterface(); void onSkinSelected(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void loadDownloads(); + void saveDownloads(); + void selectDownloadsDirectory(); + void loadGeneral(); void saveGeneral(); diff --git a/src/gui/formsettings.ui b/src/gui/formsettings.ui index 1442894b8..3f8bfa391 100644 --- a/src/gui/formsettings.ui +++ b/src/gui/formsettings.ui @@ -78,22 +78,17 @@ Feeds & messages - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - + + + Downloads + + - 6 + 7 @@ -475,8 +470,8 @@ Authors of this application are NOT responsible for lost data. 0 0 - 167 - 219 + 695 + 425 @@ -1315,6 +1310,82 @@ Authors of this application are NOT responsible for lost data. + + + + QFormLayout::AllNonFixedFieldsGrow + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Target directory for downloaded files + + + + + + Ask for each individual downloaded file + + + + + + + + + Save all downloaded files into + + + true + + + + + + + true + + + Target directory where all downloaded files are saved + + + + + + + &Browse + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + @@ -1443,5 +1514,37 @@ Authors of this application are NOT responsible for lost data. + + m_rbDownloadsAskEachFile + toggled(bool) + m_txtDownloadsTargetDirectory + setDisabled(bool) + + + 821 + 50 + + + 522 + 49 + + + + + m_rbDownloadsAskEachFile + toggled(bool) + m_btnDownloadsTargetDirectory + setDisabled(bool) + + + 821 + 50 + + + 673 + 50 + + + diff --git a/src/main.cpp b/src/main.cpp index b5130c338..54a3d64b2 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,6 +24,7 @@ #include "gui/formmain.h" #include "gui/feedmessageviewer.h" #include "gui/feedsview.h" +#include "network-web/silentnetworkaccessmanager.h" // Needed for setting ini file format on Mac OS. #ifdef Q_OS_MAC diff --git a/src/miscellaneous/application.h b/src/miscellaneous/application.h index cf38fc5a7..0377b0683 100755 --- a/src/miscellaneous/application.h +++ b/src/miscellaneous/application.h @@ -26,18 +26,13 @@ #include "miscellaneous/skinfactory.h" #include "miscellaneous/localization.h" #include "miscellaneous/databasefactory.h" +#include "miscellaneous/iofactory.h" #include "gui/systemtrayicon.h" #include "network-web/downloadmanager.h" #include #include -#if QT_VERSION >= 0x050000 -#include -#else -#include -#endif - #if defined(qApp) #undef qApp #endif @@ -128,30 +123,15 @@ class Application : public QtSingleApplication { } inline QString tempFolderPath() { -#if QT_VERSION >= 0x050000 - QString temp_directory = QStandardPaths::writableLocation(QStandardPaths::TempLocation); -#else - QString temp_directory = QDesktopServices::storageLocation(QDesktopServices::TempLocation); -#endif - return temp_directory; + return IOFactory::getSystemFolder(SYSTEM_FOLDER_ENUM::TempLocation); } inline QString documentsFolderPath() { -#if QT_VERSION >= 0x050000 - QString doc_directory = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); -#else - QString doc_directory = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); -#endif - return doc_directory; + return IOFactory::getSystemFolder(SYSTEM_FOLDER_ENUM::DocumentsLocation); } inline QString homeFolderPath() { -#if QT_VERSION >= 0x050000 - QString home_path = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); -#else - QString home_path = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); -#endif - return home_path; + return IOFactory::getSystemFolder(SYSTEM_FOLDER_ENUM::HomeLocation); } bool backupDatabaseSettings(bool backup_database, bool backup_settings, const QString &target_path, const QString &backup_name); diff --git a/src/miscellaneous/iofactory.cpp b/src/miscellaneous/iofactory.cpp index b6236d1a9..9fdcfd0f8 100755 --- a/src/miscellaneous/iofactory.cpp +++ b/src/miscellaneous/iofactory.cpp @@ -25,6 +25,14 @@ IOFactory::IOFactory() { } +QString IOFactory::getSystemFolder(SYSTEM_FOLDER_ENUM::StandardLocation location) { +#if QT_VERSION >= 0x050000 + return SYSTEM_FOLDER_ENUM::writableLocation(location); +#else + return SYSTEM_FOLDER_ENUM::storageLocation(location); +#endif +} + bool IOFactory::copyFile(const QString &source, const QString &destination) { if (QFile::exists(destination)) { if (!QFile::remove(destination)) { @@ -36,8 +44,8 @@ bool IOFactory::copyFile(const QString &source, const QString &destination) { } bool IOFactory::removeFolder(const QString& directory_name, - const QStringList& exception_file_list, - const QStringList& exception_folder_list) { + const QStringList& exception_file_list, + const QStringList& exception_folder_list) { bool result = true; QDir dir(directory_name); diff --git a/src/miscellaneous/iofactory.h b/src/miscellaneous/iofactory.h index 493718663..9f972b70f 100755 --- a/src/miscellaneous/iofactory.h +++ b/src/miscellaneous/iofactory.h @@ -20,12 +20,24 @@ #include +#if QT_VERSION >= 0x050000 +#include +#define SYSTEM_FOLDER_ENUM QStandardPaths +#else +#include +#define SYSTEM_FOLDER_ENUM QDesktopServices +#endif + class IOFactory { private: IOFactory(); - public: + public: + // Returns system-wide folder according to type. + static QString getSystemFolder(SYSTEM_FOLDER_ENUM::StandardLocation location); + + // Copies file, overwrites destination. static bool copyFile(const QString &source, const QString &destination); // Copy whole directory recursively. diff --git a/src/miscellaneous/settings.cpp b/src/miscellaneous/settings.cpp index 889092deb..4b5786715 100755 --- a/src/miscellaneous/settings.cpp +++ b/src/miscellaneous/settings.cpp @@ -150,6 +150,15 @@ DVALUE(bool) General::RemoveTrolltechJunkDef = false; DKEY General::Language = "language"; DVALUE(QString) General::LanguageDef = QLocale::system().name(); +// Downloads. +DKEY Downloads::ID = "download_manager"; + +DKEY Downloads::AlwaysPromptForFilename = "prompt_for_filename"; +DVALUE(bool) Downloads::AlwaysPromptForFilenameDef = false; + +DKEY Downloads::TargetDirectory = "target_directory"; +DVALUE(QString) Downloads::TargetDirectoryDef = IOFactory::getSystemFolder(SYSTEM_FOLDER_ENUM::DesktopLocation); + // Proxy. DKEY Proxy::ID = "proxy"; diff --git a/src/miscellaneous/settings.h b/src/miscellaneous/settings.h index 0b042f341..3ee175f09 100755 --- a/src/miscellaneous/settings.h +++ b/src/miscellaneous/settings.h @@ -164,6 +164,17 @@ namespace General { VALUE(QString) LanguageDef; } +// Downloads. +namespace Downloads { + KEY ID; + + KEY AlwaysPromptForFilename; + VALUE(bool) AlwaysPromptForFilenameDef; + + KEY TargetDirectory; + VALUE(QString) TargetDirectoryDef; +} + // Proxy. namespace Proxy { KEY ID; diff --git a/src/network-web/downloader.cpp b/src/network-web/downloader.cpp index 40837063a..05b23bb79 100755 --- a/src/network-web/downloader.cpp +++ b/src/network-web/downloader.cpp @@ -31,7 +31,7 @@ Downloader::Downloader(QObject *parent) m_timer->setSingleShot(true); connect(m_timer, SIGNAL(timeout()), this, SLOT(timeout())); - connect(m_downloadManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*))); + //connect(m_downloadManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*))); } Downloader::~Downloader() { @@ -67,7 +67,9 @@ void Downloader::downloadFile(const QString &url, int timeout, bool protected_co runGetRequest(request); } -void Downloader::finished(QNetworkReply *reply) { +void Downloader::finished() { + QNetworkReply *reply = static_cast(sender()); + m_timer->stop(); // In this phase, some part of downloading process is completed. @@ -124,6 +126,7 @@ void Downloader::runGetRequest(const QNetworkRequest &request) { m_activeReply = m_downloadManager->get(request); connect(m_activeReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(progressInternal(qint64,qint64))); + connect(m_activeReply, SIGNAL(finished()), this, SLOT(finished())); } QVariant Downloader::lastContentType() const { diff --git a/src/network-web/downloader.h b/src/network-web/downloader.h index 36bcf92ed..84f9f7388 100755 --- a/src/network-web/downloader.h +++ b/src/network-web/downloader.h @@ -56,7 +56,7 @@ class Downloader : public QObject { private slots: // Called when current reply is processed. - void finished(QNetworkReply *reply); + void finished(); // Called when progress of downloaded file changes. void progressInternal(qint64 bytes_received, qint64 bytes_total); diff --git a/src/network-web/downloaditem.ui b/src/network-web/downloaditem.ui index 0b5e4c901..650927c4a 100644 --- a/src/network-web/downloaditem.ui +++ b/src/network-web/downloaditem.ui @@ -46,7 +46,7 @@ - + 0 @@ -59,7 +59,7 @@ - + 0 @@ -79,21 +79,28 @@ false - Try again + &Try again - Stop + &Stop - Open file + &Open file + + + + + + + Open &folder diff --git a/src/network-web/downloadmanager.cpp b/src/network-web/downloadmanager.cpp index 9f7631544..e4e0ff0ce 100644 --- a/src/network-web/downloadmanager.cpp +++ b/src/network-web/downloadmanager.cpp @@ -22,6 +22,7 @@ #include "gui/formmain.h" #include "gui/tabwidget.h" #include "network-web/silentnetworkaccessmanager.h" +#include "network-web/webbrowsernetworkaccessmanager.h" #include @@ -39,58 +40,52 @@ #include -DownloadItem::DownloadItem(QNetworkReply *reply, bool request_file_name, QWidget *parent) : QWidget(parent), m_reply(reply), +DownloadItem::DownloadItem(QNetworkReply *reply, bool request_file_name, QWidget *parent) : QWidget(parent), + m_ui(new Ui::DownloadItem), m_reply(reply), m_bytesReceived(0), m_requestFileName(request_file_name), m_startedSaving(false), m_finishedDownloading(false), m_gettingFileName(false), m_canceledFileSelect(false) { - setupUi(this); + m_ui->setupUi(this); + m_ui->tryAgainButton->hide(); - tryAgainButton->hide(); - - connect(stopButton, SIGNAL(clicked()), this, SLOT(stop())); - connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); - connect(tryAgainButton, SIGNAL(clicked()), this, SLOT(tryAgain())); + connect(m_ui->stopButton, SIGNAL(clicked()), this, SLOT(stop())); + connect(m_ui->openButton, SIGNAL(clicked()), this, SLOT(openFile())); + connect(m_ui->tryAgainButton, SIGNAL(clicked()), this, SLOT(tryAgain())); if (!request_file_name) { - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - m_requestFileName = settings.value(QLatin1String("alwaysPromptForFileName"), false).toBool(); + m_requestFileName = qApp->settings()->value(GROUP(Downloads), SETTING(Downloads::AlwaysPromptForFilename)).toBool(); } - /*if (reply != NULL) { - reply->deleteLater(); - }*/ - init(); } +DownloadItem::~DownloadItem() { + delete m_ui; +} + void DownloadItem::init() { - if (!m_reply) + if (m_reply == NULL) { return; + } m_startedSaving = false; m_finishedDownloading = false; - - openButton->setEnabled(false); - - // attach to the m_reply + m_ui->openButton->setEnabled(false); + m_ui->toolButton->setEnabled(false); m_url = m_reply->url(); m_reply->setParent(this); - connect(m_reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead())); - connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), - this, SLOT(error(QNetworkReply::NetworkError))); - connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), - this, SLOT(downloadProgress(qint64, qint64))); - connect(m_reply, SIGNAL(metaDataChanged()), - this, SLOT(metaDataChanged())); - connect(m_reply, SIGNAL(finished()), - this, SLOT(finished())); - // reset info - downloadInfoLabel->clear(); - progressBar->setValue(0); + connect(m_reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead())); + connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError))); + connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64))); + connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged())); + connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); + + // Reset info. + m_ui->m_lblInfoDownload->clear(); + m_ui->progressBar->setValue(0); getFileName(); - // start timer for the download estimation + // Start timer for the download estimation. m_downloadTime.start(); if (m_reply->error() != QNetworkReply::NoError) { @@ -99,82 +94,95 @@ void DownloadItem::init() { } } -void DownloadItem::getFileName() -{ - if (m_gettingFileName) +void DownloadItem::getFileName() { + if (m_gettingFileName) { return; + } - QString downloadDirectory = qApp->downloadManager()->downloadDirectory(); + QString download_directory = qApp->downloadManager()->downloadDirectory(); + QString default_filename = saveFileName(download_directory); + QString chosen_filename = default_filename; - QString defaultFileName = saveFileName(downloadDirectory); - QString fileName = defaultFileName; if (m_requestFileName) { m_gettingFileName = true; - fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName); + chosen_filename = QFileDialog::getSaveFileName(this, tr("Select destination for downloaded file"), default_filename); m_gettingFileName = false; - if (fileName.isEmpty()) { - progressBar->setVisible(false); + + if (chosen_filename.isEmpty()) { stop(); - fileNameLabel->setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName())); + + m_ui->progressBar->setVisible(false); + m_ui->m_fileNameLabel->setText(tr("Download for %1 cancelled").arg(QFileInfo(default_filename).fileName())); m_canceledFileSelect = true; return; } - QFileInfo fileInfo = QFileInfo(fileName); - qApp->downloadManager()->setDownloadDirectory(fileInfo.absoluteDir().absolutePath()); - fileNameLabel->setText(fileInfo.fileName()); + + QFileInfo file_info = QFileInfo(chosen_filename); + + qApp->downloadManager()->setDownloadDirectory(file_info.absoluteDir().absolutePath()); + m_ui->m_fileNameLabel->setText(file_info.fileName()); } - m_output.setFileName(fileName); + + m_output.setFileName(chosen_filename); // Check file path for saving. - QDir saveDirPath = QFileInfo(m_output.fileName()).dir(); - if (!saveDirPath.exists()) { - if (!saveDirPath.mkpath(saveDirPath.absolutePath())) { - progressBar->setVisible(false); - stop(); - downloadInfoLabel->setText(tr("Download directory (%1) couldn't be created.").arg(saveDirPath.absolutePath())); - return; - } + QDir save_dir = QFileInfo(m_output.fileName()).dir(); + + if (!save_dir.exists() && !save_dir.mkpath(save_dir.absolutePath())) { + stop(); + + m_ui->progressBar->setVisible(false); + m_ui->m_lblInfoDownload->setText(tr("Download directory %1 couldn't be created").arg(QDir::toNativeSeparators(save_dir.absolutePath()))); + return; } - fileNameLabel->setText(QFileInfo(m_output.fileName()).fileName()); - if (m_requestFileName) + m_ui->m_fileNameLabel->setText(QFileInfo(m_output.fileName()).fileName()); + + if (m_requestFileName) { downloadReadyRead(); + } } -QString DownloadItem::saveFileName(const QString &directory) const -{ - // Move this function into QNetworkReply to also get file name sent from the server +QString DownloadItem::saveFileName(const QString &directory) const { QString path; + if (m_reply->hasRawHeader("Content-Disposition")) { QString value = QLatin1String(m_reply->rawHeader("Content-Disposition")); int pos = value.indexOf(QLatin1String("filename=")); + if (pos != -1) { QString name = value.mid(pos + 9); - if (name.startsWith(QLatin1Char('"')) && name.endsWith(QLatin1Char('"'))) + + if (name.startsWith(QLatin1Char('"')) && name.endsWith(QLatin1Char('"'))) { name = name.mid(1, name.size() - 2); + } + path = name; } } - if (path.isEmpty()) + + if (path.isEmpty()) { path = m_url.path(); - - QFileInfo info(path); - QString baseName = info.completeBaseName(); - QString endName = info.suffix(); - - if (baseName.isEmpty()) { - baseName = QLatin1String("unnamed_download"); } - if (!endName.isEmpty()) - endName = QLatin1Char('.') + endName; + QFileInfo info(path); + QString base_name = info.completeBaseName(); + QString end_name = info.suffix(); - QString name = directory + baseName + endName; + if (base_name.isEmpty()) { + base_name = QLatin1String("unnamed_download"); + } + + if (!end_name.isEmpty()) { + end_name = QLatin1Char('.') + end_name; + } + + QString name = directory + base_name + end_name; if (!m_requestFileName && QFile::exists(name)) { // already exists, don't overwrite int i = 1; do { - name = directory + baseName + QLatin1Char('-') + QString::number(i++) + endName; + name = directory + base_name + QLatin1Char('-') + QString::number(i++) + end_name; } while (QFile::exists(name)); } return name; @@ -183,10 +191,10 @@ QString DownloadItem::saveFileName(const QString &directory) const void DownloadItem::stop() { setUpdatesEnabled(false); - stopButton->setEnabled(false); - stopButton->hide(); - tryAgainButton->setEnabled(true); - tryAgainButton->show(); + m_ui->stopButton->setEnabled(false); + m_ui->stopButton->hide(); + m_ui->tryAgainButton->setEnabled(true); + m_ui->tryAgainButton->show(); setUpdatesEnabled(true); m_reply->abort(); emit downloadFinished(); @@ -199,15 +207,19 @@ void DownloadItem::openFile() { QDesktopServices::openUrl(url); } +void DownloadItem::openFolder() { + // TODO: pouze na windows, otevrit explorer, jinde schovat tlacitko Open folder. +} + void DownloadItem::tryAgain() { - if (!tryAgainButton->isEnabled()) + if (!m_ui->tryAgainButton->isEnabled()) return; - tryAgainButton->setEnabled(false); - tryAgainButton->setVisible(false); - stopButton->setEnabled(true); - stopButton->setVisible(true); - progressBar->setVisible(true); + m_ui->tryAgainButton->setEnabled(false); + m_ui->tryAgainButton->setVisible(false); + m_ui->stopButton->setEnabled(true); + m_ui->stopButton->setVisible(true); + m_ui->progressBar->setVisible(true); QNetworkReply *r = qApp->downloadManager()->networkManager()->get(QNetworkRequest(m_url)); if (m_reply) @@ -228,8 +240,8 @@ void DownloadItem::downloadReadyRead() if (!m_requestFileName) getFileName(); if (!m_output.open(QIODevice::WriteOnly)) { - downloadInfoLabel->setText(tr("Error opening output file: %1") - .arg(m_output.errorString())); + m_ui->m_lblInfoDownload->setText(tr("Error opening output file: %1") + .arg(m_output.errorString())); stop(); emit statusChanged(); return; @@ -237,9 +249,9 @@ void DownloadItem::downloadReadyRead() emit statusChanged(); } if (-1 == m_output.write(m_reply->readAll())) { - downloadInfoLabel->setText(tr("Error saving: %1") - .arg(m_output.errorString())); - stopButton->click(); + m_ui->m_lblInfoDownload->setText(tr("Error saving: %1") + .arg(m_output.errorString())); + m_ui->stopButton->click(); } else { m_startedSaving = true; if (m_finishedDownloading) @@ -249,9 +261,10 @@ void DownloadItem::downloadReadyRead() void DownloadItem::error(QNetworkReply::NetworkError) { - downloadInfoLabel->setText(tr("Network Error: %1").arg(m_reply->errorString())); - tryAgainButton->setEnabled(true); - tryAgainButton->setVisible(true); + m_ui->m_lblInfoDownload->setText(tr("Error: %1").arg(m_reply->errorString())); + m_ui->tryAgainButton->setEnabled(true); + m_ui->tryAgainButton->setVisible(true); + emit downloadFinished(); } @@ -267,34 +280,33 @@ void DownloadItem::metaDataChanged() } } -void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ +void DownloadItem::downloadProgress(qint64 bytes_received, qint64 bytes_total) { QTime now = QTime::currentTime(); - if (m_lastProgressTime.msecsTo(now) < 200) + if (m_lastProgressTime.msecsTo(now) < 25) return; m_lastProgressTime = now; - m_bytesReceived = bytesReceived; + m_bytesReceived = bytes_received; qint64 currentValue = 0; qint64 totalValue = 0; - if (bytesTotal > 0) { - currentValue = bytesReceived * 100 / bytesTotal; + if (bytes_total > 0) { + currentValue = bytes_received * 100 / bytes_total; totalValue = 100; } - progressBar->setValue(currentValue); - progressBar->setMaximum(totalValue); + m_ui->progressBar->setValue(currentValue); + m_ui->progressBar->setMaximum(totalValue); emit progress(currentValue, totalValue); updateInfoLabel(); } -qint64 DownloadItem::bytesTotal() const +qint64 DownloadItem::bytes_total() const { return m_reply->header(QNetworkRequest::ContentLengthHeader).toULongLong(); } -qint64 DownloadItem::bytesReceived() const +qint64 DownloadItem::bytes_received() const { return m_bytesReceived; } @@ -304,7 +316,7 @@ double DownloadItem::remainingTime() const if (!downloading()) return -1.0; - double timeRemaining = ((double)(bytesTotal() - bytesReceived())) / currentSpeed(); + double timeRemaining = ((double)(bytes_total() - bytes_received())) / currentSpeed(); // When downloading the eta should never be 0 if (timeRemaining == 0) @@ -354,17 +366,17 @@ void DownloadItem::updateInfoLabel() .arg(DownloadManager::dataString(m_bytesReceived)) .arg(DownloadManager::dataString(bytesTotal)); } - downloadInfoLabel->setText(info); + m_ui->m_lblInfoDownload->setText(info); } bool DownloadItem::downloading() const { - return (progressBar->isVisible()); + return (m_ui->progressBar->isVisible()); } bool DownloadItem::downloadedSuccessfully() const { - return (stopButton->isHidden() && tryAgainButton->isHidden()); + return (m_ui->stopButton->isHidden() && m_ui->tryAgainButton->isHidden()); } void DownloadItem::finished() @@ -373,44 +385,30 @@ void DownloadItem::finished() if (!m_startedSaving) { return; } - progressBar->hide(); - stopButton->setEnabled(false); - stopButton->hide(); - openButton->setEnabled(true); + m_ui->progressBar->hide(); + m_ui->stopButton->setEnabled(false); + m_ui->stopButton->hide(); + m_ui->openButton->setEnabled(true); + m_ui->toolButton->setEnabled(true); m_output.close(); updateInfoLabel(); emit statusChanged(); emit downloadFinished(); } -/*! - DownloadManager is a Dialog that contains a list of DownloadItems +DownloadManager::DownloadManager(QWidget *parent) : TabContent(parent), m_ui(new Ui::DownloadManager), + m_autoSaver(new AutoSaver(this)), m_model(new DownloadModel(this)), + m_networkManager(WebBrowserNetworkAccessManager::instance()), m_iconProvider(0), m_removePolicy(Never) { + m_ui->setupUi(this); + m_ui->downloadsView->setShowGrid(false); + m_ui->downloadsView->verticalHeader()->hide(); + m_ui->downloadsView->horizontalHeader()->hide(); + m_ui->downloadsView->setAlternatingRowColors(true); + m_ui->downloadsView->horizontalHeader()->setStretchLastSection(true); + m_ui->downloadsView->setModel(m_model); - It is a basic download manager. It only downloads the file, doesn't do BitTorrent, - extract zipped files or anything fancy. - */ -DownloadManager::DownloadManager(QWidget *parent) - : TabContent(parent) - , m_autoSaver(new AutoSaver(this)) - , m_model(new DownloadModel(this)) - , m_networkManager(new SilentNetworkAccessManager(this)) - , m_iconProvider(0) - , m_removePolicy(Never) -{ - setupUi(this); - - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QString defaultLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); - setDownloadDirectory(settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString()); - - downloadsView->setShowGrid(false); - downloadsView->verticalHeader()->hide(); - downloadsView->horizontalHeader()->hide(); - downloadsView->setAlternatingRowColors(true); - downloadsView->horizontalHeader()->setStretchLastSection(true); - downloadsView->setModel(m_model); - connect(cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); + setDownloadDirectory(qApp->settings()->value(GROUP(Downloads), SETTING(Downloads::TargetDirectory)).toString()); + connect(m_ui->cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); load(); } @@ -418,22 +416,25 @@ DownloadManager::~DownloadManager() { m_autoSaver->changeOccurred(); m_autoSaver->saveIfNeccessary(); - if (m_iconProvider) + + if (m_iconProvider) { delete m_iconProvider; + } + + delete m_ui; } int DownloadManager::activeDownloads() const { int count = 0; for (int i = 0; i < m_downloads.count(); ++i) { - if (m_downloads.at(i)->stopButton->isEnabled()) + if (m_downloads.at(i)->m_ui->stopButton->isEnabled()) ++count; } return count; } -bool DownloadManager::allowQuit() -{ +bool DownloadManager::allowQuit() { if (activeDownloads() >= 1) { int choice = QMessageBox::warning(this, QString(), tr("There are %1 downloads in progress\n" @@ -449,19 +450,19 @@ bool DownloadManager::allowQuit() return true; } -void DownloadManager::download(const QNetworkRequest &request, bool requestFileName) +void DownloadManager::download(const QNetworkRequest &request, bool request_filename) { if (request.url().isEmpty()) return; - handleUnsupportedContent(m_networkManager->get(request), requestFileName); + handleUnsupportedContent(m_networkManager->get(request), request_filename); } -void DownloadManager::download(const QUrl &url, bool requestFileName) { - download(QNetworkRequest(url), requestFileName); +void DownloadManager::download(const QUrl &url, bool request_filename) { + download(QNetworkRequest(url), request_filename); } -void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool requestFileName) +void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool request_filename) { if (reply == NULL || reply->url().isEmpty()) { return; @@ -475,50 +476,37 @@ void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool reques return; } - DownloadItem *item = new DownloadItem(reply, requestFileName, this); + DownloadItem *item = new DownloadItem(reply, request_filename, this); addItem(item); if (item->m_canceledFileSelect) { return; } - // TODO: zobrazit ted. qApp->mainForm()->tabWidget()->showDownloadManager(); } -void DownloadManager::addItem(DownloadItem *item) -{ +void DownloadManager::addItem(DownloadItem *item) { connect(item, SIGNAL(statusChanged()), this, SLOT(updateRow())); connect(item, SIGNAL(downloadFinished()), this, SLOT(finished())); + int row = m_downloads.count(); m_model->beginInsertRows(QModelIndex(), row, row); m_downloads.append(item); m_model->endInsertRows(); - downloadsView->setIndexWidget(m_model->index(row, 0), item); + m_ui->downloadsView->setIndexWidget(m_model->index(row, 0), item); QIcon icon = style()->standardIcon(QStyle::SP_FileIcon); - item->fileIcon->setPixmap(icon.pixmap(48, 48)); - downloadsView->setRowHeight(row, item->sizeHint().height()); + item->m_ui->fileIcon->setPixmap(icon.pixmap(48, 48)); + m_ui->downloadsView->setRowHeight(row, item->sizeHint().height()); updateRow(item); //incase download finishes before the constructor returns - updateActiveItemCount(); } -void DownloadManager::updateActiveItemCount() -{ - int acCount = activeDownloads(); - if (acCount > 0) { - setWindowTitle(QApplication::translate("DownloadDialog", "Downloading %1", 0, QApplication::UnicodeUTF8).arg(acCount)); - } else { - setWindowTitle(QApplication::translate("DownloadDialog", "Downloads", 0, QApplication::UnicodeUTF8)); - } -} -QNetworkAccessManager *DownloadManager::networkManager() const -{ +QNetworkAccessManager *DownloadManager::networkManager() const { return m_networkManager; } void DownloadManager::finished() { - updateActiveItemCount(); if (isVisible()) { QApplication::alert(this); } @@ -540,10 +528,10 @@ void DownloadManager::updateRow(DownloadItem *item) QIcon icon = m_iconProvider->icon(item->m_output.fileName()); if (icon.isNull()) icon = style()->standardIcon(QStyle::SP_FileIcon); - item->fileIcon->setPixmap(icon.pixmap(48, 48)); + item->m_ui->fileIcon->setPixmap(icon.pixmap(48, 48)); - int oldHeight = downloadsView->rowHeight(row); - downloadsView->setRowHeight(row, qMax(oldHeight, item->minimumSizeHint().height())); + int oldHeight = m_ui->downloadsView->rowHeight(row); + m_ui->downloadsView->setRowHeight(row, qMax(oldHeight, item->minimumSizeHint().height())); bool remove = false; QWebSettings *globalSettings = QWebSettings::globalSettings(); @@ -558,7 +546,7 @@ void DownloadManager::updateRow(DownloadItem *item) if (remove) m_model->removeRow(row); - cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); + m_ui->cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); } DownloadManager::RemovePolicy DownloadManager::removePolicy() const @@ -620,21 +608,20 @@ void DownloadManager::load() QString fileName = settings.value(key + QLatin1String("location")).toString(); bool done = settings.value(key + QLatin1String("done"), true).toBool(); if (!url.isEmpty() && !fileName.isEmpty()) { - DownloadItem *item = new DownloadItem(0, this); + DownloadItem *item = new DownloadItem(0, false, this); item->m_output.setFileName(fileName); - item->fileNameLabel->setText(QFileInfo(item->m_output.fileName()).fileName()); + item->m_ui->m_fileNameLabel->setText(QFileInfo(item->m_output.fileName()).fileName()); item->m_url = url; - item->stopButton->setVisible(false); - item->stopButton->setEnabled(false); - item->tryAgainButton->setVisible(!done); - item->tryAgainButton->setEnabled(!done); - item->progressBar->setVisible(false); + item->m_ui->stopButton->setVisible(false); + item->m_ui->stopButton->setEnabled(false); + item->m_ui->tryAgainButton->setVisible(!done); + item->m_ui->tryAgainButton->setEnabled(!done); + item->m_ui->progressBar->setVisible(false); addItem(item); } key = QString(QLatin1String("download_%1_")).arg(++i); } - cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); - updateActiveItemCount(); + m_ui->cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); } void DownloadManager::cleanup() @@ -642,7 +629,6 @@ void DownloadManager::cleanup() if (m_downloads.isEmpty()) return; m_model->removeRows(0, m_downloads.count()); - updateActiveItemCount(); if (m_downloads.isEmpty() && m_iconProvider) { delete m_iconProvider; m_iconProvider = 0; @@ -662,18 +648,18 @@ QString DownloadManager::downloadDirectory() return m_downloadDirectory; } -QString DownloadManager::timeString(double timeRemaining) +QString DownloadManager::timeString(double time_remaining) { QString remaining; - if (timeRemaining > 60) { - timeRemaining = timeRemaining / 60; - timeRemaining = floor(timeRemaining); - remaining = tr("%n minutes remaining", "", int(timeRemaining)); + if (time_remaining > 60) { + time_remaining = time_remaining / 60; + time_remaining = floor(time_remaining); + remaining = tr("%n minutes remaining", "", int(time_remaining)); } else { - timeRemaining = floor(timeRemaining); - remaining = tr("%n seconds remaining", "", int(timeRemaining)); + time_remaining = floor(time_remaining); + remaining = tr("%n seconds remaining", "", int(time_remaining)); } return remaining; @@ -701,9 +687,9 @@ QString DownloadManager::dataString(qint64 size) return QString(QLatin1String("%1 %2")).arg(newSize, 0, 'f', 1).arg(unit); } -DownloadModel::DownloadModel(DownloadManager *downloadManager, QObject *parent) +DownloadModel::DownloadModel(DownloadManager *download_manager, QObject *parent) : QAbstractListModel(parent) - , m_downloadManager(downloadManager) + , m_downloadManager(download_manager) { } @@ -713,7 +699,7 @@ QVariant DownloadModel::data(const QModelIndex &index, int role) const return QVariant(); if (role == Qt::ToolTipRole) if (!m_downloadManager->m_downloads.at(index.row())->downloadedSuccessfully()) - return m_downloadManager->m_downloads.at(index.row())->downloadInfoLabel->text(); + return m_downloadManager->m_downloads.at(index.row())->m_ui->m_lblInfoDownload->text(); return QVariant(); } @@ -730,7 +716,7 @@ bool DownloadModel::removeRows(int row, int count, const QModelIndex &parent) int lastRow = row + count - 1; for (int i = lastRow; i >= row; --i) { if (m_downloadManager->m_downloads.at(i)->downloadedSuccessfully() - || m_downloadManager->m_downloads.at(i)->tryAgainButton->isEnabled()) { + || m_downloadManager->m_downloads.at(i)->m_ui->tryAgainButton->isEnabled()) { beginRemoveRows(parent, i, i); m_downloadManager->m_downloads.takeAt(i)->deleteLater(); endRemoveRows(); diff --git a/src/network-web/downloadmanager.h b/src/network-web/downloadmanager.h index 1d562439b..8dc6e3a1b 100644 --- a/src/network-web/downloadmanager.h +++ b/src/network-web/downloadmanager.h @@ -33,7 +33,7 @@ class DownloadModel; class QFileIconProvider; class QMimeData; -class DownloadItem : public QWidget, public Ui_DownloadItem { +class DownloadItem : public QWidget { Q_OBJECT friend class DownloadManager; @@ -41,12 +41,13 @@ class DownloadItem : public QWidget, public Ui_DownloadItem { public: explicit DownloadItem(QNetworkReply *reply = 0, bool request_file_name = false, QWidget *parent = 0); + virtual ~DownloadItem(); bool downloading() const; bool downloadedSuccessfully() const; - qint64 bytesTotal() const; - qint64 bytesReceived() const; + qint64 bytes_total() const; + qint64 bytes_received() const; double remainingTime() const; double currentSpeed() const; @@ -54,25 +55,26 @@ class DownloadItem : public QWidget, public Ui_DownloadItem { void stop(); void tryAgain(); void openFile(); + void openFolder(); void downloadReadyRead(); void error(QNetworkReply::NetworkError code); - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void downloadProgress(qint64 bytes_received, qint64 bytes_total); void metaDataChanged(); void finished(); signals: void statusChanged(); - void progress(qint64 bytesReceived = 0, qint64 bytesTotal = 0); + void progress(qint64 bytes_received = 0, qint64 bytes_total = 0); void downloadFinished(); private: void getFileName(); void init(); void updateInfoLabel(); - QString saveFileName(const QString &directory) const; + Ui::DownloadItem *m_ui; QUrl m_url; QFile m_output; QNetworkReply *m_reply; @@ -86,7 +88,7 @@ class DownloadItem : public QWidget, public Ui_DownloadItem { bool m_canceledFileSelect; }; -class DownloadManager : public TabContent, public Ui_DownloadManager { +class DownloadManager : public TabContent { Q_OBJECT Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy) Q_ENUMS(RemovePolicy) @@ -100,8 +102,8 @@ class DownloadManager : public TabContent, public Ui_DownloadManager { SuccessFullDownload }; - DownloadManager(QWidget *parent = 0); - ~DownloadManager(); + explicit DownloadManager(QWidget *parent = 0); + virtual ~DownloadManager(); WebBrowser *webBrowser(); QNetworkAccessManager *networkManager() const; @@ -112,16 +114,16 @@ class DownloadManager : public TabContent, public Ui_DownloadManager { RemovePolicy removePolicy() const; void setRemovePolicy(RemovePolicy policy); - static QString timeString(double timeRemaining); + static QString timeString(double time_remaining); static QString dataString(qint64 size); void setDownloadDirectory(const QString &directory); QString downloadDirectory(); public slots: - void download(const QNetworkRequest &request, bool requestFileName = false); - void download(const QUrl &url, bool requestFileName = false); - void handleUnsupportedContent(QNetworkReply *reply, bool requestFileName = false); + void download(const QNetworkRequest &request, bool request_filename = false); + void download(const QUrl &url, bool request_filename = false); + void handleUnsupportedContent(QNetworkReply *reply, bool request_filename = false); void cleanup(); private slots: @@ -133,8 +135,8 @@ class DownloadManager : public TabContent, public Ui_DownloadManager { private: void addItem(DownloadItem *item); void load(); - void updateActiveItemCount(); + Ui::DownloadManager *m_ui; AutoSaver *m_autoSaver; DownloadModel *m_model; QNetworkAccessManager *m_networkManager; @@ -150,7 +152,7 @@ class DownloadModel : public QAbstractListModel { friend class DownloadManager; public: - DownloadModel(DownloadManager *downloadManager, QObject *parent = 0); + explicit DownloadModel(DownloadManager *download_manager, QObject *parent = 0); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/src/network-web/silentnetworkaccessmanager.cpp b/src/network-web/silentnetworkaccessmanager.cpp index 6f3d0ff60..7896efadc 100644 --- a/src/network-web/silentnetworkaccessmanager.cpp +++ b/src/network-web/silentnetworkaccessmanager.cpp @@ -17,6 +17,8 @@ #include "network-web/silentnetworkaccessmanager.h" +#include "miscellaneous/application.h" + #include #include @@ -38,15 +40,14 @@ void SilentNetworkAccessManager::onAuthenticationRequired(QNetworkReply *reply, // This feed contains authentication information, it is good. authenticator->setUser(originating_object->property("username").toString()); authenticator->setPassword(originating_object->property("password").toString()); + reply->setProperty("authentication-given", true); qDebug("Feed '%s' requested authentication and got it.", qPrintable(reply->url().toString())); - - reply->setProperty("authentication-given", true); } else { + reply->setProperty("authentication-given", false); + // Authentication is required but this feed does not contain it. qDebug("Feed '%s' requested authentication but username/password is not available.", qPrintable(reply->url().toString())); - - reply->setProperty("authentication-given", false); } } diff --git a/src/network-web/silentnetworkaccessmanager.h b/src/network-web/silentnetworkaccessmanager.h index 3fa0ac5b8..85150757e 100644 --- a/src/network-web/silentnetworkaccessmanager.h +++ b/src/network-web/silentnetworkaccessmanager.h @@ -31,6 +31,7 @@ class SilentNetworkAccessManager : public BaseNetworkAccessManager { virtual ~SilentNetworkAccessManager(); protected slots: + // This cannot do any GUI stuff. void onAuthenticationRequired(QNetworkReply * reply, QAuthenticator *authenticator); }; diff --git a/src/network-web/webbrowsernetworkaccessmanager.h b/src/network-web/webbrowsernetworkaccessmanager.h index 9f25390b3..8f7f41c1a 100644 --- a/src/network-web/webbrowsernetworkaccessmanager.h +++ b/src/network-web/webbrowsernetworkaccessmanager.h @@ -33,9 +33,7 @@ class WebBrowserNetworkAccessManager : public BaseNetworkAccessManager { virtual ~WebBrowserNetworkAccessManager(); // Returns pointer to global network access manager - // used by ALL web browsers. - // NOTE: All web browsers use shared network access manager, - // which makes setting of custom network settings easy. + // used by ALL web browsers and download manager. static WebBrowserNetworkAccessManager *instance(); protected slots: