summaryrefslogtreecommitdiff
path: root/lib/commands.py
diff options
context:
space:
mode:
authorLex Neva <lexelby@users.noreply.github.com>2018-08-24 21:05:59 -0400
committerGitHub <noreply@github.com>2018-08-24 21:05:59 -0400
commit6f425f7b3e602e2356ebaba2a5d3b240729c5396 (patch)
tree7e29f10f13d63a539b4814a14fecf946ea798f92 /lib/commands.py
parent1de8487849a3f8f55d126e2687d690226e657fde (diff)
parent77177f9b55f57d1373408b3dc619a53fe45d00ce (diff)
Merge pull request #293 from inkstitch/lexelby/origin-and-stop-position
origin and stop position
Diffstat (limited to 'lib/commands.py')
-rw-r--r--lib/commands.py84
1 files changed, 64 insertions, 20 deletions
diff --git a/lib/commands.py b/lib/commands.py
index 7764539c..db3c8a71 100644
--- a/lib/commands.py
+++ b/lib/commands.py
@@ -1,33 +1,42 @@
+import sys
import inkex
import cubicsuperpath
+import simpletransform
-from .svg import apply_transforms
+from .svg import apply_transforms, get_node_transform
from .svg.tags import SVG_USE_TAG, SVG_SYMBOL_TAG, CONNECTION_START, CONNECTION_END, XLINK_HREF
-from .utils import cache
+from .utils import cache, Point
from .i18n import _, N_
COMMANDS = {
# L10N command attached to an object
- "fill_start": N_("Fill stitch starting position"),
+ N_("fill_start"): N_("Fill stitch starting position"),
# L10N command attached to an object
- "fill_end": N_("Fill stitch ending position"),
+ N_("fill_end"): N_("Fill stitch ending position"),
# L10N command attached to an object
- "stop": N_("Stop (pause machine) after sewing this object"),
+ N_("stop"): N_("Stop (pause machine) after sewing this object"),
# L10N command attached to an object
- "trim": N_("Trim thread after sewing this object"),
+ N_("trim"): N_("Trim thread after sewing this object"),
# L10N command attached to an object
- "ignore_object": N_("Ignore this object (do not stitch)"),
+ N_("ignore_object"): N_("Ignore this object (do not stitch)"),
- # L10N command that affects entire layer
- "ignore_layer": N_("Ignore layer (do not stitch any objects in this layer)")
+ # L10N command that affects a layer
+ N_("ignore_layer"): N_("Ignore layer (do not stitch any objects in this layer)"),
+
+ # L10N command that affects entire document
+ N_("origin"): N_("Origin for exported embroidery files"),
+
+ # L10N command that affects entire document
+ N_("stop_position"): N_("Jump destination for Stop commands (a.k.a. \"Frame Out position\")."),
}
OBJECT_COMMANDS = ["fill_start", "fill_end", "stop", "trim", "ignore_object"]
LAYER_COMMANDS = ["ignore_layer"]
+GLOBAL_COMMANDS = ["origin", "stop_position"]
class CommandParseError(Exception):
@@ -117,9 +126,18 @@ class StandaloneCommand(BaseCommand):
self.parse_symbol()
+ @property
+ @cache
+ def point(self):
+ pos = [float(self.node.get("x", 0)), float(self.node.get("y", 0))]
+ transform = get_node_transform(self.node)
+ simpletransform.applyTransformToPoint(transform, pos)
+
+ return Point(*pos)
+
def get_command_description(command):
- return _(COMMANDS[command])
+ return COMMANDS[command]
def find_commands(node):
@@ -144,31 +162,57 @@ def find_commands(node):
def layer_commands(layer, command):
"""Find standalone (unconnected) command symbols in this layer."""
- commands = []
+ for global_command in global_commands(layer.getroottree().getroot(), command):
+ if layer in global_command.node.iterancestors():
+ yield global_command
+
- for standalone_command in standalone_commands(layer.getroottree().getroot()):
+def global_commands(svg, command):
+ """Find standalone (unconnected) command symbols anywhere in the document."""
+
+ for standalone_command in _standalone_commands(svg):
if standalone_command.command == command:
- if layer in standalone_command.node.iterancestors():
- commands.append(command)
+ yield standalone_command
- return commands
+@cache
+def global_command(svg, command):
+ """Find a single command of the specified type.
-def standalone_commands(svg):
+ If more than one is found, print an error and exit.
+ """
+
+ commands = list(global_commands(svg, command))
+
+ if len(commands) == 1:
+ return commands[0]
+ elif len(commands) > 1:
+ print >> sys.stderr, _("Error: there is more than one %(command)s command in the document, but there can only be one. "
+ "Please remove all but one.") % dict(command=command)
+
+ # L10N This is a continuation of the previous error message, letting the user know
+ # what command we're talking about since we don't normally expose the actual
+ # command name to them. Contents of %(description)s are in a separate translation
+ # string.
+ print >> sys.stderr, _("%(command)s: %(description)s") % dict(command=command, description=_(get_command_description(command)))
+
+ sys.exit(1)
+ else:
+ return None
+
+
+def _standalone_commands(svg):
"""Find all unconnected command symbols in the SVG."""
xpath = ".//svg:use[starts-with(@xlink:href, '#inkstitch_')]"
symbols = svg.xpath(xpath, namespaces=inkex.NSS)
- commands = []
for symbol in symbols:
try:
- commands.append(StandaloneCommand(symbol))
+ yield StandaloneCommand(symbol)
except CommandParseError:
pass
- return commands
-
def is_command(node):
return CONNECTION_START in node.attrib or CONNECTION_END in node.attrib