File: wxpTag.py

package info (click to toggle)
wxpython3.0 3.0.2.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 482,760 kB
  • ctags: 518,293
  • sloc: cpp: 2,127,226; python: 294,045; makefile: 51,942; ansic: 19,033; sh: 3,013; xml: 1,629; perl: 17
file content (275 lines) | stat: -rw-r--r-- 8,956 bytes parent folder | download | duplicates (3)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#----------------------------------------------------------------------
# Name:        wxPython.lib.wxpTag
# Purpose:     A wxHtmlTagHandler that knows how to build and place
#              wxPython widgets onto web pages.
#
# Author:      Robin Dunn
#
# Created:     13-Sept-1999
# RCS-ID:      $Id$
# Copyright:   (c) 1999 by Total Control Software
# Licence:     wxWindows license
#----------------------------------------------------------------------
# 12/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o Updated for V2.5 compatability
#

'''
wx.lib.wxpTag

This module contains a wxHtmlTagHandler that knows how to build
and place wxPython widgets onto wxHtmlWindow web pages.

You don\'t need to use anything in this module directly, just
importing it will create the tag handler and add it to any
wxHtmlWinParsers created from that time forth.

Tags of the following form are recognised::

    <WXP class="classname" [module="modulename"] [width="num"] [height="num"]>
        <PARAM name="parameterName" value="parameterValue>
        ...
    </WXP>

where modulename is the name of a module (possibly in package
notation) to import and classname is the name of a class in that
module to create an instance of.  If the module tag-attribute is not
given or is an empty string, then wx is used.  The width and height
attributes are expected to be integers and will be passed to the
__init__ method of the class as a wxSize object named size.  However,
if the width attribute ends with the percent (%) symbol then the value
will be used as a percentage of the available width and the
wxHtmlWindow will manage the size.

The name-value pairs in all the nested PARAM tags are packaged up as
strings into a python dictionary and passed to the __init__ method of
the class as keyword arguments.  This means that they are all
accessible from the __init__ method as regular parameters, or you use
the special Python \*\*kw syntax in your __init__ method to get the
dictionary directly.

Some parameter values are special and if they are present then they will
be converted from strings to alternate datatypes.  They are:

    id           If the value of id can be converted to an integer, it will
                 be.  Otherwise it is assumed to be the name of an integer
                 variable in the module.

    colours      Any value of the form "#123ABC" will automatically be
                 converted to a wxColour object.

    Py Types     Any value begining with "(", "[" or "{" are expected to
                 be a Python tuple, list, or dictionary and eval()
                 will be used to convert them to that type.  If the
                 eval() fails then the original string value will be
                 preserved.

    wx Types     Any value begining with "wx" is expected to be an attempt
                 to create a wxPython object, such as a wxSize, etc.
                 The eval() will be used to try and construct the
                 object and if it fails then the original string value
                 will be used instead.

An example::

    <wxp module="wx" class="Button">
        <param name="label" value="Click here">
        <param name="id" value="ID_OK">
    </wxp>

Both the begining and ending WXP tags are required.

In the future support will be added for another tag that can be
embedded between the two begining and ending WXP tags and will
facilitate calling methods of the widget to help initialize it.
Additionally, support may be added to fetch the module from a web
server as is done with java applets.

'''
#----------------------------------------------------------------------

import  types

import  wx
import  wx.html


#----------------------------------------------------------------------

WXPTAG   = 'WXP'
PARAMTAG = 'PARAM'

#----------------------------------------------------------------------

