[QGIS Commit] r14071 - in trunk/qgis: images images/themes/default python/gui src/app src/gui src/plugins/coordinate_capture

svn_qgis at osgeo.org svn_qgis at osgeo.org
Thu Aug 12 12:59:57 EDT 2010


Author: jef
Date: 2010-08-12 16:59:57 +0000 (Thu, 12 Aug 2010)
New Revision: 14071

Added:
   trunk/qgis/images/themes/default/mActionSelectFreehand.png
   trunk/qgis/images/themes/default/mActionSelectPolygon.png
   trunk/qgis/images/themes/default/mActionSelectRadius.png
   trunk/qgis/images/themes/default/mActionSelectRectangle.png
   trunk/qgis/images/themes/default/selectTools.svg
   trunk/qgis/src/app/qgsmaptoolselectfreehand.cpp
   trunk/qgis/src/app/qgsmaptoolselectfreehand.h
   trunk/qgis/src/app/qgsmaptoolselectpolygon.cpp
   trunk/qgis/src/app/qgsmaptoolselectpolygon.h
   trunk/qgis/src/app/qgsmaptoolselectradius.cpp
   trunk/qgis/src/app/qgsmaptoolselectradius.h
   trunk/qgis/src/app/qgsmaptoolselectrectangle.cpp
   trunk/qgis/src/app/qgsmaptoolselectrectangle.h
   trunk/qgis/src/app/qgsmaptoolselectutils.cpp
   trunk/qgis/src/app/qgsmaptoolselectutils.h
Modified:
   trunk/qgis/images/images.qrc
   trunk/qgis/images/themes/default/mActionDeselectAll.png
   trunk/qgis/images/themes/default/mActionSelect.png
   trunk/qgis/python/gui/qgisinterface.sip
   trunk/qgis/python/gui/qgsrubberband.sip
   trunk/qgis/src/app/CMakeLists.txt
   trunk/qgis/src/app/qgisapp.cpp
   trunk/qgis/src/app/qgisapp.h
   trunk/qgis/src/app/qgisappinterface.cpp
   trunk/qgis/src/app/qgisappinterface.h
   trunk/qgis/src/app/qgsmaptoolselect.cpp
   trunk/qgis/src/app/qgsmaptoolselect.h
   trunk/qgis/src/gui/qgisinterface.h
   trunk/qgis/src/gui/qgsrubberband.cpp
   trunk/qgis/src/gui/qgsrubberband.h
   trunk/qgis/src/plugins/coordinate_capture/CMakeLists.txt
