Skip to content

Commit

Permalink
Implement embedded group aware drawing order mechanism (load/save to …
Browse files Browse the repository at this point in the history
…xm does not yet work)
  • Loading branch information
mhugent committed Nov 19, 2012
1 parent 0ddc034 commit 60c9fbf
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 9 deletions.
29 changes: 20 additions & 9 deletions src/app/legend/qgslayerorder.cpp
Expand Up @@ -85,13 +85,14 @@ void QgsLayerOrder::refreshLayerList()
{
clear();

foreach ( QgsLegendLayer *layer, mLegend->legendLayers() )
QList<DrawingOrderInfo> drawingOrderList = mLegend->drawingOrder();
QList<DrawingOrderInfo>::const_iterator it = drawingOrderList.constBegin();
for ( ; it != drawingOrderList.constEnd(); ++it )
{
QListWidgetItem *item = new QListWidgetItem( layer->layer()->name() );
item->setData( 1, QString::number( layer->drawingOrder() ) );
item->setData( Qt::UserRole, qVariantFromValue( qobject_cast<QObject*>( layer->layer() ) ) );
item->setCheckState( layer->isVisible() ? Qt::Checked : Qt::Unchecked );
QgsDebugMsg( QString( "add item=%1 at %2" ).arg( item ? item->text() : "(null item)" ).arg( count() ) );
QListWidgetItem *item = new QListWidgetItem( it->name );
item->setCheckState( it->checked ? Qt::Checked : Qt::Unchecked );
item->setData( Qt::UserRole, it->id );
item->setData( Qt::UserRole + 1, it->embeddedGroup );
addItem( item );
}
}
Expand Down Expand Up @@ -261,14 +262,24 @@ void QgsLayerOrder::updateLayerOrder()
if ( !isEnabled() )
return;

QList<QgsMapLayer *> layers;
QList<DrawingOrderInfo> drawingOrder;

for ( int i = 0; i < count(); i++ )
{
layers << qobject_cast<QgsMapLayer *>( item( i )->data( Qt::UserRole ).value<QObject*>() );
QListWidgetItem* listItem = item( i );
if ( !listItem )
{
continue;
}
DrawingOrderInfo info;
info.name = listItem->text();
info.id = listItem->data( Qt::UserRole ).toString();
info.checked = listItem->checkState() == Qt::Checked;
info.embeddedGroup = listItem->data( Qt::UserRole + 1 ).toBool();
drawingOrder.push_back( info );
}

mLegend->setDrawingOrder( layers );
mLegend->setDrawingOrder( drawingOrder );
}

void QgsLayerOrder::hideLine()
Expand Down
130 changes: 130 additions & 0 deletions src/app/legend/qgslegend.cpp
Expand Up @@ -841,6 +841,9 @@ QgsLegendGroup* QgsLegend::addEmbeddedGroup( const QString& groupName, const QSt
group = new QgsLegendGroup( this, groupName );
}

group->setEmbedded( true );
group->setProjectPath( projectFilePath );

QFont groupFont;
groupFont.setItalic( true );
group->setFont( 0, groupFont );
Expand Down Expand Up @@ -1146,6 +1149,68 @@ QList<QgsLegendLayer *> QgsLegend::legendLayers()
}
}

QList<DrawingOrderInfo> QgsLegend::drawingOrder()
{
QMap<int, DrawingOrderInfo> drawingOrder;
QSet<QgsLegendLayer*> embeddedGroupChildren;
int nEntries = 0;

QTreeWidgetItemIterator it( this );
while ( *it )
{
QgsLegendLayer* llayer = dynamic_cast<QgsLegendLayer *>( *it );
QgsLegendGroup* lgroup = dynamic_cast<QgsLegendGroup *>( *it );
if ( llayer )
{
if ( !embeddedGroupChildren.contains( llayer ) )
{
DrawingOrderInfo dInfo;
dInfo.name = llayer->layerName();
dInfo.id = llayer->layer()->id();
dInfo.checked = ( llayer->checkState( 0 ) == Qt::Checked );
dInfo.embeddedGroup = false;
if ( mUpdateDrawingOrder )
{
drawingOrder.insertMulti( nEntries, dInfo );
}
else
{
drawingOrder.insertMulti( llayer->drawingOrder(), dInfo );
}
++nEntries;
}
}
else if ( lgroup )
{
if ( lgroup->isEmbedded() )
{
QList<QgsLegendLayer*> groupLayers = lgroup->legendLayers();
QList<QgsLegendLayer*>::const_iterator groupLayerIt = groupLayers.constBegin();
for ( ; groupLayerIt != groupLayers.constEnd(); ++groupLayerIt )
{
embeddedGroupChildren.insert( *groupLayerIt );
}
DrawingOrderInfo dInfo;
dInfo.name = lgroup->text( 0 );
dInfo.id = lgroup->projectPath();
dInfo.checked = ( lgroup->checkState( 0 ) == Qt::Checked );
dInfo.embeddedGroup = true;
if ( mUpdateDrawingOrder )
{
drawingOrder.insertMulti( nEntries, dInfo );
}
else
{
drawingOrder.insertMulti( lgroup->drawingOrder(), dInfo );
}
++nEntries;
}
}
++it;
}
return drawingOrder.values();
}

