diff options
| author | Jabier Arraiza <jabier.arraiza@marker.es> | 2019-08-22 01:39:49 +0000 |
|---|---|---|
| committer | Jabier Arraiza <jabier.arraiza@marker.es> | 2019-08-22 01:39:49 +0000 |
| commit | d1a647def410422f10d4386529efbcbf14532ce4 (patch) | |
| tree | 19e7e1b57cd5c8e048b434a44122577cda134729 | |
| parent | Update it.po (diff) | |
| download | inkscape-d1a647def410422f10d4386529efbcbf14532ce4.tar.gz inkscape-d1a647def410422f10d4386529efbcbf14532ce4.zip | |
Merge XML and CSS widgets improvements from https://gitlab.com/inkscape/inkscape/merge_requests/801
| -rw-r--r-- | share/icons/Tango/scalable/actions/horizontal.svg | 157 | ||||
| -rw-r--r-- | share/icons/Tango/scalable/actions/vertical.svg | 157 | ||||
| -rw-r--r-- | share/icons/hicolor/scalable/actions/horizontal.svg | 157 | ||||
| -rw-r--r-- | share/icons/hicolor/scalable/actions/vertical.svg | 157 | ||||
| -rw-r--r-- | share/icons/hicolor/symbolic/actions/horizontal-symbolic.svg | 157 | ||||
| -rw-r--r-- | share/icons/hicolor/symbolic/actions/vertical-symbolic.svg | 157 | ||||
| -rw-r--r-- | share/ui/dialog-css.ui | 24 | ||||
| -rw-r--r-- | share/ui/style.css | 66 | ||||
| -rw-r--r-- | src/inkscape.cpp | 21 | ||||
| -rw-r--r-- | src/ui/dialog/attrdialog.cpp | 207 | ||||
| -rw-r--r-- | src/ui/dialog/attrdialog.h | 17 | ||||
| -rw-r--r-- | src/ui/dialog/desktop-tracker.h | 2 | ||||
| -rw-r--r-- | src/ui/dialog/selectorsdialog.cpp | 156 | ||||
| -rw-r--r-- | src/ui/dialog/selectorsdialog.h | 12 | ||||
| -rw-r--r-- | src/ui/dialog/styledialog.cpp | 258 | ||||
| -rw-r--r-- | src/ui/dialog/styledialog.h | 19 | ||||
| -rw-r--r-- | src/ui/dialog/symbols.cpp | 2 | ||||
| -rw-r--r-- | src/ui/dialog/xml-tree.cpp | 128 | ||||
| -rw-r--r-- | src/ui/dialog/xml-tree.h | 10 |
19 files changed, 1591 insertions, 273 deletions
diff --git a/share/icons/Tango/scalable/actions/horizontal.svg b/share/icons/Tango/scalable/actions/horizontal.svg new file mode 100644 index 000000000..41f42514a --- /dev/null +++ b/share/icons/Tango/scalable/actions/horizontal.svg @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg1" + width="16" + height="16" + viewBox="0 0 16 16" + sodipodi:docname="horizontal-symbolic.svg" + inkscape:version="1.0alpha2 (cdfd683da9, 2019-08-11, custom)"> + <style + id="style82"></style> + <defs + id="defs250"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect942" + is_visible="true" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1" + unit="px" + method="auto" + mode="F" + radius="0.2" + chamfer_steps="1" + flexible="false" + use_knot_distance="false" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + hide_knots="false" + only_selected="false" + apply_with_radius="true" + apply_no_radius="true" + use_knot_distance="false" + flexible="false" + chamfer_steps="1" + radius="0.2" + mode="F" + method="auto" + unit="px" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1" + is_visible="true" + id="path-effect928" + effect="fillet_chamfer" /> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:snap-global="false" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + id="namedview" + showgrid="true" + inkscape:zoom="32" + inkscape:cx="5.4845974" + inkscape:cy="7.2243182" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:document-rotation="0" + inkscape:window-width="1280" + inkscape:window-height="960" + inkscape:window-maximized="1" + inkscape:current-layer="layercompo"> + <inkscape:grid + type="xygrid" + id="grid" /> + <sodipodi:guide + id="guide976" + orientation="0,-1" + position="8.96875,14.96875" /> + </sodipodi:namedview> + <metadata + id="metadata1906"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" /> + <dc:title></dc:title> + <dc:date>13 Nov 2018</dc:date> + <dc:creator> + <cc:Agent> + <dc:title>Ramón Miranda</dc:title> + </cc:Agent> + </dc:creator> + <dc:rights> + <cc:Agent> + <dc:title>see the license tab</dc:title> + </cc:Agent> + </dc:rights> + <dc:subject> + <rdf:Bag> + <rdf:li>icon ui</rdf:li> + </rdf:Bag> + </dc:subject> + <dc:description>This is a little contribution with Inkscape Project +Ramon Miranda www.ramonmiranda.com (design and SVG file) +Jabiertxo (SVG stuff to integrate them in UI)</dc:description> + <dc:publisher> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:publisher> + <dc:identifier /> + <dc:source /> + <dc:relation /> + <dc:language>-</dc:language> + <dc:coverage /> + <dc:contributor> + <cc:Agent> + <dc:title>Ramon Miranda +Jabier Arraiza</dc:title> + </cc:Agent> + </dc:contributor> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layercompo" + inkscape:label="feFlood"> + <path + id="rect22048" + d="M 0,0 H 16 V 16 H 0 Z" + style="opacity:0;fill:none" /> + <path + inkscape:connector-curvature="0" + d="M 15,1.3905104 C 15,1.1770724 14.831111,1 14.627537,1 H 8.1727921 C 8.1449961,1 8.1202361,1.00986 8.0940761,1.016104 A 0.17579185,0.18430973 0 0 0 8.0249587,1 H 1.372463 C 1.168889,1 1,1.1770724 1,1.3905104 V 14.60949 C 1,14.822928 1.168889,15 1.372463,15 h 6.6524957 a 0.17579185,0.18430973 0 0 0 0.071037,-0.0161 C 8.1215867,14.9899 8.1456487,15 8.1727917,15 H 14.627537 C 14.831111,15 15,14.822928 15,14.60949 Z m -0.351344,0 V 14.60949 c 0,0.01424 -0.0075,0.02214 -0.02112,0.02214 H 8.1996708 V 1.3683681 h 6.4278662 c 0.01358,0 0.02112,0.0079 0.02112,0.022142 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.359965;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" + id="path966" /> + <g + style="opacity:1" + transform="scale(1,-1)" + id="g968" /> + </g> +</svg> diff --git a/share/icons/Tango/scalable/actions/vertical.svg b/share/icons/Tango/scalable/actions/vertical.svg new file mode 100644 index 000000000..d625d2867 --- /dev/null +++ b/share/icons/Tango/scalable/actions/vertical.svg @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg1" + width="16" + height="16" + viewBox="0 0 16 16" + sodipodi:docname="vertical-symbolic.svg" + inkscape:version="1.0alpha2 (cdfd683da9, 2019-08-11, custom)"> + <style + id="style82"></style> + <defs + id="defs250"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect942" + is_visible="true" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1" + unit="px" + method="auto" + mode="F" + radius="0.2" + chamfer_steps="1" + flexible="false" + use_knot_distance="false" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + hide_knots="false" + only_selected="false" + apply_with_radius="true" + apply_no_radius="true" + use_knot_distance="false" + flexible="false" + chamfer_steps="1" + radius="0.2" + mode="F" + method="auto" + unit="px" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1" + is_visible="true" + id="path-effect928" + effect="fillet_chamfer" /> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:snap-global="false" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + id="namedview" + showgrid="true" + inkscape:zoom="32" + inkscape:cx="5.4845974" + inkscape:cy="7.2243182" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:document-rotation="0" + inkscape:window-width="1280" + inkscape:window-height="960" + inkscape:window-maximized="1" + inkscape:current-layer="layercompo"> + <inkscape:grid + type="xygrid" + id="grid" /> + <sodipodi:guide + id="guide976" + orientation="0,-1" + position="8.96875,14.96875" /> + </sodipodi:namedview> + <metadata + id="metadata1906"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" /> + <dc:title></dc:title> + <dc:date>13 Nov 2018</dc:date> + <dc:creator> + <cc:Agent> + <dc:title>Ramón Miranda</dc:title> + </cc:Agent> + </dc:creator> + <dc:rights> + <cc:Agent> + <dc:title>see the license tab</dc:title> + </cc:Agent> + </dc:rights> + <dc:subject> + <rdf:Bag> + <rdf:li>icon ui</rdf:li> + </rdf:Bag> + </dc:subject> + <dc:description>This is a little contribution with Inkscape Project +Ramon Miranda www.ramonmiranda.com (design and SVG file) +Jabiertxo (SVG stuff to integrate them in UI)</dc:description> + <dc:publisher> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:publisher> + <dc:identifier /> + <dc:source /> + <dc:relation /> + <dc:language>-</dc:language> + <dc:coverage /> + <dc:contributor> + <cc:Agent> + <dc:title>Ramon Miranda +Jabier Arraiza</dc:title> + </cc:Agent> + </dc:contributor> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layercompo" + inkscape:label="feFlood"> + <path + id="rect22048" + d="M 0,0 H 16 V 16 H 0 Z" + style="opacity:0;fill:none" /> + <path + inkscape:connector-curvature="0" + d="M 1.3905104,1 C 1.1770724,1 1,1.1688888 1,1.3724629 v 6.454745 c 0,0.027796 0.00986,0.052556 0.016104,0.078716 A 0.18430973,0.17579185 0 0 0 1,7.9750413 V 14.627537 C 1,14.831111 1.1770724,15 1.3905104,15 H 14.60949 C 14.822928,15 15,14.831111 15,14.627537 V 7.9750413 A 0.18430973,0.17579185 0 0 0 14.9839,7.9040043 C 14.9899,7.8784133 15,7.8543513 15,7.8272083 V 1.3724629 C 15,1.1688888 14.822928,1 14.60949,1 Z m 0,0.3513439 H 14.60949 c 0.01424,0 0.02214,0.00754 0.02214,0.021119 V 7.8003292 H 1.3683681 V 1.3724629 c 0,-0.013583 0.0079,-0.021119 0.022142,-0.021119 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.359965;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" + id="path966" /> + <g + style="opacity:1" + transform="scale(1,-1)" + id="g968" /> + </g> +</svg> diff --git a/share/icons/hicolor/scalable/actions/horizontal.svg b/share/icons/hicolor/scalable/actions/horizontal.svg new file mode 100644 index 000000000..41f42514a --- /dev/null +++ b/share/icons/hicolor/scalable/actions/horizontal.svg @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg1" + width="16" + height="16" + viewBox="0 0 16 16" + sodipodi:docname="horizontal-symbolic.svg" + inkscape:version="1.0alpha2 (cdfd683da9, 2019-08-11, custom)"> + <style + id="style82"></style> + <defs + id="defs250"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect942" + is_visible="true" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1" + unit="px" + method="auto" + mode="F" + radius="0.2" + chamfer_steps="1" + flexible="false" + use_knot_distance="false" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + hide_knots="false" + only_selected="false" + apply_with_radius="true" + apply_no_radius="true" + use_knot_distance="false" + flexible="false" + chamfer_steps="1" + radius="0.2" + mode="F" + method="auto" + unit="px" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1" + is_visible="true" + id="path-effect928" + effect="fillet_chamfer" /> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:snap-global="false" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + id="namedview" + showgrid="true" + inkscape:zoom="32" + inkscape:cx="5.4845974" + inkscape:cy="7.2243182" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:document-rotation="0" + inkscape:window-width="1280" + inkscape:window-height="960" + inkscape:window-maximized="1" + inkscape:current-layer="layercompo"> + <inkscape:grid + type="xygrid" + id="grid" /> + <sodipodi:guide + id="guide976" + orientation="0,-1" + position="8.96875,14.96875" /> + </sodipodi:namedview> + <metadata + id="metadata1906"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" /> + <dc:title></dc:title> + <dc:date>13 Nov 2018</dc:date> + <dc:creator> + <cc:Agent> + <dc:title>Ramón Miranda</dc:title> + </cc:Agent> + </dc:creator> + <dc:rights> + <cc:Agent> + <dc:title>see the license tab</dc:title> + </cc:Agent> + </dc:rights> + <dc:subject> + <rdf:Bag> + <rdf:li>icon ui</rdf:li> + </rdf:Bag> + </dc:subject> + <dc:description>This is a little contribution with Inkscape Project +Ramon Miranda www.ramonmiranda.com (design and SVG file) +Jabiertxo (SVG stuff to integrate them in UI)</dc:description> + <dc:publisher> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:publisher> + <dc:identifier /> + <dc:source /> + <dc:relation /> + <dc:language>-</dc:language> + <dc:coverage /> + <dc:contributor> + <cc:Agent> + <dc:title>Ramon Miranda +Jabier Arraiza</dc:title> + </cc:Agent> + </dc:contributor> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layercompo" + inkscape:label="feFlood"> + <path + id="rect22048" + d="M 0,0 H 16 V 16 H 0 Z" + style="opacity:0;fill:none" /> + <path + inkscape:connector-curvature="0" + d="M 15,1.3905104 C 15,1.1770724 14.831111,1 14.627537,1 H 8.1727921 C 8.1449961,1 8.1202361,1.00986 8.0940761,1.016104 A 0.17579185,0.18430973 0 0 0 8.0249587,1 H 1.372463 C 1.168889,1 1,1.1770724 1,1.3905104 V 14.60949 C 1,14.822928 1.168889,15 1.372463,15 h 6.6524957 a 0.17579185,0.18430973 0 0 0 0.071037,-0.0161 C 8.1215867,14.9899 8.1456487,15 8.1727917,15 H 14.627537 C 14.831111,15 15,14.822928 15,14.60949 Z m -0.351344,0 V 14.60949 c 0,0.01424 -0.0075,0.02214 -0.02112,0.02214 H 8.1996708 V 1.3683681 h 6.4278662 c 0.01358,0 0.02112,0.0079 0.02112,0.022142 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.359965;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" + id="path966" /> + <g + style="opacity:1" + transform="scale(1,-1)" + id="g968" /> + </g> +</svg> diff --git a/share/icons/hicolor/scalable/actions/vertical.svg b/share/icons/hicolor/scalable/actions/vertical.svg new file mode 100644 index 000000000..d625d2867 --- /dev/null +++ b/share/icons/hicolor/scalable/actions/vertical.svg @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg1" + width="16" + height="16" + viewBox="0 0 16 16" + sodipodi:docname="vertical-symbolic.svg" + inkscape:version="1.0alpha2 (cdfd683da9, 2019-08-11, custom)"> + <style + id="style82"></style> + <defs + id="defs250"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect942" + is_visible="true" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1" + unit="px" + method="auto" + mode="F" + radius="0.2" + chamfer_steps="1" + flexible="false" + use_knot_distance="false" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + hide_knots="false" + only_selected="false" + apply_with_radius="true" + apply_no_radius="true" + use_knot_distance="false" + flexible="false" + chamfer_steps="1" + radius="0.2" + mode="F" + method="auto" + unit="px" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1" + is_visible="true" + id="path-effect928" + effect="fillet_chamfer" /> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:snap-global="false" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + id="namedview" + showgrid="true" + inkscape:zoom="32" + inkscape:cx="5.4845974" + inkscape:cy="7.2243182" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:document-rotation="0" + inkscape:window-width="1280" + inkscape:window-height="960" + inkscape:window-maximized="1" + inkscape:current-layer="layercompo"> + <inkscape:grid + type="xygrid" + id="grid" /> + <sodipodi:guide + id="guide976" + orientation="0,-1" + position="8.96875,14.96875" /> + </sodipodi:namedview> + <metadata + id="metadata1906"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" /> + <dc:title></dc:title> + <dc:date>13 Nov 2018</dc:date> + <dc:creator> + <cc:Agent> + <dc:title>Ramón Miranda</dc:title> + </cc:Agent> + </dc:creator> + <dc:rights> + <cc:Agent> + <dc:title>see the license tab</dc:title> + </cc:Agent> + </dc:rights> + <dc:subject> + <rdf:Bag> + <rdf:li>icon ui</rdf:li> + </rdf:Bag> + </dc:subject> + <dc:description>This is a little contribution with Inkscape Project +Ramon Miranda www.ramonmiranda.com (design and SVG file) +Jabiertxo (SVG stuff to integrate them in UI)</dc:description> + <dc:publisher> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:publisher> + <dc:identifier /> + <dc:source /> + <dc:relation /> + <dc:language>-</dc:language> + <dc:coverage /> + <dc:contributor> + <cc:Agent> + <dc:title>Ramon Miranda +Jabier Arraiza</dc:title> + </cc:Agent> + </dc:contributor> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layercompo" + inkscape:label="feFlood"> + <path + id="rect22048" + d="M 0,0 H 16 V 16 H 0 Z" + style="opacity:0;fill:none" /> + <path + inkscape:connector-curvature="0" + d="M 1.3905104,1 C 1.1770724,1 1,1.1688888 1,1.3724629 v 6.454745 c 0,0.027796 0.00986,0.052556 0.016104,0.078716 A 0.18430973,0.17579185 0 0 0 1,7.9750413 V 14.627537 C 1,14.831111 1.1770724,15 1.3905104,15 H 14.60949 C 14.822928,15 15,14.831111 15,14.627537 V 7.9750413 A 0.18430973,0.17579185 0 0 0 14.9839,7.9040043 C 14.9899,7.8784133 15,7.8543513 15,7.8272083 V 1.3724629 C 15,1.1688888 14.822928,1 14.60949,1 Z m 0,0.3513439 H 14.60949 c 0.01424,0 0.02214,0.00754 0.02214,0.021119 V 7.8003292 H 1.3683681 V 1.3724629 c 0,-0.013583 0.0079,-0.021119 0.022142,-0.021119 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.359965;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" + id="path966" /> + <g + style="opacity:1" + transform="scale(1,-1)" + id="g968" /> + </g> +</svg> diff --git a/share/icons/hicolor/symbolic/actions/horizontal-symbolic.svg b/share/icons/hicolor/symbolic/actions/horizontal-symbolic.svg new file mode 100644 index 000000000..41f42514a --- /dev/null +++ b/share/icons/hicolor/symbolic/actions/horizontal-symbolic.svg @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg1" + width="16" + height="16" + viewBox="0 0 16 16" + sodipodi:docname="horizontal-symbolic.svg" + inkscape:version="1.0alpha2 (cdfd683da9, 2019-08-11, custom)"> + <style + id="style82"></style> + <defs + id="defs250"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect942" + is_visible="true" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1" + unit="px" + method="auto" + mode="F" + radius="0.2" + chamfer_steps="1" + flexible="false" + use_knot_distance="false" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + hide_knots="false" + only_selected="false" + apply_with_radius="true" + apply_no_radius="true" + use_knot_distance="false" + flexible="false" + chamfer_steps="1" + radius="0.2" + mode="F" + method="auto" + unit="px" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1" + is_visible="true" + id="path-effect928" + effect="fillet_chamfer" /> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:snap-global="false" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + id="namedview" + showgrid="true" + inkscape:zoom="32" + inkscape:cx="5.4845974" + inkscape:cy="7.2243182" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:document-rotation="0" + inkscape:window-width="1280" + inkscape:window-height="960" + inkscape:window-maximized="1" + inkscape:current-layer="layercompo"> + <inkscape:grid + type="xygrid" + id="grid" /> + <sodipodi:guide + id="guide976" + orientation="0,-1" + position="8.96875,14.96875" /> + </sodipodi:namedview> + <metadata + id="metadata1906"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" /> + <dc:title></dc:title> + <dc:date>13 Nov 2018</dc:date> + <dc:creator> + <cc:Agent> + <dc:title>Ramón Miranda</dc:title> + </cc:Agent> + </dc:creator> + <dc:rights> + <cc:Agent> + <dc:title>see the license tab</dc:title> + </cc:Agent> + </dc:rights> + <dc:subject> + <rdf:Bag> + <rdf:li>icon ui</rdf:li> + </rdf:Bag> + </dc:subject> + <dc:description>This is a little contribution with Inkscape Project +Ramon Miranda www.ramonmiranda.com (design and SVG file) +Jabiertxo (SVG stuff to integrate them in UI)</dc:description> + <dc:publisher> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:publisher> + <dc:identifier /> + <dc:source /> + <dc:relation /> + <dc:language>-</dc:language> + <dc:coverage /> + <dc:contributor> + <cc:Agent> + <dc:title>Ramon Miranda +Jabier Arraiza</dc:title> + </cc:Agent> + </dc:contributor> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layercompo" + inkscape:label="feFlood"> + <path + id="rect22048" + d="M 0,0 H 16 V 16 H 0 Z" + style="opacity:0;fill:none" /> + <path + inkscape:connector-curvature="0" + d="M 15,1.3905104 C 15,1.1770724 14.831111,1 14.627537,1 H 8.1727921 C 8.1449961,1 8.1202361,1.00986 8.0940761,1.016104 A 0.17579185,0.18430973 0 0 0 8.0249587,1 H 1.372463 C 1.168889,1 1,1.1770724 1,1.3905104 V 14.60949 C 1,14.822928 1.168889,15 1.372463,15 h 6.6524957 a 0.17579185,0.18430973 0 0 0 0.071037,-0.0161 C 8.1215867,14.9899 8.1456487,15 8.1727917,15 H 14.627537 C 14.831111,15 15,14.822928 15,14.60949 Z m -0.351344,0 V 14.60949 c 0,0.01424 -0.0075,0.02214 -0.02112,0.02214 H 8.1996708 V 1.3683681 h 6.4278662 c 0.01358,0 0.02112,0.0079 0.02112,0.022142 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.359965;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" + id="path966" /> + <g + style="opacity:1" + transform="scale(1,-1)" + id="g968" /> + </g> +</svg> diff --git a/share/icons/hicolor/symbolic/actions/vertical-symbolic.svg b/share/icons/hicolor/symbolic/actions/vertical-symbolic.svg new file mode 100644 index 000000000..d625d2867 --- /dev/null +++ b/share/icons/hicolor/symbolic/actions/vertical-symbolic.svg @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg1" + width="16" + height="16" + viewBox="0 0 16 16" + sodipodi:docname="vertical-symbolic.svg" + inkscape:version="1.0alpha2 (cdfd683da9, 2019-08-11, custom)"> + <style + id="style82"></style> + <defs + id="defs250"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect942" + is_visible="true" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1" + unit="px" + method="auto" + mode="F" + radius="0.2" + chamfer_steps="1" + flexible="false" + use_knot_distance="false" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + hide_knots="false" + only_selected="false" + apply_with_radius="true" + apply_no_radius="true" + use_knot_distance="false" + flexible="false" + chamfer_steps="1" + radius="0.2" + mode="F" + method="auto" + unit="px" + satellites_param="F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1 @ F,0,0,1,0,0.2,0,1" + is_visible="true" + id="path-effect928" + effect="fillet_chamfer" /> + </defs> + <sodipodi:namedview + inkscape:guide-bbox="true" + showguides="true" + inkscape:snap-global="false" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + id="namedview" + showgrid="true" + inkscape:zoom="32" + inkscape:cx="5.4845974" + inkscape:cy="7.2243182" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:document-rotation="0" + inkscape:window-width="1280" + inkscape:window-height="960" + inkscape:window-maximized="1" + inkscape:current-layer="layercompo"> + <inkscape:grid + type="xygrid" + id="grid" /> + <sodipodi:guide + id="guide976" + orientation="0,-1" + position="8.96875,14.96875" /> + </sodipodi:namedview> + <metadata + id="metadata1906"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" /> + <dc:title></dc:title> + <dc:date>13 Nov 2018</dc:date> + <dc:creator> + <cc:Agent> + <dc:title>Ramón Miranda</dc:title> + </cc:Agent> + </dc:creator> + <dc:rights> + <cc:Agent> + <dc:title>see the license tab</dc:title> + </cc:Agent> + </dc:rights> + <dc:subject> + <rdf:Bag> + <rdf:li>icon ui</rdf:li> + </rdf:Bag> + </dc:subject> + <dc:description>This is a little contribution with Inkscape Project +Ramon Miranda www.ramonmiranda.com (design and SVG file) +Jabiertxo (SVG stuff to integrate them in UI)</dc:description> + <dc:publisher> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:publisher> + <dc:identifier /> + <dc:source /> + <dc:relation /> + <dc:language>-</dc:language> + <dc:coverage /> + <dc:contributor> + <cc:Agent> + <dc:title>Ramon Miranda +Jabier Arraiza</dc:title> + </cc:Agent> + </dc:contributor> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layercompo" + inkscape:label="feFlood"> + <path + id="rect22048" + d="M 0,0 H 16 V 16 H 0 Z" + style="opacity:0;fill:none" /> + <path + inkscape:connector-curvature="0" + d="M 1.3905104,1 C 1.1770724,1 1,1.1688888 1,1.3724629 v 6.454745 c 0,0.027796 0.00986,0.052556 0.016104,0.078716 A 0.18430973,0.17579185 0 0 0 1,7.9750413 V 14.627537 C 1,14.831111 1.1770724,15 1.3905104,15 H 14.60949 C 14.822928,15 15,14.831111 15,14.627537 V 7.9750413 A 0.18430973,0.17579185 0 0 0 14.9839,7.9040043 C 14.9899,7.8784133 15,7.8543513 15,7.8272083 V 1.3724629 C 15,1.1688888 14.822928,1 14.60949,1 Z m 0,0.3513439 H 14.60949 c 0.01424,0 0.02214,0.00754 0.02214,0.021119 V 7.8003292 H 1.3683681 V 1.3724629 c 0,-0.013583 0.0079,-0.021119 0.022142,-0.021119 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.359965;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" + id="path966" /> + <g + style="opacity:1" + transform="scale(1,-1)" + id="g968" /> + </g> +</svg> diff --git a/share/ui/dialog-css.ui b/share/ui/dialog-css.ui index 6ffcabc71..682df1b93 100644 --- a/share/ui/dialog-css.ui +++ b/share/ui/dialog-css.ui @@ -31,10 +31,16 @@ </packing> </child> <child> - <object class="GtkLabel" id="CSSSelector"> + <object class="GtkEventBox" id="CSSSelectorEventBox"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">Selector</property> + <child> + <object class="GtkLabel" id="CSSSelector"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Selector</property> + </object> + </child> </object> <packing> <property name="expand">False</property> @@ -43,6 +49,17 @@ </packing> </child> <child> + <object class="GtkEntry" id="CSSEditSelector"> + <property name="can_focus">True</property> + <property name="no_show_all">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> <object class="GtkLabel"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -51,7 +68,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">2</property> + <property name="position">4</property> </packing> </child> </object> @@ -68,7 +85,6 @@ <property name="has_tooltip">True</property> <property name="hscroll_policy">natural</property> <property name="vscroll_policy">natural</property> - <property name="headers_visible">False</property> <property name="enable_search">False</property> <property name="fixed_height_mode">True</property> <property name="hover_selection">True</property> diff --git a/share/ui/style.css b/share/ui/style.css index a7bed5d59..6287a1622 100644 --- a/share/ui/style.css +++ b/share/ui/style.css @@ -66,7 +66,7 @@ * ::::::: Color based * ::::::: apply to colors * ::::::: scope widget and all his childs - * ".invert" invert colors + * ".inverted" invert colors * :::::::: Icon Based. * ".symbolic" Force icon symbolic * ".regular" Force colorful icons @@ -91,37 +91,22 @@ image { -gtk-icon-style: regular; } -.invert { - color: @theme_bg_color; - background-color: @theme_fg_color; - background-image: image(@theme_fg_color); -} - -.dark .forcebright { - color: @theme_bg_color; - background-color: @theme_fg_color; - background-image: image(@theme_fg_color); -} - +.inverted, +.dark .forcebright, .bright .forcedark { color: @theme_bg_color; background-color: @theme_fg_color; background-image: image(@theme_fg_color); } -.invert :not(overshoot):not(undershoot):not(.rawimage) { - color: inherit; - background-color: inherit; -} -.dark .forcebright :not(overshoot):not(undershoot):not(.rawimage) { - color: inherit; - background-color: inherit; -} -.bright .forcedark :not(overshoot):not(undershoot):not(.rawimage) { +.inverted :not(menuitem):not(.rawstyle):not(overshoot):not(undershoot):not(selection), +.bright .forcedark :not(menuitem):not(.rawstyle):not(overshoot):not(undershoot):not(selection), +.dark .forcebright :not(menuitem):not(.rawstyle):not(overshoot):not(undershoot):not(selection) { color: inherit; background-color: inherit; + background-image: inherit; } .combobright * { @@ -225,8 +210,8 @@ spinbutton undershoot { #LPESelectorFlowBox flowboxchild:selected image, #LPESelectorFlowBox flowboxchild:selected label { - background-color: @theme_selected_bg_color; color: @theme_selected_fg_color; + background-color: @theme_selected_bg_color; background-image: image(@theme_selected_bg_color); } @@ -311,6 +296,41 @@ spinbutton undershoot { padding-bottom: 0; } +#XMLAndAttributesDialog .radio.image-button, +#SelectorsAndStyleDialog .radio.image-button { + margin: 0; + padding: 0px; + border-radius: 2px 0 0 2px; +} + +#XMLAndAttributesDialog .radio.image-button:last-child, +#SelectorsAndStyleDialog .radio.image-button:last-child { + border-radius: 0 2px 2px 0; + border-left-width: 0; +} + +#SelectorsAndStyleDialog treeview button { + border-width: 0; + margin: 0 0 1px 0; +} + +#SelectorsAndStyleDialog treeview button:nth-child(3), +#SelectorsAndStyleDialog treeview.style_sheet button:nth-child(4) { + border-width: 0 0 0 2px; + border-color: @theme_fg_color; + border-style: solid; + opacity: 0.5; +} + +#SelectorsAndStyleDialog treeview.style_sheet button:nth-child(3) { + border-width: 0; +} + +#SelectorsAndStyleDialog treeview button { + min-height: 3px; + font-size: 1px; +} + #InkRuler { font-size: 7pt; } diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 661441729..f76ea3c22 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -526,16 +526,23 @@ Glib::ustring Application::get_symbolic_colors() css_str += colornamederror; css_str += ";}"; css_str += "#InkRuler,"; - css_str += "image:not(.rawimage)"; + /* ":not(.rawstyle) > image" works only on images in first level of widget container + if in the future we use a complex widget with more levels and we dont want to tweak the color + here, retaining default we can add more lines like ":not(.rawstyle) > > image" */ + css_str += ":not(.rawstyle) > image"; css_str += "{color:"; css_str += colornamed; css_str += ";}"; - css_str += ".dark .forcebright image:not(.rawimage),"; - css_str += ".bright .forcedark image:not(.rawimage),"; - css_str += ".dark image.forcebright:not(.rawimage),"; - css_str += ".bright image.forcedark:not(.rawimage),"; - css_str += ".invert image:not(.rawimage),"; - css_str += "image.invert:not(.rawimage)"; + css_str += ".dark .forcebright :not(.rawstyle) > image,"; + css_str += ".dark .forcebright image:not(.rawstyle),"; + css_str += ".bright .forcedark :not(.rawstyle) > image,"; + css_str += ".bright .forcedark image:not(.rawstyle),"; + css_str += ".dark :not(.rawstyle) > image.forcebright,"; + css_str += ".dark image.forcebright:not(.rawstyle),"; + css_str += ".bright :not(.rawstyle) > image.forcedark,"; + css_str += ".bright image.forcedark:not(.rawstyle),"; + css_str += ".inverse :not(.rawstyle) > image,"; + css_str += ".inverse image:not(.rawstyle)"; css_str += "{color:"; css_str += colornamed_inverse; css_str += ";}"; diff --git a/src/ui/dialog/attrdialog.cpp b/src/ui/dialog/attrdialog.cpp index 3db739059..a499602ce 100644 --- a/src/ui/dialog/attrdialog.cpp +++ b/src/ui/dialog/attrdialog.cpp @@ -58,7 +58,6 @@ namespace Inkscape { namespace UI { namespace Dialog { - /** * Constructor * A treeview whose each row corresponds to an XML attribute of a selected node @@ -72,6 +71,9 @@ AttrDialog::AttrDialog() set_size_request(20, 15); _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); _treeView.set_headers_visible(true); + _treeView.set_hover_selection(true); + _treeView.set_activate_on_single_click(true); + _treeView.set_can_focus(false); _scrolledWindow.add(_treeView); _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); @@ -103,16 +105,19 @@ AttrDialog::AttrDialog() _nameRenderer->property_editable() = true; _nameRenderer->property_placeholder_text().set_value(_("Attribute Name")); _nameRenderer->signal_edited().connect(sigc::mem_fun(*this, &AttrDialog::nameEdited)); + _nameRenderer->signal_editing_started().connect(sigc::mem_fun(*this, &AttrDialog::startNameEdit)); _treeView.append_column(_("Name"), *_nameRenderer); _nameCol = _treeView.get_column(1); if (_nameCol) { - _nameCol->add_attribute(_nameRenderer->property_text(), _attrColumns._attributeName); + _nameCol->set_resizable(true); + _nameCol->add_attribute(_nameRenderer->property_text(), _attrColumns._attributeName); } status.set_halign(Gtk::ALIGN_START); status.set_valign(Gtk::ALIGN_CENTER); status.set_size_request(1, -1); status.set_markup(""); status.set_line_wrap(true); + status.get_style_context()->add_class("inksmall"); status_box.pack_start(status, TRUE, TRUE, 0); _getContents()->pack_end(status_box, false, false, 2); @@ -126,19 +131,44 @@ AttrDialog::AttrDialog() _valueRenderer->property_placeholder_text().set_value(_("Attribute Value")); _valueRenderer->property_ellipsize().set_value(Pango::ELLIPSIZE_MIDDLE); _valueRenderer->signal_edited().connect(sigc::mem_fun(*this, &AttrDialog::valueEdited)); + _valueRenderer->signal_editing_started().connect(sigc::mem_fun(*this, &AttrDialog::startValueEdit)); _treeView.append_column(_("Value"), *_valueRenderer); _valueCol = _treeView.get_column(2); if (_valueCol) { _valueCol->add_attribute(_valueRenderer->property_text(), _attrColumns._attributeValue); } + _popover = Gtk::manage(new Gtk::Popover()); + Gtk::Box *vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + Gtk::Box *hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL)); + _textview = Gtk::manage(new Gtk::TextView()); + _textview->set_wrap_mode(Gtk::WrapMode::WRAP_CHAR); + _textview->set_editable(true); + _textview->set_monospace(true); + _textview->set_border_width(6); + Glib::RefPtr<Gtk::TextBuffer> textbuffer = Gtk::TextBuffer::create(); + textbuffer->set_text(""); + _textview->set_buffer(textbuffer); + _scrolled_text_view.add(*_textview); + _scrolled_text_view.set_max_content_height(450); + _scrolled_text_view.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + _scrolled_text_view.set_propagate_natural_width(true); + _update = Gtk::manage(new Gtk::Button(_("Update"))); + _update->signal_clicked().connect(sigc::mem_fun(*this, &AttrDialog::valueEditedPop)); + hbox->pack_end(*_update, Gtk::PACK_EXPAND_WIDGET, 3); + vbox->pack_start(_scrolled_text_view, Gtk::PACK_EXPAND_WIDGET, 3); + vbox->pack_start(*hbox, Gtk::PACK_EXPAND_WIDGET, 3); + _popover->add(*vbox); + _popover->hide(); + _popover->set_relative_to(_treeView); + _popover->set_position(Gtk::PositionType::POS_BOTTOM); + _popover->signal_closed().connect(sigc::mem_fun(*this, &AttrDialog::popClosed)); + _popover->get_style_context()->add_class("inverted"); attr_reset_context(0); _getContents()->pack_start(_mainBox, Gtk::PACK_EXPAND_WIDGET); - setDesktop(getDesktop()); + _updating = false; } - - /** * @brief AttrDialog::~AttrDialog * Class destructor @@ -152,6 +182,71 @@ AttrDialog::~AttrDialog() _message_changed_connection.~connection(); } +void AttrDialog::startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &path) +{ + Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell); + entry->signal_key_press_event().connect(sigc::bind(sigc::mem_fun(*this, &AttrDialog::onNameKeyPressed), entry)); +} + +gboolean sp_show_attr_pop(gpointer data) +{ + AttrDialog *attrdialog = reinterpret_cast<AttrDialog *>(data); + auto vscroll = attrdialog->_scrolled_text_view.get_vadjustment(); + int height = vscroll->get_upper() + 12; // padding 6+6 + if (height < 450) { + attrdialog->_scrolled_text_view.set_min_content_height(height); + } else { + attrdialog->_scrolled_text_view.set_min_content_height(450); + } + return FALSE; +} + +void AttrDialog::startValueEdit(Gtk::CellEditable *cell, const Glib::ustring &path) +{ + Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell); + entry->signal_key_press_event().connect(sigc::bind(sigc::mem_fun(*this, &AttrDialog::onValueKeyPressed), entry)); + int width = 0; + int height = 0; + int colwidth = _valueCol->get_width(); + _textview->set_size_request(colwidth - 6, -1); + _popover->set_size_request(colwidth, -1); + valuepath = path; + entry->get_layout()->get_pixel_size(width, height); + Gtk::TreeIter iter = *_store->get_iter(path); + Gtk::TreeModel::Row row = *iter; + if (row && this->_repr) { + Glib::ustring name = row[_attrColumns._attributeName]; + if (colwidth < width || name == "content") { + Gtk::TreeIter iter = *_store->get_iter(path); + Gdk::Rectangle rect; + _treeView.get_cell_area((Gtk::TreeModel::Path)iter, *_valueCol, rect); + if (_popover->get_position() == Gtk::PositionType::POS_BOTTOM) { + rect.set_y(rect.get_y() + 20); + } + _popover->set_pointing_to(rect); + Glib::RefPtr<Gtk::TextBuffer> textbuffer = Gtk::TextBuffer::create(); + textbuffer->set_text(entry->get_text()); + _textview->set_buffer(textbuffer); + cell->editing_done(); + cell->remove_widget(); + int scrolledcontentheight = 20; + if (name == "content") { + scrolledcontentheight = 450; + } + _scrolled_text_view.set_min_content_height(scrolledcontentheight); + _popover->show_all(); + _popover->check_resize(); + g_timeout_add(50, &sp_show_attr_pop, this); + } + } +} + +void AttrDialog::popClosed() +{ + Glib::RefPtr<Gtk::TextBuffer> textbuffer = Gtk::TextBuffer::create(); + textbuffer->set_text(""); + _textview->set_buffer(textbuffer); +} /** * @brief AttrDialog::setDesktop @@ -224,6 +319,9 @@ void AttrDialog::attr_reset_context(gint attr) */ void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, const gchar * new_value) { + if (_updating) { + return; + } for(auto iter: this->_store->children()) { Gtk::TreeModel::Row row = *iter; @@ -235,6 +333,7 @@ void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, co } else { _store->erase(iter); } + break; } } if (new_value && strcmp(new_value, "") != 0) { @@ -243,7 +342,7 @@ void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, co { return; } else { - Gtk::TreeModel::Row row = *(_store->append()); + Gtk::TreeModel::Row row = *(_store->prepend()); row[_attrColumns._attributeName] = name; row[_attrColumns._attributeValue] = new_value; } @@ -257,7 +356,7 @@ void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, co bool AttrDialog::onAttrCreate(GdkEventButton *event) { if(event->type == GDK_BUTTON_RELEASE && event->button == 1 && this->_repr) { - Gtk::TreeIter iter = _store->append(); + Gtk::TreeIter iter = _store->prepend(); Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iter; _treeView.set_cursor(path, *_nameCol, true); grab_focus(); @@ -298,39 +397,80 @@ bool AttrDialog::onKeyPressed(GdkEventKey *event) if(this->_repr) { auto selection = this->_treeView.get_selection(); Gtk::TreeModel::Row row = *(selection->get_selected()); + Gtk::TreeIter iter = *(selection->get_selected()); + bool ret = false; switch (event->keyval) { case GDK_KEY_Delete: - case GDK_KEY_KP_Delete: - { + case GDK_KEY_KP_Delete: { // Create new attribute (repeat code, fold into above event!) Glib::ustring name = row[_attrColumns._attributeName]; - if(name == "content") { - return true; - } else { + if (name != "content") { this->_store->erase(row); this->_repr->setAttribute(name.c_str(), nullptr, false); this->setUndo(_("Delete attribute")); } - return true; - } + ret = true; + } break; case GDK_KEY_plus: case GDK_KEY_Insert: { // Create new attribute (repeat code, fold into above event!) - Gtk::TreeIter iter = this->_store->append(); + Gtk::TreeIter iter = this->_store->prepend(); Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iter; this->_treeView.set_cursor(path, *this->_nameCol, true); grab_focus(); - return true; - } + ret = true; + } break; } } return false; } +bool AttrDialog::onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry) +{ + g_debug("StyleDialog::_onNameKeyPressed"); + bool ret = false; + switch (event->keyval) { + case GDK_KEY_Tab: + case GDK_KEY_KP_Tab: + entry->editing_done(); + ret = true; + break; + } + return ret; +} + + +bool AttrDialog::onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry) +{ + g_debug("StyleDialog::_onValueKeyPressed"); + bool ret = false; + switch (event->keyval) { + case GDK_KEY_Tab: + case GDK_KEY_KP_Tab: + entry->editing_done(); + ret = true; + break; + } + return ret; +} + +gboolean sp_attrdialog_store_move_to_next(gpointer data) +{ + AttrDialog *attrdialog = reinterpret_cast<AttrDialog *>(data); + auto selection = attrdialog->_treeView.get_selection(); + Gtk::TreeIter iter = *(selection->get_selected()); + Gtk::TreeModel::Path model = (Gtk::TreeModel::Path)iter; + if (model == attrdialog->_modelpath) { + attrdialog->_treeView.set_cursor(attrdialog->_modelpath, *attrdialog->_valueCol, true); + } + return FALSE; +} /** + * + * * @brief AttrDialog::nameEdited * @param event * @return @@ -339,36 +479,44 @@ bool AttrDialog::onKeyPressed(GdkEventKey *event) void AttrDialog::nameEdited (const Glib::ustring& path, const Glib::ustring& name) { Gtk::TreeIter iter = *_store->get_iter(path); - Gtk::TreeModel::Path modelpath = (Gtk::TreeModel::Path)iter; + _modelpath = (Gtk::TreeModel::Path)iter; Gtk::TreeModel::Row row = *iter; if(row && this->_repr) { Glib::ustring old_name = row[_attrColumns._attributeName]; if (old_name == name) { - _treeView.set_cursor(modelpath, *_valueCol, true); + g_timeout_add(50, &sp_attrdialog_store_move_to_next, this); grab_focus(); return; } - if (old_name == "content" || - old_name == name) - { + if (old_name == "content") { return; } Glib::ustring value = row[_attrColumns._attributeValue]; // Move to editing value, we set the name as a temporary store value if (!old_name.empty()) { // Remove old named value + _updating = true; _repr->setAttribute(old_name.c_str(), nullptr, false); + _updating = false; } if (!name.empty()) { row[_attrColumns._attributeName] = name; - _repr->setAttribute(name.c_str(), value, false); - _treeView.set_cursor(modelpath, *_valueCol, true); grab_focus(); + _updating = true; + _repr->setAttribute(name.c_str(), value, false); + _updating = false; + g_timeout_add(50, &sp_attrdialog_store_move_to_next, this); } this->setUndo(_("Rename attribute")); } } +void AttrDialog::valueEditedPop() +{ + Glib::ustring value = _textview->get_buffer()->get_text(); + valueEdited(valuepath, value); +} + /** * @brief AttrDialog::valueEdited * @param event @@ -380,6 +528,10 @@ void AttrDialog::valueEdited (const Glib::ustring& path, const Glib::ustring& va Gtk::TreeModel::Row row = *_store->get_iter(path); if(row && this->_repr) { Glib::ustring name = row[_attrColumns._attributeName]; + Glib::ustring old_value = row[_attrColumns._attributeValue]; + if (old_value == value) { + return; + } if(name.empty()) return; if (name == "content") { _repr->setContent(value.c_str()); @@ -389,7 +541,14 @@ void AttrDialog::valueEdited (const Glib::ustring& path, const Glib::ustring& va if(!value.empty()) { row[_attrColumns._attributeValue] = value; } + Inkscape::Selection *selection = _desktop->getSelection(); + SPObject *obj = nullptr; + if (selection->objects().size() == 1) { + obj = selection->objects().back(); + obj->style->readFromObject(obj); + obj->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } this->setUndo(_("Change attribute value")); } } diff --git a/src/ui/dialog/attrdialog.h b/src/ui/dialog/attrdialog.h index 68ea14cc9..2c57447c4 100644 --- a/src/ui/dialog/attrdialog.h +++ b/src/ui/dialog/attrdialog.h @@ -17,7 +17,9 @@ #include "message.h" #include <gtkmm/dialog.h> #include <gtkmm/liststore.h> +#include <gtkmm/popover.h> #include <gtkmm/scrolledwindow.h> +#include <gtkmm/textview.h> #include <gtkmm/treeview.h> #include <ui/widget/panel.h> @@ -61,6 +63,11 @@ public: Gtk::CellRendererText *_valueRenderer; Gtk::TreeViewColumn *_nameCol; Gtk::TreeViewColumn *_valueCol; + Gtk::TreeModel::Path _modelpath; + Gtk::Popover *_popover; + Gtk::TextView *_textview; + Gtk::Button *_update; + Glib::ustring valuepath; /** * Status bar @@ -71,14 +78,15 @@ public: // Widgets Gtk::VBox _mainBox; Gtk::ScrolledWindow _scrolledWindow; + Gtk::ScrolledWindow _scrolled_text_view; Gtk::HBox _buttonBox; Gtk::Button _buttonAddAttribute; - // Variables - Inkscape SPDesktop* _desktop; Inkscape::XML::Node* _repr; Gtk::HBox status_box; Gtk::Label status; + bool _updating; // Helper functions void setDesktop(SPDesktop* desktop) override; @@ -95,12 +103,17 @@ public: */ sigc::connection _message_changed_connection; void onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, const gchar * new_value); + bool onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry); + bool onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry); void onAttrDelete(Glib::ustring path); bool onAttrCreate(GdkEventButton *event); bool onKeyPressed(GdkEventKey *event); + void popClosed(); + void startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &path); + void startValueEdit(Gtk::CellEditable *cell, const Glib::ustring &path); void nameEdited(const Glib::ustring &path, const Glib::ustring &name); void valueEdited(const Glib::ustring &path, const Glib::ustring &value); - + void valueEditedPop(); }; diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h index b681c9ca1..7b9439006 100644 --- a/src/ui/dialog/desktop-tracker.h +++ b/src/ui/dialog/desktop-tracker.h @@ -46,7 +46,7 @@ private: SPDesktop *base; SPDesktop *desktop; GtkWidget *widget; - gulong hierID; + unsigned long hierID; sigc::connection inkID; bool trackActive; sigc::signal<void, SPDesktop*> desktopChangedSig; diff --git a/src/ui/dialog/selectorsdialog.cpp b/src/ui/dialog/selectorsdialog.cpp index eda036c58..89d109ae9 100644 --- a/src/ui/dialog/selectorsdialog.cpp +++ b/src/ui/dialog/selectorsdialog.cpp @@ -19,9 +19,10 @@ #include "inkscape.h" #include "selection.h" #include "style.h" -#include "verbs.h" #include "ui/icon-loader.h" +#include "ui/icon-names.h" #include "ui/widget/iconrenderer.h" +#include "verbs.h" #include "xml/attribute-record.h" #include "xml/node-observer.h" @@ -200,69 +201,6 @@ bool SelectorsDialog::TreeStore::row_draggable_vfunc(const Gtk::TreeModel::Path return Gtk::TreeStore::row_draggable_vfunc(path); } -void SelectorsDialog::fixCSSSelectors(Glib::ustring &selector) -{ - g_debug("SelectorsDialog::fixCSSSelectors"); - REMOVE_SPACES(selector); - Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me - CRSelector *cr_selector = cr_selector_parse_from_buf((guchar *)my_selector.c_str(), CR_UTF_8); - selector = Glib::ustring(""); - CRSelector const *cur = nullptr; - for (cur = cr_selector; cur; cur = cur->next) { - if (cur->simple_sel) { - gchar *selectorchar = reinterpret_cast<gchar *>(cr_simple_sel_to_string(cur->simple_sel)); - if (selectorchar) { - Glib::ustring toadd = Glib::ustring(selectorchar); - selector = selector.empty() ? toadd : selector + "," + toadd; - g_free(selectorchar); - } - } - } - std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,]+", selector); - std::vector<Glib::ustring> selectorresult; - selector = Glib::ustring(""); - for (auto token : tokens) { - REMOVE_SPACES(token); - std::vector<Glib::ustring> tokensplus = Glib::Regex::split_simple("[ ]+", token); - Glib::ustring selectorpart = Glib::ustring(""); - for (auto tokenplus : tokensplus) { - REMOVE_SPACES(tokenplus); - Glib::ustring toparse = Glib::ustring(tokenplus); - Glib::ustring tag = Glib::ustring(""); - if (toparse[0] != '.' && toparse[0] != '#') { - auto i = std::min(toparse.find("#"), toparse.find(".")); - tag = toparse.substr(0, i); - if (!SPAttributeRelSVG::isSVGElement(tag)) { - continue; - } - if (i != std::string::npos) { - toparse.erase(0, i); - } else { - toparse = tag; - selectorpart = selectorpart == Glib::ustring("") ? toparse : selectorpart + " " + toparse; - continue; - } - } - auto i = toparse.find("#"); - if (i != std::string::npos) { - toparse.erase(i, 1); - } - auto j = toparse.find("#"); - if (i != std::string::npos && j != std::string::npos) { - continue; - } else if (i != std::string::npos) { - toparse.insert(i, "#"); - } - toparse = tag + toparse; - selectorpart = selectorpart == Glib::ustring("") ? toparse : selectorpart + " " + toparse; - } - selectorresult.push_back(selectorpart); - } - for (auto selectorpart : selectorresult) { - selector = selector == Glib::ustring("") ? selectorpart : selector + "," + selectorpart; - } -} - /** * Allow dropping only in between other selectors. */ @@ -404,19 +342,30 @@ void SelectorsDialog::_showWidgets() _vadj = _scrolled_window_selectors.get_vadjustment(); _vadj->signal_value_changed().connect(sigc::mem_fun(*this, &SelectorsDialog::_vscrool)); _selectors_box.pack_start(_scrolled_window_selectors, Gtk::PACK_EXPAND_WIDGET); - Gtk::Label *dirtogglerlabel = Gtk::manage(new Gtk::Label(_("Paned vertical"))); + /* Gtk::Label *dirtogglerlabel = Gtk::manage(new Gtk::Label(_("Paned vertical"))); dirtogglerlabel->get_style_context()->add_class("inksmall"); _direction.property_active() = dir; _direction.property_active().signal_changed().connect(sigc::mem_fun(*this, &SelectorsDialog::_toggleDirection)); - _direction.get_style_context()->add_class("inkswitch"); + _direction.get_style_context()->add_class("inkswitch"); */ _styleButton(_create, "list-add", "Add a new CSS Selector"); _create.signal_clicked().connect(sigc::mem_fun(*this, &SelectorsDialog::_addSelector)); _styleButton(_del, "list-remove", "Remove a CSS Selector"); _button_box.pack_start(_create, Gtk::PACK_SHRINK); _button_box.pack_start(_del, Gtk::PACK_SHRINK); - _button_box.pack_start(_direction, false, false, 0); - _button_box.pack_start(*dirtogglerlabel, false, false, 0); - _selectors_box.pack_end(_button_box, false, false, 0); + Gtk::RadioButton::Group group; + Gtk::RadioButton *_horizontal = Gtk::manage(new Gtk::RadioButton()); + Gtk::RadioButton *_vertical = Gtk::manage(new Gtk::RadioButton()); + _horizontal->set_image_from_icon_name(INKSCAPE_ICON("horizontal")); + _vertical->set_image_from_icon_name(INKSCAPE_ICON("vertical")); + _horizontal->set_group(group); + _vertical->set_group(group); + _vertical->set_active(dir); + _vertical->signal_toggled().connect( + sigc::bind(sigc::mem_fun(*this, &SelectorsDialog::_toggleDirection), _vertical)); + _horizontal->property_draw_indicator() = false; + _vertical->property_draw_indicator() = false; + _button_box.pack_end(*_horizontal, false, false, 0); + _button_box.pack_end(*_vertical, false, false, 0); _del.signal_clicked().connect(sigc::mem_fun(*this, &SelectorsDialog::_delSelector)); _del.hide(); _style_dialog = new StyleDialog; @@ -424,36 +373,62 @@ void SelectorsDialog::_showWidgets() _paned.pack1(*_style_dialog, Gtk::SHRINK); _paned.pack2(_selectors_box, true, true); _getContents()->pack_start(_paned, Gtk::PACK_EXPAND_WIDGET); + _getContents()->pack_start(_button_box, false, false, 0); show_all(); int widthpos = _paned.property_max_position(); int panedpos = prefs->getInt("/dialogs/selectors/panedpos", 130); _paned.set_position(panedpos); _paned.property_wide_handle() = true; - _paned.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectorsDialog::_resized), false); + _paned.property_position().signal_changed().connect(sigc::mem_fun(*this, &SelectorsDialog::_childresized)); + _paned.signal_size_allocate().connect(sigc::mem_fun(*this, &SelectorsDialog::_panedresized)); set_size_request(320, 260); set_name("SelectorsAndStyleDialog"); } -bool SelectorsDialog::_resized(GdkEventButton *event) +void SelectorsDialog::_panedresized(Gtk::Allocation allocation) +{ + g_debug("SelectorsDialog::_panedresized"); + _resized(); +} + +void SelectorsDialog::_childresized() +{ + g_debug("SelectorsDialog::_childresized"); + _resized(); +} + +void SelectorsDialog::_resized() { g_debug("SelectorsDialog::_resized"); _scroollock = true; + if (_updating) { + return; + } + _updating = true; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool dir = !prefs->getBool("/dialogs/selectors/vertical", true); + int max = int(_paned.property_max_position() * 0.95); + int min = int(_paned.property_max_position() * 0.05); + if (_paned.get_position() > max) { + _paned.property_position() = max; + } + if (_paned.get_position() < min) { + _paned.property_position() = min; + } prefs->setInt("/dialogs/selectors/panedpos", _paned.get_position()); - return false; + _updating = false; } - -void SelectorsDialog::_toggleDirection() +void SelectorsDialog::_toggleDirection(Gtk::RadioButton *vertical) { g_debug("SelectorsDialog::_toggleDirection"); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool dir = !prefs->getBool("/dialogs/selectors/vertical", true); + bool dir = vertical->get_active(); prefs->setBool("/dialogs/selectors/vertical", dir); _paned.set_orientation(dir ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL); - int widthpos = _paned.property_max_position(); + _paned.check_resize(); + int widthpos = _paned.property_max_position() - _paned.property_min_position(); prefs->setInt("/dialogs/selectors/panedpos", widthpos / 2); _paned.set_position(widthpos / 2); } @@ -573,7 +548,7 @@ void SelectorsDialog::_readStyleElement() for (unsigned i = 0; i < tokens.size() - 1; i += 2) { Glib::ustring selector = tokens[i]; REMOVE_SPACES(selector); // Remove leading/trailing spaces - fixCSSSelectors(selector); + selector = _style_dialog->fixCSSSelectors(selector); for (auto &row : _store->children()) { Glib::ustring selectorold = row[_mColumns._colSelector]; if (selectorold == selector) { @@ -588,7 +563,7 @@ void SelectorsDialog::_readStyleElement() Glib::ustring selector = tokens[i]; REMOVE_SPACES(selector); // Remove leading/trailing spaces Glib::ustring selector_old = selector; - fixCSSSelectors(selector); + selector = _style_dialog->fixCSSSelectors(selector); if (selector_old != selector) { rewrite = true; } @@ -778,8 +753,12 @@ Glib::ustring sp_get_selector_classes(Glib::ustring selector) //, SelectorType s REMOVE_SPACES(selector); Glib::ustring toparse = Glib::ustring(selector); selector = Glib::ustring(""); + auto i = toparse.find("."); + if (i == std::string::npos) { + return ""; + } if (toparse[0] != '.' && toparse[0] != '#') { - auto i = std::min(toparse.find("#"), toparse.find(".")); + i = std::min(toparse.find("#"), toparse.find(".")); Glib::ustring tag = toparse.substr(0, i); if (!SPAttributeRelSVG::isSVGElement(tag)) { return selector; @@ -788,7 +767,7 @@ Glib::ustring sp_get_selector_classes(Glib::ustring selector) //, SelectorType s toparse.erase(0, i); } } - auto i = toparse.find("#"); + i = toparse.find("#"); if (i != std::string::npos) { toparse.erase(i, 1); } @@ -856,7 +835,7 @@ void SelectorsDialog::_addToSelector(Gtk::TreeModel::Row row) if (insertid) { multiselector = multiselector + ",#" + id; } - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + Gtk::TreeModel::Row childrow = *(_store->prepend(row->children())); childrow[_mColumns._colSelector] = "#" + Glib::ustring(id); childrow[_mColumns._colExpand] = false; childrow[_mColumns._colType] = OBJECT; @@ -1093,6 +1072,9 @@ void SelectorsDialog::_selectObjects(int eventX, int eventY) int y2 = 0; // To do: We should be able to do this via passing in row. if (_treeView.get_path_at_pos(eventX, eventY, path, col, x2, y2)) { + if (_lastpath.size() && _lastpath == path) { + return; + } if (col == _treeView.get_column(1) && x2 > 25) { getDesktop()->selection->clear(); Gtk::TreeModel::iterator iter = _store->get_iter(path); @@ -1108,6 +1090,7 @@ void SelectorsDialog::_selectObjects(int eventX, int eventY) getDesktop()->selection->add(obj); } } + _lastpath = path; } } } @@ -1179,9 +1162,8 @@ void SelectorsDialog::_addSelector() * for selector. If the entrybox is empty, the text (thus selectorName) is * set to ".Class1" */ - selectorValue = textEditPtr->get_text(); + selectorValue = _style_dialog->fixCSSSelectors(Glib::ustring(textEditPtr->get_text())); _del.show(); - fixCSSSelectors(selectorValue); if (selectorValue.empty()) { textLabelPtr->show(); } else { @@ -1190,7 +1172,6 @@ void SelectorsDialog::_addSelector() } delete textDialogPtr; // ==== Handle response ==== - // If class selector, add selector name to class attribute for each object REMOVE_SPACES(selectorValue); std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,]+", selectorValue); @@ -1214,7 +1195,7 @@ void SelectorsDialog::_addSelector() } } objVec = _getObjVec(selectorValue); - Gtk::TreeModel::Row row = *(_store->append()); + Gtk::TreeModel::Row row = *(_store->prepend()); row[_mColumns._colExpand] = true; row[_mColumns._colType] = SELECTOR; row[_mColumns._colSelector] = selectorValue; @@ -1223,7 +1204,7 @@ void SelectorsDialog::_addSelector() row[_mColumns._colVisible] = true; row[_mColumns._colSelected] = 400; for (auto &obj : objVec) { - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + Gtk::TreeModel::Row childrow = *(_store->prepend(row->children())); childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); childrow[_mColumns._colExpand] = false; childrow[_mColumns._colType] = OBJECT; @@ -1382,6 +1363,7 @@ void SelectorsDialog::_handleDesktopChanged(SPDesktop *desktop) void SelectorsDialog::_handleSelectionChanged() { g_debug("SelectorsDialog::_handleSelectionChanged()"); + _lastpath.clear(); _treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); _selectRow(); } diff --git a/src/ui/dialog/selectorsdialog.h b/src/ui/dialog/selectorsdialog.h index 6830a0124..66d9bb859 100644 --- a/src/ui/dialog/selectorsdialog.h +++ b/src/ui/dialog/selectorsdialog.h @@ -15,12 +15,13 @@ #ifndef SELECTORSDIALOG_H #define SELECTORSDIALOG_H -#include "ui/dialog/styledialog.h" #include "ui/dialog/desktop-tracker.h" #include "ui/dialog/dialog-manager.h" +#include "ui/dialog/styledialog.h" #include "ui/widget/panel.h" #include <gtkmm/dialog.h> #include <gtkmm/paned.h> +#include <gtkmm/radiobutton.h> #include <gtkmm/scrolledwindow.h> #include <gtkmm/switch.h> #include <gtkmm/treemodelfilter.h> @@ -64,7 +65,6 @@ class SelectorsDialog : public Widget::Panel { // Monitor all objects for addition/removal/attribute change class NodeWatcher; enum SelectorType { CLASS, ID, TAG }; - void fixCSSSelectors(Glib::ustring &selector); std::vector<SelectorsDialog::NodeWatcher *> _nodeWatchers; void _nodeAdded( Inkscape::XML::Node &repr ); void _nodeRemoved( Inkscape::XML::Node &repr ); @@ -117,10 +117,10 @@ class SelectorsDialog : public Widget::Panel { Glib::RefPtr<Gtk::TreeModelFilter> _modelfilter; Glib::RefPtr<TreeStore> _store; Gtk::TreeView _treeView; + Gtk::TreeModel::Path _lastpath; // Widgets Gtk::Paned _paned; Glib::RefPtr<Gtk::Adjustment> _vadj; - Gtk::Switch _direction; Gtk::Box _button_box; Gtk::Box _selectors_box; Gtk::ScrolledWindow _scrolled_window_selectors; @@ -146,9 +146,11 @@ class SelectorsDialog : public Widget::Panel { void _insertClass(SPObject *obj, const Glib::ustring &className); void _removeClass(const std::vector<SPObject *> &objVec, const Glib::ustring &className, bool all = false); void _removeClass(SPObject *obj, const Glib::ustring &className, bool all = false); - void _toggleDirection(); + void _toggleDirection(Gtk::RadioButton *vertical); void _showWidgets(); - bool _resized(GdkEventButton *event); + void _resized(); + void _childresized(); + void _panedresized(Gtk::Allocation allocation); void _selectObjects(int, int); // Variables diff --git a/src/ui/dialog/styledialog.cpp b/src/ui/dialog/styledialog.cpp index 75b44f831..884da2df2 100644 --- a/src/ui/dialog/styledialog.cpp +++ b/src/ui/dialog/styledialog.cpp @@ -201,18 +201,11 @@ StyleDialog::StyleDialog() Gtk::Box *alltoggler = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL)); Gtk::Label *infotoggler = Gtk::manage(new Gtk::Label(_("Edit Full Stylesheet"))); infotoggler->get_style_context()->add_class("inksmall"); - _all_css = Gtk::manage(new Gtk::Switch()); _vadj = _scrolledWindow.get_vadjustment(); _vadj->signal_value_changed().connect(sigc::mem_fun(*this, &StyleDialog::_vscrool)); - //_all_css->property_active().signal_changed().connect(sigc::mem_fun(*this, &StyleDialog::_reload)); - // alltoggler->pack_start(*_all_css, false, false, 0); - // alltoggler->pack_start(*infotoggler, false, false, 0); - //_all_css->set_active(false); - //_mainBox.pack_start(*alltoggler, false, false, 0); _mainBox.set_orientation(Gtk::ORIENTATION_VERTICAL); _getContents()->pack_start(_mainBox, Gtk::PACK_EXPAND_WIDGET); - //_all_css->get_style_context()->add_class("inkswitch"); // Document & Desktop _desktop_changed_connection = _desktopTracker.connectDesktopChanged(sigc::mem_fun(*this, &StyleDialog::_handleDesktopChanged)); @@ -223,6 +216,7 @@ StyleDialog::StyleDialog() _selection_changed_connection = getDesktop()->getSelection()->connectChanged( sigc::hide(sigc::mem_fun(this, &StyleDialog::_handleSelectionChanged))); + // Add watchers _updateWatchers(); @@ -240,6 +234,43 @@ void StyleDialog::_vscrool() } } +Glib::ustring StyleDialog::fixCSSSelectors(Glib::ustring selector) +{ + g_debug("SelectorsDialog::fixCSSSelectors"); + REMOVE_SPACES(selector); + Glib::ustring selector_out = ""; + std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,]+", selector); + for (auto token : tokens) { + if (!selector_out.empty()) { + selector_out += ","; + } + REMOVE_SPACES(token); + std::vector<Glib::ustring> subtokens = Glib::Regex::split_simple("[ ]+", token); + for (auto subtoken : subtokens) { + REMOVE_SPACES(subtoken); + Glib::ustring my_selector = subtoken + " {"; // Parsing fails sometimes without '{'. Fix me + CRSelector *cr_selector = cr_selector_parse_from_buf((guchar *)my_selector.c_str(), CR_UTF_8); + gchar *selectorchar = reinterpret_cast<gchar *>(cr_selector_to_string(cr_selector)); + if (selectorchar) { + Glib::ustring toadd = Glib::ustring(selectorchar); + g_free(selectorchar); + if (toadd[0] != '.' && toadd[0] != '#' && toadd.size() > 1) { + auto i = std::min(toadd.find("#"), toadd.find(".")); + Glib::ustring tag = toadd; + if (i != std::string::npos) { + tag = tag.substr(0, i); + } + if (!SPAttributeRelSVG::isSVGElement(tag)) { + return ""; + } + } + selector_out = selector_out.empty() ? toadd : selector_out + " " + toadd; + } + } + } + return selector_out; +} + /** * Class destructor */ @@ -466,6 +497,7 @@ void StyleDialog::_readStyleElement() css_selector->set_text("element"); Gtk::TreeView *css_tree; _builder->get_widget("CSSTree", css_tree); + css_tree->get_style_context()->add_class("style_element"); Glib::RefPtr<Gtk::TreeStore> store = Gtk::TreeStore::create(_mColumns); css_tree->set_model(store); css_selector_event_add->signal_button_release_event().connect( @@ -473,7 +505,7 @@ void StyleDialog::_readStyleElement() sigc::mem_fun(*this, &StyleDialog::_addRow), store, css_tree, "style_properties", selectorpos)); Inkscape::UI::Widget::IconRenderer *addRenderer = manage(new Inkscape::UI::Widget::IconRenderer()); addRenderer->add_icon("edit-delete"); - int addCol = css_tree->append_column("Delete row", *addRenderer) - 1; + int addCol = css_tree->append_column("", *addRenderer) - 1; Gtk::TreeViewColumn *col = css_tree->get_column(addCol); if (col) { addRenderer->signal_activated().connect( @@ -485,9 +517,10 @@ void StyleDialog::_readStyleElement() label->signal_edited().connect(sigc::bind<Glib::RefPtr<Gtk::TreeStore>, Gtk::TreeView *>( sigc::mem_fun(*this, &StyleDialog::_nameEdited), store, css_tree)); label->signal_editing_started().connect(sigc::mem_fun(*this, &StyleDialog::_startNameEdit)); - addCol = css_tree->append_column("CSS Property", *label) - 1; + addCol = css_tree->append_column("", *label) - 1; col = css_tree->get_column(addCol); if (col) { + col->set_resizable(true); col->add_attribute(label->property_text(), _mColumns._colName); } Gtk::CellRendererText *value = Gtk::manage(new Gtk::CellRendererText()); @@ -497,7 +530,7 @@ void StyleDialog::_readStyleElement() sigc::bind<Glib::RefPtr<Gtk::TreeStore>>(sigc::mem_fun(*this, &StyleDialog::_valueEdited), store)); value->signal_editing_started().connect( sigc::bind<Glib::RefPtr<Gtk::TreeStore>>(sigc::mem_fun(*this, &StyleDialog::_startValueEdit), store)); - addCol = css_tree->append_column("CSS Value", *value) - 1; + addCol = css_tree->append_column("", *value) - 1; col = css_tree->get_column(addCol); if (col) { col->add_attribute(value->property_text(), _mColumns._colValue); @@ -506,7 +539,7 @@ void StyleDialog::_readStyleElement() Inkscape::UI::Widget::IconRenderer *urlRenderer = manage(new Inkscape::UI::Widget::IconRenderer()); urlRenderer->add_icon("empty"); urlRenderer->add_icon("edit-redo"); - int urlCol = css_tree->append_column("Go to", *urlRenderer) - 1; + int urlCol = css_tree->append_column("", *urlRenderer) - 1; Gtk::TreeViewColumn *urlcol = css_tree->get_column(urlCol); if (urlcol) { urlRenderer->signal_activated().connect( @@ -515,19 +548,19 @@ void StyleDialog::_readStyleElement() } std::map<Glib::ustring, Glib::ustring> attr_prop; Gtk::TreeModel::Path path; - if (!_all_css->get_active() && obj && obj->getRepr()->attribute("style")) { + if (obj && obj->getRepr()->attribute("style")) { Glib::ustring style = obj->getRepr()->attribute("style"); attr_prop = parseStyle(style); for (auto iter : obj->style->properties()) { if (attr_prop.count(iter->name)) { - Gtk::TreeModel::Row row = *(store->append()); + Gtk::TreeModel::Row row = *(store->prepend()); row[_mColumns._colSelector] = "style_properties"; row[_mColumns._colSelectorPos] = 0; row[_mColumns._colActive] = true; row[_mColumns._colName] = iter->name; row[_mColumns._colValue] = iter->get_value(); row[_mColumns._colStrike] = false; - row[_mColumns._colOwner] = Glib::ustring("Value active"); + row[_mColumns._colOwner] = Glib::ustring("Current value"); row[_mColumns._colHref] = nullptr; row[_mColumns._colLinked] = false; if (is_url(iter->get_value().c_str())) { @@ -554,7 +587,7 @@ void StyleDialog::_readStyleElement() REMOVE_SPACES(selector); // Remove leading/trailing spaces // Get list of objects selector matches std::vector<SPObject *> objVec = _getObjVec(selector); - if (obj && !_all_css->get_active()) { + if (obj) { bool stop = true; for (auto objel : objVec) { if (objel->getId() == obj->getId()) { @@ -592,14 +625,25 @@ void StyleDialog::_readStyleElement() _builder->get_widget("CSSSelectorContainer", css_selector_container); Gtk::Label *css_selector; _builder->get_widget("CSSSelector", css_selector); + Gtk::EventBox *css_selector_event_box; + _builder->get_widget("CSSSelectorEventBox", css_selector_event_box); + Gtk::Entry *css_edit_selector; + _builder->get_widget("CSSEditSelector", css_edit_selector); Gtk::EventBox *css_selector_event_add; _builder->get_widget("CSSSelectorEventAdd", css_selector_event_add); css_selector_event_add->add_events(Gdk::BUTTON_RELEASE_MASK); css_selector->set_text(selector); Gtk::TreeView *css_tree; _builder->get_widget("CSSTree", css_tree); + css_tree->get_style_context()->add_class("style_sheet"); Glib::RefPtr<Gtk::TreeStore> store = Gtk::TreeStore::create(_mColumns); css_tree->set_model(store); + css_selector_event_box->signal_button_release_event().connect( + sigc::bind(sigc::mem_fun(*this, &StyleDialog::_selectorStartEdit), css_selector, css_edit_selector)); + css_edit_selector->signal_key_press_event().connect(sigc::bind( + sigc::mem_fun(*this, &StyleDialog::_selectorEditKeyPress), store, css_selector, css_edit_selector)); + css_edit_selector->signal_activate().connect( + sigc::bind(sigc::mem_fun(*this, &StyleDialog::_selectorActivate), store, css_selector, css_edit_selector)); Inkscape::UI::Widget::IconRenderer *addRenderer = manage(new Inkscape::UI::Widget::IconRenderer()); addRenderer->add_icon("edit-delete"); int addCol = css_tree->append_column("Delete row", *addRenderer) - 1; @@ -625,6 +669,7 @@ void StyleDialog::_readStyleElement() addCol = css_tree->append_column("CSS Selector", *label) - 1; col = css_tree->get_column(addCol); if (col) { + col->set_resizable(true); col->add_attribute(label->property_text(), _mColumns._colName); } Gtk::CellRendererText *value = Gtk::manage(new Gtk::CellRendererText()); @@ -662,7 +707,7 @@ void StyleDialog::_readStyleElement() css_selector_event_add->signal_button_release_event().connect( sigc::bind<Glib::RefPtr<Gtk::TreeStore>, Gtk::TreeView *, Glib::ustring, gint>( sigc::mem_fun(*this, &StyleDialog::_addRow), store, css_tree, selector, selectorpos)); - if (obj && !_all_css->get_active()) { + if (obj) { for (auto iter : result_props) { Gtk::TreeIter iterstore = store->append(); Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iterstore; @@ -690,7 +735,7 @@ void StyleDialog::_readStyleElement() row[_mColumns._colOwner] = Glib::ustring(""); } else { row[_mColumns._colStrike] = false; - row[_mColumns._colOwner] = Glib::ustring("Value active"); + row[_mColumns._colOwner] = Glib::ustring("Current value"); _addOwnerStyle(iter.first, selector); } } else { @@ -701,7 +746,7 @@ void StyleDialog::_readStyleElement() } } else { for (auto iter : result_props) { - Gtk::TreeModel::Row row = *(store->append()); + Gtk::TreeModel::Row row = *(store->prepend()); row[_mColumns._colSelector] = selector; row[_mColumns._colSelectorPos] = selectorpos; row[_mColumns._colActive] = iter.second.second; @@ -727,12 +772,13 @@ void StyleDialog::_readStyleElement() css_selector_event_add->add_events(Gdk::BUTTON_RELEASE_MASK); store = Gtk::TreeStore::create(_mColumns); _builder->get_widget("CSSTree", css_tree); + css_tree->get_style_context()->add_class("style_attribute"); css_tree->set_model(store); css_selector_event_add->signal_button_release_event().connect( sigc::bind<Glib::RefPtr<Gtk::TreeStore>, Gtk::TreeView *, Glib::ustring, gint>( sigc::mem_fun(*this, &StyleDialog::_addRow), store, css_tree, "attributes", selectorpos)); bool hasattributes = false; - if (obj && !_all_css->get_active()) { + if (obj) { for (auto iter : obj->style->properties()) { if (iter->style_src != SP_STYLE_SRC_UNSET) { if (iter->name != "font" && iter->name != "d" && iter->name != "marker") { @@ -757,6 +803,7 @@ void StyleDialog::_readStyleElement() addCol = css_tree->append_column("CSS Property", *label) - 1; col = css_tree->get_column(addCol); if (col) { + col->set_resizable(true); col->add_attribute(label->property_text(), _mColumns._colName); } Gtk::CellRendererText *value = Gtk::manage(new Gtk::CellRendererText()); @@ -774,7 +821,7 @@ void StyleDialog::_readStyleElement() col->add_attribute(value->property_strikethrough(), _mColumns._colStrike); } } - Gtk::TreeIter iterstore = store->append(); + Gtk::TreeIter iterstore = store->prepend(); Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iterstore; Gtk::TreeModel::Row row = *(iterstore); row[_mColumns._colSelector] = "attributes"; @@ -788,7 +835,7 @@ void StyleDialog::_readStyleElement() row[_mColumns._colOwner] = tooltiptext; } else { row[_mColumns._colStrike] = false; - row[_mColumns._colOwner] = Glib::ustring("Value active"); + row[_mColumns._colOwner] = Glib::ustring("Current value"); _addOwnerStyle(iter->name, "inline attributes"); } hasattributes = true; @@ -826,6 +873,43 @@ void StyleDialog::_readStyleElement() _updating = false; } +bool StyleDialog::_selectorStartEdit(GdkEventButton *event, Gtk::Label *selector, Gtk::Entry *selector_edit) +{ + g_debug("StyleDialog::_selectorStartEdit"); + if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { + selector->hide(); + selector_edit->set_text(selector->get_text()); + selector_edit->show(); + } + return false; +} + +void StyleDialog::_selectorActivate(Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector, Gtk::Entry *selector_edit) +{ + g_debug("StyleDialog::_selectorEditKeyPress"); + bool ret = false; + Glib::ustring newselector = fixCSSSelectors(selector_edit->get_text()); + if (newselector.empty()) { + selector_edit->get_style_context()->add_class("system_error_color"); + return; + } + _writeStyleElement(store, selector->get_text(), selector_edit->get_text()); +} + +bool StyleDialog::_selectorEditKeyPress(GdkEventKey *event, Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector, + Gtk::Entry *selector_edit) +{ + g_debug("StyleDialog::_selectorEditKeyPress"); + switch (event->keyval) { + case GDK_KEY_Escape: + selector->show(); + selector_edit->hide(); + selector_edit->get_style_context()->remove_class("system_error_color"); + break; + } + return false; +} + bool StyleDialog::_on_foreach_iter(const Gtk::TreeModel::iterator &iter) { g_debug("StyleDialog::_on_foreach_iter"); @@ -921,7 +1005,8 @@ std::map<Glib::ustring, Glib::ustring> StyleDialog::parseStyle(Glib::ustring sty /** * Update the content of the style element as selectors (or objects) are added/removed. */ -void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::ustring selector) +void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::ustring selector, + Glib::ustring new_selector) { g_debug("StyleDialog::_writeStyleElemen"); if (_updating) { @@ -936,7 +1021,7 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u if (!obj) { obj = getDesktop()->getDocument()->getXMLDialogSelectedObject(); } - if (selection->objects().size() < 2 && !obj && !_all_css->get_active()) { + if (selection->objects().size() < 2 && !obj) { _readStyleElement(); return; } @@ -944,6 +1029,9 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u gint selectorpos = 0; std::string styleContent = ""; if (selector != "style_properties" && selector != "attributes") { + if (!new_selector.empty()) { + selector = new_selector; + } styleContent = "\n" + selector + " { \n"; } for (auto &row : store->children()) { @@ -965,13 +1053,17 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u styleContent = styleContent + "}"; } if (selector == "style_properties") { + _updating = true; obj->getRepr()->setAttribute("style", styleContent, false); + _updating = false; } else if (selector == "attributes") { for (auto iter : obj->style->properties()) { if (iter->name != "font" && iter->name != "d" && iter->name != "marker") { const gchar *attr = obj->getRepr()->attribute(iter->name.c_str()); if (attr) { + _updating = true; obj->getRepr()->setAttribute(iter->name.c_str(), nullptr); + _updating = false; } } } @@ -979,13 +1071,15 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u Glib::ustring name = row[_mColumns._colName]; Glib::ustring value = row[_mColumns._colValue]; if (!(name.empty() && value.empty())) { + _updating = true; obj->getRepr()->setAttribute(name.c_str(), value, false); + _updating = false; } } } else if (!selector.empty()) { // styleshet // We could test if styleContent is empty and then delete the style node here but there is no // harm in keeping it around ... - SPDocument *document = SP_ACTIVE_DOCUMENT; + std::string pos = std::to_string(selectorpos); std::string selectormatch = "("; for (selectorpos; selectorpos > 1; selectorpos--) { @@ -998,14 +1092,16 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u std::string result; std::regex_replace(std::back_inserter(result), content.begin(), content.end(), e, "$1" + styleContent + "$3"); textNode->setContent(result.c_str()); - INKSCAPE.readStyleSheets(); - for (auto iter : document->getObjectsBySelector(selector)) { - iter->style->readFromObject(iter); - iter->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - } + INKSCAPE.readStyleSheets(true); } _updating = false; _readStyleElement(); + /* SPDocument *document = SP_ACTIVE_DOCUMENT; + for (auto iter : document->getObjectsBySelector(selector)) { + std::cout << std::endl; + iter->style->readFromObject(iter); + iter->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } */ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_STYLE, _("Edited style element.")); g_debug("StyleDialog::_writeStyleElement(): | %s |", styleContent.c_str()); @@ -1017,7 +1113,7 @@ bool StyleDialog::_addRow(GdkEventButton *evt, Glib::RefPtr<Gtk::TreeStore> stor g_debug("StyleDialog::_addRow"); if (evt->type == GDK_BUTTON_RELEASE && evt->button == 1) { - Gtk::TreeIter iter = store->append(); + Gtk::TreeIter iter = store->prepend(); Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iter; Gtk::TreeModel::Row row = *(iter); row[_mColumns._colSelector] = selector; @@ -1050,7 +1146,7 @@ void StyleDialog::_setAutocompletion(Gtk::Entry *entry, SPStyleEnum const cssenu gint counter = 0; const char * key = cssenum[counter].key; while (key) { - Gtk::TreeModel::Row row = *(completionModel->append()); + Gtk::TreeModel::Row row = *(completionModel->prepend()); row[_mCSSData._colCSSData] = Glib::ustring(key); counter++; key = cssenum[counter].key; @@ -1144,7 +1240,9 @@ StyleDialog::_startValueEdit(Gtk::CellEditable* cell, const Glib::ustring& path, _setAutocompletion(entry, enum_color_interpolation); } entry->signal_key_release_event().connect( - sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onValueKeyReleased), cell)); + sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onValueKeyReleased), entry)); + entry->signal_key_press_event().connect( + sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onValueKeyPressed), entry)); } } @@ -1165,7 +1263,22 @@ void StyleDialog::_startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &p } Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell); entry->set_completion(entry_completion); - entry->signal_key_release_event().connect(sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onNameKeyReleased), cell)); + entry->signal_key_release_event().connect( + sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onNameKeyReleased), entry)); + entry->signal_key_press_event().connect(sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onNameKeyPressed), entry)); +} + + +gboolean sp_styledialog_store_move_to_next(gpointer data) +{ + StyleDialog *styledialog = reinterpret_cast<StyleDialog *>(data); + auto selection = styledialog->_current_css_tree->get_selection(); + Gtk::TreeIter iter = *(selection->get_selected()); + Gtk::TreeModel::Path model = (Gtk::TreeModel::Path)iter; + if (model == styledialog->_current_path) { + styledialog->_current_css_tree->set_cursor(styledialog->_current_path, *styledialog->_current_value_col, true); + } + return FALSE; } /** @@ -1181,9 +1294,10 @@ void StyleDialog::_nameEdited(const Glib::ustring &path, const Glib::ustring &na _scroollock = true; Gtk::TreeModel::Row row = *store->get_iter(path); - Gtk::TreeModel::Path pathel = (Gtk::TreeModel::Path)*store->get_iter(path); + _current_path = (Gtk::TreeModel::Path)*store->get_iter(path); if (row) { + _current_css_tree = css_tree; Glib::ustring finalname = name; auto i = std::min(finalname.find(";"), finalname.find(":")); if (i != std::string::npos) { @@ -1197,7 +1311,7 @@ void StyleDialog::_nameEdited(const Glib::ustring &path, const Glib::ustring &na Glib::ustring selector = row[_mColumns._colSelector]; Glib::ustring value = row[_mColumns._colValue]; bool is_attr = selector == "attributes"; - + Glib::ustring old_name = row[_mColumns._colName]; row[_mColumns._colName] = finalname; if (finalname.empty() && value.empty()) { store->erase(row); @@ -1206,10 +1320,11 @@ void StyleDialog::_nameEdited(const Glib::ustring &path, const Glib::ustring &na if (pos < 1 || is_attr) { col = 2; } - if (write) { + _current_value_col = css_tree->get_column(col); + if (write && old_name != name) { _writeStyleElement(store, selector); } else { - css_tree->set_cursor(pathel, *(css_tree->get_column(col)), true); + g_timeout_add(50, &sp_styledialog_store_move_to_next, this); grab_focus(); } } @@ -1235,6 +1350,10 @@ void StyleDialog::_valueEdited(const Glib::ustring &path, const Glib::ustring &v if (i != std::string::npos) { finalvalue.erase(i, finalvalue.size() - i); } + Glib::ustring old_value = row[_mColumns._colValue]; + if (old_value == finalvalue) { + return; + } row[_mColumns._colValue] = finalvalue; Glib::ustring selector = row[_mColumns._colSelector]; Glib::ustring name = row[_mColumns._colName]; @@ -1258,56 +1377,81 @@ void StyleDialog::_activeToggled(const Glib::ustring &path, Glib::RefPtr<Gtk::Tr } } -bool StyleDialog::_onNameKeyReleased(GdkEventKey *event, Gtk::CellEditable *cell) +bool StyleDialog::_onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry) { g_debug("StyleDialog::_onNameKeyReleased"); - + bool ret = false; switch (event->keyval) { case GDK_KEY_Tab: case GDK_KEY_KP_Tab: - case GDK_KEY_colon: { - cell->editing_done(); - return true; - } + entry->editing_done(); + ret = true; + break; + } + return ret; +} + +bool StyleDialog::_onNameKeyReleased(GdkEventKey *event, Gtk::Entry *entry) +{ + g_debug("StyleDialog::_onNameKeyReleased"); + bool ret = false; + switch (event->keyval) { + case GDK_KEY_equal: + case GDK_KEY_colon: + entry->editing_done(); + ret = true; + break; case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: case GDK_KEY_semicolon: { - Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell); Glib::ustring text = entry->get_text(); auto i = std::min(text.find(";"), text.find(":")); if (i != std::string::npos) { - cell->editing_done(); - return true; + entry->editing_done(); + ret = true; } + break; } } - return false; + return ret; } -bool StyleDialog::_onValueKeyReleased(GdkEventKey *event, Gtk::CellEditable *cell) +bool StyleDialog::_onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry) { g_debug("StyleDialog::_onValueKeyReleased"); - + bool ret = false; switch (event->keyval) { case GDK_KEY_Tab: case GDK_KEY_KP_Tab: - case GDK_KEY_semicolon: { - cell->editing_done(); - return true; - } + entry->editing_done(); + ret = true; + break; + } + return ret; +} + +bool StyleDialog::_onValueKeyReleased(GdkEventKey *event, Gtk::Entry *entry) +{ + g_debug("StyleDialog::_onValueKeyReleased"); + bool ret = false; + switch (event->keyval) { + case GDK_KEY_semicolon: + entry->editing_done(); + ret = true; + break; case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: case GDK_KEY_colon: { - Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell); Glib::ustring text = entry->get_text(); auto i = std::min(text.find(";"), text.find(":")); if (i != std::string::npos) { - cell->editing_done(); - return true; + entry->editing_done(); + ret = true; } + break; } } - return false; + return ret; } void StyleDialog::_addWatcherRecursive(Inkscape::XML::Node *node) diff --git a/src/ui/dialog/styledialog.h b/src/ui/dialog/styledialog.h index 90b9d298f..b7ccf6619 100644 --- a/src/ui/dialog/styledialog.h +++ b/src/ui/dialog/styledialog.h @@ -67,6 +67,10 @@ class StyleDialog : public Widget::Panel { static StyleDialog &getInstance() { return *new StyleDialog(); } void setCurrentSelector(Glib::ustring current_selector); + Gtk::TreeView *_current_css_tree; + Gtk::TreeViewColumn *_current_value_col; + Gtk::TreeModel::Path _current_path; + Glib::ustring fixCSSSelectors(Glib::ustring selector); private: // Monitor <style> element for changes. @@ -119,21 +123,26 @@ class StyleDialog : public Widget::Panel { Glib::RefPtr<Gtk::Adjustment> _vadj; Gtk::Box _mainBox; Gtk::Box _styleBox; - Gtk::Switch *_all_css; - // Reading and writing the style element. Inkscape::XML::Node *_getStyleTextNode(); void _readStyleElement(); Glib::RefPtr<Gtk::TreeModel> _selectTree(Glib::ustring selector); - void _writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::ustring selector); + void _writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::ustring selector, + Glib::ustring new_selector = ""); + void _selectorActivate(Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector, Gtk::Entry *selector_edit); + bool _selectorEditKeyPress(GdkEventKey *event, Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector, + Gtk::Entry *selector_edit); + bool _selectorStartEdit(GdkEventButton *event, Gtk::Label *selector, Gtk::Entry *selector_edit); void _activeToggled(const Glib::ustring &path, Glib::RefPtr<Gtk::TreeStore> store); bool _addRow(GdkEventButton *evt, Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeView *css_tree, Glib::ustring selector, gint pos); void _onPropDelete(Glib::ustring path, Glib::RefPtr<Gtk::TreeStore> store); void _nameEdited(const Glib::ustring &path, const Glib::ustring &name, Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeView *css_tree); - bool _onNameKeyReleased(GdkEventKey *event, Gtk::CellEditable *cell); - bool _onValueKeyReleased(GdkEventKey *event, Gtk::CellEditable *cell); + bool _onNameKeyReleased(GdkEventKey *event, Gtk::Entry *entry); + bool _onValueKeyReleased(GdkEventKey *event, Gtk::Entry *entry); + bool _onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry); + bool _onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry); void _onLinkObj(Glib::ustring path, Glib::RefPtr<Gtk::TreeStore> store); void _valueEdited(const Glib::ustring &path, const Glib::ustring &value, Glib::RefPtr<Gtk::TreeStore> store); void _startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &path); diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index de5184058..2ecf612d2 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -207,7 +207,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : overlay_opacity = new Gtk::Image(); overlay_opacity->set_halign(Gtk::ALIGN_START); overlay_opacity->set_valign(Gtk::ALIGN_START); - overlay_opacity->get_style_context()->add_class("rawimage"); + overlay_opacity->get_style_context()->add_class("rawstyle"); // No results overlay_icon = sp_get_icon_image("searching", Gtk::ICON_SIZE_DIALOG); diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 91c24bd4c..ef0131168 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -46,27 +46,28 @@ namespace Inkscape { namespace UI { namespace Dialog { -XmlTree::XmlTree() : - UI::Widget::Panel("/dialogs/xml/", SP_VERB_DIALOG_XML_EDITOR), - blocked (0), - _message_stack (nullptr), - _message_context (nullptr), - current_desktop (nullptr), - current_document (nullptr), - selected_attr (0), - selected_repr (nullptr), - tree (nullptr), - status (""), - tree_toolbar(), - xml_element_new_button ( _("New element node")), - xml_text_new_button ( _("New text node")), - xml_node_delete_button ( Q_("nodeAsInXMLdialogTooltip|Delete node")), - xml_node_duplicate_button ( _("Duplicate node")), - unindent_node_button(), - indent_node_button(), - raise_node_button(), - lower_node_button(), - new_window(nullptr) +XmlTree::XmlTree() + : UI::Widget::Panel("/dialogs/xml/", SP_VERB_DIALOG_XML_EDITOR) + , blocked(0) + , _message_stack(nullptr) + , _message_context(nullptr) + , current_desktop(nullptr) + , current_document(nullptr) + , selected_attr(0) + , selected_repr(nullptr) + , tree(nullptr) + , status("") + , tree_toolbar() + , xml_element_new_button(_("New element node")) + , xml_text_new_button(_("New text node")) + , xml_node_delete_button(Q_("nodeAsInXMLdialogTooltip|Delete node")) + , xml_node_duplicate_button(_("Duplicate node")) + , unindent_node_button() + , indent_node_button() + , raise_node_button() + , lower_node_button() + , new_window(nullptr) + , _updating(false) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; @@ -79,6 +80,7 @@ XmlTree::XmlTree() : status.set_size_request(1, -1); status.set_markup(""); status.set_line_wrap(true); + status.get_style_context()->add_class("inksmall"); status_box.pack_start( status, TRUE, TRUE, 0); contents->pack_start(_paned, true, true, 0); contents->set_valign(Gtk::ALIGN_FILL); @@ -172,28 +174,35 @@ XmlTree::XmlTree() : Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool attrtoggler = prefs->getBool("/dialogs/xml/attrtoggler", true); bool dir = prefs->getBool("/dialogs/xml/vertical", true); - attributes = new AttrDialog; + attributes = new AttrDialog(); _paned.set_orientation(dir ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL); + _paned.check_resize(); _paned.pack1(node_box, Gtk::SHRINK); /* attributes */ Gtk::Box *actionsbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL)); actionsbox->set_valign(Gtk::ALIGN_START); Gtk::Label *attrtogglerlabel = Gtk::manage(new Gtk::Label(_("Show attributes"))); attrtogglerlabel->set_margin_right(5); - _attrswitch.property_active() = attrtoggler; _attrswitch.get_style_context()->add_class("inkswitch"); + _attrswitch.get_style_context()->add_class("rawstyle"); + _attrswitch.property_active() = attrtoggler; _attrswitch.property_active().signal_changed().connect(sigc::mem_fun(*this, &XmlTree::_attrtoggler)); attrtogglerlabel->get_style_context()->add_class("inksmall"); - _dirtogglerlabel = Gtk::manage(new Gtk::Label(_("Paned vertical"))); - _direction.property_active() = dir; - _direction.property_active().signal_changed().connect(sigc::mem_fun(*this, &XmlTree::_toggleDirection)); - _direction.get_style_context()->add_class("inkswitch"); - _dirtogglerlabel->get_style_context()->add_class("inksmall"); - actionsbox->pack_start(_attrswitch, Gtk::PACK_SHRINK); actionsbox->pack_start(*attrtogglerlabel, Gtk::PACK_SHRINK); - actionsbox->pack_start(_direction, Gtk::PACK_SHRINK); - actionsbox->pack_start(*_dirtogglerlabel, Gtk::PACK_SHRINK); - + actionsbox->pack_start(_attrswitch, Gtk::PACK_SHRINK); + Gtk::RadioButton::Group group; + Gtk::RadioButton *_horizontal = Gtk::manage(new Gtk::RadioButton()); + Gtk::RadioButton *_vertical = Gtk::manage(new Gtk::RadioButton()); + _horizontal->set_image_from_icon_name(INKSCAPE_ICON("horizontal")); + _vertical->set_image_from_icon_name(INKSCAPE_ICON("vertical")); + _horizontal->set_group(group); + _vertical->set_group(group); + _vertical->set_active(dir); + _vertical->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &XmlTree::_toggleDirection), _vertical)); + _horizontal->property_draw_indicator() = false; + _vertical->property_draw_indicator() = false; + actionsbox->pack_end(*_horizontal, false, false, 0); + actionsbox->pack_end(*_vertical, false, false, 0); _paned.pack2(*attributes, true, true); contents->pack_start(*actionsbox, false, false, 0); /* Signal handlers */ @@ -213,22 +222,16 @@ XmlTree::XmlTree() : desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &XmlTree::set_tree_desktop) ); deskTrack.connect(GTK_WIDGET(gobj())); int widthpos = _paned.property_max_position(); - int panedpos = prefs->getInt("/dialogs/xml/panedpos", 130); - - _paned.set_position(panedpos); - _paned.signal_button_release_event().connect(sigc::mem_fun(*this, &XmlTree::_resized), - false); /* initial show/hide */ + _paned.property_position().signal_changed().connect(sigc::mem_fun(*this, &XmlTree::_childresized)); + _paned.signal_size_allocate().connect(sigc::mem_fun(*this, &XmlTree::_panedresized)); set_name("XMLAndAttributesDialog"); set_spacing(0); set_size_request(320, 260); show_all(); _paned.property_wide_handle() = true; - if (!attrtoggler) { - attributes->hide(); - _dirtogglerlabel->hide(); - _direction.hide(); - _paned.set_position(widthpos); - } + int panedpos = prefs->getInt("/dialogs/xml/panedpos", 130); + _paned.set_position(panedpos); + _resized(); tree_reset_context(); g_assert(desktop != nullptr); @@ -236,20 +239,43 @@ XmlTree::XmlTree() : } -bool XmlTree::_resized(GdkEventButton *event) +void XmlTree::_panedresized(Gtk::Allocation allocation) { _resized(); } + +void XmlTree::_childresized() { _resized(); } + +void XmlTree::_resized() { + if (_updating) { + return; + } + _updating = true; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool dir = !prefs->getBool("/dialogs/xml/vertical", true); + int max = int(_paned.property_max_position() * 0.95); + int min = int(_paned.property_max_position() * 0.05); + bool attrtoggler = prefs->getBool("/dialogs/xml/attrtoggler", true); + if (attrtoggler && _paned.get_position() > max) { + _paned.property_position() = max; + } + if (attrtoggler && _paned.get_position() < min) { + _paned.property_position() = min; + } + if (!attrtoggler) { + attributes->hide(); + _paned.property_position() = _paned.property_max_position(); + } prefs->setInt("/dialogs/xml/panedpos", _paned.get_position()); - return true; + _updating = false; } -void XmlTree::_toggleDirection() +void XmlTree::_toggleDirection(Gtk::RadioButton *vertical) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool dir = !prefs->getBool("/dialogs/xml/vertical", true); + bool dir = vertical->get_active(); prefs->setBool("/dialogs/xml/vertical", dir); _paned.set_orientation(dir ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL); - int widthpos = _paned.property_max_position(); + _paned.check_resize(); + int widthpos = _paned.property_max_position() - _paned.property_min_position(); prefs->setInt("/dialogs/xml/panedpos", widthpos / 2); _paned.set_position(widthpos / 2); } @@ -261,15 +287,11 @@ void XmlTree::_attrtoggler() prefs->setBool("/dialogs/xml/attrtoggler", attrtoggler); if (attrtoggler) { attributes->show(); - _dirtogglerlabel->show(); - _direction.show(); - int widthpos = _paned.property_max_position(); + int widthpos = _paned.property_max_position() - _paned.property_min_position(); prefs->setInt("/dialogs/xml/panedpos", widthpos / 2); _paned.set_position(widthpos / 2); } else { attributes->hide(); - _dirtogglerlabel->hide(); - _direction.hide(); int widthpos = _paned.property_max_position(); _paned.set_position(widthpos); } diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h index f9c3c1c02..ea24ac52b 100644 --- a/src/ui/dialog/xml-tree.h +++ b/src/ui/dialog/xml-tree.h @@ -19,6 +19,7 @@ #include <gtkmm/button.h> #include <gtkmm/entry.h> #include <gtkmm/paned.h> +#include <gtkmm/radiobutton.h> #include <gtkmm/scrolledwindow.h> #include <gtkmm/separatortoolitem.h> #include <gtkmm/switch.h> @@ -166,8 +167,10 @@ private: void present() override; void _attrtoggler(); - void _toggleDirection(); - bool _resized(GdkEventButton *event); + void _toggleDirection(Gtk::RadioButton *vertical); + void _resized(); + void _childresized(); + void _panedresized(Gtk::Allocation allocation); bool in_dt_coordsys(SPObject const &item); /** @@ -180,6 +183,7 @@ private: */ gint blocked; + bool _updating; /** * Status bar */ @@ -217,8 +221,6 @@ private: Gtk::VBox node_box; Gtk::HBox status_box; Gtk::Switch _attrswitch; - Gtk::Switch _direction; - Gtk::Label *_dirtogglerlabel; Gtk::Label status; Gtk::Toolbar tree_toolbar; Gtk::ToolButton xml_element_new_button; |
