diff options
| -rw-r--r-- | icons/inx/apply_attribute.svg | 119 | ||||
| -rw-r--r-- | lib/extensions/__init__.py | 2 | ||||
| -rw-r--r-- | lib/extensions/apply_attribute.py | 47 | ||||
| -rw-r--r-- | templates/apply_attribute.xml | 35 |
4 files changed, 203 insertions, 0 deletions
diff --git a/icons/inx/apply_attribute.svg b/icons/inx/apply_attribute.svg new file mode 100644 index 00000000..9280df9f --- /dev/null +++ b/icons/inx/apply_attribute.svg @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xml:space="preserve" + width="99.999901mm" + height="100mm" + version="1.1" + style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision" + viewBox="0 0 15109 15109.485" + id="svg5" + sodipodi:docname="apply_attribute.svg" + inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview + id="namedview5" + pagecolor="#ffffff" + bordercolor="#000000" + borderopacity="0.25" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:document-units="mm" + inkscape:zoom="1.4765" + inkscape:cx="187.26719" + inkscape:cy="133.42364" + inkscape:window-width="1920" + inkscape:window-height="1131" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="Layer_x0020_1" + showgrid="false" /><defs + id="defs1"><symbol + id="inkstitch_trim"> + <title + id="inkstitch_title9282">Trim the thread after sewing this object.</title> + <path + id="inkstitch_circle13405" + d="m 9.2465284,-8.6e-6 c 1.8e-6,2.452339 -0.9741847,4.804237 -2.7082493,6.538304 C 4.8042146,8.2723614 2.4523174,9.2465504 -2.1625959e-5,9.2465514 -2.4523623,9.2465534 -4.8042621,8.2723654 -6.5383288,6.5382984 -8.2723956,4.8042314 -9.2465834,2.4523324 -9.2465816,-8.6e-6 c 6e-7,-2.452339 0.9741895,-4.804237 2.708256,-6.538301 1.7340665,-1.734065 4.0859648,-2.708252 6.538303974041,-2.70825 C 5.1067066,-9.2465576 9.2465271,-5.1067366 9.2465284,-8.6e-6 c 0,0 0,0 0,0" + style="opacity:1;vector-effect:none;fill:#fafafa;fill-opacity:1;fill-rule:evenodd;stroke:#003399;stroke-width:1.06500006;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3.19500017, 3.19500017;stroke-dashoffset:0;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-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;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:#050505;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.41421342;stroke-linecap:butt;stroke-linejoin:miter;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" + d="m -3.0000256,-5.9834096 c -1.30575,0 -2.375,1.06924 -2.375,2.375 0,1.30575 1.06925,2.375 2.375,2.375 0.58687,0 1.11944,-0.22369 1.53516,-0.58007 0,0 0.61717997,1.62109 0.61717997,1.62109 0,0 -2.29881997,6.01758 -2.29881997,6.01758 0.98655,-0.12511 1.23728,-0.26171 1.67382,-0.97461 0,0 1.33007997,-3.18945 1.33007997,-3.18945 0,0 1.23633003,3.25 1.23633003,3.25 0.23227,0.77906 0.84315,0.79218 1.57813,1.07226 0,0 -2.05469003,-6.14258 -2.05469003,-6.14258 0,0 0.73047003,-1.75 0.73047003,-1.75 0.42849,0.41682 1.01136,0.67578 1.65234,0.67578 1.30575,0 2.375,-1.06925 2.375,-2.375 0,-1.30576 -1.06925,-2.375 -2.375,-2.375 -1.06233,0 -1.95701,0.71265 -2.25781003,1.67969 0,0 -0.0117,-0.0156 -0.0117,-0.0156 0,0 -0.80274,2.10156 -0.80274,2.10156 0,0 -0.59179,-1.76562 -0.59179,-1.76562 -0.18242,-1.12808 -1.15864997,-2 -2.33593997,-2 0,0 -2e-5,-3e-5 -2e-5,-3e-5 m 0,1 c 0.76531,0 1.375,0.60968 1.375,1.375 0,0.76531 -0.60969,1.375 -1.375,1.375 -0.76531,0 -1.375,-0.60969 -1.375,-1.375 0,-0.76532 0.60969,-1.375 1.375,-1.375 0,0 0,0 0,0 m 6,0 c 0.76531,0 1.375,0.60968 1.375,1.375 0,0.76531 -0.60969,1.375 -1.375,1.375 -0.76531,0 -1.375,-0.60969 -1.375,-1.375 0,-0.76532 0.60969,-1.375 1.375,-1.375 0,0 0,0 0,0" + id="inkstitch_path13416" + inkscape:connector-curvature="0" /> + </symbol> + + + + + </defs> + <g + id="Layer_x0020_1" + inkscape:label="Layer 1" + inkscape:groupmode="layer"> + <g + id="g6" + transform="matrix(3.72213,0,0,3.72213,-40581.951,-41363.2)" + style="opacity:1;stroke-width:0.268663"><path + class="fil1" + d="M 14667.311,12672.251 C 14670.674,12694.45 14689.847,12711.269 14712.719,12711.269 V 12711.269 C 14737.947,12711.269 14758.801,12690.75 14758.801,12665.186 V 12616.75 C 14758.801,12604.305 14764.856,12593.877 14775.283,12587.15 14786.047,12580.759 14798.492,12580.423 14809.256,12586.478 14837.174,12600.941 14855.674,12628.523 14855.674,12664.514 V 13602.296 C 14855.674,13651.741 14814.974,13692.441 14765.528,13692.441 H 14667.311 V 13841.45 C 14667.311,14399.478 14210.865,14855.923 13652.837,14855.923 H 12236.746 C 11678.719,14855.923 11221.937,14399.478 11221.937,13841.45 V 13706.232 H 11125.737 C 11074.946,13706.232 11033.573,13664.86 11033.573,13614.405 V 12679.986 C 11033.573,12629.532 11074.946,12588.159 11125.737,12588.159 H 11221.937 V 12425.359 C 11221.937,11867.331 11678.719,11410.886 12236.746,11410.886 H 13652.837 C 14210.865,11410.886 14667.311,11867.331 14667.311,12425.359 Z M 11150.292,13239.359 H 11186.282 C 11200.746,13239.359 11213.528,13246.423 11221.937,13256.85 V 13314.032 C 11213.528,13324.796 11200.746,13331.523 11186.282,13331.523 H 11150.292 C 11125.065,13331.523 11104.546,13310.669 11104.546,13285.441 V 13285.441 C 11104.546,13260.214 11125.065,13239.359 11150.292,13239.359 Z M 11168.455,13478.177 C 11193.683,13478.177 11214.201,13498.696 11214.201,13523.923 11214.201,13549.486 11193.683,13570.005 11168.455,13570.005 11142.892,13570.005 11122.374,13549.486 11122.374,13523.923 11122.374,13498.696 11142.892,13478.177 11168.455,13478.177 Z M 14705.319,13239.359 H 14741.311 C 14766.538,13239.359 14787.392,13260.214 14787.392,13285.441 V 13285.441 C 14787.392,13310.669 14766.538,13331.523 14741.311,13331.523 H 14705.319 C 14689.51,13331.523 14675.719,13323.45 14667.311,13311.005 V 13259.877 C 14675.719,13247.769 14689.51,13239.359 14705.319,13239.359 Z M 14723.483,13478.514 C 14748.711,13478.514 14768.892,13498.696 14768.892,13523.923 14768.892,13549.15 14748.711,13569.669 14723.483,13569.669 14698.256,13569.669 14677.738,13549.15 14677.738,13523.923 14677.738,13498.696 14698.256,13478.514 14723.483,13478.514 Z M 12236.746,11583.104 C 11773.91,11583.104 11394.492,11962.523 11394.492,12425.359 V 13841.45 C 11394.492,14304.287 11773.91,14683.706 12236.746,14683.706 H 13652.837 C 14115.674,14683.706 14495.093,14304.287 14495.093,13841.45 V 12425.359 C 14495.093,11962.523 14115.674,11583.104 13652.837,11583.104 Z" + id="path1" + style="fill:#003399;stroke:none;stroke-width:10.7404;stroke-dasharray:none" + sodipodi:nodetypes="cssssccssscsssscsssscsssscssccssssssssssssssssccsssssssssssssss" /></g> + <g + id="g2" + transform="matrix(160.06796,0,0,160.06796,-2915.3108,2854.5645)" + style="clip-rule:evenodd;fill-rule:evenodd;stroke-width:0.249752;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"><rect + style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:0.249752;stroke-miterlimit:5.5;stroke-dasharray:none" + id="rect1-5" + width="0.61187506" + height="21" + x="44.194061" + y="21" /><circle + style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.943942;stroke-miterlimit:5.5;stroke-dasharray:none" + id="path1-9" + cx="44.5" + cy="22.5" + r="2.5" /><rect + style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:0.249752;stroke-miterlimit:5.5;stroke-dasharray:none" + id="rect2-0" + width="0.61187506" + height="21" + x="52.194061" + y="21" /><circle + style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.943942;stroke-miterlimit:5.5;stroke-dasharray:none" + id="circle2" + cx="52.5" + cy="32.5" + r="2.5" /><rect + style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:0.249752;stroke-miterlimit:5.5;stroke-dasharray:none" + id="rect3-9" + width="0.61187506" + height="21" + x="60.194061" + y="21" /><circle + style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.943942;stroke-miterlimit:5.5;stroke-dasharray:none" + id="circle3" + cx="60.5" + cy="28.5" + r="2.5" /></g><g + id="g3" + transform="translate(4877.2179)"><rect + style="fill:none;stroke:#b6b8b7;stroke-width:229.211;stroke-dasharray:none" + id="rect1" + width="2692.2827" + height="2811.0598" + x="3621.5798" + y="8304.1914" /><rect + style="fill:none;stroke:#b6b8b7;stroke-width:229.211;stroke-dasharray:none" + id="rect2" + width="2692.2827" + height="2811.0598" + x="3621.5798" + y="4386.417" /></g></g> +</svg> diff --git a/lib/extensions/__init__.py b/lib/extensions/__init__.py index f6694a90..b4a08840 100644 --- a/lib/extensions/__init__.py +++ b/lib/extensions/__init__.py @@ -4,6 +4,7 @@ # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. from .about import About +from .apply_attribute import ApplyAttribute from .apply_palette import ApplyPalette from .apply_threadlist import ApplyThreadlist from .auto_run import AutoRun @@ -82,6 +83,7 @@ from .zip import Zip extensions = [ About, + ApplyAttribute, ApplyPalette, ApplyThreadlist, AutoRun, diff --git a/lib/extensions/apply_attribute.py b/lib/extensions/apply_attribute.py new file mode 100644 index 00000000..0d3e30e6 --- /dev/null +++ b/lib/extensions/apply_attribute.py @@ -0,0 +1,47 @@ +# Authors: see git history +# +# Copyright (c) 2025 Authors +# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. + +from inkex import Boolean, errormsg + +from ..i18n import _ +from .base import InkstitchExtension + + +class ApplyAttribute(InkstitchExtension): + ''' + Applies a given attribute to all selected elements + ''' + def __init__(self, *args, **kwargs): + InkstitchExtension.__init__(self, *args, **kwargs) + self.arg_parser.add_argument("--notebook") + self.arg_parser.add_argument("-n", "--namespace", dest="namespace", type=str, default='inkstitch') + self.arg_parser.add_argument("-k", "--key", dest="key", type=str, default='') + self.arg_parser.add_argument("-v", "--value", dest="value", type=str, default='') + self.arg_parser.add_argument("-r", "--remove", dest="remove", type=Boolean, default=False) + + def effect(self): + self.get_elements() + if not self.elements: + errormsg(_("Please select at least one element.")) + return + + if not self.options.key: + errormsg(_("Please enter the attribute name.")) + return + + key = '' + if self.options.namespace: + key = f'{self.options.namespace}:' + key += self.options.key + + if self.options.remove: + for element in self.elements: + element.node.pop(key) + else: + if not self.options.value: + errormsg(_("Please enter a value.")) + return + for element in self.elements: + element.node.set(key, self.options.value) diff --git a/templates/apply_attribute.xml b/templates/apply_attribute.xml new file mode 100644 index 00000000..ddc7e0d4 --- /dev/null +++ b/templates/apply_attribute.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<inkscape-extension translationdomain="inkstitch" xmlns="http://www.inkscape.org/namespace/inkscape/extension"> + <name>Apply attribute</name> + <id>org.{{ id_inkstitch }}.apply_attribute</id> + <param name="extension" type="string" gui-hidden="true">apply_attribute</param> + <effect> + <object-type>all</object-type> + <icon>{{ icon_path }}inx/apply_attribute.svg</icon> + <menu-tip>Applies a custom attribute to multiple elements</menu-tip> + <effects-menu> + <submenu name="{{ menu_inkstitch }}" translatable="no"> + <submenu name="Edit" /> + </submenu> + </effects-menu> + </effect> + <param name="notebook" type="notebook"> + <page name="options" gui-text="Options"> + <param name="namespace" type="string" gui-text="Namespace">inkstitch</param> + <param name="key" type="string" gui-text="Attribute"></param> + <param name="value" type="string" gui-text="Value"></param> + <spacer /> + <param name="remove" type="boolean" gui-text="Remove attribute">false</param> + </page> + <page name="info" gui-text="Help"> + <label appearance="header">This extension sets a custom attribute to all selected elements.</label> + <spacer/> + <label>It is an extension for experienced users.</label> + <spacer/> + <label appearance="url">https://inkstitch.org/docs/edit/#apply-attribute</label> + </page> + </param> + <script> + {{ command_tag | safe }} + </script> +</inkscape-extension> |
