18 changes: 18 additions & 0 deletions src/app/legend/qgslegend.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ class QgsMapCanvasLayer;
//value: containter with layer ids contained in the group
typedef QPair< QString, QList<QString> > GroupLayerInfo;

struct DrawingOrderInfo
{
QString name;
QString id;
bool checked;
bool embeddedGroup;
};

/**
\class QgsLegend
\brief A Legend treeview for QGIS
Expand Down Expand Up @@ -120,8 +128,15 @@ class QgsLegend : public QTreeWidget
//!Return all layers in drawing order
QList<QgsLegendLayer *> legendLayers();

//!Return info about layers and embedded groups in drawing order
QList<DrawingOrderInfo> drawingOrder();

QStringList drawingOrderLayers();

void setDrawingOrder( QList<QgsMapLayer *> );

void setDrawingOrder( const QList<DrawingOrderInfo>& order );

/*!set the current layer
returns true if the layer exists, false otherwise*/
bool setCurrentLayer( QgsMapLayer *layer );
Expand Down Expand Up @@ -212,6 +227,9 @@ class QgsLegend : public QTreeWidget
/**Returns the legend layer to which a map layer belongs to*/
QgsLegendLayer* findLegendLayer( const QgsMapLayer *layer );

/**Returns legend group by group name and project path (empty for not-embedded groups)*/
QgsLegendGroup* findLegendGroup( const QString& name, const QString& projectPath = QString() );

public slots:

/*!Adds a new layer group with the maplayers to the canvas*/
Expand Down
6 changes: 6 additions & 0 deletions src/app/legend/qgslegendgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ QgsLegendGroup::QgsLegendGroup( QTreeWidgetItem * theItem, QString theName )
setCheckState( 0, Qt::Checked );
QIcon myIcon = QgsApplication::getThemeIcon( "/mActionFolder.png" );
setIcon( 0, myIcon );
mEmbedded = false;
mDrawingOrder = -1;
}
QgsLegendGroup::QgsLegendGroup( QTreeWidget* theListView, QString theString )
: QgsLegendItem( theListView, theString )
Expand All @@ -36,6 +38,8 @@ QgsLegendGroup::QgsLegendGroup( QTreeWidget* theListView, QString theString )
setCheckState( 0, Qt::Checked );
QIcon myIcon = QgsApplication::getThemeIcon( "/mActionFolder.png" );
setIcon( 0, myIcon );
mEmbedded = false;
mDrawingOrder = -1;
}

QgsLegendGroup::QgsLegendGroup( QString name ): QgsLegendItem()
Expand All @@ -46,6 +50,8 @@ QgsLegendGroup::QgsLegendGroup( QString name ): QgsLegendItem()
QIcon myIcon = QgsApplication::getThemeIcon( + "/mActionFolder.png" );
setText( 0, name );
setIcon( 0, myIcon );
mEmbedded = false;
mDrawingOrder = -1;
}

QgsLegendGroup::~QgsLegendGroup()
Expand Down
16 changes: 16 additions & 0 deletions src/app/legend/qgslegendgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ class QgsLegendGroup : public QgsLegendItem
QList<QgsLegendLayer*> legendLayers( bool recurse = true );

Qt::CheckState pendingCheckState();

bool isEmbedded() const { return mEmbedded; }
void setEmbedded( bool b ) { mEmbedded = b; }

QString projectPath() const { return mProjectPath; }
void setProjectPath( const QString& path ) { mProjectPath = path; }

int drawingOrder() const { return mDrawingOrder; }
void setDrawingOrder( int i ) { mDrawingOrder = i; }

private:
bool mEmbedded;
/**Path to project from which the group is embedded. Empty for not-embedded groups*/
QString mProjectPath;
int mDrawingOrder;

};

#endif
129 changes: 100 additions & 29 deletions src/mapserver/qgsprojectparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2289,58 +2289,116 @@ QgsRectangle QgsProjectParser::layerBoundingBoxInProjectCRS( const QDomElement&
return BBox;
}

