[QGIS Commit] r14526 - trunk/qgis/src/app/legend

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun Nov 7 11:08:42 EST 2010


Author: jef
Date: 2010-11-07 08:08:42 -0800 (Sun, 07 Nov 2010)
New Revision: 14526

Modified:
   trunk/qgis/src/app/legend/qgslegend.cpp
   trunk/qgis/src/app/legend/qgslegend.h
   trunk/qgis/src/app/legend/qgslegendgroup.cpp
   trunk/qgis/src/app/legend/qgslegendgroup.h
Log:
more legend refactoring to fix it

Modified: trunk/qgis/src/app/legend/qgslegend.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.cpp	2010-11-07 09:40:36 UTC (rev 14525)
+++ trunk/qgis/src/app/legend/qgslegend.cpp	2010-11-07 16:08:42 UTC (rev 14526)
@@ -52,6 +52,7 @@
   , mMousePressedFlag( false )
   , mMapCanvas( canvas )
   , mMinimumIconSize( 20, 20 )
+  , mChanging( false )
 {
   setObjectName( name );
 
@@ -145,6 +146,7 @@
   {
     mMapCanvas->setCurrentLayer( layer );
   }
+
   emit currentLayerChanged( layer );
 }
 
@@ -406,7 +408,13 @@
     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 )
@@ -587,14 +595,7 @@
 
   //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() );
@@ -1507,119 +1508,106 @@
 }
 
 
-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 )
+  QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( item );
+  QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( item );
+
+  if ( !ll && !lg )
   {
-    theLegendLayer->layer()->setLayerName( theLegendLayer->text( 0 ) );
+    return;
   }
 
-  // has the checkState changed?
-  if ( item->data( 0, Qt::UserRole ).toInt() == 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
 
-  saveCheckStates( invisibleRootItem() );
-
-  bool renderFlagState = mMapCanvas->renderFlag();
-  if ( renderFlagState )
-    mMapCanvas->setRenderFlag( false );
-
-  if ( !item->isSelected() )
+  if ( ll )
   {
-    propagateItemChange( item, 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 ) );
   }
-  else
-  {
-    foreach( QTreeWidgetItem * i, selectedItems() )
-    {
-      propagateItemChange( i, item->checkState( 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()

Modified: trunk/qgis/src/app/legend/qgslegend.h
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.h	2010-11-07 09:40:36 UTC (rev 14525)
+++ trunk/qgis/src/app/legend/qgslegend.h	2010-11-07 16:08:42 UTC (rev 14526)
@@ -189,10 +189,6 @@
     /**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*/
@@ -373,7 +369,6 @@
     /**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*/
@@ -419,8 +414,7 @@
     /**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
@@ -447,6 +441,8 @@
     void showItem( QString msg, QTreeWidgetItem *item );
 #endif
 
+    void updateGroupCheckStates( QTreeWidgetItem *item );
+
   signals:
     void itemMoved( QModelIndex oldIndex, QModelIndex newIndex );
 

Modified: trunk/qgis/src/app/legend/qgslegendgroup.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegendgroup.cpp	2010-11-07 09:40:36 UTC (rev 14525)
+++ trunk/qgis/src/app/legend/qgslegendgroup.cpp	2010-11-07 16:08:42 UTC (rev 14526)
@@ -93,7 +93,7 @@
   return result;
 }
 
-void QgsLegendGroup::updateCheckState()
+Qt::CheckState QgsLegendGroup::pendingCheckState()
 {
   QList<QgsLegendItem *> elements;
 
@@ -111,7 +111,7 @@
   }
 
   if ( elements.isEmpty() )
-    return;
+    return Qt::PartiallyChecked;
 
   Qt::CheckState theState = elements[0]->checkState( 0 );
   foreach( QgsLegendItem * li, elements )
@@ -123,8 +123,5 @@
     }
   }
 
-  if ( theState != checkState( 0 ) )
-  {
-    setCheckState( 0, theState );
-  }
+  return theState;
 }

Modified: trunk/qgis/src/app/legend/qgslegendgroup.h
===================================================================
--- trunk/qgis/src/app/legend/qgslegendgroup.h	2010-11-07 09:40:36 UTC (rev 14525)
+++ trunk/qgis/src/app/legend/qgslegendgroup.h	2010-11-07 16:08:42 UTC (rev 14526)
@@ -40,8 +40,8 @@
     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



More information about the QGIS-commit mailing list