QList<QgsMapLayer *> QgsLegend::layers()
{
QList<QgsMapLayer *> ls;
Expand Down Expand Up @@ -1186,6 +1251,45 @@ void QgsLegend::setDrawingOrder( QList<QgsMapLayer *> layers )
updateMapCanvasLayerSet();
}

void QgsLegend::setDrawingOrder( const QList<DrawingOrderInfo>& order )
{
QList<QgsMapCanvasLayer> layers;

QList<DrawingOrderInfo>::const_iterator orderIt = order.constBegin();
int i = 0;
for ( ; orderIt != order.constEnd(); ++orderIt )
{
if ( orderIt->embeddedGroup )
{
//find group
QgsLegendGroup* group = findLegendGroup( orderIt->name, orderIt->id );
if ( group )
{
group->setDrawingOrder( i );
QList<QgsLegendLayer*> groupLayers = group->legendLayers();
QList<QgsLegendLayer*>::iterator groupIt = groupLayers.begin();
for ( ; groupIt != groupLayers.end(); ++groupIt )
{
( *groupIt )->setDrawingOrder( i );
layers.push_back(( *groupIt )->canvasLayer() );
++i;
}
}
}
else
{
QgsLegendLayer *ll = findLegendLayer( orderIt->id );
if ( ll )
{
ll->setDrawingOrder( i );
layers.push_back( ll->canvasLayer() );
++i;
}
}
}
mMapCanvas->setLayerSet( layers );
}

bool QgsLegend::setCurrentLayer( QgsMapLayer *layer )
{
QgsLegendLayer *ll = findLegendLayer( layer );
Expand Down Expand Up @@ -1405,6 +1509,11 @@ bool QgsLegend::writeXML( QList<QTreeWidgetItem *> items, QDomNode &node, QDomDo
{
legendgroupnode.setAttribute( "embedded", 1 );
legendgroupnode.setAttribute( "project", QgsProject::instance()->writePath( embedIt.value() ) );
QgsLegendGroup* group = dynamic_cast<QgsLegendGroup*>( item );
if ( group )
{
legendgroupnode.setAttribute( "drawingOrder", group->drawingOrder() );
}
}
else
{
Expand Down Expand Up @@ -1531,6 +1640,10 @@ bool QgsLegend::readXML( QgsLegendGroup *parent, const QDomNode &node )
if ( childelem.attribute( "embedded" ) == "1" )
{
theGroup = addEmbeddedGroup( name, QgsProject::instance()->readPath( childelem.attribute( "project" ) ) );
if ( childelem.hasAttribute( "drawingOrder" ) )
{
theGroup->setDrawingOrder( childelem.attribute( "drawingOrder" ).toInt() );
}
updateGroupCheckStates( theGroup );
}
else
Expand Down Expand Up @@ -1742,6 +1855,23 @@ QgsLegendLayer* QgsLegend::findLegendLayer( const QgsMapLayer *layer )
return 0;
}

QgsLegendGroup* QgsLegend::findLegendGroup( const QString& name, const QString& projectPath )
{
QgsLegendGroup* group = 0;
for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) )
{
group = dynamic_cast<QgsLegendGroup*>( theItem );
if ( group )
{
if ( group->text( 0 ) == name && group->projectPath() == projectPath )
{
return group;
}
}
}
return 0;
}


void QgsLegend::adjustIconSize()
{
Expand Down
18 changes: 18 additions & 0 deletions src/app/legend/qgslegend.h
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
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
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

0 comments on commit 60c9fbf

Please sign in to comment.