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