QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsexternalresourcewidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsexternalresourcewidget.cpp
3
4 ---------------------
5 begin : 16.12.2015
6 copyright : (C) 2015 by Denis Rouzaud
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18
19#include "qgsapplication.h"
20#include "qgsexternalstorage.h"
22#include "qgsmediawidget.h"
23#include "qgsmessagebar.h"
25#include "qgspixmaplabel.h"
26#include "qgsproject.h"
27#include "qgstaskmanager.h"
28
29#include <QDir>
30#include <QGridLayout>
31#include <QImageReader>
32#include <QMimeDatabase>
33#include <QMimeType>
34#include <QMovie>
35#include <QSettings>
36#include <QString>
37#include <QToolButton>
38#include <QVariant>
39
40#include "moc_qgsexternalresourcewidget.cpp"
41
42using namespace Qt::StringLiterals;
43
45 : QWidget( parent )
46{
47 setBackgroundRole( QPalette::Window );
48 setAutoFillBackground( true );
49
50 QGridLayout *layout = new QGridLayout();
51 layout->setContentsMargins( 0, 0, 0, 0 );
52
53 mFileWidget = new QgsExternalStorageFileWidget( this );
54 layout->addWidget( mFileWidget, 0, 0 );
55 mFileWidget->setVisible( mFileWidgetVisible );
56
57 mPixmapLabel = new QgsPixmapLabel( this );
58 layout->addWidget( mPixmapLabel, 1, 0 );
59
60 mMediaWidget = new QgsMediaWidget( this );
61 layout->addWidget( mMediaWidget, 3, 0 );
62
63 mLoadingLabel = new QLabel( this );
64 layout->addWidget( mLoadingLabel, 4, 0 );
65 mLoadingMovie = new QMovie( QgsApplication::iconPath( u"/mIconLoading.gif"_s ), QByteArray(), this );
66 mLoadingMovie->setScaledSize( QSize( 32, 32 ) );
67 mLoadingLabel->setMovie( mLoadingMovie );
68
69 mErrorLabel = new QLabel( this );
70 layout->addWidget( mErrorLabel, 5, 0 );
71 mErrorLabel->setPixmap( QPixmap( QgsApplication::iconPath( u"/mIconWarning.svg"_s ) ) );
72
73 updateDocumentViewer();
74
75 setLayout( layout );
76
77 connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsExternalResourceWidget::loadDocument );
79}
80
81QVariant QgsExternalResourceWidget::documentPath( QMetaType::Type type ) const
82{
83 const QString path = mFileWidget->filePath();
84 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
85 {
87 }
88 else
89 {
90 return path;
91 }
92}
93
94QVariant QgsExternalResourceWidget::documentPath( QVariant::Type type ) const
95{
97}
98
99
101{
102 mFileWidget->setFilePath( path.toString() );
103}
104
109
111{
112 return mFileWidgetVisible;
113}
114
116{
117 mFileWidgetVisible = visible;
118 mFileWidget->setVisible( visible );
119}
120
125
127{
128 mDocumentViewerContent = content;
129 if ( mDocumentViewerContent != Image )
130 updateDocumentViewer();
131 loadDocument( mFileWidget->filePath() );
132}
133
135{
136 return mDocumentViewerHeight;
137}
138
140{
141 mDocumentViewerHeight = height;
142 updateDocumentViewer();
143}
144
146{
147 return mDocumentViewerWidth;
148}
149
151{
152 mDocumentViewerWidth = width;
153 updateDocumentViewer();
154}
155
157{
158 mFileWidget->setReadOnly( readOnly );
159}
160
161void QgsExternalResourceWidget::updateDocumentViewer()
162{
163 mErrorLabel->setVisible( false );
164 mLoadingLabel->setVisible( false );
165 mLoadingMovie->stop();
166
167 switch ( mDocumentViewerContent )
168 {
169 case Web:
170 {
171 mMediaWidget->setVisible( false );
172 mPixmapLabel->setVisible( false );
173 break;
174 }
175
176 case Image:
177 {
178 mMediaWidget->setVisible( false );
179 mPixmapLabel->setVisible( true );
180
181 const QPixmap pm = mPixmapLabel->pixmap();
182
183 if ( !pm || pm.isNull() )
184 {
185 mPixmapLabel->setMinimumSize( QSize( 0, 0 ) );
186 }
187 else
188 {
189 QSize size( mDocumentViewerWidth, mDocumentViewerHeight );
190 if ( size.width() == 0 && size.height() > 0 )
191 {
192 size.setWidth( size.height() * pm.size().width() / pm.size().height() );
193 }
194 else if ( size.width() > 0 && size.height() == 0 )
195 {
196 size.setHeight( size.width() * pm.size().height() / pm.size().width() );
197 }
198
199 if ( size.width() != 0 || size.height() != 0 )
200 {
201 mPixmapLabel->setMinimumSize( size );
202 mPixmapLabel->setMaximumSize( size );
203 }
204 }
205 break;
206 }
207
208 case Audio:
209 case Video:
210 {
211 mMediaWidget->setVisible( true );
212 mPixmapLabel->setVisible( false );
213
214 mMediaWidget->setMode( mDocumentViewerContent == Video ? QgsMediaWidget::Video : QgsMediaWidget::Audio );
215 mMediaWidget->setVideoHeight( mDocumentViewerHeight );
216 break;
217 }
218
219 case NoContent:
220 {
221 mMediaWidget->setVisible( false );
222 mPixmapLabel->setVisible( false );
223 break;
224 }
225 }
226}
227
228QString QgsExternalResourceWidget::resolvePath( const QString &path )
229{
230 switch ( mRelativeStorage )
231 {
233 return path;
234 break;
236 return QFileInfo( QgsProject::instance()->absoluteFilePath() ).dir().filePath( path );
237 break;
239 return QDir( mDefaultRoot ).filePath( path );
240 break;
241 }
242 return QString(); // avoid warnings
243}
244
246{
247 return mDefaultRoot;
248}
249
251{
252 mFileWidget->setDefaultRoot( defaultRoot );
253 mDefaultRoot = defaultRoot;
254}
255
260
262{
263 mFileWidget->setRelativeStorage( relativeStorage );
264 mRelativeStorage = relativeStorage;
265}
266
268{
269 mFileWidget->setStorageType( storageType );
270}
271
273{
274 return mFileWidget->storageType();
275}
276
278{
279 mFileWidget->setStorageAuthConfigId( authCfg );
280}
281
283{
284 return mFileWidget->storageAuthConfigId();
285}
286
288{
289 mFileWidget->setMessageBar( messageBar );
290}
291
293{
294 return mFileWidget->messageBar();
295}
296
297void QgsExternalResourceWidget::updateDocumentContent( const QString &filePath )
298{
299 switch ( mDocumentViewerContent )
300 {
301 case Image:
302 {
303 QImageReader ir( filePath );
304 // ensure image orientation and transforms are correctly handled
305 ir.setAutoTransform( true );
306 const QPixmap pm = QPixmap::fromImage( ir.read() );
307 if ( !pm.isNull() )
308 {
309 mPixmapLabel->setPixmap( pm );
310 }
311 else
312 {
313 mPixmapLabel->clear();
314 }
315 break;
316 }
317
318 case Audio:
319 case Video:
320 {
321 mMediaWidget->setMediaPath( filePath );
322 break;
323 }
324
325 case Web:
326 case NoContent:
327 {
328 break;
329 }
330 }
331
332 updateDocumentViewer();
333}
334
335void QgsExternalResourceWidget::clearContent()
336{
337 if ( mDocumentViewerContent == Image )
338 {
339 mPixmapLabel->clear();
340 }
341
342 updateDocumentViewer();
343}
344
345void QgsExternalResourceWidget::loadDocument( const QString &path )
346{
347 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
348 {
349 if ( mFileWidget->externalStorage() && mContent )
350 {
351 mContent->cancel();
352 mContent.clear();
353 }
354
355 clearContent();
356 }
357 else if ( mDocumentViewerContent != NoContent )
358 {
359 const QString resolvedPath = resolvePath( path );
360
361 if ( mFileWidget->externalStorage() )
362 {
363 if ( mContent )
364 {
365 mContent->cancel();
366 }
367
368 mContent = mFileWidget->externalStorage()->fetch( resolvedPath, storageAuthConfigId() );
369
370 mMediaWidget->setVisible( false );
371 mPixmapLabel->setVisible( false );
372 mErrorLabel->setVisible( false );
373 mLoadingLabel->setVisible( true );
374 mLoadingMovie->start();
375 connect( mContent, &QgsExternalStorageFetchedContent::fetched, this, &QgsExternalResourceWidget::onFetchFinished );
376 connect( mContent, &QgsExternalStorageFetchedContent::errorOccurred, this, &QgsExternalResourceWidget::onFetchFinished );
377 connect( mContent, &QgsExternalStorageFetchedContent::canceled, this, &QgsExternalResourceWidget::onFetchFinished );
378
379 mContent->fetch();
380 }
381 else
382 {
383 updateDocumentContent( resolvedPath );
384 }
385 }
386}
387
388void QgsExternalResourceWidget::onFetchFinished()
389{
390 QgsExternalStorageFetchedContent *content = qobject_cast<QgsExternalStorageFetchedContent *>( sender() );
391
392 if ( content == mContent && mContent->status() == Qgis::ContentStatus::Failed )
393 {
394 mPixmapLabel->setVisible( false );
395 mLoadingLabel->setVisible( false );
396 mLoadingMovie->stop();
397 mErrorLabel->setVisible( true );
398
399 if ( messageBar() )
400 {
401 messageBar()->pushWarning( tr( "Fetching External Resource" ), tr( "Error while fetching external resource '%1' : %2" ).arg( mFileWidget->filePath(), mContent->errorString() ) );
402 }
403 }
404 else if ( content == mContent && mContent->status() == Qgis::ContentStatus::Finished )
405 {
406 const QString filePath = mDocumentViewerContent == Web
407 ? QUrl::fromLocalFile( mContent->filePath() ).toString()
408 : mContent->filePath();
409
410 updateDocumentContent( filePath );
411 }
412
413 content->deleteLater();
414}
@ Finished
Content fetching/storing is finished and successful.
Definition qgis.h:1906
@ Failed
Content fetching/storing has failed.
Definition qgis.h:1907
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
void setDocumentPath(const QVariant &documentPath)
void setMessageBar(QgsMessageBar *messageBar)
Set messageBar to report messages.
void setStorageAuthConfigId(const QString &authCfg)
Sets the authentication configuration ID to be used for the current external storage (if defined).
QgsMessageBar * messageBar() const
Returns message bar used to report messages.
QgsExternalStorageFileWidget * fileWidget()
Returns file widget to allow its configuration.
QgsExternalResourceWidget(QWidget *parent=nullptr)
QgsExternalResourceWidget creates a widget with a file widget and a document viewer Both part of the ...
void setStorageType(const QString &storageType)
Set storageType storage type unique identifier as defined in QgsExternalStorageRegistry or an empty Q...
void setRelativeStorage(QgsFileWidget::RelativeStorage relativeStorage)
Configures if paths are handled absolute or relative and if relative, which should be the base path.
void setDocumentViewerHeight(int height)
setDocumentViewerWidth set the height of the document viewer.
QString storageType() const
Returns storage type unique identifier as defined in QgsExternalStorageRegistry.
void setDocumentViewerContent(QgsExternalResourceWidget::DocumentViewerContent content)
setDocumentViewerContent defines the type of content to be shown. Widget will be adapted accordingly
DocumentViewerContent documentViewerContent
QString storageAuthConfigId() const
Returns the authentication configuration ID used for the current external storage (if defined).
void setDefaultRoot(const QString &defaultRoot)
Configures the base path which should be used if the relativeStorage property is set to QgsFileWidget...
QgsFileWidget::RelativeStorage relativeStorage
void setDocumentViewerWidth(int width)
setDocumentViewerWidth set the width of the document viewer.
void setFileWidgetVisible(bool visible)
Sets the visibility of the file widget in the layout.
QVariant documentPath(QMetaType::Type type=QMetaType::Type::QString) const
documentPath returns the path of the current document in the widget
void valueChanged(const QString &value)
Emitted as soon as the current document changes.
void setReadOnly(bool readOnly)
defines if the widget is readonly
void canceled()
The signal is emitted when content fetching/storing has been canceled.
void errorOccurred(const QString &errorString)
The signal is emitted when an error occurred.
void fetched()
The signal is emitted when the resource has successfully been fetched.
A widget for selecting a file or a folder and optionally storing it to an external storage backend.
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
RelativeStorage
The RelativeStorage enum determines if path is absolute, relative to the current project path or rela...
A widget for playing back audio and video media files.
@ Video
Video-centric user interface.
@ Audio
Audio-centric user interface.
A bar for displaying non-blocking messages to the user.
void pushWarning(const QString &title, const QString &message)
Pushes a warning message that must be manually dismissed by the user.
Shows a pixmap and adjusts its size to the space given to the widget by the layout and keeping its as...
void setPixmap(const QPixmap &)
static QgsProject * instance()
Returns the QgsProject singleton instance.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.