Log:
add advanced selection tools from Jeremy Palmer. Thanks. (apply #2938)

Modified: trunk/qgis/images/images.qrc
===================================================================
--- trunk/qgis/images/images.qrc	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/images/images.qrc	2010-08-12 16:59:57 UTC (rev 14071)
@@ -194,6 +194,10 @@
     <file>themes/default/mActionSaveMapAsImage.png</file>
     <file>themes/default/mActionScaleBar.png</file>
     <file>themes/default/mActionSelect.png</file>
+    <file>themes/default/mActionSelectRectangle.png</file>
+    <file>themes/default/mActionSelectFreehand.png</file>
+    <file>themes/default/mActionSelectPolygon.png</file>
+    <file>themes/default/mActionSelectRadius.png</file>
     <file>themes/default/mActionSelectedToTop.png</file>
     <file>themes/default/mActionSelectPan.png</file>
     <file>themes/default/mActionShowAllLayers.png</file>

Modified: trunk/qgis/images/themes/default/mActionDeselectAll.png
===================================================================
(Binary files differ)

Modified: trunk/qgis/images/themes/default/mActionSelect.png
===================================================================
(Binary files differ)

Added: trunk/qgis/images/themes/default/mActionSelectFreehand.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/images/themes/default/mActionSelectFreehand.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/images/themes/default/mActionSelectPolygon.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/images/themes/default/mActionSelectPolygon.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/images/themes/default/mActionSelectRadius.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/images/themes/default/mActionSelectRadius.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/images/themes/default/mActionSelectRectangle.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/images/themes/default/mActionSelectRectangle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/images/themes/default/selectTools.svg
===================================================================
--- trunk/qgis/images/themes/default/selectTools.svg	                        (rev 0)
+++ trunk/qgis/images/themes/default/selectTools.svg	2010-08-12 16:59:57 UTC (rev 14071)
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="128"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="selectTools.svg"
+   inkscape:export-filename="C:\Dev\SPI\QGIS\qgis_linz\images\themes\default\mActionDeselectAll.png"
+   inkscape:export-xdpi="22.5"
+   inkscape:export-ydpi="22.5"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0"
+   style="display:inline">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 64 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="128 : 64 : 1"
+       inkscape:persp3d-origin="64 : 42.666667 : 1"
+       id="perspective3673" />
+    <inkscape:perspective
+       id="perspective3683"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3632"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2849"
+       inkscape:persp3d-origin="200 : 133.33333 : 1"
+       inkscape:vp_z="400 : 200 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 200 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2862"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.0689466"
+     inkscape:cx="87.337091"
+     inkscape:cy="28.491338"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer3"
+     inkscape:window-width="1920"
+     inkscape:window-height="1181"
+     inkscape:window-x="1916"
+     inkscape:window-y="-4"
+     showgrid="false"
+     showguides="false"
+     inkscape:guide-bbox="true"
+     inkscape:window-maximized="1"
+     inkscape:snap-bbox="false">
+    <sodipodi:guide
+       orientation="0,1"
+       position="72.98243,80.487715"
+       id="guide3475" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="8.7993001,105.5916"
+       id="guide3477" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="119.04935,94.721877"
+       id="guide3479" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="62.889115,99.121527"
+       id="guide3481" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="16.045782,34.161988"
+       id="guide3483" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     id="layer18"
+     inkscape:label="geometry"
+     style="display:inline">
+    <path
+       sodipodi:nodetypes="cccccccccccccc"
+       id="path3651"
+       d="m 19.779996,17.509313 c -3.532055,4.322031 -7.342958,7.665491 -10.5961677,12.966093 -2.2307708,7.828585 3.0673117,23.241111 2.5096197,27.889335 1.022437,9.867278 -7.9935995,28.786358 -4.461544,35.473271 5.298083,6.442268 19.519255,13.373828 32.625039,14.189308 14.592967,-0.0815 26.676315,-0.89702 37.086584,-3.91428 12.362197,-6.279184 26.397473,-10.356568 37.086593,-18.837539 5.76282,-8.480967 0.92948,-16.961934 1.39422,-25.442901 1.20834,-9.622635 8.27245,-19.245272 3.62501,-28.867907 C 112.26408,22.483725 104.92113,16.204548 96.183935,12.127161 87.632642,9.7622757 80.75443,5.9295309 70.530057,5.0325056 59.469147,5.6848874 53.148627,6.5819127 49.61657,11.148587 c -5.018489,4.879529 -13.661982,2.909048 -20.632396,4.608214 -3.068059,0.584171 -1.953421,-0.788805 -9.204178,1.752512 z"
+       style="fill:#f9f5aa;fill-opacity:1;fill-rule:evenodd;stroke:#f7ff0e;stroke-width:9.08285809;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="polygon"
+     style="display:none">
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.5527215;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:9.10544312, 4.55272156;stroke-dashoffset:0.91054431;marker-start:none"
+       d="m 17.47589,31.218672 0,56.625225 82.65304,0 0,-34.88518 L 58.279291,7.9618805 17.47589,31.218672 z"
+       id="path3739"
+       sodipodi:nodetypes="cccccc" />
+  </g>
+  <g
+     style="display:none"
+     inkscape:label="rectangle"
+     id="g3353"
+     inkscape:groupmode="layer">
+    <rect
+       ry="4.2915325"
+       rx="3.7192686"
+       y="18.580549"
+       x="20.102806"
+       height="66.669243"
+       width="70.849724"
+       id="rect3357"
+       style="fill:none;stroke:#000000;stroke-width:4.85300016;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14.559, 4.853;stroke-dashoffset:0" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer4"
+     inkscape:label="freehand"
+     style="display:none">
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.85300016;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14.55900049, 4.85300016;stroke-dashoffset:0"
+       d="m 65.631777,19.622757 c 3.372249,2.334854 6.798968,4.534261 9.6239,7.493861 3.548394,1.422469 6.188971,4.211435 9.151571,6.404982 2.26531,2.776805 4.907746,5.034247 6.784489,7.925865 3.159939,2.920266 2.011006,6.867562 -0.715179,9.631059 -2.126962,2.305245 -4.955287,3.74761 -8.125686,4.296975 -3.456502,0.706393 -6.916555,1.400855 -10.371803,2.108626 -2.053947,3.955867 -6.051049,7.653779 -5.629434,12.251329 0.467619,3.008031 1.223448,6.242605 0.136154,9.094395 0.407152,1.920461 -1.049349,5.429071 -3.496388,7.483144 -1.754341,0.327918 -7.289292,1.888569 -4.324372,1.828724 -3.127392,1.409414 -6.690985,1.603867 -10.026642,2.438953 -2.480112,0.479602 -4.947038,1.045241 -7.425489,1.509628 -3.607438,-0.677375 -7.892266,-0.579686 -9.408378,-4.843976 -2.134562,-2.261195 -3.150972,-5.044904 -4.003804,-7.910423 -1.013951,-3.096434 -0.04344,-6.390682 1.873569,-8.917917 2.811686,-2.178519 4.140031,-4.626929 5.476315,-8.14662 0.913521,-3.585631 -0.937579,-7.955511 -5.086237,-8.4
 16383 -3.61114,-1.462893 -7.894018,-2.302632 -11.360052,-4.460891 -3.650399,-0.479435 -4.921101,-5.047635 -6.712353,-8.065664 -0.433468,-3.055139 -1.705333,-6.09 -1.535071,-9.142397 -0.4963948,-4.45055 2.458202,-6.675362 4.551653,-9.909291 3.013664,-3.080159 6.001773,-6.96011 10.451694,-7.848464 2.041769,-3.03077 5.891971,-3.511097 9.383844,-4.07197 2.365637,-0.298342 4.728099,-1.3569002 7.079018,-1.11044 3.713249,0.1535691 7.338273,2.214335 11.000028,3.581469 3.286492,2.625264 7.499402,2.579901 10.852758,5.636778 0.619669,0.384552 1.238165,0.770994 1.855895,1.158648 z"
+       id="path2835" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer1"
+     inkscape:label="circle"
+     style="display:none">
+    <path
+       sodipodi:type="arc"
+       style="fill:none;stroke:#000000;stroke-width:4.3162117;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12.9486357, 4.3162119;stroke-dashoffset:0;display:inline"
+       id="path3711"
+       sodipodi:cx="12.41272"
+       sodipodi:cy="10.343482"
+       sodipodi:rx="37.168804"
+       sodipodi:ry="37.168804"
+       d="m 49.581524,10.343482 a 37.168804,37.168804 0 1 1 -74.337608,0 37.168804,37.168804 0 1 1 74.337608,0 z"
+       transform="matrix(0.98001475,0,0,0.98001475,41.225852,38.703496)" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="deselect"
+     style="display:inline">
+    <path
+       style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:1.49048018;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="M 29.698339,52.423481 C 16.051712,52.698413 3.7408429,65.048573 4.6081639,78.953941 4.8817259,94.332694 20.485443,106.38102 35.480351,103.75189 49.274567,102.24135 60.320488,88.247365 57.669083,74.382603 55.631983,61.225586 42.881728,51.610763 29.698339,52.423481 z m 1.440284,7.723266 c 4.459556,-0.06984 8.968478,1.410814 12.419846,4.237359 -9.818417,7.003216 -19.85089,14.970704 -29.536271,21.374658 -4.7651221,-9.524832 1.348854,-21.773355 11.292666,-24.651827 1.880027,-0.607635 3.849567,-0.917354 5.823759,-0.96019 z m 17.408658,10.645582 c 5.037209,10.044615 -2.047165,22.890788 -12.83732,24.985806 -5.71851,1.360445 -11.98502,0.0904 -16.552835,-3.611148 9.772879,-7.044573 19.727298,-14.730417 29.390155,-21.374658 z"
+       id="path2834" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer5"
+     inkscape:label="single"
+     style="display:none">
+    <path
+       id="path1875"
+       style="fill:none;stroke:#414141;stroke-width:5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
+       d="m 54.856583,17.189923 4.11214,11.11022 10.36977,-5.8817 -3.99191,11.15397 11.72465,2.15947 -10.2281,5.97866 7.59343,9.1902 -11.67845,-1.99414 -0.0908,11.920741 -7.66432,-9.033851 -7.7326,9.073431 -0.064,-11.846531 -11.7562,1.98056 7.5663,-9.11608 -10.27893,-6.03903 11.65623,-2.12013 -3.99205,-11.23289 10.29207,5.86787 4.16277,-11.17077 z" />
+  </g>
+  <g
+     style="display:inline"
+     inkscape:label="cursor"
+     id="g3343"
+     inkscape:groupmode="layer">
+    <path
+       inkscape:export-filename="/Users/tim/dev/cpp/qgis/images/themes/default/mActionSelect.png"
+       inkscape:export-ydpi="21.652922"
+       inkscape:export-xdpi="21.652922"
+       sodipodi:nodetypes="cccccccc"
+       id="path3349"
+       d="M 65.601843,106.16511 53.904423,35.587576 118.53385,75.098555 94.614817,82.168858 120.52875,117.31634 108.41356,126.20813 83.079984,89.636153 65.601843,106.16511 z"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.87363958;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
+    <path
+       inkscape:export-ydpi="21.652922"
+       inkscape:export-xdpi="21.652922"
+       sodipodi:nodetypes="cccccccc"
+       id="path3351"
+       d="M 65.469806,103.68103 54.660978,36.602094 114.38086,74.154478 92.278819,80.874298 116.22422,114.27949 105.02935,122.73052 81.620226,87.971433 65.469806,103.68103 z"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#414141;stroke-width:3.63013959;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+  </g>
+</svg>

Modified: trunk/qgis/python/gui/qgisinterface.sip
===================================================================
--- trunk/qgis/python/gui/qgisinterface.sip	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/python/gui/qgisinterface.sip	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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;

Modified: trunk/qgis/python/gui/qgsrubberband.sip
===================================================================
--- trunk/qgis/python/gui/qgsrubberband.sip	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/python/gui/qgsrubberband.sip	2010-08-12 16:59:57 UTC (rev 14071)
@@ -57,6 +57,10 @@
 
     /**Return vertex*/
     const QgsPoint *getPoint(int i, int j=0) const;
+    
+    /**Returns the rubberband as a Geometry.
+    * added in 1.6 */
+    QgsGeometry* asGeometry();
 
   protected:
     virtual void paint(QPainter* p);

Modified: trunk/qgis/src/app/CMakeLists.txt
===================================================================
--- trunk/qgis/src/app/CMakeLists.txt	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/app/CMakeLists.txt	2010-08-12 16:59:57 UTC (rev 14071)
@@ -49,6 +49,11 @@
   qgsmaptoolreshape.cpp
   qgsmaptoolrotatepointsymbols.cpp
   qgsmaptoolselect.cpp
+  qgsmaptoolselectrectangle.cpp
+  qgsmaptoolselectfreehand.cpp
+  qgsmaptoolselectpolygon.cpp
+  qgsmaptoolselectradius.cpp
+  qgsmaptoolselectutils.cpp
   qgsmaptoolsimplify.cpp
   qgsmaptoolsplitfeatures.cpp
   qgsmaptooltextannotation.cpp
@@ -163,6 +168,10 @@
   qgsmaptoolreshape.h
   qgsmaptoolrotatepointsymbols.h
   qgsmaptoolselect.h
+  qgsmaptoolselectrectangle.h
+  qgsmaptoolselectfreehand.h
+  qgsmaptoolselectpolygon.h
+  qgsmaptoolselectradius.h
   qgsmaptooladdvertex.h
   qgsmaptooldeletering.h
   qgsmaptooldeletepart.h

Modified: trunk/qgis/src/app/qgisapp.cpp
===================================================================
--- trunk/qgis/src/app/qgisapp.cpp	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/app/qgisapp.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -201,6 +201,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"
@@ -559,6 +563,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;
@@ -877,6 +885,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" ) );
@@ -1254,6 +1286,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 );
@@ -1419,13 +1459,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 );
@@ -1433,7 +1479,7 @@
   mViewMenu->addAction( mActionZoomLast );
   mViewMenu->addAction( mActionZoomNext );
   mViewMenu->addAction( mActionZoomActualSize );
