@@ -27,104 +27,30 @@ QgsNetworkContentFetcherRegistry::QgsNetworkContentFetcherRegistry()
2727
2828QgsNetworkContentFetcherRegistry::~QgsNetworkContentFetcherRegistry ()
2929{
30- QMap<QUrl , QgsFetchedContent *>::const_iterator it = mFileRegistry .constBegin ();
30+ QMap<QString , QgsFetchedContent *>::const_iterator it = mFileRegistry .constBegin ();
3131 for ( ; it != mFileRegistry .constEnd (); ++it )
3232 {
3333 delete it.value ();
3434 }
3535 mFileRegistry .clear ();
3636}
3737
38- const QgsFetchedContent *QgsNetworkContentFetcherRegistry::fetch ( const QUrl &url, const FetchingMode fetchingMode )
38+ const QgsFetchedContent *QgsNetworkContentFetcherRegistry::fetch ( const QString &url, const FetchingMode fetchingMode )
3939{
40- QMutexLocker locker ( & mMutex );
40+
4141 if ( mFileRegistry .contains ( url ) )
4242 {
4343 return mFileRegistry .value ( url );
4444 }
4545
46- QgsFetchedContent *content = new QgsFetchedContent ( nullptr , QgsFetchedContent::NotStarted );
47-
48- // start
49- QObject::connect ( content, &QgsFetchedContent::downloadStarted, this , [ = ]( const bool redownload )
50- {
51- if ( redownload && content->status () == QgsFetchedContent::Downloading )
52- {
53- {
54- QMutexLocker locker ( &mMutex );
55- if ( content->mFetchingTask )
56- disconnect ( content->mFetchingTask , &QgsNetworkContentFetcherTask::fetched, content, &QgsFetchedContent::taskCompleted );
57- }
58- // no locker when calling cancel!
59- content->cancel ();
60- }
61- QMutexLocker locker ( &mMutex );
62- if ( redownload ||
63- content->status () == QgsFetchedContent::NotStarted ||
64- content->status () == QgsFetchedContent::Failed )
65- {
66- content->mFetchingTask = new QgsNetworkContentFetcherTask ( url );
67- connect ( content->mFetchingTask , &QgsNetworkContentFetcherTask::fetched, content, &QgsFetchedContent::taskCompleted );
68- QgsApplication::instance ()->taskManager ()->addTask ( content->mFetchingTask );
69- content->mStatus = QgsFetchedContent::Downloading;
70- }
71- } );
72-
73- // cancel
74- QObject::connect ( content, &QgsFetchedContent::cancelTriggered, this , [ = ]()
75- {
76- QMutexLocker locker ( &mMutex );
77- if ( content->mFetchingTask && content->mFetchingTask ->canCancel () )
78- {
79- content->mFetchingTask ->cancel ();
80- }
81- if ( content->mFile )
82- {
83- content->mFile ->deleteLater ();
84- content->mFilePath = QString ();
85- }
86- } );
87-
88- // finished
89- connect ( content, &QgsFetchedContent::taskCompleted, this , [ = ]()
90- {
91- QMutexLocker locker ( &mMutex );
92- if ( !content->mFetchingTask || !content->mFetchingTask ->reply () )
93- {
94- // if no reply, it has been canceled
95- content->mStatus = QgsFetchedContent::Failed;
96- content->mError = QNetworkReply::OperationCanceledError;
97- content->mFilePath = QString ();
98- }
99- else
100- {
101- QNetworkReply *reply = content->mFetchingTask ->reply ();
102- if ( reply->error () == QNetworkReply::NoError )
103- {
104- QTemporaryFile *tf = new QTemporaryFile ( QStringLiteral ( " XXXXXX" ) );
105- content->mFile = tf;
106- tf->open ();
107- content->mFile ->write ( reply->readAll () );
108- // Qt docs notes that on some system if fileName is not called before close, file might get deleted
109- content->mFilePath = tf->fileName ();
110- tf->close ();
111- content->mStatus = QgsFetchedContent::Finished;
112- }
113- else
114- {
115- content->mStatus = QgsFetchedContent::Failed;
116- content->mError = reply->error ();
117- content->mFilePath = QString ();
118- }
119- }
120- content->emitFetched ();
121- } );
46+ QgsFetchedContent *content = new QgsFetchedContent ( url, nullptr , QgsFetchedContent::NotStarted );
12247
12348 mFileRegistry .insert ( url, content );
12449
12550 if ( fetchingMode == DownloadImmediately )
12651 content->download ();
12752
53+
12854 return content;
12955}
13056
@@ -135,11 +61,10 @@ QFile *QgsNetworkContentFetcherRegistry::localFile( const QString &filePathOrUrl
13561
13662 if ( !QUrl::fromUserInput ( filePathOrUrl ).isLocalFile () )
13763 {
138- QMutexLocker locker ( &mMutex );
139- if ( mFileRegistry .contains ( QUrl ( path ) ) )
64+ if ( mFileRegistry .contains ( path ) )
14065 {
141- const QgsFetchedContent *content = mFileRegistry .value ( QUrl ( path ) );
142- if ( content->status () == QgsFetchedContent::Finished && ! content->file () )
66+ const QgsFetchedContent *content = mFileRegistry .value ( path );
67+ if ( content && content ->status () == QgsFetchedContent::Finished && content->file () )
14368 {
14469 file = content->file ();
14570 }
@@ -166,10 +91,9 @@ QString QgsNetworkContentFetcherRegistry::localPath( const QString &filePathOrUr
16691
16792 if ( !QUrl::fromUserInput ( filePathOrUrl ).isLocalFile () )
16893 {
169- QMutexLocker locker ( &mMutex );
170- if ( mFileRegistry .contains ( QUrl ( path ) ) )
94+ if ( mFileRegistry .contains ( path ) )
17195 {
172- const QgsFetchedContent *content = mFileRegistry .value ( QUrl ( path ) );
96+ const QgsFetchedContent *content = mFileRegistry .value ( path );
17397 if ( content->status () == QgsFetchedContent::Finished && !content->filePath ().isEmpty () )
17498 {
17599 path = content->filePath ();
@@ -190,3 +114,75 @@ QString QgsNetworkContentFetcherRegistry::localPath( const QString &filePathOrUr
190114
191115
192116
117+
118+ void QgsFetchedContent::download ( bool redownload )
119+ {
120+
121+ if ( redownload && status () == QgsFetchedContent::Downloading )
122+ {
123+ {
124+ if ( mFetchingTask )
125+ disconnect ( mFetchingTask , &QgsNetworkContentFetcherTask::taskCompleted, this , &QgsFetchedContent::taskCompleted );
126+ }
127+ cancel ();
128+ }
129+ if ( redownload ||
130+ status () == QgsFetchedContent::NotStarted ||
131+ status () == QgsFetchedContent::Failed )
132+ {
133+ mFetchingTask = new QgsNetworkContentFetcherTask ( mUrl );
134+ // use taskCompleted which is main thread rather than fetched signal in worker thread
135+ connect ( mFetchingTask , &QgsNetworkContentFetcherTask::taskCompleted, this , &QgsFetchedContent::taskCompleted );
136+ QgsApplication::instance ()->taskManager ()->addTask ( mFetchingTask );
137+ mStatus = QgsFetchedContent::Downloading;
138+ }
139+
140+ }
141+
142+ void QgsFetchedContent::cancel ()
143+ {
144+ if ( mFetchingTask && mFetchingTask ->canCancel () )
145+ {
146+ mFetchingTask ->cancel ();
147+ }
148+ if ( mFile )
149+ {
150+ mFile ->deleteLater ();
151+ mFilePath = QString ();
152+ }
153+ }
154+
155+
156+ void QgsFetchedContent::taskCompleted ()
157+ {
158+ if ( !mFetchingTask || !mFetchingTask ->reply () )
159+ {
160+ // if no reply, it has been canceled
161+ mStatus = QgsFetchedContent::Failed;
162+ mError = QNetworkReply::OperationCanceledError;
163+ mFilePath = QString ();
164+ }
165+ else
166+ {
167+ QNetworkReply *reply = mFetchingTask ->reply ();
168+ if ( reply->error () == QNetworkReply::NoError )
169+ {
170+ QTemporaryFile *tf = new QTemporaryFile ( QStringLiteral ( " XXXXXX" ) );
171+ mFile = tf;
172+ tf->open ();
173+ mFile ->write ( reply->readAll () );
174+ // Qt docs notes that on some system if fileName is not called before close, file might get deleted
175+ mFilePath = tf->fileName ();
176+ tf->close ();
177+ mStatus = QgsFetchedContent::Finished;
178+ }
179+ else
180+ {
181+ mStatus = QgsFetchedContent::Failed;
182+ mError = reply->error ();
183+ mFilePath = QString ();
184+ }
185+ }
186+
187+ emit fetched ();
188+ }
0 commit comments