Skip to content

Commit 325168e

Browse files
authored
Merge pull request #5392 from nyalldawson/file_downloader
Split QgsFileDownloader into separate core/gui classes
2 parents b855ad1 + 406425d commit 325168e

14 files changed

+292
-89
lines changed

doc/api_break.dox

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,15 @@ QgsFieldProxyModel {#qgis_api_break_3_0_QgsFieldProxyModel}
12531253
- In QgsFieldProxyModel::Filter, All has been renamed to AllTypes
12541254

12551255

1256+
QgsFileDownloader {#qgis_api_break_3_0_QgsFileDownloader}
1257+
-----------------
1258+
1259+
- In 2.x QgsFileDownloader was a gui library class. In 3.0 its functionality has been split into
1260+
two new classes - a core QgsFileDownloader class, which handles just the file download functionality
1261+
and contains no GUI progress bar dialog, and a separate QgsFileDownloaderDialog class which
1262+
incorporates a QgsFileDownloader together with a user-visible progress bar dialog
1263+
1264+
12561265
QgsGeometry {#qgis_api_break_3_0_QgsGeometry}
12571266
-----------
12581267

python/core/core_auto.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@
310310
%Include qgsfieldformatterregistry.sip
311311
%Include qgsfieldmodel.sip
312312
%Include qgsfieldproxymodel.sip
313+
%Include qgsfiledownloader.sip
313314
%Include qgsgeometryvalidator.sip
314315
%Include qgsgml.sip
315316
%Include qgsgmlschema.sip

python/gui/qgsfiledownloader.sip renamed to python/core/qgsfiledownloader.sip

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/************************************************************************
22
* This file has been generated automatically from *
33
* *
4-
* src/gui/qgsfiledownloader.h *
4+
* src/core/qgsfiledownloader.h *
55
* *
66
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
77
************************************************************************/
@@ -16,29 +16,33 @@ class QgsFileDownloader : QObject
1616

1717
To use this class, it is necessary to pass the URL and an output file name as
1818
arguments to the constructor, the download will start immediately.
19-
The download is asynchronous and depending on the guiNotificationsEnabled
20-
parameter accepted by the constructor (default = true) the class will
21-
show a progress dialog and report all errors in a QMessageBox.warning dialog.
22-
If the guiNotificationsEnabled parameter is set to false, the class can still
23-
be used through the signals and slots mechanism.
19+
20+
The download is asynchronous.
21+
2422
The object will destroy itself when the request completes, errors or is canceled.
2523
An optional authentication configuration can be specified.
2624

27-
.. versionadded:: 2.18.1
25+
.. note::
26+
27+
This class was part of the GUI library from QGIS 2.18.1 until QGIS 3.0
28+
.. versionadded:: 3.0
2829
%End
2930

3031
%TypeHeaderCode
3132
#include "qgsfiledownloader.h"
3233
%End
3334
public:
3435

35-
QgsFileDownloader( const QUrl &url, const QString &outputFileName, bool guiNotificationsEnabled = true, const QString &authcfg = QString() );
36+
QgsFileDownloader( const QUrl &url, const QString &outputFileName, const QString &authcfg = QString(), bool delayStart = false );
3637
%Docstring
3738
QgsFileDownloader
3839
\param url the download url
3940
\param outputFileName file name where the downloaded content will be stored
40-
\param guiNotificationsEnabled if false, the downloader will not display any progress bar or error message
4141
\param authcfg optionally apply this authentication configuration
42+
\param delayStart if true, the download will not be commenced immediately and must
43+
be triggered by a later call to startDownload(). This can be useful if connections need
44+
to be made to the downloader and there's a chance the download will emit
45+
signals before these connections have been made.
4246
%End
4347

4448
signals:
@@ -50,10 +54,13 @@ Emitted when the download has completed successfully
5054
%Docstring
5155
Emitted always when the downloader exits
5256
%End
57+
5358
void downloadCanceled();
5459
%Docstring
55-
Emitted when the download was canceled by the user
60+
Emitted when the download was canceled by the user.
61+
.. seealso:: cancelDownload()
5662
%End
63+
5764
void downloadError( QStringList errorMessages );
5865
%Docstring
5966
Emitted when an error makes the download fail
@@ -65,13 +72,16 @@ Emitted when data are ready to be processed
6572

6673
public slots:
6774

68-
void onDownloadCanceled();
75+
void cancelDownload();
76+
%Docstring
77+
Call to abort the download and delete this object after the cancelation
78+
has been processed.
79+
.. seealso:: downloadCanceled()
80+
%End
81+
82+
void startDownload();
6983
%Docstring
70-
Called when a download is canceled by the user
71-
this slot aborts the download and deletes
72-
the object.
73-
Never call this slot directly: this is meant to
74-
be managed by the signal-slot system.
84+
Called to start the download
7585
%End
7686

7787
protected:
@@ -82,7 +92,7 @@ Emitted when data are ready to be processed
8292
/************************************************************************
8393
* This file has been generated automatically from *
8494
* *
85-
* src/gui/qgsfiledownloader.h *
95+
* src/core/qgsfiledownloader.h *
8696
* *
8797
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
8898
************************************************************************/

python/gui/gui_auto.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
%Include qgsuserinputdockwidget.sip
1919
%Include qgsbrowserdockwidget.sip
2020
%Include qgsvertexmarker.sip
21-
%Include qgsfiledownloader.sip
2221
%Include qgsabstractdatasourcewidget.sip
2322
%Include qgssourceselectprovider.sip
2423
%Include qgssourceselectproviderregistry.sip
@@ -201,6 +200,7 @@
201200
%Include qgstreewidgetitem.sip
202201
%Include qgsunitselectionwidget.sip
203202
%Include qgsvariableeditorwidget.sip
203+
%Include qgsfiledownloaderdialog.sip
204204
%Include raster/qgsmultibandcolorrendererwidget.sip
205205
%Include raster/qgspalettedrendererwidget.sip
206206
%Include raster/qgsrasterbandcombobox.sip
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/gui/qgsfiledownloaderdialog.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
class QgsFileDownloaderDialog : QProgressDialog
13+
{
14+
%Docstring
15+
QgsFileDownloaderDialog is a QProgressDialog subclass which
16+
handles file downloads and user feedback.
17+
18+
Internally, it uses QgsFileDownloader to handle the download,
19+
while showing progress via a progress dialog and supporting
20+
cancelation.
21+
22+
.. note::
23+
24+
Until QGIS 3.0 this functionality was available via QgsFileDownloader.
25+
26+
.. versionadded:: 3.0
27+
%End
28+
29+
%TypeHeaderCode
30+
#include "qgsfiledownloaderdialog.h"
31+
%End
32+
public:
33+
34+
QgsFileDownloaderDialog( const QUrl &url, const QString &outputFileName, const QString &authcfg = QString() );
35+
%Docstring
36+
QgsFileDownloader
37+
\param url the download url
38+
\param outputFileName file name where the downloaded content will be stored
39+
\param authcfg optionally apply this authentication configuration
40+
%End
41+
42+
signals:
43+
void downloadCompleted();
44+
%Docstring
45+
Emitted when the download has completed successfully
46+
%End
47+
void downloadExited();
48+
%Docstring
49+
Emitted always when the downloader exits
50+
%End
51+
void downloadCanceled();
52+
%Docstring
53+
Emitted when the download was canceled by the user
54+
%End
55+
void downloadError( QStringList errorMessages );
56+
%Docstring
57+
Emitted when an error makes the download fail
58+
%End
59+
void downloadProgress( qint64 bytesReceived, qint64 bytesTotal );
60+
%Docstring
61+
Emitted when data are ready to be processed
62+
%End
63+
64+
};
65+
66+
/************************************************************************
67+
* This file has been generated automatically from *
68+
* *
69+
* src/gui/qgsfiledownloaderdialog.h *
70+
* *
71+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
72+
************************************************************************/

src/app/qgsidentifyresultsdialog.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#include "qgswebframe.h"
4343
#include "qgsstringutils.h"
4444
#include "qgstreewidgetitem.h"
45-
#include "qgsfiledownloader.h"
45+
#include "qgsfiledownloaderdialog.h"
4646
#include "qgsfieldformatterregistry.h"
4747
#include "qgsfieldformatter.h"
4848
#include "qgssettings.h"
@@ -132,7 +132,7 @@ void QgsIdentifyResultsWebView::handleDownload( QUrl url )
132132
{
133133
settings.setValue( DOWNLOADER_LAST_DIR_KEY, QFileInfo( targetFile ).dir().absolutePath() );
134134
// Start the download
135-
new QgsFileDownloader( url, targetFile );
135+
new QgsFileDownloaderDialog( url, targetFile );
136136
}
137137
}
138138
}

src/core/CMakeLists.txt

100644100755
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ SET(QGIS_CORE_SRCS
182182
qgsfieldmodel.cpp
183183
qgsfieldproxymodel.cpp
184184
qgsfields.cpp
185+
qgsfiledownloader.cpp
185186
qgsfontutils.cpp
186187
qgsgeometrysimplifier.cpp
187188
qgsgeometryvalidator.cpp
@@ -588,6 +589,7 @@ SET(QGIS_CORE_MOC_HDRS
588589
qgsfieldformatterregistry.h
589590
qgsfieldmodel.h
590591
qgsfieldproxymodel.h
592+
qgsfiledownloader.h
591593
qgsgeometryvalidator.h
592594
qgsgml.h
593595
qgsgmlschema.h

src/gui/qgsfiledownloader.cpp renamed to src/core/qgsfiledownloader.cpp

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,18 @@
2121
#include <QNetworkAccessManager>
2222
#include <QNetworkRequest>
2323
#include <QNetworkReply>
24-
#include <QMessageBox>
2524
#ifndef QT_NO_SSL
2625
#include <QSslError>
2726
#endif
2827

29-
QgsFileDownloader::QgsFileDownloader( const QUrl &url, const QString &outputFileName, bool enableGuiNotifications, const QString &authcfg )
28+
QgsFileDownloader::QgsFileDownloader( const QUrl &url, const QString &outputFileName, const QString &authcfg, bool delayStart )
3029
: mUrl( url )
3130
, mDownloadCanceled( false )
32-
, mGuiNotificationsEnabled( enableGuiNotifications )
3331
{
3432
mFile.setFileName( outputFileName );
3533
mAuthCfg = authcfg;
36-
startDownload();
34+
if ( !delayStart )
35+
startDownload();
3736
}
3837

3938

@@ -44,10 +43,6 @@ QgsFileDownloader::~QgsFileDownloader()
4443
mReply->abort();
4544
mReply->deleteLater();
4645
}
47-
if ( mProgressDialog )
48-
{
49-
mProgressDialog->deleteLater();
50-
}
5146
}
5247

5348

@@ -83,17 +78,9 @@ void QgsFileDownloader::startDownload()
8378
#ifndef QT_NO_SSL
8479
connect( nam, &QgsNetworkAccessManager::sslErrors, this, &QgsFileDownloader::onSslErrors, Qt::UniqueConnection );
8580
#endif
86-
if ( mGuiNotificationsEnabled )
87-
{
88-
mProgressDialog = new QProgressDialog();
89-
mProgressDialog->setWindowTitle( tr( "Download" ) );
90-
mProgressDialog->setLabelText( tr( "Downloading %1." ).arg( mFile.fileName() ) );
91-
mProgressDialog->show();
92-
connect( mProgressDialog, &QProgressDialog::canceled, this, &QgsFileDownloader::onDownloadCanceled );
93-
}
9481
}
9582