class wxpTagHandler(wx.html.HtmlWinTagHandler):
    def __init__(self):
        wx.html.HtmlWinTagHandler.__init__(self)
        self.ctx = None

    def GetSupportedTags(self):
        return WXPTAG+','+PARAMTAG


    def HandleTag(self, tag):
        name = tag.GetName()
        if name == WXPTAG:
            return self.HandleWxpTag(tag)
        elif name == PARAMTAG:
            return self.HandleParamTag(tag)
        else:
            raise ValueError, 'unknown tag: ' + name


    def HandleWxpTag(self, tag):
        # create a new context object
        self.ctx = _Context()

        # find and import the module
        modName = ''
        if tag.HasParam('MODULE'):
            modName = tag.GetParam('MODULE')
        if modName:
            self.ctx.classMod = _my_import(modName)
        else:
            self.ctx.classMod = wx

        # find and verify the class
        if not tag.HasParam('CLASS'):
            raise AttributeError, "WXP tag requires a CLASS attribute"

        className = tag.GetParam('CLASS')
        self.ctx.classObj = getattr(self.ctx.classMod, className)
        if type(self.ctx.classObj) not in [ types.ClassType, types.TypeType]:
            raise TypeError, "WXP tag attribute CLASS must name a class"

        # now look for width and height
        width = -1
        height = -1
        if tag.HasParam('WIDTH'):
            width = tag.GetParam('WIDTH')
            if width[-1] == '%':
                self.ctx.floatWidth = int(width[:-1], 0)
                width = self.ctx.floatWidth
            else:
                width = int(width)
        if tag.HasParam('HEIGHT'):
            height = int(tag.GetParam('HEIGHT'))
        self.ctx.kwargs['size'] = wx.Size(width, height)

        # parse up to the closing tag, and gather any nested Param tags.
        self.ParseInner(tag)

        # create the object
        parent = self.GetParser().GetWindowInterface().GetHTMLWindow()
        if parent:
            obj = self.ctx.classObj(parent, **self.ctx.kwargs)
            obj.Show(True)

            # add it to the HtmlWindow
            self.GetParser().GetContainer().InsertCell(
                wx.html.HtmlWidgetCell(obj, self.ctx.floatWidth))
            self.ctx = None
        return True


    def HandleParamTag(self, tag):
        if not tag.HasParam('NAME'):
            return False

        name = tag.GetParam('NAME')
        value = ""
        if tag.HasParam('VALUE'):
            value = tag.GetParam('VALUE')

        # check for a param named 'id'
        if name == 'id':
            theID = -1
            try:
                theID = int(value)
            except ValueError:
                theID = getattr(self.ctx.classMod, value)
            value = theID


        # check for something that should be evaluated
        elif value and value[0] in '[{(' or value[:2] == 'wx':
            saveVal = value
            try:
                value = eval(value, self.ctx.classMod.__dict__)
            except:
                value = saveVal

        # convert to wx.Colour
        elif value and value[0] == '#':
            try:
                red   = int('0x'+value[1:3], 16)
                green = int('0x'+value[3:5], 16)
                blue  = int('0x'+value[5:], 16)
                value = wx.Colour(red, green, blue)
            except:
                pass

        if self.ctx:
            self.ctx.kwargs[str(name)] = value
        return False


#----------------------------------------------------------------------
# just a place to hold some values
class _Context:
    def __init__(self):
        self.kwargs = {}
        self.width = -1
        self.height = -1
        self.classMod = None
        self.classObj = None
        self.floatWidth = 0


#----------------------------------------------------------------------
# Function to assist with importing packages
def _my_import(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod


#----------------------------------------------------------------------
# Function to parse a param string (of the form 'item=value item2="value etc"'
# and creates a dictionary
def _param2dict(param):
    i = 0; j = 0; s = len(param); d = {}
    while 1:
        while i<s and param[i] == " " : i = i+1
        if i>=s: break
        j = i
        while j<s and param[j] != "=": j=j+1
        if j+1>=s:
            break
        word = param[i:j]
        i=j+1
        if (param[i] == '"'):
            j=i+1
            while j<s and param[j] != '"' : j=j+1
            if j == s: break
            val = param[i+1:j]
        elif (param[i] != " "):
            j=i+1
            while j<s and param[j] != " " : j=j+1
            val = param[i:j]
        else:
            val = ""
        i=j+1
        d[word] = val
    return d

#----------------------------------------------------------------------


# Add our handler class to the collection of tag handlers maintained
# by wxWidgets.
wx.html.HtmlWinParser_AddTagHandler(wxpTagHandler)