mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
* Save and restore visiblity state of embedded group layers (fixes #4097)
* Adds support for lists in custom properties
This commit is contained in:
parent
3711fd5899
commit
b49da36c7f
@ -11,11 +11,11 @@ class QgsLayerTreeUtils
|
||||
|
||||
public:
|
||||
|
||||
//! Try to load layer tree from <legend> tag from project files from QGIS 2.2 and below
|
||||
//! Try to load layer tree from \verbatim <legend> \endverbatim tag from project files from QGIS 2.2 and below
|
||||
static bool readOldLegend( QgsLayerTreeGroup* root, const QDomElement& legendElem );
|
||||
//! Try to load custom layer order from <legend> tag from project files from QGIS 2.2 and below
|
||||
//! Try to load custom layer order from \verbatim <legend> \endverbatim tag from project files from QGIS 2.2 and below
|
||||
static bool readOldLegendLayerOrder( const QDomElement& legendElem, bool& hasCustomOrder, QStringList& order );
|
||||
//! Return <legend> tag used in QGIS 2.2 and below
|
||||
//! Return \verbatim <legend> \endverbatim tag used in QGIS 2.2 and below
|
||||
static QDomElement writeOldLegend( QDomDocument& doc, QgsLayerTreeGroup* root, bool hasCustomOrder, const QStringList& order );
|
||||
|
||||
//! Convert Qt::CheckState to QString
|
||||
@ -31,7 +31,10 @@ class QgsLayerTreeUtils
|
||||
//! Remove layer nodes that refer to invalid layers
|
||||
static void removeInvalidLayers( QgsLayerTreeGroup* group );
|
||||
|
||||
//! Remove subtree of embedded groups. Useful when saving layer tree
|
||||
static void removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group );
|
||||
//! Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers
|
||||
static void replaceChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group );
|
||||
|
||||
|
||||
//! get invisible layers
|
||||
static QStringList invisibleLayerList( QgsLayerTreeNode *node );
|
||||
};
|
||||
|
@ -252,10 +252,11 @@ class QgsProject : QObject
|
||||
bool createEmbeddedLayer( const QString& layerId, const QString& projectFilePath, QList<QDomNode>& brokenNodes,
|
||||
QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList, bool saveFlag = true );
|
||||
*/
|
||||
|
||||
/** Create layer group instance defined in an arbitrary project file.
|
||||
* @note: added in version 2.4
|
||||
*/
|
||||
QgsLayerTreeGroup* createEmbeddedGroup( const QString& groupName, const QString& projectFilePath );
|
||||
QgsLayerTreeGroup* createEmbeddedGroup( const QString& groupName, const QString& projectFilePath, const QStringList &invisibleLayers );
|
||||
|
||||
/** Convenience function to set snap settings per layer */
|
||||
void setSnapSettingsForLayer( const QString& layerId, bool enabled, QgsSnapper::SnappingType type, QgsTolerance::UnitType unit, double tolerance,
|
||||
@ -305,9 +306,6 @@ class QgsProject : QObject
|
||||
//! @note not available in python bindings
|
||||
// void loadEmbeddedNodes( QgsLayerTreeGroup* group );
|
||||
|
||||
//! @note not available in python bindings
|
||||
// void updateEmbeddedGroupsProjectPath( QgsLayerTreeGroup* group );
|
||||
|
||||
signals:
|
||||
//! emitted when project is being read
|
||||
void readProject( const QDomDocument & );
|
||||
|
@ -7958,7 +7958,7 @@ void QgisApp::embedLayers()
|
||||
QStringList::const_iterator groupIt = groups.constBegin();
|
||||
for ( ; groupIt != groups.constEnd(); ++groupIt )
|
||||
{
|
||||
QgsLayerTreeGroup* newGroup = QgsProject::instance()->createEmbeddedGroup( *groupIt, projectFile );
|
||||
QgsLayerTreeGroup* newGroup = QgsProject::instance()->createEmbeddedGroup( *groupIt, projectFile, QStringList() );
|
||||
|
||||
if ( newGroup )
|
||||
QgsProject::instance()->layerTreeRoot()->addChildNode( newGroup );
|
||||
@ -9935,7 +9935,7 @@ void QgisApp::writeProject( QDomDocument &doc )
|
||||
// can be opened in older versions of QGIS without loosing information about layer groups.
|
||||
|
||||
QgsLayerTreeNode* clonedRoot = QgsProject::instance()->layerTreeRoot()->clone();
|
||||
QgsLayerTreeUtils::removeChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
|
||||
QgsLayerTreeUtils::replaceChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
|
||||
QgsLayerTreeUtils::updateEmbeddedGroupsProjectPath( QgsLayerTree::toGroup( clonedRoot ) ); // convert absolute paths to relative paths if required
|
||||
QDomElement oldLegendElem = QgsLayerTreeUtils::writeOldLegend( doc, QgsLayerTree::toGroup( clonedRoot ),
|
||||
mLayerTreeCanvasBridge->hasCustomLayerOrder(), mLayerTreeCanvasBridge->customLayerOrder() );
|
||||
|
@ -304,16 +304,43 @@ void QgsLayerTreeUtils::removeInvalidLayers( QgsLayerTreeGroup* group )
|
||||
group->removeChildNode( node );
|
||||
}
|
||||
|
||||
void QgsLayerTreeUtils::removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group )
|
||||
QStringList QgsLayerTreeUtils::invisibleLayerList( QgsLayerTreeNode *node )
|
||||
{
|
||||
QStringList list;
|
||||
|
||||
if ( QgsLayerTree::isGroup( node ) )
|
||||
{
|
||||
foreach ( QgsLayerTreeNode *child, QgsLayerTree::toGroup( node )->children() )
|
||||
{
|
||||
list << invisibleLayerList( child );
|
||||
}
|
||||
}
|
||||
else if ( QgsLayerTree::isLayer( node ) )
|
||||
{
|
||||
QgsLayerTreeLayer *layer = QgsLayerTree::toLayer( node );
|
||||
|
||||
if ( !layer->isVisible() )
|
||||
list << layer->layerId();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void QgsLayerTreeUtils::replaceChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group )
|
||||
{
|
||||
foreach ( QgsLayerTreeNode* child, group->children() )
|
||||
{
|
||||
if ( QgsLayerTree::isGroup( child ) )
|
||||
{
|
||||
if ( child->customProperty( "embedded" ).toInt() )
|
||||
{
|
||||
child->setCustomProperty( "embedded-invisible-layers", invisibleLayerList( child ) );
|
||||
QgsLayerTree::toGroup( child )->removeAllChildren();
|
||||
}
|
||||
else
|
||||
removeChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( child ) );
|
||||
{
|
||||
replaceChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( child ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class QDomElement;
|
||||
class QDomDocument;
|
||||
class QStringList;
|
||||
|
||||
class QgsLayerTreeNode;
|
||||
class QgsLayerTreeGroup;
|
||||
class QgsLayerTreeLayer;
|
||||
|
||||
@ -55,12 +56,14 @@ class CORE_EXPORT QgsLayerTreeUtils
|
||||
//! Remove layer nodes that refer to invalid layers
|
||||
static void removeInvalidLayers( QgsLayerTreeGroup* group );
|
||||
|
||||
//! Remove subtree of embedded groups. Useful when saving layer tree
|
||||
static void removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group );
|
||||
//! Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers
|
||||
static void replaceChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group );
|
||||
|
||||
//! @note not available in python bindings
|
||||
static void updateEmbeddedGroupsProjectPath( QgsLayerTreeGroup* group );
|
||||
|
||||
//! get invisible layers
|
||||
static QStringList invisibleLayerList( QgsLayerTreeNode *node );
|
||||
};
|
||||
|
||||
#endif // QGSLAYERTREEUTILS_H
|
||||
|
@ -88,8 +88,24 @@ void QgsObjectCustomProperties::readXml( const QDomNode& parentNode, const QStri
|
||||
QString key = propElement.attribute( "key" );
|
||||
if ( key.isEmpty() || key.startsWith( keyStartsWith ) )
|
||||
{
|
||||
QString value = propElement.attribute( "value" );
|
||||
mMap[key] = QVariant( value );
|
||||
if ( propElement.hasAttribute( "value" ) )
|
||||
{
|
||||
QString value = propElement.attribute( "value" );
|
||||
mMap[key] = QVariant( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList list;
|
||||
|
||||
for ( QDomElement itemElement = propElement.firstChildElement( "value" );
|
||||
!itemElement.isNull();
|
||||
itemElement = itemElement.nextSiblingElement( "value" ) )
|
||||
{
|
||||
list << itemElement.text();
|
||||
}
|
||||
|
||||
mMap[key] = QVariant( list );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +126,19 @@ void QgsObjectCustomProperties::writeXml( QDomNode& parentNode, QDomDocument& do
|
||||
{
|
||||
QDomElement propElement = doc.createElement( "property" );
|
||||
propElement.setAttribute( "key", it.key() );
|
||||
propElement.setAttribute( "value", it.value().toString() );
|
||||
if ( it.value().canConvert<QString>() )
|
||||
{
|
||||
propElement.setAttribute( "value", it.value().toString() );
|
||||
}
|
||||
else if ( it.value().canConvert<QStringList>() )
|
||||
{
|
||||
foreach ( QString value, it.value().toStringList() )
|
||||
{
|
||||
QDomElement itemElement = doc.createElement( "value" );
|
||||
itemElement.appendChild( doc.createTextNode( value ) );
|
||||
propElement.appendChild( itemElement );
|
||||
}
|
||||
}
|
||||
propsElement.appendChild( propElement );
|
||||
}
|
||||
|
||||
|
@ -974,7 +974,7 @@ void QgsProject::loadEmbeddedNodes( QgsLayerTreeGroup* group )
|
||||
QString projectPath = readPath( childGroup->customProperty( "embedded_project" ).toString() );
|
||||
childGroup->setCustomProperty( "embedded_project", projectPath );
|
||||
|
||||
QgsLayerTreeGroup* newGroup = createEmbeddedGroup( childGroup->name(), projectPath );
|
||||
QgsLayerTreeGroup* newGroup = createEmbeddedGroup( childGroup->name(), projectPath, childGroup->customProperty( "embedded-invisible-layers" ).toStringList() );
|
||||
if ( newGroup )
|
||||
{
|
||||
QList<QgsLayerTreeNode*> clonedChildren;
|
||||
@ -1083,7 +1083,7 @@ bool QgsProject::write()
|
||||
|
||||
// write layer tree - make sure it is without embedded subgroups
|
||||
QgsLayerTreeNode* clonedRoot = mRootGroup->clone();
|
||||
QgsLayerTreeUtils::removeChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
|
||||
QgsLayerTreeUtils::replaceChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
|
||||
QgsLayerTreeUtils::updateEmbeddedGroupsProjectPath( QgsLayerTree::toGroup( clonedRoot ) ); // convert absolute paths to relative paths if required
|
||||
clonedRoot->writeXML( qgisNode );
|
||||
delete clonedRoot;
|
||||
@ -1794,7 +1794,7 @@ bool QgsProject::createEmbeddedLayer( const QString& layerId, const QString& pro
|
||||
}
|
||||
|
||||
|
||||
QgsLayerTreeGroup* QgsProject::createEmbeddedGroup( const QString& groupName, const QString& projectFilePath )
|
||||
QgsLayerTreeGroup* QgsProject::createEmbeddedGroup( const QString& groupName, const QString& projectFilePath, const QStringList &invisibleLayers )
|
||||
{
|
||||
//open project file, get layer ids in group, add the layers
|
||||
QFile projectFile( projectFilePath );
|
||||
@ -1863,6 +1863,12 @@ QgsLayerTreeGroup* QgsProject::createEmbeddedGroup( const QString& groupName, co
|
||||
thisProjectIdentifyDisabledLayers.append( layerId );
|
||||
QgsProject::instance()->writeEntry( "Identify", "/disabledLayers", thisProjectIdentifyDisabledLayers );
|
||||
}
|
||||
|
||||
QgsLayerTreeLayer *layer = newGroup->findLayer( layerId );
|
||||
if ( layer )
|
||||
{
|
||||
layer->setVisible( invisibleLayers.contains( layerId ) ? Qt::Unchecked : Qt::Checked );
|
||||
}
|
||||
}
|
||||
|
||||
return newGroup;
|
||||
|
@ -299,7 +299,7 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
/** Create layer group instance defined in an arbitrary project file.
|
||||
* @note: added in version 2.4
|
||||
*/
|
||||
QgsLayerTreeGroup* createEmbeddedGroup( const QString& groupName, const QString& projectFilePath );
|
||||
QgsLayerTreeGroup* createEmbeddedGroup( const QString& groupName, const QString& projectFilePath, const QStringList &invisibleLayers );
|
||||
|
||||
/** Convenience function to set snap settings per layer */
|
||||
void setSnapSettingsForLayer( const QString& layerId, bool enabled, QgsSnapper::SnappingType type, QgsTolerance::UnitType unit, double tolerance,
|
||||
|
Loading…
x
Reference in New Issue
Block a user