mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Merge pull request #5086 from pblottiere/pr_auxiliary_storage
[Feature] Auxiliary Storage
This commit is contained in:
commit
ac66ced1c3
@ -485,6 +485,7 @@
|
||||
<file>themes/default/unlocked.svg</file>
|
||||
<file>themes/default/unlockedGray.svg</file>
|
||||
<file>themes/default/user.svg</file>
|
||||
<file>themes/default/mIconAuxiliaryStorage.svg</file>
|
||||
<file>flags/eu.png</file>
|
||||
<file>flags/bn.png</file>
|
||||
<file>flags/gl.png</file>
|
||||
|
280
images/themes/default/mIconAuxiliaryStorage.svg
Normal file
280
images/themes/default/mIconAuxiliaryStorage.svg
Normal file
@ -0,0 +1,280 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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"
|
||||
height="24"
|
||||
width="24"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
sodipodi:docname="mIconAuxiliaryStorage2.svg"
|
||||
inkscape:version="0.92.1 r15371">
|
||||
<metadata
|
||||
id="metadata14">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs12">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath6054">
|
||||
<rect
|
||||
style="display:inline;fill:#a40000;fill-opacity:1;stroke:none"
|
||||
id="rect6056"
|
||||
width="48"
|
||||
height="22"
|
||||
x="-126"
|
||||
y="-6"
|
||||
transform="matrix(0.9545455,0,0,0.89256196,-4.6363639,-1.3719273)" />
|
||||
</clipPath>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4938"
|
||||
x="-0.065465368"
|
||||
width="1.1309307"
|
||||
y="-0.34369317"
|
||||
height="1.6873863"
|
||||
style="color-interpolation-filters:sRGB">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="1.1456439"
|
||||
id="feGaussianBlur4940" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient_SkyBlue"
|
||||
id="linearGradient5485"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="0.5"
|
||||
y1="12"
|
||||
x2="15.5"
|
||||
y2="12"
|
||||
gradientTransform="matrix(0.88966084,0,0,1.3582695,1.0687967,1.2233435)" />
|
||||
<linearGradient
|
||||
id="linearGradient_SkyBlue">
|
||||
<stop
|
||||
id="stop3832"
|
||||
offset="0"
|
||||
style="stop-color:#e7e7e7;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3834"
|
||||
offset="1"
|
||||
style="stop-color:#c0c0c0;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3820"
|
||||
id="linearGradient5487"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-122.5"
|
||||
y1="27"
|
||||
x2="-81.5"
|
||||
y2="27"
|
||||
gradientTransform="matrix(0.32548569,0,0,0.52821591,41.385986,4.5812617)" />
|
||||
<linearGradient
|
||||
id="linearGradient3820">
|
||||
<stop
|
||||
style="stop-color:#dcdcdc;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3823" />
|
||||
<stop
|
||||
style="stop-color:#545454;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3825" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3829"
|
||||
id="linearGradient5489"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-122"
|
||||
y1="23.5"
|
||||
x2="-82"
|
||||
y2="23.5"
|
||||
gradientTransform="matrix(0.32548569,0,0,0.52821591,41.385986,5.1094941)" />
|
||||
<linearGradient
|
||||
id="linearGradient3829">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.60000002;"
|
||||
offset="0"
|
||||
id="stop3831" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.20784314;"
|
||||
offset="1"
|
||||
id="stop3833" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4365"
|
||||
id="linearGradient5491"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-121"
|
||||
y1="30"
|
||||
x2="-102"
|
||||
y2="30"
|
||||
gradientTransform="matrix(0.32548569,0,0,0.52821591,41.385986,0.88373362)" />
|
||||
<linearGradient
|
||||
id="linearGradient4365">
|
||||
<stop
|
||||
id="stop4367"
|
||||
offset="0"
|
||||
style="stop-color:#000000;stop-opacity:0.80000001;" />
|
||||
<stop
|
||||
id="stop4369"
|
||||
offset="1"
|
||||
style="stop-color:#000000;stop-opacity:0.15384616;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient_SkyBlue"
|
||||
id="linearGradient5493"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="0.5"
|
||||
y1="12"
|
||||
x2="15.5"
|
||||
y2="12"
|
||||
gradientTransform="matrix(0.88966084,0,0,1.3582695,1.0687967,-4.5870147)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3820"
|
||||
id="linearGradient5495"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-122.5"
|
||||
y1="27"
|
||||
x2="-81.5"
|
||||
y2="27"
|
||||
gradientTransform="matrix(0.32548569,0,0,0.52821591,41.385986,-1.2290967)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3829"
|
||||
id="linearGradient5497"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-122"
|
||||
y1="23.5"
|
||||
x2="-82"
|
||||
y2="23.5"
|
||||
gradientTransform="matrix(0.32548569,0,0,0.52821591,41.385986,-0.70091386)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4365"
|
||||
id="linearGradient5499"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-121"
|
||||
y1="30"
|
||||
x2="-102"
|
||||
y2="30"
|
||||
gradientTransform="matrix(0.32548569,0,0,0.52821591,41.385986,-4.9266245)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="958"
|
||||
inkscape:window-height="1058"
|
||||
id="namedview10"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg8" />
|
||||
<g
|
||||
transform="translate(3.11,-1028.2722)"
|
||||
id="g6"
|
||||
style="fill-rule:evenodd;stroke:#727272;stroke-linejoin:round">
|
||||
<path
|
||||
d="m 4.5,1050.8618 v -21 h 10 l 5,5 v 16.0004 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="m 14.5,1029.8618 v 5 h 5 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#f0f0f0" />
|
||||
</g>
|
||||
<ellipse
|
||||
style="display:inline;fill:#2e3436;fill-opacity:0.8;stroke:none;filter:url(#filter4938)"
|
||||
id="path4932"
|
||||
transform="matrix(0.340985,0,0,0.72629687,42.966917,16.334045)"
|
||||
clip-path="url(#clipPath6054)"
|
||||
cx="-102"
|
||||
cy="6"
|
||||
rx="21"
|
||||
ry="4" />
|
||||
<path
|
||||
id="path4791"
|
||||
d="m 8.1860847,12.768588 c -3.6850976,0 -6.6724579,1.216316 -6.6724579,2.716582 v 4.074822 c 0,1.500265 2.9873603,2.716483 6.6724579,2.716483 3.6850943,0 6.6724533,-1.216218 6.6724533,-2.716483 V 15.48517 c 0,-1.500266 -2.987359,-2.716582 -6.6724533,-2.716582 z"
|
||||
style="display:inline;fill:url(#linearGradient5485);fill-opacity:1;stroke:none;stroke-width:0.41464046"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient5487);fill-opacity:1;stroke:none;stroke-width:0.41464046"
|
||||
d="m 1.5648452,14.881468 c -0.034064,0.111272 -0.050856,0.231705 -0.050856,0.346691 v 4.324751 c 0,1.500315 2.9873603,2.723565 6.6724571,2.723565 3.6850967,0 6.6724557,-1.22325 6.6724557,-2.723565 v -4.324751 c 0,-0.114986 -0.01679,-0.235419 -0.05086,-0.346691 -0.410385,1.340067 -3.218924,2.376972 -6.6215988,2.376972 -3.4026751,0 -6.2112121,-1.036905 -6.6215998,-2.376972 z"
|
||||
id="path4822"
|
||||
sodipodi:nodetypes="cccscccsc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient5489);fill-opacity:1;stroke:none;stroke-width:0.46920153;marker:none;enable-background:accumulate"
|
||||
d="m 8.1864441,13.032729 c -1.8304566,0 -3.4817402,0.309105 -4.6686851,0.792324 -0.593475,0.241609 -1.0791673,0.506295 -1.3934864,0.808863 -0.3143181,0.30247 -0.4475406,0.613011 -0.4475406,0.858335 v 4.060659 c 0,0.245275 0.1332225,0.555766 0.4475406,0.858335 0.3143191,0.302519 0.8000114,0.567205 1.3934864,0.808814 1.1869449,0.483267 2.8382285,0.792323 4.6686851,0.792323 1.8304579,0 3.4817389,-0.309056 4.6686859,-0.792323 0.593473,-0.241609 1.079168,-0.506295 1.393485,-0.808814 0.314318,-0.302569 0.447543,-0.61306 0.447543,-0.858335 v -4.060659 c 0,-0.245324 -0.133225,-0.555865 -0.447543,-0.858335 -0.314317,-0.302568 -0.800012,-0.567254 -1.393485,-0.808863 -1.186947,-0.483219 -2.838228,-0.792324 -4.6686859,-0.792324 z m 0,0.528183 c 1.8032025,0 3.4332069,0.257406 4.5771429,0.726313 0.571968,0.234479 1.014393,0.500353 1.281599,0.759294 0.267207,0.258991 0.325487,0.443553 0.325487,0.429192 v 4.09369 c 0,-0.01436 -0.05828,0.170201 -0.325487,0.429142 -0.267206,0.258991 -0.709631,0.524865 -1.281599,0.759343 -1.143935,0.468907 -2.7739404,0.726264 -4.5771429,0.726264 -1.8032048,0 -3.4332067,-0.257357 -4.5771418,-0.726264 C 3.037333,20.523408 2.5949098,20.257534 2.3277026,19.998543 2.0604954,19.739602 2.0022155,19.55504 2.0022155,19.569401 v -4.09369 c 0,0.01436 0.058283,-0.170201 0.3254871,-0.429192 0.2672072,-0.258941 0.7096304,-0.524815 1.2815997,-0.759294 1.1439351,-0.468907 2.773937,-0.726313 4.5771418,-0.726313 z"
|
||||
id="path4803"
|
||||
sodipodi:nodetypes="cssccsssssccssccssccsssssccssc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#3f3f3f;stroke-width:0.4146404;stroke-opacity:1"
|
||||
d="m 8.1860847,12.768588 c -3.6850976,0 -6.6724579,1.216316 -6.6724579,2.716582 v 4.074822 c 0,1.500265 2.9873603,2.716483 6.6724579,2.716483 3.6850943,0 6.6724533,-1.216218 6.6724533,-2.716483 V 15.48517 c 0,-1.500266 -2.987359,-2.716582 -6.6724533,-2.716582 z"
|
||||
id="path4721"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient5491);fill-opacity:1;stroke:none;stroke-width:0.41464046"
|
||||
d="m 2.0022155,15.558262 v 0.528232 c 0.9927301,0.993128 3.388153,1.700178 6.1842286,1.700178 2.7960739,0 5.1914989,-0.70705 6.1842289,-1.700178 v -0.528232 c -0.99273,0.993177 -3.388155,1.700178 -6.1842289,1.700178 -2.7960756,0 -5.1914985,-0.707001 -6.1842286,-1.700178 z"
|
||||
id="path4831"
|
||||
sodipodi:nodetypes="ccsccsc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient5493);fill-opacity:1;stroke:none;stroke-width:1.09927213"
|
||||
d="m 8.1860811,6.958283 c -3.685094,0 -6.6724543,1.2162175 -6.6724543,2.7165315 v 4.0747685 c 0,1.500315 2.9873603,2.716583 6.6724543,2.716583 3.6850979,0 6.6724569,-1.216268 6.6724569,-2.716583 V 9.6748145 c 0,-1.500314 -2.987359,-2.7165315 -6.6724569,-2.7165315 z"
|
||||
id="path4882"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccscccsc"
|
||||
id="path4884"
|
||||
d="m 1.5648452,9.0711145 c -0.034064,0.111222 -0.050856,0.231655 -0.050856,0.346641 v 4.3247475 c 0,1.500314 2.9873603,2.723613 6.6724571,2.723613 3.6850967,0 6.6724557,-1.223299 6.6724557,-2.723613 V 9.4177555 c 0,-0.114986 -0.01679,-0.235419 -0.05086,-0.346641 -0.410385,1.3400645 -3.218924,2.3769665 -6.6215988,2.3769665 -3.4026751,0 -6.2112121,-1.036902 -6.6215998,-2.3769665 z"
|
||||
style="display:inline;fill:url(#linearGradient5495);fill-opacity:1;stroke:none;stroke-width:0.41464046"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="cssccsssssccssccssccsssssccssc"
|
||||
id="path4886"
|
||||
d="m 8.1864441,7.2223249 c -1.8304566,0 -3.4817402,0.3091053 -4.6686851,0.7923235 C 2.924284,8.2563077 2.4385917,8.520944 2.1242726,8.823512 1.8099545,9.1260325 1.676732,9.4365735 1.676732,9.6818475 v 4.0606555 c 0,0.245273 0.1332225,0.555815 0.4475406,0.858334 0.3143191,0.302569 0.8000114,0.567254 1.3934864,0.808863 1.1869449,0.483219 2.8382285,0.792324 4.6686851,0.792324 1.8304579,0 3.4817389,-0.309105 4.6686859,-0.792324 0.593473,-0.241609 1.079168,-0.506294 1.393485,-0.808863 0.314318,-0.302519 0.447543,-0.613061 0.447543,-0.858334 V 9.6818475 c 0,-0.245274 -0.133225,-0.555815 -0.447543,-0.8583355 C 13.934298,8.520944 13.448603,8.2563077 12.85513,8.0146484 11.668183,7.5314302 10.016902,7.2223249 8.1864441,7.2223249 Z m 0,0.5282328 c 1.8032025,0 3.4332069,0.2574057 4.5771429,0.7263133 0.571968,0.234428 1.014393,0.5003525 1.281599,0.7592945 0.267207,0.258991 0.325487,0.443553 0.325487,0.429192 v 4.0936355 c 0,-0.01436 -0.05828,0.17025 -0.325487,0.429192 -0.267206,0.25899 -0.709631,0.524865 -1.281599,0.759294 -1.143935,0.468956 -2.7739404,0.726313 -4.5771429,0.726313 -1.8032048,0 -3.4332067,-0.257357 -4.5771418,-0.726313 C 3.037333,14.71305 2.5949098,14.447175 2.3277026,14.188185 2.0604954,13.929243 2.0022155,13.744632 2.0022155,13.758993 V 9.6653575 c 0,0.01436 0.058283,-0.170201 0.3254871,-0.429192 C 2.5949098,8.9772235 3.037333,8.711299 3.6093023,8.476871 4.7532374,8.0079634 6.3832393,7.7505577 8.1864441,7.7505577 Z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient5497);fill-opacity:1;stroke:none;stroke-width:0.46920153;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path4888"
|
||||
d="m 8.1860811,6.958283 c -3.685094,0 -6.6724543,1.2162175 -6.6724543,2.7165315 v 4.0747685 c 0,1.500315 2.9873603,2.716583 6.6724543,2.716583 3.6850979,0 6.6724569,-1.216268 6.6724569,-2.716583 V 9.6748145 c 0,-1.500314 -2.987359,-2.7165315 -6.6724569,-2.7165315 z"
|
||||
style="display:inline;fill:none;stroke:#3f3f3f;stroke-width:0.4146404;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccsccsc"
|
||||
id="path4892"
|
||||
d="m 2.0022155,9.7478575 v 0.5282315 c 0.9927301,0.993175 3.388153,1.700175 6.1842286,1.700175 2.7960739,0 5.1914989,-0.707 6.1842289,-1.700175 V 9.7478575 c -0.99273,0.9932245 -3.388155,1.7002235 -6.1842289,1.7002235 -2.7960756,0 -5.1914985,-0.706999 -6.1842286,-1.7002235 z"
|
||||
style="display:inline;fill:url(#linearGradient5499);fill-opacity:1;stroke:none;stroke-width:0.41464046"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
@ -297,6 +297,7 @@
|
||||
%Include qgsapplication.sip
|
||||
%Include qgsactionscoperegistry.sip
|
||||
%Include qgsanimatedicon.sip
|
||||
%Include qgsauxiliarystorage.sip
|
||||
%Include qgsbrowsermodel.sip
|
||||
%Include qgscoordinatereferencesystem.sip
|
||||
%Include qgscredentials.sip
|
||||
|
@ -124,6 +124,13 @@ class QgsProjectArchive : QgsArchive
|
||||
:return: true if the file is well removed, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QString auxiliaryStorageFile() const;
|
||||
%Docstring
|
||||
Returns the current .qgd auxiliary storage file or an empty string if
|
||||
there's none
|
||||
:rtype: str
|
||||
%End
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
397
python/core/qgsauxiliarystorage.sip
Normal file
397
python/core/qgsauxiliarystorage.sip
Normal file
@ -0,0 +1,397 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/qgsauxiliarystorage.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsAuxiliaryLayer : QgsVectorLayer
|
||||
{
|
||||
%Docstring
|
||||
|
||||
|
||||
Class allowing to manage the auxiliary storage for a vector layer.
|
||||
|
||||
Such auxiliary data are data used mostly for the needs of QGIS (symbology)
|
||||
and have no real interest in being stored with the native raw geospatial
|
||||
data.
|
||||
|
||||
The need arises from the restrictions existing in the manual placement of
|
||||
labels. Manual placement of labels are possible in QGIS by setting some
|
||||
labeling properties (X and Y position, and rotation angle optionally) as
|
||||
being "data-defined", meaning that values come from a column (or an
|
||||
expression). But setting this up on an existing layer requires either to
|
||||
add new columns to the source layer, while it is not always possible or
|
||||
desirable.
|
||||
|
||||
This QgsAuxiliaryLayer provides the solution to this limitation. Actually
|
||||
it's an editable join to the original vector layer with some
|
||||
synchronisation mechanisms activated such as "Upsert On Edit" or "Delete
|
||||
Cascade". Thus, auxiliary fields are editable even if the
|
||||
source layer is not and edition of a joined field is also possible.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsauxiliarystorage.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer );
|
||||
%Docstring
|
||||
Constructor
|
||||
|
||||
\param pkField The primary key to use for joining
|
||||
\param filename The database path
|
||||
\param table The table name
|
||||
\param vlayer The target vector layer in join definition
|
||||
%End
|
||||
|
||||
virtual ~QgsAuxiliaryLayer();
|
||||
%Docstring
|
||||
Destructor
|
||||
%End
|
||||
|
||||
|
||||
|
||||
QgsAuxiliaryLayer *clone( QgsVectorLayer *layer ) const /Factory/;
|
||||
%Docstring
|
||||
Returns a new instance equivalent to this one. The underlying table
|
||||
is duplicate for the layer given in parameter. Note that the current
|
||||
auxiliary layer should be saved to have a proper duplicated table.
|
||||
|
||||
\param layer The layer for which the clone is made
|
||||
:rtype: QgsAuxiliaryLayer
|
||||
%End
|
||||
|
||||
QgsVectorLayer *toSpatialLayer() const;
|
||||
%Docstring
|
||||
An auxiliary layer is not spatial. This method returns a spatial
|
||||
representation of auxiliary data.
|
||||
|
||||
:return: A new spatial vector layer
|
||||
:rtype: QgsVectorLayer
|
||||
%End
|
||||
|
||||
bool clear();
|
||||
%Docstring
|
||||
Deletes all features from the layer. Changes are automatically committed
|
||||
and the layer remains editable.
|
||||
|
||||
:return: true if changes are committed without error, false otherwise.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsVectorLayerJoinInfo joinInfo() const;
|
||||
%Docstring
|
||||
Returns information to use for joining with primary key and so on.
|
||||
:rtype: QgsVectorLayerJoinInfo
|
||||
%End
|
||||
|
||||
bool exists( const QgsPropertyDefinition &definition ) const;
|
||||
%Docstring
|
||||
Returns true if the property is stored in the layer already, false
|
||||
otherwise.
|
||||
|
||||
\param definition The property definition to check
|
||||
|
||||
:return: true if the property is stored, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool addAuxiliaryField( const QgsPropertyDefinition &definition );
|
||||
%Docstring
|
||||
Add an an auxiliary field for the given property. Setup for widget
|
||||
editors are updated in the target layer as weel as the attribute
|
||||
table config to hide auxiliary fields by default.
|
||||
|
||||
\param definition The definition of the property to add
|
||||
|
||||
:return: true if the auxiliary field is well added, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsFields auxiliaryFields() const;
|
||||
%Docstring
|
||||
Returns a list of all auxiliary fields currently managed by the layer.
|
||||
:rtype: QgsFields
|
||||
%End
|
||||
|
||||
bool save();
|
||||
%Docstring
|
||||
Commit changes and starts editing then.
|
||||
|
||||
:return: true if commit step passed, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual bool deleteAttribute( int attr );
|
||||
%Docstring
|
||||
Remove attribute from the layer and commit changes. The layer remains
|
||||
editable.
|
||||
|
||||
\param attr The index of the attribute to remove
|
||||
|
||||
:return: true if the attribute is well deleted, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool isHiddenProperty( int index ) const;
|
||||
%Docstring
|
||||
Returns true if the underlying field have to be hidden from editing
|
||||
tools like attribute table, false otherwise.
|
||||
|
||||
\param index The index of the field for which visibility is checked
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
int indexOfPropertyDefinition( const QgsPropertyDefinition &definition ) const;
|
||||
%Docstring
|
||||
Returns the index of the auxiliary field for a specific property
|
||||
definition.
|
||||
|
||||
\param definition The property definition
|
||||
|
||||
:return: The index of the field corresponding to the property or -1
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
int propertyFromIndex( int index ) const;
|
||||
%Docstring
|
||||
Returns the underlying property key for the field index. The key may be
|
||||
a PAL, diagram or symbology property according to the underlying
|
||||
property definition of the field. The key -1 is returned if an error
|
||||
happened.
|
||||
|
||||
\param index The index of the field
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
QgsPropertyDefinition propertyDefinitionFromIndex( int index ) const;
|
||||
%Docstring
|
||||
Returns the property definition fir the underlying field index.
|
||||
|
||||
\param index The index of the field
|
||||
:rtype: QgsPropertyDefinition
|
||||
%End
|
||||
|
||||
static int createProperty( QgsPalLayerSettings::Property property, QgsVectorLayer *vlayer );
|
||||
%Docstring
|
||||
Creates if necessary a new auxiliary field for a PAL property and
|
||||
activate this property in settings.
|
||||
|
||||
\param property The property to create
|
||||
\param vlayer The vector layer
|
||||
|
||||
:return: The index of the auxiliary field or -1
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
static int createProperty( QgsDiagramLayerSettings::Property property, QgsVectorLayer *vlayer );
|
||||
%Docstring
|
||||
Creates if necessary a new auxiliary field for a diagram's property and
|
||||
activate this this property in settings.
|
||||
|
||||
\param property The property to create
|
||||
\param vlayer The vector layer
|
||||
|
||||
:return: The index of the auxiliary field or -1
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
static QgsField createAuxiliaryField( const QgsPropertyDefinition &definition );
|
||||
%Docstring
|
||||
Creates a new auxiliary field from a property definition.
|
||||
|
||||
\param definition The property definition of the auxiliary field to create
|
||||
:rtype: QgsField
|
||||
%End
|
||||
|
||||
static QgsField createAuxiliaryField( const QgsField &field );
|
||||
%Docstring
|
||||
Creates a new auxiliary field from a field.
|
||||
|
||||
\param field The field to use to create the auxiliary field
|
||||
:rtype: QgsField
|
||||
%End
|
||||
|
||||
static QString nameFromProperty( const QgsPropertyDefinition &def, bool joined = false );
|
||||
%Docstring
|
||||
Returns the name of the auxiliary field for a property definition.
|
||||
|
||||
\param def The property definition
|
||||
\param joined The join prefix is taken into account if true
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QgsPropertyDefinition propertyDefinitionFromField( const QgsField &field );
|
||||
%Docstring
|
||||
Returns the property definition from an auxiliary field.
|
||||
|
||||
\param field The auxiliary field
|
||||
:rtype: QgsPropertyDefinition
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
class QgsAuxiliaryStorage
|
||||
{
|
||||
%Docstring
|
||||
|
||||
|
||||
Class providing some utility methods to manage auxiliary storage.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsauxiliarystorage.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsAuxiliaryStorage( const QgsProject &project, bool copy = true );
|
||||
%Docstring
|
||||
Constructor.
|
||||
|
||||
The project filename is used to build a database path at the same
|
||||
location, but with a different extension. Then, it's the same logic as
|
||||
.. seealso:: QgsAuxiliaryStorage(const QString &, bool copy).
|
||||
|
||||
|
||||
\param project The project for which the auxiliary storage has to be used
|
||||
\param copy Parameter indicating if a copy of the database has to be used
|
||||
%End
|
||||
|
||||
QgsAuxiliaryStorage( const QString &filename = QString(), bool copy = true );
|
||||
%Docstring
|
||||
Constructor.
|
||||
|
||||
If a valid database path is given in parameter and copy mode is
|
||||
deactivated, then every changes is directly committed on the original
|
||||
database. But if the copy mode is activated, then changes are committed
|
||||
on a copy of the database (a temporary file) and a save action is
|
||||
therefore necessary to keep modifications in the original file.
|
||||
|
||||
If an empty string for the database path is given in parameter, then
|
||||
a database is created in a temporary file whatever the copy mode.
|
||||
|
||||
If the database path given in parameter is not empty but does not exist,
|
||||
then a database is created at this location when copy mode is
|
||||
deactivated. When copy mode is activated, a temporary database is used
|
||||
instead and a save action will be necessary to create the database at
|
||||
the original location given in parameter.
|
||||
|
||||
\param filename The path of the database
|
||||
\param copy Parameter indicating if a copy of the database has to be used
|
||||
%End
|
||||
|
||||
virtual ~QgsAuxiliaryStorage();
|
||||
%Docstring
|
||||
Destructor.
|
||||
%End
|
||||
|
||||
bool isValid() const;
|
||||
%Docstring
|
||||
Returns the status of the auxiliary storage currently definied.
|
||||
|
||||
:return: true if the auxiliary storage is valid, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QString fileName() const;
|
||||
%Docstring
|
||||
Returns the target filename of the database.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QString currentFileName() const;
|
||||
%Docstring
|
||||
Returns the path of current database used. It may be different from the
|
||||
target filename if the auxiliary storage is opened in copy mode.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
bool saveAs( const QString &filename ) const;
|
||||
%Docstring
|
||||
Saves the current database to a new path.
|
||||
|
||||
:return: true if everything is saved, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool saveAs( const QgsProject &project ) const;
|
||||
%Docstring
|
||||
Saves the current database to a new path for a specific project.
|
||||
Actually, the current filename of the project is used to deduce the
|
||||
path of the database to save.
|
||||
|
||||
:return: true if everything is saved, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool save() const;
|
||||
%Docstring
|
||||
Saves the current database.
|
||||
|
||||
:return: true if everything is saved, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsAuxiliaryLayer *createAuxiliaryLayer( const QgsField &field, QgsVectorLayer *layer ) const /Factory/;
|
||||
%Docstring
|
||||
Creates an auxiliary layer for a vector layer. A new table is created if
|
||||
necessary. The primary key to use to construct the auxiliary layer is
|
||||
given in parameter.
|
||||
|
||||
\param field The primary key to join
|
||||
\param layer The vector layer for which the auxiliary layer has to be created
|
||||
|
||||
:return: A new auxiliary layer or a None if an error happened.
|
||||
:rtype: QgsAuxiliaryLayer
|
||||
%End
|
||||
|
||||
static bool deleteTable( const QgsDataSourceUri &uri );
|
||||
%Docstring
|
||||
Removes a table from the auxiliary storage.
|
||||
|
||||
\param uri The uri of the table to remove
|
||||
|
||||
:return: true if the table is well deleted, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static bool duplicateTable( const QgsDataSourceUri &uri, const QString &newTable );
|
||||
%Docstring
|
||||
Duplicates a table and its content.
|
||||
|
||||
\param uri The uri of the table to duplicate
|
||||
\param newTable The name of the new table
|
||||
|
||||
:return: true if the table is well duplicated, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static QString extension();
|
||||
%Docstring
|
||||
Returns the extension used for auxiliary databases.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/qgsauxiliarystorage.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -811,6 +811,15 @@ Returns the number of registered layers.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
|
||||
QgsAuxiliaryStorage *auxiliaryStorage();
|
||||
%Docstring
|
||||
Returns the current auxiliary storage.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: QgsAuxiliaryStorage
|
||||
%End
|
||||
|
||||
signals:
|
||||
void readProject( const QDomDocument & );
|
||||
%Docstring
|
||||
|
@ -72,15 +72,17 @@ class QgsPropertyDefinition
|
||||
Constructs an empty property.
|
||||
%End
|
||||
|
||||
QgsPropertyDefinition( const QString &name, const QString &description, StandardPropertyTemplate type );
|
||||
QgsPropertyDefinition( const QString &name, const QString &description, StandardPropertyTemplate type, const QString &origin = QString(), const QString &comment = QString() );
|
||||
%Docstring
|
||||
Constructor for QgsPropertyDefinition, using a standard property template.
|
||||
\param name is used internally and should be a unique, alphanumeric string.
|
||||
\param description can be any localised string describing what the property is used for.
|
||||
\param type one of the predefined standard property template
|
||||
\param origin The origin of the property
|
||||
\param comment A free comment for the property
|
||||
%End
|
||||
|
||||
QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText );
|
||||
QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText, const QString &origin = QString(), const QString &comment = QString() );
|
||||
%Docstring
|
||||
Constructor for custom QgsPropertyDefinitions.
|
||||
\param name is used internally and should be a unique, alphanumeric string.
|
||||
@ -88,6 +90,8 @@ class QgsPropertyDefinition
|
||||
\param description can be any localised string describing what the property is used for.
|
||||
\param helpText parameter should specify a descriptive string for users outlining the types
|
||||
of value acceptable by the property (eg 'dashed' or 'solid' for a line style property).
|
||||
\param origin The origin of the property
|
||||
\param comment A free comment for the property
|
||||
%End
|
||||
|
||||
QString name() const;
|
||||
@ -96,18 +100,54 @@ class QgsPropertyDefinition
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setName( const QString &name );
|
||||
%Docstring
|
||||
Sets the name of the property
|
||||
%End
|
||||
|
||||
QString origin() const;
|
||||
%Docstring
|
||||
Returns the origin of the property. For example, a PAL property has an
|
||||
origin set to "labeling" while a diagram property has an origin set to
|
||||
"diagram".
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setOrigin( const QString &origin );
|
||||
%Docstring
|
||||
Sets the origin of the property. For example, a PAL property has an
|
||||
origin set to "labeling" while a diagram property has an origin set to
|
||||
"diagram".
|
||||
%End
|
||||
|
||||
QString description() const;
|
||||
%Docstring
|
||||
Descriptive name of the property.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QString comment() const;
|
||||
%Docstring
|
||||
Returns the comment of the property
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setComment( const QString &comment );
|
||||
%Docstring
|
||||
Sets comment of the property
|
||||
%End
|
||||
|
||||
QString helpText() const;
|
||||
%Docstring
|
||||
Helper text for using the property, including a description of the valid values for the property.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setDataType( DataType type );
|
||||
%Docstring
|
||||
Sets the data type
|
||||
%End
|
||||
|
||||
DataType dataType() const;
|
||||
%Docstring
|
||||
Returns the allowable field/value data type for the property.
|
||||
|
@ -223,6 +223,7 @@ Try to find a rule given its unique key
|
||||
:rtype: QgsRuleBasedLabeling.Rule
|
||||
%End
|
||||
|
||||
|
||||
QgsRuleBasedLabeling::Rule *clone() const /Factory/;
|
||||
%Docstring
|
||||
clone this rule, return new instance
|
||||
@ -285,6 +286,16 @@ Create the instance from a DOM element with saved configuration
|
||||
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
|
||||
virtual QStringList subProviders() const;
|
||||
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const;
|
||||
|
||||
virtual void setSettings( QgsPalLayerSettings *settings /Transfer/, const QString &providerId = QString() );
|
||||
%Docstring
|
||||
Set pal settings for a specific provider (takes ownership).
|
||||
|
||||
\param settings Pal layer settings
|
||||
\param providerId The id of the provider
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
virtual bool requiresAdvancedEffects() const;
|
||||
|
||||
|
||||
|
@ -774,6 +774,41 @@ Return the provider type for this layer
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
bool loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage, const QString &key = QString() );
|
||||
%Docstring
|
||||
Loads the auxiliary layer for this vector layer. If there's no
|
||||
corresponding table in the database, then nothing happens and false is
|
||||
returned. The key is optional because if this layer has been read from
|
||||
a XML document, then the key read in this document is used by default.
|
||||
|
||||
\param storage The auxiliary storage where to look for the table
|
||||
\param key The key to use for joining.
|
||||
|
||||
:return: true if the auxiliary layer is well loaded, false otherwise
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setAuxiliaryLayer( QgsAuxiliaryLayer *layer /Transfer/ = 0 );
|
||||
%Docstring
|
||||
Sets the current auxiliary layer. The auxiliary layer is automatically
|
||||
put in editable mode and fields are updated. Moreover, a join is created
|
||||
between the current layer and the auxiliary layer. Ownership is
|
||||
transferred.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
QgsAuxiliaryLayer *auxiliaryLayer();
|
||||
%Docstring
|
||||
Returns the current auxiliary layer.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: QgsAuxiliaryLayer
|
||||
%End
|
||||
|
||||
|
||||
virtual bool readSymbology( const QDomNode &layerNode, QString &errorMessage, const QgsReadWriteContext &context );
|
||||
|
||||
%Docstring
|
||||
@ -1059,7 +1094,8 @@ Return the provider type for this layer
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
const QgsAbstractVectorLayerLabeling *labeling() const;
|
||||
|
||||
QgsAbstractVectorLayerLabeling *labeling();
|
||||
%Docstring
|
||||
Access to labeling configuration. May be null if labeling is not used.
|
||||
.. versionadded:: 3.0
|
||||
@ -1090,6 +1126,15 @@ Returns true if the provider has been modified since the last commit
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool isAuxiliaryField( int index, int &srcIndex ) const;
|
||||
%Docstring
|
||||
Returns true if the field comes from the auxiliary layer,
|
||||
false otherwise.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual void reload();
|
||||
%Docstring
|
||||
Synchronises with changes in the datasource
|
||||
@ -1269,7 +1314,7 @@ Returns a map of field name to attribute alias
|
||||
A set of attributes that are not advertised in WFS requests with QGIS server.
|
||||
%End
|
||||
|
||||
bool deleteAttribute( int attr );
|
||||
virtual bool deleteAttribute( int attr );
|
||||
%Docstring
|
||||
Delete an attribute field (but does not commit it)
|
||||
:rtype: bool
|
||||
|
@ -130,6 +130,18 @@ Quick way to test if there is any join at all
|
||||
:rtype: QgsFeature
|
||||
%End
|
||||
|
||||
bool isAuxiliaryJoin( const QgsVectorLayerJoinInfo &info ) const;
|
||||
%Docstring
|
||||
Returns true if the join information is about auxiliary layer, false otherwise
|
||||
|
||||
\param info The join information
|
||||
|
||||
:return: true if the join information is about auxiliary layer, false otherwise
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsVectorLayerJoinBuffer *clone() const /Factory/;
|
||||
%Docstring
|
||||
Create a copy of the join buffer
|
||||
|
@ -166,6 +166,39 @@ Returns whether values from the joined layer should be cached in memory to speed
|
||||
:rtype: QgsFeature
|
||||
%End
|
||||
|
||||
void setJoinFieldNamesBlackList( const QStringList &blackList );
|
||||
%Docstring
|
||||
Sets a list of fields to ignore whatever happens.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
QStringList joinFieldNamesBlackList() const;
|
||||
%Docstring
|
||||
Returns the list of fields to ignore.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
bool hasSubset( bool blacklisted = true ) const;
|
||||
%Docstring
|
||||
Returns true if blacklisted fields is not empty or if a subset of names
|
||||
has been set.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static QStringList joinFieldNamesSubset( const QgsVectorLayerJoinInfo &info, bool blacklisted = true );
|
||||
%Docstring
|
||||
Returns the list of field names to use for joining considering
|
||||
blacklisted fields and subset.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
bool operator==( const QgsVectorLayerJoinInfo &other ) const;
|
||||
|
||||
void setJoinFieldNamesSubset( QStringList *fieldNamesSubset /Transfer/ );
|
||||
@ -194,6 +227,7 @@ Returns whether values from the joined layer should be cached in memory to speed
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -61,6 +61,16 @@ Get list of sub-providers within the layer's labeling.
|
||||
:rtype: QgsPalLayerSettings
|
||||
%End
|
||||
|
||||
virtual void setSettings( QgsPalLayerSettings *settings /Transfer/, const QString &providerId = QString() ) = 0;
|
||||
%Docstring
|
||||
Set pal settings for a specific provider (takes ownership).
|
||||
|
||||
\param settings Pal layer settings
|
||||
\param providerId The id of the provider
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
virtual bool requiresAdvancedEffects() const = 0;
|
||||
%Docstring
|
||||
Returns true if drawing labels requires advanced effects like composition
|
||||
@ -109,6 +119,17 @@ Constructs simple labeling configuration with given initial settings
|
||||
virtual QgsAbstractVectorLayerLabeling *clone() const /Factory/;
|
||||
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
|
||||
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const;
|
||||
|
||||
virtual void setSettings( QgsPalLayerSettings *settings /Transfer/, const QString &providerId = QString() );
|
||||
%Docstring
|
||||
Set pal settings (takes ownership).
|
||||
|
||||
\param settings Pal layer settings
|
||||
\param providerId Unused parameter
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
virtual bool requiresAdvancedEffects() const;
|
||||
|
||||
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const;
|
||||
|
@ -47,7 +47,7 @@ In C++ you can use QgsSymbolLayerMetadata convenience class.
|
||||
Create a symbol layer of this type given the map of properties.
|
||||
:rtype: QgsSymbolLayer
|
||||
%End
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( const QgsVectorLayer * ) /Factory/;
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( QgsVectorLayer * ) /Factory/;
|
||||
%Docstring
|
||||
Create widget for symbol layer of this type. Can return NULL if there's no GUI
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
@ -86,7 +86,7 @@ Convenience metadata class that uses static functions to create symbol layer and
|
||||
|
||||
|
||||
virtual QgsSymbolLayer *createSymbolLayer( const QgsStringMap &map ) /Factory/;
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( const QgsVectorLayer *vl ) /Factory/;
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( QgsVectorLayer *vl ) /Factory/;
|
||||
virtual QgsSymbolLayer *createSymbolLayerFromSld( QDomElement &elem ) /Factory/;
|
||||
virtual void resolvePaths( QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving );
|
||||
|
||||
|
@ -152,6 +152,8 @@
|
||||
%Include qgsmessagelogviewer.sip
|
||||
%Include qgsmessageviewer.sip
|
||||
%Include qgsmetadatawidget.sip
|
||||
%Include qgsnewauxiliarylayerdialog.sip
|
||||
%Include qgsnewauxiliaryfielddialog.sip
|
||||
%Include qgsnewhttpconnection.sip
|
||||
%Include qgsnewmemorylayerdialog.sip
|
||||
%Include qgsnewnamedialog.sip
|
||||
|
54
python/gui/qgsnewauxiliaryfielddialog.sip
Normal file
54
python/gui/qgsnewauxiliaryfielddialog.sip
Normal file
@ -0,0 +1,54 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsnewauxiliaryfielddialog.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsNewAuxiliaryFieldDialog: QDialog
|
||||
{
|
||||
%Docstring
|
||||
|
||||
A dialog to create a new auxiliary field
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsnewauxiliaryfielddialog.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsNewAuxiliaryFieldDialog( const QgsPropertyDefinition &definition, QgsVectorLayer *layer, bool nameOnly = true, QWidget *parent = 0 );
|
||||
%Docstring
|
||||
Constructor.
|
||||
|
||||
\param definition The property definition to use to create the auxiliary field
|
||||
\param layer The vector layer for which the auxiliary layer has to be created
|
||||
\param nameOnly True to indicate that only the name widget is enabled
|
||||
\param parent Parent window
|
||||
%End
|
||||
|
||||
QgsPropertyDefinition propertyDefinition() const;
|
||||
%Docstring
|
||||
Returns the underlying property definition.
|
||||
:rtype: QgsPropertyDefinition
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void accept();
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsnewauxiliaryfielddialog.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
46
python/gui/qgsnewauxiliarylayerdialog.sip
Normal file
46
python/gui/qgsnewauxiliarylayerdialog.sip
Normal file
@ -0,0 +1,46 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsnewauxiliarylayerdialog.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsNewAuxiliaryLayerDialog: QDialog
|
||||
{
|
||||
%Docstring
|
||||
|
||||
A dialog to create a new auxiliary layer
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsNewAuxiliaryLayerDialog( QgsVectorLayer *layer, QWidget *parent = 0 );
|
||||
%Docstring
|
||||
Constructor.
|
||||
|
||||
\param layer The vector layer for which the auxiliary layer has to be created
|
||||
\param parent Parent window
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void accept();
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsnewauxiliarylayerdialog.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -42,25 +42,29 @@ class QgsPropertyOverrideButton: QToolButton
|
||||
void init( int propertyKey,
|
||||
const QgsProperty &property,
|
||||
const QgsPropertiesDefinition &definitions,
|
||||
const QgsVectorLayer *layer = 0 );
|
||||
const QgsVectorLayer *layer = 0,
|
||||
bool auxiliaryStorageEnabled = false );
|
||||
%Docstring
|
||||
Initialize a newly constructed property button (useful if button was included in a UI layout).
|
||||
\param propertyKey key for corresponding property
|
||||
\param property initial value of associated property to show in widget
|
||||
\param definitions properties definitions for corresponding collection
|
||||
\param layer associated vector layer
|
||||
\param auxiliaryStorageEnabled If true, activate the button to store data defined in auxiliary storage
|
||||
%End
|
||||
|
||||
void init( int propertyKey,
|
||||
const QgsAbstractPropertyCollection &collection,
|
||||
const QgsPropertiesDefinition &definitions,
|
||||
const QgsVectorLayer *layer = 0 );
|
||||
const QgsVectorLayer *layer = 0,
|
||||
bool auxiliaryStorageEnabled = false );
|
||||
%Docstring
|
||||
Initialize a newly constructed property button (useful if button was included in a UI layout).
|
||||
\param propertyKey key for corresponding property
|
||||
\param collection associated property collection
|
||||
\param definitions properties definitions for collection
|
||||
\param layer associated vector layer
|
||||
\param auxiliaryStorageEnabled If true, activate the button to store data defined in auxiliary storage
|
||||
%End
|
||||
|
||||
QgsProperty toProperty() const;
|
||||
@ -172,6 +176,13 @@ class QgsPropertyOverrideButton: QToolButton
|
||||
an expression context for the button when required.
|
||||
%End
|
||||
|
||||
void updateFieldLists();
|
||||
%Docstring
|
||||
Updates list of fields.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
@ -190,6 +201,11 @@ Emitted when property definition changes
|
||||
void activated( bool isActive );
|
||||
%Docstring
|
||||
Emitted when the activated status of the widget changes
|
||||
%End
|
||||
|
||||
void createAuxiliaryField();
|
||||
%Docstring
|
||||
Emitted when creating a new auxiliary field
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
@ -16,14 +16,14 @@ class QgsArrowSymbolLayerWidget: QgsSymbolLayerWidget
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsArrowSymbolLayerWidget( const QgsVectorLayer *layer, QWidget *parent /TransferThis/ = 0 );
|
||||
QgsArrowSymbolLayerWidget( QgsVectorLayer *layer, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor
|
||||
\param layer the layer where this symbol layer is applied
|
||||
\param parent the parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *layer ) /Factory/;
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *layer ) /Factory/;
|
||||
%Docstring
|
||||
Static creation method
|
||||
\param layer the layer where this symbol layer is applied
|
||||
|
@ -15,10 +15,18 @@ class QgsEllipseSymbolLayerWidget: QgsSymbolLayerWidget
|
||||
#include "qgsellipsesymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsEllipseSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsEllipseSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsEllipseSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
|
@ -18,7 +18,15 @@ class QgsLayerPropertiesWidget : QgsPanelWidget, QgsExpressionContextGenerator
|
||||
#include "qgslayerpropertieswidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsLayerPropertiesWidget( QgsSymbolLayer *layer, const QgsSymbol *symbol, const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
QgsLayerPropertiesWidget( QgsSymbolLayer *layer, const QgsSymbol *symbol, QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsLayerPropertiesWidget.
|
||||
\param layer the symbol layer
|
||||
\param symbol the symbol
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
void setContext( const QgsSymbolWidgetContext &context );
|
||||
%Docstring
|
||||
|
@ -16,7 +16,13 @@ class QgsSymbolLayerWidget : QWidget, protected QgsExpressionContextGenerator
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsSymbolLayerWidget( QWidget *parent /TransferThis/, const QgsVectorLayer *vl = 0 );
|
||||
|
||||
QgsSymbolLayerWidget( QWidget *parent /TransferThis/, QgsVectorLayer *vl = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) = 0;
|
||||
virtual QgsSymbolLayer *symbolLayer() = 0;
|
||||
@ -91,10 +97,18 @@ class QgsSimpleLineSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsSimpleLineSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsSimpleLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsSimpleLineSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsSimpleLineSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -117,10 +131,18 @@ class QgsSimpleMarkerSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsSimpleMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsSimpleMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsSimpleMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsSimpleMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -146,10 +168,18 @@ class QgsSimpleFillSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsSimpleFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsSimpleFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsSimpleFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsSimpleFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -180,14 +210,14 @@ class QgsFilledMarkerSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsFilledMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
QgsFilledMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsFilledMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsFilledMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
@ -211,10 +241,18 @@ class QgsGradientFillSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsGradientFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsGradientFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsGradientFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsGradientFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -247,10 +285,18 @@ class QgsShapeburstFillSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsShapeburstFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsShapeburstFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsShapeburstFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsShapeburstFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -275,10 +321,18 @@ class QgsMarkerLineSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsMarkerLineSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsMarkerLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsMarkerLineSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsMarkerLineSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -306,10 +360,18 @@ class QgsSvgMarkerSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsSvgMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsSvgMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsSvgMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsSvgMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -334,10 +396,18 @@ class QgsRasterFillSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsRasterFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsRasterFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsRasterFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsRasterFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -358,10 +428,18 @@ class QgsSVGFillSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsSVGFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsSVGFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsSVGFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsSVGFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -392,9 +470,17 @@ class QgsLinePatternFillSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsLinePatternFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsLinePatternFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsLinePatternFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsLinePatternFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -415,9 +501,18 @@ class QgsPointPatternFillSymbolLayerWidget: QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsPointPatternFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
|
||||
QgsPointPatternFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsPointPatternFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsPointPatternFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -438,10 +533,18 @@ class QgsFontMarkerSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsFontMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsFontMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsFontMarkerSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -476,10 +579,18 @@ class QgsCentroidFillSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsCentroidFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsCentroidFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsCentroidFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsCentroidFillSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
@ -500,9 +611,15 @@ class QgsGeometryGeneratorSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsGeometryGeneratorSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsGeometryGeneratorSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsGeometryGeneratorSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Will be registered as factory
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
|
@ -28,7 +28,7 @@ class QgsSymbolSelectorWidget: QgsPanelWidget
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *style, const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Symbol selector widget that can be used to select and build a symbol
|
||||
\param symbol The symbol to load into the widget as a start point.
|
||||
@ -184,7 +184,17 @@ class QgsSymbolSelectorDialog : QDialog
|
||||
#include "qgssymbolselectordialog.h"
|
||||
%End
|
||||
public:
|
||||
QgsSymbolSelectorDialog( QgsSymbol *symbol, QgsStyle *style, const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0, bool embedded = false );
|
||||
|
||||
QgsSymbolSelectorDialog( QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0, bool embedded = false );
|
||||
%Docstring
|
||||
Constructor for QgsSymbolSelectorDialog.
|
||||
|
||||
\param symbol The symbol
|
||||
\param style The style
|
||||
\param vl Associated vector layer
|
||||
\param parent Parent widget
|
||||
\param embedded True to embed in renderer properties dialog, false otherwise
|
||||
%End
|
||||
~QgsSymbolSelectorDialog();
|
||||
|
||||
QMenu *advancedMenu();
|
||||
|
@ -19,7 +19,16 @@ class QgsSymbolsListWidget : QWidget
|
||||
#include "qgssymbolslistwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent /TransferThis/, const QgsVectorLayer *layer = 0 );
|
||||
|
||||
QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent /TransferThis/, QgsVectorLayer *layer = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsSymbolsListWidget.
|
||||
\param symbol the symbol
|
||||
\param style the style
|
||||
\param menu the menu where to show it
|
||||
\param parent parent widget
|
||||
\param layer associated vector layer
|
||||
%End
|
||||
|
||||
|
||||
virtual ~QgsSymbolsListWidget();
|
||||
|
@ -15,10 +15,18 @@ class QgsVectorFieldSymbolLayerWidget: QgsSymbolLayerWidget
|
||||
#include "qgsvectorfieldsymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
QgsVectorFieldSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) /Factory/;
|
||||
QgsVectorFieldSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsVectorFieldSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
\param parent parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsVectorFieldSymbolLayerWidget.
|
||||
\param vl associated vector layer
|
||||
:rtype: QgsSymbolLayerWidget
|
||||
%End
|
||||
|
||||
|
@ -98,6 +98,7 @@ typedef SInt32 SRefCon;
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgis_app.h"
|
||||
#include "qgscrashhandler.h"
|
||||
#include "qgsziputils.h"
|
||||
|
||||
#include "qgsuserprofilemanager.h"
|
||||
#include "qgsuserprofile.h"
|
||||
@ -1169,7 +1170,8 @@ int main( int argc, char *argv[] )
|
||||
{
|
||||
QgsDebugMsg( QString( "Trying to load file : %1" ).arg( layerName ) );
|
||||
// don't load anything with a .qgs extension - these are project files
|
||||
if ( !layerName.endsWith( QLatin1String( ".qgs" ), Qt::CaseInsensitive ) )
|
||||
if ( !layerName.endsWith( QLatin1String( ".qgs" ), Qt::CaseInsensitive )
|
||||
&& !QgsZipUtils::isZipFile( layerName ) )
|
||||
{
|
||||
qgis->openLayer( layerName );
|
||||
}
|
||||
|
@ -79,6 +79,7 @@
|
||||
#include "qgstaskmanager.h"
|
||||
#include "qgsziputils.h"
|
||||
#include "qgsbrowsermodel.h"
|
||||
#include "qgsvectorlayerjoinbuffer.h"
|
||||
|
||||
#ifdef HAVE_3D
|
||||
#include "qgsabstract3drenderer.h"
|
||||
@ -1856,7 +1857,7 @@ void QgisApp::createActions()
|
||||
connect( mActionRollbackAllEdits, &QAction::triggered, this, &QgisApp::rollbackAllEdits );
|
||||
connect( mActionCancelEdits, &QAction::triggered, this, [ = ] { cancelEdits(); } );
|
||||
connect( mActionCancelAllEdits, &QAction::triggered, this, &QgisApp::cancelAllEdits );
|
||||
connect( mActionLayerSaveAs, &QAction::triggered, this, &QgisApp::saveAsFile );
|
||||
connect( mActionLayerSaveAs, &QAction::triggered, this, [ = ] { saveAsFile(); } );
|
||||
connect( mActionSaveLayerDefinition, &QAction::triggered, this, &QgisApp::saveAsLayerDefinition );
|
||||
connect( mActionRemoveLayer, &QAction::triggered, this, &QgisApp::removeLayer );
|
||||
connect( mActionDuplicateLayer, &QAction::triggered, this, [ = ] { duplicateLayers(); } );
|
||||
@ -6442,9 +6443,11 @@ void QgisApp::attributeTable()
|
||||
// the dialog will be deleted by itself on close
|
||||
}
|
||||
|
||||
void QgisApp::saveAsRasterFile()
|
||||
void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
|
||||
{
|
||||
QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( activeLayer() );
|
||||
if ( !rasterLayer )
|
||||
rasterLayer = qobject_cast<QgsRasterLayer *>( activeLayer() );
|
||||
|
||||
if ( !rasterLayer )
|
||||
{
|
||||
return;
|
||||
@ -6578,20 +6581,22 @@ void QgisApp::saveAsRasterFile()
|
||||
}
|
||||
|
||||
|
||||
void QgisApp::saveAsFile()
|
||||
void QgisApp::saveAsFile( QgsMapLayer *layer )
|
||||
{
|
||||
QgsMapLayer *layer = activeLayer();
|
||||
if ( !layer )
|
||||
layer = activeLayer();
|
||||
|
||||
if ( !layer )
|
||||
return;
|
||||
|
||||
QgsMapLayer::LayerType layerType = layer->type();
|
||||
if ( layerType == QgsMapLayer::RasterLayer )
|
||||
{
|
||||
saveAsRasterFile();
|
||||
saveAsRasterFile( qobject_cast<QgsRasterLayer *>( layer ) );
|
||||
}
|
||||
else if ( layerType == QgsMapLayer::VectorLayer )
|
||||
{
|
||||
saveAsVectorFileGeneral();
|
||||
saveAsVectorFileGeneral( qobject_cast<QgsVectorLayer *>( layer ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -8631,7 +8636,14 @@ void QgisApp::layerSubsetString()
|
||||
if ( !vlayer )
|
||||
return;
|
||||
|
||||
if ( !vlayer->vectorJoins().isEmpty() )
|
||||
bool joins = !vlayer->vectorJoins().isEmpty();
|
||||
if ( vlayer->vectorJoins().size() == 1 )
|
||||
{
|
||||
QgsVectorLayerJoinInfo info = vlayer->vectorJoins()[0];
|
||||
joins = !vlayer->joinBuffer()->isAuxiliaryJoin( info );
|
||||
}
|
||||
|
||||
if ( joins )
|
||||
{
|
||||
if ( QMessageBox::question( nullptr, tr( "Filter on joined fields" ),
|
||||
tr( "You are about to set a subset filter on a layer that has joined fields. "
|
||||
@ -8869,6 +8881,9 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
|
||||
}
|
||||
else if ( vlayer )
|
||||
{
|
||||
if ( vlayer->auxiliaryLayer() )
|
||||
vlayer->auxiliaryLayer()->save();
|
||||
|
||||
dupLayer = vlayer->clone();
|
||||
}
|
||||
}
|
||||
@ -10993,38 +11008,16 @@ void QgisApp::updateLabelToolButtons()
|
||||
for ( QMap<QString, QgsMapLayer *>::iterator it = layers.begin(); it != layers.end(); ++it )
|
||||
{
|
||||
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( it.value() );
|
||||
if ( !vlayer || !vlayer->isEditable() ||
|
||||
( !vlayer->diagramsEnabled() && !vlayer->labelsEnabled() ) )
|
||||
continue;
|
||||
if ( vlayer && ( vlayer->diagramsEnabled() || vlayer->labelsEnabled() ) )
|
||||
{
|
||||
enablePin = true;
|
||||
enableShowHide = true;
|
||||
enableMove = true;
|
||||
enableRotate = true;
|
||||
enableChange = true;
|
||||
|
||||
int colX, colY, colShow, colAng;
|
||||
enablePin =
|
||||
enablePin ||
|
||||
( qobject_cast<QgsMapToolPinLabels *>( mMapTools.mPinLabels ) &&
|
||||
( qobject_cast<QgsMapToolPinLabels *>( mMapTools.mPinLabels )->labelMoveable( vlayer, colX, colY )
|
||||
|| qobject_cast<QgsMapToolPinLabels *>( mMapTools.mPinLabels )->diagramMoveable( vlayer, colX, colY ) ) );
|
||||
|
||||
enableShowHide =
|
||||
enableShowHide ||
|
||||
( qobject_cast<QgsMapToolShowHideLabels *>( mMapTools.mShowHideLabels ) &&
|
||||
( qobject_cast<QgsMapToolShowHideLabels *>( mMapTools.mShowHideLabels )->labelCanShowHide( vlayer, colShow )
|
||||
|| qobject_cast<QgsMapToolShowHideLabels *>( mMapTools.mShowHideLabels )->diagramCanShowHide( vlayer, colShow ) ) );
|
||||
|
||||
enableMove =
|
||||
enableMove ||
|
||||
( qobject_cast<QgsMapToolMoveLabel *>( mMapTools.mMoveLabel ) &&
|
||||
( qobject_cast<QgsMapToolMoveLabel *>( mMapTools.mMoveLabel )->labelMoveable( vlayer, colX, colY )
|
||||
|| qobject_cast<QgsMapToolMoveLabel *>( mMapTools.mMoveLabel )->diagramMoveable( vlayer, colX, colY ) ) );
|
||||
|
||||
enableRotate =
|
||||
enableRotate ||
|
||||
( qobject_cast<QgsMapToolRotateLabel *>( mMapTools.mRotateLabel ) &&
|
||||
qobject_cast<QgsMapToolRotateLabel *>( mMapTools.mRotateLabel )->layerIsRotatable( vlayer, colAng ) );
|
||||
|
||||
enableChange = true;
|
||||
|
||||
if ( enablePin && enableShowHide && enableMove && enableRotate && enableChange )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mActionPinLabels->setEnabled( enablePin );
|
||||
|
@ -654,6 +654,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
QSize iconSize( bool dockedToolbar = false ) const;
|
||||
|
||||
public slots:
|
||||
//! save current vector layer
|
||||
void saveAsFile( QgsMapLayer *layer = nullptr );
|
||||
|
||||
//! Process the list of URIs that have been dropped in QGIS
|
||||
void handleDropUriList( const QgsMimeDataUtils::UriList &lst );
|
||||
//! Convenience function to open either a project or a layer file.
|
||||
@ -1439,13 +1442,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
//! set the CAD dock widget visible
|
||||
void setCadDockVisible( bool visible );
|
||||
|
||||
//! save current vector layer
|
||||
void saveAsFile();
|
||||
|
||||
void saveAsLayerDefinition();
|
||||
|
||||
//! save current raster layer
|
||||
void saveAsRasterFile();
|
||||
void saveAsRasterFile( QgsRasterLayer *layer = nullptr );
|
||||
|
||||
//! show Python console
|
||||
void showPythonDialog();
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgisapp.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMessageBox>
|
||||
@ -484,8 +486,9 @@ QgsDiagramProperties::~QgsDiagramProperties()
|
||||
|
||||
void QgsDiagramProperties::registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsDiagramLayerSettings::Property key )
|
||||
{
|
||||
button->init( key, mDataDefinedProperties, QgsDiagramLayerSettings::propertyDefinitions(), mLayer );
|
||||
button->init( key, mDataDefinedProperties, QgsDiagramLayerSettings::propertyDefinitions(), mLayer, true );
|
||||
connect( button, &QgsPropertyOverrideButton::changed, this, &QgsDiagramProperties::updateProperty );
|
||||
connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsDiagramProperties::createAuxiliaryField );
|
||||
button->registerExpressionContextGenerator( this );
|
||||
}
|
||||
|
||||
@ -1048,3 +1051,35 @@ void QgsDiagramProperties::showHelp()
|
||||
{
|
||||
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#legend" ) );
|
||||
}
|
||||
|
||||
void QgsDiagramProperties::createAuxiliaryField()
|
||||
{
|
||||
// try to create an auxiliary layer if not yet created
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
// return if still not exists
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
return;
|
||||
|
||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||
const QgsDiagramLayerSettings::Property key = static_cast< QgsDiagramLayerSettings::Property >( button->propertyKey() );
|
||||
const QgsPropertyDefinition def = QgsDiagramLayerSettings::propertyDefinitions()[key];
|
||||
|
||||
// create property in auxiliary storage if necessary
|
||||
if ( !mLayer->auxiliaryLayer()->exists( def ) )
|
||||
mLayer->auxiliaryLayer()->addAuxiliaryField( def );
|
||||
|
||||
// update property with join field name from auxiliary storage
|
||||
QgsProperty property = button->toProperty();
|
||||
property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
|
||||
property.setActive( true );
|
||||
button->updateFieldLists();
|
||||
button->setToProperty( property );
|
||||
mDataDefinedProperties.setProperty( key, button->toProperty() );
|
||||
|
||||
emit auxiliaryFieldCreated();
|
||||
}
|
||||
|
@ -39,6 +39,10 @@ class APP_EXPORT QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPr
|
||||
//! Adds an attribute from the list of available attributes to the assigned attributes with a random color.
|
||||
void addAttribute( QTreeWidgetItem *item );
|
||||
|
||||
signals:
|
||||
|
||||
void auxiliaryFieldCreated();
|
||||
|
||||
public slots:
|
||||
void apply();
|
||||
void mDiagramTypeComboBox_currentIndexChanged( int index );
|
||||
@ -95,6 +99,8 @@ class APP_EXPORT QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPr
|
||||
|
||||
void updateProperty();
|
||||
void showHelp();
|
||||
|
||||
void createAuxiliaryField();
|
||||
};
|
||||
|
||||
class EditBlockerDelegate: public QStyledItemDelegate
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsvectorlayerlabeling.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
|
||||
QgsExpressionContext QgsLabelingGui::createExpressionContext() const
|
||||
{
|
||||
@ -44,9 +46,12 @@ QgsExpressionContext QgsLabelingGui::createExpressionContext() const
|
||||
|
||||
void QgsLabelingGui::registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsPalLayerSettings::Property key )
|
||||
{
|
||||
button->init( key, mDataDefinedProperties, QgsPalLayerSettings::propertyDefinitions(), mLayer );
|
||||
button->init( key, mDataDefinedProperties, QgsPalLayerSettings::propertyDefinitions(), mLayer, true );
|
||||
connect( button, &QgsPropertyOverrideButton::changed, this, &QgsLabelingGui::updateProperty );
|
||||
connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsLabelingGui::createAuxiliaryField );
|
||||
button->registerExpressionContextGenerator( this );
|
||||
|
||||
mButtons[key] = button;
|
||||
}
|
||||
|
||||
void QgsLabelingGui::updateProperty()
|
||||
@ -610,6 +615,48 @@ void QgsLabelingGui::updateUi()
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLabelingGui::createAuxiliaryField()
|
||||
{
|
||||
// try to create an auxiliary layer if not yet created
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
// return if still not exists
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
return;
|
||||
|
||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||
const QgsPalLayerSettings::Property key = static_cast< QgsPalLayerSettings::Property >( button->propertyKey() );
|
||||
const QgsPropertyDefinition def = QgsPalLayerSettings::propertyDefinitions()[key];
|
||||
|
||||
// create property in auxiliary storage if necessary
|
||||
if ( !mLayer->auxiliaryLayer()->exists( def ) )
|
||||
mLayer->auxiliaryLayer()->addAuxiliaryField( def );
|
||||
|
||||
// update property with join field name from auxiliary storage
|
||||
QgsProperty property = button->toProperty();
|
||||
property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
|
||||
property.setActive( true );
|
||||
button->updateFieldLists();
|
||||
button->setToProperty( property );
|
||||
mDataDefinedProperties.setProperty( key, button->toProperty() );
|
||||
|
||||
emit auxiliaryFieldCreated();
|
||||
}
|
||||
|
||||
void QgsLabelingGui::deactivateField( QgsPalLayerSettings::Property key )
|
||||
{
|
||||
if ( mButtons.contains( key ) )
|
||||
{
|
||||
QgsPropertyOverrideButton *button = mButtons[ key ];
|
||||
QgsProperty p = button->toProperty();
|
||||
p.setField( QString() );
|
||||
p.setActive( false );
|
||||
button->updateFieldLists();
|
||||
button->setToProperty( p );
|
||||
mDataDefinedProperties.setProperty( key, p );
|
||||
}
|
||||
}
|
||||
|
@ -43,10 +43,26 @@ class APP_EXPORT QgsLabelingGui : public QgsTextFormatWidget, private QgsExpress
|
||||
|
||||
void setLayer( QgsMapLayer *layer );
|
||||
|
||||
/**
|
||||
* Deactivate a field from data defined properties and update the
|
||||
* corresponding button.
|
||||
*
|
||||
* \param key The property key to deactivate
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void deactivateField( QgsPalLayerSettings::Property key );
|
||||
|
||||
signals:
|
||||
|
||||
void auxiliaryFieldCreated();
|
||||
|
||||
public slots:
|
||||
|
||||
void updateUi();
|
||||
|
||||
void createAuxiliaryField();
|
||||
|
||||
protected:
|
||||
void blockInitSignals( bool block );
|
||||
void syncDefinedCheckboxFrame( QgsPropertyOverrideButton *ddBtn, QCheckBox *chkBx, QFrame *f );
|
||||
@ -62,6 +78,8 @@ class APP_EXPORT QgsLabelingGui : public QgsTextFormatWidget, private QgsExpress
|
||||
void populateDataDefinedButtons();
|
||||
void registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsPalLayerSettings::Property key );
|
||||
|
||||
QMap<QgsPalLayerSettings::Property, QgsPropertyOverrideButton *> mButtons;
|
||||
|
||||
private slots:
|
||||
|
||||
void updateProperty();
|
||||
|
@ -40,6 +40,11 @@ QgsLabelingWidget::QgsLabelingWidget( QgsVectorLayer *layer, QgsMapCanvas *canva
|
||||
setLayer( layer );
|
||||
}
|
||||
|
||||
QgsLabelingGui *QgsLabelingWidget::labelingGui()
|
||||
{
|
||||
return qobject_cast<QgsLabelingGui *>( mWidget );
|
||||
}
|
||||
|
||||
void QgsLabelingWidget::resetSettings()
|
||||
{
|
||||
if ( mOldSettings )
|
||||
@ -96,6 +101,12 @@ void QgsLabelingWidget::adaptToLayer()
|
||||
{
|
||||
mLabelModeComboBox->setCurrentIndex( 0 );
|
||||
}
|
||||
|
||||
QgsLabelingGui *lg = qobject_cast<QgsLabelingGui *>( mWidget );
|
||||
if ( lg )
|
||||
{
|
||||
lg->updateUi();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLabelingWidget::writeSettingsToLayer()
|
||||
@ -156,6 +167,7 @@ void QgsLabelingWidget::labelModeChanged( int index )
|
||||
QgsLabelingGui *simpleWidget = new QgsLabelingGui( mLayer, mCanvas, *mSimpleSettings, this );
|
||||
simpleWidget->setDockMode( dockMode() );
|
||||
connect( simpleWidget, &QgsTextFormatWidget::widgetChanged, this, &QgsLabelingWidget::widgetChanged );
|
||||
connect( simpleWidget, &QgsLabelingGui::auxiliaryFieldCreated, this, &QgsLabelingWidget::auxiliaryFieldCreated );
|
||||
|
||||
if ( index == 3 )
|
||||
simpleWidget->setLabelMode( QgsLabelingGui::ObstaclesOnly );
|
||||
|
@ -38,6 +38,13 @@ class QgsLabelingWidget : public QgsMapLayerConfigWidget, private Ui::QgsLabelin
|
||||
public:
|
||||
QgsLabelingWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr );
|
||||
|
||||
/**
|
||||
* Returns the labeling gui widget or a nullptr if none.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsLabelingGui *labelingGui();
|
||||
|
||||
public slots:
|
||||
void setLayer( QgsMapLayer *layer );
|
||||
//! save config to layer
|
||||
@ -51,6 +58,10 @@ class QgsLabelingWidget : public QgsMapLayerConfigWidget, private Ui::QgsLabelin
|
||||
|
||||
void resetSettings();
|
||||
|
||||
signals:
|
||||
|
||||
void auxiliaryFieldCreated();
|
||||
|
||||
protected slots:
|
||||
void labelModeChanged( int index );
|
||||
void showEngineConfigDialog();
|
||||
|
@ -131,6 +131,12 @@ void QgsLabelPropertyDialog::init( const QString &layerId, const QString &provid
|
||||
if ( mCurLabelField >= 0 )
|
||||
{
|
||||
mLabelTextLineEdit->setText( attributeValues.at( mCurLabelField ).toString() );
|
||||
|
||||
if ( vlayer->isEditable() )
|
||||
mLabelTextLineEdit->setEnabled( true );
|
||||
else
|
||||
mLabelTextLineEdit->setEnabled( false );
|
||||
|
||||
const QgsFields &layerFields = vlayer->fields();
|
||||
switch ( layerFields.at( mCurLabelField ).type() )
|
||||
{
|
||||
|
@ -23,6 +23,27 @@
|
||||
|
||||
QgsMapToolChangeLabelProperties::QgsMapToolChangeLabelProperties( QgsMapCanvas *canvas ): QgsMapToolLabel( canvas )
|
||||
{
|
||||
mPalProperties << QgsPalLayerSettings::PositionX;
|
||||
mPalProperties << QgsPalLayerSettings::PositionY;
|
||||
mPalProperties << QgsPalLayerSettings::Show;
|
||||
mPalProperties << QgsPalLayerSettings::LabelRotation;
|
||||
mPalProperties << QgsPalLayerSettings::Family;
|
||||
mPalProperties << QgsPalLayerSettings::FontStyle;
|
||||
mPalProperties << QgsPalLayerSettings::Size;
|
||||
mPalProperties << QgsPalLayerSettings::Bold;
|
||||
mPalProperties << QgsPalLayerSettings::Italic;
|
||||
mPalProperties << QgsPalLayerSettings::Underline;
|
||||
mPalProperties << QgsPalLayerSettings::Color;
|
||||
mPalProperties << QgsPalLayerSettings::Strikeout;
|
||||
mPalProperties << QgsPalLayerSettings::BufferSize;
|
||||
mPalProperties << QgsPalLayerSettings::BufferColor;
|
||||
mPalProperties << QgsPalLayerSettings::LabelDistance;
|
||||
mPalProperties << QgsPalLayerSettings::Hali;
|
||||
mPalProperties << QgsPalLayerSettings::Vali;
|
||||
mPalProperties << QgsPalLayerSettings::ScaleVisibility;
|
||||
mPalProperties << QgsPalLayerSettings::MinScale;
|
||||
mPalProperties << QgsPalLayerSettings::MaxScale;
|
||||
mPalProperties << QgsPalLayerSettings::AlwaysShow;
|
||||
}
|
||||
|
||||
void QgsMapToolChangeLabelProperties::canvasPressEvent( QgsMapMouseEvent *e )
|
||||
@ -37,12 +58,25 @@ void QgsMapToolChangeLabelProperties::canvasPressEvent( QgsMapMouseEvent *e )
|
||||
}
|
||||
|
||||
mCurrentLabel = LabelDetails( labelPos );
|
||||
if ( !mCurrentLabel.valid || !mCurrentLabel.layer || !mCurrentLabel.layer->isEditable() )
|
||||
if ( !mCurrentLabel.valid || !mCurrentLabel.layer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
createRubberBands();
|
||||
|
||||
if ( !mCurrentLabel.layer->isEditable() )
|
||||
{
|
||||
QgsPalIndexes indexes;
|
||||
bool newAuxiliaryLayer = createAuxiliaryFields( indexes );
|
||||
|
||||
// in case of a new auxiliary layer, a dialog window is displayed and the
|
||||
// canvas release event is lost.
|
||||
if ( newAuxiliaryLayer )
|
||||
{
|
||||
canvasReleaseEvent( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsMapToolChangeLabelProperties::canvasReleaseEvent( QgsMapMouseEvent *e )
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "qgsvectorlayerlabeling.h"
|
||||
#include "qgsdiagramrenderer.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsvectorlayerjoininfo.h"
|
||||
#include "qgsvectorlayerjoinbuffer.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
@ -688,14 +691,14 @@ QgsMapToolLabel::LabelDetails::LabelDetails( const QgsLabelPosition &p )
|
||||
: pos( p )
|
||||
{
|
||||
layer = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( pos.layerID ) );
|
||||
if ( layer && layer->labeling() )
|
||||
if ( layer && layer->labeling() && !p.isDiagram )
|
||||
{
|
||||
settings = layer->labeling()->settings( pos.providerID );
|
||||
|
||||
if ( p.isDiagram )
|
||||
valid = layer->diagramsEnabled();
|
||||
else
|
||||
valid = true;
|
||||
valid = true;
|
||||
}
|
||||
else if ( layer && layer->diagramsEnabled() && p.isDiagram )
|
||||
{
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if ( !valid )
|
||||
@ -704,3 +707,95 @@ QgsMapToolLabel::LabelDetails::LabelDetails( const QgsLabelPosition &p )
|
||||
settings = QgsPalLayerSettings();
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsMapToolLabel::createAuxiliaryFields( QgsPalIndexes &indexes )
|
||||
{
|
||||
return createAuxiliaryFields( mCurrentLabel, indexes );
|
||||
}
|
||||
|
||||
bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsPalIndexes &indexes ) const
|
||||
{
|
||||
bool newAuxiliaryLayer = false;
|
||||
QgsVectorLayer *vlayer = details.layer;
|
||||
QString providerId = details.pos.providerID;
|
||||
|
||||
if ( !vlayer || !vlayer->labeling() )
|
||||
return newAuxiliaryLayer;
|
||||
|
||||
if ( !vlayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( vlayer );
|
||||
dlg.exec();
|
||||
newAuxiliaryLayer = true;
|
||||
}
|
||||
|
||||
if ( !vlayer->auxiliaryLayer() )
|
||||
return false;
|
||||
|
||||
for ( const QgsPalLayerSettings::Property &p : qgsAsConst( mPalProperties ) )
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
// always use the default activated property
|
||||
QgsProperty prop = details.settings.dataDefinedProperties().property( p );
|
||||
if ( prop.propertyType() == QgsProperty::FieldBasedProperty && prop.isActive() )
|
||||
{
|
||||
index = vlayer->fields().lookupField( prop.field() );
|
||||
}
|
||||
else
|
||||
{
|
||||
index = QgsAuxiliaryLayer::createProperty( p, vlayer );
|
||||
}
|
||||
|
||||
indexes[p] = index;
|
||||
}
|
||||
|
||||
details.settings = vlayer->labeling()->settings( providerId );
|
||||
|
||||
return newAuxiliaryLayer;
|
||||
}
|
||||
|
||||
bool QgsMapToolLabel::createAuxiliaryFields( QgsDiagramIndexes &indexes )
|
||||
{
|
||||
return createAuxiliaryFields( mCurrentLabel, indexes );
|
||||
}
|
||||
|
||||
|
||||
bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsDiagramIndexes &indexes )
|
||||
{
|
||||
bool newAuxiliaryLayer = false;
|
||||
QgsVectorLayer *vlayer = details.layer;
|
||||
|
||||
if ( !vlayer )
|
||||
return newAuxiliaryLayer;
|
||||
|
||||
if ( !vlayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( vlayer );
|
||||
dlg.exec();
|
||||
newAuxiliaryLayer = true;
|
||||
}
|
||||
|
||||
if ( !vlayer->auxiliaryLayer() )
|
||||
return false;
|
||||
|
||||
for ( const QgsDiagramLayerSettings::Property &p : qgsAsConst( mDiagramProperties ) )
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
// always use the default activated property
|
||||
QgsProperty prop = vlayer->diagramLayerSettings()->dataDefinedProperties().property( p );
|
||||
if ( prop.propertyType() == QgsProperty::FieldBasedProperty && prop.isActive() )
|
||||
{
|
||||
index = vlayer->fields().lookupField( prop.field() );
|
||||
}
|
||||
else
|
||||
{
|
||||
index = QgsAuxiliaryLayer::createProperty( p, vlayer );
|
||||
}
|
||||
|
||||
indexes[p] = index;
|
||||
}
|
||||
|
||||
return newAuxiliaryLayer;
|
||||
}
|
||||
|
@ -20,10 +20,15 @@
|
||||
|
||||
#include "qgsmaptool.h"
|
||||
#include "qgspallabeling.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
#include "qgis_app.h"
|
||||
|
||||
class QgsRubberBand;
|
||||
|
||||
typedef QMap<QgsPalLayerSettings::Property, int> QgsPalIndexes;
|
||||
typedef QMap<QgsDiagramLayerSettings::Property, int> QgsDiagramIndexes;
|
||||
|
||||
//! Base class for map tools that modify label properties
|
||||
class APP_EXPORT QgsMapToolLabel: public QgsMapTool
|
||||
{
|
||||
@ -175,6 +180,14 @@ class APP_EXPORT QgsMapToolLabel: public QgsMapTool
|
||||
\since QGIS 2.16
|
||||
*/
|
||||
bool isPinned();
|
||||
|
||||
bool createAuxiliaryFields( QgsPalIndexes &palIndexes );
|
||||
bool createAuxiliaryFields( LabelDetails &details, QgsPalIndexes &palIndexes ) const;
|
||||
bool createAuxiliaryFields( QgsDiagramIndexes &diagIndexes );
|
||||
bool createAuxiliaryFields( LabelDetails &details, QgsDiagramIndexes &diagIndexes );
|
||||
|
||||
QList<QgsPalLayerSettings::Property> mPalProperties;
|
||||
QList<QgsDiagramLayerSettings::Property> mDiagramProperties;
|
||||
};
|
||||
|
||||
#endif // QGSMAPTOOLLABEL_H
|
||||
|
@ -27,6 +27,12 @@ QgsMapToolMoveLabel::QgsMapToolMoveLabel( QgsMapCanvas *canvas )
|
||||
, mClickOffsetY( 0 )
|
||||
{
|
||||
mToolName = tr( "Move label" );
|
||||
|
||||
mPalProperties << QgsPalLayerSettings::PositionX;
|
||||
mPalProperties << QgsPalLayerSettings::PositionY;
|
||||
|
||||
mDiagramProperties << QgsDiagramLayerSettings::PositionX;
|
||||
mDiagramProperties << QgsDiagramLayerSettings::PositionY;
|
||||
}
|
||||
|
||||
void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent *e )
|
||||
@ -43,14 +49,35 @@ void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent *e )
|
||||
mCurrentLabel = LabelDetails( labelPos );
|
||||
|
||||
QgsVectorLayer *vlayer = mCurrentLabel.layer;
|
||||
if ( !vlayer || !vlayer->isEditable() )
|
||||
if ( !vlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int xCol, yCol;
|
||||
if ( labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) ||
|
||||
diagramMoveable( vlayer, xCol, yCol ) )
|
||||
|
||||
if ( !mCurrentLabel.pos.isDiagram && !labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) )
|
||||
{
|
||||
QgsPalIndexes indexes;
|
||||
|
||||
if ( createAuxiliaryFields( indexes ) )
|
||||
return;
|
||||
|
||||
xCol = indexes[ QgsPalLayerSettings::PositionX ];
|
||||
yCol = indexes[ QgsPalLayerSettings::PositionY ];
|
||||
}
|
||||
else if ( mCurrentLabel.pos.isDiagram && !diagramMoveable( vlayer, xCol, yCol ) )
|
||||
{
|
||||
QgsDiagramIndexes indexes;
|
||||
|
||||
if ( createAuxiliaryFields( indexes ) )
|
||||
return;
|
||||
|
||||
xCol = indexes[ QgsDiagramLayerSettings::PositionX ];
|
||||
yCol = indexes[ QgsDiagramLayerSettings::PositionY ];
|
||||
}
|
||||
|
||||
if ( xCol >= 0 && yCol >= 0 )
|
||||
{
|
||||
mStartPointMapCoords = toMapCoordinates( e->pos() );
|
||||
QgsPointXY referencePoint;
|
||||
@ -91,7 +118,7 @@ void QgsMapToolMoveLabel::canvasReleaseEvent( QgsMapMouseEvent *e )
|
||||
deleteRubberBands();
|
||||
|
||||
QgsVectorLayer *vlayer = mCurrentLabel.layer;
|
||||
if ( !vlayer || !vlayer->isEditable() )
|
||||
if ( !vlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -260,13 +260,6 @@ void QgsMapToolPinLabels::pinUnpinLabels( const QgsRectangle &ext, QMouseEvent *
|
||||
continue;
|
||||
}
|
||||
|
||||
QgsVectorLayer *vlayer = mCurrentLabel.layer;
|
||||
if ( !vlayer->isEditable() )
|
||||
{
|
||||
QgsDebugMsg( QString( "Vector layer not editable, skipping label" ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
// unpin label
|
||||
if ( isPinned() && ( doUnpin || toggleUnpinOrPin ) )
|
||||
{
|
||||
@ -297,7 +290,7 @@ void QgsMapToolPinLabels::pinUnpinLabels( const QgsRectangle &ext, QMouseEvent *
|
||||
|
||||
if ( labelChanged )
|
||||
{
|
||||
mCanvas->refresh();
|
||||
mCurrentLabel.layer->triggerRepaint();
|
||||
|
||||
if ( !mShowPinned )
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ QgsMapToolRotateLabel::QgsMapToolRotateLabel( QgsMapCanvas *canvas )
|
||||
, mCurrentMouseAzimuth( 0.0 )
|
||||
, mCtrlPressed( false )
|
||||
{
|
||||
mPalProperties << QgsPalLayerSettings::LabelRotation;
|
||||
}
|
||||
|
||||
QgsMapToolRotateLabel::~QgsMapToolRotateLabel()
|
||||
@ -76,6 +77,14 @@ void QgsMapToolRotateLabel::canvasPressEvent( QgsMapMouseEvent *e )
|
||||
|
||||
bool hasRotationValue;
|
||||
int rotationCol;
|
||||
|
||||
if ( !labelIsRotatable( mCurrentLabel.layer, mCurrentLabel.settings, rotationCol ) )
|
||||
{
|
||||
QgsPalIndexes indexes;
|
||||
if ( createAuxiliaryFields( indexes ) )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( currentLabelDataDefinedRotation( mCurrentRotation, hasRotationValue, rotationCol, true ) )
|
||||
{
|
||||
if ( !hasRotationValue )
|
||||
|
@ -35,6 +35,9 @@ QgsMapToolShowHideLabels::QgsMapToolShowHideLabels( QgsMapCanvas *canvas )
|
||||
{
|
||||
mToolName = tr( "Show/hide labels" );
|
||||
mRubberBand = nullptr;
|
||||
|
||||
mPalProperties << QgsPalLayerSettings::Show;
|
||||
mDiagramProperties << QgsDiagramLayerSettings::Show;
|
||||
}
|
||||
|
||||
QgsMapToolShowHideLabels::~QgsMapToolShowHideLabels()
|
||||
@ -45,6 +48,24 @@ QgsMapToolShowHideLabels::~QgsMapToolShowHideLabels()
|
||||
void QgsMapToolShowHideLabels::canvasPressEvent( QgsMapMouseEvent *e )
|
||||
{
|
||||
Q_UNUSED( e );
|
||||
|
||||
QgsMapLayer *layer = mCanvas->currentLayer();
|
||||
QgsVectorLayer *vlayer = dynamic_cast<QgsVectorLayer *>( layer );
|
||||
if ( !vlayer )
|
||||
return;
|
||||
|
||||
int showCol;
|
||||
if ( !labelCanShowHide( vlayer, showCol )
|
||||
|| !diagramCanShowHide( vlayer, showCol ) )
|
||||
{
|
||||
if ( !vlayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( vlayer );
|
||||
dlg.exec();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mSelectRect.setRect( 0, 0, 0, 0 );
|
||||
mSelectRect.setTopLeft( e->pos() );
|
||||
mSelectRect.setBottomRight( e->pos() );
|
||||
@ -107,72 +128,46 @@ void QgsMapToolShowHideLabels::canvasReleaseEvent( QgsMapMouseEvent *e )
|
||||
void QgsMapToolShowHideLabels::showHideLabels( QMouseEvent *e )
|
||||
{
|
||||
QgsMapLayer *layer = mCanvas->currentLayer();
|
||||
|
||||
QgsVectorLayer *vlayer = dynamic_cast<QgsVectorLayer *>( layer );
|
||||
if ( !vlayer )
|
||||
{
|
||||
QgsDebugMsg( "Failed to cast label layer to vector layer" );
|
||||
return;
|
||||
}
|
||||
if ( !vlayer->isEditable() )
|
||||
{
|
||||
QgsDebugMsg( "Vector layer not editable, skipping label" );
|
||||
return;
|
||||
}
|
||||
|
||||
bool doHide = e->modifiers() & Qt::ShiftModifier;
|
||||
bool labelChanged = false;
|
||||
QString editTxt = doHide ? tr( "Hid labels" ) : tr( "Showed labels" );
|
||||
vlayer->beginEditCommand( editTxt );
|
||||
|
||||
if ( !doHide )
|
||||
bool labelChanged = false;
|
||||
if ( doHide )
|
||||
{
|
||||
QgsDebugMsg( "Showing labels operation" );
|
||||
|
||||
QgsFeatureIds selectedFeatIds;
|
||||
if ( !selectedFeatures( vlayer, selectedFeatIds ) )
|
||||
QList<QgsLabelPosition> positions;
|
||||
if ( selectedLabelFeatures( vlayer, positions ) )
|
||||
{
|
||||
vlayer->destroyEditCommand();
|
||||
return;
|
||||
}
|
||||
|
||||
QgsDebugMsg( "Number of selected labels or features: " + QString::number( selectedFeatIds.size() ) );
|
||||
|
||||
if ( selectedFeatIds.isEmpty() )
|
||||
{
|
||||
vlayer->destroyEditCommand();
|
||||
return;
|
||||
}
|
||||
|
||||
Q_FOREACH ( QgsFeatureId fid, selectedFeatIds )
|
||||
{
|
||||
mCurrentLabel.pos.featureId = fid;
|
||||
|
||||
mCurrentLabel.pos.isDiagram = false;
|
||||
bool labChanged = showHide( vlayer, true );
|
||||
|
||||
mCurrentLabel.pos.isDiagram = true;
|
||||
bool diagChanged = showHide( vlayer, true );
|
||||
|
||||
if ( labChanged || diagChanged )
|
||||
for ( const QgsLabelPosition &pos : qgsAsConst( positions ) )
|
||||
{
|
||||
// TODO: highlight features (maybe with QTimer?)
|
||||
labelChanged = true;
|
||||
if ( showHide( pos, false ) )
|
||||
labelChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "Hiding labels operation" );
|
||||
|
||||
QList<QgsLabelPosition> positions;
|
||||
if ( selectedLabelFeatures( vlayer, positions ) )
|
||||
QgsFeatureIds fids;
|
||||
if ( selectedFeatures( vlayer, fids ) )
|
||||
{
|
||||
Q_FOREACH ( const QgsLabelPosition &pos, positions )
|
||||
for ( const QgsFeatureId &fid : qgsAsConst( fids ) )
|
||||
{
|
||||
mCurrentLabel.pos = pos;
|
||||
QgsLabelPosition pos;
|
||||
pos.featureId = fid;
|
||||
pos.layerID = vlayer->id();
|
||||
|
||||
if ( showHide( vlayer, false ) )
|
||||
// we want to show labels...
|
||||
pos.isDiagram = false;
|
||||
if ( showHide( pos, true ) )
|
||||
labelChanged = true;
|
||||
|
||||
// ... and diagrams
|
||||
pos.isDiagram = true;
|
||||
if ( showHide( pos, true ) )
|
||||
labelChanged = true;
|
||||
}
|
||||
}
|
||||
@ -274,42 +269,45 @@ bool QgsMapToolShowHideLabels::selectedLabelFeatures( QgsVectorLayer *vlayer,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsMapToolShowHideLabels::showHide( QgsVectorLayer *vl, const bool show )
|
||||
bool QgsMapToolShowHideLabels::showHide( const QgsLabelPosition &pos, bool show )
|
||||
{
|
||||
// verify attribute table has proper field setup
|
||||
bool showSuccess;
|
||||
int showCol;
|
||||
int showVal;
|
||||
LabelDetails details = LabelDetails( pos );
|
||||
|
||||
if ( !dataDefinedShowHide( vl, mCurrentLabel.pos.featureId, showVal,
|
||||
showSuccess, showCol ) )
|
||||
{
|
||||
if ( !details.valid )
|
||||
return false;
|
||||
|
||||
QgsVectorLayer *vlayer = details.layer;
|
||||
if ( !vlayer )
|
||||
return false;
|
||||
|
||||
int showCol = -1;
|
||||
if ( pos.isDiagram )
|
||||
{
|
||||
if ( !diagramCanShowHide( vlayer, showCol ) )
|
||||
{
|
||||
QgsDiagramIndexes indexes;
|
||||
createAuxiliaryFields( details, indexes );
|
||||
|
||||
showCol = indexes[ QgsDiagramLayerSettings::Show ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !labelCanShowHide( vlayer, showCol ) )
|
||||
{
|
||||
QgsPalIndexes indexes;
|
||||
createAuxiliaryFields( details, indexes );
|
||||
|
||||
showCol = indexes[ QgsPalLayerSettings::Show ];
|
||||
}
|
||||
}
|
||||
|
||||
// we need to pass int value to the provider
|
||||
// (committing bool value would fail on int field)
|
||||
int curVal = show ? 1 : 0;
|
||||
|
||||
// check if attribute value is already the same
|
||||
if ( showSuccess && showVal == curVal )
|
||||
if ( showCol >= 0 )
|
||||
{
|
||||
return false;
|
||||
int showVal = show ? 1 : 0;
|
||||
vlayer->changeAttributeValue( pos.featureId, showCol, showVal );
|
||||
return true;
|
||||
}
|
||||
|
||||
// allow NULL (maybe default) value to stand for show label (i.e. 1)
|
||||
// skip NULL attributes if trying to show label
|
||||
if ( !showSuccess && curVal == 1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// different attribute value, edit table
|
||||
if ( ! vl->changeAttributeValue( mCurrentLabel.pos.featureId, showCol, curVal ) )
|
||||
{
|
||||
QgsDebugMsg( "Failed write to attribute table" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -64,8 +64,7 @@ class APP_EXPORT QgsMapToolShowHideLabels : public QgsMapToolLabel
|
||||
bool selectedLabelFeatures( QgsVectorLayer *vlayer,
|
||||
QList<QgsLabelPosition> &listPos );
|
||||
|
||||
//! Show label or diagram with feature ID
|
||||
bool showHide( QgsVectorLayer *vl, const bool show );
|
||||
bool showHide( const QgsLabelPosition &pos, bool show );
|
||||
};
|
||||
|
||||
#endif // QGSMAPTOOLSHOWHIDELABELS_H
|
||||
|
@ -55,6 +55,11 @@
|
||||
#include "qgssettings.h"
|
||||
#include "qgsrendererpropertiesdialog.h"
|
||||
#include "qgsstyle.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
#include "qgsnewauxiliaryfielddialog.h"
|
||||
#include "qgslabelinggui.h"
|
||||
#include "qgssymbollayer.h"
|
||||
|
||||
#include "layertree/qgslayertreelayer.h"
|
||||
#include "qgslayertree.h"
|
||||
@ -144,6 +149,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
||||
layout->setMargin( 0 );
|
||||
labelingDialog = new QgsLabelingWidget( mLayer, QgisApp::instance()->mapCanvas(), labelingFrame );
|
||||
labelingDialog->layout()->setContentsMargins( -1, 0, -1, 0 );
|
||||
connect( labelingDialog, &QgsLabelingWidget::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
|
||||
layout->addWidget( labelingDialog );
|
||||
labelingFrame->setLayout( layout );
|
||||
}
|
||||
@ -253,6 +259,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
||||
diagLayout->setMargin( 0 );
|
||||
diagramPropertiesDialog = new QgsDiagramProperties( mLayer, mDiagramFrame, QgisApp::instance()->mapCanvas() );
|
||||
diagramPropertiesDialog->layout()->setContentsMargins( -1, 0, -1, 0 );
|
||||
connect( diagramPropertiesDialog, &QgsDiagramProperties::auxiliaryFieldCreated, this, [ = ] { updateAuxiliaryStoragePage(); } );
|
||||
diagLayout->addWidget( diagramPropertiesDialog );
|
||||
mDiagramFrame->setLayout( diagLayout );
|
||||
|
||||
@ -349,6 +356,31 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
|
||||
|
||||
connect( mRefreshLayerCheckBox, &QCheckBox::toggled, mRefreshLayerIntervalSpinBox, &QDoubleSpinBox::setEnabled );
|
||||
|
||||
// auxiliary layer
|
||||
QMenu *menu = new QMenu( this );
|
||||
|
||||
mAuxiliaryLayerActionNew = new QAction( tr( "Create" ), this );
|
||||
menu->addAction( mAuxiliaryLayerActionNew );
|
||||
connect( mAuxiliaryLayerActionNew, &QAction::triggered, this, &QgsVectorLayerProperties::onAuxiliaryLayerNew );
|
||||
|
||||
mAuxiliaryLayerActionClear = new QAction( tr( "Clear" ), this );
|
||||
menu->addAction( mAuxiliaryLayerActionClear );
|
||||
connect( mAuxiliaryLayerActionClear, &QAction::triggered, this, &QgsVectorLayerProperties::onAuxiliaryLayerClear );
|
||||
|
||||
mAuxiliaryLayerActionDelete = new QAction( tr( "Delete" ), this );
|
||||
menu->addAction( mAuxiliaryLayerActionDelete );
|
||||
connect( mAuxiliaryLayerActionDelete, &QAction::triggered, this, &QgsVectorLayerProperties::onAuxiliaryLayerDelete );
|
||||
|
||||
mAuxiliaryLayerActionExport = new QAction( tr( "Export" ), this );
|
||||
menu->addAction( mAuxiliaryLayerActionExport );
|
||||
connect( mAuxiliaryLayerActionExport, &QAction::triggered, this, &QgsVectorLayerProperties::onAuxiliaryLayerExport );
|
||||
|
||||
mAuxiliaryStorageActions->setMenu( menu );
|
||||
|
||||
connect( mAuxiliaryStorageFieldsDeleteBtn, &QPushButton::clicked, this, &QgsVectorLayerProperties::onAuxiliaryLayerDeleteField );
|
||||
connect( mAuxiliaryStorageFieldsAddBtn, &QPushButton::clicked, this, &QgsVectorLayerProperties::onAuxiliaryLayerAddField );
|
||||
|
||||
updateAuxiliaryStoragePage();
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::toggleEditing()
|
||||
@ -1245,6 +1277,11 @@ void QgsVectorLayerProperties::addJoinToTreeWidget( const QgsVectorLayerJoinInfo
|
||||
}
|
||||
|
||||
joinItem->setText( 0, QStringLiteral( "Join layer" ) );
|
||||
if ( mLayer->auxiliaryLayer() && mLayer->auxiliaryLayer()->id() == join.joinLayerId() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
joinItem->setText( 1, joinLayer->name() );
|
||||
|
||||
QFont f = joinItem->font( 0 );
|
||||
@ -1369,6 +1406,7 @@ void QgsVectorLayerProperties::updateSymbologyPage()
|
||||
mRendererDialog->setMapCanvas( QgisApp::instance()->mapCanvas() );
|
||||
connect( mRendererDialog, &QgsRendererPropertiesDialog::showPanel, this, &QgsVectorLayerProperties::openPanel );
|
||||
connect( mRendererDialog, &QgsRendererPropertiesDialog::layerVariablesChanged, this, &QgsVectorLayerProperties::updateVariableEditor );
|
||||
connect( mRendererDialog, &QgsRendererPropertiesDialog::widgetChanged, this, [ = ] { updateAuxiliaryStoragePage(); } );
|
||||
|
||||
// display the menu to choose the output format (fix #5136)
|
||||
mActionSaveStyleAs->setText( tr( "Save Style" ) );
|
||||
@ -1453,3 +1491,225 @@ void QgsVectorLayerProperties::showHelp()
|
||||
{
|
||||
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html" ) );
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::updateAuxiliaryStoragePage( bool reset )
|
||||
{
|
||||
const QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
|
||||
if ( alayer )
|
||||
{
|
||||
// set widgets to enable state
|
||||
mAuxiliaryStorageInformationGrpBox->setEnabled( true );
|
||||
mAuxiliaryStorageFieldsGrpBox->setEnabled( true );
|
||||
|
||||
// update key
|
||||
mAuxiliaryStorageKeyLineEdit->setText( alayer->joinInfo().targetFieldName() );
|
||||
|
||||
// update feature count
|
||||
int features = alayer->featureCount();
|
||||
mAuxiliaryStorageFeaturesLineEdit->setText( QString::number( features ) );
|
||||
|
||||
// update actions
|
||||
mAuxiliaryLayerActionClear->setEnabled( true );
|
||||
mAuxiliaryLayerActionDelete->setEnabled( true );
|
||||
mAuxiliaryLayerActionExport->setEnabled( true );
|
||||
mAuxiliaryLayerActionNew->setEnabled( false );
|
||||
|
||||
const QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
if ( alayer )
|
||||
{
|
||||
const int fields = alayer->auxiliaryFields().count();
|
||||
mAuxiliaryStorageFieldsLineEdit->setText( QString::number( fields ) );
|
||||
|
||||
// add fields
|
||||
mAuxiliaryStorageFieldsTree->clear();
|
||||
for ( const QgsField &field : alayer->auxiliaryFields() )
|
||||
{
|
||||
const QgsPropertyDefinition prop = QgsAuxiliaryLayer::propertyDefinitionFromField( field );
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
|
||||
item->setText( 0, prop.origin() );
|
||||
item->setText( 1, prop.name() );
|
||||
item->setText( 2, prop.comment() );
|
||||
item->setText( 3, field.typeName() );
|
||||
item->setText( 4, field.name() );
|
||||
|
||||
mAuxiliaryStorageFieldsTree->addTopLevelItem( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mAuxiliaryStorageInformationGrpBox->setEnabled( false );
|
||||
mAuxiliaryStorageFieldsGrpBox->setEnabled( false );
|
||||
|
||||
mAuxiliaryLayerActionClear->setEnabled( false );
|
||||
mAuxiliaryLayerActionDelete->setEnabled( false );
|
||||
mAuxiliaryLayerActionExport->setEnabled( false );
|
||||
mAuxiliaryLayerActionNew->setEnabled( true );
|
||||
|
||||
mAuxiliaryStorageFieldsTree->clear();
|
||||
mAuxiliaryStorageKeyLineEdit->setText( QString() );
|
||||
mAuxiliaryStorageFieldsLineEdit->setText( QString() );
|
||||
mAuxiliaryStorageFeaturesLineEdit->setText( QString() );
|
||||
}
|
||||
|
||||
if ( reset && labelingDialog )
|
||||
{
|
||||
labelingDialog->setLayer( mLayer );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::onAuxiliaryLayerNew()
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
|
||||
if ( alayer )
|
||||
return;
|
||||
|
||||
QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
|
||||
if ( dlg.exec() == QDialog::Accepted )
|
||||
{
|
||||
updateAuxiliaryStoragePage( true );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::onAuxiliaryLayerClear()
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
|
||||
if ( !alayer )
|
||||
return;
|
||||
|
||||
const QString msg = tr( "Are you sure you want to clear auxiliary data for %1" ).arg( mLayer->name() );
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question( this, "Clear auxiliary data", msg, QMessageBox::Yes | QMessageBox::No );
|
||||
|
||||
if ( reply == QMessageBox::Yes )
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
alayer->clear();
|
||||
QApplication::restoreOverrideCursor();
|
||||
updateAuxiliaryStoragePage( true );
|
||||
mLayer->triggerRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::onAuxiliaryLayerDelete()
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
if ( !alayer )
|
||||
return;
|
||||
|
||||
const QString msg = tr( "Are you sure you want to delete auxiliary storage for %1" ).arg( mLayer->name() );
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question( this, "Delete auxiliary storage", msg, QMessageBox::Yes | QMessageBox::No );
|
||||
|
||||
if ( reply == QMessageBox::Yes )
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
QgsDataSourceUri uri( alayer->source() );
|
||||
|
||||
// delete each attribute to correctly update layer settings and data
|
||||
// defined buttons
|
||||
while ( alayer->auxiliaryFields().size() > 0 )
|
||||
{
|
||||
QgsField aField = alayer->auxiliaryFields()[0];
|
||||
deleteAuxiliaryField( alayer->fields().indexOf( aField.name() ) );
|
||||
}
|
||||
|
||||
mLayer->setAuxiliaryLayer(); // remove auxiliary layer
|
||||
QgsAuxiliaryStorage::deleteTable( uri );
|
||||
QApplication::restoreOverrideCursor();
|
||||
updateAuxiliaryStoragePage( true );
|
||||
mLayer->triggerRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::onAuxiliaryLayerExport()
|
||||
{
|
||||
const QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
if ( !alayer )
|
||||
return;
|
||||
|
||||
std::unique_ptr<QgsVectorLayer> clone;
|
||||
clone.reset( alayer->toSpatialLayer() );
|
||||
|
||||
QgisApp::instance()->saveAsFile( clone.get() );
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::onAuxiliaryLayerDeleteField()
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
if ( !alayer )
|
||||
return;
|
||||
|
||||
QList<QTreeWidgetItem *> items = mAuxiliaryStorageFieldsTree->selectedItems();
|
||||
if ( items.count() < 1 )
|
||||
return;
|
||||
|
||||
// get auxiliary field name and index from item
|
||||
const QTreeWidgetItem *item = items[0];
|
||||
QgsPropertyDefinition def;
|
||||
def.setOrigin( item->text( 0 ) );
|
||||
def.setName( item->text( 1 ) );
|
||||
def.setComment( item->text( 2 ) );
|
||||
|
||||
const QString fieldName = QgsAuxiliaryLayer::nameFromProperty( def );
|
||||
|
||||
const int index = mLayer->auxiliaryLayer()->fields().indexOf( fieldName );
|
||||
if ( index < 0 )
|
||||
return;
|
||||
|
||||
// should be only 1 field
|
||||
const QString msg = tr( "Are you sure you want to delete auxiliary field %1 for %2" ).arg( item->text( 1 ), item->text( 0 ) );
|
||||
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question( this, "Delete auxiliary field", msg, QMessageBox::Yes | QMessageBox::No );
|
||||
|
||||
if ( reply == QMessageBox::Yes )
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
deleteAuxiliaryField( index );
|
||||
mLayer->triggerRepaint();
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::onAuxiliaryLayerAddField()
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = mLayer->auxiliaryLayer();
|
||||
if ( !alayer )
|
||||
return;
|
||||
|
||||
QgsNewAuxiliaryFieldDialog dlg( QgsPropertyDefinition(), mLayer, false );
|
||||
if ( dlg.exec() == QDialog::Accepted )
|
||||
{
|
||||
updateAuxiliaryStoragePage();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsVectorLayerProperties::deleteAuxiliaryField( int index )
|
||||
{
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
return;
|
||||
|
||||
int key = mLayer->auxiliaryLayer()->propertyFromIndex( index );
|
||||
QgsPropertyDefinition def = mLayer->auxiliaryLayer()->propertyDefinitionFromIndex( index );
|
||||
|
||||
if ( mLayer->auxiliaryLayer()->deleteAttribute( index ) )
|
||||
{
|
||||
mLayer->updateFields();
|
||||
|
||||
// immediately deactivate data defined button
|
||||
if ( key >= 0 && def.origin().compare( "labeling", Qt::CaseInsensitive ) == 0
|
||||
&& labelingDialog
|
||||
&& labelingDialog->labelingGui() )
|
||||
{
|
||||
labelingDialog->labelingGui()->deactivateField( ( QgsPalLayerSettings::Property ) key );
|
||||
}
|
||||
|
||||
updateAuxiliaryStoragePage( true );
|
||||
mFieldsPropertiesDialog->init();
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +156,18 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
||||
*/
|
||||
void updateFieldsPropertiesDialog();
|
||||
|
||||
void onAuxiliaryLayerNew();
|
||||
|
||||
void onAuxiliaryLayerClear();
|
||||
|
||||
void onAuxiliaryLayerDelete();
|
||||
|
||||
void onAuxiliaryLayerDeleteField();
|
||||
|
||||
void onAuxiliaryLayerAddField();
|
||||
|
||||
void onAuxiliaryLayerExport();
|
||||
|
||||
private:
|
||||
|
||||
void saveStyleAs( StyleType styleType );
|
||||
@ -206,6 +218,9 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
||||
//! Adds a new join to mJoinTreeWidget
|
||||
void addJoinToTreeWidget( const QgsVectorLayerJoinInfo &join, const int insertIndex = -1 );
|
||||
|
||||
void updateAuxiliaryStoragePage( bool reset = false );
|
||||
void deleteAuxiliaryField( int index );
|
||||
|
||||
QgsExpressionContext mContext;
|
||||
|
||||
QgsExpressionContext createExpressionContext() const override;
|
||||
@ -217,6 +232,13 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
|
||||
|
||||
QgsMetadataWidget *mMetadataWidget = nullptr;
|
||||
|
||||
QAction *mAuxiliaryLayerActionNew = nullptr;
|
||||
QAction *mAuxiliaryLayerActionClear = nullptr;
|
||||
QAction *mAuxiliaryLayerActionDelete = nullptr;
|
||||
QAction *mAuxiliaryLayerActionExport = nullptr;
|
||||
QAction *mAuxiliaryLayerActionDeleteField = nullptr;
|
||||
QAction *mAuxiliaryLayerActionAddField = nullptr;
|
||||
|
||||
private slots:
|
||||
void openPanel( QgsPanelWidget *panel );
|
||||
};
|
||||
|
@ -134,6 +134,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgsattributes.cpp
|
||||
qgsattributetableconfig.cpp
|
||||
qgsattributeeditorelement.cpp
|
||||
qgsauxiliarystorage.cpp
|
||||
qgsbearingutils.cpp
|
||||
qgsbrowsermodel.cpp
|
||||
qgscachedfeatureiterator.cpp
|
||||
@ -572,6 +573,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
qgsactionmanager.h
|
||||
qgsactionscoperegistry.h
|
||||
qgsanimatedicon.h
|
||||
qgsauxiliarystorage.h
|
||||
qgsbrowsermodel.h
|
||||
qgscoordinatereferencesystem.h
|
||||
qgscredentials.h
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qgsarchive.h"
|
||||
#include "qgsziputils.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
#include <iostream>
|
||||
|
||||
QgsArchive::QgsArchive()
|
||||
@ -136,3 +137,17 @@ bool QgsProjectArchive::clearProjectFile()
|
||||
{
|
||||
return removeFile( projectFile() );
|
||||
}
|
||||
|
||||
QString QgsProjectArchive::auxiliaryStorageFile() const
|
||||
{
|
||||
const QString extension = QgsAuxiliaryStorage::extension();
|
||||
|
||||
for ( const QString &file : files() )
|
||||
{
|
||||
const QFileInfo fileInfo( file );
|
||||
if ( fileInfo.suffix().compare( extension, Qt::CaseInsensitive ) == 0 )
|
||||
return file;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
@ -134,6 +134,12 @@ class CORE_EXPORT QgsProjectArchive : public QgsArchive
|
||||
* \returns true if the file is well removed, false otherwise
|
||||
*/
|
||||
bool clearProjectFile();
|
||||
|
||||
/**
|
||||
* Returns the current .qgd auxiliary storage file or an empty string if
|
||||
* there's none
|
||||
*/
|
||||
QString auxiliaryStorageFile() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
829
src/core/qgsauxiliarystorage.cpp
Normal file
829
src/core/qgsauxiliarystorage.cpp
Normal file
@ -0,0 +1,829 @@
|
||||
/***************************************************************************
|
||||
qgsauxiliarystorage.cpp - description
|
||||
-------------------
|
||||
begin : Aug 28, 2017
|
||||
copyright : (C) 2017 by Paul Blottiere
|
||||
email : paul.blottiere@oslandia.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsauxiliarystorage.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsslconnect.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectorlayerlabeling.h"
|
||||
#include "qgsdiagramrenderer.h"
|
||||
#include "qgsmemoryproviderutils.h"
|
||||
#include "qgssymbollayer.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
const QString AS_JOINFIELD = "ASPK";
|
||||
const QString AS_EXTENSION = "qgd";
|
||||
const QString AS_JOINPREFIX = "auxiliary_storage_";
|
||||
|
||||
const QVector<QgsPalLayerSettings::Property> palHiddenProperties
|
||||
{
|
||||
QgsPalLayerSettings::PositionX,
|
||||
QgsPalLayerSettings::PositionY,
|
||||
QgsPalLayerSettings::Show,
|
||||
QgsPalLayerSettings::LabelRotation,
|
||||
QgsPalLayerSettings::Family,
|
||||
QgsPalLayerSettings::FontStyle,
|
||||
QgsPalLayerSettings::Size,
|
||||
QgsPalLayerSettings::Bold,
|
||||
QgsPalLayerSettings::Italic,
|
||||
QgsPalLayerSettings::Underline,
|
||||
QgsPalLayerSettings::Color,
|
||||
QgsPalLayerSettings::Strikeout,
|
||||
QgsPalLayerSettings::BufferSize,
|
||||
QgsPalLayerSettings::BufferColor,
|
||||
QgsPalLayerSettings::LabelDistance,
|
||||
QgsPalLayerSettings::Hali,
|
||||
QgsPalLayerSettings::Vali,
|
||||
QgsPalLayerSettings::ScaleVisibility,
|
||||
QgsPalLayerSettings::MinScale,
|
||||
QgsPalLayerSettings::MaxScale,
|
||||
QgsPalLayerSettings::AlwaysShow
|
||||
};
|
||||
|
||||
//
|
||||
// QgsAuxiliaryLayer
|
||||
//
|
||||
|
||||
QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer )
|
||||
: QgsVectorLayer( QString( "%1|layername=%2" ).arg( filename, table ), QString( "%1_auxiliarystorage" ).arg( table ), "ogr" )
|
||||
, mFileName( filename )
|
||||
, mTable( table )
|
||||
, mLayer( vlayer )
|
||||
{
|
||||
// init join info
|
||||
mJoinInfo.setPrefix( AS_JOINPREFIX );
|
||||
mJoinInfo.setJoinLayer( this );
|
||||
mJoinInfo.setJoinFieldName( AS_JOINFIELD );
|
||||
mJoinInfo.setTargetFieldName( pkField );
|
||||
mJoinInfo.setEditable( true );
|
||||
mJoinInfo.setUpsertOnEdit( true );
|
||||
mJoinInfo.setCascadedDelete( true );
|
||||
mJoinInfo.setJoinFieldNamesBlackList( QStringList() << QStringLiteral( "rowid" ) ); // introduced by ogr provider
|
||||
}
|
||||
|
||||
QgsAuxiliaryLayer *QgsAuxiliaryLayer::clone( QgsVectorLayer *target ) const
|
||||
{
|
||||
QgsAuxiliaryStorage::duplicateTable( source(), target->id() );
|
||||
return new QgsAuxiliaryLayer( mJoinInfo.targetFieldName(), mFileName, target->id(), target );
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::clear()
|
||||
{
|
||||
bool rc = deleteFeatures( allFeatureIds() );
|
||||
commitChanges();
|
||||
startEditing();
|
||||
return rc;
|
||||
}
|
||||
|
||||
QgsVectorLayer *QgsAuxiliaryLayer::toSpatialLayer() const
|
||||
{
|
||||
QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );
|
||||
|
||||
QString pkField = mJoinInfo.targetFieldName();
|
||||
QgsFeature joinFeature;
|
||||
QgsFeature targetFeature;
|
||||
QgsFeatureIterator it = getFeatures();
|
||||
|
||||
layer->startEditing();
|
||||
while ( it.nextFeature( joinFeature ) )
|
||||
{
|
||||
QString filter = QgsExpression::createFieldEqualityExpression( pkField, joinFeature.attribute( AS_JOINFIELD ) );
|
||||
|
||||
QgsFeatureRequest request;
|
||||
request.setFilterExpression( filter );
|
||||
|
||||
mLayer->getFeatures( request ).nextFeature( targetFeature );
|
||||
|
||||
if ( targetFeature.isValid() )
|
||||
{
|
||||
QgsFeature newFeature( joinFeature );
|
||||
newFeature.setGeometry( targetFeature.geometry() );
|
||||
layer->addFeature( newFeature );
|
||||
}
|
||||
}
|
||||
layer->commitChanges();
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
QgsVectorLayerJoinInfo QgsAuxiliaryLayer::joinInfo() const
|
||||
{
|
||||
return mJoinInfo;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::exists( const QgsPropertyDefinition &definition ) const
|
||||
{
|
||||
return ( indexOfPropertyDefinition( definition ) >= 0 );
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::addAuxiliaryField( const QgsPropertyDefinition &definition )
|
||||
{
|
||||
if ( ( definition.name().isEmpty() && definition.comment().isEmpty() ) || exists( definition ) )
|
||||
return false;
|
||||
|
||||
const QgsField af = createAuxiliaryField( definition );
|
||||
const bool rc = addAttribute( af );
|
||||
updateFields();
|
||||
mLayer->updateFields();
|
||||
|
||||
if ( rc )
|
||||
{
|
||||
int auxIndex = indexOfPropertyDefinition( definition );
|
||||
int index = mLayer->fields().indexOf( nameFromProperty( definition, true ) );
|
||||
|
||||
if ( index >= 0 && auxIndex >= 0 )
|
||||
{
|
||||
if ( isHiddenProperty( auxIndex ) )
|
||||
{
|
||||
// update editor widget
|
||||
QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Hidden" ), QVariantMap() );
|
||||
setEditorWidgetSetup( auxIndex, setup );
|
||||
|
||||
// column is hidden
|
||||
QgsAttributeTableConfig attrCfg = mLayer->attributeTableConfig();
|
||||
attrCfg.update( mLayer->fields() );
|
||||
QVector<QgsAttributeTableConfig::ColumnConfig> columns = attrCfg.columns();
|
||||
QVector<QgsAttributeTableConfig::ColumnConfig>::iterator it;
|
||||
|
||||
for ( it = columns.begin(); it != columns.end(); ++it )
|
||||
{
|
||||
if ( it->name.compare( mLayer->fields().field( index ).name() ) == 0 )
|
||||
it->hidden = true;
|
||||
}
|
||||
|
||||
attrCfg.setColumns( columns );
|
||||
mLayer->setAttributeTableConfig( attrCfg );
|
||||
}
|
||||
else if ( definition.standardTemplate() == QgsPropertyDefinition::ColorNoAlpha
|
||||
|| definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha )
|
||||
{
|
||||
QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Color" ), QVariantMap() );
|
||||
setEditorWidgetSetup( auxIndex, setup );
|
||||
}
|
||||
|
||||
mLayer->setEditorWidgetSetup( index, editorWidgetSetup( auxIndex ) );
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
QgsFields QgsAuxiliaryLayer::auxiliaryFields() const
|
||||
{
|
||||
QgsFields afields;
|
||||
|
||||
for ( int i = 2; i < fields().count(); i++ ) // ignore rowid and PK field
|
||||
afields.append( createAuxiliaryField( fields().field( i ) ) );
|
||||
|
||||
return afields;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::deleteAttribute( int attr )
|
||||
{
|
||||
QgsVectorLayer::deleteAttribute( attr );
|
||||
bool rc = commitChanges();
|
||||
startEditing();
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::save()
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
if ( isEditable() )
|
||||
{
|
||||
rc = commitChanges();
|
||||
}
|
||||
|
||||
startEditing();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int QgsAuxiliaryLayer::createProperty( QgsPalLayerSettings::Property property, QgsVectorLayer *layer )
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
if ( layer && layer->labeling() && layer->auxiliaryLayer() )
|
||||
{
|
||||
// property definition are identical whatever the provider id
|
||||
const QgsPropertyDefinition def = layer->labeling()->settings().propertyDefinitions()[property];
|
||||
const QString fieldName = nameFromProperty( def, true );
|
||||
|
||||
layer->auxiliaryLayer()->addAuxiliaryField( def );
|
||||
|
||||
if ( layer->auxiliaryLayer()->indexOfPropertyDefinition( def ) >= 0 )
|
||||
{
|
||||
const QgsProperty prop = QgsProperty::fromField( fieldName );
|
||||
|
||||
for ( const QString &providerId : layer->labeling()->subProviders() )
|
||||
{
|
||||
QgsPalLayerSettings *settings = new QgsPalLayerSettings( layer->labeling()->settings( providerId ) );
|
||||
|
||||
QgsPropertyCollection c = settings->dataDefinedProperties();
|
||||
c.setProperty( property, prop );
|
||||
settings->setDataDefinedProperties( c );
|
||||
|
||||
layer->labeling()->setSettings( settings, providerId );
|
||||
}
|
||||
|
||||
emit layer->styleChanged();
|
||||
}
|
||||
|
||||
index = layer->fields().lookupField( fieldName );
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int QgsAuxiliaryLayer::createProperty( QgsDiagramLayerSettings::Property property, QgsVectorLayer *layer )
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
if ( layer && layer->diagramLayerSettings() && layer->auxiliaryLayer() )
|
||||
{
|
||||
const QgsPropertyDefinition def = layer->diagramLayerSettings()->propertyDefinitions()[property];
|
||||
|
||||
if ( layer->auxiliaryLayer()->addAuxiliaryField( def ) )
|
||||
{
|
||||
const QString fieldName = nameFromProperty( def, true );
|
||||
const QgsProperty prop = QgsProperty::fromField( fieldName );
|
||||
|
||||
QgsDiagramLayerSettings settings( *layer->diagramLayerSettings() );
|
||||
|
||||
QgsPropertyCollection c = settings.dataDefinedProperties();
|
||||
c.setProperty( property, prop );
|
||||
settings.setDataDefinedProperties( c );
|
||||
|
||||
layer->setDiagramLayerSettings( settings );
|
||||
emit layer->styleChanged();
|
||||
|
||||
index = layer->fields().lookupField( fieldName );
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::isHiddenProperty( int index ) const
|
||||
{
|
||||
bool hidden = false;
|
||||
QgsPropertyDefinition def = propertyDefinitionFromIndex( index );
|
||||
|
||||
if ( def.origin().compare( "labeling" ) == 0 )
|
||||
{
|
||||
for ( const QgsPalLayerSettings::Property &p : palHiddenProperties )
|
||||
{
|
||||
const QString propName = QgsPalLayerSettings::propertyDefinitions()[ p ].name();
|
||||
if ( propName.compare( def.name() ) == 0 )
|
||||
{
|
||||
hidden = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hidden;
|
||||
}
|
||||
|
||||
int QgsAuxiliaryLayer::propertyFromIndex( int index ) const
|
||||
{
|
||||
int p = -1;
|
||||
QgsPropertyDefinition aDef = propertyDefinitionFromIndex( index );
|
||||
|
||||
if ( aDef.origin().compare( QStringLiteral( "labeling" ) ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition defs = QgsPalLayerSettings::propertyDefinitions();
|
||||
QgsPropertiesDefinition::const_iterator it = defs.constBegin();
|
||||
for ( ; it != defs.constEnd(); ++it )
|
||||
{
|
||||
if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
p = it.key();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( aDef.origin().compare( QStringLiteral( "symbol" ) ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition defs = QgsSymbolLayer::propertyDefinitions();
|
||||
QgsPropertiesDefinition::const_iterator it = defs.constBegin();
|
||||
for ( ; it != defs.constEnd(); ++it )
|
||||
{
|
||||
if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
p = it.key();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( aDef.origin().compare( QStringLiteral( "diagram" ) ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition defs = QgsDiagramLayerSettings::propertyDefinitions();
|
||||
QgsPropertiesDefinition::const_iterator it = defs.constBegin();
|
||||
for ( ; it != defs.constEnd(); ++it )
|
||||
{
|
||||
if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
p = it.key();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
QgsPropertyDefinition QgsAuxiliaryLayer::propertyDefinitionFromIndex( int index ) const
|
||||
{
|
||||
return propertyDefinitionFromField( fields().field( index ) );
|
||||
}
|
||||
|
||||
int QgsAuxiliaryLayer::indexOfPropertyDefinition( const QgsPropertyDefinition &def ) const
|
||||
{
|
||||
return fields().indexOf( nameFromProperty( def ) );
|
||||
}
|
||||
|
||||
QString QgsAuxiliaryLayer::nameFromProperty( const QgsPropertyDefinition &def, bool joined )
|
||||
{
|
||||
QString fieldName = def.origin();
|
||||
|
||||
if ( !def.name().isEmpty() )
|
||||
fieldName = QString( "%1_%2" ).arg( fieldName, def.name().toLower() );
|
||||
|
||||
if ( !def.comment().isEmpty() )
|
||||
fieldName = QString( "%1_%2" ).arg( fieldName ).arg( def.comment() );
|
||||
|
||||
if ( joined )
|
||||
fieldName = QString( "%1%2" ).arg( AS_JOINPREFIX, fieldName );
|
||||
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
QgsField QgsAuxiliaryLayer::createAuxiliaryField( const QgsPropertyDefinition &def )
|
||||
{
|
||||
QgsField afield;
|
||||
|
||||
if ( !def.name().isEmpty() || !def.comment().isEmpty() )
|
||||
{
|
||||
QVariant::Type type;
|
||||
QString typeName;
|
||||
int len( 0 ), precision( 0 );
|
||||
switch ( def.dataType() )
|
||||
{
|
||||
case QgsPropertyDefinition::DataTypeString:
|
||||
type = QVariant::String;
|
||||
len = 50;
|
||||
typeName = "String";
|
||||
break;
|
||||
case QgsPropertyDefinition::DataTypeNumeric:
|
||||
type = QVariant::Double;
|
||||
len = 0;
|
||||
precision = 0;
|
||||
typeName = "Real";
|
||||
break;
|
||||
case QgsPropertyDefinition::DataTypeBoolean:
|
||||
type = QVariant::Int; // sqlite does not have a bool type
|
||||
typeName = "Integer";
|
||||
break;
|
||||
}
|
||||
|
||||
afield.setType( type );
|
||||
afield.setName( nameFromProperty( def ) );
|
||||
afield.setTypeName( typeName );
|
||||
afield.setLength( len );
|
||||
afield.setPrecision( precision );
|
||||
}
|
||||
|
||||
return afield;
|
||||
}
|
||||
|
||||
QgsPropertyDefinition QgsAuxiliaryLayer::propertyDefinitionFromField( const QgsField &f )
|
||||
{
|
||||
QgsPropertyDefinition def;
|
||||
const QStringList parts = f.name().split( '_' );
|
||||
|
||||
if ( parts.size() <= 1 )
|
||||
return def;
|
||||
|
||||
const QString origin = parts[0];
|
||||
const QString propertyName = parts[1];
|
||||
|
||||
if ( origin.compare( "labeling", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition props = QgsPalLayerSettings::propertyDefinitions();
|
||||
for ( const QgsPropertyDefinition &p : props.values() )
|
||||
{
|
||||
if ( p.name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
def = p;
|
||||
if ( parts.size() == 3 )
|
||||
def.setComment( parts[2] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( origin.compare( "symbol", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition props = QgsSymbolLayer::propertyDefinitions();
|
||||
for ( const QgsPropertyDefinition &p : props.values() )
|
||||
{
|
||||
if ( p.name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
def = p;
|
||||
if ( parts.size() == 3 )
|
||||
def.setComment( parts[2] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( origin.compare( "diagram", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition props = QgsDiagramLayerSettings::propertyDefinitions();
|
||||
for ( const QgsPropertyDefinition &p : props.values() )
|
||||
{
|
||||
if ( p.name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
def = p;
|
||||
if ( parts.size() == 3 )
|
||||
def.setComment( parts[2] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
def.setOrigin( origin );
|
||||
def.setName( propertyName );
|
||||
|
||||
if ( parts.size() == 3 )
|
||||
def.setComment( parts[2] );
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
QgsField QgsAuxiliaryLayer::createAuxiliaryField( const QgsField &field )
|
||||
{
|
||||
QgsPropertyDefinition def = propertyDefinitionFromField( field );
|
||||
QgsField afield;
|
||||
|
||||
if ( !def.name().isEmpty() || !def.comment().isEmpty() )
|
||||
{
|
||||
afield = createAuxiliaryField( def );
|
||||
afield.setTypeName( field.typeName() );
|
||||
}
|
||||
|
||||
return afield;
|
||||
}
|
||||
|
||||
//
|
||||
// QgsAuxiliaryStorage
|
||||
//
|
||||
|
||||
QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QgsProject &project, bool copy )
|
||||
: mCopy( copy )
|
||||
{
|
||||
initTmpFileName();
|
||||
|
||||
if ( !project.fileInfo().fileName().isEmpty() )
|
||||
{
|
||||
const QFileInfo info = project.fileInfo();
|
||||
const QString path = info.path() + QDir::separator() + info.baseName();
|
||||
const QString asFileName = path + "." + QgsAuxiliaryStorage::extension();
|
||||
mFileName = asFileName;
|
||||
}
|
||||
|
||||
sqlite3 *handler = open( mFileName );
|
||||
close( handler );
|
||||
}
|
||||
|
||||
QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QString &filename, bool copy )
|
||||
: mFileName( filename )
|
||||
, mCopy( copy )
|
||||
{
|
||||
initTmpFileName();
|
||||
|
||||
sqlite3 *handler = open( filename );
|
||||
close( handler );
|
||||
}
|
||||
|
||||
QgsAuxiliaryStorage::~QgsAuxiliaryStorage()
|
||||
{
|
||||
QFile::remove( mTmpFileName );
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::isValid() const
|
||||
{
|
||||
return mValid;
|
||||
}
|
||||
|
||||
QString QgsAuxiliaryStorage::fileName() const
|
||||
{
|
||||
return mFileName;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::save() const
|
||||
{
|
||||
if ( mFileName.isEmpty() )
|
||||
{
|
||||
// only a saveAs is available on a new database
|
||||
return false;
|
||||
}
|
||||
else if ( mCopy )
|
||||
{
|
||||
if ( QFile::exists( mFileName ) )
|
||||
QFile::remove( mFileName );
|
||||
|
||||
return QFile::copy( mTmpFileName, mFileName );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the file is not empty the copy mode is not activated, then we're
|
||||
// directly working on the database since the beginning (no savepoints
|
||||
// /rollback for now)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QgsAuxiliaryLayer *QgsAuxiliaryStorage::createAuxiliaryLayer( const QgsField &field, QgsVectorLayer *layer ) const
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = nullptr;
|
||||
|
||||
if ( mValid && layer )
|
||||
{
|
||||
const QString table( layer->id() );
|
||||
sqlite3 *handler = openDB( currentFileName() );
|
||||
|
||||
if ( !tableExists( table, handler ) )
|
||||
{
|
||||
if ( !createTable( field.typeName(), table, handler ) )
|
||||
{
|
||||
close( handler );
|
||||
return alayer;
|
||||
}
|
||||
}
|
||||
|
||||
alayer = new QgsAuxiliaryLayer( field.name(), currentFileName(), table, layer );
|
||||
alayer->startEditing();
|
||||
close( handler );
|
||||
}
|
||||
|
||||
return alayer;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::deleteTable( const QgsDataSourceUri &ogrUri )
|
||||
{
|
||||
bool rc = false;
|
||||
QgsDataSourceUri uri = parseOgrUri( ogrUri );
|
||||
|
||||
if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
|
||||
{
|
||||
sqlite3 *handler = openDB( uri.database() );
|
||||
|
||||
if ( handler )
|
||||
{
|
||||
QString sql = QString( "DROP TABLE %1" ).arg( uri.table() );
|
||||
rc = exec( sql, handler );
|
||||
|
||||
sql = QString( "VACUUM" );
|
||||
rc = exec( sql, handler );
|
||||
|
||||
close( handler );
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::duplicateTable( const QgsDataSourceUri &ogrUri, const QString &newTable )
|
||||
{
|
||||
QgsDataSourceUri uri = parseOgrUri( ogrUri );
|
||||
bool rc = false;
|
||||
|
||||
if ( !uri.table().isEmpty() && !uri.database().isEmpty() )
|
||||
{
|
||||
sqlite3 *handler = openDB( uri.database() );
|
||||
|
||||
if ( handler )
|
||||
{
|
||||
QString sql = QString( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
|
||||
rc = exec( sql, handler );
|
||||
|
||||
close( handler );
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::saveAs( const QString &filename ) const
|
||||
{
|
||||
if ( QFile::exists( filename ) )
|
||||
QFile::remove( filename );
|
||||
|
||||
return QFile::copy( currentFileName(), filename );
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::saveAs( const QgsProject &project ) const
|
||||
{
|
||||
return saveAs( filenameForProject( project ) );
|
||||
}
|
||||
|
||||
QString QgsAuxiliaryStorage::extension()
|
||||
{
|
||||
return AS_EXTENSION;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::exec( const QString &sql, sqlite3 *handler )
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
if ( handler )
|
||||
{
|
||||
const int err = sqlite3_exec( handler, sql.toStdString().c_str(), nullptr, nullptr, nullptr );
|
||||
|
||||
if ( err == SQLITE_OK )
|
||||
rc = true;
|
||||
else
|
||||
debugMsg( sql, handler );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void QgsAuxiliaryStorage::debugMsg( const QString &sql, sqlite3 *handler )
|
||||
{
|
||||
const QString err = QString::fromUtf8( sqlite3_errmsg( handler ) );
|
||||
const QString msg = QObject::tr( "Unable to execute" );
|
||||
const QString errMsg = QObject::tr( "%1 '%2': %3" ).arg( msg ).arg( sql ).arg( err );
|
||||
QgsDebugMsg( errMsg );
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::openDB( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
|
||||
bool rc = QgsSLConnect::sqlite3_open_v2( filename.toUtf8().constData(), &handler, SQLITE_OPEN_READWRITE, nullptr );
|
||||
if ( rc )
|
||||
{
|
||||
debugMsg( "sqlite3_open_v2", handler );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::createTable( const QString &type, const QString &table, sqlite3 *handler )
|
||||
{
|
||||
const QString sql = QString( "CREATE TABLE IF NOT EXISTS '%1' ( '%2' %3 )" ).arg( table ).arg( AS_JOINFIELD ).arg( type );
|
||||
|
||||
if ( !exec( sql, handler ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::createDB( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
int rc;
|
||||
|
||||
// open/create database
|
||||
rc = QgsSLConnect::sqlite3_open_v2( filename.toUtf8().constData(), &handler, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
|
||||
if ( rc )
|
||||
{
|
||||
debugMsg( "sqlite3_open_v2", handler );
|
||||
return handler;
|
||||
}
|
||||
|
||||
// activating Foreign Key constraints
|
||||
if ( !exec( "PRAGMA foreign_keys = 1", handler ) )
|
||||
return handler;
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryStorage::tableExists( const QString &table, sqlite3 *handler )
|
||||
{
|
||||
const QString sql = QString( "SELECT 1 FROM sqlite_master WHERE type='table' AND name='%1'" ).arg( table );
|
||||
int rows = 0;
|
||||
int columns = 0;
|
||||
char **results = nullptr;
|
||||
const int rc = sqlite3_get_table( handler, sql.toStdString().c_str(), &results, &rows, &columns, nullptr );
|
||||
if ( rc != SQLITE_OK )
|
||||
{
|
||||
debugMsg( sql, handler );
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_free_table( results );
|
||||
if ( rows >= 1 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::open( const QString &filename )
|
||||
{
|
||||
sqlite3 *handler = nullptr;
|
||||
|
||||
if ( filename.isEmpty() )
|
||||
{
|
||||
if ( ( handler = createDB( currentFileName() ) ) )
|
||||
mValid = true;
|
||||
}
|
||||
else if ( QFile::exists( filename ) )
|
||||
{
|
||||
if ( mCopy )
|
||||
QFile::copy( filename, mTmpFileName );
|
||||
|
||||
if ( ( handler = openDB( currentFileName() ) ) )
|
||||
mValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( handler = createDB( currentFileName() ) ) )
|
||||
mValid = true;
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
sqlite3 *QgsAuxiliaryStorage::open( const QgsProject &project )
|
||||
{
|
||||
return open( filenameForProject( project ) );
|
||||
}
|
||||
|
||||
void QgsAuxiliaryStorage::close( sqlite3 *handler )
|
||||
{
|
||||
if ( handler )
|
||||
{
|
||||
QgsSLConnect::sqlite3_close_v2( handler );
|
||||
handler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsAuxiliaryStorage::filenameForProject( const QgsProject &project )
|
||||
{
|
||||
const QFileInfo info = project.fileInfo();
|
||||
const QString path = info.path() + QDir::separator() + info.baseName();
|
||||
return path + "." + QgsAuxiliaryStorage::extension();
|
||||
}
|
||||
|
||||
void QgsAuxiliaryStorage::initTmpFileName()
|
||||
{
|
||||
QTemporaryFile tmpFile;
|
||||
tmpFile.open();
|
||||
tmpFile.close();
|
||||
mTmpFileName = tmpFile.fileName();
|
||||
}
|
||||
|
||||
QString QgsAuxiliaryStorage::currentFileName() const
|
||||
{
|
||||
if ( mCopy || mFileName.isEmpty() )
|
||||
return mTmpFileName;
|
||||
else
|
||||
return mFileName;
|
||||
}
|
||||
|
||||
QgsDataSourceUri QgsAuxiliaryStorage::parseOgrUri( const QgsDataSourceUri &uri )
|
||||
{
|
||||
QgsDataSourceUri newUri;
|
||||
|
||||
// parsing for ogr style uri :
|
||||
// " filePath|layername='tableName' table="" sql="
|
||||
QStringList uriParts = uri.uri().split( '|' );
|
||||
if ( uriParts.count() < 2 )
|
||||
return newUri;
|
||||
|
||||
const QString databasePath = uriParts[0].replace( ' ', "" );
|
||||
|
||||
const QString table = uriParts[1];
|
||||
QStringList tableParts = table.split( ' ' );
|
||||
|
||||
if ( tableParts.count() < 1 )
|
||||
return newUri;
|
||||
|
||||
const QString tableName = tableParts[0].replace( "layername=", "" );
|
||||
|
||||
newUri.setDataSource( QString(), tableName, QString() );
|
||||
newUri.setDatabase( databasePath );
|
||||
|
||||
return newUri;
|
||||
}
|
411
src/core/qgsauxiliarystorage.h
Normal file
411
src/core/qgsauxiliarystorage.h
Normal file
@ -0,0 +1,411 @@
|
||||
/***************************************************************************
|
||||
qgsauxiliarystorage.h - description
|
||||
-------------------
|
||||
begin : Aug 28, 2017
|
||||
copyright : (C) 2017 by Paul Blottiere
|
||||
email : paul.blottiere@oslandia.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSAUXILIARYSTORAGE_H
|
||||
#define QGSAUXILIARYSTORAGE_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgspallabeling.h"
|
||||
#include "qgsdiagramrenderer.h"
|
||||
#include "qgsvectorlayerjoininfo.h"
|
||||
#include "qgsproperty.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QgsProject;
|
||||
|
||||
/**
|
||||
* \class QgsAuxiliaryLayer
|
||||
*
|
||||
* \ingroup core
|
||||
*
|
||||
* Class allowing to manage the auxiliary storage for a vector layer.
|
||||
*
|
||||
* Such auxiliary data are data used mostly for the needs of QGIS (symbology)
|
||||
* and have no real interest in being stored with the native raw geospatial
|
||||
* data.
|
||||
*
|
||||
* The need arises from the restrictions existing in the manual placement of
|
||||
* labels. Manual placement of labels are possible in QGIS by setting some
|
||||
* labeling properties (X and Y position, and rotation angle optionally) as
|
||||
* being "data-defined", meaning that values come from a column (or an
|
||||
* expression). But setting this up on an existing layer requires either to
|
||||
* add new columns to the source layer, while it is not always possible or
|
||||
* desirable.
|
||||
*
|
||||
* This QgsAuxiliaryLayer provides the solution to this limitation. Actually
|
||||
* it's an editable join to the original vector layer with some
|
||||
* synchronisation mechanisms activated such as "Upsert On Edit" or "Delete
|
||||
* Cascade". Thus, auxiliary fields are editable even if the
|
||||
* source layer is not and edition of a joined field is also possible.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param pkField The primary key to use for joining
|
||||
* \param filename The database path
|
||||
* \param table The table name
|
||||
* \param vlayer The target vector layer in join definition
|
||||
*/
|
||||
QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer );
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~QgsAuxiliaryLayer() = default;
|
||||
|
||||
/**
|
||||
* Copy constructor deactivated
|
||||
*/
|
||||
QgsAuxiliaryLayer( const QgsAuxiliaryLayer &rhs ) = delete;
|
||||
|
||||
QgsAuxiliaryLayer &operator=( QgsAuxiliaryLayer const &rhs ) = delete;
|
||||
|
||||
/**
|
||||
* Returns a new instance equivalent to this one. The underlying table
|
||||
* is duplicate for the layer given in parameter. Note that the current
|
||||
* auxiliary layer should be saved to have a proper duplicated table.
|
||||
*
|
||||
* \param layer The layer for which the clone is made
|
||||
*/
|
||||
QgsAuxiliaryLayer *clone( QgsVectorLayer *layer ) const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* An auxiliary layer is not spatial. This method returns a spatial
|
||||
* representation of auxiliary data.
|
||||
*
|
||||
* \returns A new spatial vector layer
|
||||
*/
|
||||
QgsVectorLayer *toSpatialLayer() const;
|
||||
|
||||
/**
|
||||
* Deletes all features from the layer. Changes are automatically committed
|
||||
* and the layer remains editable.
|
||||
*
|
||||
* \returns true if changes are committed without error, false otherwise.
|
||||
*/
|
||||
bool clear();
|
||||
|
||||
/**
|
||||
* Returns information to use for joining with primary key and so on.
|
||||
*/
|
||||
QgsVectorLayerJoinInfo joinInfo() const;
|
||||
|
||||
/**
|
||||
* Returns true if the property is stored in the layer already, false
|
||||
* otherwise.
|
||||
*
|
||||
* \param definition The property definition to check
|
||||
*
|
||||
* \returns true if the property is stored, false otherwise
|
||||
*/
|
||||
bool exists( const QgsPropertyDefinition &definition ) const;
|
||||
|
||||
/**
|
||||
* Add an an auxiliary field for the given property. Setup for widget
|
||||
* editors are updated in the target layer as weel as the attribute
|
||||
* table config to hide auxiliary fields by default.
|
||||
*
|
||||
* \param definition The definition of the property to add
|
||||
*
|
||||
* \returns true if the auxiliary field is well added, false otherwise
|
||||
*/
|
||||
bool addAuxiliaryField( const QgsPropertyDefinition &definition );
|
||||
|
||||
/**
|
||||
* Returns a list of all auxiliary fields currently managed by the layer.
|
||||
*/
|
||||
QgsFields auxiliaryFields() const;
|
||||
|
||||
/**
|
||||
* Commit changes and starts editing then.
|
||||
*
|
||||
* \returns true if commit step passed, false otherwise
|
||||
*/
|
||||
bool save();
|
||||
|
||||
/**
|
||||
* Remove attribute from the layer and commit changes. The layer remains
|
||||
* editable.
|
||||
*
|
||||
* \param attr The index of the attribute to remove
|
||||
*
|
||||
* \returns true if the attribute is well deleted, false otherwise
|
||||
*/
|
||||
virtual bool deleteAttribute( int attr ) override;
|
||||
|
||||
/**
|
||||
* Returns true if the underlying field have to be hidden from editing
|
||||
* tools like attribute table, false otherwise.
|
||||
*
|
||||
* \param index The index of the field for which visibility is checked
|
||||
*/
|
||||
bool isHiddenProperty( int index ) const;
|
||||
|
||||
/**
|
||||
* Returns the index of the auxiliary field for a specific property
|
||||
* definition.
|
||||
*
|
||||
* \param definition The property definition
|
||||
*
|
||||
* \returns The index of the field corresponding to the property or -1
|
||||
*/
|
||||
int indexOfPropertyDefinition( const QgsPropertyDefinition &definition ) const;
|
||||
|
||||
/**
|
||||
* Returns the underlying property key for the field index. The key may be
|
||||
* a PAL, diagram or symbology property according to the underlying
|
||||
* property definition of the field. The key -1 is returned if an error
|
||||
* happened.
|
||||
*
|
||||
* \param index The index of the field
|
||||
*/
|
||||
int propertyFromIndex( int index ) const;
|
||||
|
||||
/**
|
||||
* Returns the property definition fir the underlying field index.
|
||||
*
|
||||
* \param index The index of the field
|
||||
*/
|
||||
QgsPropertyDefinition propertyDefinitionFromIndex( int index ) const;
|
||||
|
||||
/**
|
||||
* Creates if necessary a new auxiliary field for a PAL property and
|
||||
* activate this property in settings.
|
||||
*
|
||||
* \param property The property to create
|
||||
* \param vlayer The vector layer
|
||||
*
|
||||
* \returns The index of the auxiliary field or -1
|
||||
*/
|
||||
static int createProperty( QgsPalLayerSettings::Property property, QgsVectorLayer *vlayer );
|
||||
|
||||
/**
|
||||
* Creates if necessary a new auxiliary field for a diagram's property and
|
||||
* activate this this property in settings.
|
||||
*
|
||||
* \param property The property to create
|
||||
* \param vlayer The vector layer
|
||||
*
|
||||
* \returns The index of the auxiliary field or -1
|
||||
*/
|
||||
static int createProperty( QgsDiagramLayerSettings::Property property, QgsVectorLayer *vlayer );
|
||||
|
||||
/**
|
||||
* Creates a new auxiliary field from a property definition.
|
||||
*
|
||||
* \param definition The property definition of the auxiliary field to create
|
||||
*/
|
||||
static QgsField createAuxiliaryField( const QgsPropertyDefinition &definition );
|
||||
|
||||
/**
|
||||
* Creates a new auxiliary field from a field.
|
||||
*
|
||||
* \param field The field to use to create the auxiliary field
|
||||
*/
|
||||
static QgsField createAuxiliaryField( const QgsField &field );
|
||||
|
||||
/**
|
||||
* Returns the name of the auxiliary field for a property definition.
|
||||
*
|
||||
* \param def The property definition
|
||||
* \param joined The join prefix is taken into account if true
|
||||
*/
|
||||
static QString nameFromProperty( const QgsPropertyDefinition &def, bool joined = false );
|
||||
|
||||
/**
|
||||
* Returns the property definition from an auxiliary field.
|
||||
*
|
||||
* \param field The auxiliary field
|
||||
*/
|
||||
static QgsPropertyDefinition propertyDefinitionFromField( const QgsField &field );
|
||||
|
||||
private:
|
||||
QgsVectorLayerJoinInfo mJoinInfo;
|
||||
QString mFileName;
|
||||
QString mTable;
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class QgsAuxiliaryStorage
|
||||
*
|
||||
* \ingroup core
|
||||
*
|
||||
* \brief Class providing some utility methods to manage auxiliary storage.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsAuxiliaryStorage
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The project filename is used to build a database path at the same
|
||||
* location, but with a different extension. Then, it's the same logic as
|
||||
* described for \see QgsAuxiliaryStorage(const QString &, bool copy).
|
||||
*
|
||||
*
|
||||
* \param project The project for which the auxiliary storage has to be used
|
||||
* \param copy Parameter indicating if a copy of the database has to be used
|
||||
*/
|
||||
QgsAuxiliaryStorage( const QgsProject &project, bool copy = true );
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* If a valid database path is given in parameter and copy mode is
|
||||
* deactivated, then every changes is directly committed on the original
|
||||
* database. But if the copy mode is activated, then changes are committed
|
||||
* on a copy of the database (a temporary file) and a save action is
|
||||
* therefore necessary to keep modifications in the original file.
|
||||
*
|
||||
* If an empty string for the database path is given in parameter, then
|
||||
* a database is created in a temporary file whatever the copy mode.
|
||||
*
|
||||
* If the database path given in parameter is not empty but does not exist,
|
||||
* then a database is created at this location when copy mode is
|
||||
* deactivated. When copy mode is activated, a temporary database is used
|
||||
* instead and a save action will be necessary to create the database at
|
||||
* the original location given in parameter.
|
||||
*
|
||||
* \param filename The path of the database
|
||||
* \param copy Parameter indicating if a copy of the database has to be used
|
||||
*/
|
||||
QgsAuxiliaryStorage( const QString &filename = QString(), bool copy = true );
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~QgsAuxiliaryStorage();
|
||||
|
||||
/**
|
||||
* Returns the status of the auxiliary storage currently definied.
|
||||
*
|
||||
* \returns true if the auxiliary storage is valid, false otherwise
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
/**
|
||||
* Returns the target filename of the database.
|
||||
*/
|
||||
QString fileName() const;
|
||||
|
||||
/**
|
||||
* Returns the path of current database used. It may be different from the
|
||||
* target filename if the auxiliary storage is opened in copy mode.
|
||||
*/
|
||||
QString currentFileName() const;
|
||||
|
||||
/**
|
||||
* Saves the current database to a new path.
|
||||
*
|
||||
* \returns true if everything is saved, false otherwise
|
||||
*/
|
||||
bool saveAs( const QString &filename ) const;
|
||||
|
||||
/**
|
||||
* Saves the current database to a new path for a specific project.
|
||||
* Actually, the current filename of the project is used to deduce the
|
||||
* path of the database to save.
|
||||
*
|
||||
* \returns true if everything is saved, false otherwise
|
||||
*/
|
||||
bool saveAs( const QgsProject &project ) const;
|
||||
|
||||
/**
|
||||
* Saves the current database.
|
||||
*
|
||||
* \returns true if everything is saved, false otherwise
|
||||
*/
|
||||
bool save() const;
|
||||
|
||||
/**
|
||||
* Creates an auxiliary layer for a vector layer. A new table is created if
|
||||
* necessary. The primary key to use to construct the auxiliary layer is
|
||||
* given in parameter.
|
||||
*
|
||||
* \param field The primary key to join
|
||||
* \param layer The vector layer for which the auxiliary layer has to be created
|
||||
*
|
||||
* \returns A new auxiliary layer or a nullptr if an error happened.
|
||||
*/
|
||||
QgsAuxiliaryLayer *createAuxiliaryLayer( const QgsField &field, QgsVectorLayer *layer ) const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Removes a table from the auxiliary storage.
|
||||
*
|
||||
* \param uri The uri of the table to remove
|
||||
*
|
||||
* \returns true if the table is well deleted, false otherwise
|
||||
*/
|
||||
static bool deleteTable( const QgsDataSourceUri &uri );
|
||||
|
||||
/**
|
||||
* Duplicates a table and its content.
|
||||
*
|
||||
* \param uri The uri of the table to duplicate
|
||||
* \param newTable The name of the new table
|
||||
*
|
||||
* \returns true if the table is well duplicated, false otherwise
|
||||
*/
|
||||
static bool duplicateTable( const QgsDataSourceUri &uri, const QString &newTable );
|
||||
|
||||
/**
|
||||
* Returns the extension used for auxiliary databases.
|
||||
*/
|
||||
static QString extension();
|
||||
|
||||
private:
|
||||
sqlite3 *open( const QString &filename = QString() );
|
||||
sqlite3 *open( const QgsProject &project );
|
||||
|
||||
void initTmpFileName();
|
||||
|
||||
static QString filenameForProject( const QgsProject &project );
|
||||
static sqlite3 *createDB( const QString &filename );
|
||||
static sqlite3 *openDB( const QString &filename );
|
||||
static void close( sqlite3 *handler );
|
||||
static bool tableExists( const QString &table, sqlite3 *handler );
|
||||
static bool createTable( const QString &type, const QString &table, sqlite3 *handler );
|
||||
|
||||
static bool exec( const QString &sql, sqlite3 *handler );
|
||||
static void debugMsg( const QString &sql, sqlite3 *handler );
|
||||
|
||||
static QgsDataSourceUri parseOgrUri( const QgsDataSourceUri &uri );
|
||||
|
||||
bool mValid = false;
|
||||
QString mFileName; // original filename
|
||||
QString mTmpFileName; // temporary filename used in copy mode
|
||||
bool mCopy = false;
|
||||
};
|
||||
|
||||
#endif
|
@ -34,20 +34,22 @@ void QgsDiagramLayerSettings::initPropertyDefinitions()
|
||||
if ( !sPropertyDefinitions.isEmpty() )
|
||||
return;
|
||||
|
||||
const QString origin = QStringLiteral( "diagram" );
|
||||
|
||||
sPropertyDefinitions = QgsPropertiesDefinition
|
||||
{
|
||||
{ QgsDiagramLayerSettings::BackgroundColor, QgsPropertyDefinition( "backgroundColor", QObject::tr( "Background color" ), QgsPropertyDefinition::ColorWithAlpha ) },
|
||||
{ QgsDiagramLayerSettings::StrokeColor, QgsPropertyDefinition( "strokeColor", QObject::tr( "Stroke color" ), QgsPropertyDefinition::ColorWithAlpha ) },
|
||||
{ QgsDiagramLayerSettings::StrokeWidth, QgsPropertyDefinition( "strokeWidth", QObject::tr( "Stroke width" ), QgsPropertyDefinition::StrokeWidth ) },
|
||||
{ QgsDiagramLayerSettings::PositionX, QgsPropertyDefinition( "positionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsDiagramLayerSettings::PositionY, QgsPropertyDefinition( "positionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsDiagramLayerSettings::Distance, QgsPropertyDefinition( "distance", QObject::tr( "Placement distance" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsDiagramLayerSettings::Priority, QgsPropertyDefinition( "priority", QObject::tr( "Placement priority" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsDiagramLayerSettings::ZIndex, QgsPropertyDefinition( "zIndex", QObject::tr( "Placement z-index" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsDiagramLayerSettings::IsObstacle, QgsPropertyDefinition( "isObstacle", QObject::tr( "Diagram is an obstacle" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsDiagramLayerSettings::Show, QgsPropertyDefinition( "show", QObject::tr( "Show diagram" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsDiagramLayerSettings::AlwaysShow, QgsPropertyDefinition( "alwaysShow", QObject::tr( "Always show diagram" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsDiagramLayerSettings::StartAngle, QgsPropertyDefinition( "startAngle", QObject::tr( "Pie chart start angle" ), QgsPropertyDefinition::Rotation ) },
|
||||
{ QgsDiagramLayerSettings::BackgroundColor, QgsPropertyDefinition( "backgroundColor", QObject::tr( "Background color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
|
||||
{ QgsDiagramLayerSettings::StrokeColor, QgsPropertyDefinition( "strokeColor", QObject::tr( "Stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
|
||||
{ QgsDiagramLayerSettings::StrokeWidth, QgsPropertyDefinition( "strokeWidth", QObject::tr( "Stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
|
||||
{ QgsDiagramLayerSettings::PositionX, QgsPropertyDefinition( "positionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsDiagramLayerSettings::PositionY, QgsPropertyDefinition( "positionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsDiagramLayerSettings::Distance, QgsPropertyDefinition( "distance", QObject::tr( "Placement distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsDiagramLayerSettings::Priority, QgsPropertyDefinition( "priority", QObject::tr( "Placement priority" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsDiagramLayerSettings::ZIndex, QgsPropertyDefinition( "zIndex", QObject::tr( "Placement z-index" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsDiagramLayerSettings::IsObstacle, QgsPropertyDefinition( "isObstacle", QObject::tr( "Diagram is an obstacle" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsDiagramLayerSettings::Show, QgsPropertyDefinition( "show", QObject::tr( "Show diagram" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsDiagramLayerSettings::AlwaysShow, QgsPropertyDefinition( "alwaysShow", QObject::tr( "Always show diagram" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsDiagramLayerSettings::StartAngle, QgsPropertyDefinition( "startAngle", QObject::tr( "Pie chart start angle" ), QgsPropertyDefinition::Rotation, origin ) },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -97,134 +97,136 @@ void QgsPalLayerSettings::initPropertyDefinitions()
|
||||
if ( !sPropertyDefinitions.isEmpty() )
|
||||
return;
|
||||
|
||||
const QString origin = QStringLiteral( "labeling" );
|
||||
|
||||
sPropertyDefinitions = QgsPropertiesDefinition
|
||||
{
|
||||
{ QgsPalLayerSettings::Size, QgsPropertyDefinition( "Size", QObject::tr( "Font size" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsPalLayerSettings::Bold, QgsPropertyDefinition( "Bold", QObject::tr( "Bold style" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::Italic, QgsPropertyDefinition( "Italic", QObject::tr( "Italic style" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::Underline, QgsPropertyDefinition( "Underline", QObject::tr( "Draw underline" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::Color, QgsPropertyDefinition( "Color", QObject::tr( "Text color" ), QgsPropertyDefinition::ColorNoAlpha ) },
|
||||
{ QgsPalLayerSettings::Strikeout, QgsPropertyDefinition( "Strikeout", QObject::tr( "Draw strikeout" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::Size, QgsPropertyDefinition( "Size", QObject::tr( "Font size" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsPalLayerSettings::Bold, QgsPropertyDefinition( "Bold", QObject::tr( "Bold style" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::Italic, QgsPropertyDefinition( "Italic", QObject::tr( "Italic style" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::Underline, QgsPropertyDefinition( "Underline", QObject::tr( "Draw underline" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::Color, QgsPropertyDefinition( "Color", QObject::tr( "Text color" ), QgsPropertyDefinition::ColorNoAlpha, origin ) },
|
||||
{ QgsPalLayerSettings::Strikeout, QgsPropertyDefinition( "Strikeout", QObject::tr( "Draw strikeout" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{
|
||||
QgsPalLayerSettings::Family, QgsPropertyDefinition( "Family", QgsPropertyDefinition::DataTypeString, QObject::tr( "Font family" ), QObject::tr( "string " ) + QObject::tr( "[<b>family</b>|<b>family[foundry]</b>],<br>"
|
||||
"e.g. Helvetica or Helvetica [Cronyx]" ) )
|
||||
"e.g. Helvetica or Helvetica [Cronyx]" ), origin )
|
||||
},
|
||||
{
|
||||
QgsPalLayerSettings::FontStyle, QgsPropertyDefinition( "FontStyle", QgsPropertyDefinition::DataTypeString, QObject::tr( "Font style" ), QObject::tr( "string " ) + QObject::tr( "[<b>font style name</b>|<b>Ignore</b>],<br>"
|
||||
"e.g. Bold Condensed or Light Italic" ) )
|
||||
"e.g. Bold Condensed or Light Italic" ), origin )
|
||||
},
|
||||
{ QgsPalLayerSettings::FontSizeUnit, QgsPropertyDefinition( "FontSizeUnit", QObject::tr( "Font size units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::FontTransp, QgsPropertyDefinition( "FontTransp", QObject::tr( "Text transparency" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::FontOpacity, QgsPropertyDefinition( "FontOpacity", QObject::tr( "Text opacity" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::FontCase, QgsPropertyDefinition( "FontCase", QgsPropertyDefinition::DataTypeString, QObject::tr( "Font case" ), QObject::tr( "string " ) + QStringLiteral( "[<b>NoChange</b>|<b>Upper</b>|<br><b>Lower</b>|<b>Capitalize</b>]" ) ) },
|
||||
{ QgsPalLayerSettings::FontLetterSpacing, QgsPropertyDefinition( "FontLetterSpacing", QObject::tr( "Letter spacing" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::FontWordSpacing, QgsPropertyDefinition( "FontWordSpacing", QObject::tr( "Word spacing" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::FontBlendMode, QgsPropertyDefinition( "FontBlendMode", QObject::tr( "Text blend mode" ), QgsPropertyDefinition::BlendMode ) },
|
||||
{ QgsPalLayerSettings::MultiLineWrapChar, QgsPropertyDefinition( "MultiLineWrapChar", QObject::tr( "Wrap character" ), QgsPropertyDefinition::String ) },
|
||||
{ QgsPalLayerSettings::MultiLineHeight, QgsPropertyDefinition( "MultiLineHeight", QObject::tr( "Line height" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsPalLayerSettings::MultiLineAlignment, QgsPropertyDefinition( "MultiLineAlignment", QgsPropertyDefinition::DataTypeString, QObject::tr( "Line alignment" ), QObject::tr( "string " ) + "[<b>Left</b>|<b>Center</b>|<b>Right</b>|<b>Follow</b>]" ) },
|
||||
{ QgsPalLayerSettings::DirSymbDraw, QgsPropertyDefinition( "DirSymbDraw", QObject::tr( "Draw direction symbol" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::DirSymbLeft, QgsPropertyDefinition( "DirSymbLeft", QObject::tr( "Left direction symbol" ), QgsPropertyDefinition::String ) },
|
||||
{ QgsPalLayerSettings::DirSymbRight, QgsPropertyDefinition( "DirSymbRight", QObject::tr( "Right direction symbol" ), QgsPropertyDefinition::String ) },
|
||||
{ QgsPalLayerSettings::DirSymbPlacement, QgsPropertyDefinition( "DirSymbPlacement", QgsPropertyDefinition::DataTypeString, QObject::tr( "Direction symbol placement" ), QObject::tr( "string " ) + "[<b>LeftRight</b>|<b>Above</b>|<b>Below</b>]" ) },
|
||||
{ QgsPalLayerSettings::DirSymbReverse, QgsPropertyDefinition( "DirSymbReverse", QObject::tr( "Reverse direction symbol" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::NumFormat, QgsPropertyDefinition( "NumFormat", QObject::tr( "Format as number" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::NumDecimals, QgsPropertyDefinition( "NumDecimals", QObject::tr( "Number of decimal places" ), QgsPropertyDefinition::IntegerPositive ) },
|
||||
{ QgsPalLayerSettings::NumPlusSign, QgsPropertyDefinition( "NumPlusSign", QObject::tr( "Draw + sign" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::BufferDraw, QgsPropertyDefinition( "BufferDraw", QObject::tr( "Draw buffer" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::BufferSize, QgsPropertyDefinition( "BufferSize", QObject::tr( "Symbol size" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsPalLayerSettings::BufferUnit, QgsPropertyDefinition( "BufferUnit", QObject::tr( "Buffer units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::BufferColor, QgsPropertyDefinition( "BufferColor", QObject::tr( "Buffer color" ), QgsPropertyDefinition::ColorNoAlpha ) },
|
||||
{ QgsPalLayerSettings::BufferTransp, QgsPropertyDefinition( "BufferTransp", QObject::tr( "Buffer transparency" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::BufferOpacity, QgsPropertyDefinition( "BufferOpacity", QObject::tr( "Buffer opacity" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::BufferJoinStyle, QgsPropertyDefinition( "BufferJoinStyle", QObject::tr( "Buffer join style" ), QgsPropertyDefinition::PenJoinStyle ) },
|
||||
{ QgsPalLayerSettings::BufferBlendMode, QgsPropertyDefinition( "BufferBlendMode", QObject::tr( "Buffer blend mode" ), QgsPropertyDefinition::BlendMode ) },
|
||||
{ QgsPalLayerSettings::ShapeDraw, QgsPropertyDefinition( "ShapeDraw", QObject::tr( "Draw shape" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::FontSizeUnit, QgsPropertyDefinition( "FontSizeUnit", QObject::tr( "Font size units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::FontTransp, QgsPropertyDefinition( "FontTransp", QObject::tr( "Text transparency" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::FontOpacity, QgsPropertyDefinition( "FontOpacity", QObject::tr( "Text opacity" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::FontCase, QgsPropertyDefinition( "FontCase", QgsPropertyDefinition::DataTypeString, QObject::tr( "Font case" ), QObject::tr( "string " ) + QStringLiteral( "[<b>NoChange</b>|<b>Upper</b>|<br><b>Lower</b>|<b>Capitalize</b>]" ), origin ) },
|
||||
{ QgsPalLayerSettings::FontLetterSpacing, QgsPropertyDefinition( "FontLetterSpacing", QObject::tr( "Letter spacing" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::FontWordSpacing, QgsPropertyDefinition( "FontWordSpacing", QObject::tr( "Word spacing" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::FontBlendMode, QgsPropertyDefinition( "FontBlendMode", QObject::tr( "Text blend mode" ), QgsPropertyDefinition::BlendMode, origin ) },
|
||||
{ QgsPalLayerSettings::MultiLineWrapChar, QgsPropertyDefinition( "MultiLineWrapChar", QObject::tr( "Wrap character" ), QgsPropertyDefinition::String, origin ) },
|
||||
{ QgsPalLayerSettings::MultiLineHeight, QgsPropertyDefinition( "MultiLineHeight", QObject::tr( "Line height" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsPalLayerSettings::MultiLineAlignment, QgsPropertyDefinition( "MultiLineAlignment", QgsPropertyDefinition::DataTypeString, QObject::tr( "Line alignment" ), QObject::tr( "string " ) + "[<b>Left</b>|<b>Center</b>|<b>Right</b>|<b>Follow</b>]", origin ) },
|
||||
{ QgsPalLayerSettings::DirSymbDraw, QgsPropertyDefinition( "DirSymbDraw", QObject::tr( "Draw direction symbol" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::DirSymbLeft, QgsPropertyDefinition( "DirSymbLeft", QObject::tr( "Left direction symbol" ), QgsPropertyDefinition::String, origin ) },
|
||||
{ QgsPalLayerSettings::DirSymbRight, QgsPropertyDefinition( "DirSymbRight", QObject::tr( "Right direction symbol" ), QgsPropertyDefinition::String, origin ) },
|
||||
{ QgsPalLayerSettings::DirSymbPlacement, QgsPropertyDefinition( "DirSymbPlacement", QgsPropertyDefinition::DataTypeString, QObject::tr( "Direction symbol placement" ), QObject::tr( "string " ) + "[<b>LeftRight</b>|<b>Above</b>|<b>Below</b>]", origin ) },
|
||||
{ QgsPalLayerSettings::DirSymbReverse, QgsPropertyDefinition( "DirSymbReverse", QObject::tr( "Reverse direction symbol" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::NumFormat, QgsPropertyDefinition( "NumFormat", QObject::tr( "Format as number" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::NumDecimals, QgsPropertyDefinition( "NumDecimals", QObject::tr( "Number of decimal places" ), QgsPropertyDefinition::IntegerPositive, origin ) },
|
||||
{ QgsPalLayerSettings::NumPlusSign, QgsPropertyDefinition( "NumPlusSign", QObject::tr( "Draw + sign" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::BufferDraw, QgsPropertyDefinition( "BufferDraw", QObject::tr( "Draw buffer" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::BufferSize, QgsPropertyDefinition( "BufferSize", QObject::tr( "Symbol size" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsPalLayerSettings::BufferUnit, QgsPropertyDefinition( "BufferUnit", QObject::tr( "Buffer units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::BufferColor, QgsPropertyDefinition( "BufferColor", QObject::tr( "Buffer color" ), QgsPropertyDefinition::ColorNoAlpha, origin ) },
|
||||
{ QgsPalLayerSettings::BufferTransp, QgsPropertyDefinition( "BufferTransp", QObject::tr( "Buffer transparency" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::BufferOpacity, QgsPropertyDefinition( "BufferOpacity", QObject::tr( "Buffer opacity" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::BufferJoinStyle, QgsPropertyDefinition( "BufferJoinStyle", QObject::tr( "Buffer join style" ), QgsPropertyDefinition::PenJoinStyle, origin ) },
|
||||
{ QgsPalLayerSettings::BufferBlendMode, QgsPropertyDefinition( "BufferBlendMode", QObject::tr( "Buffer blend mode" ), QgsPropertyDefinition::BlendMode, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeDraw, QgsPropertyDefinition( "ShapeDraw", QObject::tr( "Draw shape" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{
|
||||
QgsPalLayerSettings::ShapeKind, QgsPropertyDefinition( "ShapeKind", QgsPropertyDefinition::DataTypeString, QObject::tr( "Shape type" ), QObject::tr( "string " ) + QStringLiteral( "[<b>Rectangle</b>|<b>Square</b>|<br>"
|
||||
"<b>Ellipse</b>|<b>Circle</b>|<b>SVG</b>]" ) )
|
||||
"<b>Ellipse</b>|<b>Circle</b>|<b>SVG</b>]" ), origin )
|
||||
},
|
||||
{ QgsPalLayerSettings::ShapeSVGFile, QgsPropertyDefinition( "ShapeSVGFile", QObject::tr( "Shape SVG path" ), QgsPropertyDefinition::SvgPath ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeType, QgsPropertyDefinition( "ShapeSizeType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Shape size type" ), QObject::tr( "string " ) + "[<b>Buffer</b>|<b>Fixed</b>]" ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeX, QgsPropertyDefinition( "ShapeSizeX", QObject::tr( "Shape size (X)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeY, QgsPropertyDefinition( "ShapeSizeY", QObject::tr( "Shape size (Y)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeUnits, QgsPropertyDefinition( "ShapeSizeUnits", QObject::tr( "Shape size units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::ShapeRotationType, QgsPropertyDefinition( "ShapeRotationType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Shape rotation type" ), QObject::tr( "string " ) + "[<b>Sync</b>|<b>Offset</b>|<b>Fixed</b>]" ) },
|
||||
{ QgsPalLayerSettings::ShapeRotation, QgsPropertyDefinition( "ShapeRotation", QObject::tr( "Shape rotation" ), QgsPropertyDefinition::Rotation ) },
|
||||
{ QgsPalLayerSettings::ShapeOffset, QgsPropertyDefinition( "ShapeOffset", QObject::tr( "Shape offset" ), QgsPropertyDefinition::Offset ) },
|
||||
{ QgsPalLayerSettings::ShapeOffsetUnits, QgsPropertyDefinition( "ShapeOffsetUnits", QObject::tr( "Shape offset units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::ShapeRadii, QgsPropertyDefinition( "ShapeRadii", QObject::tr( "Shape radii" ), QgsPropertyDefinition::Size2D ) },
|
||||
{ QgsPalLayerSettings::ShapeRadiiUnits, QgsPropertyDefinition( "ShapeRadiiUnits", QObject::tr( "Symbol radii units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::ShapeTransparency, QgsPropertyDefinition( "ShapeTransparency", QObject::tr( "Shape transparency" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::ShapeOpacity, QgsPropertyDefinition( "ShapeOpacity", QObject::tr( "Shape opacity" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::ShapeBlendMode, QgsPropertyDefinition( "ShapeBlendMode", QObject::tr( "Shape blend mode" ), QgsPropertyDefinition::BlendMode ) },
|
||||
{ QgsPalLayerSettings::ShapeFillColor, QgsPropertyDefinition( "ShapeFillColor", QObject::tr( "Shape fill color" ), QgsPropertyDefinition::ColorWithAlpha ) },
|
||||
{ QgsPalLayerSettings::ShapeStrokeColor, QgsPropertyDefinition( "ShapeBorderColor", QObject::tr( "Shape stroke color" ), QgsPropertyDefinition::ColorWithAlpha ) },
|
||||
{ QgsPalLayerSettings::ShapeStrokeWidth, QgsPropertyDefinition( "ShapeBorderWidth", QObject::tr( "Shape stroke width" ), QgsPropertyDefinition::StrokeWidth ) },
|
||||
{ QgsPalLayerSettings::ShapeStrokeWidthUnits, QgsPropertyDefinition( "ShapeBorderWidthUnits", QObject::tr( "Shape stroke width units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::ShapeJoinStyle, QgsPropertyDefinition( "ShapeJoinStyle", QObject::tr( "Shape join style" ), QgsPropertyDefinition::PenJoinStyle ) },
|
||||
{ QgsPalLayerSettings::ShadowDraw, QgsPropertyDefinition( "ShadowDraw", QObject::tr( "Draw shadow" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::ShapeSVGFile, QgsPropertyDefinition( "ShapeSVGFile", QObject::tr( "Shape SVG path" ), QgsPropertyDefinition::SvgPath, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeType, QgsPropertyDefinition( "ShapeSizeType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Shape size type" ), QObject::tr( "string " ) + "[<b>Buffer</b>|<b>Fixed</b>]", origin ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeX, QgsPropertyDefinition( "ShapeSizeX", QObject::tr( "Shape size (X)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeY, QgsPropertyDefinition( "ShapeSizeY", QObject::tr( "Shape size (Y)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeSizeUnits, QgsPropertyDefinition( "ShapeSizeUnits", QObject::tr( "Shape size units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeRotationType, QgsPropertyDefinition( "ShapeRotationType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Shape rotation type" ), QObject::tr( "string " ) + "[<b>Sync</b>|<b>Offset</b>|<b>Fixed</b>]", origin ) },
|
||||
{ QgsPalLayerSettings::ShapeRotation, QgsPropertyDefinition( "ShapeRotation", QObject::tr( "Shape rotation" ), QgsPropertyDefinition::Rotation, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeOffset, QgsPropertyDefinition( "ShapeOffset", QObject::tr( "Shape offset" ), QgsPropertyDefinition::Offset, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeOffsetUnits, QgsPropertyDefinition( "ShapeOffsetUnits", QObject::tr( "Shape offset units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeRadii, QgsPropertyDefinition( "ShapeRadii", QObject::tr( "Shape radii" ), QgsPropertyDefinition::Size2D, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeRadiiUnits, QgsPropertyDefinition( "ShapeRadiiUnits", QObject::tr( "Symbol radii units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeTransparency, QgsPropertyDefinition( "ShapeTransparency", QObject::tr( "Shape transparency" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeOpacity, QgsPropertyDefinition( "ShapeOpacity", QObject::tr( "Shape opacity" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeBlendMode, QgsPropertyDefinition( "ShapeBlendMode", QObject::tr( "Shape blend mode" ), QgsPropertyDefinition::BlendMode, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeFillColor, QgsPropertyDefinition( "ShapeFillColor", QObject::tr( "Shape fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeStrokeColor, QgsPropertyDefinition( "ShapeBorderColor", QObject::tr( "Shape stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeStrokeWidth, QgsPropertyDefinition( "ShapeBorderWidth", QObject::tr( "Shape stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeStrokeWidthUnits, QgsPropertyDefinition( "ShapeBorderWidthUnits", QObject::tr( "Shape stroke width units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::ShapeJoinStyle, QgsPropertyDefinition( "ShapeJoinStyle", QObject::tr( "Shape join style" ), QgsPropertyDefinition::PenJoinStyle, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowDraw, QgsPropertyDefinition( "ShadowDraw", QObject::tr( "Draw shadow" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{
|
||||
QgsPalLayerSettings::ShadowUnder, QgsPropertyDefinition( "ShadowUnder", QgsPropertyDefinition::DataTypeString, QObject::tr( "Symbol size" ), QObject::tr( "string " ) + QStringLiteral( "[<b>Lowest</b>|<b>Text</b>|<br>"
|
||||
"<b>Buffer</b>|<b>Background</b>]" ) )
|
||||
"<b>Buffer</b>|<b>Background</b>]" ), origin )
|
||||
},
|
||||
{ QgsPalLayerSettings::ShadowOffsetAngle, QgsPropertyDefinition( "ShadowOffsetAngle", QObject::tr( "Shadow offset angle" ), QgsPropertyDefinition::Rotation ) },
|
||||
{ QgsPalLayerSettings::ShadowOffsetDist, QgsPropertyDefinition( "ShadowOffsetDist", QObject::tr( "Shadow offset distance" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsPalLayerSettings::ShadowOffsetUnits, QgsPropertyDefinition( "ShadowOffsetUnits", QObject::tr( "Shadow offset units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::ShadowRadius, QgsPropertyDefinition( "ShadowRadius", QObject::tr( "Shadow blur radius" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsPalLayerSettings::ShadowRadiusUnits, QgsPropertyDefinition( "ShadowRadiusUnits", QObject::tr( "Shadow blur units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::ShadowTransparency, QgsPropertyDefinition( "ShadowTransparency", QObject::tr( "Shadow transparency" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::ShadowOpacity, QgsPropertyDefinition( "ShadowOpacity", QObject::tr( "Shadow opacity" ), QgsPropertyDefinition::Opacity ) },
|
||||
{ QgsPalLayerSettings::ShadowScale, QgsPropertyDefinition( "ShadowScale", QObject::tr( "Shadow scale" ), QgsPropertyDefinition::IntegerPositive ) },
|
||||
{ QgsPalLayerSettings::ShadowColor, QgsPropertyDefinition( "ShadowColor", QObject::tr( "Shadow color" ), QgsPropertyDefinition::ColorNoAlpha ) },
|
||||
{ QgsPalLayerSettings::ShadowBlendMode, QgsPropertyDefinition( "ShadowBlendMode", QObject::tr( "Shadow blend mode" ), QgsPropertyDefinition::BlendMode ) },
|
||||
{ QgsPalLayerSettings::ShadowOffsetAngle, QgsPropertyDefinition( "ShadowOffsetAngle", QObject::tr( "Shadow offset angle" ), QgsPropertyDefinition::Rotation, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowOffsetDist, QgsPropertyDefinition( "ShadowOffsetDist", QObject::tr( "Shadow offset distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowOffsetUnits, QgsPropertyDefinition( "ShadowOffsetUnits", QObject::tr( "Shadow offset units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowRadius, QgsPropertyDefinition( "ShadowRadius", QObject::tr( "Shadow blur radius" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowRadiusUnits, QgsPropertyDefinition( "ShadowRadiusUnits", QObject::tr( "Shadow blur units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowTransparency, QgsPropertyDefinition( "ShadowTransparency", QObject::tr( "Shadow transparency" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowOpacity, QgsPropertyDefinition( "ShadowOpacity", QObject::tr( "Shadow opacity" ), QgsPropertyDefinition::Opacity, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowScale, QgsPropertyDefinition( "ShadowScale", QObject::tr( "Shadow scale" ), QgsPropertyDefinition::IntegerPositive, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowColor, QgsPropertyDefinition( "ShadowColor", QObject::tr( "Shadow color" ), QgsPropertyDefinition::ColorNoAlpha, origin ) },
|
||||
{ QgsPalLayerSettings::ShadowBlendMode, QgsPropertyDefinition( "ShadowBlendMode", QObject::tr( "Shadow blend mode" ), QgsPropertyDefinition::BlendMode, origin ) },
|
||||
|
||||
{ QgsPalLayerSettings::CentroidWhole, QgsPropertyDefinition( "CentroidWhole", QgsPropertyDefinition::DataTypeString, QObject::tr( "Centroid of whole shape" ), QObject::tr( "string " ) + "[<b>Visible</b>|<b>Whole</b>]" ) },
|
||||
{ QgsPalLayerSettings::CentroidWhole, QgsPropertyDefinition( "CentroidWhole", QgsPropertyDefinition::DataTypeString, QObject::tr( "Centroid of whole shape" ), QObject::tr( "string " ) + "[<b>Visible</b>|<b>Whole</b>]", origin ) },
|
||||
{
|
||||
QgsPalLayerSettings::OffsetQuad, QgsPropertyDefinition( "OffsetQuad", QgsPropertyDefinition::DataTypeString, QObject::tr( "Offset quadrant" ), QObject::tr( "int<br>" ) + QStringLiteral( "[<b>0</b>=Above Left|<b>1</b>=Above|<b>2</b>=Above Right|<br>"
|
||||
"<b>3</b>=Left|<b>4</b>=Over|<b>5</b>=Right|<br>"
|
||||
"<b>6</b>=Below Left|<b>7</b>=Below|<b>8</b>=Below Right]" ) )
|
||||
"<b>6</b>=Below Left|<b>7</b>=Below|<b>8</b>=Below Right]" ), origin )
|
||||
},
|
||||
{ QgsPalLayerSettings::OffsetXY, QgsPropertyDefinition( "OffsetXY", QObject::tr( "Offset" ), QgsPropertyDefinition::Offset ) },
|
||||
{ QgsPalLayerSettings::OffsetUnits, QgsPropertyDefinition( "OffsetUnits", QObject::tr( "Offset units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::LabelDistance, QgsPropertyDefinition( "LabelDistance", QObject::tr( "Label distance" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsPalLayerSettings::DistanceUnits, QgsPropertyDefinition( "DistanceUnits", QObject::tr( "Label distance units" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::OffsetRotation, QgsPropertyDefinition( "OffsetRotation", QObject::tr( "Offset rotation" ), QgsPropertyDefinition::Rotation ) },
|
||||
{ QgsPalLayerSettings::CurvedCharAngleInOut, QgsPropertyDefinition( "CurvedCharAngleInOut", QgsPropertyDefinition::DataTypeString, QObject::tr( "Curved character angles" ), QObject::tr( "double coord [<b>in,out</b> as 20.0-60.0,20.0-95.0]" ) ) },
|
||||
{ QgsPalLayerSettings::RepeatDistance, QgsPropertyDefinition( "RepeatDistance", QObject::tr( "Repeat distance" ), QgsPropertyDefinition::DoublePositive ) },
|
||||
{ QgsPalLayerSettings::RepeatDistanceUnit, QgsPropertyDefinition( "RepeatDistanceUnit", QObject::tr( "Repeat distance unit" ), QgsPropertyDefinition::RenderUnits ) },
|
||||
{ QgsPalLayerSettings::Priority, QgsPropertyDefinition( "Priority", QgsPropertyDefinition::DataTypeString, QObject::tr( "Label priority" ), QObject::tr( "double [0.0-10.0]" ) ) },
|
||||
{ QgsPalLayerSettings::IsObstacle, QgsPropertyDefinition( "IsObstacle", QObject::tr( "Feature is a label obstacle" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::ObstacleFactor, QgsPropertyDefinition( "ObstacleFactor", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Obstacle factor" ), QObject::tr( "double [0.0-10.0]" ) ) },
|
||||
{ QgsPalLayerSettings::OffsetXY, QgsPropertyDefinition( "OffsetXY", QObject::tr( "Offset" ), QgsPropertyDefinition::Offset, origin ) },
|
||||
{ QgsPalLayerSettings::OffsetUnits, QgsPropertyDefinition( "OffsetUnits", QObject::tr( "Offset units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::LabelDistance, QgsPropertyDefinition( "LabelDistance", QObject::tr( "Label distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsPalLayerSettings::DistanceUnits, QgsPropertyDefinition( "DistanceUnits", QObject::tr( "Label distance units" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::OffsetRotation, QgsPropertyDefinition( "OffsetRotation", QObject::tr( "Offset rotation" ), QgsPropertyDefinition::Rotation, origin ) },
|
||||
{ QgsPalLayerSettings::CurvedCharAngleInOut, QgsPropertyDefinition( "CurvedCharAngleInOut", QgsPropertyDefinition::DataTypeString, QObject::tr( "Curved character angles" ), QObject::tr( "double coord [<b>in,out</b> as 20.0-60.0,20.0-95.0]" ), origin ) },
|
||||
{ QgsPalLayerSettings::RepeatDistance, QgsPropertyDefinition( "RepeatDistance", QObject::tr( "Repeat distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
|
||||
{ QgsPalLayerSettings::RepeatDistanceUnit, QgsPropertyDefinition( "RepeatDistanceUnit", QObject::tr( "Repeat distance unit" ), QgsPropertyDefinition::RenderUnits, origin ) },
|
||||
{ QgsPalLayerSettings::Priority, QgsPropertyDefinition( "Priority", QgsPropertyDefinition::DataTypeString, QObject::tr( "Label priority" ), QObject::tr( "double [0.0-10.0]" ), origin ) },
|
||||
{ QgsPalLayerSettings::IsObstacle, QgsPropertyDefinition( "IsObstacle", QObject::tr( "Feature is a label obstacle" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::ObstacleFactor, QgsPropertyDefinition( "ObstacleFactor", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Obstacle factor" ), QObject::tr( "double [0.0-10.0]" ), origin ) },
|
||||
{
|
||||
QgsPalLayerSettings::PredefinedPositionOrder, QgsPropertyDefinition( "PredefinedPositionOrder", QgsPropertyDefinition::DataTypeString, QObject::tr( "Predefined position order" ), QObject::tr( "Comma separated list of placements in order of priority<br>" )
|
||||
+ QStringLiteral( "[<b>TL</b>=Top left|<b>TSL</b>=Top, slightly left|<b>T</b>=Top middle|<br>"
|
||||
"<b>TSR</b>=Top, slightly right|<b>TR</b>=Top right|<br>"
|
||||
"<b>L</b>=Left|<b>R</b>=Right|<br>"
|
||||
"<b>BL</b>=Bottom left|<b>BSL</b>=Bottom, slightly left|<b>B</b>=Bottom middle|<br>"
|
||||
"<b>BSR</b>=Bottom, slightly right|<b>BR</b>=Bottom right]" ) )
|
||||
"<b>BSR</b>=Bottom, slightly right|<b>BR</b>=Bottom right]" ), origin )
|
||||
},
|
||||
{ QgsPalLayerSettings::PositionX, QgsPropertyDefinition( "PositionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::PositionY, QgsPropertyDefinition( "PositionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::Hali, QgsPropertyDefinition( "Hali", QgsPropertyDefinition::DataTypeString, QObject::tr( "Horizontal alignment" ), QObject::tr( "string " ) + "[<b>Left</b>|<b>Center</b>|<b>Right</b>]" ) },
|
||||
{ QgsPalLayerSettings::PositionX, QgsPropertyDefinition( "PositionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::PositionY, QgsPropertyDefinition( "PositionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::Hali, QgsPropertyDefinition( "Hali", QgsPropertyDefinition::DataTypeString, QObject::tr( "Horizontal alignment" ), QObject::tr( "string " ) + "[<b>Left</b>|<b>Center</b>|<b>Right</b>]", origin ) },
|
||||
{
|
||||
QgsPalLayerSettings::Vali, QgsPropertyDefinition( "Vali", QgsPropertyDefinition::DataTypeString, QObject::tr( "Vertical alignment" ), QObject::tr( "string " ) + QStringLiteral( "[<b>Bottom</b>|<b>Base</b>|<br>"
|
||||
"<b>Half</b>|<b>Cap</b>|<b>Top</b>]" ) )
|
||||
"<b>Half</b>|<b>Cap</b>|<b>Top</b>]" ), origin )
|
||||
},
|
||||
{ QgsPalLayerSettings::Rotation, QgsPropertyDefinition( "Rotation", QObject::tr( "Label rotation (deprecated)" ), QgsPropertyDefinition::Rotation ) },
|
||||
{ QgsPalLayerSettings::LabelRotation, QgsPropertyDefinition( "LabelRotation", QObject::tr( "Label rotation" ), QgsPropertyDefinition::Rotation ) },
|
||||
{ QgsPalLayerSettings::ScaleVisibility, QgsPropertyDefinition( "ScaleVisibility", QObject::tr( "Scale based visibility" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::MinScale, QgsPropertyDefinition( "MinScale", QObject::tr( "Minimum scale (denominator)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::MaxScale, QgsPropertyDefinition( "MaxScale", QObject::tr( "Maximum scale (denominator)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::MinimumScale, QgsPropertyDefinition( "MinimumScale", QObject::tr( "Minimum scale (denominator)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::MaximumScale, QgsPropertyDefinition( "MaximumScale", QObject::tr( "Maximum scale (denominator)" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::Rotation, QgsPropertyDefinition( "Rotation", QObject::tr( "Label rotation (deprecated)" ), QgsPropertyDefinition::Rotation, origin ) },
|
||||
{ QgsPalLayerSettings::LabelRotation, QgsPropertyDefinition( "LabelRotation", QObject::tr( "Label rotation" ), QgsPropertyDefinition::Rotation, origin ) },
|
||||
{ QgsPalLayerSettings::ScaleVisibility, QgsPropertyDefinition( "ScaleVisibility", QObject::tr( "Scale based visibility" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::MinScale, QgsPropertyDefinition( "MinScale", QObject::tr( "Minimum scale (denominator)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::MaxScale, QgsPropertyDefinition( "MaxScale", QObject::tr( "Maximum scale (denominator)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::MinimumScale, QgsPropertyDefinition( "MinimumScale", QObject::tr( "Minimum scale (denominator)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::MaximumScale, QgsPropertyDefinition( "MaximumScale", QObject::tr( "Maximum scale (denominator)" ), QgsPropertyDefinition::Double, origin ) },
|
||||
|
||||
{ QgsPalLayerSettings::FontLimitPixel, QgsPropertyDefinition( "FontLimitPixel", QObject::tr( "Limit font pixel size" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::FontMinPixel, QgsPropertyDefinition( "FontMinPixel", QObject::tr( "Minimum pixel size" ), QgsPropertyDefinition::IntegerPositive ) },
|
||||
{ QgsPalLayerSettings::FontMaxPixel, QgsPropertyDefinition( "FontMaxPixel", QObject::tr( "Maximum pixel size" ), QgsPropertyDefinition::IntegerPositive ) },
|
||||
{ QgsPalLayerSettings::ZIndex, QgsPropertyDefinition( "ZIndex", QObject::tr( "Label z-index" ), QgsPropertyDefinition::Double ) },
|
||||
{ QgsPalLayerSettings::Show, QgsPropertyDefinition( "Show", QObject::tr( "Show label" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::AlwaysShow, QgsPropertyDefinition( "AlwaysShow", QObject::tr( "Always show label" ), QgsPropertyDefinition::Boolean ) },
|
||||
{ QgsPalLayerSettings::FontLimitPixel, QgsPropertyDefinition( "FontLimitPixel", QObject::tr( "Limit font pixel size" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::FontMinPixel, QgsPropertyDefinition( "FontMinPixel", QObject::tr( "Minimum pixel size" ), QgsPropertyDefinition::IntegerPositive, origin ) },
|
||||
{ QgsPalLayerSettings::FontMaxPixel, QgsPropertyDefinition( "FontMaxPixel", QObject::tr( "Maximum pixel size" ), QgsPropertyDefinition::IntegerPositive, origin ) },
|
||||
{ QgsPalLayerSettings::ZIndex, QgsPropertyDefinition( "ZIndex", QObject::tr( "Label z-index" ), QgsPropertyDefinition::Double, origin ) },
|
||||
{ QgsPalLayerSettings::Show, QgsPropertyDefinition( "Show", QObject::tr( "Show label" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
{ QgsPalLayerSettings::AlwaysShow, QgsPropertyDefinition( "AlwaysShow", QObject::tr( "Always show label" ), QgsPropertyDefinition::Boolean, origin ) },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "qgslayoutmanager.h"
|
||||
#include "qgsmaplayerstore.h"
|
||||
#include "qgsziputils.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileInfo>
|
||||
@ -335,6 +336,7 @@ QgsProject::QgsProject( QObject *parent )
|
||||
, mRootGroup( new QgsLayerTree )
|
||||
, mLabelingEngineSettings( new QgsLabelingEngineSettings )
|
||||
, mArchive( new QgsProjectArchive() )
|
||||
, mAuxiliaryStorage( new QgsAuxiliaryStorage() )
|
||||
{
|
||||
mProperties.setName( QStringLiteral( "properties" ) );
|
||||
clear();
|
||||
@ -424,8 +426,6 @@ void QgsProject::setFileName( const QString &name )
|
||||
if ( newHomePath != oldHomePath )
|
||||
emit homePathChanged();
|
||||
|
||||
mArchive->clear();
|
||||
|
||||
setDirty( true );
|
||||
}
|
||||
|
||||
@ -493,6 +493,7 @@ void QgsProject::clear()
|
||||
|
||||
mLabelingEngineSettings->clear();
|
||||
|
||||
mAuxiliaryStorage.reset( new QgsAuxiliaryStorage() );
|
||||
mArchive->clear();
|
||||
|
||||
emit labelingEngineSettingsChanged();
|
||||
@ -776,9 +777,14 @@ bool QgsProject::read()
|
||||
bool rc;
|
||||
|
||||
if ( QgsZipUtils::isZipFile( mFile.fileName() ) )
|
||||
{
|
||||
rc = unzip( mFile.fileName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mAuxiliaryStorage.reset( new QgsAuxiliaryStorage( *this ) );
|
||||
rc = readProjectFile( mFile.fileName() );
|
||||
}
|
||||
|
||||
mFile.setFileName( filename );
|
||||
return rc;
|
||||
@ -850,9 +856,11 @@ bool QgsProject::readProjectFile( const QString &filename )
|
||||
projectFile.updateRevision( thisVersion );
|
||||
}
|
||||
|
||||
// start new project, just keep the file name
|
||||
// start new project, just keep the file name and auxiliary storage
|
||||
QString fileName = mFile.fileName();
|
||||
std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
|
||||
clear();
|
||||
mAuxiliaryStorage = std::move( aStorage );
|
||||
mFile.setFileName( fileName );
|
||||
|
||||
// now get any properties
|
||||
@ -1258,9 +1266,22 @@ bool QgsProject::write( const QString &filename )
|
||||
bool QgsProject::write()
|
||||
{
|
||||
if ( QgsZipUtils::isZipFile( mFile.fileName() ) )
|
||||
{
|
||||
return zip( mFile.fileName() );
|
||||
}
|
||||
else
|
||||
return writeProjectFile( mFile.fileName() );
|
||||
{
|
||||
// write project file even if the auxiliary storage is not correctly
|
||||
// saved
|
||||
const bool asOk = saveAuxiliaryStorage();
|
||||
const bool writeOk = writeProjectFile( mFile.fileName() );
|
||||
|
||||
// errors raised during writing project file are more important
|
||||
if ( !asOk && writeOk )
|
||||
setError( tr( "Unable to save auxiliary storage" ) );
|
||||
|
||||
return asOk && writeOk;
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsProject::writeProjectFile( const QString &filename )
|
||||
@ -2132,6 +2153,18 @@ bool QgsProject::unzip( const QString &filename )
|
||||
return false;
|
||||
}
|
||||
|
||||
// load auxiliary storage
|
||||
if ( !archive->auxiliaryStorageFile().isEmpty() )
|
||||
{
|
||||
// database file is already a copy as it's been unzipped. So we don't open
|
||||
// auxiliary storage in copy mode in this case
|
||||
mAuxiliaryStorage.reset( new QgsAuxiliaryStorage( archive->auxiliaryStorageFile(), false ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
mAuxiliaryStorage.reset( new QgsAuxiliaryStorage( *this ) );
|
||||
}
|
||||
|
||||
// read the project file
|
||||
if ( ! readProjectFile( archive->projectFile() ) )
|
||||
{
|
||||
@ -2170,8 +2203,19 @@ bool QgsProject::zip( const QString &filename )
|
||||
return false;
|
||||
}
|
||||
|
||||
// save auxiliary storage
|
||||
const QFileInfo info( qgsFile );
|
||||
const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + "." + QgsAuxiliaryStorage::extension();
|
||||
|
||||
if ( ! saveAuxiliaryStorage( asFileName ) )
|
||||
{
|
||||
setError( tr( "Unable to save auxiliary storage" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// create the archive
|
||||
archive->addFile( qgsFile.fileName() );
|
||||
archive->addFile( asFileName );
|
||||
|
||||
// zip
|
||||
if ( !archive->zip( filename ) )
|
||||
@ -2199,6 +2243,22 @@ QList<QgsMapLayer *> QgsProject::addMapLayers(
|
||||
if ( addToLegend )
|
||||
emit legendLayersAdded( myResultList );
|
||||
}
|
||||
|
||||
if ( mAuxiliaryStorage )
|
||||
{
|
||||
for ( QgsMapLayer *mlayer : myResultList )
|
||||
{
|
||||
if ( mlayer->type() != QgsMapLayer::VectorLayer )
|
||||
continue;
|
||||
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mlayer );
|
||||
if ( vl )
|
||||
{
|
||||
vl->loadAuxiliaryLayer( *mAuxiliaryStorage.get() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return myResultList;
|
||||
}
|
||||
|
||||
@ -2293,3 +2353,37 @@ void QgsProject::setTrustLayerMetadata( bool trust )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsProject::saveAuxiliaryStorage( const QString &filename )
|
||||
{
|
||||
for ( QgsMapLayer *l : mapLayers().values() )
|
||||
{
|
||||
if ( l->type() != QgsMapLayer::VectorLayer )
|
||||
continue;
|
||||
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( l );
|
||||
if ( vl && vl->auxiliaryLayer() )
|
||||
{
|
||||
vl->auxiliaryLayer()->save();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !filename.isEmpty() )
|
||||
{
|
||||
return mAuxiliaryStorage->saveAs( filename );
|
||||
}
|
||||
else
|
||||
{
|
||||
return mAuxiliaryStorage->saveAs( *this );
|
||||
}
|
||||
}
|
||||
|
||||
const QgsAuxiliaryStorage *QgsProject::auxiliaryStorage() const
|
||||
{
|
||||
return mAuxiliaryStorage.get();
|
||||
}
|
||||
|
||||
QgsAuxiliaryStorage *QgsProject::auxiliaryStorage()
|
||||
{
|
||||
return mAuxiliaryStorage.get();
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ class QgsAnnotationManager;
|
||||
class QgsLayoutManager;
|
||||
class QgsLayerTree;
|
||||
class QgsLabelingEngineSettings;
|
||||
class QgsAuxiliaryStorage;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
@ -809,6 +810,20 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
*/
|
||||
bool trustLayerMetadata() const { return mTrustLayerMetadata; }
|
||||
|
||||
/**
|
||||
* Returns the current const auxiliary storage.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
const QgsAuxiliaryStorage *auxiliaryStorage() const SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Returns the current auxiliary storage.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsAuxiliaryStorage *auxiliaryStorage();
|
||||
|
||||
signals:
|
||||
//! emitted when project is being read
|
||||
void readProject( const QDomDocument & );
|
||||
@ -1101,6 +1116,9 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
//! Zip project
|
||||
bool zip( const QString &filename );
|
||||
|
||||
//! Save auxiliary storage to database
|
||||
bool saveAuxiliaryStorage( const QString &filename = QString() );
|
||||
|
||||
std::unique_ptr< QgsMapLayerStore > mLayerStore;
|
||||
|
||||
QString mErrorMessage;
|
||||
@ -1136,6 +1154,8 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
|
||||
std::unique_ptr<QgsProjectArchive> mArchive;
|
||||
|
||||
std::unique_ptr<QgsAuxiliaryStorage> mAuxiliaryStorage;
|
||||
|
||||
QFile mFile; // current physical project file
|
||||
mutable QgsProjectPropertyKey mProperties; // property hierarchy, TODO: this shouldn't be mutable
|
||||
QString mTitle; // project title
|
||||
|
@ -21,10 +21,12 @@
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgscolorramp.h"
|
||||
|
||||
QgsPropertyDefinition::QgsPropertyDefinition( const QString &name, const QString &description, QgsPropertyDefinition::StandardPropertyTemplate type )
|
||||
QgsPropertyDefinition::QgsPropertyDefinition( const QString &name, const QString &description, QgsPropertyDefinition::StandardPropertyTemplate type, const QString &origin, const QString &comment )
|
||||
: mName( name )
|
||||
, mDescription( description )
|
||||
, mStandardType( type )
|
||||
, mOrigin( origin )
|
||||
, mComment( comment )
|
||||
{
|
||||
switch ( mStandardType )
|
||||
{
|
||||
@ -169,11 +171,13 @@ QgsPropertyDefinition::QgsPropertyDefinition( const QString &name, const QString
|
||||
}
|
||||
}
|
||||
|
||||
QgsPropertyDefinition::QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText )
|
||||
QgsPropertyDefinition::QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText, const QString &origin, const QString &comment )
|
||||
: mName( name )
|
||||
, mDescription( description )
|
||||
, mTypes( dataType )
|
||||
, mHelpText( helpText )
|
||||
, mOrigin( origin )
|
||||
, mComment( comment )
|
||||
{}
|
||||
|
||||
bool QgsPropertyDefinition::supportsAssistant() const
|
||||
@ -622,7 +626,7 @@ bool QgsProperty::valueAsBool( const QgsExpressionContext &context, bool default
|
||||
bool valOk = false;
|
||||
QVariant val = value( context, defaultValue, &valOk );
|
||||
|
||||
if ( !valOk || !val.isValid() )
|
||||
if ( !valOk || !val.isValid() || val.isNull() )
|
||||
return defaultValue;
|
||||
|
||||
if ( ok )
|
||||
|
@ -115,8 +115,10 @@ class CORE_EXPORT QgsPropertyDefinition
|
||||
* \param name is used internally and should be a unique, alphanumeric string.
|
||||
* \param description can be any localised string describing what the property is used for.
|
||||
* \param type one of the predefined standard property template
|
||||
* \param origin The origin of the property
|
||||
* \param comment A free comment for the property
|
||||
*/
|
||||
QgsPropertyDefinition( const QString &name, const QString &description, StandardPropertyTemplate type );
|
||||
QgsPropertyDefinition( const QString &name, const QString &description, StandardPropertyTemplate type, const QString &origin = QString(), const QString &comment = QString() );
|
||||
|
||||
/**
|
||||
* Constructor for custom QgsPropertyDefinitions.
|
||||
@ -125,24 +127,60 @@ class CORE_EXPORT QgsPropertyDefinition
|
||||
* \param description can be any localised string describing what the property is used for.
|
||||
* \param helpText parameter should specify a descriptive string for users outlining the types
|
||||
* of value acceptable by the property (eg 'dashed' or 'solid' for a line style property).
|
||||
* \param origin The origin of the property
|
||||
* \param comment A free comment for the property
|
||||
*/
|
||||
QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText );
|
||||
QgsPropertyDefinition( const QString &name, DataType dataType, const QString &description, const QString &helpText, const QString &origin = QString(), const QString &comment = QString() );
|
||||
|
||||
/**
|
||||
* Returns the name of the property. This is used internally and should be a unique, alphanumeric string.
|
||||
*/
|
||||
QString name() const { return mName; }
|
||||
|
||||
/**
|
||||
* Sets the name of the property
|
||||
*/
|
||||
void setName( const QString &name ) { mName = name; }
|
||||
|
||||
/**
|
||||
* Returns the origin of the property. For example, a PAL property has an
|
||||
* origin set to "labeling" while a diagram property has an origin set to
|
||||
* "diagram".
|
||||
*/
|
||||
QString origin() const { return mOrigin; }
|
||||
|
||||
/**
|
||||
* Sets the origin of the property. For example, a PAL property has an
|
||||
* origin set to "labeling" while a diagram property has an origin set to
|
||||
* "diagram".
|
||||
*/
|
||||
void setOrigin( const QString &origin ) { mOrigin = origin; }
|
||||
|
||||
/**
|
||||
* Descriptive name of the property.
|
||||
*/
|
||||
QString description() const { return mDescription; }
|
||||
|
||||
/**
|
||||
* Returns the comment of the property
|
||||
*/
|
||||
QString comment() const { return mComment; }
|
||||
|
||||
/**
|
||||
* Sets comment of the property
|
||||
*/
|
||||
void setComment( const QString &comment ) { mComment = comment; }
|
||||
|
||||
/**
|
||||
* Helper text for using the property, including a description of the valid values for the property.
|
||||
*/
|
||||
QString helpText() const { return mHelpText; }
|
||||
|
||||
/**
|
||||
* Sets the data type
|
||||
*/
|
||||
void setDataType( DataType type ) { mTypes = type; }
|
||||
|
||||
/**
|
||||
* Returns the allowable field/value data type for the property.
|
||||
*/
|
||||
@ -167,6 +205,8 @@ class CORE_EXPORT QgsPropertyDefinition
|
||||
DataType mTypes = DataTypeString;
|
||||
QString mHelpText;
|
||||
StandardPropertyTemplate mStandardType = Custom;
|
||||
QString mOrigin;
|
||||
QString mComment;
|
||||
|
||||
static QString trString();
|
||||
};
|
||||
|
@ -177,6 +177,20 @@ const QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::findRuleByKey( con
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::findRuleByKey( const QString &key )
|
||||
{
|
||||
if ( key == mRuleKey )
|
||||
return this;
|
||||
|
||||
for ( Rule *rule : mChildren )
|
||||
{
|
||||
Rule *r = rule->findRuleByKey( key );
|
||||
if ( r )
|
||||
return r;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::clone() const
|
||||
{
|
||||
QgsPalLayerSettings *s = mSettings ? new QgsPalLayerSettings( *mSettings ) : nullptr;
|
||||
@ -451,3 +465,13 @@ bool QgsRuleBasedLabeling::requiresAdvancedEffects() const
|
||||
{
|
||||
return mRootRule->requiresAdvancedEffects();
|
||||
}
|
||||
|
||||
void QgsRuleBasedLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
|
||||
{
|
||||
if ( settings )
|
||||
{
|
||||
Rule *rule = mRootRule->findRuleByKey( providerId );
|
||||
if ( rule && rule->settings() )
|
||||
return rule->setSettings( settings );
|
||||
}
|
||||
}
|
||||
|
@ -231,6 +231,17 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
|
||||
//! Try to find a rule given its unique key
|
||||
const QgsRuleBasedLabeling::Rule *findRuleByKey( const QString &key ) const;
|
||||
|
||||
/**
|
||||
* Find a labeling rule thanks to its key.
|
||||
*
|
||||
* \param key The key of the rule to find
|
||||
*
|
||||
* \returns The rule or a nullptr if not found
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsRuleBasedLabeling::Rule *findRuleByKey( const QString &key ) SIP_SKIP;
|
||||
|
||||
//! clone this rule, return new instance
|
||||
QgsRuleBasedLabeling::Rule *clone() const SIP_FACTORY;
|
||||
|
||||
@ -350,6 +361,16 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
|
||||
virtual QgsVectorLayerLabelProvider *provider( QgsVectorLayer *layer ) const override SIP_SKIP;
|
||||
virtual QStringList subProviders() const override;
|
||||
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const override;
|
||||
|
||||
/**
|
||||
* Set pal settings for a specific provider (takes ownership).
|
||||
*
|
||||
* \param settings Pal layer settings
|
||||
* \param providerId The id of the provider
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual void setSettings( QgsPalLayerSettings *settings SIP_TRANSFER, const QString &providerId = QString() ) override;
|
||||
bool requiresAdvancedEffects() const override;
|
||||
|
||||
protected:
|
||||
|
@ -88,6 +88,7 @@
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgstaskmanager.h"
|
||||
#include "qgstransaction.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include "diagram/qgsdiagram.h"
|
||||
|
||||
@ -139,6 +140,8 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
|
||||
bool readExtentFromXml )
|
||||
: QgsMapLayer( VectorLayer, baseName, vectorLayerPath )
|
||||
, mProviderKey( providerKey )
|
||||
, mAuxiliaryLayer( nullptr )
|
||||
, mAuxiliaryLayerKey( QString() )
|
||||
, mReadExtentFromXml( readExtentFromXml )
|
||||
{
|
||||
mActions = new QgsActionManager( this );
|
||||
@ -198,7 +201,10 @@ QgsVectorLayer *QgsVectorLayer::clone() const
|
||||
QList<QgsVectorLayerJoinInfo> joins = vectorJoins();
|
||||
Q_FOREACH ( const QgsVectorLayerJoinInfo &join, joins )
|
||||
{
|
||||
layer->addJoin( join );
|
||||
// do not copy join information for auxiliary layer
|
||||
if ( !auxiliaryLayer()
|
||||
|| ( auxiliaryLayer() && auxiliaryLayer()->id() != join.joinLayerId() ) )
|
||||
layer->addJoin( join );
|
||||
}
|
||||
|
||||
layer->setProviderEncoding( dataProvider()->encoding() );
|
||||
@ -261,6 +267,9 @@ QgsVectorLayer *QgsVectorLayer::clone() const
|
||||
|
||||
layer->setEditFormConfig( editFormConfig() );
|
||||
|
||||
if ( auxiliaryLayer() )
|
||||
layer->setAuxiliaryLayer( auxiliaryLayer()->clone( layer ) );
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
@ -1447,6 +1456,14 @@ bool QgsVectorLayer::readXml( const QDomNode &layer_node, const QgsReadWriteCont
|
||||
}
|
||||
}
|
||||
|
||||
// auxiliary layer
|
||||
const QDomNode asNode = layer_node.namedItem( QStringLiteral( "auxiliaryLayer" ) );
|
||||
const QDomElement asElem = asNode.toElement();
|
||||
if ( !asElem.isNull() )
|
||||
{
|
||||
mAuxiliaryLayerKey = asElem.attribute( QStringLiteral( "key" ) );
|
||||
}
|
||||
|
||||
return mValid; // should be true if read successfully
|
||||
|
||||
} // void QgsVectorLayer::readXml
|
||||
@ -1667,6 +1684,15 @@ bool QgsVectorLayer::writeXml( QDomNode &layer_node,
|
||||
|
||||
writeStyleManager( layer_node, document );
|
||||
|
||||
// auxiliary layer
|
||||
QDomElement asElem = document.createElement( QStringLiteral( "auxiliaryLayer" ) );
|
||||
if ( mAuxiliaryLayer )
|
||||
{
|
||||
const QString pkField = mAuxiliaryLayer->joinInfo().targetFieldName();
|
||||
asElem.setAttribute( QStringLiteral( "key" ), pkField );
|
||||
}
|
||||
layer_node.appendChild( asElem );
|
||||
|
||||
// renderer specific settings
|
||||
QString errorMsg;
|
||||
return writeSymbology( layer_node, document, errorMsg, context );
|
||||
@ -2813,6 +2839,26 @@ bool QgsVectorLayer::isModified() const
|
||||
return mEditBuffer && mEditBuffer->isModified();
|
||||
}
|
||||
|
||||
|
||||
bool QgsVectorLayer::isAuxiliaryField( int index, int &srcIndex ) const
|
||||
{
|
||||
bool auxiliaryField = false;
|
||||
srcIndex = -1;
|
||||
|
||||
if ( !auxiliaryLayer() )
|
||||
return auxiliaryField;
|
||||
|
||||
if ( index >= 0 && fields().fieldOrigin( index ) == QgsFields::OriginJoin )
|
||||
{
|
||||
const QgsVectorLayerJoinInfo *info = mJoinBuffer->joinForFieldIndex( index, fields(), srcIndex );
|
||||
|
||||
if ( info && info->joinLayerId() == auxiliaryLayer()->id() )
|
||||
auxiliaryField = true;
|
||||
}
|
||||
|
||||
return auxiliaryField;
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setRenderer( QgsFeatureRenderer *r )
|
||||
{
|
||||
if ( !isSpatial() )
|
||||
@ -4223,6 +4269,66 @@ QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag
|
||||
return loadNamedStyle( theURI, resultFlag, false );
|
||||
}
|
||||
|
||||
bool QgsVectorLayer::loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage, const QString &key )
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
QString joinKey = mAuxiliaryLayerKey;
|
||||
if ( !key.isEmpty() )
|
||||
joinKey = key;
|
||||
|
||||
if ( storage.isValid() && !joinKey.isEmpty() )
|
||||
{
|
||||
QgsAuxiliaryLayer *alayer = nullptr;
|
||||
|
||||
int idx = fields().lookupField( joinKey );
|
||||
|
||||
if ( idx >= 0 )
|
||||
{
|
||||
alayer = storage.createAuxiliaryLayer( fields().field( idx ), this );
|
||||
|
||||
if ( alayer )
|
||||
{
|
||||
setAuxiliaryLayer( alayer );
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setAuxiliaryLayer( QgsAuxiliaryLayer *alayer )
|
||||
{
|
||||
mAuxiliaryLayerKey.clear();
|
||||
|
||||
if ( mAuxiliaryLayer )
|
||||
removeJoin( mAuxiliaryLayer->id() );
|
||||
|
||||
if ( alayer )
|
||||
{
|
||||
addJoin( alayer->joinInfo() );
|
||||
|
||||
if ( !alayer->isEditable() )
|
||||
alayer->startEditing();
|
||||
|
||||
mAuxiliaryLayerKey = alayer->joinInfo().targetFieldName();
|
||||
}
|
||||
|
||||
mAuxiliaryLayer.reset( alayer );
|
||||
updateFields();
|
||||
}
|
||||
|
||||
const QgsAuxiliaryLayer *QgsVectorLayer::auxiliaryLayer() const
|
||||
{
|
||||
return mAuxiliaryLayer.get();
|
||||
}
|
||||
|
||||
QgsAuxiliaryLayer *QgsVectorLayer::auxiliaryLayer()
|
||||
{
|
||||
return mAuxiliaryLayer.get();
|
||||
}
|
||||
|
||||
QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag, bool loadFromLocalDB )
|
||||
{
|
||||
QgsDataSourceUri dsUri( theURI );
|
||||
|
@ -70,6 +70,8 @@ class QgsVectorLayerFeatureCounter;
|
||||
class QgsAbstractVectorLayerLabeling;
|
||||
class QgsPoint;
|
||||
class QgsFeedback;
|
||||
class QgsAuxiliaryStorage;
|
||||
class QgsAuxiliaryLayer;
|
||||
|
||||
typedef QList<int> QgsAttributeList;
|
||||
typedef QSet<int> QgsAttributeIds;
|
||||
@ -783,6 +785,46 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
*/
|
||||
virtual QString loadNamedStyle( const QString &theURI, bool &resultFlag SIP_OUT ) override;
|
||||
|
||||
/**
|
||||
* Loads the auxiliary layer for this vector layer. If there's no
|
||||
* corresponding table in the database, then nothing happens and false is
|
||||
* returned. The key is optional because if this layer has been read from
|
||||
* a XML document, then the key read in this document is used by default.
|
||||
*
|
||||
* \param storage The auxiliary storage where to look for the table
|
||||
* \param key The key to use for joining.
|
||||
*
|
||||
* \returns true if the auxiliary layer is well loaded, false otherwise
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage, const QString &key = QString() );
|
||||
|
||||
/**
|
||||
* Sets the current auxiliary layer. The auxiliary layer is automatically
|
||||
* put in editable mode and fields are updated. Moreover, a join is created
|
||||
* between the current layer and the auxiliary layer. Ownership is
|
||||
* transferred.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*
|
||||
*/
|
||||
void setAuxiliaryLayer( QgsAuxiliaryLayer *layer SIP_TRANSFER = nullptr );
|
||||
|
||||
/**
|
||||
* Returns the current auxiliary layer.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsAuxiliaryLayer *auxiliaryLayer();
|
||||
|
||||
/**
|
||||
* Returns the current const auxiliary layer.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
const QgsAuxiliaryLayer *auxiliaryLayer() const SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Read the symbology for the current layer from the Dom node supplied.
|
||||
* \param layerNode node that will contain the symbology definition for this layer.
|
||||
@ -1093,11 +1135,17 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
*/
|
||||
int addTopologicalPoints( const QgsPointXY &p );
|
||||
|
||||
/**
|
||||
* Access to const labeling configuration. May be null if labeling is not used.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
const QgsAbstractVectorLayerLabeling *labeling() const SIP_SKIP { return mLabeling; }
|
||||
|
||||
/**
|
||||
* Access to labeling configuration. May be null if labeling is not used.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
const QgsAbstractVectorLayerLabeling *labeling() const { return mLabeling; }
|
||||
QgsAbstractVectorLayerLabeling *labeling() { return mLabeling; }
|
||||
|
||||
/**
|
||||
* Set labeling configuration. Takes ownership of the object.
|
||||
@ -1114,6 +1162,14 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
//! Returns true if the provider has been modified since the last commit
|
||||
virtual bool isModified() const;
|
||||
|
||||
/**
|
||||
* Returns true if the field comes from the auxiliary layer,
|
||||
* false otherwise.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool isAuxiliaryField( int index, int &srcIndex ) const;
|
||||
|
||||
//! Synchronises with changes in the datasource
|
||||
virtual void reload() override;
|
||||
|
||||
@ -1262,7 +1318,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
void setExcludeAttributesWfs( const QSet<QString> &att ) { mExcludeAttributesWFS = att; }
|
||||
|
||||
//! Delete an attribute field (but does not commit it)
|
||||
bool deleteAttribute( int attr );
|
||||
virtual bool deleteAttribute( int attr );
|
||||
|
||||
/**
|
||||
* Deletes a list of attribute fields (but does not commit it)
|
||||
@ -2145,6 +2201,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
mutable bool mValidExtent = false;
|
||||
mutable bool mLazyExtent = true;
|
||||
|
||||
//! Auxiliary layer
|
||||
std::unique_ptr<QgsAuxiliaryLayer> mAuxiliaryLayer;
|
||||
|
||||
//! Key to use to join auxiliary layer
|
||||
QString mAuxiliaryLayerKey;
|
||||
|
||||
// Features in renderer classes counted
|
||||
bool mSymbolFeatureCounted = false;
|
||||
|
||||
|
@ -944,10 +944,12 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg
|
||||
|
||||
// maybe user requested just a subset of layer's attributes
|
||||
// so we do not have to cache everything
|
||||
bool hasSubset = joinInfo->joinFieldNamesSubset();
|
||||
QVector<int> subsetIndices;
|
||||
if ( hasSubset )
|
||||
subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, *joinInfo->joinFieldNamesSubset() );
|
||||
if ( joinInfo->hasSubset() )
|
||||
{
|
||||
const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( *joinInfo );
|
||||
subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, subsetNames );
|
||||
}
|
||||
|
||||
// select (no geometry)
|
||||
QgsFeatureRequest request;
|
||||
@ -963,7 +965,7 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg
|
||||
{
|
||||
int index = indexOffset;
|
||||
QgsAttributes attr = fet.attributes();
|
||||
if ( hasSubset )
|
||||
if ( joinInfo->hasSubset() )
|
||||
{
|
||||
for ( int i = 0; i < subsetIndices.count(); ++i )
|
||||
f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) );
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
@ -137,11 +138,11 @@ void QgsVectorLayerJoinBuffer::cacheJoinLayer( QgsVectorLayerJoinInfo &joinInfo
|
||||
request.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
// maybe user requested just a subset of layer's attributes
|
||||
// so we do not have to cache everything
|
||||
bool hasSubset = joinInfo.joinFieldNamesSubset();
|
||||
QVector<int> subsetIndices;
|
||||
if ( hasSubset )
|
||||
if ( joinInfo.hasSubset() )
|
||||
{
|
||||
subsetIndices = joinSubsetIndices( cacheLayer, *joinInfo.joinFieldNamesSubset() );
|
||||
const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( joinInfo );
|
||||
subsetIndices = joinSubsetIndices( cacheLayer, subsetNames );
|
||||
|
||||
// we need just subset of attributes - but make sure to include join field name
|
||||
QgsAttributeList cacheLayerAttrs = subsetIndices.toList();
|
||||
@ -156,7 +157,7 @@ void QgsVectorLayerJoinBuffer::cacheJoinLayer( QgsVectorLayerJoinInfo &joinInfo
|
||||
{
|
||||
QgsAttributes attrs = f.attributes();
|
||||
QString key = attrs.at( joinFieldIndex ).toString();
|
||||
if ( hasSubset )
|
||||
if ( joinInfo.hasSubset() )
|
||||
{
|
||||
QgsAttributes subsetAttrs( subsetIndices.count() );
|
||||
for ( int i = 0; i < subsetIndices.count(); ++i )
|
||||
@ -213,11 +214,10 @@ void QgsVectorLayerJoinBuffer::updateFields( QgsFields &fields )
|
||||
QString joinFieldName = joinIt->joinFieldName();
|
||||
|
||||
QSet<QString> subset;
|
||||
bool hasSubset = false;
|
||||
if ( joinIt->joinFieldNamesSubset() )
|
||||
if ( joinIt->hasSubset() )
|
||||
{
|
||||
hasSubset = true;
|
||||
subset = QSet<QString>::fromList( *joinIt->joinFieldNamesSubset() );
|
||||
const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( *joinIt );
|
||||
subset = QSet<QString>::fromList( subsetNames );
|
||||
}
|
||||
|
||||
if ( joinIt->prefix().isNull() )
|
||||
@ -232,12 +232,12 @@ void QgsVectorLayerJoinBuffer::updateFields( QgsFields &fields )
|
||||
for ( int idx = 0; idx < joinFields.count(); ++idx )
|
||||
{
|
||||
// if using just a subset of fields, filter some of them out
|
||||
if ( hasSubset && !subset.contains( joinFields.at( idx ).name() ) )
|
||||
if ( joinIt->hasSubset() && !subset.contains( joinFields.at( idx ).name() ) )
|
||||
continue;
|
||||
|
||||
//skip the join field to avoid double field names (fields often have the same name)
|
||||
// when using subset of field, use all the selected fields
|
||||
if ( hasSubset || joinFields.at( idx ).name() != joinFieldName )
|
||||
if ( joinIt->hasSubset() || joinFields.at( idx ).name() != joinFieldName )
|
||||
{
|
||||
QgsField f = joinFields.at( idx );
|
||||
f.setName( prefix + f.name() );
|
||||
@ -266,6 +266,9 @@ void QgsVectorLayerJoinBuffer::writeXml( QDomNode &layer_node, QDomDocument &doc
|
||||
QList< QgsVectorLayerJoinInfo >::const_iterator joinIt = mVectorJoins.constBegin();
|
||||
for ( ; joinIt != mVectorJoins.constEnd(); ++joinIt )
|
||||
{
|
||||
if ( isAuxiliaryJoin( *joinIt ) )
|
||||
continue;
|
||||
|
||||
QDomElement joinElem = document.createElement( QStringLiteral( "join" ) );
|
||||
|
||||
joinElem.setAttribute( QStringLiteral( "targetFieldName" ), joinIt->targetFieldName() );
|
||||
@ -279,10 +282,12 @@ void QgsVectorLayerJoinBuffer::writeXml( QDomNode &layer_node, QDomDocument &doc
|
||||
joinElem.setAttribute( QStringLiteral( "upsertOnEdit" ), joinIt->hasUpsertOnEdit() );
|
||||
joinElem.setAttribute( QStringLiteral( "cascadedDelete" ), joinIt->hasCascadedDelete() );
|
||||
|
||||
if ( joinIt->joinFieldNamesSubset() )
|
||||
if ( joinIt->hasSubset() )
|
||||
{
|
||||
QDomElement subsetElem = document.createElement( QStringLiteral( "joinFieldsSubset" ) );
|
||||
Q_FOREACH ( const QString &fieldName, *joinIt->joinFieldNamesSubset() )
|
||||
const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( *joinIt );
|
||||
|
||||
Q_FOREACH ( const QString &fieldName, subsetNames )
|
||||
{
|
||||
QDomElement fieldElem = document.createElement( QStringLiteral( "field" ) );
|
||||
fieldElem.setAttribute( QStringLiteral( "name" ), fieldName );
|
||||
@ -552,10 +557,10 @@ bool QgsVectorLayerJoinBuffer::addFeatures( QgsFeatureList &features, QgsFeature
|
||||
|
||||
if ( existingFeature.isValid() )
|
||||
{
|
||||
const QStringList *subsetFields = info.joinFieldNamesSubset();
|
||||
if ( subsetFields )
|
||||
if ( info.hasSubset() )
|
||||
{
|
||||
Q_FOREACH ( const QString &field, *subsetFields )
|
||||
const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( info );
|
||||
Q_FOREACH ( const QString &field, subsetNames )
|
||||
{
|
||||
QVariant newValue = joinFeature.attribute( field );
|
||||
int fieldIndex = joinLayer->fields().indexOf( field );
|
||||
@ -655,3 +660,13 @@ bool QgsVectorLayerJoinBuffer::deleteFeatures( const QgsFeatureIds &fids ) const
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsVectorLayerJoinBuffer::isAuxiliaryJoin( const QgsVectorLayerJoinInfo &info ) const
|
||||
{
|
||||
const QgsAuxiliaryLayer *al = mLayer->auxiliaryLayer();
|
||||
|
||||
if ( al && al->id() == info.joinLayerId() )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -121,6 +121,17 @@ class CORE_EXPORT QgsVectorLayerJoinBuffer : public QObject, public QgsFeatureSi
|
||||
*/
|
||||
QgsFeature targetedFeatureOf( const QgsVectorLayerJoinInfo *info, const QgsFeature &feature ) const;
|
||||
|
||||
/**
|
||||
* Returns true if the join information is about auxiliary layer, false otherwise
|
||||
*
|
||||
* \param info The join information
|
||||
*
|
||||
* \returns true if the join information is about auxiliary layer, false otherwise
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool isAuxiliaryJoin( const QgsVectorLayerJoinInfo &info ) const;
|
||||
|
||||
/**
|
||||
* Create a copy of the join buffer
|
||||
* \since QGIS 2.6
|
||||
|
@ -68,3 +68,50 @@ QgsFeature QgsVectorLayerJoinInfo::extractJoinedFeature( const QgsFeature &featu
|
||||
|
||||
return joinFeature;
|
||||
}
|
||||
|
||||
QStringList QgsVectorLayerJoinInfo::joinFieldNamesSubset( const QgsVectorLayerJoinInfo &info, bool blacklisted )
|
||||
{
|
||||
QStringList fieldNames;
|
||||
|
||||
if ( blacklisted && !info.joinFieldNamesBlackList().isEmpty() )
|
||||
{
|
||||
QStringList *lst = info.joinFieldNamesSubset();
|
||||
if ( lst )
|
||||
{
|
||||
for ( const QString &s : qgsAsConst( *lst ) )
|
||||
{
|
||||
if ( !info.joinFieldNamesBlackList().contains( s ) )
|
||||
fieldNames.append( s );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( const QgsField &f : info.joinLayer()->fields() )
|
||||
{
|
||||
if ( !info.joinFieldNamesBlackList().contains( f.name() )
|
||||
&& f.name() != info.joinFieldName() )
|
||||
fieldNames.append( f.name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList *lst = info.joinFieldNamesSubset();
|
||||
if ( lst )
|
||||
{
|
||||
fieldNames = *lst;
|
||||
}
|
||||
}
|
||||
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
bool QgsVectorLayerJoinInfo::hasSubset( bool blacklisted ) const
|
||||
{
|
||||
bool subset = joinFieldNamesSubset();
|
||||
|
||||
if ( blacklisted )
|
||||
subset |= !joinFieldNamesBlackList().isEmpty();
|
||||
|
||||
return subset;
|
||||
}
|
||||
|
@ -141,6 +141,36 @@ class CORE_EXPORT QgsVectorLayerJoinInfo
|
||||
*/
|
||||
QgsFeature extractJoinedFeature( const QgsFeature &feature ) const;
|
||||
|
||||
/**
|
||||
* Sets a list of fields to ignore whatever happens.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void setJoinFieldNamesBlackList( const QStringList &blackList ) { mBlackList = blackList; }
|
||||
|
||||
/**
|
||||
* Returns the list of fields to ignore.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QStringList joinFieldNamesBlackList() const { return mBlackList; }
|
||||
|
||||
/**
|
||||
* Returns true if blacklisted fields is not empty or if a subset of names
|
||||
* has been set.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool hasSubset( bool blacklisted = true ) const;
|
||||
|
||||
/**
|
||||
* Returns the list of field names to use for joining considering
|
||||
* blacklisted fields and subset.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
static QStringList joinFieldNamesSubset( const QgsVectorLayerJoinInfo &info, bool blacklisted = true );
|
||||
|
||||
bool operator==( const QgsVectorLayerJoinInfo &other ) const
|
||||
{
|
||||
return mTargetFieldName == other.mTargetFieldName &&
|
||||
@ -197,6 +227,8 @@ class CORE_EXPORT QgsVectorLayerJoinInfo
|
||||
|
||||
bool mCascadedDelete = false;
|
||||
|
||||
QStringList mBlackList;
|
||||
|
||||
//! Cache for joined attributes to provide fast lookup (size is 0 if no memory caching)
|
||||
QHash< QString, QgsAttributes> cachedAttributes;
|
||||
|
||||
|
@ -546,3 +546,13 @@ void QgsVectorLayerSimpleLabeling::toSld( QDomNode &parent, const QgsStringMap &
|
||||
|
||||
|
||||
}
|
||||
|
||||
void QgsVectorLayerSimpleLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
|
||||
{
|
||||
Q_UNUSED( providerId );
|
||||
|
||||
if ( mSettings.get() == settings )
|
||||
return;
|
||||
|
||||
mSettings.reset( settings );
|
||||
}
|
||||
|
@ -68,6 +68,16 @@ class CORE_EXPORT QgsAbstractVectorLayerLabeling
|
||||
*/
|
||||
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const = 0;
|
||||
|
||||
/**
|
||||
* Set pal settings for a specific provider (takes ownership).
|
||||
*
|
||||
* \param settings Pal layer settings
|
||||
* \param providerId The id of the provider
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual void setSettings( QgsPalLayerSettings *settings SIP_TRANSFER, const QString &providerId = QString() ) = 0;
|
||||
|
||||
/**
|
||||
* Returns true if drawing labels requires advanced effects like composition
|
||||
* modes, which could prevent it being used as an isolated cached image
|
||||
@ -121,6 +131,17 @@ class CORE_EXPORT QgsVectorLayerSimpleLabeling : public QgsAbstractVectorLayerLa
|
||||
virtual QgsVectorLayerLabelProvider *provider( QgsVectorLayer *layer ) const override SIP_SKIP;
|
||||
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const override;
|
||||
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const override;
|
||||
|
||||
/**
|
||||
* Set pal settings (takes ownership).
|
||||
*
|
||||
* \param settings Pal layer settings
|
||||
* \param providerId Unused parameter
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual void setSettings( QgsPalLayerSettings *settings SIP_TRANSFER, const QString &providerId = QString() ) override;
|
||||
|
||||
bool requiresAdvancedEffects() const override;
|
||||
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const override;
|
||||
|
||||
|
@ -38,58 +38,60 @@ void QgsSymbolLayer::initPropertyDefinitions()
|
||||
if ( !sPropertyDefinitions.isEmpty() )
|
||||
return;
|
||||
|
||||
QString origin = QStringLiteral( "symbol" );
|
||||
|
||||
sPropertyDefinitions = QgsPropertiesDefinition
|
||||
{
|
||||
{ QgsSymbolLayer::PropertySize, QgsPropertyDefinition( "size", QObject::tr( "Symbol size" ), QgsPropertyDefinition::Size ) },
|
||||
{ QgsSymbolLayer::PropertyAngle, QgsPropertyDefinition( "angle", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation ) },
|
||||
{ QgsSymbolLayer::PropertyName, QgsPropertyDefinition( "name", QObject::tr( "Symbol name" ), QgsPropertyDefinition::String ) },
|
||||
{ QgsSymbolLayer::PropertyFillColor, QgsPropertyDefinition( "fillColor", QObject::tr( "Symbol fill color" ), QgsPropertyDefinition::ColorWithAlpha ) },
|
||||
{ QgsSymbolLayer::PropertyStrokeColor, QgsPropertyDefinition( "outlineColor", QObject::tr( "Symbol stroke color" ), QgsPropertyDefinition::ColorWithAlpha ) },
|
||||
{ QgsSymbolLayer::PropertyStrokeWidth, QgsPropertyDefinition( "outlineWidth", QObject::tr( "Symbol stroke width" ), QgsPropertyDefinition::StrokeWidth ) },
|
||||
{ QgsSymbolLayer::PropertyStrokeStyle, QgsPropertyDefinition( "outlineStyle", QObject::tr( "Symbol stroke style" ), QgsPropertyDefinition::LineStyle )},
|
||||
{ QgsSymbolLayer::PropertyOffset, QgsPropertyDefinition( "offset", QObject::tr( "Symbol offset" ), QgsPropertyDefinition::Offset )},
|
||||
{ QgsSymbolLayer::PropertyCharacter, QgsPropertyDefinition( "char", QObject::tr( "Marker character(s)" ), QgsPropertyDefinition::String )},
|
||||
{ QgsSymbolLayer::PropertyWidth, QgsPropertyDefinition( "width", QObject::tr( "Symbol width" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyHeight, QgsPropertyDefinition( "height", QObject::tr( "Symbol height" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyPreserveAspectRatio, QgsPropertyDefinition( "preserveAspectRatio", QObject::tr( "Preserve aspect ratio between width and height" ), QgsPropertyDefinition::Boolean )},
|
||||
{ QgsSymbolLayer::PropertyFillStyle, QgsPropertyDefinition( "fillStyle", QObject::tr( "Symbol fill style" ), QgsPropertyDefinition::FillStyle )},
|
||||
{ QgsSymbolLayer::PropertyJoinStyle, QgsPropertyDefinition( "joinStyle", QObject::tr( "Outline join style" ), QgsPropertyDefinition::PenJoinStyle )},
|
||||
{ QgsSymbolLayer::PropertySecondaryColor, QgsPropertyDefinition( "color2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha )},
|
||||
{ QgsSymbolLayer::PropertyLineAngle, QgsPropertyDefinition( "lineAngle", QObject::tr( "Angle for line fills" ), QgsPropertyDefinition::Rotation )},
|
||||
{ QgsSymbolLayer::PropertyGradientType, QgsPropertyDefinition( "gradientType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient type" ), QObject::tr( "string " ) + QLatin1String( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" ) )},
|
||||
{ QgsSymbolLayer::PropertyCoordinateMode, QgsPropertyDefinition( "gradientMode", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>feature</b>|<b>viewport</b>]" ) )},
|
||||
{ QgsSymbolLayer::PropertyGradientSpread, QgsPropertyDefinition( "gradientSpread", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient spread" ), QObject::tr( "string " ) + QLatin1String( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" ) )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference1X, QgsPropertyDefinition( "gradientRef1X", QObject::tr( "Reference point 1 (X)" ), QgsPropertyDefinition::Double0To1 )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference1Y, QgsPropertyDefinition( "gradientRef1Y", QObject::tr( "Reference point 1 (Y)" ), QgsPropertyDefinition::Double0To1 )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference2X, QgsPropertyDefinition( "gradientRef2X", QObject::tr( "Reference point 2 (X)" ), QgsPropertyDefinition::Double0To1 )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference2Y, QgsPropertyDefinition( "gradientRef2Y", QObject::tr( "Reference point 2 (Y)" ), QgsPropertyDefinition::Double0To1 )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference1IsCentroid, QgsPropertyDefinition( "gradientRef1Centroid", QObject::tr( "Reference point 1 follows feature centroid" ), QgsPropertyDefinition::Boolean )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference2IsCentroid, QgsPropertyDefinition( "gradientRef2Centroid", QObject::tr( "Reference point 2 follows feature centroid" ), QgsPropertyDefinition::Boolean )},
|
||||
{ QgsSymbolLayer::PropertyBlurRadius, QgsPropertyDefinition( "blurRadius", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Blur radius" ), QObject::tr( "Integer between 0 and 18" ) )},
|
||||
{ QgsSymbolLayer::PropertyLineDistance, QgsPropertyDefinition( "lineDistance", QObject::tr( "Distance between lines" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyShapeburstUseWholeShape, QgsPropertyDefinition( "shapeburstWholeShape", QObject::tr( "Shade whole shape" ), QgsPropertyDefinition::Boolean )},
|
||||
{ QgsSymbolLayer::PropertyShapeburstMaxDistance, QgsPropertyDefinition( "shapeburstMaxDist", QObject::tr( "Maximum distance for shapeburst fill" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyShapeburstIgnoreRings, QgsPropertyDefinition( "shapeburstIgnoreRings", QObject::tr( "Ignore rings in feature" ), QgsPropertyDefinition::Boolean )},
|
||||
{ QgsSymbolLayer::PropertyFile, QgsPropertyDefinition( "file", QObject::tr( "Symbol file path" ), QgsPropertyDefinition::String )},
|
||||
{ QgsSymbolLayer::PropertyDistanceX, QgsPropertyDefinition( "distanceX", QObject::tr( "Horizontal distance between markers" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyDistanceY, QgsPropertyDefinition( "distanceY", QObject::tr( "Vertical distance between markers" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyDisplacementX, QgsPropertyDefinition( "displacementX", QObject::tr( "Horizontal displacement between rows" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyDisplacementY, QgsPropertyDefinition( "displacementY", QObject::tr( "Vertical displacement between columns" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyOpacity, QgsPropertyDefinition( "alpha", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity )},
|
||||
{ QgsSymbolLayer::PropertyCustomDash, QgsPropertyDefinition( "customDash", QgsPropertyDefinition::DataTypeString, QObject::tr( "Custom dash pattern" ), QObject::tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" ) )},
|
||||
{ QgsSymbolLayer::PropertyCapStyle, QgsPropertyDefinition( "capStyle", QObject::tr( "Line cap style" ), QgsPropertyDefinition::CapStyle )},
|
||||
{ QgsSymbolLayer::PropertyPlacement, QgsPropertyDefinition( "placement", QgsPropertyDefinition::DataTypeString, QObject::tr( "Marker placement" ), QObject::tr( "string " ) + "[<b>interval</b>|<b>vertex</b>|<b>lastvertex</b>|<b>firstvertex</b>|<b>centerpoint</b>|<b>curvepoint</b>]" )},
|
||||
{ QgsSymbolLayer::PropertyInterval, QgsPropertyDefinition( "interval", QObject::tr( "Marker interval" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyOffsetAlongLine, QgsPropertyDefinition( "offsetAlongLine", QObject::tr( "Offset along line" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyHorizontalAnchor, QgsPropertyDefinition( "hAnchor", QObject::tr( "Horizontal anchor point" ), QgsPropertyDefinition::HorizontalAnchor )},
|
||||
{ QgsSymbolLayer::PropertyVerticalAnchor, QgsPropertyDefinition( "vAnchor", QObject::tr( "Vertical anchor point" ), QgsPropertyDefinition::VerticalAnchor )},
|
||||
{ QgsSymbolLayer::PropertyLayerEnabled, QgsPropertyDefinition( "enabled", QObject::tr( "Layer enabled" ), QgsPropertyDefinition::Boolean )},
|
||||
{ QgsSymbolLayer::PropertyArrowWidth, QgsPropertyDefinition( "arrowWidth", QObject::tr( "Arrow line width" ), QgsPropertyDefinition::StrokeWidth )},
|
||||
{ QgsSymbolLayer::PropertyArrowStartWidth, QgsPropertyDefinition( "arrowStartWidth", QObject::tr( "Arrow line start width" ), QgsPropertyDefinition::StrokeWidth )},
|
||||
{ QgsSymbolLayer::PropertyArrowHeadLength, QgsPropertyDefinition( "arrowHeadLength", QObject::tr( "Arrow head length" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyArrowHeadThickness, QgsPropertyDefinition( "arrowHeadThickness", QObject::tr( "Arrow head thickness" ), QgsPropertyDefinition::DoublePositive )},
|
||||
{ QgsSymbolLayer::PropertyArrowHeadType, QgsPropertyDefinition( "arrowHeadType", QObject::tr( "Arrow head type" ), QgsPropertyDefinition::IntegerPositive )},
|
||||
{ QgsSymbolLayer::PropertyArrowType, QgsPropertyDefinition( "arrowType", QObject::tr( "Arrow type" ), QgsPropertyDefinition::IntegerPositive )},
|
||||
{ QgsSymbolLayer::PropertySize, QgsPropertyDefinition( "size", QObject::tr( "Symbol size" ), QgsPropertyDefinition::Size, origin ) },
|
||||
{ QgsSymbolLayer::PropertyAngle, QgsPropertyDefinition( "angle", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation, origin ) },
|
||||
{ QgsSymbolLayer::PropertyName, QgsPropertyDefinition( "name", QObject::tr( "Symbol name" ), QgsPropertyDefinition::String, origin ) },
|
||||
{ QgsSymbolLayer::PropertyFillColor, QgsPropertyDefinition( "fillColor", QObject::tr( "Symbol fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
|
||||
{ QgsSymbolLayer::PropertyStrokeColor, QgsPropertyDefinition( "outlineColor", QObject::tr( "Symbol stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
|
||||
{ QgsSymbolLayer::PropertyStrokeWidth, QgsPropertyDefinition( "outlineWidth", QObject::tr( "Symbol stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
|
||||
{ QgsSymbolLayer::PropertyStrokeStyle, QgsPropertyDefinition( "outlineStyle", QObject::tr( "Symbol stroke style" ), QgsPropertyDefinition::LineStyle, origin )},
|
||||
{ QgsSymbolLayer::PropertyOffset, QgsPropertyDefinition( "offset", QObject::tr( "Symbol offset" ), QgsPropertyDefinition::Offset, origin )},
|
||||
{ QgsSymbolLayer::PropertyCharacter, QgsPropertyDefinition( "char", QObject::tr( "Marker character(s)" ), QgsPropertyDefinition::String, origin )},
|
||||
{ QgsSymbolLayer::PropertyWidth, QgsPropertyDefinition( "width", QObject::tr( "Symbol width" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyHeight, QgsPropertyDefinition( "height", QObject::tr( "Symbol height" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyPreserveAspectRatio, QgsPropertyDefinition( "preserveAspectRatio", QObject::tr( "Preserve aspect ratio between width and height" ), QgsPropertyDefinition::Boolean, origin )},
|
||||
{ QgsSymbolLayer::PropertyFillStyle, QgsPropertyDefinition( "fillStyle", QObject::tr( "Symbol fill style" ), QgsPropertyDefinition::FillStyle, origin )},
|
||||
{ QgsSymbolLayer::PropertyJoinStyle, QgsPropertyDefinition( "joinStyle", QObject::tr( "Outline join style" ), QgsPropertyDefinition::PenJoinStyle, origin )},
|
||||
{ QgsSymbolLayer::PropertySecondaryColor, QgsPropertyDefinition( "color2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin )},
|
||||
{ QgsSymbolLayer::PropertyLineAngle, QgsPropertyDefinition( "lineAngle", QObject::tr( "Angle for line fills" ), QgsPropertyDefinition::Rotation, origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientType, QgsPropertyDefinition( "gradientType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient type" ), QObject::tr( "string " ) + QLatin1String( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" ), origin )},
|
||||
{ QgsSymbolLayer::PropertyCoordinateMode, QgsPropertyDefinition( "gradientMode", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>feature</b>|<b>viewport</b>]" ), origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientSpread, QgsPropertyDefinition( "gradientSpread", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient spread" ), QObject::tr( "string " ) + QLatin1String( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" ), origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference1X, QgsPropertyDefinition( "gradientRef1X", QObject::tr( "Reference point 1 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference1Y, QgsPropertyDefinition( "gradientRef1Y", QObject::tr( "Reference point 1 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference2X, QgsPropertyDefinition( "gradientRef2X", QObject::tr( "Reference point 2 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference2Y, QgsPropertyDefinition( "gradientRef2Y", QObject::tr( "Reference point 2 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference1IsCentroid, QgsPropertyDefinition( "gradientRef1Centroid", QObject::tr( "Reference point 1 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
|
||||
{ QgsSymbolLayer::PropertyGradientReference2IsCentroid, QgsPropertyDefinition( "gradientRef2Centroid", QObject::tr( "Reference point 2 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
|
||||
{ QgsSymbolLayer::PropertyBlurRadius, QgsPropertyDefinition( "blurRadius", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Blur radius" ), QObject::tr( "Integer between 0 and 18" ), origin )},
|
||||
{ QgsSymbolLayer::PropertyLineDistance, QgsPropertyDefinition( "lineDistance", QObject::tr( "Distance between lines" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyShapeburstUseWholeShape, QgsPropertyDefinition( "shapeburstWholeShape", QObject::tr( "Shade whole shape" ), QgsPropertyDefinition::Boolean, origin )},
|
||||
{ QgsSymbolLayer::PropertyShapeburstMaxDistance, QgsPropertyDefinition( "shapeburstMaxDist", QObject::tr( "Maximum distance for shapeburst fill" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyShapeburstIgnoreRings, QgsPropertyDefinition( "shapeburstIgnoreRings", QObject::tr( "Ignore rings in feature" ), QgsPropertyDefinition::Boolean, origin )},
|
||||
{ QgsSymbolLayer::PropertyFile, QgsPropertyDefinition( "file", QObject::tr( "Symbol file path" ), QgsPropertyDefinition::String, origin )},
|
||||
{ QgsSymbolLayer::PropertyDistanceX, QgsPropertyDefinition( "distanceX", QObject::tr( "Horizontal distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyDistanceY, QgsPropertyDefinition( "distanceY", QObject::tr( "Vertical distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyDisplacementX, QgsPropertyDefinition( "displacementX", QObject::tr( "Horizontal displacement between rows" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyDisplacementY, QgsPropertyDefinition( "displacementY", QObject::tr( "Vertical displacement between columns" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyOpacity, QgsPropertyDefinition( "alpha", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity, origin )},
|
||||
{ QgsSymbolLayer::PropertyCustomDash, QgsPropertyDefinition( "customDash", QgsPropertyDefinition::DataTypeString, QObject::tr( "Custom dash pattern" ), QObject::tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" ), origin )},
|
||||
{ QgsSymbolLayer::PropertyCapStyle, QgsPropertyDefinition( "capStyle", QObject::tr( "Line cap style" ), QgsPropertyDefinition::CapStyle, origin )},
|
||||
{ QgsSymbolLayer::PropertyPlacement, QgsPropertyDefinition( "placement", QgsPropertyDefinition::DataTypeString, QObject::tr( "Marker placement" ), QObject::tr( "string " ) + "[<b>interval</b>|<b>vertex</b>|<b>lastvertex</b>|<b>firstvertex</b>|<b>centerpoint</b>|<b>curvepoint</b>]", origin )},
|
||||
{ QgsSymbolLayer::PropertyInterval, QgsPropertyDefinition( "interval", QObject::tr( "Marker interval" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyOffsetAlongLine, QgsPropertyDefinition( "offsetAlongLine", QObject::tr( "Offset along line" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyHorizontalAnchor, QgsPropertyDefinition( "hAnchor", QObject::tr( "Horizontal anchor point" ), QgsPropertyDefinition::HorizontalAnchor, origin )},
|
||||
{ QgsSymbolLayer::PropertyVerticalAnchor, QgsPropertyDefinition( "vAnchor", QObject::tr( "Vertical anchor point" ), QgsPropertyDefinition::VerticalAnchor, origin )},
|
||||
{ QgsSymbolLayer::PropertyLayerEnabled, QgsPropertyDefinition( "enabled", QObject::tr( "Layer enabled" ), QgsPropertyDefinition::Boolean, origin )},
|
||||
{ QgsSymbolLayer::PropertyArrowWidth, QgsPropertyDefinition( "arrowWidth", QObject::tr( "Arrow line width" ), QgsPropertyDefinition::StrokeWidth, origin )},
|
||||
{ QgsSymbolLayer::PropertyArrowStartWidth, QgsPropertyDefinition( "arrowStartWidth", QObject::tr( "Arrow line start width" ), QgsPropertyDefinition::StrokeWidth, origin )},
|
||||
{ QgsSymbolLayer::PropertyArrowHeadLength, QgsPropertyDefinition( "arrowHeadLength", QObject::tr( "Arrow head length" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyArrowHeadThickness, QgsPropertyDefinition( "arrowHeadThickness", QObject::tr( "Arrow head thickness" ), QgsPropertyDefinition::DoublePositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyArrowHeadType, QgsPropertyDefinition( "arrowHeadType", QObject::tr( "Arrow head type" ), QgsPropertyDefinition::IntegerPositive, origin )},
|
||||
{ QgsSymbolLayer::PropertyArrowType, QgsPropertyDefinition( "arrowType", QObject::tr( "Arrow type" ), QgsPropertyDefinition::IntegerPositive, origin )},
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class CORE_EXPORT QgsSymbolLayerAbstractMetadata
|
||||
//! Create a symbol layer of this type given the map of properties.
|
||||
virtual QgsSymbolLayer *createSymbolLayer( const QgsStringMap &map ) = 0 SIP_FACTORY;
|
||||
//! Create widget for symbol layer of this type. Can return NULL if there's no GUI
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( const QgsVectorLayer * ) SIP_FACTORY { return nullptr; }
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( QgsVectorLayer * ) SIP_FACTORY { return nullptr; }
|
||||
//! Create a symbol layer of this type given the map of properties.
|
||||
virtual QgsSymbolLayer *createSymbolLayerFromSld( QDomElement & ) SIP_FACTORY { return nullptr; }
|
||||
|
||||
@ -75,7 +75,7 @@ class CORE_EXPORT QgsSymbolLayerAbstractMetadata
|
||||
};
|
||||
|
||||
typedef QgsSymbolLayer *( *QgsSymbolLayerCreateFunc )( const QgsStringMap & ) SIP_SKIP;
|
||||
typedef QgsSymbolLayerWidget *( *QgsSymbolLayerWidgetFunc )( const QgsVectorLayer * ) SIP_SKIP;
|
||||
typedef QgsSymbolLayerWidget *( *QgsSymbolLayerWidgetFunc )( QgsVectorLayer * ) SIP_SKIP;
|
||||
typedef QgsSymbolLayer *( *QgsSymbolLayerCreateFromSldFunc )( QDomElement & ) SIP_SKIP;
|
||||
typedef void ( *QgsSymbolLayerPathResolverFunc )( QgsStringMap &, const QgsPathResolver &, bool ) SIP_SKIP;
|
||||
|
||||
@ -113,7 +113,7 @@ class CORE_EXPORT QgsSymbolLayerMetadata : public QgsSymbolLayerAbstractMetadata
|
||||
void setWidgetFunction( QgsSymbolLayerWidgetFunc f ) { mWidgetFunc = f; } SIP_SKIP
|
||||
|
||||
virtual QgsSymbolLayer *createSymbolLayer( const QgsStringMap &map ) override SIP_FACTORY { return mCreateFunc ? mCreateFunc( map ) : nullptr; }
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( const QgsVectorLayer *vl ) override SIP_FACTORY { return mWidgetFunc ? mWidgetFunc( vl ) : nullptr; }
|
||||
virtual QgsSymbolLayerWidget *createSymbolLayerWidget( QgsVectorLayer *vl ) override SIP_FACTORY { return mWidgetFunc ? mWidgetFunc( vl ) : nullptr; }
|
||||
virtual QgsSymbolLayer *createSymbolLayerFromSld( QDomElement &elem ) override SIP_FACTORY { return mCreateFromSldFunc ? mCreateFromSldFunc( elem ) : nullptr; }
|
||||
virtual void resolvePaths( QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving ) override
|
||||
{
|
||||
|
@ -296,6 +296,8 @@ SET(QGIS_GUI_SRCS
|
||||
qgsmessagelogviewer.cpp
|
||||
qgsmessageviewer.cpp
|
||||
qgsmetadatawidget.cpp
|
||||
qgsnewauxiliarylayerdialog.cpp
|
||||
qgsnewauxiliaryfielddialog.cpp
|
||||
qgsnewhttpconnection.cpp
|
||||
qgsnewmemorylayerdialog.cpp
|
||||
qgsnewnamedialog.cpp
|
||||
@ -456,6 +458,8 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgsmessagelogviewer.h
|
||||
qgsmessageviewer.h
|
||||
qgsmetadatawidget.h
|
||||
qgsnewauxiliarylayerdialog.h
|
||||
qgsnewauxiliaryfielddialog.h
|
||||
qgsnewhttpconnection.h
|
||||
qgsnewmemorylayerdialog.h
|
||||
qgsnewnamedialog.h
|
||||
|
@ -1996,10 +1996,11 @@ void QgsAttributeForm::updateJoinedFields( const QgsEditorWidgetWrapper &eww )
|
||||
|
||||
mJoinedFeatures[info] = joinFeature;
|
||||
|
||||
QStringList *subsetFields = info->joinFieldNamesSubset();
|
||||
if ( subsetFields )
|
||||
if ( info->hasSubset() )
|
||||
{
|
||||
Q_FOREACH ( const QString &field, *subsetFields )
|
||||
const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( *info );
|
||||
|
||||
Q_FOREACH ( const QString &field, subsetNames )
|
||||
{
|
||||
QString prefixedName = info->prefixedFieldName( field );
|
||||
QVariant val;
|
||||
|
103
src/gui/qgsnewauxiliaryfielddialog.cpp
Normal file
103
src/gui/qgsnewauxiliaryfielddialog.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/***************************************************************************
|
||||
qgsnewauxiliaryfielddialog.cpp - description
|
||||
-------------------
|
||||
begin : Sept 05, 2017
|
||||
copyright : (C) 2017 by Paul Blottiere
|
||||
email : paul.blottiere@oslandia.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsnewauxiliaryfielddialog.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
QgsNewAuxiliaryFieldDialog::QgsNewAuxiliaryFieldDialog( const QgsPropertyDefinition &def, QgsVectorLayer *layer, bool nameOnly, QWidget *parent )
|
||||
: QDialog( parent )
|
||||
, mLayer( layer )
|
||||
, mNameOnly( nameOnly )
|
||||
, mPropertyDefinition( def )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
mType->addItem( tr( "String" ) );
|
||||
mType->addItem( tr( "Real" ) );
|
||||
mType->addItem( tr( "Integer" ) );
|
||||
|
||||
switch ( def.dataType() )
|
||||
{
|
||||
case QgsPropertyDefinition::DataTypeString:
|
||||
mType->setCurrentIndex( mType->findText( tr( "String" ) ) );
|
||||
break;
|
||||
case QgsPropertyDefinition::DataTypeNumeric:
|
||||
mType->setCurrentIndex( mType->findText( tr( "Real" ) ) );
|
||||
break;
|
||||
case QgsPropertyDefinition::DataTypeBoolean:
|
||||
mType->setCurrentIndex( mType->findText( tr( "Integer" ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( mNameOnly )
|
||||
mType->setEnabled( false );
|
||||
else
|
||||
mType->setEnabled( true );
|
||||
}
|
||||
|
||||
void QgsNewAuxiliaryFieldDialog::accept()
|
||||
{
|
||||
QgsPropertyDefinition def = mPropertyDefinition;
|
||||
def.setComment( mName->text() );
|
||||
|
||||
if ( !mNameOnly )
|
||||
{
|
||||
if ( mType->currentText().compare( tr( "String" ) ) == 0 )
|
||||
{
|
||||
def.setDataType( QgsPropertyDefinition::DataTypeString );
|
||||
}
|
||||
else if ( mType->currentText().compare( tr( "Real" ) ) == 0 )
|
||||
{
|
||||
def.setDataType( QgsPropertyDefinition::DataTypeNumeric );
|
||||
}
|
||||
else
|
||||
{
|
||||
def.setDataType( QgsPropertyDefinition::DataTypeBoolean );
|
||||
}
|
||||
|
||||
def.setOrigin( "user" );
|
||||
def.setName( "custom" );
|
||||
}
|
||||
|
||||
QString fieldName = QgsAuxiliaryLayer::nameFromProperty( def, true );
|
||||
const int idx = mLayer->fields().lookupField( fieldName );
|
||||
if ( idx >= 0 )
|
||||
{
|
||||
const QString title = tr( "Invalid name" );
|
||||
const QString msg = tr( "Auxiliary field '%1' already exists" ).arg( fieldName );
|
||||
QMessageBox::critical( this, title, msg, QMessageBox::Ok );
|
||||
}
|
||||
else if ( def.comment().isEmpty() )
|
||||
{
|
||||
const QString title = tr( "Invalid name" );
|
||||
const QString msg = tr( "Name is a mandatory parameter" );
|
||||
QMessageBox::critical( this, title, msg, QMessageBox::Ok );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( mLayer->auxiliaryLayer()->addAuxiliaryField( def ) )
|
||||
mPropertyDefinition = def;
|
||||
QDialog::accept();
|
||||
}
|
||||
}
|
||||
|
||||
QgsPropertyDefinition QgsNewAuxiliaryFieldDialog::propertyDefinition() const
|
||||
{
|
||||
return mPropertyDefinition;
|
||||
}
|
63
src/gui/qgsnewauxiliaryfielddialog.h
Normal file
63
src/gui/qgsnewauxiliaryfielddialog.h
Normal file
@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
qgsnewauxiliaryfielddialog.h - description
|
||||
-------------------
|
||||
begin : Sept 05, 2017
|
||||
copyright : (C) 2017 by Paul Blottiere
|
||||
email : paul.blottiere@oslandia.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSNEWAUXILIARYFIELDDIALOG_H
|
||||
#define QGSNEWAUXILIARYFIELDDIALOG_H
|
||||
|
||||
#include "ui_qgsnewauxiliaryfielddialogbase.h"
|
||||
#include "qgsguiutils.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsproperty.h"
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
*
|
||||
* \brief A dialog to create a new auxiliary field
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsNewAuxiliaryFieldDialog: public QDialog, private Ui::QgsNewAuxiliaryFieldDialogBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* \param definition The property definition to use to create the auxiliary field
|
||||
* \param layer The vector layer for which the auxiliary layer has to be created
|
||||
* \param nameOnly True to indicate that only the name widget is enabled
|
||||
* \param parent Parent window
|
||||
*/
|
||||
QgsNewAuxiliaryFieldDialog( const QgsPropertyDefinition &definition, QgsVectorLayer *layer, bool nameOnly = true, QWidget *parent = nullptr );
|
||||
|
||||
/**
|
||||
* Returns the underlying property definition.
|
||||
*/
|
||||
QgsPropertyDefinition propertyDefinition() const;
|
||||
|
||||
protected:
|
||||
void accept() override;
|
||||
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
bool mNameOnly = true;
|
||||
QgsPropertyDefinition mPropertyDefinition;
|
||||
};
|
||||
|
||||
#endif
|
50
src/gui/qgsnewauxiliarylayerdialog.cpp
Normal file
50
src/gui/qgsnewauxiliarylayerdialog.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/***************************************************************************
|
||||
qgsnewauxiliarylayerdialog.cpp - description
|
||||
-------------------
|
||||
begin : Aug 28, 2017
|
||||
copyright : (C) 2017 by Paul Blottiere
|
||||
email : paul.blottiere@oslandia.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
QgsNewAuxiliaryLayerDialog::QgsNewAuxiliaryLayerDialog( QgsVectorLayer *layer, QWidget *parent )
|
||||
: QDialog( parent )
|
||||
, mLayer( layer )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
for ( const QgsField &field : mLayer->fields() )
|
||||
comboBox->addItem( field.name() );
|
||||
}
|
||||
|
||||
void QgsNewAuxiliaryLayerDialog::accept()
|
||||
{
|
||||
const int idx = mLayer->fields().lookupField( comboBox->currentText() );
|
||||
|
||||
if ( idx >= 0 )
|
||||
{
|
||||
const QgsField field = mLayer->fields().field( idx );
|
||||
QgsAuxiliaryLayer *alayer = QgsProject::instance()->auxiliaryStorage()->createAuxiliaryLayer( field, mLayer );
|
||||
|
||||
if ( alayer )
|
||||
{
|
||||
mLayer->setAuxiliaryLayer( alayer );
|
||||
}
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
}
|
53
src/gui/qgsnewauxiliarylayerdialog.h
Normal file
53
src/gui/qgsnewauxiliarylayerdialog.h
Normal file
@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
qgsnewauxiliarylayerdialog.h - description
|
||||
-------------------
|
||||
begin : Aug 28, 2017
|
||||
copyright : (C) 2017 by Paul Blottiere
|
||||
email : paul.blottiere@oslandia.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSNEWAUXILIARYLAYERDIALOG_H
|
||||
#define QGSNEWAUXILIARYLAYERDIALOG_H
|
||||
|
||||
#include "ui_qgsnewauxiliarylayerdialogbase.h"
|
||||
#include "qgsguiutils.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
*
|
||||
* \brief A dialog to create a new auxiliary layer
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsNewAuxiliaryLayerDialog: public QDialog, private Ui::QgsNewAuxiliaryLayerDialogBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* \param layer The vector layer for which the auxiliary layer has to be created
|
||||
* \param parent Parent window
|
||||
*/
|
||||
QgsNewAuxiliaryLayerDialog( QgsVectorLayer *layer, QWidget *parent = nullptr );
|
||||
|
||||
protected:
|
||||
void accept() override;
|
||||
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
@ -22,6 +22,7 @@
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgspanelwidget.h"
|
||||
#include "qgspropertyassistantwidget.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QMenu>
|
||||
@ -66,6 +67,9 @@ QgsPropertyOverrideButton::QgsPropertyOverrideButton( QWidget *parent,
|
||||
|
||||
mActionDescription = new QAction( tr( "Description..." ), this );
|
||||
|
||||
mActionCreateAuxiliaryField = new QAction( tr( "Store data in the project" ), this );
|
||||
mActionCreateAuxiliaryField->setCheckable( true );
|
||||
|
||||
mActionExpDialog = new QAction( tr( "Edit..." ), this );
|
||||
mActionExpression = nullptr;
|
||||
mActionPasteExpr = new QAction( tr( "Paste" ), this );
|
||||
@ -79,9 +83,10 @@ QgsPropertyOverrideButton::QgsPropertyOverrideButton( QWidget *parent,
|
||||
}
|
||||
|
||||
|
||||
void QgsPropertyOverrideButton::init( int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer )
|
||||
void QgsPropertyOverrideButton::init( int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer, bool auxiliaryStorageEnabled )
|
||||
{
|
||||
mVectorLayer = layer;
|
||||
mAuxiliaryStorageEnabled = auxiliaryStorageEnabled;
|
||||
setToProperty( property );
|
||||
mPropertyKey = propertyKey;
|
||||
|
||||
@ -122,9 +127,9 @@ void QgsPropertyOverrideButton::init( int propertyKey, const QgsProperty &proper
|
||||
updateGui();
|
||||
}
|
||||
|
||||
void QgsPropertyOverrideButton::init( int propertyKey, const QgsAbstractPropertyCollection &collection, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer )
|
||||
void QgsPropertyOverrideButton::init( int propertyKey, const QgsAbstractPropertyCollection &collection, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer, bool auxiliaryStorageEnabled )
|
||||
{
|
||||
init( propertyKey, collection.property( propertyKey ), definitions, layer );
|
||||
init( propertyKey, collection.property( propertyKey ), definitions, layer, auxiliaryStorageEnabled );
|
||||
}
|
||||
|
||||
|
||||
@ -329,6 +334,25 @@ void QgsPropertyOverrideButton::aboutToShowMenu()
|
||||
|
||||
mDefineMenu->addSeparator();
|
||||
|
||||
// deactivate button if field already exists
|
||||
if ( mAuxiliaryStorageEnabled )
|
||||
{
|
||||
mDefineMenu->addAction( mActionCreateAuxiliaryField );
|
||||
|
||||
const QgsAuxiliaryLayer *alayer = mVectorLayer->auxiliaryLayer();
|
||||
|
||||
mActionCreateAuxiliaryField->setEnabled( true );
|
||||
mActionCreateAuxiliaryField->setChecked( false );
|
||||
|
||||
int index = mVectorLayer->fields().indexFromName( mFieldName );
|
||||
int srcIndex;
|
||||
if ( index >= 0 && alayer && mVectorLayer->isAuxiliaryField( index, srcIndex ) )
|
||||
{
|
||||
mActionCreateAuxiliaryField->setEnabled( false );
|
||||
mActionCreateAuxiliaryField->setChecked( true );
|
||||
}
|
||||
}
|
||||
|
||||
bool fieldActive = false;
|
||||
if ( !mDataTypesString.isEmpty() )
|
||||
{
|
||||
@ -507,6 +531,10 @@ void QgsPropertyOverrideButton::menuActionTriggered( QAction *action )
|
||||
{
|
||||
showAssistant();
|
||||
}
|
||||
else if ( action == mActionCreateAuxiliaryField )
|
||||
{
|
||||
emit createAuxiliaryField();
|
||||
}
|
||||
else if ( mFieldsMenu->actions().contains( action ) ) // a field name clicked
|
||||
{
|
||||
if ( action->isEnabled() )
|
||||
|
@ -69,11 +69,13 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
* \param property initial value of associated property to show in widget
|
||||
* \param definitions properties definitions for corresponding collection
|
||||
* \param layer associated vector layer
|
||||
* \param auxiliaryStorageEnabled If true, activate the button to store data defined in auxiliary storage
|
||||
*/
|
||||
void init( int propertyKey,
|
||||
const QgsProperty &property,
|
||||
const QgsPropertiesDefinition &definitions,
|
||||
const QgsVectorLayer *layer = nullptr );
|
||||
const QgsVectorLayer *layer = nullptr,
|
||||
bool auxiliaryStorageEnabled = false );
|
||||
|
||||
/**
|
||||
* Initialize a newly constructed property button (useful if button was included in a UI layout).
|
||||
@ -81,11 +83,13 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
* \param collection associated property collection
|
||||
* \param definitions properties definitions for collection
|
||||
* \param layer associated vector layer
|
||||
* \param auxiliaryStorageEnabled If true, activate the button to store data defined in auxiliary storage
|
||||
*/
|
||||
void init( int propertyKey,
|
||||
const QgsAbstractPropertyCollection &collection,
|
||||
const QgsPropertiesDefinition &definitions,
|
||||
const QgsVectorLayer *layer = nullptr );
|
||||
const QgsVectorLayer *layer = nullptr,
|
||||
bool auxiliaryStorageEnabled = false );
|
||||
|
||||
/**
|
||||
* Returns a QgsProperty object encapsulating the current state of the
|
||||
@ -181,6 +185,13 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
*/
|
||||
void registerExpressionContextGenerator( QgsExpressionContextGenerator *generator );
|
||||
|
||||
/**
|
||||
* Updates list of fields.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void updateFieldLists();
|
||||
|
||||
/**
|
||||
* Sets a symbol which can be used for previews inside the widget or in any dialog created
|
||||
* by the widget. If not specified, a default created symbol will be used instead.
|
||||
@ -203,13 +214,14 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
//! Emitted when the activated status of the widget changes
|
||||
void activated( bool isActive );
|
||||
|
||||
//! Emitted when creating a new auxiliary field
|
||||
void createAuxiliaryField();
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent( QMouseEvent *event ) override;
|
||||
|
||||
private:
|
||||
|
||||
void updateFieldLists();
|
||||
|
||||
void showDescriptionDialog();
|
||||
void showExpressionDialog();
|
||||
void showAssistant();
|
||||
@ -246,6 +258,7 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
QAction *mActionCopyExpr = nullptr;
|
||||
QAction *mActionClearExpr = nullptr;
|
||||
QAction *mActionAssistant = nullptr;
|
||||
QAction *mActionCreateAuxiliaryField = nullptr;
|
||||
|
||||
QgsPropertyDefinition mDefinition;
|
||||
|
||||
@ -280,6 +293,8 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
//! Internal property used for storing state of widget
|
||||
QgsProperty mProperty;
|
||||
|
||||
bool mAuxiliaryStorageEnabled = false;
|
||||
|
||||
std::shared_ptr< QgsSymbol > mSymbol;
|
||||
|
||||
private slots:
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "qgsvectorlayer.h"
|
||||
#include <QColorDialog>
|
||||
|
||||
QgsArrowSymbolLayerWidget::QgsArrowSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsArrowSymbolLayerWidget::QgsArrowSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
|
||||
{
|
||||
|
@ -37,13 +37,13 @@ class GUI_EXPORT QgsArrowSymbolLayerWidget: public QgsSymbolLayerWidget, private
|
||||
* \param layer the layer where this symbol layer is applied
|
||||
* \param parent the parent widget
|
||||
*/
|
||||
QgsArrowSymbolLayerWidget( const QgsVectorLayer *layer, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
QgsArrowSymbolLayerWidget( QgsVectorLayer *layer, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
|
||||
/**
|
||||
* Static creation method
|
||||
* \param layer the layer where this symbol layer is applied
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *layer ) SIP_FACTORY { return new QgsArrowSymbolLayerWidget( layer ); }
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *layer ) SIP_FACTORY { return new QgsArrowSymbolLayerWidget( layer ); }
|
||||
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
virtual QgsSymbolLayer *symbolLayer() override;
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "qgsvectorlayer.h"
|
||||
#include <QColorDialog>
|
||||
|
||||
QgsEllipseSymbolLayerWidget::QgsEllipseSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsEllipseSymbolLayerWidget::QgsEllipseSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
|
||||
{
|
||||
|
@ -31,9 +31,19 @@ class GUI_EXPORT QgsEllipseSymbolLayerWidget: public QgsSymbolLayerWidget, priva
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsEllipseSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsEllipseSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsEllipseSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsEllipseSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
|
||||
/**
|
||||
* Creates a new QgsSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsEllipseSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
|
@ -89,7 +89,7 @@ static void _initWidgetFunctions()
|
||||
}
|
||||
|
||||
|
||||
QgsLayerPropertiesWidget::QgsLayerPropertiesWidget( QgsSymbolLayer *layer, const QgsSymbol *symbol, const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsLayerPropertiesWidget::QgsLayerPropertiesWidget( QgsSymbolLayer *layer, const QgsSymbol *symbol, QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsPanelWidget( parent )
|
||||
, mLayer( layer )
|
||||
, mSymbol( symbol )
|
||||
|
@ -43,7 +43,15 @@ class GUI_EXPORT QgsLayerPropertiesWidget : public QgsPanelWidget, public QgsExp
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsLayerPropertiesWidget( QgsSymbolLayer *layer, const QgsSymbol *symbol, const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Constructor for QgsLayerPropertiesWidget.
|
||||
* \param layer the symbol layer
|
||||
* \param symbol the symbol
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsLayerPropertiesWidget( QgsSymbolLayer *layer, const QgsSymbol *symbol, QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression contexts.
|
||||
@ -93,7 +101,7 @@ class GUI_EXPORT QgsLayerPropertiesWidget : public QgsPanelWidget, public QgsExp
|
||||
QgsSymbolLayer *mLayer = nullptr;
|
||||
|
||||
const QgsSymbol *mSymbol = nullptr;
|
||||
const QgsVectorLayer *mVectorLayer = nullptr;
|
||||
QgsVectorLayer *mVectorLayer = nullptr;
|
||||
|
||||
private slots:
|
||||
void reloadLayer();
|
||||
|
@ -38,6 +38,9 @@
|
||||
#include "qgssvgselectorwidget.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
#include "qgsnewauxiliaryfielddialog.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QColorDialog>
|
||||
@ -109,12 +112,53 @@ QgsSymbolWidgetContext QgsSymbolLayerWidget::context() const
|
||||
|
||||
void QgsSymbolLayerWidget::registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key )
|
||||
{
|
||||
button->init( key, symbolLayer()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer );
|
||||
button->init( key, symbolLayer()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer, true );
|
||||
connect( button, &QgsPropertyOverrideButton::changed, this, &QgsSymbolLayerWidget::updateDataDefinedProperty );
|
||||
connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolLayerWidget::createAuxiliaryField );
|
||||
|
||||
button->registerExpressionContextGenerator( this );
|
||||
}
|
||||
|
||||
void QgsSymbolLayerWidget::createAuxiliaryField()
|
||||
{
|
||||
// try to create an auxiliary layer if not yet created
|
||||
if ( !mVectorLayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( mVectorLayer, this );
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
// return if still not exists
|
||||
if ( !mVectorLayer->auxiliaryLayer() )
|
||||
return;
|
||||
|
||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||
QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
|
||||
QgsPropertyDefinition def = QgsSymbolLayer::propertyDefinitions()[key];
|
||||
|
||||
// create property in auxiliary storage if necessary
|
||||
if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
|
||||
{
|
||||
QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this );
|
||||
if ( dlg.exec() == QDialog::Accepted )
|
||||
def = dlg.propertyDefinition();
|
||||
}
|
||||
|
||||
// return if still not exist
|
||||
if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
|
||||
return;
|
||||
|
||||
// update property with join field name from auxiliary storage
|
||||
QgsProperty property = button->toProperty();
|
||||
property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
|
||||
property.setActive( true );
|
||||
button->updateFieldLists();
|
||||
button->setToProperty( property );
|
||||
symbolLayer()->setDataDefinedProperty( key, button->toProperty() );
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsSymbolLayerWidget::updateDataDefinedProperty()
|
||||
{
|
||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||
@ -123,7 +167,7 @@ void QgsSymbolLayerWidget::updateDataDefinedProperty()
|
||||
emit changed();
|
||||
}
|
||||
|
||||
QgsSimpleLineSymbolLayerWidget::QgsSimpleLineSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsSimpleLineSymbolLayerWidget::QgsSimpleLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -371,7 +415,7 @@ void QgsSimpleLineSymbolLayerWidget::updatePatternIcon()
|
||||
///////////
|
||||
|
||||
|
||||
QgsSimpleMarkerSymbolLayerWidget::QgsSimpleMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsSimpleMarkerSymbolLayerWidget::QgsSimpleMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -660,7 +704,7 @@ void QgsSimpleMarkerSymbolLayerWidget::updateAssistantSymbol()
|
||||
|
||||
///////////
|
||||
|
||||
QgsSimpleFillSymbolLayerWidget::QgsSimpleFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsSimpleFillSymbolLayerWidget::QgsSimpleFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -813,7 +857,7 @@ void QgsSimpleFillSymbolLayerWidget::mOffsetUnitWidget_changed()
|
||||
|
||||
///////////
|
||||
|
||||
QgsFilledMarkerSymbolLayerWidget::QgsFilledMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsFilledMarkerSymbolLayerWidget::QgsFilledMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -991,7 +1035,7 @@ void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
|
||||
|
||||
///////////
|
||||
|
||||
QgsGradientFillSymbolLayerWidget::QgsGradientFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsGradientFillSymbolLayerWidget::QgsGradientFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -1322,7 +1366,7 @@ void QgsGradientFillSymbolLayerWidget::mOffsetUnitWidget_changed()
|
||||
|
||||
///////////
|
||||
|
||||
QgsShapeburstFillSymbolLayerWidget::QgsShapeburstFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsShapeburstFillSymbolLayerWidget::QgsShapeburstFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -1583,7 +1627,7 @@ void QgsShapeburstFillSymbolLayerWidget::mIgnoreRingsCheckBox_stateChanged( int
|
||||
|
||||
///////////
|
||||
|
||||
QgsMarkerLineSymbolLayerWidget::QgsMarkerLineSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsMarkerLineSymbolLayerWidget::QgsMarkerLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -1753,7 +1797,7 @@ void QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
|
||||
///////////
|
||||
|
||||
|
||||
QgsSvgMarkerSymbolLayerWidget::QgsSvgMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsSvgMarkerSymbolLayerWidget::QgsSvgMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -2239,7 +2283,7 @@ void QgsSvgMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged(
|
||||
|
||||
/////////////
|
||||
|
||||
QgsSVGFillSymbolLayerWidget::QgsSVGFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent ): QgsSymbolLayerWidget( parent, vl )
|
||||
QgsSVGFillSymbolLayerWidget::QgsSVGFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent ): QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
setupUi( this );
|
||||
@ -2538,7 +2582,7 @@ void QgsSVGFillSymbolLayerWidget::mSvgStrokeWidthUnitWidget_changed()
|
||||
|
||||
/////////////
|
||||
|
||||
QgsLinePatternFillSymbolLayerWidget::QgsLinePatternFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent ):
|
||||
QgsLinePatternFillSymbolLayerWidget::QgsLinePatternFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent ):
|
||||
QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
setupUi( this );
|
||||
@ -2645,7 +2689,7 @@ void QgsLinePatternFillSymbolLayerWidget::mOffsetUnitWidget_changed()
|
||||
|
||||
/////////////
|
||||
|
||||
QgsPointPatternFillSymbolLayerWidget::QgsPointPatternFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent ):
|
||||
QgsPointPatternFillSymbolLayerWidget::QgsPointPatternFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent ):
|
||||
QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
setupUi( this );
|
||||
@ -2795,7 +2839,7 @@ void QgsPointPatternFillSymbolLayerWidget::mVerticalDisplacementUnitWidget_chang
|
||||
|
||||
/////////////
|
||||
|
||||
QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -3034,7 +3078,7 @@ void QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol()
|
||||
///////////////
|
||||
|
||||
|
||||
QgsCentroidFillSymbolLayerWidget::QgsCentroidFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsCentroidFillSymbolLayerWidget::QgsCentroidFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -3076,7 +3120,7 @@ void QgsCentroidFillSymbolLayerWidget::mDrawAllPartsCheckBox_stateChanged( int s
|
||||
|
||||
///////////////
|
||||
|
||||
QgsRasterFillSymbolLayerWidget::QgsRasterFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsRasterFillSymbolLayerWidget::QgsRasterFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
@ -3359,7 +3403,7 @@ void QgsRasterFillSymbolLayerWidget::updatePreviewImage()
|
||||
}
|
||||
|
||||
|
||||
QgsGeometryGeneratorSymbolLayerWidget::QgsGeometryGeneratorSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsGeometryGeneratorSymbolLayerWidget::QgsGeometryGeneratorSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
|
||||
{
|
||||
|
@ -36,7 +36,13 @@ class GUI_EXPORT QgsSymbolLayerWidget : public QWidget, protected QgsExpressionC
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSymbolLayerWidget( QWidget *parent SIP_TRANSFERTHIS, const QgsVectorLayer *vl = nullptr )
|
||||
|
||||
/**
|
||||
* Constructor for QgsSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsSymbolLayerWidget( QWidget *parent SIP_TRANSFERTHIS, QgsVectorLayer *vl = nullptr )
|
||||
: QWidget( parent )
|
||||
, mVectorLayer( vl )
|
||||
{}
|
||||
@ -78,7 +84,7 @@ class GUI_EXPORT QgsSymbolLayerWidget : public QWidget, protected QgsExpressionC
|
||||
QgsExpressionContext createExpressionContext() const override;
|
||||
|
||||
private:
|
||||
const QgsVectorLayer *mVectorLayer = nullptr;
|
||||
QgsVectorLayer *mVectorLayer = nullptr;
|
||||
|
||||
QgsMapCanvas *mMapCanvas = nullptr;
|
||||
|
||||
@ -101,6 +107,9 @@ class GUI_EXPORT QgsSymbolLayerWidget : public QWidget, protected QgsExpressionC
|
||||
protected slots:
|
||||
void updateDataDefinedProperty();
|
||||
|
||||
private slots:
|
||||
void createAuxiliaryField();
|
||||
|
||||
private:
|
||||
QgsSymbolWidgetContext mContext;
|
||||
};
|
||||
@ -120,9 +129,19 @@ class GUI_EXPORT QgsSimpleLineSymbolLayerWidget : public QgsSymbolLayerWidget, p
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSimpleLineSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSimpleLineSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsSimpleLineSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsSimpleLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsSimpleLineSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSimpleLineSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -169,9 +188,19 @@ class GUI_EXPORT QgsSimpleMarkerSymbolLayerWidget : public QgsSymbolLayerWidget,
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSimpleMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSimpleMarkerSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsSimpleMarkerSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsSimpleMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsSimpleMarkerSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSimpleMarkerSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -220,9 +249,19 @@ class GUI_EXPORT QgsSimpleFillSymbolLayerWidget : public QgsSymbolLayerWidget, p
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSimpleFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSimpleFillSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsSimpleFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsSimpleFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsSimpleFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSimpleFillSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -269,13 +308,13 @@ class GUI_EXPORT QgsFilledMarkerSymbolLayerWidget : public QgsSymbolLayerWidget,
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsFilledMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
QgsFilledMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
|
||||
/**
|
||||
* Creates a new QgsFilledMarkerSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsFilledMarkerSymbolLayerWidget( vl ); }
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsFilledMarkerSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -316,9 +355,19 @@ class GUI_EXPORT QgsGradientFillSymbolLayerWidget : public QgsSymbolLayerWidget,
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGradientFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsGradientFillSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsGradientFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsGradientFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsGradientFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsGradientFillSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -363,9 +412,19 @@ class GUI_EXPORT QgsShapeburstFillSymbolLayerWidget : public QgsSymbolLayerWidge
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsShapeburstFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsShapeburstFillSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsShapeburstFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsShapeburstFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsShapeburstFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsShapeburstFillSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -405,9 +464,19 @@ class GUI_EXPORT QgsMarkerLineSymbolLayerWidget : public QgsSymbolLayerWidget, p
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsMarkerLineSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsMarkerLineSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsMarkerLineSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsMarkerLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsMarkerLineSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsMarkerLineSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -448,9 +517,19 @@ class GUI_EXPORT QgsSvgMarkerSymbolLayerWidget : public QgsSymbolLayerWidget, pr
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSvgMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSvgMarkerSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsSvgMarkerSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsSvgMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsSvgMarkerSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSvgMarkerSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -507,9 +586,19 @@ class GUI_EXPORT QgsRasterFillSymbolLayerWidget : public QgsSymbolLayerWidget, p
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsRasterFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsRasterFillSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsRasterFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsRasterFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsRasterFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsRasterFillSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -548,9 +637,19 @@ class GUI_EXPORT QgsSVGFillSymbolLayerWidget : public QgsSymbolLayerWidget, priv
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSVGFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSVGFillSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsSVGFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsSVGFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsSVGFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsSVGFillSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -599,8 +698,18 @@ class GUI_EXPORT QgsLinePatternFillSymbolLayerWidget : public QgsSymbolLayerWidg
|
||||
|
||||
public:
|
||||
|
||||
QgsLinePatternFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsLinePatternFillSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsLinePatternFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsLinePatternFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsLinePatternFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsLinePatternFillSymbolLayerWidget( vl ); }
|
||||
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
virtual QgsSymbolLayer *symbolLayer() override;
|
||||
@ -631,8 +740,19 @@ class GUI_EXPORT QgsPointPatternFillSymbolLayerWidget: public QgsSymbolLayerWidg
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsPointPatternFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsPointPatternFillSymbolLayerWidget( vl ); }
|
||||
|
||||
/**
|
||||
* Constructor for QgsPointPatternFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsPointPatternFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsPointPatternFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsPointPatternFillSymbolLayerWidget( vl ); }
|
||||
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
virtual QgsSymbolLayer *symbolLayer() override;
|
||||
@ -667,9 +787,19 @@ class GUI_EXPORT QgsFontMarkerSymbolLayerWidget : public QgsSymbolLayerWidget, p
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsFontMarkerSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsFontMarkerSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsFontMarkerSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsFontMarkerSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsFontMarkerSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -724,9 +854,19 @@ class GUI_EXPORT QgsCentroidFillSymbolLayerWidget : public QgsSymbolLayerWidget,
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsCentroidFillSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsCentroidFillSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsCentroidFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsCentroidFillSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsCentroidFillSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsCentroidFillSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
@ -756,12 +896,18 @@ class GUI_EXPORT QgsGeometryGeneratorSymbolLayerWidget : public QgsSymbolLayerWi
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsGeometryGeneratorSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Constructor for QgsGeometryGeneratorSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsGeometryGeneratorSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Will be registered as factory
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsGeometryGeneratorSymbolLayerWidget( vl ); }
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsGeometryGeneratorSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
|
@ -215,7 +215,7 @@ class SymbolLayerItem : public QStandardItem
|
||||
|
||||
//////////
|
||||
|
||||
QgsSymbolSelectorWidget::QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *style, const QgsVectorLayer *vl, QWidget *parent )
|
||||
QgsSymbolSelectorWidget::QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsPanelWidget( parent )
|
||||
, mVectorLayer( vl )
|
||||
{
|
||||
@ -671,7 +671,7 @@ void QgsSymbolSelectorWidget::changeLayer( QgsSymbolLayer *newLayer )
|
||||
layerChanged();
|
||||
}
|
||||
|
||||
QgsSymbolSelectorDialog::QgsSymbolSelectorDialog( QgsSymbol *symbol, QgsStyle *style, const QgsVectorLayer *vl, QWidget *parent, bool embedded )
|
||||
QgsSymbolSelectorDialog::QgsSymbolSelectorDialog( QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent, bool embedded )
|
||||
: QDialog( parent )
|
||||
{
|
||||
setLayout( new QVBoxLayout() );
|
||||
|
@ -100,7 +100,7 @@ class GUI_EXPORT QgsSymbolSelectorWidget: public QgsPanelWidget, private Ui::Qgs
|
||||
* \param vl The vector layer for the symbol.
|
||||
* \param parent
|
||||
*/
|
||||
QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *style, const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
QgsSymbolSelectorWidget( QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
//! return menu for "advanced" button - create it if doesn't exist and show the advanced button
|
||||
QMenu *advancedMenu();
|
||||
@ -242,7 +242,7 @@ class GUI_EXPORT QgsSymbolSelectorWidget: public QgsPanelWidget, private Ui::Qgs
|
||||
QgsStyle *mStyle = nullptr;
|
||||
QgsSymbol *mSymbol = nullptr;
|
||||
QMenu *mAdvancedMenu = nullptr;
|
||||
const QgsVectorLayer *mVectorLayer = nullptr;
|
||||
QgsVectorLayer *mVectorLayer = nullptr;
|
||||
|
||||
QStandardItemModel *model = nullptr;
|
||||
QWidget *mPresentWidget = nullptr;
|
||||
@ -261,7 +261,17 @@ class GUI_EXPORT QgsSymbolSelectorDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSymbolSelectorDialog( QgsSymbol *symbol, QgsStyle *style, const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr, bool embedded = false );
|
||||
|
||||
/**
|
||||
* Constructor for QgsSymbolSelectorDialog.
|
||||
*
|
||||
* \param symbol The symbol
|
||||
* \param style The style
|
||||
* \param vl Associated vector layer
|
||||
* \param parent Parent widget
|
||||
* \param embedded True to embed in renderer properties dialog, false otherwise
|
||||
*/
|
||||
QgsSymbolSelectorDialog( QgsSymbol *symbol, QgsStyle *style, QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr, bool embedded = false );
|
||||
~QgsSymbolSelectorDialog();
|
||||
|
||||
//! return menu for "advanced" button - create it if doesn't exist and show the advanced button
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QString>
|
||||
@ -41,7 +43,7 @@
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent, const QgsVectorLayer *layer )
|
||||
QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent, QgsVectorLayer *layer )
|
||||
: QWidget( parent )
|
||||
, mSymbol( symbol )
|
||||
, mStyle( style )
|
||||
@ -127,6 +129,61 @@ void QgsSymbolsListWidget::registerDataDefinedButton( QgsPropertyOverrideButton
|
||||
{
|
||||
button->setProperty( "propertyKey", key );
|
||||
button->registerExpressionContextGenerator( this );
|
||||
|
||||
connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsSymbolsListWidget::createAuxiliaryField );
|
||||
}
|
||||
|
||||
void QgsSymbolsListWidget::createAuxiliaryField()
|
||||
{
|
||||
// try to create an auxiliary layer if not yet created
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
// return if still not exists
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
return;
|
||||
|
||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||
QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
|
||||
const QgsPropertyDefinition def = QgsSymbolLayer::propertyDefinitions()[key];
|
||||
|
||||
// create property in auxiliary storage if necessary
|
||||
if ( !mLayer->auxiliaryLayer()->exists( def ) )
|
||||
mLayer->auxiliaryLayer()->addAuxiliaryField( def );
|
||||
|
||||
// update property with join field name from auxiliary storage
|
||||
QgsProperty property = button->toProperty();
|
||||
property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
|
||||
property.setActive( true );
|
||||
button->updateFieldLists();
|
||||
button->setToProperty( property );
|
||||
|
||||
QgsMarkerSymbol *markerSymbol = static_cast<QgsMarkerSymbol *>( mSymbol );
|
||||
QgsLineSymbol *lineSymbol = static_cast<QgsLineSymbol *>( mSymbol );
|
||||
switch ( key )
|
||||
{
|
||||
case QgsSymbolLayer::PropertyAngle:
|
||||
if ( markerSymbol )
|
||||
markerSymbol->setDataDefinedAngle( button->toProperty() );
|
||||
break;
|
||||
case QgsSymbolLayer::PropertySize:
|
||||
if ( markerSymbol )
|
||||
{
|
||||
markerSymbol->setDataDefinedSize( button->toProperty() );
|
||||
markerSymbol->setScaleMethod( QgsSymbol::ScaleDiameter );
|
||||
}
|
||||
break;
|
||||
case QgsSymbolLayer::PropertyStrokeWidth:
|
||||
if ( lineSymbol )
|
||||
lineSymbol->setDataDefinedWidth( button->toProperty() );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsSymbolsListWidget::setContext( const QgsSymbolWidgetContext &context )
|
||||
@ -510,10 +567,10 @@ void QgsSymbolsListWidget::updateSymbolInfo()
|
||||
if ( mLayer )
|
||||
{
|
||||
QgsProperty ddSize( markerSymbol->dataDefinedSize() );
|
||||
mSizeDDBtn->init( QgsSymbolLayer::PropertySize, ddSize, QgsSymbolLayer::propertyDefinitions(), mLayer );
|
||||
mSizeDDBtn->init( QgsSymbolLayer::PropertySize, ddSize, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
|
||||
spinSize->setEnabled( !mSizeDDBtn->isActive() );
|
||||
QgsProperty ddAngle( markerSymbol->dataDefinedAngle() );
|
||||
mRotationDDBtn->init( QgsSymbolLayer::PropertyAngle, ddAngle, QgsSymbolLayer::propertyDefinitions(), mLayer );
|
||||
mRotationDDBtn->init( QgsSymbolLayer::PropertyAngle, ddAngle, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
|
||||
spinAngle->setEnabled( !mRotationDDBtn->isActive() );
|
||||
}
|
||||
else
|
||||
@ -530,7 +587,7 @@ void QgsSymbolsListWidget::updateSymbolInfo()
|
||||
if ( mLayer )
|
||||
{
|
||||
QgsProperty dd( lineSymbol->dataDefinedWidth() );
|
||||
mWidthDDBtn->init( QgsSymbolLayer::PropertyStrokeWidth, dd, QgsSymbolLayer::propertyDefinitions(), mLayer );
|
||||
mWidthDDBtn->init( QgsSymbolLayer::PropertyStrokeWidth, dd, QgsSymbolLayer::propertyDefinitions(), mLayer, true );
|
||||
spinWidth->setEnabled( !mWidthDDBtn->isActive() );
|
||||
}
|
||||
else
|
||||
|
@ -38,7 +38,16 @@ class GUI_EXPORT QgsSymbolsListWidget : public QWidget, private Ui::SymbolsListW
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent SIP_TRANSFERTHIS, const QgsVectorLayer *layer = nullptr );
|
||||
|
||||
/**
|
||||
* Constructor for QgsSymbolsListWidget.
|
||||
* \param symbol the symbol
|
||||
* \param style the style
|
||||
* \param menu the menu where to show it
|
||||
* \param parent parent widget
|
||||
* \param layer associated vector layer
|
||||
*/
|
||||
QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style, QMenu *menu, QWidget *parent SIP_TRANSFERTHIS, QgsVectorLayer *layer = nullptr );
|
||||
|
||||
|
||||
virtual ~QgsSymbolsListWidget();
|
||||
@ -94,6 +103,7 @@ class GUI_EXPORT QgsSymbolsListWidget : public QWidget, private Ui::SymbolsListW
|
||||
void groupsCombo_currentIndexChanged( int index );
|
||||
void updateAssistantSymbol();
|
||||
void opacityChanged( double value );
|
||||
void createAuxiliaryField();
|
||||
|
||||
private:
|
||||
QgsSymbol *mSymbol = nullptr;
|
||||
@ -101,7 +111,7 @@ class GUI_EXPORT QgsSymbolsListWidget : public QWidget, private Ui::SymbolsListW
|
||||
QgsStyle *mStyle = nullptr;
|
||||
QMenu *mAdvancedMenu = nullptr;
|
||||
QAction *mClipFeaturesAction = nullptr;
|
||||
const QgsVectorLayer *mLayer = nullptr;
|
||||
QgsVectorLayer *mLayer = nullptr;
|
||||
QgsMapCanvas *mMapCanvas = nullptr;
|
||||
|
||||
void populateSymbolView();
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "qgsvectorfieldsymbollayer.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
QgsVectorFieldSymbolLayerWidget::QgsVectorFieldSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent ): QgsSymbolLayerWidget( parent, vl )
|
||||
QgsVectorFieldSymbolLayerWidget::QgsVectorFieldSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent ): QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
setupUi( this );
|
||||
connect( mScaleSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsVectorFieldSymbolLayerWidget::mScaleSpinBox_valueChanged );
|
||||
|
@ -30,9 +30,19 @@ class GUI_EXPORT QgsVectorFieldSymbolLayerWidget: public QgsSymbolLayerWidget, p
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsVectorFieldSymbolLayerWidget( const QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
|
||||
static QgsSymbolLayerWidget *create( const QgsVectorLayer *vl ) SIP_FACTORY { return new QgsVectorFieldSymbolLayerWidget( vl ); }
|
||||
/**
|
||||
* Constructor for QgsVectorFieldSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsVectorFieldSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = 0 );
|
||||
|
||||
/**
|
||||
* Creates a new QgsVectorFieldSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsVectorFieldSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
|
111
src/ui/qgsnewauxiliaryfielddialogbase.ui
Normal file
111
src/ui/qgsnewauxiliaryfielddialogbase.ui
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsNewAuxiliaryFieldDialogBase</class>
|
||||
<widget class="QDialog" name="QgsNewAuxiliaryFieldDialogBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>397</width>
|
||||
<height>159</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Auxiliary storage : new auxiliary field</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>120</y>
|
||||
<width>341</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>New auxiliary field parameters</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="mType"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="mName"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>QgsNewAuxiliaryFieldDialogBase</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>QgsNewAuxiliaryFieldDialogBase</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
93
src/ui/qgsnewauxiliarylayerdialogbase.ui
Normal file
93
src/ui/qgsnewauxiliarylayerdialogbase.ui
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsNewAuxiliaryLayerDialogBase</class>
|
||||
<widget class="QDialog" name="QgsNewAuxiliaryLayerDialogBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>139</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Auxiliary storage : choose primary key</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>100</y>
|
||||
<width>341</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>81</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Select the primary key to use for joining with internal data storage</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>QgsNewAuxiliaryLayerDialogBase</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>QgsNewAuxiliaryLayerDialogBase</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -273,6 +273,15 @@
|
||||
<normaloff>:/images/themes/default/propertyicons/overlay.png</normaloff>:/images/themes/default/propertyicons/overlay.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Auxiliary Storage</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mIconAuxiliaryStorage.svg</normaloff>:/images/themes/default/mIconAuxiliaryStorage.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -1995,6 +2004,237 @@ border-radius: 2px;</string>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="mOptsPage_AuxiliaryStorage">
|
||||
<widget class="QWidget" name="mAuxiliaryStorageScrollArea" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>671</width>
|
||||
<height>551</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QgsCollapsibleGroupBox" name="mAuxiliaryStorageInformationGrpBox">
|
||||
<property name="title">
|
||||
<string>Information</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="syncGroup">
|
||||
<string notr="true">vectormeta</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="mAuxiliaryStorageFeaturesLineEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="mAuxiliaryStorageFieldsLabel">
|
||||
<property name="text">
|
||||
<string>Fields</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mAuxiliaryStorageFeaturesLabel">
|
||||
<property name="text">
|
||||
<string>Features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="mAuxiliaryStorageFieldsLineEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>A name used to identify the layer. The short name is a text string used for machine-to-machine communication.</string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="mAuxiliaryStorageKeyLabel">
|
||||
<property name="text">
|
||||
<string>Key</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="mAuxiliaryStorageKeyLineEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="mAuxiliaryStorageActions">
|
||||
<property name="text">
|
||||
<string>Auxiliary Layer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QgsCollapsibleGroupBox" name="mAuxiliaryStorageFieldsGrpBox">
|
||||
<property name="title">
|
||||
<string>Fields</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="3" column="0" rowspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="mAuxiliaryStorageFieldsAddBtn">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="mAuxiliaryStorageFieldsDeleteBtn">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeWidget" name="mAuxiliaryStorageFieldsTree">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Target</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Property</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Full Name</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Auxiliary storage tables can contain additional data that should only belong to the project file. For instance, specific location or rotation for labels. Auxiliary data are saved in qgd files. New fields can be added from any data-defined widget when needed. Be aware that this information will NOT be saved in you datasource but only in the project file.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -186,6 +186,7 @@ ADD_PYTHON_TEST(PyQgsZipUtils test_qgsziputils.py)
|
||||
ADD_PYTHON_TEST(PyQgsSourceSelectProvider test_qgssourceselectprovider.py)
|
||||
ADD_PYTHON_TEST(PyQgsAuthManagerProxy test_authmanager_proxy.py)
|
||||
ADD_PYTHON_TEST(PyQgsAuthSettingsWidget test_authsettingswidget.py)
|
||||
ADD_PYTHON_TEST(PyQgsAuxiliaryStorage test_qgsauxiliarystorage.py)
|
||||
|
||||
IF (NOT WIN32)
|
||||
ADD_PYTHON_TEST(PyQgsLogger test_qgslogger.py)
|
||||
|
390
tests/src/python/test_qgsauxiliarystorage.py
Normal file
390
tests/src/python/test_qgsauxiliarystorage.py
Normal file
@ -0,0 +1,390 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for Auxiliary Storage.
|
||||
|
||||
.. note:: 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.
|
||||
"""
|
||||
__author__ = 'Paul Blottiere'
|
||||
__date__ = '06/09/2017'
|
||||
__copyright__ = 'Copyright 2017, The QGIS Project'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
import os
|
||||
|
||||
from qgis.PyQt.QtCore import QTemporaryFile
|
||||
from qgis.core import (QgsAuxiliaryStorage,
|
||||
QgsAuxiliaryLayer,
|
||||
QgsVectorLayer,
|
||||
QgsFeature,
|
||||
QgsGeometry,
|
||||
QgsPropertyDefinition,
|
||||
QgsProject,
|
||||
QgsFeatureRequest,
|
||||
QgsPalLayerSettings,
|
||||
QgsSymbolLayer,
|
||||
QgsVectorLayerSimpleLabeling,
|
||||
NULL)
|
||||
from qgis.testing import start_app, unittest
|
||||
from utilities import unitTestDataPath, writeShape
|
||||
start_app()
|
||||
|
||||
|
||||
def tmpPath():
|
||||
f = QTemporaryFile()
|
||||
f.open()
|
||||
f.close()
|
||||
os.remove(f.fileName())
|
||||
|
||||
return f.fileName()
|
||||
|
||||
|
||||
def createLayer():
|
||||
vl = QgsVectorLayer(
|
||||
'Point?crs=epsg:4326&field=pk:integer&field=cnt:integer&field=name:string(0)&field=name2:string(0)&field=num_char:string&key=pk', 'test', 'memory')
|
||||
assert (vl.isValid())
|
||||
|
||||
f1 = QgsFeature()
|
||||
f1.setAttributes([5, -200, NULL, 'NuLl', '5'])
|
||||
f1.setGeometry(QgsGeometry.fromWkt('Point (-71.123 78.23)'))
|
||||
|
||||
f2 = QgsFeature()
|
||||
f2.setAttributes([3, 300, 'Pear', 'PEaR', '3'])
|
||||
|
||||
f3 = QgsFeature()
|
||||
f3.setAttributes([1, 100, 'Orange', 'oranGe', '1'])
|
||||
f3.setGeometry(QgsGeometry.fromWkt('Point (-70.332 66.33)'))
|
||||
|
||||
f4 = QgsFeature()
|
||||
f4.setAttributes([2, 200, 'Apple', 'Apple', '2'])
|
||||
f4.setGeometry(QgsGeometry.fromWkt('Point (-68.2 70.8)'))
|
||||
|
||||
f5 = QgsFeature()
|
||||
f5.setAttributes([4, 400, 'Honey', 'Honey', '4'])
|
||||
f5.setGeometry(QgsGeometry.fromWkt('Point (-65.32 78.3)'))
|
||||
|
||||
vl.dataProvider().addFeatures([f1, f2, f3, f4, f5])
|
||||
return vl
|
||||
|
||||
|
||||
class TestQgsAuxiliaryStorage(unittest.TestCase):
|
||||
|
||||
def testCreateSaveOpenStorageWithString(self):
|
||||
# Empty string in copy mode. A new database is created in a temporary
|
||||
# file.
|
||||
s0 = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s0.isValid())
|
||||
|
||||
# saveAs should be used instead of save in case of an empty string
|
||||
# given to the constructor of QgsAuxiliaryStorage
|
||||
self.assertEqual(s0.fileName(), "")
|
||||
self.assertFalse(s0.save())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl0 = createLayer()
|
||||
pkf = vl0.fields().field(vl0.fields().indexOf('pk'))
|
||||
al0 = s0.createAuxiliaryLayer(pkf, vl0)
|
||||
self.assertTrue(al0.isValid())
|
||||
|
||||
# Test the auxiliary key
|
||||
key = al0.joinInfo().targetFieldName()
|
||||
self.assertEqual(key, 'pk')
|
||||
|
||||
# Add a field in auxiliary layer
|
||||
p = QgsPropertyDefinition('propName', QgsPropertyDefinition.DataTypeNumeric, '', '', 'user')
|
||||
self.assertTrue(al0.addAuxiliaryField(p))
|
||||
|
||||
# saveAs without saving the auxiliary layer, the auxiliary field is lost
|
||||
f = tmpPath()
|
||||
self.assertTrue(s0.saveAs(f))
|
||||
|
||||
# Open the previous database.
|
||||
s1 = QgsAuxiliaryStorage(f)
|
||||
self.assertTrue(s1.isValid())
|
||||
|
||||
# Load the auxiliary layer from auxiliary storage
|
||||
self.assertTrue(vl0.loadAuxiliaryLayer(s1, key))
|
||||
|
||||
# As the vl0 has not been saved before saving the storage, there
|
||||
# shouldn't have auxiliary fields
|
||||
self.assertEqual(len(vl0.auxiliaryLayer().auxiliaryFields()), 0)
|
||||
|
||||
# Save the layer before saving the storage
|
||||
self.assertTrue(al0.save())
|
||||
self.assertTrue(s0.saveAs(f))
|
||||
|
||||
# Open the previous database.
|
||||
s2 = QgsAuxiliaryStorage(f)
|
||||
self.assertTrue(s2.isValid())
|
||||
|
||||
# Load the auxiliary layer from auxiliary storage
|
||||
self.assertTrue(vl0.loadAuxiliaryLayer(s2, key))
|
||||
|
||||
# As the vl0 has been saved before saving the storage, there
|
||||
# should have 1 auxiliary field
|
||||
self.assertEqual(len(vl0.auxiliaryLayer().auxiliaryFields()), 1)
|
||||
|
||||
# save is available on s2
|
||||
self.assertTrue(s2.save())
|
||||
|
||||
def testCreateSaveOpenStorageWithProject(self):
|
||||
# New project without fileName
|
||||
p = QgsProject()
|
||||
|
||||
# Create storage
|
||||
s0 = QgsAuxiliaryStorage(p)
|
||||
self.assertTrue(s0.isValid())
|
||||
|
||||
# saveAs should be used instead of save in case of an empty string
|
||||
# given to the constructor of QgsAuxiliaryStorage
|
||||
self.assertEqual(s0.fileName(), "")
|
||||
self.assertFalse(s0.save())
|
||||
|
||||
# saveAs
|
||||
f = tmpPath()
|
||||
self.assertTrue(s0.saveAs(f))
|
||||
|
||||
def testProjectStorage(self):
|
||||
# New project without fileName
|
||||
p0 = QgsProject()
|
||||
self.assertTrue(p0.auxiliaryStorage().isValid())
|
||||
|
||||
# Create new layers with key otherwise auxiliary layers are not
|
||||
# automacially created when added in project
|
||||
vl0 = createLayer()
|
||||
vl0Shp = writeShape(vl0, 'vl0.shp')
|
||||
|
||||
vl1 = createLayer()
|
||||
vl1Shp = writeShape(vl1, 'vl1.shp')
|
||||
|
||||
vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr')
|
||||
self.assertTrue(vl0.isValid())
|
||||
|
||||
vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr')
|
||||
self.assertTrue(vl1.isValid())
|
||||
|
||||
# Add layers to project and check underlying auxiliary layers
|
||||
p0.addMapLayers([vl0, vl1])
|
||||
|
||||
self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk'))
|
||||
self.assertTrue(vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char'))
|
||||
|
||||
al0 = vl0.auxiliaryLayer()
|
||||
al1 = vl1.auxiliaryLayer()
|
||||
|
||||
self.assertEqual(al0.joinInfo().targetFieldName(), 'pk')
|
||||
self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char')
|
||||
|
||||
# Add a field in auxiliary layers
|
||||
pdef0 = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut')
|
||||
self.assertTrue(al0.addAuxiliaryField(pdef0))
|
||||
|
||||
pdef1 = QgsPropertyDefinition('propname1', QgsPropertyDefinition.DataTypeString, '', '', 'ut')
|
||||
self.assertTrue(al1.addAuxiliaryField(pdef1))
|
||||
|
||||
# Check auxiliary fields names
|
||||
af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False)
|
||||
self.assertEqual(af0Name, 'ut_propname')
|
||||
af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False)
|
||||
self.assertEqual(af1Name, 'ut_propname1')
|
||||
|
||||
# Set value for auxiliary fields
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
|
||||
f = QgsFeature()
|
||||
vl0.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True)
|
||||
index0 = vl0.fields().indexOf(af0Name)
|
||||
vl0.changeAttributeValue(f.id(), index0, 333)
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
|
||||
f = QgsFeature()
|
||||
vl1.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True)
|
||||
index1 = vl1.fields().indexOf(af1Name)
|
||||
vl1.changeAttributeValue(f.id(), index0, 'myvalue')
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
|
||||
f = QgsFeature()
|
||||
vl1.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
vl1.changeAttributeValue(f.id(), index0, 'myvalue1')
|
||||
|
||||
# Save the project in a zip file
|
||||
f = tmpPath() + '.qgz'
|
||||
p0.write(f)
|
||||
|
||||
# Open the zip file with embedded auxiliary storage
|
||||
p1 = QgsProject()
|
||||
p1.read(f)
|
||||
|
||||
# Check that auxiliary fields are well loaded in layers
|
||||
self.assertEqual(len(p1.mapLayers().values()), 2)
|
||||
|
||||
for vl in p1.mapLayers().values():
|
||||
al = vl.auxiliaryLayer()
|
||||
self.assertEqual(len(al.auxiliaryFields()), 1)
|
||||
|
||||
af = al.auxiliaryFields()[0]
|
||||
afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af)
|
||||
self.assertEqual(afPropDef.origin(), 'ut')
|
||||
|
||||
if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk':
|
||||
self.assertEqual(afPropDef.name(), 'propname')
|
||||
self.assertEqual(al.featureCount(), 1)
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
self.assertEqual(f.attributes()[index0], 333.0)
|
||||
else: # num_char
|
||||
self.assertEqual(al.featureCount(), 2)
|
||||
self.assertEqual(afPropDef.name(), 'propname1')
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
self.assertEqual(f.attributes()[index1], 'myvalue')
|
||||
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
self.assertEqual(f.attributes()[index1], 'myvalue1')
|
||||
|
||||
def testAuxiliaryFieldWidgets(self):
|
||||
# Init storage
|
||||
s = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s.isValid())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl = createLayer()
|
||||
pkf = vl.fields().field(vl.fields().indexOf('pk'))
|
||||
al = s.createAuxiliaryLayer(pkf, vl)
|
||||
self.assertTrue(al.isValid())
|
||||
|
||||
# Set the auxiliary layer to the vector layer
|
||||
vl.setAuxiliaryLayer(al)
|
||||
|
||||
# Add a visible property
|
||||
p = QgsPropertyDefinition('propName', QgsPropertyDefinition.DataTypeNumeric, '', '', 'user')
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
|
||||
index = al.indexOfPropertyDefinition(p)
|
||||
self.assertFalse(al.isHiddenProperty(index))
|
||||
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
setup = vl.editorWidgetSetup(index)
|
||||
self.assertEqual(setup.type(), '')
|
||||
|
||||
tested = False
|
||||
for c in vl.attributeTableConfig().columns():
|
||||
if c.name == afName:
|
||||
self.assertFalse(c.hidden)
|
||||
tested = True
|
||||
break
|
||||
self.assertTrue(tested)
|
||||
|
||||
# Add a hidden property
|
||||
p = QgsPalLayerSettings.propertyDefinitions()[QgsPalLayerSettings.PositionX]
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
|
||||
index = al.indexOfPropertyDefinition(p)
|
||||
self.assertTrue(al.isHiddenProperty(index))
|
||||
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
setup = vl.editorWidgetSetup(index)
|
||||
self.assertEqual(setup.type(), 'Hidden')
|
||||
|
||||
tested = False
|
||||
for c in vl.attributeTableConfig().columns():
|
||||
if c.name == afName:
|
||||
self.assertTrue(c.hidden)
|
||||
tested = True
|
||||
break
|
||||
self.assertTrue(tested)
|
||||
|
||||
# Add a color property
|
||||
p = QgsSymbolLayer.propertyDefinitions()[QgsSymbolLayer.PropertyFillColor]
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
|
||||
index = al.indexOfPropertyDefinition(p)
|
||||
self.assertFalse(al.isHiddenProperty(index))
|
||||
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
setup = vl.editorWidgetSetup(index)
|
||||
self.assertEqual(setup.type(), 'Color')
|
||||
|
||||
def testClear(self):
|
||||
s = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s.isValid())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl = createLayer()
|
||||
pkf = vl.fields().field(vl.fields().indexOf('pk'))
|
||||
al = s.createAuxiliaryLayer(pkf, vl)
|
||||
self.assertTrue(al.isValid())
|
||||
vl.setAuxiliaryLayer(al)
|
||||
|
||||
# Add a field in auxiliary layer
|
||||
p = QgsPropertyDefinition('myprop', QgsPropertyDefinition.DataTypeNumeric, '', '', 'me')
|
||||
self.assertFalse(al.exists(p))
|
||||
self.assertTrue(al.addAuxiliaryField(p))
|
||||
self.assertTrue(al.exists(p))
|
||||
|
||||
# Count auxiliary features
|
||||
self.assertEqual(al.featureCount(), 0)
|
||||
|
||||
# Set value for auxiliary fields
|
||||
req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
|
||||
f = QgsFeature()
|
||||
vl.getFeatures(req).nextFeature(f)
|
||||
self.assertTrue(f.isValid())
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
index = vl.fields().indexOf(afName)
|
||||
vl.changeAttributeValue(f.id(), index, 333)
|
||||
|
||||
# Count auxiliary features
|
||||
self.assertEqual(al.featureCount(), 1)
|
||||
|
||||
# Clear and count
|
||||
al.clear()
|
||||
self.assertEqual(al.featureCount(), 0)
|
||||
|
||||
def testCreateProperty(self):
|
||||
s = QgsAuxiliaryStorage()
|
||||
self.assertTrue(s.isValid())
|
||||
|
||||
# Create a new auxiliary layer with 'pk' as key
|
||||
vl = createLayer()
|
||||
pkf = vl.fields().field(vl.fields().indexOf('pk'))
|
||||
al = s.createAuxiliaryLayer(pkf, vl)
|
||||
self.assertTrue(al.isValid())
|
||||
vl.setAuxiliaryLayer(al)
|
||||
|
||||
# Create a new labeling property on layer without labels
|
||||
key = QgsPalLayerSettings.PositionX
|
||||
index = QgsAuxiliaryLayer.createProperty(key, vl)
|
||||
self.assertEqual(index, -1)
|
||||
|
||||
vl.setLabeling(QgsVectorLayerSimpleLabeling(QgsPalLayerSettings()))
|
||||
index = QgsAuxiliaryLayer.createProperty(key, vl)
|
||||
|
||||
p = QgsPalLayerSettings.propertyDefinitions()[key]
|
||||
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
|
||||
afIndex = vl.fields().indexOf(afName)
|
||||
self.assertEqual(index, afIndex)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -123,6 +123,8 @@ def writeShape(theMemoryLayer, theFileName):
|
||||
mySkipAttributesFlag)
|
||||
assert myResult == QgsVectorFileWriter.NoError, 'Writing shape failed, Error {} ({})'.format(myResult, myErrorMessage)
|
||||
|
||||
return myFileName
|
||||
|
||||
|
||||
def doubleNear(a, b, tol=0.0000000001):
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user