-  mActionViewSeparator2 = mViewMenu->addSeparator();
+  mActionViewSeparator4 = mViewMenu->addSeparator();
 
   mViewMenu->addAction( mActionMapTips );
   mViewMenu->addAction( mActionNewBookmark );
@@ -1442,7 +1488,7 @@
 
   if ( layout != QDialogButtonBox::KdeLayout )
   {
-    mActionViewSeparator3 = mViewMenu->addSeparator();
+    mActionViewSeparator5 = mViewMenu->addSeparator();
     mViewMenu->addMenu( mPanelMenu );
     mViewMenu->addMenu( mToolbarMenu );
     mViewMenu->addAction( mActionToggleFullScreen );
@@ -1650,14 +1696,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 );
@@ -1918,6 +1975,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" ) );
@@ -2058,6 +2119,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 +4469,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() )
@@ -5793,6 +5883,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 );
@@ -5846,6 +5940,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 );
@@ -6065,6 +6163,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 );

Modified: trunk/qgis/src/app/qgisapp.h
===================================================================
--- trunk/qgis/src/app/qgisapp.h	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/app/qgisapp.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -249,6 +249,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; }
@@ -611,6 +615,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();
 
@@ -828,6 +844,7 @@
     QToolBar *mDigitizeToolBar;
     QToolBar *mAdvancedDigitizeToolBar;
     QToolBar *mAttributesToolBar;