void QgsProjectParser::addDrawingOrder( QDomElement& parentElem, QDomDocument& doc ) const
void QgsProjectParser::addDrawingOrder( QDomElement elem, bool useDrawingOrder, QMap<int, QString>& orderedLayerList, int& nEmbeddedGroupLayers,
bool embedded, int embeddedOrder ) const
{
if ( !mXMLDoc )
if ( elem.isNull() )
{
return;
}

//find legend section
QDomElement legendElement = mXMLDoc->documentElement().firstChildElement( "legend" );
if ( legendElement.isNull() )
if ( elem.tagName() == "legendlayer" )
{
return;
}

QStringList layerList;
if ( useDrawingOrder || embeddedOrder != -1 )
{
int order = -1;
if ( embedded )
{
order = embeddedOrder;
}
else
{
order = drawingOrder( elem );
}
orderedLayerList.insertMulti( order + nEmbeddedGroupLayers, elem.attribute( "name" ) );
}
else
{
orderedLayerList.insertMulti( orderedLayerList.size(), elem.attribute( "name" ) );
}

bool useDrawingOrder = ( legendElement.attribute( "updateDrawingOrder" ) == "false" );
QDomNodeList layerNodeList = legendElement.elementsByTagName( "legendlayer" );
if ( !useDrawingOrder ) //bottom to top
{
for ( int i = 0; i < layerNodeList.size(); ++i )
if ( embedded )
{
layerList.prepend( layerNodeList.at( i ).toElement().attribute( "name" ) );
++nEmbeddedGroupLayers;
}
}
else
else if ( elem.tagName() == "legendgroup" )
{
QMap<int, QString> orderedLayerNames;
for ( int i = 0; i < layerNodeList.size(); ++i )
//embedded vs. not embedded
if ( elem.attribute( "embedded" ) == "1" && !embedded )
{
QString layerName = layerNodeList.at( i ).toElement().attribute( "name" );
int order = layerNodeList.at( i ).toElement().attribute( "drawingOrder" ).toInt();
if ( order == -1 )
//load layers / elements from project file
QString project = convertToAbsolutePath( elem.attribute( "project" ) );
QString embeddedGroupName = elem.attribute( "name" );
int embedDrawingOrder = elem.attribute( "drawingOrder", "-1" ).toInt();
QgsProjectParser* p = dynamic_cast<QgsProjectParser*>( QgsConfigCache::instance()->searchConfiguration( project ) );
if ( p )
{
layerList.prepend( layerName );
QList<QDomElement> embeddedGroupElements = p->mLegendGroupElements;
foreach ( const QDomElement &groupElem, embeddedGroupElements )
{
if ( groupElem.attribute( "name" ) == embeddedGroupName )
{
addDrawingOrder( groupElem, false, orderedLayerList, nEmbeddedGroupLayers, true, embedDrawingOrder );
break;
}
}
}
else
}
else
{
QDomNodeList childList = elem.childNodes();
QDomElement childElem;
for ( int i = 0; i < childList.size(); ++i )
{
orderedLayerNames.insert( order, layerName );
addDrawingOrder( childList.at( i ).toElement(), useDrawingOrder, orderedLayerList, nEmbeddedGroupLayers,
embedded, embeddedOrder );
}
}
}
}

QMap<int, QString>::const_iterator orderIt = orderedLayerNames.constBegin();
for ( ; orderIt != orderedLayerNames.constEnd(); ++orderIt )
{
layerList.prepend( *orderIt );
}
void QgsProjectParser::addDrawingOrder( QDomElement& parentElem, QDomDocument& doc ) const
{

return; //soon...

#if 0
if ( !mXMLDoc )
{
return;
}

//find legend section
QDomElement legendElement = mXMLDoc->documentElement().firstChildElement( "legend" );
if ( legendElement.isNull() )
{
return;
}

bool useDrawingOrder = ( legendElement.attribute( "updateDrawingOrder" ) == "false" );
int nEmbeddedGroupLayers = 0;
QMap<int, QString> orderedLayerNames;

QDomNodeList legendChildren = legendElement.childNodes();
QDomElement childElem;
for ( int i = 0; i < legendChildren.size(); ++i )
{
addDrawingOrder( legendChildren.at( i ).toElement(), useDrawingOrder, orderedLayerNames, nEmbeddedGroupLayers, false );
}

QStringList layerList;
QMap<int, QString>::const_iterator nameIt = orderedLayerNames.constBegin();
for ( ; nameIt != orderedLayerNames.constEnd(); ++nameIt )
{
layerList.prepend( nameIt.value() );
}

QDomElement layerDrawingOrderElem = doc.createElement( "LayerDrawingOrder" );
QDomText drawingOrderText = doc.createTextNode( layerList.join( "," ) );
layerDrawingOrderElem.appendChild( drawingOrderText );
parentElem.appendChild( layerDrawingOrderElem );
#endif //0
}

void QgsProjectParser::projectLayerMap( QMap<QString, QgsMapLayer*>& layerMap ) const
Expand Down Expand Up @@ -2689,3 +2747,16 @@ void QgsProjectParser::drawAnnotationRectangle( QPainter* p, const QDomElement&

p->drawRect( QRectF( xPos, yPos, itemWidth, itemHeight ) );
}

int QgsProjectParser::drawingOrder( const QDomElement& elem )
{
QDomElement e = elem;
while ( !e.isNull() )
{
if ( e.hasAttribute( "drawingOrder" ) )
{
return e.attribute( "drawingOrder" ).toInt();
}
e = e.parentNode().toElement();
}
}
6 changes: 6 additions & 0 deletions src/mapserver/qgsprojectparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ class QgsProjectParser: public QgsConfigParser
void setMaxWidthHeight();
/**Reads layer drawing order from the legend section of the project file and appends it to the parent elemen (usually the <Capability> element)*/
void addDrawingOrder( QDomElement& parentElem, QDomDocument& doc ) const;
/**Adds drawing order info from layer element or group element (recursive)*/
void addDrawingOrder( QDomElement elem, bool useDrawingOrder, QMap<int, QString>& orderedLayerList, int& nEmbeddedGroupLayers,
bool embedded = false, int embeddedOrder = -1 ) const;
/**Returns project layers by id*/
void projectLayerMap( QMap<QString, QgsMapLayer*>& layerMap ) const;

Expand Down Expand Up @@ -244,6 +247,9 @@ class QgsProjectParser: public QgsConfigParser
@param itemWidth item width in pixels in the QGIS project (screen pixels)
@param itemHeight item height in pixels in the QGIS project (screen pixels)*/
static void drawAnnotationRectangle( QPainter* p, const QDomElement& elem, double scaleFactor, double xPos, double yPos, int itemWidth, int itemHeight );

/**Returns the drawing order attribute of the element or of one parent. Returns -1 if the element and all the parents don't have drawing order attribute*/
static int drawingOrder( const QDomElement& elem );
};

#endif // QGSPROJECTPARSER_H