Skip to content

Commit

Permalink
Add metadata editing tab to vector tile layer properties
Browse files Browse the repository at this point in the history
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 4ba21e0
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 8 deletions.
106 changes: 99 additions & 7 deletions src/app/vectortile/qgsvectortilelayerproperties.cpp
Expand Up @@ -25,6 +25,7 @@
#include "qgsgui.h"
#include "qgsnative.h"
#include "qgsapplication.h"
#include "qgsmetadatawidget.h"

#include <QFileDialog>
#include <QMenu>
Expand All @@ -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 );

Expand Down Expand Up @@ -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();
Expand All @@ -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()
Expand Down Expand Up @@ -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" );
Expand All @@ -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 );
}
15 changes: 15 additions & 0 deletions src/app/vectortile/qgsvectortilelayerproperties.h
Expand Up @@ -26,6 +26,7 @@ class QgsMessageBar;
class QgsVectorTileBasicLabelingWidget;
class QgsVectorTileBasicRendererWidget;
class QgsVectorTileLayer;
class QgsMetadataWidget;


class QgsVectorTileLayerProperties : public QgsOptionsDialogBase, private Ui::QgsVectorTileLayerPropertiesBase
Expand All @@ -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();

Expand All @@ -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
2 changes: 1 addition & 1 deletion src/gui/raster/qgsrasterlayerproperties.cpp
Expand Up @@ -851,7 +851,7 @@ void QgsRasterLayerProperties::sync()
pixmapPalette->repaint();
#endif

QgsDebugMsg( QStringLiteral( "populate metadata tab" ) );
QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
/*
* Metadata Tab
*/
Expand Down
44 changes: 44 additions & 0 deletions src/ui/qgsvectortilelayerpropertiesbase.ui
Expand Up @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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>
Expand Down

0 comments on commit 4ba21e0

Please sign in to comment.