[FEATURE][cad] Implement "repeating" locking mode for constraints

When enabled, repeating locks are not automatically cleared when
a new point is added. They are handy when the same constraint
must be repeated for multiple points (eg adding vertices
which are always 50 meters apart)

(fix #12605)
This commit is contained in:
Nyall Dawson 2016-05-02 17:28:06 +10:00
parent bd305885c2
commit e53cb6ef3c
6 changed files with 696 additions and 74 deletions

View File

@ -581,6 +581,7 @@
<file>themes/default/multieditChangedValues.svg</file>
<file>themes/default/multieditMixedValues.svg</file>
<file>themes/default/multieditSameValues.svg</file>
<file>themes/default/locked_repeating.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>

View File

@ -0,0 +1,434 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="svg5692"
sodipodi:docname="locked_repeating.svg"
inkscape:version="0.91 r13725"
inkscape:export-filename="/mnt/home1/robert/svn/graphics/trunk/toolbar-icons/24x24/unlocked.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
x="0px"
y="0px"
width="16"
height="16"
viewBox="0 0 16 16"
enable-background="new 0 0 24 24"
xml:space="preserve"><metadata
id="metadata18"><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><defs
id="defs16"><linearGradient
id="linearGradient3965"><stop
id="stop3971"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" /><stop
style="stop-color:#959595;stop-opacity:1;"
offset="0.85191339"
id="stop3977" /><stop
id="stop3979"
offset="0.91825092"
style="stop-color:#6f6f6f;stop-opacity:1;" /><stop
style="stop-color:#4a4a4a;stop-opacity:1;"
offset="1"
id="stop3969" /></linearGradient><linearGradient
id="linearGradient3645"><stop
id="stop3647"
offset="0"
style="stop-color:#edd400;stop-opacity:1;" /><stop
id="stop3649"
offset="1"
style="stop-color:#fff17a;stop-opacity:1;" /></linearGradient><linearGradient
id="linearGradient3657"><stop
id="stop3659"
offset="0"
style="stop-color:#fce94f;stop-opacity:1;" /><stop
id="stop3661"
offset="1"
style="stop-color:#e7ce04;stop-opacity:1;" /></linearGradient><linearGradient
id="linearGradient2877"><stop
id="stop2879"
offset="0"
style="stop-color:#edd400;stop-opacity:1;" /><stop
id="stop2881"
offset="1"
style="stop-color:#c2ad00;stop-opacity:1;" /></linearGradient><linearGradient
id="linearGradient4042"><stop
id="stop4044"
offset="0"
style="stop-color:#f2d6a9;stop-opacity:1;" /><stop
id="stop4046"
offset="1"
style="stop-color:#e9b96e;stop-opacity:1;" /></linearGradient><linearGradient
id="linearGradient2843"><stop
id="stop2845"
offset="0"
style="stop-color:#eeeeec;stop-opacity:1;" /><stop
id="stop2847"
offset="1"
style="stop-color:#c8c8c2;stop-opacity:1;" /></linearGradient><linearGradient
id="linearGradient2835"><stop
id="stop2837"
offset="0"
style="stop-color:#ccf2a6;stop-opacity:1;" /><stop
id="stop2839"
offset="1"
style="stop-color:#8ae234;stop-opacity:1;" /></linearGradient><inkscape:perspective
id="perspective3257"
inkscape:persp3d-origin="16 : 10.666667 : 1"
inkscape:vp_z="32 : 16 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 16 : 1"
sodipodi:type="inkscape:persp3d" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective6979" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective7934" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective8023" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective8057" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective8095" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective8219" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective8279" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3803" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3869" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3929" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3968" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective4002" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective4032" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective4053" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective2905" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective2979" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective2842" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective2978" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3238" /><radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8118545,0.97422537,-1.1052481,0.9210397,19.809981,-0.4170292)"
r="6.158739"
fy="17.838446"
fx="0.5"
cy="17.838446"
cx="0.5"
id="radialGradient4048"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective4058" /><radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.81185454,1.1365964,-1.1707271,0.83623306,20.063146,-1.4817979)"
r="6.1587391"
fy="3.8663561"
fx="8.5770311"
cy="3.8663561"
cx="8.5770311"
id="radialGradient4048-2"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4042"
id="radialGradient4067"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8118545,0.97422537,-1.1052481,0.9210397,19.809981,-8.4170292)"
cx="0.5"
cy="17.838446"
fx="0.5"
fy="17.838446"
r="6.1587391" /><radialGradient
r="6.1587391"
fy="3.8663561"
fx="8.5770311"
cy="3.8663561"
cx="8.5770311"
gradientTransform="matrix(0.81185454,1.1365964,-1.1707271,0.83623306,20.063146,-1.4817979)"
gradientUnits="userSpaceOnUse"
id="radialGradient4094"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.1587391"
fy="3.8663561"
fx="8.5770311"
cy="3.8663561"
cx="8.5770311"
gradientTransform="matrix(0.81185454,1.1365964,-1.1707271,0.83623306,20.063146,-1.4817979)"
gradientUnits="userSpaceOnUse"
id="radialGradient4097"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.1587391"
fy="3.8663561"
fx="8.5770311"
cy="3.8663561"
cx="8.5770311"
gradientTransform="matrix(0.81185454,1.1365964,-1.1707271,0.83623306,20.063146,-1.4817979)"
gradientUnits="userSpaceOnUse"
id="radialGradient4100"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.1587391"
fy="3.8663561"
fx="8.5770311"
cy="3.8663561"
cx="8.5770311"
gradientTransform="matrix(0.81185454,1.1365964,-1.1707271,0.83623306,20.063146,-1.4817979)"
gradientUnits="userSpaceOnUse"
id="radialGradient4103"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.158739"
fy="17.838446"
fx="0.5"
cy="17.838446"
cx="0.5"
gradientTransform="matrix(0.8118545,0.97422537,-1.1052481,0.9210397,19.809981,-0.4170292)"
gradientUnits="userSpaceOnUse"
id="radialGradient4106"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.158739"
fy="17.838446"
fx="0.5"
cy="17.838446"
cx="0.5"
gradientTransform="matrix(0.8118545,0.97422537,-1.1052481,0.9210397,19.809981,-0.4170292)"
gradientUnits="userSpaceOnUse"
id="radialGradient4109"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.158739"
fy="17.838446"
fx="0.5"
cy="17.838446"
cx="0.5"
gradientTransform="matrix(0.8118545,0.97422537,-1.1052481,0.9210397,19.809981,-0.4170292)"
gradientUnits="userSpaceOnUse"
id="radialGradient4112"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.158739"
fy="17.838446"
fx="0.5"
cy="17.838446"
cx="0.5"
gradientTransform="matrix(0.8118545,0.97422537,-1.1052481,0.9210397,19.809981,-0.4170292)"
gradientUnits="userSpaceOnUse"
id="radialGradient4115"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><radialGradient
r="6.158739"
fy="17.838446"
fx="0.5"
cy="17.838446"
cx="0.5"
gradientTransform="matrix(0.8118545,0.97422537,-1.1052481,0.9210397,19.809981,-0.4170292)"
gradientUnits="userSpaceOnUse"
id="radialGradient4118"
xlink:href="#linearGradient4042"
inkscape:collect="always" /><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective8198" /><linearGradient
gradientUnits="userSpaceOnUse"
y2="18.5"
x2="13.5"
y1="10.5"
x1="10.5"
id="linearGradient3663"
xlink:href="#linearGradient3657"
inkscape:collect="always" /><linearGradient
gradientTransform="translate(0,-3)"
y2="18.5"
x2="13.5"
y1="10.5"
x1="10.5"
gradientUnits="userSpaceOnUse"
id="linearGradient3669"
xlink:href="#linearGradient3657"
inkscape:collect="always" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1855"
inkscape:window-height="1056"
id="namedview14"
showgrid="true"
inkscape:zoom="32"
inkscape:cx="10.840595"
inkscape:cy="7.8233144"
inkscape:window-x="1345"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="layer4"><inkscape:grid
type="xygrid"
id="grid4151"
dotted="false" /></sodipodi:namedview><g
id="layer4"
transform="translate(0,-16)"
inkscape:groupmode="layer"
inkscape:label="1"><linearGradient
id="rect2912_1_"
gradientUnits="userSpaceOnUse"
x1="303.85739"
y1="-376.5"
x2="308.1431"
y2="-376.5"
gradientTransform="matrix(1,0,0,-1,-326.294,-350.383)"><stop
offset="0"
style="stop-color:#E9B96E"
id="stop9" /><stop
offset="1"
style="stop-color:#E19E36"
id="stop11" /></linearGradient><g
id="g4246"
transform="matrix(0.90237132,0,0,1,1.2895278,0.125)"
style="opacity:0.835"><path
id="path2932_1_-0-1-5"
sodipodi:nodetypes="ccc"
d="m 6.618053,21.551166 c 0.09979,-2.918246 0.798331,-4.239386 3.213153,-4.06144 2.414551,0.177516 2.957532,1.588859 2.857291,4.507339"
inkscape:connector-curvature="0"
style="fill:none;stroke:#888a85;stroke-width:3.15811992;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
id="path2932_1_-2-2"
sodipodi:nodetypes="ccc"
d="m 6.606018,21.551166 c 0.09979,-2.918246 0.798331,-4.27316 3.213153,-4.095215 2.414551,0.177516 2.957532,1.622634 2.857292,4.541114"
inkscape:connector-curvature="0"
style="fill:none;stroke:#eeeeec;stroke-width:1.0527066;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><rect
ry="0.85714287"
rx="0.76923084"
y="22.396696"
x="4.6875"
height="6"
width="10"
id="rect4170-2-6"
style="opacity:1;fill:#e5dba9;fill-opacity:1;stroke:#9f8e41;stroke-width:1.0527066;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g><g
id="g4251"
transform="matrix(0.89256949,0,0,1,0.18267329,0)"><path
id="path2932_1_-0-1"
sodipodi:nodetypes="ccc"
d="m 3.4305529,23.654471 c 0.099794,-2.918246 0.7983306,-4.239386 3.213153,-4.06144 2.414551,0.177516 2.9575317,1.588859 2.8572907,4.507339"
inkscape:connector-curvature="0"
style="fill:none;stroke:#888a85;stroke-width:3.17541313;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
id="path2932_1_-2"
sodipodi:nodetypes="ccc"
d="m 3.4185183,23.654471 c 0.099794,-2.918246 0.7983306,-4.27316 3.213153,-4.095215 2.4145507,0.177516 2.9575314,1.622634 2.8572913,4.541114"
inkscape:connector-curvature="0"
style="fill:none;stroke:#eeeeec;stroke-width:1.05847108;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><rect
ry="0.85714287"
rx="0.76923084"
y="24.5"
x="1.5"
height="6"
width="10"
id="rect4170-2"
style="opacity:1;fill:#e5dba9;fill-opacity:1;stroke:#9f8e41;stroke-width:1.05847108;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g></g></svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -67,7 +67,7 @@ class QgsAdvancedDigitizingDockWidget : QDockWidget
HardLock
};
CadConstraint( QLineEdit* lineEdit, QToolButton* lockerButton, QToolButton* relativeButton = 0 );
CadConstraint( QLineEdit* lineEdit, QToolButton* lockerButton, QToolButton* relativeButton = nullptr, QToolButton* repeatingLockButton = nullptr );
/**
* The current lock mode of this constraint
@ -78,6 +78,14 @@ class QgsAdvancedDigitizingDockWidget : QDockWidget
* Is any kind of lock mode enabled
*/
bool isLocked() const;
/** Returns true if a repeating lock is set for the constraint. Repeating locks are not
* automatically cleared after a new point is added.
* @note added in QGIS 2.16
* @see setRepeatingLock()
*/
bool isRepeatingLock() const;
/**
* Is the constraint in relative mode
*/
@ -97,6 +105,14 @@ class QgsAdvancedDigitizingDockWidget : QDockWidget
*/
void setLockMode( LockMode mode );
/** Sets whether a repeating lock is set for the constraint. Repeating locks are not
* automatically cleared after a new point is added.
* @param repeating set to true to set the lock to repeat automatically
* @note added in QGIS 2.16
* @see isRepeatingLock()
*/
void setRepeatingLock( bool repeating );
/**
* Set if the constraint should be treated relative
*/
@ -284,7 +300,8 @@ class QgsAdvancedDigitizingDockWidget : QDockWidget
void lockConstraint( bool activate = true );
//! unlock all constraints
void releaseLocks();
//! @param releaseRepeatingLocks set to false to preserve the lock for any constraints set to repeating lock mode
void releaseLocks( bool releaseRepeatingLocks = true );
//! set the relative properties of constraints
void setConstraintRelative( bool activate );

