mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Add relations capabilites and widgets
This commit is contained in:
parent
fb32966932
commit
dc3b56a13c
@ -438,6 +438,10 @@
|
||||
<file>flags/nb_NO.png</file>
|
||||
<file>flags/gl.png</file>
|
||||
<file>flags/hi.png</file>
|
||||
<file>themes/default/relation.svg</file>
|
||||
<file>themes/default/mActionLink.svg</file>
|
||||
<file>themes/default/mActionUnlink.svg</file>
|
||||
<file>themes/default/mActionRemove.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="/images/tips">
|
||||
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
|
||||
|
@ -14,7 +14,7 @@
|
||||
id="svg5692"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="mActionAddDelimitedTextLayer.svg"
|
||||
sodipodi:docname="mActionAdd.svg"
|
||||
inkscape:export-filename="/media/home1/robert/svn/graphics/trunk/toolbar-icons/32x32/layer-vector.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
@ -80,7 +80,7 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.937501"
|
||||
inkscape:cx="-5.5360852"
|
||||
inkscape:cx="-5.410595"
|
||||
inkscape:cy="11.532645"
|
||||
inkscape:current-layer="layer2"
|
||||
showgrid="true"
|
||||
@ -90,7 +90,7 @@
|
||||
inkscape:window-width="1231"
|
||||
inkscape:window-height="858"
|
||||
inkscape:window-x="683"
|
||||
inkscape:window-y="115"
|
||||
inkscape:window-y="867"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:snap-global="true"
|
||||
showguides="true"
|
||||
@ -162,7 +162,7 @@
|
||||
transform="translate(0,-8)">
|
||||
<g
|
||||
id="g3772"
|
||||
transform="matrix(1.8506786,0,0,1.8506786,-35.158971,-27.158972)">
|
||||
transform="matrix(1.6141779,0,0,1.6141779,-29.159575,-21.159576)">
|
||||
<rect
|
||||
ry="2.6149368"
|
||||
inkscape:export-ydpi="120"
|
||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.1 KiB |
74
images/themes/default/mActionLink.svg
Normal file
74
images/themes/default/mActionLink.svg
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24"
|
||||
height="24"
|
||||
id="svg3072"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="New document 1">
|
||||
<defs
|
||||
id="defs3074" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.4"
|
||||
inkscape:cx="8.6107244"
|
||||
inkscape:cy="15.703898"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="867"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3077">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1028.3622)">
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2902"
|
||||
width="10.839286"
|
||||
height="4.098249"
|
||||
x="2.4375007"
|
||||
y="1038.1122"
|
||||
rx="2.6428566"
|
||||
ry="2.0491245" />
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2902-3"
|
||||
width="10.839286"
|
||||
height="4.098249"
|
||||
x="10.964286"
|
||||
y="1038.1345"
|
||||
rx="2.6428566"
|
||||
ry="2.0491245" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
193
images/themes/default/mActionRemove.svg
Normal file
193
images/themes/default/mActionRemove.svg
Normal file
@ -0,0 +1,193 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24"
|
||||
height="24"
|
||||
id="svg5692"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="mActionRemove.svg"
|
||||
inkscape:export-filename="/media/home1/robert/svn/graphics/trunk/toolbar-icons/32x32/layer-vector.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<title
|
||||
id="title2829">GIS icon theme 0.2</title>
|
||||
<defs
|
||||
id="defs5694">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 16 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="32 : 16 : 1"
|
||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||
id="perspective3486" />
|
||||
<inkscape:perspective
|
||||
id="perspective3496"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective3600"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective7871"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective8710"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective9811"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<inkscape:perspective
|
||||
id="perspective4762"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.937501"
|
||||
inkscape:cx="-5.410595"
|
||||
inkscape:cy="11.532645"
|
||||
inkscape:current-layer="layer2"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
borderlayer="false"
|
||||
inkscape:window-width="1231"
|
||||
inkscape:window-height="858"
|
||||
inkscape:window-x="687"
|
||||
inkscape:window-y="867"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:snap-global="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-grids="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5700"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
dotted="true"
|
||||
originx="2.5px"
|
||||
originy="2.5px" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5697">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>GIS icon theme 0.2</dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Robert Szczepanek</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>Robert Szczepanek</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>GIS icons</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:coverage>GIS icons</dc:coverage>
|
||||
<dc:description>http://robert.szczepanek.pl/</dc:description>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer"
|
||||
style="display:inline"
|
||||
transform="translate(0,-8)">
|
||||
<g
|
||||
id="layer1"
|
||||
transform="matrix(2.0979294,0,0,2.0979294,-27.846021,-36.723572)">
|
||||
<g
|
||||
id="g8247">
|
||||
<path
|
||||
style="opacity:0.9;fill:#cc0000;stroke:#cc0000;stroke-linecap:square;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 15.143,22.5 h 7.715 c 0.354,0 0.643,0.288 0.643,0.643 v 7.715 c 0,0.354 -0.288,0.643 -0.643,0.643 h -7.715 c -0.354,0 -0.643,-0.288 -0.643,-0.643 v -7.715 c 0,-0.355 0.288,-0.643 0.643,-0.643 z"
|
||||
enable-background="new "
|
||||
id="rect10143-0-5" />
|
||||
<path
|
||||
style="opacity:0.3;fill:#fcffff"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 14.5,27 h 9 v -3 c 0,-1.5 0,-1.5 -2.25,-1.5 -0.523,0 -4.555,0 -5.25,0 -1.5,0 -1.5,0 -1.5,1.5 0,0.75 0,1.5 0,3 z"
|
||||
enable-background="new "
|
||||
id="path10149-9-8" />
|
||||
<path
|
||||
style="fill:#5c3566;stroke:#eeeeec;stroke-width:1.70560002;stroke-linecap:round"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 16,24 6.001,6"
|
||||
id="path13835-7" />
|
||||
<path
|
||||
style="fill:#5c3566;stroke:#eeeeec;stroke-width:1.70560002;stroke-linecap:round"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 16,30 6.001,-6"
|
||||
id="path8245" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.6 KiB |
122
images/themes/default/mActionUnlink.svg
Normal file
122
images/themes/default/mActionUnlink.svg
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="24"
|
||||
height="24"
|
||||
id="svg3072"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="New document 1">
|
||||
<defs
|
||||
id="defs3074" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.839192"
|
||||
inkscape:cx="8.1893275"
|
||||
inkscape:cy="11.967963"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="867"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3077">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1028.3622)">
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect2902"
|
||||
width="9.4553576"
|
||||
height="4.0982666"
|
||||
x="0.91964388"
|
||||
y="1038.1122"
|
||||
rx="2.6428566"
|
||||
ry="2.0491245" />
|
||||
<rect
|
||||
ry="2.0491245"
|
||||
rx="2.6428566"
|
||||
y="1038.1122"
|
||||
x="12.919643"
|
||||
height="4.0982666"
|
||||
width="9.4553576"
|
||||
id="rect3910"
|
||||
style="color:#000000;fill:none;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 11.72724,1041.8503 0,1.973"
|
||||
id="path3963"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 8.8560596,1037.3242 1.3951174,1.3952"
|
||||
id="path3978"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3980"
|
||||
d="m 14.551073,1037.2136 -1.395122,1.3952"
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 10.235393,1041.6178 -1.395117,1.3952"
|
||||
id="path3982"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3984"
|
||||
d="m 13.029679,1041.602 1.395122,1.3952"
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 15.3451,1040.1482 -1.973,0"
|
||||
id="path3986"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3988"
|
||||
d="m 11.72724,1036.5771 0,1.973"
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3992"
|
||||
d="m 9.8659588,1040.1482 -1.973,0"
|
||||
style="fill:none;stroke:#820521;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
605
images/themes/default/relation.svg
Normal file
605
images/themes/default/relation.svg
Normal file
@ -0,0 +1,605 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns: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"
|
||||
id="svg3428"
|
||||
height="32"
|
||||
width="32"
|
||||
version="1.0"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="relation.svg">
|
||||
<metadata
|
||||
id="metadata61">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1153"
|
||||
inkscape:window-height="836"
|
||||
id="namedview59"
|
||||
showgrid="false"
|
||||
inkscape:zoom="55.625732"
|
||||
inkscape:cx="19.005713"
|
||||
inkscape:cy="22.381052"
|
||||
inkscape:window-x="148"
|
||||
inkscape:window-y="915"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg3428" />
|
||||
<defs
|
||||
id="defs3430">
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
y2="104.06"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="64"
|
||||
y1="21.941"
|
||||
x1="64">
|
||||
<stop
|
||||
id="stop24"
|
||||
style="stop-color:#dadada"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop26"
|
||||
style="stop-color:#ccc"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="XMLID_6_"
|
||||
y2="103.07"
|
||||
xlink:href="#XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="64"
|
||||
y1="21.523001"
|
||||
x1="64">
|
||||
<stop
|
||||
id="stop31"
|
||||
style="stop-color:#d9d9d9"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop33"
|
||||
style="stop-color:#ccc"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3511"
|
||||
y2="44.139999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="-9.7747002"
|
||||
gradientTransform="matrix(-0.50045,-0.49965,-0.84917,0.84785,49.112,-9.0091)"
|
||||
y1="44.229"
|
||||
x1="-6.3077998">
|
||||
<stop
|
||||
id="stop6223"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop6225"
|
||||
style="stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3514"
|
||||
y2="35.078999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="90.221001"
|
||||
gradientTransform="matrix(-0.82274,-0.82219,-0.71961,0.71912,121.1,81.547)"
|
||||
y1="35.152"
|
||||
x1="97.442001">
|
||||
<stop
|
||||
id="stop4958"
|
||||
style="stop-color:#f8b17e"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4960"
|
||||
style="stop-color:#e35d4f"
|
||||
offset=".26238" />
|
||||
<stop
|
||||
id="stop4962"
|
||||
style="stop-color:#c6262e"
|
||||
offset=".66347" />
|
||||
<stop
|
||||
id="stop4964"
|
||||
style="stop-color:#690b54"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3516"
|
||||
y2="27.273001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="36.000999"
|
||||
gradientTransform="matrix(-1,0,0,1,49.001,5.4986e-4)"
|
||||
y1="34.022999"
|
||||
x1="29.278">
|
||||
<stop
|
||||
id="stop2492"
|
||||
style="stop-color:#791235"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2494"
|
||||
style="stop-color:#dd3b27"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3533"
|
||||
y2="88.005997"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="317.16"
|
||||
gradientTransform="matrix(-1.363,0,0,1.3617,452.82,-67.958)"
|
||||
y1="75.574997"
|
||||
x1="326.60001">
|
||||
<stop
|
||||
id="stop7423-0"
|
||||
style="stop-color:#fff"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop7425-2"
|
||||
style="stop-color:#fff;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3536"
|
||||
y2="60.768002"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="308.64999"
|
||||
gradientTransform="matrix(-1.363,0,0,1.3617,452.82,-67.958)"
|
||||
y1="58.443001"
|
||||
x1="302.29001">
|
||||
<stop
|
||||
id="stop7383"
|
||||
style="stop-color:#babdb6"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop7385"
|
||||
style="stop-color:#fff"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3539"
|
||||
y2="81.926003"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="335.29999"
|
||||
gradientTransform="matrix(-1.363,0,0,1.3617,452.82,-67.958)"
|
||||
y1="64.294998"
|
||||
x1="304.76001">
|
||||
<stop
|
||||
id="stop4436"
|
||||
style="stop-color:#d3d7cf"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4438"
|
||||
style="stop-color:#babdb6"
|
||||
offset=".18304" />
|
||||
<stop
|
||||
id="stop4440"
|
||||
style="stop-color:#fff"
|
||||
offset=".31893" />
|
||||
<stop
|
||||
id="stop4442"
|
||||
style="stop-color:#babdb6"
|
||||
offset=".87644" />
|
||||
<stop
|
||||
id="stop4444"
|
||||
style="stop-color:#eeeeec"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3541"
|
||||
y2="58.612"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="305.67001"
|
||||
gradientTransform="matrix(-1.363,0,0,1.3617,452.82,-67.958)"
|
||||
y1="52.786999"
|
||||
x1="301.32001">
|
||||
<stop
|
||||
id="stop7446"
|
||||
style="stop-color:#888a85"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop7448"
|
||||
style="stop-color:#555753"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3591"
|
||||
y2="103.07"
|
||||
xlink:href="#XMLID_6_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="64"
|
||||
gradientTransform="matrix(0.37137,0,0,0.37075,0.23836,-0.35744)"
|
||||
y1="21.523001"
|
||||
x1="64" />
|
||||
<linearGradient
|
||||
id="linearGradient3593"
|
||||
y2="102.05"
|
||||
xlink:href="#XMLID_6_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="49.374001"
|
||||
gradientTransform="matrix(0.37137,0,0,0.37075,0.23836,-0.35744)"
|
||||
y1="22.275"
|
||||
x1="49.272999" />
|
||||
<linearGradient
|
||||
id="linearGradient3596"
|
||||
y2="104.06"
|
||||
xlink:href="#XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="64"
|
||||
gradientTransform="matrix(0.32178,0,0,0.32124,3.4122,3.0428)"
|
||||
y1="21.941"
|
||||
x1="64" />
|
||||
<linearGradient
|
||||
id="linearGradient3598"
|
||||
y2="20.895"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="84.639"
|
||||
gradientTransform="matrix(0.32178,0,0,0.32124,3.4122,3.0428)"
|
||||
y1="105.1"
|
||||
x1="86.133003">
|
||||
<stop
|
||||
id="stop5130"
|
||||
style="stop-color:#fff"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop5132"
|
||||
style="stop-color:#959595"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3601"
|
||||
y2="117.23"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="64"
|
||||
gradientTransform="scale(0.375,0.375)"
|
||||
y1="6.8743"
|
||||
x1="64">
|
||||
<stop
|
||||
id="stop11"
|
||||
style="stop-color:#f2f2f2"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop13"
|
||||
style="stop-color:#d8d8d8"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3184"
|
||||
id="radialGradient6101"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.9739412,0,0,0.9750591,-92.994702,1.6957237)"
|
||||
cx="255"
|
||||
cy="63.005722"
|
||||
fx="262.43524"
|
||||
fy="71.574997"
|
||||
r="23.279442" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3184"
|
||||
id="radialGradient6107"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.9739412,0,0,0.9750591,-44.261685,1.6957237)"
|
||||
cx="255"
|
||||
cy="63.005722"
|
||||
fx="262.43524"
|
||||
fy="71.574997"
|
||||
r="23.279442" />
|
||||
<radialGradient
|
||||
id="radialGradient3605"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="73.615997"
|
||||
cx="6.7027001"
|
||||
gradientTransform="matrix(3.0435,0,0,0.96975,3.6,-30.399)"
|
||||
r="7.2284002">
|
||||
<stop
|
||||
id="stop10693"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop10695"
|
||||
style="stop-opacity:0"
|
||||
offset="1" />
|
||||
</radialGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2990"
|
||||
id="radialGradient6367"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.9679843,-0.1075536,0.2763828,2.487449,-167.98216,-101.63236)"
|
||||
cx="267.42477"
|
||||
cy="81.257088"
|
||||
fx="267.42477"
|
||||
fy="81.257088"
|
||||
r="23.279442" />
|
||||
<linearGradient
|
||||
id="linearGradient2990">
|
||||
<stop
|
||||
id="stop2992"
|
||||
offset="0"
|
||||
style="stop-color:#d7d7d7;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop2994"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath6103">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6105"
|
||||
d="m 200.1619,45.294924 c -5.42224,0.212474 -9.70739,4.671813 -9.70376,10.098216 l 0,25.245539 c 0.0171,3.487235 1.83207,6.718917 4.80092,8.54838 2.96888,1.829463 6.67151,1.997824 9.79416,0.445344 l 25.24554,-12.62277 c 3.37866,-1.725896 5.50499,-5.199776 5.50499,-8.993723 0,-3.793948 -2.12633,-7.267827 -5.50499,-8.993724 l -25.24554,-12.62277 c -1.51165,-0.77352 -3.19397,-1.153395 -4.89132,-1.104492 z"
|
||||
style="fill:url(#radialGradient6107);fill-opacity:1;fill-rule:evenodd;stroke:none" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath6097">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#radialGradient6101);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
d="m 151.42888,45.294924 c -5.42224,0.212474 -9.70739,4.671813 -9.70376,10.098216 l 0,25.245539 c 0.0171,3.487235 1.83207,6.718917 4.80092,8.54838 2.96888,1.829463 6.67151,1.997824 9.79416,0.445344 l 25.24554,-12.62277 c 3.37866,-1.725896 5.50499,-5.199776 5.50499,-8.993723 0,-3.793948 -2.12633,-7.267827 -5.50499,-8.993724 L 156.3202,46.399416 c -1.51165,-0.77352 -3.19397,-1.153395 -4.89132,-1.104492 z"
|
||||
id="path6099" />
|
||||
</clipPath>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3605"
|
||||
id="radialGradient4175"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(3.0435,0,0,0.96975,3.6,-30.399)"
|
||||
cx="6.7027001"
|
||||
cy="73.615997"
|
||||
r="7.2284002" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3601"
|
||||
id="linearGradient4177"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.375,0.375)"
|
||||
x1="64"
|
||||
y1="6.8743"
|
||||
x2="64"
|
||||
y2="117.23" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_5_"
|
||||
id="linearGradient4179"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.32178,0,0,0.32124,3.4122,3.0428)"
|
||||
x1="64"
|
||||
y1="21.941"
|
||||
x2="64"
|
||||
y2="104.06" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3598"
|
||||
id="linearGradient4181"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.32178,0,0,0.32124,3.4122,3.0428)"
|
||||
x1="86.133003"
|
||||
y1="105.1"
|
||||
x2="84.639"
|
||||
y2="20.895" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_6_"
|
||||
id="linearGradient4183"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.37137,0,0,0.37075,0.23836,-0.35744)"
|
||||
x1="64"
|
||||
y1="21.523001"
|
||||
x2="64"
|
||||
y2="103.07" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#XMLID_6_"
|
||||
id="linearGradient4185"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.37137,0,0,0.37075,0.23836,-0.35744)"
|
||||
x1="49.272999"
|
||||
y1="22.275"
|
||||
x2="49.374001"
|
||||
y2="102.05" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2990"
|
||||
id="radialGradient4187"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.9679843,-0.1075536,0.2763828,2.487449,-167.98216,-101.63236)"
|
||||
cx="267.42477"
|
||||
cy="81.257088"
|
||||
fx="267.42477"
|
||||
fy="81.257088"
|
||||
r="23.279442" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3923"
|
||||
id="linearGradient3929"
|
||||
x1="4.5"
|
||||
y1="2.5"
|
||||
x2="9.5"
|
||||
y2="14.5"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3923">
|
||||
<stop
|
||||
style="stop-color:#f1f1f1;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3925" />
|
||||
<stop
|
||||
style="stop-color:#d6d6d6;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3927" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientTransform="translate(1.1324644,1.2047943)"
|
||||
y2="14.5"
|
||||
x2="9.5"
|
||||
y1="2.5"
|
||||
x1="4.5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3082"
|
||||
xlink:href="#linearGradient3923"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3923"
|
||||
id="linearGradient4095"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(1.1324644,1.2047943)"
|
||||
x1="4.5"
|
||||
y1="2.5"
|
||||
x2="9.5"
|
||||
y2="14.5" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3923"
|
||||
id="linearGradient4097"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(1.1324644,1.2047943)"
|
||||
x1="4.5"
|
||||
y1="2.5"
|
||||
x2="9.5"
|
||||
y2="14.5" />
|
||||
</defs>
|
||||
<path
|
||||
style="fill:#000073;fill-opacity:0;stroke:#2b3b4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 10.283011,8.3578359 10.139192,0.00203 0,7.8920306"
|
||||
id="path3974"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<g
|
||||
id="g4061"
|
||||
transform="translate(-0.431455,-0.14381833)">
|
||||
<rect
|
||||
ry="1"
|
||||
rx="1"
|
||||
y="1.7047944"
|
||||
x="2.6324642"
|
||||
height="15"
|
||||
width="13"
|
||||
id="rect3921"
|
||||
style="color:#000000;fill:url(#linearGradient4097);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
id="path3931"
|
||||
d="m 2.6324644,5.7047943 12.9999996,0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3933"
|
||||
d="m 4.6324644,8.7047943 2,0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3935"
|
||||
d="m 4.6324644,11.704794 2,0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3937"
|
||||
d="m 4.6324644,14.704795 2,0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3939"
|
||||
d="m 9.6324641,8.7047943 3.9999999,0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3941"
|
||||
d="m 9.5703417,11.663069 4.0621223,0.04172"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3943"
|
||||
d="m 9.6324641,14.704795 3.9999999,0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3945"
|
||||
d="m 4.7035514,3.7105107 1.928913,-0.00572"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3947"
|
||||
d="m 9.6324641,3.7047943 3.9999999,0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4073"
|
||||
transform="translate(14.885197,13.80656)">
|
||||
<rect
|
||||
style="color:#000000;fill:url(#linearGradient4095);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect4075"
|
||||
width="13"
|
||||
height="15"
|
||||
x="2.6324642"
|
||||
y="1.7047944"
|
||||
rx="1"
|
||||
ry="1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 2.6324644,5.7047943 12.9999996,0"
|
||||
id="path4077" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 4.6324644,8.7047943 2,0"
|
||||
id="path4079" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 4.6324644,11.704794 2,0"
|
||||
id="path4081" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 4.6324644,14.704795 2,0"
|
||||
id="path4083" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 9.6324641,8.7047943 3.9999999,0"
|
||||
id="path4085" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 9.5703417,11.663069 4.0621223,0.04172"
|
||||
id="path4087" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 9.6324641,14.704795 3.9999999,0"
|
||||
id="path4089" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 4.7035514,3.7105107 1.928913,-0.00572"
|
||||
id="path4091" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 9.6324641,3.7047943 3.9999999,0"
|
||||
id="path4093" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 23 KiB |
@ -27,9 +27,9 @@
|
||||
%Include qgsdatasourceuri.sip
|
||||
%Include qgsdbfilterproxymodel.sip
|
||||
%Include qgsdistancearea.sip
|
||||
%Include qgseditorwidgetconfig.sip
|
||||
%Include qgserror.sip
|
||||
%Include qgsexpression.sip
|
||||
%Include qgseditorwidgetconfig.sip
|
||||
%Include qgsfeature.sip
|
||||
%Include qgsfeatureiterator.sip
|
||||
%Include qgsfeaturerequest.sip
|
||||
@ -68,6 +68,7 @@
|
||||
%Include qgsproviderregistry.sip
|
||||
%Include qgspythonrunner.sip
|
||||
%Include qgsrectangle.sip
|
||||
%Include qgsrelation.sip
|
||||
%Include qgsrenderchecker.sip
|
||||
%Include qgsrendercontext.sip
|
||||
%Include qgsrunprocess.sip
|
||||
|
171
python/core/qgsrelation.sip
Normal file
171
python/core/qgsrelation.sip
Normal file
@ -0,0 +1,171 @@
|
||||
/***************************************************************************
|
||||
qgsrelation.sip
|
||||
--------------------------------------
|
||||
Date : 29.4.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
class QgsRelation
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsrelation.h>
|
||||
%End
|
||||
public:
|
||||
/**
|
||||
* Defines a relation between matchin fields of the two involved tables of a relation.
|
||||
* Often, a relation is only defined by just one FieldPair with the name of the foreign key
|
||||
* column of the referencing table as first element and the name of the primkary key column
|
||||
* of the referenced table as the second element.
|
||||
*
|
||||
*/
|
||||
typedef QPair< QString, QString > FieldPair;
|
||||
|
||||
/**
|
||||
* Default constructor. Creates an invalid relation.
|
||||
*/
|
||||
QgsRelation();
|
||||
|
||||
/**
|
||||
* Creates a relation from an XML structure. Used for reading .qgs projects.
|
||||
*
|
||||
* @param node The dom node containing the relation information
|
||||
*
|
||||
* @return A relation
|
||||
*/
|
||||
static QgsRelation createFromXML( const QDomNode& node );
|
||||
|
||||
/**
|
||||
* Writes a relation to an XML structure. Used for saving .qgs projects
|
||||
*
|
||||
* @param node The parent node in which the relation will be created
|
||||
* @param doc The document in which the relation will be saved
|
||||
*/
|
||||
void writeXML( QDomNode& node, QDomDocument& doc ) const;
|
||||
|
||||
/**
|
||||
* Set a name for this relation
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setRelationId( QString id );
|
||||
|
||||
/**
|
||||
* Set a name for this relation
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
void setRelationName( QString name );
|
||||
|
||||
/**
|
||||
* Set the referencing layer id. This layer will be searched in the registry.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setReferencingLayer( QString id );
|
||||
|
||||
/**
|
||||
* Set the referenced layer id. This layer will be searched in the registry.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setReferencedLayer( QString id );
|
||||
|
||||
/**
|
||||
* Add a field pairs which is part of this relation
|
||||
* The first element of each pair are the field names fo the foreign key.
|
||||
* The second element of each pair are the field names of the matching primary key.
|
||||
*
|
||||
* @param referencingField The field name on the referencing layer (FK)
|
||||
* @param referencedField The field name on the referenced layer (PK)
|
||||
*/
|
||||
void addFieldPair( QString referencingField, QString referencedField );
|
||||
|
||||
/**
|
||||
* Creates an iterator which returns all the features on the referencing (child) layer
|
||||
* which have a foreign key pointing to the provided feature.
|
||||
*
|
||||
* @param feature A feature from the referenced (parent) layer
|
||||
*
|
||||
* @return An iterator with all the referenced features
|
||||
*/
|
||||
QgsFeatureIterator getRelatedFeatures( const QgsFeature& feature ) const;
|
||||
|
||||
/**
|
||||
* Creates a request to return all the features on the referencing (child) layer
|
||||
* which have a foreign key pointing to the provided feature.
|
||||
*
|
||||
* @param feature A feature from the referenced (parent) layer
|
||||
*
|
||||
* @return An request for all the referenced features
|
||||
*/
|
||||
QgsFeatureRequest getRelatedFeaturesRequest( const QgsFeature& feature ) const;
|
||||
|
||||
const QString name() const;
|
||||
|
||||
/**
|
||||
* The id
|
||||
* @return
|
||||
*/
|
||||
const QString& id() const;
|
||||
|
||||
/**
|
||||
* Access the referencing (child) layer's id
|
||||
* This is the layer which has the field(s) which point to another layer
|
||||
*
|
||||
* @return The id of the referencing layer
|
||||
*/
|
||||
QString referencingLayerId() const;
|
||||
|
||||
/**
|
||||
* Access the referencing (child) layer
|
||||
* This is the layer which has the field(s) which point to another layer
|
||||
*
|
||||
* @return The referencing layer
|
||||
*/
|
||||
QgsVectorLayer* referencingLayer() const;
|
||||
|
||||
/**
|
||||
* Access the referenced (parent) layer's id
|
||||
*
|
||||
* @return The id of the referenced layer
|
||||
*/
|
||||
QString referencedLayerId() const;
|
||||
|
||||
/**
|
||||
* Access the referenced (parent) layer
|
||||
*
|
||||
* @return referenced layer
|
||||
*/
|
||||
QgsVectorLayer* referencedLayer() const;
|
||||
|
||||
/**
|
||||
* Returns the field pairs which form this relation
|
||||
* The first element of each pair are the field names fo the foreign key.
|
||||
* The second element of each pair are the field names of the matching primary key.
|
||||
*
|
||||
* @return The fields forming the relation
|
||||
*/
|
||||
QMap< QString, QString > fieldPairs() const;
|
||||
%MethodCode
|
||||
QList< QgsRelation::FieldPair > pairs = sipCpp->fieldPairs();
|
||||
Q_FOREACH( const QgsRelation::FieldPair& pair, pairs )
|
||||
{
|
||||
sipRes->insert( pair.first, pair.second );
|
||||
}
|
||||
%End
|
||||
|
||||
/**
|
||||
* Returns the validity of this relation. Don't use the information if it's not valid.
|
||||
*
|
||||
* @return true if the relation is valid
|
||||
*/
|
||||
bool isValid() const;
|
||||
};
|
@ -5,11 +5,12 @@ class QgsAttributeDialog : QObject
|
||||
%End
|
||||
|
||||
public:
|
||||
QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget* parent = 0, bool showDialogButtons = true );
|
||||
QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget* parent = 0, bool showDialogButtons = true ) /Deprecated/;
|
||||
QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QWidget* parent = 0, bool showDialogButtons = true );
|
||||
void saveGeometry();
|
||||
void restoreGeometry();
|
||||
QDialog *dialog();
|
||||
QgsFeature* feature();
|
||||
const QgsFeature* feature();
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
|
@ -260,6 +260,10 @@
|
||||
|
||||
#include "nodetool/qgsmaptoolnodetool.h"
|
||||
|
||||
// Editor widgets
|
||||
#include "qgseditorwidgetregistry.h"
|
||||
#include "qgsrelationreferencefactory.h"
|
||||
|
||||
//
|
||||
// Conditional Includes
|
||||
//
|
||||
@ -577,6 +581,13 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
|
||||
|
||||
mVectorLayerTools = new QgsGuiVectorLayerTools();
|
||||
|
||||
// Init the editor widget types
|
||||
QgsEditorWidgetRegistry* editorWidgetRegistry = QgsEditorWidgetRegistry::instance();
|
||||
QgsAttributeEditorContext context;
|
||||
context.setVectorLayerTools( vectorLayerTools() );
|
||||
editorWidgetRegistry->registerWidget( "RelationReference", new QgsRelationReferenceFactory( context, tr( "Relation Reference" ) ) );
|
||||
|
||||
|
||||
mInternalClipboard = new QgsClipboard; // create clipboard
|
||||
connect( mInternalClipboard, SIGNAL( changed() ), this, SLOT( clipboardChanged() ) );
|
||||
mQgisInterface = new QgisAppInterface( this ); // create the interfce
|
||||
|
@ -609,7 +609,7 @@ void QgisAppInterface::cacheloadForm( QString uifile )
|
||||
}
|
||||
}
|
||||
|
||||
QDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeature &f )
|
||||
QDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeature &feature )
|
||||
{
|
||||
QgsDistanceArea myDa;
|
||||
|
||||
@ -617,10 +617,15 @@ QDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeature &f )
|
||||
myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() );
|
||||
myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
|
||||
|
||||
QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &f, false, myDa );
|
||||
QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &feature, false, NULL, true );
|
||||
return dialog->dialog();
|
||||
}
|
||||
|
||||
QgsVectorLayerTools* QgisAppInterface::vectorLayerTools()
|
||||
{
|
||||
return qgis->vectorLayerTools();
|
||||
}
|
||||
|
||||
QList<QgsMapLayer *> QgisAppInterface::editableLayers( bool modified ) const
|
||||
{
|
||||
return qgis->editableLayers( modified );
|
||||
|
@ -423,15 +423,34 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
|
||||
virtual QAction *actionCheckQgisVersion();
|
||||
virtual QAction *actionAbout();
|
||||
|
||||
//! open feature form
|
||||
// returns true when dialog was accepted
|
||||
// @param l vector layer
|
||||
// @param f feature to show/modify
|
||||
// @param updateFeatureOnly only update the feature update (don't change any attributes of the layer)
|
||||
// @added in 1.6
|
||||
/**
|
||||
* Open feature form
|
||||
* returns true when dialog was accepted
|
||||
* @param l vector layer
|
||||
* @param f feature to show/modify
|
||||
* @param updateFeatureOnly only update the feature update (don't change any attributes of the layer)
|
||||
* @note added in 1.6
|
||||
*/
|
||||
virtual bool openFeatureForm( QgsVectorLayer *l, QgsFeature &f, bool updateFeatureOnly = false );
|
||||
|
||||
virtual QDialog* getFeatureForm( QgsVectorLayer *l, QgsFeature &f );
|
||||
/**
|
||||
* Returns a feature form for a given feature
|
||||
*
|
||||
* @param layer The layer for which the dialog will be created
|
||||
* @param feature The feature for which the dialog will be created
|
||||
*
|
||||
* @return A feature form
|
||||
*/
|
||||
virtual QDialog* getFeatureForm( QgsVectorLayer *layer, QgsFeature &feature );
|
||||
|
||||
/**
|
||||
* Access the vector layer tools instance.
|
||||
* With the help of this you can access methods like addFeature, startEditing
|
||||
* or stopEditing while giving the user the appropriate dialogs.
|
||||
*
|
||||
* @return An instance of the vector layer tools
|
||||
*/
|
||||
virtual QgsVectorLayerTools* vectorLayerTools();
|
||||
|
||||
/** This method is only needed when using a UI form with a custom widget plugin and calling
|
||||
* openFeatureForm or getFeatureForm from Python (PyQt4) and you havn't used the info tool first.
|
||||
@ -449,11 +468,13 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
|
||||
/** Return vector layers in edit mode
|
||||
* @param modified whether to return only layers that have been modified
|
||||
* @returns list of layers in legend order, or empty list
|
||||
* @note added in 1.9 */
|
||||
* @note added in 1.9
|
||||
*/
|
||||
virtual QList<QgsMapLayer *> editableLayers( bool modified = false ) const;
|
||||
|
||||
/** Get timeout for timed messages: default of 5 seconds
|
||||
* @note added in 1.9 */
|
||||
* @note added in 1.9
|
||||
*/
|
||||
virtual int messageTimeout();
|
||||
|
||||
signals:
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
@ -96,9 +97,23 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
|
||||
connect( mDesignerTree, SIGNAL( itemSelectionChanged() ), this, SLOT( onAttributeSelectionChanged() ) );
|
||||
connect( mFieldsList, SIGNAL( itemSelectionChanged() ), this, SLOT( onAttributeSelectionChanged() ) );
|
||||
|
||||
mRelationsList = new DragList( mRelationsFrame );
|
||||
mRelationsFrameLayout->addWidget( mRelationsList );
|
||||
mRelationsList->setColumnCount( RelColCount );
|
||||
mRelationsList->setDragDropMode( QAbstractItemView::DragOnly );
|
||||
mRelationsList->setSelectionMode( QAbstractItemView::SingleSelection );
|
||||
mRelationsList->setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
mRelationsList->setHorizontalHeaderItem( RelIdCol, new QTableWidgetItem( tr( "Id" ) ) );
|
||||
mRelationsList->setHorizontalHeaderItem( RelNameCol, new QTableWidgetItem( tr( "Name" ) ) );
|
||||
mRelationsList->setHorizontalHeaderItem( RelLayerCol, new QTableWidgetItem( tr( "Layer" ) ) );
|
||||
mRelationsList->setHorizontalHeaderItem( RelFieldCol, new QTableWidgetItem( tr( "Field" ) ) );
|
||||
mRelationsList->verticalHeader()->hide();
|
||||
|
||||
leEditForm->setText( layer->editForm() );
|
||||
leEditFormInit->setText( layer->editFormInit() );
|
||||
|
||||
loadRelations();
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
@ -135,6 +150,10 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
|
||||
newWidget = mDesignerTree->addItem( parent, DesignerTreeItemData( DesignerTreeItemData::Field, widgetDef->name() ) );
|
||||
break;
|
||||
|
||||
case QgsAttributeEditorElement::AeTypeRelation:
|
||||
newWidget = mDesignerTree->addItem( parent, DesignerTreeItemData( DesignerTreeItemData::Field, widgetDef->name() ) );
|
||||
break;
|
||||
|
||||
case QgsAttributeEditorElement::AeTypeContainer:
|
||||
{
|
||||
newWidget = mDesignerTree->addItem( parent, DesignerTreeItemData( DesignerTreeItemData::Container, widgetDef->name() ) );
|
||||
@ -235,6 +254,40 @@ void QgsFieldsProperties::setRow( int row, int idx, const QgsField &field )
|
||||
mFieldsList->setItem( row, attrWFSCol, wfsAttrItem );
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::loadRelations()
|
||||
{
|
||||
mRelationsList->setRowCount( 0 );
|
||||
|
||||
QList<QgsRelation> relations = QgsProject::instance()->relationManager()->referencedRelations( mLayer );
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Q_FOREACH( const QgsRelation& relation, relations )
|
||||
{
|
||||
mRelationsList->insertRow( idx );
|
||||
|
||||
QTableWidgetItem* item = new QTableWidgetItem( relation.name() );
|
||||
item->setFlags( Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable );
|
||||
DesignerTreeItemData itemData( DesignerTreeItemData::Relation, QString( "%1" ).arg( relation.id() ) );
|
||||
item->setData( DesignerTreeRole, itemData.asQVariant() );
|
||||
mRelationsList->setItem( idx, RelNameCol, item );
|
||||
|
||||
item = new QTableWidgetItem( relation.referencingLayer()->name() );
|
||||
item->setFlags( Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable );
|
||||
mRelationsList->setItem( idx, RelLayerCol, item );
|
||||
|
||||
item = new QTableWidgetItem( relation.fieldPairs().first().referencingField() );
|
||||
item->setFlags( Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable );
|
||||
mRelationsList->setItem( idx, RelFieldCol, item );
|
||||
|
||||
item = new QTableWidgetItem( relation.id() );
|
||||
item->setFlags( Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable );
|
||||
mRelationsList->setItem( idx, RelIdCol, item );
|
||||
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::on_mAddItemButton_clicked()
|
||||
{
|
||||
QList<QTableWidgetItem*> listItems = mFieldsList->selectedItems();
|
||||
@ -693,6 +746,13 @@ QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTr
|
||||
break;
|
||||
}
|
||||
|
||||
case DesignerTreeItemData::Relation:
|
||||
{
|
||||
QgsRelation relation = QgsProject::instance()->relationManager()->relation( itemData.name() );
|
||||
widgetDef = new QgsAttributeEditorRelation( itemData.name(), relation, parent );
|
||||
break;
|
||||
}
|
||||
|
||||
case DesignerTreeItemData::Container:
|
||||
{
|
||||
QgsAttributeEditorContainer* container = new QgsAttributeEditorContainer( itemData.name(), parent );
|
||||
|
@ -43,6 +43,7 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
||||
enum Type
|
||||
{
|
||||
Field,
|
||||
Relation,
|
||||
Container
|
||||
};
|
||||
|
||||
@ -159,6 +160,8 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
||||
void loadRows();
|
||||
void setRow( int row, int idx, const QgsField &field );
|
||||
|
||||
void loadRelations();
|
||||
|
||||
void loadAttributeEditorTree();
|
||||
QTreeWidgetItem *loadAttributeEditorTreeItem( QgsAttributeEditorElement* const widgetDef, QTreeWidgetItem* parent );
|
||||
|
||||
@ -197,6 +200,7 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
||||
QgsVectorLayer* mLayer;
|
||||
DesignerTree* mDesignerTree;
|
||||
DragList* mFieldsList;
|
||||
DragList* mRelationsList;
|
||||
|
||||
// Holds all the first column items (header: id) of the table.
|
||||
// The index in the list is the fieldIdx, and therefore acts as a mapping
|
||||
@ -219,6 +223,15 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
||||
attrColCount,
|
||||
};
|
||||
|
||||
enum relationColumns
|
||||
{
|
||||
RelNameCol = 0,
|
||||
RelLayerCol,
|
||||
RelFieldCol,
|
||||
RelIdCol,
|
||||
RelColCount
|
||||
};
|
||||
|
||||
static QMap< QgsVectorLayer::EditType, QString > editTypeMap;
|
||||
static void setupEditTypes();
|
||||
static QString editTypeButtonText( QgsVectorLayer::EditType type );
|
||||
|
@ -43,6 +43,9 @@
|
||||
#include "qgsstylev2managerdialog.h"
|
||||
#include "qgsvectorcolorrampv2.h"
|
||||
#include "qgssymbolv2selectordialog.h"
|
||||
#include "qgsrelationmanagerdialog.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgisapp.h"
|
||||
|
||||
//qt includes
|
||||
#include <QColorDialog>
|
||||
@ -442,6 +445,20 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
|
||||
resetPythonMacros();
|
||||
}
|
||||
|
||||
// Initialize relation manager
|
||||
mRelationManagerDlg = new QgsRelationManagerDialog( QgsProject::instance()->relationManager(), mTabRelations );
|
||||
mTabRelations->layout()->addWidget( mRelationManagerDlg );
|
||||
|
||||
QList<QgsVectorLayer*> vectorLayers;
|
||||
foreach ( QgsMapLayer* mapLayer, mapLayers.values() )
|
||||
{
|
||||
if ( QgsMapLayer::VectorLayer == mapLayer->type() )
|
||||
{
|
||||
vectorLayers.append( qobject_cast<QgsVectorLayer*> ( mapLayer ) );
|
||||
}
|
||||
}
|
||||
mRelationManagerDlg->setLayers( vectorLayers );
|
||||
|
||||
// Update projection selector (after mLayerSrsId is set)
|
||||
bool myProjectionEnabled = myRenderer->hasCrsTransformEnabled();
|
||||
bool onFlyChecked = cbxProjectionEnabled->isChecked();
|
||||
@ -794,6 +811,8 @@ void QgsProjectProperties::apply()
|
||||
}
|
||||
QgsProject::instance()->writeEntry( "Macros", "/pythonCode", pythonMacros );
|
||||
|
||||
QgsProject::instance()->relationManager()->setRelations( mRelationManagerDlg->relations() );
|
||||
|
||||
//todo XXX set canvas color
|
||||
emit refresh();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "qgscontexthelp.h"
|
||||
|
||||
class QgsMapCanvas;
|
||||
class QgsRelationManagerDialog;
|
||||
class QgsStyleV2;
|
||||
|
||||
/*! Dialog to set project level properties
|
||||
@ -162,6 +163,7 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
|
||||
void refresh();
|
||||
|
||||
private:
|
||||
QgsRelationManagerDialog *mRelationManagerDlg;
|
||||
QgsMapCanvas* mMapCanvas;
|
||||
QgsStyleV2* mStyle;
|
||||
|
||||
|
@ -106,6 +106,8 @@ SET(QGIS_CORE_SRCS
|
||||
qgsprovidermetadata.cpp
|
||||
qgsproviderregistry.cpp
|
||||
qgspythonrunner.cpp
|
||||
qgsrelation.cpp
|
||||
qgsrelationmanager.cpp
|
||||
qgsrendercontext.cpp
|
||||
qgsrenderchecker.cpp
|
||||
qgsrectangle.cpp
|
||||
@ -311,6 +313,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
qgspluginlayer.h
|
||||
qgsproject.h
|
||||
qgsrunprocess.h
|
||||
qgsrelationmanager.h
|
||||
qgsvectorlayer.h
|
||||
qgsvectorlayereditbuffer.h
|
||||
qgsnetworkaccessmanager.h
|
||||
@ -429,6 +432,8 @@ SET(QGIS_CORE_HDRS
|
||||
qgsrectangle.h
|
||||
qgsrendercontext.h
|
||||
qgsrenderchecker.h
|
||||
qgsrelation.h
|
||||
qgsrelationmanager.h
|
||||
qgsrunprocess.h
|
||||
qgsscalecalculator.h
|
||||
qgssnapper.h
|
||||
|
@ -56,7 +56,7 @@ QgsFeatureRequest& QgsFeatureRequest::operator=( const QgsFeatureRequest & rh )
|
||||
mFilterFids = rh.mFilterFids;
|
||||
if ( rh.mFilterExpression )
|
||||
{
|
||||
mFilterExpression = new QgsExpression( rh.mFilterExpression->expression() );
|
||||
mFilterExpression = new QgsExpression( rh.mFilterExpression->dump() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -144,7 +144,7 @@ bool QgsFeatureRequest::acceptFeature( const QgsFeature& feature )
|
||||
break;
|
||||
|
||||
case QgsFeatureRequest::FilterFid:
|
||||
if ( feature.id () == mFilterFid )
|
||||
if ( feature.id() == mFilterFid )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@ -158,7 +158,7 @@ bool QgsFeatureRequest::acceptFeature( const QgsFeature& feature )
|
||||
break;
|
||||
|
||||
case QgsFeatureRequest::FilterFids:
|
||||
if ( mFilterFids.contains ( feature.id () ) )
|
||||
if ( mFilterFids.contains( feature.id() ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
@ -130,7 +130,6 @@ class CORE_EXPORT QgsFeatureRequest
|
||||
bool acceptFeature( const QgsFeature& feature );
|
||||
|
||||
// TODO: in future
|
||||
// void setFilterExpression(const QString& expression); // using QgsExpression
|
||||
// void setFilterNativeExpression(con QString& expr); // using provider's SQL (if supported)
|
||||
// void setLimit(int limit);
|
||||
|
||||
|
@ -20,18 +20,19 @@
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
#include "qgslogger.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsexception.h"
|
||||
#include "qgsprojectproperty.h"
|
||||
#include "qgsprojectfiletransform.h"
|
||||
#include "qgsprojectversion.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgspluginlayer.h"
|
||||
#include "qgspluginlayerregistry.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsprojectfiletransform.h"
|
||||
#include "qgsprojectproperty.h"
|
||||
#include "qgsprojectversion.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileInfo>
|
||||
@ -332,7 +333,9 @@ struct QgsProject::Imp
|
||||
|
||||
|
||||
QgsProject::QgsProject()
|
||||
: imp_( new QgsProject::Imp ), mBadLayerHandler( new QgsProjectBadLayerDefaultHandler() )
|
||||
: imp_( new QgsProject::Imp )
|
||||
, mBadLayerHandler( new QgsProjectBadLayerDefaultHandler() )
|
||||
, mRelationManager( new QgsRelationManager( this ) )
|
||||
{
|
||||
// Set some default project properties
|
||||
// XXX THESE SHOULD BE MOVED TO STATUSBAR RELATED SOURCE
|
||||
@ -349,6 +352,7 @@ QgsProject::QgsProject()
|
||||
QgsProject::~QgsProject()
|
||||
{
|
||||
delete mBadLayerHandler;
|
||||
delete mRelationManager;
|
||||
|
||||
// note that std::auto_ptr automatically deletes imp_ when it's destroyed
|
||||
} // QgsProject dtor
|
||||
@ -717,7 +721,6 @@ QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument const &do
|
||||
|
||||
} // _getMapLayers
|
||||
|
||||
|
||||
bool QgsProject::addLayer( const QDomElement& layerElem, QList<QDomNode>& brokenNodes, QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList )
|
||||
{
|
||||
QString type = layerElem.attribute( "type" );
|
||||
@ -865,6 +868,7 @@ bool QgsProject::read()
|
||||
|
||||
imp_->clear();
|
||||
mEmbeddedLayers.clear();
|
||||
mRelationManager->clear();
|
||||
|
||||
// now get any properties
|
||||
_getProperties( *doc, imp_->properties_ );
|
||||
@ -1801,3 +1805,8 @@ QString QgsProject::homePath() const
|
||||
|
||||
return pfi.canonicalPath();
|
||||
}
|
||||
|
||||
QgsRelationManager* QgsProject::relationManager() const
|
||||
{
|
||||
return mRelationManager;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ class QDomNode;
|
||||
|
||||
class QgsMapLayer;
|
||||
class QgsProjectBadLayerHandler;
|
||||
class QgsRelationManager;
|
||||
class QgsVectorLayer;
|
||||
|
||||
/** \ingroup core
|
||||
@ -281,10 +282,10 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
@note added in 1.4 */
|
||||
void setBadLayerHandler( QgsProjectBadLayerHandler* handler );
|
||||
|
||||
/**Returns project file path if layer is embedded from other project file. Returns empty string if layer is not embedded*/
|
||||
/** Returns project file path if layer is embedded from other project file. Returns empty string if layer is not embedded*/
|
||||
QString layerIsEmbedded( const QString& id ) const;
|
||||
|
||||
/**Creates a maplayer instance defined in an arbitrary project file. Caller takes ownership
|
||||
/** Creates a maplayer instance defined in an arbitrary project file. Caller takes ownership
|
||||
@return the layer or 0 in case of error
|
||||
@note: added in version 1.8
|
||||
@note not available in python bindings
|
||||
@ -292,21 +293,21 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
bool createEmbeddedLayer( const QString& layerId, const QString& projectFilePath, QList<QDomNode>& brokenNodes,
|
||||
QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList, bool saveFlag = true );
|
||||
|
||||
/**Convenience function to set snap settings per layer
|
||||
/** Convenience function to set snap settings per layer
|
||||
@note added in version 1.9*/
|
||||
void setSnapSettingsForLayer( const QString& layerId, bool enabled, QgsSnapper::SnappingType type, QgsTolerance::UnitType unit, double tolerance,
|
||||
bool avoidIntersection );
|
||||
|
||||
/**Convenience function to query snap settings of a layer
|
||||
/** Convenience function to query snap settings of a layer
|
||||
@note added in version 1.9*/
|
||||
bool snapSettingsForLayer( const QString& layerId, bool& enabled, QgsSnapper::SnappingType& type, QgsTolerance::UnitType& units, double& tolerance,
|
||||
bool& avoidIntersection ) const;
|
||||
|
||||
/**Convenience function to set topological editing
|
||||
/** Convenience function to set topological editing
|
||||
@note added in version 1.9*/
|
||||
void setTopologicalEditing( bool enabled );
|
||||
|
||||
/**Convenience function to query topological editing status
|
||||
/** Convenience function to query topological editing status
|
||||
@note added in version 1.9*/
|
||||
bool topologicalEditing() const;
|
||||
|
||||
@ -315,6 +316,8 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
@note added in version 2.0 */
|
||||
QString homePath() const;
|
||||
|
||||
QgsRelationManager* relationManager() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** Set error message from read/write operation
|
||||
@ -398,6 +401,8 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
void snapSettings( QStringList& layerIdList, QStringList& enabledList, QStringList& snapTypeList, QStringList& snapUnitList, QStringList& toleranceUnitList,
|
||||
QStringList& avoidIntersectionList ) const;
|
||||
|
||||
QgsRelationManager* mRelationManager;
|
||||
|
||||
}; // QgsProject
|
||||
|
||||
|
||||
|
258
src/core/qgsrelation.cpp
Normal file
258
src/core/qgsrelation.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
/***************************************************************************
|
||||
qgsrelation.cpp
|
||||
--------------------------------------
|
||||
Date : 29.4.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsrelation.h"
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
QgsRelation::QgsRelation()
|
||||
: mReferencingLayer( NULL )
|
||||
, mReferencedLayer( NULL )
|
||||
, mValid( false )
|
||||
{
|
||||
}
|
||||
|
||||
QgsRelation QgsRelation::createFromXML( const QDomNode &node )
|
||||
{
|
||||
QDomElement elem = node.toElement();
|
||||
|
||||
if ( elem.tagName() != "relation" )
|
||||
{
|
||||
QgsLogger::warning( QApplication::translate( "QgsRelation", "Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
|
||||
}
|
||||
|
||||
QgsRelation relation;
|
||||
|
||||
QString referencingLayerId = elem.attribute( "referencingLayer" );
|
||||
QString referencedLayerId = elem.attribute( "referencedLayer" );
|
||||
QString id = elem.attribute( "id" );
|
||||
QString name = elem.attribute( "name" );
|
||||
|
||||
const QMap<QString, QgsMapLayer*>& mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
|
||||
|
||||
QgsMapLayer* referencingLayer = mapLayers[referencingLayerId];
|
||||
QgsMapLayer* referencedLayer = mapLayers[referencedLayerId];;
|
||||
|
||||
if ( NULL == referencingLayer )
|
||||
{
|
||||
QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which does not exist." ).arg( referencingLayerId ) );
|
||||
}
|
||||
else if ( QgsMapLayer::VectorLayer != referencingLayer->type() )
|
||||
{
|
||||
QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencingLayerId ) );
|
||||
}
|
||||
|
||||
if ( NULL == referencedLayer )
|
||||
{
|
||||
QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which does not exist." ).arg( referencedLayerId ) );
|
||||
}
|
||||
else if ( QgsMapLayer::VectorLayer != referencedLayer->type() )
|
||||
{
|
||||
QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencedLayerId ) );
|
||||
}
|
||||
|
||||
relation.mReferencingLayerId = referencingLayerId;
|
||||
relation.mReferencingLayer = qobject_cast<QgsVectorLayer*>( referencingLayer );
|
||||
relation.mReferencedLayerId = referencedLayerId;
|
||||
relation.mReferencedLayer = qobject_cast<QgsVectorLayer*>( referencedLayer );
|
||||
relation.mRelationId = id;
|
||||
relation.mRelationName = name;
|
||||
|
||||
QDomNodeList references = elem.elementsByTagName( "fieldRef" );
|
||||
for ( int i = 0; i < references.size(); ++i )
|
||||
{
|
||||
QDomElement refEl = references.at( i ).toElement();
|
||||
|
||||
QString referencingField = refEl.attribute( "referencingField" );
|
||||
QString referencedField = refEl.attribute( "referencedField" );
|
||||
|
||||
relation.addFieldPair( referencingField, referencedField );
|
||||
}
|
||||
|
||||
relation.mValid = true;
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
void QgsRelation::writeXML( QDomNode &node, QDomDocument &doc ) const
|
||||
{
|
||||
QDomElement elem = doc.createElement( "relation" );
|
||||
elem.setAttribute( "id", mRelationId );
|
||||
elem.setAttribute( "name", mRelationName );
|
||||
elem.setAttribute( "referencingLayer", mReferencingLayerId );
|
||||
elem.setAttribute( "referencedLayer", mReferencedLayerId );
|
||||
|
||||
foreach ( FieldPair fields, mFieldPairs )
|
||||
{
|
||||
QDomElement referenceElem = doc.createElement( "fieldRef" );
|
||||
referenceElem.setAttribute( "referencingField", fields.first );
|
||||
referenceElem.setAttribute( "referencedField", fields.second );
|
||||
elem.appendChild( referenceElem );
|
||||
}
|
||||
|
||||
node.appendChild( elem );
|
||||
}
|
||||
|
||||
void QgsRelation::setRelationId( QString id )
|
||||
{
|
||||
mRelationId = id;
|
||||
}
|
||||
|
||||
void QgsRelation::setRelationName( QString name )
|
||||
{
|
||||
mRelationName = name;
|
||||
}
|
||||
|
||||
void QgsRelation::setReferencingLayer( QString id )
|
||||
{
|
||||
mReferencingLayerId = id;
|
||||
|
||||
updateRelationStatus();
|
||||
}
|
||||
|
||||
void QgsRelation::setReferencedLayer( QString id )
|
||||
{
|
||||
mReferencedLayerId = id;
|
||||
|
||||
updateRelationStatus();
|
||||
}
|
||||
|
||||
void QgsRelation::addFieldPair( QString referencingField, QString referencedField )
|
||||
{
|
||||
mFieldPairs << FieldPair( referencingField, referencedField );
|
||||
updateRelationStatus();
|
||||
}
|
||||
|
||||
void QgsRelation::addFieldPair( QgsRelation::FieldPair fieldPair )
|
||||
{
|
||||
mFieldPairs << fieldPair;
|
||||
updateRelationStatus();
|
||||
}
|
||||
|
||||
QgsFeatureIterator QgsRelation::getRelatedFeatures( const QgsFeature& feature ) const
|
||||
{
|
||||
return referencingLayer()->getFeatures( getRelatedFeaturesRequest( feature ) );
|
||||
}
|
||||
|
||||
QgsFeatureRequest QgsRelation::getRelatedFeaturesRequest( const QgsFeature& feature ) const
|
||||
{
|
||||
QStringList conditions;
|
||||
|
||||
foreach ( const QgsRelation::FieldPair& fieldPair, mFieldPairs )
|
||||
{
|
||||
int referencingIdx = referencingLayer()->pendingFields().indexFromName( fieldPair.referencingField() );
|
||||
QgsField referencingField = referencingLayer()->pendingFields().at( referencingIdx );
|
||||
|
||||
switch ( referencingField.type() )
|
||||
{
|
||||
case QVariant::String:
|
||||
// Use quotes
|
||||
conditions << QString( "\"%1\" = '%2'" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
|
||||
break;
|
||||
|
||||
default:
|
||||
// No quotes
|
||||
conditions << QString( "\"%1\" = %2" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureRequest myRequest;
|
||||
|
||||
QgsDebugMsg( QString( "Filter conditions: '%1'" ).arg( conditions.join( " AND " ) ) );
|
||||
|
||||
myRequest.setFilterExpression( conditions.join( " AND " ) );
|
||||
|
||||
return myRequest;
|
||||
}
|
||||
|
||||
const QString QgsRelation::name() const
|
||||
{
|
||||
return mRelationName;
|
||||
}
|
||||
|
||||
const QString& QgsRelation::id() const
|
||||
{
|
||||
return mRelationId;
|
||||
}
|
||||
|
||||
QString QgsRelation::referencingLayerId() const
|
||||
{
|
||||
return mReferencingLayerId;
|
||||
}
|
||||
|
||||
QgsVectorLayer* QgsRelation::referencingLayer() const
|
||||
{
|
||||
return mReferencingLayer;
|
||||
}
|
||||
|
||||
QString QgsRelation::referencedLayerId() const
|
||||
{
|
||||
return mReferencedLayerId;
|
||||
}
|
||||
|
||||
QgsVectorLayer* QgsRelation::referencedLayer() const
|
||||
{
|
||||
return mReferencedLayer;
|
||||
}
|
||||
|
||||
QList<QgsRelation::FieldPair> QgsRelation::fieldPairs() const
|
||||
{
|
||||
return mFieldPairs;
|
||||
}
|
||||
|
||||
bool QgsRelation::isValid() const
|
||||
{
|
||||
return mValid;
|
||||
}
|
||||
|
||||
void QgsRelation::updateRelationStatus()
|
||||
{
|
||||
const QMap<QString, QgsMapLayer*>& mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
|
||||
|
||||
mReferencingLayer = qobject_cast<QgsVectorLayer*>( mapLayers[mReferencingLayerId] );
|
||||
mReferencedLayer = qobject_cast<QgsVectorLayer*>( mapLayers[mReferencedLayerId] );
|
||||
|
||||
mValid = true;
|
||||
|
||||
if ( !mReferencedLayer || !mReferencingLayer )
|
||||
{
|
||||
mValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( mFieldPairs.count() < 1 )
|
||||
{
|
||||
mValid = false;
|
||||
}
|
||||
|
||||
Q_FOREACH( const FieldPair& fieldPair, mFieldPairs )
|
||||
{
|
||||
if ( -1 == mReferencingLayer->fieldNameIndex( fieldPair.first )
|
||||
|| -1 == mReferencedLayer->fieldNameIndex( fieldPair.second ) )
|
||||
{
|
||||
mValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelation::runChecks()
|
||||
{
|
||||
|
||||
}
|
227
src/core/qgsrelation.h
Normal file
227
src/core/qgsrelation.h
Normal file
@ -0,0 +1,227 @@
|
||||
/***************************************************************************
|
||||
qgsrelation.h
|
||||
--------------------------------------
|
||||
Date : 29.4.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSRELATION_H
|
||||
#define QGSRELATION_H
|
||||
|
||||
#include <QList>
|
||||
#include <QDomNode>
|
||||
#include <QPair>
|
||||
|
||||
#include "qgsfield.h"
|
||||
#include "qgsfeatureiterator.h"
|
||||
|
||||
class QgsVectorLayer;
|
||||
|
||||
class CORE_EXPORT QgsRelation
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Defines a relation between matchin fields of the two involved tables of a relation.
|
||||
* Often, a relation is only defined by just one FieldPair with the name of the foreign key
|
||||
* column of the referencing table as first element and the name of the primkary key column
|
||||
* of the referenced table as the second element.
|
||||
*
|
||||
*/
|
||||
class FieldPair : public QPair< QString, QString >
|
||||
{
|
||||
public:
|
||||
//! Default constructor: NULL strings
|
||||
FieldPair()
|
||||
: QPair< QString, QString >() {}
|
||||
|
||||
//! Constructor which takes two fields
|
||||
FieldPair( QString referencingField, QString referencedField )
|
||||
: QPair< QString, QString >( referencingField, referencedField ) {}
|
||||
|
||||
//! Get the name of the referencing field
|
||||
const QString& referencingField() const { return first; }
|
||||
//! Get the name of the referenced field
|
||||
const QString& referencedField() const { return second; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Default constructor. Creates an invalid relation.
|
||||
*/
|
||||
QgsRelation();
|
||||
|
||||
/**
|
||||
* Creates a relation from an XML structure. Used for reading .qgs projects.
|
||||
*
|
||||
* @param node The dom node containing the relation information
|
||||
*
|
||||
* @return A relation
|
||||
*/
|
||||
static QgsRelation createFromXML( const QDomNode& node );
|
||||
|
||||
/**
|
||||
* Writes a relation to an XML structure. Used for saving .qgs projects
|
||||
*
|
||||
* @param node The parent node in which the relation will be created
|
||||
* @param doc The document in which the relation will be saved
|
||||
*/
|
||||
void writeXML( QDomNode& node, QDomDocument& doc ) const;
|
||||
|
||||
/**
|
||||
* Set a name for this relation
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setRelationId( QString id );
|
||||
|
||||
/**
|
||||
* Set a name for this relation
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
void setRelationName( QString name );
|
||||
|
||||
/**
|
||||
* Set the referencing layer id. This layer will be searched in the registry.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setReferencingLayer( QString id );
|
||||
|
||||
/**
|
||||
* Set the referenced layer id. This layer will be searched in the registry.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setReferencedLayer( QString id );
|
||||
|
||||
/**
|
||||
* Add a field pairs which is part of this relation
|
||||
* The first element of each pair are the field names fo the foreign key.
|
||||
* The second element of each pair are the field names of the matching primary key.
|
||||
*
|
||||
* @param referencingField The field name on the referencing layer (FK)
|
||||
* @param referencedField The field name on the referenced layer (PK)
|
||||
*/
|
||||
void addFieldPair( QString referencingField, QString referencedField );
|
||||
|
||||
/**
|
||||
* Add a field pairs which is part of this relation
|
||||
* The first element of each pair are the field names fo the foreign key.
|
||||
* The second element of each pair are the field names of the matching primary key.
|
||||
*
|
||||
* @param fieldPair A pair of two strings
|
||||
*/
|
||||
void addFieldPair( FieldPair fieldPair );
|
||||
|
||||
/**
|
||||
* Creates an iterator which returns all the features on the referencing (child) layer
|
||||
* which have a foreign key pointing to the provided feature.
|
||||
*
|
||||
* @param feature A feature from the referenced (parent) layer
|
||||
*
|
||||
* @return An iterator with all the referenced features
|
||||
*/
|
||||
QgsFeatureIterator getRelatedFeatures( const QgsFeature& feature ) const;
|
||||
|
||||
/**
|
||||
* Creates a request to return all the features on the referencing (child) layer
|
||||
* which have a foreign key pointing to the provided feature.
|
||||
*
|
||||
* @param feature A feature from the referenced (parent) layer
|
||||
*
|
||||
* @return An request for all the referenced features
|
||||
*/
|
||||
QgsFeatureRequest getRelatedFeaturesRequest( const QgsFeature& feature ) const;
|
||||
|
||||
const QString name() const;
|
||||
|
||||
/**
|
||||
* The id
|
||||
* @return
|
||||
*/
|
||||
const QString& id() const;
|
||||
|
||||
/**
|
||||
* Access the referencing (child) layer's id
|
||||
* This is the layer which has the field(s) which point to another layer
|
||||
*
|
||||
* @return The id of the referencing layer
|
||||
*/
|
||||
QString referencingLayerId() const;
|
||||
|
||||
/**
|
||||
* Access the referencing (child) layer
|
||||
* This is the layer which has the field(s) which point to another layer
|
||||
*
|
||||
* @return The referencing layer
|
||||
*/
|
||||
QgsVectorLayer* referencingLayer() const;
|
||||
|
||||
/**
|
||||
* Access the referenced (parent) layer's id
|
||||
*
|
||||
* @return The id of the referenced layer
|
||||
*/
|
||||
QString referencedLayerId() const;
|
||||
|
||||
/**
|
||||
* Access the referenced (parent) layer
|
||||
*
|
||||
* @return referenced layer
|
||||
*/
|
||||
QgsVectorLayer* referencedLayer() const;
|
||||
|
||||
/**
|
||||
* Returns the field pairs which form this relation
|
||||
* The first element of each pair are the field names fo the foreign key.
|
||||
* The second element of each pair are the field names of the matching primary key.
|
||||
*
|
||||
* @return The fields forming the relation
|
||||
*/
|
||||
QList< FieldPair > fieldPairs() const;
|
||||
|
||||
/**
|
||||
* Returns the validity of this relation. Don't use the information if it's not valid.
|
||||
*
|
||||
* @return true if the relation is valid
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
protected:
|
||||
void updateRelationStatus();
|
||||
void runChecks();
|
||||
|
||||
private:
|
||||
/** Unique Id */
|
||||
QString mRelationId;
|
||||
/** Human redable name*/
|
||||
QString mRelationName;
|
||||
/** The child layer */
|
||||
QString mReferencingLayerId;
|
||||
/** The child layer */
|
||||
QgsVectorLayer* mReferencingLayer;
|
||||
/** The parent layer id */
|
||||
QString mReferencedLayerId;
|
||||
/** The parent layer */
|
||||
QgsVectorLayer* mReferencedLayer;
|
||||
/** A list of fields which define the relation.
|
||||
* In most cases there will be only one value, but multiple values
|
||||
* are supported for composited foreign keys.
|
||||
* The first field is on the referencing layer, the second on the referenced */
|
||||
QList< FieldPair > mFieldPairs;
|
||||
|
||||
bool mValid;
|
||||
};
|
||||
|
||||
// Register QgsRelation for usage with QVariant
|
||||
Q_DECLARE_METATYPE( QgsRelation )
|
||||
|
||||
#endif // QGSRELATION_H
|
172
src/core/qgsrelationmanager.cpp
Normal file
172
src/core/qgsrelationmanager.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/***************************************************************************
|
||||
qgsrelationmanager.cpp
|
||||
--------------------------------------
|
||||
Date : 1.3.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsrelationmanager.h"
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
QgsRelationManager::QgsRelationManager( QgsProject* project )
|
||||
: QObject( project )
|
||||
, mProject( project )
|
||||
{
|
||||
connect( project, SIGNAL( readProject( const QDomDocument& ) ), SLOT( readProject( const QDomDocument& ) ) );
|
||||
connect( project, SIGNAL( writeProject( QDomDocument& ) ), SLOT( writeProject( QDomDocument& ) ) );
|
||||
}
|
||||
|
||||
void QgsRelationManager::setRelations( const QList<QgsRelation>& relations )
|
||||
{
|
||||
mRelations.clear();
|
||||
foreach ( const QgsRelation& rel, relations )
|
||||
{
|
||||
addRelation( rel );
|
||||
}
|
||||
}
|
||||
|
||||
const QMap<QString, QgsRelation>& QgsRelationManager::relations() const
|
||||
{
|
||||
return mRelations;
|
||||
}
|
||||
|
||||
void QgsRelationManager::addRelation( const QgsRelation& relation )
|
||||
{
|
||||
if ( !relation.isValid() )
|
||||
return;
|
||||
|
||||
mRelations.insert( relation.id(), relation );
|
||||
|
||||
mProject->dirty( true );
|
||||
}
|
||||
|
||||
void QgsRelationManager::removeRelation( const QString& name )
|
||||
{
|
||||
mRelations.remove( name );
|
||||
}
|
||||
|
||||
void QgsRelationManager::removeRelation( const QgsRelation& relation )
|
||||
{
|
||||
mRelations.remove( relation.id() );
|
||||
}
|
||||
|
||||
QgsRelation QgsRelationManager::relation( const QString& id ) const
|
||||
{
|
||||
return mRelations.value( id );
|
||||
}
|
||||
|
||||
void QgsRelationManager::clear()
|
||||
{
|
||||
mRelations.clear();
|
||||
}
|
||||
|
||||
QList<QgsRelation> QgsRelationManager::referencingRelations( QgsVectorLayer* layer, int fieldIdx ) const
|
||||
{
|
||||
if ( !layer )
|
||||
{
|
||||
return mRelations.values();
|
||||
}
|
||||
|
||||
QList<QgsRelation> relations;
|
||||
|
||||
foreach ( const QgsRelation& rel, mRelations )
|
||||
{
|
||||
if ( rel.referencingLayer() == layer )
|
||||
{
|
||||
if ( fieldIdx != -2 )
|
||||
{
|
||||
bool containsField = false;
|
||||
foreach ( const QgsRelation::FieldPair& fp, rel.fieldPairs() )
|
||||
{
|
||||
if ( fieldIdx == layer->fieldNameIndex( fp.referencingField() ) )
|
||||
{
|
||||
containsField = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !containsField )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
relations.append( rel );
|
||||
}
|
||||
}
|
||||
|
||||
return relations;
|
||||
}
|
||||
|
||||
QList<QgsRelation> QgsRelationManager::referencedRelations( QgsVectorLayer* layer ) const
|
||||
{
|
||||
if ( !layer )
|
||||
{
|
||||
return mRelations.values();
|
||||
}
|
||||
|
||||
QList<QgsRelation> relations;
|
||||
|
||||
foreach ( const QgsRelation& rel, mRelations )
|
||||
{
|
||||
if ( rel.referencedLayer() == layer )
|
||||
{
|
||||
relations.append( rel );
|
||||
}
|
||||
}
|
||||
|
||||
return relations;
|
||||
}
|
||||
|
||||
void QgsRelationManager::readProject( const QDomDocument & doc )
|
||||
{
|
||||
mRelations.clear();
|
||||
|
||||
QDomNodeList nodes = doc.elementsByTagName( "relations" );
|
||||
if ( nodes.count() )
|
||||
{
|
||||
QDomNode node = nodes.item( 0 );
|
||||
QDomNodeList relationNodes = node.childNodes();
|
||||
int relCount = relationNodes.count();
|
||||
for ( int i = 0; i < relCount; ++i )
|
||||
{
|
||||
addRelation( QgsRelation::createFromXML( relationNodes.at( i ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "No relations data present in this document" );
|
||||
}
|
||||
|
||||
emit( relationsLoaded() );
|
||||
}
|
||||
|
||||
void QgsRelationManager::writeProject( QDomDocument & doc )
|
||||
{
|
||||
QDomNodeList nl = doc.elementsByTagName( "qgis" );
|
||||
if ( !nl.count() )
|
||||
{
|
||||
QgsDebugMsg( "Unable to find qgis element in project file" );
|
||||
return;
|
||||
}
|
||||
QDomNode qgisNode = nl.item( 0 ); // there should only be one
|
||||
|
||||
QDomElement relationsNode = doc.createElement( "relations" );
|
||||
qgisNode.appendChild( relationsNode );
|
||||
|
||||
foreach ( const QgsRelation& relation, mRelations )
|
||||
{
|
||||
relation.writeXML( relationsNode, doc );
|
||||
}
|
||||
}
|
66
src/core/qgsrelationmanager.h
Normal file
66
src/core/qgsrelationmanager.h
Normal file
@ -0,0 +1,66 @@
|
||||
/***************************************************************************
|
||||
qgsrelationmanager.h
|
||||
--------------------------------------
|
||||
Date : 1.3.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSRELATIONMANAGER_H
|
||||
#define QGSRELATIONMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPair>
|
||||
#include <QDomNode>
|
||||
#include <QDomDocument>
|
||||
|
||||
#include "qgsrelation.h"
|
||||
|
||||
class QgsProject;
|
||||
class QgsVectorLayer;
|
||||
|
||||
/**
|
||||
* This class manages a set of relations between layers.
|
||||
*/
|
||||
class CORE_EXPORT QgsRelationManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsRelationManager( QgsProject* project );
|
||||
|
||||
void setRelations( const QList<QgsRelation>& relations );
|
||||
const QMap<QString, QgsRelation>& relations() const;
|
||||
void addRelation( const QgsRelation& relation );
|
||||
void removeRelation( const QString& name );
|
||||
void removeRelation( const QgsRelation& relation );
|
||||
QgsRelation relation( const QString& id ) const;
|
||||
void clear();
|
||||
|
||||
QList<QgsRelation> referencingRelations( QgsVectorLayer* layer = NULL, int fieldIdx = -2 ) const;
|
||||
QList<QgsRelation> referencedRelations( QgsVectorLayer* layer = NULL ) const;
|
||||
|
||||
signals:
|
||||
void relationsLoaded();
|
||||
|
||||
public slots:
|
||||
|
||||
private slots:
|
||||
void readProject( const QDomDocument &doc );
|
||||
void writeProject( QDomDocument &doc );
|
||||
|
||||
private:
|
||||
/** The references */
|
||||
QMap<QString, QgsRelation> mRelations;
|
||||
|
||||
QgsProject* mProject;
|
||||
};
|
||||
|
||||
#endif // QGSRELATIONMANAGER_H
|
@ -168,11 +168,13 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
||||
*/
|
||||
virtual void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );
|
||||
|
||||
/**Returns the possible enum values of an attribute. Returns an empty stringlist if a provider does not support enum types
|
||||
or if the given attribute is not an enum type.
|
||||
/**
|
||||
* Returns the possible enum values of an attribute. Returns an empty stringlist if a provider does not support enum types
|
||||
* or if the given attribute is not an enum type.
|
||||
* @param index the index of the attribute
|
||||
* @param enumList reference to the list to fill
|
||||
@note: added in version 1.2*/
|
||||
* @note: added in version 1.2
|
||||
*/
|
||||
virtual void enumValues( int index, QStringList& enumList ) { Q_UNUSED( index ); enumList.clear(); }
|
||||
|
||||
/**
|
||||
@ -260,7 +262,9 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
||||
*/
|
||||
int fieldNameIndex( const QString& fieldName ) const;
|
||||
|
||||
/**Return a map where the key is the name of the field and the value is its index*/
|
||||
/**
|
||||
* Return a map where the key is the name of the field and the value is its index
|
||||
*/
|
||||
QMap<QString, int> fieldNameMap() const;
|
||||
|
||||
/**
|
||||
@ -313,17 +317,20 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
||||
/** Returns a list of available encodings */
|
||||
static const QStringList &availableEncodings();
|
||||
|
||||
/* provider has errors to report
|
||||
/**
|
||||
* Provider has errors to report
|
||||
* @note added in 1.7
|
||||
*/
|
||||
bool hasErrors();
|
||||
|
||||
/* clear recorded errors
|
||||
/**
|
||||
* Clear recorded errors
|
||||
* @note added in 1.7
|
||||
*/
|
||||
void clearErrors();
|
||||
|
||||
/* get recorded errors
|
||||
/**
|
||||
* Get recorded errors
|
||||
* @note added in 1.7
|
||||
*/
|
||||
QStringList errors();
|
||||
@ -350,13 +357,13 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
||||
/** should provider fetch also features that don't have geometry? */
|
||||
bool mFetchFeaturesWithoutGeom;
|
||||
|
||||
/**True if geometry should be added to the features in nextFeature calls*/
|
||||
/** True if geometry should be added to the features in nextFeature calls*/
|
||||
bool mFetchGeom;
|
||||
|
||||
/**List of attribute indices to fetch with nextFeature calls*/
|
||||
/** List of attribute indices to fetch with nextFeature calls*/
|
||||
QgsAttributeList mAttributesToFetch;
|
||||
|
||||
/**The names of the providers native types*/
|
||||
/** The names of the providers native types*/
|
||||
QList< NativeType > mNativeTypes;
|
||||
|
||||
void pushError( QString msg );
|
||||
@ -368,7 +375,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
||||
/** old notation **/
|
||||
QMap<QString, QVariant::Type> mOldTypeList;
|
||||
|
||||
// list of errors
|
||||
/** list of errors */
|
||||
QStringList mErrors;
|
||||
|
||||
static QStringList smEncodings;
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "qgspoint.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsrendercontext.h"
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
@ -176,6 +177,8 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
|
||||
}
|
||||
|
||||
connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( selectionChanged() ) );
|
||||
|
||||
connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
|
||||
} // QgsVectorLayer ctor
|
||||
|
||||
|
||||
@ -2117,6 +2120,13 @@ QgsAttributeEditorElement* QgsVectorLayer::attributeEditorElementFromDomElement(
|
||||
int idx = *( dataProvider()->fieldNameMap() ).find( name );
|
||||
newElement = new QgsAttributeEditorField( name, idx, parent );
|
||||
}
|
||||
else if ( elem.tagName() == "attributeEditorRelation" )
|
||||
{
|
||||
// At this time, the relations are not loaded
|
||||
// So we only grab the id and delegate the rest to onRelationsLoaded()
|
||||
QString name = elem.attribute( "name" );
|
||||
newElement = new QgsAttributeEditorRelation( name, elem.attribute( "relation", "[None]" ), parent );
|
||||
}
|
||||
return newElement;
|
||||
}
|
||||
|
||||
@ -3834,6 +3844,23 @@ void QgsVectorLayer::invalidateSymbolCountedFlag()
|
||||
mSymbolFeatureCounted = false;
|
||||
}
|
||||
|
||||
void QgsVectorLayer::onRelationsLoaded()
|
||||
{
|
||||
Q_FOREACH( QgsAttributeEditorElement* elem, mAttributeEditorElements )
|
||||
{
|
||||
if ( elem->type() == QgsAttributeEditorElement::AeTypeContainer )
|
||||
{
|
||||
QgsAttributeEditorContainer* cont = dynamic_cast< QgsAttributeEditorContainer* >( elem );
|
||||
QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
|
||||
Q_FOREACH( QgsAttributeEditorElement* relElem, relations )
|
||||
{
|
||||
QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
|
||||
rel->init( QgsProject::instance()->relationManager() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QgsVectorLayer::ValueRelationData &QgsVectorLayer::valueRelation( int idx )
|
||||
{
|
||||
const QgsFields &fields = pendingFields();
|
||||
@ -3855,6 +3882,11 @@ QgsVectorLayer::ValueRelationData &QgsVectorLayer::valueRelation( int idx )
|
||||
return mValueRelations[fieldName];
|
||||
}
|
||||
|
||||
QList<QgsRelation> QgsVectorLayer::referencingRelations( int idx )
|
||||
{
|
||||
return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
|
||||
}
|
||||
|
||||
QList<QgsAttributeEditorElement*> &QgsVectorLayer::attributeEditorElements()
|
||||
{
|
||||
return mAttributeEditorElements;
|
||||
@ -4057,3 +4089,18 @@ bool QgsVectorLayer::applyNamedStyle( QString namedStyle, QString errorMsg )
|
||||
|
||||
return readSymbology( myRoot, errorMsg );
|
||||
}
|
||||
|
||||
|
||||
QDomElement QgsAttributeEditorRelation::toDomElement( QDomDocument& doc ) const
|
||||
{
|
||||
QDomElement elem = doc.createElement( "attributeEditorRelation" );
|
||||
elem.setAttribute( "name", mName );
|
||||
elem.setAttribute( "relation", mRelation.id() );
|
||||
return elem;
|
||||
}
|
||||
|
||||
bool QgsAttributeEditorRelation::init( QgsRelationManager* relationManager )
|
||||
{
|
||||
mRelation = relationManager->relation( mRelationId );
|
||||
return mRelation.isValid();
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "qgsfield.h"
|
||||
#include "qgssnapper.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgsrelation.h"
|
||||
|
||||
class QPainter;
|
||||
class QImage;
|
||||
@ -44,6 +45,8 @@ class QgsGeometryVertexIndex;
|
||||
class QgsLabel;
|
||||
class QgsMapToPixel;
|
||||
class QgsRectangle;
|
||||
class QgsRelation;
|
||||
class QgsRelationManager;
|
||||
class QgsVectorDataProvider;
|
||||
class QgsSingleSymbolRendererV2;
|
||||
class QgsRectangle;
|
||||
@ -68,6 +71,7 @@ class CORE_EXPORT QgsAttributeEditorElement : public QObject
|
||||
{
|
||||
AeTypeContainer,
|
||||
AeTypeField,
|
||||
AeTypeRelation,
|
||||
AeTypeInvalid
|
||||
};
|
||||
|
||||
@ -121,6 +125,37 @@ class CORE_EXPORT QgsAttributeEditorField : public QgsAttributeEditorElement
|
||||
int mIdx;
|
||||
};
|
||||
|
||||
/** @note Added in 2.1 */
|
||||
class CORE_EXPORT QgsAttributeEditorRelation : public QgsAttributeEditorElement
|
||||
{
|
||||
public:
|
||||
QgsAttributeEditorRelation( QString name , const QString relationId, QObject *parent )
|
||||
: QgsAttributeEditorElement( AeTypeRelation, name, parent )
|
||||
, mRelationId( relationId ) {}
|
||||
|
||||
QgsAttributeEditorRelation( QString name , const QgsRelation& relation, QObject *parent )
|
||||
: QgsAttributeEditorElement( AeTypeRelation, name, parent )
|
||||
, mRelationId( relation.id() )
|
||||
, mRelation( relation ) {}
|
||||
|
||||
~QgsAttributeEditorRelation() {}
|
||||
|
||||
virtual QDomElement toDomElement( QDomDocument& doc ) const;
|
||||
const QgsRelation& relation() const { return mRelation; }
|
||||
|
||||
/**
|
||||
* Initializes the relation from the id
|
||||
*
|
||||
* @param relManager The relation manager to use for the initialization
|
||||
* @return true if the relation was found in the relationmanager
|
||||
*/
|
||||
bool init( QgsRelationManager* relManager );
|
||||
|
||||
private:
|
||||
QString mRelationId;
|
||||
QgsRelation mRelation;
|
||||
};
|
||||
|
||||
/** @note added in 1.7 */
|
||||
struct CORE_EXPORT QgsVectorJoinInfo
|
||||
{
|
||||
@ -1202,6 +1237,22 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
**/
|
||||
ValueRelationData &valueRelation( int idx );
|
||||
|
||||
/**
|
||||
* Get relations, where the foreign key is on this layer
|
||||
*
|
||||
* @param idx Only get relations, where idx forms part of the foreign key
|
||||
* @return A list of relations
|
||||
*/
|
||||
QList<QgsRelation> referencingRelations( int idx );
|
||||
|
||||
/**
|
||||
* Get relations, where the foreign key is on another layer, referencing this layer
|
||||
*
|
||||
* @param idx Only get relations, where idx forms part of the referenced key
|
||||
* @return A list of relations
|
||||
*/
|
||||
QList<QgsRelation> referencedRelations( int idx );
|
||||
|
||||
/**access date format
|
||||
* @note added in 1.9
|
||||
*/
|
||||
@ -1446,6 +1497,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
void committedAttributeValuesChanges( const QString& layerId, const QgsChangedAttributesMap& changedAttributesValues );
|
||||
void committedGeometriesChanges( const QString& layerId, const QgsGeometryMap& changedGeometries );
|
||||
|
||||
void saveLayerToProject();
|
||||
|
||||
/** Emitted when the font family defined for labeling layer is not found on system
|
||||
* @note added in 1.9
|
||||
*/
|
||||
@ -1460,6 +1513,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
/** Signal emitted when setLayerTransparency() is called */
|
||||
void layerTransparencyChanged( int layerTransparency );
|
||||
|
||||
private slots:
|
||||
void onRelationsLoaded();
|
||||
|
||||
protected:
|
||||
/** Set the extent */
|
||||
void setExtent( const QgsRectangle &rect );
|
||||
|
@ -26,7 +26,7 @@ QgsVectorLayerCache::QgsVectorLayerCache( QgsVectorLayer* layer, int cacheSize,
|
||||
mCache.setMaxCost( cacheSize );
|
||||
|
||||
connect( mLayer, SIGNAL( featureDeleted( QgsFeatureId ) ), SLOT( featureDeleted( QgsFeatureId ) ) );
|
||||
connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), SLOT( featureAdded( QgsFeatureId ) ) );
|
||||
connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), SLOT( onFeatureAdded( QgsFeatureId ) ) );
|
||||
connect( mLayer, SIGNAL( layerDeleted() ), SLOT( layerDeleted() ) );
|
||||
|
||||
setCacheGeometry( true );
|
||||
@ -200,7 +200,7 @@ void QgsVectorLayerCache::featureDeleted( QgsFeatureId fid )
|
||||
mCache.remove( fid );
|
||||
}
|
||||
|
||||
void QgsVectorLayerCache::featureAdded( QgsFeatureId fid )
|
||||
void QgsVectorLayerCache::onFeatureAdded( QgsFeatureId fid )
|
||||
{
|
||||
if ( mFullCache )
|
||||
{
|
||||
@ -212,6 +212,7 @@ void QgsVectorLayerCache::featureAdded( QgsFeatureId fid )
|
||||
QgsFeature feat;
|
||||
featureAtId( fid, feat );
|
||||
}
|
||||
emit( featureAdded( fid ) );
|
||||
}
|
||||
|
||||
void QgsVectorLayerCache::attributeAdded( int field )
|
||||
|
@ -242,10 +242,19 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject
|
||||
*/
|
||||
void attributeValueChanged( const QgsFeatureId& fid, const int& field, const QVariant &value );
|
||||
|
||||
/**
|
||||
* Is emitted, when a new feature has been added to the layer and this cache.
|
||||
* You should connect to this signal instead of the layers', if you want to be sure
|
||||
* that this cache has updated information for the new feature
|
||||
*
|
||||
* @param fid The featureid of the changed feature
|
||||
*/
|
||||
void featureAdded( QgsFeatureId fid );
|
||||
|
||||
private slots:
|
||||
void onAttributeValueChanged( QgsFeatureId fid, int field, const QVariant& value );
|
||||
void featureDeleted( QgsFeatureId fid );
|
||||
void featureAdded( QgsFeatureId fid );
|
||||
void onFeatureAdded( QgsFeatureId fid );
|
||||
void attributeAdded( int field );
|
||||
void attributeDeleted( int field );
|
||||
void geometryChanged( QgsFeatureId fid, QgsGeometry& geom );
|
||||
|
@ -54,35 +54,47 @@ editorwidgets/core/qgseditorconfigwidget.cpp
|
||||
editorwidgets/core/qgseditorwidgetfactory.cpp
|
||||
editorwidgets/core/qgseditorwidgetregistry.cpp
|
||||
editorwidgets/core/qgseditorwidgetwrapper.cpp
|
||||
editorwidgets/qgsrelationreferencewidget.cpp
|
||||
editorwidgets/qgsrelationreferencefactory.cpp
|
||||
editorwidgets/qgsrelreferenceconfigdlg.cpp
|
||||
|
||||
qgisgui.cpp
|
||||
qgisinterface.cpp
|
||||
qgsannotationitem.cpp
|
||||
qgsattributeeditor.cpp
|
||||
qgsattributedialog.cpp
|
||||
qgsbusyindicatordialog.cpp
|
||||
qgslegendinterface.cpp
|
||||
qgspluginmanagerinterface.cpp
|
||||
qgsattributeeditor.cpp
|
||||
qgsattributeeditorcontext.cpp
|
||||
qgsblendmodecombobox.cpp
|
||||
qgsbusyindicatordialog.cpp
|
||||
qgscharacterselectdialog.cpp
|
||||
qgscollapsiblegroupbox.cpp
|
||||
qgscolorbutton.cpp
|
||||
qgscolordialog.cpp
|
||||
qgscomposerview.cpp
|
||||
qgscomposerruler.cpp
|
||||
qgscomposerview.cpp
|
||||
qgscredentialdialog.cpp
|
||||
qgscursors.cpp
|
||||
qgsdatadefinedbutton.cpp
|
||||
qgsdetaileditemdata.cpp
|
||||
qgsdetaileditemdelegate.cpp
|
||||
qgsdetaileditemwidget.cpp
|
||||
qgsdetaileditemdata.cpp
|
||||
qgsdialog.cpp
|
||||
qgsencodingfiledialog.cpp
|
||||
qgserrordialog.cpp
|
||||
qgsfiledropedit.cpp
|
||||
qgsexpressionbuilderdialog.cpp
|
||||
qgsexpressionbuilderwidget.cpp
|
||||
qgsexpressionhighlighter.cpp
|
||||
qgsexpressionselectiondialog.cpp
|
||||
qgsfeatureselectiondlg.cpp
|
||||
qgsfieldvalidator.cpp
|
||||
qgsfiledropedit.cpp
|
||||
qgsfilterlineedit.cpp
|
||||
qgsformannotationitem.cpp
|
||||
qgshtmlannotationitem.cpp
|
||||
qgshighlight.cpp
|
||||
qgsgenericprojectionselector.cpp
|
||||
qgshighlight.cpp
|
||||
qgshtmlannotationitem.cpp
|
||||
qgslegendinterface.cpp
|
||||
qgsludialog.cpp
|
||||
qgsmanageconnectionsdialog.cpp
|
||||
qgsmapcanvas.cpp
|
||||
qgsmapcanvasitem.cpp
|
||||
@ -99,6 +111,7 @@ qgsmessagebar.cpp
|
||||
qgsmessagebaritem.cpp
|
||||
qgsmessageviewer.cpp
|
||||
qgsmessagelogviewer.cpp
|
||||
qgsmessageviewer.cpp
|
||||
qgsnewhttpconnection.cpp
|
||||
qgsnewvectorlayerdialog.cpp
|
||||
qgsnumericsortlistviewitem.cpp
|
||||
@ -106,26 +119,23 @@ qgsoptionsdialogbase.cpp
|
||||
qgscredentialdialog.cpp
|
||||
qgsattributeeditorcontext.cpp
|
||||
qgsowssourceselect.cpp
|
||||
qgspluginmanagerinterface.cpp
|
||||
qgsprojectbadlayerguihandler.cpp
|
||||
qgsprojectionselector.cpp
|
||||
qgsrasterlayersaveasdialog.cpp
|
||||
qgsquerybuilder.cpp
|
||||
qgsrasterformatsaveoptionswidget.cpp
|
||||
qgsrasterlayersaveasdialog.cpp
|
||||
qgsrasterpyramidsoptionswidget.cpp
|
||||
qgsrelationadddlg.cpp
|
||||
qgsrelationeditor.cpp
|
||||
qgsrelationmanagerdialog.cpp
|
||||
qgsrubberband.cpp
|
||||
qgsscalecombobox.cpp
|
||||
qgssearchquerybuilder.cpp
|
||||
qgssublayersdialog.cpp
|
||||
qgssvgannotationitem.cpp
|
||||
qgstextannotationitem.cpp
|
||||
qgsvertexmarker.cpp
|
||||
qgsludialog.cpp
|
||||
qgssearchquerybuilder.cpp
|
||||
qgsexpressionbuilderwidget.cpp
|
||||
qgsexpressionbuilderdialog.cpp
|
||||
qgsexpressionselectiondialog.cpp
|
||||
qgsexpressionhighlighter.cpp
|
||||
qgsquerybuilder.cpp
|
||||
qgscollapsiblegroupbox.cpp
|
||||
qgsfilterlineedit.cpp
|
||||
qgssublayersdialog.cpp
|
||||
)
|
||||
|
||||
IF (WITH_TOUCH)
|
||||
@ -191,27 +201,37 @@ attributetable/qgsvectorlayerselectionmanager.h
|
||||
editorwidgets/core/qgseditorconfigwidget.h
|
||||
editorwidgets/core/qgseditorwidgetregistry.h
|
||||
editorwidgets/core/qgseditorwidgetwrapper.h
|
||||
editorwidgets/qgsrelationreferencewidget.h
|
||||
editorwidgets/qgsrelreferenceconfigdlg.h
|
||||
|
||||
qgisinterface.h
|
||||
qgsattributedialog.h
|
||||
qgsattributeeditor.h
|
||||
qgsblendmodecombobox.h
|
||||
qgsbusyindicatordialog.h
|
||||
qgscharacterselectdialog.h
|
||||
qgscollapsiblegroupbox.h
|
||||
qgscolordialog.h
|
||||
qgscomposerview.h
|
||||
qgscredentialdialog.h
|
||||
qgsdatadefinedbutton.h
|
||||
qgsdetaileditemdelegate.h
|
||||
qgsdetaileditemwidget.h
|
||||
qgsdialog.h
|
||||
qgslegendinterface.h
|
||||
qgspluginmanagerinterface.h
|
||||
qgisinterface.h
|
||||
qgsencodingfiledialog.h
|
||||
qgserrordialog.h
|
||||
qgsexpressionbuilderwidget.h
|
||||
qgsexpressionhighlighter.h
|
||||
qgsexpressionselectiondialog.h
|
||||
qgsfeatureselectiondlg.h
|
||||
qgsfieldvalidator.h
|
||||
qgsfilterlineedit.h
|
||||
qgsformannotationitem.h
|
||||
qgshtmlannotationitem.h
|
||||
qgsgenericprojectionselector.h
|
||||
qgshtmlannotationitem.h
|
||||
qgslegendinterface.h
|
||||
qgslonglongvalidator.h
|
||||
qgsludialog.h
|
||||
qgsmanageconnectionsdialog.h
|
||||
qgsmapcanvas.h
|
||||
qgsmapoverviewcanvas.h
|
||||
@ -219,28 +239,24 @@ qgsmaptoolemitpoint.h
|
||||
qgsmaptoolidentify.h
|
||||
qgsmessagebaritem.h
|
||||
qgsmessagebar.h
|
||||
qgsmessageviewer.h
|
||||
qgsmessagelogviewer.h
|
||||
qgsmessageviewer.h
|
||||
qgsnewhttpconnection.h
|
||||
qgsnewvectorlayerdialog.h
|
||||
qgsoptionsdialogbase.h
|
||||
qgscredentialdialog.h
|
||||
qgsowssourceselect.h
|
||||
qgsprojectionselector.h
|
||||
qgsrasterlayersaveasdialog.h
|
||||
qgsrasterformatsaveoptionswidget.h
|
||||
qgsrasterpyramidsoptionswidget.h
|
||||
qgsludialog.h
|
||||
qgspluginmanagerinterface.h
|
||||
qgsprojectbadlayerguihandler.h
|
||||
qgslonglongvalidator.h
|
||||
qgssearchquerybuilder.h
|
||||
qgsscalecombobox.h
|
||||
qgsexpressionbuilderwidget.h
|
||||
qgsexpressionhighlighter.h
|
||||
qgsexpressionselectiondialog.h
|
||||
qgsprojectionselector.h
|
||||
qgsquerybuilder.h
|
||||
qgscollapsiblegroupbox.h
|
||||
qgsfilterlineedit.h
|
||||
qgsrasterformatsaveoptionswidget.h
|
||||
qgsrasterlayersaveasdialog.h
|
||||
qgsrasterpyramidsoptionswidget.h
|
||||
qgsrelationadddlg.h
|
||||
qgsrelationeditor.h
|
||||
qgsrelationmanagerdialog.h
|
||||
qgsscalecombobox.h
|
||||
qgssearchquerybuilder.h
|
||||
qgssublayersdialog.h
|
||||
)
|
||||
|
||||
@ -251,14 +267,25 @@ QT4_WRAP_CPP(QGIS_GUI_MOC_SRCS ${QGIS_GUI_MOC_HDRS})
|
||||
SET(QGIS_GUI_HDRS
|
||||
qgisgui.h
|
||||
qgisinterface.h
|
||||
qgsattributeeditor.h
|
||||
qgsattributedialog.h
|
||||
qgsattributeeditorcontext.h
|
||||
qgsbusyindicatordialog.h
|
||||
qgscharacterselectdialog.h
|
||||
qgscollapsiblegroupbox.h
|
||||
qgscolordialog.h
|
||||
qgscredentialdialog.h
|
||||
qgscursors.h
|
||||
qgsdatadefinedbutton.h
|
||||
qgsencodingfiledialog.h
|
||||
qgsexpressionbuilderdialog.h
|
||||
qgsexpressionbuilderwidget.h
|
||||
qgsexpressionhighlighter.h
|
||||
qgsexpressionselectiondialog.h
|
||||
qgsfeatureselectiondlg.h
|
||||
qgsfieldvalidator.h
|
||||
qgsfiledropedit.h
|
||||
qgsfilterlineedit.h
|
||||
qgsgenericprojectionselector.h
|
||||
qgshighlight.h
|
||||
qgsmapcanvas.h
|
||||
@ -266,6 +293,7 @@ qgsmapcanvasitem.h
|
||||
qgsmapcanvasmap.h
|
||||
qgsmapcanvassnapper.h
|
||||
qgsmapoverviewcanvas.h
|
||||
qgsmaptip.h
|
||||
qgsmaptool.h
|
||||
qgsmaptoolemitpoint.h
|
||||
qgsmaptoolidentify.h
|
||||
@ -275,25 +303,15 @@ qgsmessagebaritem.h
|
||||
qgsmessagebar.h
|
||||
qgsmessageviewer.h
|
||||
qgsoptionsdialogbase.h
|
||||
qgscredentialdialog.h
|
||||
qgsowssourceselect.h
|
||||
qgsprojectionselector.h
|
||||
qgsrelationeditor.h
|
||||
qgsrubberband.h
|
||||
qgsvertexmarker.h
|
||||
qgsmaptip.h
|
||||
qgsscalecombobox.h
|
||||
qgsblendmodecombobox.h
|
||||
qgssearchquerybuilder.h
|
||||
qgsattributeeditor.h
|
||||
qgsattributedialog.h
|
||||
qgsfieldvalidator.h
|
||||
qgsexpressionbuilderwidget.h
|
||||
qgsexpressionbuilderdialog.h
|
||||
qgsexpressionselectiondialog.h
|
||||
qgsexpressionhighlighter.h
|
||||
qgscollapsiblegroupbox.h
|
||||
qgsfilterlineedit.h
|
||||
qgssublayersdialog.h
|
||||
qgsvectorlayertools.h
|
||||
qgsvertexmarker.h
|
||||
qgsnumericsortlistviewitem.h
|
||||
qgsannotationitem.h
|
||||
qgstextannotationitem.h
|
||||
@ -319,6 +337,9 @@ editorwidgets/core/qgseditorconfigwidget.h
|
||||
editorwidgets/core/qgseditorwidgetfactory.h
|
||||
editorwidgets/core/qgseditorwidgetregistry.h
|
||||
editorwidgets/core/qgseditorwidgetwrapper.h
|
||||
editorwidgets/qgsrelationreferencefactory.h
|
||||
editorwidgets/qgsrelationreferencewidget.h
|
||||
editorwidgets/qgsrelreferenceconfigdlg.h
|
||||
|
||||
raster/qgsrasterrendererwidget.h
|
||||
)
|
||||
|
@ -21,13 +21,11 @@
|
||||
#include "qgsmessagelog.h"
|
||||
|
||||
|
||||
QgsEditorWidgetRegistry *QgsEditorWidgetRegistry::sInstance = 0;
|
||||
QgsEditorWidgetRegistry QgsEditorWidgetRegistry::sInstance;
|
||||
|
||||
QgsEditorWidgetRegistry* QgsEditorWidgetRegistry::instance()
|
||||
{
|
||||
if( !sInstance )
|
||||
sInstance = new QgsEditorWidgetRegistry();
|
||||
return sInstance;
|
||||
return &sInstance;
|
||||
}
|
||||
|
||||
QgsEditorWidgetRegistry::QgsEditorWidgetRegistry()
|
||||
|
@ -112,7 +112,7 @@ class GUI_EXPORT QgsEditorWidgetRegistry : public QObject
|
||||
|
||||
private:
|
||||
QMap<QString, QgsEditorWidgetFactory*> mWidgetFactories;
|
||||
static QgsEditorWidgetRegistry *sInstance;
|
||||
static QgsEditorWidgetRegistry sInstance;
|
||||
};
|
||||
|
||||
|
||||
|
59
src/gui/editorwidgets/qgsrelationreferencefactory.cpp
Normal file
59
src/gui/editorwidgets/qgsrelationreferencefactory.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
qgsrelationreferencefactory.cpp
|
||||
--------------------------------------
|
||||
Date : 29.5.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsrelationreferencefactory.h"
|
||||
|
||||
#include "qgsrelationreferencewidget.h"
|
||||
#include "qgsrelreferenceconfigdlg.h"
|
||||
|
||||
QgsRelationReferenceFactory::QgsRelationReferenceFactory( QgsAttributeEditorContext context, QString name )
|
||||
: QgsEditorWidgetFactory( name )
|
||||
, mEditorContext( context )
|
||||
{
|
||||
}
|
||||
|
||||
QgsEditorWidgetWrapper* QgsRelationReferenceFactory::create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const
|
||||
{
|
||||
return new QgsRelationReferenceWidget( vl, fieldIdx, editor, mEditorContext, parent );
|
||||
}
|
||||
|
||||
QgsEditorConfigWidget* QgsRelationReferenceFactory::configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const
|
||||
{
|
||||
return new QgsRelReferenceConfigDlg( vl, fieldIdx, parent );
|
||||
}
|
||||
|
||||
QgsEditorWidgetConfig QgsRelationReferenceFactory::readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx )
|
||||
{
|
||||
Q_UNUSED( layer );
|
||||
Q_UNUSED( fieldIdx );
|
||||
QMap<QString, QVariant> cfg;
|
||||
|
||||
cfg.insert( "AllowNULL", configElement.attribute( "AllowNULL" ) == "1" );
|
||||
cfg.insert( "ShowForm", configElement.attribute( "ShowForm" ) == "1" );
|
||||
cfg.insert( "Relation", configElement.attribute( "Relation" ) );
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
void QgsRelationReferenceFactory::writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx )
|
||||
{
|
||||
Q_UNUSED( doc );
|
||||
Q_UNUSED( layer );
|
||||
Q_UNUSED( fieldIdx );
|
||||
|
||||
configElement.setAttribute( "AllowNULL", config["AllowNULL"].toBool() );
|
||||
configElement.setAttribute( "ShowForm", config["ShowForm"].toBool() );
|
||||
configElement.setAttribute( "Relation", config["Relation"].toString() );
|
||||
}
|
79
src/gui/editorwidgets/qgsrelationreferencefactory.h
Normal file
79
src/gui/editorwidgets/qgsrelationreferencefactory.h
Normal file
@ -0,0 +1,79 @@
|
||||
/***************************************************************************
|
||||
qgsrelationreferencefactory.h
|
||||
--------------------------------------
|
||||
Date : 29.5.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSRELATIONREFERENCEFACTORY_H
|
||||
#define QGSRELATIONREFERENCEFACTORY_H
|
||||
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
|
||||
class GUI_EXPORT QgsRelationReferenceFactory : public QgsEditorWidgetFactory
|
||||
{
|
||||
public:
|
||||
QgsRelationReferenceFactory( QgsAttributeEditorContext context, QString name );
|
||||
|
||||
/**
|
||||
* Override this in your implementation.
|
||||
* Create a new editor widget wrapper. Call {@link QgsEditorWidgetRegistry::create()}
|
||||
* instead of calling this method directly.
|
||||
*
|
||||
* @param vl The vector layer on which this widget will act
|
||||
* @param fieldIdx The field index on which this widget will act
|
||||
* @param editor An editor widget if already existent. If NULL is provided, a new widget will be created.
|
||||
* @param parent The parent for the wrapper class and any created widget.
|
||||
*
|
||||
* @return A new widget wrapper
|
||||
*/
|
||||
virtual QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const;
|
||||
|
||||
/**
|
||||
* Override this in your implementation.
|
||||
* Create a new configuration widget for this widget type.
|
||||
*
|
||||
* @param vl The layer for which the widget will be created
|
||||
* @param fieldIdx The field index for which the widget will be created
|
||||
* @param parent The parent widget of the created config widget
|
||||
*
|
||||
* @return A configuration widget
|
||||
*/
|
||||
virtual QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const;
|
||||
|
||||
/**
|
||||
* Read the config from an XML file and map it to a proper {@link QgsEditorWidgetConfig}.
|
||||
*
|
||||
* @param configElement The configuration element from the project file
|
||||
* @param layer The layer for which this configuration applies
|
||||
* @param fieldIdx The field on the layer for which this configuration applies
|
||||
*
|
||||
* @return A configuration object. This will be passed to your widget wrapper later on
|
||||
*/
|
||||
virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx );
|
||||
|
||||
/**
|
||||
* Serialize your configuration and save it in a xml doc.
|
||||
*
|
||||
* @param config The configuration to serialize
|
||||
* @param configElement The element, where you can write your configuration into
|
||||
* @param doc The document. You can use this to create new nodes
|
||||
* @param layer The layer for which this configuration applies
|
||||
* @param fieldIdx The field on the layer for which this configuration applies
|
||||
*/
|
||||
virtual void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx );
|
||||
|
||||
private:
|
||||
QgsAttributeEditorContext mEditorContext;
|
||||
};
|
||||
|
||||
#endif // QGSRELATIONREFERENCEFACTORY_H
|
202
src/gui/editorwidgets/qgsrelationreferencewidget.cpp
Normal file
202
src/gui/editorwidgets/qgsrelationreferencewidget.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
/***************************************************************************
|
||||
qgsrelationreferencewidget.cpp
|
||||
--------------------------------------
|
||||
Date : 20.4.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsrelationreferencewidget.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QDialog>
|
||||
|
||||
#include "qgsattributedialog.h"
|
||||
#include "qgscollapsiblegroupbox.h"
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsrelreferenceconfigdlg.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
QgsRelationReferenceWidget::QgsRelationReferenceWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QgsAttributeEditorContext context, QWidget* parent )
|
||||
: QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
|
||||
, mInitialValueAssigned( false )
|
||||
, mComboBox( NULL )
|
||||
, mAttributeEditorFrame( NULL )
|
||||
, mAttributeEditorLayout( NULL )
|
||||
, mAttributeEditorButton( NULL )
|
||||
, mReferencedLayer( NULL )
|
||||
, mAttributeDialog( NULL )
|
||||
, mEditorContext( context )
|
||||
{
|
||||
}
|
||||
|
||||
QWidget* QgsRelationReferenceWidget::createWidget( QWidget* parent )
|
||||
{
|
||||
return new QWidget( parent );
|
||||
}
|
||||
|
||||
void QgsRelationReferenceWidget::initWidget( QWidget* editor )
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout( editor );
|
||||
editor->setLayout( layout );
|
||||
|
||||
mComboBox = new QComboBox( editor );
|
||||
layout->addWidget( mComboBox, 0, 0, 1, 1 );
|
||||
|
||||
if ( config( "ShowForm", true ).toBool() )
|
||||
{
|
||||
mAttributeEditorFrame = new QgsCollapsibleGroupBox( editor );
|
||||
mAttributeEditorLayout = new QVBoxLayout( mAttributeEditorFrame );
|
||||
mAttributeEditorFrame->setLayout( mAttributeEditorLayout );
|
||||
|
||||
layout->addWidget( mAttributeEditorFrame, 1, 0, 1, 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mAttributeEditorButton = new QPushButton( tr( "Open Form" ) );
|
||||
|
||||
layout->addWidget( mAttributeEditorButton, 0, 1, 1, 1 );
|
||||
|
||||
connect( mAttributeEditorButton, SIGNAL( clicked() ), this, SLOT( openForm() ) );
|
||||
}
|
||||
|
||||
layout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding ), 0, 2, 1, 1 );
|
||||
|
||||
QgsRelation relation = QgsProject::instance()->relationManager()->relation( config( "Relation" ).toString() );
|
||||
|
||||
if ( relation.isValid() )
|
||||
{
|
||||
mReferencedLayer = relation.referencedLayer();
|
||||
int refFieldIdx = mReferencedLayer->fieldNameIndex( relation.fieldPairs().first().second );
|
||||
|
||||
QgsFeatureIterator fit = mReferencedLayer->getFeatures( QgsFeatureRequest() );
|
||||
|
||||
QgsExpression exp( mReferencedLayer->displayExpression() );
|
||||
exp.prepare( mReferencedLayer->pendingFields() );
|
||||
|
||||
QgsFeature f;
|
||||
while ( fit.nextFeature( f ) )
|
||||
{
|
||||
QString txt = exp.evaluate( &f ).toString();
|
||||
|
||||
mComboBox->addItem( txt, f.id() );
|
||||
|
||||
mFidFkMap.insert( f.id(), f.attribute( refFieldIdx ) );
|
||||
}
|
||||
|
||||
if ( config( "AllowNULL" ).toBool() )
|
||||
{
|
||||
mComboBox->addItem( "[NULL]" );
|
||||
}
|
||||
|
||||
// Only connect after iterating, to have only one iterator on the referenced table at once
|
||||
connect( mComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( referenceChanged( int ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QLabel* lbl = new QLabel( tr( "The relation is not valid. Please make sure your relation definitions are ok." ) );
|
||||
QFont font = lbl->font();
|
||||
font.setItalic( true );
|
||||
lbl->setStyleSheet( "QLabel { color: red; } " );
|
||||
lbl->setFont( font );
|
||||
layout->addWidget( lbl, 1, 0, 1, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
QVariant QgsRelationReferenceWidget::value()
|
||||
{
|
||||
QVariant varFid = mComboBox->itemData( mComboBox->currentIndex() );
|
||||
if ( varFid.isNull() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
else
|
||||
{
|
||||
return mFidFkMap.value( varFid.value<QgsFeatureId>() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationReferenceWidget::setValue( const QVariant& value )
|
||||
{
|
||||
QgsFeatureId fid = mFidFkMap.key( value );
|
||||
int oldIdx = mComboBox->currentIndex();
|
||||
mComboBox->setCurrentIndex( mComboBox->findData( fid ) );
|
||||
|
||||
if ( !mInitialValueAssigned )
|
||||
{
|
||||
// In case the default-selected item (first) is the actual item
|
||||
// then no referenceChanged event was triggered automatically:
|
||||
// Do it!
|
||||
if ( oldIdx == mComboBox->currentIndex() )
|
||||
referenceChanged( mComboBox->currentIndex() );
|
||||
mInitialValueAssigned = true;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationReferenceWidget::setEnabled( bool enabled )
|
||||
{
|
||||
mComboBox->setEnabled( enabled );
|
||||
}
|
||||
|
||||
void QgsRelationReferenceWidget::referenceChanged( int index )
|
||||
{
|
||||
QgsFeatureId fid = mComboBox->itemData( index ).value<QgsFeatureId>();
|
||||
|
||||
emit valueChanged( mFidFkMap.value( fid ) );
|
||||
|
||||
// Check if we're running with an embedded frame we need to update
|
||||
if ( mAttributeEditorFrame )
|
||||
{
|
||||
QgsFeature feat;
|
||||
|
||||
mReferencedLayer->getFeatures( QgsFeatureRequest().setFilterFid( fid ) ).nextFeature( feat );
|
||||
|
||||
if ( feat.isValid() )
|
||||
{
|
||||
// Backup old dialog and delete only after creating the new dialog, so we can "hot-swap" the contained QgsFeature
|
||||
QgsAttributeDialog* oldDialog = mAttributeDialog;
|
||||
|
||||
if ( mAttributeDialog && mAttributeDialog->dialog() )
|
||||
{
|
||||
mAttributeEditorLayout->removeWidget( mAttributeDialog->dialog() );
|
||||
}
|
||||
|
||||
// TODO: Get a proper QgsDistanceArea thingie
|
||||
mAttributeDialog = new QgsAttributeDialog( mReferencedLayer, new QgsFeature( feat ), true, mAttributeEditorFrame, false, mEditorContext );
|
||||
QWidget* attrDialog = mAttributeDialog->dialog();
|
||||
attrDialog->setWindowFlags( Qt::Widget ); // Embed instead of opening as window
|
||||
mAttributeEditorLayout->addWidget( attrDialog );
|
||||
attrDialog->show();
|
||||
|
||||
delete oldDialog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationReferenceWidget::openForm()
|
||||
{
|
||||
QgsFeatureId fid = mComboBox->itemData( mComboBox->currentIndex() ).value<QgsFeatureId>();
|
||||
|
||||
QgsFeature feat;
|
||||
|
||||
mReferencedLayer->getFeatures( QgsFeatureRequest().setFilterFid( fid ) ).nextFeature( feat );
|
||||
|
||||
if ( !feat.isValid() )
|
||||
return;
|
||||
|
||||
// TODO: Get a proper QgsDistanceArea thingie
|
||||
mAttributeDialog = new QgsAttributeDialog( mReferencedLayer, new QgsFeature( feat ), true, widget(), true, mEditorContext );
|
||||
mAttributeDialog->exec();
|
||||
delete mAttributeDialog;
|
||||
}
|
63
src/gui/editorwidgets/qgsrelationreferencewidget.h
Normal file
63
src/gui/editorwidgets/qgsrelationreferencewidget.h
Normal file
@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
qgsrelationreferencewidget.h
|
||||
--------------------------------------
|
||||
Date : 20.4.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSRELATIONREFERENCEWIDGET_H
|
||||
#define QGSRELATIONREFERENCEWIDGET_H
|
||||
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
#include "qgseditorwidgetwrapper.h"
|
||||
#include "qgsfeature.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class QgsAttributeDialog;
|
||||
class QgsVectorLayerTools;
|
||||
|
||||
class GUI_EXPORT QgsRelationReferenceWidget : public QgsEditorWidgetWrapper
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsRelationReferenceWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QgsAttributeEditorContext context, QWidget* parent = 0 );
|
||||
virtual QWidget* createWidget( QWidget* parent );
|
||||
virtual void initWidget( QWidget* editor );
|
||||
virtual QVariant value();
|
||||
|
||||
signals:
|
||||
void valueChanged( const QVariant& value );
|
||||
|
||||
public slots:
|
||||
virtual void setValue( const QVariant& value );
|
||||
virtual void setEnabled( bool enabled );
|
||||
|
||||
private slots:
|
||||
void referenceChanged( int index );
|
||||
void openForm();
|
||||
|
||||
private:
|
||||
bool mInitialValueAssigned;
|
||||
QComboBox* mComboBox;
|
||||
QWidget* mAttributeEditorFrame;
|
||||
QVBoxLayout* mAttributeEditorLayout;
|
||||
QPushButton* mAttributeEditorButton;
|
||||
QgsVectorLayer* mReferencedLayer;
|
||||
QVariant mCurrentValue;
|
||||
QgsAttributeDialog* mAttributeDialog;
|
||||
QHash<QgsFeatureId, QVariant> mFidFkMap; // Mapping from feature id => foreign key
|
||||
QgsAttributeEditorContext mEditorContext;
|
||||
};
|
||||
|
||||
#endif // QGSRELATIONREFERENCEWIDGET_H
|
78
src/gui/editorwidgets/qgsrelreferenceconfigdlg.cpp
Normal file
78
src/gui/editorwidgets/qgsrelreferenceconfigdlg.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/***************************************************************************
|
||||
qgsrelreferenceconfigdlg.cpp
|
||||
--------------------------------------
|
||||
Date : 21.4.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsrelreferenceconfigdlg.h"
|
||||
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
QgsRelReferenceConfigDlg::QgsRelReferenceConfigDlg( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
|
||||
: QgsEditorConfigWidget( vl, fieldIdx, parent )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
foreach ( const QgsRelation& relation, vl->referencingRelations( fieldIdx ) )
|
||||
{
|
||||
QgsField fld = relation.fieldPairs().first().second;
|
||||
mComboRelation->addItem( QString( "%1 (%2)" ).arg( relation.id(), relation.referencedLayerId() ), relation.id() );
|
||||
if ( relation.referencedLayer() )
|
||||
{
|
||||
mTxtDisplayExpression->setText( relation.referencedLayer()->displayExpression() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelReferenceConfigDlg::setConfig( const QMap<QString, QVariant>& config )
|
||||
{
|
||||
if ( config.contains( "AllowNULL" ) )
|
||||
{
|
||||
mCbxAllowNull->setChecked( config[ "AllowNULL" ].toBool() );
|
||||
}
|
||||
|
||||
if ( config.contains( "ShowForm" ) )
|
||||
{
|
||||
mCbxShowForm->setChecked( config[ "ShowForm" ].toBool() );
|
||||
}
|
||||
|
||||
if ( config.contains( "Relation" ) )
|
||||
{
|
||||
mComboRelation->setCurrentIndex( mComboRelation->findData( config[ "Relation" ].toString() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelReferenceConfigDlg::on_mComboRelation_indexChanged( int idx )
|
||||
{
|
||||
QString relName = mComboRelation->itemData( idx ).toString();
|
||||
QgsRelation rel = QgsProject::instance()->relationManager()->relation( relName );
|
||||
|
||||
QgsVectorLayer* referencedLayer = rel.referencedLayer();
|
||||
if ( referencedLayer )
|
||||
{
|
||||
mTxtDisplayExpression->setText( referencedLayer->displayExpression() );
|
||||
}
|
||||
}
|
||||
|
||||
QgsEditorWidgetConfig QgsRelReferenceConfigDlg::config()
|
||||
{
|
||||
QgsEditorWidgetConfig myConfig;
|
||||
myConfig.insert( "AllowNULL", mCbxAllowNull->isChecked() );
|
||||
myConfig.insert( "ShowForm", mCbxShowForm->isChecked() );
|
||||
myConfig.insert( "Relation", mComboRelation->itemData( mComboRelation->currentIndex() ) );
|
||||
|
||||
return myConfig;
|
||||
}
|
35
src/gui/editorwidgets/qgsrelreferenceconfigdlg.h
Normal file
35
src/gui/editorwidgets/qgsrelreferenceconfigdlg.h
Normal file
@ -0,0 +1,35 @@
|
||||
/***************************************************************************
|
||||
qgsrelreferenceconfigdlgbase.h
|
||||
--------------------------------------
|
||||
Date : 21.4.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSRELREFERENCECONFIGDLGBASE_H
|
||||
#define QGSRELREFERENCECONFIGDLGBASE_H
|
||||
|
||||
#include "ui_qgsrelreferenceconfigdlgbase.h"
|
||||
#include "qgseditorconfigwidget.h"
|
||||
|
||||
class GUI_EXPORT QgsRelReferenceConfigDlg : public QgsEditorConfigWidget, private Ui::QgsRelReferenceConfigDlgBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsRelReferenceConfigDlg( QgsVectorLayer* vl, int fieldIdx, QWidget* parent );
|
||||
virtual QgsEditorWidgetConfig config();
|
||||
virtual void setConfig( const QgsEditorWidgetConfig& config );
|
||||
|
||||
private slots:
|
||||
void on_mComboRelation_indexChanged( int idx );
|
||||
};
|
||||
|
||||
#endif // QGSRELREFERENCECONFIGDLGBASE_H
|
@ -34,6 +34,7 @@ class QgsLegendInterface;
|
||||
class QgsPluginManagerInterface;
|
||||
class QgsFeature;
|
||||
class QgsMessageBar;
|
||||
class QgsVectorLayerTools;
|
||||
|
||||
#include <QObject>
|
||||
#include <QFont>
|
||||
@ -217,7 +218,7 @@ class GUI_EXPORT QgisInterface : public QObject
|
||||
/** Return the message bar of the main app */
|
||||
virtual QgsMessageBar * messageBar() = 0;
|
||||
|
||||
/**Return mainwindows / composer views of running composer instances (currently only one)*/
|
||||
/** Return mainwindows / composer views of running composer instances (currently only one) */
|
||||
virtual QList<QgsComposerView*> activeComposers() = 0;
|
||||
|
||||
/** Create a new composer
|
||||
@ -530,13 +531,17 @@ class GUI_EXPORT QgisInterface : public QObject
|
||||
virtual QAction *actionCheckQgisVersion() = 0;
|
||||
virtual QAction *actionAbout() = 0;
|
||||
|
||||
//! Open feature form
|
||||
// returns true when dialog was accepted
|
||||
// @added in 1.6
|
||||
/**
|
||||
* Open feature form
|
||||
* @return true when dialog was accepted
|
||||
* @note added in 1.6
|
||||
*/
|
||||
virtual bool openFeatureForm( QgsVectorLayer *l, QgsFeature &f, bool updateFeatureOnly = false ) = 0;
|
||||
|
||||
virtual QDialog* getFeatureForm( QgsVectorLayer *l, QgsFeature &f ) = 0;
|
||||
|
||||
virtual QgsVectorLayerTools* vectorLayerTools() = 0;
|
||||
|
||||
virtual void preloadForm( QString uifile ) = 0;
|
||||
|
||||
/** Return vector layers in edit mode
|
||||
@ -555,18 +560,21 @@ class GUI_EXPORT QgisInterface : public QObject
|
||||
*/
|
||||
void currentLayerChanged( QgsMapLayer * layer );
|
||||
|
||||
/**This signal is emitted when a new composer instance has been created
|
||||
/**
|
||||
* This signal is emitted when a new composer instance has been created
|
||||
* @note added in 1.4
|
||||
*/
|
||||
void composerAdded( QgsComposerView* v );
|
||||
|
||||
/**This signal is emitted before a new composer instance is going to be removed
|
||||
/**
|
||||
* This signal is emitted before a new composer instance is going to be removed
|
||||
* @note added in 1.4
|
||||
*/
|
||||
void composerWillBeRemoved( QgsComposerView* v );
|
||||
/**This signal is emitted when the initialization is complete
|
||||
* @note added in version 1.6
|
||||
*/
|
||||
/**
|
||||
* This signal is emitted when the initialization is complete
|
||||
* @note added in 1.6
|
||||
*/
|
||||
void initializationCompleted();
|
||||
/** emitted when a project file is successfully read
|
||||
@note
|
||||
@ -574,7 +582,7 @@ class GUI_EXPORT QgisInterface : public QObject
|
||||
plug-in can connect to this signal. When it is emitted, the plug-in
|
||||
knows to then check the project properties for any relevant state.
|
||||
|
||||
Added in v1.6
|
||||
Added in 1.6
|
||||
*/
|
||||
void projectRead();
|
||||
/** emitted when starting an entirely new project
|
||||
@ -585,7 +593,7 @@ class GUI_EXPORT QgisInterface : public QObject
|
||||
it's probably more semantically correct to have an entirely separate
|
||||
signal for when this happens.
|
||||
|
||||
Added in v1.6
|
||||
Added in 1.6
|
||||
*/
|
||||
void newProjectCreated();
|
||||
};
|
||||
|
@ -20,8 +20,9 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsrelationeditor.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsattributeeditor.h"
|
||||
#include "qgshighlight.h"
|
||||
#include "qgsexpression.h"
|
||||
@ -266,6 +267,22 @@ void QgsAttributeDialog::init()
|
||||
}
|
||||
}
|
||||
|
||||
QList<QgsRelation> relations = QgsProject::instance()->relationManager()->referencedRelations( mLayer );
|
||||
|
||||
foreach ( const QgsRelation& relation, relations )
|
||||
{
|
||||
relation.id();
|
||||
|
||||
QWidget *myWidget = QgsRelationEditorWidget::createRelationEditor( relation, *mFeature, mContext );
|
||||
myWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||
if ( !myWidget )
|
||||
continue;
|
||||
|
||||
mypInnerLayout->addWidget( myWidget, index, 0, 1, 2 );
|
||||
mypInnerLayout->setRowStretch( index, 1 );
|
||||
++index;
|
||||
}
|
||||
|
||||
// Set focus to first widget in list, to help entering data without moving the mouse.
|
||||
if ( mypInnerLayout->rowCount() > 0 )
|
||||
{
|
||||
@ -274,7 +291,7 @@ void QgsAttributeDialog::init()
|
||||
widget->setFocus( Qt::OtherFocusReason );
|
||||
}
|
||||
|
||||
QSpacerItem *mypSpacer = new QSpacerItem( 10, 10, QSizePolicy::Fixed, QSizePolicy::Expanding );
|
||||
QSpacerItem *mypSpacer = new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::MinimumExpanding );
|
||||
mypInnerLayout->addItem( mypSpacer, mypInnerLayout->rowCount() + 1, 0 );
|
||||
}
|
||||
else
|
||||
|
@ -28,6 +28,7 @@ class QgsFeature;
|
||||
class QgsField;
|
||||
class QgsHighlight;
|
||||
class QgsVectorLayer;
|
||||
class QgsVectorLayerTools;
|
||||
|
||||
class GUI_EXPORT QgsAttributeDialog : public QObject
|
||||
{
|
||||
@ -35,24 +36,36 @@ class GUI_EXPORT QgsAttributeDialog : public QObject
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief QgsAttributeDialog
|
||||
* @param vl
|
||||
* @param thepFeature
|
||||
* @param featureOwner
|
||||
* @param myDa
|
||||
* @param parent
|
||||
* @param showDialogButtons
|
||||
* Create an attribute dialog for a given layer and feature
|
||||
*
|
||||
* @param vl The layer for which the dialog will be generated
|
||||
* @param thepFeature A feature for which the dialog will be generated
|
||||
* @param featureOwner Set to true, if the dialog should take ownership of the feature
|
||||
* @param myDa A QgsDistanceArea which will be used for expressions
|
||||
* @param parent A parent widget for the dialog
|
||||
* @param showDialogButtons True: Show the dialog buttons accept/cancel
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget* parent = 0, bool showDialogButtons = true );
|
||||
|
||||
/**
|
||||
* Create an attribute dialog for a given layer and feature
|
||||
*
|
||||
* @param vl The layer for which the dialog will be generated
|
||||
* @param thepFeature A feature for which the dialog will be generated
|
||||
* @param featureOwner Set to true, if the dialog should take ownership of the feature
|
||||
* @param parent A parent widget for the dialog
|
||||
* @param showDialogButtons True: Show the dialog buttons accept/cancel
|
||||
* @param context The context in which this dialog is created
|
||||
*
|
||||
*/
|
||||
QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QWidget* parent = 0, bool showDialogButtons = true, QgsAttributeEditorContext context = QgsAttributeEditorContext() );
|
||||
|
||||
~QgsAttributeDialog();
|
||||
|
||||
/** Saves the size and position for the next time
|
||||
* this dialog box was used.
|
||||
* this dialog box will be used.
|
||||
*/
|
||||
void saveGeometry();
|
||||
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "qgseditorwidgetwrapper.h"
|
||||
|
||||
#include "qgsattributedialog.h"
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
#include "qgsattributeeditor.h"
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
#include "qgscategorizedsymbolrendererv2.h"
|
||||
#include "qgscolorbutton.h"
|
||||
#include "qgsexpression.h"
|
||||
@ -32,6 +32,8 @@
|
||||
#include "qgslonglongvalidator.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
#include "qgsrelationeditor.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
@ -1430,6 +1432,16 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsAttributeEditorElement::AeTypeRelation:
|
||||
{
|
||||
const QgsAttributeEditorRelation* relDef = dynamic_cast<const QgsAttributeEditorRelation*>( widgetDef );
|
||||
|
||||
newWidget = QgsRelationEditorWidget::createRelationEditor( relDef->relation(), feat, context );
|
||||
labelText = QString::null;
|
||||
labelOnTop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsAttributeEditorElement::AeTypeContainer:
|
||||
{
|
||||
const QgsAttributeEditorContainer* container = dynamic_cast<const QgsAttributeEditorContainer*>( widgetDef );
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <QGridLayout>
|
||||
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
|
||||
class QObject;
|
||||
class QWidget;
|
||||
@ -31,6 +32,7 @@ class QListWidget;
|
||||
class QgsAttributeEditorContext;
|
||||
class QgsAttributeEditorElement;
|
||||
class QgsDualView;
|
||||
class QgsRelationManager;
|
||||
class QgsVectorLayer;
|
||||
|
||||
/* \brief create attribute widget for editing */
|
||||
@ -67,7 +69,6 @@ class GUI_EXPORT QgsAttributeEditor : public QObject
|
||||
*
|
||||
*/
|
||||
static QWidget* createAttributeEditor( QWidget* parent, QWidget* editor, QgsVectorLayer* vl, int idx, const QVariant& value );
|
||||
|
||||
/**
|
||||
* Creates or prepares a attributre editor widget
|
||||
* @param parent The parent object
|
||||
|
40
src/gui/qgsfeatureselectiondlg.cpp
Normal file
40
src/gui/qgsfeatureselectiondlg.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/***************************************************************************
|
||||
qgsfeatureselectiondlg.cpp
|
||||
--------------------------------------
|
||||
Date : 11.6.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsfeatureselectiondlg.h"
|
||||
|
||||
#include "qgsgenericfeatureselectionmanager.h"
|
||||
#include "qgsdistancearea.h"
|
||||
|
||||
QgsFeatureSelectionDlg::QgsFeatureSelectionDlg( QgsVectorLayer* vl, QWidget *parent )
|
||||
: QDialog( parent )
|
||||
, mVectorLayer( vl )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
mFeatureSelection = new QgsGenericFeatureSelectionManager( mDualView );
|
||||
|
||||
mDualView->setFeatureSelectionManager( mFeatureSelection );
|
||||
|
||||
// TODO: Proper QgsDistanceArea, proper mapcanvas
|
||||
mDualView->init( mVectorLayer, NULL );
|
||||
}
|
||||
|
||||
const QgsFeatureIds& QgsFeatureSelectionDlg::selectedFeatures()
|
||||
{
|
||||
return mFeatureSelection->selectedFeaturesIds();
|
||||
}
|
||||
|
||||
|
37
src/gui/qgsfeatureselectiondlg.h
Normal file
37
src/gui/qgsfeatureselectiondlg.h
Normal file
@ -0,0 +1,37 @@
|
||||
/***************************************************************************
|
||||
qgsfeatureselectiondlg.h
|
||||
--------------------------------------
|
||||
Date : 11.6.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSFEATURESELECTIONDLG_H
|
||||
#define QGSFEATURESELECTIONDLG_H
|
||||
|
||||
class QgsGenericFeatureSelectionManager;
|
||||
|
||||
#include "ui_qgsfeatureselectiondlg.h"
|
||||
|
||||
class QgsFeatureSelectionDlg : public QDialog, private Ui::QgsFeatureSelectionDlg
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsFeatureSelectionDlg( QgsVectorLayer* vl, QWidget *parent = 0 );
|
||||
|
||||
const QgsFeatureIds& selectedFeatures();
|
||||
|
||||
private:
|
||||
QgsGenericFeatureSelectionManager* mFeatureSelection;
|
||||
QgsVectorLayer* mVectorLayer;
|
||||
};
|
||||
|
||||
#endif // QGSFEATURESELECTIONDLG_H
|
79
src/gui/qgsrelationadddlg.cpp
Normal file
79
src/gui/qgsrelationadddlg.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "qgsrelationadddlg.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
QgsRelationAddDlg::QgsRelationAddDlg( QWidget *parent ) :
|
||||
QDialog( parent )
|
||||
{
|
||||
setupUi( this );
|
||||
}
|
||||
|
||||
void QgsRelationAddDlg::addLayers( QList< QgsVectorLayer* > layers )
|
||||
{
|
||||
mCbxReferencingLayer->addItem( "", "" );
|
||||
mCbxReferencedLayer->addItem( "", "" );
|
||||
|
||||
foreach ( QgsVectorLayer* layer, layers )
|
||||
{
|
||||
mCbxReferencingLayer->addItem( layer->name(), layer->id() );
|
||||
mCbxReferencedLayer->addItem( layer->name(), layer->id() );
|
||||
|
||||
mLayers.insert( layer->id(), layer );
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsRelationAddDlg::referencingLayerId()
|
||||
{
|
||||
return mCbxReferencingLayer->itemData( mCbxReferencingLayer->currentIndex() ).toString();
|
||||
}
|
||||
|
||||
QString QgsRelationAddDlg::referencedLayerId()
|
||||
{
|
||||
return mCbxReferencedLayer->itemData( mCbxReferencedLayer->currentIndex() ).toString();
|
||||
}
|
||||
|
||||
QList< QPair< QString, QString > > QgsRelationAddDlg::references()
|
||||
{
|
||||
QList< QPair< QString, QString > > references;
|
||||
|
||||
QString referencingField = mCbxReferencingField->itemData( mCbxReferencingField->currentIndex() ).toString();
|
||||
QString referencedField = mCbxReferencedField->itemData( mCbxReferencedField->currentIndex() ).toString();
|
||||
|
||||
references.append( QPair<QString, QString> ( referencingField, referencedField ) );
|
||||
|
||||
return references;
|
||||
}
|
||||
|
||||
QString QgsRelationAddDlg::relationId()
|
||||
{
|
||||
return mTxtRelationId->text();
|
||||
}
|
||||
|
||||
QString QgsRelationAddDlg::relationName()
|
||||
{
|
||||
return mTxtRelationName->text();
|
||||
}
|
||||
|
||||
void QgsRelationAddDlg::on_mCbxReferencingLayer_currentIndexChanged( int index )
|
||||
{
|
||||
loadLayerAttributes( mCbxReferencingField, mLayers[mCbxReferencingLayer->itemData( index ).toString()] );
|
||||
}
|
||||
|
||||
void QgsRelationAddDlg::on_mCbxReferencedLayer_currentIndexChanged( int index )
|
||||
{
|
||||
loadLayerAttributes( mCbxReferencedField, mLayers[mCbxReferencedLayer->itemData( index ).toString()] );
|
||||
}
|
||||
|
||||
void QgsRelationAddDlg::loadLayerAttributes( QComboBox* cbx, QgsVectorLayer* layer )
|
||||
{
|
||||
cbx->clear();
|
||||
|
||||
if ( !layer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( QgsField fld, layer->pendingFields().toList() )
|
||||
{
|
||||
cbx->addItem( fld.name(), fld.name() );
|
||||
}
|
||||
}
|
36
src/gui/qgsrelationadddlg.h
Normal file
36
src/gui/qgsrelationadddlg.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef QGSRELATIONADDDLG_H
|
||||
#define QGSRELATIONADDDLG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_qgsrelationadddlgbase.h"
|
||||
|
||||
class QgsVectorLayer;
|
||||
|
||||
class QgsRelationAddDlg : public QDialog, private Ui::QgsRelationAddDlgBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsRelationAddDlg( QWidget *parent = 0 );
|
||||
|
||||
void addLayers( QList<QgsVectorLayer* > layers );
|
||||
|
||||
QString referencingLayerId();
|
||||
QString referencedLayerId();
|
||||
QList< QPair< QString, QString > > references();
|
||||
QString relationId();
|
||||
QString relationName();
|
||||
|
||||
|
||||
private slots:
|
||||
void on_mCbxReferencingLayer_currentIndexChanged( int index );
|
||||
void on_mCbxReferencedLayer_currentIndexChanged( int index );
|
||||
|
||||
private:
|
||||
void loadLayerAttributes( QComboBox* cbx, QgsVectorLayer* layer );
|
||||
|
||||
QMap< QString, QgsVectorLayer* > mLayers;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSRELATIONADDDLG_H
|
183
src/gui/qgsrelationeditor.cpp
Normal file
183
src/gui/qgsrelationeditor.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
/***************************************************************************
|
||||
qgsrelationeditor.cpp
|
||||
--------------------------------------
|
||||
Date : 17.5.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsrelationeditor.h"
|
||||
|
||||
#include "attributetable/qgsdualview.h"
|
||||
|
||||
#include "qgsdistancearea.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsfeatureselectiondlg.h"
|
||||
#include "qgsgenericfeatureselectionmanager.h"
|
||||
#include "qgsrelation.h"
|
||||
#include "qgsvectorlayertools.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
QgsRelationEditorWidget::QgsRelationEditorWidget( const QgsRelation& relation, const QgsFeature& feature, QgsAttributeEditorContext context, QWidget* parent )
|
||||
: QgsCollapsibleGroupBox( relation.name(), parent )
|
||||
, mDualView( NULL )
|
||||
, mEditorContext( context )
|
||||
, mRelation( relation )
|
||||
, mFeature( feature )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
connect( relation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( referencingLayerEditingToggled() ) );
|
||||
connect( relation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( referencingLayerEditingToggled() ) );
|
||||
connect( this, SIGNAL( collapsedStateChanged( bool ) ), this, SIGNAL( onCollapsedStateChanged( bool ) ) );
|
||||
|
||||
// Set initial state for add/remove etc. buttons
|
||||
referencingLayerEditingToggled();
|
||||
}
|
||||
|
||||
QgsRelationEditorWidget* QgsRelationEditorWidget::createRelationEditor( const QgsRelation& relation, const QgsFeature& feature, QgsAttributeEditorContext context, QWidget* parent )
|
||||
{
|
||||
QgsRelationEditorWidget* editor = new QgsRelationEditorWidget( relation, feature, context, parent );
|
||||
|
||||
QgsDualView* dualView = new QgsDualView( editor );
|
||||
QgsVectorLayer* lyr = relation.referencingLayer();
|
||||
|
||||
bool canChangeAttributes = lyr->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
|
||||
|
||||
editor->mToggleEditingButton->setEnabled( canChangeAttributes && !lyr->isReadOnly() );
|
||||
|
||||
editor->mFeatureSelectionMgr = new QgsGenericFeatureSelectionManager( dualView );
|
||||
dualView->setFeatureSelectionManager( editor->mFeatureSelectionMgr );
|
||||
|
||||
editor->mBrowserWidget->layout()->addWidget( dualView );
|
||||
|
||||
QgsFeatureRequest myRequest = relation.getRelatedFeaturesRequest( feature );
|
||||
|
||||
dualView->init( relation.referencingLayer(), NULL, myRequest, context );
|
||||
|
||||
editor->mDualView = dualView;
|
||||
|
||||
editor->mViewModeButtonGroup->setId( editor->mTableViewButton, QgsDualView::AttributeTable );
|
||||
editor->mViewModeButtonGroup->setId( editor->mFormViewButton, QgsDualView::AttributeEditor );
|
||||
|
||||
connect( editor->mViewModeButtonGroup, SIGNAL( buttonClicked( int ) ), dualView, SLOT( setCurrentIndex( int ) ) );
|
||||
connect( dualView, SIGNAL( currentChanged( int ) ), editor, SLOT( viewModeChanged( int ) ) );
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::onCollapsedStateChanged( bool state )
|
||||
{
|
||||
if ( state && !mDualView->masterModel() )
|
||||
{
|
||||
// TODO: Lazy init dual view if collapsed on init
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::referencingLayerEditingToggled()
|
||||
{
|
||||
bool editable = mRelation.referencingLayer()->isEditable();
|
||||
|
||||
mAddFeatureButton->setEnabled( editable );
|
||||
mLinkFeatureButton->setEnabled( editable );
|
||||
mDeleteFeatureButton->setEnabled( editable );
|
||||
mUnlinkFeatureButton->setEnabled( editable );
|
||||
mToggleEditingButton->setChecked( editable );
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::viewModeChanged( int mode )
|
||||
{
|
||||
mViewModeButtonGroup->button( mode )->click();
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::on_mAddFeatureButton_clicked()
|
||||
{
|
||||
QgsAttributeMap keyAttrs;
|
||||
|
||||
QgsFields fields = mRelation.referencingLayer()->pendingFields();
|
||||
|
||||
foreach ( QgsRelation::FieldPair fieldPair, mRelation.fieldPairs() )
|
||||
{
|
||||
keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeature.attribute( fieldPair.referencedField() ) );
|
||||
}
|
||||
|
||||
mEditorContext.vectorLayerTools()->addFeature( mDualView->masterModel()->layer(), keyAttrs );
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::on_mLinkFeatureButton_clicked()
|
||||
{
|
||||
QgsFeatureSelectionDlg selectionDlg( mRelation.referencingLayer(), this );
|
||||
|
||||
if ( selectionDlg.exec() )
|
||||
{
|
||||
QMap<int, QVariant> keys;
|
||||
foreach ( const QgsRelation::FieldPair fieldPair, mRelation.fieldPairs() )
|
||||
{
|
||||
int idx = mRelation.referencingLayer()->fieldNameIndex( fieldPair.referencingField() );
|
||||
QVariant val = mFeature.attribute( fieldPair.referencedField() );
|
||||
keys.insert( idx, val );
|
||||
}
|
||||
|
||||
foreach ( QgsFeatureId fid, selectionDlg.selectedFeatures() )
|
||||
{
|
||||
QMapIterator<int, QVariant> it( keys );
|
||||
while ( it.hasNext() )
|
||||
{
|
||||
it.next();
|
||||
mRelation.referencingLayer()->changeAttributeValue( fid, it.key(), it.value() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::on_mDeleteFeatureButton_clicked()
|
||||
{
|
||||
foreach ( QgsFeatureId fid, mFeatureSelectionMgr->selectedFeaturesIds() )
|
||||
{
|
||||
mRelation.referencingLayer()->deleteFeature( fid );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::on_mUnlinkFeatureButton_clicked()
|
||||
{
|
||||
QMap<int, QgsField> keyFields;
|
||||
foreach ( const QgsRelation::FieldPair fieldPair, mRelation.fieldPairs() )
|
||||
{
|
||||
int idx = mRelation.referencingLayer()->fieldNameIndex( fieldPair.referencingField() );
|
||||
QgsField fld = mRelation.referencingLayer()->pendingFields().at( idx );
|
||||
keyFields.insert( idx, fld );
|
||||
}
|
||||
|
||||
foreach ( QgsFeatureId fid, mFeatureSelectionMgr->selectedFeaturesIds() )
|
||||
{
|
||||
QMapIterator<int, QgsField> it( keyFields );
|
||||
while ( it.hasNext() )
|
||||
{
|
||||
it.next();
|
||||
mRelation.referencingLayer()->changeAttributeValue( fid, it.key(), QVariant( it.value().type() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationEditorWidget::on_mToggleEditingButton_toggled( bool state )
|
||||
{
|
||||
if ( state )
|
||||
{
|
||||
mEditorContext.vectorLayerTools()->startEditing( mRelation.referencingLayer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mEditorContext.vectorLayerTools()->stopEditing( mRelation.referencingLayer() );
|
||||
}
|
||||
}
|
60
src/gui/qgsrelationeditor.h
Normal file
60
src/gui/qgsrelationeditor.h
Normal file
@ -0,0 +1,60 @@
|
||||
/***************************************************************************
|
||||
qgsrelationeditor.h
|
||||
--------------------------------------
|
||||
Date : 17.5.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSRELATIONEDITOR_H
|
||||
#define QGSRELATIONEDITOR_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "ui_qgsrelationeditorwidgetbase.h"
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
#include "qgsrelation.h"
|
||||
|
||||
class QgsDualView;
|
||||
class QgsFeature;
|
||||
class QgsGenericFeatureSelectionManager;
|
||||
class QgsVectorLayer;
|
||||
class QgsVectorLayerTools;
|
||||
|
||||
class QgsRelationEditorWidget : public QgsCollapsibleGroupBox, private Ui::QgsRelationEditorWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsRelationEditorWidget( const QgsRelation& relation, const QgsFeature& feature, QgsAttributeEditorContext context, QWidget* parent = NULL );
|
||||
|
||||
static QgsRelationEditorWidget* createRelationEditor( const QgsRelation& relation, const QgsFeature& feature, QgsAttributeEditorContext context, QWidget* parent = NULL );
|
||||
|
||||
private slots:
|
||||
void onCollapsedStateChanged( bool state );
|
||||
void referencingLayerEditingToggled();
|
||||
void viewModeChanged( int mode );
|
||||
|
||||
void on_mAddFeatureButton_clicked();
|
||||
void on_mLinkFeatureButton_clicked();
|
||||
void on_mDeleteFeatureButton_clicked();
|
||||
void on_mUnlinkFeatureButton_clicked();
|
||||
void on_mToggleEditingButton_toggled( bool state );
|
||||
|
||||
private:
|
||||
QgsDualView* mDualView;
|
||||
QgsGenericFeatureSelectionManager* mFeatureSelectionMgr;
|
||||
QgsAttributeEditorContext mEditorContext;
|
||||
QgsRelation mRelation;
|
||||
QgsFeature mFeature;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSRELATIONEDITOR_H
|
154
src/gui/qgsrelationmanagerdialog.cpp
Normal file
154
src/gui/qgsrelationmanagerdialog.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/***************************************************************************
|
||||
qgsrelationmanagerdialog.cpp
|
||||
--------------------------------------
|
||||
Date : 23.2.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsrelationadddlg.h"
|
||||
#include "qgsrelationmanagerdialog.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
QgsRelationManagerDialog::QgsRelationManagerDialog( QgsRelationManager* relationMgr, QWidget *parent ) :
|
||||
QWidget( parent ),
|
||||
Ui::QgsRelationManagerDialogBase(),
|
||||
mRelationManager( relationMgr )
|
||||
{
|
||||
setupUi( this );
|
||||
}
|
||||
|
||||
QgsRelationManagerDialog::~QgsRelationManagerDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void QgsRelationManagerDialog::setLayers( QList< QgsVectorLayer* > layers )
|
||||
{
|
||||
mLayers = layers;
|
||||
|
||||
const QList<QgsRelation>& relations = mRelationManager->relations().values();
|
||||
|
||||
Q_FOREACH( const QgsRelation& rel, relations )
|
||||
{
|
||||
addRelation( rel );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationManagerDialog::addRelation( const QgsRelation &rel )
|
||||
{
|
||||
int row = mRelationsTable->rowCount();
|
||||
mRelationsTable->insertRow( row );
|
||||
|
||||
QTableWidgetItem* item = new QTableWidgetItem( rel.name() );
|
||||
// Save relation in first column's item
|
||||
item->setData( Qt::UserRole, QVariant::fromValue<QgsRelation>( rel ) );
|
||||
mRelationsTable->setItem( row, 0, item );
|
||||
|
||||
|
||||
item = new QTableWidgetItem( rel.referencingLayer()->name() );
|
||||
item->setFlags( Qt::ItemIsEditable );
|
||||
mRelationsTable->setItem( row, 1, item );
|
||||
|
||||
item = new QTableWidgetItem( rel.fieldPairs().first().referencingField() );
|
||||
item->setFlags( Qt::ItemIsEditable );
|
||||
mRelationsTable->setItem( row, 2, item );
|
||||
|
||||
item = new QTableWidgetItem( rel.referencedLayer()->name() );
|
||||
item->setFlags( Qt::ItemIsEditable );
|
||||
mRelationsTable->setItem( row, 3, item );
|
||||
|
||||
item = new QTableWidgetItem( rel.fieldPairs().first().referencedField() );
|
||||
item->setFlags( Qt::ItemIsEditable );
|
||||
mRelationsTable->setItem( row, 4, item );
|
||||
|
||||
item = new QTableWidgetItem( rel.id() );
|
||||
item->setFlags( Qt::ItemIsEditable );
|
||||
mRelationsTable->setItem( row, 5, item );
|
||||
}
|
||||
|
||||
void QgsRelationManagerDialog::on_mBtnAddRelation_clicked()
|
||||
{
|
||||
QgsRelationAddDlg addDlg;
|
||||
addDlg.addLayers( mLayers );
|
||||
|
||||
if ( addDlg.exec() )
|
||||
{
|
||||
QgsRelation relation;
|
||||
|
||||
relation.setReferencingLayer( addDlg.referencingLayerId() );
|
||||
relation.setReferencedLayer( addDlg.referencedLayerId() );
|
||||
QString relationId = addDlg.relationId();
|
||||
if ( addDlg.relationId() == "" )
|
||||
relationId = QString( "%1_%2_%3_%4" )
|
||||
.arg( addDlg.referencingLayerId() )
|
||||
.arg( addDlg.references().first().first )
|
||||
.arg( addDlg.referencedLayerId() )
|
||||
.arg( addDlg.references().first().second );
|
||||
|
||||
QStringList existingNames;
|
||||
|
||||
|
||||
Q_FOREACH( const QgsRelation& rel, relations() )
|
||||
{
|
||||
existingNames << rel.id();
|
||||
}
|
||||
|
||||
QString tempId = relationId + "_%1";
|
||||
int suffix = 1;
|
||||
while ( existingNames.contains( relationId ) )
|
||||
{
|
||||
relationId = tempId.arg( suffix );
|
||||
++suffix;
|
||||
}
|
||||
relation.setRelationId( relationId );
|
||||
relation.addFieldPair( addDlg.references().first().first, addDlg.references().first().second );
|
||||
|
||||
addRelation( relation );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelationManagerDialog::on_mBtnRemoveRelation_clicked()
|
||||
{
|
||||
mRelationsTable->removeRow( mRelationsTable->currentItem()->row() );
|
||||
}
|
||||
|
||||
QList< QgsRelation > QgsRelationManagerDialog::relations()
|
||||
{
|
||||
QList< QgsRelation > relations;
|
||||
|
||||
for ( int i = 0; i < mRelationsTable->rowCount(); ++i )
|
||||
{
|
||||
QgsRelation relation = mRelationsTable->item( i, 0 )->data( Qt::UserRole ).value<QgsRelation>();
|
||||
// The name can be editted in the table, so apply this one
|
||||
relation.setRelationName( mRelationsTable->item( i, 0 )->data( Qt::DisplayRole ).toString() );
|
||||
relations << relation;
|
||||
}
|
||||
|
||||
return relations;
|
||||
}
|
||||
|
||||
#if 0
|
||||
QTreeWidgetItem* QgsRelationManagerDialog::findLayerItem( QString id )
|
||||
{
|
||||
int count = mRelationsTreeWdg->topLevelItemCount();
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
{
|
||||
QTreeWidgetItem* item = mRelationsTreeWdg->topLevelItem( i );
|
||||
if ( item->data( 0, Qt::UserRole ).toString() == id )
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
50
src/gui/qgsrelationmanagerdialog.h
Normal file
50
src/gui/qgsrelationmanagerdialog.h
Normal file
@ -0,0 +1,50 @@
|
||||
/***************************************************************************
|
||||
qgsrelationmanagerdialog.h
|
||||
--------------------------------------
|
||||
Date : 23.2.2013
|
||||
Copyright : (C) 2013 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSRELATIONMANAGERDIALOG_H
|
||||
#define QGSRELATIONMANAGERDIALOG_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "ui_qgsrelationmanagerdialogbase.h"
|
||||
|
||||
class QgsRelation;
|
||||
class QgsRelationManager;
|
||||
class QgsRelationManagerTreeModel;
|
||||
class QgsVectorLayer;
|
||||
|
||||
class GUI_EXPORT QgsRelationManagerDialog : public QWidget, private Ui::QgsRelationManagerDialogBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsRelationManagerDialog( QgsRelationManager* relationMgr, QWidget *parent = 0 );
|
||||
~QgsRelationManagerDialog();
|
||||
|
||||
void setLayers( QList< QgsVectorLayer* > );
|
||||
|
||||
void addRelation( const QgsRelation& rel );
|
||||
QList< QgsRelation > relations();
|
||||
|
||||
public slots:
|
||||
void on_mBtnAddRelation_clicked();
|
||||
void on_mBtnRemoveRelation_clicked();
|
||||
|
||||
private:
|
||||
QgsRelationManager* mRelationManager;
|
||||
// QgsRelationManagerTreeModel* mRelationTreeModel;
|
||||
QList< QgsVectorLayer* > mLayers;
|
||||
};
|
||||
|
||||
#endif // QGSRELATIONMANAGERDIALOG_H
|
@ -1,8 +1,9 @@
|
||||
|
||||
FILE(GLOB QGIS_UIS "${CMAKE_CURRENT_SOURCE_DIR}/*.ui")
|
||||
FILE(GLOB SYMBOLLAYER_UIS "${CMAKE_CURRENT_SOURCE_DIR}/symbollayer/*.ui")
|
||||
FILE(GLOB EDITORWIDGET_UIS "${CMAKE_CURRENT_SOURCE_DIR}/editorwidgets/*.ui")
|
||||
|
||||
QT4_WRAP_UI(QGIS_UIS_H ${QGIS_UIS} ${SYMBOLLAYER_UIS})
|
||||
QT4_WRAP_UI(QGIS_UIS_H ${QGIS_UIS} ${SYMBOLLAYER_UIS} ${EDITORWIDGET_UIS})
|
||||
|
||||
ADD_CUSTOM_TARGET(ui ALL DEPENDS ${QGIS_UIS_H})
|
||||
|
||||
|
55
src/ui/editorwidgets/qgsrelreferenceconfigdlgbase.ui
Normal file
55
src/ui/editorwidgets/qgsrelreferenceconfigdlgbase.ui
Normal file
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsRelReferenceConfigDlgBase</class>
|
||||
<widget class="QWidget" name="QgsRelReferenceConfigDlgBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>175</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Display expression</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mCbxAllowNull">
|
||||
<property name="text">
|
||||
<string>Allow NULL value</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mCbxShowForm">
|
||||
<property name="text">
|
||||
<string>Show embedded form</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Relation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="mComboRelation"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="mTxtDisplayExpression"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -43,7 +43,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionToggleEditing.svg</normaloff>:/images/themes/default/mActionToggleEditing.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
@ -72,7 +72,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionSaveEdits.svg</normaloff>:/images/themes/default/mActionSaveEdits.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
@ -118,7 +118,7 @@
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionDeleteSelected.svg</normaloff>:/images/themes/default/mActionDeleteSelected.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
@ -148,7 +148,7 @@
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mIconExpressionSelect.svg</normaloff>:/images/themes/default/mIconExpressionSelect.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
@ -244,7 +244,7 @@
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionPanToSelected.svg</normaloff>../../images/themes/default/mActionPanToSelected.svg</iconset>
|
||||
<normaloff>:/images/themes/default/mActionPanToSelected.svg</normaloff>:/images/themes/default/mActionPanToSelected.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
@ -269,7 +269,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource=":/imagesimages.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionZoomToSelected.svg</normaloff>:/images/themes/default/mActionZoomToSelected.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
@ -497,7 +497,7 @@
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAttributeViewButton">
|
||||
<property name="text">
|
||||
<string>Attribute View</string>
|
||||
<string>Form View</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
@ -553,7 +553,7 @@
|
||||
</action>
|
||||
<action name="mActionShowAllFilter">
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionFilter.png</normaloff>:/images/themes/default/mActionFilter.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -562,7 +562,7 @@
|
||||
</action>
|
||||
<action name="mActionSelectedFilter">
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionFilter.png</normaloff>:/images/themes/default/mActionFilter.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -571,7 +571,7 @@
|
||||
</action>
|
||||
<action name="mActionVisibleFilter">
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionFilter.png</normaloff>:/images/themes/default/mActionFilter.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -585,7 +585,7 @@
|
||||
</action>
|
||||
<action name="mActionEditedFilter">
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/themes/default/mActionFilter.png</normaloff>:/images/themes/default/mActionFilter.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -622,9 +622,7 @@
|
||||
<tabstop>mRemoveAttribute</tabstop>
|
||||
<tabstop>mOpenFieldCalculator</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../images/images.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>mToggleEditingButton</sender>
|
||||
|
78
src/ui/qgsfeatureselectiondlg.ui
Normal file
78
src/ui/qgsfeatureselectiondlg.ui
Normal file
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsFeatureSelectionDlg</class>
|
||||
<widget class="QDialog" name="QgsFeatureSelectionDlg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>468</width>
|
||||
<height>496</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QgsDualView" name="mDualView">
|
||||
<widget class="QWidget" name="page"/>
|
||||
<widget class="QWidget" name="page_2"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="mButtonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsDualView</class>
|
||||
<extends>QStackedWidget</extends>
|
||||
<header>qgsdualview.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>mButtonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>QgsFeatureSelectionDlg</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>mButtonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>QgsFeatureSelectionDlg</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>
|
@ -107,12 +107,20 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="mAttributesListFrame" native="true">
|
||||
<layout class="QGridLayout" name="mAttributesListLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
<widget class="QgsCollapsibleGroupBox" name="mAttributesListFrame">
|
||||
<property name="title">
|
||||
<string>Fields</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="mAttributesListLayout"/>
|
||||
</widget>
|
||||
<widget class="QgsCollapsibleGroupBox" name="mRelationsFrame">
|
||||
<property name="title">
|
||||
<string>Relations</string>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="mRelationsFrameLayout"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
@ -430,6 +438,14 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBox</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header>qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../images/images.qrc"/>
|
||||
</resources>
|
||||
|
@ -152,6 +152,15 @@
|
||||
<normaloff>:/images/themes/default/propertyicons/action.svg</normaloff>:/images/themes/default/propertyicons/action.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Relations</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/relation.svg</normaloff>:/images/themes/default/relation.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -217,9 +226,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-19</y>
|
||||
<width>631</width>
|
||||
<height>686</height>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>712</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
@ -776,8 +785,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>646</width>
|
||||
<height>667</height>
|
||||
<width>323</width>
|
||||
<height>46</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
@ -836,8 +845,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>646</width>
|
||||
<height>669</height>
|
||||
<width>133</width>
|
||||
<height>100</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
@ -918,8 +927,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>646</width>
|
||||
<height>669</height>
|
||||
<width>371</width>
|
||||
<height>336</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
@ -1296,8 +1305,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>631</width>
|
||||
<height>1254</height>
|
||||
<width>491</width>
|
||||
<height>1347</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
@ -1928,8 +1937,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>646</width>
|
||||
<height>669</height>
|
||||
<width>163</width>
|
||||
<height>111</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||
@ -1970,6 +1979,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="mTabRelations">
|
||||
<layout class="QGridLayout" name="gridLayout_16">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
128
src/ui/qgsrelationadddlgbase.ui
Normal file
128
src/ui/qgsrelationadddlgbase.ui
Normal file
@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsRelationAddDlgBase</class>
|
||||
<widget class="QDialog" name="QgsRelationAddDlgBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>581</width>
|
||||
<height>254</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="mCbxReferencingField"/>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="mCbxReferencingLayer"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Referencing Field</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Referenced Layer (Parent)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Referenced Field</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="mCbxReferencedLayer"/>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="mCbxReferencedField"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Referencing Layer (Child)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0" colspan="3">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Id</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="mTxtRelationId">
|
||||
<property name="placeholderText">
|
||||
<string>[Generated automatically]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="mTxtRelationName"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>QgsRelationAddDlgBase</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>QgsRelationAddDlgBase</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>
|
182
src/ui/qgsrelationeditorwidgetbase.ui
Normal file
182
src/ui/qgsrelationeditorwidgetbase.ui
Normal file
@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsRelationEditorWidgetBase</class>
|
||||
<widget class="QgsCollapsibleGroupBox" name="QgsRelationEditorWidgetBase">
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="mToggleEditingButton">
|
||||
<property name="toolTip">
|
||||
<string>Toggle editing</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Toggle editing</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionToggleEditing.png</normaloff>:/images/themes/default/mActionToggleEditing.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAddFeatureButton">
|
||||
<property name="text">
|
||||
<string>New</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionAdd.svg</normaloff>:/images/themes/default/mActionAdd.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mDeleteFeatureButton">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionRemove.svg</normaloff>:/images/themes/default/mActionRemove.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mLinkFeatureButton">
|
||||
<property name="text">
|
||||
<string>Link</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionLink.svg</normaloff>:/images/themes/default/mActionLink.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mUnlinkFeatureButton">
|
||||
<property name="text">
|
||||
<string>Unlink</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionUnlink.svg</normaloff>:/images/themes/default/mActionUnlink.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<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="QToolButton" name="mFormViewButton">
|
||||
<property name="text">
|
||||
<string>Form View</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionPropertyItem.png</normaloff>:/images/themes/default/mActionPropertyItem.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">mViewModeButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mTableViewButton">
|
||||
<property name="text">
|
||||
<string>Table View</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionOpenTable.png</normaloff>:/images/themes/default/mActionOpenTable.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">mViewModeButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="mBrowserWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBox</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header>qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../images/images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="mViewModeButtonGroup"/>
|
||||
</buttongroups>
|
||||
</ui>
|
109
src/ui/qgsrelationmanagerdialogbase.ui
Normal file
109
src/ui/qgsrelationmanagerdialogbase.ui
Normal file
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsRelationManagerDialogBase</class>
|
||||
<widget class="QWidget" name="QgsRelationManagerDialogBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>713</width>
|
||||
<height>427</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="mRelationsTable">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Referencing Layer</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Referencing Field</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Referenced Layer</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Referenced Field</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Id</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<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="mBtnAddRelation">
|
||||
<property name="text">
|
||||
<string>Add Relation</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionSignPlus.png</normaloff>:/images/themes/default/mActionSignPlus.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="mBtnRemoveRelation">
|
||||
<property name="text">
|
||||
<string>Remove Relation</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionSignMinus.png</normaloff>:/images/themes/default/mActionSignMinus.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../images/images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
x
Reference in New Issue
Block a user