diff options
Diffstat (limited to 'lib/extensions')
| -rw-r--r-- | lib/extensions/base.py | 44 | ||||
| -rw-r--r-- | lib/extensions/params.py | 32 | ||||
| -rw-r--r-- | lib/extensions/remove_embroidery_settings.py | 20 | ||||
| -rw-r--r-- | lib/extensions/simulator.py | 2 | ||||
| -rw-r--r-- | lib/extensions/troubleshoot.py | 118 |
5 files changed, 138 insertions, 78 deletions
diff --git a/lib/extensions/base.py b/lib/extensions/base.py index 440a5413..310dd873 100644 --- a/lib/extensions/base.py +++ b/lib/extensions/base.py @@ -1,18 +1,20 @@ -from collections import MutableMapping -from copy import deepcopy import json import os import re +from collections import MutableMapping +from copy import deepcopy -import inkex from stringcase import snakecase -from ..commands import layer_commands +import inkex + +from ..commands import is_command, layer_commands from ..elements import EmbroideryElement, nodes_to_elements +from ..elements.clone import is_clone, is_embroiderable_clone from ..i18n import _ from ..svg import generate_unique_id -from ..svg.tags import SVG_GROUP_TAG, INKSCAPE_GROUPMODE, SVG_DEFS_TAG, EMBROIDERABLE_TAGS - +from ..svg.tags import (CONNECTOR_TYPE, EMBROIDERABLE_TAGS, INKSCAPE_GROUPMODE, + NOT_EMBROIDERABLE_TAGS, SVG_DEFS_TAG, SVG_GROUP_TAG) SVG_METADATA_TAG = inkex.addNS("metadata", "svg") @@ -128,10 +130,9 @@ class InkstitchExtension(inkex.Effect): else: inkex.errormsg(_("There are no objects in the entire document that Ink/Stitch knows how to work with.") + "\n") - inkex.errormsg(_("Ink/Stitch only knows how to work with paths. It can't work with objects like text, rectangles, or circles.") + "\n") - inkex.errormsg(_("Tip: select some objects and use Path -> Object to Path to convert them to paths.") + "\n") + inkex.errormsg(_("Tip: Select some objects and use Path -> Object to Path to convert them to paths.") + "\n") - def descendants(self, node, selected=False): + def descendants(self, node, selected=False, troubleshoot=False): # noqa: C901 nodes = [] element = EmbroideryElement(node) @@ -148,6 +149,10 @@ class InkstitchExtension(inkex.Effect): if node.tag == SVG_DEFS_TAG: return [] + # command connectors with a fill color set, will glitch into the elements list + if is_command(node) or node.get(CONNECTOR_TYPE): + return[] + if self.selected: if node.get("id") in self.selected: selected = True @@ -156,23 +161,26 @@ class InkstitchExtension(inkex.Effect): selected = True for child in node: - nodes.extend(self.descendants(child, selected)) + nodes.extend(self.descendants(child, selected, troubleshoot)) - if selected and node.tag in EMBROIDERABLE_TAGS: - nodes.append(node) + if selected: + if node.tag in EMBROIDERABLE_TAGS or is_embroiderable_clone(node): + nodes.append(node) + elif troubleshoot and (node.tag in NOT_EMBROIDERABLE_TAGS or is_clone(node)): + nodes.append(node) return nodes - def get_nodes(self): - return self.descendants(self.document.getroot()) + def get_nodes(self, troubleshoot=False): + return self.descendants(self.document.getroot(), troubleshoot=troubleshoot) - def get_elements(self): - self.elements = nodes_to_elements(self.get_nodes()) + def get_elements(self, troubleshoot=False): + self.elements = nodes_to_elements(self.get_nodes(troubleshoot)) if self.elements: return True - else: + if not troubleshoot: self.no_elements_error() - return False + return False def elements_to_patches(self, elements): patches = [] diff --git a/lib/extensions/params.py b/lib/extensions/params.py index a3ba7784..600a4669 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -1,19 +1,21 @@ # -*- coding: UTF-8 -*- +import os +import sys from collections import defaultdict from copy import copy from itertools import groupby -import os -import sys - import wx from wx.lib.scrolledpanel import ScrolledPanel from ..commands import is_command -from ..elements import EmbroideryElement, Fill, AutoFill, Stroke, SatinColumn +from ..elements import (AutoFill, Clone, EmbroideryElement, Fill, Polyline, + SatinColumn, Stroke) +from ..elements.clone import is_clone from ..gui import PresetsPanel, SimulatorPreview from ..i18n import _ +from ..svg.tags import SVG_POLYLINE_TAG from ..utils import get_resource_dir from .base import InkstitchExtension @@ -465,16 +467,18 @@ class Params(InkstitchExtension): classes = [] if not is_command(node): - if element.get_style("fill", "black") is not None: - classes.append(AutoFill) - classes.append(Fill) - - if element.get_style("stroke") is not None: - classes.append(Stroke) - - if element.get_style("stroke-dasharray") is None: - classes.append(SatinColumn) - + if node.tag == SVG_POLYLINE_TAG: + classes.append(Polyline) + elif is_clone(node): + classes.append(Clone) + else: + if element.get_style("fill", 'black') and not element.get_style("fill-opacity", 1) == "0": + classes.append(AutoFill) + classes.append(Fill) + if element.get_style("stroke") is not None: + classes.append(Stroke) + if element.get_style("stroke-dasharray") is None: + classes.append(SatinColumn) return classes def get_nodes_by_class(self): diff --git a/lib/extensions/remove_embroidery_settings.py b/lib/extensions/remove_embroidery_settings.py index d39c7e94..2a4d06dd 100644 --- a/lib/extensions/remove_embroidery_settings.py +++ b/lib/extensions/remove_embroidery_settings.py @@ -1,6 +1,7 @@ import inkex from ..commands import find_commands +from ..svg.svg import find_elements from .base import InkstitchExtension @@ -12,6 +13,8 @@ class RemoveEmbroiderySettings(InkstitchExtension): self.OptionParser.add_option("-d", "--del_print", dest="del_print", type="inkbool", default=False) def effect(self): + self.svg = self.document.getroot() + if self.options.del_params: self.remove_params() if self.options.del_commands: @@ -21,7 +24,7 @@ class RemoveEmbroiderySettings(InkstitchExtension): def remove_print_settings(self): print_settings = "svg:metadata//*" - print_settings = self.find_elements(print_settings) + print_settings = find_elements(self.svg, print_settings) for print_setting in print_settings: if print_setting.prefix == "inkstitch": self.remove_element(print_setting) @@ -29,7 +32,7 @@ class RemoveEmbroiderySettings(InkstitchExtension): def remove_params(self): if not self.selected: xpath = ".//svg:path" - elements = self.find_elements(xpath) + elements = find_elements(self.svg, xpath) self.remove_inkstitch_attributes(elements) else: for node in self.selected: @@ -41,7 +44,7 @@ class RemoveEmbroiderySettings(InkstitchExtension): # we are not able to grab commands by a specific id # so let's move through every object instead and see if it has a command xpath = ".//svg:path|.//svg:circle|.//svg:rect|.//svg:ellipse" - elements = self.find_elements(xpath) + elements = find_elements(self.svg, xpath) else: elements = [] for node in self.selected: @@ -64,19 +67,14 @@ class RemoveEmbroiderySettings(InkstitchExtension): def get_selected_elements(self, element_id): xpath = ".//svg:g[@id='%(id)s']//svg:path|.//svg:g[@id='%(id)s']//svg:use" % dict(id=element_id) - elements = self.find_elements(xpath) + elements = find_elements(self.svg, xpath) if not elements: xpath = ".//*[@id='%s']" % element_id - elements = self.find_elements(xpath) - return elements - - def find_elements(self, xpath): - svg = self.document.getroot() - elements = svg.xpath(xpath, namespaces=inkex.NSS) + elements = find_elements(self.svg, xpath) return elements def remove_elements(self, xpath): - elements = self.find_elements(xpath) + elements = find_elements(self.svg, xpath) for element in elements: self.remove_element(element) diff --git a/lib/extensions/simulator.py b/lib/extensions/simulator.py index 1c0627ba..66be752b 100644 --- a/lib/extensions/simulator.py +++ b/lib/extensions/simulator.py @@ -9,6 +9,8 @@ class Simulator(InkstitchExtension): InkstitchExtension.__init__(self) def effect(self): + if not self.get_elements(): + return api_server = APIServer(self) port = api_server.start_server() electron = open_url("/simulator?port=%d" % port) diff --git a/lib/extensions/troubleshoot.py b/lib/extensions/troubleshoot.py index b67a5dc1..6b63390a 100644 --- a/lib/extensions/troubleshoot.py +++ b/lib/extensions/troubleshoot.py @@ -1,43 +1,48 @@ -from itertools import chain import textwrap import inkex from ..commands import add_layer_commands -from ..elements.validation import ValidationWarning, ValidationError +from ..elements.validation import (ObjectTypeWarning, ValidationError, + ValidationWarning) from ..i18n import _ from ..svg import get_correction_transform -from ..svg.tags import (INKSCAPE_GROUPMODE, INKSCAPE_LABEL, - SODIPODI_ROLE, SVG_GROUP_TAG, SVG_PATH_TAG, - SVG_TEXT_TAG, SVG_TSPAN_TAG) +from ..svg.tags import (INKSCAPE_GROUPMODE, INKSCAPE_LABEL, SODIPODI_ROLE, + SVG_GROUP_TAG, SVG_PATH_TAG, SVG_TEXT_TAG, + SVG_TSPAN_TAG) from .base import InkstitchExtension class Troubleshoot(InkstitchExtension): def effect(self): - if not self.get_elements(): - return self.create_troubleshoot_layer() - problem_types = set() - for element in self.elements: - for problem in chain(element.validation_errors(), element.validation_warnings()): - problem_types.add(type(problem)) - self.insert_pointer(problem) - - if problem_types: + problem_types = {'error': set(), 'warning': set(), 'type_warning': set()} + + if self.get_elements(True): + for element in self.elements: + for problem in element.validation_errors(): + problem_types['error'].add(type(problem)) + self.insert_pointer(problem) + for problem in element.validation_warnings(): + if isinstance(problem, ObjectTypeWarning): + problem_types['type_warning'].add(type(problem)) + else: + problem_types['warning'].add(type(problem)) + self.insert_pointer(problem) + + if any(problem_types.values()): self.add_descriptions(problem_types) else: svg = self.document.getroot() svg.remove(self.troubleshoot_layer) - message = _("All selected shapes are valid!") + message = _("All selected shapes are valid! ") message += "\n\n" - message += _("Tip: If you are still having an issue with an object not being rendered, " - "you might need to convert it it to a path (Path -> Object to Path) or check if it is possibly in an ignored layer.") - + message += _("If you are still having trouble with a shape not being embroidered, " + "check if it is in a layer with an ignore command.") inkex.errormsg(message) def insert_pointer(self, problem): @@ -49,9 +54,12 @@ class Troubleshoot(InkstitchExtension): elif isinstance(problem, ValidationError): fill_color = "#ff0000" layer = self.error_group + elif isinstance(problem, ObjectTypeWarning): + fill_color = "#ff9900" + layer = self.type_warning_group - pointer_style = "stroke:#ffffff;stroke-width:0.2;fill:%s;" % (fill_color) - text_style = "fill:%s;stroke:#ffffff;stroke-width:0.2;font-size:8px;text-align:center;text-anchor:middle" % (fill_color) + pointer_style = "stroke:#000000;stroke-width:0.2;fill:%s;" % (fill_color) + text_style = "fill:%s;stroke:#000000;stroke-width:0.2;font-size:8px;text-align:center;text-anchor:middle" % (fill_color) path = inkex.etree.Element( SVG_PATH_TAG, @@ -119,13 +127,23 @@ class Troubleshoot(InkstitchExtension): }) layer.append(warning_group) + type_warning_group = inkex.etree.SubElement( + layer, + SVG_GROUP_TAG, + { + "id": '__validation_ignored__', + INKSCAPE_LABEL: _("Type Warnings"), + }) + layer.append(type_warning_group) + self.troubleshoot_layer = layer self.error_group = error_group self.warning_group = warning_group + self.type_warning_group = type_warning_group def add_descriptions(self, problem_types): svg = self.document.getroot() - text_x = str(self.unittouu(svg.get('width')) + 5) + text_x = str(float(svg.get('viewBox', '0 0 800 0').split(' ')[2]) + 5.0) text_container = inkex.etree.Element( SVG_TEXT_TAG, @@ -138,23 +156,40 @@ class Troubleshoot(InkstitchExtension): self.troubleshoot_layer.append(text_container) text = [ - [_("Troubleshoot"), "font-weight: bold; font-size: 6px;"], + [_("Troubleshoot"), "font-weight: bold; font-size: 8px;"], ["", ""] ] - for problem in problem_types: - text_color = "#ff0000" - if issubclass(problem, ValidationWarning): + for problem_type, problems in problem_types.items(): + if problem_type == "error": + text_color = "#ff0000" + problem_type_header = _("Errors") + problem_type_description = _("Problems that will prevent the shape from being embroidered.") + elif problem_type == "warning": text_color = "#ffdd00" - - text.append([problem.name, "font-weight: bold; fill:%s;" % text_color]) - description_parts = textwrap.wrap(problem.description, 60) - for description in description_parts: - text.append([description, "font-size: 3px;"]) - text.append(["", ""]) - for step in problem.steps_to_solve: - text.append([step, "font-size: 4px;"]) - text.append(["", ""]) + problem_type_header = _("Warnings") + problem_type_description = _("These are problems that won't prevent the shape from being embroidered. " + "You should consider to fix the warning, but if you don't, " + "Ink/Stitch will do its best to process the object.") + elif problem_type == "type_warning": + text_color = "#ff9900" + problem_type_header = _("Object Type Warnings") + problem_type_description = _("Ink/Stitch only knows how to works with paths and ignores everything else. " + "You might want these shapes to be ignored, but if you don't, " + "follow the instructions to change this behaviour.") + if problems: + text.append([problem_type_header, "font-weight: bold; fill: %s; text-decoration: underline; font-size: 7px;" % text_color]) + text.append(["", ""]) + text.append([problem_type_description, "fill:%s;" % text_color]) + text.append(["", ""]) + + for problem in problems: + text.append([problem.name, "font-weight: bold; fill: %s;" % text_color]) + text.append([problem.description, "font-size: 3px;"]) + text.append(["", ""]) + for step in problem.steps_to_solve: + text.append([step, "font-size: 4px;"]) + text.append(["", ""]) explain_layer = _('It is possible, that one object contains more than one error, ' + 'yet there will be only one pointer per object. Run this function again, ' + @@ -162,7 +197,9 @@ class Troubleshoot(InkstitchExtension): '"Troubleshoot" through the objects panel (Object -> Objects...).') explain_layer_parts = textwrap.wrap(explain_layer, 60) for description in explain_layer_parts: - text.append([description, "font-style: italic; font-size: 3px;"]) + text.append([description, "font-style: italic; font-size: 4px;"]) + + text = self.split_text(text) for text_line in text: tspan = inkex.etree.Element( @@ -174,3 +211,14 @@ class Troubleshoot(InkstitchExtension): ) tspan.text = text_line[0] text_container.append(tspan) + + def split_text(self, text): + splitted_text = [] + for text_part, style in text: + if text_part: + description_parts = textwrap.wrap(text_part, 60) + for description in description_parts: + splitted_text.append([description, style]) + else: + splitted_text.append(["", ""]) + return splitted_text |
