Skip to content
Permalink
Browse files
Add layer tree support into QgsProject
  • Loading branch information
wonder-sk committed May 21, 2014
1 parent 1fecde4 commit de146fbac51c27437eaab4a90ff69dc843e3bc5d
@@ -3201,9 +3201,7 @@ void QgisApp::fileNew( bool thePromptToSaveFlag, bool forceBlank )
closeProject();

QgsProject* prj = QgsProject::instance();
prj->title( QString::null );
prj->setFileName( QString::null );
prj->clearProperties(); // why carry over properties from previous projects?
prj->clear();

//set the color for selections
//the default can be set in qgisoptions
@@ -8,9 +8,9 @@
QgsLayerTreeNode* QgsLayerTreeNode::readXML(QDomElement& element)
{
QgsLayerTreeNode* node = 0;
if (element.tagName() == "tree-group")
if (element.tagName() == "layer-tree-group")
node = QgsLayerTreeGroup::readXML(element);
else if (element.tagName() == "tree-layer")
else if (element.tagName() == "layer-tree-layer")
node = QgsLayerTreeLayer::readXML(element);

return node;
@@ -129,8 +129,8 @@ void QgsLayerTreeGroup::connectToChildNode(QgsLayerTreeNode* node)
if (node->nodeType() == QgsLayerTreeNode::NodeLayer)
{
// TODO: this could be handled directly by LayerTreeLayer by listening to QgsMapLayerRegistry...
QgsLayerTreeLayer* nodeLayer = static_cast<QgsLayerTreeLayer*>(node);
connect(nodeLayer->layer(), SIGNAL(destroyed()), this, SLOT(layerDestroyed()));
//QgsLayerTreeLayer* nodeLayer = static_cast<QgsLayerTreeLayer*>(node);
//connect(nodeLayer->layer(), SIGNAL(destroyed()), this, SLOT(layerDestroyed()));
}

connect(node, SIGNAL(visibilityChanged(Qt::CheckState)), this, SLOT(updateVisibilityFromChildren()));
@@ -211,7 +211,7 @@ QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer(const QString& layerId)

QgsLayerTreeGroup* QgsLayerTreeGroup::readXML(QDomElement& element)
{
if (element.tagName() != "tree-group")
if (element.tagName() != "layer-tree-group")
return 0;

QString name = element.attribute("name");
@@ -239,7 +239,7 @@ QgsLayerTreeGroup* QgsLayerTreeGroup::readXML(QDomElement& element)
void QgsLayerTreeGroup::writeXML(QDomElement& parentElement)
{
QDomDocument doc = parentElement.ownerDocument();
QDomElement elem = doc.createElement("tree-group");
QDomElement elem = doc.createElement("layer-tree-group");
elem.setAttribute("name", mName);
elem.setAttribute("expanded", mExpanded ? "1" : "0");
elem.setAttribute("checked", QgsLayerTreeUtils::checkStateToXml(mChecked));
@@ -252,6 +252,17 @@ void QgsLayerTreeGroup::writeXML(QDomElement& parentElement)
parentElement.appendChild(elem);
}

QString QgsLayerTreeGroup::dump() const
{
QString header = QString( "GROUP: %1 visible=%2 expanded=%3\n" ).arg( name() ).arg( mChecked ).arg( mExpanded );
QStringList childrenDump;
foreach (QgsLayerTreeNode* node, mChildren)
childrenDump << node->dump().split( "\n" );
for (int i = 0; i < childrenDump.count(); ++i)
childrenDump[i].prepend( " " );
return header + childrenDump.join( "\n" );
}

void QgsLayerTreeGroup::setVisible(Qt::CheckState state)
{
if (mChecked == state)
@@ -360,7 +371,7 @@ void QgsLayerTreeLayer::setVisible(bool state)

QgsLayerTreeLayer* QgsLayerTreeLayer::readXML(QDomElement& element)
{
if (element.tagName() != "tree-layer")
if (element.tagName() != "layer-tree-layer")
return 0;

QString layerID = element.attribute("id");
@@ -388,7 +399,7 @@ QgsLayerTreeLayer* QgsLayerTreeLayer::readXML(QDomElement& element)
void QgsLayerTreeLayer::writeXML(QDomElement& parentElement)
{
QDomDocument doc = parentElement.ownerDocument();
QDomElement elem = doc.createElement("tree-layer");
QDomElement elem = doc.createElement("layer-tree-layer");
elem.setAttribute("id", mLayerId);
elem.setAttribute("name", layerName());
elem.setAttribute("visible", mVisible ? "1" : "0");
@@ -399,6 +410,11 @@ void QgsLayerTreeLayer::writeXML(QDomElement& parentElement)
parentElement.appendChild(elem);
}

QString QgsLayerTreeLayer::dump() const
{
return QString( "LAYER: %1 visible=%2 expanded=%3 id=%4\n" ).arg( layerName() ).arg( mVisible ).arg( mExpanded ).arg( layerId() );
}

void QgsLayerTreeLayer::registryLayersAdded(QList<QgsMapLayer*> layers)
{
foreach (QgsMapLayer* l, layers)
@@ -30,6 +30,8 @@ class CORE_EXPORT QgsLayerTreeNode : public QObject
static QgsLayerTreeNode* readXML(QDomElement& element);
virtual void writeXML(QDomElement& parentElement) = 0;

virtual QString dump() const = 0;

bool isExpanded() const { return mExpanded; }
void setExpanded(bool expanded) { mExpanded = expanded; }

@@ -109,6 +111,8 @@ class QgsLayerTreeLayer : public QgsLayerTreeNode
static QgsLayerTreeLayer* readXML(QDomElement& element);
virtual void writeXML(QDomElement& parentElement);

virtual QString dump() const;

protected slots:
void registryLayersAdded(QList<QgsMapLayer*> layers);

@@ -148,6 +152,8 @@ class QgsLayerTreeGroup : public QgsLayerTreeNode
static QgsLayerTreeGroup* readXML(QDomElement& element);
virtual void writeXML(QDomElement& parentElement);

virtual QString dump() const;

Qt::CheckState isVisible() const { return mChecked; }
void setVisible(Qt::CheckState state);

@@ -6,6 +6,9 @@

QgsLayerTreeGroup* QgsLayerTreeUtils::readOldLegend(const QDomElement& legendElem)
{
if (legendElem.isNull())
return 0;

QDomNodeList legendChildren = legendElem.childNodes();
QgsLayerTreeGroup* root = new QgsLayerTreeGroup;

@@ -11,7 +11,7 @@ class CORE_EXPORT QgsLayerTreeUtils
{
public:

// return a new instance
// return a new instance - or null on error
static QgsLayerTreeGroup* readOldLegend(const QDomElement& legendElem);

static QString checkStateToXml(Qt::CheckState state);
@@ -22,6 +22,8 @@

#include "qgsdatasourceuri.h"
#include "qgsexception.h"
#include "qgslayertreenode.h"
#include "qgslayertreeutils.h"
#include "qgslogger.h"
#include "qgsmaplayerregistry.h"
#include "qgspluginlayer.h"
@@ -304,7 +306,7 @@ struct QgsProject::Imp
bool dirty;

Imp()
: title( "" )
: title( )
, dirty( false )
{ // top property node is the root
// "properties" that contains all plug-in
@@ -318,14 +320,10 @@ struct QgsProject::Imp
{
//QgsDebugMsg( "Clearing project properties Impl->clear();" );

file.setFileName( QString() );
properties_.clearKeys();
title = "";

// reset some default project properties
// XXX THESE SHOULD BE MOVED TO STATUSBAR RELATED SOURCE
QgsProject::instance()->writeEntry( "PositionPrecision", "/Automatic", true );
QgsProject::instance()->writeEntry( "PositionPrecision", "/DecimalPlaces", 2 );
QgsProject::instance()->writeEntry( "Paths", "/Absolute", false );
title.clear();
dirty = false;
}

}; // struct QgsProject::Imp
@@ -336,15 +334,10 @@ QgsProject::QgsProject()
: imp_( new QgsProject::Imp )
, mBadLayerHandler( new QgsProjectBadLayerDefaultHandler() )
, mRelationManager( new QgsRelationManager( this ) )
, mRootGroup( 0 )
{
// Set some default project properties
// XXX THESE SHOULD BE MOVED TO STATUSBAR RELATED SOURCE
writeEntry( "PositionPrecision", "/Automatic", true );
writeEntry( "PositionPrecision", "/DecimalPlaces", 2 );
writeEntry( "Paths", "/Absolute", false );
// XXX writeEntry() makes the project dirty, but it doesn't make sense
// for a new project to be dirty, so let's clean it up
dirty( false );
clear();

} // QgsProject ctor


@@ -353,6 +346,7 @@ QgsProject::~QgsProject()
{
delete mBadLayerHandler;
delete mRelationManager;
delete mRootGroup;

// note that std::auto_ptr automatically deletes imp_ when it's destroyed
} // QgsProject dtor
@@ -375,6 +369,11 @@ void QgsProject::title( QString const &title )
dirty( true );
} // void QgsProject::title

void QgsProject::setTitle( const QString& t )
{
title( t );
}


QString const & QgsProject::title() const
{
@@ -393,6 +392,11 @@ void QgsProject::dirty( bool b )
imp_->dirty = b;
} // bool QgsProject::isDirty()

void QgsProject::setDirty(bool b)
{
dirty( b );
}



void QgsProject::setFileName( QString const &name )
@@ -409,6 +413,24 @@ QString QgsProject::fileName() const
return imp_->file.fileName();
} // QString QgsProject::fileName() const

void QgsProject::clear()
{
imp_->clear();
mEmbeddedLayers.clear();
mRelationManager->clear();

delete mRootGroup;
mRootGroup = new QgsLayerTreeGroup;

// reset some default project properties
// XXX THESE SHOULD BE MOVED TO STATUSBAR RELATED SOURCE
writeEntry( "PositionPrecision", "/Automatic", true );
writeEntry( "PositionPrecision", "/DecimalPlaces", 2 );
writeEntry( "Paths", "/Absolute", false );

setDirty( false );
}



/// basically a debugging tool to dump property list values
@@ -858,13 +880,11 @@ bool QgsProject::read()

}

// before we start loading everything, let's clear out the current set of
// properties first so that we don't have the properties from the previous
// project still hanging around
// start new project, just keep the file name

imp_->clear();
mEmbeddedLayers.clear();
mRelationManager->clear();
QString fileName = imp_->file.fileName();
clear();
imp_->file.setFileName(fileName);

// now get any properties
_getProperties( *doc, imp_->properties_ );
@@ -873,12 +893,28 @@ bool QgsProject::read()

dump_( imp_->properties_ );


// restore the canvas' area of interest

// now get project title
_getTitle( *doc, imp_->title );

// read the layer tree from project file

QgsLayerTreeGroup* newRoot = 0;
QDomElement layerTreeElem = doc->documentElement().firstChildElement( "layer-tree-group" );
if ( !layerTreeElem.isNull() )
{
newRoot = QgsLayerTreeGroup::readXML( layerTreeElem );
}
else
{
newRoot = QgsLayerTreeUtils::readOldLegend( doc->documentElement().firstChildElement( "legend" ) );
}

if ( newRoot )
{
delete mRootGroup;
mRootGroup = newRoot;
QgsDebugMsg( "Loaded layer tree:\n " + mRootGroup->dump() );
}

// get the map layers
QPair< bool, QList<QDomNode> > getMapLayersResults = _getMapLayers( *doc );
@@ -992,6 +1028,9 @@ bool QgsProject::write()
QDomText titleText = doc->createTextNode( title() ); // XXX why have title TWICE?
titleNode.appendChild( titleText );

// write layer tree
mRootGroup->writeXML( qgisNode );

// let map canvas and legend write their information
emit writeProject( *doc );

@@ -1093,9 +1132,7 @@ bool QgsProject::write()

void QgsProject::clearProperties()
{
//QgsDebugMsg("entered.");

imp_->clear();
clear();

dirty( true );
} // QgsProject::clearProperties()
@@ -1830,3 +1867,8 @@ QgsRelationManager* QgsProject::relationManager() const
{
return mRelationManager;
}

QgsLayerTreeGroup* QgsProject::layerTreeRoot() const
{
return mRootGroup;
}

0 comments on commit de146fb

Please sign in to comment.