[QGIS Commit] r11290 - in trunk/qgis/src: app app/legend core

svn_qgis at osgeo.org svn_qgis at osgeo.org
Fri Aug 7 07:58:50 EDT 2009


Author: mhugent
Date: 2009-08-07 07:58:50 -0400 (Fri, 07 Aug 2009)
New Revision: 11290

Modified:
   trunk/qgis/src/app/legend/qgslegend.cpp
   trunk/qgis/src/app/legend/qgslegend.h
   trunk/qgis/src/app/qgisapp.cpp
   trunk/qgis/src/core/qgsvectorlayer.cpp
Log:
Ask for commit/rollback of pending edits on layer remove and when leaving QGIS (fix for bug #1443). Additionally fix for a memory leak and some formating changes of the commit script

Modified: trunk/qgis/src/app/legend/qgslegend.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.cpp	2009-08-07 10:45:46 UTC (rev 11289)
+++ trunk/qgis/src/app/legend/qgslegend.cpp	2009-08-07 11:58:50 UTC (rev 11290)
@@ -76,12 +76,12 @@
            this, SLOT( writeProject( QDomDocument & ) ) );
 
   // Initialise the line indicator widget.
-  mInsertionLine = new QWidget(viewport());
+  mInsertionLine = new QWidget( viewport() );
   hideLine();
-  mInsertionLine->setAutoFillBackground(true);
+  mInsertionLine->setAutoFillBackground( true );
   QPalette pal = mInsertionLine->palette();
-  pal.setColor(mInsertionLine->backgroundRole(), Qt::blue);
-  mInsertionLine->setPalette(pal);
+  pal.setColor( mInsertionLine->backgroundRole(), Qt::blue );
+  mInsertionLine->setPalette( pal );
 
   setSortingEnabled( false );
   setDragEnabled( false );
@@ -129,6 +129,7 @@
   mPixmapHeightValues.clear();
   updateMapCanvasLayerSet();
   setIconSize( mMinimumIconSize );
+  mItemBeingMoved = 0;
 }
 
 void QgsLegend::selectAll( bool select )
@@ -256,7 +257,7 @@
 
     hideLine();
     updateLineWidget();
-    scrollToItem (item );
+    scrollToItem( item );
 
     QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>( mItemBeingMoved );
     QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>( item );
@@ -269,14 +270,14 @@
       {
         if ( yCoordAboveCenter( dest, e->y() ) ) //over center of item
         {
-          int line_y    = visualItemRect(item).top() + 1;
-          int line_left = visualItemRect(item).left();
+          int line_y    = visualItemRect( item ).top() + 1;
+          int line_left = visualItemRect( item ).left();
 
           if ( action == QgsLegendItem::REORDER ||  action == QgsLegendItem::INSERT )
           {
             QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
             mDropAction = BEFORE;
-            showLine( line_y, line_left);
+            showLine( line_y, line_left );
             setCursor( QCursor( Qt::SizeVerCursor ) );
           }
           else //no action
@@ -288,21 +289,21 @@
         }
         else // below center of item
         {
-          int line_y    = visualItemRect(item).bottom() - 2;
-          int line_left = visualItemRect(item).left();
+          int line_y    = visualItemRect( item ).bottom() - 2;
+          int line_left = visualItemRect( item ).left();
 
           if ( action == QgsLegendItem::REORDER )
           {
             QgsDebugMsg( "mouseMoveEvent::REORDER bottom half" );
             mDropAction = AFTER;
-            showLine( line_y, line_left);
+            showLine( line_y, line_left );
             setCursor( QCursor( Qt::SizeVerCursor ) );
           }
           else if ( action == QgsLegendItem::INSERT )
           {
             QgsDebugMsg( "mouseMoveEvent::INSERT" );
             mDropAction = INTO_GROUP;
-            showLine( line_y, line_left);
+            showLine( line_y, line_left );
             setCursor( QCursor( Qt::SizeVerCursor ) );
           }
           else//no action
@@ -318,7 +319,7 @@
         setCursor( QCursor( Qt::ForbiddenCursor ) );
       }
     }
