This commit is contained in:
Martin Rotter 2015-01-24 09:32:54 +01:00
parent 7fb7e4aad3
commit 6668c4280e
23 changed files with 424 additions and 265 deletions

View File

@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -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)
);

View File

@ -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)
);

View File

@ -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)
);

View File

@ -9,6 +9,7 @@ Fixed:
Added:
<ul>
<li></li>
</ul>
<hr/>

View File

@ -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();

View File

@ -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();

View File

@ -78,22 +78,17 @@
<string>Feeds &amp; messages</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QDialogButtonBox" name="m_buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
<item>
<property name="text">
<string>Downloads</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QStackedWidget" name="m_stackedSettings">
<property name="currentIndex">
<number>6</number>
<number>7</number>
</property>
<widget class="QWidget" name="m_pageGeneral">
<layout class="QFormLayout" name="formLayout_5">
@ -475,8 +470,8 @@ Authors of this application are NOT responsible for lost data.</string>
<rect>
<x>0</x>
<y>0</y>
<width>167</width>
<height>219</height>
<width>695</width>
<height>425</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@ -1315,6 +1310,82 @@ Authors of this application are NOT responsible for lost data.</string>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_pageDownloads">
<layout class="QFormLayout" name="formLayout_19">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Target directory for downloaded files</string>
</property>
<layout class="QFormLayout" name="formLayout_20">
<item row="1" column="0">
<widget class="QRadioButton" name="m_rbDownloadsAskEachFile">
<property name="text">
<string>Ask for each individual downloaded file</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QRadioButton" name="m_rbDownloadsSaveAllIntoDirectory">
<property name="text">
<string>Save all downloaded files into</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="m_txtDownloadsTargetDirectory">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string>Target directory where all downloaded files are saved</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_btnDownloadsTargetDirectory">
<property name="text">
<string>&amp;Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QDialogButtonBox" name="m_buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
@ -1443,5 +1514,37 @@ Authors of this application are NOT responsible for lost data.</string>
</hint>
</hints>
</connection>
<connection>
<sender>m_rbDownloadsAskEachFile</sender>
<signal>toggled(bool)</signal>
<receiver>m_txtDownloadsTargetDirectory</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>821</x>
<y>50</y>
</hint>
<hint type="destinationlabel">
<x>522</x>
<y>49</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_rbDownloadsAskEachFile</sender>
<signal>toggled(bool)</signal>
<receiver>m_btnDownloadsTargetDirectory</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>821</x>
<y>50</y>
</hint>
<hint type="destinationlabel">
<x>673</x>
<y>50</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -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

View File

@ -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 <QMutex>
#include <QList>
#if QT_VERSION >= 0x050000
#include <QStandardPaths>
#else
#include <QDesktopServices>
#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);

View File

@ -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);

View File

@ -20,12 +20,24 @@
#include <QStringList>
#if QT_VERSION >= 0x050000
#include <QStandardPaths>
#define SYSTEM_FOLDER_ENUM QStandardPaths
#else
#include <QDesktopServices>
#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.

View File

@ -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";

View File

@ -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;

View File

@ -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<QNetworkReply*>(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 {

View File

@ -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);

View File

@ -46,7 +46,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="SqueezeLabel" name="fileNameLabel" native="true">
<widget class="SqueezeLabel" name="m_fileNameLabel" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -59,7 +59,7 @@
</widget>
</item>
<item>
<widget class="SqueezeLabel" name="downloadInfoLabel" native="true">
<widget class="SqueezeLabel" name="m_lblInfoDownload" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -79,21 +79,28 @@
<bool>false</bool>
</property>
<property name="text">
<string>Try again</string>
<string>&amp;Try again</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="stopButton">
<property name="text">
<string>Stop</string>
<string>&amp;Stop</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="openButton">
<property name="text">
<string>Open file</string>
<string>&amp;Open file</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string>Open &amp;folder</string>
</property>
</widget>
</item>

View File

@ -22,6 +22,7 @@
#include "gui/formmain.h"
#include "gui/tabwidget.h"
#include "network-web/silentnetworkaccessmanager.h"
#include "network-web/webbrowsernetworkaccessmanager.h"
#include <math.h>
@ -39,58 +40,52 @@
#include <QWebSettings>
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();

View File

@ -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;

View File

@ -17,6 +17,8 @@
#include "network-web/silentnetworkaccessmanager.h"
#include "miscellaneous/application.h"
#include <QNetworkReply>
#include <QAuthenticator>
@ -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);
}
}

View File

@ -31,6 +31,7 @@ class SilentNetworkAccessManager : public BaseNetworkAccessManager {
virtual ~SilentNetworkAccessManager();
protected slots:
// This cannot do any GUI stuff.
void onAuthenticationRequired(QNetworkReply * reply, QAuthenticator *authenticator);
};

View File

@ -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: