mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[layertree] Fix #10347 - save also old <legend> tag
QGIS server does not use QgsProject for loading of QGIS project. In order to allow reading of new projects, let's also write the original <legend> tag to the project. Ideally the server should be ported to new layer tree implementation, but that requires non-trivial changes to the server components. The <legend> tag is ignored by QGIS application in >= 2.4 and this way also the new project files can be opened in older versions of QGIS without loosing information about layer groups.
This commit is contained in:
parent
bba9a99d32
commit
2df8f8c11e
@ -9546,6 +9546,20 @@ void QgisApp::projectChanged( const QDomDocument &doc )
|
|||||||
|
|
||||||
void QgisApp::writeProject( QDomDocument &doc )
|
void QgisApp::writeProject( QDomDocument &doc )
|
||||||
{
|
{
|
||||||
|
// QGIS server does not use QgsProject for loading of QGIS project.
|
||||||
|
// In order to allow reading of new projects, let's also write the original <legend> tag to the project.
|
||||||
|
// Ideally the server should be ported to new layer tree implementation, but that requires
|
||||||
|
// non-trivial changes to the server components.
|
||||||
|
// The <legend> tag is ignored by QGIS application in >= 2.4 and this way also the new project files
|
||||||
|
// 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 ) );
|
||||||
|
QDomElement oldLegendElem = QgsLayerTreeUtils::writeOldLegend( doc, QgsLayerTree::toGroup( clonedRoot ),
|
||||||
|
mLayerTreeCanvasBridge->hasCustomLayerOrder(), mLayerTreeCanvasBridge->customLayerOrder() );
|
||||||
|
delete clonedRoot;
|
||||||
|
doc.firstChildElement( "qgis" ).appendChild( oldLegendElem );
|
||||||
|
|
||||||
projectChanged( doc );
|
projectChanged( doc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,79 @@ bool QgsLayerTreeUtils::readOldLegendLayerOrder( const QDomElement& legendElem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static QDomElement _writeOldLegendLayer( QDomDocument& doc, QgsLayerTreeLayer* nodeLayer, bool hasCustomOrder, const QStringList& order )
|
||||||
|
{
|
||||||
|
int drawingOrder = -1;
|
||||||
|
if ( hasCustomOrder )
|
||||||
|
drawingOrder = order.indexOf( nodeLayer->layerId() );
|
||||||
|
|
||||||
|
QDomElement layerElem = doc.createElement( "legendlayer" );
|
||||||
|
layerElem.setAttribute( "drawingOrder", drawingOrder );
|
||||||
|
layerElem.setAttribute( "open", nodeLayer->isExpanded() ? "true" : "false" );
|
||||||
|
layerElem.setAttribute( "checked", QgsLayerTreeUtils::checkStateToXml( nodeLayer->isVisible() ) );
|
||||||
|
layerElem.setAttribute( "name", nodeLayer->layerName() );
|
||||||
|
layerElem.setAttribute( "showFeatureCount", nodeLayer->customProperty( "showFeatureCount" ).toInt() );
|
||||||
|
|
||||||
|
QDomElement fileGroupElem = doc.createElement( "filegroup" );
|
||||||
|
fileGroupElem.setAttribute( "open", nodeLayer->isExpanded() ? "true" : "false" );
|
||||||
|
fileGroupElem.setAttribute( "hidden", "false" );
|
||||||
|
|
||||||
|
QDomElement layerFileElem = doc.createElement( "legendlayerfile" );
|
||||||
|
layerFileElem.setAttribute( "isInOverview", nodeLayer->customProperty( "overview" ).toInt() );
|
||||||
|
layerFileElem.setAttribute( "layerid", nodeLayer->layerId() );
|
||||||
|
layerFileElem.setAttribute( "visible", nodeLayer->isVisible() == Qt::Checked ? 1 : 0 );
|
||||||
|
|
||||||
|
layerElem.appendChild( fileGroupElem );
|
||||||
|
fileGroupElem.appendChild( layerFileElem );
|
||||||
|
return layerElem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need forward declaration as write[..]Group and write[..]GroupChildren call each other
|
||||||
|
static void _writeOldLegendGroupChildren( QDomDocument& doc, QDomElement& groupElem, QgsLayerTreeGroup* nodeGroup, bool hasCustomOrder, const QStringList& order );
|
||||||
|
|
||||||
|
static QDomElement _writeOldLegendGroup( QDomDocument& doc, QgsLayerTreeGroup* nodeGroup, bool hasCustomOrder, const QStringList& order )
|
||||||
|
{
|
||||||
|
QDomElement groupElem = doc.createElement( "legendgroup" );
|
||||||
|
groupElem.setAttribute( "open", nodeGroup->isExpanded() ? "true" : "false" );
|
||||||
|
groupElem.setAttribute( "name", nodeGroup->name() );
|
||||||
|
groupElem.setAttribute( "checked", QgsLayerTreeUtils::checkStateToXml( nodeGroup->isVisible() ) );
|
||||||
|
|
||||||
|
if ( nodeGroup->customProperty( "embedded" ).toInt() )
|
||||||
|
{
|
||||||
|
groupElem.setAttribute( "embedded", 1 );
|
||||||
|
groupElem.setAttribute( "project", nodeGroup->customProperty( "embedded_project" ).toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeOldLegendGroupChildren( doc, groupElem, nodeGroup, hasCustomOrder, order );
|
||||||
|
return groupElem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void _writeOldLegendGroupChildren( QDomDocument& doc, QDomElement& groupElem, QgsLayerTreeGroup* nodeGroup, bool hasCustomOrder, const QStringList& order )
|
||||||
|
{
|
||||||
|
foreach ( QgsLayerTreeNode* node, nodeGroup->children() )
|
||||||
|
{
|
||||||
|
if ( QgsLayerTree::isGroup( node ) )
|
||||||
|
{
|
||||||
|
groupElem.appendChild( _writeOldLegendGroup( doc, QgsLayerTree::toGroup( node ), hasCustomOrder, order ) );
|
||||||
|
}
|
||||||
|
else if ( QgsLayerTree::isLayer( node ) )
|
||||||
|
{
|
||||||
|
groupElem.appendChild( _writeOldLegendLayer( doc, QgsLayerTree::toLayer( node ), hasCustomOrder, order ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QDomElement QgsLayerTreeUtils::writeOldLegend( QDomDocument& doc, QgsLayerTreeGroup* root, bool hasCustomOrder, const QStringList& order )
|
||||||
|
{
|
||||||
|
QDomElement legendElem = doc.createElement( "legend" );
|
||||||
|
legendElem.setAttribute( "updateDrawingOrder", hasCustomOrder ? "false" : "true" );
|
||||||
|
|
||||||
|
_writeOldLegendGroupChildren( doc, legendElem, root, hasCustomOrder, order );
|
||||||
|
|
||||||
|
return legendElem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString QgsLayerTreeUtils::checkStateToXml( Qt::CheckState state )
|
QString QgsLayerTreeUtils::checkStateToXml( Qt::CheckState state )
|
||||||
@ -223,3 +296,17 @@ void QgsLayerTreeUtils::removeInvalidLayers( QgsLayerTreeGroup* group )
|
|||||||
foreach ( QgsLayerTreeNode* node, nodesToRemove )
|
foreach ( QgsLayerTreeNode* node, nodesToRemove )
|
||||||
group->removeChildNode( node );
|
group->removeChildNode( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsLayerTreeUtils::removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group )
|
||||||
|
{
|
||||||
|
foreach ( QgsLayerTreeNode* child, group->children() )
|
||||||
|
{
|
||||||
|
if ( QgsLayerTree::isGroup( child ) )
|
||||||
|
{
|
||||||
|
if ( child->customProperty( "embedded" ).toInt() )
|
||||||
|
QgsLayerTree::toGroup( child )->removeAllChildren();
|
||||||
|
else
|
||||||
|
removeChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( child ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
class QDomElement;
|
class QDomElement;
|
||||||
|
class QDomDocument;
|
||||||
class QStringList;
|
class QStringList;
|
||||||
|
|
||||||
class QgsLayerTreeGroup;
|
class QgsLayerTreeGroup;
|
||||||
@ -38,6 +39,8 @@ class CORE_EXPORT QgsLayerTreeUtils
|
|||||||
static bool readOldLegend( QgsLayerTreeGroup* root, const QDomElement& legendElem );
|
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 <legend> tag from project files from QGIS 2.2 and below
|
||||||
static bool readOldLegendLayerOrder( const QDomElement& legendElem, bool& hasCustomOrder, QStringList& order );
|
static bool readOldLegendLayerOrder( const QDomElement& legendElem, bool& hasCustomOrder, QStringList& order );
|
||||||
|
//! Return <legend> tag used in QGIS 2.2 and below
|
||||||
|
static QDomElement writeOldLegend( QDomDocument& doc, QgsLayerTreeGroup* root, bool hasCustomOrder, const QStringList& order );
|
||||||
|
|
||||||
static QString checkStateToXml( Qt::CheckState state );
|
static QString checkStateToXml( Qt::CheckState state );
|
||||||
static Qt::CheckState checkStateFromXml( QString txt );
|
static Qt::CheckState checkStateFromXml( QString txt );
|
||||||
@ -45,7 +48,9 @@ class CORE_EXPORT QgsLayerTreeUtils
|
|||||||
static bool layersEditable( const QList<QgsLayerTreeLayer*>& layerNodes );
|
static bool layersEditable( const QList<QgsLayerTreeLayer*>& layerNodes );
|
||||||
static bool layersModified( const QList<QgsLayerTreeLayer*>& layerNodes );
|
static bool layersModified( const QList<QgsLayerTreeLayer*>& layerNodes );
|
||||||
|
|
||||||
static void removeInvalidLayers(QgsLayerTreeGroup* group );
|
static void removeInvalidLayers( QgsLayerTreeGroup* group );
|
||||||
|
|
||||||
|
static void removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void addLegendGroupToTreeWidget( const QDomElement& groupElem, QgsLayerTreeGroup* parent );
|
static void addLegendGroupToTreeWidget( const QDomElement& groupElem, QgsLayerTreeGroup* parent );
|
||||||
|
@ -995,21 +995,6 @@ void QgsProject::loadEmbeddedNodes( QgsLayerTreeGroup* group )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsProject::removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group )
|
|
||||||
{
|
|
||||||
foreach ( QgsLayerTreeNode* child, group->children() )
|
|
||||||
{
|
|
||||||
if ( QgsLayerTree::isGroup( child ) )
|
|
||||||
{
|
|
||||||
if ( child->customProperty( "embedded" ).toInt() )
|
|
||||||
QgsLayerTree::toGroup( child )->removeAllChildren();
|
|
||||||
else
|
|
||||||
removeChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( child ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool QgsProject::read( QDomNode & layerNode )
|
bool QgsProject::read( QDomNode & layerNode )
|
||||||
{
|
{
|
||||||
@ -1090,7 +1075,7 @@ bool QgsProject::write()
|
|||||||
|
|
||||||
// write layer tree - make sure it is without embedded subgroups
|
// write layer tree - make sure it is without embedded subgroups
|
||||||
QgsLayerTreeNode* clonedRoot = mRootGroup->clone();
|
QgsLayerTreeNode* clonedRoot = mRootGroup->clone();
|
||||||
removeChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
|
QgsLayerTreeUtils::removeChildrenOfEmbeddedGroups( QgsLayerTree::toGroup( clonedRoot ) );
|
||||||
clonedRoot->writeXML( qgisNode );
|
clonedRoot->writeXML( qgisNode );
|
||||||
delete clonedRoot;
|
delete clonedRoot;
|
||||||
|
|
||||||
|
@ -357,8 +357,6 @@ class CORE_EXPORT QgsProject : public QObject
|
|||||||
|
|
||||||
void loadEmbeddedNodes( QgsLayerTreeGroup* group );
|
void loadEmbeddedNodes( QgsLayerTreeGroup* group );
|
||||||
|
|
||||||
void removeChildrenOfEmbeddedGroups( QgsLayerTreeGroup* group );
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
//! emitted when project is being read
|
//! emitted when project is being read
|
||||||
void readProject( const QDomDocument & );
|
void readProject( const QDomDocument & );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user