mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
load and save metadata to a QMD file
This commit is contained in:
parent
a343570eab
commit
3432bf8f3b
@ -55,6 +55,12 @@ This is the base class for all map layer types (vector, raster).
|
|||||||
PluginLayer
|
PluginLayer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PropertyType
|
||||||
|
{
|
||||||
|
Style,
|
||||||
|
Metadata,
|
||||||
|
};
|
||||||
|
|
||||||
QgsMapLayer( QgsMapLayer::LayerType type = VectorLayer, const QString &name = QString(), const QString &source = QString() );
|
QgsMapLayer( QgsMapLayer::LayerType type = VectorLayer, const QString &name = QString(), const QString &source = QString() );
|
||||||
%Docstring
|
%Docstring
|
||||||
Constructor for QgsMapLayer
|
Constructor for QgsMapLayer
|
||||||
@ -80,6 +86,15 @@ is still unique.
|
|||||||
QgsMapLayer::LayerType type() const;
|
QgsMapLayer::LayerType type() const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns the type of the layer.
|
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
|
%End
|
||||||
|
|
||||||
QString id() const;
|
QString id() const;
|
||||||
@ -545,6 +560,118 @@ Sets layer's spatial reference system
|
|||||||
%Docstring
|
%Docstring
|
||||||
A convenience function to capitalize and format a layer ``name``.
|
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
|
.. versionadded:: 3.0
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
@ -46,6 +46,11 @@ If the CRS is updated.
|
|||||||
void acceptMetadata();
|
void acceptMetadata();
|
||||||
%Docstring
|
%Docstring
|
||||||
Saves the metadata to the layer.
|
Saves the metadata to the layer.
|
||||||
|
%End
|
||||||
|
|
||||||
|
virtual void setMetadata( const QgsLayerMetadata &metadata );
|
||||||
|
%Docstring
|
||||||
|
Sets the layer's ``metadata`` store.
|
||||||
%End
|
%End
|
||||||
|
|
||||||
static QMap<QString, QString> parseLanguages();
|
static QMap<QString, QString> parseLanguages();
|
||||||
|
@ -4321,6 +4321,7 @@ bool QgisApp::addVectorLayers( const QStringList &layerQStringList, const QStrin
|
|||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
l->loadDefaultStyle( ok );
|
l->loadDefaultStyle( ok );
|
||||||
|
l->loadDefaultMetadata( ok );
|
||||||
}
|
}
|
||||||
activateDeactivateLayerRelatedActions( activeLayer() );
|
activateDeactivateLayerRelatedActions( activeLayer() );
|
||||||
|
|
||||||
@ -4747,6 +4748,7 @@ void QgisApp::askUserForOGRSublayers( QgsVectorLayer *layer )
|
|||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
l->loadDefaultStyle( ok );
|
l->loadDefaultStyle( ok );
|
||||||
|
l->loadDefaultMetadata( ok );
|
||||||
if ( addToGroup )
|
if ( addToGroup )
|
||||||
group->addLayer( l );
|
group->addLayer( l );
|
||||||
}
|
}
|
||||||
@ -4839,6 +4841,7 @@ void QgisApp::addDatabaseLayers( QStringList const &layerPathList, QString const
|
|||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
l->loadDefaultStyle( ok );
|
l->loadDefaultStyle( ok );
|
||||||
|
l->loadDefaultMetadata( ok );
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw the map
|
// draw the map
|
||||||
@ -10249,6 +10252,7 @@ QgsVectorLayer *QgisApp::addVectorLayer( const QString &vectorLayerPath, const Q
|
|||||||
QgsProject::instance()->addMapLayers( myList );
|
QgsProject::instance()->addMapLayers( myList );
|
||||||
bool ok;
|
bool ok;
|
||||||
layer->loadDefaultStyle( ok );
|
layer->loadDefaultStyle( ok );
|
||||||
|
layer->loadDefaultMetadata( ok );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -104,16 +104,26 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv
|
|||||||
|
|
||||||
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );
|
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );
|
||||||
|
|
||||||
QPushButton *b = new QPushButton( tr( "Style" ) );
|
mBtnStyle = new QPushButton( tr( "Style" ) );
|
||||||
QMenu *m = new QMenu( this );
|
QMenu *menuStyle = new QMenu( this );
|
||||||
m->addAction( tr( "Load Style..." ), this, SLOT( loadStyle_clicked() ) );
|
menuStyle->addAction( tr( "Load Style..." ), this, SLOT( loadStyle_clicked() ) );
|
||||||
m->addAction( tr( "Save Style..." ), this, SLOT( saveStyleAs_clicked() ) );
|
menuStyle->addAction( tr( "Save Style..." ), this, SLOT( saveStyleAs_clicked() ) );
|
||||||
m->addSeparator();
|
menuStyle->addSeparator();
|
||||||
m->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultStyle_clicked() ) );
|
menuStyle->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultStyle_clicked() ) );
|
||||||
m->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultStyle_clicked() ) );
|
menuStyle->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultStyle_clicked() ) );
|
||||||
b->setMenu( m );
|
mBtnStyle->setMenu( menuStyle );
|
||||||
connect( m, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
|
connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
|
||||||
buttonBox->addButton( b, 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, 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 );
|
connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsRasterLayerProperties::syncToLayer );
|
||||||
|
|
||||||
@ -436,6 +446,7 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanv
|
|||||||
|
|
||||||
QString title = QString( tr( "Layer Properties - %1" ) ).arg( lyr->name() );
|
QString title = QString( tr( "Layer Properties - %1" ) ).arg( lyr->name() );
|
||||||
restoreOptionsBaseUi( title );
|
restoreOptionsBaseUi( title );
|
||||||
|
optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
|
||||||
} // QgsRasterLayerProperties ctor
|
} // QgsRasterLayerProperties ctor
|
||||||
|
|
||||||
|
|
||||||
@ -1488,6 +1499,10 @@ void QgsRasterLayerProperties::optionsStackedWidget_CurrentChanged( int index )
|
|||||||
{
|
{
|
||||||
QgsOptionsDialogBase::optionsStackedWidget_CurrentChanged( index );
|
QgsOptionsDialogBase::optionsStackedWidget_CurrentChanged( index );
|
||||||
|
|
||||||
|
bool isMetadataPanel = ( index == mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
|
||||||
|
mBtnStyle->setVisible( ! isMetadataPanel );
|
||||||
|
mBtnMetadata->setVisible( isMetadataPanel );
|
||||||
|
|
||||||
if ( !mHistogramWidget )
|
if ( !mHistogramWidget )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1856,6 +1871,102 @@ void QgsRasterLayerProperties::saveStyleAs_clicked()
|
|||||||
QMessageBox::information( this, tr( "Saved Style" ), message );
|
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()
|
void QgsRasterLayerProperties::toggleBuildPyramidsButton()
|
||||||
{
|
{
|
||||||
if ( lbxPyramidResolutions->selectedItems().empty() )
|
if ( lbxPyramidResolutions->selectedItems().empty() )
|
||||||
|
@ -103,6 +103,16 @@ class APP_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private
|
|||||||
void loadStyle_clicked();
|
void loadStyle_clicked();
|
||||||
//! Save a style when appriate button is pressed.
|
//! Save a style when appriate button is pressed.
|
||||||
void saveStyleAs_clicked();
|
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
|
//! Help button
|
||||||
void showHelp();
|
void showHelp();
|
||||||
|
|
||||||
@ -131,6 +141,11 @@ class APP_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private
|
|||||||
void refreshLegend( const QString &layerID, bool expandItem );
|
void refreshLegend( const QString &layerID, bool expandItem );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QPushButton *mBtnStyle = nullptr;
|
||||||
|
QPushButton *mBtnMetadata = nullptr;
|
||||||
|
QAction *mActionLoadMetadata = nullptr;
|
||||||
|
QAction *mActionSaveMetadataAs = nullptr;
|
||||||
|
|
||||||
//! \brief A constant that signals property not used
|
//! \brief A constant that signals property not used
|
||||||
const QString TRSTRING_NOT_SET;
|
const QString TRSTRING_NOT_SET;
|
||||||
|
|
||||||
|
@ -111,16 +111,26 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
|||||||
// and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
|
// and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
|
||||||
initOptionsBase( false );
|
initOptionsBase( false );
|
||||||
|
|
||||||
QPushButton *b = new QPushButton( tr( "Style" ) );
|
mBtnStyle = new QPushButton( tr( "Style" ), this );
|
||||||
QMenu *m = new QMenu( this );
|
QMenu *menuStyle = new QMenu( this );
|
||||||
mActionLoadStyle = m->addAction( tr( "Load Style" ), this, SLOT( loadStyle_clicked() ) );
|
mActionLoadStyle = menuStyle->addAction( tr( "Load Style" ), this, SLOT( loadStyle_clicked() ) );
|
||||||
mActionSaveStyleAs = m->addAction( tr( "Save Style" ), this, SLOT( saveStyleAs_clicked() ) );
|
mActionSaveStyleAs = menuStyle->addAction( tr( "Save Style" ), this, SLOT( saveStyleAs_clicked() ) );
|
||||||
m->addSeparator();
|
menuStyle->addSeparator();
|
||||||
m->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultStyle_clicked() ) );
|
menuStyle->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultStyle_clicked() ) );
|
||||||
m->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultStyle_clicked() ) );
|
menuStyle->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultStyle_clicked() ) );
|
||||||
b->setMenu( m );
|
mBtnStyle->setMenu( menuStyle );
|
||||||
connect( m, &QMenu::aboutToShow, this, &QgsVectorLayerProperties::aboutToShowStyleMenu );
|
connect( menuStyle, &QMenu::aboutToShow, this, &QgsVectorLayerProperties::aboutToShowStyleMenu );
|
||||||
buttonBox->addButton( b, 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, 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, &QgsVectorLayerProperties::syncToLayer );
|
connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsVectorLayerProperties::syncToLayer );
|
||||||
|
|
||||||
@ -227,6 +237,15 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
|||||||
delete mOptsPage_3DView; // removes both the "3d view" list item and its page
|
delete mOptsPage_3DView; // removes both the "3d view" list item and its page
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Metadata tab, before the syncToLayer
|
||||||
|
QVBoxLayout *metadataLayout = new QVBoxLayout( metadataFrame );
|
||||||
|
metadataLayout->setMargin( 0 );
|
||||||
|
mMetadataWidget = new QgsMetadataWidget( this, mLayer );
|
||||||
|
mMetadataWidget->layout()->setContentsMargins( -1, 0, -1, 0 );
|
||||||
|
mMetadataWidget->setMapCanvas( QgisApp::instance()->mapCanvas() );
|
||||||
|
metadataLayout->addWidget( mMetadataWidget );
|
||||||
|
metadataFrame->setLayout( metadataLayout );
|
||||||
|
|
||||||
syncToLayer();
|
syncToLayer();
|
||||||
|
|
||||||
if ( mLayer->dataProvider() )//enable spatial index button group if supported by provider
|
if ( mLayer->dataProvider() )//enable spatial index button group if supported by provider
|
||||||
@ -282,15 +301,6 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
|||||||
diagLayout->addWidget( diagramPropertiesDialog );
|
diagLayout->addWidget( diagramPropertiesDialog );
|
||||||
mDiagramFrame->setLayout( diagLayout );
|
mDiagramFrame->setLayout( diagLayout );
|
||||||
|
|
||||||
// Metadata tab
|
|
||||||
QVBoxLayout *metadataLayout = new QVBoxLayout( metadataFrame );
|
|
||||||
metadataLayout->setMargin( 0 );
|
|
||||||
mMetadataWidget = new QgsMetadataWidget( this, mLayer );
|
|
||||||
mMetadataWidget->layout()->setContentsMargins( -1, 0, -1, 0 );
|
|
||||||
mMetadataWidget->setMapCanvas( QgisApp::instance()->mapCanvas() );
|
|
||||||
metadataLayout->addWidget( mMetadataWidget );
|
|
||||||
metadataFrame->setLayout( metadataLayout );
|
|
||||||
|
|
||||||
// Legend tab
|
// Legend tab
|
||||||
mLegendConfigEmbeddedWidget->setLayer( mLayer );
|
mLegendConfigEmbeddedWidget->setLayer( mLayer );
|
||||||
|
|
||||||
@ -401,6 +411,8 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
|||||||
connect( mAuxiliaryStorageFieldsAddBtn, &QPushButton::clicked, this, &QgsVectorLayerProperties::onAuxiliaryLayerAddField );
|
connect( mAuxiliaryStorageFieldsAddBtn, &QPushButton::clicked, this, &QgsVectorLayerProperties::onAuxiliaryLayerAddField );
|
||||||
|
|
||||||
updateAuxiliaryStoragePage();
|
updateAuxiliaryStoragePage();
|
||||||
|
|
||||||
|
optionsStackedWidget_CurrentChanged( mOptStackedWidget->currentIndex() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsVectorLayerProperties::toggleEditing()
|
void QgsVectorLayerProperties::toggleEditing()
|
||||||
@ -546,6 +558,8 @@ void QgsVectorLayerProperties::syncToLayer()
|
|||||||
mVector3DWidget->setLayer( mLayer );
|
mVector3DWidget->setLayer( mLayer );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mMetadataWidget->setMetadata( mLayer->metadata() );
|
||||||
|
|
||||||
} // syncToLayer()
|
} // syncToLayer()
|
||||||
|
|
||||||
void QgsVectorLayerProperties::apply()
|
void QgsVectorLayerProperties::apply()
|
||||||
@ -982,6 +996,108 @@ void QgsVectorLayerProperties::saveStyleAs_clicked()
|
|||||||
saveStyleAs( QML );
|
saveStyleAs( QML );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsVectorLayerProperties::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 QgsVectorLayerProperties::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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString myMessage;
|
||||||
|
bool defaultLoadedFlag = false;
|
||||||
|
myMessage = mLayer->saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
|
||||||
|
|
||||||
|
//reset if the default style was loaded OK only
|
||||||
|
if ( defaultLoadedFlag )
|
||||||
|
{
|
||||||
|
syncToLayer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//let the user know what went wrong
|
||||||
|
QMessageBox::information( this, tr( "Saved Metadata" ), myMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo myFI( myOutputFileName );
|
||||||
|
QString myPath = myFI.path();
|
||||||
|
// Persist last used dir
|
||||||
|
myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsVectorLayerProperties::saveDefaultMetadata()
|
||||||
|
{
|
||||||
|
mMetadataWidget->acceptMetadata();
|
||||||
|
|
||||||
|
bool defaultSavedFlag = false;
|
||||||
|
QString errorMsg = mLayer->saveDefaultMetadata( defaultSavedFlag );
|
||||||
|
if ( !defaultSavedFlag )
|
||||||
|
{
|
||||||
|
QMessageBox::warning( this, tr( "Default Metadata" ), errorMsg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsVectorLayerProperties::loadDefaultMetadata()
|
||||||
|
{
|
||||||
|
bool defaultLoadedFlag = false;
|
||||||
|
QString myMessage = mLayer->loadNamedMetadata( mLayer->metadataUri(), defaultLoadedFlag );
|
||||||
|
//reset if the default metadata was loaded OK only
|
||||||
|
if ( defaultLoadedFlag )
|
||||||
|
{
|
||||||
|
mMetadataWidget->setMetadata( mLayer->metadata() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information( this, tr( "Default Metadata" ), myMessage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QgsVectorLayerProperties::saveStyleAsMenuTriggered( QAction *action )
|
void QgsVectorLayerProperties::saveStyleAsMenuTriggered( QAction *action )
|
||||||
{
|
{
|
||||||
QMenu *menu = qobject_cast<QMenu *>( sender() );
|
QMenu *menu = qobject_cast<QMenu *>( sender() );
|
||||||
@ -1045,7 +1161,7 @@ void QgsVectorLayerProperties::saveStyleAs( StyleType styleType )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
|
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
|
||||||
extension = QStringLiteral( ".qml" );
|
extension = QgsMapLayer::extensionPropertyType( QgsMapLayer::Style );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save layer properties as style file" ),
|
QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save layer properties as style file" ),
|
||||||
@ -1480,6 +1596,10 @@ void QgsVectorLayerProperties::optionsStackedWidget_CurrentChanged( int index )
|
|||||||
{
|
{
|
||||||
QgsOptionsDialogBase::optionsStackedWidget_CurrentChanged( index );
|
QgsOptionsDialogBase::optionsStackedWidget_CurrentChanged( index );
|
||||||
|
|
||||||
|
bool isMetadataPanel = ( index == mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
|
||||||
|
mBtnStyle->setVisible( ! isMetadataPanel );
|
||||||
|
mBtnMetadata->setVisible( isMetadataPanel );
|
||||||
|
|
||||||
if ( index != mOptStackedWidget->indexOf( mOptsPage_Information ) || mMetadataFilled )
|
if ( index != mOptStackedWidget->indexOf( mOptsPage_Information ) || mMetadataFilled )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -118,6 +118,10 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
|||||||
void saveDefaultStyle_clicked();
|
void saveDefaultStyle_clicked();
|
||||||
void loadStyle_clicked();
|
void loadStyle_clicked();
|
||||||
void saveStyleAs_clicked();
|
void saveStyleAs_clicked();
|
||||||
|
void loadMetadata();
|
||||||
|
void saveMetadataAs();
|
||||||
|
void saveDefaultMetadata();
|
||||||
|
void loadDefaultMetadata();
|
||||||
void optionsStackedWidget_CurrentChanged( int index ) override;
|
void optionsStackedWidget_CurrentChanged( int index ) override;
|
||||||
void pbnUpdateExtents_clicked();
|
void pbnUpdateExtents_clicked();
|
||||||
|
|
||||||
@ -167,6 +171,12 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
enum PropertyType
|
||||||
|
{
|
||||||
|
Style = 0,
|
||||||
|
Metadata,
|
||||||
|
};
|
||||||
|
|
||||||
void saveStyleAs( StyleType styleType );
|
void saveStyleAs( StyleType styleType );
|
||||||
|
|
||||||
//! When provider supports, it will list all the styles relative the layer in a dialog
|
//! When provider supports, it will list all the styles relative the layer in a dialog
|
||||||
@ -182,6 +192,11 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
|||||||
|
|
||||||
QString mOriginalSubsetSQL;
|
QString mOriginalSubsetSQL;
|
||||||
|
|
||||||
|
QPushButton *mBtnStyle = nullptr;
|
||||||
|
QPushButton *mBtnMetadata = nullptr;
|
||||||
|
QAction *mActionLoadMetadata = nullptr;
|
||||||
|
QAction *mActionSaveMetadataAs = nullptr;
|
||||||
|
|
||||||
QMenu *mSaveAsMenu = nullptr;
|
QMenu *mSaveAsMenu = nullptr;
|
||||||
QMenu *mLoadStyleMenu = nullptr;
|
QMenu *mLoadStyleMenu = nullptr;
|
||||||
|
|
||||||
|
@ -54,6 +54,19 @@
|
|||||||
#include "qgssettings.h" // TODO: get rid of it [MD]
|
#include "qgssettings.h" // TODO: get rid of it [MD]
|
||||||
#include "qgsstringutils.h"
|
#include "qgsstringutils.h"
|
||||||
|
|
||||||
|
QString QgsMapLayer::extensionPropertyType( QgsMapLayer::PropertyType type )
|
||||||
|
{
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
return QStringLiteral( ".qmd" );
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
return QStringLiteral( ".qml" );
|
||||||
|
}
|
||||||
|
return QStringLiteral();
|
||||||
|
}
|
||||||
|
|
||||||
QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
|
QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
|
||||||
const QString &lyrname,
|
const QString &lyrname,
|
||||||
const QString &source )
|
const QString &source )
|
||||||
@ -1009,7 +1022,7 @@ QString QgsMapLayer::formatLayerName( const QString &name )
|
|||||||
return layerName;
|
return layerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QgsMapLayer::styleURI() const
|
QString QgsMapLayer::baseURI( PropertyType type ) const
|
||||||
{
|
{
|
||||||
QString myURI = publicSource();
|
QString myURI = publicSource();
|
||||||
|
|
||||||
@ -1051,7 +1064,7 @@ QString QgsMapLayer::styleURI() const
|
|||||||
myURI.chop( 4 );
|
myURI.chop( 4 );
|
||||||
myFileInfo.setFile( myURI );
|
myFileInfo.setFile( myURI );
|
||||||
// get the file name for our .qml style file
|
// get the file name for our .qml style file
|
||||||
key = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() + ".qml";
|
key = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() + QgsMapLayer::extensionPropertyType( type );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1061,12 +1074,42 @@ QString QgsMapLayer::styleURI() const
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QgsMapLayer::metadataUri() const
|
||||||
|
{
|
||||||
|
return baseURI( PropertyType::Metadata );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsMapLayer::saveDefaultMetadata( bool &resultFlag )
|
||||||
|
{
|
||||||
|
return saveNamedMetadata( metadataUri(), resultFlag );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsMapLayer::loadDefaultMetadata( bool &resultFlag )
|
||||||
|
{
|
||||||
|
return loadNamedMetadata( metadataUri(), resultFlag );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsMapLayer::styleURI() const
|
||||||
|
{
|
||||||
|
return baseURI( PropertyType::Style );
|
||||||
|
}
|
||||||
|
|
||||||
QString QgsMapLayer::loadDefaultStyle( bool &resultFlag )
|
QString QgsMapLayer::loadDefaultStyle( bool &resultFlag )
|
||||||
{
|
{
|
||||||
return loadNamedStyle( styleURI(), resultFlag );
|
return loadNamedStyle( styleURI(), resultFlag );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QgsMapLayer::loadNamedMetadataFromDatabase( const QString &db, const QString &uri, QString &qmd )
|
||||||
|
{
|
||||||
|
return loadNamedPropertyFromDatabase( db, uri, qmd, PropertyType::Metadata );
|
||||||
|
}
|
||||||
|
|
||||||
bool QgsMapLayer::loadNamedStyleFromDatabase( const QString &db, const QString &uri, QString &qml )
|
bool QgsMapLayer::loadNamedStyleFromDatabase( const QString &db, const QString &uri, QString &qml )
|
||||||
|
{
|
||||||
|
return loadNamedPropertyFromDatabase( db, uri, qml, PropertyType::Style );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsMapLayer::loadNamedPropertyFromDatabase( const QString &db, const QString &uri, QString &xml, QgsMapLayer::PropertyType type )
|
||||||
{
|
{
|
||||||
QgsDebugMsgLevel( QString( "db = %1 uri = %2" ).arg( db, uri ), 4 );
|
QgsDebugMsgLevel( QString( "db = %1 uri = %2" ).arg( db, uri ), 4 );
|
||||||
|
|
||||||
@ -1078,7 +1121,7 @@ bool QgsMapLayer::loadNamedStyleFromDatabase( const QString &db, const QString &
|
|||||||
|
|
||||||
int myResult;
|
int myResult;
|
||||||
|
|
||||||
QgsDebugMsgLevel( QString( "Trying to load style for \"%1\" from \"%2\"" ).arg( uri, db ), 4 );
|
QgsDebugMsgLevel( QString( "Trying to load style or metadata for \"%1\" from \"%2\"" ).arg( uri, db ), 4 );
|
||||||
|
|
||||||
if ( db.isEmpty() || !QFile( db ).exists() )
|
if ( db.isEmpty() || !QFile( db ).exists() )
|
||||||
return false;
|
return false;
|
||||||
@ -1089,7 +1132,18 @@ bool QgsMapLayer::loadNamedStyleFromDatabase( const QString &db, const QString &
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString mySql = QStringLiteral( "select qml from tbl_styles where style=?" );
|
QString mySql;
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
mySql = QStringLiteral( "select qmd from tbl_metadata where metadata=?" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
mySql = QStringLiteral( "select qml from tbl_styles where style=?" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
statement = database.prepare( mySql, myResult );
|
statement = database.prepare( mySql, myResult );
|
||||||
if ( myResult == SQLITE_OK )
|
if ( myResult == SQLITE_OK )
|
||||||
{
|
{
|
||||||
@ -1098,7 +1152,7 @@ bool QgsMapLayer::loadNamedStyleFromDatabase( const QString &db, const QString &
|
|||||||
if ( sqlite3_bind_text( statement.get(), 1, param.data(), param.length(), SQLITE_STATIC ) == SQLITE_OK &&
|
if ( sqlite3_bind_text( statement.get(), 1, param.data(), param.length(), SQLITE_STATIC ) == SQLITE_OK &&
|
||||||
sqlite3_step( statement.get() ) == SQLITE_ROW )
|
sqlite3_step( statement.get() ) == SQLITE_ROW )
|
||||||
{
|
{
|
||||||
qml = QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement.get(), 0 ) ) );
|
xml = QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement.get(), 0 ) ) );
|
||||||
resultFlag = true;
|
resultFlag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1107,9 +1161,15 @@ bool QgsMapLayer::loadNamedStyleFromDatabase( const QString &db, const QString &
|
|||||||
|
|
||||||
|
|
||||||
QString QgsMapLayer::loadNamedStyle( const QString &uri, bool &resultFlag )
|
QString QgsMapLayer::loadNamedStyle( const QString &uri, bool &resultFlag )
|
||||||
|
{
|
||||||
|
return loadNamedProperty( uri, PropertyType::Style, resultFlag );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsMapLayer::loadNamedProperty( const QString &uri, QgsMapLayer::PropertyType type, bool &resultFlag )
|
||||||
{
|
{
|
||||||
QgsDebugMsgLevel( QString( "uri = %1 myURI = %2" ).arg( uri, publicSource() ), 4 );
|
QgsDebugMsgLevel( QString( "uri = %1 myURI = %2" ).arg( uri, publicSource() ), 4 );
|
||||||
|
|
||||||
|
QgsDebugMsg( "loadNamedProperty" );
|
||||||
resultFlag = false;
|
resultFlag = false;
|
||||||
|
|
||||||
QDomDocument myDocument( QStringLiteral( "qgis" ) );
|
QDomDocument myDocument( QStringLiteral( "qgis" ) );
|
||||||
@ -1121,6 +1181,7 @@ QString QgsMapLayer::loadNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
QFile myFile( uri );
|
QFile myFile( uri );
|
||||||
if ( myFile.open( QFile::ReadOnly ) )
|
if ( myFile.open( QFile::ReadOnly ) )
|
||||||
{
|
{
|
||||||
|
QgsDebugMsg( QString( "file found %1" ).arg( uri ) );
|
||||||
// read file
|
// read file
|
||||||
resultFlag = myDocument.setContent( &myFile, &myErrorMessage, &line, &column );
|
resultFlag = myDocument.setContent( &myFile, &myErrorMessage, &line, &column );
|
||||||
if ( !resultFlag )
|
if ( !resultFlag )
|
||||||
@ -1132,20 +1193,47 @@ QString QgsMapLayer::loadNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
QFileInfo project( QgsProject::instance()->fileName() );
|
QFileInfo project( QgsProject::instance()->fileName() );
|
||||||
QgsDebugMsgLevel( QString( "project fileName: %1" ).arg( project.absoluteFilePath() ), 4 );
|
QgsDebugMsgLevel( QString( "project fileName: %1" ).arg( project.absoluteFilePath() ), 4 );
|
||||||
|
|
||||||
QString qml;
|
QString xml;
|
||||||
if ( loadNamedStyleFromDatabase( QDir( QgsApplication::qgisSettingsDirPath() ).absoluteFilePath( QStringLiteral( "qgis.qmldb" ) ), uri, qml ) ||
|
switch ( type )
|
||||||
( project.exists() && loadNamedStyleFromDatabase( project.absoluteDir().absoluteFilePath( project.baseName() + ".qmldb" ), uri, qml ) ) ||
|
|
||||||
loadNamedStyleFromDatabase( QDir( QgsApplication::pkgDataPath() ).absoluteFilePath( QStringLiteral( "resources/qgis.qmldb" ) ), uri, qml ) )
|
|
||||||
{
|
{
|
||||||
resultFlag = myDocument.setContent( qml, &myErrorMessage, &line, &column );
|
case QgsMapLayer::Style:
|
||||||
if ( !resultFlag )
|
|
||||||
{
|
{
|
||||||
myErrorMessage = tr( "%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
|
if ( loadNamedStyleFromDatabase( QDir( QgsApplication::qgisSettingsDirPath() ).absoluteFilePath( QStringLiteral( "qgis.qmldb" ) ), uri, xml ) ||
|
||||||
|
( project.exists() && loadNamedStyleFromDatabase( project.absoluteDir().absoluteFilePath( project.baseName() + ".qmldb" ), uri, xml ) ) ||
|
||||||
|
loadNamedStyleFromDatabase( QDir( QgsApplication::pkgDataPath() ).absoluteFilePath( QStringLiteral( "resources/qgis.qmldb" ) ), uri, xml ) )
|
||||||
|
{
|
||||||
|
resultFlag = myDocument.setContent( xml, &myErrorMessage, &line, &column );
|
||||||
|
if ( !resultFlag )
|
||||||
|
{
|
||||||
|
myErrorMessage = tr( "%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myErrorMessage = tr( "Style not found in database" );
|
||||||
|
resultFlag = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QgsMapLayer::Metadata:
|
||||||
|
{
|
||||||
|
if ( loadNamedMetadataFromDatabase( QDir( QgsApplication::qgisSettingsDirPath() ).absoluteFilePath( QStringLiteral( "qgis.qmldb" ) ), uri, xml ) ||
|
||||||
|
( project.exists() && loadNamedMetadataFromDatabase( project.absoluteDir().absoluteFilePath( project.baseName() + ".qmldb" ), uri, xml ) ) ||
|
||||||
|
loadNamedMetadataFromDatabase( QDir( QgsApplication::pkgDataPath() ).absoluteFilePath( QStringLiteral( "resources/qgis.qmldb" ) ), uri, xml ) )
|
||||||
|
{
|
||||||
|
resultFlag = myDocument.setContent( xml, &myErrorMessage, &line, &column );
|
||||||
|
if ( !resultFlag )
|
||||||
|
{
|
||||||
|
myErrorMessage = tr( "%1 at line %2 column %3" ).arg( myErrorMessage ).arg( line ).arg( column );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myErrorMessage = tr( "Metadata not found in database" );
|
||||||
|
resultFlag = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
myErrorMessage = tr( "Style not found in database" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1154,13 +1242,33 @@ QString QgsMapLayer::loadNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
return myErrorMessage;
|
return myErrorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
resultFlag = importNamedStyle( myDocument, myErrorMessage );
|
switch ( type )
|
||||||
if ( !resultFlag )
|
{
|
||||||
myErrorMessage = tr( "Loading style file %1 failed because:\n%2" ).arg( uri, myErrorMessage );
|
case QgsMapLayer::Style:
|
||||||
|
resultFlag = importNamedStyle( myDocument, myErrorMessage );
|
||||||
|
if ( !resultFlag )
|
||||||
|
myErrorMessage = tr( "Loading style file %1 failed because:\n%2" ).arg( uri, myErrorMessage );
|
||||||
|
break;
|
||||||
|
case QgsMapLayer::Metadata:
|
||||||
|
resultFlag = importNamedMetadata( myDocument, myErrorMessage );
|
||||||
|
if ( !resultFlag )
|
||||||
|
myErrorMessage = tr( "Loading metadata file %1 failed because:\n%2" ).arg( uri, myErrorMessage );
|
||||||
|
break;
|
||||||
|
}
|
||||||
return myErrorMessage;
|
return myErrorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QgsMapLayer::importNamedMetadata( QDomDocument &document, QString &errorMessage )
|
||||||
|
{
|
||||||
|
QDomElement myRoot = document.firstChildElement( QStringLiteral( "qgis" ) );
|
||||||
|
if ( myRoot.isNull() )
|
||||||
|
{
|
||||||
|
errorMessage = tr( "Root <qgis> element could not be found" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mMetadata.readMetadataXml( myRoot );
|
||||||
|
}
|
||||||
|
|
||||||
bool QgsMapLayer::importNamedStyle( QDomDocument &myDocument, QString &myErrorMessage )
|
bool QgsMapLayer::importNamedStyle( QDomDocument &myDocument, QString &myErrorMessage )
|
||||||
{
|
{
|
||||||
@ -1210,6 +1318,25 @@ bool QgsMapLayer::importNamedStyle( QDomDocument &myDocument, QString &myErrorMe
|
|||||||
return readSymbology( myRoot, myErrorMessage, QgsReadWriteContext() ); // TODO: support relative paths in QML?
|
return readSymbology( myRoot, myErrorMessage, QgsReadWriteContext() ); // TODO: support relative paths in QML?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsMapLayer::exportNamedMetadata( QDomDocument &doc, QString &errorMsg ) const
|
||||||
|
{
|
||||||
|
QDomImplementation DomImplementation;
|
||||||
|
QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );
|
||||||
|
QDomDocument myDocument( documentType );
|
||||||
|
|
||||||
|
QDomElement myRootNode = myDocument.createElement( QStringLiteral( "qgis" ) );
|
||||||
|
myRootNode.setAttribute( QStringLiteral( "version" ), Qgis::QGIS_VERSION );
|
||||||
|
myDocument.appendChild( myRootNode );
|
||||||
|
|
||||||
|
if ( !mMetadata.writeMetadataXml( myRootNode, myDocument ) )
|
||||||
|
{
|
||||||
|
errorMsg = QObject::tr( "Could not save metadata" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
doc = myDocument;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsMapLayer::exportNamedStyle( QDomDocument &doc, QString &errorMsg ) const
|
void QgsMapLayer::exportNamedStyle( QDomDocument &doc, QString &errorMsg ) const
|
||||||
{
|
{
|
||||||
QDomImplementation DomImplementation;
|
QDomImplementation DomImplementation;
|
||||||
@ -1256,13 +1383,19 @@ QString QgsMapLayer::saveDefaultStyle( bool &resultFlag )
|
|||||||
return saveNamedStyle( styleURI(), resultFlag );
|
return saveNamedStyle( styleURI(), resultFlag );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
QString QgsMapLayer::saveNamedMetadata( const QString &uri, bool &resultFlag )
|
||||||
{
|
{
|
||||||
QString myErrorMessage;
|
return saveNamedProperty( uri, QgsMapLayer::Metadata, resultFlag );
|
||||||
QDomDocument myDocument;
|
}
|
||||||
exportNamedStyle( myDocument, myErrorMessage );
|
|
||||||
|
|
||||||
// check if the uri is a file or ends with .qml,
|
QString QgsMapLayer::loadNamedMetadata( const QString &uri, bool &resultFlag )
|
||||||
|
{
|
||||||
|
return loadNamedProperty( uri, QgsMapLayer::Metadata, resultFlag );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsMapLayer::saveNamedProperty( const QString &uri, QgsMapLayer::PropertyType type, bool &resultFlag )
|
||||||
|
{
|
||||||
|
// check if the uri is a file or ends with .qml/.qmd,
|
||||||
// which indicates that it should become one
|
// which indicates that it should become one
|
||||||
// everything else goes to the database
|
// everything else goes to the database
|
||||||
QString filename;
|
QString filename;
|
||||||
@ -1290,8 +1423,21 @@ QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
filename = uri;
|
filename = uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString myErrorMessage;
|
||||||
|
QDomDocument myDocument;
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
exportNamedMetadata( myDocument, myErrorMessage );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
exportNamedStyle( myDocument, myErrorMessage );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
QFileInfo myFileInfo( filename );
|
QFileInfo myFileInfo( filename );
|
||||||
if ( myFileInfo.exists() || filename.endsWith( QLatin1String( ".qml" ), Qt::CaseInsensitive ) )
|
if ( myFileInfo.exists() || filename.endsWith( QgsMapLayer::extensionPropertyType( type ), Qt::CaseInsensitive ) )
|
||||||
{
|
{
|
||||||
QFileInfo myDirInfo( myFileInfo.path() ); //excludes file name
|
QFileInfo myDirInfo( myFileInfo.path() ); //excludes file name
|
||||||
if ( !myDirInfo.isWritable() )
|
if ( !myDirInfo.isWritable() )
|
||||||
@ -1299,8 +1445,8 @@ QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
return tr( "The directory containing your dataset needs to be writable!" );
|
return tr( "The directory containing your dataset needs to be writable!" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// now construct the file name for our .qml style file
|
// now construct the file name for our .qml or .qmd file
|
||||||
QString myFileName = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() + ".qml";
|
QString myFileName = myFileInfo.path() + QDir::separator() + myFileInfo.completeBaseName() + QgsMapLayer::extensionPropertyType( type );
|
||||||
|
|
||||||
QFile myFile( myFileName );
|
QFile myFile( myFileName );
|
||||||
if ( myFile.open( QFile::WriteOnly | QFile::Truncate ) )
|
if ( myFile.open( QFile::WriteOnly | QFile::Truncate ) )
|
||||||
@ -1310,12 +1456,27 @@ QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
myDocument.save( myFileStream, 2 );
|
myDocument.save( myFileStream, 2 );
|
||||||
myFile.close();
|
myFile.close();
|
||||||
resultFlag = true;
|
resultFlag = true;
|
||||||
return tr( "Created default style file as %1" ).arg( myFileName );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
return tr( "Created default metadata file as %1" ).arg( myFileName );
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
return tr( "Created default style file as %1" ).arg( myFileName );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resultFlag = false;
|
resultFlag = false;
|
||||||
return tr( "ERROR: Failed to created default style file as %1. Check file permissions and retry." ).arg( myFileName );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
return tr( "ERROR: Failed to created default metadata file as %1. Check file permissions and retry." ).arg( myFileName );
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
return tr( "ERROR: Failed to created default style file as %1. Check file permissions and retry." ).arg( myFileName );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1335,18 +1496,45 @@ QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
QByteArray param0 = uri.toUtf8();
|
QByteArray param0 = uri.toUtf8();
|
||||||
QByteArray param1 = qml.toUtf8();
|
QByteArray param1 = qml.toUtf8();
|
||||||
|
|
||||||
QString mySql = QStringLiteral( "create table if not exists tbl_styles(style varchar primary key,qml varchar)" );
|
QString mySql;
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
mySql = QStringLiteral( "create table if not exists tbl_metadata(metadata varchar primary key,qmd varchar)" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
mySql = QStringLiteral( "create table if not exists tbl_styles(style varchar primary key,qml varchar)" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
statement = database.prepare( mySql, myResult );
|
statement = database.prepare( mySql, myResult );
|
||||||
if ( myResult == SQLITE_OK )
|
if ( myResult == SQLITE_OK )
|
||||||
{
|
{
|
||||||
if ( sqlite3_step( statement.get() ) != SQLITE_DONE )
|
if ( sqlite3_step( statement.get() ) != SQLITE_DONE )
|
||||||
{
|
{
|
||||||
resultFlag = false;
|
resultFlag = false;
|
||||||
return tr( "The style table could not be created." );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
return tr( "The metadata table could not be created." );
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
return tr( "The style table could not be created." );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mySql = QStringLiteral( "insert into tbl_styles(style,qml) values (?,?)" );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
mySql = QStringLiteral( "insert into tbl_metadata(metadata,qmd) values (?,?)" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
mySql = QStringLiteral( "insert into tbl_styles(style,qml) values (?,?)" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
statement = database.prepare( mySql, myResult );
|
statement = database.prepare( mySql, myResult );
|
||||||
if ( myResult == SQLITE_OK )
|
if ( myResult == SQLITE_OK )
|
||||||
{
|
{
|
||||||
@ -1355,15 +1543,33 @@ QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
sqlite3_step( statement.get() ) == SQLITE_DONE )
|
sqlite3_step( statement.get() ) == SQLITE_DONE )
|
||||||
{
|
{
|
||||||
resultFlag = true;
|
resultFlag = true;
|
||||||
myErrorMessage = tr( "The style %1 was saved to database" ).arg( uri );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
myErrorMessage = tr( "The metadata %1 was saved to database" ).arg( uri );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
myErrorMessage = tr( "The style %1 was saved to database" ).arg( uri );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !resultFlag )
|
if ( !resultFlag )
|
||||||
{
|
{
|
||||||
QString mySql = QStringLiteral( "update tbl_styles set qml=? where style=?" );
|
QString mySql;
|
||||||
statement = database.prepare( mySql, myResult );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
mySql = QStringLiteral( "update tbl_metadata set qmd=? where metadata=?" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
mySql = QStringLiteral( "update tbl_styles set qml=? where style=?" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
statement = database.prepare( mySql, myResult );
|
||||||
if ( myResult == SQLITE_OK )
|
if ( myResult == SQLITE_OK )
|
||||||
{
|
{
|
||||||
if ( sqlite3_bind_text( statement.get(), 2, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
|
if ( sqlite3_bind_text( statement.get(), 2, param0.data(), param0.length(), SQLITE_STATIC ) == SQLITE_OK &&
|
||||||
@ -1371,18 +1577,45 @@ QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
sqlite3_step( statement.get() ) == SQLITE_DONE )
|
sqlite3_step( statement.get() ) == SQLITE_DONE )
|
||||||
{
|
{
|
||||||
resultFlag = true;
|
resultFlag = true;
|
||||||
myErrorMessage = tr( "The style %1 was updated in the database." ).arg( uri );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
myErrorMessage = tr( "The metadata %1 was updated in the database." ).arg( uri );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
myErrorMessage = tr( "The style %1 was updated in the database." ).arg( uri );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resultFlag = false;
|
resultFlag = false;
|
||||||
myErrorMessage = tr( "The style %1 could not be updated in the database." ).arg( uri );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
myErrorMessage = tr( "The metadata %1 could not be updated in the database." ).arg( uri );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
myErrorMessage = tr( "The style %1 could not be updated in the database." ).arg( uri );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resultFlag = false;
|
resultFlag = false;
|
||||||
myErrorMessage = tr( "The style %1 could not be inserted into database." ).arg( uri );
|
switch ( type )
|
||||||
|
{
|
||||||
|
case Metadata:
|
||||||
|
myErrorMessage = tr( "The metadata %1 could not be inserted into database." ).arg( uri );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style:
|
||||||
|
myErrorMessage = tr( "The style %1 could not be inserted into database." ).arg( uri );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1390,6 +1623,11 @@ QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
|||||||
return myErrorMessage;
|
return myErrorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QgsMapLayer::saveNamedStyle( const QString &uri, bool &resultFlag )
|
||||||
|
{
|
||||||
|
return saveNamedProperty( uri, QgsMapLayer::Style, resultFlag );
|
||||||
|
}
|
||||||
|
|
||||||
void QgsMapLayer::exportSldStyle( QDomDocument &doc, QString &errorMsg ) const
|
void QgsMapLayer::exportSldStyle( QDomDocument &doc, QString &errorMsg ) const
|
||||||
{
|
{
|
||||||
QDomDocument myDocument = QDomDocument();
|
QDomDocument myDocument = QDomDocument();
|
||||||
|
@ -98,6 +98,16 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
|||||||
PluginLayer
|
PluginLayer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maplayer has a style and a metadata property
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
enum PropertyType
|
||||||
|
{
|
||||||
|
Style = 0,
|
||||||
|
Metadata,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for QgsMapLayer
|
* Constructor for QgsMapLayer
|
||||||
* \param type layer type
|
* \param type layer type
|
||||||
@ -126,6 +136,13 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
|||||||
*/
|
*/
|
||||||
QgsMapLayer::LayerType type() const;
|
QgsMapLayer::LayerType type() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the extension of a Property.
|
||||||
|
* \returns The extension
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
static QString extensionPropertyType( PropertyType type );
|
||||||
|
|
||||||
//! Returns the layer's unique ID, which is used to access this layer from QgsProject.
|
//! Returns the layer's unique ID, which is used to access this layer from QgsProject.
|
||||||
QString id() const;
|
QString id() const;
|
||||||
|
|
||||||
@ -525,6 +542,96 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
|||||||
*/
|
*/
|
||||||
static QString formatLayerName( const QString &name );
|
static QString formatLayerName( const QString &name );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
* \returns a QString with the metadata file name
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
virtual QString metadataUri() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
void exportNamedMetadata( QDomDocument &doc, QString &errorMsg ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* \returns a QString with any status messages
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
virtual QString saveDefaultMetadata( bool &resultFlag SIP_OUT );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* \returns a QString with any status messages
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
QString saveNamedMetadata( const QString &uri, bool &resultFlag );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* \returns a QString with any status messages
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
virtual QString loadNamedMetadata( const QString &uri, bool &resultFlag SIP_OUT );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* \returns a QString with any status messages
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
QString loadDefaultMetadata( bool &resultFlag );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* \returns true if style was successfully loaded
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
bool loadNamedMetadataFromDatabase( const QString &db, const QString &uri, QString &qmd );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import the metadata of this layer from a QDomDocument
|
||||||
|
* \param document source QDomDocument
|
||||||
|
* \param errorMessage this QString will be initialized on error
|
||||||
|
* \returns true on success
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
bool importNamedMetadata( QDomDocument &document, QString &errorMessage );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the style URI for this layer
|
* Retrieve the style URI for this layer
|
||||||
* (either as a .qml file on disk or as a
|
* (either as a .qml file on disk or as a
|
||||||
@ -1169,6 +1276,11 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
virtual QString baseURI( PropertyType type ) const;
|
||||||
|
QString saveNamedProperty( const QString &uri, QgsMapLayer::PropertyType type, bool &resultFlag );
|
||||||
|
QString loadNamedProperty( const QString &uri, QgsMapLayer::PropertyType type, bool &resultFlag );
|
||||||
|
bool loadNamedPropertyFromDatabase( const QString &db, const QString &uri, QString &xml, QgsMapLayer::PropertyType type );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns true by default but can be overwritten to specify
|
* This method returns true by default but can be overwritten to specify
|
||||||
* that a certain layer is writable.
|
* that a certain layer is writable.
|
||||||
|
@ -820,6 +820,12 @@ void QgsMetadataWidget::acceptMetadata()
|
|||||||
mLayer->setMetadata( mMetadata );
|
mLayer->setMetadata( mMetadata );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsMetadataWidget::setMetadata( const QgsLayerMetadata &metadata )
|
||||||
|
{
|
||||||
|
mMetadata = metadata;
|
||||||
|
setPropertiesFromLayer();
|
||||||
|
}
|
||||||
|
|
||||||
void QgsMetadataWidget::syncFromCategoriesTabToKeywordsTab() const
|
void QgsMetadataWidget::syncFromCategoriesTabToKeywordsTab() const
|
||||||
{
|
{
|
||||||
if ( mCategoriesModel->rowCount() > 0 )
|
if ( mCategoriesModel->rowCount() > 0 )
|
||||||
|
@ -66,6 +66,11 @@ class GUI_EXPORT QgsMetadataWidget : public QWidget, private Ui::QgsMetadataWidg
|
|||||||
*/
|
*/
|
||||||
void acceptMetadata();
|
void acceptMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the layer's \a metadata store.
|
||||||
|
*/
|
||||||
|
virtual void setMetadata( const QgsLayerMetadata &metadata );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of languages available by default in the wizard.
|
* Returns a list of languages available by default in the wizard.
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,7 @@ __copyright__ = 'Copyright 2017, The QGIS Project'
|
|||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
import qgis # NOQA
|
import qgis # NOQA
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from qgis.core import (QgsReadWriteContext,
|
from qgis.core import (QgsReadWriteContext,
|
||||||
QgsVectorLayer,
|
QgsVectorLayer,
|
||||||
@ -88,6 +89,22 @@ class TestQgsMapLayer(unittest.TestCase):
|
|||||||
self.assertTrue(layer2.hasAutoRefreshEnabled())
|
self.assertTrue(layer2.hasAutoRefreshEnabled())
|
||||||
self.assertEqual(layer2.autoRefreshInterval(), 56)
|
self.assertEqual(layer2.autoRefreshInterval(), 56)
|
||||||
|
|
||||||
|
def testReadWriteMetadata(self):
|
||||||
|
layer = QgsVectorLayer("Point?field=fldtxt:string", "layer", "memory")
|
||||||
|
m = layer.metadata()
|
||||||
|
# Only abstract, more tests are done in test_qgslayermetadata.py
|
||||||
|
m.setAbstract('My abstract')
|
||||||
|
layer.setMetadata(m)
|
||||||
|
self.assertTrue(layer.metadata().abstract(), 'My abstract')
|
||||||
|
destination = tempfile.NamedTemporaryFile(suffix='.qmd').name
|
||||||
|
message, status = layer.saveNamedMetadata(destination)
|
||||||
|
self.assertTrue(status, message)
|
||||||
|
|
||||||
|
layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer", "memory")
|
||||||
|
message, status = layer2.loadNamedMetadata(destination)
|
||||||
|
self.assertTrue(status)
|
||||||
|
self.assertTrue(layer2.metadata().abstract(), 'My abstract')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user