QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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"
22#include "qgstaskmanager.h"
23#include "qgsexternalstorage.h"
24#include "qgsmessagebar.h"
26
27#include <QDir>
28#include <QGridLayout>
29#include <QVariant>
30#include <QSettings>
31#include <QImageReader>
32#include <QToolButton>
33#include <QMimeType>
34#include <QMimeDatabase>
35#include <QMovie>
36#ifdef WITH_QTWEBKIT
37#include <QWebView>
38#endif
39
41 : QWidget( parent )
42{
43 setBackgroundRole( QPalette::Window );
44 setAutoFillBackground( true );
45
46 QGridLayout *layout = new QGridLayout();
47 layout->setContentsMargins( 0, 0, 0, 0 );
48
49 mFileWidget = new QgsExternalStorageFileWidget( this );
50 layout->addWidget( mFileWidget, 0, 0 );
51 mFileWidget->setVisible( mFileWidgetVisible );
52
53 mPixmapLabel = new QgsPixmapLabel( this );
54 layout->addWidget( mPixmapLabel, 1, 0 );
55
56#ifdef WITH_QTWEBKIT
57 mWebView = new QWebView( this );
58 mWebView->setAcceptDrops( false );
59 layout->addWidget( mWebView, 2, 0 );
60#endif
61
62 mLoadingLabel = new QLabel( this );
63 layout->addWidget( mLoadingLabel, 3, 0 );
64 mLoadingMovie = new QMovie( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), QByteArray(), this );
65 mLoadingMovie->setScaledSize( QSize( 32, 32 ) );
66 mLoadingLabel->setMovie( mLoadingMovie );
67
68 mErrorLabel = new QLabel( this );
69 layout->addWidget( mErrorLabel, 4, 0 );
70 mErrorLabel->setPixmap( QPixmap( QgsApplication::iconPath( QStringLiteral( "/mIconWarning.svg" ) ) ) );
71
72 updateDocumentViewer();
73
74 setLayout( layout );
75
76 connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsExternalResourceWidget::loadDocument );
78}
79
80QVariant QgsExternalResourceWidget::documentPath( QVariant::Type type ) const
81{
82 const QString path = mFileWidget->filePath();
83 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
84 {
85 return QVariant( type );
86 }
87 else
88 {
89 return path;
90 }
91}
92
94{
95 mFileWidget->setFilePath( path.toString() );
96}
97
99{
100 return mFileWidget;
101}
102
104{
105 return mFileWidgetVisible;
106}
107
109{
110 mFileWidgetVisible = visible;
111 mFileWidget->setVisible( visible );
112}
113
115{
116 return mDocumentViewerContent;
117}
118
120{
121 mDocumentViewerContent = content;
122 if ( mDocumentViewerContent != Image )
123 updateDocumentViewer();
124 loadDocument( mFileWidget->filePath() );
125}
126
128{
129 return mDocumentViewerHeight;
130}
131
133{
134 mDocumentViewerHeight = height;
135 updateDocumentViewer();
136}
137
139{
140 return mDocumentViewerWidth;
141}
142
144{
145 mDocumentViewerWidth = width;
146 updateDocumentViewer();
147}
148
150{
151 mFileWidget->setReadOnly( readOnly );
152}
153
154void QgsExternalResourceWidget::updateDocumentViewer()
155{
156 mErrorLabel->setVisible( false );
157 mLoadingLabel->setVisible( false );
158 mLoadingMovie->stop();
159
160#ifdef WITH_QTWEBKIT
161 mWebView->setVisible( mDocumentViewerContent == Web );
162#endif
163
164 mPixmapLabel->setVisible( mDocumentViewerContent == Image );
165
166 if ( mDocumentViewerContent == Image )
167 {
168#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
169 const QPixmap pm = mPixmapLabel->pixmap() ? *mPixmapLabel->pixmap() : QPixmap();
170#else
171 const QPixmap pm = mPixmapLabel->pixmap();
172#endif
173
174 if ( !pm || pm.isNull() )
175 {
176 mPixmapLabel->setMinimumSize( QSize( 0, 0 ) );
177 }
178 else
179 {
180 QSize size( mDocumentViewerWidth, mDocumentViewerHeight );
181 if ( size.width() == 0 && size.height() > 0 )
182 {
183 size.setWidth( size.height() * pm.size().width() / pm.size().height() );
184 }
185 else if ( size.width() > 0 && size.height() == 0 )
186 {
187 size.setHeight( size.width() * pm.size().height() / pm.size().width() );
188 }
189
190 if ( size.width() != 0 || size.height() != 0 )
191 {
192 mPixmapLabel->setMinimumSize( size );
193 mPixmapLabel->setMaximumSize( size );
194 }
195 }
196 }
197}
198
199QString QgsExternalResourceWidget::resolvePath( const QString &path )
200{
201 switch ( mRelativeStorage )
202 {
204 return path;
205 break;
207 return QFileInfo( QgsProject::instance()->absoluteFilePath() ).dir().filePath( path );
208 break;
210 return QDir( mDefaultRoot ).filePath( path );
211 break;
212 }
213 return QString(); // avoid warnings
214}
215
217{
218 return mDefaultRoot;
219}
220
221void QgsExternalResourceWidget::setDefaultRoot( const QString &defaultRoot )
222{
223 mFileWidget->setDefaultRoot( defaultRoot );
224 mDefaultRoot = defaultRoot;
225}
226
228{
229 return mRelativeStorage;
230}
231
233{
234 mFileWidget->setRelativeStorage( relativeStorage );
235 mRelativeStorage = relativeStorage;
236}
237
238void QgsExternalResourceWidget::setStorageType( const QString &storageType )
239{
240 mFileWidget->setStorageType( storageType );
241}
242
244{
245 return mFileWidget->storageType();
246}
247
249{
250 mFileWidget->setStorageAuthConfigId( authCfg );
251}
252
254{
255 return mFileWidget->storageAuthConfigId();
256}
257
259{
260 mFileWidget->setMessageBar( messageBar );
261}
262
264{
265 return mFileWidget->messageBar();
266}
267
268void QgsExternalResourceWidget::updateDocumentContent( const QString &filePath )
269{
270#ifdef WITH_QTWEBKIT
271 if ( mDocumentViewerContent == Web )
272 {
273 mWebView->load( QUrl::fromEncoded( filePath.toUtf8() ) );
274 mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
275 }
276#endif
277
278 if ( mDocumentViewerContent == Image )
279 {
280 // use an image reader to ensure image orientation and transforms are correctly handled
281 QImageReader ir( filePath );
282 ir.setAutoTransform( true );
283 const QPixmap pm = QPixmap::fromImage( ir.read() );
284 if ( !pm.isNull() )
285 mPixmapLabel->setPixmap( pm );
286 else
287 mPixmapLabel->clear();
288 }
289
290 updateDocumentViewer();
291}
292
293void QgsExternalResourceWidget::clearContent()
294{
295#ifdef WITH_QTWEBKIT
296 if ( mDocumentViewerContent == Web )
297 {
298 mWebView->load( QUrl( QStringLiteral( "about:blank" ) ) );
299 }
300#endif
301 if ( mDocumentViewerContent == Image )
302 {
303 mPixmapLabel->clear();
304 }
305
306 updateDocumentViewer();
307}
308
309void QgsExternalResourceWidget::loadDocument( const QString &path )
310{
311 if ( path.isEmpty() || path == QgsApplication::nullRepresentation() )
312 {
313 if ( mFileWidget->externalStorage() && mContent )
314 {
315 mContent->cancel();
316 mContent.clear();
317 }
318
319 clearContent();
320 }
321 else if ( mDocumentViewerContent != NoContent )
322 {
323 const QString resolvedPath = resolvePath( path );
324
325 if ( mFileWidget->externalStorage() )
326 {
327 if ( mContent )
328 {
329 mContent->cancel();
330 }
331
332 mContent = mFileWidget->externalStorage()->fetch( resolvedPath, storageAuthConfigId() );
333
334#ifdef WITH_QTWEBKIT
335 mWebView->setVisible( false );
336#endif
337 mPixmapLabel->setVisible( false );
338 mErrorLabel->setVisible( false );
339 mLoadingLabel->setVisible( true );
340 mLoadingMovie->start();
341 connect( mContent, &QgsExternalStorageFetchedContent::fetched, this, &QgsExternalResourceWidget::onFetchFinished );
342 connect( mContent, &QgsExternalStorageFetchedContent::errorOccurred, this, &QgsExternalResourceWidget::onFetchFinished );
343 connect( mContent, &QgsExternalStorageFetchedContent::canceled, this, &QgsExternalResourceWidget::onFetchFinished );
344
345 mContent->fetch();
346 }
347 else
348 {
349 updateDocumentContent( resolvedPath );
350 }
351 }
352}
353
354void QgsExternalResourceWidget::onFetchFinished()
355{
356 QgsExternalStorageFetchedContent *content = qobject_cast<QgsExternalStorageFetchedContent *>( sender() );
357
358 if ( content == mContent && mContent->status() == Qgis::ContentStatus::Failed )
359 {
360#ifdef WITH_QTWEBKIT
361 mWebView->setVisible( false );
362#endif
363 mPixmapLabel->setVisible( false );
364 mLoadingLabel->setVisible( false );
365 mLoadingMovie->stop();
366 mErrorLabel->setVisible( true );
367
368 if ( messageBar() )
369 {
370 messageBar()->pushWarning( tr( "Fetching External Resource" ),
371 tr( "Error while fetching external resource '%1' : %2" ).arg(
372 mFileWidget->filePath(), mContent->errorString() ) );
373 }
374 }
375 else if ( content == mContent && mContent->status() == Qgis::ContentStatus::Finished )
376 {
377 const QString filePath = mDocumentViewerContent == Web
378 ? QUrl::fromLocalFile( mContent->filePath() ).toString()
379 : mContent->filePath();
380
381 updateDocumentContent( filePath );
382 }
383
384 content->deleteLater();
385}
@ 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)
QVariant documentPath(QVariant::Type type=QVariant::String) const
documentPath returns the path of the current document in the widget
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.
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...
Definition: qgsfilewidget.h:79
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.
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:61
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.
Definition: qgsproject.cpp:477