source: orange/Orange/OrangeCanvas/preview/scanner.py @ 11683:7b9dcf8abcc4

Revision 11683:7b9dcf8abcc4, 3.4 KB checked in by Ales Erjavec <ales.erjavec@…>, 8 months ago (diff)

Refactored scheme parsing.

Using widget description's "replaces" list to resolve widgets.

Line 
1"""
2Scheme file preview parser.
3
4"""
5import sys
6import logging
7
8from xml.sax import make_parser, handler, saxutils, SAXParseException
9
10from ..scheme.readwrite import scheme_load
11log = logging.getLogger(__name__)
12
13
14class PreviewHandler(handler.ContentHandler):
15    def __init__(self):
16        self._in_name = False
17        self._in_description = False
18        self._in_thumbnail = False
19        self.name_data = []
20        self.title = None
21        self.description = None
22        self.description_data = []
23        self.thumbnail_data = []
24
25    def startElement(self, name, attrs):
26        if name == "scheme":
27            if attrs.get("version", "1.0") >= "2.0":
28                self.title = attrs.get("title", None)
29                self.description = attrs.get("description", None)
30
31        elif name == "thumbnail":
32            self._in_thumbnail = True
33
34    def endElement(self, name):
35        if name == "name":
36            self._in_name = False
37        elif name == "description":
38            self._in_description = False
39        elif name == "thumbnail":
40            self._in_thumbnail = False
41
42    def characters(self, content):
43        if self._in_name:
44            self.name_data.append(content)
45        elif self._in_description:
46            self.description_data.append(content)
47        elif self._in_thumbnail:
48            self._thumbnail_data.append(content)
49
50
51def preview_parse(scheme_file):
52    """Return the title, description, and thumbnail svg image data from a
53    `scheme_file` (can be a file path or a file-like object).
54
55    """
56    parser = make_parser()
57    handler = PreviewHandler()
58    parser.setContentHandler(handler)
59    parser.parse(scheme_file)
60
61    name_data = handler.title or ""
62    description_data = handler.description or ""
63    svg_data = "".join(handler.thumbnail_data)
64
65    return (saxutils.unescape(name_data),
66            saxutils.unescape(description_data),
67            saxutils.unescape(svg_data))
68
69
70def scheme_svg_thumbnail(scheme_file):
71    """Load the scheme scheme from a file and return it's svg image
72    representation.
73
74    """
75    from .. import scheme
76    from ..canvas import scene
77    from ..registry import global_registry
78
79    scheme = scheme.Scheme()
80    errors = []
81    scheme_load(scheme, scheme_file, error_handler=errors.append)
82
83    tmp_scene = scene.CanvasScene()
84    tmp_scene.set_registry(global_registry())
85    tmp_scene.set_scheme(scheme)
86
87    # Force the anchor point layout.
88    tmp_scene.anchor_layout().activate()
89
90    svg = scene.grab_svg(tmp_scene)
91    tmp_scene.clear()
92    tmp_scene.deleteLater()
93    return svg
94
95
96def scan_update(item):
97    """Given a preview item, scan the scheme file ('item.path') and update the
98    items contents.
99
100    """
101
102    path = unicode(item.path())
103
104    # workaround for bugs.python.org/issue11159
105    path = path.encode(sys.getfilesystemencoding())
106
107    try:
108        title, desc, svg = preview_parse(path)
109    except SAXParseException, ex:
110        log.error("%r is malformed (%r)", path, ex)
111        item.setEnabled(False)
112        item.setSelectable(False)
113        return
114
115    if not svg:
116        try:
117            svg = scheme_svg_thumbnail(path)
118        except Exception:
119            log.error("Could not render scheme preview for %r", title,
120                      exc_info=True)
121
122    if item.name() != title:
123        item.setName(title)
124
125    if item.description() != desc:
126        item.setDescription(desc)
127
128    if svg:
129        item.setThumbnail(svg)
Note: See TracBrowser for help on using the repository browser.