View File

@ -103,10 +103,10 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas*
mCadPaintItem = new QgsAdvancedDigitizingCanvasItem( canvas, this ) ;
mAngleConstraint = new CadConstraint( mAngleLineEdit, mLockAngleButton, mRelativeAngleButton );
mDistanceConstraint = new CadConstraint( mDistanceLineEdit, mLockDistanceButton ) ;
mXConstraint = new CadConstraint( mXLineEdit, mLockXButton, mRelativeXButton );
mYConstraint = new CadConstraint( mYLineEdit, mLockYButton, mRelativeYButton ) ;
mAngleConstraint = new CadConstraint( mAngleLineEdit, mLockAngleButton, mRelativeAngleButton, mRepeatingLockAngleButton );
mDistanceConstraint = new CadConstraint( mDistanceLineEdit, mLockDistanceButton, nullptr, mRepeatingLockDistanceButton ) ;
mXConstraint = new CadConstraint( mXLineEdit, mLockXButton, mRelativeXButton, mRepeatingLockXButton );
mYConstraint = new CadConstraint( mYLineEdit, mLockYButton, mRelativeYButton, mRepeatingLockYButton ) ;
mAdditionalConstraint = NoConstraint ;
mMapCanvas->installEventFilter( this );
@ -135,6 +135,10 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas*
connect( mRelativeAngleButton, SIGNAL( clicked( bool ) ), this, SLOT( setConstraintRelative( bool ) ) );
connect( mRelativeXButton, SIGNAL( clicked( bool ) ), this, SLOT( setConstraintRelative( bool ) ) );
connect( mRelativeYButton, SIGNAL( clicked( bool ) ), this, SLOT( setConstraintRelative( bool ) ) );
connect( mRepeatingLockDistanceButton, SIGNAL( clicked( bool ) ), this, SLOT( setConstraintRepeatingLock( bool ) ) );
connect( mRepeatingLockAngleButton, SIGNAL( clicked( bool ) ), this, SLOT( setConstraintRepeatingLock( bool ) ) );
connect( mRepeatingLockXButton, SIGNAL( clicked( bool ) ), this, SLOT( setConstraintRepeatingLock( bool ) ) );
connect( mRepeatingLockYButton, SIGNAL( clicked( bool ) ), this, SLOT( setConstraintRepeatingLock( bool ) ) );
connect( mAngleLineEdit, SIGNAL( returnPressed() ), this, SLOT( lockConstraint() ) );
connect( mDistanceLineEdit, SIGNAL( returnPressed() ), this, SLOT( lockConstraint() ) );
connect( mXLineEdit, SIGNAL( returnPressed() ), this, SLOT( lockConstraint() ) );
@ -262,6 +266,26 @@ void QgsAdvancedDigitizingDockWidget::setConstraintRelative( bool activate )
}
}
void QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock( bool activate )
{
if ( sender() == mRepeatingLockDistanceButton )
{
mDistanceConstraint->setRepeatingLock( activate );
}
else if ( sender() == mRepeatingLockAngleButton )
{
mAngleConstraint->setRepeatingLock( activate );
}
else if ( sender() == mRepeatingLockXButton )
{
mXConstraint->setRepeatingLock( activate );
}
else if ( sender() == mRepeatingLockYButton )
{
mYConstraint->setRepeatingLock( activate );
}
}
void QgsAdvancedDigitizingDockWidget::setConstructionMode( bool enabled )
{
mConstructionMode = enabled;
@ -291,16 +315,20 @@ void QgsAdvancedDigitizingDockWidget::settingsButtonTriggered( QAction* action )
}
}
void QgsAdvancedDigitizingDockWidget::releaseLocks()
void QgsAdvancedDigitizingDockWidget::releaseLocks( bool releaseRepeatingLocks )
{
// release all locks except construction mode
lockAdditionalConstraint( NoConstraint );
mAngleConstraint->setLockMode( CadConstraint::NoLock );
mDistanceConstraint->setLockMode( CadConstraint::NoLock );
mXConstraint->setLockMode( CadConstraint::NoLock );
mYConstraint->setLockMode( CadConstraint::NoLock );
if ( releaseRepeatingLocks || !mAngleConstraint->isRepeatingLock() )
mAngleConstraint->setLockMode( CadConstraint::NoLock );
if ( releaseRepeatingLocks || !mDistanceConstraint->isRepeatingLock() )
mDistanceConstraint->setLockMode( CadConstraint::NoLock );
if ( releaseRepeatingLocks || !mXConstraint->isRepeatingLock() )
mXConstraint->setLockMode( CadConstraint::NoLock );
if ( releaseRepeatingLocks || !mYConstraint->isRepeatingLock() )
mYConstraint->setLockMode( CadConstraint::NoLock );
}
#if 0
@ -899,7 +927,7 @@ bool QgsAdvancedDigitizingDockWidget::canvasReleaseEvent( QgsMapMouseEvent* e, b
addPoint( e->mapPoint() );
releaseLocks();
releaseLocks( false );
if ( e->button() == Qt::LeftButton )
{
@ -947,7 +975,7 @@ bool QgsAdvancedDigitizingDockWidget::canvasKeyPressEventFilter( QKeyEvent* e )
case Qt::Key_Delete:
{
removePreviousPoint();
releaseLocks();
releaseLocks( false );
break;
}
case Qt::Key_Escape:
@ -984,7 +1012,7 @@ void QgsAdvancedDigitizingDockWidget::keyPressEvent( QKeyEvent *e )
case Qt::Key_Delete:
{
removePreviousPoint();
releaseLocks();
releaseLocks( false );
break;
}
case Qt::Key_Escape:
@ -1228,6 +1256,18 @@ void QgsAdvancedDigitizingDockWidget::CadConstraint::setLockMode( LockMode mode
{
mLockMode = mode;
mLockerButton->setChecked( mode == HardLock );
if ( mRepeatingLockButton )
{
if ( mode == HardLock )
{
mRepeatingLockButton->setEnabled( true );
}
else
{
mRepeatingLockButton->setChecked( false );
mRepeatingLockButton->setEnabled( false );
}
}
if ( mode == NoLock )
{
@ -1235,6 +1275,13 @@ void QgsAdvancedDigitizingDockWidget::CadConstraint::setLockMode( LockMode mode
}
}
void QgsAdvancedDigitizingDockWidget::CadConstraint::setRepeatingLock( bool repeating )
{
mRepeatingLock = repeating;
if ( mRepeatingLockButton )
mRepeatingLockButton->setChecked( repeating );
}
void QgsAdvancedDigitizingDockWidget::CadConstraint::setRelative( bool relative )
{
mRelative = relative;

View File

@ -89,11 +89,13 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
HardLock
};
CadConstraint( QLineEdit* lineEdit, QToolButton* lockerButton, QToolButton* relativeButton = nullptr )
CadConstraint( QLineEdit* lineEdit, QToolButton* lockerButton, QToolButton* relativeButton = nullptr, QToolButton* repeatingLockButton = nullptr )
: mLineEdit( lineEdit )
, mLockerButton( lockerButton )
, mRelativeButton( relativeButton )
, mRepeatingLockButton( repeatingLockButton )
, mLockMode( NoLock )
, mRepeatingLock( false )
, mRelative( false )
, mValue( 0.0 )
{}
@ -107,6 +109,14 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
* Is any kind of lock mode enabled
*/
bool isLocked() const { return mLockMode != NoLock; }
/** Returns true if a repeating lock is set for the constraint. Repeating locks are not
* automatically cleared after a new point is added.
* @note added in QGIS 2.16
* @see setRepeatingLock()
*/
bool isRepeatingLock() const { return mRepeatingLock; }
/**
* Is the constraint in relative mode
*/
@ -126,6 +136,14 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
*/
void setLockMode( LockMode mode );
/** Sets whether a repeating lock is set for the constraint. Repeating locks are not
* automatically cleared after a new point is added.
* @param repeating set to true to set the lock to repeat automatically
* @note added in QGIS 2.16
* @see isRepeatingLock()
*/
void setRepeatingLock( bool repeating );
/**
* Set if the constraint should be treated relative
*/
@ -152,7 +170,9 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
QLineEdit* mLineEdit;
QToolButton* mLockerButton;
QToolButton* mRelativeButton;
QToolButton* mRepeatingLockButton;
LockMode mLockMode;
bool mRepeatingLock;
bool mRelative;
double mValue;
};
@ -329,11 +349,15 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QDockWidget, private U
void constraintFocusOut();
//! unlock all constraints
void releaseLocks();
//! @param releaseRepeatingLocks set to false to preserve the lock for any constraints set to repeating lock mode
void releaseLocks( bool releaseRepeatingLocks = true );
//! set the relative properties of constraints
void setConstraintRelative( bool activate );
//! Set the repeating lock property of constraints
void setConstraintRepeatingLock( bool activate );
//! activate/deactivate tools. It is called when tools are activated manually (from the GUI)
//! it will call setCadEnabled to properly update the UI.
void activateCad( bool enabled );

View File

@ -45,7 +45,16 @@
<item>
<widget class="QWidget" name="mCadWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -78,7 +87,16 @@
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -188,30 +206,39 @@
<item>
<widget class="QWidget" name="mInputWidgets" native="true">
<layout class="QGridLayout" name="mInputLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="2" column="2">
<widget class="QLineEdit" name="mXLineEdit">
<property name="toolTip">
<string>X coordinate</string>
<item row="3" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>y</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="mDistanceLineEdit">
<item row="3" column="2">
<widget class="QLineEdit" name="mYLineEdit">
<property name="toolTip">
<string>Distance</string>
<string>Y coordinate</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="mLockDistanceButton">
<item row="3" column="3">
<widget class="QToolButton" name="mLockYButton">
<property name="toolTip">
<string>Lock distance</string>
<string>Lock y coordinate</string>
</property>
<property name="text">
<string>...</string>
@ -225,6 +252,40 @@
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="mLockXButton">
<property name="toolTip">
<string>Lock x coordinate</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/cadtools/lock.png</normaloff>:/images/themes/default/cadtools/lock.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QToolButton" name="mRelativeYButton">
<property name="toolTip">
<string>Toggles relative y to previous node</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/cadtools/delta.png</normaloff>:/images/themes/default/cadtools/delta.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QToolButton" name="mLockAngleButton">
<property name="toolTip">
@ -242,34 +303,24 @@
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QToolButton" name="mLockYButton">
<item row="2" column="2">
<widget class="QLineEdit" name="mXLineEdit">
<property name="toolTip">
<string>Lock y coordinate</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/cadtools/lock.png</normaloff>:/images/themes/default/cadtools/lock.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
<string>X coordinate</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label">
<item row="1" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>d</string>
<string>a</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QToolButton" name="mRelativeYButton">
<item row="1" column="0">
<widget class="QToolButton" name="mRelativeAngleButton">
<property name="toolTip">
<string>Toggles relative y to previous node</string>
<string>Toggles relative angle to previous segment</string>
</property>
<property name="text">
<string>...</string>
@ -281,12 +332,8 @@
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>a</string>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
@ -304,10 +351,34 @@
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLineEdit" name="mYLineEdit">
<item row="0" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>d</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="mLockDistanceButton">
<property name="toolTip">
<string>Y coordinate</string>
<string>Lock distance</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/cadtools/lock.png</normaloff>:/images/themes/default/cadtools/lock.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="mDistanceLineEdit">
<property name="toolTip">
<string>Distance</string>
</property>
</widget>
</item>
@ -328,46 +399,70 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>y</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="mLockXButton">
<item row="0" column="4">
<widget class="QToolButton" name="mRepeatingLockDistanceButton">
<property name="toolTip">
<string>Lock x coordinate</string>
<string>Continuously lock distance</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/cadtools/lock.png</normaloff>:/images/themes/default/cadtools/lock.png</iconset>
<normaloff>:/images/themes/default/locked_repeating.svg</normaloff>:/images/themes/default/locked_repeating.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QToolButton" name="mRelativeAngleButton">
<item row="1" column="4">
<widget class="QToolButton" name="mRepeatingLockAngleButton">
<property name="toolTip">
<string>Toggles relative angle to previous segment</string>
<string>Continuously lock angle</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/cadtools/delta.png</normaloff>:/images/themes/default/cadtools/delta.png</iconset>
<normaloff>:/images/themes/default/locked_repeating.svg</normaloff>:/images/themes/default/locked_repeating.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
</widget>
</item>
<item row="2" column="4">
<widget class="QToolButton" name="mRepeatingLockXButton">
<property name="toolTip">
<string>Continuously lock x coordinate</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/locked_repeating.svg</normaloff>:/images/themes/default/locked_repeating.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QToolButton" name="mRepeatingLockYButton">
<property name="toolTip">
<string>Continuously lock y coordinate</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/locked_repeating.svg</normaloff>:/images/themes/default/locked_repeating.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
@ -404,19 +499,23 @@
<tabstop>mSettingsButton</tabstop>
<tabstop>mDistanceLineEdit</tabstop>
<tabstop>mLockDistanceButton</tabstop>
<tabstop>mRepeatingLockDistanceButton</tabstop>
<tabstop>mRelativeAngleButton</tabstop>
<tabstop>mAngleLineEdit</tabstop>
<tabstop>mLockAngleButton</tabstop>
<tabstop>mRepeatingLockAngleButton</tabstop>
<tabstop>mRelativeXButton</tabstop>
<tabstop>mXLineEdit</tabstop>
<tabstop>mLockXButton</tabstop>
<tabstop>mRepeatingLockXButton</tabstop>
<tabstop>mRelativeYButton</tabstop>
<tabstop>mYLineEdit</tabstop>
<tabstop>mLockYButton</tabstop>
<tabstop>mRepeatingLockYButton</tabstop>
</tabstops>
<resources>
<include location="../plugins/georeferencer/georeferencer.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../plugins/georeferencer/georeferencer.qrc"/>
</resources>
<connections/>
</ui>