QGIS API Documentation 3.37.0-Master (49cede7946b)
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#include "qgspixmaplabel.h"
19#include "qgsproject.h"
20#include "qgsapplication.h"
21#include "qgsmediawidget.h"
23#include "qgstaskmanager.h"
24#include "qgsexternalstorage.h"
25#include "qgsmessagebar.h"
27
28#include <QDir>
29#include <QGridLayout>
30#include <QVariant>
31#include <QSettings>
32#include <QImageReader>
33#include <QToolButton>
34#include <QMimeType>
35#include <QMimeDatabase>
36#include <QMovie>
37#ifdef WITH_QTWEBKIT
38#include <QWebView>
39#endif
40
42 : QWidget( parent )
43{
44 setBackgroundRole( QPalette::Window );
45 setAutoFillBackground( true );
46
47 QGridLayout *layout = new QGridLayout();
48 layout->setContentsMargins( 0, 0, 0, 0 );
49
50 mFileWidget = new QgsExternalStorageFileWidget( this );
51 layout->addWidget( mFileWidget, 0, 0 );
52 mFileWidget->setVisible( mFileWidgetVisible );
53
54 mPixmapLabel = new QgsPixmapLabel( this );
55 layout->addWidget( mPixmapLabel, 1, 0 );
56
57#ifdef WITH_QTWEBKIT
58 mWebView = new QWebView( this );
59 mWebView->setAcceptDrops( false );
60 layout->addWidget( mWebView, 2, 0 );
61#endif
62
63 mMediaWidget = new QgsMediaWidget( this );
64 layout->addWidget( mMediaWidget, 3, 0 );
65
66 mLoadingLabel = new QLabel( this );
67 layout->addWidget( mLoadingLabel, 4, 0 );
68 mLoadingMovie = new QMovie( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), QByteArray(), this );
69 mLoadingMovie->setScaledSize( QSize( 32, 32 ) );
70 mLoadingLabel->setMovie( mLoadingMovie );
71
72 mErrorLabel = new QLabel( this );
73 layout->addWidget( mErrorLabel, 5, 0 );
74 mErrorLabel->setPixmap( QPixmap( QgsApplication::iconPath( QStringLiteral( "/mIconWarning.svg" ) ) ) );
75
76 updateDocumentViewer();
77
78 setLayout( layout );
79
80 connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsExternalResourceWidget::loadDocument );
82}
83
84QVariant QgsExternalResourceWidget::documentPath( QMetaType::Type type ) const
85{
86 const QString path = mFileWidget->filePath();
87 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
88 {
90 }
91 else
92 {
93 return path;
94 }
95}
96
97QVariant QgsExternalResourceWidget::documentPath( QVariant::Type type ) const
98{
100}
101
102
104{
105 mFileWidget->setFilePath( path.toString() );
106}
107
112
114{
115 return mFileWidgetVisible;
116}
117
119{
120 mFileWidgetVisible = visible;
121 mFileWidget->setVisible( visible );
122}
123
128
130{
131 mDocumentViewerContent = content;
132 if ( mDocumentViewerContent != Image )
133 updateDocumentViewer();
134 loadDocument( mFileWidget->filePath() );
135}
136
138{
139 return mDocumentViewerHeight;
140}
141
143{
144 mDocumentViewerHeight = height;
145 updateDocumentViewer();
146}
147
149{
150 return mDocumentViewerWidth;
151}
152
154{
155 mDocumentViewerWidth = width;
156 updateDocumentViewer();
157}
158
160{
161 mFileWidget->setReadOnly( readOnly );
162}
163
164void QgsExternalResourceWidget::updateDocumentViewer()
165{
166 mErrorLabel->setVisible( false );
167 mLoadingLabel->setVisible( false );
168 mLoadingMovie->stop();
169
170 switch ( mDocumentViewerContent )
171 {
172 case Web:
173 {
174#ifdef WITH_QTWEBKIT
175 mWebView->setVisible( true );
176#endif
177 mMediaWidget->setVisible( false );
178 mPixmapLabel->setVisible( false );
179 break;
180 }
181
182 case Image:
183 {
184#ifdef WITH_QTWEBKIT
185 mWebView->setVisible( false );
186#endif
187 mMediaWidget->setVisible( false );
188 mPixmapLabel->setVisible( true );
189
190#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
191 const QPixmap pm = mPixmapLabel->pixmap() ? *mPixmapLabel->pixmap() : QPixmap();
192#else
193 const QPixmap pm = mPixmapLabel->pixmap();
194#endif
195
196 if ( !pm || pm.isNull() )
197 {
198 mPixmapLabel->setMinimumSize( QSize( 0, 0 ) );
199 }
200 else
201 {
202 QSize size( mDocumentViewerWidth, mDocumentViewerHeight );
203 if ( size.width() == 0 && size.height() > 0 )
204 {
205 size.setWidth( size.height() * pm.size().width() / pm.size().height() );
206 }
207 else if ( size.width() > 0 && size.height() == 0 )
208 {
209 size.setHeight( size.width() * pm.size().height() / pm.size().width() );
210 }
211
212 if ( size.width() != 0 || size.height() != 0 )
213 {
214 mPixmapLabel->setMinimumSize( size );
215 mPixmapLabel->setMaximumSize( size );
216 }
217 }
218 break;
219 }
220
221 case Audio:
222 case Video:
223 {
224#ifdef WITH_QTWEBKIT
225 mWebView->setVisible( false );
226#endif
227 mMediaWidget->setVisible( true );
228 mPixmapLabel->setVisible( false );
229
230 mMediaWidget->setMode( mDocumentViewerContent == Video ? QgsMediaWidget::Video : QgsMediaWidget::Audio );
231 mMediaWidget->setVideoHeight( mDocumentViewerHeight );
232 break;
233 }
234
235 case NoContent:
236 {
237#ifdef WITH_QTWEBKIT
238 mWebView->setVisible( false );
239#endif
240 mMediaWidget->setVisible( false );
241 mPixmapLabel->setVisible( false );
242 break;
243 }
244 }
245}
246
247QString QgsExternalResourceWidget::resolvePath( const QString &path )
248{
249 switch ( mRelativeStorage )
250 {
252 return path;
253 break;
255 return QFileInfo( QgsProject::instance()->absoluteFilePath() ).dir().filePath( path );
256 break;
258 return QDir( mDefaultRoot ).filePath( path );
259 break;
260 }
261 return QString(); // avoid warnings
262}
263
265{
266 return mDefaultRoot;
267}
268
269void QgsExternalResourceWidget::setDefaultRoot( const QString &defaultRoot )
270{
271 mFileWidget->setDefaultRoot( defaultRoot );
272 mDefaultRoot = defaultRoot;
273}
274
279
285
286void QgsExternalResourceWidget::setStorageType( const QString &storageType )
287{
288 mFileWidget->setStorageType( storageType );
289}
290
292{
293 return mFileWidget->storageType();
294}
295
297{
298 mFileWidget->setStorageAuthConfigId( authCfg );
299}
300
302{
303 return mFileWidget->storageAuthConfigId();
304}
305
307{
308 mFileWidget->setMessageBar( messageBar );
309}
310
312{
313 return mFileWidget->messageBar();
314}
315
316void QgsExternalResourceWidget::updateDocumentContent( const QString &filePath )
317{
318 switch ( mDocumentViewerContent )
319 {
320 case Web:
321 {
322#ifdef WITH_QTWEBKIT
323 mWebView->load( QUrl::fromUserInput( filePath.toUtf8() ) );
324 mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
325#endif
326 break;
327 }
328
329 case Image:
330 {
331 QImageReader ir( filePath );
332 // ensure image orientation and transforms are correctly handled
333 ir.setAutoTransform( true );
334 const QPixmap pm = QPixmap::fromImage( ir.read() );
335 if ( !pm.isNull() )
336 {
337 mPixmapLabel->setPixmap( pm );
338 }
339 else
340 {
341 mPixmapLabel->clear();
342 }
343 break;
344 }
345
346 case Audio:
347 case Video:
348 {
349 mMediaWidget->setMediaPath( filePath );
350 break;
351 }
352
353 case NoContent:
354 {
355 break;
356 }
357 }
358
359 updateDocumentViewer();
360}
361
362void QgsExternalResourceWidget::clearContent()
363{
364#ifdef WITH_QTWEBKIT
365 if ( mDocumentViewerContent == Web )
366 {
367 mWebView->load( QUrl( QStringLiteral( "about:blank" ) ) );
368 }
369#endif
370 if ( mDocumentViewerContent == Image )
371 {
372 mPixmapLabel->clear();
373 }
374
375 updateDocumentViewer();
376}
377
378void QgsExternalResourceWidget::loadDocument( const QString &path )
379{
380 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
381 {
382 if ( mFileWidget->externalStorage() && mContent )
383 {
384 mContent->cancel();
385 mContent.clear();
386 }
387
388 clearContent();
389 }
390 else if ( mDocumentViewerContent != NoContent )
391 {
392 const QString resolvedPath = resolvePath( path );
393
394 if ( mFileWidget->externalStorage() )
395 {
396 if ( mContent )
397 {
398 mContent->cancel();
399 }
400
401 mContent = mFileWidget->externalStorage()->fetch( resolvedPath, storageAuthConfigId() );
402
403#ifdef WITH_QTWEBKIT
404 mWebView->setVisible( false );
405#endif
406 mMediaWidget->setVisible( false );
407 mPixmapLabel->setVisible( false );
408 mErrorLabel->setVisible( false );
409 mLoadingLabel->setVisible( true );
410 mLoadingMovie->start();
411 connect( mContent, &QgsExternalStorageFetchedContent::fetched, this, &QgsExternalResourceWidget::onFetchFinished );
412 connect( mContent, &QgsExternalStorageFetchedContent::errorOccurred, this, &QgsExternalResourceWidget::onFetchFinished );
413 connect( mContent, &QgsExternalStorageFetchedContent::canceled, this, &QgsExternalResourceWidget::onFetchFinished );
414
415 mContent->fetch();
416 }
417 else
418 {
419 updateDocumentContent( resolvedPath );
420 }
421 }
422}
423
424void QgsExternalResourceWidget::onFetchFinished()
425{
426 QgsExternalStorageFetchedContent *content = qobject_cast<QgsExternalStorageFetchedContent *>( sender() );
427
428 if ( content == mContent && mContent->status() == Qgis::ContentStatus::Failed )
429 {
430#ifdef WITH_QTWEBKIT
431 mWebView->setVisible( false );
432#endif
433 mPixmapLabel->setVisible( false );
434 mLoadingLabel->setVisible( false );
435 mLoadingMovie->stop();
436 mErrorLabel->setVisible( true );
437
438 if ( messageBar() )
439 {
440 messageBar()->pushWarning( tr( "Fetching External Resource" ),
441 tr( "Error while fetching external resource '%1' : %2" ).arg(
442 mFileWidget->filePath(), mContent->errorString() ) );
443 }
444 }
445 else if ( content == mContent && mContent->status() == Qgis::ContentStatus::Finished )
446 {
447 const QString filePath = mDocumentViewerContent == Web
448 ? QUrl::fromLocalFile( mContent->filePath() ).toString()
449 : mContent->filePath();
450
451 updateDocumentContent( filePath );
452 }
453
454 content->deleteLater();
455}
@ Finished
Content fetching/storing is finished and successful.
@ Failed
Content fetching/storing has failed.
static QString nullRepresentation()
This string is 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 null QStri...
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 setReadOnly(bool readOnly)
defines if the widget is readonly
void valueChanged(const QString &)
emitteed as soon as the current document changes
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.
Class for QgsExternalStorage fetched content.
void fetched()
The signal is emitted when the resource has successfully been fetched.
The QgsExternalStorageFileWidget class creates a widget for selecting a file or a folder and stores i...
void setMessageBar(QgsMessageBar *messageBar)
Set messageBar to report messages.
const QString & storageAuthConfigId() const
Returns the authentication configuration ID used for the current external storage (if defined)
void setStorageType(const QString &storageType)
Set storageType storage type unique identifier as defined in QgsExternalStorageRegistry or null QStri...
void setReadOnly(bool readOnly) override
Sets whether the widget should be read only.
QgsExternalStorage * externalStorage() const
Returns external storage used to store selected file names, nullptr if none have been defined.
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.
QgsExternalStorageFetchedContent * fetch(const QString &url, const QString &authCfg=QString(), Qgis::ActionStart fetchingMode=Qgis::ActionStart::Deferred) const
Fetches file from url for this project external storage.
QString filePath()
Returns the current file path(s).
void setRelativeStorage(QgsFileWidget::RelativeStorage relativeStorage)
Sets whether the relative path is with respect to the project path or the default path.
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...
void setDefaultRoot(const QString &defaultRoot)
Returns the default root path used as the first shown location when picking a file and used if the Re...
void setFilePath(const QString &path)
Sets the current file path.
The QgsMediaWidget class creates a widget for playing back audio and video media files.
@ Video
Video-centric user interface.
void setMode(Mode mode)
Sets the media widget mode.
void setVideoHeight(int height)
Sets the video frame height.
void setMediaPath(const QString &path)
Sets the media path.
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.
The QgsPixmapLabel class shows a pixmap and adjusts its size to the space given to the widget by the ...
void clear()
Clears any label contents.
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.