Index: /trunk/qgis/python/core/symbology-ng-core.sip =================================================================== --- qgis-1.4.0/python/core/symbology-ng-core.sip (revision 13416) +++ /trunk/qgis/python/core/symbology-ng-core.sip (revision 13501) @@ -490,6 +490,5 @@ void setRenderHints( int hints ); - // Colour used for selections - + // Color used for selections static QColor selectionColor(); Index: /trunk/qgis/src/app/legend/qgslegendlayer.cpp =================================================================== --- qgis-1.4.0/src/app/legend/qgslegendlayer.cpp (revision 13460) +++ /trunk/qgis/src/app/legend/qgslegendlayer.cpp (revision 13501) @@ -34,8 +34,4 @@ #include "qgsvectorlayer.h" #include "qgsvectordataprovider.h" -#include "qgsvectorfilewriter.h" -#include "qgsgenericprojectionselector.h" -#include "qgsattributetabledialog.h" -#include "ogr/qgsvectorlayersaveasdialog.h" #include "qgsrendererv2.h" @@ -172,4 +168,6 @@ rasterLayerSymbology( rlayer ); // get and change symbology } + + updateIcon(); } @@ -303,6 +301,4 @@ changeSymbologySettings( layer, itemList ); - - updateIcon(); } @@ -381,8 +377,8 @@ } -void QgsLegendLayer::addToPopupMenu( QMenu& theMenu, QAction* toggleEditingAction ) -{ - - QgsMapLayer* lyr = layer(); +void QgsLegendLayer::addToPopupMenu( QMenu& theMenu ) +{ + QgsMapLayer *lyr = layer(); + QAction *toggleEditingAction = QgisApp::instance()->actionToggleEditing(); // zoom to layer extent @@ -402,6 +398,5 @@ // remove from canvas - theMenu.addAction( QgisApp::getThemeIcon( "/mActionRemove.png" ), - tr( "&Remove" ), legend(), SLOT( removeCurrentLayer() ) ); + theMenu.addAction( QgisApp::getThemeIcon( "/mActionRemove.png" ), tr( "&Remove" ), QgisApp::instance(), SLOT( removeLayer() ) ); theMenu.addSeparator(); @@ -412,5 +407,6 @@ // attribute table - theMenu.addAction( tr( "&Open attribute table" ), this, SLOT( table() ) ); + theMenu.addAction( tr( "&Open attribute table" ), + QgisApp::instance(), SLOT( attributeTable() ) ); // allow editing @@ -426,12 +422,14 @@ // save as vector file - theMenu.addAction( tr( "Save as..." ), this, SLOT( saveAsVectorFile() ) ); + theMenu.addAction( tr( "Save as..." ), QgisApp::instance(), SLOT( saveAsVectorFile() ) ); // save selection as vector file - QAction* saveSelectionAsAction = theMenu.addAction( tr( "Save selection as..." ), this, SLOT( saveSelectionAsVectorFile() ) ); + QAction* saveSelectionAsAction = theMenu.addAction( tr( "Save selection as..." ), QgisApp::instance(), SLOT( saveSelectionAsVectorFile() ) ); if ( vlayer->selectedFeatureCount() == 0 ) { saveSelectionAsAction->setEnabled( false ); } + + theMenu.addAction( tr( "&Subset" ), QgisApp::instance(), SLOT( layerSubsetString() ) ); theMenu.addSeparator(); @@ -440,24 +438,5 @@ // properties goes on bottom of menu for consistency with normal ui standards // e.g. kde stuff - theMenu.addAction( tr( "&Properties" ), legend(), SLOT( legendLayerShowProperties() ) ); - -} - -void QgsLegendLayer::table() -{ - QgsVectorLayer * myLayer = qobject_cast( mLyr.layer() ); - QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( myLayer ); - mDialog->show(); - // the dialog will be deleted by itself on close -} - -void QgsLegendLayer::saveAsVectorFile() -{ - saveAsVectorFileGeneral( false ); -} - -void QgsLegendLayer::saveSelectionAsVectorFile() -{ - saveAsVectorFileGeneral( true ); + theMenu.addAction( tr( "&Properties" ), QgisApp::instance(), SLOT( layerProperties() ) ); } @@ -492,82 +471,4 @@ legend()->updateMapCanvasLayerSet(); legend()->updateOverview(); -} - -void QgsLegendLayer::saveAsVectorFileGeneral( bool saveOnlySelection ) -{ - QgsCoordinateReferenceSystem destCRS; - - if ( mLyr.layer()->type() != QgsMapLayer::VectorLayer ) - return; - - QgsVectorLayer* vlayer = qobject_cast( mLyr.layer() ); - - QgsVectorLayerSaveAsDialog *dialog = new QgsVectorLayerSaveAsDialog( QgisApp::instance() ); - - if ( dialog->exec() == QDialog::Accepted ) - { - QString encoding = dialog->encoding(); - QString vectorFilename = dialog->filename(); - QString format = dialog->format(); - - if ( dialog->crs() < 0 ) - { - // Find out if we have projections enabled or not - if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() ) - { - destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs(); - } - else - { - destCRS = vlayer->srs(); - } - } - else - { - destCRS = QgsCoordinateReferenceSystem( dialog->crs(), QgsCoordinateReferenceSystem::InternalCrsId ); - } - - // overwrite the file - user will already have been prompted - // to verify they want to overwrite by the file dialog above - // might not even exists in the given case. - // add the extension if not present - if ( format == "ESRI Shapefile" ) - { - if ( !vectorFilename.endsWith( ".shp", Qt::CaseInsensitive ) ) - { - vectorFilename += ".shp"; - } - QgsVectorFileWriter::deleteShapeFile( vectorFilename ); - } - - //GE does not open files without extensions. Therefore we append it automatically for kml files - if ( format == "KML" ) - { - if ( !vectorFilename.endsWith( ".kml", Qt::CaseInsensitive ) ) - { - vectorFilename += ".kml"; - } - } - - // ok if the file existed it should be deleted now so we can continue... - QApplication::setOverrideCursor( Qt::WaitCursor ); - - QgsVectorFileWriter::WriterError error; - QString errorMessage; - error = QgsVectorFileWriter::writeAsVectorFormat( vlayer, vectorFilename, encoding, &destCRS, format, saveOnlySelection, &errorMessage ); - - QApplication::restoreOverrideCursor(); - - if ( error == QgsVectorFileWriter::NoError ) - { - QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to vector file has been completed" ) ); - } - else - { - QMessageBox::warning( 0, tr( "Save error" ), tr( "Export to vector file failed.\nError: %1" ).arg( errorMessage ) ); - } - } - - delete dialog; } @@ -589,5 +490,4 @@ } - QgsMapCanvasLayer& QgsLegendLayer::canvasLayer() { @@ -600,3 +500,2 @@ setText( 0, name ); } - Index: /trunk/qgis/src/app/legend/qgslegend.cpp =================================================================== --- qgis-1.4.0/src/app/legend/qgslegend.cpp (revision 13476) +++ /trunk/qgis/src/app/legend/qgslegend.cpp (revision 13501) @@ -33,10 +33,5 @@ #include "qgsproject.h" #include "qgsrasterlayer.h" -#include "qgsrasterlayerproperties.h" -#include "qgsvectorlayerproperties.h" - -#include "qgsattributetabledialog.h" - -#include +#include "qgsvectorlayer.h" #include @@ -58,12 +53,13 @@ set mItemBeingMoved pointer to 0 to prevent SuSE 9.0 crash */ -QgsLegend::QgsLegend( QWidget * parent, const char *name ) +QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name ) : QTreeWidget( parent ), mMousePressedFlag( false ), mItemBeingMoved( 0 ), - mToggleEditingAction( 0 ), - mMapCanvas( 0 ), + mMapCanvas( canvas ), mMinimumIconSize( 20, 20 ) { + setObjectName( name ); + connect( this, SIGNAL( itemChanged( QTreeWidgetItem*, int ) ), this, SLOT( handleItemChange( QTreeWidgetItem*, int ) ) ); @@ -77,4 +73,15 @@ connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ), this, SLOT( writeProject( QDomDocument & ) ) ); + + // connect map layer registry signal to legend + connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), + this, SLOT( removeLayer( QString ) ) ); + connect( QgsMapLayerRegistry::instance(), SIGNAL( removedAll() ), + this, SLOT( removeAll() ) ); + connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), + this, SLOT( addLayer( QgsMapLayer * ) ) ); + + connect( mMapCanvas, SIGNAL( layersChanged() ), + this, SLOT( refreshCheckStates() ) ); // Initialise the line indicator widget. @@ -175,11 +182,6 @@ } -void QgsLegend::removeLayer( QString layer_key ) -{ - if ( !mMapCanvas || mMapCanvas->isDrawing() ) - { - return; - } - +void QgsLegend::removeLayer( QString layerId ) +{ QgsDebugMsg( "called." ); @@ -192,9 +194,8 @@ QgsLegendLayer* ll = qobject_cast( li ); - if ( ll && ll->layer() && ll->layer()->getLayerID() == layer_key ) + if ( ll && ll->layer() && ll->layer()->getLayerID() == layerId ) { removeItem( ll ); delete ll; - break; } @@ -423,9 +424,5 @@ void QgsLegend::mouseDoubleClickEvent( QMouseEvent* e ) { - if ( !mMapCanvas || mMapCanvas->isDrawing() ) - { - return; - } - legendLayerShowProperties(); + QgisApp::instance()->layerProperties(); } @@ -445,5 +442,5 @@ if ( li->type() == QgsLegendItem::LEGEND_LAYER ) { - ( static_cast( li ) )->addToPopupMenu( theMenu, mToggleEditingAction ); + qobject_cast( li )->addToPopupMenu( theMenu ); if ( li->parent() ) @@ -566,15 +563,4 @@ } -void QgsLegend::setMapCanvas( QgsMapCanvas * canvas ) -{ - if ( mMapCanvas ) - { - disconnect( mMapCanvas, SIGNAL( layersChanged() ) ); - } - - mMapCanvas = canvas; - connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( refreshCheckStates() ) ); -} - QgsLegendLayer* QgsLegend::currentLegendLayer() { @@ -647,80 +633,12 @@ while ( child ) { - setCurrentItem( child ); - removeCurrentLayer(); + QgsLegendLayer* ll = dynamic_cast( child ); + if ( ll ) + QgsMapLayerRegistry::instance()->removeMapLayer( ll->layer()->getLayerID() ); child = lg->child( 0 ); } delete lg; + adjustIconSize(); -} - -void QgsLegend::removeCurrentLayer() -{ - if ( !mMapCanvas || mMapCanvas->isDrawing() ) - { - return; - } - - //if the current item is a legend layer: remove all layers of the current legendLayer - QgsLegendLayer* ll = dynamic_cast( currentItem() ); - if ( !ll ) - return; - - removeLayer( ll->layer(), true ); - - adjustIconSize(); -} - -bool QgsLegend::removeLayer( QgsMapLayer* ml, bool askCancelOnEditable ) -{ - if ( !ml ) - { - return false; - } - - QgsVectorLayer* vl = qobject_cast( 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; } @@ -739,33 +657,4 @@ insertItem( layer, group ); -} - -void QgsLegend::legendLayerShowProperties() -{ - if ( !mMapCanvas || mMapCanvas->isDrawing() ) - { - return; - } - - QgsLegendItem* li = dynamic_cast( currentItem() ); - - if ( !li ) - { - return; - } - - if ( li->type() != QgsLegendItem::LEGEND_LAYER ) - return; - - QgsLegendLayer* ll = qobject_cast( li ); - if ( !ll ) - return; - - //QgsDebugMsg("Showing layer properties dialog"); - - QgisApp::instance()->showLayerProperties( ll->layer() ); - - ll->updateIcon(); - } @@ -1733,33 +1622,4 @@ } -void QgsLegend::legendLayerAttributeTable() -{ - if ( !mMapCanvas || mMapCanvas->isDrawing() ) - { - return; - } - - QgsVectorLayer *vlayer = 0; - - // try whether it's a legend layer - QgsLegendLayer* ll = dynamic_cast( currentItem() ); - if ( !ll ) - { - // nothing selected - QMessageBox::information( this, - tr( "No Layer Selected" ), - tr( "To open an attribute table, you must select a vector layer in the legend" ) ); - return; - } - - vlayer = qobject_cast( ll->layer() ); - if ( vlayer ) - { - QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( vlayer ); - mDialog->show(); - // the dialog will be deleted by itself on close - } -} - void QgsLegend::readProject( const QDomDocument & doc ) { Index: /trunk/qgis/src/app/legend/qgslegendlayer.h =================================================================== --- qgis-1.4.0/src/app/legend/qgslegendlayer.h (revision 13380) +++ /trunk/qgis/src/app/legend/qgslegendlayer.h (revision 13501) @@ -62,5 +62,5 @@ /** called to add appropriate menu items to legend's popup menu */ - void addToPopupMenu( QMenu& theMenu, QAction* toggleEditingAction ); + void addToPopupMenu( QMenu& theMenu ); /** Set layer to be visible in canvas */ @@ -81,10 +81,4 @@ /**Toggle show in overview*/ void showInOverview(); - - /**Show layer attribute table*/ - void table(); - - void saveAsVectorFile(); - void saveSelectionAsVectorFile(); /**update the layer's icon to show whether is in editing mode or in overview */ @@ -109,6 +103,4 @@ QPixmap getOriginalPixmap(); - void saveAsVectorFileGeneral( bool saveOnlySelection ); - private: /** Helper method to make the font bold from all ctors. Index: /trunk/qgis/src/app/legend/qgslegend.h =================================================================== --- qgis-1.4.0/src/app/legend/qgslegend.h (revision 13476) +++ /trunk/qgis/src/app/legend/qgslegend.h (revision 13501) @@ -97,5 +97,5 @@ * @param theName An optional name for the widget */ - QgsLegend( QWidget * parent = 0, const char *name = 0 ); + QgsLegend( QgsMapCanvas *canvas, QWidget * parent = 0, const char *name = 0 ); //! Destructor @@ -182,7 +182,4 @@ void removePixmapHeightValue( int height ); - /**Sets the toggle editing action. Usually called from QgisApp*/ - void setToggleEditingAction( QAction* editingAction ) {mToggleEditingAction = editingAction;} - /**Returns structure with legend pixmaps*/ QgsLegendPixmaps& pixmaps() { return mPixmaps; } @@ -200,6 +197,4 @@ void setLayerVisible( QgsMapLayer * layer, bool visible ); - - void setMapCanvas( QgsMapCanvas * canvas ); /**Updates symbology items for a layer*/ @@ -244,14 +239,4 @@ void writeProject( QDomDocument & ); - /**Removes the current LegendLayer*/ - void removeCurrentLayer(); - - /**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 ); - /*! * Moves a layer to a group. @@ -272,10 +257,4 @@ Only works on raster layers*/ void legendLayerZoomNative(); - - /**Show attribute table*/ - void legendLayerAttributeTable(); - - /**Shows the property dialog of the first legend layer file in a legend layer*/ - void legendLayerShowProperties(); /**Updates check states when the map canvas layer set is changed */ @@ -441,7 +420,4 @@ std::deque mLayersPriorToMove; - /**Action for the legendlayer right click menu*/ - QAction* mToggleEditingAction; - /*! * A function to determine how far down in the list an item is (starting with one for the first Item). Index: /trunk/qgis/src/app/qgsattributedialog.cpp =================================================================== --- qgis-1.4.0/src/app/qgsattributedialog.cpp (revision 13339) +++ /trunk/qgis/src/app/qgsattributedialog.cpp (revision 13501) @@ -206,5 +206,4 @@ connect( buttonBox, SIGNAL( rejected() ), mDialog, SLOT( reject() ) ); - connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) ); } Index: /trunk/qgis/src/app/qgsmeasuredialog.cpp =================================================================== --- qgis-1.4.0/src/app/qgsmeasuredialog.cpp (revision 12178) +++ /trunk/qgis/src/app/qgsmeasuredialog.cpp (revision 13501) @@ -77,5 +77,5 @@ { addPoint( point ); - this->show(); + show(); } raise(); Index: /trunk/qgis/src/app/qgsattributedialog.h =================================================================== --- qgis-1.4.0/src/app/qgsattributedialog.h (revision 12806) +++ /trunk/qgis/src/app/qgsattributedialog.h (revision 13501) @@ -52,7 +52,4 @@ public slots: - /** Overloaded accept method which will write the feature field - * values, then delegate to QDialog::accept() - */ void accept(); Index: /trunk/qgis/src/app/qgsundowidget.cpp =================================================================== --- qgis-1.4.0/src/app/qgsundowidget.cpp (revision 11756) +++ /trunk/qgis/src/app/qgsundowidget.cpp (revision 13501) @@ -3,4 +3,5 @@ #include "qgsmaplayer.h" #include "qgsmapcanvas.h" +#include "qgslegend.h" #include "qgisapp.h" @@ -11,9 +12,10 @@ setupUi( this ); setWidget( dockWidgetContents ); - connect( this->undoButton, SIGNAL( clicked() ), - this, SLOT( undo( ) ) ); - connect( this->redoButton, SIGNAL( clicked() ), - this, SLOT( redo( ) ) ); + connect( undoButton, SIGNAL( clicked() ), this, SLOT( undo( ) ) ); + connect( redoButton, SIGNAL( clicked() ), this, SLOT( redo( ) ) ); + connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), + this, SLOT( layerChanged( QgsMapLayer* ) ) ); + undoButton->setDisabled( true ); redoButton->setDisabled( true ); @@ -100,6 +102,6 @@ gridLayout->addWidget( mUndoView, 0, 0, 1, 2 ); setWidget( dockWidgetContents ); - connect( this->mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) ); - connect( this->mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) ); + connect( mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) ); + connect( mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) ); // indexChanged() triggers a refresh. but it gets triggered also when a new action @@ -107,8 +109,8 @@ // vector layer: it causes potentially multiple refreshes when moving more commands // back, but avoids double refresh in common case when adding commands to the stack - //connect(this->mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(indexChanged(int))); + //connect(mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(indexChanged(int))); - this->undoButton->setDisabled( !mUndoStack->canUndo() ); - this->redoButton->setDisabled( !mUndoStack->canRedo() ); + undoButton->setDisabled( !mUndoStack->canUndo() ); + redoButton->setDisabled( !mUndoStack->canRedo() ); } Index: /trunk/qgis/src/app/qgsmaptoolnodetool.cpp =================================================================== --- qgis-1.4.0/src/app/qgsmaptoolnodetool.cpp (revision 13380) +++ /trunk/qgis/src/app/qgsmaptoolnodetool.cpp (revision 13501) @@ -27,4 +27,5 @@ #include "qgslogger.h" #include "qgisapp.h" +#include "qgslegend.h" #include @@ -70,4 +71,7 @@ //signal changing of coordinate renderer changed to repaint markers connect( canvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( coordinatesChanged( ) ) ); + //signal changing of current layer + connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), + this, SLOT( currentLayerChanged( QgsMapLayer* ) ) ); } Index: /trunk/qgis/src/app/qgisapp.h =================================================================== --- qgis-1.4.0/src/app/qgisapp.h (revision 13476) +++ /trunk/qgis/src/app/qgisapp.h (revision 13501) @@ -154,8 +154,5 @@ void saveMapAsImage( QString, QPixmap * ); /** Get the mapcanvas object from the app */ - QgsMapCanvas * mapCanvas() { return mMapCanvas; }; - - //! returns pointer to map legend - QgsLegend *legend() { return mMapLegend; } + QgsMapCanvas * mapCanvas(); //! Set theme (icons) @@ -275,4 +272,5 @@ QAction *actionOpenTable() { return mActionOpenTable; } QAction *actionToggleEditing() { return mActionToggleEditing; } + QAction *actionSaveEdits() { return mActionSaveEdits; } QAction *actionLayerSaveAs() { return mActionLayerSaveAs; } QAction *actionLayerSelectionSaveAs() { return mActionLayerSelectionSaveAs; } @@ -283,4 +281,5 @@ #endif QAction *actionLayerProperties() { return mActionLayerProperties; } + QAction *actionLayerSubsetString() { return mActionLayerSubsetString; } QAction *actionLayerSeparator2() { return mActionLayerSeparator2; } QAction *actionAddToOverview() { return mActionAddToOverview; } @@ -357,4 +356,7 @@ void showLayerProperties( QgsMapLayer *ml ); + //! returns pointer to map legend + QgsLegend *legend(); + public slots: //! Zoom to full extent @@ -367,4 +369,7 @@ void zoomToSelected(); + //! open the properties dialog for the currently selected layer + void layerProperties(); + //! mark project dirty void markDirty(); @@ -372,4 +377,7 @@ //! layer was added void layerWasAdded( QgsMapLayer * ); + + //! layer will be removed + void removingLayer( QString ); void updateUndoActions(); @@ -594,4 +602,10 @@ void toggleEditing(); + //! save current edits and start new transaction + void saveEdits(); + + //! change layer subset of current vector layer + void layerSubsetString(); + //! map tool changed void mapToolChanged( QgsMapTool *tool ); @@ -600,4 +614,6 @@ Is called from the legend when the current legend item has changed*/ void activateDeactivateLayerRelatedActions( QgsMapLayer* layer ); + + void selectionChanged( QgsMapLayer *layer ); void showProgress( int theProgress, int theTotalSteps ); @@ -639,12 +655,9 @@ //! starts/stops editing mode of a layer - void toggleEditing( QgsMapLayer *layer ); + bool toggleEditing( QgsMapLayer *layer, bool allowCancel = true ); //! save current vector layer void saveAsVectorFile(); void saveSelectionAsVectorFile(); - - //! open the properties dialog for the currently selected layer - void layerProperties(); //! show python console @@ -757,4 +770,6 @@ bool loadComposersFromProject( const QString& projectFilePath ); + void saveAsVectorFileGeneral( bool saveOnlySelection ); + /**Returns all annotation items in the canvas*/ QList annotationItems(); @@ -777,7 +792,7 @@ void createStatusBar(); void setupConnections(); - void createLegend(); + void initLegend(); void createOverview(); - void createCanvas(); + void createCanvasTools(); bool createDB(); void createMapTips(); @@ -875,4 +890,5 @@ QAction *mActionOpenTable; QAction *mActionToggleEditing; + QAction *mActionSaveEdits; QAction *mActionLayerSaveAs; QAction *mActionLayerSelectionSaveAs; @@ -883,4 +899,5 @@ #endif QAction *mActionLayerProperties; + QAction *mActionLayerSubsetString; QAction *mActionLayerSeparator2; QAction *mActionAddToOverview; Index: /trunk/qgis/src/app/qgisapp.cpp =================================================================== --- qgis-1.4.0/src/app/qgisapp.cpp (revision 13496) +++ /trunk/qgis/src/app/qgisapp.cpp (revision 13501) @@ -153,8 +153,10 @@ #include "ogr/qgsogrsublayersdialog.h" #include "ogr/qgsopenvectorlayerdialog.h" +#include "ogr/qgsvectorlayersaveasdialog.h" #include "qgsattributetabledialog.h" #include "qgsvectorfilewriter.h" #include "qgscredentialdialog.h" #include "qgstilescalewidget.h" +#include "qgsquerybuilder.h" #ifdef HAVE_QWT @@ -350,5 +352,4 @@ QgisApp::instance()->statusBar()->showMessage( QObject::tr( "CRS undefined - defaulting to default CRS" ) ); } - } @@ -387,5 +388,4 @@ createDB(); - mSplash->showMessage( tr( "Reading settings" ), Qt::AlignHCenter | Qt::AlignBottom ); qApp->processEvents(); @@ -393,4 +393,19 @@ mSplash->showMessage( tr( "Setting up the GUI" ), Qt::AlignHCenter | Qt::AlignBottom ); qApp->processEvents(); + + // "theMapCanvas" used to find this canonical instance later + mMapCanvas = new QgsMapCanvas( this, "theMapCanvas" ); + mMapCanvas->setWhatsThis( tr( "Map canvas. This is where raster and vector " + "layers are displayed when added to the map" ) ); + setCentralWidget( mMapCanvas ); + //set the focus to the map canvas + mMapCanvas->setFocus(); + + // "theMapLegend" used to find this canonical instance later + mMapLegend = new QgsLegend( mMapCanvas, this, "theMapLegend" ); + + // create undo widget + mUndoWidget = new QgsUndoWidget( NULL, mMapCanvas ); + mUndoWidget->setObjectName( "Undo" ); createActions(); @@ -399,7 +414,7 @@ createToolBars(); createStatusBar(); - createCanvas(); + createCanvasTools(); mMapCanvas->freeze(); - createLegend(); + initLegend(); createOverview(); createMapTips(); @@ -407,12 +422,9 @@ updateRecentProjectPaths(); + addDockWidget( Qt::LeftDockWidgetArea, mUndoWidget ); + mUndoWidget->hide(); + mInternalClipboard = new QgsClipboard; // create clipboard mQgisInterface = new QgisAppInterface( this ); // create the interfce - - // create undo widget - mUndoWidget = new QgsUndoWidget( NULL, mMapCanvas ); - mUndoWidget->setObjectName( "Undo" ); - addDockWidget( Qt::LeftDockWidgetArea, mUndoWidget ); - mUndoWidget->hide(); #ifdef Q_WS_MAC @@ -698,12 +710,12 @@ shortcuts->registerAction( mActionUndo, tr( "Ctrl+Z" ) ); mActionUndo->setStatusTip( tr( "Undo the last operation" ) ); + connect( mActionUndo, SIGNAL( triggered() ), mUndoWidget, SLOT( undo() ) ); mActionUndo->setEnabled( false ); - // action connected to mUndoWidget::undo slot in setupConnections() mActionRedo = new QAction( getThemeIcon( "mActionRedo.png" ), tr( "&Redo" ), this ); shortcuts->registerAction( mActionRedo, tr( "Ctrl+Shift+Z" ) ); mActionRedo->setStatusTip( tr( "Redo the last operation" ) ); + connect( mActionRedo, SIGNAL( triggered() ), mUndoWidget, SLOT( redo() ) ); mActionRedo->setEnabled( false ); - // action connected to mUndoWidget::redo slot in setupConnections() mActionCutFeatures = new QAction( getThemeIcon( "mActionEditCut.png" ), tr( "Cut Features" ), this ); @@ -999,4 +1011,10 @@ connect( mActionToggleEditing, SIGNAL( triggered() ), this, SLOT( toggleEditing() ) ); mActionToggleEditing->setEnabled( false ); + + mActionSaveEdits = new QAction( getThemeIcon( "mActionSaveEdits.png" ), tr( "Save edits" ), this ); + shortcuts->registerAction( mActionSaveEdits ); + mActionSaveEdits->setStatusTip( tr( "Save edits to current layer , but continue editing" ) ); + connect( mActionSaveEdits, SIGNAL( triggered() ), this, SLOT( saveEdits() ) ); + mActionSaveEdits->setEnabled( false ); mActionLayerSaveAs = new QAction( tr( "Save as..." ), this ); @@ -1037,4 +1055,10 @@ connect( mActionLayerProperties, SIGNAL( triggered() ), this, SLOT( layerProperties() ) ); mActionLayerProperties->setEnabled( false ); + + mActionLayerSubsetString = new QAction( tr( "Subset..." ), this ); + shortcuts->registerAction( mActionLayerSubsetString ); + mActionLayerProperties->setStatusTip( tr( "Set subset query of the current layer" ) ); + connect( mActionLayerSubsetString, SIGNAL( triggered() ), this, SLOT( layerSubsetString() ) ); + mActionLayerSubsetString->setEnabled( false ); mActionAddToOverview = new QAction( getThemeIcon( "mActionInOverview.png" ), tr( "Add to Overview" ), this ); @@ -1438,4 +1462,5 @@ mLayerMenu->addAction( mActionOpenTable ); + mLayerMenu->addAction( mActionSaveEdits ); mLayerMenu->addAction( mActionToggleEditing ); mLayerMenu->addAction( mActionLayerSaveAs ); @@ -1443,4 +1468,5 @@ mLayerMenu->addAction( mActionRemoveLayer ); mLayerMenu->addAction( mActionLayerProperties ); + mLayerMenu->addAction( mActionLayerSubsetString ); mActionLayerSeparator2 = mLayerMenu->addSeparator(); @@ -1558,4 +1584,5 @@ mDigitizeToolBar->setObjectName( "Digitizing" ); mDigitizeToolBar->addAction( mActionToggleEditing ); + mDigitizeToolBar->addAction( mActionSaveEdits ); mDigitizeToolBar->addAction( mActionCapturePoint ); mDigitizeToolBar->addAction( mActionCaptureLine ); @@ -1622,16 +1649,16 @@ mAttributesToolBar->addAction( mActionNewBookmark ); // Annotation tools - QToolButton* mAnnotationToolButton = new QToolButton(); - mAnnotationToolButton->setPopupMode( QToolButton::InstantPopup ); - mAnnotationToolButton->setAutoRaise( true ); - mAnnotationToolButton->setToolButtonStyle( Qt::ToolButtonIconOnly ); - mAnnotationToolButton->setCheckable( true ); - mAnnotationToolButton->addAction( mActionTextAnnotation ); - mAnnotationToolButton->addAction( mActionFormAnnotation ); - mAnnotationToolButton->addAction( mActionAnnotation ); - mAnnotationToolButton->setDefaultAction( mActionTextAnnotation ); - QObject::connect( mAnnotationToolButton, SIGNAL( triggered( QAction* ) ), \ - mAnnotationToolButton, SLOT( setDefaultAction( QAction* ) ) ); - mAttributesToolBar->addWidget( mAnnotationToolButton ); + QToolButton *annotationToolButton = new QToolButton(); + annotationToolButton->setPopupMode( QToolButton::InstantPopup ); + annotationToolButton->setAutoRaise( true ); + annotationToolButton->setToolButtonStyle( Qt::ToolButtonIconOnly ); + annotationToolButton->setCheckable( true ); + annotationToolButton->addAction( mActionTextAnnotation ); + annotationToolButton->addAction( mActionFormAnnotation ); + annotationToolButton->addAction( mActionAnnotation ); + annotationToolButton->setDefaultAction( mActionTextAnnotation ); + connect( annotationToolButton, SIGNAL( triggered( QAction* ) ), + annotationToolButton, SLOT( setDefaultAction( QAction* ) ) ); + mAttributesToolBar->addWidget( annotationToolButton ); mToolbarMenu->addAction( mAttributesToolBar->toggleViewAction() ); // @@ -1837,4 +1864,5 @@ mActionDraw->setIcon( getThemeIcon( "/mActionDraw.png" ) ); mActionToggleEditing->setIcon( getThemeIcon( "/mActionToggleEditing.png" ) ); + mActionSaveEdits->setIcon( getThemeIcon( "/mActionSaveEdits.png" ) ); mActionCutFeatures->setIcon( getThemeIcon( "/mActionEditCut.png" ) ); mActionCopyFeatures->setIcon( getThemeIcon( "/mActionEditCopy.png" ) ); @@ -1898,81 +1926,74 @@ // connect the "cleanup" slot connect( qApp, SIGNAL( aboutToQuit() ), this, SLOT( saveWindowState() ) ); - //connect the legend, mapcanvas and overview canvas to the registry - - // connect map layer registry signals to legend - connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), - mMapLegend, SLOT( removeLayer( QString ) ) ); - connect( QgsMapLayerRegistry::instance(), SIGNAL( removedAll() ), - mMapLegend, SLOT( removeAll() ) ); - connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), - mMapLegend, SLOT( addLayer( QgsMapLayer * ) ) ); - connect( mMapLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), - this, SLOT( activateDeactivateLayerRelatedActions( QgsMapLayer* ) ) ); - connect( mMapLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), - mUndoWidget, SLOT( layerChanged( QgsMapLayer* ) ) ); - connect( mMapLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), - mMapTools.mNodeTool, SLOT( currentLayerChanged( QgsMapLayer* ) ) ); - - //signal when mouse moved over window (coords display in status bar) - connect( mMapCanvas, SIGNAL( xyCoordinates( const QgsPoint & ) ), this, SLOT( showMouseCoordinate( const QgsPoint & ) ) ); - connect( mMapCanvas->mapRenderer(), SIGNAL( drawingProgress( int, int ) ), this, SLOT( showProgress( int, int ) ) ); - connect( mMapCanvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( hasCrsTransformEnabled( bool ) ) ); - connect( mMapCanvas->mapRenderer(), SIGNAL( destinationSrsChanged() ), this, SLOT( destinationSrsChanged() ) ); - connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( showExtents() ) ); - connect( mMapCanvas, SIGNAL( scaleChanged( double ) ), this, SLOT( showScale( double ) ) ); - connect( mMapCanvas, SIGNAL( scaleChanged( double ) ), this, SLOT( updateMouseCoordinatePrecision() ) ); - connect( mMapCanvas, SIGNAL( mapToolSet( QgsMapTool * ) ), this, SLOT( mapToolChanged( QgsMapTool * ) ) ); + + // signal when mouse moved over window (coords display in status bar) + connect( mMapCanvas, SIGNAL( xyCoordinates( const QgsPoint & ) ), + this, SLOT( showMouseCoordinate( const QgsPoint & ) ) ); + connect( mMapCanvas, SIGNAL( extentsChanged() ), + this, SLOT( showExtents() ) ); + connect( mMapCanvas, SIGNAL( scaleChanged( double ) ), + this, SLOT( showScale( double ) ) ); + connect( mMapCanvas, SIGNAL( scaleChanged( double ) ), + this, SLOT( updateMouseCoordinatePrecision() ) ); + connect( mMapCanvas, SIGNAL( mapToolSet( QgsMapTool * ) ), + this, SLOT( mapToolChanged( QgsMapTool * ) ) ); connect( mMapCanvas, SIGNAL( selectionChanged( QgsMapLayer * ) ), + this, SLOT( selectionChanged( QgsMapLayer * ) ) ); + connect( mMapCanvas, SIGNAL( extentsChanged() ), + this, SLOT( markDirty() ) ); + connect( mMapCanvas, SIGNAL( layersChanged() ), + this, SLOT( markDirty() ) ); + + connect( mMapCanvas, SIGNAL( zoomLastStatusChanged( bool ) ), + mActionZoomLast, SLOT( setEnabled( bool ) ) ); + connect( mMapCanvas, SIGNAL( zoomNextStatusChanged( bool ) ), + mActionZoomNext, SLOT( setEnabled( bool ) ) ); + connect( mRenderSuppressionCBox, SIGNAL( toggled( bool ) ), + mMapCanvas, SLOT( setRenderFlag( bool ) ) ); + + // connect renderer + connect( mMapCanvas->mapRenderer(), SIGNAL( drawingProgress( int, int ) ), + this, SLOT( showProgress( int, int ) ) ); + connect( mMapCanvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), + this, SLOT( hasCrsTransformEnabled( bool ) ) ); + connect( mMapCanvas->mapRenderer(), SIGNAL( destinationSrsChanged() ), + this, SLOT( destinationSrsChanged() ) ); + + // connect legend signals + connect( mMapLegend, SIGNAL( currentLayerChanged( QgsMapLayer * ) ), this, SLOT( activateDeactivateLayerRelatedActions( QgsMapLayer * ) ) ); - - // track of canvas layers and extents and mark project dirty on changes - connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( markDirty() ) ); - connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( markDirty() ) ); - connect( mMapLegend, SIGNAL( zOrderChanged() ), this, SLOT( markDirty() ) ); - + connect( mMapLegend, SIGNAL( zOrderChanged() ), + this, SLOT( markDirty() ) ); + + // connect map layer registry connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer * ) ), this, SLOT( layerWasAdded( QgsMapLayer * ) ) ); - - connect( mRenderSuppressionCBox, SIGNAL( toggled( bool ) ), mMapCanvas, SLOT( setRenderFlag( bool ) ) ); - // - // Do we really need this ??? - its already connected to the esc key...TS - // - connect( mStopRenderButton, SIGNAL( clicked() ), this, SLOT( stopRendering() ) ); + connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), + this, SLOT( removingLayer( QString ) ) ); // Connect warning dialog from project reading connect( QgsProject::instance(), SIGNAL( oldProjectVersionWarning( QString ) ), this, SLOT( oldProjectVersionWarning( QString ) ) ); - - connect( QgsProject::instance(), SIGNAL( layerLoaded( int, int ) ), this, SLOT( showProgress( int, int ) ) ); - - // setup undo/redo actions - connect( mActionUndo, SIGNAL( triggered() ), mUndoWidget, SLOT( undo() ) ); - connect( mActionRedo, SIGNAL( triggered() ), mUndoWidget, SLOT( redo() ) ); - connect( mUndoWidget, SIGNAL( undoStackChanged() ), this, SLOT( updateUndoActions() ) ); - - // Connect status from ZoomLast/ZoomNext to corresponding action - connect( mMapCanvas, SIGNAL( zoomLastStatusChanged( bool ) ), mActionZoomLast, SLOT( setEnabled( bool ) ) ); - connect( mMapCanvas, SIGNAL( zoomNextStatusChanged( bool ) ), mActionZoomNext, SLOT( setEnabled( bool ) ) ); - - // Monitor change of project path + connect( QgsProject::instance(), SIGNAL( layerLoaded( int, int ) ), + this, SLOT( showProgress( int, int ) ) ); connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ), this, SLOT( readProject( const QDomDocument & ) ) ); connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ), this, SLOT( writeProject( QDomDocument & ) ) ); - - connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument& ) ), this, SLOT( writeAnnotationItemsToProject( QDomDocument& ) ) ); -} - -void QgisApp::createCanvas() -{ - // "theMapCanvas" used to find this canonical instance later - mMapCanvas = new QgsMapCanvas( this, "theMapCanvas" ); - mMapCanvas->setWhatsThis( tr( "Map canvas. This is where raster and vector " - "layers are displayed when added to the map" ) ); - - setCentralWidget( mMapCanvas ); - // set the focus to the map canvas - mMapCanvas->setFocus(); - + connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument& ) ), + this, SLOT( writeAnnotationItemsToProject( QDomDocument& ) ) ); + + // + // Do we really need this ??? - its already connected to the esc key...TS + // + connect( mStopRenderButton, SIGNAL( clicked() ), + this, SLOT( stopRendering() ) ); + + // setup undo/redo actions + connect( mUndoWidget, SIGNAL( undoStackChanged() ), this, SLOT( updateUndoActions() ) ); +} + +void QgisApp::createCanvasTools() +{ // create tools mMapTools.mZoomIn = new QgsMapToolZoom( mMapCanvas, false /* zoomIn */ ); @@ -2097,14 +2118,18 @@ } -void QgisApp::createLegend() -{ - //legend - mMapLegend = new QgsLegend( NULL, "theMapLegend" ); - mMapLegend->setObjectName( "theMapLegend" ); - mMapLegend->setMapCanvas( mMapCanvas ); - - //add the toggle editing action also to legend such that right click menu and button show the same state - mMapLegend->setToggleEditingAction( mActionToggleEditing ); - +QgsLegend *QgisApp::legend() +{ + Q_ASSERT( mMapLegend ); + return mMapLegend; +} + +QgsMapCanvas *QgisApp::mapCanvas() +{ + Q_ASSERT( mMapCanvas ); + return mMapCanvas; +} + +void QgisApp::initLegend() +{ mMapLegend->setWhatsThis( tr( "Map legend that displays all the layers currently on the map canvas. Click on the check box to turn a layer on or off. Double click on a layer in the legend to customize its appearance and set other properties." ) ); mLegendDock = new QDockWidget( tr( "Layers" ), this ); @@ -2853,7 +2878,4 @@ } - - - void QgisApp::fileExit() { @@ -3779,5 +3801,5 @@ } - QgsVectorLayer *myLayer = qobject_cast( mMapLegend->currentLayer() ); + QgsVectorLayer *myLayer = qobject_cast( activeLayer() ); if ( !myLayer ) { @@ -3792,29 +3814,102 @@ void QgisApp::saveAsVectorFile() { - if ( mMapLegend ) - { - QgsLegendLayer* currentLegendLayer = mMapLegend->currentLegendLayer(); - if ( currentLegendLayer ) - { - currentLegendLayer->saveAsVectorFile(); - } - } + saveAsVectorFileGeneral( false ); } void QgisApp::saveSelectionAsVectorFile() { - if ( mMapLegend ) - { - QgsLegendLayer* currentLegendLayer = mMapLegend->currentLegendLayer(); - if ( currentLegendLayer ) - { - currentLegendLayer->saveSelectionAsVectorFile(); - } - } -} + saveAsVectorFileGeneral( true ); +} + +void QgisApp::saveAsVectorFileGeneral( bool saveOnlySelection ) +{ + if ( mMapCanvas && mMapCanvas->isDrawing() ) + return; + + if ( !mMapLegend ) + return; + + QgsVectorLayer *vlayer = qobject_cast( activeLayer() ); + if ( !vlayer ) + return; + + QgsCoordinateReferenceSystem destCRS; + + QgsVectorLayerSaveAsDialog *dialog = new QgsVectorLayerSaveAsDialog( this ); + + if ( dialog->exec() == QDialog::Accepted ) + { + QString encoding = dialog->encoding(); + QString vectorFilename = dialog->filename(); + QString format = dialog->format(); + + if ( dialog->crs() < 0 ) + { + // Find out if we have projections enabled or not + if ( mMapCanvas->mapRenderer()->hasCrsTransformEnabled() ) + { + destCRS = mMapCanvas->mapRenderer()->destinationSrs(); + } + else + { + destCRS = vlayer->srs(); + } + } + else + { + destCRS = QgsCoordinateReferenceSystem( dialog->crs(), QgsCoordinateReferenceSystem::InternalCrsId ); + } + + // overwrite the file - user will already have been prompted + // to verify they want to overwrite by the file dialog above + // might not even exists in the given case. + // add the extension if not present + if ( format == "ESRI Shapefile" ) + { + if ( !vectorFilename.endsWith( ".shp", Qt::CaseInsensitive ) ) + { + vectorFilename += ".shp"; + } + QgsVectorFileWriter::deleteShapeFile( vectorFilename ); + } + + //GE does not open files without extensions. Therefore we append it automatically for kml files + if ( format == "KML" ) + { + if ( !vectorFilename.endsWith( ".kml", Qt::CaseInsensitive ) ) + { + vectorFilename += ".kml"; + } + } + + // ok if the file existed it should be deleted now so we can continue... + QApplication::setOverrideCursor( Qt::WaitCursor ); + + QgsVectorFileWriter::WriterError error; + QString errorMessage; + error = QgsVectorFileWriter::writeAsVectorFormat( vlayer, vectorFilename, encoding, &destCRS, format, saveOnlySelection, &errorMessage ); + + QApplication::restoreOverrideCursor(); + + if ( error == QgsVectorFileWriter::NoError ) + { + QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to vector file has been completed" ) ); + } + else + { + QMessageBox::warning( 0, tr( "Save error" ), tr( "Export to vector file failed.\nError: %1" ).arg( errorMessage ) ); + } + } + + delete dialog; +} + void QgisApp::layerProperties() { - mMapLegend->legendLayerShowProperties(); + if ( mMapCanvas && mMapCanvas->isDrawing() ) + return; + + showLayerProperties( activeLayer() ); } @@ -4379,7 +4474,5 @@ } - QgsMapLayer * selectionLayer = ( layerContainingSelection != 0 ) ? - ( layerContainingSelection ) : - ( activeLayer() ); + QgsMapLayer *selectionLayer = layerContainingSelection ? layerContainingSelection : activeLayer(); if ( selectionLayer ) @@ -4408,7 +4501,5 @@ } - QgsMapLayer * selectionLayer = ( layerContainingSelection != 0 ) ? - ( layerContainingSelection ) : - ( activeLayer() ); + QgsMapLayer *selectionLayer = layerContainingSelection ? layerContainingSelection : activeLayer(); if ( selectionLayer ) @@ -4434,7 +4525,5 @@ } - QgsMapLayer * pasteLayer = ( destinationLayer != 0 ) ? - ( destinationLayer ) : - ( activeLayer() ); + QgsMapLayer *pasteLayer = destinationLayer ? destinationLayer : activeLayer(); if ( pasteLayer ) @@ -4494,20 +4583,70 @@ return; - QgsLegendLayer* currentLayer = mMapLegend->currentLegendLayer(); + QgsVectorLayer *currentLayer = qobject_cast( activeLayer() ); if ( currentLayer ) { - toggleEditing( mMapLegend->currentLayer() ); + toggleEditing( currentLayer, true ); } else { + // active although there's no layer active!? mActionToggleEditing->setChecked( false ); } } -void QgisApp::toggleEditing( QgsMapLayer *layer ) +void QgisApp::saveEdits() +{ + if ( mMapCanvas && mMapCanvas->isDrawing() ) + return; + + QgsVectorLayer *vlayer = qobject_cast( activeLayer() ); + if ( !vlayer || !vlayer->isEditable() || !vlayer->isModified() ) + return; + + if ( !vlayer->commitChanges() ) + { + QMessageBox::information( 0, + tr( "Error" ), + tr( "Could not commit changes to layer %1\n\nErrors: %2\n" ) + .arg( vlayer->name() ) + .arg( vlayer->commitErrors().join( "\n " ) ) ); + } + + vlayer->startEditing(); +} + +void QgisApp::layerSubsetString() +{ + if ( mMapCanvas && mMapCanvas->isDrawing() ) + return; + + QgsVectorLayer *vlayer = qobject_cast( activeLayer() ); + if ( !vlayer ) + return; + + // launch the query builder + QgsQueryBuilder *qb = new QgsQueryBuilder( vlayer, this ); + + // Set the sql in the query builder to the same in the prop dialog + // (in case the user has already changed it) + qb->setSql( vlayer->subsetString() ); + // Open the query builder + if ( qb->exec() ) + { + // if the sql is changed, update it in the prop subset text box + vlayer->setSubsetString( qb->sql() ); + mMapCanvas->refresh(); + } + + // delete the query builder object + delete qb; +} + + +bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel ) { if ( !layer ) { - return; + return false; } @@ -4515,5 +4654,5 @@ if ( !vlayer ) { - return; + return false; } @@ -4524,40 +4663,47 @@ { QMessageBox::information( 0, tr( "Start editing failed" ), tr( "Provider cannot be opened for editing" ) ); + return false; } } else if ( vlayer->isModified() ) { - // commit or roll back? - QMessageBox::StandardButton commit = - QMessageBox::information( 0, - tr( "Stop editing" ), - tr( "Do you want to save the changes to layer %1?" ).arg( vlayer->name() ), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel ); - - if ( commit == QMessageBox::Save ) - { - if ( !vlayer->commitChanges() ) - { - QMessageBox::information( 0, - tr( "Error" ), - tr( "Could not commit changes to layer %1\n\nErrors: %2\n" ) - .arg( vlayer->name() ) - .arg( vlayer->commitErrors().join( "\n " ) ) ); - // Leave the in-memory editing state alone, - // to give the user a chance to enter different values - // and try the commit again later - } - } - else if ( commit == QMessageBox::Discard ) - { - if ( !vlayer->rollBack() ) - { - QMessageBox::information( 0, tr( "Error" ), tr( "Problems during roll back" ) ); - } - } - else //cancel - { - mActionToggleEditing->setChecked( vlayer->isEditable() ); - return; + QMessageBox::StandardButtons buttons = QMessageBox::Save | QMessageBox::Discard; + if ( allowCancel ) + buttons |= QMessageBox::Cancel; + + switch ( QMessageBox::information( 0, + tr( "Stop editing" ), + tr( "Do you want to save the changes to layer %1?" ).arg( vlayer->name() ), + buttons ) ) + { + case QMessageBox::Cancel: + mActionToggleEditing->setChecked( vlayer->isEditable() ); + return false; + + case QMessageBox::Save: + if ( !vlayer->commitChanges() ) + { + QMessageBox::information( 0, + tr( "Error" ), + tr( "Could not commit changes to layer %1\n\nErrors: %2\n" ) + .arg( vlayer->name() ) + .arg( vlayer->commitErrors().join( "\n " ) ) ); + // Leave the in-memory editing state alone, + // to give the user a chance to enter different values + // and try the commit again later + return false; + } + break; + + case QMessageBox::Discard: + if ( !vlayer->rollBack() ) + { + QMessageBox::information( 0, tr( "Error" ), tr( "Problems during roll back" ) ); + return false; + } + break; + + default: + break; } } @@ -4567,5 +4713,5 @@ } - if ( layer == mMapLegend->currentLayer() ) + if ( layer == activeLayer() ) { activateDeactivateLayerRelatedActions( layer ); @@ -4575,4 +4721,5 @@ mActionToggleEditing->setChecked( vlayer->isEditable() ); vlayer->triggerRepaint(); + return true; } @@ -4686,30 +4833,39 @@ } +void QgisApp::removingLayer( QString layerId ) +{ + QgsVectorLayer *vlayer = qobject_cast( QgsMapLayerRegistry::instance()->mapLayer( layerId ) ); + if ( !vlayer || !vlayer->isEditable() ) + return; + + toggleEditing( vlayer, false ); +} + +void QgisApp::removeAllLayers() +{ + QgsMapLayerRegistry::instance()->removeAllMapLayers(); +} + void QgisApp::removeLayer() { - mMapLegend->removeCurrentLayer(); -} - - -void QgisApp::removeAllLayers() -{ - //iterate through all the layers in order to ask if uncommited changes should be saved - if ( mMapLegend ) - { - QMap layers = QgsMapLayerRegistry::instance()->mapLayers(); - QMap::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(); - } - + if ( mMapCanvas && mMapCanvas->isDrawing() ) + { + return; + } + + QgsMapLayer *layer = activeLayer(); + + if ( !layer ) + { + return; + } + + QgsVectorLayer *vlayer = qobject_cast( layer ); + if ( vlayer && vlayer->isEditable() && !toggleEditing( vlayer, true ) ) + return; + + QgsMapLayerRegistry::instance()->removeMapLayer( layer->getLayerID() ); mMapCanvas->refresh(); -} //remove all layers +} void QgisApp::showGpsTool() @@ -5051,5 +5207,5 @@ QgsMapLayer *QgisApp::activeLayer() { - return mMapLegend->currentLayer(); + return mMapLegend ? mMapLegend->currentLayer() : 0; } @@ -5057,4 +5213,7 @@ bool QgisApp::setActiveLayer( QgsMapLayer *layer ) { + if ( !layer ) + return false; + return mMapLegend->setCurrentLayer( layer ); } @@ -5079,6 +5238,4 @@ // QApplication::setOverrideCursor(Qt::WaitCursor); - // create the layer - QgsVectorLayer *layer; /* Eliminate the need to instantiate the layer based on provider type. The caller is responsible for cobbling together the needed information to @@ -5089,5 +5246,6 @@ + " and providerKey of " + providerKey ); - layer = new QgsVectorLayer( vectorLayerPath, baseName, providerKey ); + // create the layer + QgsVectorLayer *layer = new QgsVectorLayer( vectorLayerPath, baseName, providerKey ); if ( layer && layer->isValid() ) @@ -5200,6 +5358,5 @@ mMapCanvas->freeze( false ); - return ( answer != QMessageBox::Cancel ); - + return answer != QMessageBox::Cancel; } // QgisApp::saveDirty() @@ -5594,4 +5751,14 @@ } +void QgisApp::selectionChanged( QgsMapLayer *layer ) +{ + QgsVectorLayer *vlayer = qobject_cast( layer ); + if ( vlayer ) + { + showStatusMessage( tr( "%n feature(s) selected on layer %1.", "number of selected features", vlayer->selectedFeatureCount() ).arg( vlayer->name() ) ); + } + activateDeactivateLayerRelatedActions( layer ); +} + void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer ) { @@ -5603,8 +5770,10 @@ mActionOpenTable->setEnabled( false ); mActionToggleEditing->setEnabled( false ); + mActionSaveEdits->setEnabled( false ); mActionLayerSaveAs->setEnabled( false ); mActionLayerSelectionSaveAs->setEnabled( false ); mActionRemoveLayer->setEnabled( false ); mActionLayerProperties->setEnabled( false ); + mActionLayerSubsetString->setEnabled( false ); mActionAddToOverview->setEnabled( false ); @@ -5647,5 +5816,5 @@ QgsVectorLayer* vlayer = qobject_cast( layer ); const QgsVectorDataProvider* dprovider = vlayer->dataProvider(); - bool layerHasSelection = ( vlayer->selectedFeatureCount() != 0 ); + bool layerHasSelection = vlayer->selectedFeatureCount() != 0; mActionSelect->setEnabled( true ); @@ -5669,8 +5838,10 @@ mActionToggleEditing->setEnabled( true ); mActionToggleEditing->setChecked( vlayer->isEditable() ); + mActionSaveEdits->setEnabled( vlayer->isEditable() ); } else { mActionToggleEditing->setEnabled( false ); + mActionSaveEdits->setEnabled( false ); } @@ -5864,8 +6035,10 @@ else if ( layer->type() == QgsMapLayer::RasterLayer ) { + mActionLayerSubsetString->setEnabled( false ); mActionSelect->setEnabled( false ); mActionZoomActualSize->setEnabled( true ); mActionOpenTable->setEnabled( false ); mActionToggleEditing->setEnabled( false ); + mActionSaveEdits->setEnabled( false ); mActionLayerSaveAs->setEnabled( false ); mActionLayerSelectionSaveAs->setEnabled( false ); @@ -5996,10 +6169,10 @@ // connect up any request the raster may make to update the app progress - QObject::connect( theRasterLayer, SIGNAL( drawingProgress( int, int ) ), - this, SLOT( showProgress( int, int ) ) ); + connect( theRasterLayer, SIGNAL( drawingProgress( int, int ) ), + this, SLOT( showProgress( int, int ) ) ); // connect up any request the raster may make to update the statusbar message - QObject::connect( theRasterLayer, SIGNAL( statusChanged( QString ) ), - this, SLOT( showStatusMessage( QString ) ) ); + connect( theRasterLayer, SIGNAL( statusChanged( QString ) ), + this, SLOT( showStatusMessage( QString ) ) ); return true; @@ -6468,4 +6641,7 @@ */ + if ( !ml ) + return; + if ( ml->type() == QgsMapLayer::RasterLayer ) { @@ -6514,5 +6690,4 @@ QMessageBox::information( this, tr( "Warning" ), tr( "This layer doesn't have a properties dialog." ) ); } - } } Index: /trunk/qgis/src/core/qgsvectorlayer.cpp =================================================================== --- qgis-1.4.0/src/core/qgsvectorlayer.cpp (revision 13380) +++ /trunk/qgis/src/core/qgsvectorlayer.cpp (revision 13501) @@ -2951,5 +2951,5 @@ // add label node - QDomElement label = doc.createElement( "label" ); + QDomElement labelElem = doc.createElement( "label" ); QDomText labelText = doc.createTextNode( "" ); @@ -2962,7 +2962,7 @@ labelText.setData( "0" ); } - label.appendChild( labelText ); - - node.appendChild( label ); + labelElem.appendChild( labelText ); + + node.appendChild( labelElem ); // add attribute actions @@ -2975,5 +2975,5 @@ // XXX function. I think. - const QgsLabel *myLabel = this->label(); + const QgsLabel *myLabel = label(); if ( myLabel ) Index: /trunk/qgis/src/core/qgsapplication.cpp =================================================================== --- qgis-1.4.0/src/core/qgsapplication.cpp (revision 13494) +++ /trunk/qgis/src/core/qgsapplication.cpp (revision 13501) @@ -72,5 +72,4 @@ QgsApplication::~QgsApplication() { - } Index: /trunk/qgis/src/core/qgsmaplayerregistry.cpp =================================================================== --- qgis-1.4.0/src/core/qgsmaplayerregistry.cpp (revision 11961) +++ /trunk/qgis/src/core/qgsmaplayerregistry.cpp (revision 13501) @@ -103,5 +103,4 @@ void QgsMapLayerRegistry::removeAllMapLayers() { - // moved before physically removing the layers emit removedAll(); // now let all canvas Observers know to clear Index: /trunk/qgis/src/core/qgsmaplayerregistry.h =================================================================== --- qgis-1.4.0/src/core/qgsmaplayerregistry.h (revision 13380) +++ /trunk/qgis/src/core/qgsmaplayerregistry.h (revision 13501) @@ -64,5 +64,5 @@ which won't be used in main map canvas but will be used in a special one */ - QgsMapLayer * addMapLayer( QgsMapLayer * theMapLayer, bool theEmitSignal = true ); + QgsMapLayer *addMapLayer( QgsMapLayer * theMapLayer, bool theEmitSignal = true ); /** Remove a layer from qgis Index: /trunk/qgis/images/images.qrc =================================================================== --- qgis-1.4.0/images/images.qrc (revision 13189) +++ /trunk/qgis/images/images.qrc (revision 13501) @@ -375,4 +375,5 @@ themes/gis/plugins/wfs.png themes/gis/plugins/coordinate_capture/coordinate_capture.png + themes/default/mActionSaveEdits.png