Skip to content
Permalink
Browse files

Ask for commit/rollback of pending edits on layer remove and when lea…

…ving QGIS (fix for bug #1443). Additionally fix for a memory leak and some formating changes of the commit script

git-svn-id: http://svn.osgeo.org/qgis/trunk@11290 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent
mhugent committed Aug 7, 2009
1 parent ca4c98e commit 2c9085c84618fc7627fc0bde8a2c11bd84e3d83d
Showing with 110 additions and 35 deletions.
  1. +77 −25 src/app/legend/qgslegend.cpp
  2. +8 −1 src/app/legend/qgslegend.h
  3. +23 −7 src/app/qgisapp.cpp
  4. +2 −2 src/core/qgsvectorlayer.cpp
@@ -76,12 +76,12 @@ QgsLegend::QgsLegend( QWidget * parent, const char *name )
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 @@ void QgsLegend::removeAll()
mPixmapHeightValues.clear();
updateMapCanvasLayerSet();
setIconSize( mMinimumIconSize );
mItemBeingMoved = 0;
}

void QgsLegend::selectAll( bool select )
@@ -256,7 +257,7 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )

hideLine();
updateLineWidget();
scrollToItem (item );
scrollToItem( item );

QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>( mItemBeingMoved );
QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>( item );
@@ -269,14 +270,14 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
{
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 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
}
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 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
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,15 +331,15 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
{
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
{
QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
mDropAction = NO_ACTION;
setCursor( QCursor( Qt::ForbiddenCursor ) );
}
}
}

else
@@ -370,7 +371,7 @@ void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>( destItem );

// no change?
if ( !dest || !origin || (dest == origin) )
if ( !dest || !origin || ( dest == origin ) )
{
checkLayerOrderUpdate();
return;
@@ -438,7 +439,7 @@ void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
{
// 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 @@ void QgsLegend::legendLayerRemove()
//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,6 +734,59 @@ void QgsLegend::legendLayerRemove()
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()
@@ -1992,12 +2044,12 @@ bool QgsLegend::checkLayerOrderUpdate()

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 * QgsLegend::lastVisibleItem()
{
QTreeWidgetItem *current;
QTreeWidgetItem *next;

current = topLevelItem( topLevelItemCount() - 1 );
while ( ( next = itemBelow( current ) ) )
while (( next = itemBelow( current ) ) )
{
current = next;
}
@@ -222,6 +222,13 @@ class QgsLegend : public QTreeWidget
/**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 @@ class QgsLegend : public QTreeWidget
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();
@@ -3026,6 +3026,7 @@ void QgisApp::fileExit()

if ( saveDirty() )
{
mMapCanvas->freeze( true );
removeAllLayers();
qApp->exit( 0 );
}
@@ -3051,14 +3052,17 @@ void QgisApp::fileNew( bool thePromptToSaveFlag )
{
if ( !saveDirty() )
{
mMapCanvas->freeze( true );
removeAllLayers();
mMapCanvas->freeze( false );
return;
}
}

//QgsDebugMsg("erasing project");

mMapCanvas->freeze( true );
QgsMapLayerRegistry::instance()->removeAllMapLayers();
removeAllLayers();
mMapCanvas->clear();

delete mComposer;
@@ -4240,6 +4244,7 @@ void QgisApp::mergeSelectedFeatures()
QgsMergeAttributesDialog d( featureList, vl, mapCanvas() );
if ( d.exec() == QDialog::Rejected )
{
delete unionGeom;
return;
}

@@ -4287,7 +4292,7 @@ void QgisApp::mergeSelectedFeatures()

vl->addFeature( newFeature, false );

vl->endEditCommand();;
vl->endEditCommand();

if ( mapCanvas() )
{
@@ -4652,10 +4657,6 @@ void QgisApp::isInOverview()
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::removeLayer()

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 );
@@ -743,7 +743,7 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
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 @@ bool QgsVectorLayer::rollBack()
emit editingStopped();

setModified( FALSE );

triggerRepaint();


return true;
}

0 comments on commit 2c9085c

Please sign in to comment.
You can’t perform that action at this time.