Skip to content

Commit

Permalink
more legend refactoring to fix it
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14526 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Nov 7, 2010
1 parent 8ebd735 commit 855d370
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 103 deletions.
164 changes: 76 additions & 88 deletions src/app/legend/qgslegend.cpp
Expand Up @@ -52,6 +52,7 @@ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
, mMousePressedFlag( false )
, mMapCanvas( canvas )
, mMinimumIconSize( 20, 20 )
, mChanging( false )
{
setObjectName( name );

Expand Down Expand Up @@ -145,6 +146,7 @@ void QgsLegend::handleCurrentItemChanged( QTreeWidgetItem* current, QTreeWidgetI
{
mMapCanvas->setCurrentLayer( layer );
}

emit currentLayerChanged( layer );
}

Expand Down Expand Up @@ -406,7 +408,13 @@ void QgsLegend::updateGroupCheckStates( QTreeWidgetItem *item )
updateGroupCheckStates( item->child( i ) );
}

lg->updateCheckState();
Qt::CheckState theState = lg->pendingCheckState();
if ( theState != lg->checkState( 0 ) )
{
blockSignals( true );
lg->setCheckState( 0, theState );
blockSignals( false );
}
}

void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
Expand Down Expand Up @@ -587,14 +595,7 @@ void QgsLegend::addLayer( QgsMapLayer * layer )

//set the correct check states
blockSignals( true );
if ( llayer->isVisible() )
{
llayer->setCheckState( 0, Qt::Checked );
}
else
{
llayer->setCheckState( 0, Qt::Unchecked );
}
llayer->setCheckState( 0, llayer->isVisible() ? Qt::Checked : Qt::Unchecked );
blockSignals( false );

QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( currentItem() );
Expand Down Expand Up @@ -1507,119 +1508,106 @@ void QgsLegend::removePixmapHeightValue( int height )
}


void QgsLegend::handleItemChange( QTreeWidgetItem* item, int row )
void QgsLegend::handleItemChange( QTreeWidgetItem* item, int column )
{
if ( !item )
{
return;
}

//if the text of a QgsLegendLayer has changed, change the display names of all its maplayers
// TODO: is this still necessary?
QgsLegendLayer* theLegendLayer = dynamic_cast<QgsLegendLayer *>( item ); //item is a legend layer
if ( theLegendLayer )
{
theLegendLayer->layer()->setLayerName( theLegendLayer->text( 0 ) );
}

// has the checkState changed?
if ( item->data( 0, Qt::UserRole ).toInt() == item->checkState( 0 ) )
return;

saveCheckStates( invisibleRootItem() );
QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( item );
QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( item );

bool renderFlagState = mMapCanvas->renderFlag();
if ( renderFlagState )
mMapCanvas->setRenderFlag( false );

if ( !item->isSelected() )
if ( !ll && !lg )
{
propagateItemChange( item, item->checkState( 0 ) );
return;
}

#ifdef QGISDEBUG
if ( item->checkState( 0 ) == Qt::Checked )
showItem( "handleItemChange[checked]", item );
else if ( item->checkState( 0 ) == Qt::Unchecked )
showItem( "handleItemChange[unchecked]", item );
else if ( item->checkState( 0 ) == Qt::PartiallyChecked )
showItem( "handleItemChange[partially]", item );
else
showItem( "handleItemChange[?]", item );
#endif

if ( ll )
{
foreach( QTreeWidgetItem * i, selectedItems() )
{
propagateItemChange( i, item->checkState( 0 ) );
}
//if the text of a QgsLegendLayer has changed, change the display names of all its maplayers
// TODO: is this still necessary?
ll->layer()->setLayerName( ll->text( 0 ) );
}

// update layer set
updateMapCanvasLayerSet();
bool renderFlagState;
bool changing = mChanging;
mChanging = true;

// If it was on, turn it back on, otherwise leave it
// off, as turning it on causes a refresh.
if ( renderFlagState )
mMapCanvas->setRenderFlag( true );
}

void QgsLegend::saveCheckStates( QTreeWidgetItem *item )
{
for ( int i = 0; i < item->childCount(); i++ )
if ( !changing )
{
QTreeWidgetItem *child = item->child( i );
child->setData( 0, Qt::UserRole, child->checkState( 0 ) );
saveCheckStates( child );
}
}
renderFlagState = mMapCanvas->renderFlag();
if ( renderFlagState )
mMapCanvas->setRenderFlag( false );

