Skip to content

Commit

Permalink
[attribute form] Add audio and video support to attachments editor wi…
Browse files Browse the repository at this point in the history
…dget
  • Loading branch information
nirvn authored and nyalldawson committed Jan 27, 2023
1 parent be833c3 commit 56e0729
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 44 deletions.
4 changes: 3 additions & 1 deletion python/gui/auto_generated/qgsexternalresourcewidget.sip.in
Expand Up @@ -42,7 +42,9 @@ It can also be used to display a picture or a web page.
{
NoContent,
Image,
Web
Web,
Audio,
Video,
};

explicit QgsExternalResourceWidget( QWidget *parent /TransferThis/ = 0 );
Expand Down
2 changes: 1 addition & 1 deletion src/gui/editorwidgets/core/qgswidgetwrapper.cpp
Expand Up @@ -28,7 +28,7 @@ const QgsPropertiesDefinition &QgsWidgetWrapper::propertyDefinitions()
properties =
{
{ RootPath, QgsPropertyDefinition( "propertyRootPath", QgsPropertyDefinition::DataTypeString, QObject::tr( "Root path" ), QObject::tr( "string of variable length representing root path to attachment" ) ) },
{ DocumentViewerContent, QgsPropertyDefinition( "documentViewerContent", QgsPropertyDefinition::DataTypeString, QObject::tr( "Document viewer content" ), QObject::tr( "string" ) + "<b>NoContent</b>|<b>Image</b>|<b>Web</b>" ) },
{ DocumentViewerContent, QgsPropertyDefinition( "documentViewerContent", QgsPropertyDefinition::DataTypeString, QObject::tr( "Document viewer content" ), QObject::tr( "string" ) + "<b>NoContent</b>|<b>Image</b>|<b>Audio</b>|<b>Video</b>|<b>Web</b>" ) },
{ StorageUrl, QgsPropertyDefinition( "storageUrl", QgsPropertyDefinition::DataTypeString, QObject::tr( "Storage Url" ), QObject::tr( "String of variable length representing the URL used to store document with an external storage" ) ) }
};
}
Expand Down
10 changes: 8 additions & 2 deletions src/gui/editorwidgets/qgsexternalresourceconfigdlg.cpp
Expand Up @@ -96,14 +96,20 @@ QgsExternalResourceConfigDlg::QgsExternalResourceConfigDlg( QgsVectorLayer *vl,
connect( mStorageModeCbx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
connect( mStoragePathCbx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
connect( mDocumentViewerGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
connect( mDocumentViewerContentComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]( int idx )
{ mDocumentViewerContentSettingsWidget->setEnabled( ( QgsExternalResourceWidget::DocumentViewerContent )idx != QgsExternalResourceWidget::NoContent ); } );
connect( mDocumentViewerContentComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]( int )
{
const QgsExternalResourceWidget::DocumentViewerContent content = static_cast<QgsExternalResourceWidget::DocumentViewerContent>( mDocumentViewerContentComboBox->currentData().toInt() );
const bool hasSizeSettings = ( content != QgsExternalResourceWidget::NoContent && content != QgsExternalResourceWidget::Audio );
mDocumentViewerContentSettingsWidget->setEnabled( hasSizeSettings );
} );
connect( mDocumentViewerHeight, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
connect( mDocumentViewerWidth, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
connect( mStorageUrlExpression, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );

mDocumentViewerContentComboBox->addItem( tr( "No Content" ), QgsExternalResourceWidget::NoContent );
mDocumentViewerContentComboBox->addItem( tr( "Image" ), QgsExternalResourceWidget::Image );
mDocumentViewerContentComboBox->addItem( tr( "Audio" ), QgsExternalResourceWidget::Audio );
mDocumentViewerContentComboBox->addItem( tr( "Video" ), QgsExternalResourceWidget::Video );
mDocumentViewerContentComboBox->addItem( tr( "Web View" ), QgsExternalResourceWidget::Web );
}

Expand Down
8 changes: 8 additions & 0 deletions src/gui/editorwidgets/qgsexternalresourcewidgetwrapper.cpp
Expand Up @@ -104,6 +104,14 @@ void QgsExternalResourceWidgetWrapper::updateProperties( const QgsFeature &featu
{
dvc = QgsExternalResourceWidget::Image;
}
else if ( dvcString.compare( QLatin1String( "audio" ), Qt::CaseInsensitive ) == 0 )
{
dvc = QgsExternalResourceWidget::Audio;
}
else if ( dvcString.compare( QLatin1String( "video" ), Qt::CaseInsensitive ) == 0 )
{
dvc = QgsExternalResourceWidget::Video;
}
else if ( dvcString.compare( QLatin1String( "web" ), Qt::CaseInsensitive ) == 0 )
{
dvc = QgsExternalResourceWidget::Web;
Expand Down
142 changes: 103 additions & 39 deletions src/gui/qgsexternalresourcewidget.cpp
Expand Up @@ -18,6 +18,7 @@
#include "qgspixmaplabel.h"
#include "qgsproject.h"
#include "qgsapplication.h"
#include "qgsmediawidget.h"
#include "qgsnetworkaccessmanager.h"
#include "qgstaskmanager.h"
#include "qgsexternalstorage.h"
Expand Down Expand Up @@ -59,14 +60,17 @@ QgsExternalResourceWidget::QgsExternalResourceWidget( QWidget *parent )
layout->addWidget( mWebView, 2, 0 );
#endif

mMediaWidget = new QgsMediaWidget( this );
layout->addWidget( mMediaWidget, 3, 0 );

mLoadingLabel = new QLabel( this );
layout->addWidget( mLoadingLabel, 3, 0 );
layout->addWidget( mLoadingLabel, 4, 0 );
mLoadingMovie = new QMovie( QgsApplication::iconPath( QStringLiteral( "/mIconLoading.gif" ) ), QByteArray(), this );
mLoadingMovie->setScaledSize( QSize( 32, 32 ) );
mLoadingLabel->setMovie( mLoadingMovie );

mErrorLabel = new QLabel( this );
layout->addWidget( mErrorLabel, 4, 0 );
layout->addWidget( mErrorLabel, 5, 0 );
mErrorLabel->setPixmap( QPixmap( QgsApplication::iconPath( QStringLiteral( "/mIconWarning.svg" ) ) ) );

updateDocumentViewer();
Expand Down Expand Up @@ -157,41 +161,79 @@ void QgsExternalResourceWidget::updateDocumentViewer()
mLoadingLabel->setVisible( false );
mLoadingMovie->stop();

switch ( mDocumentViewerContent )
{
case Web:
{
#ifdef WITH_QTWEBKIT
mWebView->setVisible( mDocumentViewerContent == Web );
mWebView->setVisible( true );
#endif
mMediaWidget->setVisible( false );
mPixmapLabel->setVisible( false );
break;
}

mPixmapLabel->setVisible( mDocumentViewerContent == Image );
case Image:
{
#ifdef WITH_QTWEBKIT
mWebView->setVisible( false );
#endif
mMediaWidget->setVisible( false );
mPixmapLabel->setVisible( true );

if ( mDocumentViewerContent == Image )
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
const QPixmap pm = mPixmapLabel->pixmap() ? *mPixmapLabel->pixmap() : QPixmap();
const QPixmap pm = mPixmapLabel->pixmap() ? *mPixmapLabel->pixmap() : QPixmap();
#else
const QPixmap pm = mPixmapLabel->pixmap();
const QPixmap pm = mPixmapLabel->pixmap();
#endif

if ( !pm || pm.isNull() )
{
mPixmapLabel->setMinimumSize( QSize( 0, 0 ) );
}
else
{
QSize size( mDocumentViewerWidth, mDocumentViewerHeight );
if ( size.width() == 0 && size.height() > 0 )
if ( !pm || pm.isNull() )
{
size.setWidth( size.height() * pm.size().width() / pm.size().height() );
mPixmapLabel->setMinimumSize( QSize( 0, 0 ) );
}
else if ( size.width() > 0 && size.height() == 0 )
else
{
size.setHeight( size.width() * pm.size().height() / pm.size().width() );
QSize size( mDocumentViewerWidth, mDocumentViewerHeight );
if ( size.width() == 0 && size.height() > 0 )
{
size.setWidth( size.height() * pm.size().width() / pm.size().height() );
}
else if ( size.width() > 0 && size.height() == 0 )
{
size.setHeight( size.width() * pm.size().height() / pm.size().width() );
}

if ( size.width() != 0 || size.height() != 0 )
{
mPixmapLabel->setMinimumSize( size );
mPixmapLabel->setMaximumSize( size );
}
}
break;
}

if ( size.width() != 0 || size.height() != 0 )
{
mPixmapLabel->setMinimumSize( size );
mPixmapLabel->setMaximumSize( size );
}
case Audio:
case Video:
{
#ifdef WITH_QTWEBKIT
mWebView->setVisible( false );
#endif
mMediaWidget->setVisible( true );
mPixmapLabel->setVisible( false );

mMediaWidget->setMode( mDocumentViewerContent == Video ? QgsMediaWidget::Video : QgsMediaWidget::Audio );
mMediaWidget->setVideoHeight( mDocumentViewerHeight );
break;
}

case NoContent:
{
#ifdef WITH_QTWEBKIT
mWebView->setVisible( false );
#endif
mMediaWidget->setVisible( false );
mPixmapLabel->setVisible( false );
break;
}
}
}
Expand Down Expand Up @@ -267,24 +309,45 @@ QgsMessageBar *QgsExternalResourceWidget::messageBar() const

void QgsExternalResourceWidget::updateDocumentContent( const QString &filePath )
{
#ifdef WITH_QTWEBKIT
if ( mDocumentViewerContent == Web )
switch ( mDocumentViewerContent )
{
mWebView->load( QUrl::fromEncoded( filePath.toUtf8() ) );
mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
}
case Web:
{
#ifdef WITH_QTWEBKIT
mWebView->load( QUrl::fromEncoded( filePath.toUtf8() ) );
mWebView->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
#endif
break;
}

if ( mDocumentViewerContent == Image )
{
// use an image reader to ensure image orientation and transforms are correctly handled
QImageReader ir( filePath );
ir.setAutoTransform( true );
const QPixmap pm = QPixmap::fromImage( ir.read() );
if ( !pm.isNull() )
mPixmapLabel->setPixmap( pm );
else
mPixmapLabel->clear();
case Image:
{
QImageReader ir( filePath );
// ensure image orientation and transforms are correctly handled
ir.setAutoTransform( true );
const QPixmap pm = QPixmap::fromImage( ir.read() );
if ( !pm.isNull() )
{
mPixmapLabel->setPixmap( pm );
}
else
{
mPixmapLabel->clear();
}
break;
}

case Audio:
case Video:
{
mMediaWidget->setMediaPath( filePath );
break;
}

case NoContent:
{
break;
}
}

updateDocumentViewer();
Expand Down Expand Up @@ -334,6 +397,7 @@ void QgsExternalResourceWidget::loadDocument( const QString &path )
#ifdef WITH_QTWEBKIT
mWebView->setVisible( false );
#endif
mMediaWidget->setVisible( false );
mPixmapLabel->setVisible( false );
mErrorLabel->setVisible( false );
mLoadingLabel->setVisible( true );
Expand Down
9 changes: 8 additions & 1 deletion src/gui/qgsexternalresourcewidget.h
Expand Up @@ -19,6 +19,7 @@

class QWebView;
class QgsPixmapLabel;
class QgsMediaWidget;
class QgsMessageBar;
class QgsExternalStorageFileWidget;
class QgsExternalStorageFetchedContent;
Expand Down Expand Up @@ -74,7 +75,9 @@ class GUI_EXPORT QgsExternalResourceWidget : public QWidget
{
NoContent,
Image,
Web
Web,
Audio, // since QGIS 3.30
Video, // since QGIS 3.30
};

/**
Expand Down Expand Up @@ -217,9 +220,11 @@ class GUI_EXPORT QgsExternalResourceWidget : public QWidget

//! properties
bool mFileWidgetVisible = true;

DocumentViewerContent mDocumentViewerContent = NoContent;
int mDocumentViewerHeight = 0;
int mDocumentViewerWidth = 0;

QgsFileWidget::RelativeStorage mRelativeStorage = QgsFileWidget::Absolute;
QString mDefaultRoot; // configured default root path for QgsFileWidget::RelativeStorage::RelativeDefaultPath

Expand All @@ -230,6 +235,8 @@ class GUI_EXPORT QgsExternalResourceWidget : public QWidget
//! This webview is used as a container to display the picture
QWebView *mWebView = nullptr;
#endif
QgsMediaWidget *mMediaWidget = nullptr;

QLabel *mLoadingLabel = nullptr;
QLabel *mErrorLabel = nullptr;
QMovie *mLoadingMovie = nullptr;
Expand Down

0 comments on commit 56e0729

Please sign in to comment.