QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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 <QToolButton>
37#include <QVariant>
38
39#include "moc_qgsexternalresourcewidget.cpp"
40
41#ifdef WITH_QTWEBKIT
42#include <QWebView>
43#endif
44
46 : QWidget( parent )
47{
48 setBackgroundRole( QPalette::Window );
49 setAutoFillBackground( true );
50
51 QGridLayout *layout = new QGridLayout();
52 layout->setContentsMargins( 0, 0, 0, 0 );
53
54 mFileWidget = new QgsExternalStorageFileWidget( this );
55 layout->addWidget( mFileWidget, 0, 0 );
56 mFileWidget->setVisible( mFileWidgetVisible );
57
58 mPixmapLabel = new QgsPixmapLabel( this );
59 layout->addWidget( mPixmapLabel, 1, 0 );
60
61#ifdef WITH_QTWEBKIT
62 mWebView = new QWebView( this );
63 mWebView->setAcceptDrops( false );
64 layout->addWidget( mWebView, 2, 0 );
65#endif
66
67 mMediaWidget = new QgsMediaWidget( this );
68 layout->addWidget( mMediaWidget, 3, 0 );
69
70 mLoadingLabel = new QLabel( this );
71 layout->addWidget( mLoadingLabel, 4, 0 );
72 mLoadingMovie = new QMovie( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), QByteArray(), this );
73 mLoadingMovie->setScaledSize( QSize( 32, 32 ) );
74 mLoadingLabel->setMovie( mLoadingMovie );
75
76 mErrorLabel = new QLabel( this );
77 layout->addWidget( mErrorLabel, 5, 0 );
78 mErrorLabel->setPixmap( QPixmap( QgsApplication::iconPath( QStringLiteral( "/mIconWarning.svg" ) ) ) );
79
80 updateDocumentViewer();
81
82 setLayout( layout );
83
84 connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsExternalResourceWidget::loadDocument );
86}
87
88QVariant QgsExternalResourceWidget::documentPath( QMetaType::Type type ) const
89{
90 const QString path = mFileWidget->filePath();
91 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
92 {
94 }
95 else
96 {
97 return path;
98 }
99}
100
101QVariant QgsExternalResourceWidget::documentPath( QVariant::Type type ) const
102{
104}
105
106
108{
109 mFileWidget->setFilePath( path.toString() );
110}
111
116
118{
119 return mFileWidgetVisible;
120}
121
123{
124 mFileWidgetVisible = visible;
125 mFileWidget->setVisible( visible );
126}
127
132
134{
135 mDocumentViewerContent = content;
136 if ( mDocumentViewerContent != Image )
137 updateDocumentViewer();
138 loadDocument( mFileWidget->filePath() );
139}
140
142{
143 return mDocumentViewerHeight;
144}
145
147{
148 mDocumentViewerHeight = height;
149 updateDocumentViewer();
150}
151
153{
154 return mDocumentViewerWidth;
155}
156
158{
159 mDocumentViewerWidth = width;
160 updateDocumentViewer();
161}
162
164{
165 mFileWidget->setReadOnly( readOnly );
166}
167
168void QgsExternalResourceWidget::updateDocumentViewer()
169{
170 mErrorLabel->setVisible( false );
171 mLoadingLabel->setVisible( false );
172 mLoadingMovie->stop();
173
174 switch ( mDocumentViewerContent )
175 {
176 case Web:
177 {
178#ifdef WITH_QTWEBKIT
179 mWebView->setVisible( true );
180#endif
181 mMediaWidget->setVisible( false );
182 mPixmapLabel->setVisible( false );
183 break;
184 }
185
186 case Image:
187 {
188#ifdef WITH_QTWEBKIT
189 mWebView->setVisible( false );
190#endif
191 mMediaWidget->setVisible( false );
192 mPixmapLabel->setVisible( true );
193
194#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
195 const QPixmap pm = mPixmapLabel->pixmap() ? *mPixmapLabel->pixmap() : QPixmap();
196#else
197 const QPixmap pm = mPixmapLabel->pixmap();
198#endif
199
200 if ( !pm || pm.isNull() )
201 {
202 mPixmapLabel->setMinimumSize( QSize( 0, 0 ) );
203 }
204 else
205 {
206 QSize size( mDocumentViewerWidth, mDocumentViewerHeight );
207 if ( size.width() == 0 && size.height() > 0 )
208 {
209 size.setWidth( size.height() * pm.size().width() / pm.size().height() );
210 }
211 else if ( size.width() > 0 && size.height() == 0 )
212 {
213 size.setHeight( size.width() * pm.size().height() / pm.size().width() );
214 }
215
216 if ( size.width() != 0 || size.height() != 0 )
217 {
218 mPixmapLabel->setMinimumSize( size );
219 mPixmapLabel->setMaximumSize( size );
220 }
221 }
222 break;
223 }
224
225 case Audio:
226 case Video:
227 {
228#ifdef WITH_QTWEBKIT
229 mWebView->setVisible( false );
230#endif
231 mMediaWidget->setVisible( true );
232 mPixmapLabel->setVisible( false );
233
234 mMediaWidget->setMode( mDocumentViewerContent == Video ? QgsMediaWidget::Video : QgsMediaWidget::Audio );
235 mMediaWidget->setVideoHeight( mDocumentViewerHeight );
236 break;
237 }
238
239 case NoContent:
240 {
241#ifdef WITH_QTWEBKIT
242 mWebView->setVisible( false );
243#endif
244 mMediaWidget->setVisible( false );
245 mPixmapLabel->setVisible( false );
246 break;
247 }
248 }
249}
250
251QString QgsExternalResourceWidget::resolvePath( const QString &path )
252{
253 switch ( mRelativeStorage )
254 {
256 return path;
257 break;
259 return QFileInfo( QgsProject::instance()->absoluteFilePath() ).dir().filePath( path );
260 break;
262 return QDir( mDefaultRoot ).filePath( path );
263 break;
264 }
265 return QString(); // avoid warnings
266}
267
269{
270 return mDefaultRoot;
271}
272
274{
275 mFileWidget->setDefaultRoot( defaultRoot );
276 mDefaultRoot = defaultRoot;
277}
278
283
285{
286 mFileWidget->setRelativeStorage( relativeStorage );
287 mRelativeStorage = relativeStorage;
288}
289
291{
292 mFileWidget->setStorageType( storageType );
293}
294
296{
297 return mFileWidget->storageType();
298}
299
301{
302 mFileWidget->setStorageAuthConfigId( authCfg );
303}
304
306{
307 return mFileWidget->storageAuthConfigId();
308}
309
311{
312 mFileWidget->setMessageBar( messageBar );
313}
314
316{
317 return mFileWidget->messageBar();
318}
319
320void QgsExternalResourceWidget::updateDocumentContent( const QString &filePath )
321{
322 switch ( mDocumentViewerContent )
323 {
324 case Web:
325 {
326#ifdef WITH_QTWEBKIT
327 mWebView->load( QUrl::fromUserInput( filePath.toUtf8() ) );
328 mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
329#endif
330 break;
331 }
332
333 case Image:
334 {
335 QImageReader ir( filePath );
336 // ensure image orientation and transforms are correctly handled
337 ir.setAutoTransform( true );
338 const QPixmap pm = QPixmap::fromImage( ir.read() );
339 if ( !pm.isNull() )
340 {
341 mPixmapLabel->setPixmap( pm );
342 }
343 else
344 {
345 mPixmapLabel->clear();
346 }
347 break;
348 }
349
350 case Audio:
351 case Video:
352 {
353 mMediaWidget->setMediaPath( filePath );
354 break;
355 }
356
357 case NoContent:
358 {
359 break;
360 }
361 }
362
363 updateDocumentViewer();
364}
365
366void QgsExternalResourceWidget::clearContent()
367{
368#ifdef WITH_QTWEBKIT
369 if ( mDocumentViewerContent == Web )
370 {
371 mWebView->load( QUrl( QStringLiteral( "about:blank" ) ) );
372 }
373#endif
374 if ( mDocumentViewerContent == Image )
375 {
376 mPixmapLabel->clear();
377 }
378
379 updateDocumentViewer();
380}
381
382void QgsExternalResourceWidget::loadDocument( const QString &path )
383{
384 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
385 {
386 if ( mFileWidget->externalStorage() && mContent )
387 {
388 mContent->cancel();
389 mContent.clear();
390 }
391
392 clearContent();
393 }
394 else if ( mDocumentViewerContent != NoContent )
395 {
396 const QString resolvedPath = resolvePath( path );
397
398 if ( mFileWidget->externalStorage() )
399 {
400 if ( mContent )
401 {
402 mContent->cancel();
403 }
404
405 mContent = mFileWidget->externalStorage()->fetch( resolvedPath, storageAuthConfigId() );
406
407#ifdef WITH_QTWEBKIT
408 mWebView->setVisible( false );
409#endif
410 mMediaWidget->setVisible( false );
411 mPixmapLabel->setVisible( false );
412 mErrorLabel->setVisible( false );
413 mLoadingLabel->setVisible( true );
414 mLoadingMovie->start();
415 connect( mContent, &QgsExternalStorageFetchedContent::fetched, this, &QgsExternalResourceWidget::onFetchFinished );
416 connect( mContent, &QgsExternalStorageFetchedContent::errorOccurred, this, &QgsExternalResourceWidget::onFetchFinished );
417 connect( mContent, &QgsExternalStorageFetchedContent::canceled, this, &QgsExternalResourceWidget::onFetchFinished );
418
419 mContent->fetch();
420 }
421 else
422 {
423 updateDocumentContent( resolvedPath );
424 }
425 }
426}
427
428void QgsExternalResourceWidget::onFetchFinished()
429{
430 QgsExternalStorageFetchedContent *content = qobject_cast<QgsExternalStorageFetchedContent *>( sender() );
431
432 if ( content == mContent && mContent->status() == Qgis::ContentStatus::Failed )
433 {
434#ifdef WITH_QTWEBKIT
435 mWebView->setVisible( false );
436#endif
437 mPixmapLabel->setVisible( false );
438 mLoadingLabel->setVisible( false );
439 mLoadingMovie->stop();
440 mErrorLabel->setVisible( true );
441
442 if ( messageBar() )
443 {
444 messageBar()->pushWarning( tr( "Fetching External Resource" ), tr( "Error while fetching external resource '%1' : %2" ).arg( mFileWidget->filePath(), mContent->errorString() ) );
445 }
446 }
447 else if ( content == mContent && mContent->status() == Qgis::ContentStatus::Finished )
448 {
449 const QString filePath = mDocumentViewerContent == Web
450 ? QUrl::fromLocalFile( mContent->filePath() ).toString()
451 : mContent->filePath();
452
453 updateDocumentContent( filePath );
454 }
455
456 content->deleteLater();
457}
@ Finished
Content fetching/storing is finished and successful.
Definition qgis.h:1848
@ Failed
Content fetching/storing has failed.
Definition qgis.h:1849
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...
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.