void QgsLegend::propagateItemChange( QTreeWidgetItem *item, Qt::CheckState state )
{
QgsLegendGroup* lg = dynamic_cast<QgsLegendGroup *>( item ); //item is a legend group
if ( lg )
{
QList<QTreeWidgetItem *> items;
items << item;
while ( !items.isEmpty() )
if ( item->isSelected() )
{
QTreeWidgetItem *litem = items.takeFirst();

QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( litem );
if ( ll )
foreach( QTreeWidgetItem * i, selectedItems() )
{
blockSignals( true );
ll->setCheckState( 0, state );
blockSignals( false );

if ( ll->layer() )
if ( i != item )
{
ll->setVisible( lg->checkState( 0 ) == Qt::Checked );
i->setCheckState( 0, item->checkState( 0 ) );
}
}

QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( litem );
if ( lg )
{
blockSignals( true );
lg->setCheckState( 0, state );
blockSignals( false );

for ( int i = 0; i < lg->childCount(); i++ )
items << lg->child( i );
}
}
}

QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer *>( item ); //item is a legend layer
if ( ll )
{
blockSignals( true );
ll->setCheckState( 0, state );
ll->setVisible( ll->checkState( 0 ) == Qt::Checked );
}

if ( ll->layer() )
if ( lg && lg->checkState( 0 ) != Qt::PartiallyChecked )
{
Qt::CheckState theState = lg->checkState( 0 );
for ( int i = 0; i < item->childCount(); i++ )
{
ll->setVisible( state == Qt::Checked );
QTreeWidgetItem *child = item->child( i );
if ( child->checkState( 0 ) != item->checkState( 0 ) )
child->setCheckState( 0, theState );
}
}

QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup*>( ll->parent() );
while ( lg )
// propagate updates to upper groups
for (
QgsLegendGroup *plg = dynamic_cast<QgsLegendGroup *>( item->parent() );
plg;
plg = dynamic_cast<QgsLegendGroup *>( plg->parent() )
)
{
Qt::CheckState theState = plg->pendingCheckState();

if ( theState != plg->checkState( 0 ) )
{
lg->updateCheckState();
lg = dynamic_cast<QgsLegendGroup*>( lg->parent() );
blockSignals( true );
plg->setCheckState( 0, theState );
blockSignals( false );
}
}

blockSignals( false );
if ( !changing )
{
// update layer set
updateMapCanvasLayerSet();

// If it was on, turn it back on, otherwise leave it
// off, as turning it on causes a refresh.
if ( renderFlagState )
mMapCanvas->setRenderFlag( true );
}

mChanging = changing;
}

void QgsLegend::openEditor()
Expand Down
10 changes: 3 additions & 7 deletions src/app/legend/qgslegend.h
Expand Up @@ -189,10 +189,6 @@ class QgsLegend : public QTreeWidget
/**Returns a layers check state*/
Qt::CheckState layerCheckState( QgsMapLayer * layer );

void updateCheckStates( QTreeWidgetItem* item, Qt::CheckState state ) { item->setData( 0, Qt::UserRole, state ); }

void updateGroupCheckStates( QTreeWidgetItem *item );

public slots:

/*!Adds a new layer group with the maplayer to the canvas*/
Expand Down Expand Up @@ -373,7 +369,6 @@ class QgsLegend : public QTreeWidget
/**Sets all listview items to closed*/
void collapseAll();
void handleItemChange( QTreeWidgetItem* item, int row );
void propagateItemChange( QTreeWidgetItem *item, Qt::CheckState state );
/** delegates current layer to map canvas */
void handleCurrentItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* previous );
/**Calls openPersistentEditor for the current item*/
Expand Down Expand Up @@ -419,8 +414,7 @@ class QgsLegend : public QTreeWidget
/**QgsLegend does not set the icon with/height to values lower than the minimum icon size*/
QSize mMinimumIconSize;

/** save item check states */
void saveCheckStates( QTreeWidgetItem *item );
bool mChanging;

/** structure which holds pixmap which are used in legend */
class QgsLegendPixmaps
Expand All @@ -447,6 +441,8 @@ class QgsLegend : public QTreeWidget
void showItem( QString msg, QTreeWidgetItem *item );
#endif

void updateGroupCheckStates( QTreeWidgetItem *item );

signals:
void itemMoved( QModelIndex oldIndex, QModelIndex newIndex );

Expand Down
9 changes: 3 additions & 6 deletions src/app/legend/qgslegendgroup.cpp
Expand Up @@ -93,7 +93,7 @@ QList<QgsLegendLayer*> QgsLegendGroup::legendLayers( bool recurse )
return result;
}

void QgsLegendGroup::updateCheckState()
Qt::CheckState QgsLegendGroup::pendingCheckState()
{
QList<QgsLegendItem *> elements;

Expand All @@ -111,7 +111,7 @@ void QgsLegendGroup::updateCheckState()
}

if ( elements.isEmpty() )
return;
return Qt::PartiallyChecked;

Qt::CheckState theState = elements[0]->checkState( 0 );
foreach( QgsLegendItem * li, elements )
Expand All @@ -123,8 +123,5 @@ void QgsLegendGroup::updateCheckState()
}
}

if ( theState != checkState( 0 ) )
{
setCheckState( 0, theState );
}
return theState;
}
4 changes: 2 additions & 2 deletions src/app/legend/qgslegendgroup.h
Expand Up @@ -40,8 +40,8 @@ class QgsLegendGroup : public QgsLegendItem
bool insert( QgsLegendItem* theItem );
/**Returns all legend layers under this group (including those of subgroups by default)*/
QList<QgsLegendLayer*> legendLayers( bool recurse = true );
/**Goes through all the legendlayers and sets check state to checked/partially checked/unchecked*/
void updateCheckState();

Qt::CheckState pendingCheckState();
};

#endif

0 comments on commit 855d370

Please sign in to comment.