-    else if (!item && e->pos().y() >= 0 && e->pos().y() < viewport()->height() &&  e->pos().x() >= 0 && e->pos().x() < viewport()->width() )
+    else if ( !item && e->pos().y() >= 0 && e->pos().y() < viewport()->height() &&  e->pos().x() >= 0 && e->pos().x() < viewport()->width() )
     {
       // Outside the listed items, but check if we are in the empty area
       // of the viewport, so we can drop after the last top level item.
@@ -330,7 +331,7 @@
       {
         QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
         mDropAction = AFTER;
-        showLine(visualItemRect( lastVisibleItem() ).bottom() + 1, 0);      
+        showLine( visualItemRect( lastVisibleItem() ).bottom() + 1, 0 );
         setCursor( QCursor( Qt::SizeVerCursor ) );
       }
       else //no action
@@ -338,7 +339,7 @@
         QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
         mDropAction = NO_ACTION;
         setCursor( QCursor( Qt::ForbiddenCursor ) );
-      } 
+      }
     }
 
     else
@@ -370,7 +371,7 @@
   QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>( destItem );
 
   // no change?
-  if ( !dest || !origin || (dest == origin) )
+  if ( !dest || !origin || ( dest == origin ) )
   {
     checkLayerOrderUpdate();
     return;
@@ -438,7 +439,7 @@
   {
     // Do the actual move here.
     QgsDebugMsg( "Other type of drag'n'drop happened!" );
-    if ( mDropAction == AFTER) //over center of item
+    if ( mDropAction == AFTER ) //over center of item
     {
       QgsDebugMsg( "Drop AFTER" );
       if ( dest->nextSibling() != origin )
@@ -702,9 +703,7 @@
       //remove the layer
       if ( *it )
       {
-        //the map layer registry emits a signal and this will remove the legend layer file
-        //from the legend and from memory by calling QgsLegend::removeLayer(QString layer key)
-        QgsMapLayerRegistry::instance()->removeMapLayer(( *it )->getLayerID() );
+        removeLayer( *it, true );
       }
     }
 
@@ -735,8 +734,61 @@
   return;
 }
 
+bool QgsLegend::removeLayer( QgsMapLayer* ml, bool askCancelOnEditable )
+{
+  if ( !ml )
+  {
+    return false;
+  }
 
+  QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( ml );
+  if ( vl )
+  {
+    //is layer editable and changed?
+    if ( vl->isEditable() && vl->isModified() )
+    {
+      QMessageBox::StandardButton commit;
+      if ( askCancelOnEditable )
+      {
+        commit = QMessageBox::information( this,
+                                           tr( "Stop editing" ),
+                                           tr( "Do you want to save the changes to layer %1?" ).arg( vl->name() ),
+                                           QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel );
+        if ( commit == QMessageBox::Cancel )
+        {
+          return false;
+        }
+      }
+      else
+      {
+        commit = QMessageBox::information( this,
+                                           tr( "Stop editing" ),
+                                           tr( "Do you want to save the changes to layer %1?" ).arg( vl->name() ),
+                                           QMessageBox::Save | QMessageBox::Discard );
+      }
 
+      if ( commit == QMessageBox::Save )
+      {
+        if ( !vl->commitChanges() )
+        {
+          return false;
+        }
+      }
+      else if ( commit == QMessageBox::Discard )
+      {
+        if ( !vl->rollBack() )
+        {
+          return false;
+        }
+      }
+    }
+  }
+  QgsMapLayerRegistry::instance()->removeMapLayer( ml->getLayerID() );
+  return true;
+}
+
+
+
 void QgsLegend::legendLayerShowProperties()
 {
   if ( !mMapCanvas || mMapCanvas->isDrawing() )
@@ -1992,12 +2044,12 @@
 
 void QgsLegend::hideLine()
 {
-  mInsertionLine->setGeometry(0, -100, 1, 1);
+  mInsertionLine->setGeometry( 0, -100, 1, 1 );
 }
 
-void QgsLegend::showLine(int y, int left)
+void QgsLegend::showLine( int y, int left )
 {
-  mInsertionLine->setGeometry(left, y, viewport()->width(), 2);
+  mInsertionLine->setGeometry( left, y, viewport()->width(), 2 );
 }
 
 void QgsLegend::updateLineWidget()
@@ -2010,9 +2062,9 @@
 {
   QTreeWidgetItem *current;
   QTreeWidgetItem *next;
-  
+
   current = topLevelItem( topLevelItemCount() - 1 );
-  while ( ( next = itemBelow( current ) ) )
+  while (( next = itemBelow( current ) ) )
   {
     current = next;
   }

Modified: trunk/qgis/src/app/legend/qgslegend.h
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.h	2009-08-07 10:45:46 UTC (rev 11289)
+++ trunk/qgis/src/app/legend/qgslegend.h	2009-08-07 11:58:50 UTC (rev 11290)
@@ -222,6 +222,13 @@
     /**Removes the current LegendLayer and all its LegendLayerFiles*/
     void legendLayerRemove();
 
+    /**Removes a layer. If the layer is editable, a dialog is shown where user can select 'save', 'discard' and optionally 'cancel'. Cancel
+      is useful if a single layer is removed whereas on closing of the whole project or application, the cancel option may not be possible
+      @param ml the maplayer to remove
+      @param askCancelOnEditable gibe cancel option in the dialog for editable (and changed) layers
+      @param return false if canceled or in case of error, true else*/
+    bool removeLayer( QgsMapLayer* ml, bool askCancelOnEditable );
+
     /**Toggle show in overview for current layer*/
     void legendLayerShowInOverview();
 
@@ -317,7 +324,7 @@
     void hideLine();
 
     /** Show the line that indicates insertion position */
-    void showLine(int y, int left);
+    void showLine( int y, int left );
 
     /** Update the widget with latest changes immediately */
     void updateLineWidget();

Modified: trunk/qgis/src/app/qgisapp.cpp
===================================================================
--- trunk/qgis/src/app/qgisapp.cpp	2009-08-07 10:45:46 UTC (rev 11289)
+++ trunk/qgis/src/app/qgisapp.cpp	2009-08-07 11:58:50 UTC (rev 11290)
@@ -3026,6 +3026,7 @@
 
   if ( saveDirty() )
   {
+    mMapCanvas->freeze( true );
     removeAllLayers();
     qApp->exit( 0 );
   }
@@ -3051,6 +3052,9 @@
   {
     if ( !saveDirty() )
     {
+      mMapCanvas->freeze( true );
+      removeAllLayers();
+      mMapCanvas->freeze( false );
       return;
     }
   }
@@ -3058,7 +3062,7 @@
   //QgsDebugMsg("erasing project");
 
   mMapCanvas->freeze( true );
-  QgsMapLayerRegistry::instance()->removeAllMapLayers();
+  removeAllLayers();
   mMapCanvas->clear();
 
   delete mComposer;
@@ -4240,6 +4244,7 @@
   QgsMergeAttributesDialog d( featureList, vl, mapCanvas() );
   if ( d.exec() == QDialog::Rejected )
   {
+    delete unionGeom;
     return;
   }
 
@@ -4287,7 +4292,7 @@
 
   vl->addFeature( newFeature, false );
 
-  vl->endEditCommand();;
+  vl->endEditCommand();
 
   if ( mapCanvas() )
   {
@@ -4652,10 +4657,6 @@
 void QgisApp::removeLayer()
 {
   QgsLegendLayerFile* currentLayerFile = mMapLegend->currentLayerFile();
-  if ( currentLayerFile && currentLayerFile->isEditing() )
-  {
-    toggleEditing( dynamic_cast<QgsVectorLayer *>( currentLayerFile->layer() ) );
-  }
   mMapLegend->legendLayerRemove();
   // notify the project we've made a change
   QgsProject::instance()->dirty( true );
@@ -4664,7 +4665,22 @@
 
 void QgisApp::removeAllLayers()
 {
-  QgsMapLayerRegistry::instance()->removeAllMapLayers();
+  //iterate through all the layers in order to ask if uncommited changes should be saved
+  if ( mMapLegend )
+  {
+    QMap<QString, QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers();
+    QMap<QString, QgsMapLayer*>::iterator layer_it = layers.begin();
+    for ( ; layer_it != layers.end(); ++layer_it )
+    {
+      mMapLegend->removeLayer( layer_it.value(), false );
+    }
+    mMapLegend->removeAll();
+  }
+  else //no legend? Remove all the layers from the registry directly in this case
+  {
+    QgsMapLayerRegistry::instance()->removeAllMapLayers();
+  }
+
   mMapCanvas->refresh();
   // notify the project we've made a change
   QgsProject::instance()->dirty( true );

Modified: trunk/qgis/src/core/qgsvectorlayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.cpp	2009-08-07 10:45:46 UTC (rev 11289)
+++ trunk/qgis/src/core/qgsvectorlayer.cpp	2009-08-07 11:58:50 UTC (rev 11290)
@@ -743,7 +743,7 @@
         double opacity = 1.0;
         if ( !mRenderer->usesTransparency() )
         {
-          opacity = ( mTransparencyLevel * 1.0) / 255.0;
+          opacity = ( mTransparencyLevel * 1.0 ) / 255.0;
         }
         mRenderer->renderFeature( rendererContext, fet, &marker, sel, opacity );
 
@@ -3094,9 +3094,9 @@
   emit editingStopped();
 
   setModified( FALSE );
-
   triggerRepaint();
 
+
   return true;
 }
 



More information about the QGIS-commit mailing list