Skip to content
Permalink
Browse files
[FEATURE] allow legend independant drawing order
  • Loading branch information
jef-n committed Nov 26, 2011
1 parent 7c40bf3 commit 46bc34df8c0312cd169f7a1e10305060437d5cfc
@@ -124,6 +124,7 @@ SET(QGIS_APP_SRCS
legend/qgslegendsymbologygroup.cpp
legend/qgslegendsymbologyitem.cpp
legend/qgslegendvectorsymbologyitem.cpp
legend/qgslayerorder.cpp

ogr/qgsogrhelperfunctions.cpp
ogr/qgsopenvectorlayerdialog.cpp
@@ -238,6 +239,7 @@ SET (QGIS_APP_MOC_HDRS
legend/qgslegend.h
legend/qgsapplegendinterface.h
legend/qgslegendlayer.h
legend/qgslayerorder.h

ogr/qgsopenvectorlayerdialog.h
ogr/qgsnewogrconnection.h
@@ -129,7 +129,7 @@ void QgsLegend::showItem( QString msg, QTreeWidgetItem *item )
else
type = "item";

QgsDebugMsg( QString( "%1: %2 %3 row:%4" ).arg( msg ).arg( type ).arg( item->text( 0 ) ).arg( indexFromItem( item ).row() ) );
QgsDebugMsgLevel( QString( "%1: %2 %3 row:%4" ).arg( msg ).arg( type ).arg( item->text( 0 ) ).arg( indexFromItem( item ).row() ), 3 );
}
#else
#define showItem(msg, item)
@@ -191,6 +191,8 @@ int QgsLegend::addGroup( QString name, bool expand, int groupIndex )

void QgsLegend::removeAll()
{
QgsDebugMsg( "Entering." );

clear();
mEmbeddedGroups.clear();
mPixmapWidthValues.clear();
@@ -240,7 +242,7 @@ void QgsLegend::removeGroup( int groupIndex )

void QgsLegend::removeLayer( QString layerId )
{
QgsDebugMsg( "called." );
QgsDebugMsg( "Entering." );

for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) )
{
@@ -563,7 +565,6 @@ void QgsLegend::mouseDoubleClickEvent( QMouseEvent *e )
Q_UNUSED( e );

QSettings settings;

switch ( settings.value( "/qgis/legendDoubleClickAction", 0 ).toInt() )
{
case 0:
@@ -620,6 +621,10 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi
theMenu.addAction( QgisApp::getThemeIcon( "/mActionExpandTree.png" ), tr( "&Expand all" ), this, SLOT( expandAll() ) );
theMenu.addAction( QgisApp::getThemeIcon( "/mActionCollapseTree.png" ), tr( "&Collapse all" ), this, SLOT( collapseAll() ) );

QAction *updateDrawingOrderAction = theMenu.addAction( QgisApp::getThemeIcon( "/mUpdateDrawingOrder.png" ), tr( "&Update drawing order" ), this, SLOT( toggleDrawingOrderUpdate() ) );
updateDrawingOrderAction->setCheckable( true );
updateDrawingOrderAction->setChecked( mUpdateDrawingOrder );

theMenu.exec( position );
}

@@ -775,6 +780,7 @@ int QgsLegend::getItemPos( QTreeWidgetItem* item )

void QgsLegend::addLayer( QgsMapLayer * layer )
{
QgsDebugMsg( "Entering." );
if ( !mMapCanvas || mMapCanvas->isDrawing() )
{
return;
@@ -879,20 +885,96 @@ QList<QgsMapLayer *> QgsLegend::selectedLayers()
return layers;
}

QList<QgsLegendLayer *> QgsLegend::legendLayers()
{
if ( mUpdateDrawingOrder )
{
QList< QgsLegendLayer * > items;
QTreeWidgetItemIterator it( this );
while ( *it )
{
QgsLegendLayer *llayer = dynamic_cast<QgsLegendLayer *>( *it );
if ( llayer )
items.append( llayer );

++it;
}

return items;
}
else
{
int n = 0;
QMap< int, QgsLegendLayer * > items;
QTreeWidgetItemIterator it( this );
while ( *it )
{
QgsLegendLayer *llayer = dynamic_cast<QgsLegendLayer *>( *it );
if ( llayer )
{
QgsDebugMsgLevel( QString( "n=%1 o=%2 name=%3" ).arg( n ).arg( llayer->drawingOrder() ).arg( llayer->layer()->name() ), 3 );
items.insertMulti( llayer->drawingOrder(), llayer );
n++;
}

++it;
}

QList< QgsLegendLayer * > ls;

foreach( int o, items.uniqueKeys() )
{
QgsDebugMsgLevel( QString( "o=%1" ).arg( o ), 3 );
QList< QgsLegendLayer *> values = items.values( o );
for ( int i = values.size() - 1; i >= 0; i-- )
{
QgsDebugMsgLevel( QString( " layer=%1" ).arg( values[i]->layer()->name() ), 3 );
ls << values[i];
}
}

return ls;
}
}

QList<QgsMapLayer *> QgsLegend::layers()
{
QList< QgsMapLayer * > items;
QTreeWidgetItemIterator it( this );
while ( *it )
QList<QgsMapLayer *> ls;

foreach( QgsLegendLayer *l, legendLayers() )
{
ls << l->layer();
}

return ls;
}

QList<QgsMapCanvasLayer> QgsLegend::canvasLayers()
{
QList<QgsMapCanvasLayer> ls;

foreach( QgsLegendLayer *l, legendLayers() )
{
QgsLegendLayer *llayer = dynamic_cast<QgsLegendLayer *>( *it );
if ( llayer )
items.append( llayer->layer() );
ls << l->canvasLayer();
}

return ls;
}

void QgsLegend::setDrawingOrder( QList<QgsMapLayer *> layers )
{
QgsDebugMsg( "Entering." );

++it;
for ( int i = 0; i < layers.size(); i++ )
{
QgsLegendLayer *ll = findLegendLayer( layers[i] );
if ( !ll )
continue;
QgsDebugMsgLevel( QString( "setting order=%1 name=%2." ).arg( i ).arg( layers[i]->name() ), 3 );
ll->setDrawingOrder( i );
}

return items;
updateMapCanvasLayerSet();
}

bool QgsLegend::setCurrentLayer( QgsMapLayer *layer )
@@ -1151,6 +1233,7 @@ bool QgsLegend::writeXML( QList<QTreeWidgetItem *> items, QDomNode &node, QDomDo
// to keep it compatible with older projects
QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( item );
QgsMapLayer* layer = ll->layer();
legendlayernode.setAttribute( "drawingOrder", ll->drawingOrder() );
legendlayernode.setAttribute( "showFeatureCount", ll->showFeatureCount() );

QDomElement layerfilegroupnode = document.createElement( "filegroup" );
@@ -1319,6 +1402,7 @@ bool QgsLegend::readXML( QDomNode& legendnode )
{
clear(); //remove all items first
mEmbeddedGroups.clear();
mUpdateDrawingOrder = legendnode.toElement().attribute( "updateDrawingOrder", "true" ) == "true";
return readXML( 0, legendnode );
}

@@ -1340,6 +1424,7 @@ QgsLegendLayer* QgsLegend::readLayerFromXML( QDomElement& childelem, bool& isOpe

// create the item
QgsLegendLayer* ll = new QgsLegendLayer( theMapLayer );
ll->setDrawingOrder( childelem.attribute( "drawingOrder", "-1" ).toInt() );
ll->setShowFeatureCount( childelem.attribute( "showFeatureCount", "0" ).toInt(), false );

// load layer's visibility and 'show in overview' flag
@@ -1624,14 +1709,14 @@ void QgsLegend::insertItem( QTreeWidgetItem* move, QTreeWidgetItem* into )

void QgsLegend::moveItem( QTreeWidgetItem* move, QTreeWidgetItem* after )
{
QgsDebugMsg( QString( "Moving layer : %1 (%2)" ).arg( move->text( 0 ) ).arg( move->type() ) );
QgsDebugMsgLevel( QString( "Moving layer : %1 (%2)" ).arg( move->text( 0 ) ).arg( move->type() ), 3 );
if ( after )
{
QgsDebugMsg( QString( "after layer : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) );
QgsDebugMsgLevel( QString( "after layer : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ), 3 );
}
else
{
QgsDebugMsg( "as toplevel item" );
QgsDebugMsgLevel( "as toplevel item", 3 );
}

static_cast<QgsLegendItem*>( move )->storeAppearanceSettings();//store settings in the moved item and its childern
@@ -1678,21 +1763,8 @@ void QgsLegend::removeItem( QTreeWidgetItem* item )

void QgsLegend::updateMapCanvasLayerSet()
{
QList<QgsMapCanvasLayer> layers;

// create list of the layers
for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) )
{
QgsLegendItem *li = dynamic_cast<QgsLegendItem *>( theItem );
QgsLegendLayer *ll = qobject_cast<QgsLegendLayer *>( li );
if ( ll )
{
QgsMapCanvasLayer& lyr = ll->canvasLayer();
layers.append( lyr );
}
}

// set layers in canvas
QgsDebugMsg( "Entering." );
QList<QgsMapCanvasLayer> layers = canvasLayers();
mMapCanvas->setLayerSet( layers );
}

@@ -2114,11 +2186,11 @@ void QgsLegend::writeProject( QDomDocument & doc )
QDomNode qgisNode = nl.item( 0 ); // there should only be one, so zeroth element ok

QDomElement mapcanvasNode = doc.createElement( "legend" );
mapcanvasNode.setAttribute( "updateDrawingOrder", mUpdateDrawingOrder ? "true" : "false" );
qgisNode.appendChild( mapcanvasNode );
writeXML( mapcanvasNode, doc );
}


bool QgsLegend::checkLayerOrderUpdate()
{
QStringList layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary
@@ -2147,7 +2219,6 @@ void QgsLegend::updateLineWidget()
mInsertionLine->repaint();
}


QTreeWidgetItem * QgsLegend::lastVisibleItem()
{
QTreeWidgetItem *current;
@@ -2272,3 +2343,27 @@ bool QgsLegend::groupEmbedded( QTreeWidgetItem* item ) const

return mEmbeddedGroups.contains( gItem->text( 0 ) );
}

void QgsLegend::setUpdateDrawingOrder( bool updateDrawingOrder )
{
if ( mUpdateDrawingOrder == updateDrawingOrder )
return;

mUpdateDrawingOrder = updateDrawingOrder;

QgsProject::instance()->dirty( true );

updateMapCanvasLayerSet();

emit updateDrawingOrderChanged( mUpdateDrawingOrder );
}

bool QgsLegend::updateDrawingOrder()
{
return mUpdateDrawingOrder;
}

void QgsLegend::toggleDrawingOrderUpdate()
{
setUpdateDrawingOrder( !mUpdateDrawingOrder );
}
@@ -34,6 +34,7 @@ class QDomNode;
class QMouseEvent;
class QTreeWidgetItem;
class QgsCoordinateReferenceSystem;
class QgsMapCanvasLayer;

//Information about relationship between groups and layers
//key: group name (or null strings for single layers without groups)
@@ -111,10 +112,12 @@ class QgsLegend : public QTreeWidget
Else, an empty list is returned.*/
QList<QgsMapLayer *> selectedLayers();

/*!Returns all layers loaded in QgsMapCanvas.
/*!Returns all layers loaded in QgsMapCanvas in drawing order
Else, an empty list is returned.*/
QList<QgsMapLayer *> layers();

void setDrawingOrder( QList<QgsMapLayer *> );

/*!set the current layer
returns true if the layer exists, false otherwise*/
bool setCurrentLayer( QgsMapLayer *layer );
@@ -196,6 +199,9 @@ class QgsLegend : public QTreeWidget
/**Add group from other project file. Returns a pointer to the new group in case of success or 0 in case of error*/
QgsLegendGroup* addEmbeddedGroup( const QString& groupName, const QString& projectFilePath, QgsLegendItem* parent = 0 );

/** return canvas */
QgsMapCanvas *canvas() { return mMapCanvas; }

public slots:

/*!Adds a new layer group with the maplayer to the canvas*/
@@ -295,6 +301,12 @@ class QgsLegend : public QTreeWidget
/** Set CRS for selected layers */
void setCRSForSelectedLayers( const QgsCoordinateReferenceSystem &crs );

/** Update drawing order */
bool updateDrawingOrder();

/** Update drawing order */
void setUpdateDrawingOrder( bool updateDrawingOrder );

protected:

/*!Event handler for mouse movements.
@@ -405,6 +417,8 @@ class QgsLegend : public QTreeWidget
void expandAll();
/**Sets all listview items to closed*/
void collapseAll();
/** toogle update drawing order */
void toggleDrawingOrderUpdate();
void handleItemChange( QTreeWidgetItem* item, int row );
/** delegates current layer to map canvas */
void handleCurrentItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* previous );
@@ -417,6 +431,9 @@ class QgsLegend : public QTreeWidget
bool readXML( QgsLegendGroup *parent, const QDomNode &node );
bool writeXML( QList<QTreeWidgetItem *> items, QDomNode &node, QDomDocument &document );

QList<QgsMapCanvasLayer> canvasLayers();
QList<QgsLegendLayer *> legendLayers();

/*! Prevent the copying of QgsLegends
* @todo See if this is really required - we may want multiple map, canvas and
legend support at some stage in the future.
@@ -459,6 +476,9 @@ class QgsLegend : public QTreeWidget

bool mChanging;

/** moving the layers in the hierarchy also changes the drawing order */
bool mUpdateDrawingOrder;

/** structure which holds pixmap which are used in legend */
class QgsLegendPixmaps
{
@@ -491,7 +511,9 @@ class QgsLegend : public QTreeWidget

void zOrderChanged();

//! Emited whenever current (selected) layer changes
void updateDrawingOrderChanged( bool );

//! Emitted whenever current (selected) layer changes
// the pointer to layer can be null if no layer is selected
void currentLayerChanged( QgsMapLayer * layer );
};

0 comments on commit 46bc34d

Please sign in to comment.