summaryrefslogtreecommitdiff
path: root/lib/extensions/base.py
blob: 7ec987350c5a9a61e89d2858d31af3edbbb76df5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Authors: see git history
#
# Copyright (c) 2010 Authors
# Licensed under the GNU GPL version 3.0 or later.  See the file LICENSE for details.

import os

import inkex

from ..elements import iterate_nodes, nodes_to_elements
from ..i18n import _
from ..metadata import InkStitchMetadata
from ..svg import generate_unique_id
from ..svg.tags import INKSCAPE_GROUPMODE, SVG_GROUP_TAG
from ..update import update_inkstitch_document


class InkstitchExtension(inkex.EffectExtension):
    """Base class for Inkstitch extensions.  Not intended for direct use."""

    # Set to True to hide this extension from release builds of Ink/Stitch.  It will
    # only be available in development installations.
    DEVELOPMENT_ONLY = False

    def load(self, *args, **kwargs):
        document = super().load(*args, **kwargs)
        update_inkstitch_document(document)
        return document

    @classmethod
    def name(cls):
        # Convert CamelCase to snake_case
        return cls.__name__[0].lower() + ''.join([x if x.islower() else f'_{x.lower()}'
                                                  for x in cls.__name__[1:]])

    def hide_all_layers(self):
        for g in self.document.getroot().findall(SVG_GROUP_TAG):
            if g.get(INKSCAPE_GROUPMODE) == "layer":
                g.set("style", "display:none")

    def get_current_layer(self):
        # if no layer is selected, inkex defaults to the root, which isn't
        # particularly useful
        current_layer = self.svg.get_current_layer()
        if current_layer is self.document.getroot():
            try:
                current_layer = self.document.xpath(".//svg:g[@inkscape:groupmode='layer']", namespaces=inkex.NSS)[0]
            except IndexError:
                # No layers at all??  Fine, we'll stick with the default.
                pass
        return current_layer

    def no_elements_error(self):
        if self.svg.selection:
            # l10n This was previously: "No embroiderable paths selected."
            inkex.errormsg(_("Ink/Stitch doesn't know how to work with any of the objects you've selected. "
                             "Please check if selected elements are visible.") + "\n")
        else:
            inkex.errormsg(_("There are no objects in the entire document that Ink/Stitch knows how to work with.") + "\n")

        inkex.errormsg(_("Tip: Run Extensions > Ink/Stitch > Troubleshoot > Troubleshoot Objects") + "\n")

    def get_nodes(self, troubleshoot=False):
        # Postorder traversal of selected nodes and their descendants.
        # Returns all nodes if there is no selection.
        if self.svg.selection:
            selection = list(self.svg.selection)
        else:
            selection = None

        return iterate_nodes(self.document.getroot(), selection=selection, troubleshoot=troubleshoot)

    def get_elements(self, troubleshoot=False):
        self.elements = nodes_to_elements(self.get_nodes(troubleshoot))
        if self.elements:
            return True
        if not troubleshoot:
            self.no_elements_error()
        return False

    def elements_to_stitch_groups(self, elements):
        next_elements = [None]
        if len(elements) > 1:
            next_elements = elements[1:] + next_elements
        stitch_groups = []
        for element, next_element in zip(elements, next_elements):
            if stitch_groups:
                last_stitch_group = stitch_groups[-1]
            else:
                last_stitch_group = None

            stitch_groups.extend(element.embroider(last_stitch_group, next_element))

        return stitch_groups

    def get_inkstitch_metadata(self):
        return InkStitchMetadata(self.svg)

    def get_base_file_name(self):
        svg_filename = self.document.getroot().get(inkex.addNS('docname', 'sodipodi'), "embroidery.svg")

        return os.path.splitext(svg_filename)[0]

    def uniqueId(self, prefix, make_new_id=True):
        """Override inkex.Effect.uniqueId with a nicer naming scheme."""
        return generate_unique_id(self.document, prefix)