Index: images/images.qrc =================================================================== --- images/images.qrc (revision 639) +++ images/images.qrc (working copy) @@ -193,6 +193,10 @@ themes/default/mActionSaveMapAsImage.png themes/default/mActionScaleBar.png themes/default/mActionSelect.png + themes/default/mActionSelectRectangle.png + themes/default/mActionSelectFreehand.png + themes/default/mActionSelectPolygon.png + themes/default/mActionSelectRadius.png themes/default/mActionSelectedToTop.png themes/default/mActionSelectPan.png themes/default/mActionShowAllLayers.png Index: images/themes/default/mActionDeselectAll.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: images/themes/default/mActionSelect.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: images/themes/default/mActionSelectFreehand.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: images\themes\default\mActionSelectFreehand.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: images/themes/default/mActionSelectPolygon.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: images\themes\default\mActionSelectPolygon.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: images/themes/default/mActionSelectRadius.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: images\themes\default\mActionSelectRadius.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: images/themes/default/mActionSelectRect.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: images\themes\default\mActionSelectRect.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: images/themes/default/mActionSelectRectangle.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: images\themes\default\mActionSelectRectangle.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: images/themes/default/selectTools.svg =================================================================== --- images/themes/default/selectTools.svg (revision 0) +++ images/themes/default/selectTools.svg (revision 0) @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Index: python/gui/qgisinterface.sip =================================================================== --- python/gui/qgisinterface.sip (revision 639) +++ python/gui/qgisinterface.sip (working copy) @@ -193,6 +193,10 @@ virtual QAction *actionZoomIn() = 0; virtual QAction *actionZoomOut() = 0; virtual QAction *actionSelect() = 0; + virtual QAction *actionSelectRectangle() = 0; + virtual QAction *actionSelectPolygon() = 0; + virtual QAction *actionSelectFreehand() = 0; + virtual QAction *actionSelectRadius() = 0; virtual QAction *actionIdentify() = 0; virtual QAction *actionMeasure() = 0; virtual QAction *actionMeasureArea() = 0; Index: python/gui/qgsrubberband.sip =================================================================== --- python/gui/qgsrubberband.sip (revision 639) +++ python/gui/qgsrubberband.sip (working copy) @@ -57,6 +57,10 @@ /**Return vertex*/ const QgsPoint *getPoint(int i, int j=0) const; + + /**Returns the rubberband as a Geometry. + * added in 1.5 */ + QgsGeometry* asGeometry(); protected: virtual void paint(QPainter* p); Index: src/app/CMakeLists.txt =================================================================== --- src/app/CMakeLists.txt (revision 639) +++ src/app/CMakeLists.txt (working copy) @@ -46,6 +46,11 @@ qgsmaptoolreshape.cpp qgsmaptoolrotatepointsymbols.cpp qgsmaptoolselect.cpp + qgsmaptoolselectrectangle.cpp + qgsmaptoolselectfreehand.cpp + qgsmaptoolselectpolygon.cpp + qgsmaptoolselectradius.cpp + qgsmaptoolselectutils.cpp qgsmaptoolsimplify.cpp qgsmaptoolsplitfeatures.cpp qgsmaptooltextannotation.cpp @@ -158,6 +163,11 @@ qgsmaptoolreshape.h qgsmaptoolrotatepointsymbols.h qgsmaptoolselect.h + qgsmaptoolselectrectangle.h + qgsmaptoolselectfreehand.h + qgsmaptoolselectpolygon.h + qgsmaptoolselectradius.h + qgsmaptoolselectutils.h qgsmaptooladdvertex.h qgsmaptooldeletering.h qgsmaptooldeletepart.h Index: src/app/qgisapp.cpp =================================================================== --- src/app/qgisapp.cpp (revision 639) +++ src/app/qgisapp.cpp (working copy) @@ -199,6 +199,10 @@ #include "qgsmaptoolnodetool.h" #include "qgsmaptoolpan.h" #include "qgsmaptoolselect.h" +#include "qgsmaptoolselectrectangle.h" +#include "qgsmaptoolselectfreehand.h" +#include "qgsmaptoolselectpolygon.h" +#include "qgsmaptoolselectradius.h" #include "qgsmaptoolreshape.h" #include "qgsmaptoolrotatepointsymbols.h" #include "qgsmaptoolsplitfeatures.h" @@ -551,6 +555,10 @@ delete mMapTools.mReshapeFeatures; delete mMapTools.mSplitFeatures; delete mMapTools.mSelect; + delete mMapTools.mSelectRectangle; + delete mMapTools.mSelectPolygon; + delete mMapTools.mSelectFreehand; + delete mMapTools.mSelectRadius; #if 0 //these three tools to be deprecated - use node tool rather delete mMapTools.mVertexAdd; @@ -869,6 +877,30 @@ connect( mActionSelect, SIGNAL( triggered() ), this, SLOT( select() ) ); mActionSelect->setEnabled( false ); + mActionSelectRectangle = new QAction( getThemeIcon( "mActionSelectRectangle.png" ), tr( "Select features by rectangle" ), this ); + shortcuts->registerAction( mActionSelectRectangle ); + mActionSelectRectangle->setStatusTip( tr( "Select features by rectangle" ) ); + connect( mActionSelectRectangle, SIGNAL( triggered() ), this, SLOT( selectByRectangle() ) ); + mActionSelectRectangle->setEnabled( false ); + + mActionSelectPolygon = new QAction( getThemeIcon( "mActionSelectPolygon.png" ), tr( "Select features by polygon" ), this ); + shortcuts->registerAction( mActionSelectPolygon ); + mActionSelectPolygon->setStatusTip( tr( "Select features by polygon" ) ); + connect( mActionSelectPolygon, SIGNAL( triggered() ), this, SLOT( selectByPolygon() ) ); + mActionSelectPolygon->setEnabled( false ); + + mActionSelectFreehand = new QAction( getThemeIcon( "mActionSelectFreehand.png" ), tr( "Select features by freehand" ), this ); + shortcuts->registerAction( mActionSelectFreehand ); + mActionSelectFreehand->setStatusTip( tr( "Select features by freehand" ) ); + connect( mActionSelectFreehand, SIGNAL( triggered() ), this, SLOT( selectByFreehand() ) ); + mActionSelectFreehand->setEnabled( false ); + + mActionSelectRadius = new QAction( getThemeIcon( "mActionSelectRadius.png" ), tr( "Select features by radius" ), this ); + shortcuts->registerAction( mActionSelectRadius ); + mActionSelectRadius->setStatusTip( tr( "Select features by radius" ) ); + connect( mActionSelectRadius, SIGNAL( triggered() ), this, SLOT( selectByRadius() ) ); + mActionSelectRadius->setEnabled( false ); + mActionDeselectAll = new QAction( getThemeIcon( "mActionDeselectAll.png" ), tr( "Deselect features from all layers" ), this ); shortcuts->registerAction( mActionDeselectAll ); mActionDeselectAll->setStatusTip( tr( "Deselect features from all layers" ) ); @@ -1243,6 +1275,14 @@ mMapToolGroup->addAction( mActionIdentify ); mActionSelect->setCheckable( true ); mMapToolGroup->addAction( mActionSelect ); + mActionSelectRectangle->setCheckable( true ); + mMapToolGroup->addAction( mActionSelectRectangle ); + mActionSelectPolygon->setCheckable( true ); + mMapToolGroup->addAction( mActionSelectPolygon ); + mActionSelectFreehand->setCheckable( true ); + mMapToolGroup->addAction( mActionSelectFreehand ); + mActionSelectRadius->setCheckable( true ); + mMapToolGroup->addAction( mActionSelectRadius ); mActionDeselectAll->setCheckable( false ); mMapToolGroup->addAction( mActionDeselectAll ); mActionMeasure->setCheckable( true ); @@ -1408,13 +1448,19 @@ mViewMenu->addAction( mActionPan ); mViewMenu->addAction( mActionZoomIn ); mViewMenu->addAction( mActionZoomOut ); + mActionViewSeparator1 = mViewMenu->addSeparator(); mViewMenu->addAction( mActionSelect ); + mViewMenu->addAction( mActionSelectRectangle ); + mViewMenu->addAction( mActionSelectPolygon ); + mViewMenu->addAction( mActionSelectFreehand ); + mViewMenu->addAction( mActionSelectRadius ); mViewMenu->addAction( mActionDeselectAll ); + mActionViewSeparator2 = mViewMenu->addSeparator(); mViewMenu->addAction( mActionIdentify ); mViewMenu->addAction( mActionMeasure ); mViewMenu->addAction( mActionMeasureArea ); mViewMenu->addAction( mActionMeasureAngle ); - mActionViewSeparator1 = mViewMenu->addSeparator(); + mActionViewSeparator3 = mViewMenu->addSeparator(); mViewMenu->addAction( mActionZoomFullExtent ); mViewMenu->addAction( mActionZoomToLayer ); @@ -1422,7 +1468,7 @@ mViewMenu->addAction( mActionZoomLast ); mViewMenu->addAction( mActionZoomNext ); mViewMenu->addAction( mActionZoomActualSize ); - mActionViewSeparator2 = mViewMenu->addSeparator(); + mActionViewSeparator4 = mViewMenu->addSeparator(); mViewMenu->addAction( mActionMapTips ); mViewMenu->addAction( mActionNewBookmark ); @@ -1431,7 +1477,7 @@ if ( layout != QDialogButtonBox::KdeLayout ) { - mActionViewSeparator3 = mViewMenu->addSeparator(); + mActionViewSeparator5 = mViewMenu->addSeparator(); mViewMenu->addMenu( mPanelMenu ); mViewMenu->addMenu( mToolbarMenu ); mViewMenu->addAction( mActionToggleFullScreen ); @@ -1638,14 +1684,25 @@ mMapNavToolBar->addAction( mActionZoomNext ); mMapNavToolBar->addAction( mActionDraw ); mToolbarMenu->addAction( mMapNavToolBar->toggleViewAction() ); + // + // Feature Select Toolbar + mFeatureSelectToolBar = addToolBar( tr( "Select Tools" ) ); + mFeatureSelectToolBar->setIconSize( myIconSize ); + mFeatureSelectToolBar->setObjectName( "Select Tools" ); + mFeatureSelectToolBar->addAction( mActionIdentify ); + mFeatureSelectToolBar->addAction( mActionSelect ); + mFeatureSelectToolBar->addAction( mActionSelectRectangle ); + mFeatureSelectToolBar->addAction( mActionSelectPolygon ); + mFeatureSelectToolBar->addAction( mActionSelectFreehand ); + mFeatureSelectToolBar->addAction( mActionSelectRadius ); + mFeatureSelectToolBar->addAction( mActionDeselectAll ); + + // // Attributes Toolbar mAttributesToolBar = addToolBar( tr( "Attributes" ) ); mAttributesToolBar->setIconSize( myIconSize ); mAttributesToolBar->setObjectName( "Attributes" ); - mAttributesToolBar->addAction( mActionIdentify ); - mAttributesToolBar->addAction( mActionSelect ); - mAttributesToolBar->addAction( mActionDeselectAll ); mAttributesToolBar->addAction( mActionOpenTable ); mAttributesToolBar->addAction( mActionMeasure ); mAttributesToolBar->addAction( mActionMeasureArea ); @@ -1905,6 +1962,10 @@ mActionZoomToLayer->setIcon( getThemeIcon( "/mActionZoomToLayer.png" ) ); mActionIdentify->setIcon( getThemeIcon( "/mActionIdentify.png" ) ); mActionSelect->setIcon( getThemeIcon( "/mActionSelect.png" ) ); + mActionSelectRectangle->setIcon( getThemeIcon( "/mActionSelectRectangle.png" ) ); + mActionSelectPolygon->setIcon( getThemeIcon( "/mActionSelectPolygon.png" ) ); + mActionSelectFreehand->setIcon( getThemeIcon( "/mActionSelectFreehand.png" ) ); + mActionSelectRadius->setIcon( getThemeIcon( "/mActionSelectRadius.png" ) ); mActionDeselectAll->setIcon( getThemeIcon( "/mActionDeselectAll.png" ) ); mActionOpenTable->setIcon( getThemeIcon( "/mActionOpenTable.png" ) ); mActionMeasure->setIcon( getThemeIcon( "/mActionMeasure.png" ) ); @@ -2039,6 +2100,15 @@ mMapTools.mSplitFeatures->setAction( mActionSplitFeatures ); mMapTools.mSelect = new QgsMapToolSelect( mMapCanvas ); mMapTools.mSelect->setAction( mActionSelect ); + mMapTools.mSelectRectangle = new QgsMapToolSelectRectangle( mMapCanvas ); + mMapTools.mSelectRectangle->setAction( mActionSelectRectangle ); + mMapTools.mSelectPolygon = new QgsMapToolSelectPolygon( mMapCanvas ); + mMapTools.mSelectPolygon->setAction( mActionSelectPolygon ); + mMapTools.mSelectFreehand = new QgsMapToolSelectFreehand( mMapCanvas ); + mMapTools.mSelectFreehand->setAction( mActionSelectFreehand ); + mMapTools.mSelectRadius = new QgsMapToolSelectRadius( mMapCanvas ); + mMapTools.mSelectRadius->setAction( mActionSelectRadius ); + #if 0 //these three tools to be deprecated - use node tool rather mMapTools.mVertexAdd = new QgsMapToolAddVertex( mMapCanvas ); mMapTools.mVertexAdd->setAction( mActionAddVertex ); @@ -4399,6 +4491,26 @@ mMapCanvas->setMapTool( mMapTools.mSelect ); } +void QgisApp::selectByRectangle() +{ + mMapCanvas->setMapTool( mMapTools.mSelectRectangle ); +} + +void QgisApp::selectByPolygon() +{ + mMapCanvas->setMapTool( mMapTools.mSelectPolygon ); +} + +void QgisApp::selectByFreehand() +{ + mMapCanvas->setMapTool( mMapTools.mSelectFreehand ); +} + +void QgisApp::selectByRadius() +{ + mMapCanvas->setMapTool( mMapTools.mSelectRadius ); +} + void QgisApp::deselectAll() { if ( !mMapCanvas || mMapCanvas->isDrawing() ) @@ -5764,6 +5876,10 @@ if ( !layer ) { mActionSelect->setEnabled( false ); + mActionSelectRectangle->setEnabled( false ); + mActionSelectPolygon->setEnabled( false ); + mActionSelectFreehand->setEnabled( false ); + mActionSelectRadius->setEnabled( false ); mActionIdentify->setEnabled( QSettings().value( "/Map/identifyMode", 0 ).toInt() != 0 ); mActionZoomActualSize->setEnabled( false ); mActionOpenTable->setEnabled( false ); @@ -5817,6 +5933,10 @@ bool layerHasSelection = vlayer->selectedFeatureCount() != 0; mActionSelect->setEnabled( true ); + mActionSelectRectangle->setEnabled( true ); + mActionSelectPolygon->setEnabled( true ); + mActionSelectFreehand->setEnabled( true ); + mActionSelectRadius->setEnabled( true ); mActionIdentify->setEnabled( true ); mActionZoomActualSize->setEnabled( false ); mActionOpenTable->setEnabled( true ); @@ -6036,6 +6156,10 @@ { mActionLayerSubsetString->setEnabled( false ); mActionSelect->setEnabled( false ); + mActionSelectRectangle->setEnabled( false ); + mActionSelectPolygon->setEnabled( false ); + mActionSelectFreehand->setEnabled( false ); + mActionSelectRadius->setEnabled( false ); mActionZoomActualSize->setEnabled( true ); mActionOpenTable->setEnabled( false ); mActionToggleEditing->setEnabled( false ); Index: src/app/qgisapp.h =================================================================== --- src/app/qgisapp.h (revision 639) +++ src/app/qgisapp.h (working copy) @@ -244,6 +244,10 @@ QAction *actionZoomIn() { return mActionZoomIn; } QAction *actionZoomOut() { return mActionZoomOut; } QAction *actionSelect() { return mActionSelect; } + QAction *actionSelectRectangle() { return mActionSelectRectangle; } + QAction *actionSelectPolygon() { return mActionSelectPolygon; } + QAction *actionSelectFreehand() { return mActionSelectFreehand; } + QAction *actionSelectRadius() { return mActionSelectRadius; } QAction *actionIdentify() { return mActionIdentify; } QAction *actionMeasure() { return mActionMeasure; } QAction *actionMeasureArea() { return mActionMeasureArea; } @@ -592,6 +596,18 @@ //! activates the selection tool void select(); + //! activates the rectangle selection tool + void selectByRectangle(); + + //! activates the polygon selection tool + void selectByPolygon(); + + //! activates the freehand selection tool + void selectByFreehand(); + + //! activates the radius selection tool + void selectByRadius(); + //! deselect features from all layers void deselectAll(); @@ -804,6 +820,7 @@ QToolBar *mDigitizeToolBar; QToolBar *mAdvancedDigitizeToolBar; QToolBar *mAttributesToolBar; + QToolBar *mFeatureSelectToolBar; QToolBar *mPluginToolBar; QToolBar *mHelpToolBar; @@ -856,25 +873,31 @@ QAction *mActionPan; QAction *mActionZoomIn; QAction *mActionZoomOut; + QAction *mActionViewSeparator1; QAction *mActionSelect; + QAction *mActionSelectRectangle; + QAction *mActionSelectPolygon; + QAction *mActionSelectFreehand; + QAction *mActionSelectRadius; QAction *mActionDeselectAll; + QAction *mActionViewSeparator2; QAction *mActionIdentify; QAction *mActionMeasure; QAction *mActionMeasureAngle; QAction *mActionMeasureArea; - QAction *mActionViewSeparator1; + QAction *mActionViewSeparator3; QAction *mActionZoomFullExtent; QAction *mActionZoomToLayer; QAction *mActionZoomToSelected; QAction *mActionZoomLast; QAction *mActionZoomNext; QAction *mActionZoomActualSize; - QAction *mActionViewSeparator2; + QAction *mActionViewSeparator4; QAction *mActionMapTips; QAction *mActionNewBookmark; QAction *mActionShowBookmarks; QAction *mActionDraw; - QAction *mActionViewSeparator3; + QAction *mActionViewSeparator5; QAction *mActionTextAnnotation; QAction *mActionFormAnnotation; QAction *mActionAnnotation; @@ -985,6 +1008,10 @@ QgsMapTool* mReshapeFeatures; QgsMapTool* mSplitFeatures; QgsMapTool* mSelect; + QgsMapTool* mSelectRectangle; + QgsMapTool* mSelectPolygon; + QgsMapTool* mSelectFreehand; + QgsMapTool* mSelectRadius; QgsMapTool* mVertexAdd; QgsMapTool* mVertexMove; QgsMapTool* mVertexDelete; Index: src/app/qgisappinterface.cpp =================================================================== --- src/app/qgisappinterface.cpp (revision 639) +++ src/app/qgisappinterface.cpp (working copy) @@ -285,6 +285,10 @@ QAction *QgisAppInterface::actionZoomIn() { return qgis->actionZoomIn(); } QAction *QgisAppInterface::actionZoomOut() { return qgis->actionZoomOut(); } QAction *QgisAppInterface::actionSelect() { return qgis->actionSelect(); } +QAction *QgisAppInterface::actionSelectRectangle() { return qgis->actionSelectRectangle(); } +QAction *QgisAppInterface::actionSelectPolygon() { return qgis->actionSelectPolygon(); } +QAction *QgisAppInterface::actionSelectFreehand() { return qgis->actionSelectFreehand(); } +QAction *QgisAppInterface::actionSelectRadius() { return qgis->actionSelectRadius(); } QAction *QgisAppInterface::actionIdentify() { return qgis->actionIdentify(); } QAction *QgisAppInterface::actionMeasure() { return qgis->actionMeasure(); } QAction *QgisAppInterface::actionMeasureArea() { return qgis->actionMeasureArea(); } Index: src/app/qgisappinterface.h =================================================================== --- src/app/qgisappinterface.h (revision 639) +++ src/app/qgisappinterface.h (working copy) @@ -198,6 +198,10 @@ virtual QAction *actionZoomIn(); virtual QAction *actionZoomOut(); virtual QAction *actionSelect(); + virtual QAction *actionSelectRectangle(); + virtual QAction *actionSelectPolygon(); + virtual QAction *actionSelectFreehand(); + virtual QAction *actionSelectRadius(); virtual QAction *actionIdentify(); virtual QAction *actionMeasure(); virtual QAction *actionMeasureArea(); Index: src/app/qgsmaptoolselect.cpp =================================================================== --- src/app/qgsmaptoolselect.cpp (revision 639) +++ src/app/qgsmaptoolselect.cpp (working copy) @@ -1,5 +1,5 @@ /*************************************************************************** - qgsmaptoolselect.cpp - map tool for selecting features + qgsmaptoolselect.cpp - map tool for selecting features by single click ---------------------- begin : January 2006 copyright : (C) 2006 by Martin Dobias @@ -12,144 +12,43 @@ * (at your option) any later version. * * * ***************************************************************************/ -/* $Id: qgsmaptoolselect.cpp 13380 2010-04-25 12:51:49Z jef $ */ +/* $Id$ */ + #include "qgsmaptoolselect.h" +#include "qgsmaptoolselectutils.h" +#include "qgsrubberband.h" #include "qgsmapcanvas.h" -#include "qgsmaptopixel.h" #include "qgsvectorlayer.h" -#include "qgscsexception.h" -#include "qgscursors.h" -#include "qgslogger.h" +#include "qgsgeometry.h" +#include "qgspoint.h" #include "qgis.h" -#include -#include #include -#include #include QgsMapToolSelect::QgsMapToolSelect( QgsMapCanvas* canvas ) - : QgsMapTool( canvas ), mDragging( false ) +: QgsMapTool( canvas ) { - QPixmap mySelectQPixmap = QPixmap(( const char ** ) select_cursor ); - mCursor = QCursor( mySelectQPixmap, 1, 1 ); - mRubberBand = 0; + mCursor = Qt::ArrowCursor; } - -void QgsMapToolSelect::canvasPressEvent( QMouseEvent * e ) -{ - mSelectRect.setRect( 0, 0, 0, 0 ); -} - - -void QgsMapToolSelect::canvasMoveEvent( QMouseEvent * e ) -{ - if ( e->buttons() != Qt::LeftButton ) - return; - - if ( !mDragging ) - { - mDragging = true; - mRubberBand = new QRubberBand( QRubberBand::Rectangle, mCanvas ); - mSelectRect.setTopLeft( e->pos() ); - } - - mSelectRect.setBottomRight( e->pos() ); - mRubberBand->setGeometry( mSelectRect.normalized() ); - mRubberBand->show(); -} - - void QgsMapToolSelect::canvasReleaseEvent( QMouseEvent * e ) { - if ( !mCanvas->currentLayer() || - qobject_cast( mCanvas->currentLayer() ) == NULL ) + QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( mCanvas ); + if ( vlayer == NULL ) { - QMessageBox::warning( mCanvas, tr( "No active layer" ), - tr( "To select features, you must choose a " - "vector layer by clicking on its name in the legend" - ) ); return; } - QgsVectorLayer* vlayer = qobject_cast( mCanvas->currentLayer() ); - //if the user simply clicked without dragging a rect - //we will fabricate a small 1x1 pix rect and then continue - //as if they had dragged a rect - if ( !mDragging ) - { - int boxSize = 0; - if ( vlayer->geometryType() != QGis::Polygon ) - { - //if point or line use an artificial bounding box of 10x10 pixels - //to aid the user to click on a feature accurately - boxSize = 5; - } - else - { - //otherwise just use the click point for polys - boxSize = 1; - } - mSelectRect.setLeft( e->pos().x() - boxSize ); - mSelectRect.setRight( e->pos().x() + boxSize ); - mSelectRect.setTop( e->pos().y() - boxSize ); - mSelectRect.setBottom( e->pos().y() + boxSize ); - } - else - { - delete mRubberBand; - mRubberBand = 0; - - // Set valid values for rectangle's width and height - if ( mSelectRect.width() == 1 ) - { - mSelectRect.setLeft( mSelectRect.left() + 1 ); - } - if ( mSelectRect.height() == 1 ) - { - mSelectRect.setBottom( mSelectRect.bottom() + 1 ); - } - } - - mDragging = false; - - const QgsMapToPixel* transform = mCanvas->getCoordinateTransform(); - QgsPoint ll = transform->toMapCoordinates( mSelectRect.left(), mSelectRect.bottom() ); - QgsPoint ur = transform->toMapCoordinates( mSelectRect.right(), mSelectRect.top() ); - - QgsRectangle search( ll.x(), ll.y(), ur.x(), ur.y() ); - - // if Ctrl key is pressed, selected features will be flipped in selection - // instead of removing old selection - bool flip = ( e->modifiers() & Qt::ControlModifier ); - - // toLayerCoordinates will throw an exception for an 'invalid' rectangle. - // For example, if you project a world map onto a globe using EPSG 2163 - // and then click somewhere off the globe, an exception will be thrown. - try - { - search = toLayerCoordinates( vlayer, search ); - } - catch ( QgsCsException &cse ) - { - Q_UNUSED( cse ); - // catch exception for 'invalid' rectangle and leave existing selection unchanged - QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); - QMessageBox::warning( mCanvas, tr( "CRS Exception" ), - tr( "Selection extends beyond layer's coordinate system." ) ); - return; - } - - QApplication::setOverrideCursor( Qt::WaitCursor ); - if ( flip ) - { - vlayer->invertSelectionInRectangle( search ); - } - else - { - vlayer->select( search, false ); - } - QApplication::restoreOverrideCursor(); + QgsRubberBand rubberBand( mCanvas, true ); + QRect selectRect(0, 0, 0, 0); + QgsMapToolSelectUtils::expandSelectRectangle( selectRect, vlayer, e->pos() ); + QgsMapToolSelectUtils::setRubberBand( mCanvas, selectRect, &rubberBand ); + QgsGeometry* selectGeom = rubberBand.asGeometry(); + bool addSelection = e->modifiers() & Qt::ControlModifier ? true : false; + bool substractSelection = e->modifiers() & Qt::ShiftModifier ? true : false; + QgsMapToolSelectUtils::setSelectFeatures( mCanvas, selectGeom, false, addSelection, substractSelection, true ); + delete selectGeom; + rubberBand.reset( true ); } Property changes on: src\app\qgsmaptoolselect.cpp ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselect.h =================================================================== --- src/app/qgsmaptoolselect.h (revision 639) +++ src/app/qgsmaptoolselect.h (working copy) @@ -1,9 +1,9 @@ /*************************************************************************** - qgsmaptoolselect.h - map tool for selecting features + qgsmaptoolselect.h - map tool for selecting features by single click --------------------- - begin : January 2006 - copyright : (C) 2006 by Martin Dobias - email : wonder.sk at gmail dot com + begin : May 2010 + copyright : (C) 2010 by Jeremy Palmer + email : jpalmer at linz dot govt dot nz *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * @@ -12,45 +12,26 @@ * (at your option) any later version. * * * ***************************************************************************/ -/* $Id: qgsmaptoolselect.h 13187 2010-03-28 22:14:44Z jef $ */ +/* $Id$ */ #ifndef QGSMAPTOOLSELECT_H #define QGSMAPTOOLSELECT_H #include "qgsmaptool.h" -#include - -class QRubberBand; class QgsMapCanvas; +class QMouseEvent; - class QgsMapToolSelect : public QgsMapTool { - Q_OBJECT - public: - QgsMapToolSelect( QgsMapCanvas* canvas ); + Q_OBJECT +public: + QgsMapToolSelect( QgsMapCanvas* canvas ); - //! Overridden mouse move event - virtual void canvasMoveEvent( QMouseEvent * e ); + //! Overridden mouse release event + virtual void canvasReleaseEvent( QMouseEvent * e ); - //! Overridden mouse press event - virtual void canvasPressEvent( QMouseEvent * e ); - - //! Overridden mouse release event - virtual void canvasReleaseEvent( QMouseEvent * e ); - - - protected: - - //! stores actual select rect - QRect mSelectRect; - - //! Flag to indicate a map canvas drag operation is taking place - bool mDragging; - - //! rubber band for select rect - QRubberBand* mRubberBand; +private: }; #endif Property changes on: src\app\qgsmaptoolselect.h ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectfreehand.cpp =================================================================== --- src/app/qgsmaptoolselectfreehand.cpp (revision 0) +++ src/app/qgsmaptoolselectfreehand.cpp (revision 0) @@ -0,0 +1,80 @@ +/*************************************************************************** +qgsmaptoolselectfreehand.cpp - map tool for selecting features by freehand +--------------------- +begin : May 2010 +copyright : (C) 2010 by Jeremy Palmer +email : jpalmer at linz dot govt dot nz +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ +/* $Id$ */ + +#include "qgsmaptoolselectfreehand.h" +#include "qgsmaptoolselectutils.h" +#include "qgsgeometry.h" +#include "qgsrubberband.h" +#include "qgsmapcanvas.h" +#include "qgis.h" + +#include + + +QgsMapToolSelectFreehand::QgsMapToolSelectFreehand( QgsMapCanvas* canvas ) + : QgsMapTool( canvas ) +{ + mRubberBand = 0; + mCursor = Qt::ArrowCursor; +} + +QgsMapToolSelectFreehand::~QgsMapToolSelectFreehand() +{ + delete mRubberBand; +} + +void QgsMapToolSelectFreehand::canvasPressEvent( QMouseEvent * e ) +{ + if ( e->button() != Qt::LeftButton ) + { + return; + } + if ( mRubberBand == NULL ) + { + mRubberBand = new QgsRubberBand( mCanvas, true ); + } + mRubberBand->addPoint( toMapCoordinates( e->pos() ) ); + mDragging = true; +} + + +void QgsMapToolSelectFreehand::canvasMoveEvent( QMouseEvent * e ) +{ + if ( !mDragging || mRubberBand == NULL ) + { + return; + } + mRubberBand->addPoint( toMapCoordinates( e->pos() ) ); +} + + +void QgsMapToolSelectFreehand::canvasReleaseEvent( QMouseEvent * e ) +{ + if ( mRubberBand == NULL ) + { + return; + } + if ( mRubberBand->numberOfVertices() > 2 ) + { + QgsGeometry* shapeGeom = mRubberBand->asGeometry(); + QgsMapToolSelectUtils::setSelectFeatures( mCanvas, shapeGeom, e ); + delete shapeGeom; + } + mRubberBand->reset( true ); + delete mRubberBand; + mRubberBand = 0; + mDragging = false; +} Property changes on: src\app\qgsmaptoolselectfreehand.cpp ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectfreehand.h =================================================================== --- src/app/qgsmaptoolselectfreehand.h (revision 0) +++ src/app/qgsmaptoolselectfreehand.h (revision 0) @@ -0,0 +1,51 @@ +/*************************************************************************** + qgsmaptoolselectfreehand.h - map tool for selecting features by freehand + --------------------- + begin : May 2010 + copyright : (C) 2010 by Jeremy Palmer + email : jpalmer at linz dot govt dot nz + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* $Id$ */ + +#ifndef QGSMAPTOOLSELECTFREEHAND_H +#define QGSMAPTOOLSELECTFREEHAND_H + +#include "qgsmaptool.h" + +class QgsMapCanvas; +class QgsRubberBand; + + +class QgsMapToolSelectFreehand : public QgsMapTool +{ + Q_OBJECT + public: + QgsMapToolSelectFreehand( QgsMapCanvas* canvas ); + + virtual ~QgsMapToolSelectFreehand(); + + //! Overridden mouse move event + virtual void canvasMoveEvent( QMouseEvent * e ); + + //! Overridden mouse press event + virtual void canvasPressEvent( QMouseEvent * e ); + + //! Overridden mouse release event + virtual void canvasReleaseEvent( QMouseEvent * e ); + + private: + + //! used for storing all of the maps point for the freehand sketch + QgsRubberBand* mRubberBand; + + bool mDragging; +}; + +#endif Property changes on: src\app\qgsmaptoolselectfreehand.h ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectpolygon.cpp =================================================================== --- src/app/qgsmaptoolselectpolygon.cpp (revision 0) +++ src/app/qgsmaptoolselectpolygon.cpp (revision 0) @@ -0,0 +1,75 @@ +/*************************************************************************** +qgsmaptoolselectpolygon.cpp - map tool for selecting features by polygon +--------------------- +begin : May 2010 +copyright : (C) 2010 by Jeremy Palmer +email : jpalmer at linz dot govt dot nz +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ +/* $Id$ */ + +#include "qgsmaptoolselectpolygon.h" +#include "qgsmaptoolselectutils.h" +#include "qgsgeometry.h" +#include "qgsrubberband.h" +#include "qgsmapcanvas.h" +#include "qgis.h" + +#include + + +QgsMapToolSelectPolygon::QgsMapToolSelectPolygon( QgsMapCanvas* canvas ) +: QgsMapTool( canvas ) +{ + mRubberBand = 0; + mCursor = Qt::ArrowCursor; +} + +QgsMapToolSelectPolygon::~QgsMapToolSelectPolygon() +{ + delete mRubberBand; +} + +void QgsMapToolSelectPolygon::canvasPressEvent( QMouseEvent * e ) +{ + if ( mRubberBand == NULL ) + { + mRubberBand = new QgsRubberBand( mCanvas, true ); + } + if ( e->button() == Qt::LeftButton ) + { + mRubberBand->addPoint( toMapCoordinates( e->pos() ) ); + } + else + { + if ( mRubberBand->numberOfVertices() > 2 ) + { + QgsGeometry* polygonGeom = mRubberBand->asGeometry(); + QgsMapToolSelectUtils::setSelectFeatures( mCanvas, polygonGeom, e ); + delete polygonGeom; + } + mRubberBand->reset( true ); + delete mRubberBand; + mRubberBand = 0; + } +} + +void QgsMapToolSelectPolygon::canvasMoveEvent( QMouseEvent * e ) +{ + if ( mRubberBand == NULL ) + { + return; + } + if ( mRubberBand->numberOfVertices() > 0 ) + { + mRubberBand->removeLastPoint( 0 ); + mRubberBand->addPoint( toMapCoordinates( e->pos() ) ); + } +} + Property changes on: src\app\qgsmaptoolselectpolygon.cpp ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectpolygon.h =================================================================== --- src/app/qgsmaptoolselectpolygon.h (revision 0) +++ src/app/qgsmaptoolselectpolygon.h (revision 0) @@ -0,0 +1,46 @@ +/*************************************************************************** +qgsmaptoolselectpolygon.h - map tool for selecting features by polygon +--------------------- +begin : May 2010 +copyright : (C) 2010 by Jeremy Palmer +email : jpalmer at linz dot govt dot nz +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ +/* $Id$ */ + +#ifndef QGSMAPTOOLSELECTPOLYGON_H +#define QGSMAPTOOLSELECTPOLYGON_H + +#include "qgsmaptool.h" + +class QgsMapCanvas; +class QgsRubberBand; + + +class QgsMapToolSelectPolygon : public QgsMapTool +{ + Q_OBJECT +public: + QgsMapToolSelectPolygon( QgsMapCanvas* canvas ); + + virtual ~QgsMapToolSelectPolygon(); + + //! Overridden mouse move event + virtual void canvasMoveEvent( QMouseEvent * e ); + + //! Overridden mouse press event + virtual void canvasPressEvent( QMouseEvent * e ); + +private: + + //! used for storing all of the maps point for the polygon + QgsRubberBand* mRubberBand; +}; + +#endif Property changes on: src\app\qgsmaptoolselectpolygon.h ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectradius.cpp =================================================================== --- src/app/qgsmaptoolselectradius.cpp (revision 0) +++ src/app/qgsmaptoolselectradius.cpp (revision 0) @@ -0,0 +1,112 @@ +/*************************************************************************** +qgsmaptoolselectradius.cpp - map tool for selecting features by radius +--------------------- +begin : May 2010 +copyright : (C) 2010 by Jeremy Palmer +email : jpalmer at linz dot govt dot nz +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ +/* $Id$ */ + +#include "qgsmaptoolselectradius.h" +#include "qgsmaptoolselectutils.h" +#include "qgsgeometry.h" +#include "qgsrubberband.h" +#include "qgsmapcanvas.h" +#include "qgis.h" +#include "qgslogger.h" + +#include +#include + +#ifndef M_PI +#define M_PI 3.1415926535897931159979634685 +#endif + +const int RADIUS_SEGMENTS = 40; + +QgsMapToolSelectRadius::QgsMapToolSelectRadius( QgsMapCanvas* canvas ) +: QgsMapTool( canvas ), mDragging( false ) +{ + mRubberBand = 0; + mCursor = Qt::ArrowCursor; +} + +QgsMapToolSelectRadius::~QgsMapToolSelectRadius() +{ + delete mRubberBand; +} + +void QgsMapToolSelectRadius::canvasPressEvent( QMouseEvent * e ) +{ + if ( e->button() != Qt::LeftButton ) + { + return; + } + mRadiusCenter = toMapCoordinates( e->pos() ); +} + + +void QgsMapToolSelectRadius::canvasMoveEvent( QMouseEvent * e ) +{ + if ( e->buttons() != Qt::LeftButton ) + { + return; + } + if ( !mDragging ) + { + if ( mRubberBand == NULL ) + { + mRubberBand = new QgsRubberBand( mCanvas, true ); + } + mDragging = true; + } + QgsPoint radiusEdge = toMapCoordinates( e->pos() ); + setRadiusRubberBand( radiusEdge ); +} + + +void QgsMapToolSelectRadius::canvasReleaseEvent( QMouseEvent * e ) +{ + if ( e->button() != Qt::LeftButton ) + { + return; + } + if ( !mDragging ) + { + if ( mRubberBand == NULL ) + { + mRubberBand = new QgsRubberBand( mCanvas, true ); + } + mRadiusCenter = toMapCoordinates( e->pos() ); + QgsPoint radiusEdge = toMapCoordinates( QPoint( e->pos().x() + 1, e->pos().y() + 1 ) ); + setRadiusRubberBand( radiusEdge ); + } + QgsGeometry* radiusGeometry = mRubberBand->asGeometry(); + QgsMapToolSelectUtils::setSelectFeatures( mCanvas, radiusGeometry, e ); + delete radiusGeometry; + mRubberBand->reset( true ); + delete mRubberBand; + mRubberBand = 0; + mDragging = false; +} + + +void QgsMapToolSelectRadius::setRadiusRubberBand( QgsPoint & radiusEdge ) +{ + double r = sqrt( mRadiusCenter.sqrDist( radiusEdge ) ); + mRubberBand->reset( true ); + for ( int i = 0; i <= RADIUS_SEGMENTS; ++i ) + { + double theta = i * ( 2.0 * M_PI / RADIUS_SEGMENTS ); + QgsPoint radiusPoint( mRadiusCenter.x() + r * cos( theta ), + mRadiusCenter.y() + r * sin( theta ) ); + mRubberBand->addPoint( radiusPoint ); + } +} Property changes on: src\app\qgsmaptoolselectradius.cpp ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectradius.h =================================================================== --- src/app/qgsmaptoolselectradius.h (revision 0) +++ src/app/qgsmaptoolselectradius.h (revision 0) @@ -0,0 +1,60 @@ +/*************************************************************************** +qgsmaptoolselectradius.h - map tool for selecting features by radius +--------------------- +begin : May 2010 +copyright : (C) 2010 by Jeremy Palmer +email : jpalmer at linz dot govt dot nz +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ +/* $Id$ */ + +#ifndef QGSMAPTOOLSELECTRADIUS_H +#define QGSMAPTOOLSELECTRADIUS_H + + +#include "qgsmaptool.h" +#include "qgspoint.h" + +class QgsMapCanvas; +class QgsRubberBand; + + +class QgsMapToolSelectRadius : public QgsMapTool +{ + Q_OBJECT +public: + QgsMapToolSelectRadius( QgsMapCanvas* canvas ); + + virtual ~QgsMapToolSelectRadius(); + + //! Overridden mouse move event + virtual void canvasMoveEvent( QMouseEvent * e ); + + //! Overridden mouse press event + virtual void canvasPressEvent( QMouseEvent * e ); + + //! Overridden mouse release event + virtual void canvasReleaseEvent( QMouseEvent * e ); + +private: + + //! sets the rubber band to a circle approximated using 40 segments. + // The radius center point is defined in the canvasPressEvent event. + void setRadiusRubberBand( QgsPoint & radiusEdge ); + + //! used for storing all of the maps point for the polygon + QgsRubberBand* mRubberBand; + + //! Center point for the radius + QgsPoint mRadiusCenter; + + bool mDragging; +}; + +#endif Property changes on: src\app\qgsmaptoolselectradius.h ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectrectangle.cpp =================================================================== --- src/app/qgsmaptoolselectrectangle.cpp (revision 0) +++ src/app/qgsmaptoolselectrectangle.cpp (revision 0) @@ -0,0 +1,101 @@ +/*************************************************************************** + qgsmaptoolselectrectangle.cpp - map tool for selecting features by + rectangle + ---------------------- + begin : January 2006 + copyright : (C) 2006 by Martin Dobias + email : wonder.sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* $Id: qgsmaptoolselectrangle.cpp 13380 2010-04-25 12:51:49Z jef $ */ + +#include "qgsmaptoolselectrectangle.h" +#include "qgsmaptoolselectutils.h" +#include "qgsrubberband.h" +#include "qgsmapcanvas.h" +#include "qgsmaptopixel.h" +#include "qgsvectorlayer.h" +#include "qgscursors.h" +#include "qgsgeometry.h" +#include "qgspoint.h" +#include "qgis.h" + +#include +#include + + +QgsMapToolSelectRectangle::QgsMapToolSelectRectangle( QgsMapCanvas* canvas ) + : QgsMapTool( canvas ), mDragging( false ) +{ + QPixmap mySelectQPixmap = QPixmap(( const char ** ) select_cursor ); + mCursor = QCursor( mySelectQPixmap, 1, 1 ); + mRubberBand = 0; +} + + +void QgsMapToolSelectRectangle::canvasPressEvent( QMouseEvent * e ) +{ + mSelectRect.setRect( 0, 0, 0, 0 ); + mRubberBand = new QgsRubberBand( mCanvas, true ); +} + + +void QgsMapToolSelectRectangle::canvasMoveEvent( QMouseEvent * e ) +{ + if ( e->buttons() != Qt::LeftButton ) + return; + + if ( !mDragging ) + { + mDragging = true; + mSelectRect.setTopLeft( e->pos() ); + } + mSelectRect.setBottomRight( e->pos() ); + QgsMapToolSelectUtils::setRubberBand( mCanvas, mSelectRect, mRubberBand ); +} + + +void QgsMapToolSelectRectangle::canvasReleaseEvent( QMouseEvent * e ) +{ + QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( mCanvas ); + if ( vlayer == NULL ) + { + return; + } + + //if the user simply clicked without dragging a rect + //we will fabricate a small 1x1 pix rect and then continue + //as if they had dragged a rect + if ( !mDragging ) + { + QgsMapToolSelectUtils::expandSelectRectangle( mSelectRect, vlayer, e->pos() ); + } + else + { + // Set valid values for rectangle's width and height + if ( mSelectRect.width() == 1 ) + { + mSelectRect.setLeft( mSelectRect.left() + 1 ); + } + if ( mSelectRect.height() == 1 ) + { + mSelectRect.setBottom( mSelectRect.bottom() + 1 ); + } + } + + QgsMapToolSelectUtils::setRubberBand( mCanvas, mSelectRect, mRubberBand ); + QgsGeometry* selectGeom = mRubberBand->asGeometry(); + QgsMapToolSelectUtils::setSelectFeatures( mCanvas, selectGeom, e ); + delete selectGeom; + + mRubberBand->reset( true ); + delete mRubberBand; + mRubberBand = 0; + mDragging = false; +} Index: src/app/qgsmaptoolselectrectangle.h =================================================================== --- src/app/qgsmaptoolselectrectangle.h (revision 0) +++ src/app/qgsmaptoolselectrectangle.h (revision 0) @@ -0,0 +1,58 @@ +/*************************************************************************** + qgsmaptoolselectrectangle.h - map tool for selecting features by + rectangle + --------------------- + begin : January 2006 + copyright : (C) 2006 by Martin Dobias + email : wonder.sk at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* $Id: qgsmaptoolselectrectangle.h 13187 2010-03-28 22:14:44Z jef $ */ + +#ifndef QGSMAPTOOLRECTANGLE_H +#define QGSMAPTOOLRECTANGLE_H + +#include +#include "qgsmaptool.h" + +class QPoint; +class QMouseEvent; +class QgsMapCanvas; +class QgsVectorLayer; +class QgsGeometry; +class QgsRubberBand; + + +class QgsMapToolSelectRectangle : public QgsMapTool +{ + Q_OBJECT + public: + QgsMapToolSelectRectangle( QgsMapCanvas* canvas ); + + //! Overridden mouse move event + virtual void canvasMoveEvent( QMouseEvent * e ); + + //! Overridden mouse press event + virtual void canvasPressEvent( QMouseEvent * e ); + + //! Overridden mouse release event + virtual void canvasReleaseEvent( QMouseEvent * e ); + + private: + + //! Flag to indicate a map canvas drag operation is taking place + bool mDragging; + + //! stores actual select rect + QRect mSelectRect; + + QgsRubberBand* mRubberBand; +}; + +#endif Index: src/app/qgsmaptoolselectutils.cpp =================================================================== --- src/app/qgsmaptoolselectutils.cpp (revision 0) +++ src/app/qgsmaptoolselectutils.cpp (revision 0) @@ -0,0 +1,197 @@ +/*************************************************************************** +qgsmaptoolselectutils.cpp - Utility methods to help with select map tools +--------------------- +begin : May 2010 +copyright : (C) 2010 by Jeremy Palmer +email : jpalmer at linz dot govt dot nz +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ +/* $Id$ */ + +#include + +#include "qgsmaptoolselectutils.h" +#include "qgsmapcanvas.h" +#include "qgsvectorlayer.h" +#include "qgsfeature.h" +#include "qgsgeometry.h" +#include "qgsrubberband.h" +#include "qgscsexception.h" +#include "qgslogger.h" +#include "qgis.h" + +#include +#include +#include + +QgsVectorLayer* QgsMapToolSelectUtils::getCurrentVectorLayer( QgsMapCanvas* canvas ) +{ + QgsVectorLayer* vlayer = NULL; + if ( !canvas->currentLayer() + || ( vlayer = qobject_cast( canvas->currentLayer() ) ) == NULL ) + { + QMessageBox::warning( canvas, QObject::tr( "No active vector layer" ), + QObject::tr( "To select features, you must choose a " + "vector layer by clicking on its name in the legend" + ) ); + } + return vlayer; +} + +void QgsMapToolSelectUtils::setRubberBand( QgsMapCanvas* canvas, QRect& selectRect, QgsRubberBand* rubberBand ) +{ + const QgsMapToPixel* transform = canvas->getCoordinateTransform(); + QgsPoint ll = transform->toMapCoordinates( selectRect.left(), selectRect.bottom() ); + QgsPoint ur = transform->toMapCoordinates( selectRect.right(), selectRect.top() ); + rubberBand->reset( true ); + rubberBand->addPoint( ll, false ); + rubberBand->addPoint( QgsPoint( ur.x(), ll.y() ), false ); + rubberBand->addPoint( ur, false ); + rubberBand->addPoint( QgsPoint( ll.x(), ur.y() ), true ); +} + +void QgsMapToolSelectUtils::expandSelectRectangle( QRect& selectRect, + QgsVectorLayer* vlayer, + QPoint point ) +{ + int boxSize = 0; + if ( vlayer->geometryType() != QGis::Polygon ) + { + //if point or line use an artificial bounding box of 10x10 pixels + //to aid the user to click on a feature accurately + boxSize = 5; + } + else + { + //otherwise just use the click point for polys + boxSize = 1; + } + selectRect.setLeft( point.x() - boxSize ); + selectRect.setRight( point.x() + boxSize ); + selectRect.setTop( point.y() - boxSize ); + selectRect.setBottom( point.y() + boxSize ); +} + +void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas, + QgsGeometry* selectGeometry, + bool doContains, + bool addSelection, + bool substractSelection, + bool singleSelect ) +{ + if ( selectGeometry->type() != QGis::Polygon ) + { + return; + } + QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas ); + if ( vlayer == NULL ) + { + return; + } + + // toLayerCoordinates will throw an exception for any 'invalid' points in + // the rubber band. + // For example, if you project a world map onto a globe using EPSG 2163 + // and then click somewhere off the globe, an exception will be thrown. + QgsGeometry selectGeomTrans( *selectGeometry ); + try + { + QgsCoordinateTransform ct( canvas->mapRenderer()->destinationSrs(), vlayer->crs() ); + selectGeomTrans.transform( ct ); + } + catch ( QgsCsException &cse ) + { + Q_UNUSED( cse ); + // catch exception for 'invalid' point and leave existing selection unchanged + QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); + QMessageBox::warning( canvas, QObject::tr( "CRS Exception" ), + QObject::tr( "Selection extends beyond layer's coordinate system." ) ); + return; + } + + QApplication::setOverrideCursor( Qt::WaitCursor ); + + QgsDebugMsg( "Selection layer: " + vlayer->name() ); + QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() ); + QgsDebugMsg( "doContains: " + QString( doContains? "T" : "F") ); + QgsDebugMsg( "addSelection: " + QString( addSelection? "T" : "F") ); + QgsDebugMsg( "substractSelection: " + QString( substractSelection? "T" : "F") ); + + vlayer->select( QgsAttributeList(), selectGeomTrans.boundingBox(), true, true ); + + QgsFeatureIds newSelectedFeatures; + QgsFeature f; + int closestFeatureId = 0; + double closestFeatureDist = std::numeric_limits::max(); + while ( vlayer->nextFeature( f ) ) + { + QgsGeometry* g = f.geometry(); + if ( doContains && !selectGeomTrans.contains( g ) ) + { + continue; + } + if ( singleSelect ) + { + double distance = g->distance( selectGeomTrans ); + if ( distance <= closestFeatureDist ) + { + closestFeatureDist = distance; + closestFeatureId = f.id(); + } + } + else + { + newSelectedFeatures.insert( f.id() ); + } + } + if ( singleSelect && closestFeatureId > 0 ) + { + newSelectedFeatures.insert( closestFeatureId ); + } + + QgsDebugMsg( "Number of selected features: " + QString::number( newSelectedFeatures.size() ) ); + + QgsFeatureIds layerSelectedFeatures; + if ( addSelection ) + { + layerSelectedFeatures = vlayer->selectedFeaturesIds(); + QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd(); + while ( i != newSelectedFeatures.constBegin() ) { + --i; + layerSelectedFeatures.insert( *i ); + } + } + else if ( substractSelection ) + { + layerSelectedFeatures = vlayer->selectedFeaturesIds(); + QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd(); + while ( i != newSelectedFeatures.constBegin() ) { + --i; + if ( layerSelectedFeatures.contains( *i ) ) + { + layerSelectedFeatures.remove( *i ); + } + } + } + else + { + layerSelectedFeatures = newSelectedFeatures; + } + vlayer->setSelectedFeatures( layerSelectedFeatures ); + + QApplication::restoreOverrideCursor(); +} + +void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, QMouseEvent * e ) +{ + bool doContains = e->modifiers() & Qt::AltModifier ? false : true; + bool addSelection = e->modifiers() & Qt::ControlModifier ? true : false; + bool substractSelection = e->modifiers() & Qt::ShiftModifier ? true : false; + setSelectFeatures( canvas, selectGeometry, doContains, addSelection, substractSelection ); +} Property changes on: src\app\qgsmaptoolselectutils.cpp ___________________________________________________________________ Added: svn:keywords + Id Index: src/app/qgsmaptoolselectutils.h =================================================================== --- src/app/qgsmaptoolselectutils.h (revision 0) +++ src/app/qgsmaptoolselectutils.h (revision 0) @@ -0,0 +1,91 @@ +/*************************************************************************** +qgsmaptoolselectutils.h - Utility methods to help with select map tools +--------------------- +begin : May 2010 +copyright : (C) 2010 by Jeremy Palmer +email : jpalmer at linz dot govt dot nz +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ +/* $Id$ */ + +#ifndef QGSMAPTOOLSELECTUTILS_H +#define QGSMAPTOOLSELECTUTILS_H + +#include +#include +#include + +class QMouseEvent; +class QgsMapCanvas; +class QgsVectorLayer; +class QgsGeometry; +class QgsRubberBand; + +/** + Namespace containing methods which are useful for the select maptool widgets + */ +namespace QgsMapToolSelectUtils +{ + /** + Selects the features within currently selected layer. + @param canvas The map canvas used to get the current selected vector layer and + for any required geometry transformations + @param selectGeometry The geometry to select the layers features. This geometry + must be in terms of the canvas coordinate system. + @param doContains Features will only be selected if contained within the + selection rubber band. + @param addSelection New selected features will be added to the layer's + currently selected features. + @param substractSelection New selected features will be subtracted from + the layer's currently selected features. + @param singleSelect Only selects the closest feature to the selectGeometry. + */ + void setSelectFeatures( QgsMapCanvas* canvas, + QgsGeometry* selectGeometry, + bool doContains = true, + bool addSelection = false, + bool substractSelection = false, + bool singleSelect = false ); + + /** + Select the features within currently selected layer. + @param canvas The map canvas used to get the current selected vector layer and + for any required geometry transformations + @param selectGeometry The geometry to select the layers features. This geometry + must be in terms of the canvas coordinate system. + @param e MouseEvents are used to determine the current selection + operations (add, subtract, contains) + */ + void setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, QMouseEvent * e ); + + /** + Get the current selected canvas map layer. Returns NULL if it is not a vector layer + @param canvas The map canvas used for getting the current layer + @return QgsVectorLayer The layer + */ + QgsVectorLayer* getCurrentVectorLayer( QgsMapCanvas* canvas ); + + /** + Expands a rectangle to a minimum size for selection based on the vector layer type + @param selectRect The QRect to expand + @param vlayer The vector layer layer + @param vlayer The point to expand the rectangle around + */ + void expandSelectRectangle( QRect& selectRect, QgsVectorLayer* vlayer, const QPoint point ); + + /** + Sets a QgsRubberband to rectangle in map units using a rectangle defined in device coords + @param canvas The map canvas used to transform the rectangle into map units + @param selectRect The input rectangle in device coords + @param rubberBand The rubberband that will be set in map units using the input rectangle + */ + void setRubberBand( QgsMapCanvas* canvas, QRect& selectRect, QgsRubberBand* rubberBand ); +} + +#endif Property changes on: src\app\qgsmaptoolselectutils.h ___________________________________________________________________ Added: svn:keywords + Id Index: src/gui/qgisinterface.h =================================================================== --- src/gui/qgisinterface.h (revision 639) +++ src/gui/qgisinterface.h (working copy) @@ -239,6 +239,10 @@ virtual QAction *actionZoomIn() = 0; virtual QAction *actionZoomOut() = 0; virtual QAction *actionSelect() = 0; + virtual QAction *actionSelectRectangle() = 0; + virtual QAction *actionSelectPolygon() = 0; + virtual QAction *actionSelectFreehand() = 0; + virtual QAction *actionSelectRadius() = 0; virtual QAction *actionIdentify() = 0; virtual QAction *actionMeasure() = 0; virtual QAction *actionMeasureArea() = 0; Index: src/gui/qgsrubberband.cpp =================================================================== --- src/gui/qgsrubberband.cpp (revision 639) +++ src/gui/qgsrubberband.cpp (working copy) @@ -431,3 +431,50 @@ else return 0; } + +QgsGeometry *QgsRubberBand::asGeometry() +{ + QgsGeometry *geom = NULL; + if ( mIsPolygon ) + { + QgsPolygon polygon; + QList>::const_iterator it = mPoints.constBegin(); + for ( ; it != mPoints.constEnd(); ++it ) + { + polygon.append( getPolyline( *it ) ); + } + geom = QgsGeometry::fromPolygon( polygon ); + } + else + { + if ( mPoints.size() > 0 ) + { + if ( mPoints.size() > 1 ) + { + QgsMultiPolyline multiPolyline; + QList>::const_iterator it = mPoints.constBegin(); + for ( ; it != mPoints.constEnd(); ++it ) + { + multiPolyline.append( getPolyline( *it ) ); + } + geom = QgsGeometry::fromMultiPolyline( multiPolyline ); + } + else + { + geom = QgsGeometry::fromPolyline( getPolyline( mPoints[0] ) ); + } + } + } + return geom; +} + +QgsPolyline QgsRubberBand::getPolyline( const QList & points ) +{ + QgsPolyline polyline; + QList::const_iterator iter = points.constBegin(); + for ( ; iter != points.constEnd(); ++iter ) + { + polyline.append( *iter ); + } + return polyline; +} Index: src/gui/qgsrubberband.h =================================================================== --- src/gui/qgsrubberband.h (revision 639) +++ src/gui/qgsrubberband.h (working copy) @@ -17,12 +17,12 @@ #define QGSRUBBERBAND_H #include "qgsmapcanvasitem.h" +#include "qgsgeometry.h" #include #include #include #include -class QgsGeometry; class QgsVectorLayer; class QPaintEvent; @@ -84,6 +84,10 @@ /**Return vertex*/ const QgsPoint *getPoint( int i, int j = 0 ) const; + /**Returns the rubberband as a Geometry. + * added in 1.5 */ + QgsGeometry* asGeometry(); + protected: virtual void paint( QPainter* p ); @@ -101,6 +105,9 @@ double mTranslationOffsetY; QgsRubberBand(); + + static QgsPolyline getPolyline( const QList & points ); + }; #endif