Skip to content

Commit

Permalink
load and save metadata to a QMD file
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry authored and nyalldawson committed Jan 7, 2018
1 parent a343570 commit 3432bf8
Show file tree
Hide file tree
Showing 12 changed files with 844 additions and 69 deletions.
127 changes: 127 additions & 0 deletions python/core/qgsmaplayer.sip
Expand Up @@ -55,6 +55,12 @@ This is the base class for all map layer types (vector, raster).
PluginLayer
};

enum PropertyType
{
Style,
Metadata,
};

QgsMapLayer( QgsMapLayer::LayerType type = VectorLayer, const QString &name = QString(), const QString &source = QString() );
%Docstring
Constructor for QgsMapLayer
Expand All @@ -80,6 +86,15 @@ is still unique.
QgsMapLayer::LayerType type() const;
%Docstring
Returns the type of the layer.
%End

static QString extensionPropertyType( PropertyType type );
%Docstring
Returns the extension of a Property.

:return: The extension

.. versionadded:: 3.0
%End

QString id() const;
Expand Down Expand Up @@ -545,6 +560,118 @@ Sets layer's spatial reference system
%Docstring
A convenience function to capitalize and format a layer ``name``.

.. versionadded:: 3.0
%End

virtual QString metadataUri() const;
%Docstring
Retrieve the metadata URI for this layer
(either as a .qmd file on disk or as a
record in the users style table in their personal qgis.db)

:return: a QString with the metadata file name

.. versionadded:: 3.0
%End

void exportNamedMetadata( QDomDocument &doc, QString &errorMsg ) const;
%Docstring
Export the current metadata of this layer as named metadata in a QDomDocument

:param doc: the target QDomDocument
:param errorMsg: this QString will be initialized on error

.. versionadded:: 3.0
%End

virtual QString saveDefaultMetadata( bool &resultFlag /Out/ );
%Docstring
Save the current metadata of this layer as the default metadata
(either as a .qmd file on disk or as a
record in the users style table in their personal qgis.db)

:param resultFlag: a reference to a flag that will be set to false if
we did not manage to save the default metadata.

:return: a QString with any status messages

.. versionadded:: 3.0
%End

QString saveNamedMetadata( const QString &uri, bool &resultFlag );
%Docstring
Save the current metadata of this layer as a named metadata
(either as a .qmd file on disk or as a
record in the users style table in their personal qgis.db)

:param uri: the file name or other URI for the
metadata file. First an attempt will be made to see if this
is a file and save to that, if that fails the qgis.db metadata
table will be used to create a metadata entry who's
key matches the URI.
:param resultFlag: a reference to a flag that will be set to false if
we did not manage to save the default metadata.

:return: a QString with any status messages

.. versionadded:: 3.0
%End

virtual QString loadNamedMetadata( const QString &uri, bool &resultFlag /Out/ );
%Docstring
Retrieve a named metadata for this layer if one
exists (either as a .qmd file on disk or as a
record in the users style table in their personal qgis.db)

:param uri: - the file name or other URI for the
metadata file. First an attempt will be made to see if this
is a file and load that, if that fails the qgis.db metadata
table will be consulted to see if there is a metadata who's
key matches the URI.
:param resultFlag: a reference to a flag that will be set to false if
we did not manage to load the default metadata.

:return: a QString with any status messages

.. versionadded:: 3.0
%End

QString loadDefaultMetadata( bool &resultFlag );
%Docstring
Retrieve the default metadata for this layer if one
exists (either as a .qmd file on disk or as a
record in the users metadata table in their personal qgis.db)

:param resultFlag: a reference to a flag that will be set to false if
we did not manage to load the default metadata.

:return: a QString with any status messages

.. versionadded:: 3.0
%End

bool loadNamedMetadataFromDatabase( const QString &db, const QString &uri, QString &qmd );
%Docstring
Retrieve a named metadata for this layer from a sqlite database.

:param db: path to sqlite database
:param uri: uri for table
:param qmd: will be set to QMD xml metadata content from database

:return: true if style was successfully loaded

.. versionadded:: 3.0
%End

bool importNamedMetadata( QDomDocument &document, QString &errorMessage );
%Docstring
Import the metadata of this layer from a QDomDocument

:param document: source QDomDocument
:param errorMessage: this QString will be initialized on error

:return: true on success

.. versionadded:: 3.0
%End

Expand Down
5 changes: 5 additions & 0 deletions python/gui/qgsmetadatawidget.sip
Expand Up @@ -46,6 +46,11 @@ If the CRS is updated.
void acceptMetadata();
%Docstring
Saves the metadata to the layer.
%End

virtual void setMetadata( const QgsLayerMetadata &metadata );
%Docstring
Sets the layer's ``metadata`` store.
%End

static QMap<QString, QString> parseLanguages();
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -4321,6 +4321,7 @@ bool QgisApp::addVectorLayers( const QStringList &layerQStringList, const QStrin
{
bool ok;
l->loadDefaultStyle( ok );
l->loadDefaultMetadata( ok );
}
activateDeactivateLayerRelatedActions( activeLayer() );

Expand Down Expand Up @@ -4747,6 +4748,7 @@ void QgisApp::askUserForOGRSublayers( QgsVectorLayer *layer )
{
bool ok;
l->loadDefaultStyle( ok );
l->loadDefaultMetadata( ok );
if ( addToGroup )
group->addLayer( l );
}
Expand Down Expand Up @@ -4839,6 +4841,7 @@ void QgisApp::addDatabaseLayers( QStringList const &layerPathList, QString const
{
bool ok;
l->loadDefaultStyle( ok );
l->loadDefaultMetadata( ok );
}

// draw the map
Expand Down Expand Up @@ -10249,6 +10252,7 @@ QgsVectorLayer *QgisApp::addVectorLayer( const QString &vectorLayerPath, const Q
QgsProject::instance()->addMapLayers( myList );
bool ok;
layer->loadDefaultStyle( ok );
layer->loadDefaultMetadata( ok );
}
}
else
Expand Down
131 changes: 121 additions & 10 deletions src/app/qgsrasterlayerproperties.cpp
Expand Up @@ -104,16 +104,26 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv

connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );

QPushButton *b = new QPushButton( tr( "Style" ) );
QMenu *m = new QMenu( this );
m->addAction( tr( "Load Style..." ), this, SLOT( loadStyle_clicked() ) );
m->addAction( tr( "Save Style..." ), this, SLOT( saveStyleAs_clicked() ) );
m->addSeparator();
m->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultStyle_clicked() ) );
m->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultStyle_clicked() ) );
b->setMenu( m );
connect( m, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
buttonBox->addButton( b, QDialogButtonBox::ResetRole );
mBtnStyle = new QPushButton( tr( "Style" ) );
QMenu *menuStyle = new QMenu( this );
menuStyle->addAction( tr( "Load Style..." ), this, SLOT( loadStyle_clicked() ) );
menuStyle->addAction( tr( "Save Style..." ), this, SLOT( saveStyleAs_clicked() ) );
menuStyle->addSeparator();
menuStyle->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultStyle_clicked() ) );
menuStyle->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultStyle_clicked() ) );
mBtnStyle->setMenu( menuStyle );
connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );

mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
QMenu *menuMetadata = new QMenu( this );
mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata" ), this, SLOT( loadMetadata() ) );
mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata" ), this, SLOT( saveMetadataAs() ) );
menuMetadata->addSeparator();
menuMetadata->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultMetadata() ) );
menuMetadata->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultMetadata() ) );
mBtnMetadata->setMenu( menuMetadata );
buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );

connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsRasterLayerProperties::syncToLayer );

Expand Down Expand Up @@ -436,6 +446,7 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv

QString title = QString( tr( "Layer Properties - %1" ) ).arg( lyr->name() );
restoreOptionsBaseUi( title );
optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
} // QgsRasterLayerProperties ctor


Expand Down Expand Up @@ -1488,6 +1499,10 @@ void QgsRasterLayerProperties::optionsStackedWidget_CurrentChanged( int index )
{
QgsOptionsDialogBase::optionsStackedWidget_CurrentChanged( index );

bool isMetadataPanel = ( index == mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
mBtnStyle->setVisible( ! isMetadataPanel );
mBtnMetadata->setVisible( isMetadataPanel );

if ( !mHistogramWidget )
return;

Expand Down Expand Up @@ -1856,6 +1871,102 @@ void QgsRasterLayerProperties::saveStyleAs_clicked()
QMessageBox::information( this, tr( "Saved Style" ), message );
}

//
//
// Next four methods for saving and restoring QMD metadata
//
//

void QgsRasterLayerProperties::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 = mRasterLayer->loadNamedMetadata( myFileName, defaultLoadedFlag );

//reset if the default style was loaded OK only
if ( defaultLoadedFlag )
{
mMetadataWidget->setMetadata( mRasterLayer->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 QgsRasterLayerProperties::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 = mRasterLayer->saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
if ( defaultLoadedFlag )
myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
else
QMessageBox::information( this, tr( "Saved Metadata" ), message );
}

void QgsRasterLayerProperties::saveDefaultMetadata()
{
mMetadataWidget->acceptMetadata();

bool defaultSavedFlag = false;
QString errorMsg = mRasterLayer->saveDefaultMetadata( defaultSavedFlag );
if ( !defaultSavedFlag )
{
QMessageBox::warning( this, tr( "Default Metadata" ), errorMsg );
}
}

void QgsRasterLayerProperties::loadDefaultMetadata()
{
bool defaultLoadedFlag = false;
QString myMessage = mRasterLayer->loadNamedMetadata( mRasterLayer->metadataUri(), defaultLoadedFlag );
//reset if the default metadata was loaded OK only
if ( defaultLoadedFlag )
{
mMetadataWidget->setMetadata( mRasterLayer->metadata() );
}
else
{
QMessageBox::information( this, tr( "Default Metadata" ), myMessage );
}
}


void QgsRasterLayerProperties::toggleBuildPyramidsButton()
{
if ( lbxPyramidResolutions->selectedItems().empty() )
Expand Down
15 changes: 15 additions & 0 deletions src/app/qgsrasterlayerproperties.h
Expand Up @@ -103,6 +103,16 @@ class APP_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private
void loadStyle_clicked();
//! Save a style when appriate button is pressed.
void saveStyleAs_clicked();

//! Load a saved metadata file.
void loadMetadata();
//! Save a metadata.
void saveMetadataAs();
//! Save the default metadata.
void saveDefaultMetadata();
//! Load the default metadata.
void loadDefaultMetadata();

//! Help button
void showHelp();

Expand Down Expand Up @@ -131,6 +141,11 @@ class APP_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private
void refreshLegend( const QString &layerID, bool expandItem );

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

//! \brief A constant that signals property not used
const QString TRSTRING_NOT_SET;

Expand Down

0 comments on commit 3432bf8

Please sign in to comment.