Skip to content
Permalink
Browse files

Add metadata editing tab to vector tile layer properties

These layers can also have useful metadata which users may want to
set, e.g. access restrictions and attribution information
  • Loading branch information
nyalldawson committed Sep 7, 2020
1 parent 88f9dae commit 4ba21e0c22275e444c8bff6737d794ae41ecb2d4
@@ -25,6 +25,7 @@
#include "qgsgui.h"
#include "qgsnative.h"
#include "qgsapplication.h"
#include "qgsmetadatawidget.h"

#include <QFileDialog>
#include <QMenu>
@@ -34,6 +35,7 @@
QgsVectorTileLayerProperties::QgsVectorTileLayerProperties( QgsVectorTileLayer *lyr, QgsMapCanvas *canvas, QgsMessageBar *messageBar, QWidget *parent, Qt::WindowFlags flags )
: QgsOptionsDialogBase( QStringLiteral( "VectorTileLayerProperties" ), parent, flags )
, mLayer( lyr )
, mMapCanvas( canvas )
{
setupUi( this );

@@ -74,6 +76,17 @@ QgsVectorTileLayerProperties::QgsVectorTileLayerProperties( QgsVectorTileLayer *
mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );

#endif
mOptsPage_Information->setContentsMargins( 0, 0, 0, 0 );

QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
layout->setContentsMargins( 0, 0, 0, 0 );
metadataFrame->setContentsMargins( 0, 0, 0, 0 );
mMetadataWidget = new QgsMetadataWidget( this, mLayer );
mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
mMetadataWidget->setMapCanvas( mMapCanvas );
layout->addWidget( mMetadataWidget );
metadataFrame->setLayout( layout );
mOptsPage_Metadata->setContentsMargins( 0, 0, 0, 0 );

// update based on lyr's current state
syncToLayer();
@@ -89,27 +102,35 @@ QgsVectorTileLayerProperties::QgsVectorTileLayerProperties( QgsVectorTileLayer *

QString title = QString( tr( "Layer Properties - %1" ) ).arg( mLayer->name() );

if ( !mLayer->styleManager()->isDefault( mLayer->styleManager()->currentStyle() ) )
title += QStringLiteral( " (%1)" ).arg( mLayer->styleManager()->currentStyle() );
restoreOptionsBaseUi( title );

QPushButton *btnStyle = new QPushButton( tr( "Style" ) );
mBtnStyle = new QPushButton( tr( "Style" ) );
QMenu *menuStyle = new QMenu( this );
menuStyle->addAction( tr( "Load Style…" ), this, &QgsVectorTileLayerProperties::loadStyle );
menuStyle->addAction( tr( "Save Style…" ), this, &QgsVectorTileLayerProperties::saveStyleAs );
menuStyle->addSeparator();
menuStyle->addAction( tr( "Save as Default" ), this, &QgsVectorTileLayerProperties::saveDefaultStyle );
menuStyle->addAction( tr( "Restore Default" ), this, &QgsVectorTileLayerProperties::loadDefaultStyle );
btnStyle->setMenu( menuStyle );
mBtnStyle->setMenu( menuStyle );
connect( menuStyle, &QMenu::aboutToShow, this, &QgsVectorTileLayerProperties::aboutToShowStyleMenu );

buttonBox->addButton( btnStyle, QDialogButtonBox::ResetRole );
buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );

mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
QMenu *menuMetadata = new QMenu( this );
mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsVectorTileLayerProperties::loadMetadata );
mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsVectorTileLayerProperties::saveMetadataAs );
mBtnMetadata->setMenu( menuMetadata );
buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );

if ( !mLayer->styleManager()->isDefault( mLayer->styleManager()->currentStyle() ) )
title += QStringLiteral( " (%1)" ).arg( mLayer->styleManager()->currentStyle() );
restoreOptionsBaseUi( title );
}

void QgsVectorTileLayerProperties::apply()
{
mRendererWidget->apply();
mLabelingWidget->apply();
mMetadataWidget->acceptMetadata();
}

void QgsVectorTileLayerProperties::syncToLayer()
@@ -243,6 +264,68 @@ void QgsVectorTileLayerProperties::aboutToShowStyleMenu()
QgsMapLayerStyleGuiUtils::instance()->addStyleManagerActions( m, mLayer );
}

void QgsVectorTileLayerProperties::loadMetadata()
{
QgsSettings myQSettings; // where we keep last used filter in persistent state
QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();

QString myFileName = QFileDialog::getOpenFileName( this, tr( "Load layer metadata from metadata file" ), myLastUsedDir,
tr( "QGIS Layer Metadata File" ) + " (*.qmd)" );
if ( myFileName.isNull() )
{
return;
}

QString myMessage;
bool defaultLoadedFlag = false;
myMessage = mLayer->loadNamedMetadata( myFileName, defaultLoadedFlag );

//reset if the default style was loaded OK only
if ( defaultLoadedFlag )
{
mMetadataWidget->setMetadata( &mLayer->metadata() );
}
else
{
//let the user know what went wrong
QMessageBox::warning( this, tr( "Load Metadata" ), myMessage );
}

QFileInfo myFI( myFileName );
QString myPath = myFI.path();
myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );

activateWindow(); // set focus back to properties dialog
}

void QgsVectorTileLayerProperties::saveMetadataAs()
{
QgsSettings myQSettings; // where we keep last used filter in persistent state
QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();

QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save Layer Metadata as QMD" ),
myLastUsedDir, tr( "QMD File" ) + " (*.qmd)" );
if ( myOutputFileName.isNull() ) //dialog canceled
{
return;
}

mMetadataWidget->acceptMetadata();

//ensure the user never omitted the extension from the file name
if ( !myOutputFileName.endsWith( QgsMapLayer::extensionPropertyType( QgsMapLayer::Metadata ), Qt::CaseInsensitive ) )
{
myOutputFileName += QgsMapLayer::extensionPropertyType( QgsMapLayer::Metadata );
}

bool defaultLoadedFlag = false;
QString message = mLayer->saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
if ( defaultLoadedFlag )
myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
else
QMessageBox::information( this, tr( "Save Metadata" ), message );
}

void QgsVectorTileLayerProperties::showHelp()
{
const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
@@ -265,3 +348,12 @@ void QgsVectorTileLayerProperties::urlClicked( const QUrl &url )
else
QDesktopServices::openUrl( url );
}

void QgsVectorTileLayerProperties::optionsStackedWidget_CurrentChanged( int index )
{
QgsOptionsDialogBase::optionsStackedWidget_CurrentChanged( index );

bool isMetadataPanel = ( index == mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
mBtnStyle->setVisible( ! isMetadataPanel );
mBtnMetadata->setVisible( isMetadataPanel );
}
@@ -26,6 +26,7 @@ class QgsMessageBar;
class QgsVectorTileBasicLabelingWidget;
class QgsVectorTileBasicRendererWidget;
class QgsVectorTileLayer;
class QgsMetadataWidget;


class QgsVectorTileLayerProperties : public QgsOptionsDialogBase, private Ui::QgsVectorTileLayerPropertiesBase
@@ -42,9 +43,14 @@ class QgsVectorTileLayerProperties : public QgsOptionsDialogBase, private Ui::Qg
void loadStyle();
void saveStyleAs();
void aboutToShowStyleMenu();
void loadMetadata();
void saveMetadataAs();
void showHelp();
void urlClicked( const QUrl &url );

protected slots:
void optionsStackedWidget_CurrentChanged( int index ) override SIP_SKIP ;

private:
void syncToLayer();

@@ -53,6 +59,15 @@ class QgsVectorTileLayerProperties : public QgsOptionsDialogBase, private Ui::Qg

QgsVectorTileBasicRendererWidget *mRendererWidget = nullptr;
QgsVectorTileBasicLabelingWidget *mLabelingWidget = nullptr;

QPushButton *mBtnStyle = nullptr;
QPushButton *mBtnMetadata = nullptr;
QAction *mActionLoadMetadata = nullptr;
QAction *mActionSaveMetadataAs = nullptr;

QgsMapCanvas *mMapCanvas = nullptr;
QgsMetadataWidget *mMetadataWidget = nullptr;

};

#endif // QGSVECTORTILELAYERPROPERTIES_H
@@ -851,7 +851,7 @@ void QgsRasterLayerProperties::sync()
pixmapPalette->repaint();
#endif

QgsDebugMsg( QStringLiteral( "populate metadata tab" ) );
QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
/*
* Metadata Tab
*/
@@ -102,6 +102,9 @@
<property name="text">
<string>Information</string>
</property>
<property name="toolTip">
<string>Information</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/propertyicons/metadata.svg</normaloff>:/images/themes/default/propertyicons/metadata.svg</iconset>
@@ -123,11 +126,26 @@
<property name="text">
<string>Labels</string>
</property>
<property name="toolTip">
<string>Labels</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/propertyicons/labels.svg</normaloff>:/images/themes/default/propertyicons/labels.svg</iconset>
</property>
</item>
<item>
<property name="text">
<string>Metadata</string>
</property>
<property name="toolTip">
<string>Metadata</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/propertyicons/editmetadata.svg</normaloff>:/images/themes/default/propertyicons/editmetadata.svg</iconset>
</property>
</item>
</widget>
</item>
</layout>
@@ -210,6 +228,32 @@
<widget class="QWidget" name="mOptsPage_Labeling">
<layout class="QVBoxLayout" name="verticalLayout_4"/>
</widget>
<widget class="QWidget" name="mOptsPage_Metadata">
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="metadataFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

0 comments on commit 4ba21e0

Please sign in to comment.
You can’t perform that action at this time.