diff options
| -rw-r--r-- | .github/workflows/build.yml | 2 | ||||
| -rwxr-xr-x | bin/build-distribution-archives | 5 | ||||
| -rw-r--r-- | dbus/select_elements.py | 56 | ||||
| -rw-r--r-- | lib/extensions/__init__.py | 2 | ||||
| -rw-r--r-- | lib/extensions/select_elements.py | 157 | ||||
| -rw-r--r-- | templates/select_elements.xml | 71 |
6 files changed, 289 insertions, 4 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8a74dae..0d1567a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: - uses: ruby/setup-ruby@v1 with: ruby-version: 3.1 - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: pip-cache with: path: ~/.cache/pip diff --git a/bin/build-distribution-archives b/bin/build-distribution-archives index 05fdc0f7..48660777 100755 --- a/bin/build-distribution-archives +++ b/bin/build-distribution-archives @@ -4,7 +4,7 @@ ARCH="$(uname -m)" mkdir artifacts if [ "$BUILD" = "osx" ]; then - cp -a icons locales print LICENSE VERSION images/examples palettes symbols fonts tiles inx dist/inkstitch.app/Contents/Resources + cp -a icons locales print LICENSE VERSION images/examples palettes symbols fonts tiles dbus inx dist/inkstitch.app/Contents/Resources # adding version to Info.plist sed -i '' 's/0.0.0/'${VERSION}'/' dist/inkstitch.app/Contents/Info.plist rm -rf dist/inkstitch/ @@ -87,10 +87,9 @@ if [ "$BUILD" = "osx" ]; then python -m zipfile -c ../artifacts/inkstitch-${VERSION}-${OS}.zip * cd .. else - cp -a images/examples palettes symbols fonts tiles inx LICENSE VERSION dist/inkstitch + cp -a images/examples palettes symbols fonts tiles dbus inx LICENSE VERSION dist/inkstitch cp -a icons locales print dist/inkstitch/bin cp -a electron/build/*-unpacked dist/inkstitch/electron - fi if [ "$BUILD" = "windows" ]; then diff --git a/dbus/select_elements.py b/dbus/select_elements.py new file mode 100644 index 00000000..2b663aed --- /dev/null +++ b/dbus/select_elements.py @@ -0,0 +1,56 @@ +# Authors: see git history +# +# Copyright (c) 2022 Authors +# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. +# +# The original Source can be found here: +# https://gitlab.com/inkscape/inkscape/uploads/ca84fa1092f8d6e81e49b99e659cd025/dbus_test.py + +import sys +from time import sleep + +import gi +from gi.repository import Gio, GLib + +gi.require_version("Gio", "2.0") + + +class DBusActions: + def __init__(self): + try: + bus = Gio.bus_get_sync(Gio.BusType.SESSION, None) + except BaseException: + exit() + + proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None, + 'org.freedesktop.DBus', + '/org/freedesktop/DBus', + 'org.freedesktop.DBus', None) + names_list = proxy.call_sync('ListNames', None, Gio.DBusCallFlags.NO_AUTO_START, 500, None) + + # names_list is a GVariant, must unpack + names = names_list.unpack()[0] + + # Look for Inkscape; names is a tuple. + for name in names: + if ('org.inkscape.Inkscape' in name): + break + + appGroupName = "/org/inkscape/Inkscape" + self.applicationGroup = Gio.DBusActionGroup.get( + bus, + name, + appGroupName) + + def run_action(self, action, param): + self.applicationGroup.activate_action(action, param) + + +# start dbus +dbus = DBusActions() +# give it some time to start +sleep(0.2) +# clear previous selection +dbus.run_action('select-clear', None) +# select with the list of ids +dbus.run_action('select-by-id', GLib.Variant.new_string(sys.argv[1])) diff --git a/lib/extensions/__init__.py b/lib/extensions/__init__.py index 50623bb6..fc70fcef 100644 --- a/lib/extensions/__init__.py +++ b/lib/extensions/__init__.py @@ -43,6 +43,7 @@ from .preferences import Preferences from .print_pdf import Print from .remove_embroidery_settings import RemoveEmbroiderySettings from .reorder import Reorder +from .select_elements import SelectElements from .selection_to_guide_line import SelectionToGuideLine from .selection_to_pattern import SelectionToPattern from .simulator import Simulator @@ -99,4 +100,5 @@ __all__ = extensions = [StitchPlanPreview, Reorder, DuplicateParams, Preferences, + SelectElements, CutworkSegmentation] diff --git a/lib/extensions/select_elements.py b/lib/extensions/select_elements.py new file mode 100644 index 00000000..29fa529b --- /dev/null +++ b/lib/extensions/select_elements.py @@ -0,0 +1,157 @@ +# Authors: see git history +# +# Copyright (c) 2022 Authors +# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. + +import os +import subprocess +import sys + +from inkex import Boolean + +from ..elements import Clone, FillStitch, Polyline, SatinColumn, Stroke +from ..utils import get_bundled_dir +from .base import InkstitchExtension + + +class SelectElements(InkstitchExtension): + def add_arguments(self, pars): + self.arg_parser.add_argument("--options", type=str, dest="notebook") + pars.add_argument("--stitch-type", type=str, dest="stitch_type") + pars.add_argument("--info", type=str, dest="info") + + pars.add_argument("--select-running-stitch", type=Boolean, dest="running", default=False) + pars.add_argument("--select-ripples", type=Boolean, dest="ripples", default=False) + pars.add_argument("--select-manual", type=Boolean, dest="manual", default=False) + pars.add_argument("--select-polyline", type=Boolean, dest="poly", default=False) + pars.add_argument("--select-zigzag", type=Boolean, dest="zigzag", default=False) + pars.add_argument("--select-satin", type=Boolean, dest="satin", default=False) + pars.add_argument("--satin-underlay", type=str, dest="satin_underlay", default="all") + pars.add_argument("--select-e", type=Boolean, dest="e", default=False) + pars.add_argument("--select-auto-fill", type=Boolean, dest="fill", default=False) + pars.add_argument("--select-contour-fill", type=Boolean, dest="contour", default=False) + pars.add_argument("--select-guided-fill", type=Boolean, dest="guided", default=False) + pars.add_argument("--select-legacy-fill", type=Boolean, dest="legacy", default=False) + pars.add_argument("--fill-underlay", type=str, dest="fill_underlay", default="all") + pars.add_argument("--select-clone", type=Boolean, dest="clone", default=False) + + pars.add_argument("--python-path", type=str, dest="python_path", default='') + + def effect(self): + py_path, file_path = self._get_paths() + id_list = self._get_id_list() + + subprocess.Popen( + [py_path, 'select_elements.py', id_list], + cwd=file_path, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + + def _get_paths(self): + file_path = get_bundled_dir("dbus") + + if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): + if sys.platform == "linux": + py_path = "python3" + elif sys.platform.startswith("win"): + # sadly we cannot access python interpreters, so we have to guess the file path in windows + # and we could be very wrong + py_path = 'c:/program files/inkscape/bin/python.exe' + elif sys.platform == "darwin": + py_path = '/Applications/Inkscape.app/Contents/Resources/bin/python3' + py_path = 'python3' + else: + # we are running a local install + py_path = sys.executable + + # For some reason we cannot use the subprocess method wait() to finish the process properly + # and we'll get a warning. It will break functionality of the selection. + # There is most possibly a better way than to just ignore the warning?!? + with open(os.devnull, 'w') as null: + sys.stderr = null + sys.stdout = null + + # custom python path + if self.options.python_path: + py_path = self.options.python_path + + return py_path, file_path + + def _get_id_list(self): + if not self.get_elements(): + return '' + + ids = set() + for element in self.elements: + if isinstance(element, Stroke) and self._select_stroke(element): + ids.add(element.id) + elif isinstance(element, Polyline) and self.options.poly: + ids.add(element.id) + elif isinstance(element, FillStitch) and self._select_fill(element): + ids.add(element.id) + elif isinstance(element, SatinColumn) and self._select_satin(element): + ids.add(element.id) + elif isinstance(element, Clone) and self.options.clone: + ids.add(element.id) + + return ','.join(ids) + + def _select_stroke(self, element): + select = False + method = element.stroke_method + manual = element.manual_stitch_mode + if self.options.ripples and method == 1: + select = True + elif self.options.manual and manual: + select = True + elif method == 1 or manual: + return False + elif self.options.zigzag and not element.dashed: + select = True + elif self.options.running and element.dashed: + select = True + return select + + def _select_fill(self, element): + select = False + if not self._select_fill_underlay(element): + return False + method = element.fill_method + if self.options.fill and method == 0: + select = True + elif self.options.contour and method == 1: + select = True + elif self.options.guided and method == 2: + select = True + elif self.options.legacy and method == 3: + select = True + return select + + def _select_fill_underlay(self, element): + underlay = {'all': True, 'no': not element.fill_underlay, 'yes': element.fill_underlay} + return underlay[self.options.fill_underlay] + + def _select_satin(self, element): + select = False + if not (self.options.satin or self.options.e): + return False + if not self._select_satin_underlay(element): + return False + if self.options.e and element.e_stitch: + select = True + elif self.options.satin and not element.e_stitch: + select = True + return select + + def _select_satin_underlay(self, element): + underlay = {'all': None, 'no': None, 'center': None, 'contour': None, 'zigzag': None} + underlay['center'] = element.center_walk_underlay + underlay['contour'] = element.contour_underlay + underlay['zigzag'] = element.zigzag_underlay + underlay['no'] = not any(underlay.values()) + underlay['all'] = True + return underlay[self.options.satin_underlay] + + +if __name__ == '__main__': + SelectElements().run() diff --git a/templates/select_elements.xml b/templates/select_elements.xml new file mode 100644 index 00000000..cf9634a2 --- /dev/null +++ b/templates/select_elements.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> + <name>Select embroidery elements</name> + <id>org.inkstitch.select_elements</id> + <param name="extension" type="string" gui-hidden="true">select_elements</param> + + <param name="options" type="notebook"> + <page name="stitch-type" gui-text="Select options"> + <label appearance="header">Select Stitch Type</label> + <label>Stroke type</label> + <param indent="1" name="select-running-stitch" type="boolean" gui-text="Running Stitch">false</param> + <param indent="1" name="select-ripples" type="boolean" gui-text="Ripples">false</param> + <param indent="1" name="select-manual" type="boolean" gui-text="Manual Stitch">false</param> + <param indent="1" name="select-polyline" type="boolean" gui-text="Polyline">false</param> + <param indent="1" name="select-zigzag" type="boolean" gui-text="ZigZag Stitch">false</param> + <label>Satin</label> + <param indent="1" name="select-satin" type="boolean" gui-text="Satin Column">false</param> + <param indent="1" name="select-e" type="boolean" gui-text="E-Stitch">false</param> + <param indent="1" name="satin-underlay" type="optiongroup" appearance="combo" gui-text="Underlay type" + gui-description="Only select satins with this underlay type"> + <option value="all">No restriction</option> + <option value="no">No underlay</option> + <option value="center">Centerwalk</option> + <option value="contour">Contour</option> + <option value="zigzag">Zigzag</option> + </param> + <label>Fills</label> + <param indent="1" name="select-auto-fill" type="boolean" gui-text="Fill">false</param> + <param indent="1" name="select-contour-fill" type="boolean" gui-text="Contour Fill">false</param> + <param indent="1" name="select-guided-fill" type="boolean" gui-text="Guided Fill">false</param> + <param indent="1" name="select-legacy-fill" type="boolean" gui-text="Legacy Fill">false</param> + <param indent="1" name="fill-underlay" type="optiongroup" appearance="combo" gui-text="Underlay" + gui-description="Only select fills with this underlay"> + <option value="all">No restriction</option> + <option value="yes">Underlay</option> + <option value="no">No Underlay</option> + </param> + <label>Clone</label> + <param indent="1" name="select-clone" type="boolean" gui-text="Clone">false</param> + </page> + <page name="info" gui-text="Help"> + <label appearance="header">Select embroidery objects</label> + <spacer /> + <label>Selects specific embroidery elements by stitch type.</label> + <label>If there is already an active selection, non maching elements will be deselected.</label> + <spacer /> + <separator /> + <spacer /> + <label appearance="header">Troubleshoot</label> + <spacer /> + <label>If this isn't working for you, you may need to insert your path to a python executable manualy.</label> + <spacer /> + <label>* Windows: Open the "Command Prompt" and type "where python". Copy the path and paste it here.</label> + <label>* Linux: Open the command line and type "which python". Copy the path and paste it here.</label> + <label>* macOS: doesn't work, sorry</label> + <param name="python-path" type="string" gui-text="Python Path"></param> + </page> + </param> + + <effect> + <object-type>all</object-type> + <effects-menu> + <submenu name="Ink/Stitch" translatable="no"> + <submenu name="Edit" /> + </submenu> + </effects-menu> + </effect> + <script> + {{ command_tag | safe }} + </script> +</inkscape-extension> |