96-
void QgsFileDownloader::onDownloadCanceled()
83+
void QgsFileDownloader::cancelDownload()
9784
{
9885
mDownloadCanceled = true;
9986
emit downloadCanceled();
@@ -126,11 +113,6 @@ void QgsFileDownloader::error( const QStringList &errorMessages )
126113
{
127114
mErrors << errorMessages[i];
128115
}
129-
// Show error
130-
if ( mGuiNotificationsEnabled )
131-
{
132-
QMessageBox::warning( nullptr, tr( "Download failed" ), mErrors.join( QStringLiteral( "<br>" ) ) );
133-
}
134116
emit downloadError( mErrors );
135117
}
136118

@@ -142,7 +124,12 @@ void QgsFileDownloader::error( const QString &errorMessage )
142124
void QgsFileDownloader::onReadyRead()
143125
{
144126
Q_ASSERT( mReply );
145-
if ( ! mFile.isOpen() && ! mFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
127+
if ( mFile.fileName().isEmpty() )
128+
{
129+
error( tr( "No output filename specified" ) );
130+
onFinished();
131+
}
132+
else if ( ! mFile.isOpen() && ! mFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
146133
{
147134
error( tr( "Cannot open output file: %1" ).arg( mFile.fileName() ) );
148135
onFinished();
@@ -159,18 +146,19 @@ void QgsFileDownloader::onFinished()
159146
// when canceled
160147
if ( ! mErrors.isEmpty() || mDownloadCanceled )
161148
{
162-
mFile.close();
163-
mFile.remove();
164-
if ( mGuiNotificationsEnabled )
165-
mProgressDialog->hide();
149+
if ( mFile.isOpen() )
150+
mFile.close();
151+
if ( mFile.exists() )
152+
mFile.remove();
166153
}
167154
else
168155
{
169156
// download finished normally
170-
if ( mGuiNotificationsEnabled )
171-
mProgressDialog->hide();
172-
mFile.flush();
173-
mFile.close();
157+
if ( mFile.isOpen() )
158+
{
159+
mFile.flush();
160+
mFile.close();
161+
}
174162

175163
// get redirection url
176164
QVariant redirectionTarget = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
@@ -206,11 +194,6 @@ void QgsFileDownloader::onDownloadProgress( qint64 bytesReceived, qint64 bytesTo
206194
{
207195
return;
208196
}
209-
if ( mGuiNotificationsEnabled )
210-
{
211-
mProgressDialog->setMaximum( bytesTotal );
212-
mProgressDialog->setValue( bytesReceived );
213-
}
214197
emit downloadProgress( bytesReceived, bytesTotal );
215198
}
216199

0 commit comments

Comments
 (0)