+    QToolBar *mFeatureSelectToolBar;
     QToolBar *mPluginToolBar;
     QToolBar *mHelpToolBar;
 
@@ -880,25 +897,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;
@@ -1010,6 +1033,10 @@
         QgsMapTool* mReshapeFeatures;
         QgsMapTool* mSplitFeatures;
         QgsMapTool* mSelect;
+        QgsMapTool* mSelectRectangle;
+        QgsMapTool* mSelectPolygon;
+        QgsMapTool* mSelectFreehand;
+        QgsMapTool* mSelectRadius;
         QgsMapTool* mVertexAdd;
         QgsMapTool* mVertexMove;
         QgsMapTool* mVertexDelete;

Modified: trunk/qgis/src/app/qgisappinterface.cpp
===================================================================
--- trunk/qgis/src/app/qgisappinterface.cpp	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/app/qgisappinterface.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -289,6 +289,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(); }

Modified: trunk/qgis/src/app/qgisappinterface.h
===================================================================
--- trunk/qgis/src/app/qgisappinterface.h	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/app/qgisappinterface.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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();

Modified: trunk/qgis/src/app/qgsmaptoolselect.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselect.cpp	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/app/qgsmaptoolselect.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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
@@ -14,142 +14,41 @@
  ***************************************************************************/
 /* $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 <QApplication>
-#include <QMessageBox>
 #include <QMouseEvent>
-#include <QRubberBand>
 #include <QRect>
 
 
 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<QgsVectorLayer *>( 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<QgsVectorLayer *>( 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 );
 }

Modified: trunk/qgis/src/app/qgsmaptoolselect.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselect.h	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/app/qgsmaptoolselect.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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  *
@@ -18,39 +18,20 @@
 #define QGSMAPTOOLSELECT_H
 
 #include "qgsmaptool.h"
-#include <QRect>
 
-
-class QRubberBand;
 class QgsMapCanvas;
+class QMouseEvent;
 
-
 class QgsMapToolSelect : public QgsMapTool
 {
     Q_OBJECT
   public:
     QgsMapToolSelect( 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 );
 
-
-  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

Added: trunk/qgis/src/app/qgsmaptoolselectfreehand.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectfreehand.cpp	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectfreehand.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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 <QMouseEvent>
+
+
+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;
+}

Added: trunk/qgis/src/app/qgsmaptoolselectfreehand.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectfreehand.h	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectfreehand.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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

Added: trunk/qgis/src/app/qgsmaptoolselectpolygon.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectpolygon.cpp	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectpolygon.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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 <QMouseEvent>
+
+
+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() ) );
+  }
+}
+

Added: trunk/qgis/src/app/qgsmaptoolselectpolygon.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectpolygon.h	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectpolygon.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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

Added: trunk/qgis/src/app/qgsmaptoolselectradius.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectradius.cpp	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectradius.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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 <cmath>
+#include <QMouseEvent>
+
+#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 );
+  }
+}

Added: trunk/qgis/src/app/qgsmaptoolselectradius.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectradius.h	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectradius.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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

Added: trunk/qgis/src/app/qgsmaptoolselectrectangle.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectrectangle.cpp	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectrectangle.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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 <QMouseEvent>
+#include <QRect>
+
+
+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;
+}

Added: trunk/qgis/src/app/qgsmaptoolselectrectangle.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectrectangle.h	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectrectangle.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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 <QRect>
+#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

Added: trunk/qgis/src/app/qgsmaptoolselectutils.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectutils.cpp	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectutils.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -0,0 +1,203 @@
+/***************************************************************************
+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 <limits>
+
+#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 <QMouseEvent>
+#include <QApplication>
+#include <QMessageBox>
+
+QgsVectorLayer* QgsMapToolSelectUtils::getCurrentVectorLayer( QgsMapCanvas* canvas )
+{
+  QgsVectorLayer* vlayer = NULL;
+  if ( !canvas->currentLayer()
+       || ( vlayer = qobject_cast<QgsVectorLayer *>( 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 );
+
+  if ( canvas->mapRenderer()->hasCrsTransformEnabled() )
+  {
+    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<double>::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 );
+}

Added: trunk/qgis/src/app/qgsmaptoolselectutils.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolselectutils.h	                        (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolselectutils.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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 <Qt>
+#include <QRect>
+#include <QPoint>
+
+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

Modified: trunk/qgis/src/gui/qgisinterface.h
===================================================================
--- trunk/qgis/src/gui/qgisinterface.h	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/gui/qgisinterface.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -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;

Modified: trunk/qgis/src/gui/qgsrubberband.cpp
===================================================================
--- trunk/qgis/src/gui/qgsrubberband.cpp	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/gui/qgsrubberband.cpp	2010-08-12 16:59:57 UTC (rev 14071)
@@ -431,3 +431,50 @@
   else
     return 0;
 }
+
+QgsGeometry *QgsRubberBand::asGeometry()
+{
+  QgsGeometry *geom = NULL;
+  if ( mIsPolygon )
+  {
+    QgsPolygon polygon;
+    QList<QList<QgsPoint>>::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<QList<QgsPoint>>::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<QgsPoint> & points )
+{
+  QgsPolyline polyline;
+  QList<QgsPoint>::const_iterator iter = points.constBegin();
+  for ( ; iter != points.constEnd(); ++iter )
+  {
+    polyline.append( *iter );
+  }
+  return polyline;
+}

Modified: trunk/qgis/src/gui/qgsrubberband.h
===================================================================
--- trunk/qgis/src/gui/qgsrubberband.h	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/gui/qgsrubberband.h	2010-08-12 16:59:57 UTC (rev 14071)
@@ -17,12 +17,12 @@
 #define QGSRUBBERBAND_H
 
 #include "qgsmapcanvasitem.h"
+#include "qgsgeometry.h"
 #include <QBrush>
 #include <QList>
 #include <QPen>
 #include <QPolygon>
 
-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.6 */
+    QgsGeometry* asGeometry();
+
   protected:
     virtual void paint( QPainter* p );
 
@@ -101,6 +105,9 @@
     double mTranslationOffsetY;
 
     QgsRubberBand();
+
+    static QgsPolyline getPolyline( const QList<QgsPoint> & points );
+
 };
 
 #endif

Modified: trunk/qgis/src/plugins/coordinate_capture/CMakeLists.txt
===================================================================
--- trunk/qgis/src/plugins/coordinate_capture/CMakeLists.txt	2010-08-12 14:14:11 UTC (rev 14070)
+++ trunk/qgis/src/plugins/coordinate_capture/CMakeLists.txt	2010-08-12 16:59:57 UTC (rev 14071)
@@ -36,6 +36,7 @@
      ../../core/symbology
      ../../gui
      ..
+     ${GEOS_INCLUDE_DIR}
 )
 
 TARGET_LINK_LIBRARIES(coordinatecaptureplugin



More information about the QGIS-commit mailing list