wxglade-0.6.8.orig/0000755000175000017500000000000012170277707014327 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widget_properties.py0000644000175000017500000015000512167336636020444 0ustar georgeskgeorgesk""" Classes to handle the various properties of the widgets (name, size, color, etc.) @copyright: 2002-2007 Alberto Griggio @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # this is needed for wx >= 2.3.4 to clip the label showing the name of the # property, otherwise on the properties tabs horizontal scrollbars are shown from xml.sax.saxutils import escape import wx.grid import common import misc from misc import _reverse_dict _label_initial_width = 5 try: import wx.lib.stattext wxGenStaticText = wx.lib.stattext.GenStaticText except ImportError: wxGenStaticText = wx.StaticText _encode = common._encode_to_xml class Property: """\ A class to handle a single property of a widget. @ivar owner: The widget this property belongs to @ivar parent: The widget inside which the property is displayed @ivar tooltip: Tooltip text @type tooltip: String @ivar _tooltip_widgets: All widgets to set tooltips for @type _tooltip_widgets: List """ def __init__(self, owner, name, parent, getter=None, setter=None, label=None): """\ Access to the property is made through the getter and setter functions, which are invoked also in the default event handler. If they are None, they default to owner[name][0] and owner[name][1] """ self.val = None self.parent = parent self.owner = owner self.getter = getter self.setter = setter self.tooltip = None self._tooltip_widgets = [] self.name = name if label: self.dispName = label else: self.dispName = name def on_change_val(self, event): """\ Event handler called to notify owner that the value of the Property has changed """ val = self.get_value() if not misc.streq(self.val, val): common.app_tree.app.saved = False # update the status of the app if self.setter: self.setter(val) else: self.owner[self.name][1](val) self.val = self.get_value() event.Skip() def write(self, outfile, tabs=0): """\ Writes the xml code for this property onto the given file. @param outfile: A file or a file-like object @type outfile: String @param tabs: Indention level, Each level are four spaces @type tabs: Integer """ if self.getter: value = self.getter() else: value = self.owner[self.name][0]() if not misc.streq(value, ''): fwrite = outfile.write fwrite(' ' * tabs + '<%s>' % self.name) fwrite(escape(_encode(value))) fwrite('\n' % self.name) def bind_event(self, function): """\ Sets the default event handler for this property. """ raise NotImplementedError def get_value(self): """\ Return the content of this propery. """ raise NotImplementedError def set_value(self, value): """\ Set the content of this property to the given value. """ raise NotImplementedError def _mangle(self, label): """\ Returns a mangled version of label, suitable for displaying the name of a property. @type label: String @param label: Text to mangle """ return misc.wxstr(misc.capitalize(label).replace('_', ' ')) def set_tooltip(self, text=None): """\ Set same tooltip text to all widgets in L{self._tooltip_widgets}. The text is taken from the C{text} paramater or from L{self.tooltip}. C{text} will be stored in L{self.tooltip} if it is given. @param text: Tooltip text @type text: String """ # check parameter first if text: self.tooltip = text # check for attributes if not self.tooltip or not self._tooltip_widgets: return # set tooltip for widget in self._tooltip_widgets: if widget: widget.SetToolTip(wx.ToolTip(self.tooltip)) # end of class Property class HiddenProperty(Property): """\ Properties not associated to any control, i.e. not editable by the user. """ def __init__(self, owner, name, value=None, label=None): try: getter, setter = owner[name] except KeyError: common.message.exception(_('Internal Error')) if callable(value): getter = value else: def getter(): return value def setter(v): pass self.panel = None # this is needed to provide an uniform treatment, # but is always None Property.__init__(self, owner, name, None, getter, setter, label=label) if value is not None: if callable(value): self.value = value() else: self.value = value def bind_event(self, function): pass def get_value(self): return self.value def set_value(self, val): self.value = val # end of class HiddenProperty class _activator: """\ A utility class which provides: - a method, toggle_active, to (de)activate a Property of a widget - a method, toggle_blocked, to (un)block enabler of a Property of a widget - a method, prepare_activator, to assign enabler and target with settings """ def __init__(self, target=None, enabler=None, omitter=None): """\ @param target: Name of the object to Enable/Disable @param enabler: Check box which provides the ability to Enable/Disable the Property """ self._target = target self._enabler = enabler if self._enabler: self._blocked = self.is_blocked() else: self._blocked = False if self.is_blocked(): self.toggle_active(False, False) elif self._target: self._active = self.is_active() else: self._active = True self.set_omitter(omitter) def toggle_active(self, active=None, refresh=True): # active is not given when refreshing target and enabler if active and self.is_blocked(): self._active = False # blocked is always inactive # (security measure) elif active is not None: self._active = active if not self._target: return try: for target in self._target: target.Enable(self._active) except TypeError: self._target.Enable(self._active) if self._active and self._omitter: try: value = self.owner.access_functions[self.name][0]() self.owner.access_functions[self.name][1](value) except: pass if refresh: try: common.app_tree.app.saved = False except AttributeError: pass # why does this happen on win at startup? try: self._enabler.SetValue(self._active) except AttributeError: pass def is_active(self): if self.is_blocked(): return False if self._target: try: return self._target[0].IsEnabled() except TypeError: return self._target.IsEnabled() return self._active def toggle_blocked(self, blocked=None): if blocked is not None: self._blocked = blocked if self._enabler: self._enabler.Enable(not self._blocked) if self.is_blocked(): # deactivate blocked self.toggle_active(False, False) elif self._enabler: # refresh activity of target and value of enabler self.toggle_active(refresh=False) elif not getattr(self, 'can_disable', None) and self._omitter: # enable blocked widget (that would be always active) without # _enabler if self.owner.get_property_blocking(self._omitter): self.toggle_active(True, False) def is_blocked(self): if self._enabler: return not self._enabler.IsEnabled() return self._blocked def prepare_activator(self, enabler=None, target=None): if target: self._target = target if enabler: self._enabler = enabler self.toggle_blocked() def set_omitter(self, omitter): self._omitter = omitter if omitter: self.owner.set_property_blocking(omitter, self.name) def remove_omitter(self): if self._omitter: self.owner.remove_property_blocking(self._omitter, self.name) # end of class _activator class TextProperty(Property, _activator): """\ Properties associated to a text control. """ def __init__(self, owner, name, parent=None, can_disable=False, enabled=False, readonly=False, multiline=False, label=None, blocked=False, omitter=None): Property.__init__(self, owner, name, parent, label=label) self.val = misc.wxstr(owner[name][0]()) self.can_disable = can_disable self.readonly = readonly self.multiline = multiline _activator.__init__(self, omitter=omitter) if can_disable: self.toggle_active(enabled) self.toggle_blocked(blocked) self.panel = None if parent is not None: self.display(parent) def display(self, parent): """\ Actually builds the text control to set the value of the property interactively """ self.id = wx.NewId() if self.readonly: style = wx.TE_READONLY else: style = 0 if self.multiline: style |= wx.TE_MULTILINE val = self.get_value() if self.multiline: val = val.replace('\\n', '\n') lbl = getattr(self, 'label', None) if lbl is None: lbl = self._mangle(self.dispName) label = wxGenStaticText(parent, -1, lbl, size=(_label_initial_width, -1)) self.text = wx.TextCtrl( parent, self.id, val, style=style, size=(1, -1), ) enabler = None if self.can_disable: enabler = wx.CheckBox(parent, self.id + 1, '', size=(1, -1)) wx.EVT_CHECKBOX(enabler, self.id + 1, lambda event: self.toggle_active(event.IsChecked())) self._tooltip_widgets = [label, self.text, enabler] self.set_tooltip() self.prepare_activator(enabler, self.text) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 2, wx.ALL | wx.ALIGN_CENTER, 3) if getattr(self, '_enabler', None) is not None: sizer.Add(self._enabler, 1, wx.ALL | wx.ALIGN_CENTER, 3) option = 4 else: option = 5 sizer.Add(self.text, option, wx.ALL | wx.ALIGN_CENTER, 3) if self.multiline: h = self.text.GetCharHeight() sizer.SetItemMinSize(self.text, -1, h * 3) self.panel = sizer self.bind_event(self.on_change_val) wx.EVT_CHAR(self.text, self.on_char) def on_char(self, event): if event.GetKeyCode() == wx.WXK_ESCAPE: self.text.SetValue(self.val) self.text.SetInsertionPointEnd() event.Skip() def bind_event(self, function): def func_2(event): if self.text.IsBeingDeleted(): return if self.text.IsEnabled(): #wx.CallAfter(function, event) function(event) event.Skip() wx.EVT_KILL_FOCUS(self.text, func_2) def get_value(self): try: val = self.text.GetValue() if self.multiline: return val.replace('\n', '\\n') return val except AttributeError: return self.val def set_value(self, value): value = misc.wxstr(value) if self.multiline: self.val = value.replace('\n', '\\n') value = value.replace('\\n', '\n') else: self.val = value try: self.text.SetValue(value) except AttributeError: pass def write(self, outfile, tabs=0): if self.is_active(): Property.write(self, outfile, tabs) # end of class TextProperty class CheckBoxProperty(Property, _activator): """\ Properties whose values can be changed by one checkbox. """ def __init__(self, owner, name, parent=None, label=None, write_always=False, omitter=None): Property.__init__(self, owner, name, parent, label=label) self.val = int(owner[name][0]()) if label is None or label == name: label = self._mangle(name) self.label = label self.panel = None self.write_always = write_always _activator.__init__(self, omitter=omitter) if parent is not None: self.display(parent) def display(self, parent): """\ Actually builds the check box to set the value of the property interactively """ self.id = wx.NewId() #self.panel = wxPanel(parent, -1) self.cb = wx.CheckBox(parent, self.id, '') self.cb.SetValue(self.val) label = wxGenStaticText(parent, -1, self.label) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 5, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3) sizer.Add(self.cb, 0, wx.ALIGN_CENTER | wx.ALL, 3) self._tooltip_widgets = [label, self.cb] self.set_tooltip() self.prepare_activator(target=self.cb) self.panel = sizer self.bind_event(self.on_change_val) def bind_event(self, function): wx.EVT_CHECKBOX(self.cb, self.id, function) def get_value(self): try: return int(self.cb.GetValue()) except AttributeError: return int(self.val) def set_value(self, val): self.val = int(val) try: self.cb.SetValue(self.val) except AttributeError: pass def write(self, outfile, tabs=0): if self.write_always or self.get_value(): if self.getter: value = int(self.getter()) else: value = int(self.owner[self.name][0]()) fwrite = outfile.write fwrite(' ' * tabs + '<%s>' % self.name) fwrite(escape(_encode(value))) fwrite('\n' % self.name) # end of class CheckBoxProperty class CheckListProperty(Property, _activator): """\ Properties whose values can be changed by a list of checkboxes. """ def __init__(self, owner, name, parent=None, labels=None, writer=None, tooltips=None, omitter=None): """ @type labels: list of strings @param labels: list of names of the labels of the checkboxes; a label that begins with the string "#section#" is used as the title of a static box that encloses the checkboxes that follow @type tooltips: tuple of strings @param tooltips: a list of strings to be displayed as the tool-tips for the properties """ Property.__init__(self, owner, name, parent, label=None) self.values = owner[name][0]() self.labels = labels self.tooltips = tooltips # the writer param is a function to customize the generation of the xml # for this property self.writer = writer self.panel = None _activator.__init__(self, omitter=omitter) if parent is not None: self.display(parent) def display(self, parent): """\ Actually builds the list of checkboxes to set the value of the property interactively """ self.id = wx.NewId() #self.panel = wxPanel(parent, -1) self.choices = [] tmp_sizer = wx.BoxSizer(wx.VERTICAL) #self.panel.SetAutoLayout(True) i = j = 0 tmp = tmp_sizer while 1: if i >= len(self.labels): break if self.labels[i].startswith('#section#'): if tmp != tmp_sizer: tmp_sizer.Add(tmp, 1, wx.ALL | wx.EXPAND, 5) lbl = self._mangle(self.labels[i].replace(u'#section#', '')) s = wx.FULL_REPAINT_ON_RESIZE tmp = wx.StaticBoxSizer(wx.StaticBox(parent, -1, lbl, style=s), wx.VERTICAL) else: c = wx.CheckBox(parent, self.id + j, self.labels[i]) self.choices.append(c) tmp.Add(c) j += 1 i += 1 if tmp != tmp_sizer: tmp_sizer.Add(tmp, 0, wx.ALL | wx.EXPAND, 5) self.prepare_activator(target=self.choices) for i in range(len(self.values)): self.choices[i].SetValue(self.values[i]) #Set the tool-tips for the properties if self.tooltips is not None: for i in range(len(self.tooltips)): if i >= len(self.choices): break self.choices[i].SetToolTip(wx.ToolTip(self.tooltips[i])) self.panel = tmp_sizer self.bind_event(self.on_change_val) def bind_event(self, function): for i in range(len(self.choices)): wx.EVT_CHECKBOX(self.choices[i], self.id + i, function) def get_value(self): try: return [c.GetValue() for c in self.choices] except AttributeError: return self.values def set_value(self, value): self.values = self.prepare_value(value) try: for i in range(len(self.values)): self.choices[i].SetValue(self.values[i]) except AttributeError: pass def write(self, outfile, tabs=0): if self.writer is not None: return self.writer(outfile, tabs) val = self.owner[self.name][0]() def filter_func(label): return not label.startswith('#section#') labels = filter(filter_func, self.labels) tmp = '|'.join([labels[c] for c in range(len(labels)) if val[c]]) if tmp: fwrite = outfile.write fwrite(' ' * tabs + '<%s>' % self.name) fwrite(escape(_encode(tmp))) fwrite('\n' % self.name) def prepare_value(self, old_val): """\ turns a string of tokens separated by '|' into a list of boolean values """ try: old_val = old_val.split("|") except AttributeError: return list(old_val) ret = [] for l in self.labels: if l in old_val: ret.append(1) elif not l.startswith('#section#'): ret.append(0) return ret # end of class CheckListProperty class SpinProperty(Property, _activator): """\ Properties associated to a spin control. """ def __init__(self, owner, name, parent=None, can_disable=False, r=None, enabled=False, immediate=False, label=None, blocked=False, omitter=None): # r = range of the spin (min, max) Property.__init__(self, owner, name, parent, label=label) self.can_disable = can_disable self.immediate = immediate # if true, changes to this property have an # immediate effect (instead of waiting the # focus change...) _activator.__init__(self, omitter=omitter) if can_disable: self.toggle_active(enabled) self.toggle_blocked(blocked) if r is not None: self.val_range = (r[0], max(r[0], r[1])) else: self.val_range = None self.panel = None self.val = owner[name][0]() if parent is not None: self.display(parent) def display(self, parent): """\ Actually builds the spin control to set the value of the property interactively """ self.id = wx.NewId() if self.val_range is None: self.val_range = (0, 1000) lbl = getattr(self, 'label', None) if lbl is None: lbl = self._mangle(self.dispName) label = wxGenStaticText(parent, -1, lbl, size=(_label_initial_width, -1)) self.spin = wx.SpinCtrl(parent, self.id, min=self.val_range[0], max=self.val_range[1]) val = int(self.owner[self.name][0]()) if not val: self.spin.SetValue(1) # needed for GTK to display a '0' self.spin.SetValue(val) enabler = None if self.can_disable: enabler = wx.CheckBox(parent, self.id + 1, '', size=(1, -1)) wx.EVT_CHECKBOX(enabler, self.id + 1, lambda event: self.toggle_active(event.IsChecked())) self._tooltip_widgets = [label, self.spin, enabler] self.set_tooltip() self.prepare_activator(enabler, self.spin) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 2, wx.ALL | wx.ALIGN_CENTER, 3) if getattr(self, '_enabler', None) is not None: sizer.Add(self._enabler, 1, wx.ALL | wx.ALIGN_CENTER, 3) option = 4 else: option = 5 sizer.Add(self.spin, option, wx.ALL | wx.ALIGN_CENTER, 3) self.panel = sizer self.bind_event(self.on_change_val) def bind_event(self, function): def func_2(event): if self.spin.IsBeingDeleted(): return if self.is_active(): function(event) event.Skip() wx.EVT_KILL_FOCUS(self.spin, func_2) if wx.Platform == '__WXMAC__' or self.immediate: wx.EVT_TEXT(self.spin, self.spin.GetId(), func_2) wx.EVT_SPINCTRL(self.spin, self.spin.GetId(), func_2) def get_value(self): try: return self.spin.GetValue() except AttributeError: return self.val def set_value(self, value): self.val = int(value) try: self.spin.SetValue(int(value)) except AttributeError: pass def set_range(self, min_v, max_v): self.val_range = (min_v, max(min_v, max_v)) try: self.spin.SetRange(min_v, max_v) except AttributeError: pass def write(self, outfile, tabs=0): if self.is_active(): Property.write(self, outfile, tabs) # end of class SpinProperty class DialogProperty(Property, _activator): """\ Property which selection is made through a dialog, which must provide a get_value method. """ def __init__(self, owner, name, parent, dialog, can_disable=False, enabled=False, label=None, blocked=False, omitter=None): Property.__init__(self, owner, name, parent, label=label) self.dialog = dialog self.panel = None self.can_disable = can_disable _activator.__init__(self, omitter=omitter) if can_disable: self.toggle_active(enabled) self.toggle_blocked(blocked) if parent is not None: self.display(parent) self.val = "%s" % owner[name][0]() def display(self, parent): """\ Actually builds the panel (with the text ctrl and the button to display the dialog) to set the value of the property interactively """ self.id = wx.NewId() val = misc.wxstr(self.owner[self.name][0]()) label = wxGenStaticText(parent, -1, self._mangle(self.dispName), size=(_label_initial_width, -1)) self.text = wx.TextCtrl(parent, self.id, val, size=(1, -1)) self.btn = wx.Button(parent, self.id + 1, " ... ", size=(_label_initial_width, -1)) enabler = None if self.can_disable: enabler = wx.CheckBox(parent, self.id + 1, '', size=(1, -1)) wx.EVT_CHECKBOX(enabler, self.id + 1, lambda event: self.toggle_active(event.IsChecked())) self.prepare_activator(enabler, self.text) self._tooltip_widgets = [label, self.text, self.btn, enabler] self.set_tooltip() if self.can_disable: self.btn.Enable(self.is_active()) wx.EVT_BUTTON(self.btn, self.id + 1, self.display_dialog) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 2, wx.ALL | wx.ALIGN_CENTER, 3) if getattr(self, '_enabler', None) is not None: sizer.Add(self._enabler, 1, wx.ALL | wx.ALIGN_CENTER, 3) option = 3 else: option = 4 sizer.Add(self.text, option, wx.ALL | wx.ALIGN_CENTER, 3) sizer.Add(self.btn, 1, wx.ALL | wx.ALIGN_CENTER, 3) self.panel = sizer self.bind_event(self.on_change_val) wx.EVT_CHAR(self.text, self.on_char) def on_char(self, event): if event.GetKeyCode() == wx.WXK_ESCAPE: self.text.SetValue(self.val) self.text.SetInsertionPointEnd() event.Skip() def display_dialog(self, event): if self.dialog.ShowModal() == wx.ID_OK: self.text.SetValue(misc.wxstr(self.dialog.get_value())) self.text.ProcessEvent(wx.FocusEvent(wx.wxEVT_KILL_FOCUS, self.id)) def bind_event(self, function): def func_2(event): if self.text.IsBeingDeleted(): return function(event) wx.EVT_KILL_FOCUS(self.text, func_2) def get_value(self): try: return self.text.GetValue() except AttributeError: return self.val def set_value(self, value): self.val = misc.wxstr(value) try: self.text.SetValue(self.val) except AttributeError: pass def write(self, outfile, tabs=0): if self.is_active(): Property.write(self, outfile, tabs) def toggle_active(self, active=None, refresh=True): _activator.toggle_active(self, active, refresh) try: self.btn.Enable(self.is_active()) except AttributeError: pass # end of class DialogProperty class FileDialogProperty(DialogProperty): dialog = [None] class FileDialog: def __init__(self, parent, message, wildcard, style, label=None): self.parent = parent self.message = message self.wildcard = wildcard self.style = style self.value = None def ShowModal(self): self.value = misc.FileSelector( self.message, wildcard=self.wildcard, flags=self.style) if self.value: return wx.ID_OK def get_value(self): return self.value # end of class FileDialog def __init__(self, owner, name, parent=None, wildcard=_("All Files|*"), message=_("Choose a file"), can_disable=True, style=0, label=None, blocked=False, omitter=None): if not self.dialog[0]: ## self.dialog[0] = wxFileDialog(parent, message, ## wildcard=wildcard, style=style) ## self.dialog[0].get_value = self.dialog[0].GetPath self.dialog[0] = self.FileDialog( parent, message, wildcard, style) DialogProperty.__init__(self, owner, name, parent, self.dialog[0], can_disable, label=label, blocked=blocked, omitter=omitter) # end of class FileDialogProperty class ColorDialogProperty(DialogProperty): str_to_colors = { 'wxSYS_COLOUR_SCROLLBAR': wx.SYS_COLOUR_SCROLLBAR, 'wxSYS_COLOUR_BACKGROUND': wx.SYS_COLOUR_BACKGROUND, 'wxSYS_COLOUR_ACTIVECAPTION': wx.SYS_COLOUR_ACTIVECAPTION, 'wxSYS_COLOUR_INACTIVECAPTION': wx.SYS_COLOUR_INACTIVECAPTION, 'wxSYS_COLOUR_MENU': wx.SYS_COLOUR_MENU, 'wxSYS_COLOUR_WINDOW': wx.SYS_COLOUR_WINDOW, 'wxSYS_COLOUR_WINDOWFRAME': wx.SYS_COLOUR_WINDOWFRAME, 'wxSYS_COLOUR_MENUTEXT': wx.SYS_COLOUR_MENUTEXT, 'wxSYS_COLOUR_WINDOWTEXT': wx.SYS_COLOUR_WINDOWTEXT, 'wxSYS_COLOUR_CAPTIONTEXT': wx.SYS_COLOUR_CAPTIONTEXT, 'wxSYS_COLOUR_ACTIVEBORDER': wx.SYS_COLOUR_ACTIVEBORDER, 'wxSYS_COLOUR_INACTIVEBORDER': wx.SYS_COLOUR_INACTIVEBORDER, 'wxSYS_COLOUR_APPWORKSPACE': wx.SYS_COLOUR_APPWORKSPACE, 'wxSYS_COLOUR_HIGHLIGHT': wx.SYS_COLOUR_HIGHLIGHT, 'wxSYS_COLOUR_HIGHLIGHTTEXT': wx.SYS_COLOUR_HIGHLIGHTTEXT, 'wxSYS_COLOUR_BTNFACE': wx.SYS_COLOUR_BTNFACE, 'wxSYS_COLOUR_BTNSHADOW': wx.SYS_COLOUR_BTNSHADOW, 'wxSYS_COLOUR_GRAYTEXT': wx.SYS_COLOUR_GRAYTEXT, 'wxSYS_COLOUR_BTNTEXT': wx.SYS_COLOUR_BTNTEXT, 'wxSYS_COLOUR_INACTIVECAPTIONTEXT': wx.SYS_COLOUR_INACTIVECAPTIONTEXT, 'wxSYS_COLOUR_BTNHIGHLIGHT': wx.SYS_COLOUR_BTNHIGHLIGHT, 'wxSYS_COLOUR_3DDKSHADOW': wx.SYS_COLOUR_3DDKSHADOW, 'wxSYS_COLOUR_3DLIGHT': wx.SYS_COLOUR_3DLIGHT, 'wxSYS_COLOUR_INFOTEXT': wx.SYS_COLOUR_INFOTEXT, 'wxSYS_COLOUR_INFOBK': wx.SYS_COLOUR_INFOBK, 'wxSYS_COLOUR_DESKTOP': wx.SYS_COLOUR_DESKTOP, 'wxSYS_COLOUR_3DFACE': wx.SYS_COLOUR_3DFACE, 'wxSYS_COLOUR_3DSHADOW': wx.SYS_COLOUR_3DSHADOW, 'wxSYS_COLOUR_3DHIGHLIGHT': wx.SYS_COLOUR_3DHIGHLIGHT, 'wxSYS_COLOUR_3DHILIGHT': wx.SYS_COLOUR_3DHILIGHT, 'wxSYS_COLOUR_BTNHILIGHT': wx.SYS_COLOUR_BTNHILIGHT } colors_to_str = _reverse_dict(str_to_colors) dialog = [None] def __init__(self, owner, name, parent=None, can_disable=True, label=None, blocked=False, omitter=None): if not self.dialog[0]: from color_dialog import wxGladeColorDialog self.dialog[0] = wxGladeColorDialog(self.str_to_colors) DialogProperty.__init__(self, owner, name, parent, self.dialog[0], can_disable, label=label, blocked=blocked, omitter=omitter) def display_dialog(self, event): self.dialog.set_value(self.get_value()) DialogProperty.display_dialog(self, event) def toggle_active(self, active=None, refresh=True): DialogProperty.toggle_active(self, active, refresh) if not self.is_active(): # restore the original value if toggled off color = self.owner._original.get(self.name, None) if color is not None and self.owner.widget is not None: which = 'Set%sColour' % self.name.capitalize() func = getattr(self.owner.widget, which, lambda c: None) func(color) self.owner.widget.Refresh() else: # restore the saved value getval, setval = self.owner[self.name] setval(getval()) # end of class ColorDialogProperty class FontDialogProperty(DialogProperty): font_families_to = {'default': wx.DEFAULT, 'decorative': wx.DECORATIVE, 'roman': wx.ROMAN, 'swiss': wx.SWISS, 'script': wx.SCRIPT, 'modern': wx.MODERN, } font_families_from = _reverse_dict(font_families_to) font_styles_to = {'normal': wx.NORMAL, 'slant': wx.SLANT, 'italic': wx.ITALIC, } font_styles_from = _reverse_dict(font_styles_to) font_weights_to = {'normal': wx.NORMAL, 'light': wx.LIGHT, 'bold': wx.BOLD, } font_weights_from = _reverse_dict(font_weights_to) font_families_to['teletype'] = wx.TELETYPE font_families_from[wx.TELETYPE] = 'teletype' dialog = [None] def __init__(self, owner, name, parent=None, can_disable=True, label=None, blocked=False, omitter=None): if not self.dialog[0]: import font_dialog self.dialog[0] = font_dialog.wxGladeFontDialog(parent, -1, "") DialogProperty.__init__(self, owner, name, parent, self.dialog[0], can_disable, label=label, blocked=blocked, omitter=omitter) def display_dialog(self, event): try: props = eval(self.get_value()) except: common.message.exception(_('Internal Error')) else: if len(props) == 6: self.dialog.set_value(props) DialogProperty.display_dialog(self, event) def write(self, outfile, tabs=0): if self.is_active(): try: props = [_encode(s) for s in eval(self.get_value().strip())] except: common.message.exception(_('Internal Error')) return if len(props) < 6: print _('error in the value of the property "%s"') % self.name return fwrite = outfile.write fwrite(' ' * tabs + '<%s>\n' % self.name) tstr = ' ' * (tabs + 1) fwrite('%s%s\n' % (tstr, escape(props[0]))) fwrite('%s%s\n' % (tstr, escape(props[1]))) fwrite('%s\n' % (tstr, escape(props[2]))) fwrite('%s%s\n' % (tstr, escape(props[3]))) fwrite('%s%s\n' % (tstr, escape(props[4]))) fwrite('%s%s\n' % (tstr, escape(props[5]))) fwrite(' ' * tabs + '\n' % self.name) def toggle_active(self, active=None, refresh=True): DialogProperty.toggle_active(self, active, refresh) if not self.is_active(): # restore the original value if toggled off font = self.owner._original['font'] if font is not None and self.owner.widget is not None: self.owner.widget.SetFont(font) self.owner.widget.Refresh() else: # restore the saved value getval, setval = self.owner[self.name] setval(getval()) # end of class FontDialogProperty class RadioProperty(Property, _activator): """\ Properties controlled by a series of radio buttons. @ivar sort: Sort the the choices. @type sort: Boolean @ivar capitalize: Capitalise the first character of each entry in C{choices} list. Capitalising the first character is an internal process. It does not affect the functions L{get_str_value()}, L{set_str_value()}, L{set_value()} and L{get_value()}. They still handle the original entries. @type capitalize: Boolean @ivar _cap2orig: Dictionary for reverse mapping between the capitalised entry and the original one. @type _cap2orig: Dictionary """ def __init__(self, owner, name, parent, choices, can_disable=False, enabled=False, columns=1, label=None, tooltips=None, blocked=False, omitter=None, sort=False, capitalize=False): Property.__init__(self, owner, name, parent, label=label) self.can_disable = can_disable _activator.__init__(self, omitter=omitter) if can_disable: self.toggle_active(enabled) self.toggle_blocked(blocked) self._cap2orig = {} self.capitalize = capitalize self.choices = choices self.columns = columns self.panel = None self.label = label self.sort = sort self.tooltips = tooltips self.val = owner[name][0]() if label is None: self.label = self._mangle(name) if parent is not None: self.display(parent) def display(self, parent): """\ Actually builds the radio box to set the value of the property interactively """ self.id = wx.NewId() style = wx.RA_SPECIFY_COLS | wx.NO_BORDER | wx.CLIP_CHILDREN if not self.can_disable: szr = wx.BoxSizer(wx.HORIZONTAL) style = wx.RA_SPECIFY_COLS else: szr = wx.StaticBoxSizer(wx.StaticBox(parent, -1, self.label), wx.HORIZONTAL) if self.capitalize: new_choices = [] for orig in self.choices: cap = misc.capitalize(orig) new_choices.append(cap) self._cap2orig[cap] = orig self.choices = new_choices if self.sort: self.choices.sort() self.options = wx.RadioBox(parent, self.id, self.label, choices=self.choices, majorDimension=self.columns, style=style) #Set the tool-tips for the properties if self.tooltips is not None: for i in range(len(self.tooltips)): if i >= len(self.choices): break self.options.SetItemToolTip(i, self.tooltips[i]) try: self.options.SetSelection(int(self.val)) except: pass enabler = None if self.can_disable: enabler = wx.CheckBox(parent, self.id + 1, "") szr.Add(enabler) wx.EVT_CHECKBOX(enabler, self.id + 1, lambda e: self.toggle_active(e.IsChecked())) self.options.SetLabel("") self.prepare_activator(enabler, self.options) szr.Add(self.options, 1, wx.EXPAND) self.panel = szr self.bind_event(self.on_change_val) def bind_event(self, function): def func_2(event, function=function, self=self): if self.options.IsEnabled(): function(event) wx.EVT_RADIOBOX(self.options, self.id, func_2) def get_value(self): """\ Return the zero-based position if the selected entry """ try: return self.options.GetSelection() except AttributeError: return self.val def get_str_value(self): """\ Return the content of the selected entry """ try: selected_string = self.options.GetStringSelection() # reverse lookup for capitalized selections if self.capitalize: selected_string = self._cap2orig[selected_string] return selected_string except AttributeError: if 0 <= self.val < len(self.choices): selected_string = self.choices[self.val] # reverse lookup for capitalized selections if self.capitalize: selected_string = self._cap2orig[selected_string] return selected_string else: return '' def set_value(self, value): try: self.val = int(value) except ValueError: if self.capitalize: value = misc.capitalize(value) self.val = self.choices.index(value) try: self.options.SetSelection(self.val) except AttributeError: pass def set_str_value(self, value): """\ Select the entry specified by given value. """ if self.capitalize: value = misc.capitalize(value) try: self.val = self.choices.index(value) self.options.SetSelection(self.val) except (AttributeError, ValueError): pass def write(self, outfile, tabs=0): if self.is_active(): outfile.write(' ' * tabs + '<%s>%s\n' % (self.name, escape(_encode(self.get_str_value())), self.name)) # end of class RadioProperty class GridProperty(Property, _activator): """\ Property whose values are modified through a wxGrid table. @ivar can_add: Add Button to add a new entry @type can_add: Boolean @ivar can_insert: Add Button to insert a new entry @type can_insert: Boolean @ivar can_remove: Add Button to remove a new entry @type can_remove: Boolean @ivar can_remove_last: Allow to remove last entry @type can_remove_last: Boolean @ivar cols: List of 2-tuples with these fields: - label for the column - type: GridProperty.STRING, GridProperty.INT, GridProperty.FLOAT @ivar col_sizes: List of column widths @type col_sizes: List of Integer @ivar rows: Number of rows @type rows: Integer """ STRING, INT, FLOAT, BOOL = 0, 1, 2, 3 col_format = [lambda g, c: None, lambda g, c: g.SetColFormatNumber(c), lambda g, c: g.SetColFormatFloat(c), lambda g, c: g.SetColFormatBool(c)] def __init__(self, owner, name, parent, cols, rows=1, can_add=True, can_remove=True, can_insert=True, label=None, omitter=None, col_sizes=None, can_remove_last=True): Property.__init__(self, owner, name, parent, label=label) self.val = owner[name][0]() self.set_value(self.val) self.rows, self.cols = rows, cols self.can_add = can_add self.can_remove = can_remove self.can_insert = can_insert self.can_remove_last = can_remove_last if col_sizes is None: self.col_sizes = [] else: self.col_sizes = col_sizes self.panel = None self.cur_row = 0 _activator.__init__(self, omitter=omitter) if parent is not None: self.display(parent) def display(self, parent): """\ Actually builds the grid to set the value of the property interactively """ children = [] self.panel = wx.Panel(parent, -1) # why if the grid is not on this # panel it is not displayed??? label = getattr(self, 'label', self._mangle(self.dispName)) sizer = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1, label), wx.VERTICAL) self.btn_id = wx.NewId() self.btn = wx.Button(self.panel, self.btn_id, _(" Apply "), style=wx.BU_EXACTFIT) children.append(self.btn) if self.can_add: self.add_btn = wx.Button(self.panel, self.btn_id + 1, _(" Add "), style=wx.BU_EXACTFIT) children.append(self.add_btn) if self.can_insert: self.insert_btn = wx.Button(self.panel, self.btn_id + 3, _(" Insert "), style=wx.BU_EXACTFIT) children.append(self.insert_btn) if self.can_remove: self.remove_btn = wx.Button(self.panel, self.btn_id + 2, _(" Remove "), style=wx.BU_EXACTFIT) children.append(self.remove_btn) self.grid = wx.grid.Grid(self.panel, -1) self.grid.CreateGrid(self.rows, len(self.cols)) children.append(self.grid) self.grid.SetMargins(0, 0) for i in range(len(self.cols)): self.grid.SetColLabelValue(i, misc.wxstr(self.cols[i][0])) GridProperty.col_format[self.cols[i][1]](self.grid, i) self.cols = len(self.cols) self.grid.SetRowLabelSize(0) self.grid.SetColLabelSize(20) if self.col_sizes: self.set_col_sizes(self.col_sizes) self.btn_sizer = wx.BoxSizer(wx.HORIZONTAL) extra_flag = wx.FIXED_MINSIZE self.btn_sizer.Add(self.btn, 0, extra_flag) if self.can_add: self.btn_sizer.Add( self.add_btn, 0, wx.LEFT | wx.RIGHT | extra_flag, 4, ) wx.EVT_BUTTON(self.add_btn, self.btn_id + 1, self.add_row) if self.can_insert: self.btn_sizer.Add( self.insert_btn, 0, wx.LEFT | wx.RIGHT | extra_flag, 4) wx.EVT_BUTTON(self.insert_btn, self.btn_id + 3, self.insert_row) if self.can_remove: self.btn_sizer.Add(self.remove_btn, 0, extra_flag) wx.EVT_BUTTON(self.remove_btn, self.btn_id + 2, self.remove_row) sizer.Add(self.btn_sizer, 0, wx.BOTTOM | wx.EXPAND, 2) sizer.Add(self.grid, 1, wx.EXPAND) self.panel.SetAutoLayout(1) self.panel.SetSizer(sizer) self.panel.SetSize(sizer.GetMinSize()) self.prepare_activator(target=children) wx.grid.EVT_GRID_SELECT_CELL(self.grid, self.on_select_cell) self.bind_event(self.on_change_val) self.set_value(self.val) def on_select_cell(self, event): self.cur_row = event.GetRow() event.Skip() def bind_event(self, function): def func(event): self.grid.SaveEditControlValue() function(event) wx.EVT_BUTTON(self.btn, self.btn_id, func) def get_value(self): if not hasattr(self, 'grid'): return self.val l = [] for i in range(self.rows): l2 = [] for j in range(self.cols): l2.append(self.grid.GetCellValue(i, j)) l.append(l2) return l def on_change_val(self, event): """\ Event handler called to notify owner that the value of the Property has changed """ val = self.get_value() def ok(): if len(self.val) != len(val): return True for i in range(len(val)): for j in range(len(val[i])): if not misc.streq(val[i][j], self.val[i][j]): return True return False if ok(): common.app_tree.app.saved = False # update the status of the app if self.setter: self.setter(val) else: self.owner[self.name][1](val) self.val = val event.Skip() def set_value(self, values): self.val = [[misc.wxstr(v) for v in val] for val in values] if not hasattr(self, 'grid'): return # values is a list of lists with the values of the cells size = len(values) # add or remove rows if self.rows < size: self.grid.AppendRows(size - self.rows) self.rows = size elif self.rows != size: self.grid.DeleteRows(size, self.rows - size) # update content for i in range(len(self.val)): for j in range(len(self.val[i])): self.grid.SetCellValue(i, j, self.val[i][j]) # update state of the remove button self._update_remove_button() def add_row(self, event): self.grid.AppendRows() self.grid.MakeCellVisible(self.rows, 0) self.grid.ForceRefresh() self.rows += 1 self._update_remove_button() def remove_row(self, event): if not self.can_remove_last and self.rows == 1: common.message.warn( _('You can not remove the last entry!') ) return if self.rows > 0: # 1: self.grid.DeleteRows(self.cur_row) self.rows -= 1 self._update_remove_button() def insert_row(self, event): self.grid.InsertRows(self.cur_row) self.grid.MakeCellVisible(self.cur_row, 0) self.grid.ForceRefresh() self.rows += 1 self._update_remove_button() def set_col_sizes(self, sizes): """\ sets the width of the columns. sizes is a list of integers with the size of each column: a value of 0 stands for a default size, while -1 means to expand the column to fit the available space (at most one column can have size -1) """ col_to_expand = -1 total_w = 0 for i in range(self.grid.GetNumberCols()): try: w = sizes[i] except IndexError: return if not w: self.grid.AutoSizeColumn(i) total_w += self.grid.GetColSize(i) elif w < 0: col_to_expand = i else: self.grid.SetColSize(i, w) total_w += w if col_to_expand >= 0: self.grid.AutoSizeColumn(col_to_expand) w = self.grid.GetSize()[0] - total_w if w >= self.grid.GetColSize(col_to_expand): self.grid.SetColSize(col_to_expand, w) def _update_remove_button(self): """\ Enable or disable remove button The state of the remove button depends on the number of rows and L{self.can_remove_last}. @see: L{self.can_remove_last} @see: L{self.can_remove} @see: L{self.rows} """ if self.can_remove and not self.can_remove_last: self.remove_btn.Enable(self.rows > 1) # end of class GridProperty class ComboBoxProperty(Property, _activator): """\ Properties whose values can be changed with a combobox. """ def __init__(self, owner, name, choices, parent=None, label=None, can_disable=False, enabled=False, write_always=False, blocked=False, omitter=None): Property.__init__(self, owner, name, parent, label=label) self.val = misc.wxstr(owner[name][0]()) if label is None: label = self._mangle(name) self.label = label self.panel = None self.write_always = write_always self.choices = choices self.can_disable = can_disable _activator.__init__(self, omitter=omitter) if can_disable: self.toggle_active(enabled) self.toggle_blocked(blocked) if parent is not None: self.display(parent) def display(self, parent): """\ Actually builds the check box to set the value of the property interactively """ self.id = wx.NewId() self.cb = wx.ComboBox(parent, self.id, choices=self.choices, style=wx.CB_DROPDOWN | wx.CB_READONLY) self.cb.SetValue(self.val) label = wx.StaticText(parent, -1, self.label) enabler = None if self.can_disable: enabler = wx.CheckBox(parent, self.id + 1, '', size=(1, -1)) wx.EVT_CHECKBOX(enabler, self.id + 1, lambda event: self.toggle_active(event.IsChecked())) self._tooltip_widgets = [label, self.cb, enabler] self.set_tooltip() self.prepare_activator(enabler, self.cb) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 2, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3) if getattr(self, '_enabler', None) is not None: sizer.Add(self._enabler, 1, wx.ALL | wx.ALIGN_CENTER, 3) option = 4 else: option = 5 sizer.Add(self.cb, option, wx.ALIGN_CENTER | wx.ALL, 3) self.panel = sizer self.bind_event(self.on_change_val) def bind_event(self, function): wx.EVT_COMBOBOX(self.cb, self.id, function) def get_value(self): try: return misc.wxstr(self.cb.GetValue()) except AttributeError: return misc.wxstr(self.val) def set_value(self, val): self.val = misc.wxstr(val) try: self.cb.SetValue(self.val) except AttributeError: pass def write(self, outfile, tabs=0): if self.write_always or (self.is_active() and self.get_value()): if self.getter: value = misc.wxstr(self.getter()) else: value = misc.wxstr(self.owner[self.name][0]()) if value != 'None': fwrite = outfile.write fwrite(' ' * tabs + '<%s>' % self.name) fwrite(escape(_encode(value))) fwrite('\n' % self.name) # end of class ComboBoxProperty wxglade-0.6.8.orig/misc.py0000644000175000017500000003434612167336636015651 0ustar georgeskgeorgesk# misc.py: Miscellaneus stuff, used in many parts of wxGlade # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common import os import wx if wx.Platform == '__WXMSW__': class wxGladeRadioButton(wx.RadioButton): """ custom wxRadioButton class which tries to implement a better GetBestSize than the default one for WXMSW (mostly copied from wxCheckBox::DoGetBestSize in checkbox.cpp) """ __radio_size = None def GetBestSize(self): if not self.__radio_size: dc = wx.ScreenDC() dc.SetFont(wx.SystemSettings_GetFont( wx.SYS_DEFAULT_GUI_FONT)) self.__radio_size = (3*dc.GetCharHeight())/2 label = self.GetLabel() if label: w, h = self.GetTextExtent(label) w += self.__radio_size + self.GetCharWidth() if h < self.__radio_size: h = self.__radio_size else: w = h = self.__radio_size return w, h # end of class wxGladeRadioButton else: wxGladeRadioButton = wx.RadioButton # ALB 2004-10-27 FileSelector = wx.FileSelector DirSelector = wx.DirSelector #--------------------- Selection Markers ---------------------------------- class SelectionTag(wx.Window): """\ This is one of the small black squares that appear at the corners of the active widgets """ def __init__(self, parent, pos=None): kwds = { 'size': (7, 7) } if pos: kwds['position'] = pos wx.Window.__init__(self, parent, -1, **kwds) self.SetBackgroundColour(wx.BLUE) #wx.BLACK) self.Hide() # end of class SelectionTag class SelectionMarker: """\ Collection of the 4 SelectionTagS for each widget """ def __init__(self, owner, parent, visible=False): self.visible = visible self.owner = owner self.parent = parent if wx.Platform == '__WXMSW__': self.parent = owner self.tag_pos = None self.tags = None #self.tags = [ SelectionTag(self.parent) for i in range(4) ] self.update() if visible: for t in self.tags: t.Show() def update(self, event=None): if self.owner is self.parent: x, y = 0, 0 else: x, y = self.owner.GetPosition() w, h = self.owner.GetClientSize() def position(j): if not j: return x, y # top-left elif j == 1: return x+w-7, y # top-right elif j == 2: return x+w-7, y+h-7 # bottom-right else: return x, y+h-7 # bottom-left ## for i in range(len(self.tags)): ## self.tags[i].SetPosition(position(i)) self.tag_pos = [ position(i) for i in range(4) ] if self.visible: if not self.tags: self.tags = [ SelectionTag(self.parent) for i in range(4) ] for i in range(4): self.tags[i].SetPosition(self.tag_pos[i]) if event: event.Skip() def Show(self, visible): ## self.visible = visible ## for tag in self.tags: tag.Show(visible) if self.visible != visible: self.visible = visible if self.visible: if not self.tags: self.tags = [ SelectionTag(self.parent) for i in range(4) ] for i in range(4): self.tags[i].SetPosition(self.tag_pos[i]) self.tags[i].Show() else: for tag in self.tags: tag.Destroy() self.tags = None def Destroy(self): if self.tags: for tag in self.tags: tag.Destroy() self.tags = None def Reparent(self, parent): self.parent = parent if self.tags: for tag in self.tags: tag.Reparent(parent) # end of class SelectionMarker #---------------------------------------------------------------------------- _encode = common._encode_from_xml def bound(number, lower, upper): return min(max(lower, number), upper) def capitalize(string): """\ Return string with first character capitalised. Some acronym like XML, XRC. @param string: String to convert @type string: String (plain or unicode) @note: Be carefully it possibly breaks i18n. """ # Don't capitalise those terms if string.upper() in ['XML', 'XRC', 'URL']: return string.upper() return string.capitalize() def color_to_string(color): """\ returns the hexadecimal string representation of the given color: for example: wxWHITE ==> #ffffff """ import operator return '#' + reduce(operator.add, ['%02x' % bound(c, 0, 255) for c in color.Get()]) def string_to_color(color): """\ returns the wxColour which corresponds to the given hexadecimal string representation: for example: #ffffff ==> wxColour(255, 255, 255) """ if len(color) != 7: raise ValueError return apply(wx.Colour, [int(color[i:i+2], 16) for i in range(1, 7, 2)]) def format_for_version(version): """\ Return the version information in C{for_version} in a string. Example:: >>> print format_for_version((2, 8)) 2.8 @see: L{wxglade.codegen.BaseCodeWriter.for_version} """ return '%s.%s' % version def get_toplevel_parent(obj): if not isinstance(obj, wx.Window): window = obj.widget else: window = obj while window and not window.IsTopLevel(): window = window.GetParent() return window def get_toplevel_widget(widget): from edit_windows import EditBase, TopLevelBase from edit_sizers import Sizer if isinstance(widget, Sizer): widget = widget.window assert isinstance(widget, EditBase), _("EditBase or SizerBase object needed") while widget and not isinstance(widget, TopLevelBase): widget = widget.parent return widget if wx.Platform == '__WXGTK__': # default wxMenu seems to have probles with SetTitle on GTK class wxGladePopupMenu(wx.Menu): def __init__(self, title): wx.Menu.__init__(self) self.TITLE_ID = wx.NewId() item = self.Append(self.TITLE_ID, title) self.AppendSeparator() font = item.GetFont() font.SetWeight(wx.BOLD) item.SetFont(wx.Font(font.GetPointSize(), font.GetFamily(), font.GetStyle(), wx.BOLD)) def SetTitle(self, title): self.SetLabel(self.TITLE_ID, title) else: wxGladePopupMenu = wx.Menu def check_wx_version(major, minor=0, release=0, revision=0): """\ returns True if the current wxPython version is at least major.minor.release """ #return wx.__version__ >= "%d.%d.%d.%d" % (major, minor, release, revision) return wx.VERSION[:-1] >= (major, minor, release, revision) #---------------------------------------------------------------------- use_menu_icons = None _item_bitmaps = {} def append_item(menu, id, text, xpm_file_or_artid=None): global use_menu_icons if use_menu_icons is None: import config use_menu_icons = config.preferences.use_menu_icons item = wx.MenuItem(menu, id, text) if wx.Platform == '__WXMSW__': path = 'msw/' else: path = 'gtk/' path = os.path.join(common.icons_path, path) if use_menu_icons and xpm_file_or_artid is not None: bmp = None if not xpm_file_or_artid.startswith('wxART_'): try: bmp = _item_bitmaps[xpm_file_or_artid] except KeyError: f = os.path.join(path, xpm_file_or_artid) if os.path.isfile(f): bmp = _item_bitmaps[xpm_file_or_artid] = \ wx.Bitmap(f, wx.BITMAP_TYPE_XPM) else: bmp = None else: # xpm_file_or_artid is an id for wx.ArtProvider bmp = wx.ArtProvider.GetBitmap( xpm_file_or_artid, wx.ART_MENU, (16, 16)) if bmp is not None: try: item.SetBitmap(bmp) except AttributeError: pass menu.AppendItem(item) #----------- 2002-11-01 ------------------------------------------------------ # if not None, this is the currently selected widget - This is different from # tree.WidgetTree.cur_widget because it takes into account also SizerSlot # objects # this is an implementation hack, used to handle keyboard shortcuts for # popup menus properly (for example, to ensure that the object to remove is # the currently highlighted one, ecc...) focused_widget = None def _remove(): global focused_widget if focused_widget is not None: focused_widget.remove() focused_widget = None def _cut(): global focused_widget if focused_widget is not None: try: focused_widget.clipboard_cut() except AttributeError: pass else: focused_widget = None def _copy(): if focused_widget is not None: try: focused_widget.clipboard_copy() except AttributeError: pass def _paste(): if focused_widget is not None: try: focused_widget.clipboard_paste() except AttributeError: pass # accelerator table to enable keyboard shortcuts for the popup menus of the # various widgets (remove, cut, copy, paste) accel_table = [ (0, wx.WXK_DELETE, _remove), (wx.ACCEL_CTRL, ord('C'), _copy), (wx.ACCEL_CTRL, ord('X'), _cut), (wx.ACCEL_CTRL, ord('V'), _paste), ] #----------------------------------------------------------------------------- def _reverse_dict(src): """\ Returns a dictionary whose keys are 'src' values and values 'src' keys. """ ret = {} for key, val in src.iteritems(): ret[val] = key return ret #----- # if not None, this is the SizerSlot wich has the "mouse focus": this is used # to restore the mouse cursor if the user cancelled the addition of a widget _currently_under_mouse = None #----------------------------------------------------------------------------- def get_geometry(win): x, y = win.GetPosition() w, h = win.GetSize() if 0 <= x <= wx.SystemSettings_GetMetric(wx.SYS_SCREEN_X) and \ 0 <= y <= wx.SystemSettings_GetMetric(wx.SYS_SCREEN_Y): return (x, y, w, h) return None def set_geometry(win, geometry): if geometry is None: return try: if len(geometry) == 4: win.SetDimensions(*[int(x) for x in geometry]) else: win.SetPosition([int(x) for x in geometry]) except Exception, e: print e #----------------------------------------------------------------------------- # snagged out of the Python cookbook def import_name(module_path, name): import imp path, mname = os.path.split(module_path) #print 'path, mname =', path, mname mname = os.path.splitext(mname)[0] #print 'mname:', mname try: mfile, pathname, description = imp.find_module(mname, [path]) try: module = imp.load_module(mname, mfile, pathname, description) finally: mfile.close() except ImportError: common.message.exception(_('Internal Error')) return None return vars(module)[name] #------------------------------------------------------------------------------ # helper functions to work with a Unicode-enabled wxPython #------------------------------------------------------------------------------ def streq(s1, s2): """\ Returns True if the strings or unicode objects s1 and s2 are equal, i.e. contain the same text. Appropriate encoding/decoding are performed to make the comparison """ try: return s1 == s2 except UnicodeError: if type(s1) == type(u''): s1 = s1.encode(common.app_tree.app.encoding) else: s2 = s2.encode(common.app_tree.app.encoding) return s1 == s2 def wxstr(s, encoding=None): """\ Converts the object s to str or unicode, according to what wxPython expects """ if encoding is None: if common.app_tree is None: return str(s) else: encoding = common.app_tree.app.encoding if wx.USE_UNICODE: if type(s) != type(u''): return unicode(str(s), encoding) else: return s else: if type(s) == type(u''): return s.encode(encoding) else: return str(s) #------------------------------------------------------------------------------ # wxPanel used to reparent the property-notebooks when they are hidden. This # has been added on 2003-06-22 to fix what seems to me a (wx)GTK2 bug #------------------------------------------------------------------------------ hidden_property_panel = None def design_title(title): return _(' - ') + title import re _get_xpm_bitmap_re = re.compile(r'"(?:[^"]|\\")*"') del re def get_xpm_bitmap(path): bmp = wx.NullBitmap if not os.path.exists(path): if '.zip' in path: import zipfile archive, name = path.split('.zip', 1) archive += '.zip' if name.startswith(os.sep): name = name.split(os.sep, 1)[1] if zipfile.is_zipfile(archive): # extract the XPM lines... try: data = zipfile.ZipFile(archive).read(name) data = [d[1:-1] for d in _get_xpm_bitmap_re.findall(data)] ## print "DATA:" ## for d in data: print d bmp = wx.BitmapFromXPMData(data) except: common.message.exception(_('Internal Error')) bmp = wx.NullBitmap else: bmp = wx.Bitmap(path, wx.BITMAP_TYPE_XPM) return bmp def get_relative_path(path, for_preview=False): """\ Get an absolute path relative to the current output directory (where the code is generated). """ if os.path.isabs(path): return path p = common.app_tree.app.output_path if for_preview: p = getattr(common.app_tree.app, 'real_output_path', '') p = common._encode_from_xml(common._encode_to_xml(p)) d = os.path.dirname(p) if d: path = os.path.join(d, path) else: path = os.path.abspath(path) return path wxglade-0.6.8.orig/CHANGES.txt0000644000175000017500000112603312150154266016136 0ustar georgeskgeorgesk2013-04-07 Carsten Grohmann Improve usability of the dialog to list and open templates Files (added, modified or removed): * NEWS.txt * res/templates_ui.wxg * template.py * templates_ui.py Regression in generated Python code for bindung events The regression was introduced in 1173:95047b445b12 "Rework generating constructor code in all code generators". The generated code raised an AssertionError if the source of the event is specified by an ID number instead of a widget. Files (added, modified or removed): * NEWS.txt * codegen/py_codegen.py 2013-04-06 Carsten Grohmann Preselect some dialog elements Simplify usage of some dialogs by setting focus to first input widget and select the widget content. Files (added, modified or removed): * NEWS.txt * edit_sizers/edit_sizers.py * res/templates_ui.wxg * templates_ui.py * widgets/spacer/spacer.py 2013-04-03 Carsten Grohmann Show feedback in status bar if code generation dialog is suppressed Files (added, modified or removed): * application.py 2013-04-01 Carsten Grohmann Repair GUI test broken with 1223:602859354d4b Files (added, modified or removed): * tests/test_gui.py Remove empty line between shebang and encoding statement in Python files The additional empty line between the shebang and the encoding statement violates PEP 0263 and causes some trouble with utf-8 on win7. Files (added, modified or removed): * NEWS.txt * codegen/py_codegen.py * tests/casefiles/CalendarCtrl.py * tests/casefiles/FontColour.py * tests/casefiles/Gauge.py * tests/casefiles/Grid.py * tests/casefiles/HyperlinkCtrl_26.py * tests/casefiles/HyperlinkCtrl_28.py * tests/casefiles/PyAddApp_multi_detailed.py * tests/casefiles/PyAddApp_multi_gettext_detailed.py * tests/casefiles/PyAddApp_multi_gettext_simple.py * tests/casefiles/PyAddApp_multi_simple.py * tests/casefiles/PyOgg1.py * tests/casefiles/PyOgg1_oldnamespace.py * tests/casefiles/PyOgg2_app.py * tests/casefiles/PyOgg3.py * tests/casefiles/Python_Preferences.py * tests/casefiles/Sizers_classattr.py * tests/casefiles/Sizers_no_classattr.py * tests/casefiles/add_class_inplace_extended.py * tests/casefiles/add_class_inplace_orig.py * tests/casefiles/no_suitable_writer.py * tests/casefiles/remove_class_inplace_expected.py * tests/casefiles/remove_class_inplace_input.py Change handling of empty lines in file headers Hardcoded empty lines are removed. The empty lines are added to the variables shebang, tmpl_encoding and language_note. Thereby the generated code has not changed. Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py Minor change in source documentation Files (added, modified or removed): * application.py 2013-03-31 Carsten Grohmann Update Main Developer Files (added, modified or removed): * credits.txt Add a config option to suppress the code generation success message Files (added, modified or removed): * NEWS.txt * application.py * config.py * configUI.py * configdialog.py * res/preferences.wxg Fix plus sign for uncommitted changes in version number. "++" was shown due a logical bug. Now just "+" is shown. The plus sign in version number indicates not committed changes. Files (added, modified or removed): * common.py 2013-03-30 Carsten Grohmann Set version numbers back to HG to start new development cycle Files (added, modified or removed): * NEWS.txt * common.py * install/pyinstaller/wxglade-installer.iss 2013-03-29 Carsten Grohmann Added tag rel_0.6.6 for changeset 9ee81dcd0dc1 Files (added, modified or removed): * .hgtags Uninstall byte-code files for hyperlink widget too Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss Added tag rel_0.6.6 for changeset 4487d7edc422 Files (added, modified or removed): * .hgtags Bump version number to 0.6.6 Files (added, modified or removed): * common.py * install/pyinstaller/wxglade-installer.iss Prerelease documentation updates Files (added, modified or removed): * CHANGES.txt * NEWS.txt * README.txt * credits.txt Combine language specific panels in application properties dialog Files (added, modified or removed): * application.py * docs/html/apa.html * docs/html/apb.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch01s07.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch02s06.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/html/properties_window_application.png * docs/html/properties_window_settings.png * docs/html/properties_window_tab_1_change.png * docs/html/wxglade.png * docs/pdf/manual.pdf * docs/src/manual.xml * docs/src/properties_window.png * docs/src/properties_window_application.png * docs/src/properties_window_settings.png * docs/src/properties_window_tab_1_change.png * docs/src/wxglade.png Typo in source documentation Files (added, modified or removed): * application.py * codegen/__init__.py Change some default settings and reorg internal handling The primary changes are: - usage of UTF-8 as fallback encoding - enable gettext per default Some of the default values are converted from hard coded values to variables located in config module. Files (added, modified or removed): * NEWS.txt * application.py * codegen/__init__.py * config.py * docs/html/apa.html * docs/html/apb.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch01s07.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch02s06.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/pdf/manual.pdf * docs/src/manual.xml * tests/casefiles/PyAddApp_multi_detailed.py * tests/casefiles/PyAddApp_multi_gettext_detailed.py * tests/casefiles/PyAddApp_multi_gettext_simple.py * tests/casefiles/PyAddApp_multi_simple.py * xml_parse.py 2013-03-16 Carsten Grohmann Unify test cases Files (added, modified or removed): * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg1.wxg * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg1.wxg * tests/casefiles/PyOgg1.py * tests/casefiles/PyOgg1.wxg * tests/casefiles/PyOgg1_oldnamespace.py 2013-03-15 Carsten Grohmann Setting invalid windows names hasn't blocked fully (sf bug #154) Files (added, modified or removed): * NEWS.txt * edit_windows.py 2013-03-08 Carsten Grohmann Extend documentation with a best practice section Files (added, modified or removed): * docs/html/apa.html * docs/html/apb.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch01s07.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch02s06.html * docs/html/ch02s07.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch05.html * docs/html/ch05s03.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/pdf/manual.pdf * docs/src/manual.xml 2013-03-02 Carsten Grohmann Do not format wx classnames, constants and ... twice in Python. Add check if the parameter hand over to cn() is already formatted and do not format such a parameter again. This is just the case if the user enters language-specific formatted values. Files (added, modified or removed): * codegen/py_codegen.py * tests/test_codegen.py 2013-02-05 Carsten Grohmann Added tooltips to sizer elements and dialogs Files (added, modified or removed): * edit_sizers/edit_sizers.py 2013-02-04 Carsten Grohmann Unify code generation of adding objects to sizers Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/test_codegen.py 2013-02-03 Carsten Grohmann Set "Overwrite existing sources" for new projects Files (added, modified or removed): * NEWS.txt * application.py Small change to format flags in Python Files (added, modified or removed): * codegen/py_codegen.py 2013-02-02 Carsten Grohmann Don't format border property in add_sizeritem - it's always an integer Files (added, modified or removed): * codegen/pl_codegen.py * codegen/py_codegen.py Improve flag handling in Lisp code generator Files (added, modified or removed): * codegen/lisp_codegen.py * widgets/button/lisp_codegen.py * widgets/checkbox/lisp_codegen.py * widgets/choice/lisp_codegen.py * widgets/combo_box/lisp_codegen.py * widgets/gauge/lisp_codegen.py * widgets/hyperlink_ctrl/lisp_codegen.py * widgets/list_box/lisp_codegen.py * widgets/list_ctrl/lisp_codegen.py * widgets/notebook/lisp_codegen.py * widgets/panel/lisp_codegen.py * widgets/radio_box/lisp_codegen.py * widgets/radio_button/lisp_codegen.py * widgets/slider/lisp_codegen.py * widgets/spin_button/lisp_codegen.py * widgets/spin_ctrl/lisp_codegen.py * widgets/splitter_window/lisp_codegen.py * widgets/static_bitmap/lisp_codegen.py * widgets/static_line/lisp_codegen.py * widgets/static_text/lisp_codegen.py * widgets/text_ctrl/lisp_codegen.py * widgets/toolbar/lisp_codegen.py * widgets/tree_ctrl/lisp_codegen.py 2013-02-01 Carsten Grohmann Add "Store as attribute" for sizers Sizers won't store as class attributes per default. You can enable this using the new GUI element. This change primarily affects Python and C++, because the code generators for Perl and Lisp do already store sizers as class attributes. Files (added, modified or removed): * NEWS.txt * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * edit_sizers/edit_sizers.py * edit_sizers/lisp_sizers_codegen.py * edit_sizers/perl_sizers_codegen.py * edit_sizers/sizers_codegen.py * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg2_MyFrame.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Sizers_classattr.cpp * tests/casefiles/Sizers_classattr.h * tests/casefiles/Sizers_classattr.lisp * tests/casefiles/Sizers_classattr.pl * tests/casefiles/Sizers_classattr.py * tests/casefiles/Sizers_classattr.wxg * tests/casefiles/Sizers_classattr.xrc * tests/casefiles/Sizers_no_classattr.cpp * tests/casefiles/Sizers_no_classattr.h * tests/casefiles/Sizers_no_classattr.lisp * tests/casefiles/Sizers_no_classattr.pl * tests/casefiles/Sizers_no_classattr.py * tests/casefiles/Sizers_no_classattr.wxg * tests/casefiles/Sizers_no_classattr.xrc * tests/casefiles/add_class_inplace_extended.lisp * tests/casefiles/add_class_inplace_orig.lisp * tests/casefiles/remove_class_inplace_expected.lisp * tests/casefiles/remove_class_inplace_input.lisp * tests/test_codegen.py * wxglade.py 2013-01-31 Carsten Grohmann Fix AttributeError during preview of a new generated project. This bug is a regression introducted in commit 197d18d "Set codewriter variables back to defaults if a new document is created" Files (added, modified or removed): * codegen/py_codegen.py 2013-01-28 Carsten Grohmann Add source documention for in_sizers and in_windows Files (added, modified or removed): * xml_parse.py 2013-01-25 Carsten Grohmann Improve error message for missing test files Files (added, modified or removed): * tests/__init__.py Introduce WXGladeBaseTest._test_all() to generate code for all languages at once. Files (added, modified or removed): * tests/__init__.py * tests/test_codegen.py 2013-01-18 Carsten Grohmann Unify sizer code generation Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_sizers/lisp_sizers_codegen.py * edit_sizers/perl_sizers_codegen.py * edit_sizers/sizers_codegen.py * tests/casefiles/CPP_Preferences.cpp * tests/casefiles/FontColour.lisp * tests/casefiles/Gauge.lisp * tests/casefiles/Grid.lisp * tests/casefiles/HyperlinkCtrl_26.lisp * tests/casefiles/HyperlinkCtrl_28.lisp * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg2_MyFrame.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Lisp_wxBitmapButton.lisp * tests/casefiles/Perl_Preferences.pl * tests/casefiles/add_class_inplace_extended.lisp * tests/casefiles/add_class_inplace_orig.lisp * tests/casefiles/no_suitable_writer.lisp * tests/casefiles/remove_class_inplace_expected.lisp * tests/casefiles/remove_class_inplace_input.lisp 2013-01-15 Carsten Grohmann Add more wx constants to prevent formatting of those contants. Files (added, modified or removed): * codegen/pl_codegen.py 2013-01-07 Carsten Grohmann applied patch by Roel van Os: "When pasting: only search current top-level window for duplicate names" Original commit: 923:3b06bb046ccf at https://bitbucket.org/elentirmo/wxglade_elentirmo Files (added, modified or removed): * NEWS.txt * tree.py * xml_parse.py 2013-01-05 Carsten Grohmann Remove flag wxTHICK_FRAME because it is not available with wxPerl 2.8 The code generated by the test suite is fine, but you can't start the test programs with a current wxPerl. Thereby I've remove this flag. Files (added, modified or removed): * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg1.wxg * tests/casefiles/CPPOgg2.wxg * tests/casefiles/CPPOgg2_MyDialog.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg1.wxg * tests/casefiles/LispOgg2.wxg * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/LispOgg3.wxg * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg1.wxg * tests/casefiles/PlOgg2.wxg * tests/casefiles/PlOgg2_MyDialog.pm * tests/casefiles/PlOgg3.pl * tests/casefiles/PyOgg1.py * tests/casefiles/PyOgg1.wxg * tests/casefiles/PyOgg1_oldnamespace.py * tests/casefiles/PyOgg2.wxg * tests/casefiles/PyOgg2_MyDialog.py * tests/casefiles/PyOgg3.py 2013-01-04 Carsten Grohmann Don't add unsupported widgets to a sizer Widgets without code generator or widget that are not supporting the requested wx version are blacklisted now. Thereby the widgets won't add to any sizers. Files (added, modified or removed): * NEWS.txt * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/casefiles/HyperlinkCtrl_26.cpp * tests/casefiles/HyperlinkCtrl_26.lisp * tests/casefiles/HyperlinkCtrl_26.pl * tests/casefiles/HyperlinkCtrl_26.py * tests/casefiles/no_suitable_writer.cpp * tests/casefiles/no_suitable_writer.lisp * tests/casefiles/no_suitable_writer.pl * tests/casefiles/no_suitable_writer.py * tests/casefiles/no_suitable_writer.wxg Activate tests for HyperlinkCtrl and Lisp Files (added, modified or removed): * tests/casefiles/HyperlinkCtrl_26.lisp * tests/test_codegen.py Remove unused imports of cStringIO Files (added, modified or removed): * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py Add warning messages to Perl, Python and Lisp source code again Files (added, modified or removed): * codegen/__init__.py * tests/casefiles/HyperlinkCtrl_26.pl * tests/casefiles/HyperlinkCtrl_26.py * tests/casefiles/no_suitable_writer.lisp * tests/casefiles/no_suitable_writer.pl * tests/casefiles/no_suitable_writer.py 2013-01-02 Carsten Grohmann Unify code generation for widgets in Perl, Python and Lisp. Merge add_object() code of Perl, Python and Lisp code writer. The change unify the code generation code. The warning messages won't be included in generated Perl code now. One of the next commits will re-introduce the warning messages to Perl, Python and Lisp. Files (added, modified or removed): * codegen/__init__.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/casefiles/HyperlinkCtrl_26.pl * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Perl_Preferences.pl * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg2_MyDialog.pm * tests/casefiles/no_suitable_writer.lisp * tests/casefiles/no_suitable_writer.pl * tests/test_codegen.py 2013-01-01 Carsten Grohmann Solve logical bug in test case for no suitable writer A difference between generated and expected code causes an test failure (that's ok). But the temporary removed wxButton widget wouldn't restored in such a case. This change fixes the behaviour. Files (added, modified or removed): * tests/test_codegen.py 2012-12-30 Carsten Grohmann Replace traceback.print_exc() by common.message.exception() Files (added, modified or removed): * application.py * codegen/__init__.py * edit_sizers/edit_sizers.py * edit_windows.py * font_dialog.py * misc.py * tree.py * widget_properties.py * wxglade.py Rework generating code in Lisp, Perl and Python code generator This changes primarily unify the add_class() function and move it to the base class. BTW: This changes solves a bug that has suppressed adding extra code to Perl sources. Files (added, modified or removed): * codegen/__init__.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg1.wxg 2012-12-29 Carsten Grohmann Simplify access to parent attributes in SourceFileContent The language specific instances of SourceFileContent need access to a few attributes of the parent code writer instance. Most of the ctor parameters are replaced by a new parameter called "code_writer" and this is used to access parents attributes in the ctor once. Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py Exclude test cases from pylint run Files (added, modified or removed): * Makefile Use OrderedDict in XRC code generator to prevent flipping of entries. This flipping entries may break unittests randomly. Files (added, modified or removed): * codegen/xrc_codegen.py * tests/casefiles/add_class_inplace_extended.xrc Add 3rd party software OrderedDict The class OrderedDict provides a dictionary that remembers insertion order. This feature is useful to prevent flipping of lines or code blocks in automatically generated source code. Files (added, modified or removed): * docs/html/apa.html * docs/html/apb.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch01s07.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/pdf/manual.pdf * docs/src/manual.xml * ordereddict.py Suppress appendix toc in HTML documentation Files (added, modified or removed): * Makefile * docs/src/html.xsl 2012-12-28 Carsten Grohmann Fix warning for removed / renamed top-level classes. The mis-formatting of the warning messages, was probably introduced during the code generator rework. I'm sorry. Files (added, modified or removed): * codegen/__init__.py * tests/casefiles/remove_class_inplace_expected.cpp * tests/casefiles/remove_class_inplace_expected.lisp * tests/casefiles/remove_class_inplace_expected.pl * tests/casefiles/remove_class_inplace_expected.py * tests/test_codegen.py Add two test cases for adding and removing top-level widget in-place The generated code looks broken for Perl, Python and Lisp currently. Files (added, modified or removed): * tests/casefiles/add_class_inplace_extended.cpp * tests/casefiles/add_class_inplace_extended.h * tests/casefiles/add_class_inplace_extended.lisp * tests/casefiles/add_class_inplace_extended.pl * tests/casefiles/add_class_inplace_extended.py * tests/casefiles/add_class_inplace_extended.wxg * tests/casefiles/add_class_inplace_extended.xrc * tests/casefiles/add_class_inplace_orig.cpp * tests/casefiles/add_class_inplace_orig.h * tests/casefiles/add_class_inplace_orig.lisp * tests/casefiles/add_class_inplace_orig.pl * tests/casefiles/add_class_inplace_orig.py * tests/casefiles/add_class_inplace_orig.xrc * tests/casefiles/remove_class_inplace.wxg * tests/casefiles/remove_class_inplace_expected.cpp * tests/casefiles/remove_class_inplace_expected.h * tests/casefiles/remove_class_inplace_expected.lisp * tests/casefiles/remove_class_inplace_expected.pl * tests/casefiles/remove_class_inplace_expected.py * tests/casefiles/remove_class_inplace_expected.xrc * tests/casefiles/remove_class_inplace_input.cpp * tests/casefiles/remove_class_inplace_input.h * tests/casefiles/remove_class_inplace_input.lisp * tests/casefiles/remove_class_inplace_input.pl * tests/casefiles/remove_class_inplace_input.py * tests/casefiles/remove_class_inplace_input.xrc * tests/test_codegen.py 2012-12-26 Carsten Grohmann Add a test case to test "no suitable writer" warning. This warning occurs if the widget exists generally but there is no writer for the language to generate. Currently the warning won't written to all generated source files. It will be written for C++, Lisp and Perl. Not for Python. Files (added, modified or removed): * NEWS.txt * tests/casefiles/no_suitable_writer.cpp * tests/casefiles/no_suitable_writer.h * tests/casefiles/no_suitable_writer.lisp * tests/casefiles/no_suitable_writer.pl * tests/casefiles/no_suitable_writer.py * tests/casefiles/no_suitable_writer.wxg * tests/casefiles/no_suitable_writer.xrc * tests/test_codegen.py Replace os.mkdir() by more robust and recursive working os.makedirs() Files (added, modified or removed): * common.py * config.py * template.py Add faked implementation of os.makedirs() for unittests Files (added, modified or removed): * tests/__init__.py 2012-12-25 Carsten Grohmann Improve storing files from code generators. Add new functions to separate creating filenames to unify code generators a little bit more. Create sub directories e.g. for Perl modules during saving of the generated source code. Files (added, modified or removed): * codegen/__init__.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py Improve faked os.path.isdir() implementation This implementation will be used for tests only. Files (added, modified or removed): * tests/__init__.py 2012-12-23 Carsten Grohmann Rework generating constructor code in all code generators This causes some minor changes in the code generated by wxGlade for Lisp, Perl, Python and C++. For Perl: Some empty lines are gone. For Lisp: The round brackets are now outside of the blocks "begin wxGlade" and "end wxGlade" in the Lisp code now. There is an additional new line in front of the dependencies now. For Python: A single quotation mark has changed in a printed message. For C++: Event table and event handler stubs have been moved later in the same file. This change was necessary to equalise parts of the C++ code generator code. Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg2_MyDialog.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/CPP_wxCalendarCtrl.cpp * tests/casefiles/CalendarCtrl.pl * tests/casefiles/FontColour.lisp * tests/casefiles/FontColour.pl * tests/casefiles/Gauge.lisp * tests/casefiles/Gauge.pl * tests/casefiles/Grid.cpp * tests/casefiles/Grid.lisp * tests/casefiles/Grid.pl * tests/casefiles/Grid.py * tests/casefiles/HyperlinkCtrl_26.lisp * tests/casefiles/HyperlinkCtrl_26.pl * tests/casefiles/HyperlinkCtrl_28.lisp * tests/casefiles/HyperlinkCtrl_28.pl * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg2_MyFrame.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Lisp_wxBitmapButton.lisp * tests/casefiles/Perl_Preferences.pl * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg2_MyDialog.pm * tests/casefiles/PlOgg2_MyFrame.pm * tests/casefiles/PlOgg3.pl * tests/casefiles/PyOgg1.py * tests/casefiles/PyOgg1_oldnamespace.py * tests/casefiles/PyOgg2_MyDialog.py * tests/casefiles/PyOgg3.py 2012-12-22 Carsten Grohmann Fix for wrong formatted error message Files (added, modified or removed): * codegen/__init__.py 2012-12-21 Carsten Grohmann Rework __do_layout() and __set_properties() in all code generators Now the functions __do_layout() and __set_properties() are generated by using the same code. This causes some minor changes in the code generated by wxGlade for both functions for Perl and Lisp. Both changes effects only Perl and Lisp code generated for both functions and if in-place editing is used. For Perl: Some empty lines are gone. For Lisp: The round brackets are now outside of the blocks "begin wxGlade" and "end wxGlade" in the Lisp code now. Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/casefiles/CalendarCtrl.pl * tests/casefiles/FontColour.lisp * tests/casefiles/FontColour.pl * tests/casefiles/Gauge.lisp * tests/casefiles/Gauge.pl * tests/casefiles/Grid.lisp * tests/casefiles/Grid.pl * tests/casefiles/HyperlinkCtrl_26.lisp * tests/casefiles/HyperlinkCtrl_26.pl * tests/casefiles/HyperlinkCtrl_28.lisp * tests/casefiles/HyperlinkCtrl_28.pl * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg2_MyFrame.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Lisp_wxBitmapButton.lisp * tests/casefiles/Perl_Preferences.pl * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg2_MyDialog.pm * tests/casefiles/PlOgg2_MyFrame.pm * tests/casefiles/PlOgg3.pl Remove preview code from Perl code generator Files (added, modified or removed): * codegen/pl_codegen.py Add missing newlines in Lisp codegen for wxBitmapButton Files (added, modified or removed): * widgets/bitmap_button/lisp_codegen.py 2012-12-20 Carsten Grohmann Code generatore source code cleanups and aligments Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py Add BaseSourceFileContent._format_comment() and _source_comment(). Generic functions to write a warning message to the source code. Files (added, modified or removed): * codegen/__init__.py * codegen/xrc_codegen.py * tests/casefiles/HyperlinkCtrl_26.cpp * tests/casefiles/HyperlinkCtrl_26.pl 2012-12-19 Carsten Grohmann Fix directory check in CodeWriter class if just the file name is given Files (added, modified or removed): * xml_parse.py Update NEWS.txt Files (added, modified or removed): * NEWS.txt Add new widget HyperlinkCtrl Files (added, modified or removed): * NEWS.txt * icons/hyperlink_ctrl.xpm * tests/casefiles/HyperlinkCtrl_26.cpp * tests/casefiles/HyperlinkCtrl_26.h * tests/casefiles/HyperlinkCtrl_26.lisp * tests/casefiles/HyperlinkCtrl_26.pl * tests/casefiles/HyperlinkCtrl_26.py * tests/casefiles/HyperlinkCtrl_26.wxg * tests/casefiles/HyperlinkCtrl_26.xrc * tests/casefiles/HyperlinkCtrl_28.cpp * tests/casefiles/HyperlinkCtrl_28.h * tests/casefiles/HyperlinkCtrl_28.lisp * tests/casefiles/HyperlinkCtrl_28.pl * tests/casefiles/HyperlinkCtrl_28.py * tests/casefiles/HyperlinkCtrl_28.wxg * tests/casefiles/HyperlinkCtrl_28.xrc * tests/test_codegen.py * widgets/hyperlink_ctrl/__init__.py * widgets/hyperlink_ctrl/codegen.py * widgets/hyperlink_ctrl/hyperlink_ctrl.py * widgets/hyperlink_ctrl/lisp_codegen.py * widgets/hyperlink_ctrl/perl_codegen.py * widgets/widgets.txt 2012-12-18 Carsten Grohmann Remove code to support Python 2.2 Files (added, modified or removed): * events_mixin.py * misc.py Epydoc fix Files (added, modified or removed): * misc.py Remove unused code Files (added, modified or removed): * edit_windows.py * widget_properties.py Add support for widget builder that don't support all wx versions Some new widgets like wxHyperlinkCtrl are not available for wxWidgets 2.6. Thereby a new class attribute called "supported_by" is introducted. The attribute has set in the code generator class are well as in the class to edit the widget. The properties window shows a note at bottom if the widget is not supported at all wx versions supported by wxGlade. Files (added, modified or removed): * NEWS.txt * codegen/__init__.py * edit_windows.py * misc.py Add a class variable to Application class with all supported wx versions The class variable Application.all_supported_versions contains a list of all supported wxWidgets versions now. The variable is also used to build GUI elements. Files (added, modified or removed): * application.py 2012-12-17 Carsten Grohmann Just add a comment to source Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py 2012-12-16 Carsten Grohmann Unify codegenerators Move the initial action for adding a object from language specific code generators to base class BaseCodeWriter. Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py 2012-12-14 Carsten Grohmann Minor changes to eliminate a indentation level Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py Check abbreviations case in-sensitive and return them upper case The function capitalize() doesn't capitalize some abbreviations e.g. XML. Now the check for this abbreviations is case in-sensitive and returns the abbreviation always upper case. Files (added, modified or removed): * misc.py 2012-12-11 Carsten Grohmann Show filename of loaded project file Files (added, modified or removed): * main.py 2012-12-08 Carsten Grohmann Use common.messages.exception() for exception logging Files (added, modified or removed): * xml_parse.py Implement workaround for SAX internal UnicodeEncodeError (sf bug #149) Permanent workaround for Python bug "Sax parser crashes if given unicode file name" (http://bugs.python.org/issue11159). This bug causes a UnicodeEncodeError if the SAX XML parser wants to store an unicode filename internally. That's not a general file handling issue because the parameter source is an open file already. Files (added, modified or removed): * xml_parse.py Improve message logging Files (added, modified or removed): * NEWS.txt * application.py * codegen/__init__.py * codegen/xrc_codegen.py * common.py * main.py * widget_properties.py 2012-12-07 Carsten Grohmann Pep8 and documentation changes only Files (added, modified or removed): * xml_parse.py Rename unused variable Files (added, modified or removed): * layout_option_property.py Remove mutable default arguments Files (added, modified or removed): * main.py Add some comments Files (added, modified or removed): * edit_sizers/__init__.py Remove mutable default arguments Files (added, modified or removed): * application.py * widget_properties.py Remove unused parameter first in on_change_value() Currently on_change_value() is mostly used for event handling an mutable argument first isn't used. Files (added, modified or removed): * widget_properties.py 2012-12-04 Carsten Grohmann Update and extend documentation Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch01s07.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch02s06.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch05.html * docs/html/ch05s03.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/html/wxglade.png * docs/pdf/manual.pdf * docs/src/manual.xml * docs/src/wxglade.png Set HG executable bit only Files (added, modified or removed): * xrc2wxg.py 2012-12-03 Carsten Grohmann Fix exceptions during widget preview triggered by keyboard shortcut Files (added, modified or removed): * NEWS.txt * edit_windows.py * main.py 2012-12-01 Carsten Grohmann Pep8 changes only Files (added, modified or removed): * xrc2wxg.py 2012-11-28 Carsten Grohmann Add file extension automatically if no extension is given Files (added, modified or removed): * application.py * codegen/cpp_codegen.py * main.py Add myself Files (added, modified or removed): * credits.txt 2012-11-11 Carsten Grohmann Relocate parts of the i18n code to a earlier position in file Files (added, modified or removed): * codegen/cpp_codegen.py * tests/casefiles/CPPAddApp_multi_gettext_detailed.cpp * tests/casefiles/CPPAddApp_multi_gettext_simple.cpp * tests/casefiles/CPPAddApp_single_gettext_detailed.cpp * tests/casefiles/CPPAddApp_single_gettext_simple.cpp * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg1.h * tests/casefiles/CPPOgg2_main.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/CPPOgg3.h * tests/casefiles/CPP_Preferences.cpp * tests/casefiles/CPP_Preferences.h * tests/casefiles/FontColour.cpp * tests/casefiles/FontColour.h Remove cleaning variables in BaseCodeWriter.initialze() The cleanup is done in BaseCodeWriter._init_vars() already. Files (added, modified or removed): * codegen/__init__.py Add simple application start code to C++ code generator Files (added, modified or removed): * NEWS.txt * codegen/cpp_codegen.py * tests/casefiles/CPPAddApp_multi_gettext_detailed.cpp * tests/casefiles/CPPAddApp_multi_gettext_simple.cpp * tests/casefiles/CPPAddApp_multi_simple.cpp * tests/casefiles/CPPAddApp_single_gettext_detailed.cpp * tests/casefiles/CPPAddApp_single_gettext_simple.cpp * tests/casefiles/CPPAddApp_single_simple.cpp * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg2_main.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/CPP_Preferences.cpp * tests/casefiles/CPP_wxCalendarCtrl.cpp * tests/casefiles/CalendarCtrl.cpp * tests/casefiles/FontColour.cpp * tests/casefiles/Gauge.cpp * tests/casefiles/Grid.cpp * tests/test_codegen.py Add i18n support to C++ code generator Files (added, modified or removed): * NEWS.txt * codegen/cpp_codegen.py * tests/casefiles/CPPAddApp_multi_gettext_detailed.cpp * tests/casefiles/CPPAddApp_single_gettext_detailed.cpp * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg2_main.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/FontColour.cpp 2012-11-10 Carsten Grohmann Update NEWS.txt Files (added, modified or removed): * NEWS.txt Rename some codegen variables and extent source documentation Files (added, modified or removed): * codegen/__init__.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py Relocate Pythons gettext import statements Files (added, modified or removed): * codegen/py_codegen.py * tests/casefiles/FontColour.py * tests/casefiles/PyAddApp_multi_gettext_detailed.py * tests/casefiles/PyAddApp_multi_gettext_simple.py * tests/casefiles/PyAddApp_single_gettext_detailed.py * tests/casefiles/PyAddApp_single_gettext_simple.py * tests/casefiles/PyOgg1.py * tests/casefiles/PyOgg1_oldnamespace.py * tests/casefiles/PyOgg2_app.py * tests/casefiles/PyOgg3.py * tests/casefiles/Python_Preferences.py Move python codegen specific code from BaseCodeWriter to PythonCodeWriter Files (added, modified or removed): * codegen/__init__.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py 2012-11-09 Carsten Grohmann Set codewriter variables back to defaults if a new document is created Files (added, modified or removed): * codegen/__init__.py * codegen/pl_codegen.py * codegen/py_codegen.py 2012-11-07 Carsten Grohmann Simplify generation of Perl application startup code Files (added, modified or removed): * codegen/pl_codegen.py * tests/casefiles/PlAddApp_multi_gettext_simple.pl * tests/casefiles/PlAddApp_multi_simple.pl * tests/casefiles/PlOgg2_app.pl Separate code templates for application startup code The code pieces are moved into class variables as well as join language specific parts of add_app(). Files (added, modified or removed): * NEWS.txt * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/test_codegen.py 2012-11-05 Carsten Grohmann Add more tests for app code generation Files (added, modified or removed): * tests/casefiles/CPPAddApp_detailed.cpp * tests/casefiles/CPPAddApp_gettext_detailed.cpp * tests/casefiles/CPPAddApp_gettext_simple.cpp * tests/casefiles/CPPAddApp_multi_detailed.cpp * tests/casefiles/CPPAddApp_multi_gettext_detailed.cpp * tests/casefiles/CPPAddApp_simple.cpp * tests/casefiles/CPPAddApp_single_detailed.cpp * tests/casefiles/CPPAddApp_single_gettext_detailed.cpp * tests/casefiles/CPPAddApp_single_gettext_simple.cpp * tests/casefiles/CPPAddApp_single_simple.cpp * tests/casefiles/LispAddApp_detailed.lisp * tests/casefiles/LispAddApp_gettext_detailed.lisp * tests/casefiles/LispAddApp_gettext_simple.lisp * tests/casefiles/LispAddApp_multi_detailed.lisp * tests/casefiles/LispAddApp_multi_gettext_detailed.lisp * tests/casefiles/LispAddApp_multi_gettext_simple.lisp * tests/casefiles/LispAddApp_multi_simple.lisp * tests/casefiles/LispAddApp_simple.lisp * tests/casefiles/LispAddApp_single_detailed.lisp * tests/casefiles/LispAddApp_single_gettext_detailed.lisp * tests/casefiles/LispAddApp_single_gettext_simple.lisp * tests/casefiles/LispAddApp_single_simple.lisp * tests/casefiles/PlAddApp_detailed.pl * tests/casefiles/PlAddApp_gettext_detailed.pl * tests/casefiles/PlAddApp_gettext_simple.pl * tests/casefiles/PlAddApp_multi_detailed.pl * tests/casefiles/PlAddApp_multi_gettext_detailed.pl * tests/casefiles/PlAddApp_multi_gettext_simple.pl * tests/casefiles/PlAddApp_multi_simple.pl * tests/casefiles/PlAddApp_simple.pl * tests/casefiles/PlAddApp_single_detailed.pl * tests/casefiles/PlAddApp_single_gettext_detailed.pl * tests/casefiles/PlAddApp_single_gettext_simple.pl * tests/casefiles/PlAddApp_single_simple.pl * tests/casefiles/PyAddApp_detailed.py * tests/casefiles/PyAddApp_gettext_detailed.py * tests/casefiles/PyAddApp_gettext_simple.py * tests/casefiles/PyAddApp_multi_detailed.py * tests/casefiles/PyAddApp_multi_gettext_detailed.py * tests/casefiles/PyAddApp_multi_gettext_simple.py * tests/casefiles/PyAddApp_multi_simple.py * tests/casefiles/PyAddApp_simple.py * tests/casefiles/PyAddApp_single_detailed.py * tests/casefiles/PyAddApp_single_gettext_detailed.py * tests/casefiles/PyAddApp_single_gettext_simple.py * tests/casefiles/PyAddApp_single_simple.py * tests/test_codegen.py Rename CPPCodeWriter.output_source to CPPCodeWriter.output_file Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * tests/test_codegen.py 2012-11-04 Carsten Grohmann Add test for app code generation Files (added, modified or removed): * tests/casefiles/CPPAddApp_detailed.cpp * tests/casefiles/CPPAddApp_gettext_detailed.cpp * tests/casefiles/CPPAddApp_gettext_simple.cpp * tests/casefiles/CPPAddApp_simple.cpp * tests/casefiles/LispAddApp_detailed.lisp * tests/casefiles/LispAddApp_gettext_detailed.lisp * tests/casefiles/LispAddApp_gettext_simple.lisp * tests/casefiles/LispAddApp_simple.lisp * tests/casefiles/PlAddApp_detailed.pl * tests/casefiles/PlAddApp_gettext_detailed.pl * tests/casefiles/PlAddApp_gettext_simple.pl * tests/casefiles/PlAddApp_simple.pl * tests/casefiles/PyAddApp_detailed.py * tests/casefiles/PyAddApp_gettext_detailed.py * tests/casefiles/PyAddApp_gettext_simple.py * tests/casefiles/PyAddApp_simple.py * tests/test_codegen.py 2012-11-01 Carsten Grohmann Add more tooltips to properties window Files (added, modified or removed): * NEWS.txt * application.py Added tooltip for DialogProperty Files (added, modified or removed): * widget_properties.py 2012-10-29 Carsten Grohmann Rework tooltip handling to allow to set of tooltips without calling display() Files (added, modified or removed): * widget_properties.py Minor layout changes in wxGlade manual Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/pdf/manual.pdf * docs/src/manual.xml 2012-10-28 Carsten Grohmann Minor source documentation changes Files (added, modified or removed): * widget_properties.py Enable sorting and capitalising code writer languages in "Properties" window Files (added, modified or removed): * application.py * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/design_window.png * docs/html/design_window_empty_slot.png * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/html/properties_window.png * docs/html/select_frame.png * docs/pdf/manual.pdf * docs/src/design_window.png * docs/src/design_window_empty_slot.png * docs/src/properties_window.png * docs/src/select_frame.png Extent RadioProperty to sort and capitalise the choices Files (added, modified or removed): * widget_properties.py 2012-10-27 Carsten Grohmann Consolidate creation of file dialog wildcards Files (added, modified or removed): * application.py Write and use own function to capitalise first character. This function don't change upper case abbreviations like XML and XRC. Be carefully because this function may break i18n. Files (added, modified or removed): * application.py * misc.py * widget_properties.py 2012-10-11 Carsten Grohmann Minor update Files (added, modified or removed): * README.txt 2012-10-09 Carsten Grohmann Improve tooltip for wxButton Files (added, modified or removed): * widgets/button/button.py Add test case for testing code generation in GUI Files (added, modified or removed): * application.py * tests/test_gui.py Separate setting of test specific options in a wxg (XML) file Files (added, modified or removed): * tests/__init__.py 2012-09-19 Carsten Grohmann Replace spaces in a template file by underscore Files (added, modified or removed): * templates/Dialog with two buttons.wgt * templates/Dialog_with_two_buttons.wgt 2012-09-16 Carsten Grohmann Change tooltip handling - mangled property names will not show anymore - tooltips will be shown at all elements of a property Files (added, modified or removed): * NEWS.txt * layout_option_property.py * widget_properties.py 2012-09-15 Carsten Grohmann Remove unused variable msg from command_line_code_generation() Files (added, modified or removed): * wxglade.py 2012-08-13 Carsten Grohmann Rebuild documentation Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/pdf/manual.pdf Update and extend documentation Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch05.html * docs/html/ch05s03.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/html/properties_window.png * docs/pdf/manual.pdf * docs/src/manual.xml * docs/src/properties_window.png 2012-07-08 Carsten Grohmann Add test code for wxCalendarCtrl Files (added, modified or removed): * tests/casefiles/CalendarCtrl.cpp * tests/casefiles/CalendarCtrl.h * tests/casefiles/CalendarCtrl.pl * tests/casefiles/CalendarCtrl.py * tests/casefiles/CalendarCtrl.wxg * tests/casefiles/CalendarCtrl.xrc * tests/test_codegen.py 2012-07-08 Eric McKeeth Add Perl code generator for wxCalendarCtrl Special thanks to Eric for sharing his code. Files (added, modified or removed): * widgets/calendar_ctrl/perl_codegen.py 2012-06-11 Carsten Grohmann Fix typos introduces in last commit :-( Files (added, modified or removed): * codegen/cpp_codegen.py Write isolation directives at beginning in C++ header files Files (added, modified or removed): * NEWS.txt * codegen/cpp_codegen.py * tests/casefiles/CPPOgg1.h * tests/casefiles/CPPOgg2_MyDialog.h * tests/casefiles/CPPOgg2_MyFrame.h * tests/casefiles/CPPOgg3.h * tests/casefiles/CPP_Preferences.h * tests/casefiles/CPP_wxCalendarCtrl.h * tests/casefiles/FontColour.h * tests/casefiles/Gauge.h * tests/casefiles/Grid.h 2012-06-09 Carsten Grohmann Extend documentation about the various installation methods Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/pdf/manual.pdf * docs/src/manual.xml 2012-06-07 Carsten Grohmann Fix regression in generate_code_id() for parameter id Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/test_codegen.py 2012-05-31 Carsten Grohmann Replace tabs by spaces introducted in 1090:c93d25c53d31 (thanks Davorin) Files (added, modified or removed): * wxglade.py 2012-05-30 Carsten Grohmann Improve name generation of notebooks and notebook panes Noetbook names as well as notebook pane names should be unique. Deleted default names won't be reused. Files (added, modified or removed): * widgets/notebook/notebook.py 2012-05-27 Carsten Grohmann Adapt test suite to handle improved error handling well Files (added, modified or removed): * tests/__init__.py Fix: Same default names for multiple notebooks (sf bug #2000566) Files (added, modified or removed): * NEWS.txt * widgets/notebook/notebook.py 2012-05-25 Carsten Grohmann Update Copyright notice at code generators Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py 2012-05-23 Carsten Grohmann Use error() for printing error messages Files (added, modified or removed): * wxglade.py Improve error handling for non-existing and non-writable output directories Files (added, modified or removed): * application.py * errors.py * wxglade.py * xml_parse.py 2012-05-20 Carsten Grohmann Empty output path raises XmlParsingError during code generation Files (added, modified or removed): * xml_parse.py Improve error handling of chmod after writing main output file Files (added, modified or removed): * codegen/__init__.py 2012-05-18 Carsten Grohmann Fix regression for gettext handling in Perl code generator Files (added, modified or removed): * codegen/pl_codegen.py * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg1.wxg * tests/casefiles/CPPOgg2.wxg * tests/casefiles/CPPOgg2_MyDialog.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/FontColour.pl * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg1.wxg * tests/casefiles/LispOgg2.wxg * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/LispOgg3.wxg * tests/casefiles/Perl_Preferences.pl * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg1.wxg * tests/casefiles/PlOgg2.wxg * tests/casefiles/PlOgg2_MyDialog.pm * tests/casefiles/PlOgg2_MyFrame.pm * tests/casefiles/PlOgg3.pl * tests/casefiles/PyOgg1.py * tests/casefiles/PyOgg1.wxg * tests/casefiles/PyOgg1_oldnamespace.py * tests/casefiles/PyOgg2.wxg * tests/casefiles/PyOgg2_MyDialog.py * tests/casefiles/PyOgg3.py 2012-05-12 Carsten Grohmann Improve searching for files credits.txt and license.txt Both files were not found if wxGlade has been installed at /opt/wxglade like suggested in manual. Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/pdf/manual.pdf * docs/src/manual.xml * wxglade.py Unify codegenerators a little bit more Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py Minor changes for epydoc Files (added, modified or removed): * codegen/__init__.py 2012-05-11 Carsten Grohmann Write small example how to compile in all C++ source and header files Files (added, modified or removed): * codegen/cpp_codegen.py * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg1.h * tests/casefiles/CPPOgg2_MyDialog.cpp * tests/casefiles/CPPOgg2_MyDialog.h * tests/casefiles/CPPOgg2_MyFrame.cpp * tests/casefiles/CPPOgg2_MyFrame.h * tests/casefiles/CPPOgg2_main.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/CPPOgg3.h * tests/casefiles/CPP_Preferences.cpp * tests/casefiles/CPP_Preferences.h * tests/casefiles/CPP_wxCalendarCtrl.cpp * tests/casefiles/CPP_wxCalendarCtrl.h * tests/casefiles/FontColour.cpp * tests/casefiles/FontColour.h * tests/casefiles/Gauge.cpp * tests/casefiles/Gauge.h * tests/casefiles/Grid.cpp * tests/casefiles/Grid.h Convert non-C++ statements into C++ statements to allow compiling Now all C++ examples compile well. Files (added, modified or removed): * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg1.h * tests/casefiles/CPPOgg1.wxg * tests/casefiles/CPPOgg2.wxg * tests/casefiles/CPPOgg2_MyDialog.h * tests/casefiles/CPPOgg2_MyFrame.h * tests/casefiles/CPPOgg3.h 2012-05-10 Carsten Grohmann Move equal finalize() functions into code generator base class Files (added, modified or removed): * codegen/__init__.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py 2012-05-09 Carsten Grohmann Minor code changes Files (added, modified or removed): * codegen/lisp_codegen.py * codegen/pl_codegen.py Unify code generation for colours and fonts Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/casefiles/FontColour.cpp * tests/casefiles/FontColour.h * tests/casefiles/FontColour.lisp * tests/casefiles/FontColour.pl * tests/casefiles/FontColour.py * tests/casefiles/FontColour.wxg * tests/casefiles/FontColour.xrc * tests/test_codegen.py 2012-05-08 Carsten Grohmann Fix: Wrong attribute names Files (added, modified or removed): * tests/casefiles/Grid.cpp * tests/casefiles/Grid.lisp * tests/casefiles/Grid.pl * tests/casefiles/Grid.py * tests/casefiles/Grid.wxg * tests/casefiles/Grid.xrc Add one testcase for generating python code using old wx namespace Files (added, modified or removed): * tests/__init__.py * tests/casefiles/PyOgg1_oldnamespace.py * tests/test_codegen.py Format flags written namespace independent by the python code generator Old version differs between old wx namespace and the new one Files (added, modified or removed): * codegen/py_codegen.py Cleanup obsolete for_version statement Files (added, modified or removed): * widgets/menubar/codegen.py Cleanup tooltips for extracode and extraproperties This functionality is available at all code generators now Files (added, modified or removed): * code_property.py Minor changes for current maintainer Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/man/manpage.xml * docs/pdf/manual.pdf * docs/src/manual.xml 2012-05-07 Carsten Grohmann Rework and unify code generators. All code generators support extracode and extraproperties now. Sorry for the huge commit. Files (added, modified or removed): * NEWS.txt * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * tests/__init__.py * tests/casefiles/CPPOgg1.cpp * tests/casefiles/CPPOgg1.h * tests/casefiles/CPPOgg1.wxg * tests/casefiles/CPPOgg2.wxg * tests/casefiles/CPPOgg2_MyDialog.cpp * tests/casefiles/CPPOgg2_MyDialog.h * tests/casefiles/CPPOgg2_MyFrame.cpp * tests/casefiles/CPPOgg2_MyFrame.h * tests/casefiles/CPPOgg2_main.cpp * tests/casefiles/CPPOgg3.cpp * tests/casefiles/CPPOgg3.h * tests/casefiles/CPP_Preferences.cpp * tests/casefiles/CPP_Preferences.h * tests/casefiles/CPP_wxCalendarCtrl.cpp * tests/casefiles/CPP_wxCalendarCtrl.h * tests/casefiles/CPP_wxCalendarCtrl.wxg * tests/casefiles/Gauge.cpp * tests/casefiles/Gauge.h * tests/casefiles/Gauge.lisp * tests/casefiles/Gauge.pl * tests/casefiles/Gauge.py * tests/casefiles/Gauge.wxg * tests/casefiles/Grid.cpp * tests/casefiles/Grid.h * tests/casefiles/Grid.lisp * tests/casefiles/Grid.pl * tests/casefiles/Grid.py * tests/casefiles/Grid.wxg * tests/casefiles/Grid.xrc * tests/casefiles/GridEvents.cpp * tests/casefiles/GridEvents.h * tests/casefiles/GridEvents.lisp * tests/casefiles/GridEvents.pl * tests/casefiles/GridEvents.py * tests/casefiles/GridEvents.wxg * tests/casefiles/GridEvents.xrc * tests/casefiles/LispOgg1.lisp * tests/casefiles/LispOgg1.wxg * tests/casefiles/LispOgg2.wxg * tests/casefiles/LispOgg2_MyDialog.lisp * tests/casefiles/LispOgg2_MyFrame.lisp * tests/casefiles/LispOgg2_app.lisp * tests/casefiles/LispOgg3.lisp * tests/casefiles/LispOgg3.wxg * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Lisp_Preferences.wxg * tests/casefiles/Lisp_wxBitmapButton.lisp * tests/casefiles/Lisp_wxBitmapButton.wxg * tests/casefiles/Notebook_w_tabs.wxg * tests/casefiles/Notebook_wo_tabs.wxg * tests/casefiles/Perl_Preferences.pl * tests/casefiles/PlOgg1.pl * tests/casefiles/PlOgg1.wxg * tests/casefiles/PlOgg2.wxg * tests/casefiles/PlOgg2_MyDialog.pm * tests/casefiles/PlOgg2_MyFrame.pm * tests/casefiles/PlOgg2_app.pl * tests/casefiles/PlOgg3.pl * tests/casefiles/Preferences.wxg * tests/casefiles/PyOgg1.py * tests/casefiles/PyOgg1.wxg * tests/casefiles/PyOgg2.wxg * tests/casefiles/PyOgg2_MyDialog.py * tests/casefiles/PyOgg2_MyFrame.py * tests/casefiles/PyOgg2_app.py * tests/casefiles/PyOgg3.py * tests/casefiles/Python_Preferences.py * tests/test_codegen.py 2012-04-14 Carsten Grohmann Fix: Lisp code generation for wxFrame and wxDialog Files (added, modified or removed): * widgets/dialog/lisp_codegen.py * widgets/frame/lisp_codegen.py 2012-04-12 Carsten Grohmann Fix: Encoding detection for Mac OS X Files (added, modified or removed): * NEWS.txt * application.py 2012-03-14 Carsten Grohmann Add two missing HTML files of the previously committed user manual Files (added, modified or removed): * docs/html/ch03s07.html * docs/html/pr01s03.html Update wxGlade user manual Files (added, modified or removed): * Makefile * NEWS.txt * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch04s03.html * docs/html/ch04s04.html * docs/html/ch04s05.html * docs/html/ch04s06.html * docs/html/ch04s07.html * docs/html/ch04s08.html * docs/html/ch04s09.html * docs/html/ch04s10.html * docs/html/ch04s11.html * docs/html/ch04s12.html * docs/html/ch04s13.html * docs/html/ch04s14.html * docs/html/ch04s15.html * docs/html/ch04s16.html * docs/html/ch04s17.html * docs/html/ch04s18.html * docs/html/ch04s19.html * docs/html/ch04s20.html * docs/html/ch04s21.html * docs/html/ch04s22.html * docs/html/ch04s23.html * docs/html/ch04s24.html * docs/html/ch04s25.html * docs/html/ch04s26.html * docs/html/ch04s27.html * docs/html/ch05.html * docs/html/ch05s02.html * docs/html/ch05s03.html * docs/html/ch05s04.html * docs/html/example_baseclasses.png * docs/html/example_eventhandler.png * docs/html/example_setproperty.png * docs/html/example_subclassed.png * docs/html/example_variableassigment.png * docs/html/index.html * docs/html/main_window.png * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/html/properties_window.png * docs/html/properties_window_tab_1.png * docs/html/properties_window_tab_1_change.png * docs/html/properties_window_tab_2.png * docs/html/properties_window_tab_3.png * docs/html/properties_window_tab_4.png * docs/html/properties_window_tab_5.png * docs/pdf/manual.pdf * docs/src/example_baseclasses.png * docs/src/example_eventhandler.png * docs/src/example_setproperty.png * docs/src/example_subclassed.png * docs/src/example_variableassigment.png * docs/src/main_window.png * docs/src/manual.xml * docs/src/pdf.xsl * docs/src/properties_window.png * docs/src/properties_window_tab_1.png * docs/src/properties_window_tab_1_change.png * docs/src/properties_window_tab_2.png * docs/src/properties_window_tab_3.png * docs/src/properties_window_tab_4.png * docs/src/properties_window_tab_5.png 2012-03-03 Carsten Grohmann Add more constants ... Files (added, modified or removed): * codegen/pl_codegen.py 2012-03-02 Carsten Grohmann Fix: Handling of wx constants in generated Perl code Files (added, modified or removed): * codegen/pl_codegen.py * edit_sizers/perl_sizers_codegen.py * tests/casefiles/GridEvents.pl * tests/casefiles/Perl_Preferences.pl Add tests for wxGauge code generation Files (added, modified or removed): * tests/casefiles/Gauge.cpp * tests/casefiles/Gauge.h * tests/casefiles/Gauge.lisp * tests/casefiles/Gauge.pl * tests/casefiles/Gauge.py * tests/casefiles/Gauge.wxg * tests/casefiles/Gauge.xrc * tests/test_codegen.py 2012-03-02 Johan Vromans Fix: Lisp codegen for the Gauge widget was an exact copy of the Perl codegen Files (added, modified or removed): * widgets/gauge/lisp_codegen.py 2012-02-29 Carsten Grohmann Add tooltips for widgets properties "Id" and "Name" Files (added, modified or removed): * edit_windows.py 2012-02-21 Carsten Grohmann Add searching for a parallel Python module directory Files (added, modified or removed): * wxglade 2012-02-18 Carsten Grohmann Generate Perl code for wxStaticBox() with wxID_ANY instead of -1 Files (added, modified or removed): * edit_sizers/perl_sizers_codegen.py * tests/casefiles/Perl_Preferences.pl Add generate_code_id() tests incl. minor code reorg in all generate_code_id() This change may also fix some wrong behaviour introduced by changing the default widget id from -1 to wxID_ANY. Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * tests/casefiles/GridEvents.lisp * tests/casefiles/GridEvents.pl * tests/casefiles/GridEvents.py * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Lisp_wxBitmapButton.lisp * tests/casefiles/Perl_Preferences.pl * tests/test_codegen.py 2012-02-08 Carsten Grohmann Fix: String formatting issue for event handlers in Lisp code generator Files (added, modified or removed): * NEWS.txt * codegen/lisp_codegen.py * tests/casefiles/GridEvents.lisp * tests/test_codegen.py Add small tests for wxGrid events (sf bug #1542195 - not reproducible) Files (added, modified or removed): * tests/casefiles/GridEvents.cpp * tests/casefiles/GridEvents.h * tests/casefiles/GridEvents.pl * tests/casefiles/GridEvents.py * tests/casefiles/GridEvents.wxg * tests/casefiles/GridEvents.xrc * tests/test_codegen.py Show differences for failed non GUI tests (solves buggy last commit) Files (added, modified or removed): * tests/__init__.py 2012-02-07 Carsten Grohmann Regorganise test code Files (added, modified or removed): * tests/__init__.py * tests/test_codegen.py * tests/test_gui.py Do not load wxversion if wx already loaded Files (added, modified or removed): * wxglade.py Adapt pylint settings in Makefile Files (added, modified or removed): * Makefile Reorg imports Files (added, modified or removed): * code_property.py * tree.py 2012-02-04 Carsten Grohmann Split sources of test cases to generate working source files Files (added, modified or removed): * tests/casefiles/CPP_Preferences.h * tests/casefiles/CPP_Preferences.wxg * tests/casefiles/Perl_Preferences.pl * tests/casefiles/Perl_Preferences.wxg * tests/test_codegen.py Change default widget ID from -1 to wxID_ANY and adapt codegen Files (added, modified or removed): * NEWS.txt * codegen/py_codegen.py * edit_sizers/sizers_codegen.py * edit_windows.py * tests/casefiles/CPP_Preferences.cpp * tests/casefiles/Python_Preferences.py 2012-02-01 Carsten Grohmann Exclude test suite from full edtion Windows installer Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss 2012-01-30 Carsten Grohmann Split single GUI test in two different tests Files (added, modified or removed): * tests/test_gui.py Don't load wxversion twice wxversion will be imported several times only if the test suite is running. Files (added, modified or removed): * wxglade.py Add first GUI test case Files (added, modified or removed): * Makefile * test.py * tests/__init__.py * tests/casefiles/Notebook_w_tabs.wxg * tests/casefiles/Notebook_wo_tabs.wxg * tests/test_gui.py Improve error message for import notebooks without tabs Files (added, modified or removed): * widgets/notebook/notebook.py 2012-01-27 Carsten Grohmann Move preferences dialog to own file to simplify handling e.g. for test cases Files (added, modified or removed): * config.py * configdialog.py * main.py Split initialisation of wxGlade to simplify handling e.g. for test cases Files (added, modified or removed): * main.py * tests/__init__.py * wxglade.py Add platform variable This variable is introduced to eliminate dependencies to wx (e.g. wx.Platform) for non-interactive runs. Files (added, modified or removed): * common.py Minor update of NEWS file Files (added, modified or removed): * NEWS.txt Remove code to support wxPython < 2.6 Files (added, modified or removed): * misc.py 2012-01-25 Carsten Grohmann PEP8 changes and minor cleanups Files (added, modified or removed): * widget_properties.py [FIX] Prevent deleting last notebook tab (sf bug #3126974) Files (added, modified or removed): * widgets/notebook/notebook.py Added parameter to prevent removing last entry in GridProperty Files (added, modified or removed): * widget_properties.py 2012-01-23 Carsten Grohmann Disable usage of KDE file dialogs for non GTK platforms Files (added, modified or removed): * config.py * install/pyinstaller/wxglade-installer.iss 2012-01-20 Carsten Grohmann Loading code generators loads only Python files (.py, .pyc, .pyo) only now Files (added, modified or removed): * common.py 2012-01-19 Carsten Grohmann Show better version string at windows installer welcome page Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss 2012-01-17 Davorin Kunstelj [FIX] Attribute name mismatch in source of manual page Files (added, modified or removed): * docs/man/manpage.xml 2012-01-14 Carsten Grohmann Rework code generation code to move common parts to codegen/__init__.py and rework code generators partially to be more eqal. Files (added, modified or removed): * codegen/__init__.py * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py 2012-01-12 Carsten Grohmann [FIX] Prevent caching effects in Lisp code generator The code generator remembers parts of earlier generated code without initialisation of class_lines in initialize() Files (added, modified or removed): * NEWS.txt * codegen/lisp_codegen.py Add stub for new version Files (added, modified or removed): * NEWS.txt Add more test cases Files (added, modified or removed): * tests/casefiles/CPP_Preferences.cpp * tests/casefiles/CPP_Preferences.h * tests/casefiles/Lisp_Preferences.lisp * tests/casefiles/Perl_Preferences.pl * tests/casefiles/Preferences.wxg * tests/casefiles/Python_Preferences.py * tests/test_codegen.py 2012-01-11 Carsten Grohmann Set version numbers back to HG to start new development cycle Files (added, modified or removed): * common.py * install/pyinstaller/wxglade-installer.iss 2012-01-08 Carsten Grohmann Added tag rel_0.6.5 for changeset 8f314df2d7c8 Files (added, modified or removed): * .hgtags Bump version number to 0.6.5 Files (added, modified or removed): * common.py * install/pyinstaller/wxglade-installer.iss Prerelease documentation updates Files (added, modified or removed): * CHANGES.txt * NEWS.txt * README.txt 2012-01-08 Carsten Grohmann Minor manpage changes Files (added, modified or removed): * docs/man/manpage.xml 2012-01-07 Carsten Grohmann [FIX] Solve issue "C++ CalendarControl issues in 0.6.3" (sf bug #2782306) Files (added, modified or removed): * tests/casefiles/CPP_wxCalendarCtrl.cpp * tests/casefiles/CPP_wxCalendarCtrl.h * tests/casefiles/CPP_wxCalendarCtrl.wxg * tests/test_codegen.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/calendar_ctrl/codegen.py [FIX] Wrong parameters for CodeWriter() in command_line_code_generation() Bug was introduces with changeset changeset 1022 31fe078c5b0a. Files (added, modified or removed): * NEWS.txt * wxglade.py [FIX] Allow saving of generated code to filenames without directory part Files (added, modified or removed): * common.py Add new file NEWS.txt to summarise release changes Files (added, modified or removed): * CHANGES.txt * NEWS.txt * docs/ReleaseSteps.txt * install/pyinstaller/wxglade-installer.iss * install/pyinstaller/wxglade.spec * install/rpm/wxglade.spec * setup.py Enable gettext for usage message Files (added, modified or removed): * wxglade.py Update and extend manual page Files (added, modified or removed): * docs/man/manpage.xml 2012-01-06 Carsten Grohmann Change option handling as well as add --version and --help Files (added, modified or removed): * wxglade.py remove support for Python 2.2 Files (added, modified or removed): * wxglade.py * xrc2wxg.py Remove unused import edit_windows Files (added, modified or removed): * tree.py 2012-01-06 Davorin Kunstelj Added column sizes parameter to GridProperty init parameters Files (added, modified or removed): * widget_properties.py Added tooltip for CheckBoxProperty Files (added, modified or removed): * widget_properties.py 2012-01-06 Carsten Grohmann Remove code to support wxPython < 2.6 (forgotten part) Files (added, modified or removed): * application.py 2012-01-05 Carsten Grohmann Add small test suite Files (added, modified or removed): * Makefile * test.py * tests/__init__.py * tests/casefiles/Lisp_wxBitmapButton.lisp * tests/casefiles/Lisp_wxBitmapButton.wxg * tests/test_codegen.py [FIX] Add missing path quotation to codegen.lisp_codegen Files (added, modified or removed): * codegen/lisp_codegen.py 2012-01-03 Carsten Grohmann Remove needless print statement in Lisp code generator Files (added, modified or removed): * codegen/lisp_codegen.py Replace tab characters by spaces in Lisp code generator Files (added, modified or removed): * codegen/lisp_codegen.py [FIX] Wrong file extensions created by Lisp code generator Files (added, modified or removed): * codegen/lisp_codegen.py Minor documentation and code reorg in common.save_file() Files (added, modified or removed): * common.py 2012-01-02 Carsten Grohmann Minor code reorg in common.load_code_writers() Files (added, modified or removed): * common.py Merge with original file Files (added, modified or removed): * install/update-po.py Remove duplicate code EditComboBox.create_widget() Files (added, modified or removed): * widgets/combo_box/combo_box.py Remove code to support wxPython < 2.6 Files (added, modified or removed): * about.py * application.py * common.py * config.py * edit_sizers/edit_sizers.py * edit_windows.py * font_dialog.py * main.py * misc.py * tree.py * widget_properties.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/menubar/menubar.py * widgets/notebook/notebook.py * widgets/panel/panel.py * widgets/toolbar/toolbar.py * xml_parse.py Remove unused function misc.sizer_fixed_Insert() Files (added, modified or removed): * main.py * misc.py Adapt pylint settings in Makefile Files (added, modified or removed): * Makefile Remove obsolete second "import wx" Files (added, modified or removed): * misc.py 2011-12-30 Carsten Grohmann Move "Using wxPython " to main.py to eliminate "import wx" Files (added, modified or removed): * main.py * wxglade.py 2011-12-30 Davorin Kunstelj Adapt missed icon paths Files (added, modified or removed): * misc.py * res/preferences.wxg 2011-12-30 Carsten Grohmann Remove unused import and minor code elegancy changes Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/xrc_codegen.py * edit_sizers/edit_sizers.py * main.py * misc.py * tree.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/lisp_codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/button/button.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/choice/perl_codegen.py * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/gauge/gauge.py * widgets/list_box/perl_codegen.py * widgets/list_ctrl/list_ctrl.py * widgets/list_ctrl/perl_codegen.py * widgets/menubar/menubar.py * widgets/notebook/notebook.py * widgets/notebook/perl_codegen.py * widgets/slider/slider.py * widgets/spin_button/spin_button.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/lisp_codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/perl_codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/tree_ctrl.py 2011-12-29 Carsten Grohmann Adapt pylint settings in Makefile Files (added, modified or removed): * Makefile [FIX] Remove wasted wxButton_SetDefault statement The perl code sizer doesn't have this statement too. Thereby removed. Files (added, modified or removed): * widgets/bitmap_button/lisp_codegen.py Change some initial paths for documentation purposes only All effected path variables will be overwritten during initialisation. Files (added, modified or removed): * common.py 2011-12-28 Carsten Grohmann Add epydoc.conf to Windows installer exclude list Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss Clean all possible wxGlade MUICache entries always Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss Adapt missed icon path Files (added, modified or removed): * widgets/panel/panel.py Continue introducing path variables e.g. credits and license file This solves a bug preventing about dialog showing credits.txt and license.txt. The location of both files differs depending packaging method (Unix vs. Windows vs. running out of the devel directory). Files (added, modified or removed): * about.py * common.py * main.py * wxglade.py Minor reorg in determining wxGlade application directory Files (added, modified or removed): * wxglade.py 2011-12-27 Carsten Grohmann Add separate path variables for icons, docs, templates and widgets Files (added, modified or removed): * about.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * common.py * configUI.py * edit_sizers/edit_sizers.py * main.py * misc.py * template.py * tree.py * widgets/bitmap_button/codegen.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/menubar/menubar.py * widgets/panel/panel.py * widgets/static_bitmap/codegen.py * widgets/toolbar/codegen.py * widgets/toolbar/toolbar.py * wxglade.py [FIX] Typo in printing exception details Files (added, modified or removed): * codegen/pl_codegen.py 2011-12-26 Carsten Grohmann Update Trove Categorization Files (added, modified or removed): * setup.py Just an update of the Unix file permissions Files (added, modified or removed): * config.py * docs/html/design_window.png * docs/html/main_window.png * docs/html/preview_window.png * docs/html/properties_window.png * docs/html/tree_window.png * docs/src/design_window.png * docs/src/main_window.png * docs/src/manual.xml * docs/src/preview_window.png * docs/src/properties_window.png * docs/src/tree_window.png * edit_widget.py * msgdialog.py * templates_ui.py * wxglade.py * xrc2wxg.py Use only shell script wxglade to start wxGlade at Unix Files (added, modified or removed): * Makefile * setup.py Improve searching and executeing of wxglade.py in shell script wxglade Files (added, modified or removed): * wxglade Script has been replaced by setup.py in combination with Makefile Files (added, modified or removed): * install/srcpkgs/make_wxglade_release.py No need for separately callable configUI.py (preferences dialog) The preferences dialog is a menu item in the wxGlade GUI. Files (added, modified or removed): * Makefile * TODO.txt * configUI.py * setup.py Ignore files generated by Eric4 IDE too Files (added, modified or removed): * .hgignore Add maintainer-clean target to Makefile and extend BIN_FILES Files (added, modified or removed): * Makefile 2011-12-25 Carsten Grohmann Change package file names from wxglade-* to wxGlade-* Files (added, modified or removed): * setup.py Add source files of manpage and wxGlade manual to distribution Files (added, modified or removed): * setup.py 2011-12-24 Carsten Grohmann Extend Windows installer to clean MUICache registry entries There are some pages with more information about the MUI cache mechanisms: http://windowsir.blogspot.com/2005/12/mystery-of- muicachesolved.html http://forensicartifacts.com/2010/08/registry- muicache/ Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss Set version numbers back to HG to start new development cycle Files (added, modified or removed): * common.py * install/pyinstaller/wxglade-installer.iss 2011-12-20 Carsten Grohmann Added tag rel_0.6.4 for changeset d62eb65d431e Files (added, modified or removed): * .hgtags Bump version number to 0.6.4 Files (added, modified or removed): * common.py * install/pyinstaller/wxglade-installer.iss * install/pyinstaller/wxglade.spec Lot of documentation changes Files (added, modified or removed): * CHANGES.txt * README.txt * TODO.txt * changelog.style * docs/BuildingInstaller.txt * docs/ReleaseSteps.txt * install/README.txt [FIX] Algorithm to get the release tag checked the wrong changeset The release tag isn't located at tip it's located at the revision prior to the tip. Files (added, modified or removed): * common.py Added tag rel_0.5 for changeset 6a8223539dd8 Files (added, modified or removed): * .hgtags Removed tag v0.5 Files (added, modified or removed): * .hgtags 2011-12-12 Carsten Grohmann Add PHONY targets Files (added, modified or removed): * Makefile 2011-12-11 Carsten Grohmann Remove debian directory The debian directory is used to build debian packages. It will be maintainted by Debian / Ubuntu developers. Files (added, modified or removed): * debian/changelog * debian/compat * debian/control * debian/copyright * debian/dirs * debian/docs * debian/files * debian/manpage.xml * debian/menu * debian/rules * debian/wxglade.1 * install/pyinstaller/wxglade-installer.iss Move some import statements to earlier positions Files (added, modified or removed): * codegen/lisp_codegen.py * codegen/pl_codegen.py 2011-12-08 Carsten Grohmann Ignore more files Files (added, modified or removed): * .hgignore Add native Python build mechanism (setup.py) and integrate it into Makefile Files (added, modified or removed): * Makefile * setup.py 2011-11-25 Carsten Grohmann Improve start menu structure and exclude some unused docs Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss 2011-11-18 Carsten Grohmann Add PDF manual to Inno-Setup installer Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss Add manual PDF to support building on Windows without whole xml toolchain Files (added, modified or removed): * docs/pdf/manual.pdf * docs/pdf/readme.txt Integrate docs Makefile in main Makefile Files (added, modified or removed): * Makefile * docs/Makefile 2011-11-16 Carsten Grohmann Copy manpage to docs directory Files (added, modified or removed): * docs/man/manpage.xml Rework Makefile Files (added, modified or removed): * Makefile Add Makefile and setup.py to windows installer exclude list Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss 2011-11-11 Carsten Grohmann Cosmetic changes only Files (added, modified or removed): * wxglade.py Print version string at startup too Files (added, modified or removed): * wxglade.py 2011-11-10 Carsten Grohmann Ignore temporary files created during build process Files (added, modified or removed): * .hgignore Merge and unify installer scripts to reduce redundant code Files (added, modified or removed): * install/pyinstaller/wxglade-SAE-installer.iss * install/pyinstaller/wxglade-installer.iss Add License statement Files (added, modified or removed): * install/pyinstaller/hook-main.py * install/pyinstaller/wxglade.spec 2011-11-09 Carsten Grohmann Improve full edition installer Add show and agree license Create start menu entries for various documentation files Add conversion of some documentation files from Unix EOL to Windows EOL style Show README.txt after installation has been finished Files (added, modified or removed): * install/README.txt * install/pyinstaller/wxglade-installer.iss 2011-11-07 Carsten Grohmann Add label "(Standalone Edition)" to some links and menu entries Files (added, modified or removed): * install/pyinstaller/wxglade-SAE-installer.iss 2011-11-06 Carsten Grohmann [FIX] Error at "Launch wxGlade" at the end of installer Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss 2011-11-04 Carsten Grohmann Remove Python bytecode and empty app directory during deinstallation Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss 2011-10-31 Carsten Grohmann Ignore temporary directories created during build process Files (added, modified or removed): * .hgignore Whitespace changes only Files (added, modified or removed): * install/pyinstaller/wxglade-SAE-installer.iss Standard installer Files (added, modified or removed): * install/pyinstaller/wxglade-installer.iss Rework existing installer to use with standalone edition Files (added, modified or removed): * install/pyinstaller/make_installer_script.py * install/pyinstaller/wxglade-SAE-installer.iss * install/pyinstaller/wxglade-installer.iss.template Rework and improve spec file used by pyinstaller to collect all files Files (added, modified or removed): * install/pyinstaller/hook-main.py * install/pyinstaller/wxglade.spec 2011-10-30 Carsten Grohmann PEP8 and cosmetic code changes Files (added, modified or removed): * common.py Change common.version to show "(standalone edition)" for frozen installations Files (added, modified or removed): * common.py 2011-10-17 Carsten Grohmann Position of dispatch function has changes in new mercurial versions Files (added, modified or removed): * install/srcpkgs/make_wxglade_release.py Relocate RPM spec file Files (added, modified or removed): * install/rpm/wxglade.spec * wxglade.spec Merge support files from wxglade-dist-scripts repo Files (added, modified or removed): * install/README.txt * install/pyinstaller/make_installer_script.py * install/pyinstaller/mondrian.ico * install/pyinstaller/wxglade-installer.iss.template * install/pyinstaller/wxglade.spec * install/srcpkgs/make_wxglade_release.py * install/update-po.py Change location of source documentation from htmldocs to docs/apidocs Files (added, modified or removed): * .hgignore * epydoc.conf 2011-10-14 Carsten Grohmann Epydoc changes Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * font_dialog.py * widgets/notebook/notebook.py Make codegen to a package by adding __init__.py Files (added, modified or removed): * codegen/__init__.py 2011-10-12 Carsten Grohmann Epydoc changes Files (added, modified or removed): * codegen/py_codegen.py Epydoc changes Files (added, modified or removed): * common.py 2011-08-15 Carsten Grohmann Epydoc changes Files (added, modified or removed): * codegen/py_codegen.py * xml_parse.py Whitespace changes only Files (added, modified or removed): * edit_sizers/lisp_sizers_codegen.py 2011-08-14 Carsten Grohmann Some whitespace changes (e.g. remove tabs) only Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * edit_sizers/edit_sizers.py * widgets/bitmap_button/perl_codegen.py * widgets/button/perl_codegen.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/checkbox/lisp_codegen.py * widgets/checkbox/perl_codegen.py * widgets/choice/perl_codegen.py * widgets/combo_box/combo_box.py * widgets/combo_box/perl_codegen.py * widgets/custom_widget/perl_codegen.py * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/dialog/dialog.py * widgets/gauge/gauge.py * widgets/gauge/perl_codegen.py * widgets/grid/grid.py * widgets/grid/perl_codegen.py * widgets/list_box/perl_codegen.py * widgets/list_ctrl/perl_codegen.py * widgets/menubar/perl_codegen.py * widgets/panel/perl_codegen.py * widgets/radio_box/perl_codegen.py * widgets/radio_button/perl_codegen.py * widgets/slider/perl_codegen.py * widgets/spin_button/perl_codegen.py * widgets/spin_ctrl/perl_codegen.py * widgets/splitter_window/perl_codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/static_line/perl_codegen.py * widgets/static_text/perl_codegen.py * widgets/text_ctrl/perl_codegen.py * widgets/toggle_button/perl_codegen.py * widgets/toolbar/codegen.py * widgets/toolbar/perl_codegen.py * widgets/tree_ctrl/perl_codegen.py Do not use wxversion in frozen installations Files (added, modified or removed): * main.py 2011-08-08 Alberto Griggio Applied patch by Ramin Sabet to make generated Python code more PEP8-compliant Files (added, modified or removed): * codegen/py_codegen.py 2011-03-25 Alberto Griggio Fixed exception in edit_sizers.change_sizer (do not try to reparent things without a GetParent method) Thanks to Davorin Kunstelj for reporting the bug Files (added, modified or removed): * edit_sizers/edit_sizers.py 2010-08-27 Alberto Griggio Cleaned up multiple imports and added ComboBoxProperty tooltip. Patch provided by Davorin Kunstelj Files (added, modified or removed): * widget_properties.py 2010-06-29 Alberto Griggio The fix introduced in changeset 82b4f56b56c6 was actually broken. This one should be better Files (added, modified or removed): * application.py 2010-06-28 Alberto Griggio Fixed str/unicode mixing issue that was causing code generation to fail Files (added, modified or removed): * application.py 2010-01-05 Alberto Griggio added French translation by Guillaume Barthe Files (added, modified or removed): * po/fr.po 2010-01-02 Alberto Griggio generate code using the StringIO module instead of cStringIO, because the latter doesn't play nicely with Unicode Thanks to all the people who reported the bug and suggested patches Files (added, modified or removed): * xml_parse.py 2009-12-29 Alberto Griggio C++ output: applied patch by Sander Cox to prevent double line breaks to add up when no extra_code is present. Files (added, modified or removed): * codegen/cpp_codegen.py 2009-11-30 Alberto Griggio fix stupid bug in determining the version number using mercurial The code was catching only ImportError, but in fact there are more things that can go wrong. Fixed by catching everything Files (added, modified or removed): * common.py 2009-09-18 Alberto Griggio fix for issue #1962327 (extra code property allows only ASCII text) Files (added, modified or removed): * application.py applied patch by Roel van Os: "Change initialization order to improve tab order" Files (added, modified or removed): * codegen/py_codegen.py * edit_sizers/sizers_codegen.py 2009-08-25 Alberto Griggio applied patch by Johan Vromans to fix issue in Perl code generator Here's a quick summary of the issue: """ If a menu entry has a name that contains whitespace (or other non perl-identifier characters) wxglade generates invalid hash keys. """ Files (added, modified or removed): * codegen/pl_codegen.py * widgets/menubar/perl_codegen.py 2009-06-13 Alberto Griggio Applied patch by Davorin Kunstelj to allow properties to be "blocked" (locked down) when certain conditions are met Files (added, modified or removed): * edit_windows.py * tree.py * widget_properties.py * widgets/grid/grid.py 2009-05-13 Alberto Griggio Applied patch by Davorin Kunstelj to fix a tooltip mismatch on bitmap buttons Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py Applied patch by Davorin Kunstelj to not write disabled ComboBox properties I've changed the patch a little bit to be more compatible with the old behaviour Files (added, modified or removed): * widget_properties.py 2009-04-25 Alberto Griggio merged fixes to xrc2wxg Files (added, modified or removed): 2009-04-18 Alberto Griggio Use Mercurial to determine the version number of wxGlade, if possible Files (added, modified or removed): * common.py Code cleanup: removed unused imports Patch submitted by Carsten Grohmann Files (added, modified or removed): * about.py * application.py * clipboard.py * color_dialog.py * common.py * edit_sizers/edit_sizers.py * edit_widget.py * edit_windows.py * events_mixin.py * font_dialog.py * layout_option_property.py * main.py * tree.py * widget_properties.py * xml_parse.py Fixed an issue and updated some docstrings in the Python code generator Patch submitted by Carsten Grohmann Files (added, modified or removed): 2009-01-27 Alberto Griggio Fix: when importing from XRC, add a scrollable property to wx.ScrolledWindowS Files (added, modified or removed): * xrc2wxg.py 2009-01-25 Alberto Griggio fixed issue #2530409 (wxScrolledWindow could not be imported from XRC) Files (added, modified or removed): * xrc2wxg.py 2009-01-11 Alberto Griggio fix for bug #2498055 Files (added, modified or removed): * widgets/panel/codegen.py 2009-01-08 Alberto Griggio merge backout Files (added, modified or removed): * codegen/py_codegen.py Backed out changeset 3529b9200ebd Files (added, modified or removed): * codegen/py_codegen.py 2009-01-01 Alberto Griggio Moved language-specific properties of Application to separate tabs Files (added, modified or removed): * application.py Applied patch by Sander Cox to allow configuration of indentation for C++ output Files (added, modified or removed): * application.py * codegen/cpp_codegen.py * tree.py * xml_parse.py 2008-12-29 Alberto Griggio bugfix: in SpinProperty, display() was sometimes called before self.val was set Files (added, modified or removed): * widget_properties.py set common.version to 'HG' - version number is not meaningful anymore Files (added, modified or removed): * common.py bugfix: in RadioProperty, display() was sometimes called before self.val was set Files (added, modified or removed): * widget_properties.py 2008-12-26 Alberto Griggio Applied patch by Geoff May: added option to specify a custom constructor for CustomWidget Files (added, modified or removed): * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/custom_widget/perl_codegen.py 2008-11-29 Alberto Griggio merged changes from home Files (added, modified or removed): * codegen/py_codegen.py * common.py 2008-11-22 Alberto Griggio Fixed bug in common.generated_from() when code generation is invoked from the command line Files (added, modified or removed): * common.py Fixed bug in python App code generation, introduced by 'wxID_ANY' patch Files (added, modified or removed): * codegen/py_codegen.py Fixed a couple of code formatting issues (lines longer than 80 characters) Files (added, modified or removed): * widgets/custom_widget/custom_widget.py * widgets/panel/panel.py 2008-11-15 Alberto Griggio applied submitted patch to generate wx.ID_ANY instead of -1 in python code Files (added, modified or removed): * codegen/py_codegen.py 2008-10-23 Alberto Griggio applied patch by Roel van Os to fix MacOSX-related bugs Files (added, modified or removed): * layout_option_property.py * widget_properties.py 2008-10-21 Alberto Griggio fixed duplication of 'extra code' in C++ output Files (added, modified or removed): * codegen/cpp_codegen.py 2008-07-28 Alberto Griggio updated CHARSET for German and French translations Files (added, modified or removed): * po/de.po * po/fr.po 2008-07-25 Alberto Griggio avoid generation of if the list of choices is empty Files (added, modified or removed): * widgets/list_box/codegen.py 2008-04-24 Alberto Griggio applied patch by Doug Evans to fix "duplicate frame extracode" Files (added, modified or removed): * codegen/py_codegen.py 2008-03-11 Alberto Griggio fixed bug in GridSizer.set_cols the number of *rows* was used instead of that of columns... Files (added, modified or removed): * edit_sizers/edit_sizers.py 2008-02-14 Alberto Griggio fixed bug in preview when using CustomWidgets Files (added, modified or removed): * tree.py * widgets/custom_widget/codegen.py Applied patches by Johan Vromans to fix the Perl code generator for Custom Widgets Files (added, modified or removed): * widgets/custom_widget/lisp_codegen.py * widgets/custom_widget/perl_codegen.py 2008-02-01 Alberto Griggio Added tag rel_0.6.3 for changeset d58a6f9c593a Files (added, modified or removed): * .hgtags updated version number, some indentation changes to dialog.py Files (added, modified or removed): * common.py * widgets/dialog/dialog.py 2008-01-27 Alberto Griggio fixed bug #1876682 Files (added, modified or removed): * widgets/grid/codegen.py fixed indentation (only cosmetic change) Files (added, modified or removed): * widgets/grid/grid.py 2008-01-04 Alberto Griggio fixed silly bug in xrc code generation Files (added, modified or removed): * widgets/dialog/codegen.py * widgets/frame/codegen.py 2007-12-28 Alberto Griggio Added tag rel_0.6.2 for changeset 0ca2ea7b12e8 Files (added, modified or removed): * .hgtags updated version number to 0.6.2 Files (added, modified or removed): * common.py 2007-12-23 Alberto Griggio added "size hints" property to wxFrame and wxDialog Files (added, modified or removed): * application.py * edit_sizers/lisp_sizers_codegen.py * edit_sizers/perl_sizers_codegen.py * edit_sizers/sizers_codegen.py * widget_properties.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/codegen.py * widgets/frame/frame.py 2007-12-08 Alberto Griggio moved update-po.py to repository "wxglade-dist-scripts" Files (added, modified or removed): * update-po.py 2007-12-06 Alberto Griggio fix for Python <= 2.3, where no built-in "sorted" exists Files (added, modified or removed): * wxglade.py 2007-11-27 Alberto Griggio Merged i18n changes by Homin Lee Files (added, modified or removed): * common.py 2007-11-08 Homin Lee modifying... update-po.py Files (added, modified or removed): * update-po.py add update-po.py which based on mki18n.py from http://wiki.wxpython.org/Internationalization Files (added, modified or removed): * update-po.py add Japanese po from Japanese wxglade.mo Files (added, modified or removed): * po/ja.po 2007-11-08 Administrator add japanese mo, update scripts that unmanaged by gettext, add dispName to Property obj. for non-us users. Files (added, modified or removed): * about.py * application.py * code_property.py * common.py * config.py * edit_sizers/edit_sizers.py * edit_windows.py * events_mixin.py * font_dialog.py * kdefiledialog.py * layout_option_property.py * locale/ja/LC_MESSAGES/wxglade.mo * misc.py * template.py * templates_ui.py * tree.py * widget_properties.py * widgets/bitmap_button/bitmap_button.py * widgets/button/button.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/checkbox/checkbox.py * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/custom_widget/custom_widget.py * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/gauge/gauge.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/menubar.py * widgets/notebook/notebook.py * widgets/panel/panel.py * widgets/radio_box/radio_box.py * widgets/radio_button/radio_button.py * widgets/slider/slider.py * widgets/spacer/spacer.py * widgets/spin_button/spin_button.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/static_line.py * widgets/static_text/static_text.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/toggle_button.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/tree_ctrl.py * xml_parse.py 2007-11-08 Homin Lee update Korean translation Files (added, modified or removed): * po/ko.po 2007-11-27 Alberto Griggio merge Files (added, modified or removed): merged changes Files (added, modified or removed): 2007-11-17 Alberto Griggio merged rel 0.6.1 Files (added, modified or removed): fixed compilation problem when using non-standard empty arrays Files (added, modified or removed): * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/list_box/codegen.py 2007-11-27 Alberto Griggio fixed very serious regression on cpp_codegen, updated version number The problem was that old event handlers were not detected and declared/defined again at each code generation. This was because event handlers became virtual but I forgot to update the regexp that matches them to reflect this :-( Files (added, modified or removed): * codegen/cpp_codegen.py * common.py 2007-10-25 Alberto Griggio Added tag rel_0.6.1 for changeset 58d181f6df32 Files (added, modified or removed): * .hgtags changed version number to 0.6.1 Files (added, modified or removed): * common.py 2007-10-22 Alberto Griggio removed tabs from source code Files (added, modified or removed): * application.py * main.py * tree.py * widget_properties.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/button.py * widgets/button/button_stockitems.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/calendar_ctrl/codegen.py * widgets/combo_box/combo_box.py * widgets/datepicker_ctrl/codegen.py * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/dialog/dialog.py * xml_parse.py added korean translation Thanks to Homin Lee for providing this! Files (added, modified or removed): * po/ko.po 2007-10-18 Alberto Griggio patch to fix problem in code generated for wxMenuBar on OS X Files (added, modified or removed): * widgets/menubar/codegen.py * widgets/menubar/lisp_codegen.py * widgets/menubar/perl_codegen.py 2007-10-16 Alberto Griggio fixed bug in layout of frames with explicit size on wx < 2.8 Files (added, modified or removed): * widgets/frame/codegen.py * widgets/frame/perl_codegen.py fixed bug #180219 (changed std::cout to wxLogDebug) Files (added, modified or removed): * codegen/cpp_codegen.py fixed bug #1800898 (no refresh when changing foreground/backround color) Files (added, modified or removed): * widget_properties.py fixed bug #1800895 (exception when clicking "has toolbar") Files (added, modified or removed): * edit_windows.py fixed bug on python code generation Files (added, modified or removed): * widgets/calendar_ctrl/codegen.py 2007-09-23 Alberto Griggio Added tag rel_0.6 for changeset c4316ac0d906 Files (added, modified or removed): * .hgtags fixed tab ordering of properties Files (added, modified or removed): * application.py * edit_sizers/edit_sizers.py * edit_windows.py 2007-09-22 Alberto Griggio changed URL of user's manual (to use the on-line version) Files (added, modified or removed): * docs/index.html use wx.GenStaticText if available to implement labels wx.StaticText is a weird widget, with odd behaviour wrt. key and focus events. wx.GenStaticText is much better in this respect Files (added, modified or removed): * widgets/static_text/static_text.py 2007-09-19 Alberto Griggio fixed bug #1797230 Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py 2007-09-17 Alberto Griggio added option to include .wxg file name in generated source files This was requested by SPE's author, for better integration with the IDE Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * config.py * configUI.py * res/preferences.wxg 2007-09-09 Alberto Griggio added code generation preference "write_timestamp" Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * config.py * configUI.py * res/preferences.wxg fixed problems with "small_frames" on Ubuntu (actually, I think it's on GNOME...) Files (added, modified or removed): * main.py update the "saved" flag of Application when removing an empty slot Files (added, modified or removed): * edit_sizers/edit_sizers.py 2007-09-07 Alberto Griggio fixed cut-and-paste error (grr!!!) Files (added, modified or removed): * widgets/dialog/codegen.py * widgets/frame/codegen.py fixed code generation for "icon" property when using special "var:" and "code:" forms Files (added, modified or removed): * widgets/dialog/codegen.py * widgets/frame/codegen.py workaround for spinctrl bug on wxGTK 2.8.4.2 Files (added, modified or removed): * config.py fixed encoding problem with non-western locales Files (added, modified or removed): * xml_parse.py 2007-09-06 Alberto Griggio fixed compatibility with python 2.3 In python 2.3, set is not a builtin, but needs to be aliased from sets.Set Files (added, modified or removed): * tree.py fixed compatibility problem with wx 2.6 wx.ID_EDIT was introduced in 2.8... Files (added, modified or removed): * res/templates_ui.wxg * template.py * templates_ui.py fixed bug that made the tree and property windows disappear on win32 Files (added, modified or removed): * main.py small formatting fix Files (added, modified or removed): * wxglade.py 2007-09-04 Alberto Griggio fixed compatibility issue with wxPython 2.8.4.2 Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed bug in change_sizer when changing to a wx.StaticBoxSizer Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed bug in 'setup_preview_menu' when using wxPython 2.8.4.2 Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py 2007-09-02 Alberto Griggio improved support for custom components - made ChoicesProperty more general (for wxCheckListBox) - made edit_widget a bit more flexible Files (added, modified or removed): * edit_widget.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py 2007-09-01 Alberto Griggio fixed bug in event handler id generation Files (added, modified or removed): * codegen/py_codegen.py fixed a bug in handling extracode The extra code was not generated when the options "single file" and "overwrite" were set Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py fixed a bug in ExtraPropertiesProperty Files (added, modified or removed): * code_property.py Implemented "exraproperties" property. This allows you to add more properties to the generated code for the widgets. For each pair (name, value) in extraproperties for a widget, a line widget.SetName(value) will be added in __set_properties. That is, the name of the property is capitalized, and the value is taken as it is. This works for Python, C++ and Perl. For XRC, the extra line would be value (notice that there is no capitalization). Files (added, modified or removed): * code_property.py * codegen/cpp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * edit_windows.py * widget_properties.py small ui fix Files (added, modified or removed): * res/templates_ui.wxg * template.py * templates_ui.py make bold labels use the default font size Files (added, modified or removed): * msgdialog.py * res/messagedialog.wxg * res/templates_ui.wxg * templates_ui.py merged encoding fixes Files (added, modified or removed): * config.py * main.py * misc.py * tree.py fixed some encoding problems (when using non-ascii filesystem paths) Files (added, modified or removed): * config.py * kdefiledialog.py * main.py * misc.py * tree.py 2007-08-31 Alberto Griggio removed "generated from" in output file Files (added, modified or removed): * codegen/lisp_codegen.py removed "generated from" in output Files (added, modified or removed): * codegen/xrc_codegen.py implemented XRC code generation Files (added, modified or removed): * widgets/grid/codegen.py small ui improvement in CheckListProperty Files (added, modified or removed): * widget_properties.py small ui improvement Files (added, modified or removed): * code_property.py improved warning messages Files (added, modified or removed): * codegen/py_codegen.py implemented "extracode" and "custom base classes" for C++ output Files (added, modified or removed): * codegen/cpp_codegen.py added a couple of fixes for "extracode" Files (added, modified or removed): * codegen/py_codegen.py fixed bug when not overwriting existing sources Files (added, modified or removed): * codegen/py_codegen.py better implementation of check_codegen for XRC Files (added, modified or removed): * application.py added "custom base classes" support It is now possible to specify custom base classes for wxGlade- generated ones. At the moment, it works only for the Python code generator, but I plan to implement it also for C++. This feature is not really meant to be used unless the "overwrite existing sources" option is set: if not, the generated code might be incorrect. Files (added, modified or removed): * codegen/py_codegen.py * codegen/xrc_codegen.py * edit_windows.py * widgets/notebook/notebook.py * widgets/panel/panel.py * widgets/splitter_window/splitter_window.py implemented 'extracode' property for XRC Files (added, modified or removed): * codegen/xrc_codegen.py fixed a couple of UI glitches Files (added, modified or removed): * code_property.py * main.py 2007-08-30 Alberto Griggio Added "extracode" property This property allows the user to insert arbitrary code snippets in the wxGlade-generated source files. This could be quite useful, for instance to include files, define constants, etc. At the moment, only the Python code generator has been updated to support this. I plan to extend also the C++ one, for the others patches are welcome... Finally, you should use this feature only in "overwrite sources" mode: if you don't, it should work for "easy" cases (when you really insert only imports or constant declarations), but if you insert more complex stuff the wxGlade "parsers" (quoted because they aren't real parsers) will get fooled quite easily... Files (added, modified or removed): * code_property.py * codegen/py_codegen.py * edit_windows.py small fix in displaying template information Files (added, modified or removed): * template.py 2007-08-29 Alberto Griggio moved "import template" at the top level Files (added, modified or removed): * main.py implemented template editing Files (added, modified or removed): * main.py * res/templates_ui.wxg * template.py * templates_ui.py added first template management code For now, it is only possible to delete custom (i.e. not bundled with wxGlade) templates Files (added, modified or removed): * main.py * template.py A very simple example template Files (added, modified or removed): * templates/Dialog with two buttons.wgt improved templates support Added dialogs and menu entries to create an app from a template, or to save an app as a template Still needs to be finished (e.g. editing/deleting existing templates is not possible at the moment) Files (added, modified or removed): * main.py * res/templates_ui.wxg * template.py * templates_ui.py * tree.py improved message dialog Files (added, modified or removed): * msgdialog.py * res/messagedialog.wxg fixed line-wrapping Files (added, modified or removed): * template.py better handling of relative paths for images There was a problem in wxGlade: relative paths for icons (for example in toolbars or frames) were accepted by the code generator, but were not working well in the gui design and in preview. This patch fixes the problem, by interpreting paths for images as relative to the output path for the generated code Files (added, modified or removed): * application.py * misc.py * msgdialog.py * res/messagedialog.wxg * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/toolbar/codegen.py * widgets/toolbar/toolbar.py 2007-08-28 Alberto Griggio updated .hgignore Files (added, modified or removed): * .hgignore better implementation of common.message, using a custom MessageDialog Files (added, modified or removed): * common.py * config.py * msgdialog.py * res/messagedialog.wxg remember position of top-level windows when reloading an app Files (added, modified or removed): * main.py * tree.py fixed wrong commit Files (added, modified or removed): * codegen/pl_codegen.py added notification of missing code generators Every time a widget is added to the current design, or the output language is changed, check that every widget has a suitable code generator for the language, and if not warn the user Files (added, modified or removed): * application.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * common.py * main.py * tree.py 2007-08-26 Alberto Griggio applied patch to make event handlers virtual Files (added, modified or removed): * codegen/cpp_codegen.py 2007-08-22 Alberto Griggio fixed small bug in selection markers Files (added, modified or removed): * misc.py 2007-08-11 Alberto Griggio upadted version number to 0.6 Files (added, modified or removed): * common.py 2007-08-07 Alberto Griggio Closed HEAD branch Files (added, modified or removed): Removed obsolete files Files (added, modified or removed): * zmain.py * zwxglade.py merge after tagging v0.5 Files (added, modified or removed): * .cvsignore * codegen/.cvsignore * docs/.cvsignore * docs/img/.cvsignore * edit_sizers/.cvsignore * icons/.cvsignore * icons/gtk/.cvsignore * icons/msw/.cvsignore * widgets/.cvsignore * widgets/bitmap_button/.cvsignore * widgets/button/.cvsignore * widgets/calendar_ctrl/.cvsignore * widgets/checkbox/.cvsignore * widgets/choice/.cvsignore * widgets/combo_box/.cvsignore * widgets/custom_widget/.cvsignore * widgets/datepicker_ctrl/.cvsignore * widgets/dialog/.cvsignore * widgets/frame/.cvsignore * widgets/gauge/.cvsignore * widgets/grid/.cvsignore * widgets/list_box/.cvsignore * widgets/list_ctrl/.cvsignore * widgets/menubar/.cvsignore * widgets/notebook/.cvsignore * widgets/panel/.cvsignore * widgets/radio_box/.cvsignore * widgets/radio_button/.cvsignore * widgets/slider/.cvsignore * widgets/spacer/.cvsignore * widgets/spin_button/.cvsignore * widgets/spin_ctrl/.cvsignore * widgets/splitter_window/.cvsignore * widgets/static_bitmap/.cvsignore * widgets/static_line/.cvsignore * widgets/static_text/.cvsignore * widgets/text_ctrl/.cvsignore * widgets/toggle_button/.cvsignore * widgets/toolbar/.cvsignore * widgets/tree_ctrl/.cvsignore * zmain.py * zwxglade.py Added tag v0.5 for changeset 6a8223539dd8 Files (added, modified or removed): * .hgtags Removed obsolete files Files (added, modified or removed): * zmain.py * zwxglade.py Added .hgignore Files (added, modified or removed): * .hgignore Removed .cvsignore files Files (added, modified or removed): * .cvsignore * codegen/.cvsignore * docs/.cvsignore * docs/img/.cvsignore * edit_sizers/.cvsignore * icons/.cvsignore * icons/gtk/.cvsignore * icons/msw/.cvsignore * widgets/.cvsignore * widgets/bitmap_button/.cvsignore * widgets/button/.cvsignore * widgets/calendar_ctrl/.cvsignore * widgets/checkbox/.cvsignore * widgets/choice/.cvsignore * widgets/combo_box/.cvsignore * widgets/custom_widget/.cvsignore * widgets/datepicker_ctrl/.cvsignore * widgets/dialog/.cvsignore * widgets/frame/.cvsignore * widgets/gauge/.cvsignore * widgets/grid/.cvsignore * widgets/list_box/.cvsignore * widgets/list_ctrl/.cvsignore * widgets/menubar/.cvsignore * widgets/notebook/.cvsignore * widgets/panel/.cvsignore * widgets/radio_box/.cvsignore * widgets/radio_button/.cvsignore * widgets/slider/.cvsignore * widgets/spacer/.cvsignore * widgets/spin_button/.cvsignore * widgets/spin_ctrl/.cvsignore * widgets/splitter_window/.cvsignore * widgets/static_bitmap/.cvsignore * widgets/static_line/.cvsignore * widgets/static_text/.cvsignore * widgets/text_ctrl/.cvsignore * widgets/toggle_button/.cvsignore * widgets/toolbar/.cvsignore * widgets/tree_ctrl/.cvsignore Some code cleanup Files (added, modified or removed): * codegen/pl_codegen.py Several "visual" and usability improvements, like better icons, better keyboard navigation, better preview support Files (added, modified or removed): * common.py * configUI.py * edit_sizers/edit_sizers.py * edit_windows.py * font_dialog.py * layout_option_property.py * main.py * misc.py * widget_properties.py Some code cleanup Files (added, modified or removed): * widgets/bitmap_button/codegen.py * widgets/calendar_ctrl/codegen.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/gauge/gauge.py * widgets/menubar/menubar.py * widgets/slider/slider.py * widgets/spacer/spacer.py * widgets/static_line/static_line.py * widgets/toolbar/toolbar.py * wxglade.py Improved multiple files code generation. Now it is possible to generate classes living in subpackages Files (added, modified or removed): * codegen/py_codegen.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/notebook/perl_codegen.py * widgets/panel/codegen.py * widgets/panel/lisp_codegen.py * widgets/panel/panel.py * widgets/panel/perl_codegen.py * widgets/splitter_window/codegen.py * widgets/splitter_window/perl_codegen.py * widgets/splitter_window/splitter_window.py Better preview support for "cross-referencing" custom widgets. Example: suppose you have a panel called MyPanel, and a frame with a custom widget called MyPanel. Then wxGlade detects that the custom widget is actually a MyPanel instance created before, and will correctly use that in the preview Files (added, modified or removed): * application.py * tree.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * xml_parse.py 2007-07-21 Alberto Griggio Set the busy cursor before pasting (since it can take some time...) Files (added, modified or removed): * clipboard.py fixed a segfault when adding a sizer to a panel after having removed the previous one Files (added, modified or removed): * edit_sizers/edit_sizers.py * widgets/panel/panel.py 2007-06-25 Alberto Griggio minor changes to keep lines shorter than 80 characters... Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed bug in change_sizer Files (added, modified or removed): * edit_sizers/edit_sizers.py 2007-06-23 Alberto Griggio applied patch by Klaas Hartmann Files (added, modified or removed): * widgets/menubar/perl_codegen.py 2007-05-02 dinogen added a spacer because last entry are not well readable Files (added, modified or removed): * configUI.py 2007-04-19 Alberto Griggio SelectionTags are created and destroyed every time they are shown/hidden: this helps slowing down the rate at which GDI objects usage increases over time (note: this is not a real fix for the problem, I don't know enough about win32 gui to do it...) Files (added, modified or removed): * misc.py 2007-04-14 Alberto Griggio fixed bug when deleting a page of a notebook Files (added, modified or removed): * edit_windows.py * widgets/notebook/notebook.py 2007-04-12 guyru fixed some bugs Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py 2007-04-10 guyru fixed cpp codegen Files (added, modified or removed): * widgets/bitmap_button/codegen.py added styles to bitmap button widget. Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py 2007-04-04 Alberto Griggio changed version number Files (added, modified or removed): * common.py minor UI and code tweaks Files (added, modified or removed): * edit_sizers/edit_sizers.py * widget_properties.py 2007-04-02 Alberto Griggio updated credits Files (added, modified or removed): * credits.txt updated change log Files (added, modified or removed): * CHANGES.txt updated "for_version" property Files (added, modified or removed): * application.py changed version number Files (added, modified or removed): * common.py 2007-04-01 Alberto Griggio added XRC code generation for stock items Files (added, modified or removed): * widgets/button/codegen.py fixed code generation for stock items Files (added, modified or removed): * widgets/button/codegen.py * widgets/button/lisp_codegen.py * widgets/button/perl_codegen.py 2007-03-31 Alberto Griggio fixed set_stockitem Files (added, modified or removed): * widgets/button/button.py small code formatting change Files (added, modified or removed): * widget_properties.py 2007-03-30 Alberto Griggio applied some "cosmetic" patches Files (added, modified or removed): * codegen/cpp_codegen.py 2007-03-28 Alberto Griggio fixed segfault with wx 2.8 Files (added, modified or removed): * widgets/radio_box/radio_box.py removed deprecated wx.SystemSettings_GetSystemFont Files (added, modified or removed): * misc.py 2007-03-27 Alberto Griggio fixed raise_all Files (added, modified or removed): * main.py updated copyright notice Files (added, modified or removed): * README.txt * __init__.py * about.py * application.py * clipboard.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * edit_windows.py * kdefiledialog.py * layout_option_property.py * main.py * misc.py * template.py * tree.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/__init__.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/calendar_ctrl/__init__.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/calendar_ctrl/codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/custom_widget/__init__.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/datepicker_ctrl/__init__.py * widgets/datepicker_ctrl/codegen.py * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/frame/lisp_codegen.py * widgets/frame/perl_codegen.py * widgets/gauge/__init__.py * widgets/gauge/codegen.py * widgets/gauge/gauge.py * widgets/grid/__init__.py * widgets/grid/codegen.py * widgets/grid/grid.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/list_ctrl/__init__.py * widgets/list_ctrl/codegen.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/__init__.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_button/__init__.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/lisp_codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * widgets/toolbar/__init__.py * widgets/toolbar/codegen.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/__init__.py * widgets/tree_ctrl/codegen.py * widgets/tree_ctrl/tree_ctrl.py * wxglade.py * xml_parse.py * xrc2wxg.py Added patch by Johan Vromans to support stock buttons Files (added, modified or removed): * widget_properties.py * widgets/button/button.py * widgets/button/button_stockitems.py * widgets/button/codegen.py * widgets/button/lisp_codegen.py * widgets/button/perl_codegen.py fix for default path of DirDialog Files (added, modified or removed): * application.py * common.py * configUI.py * kdefiledialog.py 2007-03-26 Alberto Griggio a couple of minor fixes... Files (added, modified or removed): * widget_properties.py * widgets/list_box/list_box.py fixed SpinProperty crash with new wx 2.8 Files (added, modified or removed): * widget_properties.py updated indentation style Files (added, modified or removed): * widgets/combo_box/combo_box.py fix for hang using wxPython 2.8.1.1 on Ubuntu Files (added, modified or removed): * widgets/panel/panel.py fixed raise_all bug Files (added, modified or removed): * main.py 2007-03-19 Alberto Griggio applied patch to add a "Raise All" menu item Files (added, modified or removed): * main.py applied patch to fix submenu generation problem... Files (added, modified or removed): * widgets/menubar/perl_codegen.py small reformatting changes... Files (added, modified or removed): * main.py small change to the encoding line Files (added, modified or removed): * codegen/py_codegen.py 2007-03-18 guyru replaced tabs with regular spaces Files (added, modified or removed): * template.py 2007-03-09 Alberto Griggio changed range of "sash pos" property to allow negative values Files (added, modified or removed): * widgets/splitter_window/splitter_window.py Applied patch for event handlers Files (added, modified or removed): * codegen/pl_codegen.py 2007-03-01 Alberto Griggio changed wxversion.select("2.6") to wxversion.ensureMinimal("2.6"), fixed mixed tabs/spaces problem Files (added, modified or removed): * main.py 2007-02-13 guyru fixed header tag Files (added, modified or removed): * template.py some exception handling Files (added, modified or removed): * xml_parse.py template info reading Files (added, modified or removed): * main.py * template.py 2007-02-09 dinogen i18n completed. Now translations. Files (added, modified or removed): * po/de.po * po/fr.po i18n completed. Now translations. Files (added, modified or removed): * credits.txt * po/messages.pot * widgets/gauge/gauge.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/menubar.py * widgets/notebook/notebook.py * widgets/radio_button/radio_button.py * widgets/slider/slider.py * widgets/spacer/lisp_codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/text_ctrl.py * widgets/tree_ctrl/tree_ctrl.py 2007-02-04 Alberto Griggio updated credits Files (added, modified or removed): * credits.txt updated copyright notice Files (added, modified or removed): * license.txt fixed small bug that prevented displaying help Files (added, modified or removed): * main.py fixed bug that prevented changing from FlexGridSizer to GridSizer Files (added, modified or removed): * edit_sizers/edit_sizers.py 2007-01-31 dinogen correct fallback bug Files (added, modified or removed): * misc.py * tree.py * widget_properties.py * widgets/bitmap_button/bitmap_button.py * wxglade.py * xml_parse.py * zmain.py 2007-01-31 guyru set the default value of is_template to false Files (added, modified or removed): * application.py self credit :) Files (added, modified or removed): * credits.txt template handling Files (added, modified or removed): * main.py * tree.py * xml_parse.py removed extra ) in line 70 Files (added, modified or removed): * kdefiledialog.py fixed issue regarding starting up without an Italian locale. Files (added, modified or removed): * locale/en/LC_MESSAGES/wxglade.mo * po/en.po 2007-01-29 dinogen i18n Files (added, modified or removed): * edit_widget.py * edit_windows.py * events_mixin.py * font_dialog.py * kdefiledialog.py * layout_option_property.py * main.py 2007-01-27 dinogen preference dialog iternationalizated Files (added, modified or removed): * color_dialog.py * edit_sizers/edit_sizers.py * locale/it/LC_MESSAGES/wxglade.mo * po/it.po stupid bug Files (added, modified or removed): * clipboard.py locales added Files (added, modified or removed): * about.py * clipboard.py * color_dialog.py * common.py * config.py * configUI.py * locale/it/LC_MESSAGES/wxglade.mo * po/it.po * po/messages.pot * wxglade.py 2007-01-26 dinogen pp Files (added, modified or removed): * edit_sizers/edit_sizers.py * po/messages.po * po/messages.pot 2007-01-19 dinogen add i18n Files (added, modified or removed): * po/messages.po 2007-01-18 dinogen begin of localization Files (added, modified or removed): * clipboard.py * color_dialog.py * common.py * config.py * configUI.py * wxglade.py 2006-12-07 Alberto Griggio changed the UI of "use_new_namespace". Now the meaning is the opposite: if checked, the old "from wxPython.wx import *" mechanism will be used (unchecked by default) Files (added, modified or removed): * application.py * tree.py * xml_parse.py 2006-12-04 jkt conform to wxPython 2.7 Files (added, modified or removed): * main.py 2006-12-02 guyru added new styles and tooltips Files (added, modified or removed): * widgets/slider/slider.py *** empty log message *** Files (added, modified or removed): * widgets/radio_button/radio_button.py 2006-12-02 jkt autokudos Files (added, modified or removed): * credits.txt 2006-12-02 Alberto Griggio Better layout code generation, following Robin Dunn's comments appearing here: http://lists.wxwidgets.org/cgi-bin/ezmlm- cgi?11:mss:50516:200604:ckdkhmebfbadhedacofn Files (added, modified or removed): * edit_sizers/lisp_sizers_codegen.py * edit_sizers/perl_sizers_codegen.py * edit_sizers/sizers_codegen.py Transition to the new wx namespace completed (hopefully) Files (added, modified or removed): * application.py * common.py * configUI.py * edit_sizers/edit_sizers.py * edit_windows.py * events_mixin.py * font_dialog.py * layout_option_property.py * main.py * misc.py * tree.py * widget_properties.py * widgets/button/button.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/checkbox/checkbox.py * widgets/combo_box/combo_box.py * widgets/custom_widget/custom_widget.py * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/grid/grid.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/menubar.py * widgets/radio_box/radio_box.py * widgets/radio_button/radio_button.py * widgets/static_line/static_line.py * widgets/toolbar/toolbar.py * widgets/widgets.txt * xml_parse.py 2006-11-30 jkt add "from " to headers of generated code with compliments to Stani of SPE fame who suggested this in http://sourceforge.net/ma ilarchive/forum.php?thread_id=31139957&forum_id=10344 Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py 2006-11-23 dinogen wx module Files (added, modified or removed): * edit_widget.py * edit_windows.py Error on show_prop. Files (added, modified or removed): * application.py 2006-11-22 dinogen wx module Files (added, modified or removed): * config.py wx module Files (added, modified or removed): * application.py 2006-11-22 guyru added tooltips Files (added, modified or removed): * widgets/gauge/gauge.py * widgets/list_box/list_box.py * widgets/list_ctrl/list_ctrl.py tooltips Files (added, modified or removed): * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/dialog/dialog.py 2006-11-21 dinogen wx module Files (added, modified or removed): * clipboard.py * color_dialog.py 2006-11-20 dinogen new module wx Files (added, modified or removed): * application.py wxPython to wx module Files (added, modified or removed): * about.py 2006-11-20 guyru added tooltips and updated style labels Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py added tooltips and one more style Files (added, modified or removed): * widgets/combo_box/combo_box.py 2006-11-19 guyru added tooltips for the checkbox properties. also added one more style: wxNO_BORDER which creates flat buttons. Files (added, modified or removed): * widgets/button/button.py added tooltips for the checkbox properties Files (added, modified or removed): * widget_properties.py 2006-11-16 guyru moved to the wxPython namespace Files (added, modified or removed): * widgets/checkbox/checkbox.py * widgets/radio_button/radio_button.py moved to the wxPython namespace Files (added, modified or removed): * widgets/radio_box/radio_box.py moved to the wxPython namespace Files (added, modified or removed): * widgets/static_bitmap/static_bitmap.py * widgets/static_line/static_line.py moved to the wxPython namespace Files (added, modified or removed): * widgets/list_ctrl/list_ctrl.py moved to the wxPython namespace Files (added, modified or removed): * widgets/tree_ctrl/tree_ctrl.py moved to the wxPython namespace Files (added, modified or removed): * widgets/grid/grid.py moved to the wxPython namespace Files (added, modified or removed): * widgets/custom_widget/custom_widget.py * widgets/spacer/spacer.py moved to the wxPython namespace Files (added, modified or removed): * widgets/menubar/menubar.py 2006-11-15 guyru moved to the wxPython namespace Files (added, modified or removed): * widgets/toolbar/toolbar.py moved to the wxPython namespace Files (added, modified or removed): * widgets/datepicker_ctrl/datepicker_ctrl.py 2006-11-14 jkt convert from "import wxPython*" to "import wx" as wxPython namespace is deprecated as of 2.7.1.1 Files (added, modified or removed): * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/list_box/list_box.py 2006-11-11 guyru moved to the new syntax Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py 2006-11-07 jkt convert from "import wxPython*" to "import wx" as wxPython namespace is deprecated as of 2.7.1.1 Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py * widgets/button/button.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/gauge/gauge.py * widgets/notebook/notebook.py * widgets/panel/panel.py * widgets/slider/slider.py * widgets/spin_button/spin_button.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/splitter_window.py * widgets/static_text/static_text.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/toggle_button.py 2006-11-02 guyru moved most of the code to the new syntax, but still some old syntax remains, although the module shouldn't have any problems Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py 2006-10-29 Alberto Griggio reoreded list to keep spacer at the end Files (added, modified or removed): * widgets/widgets.txt better icons Files (added, modified or removed): * icons/calendar_ctrl.xpm * icons/datepicker_ctrl.xpm 2006-10-20 guyru wxDatePickerCtrl support Files (added, modified or removed): * icons/datepicker_ctrl.xpm * widgets/datepicker_ctrl/.cvsignore * widgets/datepicker_ctrl/__init__.py * widgets/datepicker_ctrl/codegen.py * widgets/datepicker_ctrl/datepicker_ctrl.py * widgets/widgets.txt fixed c++ code generation. missed wxDefaultDate Files (added, modified or removed): * widgets/calendar_ctrl/codegen.py various bug fixes, removed extra debugging code, fixed python code generation Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py * widgets/calendar_ctrl/codegen.py 2006-10-19 guyru *** empty log message *** Files (added, modified or removed): * widgets/calendar_ctrl/codegen.py bugfixes Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py * widgets/calendar_ctrl/codegen.py 2006-10-18 guyru a small fix to the xml_builder Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py 2006-10-15 guyru new icon Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py icon for wxCalendarCtrl Files (added, modified or removed): * icons/calendar_ctrl.xpm fixed some bugs Files (added, modified or removed): * widgets/calendar_ctrl/calendar_ctrl.py 2006-10-14 guyru initial revision for calendar_ctrl. still has some bugs in the codegen Files (added, modified or removed): * widgets/calendar_ctrl/.cvsignore * widgets/calendar_ctrl/__init__.py * widgets/calendar_ctrl/calendar_ctrl.py * widgets/calendar_ctrl/codegen.py added calendar_ctrl Files (added, modified or removed): * widgets/widgets.txt configuration file for the epydoc documentation generator Files (added, modified or removed): * epydoc.conf 2006-10-12 Alberto Griggio patch for feature request #1228246 Files (added, modified or removed): * codegen/cpp_codegen.py 2006-10-11 Alberto Griggio fixed a size bug on win xp Files (added, modified or removed): * widgets/choice/choice.py * widgets/combo_box/combo_box.py 2006-10-07 Alberto Griggio fixed some bugs Files (added, modified or removed): * main.py * widgets/menubar/codegen.py * widgets/slider/codegen.py 2006-07-02 Alberto Griggio Added event handler stubs code generation for C++ output Files (added, modified or removed): * widgets/menubar/codegen.py * widgets/toolbar/codegen.py 2006-05-16 Alberto Griggio fixed segfault and wxGridSizer removal problem Files (added, modified or removed): * edit_sizers/edit_sizers.py 2006-05-13 Alberto Griggio updated version number Files (added, modified or removed): * common.py fixed possible segfault Files (added, modified or removed): * widget_properties.py 2006-05-07 Alberto Griggio added apply button to the menu editor Files (added, modified or removed): * widgets/menubar/menubar.py added apply button to the toolbar editor Files (added, modified or removed): * widgets/toolbar/toolbar.py fixed small bug Files (added, modified or removed): * tree.py 2006-05-06 Alberto Griggio some bugs fixed Files (added, modified or removed): * application.py * codegen/xrc_codegen.py * tree.py fixed "change class" bug Files (added, modified or removed): * edit_sizers/edit_sizers.py 2006-05-02 Alberto Griggio Fixed bug when both "separate file for each class" and "overwrite existing sources" were used Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py fixed "select top window" bug Files (added, modified or removed): * application.py 2006-03-13 Alberto Griggio added wxversion select of wx2.6 Files (added, modified or removed): * main.py applied patch #1447669 Files (added, modified or removed): * widgets/custom_widget/custom_widget.py applied patch #1447674 Files (added, modified or removed): * edit_windows.py 2006-03-02 Alberto Griggio added line of release of v0.4.1 Files (added, modified or removed): * CHANGES.txt updated version number Files (added, modified or removed): * common.py 2006-02-21 georgesk fixed the changelog Files (added, modified or removed): * debian/changelog adjusted the version number for the debian package Files (added, modified or removed): * debian/changelog 2006-02-12 Alberto Griggio fixed multiple generation of event stubs Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/lisp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py 2006-01-31 georgesk fixed a lot of bugs reported by debian users, see debian/Changelog Files (added, modified or removed): * debian/changelog * debian/menu * wxglade 2006-01-17 Alberto Griggio commented out debug print statement Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed crash on windows (caused by spin properties losing focus...) Files (added, modified or removed): * widget_properties.py 2005-12-28 Alberto Griggio added option to prevent generating code for the custom class Files (added, modified or removed): * widgets/panel/panel.py added "sizerslot", i.e. keep empty slots when saving a project... Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py * tree.py * widget_properties.py * xml_parse.py 2005-12-23 Alberto Griggio fixed invalid SetSelection code generation Files (added, modified or removed): * widgets/choice/codegen.py * widgets/combo_box/codegen.py 2005-11-20 Alberto Griggio added option (to wxPanel) to disable code generation for custom classes Files (added, modified or removed): * tree.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/panel/perl_codegen.py * xml_parse.py 2005-10-27 georgesk fixed one bug about the deletion of .xvpics upon building the debian package Files (added, modified or removed): * Makefile * debian/files 2005-10-14 crazyinsomniac fixup wxGlade tag order for events Files (added, modified or removed): * codegen/pl_codegen.py import MenuHandler instead of inlining Files (added, modified or removed): * widgets/menubar/perl_codegen.py import MenuHandler instead of inlining Files (added, modified or removed): * widgets/menubar/perl_codegen.py notebooksizer for_version Files (added, modified or removed): * codegen/pl_codegen.py discovered by 1255968 (wxFoo Wx::Foo) Files (added, modified or removed): * widgets/static_bitmap/perl_codegen.py 2005-10-14 Alberto Griggio bugs fixed/added event handling support for perl output Files (added, modified or removed): * application.py * codegen/cpp_codegen.py * codegen/pl_codegen.py * widgets/menubar/perl_codegen.py 2005-10-13 dinogen Fixed bug 1289473. Show Properties of widget under a wxNotebook. Files (added, modified or removed): * edit_windows.py 2005-10-08 Alberto Griggio some patches... Files (added, modified or removed): * CHANGES.txt * application.py * codegen/pl_codegen.py * common.py 2005-09-29 efuzzyone The name for events, widgets, classes, etc., now should allow hyphen(-). This change was necessitated due to lisp, which has a convention of allowing hyphen in names. Files (added, modified or removed): * application.py * edit_windows.py * events_mixin.py 2005-09-27 efuzzyone Replace _ by - in variable names. Files (added, modified or removed): * widgets/notebook/lisp_codegen.py Fixed wxEvtHandlerConnect to wxEvtHandler_Connect. Files (added, modified or removed): * codegen/lisp_codegen.py 2005-09-25 efuzzyone Made several code improvements. Files (added, modified or removed): * widgets/frame/lisp_codegen.py * widgets/menubar/lisp_codegen.py * widgets/toolbar/lisp_codegen.py Made several improvements, also wrapped the program initialization code with unwind-protect. Files (added, modified or removed): * codegen/lisp_codegen.py 2005-09-22 efuzzyone Initial Revision for generating lisp code. Files (added, modified or removed): * widgets/checkbox/lisp_codegen.py * widgets/choice/lisp_codegen.py * widgets/combo_box/lisp_codegen.py * widgets/custom_widget/lisp_codegen.py * widgets/dialog/lisp_codegen.py * widgets/frame/lisp_codegen.py * widgets/gauge/lisp_codegen.py * widgets/grid/lisp_codegen.py * widgets/list_box/lisp_codegen.py * widgets/list_ctrl/lisp_codegen.py * widgets/menubar/lisp_codegen.py * widgets/notebook/lisp_codegen.py * widgets/panel/lisp_codegen.py * widgets/radio_box/lisp_codegen.py * widgets/radio_button/lisp_codegen.py * widgets/slider/lisp_codegen.py * widgets/spacer/lisp_codegen.py * widgets/spin_button/lisp_codegen.py * widgets/spin_ctrl/lisp_codegen.py * widgets/splitter_window/lisp_codegen.py Initial revision. Files (added, modified or removed): * widgets/static_bitmap/lisp_codegen.py * widgets/static_line/lisp_codegen.py Initial revision. Files (added, modified or removed): * codegen/lisp_codegen.py * edit_sizers/lisp_sizers_codegen.py * widgets/bitmap_button/lisp_codegen.py * widgets/button/lisp_codegen.py * widgets/static_text/lisp_codegen.py * widgets/text_ctrl/lisp_codegen.py * widgets/toggle_button/lisp_codegen.py * widgets/toolbar/lisp_codegen.py * widgets/tree_ctrl/lisp_codegen.py 2005-08-25 Alberto Griggio fixed small bug Files (added, modified or removed): * codegen/pl_codegen.py 2005-08-24 georgesk imported modifications made by Matthias Klose Files (added, modified or removed): * Makefile * debian/changelog * debian/control * debian/postinst * debian/rules * wxglade 2005-08-23 Alberto Griggio small bug fixed Files (added, modified or removed): * widgets/frame/frame.py * widgets/splitter_window/splitter_window.py 2005-08-23 georgesk updated the dependancies Files (added, modified or removed): * debian/changelog updated the dependancies Files (added, modified or removed): * debian/changelog * debian/control * debian/files 2005-08-15 crazyinsomniac discovered by 1255968 (wxFoo Wx::Foo) Files (added, modified or removed): * widgets/toolbar/perl_codegen.py * widgets/tree_ctrl/perl_codegen.py discovered by 1255968 (wxFoo Wx::Foo) Files (added, modified or removed): * widgets/toggle_button/perl_codegen.py discovered by 1255968 (wxFoo Wx::Foo) Files (added, modified or removed): * widgets/bitmap_button/perl_codegen.py * widgets/button/perl_codegen.py * widgets/checkbox/perl_codegen.py * widgets/choice/perl_codegen.py * widgets/combo_box/perl_codegen.py * widgets/gauge/perl_codegen.py * widgets/grid/perl_codegen.py * widgets/list_box/perl_codegen.py * widgets/list_ctrl/perl_codegen.py * widgets/menubar/perl_codegen.py * widgets/panel/perl_codegen.py * widgets/radio_box/perl_codegen.py * widgets/radio_button/perl_codegen.py * widgets/slider/perl_codegen.py * widgets/spin_button/perl_codegen.py * widgets/spin_ctrl/perl_codegen.py * widgets/splitter_window/perl_codegen.py * widgets/static_line/perl_codegen.py * widgets/static_text/perl_codegen.py * widgets/text_ctrl/perl_codegen.py bug related to 1255968 (1255968 fixed long ago) Files (added, modified or removed): * widgets/notebook/perl_codegen.py s/mkdir/makedirs/ -- pending bug 1255256 Files (added, modified or removed): * codegen/pl_codegen.py 2005-08-06 Alberto Griggio added to please spe... Files (added, modified or removed): * widgets/__init__.py 2005-08-01 Alberto Griggio fixed bug in the generated constructor Files (added, modified or removed): * widgets/static_bitmap/perl_codegen.py added EVT_TEXT_ENTER event Files (added, modified or removed): * widgets/combo_box/combo_box.py 2005-07-11 Alberto Griggio various bugfixes Files (added, modified or removed): * application.py * codegen/py_codegen.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/list_ctrl/list_ctrl.py * widgets/panel/panel.py * widgets/spin_ctrl/spin_ctrl.py * widgets/static_bitmap/static_bitmap.py * widgets/tree_ctrl/tree_ctrl.py 2005-06-11 Alberto Griggio fixed bug #1218563 Files (added, modified or removed): * codegen/cpp_codegen.py fixed bug #1218563 Files (added, modified or removed): * codegen/py_codegen.py 2005-06-09 Alberto Griggio changed quote_str to generate a unicode object if the string contains non-ascii chars Files (added, modified or removed): * codegen/py_codegen.py 2005-06-04 Alberto Griggio now SizerHandleButtons are based on generic buttons on all platforms (better looking even with strange themes...) Files (added, modified or removed): * edit_sizers/edit_sizers.py 2005-06-03 Alberto Griggio applied patch to fix "empty label" bug Files (added, modified or removed): * widgets/static_text/static_text.py 2005-05-13 Alberto Griggio fixed wx2.6 segfault Files (added, modified or removed): * edit_sizers/edit_sizers.py 2005-05-06 Alberto Griggio updated copyright info - added wx2.6 compatibility Files (added, modified or removed): * CHANGES.txt * README.txt * __init__.py * about.py * application.py * clipboard.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * credits.txt * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * edit_windows.py * license.txt * main.py * misc.py * tree.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/custom_widget/__init__.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/frame/perl_codegen.py * widgets/gauge/__init__.py * widgets/gauge/codegen.py * widgets/gauge/gauge.py * widgets/grid/__init__.py * widgets/grid/codegen.py * widgets/grid/grid.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/list_ctrl/__init__.py * widgets/list_ctrl/codegen.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/__init__.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_button/__init__.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * widgets/toolbar/__init__.py * widgets/toolbar/codegen.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/__init__.py * widgets/tree_ctrl/codegen.py * widgets/tree_ctrl/tree_ctrl.py * wxglade.py * xml_parse.py * xrc2wxg.py 2005-04-27 Alberto Griggio small fixes (as usual ;-) Files (added, modified or removed): * edit_sizers/edit_sizers.py * events_mixin.py 2005-04-26 Alberto Griggio fixed broken GridSizer layout Files (added, modified or removed): * edit_sizers/edit_sizers.py 2005-04-16 Alberto Griggio changed to unix eol Files (added, modified or removed): * widgets/toolbar/toolbar.py 2005-04-14 Alberto Griggio fixed small bug Files (added, modified or removed): * edit_sizers/edit_sizers.py 2005-04-09 crazyinsomniac load empty bitmap if var:/code: Files (added, modified or removed): * widgets/toolbar/toolbar.py load empty bitmap if var:/code: Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py * widgets/static_bitmap/static_bitmap.py 2005-04-07 Alberto Griggio fixed segfault when adding a panel... (introduced by mistake some weeks ago) Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py * widget_properties.py * widgets/panel/panel.py 2005-04-04 Alberto Griggio fixed some various bugs... Files (added, modified or removed): * codegen/py_codegen.py * edit_sizers/edit_sizers.py * edit_windows.py * widgets/grid/codegen.py added layout_option_property to prepare for (possible) wx.GridBagSizer support Files (added, modified or removed): * layout_option_property.py 2005-03-25 Alberto Griggio applied patch #1169318 Files (added, modified or removed): * widgets/toolbar/perl_codegen.py 2005-03-11 Alberto Griggio some bug fixes Files (added, modified or removed): * main.py * widgets/frame/codegen.py * xml_parse.py 2005-03-05 Alberto Griggio implemented "refresh" Files (added, modified or removed): * icons/gtk/refresh.xpm * icons/msw/refresh.xpm * main.py * tree.py 2005-02-21 crazyinsomniac added missing new_signature Files (added, modified or removed): * widgets/notebook/perl_codegen.py 2005-02-12 Alberto Griggio now when you select a different widget, the visible tab is preserved (if possible) Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py 2005-02-07 Alberto Griggio fixed title bug Files (added, modified or removed): * edit_windows.py * widgets/dialog/dialog.py * widgets/frame/frame.py 2005-01-20 Alberto Griggio applied patch #1101182 Files (added, modified or removed): * common.py fixed dir dialog bug and bug #1104006 Files (added, modified or removed): * config.py * main.py * misc.py * xrc2wxg.py 2005-01-14 Alberto Griggio fixed small wxDirSelector bug Files (added, modified or removed): * application.py * main.py 2005-01-10 Alberto Griggio a lot of things... unfortunately I don't remeber any of them :-( Files (added, modified or removed): * about.py * codegen/cpp_codegen.py * codegen/py_codegen.py * edit_sizers/edit_sizers.py * main.py * tree.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/notebook/notebook.py 2004-12-23 crazyinsomniac mdi allows for fullscreen, against slightly outdated main.py/wxglade.py Files (added, modified or removed): * zmain.py * zwxglade.py 2004-12-22 crazyinsomniac add missing comma Files (added, modified or removed): * widgets/bitmap_button/perl_codegen.py 2004-12-20 Alberto Griggio fixed kde file dialog bug Files (added, modified or removed): * main.py 2004-12-19 Alberto Griggio minor code generation changes for 'code:' and 'var:' Files (added, modified or removed): * widgets/bitmap_button/codegen.py * widgets/static_bitmap/codegen.py * widgets/toolbar/codegen.py some minor ui enhancements Files (added, modified or removed): * application.py * edit_sizers/edit_sizers.py * edit_windows.py * misc.py * widgets/menubar/menubar.py * widgets/panel/panel.py * widgets/toolbar/toolbar.py 2004-12-13 Alberto Griggio c++ event handling enhancements Files (added, modified or removed): * codegen/cpp_codegen.py * widgets/grid/codegen.py * widgets/list_ctrl/codegen.py * widgets/notebook/codegen.py * widgets/spin_button/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/tree_ctrl/codegen.py 2004-12-12 crazyinsomniac build_untouched_content block_start re tweak (Cheetah bug) Files (added, modified or removed): * codegen/pl_codegen.py 2004-12-11 Alberto Griggio updated email address Files (added, modified or removed): * README.txt updated system requirements Files (added, modified or removed): * README.txt 2004-12-10 Alberto Griggio event handling improvements Files (added, modified or removed): * events_mixin.py event handling improvements Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py * widgets/menubar/codegen.py some event handling enhancements Files (added, modified or removed): * application.py * events_mixin.py * main.py * widgets/MenuTree.py * widgets/menubar/menubar.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py 2004-12-08 Alberto Griggio first basic event handlers support Files (added, modified or removed): * application.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * docs/tutorial.html * edit_windows.py * events_mixin.py * main.py * misc.py * tree.py * widget_properties.py * widgets/MenuTree.py * widgets/bitmap_button/bitmap_button.py * widgets/button/button.py * widgets/checkbox/checkbox.py * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/frame/frame.py * widgets/grid/codegen.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py * widgets/notebook/notebook.py * widgets/radio_box/radio_box.py * widgets/radio_button/radio_button.py * widgets/slider/slider.py * widgets/spin_button/spin_button.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/splitter_window.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/toggle_button.py * widgets/toolbar/codegen.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/tree_ctrl.py * xml_parse.py 2004-11-18 Alberto Griggio fixed name validation regexp Files (added, modified or removed): * edit_windows.py possible fix for bug #1067586 Files (added, modified or removed): * widget_properties.py * widgets/menubar/menubar.py * widgets/toolbar/toolbar.py 2004-11-16 Alberto Griggio fixed: extra headers not inserted correctly when generating multiple files Files (added, modified or removed): * codegen/cpp_codegen.py 2004-11-08 Alberto Griggio updated version info Files (added, modified or removed): * CHANGES.txt updated version number Files (added, modified or removed): * common.py * wxglade.spec 2004-11-06 Alberto Griggio made possible to Cancel insertion of slots/rows/columns Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed recently introduced "on_size" bug Files (added, modified or removed): * edit_windows.py 2004-11-04 Alberto Griggio last changes before v0.3.5 Files (added, modified or removed): * CHANGES.txt * application.py * edit_sizers/edit_sizers.py * edit_windows.py * widgets/panel/panel.py * wxglade.spec 2004-11-02 Alberto Griggio updated credits Files (added, modified or removed): * CHANGES.txt * credits.txt patch from Vaclav Slavik to support 'icon' property in XRC Files (added, modified or removed): * widgets/dialog/codegen.py * widgets/frame/codegen.py 2004-11-02 georgesk added the definition of the function _() to the code generated in python when i18n is selected Files (added, modified or removed): * codegen/py_codegen.py added debianisation tools to the package. They can be activated by running the command 'debuild' Files (added, modified or removed): * Makefile * debian/changelog * debian/compat * debian/control * debian/copyright * debian/dirs * debian/docs * debian/files * debian/manpage.xml * debian/postinst * debian/rules * debian/wxglade.1 * wxglade 2004-11-02 Alberto Griggio various tweaks and fixes for v0.3.5 release... Files (added, modified or removed): * README.txt * about.py * application.py * common.py * config.py * configUI.py * edit_windows.py * kdefiledialog.py * main.py * misc.py * res/preferences.wxg * widget_properties.py * widgets/bitmap_button/bitmap_button.py * widgets/dialog/dialog.py * widgets/menubar/menubar.py * widgets/static_bitmap/static_bitmap.py * widgets/toolbar/toolbar.py * wxglade.py * wxglade.spec * xml_parse.py 2004-11-01 georgesk improved slightly i18n support in generated python code Files (added, modified or removed): * codegen/py_codegen.py 2004-10-27 Alberto Griggio support for windows entry point Files (added, modified or removed): * wxglade.py entry point on windows Files (added, modified or removed): * wxglade.pyw 2004-10-26 Alberto Griggio fixed windows line endings... Files (added, modified or removed): * codegen/pl_codegen.py fixed wxMDIChildFrame C++ code bug Files (added, modified or removed): * widgets/frame/codegen.py 2004-10-26 crazyinsomniac replace :: with os.sep in filenames Files (added, modified or removed): * codegen/pl_codegen.py 2004-10-24 Alberto Griggio better handling of "duplicate names" Files (added, modified or removed): * configUI.py * edit_sizers/edit_sizers.py * edit_windows.py * misc.py * res/preferences.wxg * tree.py 2004-10-21 Alberto Griggio fixed file name problem when generating multiple files Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py fixed set_size issue on wx >= 2.5 Files (added, modified or removed): * edit_windows.py 2004-10-20 Alberto Griggio fixed GridSizerBase.add_row bug Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed incorrect labeling in the tree when using custom class values Files (added, modified or removed): * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/menubar/menubar.py * widgets/panel/panel.py * widgets/toolbar/toolbar.py 2004-10-18 Alberto Griggio fixed style problem Files (added, modified or removed): * widgets/toolbar/toolbar.py patch for encoding problem Files (added, modified or removed): * xml_parse.py fixed segfault when removing a frame with a statusbar Files (added, modified or removed): * widgets/frame/frame.py fixed segfault when removing a toplevel window from the popup menu Files (added, modified or removed): * edit_windows.py * widgets/menubar/menubar.py small autosave enhancement Files (added, modified or removed): * common.py * main.py fixed bug that made it possible to double-past a sizer into a toplevel window Files (added, modified or removed): * edit_windows.py fixed minor issues Files (added, modified or removed): * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/menubar/menubar.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/text_ctrl/text_ctrl.py * widgets/toolbar/toolbar.py some ui tweaks Files (added, modified or removed): * config.py * configUI.py * icons/spinbtn.xpm * main.py * res/preferences.wxg better edit_widget support Files (added, modified or removed): * common.py * edit_sizers/edit_sizers.py * edit_widget.py * edit_windows.py * widget_properties.py 2004-10-15 Alberto Griggio some minor enhancements... Files (added, modified or removed): * codegen/py_codegen.py * common.py * docs/tutorial.html * edit_sizers/sizers_codegen.py * edit_windows.py * main.py * misc.py better default class names for xrc output Files (added, modified or removed): * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/menubar/menubar.py * widgets/toolbar/toolbar.py auto save support Files (added, modified or removed): * CHANGES.txt * common.py * config.py * configUI.py * main.py * res/preferences.wxg 2004-10-14 Alberto Griggio fixed wrong add_app code Files (added, modified or removed): * codegen/py_codegen.py 2004-10-05 Alberto Griggio various bugs fixed (preview, change of position on a sizer, ...) Files (added, modified or removed): * application.py * clipboard.py * codegen/py_codegen.py * edit_sizers/edit_sizers.py * edit_windows.py * tree.py 2004-10-02 crazyinsomniac now a radio button is displayed checked when thats its value Files (added, modified or removed): * widgets/radio_button/radio_button.py 2004-09-30 Alberto Griggio fixed segfault when using grid sizers Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed bug #1019325 Files (added, modified or removed): * widgets/frame/frame.py added wxCB_SIMPLE style Files (added, modified or removed): * widgets/combo_box/combo_box.py 2004-09-28 crazyinsomniac create_widget now has exception handling Files (added, modified or removed): * widgets/spin_button/spin_button.py create_widget now exception handling Files (added, modified or removed): * widgets/button/button.py create_widget button now takes on style as specified by user Files (added, modified or removed): * widgets/button/button.py 2004-09-27 Alberto Griggio miscellaneous fixes Files (added, modified or removed): * tree.py * widgets/bitmap_button/bitmap_button.py * widgets/static_bitmap/static_bitmap.py *** empty log message *** Files (added, modified or removed): * icons/closed_folder.xpm miscellaneous fixes Files (added, modified or removed): * main.py * widgets/dialog/dialog.py * widgets/menubar/menubar.py * widgets/panel/panel.py * widgets/splitter_window/splitter_window.py * xrc2wxg.py 2004-09-23 crazyinsomniac add style Files (added, modified or removed): * widgets/spin_button/spin_button.py no message Files (added, modified or removed): * icons/spinbtn.xpm no message Files (added, modified or removed): * widgets/spin_button/.cvsignore * widgets/spin_button/__init__.py * widgets/spin_button/codegen.py * widgets/spin_button/perl_codegen.py * widgets/spin_button/spin_button.py no message Files (added, modified or removed): * widgets/widgets.txt no message Files (added, modified or removed): * codegen/pl_codegen.py put return $self after # end wxGlade Files (added, modified or removed): * codegen/pl_codegen.py 2004-09-22 crazyinsomniac missed a # Files (added, modified or removed): * codegen/pl_codegen.py perl_codegen's now loaded from widgets.txt, just like the rest Files (added, modified or removed): * codegen/pl_codegen.py 2004-09-20 Alberto Griggio mac tweaks Files (added, modified or removed): * main.py * widgets/menubar/menubar.py * widgets/panel/panel.py 2004-09-17 Alberto Griggio updated copyright information Files (added, modified or removed): * CHANGES.txt * __init__.py * about.py * application.py * clipboard.py * codegen/cpp_codegen.py * codegen/pl_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * credits.txt * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/perl_sizers_codegen.py * edit_sizers/sizers_codegen.py * edit_widget.py * edit_windows.py * main.py * misc.py * tree.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/button/perl_codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/checkbox/perl_codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/choice/perl_codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/combo_box/perl_codegen.py * widgets/custom_widget/__init__.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/custom_widget/perl_codegen.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/dialog/perl_codegen.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/frame/perl_codegen.py * widgets/gauge/__init__.py * widgets/gauge/codegen.py * widgets/gauge/gauge.py * widgets/gauge/perl_codegen.py * widgets/grid/__init__.py * widgets/grid/codegen.py * widgets/grid/grid.py * widgets/grid/perl_codegen.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/list_box/perl_codegen.py * widgets/list_ctrl/__init__.py * widgets/list_ctrl/codegen.py * widgets/list_ctrl/list_ctrl.py * widgets/list_ctrl/perl_codegen.py * widgets/menubar/__init__.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py * widgets/menubar/perl_codegen.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/notebook/perl_codegen.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/panel/perl_codegen.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/perl_codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/perl_codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/perl_codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/perl_codegen.py * widgets/spacer/spacer.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/perl_codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/perl_codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/perl_codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/perl_codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/perl_codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/perl_codegen.py * widgets/toggle_button/toggle_button.py * widgets/toolbar/__init__.py * widgets/toolbar/codegen.py * widgets/toolbar/perl_codegen.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/__init__.py * widgets/tree_ctrl/codegen.py * widgets/tree_ctrl/perl_codegen.py * widgets/tree_ctrl/tree_ctrl.py * wxglade.py * xml_parse.py * xrc2wxg.py updated version number Files (added, modified or removed): * common.py fixed bug when removing widgets from the popup menu (GTK2) Files (added, modified or removed): * CHANGES.txt * edit_sizers/edit_sizers.py * edit_windows.py fix for staticbox bug Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py * edit_sizers/sizers_codegen.py updated version number Files (added, modified or removed): * wxglade.spec icon for .wxg files Files (added, modified or removed): * icons/wxg_file.ico 2004-09-17 crazyinsomniac fix staticbox order bug Files (added, modified or removed): * codegen/pl_codegen.py * edit_sizers/perl_sizers_codegen.py 2004-09-15 Alberto Griggio removed "fake" wxPanel from xrc code generation, as it is not necessary anymore Files (added, modified or removed): * widgets/frame/codegen.py 2004-09-04 Alberto Griggio changed version number Files (added, modified or removed): * CHANGES.txt * common.py 2004-09-02 Alberto Griggio *** empty log message *** Files (added, modified or removed): * configUI.py * res/preferences.wxg 2004-09-01 Alberto Griggio small fixes Files (added, modified or removed): * tree.py * widget_properties.py * wxglade.py * wxglade.spec fixed bug with 2.5.2.8 Files (added, modified or removed): * widgets/grid/codegen.py 2004-08-26 Alberto Griggio *** empty log message *** Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py * tree.py * widgets/panel/codegen.py * xml_parse.py 2004-08-19 Alberto Griggio fixed bug in make_object_button Files (added, modified or removed): * common.py 2004-08-18 Alberto Griggio fixed typo in wxFIXED_MINSIZE Files (added, modified or removed): * edit_windows.py 2004-08-17 Alberto Griggio "fix" for wxPython 2.5.2.x Files (added, modified or removed): * edit_windows.py 2004-08-17 crazyinsomniac again with the CR+LF to LF tomfoolery Files (added, modified or removed): * widgets/frame/perl_codegen.py * widgets/grid/perl_codegen.py * widgets/panel/perl_codegen.py 2004-08-16 Alberto Griggio fixed small bugs Files (added, modified or removed): * widget_properties.py * wxglade.py 2004-08-15 Alberto Griggio fixed bug in "_build_from_font" Files (added, modified or removed): * edit_windows.py * main.py 2004-08-12 Alberto Griggio some small improvements... Files (added, modified or removed): * CHANGES.txt * common.py * config.py * configUI.py * edit_sizers/edit_sizers.py * edit_windows.py * res/preferences.wxg 2004-08-06 Alberto Griggio *** empty log message *** Files (added, modified or removed): * common.py * license.txt * widgets/list_box/codegen.py 2004-07-21 Alberto Griggio fixed style bug in python code Files (added, modified or removed): * widgets/static_bitmap/codegen.py 2004-07-18 Alberto Griggio changed python code generator for menubar Files (added, modified or removed): * CHANGES.txt * common.py * widgets/menubar/codegen.py 2004-07-15 Alberto Griggio applied patch #985511 Files (added, modified or removed): * widgets/tree_ctrl/tree_ctrl.py 2004-06-29 Alberto Griggio applied patch #974995 Files (added, modified or removed): * codegen/py_codegen.py 2004-06-16 Alberto Griggio fixed ColorDialogProperty affecting grid in 0.3.3 Files (added, modified or removed): * widget_properties.py 2004-06-04 Alberto Griggio fixed bug #966094 Files (added, modified or removed): * edit_windows.py 2004-05-18 Alberto Griggio fixed bug on 2.5 on windows Files (added, modified or removed): * color_dialog.py 2004-05-17 Alberto Griggio added from_xml option to add_widget_node Files (added, modified or removed): * edit_widget.py more bugfixes... Files (added, modified or removed): * color_dialog.py * edit_widget.py * edit_windows.py * widget_properties.py 2004-05-14 Alberto Griggio fixed for wrong bool conversion Files (added, modified or removed): * config.py 2004-05-12 Alberto Griggio fixed 2.5 bug in choose_specific_font Files (added, modified or removed): * font_dialog.py fixed small bug in increment_label Files (added, modified or removed): * edit_widget.py 2004-05-11 Alberto Griggio fixed composed.class.Name bug :-) Files (added, modified or removed): * xml_parse.py fixed wx 2.5 incompatibility (wxSizer.Show(wxSizer, bool) not working as expected...) Files (added, modified or removed): * main.py small fixes Files (added, modified or removed): * font_dialog.py * widgets/custom_widget/custom_widget.py 2004-05-05 Alberto Griggio fixes and tweaks in preparation for release 0.3.3 Files (added, modified or removed): * CHANGES.txt * codegen/xrc_codegen.py * common.py * edit_windows.py * widget_properties.py * widgets/button/button.py * widgets/button/codegen.py * widgets/button/perl_codegen.py * widgets/choice/choice.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/frame/codegen.py * widgets/list_box/list_box.py * widgets/list_ctrl/list_ctrl.py * widgets/spin_ctrl/codegen.py 2004-05-01 Alberto Griggio removed obsolete wxLC_USER_TEXT style Files (added, modified or removed): * widgets/list_ctrl/list_ctrl.py 2004-04-26 Alberto Griggio fixes for wx2.5 Files (added, modified or removed): * application.py * edit_sizers/edit_sizers.py * widgets/choice/choice.py 2004-04-21 Alberto Griggio to turn wxGlade into a package Files (added, modified or removed): * __init__.py fixed segfault on wx2.5 Files (added, modified or removed): * edit_sizers/edit_sizers.py 2004-04-07 Alberto Griggio fixed wx 2.5 incompatibility Files (added, modified or removed): * widgets/combo_box/combo_box.py 2004-03-30 Alberto Griggio fixed splitter window layout bug Files (added, modified or removed): * widgets/splitter_window/codegen.py * widgets/splitter_window/perl_codegen.py 2004-03-15 Alberto Griggio fixed small bug Files (added, modified or removed): * widgets/menubar/menubar.py 2004-03-11 Alberto Griggio some bugfixes Files (added, modified or removed): * edit_windows.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/frame/perl_codegen.py * widgets/text_ctrl/text_ctrl.py 2004-03-10 Alberto Griggio first commit Files (added, modified or removed): * wxglade.spec 2004-03-06 Alberto Griggio fixed bug #880674 Files (added, modified or removed): * CHANGES.txt * widgets/panel/panel.py 2004-03-04 Alberto Griggio update to version 0.3.2 Files (added, modified or removed): * CHANGES.txt 2004-03-01 Alberto Griggio updated version number Files (added, modified or removed): * common.py user's manual update Files (added, modified or removed): * credits.txt * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch05.html * docs/html/ch05s02.html * docs/html/ch05s03.html * docs/html/ch05s04.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/manual.xml 2004-02-22 Alberto Griggio changed to wxWidgets Files (added, modified or removed): * icons/wxglade_small.png 2004-02-21 Alberto Griggio changed wxWindows to wxWidgets Files (added, modified or removed): * credits.txt updated version number Files (added, modified or removed): * common.py removed drop targets for the tree and property windows as they make wxGlade crash on win32 Files (added, modified or removed): * main.py 2004-02-20 Alberto Griggio fixed submenu bug Files (added, modified or removed): * widgets/MenuTree.py * widgets/menubar/codegen.py 2004-02-19 Alberto Griggio added drag&drop of wxg files for opening them Files (added, modified or removed): * CHANGES.txt * clipboard.py * main.py 2004-02-17 Alberto Griggio new manual added Files (added, modified or removed): * CHANGES.txt * docs/index.html fixed `relative paths' issue Files (added, modified or removed): * application.py * main.py 2004-02-09 Alberto Griggio made possible for GridProperty to be empty Files (added, modified or removed): * widget_properties.py 2004-02-07 Alberto Griggio *** empty log message *** Files (added, modified or removed): * CHANGES.txt 2004-02-06 Alberto Griggio applied patch #890587 Files (added, modified or removed): * config.py 2004-02-01 Alberto Griggio converted to unix EOL Files (added, modified or removed): * widgets/bitmap_button/codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/toolbar/codegen.py * widgets/toolbar/perl_codegen.py 2004-01-31 Alberto Griggio changes to support var: and code: icons Files (added, modified or removed): * widgets/dialog/dialog.py * widgets/frame/frame.py 2004-01-30 Alberto Griggio fixed wx 2.5 incompatibility Files (added, modified or removed): * tree.py added global Ctrl+g shortcut Files (added, modified or removed): * misc.py 2004-01-29 dinogen syntax error on manual Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch05.html * docs/html/ch05s02.html * docs/html/ch05s03.html * docs/html/ch05s04.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/manual.xml *** empty log message *** Files (added, modified or removed): * docs/manual.tex wxglade 16x16 icon var and code in wxFrame Files (added, modified or removed): * icons/icon16.xpm * widgets/frame/codegen.py wxglade icon in the bitmaps preview Files (added, modified or removed): * widgets/bitmap_button/codegen.py * widgets/static_bitmap/codegen.py * widgets/toolbar/codegen.py 2004-01-28 dinogen reduction of subsetction Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch05.html * docs/html/ch05s02.html * docs/html/ch05s03.html * docs/html/ch05s04.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/manual.xml 2004-01-27 dinogen manual finish Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch04s03.html * docs/html/ch04s04.html * docs/html/ch04s05.html * docs/html/ch04s06.html * docs/html/ch04s07.html * docs/html/ch04s08.html * docs/html/ch04s09.html * docs/html/ch04s10.html * docs/html/ch04s11.html * docs/html/ch04s12.html * docs/html/ch04s13.html * docs/html/ch04s14.html * docs/html/ch04s15.html * docs/html/ch04s16.html * docs/html/ch04s17.html * docs/html/ch04s18.html * docs/html/ch04s19.html * docs/html/ch04s20.html * docs/html/ch04s21.html * docs/html/ch04s22.html * docs/html/ch04s23.html * docs/html/ch04s24.html * docs/html/ch04s25.html * docs/html/ch04s26.html * docs/html/ch04s27.html * docs/html/ch05.html * docs/html/ch05s02.html * docs/html/ch05s03.html * docs/html/ch05s04.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/manual.xml doc widgets section completed Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch04.html * docs/html/ch04s02.html * docs/html/ch04s03.html * docs/html/ch04s04.html * docs/html/ch04s05.html * docs/html/ch04s06.html * docs/html/ch04s07.html * docs/html/ch04s08.html * docs/html/ch04s09.html * docs/html/ch04s10.html * docs/html/ch04s11.html * docs/html/ch04s12.html * docs/html/ch04s13.html * docs/html/ch04s14.html * docs/html/ch04s15.html * docs/html/ch04s16.html * docs/html/ch04s17.html * docs/html/ch04s18.html * docs/html/ch04s19.html * docs/html/ch04s20.html * docs/html/ch04s21.html * docs/html/ch04s22.html * docs/html/ch04s23.html * docs/html/ch04s24.html * docs/html/ch04s25.html * docs/html/ch04s26.html * docs/html/ch04s27.html * docs/html/ch05.html * docs/html/ch05s02.html * docs/html/ch05s03.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/manual.xml 2004-01-26 dinogen added pdf dir but NOT the pdf file, it is too large. Files (added, modified or removed): * docs/pdf/readme.txt Widgets section in documentation Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch02s05.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/manual.xml 2004-01-25 Alberto Griggio Removed unneeded files Files (added, modified or removed): * wxPyColourChooser/__init__.py * wxPyColourChooser/canvas.py * wxPyColourChooser/intl.py * wxPyColourChooser/license/lgpl.txt * wxPyColourChooser/license/wxwindowslib.txt * wxPyColourChooser/pycolourbox.py * wxPyColourChooser/pycolourchooser.py * wxPyColourChooser/pycolourslider.py * wxPyColourChooser/pypalette.py fixes and changes for 2.5 compatibility Files (added, modified or removed): * CHANGES.txt * about.py * codegen/py_codegen.py * color_dialog.py * config.py * edit_sizers/edit_sizers.py * font_dialog.py * main.py * misc.py * tree.py * widgets/frame/frame.py * widgets/splitter_window/splitter_window.py wrapped a long line Files (added, modified or removed): * widgets/toolbar/codegen.py 2004-01-20 dinogen added code\: tag to static_bitmap, bitmap_button and toolbar Files (added, modified or removed): * widgets/bitmap_button/codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/toolbar/codegen.py * widgets/toolbar/perl_codegen.py 2004-01-20 crazyinsomniac more \t tweaking *yawn* Files (added, modified or removed): * codegen/pl_codegen.py * edit_sizers/perl_sizers_codegen.py * widgets/button/perl_codegen.py * widgets/frame/perl_codegen.py * widgets/panel/perl_codegen.py add new new_signature, fix bug #865338 Files (added, modified or removed): * widgets/splitter_window/perl_codegen.py 2004-01-20 Alberto Griggio fixed bug #878469 Files (added, modified or removed): * edit_sizers/edit_sizers.py 2004-01-18 Alberto Griggio new "use wx namespace" option for python output Files (added, modified or removed): * about.py * application.py * codegen/py_codegen.py * misc.py * tree.py * widgets/bitmap_button/codegen.py * widgets/static_bitmap/codegen.py * widgets/toolbar/codegen.py * xml_parse.py 2004-01-08 dinogen english corrected version Files (added, modified or removed): * docs/src/manual.xml 2004-01-08 Alberto Griggio fixed `//*' bug Files (added, modified or removed): * codegen/cpp_codegen.py 2004-01-05 Alberto Griggio fixed small typo Files (added, modified or removed): * codegen/py_codegen.py * widgets/frame/frame.py 2003-12-28 Alberto Griggio updated to xrc2wxg version 0.0.3 Files (added, modified or removed): * CHANGES.txt * xrc2wxg.py 2003-12-20 Alberto Griggio fixed new wx namespace bug Files (added, modified or removed): * widgets/static_bitmap/codegen.py fixed new wx namespace bug Files (added, modified or removed): * widgets/bitmap_button/codegen.py 2003-12-17 Alberto Griggio fixed new namespace bug Files (added, modified or removed): * widgets/menubar/codegen.py 2003-12-09 dinogen static bitmap generation bug correct Files (added, modified or removed): * widgets/static_bitmap/codegen.py 2003-12-07 Alberto Griggio partially fixed bug #798041 (renaming) Files (added, modified or removed): * CHANGES.txt * tree.py 2003-12-06 Alberto Griggio it is now possible to paste a sizer into a panel Files (added, modified or removed): * CHANGES.txt * widgets/panel/panel.py 2003-12-03 Alberto Griggio fixed bug in generate_code_id Files (added, modified or removed): * codegen/cpp_codegen.py 2003-11-30 Alberto Griggio fixed new wx namespace bug Files (added, modified or removed): * codegen/py_codegen.py 2003-11-27 Alberto Griggio added some styles Files (added, modified or removed): * widgets/text_ctrl/text_ctrl.py fixed new namespace bug (wxFont) Files (added, modified or removed): * codegen/py_codegen.py fixed preview bug (use_new_namespace) Files (added, modified or removed): * application.py 2003-11-25 Alberto Griggio wrapped a long line :) Files (added, modified or removed): * config.py new wx namespace for python code generator Files (added, modified or removed): * CHANGES.txt changed version number Files (added, modified or removed): * common.py 2003-11-24 Alberto Griggio support for new wxPython namespace Files (added, modified or removed): * application.py * codegen/py_codegen.py * edit_sizers/sizers_codegen.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/custom_widget/codegen.py * widgets/dialog/codegen.py * widgets/frame/codegen.py * widgets/gauge/codegen.py * widgets/grid/codegen.py * widgets/list_box/codegen.py * widgets/list_ctrl/codegen.py * widgets/menubar/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py * widgets/toolbar/codegen.py * widgets/tree_ctrl/codegen.py small UI fixes Files (added, modified or removed): * configUI.py 2003-11-20 dinogen split config.py in configUI (base class) and config (derived class) Files (added, modified or removed): * config.py * configUI.py * res/preferences.wxg 2003-11-18 dinogen wxg preference added Files (added, modified or removed): * res/preferences.wxg 2003-11-13 Alberto Griggio fixed preview bug Files (added, modified or removed): * application.py 2003-10-30 dinogen custom widget w and h - variable default border Files (added, modified or removed): * config.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/custom_widget/perl_codegen.py 2003-10-29 lawson89 Fixes to address: (1) toplevel windows not brought to front on a double click of node (2) doubleclick on expanded toplevel node collapsed entire widget tree instead of just the node Files (added, modified or removed): * tree.py 2003-10-24 Alberto Griggio added wxSHAPED and wxADJUST_MINSIZE flags Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py * xml_parse.py 2003-10-09 dinogen *** empty log message *** Files (added, modified or removed): * docs/src/manual.xml 2003-10-07 dinogen *** empty log message *** Files (added, modified or removed): * docs/html/apa.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/ch03s06.html * docs/html/ch03s07.html * docs/html/index.html * docs/src/manual.xml 2003-10-02 dinogen *** empty log message *** Files (added, modified or removed): * docs/Makefile * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/ch03s05.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/manual.xml 2003-10-01 dinogen *** empty log message *** Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch02s04.html * docs/html/ch03.html * docs/html/ch03s02.html * docs/html/ch03s03.html * docs/html/ch03s04.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/html/properties_window_tab_1.png * docs/html/properties_window_tab_2.png * docs/html/properties_window_tab_3.png * docs/src/manual.xml * docs/src/properties_window_tab_1.png * docs/src/properties_window_tab_2.png * docs/src/properties_window_tab_3.png 2003-09-24 dinogen fixed growing cols bug Files (added, modified or removed): * docs/src/manual.xml * edit_sizers/sizers_codegen.py 2003-09-11 dinogen added border default on config window for some widget Files (added, modified or removed): * config.py * widgets/bitmap_button/bitmap_button.py * widgets/button/button.py * widgets/checkbox/checkbox.py * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/radio_button/radio_button.py * widgets/spin_ctrl/spin_ctrl.py * widgets/static_text/static_text.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/toggle_button.py 2003-09-09 dinogen *** empty log message *** Files (added, modified or removed): * docs/html/ch02s04.html * docs/html/ch03s02.html * docs/html/design_window.png * docs/html/design_window_empty_slot.png * docs/html/label_menu.png * docs/html/sizer_menu.png added some section\ Files (added, modified or removed): * docs/src/design_window_empty_slot.png * docs/src/label_menu.png * docs/src/select_frame.png * docs/src/sizer_menu.png * docs/src/test.wxg added some section Files (added, modified or removed): * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch03.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/design_window.png * docs/src/manual.xml 2003-08-31 Alberto Griggio fixed icon path quoting bug Files (added, modified or removed): * widgets/frame/codegen.py 2003-08-30 Alberto Griggio fixed bug with menu icons on wxGTK 2.4.1.2 Files (added, modified or removed): * misc.py updated to 0.3.1 Files (added, modified or removed): * CHANGES.txt * common.py removed some ^M (DOS eol) Files (added, modified or removed): * codegen/pl_codegen.py 2003-08-29 Alberto Griggio v0.3 released Files (added, modified or removed): * CHANGES.txt * common.py 2003-08-29 crazyinsomniac cleanup, locale multifile fixes, wxPySimpleApp fakery Files (added, modified or removed): * codegen/pl_codegen.py 2003-08-28 crazyinsomniac fixed "replace %s dependencies" not being replaced Files (added, modified or removed): * codegen/pl_codegen.py quote_path patch (escape $ and @ cause its ") Files (added, modified or removed): * codegen/pl_codegen.py 2003-08-27 Alberto Griggio minor cosmetic change (initial size of the property window) Files (added, modified or removed): * main.py 2003-08-26 Alberto Griggio minor UI tweak Files (added, modified or removed): * widgets/spacer/spacer.py 2003-08-23 crazyinsomniac quote_str patch (escape $ and @ cause its ") Files (added, modified or removed): * codegen/pl_codegen.py 2003-08-16 Alberto Griggio changed version id Files (added, modified or removed): * common.py silenced unimportant warning on py 2.3 Files (added, modified or removed): * main.py small change Files (added, modified or removed): * edit_sizers/edit_sizers.py fixed preview bug Files (added, modified or removed): * widgets/menubar/codegen.py * widgets/toolbar/codegen.py 2003-08-11 Alberto Griggio fixed bug #786266 Files (added, modified or removed): * widgets/radio_button/radio_button.py fixed bug #786233 Files (added, modified or removed): * main.py 2003-08-07 crazyinsomniac logic bug (if id has no val, set it to wxNewId()) Files (added, modified or removed): * codegen/pl_codegen.py * widgets/menubar/codegen.py * widgets/menubar/perl_codegen.py 2003-08-07 Alberto Griggio fixed bug #782767 Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/menubar/menubar.py * xrc2wxg.py 2003-08-07 crazyinsomniac added wxNO_BORDER as a style option Files (added, modified or removed): * widgets/frame/frame.py * widgets/panel/panel.py nonce tags now perl comments (#<...>), in case they're left over Files (added, modified or removed): * codegen/pl_codegen.py 2003-08-07 dinogen Docs on tree windows Files (added, modified or removed): * docs/Makefile * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch03.html * docs/html/design_window.png * docs/html/index.html * docs/html/main_window.png * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/html/preview_window.png * docs/html/properties_window.png * docs/html/select_frame.png * docs/html/tree_window.png * docs/src/manual.xml 2003-08-05 dinogen qqq:wq Files (added, modified or removed): * docs/manual.xml * docs/manual_des.png * docs/manual_main.png * docs/manual_preview.png * docs/manual_prop.png * docs/manual_tree.png Nuova struttura docs Files (added, modified or removed): * docs/Makefile * docs/html/apa.html * docs/html/ch01.html * docs/html/ch01s02.html * docs/html/ch01s03.html * docs/html/ch01s04.html * docs/html/ch01s05.html * docs/html/ch01s06.html * docs/html/ch02.html * docs/html/ch02s02.html * docs/html/ch02s03.html * docs/html/ch03.html * docs/html/index.html * docs/html/pr01.html * docs/html/pr01s02.html * docs/html/pr01s03.html * docs/src/design_window.png * docs/src/main_window.png * docs/src/manual.xml * docs/src/preview_window.png * docs/src/properties_window.png * docs/src/tree_window.png Added xml file Files (added, modified or removed): * docs/manual.xml 2003-08-03 Alberto Griggio better id code generation Files (added, modified or removed): * codegen/py_codegen.py 2003-08-02 Alberto Griggio fixed some python 2.3 warnings Files (added, modified or removed): * application.py * edit_sizers/edit_sizers.py * edit_windows.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/perl_codegen.py * widgets/spacer/spacer.py * widgets/static_bitmap/static_bitmap.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/tree_ctrl.py 2003-07-31 crazyinsomniac typo fix Files (added, modified or removed): * widgets/toolbar/perl_codegen.py 2003-07-31 dinogen Aggiunta sezione di exploring Files (added, modified or removed): * docs/manual.tex 2003-07-29 Alberto Griggio fixed some bugs Files (added, modified or removed): * TODO.txt * application.py * main.py * misc.py * widgets/grid/grid.py * xml_parse.py 2003-07-26 Alberto Griggio brought perl generator up to date Files (added, modified or removed): * CHANGES.txt * codegen/pl_codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/menubar/perl_codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/toolbar/perl_codegen.py fixed comment Files (added, modified or removed): * codegen/py_codegen.py fixed bug when escaping \ for pathnames Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py * widgets/bitmap_button/codegen.py * widgets/static_bitmap/codegen.py * widgets/toolbar/codegen.py 2003-07-23 Alberto Griggio some bugs fixed Files (added, modified or removed): * application.py * config.py fixes for preview when self.klass == self.base Files (added, modified or removed): * application.py * xml_parse.py 2003-07-22 dinogen aggiustati termini nel quick start Files (added, modified or removed): * docs/manual.tex 2003-07-22 Alberto Griggio generated ids are now globals Files (added, modified or removed): * codegen/py_codegen.py 2003-07-21 dinogen Quick start completed Files (added, modified or removed): * docs/manual.tex 2003-07-19 Alberto Griggio fixed bugs Files (added, modified or removed): * widgets/frame/frame.py * widgets/toolbar/codegen.py 2003-07-18 crazyinsomniac use CustomWidgetClass (temporary fix) Files (added, modified or removed): * widgets/custom_widget/perl_codegen.py another wxGrid constants fix Files (added, modified or removed): * widgets/grid/perl_codegen.py wxGridSelectCells typo fix (thanks Jouke) Files (added, modified or removed): * widgets/grid/perl_codegen.py 2003-07-18 Alberto Griggio added support for var:variable_name in bitmap properties Files (added, modified or removed): * CHANGES.txt * codegen/cpp_codegen.py * codegen/py_codegen.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/toolbar/codegen.py * widgets/toolbar/toolbar.py fixed wxMDIChildFrame preview bug Files (added, modified or removed): * application.py fixed dialog units size bug Files (added, modified or removed): * edit_windows.py 2003-07-17 Alberto Griggio fixed small label bug Files (added, modified or removed): * widgets/button/button.py * widgets/toggle_button/toggle_button.py 2003-07-16 Alberto Griggio added subclass support to XRC output Files (added, modified or removed): * CHANGES.txt * codegen/xrc_codegen.py * docs/tutorial.html * edit_windows.py * widget_properties.py * xml_parse.py 2003-07-15 Alberto Griggio new "overwrite" property of Application Files (added, modified or removed): * CHANGES.txt * application.py * codegen/cpp_codegen.py * codegen/py_codegen.py * docs/tutorial.html * tree.py * xml_parse.py 2003-07-14 Alberto Griggio changed default encoding from 'latin-1' to the equivalent 'ISO-8859-1' Files (added, modified or removed): * application.py 2003-07-13 crazyinsomniac generate_code_id fix (and probably other minor bits) Files (added, modified or removed): * codegen/pl_codegen.py 2003-07-12 Alberto Griggio added special form "name=?" for id properties Files (added, modified or removed): * docs/tutorial.html 2003-07-11 Alberto Griggio added useless comment, only to avoid emacs font-lock going insane Files (added, modified or removed): * codegen/pl_codegen.py fixed a couple of bugs, added ID_SOMETHING=? support (automatic id value generation) Files (added, modified or removed): * CHANGES.txt * codegen/cpp_codegen.py * codegen/py_codegen.py * common.py * widgets/menubar/codegen.py * widgets/toolbar/codegen.py fixed bug #769524 Files (added, modified or removed): * widgets/frame/frame.py 2003-07-11 crazyinsomniac added quote_path and othe rminor bits Files (added, modified or removed): * codegen/pl_codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/toolbar/perl_codegen.py 2003-07-10 crazyinsomniac quote_str fix and other minor bits Files (added, modified or removed): * codegen/pl_codegen.py 2003-07-09 crazyinsomniac constructor signature fixes Files (added, modified or removed): * widgets/dialog/perl_codegen.py * widgets/panel/perl_codegen.py constructor signature fixes Files (added, modified or removed): * codegen/pl_codegen.py * widgets/frame/perl_codegen.py * widgets/panel/perl_codegen.py 2003-07-08 Alberto Griggio small bugfixes Files (added, modified or removed): * application.py * edit_sizers/edit_sizers.py * edit_windows.py * widgets/menubar/codegen.py * widgets/radio_box/radio_box.py fixed radio/checkable menu items bug (c++ codegen) Files (added, modified or removed): * widgets/menubar/codegen.py 2003-07-06 crazyinsomniac minor bugfixes Files (added, modified or removed): * widgets/splitter_window/perl_codegen.py 2003-07-05 Alberto Griggio fixed some bugs Files (added, modified or removed): * CHANGES.txt * application.py * codegen/cpp_codegen.py * codegen/py_codegen.py * credits.txt * edit_windows.py 2003-06-30 Alberto Griggio added missing .cvsignore Files (added, modified or removed): * codegen/.cvsignore * docs/.cvsignore * docs/img/.cvsignore * edit_sizers/.cvsignore * icons/gtk/.cvsignore * icons/msw/.cvsignore * widgets/.cvsignore * widgets/bitmap_button/.cvsignore * widgets/button/.cvsignore * widgets/checkbox/.cvsignore * widgets/choice/.cvsignore * widgets/combo_box/.cvsignore * widgets/custom_widget/.cvsignore * widgets/dialog/.cvsignore * widgets/frame/.cvsignore * widgets/gauge/.cvsignore * widgets/grid/.cvsignore * widgets/list_box/.cvsignore * widgets/list_ctrl/.cvsignore * widgets/menubar/.cvsignore * widgets/notebook/.cvsignore * widgets/panel/.cvsignore * widgets/radio_box/.cvsignore * widgets/radio_button/.cvsignore * widgets/slider/.cvsignore * widgets/spacer/.cvsignore * widgets/spin_ctrl/.cvsignore * widgets/splitter_window/.cvsignore * widgets/static_bitmap/.cvsignore * widgets/static_line/.cvsignore * widgets/static_text/.cvsignore * widgets/text_ctrl/.cvsignore * widgets/toggle_button/.cvsignore * widgets/toolbar/.cvsignore * widgets/tree_ctrl/.cvsignore updated .cvsignore Files (added, modified or removed): * .cvsignore * icons/.cvsignore fixed "layout()" bug on 2.4.0 Files (added, modified or removed): * edit_sizers/edit_sizers.py 2003-06-29 Alberto Griggio small tweaks for xhtml compliance Files (added, modified or removed): * docs/tutorial.html 2003-06-28 Alberto Griggio small changes Files (added, modified or removed): * docs/tutorial.html small changes Files (added, modified or removed): * docs/tutorial.html 2003-06-27 Alberto Griggio small tweaks Files (added, modified or removed): * edit_windows.py * widget_properties.py * widgets/list_box/list_box.py * widgets/panel/panel.py 2003-06-27 crazyinsomniac added ScrolledWindow support Files (added, modified or removed): * widgets/panel/perl_codegen.py minor bugfixes Files (added, modified or removed): * codegen/pl_codegen.py 2003-06-26 Alberto Griggio layout() function update Files (added, modified or removed): * edit_sizers/edit_sizers.py added coding conventions info Files (added, modified or removed): * docs/tech_notes.txt first scrolled window support Files (added, modified or removed): * CHANGES.txt * tree.py * widgets/panel/codegen.py * widgets/panel/panel.py 2003-06-26 crazyinsomniac minor bugfixes Files (added, modified or removed): * widgets/frame/perl_codegen.py * widgets/toolbar/perl_codegen.py added a few missing semicolons (thanks Jouke) Files (added, modified or removed): * edit_sizers/perl_sizers_codegen.py 2003-06-25 crazyinsomniac minor fixes, some reformatting Files (added, modified or removed): * edit_sizers/perl_sizers_codegen.py * widgets/bitmap_button/perl_codegen.py * widgets/button/perl_codegen.py * widgets/checkbox/perl_codegen.py * widgets/choice/perl_codegen.py * widgets/combo_box/perl_codegen.py * widgets/frame/perl_codegen.py * widgets/gauge/perl_codegen.py * widgets/grid/perl_codegen.py * widgets/list_box/perl_codegen.py * widgets/list_ctrl/perl_codegen.py * widgets/notebook/perl_codegen.py * widgets/panel/perl_codegen.py * widgets/radio_box/perl_codegen.py * widgets/radio_button/perl_codegen.py * widgets/slider/perl_codegen.py * widgets/spin_ctrl/perl_codegen.py * widgets/splitter_window/perl_codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/static_line/perl_codegen.py * widgets/static_text/perl_codegen.py * widgets/text_ctrl/perl_codegen.py * widgets/toggle_button/perl_codegen.py * widgets/toolbar/perl_codegen.py * widgets/tree_ctrl/perl_codegen.py minor fixes, some reformatting Files (added, modified or removed): * codegen/pl_codegen.py minor fixes, some reformatting Files (added, modified or removed): * codegen/pl_codegen.py 2003-06-24 Alberto Griggio fixed a segfault due to a wxGTK wxRadioBox bug Files (added, modified or removed): * application.py 2003-06-24 crazyinsomniac add_sizeritem cleanup Files (added, modified or removed): * codegen/pl_codegen.py 2003-06-24 Alberto Griggio small tweaks Files (added, modified or removed): * application.py * codegen/py_codegen.py * edit_sizers/edit_sizers.py * edit_windows.py * main.py * misc.py * widgets/notebook/notebook.py 2003-06-24 lawson89 removed some unused debug statements Files (added, modified or removed): * edit_widget.py 2003-06-23 crazyinsomniac *** empty log message *** Files (added, modified or removed): * CHANGES.txt fixed dialog_units statements (apparently they are supported) Files (added, modified or removed): * codegen/pl_codegen.py fixed dialog_units statements (not supported in wxPerl) Files (added, modified or removed): * codegen/pl_codegen.py perl generator -- initial import into cvs Files (added, modified or removed): * codegen/pl_codegen.py * edit_sizers/perl_sizers_codegen.py perl generator -- initial import into cvs Files (added, modified or removed): * widgets/button/perl_codegen.py * widgets/radio_button/perl_codegen.py * widgets/slider/perl_codegen.py * widgets/spacer/perl_codegen.py * widgets/spin_ctrl/perl_codegen.py * widgets/splitter_window/perl_codegen.py * widgets/static_bitmap/perl_codegen.py * widgets/static_line/perl_codegen.py * widgets/static_text/perl_codegen.py * widgets/text_ctrl/perl_codegen.py * widgets/toggle_button/perl_codegen.py * widgets/toolbar/perl_codegen.py * widgets/tree_ctrl/perl_codegen.py perl generator -- initial import into cvs Files (added, modified or removed): * widgets/checkbox/perl_codegen.py * widgets/choice/perl_codegen.py * widgets/combo_box/perl_codegen.py * widgets/custom_widget/perl_codegen.py * widgets/dialog/perl_codegen.py * widgets/frame/perl_codegen.py * widgets/gauge/perl_codegen.py * widgets/grid/perl_codegen.py * widgets/list_box/perl_codegen.py * widgets/list_ctrl/perl_codegen.py * widgets/menubar/perl_codegen.py * widgets/notebook/perl_codegen.py * widgets/panel/perl_codegen.py * widgets/radio_box/perl_codegen.py perl generator -- initial import into cvs Files (added, modified or removed): * widgets/bitmap_button/perl_codegen.py 2003-06-23 lawson89 *** empty log message *** Files (added, modified or removed): * edit_widget.py 2003-06-21 Alberto Griggio fixed a bunch of unicode bugs Files (added, modified or removed): * .cvsignore * CHANGES.txt * application.py * codegen/cpp_codegen.py * common.py * edit_sizers/edit_sizers.py * edit_windows.py * icons/.cvsignore * misc.py * widget_properties.py * widgets/bitmap_button/bitmap_button.py * widgets/button/button.py * widgets/checkbox/checkbox.py * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/custom_widget/custom_widget.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/menubar/menubar.py * widgets/notebook/notebook.py * widgets/radio_box/radio_box.py * widgets/radio_button/radio_button.py * widgets/static_bitmap/static_bitmap.py * widgets/static_text/static_text.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/toggle_button.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py * xml_parse.py * xrc2wxg.py 2003-06-11 Alberto Griggio changed 'Disable()' to 'Enable(0)' in the generated code Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py 2003-06-07 dinogen manual TEX added Files (added, modified or removed): * docs/manual.tex * docs/manual_des.png * docs/manual_main.png * docs/manual_preview.png * docs/manual_prop.png * docs/manual_tree.png 2003-06-02 Alberto Griggio *** empty log message *** Files (added, modified or removed): * CHANGES.txt * common.py ToggleButtonBox Files (added, modified or removed): * main.py 2003-05-24 Alberto Griggio fixed Unicode issue Files (added, modified or removed): * xrc2wxg.py fixed XRC generator (removed 'attribute' property) Files (added, modified or removed): * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py 2003-05-22 Alberto Griggio updated XRC support to latest XRC from CVS Files (added, modified or removed): * widgets/splitter_window/codegen.py * widgets/toolbar/codegen.py local widgets support Files (added, modified or removed): * CHANGES.txt * common.py * config.py * credits.txt 2003-05-20 Alberto Griggio fixed silly bug Files (added, modified or removed): * codegen/xrc_codegen.py 2003-05-19 Alberto Griggio updated information Files (added, modified or removed): * CHANGES.txt * docs/tutorial.html 2003-05-18 Alberto Griggio small fixed (mostly unicode-related) Files (added, modified or removed): * codegen/xrc_codegen.py * widgets/menubar/codegen.py * xml_parse.py * xrc2wxg.py 2003-05-16 Alberto Griggio fixed small bugs Files (added, modified or removed): * main.py * widgets/notebook/codegen.py 2003-05-15 Alberto Griggio last fixes for the upcoming 0.2.3 Files (added, modified or removed): * CHANGES.txt * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * edit_windows.py * icons/sizer.xpm * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/codegen.py * widgets/frame/frame.py * xml_parse.py 2003-05-14 Alberto Griggio small changes Files (added, modified or removed): * common.py * edit_sizers/edit_sizers.py * main.py 2003-05-13 dinogen first write of icon property I have to test Cpp code generation. Files (added, modified or removed): * widgets/frame/codegen.py * widgets/frame/frame.py 2003-05-13 Alberto Griggio small tweaks, and $Id:$ keyword Files (added, modified or removed): * about.py * application.py * clipboard.py * color_dialog.py * common.py * config.py * edit_sizers/edit_sizers.py * edit_windows.py * font_dialog.py * main.py * misc.py * tree.py * widget_properties.py * xrc2wxg.py small tweaks, and $Id:$ keyword Files (added, modified or removed): * CHANGES.txt * README.txt * TODO.txt * application.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * edit_sizers/__init__.py * edit_sizers/sizers_codegen.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/custom_widget/__init__.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/gauge/__init__.py * widgets/gauge/codegen.py * widgets/gauge/gauge.py * widgets/grid/__init__.py * widgets/grid/codegen.py * widgets/grid/grid.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/list_ctrl/__init__.py * widgets/list_ctrl/codegen.py * widgets/list_ctrl/list_ctrl.py * widgets/menubar/__init__.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * widgets/toolbar/__init__.py * widgets/toolbar/codegen.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py * widgets/tree_ctrl/__init__.py * widgets/tree_ctrl/codegen.py * widgets/tree_ctrl/tree_ctrl.py * wxglade.py * xml_parse.py * xrc2wxg.py windows icon Files (added, modified or removed): * icons/wxglade.ico 2003-05-10 Alberto Griggio better custom widget support (and some minor fixes) Files (added, modified or removed): * CHANGES.txt * codegen/xrc_codegen.py * widget_properties.py * widgets/button/button.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/notebook/codegen.py * xrc2wxg.py 2003-05-07 Alberto Griggio added preview support Files (added, modified or removed): * CHANGES.txt * application.py * codegen/py_codegen.py * credits.txt * edit_windows.py * misc.py * widgets/custom_widget/codegen.py * widgets/frame/frame.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py * widgets/toolbar/codegen.py * widgets/toolbar/toolbar.py * xml_parse.py 2003-05-01 Alberto Griggio latest bugfixes before 0.2.2 release Files (added, modified or removed): * codegen/cpp_codegen.py * widgets/notebook/notebook.py * widgets/toolbar/codegen.py * widgets/toolbar/toolbar.py 2003-04-27 Alberto Griggio *** empty log message *** Files (added, modified or removed): * main.py * misc.py fixed small bugs and win32 incompatibilities Files (added, modified or removed): * widgets/frame/frame.py * widgets/notebook/notebook.py * widgets/splitter_window/splitter_window.py * widgets/toolbar/codegen.py * widgets/toolbar/toolbar.py 2003-04-24 Alberto Griggio style property added Files (added, modified or removed): * widgets/static_bitmap/codegen.py toolbar support, some bugfixes and small updates Files (added, modified or removed): * CHANGES.txt * codegen/py_codegen.py * config.py * credits.txt * main.py * widgets/dialog/dialog.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/menubar/menubar.py * widgets/notebook/notebook.py * widgets/panel/panel.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/static_bitmap.py * widgets/widgets.txt * xrc2wxg.py first toolbar support Files (added, modified or removed): * icons/toolbar.xpm * widgets/toolbar/__init__.py * widgets/toolbar/codegen.py * widgets/toolbar/tool.py * widgets/toolbar/toolbar.py updated credits and about box Files (added, modified or removed): * about.py * credits.txt bug fixes and new "virtual sizers" support Files (added, modified or removed): * CHANGES.txt * credits.txt * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_windows.py * main.py * tree.py * widgets/custom_widget/custom_widget.py * widgets/list_ctrl/list_ctrl.py * widgets/notebook/notebook.py * widgets/panel/panel.py * widgets/splitter_window/splitter_window.py * widgets/tree_ctrl/tree_ctrl.py * xml_parse.py 2003-04-23 Alberto Griggio new "virtual sizers" support Files (added, modified or removed): * widgets/panel/__init__.py 2003-04-22 Alberto Griggio fixed bug in __set_properties code generation Files (added, modified or removed): * codegen/py_codegen.py 2003-04-18 Alberto Griggio updated credits Files (added, modified or removed): * credits.txt fix for "bug" #723115 Files (added, modified or removed): * codegen/cpp_codegen.py 2003-04-17 Alberto Griggio new preferences and some bugfixes/tweaks Files (added, modified or removed): * CHANGES.txt * common.py * config.py * credits.txt * edit_sizers/edit_sizers.py * main.py * misc.py * widgets/custom_widget/custom_widget.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/menubar/menubar.py 2003-04-13 Alberto Griggio added support for radio menu items Files (added, modified or removed): * widgets/MenuTree.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py 2003-04-10 Alberto Griggio fixed bug #717863 Files (added, modified or removed): * codegen/py_codegen.py fixed bug #717595 Files (added, modified or removed): * main.py 2003-04-03 Alberto Griggio standalone menubar support Files (added, modified or removed): * widgets/menubar/__init__.py * widgets/menubar/codegen.py * widgets/menubar/menubar.py changed code generation API Files (added, modified or removed): * CHANGES.txt * codegen/cpp_codegen.py * codegen/py_codegen.py * common.py * edit_sizers/sizers_codegen.py * edit_windows.py * tree.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/custom_widget/codegen.py * widgets/dialog/codegen.py * widgets/widgets.txt * xrc2wxg.py changed code generation API Files (added, modified or removed): * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/gauge/codegen.py * widgets/grid/codegen.py * widgets/list_box/codegen.py * widgets/list_ctrl/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spacer/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py * widgets/tree_ctrl/codegen.py 2003-03-25 Alberto Griggio fixed grid selection mode bug Files (added, modified or removed): * edit_windows.py * widget_properties.py * widgets/grid/grid.py 2003-03-23 Alberto Griggio fixed small bug in (title property) Files (added, modified or removed): * widgets/radio_box/radio_box.py 2003-03-21 dinogen variable "prefix" used Files (added, modified or removed): * widgets/static_bitmap/codegen.py 2003-03-21 Alberto Griggio fixed small bugs in some property getter/setter Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py * widgets/radio_button/radio_button.py * widgets/spin_ctrl/spin_ctrl.py * widgets/static_bitmap/static_bitmap.py * widgets/toggle_button/toggle_button.py fixed bugs due to incorrect bool casts Files (added, modified or removed): * application.py * edit_windows.py * widgets/bitmap_button/bitmap_button.py * widgets/button/button.py * widgets/grid/grid.py 2003-03-20 Alberto Griggio fixed small layout bugs Files (added, modified or removed): * widgets/dialog/dialog.py * widgets/grid/grid.py fixed bug #706890 Files (added, modified or removed): * CHANGES.txt * edit_windows.py 2003-03-16 Alberto Griggio small changes Files (added, modified or removed): * codegen/cpp_codegen.py 2003-03-15 Alberto Griggio fixed small bugs Files (added, modified or removed): * CHANGES.txt * edit_windows.py * widgets/frame/frame.py 2003-03-14 Alberto Griggio added config.preferences.buttons_per_row Files (added, modified or removed): * CHANGES.txt * config.py * main.py 2003-03-11 Alberto Griggio added first (basic) support for wxListCtrl and wxTreeCtrl Files (added, modified or removed): * CHANGES.txt added wxTAB_TRAVERSAL style to scrolled wins that display properties Files (added, modified or removed): * application.py * edit_sizers/edit_sizers.py * edit_windows.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/gauge/gauge.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/notebook/notebook.py * widgets/slider/slider.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/splitter_window.py * widgets/text_ctrl/text_ctrl.py * widgets/widgets.txt wxTreeCtrl support Files (added, modified or removed): * icons/tree_ctrl.xpm * widgets/tree_ctrl/__init__.py * widgets/tree_ctrl/codegen.py * widgets/tree_ctrl/tree_ctrl.py wxListCtrl support Files (added, modified or removed): * icons/list_ctrl.xpm * widgets/list_ctrl/__init__.py * widgets/list_ctrl/codegen.py * widgets/list_ctrl/list_ctrl.py 2003-03-10 Alberto Griggio fixed bugs (see CHANGES.txt) Files (added, modified or removed): * CHANGES.txt * widget_properties.py * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/custom_widget/custom_widget.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/notebook/notebook.py * widgets/radio_box/radio_box.py 2003-03-09 Alberto Griggio converted true/false to True/False Files (added, modified or removed): * wxPyColourChooser/pycolourbox.py * wxPyColourChooser/pycolourchooser.py 2003-03-08 Alberto Griggio fixed bug in the codegen modules (class decl regex) Files (added, modified or removed): * CHANGES.txt * codegen/cpp_codegen.py * codegen/py_codegen.py fixed bug in wxPython 2.4.0.2's wxSizer.Insert Files (added, modified or removed): * main.py * misc.py 2003-03-06 Alberto Griggio bugfixes and improved performance and resources usage of the various properties Files (added, modified or removed): * CHANGES.txt * color_dialog.py * edit_sizers/edit_sizers.py * edit_windows.py * font_dialog.py * main.py * misc.py * widget_properties.py 2003-03-05 Alberto Griggio experimental bugfixes for bugs 698071 and 698074 Files (added, modified or removed): * widgets/frame/frame.py 2003-03-03 Alberto Griggio Added info about broken PyXML Files (added, modified or removed): * README.txt 2003-02-26 Alberto Griggio commented out traceback print Files (added, modified or removed): * wxglade.py 2003-02-22 Alberto Griggio *** empty log message *** Files (added, modified or removed): * widget_properties.py fixed bug in set_size when use_dialog_units preference is set Files (added, modified or removed): * edit_windows.py fixed bug in right_click handler Files (added, modified or removed): * tree.py fixed bug in set_size when use_dialog_units preference is set Files (added, modified or removed): * edit_windows.py 2003-02-19 Alberto Griggio fixed incompatibilities with python 2.3 due to new bool behaviour Files (added, modified or removed): * config.py * tree.py * widget_properties.py 2003-02-17 Alberto Griggio minor layout tweaks for win32 Files (added, modified or removed): * application.py * widget_properties.py 2003-02-16 Alberto Griggio fixed bug: 'create_grid' property not saved correctly Files (added, modified or removed): * widgets/grid/grid.py 2003-02-14 Alberto Griggio slightly improved error messages Files (added, modified or removed): * application.py * tree.py * xml_parse.py slightly improved error messages Files (added, modified or removed): * CHANGES.txt * application.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * main.py * tree.py * xml_parse.py 2003-02-12 Alberto Griggio fixed bug #685264 Files (added, modified or removed): * widgets/notebook/notebook.py * widgets/splitter_window/splitter_window.py 2003-02-02 Alberto Griggio *** empty log message *** Files (added, modified or removed): * CHANGES.txt 2003-01-30 Alberto Griggio fixed bug in *Pane.GetBestSize Files (added, modified or removed): * widgets/notebook/notebook.py * widgets/splitter_window/splitter_window.py 2003-01-27 Alberto Griggio updated changelog Files (added, modified or removed): * CHANGES.txt fixed bug in multi-files code generation Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py fixed some typos Files (added, modified or removed): * docs/tutorial.html 2003-01-26 Alberto Griggio updated information and fixed typos Files (added, modified or removed): * docs/tutorial.html *** empty log message *** Files (added, modified or removed): * config.py update copyright notice Files (added, modified or removed): * README.txt * about.py * application.py * clipboard.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * config.py * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * edit_windows.py * license.txt * main.py * misc.py * tree.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/custom_widget/__init__.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/gauge/__init__.py * widgets/gauge/codegen.py * widgets/gauge/gauge.py * widgets/grid/__init__.py * widgets/grid/codegen.py * widgets/grid/grid.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * wxglade.py * xml_parse.py * xrc2wxg.py small changes before v0.1.2 Files (added, modified or removed): * CHANGES.txt * common.py * wxglade.py 2003-01-24 Alberto Griggio fixed wxPython 2.4.0.2 incompatibility causing segfault at startup Files (added, modified or removed): * widget_properties.py 2003-01-20 Alberto Griggio fixed serious bug introduced after v0.2 Files (added, modified or removed): * codegen/cpp_codegen.py 2003-01-19 Alberto Griggio better paths handling (now it should be OK to execute from any dir) Files (added, modified or removed): * common.py * edit_sizers/edit_sizers.py * main.py * tree.py * widgets/dialog/dialog.py * widgets/frame/frame.py * widgets/notebook/notebook.py * widgets/panel/panel.py * widgets/splitter_window/splitter_window.py * wxglade.py some code cleanups Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/dialog/codegen.py * widgets/gauge/codegen.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py 2003-01-17 dinogen changed comment Files (added, modified or removed): * widgets/grid/__init__.py 2003-01-03 Alberto Griggio fix (?) for a win-specific bug (#661123) Files (added, modified or removed): * widgets/static_bitmap/static_bitmap.py various tweaks to code generation: - customizable automatic backup - gettext support - "local" widgets Files (added, modified or removed): * CHANGES.txt * application.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * config.py * edit_sizers/sizers_codegen.py * main.py * tree.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/dialog/codegen.py * widgets/frame/codegen.py * widgets/grid/codegen.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py * wxglade.py * xml_parse.py 2002-12-28 Alberto Griggio platform-specific bugfixes and improvements Files (added, modified or removed): * CHANGES.txt * edit_sizers/edit_sizers.py * edit_windows.py 2002-12-27 Alberto Griggio information updated Files (added, modified or removed): * README.txt workaround to avoid some segfaults on GTK Files (added, modified or removed): * widgets/frame/frame.py some corrections Files (added, modified or removed): * docs/tutorial.html 2002-12-26 Alberto Griggio more notes added Files (added, modified or removed): * docs/tutorial.html 2002-12-25 Alberto Griggio more bugs fixed Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py * edit_sizers/edit_sizers.py * widgets/notebook/codegen.py * widgets/splitter_window/codegen.py * wxglade.py 2002-12-24 Alberto Griggio fixed bug in get_property_handler caused by a typo Files (added, modified or removed): * widgets/custom_widget/custom_widget.py * widgets/grid/grid.py * widgets/notebook/notebook.py fixed typo Files (added, modified or removed): * CHANGES.txt 2002-12-23 Alberto Griggio fixed bug impacting XRC output Files (added, modified or removed): * widgets/static_text/static_text.py better error messages Files (added, modified or removed): * CHANGES.txt * application.py * main.py 2002-12-21 Alberto Griggio fixed bug in get_property_handler Files (added, modified or removed): * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/custom_widget/custom_widget.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/notebook/notebook.py * widgets/radio_box/radio_box.py 2002-12-20 Alberto Griggio fixed bugs and/or wx 2.3.4 incompatibilities Files (added, modified or removed): * application.py * main.py * misc.py * widget_properties.py * widgets/choice/choice.py * widgets/combo_box/combo_box.py * widgets/gauge/gauge.py * widgets/grid/grid.py * widgets/list_box/list_box.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py 2002-12-19 Alberto Griggio c++ code generation and some tweaks Files (added, modified or removed): * widgets/grid/codegen.py * widgets/grid/grid.py small bugfix Files (added, modified or removed): * widget_properties.py 2002-12-18 dinogen codegen for wxgrid added Files (added, modified or removed): * widgets/grid/codegen.py * widgets/grid/grid.py 2002-12-16 Alberto Griggio small improvements Files (added, modified or removed): * config.py * widget_properties.py * widgets/notebook/codegen.py 2002-12-15 Alberto Griggio fixed path-related bug Files (added, modified or removed): * about.py * main.py fixed wxPython 2.3.2.1 incompatibility Files (added, modified or removed): * widgets/splitter_window/splitter_window.py 2002-12-14 Alberto Griggio *** empty log message *** Files (added, modified or removed): * docs/img/custom_widget.gif * docs/img/sizer_slot.gif tutorial updated Files (added, modified or removed): * CHANGES.txt * docs/tutorial.html automatically add a sizer to a frame Files (added, modified or removed): * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * widgets/frame/frame.py fixed help string Files (added, modified or removed): * wxglade.py 2002-12-11 Alberto Griggio added insert_row and insert_col to grid sizers Files (added, modified or removed): * edit_sizers/edit_sizers.py better handling of renames during paste Files (added, modified or removed): * xml_parse.py fixed some minor bugs Files (added, modified or removed): * about.py * common.py * misc.py * widget_properties.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * wxglade.py fixed potential sys.path problem Files (added, modified or removed): * wxglade.py 2002-12-10 Alberto Griggio fixed bug on load_bitmap Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py implemented "escaping" from text properties to undo changes Files (added, modified or removed): * widget_properties.py safer _save_app Files (added, modified or removed): * main.py merged Files (added, modified or removed): * common.py SetSizeHints code generation Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py fixed bug on win32 Files (added, modified or removed): * color_dialog.py 2002-12-10 dinogen oops, an stupid error slops to me Files (added, modified or removed): * widgets/grid/grid.py Added columns property Files (added, modified or removed): * widgets/grid/codegen.py * widgets/grid/grid.py smart_split function moved. Files (added, modified or removed): * common.py * misc.py 2002-12-08 Alberto Griggio "fixed" code generation bugs when a container class is renamed (and we're in single file mode) Files (added, modified or removed): * codegen/py_codegen.py "fixed" code generation bugs when a container class is renamed (and we're in single file mode) Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py bug fixes Files (added, modified or removed): * CHANGES.txt * application.py * docs/tutorial.html * edit_sizers/edit_sizers.py updated credits Files (added, modified or removed): * about.py * credits.txt fixed sys.path bug Files (added, modified or removed): * wxglade.py changes due to new color and font properties Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * edit_windows.py * misc.py * widget_properties.py new font dialog Files (added, modified or removed): * font_dialog.py new color chooser dialog Files (added, modified or removed): * color_dialog.py wxPyColourChooser module by Michael Gilfix Files (added, modified or removed): * wxPyColourChooser/__init__.py * wxPyColourChooser/canvas.py * wxPyColourChooser/intl.py * wxPyColourChooser/license/lgpl.txt * wxPyColourChooser/license/wxwindowslib.txt * wxPyColourChooser/pycolourbox.py * wxPyColourChooser/pycolourchooser.py * wxPyColourChooser/pycolourslider.py * wxPyColourChooser/pypalette.py bug fixes Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py * widgets/button/button.py * widgets/combo_box/combo_box.py * widgets/notebook/codegen.py 2002-12-04 Alberto Griggio small bugfixes Files (added, modified or removed): * widgets/list_box/list_box.py * widgets/radio_box/radio_box.py fixed wxPanel style-related bugs that caused segfaults on win Files (added, modified or removed): * widgets/notebook/notebook.py * widgets/splitter_window/splitter_window.py fixed style bug Files (added, modified or removed): * widgets/panel/panel.py 2002-12-03 Alberto Griggio fixed bug that caused a SEGFAULT on win Files (added, modified or removed): * widgets/combo_box/combo_box.py * widgets/panel/panel.py * widgets/spin_ctrl/spin_ctrl.py 2002-12-03 dinogen columns names ok Files (added, modified or removed): * misc.py * widgets/grid/codegen.py * widgets/grid/grid.py 2002-12-02 Alberto Griggio added autosave/backup to the TODO Files (added, modified or removed): * TODO.txt fixed bugs Files (added, modified or removed): * main.py * tree.py * widget_properties.py * widgets/combo_box/combo_box.py 2002-12-01 Alberto Griggio fixed bug that caused segfaults occasionally Files (added, modified or removed): * widgets/notebook/notebook.py fixed bug in set_style Files (added, modified or removed): * widgets/combo_box/combo_box.py custom classes support Files (added, modified or removed): * xrc2wxg.py better icon Files (added, modified or removed): * icons/custom.xpm 2002-11-30 Alberto Griggio bux fixes (again :) Files (added, modified or removed): * edit_sizers/edit_sizers.py * widget_properties.py * widgets/checkbox/checkbox.py * widgets/radio_button/radio_button.py fixed bug on change_node_pos Files (added, modified or removed): * tree.py added option to disable progress dialog on loading Files (added, modified or removed): * config.py * main.py fixed bugs Files (added, modified or removed): * widgets/panel/panel.py * xrc2wxg.py fixed bug on SetItemMinSize when w or h are -1 Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py 2002-11-29 Alberto Griggio fixed resizing bug Files (added, modified or removed): * widgets/panel/panel.py made loading a wxg file more permissive Files (added, modified or removed): * xml_parse.py renamed xrc_import.py to xrc2wxg.py Files (added, modified or removed): * xrc2wxg.py * xrc_import.py 2002-11-28 Alberto Griggio first EXPERIMENTAL and probably BROKEN xrc to wxg converter Files (added, modified or removed): * xrc_import.py better wxFileHistory support Files (added, modified or removed): * main.py fixed menubar-related bugs Files (added, modified or removed): * widgets/frame/frame.py fixed tab ordering in GridProperty buttons Files (added, modified or removed): * widget_properties.py 2002-11-27 Alberto Griggio fixed bug on EditFrame.get_property_handler.MenuHandler Files (added, modified or removed): * widgets/frame/frame.py fixed bug on change_node_pos Files (added, modified or removed): * tree.py fixed bug on set_item_pos Files (added, modified or removed): * CHANGES.txt * edit_sizers/edit_sizers.py fixed some small bugs Files (added, modified or removed): * README.txt * edit_sizers/edit_sizers.py * edit_windows.py * widgets/grid/codegen.py * widgets/grid/grid.py 2002-11-26 Alberto Griggio some small fixes Files (added, modified or removed): * misc.py * widget_properties.py * widgets/grid/codegen.py * widgets/grid/grid.py added credits to Marcello Files (added, modified or removed): * about.py changed some code-generation details Files (added, modified or removed): * CHANGES.txt * codegen/py_codegen.py * common.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/dialog/codegen.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/gauge/codegen.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py * widgets/widgets.txt * xml_parse.py 2002-11-26 dinogen added selection property Files (added, modified or removed): * widgets/grid/codegen.py * widgets/grid/grid.py grid label bg color property Files (added, modified or removed): * widgets/grid/codegen.py * widgets/grid/grid.py Fixed VERY STUPID error in lines color Files (added, modified or removed): * widgets/grid/codegen.py Grid lines colors, but code generation isn't ok yet. Files (added, modified or removed): * widgets/grid/codegen.py 2002-11-22 dinogen grid lines color added Files (added, modified or removed): * widgets/grid/grid.py added resizing properties Files (added, modified or removed): * widgets/grid/codegen.py * widgets/grid/grid.py extra module added for wxGrid Files (added, modified or removed): * widgets/widgets.txt extra module added for wxGrid Files (added, modified or removed): * widgets/grid/codegen.py 2002-11-21 Alberto Griggio some bugs fixed Files (added, modified or removed): * codegen/py_codegen.py * main.py * widgets/frame/frame.py * widgets/notebook/notebook.py 2002-11-21 dinogen icon added for grid widget Files (added, modified or removed): * icons/grid.xpm The grid module added Files (added, modified or removed): * widgets/grid/__init__.py * widgets/grid/codegen.py * widgets/grid/grid.py 2002-11-19 Alberto Griggio fixed bug on relative paths Files (added, modified or removed): * main.py * wxglade.py wxGauge support Files (added, modified or removed): * icons/gauge.xpm * widgets/gauge/__init__.py * widgets/gauge/codegen.py * widgets/gauge/gauge.py * widgets/widgets.txt fixed bugs Files (added, modified or removed): * TODO.txt * icons/slider.xpm * widgets/custom_widget/custom_widget.py * widgets/slider/codegen.py 2002-11-17 Alberto Griggio added import_modules argument to add_widget_handler Files (added, modified or removed): * CHANGES.txt * codegen/py_codegen.py 2002-11-12 Alberto Griggio change of license (MIT) to avoid troubles Files (added, modified or removed): * CHANGES.txt * README.txt * about.py * application.py * clipboard.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * config.py * credits.txt * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * edit_windows.py * license.txt * main.py * misc.py * tree.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/custom_widget/__init__.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * wxglade.py * xml_parse.py 2002-11-09 Alberto Griggio support for wxFileHistory on wxPython >= 2.3.3 Files (added, modified or removed): * CHANGES.txt * config.py * main.py * misc.py 2002-11-03 Alberto Griggio keyboard shortcuts for popup menus almost working Files (added, modified or removed): * CHANGES.txt * edit_sizers/edit_sizers.py * edit_windows.py * misc.py * tree.py some bugs fixed Files (added, modified or removed): * widgets/bitmap_button/bitmap_button.py * widgets/panel/panel.py * widgets/static_bitmap/static_bitmap.py 2002-10-28 Alberto Griggio fixed C++ code generation bug Files (added, modified or removed): * widgets/panel/codegen.py added style property Files (added, modified or removed): * widgets/notebook/notebook.py * widgets/splitter_window/splitter_window.py custom widgets support Files (added, modified or removed): * CHANGES.txt * icons/custom.xpm * widgets/custom_widget/__init__.py * widgets/custom_widget/codegen.py * widgets/custom_widget/custom_widget.py * widgets/widgets.txt fixed bug regarding notebook sizers Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py fixed bug regarding encoding in CodeWriter Files (added, modified or removed): * xml_parse.py fixed bug in on_set_focus Files (added, modified or removed): * edit_windows.py 2002-10-26 Alberto Griggio simplified check_wx_version Files (added, modified or removed): * misc.py fixed xrc code generation bug (usenotebooksizer) Files (added, modified or removed): * CHANGES.txt * widgets/notebook/codegen.py 2002-10-25 Alberto Griggio fixed bug when the output file exists but it doesn't contain any class Files (added, modified or removed): * codegen/cpp_codegen.py fixed bug when the output file exists but it doesn't contain any class Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py fixed bug concerning renaming of toplevel widgets Files (added, modified or removed): * application.py * edit_windows.py 2002-10-24 Alberto Griggio added encoding property to Application objects Files (added, modified or removed): * CHANGES.txt * application.py * common.py * edit_windows.py * tree.py * widget_properties.py * xml_parse.py some layout tweaks Files (added, modified or removed): * main.py new EditTopLevelPanel class, to create panels without a container frame/dialog Files (added, modified or removed): * widgets/dialog/dialog.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py 2002-10-22 Alberto Griggio preferences icon Files (added, modified or removed): * icons/gtk/prefs.xpm * icons/msw/prefs.xpm changes to allow user preferences Files (added, modified or removed): * CHANGES.txt * application.py * config.py * edit_sizers/edit_sizers.py * edit_windows.py * main.py * misc.py 2002-10-20 Alberto Griggio lazy initialization of popup menus Files (added, modified or removed): * edit_sizers/edit_sizers.py * edit_windows.py * misc.py added icons for menu items and keyboard shortcuts for popup menus (not on GTK yet) Files (added, modified or removed): * CHANGES.txt * edit_sizers/edit_sizers.py * edit_windows.py * main.py * misc.py icons for menu items Files (added, modified or removed): * icons/gtk/about.xpm * icons/gtk/copy.xpm * icons/gtk/cut.xpm * icons/gtk/exit.xpm * icons/gtk/generate.xpm * icons/gtk/new.xpm * icons/gtk/open.xpm * icons/gtk/paste.xpm * icons/gtk/remove.xpm * icons/gtk/save.xpm * icons/gtk/save_as.xpm * icons/gtk/tutorial.xpm * icons/msw/copy.xpm * icons/msw/cut.xpm * icons/msw/exit.xpm * icons/msw/generate.xpm * icons/msw/new.xpm * icons/msw/open.xpm * icons/msw/paste.xpm * icons/msw/remove.xpm * icons/msw/save.xpm * icons/msw/save_as.xpm * icons/msw/tutorial.xpm added style property Files (added, modified or removed): * widgets/panel/codegen.py * widgets/panel/panel.py 2002-10-19 Alberto Griggio *** empty log message *** Files (added, modified or removed): * CHANGES.txt some layout tweaks Files (added, modified or removed): * about.py * main.py updated contents to mention new layout features (change of sizer type, change of position inside a sizer) Files (added, modified or removed): * docs/tutorial.html fixed 'style' property bug Files (added, modified or removed): * widgets/splitter_window/splitter_window.py added 'style' property Files (added, modified or removed): * widgets/panel/codegen.py * widgets/panel/panel.py added 'multiline' option to TextProperty Files (added, modified or removed): * widget_properties.py * widgets/static_text/static_text.py * widgets/text_ctrl/text_ctrl.py fixed win32 bug Files (added, modified or removed): * widgets/dialog/dialog.py 2002-10-14 Alberto Griggio small fixes Files (added, modified or removed): * edit_sizers/edit_sizers.py * tree.py * widget_properties.py 2002-10-13 Alberto Griggio fixed 2.3.3 compatibility Files (added, modified or removed): * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py fixed segfault (why?) on win32 Files (added, modified or removed): * widgets/combo_box/combo_box.py added check_wx_version function Files (added, modified or removed): * application.py * main.py * misc.py * widget_properties.py fixed bug on change_sizer Files (added, modified or removed): * edit_sizers/edit_sizers.py 2002-10-12 Alberto Griggio fixed bug on SizerBase.change_item_pos Files (added, modified or removed): * edit_sizers/edit_sizers.py change_item_pos: added Refresh() call on Win32 Files (added, modified or removed): * edit_sizers/edit_sizers.py added 'pos' property to change the position of a widget inside its sizer Files (added, modified or removed): * CHANGES.txt * TODO.txt * edit_sizers/edit_sizers.py * edit_windows.py * tree.py 2002-10-10 Alberto Griggio - added possibility to dynamically change the type of a sizer - some bugs fixed Files (added, modified or removed): * CHANGES.txt * TODO.txt * edit_sizers/edit_sizers.py * edit_windows.py * main.py * tree.py * widget_properties.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/button.py * widgets/button/codegen.py * widgets/dialog/dialog.py * widgets/spacer/spacer.py 2002-10-06 Alberto Griggio first CVS version Files (added, modified or removed): * docs/img/box_sizer_button.gif * docs/img/button_button.gif * docs/img/frame_button.gif * docs/img/notebook_button.gif * docs/img/spacer_button.gif * docs/img/text_ctrl_button.gif * docs/tutorial.html various bugs fixed. See CHANGES.txt Files (added, modified or removed): * application.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * edit_sizers/edit_sizers.py * edit_windows.py * main.py * widget_properties.py * widgets/bitmap_button/codegen.py * widgets/notebook/notebook.py * widgets/slider/slider.py * widgets/splitter_window/splitter_window.py * widgets/static_line/static_line.py new wxGlade logo Files (added, modified or removed): * about.py *** empty log message *** Files (added, modified or removed): * CHANGES.txt 2002-09-07 Alberto Griggio added wxGlade logo Files (added, modified or removed): * about.py updated the TODO list Files (added, modified or removed): * TODO.txt fixed a couple of minor win32 bugs, changed the style of tree_frame and property_frame Files (added, modified or removed): * common.py * main.py * tree.py wxGlade logo Files (added, modified or removed): * icons/wxglade_small.png 2002-09-02 Alberto Griggio new license (Python 2.2) Files (added, modified or removed): * README.txt *** empty log message *** Files (added, modified or removed): * edit_sizers.py * widgets/frame.py merged version 0.1.3 Files (added, modified or removed): * CHANGES.txt * TODO.txt * about.py * application.py * clipboard.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * credits.txt * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * edit_windows.py * icons/application.xpm * license.txt * main.py * misc.py * tree.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/checkbox.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/dialog.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/list_box.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/notebook.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_ctrl.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * wxglade.py * xml_parse.py new license (Python 2.2) Files (added, modified or removed): * CHANGES.txt * README.txt * about.py * application.py * clipboard.py * codegen/cpp_codegen.py * codegen/py_codegen.py * codegen/xrc_codegen.py * common.py * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * edit_windows.py * main.py * misc.py * tree.py * widget_properties.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * wxglade.py * xml_parse.py small change to the C++ code generator Files (added, modified or removed): * widgets/radio_box/codegen.py new license (Python 2.2) Files (added, modified or removed): * README.txt * license.txt 2002-08-27 Alberto Griggio updated with TabOrder Files (added, modified or removed): * TODO.txt bugs fixed Files (added, modified or removed): * CHANGES.txt * edit_sizers/sizers_codegen.py * widgets/dialog/dialog.py * widgets/frame/frame.py fixed bug on code generation for container widgets Files (added, modified or removed): * codegen/py_codegen.py fixed bug on C++ id code generation Files (added, modified or removed): * codegen/cpp_codegen.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py 2002-08-26 Alberto Griggio changed code generation to initialize widgets in the right order, so as to preserve the tab traversal order Files (added, modified or removed): * CHANGES.txt changed code generation to initialize widgets in the right order, so as to preserve the tab traversal order Files (added, modified or removed): * codegen/cpp_codegen.py * codegen/py_codegen.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/frame/codegen.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py * xml_parse.py 2002-08-16 Alberto Griggio some bugs fixed Files (added, modified or removed): * about.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * main.py * widgets/spacer/spacer.py updated credits Files (added, modified or removed): * credits.txt some bugs fixed Files (added, modified or removed): * common.py * edit_windows.py * wxglade.py experimental C++ code generator Files (added, modified or removed): * codegen/cpp_codegen.py * edit_sizers/sizers_codegen.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py 2002-08-15 Alberto Griggio tooltips and dialog units support Files (added, modified or removed): * codegen/py_codegen.py * edit_windows.py * main.py * wxglade.py experimental C++ code generator and other things Files (added, modified or removed): * CHANGES.txt experimental C++ code generator Files (added, modified or removed): * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spacer/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py 2002-08-12 Alberto Griggio support for dialog units and other stuff Files (added, modified or removed): * CHANGES.txt * application.py * codegen/py_codegen.py * codegen/xrc_codegen.py * edit_sizers/edit_sizers.py * edit_windows.py * main.py * widget_properties.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/frame/codegen.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py * xml_parse.py 2002-08-10 Alberto Griggio new icon Files (added, modified or removed): * icons/application.xpm better python code generation Files (added, modified or removed): * CHANGES.txt * TODO.txt * codegen/py_codegen.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/frame/codegen.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/panel/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_line/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/codegen.py bugfixes Files (added, modified or removed): * codegen/xrc_codegen.py bugfixes Files (added, modified or removed): * main.py * xml_parse.py 2002-08-06 Alberto Griggio fixed bug regarding style on GTK Files (added, modified or removed): * widgets/text_ctrl/text_ctrl.py experimental (but apparently working) XRC code generator Files (added, modified or removed): * CHANGES.txt * codegen/xrc_codegen.py * widgets/ChoicesCodeHandler.py * widgets/choice/codegen.py * widgets/combo_box/codegen.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/list_box/codegen.py * widgets/notebook/codegen.py * widgets/radio_box/codegen.py * widgets/slider/codegen.py * widgets/spin_ctrl/codegen.py * widgets/splitter_window/codegen.py mainly bugfixes Files (added, modified or removed): * application.py * codegen/py_codegen.py * edit_sizers/edit_sizers.py * license.txt * main.py * tree.py * widget_properties.py * wxglade.py * xml_parse.py 2002-08-04 Alberto Griggio bugfix in EditFlexGridSizer Files (added, modified or removed): * edit_sizers.py MANY bugs fixed Files (added, modified or removed): * edit_sizers/edit_sizers.py MANY bugs fixed Files (added, modified or removed): * edit_sizers.py made sizers local to the __do_layout method Files (added, modified or removed): * codegen/py_codegen.py various bugs fixed Files (added, modified or removed): * CHANGES.txt * README.txt * TODO.txt * about.py * application.py * common.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * main.py * widget_properties.py * widgets/MenuTree.py * widgets/bitmap_button/codegen.py * widgets/button/codegen.py * widgets/checkbox/codegen.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/notebook/codegen.py * widgets/radio_box/codegen.py * widgets/radio_button/codegen.py * widgets/static_bitmap/codegen.py * widgets/static_text/codegen.py * widgets/text_ctrl/codegen.py * widgets/toggle_button/codegen.py * wxglade.py * xml_parse.py 2002-08-03 Alberto Griggio *** empty log message *** Files (added, modified or removed): * icons/source.jpg renamed README to README.txt Files (added, modified or removed): * README * README.txt removed Files (added, modified or removed): * icons/source.jpg credits to various people Files (added, modified or removed): * credits.txt renamed README to README.txt Files (added, modified or removed): * README * README.txt removed from v0-1-3devel branch Files (added, modified or removed): * edit_sizers.py fixed just introduced wxPython 2.3.2.1 incompatibility Files (added, modified or removed): * widget_properties.py fixed just introduced wxPython 2.3.2.1 incompatibility Files (added, modified or removed): * application.py * widget_properties.py removed from v0-1-3devel branch Files (added, modified or removed): * widgets/bitmap_button.py * widgets/button.py * widgets/checkbox.py * widgets/choice.py * widgets/combo_box.py * widgets/dialog.py * widgets/frame.py * widgets/list_box.py * widgets/notebook.py * widgets/panel.py * widgets/radio_box.py * widgets/radio_button.py * widgets/slider.py * widgets/spacer.py * widgets/spin_ctrl.py * widgets/splitter_window.py * widgets/static_bitmap.py * widgets/static_line.py * widgets/static_text.py * widgets/text_ctrl.py * widgets/toggle_button.py fixed wxPython 2.3.3 incompatibilities Files (added, modified or removed): * codegen/py_codegen.py * widget_properties.py v0-1-3devel branch Files (added, modified or removed): * CHANGES.txt * application.py * codegen/py_codegen.py * common.py * edit_sizers/__init__.py * edit_sizers/edit_sizers.py * edit_sizers/sizers_codegen.py * edit_windows.py * main.py * misc.py * tree.py * widgets/ChoicesCodeHandler.py * widgets/ChoicesProperty.py * widgets/MenuTree.py * widgets/bitmap_button/__init__.py * widgets/bitmap_button/bitmap_button.py * widgets/bitmap_button/codegen.py * widgets/button/__init__.py * widgets/button/button.py * widgets/button/codegen.py * widgets/checkbox/__init__.py * widgets/checkbox/checkbox.py * widgets/checkbox/codegen.py * widgets/choice/__init__.py * widgets/choice/choice.py * widgets/choice/codegen.py * widgets/combo_box/__init__.py * widgets/combo_box/codegen.py * widgets/combo_box/combo_box.py * widgets/dialog/__init__.py * widgets/dialog/codegen.py * widgets/dialog/dialog.py * widgets/frame/__init__.py * widgets/frame/codegen.py * widgets/frame/frame.py * widgets/list_box/__init__.py * widgets/list_box/codegen.py * widgets/list_box/list_box.py * widgets/notebook/__init__.py * widgets/notebook/codegen.py * widgets/notebook/notebook.py * widgets/panel/__init__.py * widgets/panel/codegen.py * widgets/panel/panel.py * widgets/radio_box/__init__.py * widgets/radio_box/codegen.py * widgets/radio_box/radio_box.py * widgets/radio_button/__init__.py * widgets/radio_button/codegen.py * widgets/radio_button/radio_button.py * widgets/slider/__init__.py * widgets/slider/codegen.py * widgets/slider/slider.py * widgets/spacer/__init__.py * widgets/spacer/codegen.py * widgets/spacer/spacer.py * widgets/spin_ctrl/__init__.py * widgets/spin_ctrl/codegen.py * widgets/spin_ctrl/spin_ctrl.py * widgets/splitter_window/__init__.py * widgets/splitter_window/codegen.py * widgets/splitter_window/splitter_window.py * widgets/static_bitmap/__init__.py * widgets/static_bitmap/codegen.py * widgets/static_bitmap/static_bitmap.py * widgets/static_line/__init__.py * widgets/static_line/codegen.py * widgets/static_line/static_line.py * widgets/static_text/__init__.py * widgets/static_text/codegen.py * widgets/static_text/static_text.py * widgets/text_ctrl/__init__.py * widgets/text_ctrl/codegen.py * widgets/text_ctrl/text_ctrl.py * widgets/toggle_button/__init__.py * widgets/toggle_button/codegen.py * widgets/toggle_button/toggle_button.py * wxglade.py * xml_parse.py fixed wxPython 2.3.3 incompatibilities Files (added, modified or removed): * CHANGES.txt * codegen/py_codegen.py * edit_sizers.py * edit_windows.py * main.py * widget_properties.py * widgets/frame.py 2002-08-03 repo convert creating branch v0-1-3devel from HEAD Files (added, modified or removed): 2002-08-02 Alberto Griggio experimental bugfix for menubar-related segfaults on GTK Files (added, modified or removed): * widgets/frame.py 2002-08-01 Alberto Griggio first version on cvs Files (added, modified or removed): * README various bugs fixed Files (added, modified or removed): * CHANGES.txt * clipboard.py * edit_sizers.py * edit_windows.py * widget_properties.py * widgets/bitmap_button.py * widgets/radio_box.py * widgets/splitter_window.py * widgets/static_bitmap.py fixed bug in the previous bugfix :( Files (added, modified or removed): * clipboard.py updated contents Files (added, modified or removed): * CHANGES.txt * TODO.txt changed create_widget to use a default style for the dialog Files (added, modified or removed): * widgets/dialog.py added code to rename copied widgets properly Files (added, modified or removed): * xml_parse.py fixed small bug Files (added, modified or removed): * tree.py "confinement" of the option:flag:border:xml_str string before putting it inside the Clipboard Files (added, modified or removed): * clipboard.py changes updated Files (added, modified or removed): * CHANGES.txt 2002-08-01 marco_bari clipboard.py updated Files (added, modified or removed): * CHANGES.txt 2002-07-31 Alberto Griggio updated status Files (added, modified or removed): * TODO.txt cut & paste of non-toplevel sizers Files (added, modified or removed): * edit_sizers.py * xml_parse.py removed obsolete misc.Sizer Files (added, modified or removed): * common.py * edit_sizers.py * edit_windows.py * misc.py * widget_properties.py * widgets/bitmap_button.py * widgets/button.py * widgets/checkbox.py * widgets/choice.py * widgets/combo_box.py * widgets/dialog.py * widgets/frame.py * widgets/list_box.py * widgets/notebook.py * widgets/panel.py * widgets/radio_box.py * widgets/radio_button.py * widgets/slider.py * widgets/spin_ctrl.py * widgets/splitter_window.py * widgets/static_bitmap.py * widgets/static_text.py * widgets/text_ctrl.py * widgets/toggle_button.py 2002-07-30 Alberto Griggio xml_builder cleanup and some bugfixes Files (added, modified or removed): * CHANGES.txt * edit_sizers.py * widget_properties.py * widgets/notebook.py * widgets/slider.py * widgets/splitter_window.py * widgets/static_line.py * xml_parse.py minor bugfixes Files (added, modified or removed): * CHANGES.txt * TODO.txt * about.py * edit_sizers.py * edit_windows.py * misc.py * tree.py * widgets/notebook.py * widgets/panel.py * widgets/splitter_window.py 2002-07-30 marco_bari Now wxGlade's clipboard uses wxTheClipboard. Files (added, modified or removed): * clipboard.py 2002-07-29 Alberto Griggio prevented auto-expansion of tree nodes during app loading Files (added, modified or removed): * main.py * tree.py fixed bug in _enabler Files (added, modified or removed): * widget_properties.py 2002-07-29 marco_bari Corrected create_widget bug with static boxes. Files (added, modified or removed): * edit_sizers.py 2002-07-28 Alberto Griggio some bug fixes Files (added, modified or removed): * edit_windows.py * widgets/notebook.py * widgets/panel.py * widgets/splitter_window.py "create_widget" migration almost working Files (added, modified or removed): * common.py * edit_windows.py * main.py * tree.py * widgets/bitmap_button.py * widgets/button.py * widgets/checkbox.py * widgets/choice.py * widgets/combo_box.py * widgets/dialog.py * widgets/frame.py * widgets/list_box.py * widgets/notebook.py * widgets/panel.py * widgets/radio_box.py * widgets/radio_button.py * widgets/slider.py * widgets/spacer.py * widgets/spin_ctrl.py * widgets/splitter_window.py * widgets/static_bitmap.py * widgets/static_line.py * widgets/static_text.py * widgets/text_ctrl.py * widgets/toggle_button.py updated credits Files (added, modified or removed): * about.py 2002-07-28 marco_bari Added built-in function bool. Files (added, modified or removed): * wxglade.py Corrected self.parent bug in create_widget. Files (added, modified or removed): * widgets/bitmap_button.py * widgets/button.py * widgets/checkbox.py * widgets/choice.py * widgets/combo_box.py * widgets/dialog.py * widgets/frame.py * widgets/list_box.py * widgets/notebook.py * widgets/panel.py * widgets/slider.py * widgets/spacer.py * widgets/spin_ctrl.py * widgets/static_bitmap.py * widgets/static_line.py * widgets/static_text.py * widgets/text_ctrl.py * widgets/toggle_button.py 2002-07-28 Alberto Griggio nearer to the end of "create_widget" migration Files (added, modified or removed): * TODO.txt * edit_sizers.py * edit_windows.py * tree.py * widget_properties.py 2002-07-27 marco_bari Added (partial) support to new widget interface. Files (added, modified or removed): * widgets/bitmap_button.py * widgets/button.py * widgets/checkbox.py * widgets/choice.py * widgets/combo_box.py * widgets/dialog.py * widgets/frame.py * widgets/list_box.py * widgets/notebook.py * widgets/panel.py * widgets/radio_box.py * widgets/radio_button.py * widgets/slider.py * widgets/spacer.py * widgets/spin_ctrl.py * widgets/static_bitmap.py * widgets/static_line.py * widgets/static_text.py * widgets/text_ctrl.py * widgets/toggle_button.py 2002-07-26 Alberto Griggio something working again Files (added, modified or removed): * common.py * edit_sizers.py * edit_windows.py * misc.py * tree.py * widgets/button.py * widgets/frame.py * xml_parse.py 2002-07-25 Alberto Griggio show_widget support and some fixes Files (added, modified or removed): * common.py * edit_sizers.py * edit_windows.py * main.py * tree.py * xml_parse.py 2002-07-24 Alberto Griggio Fix in TopLevelBase.set_sizer Files (added, modified or removed): * edit_windows.py create_widget initial support Files (added, modified or removed): * edit_sizers.py 2002-07-24 marco_bari Added support for "create_widget" Files (added, modified or removed): * widgets/checkbox.py Added support for "create_widget" Files (added, modified or removed): * widgets/bitmap_button.py *** empty log message *** Files (added, modified or removed): * widgets/button.py Support for 'create_widget' Files (added, modified or removed): * widgets/button.py 2002-07-24 Alberto Griggio added self.widget, show_widget, create_widget, finish_widget_creation Files (added, modified or removed): * edit_windows.py 2002-07-22 Alberto Griggio fixed some typos Files (added, modified or removed): * TODO.txt Merge from vendor branch agriggio: First version on CVS Files (added, modified or removed): * wxglade.py First version on CVS Files (added, modified or removed): * .cvsignore * CHANGES.txt * TODO.txt * about.py * clipboard.py * codegen/py_codegen.py * common.py * docs/tech_notes.txt * edit_sizers.py * edit_windows.py * icons/.cvsignore * icons/application.xpm * icons/bitmap_button.xpm * icons/button.xpm * icons/checkbox.xpm * icons/choice.xpm * icons/combo_box.xpm * icons/dialog.xpm * icons/frame.xpm * icons/grid_sizer.xpm * icons/icon.xpm * icons/list_box.xpm * icons/menubar.xpm * icons/notebook.xpm * icons/panel.xpm * icons/radio_box.xpm * icons/radio_button.xpm * icons/sizer.xpm * icons/slider.xpm * icons/source.jpg * icons/spacer.xpm * icons/spin_ctrl.xpm * icons/splitter_window.xpm * icons/static_bitmap.xpm * icons/static_line.xpm * icons/static_text.xpm * icons/statusbar.xpm * icons/text_ctrl.xpm * icons/toggle_button.xpm * license.txt * main.py * misc.py * tree.py * widget_properties.py * widgets/ChoicesProperty.py * widgets/bitmap_button.py * widgets/button.py * widgets/checkbox.py * widgets/choice.py * widgets/combo_box.py * widgets/dialog.py * widgets/frame.py * widgets/list_box.py * widgets/notebook.py * widgets/panel.py * widgets/radio_box.py * widgets/radio_button.py * widgets/slider.py * widgets/spacer.py * widgets/spin_ctrl.py * widgets/splitter_window.py * widgets/static_bitmap.py * widgets/static_line.py * widgets/static_text.py * widgets/text_ctrl.py * widgets/toggle_button.py * widgets/widgets.txt * wxglade.py * xml_parse.py 2002-07-22 repo convert creating vendor branch agriggio Files (added, modified or removed): wxglade-0.6.8.orig/wxglade.py0000755000175000017500000002271312167340607016340 0ustar georgeskgeorgesk#!/usr/bin/env python """ Entry point of wxGlade @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import os import sys import gettext import common import optparse t = gettext.translation(domain="wxglade", localedir="locale", fallback=True) t.install("wxglade") import errors def _fix_path(path): """\ Returns an absolute version of path, accroding to the invoking dir of wxglade (which can be different from '.' if it is invoked from a shell script) """ if not os.path.isabs(path): return os.path.join(os.getcwd(), path) #getenv('WXGLADE_INVOKING_DIR', '.'), path) return path def error(msg): """\ Print an error message at stderr """ print >> sys.stderr, _("ERROR: %s") % msg def parse_command_line(): """\ Parse command line """ # list of all available languages # don't load code generators at this point!! languages = ['C++', 'XRC', 'lisp', 'perl', 'python'] # inject optparse.OptionParser.format_description = lambda self, formatter: self.description parser = optparse.OptionParser( add_help_option=False, usage=_("""\ Usage: wxglade start the wxGlade GUI or: wxglade generate code from command line or: wxglade --version show programs version number and exit or: wxglade -h|--help show this help message and exit"""), version=_("""\ wxGlade version %s Copyright (C) 2007-2012 Alberto Griggio License MIT: The MIT License """) % common.version ) parser.add_option( '-h', '--help', dest='help', action='store_true', help=_('show this help message and exit'), ) parser.add_option( "-g", "--generate-code", type="choice", choices=languages, metavar="LANG", dest="language", help=_("(required) output language, valid languages are: %s") % ", ".join(languages) ) parser.add_option( "-o", "--output", metavar="PATH", dest="output", help=_("(optional) output file in single-file mode or output directory in multi-file mode"), ) (options, args) = parser.parse_args() # print epilog because OptionParser.epilog isn't available to Python 2.3 if options.help: parser.print_help() print _(""" Example: Generate Python code out of myapp.wxg wxglade -o temp -g python myapp.wxg Report bugs to: or at wxGlade home page: """) sys.exit() # make absolute path if len(args) == 1: options.filename = _fix_path(args[0]) else: options.filename = None # check parameters # - language # - one file -> cmdline code generation # - no / > one files -> usage # - no language -> start gui if options.language: if len(args) == 1: options.start_gui = False elif len(args) == 0: error(_("No wxg file given!\n")) parser.print_help() sys.exit(1) else: error(_("Too many wxg files given!\n")) parser.print_help() sys.exit(1) else: options.start_gui = True return options def command_line_code_generation(filename, language, out_path=None): """\ Starts a code generator without starting the GUI. @param filename: Name of wxg file to generate code from @type filename: String @param language: Code generator language @type language: String @param out_path: output file / output directory @type out_path: String """ from xml_parse import CodeWriter if not common.code_writers.has_key(language): error(_('No writer for language "%s" available') % language) writer = common.code_writers[language] try: CodeWriter( writer=writer, input=filename, out_path=out_path, ) except (errors.WxgOutputDirectoryNotExist, errors.WxgOutputDirectoryNotWritable, errors.WxgOutputPathIsDirectory, ), inst: error(inst) sys.exit(1) except Exception: common.message.exception(_('Internal Error')) error( _("An exception occurred while generating the code for the application.\n" "If you think this is a wxGlade bug, please report it.") ) sys.exit(1) sys.exit(0) def determine_wxglade_path(): """\ @return: wxGlade application directory """ # use directory of the exe in case of frozen packages e.g. # PyInstaller or py2exe if hasattr(sys, 'frozen'): return os.path.dirname(sys.argv[0]) root = __file__ if os.path.islink(root): root = os.path.realpath(root) return os.path.dirname(os.path.abspath(root)) def init_stage1(): """\ Initialise paths for wxGlade (first stage) Path initialisation is splitted because the test suite doesn't work with proper initialised paths. """ # prepend the widgets dir to the wxglade_path = determine_wxglade_path() # set the program's paths common.wxglade_path = wxglade_path # static paths common.docs_path = os.path.join(wxglade_path, 'docs') common.icons_path = os.path.join(wxglade_path, 'icons') common.widgets_path = os.path.join(wxglade_path, 'widgets') common.templates_path = os.path.join(wxglade_path, 'templates') common.tutorial_file = os.path.join(common.docs_path, 'html', 'index.html') # search files credits.txt and license.txt at different locations # - /docs for linux packages # - at Windows or started from source directory # - /./../../../share/doc/wxglade/ for local installations # BTW: is something like /.../lib/python2.7/site-packages/wxglade common.credits_file = None common.license_file = None for searchdir in [ common.wxglade_path, common.docs_path, os.path.join(common.wxglade_path, '../../../../share/doc/wxglade'), ]: searchdir = os.path.normpath(searchdir) credits_file = os.path.join(searchdir, 'credits.txt') license_file = os.path.join(searchdir, 'license.txt') if os.path.exists(credits_file): common.credits_file = credits_file if os.path.exists(license_file): common.license_file = license_file if not common.credits_file: error(_('Credits file "credits.txt" not found!')) if not common.license_file: error(_('License file "license.txt" not found!')) # print used paths print _('Base directory: %s') % common.wxglade_path print _('Documentation directory: %s') % common.docs_path print _('Icons directory: %s') % common.icons_path print _('Build-in widgets directory: %s') % common.widgets_path print _('Template directory: %s') % common.templates_path print _('Credits file: %s') % common.credits_file print _('License file: %s') % common.license_file print _('Tutorial file: %s') % common.tutorial_file # adapt application search path sys.path = [common.wxglade_path, common.widgets_path] + sys.path def init_stage2(use_gui): """\ Initialise the remaining (non-path) parts of wxGlade (second stage) @param use_gui: Starting wxGlade GUI @type use_gui: Boolean """ common.use_gui = use_gui if use_gui: # ensure minimal wx version if not hasattr(sys, 'frozen') and \ 'wxversion' not in sys.modules and \ 'wx' not in sys.modules: import wxversion wxversion.ensureMinimal("2.6") # store current platform (None is default) import wx common.platform = wx.Platform # codewrites, widgets and sizers are loaded in class main.wxGladeFrame else: # use_gui has to be set before importing config import config config.init_preferences() common.load_code_writers() common.load_widgets() common.load_sizers() def run_main(): """\ This main procedure is started by calling either wxglade.py or wxglade.pyw on windows. It parses the command line, install the exception handler and initialise wxGlade. @see: L{common.exceptionHandler()} """ # check command line parameters first options = parse_command_line() # print versions print _("Starting wxGlade version %s on Python %s") % ( common.version, common.py_version, ) # install own exception handler sys.excepthook = common.exceptionHandler # initialise wxGlade (first stage) init_stage1() # initialise wxGlade (second stage) init_stage2(options.start_gui) if options.start_gui: # late import of main (imported wx) for using wxversion in # init_stage2() import main main.main(options.filename) else: command_line_code_generation( filename=options.filename, language=options.language, out_path=options.output, ) if __name__ == "__main__": run_main() wxglade-0.6.8.orig/kdefiledialog.py0000644000175000017500000001462511702334417017464 0ustar georgeskgeorgesk# kdefiledialog.py: support for native KDE file and dir dialog (using kdialog) # $Id: kdefiledialog.py,v 1.5 2007/03/27 07:02:07 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import signal, os, sys import misc __all__ = ['test_kde', 'kde_file_selector', 'kde_dir_selector'] def _check_for_kdialog(): pth = os.environ.get('PATH', os.defpath).split(os.pathsep) for p in pth: name = os.path.join(p, 'kdialog') if os.access(name, os.X_OK): return True return False _kdialog_ok = _check_for_kdialog() def kde_file_selector(message, default_path="", default_filename="", default_extension="", wildcard="*.*", flags=0, *args, **kwds): """\ Pops up the standard KDE file selector box, calling kdialog. The API is identical to that of wx.FileSelector. If kdialog can't be invoked, reverts to the standard wx.FileSelector. Note that at the moment not all the arguments are meaningful (for example, parent and initial position are ignored), and multiple selections are not supported. """ if not _kdialog_ok: return wx.FileSelector(message, default_path, default_filename, default_extension, wildcard, flags, *args, **kwds) r, w = os.pipe() handler = _SigChldHandler() oldhandler = signal.signal(signal.SIGCHLD, handler) pid = os.fork() if pid == 0: os.close(r) os.dup2(w, sys.stdout.fileno()) os.close(w) startdir = default_path if default_filename: if not os.path.isdir(startdir): startdir = os.path.dirname(startdir) startdir = os.path.join(startdir, default_filename) if flags & wx.SAVE: kind = '--getsavefilename' else: kind = '--getopenfilename' os.execlp('kdialog', 'kdialog', kind, startdir, _wx_to_kde_wildcard(wildcard), '--title', message) elif pid > 0: disabler = wx.WindowDisabler() app = wx.GetApp() os.close(w) while not handler.done: app.Dispatch() if handler.status != 0: os.close(r) return "" filename = os.fdopen(r).readline().strip() signal.signal(signal.SIGCHLD, oldhandler or signal.SIG_DFL) if (flags & wx.SAVE) and (flags & wx.OVERWRITE_PROMPT) and \ os.path.exists(filename): if wx.MessageBox(_("File '%s' already exists: do you really want " "to overwrite it?") % misc.wxstr(filename), _("Confirm"), style=wx.YES_NO|wx.ICON_QUESTION) == wx.NO: return kde_file_selector(message, default_path, default_filename, default_extension, wildcard, flags) return filename else: raise OSError, _("Fork Error") def kde_dir_selector(message="", default_path="", *args, **kwds): """\ Pops up the standard KDE directory selector box, calling kdialog. The API is identical to that of wx.DirSelector. If kdialog can't be invoked, reverts to the standard wx.DirSelector. Note that at the moment not all the arguments are meaningful (for example, parent and initial position are ignored). """ if not _kdialog_ok: return wx.DirSelector(message, default_path, *args, **kwds) r, w = os.pipe() handler = _SigChldHandler() oldhandler = signal.signal(signal.SIGCHLD, handler) pid = os.fork() if pid == 0: os.close(r) os.dup2(w, sys.stdout.fileno()) os.close(w) if not default_path: default_path = os.getcwd() os.execlp('kdialog', 'kdialog', '--getexistingdirectory', default_path, '--title', message) elif pid > 0: disabler = wx.WindowDisabler() app = wx.GetApp() os.close(w) while not handler.done: app.Dispatch() if handler.status != 0: os.close(r) return "" dirname = os.fdopen(r).readline().strip() signal.signal(signal.SIGCHLD, oldhandler or signal.SIG_DFL) return dirname else: raise OSError, _("Fork Error") def test_kde(): """\ Checks whether KDE (actually, kdesktop) is running. """ return os.system('dcop kdesktop > /dev/null 2>&1') == 0 class _SigChldHandler: def __init__(self): self.done = False self.status = 0 def __call__(self, signo, stackframe): pid, self.status = os.wait() self.done = True # end of class _SigChldHandler def _wx_to_kde_wildcard(wildcard): bits = wildcard.split('|') l = len(bits) ret = [] for i in range(0, l, 2): if i+1 < l: ret.append(bits[i+1].replace(';', ' ') + '|' + bits[i]) else: ret.append(bits[i].replace(';', ' ')) return '\n'.join(ret) if __name__ == '__main__': app = wx.PySimpleApp() frame = wx.Frame(None, -1, "Prova") b = wx.Button(frame, -1, "KDE File selector", pos=(0, 0)) b2 = wx.Button(frame, -1, "wx File selector", pos=(0, 70)) def on_click(event): filename = kde_file_selector( 'Select file to save', '', 'prova.py', wildcard="Python files|*.py;*.pyc|All files|*", flags=wx.SAVE|wx.OVERWRITE_PROMPT) if filename: wx.MessageBox('You selected file: %s' % filename, style=wx.OK|wx.ICON_INFORMATION) else: wx.MessageBox('No files selected!', style=wx.OK|wx.ICON_EXCLAMATION) def on_click2(event): filename = wx.FileSelector( 'Select file to save', '', 'prova.py', wildcard=_("Python files|*.py;*.pyc|All files|*"), flags=wx.SAVE|wx.OVERWRITE_PROMPT) if filename: wx.MessageBox(_('You selected file: %s') % filename, style=wx.OK|wx.ICON_INFORMATION) else: wx.MessageBox(_('No files selected!'), style=wx.OK|wx.ICON_EXCLAMATION) wx.EVT_BUTTON(b, -1, on_click) wx.EVT_BUTTON(b2, -1, on_click2) app.SetTopWindow(frame) frame.Show() app.MainLoop() wxglade-0.6.8.orig/Makefile0000644000175000017500000001444712167336636016004 0ustar georgeskgeorgesk# Makefile for wxGlade # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY DESTDIR = # Makefile defaults SHELL = /bin/sh INSTALL = install INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 PACKAGE = python-wxglade prefix = $(DESTDIR)/usr/local exec_prefix = $(DESTDIR)/usr/local bindir = $(exec_prefix)/bin datarootdir = $(prefix)/share datadir = $(datarootdir) docdir = $(datarootdir)/doc/$(PACKAGE) mandir = $(datarootdir)/man man1dir = $(mandir)/man1 PYVER = 2.3 BASE_DIR = . BIN_FILES = wxglade BUILD_DIR = $(BASE_DIR)/build BDIST_DIR = $(BASE_DIR)/bdist DOC_DIR = $(BASE_DIR)/docs DIST_DIR = $(BASE_DIR)/dist CHECK_FILES = $(filter-out $(BASE_DIR)/test.py, $(wildcard $(BASE_DIR)/*.py)) \ $(filter-out tests/%.py, $(shell find $(SOURCE_DIRS) -name "*.py")) EPYDOC_BIN = epydoc EPYDOC_CONFIG = $(BASE_DIR)/epydoc.conf EPYDOC_OPTS = --config APIDOC_DIR = $(BASE_DIR)/docs/apidocs SOURCE_DIRS = codegen edit_sizers widgets install tests SOURCE_FILES = $(wildcard $(BASE_DIR)/*.py) $(shell find $(SOURCE_DIRS) -name "*.py") TEST_BIN = $(BASE_DIR)/test.py PYLINT_BIN = pylint PYLINT_OPTS = --additional-builtins=_ --disable=C \ '--dummy-variables=_|dummy|event|empty|unused|i' \ --disable=W0105,W0201,W0212,W0401,W0403,W0614 \ --disable=R0201,R0901,R0902,R0903,R0904,R0912,R0913,R0914,R0915 \ --include-ids=y --reports=n PYLINT_PATH = "$(BASE_DIR):$(BASE_DIR)/widgets:$(BASE_DIR)/codegen" PYTHON_BIN = python DB2MAN = /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl XP = xsltproc --nonet MANUAL_HTML_DIR = $(DOC_DIR)/html MANUAL_PDF_DIR = $(DOC_DIR)/pdf MANUAL_SRC_DIR = $(DOC_DIR)/src MANUAL_XML = $(MANUAL_SRC_DIR)/manual.xml MANUAL_PICS = $(wildcard $($(MANUAL_SRC_DIR)/*.png)) MANUAL_PDF = $(MANUAL_PDF_DIR)/manual.pdf MANUAL_PDF_XSL = $(MANUAL_SRC_DIR)/pdf.xsl MANUAL_HTML = $(MANUAL_HTML_DIR)/index.html MANUAL_HTML_XSL = $(MANUAL_SRC_DIR)/html.xsl HELP= @grep -B1 '^[a-zA-Z\-]*:' Makefile |\ awk 'function p(h,t){printf"%-12s=%s\n",h,t;};\ /\#+/{t=$$0;};\ /:/{gsub(":.*","");h=$$0};\ /^--/{p(h,t);t=h="";};\ END{p(h,t)}' |\ sed -n 's/=.*\#+/:/gp' .PHONY: help clean distclean compile apidoc pylint permissions man doc \ pdf html doc-clean release rel-binary rel-source install \ maintainer-clean test # Rule to compile a single Python file %.pyc: %.py @echo "Compile $< ..." @$(PYTHON_BIN) -c "import py_compile; py_compile.compile('$<')" #+ Show this text help: $(HELP) #+ Run all test package test: test-nongui test-gui #+ Run all non-GUI test package test-nongui: @$(TEST_BIN) #+ Run all GUI test package test-gui: @$(TEST_BIN) --gui #+ Clean python compiler files and automatic generated documentation clean: @echo "Remove all automatically generated files ..." @find $(BASE_DIR) -depth -type f -name "*.pyc" -exec rm -f {} \; @find $(BASE_DIR) -depth -type f -name "*.pyo" -exec rm -f {} \; @if [ -e $(BUILD_DIR) ]; then rm -rf $(BUILD_DIR); fi @if [ -e $(BDIST_DIR) ]; then rm -rf $(BDIST_DIR); fi @if [ -e $(DIST_DIR) ]; then rm -rf $(DIST_DIR); fi @if [ -e $(APIDOC_DIR) ]; then rm -rf $(APIDOC_DIR); fi @find $(BASE_DIR) -depth -type f -name "*.orig" -exec rm -f {} \; @find $(BASE_DIR) -depth -type f -name "*~" -exec rm -f {} \; @$(RM) logdict*.log @$(RM) warnwxglade.txt @$(RM) MANIFEST #+ Remove all automatically generated and development files distclean: clean @echo "Remove development files ..." @$(RM) .hgtags .hgignore #+ Remove almost everything that can bee reconstructed with this Makefile maintainer-clean: distclean doc-clean @echo "This command is intended for maintainers to use; it" @echo 'deletes files that may need special tools to rebuild." #+ Compile all python files compile: $(BYTECODE_FILES) # Create the documentation $(APIDOC_DIR)/index.html: $(SOURCE_FILES) $(EPYDOC_CONFIG) @echo "Create documentation from source ..." @$(EPYDOC_BIN) $(EPYDOC_OPTS) $(EPYDOC_CONFIG) #+ Create documentation from source files apidoc: $(APIDOC_DIR)/index.html #+ Check all source files for logical errors using pylint pylint: PYTHONPATH=$(PYLINT_PATH) $(PYLINT_BIN) $(PYLINT_OPTS) $(CHECK_FILES) || /bin/true #+ Set proper permissions for all files and directories permissions: @echo "Set permissions for all files ..." @find $(BASE_DIR) -type d -exec chmod 755 {} \; @find $(BASE_DIR) -type f -exec chmod 644 {} \; @chmod 755 $(BIN_FILES) # Create the manpage $(DOC_DIR)/man/wxglade.1: $(DOC_DIR)/man/manpage.xml $(XP) --output $@ $(DB2MAN) $< #+ Create manpage from source files man: $(DOC_DIR)/man/wxglade.1 #+ Create documentation from source files doc: pdf html # Create PDF documentation $(MANUAL_PDF): $(MANUAL_XML) $(MANUAL_PICS) dblatex -p $(MANUAL_PDF_XSL) -o $(MANUAL_PDF_DIR)/manual.pdf $(MANUAL_XML) #+ Create PDF document based on manual xml file pdf: $(MANUAL_PDF) # Create HTML documentation $(MANUAL_HTML): $(MANUAL_XML) $(MANUAL_PICS) $(INSTALL_DATA) -t $(MANUAL_HTML_DIR) $(MANUAL_SRC_DIR)/*.png xmlto -m $(MANUAL_HTML_XSL) -o $(MANUAL_HTML_DIR) html $(MANUAL_XML) $(RM) $(MANUAL_HTML_DIR)/manual.proc #+ Create a set of HTML documents based on manual xml file html: $(MANUAL_HTML) #+ Cleanup all automatically generated manuals (if you really know what you do) doc-clean: $(RM) $(MANUAL_HTML_DIR)/*.html $(RM) $(MANUAL_HTML_DIR)/*.png $(RM) $(MANUAL_PDF) #+ Create official release packages release: rel-source rel-binary #+ Create Unix binary packages rel-binary: man pdf @echo "Creating Unix release packages ..." @$(RM) MANIFEST $(PYTHON_BIN) setup.py bdist --format=zip @$(RM) MANIFEST #+ Create Unix source release packages rel-source: man pdf @echo "Creating source packages ..." @$(RM) MANIFEST $(PYTHON_BIN) setup.py sdist --formats=gztar,zip @$(RM) MANIFEST #+ Install wxGlade locally at $(prefix) install: man pdf setup.py @echo "Install wxGlade locally at $(prefix) ..." $(PYTHON_BIN) setup.py install --prefix $(prefix) gzip -9 $(man1dir)/wxglade.1 wxglade-0.6.8.orig/clipboard.py0000644000175000017500000001037511621715605016640 0ustar georgeskgeorgesk# clipboard.py: support for cut & paste of wxGlade widgets # $Id: clipboard.py,v 1.19 2007/07/21 11:30:29 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx # Format used by wxGlade for the clipboard. _widget_data_format = wx.CustomDataFormat("wxglade_widget") class _WidgetDataObject(wx.CustomDataObject): """\ Object representig a widget in the clipboard. """ def __init__(self, *args): wx.CustomDataObject.__init__(self, _widget_data_format) if args: data = apply(self._widget2repr, args) self.SetData(data) def _widget2repr(self, *args): """\ Convert *args into a string and returns it. *args contains option, flag, border, xml_str. """ assert len(args) == 4 return ":".join([str(elem) for elem in args]) def GetWidgetData(self): """\ Convert a string into option, flag, border and xml_string and returns them in a list. """ ret = self.GetData().split(":", 3) assert len(ret) == 4, _("Invalid data in the clipboard") # remove the dirt at the end of xml_str bound = ret[3].rfind('>')+1 ret[3] = ret[3][:bound] for i in range(3): # option, flag and border are integers. ret[i] = int(ret[i]) return ret def copy(widget): """\ Copies widget and all its children to the clipboard. """ from cStringIO import StringIO xml_str = StringIO() widget.node.write(xml_str, 0) flag = widget.get_int_flag() option = widget.get_option() border = widget.get_border() if wx.TheClipboard.Open(): try: wdo = _WidgetDataObject(option, flag, border, xml_str.getvalue()) if not wx.TheClipboard.SetData(wdo): print _("Data can't be copied to clipboard.") return False return True finally: wx.TheClipboard.Close() else: print _("Clipboard can't be opened.") return False def cut(widget): """\ Copies widget and all its children to the clipboard and then removes them. """ if copy(widget): widget.remove() return True else: return False def paste(parent, sizer, pos): """\ Copies a widget (and all its children) from the clipboard to the given destination (parent, sizer and position inside the sizer) returns True if there was something to paste, False otherwise. """ if wx.TheClipboard.Open(): try: if wx.TheClipboard.IsSupported(_widget_data_format): wdo = _WidgetDataObject() if not wx.TheClipboard.GetData(wdo): print _("Data can't be copied from clipboard.") return False else: return False finally: wx.TheClipboard.Close() else: print _("Clipboard can't be opened.") return False option, flag, border, xml_str = wdo.GetWidgetData() if xml_str: import xml_parse try: wx.BeginBusyCursor() parser = xml_parse.ClipboardXmlWidgetBuilder(parent, sizer, pos, option, flag, border) parser.parse_string(xml_str) return True # Widget hierarchy pasted. finally: wx.EndBusyCursor() return False # There's nothing to paste. #----------------------------------------------------------------------------- # 2004-02-19 ALB: D&D support (thanks to Chris Liechti) #----------------------------------------------------------------------------- class FileDropTarget(wx.FileDropTarget): def __init__(self, parent): wx.FileDropTarget.__init__(self) self.parent = parent def OnDropFiles(self, x, y, filenames): if len(filenames) > 1: wx.MessageBox(_("Please only drop one file at a time"), "wxGlade", wx.ICON_ERROR) elif filenames: path = filenames[0] if self.parent.ask_save(): self.parent._open_app(path) # end of class FileDropTarget wxglade-0.6.8.orig/README.txt0000644000175000017500000000260112167341221016011 0ustar georgeskgeorgeskwxGlade: A GUI builder for wxPython/wxWidgets Version: 0.6.8 License: MIT (see license.txt) THIS PROGRAM COMES WITH NO WARRANTY * Requirements: --------------- Python >= 2.3 wxPython >= 2.6 * Installation: --------------- If you are reading this file, you already did all the necessary :-) To start the program, enter ``python wxglade.py'' in your shell * Documentation: ---------------- There's a short introductory tutorial in the docs/ subdirectory. In the examples/ subdirectory are some sample wxGlade apps (in xml format, .wxg file extension). * Known Bugs/Issues: -------------------- - If you have PyXML installed, be sure to use at least version 0.8.1, as otherwise you will not be able to generate code and load saved wxg files. This seems to be a PyXML bug, see http://sourceforge.net/tracker/?func=detail&atid=106473&aid=573011&group_id=6473 - On Windows, selection tags may not be shown properly in some cases. - On GTK, if your last operation before exiting is a paste from the clipboard, wxGlade exits with a segfault. - On GTK, menubars give troubles: they produce a lot of Gtk-WARNING and Gtk-FATAL messages and may cause segfaults. - On GTK, notebooks can cause some Gtk-WARNING messages, but they seem to work anyway. For any kind of question, there's a mailing list at https://lists.sourceforge.net/lists/listinfo/wxglade-general Enjoy! Alberto Griggio wxglade-0.6.8.orig/xrc2wxg.py0000755000175000017500000004612312150154266016306 0ustar georgeskgeorgesk#!/usr/bin/env python """ Converts an XRC resource file (in a format wxGlade likes, i.e. all windows inside sizers, no widget unknown to wxGlade, ...) into a WXG file. @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import xml.dom.minidom import getopt import os.path import sys import time __version__ = '0.0.3' _name = 'xrc2wxg' _props = { 'bg': 'background', 'fg': 'foreground', 'content': 'choices', 'item': 'choice', 'growablerows': 'growable_rows', 'growablecols': 'growable_cols', 'enabled': 'disabled', 'sashpos': 'sash_pos', } _counter_name = 1 _widgets_list = [ 'wxFrame', 'wxDialog', 'wxPanel', 'wxSplitterWindow', 'wxNotebook', 'wxButton', 'wxToggleButton', 'wxBitmapButton', 'wxTextCtrl', 'wxSpinCtrl', 'wxSlider', 'wxGauge', 'wxStaticText', 'wxCheckBox', 'wxRadioButton', 'wxRadioBox', 'wxChoice', 'wxComboBox', 'wxListBox', 'wxStaticLine', 'wxStaticBitmap', 'wxGrid', 'wxMenuBar', 'wxStatusBar', 'wxBoxSizer', 'wxStaticBoxSizer', 'wxGridSizer', 'wxFlexGridSizer', 'wxTreeCtrl', 'wxListCtrl', 'wxToolBar', 'wxScrolledWindow', ] _widgets = dict(zip(_widgets_list, [1] * len(_widgets_list))) _special_class_names = [ 'notebookpage', 'sizeritem', 'separator', 'tool', 'spacer', ] _special_class_names = dict(zip(_special_class_names, [1] * len(_special_class_names))) def get_child_elems(node): def ok(n): return n.nodeType == n.ELEMENT_NODE return filter(ok, node.childNodes) def get_text_elems(node): def ok(n): return n.nodeType == n.TEXT_NODE return filter(ok, node.childNodes) def convert(input, output): global _counter_name _counter_name = 1 document = xml.dom.minidom.parse(input) fix_fake_panels(document) set_base_classes(document) fix_properties(document) fix_widgets(document) fix_encoding(input, document) if not hasattr(output, 'write'): output = open(output, 'w') write_output(document, output) output.close() else: write_output(document, output) def write_output(document, output): """\ This code has been adapted from XRCed 0.0.7-3. Many thanks to its author Roman Rolinsky. """ dom_copy = xml.dom.minidom.Document() def indent(node, level=0): # Copy child list because it will change soon children = node.childNodes[:] # Main node doesn't need to be indented if level: text = dom_copy.createTextNode('\n' + ' ' * level) node.parentNode.insertBefore(text, node) if children: # Append newline after last child, except for text nodes if children[-1].nodeType == xml.dom.minidom.Node.ELEMENT_NODE: text = dom_copy.createTextNode('\n' + ' ' * level) node.appendChild(text) # Indent children which are elements for n in children: if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE: indent(n, level + 1) comment = dom_copy.createComment(' generated by %s %s on %s ' % (_name, __version__, time.asctime())) dom_copy.appendChild(comment) main_node = dom_copy.appendChild(document.documentElement) indent(main_node) comment_done = False for line in dom_copy.toxml().encode('utf-8').splitlines(): if not comment_done and line.startswith('', '-->\n\n') comment_done = True if line.strip(): output.write(line) output.write('\n') dom_copy.unlink() def set_base_classes(document): for elem in document.getElementsByTagName('object'): klass = elem.getAttribute('class') if klass.startswith('wx'): elem.setAttribute('base', 'Edit' + klass[2:]) name = elem.getAttribute('name') if not name: global _counter_name elem.setAttribute('name', 'object_%s' % _counter_name) _counter_name += 1 def fix_properties(document): # special case... for elem in document.getElementsByTagName('disabled'): elem.tagName = 'disabled_bitmap' for prop in _props: for elem in document.getElementsByTagName(prop): elem.tagName = _props[prop] document.documentElement.tagName = 'application' if document.documentElement.hasAttribute('version'): document.documentElement.removeAttribute('version') def fix_widgets(document): fix_menubars(document) fix_toolbars(document) fix_custom_widgets(document) fix_sizeritems(document) fix_notebooks(document) fix_splitters(document) fix_spacers(document) fix_sliders(document) fix_scrolled_windows(document) fix_toplevel_names(document) def fix_custom_widgets(document): for elem in document.getElementsByTagName('object'): klass = elem.getAttribute('class') if klass not in _widgets and klass not in _special_class_names: elem.setAttribute('base', 'CustomWidget') args = document.createElement('arguments') for child in get_child_elems(elem): # if child is a 'simple' attribute, i.e # value, convert it to an 'argument' if len(child.childNodes) == 1 and \ child.firstChild.nodeType == child.TEXT_NODE: arg = document.createElement('argument') arg.appendChild(document.createTextNode( child.tagName + ': ' + child.firstChild.data)) args.appendChild(arg) # and remove it elem.removeChild(child) # otherwise, leave it where it is (it shouldn't hurt) elem.appendChild(args) def fix_sizeritems(document): def ok(node): return node.getAttribute('class') == 'sizeritem' def ok2(node): return node.tagName == 'object' for sitem in filter(ok, document.getElementsByTagName('object')): for child in filter(ok2, get_child_elems(sitem)): sitem.appendChild(sitem.removeChild(child)) fix_flag_property(document) def fix_flag_property(document): for elem in document.getElementsByTagName('flag'): tmp = elem.firstChild.data.replace('CENTRE', 'CENTER') elem.firstChild.data = tmp.replace('GROW', 'EXPAND') if elem.firstChild.data.find('wxALIGN_CENTER_HORIZONTAL') < 0 and \ elem.firstChild.data.find('wxALIGN_CENTER_VERTICAL') < 0: elem.firstChild.data = elem.firstChild.data.replace( 'wxALIGN_CENTER', 'wxALIGN_CENTER_HORIZONTAL|' 'wxALIGN_CENTER_VERTICAL') def fix_menubars(document): def ok(elem): return elem.getAttribute('class') == 'wxMenuBar' menubars = filter(ok, document.getElementsByTagName('object')) for mb in menubars: fix_menus(document, mb) if mb.parentNode is not document.documentElement: mb_prop = document.createElement('menubar') mb_prop.appendChild(document.createTextNode('1')) mb.parentNode.insertBefore(mb_prop, mb) def fix_menus(document, menubar): def ok(elem): return elem.getAttribute('class') == 'wxMenu' menus = filter(ok, get_child_elems(menubar)) menus_node = document.createElement('menus') for menu in menus: try: label = [c for c in get_child_elems(menu) if c.tagName == 'label'][0] label = label.firstChild.data except IndexError: label = '' new_menu = document.createElement('menu') new_menu.setAttribute('name', menu.getAttribute('name')) new_menu.setAttribute('label', label) fix_sub_menus(document, menu, new_menu) menus = document.createElement('menus') menus.appendChild(new_menu) menubar.removeChild(menu).unlink() menubar.appendChild(menus) def fix_sub_menus(document, menu, new_menu): for child in get_child_elems(menu): klass = child.getAttribute('class') elem = document.createElement('') if klass == 'wxMenuItem': elem.tagName = 'item' name = document.createElement('name') name.appendChild(document.createTextNode( child.getAttribute('name'))) elem.appendChild(name) for c in get_child_elems(child): elem.appendChild(c) elif klass == 'separator': elem.tagName = 'item' for name in 'label', 'id', 'name': e = document.createElement(name) e.appendChild(document.createTextNode('---')) elem.appendChild(e) elif klass == 'wxMenu': elem.tagName = 'menu' elem.setAttribute('name', child.getAttribute('name')) try: label = [c for c in get_child_elems(child) if c.tagName == 'label'][0] label = label.firstChild.data except IndexError: label = '' elem.setAttribute('label', label) fix_sub_menus(document, child, elem) if elem.tagName: new_menu.appendChild(elem) def fix_toolbars(document): def ok(elem): return elem.getAttribute('class') == 'wxToolBar' toolbars = filter(ok, document.getElementsByTagName('object')) for tb in toolbars: fix_tools(document, tb) if tb.parentNode is not document.documentElement: tb_prop = document.createElement('toolbar') tb_prop.appendChild(document.createTextNode('1')) tb.parentNode.insertBefore(tb_prop, tb) def fix_tools(document, toolbar): tools = document.createElement('tools') for tool in [c for c in get_child_elems(toolbar) if c.tagName == 'object']: if tool.getAttribute('class') == 'tool': new_tool = document.createElement('tool') id = document.createElement('id') id.appendChild(document.createTextNode( tool.getAttribute('name'))) new_tool.appendChild(id) for c in get_child_elems(tool): if c.tagName == 'bitmap': c.tagName = 'bitmap1' elif c.tagName == 'tooltip': c.tagName = 'short_help' elif c.tagName == 'longhelp': c.tagName = 'long_help' elif c.tagName == 'toggle': c.tagName = 'type' new_tool.appendChild(c) tools.appendChild(new_tool) toolbar.removeChild(tool).unlink() elif tool.getAttribute('class') == 'separator': new_tool = document.createElement('tool') id = document.createElement('id') id.appendChild(document.createTextNode('---')) new_tool.appendChild(id) tools.appendChild(new_tool) toolbar.removeChild(tool).unlink() else: # some kind of control, unsupported at the moment, just remove it toolbar.removeChild(tool).unlink() toolbar.appendChild(tools) def fix_notebooks(document): def ispage(node): return node.getAttribute('class') == 'notebookpage' def isnotebook(node): return node.getAttribute('class') == 'wxNotebook' for nb in filter(isnotebook, document.getElementsByTagName('object')): pages = filter(ispage, get_child_elems(nb)) tabs = document.createElement('tabs') try: us = filter(lambda n: n.tagName == 'usenotebooksizer', get_child_elems(nb))[0] nb.removeChild(us).unlink() except IndexError: pass for page in pages: tab = document.createElement('tab') obj = None for c in get_child_elems(page): if c.tagName == 'label': tab.appendChild(c.firstChild) elif c.tagName == 'object': tab.setAttribute('window', c.getAttribute('name')) c.setAttribute('base', 'NotebookPane') obj = c tabs.appendChild(tab) nb.replaceChild(obj, page) nb.insertBefore(tabs, nb.firstChild) def fix_splitters(document): def issplitter(node): return node.getAttribute('class') == 'wxSplitterWindow' def ispane(node): return node.tagName == 'object' for sp in filter(issplitter, document.getElementsByTagName('object')): panes = filter(ispane, get_child_elems(sp)) assert len(panes) <= 2, "Splitter window with more than 2 panes!" for i in range(len(panes)): e = document.createElement('window_%s' % (i + 1)) e.appendChild(document.createTextNode( panes[i].getAttribute('name'))) sp.insertBefore(e, sp.firstChild) for orient in filter(lambda n: n.tagName == 'orientation', get_child_elems(sp)): if orient.firstChild.data == 'vertical': orient.firstChild.data = 'wxVERTICAL' elif orient.firstChild.data == 'horizontal': orient.firstChild.data = 'wxHORIZONTAL' def fix_fake_panels(document): def isframe(node): return node.getAttribute('class') == 'wxFrame' for frame in filter(isframe, document.getElementsByTagName('object')): for c in get_child_elems(frame): if c.tagName == 'object' and c.getAttribute('class') == 'wxPanel' \ and c.getAttribute('name') == '': elems = get_child_elems(c) if len(elems) == 1 and \ elems[0].getAttribute('class').find('Sizer') != -1: frame.replaceChild(elems[0], c) def fix_spacers(document): def isspacer(node): return node.getAttribute('class') == 'spacer' for spacer in filter(isspacer, document.getElementsByTagName('object')): spacer.setAttribute('name', 'spacer') spacer.setAttribute('base', 'EditSpacer') sizeritem = document.createElement('object') sizeritem.setAttribute('class', 'sizeritem') for child in get_child_elems(spacer): if child.tagName == 'size': w, h = [s.strip() for s in child.firstChild.data.split(',')] width = document.createElement('width') width.appendChild(document.createTextNode(w)) height = document.createElement('height') height.appendChild(document.createTextNode(h)) spacer.removeChild(child).unlink() spacer.appendChild(width) spacer.appendChild(height) else: sizeritem.appendChild(spacer.removeChild(child)) spacer.parentNode.replaceChild(sizeritem, spacer) sizeritem.appendChild(spacer) def fix_scrolled_windows(document): def isscrollwin(node): return node.getAttribute('class') == 'wxScrolledWindow' for sw in filter(isscrollwin, document.getElementsByTagName('object')): e = document.createElement('scrollable') e.appendChild(document.createTextNode('1')) sw.insertBefore(e, sw.firstChild) def fix_toplevel_names(document): names = {} for widget in get_child_elems(document.documentElement): klass = widget.getAttribute('class') if not klass: continue # don't add a new 'class' attribute if it doesn't exist if klass == 'wxPanel': widget.setAttribute('base', 'EditTopLevelPanel') klass_name = kn = klass.replace('wx', 'My') name = widget.getAttribute('name') i = 1 while names.has_key(klass_name) or klass_name == name: klass_name = kn + str(i) i += 1 widget.setAttribute('class', klass_name) def fix_sliders(document): def isslider(node): klass = node.getAttribute('class') return klass == 'wxSlider' or klass == 'wxSpinCtrl' for slider in filter(isslider, document.getElementsByTagName('object')): v1, v2 = 0, 100 for child in get_child_elems(slider): if child.tagName == 'min': v1 = child.firstChild.data.strip() slider.removeChild(child).unlink() elif child.tagName == 'max': v2 = child.firstChild.data.strip() slider.removeChild(child).unlink() rng = document.createElement('range') rng.appendChild(document.createTextNode('%s, %s' % (v1, v2))) slider.appendChild(rng) def fix_encoding(filename, document): # first try to find the encoding of the xml doc import re enc = re.compile(r'^\s*<\?xml\s+.*(encoding\s*=\s*"(.*?)").*\?>') tag = re.compile(r'<.+?>') for line in open(filename): match = re.match(enc, line) if match is not None: document.documentElement.setAttribute('encoding', match.group(2)) return elif re.match(tag, line) is not None: break # if it's not specified, try to find a child of the root called 'encoding': # I don't know why, but XRCed does this for child in document.documentElement.childNodes: if child.nodeType == child.ELEMENT_NODE and \ child.tagName == 'encoding': if child.firstChild is not None and \ child.firstChild.nodeType == child.TEXT_NODE: document.documentElement.setAttribute( 'encoding', child.firstChild.data) document.documentElement.removeChild(child) def usage(): msg = """\ usage: python %s OPTIONS [WXG_FILE] OPTIONS: -d, --debug: debug mode, i.e. you can see the whole traceback of each error If WXG_FILE is not given, it defaults to INPUT_FILE.wxg """ % _name print msg sys.exit(1) def print_exception(exc): msg = """\ An error occurred while trying to convert the XRC file. Here's the short error message: \t%s\n If you think this is a bug, or if you want to know more about the cause of the error, run this script again in debug mode (-d switch). If you find a bug, please report it to the mailing list (wxglade-general@lists.sourceforge.net), or enter a bug report at the SourceForge bug tracker. Please note that this doesn't handle ALL XRC files correctly, but only those which already are in a format which wxGlade likes (this basically means that every non-toplevel widget must be inside sizers, but there might be other cases). """ % str(exc) print >> sys.stderr, msg sys.exit(1) def main(): try: options, args = getopt.getopt(sys.argv[1:], "d", ['debug']) except getopt.GetoptError: usage() if not args: usage() input = args[0] try: output = args[1] except IndexError: output = os.path.splitext(input)[0] + '.wxg' if not options: try: convert(input, output) except Exception, e: # catch the exception and print a nice message print_exception(e) else: # if in debug mode, let the traceback be printed convert(input, output) if __name__ == '__main__': _name = os.path.basename(sys.argv[0]) main() wxglade-0.6.8.orig/license.txt0000644000175000017500000000211211621715605016500 0ustar georgeskgeorgeskCopyright (c) 2002-2007 Alberto Griggio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. wxglade-0.6.8.orig/application.py0000644000175000017500000010360412167336636017213 0ustar georgeskgeorgesk""" Application class to store properties of the application being created @copyright: 2002-2007 Alberto Griggio @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import codecs import locale import os import re import wx from widget_properties import * import common import config import errors import math import misc class FileDirDialog: """\ Custom class which displays a FileDialog or a DirDialog, according to the value of the L{Application.codegen_opt} of its parent (instance of L{Application}). @ivar default_extension: The default extension will be added to all file names without extension. @type default_extension: String @ivar file_message: Message to show on the file dialog @type file_message: String @ivar dir_message: Message to show on the directory dialog @type dir_message: String @ivar file_style: Style for the file dialog @ivar dir_style: Style for the directory dialog @ivar value: Value returned by file or directory dialog on success @ivar parent: Parent instance of L{Application} @ivar prev_dir: Previous directory """ def __init__(self, parent, wildcard=_("All Files|*"), file_message=_("Choose a file"), dir_message=None, file_style=0): self.prev_dir = config.preferences.codegen_path or "" self.wildcard = wildcard self.file_message = file_message self.dir_message = dir_message self.file_style = file_style self.dir_style = wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON self.parent = parent self.value = None self.default_extension = None def ShowModal(self): """\ Show a FileDialog or a DirDialog as a modal dialog. The selected file or directory is stored in L{value} on success. @return: C{ID_OK} or C{ID_CANCEL} @see: L{get_value()} """ if self.parent.codegen_opt == 0: self.value = misc.FileSelector( self.file_message, self.prev_dir, wildcard=self.wildcard, flags=self.file_style ) # check for file extension and add default extension if missing if self.value and self.default_extension: ext = os.path.splitext(self.value)[1].lower() if not ext: self.value = "%s%s" % (self.value, self.default_extension) else: self.value = misc.DirSelector( self.dir_message, self.prev_dir, style=self.dir_style ) if self.value: self.prev_dir = self.value if not os.path.isdir(self.prev_dir): self.prev_dir = os.path.dirname(self.prev_dir) return wx.ID_OK return wx.ID_CANCEL def get_value(self): """\ Return the dialog value returned during the last L{ShowModal()} call. @see: L{value} """ return self.value # end of class FileDirDialog class Application(object): """\ Properties of the application being created @ivar __filename: Name of the output XML file @ivar __saved: If True, there are no changes to save @ivar codegen_opt: If != 0, generates a separate file for each class @ivar for_version: Version string of major dot minor version number @type for_version: String @ivar klass: Name of the automatically generated class derived from wxApp @ivar name: Name of the wxApp instance to generate @ivar notebook: Notebook to show different property panels @cvar all_supported_versions: Supported wx versions @type all_supported_versions: List of strings """ all_supported_versions = ['2.6', '2.8'] def __init__(self, property_window): self.property_window = property_window self.notebook = wx.Notebook(self.property_window, -1) self.notebook.sizer = None self.notebook.SetAutoLayout(True) self.notebook.Hide() panel = wx.ScrolledWindow( self.notebook, wx.ID_ANY, style=wx.TAB_TRAVERSAL | wx.FULL_REPAINT_ON_RESIZE, ) panel_settings = wx.ScrolledWindow( self.notebook, wx.ID_ANY, style=wx.TAB_TRAVERSAL | wx.FULL_REPAINT_ON_RESIZE ) self.name = "app" self.__saved = True self.__filename = None self.klass = "MyApp" self.codegen_opt = config.default_multiple_files def set_codegen_opt(value): try: opt = int(value) except ValueError: pass else: self.codegen_opt = opt self.indent_mode = 1 self.indent_amount = config.default_indent_amount def set_indent_mode(value): try: opt = int(value) except ValueError: pass else: self.indent_mode = opt def set_indent_amount(value): try: opt = int(value) except ValueError: pass else: self.indent_amount = opt self.source_ext = 'cpp' self.header_ext = 'h' def set_source_ext(value): self.source_ext = value def set_header_ext(value): self.header_ext = value self.output_path = "" self.language = 'python' # output language def get_output_path(): return os.path.expanduser(self.output_path) def set_output_path(value): self.output_path = value self.is_template = False self.use_gettext = config.default_use_gettext def set_use_gettext(value): self.use_gettext = bool(int(value)) self.for_version = wx.VERSION_STRING[:3] def set_for_version(value): self.for_version = self.for_version_prop.get_str_value() self.access_functions = { 'name': (lambda : self.name, self.set_name), 'class': (lambda : self.klass, self.set_klass), 'code_generation': (lambda : self.codegen_opt, set_codegen_opt), 'indent_mode': (lambda : self.indent_mode, set_indent_mode), 'indent_amount': (lambda : self.indent_amount, set_indent_amount), 'source_ext' : (lambda : self.source_ext, set_source_ext), 'header_ext' : (lambda : self.header_ext, set_header_ext), 'output_path': (get_output_path, set_output_path), 'language': (self.get_language, self.set_language), 'encoding': (self.get_encoding, self.set_encoding), 'use_gettext': (lambda : self.use_gettext, set_use_gettext), 'for_version': (lambda : self.for_version, set_for_version), } self.name_prop = TextProperty(self, "name", panel, True) self.name_prop.set_tooltip( _('Name of the instance created from "Class"') ) self.klass_prop = TextProperty(self, "class", panel, True) self.klass_prop.set_tooltip( _("Name of the automatically generated class derived from wxApp") ) self.encoding = self._get_default_encoding() self.encoding_prop = TextProperty(self, 'encoding', panel) self.encoding_prop.set_tooltip( _("Encoding of the generated source files") ) self.use_gettext_prop = CheckBoxProperty(self, "use_gettext", panel, _("Enable gettext support")) self.use_gettext_prop.set_tooltip( _("Enable internationalisation and localisation for the generated source files") ) TOP_WIN_ID = wx.NewId() self.top_win_prop = wx.Choice(panel, TOP_WIN_ID, choices=[], size=(1, -1)) self.top_win_prop.SetToolTip(wx.ToolTip( _("This widget is used as top window in the wxApp start code") )) self.top_window = '' # name of the top window of the generated app codegen_tooltips = [ _("Write all source code in one file"), _("Split source code in one file per class / widget"), ] self.codegen_prop = RadioProperty(self, "code_generation", panel, [_("Single file"), _("Separate file for" \ " each class")], label=_("Code Generation"), tooltips=codegen_tooltips) self.indent_mode_prop = RadioProperty(self, "indent_mode", panel_settings, [_("Tabs"), _("Spaces")], columns=2, label=_("Indentation mode")) self.indent_amount_prop = SpinProperty(self, 'indent_amount', panel_settings, r=(1, 100)) self.indent_amount_prop.set_tooltip( _('Number of spaces or tabs used for one indentation level.') ) self.source_ext_prop = TextProperty(self, 'source_ext', panel_settings) self.source_ext_prop.set_tooltip(_('Extension of the source file')) self.header_ext_prop = TextProperty(self, 'header_ext', panel_settings) self.header_ext_prop.set_tooltip(_('Extension of the header file')) _writers = common.code_writers.keys() columns = 3 self.codewriters_prop = RadioProperty(self, "language", panel, _writers, columns=columns, sort=True, capitalize=True) self.codewriters_prop.set_str_value('python') for_version_tooltips = [ _("Generate source files for wxWidgets version %s") % version \ for version in self.all_supported_versions ] self.for_version_prop = RadioProperty( self, "for_version", panel, self.all_supported_versions, columns=2, label=_("wxWidgets compatibility"), tooltips=for_version_tooltips, ) self.for_version_prop.set_str_value(self.for_version) self.access_functions['use_new_namespace'] = ( self.get_use_old_namespace, self.set_use_old_namespace) self.use_old_namespace_prop = CheckBoxProperty( self, 'use_new_namespace', panel_settings, _('Use old import\n"from wxPython.wx import *"')) self.use_old_namespace_prop.set_tooltip( _('It is generally recommended to use the new namespace. ' 'The old one ("from wxPython.wx import *") has some ' 'significant drawbacks like potential namespace conflicts.' )) self.overwrite = config.default_overwrite self.access_functions['overwrite'] = \ (self.get_overwrite, self.set_overwrite) self.overwrite_prop = CheckBoxProperty( self, 'overwrite', panel, _('Overwrite existing sources'), ) self.overwrite_prop.set_tooltip( _("Overwrite existing source files or modify the code sequences " "generated by wxGlade in place") ) dialog = FileDirDialog( self, _('All files|*'), _("Select output file"), _("Select output directory"), wx.SAVE|wx.OVERWRITE_PROMPT ) self.outpath_prop = DialogProperty(self, "output_path", panel, dialog, label=_('Output path')) # update wildcards and default extention in the dialog self._update_dialog(self.outpath_prop.dialog, 'python') self.outpath_prop.set_tooltip( _("Output file or directory") ) BTN_ID = wx.NewId() btn = wx.Button( panel, BTN_ID, _("Generate code"), name="BtnGenerateCode", ) btn.SetToolTip(wx.ToolTip(_("Start generating source files"))) # layout of self.notebook - page "Application" #============================================= sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.name_prop.panel, 0, wx.EXPAND) sizer.Add(self.klass_prop.panel, 0, wx.EXPAND) sizer.Add(self.encoding_prop.panel, 0, wx.EXPAND) sizer.Add(self.use_gettext_prop.panel, 0, wx.EXPAND) szr = wx.BoxSizer(wx.HORIZONTAL) from widget_properties import _label_initial_width as _w label = wx.StaticText(panel, -1, _("Top window"), size=(_w, -1)) label.SetToolTip(wx.ToolTip( _("This widget is used as top window in the wxApp start code") )) szr.Add(label, 2, wx.ALL|wx.ALIGN_CENTER, 3) szr.Add(self.top_win_prop, 5, wx.ALL|wx.ALIGN_CENTER, 3) sizer.Add(szr, 0, wx.EXPAND) sizer.Add(self.codegen_prop.panel, 0, wx.ALL|wx.EXPAND, 4) sizer.Add(self.codewriters_prop.panel, 0, wx.ALL|wx.EXPAND, 4) sizer.Add(self.for_version_prop.panel, 0, wx.ALL|wx.EXPAND, 4) sizer.Add(self.overwrite_prop.panel, 0, wx.EXPAND) sizer.Add(self.outpath_prop.panel, 0, wx.EXPAND) sizer.Add(btn, 0, wx.ALL|wx.EXPAND, 5) self._add_page(_('Application'), panel, sizer) # layout self.notebook - page "Settings" #======================================= # general settings staticbox_general = wx.StaticBox( panel_settings, wx.ID_ANY, _("General Settings"), ) sizer_general = wx.StaticBoxSizer(staticbox_general, wx.VERTICAL) sizer_general.Add(self.indent_mode_prop.panel, 0, wx.ALL|wx.EXPAND, 4) sizer_general.Add(self.indent_amount_prop.panel, 0, wx.EXPAND) # python specific settings staticbox_python = wx.StaticBox( panel_settings, wx.ID_ANY, _("Python Settings"), ) sizer_python = wx.StaticBoxSizer(staticbox_python, wx.VERTICAL) sizer_python.Add(self.use_old_namespace_prop.panel, 0, wx.EXPAND) # C++ specific settings staticbox_cpp = wx.StaticBox( panel_settings, wx.ID_ANY, _("C++ Settings"), ) sizer_cpp = wx.StaticBoxSizer(staticbox_cpp, wx.VERTICAL) sizer_cpp.Add(self.source_ext_prop.panel, 0, wx.EXPAND) sizer_cpp.Add(self.header_ext_prop.panel, 0, wx.EXPAND) # add all to one sizer sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(sizer_general, 0, wx.EXPAND|wx.ALL, 3) sizer.Add(sizer_python, 0, wx.EXPAND|wx.ALL, 3) sizer.Add(sizer_cpp, 0, wx.EXPAND|wx.ALL, 3) self._add_page(_('Settings'), panel_settings, sizer) wx.EVT_BUTTON(btn, BTN_ID, self.generate_code) wx.EVT_CHOICE(self.top_win_prop, TOP_WIN_ID, self.set_top_window) # this is here to keep the interface similar to the various widgets # (to simplify Tree) self.widget = None # this is always None def set_name(self, value): value = "%s" % value if not re.match(self.set_name_pattern, value): self.name_prop.set_value(self.name) else: self.name = value set_name_pattern = re.compile('^[a-zA-Z]+[\w0-9-]*$') def set_klass(self, value): value = "%s" % value if not re.match(self.set_klass_pattern, value): self.klass_prop.set_value(self.klass) else: self.klass = value set_klass_pattern = re.compile('^[a-zA-Z]+[\w:.0-9-]*$') def _add_page(self, label, page, sizer): """\ Add a page to properties notebook (L{self.notebook}) """ page.SetAutoLayout(True) page.SetSizer(sizer) sizer.Layout() sizer.Fit(page) self.notebook.AddPage(page, label) h = page.GetSize()[1] page.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def _get_default_encoding(self): """\ Return determinated machine default character encoding. The default application L{config.default_encoding} is the fallback only. """ # try to set locale try: locale.setlocale(locale.LC_ALL) except locale.Error: # ignore problems by fallback to ascii print 'WARNING: Setting locale failed. Use "ascii" instead' return 'ascii' # try to query character encoding used in the selected locale try: encoding = locale.nl_langinfo(locale.CODESET) except AttributeError, e: print 'WARNING: locale.nl_langinfo(locale.CODESET) failed: %s' % str(e) # try getdefaultlocale, it used environment variables try: encoding = locale.getdefaultlocale()[1] except ValueError: encoding = config.default_encoding # On Mac OS X encoding may None or '' somehow if not encoding: encoding = config.default_encoding print 'WARNING: Empty encoding. Use "%s" instead' % encoding # check if a codec for the encoding exists try: codecs.lookup(encoding) except LookupError: print 'WARNING: No codec for encoding "%s" found. Use "ascii" instead' % encoding encoding = 'ascii' return encoding.upper() def get_encoding(self): return self.encoding def set_encoding(self, value): try: unicode('a', value) except LookupError, e: wx.MessageBox(str(e), _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR) self.encoding_prop.set_value(self.encoding) else: self.encoding = value def set_language(self, value): language = self.codewriters_prop.get_str_value() # update wildcards and default extention in the dialog self._update_dialog(self.outpath_prop.dialog, language) # check that the new language supports all the widgets in the tree if self.language != language: self.language = language self.check_codegen() def get_language(self): return self.language #codewriters_prop.get_str_value() def _get_saved(self): return self.__saved def _set_saved(self, value): if self.__saved != value: self.__saved = value t = common.app_tree.get_title().strip() if not value: common.app_tree.set_title('* ' + t) else: if t[0] == '*': common.app_tree.set_title(t[1:].strip()) saved = property(_get_saved, _set_saved) def _get_filename(self): return self.__filename def _set_filename(self, value): if not misc.streq(self.__filename, value): self.__filename = value if self.__saved: flag = ' ' else: flag = '* ' if self.__filename is not None: common.app_tree.set_title('%s(%s)' % (flag, self.__filename)) else: common.app_tree.set_title(flag) filename = property(_get_filename, _set_filename) def get_overwrite(self): return self.overwrite def set_overwrite(self, val): self.overwrite = bool(int(val)) def get_top_window(self): return self.top_window def set_top_window(self, *args): self.top_window = self.top_win_prop.GetStringSelection() def add_top_window(self, name): self.top_win_prop.Append("%s" % name) if not self.top_window: self.top_win_prop.SetSelection(self.top_win_prop.GetCount()-1) self.set_top_window() def remove_top_window(self, name): index = self.top_win_prop.FindString("%s" % name) if index != -1: if wx.Platform == '__WXGTK__': choices = [ self.top_win_prop.GetString(i) for i in \ range(self.top_win_prop.GetCount()) if i != index ] self.top_win_prop.Clear() for c in choices: self.top_win_prop.Append(c) else: self.top_win_prop.Delete(index) def update_top_window_name(self, oldname, newname): index = self.top_win_prop.FindString(oldname) if index != -1: if self.top_window == oldname: self.top_window = newname if wx.Platform == '__WXGTK__': sel_index = self.top_win_prop.GetSelection() choices = [ self.top_win_prop.GetString(i) for i in \ range(self.top_win_prop.GetCount()) ] choices[index] = newname self.top_win_prop.Clear() for c in choices: self.top_win_prop.Append(c) self.top_win_prop.SetSelection(sel_index) else: self.top_win_prop.SetString(index, newname) def reset(self): """\ resets the default values of the attributes of the app """ self.klass = "MyApp"; self.klass_prop.set_value("MyApp") self.klass_prop.toggle_active(False) self.name = "app" self.name_prop.set_value("app") self.name_prop.toggle_active(False) self.codegen_opt = config.default_multiple_files self.codegen_prop.set_value(config.default_multiple_files) self.indent_mode = 1 self.indent_amount = config.default_indent_amount self.cpp_source_ext = 'cpp' self.cpp_header_ext = 'h' self.output_path = "" self.outpath_prop.set_value("") # do not reset language, but call set_language anyway to update the # wildcard of the file dialog self.set_language(self.get_language()) self.top_window = '' self.top_win_prop.Clear() # ALB 2004-01-18 #self.set_use_new_namespace(True) #self.use_new_namespace_prop.set_value(True) self.set_use_old_namespace(False) self.use_old_namespace_prop.set_value(False) def show_properties(self, *args): sizer_tmp = self.property_window.GetSizer() child = sizer_tmp.GetChildren()[0] w = child.GetWindow() if w is self.notebook: return w.Hide() self.notebook.Reparent(self.property_window) child.SetWindow(self.notebook) w.Reparent(misc.hidden_property_panel) self.notebook.Show(True) self.property_window.Layout() self.property_window.SetTitle(_('Properties - <%s>') % self.name) try: common.app_tree.select_item(self.node) except AttributeError: pass def __getitem__(self, name): return self.access_functions[name] def generate_code(self, *args, **kwds): preview = kwds.get('preview', False) if not self.output_path: return wx.MessageBox(_("You must specify an output file\n" "before generating any code"), _("Error"), wx.OK|wx.CENTRE|wx.ICON_EXCLAMATION, self.notebook) if not preview and \ ((self.name_prop.is_active() or self.klass_prop.is_active()) \ and self.top_win_prop.GetSelection() < 0): return wx.MessageBox(_("Please select a top window " "for the application"), _("Error"), wx.OK | wx.CENTRE | wx.ICON_EXCLAMATION, self.notebook) from cStringIO import StringIO class EncStringIO(object): def __init__(self, encoding=None): self.out = StringIO() self.encoding = encoding def write(self, data): if self.encoding is not None and type(data) == type(u''): data = data.encode(self.encoding) self.out.write(data) def getvalue(self): return self.out.getvalue() # end of class EncStringIO out = EncStringIO(self.encoding) #common.app_tree.write(out) # write the xml onto a temporary buffer from xml_parse import CodeWriter try: # generate the code from the xml buffer cw = self.get_language() #self.codewriters_prop.get_str_value() if preview and cw == 'python': # of course cw == 'python', but... old = common.code_writers[cw].use_new_namespace common.code_writers[cw].use_new_namespace = True #False overwrite = self.overwrite self.overwrite = True class_names = common.app_tree.write(out) # write the xml onto a # temporary buffer if not os.path.isabs(self.output_path) and self.filename: out_path = os.path.join(os.path.dirname(self.filename), self.output_path) else: out_path = None CodeWriter( common.code_writers[cw], out.getvalue(), True, preview=preview, out_path=out_path, class_names=class_names, ) if preview and cw == 'python': common.code_writers[cw].use_new_namespace = old self.overwrite = overwrite except (errors.WxgOutputDirectoryNotExist, errors.WxgOutputDirectoryNotWritable, errors.WxgOutputPathIsDirectory, ), inst: wx.MessageBox( _("Error generating code:\n%s") % inst, _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR, ) except (IOError, OSError), msg: wx.MessageBox( _("Error generating code:\n%s") % msg, _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR, ) except Exception, msg: common.message.exception(_('Internal Error')) wx.MessageBox( _("An exception occurred while generating the code " "for the application.\n" "This is the error message associated with it:\n" " %s\n" "For more details, look at the full traceback " "on the console.\nIf you think this is a wxGlade bug," " please report it.") % msg, _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR, ) else: if not preview: if config.preferences.show_completion: # Show informational dialog wx.MessageBox( _("Code generation completed successfully"), _("Information"), wx.OK | wx.CENTRE | wx.ICON_INFORMATION, ) else: # Show message in application status bar app = wx.GetApp() frame = app.GetTopWindow() frame.user_message(_('Code generated')) def get_name(self): if self.name_prop.is_active(): return self.name return '' def get_class(self): if self.klass_prop.is_active(): return self.klass return '' def update_view(self, *args): pass def is_visible(self): return True def preview(self, widget, out_name=None): if out_name is None: import warnings warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, "application") out_name = os.tempnam(None, 'wxg') + '.py' #print 'Temporary name:', out_name widget_class_name = widget.klass # make a valid name for the class (this can be invalid for # some sensible reasons...) widget.klass = widget.klass[widget.klass.rfind('.')+1:] widget.klass = widget.klass[widget.klass.rfind(':')+1:] #if widget.klass == widget.base: # ALB 2003-11-08: always randomize the class name: this is to make # preview work even when there are multiple classes with the same name # (which makes sense for XRC output...) import random widget.klass = '_%d_%s' % \ (random.randrange(10**8, 10**9), widget.klass) self.real_output_path = self.output_path self.output_path = out_name real_codegen_opt = self.codegen_opt real_language = self.language real_use_gettext = self.use_gettext self.use_gettext = False self.language = 'python' self.codegen_opt = 0 overwrite = self.overwrite self.overwrite = 0 frame = None try: self.generate_code(preview=True) # dynamically import the generated module FrameClass = misc.import_name(self.output_path, widget.klass) if issubclass(FrameClass, wx.MDIChildFrame): frame = wx.MDIParentFrame(None, -1, '') child = FrameClass(frame, -1, '') child.SetTitle(' - ' + child.GetTitle()) w, h = child.GetSize() frame.SetClientSize((w+20, h+20)) elif not (issubclass(FrameClass, wx.Frame) or issubclass(FrameClass, wx.Dialog)): # the toplevel class isn't really toplevel, add a frame... frame = wx.Frame(None, -1, widget_class_name) if issubclass(FrameClass, wx.MenuBar): menubar = FrameClass() frame.SetMenuBar(menubar) elif issubclass(FrameClass, wx.ToolBar): toolbar = FrameClass(frame, -1) frame.SetToolBar(toolbar) else: panel = FrameClass(frame, -1) frame.Fit() else: frame = FrameClass(None, -1, '') # make sure we don't get a modal dialog... s = frame.GetWindowStyleFlag() frame.SetWindowStyleFlag(s & ~wx.DIALOG_MODAL) def on_close(event): frame.Destroy() widget.preview_widget = None widget.preview_button.SetLabel(_('Preview')) wx.EVT_CLOSE(frame, on_close) frame.SetTitle(_(' - %s') % frame.GetTitle()) # raise the frame frame.CenterOnScreen() frame.Show() # remove the temporary file (and the .pyc/.pyo ones too) for ext in '', 'c', 'o', '~': name = self.output_path + ext if os.path.isfile(name): os.unlink(name) except Exception, e: #common.message.exception(_('Internal Error')) widget.preview_widget = None widget.preview_button.SetLabel(_('Preview')) wx.MessageBox(_("Problem previewing gui: %s") % str(e), _("Error"), wx.OK|wx.CENTRE|wx.ICON_EXCLAMATION)#, self.notebook) # restore app state widget.klass = widget_class_name self.output_path = self.real_output_path del self.real_output_path self.codegen_opt = real_codegen_opt self.language = real_language self.use_gettext = real_use_gettext self.overwrite = overwrite return frame def get_use_old_namespace(self): try: return not common.code_writers['python'].use_new_namespace except: return False def set_use_old_namespace(self, val): try: common.code_writers['python'].use_new_namespace = not bool(int(val)) except: pass def check_codegen(self, widget=None, language=None): """\ Checks whether widget has a suitable code generator for the given language (default: the current active language). If not, the user is informed with a message. """ if language is None: language = self.language if widget is not None: cname = common.class_names[widget.__class__.__name__] if language != 'XRC': ok = cname in common.code_writers[language].obj_builders else: # xrc is special... xrcgen = common.code_writers['XRC'] ok = xrcgen.obj_builders.get(cname, None) is not \ xrcgen.NotImplementedXrcObject if not ok: common.message.warn( _('No %s code generator for %s (of type %s)' ' available'), misc.capitalize(language), widget.name, cname) else: # in this case, we check all the widgets in the tree def check_rec(node): if node.widget is not None: self.check_codegen(node.widget) if node.children: for c in node.children: check_rec(c) if common.app_tree.root.children: for c in common.app_tree.root.children: check_rec(c) def _update_dialog(self, dialog, language): """\ Update wildcards and default extension in the generic file and directory dialog (L{FileDirDialog}). """ ext = getattr(common.code_writers[language], 'default_extensions', []) wildcards = [] for e in ext: wildcards.append( _('%s files (*.%s)|*.%s') % (misc.capitalize(language), e, e) ) wildcards.append(_('All files|*')) dialog.wildcard = '|'.join(wildcards) if ext: dialog.default_extension = '.%s' % ext[0] else: dialog.default_extension = None # end of class Application wxglade-0.6.8.orig/TODO.txt0000644000175000017500000000431211676054124015631 0ustar georgeskgeorgeskwxGlade TODO list ================= Last update 2012-12-26 The list is more or less sorted by priority Next release: ------------- - Simplify Path handling probably split of in user path and system path e.g. for templates - Update translation - ... Real TODO (# = Partially done): ------------------------------- - Undo/Redo - Better XRC support (custom classes, separate files, ...) (#: custom classes - see the tutorial) - Event handlers support - ListCtrl and TreeCtrl (#: need to add more properties) - ToolBar for frames (#: no controls yet) - complete MenuBar with icons and StatusBar messages support (#) - Less frequently used controls - on-line help (with wxHtmlHelpController) - test of the various modules with unittest (this might come earlier...) - gettext support (#: done for code generation, todo for wxGlade itself) - ``Templates'' for particular windows (for example, something as a dialog with an image, a centered label and a couple of buttons) - TabOrder property (this may be hard though) - (Maybe) Java code generator - ... Things Done: ------------ - Code generation on separate files - "tags" on the generated code, to detect the portions of code to replace and those to keep as is, when updating an existing file - Investigation of the many memory leaks - speedup of the xml loading - separation between window objects and sizer ones in the generated code - Code generation from the command line, witout starting the GUI - support wxWindows xml resources (XRC) through a code generator - support for C++ code generation - Possibility to change the type of a sizer after its creation - Possibility to change the position of a widget inside its sizer - Edit -> Preferences... to customize some aspects of wxGlade - International characters support - Grid - Auto saving/backup of wxg files (and possibly also of generated sources) - Import of "wxGlade-friendly" XRC files - Preview of toplevel widgets - Checks on the values of some properties (name, class,...) - More basic properties for widgets (enabled for example) - ScrolledWindow (as a `scrollable' property for panels) - widgets path, to let the user add new widget modules - support for Perl code generation wxglade-0.6.8.orig/font_dialog.py0000644000175000017500000001440612150154266017163 0ustar georgeskgeorgesk# generated by wxGlade 0.2 on Sat Nov 30 15:30:36 2002 # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import misc import common _reverse_dict = misc._reverse_dict class wxGladeFontDialog(wx.Dialog): font_families_to = { 'default': wx.DEFAULT, 'decorative': wx.DECORATIVE, 'roman': wx.ROMAN, 'swiss': wx.SWISS, 'script':wx.SCRIPT, 'modern': wx.MODERN } font_families_from = _reverse_dict(font_families_to) font_styles_to = { 'normal': wx.NORMAL, 'slant': wx.SLANT, 'italic': wx.ITALIC } font_styles_from = _reverse_dict(font_styles_to) font_weights_to = {'normal': wx.NORMAL, 'light': wx.LIGHT, 'bold': wx.BOLD } font_weights_from = _reverse_dict(font_weights_to) font_families_to['teletype'] = wx.TELETYPE font_families_from[wx.TELETYPE] = 'teletype' def __init__(self, *args, **kwds): # begin wxGlade: wxGladeFontDialog.__init__ kwds["style"] = wx.DEFAULT_DIALOG_STYLE wx.Dialog.__init__(self, *args, **kwds) self.label_2_copy = wx.StaticText(self, -1, _("Family:")) self.label_3_copy = wx.StaticText(self, -1, _("Style:")) self.label_4_copy = wx.StaticText(self, -1, _("Weight:")) self.family = wx.Choice(self, -1, choices=[ "Default", "Decorative", "Roman", "Script", "Swiss", "Modern"]) self.style = wx.Choice(self, -1, choices=["Normal", "Slant", "Italic"]) self.weight = wx.Choice(self, -1, choices=["Normal", "Light", "Bold"]) self.label_1 = wx.StaticText(self, -1, _("Size in points:")) self.point_size = wx.SpinCtrl(self, -1, "", min=0, max=100) self.underline = wx.CheckBox(self, -1, _("Underlined")) self.font_btn = wx.Button(self, -1, _("Specific font...")) self.static_line_1 = wx.StaticLine(self, -1) self.ok_btn = wx.Button(self, wx.ID_OK, _("OK")) self.cancel_btn = wx.Button(self, wx.ID_CANCEL, _("Cancel")) self.__set_properties() self.__do_layout() # end wxGlade self.value = None wx.EVT_BUTTON(self, self.font_btn.GetId(), self.choose_specific_font) wx.EVT_BUTTON(self, self.ok_btn.GetId(), self.on_ok) def choose_specific_font(self, event): dialog = wx.FontDialog(self, wx.FontData()) if dialog.ShowModal() == wx.ID_OK: font = dialog.GetFontData().GetChosenFont() family = font.GetFamily() for f in (wx.VARIABLE, wx.FIXED): if family & f: family = family ^ f self.value = "['%s', '%s', '%s', '%s', '%s', '%s']" % \ (font.GetPointSize(), self.font_families_from[family], self.font_styles_from[font.GetStyle()], self.font_weights_from[font.GetWeight()], font.GetUnderlined() and 1 or 0, font.GetFaceName()) self.EndModal(wx.ID_OK) def on_ok(self, event): self.value = "['%s', '%s', '%s', '%s', '%s', '']" % \ (self.point_size.GetValue(), self.family.GetStringSelection().lower(), self.style.GetStringSelection().lower(), self.weight.GetStringSelection().lower(), self.underline.GetValue() and 1 or 0) self.EndModal(wx.ID_OK) def get_value(self): return self.value def set_value(self, props): self.family.SetStringSelection(props[1].capitalize()) self.style.SetStringSelection(props[2].capitalize()) self.weight.SetStringSelection(props[3].capitalize()) try: try: underline = int(props[4]) except ValueError: if props[4].lower() == "true": underline = 1 else: underline = 0 self.underline.SetValue(underline) self.point_size.SetValue(int(props[0])) except ValueError: common.message.exception(_('Internal Error')) def __set_properties(self): # begin wxGlade: wxGladeFontDialog.__set_properties self.SetTitle(_("Select font attributes")) self.family.SetSelection(0) self.style.SetSelection(0) self.weight.SetSelection(0) self.ok_btn.SetDefault() # end wxGlade def __do_layout(self): # begin wxGlade: wxGladeFontDialog.__do_layout sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_2 = wx.BoxSizer(wx.VERTICAL) sizer_4 = wx.BoxSizer(wx.HORIZONTAL) sizer_5 = wx.BoxSizer(wx.VERTICAL) grid_sizer_1_copy = wx.FlexGridSizer(2, 3, 2, 10) grid_sizer_2_copy = wx.FlexGridSizer(2, 3, 2, 5) grid_sizer_2_copy.Add(self.label_2_copy, 0, wx.ALIGN_BOTTOM, 3) grid_sizer_2_copy.Add(self.label_3_copy, 0, wx.ALIGN_BOTTOM, 3) grid_sizer_2_copy.Add(self.label_4_copy, 0, wx.ALIGN_BOTTOM, 3) grid_sizer_2_copy.Add(self.family, 0, wx.EXPAND, 0) grid_sizer_2_copy.Add(self.style, 0, wx.EXPAND, 0) grid_sizer_2_copy.Add(self.weight, 0, wx.EXPAND, 0) grid_sizer_2_copy.AddGrowableCol(0) grid_sizer_2_copy.AddGrowableCol(1) grid_sizer_2_copy.AddGrowableCol(2) sizer_5.Add(grid_sizer_2_copy, 0, wx.EXPAND, 0) grid_sizer_1_copy.Add(self.label_1, 0, wx.ALIGN_BOTTOM, 0) grid_sizer_1_copy.Add((20, 5), 0, wx.ALIGN_BOTTOM, 0) grid_sizer_1_copy.Add((20, 5), 0, wx.ALIGN_BOTTOM, 0) grid_sizer_1_copy.Add(self.point_size, 0, 0, 0) grid_sizer_1_copy.Add(self.underline, 0, wx.EXPAND, 0) grid_sizer_1_copy.Add(self.font_btn, 0, 0, 0) grid_sizer_1_copy.AddGrowableCol(1) sizer_5.Add(grid_sizer_1_copy, 0, wx.TOP|wx.EXPAND, 3) sizer_5.Add(self.static_line_1, 0, wx.TOP|wx.EXPAND, 8) sizer_2.Add(sizer_5, 0, wx.EXPAND, 0) sizer_4.Add(self.ok_btn, 0, wx.RIGHT, 12) sizer_4.Add(self.cancel_btn, 0, 0, 0) sizer_2.Add(sizer_4, 0, wx.TOP|wx.ALIGN_RIGHT, 9) sizer_1.Add(sizer_2, 1, wx.ALL|wx.EXPAND, 10) self.SetAutoLayout(1) self.SetSizer(sizer_1) sizer_1.Fit(self) sizer_1.SetSizeHints(self) self.Layout() # end wxGlade self.CenterOnScreen() # end of class wxGladeFontDialog wxglade-0.6.8.orig/docs/0000755000175000017500000000000012170277707015257 5ustar georgeskgeorgeskwxglade-0.6.8.orig/docs/BuildingInstaller.txt0000644000175000017500000000264112167336636021441 0ustar georgeskgeorgeskBuilding a wxGlade installer HOWTO ---------------------------------- Alberto Griggio 2007/04/20 Carsten Grohmann 2011/12/19 1. Setup PyInstaller -------------------- Install the current version of PyInstaller from http://www.pyinstaller.org. Follow the instruction published at PyInstallers homepage. This procedure is tested using PyInstaller versions 1.5 and 1.5.1. 2. Generate an executable ------------------------- - Change into source base directory and open a command prompt - Type python.exe \Build.py --noconfirm --buildpath \wxglade\build install\pyinstaller\wxglade.spec If everything works, you should now have two new subdirectories, "build" and "dist". - Now you should have a working executable in "bdist", called "wxglade.exe". If it works, you can move on to the next step 3. Generate an installer ------------------------ - Download and install Inno Setup from here: http://www.jrsoftware.org/isinfo.php - To create the installer for the Standalone Edition open "wxglade-SAE-installer.iss" with Inno Setup and run it. - To create the regular installer open "wxglade-installer.iss" with Inno Setup and run it. - If everything works, you should have the installer executables in the "dist" directory. "wxGlade-SAE--setup.exe" is the installer of the Standalone Edition. And "wxGlade--setup.exe" is the regular installer. - All done! wxglade-0.6.8.orig/docs/img/0000755000175000017500000000000012170277707016033 5ustar georgeskgeorgeskwxglade-0.6.8.orig/docs/img/button_button.gif0000644000175000017500000000031411621715605021420 0ustar georgeskgeorgeskGIF89aÂÿÿÿÖÖÖ–––{{{ÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP,€ºÜþ+ÈI«½à̓Ð]H}béfG¦*ÊbëÍÀ0ºYJØS,áÝ­ä{8׀Ǥ%¾œ¤iãMž'â„j½v£(j À‚·ÓqÚ;¤(›j6Rk2'uß{=O$øÿ€~|K†‡ˆˆm/0EŒPŽQs”“–$›œžŸ  ;wxglade-0.6.8.orig/docs/img/spacer_button.gif0000644000175000017500000000030011621715605021355 0ustar georgeskgeorgeskGIF89aÂÿÿÿÖÖÖ–––’’’ÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP,tºÜþ+ÈI«½à̓Ð]H}béfG¦*Êbë »r×6=¤û¨¦pr %=KòHü“•A)) ¥Ø¬Ö8¬:¥„°8 &POÑáy"ž­ÝnE-‡ë´€<„Ç]Š~h>ƒ„…^‡ˆ‰€~$‘’“” ;wxglade-0.6.8.orig/docs/img/custom_widget.gif0000644000175000017500000000043211621715605021370 0ustar georgeskgeorgeskGIF89aãÿÿÿÖÖÖ–––{{{ÞÞÞ㎎ߧ§ÿõ//Ú¾¾ñGGúì__èwwÿÿÿ!þCreated with The GIMP!ù ,®ÈI«½3èÍ»ÿŽd ˆeÊjk¢nÉrCmßø½ÂÚ@üÀ (ì:>WñH#(›Ù&Ù1že” j ˆ0"¡àh5ÒžS£cÁ 3Íõ*®›°œ9]{c{[H~€ eg/„ ‹i]…€YsŒM‰‚t—™|j X‘š“^)’u•$²H¸®u¼½¾¿½§1 “ÃÅÆÂÉGÍÎÏÐÑÒ;wxglade-0.6.8.orig/docs/img/text_ctrl_button.gif0000644000175000017500000000034311621715605022117 0ustar georgeskgeorgeskGIF89aÂÿÿÿÖÖÖ–––{{{ÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP,—ºÜþ+ÈI«½à̓Ð]H}béfG¦* p,Ï3ºJ¡ï|¿g“Û‹)%Â\ÑA<ž(ʱѴ¹¢Ì¬39ì„€nQ ^§a q-#ÏÙ.Zc…Ê¿r0Ýlg¼€z€[p^k m{o}`x_z„Kd‹OX”u˜,œŸš|žB¥§¨¤«©.­Œ²³´µ¶· ;wxglade-0.6.8.orig/docs/img/sizer_slot.gif0000644000175000017500000000023111621715605020705 0ustar georgeskgeorgeskGIF89a¡ÀÀÀÿÿÿÿÿÿ!þCreated with The GIMP!ù ,Q„§©ÆýN”ÍUT§Í÷jÌAÞ.¤XR©ŠšëÖ²n,Ãó]ƒ´Ýñ¾ž5ŸâixÌ_¦s‰ûA‘̤”9UZŸØ-ÑkÍ^wÜ—Ø 6§wçi;wxglade-0.6.8.orig/docs/img/notebook_button.gif0000644000175000017500000000047411621715605021734 0ustar georgeskgeorgeskGIF89a„ÿÿÿÖÖÖ–––lllÙÙÙ˜˜˜ØØØ|||~~~  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP,¨ Ždižc ®lë¾Ït ÈuÎÞzoã¾/(aÕi@bŽ®¤ @¨V…l«…¶¤1ëU»%{wư˜›eo£iê52 [€ƒxÏG$î,r|ƒ €J„„~ˆSŠƒ jb “‚•U ™›–+`š›Œ£qª«¬¬ª“   ¸¹¹ “G_iÂÁÅ*`ÇÈÄÊÉÍ2ÑÒÓÔÕÖ!;wxglade-0.6.8.orig/docs/img/box_sizer_button.gif0000644000175000017500000000154411621715605022117 0ustar georgeskgeorgeskGIF89aÆÿÿÿÖÖÖ–––ùùùûûûüüüýýýñññòòòÛÛÛÕÕÕÙÙÙÓÓÓÔÔÔÎÎÎÍÍ͉‰‰ÜÜÜÒÒÒßßß×××tttþþþÐÐÐØØØÝÝÝxxx ÚÚÚÞÞÞzzzõõõooo{{{ˆˆˆ|||ƒƒƒ øøøðððÑÑÑàààáááÉÉɆ††ôôôuuuÌÌÌçççÇÇÇ„„„lll‚‚‚}}}yyywww€€€ úúú÷÷÷âââËËËÈÈÈÏÏÏäääîîîvvvsss ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP,þ€‚ƒ„…†‡‚ŒŽ‘Š’•–”—›Ž™‹œ žŽ¨©¨‡ ¢ ¶·¶  ¯šŒ¼ÉÊÉ ÍߌÜÝÜ   Õ£ îïî !É"é#$%"$aâD "JœÈÇ£TÈ@±"ÅhL‘b…¾bHiIr¤,µ`ˆ‰˜.¼ðæ „ 0ÜÅ1ã£.¸¸@´(Ñ tRØP£gC—,l<£E•j…D]Üh°Ð'/6àÂÅ…àÈÁÒ¡±:vð(A·.Ý>jœø$ !>g¢±°á ˆ †˜¡­KRŠ  ¡ #‚X~jM€‚8Àƒç‡# â¸3$I,Ðì& ÌŠHáóÀÕÔ‘,°ÁaCY¼9;"ÐA€’ªUPh°Äl}2iòÃÉïà¿;ñ 20lnÙYcÃð!®`\Ø'(KnïWʯ?’¨(à€ß&x` ;wxglade-0.6.8.orig/docs/img/frame_button.gif0000644000175000017500000000040111621715605021174 0ustar georgeskgeorgeskGIF89aãÿÿÿÖÖÖ–––{{{òòò{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP,ÈI«½2Á»ÿ`(hbi y®^º±° Çê|Ê¡ï|߇`8 ȤrIkbBa˜TËQÔÉF}`%0èæó5<£/ênÙý®ÄÉì(½>¹{Í|vc{~s‡y€‰‹Ž9…|”Caš:ƒP ¡¢££k6+^§!©ª¬­¦°«P²¦·¸¹º»¼¤¾¿À ;wxglade-0.6.8.orig/docs/tech_notes.txt0000644000175000017500000002206411621715605020151 0ustar georgeskgeorgesk wxGlade technical notes ----------------------- Last update: 2003-06-26, but only section 9. The rest has not been updated since 2002-07-22, and it's likely be very outdated in some parts This is an informal overview of wxGlade internals, made through a sample session of use. Each action of the hypotetical user will be described from the point of view of the application, to (hopefully) understand what's happening behind the scenes. These notes are *absolutely* incomplete and in some cases they might be outdated or not completely correct: the best reference is always the source code. 1. Startup ---------- The program starts from the function 'main' in the module 'main': this creates an instance of wxGlade (a subclass of wxApp), which in turn creates a wxGladeFrame: this is the main window of the app, i.e. the one with the palette of buttons. The initialization of wxGladeFrame consists of three steps: - Creation of the three frames of the app, the palette itself, the tree and the property window - Loading of the code generator modules. The 'codegen/' subdir is scanned to find the available code generators: when a python module is found, the app tries to load it and to access its 'writer' attribute: if this is succesfully accomplished, such 'writer' object is considered a valid code generator, and is inserted into the 'common.code_writers' dict (the key used is the 'language' attribute of the writer itself) - Loading of the widget and sizer modules. To load the widgets, the file 'widgets/widgets.txt' is read, and the app tries to import every widget module listed on such file. For every module succesfully imported, the 'initialize' function is then called: this function sets up the builder and code generator functions for a particular widget (explained later), and returns a wxBitmapButton instance to be added to the main palette. The loading of the sizers is more or less the same, except that all the sizers are in the same module, 'edit_sizers', and the initialization function (called 'init_all') returns a list of wxBitmapButton objects 2. Adding a toplevel widget --------------------------- When the user clicks on a button of a toplevel widget (a Frame or a Dialog), the method 'add_toplevel_object' of wxGladeFrame is called: this is responsible for the addition of the widget to the app. This happens in this way: - the name of the class of the widget to add is obtained: this is done with the use of the 'common.refs' dict, which maps the ids of the buttons of the palette to the class names of the widgets. - with the name just obtained, the appropriate factory function for the widget to add is got from the 'common.widgets' dict. This function must accept three parameters: a reference to the parent widget (None in this case), a reference to the sizer to which the widget will be added (again None for toplevel windows) and the zero-based position inside the sizer (once again, this is unused for toplevel windows) - the call of the factory function actually builds the widgets and inserts it in the 'common.app_tree' tree with a call to its method 'insert'. The '__init__' method of the widget also builds all the Properties of the object and stores them in the 'self.properties' dict 3. Adding a toplevel sizer -------------------------- This is similar to the addition of a toplevel widget, but the action is performed in two steps: - when the user clicks on the button in the palette, the method 'add_object' of wxGladeFrame is called: this sets the global variables 'common.adding_widget' and 'common.adding_sizer' to True, and stores the class name of the sizer to add in the global 'common.widget_to_add' (the name is obtained from the 'common.refs' dict as described above) - when the user left-clicks the mouse inside the previously added toplevel widget, its 'drop_sizer' method is called, which is responsible of the addition of the sizer: it calls the factory function for the sizer (passing self as the first argument), which will build the object and add it to the tree 4. Adding a normal widget/sizer ------------------------------- This step is more or less the same as step 3: - 'wxGladeFrame.add_object' is called in response to a button click - when the user ``drops'' the widget inside a slot in a sizer, the method 'drop_widget' of edit_sizers.SizerSlot is called, which in turn calls the appropriate factory function with arguments 'self.parent', 'self.sizer' and 'self.pos' (i.e. the parent, sizer and position inside the sizer of the slot that will be replaced). Factory functions of non-toplevel objects call, apart from 'common.app_tree.insert' to insert the object in the tree, the method 'add_item' of edit_sizers.SizerBase, to add the object to the sizer and to remove the slot. For managed widgets/sizers, the '__init__' method also builds the Properties which control the layout of the object inside a sizer, and stores them in the 'self.sizer_properties' dict 5. Changing the value of a Property ----------------------------------- When the user selects a widget the property window changes to display the properties of the selected object: this is done by the functions 'show_properties' of edit_windows.EditBase and edit_sizers.SizerBase, which are called inside two event handlers for focus and tree selection events. When the value of a Property is changed, its setter function is called to update the aspect/layout of the widget the Property belongs to: such function is obtained from a call to the widget's '__getitem__' method, which must return a 2-tuple (getter, setter) for the Property 6. Saving the app ----------------- This operation is performed by the 'common.app_tree' Tree: for every Node of the tree, an 'object' xml element is generated, with the following attributes: name, class, base (class). Each object contains an element for each Property (generated by the 'write' method of Property) and then an 'object' element for all its sub-widgets and/or sizers. Properties in the 'sizer_properties' dict are treated in a different way, as well as the children of a sizer, which are sub-elements of 'sizeritem' objects: see the source code for details. 7. Loading an app from an xml file ---------------------------------- This is done by 'xml_parse.XmlWidgetBuilder', a subclass of xml.sax.handler.ContentHandler. Basically, the steps involved are the following: - when the start of an 'object' element is reached, an XmlWidgetObject instance is created and pushed onto a stack of the objects created: such object in turn calls the appropriate ``xml builder'' function (got from the 'common.widgets_from_xml' dict) that creates the widget: this function is similar to the factory function used to build the widget during an interactive session, see the code for details and differences - when the end of an 'object' element is reached, the object at the top of the stack is removed, and its widget (see the source of XmlWidgetObject) is laid out - when the end of a Property element is reached, the appropriate setter function of the owner of the Property is called. This is the default behaviour, suitable for simple properties. For more complex properties, whose xml representation consists of more sub-elements, each widget can define a particular handler: see for example FontHandler in edit_windows.WindowBase 8. Generating the source code ----------------------------- This section is the result of a cut & paste of the comment at the beginning of 'codegen/py_codegen.py'. It is *VERY* incomplete. The ContentHandler subclass which drives the code generation is xml_parse.CodeWriter How the code is generated: every time the end of an object is reached during the parsing of the xml tree, either the function 'add_object' or the function 'add_class' is called: the latter when the object is a toplevel one, the former when it is not. In the last case, 'add_object' calls the appropriate ``writer'' function for the specific object, found in the 'obj_builders' dict. Such function accepts one argument, the CodeObject representing the object for which the code has to be written, and returns 3 lists of strings, representing the lines to add to the '__init__', '__set_properties' and '__do_layout' methods of the parent object. NOTE: the lines in the '__init__' list will be added in reverse order 9. For contributors ------------------- You are, of course, free to make any chages/additions you want to wxGlade, in whatever way you like. If you decide to contribute them back, however, here are some simple (stylistic) rules to follow: note that these are only general indications, if you think they don't fit somewhere, feel free to ignore them. - class names are usually CamelCase - variables, functions and method names are lower_case_with_unserscores - ``constants'' are UPPER_CASE - source lines are at most 79 characters long - class bodies are usually ended by a # end of class ClassName comment - source files use Unix EOL conventions (LF) if possible. In any case, please don't mix Unix and Windows EOLs - put your copyright info whenever appropriate - that's all folks!! wxglade-0.6.8.orig/docs/ReleaseSteps.txt0000644000175000017500000000111512167336636020420 0ustar georgeskgeorgeskSteps to publish a new version ============================== 1. Update documentation e.g. CHANGES.txt, NEWS.txt and README.txt 2. Change the version number in common.py and wxglade-installer.iss 3. Set SHOW_CONSOLE to False in install/pyinstaller/wxglade.spec 3. Commit all open changes 4. Create a new Mercurial tag $ hg tag rel_0.6.4 5. Push changes into public repository 6. Create all packages - build windows installer (see docs/BuildingInstaller.txt) - create zip and tar.gz source packages 7. Change version number in common.py and wxglade-installer.iss to HG wxglade-0.6.8.orig/docs/src/0000755000175000017500000000000012170277707016046 5ustar georgeskgeorgeskwxglade-0.6.8.orig/docs/src/manual.xml0000755000175000017500000026051112167336636020060 0ustar georgeskgeorgesk wxGlade manual 2013-07-08 Marcello Semboli Alberto Griggio Carsten Grohmann Preface This manual describes Alberto Griggio's wxGlade program, a Python, Perl, Lisp, C++ and XRC Graphical User Interface (GUI) editor for UNIX and Microsoft Windows. Each of the chapters in this manual is designed as a tutorial for using wxGlade and a reference for widgets supported until now.
Contacts Check the project homepage http://wxglade.sourceforge.net for the mailing list to discuss the project. Use the lists for questions, proposals, bug reports and collaboration. Information, support and bug reports can be addressed to the wxGlade mailing list too. Any kind of feedback is always welcome. Marcello Semboli dinogen@siena.linux.it has written the original version of this document. The current version of this document is maintained by Carsten Grohmann.
Copyrights and Trademarks wxGlade is Copyright 2002-2007 by Alberto Griggio. Use and distribution of wxGlade is governed by the MIT license, located in Appendix A. wxWidgets is Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al. See: http://www.wxwidgets.org for details. UNIX is a registered trademark of the X Open Group, Inc. Microsoft and Windows are registered trademarks of Microsoft Corporation.
Abbreviations The following abbreviations are used in this manual: GUI Graphical User Interface OS Operating system SAE Standalone Edition wx abbreviation for wxWidgets wxg File extension used by wxGlade to store the project in a XML file. wxWidgets wxWidgets a widget toolkit and tools library for creating graphical user interfaces (GUIs) for cross-platform applications. wxWidgets is open source and written in C++. WYSIWYG What You See Is What You Get. X11 The X Window System version 11. XRC XML-based system for describing wxWidgets resources like dialogs, menus or toolbars. Those resources are loaded into the application at run-time. i18n Numeronyms for internationalisation support. Internationalisation means adapting software to different languages, regional differences, ... gettext Widespread internationalisation (i18n) and localisation system.
Introduction to wxGlade
What is wxGlade? wxGlade is an open source graphical user interface builder written in Python using popular widget toolkit wxWidgets.
wxGlade windows
wxGlade allows to create graphical user interfaces using wxWidgets. The designer can arrange different widgets using a drag and drop WYSIWYG editor. This simplifies the creation of a graphical user interface in comparison with manual coded graphical user interfaces. wxGlade is able to generate source code for Python, Perl, Lisp, C++ and XRC based on the designed GUI. As you can guess by the name, its model is Glade, the famous GTK+/GNOME GUI builder, with which wxGlade shares the philosophy and the look & feel (but not a line of code).
What Can You Do with wxGlade? With wxGlade you can: Design the whole GUI of your application inclusive simple or complex dialogs as well as menu bars, different kinds of buttons and text widgets, bitmaps, ... Use the graphical editor for editing, cutting and pasting widgets Convert your design in source code of your favorite language Run wxGlade on a wide variety of operation systems since it is written in Python
What is wxGlade NOT? wxGlade is not a full featured IDE and will never be one. wxGlade is just a graphical user interface builder. The generated code does nothing apart from displaying the created widgets. If you are looking for a complete IDE, maybe Boa Constructor http://boa-constructor.sourceforge.net or PythonCard http://www.pythoncard.org is the right tool.
Basics You need to know the basics of wxWidgets or wxPython, as well as the basics of C++, Python, Perl or Lisp. You can't use wxGlade if you do not have any basic understanding of programming. You can't learn wxWidgets programming from reading this manual either.
Requirements and Supported Platforms wxGlade has been tested and run on Windows, Linux, Mac OSX. Because wxGlade is written in Python using wxPython, it can also be run on any platform that supports Python and wxPython. Especially the wxGlade requirements are: Python 2 - at least 2.3 or any later version of Python 2 wxPython 2.6, 2.8 or 30 wxWidgets 2.6, 2.8 or 3.0, the wxWidgets are often bundled with wxPython The support for wxWidgets 3.0 as well as wxPython 3.0 based currently on the development release series 2.9 of wxPython. wxWidgets is available at http://www.wxwidgets.org and wxPython at http://www.wxpython.org.
Download Source and binary packages for stable versions are available at http://sourceforge.net/projects/wxglade. You can get the development version from Bitbucket.org at https://bitbucket.org/agriggio/wxglade/overview using anonymous Mercurial (hg) access.
Installation wxGlade is available in 4 different package types: the sources packages (.zip and .tar.gz) the full installer at Microsoft Windows (wxGlade-VERSION-setup.exe) the installer of the standalone edition at Microsoft Windows (wxGlade-SAE-VERSION-setup.exe) development version fetched with Mercurial or downloaded the current packaged development version from https://bitbucket.org
Installing at Microsoft Windows The default installer requires a local installation Python and wxPython. The wxWidgets are bundled with wxPython on Microsoft Windows. Thereby you don't need to install wxWidgets separately. There is no need to install additional packages for the standalone edition, because the standalone edition includes the required parts of Python, wxPython and wxWidgets. The installation process is quite simple. Just download the installer file, execute it and follow the installer instructions.
Installing at Unix/Linux The current Linux distributions provide wxGlade packages. Use the distribution specific install mechanism to install the wxGlade package and all dependencies. You may install wxGlade from the source package if your distribution doesn't contain a proper package.
Installing from Source The installation from scratch requires Python, wxPython and wxWidgets. Those three components have to be installed first. Maybe you could use already packaged versions of those components for your operating system. Otherwise read the installation documentation of the missing components and follow the instructions. There are two ways for installing wxGlade from source - single or multi user installation. Download a source package or a development package in a first step.
Single user installation Extract the downloaded package into a separate directory e.g. a subdirectory below user's home directory. Change in this directory and execute the wxglade file on Unix/Linux or wxglade.pyw on Microsoft Windows. That's all. Installations below users home directory don't require administrative permissions.
Multi user installation - variant 1 The first variant of a multi user installation is very similar to except the installation directory. And probably you need administrative permissions. You could extract the wxGlade source package e.g. into c:\program file\wxglade on Microsoft Windows or into /opt/wxglade on Unix/Linux.
Multi user installation - variant 2 Extract the downloaded package into a temporary directory. Change in this directory and execute the Python setup script using python setup.py in a terminal window. Installing wxGlade at /opt/wxglade # python setup.py install --prefix /opt/wxglade running install running build running build_py creating build creating build/lib.linux-i686-2.7 creating build/lib.linux-i686-2.7/wxglade creating build/lib.linux-i686-2.7/wxglade/widgets creating build/lib.linux-i686-2.7/wxglade/widgets/combo_box [...] copying docs/html/ch04s23.html -> /opt/wxglade/share/doc/wxglade/doc/html copying docs/html/ch04s26.html -> /opt/wxglade/share/doc/wxglade/doc/html copying docs/html/ch05s02.html -> /opt/wxglade/share/doc/wxglade/doc/html copying docs/html/pr01.html -> /opt/wxglade/share/doc/wxglade/doc/html creating /opt/wxglade/share/doc/wxglade/doc/pdf copying docs/pdf/manual.pdf -> /opt/wxglade/share/doc/wxglade/doc/pdf creating /opt/share/man creating /opt/share/man/man1 copying docs/man/wxglade.1 -> /opt/wxglade/share/man/man1 copying docs/man/manpage.xml -> /opt/wxglade/share/doc/wxglade copying docs/src/manual.xml -> /opt/wxglade/share/doc/wxglade running install_egg_info Writing /opt/wxglade/lib/python2.7/site-packages/wxGlade-0.6.5_-py2.7.egg-info After the installation has finished the wxGlade main script wxglade is located at <install directory>/bin. Execute the script to start wxGlade Starting wxGlade at /opt/wxglade/bin/wxglade # /opt/wxglade/bin/wxglade Starting wxGlade version 0.6.5 on Python 2.7.2+ Base directory: /opt/wxglade/lib/python2.7/site-packages/wxglade Documentation directory: /opt/wxglade/lib/python2.7/site-packages/wxglade/docs Icons directory: /opt/wxglade/lib/python2.7/site-packages/wxglade/icons Build-in widgets directory: /opt/wxglade/lib/python2.7/site-packages/wxglade/widgets Template directory: /opt/wxglade/lib/python2.7/site-packages/wxglade/templates Credits file: /opt/wxglade/share/doc/wxglade/credits.txt License file: /opt/wxglade/share/doc/wxglade/license.txt Tutorial file: /opt/wxglade/lib/python2.7/site-packages/wxglade/docs/html/index.html Using wxPython 2.8.12.1 loaded code generator for perl loaded code generator for XRC loaded code generator for python loaded code generator for lisp loaded code generator for C++ Found widgets listing -> /opt/wxglade/lib/python2.7/site-packages/wxglade/widgets/widgets.txt loading widget modules: frame dialog [...]
Exploring wxGlade
Quick start We will design a simple form. Start wxGlade by running the wxglade program on Unix platforms or the wxglade.pyw program on Microsoft Windows. You will see a Main Palette with several buttons, and a Tree Window with an icon marked Application. A Properties Window shows the properties of the Application. If you move the mouse over a button in the main window, a tooltip will display its function. To add a frame in the design window, from the Main Palette choose the first button: Add a frame. Then choose wxFrame as the base class. Look at the tree window and see that two icons are generated under the application icon, a frame icon and a sizer icon. If you double click with the mouse on the frame icon, the designer window appears. Notice that the sizer is displayed as a set of gray boxes: they are the slots of the grid sizer where you will place the widgets. You put a widget on a sizer by selecting it on the Main Window, then click on an empty slot on the frame on the designer window. Try adding a static text, a text control and a button. If you want to add something else, add empty slots on the sizer by right-clicking on the sizer on the tree window and selecting Add slot. Play around, adding four or five widgets on the frame. Now look at the properties form; there are three tabs. In the Common tab you can specify the name, size and color of the widget. In the Layout tab you can adjust borders and alignments. In the Widget tab you find the properties depending on the widget. You can select the properties of a widget by clicking on the designer window or the corresponding icon on the tree window. Try adjusting widgets with the properties form until you know you have played enough. Now let's generate the code. Select the Application icon on the tree window and go to the properties window. Check Name and Class, choose a Top window, check Single file and choose the language and set the Output path by pushing the button for selecting a path and a filename. Finally press the Generate code button, and the code is generated. Compile and enjoy.
Basics of wxGlade The program wxGlade is a tool for designing Graphical User Interfaces (GUI). It is intended to be used with the wxWidgets framework in all its flavors: C++, Lisp, Perl, Python and XRC. You use a visual editor for creating forms, menus and toolbars with the mouse. Your design is saved in a .wxg file, which is the wxGlade file format. Then you generate source code or XRC by using visual tools or invoking wxGlade at the command line. You can also use wxGlade in your makefile by generating source code only when the .wxg file changes. A .wxg file can contain multiple forms, panels, menus and toolbars and generate either a single file containing all classes or multiple files containing one class each. wxGlade does not manage events, file inclusion, function names, stubs or anything else but graphic interface code.
Best Practice The main goal of the recommendations is to improve the usability and maintainability of code generated by wxGlade. The recommendations combine the experience of many wxGlade users. Always overwrite existing sources wxGlade is able to adapt existing source files after the design has changed. This feature have some limitations e.g. in case of name changes and changed dependencies. Thereby it’s recommended to overwrite existing sources always and extend derived classes with your functionality. Use new namespace for Python projects It’s generally recommended to use the new namespace (import wx) for wxPython projects. The old one (from wxPython.wx import *) has some significant drawbacks like potential namespace conflicts. Use the C++ naming convention Use the C++ names for all wx identifies like classes, colours or events of the wx framework. Please don’t enter identifiers already formatted in a language specific form. wxGlade is able to transform the entered original identifiers in language-specific terms. You can use your own style for your object certainly. Correct entered wx constant Enter wxID_CANCEL even for wxPython instead of wx.ID_CANCEL Always use UTF-8 encoding It's generally recommended to use Unicode encoding for all non-ASCII character sets. Always use gettext support Enable internationalisation support. There are no disadvantages if internationalization is active but not used. It's hard to add i18n and Unicode afterwards from project point of view. Suggestion on naming The wxWidgets are written in C++ and follow the C++ naming convention. This naming convention may differ from the language specific and / or project specific naming convention. For consistency's sake, it's recommended to use the wxWidgets style. Prevent language specific statements Usage of language specific codes e.g. for Extra code for this widget or in generic input fields complicated changing the output langauge later e.g. to re-use GUI elements in another project too.
Language specific peculiarities
Python It's not recommended to use nested classed and functions in combination with disabled feature Overwrite existing sources. Use derived classes to implement your functionality. See also.
Lisp The Lisp code generated by wxGlade may or may not working with a current Lisp dialect. Help to improve the Lisp support is really welcome.
Command line invocation You can run wxGlade without parameters to start the GUI on an empty application as follows: wxglade Run wxGlade GUI on an existing application specifying the .wxg file as follow: wxglade <WXG File> If you only want to generate the code without starting the GUI, use the or option with the language as argument as follows: wxglade -g <LANGUAGE> <WXG File> wxglade --generate-code=<LANGUAGE> <WXG File> Possible values for LANGUAGE are "XRC", "python", "perl", "lisp" or "C++". You can also specify the destination of the generated code with or option: wxglade -g <LANGUAGE> -o <DESTINATION> <WXG File> The DESTINATION argument can be a file or a directory. If DESTINATION is a file, wxGlade will generate single-file source code. In case DESTINATION is a directory wxGlade will generate multiple-file source code. This is the complete description of the command line: # wxglade --help Usage: wxglade <WXG File> start the wxGlade GUI or: wxglade <Options> <WXG File> generate code from command line or: wxglade --version show programs version number and exit or: wxglade -h|--help show this help message and exit Options: --version show program's version number and exit -h, --help show this help message and exit -g LANG, --generate-code=LANG (required) output language, valid languages are: C++, XRC, lisp, perl, python -o PATH, --output=PATH (optional) output file in single-file mode or output directory in multi-file mode Example: Generate Python code out of myapp.wxg wxglade -o temp -g python myapp.wxg Report bugs to: <wxglade-general@lists.sourceforge.net> or at <http://sourceforge.net/projects/wxglade/> wxGlade home page: <http://wxglade.sourceforge.net/> Use wxglade.pyw instead of wxglade on Microsoft Windows.
Using the source code There are a lot of options to control the source code generation process. They are bundled in the Application page of the Properties window (see ). Let's talk about three of those options -Single file, Separate file for each class and Overwrite existing sources. The first two options triggers wxGlade to generate one file with all classes inside or multiple files - one per class/widget. The Single fileoption includes source and header file for C++ certainly. The third option Overwrite existing sources is just about control - Full control by wxGlade and Shared control. It separated the two ways to work with wxGlade.
Full control by wxGlade If Overwrite existing sources is set, wxGlade will re-generated all source files and drop potential manual changes. You've to include the generated source files and use derived classes for implementing changes. The files written by wxGlade are consistent always. Also if e.g. classes or attributes are renamed. Rewriting the whole files is less error-prone in comparison with . That is the advantages of this method. This method is the recommended one.
Shared control Manual changes in the source files won't be overwritten if Overwrite existing sources isn't set. You can safely edit the source code of the generated class. This is because wxGlade marks the untouchable code with the special comments begin wxGlade and end wxGlade. So you can edit all you need outside these two tags. When you make changes in your forms, a new code generation will not modify the user code. wxGlade is applying most of the changes but not all changes. Especially renamed classes and attributes need additional attention. Overwriting multiple files is not recommended as well as overwriting of files with percent character (%) inside is not supported.
Output path and filenames Output path specifies the name of the output file for Single file projects or the output directory for multi-file projects (Separate file for each class). The filename has to include the appropriate suffix of the programming language always. An exception is the Output path for Single file C++ projects. Filename don't contains the filename extension now. The extension for C++ source and header files will be appended later automatically.
Automatically created <classname>wxApp</classname> instance wxGlade is able to extent the created source for by a code sequence to create and start an instance of projects Top window. In case Name and Class are set, a detailed start code with a derived class of wxApp will be created. If just Name is given, a simplified start code will be generated. There is a short explanation of Class and Namein . The application start code of a multi-file project will be recreated every time the code generation is running. In opposition the application start code of single-file projects will not updated if the name of the Top window has changed and Overwrite existing sources is not set. Detailed application start code in Perl package MyApp; use base qw(Wx::App); use strict; sub OnInit { my( $self ) = shift; Wx::InitAllImageHandlers(); my $frame_1 = MyFrame->new(); $self->SetTopWindow($frame_1); $frame_1->Show(1); return 1; } # end of class MyApp package main; unless(caller){ my $local = Wx::Locale->new("English", "en", "en"); # replace with ?? $local->AddCatalog("app"); # replace with the appropriate catalog name my $app = MyApp->new(); $app->MainLoop(); } Simplified application start code in Perl package main; unless(caller){ my $local = Wx::Locale->new("English", "en", "en"); # replace with ?? $local->AddCatalog("PlOgg1_app"); # replace with the appropriate catalog name local *Wx::App::OnInit = sub{1}; my $PlOgg1_app = Wx::App->new(); Wx::InitAllImageHandlers(); my $Mp3_To_Ogg = PlOgg1_MyDialog->new(); $PlOgg1_app->SetTopWindow($Mp3_To_Ogg); $Mp3_To_Ogg->Show(1); $PlOgg1_app->MainLoop(); }
Compiling C++ code You can compile your wxGlade project after the generation of the C++ source and header files. The following examples demonstrate compiling on Linux command line using g++. Compiling a single file C++ project on Linux # g++ FontColour.cpp $(wx-config --libs) $(wx-config --cxxflags) -o FontColour # ll FontColour* -rwxr-xr-x 1 carsten carsten 72493 Jun 15 09:22 FontColour -rwxr-xr-x 1 carsten carsten 1785 Mai 11 19:24 FontColour.cpp -rwxr-xr-x 1 carsten carsten 1089 Jun 11 07:09 FontColour.h Compiling a multi file C++ project on Linux # g++ CPPOgg2_main.cpp $(wx-config --libs) $(wx-config --cxxflags) \ -o CPPOgg2_main CPPOgg2_MyDialog.cpp CPPOgg2_MyFrame.cpp # ll CPPOgg2* -rwxr-xr-x 1 carsten carsten 108354 Jun 15 09:33 CPPOgg2_main -rwxr-xr-x 1 carsten carsten 844 Mai 11 19:25 CPPOgg2_main.cpp -rw-r--r-- 1 carsten carsten 5287 Mai 18 19:06 CPPOgg2_MyDialog.cpp -rw-r--r-- 1 carsten carsten 1829 Jun 11 07:11 CPPOgg2_MyDialog.h -rw-r--r-- 1 carsten carsten 1785 Mai 11 19:25 CPPOgg2_MyFrame.cpp -rw-r--r-- 1 carsten carsten 1290 Jun 11 07:10 CPPOgg2_MyFrame.h
Handling XRC files wxGlade is able to save projects as XRC files and to convert XRC files into wxGlade projects. One way for converting XRC files is the usage of the Python script xrc2wxg.py at command line. The script is part of wxGlade. Converting a XRC file into a wxGlade project # ./xrc2wxg.py FontColour.xrc # ls -l FontColour.* -rw-r--r-- 1 carsten carsten 5554 Dez 4 20:36 FontColour.wxg -rw-r--r-- 1 carsten carsten 4992 Dez 4 20:13 FontColour.xrc The File menu provides a menu item Import from XRC... to import and open a XRC file directly. The following example shows how to load and show the frame Main from XRC file test.xrc. wxPython code to load and show a XRC resource #!/usr/bin/env python import wx from wx import xrc GUI_FILENAME = "test.xrc" GUI_MAINFRAME_NAME = "Main" class MyApp(wx.App): def OnInit(self): self.res = xrc.XmlResource(GUI_FILENAME) self.frame = self.res.LoadFrame(None, GUI_MAINFRAME_NAME) self.frame.Show() return True if __name__ == '__main__': app = MyApp() app.MainLoop()
Specifying the path of bitmaps In wxGlade some widgets need to specify a bitmap path. You can use any graphic format supported by wxWidgets. The bitmap can be specified in several ways: Usually you can type an absolute path in a text box or browse for a bitmap with a file dialog. This will produce a wxBitmap object with the typed string as bitmap path (e.g. wxBitmap("/usr/share/icons/application.png", wxBITMAP_TYPE_ANY)) You can enter a variable name using the var: tag in the text box. This will produce a wxBitmap object with the variable name as bitmap path (e.g. var:my_bitmap_path produces wxBitmap(my_bitmap_path, wxBITMAP_TYPE_ANY)). In Perl code generation a $ sign is added if you omit it. You can enter a code chunk returning a wxBitmap, by using the code: tag. This inserts verbatim the code you enter in brackets and nothing more (e.g.: if wxSomeWidget needs a wxBitmap as an argument, the string code:if (x == 0) get_bitmap1() else get_bitmap2(); produces wxSomeWidget((if (x == 0) get_bitmap1() else get_bitmap2();), option1, option2)). wxGlade never declares or assigns variable or function names, so after code generation, you have to provide extra code to declare your variables or functions. If you use var: or code: tags the preview window shows an empty bitmap of fixed size.
wxGlade User Interface
Main Palette The main window is a palette that hosts the menu and the widget choice buttons.
The Main Palette
If you pass the mouse pointer over a button a tooltip shows the button's description. The Add a Frame button and the Add a Dialog/Panel button bring up a dialog to add a frame, a dialog or a panel to your project. The Add a MenuBar button asks you for the name of the class then adds a menu bar to your project. The Add a ToolBar button asks you for the name of the class then adds a toolbar to your project. The other buttons in the main window add widgets to a form. When you click on one, the mouse pointer changes to an arrow. Then you can click on a sizer's empty cell to add the widget to it.
Tree Window The tree window shows the logical hierarchy of widgets and its child-widgets. For example you can see a panel as a tree's node and the widgets on it as child nodes.
The Tree Window
You can show or hide the tree window by the menu item View/Show Tree. Usually a frame or a panel contains a sizer, so you often see a sort of panel-sizer-widgets structure. The tree gets more complex when you nest sizers within sizers. You can navigate the visual presentation of your widget tree by mouse, expand and collapse sizers, and copy, cut or remove widgets. A click on an icon in the tree window displays the properties of the corresponding element in the properties window. A double click in a frame, dialog or panel icon makes the designer window show it as it appears. Clicking with the right button of the mouse gives you a pop-up menu.
The menu for a widget
The menu for a sizer
The pop-up menu for a widget allows you to copy, cut or remove the element. The pop-up menu for a sizer allows you to copy, cut or remove the element, or add or insert an empty slot.
Often when you add an empty slot, you have to make the designer window larger, to show the new slot.
Design Window The design window shows the frame or panel you are creating in WYSIWYG mode and allows you to select a widget from the main palette and to put it on an empty slot of a sizer. You can show the design window by double-clicking on the icon of a frame or dialog in the tree window.
The Design Window
By clicking with the right mouse button on a widget you can access the context menu. Notice that the sizers, which are invisible elements, have a little gray handle, that you can click to select the sizer or let the pop-up menu appear. The pop-up menu is the same as the one you get in the Tree Window, as shown in or in .
Properties Window The properties window lets you see and edit the properties that apply to the selected element. This window consists up to six different tabs. All six tabs are not always present. The visibility of the single tabs depends on the widget type. Most widgets have a Common tab and a Code tab. The combination of presented tabs depends on the widget type. For example: wxFrame widgets have Common, Widget and Code tabs Spacers have the tabs Layout and Code wxGridSizer widgets have Common and Grid wxBoxSizer widgets only have the Common tab Editing properties is quite simple; Properties are represented by buttons, text boxes, checks and other controls. Usually they are referenced by the same name or symbol that you find writing C++ code. Usually you get the changes in the design window in real time. In some cases you have to push the Apply button. For example, the wxNotebook widget shows in its properties window a list of child wxPanels. You have to press the Apply button to show changes you make when you add or remove panels. You can show or hide the properties window by the menu item View Show Properties .
Application Properties The page Application contains the general settings of the active wxGlade project.
Project Properties - Application settings
Name Name of the instance created from Class provides more information Class Name of the automatically generated class derived from wxApp provides more information Encoding Encoding of the generated source files. The encoding to use with new projects will be determinated automatically based on the machine settings. UTF-8 will be used if the automatic detection fails. Enable gettext support Enable internationalisation and localisation for the generated source files Top window This widget is used as top window in the wxApp start code provides more information Code Generation Write all source code in one file or split the source into one file per class / widget provides more information Language Programming language to generate the source files in wxWidgets compatibility Generate source files for the selected wxWidgets version Overwrite existing sources Overwrite existing source files or modify the code sequences generated by wxGlade in place provides more information Output path Output file or directory provides more information Generate code Start generating source files The page Settings contains the language specific settings of the active wxGlade project.
Project Properties - Language settings
Indentation mode Use spaces or tabs for indentation within the generated source files. Indentation amount Number of spaces or tabs used for one indentation level. Use old import "from wxPython.wx import *" It is generally recommended to use the new namespace. The old one (from wxPython.wx import *) has some significant drawbacks like potential namespace conflicts. Source ext Extension of the source file. The extension doesn't has a leading dot. Header ext Extension of the header file. The extension doesn't has a leading dot.
Common Properties The first tab contains the common properties that apply to all widgets. As shown in the common properties are related to name, class, size, colors, fonts and tooltip.
Common Properties
The property name is a mangled version of the wxWidgets property name. The property input field is disabled by default. wxGlade won't use disabled properties for code generation. wxWidgets defaults are used instead. Enable the property in the wxGlade GUI to set non-default values (see ).
Changing Common Properties
Name Name of the instance created from Class Class Name of the subclass of the widget. How this name affects code generation depends on the output language.
Common Properties of a subclassed widget (default behaviour)
Generated Python code of a subclassed widget class MyDialog(wxDialog): def __init__(self, *args, **kwds): # begin wxGlade: MyDialog.__init__ kwds["style"] = wxDEFAULT_DIALOG_STYLE wxDialog.__init__(self, *args, **kwds)
Base class(es) A comma-separated list of custom base classes. The first will be invoked with the same parameters as this class, while for the others the default constructor will be used. This property will be shown only for non-managed widgets for instance wxFrame, wxDialog, wxNotebook, wxPanel and wxSplitterWindow. You should probably not use this if overwrite existing sources is not set.
Common Properties with Base class(es) entry
Generated Python code of a widget with two base classes class MyFrame(myFrameMixin, wxFrame): def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE myFrameMixin.__init__(self, *args, **kwds) wxFrame.__init__(self)
Id This property could be a constant numeric value a predefined identifier e.g. wxID_ANY a predefined variable like a class member e.g. self.myButtonID a variable assignment e.g. self.myButtonID=? The pattern of a variable assignment is always variable=value. The value could be again a numeric value, a predefined identifier, another predefined variable or ? a shortcut for wxNewId()
Common Properties with a variable assignment
Generated Python code for a variable assignment class MyFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.myButtonID = wx.NewId() self.button_1 = wx.Button(self, self.myButtonID, "button_1") self.__set_properties() self.__do_layout() # end wxGlade
Size Set the widget size in pixels. Background Set the background colour of the widget. Foreground Set the foreground colour of the widget. Font Set the font for widgets text elements. Tooltip Set a tooltip for this widget. Disabled Disable the widget. Focused Sets the widget to receive keyboard input. Hidden Hide the widget.
Layout Properties The second tab is related to layout properties that control position and resizing within the sizer.
Layout Properties
These properties apply to any widget. You can check or uncheck any option related to the placement in the sizer. Many widgets may have a default value of 3 in the Border property in the Preferences Dialog (see ). If you let a widget have a default border, the wxAll option is also checked.
Widget Properties The third tab, named Widget is different for each widget, and lets you edit properties for the specific element you have selected.
Widget Properties
The set of options may also be quite complex in the case of widgets that have a great deal of methods and properties (such as grids and tree views). In this case, wxGlade greatly simplifies the process of designing forms.
Events Properties The fourth tab, named Events lists the widgets events. wxGlade generates an event handler stub and binds the event for each added handler name.
Events Properties
Events Properties with entered event handler name
Generated Python code of an <command>EVT_TEXT</command> event handler stub at line 12 class MyFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.text_ctrl_1 = wx.TextCtrl(self, -1, "") self.__set_properties() self.__do_layout() self.Bind(wx.EVT_TEXT, self.myEVTTEXT, self.text_ctrl_1) # end wxGlade def myEVTTEXT(self, event): # wxGlade: MyFrame.<event_handler> print "Event handler `myEVTTEXT' not implemented!" event.Skip()
Code Properties The fifth and last tab is named Code and has two parts.
Properties for extra code and extra properties
The upper part provides the ability to add additional code for that widget e.g. for importing a custom class. This Extra code will be added to the context of the source file and not to the context of the class. The under part simplifies setting of additional widget properties. Add the property name to the Property field and not the name of the setter function. For instance add MaxLength and not SetMaxLength. The Value field is just a text field. You can enter e.g. a simple number only as well as a complex statement e.g. 0, 0, "1" or a function call. But be carefully! Your entered sequence will be inserted in the source without any changes - one to one. Extra code and Extra properties won't be processed for the widget preview.
Set extra property
Generated Python code for setting property <command>MaxLength</command> to <command>10</command> at line 14 class MyFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.text_ctrl_1 = wx.TextCtrl(self, -1, "") self.__set_properties() self.__do_layout() # end wxGlade def __set_properties(self): # begin wxGlade: MyFrame.__set_properties self.SetTitle("frame_1") self.text_ctrl_1.SetMaxLength(10) # end wxGlade
Preferences Dialog You can access the Preferences Dialog with the menu item View Preferences . You can choose some decoration options, like whether to show icons in menus or not, but also something more effective. For example, you can modify the number of buttons in the Main Palette. If you type a value of 15 or 30, you get a long toolbar-like Main Palette. You can also choose the default path where you save wxGlade files or generate source code. Another useful option is to enable a default border of 3 around some widgets. In many cases this can be useful to have set. You need to restart wxGlade for changes to take effect.
Shortcuts Ctrl-G Generate code from the current GUI design Ctrl-I Import GUI design out of a XRC file Ctrl-N Start a new GUI design Ctrl-O Read a GUI design from a .wxg file Ctrl-S Save the current GUI design to a .wxg file Shift-Ctrl-S Save the current GUI design to another .wxg file Ctrl-P Open a preview window for the current top-level widget Ctrl-Q Exit wxGlade Ctrl-C Copy the selected item, element, text, ... Ctrl-V Insert clipboard content Ctrl-X Cut the selected item, element, text, ... F1 Show the wxGlade user manual (this documentation) F2 Show the Tree window F3 Show the Properties window F4 Show all application windows F5 Refresh the screen
Supported widgets
Introduction wxGlade supports a number of widgets and helps you to edit the properties and visual look of each one.
Widget list Follow the widget list as it appears in the wxGlade main window.
Frame This prompts for a wxFrame or a wxMDIChildFrame. A vertical wxBoxSizer is appended. In the properties window you can choose the styles and you can add an icon.
Dialog or Panel This prompts for a wxDialog or a wxPanel in top level. In the properties window you can choose the styles and, for the dialog, you can add an icon.
Panel This allows you to add a panel to a sizer. In the properties window you can choose the styles.
Splitter window This produces a wxSplitterWindow and two associated panels as well. You can choose vertical or horizontal splitting. In the properties window you can choose the styles and the sash position. Be careful not to put too large a widget in a splitter panel, because while it might appear normal in the design window, when you run your program one of two panels will take all the available space and the other will shrink to the minimum size possible.
Notebook This produces a wxNotebook and one panel for each tab. In the properties window you can add and remove tabs, which appear in a list. Don't forget to click on the Apply button to transfer changes that you have made in the list to the design window.
Button This produces a wxButton. You can enter a caption and the default flag. If you want to add an image you need a bitmap button (see ).
Toggle button This produces a wxToggleButton. You can enter a caption and the status (clicked or not) of the button.
Bitmap button This produces a wxBitmapButton. You can set the default flag on or off. You also can choose the bitmap for the button and, optionally, the bitmap for the disabled status. Refer to for bitmap path specifications.
Text control This produces a wxTextCtrl. In the properties window you can enter the text and also set the style.
Spin control This produces a wxSpinCtrl. In the properties window you can enter the value, the range and also set the style.
Slider This produces a wxSlider. In the properties window you can enter the value, the range and also set the style.
Gauge This produces a wxGauge. In the properties window you can enter the range and set the style.
Static text This produces a wxStaticText. In the properties window you can enter the text, set the style and tell wxGlade whether to store the control as an attribute.
Check box This produces a wxCheckBox. In the properties window you can enter the text, and the status, checked or not, of the button.
Radio button This produces a wxRadioButton. In the properties window you can enter the text, and the status, clicked or not, and the style.
Radio box This produces a wxRadioBox. In the properties window you can enter the dimension. The style determines whether the dimension is the number of rows or columns. You also can set which button is selected with the Selection spin starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.
Choice This produces a wxChoice. In the properties window you can enter the position of the selected item starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.
Combo Box This produces a wxComboBox. In the properties window you can enter the position of the selected item starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.
List Box This produces a wxListBox. In the properties window you can enter the position of the selected item starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.
StaticLine This produces a vertical or horizontal wxStaticLine. In the properties window you can tell wxGlade whether to store the object as an attribute of the frame class.
Static bitmap This produces a wxStaticBitmap. You will be prompted for the bitmap path. Refer to for bitmap path specifications. In the properties window you can set the style and you can tell wxGlade whether to store the object as an attribute of the frame class.
List Control This produces a wxListCtrl. In the properties window you can set the style.
Tree Control This produces a wxTreeCtrl. In the properties window you can set the style.
Grid This produces a wxGrid. In the properties window you can set the style, the row number, the label size, the line and background color and the selection mode. You can edit the list of columns, but remember to click on the Apply button to consolidate changes. Also you can choose to let wxGlade to create the grid or leave it to the user code.
Custom Widget When you put a custom widget in the design window you will be prompted for a class name. In the properties window you can set a number of custom attributes that will appear in the constructor call. These attributes have different effects in C++, Lisp, Perl, Python or XRC code generation. Four special attributes $id, $parent, $width and $height return the value you specify in the Common tab of the custom widget.
Spacer When you put a spacer into a sizer slot in the design window you will be prompted for the size; wxGlade will generate the code to set an empty space in that slot of the sizer.
Menu, Toolbar and Statusbar wxGlade License Agreement Copyright (c) 2002-2007 Alberto Griggio agriggio@users.sourceforge.net Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Licenses and Acknowledgements for Incorporated Software This section lists licenses and acknowledgements for third-party software incorporated in wxGlade.
OrderedDict The OrderedDict class version 1.1 has been integrated. The class is downloaded from http://pypi.python.org/pypi/ordereddict and contains following notice: Copyright (c) 2009 Raymond Hettinger Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
wxglade-0.6.8.orig/docs/tutorial.html0000644000175000017500000006117111621715605020010 0ustar georgeskgeorgesk wxGlade tutorial

wxGlade Tutorial

The aim of this minimal tutorial is to give an overview of wxGlade and its functionalities: despite its very short length, it is (hopefully) complete enough to make you understand how the application works, through a step-by-step description of the creation of a frame containing a notebook with some controls, a menubar and a statusbar.

Before we start, let me apologize for my English: it's not my native language (I'm Italian), so it is very far from perfection.

1. Creation of the frame

To create a new frame, click on the appropriate button of the "palette" (): a dialog asking for the name of the class of the new window is displayed: choose the name you prefer, but remember that it must be a valid name for a Python (or C++) class.

Now the frame is displayed, and the properties window changes to show the attributes of the widget just created. The first thing we'll do is change the title of the frame, which is by default equal to the object's name, and insert "Frame with notebook": the change takes effect when the Title property loses focus.

2. Creation of the menubar

Let's activate the Widget tab of the properties notebook of our frame, and check the property Has MenuBar to create a menu bar for the frame.

The properties window changes again, and now it shows the properties of the menubar: let's click on the Edit menus button to add some menus with the Menu Editor.

Click on the button Add to add a menu, and then edit the Label field to change its value to "File".
Let's then add some menu items to our File menu: click on the Add button again, change Label to "New", and finally click the > button: after the latter action we can see that the label of our item ("New") is indented compared to the previous one ("File"): this says that "New" is an item of "File".
Repeat the previous operations "ad libitum" to add other menus and items (and sub-menus), then click OK: the window gets closed, and our menubar contains the menus we added.

3. Creation of the statusbar

Under the Has MenuBar property of our frame there's the Has StatusBar one: check it to add the statusbar.

The Fields property of the object just added keeps the fields to display on the statubar: double-click on a field to edit it; to add, remove, insert other fields use the appropriate buttons.
Edit the default field, an set its value to "Created with wxGlade!", then add some other fields with the Add button: the Size column shows the dimension of each field: you can change them as you like, but remember that one of the fields must have a size of  -1 (which tells that it will fill the remaining space).
After performing these operations, click on the Apply button to reflect the changes on the widget.

4. Creation of the notebook

Now it's time to add a notebook to our frame. You should have noticed that the frame you've just added contain a BoxSizer (). This is because with wxGlade every container widget must have a Sizer before you can add sub-widgets to it, and since it is very common for frames to have just one child window, wxGlade adds an 1-slot BoxSizer automatically for you. This doesn't happen for other containers, for which you'll have to set their sizer manually, as will be explained below, after the addition of the notebook to the frame.

Let's add such notebook, then: to do so, click on the Notebook button () on the palette: now when you move the mouse inside the sizer's area (), the pointer changes its shape and becomes a cross: this tells us that we can drop the notebook on the sizer's only slot.
A left-click starts the operation, and a dialog asking for the placement of the notebook's tabs appears: choose what you like best.

Now let's select the Common tab of the properties of the object just added: we can see that the Class property's value is wxNotebook, i.e. the name of the class our object is an instance of. If we change such value, we can make our notebook an instance of a custom class derived from wxNotebook: this has no effect during the creation of the app, but it changes the generated code, so that a definition for our custom class will be written. Let's change then the value of Class to MyNotebook, to make wxGlade generate the code for the custom class.

NOTE: The above is true only for "container" widgets, i.e. those that can have children. For controls, instead, the meaning is slightly different; let me illustrate it with an example.

Suppose you have a button inside a panel, its Class is wxButton. If you change such value to MyCustomButton, wxGlade assumes that you have a subclass of wxButton called MyCustomButton defined somewhere, and that such class has a costructor compatible with that of the "regular" wxButton, and so when it generates the code for the object, it writes:
button_1 = MyCustomButton(parent, id, "Label")
instead of
button_1 = wxButton(parent, id, "Label")

NOTE 2: For XRC output, if the value of Class is different from the default one, the object will have a subclass attribute. For the example above, the code generated would be:

<object class="wxButton" name="button_1" subclass="MyCustomButton"/>

This means that you should be a little careful with XRC output, in that you have to remember to reset the Class value to the default one when adding a "top-level" widget (frame, dialog,...), because by default wxGlade assumes they are custom classes.

5. Adding and removing notebook pages

This operation is almost identical to the handling of statusbar fields: the Tabs property of our notebook controls the number of pages (tabs) and their labels (don't forget to "Apply" the changes!).

6. Addition of some controls

We have now reached the last part of this short tutorial: the addition of some controls to the first page of our notebook. In particular, we'll add a text area and two buttons: these operations will allow us to show the layout options of the objects inside sizers, and the cut & paste support of wxGlade.

As said before, the first thing to do in order to add widgets to a container is to set its sizer. Let's start with the addition of a sizer to the first page of the notebook, which is where we are going to put our controls, then: to do so, click on the BoxSizer button () on the palette, and then move the mouse inside the page. Again, the pointer is now a cross, and so we can drop the sizer on our page: if everything is OK, you should see a dialog asking for some features of the sizer to add. We have to change the default values, since we want a 2-slots vertical box, so set to Vertical the orientation and to 2 the number of slots. None of the two actions is mandatory, since both the orientation (or better, the type) of the sizer and the number of slots can be changed in any moment: the former by changing the value of the Class property, the latter from the popup menu you can activate with a right-click on the "handle" button of the sizer or on the corresponding node of the tree of widgets. (As a side note, this same procedure can be used to show the menu of almost every object handled by wxGlade).

6.1 Text area

Let's click on the TextCtrl button () and insert the text area in the first slot of our sizer.

The default dimension isn't right, as we want to display a long and multiline text: to edit the layout, let's select the Layout tab of the TextCtrl's properties, and set to 1 the value of Option and to wxEXPAND that of Alignment. To make the text area multiline, let's check the wxTE_MULTILINE checkbox of the Style property (in the Widget tab): as with almost every Style property in wxGlade, such change has no visible effect, but it changes the generated code.

6.2 Buttons

Now replace the second slot with a horizontal Sizer which will contain our two buttons: set the number of slots to 3, to leave room for a spacer to insert between the two buttons (so as they won't appear too close to each other).

Replace then the first slot with a new button, as usually with the approprate button ().
To add the second button, instead, we will use the clipboard: let's click on the Copy item of the popup menu of the first button (or select it and press Ctrl+C), then move the mouse inside the third slot, and finally click on the Paste item of the popup menu of the slot to paste the copied widget (again, you can alternatively left-click on the empty slot and then press Ctrl+V, or if you have a 3-buttons mouse just click on the empty slot with the middle button).

Now add a spacer () of the appropriate dimension between the buttons, to keep them at a reasonable distance.

Finally, the last operation we have to do is to edit the layout of the horizontal Sizer that contains the buttons: set to 0 the value of "Option", uncheck wxEXPAND from Aligment and check wxALIGN_CENTER_HORIZONTAL, and set a border (4) on the top (wxTOP) and bottom (wxBOTTOM), to keep the buttons separate from the text area and the notebook lower border.

NOTE on widgets' ids: You certainly know that every wxWindows widget has an id, used among other things for event handling, so in wxGlade each widget has an Id property. This may have the following values:

  • a number: this will be the integer which will be passed to the constructor of the widget
  • a name: in this case wxGlade assumes it is the name of an id declared somewhere in the program, and uses it. For example, you can set the value of Id to wxID_OK for the default OK button of a dialog
  • a pair name=value: in this case before the constructor of the widget the declaration of the variable is generated. For example you could write TEST_BUTTON=wxNewId() to generate the id of a button called "Test" (note for C++ code generation: since ids are stored in an anonymous enum, only constant initializers are allowed, so the assigment above is not legal - but you can use, for instance, TEST_BUTTON=100)
  • a pair name=?: this special form means that the code will contain the definition of a varable "name" with an auto-assigned unique id. For python output, this is the same as "name=wxNewId()", while for C++ output, it's the equivalent of "name=1000" (of course, 1000 is just an example here). In this latter case, wxGlade will start generating ids exacly from 1000, so you can safely use ids below that for your own purposes.

7. Last changes

Finally, suppose you are not happy with the current layout, and you decide it's better to put the buttons above the text area and not below as they are: so what can we do? Simple: let's change the value of the Pos property of the sizer which contains the buttons, and set its value to 0, to move the sizer before the text area: easy, isn't it?

Now our window is complete: all we have to do is set a reasonable initial size for it. To do this, resize the frame until you find a good size, and then activate the Size property.

8. Code generation

Before we proceed with the code generation, let's save our work, selecting the Save As... item of the File menu of the main wxGlade window: this operation is not strictly necessary, but it's a good practice to not risk to loose the work, in particular until wxGlade will reach a certain maturity :-)

Now we can go on with the code generation: select the Application item on the tree of widgets (it is the root) to make the Application tab appear on the properties window. This panel contains the options for the code generation:

  • Name: name to give to the wxApp object which represents the application: if this property and the next one (Class) are not active, there will be no code for the application startup, but only that of the various widgets
  • Class: name of the class derived from wxApp which represents the application: if this property is not active but the previous one (Name) is, the application object will be an instance of wxPySimpleApp (this applies to Python output only - for C++ output this property must be active if you want the startup code to be generated)
  • Encoding: encoding used to store the saved .wxg file (also for XRC);
  • Enable gettext support: if checked, all the strings in the generated sources will be wrapped by a "_()", ready for gettext;
  • Top window: main window of the application to generate
  • Code generation: this controls the kind of output, and lets you choose between a single source file containing all the widgets, or a separate file for each custom class defined (for C++ output, the single-file mode actually generates two files, a ".h" and a ".cpp")
  • Language: this lets you choose the language of the generated code: at the moment, Python, C++ and XRC, i.e. wxWindows resources xml format. Note that in this last case some of the properties of the application are ignored (Name, Class, Top window), and some are disallowed (you cannot set Code generation to multi-files)
  • Overwrite existing sources: if checked, the code will be completely re-generated instead of updated (see the first note below for details);
  • Output path: in single-file mode, name of the output file; in multi-file mode, path to the output directory: in this last case, every custom class will be placed in a file with the name of such class, except for the (eventual) wxApp class, which is placed in a file whose name is given by the Name property described above. For example, for our notebook, we'll have MyFrame.py, MyNotebook.py and app.py (assuming you're generating Python code, of course).
  • Generate code: button which starts the code generation

After the selection of the various options as described above, click on the Generate code button: if everything is OK, after a while a message box appears: this says that the operation is over... like this short tutorial ;-)

9. Notes

This section contains a list of things that you should know about wxGlade (known bugs and/or limitations, "hidden" features, tips and tricks, ...) which I wasn't able to fit in the tutorial . The list is loosely sorted by importance.

  • When you generate Python or C++ code, if the output file already exists, wxGlade by default doesn't overwrite all its contents, but only the lines inside a
      # begin wxGlade: ...
      # end wxGlade
      
    block. This is a desirable feature in most occasions, since it lets you add your code to the file without worrying of losing it when re-generating the GUI code, but there are situations in which a little attention is required. In particular, you should be aware of the following:
    • If the output file contains a class whose name is the same as that of one of your custom classes, but its body has no wxGlade block, the code for that class is not generated (a warning appears on the shell);
    • If you rename one of your custom classes, you should rename also its code in the output file (and also all the occurrences of such name in the wxGlade tags), because wxGlade has no way of determining the previous name of such class, and will treat it like a brand new one (this means that it will generate a new class declaration instead of updating the old one). Let me explain this with an example:
      Suppose you have a class called MyFrame, and the corresponding generated file frame.py:
      #!/usr/bin/env python
      # generated by wxGlade 0.2 on Sat Dec 14 15:15:06 2002
      
      from wxPython.wx import *
      
      class MyFrame(wxFrame):
          def __init__(self, *args, **kwds):
              # begin wxGlade: MyFrame.__init__
              kwds["style"] = wxDEFAULT_FRAME_STYLE
              wxFrame.__init__(self, *args, **kwds)
      
              self.__set_properties()
              self.__do_layout()
              # end wxGlade
      
          def __set_properties(self):
              # begin wxGlade: MyFrame.__set_properties
              self.SetTitle("frame_1")
              # end wxGlade
      
          def __do_layout(self):
              # begin wxGlade: MyFrame.__do_layout
              pass
              # end wxGlade
      
      # end of class MyFrame
      
      Now suppose you rename MyFrame to RenamedFrame. If you don't care to fix frame.py accordingly, if you re-generate it you will get something like:
      #!/usr/bin/env python
      # generated by wxGlade 0.2 on Sat Dec 14 15:15:06 2002
      
      from wxPython.wx import *
      
      class RenamedFrame(wxFrame):
          def __init__(self, *args, **kwds):
              # begin wxGlade: RenamedFrame.__init__
              kwds["style"] = wxDEFAULT_FRAME_STYLE
              wxFrame.__init__(self, *args, **kwds)
      
              self.__set_properties()
              self.__do_layout()
              # end wxGlade
      
          def __set_properties(self):
              # begin wxGlade: RenamedFrame.__set_properties
              self.SetTitle("frame_1")
              # end wxGlade
      
          def __do_layout(self):
              # begin wxGlade: RenamedFrame.__do_layout
              pass
              # end wxGlade
      
      # end of class RenamedFrame
      
      
      class MyFrame(wxFrame):
          def __init__(self, *args, **kwds):
              # content of this block not found: did you rename this class?
              pass
      
          def __set_properties(self):
              # content of this block not found: did you rename this class?
              pass
      
          def __do_layout(self):
              # content of this block not found: did you rename this class?
              pass
      
      # end of class MyFrame
      
      which is clearly not what you intended.
       
    • If you remove a custom class from the wxg file, wxGlade won't automatically remove it from the source when it is re-generated (this does not apply if there is no old version of such source), but it will try to update the parts inside wxGlade blocks nonetheless: this means that:
      • If you want to remove the class, you have to do it manually,
      • If you want to keep the class as is, you have to remove the wxGlade tags.

    As of version 0.3, it is possible to turn off this "update contents" feature, by checking the "Overwrite existing sources" property of the Application: if the property value is True, wxGlade will always re-generate the code from scratch (performing the appropriate backups, according to the preferences you can set from View->Preferences->Other).

  • When you add new custom classes to an app, if there is a previous version of the generated code, the definitions of the new classes will be inserted *before* the old ones: this usually is not a problem, but for C++ output there could be occasions in which the generated code won't compile "out of the box", but you'll have to perform some manual adjustments (e.g. add some forward declarations before the new classes).
     
  • When you add slots to sizers, it may be possible that you don't see such new slots: this happens because the size of the window that contains the sizer is too small, and so new slots are hidden. The solution is to resize the window, so that its layout is recalculated and the new slots are shown.
     
  • XRC code generation has some differences wrt Python or C++; apart from those already mentioned in section 8, the most important ones are:
    • Some widgets are not supported at all (e.g. status bar and grid): for them no code will be generated, but instead the XRC output file will contain a comment like this:
      <!-- code generator for wxStatusBar objects not available -->
          
    • Output files are always overwritten, so if you manually edit the XRC file, all the changes you made will be lost when you re-generate it.

     
  • Starting from version 0.2, there's a special component called CustomWidget (). This is different from the others because it can be used to include in a wxg file any widget, even if it is not directly supported by wxGlade. The key feature for this is the Arguments property, which has two different meanings: for Python or C++ output, it lets you define the constructor parameters for the object. In this case it has two special parameters, $parent and $id, which as you can guess by their names are placeholders for the actual parent and id of the object. For XRC output, instead, it lets you specify additional properties of the object. In this case each entry should be in the form
    name: value
    (invalid entries will be silently ignored): for each of these lines, the output will contain a
    <name>value</name>
    property of the XRC object.
     
  • Starting from version 0.2, there's a script called xrc2wxg.py shipped with wxGlade. You can use this script to convert an XRC file to a wxGlade resource, so that you can edit it with wxGlade itself. Its usage is straightforward:
    python xrc2wxg.py xrc_file.xrc wxg_file.wxg
    (if wxg_file.wxg is omitted, it defaults to xrc_file.wxg), but there are some limitations you should be aware of:
    • First of all, it can handle correctly only "wxGlade-friendly" XRC files. This basically means that all windows but the toplevel ones must be inside a sizer (but there are other cases).
    • All the widgets unknown to wxGlade will be replaced by the special CustomWidget component.
    • Finally, xrc2wxg is very experimental, and so it probably contains many bugs. If you find one of them, please report it (this is valid for wxGlade in general, BTW).
       
  • You can invoke code generation also from the command line, without starting the GUI. For the details, type
    python wxglade.py -h
    at your shell's prompt.

I hope the contents are clear (and my English not too ridicule ;-), anyway for questions, comments, critics you can reach me by e-mail at <agriggio at users dot sourceforge dot net>.

Alberto Griggio




wxglade-0.6.8.orig/docs/man/0000755000175000017500000000000012170277707016032 5ustar georgeskgeorgeskwxglade-0.6.8.orig/docs/man/manpage.xml0000644000175000017500000001604012150154266020155 0ustar georgeskgeorgesk .
will be generated. You may view the manual page with: nroff -man .
| less'. A typical entry in a Makefile or Makefile.am is: DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\ manpages/docbook.xsl XP=xsltproc -''-nonet manpage.1: manpage.dbk $(XP) $(DB2MAN) $< The xsltproc binary is found in the xsltproc package. The XSL files are in docbook-xsl. Please remember that if you create the nroff version in one of the debian/rules file targets (such as build), you will need to include xsltproc and docbook-xsl in your Build-Depends control field. --> Debian"> GNU"> ]> Georges Khaznadar
georgesk@ofset.org
This manual page was originally written by &dhusername; for the &debian; system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the &gnu; General Public License, Version 2 any later version published by the Free Software Foundation. On &debian; systems, the complete text of the &gnu; General Public License can be found in /usr/share/common-licenses/GPL.
Carsten Grohmann
mail@carstengrohmann.de
Current maintainer of this manpage.
2003 Georges Khaznadar 2012 Carsten Grohmann January 07, 2012
wxGlade 1 wxGlade User Commands January 07, 2012 &dhpackage; python program to build user interfaces based on the wxWidgets toolset. &dhpackage; --help -h &dhpackage; --version &dhpackage; FILENAME.wxg &dhpackage; -g LANG --generate-code LANG -o DESTINATION --output DESTINATION FILENAME.wxg DESCRIPTION &dhpackage; wxGlade is a GUI designer written in Python with the popular GUI toolkit wxPython, that helps you create wxWidgets/wxPython user interfaces. At the moment it can generate Python, Lisp, C++ and XRC (wxWidgets' XML resources) code. OPTIONS These programs follow the usual GNU command line syntax, with long options starting with two dashes (`-'). A summary of options is included below. For a complete description, see the Info files. or LANG If you only want to generate the code without starting the GUI, use the -g or --generate-code option with the language as argument Possible values for LANG are "python", "lisp", "XRC", "perl" or "C++". or DESTINATION You can specify the destination of the generated code with -o or --output option. The DESTINATION argument can be a file or a directory. It is a file when the FILENAME.wxg generates single-file source code. It is a directory when the FILENAME.wxg generates multiple-file source code. or Show the help message and exit Show programs version number and exit EXAMPLES Generate Python code out of myapp.wxg: &dhpackage; -o /tmp -g python myapp.wxg Open file myapp.wxg in wxGlade GUI: &dhpackage; myapp.wxg BUGS Report wxGlade bugs to <wxglade-general@lists.sourceforge.net> or <http://sourceforge.net/projects/wxglade/> SEE ALSO wxGlade home page <http://wxgalde.sourceforge.net>
wxglade-0.6.8.orig/docs/man/wxglade.10000644000175000017500000000772712150423547017555 0ustar georgeskgeorgesk'\" t .\" Title: wxGlade .\" Author: Georges Khaznadar .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: January 07, 2012 .\" Manual: User Commands .\" Source: wxGlade .\" Language: English .\" .TH "WXGLADE" "1" "January 07, 2012" "wxGlade" "User Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" wxglade \- python program to build user interfaces based on the wxWidgets toolset\&. .SH "SYNOPSIS" .HP \w'\fBwxglade\fR\ 'u \fBwxglade\fR [\-\-help | \-h] .HP \w'\fBwxglade\fR\ 'u \fBwxglade\fR [\-\-version] .HP \w'\fBwxglade\fR\ 'u \fBwxglade\fR [\fIFILENAME\&.wxg\fR] .HP \w'\fBwxglade\fR\ 'u \fBwxglade\fR {\-g\ \fILANG\fR | \-\-generate\-code\ \fILANG\fR} [\-o\ \fIDESTINATION\fR | \-\-output\ \fIDESTINATION\fR] \fIFILENAME\&.wxg\fR .SH "DESCRIPTION" .PP \fBwxglade\fR wxGlade is a GUI designer written in Python with the popular GUI toolkit wxPython, that helps you create wxWidgets/wxPython user interfaces\&. At the moment it can generate Python, Lisp, C++ and XRC (wxWidgets\*(Aq XML resources) code\&. .SH "OPTIONS" .PP These programs follow the usual GNU command line syntax, with long options starting with two dashes (`\-\*(Aq)\&. A summary of options is included below\&. For a complete description, see the Info files\&. .PP \fB\-g\fR or \fB\-\-generate\-code\fR \fILANG\fR .RS 4 If you only want to generate the code without starting the GUI, use the \-g or \-\-generate\-code option with the language as argument .sp Possible values for LANG are "python", "lisp", "XRC", "perl" or "C++"\&. .RE .PP \fB\-o\fR or \fB\-\-output\fR \fIDESTINATION\fR .RS 4 You can specify the destination of the generated code with \-o or \-\-output option\&. .sp The DESTINATION argument can be a file or a directory\&. It is a file when the FILENAME\&.wxg generates single\-file source code\&. It is a directory when the FILENAME\&.wxg generates multiple\-file source code\&. .RE .PP \fB\-h\fR or \fB\-\-help\fR .RS 4 Show the help message and exit .RE .PP \fB\-\-version\fR .RS 4 Show programs version number and exit .RE .SH "EXAMPLES" .PP Generate Python code out of myapp\&.wxg: .PP \fBwxglade\fR \-o /tmp \-g python myapp\&.wxg .PP Open file myapp\&.wxg in wxGlade GUI: .PP \fBwxglade\fR myapp\&.wxg .SH "BUGS" .PP Report wxGlade bugs to or .SH "SEE ALSO" .PP wxGlade home page .SH "AUTHORS" .PP \fBGeorges Khaznadar\fR <\&georgesk@ofset\&.org\&> .RS 4 This manual page was originally written by Georges Khaznadar for the Debian(TM) system (but may be used by others)\&. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation\&. On Debian(TM) systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL\&. .RE .PP \fBCarsten Grohmann\fR <\&mail@carstengrohmann\&.de\&> .RS 4 Current maintainer of this manpage\&. .RE .SH "COPYRIGHT" .br Copyright \(co 2003, 2012 Georges Khaznadar, Carsten Grohmann .br wxglade-0.6.8.orig/docs/pdf/0000755000175000017500000000000012170277707016030 5ustar georgeskgeorgeskwxglade-0.6.8.orig/docs/pdf/manual.pdf0000644000175000017500000146277312167336636020027 0ustar georgeskgeorgesk%PDF-1.5 %ÐÔÅØ 5 0 obj << /Length 197 /Filter /FlateDecode >> stream xÚ1kÃ@ …÷ûo´‡(’Îw§[ M [èm!ƒ©›R° Búós6@i–NÒ{÷1>Áغ—âÖ›”‘)G('„H1{¤\g”‡æú³ûá£]iàfê¿/ýØËn½1†Ugô‹“´‹5w1}Í÷ZÜÙI½1ä‘­d>à}r‡#c¨¿˜ºl¸.Ê A˜ÔÏY#ÞÜÞñ½ï³¹p˜@ŒBŽ2×Q_wíÐq¢Äö›$ÙLÒ 7wš§Ù!!Mú‚A¤R endstream endobj 47 0 obj << /Length 1148 /Filter /FlateDecode >> stream xÚí›[SÛ8†ïó+t™LÇFK–®v [ØvhK!îÛ Õq‚f}ªc/á߯dË&$,…]HRЕ¬DŽ¥ìŒò¬Š³jn§É–bÑŽD#A‡o³ª!>Ì'uT©¿×ªŒÓ& hÄ*³I{qVE^V±íž$²šæeª‡ Ѝ'“!³h´¯Ãtx™%¹Ô(NwÏF~¡eü6›W2ÑÊjbiAmÝa¸äv¸:É(XUqؤ*öŒU6³Ö†JïUTæó|j»_LŒ¤²I«zã~ wÈ Òº›¤ã.>Ÿ3µØ;VY½yœ§©MrZÒùNÓ2Om¤’×e› 9¸AXùœ¯ ‹4¦0Vb“Àz—6G¼éô8q|žD7…3Þ×I¥î¦`^ñÚæoã€d©df ¡¦ô@<¶‡!ízØø1• ¶Ç„mž°– ¶uì7‹"ÉËÞ•<¬pM^¸Æ}áúS­¢¿Ú§jú¥ÌWXÙùàŸÞËîâ¾”ÝÑ è|ºRå‚9¬ÛåÉîeÅq_âÞçÖŸ”2ª”‰7ÅOo¾x¶½V»‚÷±ÌfµœÙ@u^Ä‘úBµ}Ý­¥Ýq¥b“–³ÀÁÛ µå•^–A_^9¹ª.š<9›úsª°¯Ä«y¡bgNwkx;VïvvûLyšö;K‰Êâ.2UOïè )²‰ ‘ƒ»mœk*ív¥>Ïû¬©ºè<¦­¿™ë(7. “ë–ˆò‡øQÖûÑÃ:I:„YUæ¶óíj%wa‚:`›¶.ÁÞQž]ȲۗïiqáT¶kì–tÖmc|¬«¢¶©d!»cl½o4‰Gg25¹Fˆ‰ãµi‘ÔëºÊS“D2I¬ŒÊXš1íyÙp©ì‡´yeXt%ÂËÅë¢h‡Ý¨ì“÷‡M83ž“³àÅi÷qó¥>„áºÎ¨Å§#ÎB]ï¼zµ ìîæúó›¸O–Ћ®;ó›6ƒ×È~?=X¶‰¦ö©K·V˜Ýðž[¤g¦š6½ZO®}_Wÿ¦ªT3 ‰c¸9x]{ÛŸP­Wü—ÿ üy!ö5 endstream endobj 124 0 obj << /Length 1068 /Filter /FlateDecode >> stream xÚíœMs›8Çïþ:šTïHÇMë¤é¤;i㶇L+S .Æ›ì·_Å/Ýev¦)8º&Áè!?þÏ+‚%€àbr6Ÿ¼:%䘃ù=`<à’€PêmˆÀ|n§Oi´Pžœ®¢l¥Þ×ù»Wç¡?ÉIýIHÌ™>oý¡$Iªƒ&³ùäûéßB€~œ‚0¯&·_!X追0 R€ÇúÈ`˜p½Ÿ‚›É‡ ìZ,ø‹ $mÖ&ž „»†Ú¨¢Ù»ÌJUÜG±ª ll+– Ùùx1Ñ—¢‰½„ë­ {ÿ1Ÿ ,Â@PaLPe„^í}”dͺ×bÓ(Ue©M"OÏ×K½  •ò·ÑEy„ý­¯oè}äv«4”¥¥Œ å¹GØ´Pæ^ûâQ8M²Eîa6}ôü0¤Žòø(·Z&†òµI–ÙqÆTwHpiO¸ÔÀ½.òµ*ÊDm~"b}R‡tˆH1$¢û®™Ö!ëÓÿ±^§I•In#quˆ‰cö+`±¾ú«ƒhÅéu¾ZC$CìýBR¢7)bH]EçÛòáØ¹Ãçâ†QÏ$•Ö1®âÖÄ´ÅRa‡%rìžî­9fØÍþªêG••›Cv§|އé­;ÞF6Û†Øñ–„ºò¹áý$-ñw’ÈV~¬-Ô½*TÛêàM¥ùÒó¢®Þû½DyOWÊm¯æÁhq§?ø^e[}¹ ;ŽƒÄy¼Èãm‘×R=¿¼š™^uôrÒÑA ûj²-þZ~Ÿ/g_ºü8"ÜÁ‘}pogW×]pã쬜8ÿ¸ß M,¼yÈ‹2ÞV5…Ä/p"u"˜÷f¢>¢¤:ÖБãR3½Ù®×ºZ˜$¨nlþ}Jí,Ëÿž…’]_AÛQèeVùb7X¹»Ñ†{£É^E.m' û­¥4Ùè=r1àŲ>VkàmÊ}^D+û)eŽêøÜjspÛÔ¨ô›ݧV2•žâˆ{ÝÞ~¸MÈ;ÄBIœ4G-M;¹¹Y§IYÚGØ;Ï%&Àá´ã›?óRÝåù7½ãN†C H`oßj9gÛ²¬QCçQÇG´£Ëж¯<¡“å25]¬;é¡L9r@¯Maµ™”«h}Hsé(^²Õc§ªJaŸL'!Ϋ¾QU éÜìXx"¨Ë:qµï?´ !ŽãX¼+B†cš,ªòƒ#äJÊq+7D/¢í²zIº¦ìÈ#Ñ2*“¸q¶eB©ѱ9]Ú}ý âo&£ÍŸ<_žj«ý$eɈ£E’–%3qøJä‡+%ŽœWKÔ_¡õªyëÌG"×Ä+JaPæ«;#˳Z–§úîØ!Úí±ïƒ 8þŸ¯ƒøº8¬¹ endstream endobj 177 0 obj << /Length 683 /Filter /FlateDecode >> stream xÚí™]o›0†ïù¾i¸þƾLº5jÕiÚŠ´‹¨œ-Ž¥?Ç5,j§jS’r;`8'<~í÷‚戠I0Nƒ‹«Ä ƒb ¥3$V†£Ä@›P”hnž&‹¬°QÌ$ —YµÎÑ}zsq¥ Òp¥âÏWŽÅà¾Ï•¿Ü˜àSü ($ˆnoΰæåË`zOPçnÁÂh´y¹D’̸‚þÝ_òjÂF`))J$ÅFøÐ3LM'„„·åªõ‰ë'è$Iˆ£X™³l„1Ç’‹£ßcó ™#ßù6 Ð4†‰rº7®oá#¦ 6œo‰2â‰ÞµY[æ·e’k3à<Žl‡#ÝåèµùP¶Ëì1Š•ÁãW";\[/ëªmê…¤”x2¹ç˜F\†µ,µIˆÇQxˆ“¦,àÒóö7çívvwIé±^®Wm½ôÊü –Åܪ+´(þo|ìíªTÉyÌrÛ¸ºÃ ‚<¢PÙª3æ ÖR# ˆµQž2蓈ôÙVë^ŸidXX׋‡¬ñ²ªðçu×+wÜ…{!ȳ„÷Å3ç{y”¼ ~‰93û«†ÄԥѮÝ^¬ó¶¬+÷8Ô°%ï äoZS$f\7ßÀ›©÷´Ï¿/Ò¼#FšüYN´és#-:ÒÛí!6‰Ÿ(àCÛ@6Bt¶Azè#ð…€xï/õÛ2·Õªû2š7Õ¡µK[µoµ b/÷ç÷Baá¼¶:°(£üGUG”„›……ÃEï†Ì"&ú³4×U]öX7Yk{SÏÚMæ-çiÌ8“<äòoÞ¦f»B;g£5¿4…mlñ±Ì]$Ù ”㕈|Q"}ûÒk!Á°!â_Þ ýðH([ endstream endobj 216 0 obj << /Length 835 /Filter /FlateDecode >> stream xÚíšÍSœ0Àïü9Âa1 ’cmÕÇÎØº3=XqɲtXØò±«ýëû à~¸*:vDË…„ð’Iòãå}F!ÂèÄ8Ǿ@ÂŒ24ž"ÙL8ÈPúti®nNb(kD=lÎeRÊØºŸsŒ8ôdNÝ{¶ï90nÝiY‰Gcã·A  #²›ÚÜñÐdn\^aÀ³S„mWp´ª%çÈ#ئƒzŒ.ŒoÞœ/'ˆRÛÁœnL˜1fSÖLø,Ê ˜­ÏÍtªËã(,3•ëio-˜¸¶p]4ò©ía®û›X#‚aµ[K_EIZÔ3WyÕàš¶5ò0þ˜…+Ä›O¢zƒZôú%ÊB¤+ßO t9".c&Ù’kK¸y› O3ug ϯ2JtíÜ"ž)cUðˆSÿC“íà'ÉŠ ,},ñmá8-YºKvl9ž™©æî‡åbóNwaåL d{ØéØÙo•d““Ké`âÞ%ï¨s¢E9…Ò0ësg ö/p‰Ž¸†qTÝ×™¢ ·³¼žÄ2ÏU°VTõŸ€>PS‹€t7×j&-ŠÍe”–HØAî¾[8¯ €< `3];”yc¡jÕv«\oiÕ¨’"»­¼ :8À¡¸£]"ô9pýXVn¼Ì"y7¬€8ûÈBø}H޾G(kq4”3y›–{œ:Ñ!‡Õ ¢]“”uÕDu ¼¶&[.  Õ^Píš™„0­¦z´¬>!Àá—ß§Ê8¨ö‚ªÛÕ$²§©n›EQYë,ªÊ8¶]u A¬šÔf"çªJi²ÿÚ«€Y«›¯Á삸Ë«j×oЬqS&iûñö¯Äbc$á 9©G1uÍIA ]cºhÜþM¿ÕRÃÇÖ>°e{Ù¶å¾9\j ì¾ä?Ž¿ šÏ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 849 /Length 2417 /Filter /FlateDecode >> stream xÚÅ[ÑŠ\¹}ï¯ÐcòµªT%©`Y°×8H`Yû!Éà¯=$&ËŒ±Ç°ùûµÔ}5³öÜ‹}E`˜Û­–JGªR•êt5¹à¢‹ì’#6gŽ2;qLâ$9¶€f—ˆE—Ñ‚öR¢#u8-¤£êpqTÐ#¢7i*Ž1>…<|$Ù1ã£bŽ#šÐ1gôCa=0æT `tÍÿðQtÂ+ä"Ð&ÁÐȪxŒ–ñÏE梸˜2ÚñWˆ1¹hг“|±8áS£“ˆy%8Q€Âr!OДOðW TjS®{ƒ×–ÓAØi¬[jHØ4¡± =C öF­n’¸ ¥(v»X’K¨KvI0¾—Åæ^qè’Š©3r9 Ÿ±Ë”²3l{ Å{ÈC—¬èlÉåŒ]ÃÚsQ´—Íô`˜²n,Ìɘˆ&húLE!NUV8)³ªR]±ºL¬È¨*{o¬Ðf;š(ÔɱODuöj° +À@0³TM¡NS‡Uñ¬¡šGë¡j,A¡2ªƒBªèªA„Lù@§é³U¹¹NUVMc–úI5(¬ ï«I‘¤j˜L²(Õ¾:¡Táì:U<`HuÑ7a ©ŽØ¼Ã+˜@5ÏŠ'clF;¬®‚ÝAJm?YÄã œAÍëƒ|XÅ*éô*çÃwß¹ã wüóíË[w|æ®"ØÏîøüÝݯÜ÷ßãóÃñåß_»ãO¯ÿu}8þp{sw}s÷Ñiíx8þ|ýñöÓ‡7×q O »~ûîõÓÛßÜU@ƒšzƆ@¥¾Ø«¤|Àp,úÔ»O°Ìû÷üÓý‰’PhÉÅCîæÓ¯¿¾ú|WM>U“Kä fr¯çs uuyϳ¹Ü—U`fç—ÕêN¯1àøÓ‡Û7/®ïÜúì¹;¾¼þíÎ]d}v$ÿn ô+öàøäææ⮪ëªp¨-¤=´=R{´…P[¬¬>¸-ƒ©=šnR¸Iá&…›nR¸Iá&%6)±I‰MJlRb“›”ؤÄ&%6)±I‘&Eš”xZéáøâÓ/w§÷}wóŸÃñé퇷×N[^<þåøÃÞÔ½}h Þ.Ë¢/8óš²Çq‡ËbŸRD¿'î!ÿáÍ¿_¿¿»þàéU¿ûÂÈÉK}vZÔ“Ùga|ÄÈw·7ž¦Qó.ôÏ"iOÓ΢  ^ŒW€Ä @X|uÞ 1zŠkª‘ @B†ó* RÈ·D÷"Å|*‹jÄŠ—¸¦š4HfÏqQò!— yزIÑãnòy Ÿ~°Ì8Ãê^yÐ úeÚ‚fÂA¾^,.h†Ê4N³À¿4E°Ì$_DóÐ uEøzIr ‡h3¤ :‹©øz¹½@Bx2Í›!MP\”às^Œ:Šù¬ôh ž±3½È°3.¨<îrxŠÕ„äCY 9’x‹²dÂŽ`õ>ÇÅ|Ùà} ­™`!œÿË¢.Á#µ^2!P3¢AM».@|N–5,3 ɾOyÐ wPÚ‚f†µù!bC?H`ÖŽÏ„; äwiÐÄ…¸dÂ†Šø„üì „|é¾=j'Ͱ^’!‚Û§° ÌS!xxR3R8[ÐLð.G¯:è ùIüR†vÍC¸û‡¼¤i„$%l3›=“ª·ì¬¦ˆKd†Åø´’©ñ®·ð£œÄ $)q%Mƒ[Q¬^ÃÜ/¯áè[Ø$byH'Q£r¾šO’ÆáHãp¤q8¥5–ÖXzc#vJÛ¤ÒÖ]ÚšK#v¬­ÔÚ"­I±&ÅškR¬I±&ÅškR*ÏÛžÔŸó ô õ ö ÷ ø ù ]^WQ—wæÐÎ$Ú™E;ÓhG{µ«1gÅA—%jg5_Âã×ݸû‘Ê1ú`ËÑÎÕ>äñ(¹oŽÔqÀݱ,Ñ:ãn&+8xw ®.ìX†«£v,NÐKʆ`´–¸‚ãÚ½Cö‡wW¿}¸àÈpÁ²ãÎÝF¢¯ß#]À(¢] -`& #; ƒ†¢o3ÁZ²y]NO"dóA¶€ÙßfÔ•…`6óAÓ0ûß\4#M4Ðîù!o“öƒ´Qi š\‡ÚÊ©ž°)5aø(E¨D+8&ì¤dËý_‘+¦´á ¥ ÞEC¸—/j@<&Ùfï"A–l àk2«[Àìï]$Õ»ã‚%ùÓZ,Úÿö_Io‰vôJ^˜ö÷nB†$d$»‹}œß˜ % 2Khî€`h+8ö·ÔKÍÃ22¿´”eg䃥š¤Õo·€™°3‚¬ÒþV³I¶€Ùÿ Lj /19D\²-`öˆÈÐ}áÉ- p›Óþþ–µøZ0µÜàx ˜²?ä¥42î•:Ì›“íÉ)ÜG83Þtš(ì&¨¯õˆ щò¦ãDû»`*õË!ØnDiÞtžhLÉî}uE¹x-›ÀìïƒIÉ—¡ª‚R¸MŠö÷„„5Ä<ÐÝ8·eÓ‰¢ýÝ0!c¥2ÒÝ tº Íþ~ØŠ&d`Ûv þ¯¤÷,©oâ­“«„ö…ÄþZâ:ÿ®²š~S!ä¹Ìñ\çØ ©W:R/u¬…´íy.’ìlqêãSŸúøÜÇç>>w¶8w¶8Ë$v¸<`‡“m»VÛ–at .*Kœ·ùQ¸bÜê‡ð[¹â›|ÓÆ8 9GF8.¶-çà)¼1 _6'„cÛt3á8…=¦¡^£²Ç79R–)ô1K¹GÛðX'ðÇê#Ýç)mº ð&F<ë¡–>ά̠jÍK¸‚(¼Rï¤3ˆ@X­_3hýÎ#Ð Žý²Â^Ó&+ìURYÁ±ÿ)VXj®f KÕ¨+8&0o°Ñœã@Ð&¡ÏÂxýþýõÍÛw¿ù×þÉ:Ôî—ãUTÖ€<݈žHá¡&¹V8=^–÷L½æ­5Óï…ܾjï…Lòm÷Â^a@½Ä€zÙù÷0çÄô_Äô*îUÜ« ¸Wp¯2à^eÀ½Ê€{•÷*¦ó/lº¼^eÀ½Êà´ÿ½2ú¹ endstream endobj 255 0 obj << /Length 846 /Filter /FlateDecode >> stream xÚí˜]oÓ0†ïó+|™Õõwâ[Ƙ@C‚­BHcBnëuFiR’tíþ=N§+d(t›`Л7±Ïl?y}Ž3€ÀIðr _ÇH(`t¸€BRKkc FSp®Ö'©šêh@8 ç*[ª4º½¾NHìHA7#…± ÖïfЩûÇ£à[€íCðÖ9 å`2..˜Úwo‚L&`µé9#H¨°íœtw „@ŠrgÆBHD3ãSSVvºqæWίÕ|‘êÒM|gɘAÉXG\ÄΆ8`d×û&++•¦&›¹õïl†ªœæ‹j¸ZÏÜ*’FŽÐ³0LÊ?ðoëÃSußG1®qv€‹fB„l§Ÿ·öÏc(¹ð´HCë¼REÕŸÕpl²-7ÂãÿÊ£ÐàŽiµs”…ž4û®³JzêÉ8;Ékye¶‹äô9‰æÙ)Iôdç•ôJWʤž—Z,R3Q•É3÷ ¬…æz‰™æå{]¤Ñ ò@m_\²'.ê>cÛùŒy2*¬žŒkÅùÂl3 Õà±Ò†JÍÑ·^¼pE‘mOSõÔdK{–&L=€‘ðŒø/Í—ieöDDcqPÓ#ªI´¤²ˆ¡ð&Â<Ôw’¿Ù§³£Ÿ™¬ÊwzídŠ-E.¬îce¯}!F=YÅ «Õúýmuí…±BžFš+½²¦Q^çááªj¡Ë|YL¬žÈ}èÐ6]?Ñ™.TåˆnT› õ¨µORU–mbo¦3m¥C=HçWpdO8äp< ×®®±­"l»ºcU6cÆÒ®‚%ÿ—^@H_µÐßr•;Dnê³LF}(²›nfÙ\×wàÓƒL~‹ŠðTØ^2Éš:¦Ø)bˆ¸/c}uÔ 9‡(¡¾£®Éº$$k$wmƒXª ûZŽw Q6»l惭Èã'ßý=ùöãtOih€¥€˜ÒEÄ÷Q©«m~g³´…Í÷n»ÊÆqìѼSëSÍìù×±.$·mÒá AÂÚº¶‹ª?–í厷^:ÛÏS°äïTu?ÀÝõ#o»ÊüŒ@‰Ø>UþïÉ.É endstream endobj 277 0 obj << /Length 1603 /Filter /FlateDecode >> stream xÚXIsÛ6¾ëWðVrÑÜ—œêzlÓ¸I#eœL’EBjŠ`2’ÿ}ð‰d9íÅ|ØÞú½EvŒÒpŒÛÙËÙÅMœ©F^d,×FÙQêq ߨ5–…ñÙÜío«¬ ÖÜ s›Õ}VY_—¯/nÇHàeäË—ŽkDZ|å£ï”ŠK³ëåìÛÌ…]ÇpÜ=;ñC#ßÎ>uŒÎ^ޤ‰±“7·Fè:¶çG@WÆbö÷Ìjœ¸†çÙ¾“x•£(²ƒ @éïZ²Îr‚jŽ tŒyo#uq¹¡Üšޝ “tAxÞÒ‘GyY­HÛ1<»miYRö›†¦zzpX4-+ÛlûVgf¸ùî©Û°Zí½#m%I×|Cy£v¯^¼À»Y] Øï¯´È¬ÙÐ\k÷“©»º#íÚrS+Ìs]; C4ï‹:_<Ï¿ýpŸ–®5÷Sß$íX‹ôZþºûˆ”ÔA÷4ogë—Và˜´.˜å…æŽÛÖ<öSó:Ë7xÎÖøí6‰|“5 #Ç­õ1U;ÚëòTí÷iY¥A¦v3õ´½©~rP½ç´.Oy`^i–$ð(!-©su,¹ bG‹’t¼oÖvD=íëŽVHÖè+ M[e„k¸žºn¨°æ'v¦¨Ê«»,¶'Qé%vœè›’?‚ €…ô¤ Wÿ¼ ßܰ-i²RÆ|&2KdÍ£¡©?gÆgùhÓuÍ«‹‹Ý¾N°9ëÛœ3ÝÄ,‰]“NqÀìR¯ÐGá"L´–»å:gø-(Ï{ÎñîTc‰ïĵ¦‚·Æ¿õ„w”Õüå(˜ú86ŒgœÂíÈ\Y¤ÄEKD˜$ÃPEvsVUÙŠµ™à*UI m@ÞVîHF±Žñäí€}8d\³Z]!êMQ´„s¢^¢cBmk4€!ì¼¼ —³VÇv¬|Y[nh>!䩆°H5 ZBŠU&á+ª@ Ua'KÓÚÛ‘*ÜŒe¨Ÿ0ªJ¨ Âd»b=‹.¸VК•¤þSRg6˜Ôïmú#¢àæFd± v-í:Rã½dtIk‘Ôbõ]Ø 5£Ž×ú>Ul –÷[R lyiU\1Êûò¹ûÏ|NUíJˆä-­uX©P\e-GS`qÛ² Ô²ú×ê@## Fo$ âDaˆ¥•@]¨l³öñJÅX‘‹*ÃWJp”ÜòǛß—ÒøZ›X¨Ö&²R¶Q7 Í;h‹2+:ô*ìJ¯Â÷¤&%³Ž‘@¤#€¸¿["QќԜˆ´Œ B°<…÷D) Êñ—MCê‚îÕêTíöض5]Çvê(Ø-ó ¥Xºiš¿…¸|ÝW4S¢¢î%Òï™ð£¦ÉJå7¬H§3Rø„-yu.³Ä]·wØ\v{Õ‘lUºȱa÷*Àµâ'ó[ü¨RèV(bTB„¡#*¤w‡ãŠƒQBqzÛ ² o”GîêüT0Ũ#O& uÚ’_ÐŽÕ›H¸bms(ÿÏ'çåj…¾SùæL ¦z„<Œ¢€ õÁÏ$7oÀmlWϵ5Ϫ6&íW£P_ܤîD‘ÐöuNÀ”7¹=RÛóíÀ= 胡RHá7*&}®ÎÝÔŽÙ¾]œSAÁõµ í,þáÝNž'ÑP¢z?’¸¸¼>kuJ´ÈEˆË*V«\Ã,*ÙY3‘ÃHènÖLøIâdNA06Gåé¬õÈv¢HyÖzÏvýXkrC+e·„øÚ?(tÄ¢îp£ÙY6 %˜¿É¤gÓ’UaùxÿFVÇ«púø©…J݉…¢æôÏø·«k'A¨mý¡êǨQ¤¦{Ü‚™«z¤¨b„»êMEWmÖ>á³ØÌ[rnl–ÃTŠ„#Õ5:L%ާ¢¿@¢rÝbâ!WÆù¼©²ŅJ§¦©è\Rh‰vê'ã)%Ǻr,µ!8!}¶ñ±CÍÆß“j|Ó…_¨ös‰’:“è=|ZÜ=|º}&nAé¸=l2¤O– žc½ê¶D)y§LøÙÅ[ÒÕ<õ/ˆ€üŸÿ@ü —-„; endstream endobj 287 0 obj << /Length 543 /Filter /FlateDecode >> stream xÚ”Ñn›0†ïy _iqmÀ€o7­ÕªmÒV¤Eêzá`‡Z›ÙФo?†¥Y–j»²9øøüÿw Pn‚·EpuQ@!M£;@R˜ÒdÔ­÷«ýá¦f\„눠UÃTÏê𡸽ºÎÈ]f™ ¥0˱»wLz’R§‚÷Eð3Âàß×G0 (›àþîÞÝšƒýx²#Å©Û×à.ø /K§øŒt‚!M&ŒG sÒ‰ÙC’ÓYqñè-n¦å[˜ •T\‡Yí§ØÝ³íD3íŸBLVÂX©ÕÀžTËÓ£jk_n],"^á×w¦¤³Àͧë-³‚Oåì‘–6Ó† [¹•ªšž÷‡É¯Dg§V÷¦þ±–?BŒVÞ;—¬Ö•}ã›-TïÍ:­ë-3v´ê¼À”Än! óâQ[q¶3>^k7NÞ…Tö7ÏüYÛÖ²dÝ–uþ¾^­;ÙˆW0'¢ÌcN'Qçê"çF·ý¹o„qÅ]Ÿ{BØ FêX-í‘LÛ·­6ÝDf“¼óᯉ`jfÄYÛ-ݳz×í‡î,èfX\î†±Ü #”§S3Uõ¬só\Š3PåþL*—sþO?¶nš:qè.!c˜% R?…¶F0þÉ¡enÅž‹âóì”§ØÇïेs?$r>’ÿùçüX–T» endstream endobj 292 0 obj << /Length 904 /Filter /FlateDecode >> stream xÚUÉ’Û6½ë+pJ‘5!€—\RÉÄ£’ÝrM\c0"$¡L4—’çá•I9õ{A£_w“ #"h³úq·Zߪp•³íˆç8¯RTTFíjô¿lQË8aœD­èfÑÄw¯×w%A¥ñÌS뙕.Ijâ:'jÌ‹2Z{‘rë±zµ[}^QcB}¾Šá2åhß®>TÝkDpV•èì,[Ä)Á,Í nÐÛÕ+r™~I-1¯rz‘¿É³,õ©ÜžD?ÉÁgB!uŠÃ))™õ"(á¨Á¿÷Y.¨11™)wÁ^`Ź):/u/zö`uDR{CŸ;Σ+ŠuïL}15‚í£-À¬š:Øœ5M!ªùûÓtÒ]§º£‡½îçFGUåäñ¤uóIÁáüå>ÎL,«ñ¢@×Ò4ÎUÛ°´ÀE™Ú¶ù¼ÂUšñÂ\@§âYî¬d¸àáûzÛRô“6½ôÜMá‚nH.®øç 0NqJM„ãŠ'wê8P@Ãùwq’R²dꬺZÇŒGçñÅ£„VÎJR†Ih ç4DÓ„îìÓÈý Åälø‚j£ª ZP=­gÎÀ+NV•Ñî×rTÇ.DÚ»f³ù ƒèŽÁFln9Èn‚˜>ÚÕ]<à1¸\tµ­‰ítJqÅsÿøzн©$É£û÷o·÷ï7þ k5é!æ<2yf…ÍÓŽUªíõ&áËdß`+’›i{Ò/…UK ‡ªYÅÕ€øOP·½ÔBžÕtòV%XÕ²¾¾äò­Ü¿õ_fÒ‡3.L‡ÿç xld6{i8óqµlVôp9ÑßÂA ÀŸÕؼ½¹ Û¦öà¯?oakˆQ·°\å-€îõæÝvù&XÖ?XÂX=éÙ×fg9‚òñÉKϪh¥É.ÍX¤&0jÍã|r廯¾¾Æ­žƒÑîÍÍzóëo¿¼‚ó»-Üz±ÍŒ@àÛèφÕ3ö0žÄ ÇçŒ_ Ý4D£GÝŸb=]÷k­?yô &%¬ò„ŸìÖNà«:ˆb[>poÜèrñ¾ô‡ÎÌdÿçý73Y$ð endstream endobj 289 0 obj << /Type /XObject /Subtype /Image /Width 728 /Height 377 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 33554 /Filter /FlateDecode >> stream xÚì½XɺÿÝxvϹ¿{ïùŸ{ή9   êªëšÖœfQÉ ’sÎAÉœ$$JF’bÜä&uƒ9ò‡ÂÚ¶gº'Ãð¾Ï÷™§ººR÷Tu}ºººú³©&kÝÿlª JUuõêÕÆÆÆºº:pÌZ¤B¡”D­ ó걭€tU€"(Uü¿¿þúë½{÷à?‘œ‡B¡”DE°m¢zr+ òÕÎÛ(UÕàeþð/“ Ýá„ó(JIdéèGn ±m¢zr+ 2)øJUÅäÈã©(JIÄä<¨Û ‡|á{Iõå]9ÂäèýÁË$Ñ•ÁbÉ·«ÊüJLÙ¹?^!Úgã¼ÑÌ~½±$Úhjá!–¢ €R%ÉSºª**$_&‡`ÛÄVÐc[á±nELMTSsk“À!Î&NœÈŠ®œatx„Ñ¡¯¶3}ï]I!GÒ4:,gÜ®*3“C÷cJÚ?šF´r °v Ø*ãDJ¾$‚Û\ü·¹² €BÉYºª**$_&‡`ÛÄVÐc[á=ç<¦ ò·¶IàgÐ XÑ•Sê«Â§lÿfÆÞ»’kJØ7ê«wÈ·«ÊLÅ俈ÃLIûGÓˆ›-öÇeœLÍ—\Ngl²tb…’³:uUUTH¾LÁ¶‰­ Ç¶‚vq)`Jjy=ºr zç™ûîJ+AŸ._Ü®*3“CüwaJÚ?šFÜlé|*µ@ZA,VP(9«SWUE…äËäl›Ø zl+h.ãZÈ”´M€]95lmĬÈ{Ò bÉ·«ÊLÅó\FÚ?šF4´r=V(­ ޾¢„%Ouꪪ¨|yžË`ÛÄVÐsZÁ«ù!ÅLMœ8‘>väy(I]Â/+zçˆ4@ÉÃ[¿{vä=i±„ãò\„ãÊ#‘ù²J(6_&‡í=Δ´4hlí—^ÈÒÍ×M8Äb £EJÒ™»PÉ™yPæâ²ªnwD"«“X‘êÄŠ{“Û[Eæ+²EðäËäžÖ6•¡™c+P’V@8dœûE¦ zSÌæés ªÃ/+º¢4ÿüXÑO?üöôEó˧/Z~þóYѵ?è^R¿S¦6|þ¹Q÷¤ÄŽËsNÖï¹ÄŠ+¸òöáÉ—É!ÁûN0%íM#šÚzžI/b‰UáwD±@,Vä׎ظŒœ¢šº†ë×o\½v½®áJQi%ÝKJb`l%m²2Gd¥ l ?DaQ§®4^…ôí]¼-ì<¨ÿ…¢²Kµ 9"9EK",‘ÕI¬HubÅå¹3+¤üU‘+_až|™¢„m“åÚõëð÷%gå‡Fìª*Ä,•b[«2¨'·‚vñ(eJjy=ºB4+¨òöïÏ?ö¤6˜„¥š„œ ;YP{ó×å>)$)ƒm`ì,¯ó’$¨a=/ê7i±„ã’~_XÄŸW —™ž|¦›äΕ/“CB"O1%íM#šÙ{ÇgQ‘šŽ ð(*êI±XSâkë/~ì?·ÍÑËÄÊÁ?$ü|nž¥ƒ @ʰpéJ¿©R–9"S&Û@íÉ67‘bOÑÉÄlÈ%;'wÉŠ5Æ[ä”û|~)¸c_k`²ÙÜÖh«£ñV‡Í¦6k6{†FAR†EKõ]ýwѸ7nܼ|¥1§ 4<6ž–äLj.Üî]¿~~O'ŸgE„½p©¹vízM]- MŸuPT6®Æ[iRÆ‚âµoB"õ Wh\®ôùw1•_\!8Ûaá+Ö8zoÚ{<Æg FHœ=7Y’|ý‚«kêà0«jêœJ#q e8p’ËÙô<ða ”¡®þ Ä‚’ÏJ9WÐp¹n+ªkcÛþ;±Ee–Ä=h/«ð¬ê$¡Hu®Š¬z(Ò_¸*J+‘ef}íŒf†•/“C”­m2›©ºVön°YSS œuJ¸&‹­HвH+ƒ½P[$©ç¬\XÆ %äo­ûO¦•UÖCÕ½X^}äL¦Ìÿþ®ƒ gÓ/”WÕ FŠ®]ϾPhºÍ…îåºÎ°N¶Ú ‡Œ÷ª`JÂ&@öÂ/+:Q\™$Nf×Lñ.¾påwpW6ޞ铞ù=¸ÏWÜXë—8Ù¯êÖ/š[ZlVhlnyyãçFA K|3ï>xÁ<÷%úŸZ䛉Lð*ƒß>çfx@ú¯8dÿlŸ\ØŒ¾ð£É¾Rãà³Ò*Á?£â{Vy4·\ý›´‚XÂq!ý{/ fù“¸òˆ«Ìô/€ì„KÂÊ—É!Ûc☒ö¦·:ùËp­ƒX¬dç—@˜ÈØCþ;–T‚;-ãœGðÞ¤Ì|“œ9kºÍ9||iyåõë×#¢ŠË¸qãFYE•‘…­[ ô†‚ëŶ [Ìí=‚üv<áq.“ÞaÑ~û…t™¾[ànØL;_²{¿±¥]ÄÞhðOJË : þñi¹°™WTbïê»ÍÁ-;'.8à>—[`íä}ä¸àbrät")? ¶ÙÔšu\L±Ê@6Ï&¥z‡ì5±r„¸<éóìb©®èLÌ·A‚äØA€pµu +×Xع“|OÅqðŠØ îòŠ*ßðý,©mbIJÆyk'¯Óñ‰à>~&™Yx(­OXdhÄ>²yîB‘gÐîð=à.+¯„ÿNlQ™%‰KÎbžU$©NÂUQ’+°pU”V\eæ¹ü çËäek›ÂUw×3°y©¦fåZ¿ðýÂ5YlEÊÊÎ Ø ­ °yè¤øz.œ -ÕêF¤é1›!OR¤„ï‰1ÝæävþBm)’ëLjNIÅ%¸ ]½vý|^QľýF¶ë6›Á%È3d Ãual´´sˆw%SRsÈëщlNÆ@ê®}gœöôE˃ÇÏ_¼h2 Ïot£Qq9&'fúäoÜ]òøéóûžüþèùƒ'MÎ{RÌ­ðKmjy ÁìÃŽ¬ðMûÊç"$Hó%é·sHÐþÙ¾ˆÏr¿ôÕþÉÁÿ÷ûXåatdQÌïÒ b ÇÌKÙ[#˜åOâÊ#‘efý \e¦brÈŽØ3LIûGÓˆÛ\‚Îf]¤"U.$"†ßb± p<ñœ`¤79ÅÊÑn+êë,l ŠËÁßÍÃgÝ&ÏÈà]êàXßwW-mœV­ßlåäsn9nÞ\¹f¸v†iý'éÓK–{àîö’;ûšÛ¸ç•UU–vÐàö6­\×o17µrrñfF„»*po³wÙh¼.°à¾XRêèF\±f#3}a±Ê@6טXmsò1³v©ºTË•>ÖLÁ-^Û©Øhíì¸ûø„Çž¹Üx5>)UÝ&gß$ß ›Œ6™n³u h»_»±ÁÐ"$òÉÅb›ìrpówii™ƒgÈ_¥Ýd¸ÉÄŠÄ€Ÿù6èàœ“D6[†¾JDdQY%î€UxVu’P¤: WEV=é/\¥•È2³î¹ÊLÅäek›¬ª»÷HRþEÁ˜Ûá£Ç—é¯ó ÞÇU“y*’¡‰ÅF#Ëm.¾.ž‚r±ÄÉg;=Î…– *!Ê&akŒ„\»nëàb¼Õnp îs›à}ÇE5ó2"¼7ã\®…°TþÍ&М 9øîˆýë_ual´´¯ëîSÍ”´M€hj`Í‹æ–GŸî¼Û²ût>üLÌûã1ðH‹CèÑuþÉÓ|/Nð©:{ñ[’`FÉUËÀ£ký“gúüz_0?ß7w¢O%I“ÛOÝvAæøæoÙµüÖƒûO^¼|Ù^¶—/_²Ê3ÒäØâØß¥ÄŽ+(þáÀ,W —™ž|ȈºE–™ŠÉ!áû˜’ö¦mÜBÏ•PÑË¿'Äb`×ÁD¸2ÔÖÖ†î„À^~ðö Ü€kƪupÙñ8´#6>!)ƒ$xôdÜŽ™Y»z…F×·‡šZºøE@3'i’`[Ìl¨{ѲUA{Åe–VÔÇ´ÁËMÒ‡®Z·Ùç!Ò‰ë¯30·$»=:Žñúõ¬–e^»É$hÏ1ÈÂÎ#Ød›3c3)榥ƒ§ïŽýph<éógÍ ¹bõßð°hÁ©8Ÿ%`9ï€F[½B£˜ùúìh¿™]²bwhô+†Ù`åèqÜ@ƒk Œƒve•Väæ’ká¾’§¨¬’ÀigžU$©NÂU‘UEú WEi%\fzàu‹,3“C”­mÒºJŒRùÍŸàûŸï]ýñþÖ £7üíö/‚W<.ó‹uСEþç'ûV¬j|ÞÔòÓ½¿Þû³©©Ùgæ\¿ü‰¾U§ËSG.”Ö-òË¡ þÅ~ùL÷Ï>wp\妠dÓíÉd«0Zf'—ÄþAÅs\Ì`KdÜÍûj™>"ýI\yÄUfÈ…dÄSfÑß—9p–)iÿhÑÖ#,)»„©Ð]1¬æOa1“bnº †GâÁ‡'}ɳ&! M-Üv“S'.†«Öo±´÷Øu˜•oûærA©È,ƒ-&®»"&»¤´léÊu@¢c‰J„§¨¬’@HVáYÕ‰g¶?3©NÂq™UŽË_dU”J\e¦už§ÌT¯}_FùÚ&ý»%¶˜Û‚ Œ,7YÙ¸ø ×(/¶"™X2›XñÅhã>¼õ\8Vƒbùð7¨V6öQ1ÓÏêêýwùç®\c©Ñ\¨àæh³±åŽˆÝùEmœs­°¤’îå¹Î°N¶Ú ‡Lð«eŠÙÜÜÔXRÓTS[+m¬èTÙ?’tNœ«2:™y•lžÍ©´ :>׿pzpýw÷/ÅxÅfìO}ñ¢é×ßî/)¸3Ã~¸s¿¥åeêÅ«ö^ù*°nÅÞÆvö>q™î;m“IÂg›lO;Wù ÙÅ*Œ¶yܲýPñ4í-‘µ4Ä’3®<™/dÁÌEl¾LÙu(‘)iÿhÑÞkGrv)K¬Æ¶+–b± JÉnÁ|÷¾¸Ü=•H6#vË+$rÏ‘$¸¾ TÜ­lá6.nþá±7òXJIY9 Êɸ³1'R÷NÚª!–,_åÉt7\Ü 9»ymµsOLyµk5ì"ÓQRÓÒ}ÃöEO)©¸ÄŒHJŸpÖÚѺsoî…¸£ñ~•¾ðA1ÅLJx“ž‘éóìbåRTV !‚B]üÂ#žŸ†Ë©Ùp÷êê¾#æ4O1ÒsÏs>êº7§mV0œü«7x¿Eá*¼„g‰U’”s…¬Â³ªÏ˜Y©Hu’'®<™/dÁÌEl¾LQ¶Iÿ_sl]·Ú{:y‡í9ºëÐYáš,¶"ýÕÄÊM,$lçŠ5‚½b›3—+×#ÆfÔGÂzX\V}$ÁÎ-ÀÓ7D0µ©¬|Ãóí1§…ÜÑ+¤ým\¼„ÚZÐîÃÎ>Û-lÝ€Ê,¬¢bÀUÈÖ-€ìå¹Î°N¶Ú Ú9Ä¿Ž©×Q\%AýÏè/y=:Õª¨k ¹¥Åm×ÉM‰KwT45·€OPLâæ „¯J3êÝhTjõÖ cëS"SO[Jê¿ýÊ¿¢/½˜VPóÓ?ž7µ45¿üãqÓµŸ_¬¹n|pn@Ñ+¸ÍŽÞº}çææ–{÷Ÿ’y°y½0Ú–ñË÷ÿÁ”ad-—hˆ%g\yÄ•/¿'+_&‡ì>œÄ”´4èè³3å|©°ÂvÇ2ÅÚ ±XŒË$c§ë7YÚ‡î=BFwM,¬ Ím"´Í_Ýy`ÕºMæÖ.{¢¶Í[KÙÑývÄÂÝMQñŶYð7®4^­ºTwòôhøŒ‹˜À}<1î¿à楦¶.!ír"®´¬²¨©»|ìÔYýµ›6›nó å/¼$gI¸$®N¬Š$²R‘ê$O\yÄ•/¿'+_&‡(aÛ]W¹÷Š­Hþ!KËbë.Ç>±rÍFCskØ+¶‰1sI>WX[W×~ó"²$INÉ)(.ËDãÕkE˶Ù:B|·ÇÈVvHØyÀÑ+ÔÌÚeƒ¡ù𠆻?Ïu†u°ÐV@8db@SÒ6Vt¦æ[± >´<ðüÔ€êYeÛ‚ÂæÊÀsÓª!ÀŠÀËà[‚B€õA©¶Á‡áwR@=hq`žqÐó S&Ag¶%n J2 : ›,ĵ >I·~`ö¶ cÔ¦ ä•AÙ6ÁGX%e•¸âÀŸÒ bÉW)$_&‡ì9’”´4èì·+5§LZA,Vˆ|¢—¯Þ°dÅjϰ¨SþW¬Ù›¶®þaQ'!ø¯Þ`¸ÅÜÖ3xoXô)¸Y¦¿Î®½É»%¹úí40Þºn“)üZØ™luX·Ùt­1$ qõ×m‚¤ˆÛÖÍ_­ÁšF¦VŽvnËW­£»‚÷5¶´_½~ËF¸Ç±u³qö[¦¿–î Ú}ÄÔÊ Ò40±2±t€»B([à®Ã¬ô¹Ä #…'}ž]LEK»|ùÊ7\½·GŸÎÎ/ƒ‹í:èûí=‚÷[ à½-f6pf6[m6³Þbn·½ð_ˆ-\×ÖIÀV@[A;‡^~M¯-)Ì9$H_]gGgè«ÀºåA9ëƒÒæO lø2°aYÐØ\Xôe`=˜T²:(sI`ÞÔÀØœXú:°6!ʬÀòåA¹k‚2Ö¥¯ J_tnYP½KÛ’šxÜ}IPÞÚ  ¹$0R`•DÇ&eiÔ/úÿ”\K£~m“*g\y¤|™²÷h*SÒþÑ4¢{྄ô´œrÉŸV±X Š8àèbaëîµçp2Ð…“Ïv¸Ôuì:”|wÄZ;û¸ú†ïˆ‰ƒÍÐ}'ìÜAÁ{ÁfÛÕïܘX9zAg—kg_¸ú…´í%#¨p×nˆÐÁ@®þ;íÜè.¤æè» º{ànHŸ¹74ò„‹oø6'ï­pY ðÚ¹?ž•>—XaDFáJŸSd]÷ôÌ,¸óª­¿’u>oÕú-®þ40_1ޤÀ…ÚÁ3ØÊÁs›“œœíѧ$)®Âär …‚Ò%r³Û†‚‚R6ñöô–DØ=¡CCCCdVßÏþÓÃϪòœ%ä551*.(†2c…BAAA‘­óíœ^X™i9Dù9*9v‚(ääänÊ!ÐÏ2ÕA½°öÍKe,Ïò‹E“'~QV\Ø…D!ö‘Cx8D워Ì! ¤rrrH'sH'ô«W®ö÷cyz¸:m2èÚ‘žÃ!cì¢YÌIÕÐP…O ‘CöÕ>lyÙ ¿]H(Õà%XFA‘™C„ŸË4ÔT»:9襡>tóÆ Ue%R•-9áÌ8Ý1õ©­ªÐÑÖ:—ž*6—qº:)I$ÀΰPâðW ‡p óTx¹¹ji צnnlåïvã!€"êCÕèxEÜéSàóÅŽüŽx#–C¦œùåçGÍ;«üô¨ÜÈ!(ä…pˆB€D!‰ ‡ ‡(C|=ÝÌ“{.³¬¸pãº5VæÒoÑüy‘»wÑM ŠU+–I’‹™‘!KÉÏÉV<¨²ô"¸ƒü}È!\È< çÍ)È=‡³ƒ]w|.ÃD D±âXøÇµ?^€£ñ÷àf‚AdíÃ?žµn~øâåÞšÄsmÆÝüÛÏ îã/ ~|¶0ù‰B•ÈŒø_Ï\üû³8f0²Û^uÿ—ÇÍÏ›_^þíÅÆ¬{Ø£ää/w×þ}>‡ß.$‡ŽNédC@Q™ù!ÂŽ ãÆfµ]€Šó/èŽ%mñN=<}ÊWtsòÄ/ÎÆ’$—ýQ‘kWé ÐÕe¤Æð°à@p¯Õ_y :RÚV&RüÈ<©É2Æ(Ïü‚"ÛÃBe€©¦…ˆå’ŸŸUÜG`ù}p39¤ò×çËRï€Àq°á¡X–#¶þá¥;ÏW§ßŸt'îúcâyóϦmy¿ÏLøun⯠7§Þz"r<„nÉ@.ËSïÞcÇè0UžCNÞ¿yýš1ÚZƒú÷6xм™3B|½¤"Žä%< ?³ïî÷ùg2”pæ´©'ŽÇ‘±ófÏÎNd.Ue%cFit9=kÆ4pƒ´Ï†ø”ë™§‚Nµ„ï¾óTE*„(CV¥ßýóYË× ‚Aø·~ú]ÚÑox5Ȱ1ëÞšÅú³·6óSÌIüõΓf~ùéQ3WvKRî7PÍ³æ—Ø£äḬMü%8àNíPl4óê$òY0?ËQW]éhgWËáC‡øx¸Ïsé©«W,‡¸Ã† Ö_¾¬¤0Ÿu›ÆJ¤¦²ÜÒÌDKSؤBüà– .†pmOON”–CfN›¢¿tqìžgO9¾?ÚÓÙaÚäIÈ!È!œã!cõr³³ä,áþ¨È% çƒcá¼9‡÷Ç gÇ• @˾Ý3¦N7üÆFí›?g–bç©re-z<$5¹ûއtÚk2üròêcV¬“Wÿp |Båù«ŽžÇŸå€]4$•Ñùߪî<ð¼…d×ò²•ŸC˜‰ˆÌ§— Â!K-  GxX¸™‘Ï‚yüY7gG¸xžÏÌ(+.Üjnúj,zÜÂÍTùÅbs#ú²ë I7d —üœl\xìli€•Ë–Âen ]ígϘ.-‡ êßïÔáý"w%:fºÅ`ÔHÍaƒ­X¼ðÌу„:¨„7™X{+‹Q#4õë;yÂøÈaÄ?áøáÕË—€ijilHÇøzM« !Š£õVäåäo/¨Š™©ÉÀÞiI‰äA‰´j¨©þrÂ;¾š4Qdv\¹xººŒÖàã-ã㥣­·Šå®¬™§bÑüy¤íƒƒ6Fä._.iI»K}ôÃ#Ìq ã!¤ðþåÎOº3õÌ/ðK¿”~<9¥(ÉÉÊ©1œŒµÂ/¸sÏeò? æñg9ÆéŽ9LAUQR —S~;F‡f©1³+ÊË%îêòR‘CÄü2{úÔEsgïò‹?vˆµËÊÔxÆ”Éöí:y(véÂy×èK2Âäy³¾>¸o7ŒÉæS&N þF×C¦GböfNBîîíâ”r(jÏÊ%‹C”ö}À€ ãÆÁNžøElÔ>Ù ¹kÇö}ûìßÎõÒŠÈ\RÎ&@¬‹y‚ÉyàNMLP,‡pe-ü¾Œ†úPS£-tp9„‹C¨ 'X~ÿâOÏXž¥?? (¿Ozöò_Ú瀃91ƒËŸåˆi›²êõù!¿=mq-þcFü¯àŸû ü³>óž0W¹ò×üª;Ïa9¥p±¶´`ÍX³ÙjÉÿ,˜Ç_øq³ðÂM‰gâÌ™ ×±ö×öû|ÎÏ!ÌDDfÇsåçÓ‡÷¬ÿBoÌ ~}Gk0X»ŠèÖŽÙNÜÇb£FД–CŽÆF÷™c‡àªNÜKô®öd£"¶ÓðZš6¦‡£öàsü¾ .ð®J“ÈÕß_80^!r.ú£ñ÷¬÷b’n>™!ê}–?Ë1=þ—£WÝyÒ !w¿z_Ʊðï45µ´þúXð²0 ¼§æÁÃ/…ù:A0•¼/úŒ9¥(ia<Î=—I‡G¸žóø³ãõt…ÇC |ÄöÐÒ¢‚úKUðK³fýI2"'‡0ŸÂDíܾ|Ñ‚93¦ÑG6¬ {ÒrˆHž„㇉;þøaê¿g{ð¼Y_2xŒ¶V€—;rHgrÏû# ïÄù_Wéг È!¶Œ*WÏŽ=>JÅ8$<,dùâEìé" …’¸žóø³îÎNófÏÊÉzm~ˆöÍØÈ½5•åà¿zÅrø'óo0q°±¦óCÌ™íhk£pi}æPìˆ[w”öÁ}»…ÃP ¹)–C¸ÆC(ù{º¦Ž‚ã!8¢äB&~ð 9…"–C¦O™|h Ëó@t$Yâ€ëY0?ËQ[Uio³MG[ BúzyÏC±ÑÆê ì×gÌ(íoæJÇNäRE™…©1y_ôü2mò$Og‡c±QgO9°o×êåKfOŸJvY››|=å«èˆ° Y4oñ×Pž4Ö¦X1ܸî¯ù!Óþš²xÞÀÈ 8däðaÈ!È!(%ÿ¾Œšd†‚B‘g=U®{Ÿnôt~ ñóž?kæ°ÁƒóCFŽX»rÙɃ1thÂÆÂTo´öÀ~}Çëêøº»Ðù«êƒQ~`mŠåøã‡W-[9jÂm6зñ÷p²×¥ Ř0V7ÔÏ99Õ-¾s‡B¡CºïºîûÂC~pýär …‚ÒiÚ°jåÑØÈƒ‘»gL™¼aµ>rHçpÔ”j9…ÂïÜu»»'¥âksÁR´êCõ—.>#´n rHGpˆšjr …‚‚ßÛíF‚§EÅÄÅ!­hhh]jÈ!È!(ää444äääärrrrrrrrrrrª›rÈýû÷å‰îâæºÙØÈÚÞÎÈÂÌÍ+ØÑn·¥ÉNG›˜ðÐd›È­f¡áañ†›Ü=Ü"¶YyZX8`_††¢zºÑC PMµ9ޱ©©‰ëðŸ={Æräi&]ØóåË—Pžæææ>úH…9dÖŒéò ˆ½«ó??û÷ì% þó7µ·?úø#Í÷Þù÷ußQöîêo÷ø÷5ÿëS 5µ|ò·>ÿüç5µ·±-‹´ˆððõk×àykŸýß¿d‹¸võªÝÈ!(”ÌRyyüøñé­¦¦ÆÎÎîÃ?äOpâ2‡9::áÙ«ÂÒ÷³ÿȃ".þÞjo©%d¥…ìxëƒ4½h}ù¼õÉýÖÿïÿ}ñþ;êÿû_cÔÔþõ÷Mÿd`yÙ 5µÞíýö¤Â•¤Æð[·ná©‹2sÈë×Gjj<}ú9…¹Ùm“\·¿½EžÁIÂ!Nr؃ºðœ´´´ÈÀ!µµµÀ!bQáåË—\âìì Ñ!¤ÖÐпàI'òÆo¨6‡Ä>%3ŠØ¸;Û{»ÛZ9øxlsö°wu°Ýe½u»“ýO·XCŸÀ£æ¦žö¶AŽîîÁï¼ó1Wç2åË/á_`ŽG}õå$±NÎùóK-зÏh­‘V[-ïÞ½ÃÓ KÚãmll„Ûꡃ‚À•D!ÿ™¸8ƒõë…‹ª=b„•¥Åï¿ÿÞi¥º›»bÙÒýúÂù´µ¶æÏZ¶Úçÿþ?õÁƒ¿ž>Íß×ç·{÷:a<„ ‰$%žEA¡‡Hþ8FZQSsjÜàC 'ÉÕQ¢i§Hþ\F©ªªùßÿýß®åá?ÎÔÔ”Sy8~eF‘-Væp{ zØÚô¬µõÑÓÖÏ[_¶Ôô¢õù³Ö–f6_¼huq PS{—«s™3s湬,ê“™‘>b;åK—d¤§CÉ=|¸=,úÐŽëȾùæ¸¡ŽŠÜw§Í¢##a<åÿŒ ·ÄŸ9#\Ÿþv™›štZ©V­X‘›“óèÑ£{wï:ØÛñ?*’í_£{?~\_Wçîꢣ­õÃßw‡œ>uÒÌÄ9…¢"áTd8D@!mÂà'ê` ºZ~\¾,9‡È0%@r¡ ‰Ám ’Œ‡@᯾n@{&¼©TfmeµbéR©¯Ì!€_¾øá÷;Ï[[›A-­?…;dÐÓ§pƒÜ®6ñãá”ääE æSŸùs礦¤ÐN{vïÒ¡©9LÝÅÉé$'dÐ{Ð_ªŽìùóçn®Ú#F€À›<-ÌLÃBB˜>¡ÁÁ–æf4)G{($E¥¹pù3m¼žÞ·ß~+²„À#†Ç’… ™÷ò?Þ¾=Zkäƒ:®T€vCà?“<ÿW…ó ¢¦{oݼi¸y”P}ðàÍûí7V®ÿŽçÐnݺ5aÜXä%yÑÕ%ê‘Ù$‘~J€$É677´œC®_¿~éÒ%à>ø9DÎñ¸nÃáKÝÒÖº nl_6„‡ýùü‘½«µ¡Éº—­Ï]lmímE¬¶ÙØÙ;ƒãES«‹«×tquv¶³±fàúïx * œjäåyá­“YW;”C ÷”¡‰IÎ!2L PìsÊ*À!ð òÞ{ï!‡È3?D6ôa¡Ï[š|Ùúèeë“GOÿ|Þôäek iãO5µ·xØàè‘#dšÄjý•ÇŽev:à¸ví*qÃéeÝÕ’)Z#4%yÁ옾«G“…zų çŠõÞô’ý>ÿŒ&uãúuâ†4i.\þLد¯HžÔÔØD6çΚy6!Ü×ëŽE¢tP©êëêÆëéݺySì™äù×DX8¯¦¦&Z`‘ççáÀë¿ã94äe㜘ݙFº*©¿TY˜s®[pˆ S$Ÿ§*Õs°k×®)ís±ç\dÊÏ!2C˜É«§ím°ÑøÑÒúð·?|Ùúìeë‹?üòèÉã6iqquWS{ƒ§G{þüùh­‘‰gà— ³39„ö¶à€Ž[¸« Y²p¡Téð'Ë4àž‘ˆK @R4.Ös&AÑyª£…™)Æ™•™ñåÄ ÍÍÍf&&ûcc;®T‹‹õÆè\ª®–äLòük" ,r<â²öÖÔÔ¬X¶TC}(9ô"óDþw<‡8”‚‚‚"Ì!!™I ɧ—äç*?‡È0%@’dážHÚIªp¤ä½]eà¸#»*‘|»œCä0/ï–ç/~üá6ü÷ff&f–FÞ~®ðÏßþé»Àà7WWw·Wã!-°©ÖKŸ vGDÀ­1Àç‡È @þù rއ@g*<8AþñcÃ-q§N‰Š µtú”¯|½½ÇéêÒ2 /UrR¢Ž¶Vmmäg’ë_Y`‘óC¶Z˜³öÂwúôü¿Ìš óxÈéS'éàrrrsóBV]]¶¡¦JÉ9D†)÷¾ y.Ó»woEqñ”½1:´—üLrù ˜î}òäI}]‡›+ó}ºwÔÈ™éÏŸ?ÿî»ï 7oæ®ÿŽç„Cõ ωC$QßÏþ#‰CT€C˜BôËO?*3‡È0% £9Dæñˆîââ"¼ŽÙµk×:C”aÔÉÁ¼§$'OŸ:¥ŸÏuuF;ØÛÁ³T½ç³gÏÜ\œÉ;àà_¶WPE/_^³JÈÀ èã.3(â:ØÙBñ ;¶‡Ñ \þLƒ™ <’š’2é‹ñ¬•‡X*á%V=z$‡˜®2tÐÀÓ¦úùøÜ»{W8nÎùó_Nœ.Ú+Ì!\ÿס € ×1“’C$y°‹¢ã!þþ›px¥å¦tÐs0ò¾Ì?ÿùOÙ8¤®®ÎÕÕõ¿ÿû¿k¸ !JGsH¯^½º;‡¸89{{zùùøZYY9ÌIXð@Í‘ùÊ#ϪoPuÆëéIî¶kçÎukV‹Myãúu‰g:­Tò›<Vì§·ÓÖu‡Þyñ‚ù 5Õ,Oä.é.k÷©0‡t¯÷ed˜ ñè»…=ëëëeq~Ý:ŸC>ùäøÞ.œüÞ½{ÿío{÷Ýw{q„ßwÞyN¦ sˆ‡»Û;wnÿðÃÊåË<=ÜÅúKe---G™>å+ú&¬2”ª# Üq„œ&‡¬_½*Ð×GU9äô©“ çâPòµûC”„Cd˜ I²Ïž=“a<8äý÷ß—Cèá³P„NXíP~Y8¤sL*‘s w™£ÇDG뎥5BÓÞÖ†ù.—¿´g`œ®nMM´å/•l'DæËo 9árrHùÅ¢ cõ²ÒR„9ä\zêêË5‡©2Xù²’Â| ØßOOg4Ü›Oúb|܉cáa!ãõtè?sÚTšTCMµ«“ƒÞèQêC7oÜPUVÒÉbµÕ²ƒ8¤U¹×îãY^OäB‹’,Àˆ"ËxˆôS:n~á™ÇCš››YríÚµNQù!hh=Ǥâø=yôðô)“k«*Y2yâ„G_ª(+¿Xlnbd´É€X¶xáùÌ @ wg'õÁƒV,]œ“Õ¾9wÖLÌ×Ó}ÁÜ9¹ç2ËŠ 7®[ceaÞ™BC:šC”pí>žåõD.´(vÆ.çI–`UB‘aJ€$ÉÞ¿_¹~ýº<"<Â|e9 Mf¬ú¸ÕÒÎÚŠç¹LEI±Ž¶ Px¡}é†êòRØ,Êûksð€þÄ=aÜØ¬ôTâ.ο ;zTGsHLTy¡‰9ÒA¢äk÷1µ¼žÈ…ù`ìr‘|!Ve[×$픀Ž‘“Cx¦ˆHË!Λ««+qÀ DACSa©­ª˜öÕä¸ǘž‰gâÌ™­¡>”¼÷Ú¿Ïç"A…k€„ùÚ,ô¿Í!K/‚þÔÃÍuØÁ¬/*|žª’¯Ýdz¼žÈUõÄ.ÀØåã!’˜´òàÁyŸïÂ9Q­üÞ.°¨0ŠØÛÛóLU•œC ~ø!ü~üñÇ|ðÏ~ûí· ¤A°7ß|9 M…9”‘š|(~©¤„C>úè#±ÃµŽ™ƒƒy‰CxWcc#pH'ãrš*qÈßÇkÓ†uÔS{„fläÞšÊòœ¬ŒÕ+–KË!þÞ^ çÍÉLM®­ªHKJ\»J¿s懊ÄDEu2‡´*ÙÚ}<Ëë‰\h‘Ë9D9'ÄNVù€Còç&pnŸ={Ƶ÷ïÿ;ršÌÒPS½xÁ|êy(6zÂX½ýúŒ¥àã--‡@j î¬õï7yâ±QûTcý®,”jí>žåõD.´È墜"-Þÿý÷Þ{db 8>ùä²Imÿ·Þz‹ø“"’$Îó¬~?ýôS² èÝ»÷G}D³CACCÃõT;ŽCx¬[¬Ý'ÉÚÂ]nÈ!(ãyfD?xð;54äü¾ ÿ ïFk÷!‡ Cd¶û÷ïËÌ!jjN­‚+ ÔM'ÉEÞÌÂN 9¿·+¶sï.k÷!‡ Cd¶Y3¦Ë†"„CÒÆ!ÔŸºYøqùòeÁã³Ë—‘CÐ:âÆS¤E„‡+p™näNæ4äTOྟýG6‘s¥¼&¨FGßù¥’¼x?¼FqërrrJ™9$îô)PDΕ{ùGA;¹y*ðÛ`7®_ß²É@s˜zÿ>ŸÏ™935%¥ç èóÿŸúàÁ_OŸæïëCW£R öHþL\œÁúõÂuLæ/º"‡(œCðuò—ee¥§OœôÅøýúΟ;‡.OÔÒÒ¾cû8]] õ¡p°ÐWÅ~»z·á;D8Dñps…ð p0W¤ü<ôdž%®Ã,,(˜9c:¤9VwÌñcÇx<™ÇÈUà#‡ARÂÆÆF®?1$(ˆžI‘ãù—Y‘…gœRæêßòÑ9¥JBA)Ûx\ùk) ‡lØðË/¿Mž/]®_»zèÚ"ÂÇd°~ýwß}G6éJÔpo»rù²ï¿ÿîÏ?ÿ„ÎÑËÃø+öÛd-òÀ¡SÖ_±ü§6[¾t sÅEIÊÏóAOæYâ:Lè^ÓRS% «µµ¶æñ¤ÇÂSàM7þðÃ÷PÂía¡‹Ìçú!Yz&¹ ÆŠÅó/³" Ï´Aýû1߉ÿ‹®È!(äääš"-„tÎüpÜþᑉ°¾tù믿7ô;°yçκ qOž4ñæÄ}÷¦g@ß¬Ô¨Aú¥‰ÆÆFæ($)?Ï=™g‰ë0uuFïýéÇ™EéÉlÒãssrx<™Ç(UEއŒÖÉ_0V,±ÿ2uˆ,<ë¹ sžü_tEA!‡ ‡ ‡(ÜdƒNãæ&Ï—.%éÇ¡¯9gR±ßî475Ùµs§´ã!r×=™á¹“ËùìlJY"=%‘CB‚‚¶Z˜óŒLk‘ü_få"òˆè<Õ¸S§ÄNp•ü‹®È!(äää…›lÒ%Âó¥KIúñ˜èhý˯_¿}Í•+WLŒŒˆ¿b¿ÝyëÖ-('$òÓO?AQ/UWÓ÷e n·üÁÒr×=™á¹ÓÔØ <¡×ÖÑÖâñd£T¦Ž'OžÔ×Õy¸¹2ß—á*ØHM ð”ü_¦‘…g½·»aÝZI^´‘ð‹®È!(äääå±Îçž/]JÒ·´´@¬É“&èÛî³23h~» zÕ͇ҿÏçsgýµ~Dqsq&¯Ÿ€ƒ>òœC¸>èÉ Ïu˜I‰gáì ì×wæŒéÅEE<ž4Ai L×:hàŒiSý||îݽ+¶`Q‘ûà\ÑDÄþËÔ!²ðLb"¥ü_tEQì{»¨.r 9¤û®§Úißî”sÝ 4j»vî\·fµØ`~Ñ9Dá똡u²áú!(ã²®{ç»9¤ÓLª/º"‡àzª¸ž*rrˆò؃äÄòîbò»9DiMª/º"‡ ‡ ‡ ‡ ‡ ¡¡u•!‡ ‡ ‡ ‡ ‡ ¡¡ukéûٺ˵Š*‰CCðÄ"‡ ¡¡!‡t‡ˆ='È!È!È!È!hhhJÈ!Yi)«V,Ó¦>°_ßéS&GíÙ…ÂÃ!ɧg&Ƴ€ø‹MªøÂy¿Ø} ‡ CÐÐC@ÙiZš>îyçÏÕT–'œ>µzÅrä~ÉJN(/.¤>åÅà# ‡dœ»˜—¿Ø} ‡ CÐÐC@Ö¬vsvä.s.=àDs˜ú°!ƒõ—/+)Ì'þÇœúå¤ÁúëŽÈã©bRV”.å,õwYQás)‰°—,OK8]© Ü WPÉgÁÍL°øÂù´øÓ©ñ§òÏe4ÔTóû#‡ ‡ CÐÐT†C´45r²2ø9dòÄ '޾TQV~±ØÜÄÈh“ñ5R3jïîšÊò¼óç 6òxª‡F6ÏT•^GeI1¸©ÅÅ"æS›¼¬túæ|ZriÁp”ä›™`vjRmUE¹ÙüþÈ!È!ÝZò¬è%\ CÐк;‡ èÛCòyª%Å:ÚZÄ Žïüœ×úG‘žªÇ!%ùrÒSÚè"©¤.ès™¬ä³emCF5eé q mƒ!fiñ§È˜ü‚|h‚—*J‰ûRyiÆÙ3üþÈ!ŠåÙš˜„S—e²ææf OQÇ•œ©ÿgÒrˆlky‘uÑ‘CÐÐzàxH♸sfk¨%o¿öïóy{G™pfå²¥šÃÔÇëéÚÃã©z"`‰„ÓÀðKè‚rHyq!ÉÍL½˜—C< ÎgA¦À‡&HŸ¹€#%î¿?rˆÂ9ä²”FzR 9Dò~öwÞ!É9¤ãJÎâšB}}=ý%&‡ÈpYCACSÕù!.Îü2NW'b{hiQAý¥*øeuèÐEŒ‰Ö¡)ÖS•8„¼ül@»0ç©f&Åf¤Ÿc€Ô¾a ¼6îQÁ1Rã!ݘCr¤4©8dRk«[këºÖVݧOó¿ÿ¾ø§Ÿ&µmªµI£ª ¤öêåç024Ñ™Òþ½!ä44UäìŒ4 _/üœlèÏÆ‰x_ÄFî…½9Y°—ú¯[­Ÿ‘š\[UÈ1jäO•ä–˜þeEù°Iž×´OIOf…o›.’G"žOkŸŽÂœs4A‘þÈ!Ý—Còóó©;·ÍäçÏ[[ÞÔoÄNð< ÿÔ/'8r˜Ç³çqˆàÑ }ª’•œÀ|AæÕã›Â¬ä³¬÷bò8Þ—ÉÃ÷e:‹CèTæ?k@©ÆC ‡kù,>ЧST(¢QY™S5…p{Zrš"8D¤lë©æ¤'—æKX°ÁõC:‡CXàÁüU‡I ÄÝ«W/â`…‘ö¹Œã)Ìœ9sÈ«%¡mc€@æVVNRÄsÑ3TåæÖ'eé9g…AACCÁïËH¨’ü ™Iñ’‡GQf†Ù8$//Éo¿ý6sóÃ?”ç¹L;‡ìßÿ?ƒ}öÊÀ >àÿIkëç Â2y8䯷`ÚÎ6Åp°‚!‡ ¡!‡ôXIÅ!égãªËJCpüª$Òq%ïœ÷v¥CACCA¡TŽCÔd5IJÞ,«I’x‡–œ•ÑGÜ&m‚À!—e5ä44äJÅ8Õù32k9 9…BAu­CÐÐCP(ärZÏäèqPª*ärrH·Xd Mõ¬µ³ÖA!‡ ¡¡!‡ÈÉ!ø«˜uæzª(ä444ää4ärrrr 9 M%9¤ïgÿAACA!‡ ¡!‡t-‡(HCCCCCÐк/‡°Ô­ÇC>û¿ǃüý|'}1~Pÿ~êC 6l(,( Á×®^5tÐ@8®\¹Âu&¿ûî» ëÖ:Øä÷‡0EÓ¹ÿ¾•¥…æ0õ‘ÃÃBBxþ;á¸<É"‡ ‡ ‡ ‡ ¡uwQ¥ç2´^­¿ÒÞÖæÖ­[/^¼øí޽䤤¥‹‘]ß|óÍHM¨È}wÚ,:26ÁSä™\0onP@Àý6 ð÷ƒM~.Hضu«©±ñÝ»w@&F†§Nžàÿ…9ÇCCPÈ!hh=‡CÀ?$ÀOwô¨ÁúÏœ65=9‘ø×UW:ÚÙŒ¥=|èwâYSYnif¢¥©lÿÚª 3#CÍaêàïåî*ü\†+HÁÄpK{D7W€áâAýû=xð@äɱ03eH„[𛉠{ôð!q?|ø6ùý¹€aÄða÷îÞ%n@‘Å  ‡ ‡ CÐÐCx8då²¥¹ÙYUe%.Žö³gLoïœçÍžu>3£¬¸p«¹)ñ2Y8oN~N6hþœYNv¶í=··ÿ‚ÜóÄ_$‡ˆÌÅÑÖféÂ…r@‹æÏ“CÖ®^ebdX^VöôéSÖÉÑ1âÛo¿eúÀ樑#DžI£-›Riîß¿›üþP€‘ÃK¦}596&¦¹¹™rÈo÷î7 Pœ´"2Yääää4´îÎ!"燀£(/—¸«ËK¡$îqºcè¨ÕØ1:©ÉÄ {Çéê¼ üš¿H™ $˜•–BÜ‚ òðრ Ó¦ì×÷‹±z>^^txR{öìót«ôûü3‘gò矫;†ÌÊÇ/¿üÂïOìùóç555‹Ì÷pw#>[-Ì-ÌL@@æ¦&\Ùñ€'‹‚‚‚‚†¦ªã!"7.U”±3=ÁAq‚å/’C¸r¡w˜%çj/_¾¼zõªÕVËõk×­š<ã!¬¹ ú+–øûÑy °ÉïÏ´oߦãüñà‡†úPí#"Âù²“äA 3Yääää4´Å!ãõteÉHI’œCäaÐÂÐÁƒˆÛÌÄDx~ˆ…™©Èˆƒú÷9„ËŸi?ýôP‡°ÿ¡ƒ€IdáO9999 Må9ÄÝÙiÞìY9Y¯Íq°±¦óCÌ™íhkCç,š?¯ ÷<HÎ! ²xÁ|8déâEÉIIwïÞijjúþûïìíÖ®^Evݼqc¤ÆðèÈȿޗÑ~ëæM‘grÁ¼¹ÁdÜ#0ÀÑ‚ùüþ¦ÆÆ/^¼¸~ýšþŠån.ÎÄ8ø'%žÕÕ eŠC¸’EAAAACëîÂ5?D$!ÔVUÚÛlÓÑÖÒPêëåAX˜“÷eÀAŸÅ×^ ¤–Æp®÷eDæ)oÙD"º:: ì×GZ)*,Ül°Rدïx=='§?þøƒ»rùòšUúC­Ö_y¹¡ëLÞºu B2$Cèpù§$'OŸ:e@ß>Æ  QNž8'mð€þ«V¬¨¯«ã'á¥B¸’EAAAACëÖ¢üJK:«§3×SíQ†‚BACCéZm57-Ê˽µ`î+s3ääärrH§ÉßÛKG[KKc¸ÑæMÕå¥È!È!È!(ä44äerrrrrrrr 9 ­gr^UOÈ!(ä44änÁ!øw«ð¨r 9 9…êZuwQk3I} ©µ´´€ûîÝ»ÍÍÍà&‘mž*Ó!çCÂ!·^·å‚TÊ!Ä9 9…RùñÒjZ8ŒPàG}}ý»ï¾[]]¦«Öt ‡|RŠpqÉ9 9…ê9ÂeMMM$Œ ÿ}ë­·ß~ÛÙÙ¹W¯^=C~€¨LáÂüè“/ä44äJå9ˆ‚¿5µ´´|øá‡ô í+;h©äJ;™C€:>þøcÂ!tTLQÂtP,AACCA¡T›Cz÷îÍÿ\Œv‘ï½÷Þ§Ÿ~jbbòÁH j²š$ÇÛ™BC;K„Å!,AACC‘\}?ûTþ¨ž ø÷%Q×rÈûï¿ÿäÉ“—/_ò4(¸ë‡ßÊÊJH677wÛ¶mKBáJ“‡'$ä‘ÖÂb¦äyDÅœ" !È!hhÈ!È!(9k…غÚåB:>~0ööö^^^žžžþþþ>—iÙxe‚§-¯ á®áÅrá 0.QÔ²ÁõCÐÐÐdàî;‚Ò}9äô©“JÂ!ú> éd¥}z"!‡tÚBîü"Ïp¿CÐÐz&‡€H€ŸîèQƒôŸ9mjzr"ñ?—žºzÅrÍaêÆ Ö_¾¬¤0Ÿ†÷rsÕÒ»Ìj«*Xé7ÔT»:9襡>tóÆ Ue%™ÖT–›n´45 5þ¸¬1á!‘± ýðÐ`šãŽ`ðá:~øàÔ/'Áy€³È@<çA¤?²¥™ /°IÃûzyèhkõûü3ùG«”CB¬¶Zöá1åçºTˆÈïË"òá ‡ ¡©0‡¬\¶47; ºoGûÙ3¦ÿÉ'œ8røREYùÅbs#£M4üÂys rσÀáì`ÇJß×Ó}ÁÜ9¹ç2ËŠ 7®[cea.œ©£­ÍÒ… /ä€ÍŸ'6.ÿxˆÈXsg}½ow„ ÛÚµܵU•ü£FjFíÝ „wþœ¡ÁF±ÂuDú;ÚÙÀf~N6hþœYNv¶ÿ¥Kà<¨Þx@ é rK&Syûí·É´Öꯊ%"CÐÐTu~8Šòr‰»º¼tð€þÂW€Š’b¸a§á3R“‰;#%iœ®«0nlVz*qç_Ð=J8Á±ct²ÒRÚIM—ŸC¸b[Og´Ý6+ø·ØŽŽ1ÀÇ8A’GB<çA¤?2õOONd†¿¥2Ïeb¢¢~øá{ÖHHOàyZ1ÎsFACëáã!"7ÏÄ-˜3[C}(–þ}>§.U”78(·Ðˆàä~Ÿ&œ)„¡& ±qù9„'G';[ðññp—¤£ON8³rÙRÍaêãõtíË!\çA¤?8¸Â7ÔT« ‡,]¼è³ÿû—‡›ë°!ƒ ôA!‡ ¡!‡(œCà†=b{hiQAý¥*ø=š,bì-]¸`è  p¤%%ª<‡ÀY¥§ËÏËS…9ÄÙÙùÙ³gOŸ>½uëa7ß|Üÿüç? ß{ï½¼¼¼GÁÑ=~ü˜4Þ€€€ßÿ½Ë9DMVZœCÔÔ¼¹Ää‚7È!hh=„C.U”Y˜“÷eÀAŸÅÐ÷e4Ô‡šm¡ïÑ(3‡LŸ2ù@t$õ‰Ü >bQaþœY1ûöÀ={eéEG{€1±ÅùÅçó™é#5†ûzºåå‚|½<`‹€ÄùÌŒ×GH2´Gh¶'ek³tá‚ 9 EóçÑ\¸ü‘CääJ ¬[râ#ÃØÙÙAÄëׯ~Ô××óÍ7ÕÕÕÌÁ`Ë—/—••¨ÔÕÕyzz¶´´(-‡ð †ÈÀ!’Œ‡àÖ¤h.\þÈ!òp«óe ŒÈ†"LáléLùŸÿùŸn4Bó9³9 9¤kLÄrÈÃÕy@ß>ž®.,IÞD:h`LJ¬_½Jx~ȆµkTx<„¼±Ë”ðÛ»]Î!Ì! År×`‹b9¤¾¾ž8h. ~VB^fé ù!8‚†Öc9DÚÞMi9„ËŸëMdƒuk3S“k«*ós²ÍMŒ¤Âõâ³He¥§Ž>Ì×˃¾/›çÒSiRtÈâói.\þÝ‚Cèâ!\¢’"Ñ`KŒ‡@°ïÛì“O>Qàsa‘ŠCxÇ ÇCÐÐps)-éì’…óÉú!©‰ ̤Œ·l‚âA!]öëÃïß]žËäfg :N `IOx.#ätÌsšå?üPþç2,‘CxŸÈ´sއ ¡!‡tSé¦3oypEOg´äþJ>?$ålÂÜY3EBˆJÎSíBé¸yªLÁñ4448dœ®NFJqï e½9Â7 ðÓ=jð€þ3§MMOn_𳶪ÂÌȰ} ÷×V·^@ƒ?/ä.m57-Ê˽µ`î+s3±þ8OUN!]*«ÿU,‡tÚs2çD˜Cþñ(ùû28? ­‡pPD°¿8òs²Õª,½î _sc#‡¬\¶47;«ª¬ÄÅÑž® æloGÖß eüµº…¨4øóR~‘s w™£û{{éhkii 7Ú¼©º¼T¬?rˆœë˜1ÙƒÉ$²N˜§Jç’úúzV[[«lïíŠ5\? Mµ9dTäÚUúàðtu©1<,8ÜkõW’µÐ™·ÞÄ ]}U0ÄÁx1„ù6‡ð #üyáwîzÚ÷v•–C„WM—k8këVH¡¤¤€°… _*¸»»K’iSS“Hä¸üº©Æú!´È!hh*Æ!Ue%cFiƒcòÄ/ÆDÏš1MЮGiƒ?‹CD#°Êàò'ÜŸrˆJJæ~\e¾sGÆC®]»v¥Í¸[jjjȺî—.]rqqyþü¹$çÖYV{÷Ýweã±_ÚÅïË ¡¡IÅ! y³gíÛ1cêpÃolÔ¾ùsf ¿W"’C˜ã!)Iüã!üy!‡ T’CÈxÈ÷ßÏ£`6Õºº:€ÆÆÆo¿ýöêÕ«yyyއ®ùÓO?íի׿þõ/pƒƒë¸ï½÷uÿío{ÿý÷eàÎüÞ.‹Cð{»hh*Ì!ž®.£µFø>ãåï#˜ràåæ*!‡8ÚÙÐõ7ΛÃ\ÝBäêC—,œ(6Á…‚BACë’‘¦¥©áãážwþ\MeyÂéS«W,ï¸Þ¼ ÷¼îèQÛ,Í3S“/U”•ˆ‰Z¼`>r 9…‚†Ö9dÚÕnÎŽ"w–X𙥀À›Ä¿¶ªÂÌÈPs˜:ø{¹»ÒÞ¼¡¦ÚÕÉAoô( õ¡›7n¨*+Ns‹Á;k+®Âp¥Y„øÀ Ðæ´©éɉbÃûzyèhkõûü3Ø<—ž p6d°þòe%…ù$  K¸œ«(ärrˆl]mNV†È]Žv6 çÍÉÏÉÍŸ3ËÉΖø;ÛÛAîyâO»o_O÷sçäžË,+.ܸn•…¹pš£Fjp†+Èbå²¥¹ÙY@.Žö³gL~é’ 9dsòÄ '޾TQV~±ØÜÄÈh“ÈñºÉuà\Å@!‡ CÐÐCdã}û@-rר1:©ÉÄ ÷þãtuˆLÚ}O76ëcç_Ð=Jlv¬ ® @Q^.qW——Ð_lø Ù¢û Š’bm-~á:p®b CPÈ!hhÈ!’p\±©È^žñèg)3€ƒv»,Ú}ƒ?óay&Â’öã!bSàžð 5Õ4|♸sfk¨%Áú÷ù\l²"\dx8Ì³Š’A¬ŠŠ‚BACSa¡±èüg™ÇC2R’þÍ«—›-æÊ¿iÃ:»mV\•0H ±=´´¨ þRüÒ½,R’d±hþ¼‚Üó @»co/ØÌLM®­ªHKJ\»J_ø2r!;kÔÈô}™²âÂ1QbSà ÃÃÆFî…£ËÉÊ€££{Gj Ï|ÅÌX\ÎU ”} ‰´´ñin3{{{À%ä.‘ Ep< 9D9yôðê•+ÈçW†«µ¶´»B{GHª•ÁâO¯§‹k‹!‡HÅ! ì¹oaÂÀà(.(f 8D9ÇCÈ!8‚††ÂuÍ/¿X4oö¬e‹eefÜ¿öþðÃq§OÕãçåÙ 8!sÄÙ_ψٷ‡99D*!c|nww¤á½PwSSÁ`ÚÛéÕ«â òއüÿíyTW¾ÇÝcÔÉdΙ?Þ9yç©"‚4ʾ(¸¡FADÄ·à¢b³ â†{·M\òtó "«È"›ì‹´àŒ’™d’̼ɛ‰™1QÞOËÜôtwUW/ÐÐýýžïáܾuëÞªê~êwï­‚ ¨ÇrÈÔIžQ‘Êu“ÌðšzèÀ>¾ËKMe…tã†ñ®.–æk«à€ùÎéÎxȘіMu5úB ¢#‡KsȰaÃX<äÕW_)**:|ø0•Ü´iSÜ I¥ÒEGG§¤¤PbãÆï¾ûnuu5â!õLI?x`yØR¾j EÜœø./þ~sÂW®(ÈÍn®¯­,-9q4}ö¬™ÝÉ!* ƒCÀ!ú—y'T‹ ƒV—‘”‘Ïa#2D‡ :T¸ò¯¿þú‡~xöì×%Ø$eÑ&n¹ñ“'Oþþ÷¿Ó¾º<ÇL%„ün˜Ø$ÄC "pÍ'Ìèèèª9%™ïòbia^SY!L”Ø—¶ÓÅÑ Ïœæ•“™q[îMy¶c¬íl%©[’”GUdM Iñ±®Žk«•ËÂê«o*7Á¬r\Fm °ÉrˆúˆVñ!C†<~üXáv^þfŸÒýû÷W9?„ö5ø¸ £‘ßõ9"ïA!dÐo4˜Í‚xC®ùÔk לŸ—Ëwy ˜ë·8$øÒ.°×ѪäàÀ€¢‚|€ĸïÓ¹ü¸ÍÑ´{Yq!yÞ_eŠØ±5Ùo¶Oѵ¼êвeKmˆŒ}hW Ñûü²à»ÁQ¥žópe!ëø3ÄC ¢5‡ÐÔ”‰ž*//µ7+â¤Ñ´ÕÒÂÜÍÙiÓúH‘§‚ò’".ÝPSE%Y&?û*—ÎÍÊT¦w·üœ,.]q£ØÅÑASSŒq]úD0`èСT¬¯VêÉ"$Z<×ñ‡tE<ä׈qSCîÕ++–úÏ^½Â>°)¦µÕÊå©€üȋوášrˆ˜`ÄCĤErˆÑ¾ BMe…tã†ñ®.–æk«à€ùÎé-Ýñ˜Ñ–Mu5ºÔ£²p8‡@8D<‡¤<°{ÖÌÞÒ«ÜE£zzBW‡€CÀ!Ô«9„0£££ƒ«DÖÒâæâ<ü?ßXökÍ)É|K óšÊ •›dM Iñ±®Žk«•ËÂê«o²î/uK’ÄÆvŒuÄêp.ÿZNVè‚ Ê3Ú2$(ðfÙ V~GjŠ“½Ùˆá|Ÿ9-œ…[—ï…åwQ—Ñ´†¦ºšõëÖØÙJÈ”`q…ãóñ}·êâ¤ÑÎö6V£·ÿòK¡ú÷¥ítqt ßÅÌi^9™Ê¿ ¾…›»pîŒ×¤‰T-U~`ïnLp  Hk¡þˆUB=Ag–™Ÿ—ËwA˜ë·8$øÒ.4ÖV+lÚ±5Ùo¶Oѵ¼êвeKmˆŒ`ÍÍõõ)-ºN¦DB¬”ËŸìéqñü9ª‡À&bMxøŠå¬|pÀü²âBµÅÄ´ÎPæMk ŽžNçFayŽÏ¬xéf•Ç/æ ùÎqKBœ¯÷¬ëy¹T>*bí¯õäÆ$ÆÅxϘ®ÜߎÂÍ9Œ³=yü(UÉõkï,_& Á!é…C„gLóz$‘ɦLôTyA¨½YAý/m¥d7g§Më#YxÄÃÝ-?'‹KWÜ(¦ÛgÖ\nV&—νzÅÝÅIeµNöv¬|1ϲ…bò›øZÏ!šÖ@§ÏÎ+'3ƒ—Àñ‹iBþÝ]œ•ÃTyI—n¨©¢_„r%|; 7G‰´íÛ«ä ¨Ì‡Àà‚ ‘b ¨X¶$Ð.²‘¹`£”fÁJ°~3ãÓK~>Þk+®¼ùȬýf½&M¼xþœ@foä>¿H¿]dÝƇ@irHw>OµG=¶6Ùç‡<ïõ;;¹®?>6^ÁºpÈZisUe¥øb8$^[C êÉÒï—‡ÀÆéjÑ4ÆB_c{{»˜ƒÿçã;ú¹óÙÏ?ÿüäYçSò·ùŽvÿñÿw>í|îgÏ/5ýë_Ÿgþø#wåyüøq7GrÀ!d¬Òßÿ ƒCô;?¤+zOª“èB;‹çÛšH<‡<ýדö¶»woËZ[e -¾üâÑWMÍ-m·ïjn½E(²>:êá£/o5µüùÑŸÿø ccÔ&B:::îÞ½ÝÖÖ¶iÓ&1G®ÝeMeÍà‡À°qpˆÜàE½Ì1‡tìßO~pႎòyë/îß+--ùæ¿}ðåÄ!¾xô§/¿j¸ÙÐñùÃm[·P÷îÝ#Ù¸q£L&KMMÉ!írz>eE^ž,8‚À!0l ¡|µîiñn—!ü ‚aþÁÖöna¡–òÓÏ÷d­÷ÛZ<ø¼°´¨½ãAtÜfâÏïµßk¹×X]½qóÇ+++ÛÚÚª««÷ìÙÓÚÚJ4"> p8î-"~*¦îóCô5á›ã!„~p‘ŽIE´Ž‡<ºßþìÉ¿:;Ÿ>éüéïÿüÇÏOÿñÔµ:jßÎ=±Ò¸û÷罹¦îرC*•®[·îîÝ»111âã!tü, SæîiVæÌO.ˆ´9DÇØH÷sˆÂp ‡%ZsH]eUç³§_|ÑÞrGö諎û?o»sï«?~šÚ\Ûx»¥õþ UUUÉd²ï¾û®¶¶vçΚŽË¼\J  Så|WPÏ”a9Dn²ˆösE »^æûéÓu‰‡ýûªR¿~ý0.A8‡˜Úü¦ï/VŽ„hÊ!œÿß÷­­²„”Äí»wHbÒvïm•µm‰ÙòjÿWtùf0.Aà‡tC<Ä ã2\0¤cÿ~Ý9äé¿þùÍ7_þ¨½þVCÓífÙí¶o¾þ6:"z@Ÿ~:rÆe Ãஞbxȃ BFd´ãΟº{·-bcä®}iÉÛSbã¾ûæ/Ä!à Ñ=‚q‡À08D`,¦—ÎÑc<¤óÙÓû÷ï>üÓ£FYÓý‡Ÿßn½ó篾Ù¹yèÀW1.A8‡t)‡ôÒ÷Ë|-•Šèøysøáâ›2‡Àà‚À!0 Á!á|-'+tAíë1£-C‚o–Ý`…÷¥ítqt°´0Ÿ9Í+'3ƒËoª«YóÎ**og+IÝ’ÄêT¨œ}䫟¯YSCR|¬«£ƒÄÚjå²°ú꛸ ƒCÀ!àp+‡Löô¸xþ\cmuMeEÄšððËYáàÀ€¢‚|"ĸïÓ¹ü¸ÍÑsýÊŠ Éóæøªå¾úùêÙ±5Ùo¶Oѵ¼êвeKmˆŒÀ‡€C ÈÆejoV8ÙÛ±Âå%E\º¡¦ÊÒœK»9;åg_åÒ¹Y™j9„¯~¾z<ÜÝòs²¸tÅbG\Á!àp8‚z‡Ð›™Ûª’ 2>½äçã-±¶¢­dó‘#„¹‚€¤©®†K7ÖV«å¾úùê¡|®$g³ù‡EËŸÜ{­ð‡ Á!dÄÂöˆQ¸»8¥Ü_U^ÚÒXO?Õr_ƒø¡¡¦ŠK——±|¾úyã!n®Eù*ß[õvC`p™‡¨+±k{ú½ãMu5…ù¹¡ ‚ÔrHlô&6¯ÃßoË÷ž1=1.¦¾úfѵ¼þ,Ÿ¯~¾zvmKëë“—•Ù\_›}%cñÂ\ÆàA&Î! ¦Ì³§ß÷ps}Ël¤³ƒ}Úömj9¤±¶zõªk+;‰MR\,íÈåçdfÌœæeiaîâè°w×NVž¯~¾zdM TÌÃÝm”¹ÙdÏ §OžÀ‡€C È8Dïξò™«“cÏ©‡Àà‚ŒžC¢"Ö–—äûÍöÙ±ÎàõÀàp8‚ Óá]ÛRìíì$6á+W°¹©¬‡€CÀ!™à¸ ƒC`pCÀ!08_/8‚ p ƒC`pCÀ!08‡@ap  pó>:¼€{Ž™µÕ¦õ‘*Ÿ£Þ‹ÜÃϨûOí Á!08‚ îçšÊr_ïYþóòór¿ÿþ{ÚÚÑÑqé“Ý\œw¦níW*ýž‘Þ»oC}áàAPä©“<£"#”ë¤.r†×ÔCö \ò³¯.\h;Æú-³7§O|òØ-º?½÷ZŸQ÷ôÔºg;[Éò¥KªÊKÁ!àp8‚z5‡¤<°]dpÑ区¡§ÖËá•]_² lQ(8‡@P¯æêõ:::„jNIæ» P?¸%!N÷îO¿ý£.g¤òHXæ…sg¼&MäÞÙw`ïn¶5uK’ÄÆvŒuÄêðæúÚî9¼ŠÒj‘KËš’âc]$ÖV+—…ÕWßdåw¤¦8ÙÛ™éíÖúâð·¿ýí·¿ý­.•Ów+¼AÖB}“pÍùy¹|;[Ia~nOã]ÎH˜CÆÙž<~´©®¦äúµw–/c[çúú”]'S"!VÚ=‡'Ï!;¶&ûÍö)º–W]Q¶lÉ¢ ‘¬|pÀü²âBÄCŒƒCÚ~ѵ©R\\\ÿþýÅW® øøøAƒñ ­C† ‡@Ôu"“ɦLôTyA°xsdcmµðLe‹,Ðu"pFÂâdo—¶}ÛÂ…­¹Y™\:÷êw§n8¹QìâèÀÊË­Á‡ ‡«µµUCúöí« ‡pñ­à‚é†xHæåOƒlÇXwu9ûÁ)¶•Á%,-Ì»ôð^ÎS•Ø„-^TYZÂåS£ò ÇÂpåeM àSãåxȰaÃtáßÿþ÷ˆ‡@Ô3燤$&˜Îü6ãÌ©÷íÇÚªˆ‡deª‡èýðžÇCÜ\U>{D¡<8Äd9DmÈñ‚ Å!:®—¡îxGjÊ‚¦ºšÏ.çz–¹$4„H£¹¾–8ÄaÜX¶uÞ_n~%⥛»9Ï®m©s}}ò^[ö•ŒÅ CÀ!FÉ!qÚJ-*üôÓO\ÉxUâ8$žG¯½ö8‚ C=?„ú¾ @«Ñ/ž2Åž¢y"À!ZÜ¿‹ß¥µµuñâÅTþÕW_¥DCCƒüDz²2ùW¯^ ýúõ£‡ B?ûòhРA\¦~/Dù•0€¯NªdèСô“Ê z!.“Ëá¶‚C ÂóT uFZtîÆ÷…÷:9t覢Ñ.Tþ7Þù±Ö튗ÖíBÔ¥‚÷ËäaéÆ÷…÷FèCå7õÑz~ÈÀu™òúë¯ ÌQ[98‚À!b86²—¶€CÔr7¸ Àl«‰sæ©BÁ!úå>¢¥‡(Ȱ¢ãz™þýûƒC ‡Àஈ‡â‘üÖ®‹‡<}ú444´‡sˆp`°>Œ7ÄO/Ñ=4ßÿü‡§ìIۡܨ¬©áz^®÷Û3N8†x8‡@¤Çù!þóÈ¢Ök:?DÞÔSOöœµÞÕÑ¡¹¾–Ë41\ ‡ÄCDrˆŽóCŽ:èï7‡; ‚ çϪl´äú5û±¶uU•Üü”ÄtàAàƒ¬—Qѳ9L[îÛÃr¸ÉŸj9$6z›âçã·9ZSÑåŒ*nÛIlØ$XJPášÊr•†/Ø·{7üDL²#5…޹©®æ³KX/Á!éŽç‡ðm:yìÈxW—[ u,gÇÖd«ÑòëeTVÕX[¹v5·^†lŒF£e¿ZŸñCøŠåò9›7F- ]¨²ÑÎ|à5y—&Ä ¤|ñü)x~8‡@8Ä€ÏS šï,ý¡®Txž*8 ¨·pˆ~߯"kjØ¿;m²ç¶t×PÆûeÀ!àpA½…CôøâWG‡ŒO/á‚ ƒC`pCº™C`ƒC Á!àpAà‡Àà‡€C`p  ÈàÃ=ÍàA&Â!ø® ž)p  Sàîù‡Àà‡À08‡@Á!àAàïn¸·›»šC ý‘Cð­öR³‹8‚À!0 »Bè—  p ƒC`ƒ@8‚À!0  !à‡À086„€C ¢»ßþ_¸Àªýð-C!ÊÃ1à‡èÞÕšrËÎ]í—£¶¤‰pˆÈ¿|ÂpˆqCˆÈù!ô7ð¡L×áîáÊÒ;‰MS] Ë  `éÆÚêq*£÷;ýÞØ#k cÊLH8Q[ŒÃpˆqCˆxÏ®¸u…ô%ús¼íuÖè~°Ûâ!Áóß;z„KW•—š~³ì÷ñXú!ÚÚ8‡€CLBDrˆÈ¿LœƒõbîÏɸ9DüuXkqwqʽz…K>°ŸKPå¯ygÕ¡ý{YÉw÷í¥œÓïòŸÇå|xê$u‘œ|û8oŽ/m•ï7›ëk×…¿c;ÆÚÎV’šœÄò›êj¨ª—ù[~Í—55$ÅǺ::H¬­V. «¯¾ÉÕÆÌ»pîŒ×¤‰–æ.ŽTõ/·êâ¤ÑÎö6V£·§$³Fׯ[C-’)Á¢:TíÞ];]ß2{sâ„ñ—.þ÷¡ûÆ»ºPý3§yåg_eÅèPí$6tØ«ÃéÔ¸ük9Y¡ ‚(sÌhË @ŽÊ”Y>¡²¾q…ª|f¾}<ý0;Ó’ë×ÆÙ‚CÀ!F!àb¬Bœ@½0%nX[Žª«ª¤ôž];¸.rö¬·OMÞБÔn®¯#SÇWñbðEºq±Gô†õ”.-ºn?Ö–¶Ê÷¤ 1Ò¹¾>´‰*Ÿã3‹åÇmŽ˜ëWV\H¦XþŽ­É~³}Š®åUW”-[²hCd„Ê€ÀÉãG $¨~gù2½XBœ¯÷¬ëy¹TOTÄÚ—J£é`èH¸ƒ‰—nf•úϥ„=É ñô%,ð/Ìùqö¬™¬w.dJ$ÄJ¹üɞϟk¬­®©¬ˆX¾b¹Êc–§ •õÌ‘¯êü‡§=Ç»°qéô·&%‚CÀ!F?£5‡Ü(ȇÀà½pݤw‡|pò½Å C(AÝÙ8‰ ^XüáûÏ£7Š]‰7è'¥¹]Ö¯[³3u+woþ?_ôž1Ò)‰ ”¯Ðo>¶deréœÌ –ïæìÄâ T€å{¸»åçdqijÎÅÑAeŸîdo—¶}áÇ™šSȤF冎U^V\Ä¥jªècyɯ--ÌY1¶;/Rn·öf›ZQYH!OŸ:åèáw)Q›MÍÑA7‡L™è)"¯[1Ñh~ˆBåÅùÙt-ýË·ß‚C`pˆîB—_®÷בC¸ÿqδ•îúì_Ü×O8sêýY3¦=ÿOw°çÆDÈñÒÍÔ4Ý _ýìòÔI›ëk'yL t{ÞTWãáæJù ý&uâµÕl«|>QÈ—ïnÌF WÙg^þ480ÀvŒõxW—³œRþÛoWe&%äC`2†< ¨Ü=ãÓK~>Þk+î˜ÍGŽÐ®ñrúä ú¶[ë—†.$“¿t÷^+ü¡Ê÷)5•åò( b"¢‡´4Öå]¹¬|-‡Àà]8Dá"¬5‡°9®\ޝ÷¬GÓgxM¥4ý¤nnŽÏ,nSVÆeºã>u☣ݸëy9¬âý»Ó¸1‘•aK‰R¨§Pîsåã!tï¯>âæZT âEí Hä-kj p²«bvñ‰Fñ‘òë¹de²Ý)‘~pUy)ýdåŽYm=ø¡P8ActÔzWG6½¤WO8æ2ýUØXYÒBf„%à„M9¤ +C嵃Ctä2þÐ…Cäs¶&%fpwÖ»¶§x¤nI¢t}õMêï>þïžOI}ÿ=¯IÙüÎÔ­¶c¬¼{›Ýj5ê-ùXͯó@¤Ñóæø²¹,?6z›âï7‡åïÚ–JÅò²2©{;’Á ‘ÇIlò~é»ÉKBCr_”!q7Vùo#9!žàª0ÿßæ‡P£l~ˆŸwÜæhM9„ %Øô¡Óïoª«¡æB±ò Ǭ¶Q¨Š›®C[îÛc4ÿËÂÂEáfÏš)!à“‚M9¤¡æfÎåOÀ!08Dï"vЇÐÞâÍ‘Üs?*JK(•ñ|„eùÒ%ö¤±b;RSV. cyËl$7CƒîU)-ÿØ…u1k+;‰üzâ™Õ«VpùIq±´;»Ó'òpwenFtúä 6ÕÆj4Ûýxúa7WK sB£‹çÏ)ÿm4××ÅDo$ ¢&è°Y£‘kWsëe(Á˜J<‡pë\¨Îµá«Ø¸ÒÙÓïÓÁÐ)8;ØÓÁËϹ•?fµõpˆBUä“ÇŽŒwu¹ÕPg:‚yª&>£Åü;-·JòsÀ!08D0Ÿï~P1¬³¯|æêäØ{ŸbÍ÷?–~Șþ—Á!€®˜§Ú&»Uœ— Á!zá…™!½C¢"Ö–—äûÍöÙ±"Ò²¦†ý»Ó&{N`KwÁ!àã†]8äyTDvëǃC`pHÏy~Há]ÛžOD±“Ø„¯\Ñ+Vžö¡ÃputÈøô’‘ý/«ä1 mÀ!&!·ñ3ánä>¢1É!"ÙÕ–ºÃ=ÄFÏ!âïÁ!°1qýIkdµ‚·q¸_¥‡ô CȈ9D£ûA¯Â&rW"À!°Ñ˜C4eW†õk>©B¦#eáP6&s¿Vá.w0 ÐÜ¢‡à6ÍÿyÒÊÃpO°2‡À° þpB]lÄfB¿q†{Ž‡à«€MÖÔIÁÆmçµÇ›ïÜæ®x0 ÷sËñ=À¦ìÿ£Ìx endstream endobj 304 0 obj << /Length 1834 /Filter /FlateDecode >> stream xÚ¥XKsÛ8 ¾çWè¶ò´‘õ¶ÔËÎ$i;íöµM:Ý´Z¢m6²èŠTœüû R–lå¹ $A }géøÎÛ£“‹£é›Yîä^ž†©s±p’ÔKóÈ™åðÎEé\ºÛ›·)éä8L|wMê–T“Ÿï§o2ßÉ`g©q6ó2?¹zSì³Ìâ'JÔŽ£×G¿`ñ`§*ô²(qŠõÑåOß)aí½ã{qž9[͹v’À÷Â(ºrÎþ>òù~ÿYà¡—AÒ?Gœ{ [[x¡6Âîr.ß÷Ýï+"ÑÊSR#ñïV\ÞâèŒãwËäÊPè‘?Ñ úÎq˜yi”¡Òï“Øwq8oàÉ[-ˆ‚Ô¯†–)!±—ûæ~„a²ozžQÁ–Êä(uåŠ"±]ñÊo¿½C‚/ð *¤ÈfS±‚HÆõþÄeuQµ‚MÂĽž‰kD¶ÞXqÜì-¸ž¦œ(©øRÉæ»¥U5œYÓºEjNñR‘ì]( ÚÐZâê«K14|> }·•’×B9Â.N3ç8¼«Ûºxªô¼ãC·æ'Ž­N@˜XP"Û†–8ÿîìµáÀ‹À¡È 2è\œS\â5õ&ÇQkÿÕŠ¾úh˜ ¡Û +Õ’6?…‘éͪx’Ä5z.VFÇ’Öê:ít\*ð €/95÷®XíòjClì/¾6±ÏĦ"·S—ÄEC­¦.ù¼NÛ B8Gmï Ô‚ÜÀ¸"HC‘¨8¿Ò‚Õ@g¾^Æ‚§4¬p/‘Z“Û¹™<á†òWȦ-Œ`> stream xÚµYY“ã¶~Ÿ_Á7SU†àÍ}sìµË›lœxÆq¥vý‘ÄZФy¬FþõéF¼ÄÑΤì'Wßýur¬ƒåX?Üýíñîþû(±–„nh=î­ daâYQ¿·3ëƒ}~ú¡™ÜlÝÀ±O¢ìE±ùíñÝý÷±cÅp2ôð¤G,v< «y°=Ší{úñüæX¬½³æ'±uV;OVÀæz!|ÖÃÝ¿ï-¾3U#æwYÂy0ÕÃOÐVq)!Ì)ëÖ;ŽcÿX¶( ÑåUIzÍ,âX[7fn­#oéWl\Çþ¼q[ä…Øf¹¤_Ÿ~²|[ö²‘eGSµH?‰ƒÞÞ]jÙ¾™ËˆÜ=ÅšûG× –J CwÔ4ÚªoRÙΨëÑG'p´ß¢‰~ ¸ÍuÛØy½b7d¾ÃÍ&Qf+„xÈâ(u¢a‡?VhùœÅþ' Ÿk´å1øvlyÂ@²—)¾ï‹ÂX]ùS6Ú7ÚÔïó´©Új¯‡¿n|ÜšUè’ómñ0fq‘ul7 ýŸ·??üøÓ?iÐÊ®¯™|’+jó‚Ú nèí¾¯Ôz¡kµ×‘4„C¾EUê±Ìræ–eÜÀcn­Zæá›·¯5QäChÜ2‘©ÈW‰ß¶d)hðyÃ[U}RYÇGO5­²Nìe—eFƒsÞéë½lÒ¾ÉîÔ°jèW[¦,*ÐURÇ8Ð Œtê=¯§©NZ#BËO–ùú»Â-Øs캺}s¿Ë»ÂOŸ~ÚpðpÇ@NÛ‡™IÌ/á¤Ã¢ 1èæþþ€‘ŒßBɼ<¢«à_ do¦~UÁÃUð¬ã©ÇÂ>ªHå!g⋾@*<š…6¬7ò÷>o–Á¢ É¢JÑ9“íB‡7,þëÒé;Rˆ¥&ÏO4Í`˜$#ûó…}váÑè52o™2£Š)9š7œÇ„õQaÎYè2´H/ĽAFî.”l—ª×£*¿B_êÌ,¥’¼šå? –:¨l«E#:Y\6a`³Až²'<€Šz•3ÏávYјøáWWÑÊÀ'EFh"ôx,7¸uéâ°Â)áXƒÑ×hÏÞÉTô­¤Ã_:c¤I‹>#†>:T²5ëƒ9Œm X’¿66ŠYf+¦›1šòè1âlÝTP’ÛyË"v¤óS]Hïú¶3Îafë Øÿè8n!µ3ïI!JÚy·Ph_Ñ¿M‡MŸ¢2¤÷kÄ}’üRæO÷ÿ€ž ¬Ð?Ý@>µ¸‹ ‡Õg–ƒì9e¯R€¦ÁhϹêâœhÒÒáªb¡ýK«ç;ÃmI•fÛZ¦9ú!¥ñ˜˜08Éô(ʼ=iRñíèiVƒwÒ-®ò?“µ,3Y¦¹\Ñÿn8ØÖ€ËI\VAdÒߪ:´è(Tƒ¹Ò½æû¼Óï^YJ…µlg¨–Ve'L«,†”©Mj.¯Ž>ïEÑ·§êu¢Ñ ãT¾0þ<Yz$^ÕÍ)äÆ9Q4RdšûMÚœ–6+F=H%w¡nQeDsmô) 0¶ò šøÒvò„ðé$öO¨Í97ÔP:D¼ôÖŠ¢Y•öØšMüª­>åmKüUüN$~1ÆÎ@õ™š¬¨™îŒÀ¨ë¾ú—Ö0jf™<ˆöL2OsxkjPy0×VCí½XNŸàÞæº¼­‚ÌwWeK|9 ?a`l¥M¾†›9`èÐ5·Y¯ÀÅøVháÀ•ΠÅ3}ïƒ1  ƒ¶B_ÑÍ÷íS׈dóbWw)ð±¼Ex±7jˆòR¥+| ú1Íœ>H’vUs¡£’ "'v÷»Å–Â7 6_m‚Àni|¬NW¤UÓT#û[¨`£dF—¼]M¡‘ï,!V[4],ÃéUÐqYÈýñby0Eqaj\Ž7Fl„tTé1m…ê (Ú®ÙÅó¾àÆêËy…c± $3ln_¢)S¶nì³$N–É.:ã]Ïu/8}™Ò‹š¼Ô+ä>ª»3ó/.ºi^Ù)/±L1ëtºÉFáÜzçwL|šLë­ß{(Ïç’šÙÒÏg,_îߥîù ¯“áBó2g…ÐC®À#.€.¼êãCݺ‡ÃuýB#èÞóB4DPµv0ù S ú½³9è üÏʸéØÁ%Ê”TÖZàÎèu-Õ2Y=ŸÛߨŒ Uµ»B‹Š…{š®ÚhúZé†Ï‡¬ÍÂ<îNÛI7šØJÒkÐà ß ' N ©ØŽç–! …×éê‹!t¦o>rϯճGuhĉÈàÒóð8{ñ,›Ýå ~ë1‹ ÀݺÈÏkÙ3‚ãC"p澪»ûçe ByÑhF<»™•[î,ðãµäôþŠät¿Ü1…Ðñõs.Žák[ªiAÐîÕU#TÂìU$ÉP®p]µ xì¨2xv‚Ȫt‰× ÔTÐáe&Õ3&MC‹Ÿ×Z©^µ…×~_^ä&o ô Z_VÌ9,ˆ‡çÐEÇÓa>ª·Õé 8<ô ^û×ÅwYâøÿÏŸ.ÿeôž endstream endobj 315 0 obj << /Length 2403 /Filter /FlateDecode >> stream xÚí]ÛnãF}÷WØË}¿‹;“Ì Á>d/`20h‰–‰H¢–¢v<Ÿ–šò¸©‹Ù*·Çô$ê>,VÓ—j–M²QF²÷'o.O.Þi›Y°Š©ìò&“ ”å™¶îSÓìr˜}8ýt÷~œ‹³s&Éé$Ÿ.òñÙÇËŸ.Þ’×SñeOa4Âp͵9½ð\.{œüpyò¿Ꚍ~¹Ãe6˜œ|øH²¡ûí§Œ€°&û´j9É$%À¸rßÇÙ¯'ÿ9!­ù›X’ç¶‹¥­Þ‰µrQ[\ 8ÃýÓüp—OfãÖ¨þÐsˆ¾ü§ó&ËéÈ÷ |˜7þó¢š5ŸîF«_vú‡ЛþáûüV.]´ü¼ÄAáÈàò²¤ klVÙ͇HÛ¯nâ3Ò²õ <0]¶Æâ· ñ×Oßç±XfñÆzi¯ñ@LqYñá«ø’ÕÍëQæ¿üòþ$ûp®9}nn«iÛ¦½Û®¶ó¢YÌ‚¦vâ;ì~¸¥§lyõÓùùøº¸)ï¶õºØÝÉ¿û{Z?”Èö`„ÂiiH(ÎÓÑ0ÄGÒmì†ãv“JwOÏËz1.©ƒÒ#„º¹D¤‹CˆŒÚ؈8á.Ñq½(ÇÃÈ0(ë&B*“…¡ƒ ÞØþaPV!üÐ0\uÇ×Ç#¡-h©ÒE"ÄGFmlD$Œ[r á#1¨‹¼I«eVKÃdqñ‘q@ÍÜÒW>MöOíãò:b)ãÖÓ‹îRãtÏÚ¤TFm4g ýµÇ "Ý–†›t ñ‘AAåö@ËmÏß• O¾UÂo’Q)ÄGR ml•$ªô‘JývBåpT4óXòñÕ‚?÷x$õ°¦F0[`Ä™w0óö÷T“ëê꺺‹e+óÛ¢dt ñ‘|Å»›žÌmúè|ì»j¡~?“Ì!>Òhc#O5°Ö¡ƒjö¹·Ü‡Õ †ø·Íd£“["æŒG [nàÓtߥO¼íï1¿Íë˜öεIí‰Ãßplµ¿gM¦¶©6´±j# 8§/Tnê(·W)7i}j"•Ü:ø8¹áí/7i%pÍ^¢Ü䜰£Ü^§ÜŒOô$“[ˆ”ÚØ¹‚Š'·YMèQk¯SkÚgÂ’i-ÄGj ml„Ö4!÷G<Ç g¶Î†7±d•>y–Œ¬!>’¬hc#Ȫ«ÒO ݘíoýåµ½¾o mÀ'†¯$5áɤâ#¥†66Bj’‚äúç…Xê9ÕÅ›¯r”ÉbÀ#C55"Ò‚€ÔæEúÑÖ4–̧Ӓ1#ÄGRml7˜EŸ!­âóг×:¦§8õ)¬dñ‘GAqj@©—Æp×z–Šˆ5åÝ1Ù#²L1¥;Çíà#å€66BD;=ÃÉÒ¼¤Übå#a}(•:ø89àí/ah¨ç¸*F£«rzSÅFÄøTG²ˆ„øÈˆ ˆˆ‘ ×¥ƒ¿Õå ÌWny#m_ÒbUž¶yˆ·ï³yÙ/±ÍòÁŸn51zê÷Ûžúœ€¹»ÛUŒUŸ·<ôž!Ý))æÅ½4§-¸ùS¼ÙùÜ”¦nófb NwÖ É@±6E󯛦¨}åksۖ¶CÛÐWSå6Ÿû/¦åü¶vútê‘˶ã|P—^5‚^Æ…Ôº4÷X:Fs ü¾YÙš1®y³¶!߆/ C×ýþ¹®’[u–õ5§Å ©êÏß]\—Ó-÷µÜ(Ôö_±+;T»¸éì|ùÉïËϨt`‹¦èø¤}x±j¯5yÝ„.ÛUd,jÄ“N‹å¨º~Ï®S8Í-œþuitÿ²é¥G-¡Ä æ +¨a®»JWBÍ-ÁÓvðqS+ÚØ)·4“ëê¯=i¶êMºÌ冀ÐéÖ:øÈÈ£í¿¨âÆ9h¹%z­s·-v6þQÏËjºm½¶a±jÒ·ˆÿçÍ‚ÿöæ웞ïzså–4ÝyAÉ´±lÑ ioòyÏà»éÚOÕ]{v®ÍqÉŽ_²4&J ë¥Cx$DZ¦FP\Q0¢=û¾,&Å´ñ i4×™8r=×M£Å–öq¡A‘tÇ‚|¤8ÐÆF¨ÃíÊŒiw!?ªéü fvTÅó«¢Ü Þã²àŽ"ÝQb) ´±²ànãÝfÞl«bÝ›®ê¹ÜÞV¤|ˆÞŽ9Ò¯ ·ÃJÌ9“ LºÃÊ>Rphc#ÇÜ¥õ_R¼,&³qÞ<ÁfDh_AM¿huPŸÇJ¦Ž©´±ê mÏ.ßÖŰì;oÜ”ãb‹.,9¾œ”ßmñéþ·š»&–ÝÄgæ’±;ÄG²ml»‰"ÛÕÖ¿ËA1훇:²»ç,´éÓ§f7³>“˜ŠÝ|»ñÆög7³ ˆmK /n¡Rv^Š¥·9.j^BÖéÀ‚Ô‹wö!KIJjÝkÿAñ­(¡šiš­÷<ö`Ƨ>“i2ÄGjmlMjg85î^(oÉÊé°¸Ã÷„öY¶dñ‘@18jT·çOÿGUî;4@о"‘«TO²ÐðÈÈ`MŒâÀh{j2®ÜP9ì™AÕ÷yTL‹:wóaÏɰoÃYQGëSøìC2„øH  dàX÷iðû/ocYÀý.; B|$ ÐÆF°@Pà¯r(Øòÿ"§óÛÑd4ñ‘4@AN€ ú‰0.ç³XP¿oKFƒI´±4 ¸a¯‘o»Ëüoú¾AÆÈrÇ.5ÝÁG²mlˆqû×vvxW-¦Ã§ŸN¾»ŠC^@ØñÕ¶eEŒ©ÒdE¨õ{ÎTRîà㤌7¶V„ZçOÕf*ã3ÀÔø-c2¿†øH¿¢í?DR£@ùeÂìŸæX)¦_ÛI5\Œ75ÿm_Uh¿ÓK½=´±=¢g-hÎܽ$HÑæ oê|ûZ.UËÝS2¿>DGzih„O•iÚìÒ°ÌÇÕ(Ö©ÒïE’¹5ÄG:kìî¡Å¹C±þú=¸d) $)·@ýëC½ëÉv[:È8䟟þ•É endstream endobj 219 0 obj << /Type /ObjStm /N 100 /First 876 /Length 2196 /Filter /FlateDecode >> stream xÚÅZmoÛFþ®_±›]îìξLaMä.À.Hr@¯A>È2ëêêH$×î¿¿ghÚ¢ßD*¢p€í%éÙå3ï3»$‰Æ’d(àW²ñ™0ÃNïÅD&ã3)'Œd é½7Âz ¹¢ا4ñ.b¥èðÓ¹(M6”¼ÇE1”cÁ…*ÂÆ“ÒüÑ5)Eü]pú$Ï€ä böO˜™ôŽ03%̈¸ÈO‚/ SÙ™àÚtð:½ !7‹™õ…Ì&$Æ,Ž&äÂN‚x,ˆ§ì¢þ ü“è,1<KÌŠ0’áäôíÞpóö˜ }f²(Ìp‘€2‹N¥‘½‰TŠâ51`UŸÙÄèôI11)ø agHˇ ¼ÇC²1CC¾`zQ.sÄE ÉF)MNå\¢I0KÈ@Þx)H’ÒRÆ‹Mb5þ™8b]Ñ (;@‘©›x¨%eŠ×&k¬É¤zqde<&dVyAÒ9ŠÊÜ™œá“ÉB'ì 8˜t‹I¼­PcɵȪ¨˜aÅ ”“*!èL1…=” *1êh3î°—."HŠ” Öƒ;<ÈRµ§0BÀ°… ‘Äñ_(PÔ2/ªÓc’Ð\$˜t„΀H¼Øš¨õ, â $j˜–ÃT ÉÊ/Ä,x`uF  ` ‚l=^ZÄONN&ÕÇ¿¾Ö¦z¹X,7“êÃå馹ÿÇ|ñǤúy¹:«WŸÒ}®þ^½­^}¢æfR½¯gó)&gÚŒâm†cÊlÀÈFÇ {iNNLõÁT[~\šêµùî·ùù媶dé…ùñÇ ~FÀ£}=Û©Þˆ9ØädŒp œ,lh ­vÃðãÃðÅÙ*%†l3‡Ý0Âø0ˆ¬ƒÜÁ ±ðÀÝ0xt,P5¢Ñ ˜hÉe7Œ8>Œ­“rƒK°póÝ0Òø0b¶”ÒFJÖ‘ß ##ˆõakÌźÜã°e|Ѩ£“à,qÞBÆGḃ¼EmѽÜè8B‰–C¼Ã„-2ŽñÃ(*$‘m49ÙÀ=KãÇQTG6¥m8±X¦žpNãÒÈ¢lÚâ`g>zpŒIÁÝÖiQjØØÁhüHŠ‚|‹Â±E5ÞcüHês¶%l½…°M¥Oã‡RÅŠÛz­O%YOD§{±ôµùäIÛ¯÷¦úå?¿šï ×ÔºˆÊ(ö—ŸŸ#Ž`õ}Ná>í›åbÓ€xƒ–"ßÌyƒ¦¢Ü^¢ÃsÍ5&TïVËÙ‡œ™êÝë7¦úX_oÌçûÂz7=¯'Õ+¬[/6k0ß Q‘¬——«Y½nzžæÑ?ë³ùôçåµi„a5ÚFú×DónºÂ†è†ºÑÂïÖNi w3R;úv íÈíÛ1µcnÇÒŽíz±]/¶ëÅ›õ>d mEŽ úèTä”-óÓɤ¾ž~ùz1vI~×$T¾Ó »é⤠@tFDAˆÎw'‰dHÕ)ˆ š¥,=@Ž!Œ©ÓµÅ„Dçû$Že_îdúˆê·HPcíH„£Íz€Ä#´nl…: ¨¾céÁ‘ŽÐ»y«{.w8P(#õ÷à?¹Eçl)y8ô¼[Çè츬ãNÛ$Hþzpø#t‘]$uºH<}ò¿$å„lÚi8£1*¾Çšû¨µLGÉ[çsŽø°ø‰Ü-~…‚¾øéSüàZ·g*„r~Tå¸O!ä ?¬„r[ñä¶âɼ£byJg΀Ç;QF¾Sã…ÇÔììj»à‚~&«ñ´fÐXAõòä¤yCõr¶™/Õ‡êßïßêïw¿o6_¨ª«ëó‹éYmoþm¹:¯í¢Þ¼xÆÆô‚N¡1¢fŸÙè7Æíš¾o ¾/ÓùÅfùÃÙ|±<¯?­çõbj/æ‹Ëk;?^(ʺ1 £wNwö‘¼<Úe…™÷ßÕ•½º¾šŸ×›µ…ô^ÜwŠœöèºÄ»œâÚâüZF®ö~mpðö”¿Ý1E?Âh^Z{iù&/í°]ÒÀàÕÇ÷ȼŠÄ«¸yÚÃ&»Ä}6ùmL‘ã†ÐzzÀÒüþò¯Óÿª—ë„·_T²[ú ‚À_õh!8~¨=à:,/HÛùJÛùJÛùJÛùJÛùÊ z(w3ÒAùÀ‡‘?<ƒ&=ªD< ){Ç¿ÓåôûÙr±Þ¬.g›åj¼4 %WÎw8“GܦøÍ@5Pýkóûr1›®ÎDê}SœîéqDãµpÊÅ’9ŒšDöUoÈMz»…ÆŒKÏõ‚v#¸‘¹lY½á–Zü¢þ4D¥mööÀЪ¯«¥ºþú¶ ùv ýªgÏVÏèK±"p“Úá~8×ê!óÍéåìzs¨øœ…R[T,¬ÕÔH¨ªéùj~~>_Þ ¯ZþY¯þœ×WøolvÐVbÒsvXŸëC–ûûî—z5»\ͧv]_Ô‹ùÌΖ_îZúÉÃàîãqOR{ŠV·],ƒhYÀs†ÉYÄ·A´¼úAÏÿ¯[ ägÅrXVÔ¯Dn²\>(ËéVƒ~c’-X·>Ð5é'‰³ %É‹÷nÀõPJ¢&$,èBÈ4s$HÊÏì­/Oõ§nZ°õp¯¦1^âÝ#îõ†Ç´ ^á8ˆ6Âs$ £e¬ëSD Ã^‡Ñ¢<·Z] ¢õºí̓h‰“ÚÖ©[†ãyç£C@á°ÎA?¯dé‰-FáÄem@0|ÊTž¤½9FDë“-y ^Šº90ˆÔ1,›Ñ&ÍÞOy×S´°VÇ<Œ6£¶/ÃD–4øŽµþ5j© endstream endobj 368 0 obj << /Length 1748 /Filter /FlateDecode >> stream xÚX[“›6~÷¯à­xf—Ú§íN’I&I“Yw2$2È6Y,Q$êu}u87ãmÚ' t.ß¹ì;{Çw^/~Ý,^¼Z§NꥫpålvN¼òV)qÖ©þ]Î&w¾¸§§×%ÍÙò6Œ}÷HyCËå·ÍÛ¯ßI4çŠg”¬½Ä'ZnËkòuâ¾ÀÇâåfñç"Ð$¾ôªB/!±“_¾ùN®ïÞ:¾¥‰sj)Nø^HVú\:‹O ? œ ñât ðkì^„r •b5" ôÀ CøI\¾sÇÞ:5¿|ªJQ|,Ö~°ÀªF½¡—Al$¬DJ½`Dî|¹ |ßw?5E¶ }÷%KE–ï*D5 …j÷®Cùy™ø® ©(K<åL{ŽgŠ?²8V¥!܉úèl¬½”iZ³2†áÝžñ·n8Gèu`Æk«¾ ô=²JlÀOO{륉!dí‘8µtU-ö5=¢da ÿ΋'†àUçÓ ŒxíÅ«èYRìŒg>/#ß-x.–aìž$:ò–Ä¡ë„EšûcZN£ÓÄÆ'M]ɾ¢øüž_|\±KK¦ëS¡x%(ü XM¤-äM£”àòfyK´6Ês¼¢È¶Y’Ø­™7oq¡ ÍbP™0§#­—Z*3B着,2ª Á½åmÇî^|¬EÅjU0‰ŒE6Ù/ctŽ<ö±ÄX%Av‚†a¯¿1 çÖñÐ8 =7‘u4ÇQ=*ÞÇø\ð©j_z‹W±{3£„(UQ]Ôj!uv›+”1z×ðìª(za„çùHËN§/»‚sØf‘îjqœð¼ïl§¦~‘„S‡~õý°–j깟19¿†!¹›C¬/¢Ù–´90>R‡õ¾–0ñ‚°¯öW­.+=ЍÔÏçIhûÂÑ¥!K¡$”•η¯‹ü"L§³ÂºŽ×·mJ6Uu*ò=Sr6¶ƒ‘¥k·jÀÚ‡Ih9ñÜÆ/ÄÄÑQhÖ…R½dº‹µ ƒ¦(&Œˆ'èÆ_8­¶3…+ 5$:¿tìÛ‚0¿ìX©³¤yE¡Í´¹;l’Ö”q›ôæBŽöܵãnA²¥tUf&m<©Éd0oMû\Õ¢œ/Ͼ£^¯Ì$6‰ìv%Pø¤þâÐÐ)ŽL±~d¥d-%=‰õ(PCzâ±uHlÝw&üú¸5äu±?¨Û¶tžãû¨¿3ÝÌÖ8À­]ŠÍDf4müå”1~ûØM`Z Ý^o.£¹M=Þ>aÔõ+Ù¨´Æ dWxmÞÍŽ¹Ö:B|·l ÓvÀÀ›V†ËÀRü‹>®[šÚPµÝ®Õ¡ua+‚n¡'ÆQê¾á©à¨{q< ŽÍ§e¥[¼ls \ÉŠeÅî<µm°ƒFØ TË,Jð°C[³œÃ¨­Ìo]8ë¥7|¦i¾£¡ê»f |Ô [àÏïM·›ˆZOQ9-³Rÿ‘ñ+Ýq6-ýÈ«åê®›³Šñ>ç.hÎ7—{h2È®Øt¨eüé7(ã9`ƒ®9³üˆé¶’‰ºf²[û•äBøìV5jÇ£åxÔŽ!àŽQuÚíä¿@uÙ•Kå$¢|hc÷ú@¡G›B¿NèÅE³?<߀NïÙ?-õç•o€~ÌÙ¬æÂ~7·#þŸke/ì‡Í¿¸ñ¢v`0Ò‰¦þÐÎfb5Áá6rè-ë¸ûê qùJLâ7Q…/z…P‘c§tV”FÔfÉLï*î•ÙF§µ–”ﺟ‚l7Ã!ªù­QíÏU‡^‰®¬™™U5ò0ú‹eötg+j¸bõ Šæ÷´”_Œ!†W§ey¶adRÎô»×£\„ìû^ôf`”³&ý&Éϧ†8V…ýëªÇøw»Í¹K©îoµ¹ÿ£ÐKýèÿüøÝ1å endstream endobj 374 0 obj << /Length 2787 /Filter /FlateDecode >> stream xÚY[sÛÆ~ׯà[¨&‚,®}K\Û£Œ§ucyڎ鬈%‰X´¤þúžÛ..„¨$/ÄÞ÷ì¹~çÐ_íVþêÝÕOwW¯Þ¦ù*÷ò$LVwÛUœxI®Viß4XÝ«Ïë‡Çw•.ÌõMû냮OººþõîçWo3•ÁÎDáÎ(K½ÌWp.mJ`yš­_ñGŸãêÍÝÕ¯X⯂áªÐËT¼Ú®>ÿê¯ ˜ûyå{Qž­håa¾ªÚÕêãÕ߯|!ß?# VAèåAßåœM…^HDØ]«Ï7ïûëŸtWn:¦³Ùò×>™ž9a¿º áÑiȇÞí/JÅëcÛìZ}ÀN4p gÊŽ5wû¦©¸µmZž)LWîê²Þñø»V÷åFW<û©3-OÜÖ½i·×¿ÖÓñØ?öß}º…OàñúÛ~|/|ëþ:X›º0…¥€¿÷†7œ:;óPö{Y³7ö)ÿ¸ŽüuYìLß!?Aàå±°u ¯6×!lFšö+ëIYóWW• ô7¾ø¾Òס¿þ†?MÛýn‚­¯¿ÿþ^ñ¾ìŽÒü`ÚÊ6Ÿú}cO­ nüó—מ£*õr¥˜ª]H͉WÁ e¾•*1µMQö(lomcÓÝ“@døÐ SŸº(Ò{ÝÊ03‘Æ÷Öh `Jg8¥ïÍ|Ñl$?ë„YA¼F9ÑTÍSZì0)hà+Où™µCïáq· Æaâ¥~dHÂÊà 3Ð}н=ŸÏ$ò\Œò.ž@é40ò4 yÃIæw¦6­îegÞÈÎMSH‹˜³ S¸âSǢȜä“7ò=?E~ Ê?äóð ÜŠ¬¶}e+ GOQA¾Ö=²Ú‡HÕá@òÅNUÖ ½›šƒ^Ñ*]ËþªkxˆTmz>“@ß'’4¶ú+Ú‹±LÄ1|/~…YL*œnÙÅ„Ù3›ºzZ2Èæ¾èß¹‚¨ÌKUô²~€$§ú!¦±×õÎt¬Í7Iìà`'¶÷ã¢VzêEL=?Oçw|¦××½¶Ì<œª¾<Ú5ÖH•J×G]›ÊvÄbq“è`±“áAK±gÀˆKóÑ^8!érÊE^&*Ý÷íÌ “Ä7•zQšN7¼GÜ$/>e|>ö›ÚJΗ5Foö‹¾p¿‹ÆžY7½ éz'ÓäÉÙ×Ô½õycñ—õ¦{lj™ÛžêM_Z¿\C,°»ºþt/WY· b„“Á»‡€˜äà{´Ï“´ãh¯…=Ë‚ý©‹æs<EσܵüM×sÈÿÐjxÈæ7Çü$Æ‘*Bk×P´N!éí¢Ö /ð«‘MRl†Õбü€¼aÖÏŽ8uú¾¬Êþ‰7±ºÊý¨£ÙÈ ŽÖ[­–]÷²PÔ[“Ï^r&gÔ3÷÷¥Õ@ä ’þx4mij+'ÂS¬b$y‰c…‡Ùvg²Lfì½Ü·î¥zÐOV±P+¾‘#mÚ²·¤<–ݾÑ}^Ù1Óôš‰”ƒ(óÂÀŽ0œ,¬¿¯d„AŒúØs“`oÆç¸H‘!³ppÛ3®Sl)þ±½×r';ÜPœƒœ,-[€(§ÖH, •æÉTxûrVäIÒªÊCÙ;¡æÙÚx; ßqÊè–l4Ùf.°FмeŽ£w¹Ñ‚7戠³Þ”-èdP²ÖPT‡ÅeÿÝu¯å V´¨âò¿#Ë)/hê”ûVîëíÀ>AK£:íqŽ÷öÆö PâÁ#WkÎ@‡ô±+ÔdŒI¼¾¨Õ7a:!ÆBA/Ÿ¬7¬ÍÃÈ£ãÛ"YÖŽñ‘T¼ùÙô—µOŒ2@ñ¢$žjä‡Ê·Uà⋦þ•©ç®©9P@sô®1fªOÜá,Œ#=.¯e *pÎ'BzØëŽfÄp€ñ3b•ŽBb/âг[¦o«ë·IwoF NºiËà[˜>g\6°´ÞŒÉ$3ó=®L“|J&Ùþàš’Cmé“E³.á-½G× GšñU5òæK%,•Ed ³V ÉÌs%,.Y%ç•7•Æ^’2·Þ<êƒËB/Xðqìù©Ã,¯›¶uÄ[1ärØõè2ž}K€¿LæoQÊqÏVUz‘<…•˜²‰gBA^e„¾nÿòï×?þõõ›÷ ¯N€lγ—™€]T5ëz0›)H}†0,3¤àðeÞEÒB/M§¤=Ëê8óÀÇÿVO+žKêÎYAT:CÊÎ(>ݽ½É¬†@’€Îù’`™úñ^ð§xÁŸã_ðÂøòº”zÏøú©¤\Űnê›?¾¾½u…LѬuæ¥@eIŸDªEžì 8ÍG±›ît¤X}‰)pb˜¸Èô¦f窜“ÕZ ì´äÆ0#ç¢ïò†Â<¡m£nø[À¾âê2Xªf˜Go—®øßèŠRVb&;˜ÙüšbPy*ž… WÀzðPH€Ì+Z’=Hc&e]È@dó:íDð”ú0o 9nÛv"$Û øØ”u?5Óo¥DÕ?„°?žvÀСb1ª\¼` yæÅ®lÆ5€0™ÕÇiˆäIs«ô†ªU±”-´Œ«NYªªøŒýÞží–Z …íCÅ‚¡03T©Í _\΀i€R³”C.JÊ3¶ÖÖá8|7€ ²™Y”vr5-Md;ß´Œ‡Wžkä[œv5{mþW¡RÃXW;)¶þ`ÿŠO¾ìµÜ£gÂv`âw¨¡Å{”.Il)Xÿ¾BìîÍÀç%÷ç„ò8óyaÈ6ßÑ-ЛÜ}´ÔŽ›\P~ þ†0L¾yð‡ÝÀÖïa­èI±õ@¬’÷Ë ‚yð¥RnìàÑú§@E^–ÎJû«b(B«rÃu-W˜v ädÖœúãiÄÜkðª§ÓbOä¥Á ÿÖÜ8x÷éÖ,…ÿÓ¹ÀyîÍ’’÷Ms¹PéÔcZ®ŒË•ïIn¨0ðLI]Òl*@èC÷T•ÜOyVóÂÛÐĹ­­)`q¸{fžÝ<äÔ ÅQˆ&I<JI#îŸÙÿKp)xe;É©uñ“j¨¯ÈÙäP•­FJÄû/¦O"³Ý/3ê ÿmRS¢áy ÏU‘P‡½¥”Æ¥¾/¬b•ˆêÎä/VH#?¹ã£Ù¸¬™Ñd»[qã’g gµnÆUÝL—@išéGäßøÿ¬{r endstream endobj 381 0 obj << /Length 2389 /Filter /FlateDecode >> stream xÚí[moܸþî_!¤º‹di’"E)ÈM]ÇçÃ5—ú\Šô>ȻڵzÚ•NÒÆ1Ð_R¤´zÝ¥Ì(…K+ ‡g‡ ­­«³¿Þž¿ežåÏÁŽu»¶¨϶˜Ç¯ Y·+ëÓìáËU䯂ùS8Ûú»½Í½ýáü­ -——tlQ’¸ ¸Ðæz‹BŒ‹3wv./6%Î.oÏ~?C\ZèP®M­åöìÓ¯ÐZñw?Xϵ É­EØvø}dý|ö3¨àÃz3\dq1F½F;(‘ˆ0 0ÊrÖ§‚Î~ ³D¶¨a h-0¶CeùÛ{e‚B¼¸[Æ¥Y6Á.Hý«,°Ãc ²›m.S(xõËÇ+y÷6Œ‚×§-v½æâÄ™=tá7ñ® 7a²3úE_ãÏ *ðkÙÓÕÓ{u£B(VŠ?.ˆ#W—æy!ïö™*6`X×Ô®¢ê¢Ï¬ˆp³º¥.]5Ed¬Ü³X”X°»*yLFÈ©T&Н H‡Æ°Yäï6{£šÆ])bЂ@ÈÇ[›‡`ªb¨ŸÎ‘;Ûì·U3ëEÑ…¢æ«ß¼»ú0wàìÍœÒÙÕåëAN´YÐÔ×4Ïw#ôçÚû8Ë»’óŸEkýhTPÂ¬Žˆêø¿«Ke¨T•{öñæâÙ uŸŽ>rÂí‚4ª~D<–?kŽ:Ï.ž?Ö;P ÄM?ÊâF0hÂU H-fÄë–Dkt< ››zXOmÀpÅ¿E<Àzâœd½ëXÏ{eÂ;fW…À>D/I÷Þdc`fq¡Lùêo—?ß^¿›c!àÑÙíõOïžÊ+™™0d"ÑizcöòÉ>|5ìB14<8¤^ mD¯‡1–ó-õ*/=-XFH-a1%ÉOÆ#h:~6õòÓ¬?  ˆÝz¤INä>™?#PÖåÝEë¢-Õh¬UC9÷9-¹Nã­®N9øj «#{'sñt½ ©ß°ƒÑ Ðñ&èÇÆÙÏAš©%©ãîv‰ˆº÷ñƒ3’4Þ¤þ6Ó“ÖF!„wûí]êÉj39øæc™L)p±=“›ú ™l v“©š‚ÈGòÅv5ÿ—]~Êçb¤%©W½ÜY'_ûcÈNp¹—'#{S¿!ÙÁŽH®‰ U )I…îüÕ¶màA:‘›ú l ¶'~0@¨€ÉòìrÑë+ ^rÊ0vðj»ñÏÃHþ§Ç9,gû“±²©ß•¦`‡Y‰ŽK}Š3½˜?aµ£—ÅøÿãQEJ$×4&#eS¿!)MÁ“Q€=IÊž#Ä’ÿèÛ;k=¨3uåϾïÓ`”« “1¤©ß!¦`» A.Ïø×L€œò‹5…ÃFNƒß÷a¬Ú~á¥ÐñÂÃw)5ƒòck‡gG«øìGáj\ šÑO|—·zÑ–þü…fЇ=9ËŸŠ•-ýf¬4«‘G+žbÏ6U‹Ôo.FÒ#R; FŸ™Ç)>T D˜ÓáÉ<ÞPoèpC¨ƒãv1°=÷ä8ëuÙ÷on¿Â8Õ¦Ž;z4¼íˆùà„înê7ô·)ØáîÌ ¶§3ìÈÝ ~4í°³n¯ÆJ†šó3ùIDΣa«½°kNûLušËTNÄ'ãrS¿!—ÁެˆŠf‡m_•]ÅNŒoD®ÓD rî;šú ‰` VõP¬Öº/¿øb£ËÈdòjÔ'¿÷=ˆùçÁX7ŠÆkMŽ=úI'ÃìUÛmÇPÒ–3ßÉ(ÙÔoHIc°”dâ‚îêt÷]ø˜¢™…åÁ6©Ys"Áòo@5,§Ð“Q­©ßjÆ`GD?Ì€Õ’èMPœ´ÐòÙÝ~£99Ïãn8]`r|‹F?ëg'W°¢¿ðidž “ܹŽÓîzÆ‘R» ±1dLšçNñœvOÆí¦~Cn›‚íIè¨+ŽùpÕ/Q ©G¨uŸç`óòüü0äHIÿ›ç Ùˆ"]äüµî:”úÉxÓÔoÈc°#b"¤ÀqæÁC½¯0ñVS2éÝÂyjãÚhêpä[„Cm"Ïz&[¾O\U:Ê«d¼ÏiŸ÷´kç=‰ç×s«óžåùÎÃaÓR—Cdj™ä]œ=çR[‡>d¥P]rásØ>Ðg gäz4ó³KË2á.Ë__”y~«‚€ÍÚUtµÚ\+«|»ü¹Æ¿‡Ë4Îâu.þîVÅ·LüÝÓµ¥…ÄÁ<<ÊÚ]Ï•ûÖ9- yÊAÝÿ¸ÀD’ endstream endobj 407 0 obj << /Length 2581 /Filter /FlateDecode >> stream xÚ­Ùrä¶ñ]_Á—”9åŠ$ŠËr­+ñ&–R©ÔÚ ÍÐË!iÖêïÓnðÇk§ò4 ÐèFßÇøÎÉñïnþúxs{§Nê¥Q9ÏŽŠ¼(NœÂo8…óÑ}ùü]•úp •ï^²z̪ÃÏßßÞ'¾“ÀÍHàM™Ä^â Àk.%'î-ý…7n¾}¼ùõ&ß fR¡—åä—›?ûNgß;¾'ÓÄy1G¾ŠÖ•ópóÏŸŸï/ÙH'½4Ô’™z€Û¼(ô"ó{Ëùx |ßwÿÕ—õ‰ž9œ5-úfì¡ïæü7À¿áy%-ß9† 8$ gÝÁ!7›ôS5.R·y¦¦ʦîéchè7oê¡k*Þ<3 |L®-D¡ ÑI׺ˆCàÚj»&×}/ñ5‡@¹¯›=!_c]Tº ’oOô~ Cq×¶U™gøFø”tÐf'±\à "¼T±¨Ã?º¦ÕÝPêžûRÖEs•ûBß?ùÊï5â B÷¾×+켃06|>è6=¬@hýÜtDHgù™¶ò*ëòÈêâšø>ü†ÊÓÝKWìzFŸË~ {…² ƒÐ›Å^*Äd@ÈæY]"Ã^ï6t2s CWžNºë nò{sÄðlvš@šzA âõK9œi•UÁ¾5S)ë¾´hˆà2VCÙV+l ~Ü«¢…AzûR'= ľaøŠ@­"Qn³"‰}Ú-ë¼ $;Ë–Ö¨'³8kH·DBk£j\|óõ×´ÈÁö³²®^‘r¯+'óÎeWÐrz¬÷¬im°³°Ü÷tðˈ*Ç;.§ƒÇ™ÔýXU;O¯ôËÆ0!™ðå‡3Ä—buŒò¦±ûžI÷ì*»FO±$7™'~˜uöÊ:–»M÷‰¿Œ½™=Ò[ÅJ ¾«Ôm!¼$SZð‚ÝÄÀ‰9.cÜlxÃÑWZ[7ÙOÒsøâM˜ì+6y£Ød«XØ0ŠÅ=¼CÑú‹Ü Û/¥y0¬:}´ŽZÐNFGb¶k|‰õ3Q3h‘›Vm3èz(3ÆÊ¹ß¬ósVŸ4æéGîjd„ðë»ÄÆvtÍžÆJµŠ_¾xã€óC—Þ8ö| >YbZ!Ê|:Åœ•ƒ–ˆ2äÊщ“«>š$KI¥.* C'ÆA’d©‰”²-î‚åô R Gß ¾`¶j”^¹wUßÐqùL¿Ú;™3µàÐ&Ë‘šù@g‰%™‚îëì¢ ¾ÿ£6ù^Ìfe«|ò¹©øÒ‚¿ÍlGipÌÂÔ]×w8BÅQk=YœÍ¼¼ìmT½óAç&º]Íð„îns¼‡é£{60±~c;Yñò™ÕÔ(|ˆù€,øEC®/®hz t…N§?0ŸÂZðÿ§ÃM¸n¦º 8_Œ+·nÖ˜éè$ øõ°˜\* ‡ ¨õW‡Ìƒ¶ž®AŸZD+2|ÄŽâöÃoÂÙD݆3ÄЯ(ö& )¦pÂßµ-g•Õ;D<5‚†¬Î÷Š«c€øHr0Šv†÷¶±%éÌ[gžº³kÓ™nkÙŒþÜXôdÙ-ÄílõZsÚêwi“Köípã0 ÅÚa\/Qв·üŽ|ì«™ÉmBž¼ãš4!¯/½YÏJìØ‡‡ò²ÊÍä—mËRæÝX×v9$oÿÚ¦/ùņsؘüFL~Ãm;š¬7ó [‹ˆ Ådå–ŸÂÛ‚yÆâàyCß‚iÈùh] òet¡=.?wGLæÿøÇÎZÖÄ• ®Ã:íý·*C/…¬ó?üµú_½"ôl endstream endobj 417 0 obj << /Length 2522 /Filter /FlateDecode >> stream xÚí\mÛÆþ~¿‚Húá.é­÷».ÚÀ½Øi ìÔ…h‰Ò±¥H…’pwòß»«¥ì#EJ\öšÂþ$ŠÚ}8œgf9/+âhá臓¿_%Å*ÉÏ~¹zùä…‘23%³3¹Š‘ÂÌà®'i3$CGþzÛ¦ì=¸>·=çôç»öø§OûGwX„'ƒ­£Î*šø@« ëaX *ˆ§U,–U6Zê¢R„1FF F\ØádHÍÕÔ‘±X}FÆëâÇ"k“±þå·¡„(Œ0áiâ  ;€­MB͵˜‰¸ê(ivïµÀ­øÓ"Í']ÔØÅël}ô×Ý‹›lr¸§Im¢<ŽØ&>X°°ÄÆ&”޹#ÖïIdíYžÿ83ñÌ?’bœ§Õ¢Ë0|OR(Dhާ&>'°°ÐÌÁÂz˜¹í ÓºÐa匚8^Gç YZßôÙž@LE‚7ïÞ¿9rß¾»ÖöKƒõù}pðg[Éq¸Úk hH`a= ÉvÂ¥o»¢wµ;~œñøå,n[ç$\³…´°°¶b;ÿXüQ6i2íÒÈP<µða<Á…γÝzî[o¾œ³ë«òÚ8ö>]/—÷ßg]ÁS`e¶÷΢­(¨‡ (ޤª+žýëu¨ýš½Æäµe“Å.ÿ ÆlÈ-XXví&ZÇk;”|×&.Ý ÆPÈXX†lO;¹ß±@Œ»\!GM| GPa{ËœÌva ñë1.`-Wf7s’¢>Xƒ¦îË}¹ªì‘~ð¿~sz^•ÿNGK÷%™,ÓÊÚRÅú`šiµi™ïåÄ¡|àd5 s…Q}ÒD–îà&5—ª1mC*Oèìœq¯6“2ÏË3*NoÝý›Sé§®ëµpgÆé¬,έ*ìÍb¸­ãßŲ²e’º•õIæë¦Ùõ*+VwGÌœpæ‹YO\-ì$÷vƒ‡í8¢4ÂXokSs¯Ûl[´o¨Ç ÞÎ5†¯ãã4)7Ëí~MßÛ ¼hê)©{‚æÄÅqåŽÃæà“±l)·÷ž™B,>f·2nẅ”²µÇ†Z¥[ø°U,lï*M©DjÓ©ßS.Ý wœ›ôOxQË‹2·KRk&ÚÑßjo#ïÍ übäÛ­ú|‡e1É:³ó³òìCW–MöüGöw£»»IžL»ïÅÍîŸ\c¯Ç6ö‡”˜GmÀ 6-| ãB…íw\"âzãæ9ˆ“HasIÕUÝÞÏ&HâpÁp ÈTØ~¶0GJ×ñáç©nï*÷öÜùO¶Ý–3JªÅ²Õ§õ\ÿ›X’í¾ÔËU÷_í„[q°~JéA›ýFJ´1p®¢Õ‡)XØ^#%š!Íègi¤„ÚëÄJìÙî›dÖEbŒ”?FL´ß¤c¤ ×ÉmáM*l¿I+³Ïؤ±Ò‡­»µIãø)ÖLúÆÛ -£2deˆH…‘ ÝÁD`$4?JòO8AlógôVò/Lþg«|™7÷'Ìx±>bêOCX‹p¹?¡©Ã-ŽM|àâ¶q¤ñMq阹ÿzå¹xóæõtJ¯»öIÿÿ¿Óÿ÷„ñ !‘€;Zø@_ƒ Ûџ∠j9âRì DVOzk-ÇpÉO×è|‹Ôq\lˆ¸k¨…´+¨°ýk8fH`yÔ2PMc“>É‘ú ÒˆÜ7Ô„‡µ—'mB6¶õ“†0Á¡ ¶§„Ô¿*îA®Bߎûøj\˜½Ö©ŒWo6/}fÖI¹ùMq®ûˆmÓ÷Ùë>;ÿ²i,óC^µÿ_0`/Ö endstream endobj 365 0 obj << /Type /ObjStm /N 100 /First 860 /Length 1435 /Filter /FlateDecode >> stream xÚÍXÉnG ½÷WÔ19„]d‘µ‚/P  ˇ$‚^&†c&Ð8ŸÇ–e­ŽE[:ä0SÕݯYä#‹du‘šr*Ò’*†žzÇ0I¥äÄÍ0r%I-ñË #^1Æ̰©”š´8Òºãz2qÜHÖ°ŠæTY“ØHÕ°Žrj먤¦cIm8NS/:µÔ›ãj⸖Fu\OœÙP4V2hšG[Ôa†ÜbŠI‡bf‰«˜´2k0 9¥:r4CN…Å2~—uàQ•ÄæÂp¶9’«Ì¸S«ƒ!°u™J…œÞ5AIXÓŒærk’ìKâBx™€Sq²@°”†wzË!ê,7¼c¹N¥5L`¡@;p’|’]Fíà¡Á1Mà \H_&¸3à[2€s%2à ÷K¶1¨YØmv’Ømî –ÝæŽ q›—`p›ûâ}€Ý=nMqœº†;l(‡ô©  ø1á;¸:^Ørpw ð7œ°­9»ú†‰kϪ‡Fw©®Á(mÒŒËÅÙëI=4Ýi 30QD° &x´„¨¢*øpx%®µ6p‚µ³NÊX¾#@´¬ªŒß@Ôù2&+¢Ö2Â]¡ åeõš >ÆÄƒ& Œ0uw¢çéà`šŸ¤c‹-ö,Í¿ýþG²JÊUËĈŽíÅ»w/¦¾ˆ-ƒV…°ÒIÀ]Ë$Í•< D°6Œ< CØ®ä܆°­b3‡°UHt!¬1Y‰¹Â4“µ˜+T9Ưq§T77j9æ P@Mc®Àv¢†1‚Åî%ß4!¹Ù¨ö¨\¥&1cƒQ r†p¤žc.Fæ§®1£ìPï1#3P”^lbÏÙ!,"'sÌŨÙäÕ2‚•n„ÚÃ6%n1zQ·H8F¯˜÷ !¬2-+™¼óay—Ò…ž´Ær÷J–cŽ2G¦1OpU²þ»‡»íy:8Hó!êh»|çB¿š¢’å«yC.ú0_Ú)ùpÁ^•;~¹óÓÓÝë£Íy:NóÓ'‡i~¾yž>.ùüŸ¿7xðòífšcùÍöü ;kYqšŸmÎv§¯7gK_´Üúuóæäå£Ýûtìšx Tç§öñ«½<…ìãEÏ}j»&áF•Â6GÏH¹¬ÄÍ>øch=häÂZÅXì+ÙE#™¿Èô·ÒÙôM¾…Îùáv»ƒÄã¥+u•>[yy>ÍG¯Î—ë_N¶Mó£Ýé›Íé²B~1ÿ4ÿæåÂuz}î!Š„ƒ0•ÛS c‡ -Ç´ÔÃ…¸£4ÿ¸{¾K ý»3¼w²Û’PùÞ‰ÙsH+ûžfœFþÓÓûàÛ<½‚5—µÚ²UŒ5(6wê1±È:èJ4„EÕ–ÍnjûU!¼— ®Ãù[C¸óÍwÌ=EFØß'+Ø æµÕ‡  %ˆ-Ð!ˆÍBCc:àÔF£·¶3eé1lË”kŒ_¶i­w\ƒj'6‰aK#1·©HòG^Ì%+޹BFñ,Ã"ø‰9„mH²ÁP—šIƒbuIÌmR:áÃJ£šc®ìæªÿ—ú«¹}ž¼üëÀëï¥ÚþYãrÔû¬ÇŒí/ÚRË®P?šyƯÜtµ ÿyòöâtC(‡ûõønj r£K]¾– èèó§õRªþå`½1¸xuÝ`÷ÞŸ6¾imù܇/yrPÄNaý6e`Á§Ê vý3U¸Uù|K ZžVζkØ*™l%¬a ¥MV–«XPXCXÅaQrŒÏ麒§W±¹bsÅtðÃ"÷¿à€Úè÷“tØ¿Rr¹·Ä7SÛÝú'ÿ°îŸ>_$*ÅX©*«XœÅ»í9ø_í~~e endstream endobj 467 0 obj << /Length 2670 /Filter /FlateDecode >> stream xÚå\Qs£8~Ï¯àæ®jí«" Aªîafv’ËÔd&7“­Û©Ý-±±Ãàq|¿þ$°Á@ žæ%È µ>uHÝ¢l¬ l\Ÿ½¹?»¸Žá Ç¢–q¿4¸…,Ç4„WAŒû…ñûd÷t¸ ozN9ž¬ÝpëÓ?ïß_\ÙØ°¡¥ef-™M‘Ml›7"ê {r!/&Ïšœ½»?ûï:Ø ‡¾ ¡Éùúì÷?±±€gï Œ˜c»¼æÚà#jZPŒ/gÿ:à ?FÏŠÙåúX²‰f†`6²8Í$g÷)rlÇ YmLj=cÙ*éYù yU~²ODz,äPGlnL[H“°ccr‚&Írž›ç}Ç+C>_ŸÁ£x§žIqÏT>©;°ò¹…ñ„´¶ÉÏÝ8I½°ÒzPexDlxÆ©-º»ºuýzË ­€:—Øê–ðöîîÓjEg·û_|7ˆVõ1£výÌ7›ê+ö­¾3ŠÙ¦Ó²ñ˜]•¯Él]°íÌfPÓ&?2µ‰Mî®ÞoÃFj ‹KBF£öãPbS ¹ŒCìª|Mbë‚m'¶‰¦ô‡&¶°ùËælRÎÙ”÷%öU쮽q§l‘ÖxÌ®Ê×d¶.ØvfáÌcü™M¬=e㱘=xÆ& °tÉ; QÂeú»v=¥6fȂТ!˜="ÉCbH‡~DDËâˆbG†pb* jü§.?\É æ·ÏoeáŒià%2 ªÄOØ8§ÀyAB'?‘W÷!PwÒH^wJñäÛ”ð‰z²‰£ÿxó´h¡® òi¸¨Š›Gá”òâ´«­*P‹îsždƒ"9¦Ô§0«ÅìÉnJ ÷½ü±ŒbY¨õ.µÇ„Àì#ðÃW×ôQ Ý&îJ£e噘ÜíÓGžßL汿IU j™€Z62*}Ч@ÑÝÓ*C„6û³A„DˆU4qÓb$ëµT.üxhznbgr_`U*Ù¸¹Æm_iµFÀ†WI:ÈÇüŽhå·äµu¹s‡!n*Z¿{r×›‚lYM#ç ³ùÛ&ÛekäPBn;“ZÇÎŒˆ3èÕîú¹m!Œ-ù虨Œ‰Ñòš|½…\lëBμfàüæ¼ù«\˜ÐEûºòËw°ÿJ$ßÔç×Ú«(LßFA´8:n1„m{<»WåkÚ}4°Jp?f©ÆËõ1.£ ˆ¦”Ove`åe;ŽÒ’GYC Týª‚ "wQƒšT+–=æ›?¥^n]?<Œ½¢™Ê¸dP-Žlg2˜08/âÄÔKR¤˜Z³2Ȧ¤¨Øô2Ë8Íù.A/ãœ5½âÙ w÷Tî+ä›' o ºë숽Þù¹×>vÀdŒú¢^Æa© d¼¨—1Àc÷-½&_oáÔÛºp2f"^½éw·ÉɤßQûÁÔöÂoýÖ¿äõ°å„Q™ØÏÒUùš– ¬R±Ì}ã)£*_SÚ`OˆÔþ"P‚¬bGX­ž½8¹{ÊG,i÷á¬&_ÓÚ`˜äZB9ùbþ"´ÕbÔáN«éXˆÑñ¶jòõ¬:X¥ ük¼­Åš|MehƒíOqÓ¶Á±Sëíõ¯7³«›ï>¾¾}×ÒýCf¯ÚÎÌmÕÅàÖ«žg¦`ˆãñöGkò5-ª v€E…È}üÒ¢·¯o>^}“Î^n×,®y±¥¬Ü£ÍPñšv ªÒ§ˆ;ãíÕäkêBìÎB¸f µ[6Ü$é·*Þî_×Ò„ ý˜ã®ÍóS³trÙ—ùLºp£Ù»*_ÓÞÚ`{Ø[Ø5Ó|³ÃQ®íÂ[ö3ö§ð&ôÓaÖN¼`©eASz€£Y°*_Ó‚Ú`{XÐq–˜¦ ·Tbp“–;ÞªØKšW¡Î½Þ_¡£ßÖÁçãM¢ÞŒéðræô%=‘ñÂÚš|Mâhƒ@j"Œé‹ˆ³lÈ´ëCm~vÕþ¹‹ÆÀnž}ŒÂ“?wãYgnA±tüG#hU¾&AµÁ (¡3ó»´«þ—Çh×D›v¤Žt÷DzcM¾žõÁ°#&Ûê“Eì¥Û¸ç7Íûxë Ük¡¶…ls¼í…š|M#ŒV)CHg~4eTåk*Clÿ(‡ ËR;º=½ÞÙ,„9e6k\öTàþSû 3›­!t?i>ù©¯L­ÜU͘ñš¶Ô…Ú?€ÉR )V)KîI”ØÇ)i]‡Lþ\zá£Y§*_Ó<Ú`؇ D™ÓfŸ®59ÛêúEú¦Áù)…sF(£ÈÆæ÷=µA± XqjÃn<µñeãÍýå¾<·!Ó!D–›Ÿ>ÊRž›×?]»›®“*ˆ¼ ’Û“¨È®Øù‹•W×=¯v"#‘ˆ*é²k•áÀ²ÃO¾N üT^ËÜUýn¯ÈAÈRF”¨Uìnýy‘^¯]•Ã’l7Ù×›Çþ@ÿï,¿_‚íNV9†W¢xðŽÆ“%‹øª ¤¼8?àªWyN$¹lêð×dëA†Ï¡“}>n(È¡î7ž,É;æÄ}H¢`›ª»Ê¤PòU W5”©5©üõ=ÉB~J%»«<OJ]TórøPÞùEêa™þåE~$ŒÇLÚËäm‚@!Œ£Åv^ ¢!·†Y1Âé(odß§œéHšiX$qì¡’ >Nº!NöZ²:ެɫ‹m_$n<mxþ< “ ˜áî¦~¢M¸zõsAÆ77÷·¯ïf÷_ïÞÍ^üZÌ_µQS;›-‹îŠJ  #ÂY•NG¯%ŠFPðÂÔ‹eÑ•—o™ùÝØW§±(„2W žm©&(fjlÒw6Ë4§on|Ù€œ8ˆ3Z&M¹J¦dË«𠸚4"àž¢”tÊÇrJ'P ²íA'ž2.Ó JåÝåD8ÆX×9Ò—›H‹˜¶‰À÷¨Ò³$´WƒRÁD†‹ëv½ŸI1³\ÂéPlð“qùÏG”Ž’&á¦tÈ[í$#©9€¤Ù z›ÕBr¤ùÊ×;/dI¥˜Aiå…0Mf/†¢t¶ ‚cPQ {HàûÛ!{/ñWaí\ábQNÇKyÝëH´öÓ"SUÍÆü4xÁ1{Édù?þ-0P endstream endobj 502 0 obj << /Length 827 /Filter /FlateDecode >> stream xÚUKÓ0¾÷Wø˜H»^?bÇY´$Á m%„!·ñ¦MRòØvùõL2NÚ@+.Éx<¯ïÍHFy»z½^ÝÜÇ Ih¢…&ëG¢4Õ‰$qÿ˜“uJ>ÇÓÛ½M]x- [vv~]¿¿¹7ŒðÔ²÷ŒŒ †ˆ;8qö± nð'Uï²z³^ýXq°a„Ÿs£Td[¬>e$…½÷„Ñ(1ä8XDqF…Ô ïÉÃêÊý³~Åia%ŸBÎYPuPH[[¢àÊÖÕ(Z¿U #lw]ù•µk»ºÌËl4EäñEN® eBȧ×y[ØZΪ‹bj ¯0ÙæCwÍ”¥Ý9ôæLÏÁ1Œî}¹· I„¢‚MIZ›ÑðZ²$XïòÃçeãêÖ/žB®Wol›çì3Bâàé3—¬åžÈMm·ßC ØAH(‡\ SÎ5¹æÐ¥°[¦`¯yPVí‘jUíPý…)æhFo¡Z)ƒüq‰i¦¨‚öNL?T…û˜§™kˆˆ#*e4—Î¥ ¦Zj¢Tò—ôPÁÑST;†,­Cn‚¬+€¨¾¿:òt‚MÓÖ=î…Æ¸”™u˜x9að»;T1Ðq3$þÛf(—÷Æã¦ܾqØ© Põ¬#s_1ú¾Z­åJõê*í¶®Y‚" Ζ¾C¡Rt óùüލ<æeZ]¬›®¼ópô'»8´Ï(â‘ö´M3ÃÄih`êÃä?Ý@áô6.=µÀS¢ÿyiKª¦ endstream endobj 510 0 obj << /Length 994 /Filter /FlateDecode >> stream xÚÍVK“£6¾ûW訊e=ܲÙxk¶jª6§ö0Ùƒ°Q#8³“_ŸÖ Œg“J.¹€Ô/}Ý_Ó‚ "èÝæÍa³Û'Êp³ŽHÄ8Î8J2x' ô<}yWË¢ ·Là,›‹¬ÃO‡÷»}JP ž17žQÊpJSˆk(û$ vîÅ…qÙüxØü¾¡`C½žŽ\ ü¼yøDPº÷ˆà(KÑ“µ<#A f<†u~Þü´!sü)E4Å"‹é,YÄ–*Ùeç‘xì1†9I™ñ"h+N²ƒÃ/ýèz×@”£ÌK›ËÂ!`8£TøXqŠy¹XÓ…9zØRBHp/UãÂ~9 d]Cé°-p ªœ0îPMDXX=©¦Ð!Á“Û«Þ½¥{µ>´Ý •ܪÒýÐÂ1fÙ\¼oS¬tOª8•Þ7¯´Ê½ü1d$¸ ƒnz¼Htý¶Ü3T9þÃL ì  Ž ‚Hº`wwfè­^ó¼¨ ¦qŠ8PŸB§ØÚìÕéÒyXPöïÂ-§äZ±û©bB*fmi–à(hË&‘pñïŽÎýY_ÆÒö/J¨/½_¶Z5®í`£Í‘˜Ç(‘ëú-ăÖõ Z·é+Çïú°«ï7¡WeŸwª”n,#¦…h‚3>o!N²àWÆø÷EáÊ$lßÉs ŠÈIçèŒÚö…Q _ òVÉZŸv®ÌMY¿ŒR¨È–>ìc§š“[^ÚE¨Â†ògjbuÜÑ`þÖ,²"ÐLn Öݺ5ˆ–ÐnªÅ™ˆ]¥ÚNÿVæÃëU4åž 0cï>¤7²syßd¹ÿܯšé¨»½ ¤å»ç¸Råõ¼õÆ E±üô¯ßó£ƒëéX/¹™$ÿIÂéú¨ùZþSŠ4Ä7ö›Ï4§³ƒÃhì§/ˆÓ4¶9Í ÌÞ;j¯u[(Á‡Ûˆ§ÁG—è\@›×*ÿìAùStcœD#6M°ºNã]ÉæTzàÓ¹>Žì:6^ô¼˜êѬËe3’ဢ–ãªW–Ý|•çvxö^e]/™‘Å×n—ÑJ øï.Z¸M26Þ³ìæ=k»´+ýeþѲEM^¿jé¼3b ϹÇtI6hæƒÔÃè³Gå²v›J•ìò*Á³³³]³Y‹€Ð]¹ U£$¯T]l½´ D°7àí–¥Ù|‘ç¶öøe q”„#téö~úYIïDòšåÄ ¨]”·†âk¿ý²1Ô0€ñŸ’ñŸ;D^ý,Üú1Œ€jý›ÿ¿rº¿L endstream endobj 505 0 obj << /Type /XObject /Subtype /Image /Width 318 /Height 203 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 512 0 R /Length 9936 /Filter /FlateDecode >> stream xÚí |U¶ÿ²›úfäùwœ÷þÏÑtŸ: ¸¢ £®€ ²„„ì Ùz©&‘EVEÀa$ ; !û¾¯@ „²v:ýN÷…²RÝ]]ÝUÝé†s?¿O}nWÝ{ëVõùÖ9·V‰D›zÍ…B9„$·ä§ooA¡P!/Áö•5P(”CèÑi2â|ÜqÊR åb’ûbT¶8ŠÈxjÞŽ?´òÑir>úó‡J(µDëêî‘cë/Cc½LrŸIfj¬D¢“6c*;–®øÔœí£çl{9¦rüú>‚’OÍÞ6zά P&%ÄØúËPEY/“Üç™f5:i3¦ÀKWüË'«^ùºòõ üõjLÅ_>ýšÕʤ„[ª(ëíCnÐi¦Ì&÷vÅ¿|ºêWÍÔbu…2)!ÆÖ_†*ÊzûDËÁg˜2—\ºâcÓ×LÜxÕ\A-VP(“blýe¨¢¬·ï8÷,S0t¥Ç°#\2†)]ññ™ëÞÚÔÈ‹týP‹Õk‹ôÄ–Q¢Ë ±™16V]Ç$®¡\¯A^8ÖË$÷Ÿ¡)L•´?åØ(â“aJW|âó“65²Äª5s]6«Ôbu@¸^—ß™|©îZGwOoG·º¾¹3¹ô:½”ôäKés›µ¸¢1…Å–Õ6j; ÓÐ}e%ç|—ŸSÓÚ¥R_nî”þ\ÁÝCf}ßÚ‰ ›IccÕå0r¦¹ 7Tcë՟ñÞ>ä®8Ç”ÙäÞ®øÄ—›'on¤EŠAæ³õÙ´è™´ «õ&•q¡©€]¤`þ×G=WîùñLnÅ•"“¤Ë[Þ ?eVËW4(Ï­…ÐÚ‘Œ‹scŽüšUÑ«ÑxmÍ4Xrúú<`6·¦yÑ7q‹WJȪz3"ž£‡_J÷2%îîµ±Œ§ˆ±é*ÓD™¶ S U¿Ï4MÌQ ùSéå3¤?¿,ͬ¼ÜÚ£V/ß–9okqº·¼¾u.µJÔ‰«­ÝPlņýsd{Þ:ùjDò˜ð´WÂÏþ+*nBD´Û¼¿+2~~ûëEÏçæ)l=ª]t<½ÊÃ|Ùájø™VÖ¸híÉekf—_fVTÕòŸwyvô±CÉÅÿæhÉ açYÛr8³íMÈ~~®‹»?“²«¾Å^iéÒ¶½ãé¡Érí º©åæW²½cÃSYÀ!–Ö\ºÚÙÝÓt£ëÀùËïQ§ÇG&³ŠÑ›ÖÕ­‚’• ík©™¡_ìËØxŠ›¾¡²¬Ôà|}C«Ï4S°:ýž°Öۇ܈ ¦Ì&÷vŧæþðîw×hÝŠÜ6dsÏ„Z¬xïÖúÙ¼Òš/”GÀ£µ¶uuw«DÇ&k)Þ¼/œéÄȤ/Ö¥¶utµÜloºÙÕÚ® Xh¡bç‡Ò£*pŸoÌ¿!ÿjd*4H÷™´ @êû·¢~%s>›.;ô¹ü ÁçcéaØE• Ú#Àæcså{fH,ßxŠY±újñ˜³e{gÇ|}có»Ò8Ö¶Ìܤê¯6}*;<&"½¢¡~*¶^HíêîQëZÛövÔ©q‘ç!¯êéY¬ø÷„È3¬FÈKÊ\³’¶ÁSÙÆDœg¥”·¬û1. f{ðÆCÙeõPr_JÍ‹éú%],cã)blú†Ê²Rƒóõ U”>³°2ÖgZ}î~ŒÌbÊ\réŠOÏÛùþwM´H±Yr¸gB-V^Sä€UßlëØ«õDëö&ÁtÛω×Û€`µ_ô޲ƒã£RÆDfH©& O-YLí˜!?<1êô•­‡R|ûNTü¸¨LÒæ­õÊcé¼µuRTÒìïKÎW¶¶´w÷öÞÚ®ÞÞÞEŠã#Sà ¡-¶r@=1êÌy&³"„ЬÀ|ùîW"ϱ6'¯FË·Ÿ»%2EÕ ^ŠíŸH7è|®Ì“#¯È& ojÛ›ÒÓ¬tQDðªsäp”8y8d}*;{€U4O±÷+ù¾™²ƒKÖž€’pdû@vâÅ%Z,cã)blú†Ê²Rƒóõ UxŸiãÑyƒ}¦Åqß²ÙäÞ®øôüÝS¶41õÕÆV-2D—ZúwxfT6CáÚúÆ’‹-K¨å¯]¸¬ÂVÕ{QÛß“žz)*}Ææâ.•úRcë•Æf•ª'rˉÉÒ¤±Q™{Ó´Cà„syïÉÆDe‘ƒNšÄÌ×7kñQþ”>‹:4?æ YäMm}Sz¦RçU©ïö¿#•ññÆ"fÅK×µ#×ïY¨Øõ•"´”Úá­ügmKÐOÚ")½ðÐym¨üíþ¤ÅÔÎw¤ gËšIû“¥‰¤ñüòºeÔö·¤I¬RÊ[ ¹Àà;ÑÚ¸¹µ vËiªþ®›,K‚ýðRäù­ÒîüŽÎ.XÝxé¹;ì¾e–±q*³16ýºLƒ46ß ¡ŠÒgšŽ>¼oyŒ4—)&¹!!–$£%’ZÑäÒÿºpïÔ-M,±v#ôUj±:Zw‰”ßýKÖBÅîM'JÈÏñé‹•»&IÏLPæÕ4jO Gl9!ÿþ(8ã+×Z¦D§B݉1u -juï‘ÔòO6¾¢ÈûpCñ-è”['ËÎ0óÄ­Þ7ÿ룿dTÝ^´ )ŽiA+ª¨ûrmò»k Ïêð¡+®þEÛÃì¢ÊÅkŽÍýúXôÞsùU 3å‡&Éΰ¶eœ,·¡¹ýF[„ýñRîøBñóDYêÂйœ’_Ÿ9˜u \øš'!Š~KvëÂ1Ý‚kK?ùAtò·‰Úáv\j¾õÃ$Y2«dzÕå{ª&¬Ì{ua\¡Ö×'eÃñä-Y²þNvh±Œƒ\¦ÉcRWô>lõg[oreyLõõ¹–´Ø&hõ¹·+þmqìß_×לM¹L±–B-V@Ÿl.%ñgÈ7?΢~žº*]¥RßøŠÚÿ†,õxžÖ,7ÉZ¢Ü5“:¼ñ°6N-¨~Y–Õ§D§=s©á:8eUOïõ6Ui}[JN™IyòoxÊ“쨼Ðp½§GÝØÒA΀ы ­'ó®5wu÷T\i—®a-](«®þj{—ª­«'µ¢5àÇ¢'õ·´1¾ŽÔÝŸ½”Úù¾<á]?×)¸Ú¤=Ïv¡©síáüeʰ-¯Ën]ÜùŠ:@·°ê`þ•kͰÀ×ï>Sí½r÷üþº¹‚Z¬½­HñRþÛGùÃЏñЬ‰ò40låö'Ç˳ À‡ŠøÅÊݳ©ÿRœŸQGÀ¹|N'ÏIžÿ¾"i»P¹gµÊ@0¼PùÓ"jÏdÅY¨»T¹ š"ùä¿,Sî\D힥<ô¡üoíJo-zC‘áààIýô9uôÅÉåÊ~[*?ÿ%uhõ#¬bup¦âØGò“ÐO›#ËÿŒ:æ­ÜÕçRû82ÿUyÖÔá%Êç+÷Í£öÏRüüž"éE.«‡ ×äÙ°iºÍ‰C˜£ØÿüÔy†~É©S³©ƒ°É_Qçê ¨8õº®ä$!Æ&®¡Ú¦Ï´ú«(ì£>w?–éë¹tÅg¼OÙtù£­Íü5eSý?¼Ž°; Ó+TÞ4*~¦âèÛŠäqŠ‚—Өęԑw©ä—yP`2uîSåÉ)ŠÄWÙðs‚"ó#*î#êÔTü„*i(fP'fRÇfPÇ>¥~™¦ˆ]¡]:•úõ3êèdE ä_SäL¡’fPǧSÇß§’>VÆÑ‹@P~ª"–~ª8ñuVÁ\ +B%N§NBûSqïP)¯w†6g"•þ±®î4*a<•Mχ`3§+ŽÁÚ[è ™Ïì!]rª"a:ulºâøTů¯+²Æ* ¿§8ý©®KÐç÷‰ä@g°WŽ+!Æ&®¡Ú¦Ï´úK‹¢ç‚O 93uóåO¶5óÑ´ÍõcBN?|F¬ î 1¶þ2TQÖÛ÷m6%¢h¬²èùÐ³ÏøžxÆç8/ùž|>4yU$VPw„[ª(ëíCîÊ2 åb’ûRt9è}O¢P(»á”E.Ì×`„É^“D"!ð$· ' …BÙ›6¬ŽFrQ($…B!¹( ÉE¡\>z`ÔýwùîÅ=€r risµÝÚ3H.Ê>ÉËdÊJvûøcÎ:ŸÆš™vöÌ Ï?w.ùt?2hr‘\”Ý’k»ý`êû²ÈÖÌà¿/?›Ù¿ÞÉEÝIäêGËyYþ>ËÿöÔèGþŸÏgLÏ8—bV'ìÛû¿ý¡çädœýÄã'Ž6¹–¿ÿíé£_+)’90_Drm sWú?öçGýÓÃsgÏ‚þ£í¡ìŸÜ° ·Þx=îÄ1n§üÑBÏyæösò›ׯYMÿ§¾ÿŸµÌýêKâ¯Oýòðÿÿïó)É—F„>"’kl™»bÒÄ7ãã@ñõöBÛCÙÛ8W?óì3?~äÉŸù5þ¯£Ÿ4·Ÿ»~ØöÒØ1ôOáÆîÙÍg-ßn\ÿñ´i ð{ìÑG”r)ä?š6õ»MëÍ%× ¸7¹+ŽúÙbBõ‹Ïýï‡þÀ´öøO ºúêËãvnß ™í[¾}cÂxýÕ\KzêÙ§G?A`ß²yãk¯¼ y˜cnÄν¥Æ6¹+è“lù¯‡DÛCÙ?¹Ïþãï§NØUðžoOz2mnûî[ýÕ[ `¾nͪ—Ç…÷ÐÏèsQAnÄŠÀíØ¡ƒ9çˆ%᫹ÊÏÎüçsÏ®Š^ùâ?Ÿ7¸:ck8yôãE…¯€|dXèè'ô—\c«fî ª“q.d|¼–¢í¡âÜ2€ƒÁ?þáAˆZÁëYÖÛÕ1+ÿðÿXmì¯ÁµÜ¿j%'ý ùäÄÈÚ¿O\r­ZÿÜò#ÿÏœY_d§§¡í¡ð¾e¼ …äò'—ã\«èfÏ}j×Ü ì’‹BŸ‹>…BrQ($…B!¹(Êbr¡ …²Cq+Á„ “'cäbL‚BÙ³\ ÉE¡PH. …BrQ($פÑhT*•±o¢uvvr1ÍdãÜÕõgöööBzzz†Šæ‡Br©­­­Èü”““ããããááÁÝ8Xh$ùûûr9–¢ù¡¬Mn€€ÔÚÚÚ¨V«- 777È5 8PcäBu(­Àf’Æ ¹Dó»«$"ý{ù“+‘h´Nì1€¿ty9— à¯æÍõòõ™»hAH¸ÒßgÝbÏ5þÞß­Ž>äç½iÉ‚èÕ1±sf…®Y»liØ¢E~ü£e ÈÍÌÌrï¿ÿþþ%W?Øž?>÷O³Æ–}s™Oã%ˆaú½çLÝg*™K®e7]€Á$WË­Ž\ÆÞ 3LÁºÈù“ë8ê¡ßšòn}ó5‰ËÐaCG»;=}dz®’ÇÝ>æ2àO÷ }ßÈ'%’{G ÿ¯Q£–H\ø“KSÃ'ۉυΗôMÀæFÒÿi¹…f&þÿ&Ù|žÉÕÕ•dø“k½ž³È¥[ÈÏϧ§$YF®ÇäZœøú\Y„ÄY²ÿäÑ•Ö:¹WÕ­éíÒ´·hþó?^ìúØý÷ý¯Dò@]µêž:ŸV.‘ qÄë ‘?¹eeeÙÙÙ@î!C\!䯛™Ì"wœF¢ÑÌÔhžíèHª­={éÒ8ÝOÑ<™™ ’ÜÞFáäÒÎÈ–äÒ§J„Kª››øï1ïÐ@߈ÐyË—úE®X¸Â×/Úoù7^K¾ð]²ÅsNäJÅŽ…óÃ|—Sþ~òÐP¥«ë0q£ešn ¦@®»»;’+ ¹IIIt>A—„“ûGP}JÇé_ººv^º$¹ý˜Ï‚ŒXäÒ²•È5¸È!Ƚta‡Fº¡Quj47;4Ý]š^µVà»:5êm~vwk‚‚ä‰ÿ3TfEËJKKí6Z6¹Ïyžûb‘K©˜Î…åeìÊç‚MÇèDœìC±±Ð½g’“Þ'32â3Ç€ # ¹¬á-’ËTØJ9{£·»®©¡K£é©57Û:z5PG‡¦·÷–täJy’«R©Ì==[J® Ù¹ ”˜“ÈzÍ%—…*s*¹d0Kò Vs£e #6ž4iEë‚d`vrFÆ81¢eƒç¦„“KóéŸôñÓ±È]¼ÜK¥Ñ´õªä«cš»nú{ÍñœÙ«éôZ¾Ü×à]ºÌÛÇ72Ý*MPp¸Yg¨,H@î AƒÄ"—Ìîsùëââ"œ\}l-#711‘I(ôùÓÃÃCH´|‹Üï¿ÿý#—v¸’ÐЭ[·ÆÆVÂL˜BæÐK’+úU!c!±¾«ur===oݨ• €Ukn\k¾näæÖk@îÍö6¹ê àP‰d •¢eHäÜò¨Q£,#7///88øw¿û]kk«>ÔÖ&bQQÈqœ;lØ0’9r$L!˜©“““ rO…ÞÒŒq@kTÔE˜ S-¹3ÆÑK…;xð`Ÿ KE‰–ÜÈðuW÷ź À킞 ϳ.Õ(”ò ààÐÛ>W ?%$¢ø\°vý™ùùùû\Öݶ'wĈös†ŠœU¦ …­¦§B}n¥ä–IˆÏ}æ™¶[>w‘„^jŸã\:Z¾|n€¯F­%óò…‹+)¥»»û§-­-k¼¼ý t…ðø¹=ª @žävvvZàsac\“Ucäқς—>UeUr]]]íçªP\\ )ÍéСCÉø÷Á-Kn)Tâ«M»%’˜BæÐKíóÜ2¹7Î\Öq㦪£“„Ë®5µ’lg—šžšK®eã\B®Å>,E.Œpmæs-ç:â¿‘› ‘„ôU‚ÈäZãz®~´Ì:Ûì(äF„…Ï›3WµtéR?m Ð%—ËaP̳ٖ– È-++B®¾Ïež^FrE!ׯw?Tñ*kßý‚’ƒ >|¸››Û# ÊÀBþ÷Øž\Ž¡®¹äò¿]?88˜d`òÜ3Öû7­M®UíÐW…lvßrkk«7Löï“õV½*nNÿ?…¡ÇI*þäB<<<`:lذ!C†pìarXƒbNNN<“Öû7{,MýÞsÖŠ†Oæ6HWË’Åä:®nܸa°ä$!×äk+8Â6ˆõMƒŠ‹‹ñÉú»Paé.|›¥ÉdØÉ͛ƖÞsÏ=hÌ(|› wd5xð`wwwò((¸BÈŒ1‚ùd($2ßÙÙ™Ì'aª° "X˜Ž9’ü„À(žDYduh~($…Br‘\ ÉE¡PH. …BrQ($…B!¹( ÉE¡\ …ä¢P($…BrQ(‹•ŸŸ_YYY^^^ZZJîÓ>|ø…  S[[›–––›› e ÅÒÓÓ›ššŠ‹‹+**îà}Á_&Q´+r ö°ßŸðEY ¥Rrîܹ!C†Âð'‘sРAÕÕÕ111K—. ƒbä埗¾L6nîÛ0H:{ú¬=“K÷ÙIƒ3EήNw-¹àR ­NNN5jÔ™3gÜÝÝoÞ¼ fÙÖÖFìS.—ƒçíwr-~løâO®DaLLrÉɵ1¶$Å‚—Ï_‡Å߃pËÏÏú®6##ÃÃÃãâÅ‹ð&%%‡ Sˆ ÏŸ?DgeeÍ™3‡Ï&y8ݤrYµ“2—\ž>—>&ÜäZöú,áä:K\»xØÆÀŸ+\ýá•~É—Ë`[PP““ü–””À0¶®®.55PŠkò2"öööæó6ífZ” pvv¶Œ\nÊH-Q|.“\Ö‘ÁbruÏ›"…œ8¼ 2ä¸jÖÕªä{)%ÿ×þ˜%W‰ !W;Ãí´(}ë~d`öÉ ôññŠeeel~~~UUxU¦CZa?§¥¥³€v^^ xÕjµÝ’Ëáp- —Ïë Õ½÷Þ˽.Ô@û°ó!õêUòÎa³ÞüÀì!3#0T&äVöMV%—K˪ä’ù¢+âÁ××—¼»ìOc=77ÂfæÛnùKÞ‚k¹GË¢“ËsœK¯Z Ï%mª$Â) ÇX7778ÆÆÄÄØÃø´_È%ö)¼ÆÈ¢Ý¢rY³œ¯e-3Éåvè¶$÷÷¿ÿ½ù\z½Gèk,©T*zX a‰‹‹ ÿ¯SÝIä`!Ç1ÑÉ5öV±ÈÕÓ¾Xäsèâ’ ^ƒd~{e¢x>W?‚%'~­4ÎËçƒÜä‚Ûõðð #gžgó „½†Ï©$“ œ6ŒK{^žï@æC.ëcÂǹV%—C·†Ï…bµº¤ý>šxѲ>¶f‘Ë$ëI4Ÿ;hÐ îhmTîîî#GŽôôô2d²,¾ˆÆç¿¶%¹´Ãw´Ë"Wÿ4v-ó9,X)ZþíÜÎmrÁ³–YØZF.gœ|‹\±|îàÁƒÛÛÛ{{{9V ž¦°¢„„„eË–ñùÆ(÷W8øy’kìs¢“Ë¢•)!ƒö/ú¹ekœ¡êGr­w†Š‰­ýû\²EÜäBøËÂÃÃýüüÂÂÂd2Ïh™õywú;Ü|ñ'טË—\B($cðŠE–1ëÒ>1Bý;D$×fÑ2;ë“{ï½÷Úù¹ekŒsɧm˜™ú\Q>ÁŸ\c^˜HÛÛõ\z/1 Òâý`›3T¤qn„óóó¡Xnn®½]²åõ\«žû%»Ëܘ–'¹6»Ý‘›\!n—ž”(»Bో֒%K …ÔÔT@Æ„C×¹H€+44”ÏJU*•AHY¶qg\ϵó'Lž¡²réK·Ÿu¯õâ+‰øÜÒÒRòy5c=''‡Üý˜ÔÕÕÅgWZšÜÜÜ,#—ÏCywá}Ë„ÜJ‹’˜«‹‹ Þ²qG»$âskkkYgè”——Ø‚·­®®.))ILLäésÉ9r$ Äxà2|3vÌ'“¢6y¾Ô ¹¶|VˆE®?+dð¾b«HQ¶ñ¹f}"–§ÏµöS~|ž 2&Ñï¡å‰Š¿¢¢¢^OOOckHHL½½½½¼¼ dDD„L&ë÷ã°¸Ÿ¸ñá_$eÑ7ÑqÜ+ËšcWçñ=T( ÉE¡PH. …ä¢P($…B!¹(’‹B¡\ …ä¢PH.î ÉEY ‰°dÖ*®ç($מÉå~‘£€äÞ~ÇQ€_KBz>ßç­s))üZõe¡w!¹xå2ÔûÿƒCöN®u|®µÉµà¡°[øt¾³½C£êÑôöôôt÷jÔ «×µ/"nmר5ZéÞÄÖÔÔÄ|;q{{»íœ?¹ –¦»ÜV‰Ä ìœÜë|$Ú-rÍzø—?¹ê®îÊâÒÒ‚¢¢‚¬üìª Õµõu9¹ùÅ…%UÅUYy…ÚW[ÕÖÖæææ–éRbb¢\.·gr{u‰ðÈÌÓ©W/!¹û_ÛÄ9¬ï7‰ògéû\æÓ|Ü?û\p©E9y%ù.Ôæå¼‹½—ÔÔ^ÈËÉ¿R{åbUݲ%^ÛºººÒÒRooïââb///>=ñã¡ès­G.ÌW]–0e¼&?#äC±äÅ-ÂǼýEn]t4¨j×.äV•T——>Øpý*ø\ ·ªºöÒ…ú¬Ô¬ºŠšˆ°H`Úo ü.[¶¬   <<œ'¹¬×õ›<æµÏq®Þ÷=ÙŸø$ß÷4ø‰O{8,$W[sá5øQÖØc~ÿú\GË,l3­¶Ñ£Kãã-$WÕSVPT^\TUU:¡²®ÊÛ9[QVY–_––é½lyMMMJJ ¸Ú´´4Š¢ x~ùû\“c™Lnÿï{’/BêÑ%___³¾òi3rak¼6ó¹¢ymìsR,ñ¶„b€×bŸ[[^ÙÛݥѨ»5ª7{4ê›m0ɼ%+¥”Ÿyy98Ù¨¨(Ÿ @Ì ¦Èßçҟ˱ ¹Ö³"ƒß÷¤Q¥¿ï Ö »xî.‡&×f>WDÿk{rYA2Ùbr3RÎizÕÕÕ•ù%µõuå5Å%eõ/‡†ç¦gæ•ëÒ¹sç NnllLOO—J¥æFËäB•íÉ%þ”+ªÑ½‡“?¹úï›e~ß“Ë|I&kú Ó]æsü[>æíßsË-&ñ¹Ýíë¾^ÝÔp¥²²Ü'Ð×7ÈÏËÏ;$4¬¨ X* ò  W²bÅ ð¹ÁÁÁ‹/¶ÛhÙzäü¾'säûž´ÏuwwçïsÖ¬Y%½¼¼üu v»±z{{ö¬Zµ F1èsëÜ2Á¶ûþû-ç:I$®ƒÀçÖ×_ÌÌ˪¨­,(-,+¯¬©ª s– (q2ø>7‡‰–[Zøüúß÷d†ÊÌ9tœ <rM~åóòåËmmmô‡Ì C– ~˜\Ìêîî¾qãÔr'†AlGzHìíܲ£séÔ8c†¾·5—\¢öÖ–¢¢‚ÀA‘Š(ð¼r…|nˆoˆ»“›=Ó_Ѳi?k‘Ï%ß÷d¹ Öç&œœ ŽsMåÓúÑ2ÍïHÉ7L¹:³±u*1÷ªƒúÜ~‰–‰Ã…1¯prÕ] —Áá‚ÛÍ)Ì-(,n¸|Õ{¡7ø\äöK´l%rùßS?ÙÏÅb}rAïÄpÜqn¿øÜª]»[Vœl¹šUiiñÂe‹d+å¡‘+üü®¹®ƒ…ûÜ;æÜ²Åß÷äù•Ï~$—‰°žËÆ>W¬û™û‹\}.ŒsËËKk.Õfä”×T•\©oX¾hù÷;?Z6ÿøïèwRYƒ\[ú\G¿où²À+ð*šÜ²²ß ?ÐòŸÀ Òâ²`Ÿ`‰“@r-xÄ ÉEŸ‹÷-óÔÍæë••å.åçWÖUUVÕäR”Û—~yrÙ>£å»áY?{ö¹wÌ}Ë"’«Ñ¨ýý}—,[ìèìïï¯T¬\â¹Hà*|>÷.y²Þ>×ÏêÚ Z¶àhf¹Ú­8@2ðöµZÉgÉÝ߉²Ÿk1¯ |®eßIÇ·Ù îŒ÷PY\ŒÐ\ …ä¢PH. …BrQ(’‹B!¹( ÉE¡PH. …ä"¹(’‹B¡îlr-¾;·¹¹yøðáBç¾7ïÄC!¹ÜpßN%FR±¡äïïïääÄ¿qV puu5V–š~É …äòHEEE,rM¾Í†›\âs9–¢… \áäêû\!äÞwß}èsQH®íÉ5éÑç¢\ë‘ëoi2 —J¥"%½›‹ã¥^Æ C A9:¹–½ …O±µ_ۄДãÅ­®®®¤êÌçnÜÙÙÙX›Ðy[,”qÕ%2“Ì!KÑBPw¹«W¯6—\>U„\â-ãU!’kÒ™²Þ™Ï“\‹Ç¹...Bƹ#FŒàçšl…r r¹_Ä\jÿäâ*Ô]B®Yï³¹Ï-;99!¹¨»Êç®6’˜KíŸ\nŸ;hÐ ´Ô6Î5†$­Y>×â«BÎÎÎ&çþb Gô¹¨;ïÜ2’|g ƪôc ÂZ˜º¹¹‘ ¹D.☼*d¬ÍaÆ‘¦À·2/9é¾û…W…¬wUˆÏµøªÐˆ#ÐBPwÀ=Tæ’˳J?Žs|Žq®Éà …÷-óL¥¥¥Lr!ÖB.TÇsË($W8¹¬'šô¹Éå~>ÉE!¹ö-<ŸòC!¹¶V¯ ¡Üþ"—\:t(ÇU!r‚[æõ >n8® ‘Ë@ÌËLôºÈ…*$…ä¢P($…Br‘\ ÉE¡PH. …BrQ($…BÙ-¹Ñ”…BÙ•4 rñà†BÙƒØ «£IÉE¡[$…rPl‘\ʱErQ(õ¶H. åXØâ8…rDl‘\ÊA±ErQ(GÄÉE¡ÔÛ"¹(”ca‹ã\ʱErQ(ÅÉE¡[$…rPo‹ä¢PŽ…-ŽsQ(GÄÉE¡[$…rDl‘\ʱåI®&Lv–›øÖVÊe\/ …²[NõÉE¡Pö/&¹G¡PŽ"ÀV"‘~Q(”£°ý? ]¾ endstream endobj 512 0 obj << /Type /XObject /Subtype /Image /Width 318 /Height 203 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 161 /Filter /FlateDecode >> stream xÚíÐ10 À ø7ÝyhŸ –JÞ¥O?HÁ!v˜Œ4” endstream endobj 517 0 obj << /Length 918 /Filter /FlateDecode >> stream xÚUKÛ8 ¾çWèhµ"K¶cïm_SloEÓ],Š<ŽÆj[^[™4ûë—弚¢ÀæQ|ˆäGÒ¬e‚½]ý²]­Ÿ6«xUÈ‚m_X^ð¢RlSÁ¹IÙvÇ>Eǯo»z§ãDæ"êëáPwñçí»õS)X –…Bˬ”¼LKx×¥ ô7e´¦Cåh²ú}»úg•‚Ž`éŪœ5ýêÓgÁv {ÇϪ’½fÏòTp©  ;öaõ~%Büß;i¾á¥Ø°L)^Vº÷\ÀO‘Êí…J”þ¢d¹0×ôŠýfÁíûo$‹‡äÊÅ·¨Ê\rUf,’‹TBO¦=LUÅåOq¢Rm÷µUM:ÜþŠ3™agc™GGå}ÒL•¢•7YNnþŽSxÖ覈˜÷á)³{³ÔÙ-q¸s Ç‹>Ý©öznŒÓ=QÆ\µ7[¸qºdÈ1H!I7¼R’Âþ8C›uèìk:^¦º×Dú€/’±tGdcW›a¾‘Ïæ_=!„oð®¢ÙÿäqÁ÷^œ‚®Ö·¶vr‹Ò•·„Þ”"JŽf×j<În:4*Ë¡ ÙRÐâ $PåÞNz »;§yôõ GÊ«¼3¸×¡p§¥”ƒž]¨%F2/Er{3\óÂ{é •¥Ô*“ÑPcB¯¦ó¨v𤾾(}5XbŽ“ž5 íŒ ¶ˆJ À‰(Â…¤”=r±mÓÛ졪È"JpÝ‘N $ÀÒuõ8SJÈÛäÑY¹±c Éœb`†÷šCpkC(“î-úxÅ?}ƒp˜“PÄ[´Â¨þŒ±MÔt¦ù‚daÒÈòãwÓ,84Àuêf€@eg汫OsÐ#ƒ µ£žœÑAàÛîúÅÆN€þh‡ZbéNÃô¹Ìðƒ¯̰Q+AIBPöðÜ=D(¤¯¤ôð¬ñP4˜o¨ßw¦îlKb>ÈÃxzKR}ýˆ1ᕺ ”á „•n¬¯aCÍ˧Ë?èB(3iŸïã¨kìþ$—›èWŒÝ£…2’¯2šL»wôÂ3ÎÀÁ¹%PߨA÷Áhú>¦k F=6ßkMÇhÇä0^¾—üá·|9ý¾¬ ¿mÊ’Á§ v,ìµ"ç2KÃvÊh;‰ï.u™).dÅRØQªH­u¿~.ßò—e9ÔËÆOõþ[ó™ä•ÈþÏ–ÿ¶,-Ï endstream endobj 507 0 obj << /Type /XObject /Subtype /Image /Width 308 /Height 328 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 4950 /Filter /FlateDecode >> stream xÚí/ŒÇ€8PðÀƒ>ðh¤ZT=éV èIwRAt 8YÑ© Š "¥ R *]HdDÖ'ù@¥+ˆä‚H00(8`â÷[ÿ|ss»3ãÙñ®½¶¿O?9›ñììÜx¿Ù?ß=¼“@Ë8ûãT^b×âŸß›¶•ãÇj¨Ôó˯žÄN…¸9n+·Üüï‰{YÖÉ2éJeáôñiçQ'ðzï‹{ºAlb¨›ÝWÝø­éü.7ŸIˆ˜ÓYˆž »]ÑS×"ˆM ãæÁw‘¡®5šßáæ×Ï$N¯ÝìD¸)½§®ÕHÜŸÅ×ÑTØn.ÜÛM¶¦ó—ÝüÏýçUûM]«‰˜L¦ÓOÓÈÌãñäê¯Is•i::?ôúöýQv†ïÆÃ÷W›ÛÂÎ(¸>,»ÖP~Ÿ›r iÎ%gšz>*¯K6ÎñIwðçxòq¢²_}œ ÞŽܬ”Ù„l«|À‘°®þ›Ã3)ðèAwA#<êIåŸýr9÷ôqOÚ!ùJ<8\oÔת¹›õµL•¬ÓÍã@8\û0öÝþðå×UìbÍCn~{&!ê™>1Ðcj¿*¯ºVZè>)ô=ùùòÉÓ˳—QUßïqEUÊ|Sǽӟúó?y¶|ü¸¿Ìe¢ûzxöjxùfüüÅ w> ä”î)?"™Ï‡Ò ÉTbm¯7º|«®¸’ËDÁÍÑûQ Ê®I¢ÏÍ…ùµLgþ²›ß|w&a”4’zÜÔÁoG×’ý0_凞,_¾Í–û²,¢åÞ=í϶x%ýÈÑIîãÙ«|srÎkþz¨…Bw YƒF£+µxüáêôǾf88ì^þ1’ô‰öº³Ì²iÍu5yþÛ Pš3´p;eôáJBvÙ¢¯Lg¢ Ñ\”<ø¾+…H ø6-%Ù´¼šQUÿ«u–u¥|Y0›#˜ 5óaÆ_Y.ÔYú_é\&’ÿÅ@—íu}u6õµªÝ€º¡øŠI7zeï?Êø ·+iþR©•$Ÿô -PH7QØQ nß 5lËLbÙ5“Óä±Sœù …Û«ÝìJDö›:ô•W]ëô§|;{)–uó&½^ž|”¡Z^²tyâ«¡Ø*öÍa¾–uô°§…âzgèÊ'xöbØyÜ×Ýxüa¢zÿËò*oårÍ2=èÉŠR‡Ó/uÈzt"^te£ã¿&Î å5™»y{ëy+MÄ,g™¾ ™¿kœï¢CÉsü¨ïÛtÿbd7‚"•9ø¾g×AóH9’(ʲ4£4‹¼š¦¾Éÿa¢-#å˜e]×Wg{£ÎVµ?Žª“be7F88ìé³pgËÈù¯®(›³+VN7QØQ nþhØâ˜Ä²k&§Éc§8óÇ”ïpS|9ìFö›ú®¼êZÒbù¦ßŽ¥ýõ0x9ûŒ$ñ@öºCiØž~¸¹õO/óUöæ‡ÐY ’AÆ´š2ßfË2Ô”†•Dù”5E?å£Yù&³tù®u1:xÐÓey5…øb¢Ÿ²VÞYæÂ I›È±HäUòø6­{‘ù¯ì6ÃwWv¤eæ5œýÚ1å²Ïm¾÷ÚùµA>Ý^6޽Qg«:–£+öì·ž¶Øå*ã,ÜÙ2²¢nHþN·?{G-ºùf qËëD‡k×9M;Å™?¦ü²›Rm‰È~Sß•W]KB'ÒÒÁåG­?Çòt_ åèg2ôÏwBéJæ)ænæ‡Óï{ÏšÂ5ƒî ²ðäé@i£yÓ‹›šÁ™yÞeXôÎG¦¾P7íS ¯Ì´ •cðöJw'ý¯ì~²–ë`– Uu6‚oÙWg{£• Œ©X÷|Þkºº¨ŒoC¾–ñUØN·ÃÞQ n^þ~©a»cË®™œ&âÌ_(Ü^}¡›UûMó'kS‹ŒÒÂb¥®dX¢ïÏHzX“3ÓÚö§Vø|M;K™²pô°oFG7Dm^>œ¾ò®j6²’£t%AÂn:ËLÛP9t䦨ü¹^öí¥Ú=É€3oÕG}íž"õqÖÙ±ÑR«Æî«Ø|¬ûf¬Ûšwmþtîk©§³ 鲺î?…µàfÿ¢ˆ²k’è»´0¿–éÌïpóAÞ—Uî7gkIÈy¥¾õäçŒZuYõ]9F‰ª:Ú¹äÜAåDC¥~öù‹¡ÄüX7[eÞÎò³6=GÐyI”%}0S[^‡zá“fúR~Þ ç#Ùúó—Ãg¿´ÙyLm 1wÓJ1[÷•éÛPÕГhùÛó6üu4\u0Ëg³ãžô¶Ò˜:–f ä·—u.lÔÙª1…û*¦§6:|ͳS3ìt7 ³pgËȆDm30ö¥ôíýÊÞQ nöÎ{(»&‰>7}ùu»Xó߀›zl±ûÍÓÇYçQf¿fÿʲûYömfúM]KâøÑÜÇã“KÓ’(oéR†¦²¬#ÛË7ãùæ~ ß^Í/ Îtòáê[Úβ ©!Y«¡çøy1TtÓñ‰É¬éÒ#k™²¢lÝ.ÍÓùÙÙMJ!¿³LgbBŒF9pÉB~Yûb䬃½Ü}=ÒÉOÎç7Na£¾VYöUL´Õ rºúXá“2ËŽ–™Î/#Ë[ù.çO—×뫎ŵèæë^ ®5“ßçæí~3+D.æE¦ßLÛ ;:?æ×¸dˆ%¯z[e¬r£ê…h¸d%}GÚ𸶛1¢Û®5—ßáfÞß]Þ>ß,¹ùíÜÍ›~s¶±däã‡÷yoµâí>ùyØôFe2<–.õìÕHF³Ó®ñ’•œ;XÊéK÷Ŧ<ë.Ç4‰»ÿ¾«æÍî`f…amöÏ™ž÷3sS×"–ÑóÙ/ÃíÛèì°s=pý˜‹¹|%Ï^Ž$Ê9}é¾P7Ûö­ê²›w¿8’ÿ±öpº9€uÏxàss ëÐâ&nnà&l½›§Oc‚psõnÎ&9 …~¹†Ïp7p3f¼ãæ2òšu Yf]€ºÜ¬ñ¬°ÒiæB7õÝd;jñ`½n.Ù¦ eÓÜ4‰vz ±P‚ùªl¡L;Ñþox]çv¶ÛM§e 6ù”ôI“¸0£_Ø7ãO3“ݬůÈÓ̯ÜtÎhd„*Lbt Oˆ¤Ñ„›åÊ4äfyC¸ ô›‘—bj—FÊŽ›°knš‰=ÜlÕù&n–¹é¼^ßo6w¶PTÌuZÜ„æÜ¬ñþfü˜6…ãR€­q³€¹°“n´ÖMû‡$|›°ãnÊëŠÝœ–î}øà#ƒu3ÿaëëÄUº a7íDÜÀMÀMÜÜÀMÜÀM›ÎI'9&'|Ü€›Í¹™ei6ûqÞ¬³ynp³Y7g¿œ»iÒÍrAÉỡä“WÜÜlí˜Ö÷<íŠåms³–/”‰bÒ ¦v¸Ùz5á‘`h­›Éï6á¦ókÑ>‰Ê’¥ÃMÀÍø~Ó7#e9CyZƒª3à&àf%7ÃU7¡mn¢– 3Wãf¥™-«~½7aõn†Ù”~³êìyU]ÃMÀÍÕ»I¿ ¸¹š1íÔ…váô˜¸ äfÛîoà¦óÂQšbíw“)È`7ݬ÷™=ܬÅÍÉÇI¶|Ü€› ¹ €›¸ €›€›¸‰›¸™@ø²-u7eô~äŒüvç^æË ïîïï³on®ÇÍ,ä&ý&àæºÜ¼ó·;ô›€›ô›¸yçéÂÇk}ïîV¹ß¬å7ë›8&ðÈ"nÖèf-_(ËöBÏÖʨ5ÿgï: {ówëòb½ŸoÕ¯~n®`â¯e¬ O4]ø†u!Ñ™3Ü©•·ë|Dáäœ-?PnF] ºº¤wXœ;vaޝ…Ó|ÅȘ}(rrÎJGÀÍ6»YõZPx¡iÒ B §šŸÈˆ~7kt³é 3Ûïf`L; Î̉›¸¹®Z­½ß,_ jÈÍøuÓ®s-7Ûéfò=”% aùóÍ„Ž7qsSÜ ÜCÙÿlÿÖ”,+gŒ?c&¶]åuÚ˜M &nÖåæò÷7—9ùÒ«¸œ¸n.¼p”¶bò÷P÷P¦IOû4=±s—áæö¸YýyZöyÀÍõ÷›¸¹&7õ. ßÜ\‹›5ÞCÀ꼆 Åûî'•€›÷›¸‰›¸ €›¸ €›¸ €›U)?€›kws~W=7[éæþ^…'…êú±•ȯ€±ãæºyó4Â^…®s5nòì=nî´›{™ N&®ôÍD¿ ¸{²™UÓ3~âÊø©‡p7q³0 ½ÙVw³’°¸ ›èfÓáë4õ‡Q O§ic:Ó„).q7w­ß´ï›T=묫‹ÄMÜÄÍ…WnEôÌ“œon6"fæÕ3aL;-ý¶×i7ÓÜôö¤<&¸¹7}cÚ½ÎzÎ|™ß7wÞÍ›q¬ëWÖ¥'à&nÞœfNýªŸuà&nâ&nâ&à&nàæ»™m&X€›»àæ—_ŸmVà&nâ&nn&øU£…›€›º™v²6|7ÄMÀͦÝLX77Ûæ¦æwº)Ë•©šß·JL9…<¸‰›íf`R‚ rÓÔ7qs7Ý,(Pþ¯Ó—JZÙÿ-¿Òoâæ»YžSKtNJî7mʉ>a69×,7qsÓÝ4W_ÕÇ©5H![š›¡*¹7qs-n6¾1­=ÃOa|é¦sÔŠ›@¿¹ä˜vy7c´ÂMÀÍJcÚZúÍ‚åkAËŸoâ&nâfüùfüuÚò7æöGá:-nâæÎŽi}“Çò\àæ*ÝŒ¡v7[iºÜÄÍísS¡ßÜlÚM±,-pp³åà&à&nâ&nâ&nnn›Ì³¸ €›¸ €›¸ €›¸¹énòS›€›-tÓüZ.{ àf ÝÜßÛ¯°JðÆDüm‹…9¹‚›;ëæÍïËWùùÕ¸éüÆ7àæ®¸¹—Ù‘à”åþΗ³–ps ÝÌnúÍH= s#”ËÓž &nâ¦s@{3²­îf%aÓÜDLÜ\¯›M‡¯ÓÜÿlßmj7š6¦éL97é7 fÂYg]]d]×”7·ÊÍÛ>ÞŠèî¬ÑóMÜÄÍtÓ8èÓ3aL;½=£æò×iùªnޞ”Ç„7×᦯sL»×YÏ™/_ˆÆÍwóf[ÚÿËC\öÀÍ•všæ9=ûÔ¯úY'nà&nà&nnâ&nâ&nà&nàftN:ÉÁ^¸Ù¨›i?&bÿþ&n6äfЏ ¸Ù675¿ÓÍ´¢–_…93qs×Ü ˆ°An2g&nå9SE~í+Pfùµ¡£àfÜ,» :'%÷›á™Fæq®Ëœ™¸¹#nš«¯ê£½ÿ²¥¹9-MH’0/ÐÂM &n®ÆÍ¦Ã7¦-«ºéµ®ËMÄÄÍ­Ó.ïfÌ»«q1qskÆ´µô›.8òNäI+nâæ.»¾vêšÓY sTÌœ™¸¹ãcZßä±<¸¹J7c¨ÝͺæºdÎLÜÜq7úMÀͦÝËÒ‚½p7q7q7p7p7q7qp7“áq8ÀÍPõ‰ ä'ýps-n&Ì©U£ã<ߎ›¸ÙB7™è7·ÞMó“ º\Xˆq30)Pùk¡¯cO£¿‚͹0nn½›í×H7#'‰ÏÆD—¸‰›N7ËbFŽiër³’tˆ‰›+s³é¨½ß\£›ˆ‰›»6¦­z¾¹77¹”|¾¹ð]ÜÜ ¸¹ü=”òeÕòÄ•…©üìÄð5Þ€›Lá…›¸ÉsA€›¸îé%qs»ÝתFn®¥'нp7q7q7p7p7q7qp7“áÙÀÍÀ³î€›Ûí&s`nâf`Ó艛[é&s`n¶ÐÍMŸ“1-n›5&ý&n®ÌMæÀÄMÜl¡›+cËæÀÄMÜÜ>7·cLÜÄÍ­tsCçÀœr7q“ç‚7qÓß92«nîÌ ¸ÙB˜pp77ppp77pp7q77pp777pp77p7pp77pp7q77pp7q77pp77p7pp77ppp77pp7q77pp777pp77p7pp77pp7q77pp7q77pp77p7pp77ppp`£Ý€5âs“ ˆµGÁÍ4¤Æ!µÛa»Ù¿è'„nq€stºŒY¸ €›¸‰›Ûá&WÆ¢m!bþý‹ý ZÆÏ÷ÿçd×~ endstream endobj 513 0 obj << /Type /XObject /Subtype /Image /Width 96 /Height 88 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 1163 /Filter /FlateDecode >> stream xÚ휿kÛ@Ç=tȘ¡CÆŒ5t¨!C *ÈD† ȇ2XàÁÆd("“É`‡€:”%ˆ Át((›;”¡ 2tðÐÁÿBû¤£ŠbÎù—"½ãK8ݽ(Ò‡÷NwO™—¦‰bê/–„òc‰÷ÁE>Èù Ÿœñ)•J©{_jɶ¢ñ)ý/¯šOü.H=~kI–9öêÍF!Ì´,N|ñ£(ŸR¤Ìt*†e¡â‹ÓUpüÁøŠ†ÌÔÏÂ>¿pþ¼ÊR¢äƒþƒ|OAø@¾¿`Œ/ŧz ¡¦4ÅǼ BQù5å«îÐùœ˜(_‰|,”/>ÎÓ½èFÅþ©‰Dnøˆ§‘~®KÇ’v¦êçùTö«jSöëÊ m‚2³¯d>6\Ek«Îý`pg«-EªIJC6¯»æU·²S&6l@臡SMõ†-ñߥÚóœ9µùÔmðŸ>8îÏ¡ýÝ2o §ÓÓ¶ßm¶ü‹¤FÛ£¤­°í9S‹Í‚Ȩ¶¢_v€‰v®*MY:•ªŸª N>ÑB½òø­1*™á3 ‚¡F< Ên¥²S)(W>VÀµB†‚+¤×Ÿs{fÀ¨Pë3ÏœZ‰|"à£÷;zÏ—ÒVäºäÒ‡‚r¢=m¡%UþÒ§Ú“z©öñzRïüJͧô¦´±±î4?, ŒÃùY%óqˆâ|¤(¡%UÁÒŸB Ö¯Pí©‚a™BI|¤¦Cäóù¢w.4½¯«gÿ4žø„fyÕL> ñP”ND±èXŽ„­­-ñ@Ì=ŸÖ0T|}a_ÛQƒ‹‡O‘•¸>­;(¢8#¿ŠÙx||ò)Ÿo÷Z1­¥²Es©»(WÌ–FߨîV¬¯†ÖT`YAÚ¡]éà$ùÕ”=cóêZðRùøÉù¦jô»î½3øfIG’ŸnÝ:g,Nçç3çŽèLðii@Ã}pÆ¿]q_è´5ûÆòFCµ¡«%ñál̵.œÇÇ¡Ïç@ÜÚÝ ýñ×Ðùy¡ÕóYרEå"KÎä|Œžàr¡Åèë}«á3~¾ß>;Ï/p÷~ý“‰øEpÇ4¦s¡ÿ‘‘Y>¢ª}c*'2Ѐ:Á5ü1Ð?ó>÷“æ?üÿQ¸Þ‰ƒbÍyZÆgÁãgá±3ÉtS…uñ!ÉU¹&ƒü©&‘Í Kº’$ëU2øœh, ƒÃÚ§Ü3×_€eÙdpýŽ|òAÈù Ÿ<ñáÏ?g3ûš‚FúEùçð…Xù}y±ëÍè²=ƒˆøù€Ûœ…äçSg##|ÂmQ! â9Þȑޙ‹²ó$³A¢)ôòê$ã|Ù|»I‡ ‘(`|Eã üøÃ9S:Ô·¯‘O4ùCügáóŸ©Ï2ÏYæp`ä™?¦ 5&C Âü!#?_d8¸>E>Ège|ðS?Œïÿ úúÆ Ø endstream endobj 464 0 obj << /Type /ObjStm /N 100 /First 870 /Length 1311 /Filter /FlateDecode >> stream xÚ­XËnTGÝÏWô¤o׳»%‹ #QaA°X8Î(""¶5¶#øûœº–mFPY ÝÌ=S¯súVµ•[iE™Š*.c`‘BÂXµPw¬V˜å…=`½H Ü(b›E¦oT€Q|Öp°aÀ¨H±ŽïD‹“aµâ6±zéM°öÒµc¥O‚„!{³Œ>W›1©R™œr¡F2mOi›ñÈ ‘Æ#ÇfÀ sXØtÙ¨N¤G[ÃÆ6*¤Íà+pì0¬©!=2Ä©ðB6œÁ•£2jpåŽô ®:ñF ®ºÝ‰F 0|ލ,Ò¥1àÓásFà—fG€È–!@8å†5bjpê…Geá†×’ûÄ&2î ›È…åµêv¢ì’£ìì0³Ö½ÃðZø®ñ-\Á/£ô½¼Ö¾wlf€ñKT@rT˜Qœ£Â´Õá9*ðB¨”¤/¼Ú4¯†|)kòµÅòÍ!C¼šcXC¼#§ ñrN âõd¼!Þ–«®„z5§¼Â«êåê͉ C=W2ÖY-.:cÖ–ÃöÚ“‡‚ÙëhÉÈêÐ\ɸi3'I :uJN’¤ý*W_âY)‚x•ä© ¶ªÉS!³Æp‘Â6©1[d°“«é†ÏÏ®ÊÁAYÑCúÍO1‹/Û˜a¾ì;Æ/{L˜7ßÃÐòjw~úz{UŽËòêùaYÞl?]•[o>_lñàäífyÛ³«K¼¨Vo›åh{y~½;Ý^®ÕúÕÏÛß?œ<=ÿTŽÃE´"Æ,9¯øùÞNv0øp7i¿“ôOD•!ÑGm²G€¾gXÁ™3‰EÇÙw¶öAÑpæ g¶1§°1õ\ÞÐöß×Ï!P;1²åb00!b9¬wŒlžÃbE'ÉaçÐF ‹ïªS«jËŋѾZ›I»8ß¹’áJ\mæhÃ¥¼ºäT†‹Lõž“ŽÌY;åä cÔžÌM:ºÓÌQŒk[’£M Ý©ç¨ÀݱÎ\Ép1©ÓsTàþZ[KÚ%œLMRßFŽ ž ŸÉ㢘S:{4Þ¸ý¢¼¹Ò¡‡—Êï¶²½íë~‹[ÿ2‚ðÍÀåƒÆwúG46kú ±Å_î46Œ­ïol)Âÿ‘,µ¯“ÿ%ÙåÅîüú¢Ä,s›ûêóßËëåÍîäìò"~vú¹,Ï^/Ï·8ݽxZ–—åjw½½[±™îoGÈqOÃ܇µh{Û>¬Äå“<…¥®8îþH†ïMfoùíÏíéÍ^þŨ¯}›o @ñ³ïòþÕôfd?(rò¤È‚o›Z\ î¼þñxü¬ endstream endobj 526 0 obj << /Length 1394 /Filter /FlateDecode >> stream xÚWKÛ6¾ûWð(k-©·zk&H€>c`±HsàZ´-D–‰Žãþú9C­${[$s8œ~œ§ÌÙžqövõj³º“¬Š4LÙfÇ’4H‹ˆe¬™`›’}ôÎßÞÖ²Tþ:L¸w”ÍIÖþ§Íûû79g9h¦‘ÑŒó0ÈEv­’ˆA>˽{\¢Ä¨¬~Ù¬¾¬Èp&žïÅ(aÛãêã'ÎJ8{Ïx9;[É#KÂ(ºfV®8áiý²*R¼$ÌY˜FL°4Š‚‚GæžûwÇ„½n'–®=ÆY ò˜¥< xá«ÞTûSOžˆ‚ø' îmÎ9ª9!µk{$$.Cõê­ –XÙZ浂­Ã"ÈœÓÑfš{]Û­OÒd?-È>°$.çªÜ+M¬ºný0ñÎî/í Ý¢ò¶í|€}ñÓÄ»3ñ ½íI㙳۫cë‹Äûj~Šv˜T­Šàù`â?¡æWPÑö²ÿAš/‚ûÀek!‚"IÐMˆìü}…xÚŇpßÍUdYÎU3¨žìʆT¾P,ëž~+–³ôN“ Nb–Äió|™ÞÑ$½!Õƒ¼ÈÇô¶É˜‹Iq9[Qˆ‚2ä·V«u¸pÐï;­¬ÁóÁQ?„מpƒÏ7º§ižzwCç ÍBެGùÙ9îˆR Õ¾±q7Hª¦´Q:ã¾–ýÎÀ·wskÃa*6Zk”¹ãüŒÑ^pÝ`œ×ÀIô]˜µˆ„ƒBˆdÒ!ã, x\ “£ šåû¸œsïµ}5Â|x~³ Ú¬Ù@ÐÂÌvÁIñg1¹ÍÐ9-$oÄÖ7®v`«Î®—G…*6¡ÕÉFÕHb‰!{ÚöJêªÙ#»jp}xüðîáñ-nŽmI²)I}ZºS»&-!„zÛj’ÇeìS`k×·Çgì7Šû(-š˜Ãj¥µÁ„¸6KÌ©mpRid´¤f3ø.£c,^Ú‘9:°m)I<ÓÕxæ=úBPƒÐV’IçuBp Lc €9 ìŸ.$ÓžžjµÞÖÕö3ú{u´TmËŒq„ÀÆõ†›\Û*+Y·{×­O÷Ѝ ¼4ñn7²ICsÅ$ ñDÀ\,žÙ1 •@šsšµÚFÔ%y&î¦oŠÓ÷¹ÐÜ-kwÍzrÏíá†1  éâæpN–Ãy,F üØøÈùá幜D‹¹üÊáM¢h}ªÈÞWûƒFÞ±= Ä}2뤵1¹U:;TÀŠ&æžÚnÕ0,ît€¾òÍÝ“×ä°͈¨¶ã”z¡jS~¸CîùPmé Òy²üôµ*HÜ[©Gu ‰êÆÂóè¥wÕ•Ö5±ö½¤AúwF¨æZÝù™ÝÆs¬üÊ Ob-½Ãõ™i»όÉ\¯ÕRhüb™}¼É®S’z{tÀ7ñ´;¿¨] K$ØáåQÛ¨Å;÷ãUoü(ñÆ*^d0}ÉMîpª™›£"15×ïÙ¹…Ås5ÎæŸGßc*^˜Ztœåx_GPÛ®¦¯õq²þÑÛϑΆœT©áǬé]o,¡³Ÿvp³‡Ä1'¼À8Ö H×N#C¨ÒŒCé—ìb^[­®«/ÄlÑô¨…鬜Ùñ[;.L7«^À}`¨‡Ó¤åhÜØ¬¾Ýªß²Ú;ÕÃ8÷´|Ìe9÷~®kÃK­öxˆ,Û# «iIþXæG^HªëÕ@àsjÅFÔv” šÂ÷fÒqí謵"&Ý™ÁíTSÒÆtΙŽëç¥Sté¯í Q†Y>ÝúCC6òøGþþ ±´Ö' endstream endobj 514 0 obj << /Type /XObject /Subtype /Image /Width 96 /Height 128 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 1422 /Filter /FlateDecode >> stream xÚí½kãHÆ]l‘r‹-Rny†+ΰŶ8Á‹H±RÄà"‚6¤0"E0)‘ʤØÅ‚®8ð6‹I±˜+”Î[œbÁ)¶H±…Š+ò/ܽҀVkÍŒÇú°dùžb4š(ÒÏï;¯Gcçƒã@Rý‡$H!)–æ÷sððŸÊó©Õjy\“%ØxNˆrå³ôɆùZ$I,å|ëøDiˆ{j 㺟ÂÖñ•ˆ¼C³Jö#ñ/.«¸ÓUžŠIžnå#ouû,iä®§n?è¿0þÁø9ÃA2×ðÀö>àSy>”‡âÂ÷’ÿBû“Ÿæ-i‰óù Å壵ÈWÇåó9v _B>cÈ—÷Ö\ ¢R¿þÒ@¢2|ô“1“}iG†uѵ/û­C{×ìöLí­6þ8ëHD”–_b>™ŠuÞuï¦ÓÛI÷Ì4Ú†yÚr> œƒÆ«:«#W„ÕÒÙ°$þ·Üú*WN,!ŸÎ„D|Èff÷îüëlòÏØ¹28ýkëå//Y¹ü›äFË£…,ÍÈë+&–œ9‘ïPç¦ý¡OL¬Ë®Ùk'Fó÷&I‘O4qï<þh’LiøL™¨©Ñu¤ñºÑxÕ¨ÿVo¼ii…u$ îŸÿ™ÛO$n~å•KÈçtÊD|ìQß¾öež›­Žá·Òï5óØ^©k kråß!ïp©\t–[?žM¯Ä|jÏj{{{dNéù¨`‘¦g%æã2Åù>”š\wÈ?üá±³ñ ·>÷_Hj&ˆÑs™|>Úý+ËÙÝ‹À~Nð «UU+ùô÷ºq¬ëí@Gšv¨íïïëzåáÈøœÍBÅç“O“h… K…Ï.K8?í¸Sœ$‰¯"ï/À|Àg§øÈ×z%[¹šøÊeã³òðñ z㧸…Ü¿Šˆ¯-Ïd™bÞë{åyîjyÑs).¨N¶ü¾œ|<µÕõ¢Â ð-OÀÇ“.8ß:>i>nņ·ò|v¹ýYùJ®ý——Ñ{s?ƒø€ø€ø€ø ø”ŸOæ¯tŸÂù„Srîž$ñî@’xr®AéÍðQ ݨ¨%Ÿ‚—uPh“û“xé¶()$(]®_È·*$(] •;/<(]¸¥ ÚWµýY«ÿÕ_·ÿòx!n9:ŒŸ1¿ððð$ðŸmá³ù/7ÉÇ:³Hé§¨ÉæÎ¥åãÞºÃѰùº1þkhõÌÁÕ€•S†N%ƒ#²«¥úê[jÈÇßœ¤×Žó;wú÷Ø84üí&Þjý K?ÐÓóYk-tIùœYDc~ïzßçú;­nMnÆ‹‡Y÷Ô$V9ñQ,,Ÿn§Epg>Ÿmúy2¸²¿Íþ{ñ›çSTÛÅåCÒ:2œ§Ägxm¸æT2Ùä}›áã­ù+ë¿ÈHæwS:ÿô´ìgÌpyÞ‚ “™P²¯ºÊÉ'@ÔœÜ8æq‹hPžœ‹áš}™Ú¨öû¢ñbÿUøÀ@‡œˆD¾¶xXX=jŸBDÝ=ugaŸíH2ÙP¡(>ls‰V»Eò[¤¶Á6gËéN$_ÿ•süLp¢^ ‡Â‡Ü+ç_„%o2˜¿ƒø€h€ø€O•ø¨ÇŸË}MÀG="½Vü¹|h"Vÿµží|si…óöò!³!8™Äçó{]}3|Âm!CÌr ;»rRVa>DƒE6˜7…–þŠ<‹x€¡ Ï_ì0eHGqÿ-jŸ™CŸÌÇ?ÜuÈÛÕjy¨AV÷©?³&ˆ!~(‰Ïï2ÌOÁ|6Æ?u*ùýSH¢ÿœ¿Ê¡ endstream endobj 521 0 obj << /Type /XObject /Subtype /Image /Width 442 /Height 211 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 529 0 R /Length 7408 /Filter /FlateDecode >> stream xÚígTYŸ‡ýºûáý°{öæÑÑÙ™qÌ#Pà ¨P@ÀŒ¨˜1ŽŽèîªãŒ"fňš¬¢äœtÌú:Ž(*f’ì¿--‹ê@aw+áwÏs<·}«î­Òz¼Õ]p;tP—ŽÃçÐJ‡…êh…&§J›ÿ •'˹I&ÙÒZù'­m9Ä¿Ð8øæõžÒÕ5àÇ) )tuQR{ÚÊh˜C.ð¯%cô+´¥ÅoiF¡·×‘Þ^‡m¶Þ¹û‘¨e﹇{y1֦à ükÉÁ(ý miþk’Qè6u»íÖ[£v?’Ží–[ÝܶkÓaÈþµä`”~Ùr]ŠˆqëO»-“M[ÅN_½eîÚƒÓ—ö^Ö{}èÌån89kEðÌ•»&úìmE]Ø=j.êi ÐÒ0äÿZr0J¿îÄ×§Š˜¼þp_óK×®Z½qSž6CºõêêøùùÿÚ³sGËNû÷èaùoÿþM§á …[u÷Ø9zÏãæB[iÐÒ0äÿZr0J¿?·L1ySÈȱ£™ß·MŸ¿`ÇïR.naY ò4pÊÌék-Øp k׾ߎX(ܪûô?ì÷<Ñиh6 ­4ðUàFØB#eÜ*Ž ´|´^àMÂ]à¢mtãÊAk¿Z¥§_¡-mÈ1~íð„¸ÌâÂìË%9åùy× þ,.¼‘›}¥¤øFA^yNN©‹ËìŽ6Þ­zÌüX„èTLßU(j@[i I¸½½{×ð¶¶þaUuæµ§›Î^²1ã3v%Úç,Ù)Cvbj„ƒ”8`“—ð/·%Ÿ7`8Z/ð&á.pѶzl)TÄçÉAϘù^4=ý6²åÆ,.¾'._¿öäí«ûOUVU=¬¨xþâEÅ£G/_ÕTT¯z]óîãq“À1!#ü2„ÍÞ־ߡò¨«"Ö^¡ž×ÔÔz3Çmý³ô²æÈ5BJKÐz]àá.pM9ˆÌ 5×*Çüér *âëZÇÌ£ÿçÄÝ6ž^ehîlVµ`Kä³GËR…ÍîUª?…ðÛ}z¬ìÒ¤¥ÜÜr9sx´,Mÿ!ëÿi\é-AëEtëù^[ØŒ»À5·J@W®K†™·ž1ký9qKY±ÿ쮃ÇuìüC—ºýwÇ.ÿõˆÎÿÓé»ÿøÏÿíl·L¸Uß…¡“<!:ž{ŠE h+Í#åÙ§3Qó˜3÷¨¢’‹ï?ªrV$pïò‚š˜1sÿµ˜"õÅ·*Wm9>Ÿ ¥kû¹¿(),¿¹xG¬×ÖØÀÓY¥·*ÈÀòÔä«U •º± ~G’¨Í£'Ïç3§‡Éòù}Ž‘§Ê¢î©¿©¹vwÆŽÔ ;ʳn>¾+¬ C/É9'’®¯:7 õbBç(ÎNg"§2 Žò$[yžÖ#uR\˜Î¨8¸ò0±ÿT‹÷ƽY;ÓÆï(K¿®sÏk¨¾ýøù[cÎåÝúøÖ!Q³=—ÔŸ|¦æ•MÝšv&WýÿKØ…ÜeìQyšþCÖ:ré-AëEtë±¥ð2ç.pC¶5ú˜© a/MöÛÈ–ò£ÐwñÙ)žj2wO±Ñ»´•ž}ZË‹ìäYNLâ FEþY¬<ñ‹"›ò7› Õµõž×äݪú#¦l¡òô"å)gæüyµÙ¥*¸÷àÑëêÚWÕu™7ž¯=YîÊ$P¾âôíËwŸÐ†/ßÖ•ÞyºíHô2eˆ½<ý“aiÔl_\iEå³êšº_ÄÞåîܹwE-E/½Ø³sÙ°™L„7I¢ÁXË‹?û¬Lø4 yÔa_ºwÈÍV<­««\õfûû¯r´6Ê”žI¾úèIUumÝÝÊ·‡¯-S›Ëž±Wdè?d]ÃÓü×n¬N ¥¡y‹.m­—9w²­)Ƭ?õ+´¥•â²Q0[á|ðYs¡­¤ì|˜¢ØžÉšÌ$Ú+²¸d©òøJåá…ÊSsØÈYLÄeÄl&ÜI°“gZ+J©Á/ŠœY¬j{r{f69‰uQ$Ø)²é-göâ&“ Ÿ«Œ\Àž&Û+2ù}ŽaÒ©>J‘7[E~¦Éêº)äŠÊ*þ]aKÑËñLÊ$&‰zª(1ü¬þÂäÑÍõ¥zÎ<ƒ¡iê å­ÃpQœ#õ-bOÌVªœç|”Gµ6³c²=™ðÅJ:-j«ÏaÂ謎P4yȺ˜ÃF‚¿Žcý‹- C.p“ÊÁÔRjdK¦Ì(ô÷‰r þÛõÐ3é8?èçýyÝ9±—¦³1l¼+{~<›jKW½ ÍH&›äÎ&x°±Ô`›aËS>‚)¤YåÓØ8špŽa2lØR~Ÿô’êIWŸ{*Ÿ´r_JÙ]õg§ÇcÒ—+CƲ™¢–š/Ë(&f×lœ?MqaÏó} ûÎMb“©™;7‘MvUjofÍ”ÑÎ,í0ÞwR&Wäsé?d)&:àëbÈþ…å`\)5²%{Å(˜¯O±ú-•Æ6õÐ3)L~`õ[ŠÅúTc À¸¬‹¸óïçµõï^U×Þ}¹-¼`YÀqOe¤½2·eØt‡¬õó¥¶z€).ð¯%£ôÛx¥‰«FÁJY>hCú€U VÆKbÕ9‹ éÖìc ÀèÐ û܀ȹ*O¥j®2|ŽR¥ž‰)KZì€MwÈž*MÚðyƽÀ¿–ŒÒo#[\ZPêæ®L˜¦ŒŸª¼à5< ¬}òä€Ôñ"Æäà hóm94ð:¡Ö/€pnÚr’ë_”—à!1??­µÛ²sÇoðW €-aK@+²%‰ãç^=gMŸ–•–ÒÂmɶK§ŽÝ»þh;ÔzŲ%)I/à Ø’«¤\¼àîê<ÃÝ­åÛ’«äggªÂÏ.^0߬Oï‹ç`KÀ—±%‘ž’Ô«{7®~¹¨`ýÚÕæýÌzvûiÎ̤&¾½ÿæýûþL³;zyüÈ¡áC­ü¿ïö3Û¢d¸6Ey9‹½çÓd•  ½ä· PȨ%µ·1°ß–¦m\*¼EÊâ_Fœ ut°§[~®¯ï¾íÔܹ%Mq›µ+­Íè„Ï ÍCW½[ò¿0Aÿ¤ËÒÂ\ëW'ZÛ“?íÛËßë™[jÝ5ع50+-¥´0ŸþäséŸ[Κæ¡W¼íõ7k@AAi7EŠ-¥|Y,÷Ý<~¬C|´ª8?7&2Âcª«Öötç÷¾ ÙÒ¬Oo.\í³œÿÜ’¦pkVøè·%ivÿžÝEy9‰ qnÎS$Ú’îåÕ߉{7úN\×®úôìÿQàzšÚƲ%M~¾–ƒ,~ø®Ë0«!ûƒƒ´¶ß½sÍBé^{øPëGðwß‹Ìã¾§ W®Ë–‡÷ï¥|ßåÛf}©Ó&mÉ}2ðÓßÛX[ù,]œ.xÞR×®ü7mèñS×&{À–ºl °%l °%|1[âK1”vUb"Û´åd·‡°% J;W¥¶Ä„Ð0Ð–ÜæÐNø<[â¼`K)¶|'[l °%À– %ƒß.`KØÀ–À–íÄcšÀ–À–à« ¶°%lÙölé`÷Ëî;øœ[œ('#lþmýÏ={ôêÞmá<¯âü\®®%E;׺„±Äå’›ìBטõ,©¬õØEýJ9=«0+å2óþý¾ïÒÙzÈàÐǶo l>ÛŽÚoøum·pvš˜˜ðáå˜ÑvMl [‚–'>ÒÖæÛ¨r>.†&Z9Y\~ ¹¸¨H~ 9]K‹v®u c‰Ë%KéB똛»ì¨_)‡ D´trê¥Oí›{l Z…-÷YZ˜—æOw›ªðóåh]žX×’Çz>·ä_J\.YJZÇÜÜ%•EýJ9‰K'7÷ €6iKüîô¶gK2Æ0«!>K›÷3ã?Ÿl4·ŒV}š[êXòXŠ+$.—,¥ ­cÖ5·$Gq“O‚¦|ú—·ÓWanî°%h-߉ý¾ƒ’­¬°Á„qc¹Ï-©Â¨kÉc)®¸\²”.´ŽY×’Êö£F®[³*?;óâ¹xg§‰†ØRâ*ÌÍ=øÜ¶­Å–Á»~l>°¤ OØ€ûNœî:xyòß/ëZòXŠ+$.—,¥ ­cÖµ¤2Í3íF §æÀ~fJ¹Ì[J\…¹¹g¶„-Akaʤ‰»vno]ÏLjŽØ˜ší2 šçˆ¾ïhɶÔ5f`K`Ò[ró~fgB[ÑÏãè3°%À–[l©¹ž8¿.9ζÔoKÑ‘[jÚ²ìãÂâ8{ضÔÒmØÒX¶ì€‚‚Òv‹Öo·aË϶e J[,œëLdKG{Æß©ðóuã`ÜŸé˜è8®åüÈl‰‚[êÿmÀºlvúÔÀ~fÜo‰)ÎÏ£zxè)ãÚrºÛT¡aK”ÖhKÂÙiâέTÙ±%ÐÅiUŒ»ÔTNFš¥…9¿J”pÃ/¿àl‰‚[~¶-cUC-‡”æ“—¸…óŒ»Ôýy2äÈHÛa4wmøåœ‚-QP`Ë϶%1ÃÃ}öŒi$î¥q—šâ*>K¯\¾Tʾ̂S°% liˆ-iÚFF¢?¹—¦Xjª8?w„Í0º§.ûª NÁ–((°¥!¶ÉDKMÑ>­ÊËÊøŠ NÁ–((°¥miº¥¦ä~›é–ÿ+.8[¢ À–F´¥é–š¢ö‰Žã¾â‚S°% li -ñ³<(((°%l [¢ À–°%l‰‚‚[–(((°%l‰‚‚[–(((°%l‰‚‚[–(((íÇ–øÝé°% l [Å–X€¶ liÜ…2QPPÚö ¶€/°ž8çIØ[ê±¥P•°%¶ÔeK¬ÉŽ‚‚ÒÞŠ!¶,ÑV#G޼í冨'9räí'7Ж8È‘#o'¹á¶Ä‰EŽy{ÈbKœXäÈ‘·ùÜX¶Ä‰EŽyÛÎhKœXäÈ‘·í܈¶Ä‰EŽy[Íñ¼%räÈ‘KÉ¥ØRëoÆó–È‘#oW¹¶Ä DŽy ž·”fKœXäÈ‘—àyKi¶Ä‰EŽy ž·”fKœXäÈ‘—´ûç-%Ú'9rä%íûyKé¶Ä‰EŽyI;~ÞR—-q‘#GŽç-ñ¼%räÈ‘÷N'9räxÞÏ["G޹m‰‹9òæ–¤ÁÂÜl®NÞŠ¢­ø—Ô€ûÚˆÿò¶¦µåÁƶ [–_ôsËYÓ<šœ[j݉¥…ù—ÿ†¶l϶”lôtúÀ¡øYØÒ䶤jõwâÞ¾_í³œÿÜÒÑÁ~Í ý¶”ûn¦öñѪâüܘÈ©®°%0­-ÿ,~ò¶üÏ[þôÃ÷6ÖV>K§ ž·¤»ïE æq߉S…¿+×eËËE ?_ËA?|×e˜ÕýÁA°%€-AÛ°eÛ¸p`ËvkKÅ!;¡-͇•À–°%€-[nlKض°%bKü~KØÀ–@‹-™Ã~¿¥l [Øhµeãߌß[ØH³åeض°%д%{Ä^hËA°%l `K Õ–GÙ²ï<ض°%д¥ï^[¡-ÇL¸ [¶O[Ò_:lÙnm¹?r’Ж£Ç]‡-Û!PšSð¦}Ú28ll °%À–[l °%´+[àÐcËAÑ´åÐÀëåx87 m|¶€V„¶¤:]*;tèÀ9€.H•ÿdŸ„m endstream endobj 529 0 obj << /Type /XObject /Subtype /Image /Width 442 /Height 211 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 218 /Filter /FlateDecode >> stream xÚíÑ ÄÀõ/­)Dî"luTÆ­®“x% FÇðÓ;Íîñ endstream endobj 533 0 obj << /Length 1218 /Filter /FlateDecode >> stream xÚ¥WÝ“›6÷_Aßð$ÖI¤OMš»I&Ó¹Ì9ít®yAgÓä®íþõÝEÂ|—›IŸÐÇjµû[íoêlêÜ,Þ®W×aìÄ$\8ë'DÄžÆð ™³N{÷xºÉeª–+P·åAæË¯ëW×u"8)<<éGœD,½í!€|¹Wæãxdñ~½ø¶` CÖß½ÀIŠÅýWꤰ÷Ñ¡Ä#çØJNÀ(កqîÜ->/è‹öŒÄ¾±d'—œºÿ,YàZ¤ùüŹ÷N….a䛵Fn¬L™Î§j,êS—,W£îzg•'ºØd¥l2]šý`¾ûJÕªlTz9^›QªöªLí¤;ÕtúŽYºU]<ïA ÁûW¶ÖÇkôNWFJáä$‹}®Þ´¨wpá)Î µqW‚Ñ>D4`_\ây<]W²P&ð#È}Ÿxž‘k͵Î<…~Œùë~ñIJ=Û#|‰Á,øõØ·UψrÀ%"‚GϸèܯJÝ»½LTõ¬•ðû ¡ ŸäY^´oŠøwíù>ä7U–Þeÿªjvîÿì3ÖãMO­_…‚„Œÿ/ÞêÓ³.pÂE8ë‚.óó‹Ñy.1AV!%!¤ÇðÁ¿O³&+· (8¤£Þ«ªÉTmæ™ý~;d êž[g˜C?ã$ro'ò²RfP©afÃÂæl¿hø¡itYãCÂmLj6v_ŸZ¯Ìnà&;•Ì_öûülß%ìõÁ^ÛS6Pöë¹È¡fSr‡™Æ¨Š=œ~ÓÚhý8ŸjXcG©†v„n½3HÕfŠPµßÆ. óçCl=a}Äå<«­B¬wøMvYžÎXÍ!ö40Ä­,U>WX‰|¯“ÃgïGÌýsÉ ÜbXð’qXÐ ‹±[ÕÖä6.8˜Ä—ú¸XYmèÃó‡6 š°»<*|Ï—ç8̃B>.í¨ê¸SåD@¦é8±*Uh´Hq{„¤žÍ–ÞÿÖiõmëtï²tJš#Þkû‹A®Ì‘B¡J{caF¿/L•9ÖF.…8ôI]BüÓLp',ÄÝÈúžjÉ´Ð0ZÁ0ˆ[+A}>D HžÚ(yÄ'lZô…ª¡Ï’®5 ‘Ó1úxÌÁeå©©Ø5y„ [ÿ.Þ^n…h ¼¯FHÙ2+ë ¤[UªJZ2­UƒlY»Å‹¬Lš ±>QGý[%ͪéï®íf‚ùú¼í»¡'ü€ÁÈ`Ün]´s/b·uõ¡_5tä}OÞ]³êîY .zÚ°s‘ÆNä‘ÐïºÙl{¨¬woL‡}küœ>3_™Ï8ÂCp_çÉ_‰ÏILýù)ùÜÚ^L endstream endobj 530 0 obj << /Type /XObject /Subtype /Image /Width 403 /Height 509 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 536 0 R /Length 19699 /Filter /FlateDecode >> stream xÚí‡[Wþÿóì>?EPé½£ FJ¤J± Šˆ¢¢ˆ""H½5j, ¨ ±zï½—¨I¾»›æîf7ÉnÖì÷»©›ü>8zçÎ —v¹À{ž×Ãsî™3眹p^|Î̽sÞzkt[àšÏ[¯6Jo,|šç.ÎZoŸù3hº™|X&z‘¸Väüh‚I"—É×òô¡©!µß4ê†^H®nBôÖçPy:jÊ:Àã׫©‰5¿/£{³y&3ÖfjœNI»oLÛøŒW\ì@ÃMgÝó¾/t” y&3ÖfjœNI»o^ãêàãääÄ®_É\Ýâ®ÑOv á–sy߈N¹%èÀ,‚;©ÙÛ0KkcÂ5Á±2aÉÔŽSÑvEu!Ó._\I|HJ,š’9)."£Ÿì@£°‹kó¿ 8jËù!A:JЂÈ?ÿ÷³¯ÿ“WÿÅŠ”.å’ê„ërNxÆ™í˜oˆŽµ1áÆšàX™1έ¢ãt2}f­(çÈ´û†¸’»ùŒ[\¯4¿ä•ÿWŒÔ ËdÐQ‚¯„p—غ´ëÉô²¤ûóeÉ]Ê…Õë?s¯¢ð`V{J½š;ãÿîÐ…úgúû¦»!j‚¢æfðcME¸±¦*Š‹›HÒOv ÉöïKÿ`pÅÂ. ÉgÒQ‚\1ÂÆô‡ÄîSeôò»ÿýOpz9Û{¢ò³¿?ÿñW Ž÷,Oé¡—Ÿ~ýŸï¢ðìûSUŸS¿ª”GŸ|úÕ~úåWÚ›Yú)khÙñEÙ§üûèŸó}nÅgËÞìkE°ñËPÝSdªÚ~ùéÐçßýû‡_~øù¿ÝúWÌ•OYEòÉh :eÎz›â`oFéç~öwªªêùð/§®Ëiy;­‡:ƈ¸òqï'ß=ÿÏO¿¾êȯ¿þº7ë}—ôNù7A~/Õìœ5œxÿ“æ§ß|ÿ"âúèÓ/oW¶ïÉzŸÛ Ô`¬©7֔ǩ`Šæ‹ŽÓIöùõ_ûÅa–í3C滊ã׫Íwß^Wð-ŸíGGq™+CG)­‰ þ¶¬‡Äެ{DPfµKFÛ»6£Ù)}Ê?ûÇè\,íÂ]ugs×ìÂ5/ç•9—úd4:¥„\üp4úú[nï_¿ýqôÀów£³nnÏz@Äd_åÈo嵦2Zý¤™ª¨äÖœòw‹ÊÊZFAÿü÷÷®¢ßçÚ—}ƒjã`­06+Jß»ÿ¨¾÷“¿|Ã]ãjüð[¶÷Ëv ç^ÿ¶ìÒ]§J_Eƒ×Ü3Úäßù½ ~K“SÊùð/ß]©ýpÿ{ôK‰Î¾™uW¹‡@=ÆšÌ8åãÆšò±üñ(•/:N§¤ÏL2}fðÅå˜1‡/®cÇÞð–É[om…‰‹h}/ðÊ·ocDÞˆ %èñR9W·d•›³ÊB•þŠ—Œ^þÞµ™m\ù¼¦¿QN[ÿÓ“í÷úFõÃú¾ýÙ×=3_ŽÊÿô,ül»÷é§íøŽ^Þªêâöž®ý+½úð“=g*#OUž¸ÛýøÓ¯¨9ÏÌ6åVþõŸÑ¨I‘ŸåðËÈTÕòñóèkO6æÔ¦Îs¿þçwQYwWe (Ÿx€¢ž;e‚µÂpÍìñÏlܤ(ß™}/9¯´´eä/_?VÔp{¿úî'ªüôͺ¨SµýŸ¾êÛ5v.Ro‚üÞO¾úþVó_¬¡F#³îEd=Ë* QTù(šWgô+ŸP‚±&#.þˆãÆÚdŽò>SüVÆl÷ qe~Àç͈ë-£Öj嵸^h±÷AЕo•Ù‘7ÂG°—Žt€`ƒn­¢]•½+³ßoùøë>ÿñç_¾øÇ×þ°?çýÙ÷Ý/gIw*Ûž}õ/ŠhoAõ“ýÙ7¶g?¤½tìùÒÁg_~ýŸþ¿~éúÓwGn’U#ÚJnõ_þý?pù¢=‘ªêàÝÏž|ñOšóþï¿<þüÛS…å1Ù7<ʧ¦ +2‡ßQt¯S4lQ”FeßÝ“}ÓMÑCù»o|ò篾ýå—ÿ~óüûÓ/îV°¾É¿ c¾E;²ìÈz°5«xCV•Ÿ¢É%³×)sdbS‚òXŒ2ÑǵÉ;}–Ï´Ë—“â ŸñŠ‹hS|õ_ã…Žt€#&çf\NáÚ¬÷ºgõFd?Ú›}{'²ì‡”ÈjtQ¼º •Sž]‘]¼=»xgöý£{›œƒtà;Y}áÙ¥ÑÙ·£²ïoË.Ùœ]’U»FÑ#ÚÊæìŠØœ¢=9·©~åžÈT”Ý@MG¼`Wö½­YeYÝ¢§¦:«#TIPVƒ‡âeU!Yuû³ßß›s‹f‹ë³ëbs®s}“Æ|‹|³Z×e5¿£è]©ø`’}SÂdÆÚÔŽSõô™ñ†¸²ž¾Á_ù‘œ*²Ïq±­cËòÿrí_ªÿ¥Ul¹°/ÈnÚ’]±6«Sõ½k²zɳ«6fWûg5»d R&•YÍtÔ«½-ÎYCì@׬uÙÍ”¿‰T“]ë•ÕñvÖˆh+ïdõg7¾X¾ ŒTU.YC~Ù­¡ÙÕ›_æw­Êú@ôÔ&ƒsÖ0µ¾iô«Öeµ»¸¾É¿ ª¼E@£˜ÌX›Úqªž>3ÞWöGS‚]b«Ó±6êÛ†kÿR…Àü/޵Ú'¶MUDy9*s ×fwOkCšŒü›€·hÖ1™±6SãtJÚ}óÑÍO N9:$uت±‰«V‰CµöI+²?šªH“{ëPn¡WNÏt7¤ÉÈ¿ x‹f“k35N§¤Ý7Ä•û‡¹M`n[XnµWnïœ?Ó ¿ x‹À¬€/®•'þHŒš4 îÑÍœ¦⢽OG†~›Ç>@c!G‰Škž^R:þ6€¸fOŸ$qýù³Oæø ×¼WéÝ›s„Ž`>‹kÑ‚ÿ7O~Î%q‹Ûqy+.6¢qA\`ª¨Q â".ˆ D\ˆ¸ .4$âÒÀp◊⚃M¦D\̇ˆ+%)QGk!ýœÁˆk:65‹‹Nâ@=דáA;k+EZª½5¥ç€¸TŒ¸î]Ù¾e£…ùRmCÝ¥^kÜrÓSÆ¥¦é3Ä .y9\»|ÉyÕJJ¸®~»°à¿pʱDsc#Cƒè‘#}cæ  öÇÇÅÚXZéë¥%'q™µ•å¡ÁAt¬¡žnHP`W[ wCPÉpïÞÝQæ&Æ%è%+«È°µ²Ô]¬³ÆÅ¹²´x¼×—Õ!þçÏ<ºuýæ•KÇ»¬Zq0+"®?ßÓ'r(qúd.¥ùâòõòlm¬'(‘p8nÌ|AâXB¼—‡{}uUOGÛ¾è]\æ*'Ç[׋†úzz;;¢£"#·…‹J•½$õQ+- u„·§û‘¸ƒ¬ÀúÀ€Æºšž®£ñ‡<Ü\ÇqQ EA—è®’;ï43¡H,Øß÷þkœ¦Ê/ù£Ä¡˜=–¦&Kµ­r\–wæ$—ÿðfQhPÛÄPïάBãׂ<.}ÿýB í¸4µré½—ÕæŸ=ÅÊÓ,8vÏ®¢üó˜*ˆk̈ëeˆUWÃr(ÜbØ‘Uy©xÄõf¾ ±ÌÎV9â¢ògOèno}<4@?Yaí… Æqym_Å»Š41Ì?s*ÈÏÇÓÍ…Í"ù2§¾W\¢ùdH «¸ôƒ›E,ÿü©ŠÐŒôtm,Ì)I€¸d"®Ó'sƒüý„—¼|}Μ<Á©ÀÏÛ‹»–E þÅ%©|A")ሗ‡;ÍFù׸,LM ò. ÷÷R~hp+L¬~%(~%‡c°k\ªÅŒªˆKx“±°@oÉb.mkiA=å2Ì`¢/Ç—TÄÅü™yü˜©¡Ä .™ˆËuõªÂ+—õ\½”çºúmþÝCšÖ튌àßΓÊ$FúÅî·¶0§’é)É\faÁ%G{»%ÚZ6–Š´TV8ýx’‘¾žr%þíÙµ“»«H 6mœ|Äå²jÅñ„Ã4|tëúÕ‹ï…­ópuævˆŽzgõۗξK»¨?/O.ߨ@2Y ‚—cŠkÇÖͯ¯q¹¼¾ÆåïåI£¶H\fF†€¸&üÉy©Viþ7µUŒ¸r3R½Ý×ê.½Æefºi}àík—Yð»g—•ÅíEËl­Ó“޲‹öºK™p/ÇM7®£MÈùÛÃ/Òâò“¢ºáho{"#âׄ¿«8{Å5+¾«xñô ²%>Ç .D\šÿ]Ű ëoä]Ë;ç¶zUXhÄ .ìçòKïÞìhª¯xp—vµÔV±˜\*5‹‹~Þ¾QäºzÕÈ@¿@\«œo]/êëéíìˆŽŠŒÜÎ úûÖWW‘‹’Žè. ðo¨yùr­û®Xúñ$ŸµžµÕ=m[7oŒÙ qiš¸ªKôwu ´ÔU5×T2AÕ•—Œ ô”ho¬“Ï@ýâ"b÷í;#3Uìëê°¶0gÚš¹ô`o7½lo~ý’â..íè`_SYÎ¥;Zšl­,!.Mž*’»*Þc‚êëæÒC½ÝUîËç0#⢠.o¯¢I?³øþ=Ošèq7ñu´ŠšMê%Œÿí… .M×`ON4ïcOXe‚bÓ@J”Ý»%ŸÀŒˆ‹¨*/uZæÐßÝÉ2l­Ïž:ÑÝÞJÿ‹é'ËWQ\Žövu5¸8¯É⢩»­ùñ‹K[ô“/®×‘UŸDÄÕ‡ˆ ̼¸ˆÌ´”ma›Y¦…©IAÞ…áþÞ†šªÐà ñŠ+35Å×˳º¼”Â¹Š’âMB .MWÅû½­;þ–«Êøâª¯xy-‹m µòùÌ ¸èØßÇ›e\¢¨i‰¶–¥…"-u¼â¢Úè(Gû¥:Ú«œ–ä_„¸4M\}mUÅ÷iÆWùè^gs_\ìîa³Ä]ÅfÜUøä<Ä¥IŸãbS1ˆkV‹kn|WâÐ .q¹*. .qqˆ @\`^‰ «½cÓ âÌö‰Ä€¸âˆ qÄ4ç/ âãú׆ ÛŒoøÀ'ç>9 . .q qa=ë 0g$Ä5¯Ä57Ý €†‹«¦¢lCp ‰¡ÁíE®«WåŸâš?â*½{³ºø  å¨ò¤Óަzní üÞšÅUWUanbœ–œÔ\_;ÜßûðîÐà ˆk^‰«¦ôaoGËéíh¥UÄUõba ú‰ß;P³¸Â6†Kˆ—Ÿ*ÖV–“Í($3ÔÓ ìjkáòo]s^¹Bw±Ž­•åÉœ,™LˆK“ÅÕÓÞR[öˆåPº§½•WmY1íe»Fú{+Þ}<4ðôźfä·Ñˆ½ô¥ù²õËZ$Ö5kÁºf`râ¢p«¡¦J^\«œo]/êëéíìˆŽŠŒÜÎå[š™ä_8GqEk;·ÊdB\š,®ÑØ©øþ@w'%ú»:(Íòû:ÛùÉæšJ61¬¯(ínm¢Dwk3¥ùÖ•¿\1–íuòù⚀¸/Ò"#©~q¾¯«ÃÚœKSB‘–ÚÒðÆ_ h&Ä¥áâêjij¨,{¡£’®:bSE ¨z^ÄØÃ}=•ï=ynÑ?¦Šw¸¨‰~RšrX…C}Ý\z¨·»êÑ}ù|qMSÄU|ÿž§‡±>w+_GkáË?Ň÷×Ðr™má•Ë2™—†‹kT>ï’ è'§#&®ÞŽV.k¬.ïlnà2[ëk¨Êa²i %ÊîÝ’Ï×Ä®q%M—ƒ­õÙS'ºÛ[ ÐOÁ¸£?Âk—/Y˜šŒ™ qi¬¸¸[„$6ä_œ¯.y@^ª|tb¼ ±Ø‘UŸDÄÕ‡ˆ Lö®"é%=%™&wôç÷èžÈ]E*PwöRlF{YþæÐªòÒ‘>r”¥™©L&Ä¥ùâÀÏïio¡—ÜòåE­ÊRAù—¼š¹i¾É]Ë¢D[C-«P4@\ûWuyiHP ‘¾Þ‹Ïq½­ü9®Â‚KŽövK´µl,-i©,ÿÂÙ3”¯»XÇyåŠ[׋d2!®Y.®ÑÙ"›èÕ”>äßF|5£l«)}$¸{Ø,qW±w¾«qMó'ç*K{ÚZT,¬Š €¸4M\s컊]-MÕ%T/qˆ ̬¸È6•î ötA\â³kªÄ . .qˆ Ìyqý† ›fl`¶O .Ä@\ˆ ®ùðÎÆÄ¥!ÿ2°aæâ†Ïqiޏð‘BlØTüè)ÄqaÃqˆ 6ˆ‹cn/ qaÃ6·Å5' qaæ6q©ó©Âó*âZðûßq‰ï¾û.3#}ÅòeKu´ ôÃÃÂÚZ[Y±>úhSèý¥KJ|øá‡R¿èÏ?ÿŸ:À‡Õóüùó˜½{L ÌŒNææÊüi)+S-6lj¦ŠÓ*®Ðõ‡Æ~òÉ'?ýôÓ?¾ù¦´¤$ÀßÛõé§Ÿš™çç]üêÅv)/^R¦è/ÚÇkm¶BñüŦÈÌ —òùRVÙ¿oß®;¿þú+"*rÇÛ·äÿÀ”Å…A‡McÅEù¹Š [+KÝÅ:k\œ+K‹¹üûããbm,-èÿ{Zr—9Üß»ww”¹‰1A ¶ûÈ@ßîÈôÏòS’•§ŠR­P Q;"^x,qVOJ\hQÐ%ú»Û³{— æ9‘“³7z·haz‹þ÷ßÿæÒÿþ÷wôR>_Ê0¦F†ß|ý5—&wùûø@\Øæ’¸Ö4ÖÕ ôt?äáæÊåKˆ÷òp¯¯®êéhÛ½‹Ë$•ùzy¶4ÔÞžîGârù ‡â(¿µ±žË—h+ñc|}Úš?o¯Y-.šR`ÓÛÓóý÷ß ~w¦¦Ÿ}ö?‡^Zš™Šþ¢##¶“ÖÈYådeÑKù|êMÉc.o¯*¸|ù—_~aâ¢ÀK“ÁèÐxÅ%Z-6lšp‹íÍ\z°·›þP¹´ƒ­ ‹‹ö6ÖUå/—6¦½¶Ö¯ ¿‘/*.ÑV¨ÂšŠ2.M5ÌjqQ”›íæâ¼D{Ñr{»´”€ÑyýðÃüß&ÉM{áÑ_ô—_~iokÃ]Y¢Äßþö7ù|nûñLJ‡‡ý|¼““Žq9ûöDS¤GÊ"¢wEI5'b)W‹ ›†D\¢/É-C}=‚ÂüLJ0ÿòEÅ%Õ ›oòœâbÛ¯¿þúñÇÇìÛ»eÓF.ÇÜÔD&â\ Rdf°kYôR>Ÿ¿ýåÏf‘Õ·ß~K¾26ЧxïìéÓRÍ©27äW‹ ›&‹k™íÄ"®ª²ÕÅ5—".ÁFzÑ×]Ê¥wGE)_ã¢pHôÀ¥:ڢײ¤òùÛ_ÿúWÒ”r~ᵫ$± D\òÕbæiâJJ8âåáÞPóÆ5®Ã±Ø5.Oøƒ±ìÚ—Ÿ·Wkc=ATUÈ®qùûxÏjqøû•–”|ýõW?ÿüó_|~øPܦРܮ?ýñfÆF—òò^ßU46úäOýEûx­ÍÉÊâ"«,E&MÓäówíÜùÑGýôÓOøÃÿPvìh»#@¡Â%Ål­­¨ã—TµØ°iÈ5.Q¥Œ ôŠÝomaNsô”d6›Û³k'wW‘lzÈݤ’æÆFRwE[¡vFlãLŒ?¼D[köŠ«½­m{øV:—%Ú‹–ÙÙ=r„&k¬Ø‡OŸnÜ¢·d1²þé“'R¿èO>ù„Jêé¤>6Ç”Ê/+-uu^½x‘–£ƒ}¶BÁ.¦Ý¾u“~}˜m~üÁòÊRþÈ–TµØ°©S\šOEÉ#;k+|r6ˆKó¡yh{scS]ÏZϘèÝ6l—æ“™šB3š*Fnß6ØÛ qaÃqˆ 6ˆ @\ذA\³T\xPˆKCÄ…£Ø°7XW .€¸@\q .€¸â@\Ó'. ˜K(?BYˆ  Qâó ‰Ó!® ¸QsÄ%õÈú)ì¿æüy`ŒˆkÊGÄqˆ‹¿Ý½s[ýâ¢ü\E†­•¥îb5.Îl-ÅÚÊòÐà CC=Ý À®¶V>åX¢¹±íŠÞ92Ð'¨ÿÉð`â‘ÃvV–ÆúÛ·† ôt)7Ê­ D5˜›SmòÇ ¢Då Qô(ªÿô‰Ö⻹9”#pÞ,ºæ¼r½ônœÌÉ’w¦Ìû šO§¼ww·@%Ø2¸T>=%ÙÚÂ\{á‚ÉÇèY\d­˜}{gD\ëëjh¼?äáæÊå¯rr¼u½h¨¯§·³#:*2r[8+ïëåÉ–PL8'¨?ýx’ÏZÏÆÚꞎ¶­›7Æì‰Vn4þ`,[NÑÏÛkÌcå#.Ñ£ÈkÝß¹xîìè{õÞJ ôˇ4–f&ùΑRšëkw„oS\Rïƒh~|\,[’ÒÛÓýHÜÁ×ïÀ:zqY'.² ·Ô|‹íÍ\z°·›â å¶úº:($`åù‹V³Å¬Y…Žö5•å\º£¥‰¢å ¥°–:V^\RGQÚÎÚ*n ý¤ô˜f sT¤¥’XT™¥Ê¼¢ùR‹€Sù¦ºLÁl×åüügϾÄZ3q‰¾,¾ÏÇÓƒ&_œåt´²lXJ0ѱ)‡¯Gš)7JeØ\‰*óXyqÉ´H å¤%'©b†Ò‡÷)ø¤)Þ2;ÛÂ+—Ç—Ôû šO ©ò4Õ…¸ÀlW€¿ß‚ßÿ.ùX¢¡ž.g0…gOèno}<4@?Å#òR‘ˆËÞ®‘Bˆ"qI+°Ÿà¥ÔQåÅ)ˆº|ñ¼•¹Y}u¥è±ÊF®]¾daj„ÃM£ÐT•÷A4_&â’954pªH¾rsq&ƒÍà]E)qÑÈ-È»@qQCMUhpÀúy{q×p(Á¿VÃ%2SS|½<«ËKGú*JŠ7mQnôpìvËßÇ{ÌcÍŒª_zå—¢G ôt­rZ~çý”¾z)Ïyå .àËgshHÕ‹JH\–f¦\¦‡›ëÑøCT[cmup€¿*ïƒh>2»ÆE¡lüÁXÑ÷_¦{hÎ5.rÍgðs\Râ*,¸D‘Ìm-K EZªòÝ4šEàßc •wt°_ª£Mê(È¿¨ÜyrÈΈmTÕ“˜Z‘?6ýx’‘¾ÿ>ÿ¥èQá[6ŸÌV¼¾€Ÿ’¼}k˜ò±|.œ=C§L!YîÖõ"­qqæn5ædf¨ò>ˆæÓ)ïÙµ“»«H 6mT¾Ñ Õ=æáç¸4–Š’GvÖV³ñ÷ˆbˆk¾‰k_ô®öæÆ¦ºŸµž1Ñ»!.ð]EÍWfjе…9M©"·ocW¿!.æ6x¬ ∠.Ä@\ˆ .€¸f¿aÆm<™ âÒqáM`\!Äqqˆ UüC@\³K\ûˇ¸ . .qqMŒY÷ä=ˆ @\|z;ÛÅÍvqWD³W\d­·W8Ñ(Þ¶yÊÅ5±§C#₸ùŠ)%#åø4E\h ˆ €Y*.¾µ¤Â¡)×pïÞÝQÜJ”P^ÐÄÐ zgäÈ@Ÿ [몲.}æä .A9ÜêÌü•s¶V–º‹uÖ¸8W–sùTáîÈT9µ›’”ÈÊ‹öG¾-ˆ €ùpqž/®ø¸X¶¶²·§;-fÊçÖb¦DÂaáe7ÒNNf%è@Ý¥ýÝ”ÎÎL'Ë Äµ>0 ±®f §ëhü!7W.?áPW?×.+/Úù¶ .書ìm¬«^­öNá‹a¨ Ëm®äçqËÜOƒ"(K J¬rZ~íò%w7JSå Ä%Ú´ ]©|®]ù¶ .q‰D\奢W“¼<Ü/ž;ëæ¼šÒô³ ÿ"MîMH‰‹qQD'qÉ·q0ƒââ>ÁGùCS.®Ã±Ø5%Oøƒ±¬ŒŸ·w‹ìÚš¸Y™›)ÒR)™6º&uʱDÅËê§°|©þÈ´q0ƒâbâ’²Ötˆ‹¦c{víäîâQ‚MÓØ]Ecý]‘ìn#Ÿ²G/Òêlm¦tGk3¥Ë‹ª(.ª0jGUNMðï*JõG¦-ˆ €™*6ÖÕéëÒ(&ƒ‘Çfð“ó³îƒU3x‹B‹µîkD­qA\ÌÛ‹óÄÀœ€¸€¸ .æÀŸ=Äq0B5ˆ ââ·â @ .Mà-lذsƒ¸³}æq .€¸â@\qÄ€¸¦<qÍ00³H\5e‚M –h/r]½*ÿü{Ó:ÞÛ›wGî°³²\¢­el ¿Î×»°àLÄ¥º¸êª*ÌMŒÓ’“šëk‡û{Þ½4}ÿµ±ÞÖÊrÿÞèêòÒ¡¾žîöÖ«—óý}¼!. .ÕŶ1ôXB¼è.òØÞÝQÜ‚;”` ýŒ ôQÈDåóèy2<˜xä0…RGmß&ºZkDxXÜ©ÎHÕ@Mä*2Èxº‹uÖ¸8W–Y>=%ÙÚÂ\{ázY[YN6¦êé†vµµpeI¸T7j͆š*Ñ]ñq±l‰CoOw¶´b¡8ʧ؉Ëgã=ýx’ÏZÏÆÚꞎ¶­›7Æì‰V®ÓÒÌ„4"Õ©¨‰õu5¤¦£ñ‡<Ü\Ç.°®­©{¹ÊÉñÖõ" ðz;;¢£"#·…‹F\ü5EO\ª5‹kñ"-¶v¡©E¥ù‹PS>ïŽö5¯¤ÔÑÒD‘É˜Í b©¨@{s#—ìí¦€gÌòMu5¢'Õ×ÕA‘˜¼¸dV÷í`ZÅÅ®·W&â¢É$C 6Nùl¼S>þÅMÓX˜ŠD\cÖ e™ò4‹då‹ïßóñô é$WLGká˜ÕŠž¸hy}2Wª3½qûc(æÑ]¬cl ¿>`ÝÍ¢kꌸ õtÙ#þq0ÄuöÔÉð°-Rßé&wÙÛXKuÆßÇ;rû¶ºªŠ‘¾ÎÖæ‹çήu_£Nq‰†¸˜óâ"/ÑÄÓÔ“Çiz¸à÷¿  cî:žœ$Õ ´(è’WŠÔ³Ž¹¯i¿|øó±Då‰Þ˜O9?*J‘÷ðËâÒüï*î‹ÞÕÞÜØTWã³Ö3&z7~¹@\šÿtˆÌÔk sš*Fnß6ØÛ_.k€¸â@\∠qA\ˆ .€¸ YWQmL~MFÑÔŒz–@Å5ãO‡˜&¿&#¿ˆ 5‹K£ÖUTÛ0œüšŒ¢5@\¨A\š¶®¢Ú†áä×dÔ„±qù).þ3çE·‰­«(µ¦!—”c‰æÆF&†Ñ;#Éx\~meyhpeRØÕÖÂʧ§$[[˜sK]ˆ,°øT-k2 j Ðkïî(sc‚,ô_•·Hê­ø`°?>.ÖÆÒÂH_/íÕ/EjÙJ>RÊ7GÁ³óÊT-U~2'K&õ‹‹¿Êè6±u¥Ö4¤æ|½<[ë J$ŽãòW99Þº^Dõ ££"#·…³ò4mkj³˜*­K…“_Õ‘Ì@§ÓÒPGx{º‰;(ÚU:)uŽÇâ½<Üë««¨ü¾è]¯ë[¶’ÔòÍYš™ä_8Gn®¯Ý¾U& ×ÄÖU”ZÓš«*/åÒUe%¶Ö¢ÕRˆÂÊ7IÜÜãïRÏšŒüèôÙyQØÃÎK¦ÿª4Á?G[å€JjÙJ>RÊ7G EZ*y˜_@4€Ùqñg=‚u¥Ö4¤4 Ï(ÁZñý{>ž4iâÊëh-då©rÖL1ÁV k2òk ò¢ç%è¿*”:G~RþÕ‘üRÍ•>¼O±M!—ÙÙ^¹,“ ÀìºÆ¥t“ñõºŠRk¾q•—²È„gOèno}<4@?¥>Ÿ UL õ¬É¨bÄ%u¸TRçH®3pmNþ@©æØ¿¤k—/Y˜šŒ™ Àl¹«(³®¢Ôš†4.ü¼½¸k\”`ׂhä]îïm¨© ’—T13c£êWÞxª®5ù5Ž=À®qQ0vLqI5!uŽI G¼<Ü)SôR•LsòJ5·94¤êEßÈQ–f¦2™Ì®Ïqɬ«(µ¦!»«HG튌`wß .Q²D[ËÆÒ‚”—T±ôãIFúzj^“‘_ÍÅöìÚÉÝU¤›šÉˆKª ©s¤ÿ‡b÷[[˜Ó[—ž’¬º¸ä”jîÂÙ3”O¿Yç•+n]/’É`ÎrâšußU„¸€¸žÎ¶§C@\@\OñXÄ₸óR\ f&)®ß°aÆm&¶Éˆ 4aòq .€¸â@\qÄ€¸âˆ qÉ€§’ .˜qÕV–‡™êé†vµµ°Â¹Š [+KÝÅ:k\œÙJ£Ãý½Q;"¨¼¹‰qʱD©õÅØK©ú¥êy2<˜xä°•¥±þö­a=]øÕq XåäxëzÑP_OogGtTdä¶pVx}`@c] ©ãhü!7W.?þ`l€¯O[Sáçí5¦¸¤ê—ª'ýx’ÏZÏÆÚꞎ¶­›7Æì‰Æ¯ˆK†¾®k sV¸½¹‘KövSÜÅ¥ím¬k*ʸtUyé˜â’ª_ªGûšÊr.ÝÑÒD!~õÌq)?“PT&Å÷ïùxzмŒ[iQGk¡¼ˆÈ`lYjŠ£Æ—TýRõP>W’C{á‚§/ŠˆK0ž€ÊÕÀ ¡¨¸l­Ïž:ÑÝÞúxh€~Ž)"©H‰„C—¦PåKÕ/qÙÛ‰.P‹§JbæùÛt,–!*. S“‚¼ ü4ÔT…)®Ã±ص)o–ïáæz4þÐ@OWcmup€?Ë—ª_ªžÌÔ_/ÏêòÒ‘¾Š’âMBl0‹&†Ó!.”YXp‰‚œ%ÚZ6–Š´Ô1ÅEÓºÛhêgnl”˜äò+K‹×¸8SÜeke™“™ÁÊKÕ/UÏ“áA*æè`¿TG{•Óò‚ü‹øc`>‹kÊ©(ydgm¥9õ .)öEïjonlª«ñYë½{Æë@\c’™šbmaNS¼ÈíÛØù¬qÄ€¸ .ÄâšZqݾQº>˜ûª‘þ½{D¿b3‹Ðð3R÷ðà50—ÄÕÛÙîåáèïWS]õüùsÚûìÙ³{wïØÛÚd¤ŸïÒԞє÷™zÃ!.0—ĵz¥Ó¾=ÑÊß‹¤1åæ¼úôÉ\™þÔT”m414X¢½ÈuõªüóïM`¼Lù€šð©ghO¦{æ&Æá[6w··B\`~Šëì©“áa[¤¾ÓMCÉÞÆZª3uU4‚Ò’“šëk‡û{Þ½4ãâšÌ©ahOI÷Zë7†‡m …¸Àü š§È<âxr’TghàKˆŸüx™Ú5™3í ˼YtÍyå î ã's²ØÞ”c‰æÆFvFïŒèSO÷:Z›©E.-õ\k*Ÿž’lmaÎ=¾ âsF\ôÇ,ÿ šê*©ÎP¸ÕPS¥iâšÌÉ‹ËÒÌ$ÿÂ9Š-)Âܾ•íõõò¤ˆ DÂá8õt/.©çZ>g;`][S".0ßÄõäÉ“·W8‰vfñ"­¡¾ù«1¢ÏÌQ¥Àô‰KæŒäÅE¡‹"-µ¥¡N°·ª¼”KW••8ØZ«¡{ä¢Í¡!÷Rê¹ÖT¾‰w§âˆ¸æaÄUúðþúÀŠs–ÙÙ^¹Ìö2{S‚=„šº÷òâ¼±Qئ­Í\¾ès­¹ò4‹„¸®q ®q%M˜?׸Ø¥k—/Y˜šˆD\å¥cF\SÞ½§ÒϵVe¥æá]E¿é)É4{îï}tonÞUd™45«zñìh—¥™)ÛëçíÅ]ã¢Ä‘¸ƒê¿é)õ\kˆ às\¢Ð` 4Ò×{ñ9®·çÀ縔/¸±î]8{†bš—9¯\qëz‘஢±þ®È¶D‘:?f&õ\kˆ à“óóö“óSnݹ÷†€ï*ή/N8Œ™{o8êÀ€¸â@\qÄ€¸ .Ä₸h”¸ÔüÕ95|S_`‹kFV0­âÂã˜óâRÏ2ê|6Ô„Ïh[Øæía[¤rØùšúûÖUU°bª¬/ Ä5UâRÛ2j×dÎh°·{Å2‡³§Np/Oåf¯t\N™‚>“¢ããb׸ºp/U\_ˆkªÄÅú“Çi2µà÷¿  ›ð2žkÞ¹pö ˧±lif"ºÊO®"ÃÖÊRw±ÎçÊÒb.ŸþÞÝQä‚ì¢Rå•™ÌCÝŸ¾xn¼™±QuyiEI1%(”=ßþîN¶.†ŠëKqM•¸ø‹Îêé’µ8&¼Ìßõ«NËØâ2;·O<*q­ h¬«èé:ÈÃ͕˧HÆ×˳¥¡Žðötgp—*/Ú« /£ÃAsÉË—9ÚÛ;}Jô|G#®ƒ±4ëä^ª¸Ú×tˆ‹Y‹psqžð2®«ß>wæ]nemaÎMµ”ÅÕÞÜÈ&h,z¡x‰-šCa[4GªüÄ%sFìtœW­¤9£àòü¸‘ÂHvRf}I€F\¢Ëüä_¤påñÐÀ–Ð Š´TU®q±—d$Ñe U¿D6ùˆ+h?Å'³lIh~£LÖWWy¼ãvùâyD\hÂ5®?"fßÞÉ,óGC{•ÓòØ}{í¬,Gú¸L¶J©¼ˆd".Å5Ék\4=ô÷ñæÎ‚ìtóz¡h£Íõµ¦&ýÝOU^_ˆK£î*Šôó½3´÷Tn6Ëá®x)®Ã±Ø5.Oøƒ±ã×dΨ£¥‰¢GvåŸT¸·³]´ÑÐõÁ¹Y™OU^_ˆKC>Ç%µ+ÿü{Ëìl?ìg9éÇ“ŒôõøwE«¢éáž];¹»Š”`ÓÆq}šbÂgD‰ÜÎÏ9¸MxE½qíŠóª•\Z•õ%€¸4ü“óAëüÏŸ==Sï>9Àœ×Ô~³ïÉðà‰,Å*§åì3¾«Àœ×TA–°³²,¾¿,Àl@\ˆ â@\ q€š™¤¸~Æ ¶™Ø&#.ЄÉ#Ä€¸âˆ qÄâˆK¦oõêYĘoÞ%q͈¸¤†Þ|’RÛ—)ƒˆkJèlm676â/“º>0€¥‡úzÌŒØêŠS(®Ù8„'loå0€¸&Éú€uyç^.aÓÝÞª½pAW[ ÷òüÙÓ´w:üqáï@\|l­«ÊJ¸ô™“'¸åP~ÔŽˆÓ'rXÉwss(§ ïB¿—sõr>©+ùyÜK?o/ÚËh#}»#w˜˜›§$%²|ŠÙ¨ª—ùÇ^ç?LwæÝ§/VЦ樓`΋KðLBŠ+hJõ"rX~íò%w7JS7M#(2¡Ã&\DÙ£‡«W® xl¥ãrzI?Žöv”/h4êÙRÔ”àç³™š Ÿ?3Ò^¸@tä–>¼¿>0€¦Z4¡+¼rYù=á·+šI ¾‘d.(ñí!zxñý{>ž4·åú¬£µpbõ¨.®‚ü‹ôn?غþôÅÃ!ñ€M0·Ÿ€ÊÕÀ !ͪh>èæ¼šÒô“Æͤ¸]åÅéúå‹ç­ÌÍê«+Y%$®Y nš¶=l iííNʃ”qQt1vÄeo'ºf+3š.‘ii~ª¼‹„6®ˆKEq½>—òRv8%Ξ:ÑÝÞJ&¡Ÿ¬¼ ÏcÖ#ã+AUtâô_&vß^;+Kv‰ O×ĦÉÛt,–A“Dò÷¿;3-…L•r,‘ÒtѹóþÑëð—òœW®`¡M)àyïÝSÜ%}ý¥KøKÛ¿¾–ëçíÅ®ç°üñØ5.o–Ÿ™šBŪËKiÄ¥62SG/¦ÑŒ)rû¶YqC_CÄEݰ³²,¾c@\qÄ€¸ðN .P¿¸nß( ]Ì}áÎÈ@ÿÀÞ=¢ß¾QšÓ€ÆŠ«·³ÝËÃ=Ð߯¦ºêùóç´÷Ù³g÷îÞ±·µá‘G hNO.®Õ+öí‰Vþ^$©ÃÍyõ铹R)ºRàãé¡»XÇÒÌdGøÖîöVÑbåÅý¼½ô—.±43}77Gæì¦µ' 5UAþ~Fúz%è%þœ˜¥â:{êdxØ©ït“1ìm¬¥:ãçµ¶ðÊåž®ŽÖ樈íþ¾Êej+Ë­-ÌÏ>ÕÓÑÖ\_»%tƒTmÓÝ“5®.‡cPPGĈ¡—øs`–Š‹l@Ó1™çQç=‰K†þîNŠ©”óÉTYiªÔÀïÉ“Çiz¸à÷¿  ›ªžè-YÌ=ßõé‹'þÑKü90KŵhÁÿ“NMµJSª‚ü‹^îÊùæ&Æñq±4ƒ314ß²™¢™/³°F õtÉZSÕ“ÐõÁGâövvPâÆÒKü90WÅõäÉþCE)}ôÀÎÚªöÕS—ùèh-ܺy#ÍàˆÍ¡!Ûö¨".f-ÂÍÅyJzÒÚXokeÉݬ¤D[Sþœ˜·×íE6–îÝÝK±{T¹ËÔÈpú".ùžøzyƈa׸è%þœ˜Ÿ×¸.¾wÆÒÌ´ääà <Þqë`âji’—àW€¿³oïTõDw±®q€»ŠéÇ“(ÂaO„O\âÝÜœ°M¼©â«g¨Ní]EUz²ÆÕ%þ`,qŠÝÏ-N˜oŸãâ¯ÈÃÁÖâ?½êHÜA ´Œ ôÃ7o’¹8?Ý=©«ªXçëm¤¯KøúÔWãs\à“óøä<@}âzªaßÄw€¸T@\q .€¸`úÄjf’âú 6lØfb›Œ¸@&∠.Ä@\ˆ .€¸Lå…iD™“âRå¼ÔßÚzÀ¬ט_¦ž&qU–øúè/]BP¢¢¤xÎ ¦`V‹«¾ºÒÌØ(ýxR{s#‘ž’L/)âLF\wïÜž>q…mÚ˜p(ŽŸs$îàÖÍ»Û[M {:ÚX>å˜QΓáÁÄ#‡í¬, ô·o 㯵JÞ³¶0×^¸ÀÁÖºª¬„Ë?sò— Ê”dÆPžK5ÄG´LÔŽˆÓ'rX™wss(‡¯¦›EלW®Ð]¬ckey2'K´u~"W‘A%©üg P¹üáþ^ªÖÄÐÀÜÄ8åX¢èoG¹!îÀ½»£è(‚ôRÔœüðß®ûããbm,-ŒôõÒ’“äß+Ñ0Ýâ"kÅìÛ;}⢱#XÄ™^Z˜špÃÿxâQ–Ÿœ˜°/z×Ó Üû¬õl¬­&‰‘âböD³SX°®­©Ò»#wädfP¢¥¡Î@wiw'¥³3Ó£wF J F(¿'R Yfd o­û;Ï}CÞ;Cé‘~~ý–f&ùΑ1šëkw„oÓëëjÈGãy¸¹rùñcifMgAøy{‰þvD"íøzyÒ;Cx{ºÓб;À{»Ž%Ä{y¸Ó¯‰N™ûȼW¢`ZÅEÖbáÖ4‰KGkáP_?‡^.^¤E‰šŠ2ú·Nÿß¹ÿòôßœþø)íè`_SYÎîhi¢åìš^-Õz%?oÓ†JúhîÉý¯ß²þꥼOAÍò–ÙÙ^¹<¦7Dó©i6Ë#Û‹þvD¢Ù? J0Êt€ÿvñó}íS.®¿¿ÿ]ò±DC=]Î`Ó*®-¡”¯q…mÚÈ¥o\»²ÆuÔ9k\œK=xùÏÝÞ®‘HE,4¡Éš›ójJÓÏ‚ü‹4-’¡5I5¤J™òâ‡l\¾xÞÊÜŒÝk´K6 ©2K ZS\ªD\¢ IE\$Šè¸4ÅxR ‰D\²ï• LÇT‘|åæâLSÃ]Eš_˜¦§$³»Šô²öÕ¤ƒX±|YVzš¯—'ËÉLM¡—Õå¥#}%ÅÜ”Py|Ñ$‘¤Aó”ÑCÒRH#)ÇåU@“ÊêW#Z¦!>¢e(®£HïÎû7(M“Sç•+¸…5´94¤êÅ!4œ-ÍLE[S\‡c°k\þ>Þ¢¿цè@vËÇÓ#þ`,—ïáæz4þu¾±¶:8À_ªI GèŸBCÍ׸¤Þ+Ñ0M׸È]4gTÏç¸*J­óõæ>ÇEbþÞ“9YŠPèÅÿ÷M:rt°_ª£M~ PJt|•=z¸x‘VgkóèU—ÖfJ³š¥T~<ÉH_WQ´!A,¡\&|Ëæ“ÙŠ×ðS’·o ã7D3_ Q(Â!§Ýº^$Úú˜â"îŒØfl OÓíÄøÃK´µ”»'Ú¸g×Nî®"%ؼâ(Šl¹;€9™Rè?»ŸþPÓtjòï•h˜@“‡äogm…÷@\—æC35š_7ÕÕø¬õŒ‰Þ7໊ó绊³—ÌÔÑkw4UŒÜ¾]WŒˆ qÄ∠.Ä@\€Iò›æmd*ˆ /. ± .Ä&ð‹@C€¸À¸~Ø°Íø&:Ì!. ó‹ø ¶ݤqˆ ÄqA\ذA\óY\ª<$âÂqA\Ä… âR¿¸*K‹|}¸åÉ(QQR<Ý~˜B½H­qaƒ¸æ°¸ê«+ÍŒÒ'±aé%[ú₸°A\(®°MÅñsŽÄܺy£Œ”W¢DʱDsc#Cƒè‘#}ã:\PF´ªÚÊòÐà Ê4ÔÓ ìjk‘êI®"ÃÖÊRw±Îgå¥ê!.l×—¹‰q}uÕ›1X•…©‰|<£œïëåÙÚXOP"ápܸW¥ªUNŽ·® õõôvvDGEFn —jb}`@c]Í@O×ÑøCn®6ˆkî‰KGk![žƒ^.^¤5^qU•—r骲[ëɈK´*>}]ÖæRMЄ—KövSÜqaƒ¸æ`Ä5zEk ".f?J0]LL\¢Uß¿çãéal ÏM É·ª\ãRç%/ˆ Ä¥6qm Ý |+lÓËk\ä ¶@3E2ÌÚ H†Iå¥,LRñpUª¢ÄÙS'ºÛ[ ÐO™ž@\Ø ®9/®šÊrS#Ãô”dvW‘^ÖV–s{=Ü\Æèéj¬­ðg036ª~¥Î~Þ^Ü…)JúÆu¸@5¢UQXwa¸¿·¡¦*48H¦'6ˆkÊÅÅJRi5Ž«¢äÑ:_oîs\þ>ÞåÅùñZãâL“­•eNfëdúñ$#}=廊4•ÛAz×á¢wU\r´·[¢­eci¡HK•é Ä… âšâҨϫÏà± .l×¼úÊÄqaƒ¸ .ˆ 6ˆ µ¸°A\€¸°A\לÞ ™ ú@\@ê÷Ø4's2 ƒ¸Ä˜ZqiÚªµ@Í\»âÌö›ò∠.Ä@\€ù,.|#6lêÜ”Ÿ£21qAøuW∠.Äq .€¸à˜½ëˆ @\₸fíÍ»#wØYY.ÑÖ26Ð_çë]Xpi>˜₸ ®YJkc½­•åþ½ÑÕå¥C}=Ýí­W/çûûxC\âKDxXÜ©½O†¦`Œ"±í[ÃzºØÏUdñtë¬qq®,-³|zJ²µ…¹öÂô²¶²<48ÈÄÐÀPO7$(°«­…+ïσýñq±6–FúziÉI\æpïÞÝQæ&Æ%è%—?2ÐG±%µKù)I‰ãj@\@s°43!HíM?žä³Ö³±¶º§£mëæ1{¢™ˆÖ4ÖÕÐ?ÈÃÍuìòëÚš¸—«œo]/¢¯·³#:*2r[¸h$UŸc ñ^îõÕUTf_ô..“TæëåÙÒPGx{º‰;Èå'Š£| 2¹|Öœ* ˆ h‹i‘@ø³'~Ìãè`_óJk-Mb±bíÍ\z°·›â®1Ë7ÕÕˆv ¯«ƒ"1QqIÕÆÇÁÖ†Å{ {ëªòR.M{l­_~#ÌÓÐL,LE".6¢ÉHü7ÑS6Œ*åi:ÆÊß¿çãéAó2®˜ŽÖBÑj¥j”á‹W9“Ì«‚ü1» . ™l Û·?FJ\Žövb‘’”¸T,O‘ÏÙS'ºÛ[ ÐO¶W` ©Úø,³³XÄUUV2f·Ä4šÁY𙲻Š=mW/ç³™šâëåI»Fú*JŠ7m‘—Šå)Ì+È»0ÜßÛPSÄöšU¿‹Lm|’Žxy¸S=ük\‡c°k\ÚÅŒe×¾ü¼½Zë *0f·Ä4–æúÚˆð0Ò×âEZ&†!AîÜb·Ûi©ŽöKu´W9-/È¿(/.Ë\¢ g‰¶–¥•ç_$7Ò׳6>#ý‡b÷[[˜ÓÄ3=%™M÷ìÚÉÝU¤›’*£vDPIsc#Á]Å1@\ˆ â@\qÄ€¸âˆ qñÅEG€z˜q½… 6lêÝ&/.Єù#Ä€¸âˆ qÄ∠¦J\øž@3¿À(%.|C 6l»‰Š‹sh&œ¦”Å_\” Á.¡Y¶—¬E3GN_ !ØmU†í%kýôH< endstream endobj 536 0 obj << /Type /XObject /Subtype /Image /Width 403 /Height 509 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 436 /Filter /FlateDecode >> stream xÚíÑA İù7 x“Ü£•°ÕaI92÷DþK‚µ#Àã¼ÄL„ endstream endobj 546 0 obj << /Length 991 /Filter /FlateDecode >> stream xÚÕWKÛ6¾ëWðh¬ÕÃzÛ k (ºm×E›¸m³D…¤"ûßw(’Öc½[D-‚ô$ŠœÎ|óÍôÐyhçü¼wîî“ en1ÚP»q¢$ƒoâ£}žVÝyW€7Aä­*\·¸\Þ¸»O=”‚f*Ím¸©Ÿ‚Ý^ÉA>IWwúFJÅy¿w¾8>ÈxÈöÅ0Byå<}öPkçn³u½d…"ßsƒ0†q‰ßÏøïãHãqD¾›mµGŸ‚ üW¾ÛÞ«=ƒ غ™— ]U•šŸôWžÌ­…ÄunþrN°$…þ9pVé‘Úú]‰…°{þcû$—”Õ½W~DzðÇÎAO½‘ÀÝ©ãf¡álíG«¯´ Â$‰ñ«{Æ+|µ>Ä[&3…µý: V¬Ñ†:ZLÙ-ˆy¢Âš)G½™’‹ÍŒœîjxÛ6„þ²÷ø1leÿÔ{ÂÀ “«œÜ8•¤ÙP$n¦ÿ“îôŽÙ‹ÁN3 -éT9•¶ªúzœ‘)¿îcóÀê Ï̤á§hJ*gT›ö³7Ì4„¿8‰î&,Z~†ï ý‚ëc‹K®=¿qv个®'HilÙR™ö€7ð¶½ÀfpIOèÎ×~ºêñ–UÈ> stream xÚµ•ÍoÚ0Àïù+¬^“0þˆgÇim×jšZ•ÚÜÄ@ÖÄf‰ô¿Ÿ“Ø„¢uHåâØ~Ÿ¿÷žA`¸ >Ï‚éEœ€&‰ÀlX£„‚8±kŒÁ,÷£Íö²™OC£R¨µ(ƳëéG€[͈6š!'cní¶J8¶ò1M»…²F%8Ÿ¿leÀ}YEÊ@Z÷döî &lZÉ0Œ ¡‘ý.À]p ÿ±Õ{À‚åâ7.¬{ˆìt";ßí%EÖî)Ç0fþjzUrðE[ç·n&ÞÏdÇÑ![‚ d<4äDqÇé"_¬+Ç–ÂøÓxB1ÝTú§LMwl7+Y™\ÖÝ~Ò-ß„Z¬ÅÂéÖÒ˜\-êó1.¶dÑN@ÌäI&!‚‡]D„Ð+•Ie„ɵre×™´ážùa~!LPÜX…IèzçGíã[‰Ô' «n5âÉÌýQ>t¼ÉÍ2wßféŒ-¤’•02s¶õºJÝÕƒ-g!k8t?ï>R{f«};ù"ÛwÃ鬴±ý’ÛwzŸI·Mµ²öhžšŒ Nh÷ƒÖ¹³óÖt‡7(·§ŒÈùÖY÷-í§¤/ëáTï—j*&û63-kõ¡ Õ ø ?G"³¯¦—6§ÒWkÅûû°XîxxÅ»£xí;$6ð”ÿí?çÐë endstream endobj 543 0 obj << /Type /XObject /Subtype /Image /Width 403 /Height 509 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 555 0 R /Length 13146 /Filter /FlateDecode >> stream xÚí‡[×Þøý?îûücbCAil¨Q ¢ˆ¢QEcC]@¢kì+¢ô"RTšJ¢InI}ïÍ›^é¿/ŽNÆ-³Kùœçóðœ=sfæÌ¸çã÷ÌîžÓ£GszÎ/Àñéñ8I~ÎÑïÅ]еÆìú_ǧoXšz‰¸FfüÀñÑŠkxÊöaKà¸ýÂ3ûN7ØC¿™R_öj·tÚÒ×:«Ÿ¶ÇyµâòÙP­Å·G iÎØJ¾¾¾êŽƒb Š=:fÇã÷~aRsPÌQ—Øc& }ÚÒ×:«Ÿ¶Ëyµâò^W¡E”õÇCš3¶’¸KÝÑiÖα;>˜°÷ û»ý§Ù¯™4ôiK_ë¬~Ú.ç}B\¯Vji±¸ï(§˜˜ýEKinØ“ }ÚÒ×:«Ÿ¶ËyŸ*®¯ÒÒRq©;˜›å¿ïË–"{™4ôiK_ë¬~Ú.ç}òW___õù•ÎÓ-å˜üUw0oϤ}_š`":ó ²—IºÊEuÝöCÅb_³‰Ò×LöÕ KÚ·ŸZ<¯E]èœW+®¡oh)©Ñ”ÎE)™üUw™¸ÿKLöš÷ú“ ²—Ií.?ýòÛ‡_ü°¯ôã‘É7Íkv$J{ÌK¤¾Ù¹ ƒî†Å¾f¥¯™ì«Óǵ½Õb?mK›Õ³˜—èœ÷ qmº¥¥Åâz¼£ó‚Aû¿RQªIFš¡¢ªÈ^&  ᬰbgîÍ{ËËË·>¶é¦yåCm•¶p™áè*ã!ÿäÒnLÈkwö–~òÏ~xÚ'’SȉätxçÁ“¾f'J_3ï§ÚªíªòW¿Ÿ¶±ÍªL´yåìÖÎû„¸6×j±S\Ê@Rþª;º,<4ùÀW*JµÈ½wô e/“J5œ”‹Â’Wäå÷ÿùaFÊUuë¶ü?ûî§ß%Ú\;<¹V^~ðÅ?þ,áÙ; >’í¡’/½ÿÁç?üüëï²5-÷õDÃ6×®|ð÷ÏšwüèË3ó>ödÔ³˜$mi¡ÿ–2C- Éj?‰Ùž_RÿwÉï+ú«öPMÿtök5KvÞýû§òr{î»ÊÖŒ¼æž^öÖÿEoËÏ­~Wò»óÞÓî¨=‹Úª%†“òR­£äuõϯ4;ð\]LFŽáÄõÆ¿6~K¥ùUë³õòµÿøî·ß1VÝÿ|çņřÎÄμ¼¥B©sàÚ?ã²o-ʸôF^ƒœ± þãɵ6o‚þV!.óâáK• ï~üàç_¥uÿøVÓÒöC;bÒ×ìDékæýÔ¤“Z,·ØOۥͪRätæ-19ïâÚÒ ¥Åâz¼ã ØãS~­òh`µ÷®~¡ìeÒá‘"ÒOJ¹¸£©èíæ««¨g¥ñÈÄ­"„=§¦›žš?'íò'_þWJ’ö\Ž2œeO±ä?û껩©Åê¡Ò^ˆ1¼–’Ÿ¸¯D^þë‹o&§–ÊV‰.š¯bßÕè´³ÑÛó%ÿé—ßNI-QwÔžEmÕÜ´AÚ¦m§Î¡¾ÿñ×_~ý-ãh~LÆ%ÙQ4¸Àp~ä–[¯ZIÖîÉûÿzegn¬áÍhÃY¹X9ÚôÔ¼ñ[«ÔjÒÔÙi¹‘†©üõwÿ™•zeø–zý› ¿U«›•vEθzç…Æw>Rêû§T˜7:“¾f'J_3ï§&Ôb¹Å~Úö6›XÅZ›UžøÉÏÖÛZZ*.uÇÁq'C}­ò(ɾ«_({™4@0y8ÿñ—?ž¹þ·„Ì“qÆÓþ)•Jybú³Ró&¤ÔŒØÚ(C°æ’Œã3Sóý 7%ÿóÏ¿,1ž›òèÁÔÚmÇæ¤åNL©ohT¶.6ž“R+##“ëúõ·ßdGÙd~µ$ 庶J‰Î¡Òó>þéç_â~ï_ÿYyâÝàÔ29¦ÎUG.˜lMÍýè?“#È¡jßù王·§e\³µV¦Tˆ>ü^Ýûß÷ÃÏ¿?nÈï¿ÿ¾Ìxr\Ê ý› ¿UŽìg¼»þüû÷¿üñaÄõɯ^j<©l…ŽÇ¤¯Ù‰Ò×Ìû©I'µXn±Ÿ¶±Í¾Û³ïªy‹mVÑù­b‹ÅõxG×%g¦úFËÂì&“½”BA­#{™ÿ¬I‚tü(ãE!ÆxN˜žV8.õ¦º50µÂ7å¶Ôÿ䫿±ØÖ½g'§^›–õ¶q­L?:1õѸ2ãàÅàÔrß”Æðìwšc¡/¾Q¶þ뛟šw|ýl¼ñÔBãayúñÍŽÚ³ü©©Ôë&í”CIÍùW_;våÊõæ ¯ÿýãøÔÏõJú 9š‚z•CîúÝç/•Ö½ÿÏ/•g\åï|£nýôÛædœkˆJÏ]¼#÷q4xÄ?µJÿ&èo-{çœJÉ;ÿüþpñ;+vçÉ?J|ú©XãYóBÇ`Ò×tú©¶šÒ×Ì÷ÕöGkåûi»´Y‚N›-þVqDj“­¸6lèaB—=æ6£ŠKÝÑ-þ\ØáoL0¹ÑûšL*È^&  !ãyÆ\!Âxe¶!?ÄP6.µN»50­J©¿ïÚÿIIUÃýðíÕçê›;õÅÒúéÇÒõÊwþñÉ‚¬êÉ;ïWÿí{yyºà¦²ugñ¿äåwÞ_º+?vGþ¶³·Þþàs9]@Z•ùY¾ý¡9j2ì?¯–hëèêú{ߏ7'£8åXó8÷‹¯¿3žÚh~ᡆRå’õ,*ãÓjCÒÊç®.J?·i_nîõ¦~ñÝ C‘²õóï–ƒïøõæ?¾_{æÝpc‘ųdþóßÿ} ”[l‰µC­:û὿–1ïüúöGßì8zuyú‰I†óK³‡‘iw_6Üšf(›gÈK?»4ýÔC­”/9ñþÿ~þͯ¿þöåw?î|øi…Ú6ý›`óŤ_ˆ1^˜oÌ™e,˜j¸6.­Î7­©u‡vÁ¼¯™ô2‹=NékmÙ÷i´Y¿Ðä¼Zqùîii©¸ÔÝ—çÌxãÛ–"{™4@ayƩČ£Æ;·úë¢Ó/-K?³HzYúEɇËÇ?†Ê8º ýrtzÎÂôœEéçcš·^ó3Ü–_6Ö/HÏO?—~>*ýrDz~¸±x¢¡ÖâY"Òó2Ž-Í8#Ç7o‰Î¡¦§—É©£²8ýÜ|ã•IÆ[/Í~Fšä Óe“ n,Y‘~rYÆi-ÎL/IÈ8®´Mÿ&ؼESŒ•ÓŒ/êFÞjc›¡]hK_kß~Ú1mVyB\ÆûOðÄO~¬Õïq©;z&\ ÝÿáG¾µŸÐýŸz$\5mÀCBÓ¯ÍKÏ 4Þ°ëDcøaNzÁœôÂcÅ8ãm)T{e¨±Böz¼õºŸñŽºãxcã´ô )Ÿ+ªI/2ÖŒ16Y<ËËÆ†ée¢/µÜ¤ŽµC3Þ™š^9;½0âQùÍÑÆ·,^Z[ð3Þ•³Ïm¾Æ‚iÆëâ.¥mú7Áž[E[úZûöÓŽi³ÊâJ·]ð^_黡JÚ6ëÈ·ö¶ÿSß •>ë«Ú«yÔ+3¦ßzª'rdôo·¨ËÑ–¾ÖYý´]ÎûäÔÍïµ ¾ï ÝX3duÑÄB»X]ì³±fdú»íÕk,Ï<½:óhPFíÓ>‘#£¸E]‹¶ôµÎê§írÞ'Ä•ù·g›°ÌªÈÌ ̺gþJ[}¸EÐ%ЊkÔ¶¿ Í&pHM™ˆKÊï7ÝéÎüñ¬¤nþïÏ*Š»—‰µž™kéÑ£orèVâúßßïž<3âÊÞ¹qA·—ôßܳ§º'ˆ q!.Ä€¸âÄ…¸âB\ˆ q!.Ä€¸âj /<÷ÿº¹¸ä .€.*®v1X»D_\u7jW,æíÕ÷¥úÏ vêØ‘©éé™ qâ²ÙÁ—ÅżØóyùÛ‰ªy›¾¸B‚'Ç.Œ*)Èkj¬¿QY‘½'+Ð"âèâºüæIÁƒ–.öp$ùî#. ´$貸éÞÝÛë×®ñöp—HláüÈÆÚ›Š¦TÌ_j=&™LCª—‡»œbâ8¿üÜ¥ünC]\L´Ë'Wçä ëÕúéù)•e—íFĈ˦¸Ò6oáã-™‘Ã| ›7hM²lQŒ‹SÿýúÎvéôq›å&™œ3'bÌssqvêÛgùâX¥ðàž]Áþ²oÿ>½'ûO<ýÆe“ƒ\Cˆ¸qé‹kÁÜYÚ*DÍ­šáÂãq™ddDf³Ü$#›Ôš*»·¥O3j@ß>Êé^ìù¼¾¸´±x:Gd-ú:DÝjÒ>Џ|¼e g^G5˜Å—6Åe-âRýyäà·A.ˆ —ޏ”KF[`Ù`ODVYV"®,½ˆkˆ›«yÄ%õ×'®Øy ªG0yiS\kVªÏ¸B‚'«å³Ã žKÄå>xâÄ¥#®u«V¼<Þô‘×x¿WW**˜è7Vy–%íÃ%kå&™ø˜æg\2Õ>ã4À)eú‹§ŽIyp€¿ZY„y ë5sÅÌPŸqI¨;^{‰ëÔñ£áÓÜúËÎÛÓ#~Qì­êJ5ø1lÝ2b¨Œ@Gû?´?[}h?°?U8&/mŠK†‡‹¢£äŒ2@^Ÿ´¦w¯žJùÞ¬]ãI3üF<}üâÄ¥#®æ“7š¦nZ/åO|zØ·Ïœ¡Ú󬕛d.>!Tj®X²H)4lÞàåîöÒ =Ý\œ–.V+/_¼ÈéáøÑä þE„ÏP>U”̳ӵ×P±ƒÉ»|IlÉ÷¸qµï7ç­}±ÊÚÓ…~«øJüâêŠòk%EÁËã— .@\ˆËñÅ•¶%ÙÓÍU¢ÐØ…Q·ën!.@\ˆ‹Ù!ø‘5ÓÚ .Ä…¸âB\ˆ q!.Ä…¸@+ÄõG7NÏØ?ñ$Ò³•ä¿cqaup@tÅ ˆ âx&ÅÕa ~âêZâBÏ€¸ª+Ê—ÄÆx{¸÷îÕÓÙ©ÿ´)“:à8âêBKN@Lj«²¼ÔËÃ}ŲøÂ«¹wêkoUW¾qpHðdÇWZr:F\Ñ "W.·¶ÕâšÎ÷­/Ö¬S?%y“§›«²2NqþÕÙ3¦» pЯoøô°›U×u Ó…–œ€Ž—û`—âÇ‹Ÿš£³¦³ÅÅšõê‡N«ºV¦¼í;âôñcà‰‘âãbc£舫 -9 #®—^è©‚Ip¢³¦³ÅÅšuê_³´Ráý‡+JK$¦#®.´ä4< qIee“Û —vñå­é¬S_†ujýœóç‚&ÉøN]Öž‡Q¸ä´ÜCí-´:j©¸L&O$®XnM\ÖÖt¶Öåí¬?ÔË3kǶ[Õ•oßi”¿ÖLbG[ršßø“Hö¤¶‹K["#8÷ÁƒÔOkkªÞ8¸_íªÖÖt¶Öåí¬/½þо½Õ”Ìž1]_\]hÉiж£¸„ŠÒâè‘Ò_z¡§ŒƒÂ§‡]xó´]X\ÓÙZ—·³þÑC$XêÝ«çw7©¯/®.´ä4t˜¸@‡-9 ˆ«iÝ’Ó€¸:‘Ö-9 ˆ âÄ€¸q!.@\ú0íwqu9K .€NWK»a«»­;:¾âB\ˆ«Õâ²6ÅqScý’ؘGSo\¯ý©µý>›O­lqbg˜ï6Ô-['m$£N¥e­Ù&ט‘–êíéÑ»× #‡;wúäÎí™Ê²‹:¹µS´ô ®Ž—Å)Ž×­NœPY^z½¬dr€¿v6†Møl¨Ø9±³ú2)1Aš!mPš±6q•þéL2¥´°@êl\·Ö©oŸ¡!eE^ª«rX;EKïâêHqYœâx¨—gÁãy®$žiõ„Ï:#,‰µóþi›!­Ò?ÉAª®ýYGg2g‹§hé@\í+.óVí™âX¯^;ÅqKgT6)·sbgkͰæC‹z´s’gk§hÑ`žgènó3wŒ¸Lfu¶).m¼Qpår«'|6™ZÙÚÄÎÖf`Ö‰¸ÚK\öD\öÜæï%u«ù™;L\öDDÚ‡KS'U–— S‚Z=á³ÉÔÊÖ&v¶6óš„•ê( Õ’V%´»¸¬¢¥w [S\Ê©ÊÇ&Ÿ©µhÂg“©•­Mìlmf£-]¼HùÈO2êØ­Åeí-½ˆëi‹ qâB\€¸ .@\ˆ âĈËÄuæÄ±Ù3g(¿¹èÔå²¥ÌÒ:Úk«§ÚHèB⪻Q4É?,djQaÁwß}'[?ùä“sgßôñ’š¼ÙAÄÕ€.$®±£|_Yoþ;Jñÿ±;·gZs‘9OO\­käCãÕ$®X®ÌèìÔfè´SÇŽðÆèÒâÊÚ±}Aä÷?YiO#åàtYk¹ÅVY»Š·n7$%& qwØ¿ßÖÇg´6{³—€¸ZqXé¼úïØ/.Ù˜•©•iaÖ­ITÊÝ»ìß»çnC]EiqÌ‚ù:§PÛ#2k)ØÓÈÐ)ÁsÃgž;sJêA{X‹­²vÖ%Mò/-,¨­©z%~±Rhmöf;/ q= qÝ»woÌHßV MfcÖNħNÐ' [·\/+±éFµ=ªµ„ ãül6Rš!a’l•àG"·•Ë–ª˜µVY»Š¡^CÌWâ°6{³—€¸:=âÒ™Ùâ”ȹÏÏ •AÙ0o¯£‡>ˆKEÆtb§¨Èˆ°)ú­²vÚ œµCQ‹óWÛyiˆ«ÓŸqY›ù‰Øæj®Il#J9rð€Û ;Ÿq…†L–¿²ÌþFj¿VáÔ·~«¬]…(ÈBÄeeöf;/ quú§ŠÖfc–Œ:õ±dÔe¿"f‡<œ÷Xz·ûàAOãSÅ@ÿ‰Ù{²d×ÔØP^\½0tJ°~«¬]ÅÆukƒ&ùK¡ö—µÙ›í¼4ÄÕ‘ßã²(.k³1«ŸßÉøkql´ºÐêÞ¬]R_F[~£Fž>~ìi|ëÔñ£áÓÃä¼roOøE±Dé·ÊÚUˆúV'¬ðts•ú)ɛԘÊâìÍö_ârÌoη§ÑÈöú!âz&«Ø^´o#@WW7q .@\ˆ âĈ«ÃÄÐF:X\H$R{¤Ž@‡" .Ä€¸q .ÄÕ%þQ@quqõ ‘H“EÉ .‡_™&=ÛÉž79âB\$’£‰Ëf_@\ˆ‹DB\í+.æ7F\¤n.®ºÕëV'".ÄE"u!qúO,[׉âj©ˆZ-.Ç7^+ZhQ\_}õ•—§ÇsÿóÞð¤gO\Q‘ʺZ&ýquuq­KJÚ½kâ"ñŒ«Ä%™LCª—‡{ß—^œ8Î/?7G)oj¬_ã2ÀÉÕÅ9yãzµþ½»·×¯]ãíáîìÔáüÈÆÚ›:ÇQmQÅùWgϘ.§Яoøô°›U×ÕCe¤¥z{zôîõÂÈáÃÎ>¹s{æ0o/åÈEyW”jwê$j•æ ’QW 69—þ•ê·Ð~qýío1ÔçÁƒˆ‹„¸:F\3ÃBËKŠDA¯&­ž4a¼R¾nuâ” €ÊòÒëe%“üÕú)›7”ÖÖT͘³|i¼þqt„0ÚwÄéãÇîÔ×Öݨ‰‹Z î2¥´°@µqÝZ§¾}f„†”=z)m¥ZRb‚´Pš§´pmâ*›âji íWĜٗ.^” â"=Kâ²ùùNWuE¹’¿]wK¢%?Ô˳àj®’—àD­/qEQþU%_sýš0úDZS õ7k<Ý\Õ]ª®ýy(kGöòD ¥Á6ÅÕ–êˆëúõŠÀIþ¿ÿþ;â"=câ²³N§ˆËb¹ôk‰…”¼d´åÚáU¯çŸ³© kÝ?çü¹à€I2äTõbÏçõ¥ßBk"²y¥m×ø±cjko)yÄEb¨Ø‰âÒF\W.ÿqùxËhËæ#nõ¥j6säY;¶Ýª®|ûN£üµÙ$“—Ö".1˜TJ^B,›‡Õi¡âY™À{ž„¸:E\I‰ S'U–— S‚Ôò´-Éò²ðjnSc}Þ圹³Âõ3Øy`ác½˜à6Èåо½wêÊŠ fϘÞRq­IX©>ã’È-iU‚R>iÂøW“V7ÖÞ,/.œbó°:-lÅ÷¸°é™ט‘¾ê8+*2ÂaÅ%>‰‹‰–qœ«ó@“O [·ŒêÓçÅ^£}‡ÚŸ­œ”Íöïgq8vôЉßz÷ê9ÄÝMŽÙRqÉðpéâEÊ§Š’Q‡}Mç'q——‡{FZªÍÃê´q‘—úµyéPÒMÔOÇø­"ßœ'‘¨xåÒE±– q!.‰g\ˆ q‘Hˆ  q!.ÄE"u!q9Ú7ç¡íââ>ˆ«k-½D"‘”„¸€u .Ĉ qâè`qt ­_/!‘HŽðý®‰ Àq~l‚¸q .Ĉ q8 ¸Z±â3â®ÝP\êZ´®.Î æEܪ®´_Oà u7jW,æíÕ÷¥úÏ vêØ‘© Stq)™ÊòÒ9á3"çÌî\E„OŽ]UR×ÔX£²"{O–É:¹ˆ qi»yMe…Ë'ÉL|yoÖ.µ¼¢´Ø}°‹›i—°Ï4¤zy¸Kt4qœ_~nŽR~·¡nÙ’8 áÉÈKýúZd“]›zïîíõk×x{¸K$¶p~dcíMmĨ´Êb#m¶6.&Z.\Z›¼a½Z_"=¿Q#¥²ì²=ÃÈ; ÀÁÅuüC¾Ã†Š(”ò˜ó7¯Õbl33,´¼¤HòjÒêIÆ+åI‰ S‚®—•“ü×&®Ò¯¯%tJðÜð™çΜºS_k²)eóÆàÀ€òâÂÚšªùs–/·'âÒŠËrkW%ÈI«®• S'©õÅÕû÷î­‰·åðNp@qI·˜.(/dzg×k’‘Q›§›ëíº[P]Q®ä¥‚'JÞgˆgÁÕ\%/ÍP/OýúZêoÖˆ÷ÆŒô•­rœ•Ë–ª؈¡>EùW9öú5 „Z*.k­-Ê»¢ä¥Ùj}¹jÃÖ-â^Þc+.ó¹qþ|8ï<0rJÍCû³Gøx¿}§qÞìYÒ[¤q‚/IFUD‹FI¼WpårTdDXÈõ°Ú‘`¯çŸk©¸¬µVÌJkÕòÜ‹ç%B“t˜·×ÑÃï?œˆ)•:~>.íòúöoŒöžðÊ2o÷¦Æz¥Pu…¾ t"®–>E¯»QíÔ·Ï£ˆËÇ[zæuLZe­‘:­µq©÷áÈÁnƒ\”—̧D"µ.µïÔÍ:öÈÞ½K¶îÈLWK;,|l$¬IX©>ã ˜”´*Á~qúOÌÞ“%#Á¦Æ†òâ¸腡S‚•Mi[’å°ÒiÞ圹³Â-¶ÊZ#uZ«>ã ž¬–˨¹àá¹D\îƒÛ´qlØ1âÚÿún%½u»Aûx|`ÿ~6U ®¥‹)Ÿ*JF6Ú#®SdžOsvê/#8oOøE±êWË$ø‘A눡>}^ì%Ñ  f-¶ÊZ#uZ»(:JÎ(ƒåõIkz÷ê©”ïÍÚ%1ž4ÃoÔÈÓÇñÆpqé0}ZÈëY;»Õ½Í»|IlÉ{  +ŠKb›mFƒD5ê7"žm^‰_\]Q~­¤(80`yüÞc]Q\2ŒòöpÏ9®›ÜÒ´-Éžn®2TŒ]¥|ñºèPqâB\€¸—=¿‘´³W×6@\Ž` Gޏð$âB\Ð)â²8¨Å)IMЙ UÉ45Ö/‰y4éÆõúÍLFZª·§Gï^/Œ>ìÜé“;·g*ÔOç§Nò Õ’7¬wu(‡_«În¡Ó˜”äMžn®½žÎ|Uè¢â²8¨µ)Iµè̆ªdÖ­N” •å¥J›â ™RZX ’ܸn­Sß>3BCÊŠ½Tg§—jÊ1ɬ[“h³13C§U]+#âx–Äeq:PkS’j±97—”h+ØWÕµ?g1µ6©©”«Ç,¸rY=©Nc®ifúB\]E\½{õT‡N wêkÕIù̧½o}JR-6gC5©`S\:²ÕV³xRÆhNޏ´][‡N—ï°¡Ͼ©-¹pöŒ÷“A”Ét Ö¦$muÄ%ÑQ{‰ëÏc^͵'âÒÇ¢º›¸lNjêâJOKí;üÍ“ÇëoÖgN5bxòÆõÊV‹ÓZ›’T‹ÍÙP“¦NRŸGµ—¸ÔcJF}–eçÔ¬&s¨ .‡—DS;·gŽ;z`ÿ¾‚d²vlS·ZœÔÚ”¤&ãMýÙP•e • HíùTÑNq)Ÿ*ÊaÇFk×°gjV“9T—Êë»ç¼ñâ@\ˆ q .Ĉ뛧‡y{=K¡ aÀ3/®I/O8˜ý:ãGD ˆË‘Å¥´AmÉ€~}M¾HïPßæuuq^0/B]+Ö3tsQؼ|‹· »"®®%.Ç|Ǫ­ª,/>#rÎlÄÕFqEÌ7¦nmjl òט²UJtEq™üI;ëË}ÝÉaì™sF¥ùÇ>W.+ù]Û·©¿ú‘ò¸˜èÛ2Ôš¯efH‰I?ª©¬pà$™€‰/ïÍÚ¥–W”»v1ÿ9•d2 ©^îJ{òssÔoÀZ»‹õÛÒ~k_—íĹzä8™Æ´©AÍ?7 ”¼rdÄ…¸ºÄou".“Y_t&‡±gΕ%±1Òa%#Ç‘Ê ·n(¿b’ˆbˆ»›dFû?rð€ÿ„q’—u&U d¯­›6Zx8ï<0rJù¡ýÙ#|¼ß¾Ó8oö,éz-jOë.§uí¿ß¶`>Õ¹z®àÙ—v““ÃØólü1™ÆZ{Zw9­kÅÅ\=€¸Z-.;'‡±§ãË Kúµ#¥mM–žž¼a½Ì<œcç„äeäå7j¤TèDÙ»wÉÖ™éj‰Éì4ÖÚÓŠËQó-mÅÅ\=€¸Z-.;'‡±G\W.]|酞ʈ¯¦²Bò¨H~Á¼ˆíéµZJò¦…ó#õŵÿõÝü½Þºýç3p“Ùi¬µ§—£æ[Úþ6Š‹¹zq=cLŸòzÖÎîü RÄÕ…¸w÷ö6£A†fÚgш q9xööpÏ9®›ÿfq .@\ˆ â@\ÐmÅÐ)´Z\H$Rç¥Ö‰ ÀAFŽˆ â@\€¸âÄõ ÀÄzÝY\EyWfÍsàÔ»× ãÇŽÞÿúîVXÂf…º5‰+–++Ë;;õŸ:íÔ±#-:&¦@\ %y®.Î[7m¬(-¾ÛPwñ웳gLâ ž»0JN×ÔX£²"{O–º¸<â@\-WäœÙÖ%µ}\f³‚ZtYÜtïîíõk×x{¸K$¶p~¤²´ºhµrd“—÷Ÿ\·+Óêåá.§˜8Î/?7G)ÇÅDK$)fNÞ°^­/‘žß¨‘RYvÙžaä-ÐåÄ%º¬¨ Ä:%xnøÌsgN™/š²ycp`@yqamMÕüˆ9Ë—ÆÛqiÅ53,´¼¤HŒ÷jÒêIÆ+åI«ä¤U×Ê„©“ƒÔúîƒ]öïÝ#Z“ 3fÁ|ÞB]N\/½ÐÓÜ$ª¬ag-õ7k’ÆŒô•PÇgˆçÊeKÕlÄPŸ¢ü«J¾æú5 „Z*®êŠr%»î–_ÉËYŠò®(ù‚«¹j}O7WÃÖ-×ËJxót q™ÏÓa—v`XpårTdDXÈu©•^¯çŸk©¸,–ËaµË=«å¹ÏK„&CÈaÞ^G¼ÿp¶æJpØù¸”}µãDΙ½éÕu)®Ç2V;õíó(âòñ–žyÕ`_Ú—µˆKõ瑃ܹ(/™(‰Dzª©}§n.)ȓΛ’¼I†NŸ\:÷´>U ôŸ˜½'KF‚M åÅ…qÑ C§+›Ò¶$O (¼šÛÔXŸw9gî¬p¥|°ó@)T`òÒ¦¸Ö$¬TŸq…OVË#f‡<<—ˆË}ð ‚v€Ž¶ïœóbƒðéaû÷{ø=®1Oé{\§Ž•³8;õ—œ·§Gü¢Ø[Õ•jðcغeÄPŸ>/öí;üÐþlõ¡½´J=²ÉK›â’áá¢è(9£«óÀõIkz÷ê©”ïÍÚ%1ž4ÃoÔÈÓÇñŽèŠâêä]¾$¶äÍ€¸ŸWâWW”_+)  X¿„7âr|Ò¶${º¹ÊP1vaÔíº[¼yâÄ…¸qÎ? ¨ ®.ôÃ+‰$É¢d—Ê‹ŸuHÊèâ"‘âB\$âÄE"!.ÄE"!.;ÅÕŠUxŠÎ]Jq‘H"®V¬Âƒ¸‰Ô¹âÒY…çnCݲ%q®.΂dÔùuæRNIÞäéæªÌYúÖ톤Ą!înû÷Ûºi£:—ùÊ>&X¬½s[†ZçµÌ )ÑŸî¾ãÅõË/¿d¦§{ñ”KÞ—½W)|îþòúžÝ®ƒ\\8½ºvíÏ?ÿ¬_N"!.›âÒY…G´3%(àzY‰09Àmâ*›â’‘fÕµ2åå†uIA“üK jkª^‰_¬Î hqe-ëH@èÿ²„Í—³{—ä›-âÚµóµ°i!~øá·ß~»iãUPá3¦ú0Ifû¶Lýr qÙ—Î*<ò²àñœÉù¹9C½iÂøW“V7ÖÞ”ú3BC¬‰k㺵A“üËŠžxÆeme“ùKÍëÈéFûóä É¿q`Ÿß¨‘J8g²PçŠ+kçΰi!}ô‘É3®Y3g*ϲ$³-#C¿œDB\6Å¥³ ˜aéâEÊ§Š’QÇ}GMç'õ½<Ü3ÒR­‰KL¸:a…ÄHrð”äMê€ÔâÊ>&ƒVó: æElO7üù?yÓÂù‘÷ÍÖêôO†4¯‡Ÿ‡Ø·O”òé¡®]³æ§Ÿ~Ò/'‘ßœïôïq‰ ZTN"!.Ä…¸H$Ĉ‹DB\üÈšDB\ˆ q‘Hˆ lŠ‹û€¸ºÜÒK$I»°®"÷âÄ…¸q ®gàTWú*‰DR~B‚¸øÉ‰ÄO~â"‘ .é™Wç.ÁÓñâbŠ-âB\ˆ‹DB\ö»¥½„ÓaârÅ2 q!.ÄE"!®VˆëÞÝÛë×®ñ~¸ÞÖÂù‘µ7•òâü«³gLwà4 _ßðéa7«®+åMõKbc¤ÜÕÅ9yãz›Ç‘ )É›<Ý\Í×uµ¸K\LôÎmj×23¤D»ìu§‹ëøÑ£>^Cz÷zar`€ùâ°$âêq¥lÞP^\X[S5?bÎò¥ñJùhß§»S_[w£&>.66jR¾nuâ” €ÊòÒëe%“ümG*Ì Vu­Ì¼ w1ú¿œ½'«ù¢vï’|ScƒCE\QóçòÉÇÿýïwlß65x2ïgâzJⲈ²uÄPŸ¢ü«J¾æú5/wó#Ô߬‘IÉõò,x¼®t~nŽÍãH…k%EfmÉ{{z$®X.%ïhCÅÏ?ÿ\ÉÿðÃ}^ìÅû™„¸:>âêûÒ‹Z›©ºœóç‚&É N)±çój}uÁkÉØ<ŽäeHh±aÖvÖ&®’’­›6:ø3.y‘W§ˆk„w¹¥ˆH"«¬ÛnUW¾}§QþªõµWÁ•Ë6£#k»\͹(ÞÁì×=\—æ+…æÈ‰ÔmÅ•¶%yJP@áÕܦÆú¼Ë9sg…+ånƒ\íÛ{·¡®¬¨`öŒéjý¤Ä„©“ƒ*ËKÙÑæqtÄeq—ÆÚ›£}‡¿yò„äß8°ÏoÔH%Àì<°ð±0‰ÔÍÅ%ã8ÃÖ-#†úôy±—ãÐþl¥üè¡õîÕsˆ»›TPë‹Êâb¢eéê<ÐäSE‹ÇÑ—Å]̋؞nøó~ò¦…ó#•'ùû÷s„O qñ[E~«H"!.@\$âB\ˆ‹DB\ˆ‹DB\ˆ q‘Hˆ ÌÅÅ}@\]né%‰¤Æ]ˆ XW‘{ˆ qâB\€¸:R\B«ÅÅ×KH$’#|¿«Eâpœ› .@\ˆ qâ@\ˆ â@\€¸âÄ…¸q .@\ˆ â@\€¸âÄ€¸ .Ä€¸qq‹q .@\ˆ âÄ…¸q .Ĉ q .@\ˆ qâ@\ˆ âÄ€¸q!.@\ˆ qâ@\ˆ â@\€¸âÄ…¸q .@\ˆ â@\€¸âÄ€¸ .Ä€¸q .Ĉ qâ@\€¸ .Ä€¸q .Ĉ q .@\ˆ qâB\€¸ .Ĉ q .@\ˆ qâ@\ˆ â@\€¸¸E€¸ .Ĉ qâB\€¸âÄ€¸ .Ä€¸q .Ĉ qâ@\€¸ .Ä€¸q .Ĉ q .@\ˆ qâB\€¸ .Ĉ q .@\ˆ qâ@\ˆ â@\€¸âÄ…¸q .@\ˆ â@\€¸âÄ€¸ .Ä€¸q!.@\ˆ âÄ€¸ .Ä€¸q .Ĉ q´»¸¤€£¡#®$‰ä¨É¢¸w8&ЦÌÅààhÅ%y€.XKFŽŠ¾ºb­ÿRJ¢U endstream endobj 555 0 obj << /Type /XObject /Subtype /Image /Width 403 /Height 509 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 436 /Filter /FlateDecode >> stream xÚíÑA İù7 x“Ü£•°ÕaI92÷DþK‚µ#Àã¼ÄL„ endstream endobj 560 0 obj << /Length 723 /Filter /FlateDecode >> stream xÚTKsÛ ¾ëWp+š©1 ·>’LrJ[wzHr v4#K®$ÇI}µå&íLO,Ë>¾ÝýXŠÖˆ¢‹äÃ"™Ÿi¢ó,G‹’9É5G…†³`hQ¢¼º¨MiÓY&)Þ˜fgêônq5?W)ð̹ó*#Š)ˆ;:1ö…Âspé\’³Eò#a`C;äG.Ñr“ÜÜQTÂÛ¢Dh…ö£åIFIÆskô5ùœÐ€Ÿס³BêI!’-<$NÉFÑÝÌ¥l7›¶ñH¯»4£¸ÝÚî•í}µ“>Q4Ëá¹ô¡®=œã[J³®üe0÷NxÙ6ƒ©š>¨£ñ2¦yÛ¹”c¶`dB³ÝÖÏ>ÎÐU]{a_•k;ô$q*ðûÞ›õmšI¼¡«pžWë]gÇøtkä…/c+œ 'ê´CGÅ_!›.ÔÕÙÚ ¶t\£Œ@†F³±o½¸¬Mß¹¯~þV·uÛEý Ø{Ñ4¥†¶­‡jK&xOO \¤S’(ªç”PZ8¾A„‘y“#y|̤¿ð‚ÕóËFŸZ`á‡1Å,æ˜%ùó“eBÁÊ´"Ì©\gÂtÆÒ` ï`¤ìˆ™ ½>ôû¥’!»f¤ÈÏÇÔäEÇõìon^ªzÀ_×0<¸Hü˜2‰m×Wƒ{mWþbÔýÓ÷TPìyøZ"àg®ÔkPªf»¼è¾­Cò¬¬zs åø>x•v•BƒÌ®ÈKL›l­½3m›7)Sxðª]ÞáÝmBê‘y]äc ¶¶íÌ=!~H'=ƒÐEÞÆáBâ 6Â`My€_͹‡Ö8Pévî9ºŸºaê]¬û–JÚÛ럛cä¬>Ù.›~Ï—ö¿Èˆ¦âÖÿ/Ù«±à endstream endobj 549 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 564 0 R /Length 14544 /Filter /FlateDecode >> stream xÚí‰_Çÿÿý#~¿ïïS+ZQDEý¨µÅ[kUê}‹à}áU¥\ žµ^´Þ'7$$!„+ ˆXÛOkkë·í§ÕÞ§Úã÷‹ãšì&á’$¼öñ|ð˜ÌÌÎnæ¹3³ ™.],[ «L—'…\øàÁpÊs²{ûL¿È$®£'ßG§üàÁð}%¡®mØosÙwÎ~‘ÉÎà;;…ÒS®6«í×D;ªy·Åqù¾ŒÓó îÒ%®KÀÑÌ2^yÁåù±‡>™xâg ”ƒ£Îû¯¼hUÚ‰Ö4ÑŽjÞmr\¾ï#Þ,áC¦ÿÓˆ%àh#åYÆþóŽŒ;üÉä“ß8ÏøCwúÏ?lUÚ‰Ö4ÑŽjÞmrÜg|ßUƧپ?ÉØþ‘S÷› 岪íDkšhG5ï69î3ãùÝå|šë;Ëè·àíÐS÷› 岪íDkšhG5ï69î³ó÷ >4%gss;3wn~OYÆ‹ŽO9ýÀ «ûƒmÊeU7‚;)÷­g»h‚MÔ!\µÊk§lÛæ-x\AËì—ïûËoUò!—Yßm礸þŸþ²Œ—œzíô+¬r-:^g•€rYU€àgyøø¯»÷;­ù|ô¾*۔Ϯ>¶1ËÓ:¶bbÕ{þ…8“Ý™‹Æomx‰›¨C¸&j•׎üF.ؼ[SgvÛ;Ç}Æ÷=Õ|šíû“Œ—¥NM}Àà’Q`ñ‰:‹dP.« OšD:±é¨¬êÖç´›WýÙ(›”ÏV+~äúä ±’3aû4Ϲ23ÔÔÜ»óõoö«×&çØ¶Ù¹4/b[/5{˪gÕD„k¢¶Í›ß°ù-œþÚoÞ­¬3sæŽ.vÜg|ßkàã¤ïÜhŸþ²Œƒ–Ÿ™–ú-ƒK¶äDýHÊeU‚5‰ ÙÄÚ#ù´ûÓ/¿ÍNzòêAåݯ|ø7Ýÿ÷^Ùg ÝOïÿöû# ü~XõÅð‹Ú—óɧßüöèÏ¿éÕ$Ù§ì@TZ²üÓ¿¶düìÁïwG=[v«Ÿ†j¶_k§¨ï½_÷ÙO?ÿñçÿª¾óÃÆËÚž²“¼v öò³›÷~¦ãþñè/ýí¯ç'沚XUO¬JòÚûÜ©qÉŽ|F»2ó7‚…ˆ±+ãã[_üB'õÍOé(bu°}³žú¾_k§üðx•mJíûß=|ô'E6Üû‰Ê¤«Ñ¬«gÕD„k¢¶ÍÛªm Æ 6ïÖ×ÙêRÓ­*cu\¾ï£öÕðqÒwîUúË2úGŸþî· .ÙÒ“uö#)—Uˆ'oôÙ)ñ:Ú}ý`-çûºäKöë¹Wõõw#SÊ%å.OΤ,ªù˜Â§Õ½Â+ªþã¯æ©XsTuãã¯h÷ìî@) KS×ÞüoÔA¥Lÿ…ßQ|8j¯‘eä…ÕjMò•åI™, ¶SÔßýaióÆè”¼ä˥濙_f{Öö‰ÏûÔpçÇ¿þþ›ä-ÿë£Ù¦Õ²b’¯­LN Ù_¿h¬zbU›hþä¿?ýù×_±çÍ1ç>øó¯¿?þê§hiö¬„ÛB9¤²\pÓ'ß­{§hÝ‘üš;Ü;%v‰/#—Å‚)WÌ9›Sjúàó?QÅÿ6Üù®Œ“×Ъ‰: ×Dm›·UÛŒlÞÍB¬ÎÌD:œmM¬ŽûŒïûM|šíû“Œƒ£/Îxï[FÓ`ìdýHÊeU¢é–ž’P<õp½ºÁ’±¤æö&ÉùÐø’¦.ûøµI‘ ŠIy÷üJ1;ŽçQÌÒh¿þöÇ™‰jV”ô½¬¨ä´Èå¶ÓÚýòþ÷Ó5ô*u÷–³8­ˆJJ:dE|õà‡‰E,#ÿ(¬V “r ª¿žvŠúé÷?ÿùWÊe”4{aRÞ¤œeÉYcâ ‚gÍmbפòý/7•Å$§E%e; sßHTLŠ×ó/«ž*-=^õëïüå·ï~yøÓowž­•\™¨°-Ķ&Ä—ß?¤d{ÞUE'§YR&çѯ»D‚—Q¬pÁfÀ")ðûõÒ¶¸²Jr-,¡Œ‹ß*=7·±©¿_KãdKLÊ¥¹ÉÊ)É–V÷èÑã5’«ãšf‹;^\$ M(Ÿ”læ^]-¹6.ÁH#|«ó¢^ouòµqñÕ¶Ga1¯%”òëÉÅØ)Jªøüá£ÇCýч_þ²ùòíéIºÉ vÎzyr–Õ«‰²Ïnßý/•@E>øâpvmDJÙ¸xëñfÛÊp1vªD¹r*ïr‘ªª×K//L–‡ò®-+DêY)Ù¶ƒ—$æÑ;2&Þ–P:1¡ÒÎ%²sÅL9Arcwæ§Åï?ø½±ÿàîWוúu’+ônÚ/Ͷ‰: ×Dm›·UÛŒlÞͶÎOÉÉ,,Xg†ïÏ7Û÷'V_›uæ;>+NݰÊÅE, å²ýÎ0{£×H®-—dÑ’ŒhIæì$õÄÄ*öêÔÄ’à„ZJï[Ë€9þdúë‰Å³Ž5pýûfÉ…°Ä¦ÁÊ{ÙÓµÁ ¦¹§n[º¹ûßo–^MÔsýTü‰´µ’«+$YÄFéå-)éÎ`{”§Í/±Ôªžc§(J¹4%ÿÈE¹¼ÌrA¾ÿùI‰•‚_–Þ ½L¥q°£0%Ëv¿“‘£1~òÅ·Üü]wû{Û‹Æ2Ú©ÒÂÔèFú僟¾~ðÃãÇÆŸ)˜šXœ`¶-D®ä”39tãh¶Sg.£¶)µ·¿§é EÞþâ§³…·7½£X#½Fg-IwXšmµÓ¼ùɸ&j›—ߌÅâ›w³«3óÈN¿?ÿjb=¾ïqq]¬èâߥËB Ìw–qÈÚôˆ3ßYau©†V (—Uˆ¦7:åÜb‰ŒX$‘Ï—(g%i'%ƒy¯NM*çÒŸ.þ/Å”›ÞŸwXŸYcyh™­©Ù$½ôZR“ï·ïÜ[vL?ýèûú~¢Ýkª*îÕ£…_ÒnÝíOÖ¿­Œ>¬<˜^Ýðé7¤ÕkIå¶Gùá7KœšÉbøiìUúákÏ7Ì—ªã/Z&#÷¿ûi•$&Ѷ'‘¬áN™`GaLJ2ÌLÖ-–Èc$™{NËä¥õ_Üÿqv²Z¬zbUšu ò³8ûÏ$ŸUÐh‡n³V "Èaõ”ì?Ÿ~u\ÿÚ¡†ëÕ÷¹Db1bئüä›ß¯•|¼ýTaŒ”îÿ+’³KòæIÔÓ“JÆ'™ì—fÛDíøÎo¨\mMÞÖ x\NvÛH±ã>ã{ÒM>Ïöï]¬°È®³ðÔ÷'×g½qö{[Vž®çcõ*岪ñä>?5YïÌ«c$ ™¥ÞÿîLJÿüüÛ?Îk?Ú”re¥4sJrÓ3MY~…Ó«g nQ7%ÉK®¤¼'dµ÷¾ºÿÛÃÇ¿>ü³êÎO;¯ßž+Q å@Á?ÿú/X±¢bÓïÞúü;êOùãφϾ?r1SÊå)I¶§æ £“n„&UGH´K$2jöëS®…$«'V%ÕÍï)Mj~톔«‹¤òSrËȹêÖݱIµ‚…r<Ïüù—÷øøþÏR”÷èFäÌ%røæòÓð7öR´4k¥4{©$w¾D.)™˜dTï䥳m¢VS°¡rM´5y[ƒØqíGZ—ï{pò->Íõe Ú3ûì÷Í…rYU€ccÊÕ­)¦J*œ|5Tbˆ’ä¬O¹ÓØVH²#%Ú‰ÉOæ€)–Kr£Rr£¤y1)Y+Sr"$Å’k)cH²q™T¶NJ3—KóI”s’Õ¡ÉÁ£Ð«[R.ÑQ¢¤9¶5±SÔl©nU@š³2%oµ4T’\%xjÎ36¹~ФšNsJrµXõĪ4[¢¥%›.)Ÿ(©],ͧqþiþèäÛB ‘Ô,•PÉ×VI3–Jes$šIÉ&‡—È™7—c…4—àR®MI£0?CR6KRBç5&ùfs¯XkšhÛ6ïçSgÆ3¾KÞ†g¾O+:žgŸ¿³ŒÃ6Ëgþïœs?8ϬÓ_ Ýœo]F"¤Å‹¥Š©’J'_-yßÒŒ¥Ú…Ò‚Ò‚ˆ”Ò ÉfŠg¾GHK#$º½:SZ:ARËòN’˜gIKHÕ ¥Ê¹Ò¢iÒÊñ’zÁ£L–˜æ¤hI•,Þ*XQ%uÔQü"©ŠzXJ?NÚ xj­Á¶zbUš*­žŸ¢&qÆKê¸4s¤Es¤š©I°A(]g*yT5SR2¡±(‡—Èá›ËOÃÇ~zghMmÛæý|êÌxÆwémˆÝe¯Æ•G¤þwÞùœ!2õ«WãÊFì.o« Òäû ÔÂÛõ@‰ðW­Ü¡ð6o¢Õ¼Ûä¸ÏþžÕ‡mBpÊí‘oU ÛV0l«Ê)¶©G¾¥-½ÝVcãkÛ\x=ÅÐÞòH¢Èlq‹ÂÛ¶‰vTón“ã>ãû<›ÈåK¼~ÀèñgÚ~WÏŠ¶º˜íZ8`ð}sðcâßÛÔƒ³ÛÊwŠ¿u£öÏÝèìè„pÊÛúîÙRtéÒo=€ïÁ÷“G’ï÷î~âP…QUÏ®*|¾ç¥_u PU¯êómÂwWf÷ÖM¨ªgW•« |‡ï¾ÃwøŽªÂwøßQUøßá;ª ßá;Z&ª ßá{gh™/¾ð/øÞ~å7ëòº‹ï*¹,bfx?Ÿ>=¼º~å䱷ừµL±†ßá{³|W+åúûîÙ½KW¨®«1d^¿9+Ü3|oZÜ<ì´Ì~>ÞYW/²Ý°IãY8óêÅ~}¼/ŸMmóslYU¹ŒVtàpÅ¡ï§ ›<ѧw¯îÝ^ñï¡oíÜÖÉ}Ÿ7göÎm[_"ýWG¯¤»AÚåâé"$Åï Lã‘Ãÿ}ýÊ¥CRɰÀÀž=¼ÆM£…f%³s”䄸!þƒ¸ôù¹Ùžê{èÄ oíØÊ…¯ž¯[×®œ{—Ûݵm ½ÚãùÖøî"ý©Ãª¾{ü¨¯OŸµÑQçN§;êQiÒ”‰Üw²L£R¾»iÃk¡!%šB"tò¤­›72g¼>µH©0UW¾¹}kŸÞ½fNŸF…p»!“&4+™£D„OרU”~{ì–‰ãÆ¶‰ï©ÇÒ›N7|ïž/…MšÀ™5zÔÈÝÛ·°4Ô<|ûù¤]8CdÞ‘Ôf °^تdn×~—g§eîݵsò„q\8>îMʾ?n'·;aL0½Ê?böµKs"©þT¥Õ+—³xªÛìY3lãsÓ®¬\¶d_ÿ>½zΚözúå󭩪àU¥{T_ïÞ×.œáÇР…bβyÝšA~¾/yu5røÉ#k%‰ß3|h ¥¡”[7®knU§M ‹^¾Dð%±wVìòŠˆÛùNãœZ£Að¥À! Y.¦î5(0€™X¦Ópa³¡ŠvËuZ¶Û«G÷f%³sÁô­ô}Xà”ø½™W.Îs#fE̘F‘I{ß ìOï)—&bú´ÕQË(°|ñ‚q£ƒÏ§ž$Æ¿²bñB;¾·¸Ó̹v‰n/—ÏXíKæÏ#ÇÏ›Cá ïžôíëC¯òKŽZ²ªD/qUbñËÍŸ8nÌÅ÷NT‹_5.øÕ3'‘}Ó§†-œóF{ôït«á®Ǫ¨¥ógGØ?:M[Ξz‡Ä‰ZºèÕ—GN—eÏÎí$#ÝéMinUÉÙ3'Ž ¾$öΊ]^±ñ¤þÒìV@Úe&ò“‰í:™¬eGi“ñüõ‹gøöåÂ#‡Ûµm37¤ÈŒÆ¸ÿ@¿SoâPä?p@{øNP³~U47Ò8,MäÚÿªK)Þªdª¿J¼x?š«raJÀâJ}§)þÒ™ÓÔQ¶Çü=°¿ovã­‰þR?H†Ú?ú¥÷NqaºÔ/u÷¬Õß~×ÄœO=ѲªR_–É{0ÂG컼b'âŽó÷];¶5·oCß[v”û~ì€dlð+4*ãڪ׋]¹ø}»w ñ”sýò´)¡ÔƸHI²CÚm'ßß9|`xÐ2eh`íÒ`ƒ:5ªÅ[•lU%~|–`|w/¾›Ýº¾ÐNów]ìÞkɾ} ¤›ut± xì ”†>Þ½ Lܳ» ûw±wVôòŠœˆ[>Ÿ÷óÝ·›¦Ïu5†¬´kìùü–ëÙÌ:,d2M´ÛÃ÷–¥Å¾Ó |Ç–4Á$µé/‚F®Ñ@šú&®Ÿ²Ó P«Èx2ƒ£~Š"Ø œ|’L¾ÇnXËZgN›º6:êßA¶çÂï€N=ä°§› ›m×⪊ùž´ï­WF §ÍÇß9”bÿèb¾ ÖŠÞš„·vÑÔ¦ów#µ¸ç_^±qÇÏß•²¼ˆð>Þ½{xuü*ûüF×1Q+¸'ç`£î¶õ½eGi±ïÔlöîÚI]!Ýù§„Lä§¡î‰v·nzú\hÙÂùl–G£š#sñ4Þ¦Y'Í=iB2a<+¤_ïSÇ·ÌwÏSGöf¬eN±cóÆ^/õàFøVçBOšžÓ“ º±xªêÓùûاñV¯¤dT+º‰QÃ~=4¤•Uµ302xãÚ:‹;º˜ïVµz=,”주ä{ÿ¾}[ò|¾¯Ïº˜•ôöYžÏ§$³çóbï¬Øå;|¿Î¥>·i&¼µ›îÕ^Ý^¤ù&Ûù ï­ÛhÜÈ:wnD77r÷—l¤Gï8õbÜsãÍëVóŸêx÷z©½‰ËgS©VÔü(L] …ù»[=‡§ùH?oþdª[døt.~åÒÅ”uŽtš4ý¤›9 `hÚÒʪÚùü}ëÆuÔASGÏïš.æ»U­hj@o]çáCSâ÷¶àª’¡a“&P™4—9|ûü]컼b'ßÝ÷ûu!Æíڶžé}âÈÿ~ø~¾?ß¡»7Íé¾Í>’sÇ–9vÄ¥÷N=u|\ð« æDÂwøßÅÆ¨ƒüú; që–Is̾}i >-Cè !ð¾Ãwü“)ª ßá;$BUá;|‡D¨*|‡ï¾Ãwø‰à;|oCþÁ†­“mtcé´¾ÐÙ€ït¸i,|¾Ãwà;à_@\øÞ¶7LlØ\vã[ ßÛÄw|ʃÍ57îCgøß±Áwøß±Áw྾ÿëþš=|‡ïð|·ïû‹/ükê”°†:³Ã€íœ¾·F®絟Ña±”€vÀw[ßçÍ~#aßøî1¾cßíøn¨(>4ˆ-ÒÊ÷½@!œeYÞ§w¯ˆðe%ÍZïõf­iÇÖØÀÁþ}ûx/Y¸ÀT]é^¾³Ž’¹ó×_:x`h`@_ïõëÖüú믻eóÕ+WØ;råòeбÍ+¸=~ü89)10`°OŸÞ'Ž¿#xP œ:y"`ð þßÿ…ï𽕾Óß«Ï~¥Þd´ò}ÔÈW.œ3«éžµbÙâEÍZïuoÜ®)!“‹ ”Õú²sç¬]ãîýûÉÇg…Ïøì³Ï~øþûU1Ñq»wQä£G§½þZnN…sr²)üèÑ#';|èàŒi¯úé§Tà®7w ”v-˜ÿÕW_¡ÇÖ&¾Ö®Þ´~ñ¼¡Rï?p@³Ö{>,H•ßÔ×—k‡ørwßG½<âã>âÂß|óMÐ4$~ÿ>úKaçñï¡·o¿o_UÚ½wïsŒç±µ¡ï7LÆ1¯Ž¢‘9?2'=-,d2ƹÕCº¿ØµYëC‘øüÅG¼ždw_ß_êÞ?Þîú¯ÿa/I’“(†“;o\¯ÿøã‡¾ÿý÷ßð[úN(d¹ÔÝ+õ,2(0àð”ªòÒúZýmîzpÇiÔ*·~^ÇM™ÙöòÈáŸþ¹í»ÐÐÐ@ókE¾|°ÿÀO>ùD0¯à6rø0ÛþÝ*£­þð¾·Þw"~ï[‹Ìc‘ü|OŸ8^Wc ¹yä¬ðæú¾OÜk¡!JY ä9Ys##ÝÎw?ß¾ÿùχl÷ôéS3Ã)†æìï¿ÿ~Ôòeùë¯¿Ž ~¥²¢‚ªñãÆüþûï¶y…çï‡ÑüýîÝ»üù»UFøŽ­|o¨3OÆ"Ϧž¦>º»W·ÿ ûö4×÷›µ&ÊE³ø—º{9"õäq·óýä‰ã>}zóŸÏ¿›šJ³øîݺ’ãJ¥‚"׬^uéâ–åÔÉë×­±Í+¸=zô(1~? úúxSFÁƒ6×wþŒÖÃw€ïÏcƒï¾cƒïð½õ›Õ»õ#í6/|‡ïذÁwøŽ |÷ßq€+/¢ßÛÐwt"Ø\¿—‡ïà÷çá;ðßðßðÝ}/ X/²SÝ0±aÃz‘ø>-6lø>-|dž ¾ÃwlØÜÅ÷ιʌgøŽÿ…‡ïð¾cƒï*¹,b¦eѨ^ÝF¿ròØÛð½Å–µò7glÓôŸÿ,Y¼ˆÞ¯»Nš8^–—çŒÑð¾ ú®VÊô÷ݳ{—®P]Wcȼ~5rV8|ï¨îÕ*ã;wúùž8þÎÿþgšL5K—,‚ïð½Å¾Ï›3{ç¶­öÇób«F^:6xÔË={x ñ”’œh'ÒM}>,èƒnsáë×®rŠ¡xÁ5"ukÍ“1+£:h ÁbZ°¦$¶Îæ;uïb«Fôëêc4* ±Á²E íDº©ïÛ¶Æž;{†_~ñ…w¯—~þùg Ÿ=óÞöm[ÅÖˆ´õ½5KLRç~÷î]gzð–­)‰­³ùÞ½Û‹µFƒóÏëø«FdY„¢¸HÍO 馾«TJn™·ñóí{éÒE ¯X¾´ @õÈ‘¶ºµf‰Én]ÿe»ºœ˜ï-XSúw[ßÅVÌÉLŸî۷ϰÀÀsï¦Ú‰tSßùå—À€ÁüJ¡ZýZX…)†“ÿ#´F¤­n­Yb²Yý{ Ö”ÄÖ çï»vl³ï»Øª‘·ž,Au&õÔ?_‡‘îø¼nÆ´×iÔ2i"…é¯R©Ÿ>{IpH[ÝZ³Ä$Íß>$ø¾·Éš’Ø:ãóy?ß}q»K4…4éÎJ»fû|^lÕÈyoD*d¹7LFR{ŸŸH÷õFòä㻩©N=}š =ööÑÄ׈´Õ­5KLÞ¹sgЀþ§Nžøò‹/>|h6›Øóù6YS[góPÊò"Âgøx÷îáÕmLð«¶Ÿ¿‹­yìèaŠïÙÃ+xÔËW.œ³é¾¾7ܼI“èPøþýû¦~ùñ5"ŸÏ·f‰I’zñ¢…éõb×É'°Ïß[¹¦$¶Në;À÷ç±ÁwøŽ |‡ïذÁwøŽ |‡ïذÁwWö׸,ð½m}G'‚Íõ{yø~¾ßðßðßAëßJ°^d§ºucÆõ"ñM?€ï×Áwøà;|‡ï¾Û¡s..Ã?}g€ï¾{†ïÿg¾·ó]¬ÑÂww÷=/ý* pÈ3¯«ò²K5êzs3%èuYúUúkUla¾LðX…ùyÅZYQ¢-ÌÏ…žð¾?gß¹@C­Él¨,)T)²Óëj ö³7Ô™•9ä¬"'“Âübµª|¾×ì¦ê EvËNasuôtMßo˜ŒÑ+–õóé3 ¿oÜ›;á»Kù®Ìͨ5Vq᪲b.@1_¬VV•³\•e:ŠôQ¦QëDb*Ê ò²)@e|µoÖÖ¨r3ëŒÕ¶÷RVÕ¸œ(U’ÂpÓe}ß¶eÓk¡!%Ú¢MaèäIðÝ¥|§N¹¢DGz“†å7kMÜ€¹¸PE=i¡<§Zo±¬º¼„Â\wlÇ÷5Æüì4ûG/RȸÛý¥°uW^¥/e³~Ÿ‚nAªÜ¬†µô—Ý € ú 5Ͷòs³á»KùnЗÑ(ºqN]”Ÿ•VYjq_«Ì7V”6ÞŒ4ö.ÕÐ_ ‹çùcuYÆ5;‡¾QSMGi¨57ÎÌfãVŽÆ ¶‡Ðäë Ç c}ïÙË-KøîR¾S‡®ÈIçF×4ÒVËs(L1 ½eˆ®U“túbù;¿Wd¥Û9tiQ{ÊÇAv[? ¨3SO½Õ!è^A»ôbºKÿ®ÈËï®ö¼N-Ï¥A{Ìb:ý¥¿PÞô~Õªò³3 úR˃8£Á¡ï–ù{A¾è“ºg;t‚¬»ç—Vk¬VæeÒ½Èê¶G®æ{ì¦ SÃB-ówmMäừùN#yÒ™æìÜÌ/×qOݩӯ©²< §á=…oŠÌß©G6*K‹<Ÿ·š°?™ÎçqÏ ­\¦šÐè¾»ïÔ¢–-éÛÇÛÏ·žÏ» ïµ†Jòˆûè¼Þl¤0u릞ºªq:ß$`±F§VˆþžUfùüÝhç¸4J7V”[ErwA— óeðߟ‡ïø~€ïøþ<|ð<ß­ÂsàÊÃwà‘¾øà;€ï¾øÚÏw,Œˆ ëEà;ð¾ßðßð´ß[ Ö‹ìT·nlذ^$¾_ðý:øß|‡ïðÀw ~ït6ß;óOØá÷¬€Gún¨(߸ní°ÀÀ^=º÷íã=kÆôKçÏâ’º ï7jª‹2yfAþ¼—iÔ–ø¬4ö+ñv0V”æçÉ2¯)²Ò‹Õ ¶v¤±¢¬Pž#˰Äë lÝ àI¾O¶lÉ"µR~ÃdÔ—ûHȤ ¸¤.ùûó9eZõÍÚ‚ç–œ *KµyÙu5‚•¼ßª¤H‘GÊ߬5Õ›Åj•æÉOOÊs úÒÆòMåÚ"º' xžïÔ­l~|ØjYM†lA(Ÿý|4Ô²ça)'óºp¼Ý§€›ú>mê”9‘iW/›Õçï)I‰3¦½Î…÷Æíš2¹¨@Y­/[0wÎÚU1ð½]}רäÔ¿×ך,ý»¶v¹xyæu6&§ ì?„A_¦–[/ÑÞPkÒë4VwõÄù{¥>vÓ†W^Ù³‡Wà€õkV±îÞª=_Ï•ŸŸõt]*à‘Ïç©©(òr-˜7ãõ©¶¾+d¹Ãµ…ü‰ïõbWøÞ®¾åçÒ´Íßi·5ý»©J¯ÈI7WWæiü`ÛïÏû<Ž:÷>½{Yù®/Ñ Dc~~JŠÑ¨Ux^÷Ü|—·Ýü½º¼D‘M²W6w^ÜÝ÷IŽ¿}„äõ&#MÆW,]B3z+ßÇ}8Ej•qÿž¸×BC”²<XÊs²æFFÂ÷ö>_øôù¼Œ=Ÿ×‰=Ÿ\<¢¢XC={Íã]A~¡š†y7j %E*Ìß=Ò÷ËçÏF„ÏèÛÇ›æïAƒ££–W•—:ù|>aߚſÔÝkÔÈ©'Ã÷võ½Îòù{^~æu‚üùu©¦€û\¾T£~:b¯®ìëm”ᆠÕ奪¼,Ëçï9ÅjÕÍ's€ïÓâów×ÿ~]¡<·¦J·¾|Àw€ÿðÀwß|ðÀwßAs}Ljذ^$¾ßá;ðßðßè´ŸƒwÈÆÿV|àù北¾…߀ïðݧfÀ—\‡ï ýÞYl®¶ä:|ø™N8t‡ï¾Ãwøà;|÷$ß]pñèÖTÉ¿ÎTU¡ÌÉä~ƒº5aß;¡ï.ûû´•¥:JAr]QiÑÓÔ ¼¶> <ØwÖUuëú€þ¾óÞˆ,ÑÂwWö]W ¨(±,*Q¤È3”?•Tžy-$ך0ðlß¹ÀÍZS©®hÝê˜IãÇÁwWö]•›Yk°,%ÏJ«7=]u‚?oMtß9 å½ztç yä¬ð~>}|z÷ŠŸQQVÂÅ×›kb7mðèãÝ{Ïî]Vådg¤ûðÛ¿'î–eICÔ²%Tv¿¹ƒ¿`;¸ÝþР‚K¶:z%¥!(@»‚uãgONˆâ?¨g¯ñcGççfsñ7LÆè˸ÃŽ¹ÓÃ|7Vêm—†á¸%´jLË€Ú§/×i7¬[2i3jäˆ+ΙÕtˆ‰Z±lñ".~ç¶­!“&)Õú²51+ùåœ9}Ò¯__¶¶Ý¦MBÃbjX(_ØY3¦S$KöZhÍ#ˆÐÉ“¶nÞèÐ÷ˆðéµÊT]¹=vËÄqc¹øm[6YÊÑqåxdÿ^­/)j\Ù­¢D«S+ø/¡‡ïÎÏß9úöñVä ,:f¨ÔSwÌ…‡a]*¿œÄ}{ùùe§?]W4pH€JÞ´ì B–Ë–¿´4%£W¹0•àÐwº5qa³¡Š H(#¿ô]§Vê‹-ç®QÊ«ŸŒ¸à;|oÁx^_Z¼eãú°ÉÜnNz…éÀÝ º?YáFѵ¼Å Y9¤í¦õëø‘”’ Î) _XþÓ!~ ]‡¾ Æ[•ãa¾‹Àiœßá{ËæïÔxøÝåá)Uå¥õµ&úËR ìßiM]?MœéßùyÅúwò—ºo.LºCßùý;R<¯¯7×ȳÒG5•ÊÜ «ôð¾7Ë÷ʲRšJ;šÛàç{úÄqê 5*Eä¬p–òÍí–ù;EÚÎßiJ>|hЮÛ¸H-<¿O –’±ù;(¨\}(ûî7wð×uåg·sÁR 9!~ˆÿ ž=¼ÆÍÖ ¿a2F¯XÆ®•˺²ïÆJ=ë^­pè;üó³ÒéþP\¨j¨3ÛOOÝz½ÙÈ…Iyµ<×~zYÆ5j OÆ&Ú…ïîå{ì¦ lAöÐÉ“¶nÞÈÏš1½TWÄíîÛ5%drQ²Z_¶`«bXö§Ë¾‡…ò…åg·s1ß#§kÔ*º±lÝ2qÜX.~Û–M–r´E\9žÝ¿WëKhÌLŠ-uÄÎô×´[”ŸKwE‚åÏÑE|¯iòÝl¤Qºýô•œú÷úZ“¥×Ò.|w¯ù{à…¬é®NÝhP`K¬-|ú€hø° U¾Œ —k©çeÙUò¦x*‡/,?»£ˆù^®Óra³¡ªWî\˜2òËñlßuj¥¾Ør4JyuY‰“¾×›æÔµÆ*en†ƒñ|A¾¶ ŸL'(àpü@·Ev7Ò íÂw÷êßiÀ\k4_R¨äO©ÓW–éÙéÔM)ò̆J‡å×Y>ÏËϼNP Îh€ïb¾³,bawÿ~õûAƒÝñC|—ýü¸ïxžŸE,쎾¯‰YISomaÁ”ÉkVE»£ïóýy€ù{{CS{ÿh€½lÉ"öð ÀwøŽÿ—ð¾Ãwøßá;|‡ï¾ÃwÏóýl.³ÁwÐéÃwà;|ÀÃ|ï•/à;ÏŸ\ÿ¾Ði?ÄïÀwø|Àw|Àw:Õçï²áó8ðý:ø|î25®|ÏáÅæ þ<çw¸Úоøßá;€ïð¾»,øýy[.{dªªPæd6ku$ç ‡ïð½]}wÙõa]Öwµ<× /m§Âá{›øÞ&V{·|ø~KhH‡·‚2Zž™&ÏJ+Õ8o–X‡å™×ù‹ÓµÌw;§Ù7 Ï^¾»—ï‚1•¥Ú‚¼ìºA¶¾dûùÞõà{úN-duôJnåV Ð.Kœœ?ÄPÏ^ãÇŽÎÏͶ!Àw×ñ]-Ï1V”sa °eš7ˆ:ë’B ò³Óõ: ?¾\[¨ÌÉ —tjECãâïVëÆÖ«5J9% NŸõæûgÁ·uþFA÷4Ev†,óšZ–]k¬bµ--RÑ)`#J_Q¬ÉÏÎ`‡®(ÑÑIÉ2®©r³LUúªÒbeN&•æñ¾ÇnÚÀVfO6¶ïßY±0¾_ßÛéƒæBynM•Þ]Þ‘Ž­m[çùYÄÂðߟw…ïÓâÿeðýy€ÿƒïðÀwøß|‡ïðÀwøß;¹ïÿ`s™ ¾€N¾ßá;æ{‡¬|ßxþtàúð€Nû!|¾Ãwà;¾à;¾ƒ¶}+¾{ê­6«o1|ÇÿÇÎó=^øß|‡ïðÀ÷Öãy‹ËÜrÉß«À•}wëû€ þ5­ô½Mú,\E¾îß[Ótá;|îë{]auôJn1) °•Åâ¹¼¶#~`÷›;ü|ûõó鵜­¸ ßá;èpßc7m`‹E†Nž´uóFûñbý;?Þ’Q[DP`Û–Íð¾ñ]l1h‡‹DÛñeTäå°Œð¾ƒ÷½g/¶ ,h×~¼3¾ f„ïð¸oÿÞ­ë ŽûwY.úwø\Ç÷-׳yzXÈdš¶ÛgyýúõUÊò}ŸÊÍß)À&þð¾ƒ÷†Ü1Q+¸çðàÅãYÞ½q»|¼{Ûy>ß·÷ÊåKÙƒ}øßç}Þ?—‡ï¾w*ßñýyßñ5Ï øÜÑwß|ðÀwß|ÿƒ ›Ðßè´ƒ@ø|‡ïÀw|Àw|Àw|Àw€»øÞV+Lái§ÒV?°Ð¶¾·Ì8ø€Ã¶Ý&? Ô\ß¹ÛH·®/øôîõêË#7¬[«/-Fÿ€§úÎLÕ•¹Y«VF òóÓ¨Uðö»i¹s¬^½tþlð¨—{öðâ?(%9‘‹,PÈ#g…÷óéCcƒˆðe%,—à‚q¬´›µ¦[cû÷íã½dáºÕpñ”2zÅ2Ê5 ¿oÜ›;á;€ïíí»®P=ÀÏ×êÕ~ýO½s¬®Æ@¯.[´‹5rÄ• çÌÆjCEyLÔŠe‹±\‚ Æñ¹zJÈä¢eµ¾Œî-kWÅpñÛ¶ljÊØ¸D|ð½½}¯7»{u³zuð  ûö©ÅŽk¨ÔûÀr .ÇJ>,H•/ãÂåÅZ3paJÉ_¾øþúwêÍ­^ÍÉLŸî۷ϰÀÀsï¦6E¦§……L¦19÷Яû‹]Y.û+ÍõêÑÿ¡ƒ×“ŒVKÔÁwߟÃü}á¼9‚¯6ԙϤžb£}êŽH©*/­¯5Ñ_‡ Æ=í߇ >ä÷ï40€ï¾·“ïfCUnVÆêè•üçóìÕyoD’‰7LFòp‘$þéÇiR¯Q)"g…;\0Ž%Ø¿'ŽæéJY(ÏÉšÉn5,#%€ï¾·ÓçïÞ½z¾òòÈk×èKt¶wƒcGS§LãíàQ/_¹pŽ‹<›zš"i²ào™Ý;\0Žÿ|žÒÓ,þ¥î^£FŽH=yœ‹§”QË–P.Ê‹çó¾ãûóÀwø¾?ßð`à;ð¾ßðßðßðßð߀ïðøß€ï®~éx6øXø:•ïø{VÎßOà;ní;úw:³ïu5†ÕÑ+ô÷%(À~p²Þ\»iC€ÿ@ïÞ{vï,ÁþTXI W󤶬ë¤)äÖub?(½sÛÖI‹”Šj}Ùš˜•ö}\‚ +Iàjó÷À!ϬëÄŒ8„víß1ì/A…•¤pµþÝj]'¶ ?Þ¡ï‚KPa%)\Íw±þ̵íßIU³¡ª©ËÖií/A…•¤p5ß·l\Ïæïa!“i:ÏÅ¿¹Ý2רž™¿O7v{ìSu%ÍÊgNŸf *¬$€«ùN#꘨Üóy °‘v½É¸yÃzÿúöñÞ·› ÆÍ=‡OŠßo *¬$À-¬/|‡ïàûóð߀ïðø€ïø€ïø€ïø€ïø|‡ïÀwø|o>bÿ©‡ß©ÀIƒ\ðÿa›ë5|ÀI³\ç÷¬¾ßá;îë; ˆ­÷$/¶n%HNˆâ?¨g¯ñcGÛþº5ð½Ã}[ïI,^lÝ(J>]£VÑ`{ì–‰ãÆâ­ð½£Ö“²z0Èbë=‰Å‹­E ÊuZ.l6TõêÑo=€ï®Ö¿‹­÷$/¶n”ØâSÀw×ñ]l½'±x±u£à;®ï»ØzObñbëFÁw\ßw±õžÄâÅÖ‚ïÜÂú2Àwø¾?ßðøß€ïø€ïø€ïø€ïø€ïÀwø|‡ïÀw|Àw|Àw|Àw|Àwà;|¾ã*ßðßðßðßð߀ïðø€ïø€ïø€ïø€ïø€ïÀwø|Àw|Àw|Àw|Àw|¾Ãwà;|¾à;¾à;¾à;¾à;¾ßá;ðW ø€ïø€ïø€ïø€ïø|‡ïÀw|Àw|Àw|Àw|Àw|¾Ãwà;¾à;¾à;¾à;¾à;ð¾ßá;ðßðßðÐA¾S€Ç`Ç÷.ذaó¸MÐwNy€‡ÁÙmë;ÀSáûNa€gC²Óðž³àÙìÿ½Å'« endstream endobj 564 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 364 /Filter /FlateDecode >> stream xÚíѱ ÀÀì¿´v‚ý#w#$µSrΕÞK9¸$ÁoGŽ ëÞ« endstream endobj 569 0 obj << /Length 1516 /Filter /FlateDecode >> stream xÚÕXmoÛ6þî_Al_ä¡fø*‰ö¡/IÖ¢ëÚÕÃP¤E Û´-T–2½ÌÍ¿ßQ¤É‘§B>¬Bšâ=w¼{x$  "èròr>9»RXùÌGó5’>öG‚6 h¾BWÞþûe­ôtÆ$ñvQZEÉôëüíÙEHP’>7’"d8¤!àÖBTÁü ôÎlÃ¥™œÏ'ÿL(Ì!ˆÞéA.Ñr7¹úJÐ ¾½E ¢}=s‡$%˜qú ú4ù8!Îþ¡¶Ñ@C‰C¢O$V„ øÇì”V¿þȤû ýfðìÍŽô:½ïi˜5*f-÷ÝÊX€  êj]Ä›*w^åX=ŸÎ8%Þ«m”nâtcÇ_e»]–Úþ‡<»Ñyë¢våÐÚ!,~KóŒS"ÐLL¨´º¿0ÆßG; ­è Û-`M€ÀÚ„5bÖ lmÛrëâ´(£té~-s•ze¬ólg{Fõ«$*ŠÝ]ËÊaŒµ ’ayQ-–uàó>^mt‰m„~˦LzûfJì„Òz´6ÖzYºOˬÙ=ê<*ã&¦+}£ÓU£6=R›UåMUÚ~´¨¢Æö×ûÄ[JÄ¥Â$ ÚÜ—-îË÷CŽÝ'¶ÙO‡Ùï”ÌZZúsâ#»€AÛCJþ÷3¾—¨´†c6JŽeD’•^O1ª7¸ÐÛhʈ÷oœU9Ì ½¾ìËQœÀbŽr”ÙÒC9ªvC‡Ð‹)‰E`pþ=ÚÝ$w^°yµ›‘%&oÒê¥%P³ä·å¶ñÖËNóÓP>f cÇkååc¬¤ñži.ÛˆzXècÅCƒhÆ%õ1£0ŒU¨P®ÑºÒ;Pý£÷°ËÁkN¦föX|ç’.~³üS4´±À L7¶Ù`áBjÏ^™ñ‚ÂÌwÛ«á¶ùŸoíüY'ÙÀžÚ¢Þš y`—ÍÝMq €®à¨#Þï·¯ã(É6Ù&AÃÆP]_%¥ès;ØYr—Ÿ.ؾ4gè“ź?2Ô#MŒ´BBu9„iwŒ€5‘6¹ñ¤8__Çi\^_?.Î…NÖÇÏÌ,ŸÁæáèÀÒWÖ˜_†€$†¬Ñš团–*8ªƒ: !ü6î·ýªEI ×:Ÿ>'»ø#I9ÖØAVÊsá\ÊÝ¡MA8Ê„:PðçAúÔÄ[h¸ŸÆÑærÁç+Ê`x˜Ö½›ázsÁy”ÕÅI±ÆÒCøp‰°±§å¬.aúvéÕO$¡ò6¹GŠŸ¾Nëèÿú09à :¿xñ×»ùõë7/ÞýqyýiþùÝùcãY‰ þtqïâŒûXcãÎ!ŠÜÕä~èÖðØ:æØb Sü?Ž­SO-³&)Æ\ËÚû e ÊG½%Útê}?Ù]=àeT4%‡º2!Öæ/ýÁ Äá-µÛE³BßD‡Ç÷’¸(mÏ>°`ZU”¶®Á½…³‚[+tQ— ”7ߺá/„°¼AØÇIâäÜg8ìÐa-ê‡B[ÚáÊl*3b mf(®S4šqbÞ®òš|M©„t¾ÏãÒ%mF¾Ã>TW‹¬Ê—Ú–m³©åe®bT˜ª_;ƒôLdL"~¤~ý JQÐ endstream endobj 557 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 208 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 578 0 R /Length 11792 /Filter /FlateDecode >> stream xÚíwX׿ÿýëÞï?yž<÷~ïý%*vEDA;RÄ‚€]¬(ìb£ì.Ø¢ˆÅ.Òaa–Þa©*ŠIì^c,ÑÄ»ñ÷YÆqÚV`wö3ÏûÙçÌÙÓfæ¼æó9ggç´k§Ú:_B¡¬vÍ„çú…B Xòìcø? %`õö ! =ð>*ôg %`QyTgí©îï{ÖjVXo/‘&²š é!—Á€Bµ\m«îmˆz©¼ (¡Ê¡]»€F©ê62cÿe§l—³ïæ„#4¤ìïsÒvÙiZP¨’>]´­º·Aê¥ò>ôûª€ôRÔm€<™±Ïœc÷ßœñHsÛw£ÏÜý´ P-$}ºh[uoƒÔûïÛŠ¨Òš÷æŒ}æp:úX[A.ZP¨’>]´­º·AêýÌŸß^L•¶¼“­çýà|ô±¶‚\´ P-$}ºh[uoƒÔûùø½”*’“csž‘;1¾‡O2c_ïp×È'4ÑîÌ‹ÖqP¦Û~s;i¬]T­ˆ.JËËc Û½Yëe¥Œ§^*ïßî(£ X&m7ÏAö>ÉŒýù„&Z.ïð:ZÈEkˆšåÍ»·¿ŒÌ¹;jw93ekŠh3fqplÛ6Œ«y­_ˆ&Ù59iÔ`ÀSÄÚEՊ袴¼}óö=DÖß{eÂÙÐêìѺ¨†"º(³{Óú6k¢X¯ ¹dìþúøÙÔàø̽ê("e>!q>ûT^ă'L Î&3Rk![5?$m£¶“§¨ç¯Þ¿{ÿ!ô”ÜG’4?$u~HòbQâè@%ëQ×9)»úëÚƒR_Q¬OH<°3?8eF°Ì1°„zÒÈæñ4iQxù߯ÞüùâåÓož¿|·õˆtµøÜÌ`³fK@¿>{Évþ˜±\«J)J…#XÎuŠXO#Wá¬Ý€Œ„ðœ`©(Îÿ`RM橪 þ¢X»¨†"º(³{Óú6kyÕh߯Ý~pA^â'>W“¿4fÕPDevoZßfgíÞZ‰ÙæO$â"fm3)žççµæ½9〕1ÇŸRµôèEZ."D¦\Ìg†É ½J³DœZ.Ž_.N˜¢˜\N~ë\àT éïý®r˜#â&ç{ª'ìûñ)—à&ç?ôXÒ”à\‡ êÙGTfîñ³ ’SÎÁ%„ <»Z|~©8´Nrvcèi¸30kùÔý‚ i턞¢ å¢Ðô§ÓÒŠT'äÙ_¯ƒËX–^+9 ¥"k!å-’n?ŸœSyóþïÄø=¯áó¤‘yš4?êÜH}òüá“?Þ½{x<Ó-¸Ð!¨†Y«ˆ’C'ÃkTp O49\b¦ÌmxÈl¸ÿ<:«aýaÙ*I ÝrqœÚÒ˜]”§{S“]”™—Ú¹âY»·Vâj3ÉO›YŸŸ|‰**ïíhjgÛ®Ý|•HÞÉŒWÇyJí4B i ­ ¦ zbX ò§ÍË=BrC*(ߺ…é#óƒ˜âê«sö—$T©&-“rªÖKÎL iâ½áƽŇJ¦¼ZòËsØÉ('¾=˜õ+ìÖ5Ü\óƒ|ù~ùÞ¸Šú[«I!ÅÌZþx©²Ñ¢¨2†š†§¨ÂŸþ\}²~®DxZ5yüôù q ¢™î)Ê!DÖBÊ1D9]”·@œæ+NØ)M+¼tÿñŸ3E ®æq5É#¬ìΓ×Ξ㙢hx;p{ôØ[ÎZ«ö+îC²ŸoÝ÷ /™´¯þBÅcMNW —˜)o>zSpý»£Y¾¸ÿÇ/%.§Î+¦†Œ ©æ/ÙEyx§vT¢‹ê“W±ÖKÀÎŒäª÷3ÞC.Sõ¹}oG“ ö<•>ñÞœÑnMâŒègL-‹¼Dí[ÈEk¨ùBŸt•hòíhq}BáOŸþùæÝû»¿¿>™ûËúÐsË$ ®¢&3V^|ïÑÐÃáÛã™WÀÌùˆ“\De÷ˆ´öÞƒÇ/ß¼ûûÍûòÏ·^h˜-V°Ö–yÿ¯¿_ñ¬-á*jSÜí+wŸ‚=}ñú}ýgN§¯=ëRÊ<4M4*ä¢sH…§8w¡X Ý~MhŒ“HÉÚ<®&e\~i¢Òk׆ž÷–¤MSyÎåWn ©e-„Uá©5w}üêͻǽ •߃‘&§HíÅ¥¦¡näWË%‰Ë$I‹Ä)sÅîâ‚ !•£B.ixê˜]”Ö9Y;*ÑEõÉ«¸êå¤ÕKåÝAt…*my'3Ú¯MžýL[A.Z­ =¿9ô”›¸TÃoÅJqòšÐ ¾ýa©8ÉKœ;AÔ< =µDœâšâ#Iõ M\šì)Î/ª…ŒN¢ÊÅ©Ÿ2&,‘¤z‹å³D g‘’µøvcè¨ÅG’Ìl OQ3%yK¡’äe¡©+%q€ª«¨œõÐ4×Ñ%Wq¦«¨‚«y\Mš)Î…$›*.ž ®] I?¡$}”¨žY«œÄU‹ÄPrÌ Iü"‰t–8ÇQT­öirq -•¤€ˆ”«Cc!LÄOyˆ à¸F‹.k{Æô领íÞ­ÓfRŸñ.¾ú™>{ž–ÓŸ''3ÞæùÛ¬h.ȃ6¤ÓÐ(OIþ‰ÌM\¦á·£ÄWUÝX’;_’9O’éZ8^Tñ$ïž’BOqÞgÖÌ­þ›Y¿üW._w`—ˆ‡“¸Ç~@ð† ùæÂ¹3û$âÁvv];[Œ3 ¼­’ñÔ" hkC¤OOI*ïÎÆïز™Ÿ?y¬cû¯Ïø‘ØÝ濾m ^ÞÄžªmêá­zõ\½ÜçDd8ÜQJB\&˜9ï@YN†Œõ«Më×Nrv*ÈÉ9OtܼaIâ´ÉnÙrYuEÙ÷ßmîÙ½Ûô©S b×Éq¼VÉxjñtŸš£È€ôßmÚ8aìƒð~.:Üð{tíââ8ž kÔðaÛ¿ÛH¦îaÕ»Wì©ãÐIæÌð‚>‚i…i%»ü&§gîÚ¶uâø±D80à{Ⱦ'`+±;~´|K­1)æÌ,Owh?4iå²%d<´m¦Ç4f|Jì¹e‹ÚX÷éÙ­«Ç”ÉqgOêÓTÖ³ ÷(ËÝcN§Æ€Ó1¬µ…lð[ecmÕÅ¢ãðaC"ìem•8pçAvRn^ç§mS§¸º,_²õ+®+Ëuz¹Ääx?§¶RÉú•ÝÀ2i ójo7€$±(/‡×(Ëa·8/—ÜíÖ¹“VÉxjaM¯'ïƒí†îJ8w pžíéá9m D†ìÚaßß®)‘Æsꔕ>‹!°dÁ¼±£NFE€F;ŒXº`>ï:Íä˜3p{9{\å´/œ;_0g„OýaeÙ ¾¥–ì³p>4 ¾"šDÆ/ñž;aìèÓÇ"@P¿Ú×g¬ÃÈ㇀¾©n.ógÍh û·âŒZá³hîLOþÚaØ}ô0€ã³È{ä·CY ‡Ó²sëw#Üá¢hÛT`öø‘C¬_q]Y®ÓËu B²ïàH“·À.I"5×®†Ét«Å þü…ÓÑ}­,‰ð°!ƒ·ùo œ@ˆŒo¼Ûö³>úÃ>"Ø Û~}[‚w˜˜5+–žÆ~I0ÑÿW,]ñ´’¡ Ô&Qâ­a¬J„!o×ß&êpSü™ã‘`([büU÷ëc•Ôxk‚O°ƒ@(ígŽ%Âpª»t²`mU_«ÞëVùžŒ:¢[SÁ–%P&F¨âº²\§—ë@Lqü¾m‹¿¶öÝ€¼ëV‹Î¼ q^ÑW-:´'âwoß2ÐÖ&ùÂÙ)®ÎÐLjHð$ÉØm!Þïb?Hd7vÁÙ£íxZÉ´&QãYã;YPÙìØþ뿃w±}Ë&Uöï6‚#­Uí\'ðÐ^ ¸½zt`Ó/xçvÚw®+Ëyz9Ä$çç­­vl‡ás]•216†œŸß¸n 9²vqší–à]·Ztænà[6®ƒ&  ŸÔ°Ž4Ø&ÂNñXèñÍ#8°Sd!¬Ý@Ùdà}ÓÚÕ„×:}ŠÛêå>ߨÛ1…j€Žܧ־ÃMÜffu:7•‹÷Ý;F ÞÊ_;שּׂ‚K´c mt¿ƒ¤³}§ž^®1ÅßßåÒTO÷i½ztïlÑq´ÃHò÷wð®}}–3ç ½nÃò®[-:óÝf×¶­` áÎïê4šÌìn^ÿi^hñü¹ä(¼#ñàoèÆž0 s?Ž,¤wÏGí×wðçÁ}¿I5¦Ø²a]·. Ÿv,0ð„á9 0AÐ62šúiü>æSüÚ•Ë ´ nbб';;éÙTÇÀ~`ÿu«}¡:2†«v.Þi­šìâ ôA^ཥ¥.óó–½ü|—ÁåSÍχŠÈùy®+Ëuz¹Ÿ¯3ªßß™#Í Ûá^mѱŒ7Áo§v¼[ýÁo$;áÑÍöò fq!@zzpÅÁŠóÆüVRguztë¢Ã¤7èlt´ º„Á”@˜ú³;mÆ#½{õ N CۼܧñË-€ì¤q„Äá'ÜÌÁa‹žMåùý}ó:?0Ð`試™µv.Þi­‚¡\,8ÏCÙ…îÒᬡ.Žã¡LË2˜üýëÊr^®AÞM÷ù:§ñc·ùoÀ“ÞG„ÙöµÆçëðùyäUp÷†±3Ü·ÉŸäL±gÎéyæØÑè£ácFΛ兼#ïÈ;—jcÝçP˜Ø¤{&Œ1ûZY‚#êå>%žíäyGÞñO¦ØTäyGˆ°©È;òŽaS‘wä!BÞ‘wä!BÞ‘wê#n¸™Ù7³å…27!ï(”™ˆÆ"ï(ò޼£PÈ;ŠzQ(#ònØ&n¸íF¥y7ïø+nƹ?:#ïÈ;nÈ;òŽ¼ã†¼£L—÷¯þ÷ߨí‘wäyÇ yçç½Ã×_¹¹ºÔ×Õ¨}¬yò®\:çåϨ¶XH@é@Þ™¼Ï™9#h÷Nä]0¼£€¼óð®,-2Èž\¤•Ê{¦,ÍËCµ|¯îÝ<ݧ•hµÞëåÚê-›7Ùõ·µìÙcáüyÕe¦Å;i(Iv>|ø°ooØ »–½z¬ñ[õ÷ßCä¦Ο;G^‘sgÏB 3/ëöîÝ;QH°Ý€þ½zv?~˜µR82 ¿Í×ÿïwä]OÞáóüé“£F\ª®¤ñ>|ØÐs§NÔTVÀ=Á×géâÞZ­÷º+`›«ÓÄìLyEIѼٳV¯ð5uûq$ÜÃ}Ú;wþxöl…ïò€íÛ òíÛ7S&OJIN†prr„ß¾}«!qû÷í6eò­[· Àmßoe­v½çÍ}ðàÑÙw8Q4ñ'6HuÔµ ´°ÁTÏ6ï µ«W®_ãÇãÏ+ËJlûõÕj½×!ƒí3Ò›l}q~î@[Sç}ø·C¯ÿò ~ôè‘ýÀdx°ýÀÀ=»áš7ô›A WùQ…Ý{÷î£?¯yg6H·g¿mÓtx¿X]9zäpðÌ©‘Éq±.NÁ'VéÔ¡½VëCøÔÅG,š³›.ï]:u¤úÛí¿ú_ò+±(bŸ\sâ:[txýúµZÞÿùç“ái…™€&1ÈåcèÃßxæ«=Rž[“†Þ‘¡yɤ)`n*ËJÈH{»ûÃBË‹ /ÕVç¶ëÁ dŸ£È0éù:bÈLnßr÷î]æU¨¯¯‡ñµ,=­¿m¿›7o²æe݆ Ì´ï´ŒLüM€wVjxŒ2W‡gõÕ5/–§ ž4<µððÎsФIš!o@ÞA»vxÏ›CFöµ¶Š<^W¥„±¹—‡»¶¼ïÙ0ÉÙI.Mç!-9q¶——ÉñnmeùóÏ?‘»‘‘G=§»C ŒÙ¯^½ê³d1Dþý÷ߣF”•–B833cÜØÑ¯^½bæe¿ïßã÷Û·oSÇï´ŒÆÎ;ÍBé`Ý4á]sˆôç]“¶ñk"¼××Õ¸¹º‘ÑQ‘`£;Yt`Û/h÷Nmy¿\[ ¹`ߥ“ÅðaC£"ÂMŽ÷ˆ#á½zv§ÎÏÿ£øNÛãr¹ "W­\qæô)2Ëш#küV1ó²noß¾ ܾe¯‘µRmy§Ž8Z–z~ÔΰqÝ% Å;ºÝ¬4™<ÔÖ¾kãÒãóuøü|›múð®á¼–þö]í [«Æëì±kåÕ ïÈ» y7Îñ»VmÓ°Rþi-Õ:¼Ó|lý=mƒزãwµ“Ò<½]['Yó*øÓhè0ðŒ´Ý }GûŽnÈ;òŽò޼ˆw<ÂÖUe…I/¢„¼w4"ßnÝúøå—££MÚÊ#ï(”&ziÓ˜{¼p¾…°ú­&`ÿç?ÿãzròŽB U7bcs‚÷7àú2(”€çè^wíBÀþÂÞדB¡,­°¿ÿ⋟åéÈ; %TÝ>E>Æv×Ný|Œ¼ësQST˜øùýû-›~¸^$ŠvqÒÝlÙ´k÷®‰Âçi¼ÉåŸþ’”„ÏÓ¢wÁn|üê«&ؽ½ñùyò.ämÆŒ&Ø»tùØø’1äKæ¹ÊŒ0xÇÅ&T[tô'O>/ÿ‡¼#ïBöä¿ü² vü?,©Œ4©çtÕ¢Q-:Žrqèä]gÊô|ç 3ý/?ÿ¼p7\‹í'Œ“¦¦jB4òþqÔ¨&Ø{÷†'oÞò´¾}¬vnß–—¥¨«R&\8ïåᎼ·•y¥e¼qãF?k«#á‡ÿïÿî½y󦺺jÑBoä]ýväHìÿú×ÇÚZ!™ž¼Ï™5s«ÿf~žkÕÈ3'£†Ûµ³Å@[›PQ0O¤‰ò>d°ýµk DøBÌy"1ϺF$+nú,1é»Ìgÿ¾½üŽ£Ãš’ÂÜT˜¼ìàôäŒ{N†ŒŸw®U#ûY÷9zøxà,öžÏi¢¼ûoÞt"ú8~½¿G·.ýõ—jèø±ïü7s­Éä]Ÿ%&Á¸ß¾}[ ®Ûš’Â܆ i‚‚Ûôä½Sǵ•JÍç먫Fö·Q-B‘Ÿ­ &`4QÞ32äÄ 2?<`meyæÌi/]²(33ã#Ç‘LÜôYb²cû¯˜«Ëqñ®Ãš’ÜÀ “ž|Cò®ƒ}çZ529!ÎÓ}ª•eÏÁvv'~Œâ‰4QÞ_¼xa7 ?F;ŒÈR(&¹8AbŸü#Û‘LÜôYbR+û®Ãš’BÛ`¨NzòGŽòõ¿oÛâÏÏ;ת‘Wš— :u´¯µ•ÚHSœ¯›6e2xÝNŽ Ÿr¹Ì}êâ+Ö5"™¸é³Ä$ŒßìßÇzÝ ²¦¤ ¶W¯TSñì£F õ( 0?omµ;`{AN ºcc˜óó\«FΙá%“¦\¬®´m¬­y"M—wðäÇ£¢  „úáàGî5"™¸é³Ää7lúö9qä×û÷ß¼ySSSMÎÏdMIAmþþM°ùåÇæy äÙÃåÒTO÷i½ztïlÑq´ÃHæïï\«F:¸â»v¶pþí¹S'x"M—÷úË—aýäÉ?~üÂ`—?r¯É:?¯Ï“õïùiÑ¡ýÄ ãÉßßõ\SRh[^Þ§GéLùų­À; ŸŸ7ííÙ3Õãñì3fûX‘wäÝÜ7oï&Ø¿úJÀž<ò޼ã¦úK;éÉËå‚?\äy7ßMpoGÞ‘wÜ>ÑM{„fÊý½yoÞñ<¡lÜðÏþÇC¿ÕÄîý];IOþö±(ó9È»ayGCj¤ùW”• òïíš[yä%ìÕaÈ¥ ¨zeiiÒ‹;ãûçQ(¦îîÛË„ÝÜÉÊy·· “6¶ÒS’w£â]YR^tã˜:;=1¶¬PÅ~®<½²´°ñ&P ¾waN&|B˜ËŸ§úêÒøžª/VU@-õµ5£€“þ?YT~³ŠÜÌô¼L™ZÿÕ¶¼wílA. ä]CÞÊÉnÞÁ Ë’ãïPW& =­ ¸WÀ.|"˜¦bße©ÉLÞa$e>/ÒŠ÷×]»´ÄŸ1ióuŠ´pÚ3¥*Òá,~VZÓõªU–§'Å+K Uq•Jµ¼«Æï™éœ3uŸt„IsO-­¶²Bžš÷"ZÌQÆÆû¦õkÝ\œUã÷ÜlÈ3yØ_YZ>ô[mS(Zùó¿Ï™M¼Híî¾½-Ç;xò€3ŒÙ‰‘;^œ—M̺ƒÑ¯*WÍ„ƒ{áËãw°È5ʲÂl5óó´{óp>•˜'¤± -ïy79Þ¡ø,^hÙ³‡µUo®ùù7@Ç~ÿÅÐÃ[Î59ÞáT¯Rê õF5ïµÊ2àˆøéüRM%„Á¬C,uyãp¾ Àüœ<…Œû÷÷Ä"Õïï•<õ‚—^YZL‹$î$¬,g¥K‘wA>?&þÝ¿ÿ›ú¡ëÉIÈ;iâI½°·×Ÿz|¾Õæÿ—a¾&ôù˜ÑÂ{"BÛçç©&žzfnÄÆ ï(“þ¸¬Ìÿ#ƒE3ìèÕäD3ñTê–§'ï´IxBòÎoâIµÐLµI æª¶Ô£}Gï ¿¾ÆÓ·aŒÿ`ã3|L9ÿ;TµšçDÞQF»Ú÷Óø¿~¿Õ¬.„&§¨×p’yG ïjmñvÝÆ­6ñ ÍÇ;¸r%nƳ^$Ø2ÖõûH—Þ aç7ñpºÌyå#TË=tÝ:ï¯ãš‘O^Ÿß¡„jâñ¥ (“æõGgm½Vó1ñf~D™:ï<&ÞÌÍÙK›~TÌÉ7¬"ò(“æú„-Øú{¢êÓ8–ù˜çU Q !ò(ðNþ‰°_iüÛ,Õº`žî{T´©È›íd&J¼&ž:`‡ê9Ï&»™á…¸~˜fÇo‹"§;4ù±—‰Dçz‘ÌgÆyê4õŸÍç]ü7Í‘Çõ"q3­õ"©+ÅGäµBŸ¯CÏóuê©ÇtêèðõÂ4äa˜ÏuNw”Éñ~…²$÷6+Ý…¨='È;Êy=ô[MíÞÆ?;Ý ëER—5gEyGµ&ï†}%5µ{ÿ_iZçýóüÈ#ï(ƒó®,-^ç·z°]·Î,{öð˜6õÌÉèj'toêT•1?vÒjëMP‘§MiÒx¿XU‘-“¦%Ä‚ @}Á{QŽBŸK¾%žG•¥ÅYé©Ò„Yb\¾BF®YYZ”•–,WÅçeÊÈu+PBâÝÍÕeñBo…<íbueIa~øœÇ·ÎT•1?iÖšëË,Ñg¼>¹(Wq¹¶ €KN€Ê s3S“ꪔ ”QÞU˪lY* ¹¶úRMe¾"#§ùÕÓYi)Ê’ÂÆò«‹s³áž€d w0ëJÆË‡iþ<ë zÅ–Í›ìúÛ‚W°pþ¼êŠ2Í‘§>\j¨·7›.ï´)Myï`y/7¯&rA(Ÿ|}4ÒdÍëU•“p=>ú ïSÜ\gyyÆž?[SY¡vü#½©Kçç´µÑöO£´?Ú˜9ï4äŸMv£ß«+eIñÄ+d!p±y| †˜\§Uµ¤Æ/˜­Q–É“ãë>¿Ïå§'~Z— %Èùyè*²Ôdïys¦5?îNíÏ2iÊ`;»Ü¬Lê@€êä[th¯m³–§¿mßÞ8ÿ2ßVëÃRÿ_|í›ATÞ³ÓS`ØNŽßaWû^]^"KŽ«©(euæÁ`Ú}”ð~ãÞ³{7ï%yCÙƒÏOM 19Š =[È¿îÚÅÿ2߆ëASBަðžf¸ñ{Eq, `/Óv\2uÞLJÿpòKÕ•0_ºh!Œèi¼3j¨„–qÏ΀IÎNri*8–iɉ³½¼tküµâB#üË|Û®ÿNEž¼6ÎÏg}šŸ—’óóy\óó¬‹G”æç€e¯cL×äe¦×)+ÀÍ»X¥,ÈÎÀñ» y?{2ÚÓ}šeÏ0~·Ð¹Ï’òæ§>ÔÎÏíÞ £ø.,†®sûi™7Ǿmy'‘—·kGþÏÝI«Vµ(ïz”X³hUWJ®“ßÒ­2 SÇZކg[ÿkÐyÓã]ÛH ÓðCJ»²\)ÛœwÃy Ë{›´ª…ƒš·yg½1êÉ;úó®¹ùæoUëó®ó…ëиŽE“ªÕ–fØVéà ò 5¿ùkeÌʾ«JkkÊu+Í N…ö´•x×m„¢•»Âu&µ‚¶Uš¢ÃØPç®ÂZ5òÞ¢ãw&­À{Žßõ¡èÏ»¶Þ€­ÒsØr¼£}ç¹^úÌÏó_ /"ëÌŒZÞ[~^‡#Ò¶¯ò;Ï:à v2GŸVµï\]Ålè¹S'j*+à&àë³tño"~«ÿf'Ç ÙrYEIÑ*ßeÔrŽGFX÷¶$×–‚ÛÂ7Wp@n.ÎT`=¦M…H2Ù$g'G€œ':nÞ°N-ïžîSsÕeßmÚ8aì"ÞãzU9¹ÙD9‚´ï%Ù+»•äæ)dԯо#ïšß Yöì!KeYtLYV昲HšTj9Á»wÙX['Å}ZWÔnà€Œ´¦eeÒ*°Ô¥¥!|K„¡d{»jy‡[®Q–“ d¤–#HÞóò’|Õ±çÈÓ*š=.äy×ÁŸ/)Ì߸n‹ÓDb79.Âp nšWx/º–²X!Y`»~5R’Î9d¡K¢ØUË;k<­ñÎ僟¼#ïºß¡óPÍåþ°ÐòâÂKµÕðI¦lgÇjßÁ‹ÓgMì;5/—}~Á|a0èjy§ÚwðR„gß/ÕT¥%Æ6z5eò”xZzäy׊÷²¢BJ3ŠØíkmy$ tN†ÌËÃLùýwªñ;D2Çï0$2È~Û"¼…OãwW.`!9~Ú@ÄÃÀ†ç0HÏΔOŸ:E-ïÑÍÅY5~Ï͆…Ç»²¤(+]uÿ,+ÈËËLGÞM‹wƒœ|Žß{÷ê XeË›f¢£"ÞNØö Ú½“ìÞ—ª+7¬]Ãypõwl§A†xè7ƒ¶lÞD8ÕK-€dÖV½!Šb’ùú,%æç!@úä`ëáæV~ ­MHർ?Õ o~þJã:ïE¹Y£xYYaònr¼“Y¸Â‚y~>-9Ñ~@S¹¾Æüû;Êtýyj®°Ió?XüܬLW§‰«V,7!ÞMîùyŽßÛœ÷=;Àó{ñBorò …¼#ï‚ä…¼#ïÈ; yGÞ‘wò޼#ïæÉ;¾úɘ_B…¼£Pfnô‘w yGÞQ(Sçpk}!ï(Të«]ÛmÈ; e¶?â ï(ò޼£PÂæýÿ㜠endstream endobj 578 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 208 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 167 /Filter /FlateDecode >> stream xÚíÐ1À õ/­<> stream xÚí‰_Lûÿý¿ßïûu•®¥HiQ\e )Q©©d)Y“%×R³F%´ EDZ'3-*mhÒ"K|/.¹¸–P÷^”êþÞãäã8³˜´OïÏãù˜Çç¼?ÛûœæýšÏçsf:ƒI“–ÕAnbЗy·øAn‚JjfúA¤›ÍâP“PKÁÿAº ºÚL ®îöWù$è.Í⪂®‹êC«.sAú2 Þ ®®—®6f»KéX ´û3ÒÌ÷’……ihäoè7ýàÃYG_ªÔ4òŠ3ô>ÅpAÔ’ÎHoW—ŒKW›I; é€Îüûiæ{ ‡4ã6#ôáœÈ—ª3óàƒ1KC ˆZÒ™é­àê’q¿Q›Àb:V›/ Ç, ³ŽzÕQ ÃQK: ½\]2î7+©]%t:ª6¤¡žÛ¡¹Q¯: ´b8€ jIg¤·‚«KÆývßæ  ²'£ddžÚ×WÒPßãˆmôk u’­­ô#¨“êî©èj?£~Üù.T€0Ú*™tmpÉWnŒ+—®6“½J”„Ì[”œ5÷WÒp¬gÔ¼è× ­<ŽT3*@+†½IÓ§ÖG¯ÞGçÕYî»&[³'¡ü‘µ¬`Ÿï]Ç”;L¹§¢«ÝzFô?kß¼bÝŠÜù.T€0Ú* LzˆÉ ®ÎøLF‘µ(÷µÙSF§Ãjó¥áØ1v1¯ T5È,;ZM F´b8|yÏ'~áÂk·ëà0£ì±¹LÍž„xE7näÆoå°Ù—×ÃÎ, «ŽÌ{òàÅûï:LÜSÅUF“.®žìe„³€s3šÜ«ßî† *BˆlpÑÊ_ðª<¸:é3Qzž]ѸߨÍ^ Õ†ZgÁ+ih°òÄ‚˜zUÍóhµr#´b8÷¼[p*°>ì"6þýÞ%8ÓüKéñ£ Mmð)¹W2eŸõþC3L„>„f= ½«}iù¾¹¥ J9ÂßÉ@Ð7ó÷û/¤ ¿þ"zdþ­dF¢×möç+éjÕñ;ÕÿúØòñSkÙƒw›îÉž²ŠÌ ©:(~|óÉ_0îÇæÖÒÚKÙ餀‹§ ' §üU:öçÓ]…šaÙá°µíßú¿šÓ+^Zq*Wª)¹ª[(g¬ïúï”E‚2æßyÓÔÜÆ[OaD8Ǿ>}F€¨ ²Áň,¹v¹ÁÕyŸ±#2œaŒKWó}×騨6T)¼’††^qöÇê Tµå‘ÕÊЊáðå kT‡óTQj³{Új)UZZóˆ%(öयä&‡ežüHž¬>(¾tý>ä£s~›Bëªæþó¥aWÖ…gݸÿ ïR DÒ Ë¿ù§×±°ô.ä‹î™ï-' 飯ÖqϬä$“:T^IWOß|” ×…òÕ‚ nBQåý—s‚ŠeÏZ9A¿K4´¶µAì—ÜyžZ±6$Ň›èÍ=o½¿*p2Á(’ß^oˆÈñ‹Ußÿ“~é®Ç.?]Uæ#H;)’žEÖõº©û$Œ+¯äª‚3pxý~=Œµ9BtóáKFÿJ`üq)ÖH‹M+ª¸[÷±¹ÎQòà ÑÑKÔÇaˆŠP"\ŒÈ’k—\]â3ÑNÖƸߨÍþ :V›/ VŸr8^OhŸ0GV+7B+†@û’k|Ù.´&ç–´aáõZ?^ÜÜ ÂöéÊ‘ÄUœ ¬`‘'ãÉëÀ²ãH¼Û7DdCþE}ÃBvéŠ<Å‹{ž,ö΃Ãg¯ÞÚ³ó >²¥g-òâ$y”Πž¿~çÀ¾DÒG!^¹sÒðî§’®?´|jiÄ‹½ø©îœ wNÚ nÊ´ ‰Ü³¦’¢krõÎ3ßp¡÷¼ç ;;}[4;¨*<|)u`OŒx5÷¼;;mkTÝ=zžêp[ìÆzr¥çõ¦áï%ì̯R@Ñ늮ꃗï¥cù|Ë?&_¶EÈ­ yW¶Ð‹›äžZYû¸}ã1¸PyWý F€¨ ²Áň,¹v¹ÁÕyŸR ÈgÂ7¿\ª¢ÓQµ! }Î,<þ†ÐþayC¹Z1»Äu¯?œ+úmKÈ™5¼D›àbʾrÉç@›T+©Epz Wl˽ùææOëxgg·oD8‘57¸d6·’*]ËKœ\ Æyµ´¶®å&Î*“…XæÑý¤,Jºâ‹êšš?}^¹´Ý{ö÷æ„Z{NÁœà+JÎz%7…QÊ>®}ô'ô]Iî> M­rÏ’L ª¤*ÀœGêLHýL‰{ô¼Wì½ò‡ ï›Û¾¸ÜÖÖ¶—0+è*½š’«JåàŒÜ±dÿ ²§É¨iÅ»±+ù÷Ëw^ø<·¹ûèù9qéÞø)ï­Á¡D6¸‘%×.7¸:éó×·hä ’—ë3AÉï¤:¬6_¯Mt:ñ†Îª¨ŒV” u •ì¯3Èr/q%/XÍ»°š—ìÂəžFJíØ…ÁUPÿI½t©™4Ÿ}Ù)âõ)¼™oÃn_v ާ.`ç[W,‰ª•Î:^½ÝÌŸË.}ö¶IÚðèùõ¼³«x)À&~ÂÁ)ˆ ÙQ¾† »ˆá'X”t5— .†ÊÌ,–^·}œÍ¾*÷g)¾ü肌Bðà w¾–Wþði=µoSPû–”>ü<¹â{¦Ä=zþù;©«‚ ×Wò…k¶ÏÙ¶ðOÚ°KèÕ”\UjÅ;– ² c-¾+{q![3¿ö-%_µOcský‹Öñá2®æ%}··~#@”½ ²méA¤È.7¸ºÄgÅJ|–û;©©ì:tµÙ½{ƒA†ƒ¹K!jCŽ[Ÿä|â Æe Ã ý )8¹Œ'ƒÃêÚ‡‰W‡Š$•Ýúý%õ‘nêþVçy¨ÄñPmÙÃFÙË¥Ùš ]‰…÷·Gåúðá3åÂ*nÊ2^†+/ÇžS8“S¡¼·~#@”¨ =L¨éLÛ.÷™’Y£¢q¿QÎM:ßÎm1JM”¯jó¥¡ÉÆ”E±oeñŽ®¡Ã(…V €¯ïn©*¥Óx·’‹î½zÓÐô©¥®þc\þo~‚3Þüd[nûÒ༸äÉËwð ¥'²oìË—jý m «ž<õ¾éÓ?M-×4œ«]ÂË‘;JHöÓ¿þùHÙåz¢¨«­In×½%áß[n=~vꢟ Á–sEöÔTÁ’sc.§Ì™—ïÉBxn$Zs%TÑÉœ[/ëß55·ãÌ¿¼Œ/²ã]U±Ô’wâÚ…ŸïÎÏvãg; Ь¸•`'jãÌ/ræ¸ñ² t!¿ÈŠWEÚÎæU:ñ Ýø9î|ñþ¥ü«3y5rG™Ã«X,È÷à‹‰QGQW³xÕð‘ v~Lx þ þ-¹§ÖIÀC˜ö¸ó³–ò²ù%‹ù—äºjÅ»áÄ/‚jnü,¸Kò«)ºª@á½Æuqµ®!…ÛŽß©“î#]Ù,H˜Ï¿¦Ä=ªs:ŠþÄêGg¤kƒ«g|&|£6ü»]¤]ÅSw—8Çüé÷NX1ϧî.ž´«¤«K»Ú„ÄÛñ˺u F`úÓ‡6~jmû§©µºîï°´*¿³^‚ ùßÅ+Ö¹é­àê’q¿ýO¡÷º A­Ù¯W&øgOØ–¥þ9f¿–Zòk»ÊEl Iô‰Ÿ/t÷@ Xz‡dxz „°8]%J'?‚›^!BYðru&@z+¸ºdÜoÔ&ä7õ†Râ’=?¤\íÏ´‡™rË9¤ÔMã!ÈväÙ‡”Y…Ü!œ^ÿ ]m¦¸ü⟃ Ò…PÚÂP°ß¾Qõ¯ú&8;AzJpdÕF½CrРAø§GT›î&2ü¨Í“GûàpŸrAPm:ª6Igû}ÊUœ"¨6êª6»¶ùõW)g0dTTTÕÕÕAPmPmPmTTTÕÕÕAPmzQm† þo¿S›ùŒjƒô–Úde :ŽÖÑÖÒÔ°´˜qh€¨¢EµAîP›q¦þÝ=» rsª¯K’Ïe99ªÚŒÖ™rö9´™=“ä“Ïž­=2!6¦Ëç6J~Wm¢#ÂlæÌÒ1|¨ÆI¿Œÿ5ÀÕQ3µq]ìà¿MnˆÏÚÕÞ Edà²Ã›´ßÔØæBf9wæôA>o‚‰É0-Í™Ó-a¦Ô¡jJFá34 ê_LOíÚÌeõëŽmTþlÜqŸŸ9yŒ: ôߥݱ’úaµ9v$\WG{ýj¯“ÑG@$Ãù[ëY¨6ˆš© Äx^–HnÑV?ßys­ ór¹sfoÛ¼‰è€Ã|»KbQEÙÕÛ·i¾Ð~tBZ϶êP5%£8;ÚçådAýí[·Ìš1½Cj³70`ŽÕ *´{'ô¶wuh5ÍJéššxz±³#Ì+ ä×z¯$v|'Y{úù3Þ+< ôÆhæ´`~RBÕ¡£j³ÀÖfõJO¹Eàƒë"8@†LØù,×7T¤/¨ ÌÛ«Ê%r‹LÆ‹„éT¦¦&ÆDŠ ò¨|¥ä–ä“ÃáZC;TMÉ(r뫨6i‰§uGë$œ.—<—º‚Â,s] ùøc‘º£t ”®6^žî3,- (.&ršÅb_é±tÖŒi§ŽGб¯÷ñša1õDdDbü {;÷Å‹:9·Å8q4BnÑÊenà8Fù¶j™»rŸù†jƒôå¹ ,aˆA‰Ы):T±Ú¢Ê.1Ì6®Y Ks³P>{êäI_³j9Øâ`8V?êÐA*v€f׋Ž£òPØMŒ b·ÛOŸˆ6ÐÓí¤Ú€æ'Óv™è€tßÀUå>+ò Õé û6;ü;:·éBµù±QTQ›Ã¡!MÇÁŠc¼‰1šÂ2dœ¡Øâ𳦠vÈÐí)ríC5éë&Ÿwß܆á~Çg¾¡Ú }âž”žî¾Ý» ór«¯KRÎ'’{R[6m$;*6Ös¶úùv‡ÚüØ(*ÞµÙê»ÞÙ~ä.°[¿ÚëSÙUú|hhhرÝßÏw#£—Æ 9ÕË¡ìvðbÖóωåì„jƒI Ôð]¿Öoã%+)ÉÕRñú¤BqA•¯”\ƒÃ’‚|r8\k(•Ÿ8Á4ëbû<§ärþ8CµT8Í{÷îRùÚÚ;Êw‰ ~oBï:$ößþ÷?*Pm0©‡Úܨ(Ÿ6ÕÖDtcZÒyë9°¢[?tÈOråHÑ!Èý©÷š_š«™Úhiùøñ#•‡Œ¬ÚTWU-t°¥3’ÚÂ2ø?Œ ŒàØÉªŠÞ3ª ¦~­6€H˜>é—ñåWK‰ÑÔÄ84Dp­¤¨¦ª^;ú\ï‰ãMór²Ô~—˜>·¹{·VVm Âùs‰oß¾iiiWÙ 8·Á4ÐÔÚû«‡›+1êëéF=R}]’—%b99vTmöïÙ=o®µX˜§Ì´”%,–Zª —Ãf9;=ö p^è(+&úcÄ¢‹0KyôèÑrOÙ ìà ²o³ ;˜ØÉ¾Í"îÛ`R+µ¹U]igkCŒ±1Ñ0?ª©al86xßžŽªÍͪ hŸÔ?Õ47›yD-Õ†ºs %ý1£åÞ“º”›;Ùl¢æÁ&ÆFÇbbd+À*)`‡?uO 2ôUÕf¿MTÏBÐÃwu†F¦>¥6HùÔíÛ·'˜ŽÃ7<&TT›nJ;^¼xñäI“£Ã®Àø†Ç„jƒjÓM)::ÊØÈVR~›|ß¿/»\ÂE&TTL˜PmTL˜Pmú‘Úàu@ ¨6=¯6ø1‡i ÏpPmÁçI!‚jƒ ‚jƒ ª ‚ ª ‚ ¨6êt‘dÀ‚jÓó’Ž ÓLø}üå&LøËTL˜PmTL˜úˆÚà3û²Úàÿ´Á„jƒjÓ3b‚jƒ©?ªMV¦Ðy¡ôñ»Zš–S"#¡ÚtHm ð§šOnkk#ÈO™l¦\¨ÿ¹7ø?ÿW{İÓ-÷ïÛûúõkœÛ`RcµÉgêÑݳ+° 7§úº$ùÜY–“#ªMGÕfö¬™ÙÙYÄ"]ËwÕ†ÊüóÏ?7kjvl72Я««CµÁ¤®jãºØ%À›ò•T¶($&?:#†;;:\).¤ì§ãb-Ì'ÓÒgh ಕÕ^m2ÒÓçÙÎ%ë9ÂŒ JæÛÙ¦¦¦¢?þxb8V¯¡¡AV.¸öŸÕ 1ypÿþrO¸ø0Zæá^__ϨÐÔÔ°ƒz: dȳ5©çÎ@C°G GuÂÔëj›¼,‘rµ17›t&þdey™äJ‰×ªË<(ûX½1Q‡#`Fó¢îJŒj¯6­­­f'H$8,--•72>Òîò¥z¹FµWx=ç¾Ô2‹XN§OÅÓaÎ,«ää ҉ʃÆFäÑ Œ?ess3y>\qhll„æŒ ]ûT_L˜zwn“–t–£´G‚:ä§v{r’³£½î(í &&'Å(1µ• ,‘RR’á•Z΋E“Í&¶´´¬öZu,&F‘žP‹,FiuUÕBûQ:#©]å!ƒÿè ¥9„þlM8$v²ª;ª ¦¾°o¸Ã_¹Ú˜š‡†®•ÕTUÀ«ìÃ|OÄDéëé~רÞj)<,Tã§ÿR %º½­­mšÅ”½{~obÜÜܤHm`M´v£æ*çÏ%¾}ûÄ ^eŸê‹sLýéž”žî¾Ý» ór«¯KRÎ'ÊÞ“‚ ÑG@)Ì‚ ”Ø]±DÂôå ,zzJŒDm”Ü6JKK…ĄӲ¥°°ºYS°ƒ~OŠ”è‹.Â,åÑ£GË==dÕ†Döm`Äa;ٷŪ ¦^W@,ÌpvtÐ9BKScšÅTÙïÛÄÆDOo:TSÃØPº'Cìá¡`¦¥ia>ùLüI%FTaF†ÙÄ Ÿ>}¢—Rß·1LkÆ4‹}{÷¼zõJ¶í¥Ü\X…ilbl«0YµURÀêžd諪Í~›` ¦?fôÙ„©Õéﻹ.IIIîµ7ÉíÛLÇa°`BµQoµimm=7Íb ¹ Þc)pgÀ‹/ž<©srtظƒªz« ,yÆ›WWUõü{#::ÊØÈVR~›|©Ûî˜0¡Úà¯21aBµAPm0aBµé]µÁë€ @Pmz^mðcÓ@žá Ú ‚Ï“BÕAÕATATAPmžy H·‚jƒÐߘ0uSÂïÛ ø=g¿KŒ Ú ¨6ª ‚ (µéÚ'rîܾÍa¾Ý4\`g»+`{G=WTÕFýÔ¦¢ìê˜Q:9âÌh›•)Ô=ª²¼¬Cž÷÷k¨6ªì´ÆOƒõÇèº.bæåöSµ ;²Ð~Á7‡éMDx(ª ‚tŸÚP™›UE—6¬õ™=sF?U–SøÁn~ÏsuY„jƒ Ý­6’+%õ†RùlQ&ËÉq´Ž¶ÎˆáÎŽWŠ )ûé¸X óÉô4Ǹl"V;¶m512¥=ÒÓÝ 5²~ÖT^ßêçkl8Vgäˆ=»th8¹FSc£Kâ¯ÏýTä’ܶ·??ZËÔÄÕAz`nSRï»a½õl+Êbn6éLüÉÊò2 ¯U+–yPö±zc¢GT_—俬ðp§Œ{wÚZϹ”-.+-v[²xýY?ü·YÏž‚uÖùx3èÐpr “•’kd8E.ÉmKmû¥EµAîÛ·¡€i€(#MvÉÕRñúTÞÈ@ú »Ë—rè&N0ͺ(¤ò%—óaÚ ÛÉx“qÓSUYI}w8¹F˜®ÐÕF‘KrÛ¢Ú HO®¤J‹.oÙ´ÑÆzu˜–tò ?” òS»=9ÉÙÑ^w”ö““Çbȼ‚®Zš_*3Ô ª\¢È '×+©\ñEÒ³"—ä¶¥VR&ãp%… =´oS~µ”|¾›š‡†®•ÕTUÀ+£æ­êÊ1Qúzºí‰ñ¦y9YÊý„èV2·éÐpr.,§PÿëÜF©K²Jw‰±Pm¤ÔæjqÑV?ß™Ó-©CˆÄè£Gª¯Kò²D,'GRBR$L¿QQÑj §G÷ïÙ=o®µX˜öÌ´”%,–ܯÞYÏž½ÉÝ·éÐpraBÌ'Ã)rIn[Àa¾]DèTé}›Ñ:Ú íÛ:±1Ñ0=ª©al(Ýè  vXY˜O>’l2C‰Lªin6)&òˆœ{Rå›}7ŽÕ‡åҾݻjÓ¡áä+%ׯŒÒÉe*wInÛ¬‹øí>ÁßIu€Àþöóçý@Chõ¿\@µAPmðW™=ó½Dü‚jƒj3`AµAPmTÕAµATÕAµAú¬Úü‹ Sw&TAze"jƒ ª ‚ ¨6‚ Q›ÿæ4¸½ endstream endobj 579 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 144 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 136 /Filter /FlateDecode >> stream xÚíÐ1À õ/­‡!| 5<(ñ_õ à,p¿© endstream endobj 583 0 obj << /Length 1845 /Filter /FlateDecode >> stream xÚåZÛnÛ8}ÏWÙ{Q3¼“*P,ÚÍ)ÚbÛzŠ´0”XqŒµå¬-7ñßïP”I–)ŒŠ¢ÛÑgÎÌpNƒ½‰‡½³ƒ7ãSå{>ò%•ÞðÚIŸyʇ«"Þpì]ôîîÏfÁ8ì¨À½y­ƒYÿÛðíѩƞ†™’™™\S¤‰¹É$Ša¼Ò½#{aÂL98ü{@` öÈÃZ0‘ ïj~pñ {cøöÖÈûÚ»KFÎ=A0¢LÂýÌû|ðñ§ú×]³ˆÂ áIÁy°,0üvHî>ùH5Cé'¬³×GçsB½ã¬üqgA¶È ·Ê®a‰/&  ¥pÕÖH§ÓÉz™–!B^öŒàÞŸ‹ù|Ù×-·á2ž†+û|7oìÝ›`•N½š«ÕW,ph~û2Œâå&1zÙ:UN#)ü²”¯jìQË]ðŸ ޹ÝâÉ}0¿m÷H-rŠ˜Ë(–ç,ŒÂe‡ãtÿ›ø&³ÅÕ"CáâÚ^ƒÌ(ãI— ßõÁ˜ ûpY´˜³B«ÄŸ%S°}xD¾0Æ5—³¼D†B¨| Í{A$¢„{ùÚ÷–¡w‡tATõÛÝC˜ñl+˜˜Ñ®òS“ågÛo²B^–D>õݕ͂‹ÃLbsGÔXA"FÓ¤ER蛟åij7ŸÎ d•ÍZ< KЏØb/F)fʼ‹KïýætÌÃÂ``¢°feø:·“ÞOï§Qyæ‹ÚiÉzw÷uëAÖH^lUvŠ ©G‰îPR”ïˆWekQ"b¦d%UªJį¢JÆáu3ŒŒFÓhFí@² gוà€íSHJÊêò{ؤöÆËɪZ(™`¦¼ÌZ¡`%sRÿ¹¯œ)T=Ù"‹òéªl-"¨—,=Zåá’û[øý¶?Q\†“RrÙ“SìÁ®äÁ—û¨É|¨Ñ•qÐ#Pë EùŽèpU¶œ!Î…õ=o–¯Š€©ŠÒ‹Ã= (ÞÌvÜ{ø­ŸxÿÕceª.ŽON_ÿýn8:ýôúýÉèóðË»“¶¡>"öÈÝ DŠò!âªl-D ‡s8‰'ÞOȾƒIÛÀv)pº¦’b$ý†.بÄm¥>^㲡uE®i#0ãwÑ¢|Gˆº*[ Q ¥é±A>¢5à‚ÎVîˆ —V¯tÝu8aÖª?Í{§ªeçZ#I©µôWJÙù~ó‚J];cª‡* •áÍ4¥)n-m±É÷õ,íç/KÄ A#`UQ²þ@àm£µˆVq¥­~´ž‡Ëé•}øÞ§¢ÌÖòyBL5‘» ÇáWŒi”ñÓqÅSó*\¦Ä š í!-Gð€!4w ×óãÑë_ö™pÍqSÑî|9 .3že6ýÇPa$±Í­%ñÂùeÅvd¯̪ív’¨ ¢‡æ›7ë8^DçÇûw–N·;óÝ“ª´&ežN¢yhnF$º¤Ä F«´¦P©÷hýê J“¤×Ä[5¹]ox“*rÄq¸Œì[C>™k`¿•ÕV;j› H¶33^IX©`³²ßj6B!ȤŒT¥ïÉ»Æ+û"½´Éæ,¿“ĹހKÄM¼È7"‹W£±b¹àIÓx5·—é«`Ò‡Ó(}²—md¼è ÉÆñjÞBŠã^2dF‹øÆ ²zVÉÌðf‘Ž­1!•™¢ÊíI‘*yýas«›Å2¾ZÇöéV³†$ ú¤hÈ:§ì!#|ï ¯BõÉêIY…0+8¯’¿Íñ¸e¢›J@²¦.D7{œèέREtC¥‡“…Ó.Å´’覭ˆî .Íåâ¬)ÏM±Bš³gá¹á,„Ö•<7{žÛ ®• ªöL|ž꞉Ð6>&JuGh¦««CsI¾Û¡Ù]Ùs¨Å\á0œ)a‹å¡«[5óÎô4 EEwRI¾£Ï•màs}B!¹S$¸ú‰È矾7oŒ9Ǭî——îˆ77Ew±åûH1À”òm ûß0ËNZŒ“î_”ïèzge¤š †€£þ/Ï&!CÑîP”ïge[€ùHª¬aq-ÿ?’:6ä:ùµ¨cÃf˜²3”å;¢ÔYÙ(¥)Br$OsàÕXizÎ4•´ûUøn—ÝýÍFI¾#œ•m¢ôI¸L0"]Àí™2\½Nφˆ3ò[[®wØÒض°Aº(ßÒÎʶ€4–HùìIVa<º}àÐÜÒŽo;ή\Tïæ!gU›;ÈH3þDÿŒ£Y°Y¬cG×hÛ°u嚢x7׸ªZëÍ‘V²QÓFã§·¬{Ci$|¿Ëÿîå ó§üuü! Uü endstream endobj 566 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 144 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 604 0 R /Length 8910 /Filter /FlateDecode >> stream xÚíWÉׯýïW%Á€Y ¨"A@1 ˜0£®ºÂ$ˆ’T%(’‘!¨€Â Á°°f]®"î{ÇÆ¶í™ifÈ ·ÎsæTÝ®êºÕôýuU÷ =l˜ 2Ú€B¡P½¤aßä¢Q(ª—D‡@ÍÜãÏQ(ª—4ÑÖ‡˜äm ¹P(ª—D¥ÍL¯ÊžÑÑ2u·èIË}'Ú²$Ñ$;.Ô‡V=æ 5Õé¯àê‰~©´Ñ=XD•Á°a¿Ié, Õ×G©­œã÷d~p½$‚šê.‘jëÏÑ@¡dRÝ þ ®é—J›¿_£ 8óß7 2%Ùp²}À\ÿ' Cê%×<¿Ç“WúÓ@¡dRÝ þ ®é÷'Úì/ JjÚ|o8ye€qèi­h P2©îHWôûÓJê@!UÒÒ†l¨âp|Qèi­h P2©îHWôûó}›T÷dîØ÷uà“l8Åé¤iØ[šht®­h "ƒ8þ슩~þ®¹ýëÀò Å ŠZ[† @Ï—È~EÆ8C¿TÚèýq“* 9oa1÷O²áTçÐÅaoi¢µr:YI«­h€¨MZ¾´×¼ù–ûÌðH±p;á°e÷ÅþuŒÔ«ŸÁŸ½aWÖx]8^Ñþ Ç«>–ÈéTD€ÐÚ2&5ÄDWw|&{¶0ôûm•P%5m¾7œº&Ü,ü-)¢dVW’"¤ ÍÐ÷(ŽmL+þóSKjõ…jö¥H¯¨FwVÔ.ö“#¹}ìÌÒ€Êܺǯ? {¸•åì•àà•Ø÷^1Ž›ðÿa0–ãgï‰ Šáࢆ5¾à“9¸ºé3Ijžè]\¿?Ñæ0Ÿ* iC¬³à“l¨ºöŒyø;RD5çàJf#´¢9"ªA;x%6\†bÓ¿Ÿì¼Òõ¿o=Æ«yÝØ‹¨?óŠOß|jn…‰P³f-X¨»:’üäiý§Ö¶¯°Õ'í)Ùì•þôÑkAÃڷ;5ú?û@öBKÔ:à¡ÉÑ<†]­;]UYÛôÏç¶Ï_ÚKØ}_xÈj±o…¯önÝ?ÐïçÖö¢ê×+½S¨ÎiÖábá Ȫ#¬¶ÞýÓšRVoäSFmCø»á3(ÈŽ˜ûayÏß4µ‚Û>ÿ×9üÏNƒ¬<3É?+.˜Wõ¾¥µ Œ÷êšÀO]—ÌÀ-@$ ÂÁE‹,‘v‘ÁÕ}ŸigôHs†Ö/•6úGnQ%!mˆ­ðI6Ts‰´8õŽQmuH%³ZÑ}?-#L=ó¡¸äXA›-¬óFG‹ˆ­Ewjl¹N>)kY Yß&?ü:W?Þ•[ –ýp&eWw½\pcS`æíG/¡è—öÑ7Czyw_¹ã¥ýù÷õ—’ ©½^mbŬõI ëy†]½x/Xà»TêÊMeE_/T¿Ð³@xÔÌòL}ÊÜØþõ+ÄxaÕëÀ¤²¾‰n¬¸õ¬‹ÆG¯ÑŽá¡ð Î©«/6„–¸q“ÏfêgÞz6ëÿ§ñú$tL“²o¿Zî{5à’\uõMóŽ1”Y´?+¡ Ç’#’¯—ýõ £ã?þ#•öà ÑDB"\´Èi\=â3ÉèNØZ¿?ÑæhURÓæ{Cu×s–§ß‘ê˜6‡T2¡ÍPÇiɉ0õºjæ'ûž áµ[ÕÛÙ‘‹<¯uLWNÆ­ó¹dë•áà“Z÷ö£à~ÅÉT±-AYý®q©w6¹+ÎéDÖE[/žGX.ÿ~Ó`á [aª#EX†‹O¼‹Ÿ`õòíKï+dCj/¤WŽ>) ðê'îššÛ¾´µs£x.œ$GŸTGŸä5¬ÄÙž|‘£&’¸cr³êï­in¬‹.>—€ŽÞ)˼3xÑŽá¡ðÀO¨¶Ì›çà“æÌŒè}ã¿+¼ÓI ¾•í9YDqÿÉ$Gïäå,ä¿~ýêŠ7ô,e)³¨‡‹4BÞÞ; öì˜T^]ÛqËÑëZ§{t¢ˆ„"D8¸h‘%Ò.2¸ºï3 â|&õÓ/<+¨’–6dC ·˜¥§ß“ê¸î‡Üf6B+š Ú]âgo›/\¸Ó7f;ÎÄ«€°ïæœ]ñ-ÐfyVÀT_`áž_Á♲âÖÖ/›Ø±ó¼:®ÑûŽƒøZäU¸€UNlÝÈŽ›ëU KÚ¸ÚÚÛ7²âæz–÷BZ{]§úIXvÅÉxÖÒúåÛúåëý¿ÿÝ]má“¿Ðëèײi[½Ój«k^Á`Wü¿^ø'UØp æzògy–Óö@z(<—ˆû¥Oš?µ~ýî,0d ;z¾çMjå…žEdÑÞçGq'ÐÞ«a¤ÂJáR Ȉ}û@ÂÓ«Uo›¿ÍmþªyyW´…æ½ :ÑDB"\´Èi\ÝôùÇ)r›Ì‹ô™Ã襤¦Í÷†ã¬Ï¼§j]èmZ+Â"ë@+á_g§å&vÜZvÈ•}É•`ç“=ß»˜Üjæ}ÍÀ«ê×½,UeÌ{t¢m¨aBHwÚö¸Ïj„âúý‰6>w©úyn3Œ&jòúA›ï 5Ý—E4k}تh[¡ÍÐ(`I²u6û^ÂõûoÞ7¶|i{öîsdÞÃíܘõœSVÇá"¯°®þ\Fa뙬?áZìÂN2aÝ„¶Áiu/ß|jùò±¥­øqÓ¾ Õ+ØÙ"{ñÍzñÏÇÏO|Dy"nW»âkþ|ö–„ÿ~n»WÛpîòvn´©Ï á¡I"CŸÛ‹|JlØyÎì4Rwnœ1‹/Òá!lŠ~ò¼¾¡­­ýmcsà·[ëdæ¶ŽTœ„ƒ‚ÜäÊI\ÏIZÍNYÉδb_›ïSjès§kGf€K8@h¡!2LˆéNÛÞð™ÙHë—JÖŸTIK²¡ÖÖd»ˆi­hÚÆÝÍ2cßpë"6ß…ìνàöíì]ÇN²eçÍg‘K€¨µìnŠ 'Õ›¸ž›lþjĪ€†Æ¬Ò5œ´-h˜°–“êÄæ-ge/bñEö[wrÏC/.œdaOveÇÉ_p’×sS7r⦬b‘C“\sXwLÙ%0LSV‰¸##<„å¬@ñNÜZnš+†CV`n+áHÅi'Dìd3÷"ä »%»Àš} v8›u·›d€«;Ò³ÁÕ7>“ú‰6쪟ôÓ/Ä®¤ÈïÛ µw¤[‡½Z~öƒä²{9}ÇeºßdùºŠ“aƾ)áVCvœívœp\%œÁA!m6HÒiƒ´A¡6H¤ iƒ´AÚ 6H¤ …´éGÚÈ>èh#•ÏHTÑ&3=Íf©ÕDe¥Q ò†3C‚ŽÚˆ‹P¤ Õ´Éæ¥O™<éÐýù9Ù•·ø bm­­d€6•Ç'Æž#‹& æ‘ù„Øs•ÆGG„÷øÜ†¡a§´ 0Y8_yÜXEy¹¿MÿcŸÒ%c´±_n·Ïc·ÈMŸ®ëE È@‘°Ã‰íãyTKCæBº:¿]ˆ9ïÇakkjŽ¥0oŽ!Ì”¤ªÆÐ ËËsšš*QÿrJ’T´Y4ßè½»‰|läiù‘#bΞ"Šû=vÂÖÞXIu™6§NNRVÚìêr6ì$@2ãcj<iƒ’1Ú@ŒçffˆÜ´kûÖÅ‹Œ¯åæ€-\°{Ç6’–KÌ®ð2ÊJnþ¾g·Ò¸±K-Ìa'DÑx‘TÕz±±²ÈÍ΄ú{víœ?wŽT´9¼ßB£¹DÞóàï°·£÷E£Ù°•¡Iqç—ÛXÁ¼B~ãúµ¤ßÎÚRØžr1fýgU•ÉJcÇX›/‰Ž$öFJZÚ˜›š¸®u¹ |°_f € CNØÄù,Ò7¤ j Ðæí¥|‘›4§id¤¥y˜Zhij(ÈÏ%òåüb(æç‘ű£¥ªÆÐ‹ÈúÒ&9îü¤‰ÊÑgË%ç•ö@˜UöË!u*dÒeØJ¥‹³ã\CØ2Û`&i_ë´rþÜÙçN‡€`¤}³›Ë\ƒYgB‚â¢ÎX˜™8._Ö͹ ãLpÈMkW9€oàáÛºUŽÌ>‹ó iƒÈsX ‚ IP«‰+JX­k½Hr—fî\!c¨¯ëÏñž¥7òÖ­; jS§„÷#ò!Ç(v•° "H»¦ºjø‰ûù3aª*“ºI`~å.UàÕ7p•Ùgq¾!mPá¾Íþ½ÒÎmz6]ëEÚœð÷ÕÑš+ŽéšPÔRWƒeÈ45U°Óà0ZAž vÈPí‰"íŠ Ôu“üȽ7·¡ùÅN|ãÒ5 žI©L:rðÀµÜœÊ[üÄ‹qä3©ÛÜÉ;*&Æ wmßÚ´éZ/>ÚìÚºÙÆÂòKÍÍ6»ºü¦¥)|g•:O ôëtnÈŠ=!ÜÈЖð¾ Lºº<·¡ú,Î7¤ j |߆—–jce©<~Ü(ùÙ³ÈïÛÀºÆÍeñ´2äz§giÓµ^$¤ ¬¤”Çý}×ÈïݱmìèQÄÚŠF›µ«Œf î€æþ¸?³Æ‘rßfÎûÖë¡Zh?Lœ€Kw“š ¼Åm}dxˆà™—E>“Èû6s f®uZÉì³8ß6(ü.q¯~»/:"\A^âòpŇ<õk6´gOJcÇLTO}¾+[+ ¾~õ*hN>÷Ù¶ÉMS]ø Ë´#ö’whÇÝ…gR‚ùI¿É#h®(/§«£M~ß|XakM<“‚ ¹zç³8ß6(¤Í`ùTp€¯Úü …´é%­´³9:4"ôä\ƒYËm‘6(Ò¦—´uãú)“&ÀjÅÖÊü’¨oÊ!mPH¤ þÇ ¤ iƒ´AÚ 6H¤ …´AÚ mPH¤ Ò…´‘ù÷€ƒþÄ S&¸T YÚ P¨¾Ò…BõÙí ¤ …BÚ P(¤ JòƒŒB Y!múé˜0 ÁDeÒ¦ÏhƒO?1 µD|Éiƒ´Á„ iƒ´Á„ iƒêÚ”–òuu´‡ÿòx6bBÚ mz•6f‹M2.§ã©ˆ iÃL¹ÃÍLMîU–ÓŒˆÉi£4nLKKË@8`~EãÓÀ¤½Ý2¯#‡6]¦Í@‹n¤ ¦KþBéZ™éi´ÉÊH·µ¶š¨¬¤CC‚5ÔUGüú?(>~ôhµ³@˜ÿ¬rr|÷îÙêlÄm­i r# fê—ÇÅÆêêhR31^øðÁ¢Z{{»ß1ß隔ǻoÙôñãG¤ ¦AMøŒ=ih0óNY)6úº3b¢Î–—–‘Ü\Ö­YåDV°\bv…—ù}Ïn¥qc—Z˜çfvÕÜoj¼ðJ¯¤¨ÀaÅòÍÜd~ny'‡•/_¾$Šs g477766îÝã±}«;YÍ~…ÝÓ§O þþ~ãÇŽv\i_SSC-Ì͈j!Á'­­,kkk?44lps=x`?ÒÓ`§ hëæÛÝ·0¬¤ø7‹Ô¦N!+äçùr~1 óóÈâØQŠD^G[+órÇ<§ðjÞ45Õ¡@›ººg"ÿRMMM0ç!«½zõŠÈúô Н_¿&‹£剼¾ÞŒGùúúz­iHL2@›Ûe¥³géÚˆjLŽ¿{X¯­W”)G⊀ê[ï¾7—mÚ|ýú•,VVT,µ´€u±Ô’ñ«H ˆ+v¨+µ‘ÃAÚ`’Ú€2ÒRfü6½ôfiÔÒÔð÷å^¿SQŸÒ¾×[gºVnvæºKL‹t˜Ý]¼×Ðð¾­­ >É­ÒFOWçÙ³gx—“ìÑäyø'{Ò8EeRXðÉÊ[üÜÌ [k+iisôÐÁÅ‹Œyi©0qJON\ak;Ôh£:e2/ãrKKKMMÍjg'iij³ÔêÁƒû­­-UUU.k× m0É mîU–›™šÆˆð0˜Ÿ(*Èk¨Mõ:rHZÚÜ­(ƒVp}­¨ ¯;#<ääP£Í•œ˜Ÿ(ÈÐÔP?.-mÚÛÛ¡•¾Þ Eù‘³ fòxr†öŒ ¦CþN &¤ Ò&¤ Ò¦iC[.ᢠÒiƒ Ò…´Á„ i3ˆhƒÇ5…´é{ÚàeÓPžá mP(¾O …B!mP( iƒB¡6( …´A¡PHY:È(ÔҦ ÓLø}üå&LøË¤ &LHÒ¦B|c&Ò&¤ Ò¦ÁH›Ìô4›¥‚×ïŽR74˜ti#m†ÿò³ôõ¨¯‘‚üL=]橇ÿ|ÓP£M6/}ÊäI‡ìÏÏÉ®¼ÅO¸kkm…´‘–6 æÏËÊÊ$-¼ŒË`é”6xöbR´±_n·Ïc7óJ*+#“åqcm¬,o\#ìç## ôõÆŒR˜¦¦Êey3ež6©))‹M‘ã…i©©O–˜™&%%’›ž?¯S›ªÒØØ(’6` ÖPWñëÿ øøÑ£ÕÎNp䕯YåäøîÝ;²ÚÙˆ3ÚZÓäFÌÔ/).Ž‹ÕÕÑ¥ ]?|ð€¨ÖÞÞîwÌwº¦Æåñî[6}üøãS?Ò&6¹™Ì´Ñ×u¶¼´„£ÐÍeÝšUN„}ªÊäÐA0#‚yÑ'G£ÌÓâ‚ÏçC±¨¨ò`!x’Ÿ—«*(•·¹o9 nnF'‡•/_¾$Šs g477öîñؾլf¿ÂîéÓ§¿ñcG;®´¯©©!ŠæfDµà“ÖV–µµµ6¸¹<°ãS?ÒFQ^®¢”/ù]bþÍ"µ©Sˆ¼ºªà•vW¯dS+ˆ4Ê·IŽ¿óó JãÁR”ÙaOˆ·±²˜4AI[Sóì©pãP MKK ,‘àòTÚðxzº:mmm®.ëN…‡3Ü·#õnseEÅRK XD’ñ«È¶âŠ€*ÐFÿãSÿ޷ٿ׃™6Zšþ¾ÜâÂëw*ÊàSøe¾gÂC§¨LêÔ(Û´à/?r8±P¢Ú ³ f>ôÇtMÖÖfÚP‹:ÚZ/Ä54¼RÁ§´/öÄ={ö cÓz&¥2éÈÁ×rs*oñ/Æ ?“‚ aÁ'a+Ì‚`+i·_f›‘–r»¬À¢ª¢Â`"´a@Grr££Ï3·¢U§Læe\†™RMMÍjg'iij³ÔêÁƒû€¸ªª*—µk0^0õ#m@¼´T+KåñãF)ÈÏ6˜%ü}›ˆð0éZŠ òj‚{2¤=(ÐìcF)èëÅDe0"mÒRSuu´¿|ù"m®ääÀüDAn„¦†:,Á¤¥M{{;´Ò×›¡(?&W° ÃxÁÔ¿´AõÁw‰ìW$&&àéŠ iƒê=ÚÀã\T$L-ȇà˜0!mP½AX×L×Ô¨¬¨ÀsÒ…¿ÊÄ„ iƒ´Á„ iƒ´Á。BÚô=mð2‡i(Ïp6( ß'…B¡6( …´A¡PH …BÚ P(¤ ªoNªW…´AQOL˜z)á÷mPø« LøËÒÒ…´Á4HS½úp°Ó¦gßÈùûžÝ–K̺ÐÐÜÌôÀ¾=Òz.‰6˜6²G›²’›“'(góÒ»Ð63=Meâ„òÒ©<ïô¯ƒ´é—p“ù·RÚ—`ù‘#¦Lžd¿ÌöZnÎ ¥MÀ1ߥæ]nÓ› @¤ õ”~¿^ŸEÓ,}=ꫵ ?SOw a¤¿Ñॠ‘¹[Qv=ÿÊ–n æÍ¤´±³µôóírs?ÛÞnYÐÆ—Ë)**”Úôc/˜?/++“´ð2.ƒeÒç6]  !þ±£‰|VFº­µÕDe%åqcm¬,o\#ìç## ôõÆŒR˜¦¦Êey“°Ú»{—¦ºÚ¥ñÎŽ°¨„;å·vmߪ¡6Uyü¸CöÓª;‘F- õ+¼ïýç’ȶ~{µ––¦F÷it<ÐÕeÝÛ·omà´<qF[kš‚ÜHƒ™ú%ÅÅq±±º:Ú£äLŒ>|ðê,13MJJ$›<^§6U¥±±QÜ;hBC‚5ÔUGüú?(>~ôhµ³üÕ”ÆYåäøîÝ;ÉûýïÛ¿ˆ÷;æ;]Sc‚òx÷-›>~üH6OMIYlºˆìZ¥¥¦ÒÞq³kçŽØ˜²NLt4X¨Á™È³ZÓ4ˆ~«««BIG[믿ª‰ü…¸X"°wÚQ"˜ÛæçmݲÙxaÑ×u¶¼´äæ²nÍ*'Â>Uer艠Ê[üüœì5NŽ„ñðÁý¦Æ ¯dñJŠ V,ß¼ÁM8öyì6^0€u6¹­§9 Uw"ÀÉr~1Ù8—D¶%nû¤í2m"Μ&Îò’‚ÓÒ~…ÝÓ§Oá,õ÷÷?v´ãJûšš¢hanuòóò`‘B¾b›ûâuŸâBÉÉaåË—/‰âÃY……ÍÍÍ@§½{<¶ou—¼_H!Á'­­,kkk?44lps=x`?ÙüÐãóùP„‰"äÁB£Mkk‹ù’Å)ÉÉÿ}{? ä[[[i´qrtxöìô N*¾„“Çî]þùûÅ pøŸþ!þ {!OÛ*®_‘)3“G¼N`«2iÂùóç ¿níjbA'®£~9D2°’*º~uç6w˜ÅÅäø‹þ R”ÙaOˆ·±²˜4AI[Sóì©pr^A¥–Â÷Ê4T”òÅ9 Uw"°’Êá]&÷,Î%‘m‰•”æ´®¬¤¬,Ìa’|`ÿïpM¸? îKøVM/COW§­­ Ö€§ÂÃn€‘zó¶²¢b©¥Lò‰p“ñ«TýBLQ£uäð_¨ZZZ`M—˜˜ŸIHl–ƒOžÞ?³´ôï¿ÿjj¨C.9ÙÙ‹MŒ!r}ÇÐQ"Ù¸oSz³ˆ¼¾kijøûr‹ ¯ß©(ƒOZÍ{•ågÂC§¨Lê˜HL×ÊÍÎdˆn†¹T݉4ÚÙZûs9?æ6Œ. ïPp—x™m×VRp-ƒë/0‡ŠAGˆ±Ã‡þ˜®©AÎÍ$yw0L /^ˆkhx¤‚Oiß ˆƒeC/þò#‡+;‘¹wïÌ2.§««M}òäIwhÉÒ| ,—`½yøÃ¥D’ŽúøÉmn\ßµ}ë¼9†D"1,ødå-~nf†­µYB2#-åvY)D«ªŠ aÖ‰ƒé¢‚¼†šàF8Aþ`‡e‘¾^LÔYò&3ÔŒVTÐ×rRÄ3©²Ò[ÝÕ¦NåÒ‘ƒh´‘ª;‘Ær~ñä ÊYéÌ.‰l›yY6¿Ý'9mÒRSuu´¿|ù"m®ääÀÅWAn¬8 H¥ ¥öövh¥¯7CQ~$„3Ì%¤¢Í¦ˆû9D vß²IÚðKJDÞ1¾w÷.L¥ˆç‰oÞ¼û‰‰ ÿ ë£ÂÂü.1Òf°Hf~'WÏsQ‘pÝ$‚cBÚ mP½A8u§kjTVT`#m6(üU&¦6(¤ &¤ ª¿hƒÇÕKBÚ ¨'^‚1õö iƒB¡ð}R( iƒB¡PH 5¸hóÿ:^šâ endstream endobj 604 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 144 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 136 /Filter /FlateDecode >> stream xÚíÐ1À õ/­‡!| 5<(ñ_õ à,p¿© endstream endobj 580 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 144 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 605 0 R /Length 8648 /Filter /FlateDecode >> stream xÚí‰_ÍÙÿÇý¿ùΠdi‘ÒÎ$Zµ¨m–VûZ4e­î–%Qj”""-*•(R¡’#ÌXÊ`È2ÆdÉ2¿wg>>÷ÞO÷ÖM¹½Ïãõèq>çsÎç¼Ï¹Ÿ÷óó>ŸÏ½}úõkOjV P(ª›Ôïs‚¼Wês …ê&àÔXîø…B¡ºIÃÝy$ÈÚLÝ@¡P¨n“6ã"ë£ÍµAiÚ³¢‡»óe‘öLÔ‡V 3…êÍꊃô”s)¢_&mÌÖU2eѯߺjÏt”,,,hCƒ€Tý€”I[oM‰{$‹ ¦Š~À>–(”Rª+ÒSÎ¥~™´ósSÀ™?ª=ÓQàІ#<¶[n»5-þ‘ìš¼õæÏm,P(¥TW¤§œK!ý~A›°r¦ä¦Íç†#<·[ïn‘WЊe ¥”ꊃô”s)¤ß/VRáLÉKÚPÇk‡Íîy­X PJ©®8HO9—Búýò¾ÍY¦,,,è=Ž;6ä¾ü¥ u}vÙ%;NhELÞù_›a3·ªÉ\¬æ×µŠY¸”ŸºZd»©ä+3c{}|ÉÝ›_²Ìë„1âã’8RÅ .Þ CÛ£t7‰å 2Š8ˆ¸s1ÝŠé_ð—Û¹ºh3%3Oz—Öï´ÙXÍ”Œ´!ë,øKêù&9&>¡"ÕæÆÕsB+– ê8^‘Ù ÅÛÁæßÿ¼œ™oþyï–Â;Ÿ¿ùÇÕã6UÃæí–—¯Ú zµ­¨ J˜‡Ú”sëö£—mï>À^^ÞmÚŸû÷‡í ›¿Š.¸cþ¥ ´VbÖ m7—rÊoÏÕú¦¿_¼~÷úíûª›-O».>de]·µ°éòÝÐïë¶÷•=£Ž29tìLSË?â#ešÍÜ—Ä‘v8ÃGoÝ}ò ú½ñ 5 éj‡q‰(ú›KIaéÕ§oÚÞAá•»Cw0ØNOT/ËAdqqçby–Är‰ÎÕu›YgôÈ2†Õ/“6æ›.0%#mÈ^øKêû§8ýò„ŠT›_Ï]­X€>Ÿ‡Év§`sú–:B›%üýV›+ÉÞʆ;î¢rÞQ_~æöミê»[ O^øò Å¿cªá÷žÛÏ.Š)ºôûØÜšwt$*h‚ÍÒËúo)Ì«¼ù×Í7ÖІÌ^¨U‹ø|y™´ÉsêÞÓ×íà:R(Êå§¹øû£iåâ£æVDîíê›Ïßøþ^qõaLvíÂè¬ ~zÿ°õæ2jLãÍ»1%â#…ü‡Ï¦²,—6.fI‡3|ör“{te\n-äï=~S‡#b}ÊD ¶ä$眩½Öüºí ¶úæ_0pyçªwŠå 2Š8ˆ¸s±n…’µ»rÁ5–ćüÃ'ÏgDÓC ÷dùó»G†$”Àæý–gNQ%°.Óí£H(ðçeøom <þË9ê$mÈì…ZåÍ; Û˜vrêïWïÞ¾{/J-ôf{ór½y9óùY#ª%Žš$isrîêýe1yAüÃþ¼#@﨣?EL¨ìp¤ç îSY3Ì1.Zrçñ+;5‹ß¾ëÇ‚ ‹ÍUâ£ö)ÓBÈ{Dåùó3Bb²/66}ºYÆ}¨oB,‘QÄAÄ‹åYË%:W×mf¡@šÍT_ür!¢Ž)yiC˜±ç)Õ§«gü%îBhÅ2ĺKÜüøÕ¡3¿­Š>°@nYNÊÁqft´ñu°Bi/íŸÍ/´ãŸ‡|[ÛÛE‚ƒ“#?Ý‚ݲϋ—gY1•‘ì](H·Œ¬ÈŸ5®wïß/ä§[FT‰÷BKì#Ï0í$%‡4¿i{KüýúýV¦5:ñNM‹<Ë1j_~koT^Sã?áp¨êk÷¶e×¹‰Ê-#ªÇG\d6—6RJb<Órîq‘’g*{ò ¬#?=[%ØkY.þÉŠ—Ù ÈJp)<óöé«_}Œm®Ýyp¨°r‰à ûh½_,‘QÄAÄ‹åYË%:Wmþï¿Dóm¦âø”Ü´ùÜÐpaºkÒS¦üv_bµ"… ZZ‰ÿ:ƒž‡‹龂lP àH  s&¯xJÔyº×!ªÌ"²êß}Ò¾T‰ˆÏ˜uÚ5ö ¹ò®¤ÚF}Zv‰öd;F•ZDÖÎÞÝØu´<[)Lµ‰ª¼ÿìÍÇëòáÅ‚ƒ~‚,ÐraÚ*Ñ>ðVñ^þóލ3,;¡„ãPPsžèØö}ùùåíòìÅë©Qç$þ,e™0 ŽFD{¡òáç…ï<’SRsëÞrßæTã3Ö¤Iéû, ‰Nµç•;ïø•i9÷¸HI‡3üq¢NÃD}ÚI°_Ú§Lk–6>ƒubûzðÞßÉ'Wì,X$L‡ù„H©Ã£õ~±„ù˜Õˆƒˆ·e:‘´r‰Î¥›©sØ,ñwR㣘bÒfݺ~,õÓï×Ï»]”6´¡Ñâ ·¤§,±¦,dU€V,@ôŒ#Èùò=…®¼Ò©¼ Æ^^©ŸpúO(©¨½ê±­2óBû­òì’ +„ûíy•ônÆüØJ§˜«•¿ý ›éEçÉÞ˜÷a³¾ñÖÒ…Û ·dT]¹ýœÚžW!ÞË_/Ûã~b&-aÖá8Ô™ëϧ\ñGìk_¶<ý{ cRÔEñ»ñKÈA´ª©¼êüSsùA‚Ì yùgîµ<ŸÉ/f#m¤w·ã"-¯lÖ¶ª‚†§LËÅÇ%^Òá Ó‰Ÿ7i¯yëÑ«ô²ß×ì>$„‹Ë?~ÖA®‡ Ø‰W6™WË}´Þ/–ƒpІé&ÄAºÒVá6ÔˆJë÷ Úð.3õelÓ¥vÔœj×´ùÜÐxiÖOÉÏÄÐÀk/´bú|¦8ð+eÙ;Qp%óÌõ–§Ïß¼}×üäuJéo+D„™vüO_í8\Xq÷Ñ_pÝ„½IÇ…¨Ã_mË?mãòêî>hyùæmë›wçoþz¨q¶ Xb/ÑÇï½h}MÊ%Z"íP«3îüÚü–„ÿ¼~w¥éÙö}ÇVˆÒìxgŇ&‹&ð.ÙðªÜ¥syà•KEéÖüjjŒ´‘í»ùÇÃgmoßÝmù‡_ÐÌ´\|\â%Î0îÏŽ9oÌDw ³„ÙóG=E.‚²)¼š ¼†ÎMTo“¸ƒ°\C¢›éJÛî°™»Õ/“6ü_™’—6´¡É²œ™ÉÏä´b@´\t0X”ê 8+ã^Aµ¿ g©èPÐÇÓÕOí.(§}ª¯à¨¿è¨¿07H” Êqœ¶â×ACk~Í|aÞ!4Ìôæú gñ‹møÕ{½«Dû¡aޏ%‡š)<åsD¹ … ;þy‰C“]“ø v‚*¦¿ŠiŒ´‘Δ,X*<8_˜?KP«ÂBZΪ#íPSõp¥†ra~]…[âŸ)É"÷Äãו ¯P”õ‰6Ñ©ªní%qæÙ_ íÃÒé)çRH¿_þ§Ðë ‘…¨ÑlýÙÑ!ÇGɤb³õ•„Š2@š–G§‡D§NUwwG(–ü£óÄÕgg£+ÒSÎ¥~¿ MôoÊ-÷芹ÑǧG×(ýH{ç̳„D_“6·üú1¤…B¡(Âm ü×Kuÿ*o‚Ñ¡P¨¯,qÚ(·Köë×?z iÓÝŠÙ´¹{çÖ7!0MUnS‘6JO›ÜŒƒß„ÐT¥7µïDÚH›Þ¬ðàhªr›JŒAÚ mÐ/ÐT¤ Òiƒ¦"m6Hta4iƒ´AÚ ©H¤ Ò]iƒ´AÚ(Ÿ_ ìÿÒ¦ûŽ/×ô"md¡MQ~žÛ —ášjª*,ÆÅÇî@Úô6¿vÚ#m6ßmŠ óuGho;u¢¸þBu桃î®.ÊA›îðÄNŸœ~1\S=ëà>ºi;u2ÍgÜ7\C=-9Qác윩¤!K=ªuH›„Øí¶Ó¦h:Heà˜G­ AÚô m)>|ßÉÁÖ{ÖOÝÛèÈŒ-ðŸç9Ó»wX0&ïÞ në?ÏgüØ1Ó²!t  øм¦1’âb%î’öÉJ›^iAÚ(*¶% d`“r€YMÚ¦ŒÕ:׋BVR‡ö%ëjk‘¼™éè°•$ü†Â#/^ú#uvïØJ*ÀõW¤nwЗץ I”µME¼oß<(gl`šÄ(×IˆÝNòP–è%îüT¾?)‚„î¸o]¡ýŒðbàwïû÷ì&y˜êÁƒT%Z¥«=|ù¢ ”ĸΙ WÒLÆ 1¦¤}²Ò¦WÚ@6òÞ· ["ol£@Út®—NÓ&6Z0ÉbÄÃÄST å›Â×éëåJs´³3œB OOWÈÀf7Ñfç¶hS#ðÓQƆ° \ÐÁ(g™e³ •¸oña§cæôJÒFÞïÛæåº¹8kªSSU™h1ž~ßÖ5Aþ~äidèzG±´é\/¦ œ´ÃB! €«žõf¸4ÃfðŠÿîFÎ÷ö¤«{ˆˆ|}tp'ô€Ò’Á*8ù!—QÈ3¿fÃzö+Áášê̇&`›»‹)˜7šÓÀ†il —Þ`ÁØES9¾o¼| 'ä0ɽK£ Ë*X”Á‡ól:ÊX±±³ |°jǤ2ÐÌt4ý¾´OVÚôJÒiÓ9Y[Y†…¬R‚_ôÄmÖ×ÕÁïãï¤6½6påZ½l1\³èCðoÑ/+¤Í×G:&L}01‚´ùj´Á§Ÿ˜úZ"_2AÚ m0aBÚ m0aBÚ B›þ÷xbBÚ m6˜0õÚ ìÿƒƒí•ú‹¾Ô¥(Ú°êw¬à°Dè#˜zmÅ9§Kôõ”•6ׯ_#ùk×aÔ]¡Í£ŒéÑ €aíáÇ$ÿòåËÁƒT6˜¾QÚ\ª­™8ÞÖDÌœŒÃ´Ã:ˆ¼ qÐÀq$m°Ã|‘¢êçæÊG›×¯_“Ò1aêƒ ¿oƒ¿\À„ ¹€´Á„ iƒBÚ`ÂÔKhƒoÌDÚ`„´AÚ`Âô-Ò¦(?ÏmFûëwÕTU&XŒ‹Ý´éVÚв×ÿûïFêhøùÞ¿w¯Ã&›˜0}´).Ìס½!<ìÔ‰âú Õ™‡º»º mº›6$óþýû¬_î`o‹´Á¤ô´ñ˜534$˜{%u¼ Áæ°¡n.ÎgËËHùþ”d ó±CÔTôõDü(ŽB%¦éh“k×IþPúA’!ïç]½jåÁè'u - JÄYñüùsúš]‰TaýÏañAüæÍ›°Ðµä¥0¡¯˜ ){“MŒ ÕTÚZOkl¼Šþ‚©iMIQ7mÌÍÆHÝ{±¦ªúlE¿ßü9>¤|¤ÎˆÝ;c!"‚¸h¾7G¡Ó&$xõÞä$ÈÀjH}èà/^@>9iÏšà¶¶7ŽÓíæä@INN6äÛÚÚX±ÍÇ7oÚèäèÀÃpÇ6|^}á‹“#}}Tóñöjnnnmm íílÐ_0õ m© ¬«©–ý.qõ¹Jý‘º$o ×þJ»Ó'‹™$*1mŠŠ ý}çCfGÌvm­ýû÷AÞÏwÞñãEyôèÑh£ˆÍ›à/äY÷mˆ´4ÕitÔ9Úp¼ÌhFò/_¾¤&L½6¶ÉÉ8 q¸–†:”€ ð©<3ÃÍÅI[Kc´±ñÞ_9 •˜6ÿüó±¡d&ZŒ;Q\lok y(p‚T€H¼>n×N‰¬xüøqTdÄ g§®ÐJô•šM¼Ûƒ©wÞ· [ÂMcÃmÑ¢ógêjá¯øË|“wëêhwX¨¬w‰§ÃrÉzêÈÃßÂÂXÎ]W®\14Ð+8–o ?òÖ­[½_4êP@Bò–Кý¿ÿŽÙ„µÉÛ m0õ®gR:Ú›Ö…—•œ¨¿Pu8]ü™THˆÛ{! ‚½´Üã'÷‚¼£—jk,z::…ÊMXCL~IL„|bBà%vG ä!¼€çÜÙ³‡…Õdˉ¯^½byýÓ§Oø¼(ɦ½M´H ›šš¼==hMX£Ý¸q¶bmBtDïÛ@˜Ä‹ŠDÚ`ê…´æåº¹8kªSSU™h1^üû6ɉ ¦£L©ªê·ß“¡å±1Û |ˆšª…ùØ©{9 •›6W._V𬉠ßÒÒyi ¿há‚ýûRiµÝñqK—,bÝ·®©T¹}û6L€<á˜îMN¢|ˆÛ¥©1LÚ&¬žB׆gR¡«*¤ ¦ÞF~—&¤ Ò&¤ ÒÏ=LH¤ Ò&¤ Ò&¤ J^Úà< ú 6_Ÿ6x™ÃÔ—#¤ …Â÷I¡P(¤ …B!mP(Ò…B¡6( iƒú:' Õ­BÚ ˜'&LÝ”ðû6(üU&üå iƒ iƒBÚ`RHê;ÿ±›hƒ/Ê”eŠdÑ7Dê555Õf¦£ñ?‹"m6½‡6~:ß(mìm Žå#F6Š¥4w@ÚôeÚh B_ï«@—$êÿýw#u´ü|ïß»'—wÑ©™/ç"fÀ0-'Mؼi#ùö2¦¬¬ÌqcÍÔTN¶œX]U…´AÚô,m¢EÂÊÊŠo—6Ýá>Ì÷?xð`ýºpˆ zŠ6$ÓÚÚz¹¡áçÐ5zºÍÍÍ2gö¬Ÿ Õëׯ3212DÚt‚6—jkýæ×ÔС½îçP¤M§i»#&Ðß\.{œ6gΔÁ%˜¼2†¼5˜øûÖ-Ñ£Œ µ4Õ—.YD_ëI¼†ùq‡Ý›œ4ÚÄHuà‹qæUçϧÒ¦´ YµÂÞÆº¬ôdYÉ ›iS‘6£MrÒžÕ«Vöž•xz~^x"xýò¥KHa|Ü.W禦¦¿ž=/[&clå³gÞ¾}µmÛVõ¡ƒ½==îܹC6 Î©ÒRXhÐHètGÌvVlóðáCX¿úÿvö}Ä€úÎ>'GŸG«ùx{A¬VAiogÓáè`rôtG°V|,±šÀ$fdFÚt‚6&ƆyGIþØÑl¤ì´SîÞ½? sñbíD‹qmmozmàâûKb"1&ó±c~ÿí7’ôèYÈH›?ÿü“ä_¾| ›À ºIc•iS¬23«¿¡y×0Ëy!¬ºv­±+´áx±D«8F×ÖÖ¦:°¿\~7iÂø¼Ü\¼KÜ9Ú QS­«©&yÈ md§ \X5† û.©™G2zÕ]â†K—À*m-M¸—œ}úÜÖzÙ´·³‰ [[[›šš¼==hMm-0’¶bmBtDïÛ@˜Ä‹Š”—6€¸Ë a¡kåz&%Þ ÒF^ÚÔ_¨öŸ?WKC]G{8>“RšïÛdggA$C¾RQQNïÓÂÇ|ì˜A* …Âi“—› k··oߊß4\S¨rûöm™yȃ³½ÉIô8ñq»45†IÛ„ÕSèÚòL 2tU% mÈ÷m† Q³œh±i㆖––®|£iƒ¿“BÚô`òò˜••ÙG|iƒ´ÁßIõH‚Ài_j „Lô!8ÒiƒÂ߀w“ë26¬¯«û·Ï$¤ Òiƒ Ò…´Á„´A)mpPÝ$¤ Šyà%SwG8H õõi¤ …BÚ P(¤ …Bu…6ÿÍZ*ä endstream endobj 605 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 144 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 136 /Filter /FlateDecode >> stream xÚíÐ1À õ/­‡!| 5<(ñ_õ à,p¿© endstream endobj 609 0 obj << /Length 578 /Filter /FlateDecode >> stream xÚ½UMsÚ0½ûWèhú°üqÍ´¤“é¡|£9[MŒEmQ ¿¾’%'5%ÔÉô´b½»ïí“ØE` ¸ nŠ`¾HsðïëäcD-v¢Ñ_Oå$TªÖrÿ&Ù¹§æJ]°×²{»ÆdÇ×µ˜òÄ}ê»_xyèÄÔçÚýeJhål+J!-Ò~D8çc„Í­[Çy­x[ ãd˜ØË'YU¢™ «I|¥¦˜yœ²|L„R˜ÙõbkQC:J«F…ŸyDPxî?h·p¾´Ö§ö¾0/Eç–Öˆ2ê¡hâ{-’(Õ04_{»AóškQ/¢æg‡mvkq{Hß;×Ãxit«j¦:©¥òSžx­0+@6ÛA.óßh.4´;¢ Ç2^Û®11JÆS–ë/l|öŒ endstream endobj 615 0 obj << /Length 782 /Filter /FlateDecode >> stream xÚUKoÛ0 ¾çWè(³¢‡åÇn+º-6 [CÛƒj+‰1'Î¥iöëG‰vóh{Y.¤©}"Nf„“ËÑÙd4¾È R°"•)™L‰NYZ(’ 3A&¹§Û—ËÆT6Š¥æta–ÓD“ëñEÎIž©òžI.Y.rˆœ¤|–Ó1 ¥½Ëèëdôg$ÉØçG¥I¹Ý?rRÁÙ5á,)r² ÈÑ‚3©RÐr;ú1â}ýÉ!ƒÈ5ËyAT!˜‚xÒ3?‰=J*ãLæñÕB$ä¼…Ì?Þ䈇$ñA–·ÄwLéŒ(]0 4’.êÙ¦ë‰UL¨ÏQ¬§ßÌ®Ý84ßtíÊv®¶ë@àéM!}¡Xš&^2žh <™Ûuˆ[ÐÕ>@,SNÍjÕìðȵ(Í2šöÆm]ͬcP‰Êé¯H@=í]KL9·åoTÛåf9}ŽÃ€íÊÕmïØÙÆ8[!jHïæC©)íÂ.~ÖË7œ¯ë¿¶‹´¦}ußß)<ÐÔÄB°B÷t, `Wtn"Éé³÷²h1^$´²Ónj6Cûs$55ͦ‡µS” á¾4ÿJóʃ”ê¬í*Û– ­g~÷ËMg§¶³ËÒ¿Œ7œ×¦igˆ~àš¯m¼µe Ð7¶]7#¨ü„¸Çʘ>ê¸6@U’qzÕ׿óo镯º#½Yz‡Õ#Î|¯>¢„ÓOhðwÅM‘ŒB¦™âÙ°(¶/_š~Ÿ ´³Ê^×ɾ‰8­×(M³nQÃÖƒZlÅŽH€Ì°8Ët‚Æ‚g,Í5L‹b¹_\>¸b KNÈ$çôX‰bØá»é<5þ]á.ØÏåIí@”L˜JÓ×i4°éæuç›_$Ô™'O’”tia"àÜwÑç/<v’‡ÃyUO}[†¶qx4 è_Ê”sÔð)Ct£ØÇnül-ô€÷µUíÐt´$£º¡ôõÊ–õìʲ÷m†IÝGÔ'ãqk–îô]ÞûH$+xò?ÿJÔ«6 endstream endobj 606 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 618 0 R /Length 14012 /Filter /FlateDecode >> stream xÚí‡WYÿÿý#¾çw¾«ˆ«R ŠŠ½ˆ"‚ˆ©VÄöº‚’l¨ (®Ýµ" ‚(¢+ëîól÷ë6ÝæV]÷y~¼:;Nf&“@ï9¯“3¹¹sçfr_sïM&ŸéÒ¥eé1~1 ÓåõBëGt`˜òLöqéÿèÀ8§°Žž|÷Hý Ã÷}tR“iØÞÐÑ çYiNÁj%8‡¤R~ÚÊdÀ|M´½š·)öË÷}DB ÷.]^Ò²¢oqwwç6ì¿ð¨ëÂ#ž;?ñ(gÿè#® *€™hMm¯æm’ýò}þN%2ý¿/iYÑ·ò܆}ÂvÛõéÄÌï”ãµó“>á»ÀL´¦‰¶Wó6É~ßð}Óu>ûþzÃ>á»}<6ÚJPÌDkšh{5o“ì÷ñ||5C}ç6TE¤O:ðØPh+A0­i¢íÕ¼M²ß7çï7øÐ”œ››ËÌÜÙüž¹ ]¢öûe= 8?èf ­°"Ø›²Þúw¶ƒ&ÚDõš¨`[™NдÍ[t¿¢–Éì—ïûÈ͵|Èe®ï–yS¬ÿ§GnþsLÎz"@°UÔþ&AÚJP‚¿É³¿þþüñïYW¿ôØvS7g[Â꣛2/ùLûVLªzm_ˆ’Í•4~0á!m¢zaMT°­ŒüF.Ú¼[Sgn/º)2û}Ã÷-·øìûë ûÎËöÏ~ÂÁ²ÑÊìŒ&.‘ƒ¶T€xÝ$Î+÷äßlþ’žæÝúb”Nζ„«?q™úèMŽï¶«m\™»›2¯>üäÛßå«g’÷hÚÍY½ Ñ-Þ/½kzïÆUOÐDš¨nóæ7l~ §GùæÝÊ:sò×ÙÞ¥öû†ï[ëø(ôöé‘Û°ßüœ€ìï9X¶9Mò‰´• ×$"’.±»/ÓÓ§¿þ’T0êõ«;Š>ÿöçgÿ¡óÿÖºÑÛêèégÿã9 þØUü¥ð‹Ú–ûégßýþüÅèÕ”üϸQiê‚Ï>þ¶eÃ/žü‘Vøù¨7ëÀíE°ðóP }·—˵àÐM_<ýåÏþõ÷­O~Zqâ#Ý·¬Éiwv}ñþÃ_h¿>ÿ»æÁ·áÉ—¸šª'U¥‚;Ù[cÙv_ù‚žæ7~'Zˆ›Î}ÜüèWzSß=}F{‘ªƒî‡õïÛËeÊŸžX¬›³üƒž=A‰÷>¥2éhtôMT!¬‰ê6oAÛMmÞ­¯³àPÓ•ì—ïû¨m·ù(ô½J܆®ÑG¦üžƒe››Ù$ŸH[ *@¼þ û%VÐÓ);î0ßãÔÇÇo¯a¯ÖÜû<8õzTÊ¥ùê󻯼Ô=ŒÙYTvûcZÏ*ù÷h^Q÷>þ:|÷¥{Šï~ü5=Ý™ÿ!ÛQjaKS/ÿ›èEù5Òú¾ÂFm­ç6äï…«ÕRõÉù)ç¹ùùïÿü‡ä­þàÛ=–¤]X¤>½P}Æg{%ÿ qÕ“ª’grã§ß<}ñ÷ßkŽ4.z÷Ãÿç㯟Æh/&]Ñ-D”Å-¼áÓâö•Åí¾\zûöII"ÑÃÈ6‘A4ç⹇s«>üòÏçTñÿÔ}ò…ÇPÐDš¨nó´mÑtÑæmRuæL¤ÝéÖD°ß7|ßÞÀÇ`ß_oØ?æØ´Cßs¼Œe6É'ÒV‚ ¯>hía¿¤kþ»î•ÜoÙ°òöƒ•š#“+_uÙûO/H9œT‘’÷ðÉo”²aµ±¸½-öÛïž‘\Â¥=t!Z}&8©h]ÖUzúÕã§&_¥W©»oyY…Ñ)g£w¶Œ"¾~òÓ´ä2nCþ^¸ZE¦\"¨nüzÊõô½ø;õhQ´öbdJ^dJî<õ…±‰u¢ïš-RǤöƒ¯–ïÉ_¤>rŽÜ‰L¾43¹Ð;±†иêÉTiîþ›¿ýñìç_ÿá×gOÿkcF~¬ædHr¡n!º5!¾úñeÛr°8F}¦%§:Þ‘gâM©C$z¥ m\"­‡%çG«Ï®Ûs±ñÁ¯¾ªJª”/J´‰*„5QÝæ-hÛ¢é¢ÍÛ Dë,QªÎo\O›x‡¡¾sXtrÆ¡8^õ}™wåi+AÁ÷u_>ù㽪¯N;¹XsÚ7é:K_«}7ôeS“x‡ÆÉ-)©ÇCÕE~ê–V÷üù_K5§¼’^Í7î8‘’?)©Ú[ÝÈ^]¢9=.©žFø‚÷E½Þõéq‰·t÷Â¥LNªâד¥È¥-üòÙó¿(…ú£¾úuÕ‰SS*&&Ýy×óÕ¯&çñàóo¨*ªîÃG».Þ J½>.±nLb£neXŠL•h«ÜÚÏYbñÍ–iODª &ñŽ-Wˆ(Ô³R¶u;ND$çÑ'26±Þ7©jBR­Ì!’9ŒRˆæ¯¹þ³k<ùãeÿþáç_¿WT§9IŸ¦|iºMT!¬‰ê6oAÛMmÞ¡[çIæ]n]´Î2×Ïìûë ,9˜óŸî ¶b‰—‡¶Ò½f˜û —jNÏ×\$b4çb4çCRJ&$ßä^õO®tOºCù~ß2`NÌ<;%ùZàÞû¬_¥9ê›üjðŸzèb@r¹{RCè-ÝÜãWiNJ®aýTbÆ™XÍ©š Ä í‰Õ©ÇèÌ »—š_r• ž”"S圛zy÷±‚‚ë-äÇ_þôN®½Xz¹ö•ÆàöÂ¥Îßw.÷jý§¾gó÷Š?ê4nC™*EfH'Ò¯ž<ýöÉOýõ"1çŠr•{R£n!¢°’SsréÄå‘Ü(S%‡Q Ýœå~¤é %>xôôp郕û —jOÓ»‹ÑœÕ[šn•iÞül¬‰ênËoÆRé¢ÍÛ ¤êÌy$SgÑëçÇ$ßãÃ÷=!¡‹€.®]ºD¶ÀùÎm80ölP·‘j(È@[ *@¼ú Sß­É'¢4ᚢÀ”rï”zwÞ«þ)Õ,Öµo(¥ºáƒ°]5ço·|iyñêí•Úã“S^ùþà“‡óöÖLÝóAÍ¿ŸÒÓÓÅ7Ù«{J¿¢§M>]–^³«hÇÙ[÷?ûŽ´šœR­»—Ÿ~oé£ÕÙç¹~™¢ª>ú9öÈýpmIâ±–ÉÈãž.Öœ¥I´îR_eo™àöÂáR7C]1[S°Hs~KV~AÕ½GQ—HUOªJiµ_<ù“ÄÙžsE}¸F;tz ÜqS´Qv•<¢lÿúìQôþšÉ;ï¿wë±’C$•"…nÎO¿ûãtåÇë”.ÒÒùÿÜõ…Ùš¼0MÉÔ”J¯”ùÒt›¨Œïü†Êšhk¶m ¢ûe²ë&Jí÷ ßSÞçófÿÞE@‹ì-üãûë Ý–]˜yøG]fÝã#x•¶T€xýAñW×(yu¬æþùªÿðó³¿^|ùýŸGÊÿ½2õäBíy?õ«晢ê‡ßýD-œ^͹ÒLÝ\´æ¢¯º–¶ÍÈ¿óðëÇ¿?ûë·g/n~òtã{B5%¢{I»òè—ßþdé¢5‘*jÍÙÏ›¿üúÓ_ÿ|qÿ‹w»¼2õ„_Ê Ý·¦”»“RniÊçhò©Ù/K=í£®­žT•Šßÿ‘òd_¾³<õT”¶à@AËÈùfóçž)wD e^ã—_=þãÙ_yžZôNDJ‘Þ—Ÿ‡¿p/Åh/,Ô^œ«¹®)ž®©œRï‘rOá¡Óm¢‚Æ)ÚPYmͶ­Aj¿ò‰‚ýò}wW7ó1ÔwnÃAËsCÿh(´• Œ©§Ö¦õ×ÜPøê$M]´&wYê{‹^¶‡š‹Ášò ê×sÀÔ£ó5—¢S/Ekó¥^X˜š¤¹6^}‡6ôQ×ÏÓæÇiiÃóóµyQš¢Yê’Iê:ѽЫ«SÓ^¢µ¹º5‘)*D[±€* Í]˜š·D{–TõSß}kÊñTßóÓÜ¢·é§¾%U=©*…hÊéDAÙ¦jª'hîÌÖ^¦qþíeõ}ÝBDñÑÜž«¡’O/Öž›«ÍŸ¥¹ê­nÐ{ˆ”|¸ŒÚKË›z†ÖYú4Íõ@M%½¯±ê÷ =b­i¢¦mÞmSgŽ7|×|ðo\O+9žç~ç6²ª 0ë›Yïþ¤œÀ¬¯¯º,¬ÀK‚´×fk ý5µ _õÐ|ÐÒŒµå‘Ú+Ú+A©UãÕ”Îù¤­ ÒTDhŠéÕÚªñš;ܶޚÆ@me„¶$R[ª- ÐÖziî‰îe¢¦aVjy”¶ˆKä‘*j‚¦‰:#JÒSKùÇiµÖ [=©*ùko…§–8^š&–g–¶l–öª¶A´Qh+:ÎTr„¶x†¦rüË¢ô"½.?ùüJhM5món›:s¼á»öC“0<þú˜„ê ìoÂŽü¤„àì¯Ç$\_mª ˆòÊ÷´£ÔÂͺ£‰ø¥VÖP¸É›h{5o“ì÷ÍxV™÷Ô#6ß²îʵŊXW2bs‡ö©* ÅŠ´ÓëÒŽNI­3÷Ž:$ÑiùºXEá¦m¢íÕ¼M²ß7|OûwÇ&8­zNÚ•)iõþšïè 0ÕÁ4kဃïûØCו:Ìnï”Þ|÷Næ¿Ö³tì´1LùNå»uIÔ¥K´Rо?üüÓ‰ùž¹gùn-ÖŠÚŒEUÕ|§jä=Õ!±:ß­åÀ¢ªFW¾Ãwëò=~íJTÕèÊÀwøßá;|‡ï¾Ãwø‰à;|‡ïð¾Ãwøßá;|ï ¾w{ëá»ùÊ7èðÂ÷öõ>¬6–Zf­ô]ªáÁwøn¨ïY{wûNœàл—­M·áCoÞ¸¾·¥ïNvNãžúz{qëçOs²·;q8Ûäý»Ì†òцÚq¸¢×÷V¶íŽçûÁý{œìcc¢ßÍÚO­n6ÅÏgBöýJaApàt'{jAӧݸ^I‰Ç{íݳ‹ËSQZÒWÕ§îFuÓíº%1 ]ú8´BOEKfOù äû¤ ã7oXËÖO9dÓõ­“ïdO7­[M¯šc<ßß-¤?Õ[ÕÖ·íŽç{€ŸoÌü9¢/Ñ! ›LGŒ ®¢ƒ°*n‰«‹ŠÎ™ƒöß¡NZ¿jù€~}ßîn3jÄ0:£”Mv/Kû©œYþÌÝ;Lâû¨ÃO}·±þé¼(zÁ¼ÙQ”x4ç üß¿ÓÀòÌ‹ŠLظžVÖ¬\>y’OåÕRbÒDﵫVÈøntÿ¾uÓÆ‰ãDZõÄ„w¨í ÙÓñcÝéU~ûxúø¬ ét²¢Ãµdá|.Ž[Hà4ÝôKgN.œ7§Ÿª}¯žSΞ8"è£[ï;£ízŸ>šÃO¡A ¥ˆî]êÃÕ­•&q˰Án”‡r®]ghUhÛR‡WêXïô¾r2öо4vÄ8÷#Ù™ÄX÷Ñ fGr–·—gNF:½ëEóçôîù¶Ïx/*„=õ=Ò l2{¡‘íáû(ôܨ1#‡›|<_W[ãÚ×…­u³w×Z))* Äƺ›´î6p@aþ%–áò¥‹ƒÜ˜Ã÷ÜÓÇNä´ Ú焇‘ã³ÃfÑúу™ÎŽô*ß²è9‘t¸è%v¸¸ôùQáÆ=v(“ ¸ôØEÑãÜÇädî%û¦úûFΚiŽþN5K¢çqOGÏ  ’ß»è‡+(œË–ëIFê ƒ¦ZU#Ú¶Ôá•z#Vç;u¾çy“G>®}UÒw²u:“܇rüà¶~îÄ‘–§‡þyú¶mwƒ²ÉíE,+}Ï={Æ×g¢£½ëGl»ueéÙ™û‡ tïNCXÈ̤m[XbÏÝïÔ¿ÃÓ =5‡ïu1ËÇЊǨ»´É¬ý/^0—Ò"Ðñá.^ºŠ2Q.Ý­¿ì}¯ÒçdQGiŽù;íºoç‹/OMôHý *¿w©6Ãß—‹³ÓŠ¥‹ŽdgWU#Ú¶Ôá•z#©§qw¸h…žŠ~(ROf3n/FûN}ô®´Ô›ÕU¤6=ryî75ÒPyì·þ®wêY¢TÿNâ³Q]QÎBSoã|ß·+mØ dÊ`·ôtPWêÔºö£tùÃÅO¿ šnÛï&ÕÐLów]ÄoXÓ²ùúÕ46hïRmfï- ìzÑ40yK¼ ûw©V'yx%Þˆ5Îß©1´7¡ïÆíÅhß]TÎYû›n×]-. œÎϳ/}=MÕ¤p)«W,ãæï4* éŒVh>¾ogªüÞ¥>\ÑZÑÜ9ió&šÚ17´mK^©7b•ßÏ;:Ä-ZH––ï0SÕÜw˜ó"ù9ާûhš!šÃwãö¢Ðw”x8;‹Æí¶Ým¸ö¥q;ß÷̽éCÜÜî5ÞæRh ¿(zû~žV¸±=õõ^žÔËS3HIÜβ5a“ƒ]oC¿ŸgÐxž:²wÖ¬¢õ «Vôz»á Þ>MÚ–|ïãèhÌ÷ó¶m©Ã+õF¬ñ÷wz¾Þãíz½MóÆp¿QÒx&48}‡I+çyßœ›ÐwãöbŽëë¦ìݽ³½®¯;q8»»M7j~´N] ­óv|oß«§“ƒÿ d:nÁÓ§²ô…sgÓæ\çHS`š~öènC“…mñ¸/ è7îûy©ßß×®ˆ£š:z~×,ºw©WP+šÐ•ÆØÃ»¥&n5â÷wCÛ¶Ôá•z#¸¾Î¯§}ÿNƒ69‰æïÜOrV}ý|Æî4W®¯Ãõóð]jäïÖß5÷ì«þ¿LxHÐñCØ?Î}LĬ`øßá{þÍ1]œi <=àœØ!ð¾Ãwü¾ÃwøßQUøßá;ª ßá;|‡ïð¾ÃwøÞ–¾ÿ·ã.¸»%–ιЉEÆwÜ\€Ž| “Àæ†ðøß€ï€°pà»iO˜X°Xì·¾›Äwüʃ¥]~YS˜¾Ãw,Àw%¿¾ÁwøŽ¾ÃwøŽÅz}¯»Q=e²/=ZšïR±ÖÛþ®mðKÇðýÞ_Ÿ‰-7ãð™xZ­•¾s‘]ú8G…‡Ö^¯2ÓM­×÷ÿýÿÃ@ƒÄÒf¾/œ?—s“ÖMè;[©,/  ›ßEûwøŽ¥Ìßù†ÖTV8;Ú³u©Û¡?rØ}ÔHn=U,STnEææªê¤D*Š ôòô¸|é"|ÇßÛÞw©Û¡öUõ9°o/ [QZ2/*Rþ¦iÜS™›«MŸzµ¤¸áVíú5«'Œó„ïX:³ïz¯¬3•ïUea3ƒ ùÛ¥õï×r+–ke%Jn’È=•¹¹juE9[o¬»Ù«‡-|ÇÒ™}W˜§õßשœÂCCjª®Éß5÷üYê‘i0ÄÍí݃٠}7ôæªð ÆóæÏó‘ꑹ;¨ædpQ9 ÜUIÿß±`iwߥn‡J~2÷nC=ùÞO¥"¸)*—.U|Ç‚EÔwsÿ'@êv¨{÷ì6x ÈÝGЦËäçk÷—„ïX:Éx^&]QÿžIIÿÎ/Öï/ ß±Àw™>úûNbówZá&Ú oi÷—„ïX,Á÷6¾_¤ ]æ†ìûyG{;ª÷EºÂDZàý%q¿H,–à»eÞ/Ò@ÇõuX:ÆxÞ¯§…ïX°XÑü¾Ãw,ðÿ¾Ãw,XÌç;îÙ.¾ã8‹¾›Öwt4X,|ï þ<|¾à;¾à;¾[õ÷‹ìT'L,Xp¿H\O‹‹Y¯§U˜¾Ãw,ø¿ |‡ïXà{§ºe |Çb¾[Åý"á;,­÷ÝÜ÷‹´éú–Kç°™Á•WKá;÷”•–L™lkÓÕµ¯*vé’ï¾ûÍKønîø´ïßi¨ª(‹[²ÈÛk|ç>‚éS /üüÓO¿üòKZªvÆ´©h–X¬wþ.Г& ÜMš”Üó‘žÞm¨Y0ÏÉÁž²%¼³‘Ù°v[WG{»9‘ ·jE7·¢ñü¯¿þÚ³Gw4K,ÀwÒ³º¢|y\¬÷x–¢ðžëV¯|uËÈ—Ù¸·&lòó™Xv¥èVÍõˆÐY±‹‰nn-¾ÿöÛo{vï A³Äb>ßÛà~‘|¨/.ÌËmÖwS'þ=)Ÿó}ØAÅ—óÙzõµò®ýD7· ßÙ&\ú8}úé§h–XÌç»Â<&Ï×T][½b™¯ÏDöTá=Ù¸i^À?“tïÖUtskéߟ>}ªÕ¨§øû¡Ybé0ó÷úÚnþ®ð¦üþÆÿôïƒ]-)¶º/ôdæï¤|¯·mÑ,±t ßk¯WÑœÝËÓƒ=UxÓFJçnIù¹W·oI §Eùywê r/„[£ïK/ú׿>zþüù£Gÿ·aý:Ìß±´ïæû=ŽÃÉÁ~ÆÔ€²¢Bnp®ä¦M·ë¢çÍ¡‰¿ÊÙIðý|Ò¶-4‹Û¶û¨ó3÷[£ïy—.yzŒ¡ÉÈÀþ®«W­üñÇÐ,±´ï–y¿H\?‹™ÆóVq=-|Ç‚Åbçï¾cïð øß±`1Ÿï¸_d»øŽã,ønZßÑÑ`±ð¾€øóðø€ïø€ïø€ïøè0¾[{Pzà;| øŽ›LЩ|g+¸ÉÇwn2@'éßq“):Éü7™ ƒùΖÃ2´ïM¦¨z£úÐ Ñõ×8ßq3Úý&S`‚‹`1­ïRöá&SXÈÐÝ|¾ã&Stßðßðßðßfõ]p ½øè¾ë½À¾ß#á¶ÝºÒ£Ìuõ¸À÷6ö=-U[SSmZßß¿Ó0h@ÿ¤m[Ü uø€%ø¾7}OLô‚'OžHùÞòϸ×–ß•ªåþ"GéÑóæìЪ¹œiÚJaë9Ù+8èPVFó˘64n_K´Î6¹Z\H9Ù_íè‘ÖË®ÁwÚÞ÷éSì{÷ŒßôNTdÄùsgõ~_wûæ®}ieÔˆá4J?ΓÖ)… M¹vÕ ÚpKü&n“eK ~æ[»¾Ð.ãù‡¿œHÖ?{öLÉ÷ó>ÞhÐîéáNëô˜¹ÒDoöRþÅó®}]²2ö¹º¨J‹.s:?è uî\wßhûùû‹/ö¦ïQø{äIç¤m[h=qëf<þ ´N]ƒ€ïVç»òÌz_¾›Ãw#âUÂw¬Ôw#âUÂw¬Ôw#âU¶rþß|o/߈W‰þëý¾Î x•ð«öÝ x•ð«öÝ x•Í¥„ï¾ãú:à;®Ÿ¾ë-ßðßðßðøß€ï¸ÞøŽëi€ïí¿Žáìh?mŠIQîÿ_ª+ÊcÌsëïjÛÝÆÑÞnÊdßÃÙY2“A(Kß-<^eíõª5+—÷+H¯,/èÚ/nÉ¢¢ü¼Æú[”-'+ÓßÏW¯ïRO€ï&ñ½•ñ*ëkkzõ°H:72rå²8½§ øà»Å«¼YÝÒ¿³À8üô¾ª>W à;€ï–æ»qñ*9Hí«%ÅImmº±H8‚üò?%ÀwßÍí»Ññ*ï75–z{ËÊØ'ÔEå¬Û¿ËG¼ï¾[~¼ÊŠÒ²›Í¸ô¨ˆ0Àwß-Ð÷VÆ«œ4C“œÈO//½ÒO¥â¾Ÿ¿Us='+¾øn¥ñ*ù›=|Ècô(Ý~nd$YO¥9;ÚMŸvöôIøà;®¯¾ãúyà;þ|Àw|Àw|Àw|¾ãzà;®§¾[šï2Æ˗.øûÙõêIÐJAîÝ­\ú8G…‡Ö^¯B{ðÝŠúwAi¥E—UNŽ[6UW”Ûâé©î_æ+ËËB‚Ãf… =ønñ*E} Y·z%?eíª¡³t3×TV8;Ú£=ønñ*E}§zYQ!?…žº¨œá;€ï–ã»ñ*E}·íÖõN}?¥±þ–­M7A檊²°™ÁÚ€ïV¯RÔw•³“|ÿΠl4òg±t€ï–¯RÔ÷°™ºówR[43ðÝZâUŠ*\|9¿£Ã¶„xîûyzÊE¥†ï¾7[g¼J)… r/L™ìÛ»çÛ„¿Ÿ/+¾øŽëë€ï¸~ø®·|Àw|Àw|Àwà;|¾ãzà;®§¾·¯ïÜhÁ¦ë[.}œÃfW^-å^•ŠZ©p¢0ú刡Cî75r)´>|è`œÐ|7‡ïlåý; UeqKy{c)òQ+›Ë$ê~éá>šEàadeì§øà»ÉãU Ê©»QÝ«‡-[—Z©Üw½Ñ/3Ò÷LxЇáå鑹7¾ønòx•üþ:ßåq±>ÞãYŠ|ÔJå¾ë~I»âævöÔ zzêØZ§øà»ÉãU ¦ÛŽövÜA>j¥rß•D¿Ô&'͘@+þ~¾,.|ðÝäñ*ß.]umõŠe¾>ÙSù¨•Ê}×ý’›n×õUõÙ»{'=Ò:|ðÝñ*åЀ›¿ËG­Tî»Âè—ñ×S§O#™’€ï| WÉ/§özÕš•˽<=ØSù¨•Ê}7.ú%|ðÝäñ*ù“w'{šDóÇÞ2Q+•ûÞlTôKøà;®¯×Ïðÿ8|Àw|¾Ãwà;|¾Ãw:¹ïËÇ$¾ÿ ,V²´Þw€õòá;ð¾ßðßðßðßðÐÆ¾#F%Ðwˆ@Gò=á¶ÝºÒ£Uôï8ÿøn´ïïßi4 Ò¶-nÐ:| ûž“}Àcô(Zë>æpv–Ìx¾év]ô¼9Nö.}œãßÙÀÏ NJèÚ¯gî^ž—/]äÒS·ÓɤGw›ƾwòøN­fˆ›ËV\Ïp6¬]ãÖßÕÑÞnNdw{YÑbq ß[ãûÔ)“whÕ´B2ÒºŒïkV.ð÷«ª(#ü}'ñ3MŸzµ¤˜T]¿fõ„—7†féÓ¦ø—Rú;ë×Ú÷î5cjÀÕâWO}¼Ç³l[6ùùL,»Rt«æzDè¬ØÅ‹ô‹OÀw#|'ûTNŽwê[îN´NÞIùN~®S.Ì¿ÄÏP]QÎÖënr·x¦ôëW¹t©lÆ *¾üªØêkåÔ¡ë-Ÿ>€ïůc–-],¸OÜòØ%R¾Ó¸š†ôlNR_àëM<%‘ùèÞ­«òbé] Ö@ü:™ø´\t,Ö¡Ó€™Ë@;×ÝÔ¿·Æ÷aƒñë 7¿M×·øét†¥ƒ-fŠGMöiSyh†¾+U+ªíêËþ™¿ûùšÊ÷í[&Oò)ÊÏ»ÛP_{!48X>?‘(3x ÝÍệûèwf òÊÊë>FT[ê÷çÏího§rvÚ°vmw“øþþ†¤m[hÿ¶m÷Q#†ggî—Ï¿5a“ƒ]oÌâ|o³ûMPGt0M7äçï‘a˜¿ø.ç;äIgö5xâÖÍ$xü;Ø÷ÞÔéŸ>~¬ùe ÷Q#ëoÉøN~껹@Ö´â6p@ÝjßçaPÝ¢"Ât}o¬»yé¹%1 ñý<€ïz}Ï»xÞÖ¦`×TVÐ:uë-¿ž‡‡Ò°œË¶-!~Nd„Ìü=8pú¼ÙQü’—Çņ…Ì”ñ]ap¸Øïïv½zŽ9bEìRª<š€ï¸¾\?Àÿãðßðøß€ïðøß€ï\oƒëmÀõ´ðønR&usò«+ÊcÌsëïjÛÝÆÑÞnÊd_.€•|tJQ¸q‹³£ý´)þ%E†îQª¶øÎ!aRÆ÷Êò²®ýâ–,*ÊÏk¬¿U{½*'+“ý_¾Y_tJ)ßÙ µfåòñžc Ý£üÙIo°.߈WÙ,aRÆ ¹‘‘\X*Ñl2Ñ)å}'êkkzõ°5tðt*߈WÙ¬/¤”A}U}®ÈÛ'R^Ø›Õ-ý; Ñcèá;è<¾¯RI„IQelmº±9‚Ù· ›htJùù;AjsÁm”ïQï<¾ƒŽä»ñ*•D˜UÆEå¬ÛÛêú.R¦ƒ¾ßÔXVTèí5.+cŸq{Dÿ:Ï÷uÅ«TaRW™¨ˆ0*(±O7:¥Þ9 >Ïæ#F쾃Nâ»Añ* Š0)P¦¼ôJ?•Šû¶üVÍõœ¬L)ûÑ)•LÀgÍÐ$'½Gø:ƒïÅ«ÔaRw.,è…çFF’ƒ´gGû éÓΞ>)j– :¥ß>Ä~50nðà÷w®Ÿàÿqæç.ßðßðßðß¸ÞøŽëi€ïˆW©üï*ܸŦë[.}œÃfW^-å^½|éb€¿Ÿ]¯ž­ä^0h,ÄíZªVÔˆ¡Cøu¦õáCãÔ ¯Ò|ñ*©UeT²·×8–RZtYåä¸5aaˆm ñô”ý…_ùÙIo9”ÙÃ}4‹ÄÈÊØO)ð ^¥YãU´9²2<4dÝê•üW×®Z:ËPßåË¡Ìé{&¼ ÄðòôÈÜ›ßâUš/^%õïÔù.‹õñÏRhx_VTÈÏLO]TΆú._e¦]qs;{ê«<­S |ˆWiÖx•„£½7V±íÖ•ÕƒvM0ÔwùrXfmrÒŒ©´Bs!¾Ä«4S¼JFMÕµÕ+–ùúLdOUÎN&éßåËa™›n×ÑÐeïîôHëð4#^¥™ãU6¿yˉ°™ºónšŒê»|9\æøë©Ó§1’’a €ïˆWÙÊx•ì–R^žìiñåü>ŽÛâ¹ïÕé©`t¡Äwùr¤ªßâU6›!^%‡“ƒ=M¢ùcï‚Ü S&ûöîù6AE±7e¨ïòåÀw€ëë¸~øŽÿÇéç.ßðßðßðß¸ÞøŽëi€ïˆWiÐOŠ òƒfLwr°ïÑÝÆÃ}tæÞt©Þ½HˆdŠb8;ÚO›â_RT ‰ |¢|TLÑq›Ût}‹Þ~¯·{8Øõ¦<.*gö$……z@ úôá{ðÝBâURËwéã¼%~SEiIÓíºóï œ.¿¡’½È?ÕMgÅï9ÖhßõFÅÝ‘TÅHÞ¹‘‘»w¤),ÜÐbЧß-Êw«ŽW6+d㺵ÊýR¸C}o~3Ô†¾ëŠ)º#©ŠÅDÏOܺ™{ª·pCˆAŸ>|·(ß­:^%uîW‹ õ]ï^ õýfuK·Ëç»Þ¨˜¢;-sy\ìºÕ«GIoáƒ>}ønQ¾[u¼J*PLRæ å{Ñ}*?'èTÆñ¥¤>ü¢ôFÅÝ‘îÁÙ°vÍâ…Ñ£¤ ä¦òbè§ß-Êw«ŽWitÿ.¿ƒúwš,Swéí5.+cŸÑý»’¨˜º;”¹msBTx¨à›7……+? †~úðÝÒ¾¯³Þx•4ß´aq¾Ëìňù{Ei ÄfCFø®0*¦`GüôÔ”äÀiSï5Þ9JŠ ×{@Œøôụùn½ñ*[¾ŸW9oKˆ¯¼ZÚt»î™ÓJ¾Ÿ×»#|'fÍÐ$'ç»AQ1¹qéé;wøùL”šÚT¸ü1âÓ‡ï–æ»õÆ«$èÔA…8ØõîÑ݆ê ä÷w½{Q>çg;zøûÖÚ¸ßß•GÅävÄÿbDþrJå…Ë#>}øŽëë€ï¸~øŽÿÇYѹ §Y߀ïðøß€ïðø€ïøÀõ6\O èä¾#^¥Âx•W [þħû絺Õ£F ¿UsÝ òe*©÷˜úÁøÎ@¼ÊfCâUÎ šÁ‚†ñ‰ß¸~Þì(£Ë—ª¤Ì1iF¨ÉNï;âU6›?^eîù³ƒÝòýºÛPïÚ×…ý ݸò¥*)sLšj²ÓûŽx•Ím¯ÒßwRFúî)ZiÈÝšò¥*)sLšj²ÓûŽx•Ím¯’Î0,(ƒfîΜnMùRu–9&5 ߯²¹MâU^ž'¾K+GsúxOheùFôï5 ß›¯²MâU²¡Ô”É-_NNžäsäÐÁV–/3=&5 ß_ý@ƒx•æWÉzê‘ÇíÞ‘6zäˆÖ—/÷ý¼Ø1A¨IøÎ@¼Ê6ˆWÉØ³3Þxúέ/_¦Î¢Ç¡&á;×Ïðÿ¸öñ*|Àw|Àw|Àw|àzà;®§¾[¾ïu7ªWÄÅqsëÕÃÖÑÞ.pÚÔãG‹þ‰C4Q*^"Ã¥sTxhíõ*½ÿ%!lº¾åлט‘#–ÇŲÿûßM뻿Ÿï¼9Q%Ewêɲýé»}¼Ç+ô]o¼ÄÊò²àÀ°Y!2òÓnÕ^ºpnñÂè~*•|„à»ñ*©[§.^^C©D%ñk*+œíúαfåòˆÐYhf¾›6^e€¿ß¬à 3§NðƒÑ)ô]I¼Dã|g`ÐÌ|7m¼ÊºÚêLGѳGw–/[º˜ëîåP/±ª¢,lf0¡wþ.x#t.²ínƒfà»iãUrÜoj¤‘TDØ´)þJúwùx‰ •³Sxh÷å›Aý{_U43ßM¯Rôëzšèõݸx‰Íß#Ã0ðÝ”ñ*_žÆÓù†÷4„&gÌC3z½¾/QozcÝÍKÎ-‰Yˆïç|7y¼JZ9qäpÐôiŽöv4§y}Lôü›ÕUz}×/QÊkùßßízõ=rÄŠØ¥Ts´1ßq}¸~€ÿÇà;¾à;ð¾ßá;ð¾ßq<Àõ6¸Þ\O‹ëi€ïF#vR*Œ¤L´ ~¢T|è`Ý:Њ¿Ÿ/?§’ÊðóÐûíÑݦ×Û=ìz;;Ú»¨œû©T¶6Ýšeÿò໵ø®7ì¤hI…¾ËÄÔÙ\·4÷Ñ,J#+c?¥ˆú2“ýØ ÊHUƒNs##wïHS^[ß-6^e³²°“ ~I…¾ËÄÃ4È÷Œô=^†ëaxyzdîMõv7lð â‚|ƒ*#U˜èù‰[7T[ß-6^e³²°“ ~I…¾ËÄÃ4ÈwxÐ8üì©ôôÔ±#´N)¢¾³ ÔûsoPIeD«AS˜u«WZ[ß-6^¥’°“ü0’JçïÒñ0 òµÉI3¦°a9‹Ý!å{‹ª±KV.‹S^ÝjlX»†¦0z: ðÝŠâUʇÔíß¹0’Ü«thº]ÇÏFçîݺêN„ñ0 õöB{ß»{'=²=ÊøNã™±cF½wò¸è.ôçܶ9!*ÿÞ)~¶s§O¹õw­?¦¡¾ñ×ÛÚt£Ñ‹”æüÒ ó/QÝhR#µ ©àœ4xœ6õ^ãmãf¾[f¼J…a'EÃHr¯&oßF%Ÿ:v”FËÍGÆý´'Óߥҥ&t¨ç•çLß¹ÃÏg";ãÁw`ᾯRoØI™0’\hÐKç *ÊÁ®7A+»ÒR¹l2ñ0ÛÀwªMö¹D%Á9éˆÉ\€ù;|ï„××ÑHØÉÁÍÀ÷ýü݆zš#øûNB3ð½Ãÿ?ζ»ÍØ1£._ºhò’ñ· ßðßðßð߀ï͈W |G¼Jà»eø.õ¯¶6;2œŸŸŸ"ÿ§©@—RÕ@DJßÛÀw™Äƺ›¤!÷·TMÊÈáÃ(QfÛf}.¥6ADJßͯRÞ÷æ—Q#TNŽEùy¹hE4¤Þs?Ð¥Ô&ˆH ໹ãUêõ½ùeËÆ’bé;w(1H>Ð¥Ô&ˆH ໹ãUÊÏßUe£GÑÀ^§Nfþ.¨?Ð¥Ì))|7k¼J%ýûô€€£9IÀØÅ‹Œîß¹@—2› "%€ïæ‹W©ÄwÃSoË òöwâõ×݆Îß¹@—ò› "%€ïfŠW©×wö«œ¸Ð´Bƒd™²î×ûº. ú2 )|7U¼J½¾NŸ7;JðWXÈL…¿¿‹º4­ïˆH ðû;×Ïðÿ¸6'.ßq<€ïø€ïø€ï€6ö`ù˜Ä÷ÿbÁ‚ÅJ–Öû°ÞA>|¾Ãwà;¾à;¾à;¾à;¾à;ð¾ßqˆ€ïø€ïË÷AèHÈøÞ ,nõ)è`0»u}tTø¾Ó: cC²ÓðžYèØìÿS#À endstream endobj 618 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 1935 /Filter /FlateDecode >> stream xÚíÚkl•åð åª2)·" A£‹c²¸/ŒnÉ"(,8ÊM·™º©€(0m‹³è2åVÔ¹ ‡‚ˆ|³¡Ó-€ h‘–»Ppïûšž*h]çœü~É“óÜÏ{ž¾çžçôD|L³‰°œÍ» –¾|a šu9›QË/2(??? ;ÆFŠ›GŽÊÕoß±#*,ˆ ÞˆÇGÿþýcÊ”ÉÑá¼ó²öãIÝïžz*^Z¹2>øàp6~ØCÍ¿qÓæ˜>}z >,†ÜpC|ôÑGQZVk^]-[¶Œ¡C‡ÄãWÄ‹z!ëíu×Gñ˜1QùÌ3Q[[+^XžùMÒç•5k²> ˆßþ£(((È©_¯a]šŸ4qb,^¼8öîÛ½{÷Ž;&OŽ^½zeíÇŽ‹²òòXýÊšìšn:4hìðáÃQµýŸ¹ò{ÛÞÍåßÝòNöØ»ïeñÎÆdùúÇzÍUNŸšÛ  'NœˆýûöDz瞋K/»4WϽ¿ŒñÅccÚÔ©q, `O<ùÛ¨¨Xw$A4µxÉÒxóooÅÌûˆsÏ;7 ¦§Z·n]<8û¡,ð~ûšk²º§.Œ]ï¿óËK³ò¬Y³{ãÍ7cÞ܇³À^?fÛ¶mñȼ¹Yù™³bá¢EqËèÑŸûu¾þúú˜9sF|£C‡¨\öLÌ™;/šý`֖ε}ûŽ(/K®)ùPKç§±víÚeÁëСqpÿ(º Grïì£Gë¢K×¢\¿ú Ú0Ð5wš[~S:§»²4]÷ÝïÅMÉîqùòå1±¤$×^^úhôë×/Z·jíÛ·[oýa¼¶~}®ýÅ—^Š ãÇEQ÷¢8çœs¢xìØ“æþù?ÄÃsæÅ½÷Ü ž©U«_Iv˜c³à˜¦ââ±®mܸâ\ð¬“ÖuêÔ)K%I~ÕêÕMZœI&F·®]£M›61|رyóæ\ÛÊ—_þdþÂÂÜüœa'šœ8Ú¶kŸå$»ÒvmÛ[ήhÃ#ï¾ýûã¹dúHiY̸ÿ¾¬nÓÆMñXEEh:”ÕµÈÿwŒ®©ÙÝ»_pÚù+Ÿ}6}ûö=©~OmMtëÖ5W.êVÔhl—ÎiØ/}ÞÚšš&-ÎùÏÏå[·nG?ü0WNç:u~;õH]»{WöøÁ¡ƒ±«zgõ¸(Û¥Â×~ÚPz¬1|xüýí·su÷&tð Añ䂊xaùcÙÒ%q<9î×ëÜ©Kìܹã´sÎNŽË¯®]K–VžTß±°STWïÊ•«ª«ÍËËk4¦a¿ôy “b½V­ ’cäÑ\yïž½Mzýé\ 篪ÚénúéºWï>‘ߢE–ïѳW$kŸæÓ$xrVÐÆÒÊʸ¸÷Źººººì ‘ywïÚÍ™sòW׊_?ZÕUUÙ5ý'LCéQøÁY3bÅŠ±hñâ\ýwˆ²ùåQ»§6Keåó?óúÒ1¥Éî¸&Ù)¦éѲò¤n`®½Ï%}’ë_–]sUuu<5×þÓ)wDEr„ÿþ¡ñ³iӢߕWž4~İaqÅå—Çɘ[n½-9vwi¼³ëX³f̈•«VÅSO/ÌêF“#úOÆǸñâ›W\-ZžùÛ‡tÌ…^%'e©çEÅÈ›GæÚ'Oš¯­-†S§N‹«¯¾ºI 7jäÈ(*êcÆÇø’ qÕUW¹«O@ëG›¶m>É=’äí:ùÏ]~eÿ&•ÿòz.ùxÀè_Å{5»ãðû[âÏ÷ Ž·ßøëWzá¶nÝÓqw<ùÄ‚¯õ ’~PmßYõ¹û÷è^Ôè§Y_¦µkVGñ¤;ã­ ñî& `§‹%gjûÜó§?êüý€?“€ÿ1_Ò}åþ"'¹¾ bÊ%7 LS}]ÏÁ%K’$IgNi¼Ü׫ ÚL÷Ygƒ–ŸV¹vÍj+ÐÔš——gUš@Ûu¹8¾u׋VàS¤1òŒ;ÐS;ð;Ъu•VN‘o P@@@P@@ÿü ấÀ endstream endobj 623 0 obj << /Length 667 /Filter /FlateDecode >> stream xÚTKSÛ0¾ûWèhÏ4Š–mõØ)0p¢ÓÌô”XØšñ#XßÕý4íZ»ß·ûí*5ˆ «äÇ&Y_–I, V Í#.$G¥„³¤hS£»ôørÕ©Zg+&HÚ«á ºìas³¾¬ª ³à.3¯®h¸>‰qˆ/«t.\Jr±Iž 1Ñw.Häíúäî înÁ¹¬ÐÑGöHP‚/ÀîÐïäWBbýÿ:Z \‰¸¤˜P=&ðc!äÄö—L‡—‹åóúº§ýù×'ŽÕB²:aù,,h\q!±™¼H—¦9LQXŽiþ=[qJÒ?YNRS7zW·Ó¸×Ól´õ"~ìJs(…3Lr°7-sÂSë`œ1>Æs?›q°ÁéÕk0TgGgåé6&>ÌÍÝØï;Q‘¾„fç¼°ì”Õç4Gß]âT¬¢U#é³ÃŠ *Ð6“^bj +vÖë¹ë¦†:ûwa¼O±‡]ü\ ÑŠR,EÔ¥™ŒÃqºzgÌ“ŽSx6:c"=Z€¢8ŒãzˆQ­‰‰®ÙoÁ<{¾…î58Ö€fæÖKÛ ÆAÝ;mãW×¢;kmM3˜¡ îã8õŸ ^ì4Á¥~§ 3ÎqåÞŸëŒã‹³t·¢°ßéųÜ$ÜK¼œþN7𡦸UÖ YŽyqºL¬”PÕaš3š¶ÁÕÖéPé z]†{ÆøE0°‚—‡àÎØ¥ˆyÁ{[÷ÕKÿ–èԗʼnÀÑèAOjö‚B¶¾H W- ·ó=½Û%#¹5CQb1_ÂÀ₵:]§"(£êZÇ-z§Çéq>½¯þûr†%Éÿç¯ï/¼ÿkÅ endstream endobj 612 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 627 0 R /Length 14282 /Filter /FlateDecode >> stream xÚí‡[×÷ý3ÞH1*;XPi*"‚€( ˆ€ ‚`Fˆ"mìK° iÒ¤‚ H±“÷¦çMrS½÷¦çÞ÷‡GOÆÙÝÙÂâ²ËwžÏÃ3{fæÌ™Ùó™sÎìÌaÃú¦^&̰ÍGžý `Â0å™ì³ü?€ cšÁzòÝ#ëÿL¡ï®i=úa_ç„õìóíB35Á>,‹Ö§­ôV®Šªzëc¿Bß§'·q6,ù}3ê&www¾á„µgǯ͟uࣹ9ßh­9!&üÚs¢0@ô§Šªzëe¿Bß]ÞlB¦ÿï}3ê&RžoèqhöÁæÿFsæøÐaÙAQ úSE U½õ²ß—|ß}[ˆÖ¾¿ØÐaÙ!ŸO´…¶€¢?UÔPÕ[/û}©?ŸÔ,D[ßù†Ž‘GæŸx¢-´•¨ ý©¢†ªÞzÙïËã÷;BhHÎÇæ#w6¾§¿|Ã1ÑÇür¿!º>(®@[‰ `D°ƒ2Þòµ“¦´Šª…UQѶ ~«·Òý*µLb¿Bßg¼Õ*„\æm·ÄA±öŸþò Ç®8± ÷[¢­¢õˆV ­D „›üöÇ_Ÿ<ù9·î3”6Å5_%¬<Š)«Ò/¶`ªŠ÷ê3ÑdsMNš°èñ)­¢jaUT´­„ÂJ®´z÷§Ì|/Š)û}É÷=w…híû‹ Ç®ÊóÏû–ÃV£™å9=žÈ¡­D ^T‰+ÄæÃem½ŸÑÇÒ»ŸÎTXóUÂK%LÜ”yv›ì´oJÝ+.ÌâC=Çë>ÿð럥‹§—cÔïælµ'2QÌŽ—ŽšŽ]·â‰ª¨†°*ªX½…[XÃé¯tõîg™¹ƒÂy¶wUû}É÷½íB4ôõöé/ßpÜêÓyßqØj+rz¤i+Q^%"Ó®q‡nÐǧÿþ9,­|æ‹¥û+?ùú§ßþK×ÿ½í®)íôñã'?ÿò;u~9Xõ)¥³J)þèão~þýÏÿÒÒŒ²ùŽ(·Ìò?øºoÃO¿ý%»â“™/—ïE4 סúî«—ÈjÍ©w{>}ú¯_ÿüõ¿î~øcâ…÷YCdw¨üôáçÿ¢ýþúû_-¿^–^ÂK"*žª"•w?a‡ÆV;Tý)},ëúFi&ªØ}õƒÞ/þMõÍÓßh/ªÊ øeýíû¾z‰ü¥V)®Yÿî÷¿ýþ'%>úü)åIgC«³'ª¢ª¨bõÕm¥éJ«wÿË,:Õ´GQaDûú>3åž }gKé/ßp|Lþ“ßqØj+÷H'ÒV¢/¾è3~© ô1`7ó=>ó¼×¾¶´åÁ'¡Y·£3JVg^;Tý¬Ðþùº•µ÷> ùÜš¸ ²zðÁWËÝÙx¸êþ_ÑÇeï±eUôUõú‡ÿŒÙ_YÖòÍ¿]ñþ̽|Cá^x©6f^\q¯Ãæ%²úâû_ûêüÕŽuY¥™šº>øf^êmÅ£–&µôãöúë¿ÿ%y›ßýúðõÎØì¢õ™…k3/ûìkž4^V¸&ãjhZEdFéçßþ‡Rv+¥:´¯Ò~ýÝO‹ÓkxVòSE1™—CÓ*wäÖÑÇ/Ÿü°0½Ž–Rsßw¹1Wbôõ"¾úöÇ ôZ¾¡p/¼TQ%•MXN‰¬žþòçþ•u¶2F~=*£4*£xUf‘gj»Ò£f“ªsÒúî— ‡ËÖg^ŽÉ¸JîD¥—,I¯ðNmž4^<‰"­<ÖöŸ_~ûéß?ÿïßžþüÇ®œ²8ÙŰô ÅLKB|ùÃo´Úž“Uë2/÷­™YJG4+µMÕ)RzUe®´ðDšH/‹É¼²ãðõ®ÇŸ>¿U•Ö(•Ò*ª!¬Š*VoQÝVš®´zk…Ò2‹dTUfÎKÏÓ¦v ÑÖw¾áÄõŸúžó¼í;~_:‘¶€ݯûìÛ_.5ýcköÅ ²Bß´Û,}»ü¥Ïªº[j7õ“ûR²Î/ͬôËì«u¿ÿþÇFYÁœ´ç£Å]ûÏEf”ÍOköÎìbKce…³Ó:¨‡/:.jõb3 g§ÞUÜ OYÖ$,'K‘ÈJ^ñÙo¿ÿA)Ô½ÿå¿·\x¼0£a^Ú‰£^Y$Zš^öéãOþI9PVíï}qðzwHÖíÙ©ín©]Š…a)E¢­Š[?a‰Umïo’_ˆÊ,Ÿ/8·<¥PËJ«íØ!2½”¾ÏÔß´¦¹i­§Hâ4ªBéš^²ûI×>¾õî·¿¯´Ì‰ççµöýņc ƒO/d͉û¢­X"Áס­Ÿæ_ôFYájÙubìê:Ùµ°Œš¹ém|©z£{Z7­ÿùw}æÔãWÒo}ÄÚ÷-²³¾éÏ;ÿY§®¦×»§u.=ñ¸¯™{òÃùÙùé-¬J͹'+X#+"å¶f£+ƒâ^þ®~éM¢rRŠDV´æÊ¬‡Î•—ßî;!?üëWïôV¥K'È/Pn ¾NtfYÒÛW‹ë:>úâ;6~oxüƒâIãJ)*ï=º~ùíÓ¯¿ýñ?þL=]íŸÞäžÖ¥˜‰RXÎY§‹éÂå‘Þ%QMN£*׬ü g(ññOÏÜ|¼ùíŠòB:ºu²+jsS¬¢Õ[¸«¢ŠÛ «±ªt¥Õ[+T•™{$Qf¥ÏÏ»¥?"ô=9y˜ˆa㇠‹êƒûÎ7œw%äô÷"D§‘J(Z¶€xþEg½³\VFDËÊ—É*ƒ3ê½3:ÜKý3šÙú¹·þI)ÍïFl¹v¯ï¦åõº{›åçd<÷ýñ‡Ÿ¯:Ú²ðð»-ÿxJ «ÚØÒÃ7¿¤=?Út¤rÝÁÊýWî>úøÒjAF³â^~ü¹¯ÎÌ»ÆS„ëHdÕôþOqù–ÉkRÏõ Fž|ÿtƒì ¢<$³Ž2Á÷ÂñÎh_œÙ°\V¾^vmOnYyÓƒ/žü–Y£ªxªŠœÝúé·¿’8ûNWgž© Þ]ƒ÷·)ÍD)k¾ ÕþïÇ_ÄkYpàÑ¥»O49EªRT¡¸æGßüRØøÁ'n®—ÓõÿêšÌ¢å²ÒYÍÂŒÆ9Ò¹)VQ ß…•UÑþlÛ”î—É®˜¨j¿/ùžñPÈËíû0}²7ôñ·ï/6tÚT´äÌЬÍ} D´”¶€xñEçûg¶h²ÔSöèZÓûO¾ÿé·?þüì»_óëÿ±9ëâZù5¿Ìç=Ì˕͟ó#ÕpZzºº—š¹ÙußÌVÚ6§¬ûó¯žüüÛÿùí϶Ÿîºôx©¬Fé^²«¿ø×~eéJK¢*«mW>éýì{jOÿýëŸ>ýáй›³.øeÜQ<4Mðȸ??ãnˆ¬~…¬Œªý¦¬BŸÌv¥ÅSU¤ª‡?Ð:y7º² ¢åå'ÊûzÎm½ŸÌÊèVš‰RŽ•v}öå“_~ûãÉ¿~Ϫüœ.Dšœ"µ_®páÄ­“­•__)+Y&«Z$kœ›Ñá‘ñ@ÃS§XEE•SiEeU´?ÛöUû•NíWè»{f¯m}ç:'‡ùA[h+Q‰YÛ³ÎúËîh¸t¾¬=FV¼)ëÒúgõaìz¨¬~næ‹1`ÖÙÕ²’˜¬’yéú¬¢µYÅ!²[^™Ý´¡OfÇ*yY¼œ6¼¶Z^-« Ϭ™ŸÙ®t/´tkÖyÚKŒ¼X±$Y…ÉÖPäÅk³JcåWHU¿Ì6¥‡¦9³2øÉîÒaúeÞUU-êy¿³cÝšUv6Öcì“ßÜÅÓ©‡³jKOzs'OØÝ¹sû6§ ãm­­VDEvÞme¹qtð}´§j+@ÿë¶éùèç»nõ ¥‹èE, ¥3FÐ }ä'aK|ìø1ŽtÍtž4afÚ[&Žûº…ùÌéÓ芪Õj’{Ù8ÎÑž­üÐ~½øžwì0}étÁ·ùº¯·×ÅwNR¢ÇÌéIolåëPõ°·³¹|ö´DÙw$ÝäIøþ ³c¬£CKcÍ'ÆÇ‘ã‰qi¾±¾vŒ£=-ú¾cëæó}hQcÝÍùó¼yú¶Í þ~M µåÀÓ÷&ïöó™W[]y·åväÒð¸ ëûß¾‹R òOÙZ.<{Z˜bgcE)%—/®]µbœ£ƒõ¨‘ÁW.äK|¹Š'P–ºgÚd'Z‡ÖÜž¯mСn_/<²ˆª¥Ç®]ÍK¢ê@ŒÎw:®Ó9G•.Z½z¸ÎÐj5‰½øzÏ9sâmZ?fe´Û ½ø>ÅiRVêÞkÏ’ÎKC‚C‚)1cï[ÎÆÓwÊÖ Y³JºlJw¤[ûNÄ®[›òV2ÍÌóšs¥ðâÜÙ³h~÷Δ.ÒÓÙibEY ›¿Qr§;MšXU^Ææiž>mŠsÕçéÍ·ê'§w߉°à vÆbV. ¡™¸õ1³ÝÝN?Jî/ô÷ _"ýåŠ2§«îž]oŒt¦/EÛ  CÝŽYEégO>OçåQu Fç;5¾×^\ÜDŒëxâÈ6OWàñcÇð/åüÉlþê…ü¾§þþøº¥…V«IíEÙúzìÏ_:wfŒ½-›Ÿ>mÊî[X'¯>»€K”M¿¾—^¿æ6c:õÕg¸L£4Ò¤þù´ÉΔ.Òsä‹îŽv~7O˜Îoú ÓG°¶›fÃbüN½µ±öÔ8²&’ÚA2”æ&ŒË{ûyGîüé\j¦¥¿\Ñ co—¸q}~^Žnýyê6ÍÓyyTˆ)µïÔâ§‹fè£tm—®üª>ê¶}?š-›åîJ½2^ÿYzJÒNjûŠ/]ô›OuL·²éì;A¾ËÓÓVEGÑüò¨e{’v»Î˜®x{MؾW”«oß';×ÕT)îÎ|økzl߉¹³=“vnëûRÞØJéç'ÐÒBxe juî—S7ÀÆj Ó÷$é±}WõÍŠÒÿ®¥*ÄÇïÖ¬Ô¶}×£ïºíEgß)ÿ[i€IjÓ_ám²ÓÄåáÔ6±vJ¢lT+®¾ÁQ;Å3QZ 4ôúóö¶Ö‡dÓüÁ,¹Õ¨‘¬‡/òÆé4<ï¿××Ò@ž§oMÜô÷øÝÏ—§ïÛ“L«U–•R硼¸hihèóíl)Q¾g¤¼åê2fh<þö,–H—Pê´«ÍDúÒW“öÖn{[ÆïÚÖmaû~âð^0Ub”÷çmmâׯ¥Kß=̬L~sUÔ2>Æ¡6quô²ð]·½èì;ìÞÝ»èHéÊOG*\‡š'ú¸}óß÷…T•Æ›4ꤱ' è|¼æðL쬭N=¨›ï-M·,-ÌënÒ<µÈ4/üÙ]tÞÖÚÊÑÞNxžúð«W.gé;·o£Íùýù´”=4Чjæt—¼ãÇø}<«Ñú½?ïÚ–|w°µÕåþ¼–u›Æõ^ž}ãw‚VàSu Æøû;…¯·—Õ¨×i¼CÃXþ%õg–†³{˜4sMòî´Î¾ë¶ }Wi¦½•D×j s3oR¿]˜-8õyã.Q6úÆ©c÷·ÄÇ ïêÐiÔöþ¼Þ¡vÜyâ„z¾Nâ÷÷í‰ñÔ@SC/lšé$Óàw„…9uŸhÐ$ýåŠN èË¢ó^³wïØj¼ïËl\¿¶¹¡¾þfµŸÏ¼ÖáyZó¨ON"–fÃ5ô}ÔK¶ Ãâņð¦ÁàûÉ9 |ifÁ|ŸüS'Y¢³ÓăÙYmÍMº;鯢æ#GXtµ·=oÇêÿnß';×ÕTá~&LƒÓ÷G=]3\¦ÚŸí:cºð§ºÜœc=÷Úëª*Bƒ)ú>wö¬7¶mí¼ÛJCõÅ yú¾=Étݨ,+½ßÙQ^\´44¾cÂ4x|'ȶ47;ràïÿ[q&/—ZjK ó‰ãǦ¥ìQôýFÉuP+O#ôŒÔ}Âûó´>â_·´˜9Ý%ïø1øŽ Ó òÀwLð¾cÂßá;&Lð¾cÂßá;&Lð¾cÂßá;&Lð¾c‚ïð¾c‚ïð¾c‚ï¾c‚ï¾c‚ïð&øß1a‚ïð&øß1a‚ïƒÐwœ0hïúõ¦ÁßÊÃw†fw¾ßá;ðßðßð߯î»è_Eà;`0øÞ~§91>nГӍ–¶ÖVÁA ÏçŸÑÜeø€ùîïç»jEtMeùýÎŽ–¦[ÇŽòñö‚ïÔ¬S¯Td}œç5çèáƒ|iÃÍš±Ž´¡ðÁïܾÍiÂxê$¬ˆŠì¼ÛŠ/€Áæ{ ¿_xhÈå‚ ]w%Úî³§OºLLR³«¢£’w½!\goòn?ŸyµÕ•w[nG. Û°_ƒnüÞÚ²ms‚ëŒé#GX8Mš¸iãÞÜ‹úêžînGî§êü;¦«½M¸Î´)ÎU7ÊØ|ó­úIãÇá À°¾Ó&Ñ zº*J‹£##‚ü•úžwüØ´Éκ;#–¤¥ì­CãáÀÂlxï³èÂ=4DÑ_Ý|WŒ›!º]o=z›7þšè‚0sºKB\, Òïwvˆ|§KA]M•b†ˆO‚ “¶“~}¦øx{;rˆzà:;hô½få ѳEŽv¶•e¥Â•ß>rÏ’e(Žñ÷íI^0߇֧KAyqÑÒÐPtÀйë>@¾_È?²(ÈÖÚŠÆïÎ'¬‹YÝÖÜÄoÁÙXöê=2ÅÉéA×=EßvwR'ŸFñ¯[ZP7€:ÿøÖl¾kÅ¢ÀÀ£‡àëÀ´}§æ[žžF 7ÿI`ª¾S¿ÝiÂøâ+—ñ]0Dúóø€ïø0”ïÂç`%À·€iø®ö?ø|×öG=¥Ý­ú|1öÑË–¶Þn¥ÛÛZø×T–óMn”\ô÷³5’ ™òâ"a†Uåe!‹ÙÙX°0÷pw=~ôˆªÒòW TE’X¤á áéþ~¾zºD+ëp%N €ï¯¦}å¦Uæ|åÆúÚ°Ðàˆð0Q:]¶mNðšåÉ>Þ¬¼áhg»7ywsC=‘’œD)‘-¥úO×=I»nÖôÜk¿v© 4x‘t©$"I,Òä<Ó…/!jrÒ$²RzZ|×Öwg§‰¥Ålþ`–œÍP ¥Ç¬Z±_žÉ×Ì–gPŠ~}'Z¨ÙRLïhm¡–Í/[¶cëfaÛ·$F. gót¹Øµc»V2ªŠ$½H[ß)Ÿi“©ï¡/ßE§Àwm}_·fUFê¾¾¦¶î¦õèQTh>}_ʺ˜ÕÔÀÍ›;‡¸ÞgoÕÑüƒ¯Ð´ïmÍ} Ù,wö‘šïÚÊ aôqŒ£=_ZWU¡•Œ$ië;ý-8—Oã‹ ¯ëæ»è´ø®­ï'Oä°÷^“w½Aä¬Ìtš§ *7§÷Y”ç‰hVW”ÿ}ÞÑžënöÜk/º\¨öþ¼DD ‰Eý9:±ÔUè¿ïÂÓ໾—^¿FC`Ö©nil yjÖi>zÙÒ¬Œt¾ µ"*R¿ãwéô³gNy¸ÎdóåÅE |G|ð÷óe%äT–•†, ²±=ÂÂÜÓÝMíïï$é6~ç£*¶ÎãwU§Àw<_žŸ‡ïàý¸Ã”®9¸~ø€ïÀwø|‡ïÀwø|‡ïÀwž·ÁïÅàyZ|×á1³¡¯R¢•üæ.K³áôWéúæÃ_£cXÚXwjÀwÄ«4–x•Jwô°»Óyâ„´”=N“& ÿ/_›jãc×{Ï™ 5à;âUK¼J¥;:w‚½²êéîv&/WÕj´#Ÿ„ïˆWiDñ*•îhaÀv©< —ѼÒö:* ñqšt|×—ïˆWÙÏx•Šgƒ.>t&Y‘è/Í×VW*-­µï\øŽx•,}0Ç«TÜ]"D^'ÄÅ*éØ4ÝÚš¸É×gÔ€ïˆWi,ñ*E;b º0d45î¼¹•ÿ<¾#^%Ç(âUŠvDö ÀÅ{ì^¨°<ì7ˆ9³< |G¼Ê^#‰W)*¹‡»ë;'óDKéjI¥•ÇÎÆzñÂ@Ñ8Àw<_|Çóóàý¸ÁâUø>t|¾Ãwà;|¾Ãwà;¾à;ÏÛð<-`ˆû®¯x•Ó§NyÔÓÅShÞeêd¾•ÒÍU-•(’†¹ùûù #ZŠ>@ûÞÏ÷a=Ü]YFnÎ1JÑÍwµER›[DØö:°æûÀ}7T¼Êœ#‡ç>‹¥Ã˜3ËãøÑ#†ò½ýNó´ÉÎUåeð˜¶ï†ŠWù°»sГӕ‚ ô±à\>ÍSŠ¡|ge ?@øLÒwÆ«”§§-^Øû,ä; ¬a@߉„¸ØÍ›â1~&컡âUÒßž{ícŽ:@i^˜‰¥…9Kátw´[˜ Pß©?ãé6óÒÅóhß ß¯3`¼Ê¤]oXš›Q×B”î2uòµKÂM®8M? ¾÷ݸ(+¡]Ó ¾Sõ}Æ«Lß—B».8w¶½µ… Áõ —iü± œïì DGFÀw`ª¾Âx•zºÈeî®6V£ š9˜¥v_¾kþë<íÚßÏãw€ßßx~€÷ãpÍð}èø|‡ïÀwø|‡ïÀw|Àwž·àyZÀ÷]_ñ*c죗-m½Ý$\šüæ.K³áüm8FûæÄø¸)NN£FXÚZ[-<ŸFbQKÓ-G{;áKô!‹òùîŽvG;[öŠÐ’ëþ~V£F4S^\¤XN{[ë ÿšÊraºùð×lFr›1=!>Že€©¶ïzy¶±¾6,48"<Œ/zØÝéßÒØ@­'ÿx:ëLšñtw;“—ËÓ©í¦v\inªåæ xžmîqÚéÉÏ#âúûΧ¥4³liØŽ­›…[mß’¹4\±œ­-´#UKW¾½ˆW©™ï °‹Ì¹Œæy:õ´ÃCC.\ÆÜ^D¥ëè@ùÓ| ›Ý´5’õðU7ÊlmR’“øýyúX]Q®´œKBËÒS…é]ím%EWit€ûóÀX|$ñ*=Ü]ß9™'J¤ëŒ§»Í\È?²(ÈÖÚŠéÎ'¬‹YÝÖüüW{‰E}GÔt‹FÖu7ûîÔTѼè·òò⢀¾£G¾Nøûù–½èê+–óì™Sì·þû;]=¨··‘ÝÏ×ßñü<ðñ*€ïÆè;ð¾ßá;ð¾ßðßxÞ€çiCÜwýÆ«TRU&JãXª )ŽÒßÏ÷QO—ÒwyD{÷õ™Ç^!dмŸÏ<Ôj0DÚw½¼«*¤"ªâXJ‡ŽTŽ2"l‰Ðb ߯]*˜4~܃®{½Ï¢ÙÐ|ÑåBÔj`\¾<^¥tHŽª8–Ò¡#Õ†£l¿Ó#½_gØx•Òq {Õű”©y8ÊŠ²—©“©Ò¾k{¤¾6ß ¯R1¤é8–Ò¡#µ GIÇN}uøLÛwƒÇ«Åe"ÇRmèHÍÃQÒø‚Vú®ôˆà;ÀóunГӍ–¶ÖVÁA ÏçŸá«U•—…,^dgc=ÂÂÜÃÝõøÑ#¢þ‰(‚e¯º€“ø>¾ûûù®ZMÂÞïìhiºuìÈ!o/¶ˆÇ8ØïIÚÝp³¦ç^ûµK¡Á‹D›‹"Xª 8 ß|Ðx•Ò–Q³NM¼Ò3¶kÇvµ×aKµ'á;€ï¯RÚ2êr‡‡†\.¸ ŽÁ Æ]U$(U,5 8 ß|¸x•Ò7ÿÛ[[HX×ÓGްpš4qÓÆ ¼¹·47ETúû‚0‚¥†'á;€ï¯RCËõtѸ :2"(À_Ãö]1‚¥†'á;€ï¯R+˨q§a¿ïÞ¹Cíø]ÁRó€“ðÀ÷ˆW)m™·]=¨óOƒýÚêÊ5+WЈþïûóŽö)ÉIu7{îµ].T¼?Ïà,µ 8 ß|×{¼JiË.äŸ YdkmEãwõ¯‹YÝÖÜÄW«,+¥¥6V£GX˜{º» æÆ#Xöª 8ÙÏÿ\ ~àùyÞÀwà;|¾Ãwà;|¾à;¾ð¼ ÏÓ†¸ïªº Zõ%TE§n%ÙRâmàû@´ï¢Ü´Ê\UtJž®IdKøàû+ˆW©Gß{_ŽNÉÓ5Œl ß|èx•zô]’§kÙ¾øþ âUªò]‡ñ»(:%ßJÃÈ–øéÀ÷ŽW©¯ö]1:%Úwßú~¶ñ*õ;~F§Žß5‰l ß|èx•úõ½Wò¥ûóšE¶„ï¾h¼J½Œß…ytJaº†‘-á;€ïx¾óFްëè°*:ªõv*€ïz_⣆Ûê=^¥¿ïüwNæÝk»ÓÒØ°få º˜ âøÎ1áx•”ó葯£âøÎ1áx•yÇùxÏEÅðcªñ*KŠ®R™«+ÊQñ|ç˜d¼Ê‚sùtE— Që|abñ*iè1ÎÑñúÕ+¨r¾+bJñ*÷&練½ª¼ õ Àw¥3¥x•ŠÅ  ê€ï¹Pç¿¶ºrÍÊ4¢‡ïÀ”|Åñ*·¥Î³¿Ÿ¯0Q"þ¤¶¿¿[IãñĸthjK{!ÿLÈ¢ [k+¿;Oœ°.fu[s“Úñ;bx¾øŽçç€ïˆW |7j߀ïðøß€ïðø€ïøÀó6{¾øÞß_}¼J‰H’ÂveTYOå±·µYt¥ð"|ðÏ×€ççñ¤x?î•k€ïCÇwà;|¾Ãwà;|¾à;¾ð¼ ÏÓ†¸ïúŠW)‘H3þ~¾zºT-ÑÒtËÑÞ®ç^;_9dÑB>ßÝÑîhgKë¨ ’ÉH~s—¥Ùpú«ô`Ç8ØG/[Úz» Õ Íö]ïÃ*¶„½Ÿ«t©â¶ÁA sŽfómÍMfÃïÜnd:@K{UÉ$vw:Oœ@{tš4‘æwÚX_†j ŒÚwƒÇ«Tjtûæi“«ÊË4ô=7çXP`›goÊŸ<‘Ã>úûΧ¥½ªƒdöm’w‚½ëéîÆ£^‹6iil Žª10jß ¯R¢/8—ïáîÊ÷(í;­6ÖÑ”¤ùÄø8r<1n#k—Ç8Ú³LTÉ$,`W¶rÍÃw`ª¾*^¥Z߉„¸X•ZbüÎÒc×­My+™fæy͹Rxqî³@|»wî tÅ …A2ëª*èÀi˜ÏûµÕ•¢65ÔF, %PQûnÀx•j}§†§ÛÌKÏ«mß{ŸEéq›16™á2>ºLÜs¯¥Ïbõôª’¹iãÑ„®3¢K„£½Ý²¥a,F}¿Î°ñ*¥Gèe%d.2ÔúNïòô´UÑQ4¿Íî=ZÉzøJ7dA2iÀÎoôqýýØ­KøLÏwƒÄ«Tú ¾Òœ©îïç«vüÞWø¦[–æu7ûFå5U4/ì+ ’éáîúÎÉòðUEžäéw[KŠ®nX3ÎÑ‘½ÛŽ€–¾÷"^¥&±%—- Û±u³p«í[#—†+îKyR± ¤-Û -|ï5D¼JMbKR÷¸¶²B¸}¤¥¢}‰"O*–űéE@Kߟax•jcKÒH™E”âtuܵ47SÜ—0ò¤âNIdK s wŠ€–Àä}7H¼Jµ±%ííԶ'•¶ïd®†;E@K0î×½úx•½êbKF„-Q¿“PŠûâ‘'Uߣ"Â5Ü)Z‚¡àû«WÙ«.¶dÕ2[›”ä$~ž>VW”+Ý‹<)Lïjo+)ºJu~^“" % ¾¿úx•½êbKåÅE |G|ð÷ó-{ÑëîUyRøû;‰L wbÜFvƒNÃ" %ÀïïÞ^šä¦CàJM|WŒW €iø®C¼JžOB\ìæMñ¢DéP“Òãw†­µïr DàJµãwQn˜Œï:Ä«äùPÀÓm楋煉ҡ&Õv¤[šnmMÜäë3O“Üt \)ݾ+æ€)ݯÓ6^¥0ŸŠ²—©“iÀ¥CMj2~Ž"p¥&ãwan˜’ïÚÆ«åC›DGFðDéP“jEc÷ÆçÌòÐ$7ÝWjâ»07LÉwmãUŠò¡°¿Ÿ¯0Q"Ô¤Úñ»õâ…Â>¼ÞWJŒß•枯àùyÞëEøJßñ>,ð¾ßá;ðßð`$¾?zñý˜0a2’©ÿ¾Œ·“߀ïðø€ïø€ïø€ïø€ïø|‡ïÀwœ"à;¾à;¾à;¾à;¾à;ð¾ßðßðßðßðßðøß€ïø€ïø€ïøx5¾Ó “AÂ÷a˜0a2¹I©ïLy€‰ÁìVô`ª}§y€iC²S÷žY0mHöÿC5¢á endstream endobj 627 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 551 /Filter /FlateDecode >> stream xÚíÜ1JÃ`à/¥éÔ©«"Þ¡«‹ƒ'ðŠ ›£7ppêÖ=|~z” @ÛͲL*m t49ŽéÍR*5ÊŽl¼V_à›èæõAP1€P  @ @(€P  t¼Œí„¾° UÚС@íøšý€©o ö@ÃAùS‹û;©´-ÐÙåµÄºèúm%1€w~íP  ôÿÛ¥ – endstream endobj 630 0 obj << /Length 807 /Filter /FlateDecode >> stream xÚµV]oÚ0}çWXÚ LÃøúÛ}œh•&µ[4Mê*”–@ÑBè]Û¿›8¡I ” ìØ×ç\Ÿœk‡‘9adÜùt#㈣NsM‚Qšj'ˆqØ Á”\uŸÆq8z}®Xw&aÜ»Î#ˈŕZd+¥åÔ‚EÜ|—olwࡲ%aÐùÝŒa^¸p¡PävÙ¹ºfdŠsç„Qé,yÌ#—D£\hìÇä[ç²ÃŠüÛÚ’ £L"£ZòŒé)ßð!•~>É­ *(WåÌàó4ù´BòËš~ÉÓ¯íj‹òQgÊR£¹×i´˜?¤…¶‚‚:ëõ°îðOT7J6k?u‘®î£t³ˆÖ¹Ž¯ P¶¨wM i XM ¶-\E ·O ŠÖ¤0‡¥@ø~…gW °’:.(I­¶{¥Ð¯K‘??.6w¾‡1QM‹‡WÝr©º “i¥þ! —Ñ^-÷y¸¥ÚʦG3­Í7mõnm8*y±çáS¸¼·›–¾°ê%©(3¢¬«q”Di¸)wyñ¼¹[%¾»*‹t5óm˜…ZMÀRÈõ|&ÁðGÐÂl·Ì¯ ºÞ<Ü´Åt¼HŠ„€·–?@ÆÒTVª~êTö®²f\Ô0‰€@Á˜ 1W )I8Öž#iDfÕ¤µt—€a>`K Yô©ø…"uürûÇ0T±4V˜;=Ù²x±`-ø“^Rž©€§ÓÞPTRöOçÄw¾Ž³ 0þ޹õ8•jk¨Û8\7³&¹êkƺ_žGi³^á'S¬…9¿·šñ´=¸ Îü`M›º½+¬Ãë½™)êð§yâÔTÛ,¹’¦¸ÿs„Ô^:bÍŽóÃd²H›Éäß ±ŽâYsŇlwÏó*éUÚùdÞ·)*ð} Óùz?¬@TÔ©†Ú ‹oÀè*î¯ÇéúGKÅ›ù± ~šOK³Í‹…´Å%+Š[°j<¼Û¤Ûï]«ir»ÝDóErœ3ËåÆ{;;LÐr¾8¯öVÀ¡O‰Ú2ù?_ÙU\œ[ endstream endobj 619 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 495 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 636 0 R /Length 9548 /Filter /FlateDecode >> stream xÚíyTg¾¿Ü™¹3çÞ?îüî=g’¨q‰kܳwpAEqK\QqQã—˜5.,Ý îWEQPQTÜ@Œ1“¸O655cÜý}±´RVwÝÐ4Ïs>‡Sõv-ï[]ïÓoÐU¢D6e¼†BH>¥Ä3dÚ/ò!„äSá(ªi>ï_„’O©Ò-DäˆmK®ê¢³“õ²–®E(J£Šný9h/26;HŽQ:ˆn]ƒ€k;—ÍýÚìãûÕÚ¦ág‡´“¨ãƒF)cù©®X£ÿâvK®ê¢[«ïÂcºd-]$ÚUîÞxþÊí%»/zN?l½ä‹ŒRë’Áë ¶böª÷â7âÈêŽ4í PŽ­Kb³ƒä¥ƒèÖ5è˜Ú.f³så¥Îê^¬K öûœm¦¦iã´mž­XcàÒöK¯ªQ“‰~ŸS£ª‘µt<;!c$cæ&þê¢ÌƧ]hdµä‹ŒZ+má(SäxsxÛé»_pe:Ï9¶h÷¥3?ß6®žKÚèÚÕ•er’Ͼié§§Ëì¹+·¿'¡ßgo¿ %ÚMMßtöÜåÛ÷<’WCΩ;’­™¶œûîçì/\ý=lÛùFÏ×AÝ‹í2Rö3’ 65xùÉcnÞºóàÎý‡ig~ý0ê´u“L»°¬Y‰¾¼tKö{çÞÃÔS?÷Þ¬ÖDW={UÚ’uEiš²Øœd6!ó²ÍØË¤ ß}õýoÒ¨Ë7ïÊ^ìÕÁúÍúÃ63’ ¶ÿ~àvë%“O^»{tS¶)G#×GòÅG×AŒÒA¬;—®gÙ,·Ù¹ò^gÝ-{ÔUF·_­mM?ªƒ¶Q^•Ÿêеü#:-ûE²Ø€EÇŒ e-]$ÏN³>{d¶ÃÌ,Å6#M«½f¤*¯¦?ß-ô@ß̓L±sv<ü¤_ ˜•¸ëèw2½$éÛÆšMÿîÇÞs~0wûßý(³³¾Vvº-»£%ù“ÿÌĄԯezÁ¶Ó¦QWÔîE­Õ¦5ƒBbÕe”iƒM}íNvÛp$ 4Þµ?ó»Ë­X·Ú8ñçÒÏÜxøè‘¨#åäÏsã2†‡mjŠbZï=cŸö ©Õ³W¥fÁ™gºùàáÃñ™CW~ýàá£ï~¼`‰ë´Ãz#63k{öÏ8{mä‚]#çlÝyôŒòNÙ;D6£²ŠAl.9l榛ög|}ñÎ=©ø£ô3¿Ê‘qö`HtÄÁ(ĺséz–Ír›Ë%uV= »³®‰n¿ÏÙfF†6NÛæÙŠµV½·ü5O‡Á‹ŽÊZº Hžžf–>A{ÛÏ>žt"{Å}GO1G´ Ü÷t¸²0zpȆnAÛüBâ/]ý·”|²0^Îð‘ó³»ÌÏ¿Ü蜤nʲ|£¿i}· Ä KvËìW®w Þ-¯ÊP'»K¶ù‡ÄøÏÊAýxõ×÷‚w©+j÷¢ÖªOÈf‰ÔM[OƒMÝüýÁýC#ý-q}Bâû„lhÚØ40Ýf«ì“C'=7a¨i½Èé¹}‚7wÞÖ*0U{ÐÔêTiÀÂÃÿþýîßn_ûíîÍÛ÷'~ž0¼¦Gð6ëX×DòÃõ»²ØÔeÛLë³—4ÅK‹š¶wˆlF{·y¨…2Ý+8Áß3an\æ© OoQí3ÞTaˆ®ƒ8¥ƒXw.]ϲYn³så½Î:Ø«³šçþs!0Kgm£®XgèšÎ˯©yú¹¿è ãBYKW‰î.ñÅ«¿¯Ûÿí¸°5ÃÌÑmƒ(åYVö|ÒÑšfÉJvIèꞦDSö9ïÞýÌk[=½K0qæ*¿„6A)­L™Ê«ÃÍÑ̓ŽÈµ•®]ò‰?ÜÝ<0Íz/jI» ýÚz*%›²l»x÷Þ})‘ÏâÓ?ü66êT§=­ƒ´zi£îÕà„ §Îÿ$[M¥ýý츬®¡š¦7 Ì´®ŒRbP%YkÓ¡óJáöçGY¢ú˜¶´Ñ[u#6#£ YlÂÌ(¿àxyGši´¿eÐ!ƒCdpíÅæ’^æ/&ÇžÛ{òêïOÆ6_Ÿÿq]bêHóy7·VàÑu£tëÎ¥ëY6Ëmv®<ÖùStÑê´Í:«1ø?)§mólÅ:㻄_Ófðâ/tk)…uYËú¿3ÔÓìsô sœ$À¼!ÀÛ#$©eðaõÕöÁû<‚²dùK¿d_ª.Šé¼·ËüÊØf¬9²mðÓË®Ðåqƒ“=‚2z.>•ýåúXKd›àTå3:ðóõ#Ìk›7J>´D ]%^²ÞË'ð~]=¥Ä`S²ä€Ð­sVmÙr û€\¿u§Uð!›ÿ–2Ú%[S¢îEM_SÂä6í>röû_”û6{N]·>hêŠUê³ôkÑøWoþ|õ×û÷†ïh¼ß#(Óz#6£l94|“hÓ38Ó ŽF{±^2ùÔu¹”ÂSßß\±óÔ˜Û>°DKëÌ19n­À£ë K»˜ÒA¬×Õv"{å6;—Kê¬öbƒ:Ûü?©&ÁǵÑÚfÊ”º”¨U¢DŸì¨¶QW|sDL×ðkºè£ÔP·€¬¥«€äéiº²Ÿ9AÒ×¼¥·9±KHr«#šWÛ‡¤(Ë/Ùû“”¤dœì5;5öhö­ò¸ÝGÇXV· yj›Sg. œŸÚiîÉÔooÊlôöÃÊ«swþ ³ÇN5/1`vâ̘´ç.K§n’b½—_ogOLKcÕí2›Úúƈˆ½-I«²/¯\»9ÌÓ,8Óºá]M»•&KÔ½¨i’ÞÙ´§ŸyËPsìÔ% [öÿþʦ${Õ³W¥.a‡.\½#ÝvFøÓŠm2Ò9w™yØæFlfvÒ÷²Ø7ç¾÷_˜ÚnÖ‰uiW9DöJìÅzɳ—Þ÷ÝÇ‹wµÈ§Ï†Á¦ýÌñ½ÌIBöµÉ0ÞZG×A l£í&JÉ˺.¯³¢ëB{û}Î6!_jóüئ„.٪ٓ?lólÅ·Fmì¾âºu†,9®îUYKWɳÓ,¢½)Õ‘W›šOÄî?}åÚ»÷\üåNDò·cB× ±Äú˜žŽí×'¦\ºü«ô/y5|ÇWòïoŽkk:$ë~žuéÇ+·ïÞÿ÷݇ÏÜœ¸îTOs’ͽ„íøþÖ¿ï(å6kboSãcÎuñšŒ%~»óàÄ…ësVmårкiŽÄ3ä‹6!i]ÍÉýÍ ÒéF…F{›ÒmVÏ^•¶y]–Yº5ktèÚ¾–-‹·d_³þê|³,›±™…ñ™¸òûÝûWnÝ M¼$täåøæj—Ñ¢¾`Ù8Ä7À¼¹·yûûæ}-CŽx†ÏÝ‘|Á±î º®a³›($/ëæG uûÕÚÆÃô•6ÎÚF]ñíÑ›z¬¸îld-]”|ºö£ÐÈöæƒ¾ÚÆœîoÞ4*tÝÐ'gã`s\7srKÓ³kÿÐÈAæÍþ¡›ý-ñCC7 ÝÔÕ¼×Ë”%+z›Ž ´$Œ´Èбƒ,ñ}͉¾¦¤6¦t›{‘WÇ…®–½ø[6Y×Ä`S=,{K,›†„ƷĈ(|L‡m6Íñ43÷1§I3}Liöªg¯J=ÌÉ¢)Y¬“9¥¥9«Ÿe«\aõ·lõ4°ÞˆÍx›0Ë–£‡Y6 °$øšw·2eäxˆys• ¶l–(KŽ]/ÓJù{æ]Ìû¤]MM_æñ¾à䥃¸¶s½˜:«yÎ6æ“Ïå¹ÿ\°{%¥þ½ºbݱ[º,ùÉw寎§Ë’ß»U_'éjÙÛϲ­½ùƒ¯zšOfw"KrË?ËŽ®¡û½L™R®Ú¦«eWó?óvyµ³e¿—9K]·•9³‹eŸŸ%©%±§eWGË¡æã6÷ÒÚœášÜ×’¨–ë–±·©–æcòA,å}-Ûet!Ë7·œ°Ù´¼ÄºzöªÔÞ’Ö;4Iºm ó1e_Ë._ËnoK†ÍØŒ¬%ÇY¶ìgÙÞÙ¼Ïëɦr ‹žÙ!4=¿wä–ñK°N‘ØxaK^:HAu.—ì÷9Û„}ëÞé–Ò?lG‡°#nßÒü;zº¸ê`æëÆI!‰Ö6Mg~'ywB!„¸0Š[t¶‘ò¯¾È"Ä©<.:ðfHá`’wÕ¡Ú–(Q‚·¬PÙæÒù³îš"Ôº¢RÕ"d›EsgŠm Õ[\Ìm#!>f­»FN6ªêÚ9Ûª·Û¸«j&4¦¨tá"TUl“—·Û`ªŠm° ¶Á6ØÛ`º0¶Á6ØÛ`lƒm° ]Û`lƒmܯª%_yÛäß»æÔáÅ6ØÆ=ªjï´ñ¶‘=êâÂsØÙ­a›"g›%óç´mݲÒëå_+U²þ»ï|6q‚{Ø&?zb®ONƒªV©TaãÚUêlÛV-Ô騵«ªT¬µb©ËÛh°bŽ¶É¿sØå¶Éã¹m\k›e çV­TqD€ÿÊ% 土k ññn‰m^¤mÚ´ôúì“”éµËK½úÊš•Ë”ÙIÆÉ«ùq%åBÛNÙÿFåJi©´%ÕªV‘’/³2>ùhü[µkU®X¡¿Œ´CêFLAoÖªY®LéÍ<·nŽÓš”ÅVG¬ðhÔP–‘%CMÁÎÚ&ïç6¶q­m:ú´ ÔßæKòõêÞMÞ/‰L¨Ÿ¿òŒ9¼Võjòyñö›µgš‚>;ºNÍeK—jÔ ž|š8µ˜á^>¨Y­ª²ü¢93]b›¥ çÊ)'vÊ•mÛÊKéמLþxœºŒœœU«TZnP7ëi;‹SU6ibk¯æÊtà”OeõS&*³^M=äUíã¢Wûv}_ê/U>dZ.uëÑå=ëòÍë× Ø¿fµ7*–/×¥c‡˜¨ˆ«š‹±ÿÀþS&~¬ÎNžøñC‡ÈÄ´)“|¼[ïÚ‘(æñëé;bØPu#]ßï´;i»øçãñãZ6ofsã5ª½±xÁücGÓ÷ìLØ·³¶ÉŹmïðÚ<ŒØÆYÛÈQ ÿ|¾Í—õókîé±t‘¤©GãÁýú¨«U‹fáŸÏ“c>tPÿ×Ë•õöj!Qf=7tj1ƒ½È5ÅŠÅ dyÿ}›4¬ïÛÔ}ëÍÐÀi±k"E&=»véú^G) ™öÙÛµkÉ¥,ÓµSÇáþëfsG¹ÛlŠ^-r‹ Ͼ\êß»—¦_/_™Ž\¶¨jåJòªvËþýûH•ä%¥Jjù ¾½[6oºjù"‰lA-1Ô¿¹G“ðEó£#Ã;µoÛÇ·{ÞÇ6Ö÷m¶oI¨S«ÆñÌ£2-?e0#~ézußÞ¾5AY1eo² QÔ¤ìIV¦3Ó—/óšMÛÔ®Y#húÔ½»’rw%•‹sÛÞáµw±S¶‘G¬æ¦6µjT[¼ êæBÛHäãuÔ°e”5Û¬¨uØàR®Û²ÔA[%My5u¸( ¨åoÕ®¹tÁÓòÕáKd¬˜O÷m:¶÷Y0o¶LÌŸ;»—o¥P4¢õRé’¯Ú܈:«+ß#C ª•+Ö}ë­•Ë–:k›\œÛö¯½Ãˆm\5¶‘KõÍ’ ™5îkÆ]ÏÞlîö’kÛÌ37óh,ãaõüWʧOþD>y7­‹êèÓæÃ†æ®n¹¶Í‚ÙaõÞ~S†ñï¼UGfe %c{©”.mùF›å¯•Öö÷R¯¾’O¶‰\±Ü«YS™hÑÌsóÆ Ja½wÞ–Ë¥7¢ÎJõ¬>q,3|éâêÕªºplcïµ{xíFlãì}ù uvlãBÛän/¹¶lÿ“q®X.b‘ŸÚ séér #׿qO.^ ê&çä†gWî2S7bó$tð7àb›ñ£GÈEœLwîØ~D€ÿ»o¿eëpýñá»xî¬Ç6¢,¹µÞAUsý;©õÞ• Ÿvm¼Õ’S§ÈlbBüG¶lÚØ³[7cÛT«RYVËeh·-a³¬+¶©Y­Z.îÛ8{nÛ;¼ö#¶qúwR•+:D.T³ïÛ‡šÔûöûôV¯me<0¨oïü°Mîö’kÛHc§Mš(-•O=i©v™ÉŸŒ—ÙÆŒTKìÕM®tüô‰Š yo¯êFªT¬°xþìÜÙF®¤*U(ÿéøì«¹OÆ~X¾låÚJ×–Aýü¼šfßXHÝ´‡ñû6Íþ(=|ˆ,&µ…J·êÐÆ;ǪæúïmBMÁ2V”AŽZòeV†ø§^Ý·elШAý¥‹ÛfÚ”I•*¼®ÎÊE™ŒŽÊ•)íѨášÈ•¹ù”“ç¶½Ãkï0bgÿÞFŽaÛV^Ê—•ëÜõꪓ #ɞݺ(÷íe"Öð72¹¶Mîöâ mt‘ Ï&ËçTéR%k¼QU®˜´›•†×©YCØÔMηF êÉG®ßÇŽ®½—(‡1U•D­X*µ’“_¦åcT¦µf£ûÝ“\ V©TAûK©[·÷;)åCô“ÕÕ1›4ó­Ú5Ë”.%ƒ7¹`̱ªîô·ÄΞÛö¯½Ãˆmø[âÜÅÛ«ù¤ ãÜàÏž?ŸV«z5þsÿ“Â6…° Ë'×øÑ#ä3Ký%xQ´Mï]W/_¼bñÂæMü|»alƒm a–sÍjoÌ3éé=|Hõª•å Ûû7Øúó3lƒm° ÿ•É7N`lCÆ6ØÛ`lƒm° ¶¡ clƒm° UÅ6Ø&ÿlóÀŠâƒËáE"R5° I'„¸*؆ò®^± !ÛB° !„`B¶!„`lCÁ6„lóU!{¾3!Ľm“5Ä6„`!àó !ÅmlSPÏw&„·û6õ|gBˆÛØFVQ£,P°Ïw–:h«D) ±¶Gîl£û>“¾3_P¨p­müµÑ‹¾3!¤0\4åŸm Ïó !nlBÁ6„lCÁ6NÙf¦ÅLHþ…ž‹mÔY~ÙWØêNm¡çb­m8¶…*Šmܦ-¼¡ØÛ`lC° ¶)À7¥Ä¬§± ¶q?Û”°E~w«Âo›µÍ&`RÜlãN;Â6Û!ÛÜ¿÷oÿùŸÿñÒK{wïTJöìJ’Y)”—NËœ:yR¥Šÿþ÷¿—+[öÓ'H‰vkÓ¦–yíµ¿þõ¯U*WŽŠXi=‚rÛ|4n¬Ì¾ôÒKÿ÷ÿÛùý÷Ò¦%rèÊ—/'寗/4cº=Ûäx'Nøèå—_þÓŸþ„m°MQÛt~¯“”=J™ýpÔH™•>%Ó“&~"Óí}ÚN=0d𠙞2i¢vkÚùNÙo’iéYî:¶>4 >.63=múÔ)RÞ£{·ÂÔ)“eÖ£qcѸD&ìÙ&ǃܱCûÚ/{Ä6ئèÞ·‰Û°^&ä³UY¬b… 2»)6F¦¥ïÈ´òŸæÒ¡dZ>¦µ[KÞ¹C¦¿È8¢|ô]Û8xSëxV†”¿òì?a B…×_—Ù-O¾ÖU"öl“ãAV‡ØÛ¸Á}›ºï¼#/mX·6&zMv«ëÖUÊå*@×ÿüç?ÛÜškoJª±ÍÚÕ‘õë½ûÿù1‰RnÏ«ÚÙ¿ýío2u$M™•q‘½CäøAÆ6ØÆ l3wVvcýzõìÝÓW&æÍž¥”—*YRýì6Þšۦ䫯ÊôÂysdôräPªAKµ³Žm?ÈØÛ¸m¾ÌÊ>õÿ„üCN~™UÊ'Œ'«´iÝ*eßžôƒ)‹ÌoP¿~ŽM†2½ãÙw,uÛüóŸÿ”éÈËåôìÑÝAÛL<ÉÁû6ŽdlƒmÜãïmÆùP)‘ íZ–àêÕªý÷ý—¤q£†êw|t´I?k¹Íï¤"—W®\é/ùË+¯¼¬ÜÑuÄ6’ÉŸN,W®¬\RÉêAÓ§¬èàAÆ6؆¿%æo‰ùÏ‚m¶!؆`lƒm° ¶Á6Ûlƒm°ÍW|S(á›BIÁm P±wï^Ú¶Á6´° ÐC± ¶Á6ôPÚØ° sÛ”|åe]Μ9S»VÍ;wîèªtãÆæÍšZ//±Ù{KÚ[}ÔÈ£GÔnA-q|§ôPÚ…Ù6Ö{^]¿nÝÀýs×ñ·°.:º©§G“F 7ÆÆæ¸)lC[ Hß·Qʦ¦¶ñn­.Ö¼YÓ¬ÌLWÙÆàÌO?ýغ¥—\Rݽ{ÛÐ(c¡OÛÔ””ì“gÏžÎï¿—ëŽïÔØ¦¯ŸŸì.jõ꩟MÁ6´ЉmvìØÞÓ·‡LtïÚuOrò °\=ùöè.=êÔ¡}Ê؆¶@q°tùfM=7ÄÄx5ož—a†ƒ¶¹|ùr­Õ¿>uJ™•‰úõÞ½qã¶¡-àÞ÷mb7l(SºToØ:xßfÐÀÚß° 3f À6´ÜÃ6@¥-ØÛ`ÚØÆúZÉíÿ³€Šm° cz(mlذ G˜J[Û`ÚØè¡ØÛ8k›½ù ]Û0¶a<@[Û`ÚØè¡ØÛ`z(mlذ{?áÅÞ’2áÛ£û£Gt 碪êlõ7ªúõîuöìz(¶Á6Åð /ö¾ÜñºlJ™¸víšÅljïãCÅ6ئ>áÅ@2á%lj\z·j™–––DZͣGΟ;שCûÄmÛè¡ØÛÃ'¼8r³åôéÓžMߺu+ï÷mþõ¯Õ®US6EÅ6ئ¸=áÅEË—-5rDÞmóøÉ¯ðVEFÒC± ¶)nOxÉñ¾êRGåú¾®sµnéEÅ6؆¿%¦‡ÒÀ6€mÛ8E<áÅÍ+ƒmÛ=Û`lƒmh `À6€m° =”¶¶Á6´ÜÏ6<‚x 0¶alC[Û=Û`lC¥-€mÛ¶z(mžðò8Ox1(´÷p–ÿ+lÅÁ6Ö{w¿'¼X5îá,؆¶`žð’O¶yüüÃY° mÁ6<á%Ÿl£{8 ¶¡-؆'¼¸Ü66΂mh ¶á /Îî´Ìk¥u¦ºsçNé’¯j·`ýplC[° Oxqv§žMgfdhK2Ž­W÷ë-h΂mh ¶á /ÎîtåŠrÝwèàÁ›OKBiÅ lnA}8 ¶¡-؆'¼8»S‘äºèhïÖ­ªT®$‘ õ·êí?œ¥À¿âÛ€ÛÛè¡´Û`lC[ÛX_+ñ„z(¶Á6Œmè¡´° `À6@¥-ØÛ`ÚØè¡ØÛð„à /ÀØÛ¶z(¶Á6ØÛÐÀ6€mxC± ¶¡‡Ò((Û¸å^šz4yôè‘Z"ÓžMëVY¸`Ák¥Jªß{“cÛÿR›“ ßݵÕxløØŠƒm¬÷^ÔŸðâݺURÒµ$11QJ´ë>|ø°þ»u×/«_ï]í£%Œë`üÇÖåÃÂ×cÀ6çQÂKB||ÇöíÔ’v>m·$$h×ݵs§ò%Zm¼[ïÞµËÁ:8k 6iÔ0Ç-`(ζy\ÄŸð"žlÔ Á‘#éŸ<áeõªUýúôÉÖfîQ«Wk×½pþ¼ Z”SòS¦/\¸àHœ½o£L̘>-8(Û¶q¿'¼(ˈ(êÔ®·Q~*ÒP×>mªÎ"GꋱrêݪeZZ¶lc¯Eô /ê2óçÍ-SºÔ‚ùó´åÊ`F}h]öPçÂu¨c\‡ÜÙF¹äÙ¤ñ­[·° `›Ñ'¼wÿuÑÑ}üzë^êÕÓwýºu9Ö!×¶–/[:jälÜ·q§'¼wïÖ­’wïÖ½””´C¹Ie\§þ|HW Q· ™° gÛ=”¶`lƒmh `닞ðBÅ6؆± =”¶¶lØè¡´Û`lC[Û=Û`žð<áÛ¶lƒmÛ¶Á6€mÛ¶Á6€mÛ`À6€mÛ`À6€m° `À6ذ `À6ذ `lذ `lذ ¶lذ ¶lØÛ¶lØÛ¶lƒmÛ¶lƒmÛ¶Á6€mÛ¶Á6€mÛ`À6€mÛ`À6€m° `À6€m° `À6ذ `lذ `lذ ¶lذ ¶lØÛ¶lØÛ¶lƒmÛ¶lƒmÛ¶Á6€mÛ¶Á6€mÛ`À6€mÛ`À6€m° `À6€m° `À6ذ `À6ذ `lذ ¶lذ ¶lØÛ¶lØÛ¶lƒmÛ¶lƒmÛ¶Á6€mÛ¶Á6€mÛ`À6€mÛ`À6€m° `À6€m° `À6ذ `À6ذ `lذ `lذ ¶lØÛ¶lØÛ¶lƒmÛ¶lƒmÛ¶Á6€mÛ¶Á6€mÛ`À6€mÛ`À6€m° `À6€m° `À6ذ `À6ذ `lذ `lذ ¶lذ ¶lØÛ¶lƒmÛ¶lƒmÛ¶Á6€mÛ¶Á6€mÛ`À6€mÛ`À6€m° `À6€m° `À6ذ `À6ذ `lذ `lذ ¶lذ ¶lØÛ¶lØÛ¶l€mÛ¶Á6€mÛ¶Á6€mÛ`À6€mÛ`À6€m° `À6€m° `À6ذ `À6ذ `lذ `lذ ¶lذ ¶lØÛ¶lØÛ¶lƒmÛ¶lƒmÛ¶À6€mÛ`À6€mÛ`À6€m° `À6€m° `À6ذ `À6ذ `lnBqÄ؆‚m!؆BŒãÛp+ œºiœkÛBHî.¯° !ÛB° !„`BHQ´ ¿È#„¸*¶)àRlÚF!„¸0Š[¬mC!ù­mdšBò/¢¹°RœC!ùQÍÿ·[ endstream endobj 636 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 495 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 671 /Filter /FlateDecode >> stream xÚíÜ!NÃ`€á¯„- …!ã Ø!&P5n€XH†CîwàB0à‚+`¹AIfÆVÖ¦¤Ð>Oò™fêo+öÿ)5ˆ°øºVo@S…Ô´x~ÓQ'b:³™?ë&©1ƘüÉzù±Û‰ÞÌ»Ú`sÙÃLJ{›(Ð$Il h@·vöâàòÎV–È™ûºø~ø}¾µ X°a    (€€(€€èð´í~@h ÷TP÷”¨ûVs? @Õ_ î€œåºn®¯l  h@ÏÎ/l  L@ß^_l à‹£]  Íç\/´‡s½UÔ¹^€u®`5çzªþu®¾ó— PP@@@@PP@@@@”Â÷­šî¤1Œ‡ÙÌŸõG“ÔcŒYwN»Ñ›y§ò÷|ßw| endstream endobj 620 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 194 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 637 0 R /Length 8560 /Filter /FlateDecode >> stream xÚíwTٶƹón\÷ýñî{w­;3fÇŒŠŽŠŠHEÌ (`BÀœutÔ1ÝÕ³‚¢D%¨˜@ÌèÑqŒcœ1 àÛmiYTwÝM“šï¬o±N:a×®Ú¿:Ut÷12R¤&v“ ‚ªHFŸå=#ŸCU‘Xà°¨±]û AP©«„äm¬ä?CU‘ø´épF?Z‘ßibt[÷ 6®RMÔÖMNõ©•Þ € Ú¬ÊHM—>ÆåÓÆlI_–FFK>J‘©(YZZr ;ùFšøFجºa¿ñ¡&¢š|"L|· € ƒTe¤¦‚K/ãòiÓóÇ#|g>|”"SQ"àp ÛZc»úFßM5WŸU×Ûy¬A©ÊHM—^Æ-G›EÇøÒš6Ÿ¶óXã¸ù‘¶¢V È U™©©àÒ˸垤gó¥-m¸†Æžkûm~¤­¨•À2HU&@j*¸ô2nù÷6Çù²´´äÞɈ¼±aßëÐ_®aûÑœ¶<H@'å ÔJ`@{Pu×~8­:¥2@* ‚¶"ý—ÊqUƸȸ|Úôúé_DnÞ"rPì܇þr ;ŒÝ<`Ëc­Fo8#¨@­øMÞ¾+½õèÕ–ƒ·­–ŸT®YbíQ.¸»f Sg^õw¢IsMœÆ¿jƒoõ"•R¡Ø´ L~ˆ© ®ÊØÌ¢\"2n9Ú,ÍåKkÚ|nØa|ˆsÈcNl5ÊŒÙx†WȉZ }¾ cI³‚SN^¼M›É¹ÅæJ5«SœUüÂéÒȹLXÿå«Ù˜akÎl:xçúƒWâæéåõÛœ­S¡Ó¨åÞèxé¨éØ{Õè• ›¢¡ØQ.~Xñã‹þŠW%mæÀϳ£«·m–åñ¥!mØç,úË5ìè6(ä7Nlµ±ψR+$î‚ô H$M]³—6_üþÊ- ÕüóÞ•i·<[F÷¾ey½—çÑæÍG¯^—ÐDèõêôb*áwµ<éÆÍ‡¯JÞ—Ñ^IÊMn êMšzóÚEÃâǯƒöÝ2/o7Š ñë…ýWd‰t5!ôÒ™â/ß¼ó®4÷ú³™ÑW”YC *\•V|þÎK÷MIiNÑÀ=œ%óÔ™”Zøˆ=4¶ÚšŒbÚL)x¨²uZwíâÝßé ¾xK£¨³Aùd}¡ÍŠ,‘þ‡ú§+×̺ôämÉ{*¼pçõIÞÐÙ“Õ/A€h(6@”ƒKY*ËUWåmœhQ`Œ`\>mÌ—ŸæKCÚ°{é/×ÐÄ'bðÖß8±ÕÆm:#^H­>_fáNþ‡hsàÊB–6Ó¤Qv+rؽ9çn¹Ê–ìñ–Æ¯Éø8ùÉ»ã·*íÀék”ß’yµ7¯«s×îy¬9>%8ýìµ{´¹*å2;|Ÿ"вÎß÷Y™–’s™òë÷]1_vŠkÈ…³jŠt‡·$ž«ÃæEººûä"ââNùÉ“¥ÑG ®=ìëLù¨ÅåŸ|3ïúóÒ²2BGö¥Á‰ù“ƒ&Jc|¥»Wá;3OI67î¿x_Z:7¢`â¶ËïKË®Ý{á'K¡Ü‰J­JW8<ÿÆ“iëL[³wÿéëì™Rç"•nd›ˆHeÍI+“Â“Žæ_¾ý¦„ /Ë»þŒ<£­3kD‚ÑPl€(— ²T–« .½ØÌq€†S¶D0n9Ú¬ÈçKkÚ|nØÉoûÐß8}šo:#^H­>]f²p§€ÃΫÏe^P4,0“ëJšà#Ýí6ËAÚüõÑÓÁi/MuG±eŸ$Ög•buïñ³!¸†üQ8«¼${HdßN‘®^¼~ÿî}©<2ÍG–è%Iö’$—&Xûç©åN”-!ýúô-U[º5ÝOº[QSšLGdãR‹TºQ]ç*/®ò£S|¤±óƒ ŠŠ?½¢ 8"ÞUm @4 ÊÁ%ˆ,•å*ƒ«ò6 P ÎfNå¾¹à_È—¶´ávž¸cXèNŸîû›ÎŠR+$Á[âÛ_ï:zuNÐŽILLÿ€clù<Ù¶‘Í¿žP%ò¨‘Ò4'©âš/)y7…ÙÙ'àÓ[‚…+·{JRúd;H ؽ“™Û€Sôl%8.ºãO–ÆØúç*• 8Ê·“-éJ¶ïöÛ’wTB÷â+¿þ>;ºh°äP߀ã"Gí-Mì L).ºuŸz ®ò.ß]Xè"?fëŸgá_ l ["bµJ:q‹-L?yeº,ÚKšÚç[®•¢YU›¿2Ú30™Îˆµÿ©þGíNˆ¸HÄꤲ¦svqüÍ׿þ8·¹|ëÞ®´œiÌ:›â½Õ¸¢¡ØQ.Ad©,W\•´ùË%ºé,—Wi3'‘ïIiM›Ï ;OŽö„¯ ›Ï Z±…$®µRþvw™Mab¼™D’çÇÄ»I2íOr{XRý;¿)Uü7Å <<|Ývn3›‰ìøé±Kš8(0Ë2 äæ"Å-þÑÓÙ²È~9ì=Úãî©ÌÎ Li¦,zŽ|;qIy”/àQT"ÒÕ'ß»f{jê1…Cž¾|ãxBå×RfÈ¢©7VÜ(œFKS¯K:xêÆÝߨ÷6‡Šž*;k(b’WÈeÂø¯_péAöIÜ(œ$y䇯0©™ø¥[RRž»ûè¹›4SyêLt¢øñ ÛaÒð}4Ó#8_yRe'*µ:ó.Uûùæ]Ÿ 9V]Ø•ûH©+Q'åš7¾Ž9rí‡Íû'Êèî7Aš0†IÅd–é#Éï­Æ%ÚðÄ Ê´Õ»Í,j” Õ[Ž6’ó|•ŸÛ ¤@Í!…¾ÐæsÃ.ÓF„?U–ï–s| öR+¤Ï—Y„³4G“½ÖÌ…ø£W=yþöÝûÛ¿½‰Èº:K¾ÃWï$ý4·ß–}çá3Š/Ú–q‘nñ>Lbé j»1¥ðνG¯Þ¾ûãíû“×_,ÜU4’ÉT9JPÆÝ—¼aËUZ¢®«¹±·.Þ~Bs‰ßß¼¿PütÍö½³äÑN’ãʇ¦‰¬$gûIr]˜¬±L ÝtyŒ£4O¥yêLJ?ÿ”ê„ì-œ!ß9Z–º9UñÌròâ-I¡ÊNTjCrÁí_½~ûîÑËyÚ &.ªðäòëð·ËO–à+KÇìñ`Ò‡2Gì%§¬$çtód5K9@¡¡2LØ©LÛª°Y¼P0.Ÿ6–Ò‹|iK®a×InáOµµÀj¦|çÊEvxŒlŸ3sBýVÌ%Eɲ¼dž² ùQ;i•s´q‘uay2é´w˜ì¨Sȵu` †ËŽxÊ2½di#eÉNôaΩ¥/“ï.Ï-KãÊuÔueÏœ¡1•–¥Óì‚êÛÊ.¨<´ÊHÙÑ&(’â«J2H©þ`g]輪2RSÁ¥—qËÿRè½ÈR^döÓqÓù¦óÒ5ÒüL³Ÿr¬dEú2@fÅÌŠ(Ï«ê R>A)ʪ×6U&@j*¸ô2n9Ú]5l¹e ÊtÊà´ê¼'¾œY¥CµD|ÚX¯¼Fê>?‚ HbÙ"  •_<[AZéCÝI8Y5"8  TyÔÔ!kŒŒpÊjmîܺa¨ªCGWWL­C´Ù¼’hS«Nq=§ 9!9v§¡Š.6˜ª_Õ9ÚÔªS Ú*jÏ›UWB¸™ ÚTæƒ6  Lm@дm@Ð! Ú€6  hÚ€6  hƒm@д1Û¶l k>X&qr´mª“6ýìí~Z0ÍïŒmøí7;¶me7ÍŸC{«âIJ´9™}´]ëV¹9Çø%ÆmÛPÉùÂüóævédÒºe‹±^žù¹'¸N¤þß›tlÖ¤Q«½{³&¶ZTD¸¥y/ªC5åÒ@miSùk´Ñ/m9õ÷ó«r Q#\é|‘(ÃÝéÌž6Ù¤½1Ý/º~ßi¥4à‡Ù3:wìдQCs³t7Ѫšè(S:·eëoZ³R/´ ÙL—ÝìZ4kÚßÁŽk+s³Å?ÌáêÐÅÙ¶M«Ý‘a"¶)Ä­L]¶ha_;[6ï¿äGj¾bÉBvÓÎÚ’öòGLŒ‰rwJö“I“}½¹r²Ímøåò=»wøŽÛѸ]ËæÍ†Q¡©:Ìm|Æ]²ðnsñ¦Lô¥Ì²%‹œûÈH#òxŽtŸ:i"׉ËÐÁ3Ó‰??Ìcok£²óÆí6¯_wætÞ¡ý™ãG{iK®muîUéFÐF[ÚWÃ6®S¹Ë{Œ§­•eDÈ&’µeï c¼¸àrèc¶q-ù|¢÷Øïš5u´ëC°›V½{iUMdz¦ß¼žêûŒmÑ«§^hcÚå{¹ÿ²ø‘“‘.Ã]† ¢BɲŸºv2¡+Š­ã2xÐdŸñâ¶©H·¹MRLÁ-:Lñ¸4ÖcfÌ(wÊGnÝÔ¶u+ÚËïÙg¬™D»X“¸rïÑö¶ÖÛC7‘¨®|êD[K‹°Mëb"Ã;÷÷rQù¹ò{›ôÔ”Î&Μ¦<ý¥É ñò=L»¦ïMaf΢) ×Iö¡,6_w²y“Æ*iÓ©c‡€åKÈÔíIJ‡k[{Õ¹´ÑŠ64ñˆç½4àˤƒñ浫ؗ5øVe'ܦ <)>–¦@m[·4íÒeÛÖmi£Ãµ­Î½êÜÚèknC0ÜÉ¢ mŠÇšxè©ÛÔmi³.ˆ±±ìMóaîúgË—/^@wÞ¤]уœúÍœ2Q7Ût¦ÍúÕA=º~OÓøn]:Ó&M´hnOöP¹¸»øå *Ë7âÇ{Ão¿©"ÚD†‡ÚÙXS¦Õž„8¶°G·®ô¸Ta'Ü&™§\ù™‚°ÍíÛêqn£î̪u¯7‚6Ú¾·¡{¨¶s=ÒF·Qt¦ õ¿`ÎÌ¡úË0§H§Gz6Oüøð"b]“qŸŸÜiÆu¢ò"Ôð?àD›¹3¦ÒCå‡ ržêçÓ½kUîúróݼªÂ¹ !‹žF•‡1UçÿI™õèN>ú9r%+–.¡Í´”ä³ù§R“FººŠÓƸMkªÌ•ÓÔn_ÊjK´éhl¬Ã{m¯muîUçFÐFëÿIµn5m¢/=¨*ÞÛË¥Ü{ûñ^ܳ-ͼG{TmtEgÚÐÁ.[´Ž”îzt¤ü:‹Ì¥Íy³¦q%êl£'Ÿq£c£#èAÞÑ®×I›–-6¯[­mèIªU‹æ?ÎU<Í-˜=³yÓ&쳕àX¼ÇxÚY+^,È6¾¿¼·±ùR>c²/U#«¡Vû9VhªÎŸ·‘Ki®H“®ä|a>ñ§‡iWš˜›õ Ù´Aœ6Ë–,jÕâ;n“ÊhvÔ¬I#Kó^;"·éò?)-¯muîUçFÐFÛÏÛû;صhÞ”žsÍz˜rŸI ™äH×áì{{ÊÄ‹þGFgÚè6І´ˆ ~ZL÷©F th×–ž˜øÝÒwîØ›ØˆØF×›¹YšáÐóûìi“ùïÉ:˜JŠ!«èâ§<ÝF)Ïÿ˜àOô$ئU þ?MÈ6סƒÙrßqc¨97g£ÃìÒ©c“F iòFŒšjHŸ%ÖöÚVç^unmðYbÝähg»hþøØóÆ5A&íñÍ|O ´©…!Lw®¹3¦Ò=‹û'x]¤‡›KTèæðÍl--<Ý]Aд©…!LæŽÆíÖ1uú+]3&û¶oÛš\‡ŠSõñ3дmð­LüâhÚ „Aдm@дm  hÚ€60´mªŽ6´Iuqár¤êLUÚ`‘t‚ô%Ђ j{zm m m ‚@‚@‚@Ђ Ђ Ðæb-[ß‚ æMÕYÚ@h#„\ß‚ ú6·©©õ!ªoïmjj}g‚ †6Ô„[¡f×w&ø&AT¤LÝh#ø=“_ß?‚„T«’~i£á¿ª}g‚jÃCSÕѦö¬ï AÓ‚ ´ ´ ´ÑŠ6+e ÕN!ê Œ6øg_mKepëD½áѾ­Ubi?€6  Ú€6  hÚTµŒ>&åÓæÁýûÜC m>|ð€Ûü®YS6O'(1A×7n\§‰ ûä¢ßZç´©·sJ4iÏÉÎfo£Ã†Ñ9ðµº?Žöô¤á¢£¢–þ´¤>ÓF¦§§ÑDâýû÷“üüÂB·VÅ ­ÎsÚÔgÚdd¤tw£Ì—CYYÕ@š»» LYYÙàÎÙÇŽ6"›ä%š¢¬X¾¬‡i·’’’ª8¡Õyî@›úLºll¬­âbcílm+3ÍÐðŠ}øð¡I‡ö—‹ŠØMÊôìÑýùóç Èæž=I´¹cGtÐê¿$ÿôé¦Ý”{à/ÎÚ€6  VxÑvÐmááôÜwâøñ=ÒQlX¿^eÜâ,  hÚ`…m%HqìëЦu+e¸ÿªP¿8KÿÄ1¢ ~0xÚ !ÊàдA”ÁH ò³VxA”Á  æ6ˆ2ø ´AB”Á  ¢ ~m@Dü€Ú !ÊàÐ+¼ a…$ÌmpO‡@$DüÚ€6ˆ2ø ´AB”Á  hƒ(ƒjŠ6¹Â‹µ¥EYYWBy+‹Þ‚&Ö¯oܰ÷»7ÚðAýoª4Œ2în#øf|ýÅ DüPh£.Ay*á·õ52&f';å5´A[Ú°£Ó´ê]I hÚ€6†ºÂKÔöíc¼¼ØtÅo[|ëMZØSô—òÅÅŚؠí{6³bù²À€Ð´m o…¶¢s'“ÄÄúËBƒk»|ÙRšØ Ã܆}ut°ÏÍÍm@ÐF ut…®ÎºµÁM5\¿n-¿œÌp‹Ö)¦:ÅÅÜTGÜÝhþ ²²èýòåKдmT¦:ºÂ‹xøïЉñòôì5Ò}÷®]Ú 3m(…n ™>m*hÚà½!­ð"þŽ}²ìÊÌÌ`_R‰Û ÕLJfºiÊÚ€6õ™6Hˆ2ø´meðh£ü‚^eðhƒ¹ ¢ ~@meðhƒ„(ƒ@ÐQ? 6Hˆ2ø´Á /HXá s$$$Ð ´m@$$$дABBmêmþׂÿ endstream endobj 637 0 obj << /Type /XObject /Subtype /Image /Width 378 /Height 194 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 173 /Filter /FlateDecode >> stream xÚíÐ1À õ/­1ô€Ôp Ä_Õ+øcHÆ… endstream endobj 520 0 obj << /Type /ObjStm /N 100 /First 883 /Length 1669 /Filter /FlateDecode >> stream xÚÅYKo7¾ëWðØÊ%g†C0ä§Z4HrHk䇸M¤@¶ôß÷›ÕÃ’µ²)gÛ\¼ÔîÇáì7ï5»àR¬N—äJq‰’£q%Ç¢¸²“e§Q‘8U{^\â"U—¥Lûr%9¸Â¶O û÷BHXÉ Í¥Ø!‹É0ÑB Áá4Iœ]L5ãQq1sÅ¢ºX vI€¦P/Itg AhÅáéÂ&G°(À$`RƮĎ´˜ÂÀd¶G“3ŽHÕQ &°8ø“’:Žäà™ATÄë0«Ý1~BÁK"Üa,ªNRÂÓ.)jrpœµšvŽKÄv¨Â@_\#\ñ ɵb{õ ,Xä2I991SV,ÔÀÙ E;Ëx¹TÈ Ã zK 8¬JJS°=^àDÅ0£:lÏÐ%Á$g“·(´@)fò 9ÕL éRÅ$Û¢£0L0³ãG f÷j.E2I"LfŠ8ÔÌIÉÀ¸ËÁÀfWØJíC5(® æLXôVÐlú' öÁ,0öþÏ£™³Àp²½á‘Ø1 ÃÅ¥+ X '«Ýe±íЧO4âQ:¸VóíÝ´ar,& 5Æ¢Ã`C7AªÓ wPˆÈÆ“áâ“““I÷ÄDÞ ×½þý˜Î+h‹)yÊÕÍ®>}z3yðàV,GOˆ¾ìé|véNN\w )y¹ç‡—~ P÷ú·wMß/AÏ>›¥V°gŸÍZ¼>_Ìß¿œ^º3×=rêºWÓ¯—†zûqúØm|õÏ—)¸9éãðéìò–íÕt/¦ó«ÅûéEŸ ú[¿N?œ¿}4ÿê΂%žj/¬®Hô¥¾Á©o­Vð§‹ùÕü\ |8›ÍqÀYŸ›LÓDKo(Ôã&ÝË«w—ýï_ÎgOºGóŇé¢?8¼é~îžuÏbÿÃT)g£_š!Á¾&ŸŽˆ2/D@=ìy{麧óWsÓüðçùÇ«ÅÔ³ç¶q´È87—k=jð–t›ôm=Ìwà¤ßù ïg[rñm¼r4%öUš b_’Z°ÓX±K\}Dô¶`#\©Ö£âKp F,wÉ:Fúü5JŒ0ïÅÇbd‹¦mË«gÄúAËoƒ×æLÁgjÃÆ¼*5aKôVc޳²y\­Q<8Qƒé¬g£XKö3šÜ/£]§0^¾¦µ5Ëk]^%¬®qu¥1S0_AZ†CT8*ç”}‰q0¹\\½»ÀæóùÌ“×Ý3Ž6ªÉGÔñµ6(«-ãwÒuÎ\7Ú zy´bßIQ¸Z‰ Y“F>kÖæZ•ña.žûŽ}©Z]T“ÿ_*ê- ¯ÍCÕô‘óðÍê(­ÕñÎ…Òö’ÕÁ¼sG¾Y¦·|³”ÞœoÒ]ÕaN›ªÃ6x•Å91NÜ›¥0:ÈÝ6¹ÓjØç²ŒÀåV*—U O:n7Š>NFúA߇™Œc¾Ëœ,oïËxqÇš½Mš—<ʦWo³Æk4†r»õfÀ¥zD;º ^¹]F6´ ½ C2µa™^Nš°G©ZÇë1Qb¤ŽãìuÏÙ5›8´‘8¶Á›)ìqiÃæeíkÁZ9Š$mØ@ž95a© ì¤6¨Õåf”Ï¡ii«¥ç¹ ›²mXýF«t»NmŸdÒæë‚}äÓ4Š—ýÑ©Äq}¼ÐYªì8j¹qÈ¿†°Ñ¦æØ„Mµxûtׄ-Èh¡›=5BÑš35ª‹¶ž‡Âw›På‚´aA¯H½˜@½mÂRŠH!mP ¼öÍ·Án¬Ø 45ÊeoÎÛ„ÅÔ`Å›°:0¡¦à•Ú¢"rõÚ¨Ÿc›—Ř}n5EPŸk›GÚ*–ÿ(9Ú t“ûh#9jØk4Ü«¸æÆ¾²7Wüðú[Ÿ zÉ·0¹Ó;Ýc Ò˜öh‰<ê`-ñ˜Í?†íR‹c ½¬ö_î9D?‹ Poº‘n´Ýºþ„ÙRÐvÀë† M¿ ´A¬5 mKH¢ßð1ð¶¶:Ú¿“t”°¢½žC騞C×ÿ9Ôs(ñ¹v|—‰†°‡L4€¥Z1~òxÓbQ#bûf)#›åˆu¼1 ä–ƒÿ R4 endstream endobj 642 0 obj << /Length 1609 /Filter /FlateDecode >> stream xÚ½Y[“›6~÷¯ ›‡ÚZ«eÚÎäbï4“̤Y7ÓL’¡Ä°^ Œ³»ÿ¾Glƒc/qžÄ¹é|ŸŽ$ÀÎÌÁÎEïé¤w>ö¤#‘T8“+ÇHHæxžq&‘ó¾{w‘†Q<R÷ça¶ ÓÁÇÉ‹ó±4SšÜ§È'>ØÕJÔyÏs•Jo4é}éÁYûEæ:ÓyïýGìDðî…ƒ—¾s«%çŽK0¢L@;u.{õ°#骦z\lZfÈÃÜñ¸„K•e5N‘ô¥C”´tŠØ¹jµôMû6òºý*ÊC„"GÁ6.Ây|„|$YRASåvñÆéUSãW5à*!ž3$ÈÒLà—6C.b¾³!³Ån³Œ" É­Ym5 °ybÓî®E$fìÛD¦y¦ˆž†Èuû‰Ü5ØV"3Œ0¥&£â!DÞÅš=Ô,ã»2˜–E†Öw/vpõ <}U ½‰mœC4â"¨{2¢Õíw$Z×`[‰F$ÂêÜ£8ãý¢Á".ƒ›"¿‰‹2‰w• | Š˜ÃaÍ;ŠuûQìl+ŠØGÛ£‘ÿCPŒò ïóeÙ@H2ò]ÿd6ìw°s°m é!Â…ÁBþŸ&Yt\>ªÆÞN‚ÉèŸÉÎFû>rä$æ÷àçônÚ÷Æc6B]+¥<Ñëö;½k°;ˆNÇ•eðX“–`{ÿ®ñÚVñúÑ~(ã÷QÌÝÿ¸k•ðô•ód˜ÕÌw„¬c¨íˆy.¢Ô·ˆ‘ʈ‹ˆQ|uJ­+úW¤=Äùg»ö.òx0$}ëÈ»Í'°ðx¿Ö«ûÝwÆßÚç¦ ®Ã,J㢩øÇ¡ÅG˜‹ñɈ\·ß‘É]ƒm§²€Ý¶º¨zà>[«G7E²Åsùسnq­• »qÖ¯þ}ÀFøó~:fùa%ó›4žÃ,â­SÃOg‡rÐ5wÚ“q°n¿#»ÛÎAH³Ÿ¨{w–®=ç—ËÏÉM×S:÷fl[(á6-‡×xnÃÇ|ä ÞüzÎøz®s C}‹råæçU²íiƒ!ŽDse ô~–뿞ß] (î«Ë)ôq¿º¡6~.`gH9bÂ5†'×öŸÂŒéUym:°’M# ¥i•á'ÓHæ™Áf`¥>PÊTðä ס/o¢3›°(¨±~ëO€²Ê2ñ]äcà0\aÓ';€Áì15"mý’º¦Ã<ŒÜjøüÏ9ñç9dÿÊǰr2Üð²ýk†H8º’ ˆ»ö`1Nf˦‘!âÁ6Ì`®¯× ô««¼0x@Üþ]Y„¦;Í«ÿ:«¬5$Z>9¬¨0$Lêp†Œ"Ìù&´¾ß_ÞN@S%Þ¶Š\9ùšD:>)+ùðS’&å½Íí`­I™äY˜š¾ Zf‚¾ì—À—¦s›D³Ø:Ñ †œòJÖWå9‡©e3kÝ].Ê|nÛ@Â…U›\'6ZŹ‘M‘BÓO}Ž8Qº–ã·IššD~ªEwKKɲZÓ¶ “3_5$ù²˜n,›´ ŸÚ›jÜζšTOÆ6ñd¼¿Ì"'4-žÐZ¨}.Qáh<ÕH\Ú¼BGû§Að±ÂÐ eoÅ4H8Ãnÿ‰†Þ”•w+rozª X¼!¨²kàÞVÆtÂâÔ5Sfò²¡Ù³fL=!­ 4Ô4u:0p™M7UðÂëU¦sû.Ée˜M­–¡34T”ö&'6º H@9°ûÖ«ðîeœÍ >nWT.‘Ú&­¤©r‘YfrÂoóÅ’rõÓö2.÷y aYó¦'+,=ìŒÞ!ý0]ÆëxÖ™‡Ž^FÒK]àU¸6¯kz®u¬‹w`(»4ï¦aV+G»þ+sØf1Èoåÿô‰×h endstream endobj 639 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 654 0 R /Length 11373 /Filter /FlateDecode >> stream xÚíXWÞÿݼÛ÷ÿìóî¾ûvkìˆcԨؕk„Ø»öÞ!ʽìb/1VD (‚€É»éù§šêf“˜¶ÿŽãܙႠ€ŸïóyxfÎrfîùÜsÎår©R¥ 5»O€JL•;‘åá;¿€JŒ¢¼"{×µÿ*1 ý#”Ž^|ïù¿P‰ÑúÞ!ìRé°<·yзÁQ ým®à6(R¶—½J­e×DVó.ój}o’©Å³J•Û,OOOuÇæv6›°£ËÊ·zlüÔdËæ;šMØ¥«@q?Môa5ïR9¯Ö÷¶‹NkÓÿs›‚…¢"Ê«;6ººëª·zmúÔuº­|³Ñ°Uº ”÷ÓDVó.•óÞãûâ³ZŠíû [íµùFq‘½t(#>¬æ]*ç½g<œ¡¥¸¾«;º_ë½ùFq‘½t(#>¬æ]*ç½wþ~N‹LÉÕ¹¹ÅÌ]™ßËOuÇÆ#7øF¦C÷úà¼ì¥«@B¹¨Š[ÿGí¦6Ñ"Qš¨n_‹N°t›·áy -³8¯Ö÷g^8¯E\Vûn‹‹Rúù©îØdôæg£?Ó¡Ûkä†Kº d/]í.·~üùßF§¾×iY–ó–¥>Î%cÃ÷?ÜŠ™UïÁÄ•Ý]¹iÚPŠ·È°‰‰ÒDuûZ¨¡mä†Íû~꬞ŹÄâ¼÷ø¾ä‚–bû~gÇ&cczÇ|¦¢l& £6^RQ Ud/]„;Mâ€0sM|Öµ÷d5î»í¶|¨µÒN³íœcßê³,õWæ¹Õ—6¥¾ÿæ'ßZW¯T®±twW¶)ò¦ÉAœ&×+W-×^²ê隨‹(MÔ¹yk¶¶…ËOëæ}ŸuVÔ.+g7;ï=¾/ÍÖâ¢ïÊh_~ª;6·µoÌç*Êf£7^².”½tÔ&1<ìˆ0eõ1Y½ùÍ·ƒÂÚßytEÒ;Ÿ|}ëyý_šÝaY¶¬¾}ãÛï~ÁÀw«’ß•í¡–Å¾õö§ßþðÓ/òhDüÛê‰äh¶„·ßø¤`Çw?û.*ñö÷ÖA=‹.Úm¤†>ËÓ,5~Ë«—Þ½ù¯ïúþÇŸ/¼ùÕŒ=¯;_²‹<•¿2éÝWÞÿ—œ÷û~μþɰð£jMtÕ3«RBþ åÒ”ÍVWVãó>5<ˆ‹¾qíƒoä¢>½yKÎbVç'ë®ïËÓ,Ž? 4ÙyË´W¿¸õÃORxõý›rL¹ź{º&ê"JunÞº¶mXnؼï¿Îº[-gÔUFw^­ïí—]Ôâ¢ïÊ£òSݱYÀŽ~/~®¢l6fÓ%ëBÙKWáνÍ74]Vû¬ÈW|ŸjÛÝ}y¦òhæ•wü#ÏŽŒ8:ÎvhõñÛ€ì÷W&¼ø†,G§ü³ƒæPWÞøhØês“×$_~ã#Y]ÿšr¢ÈÄ‚¦žöÊÇ+’â3_“åõ‰¯·_š£î¨=‹Z«É¶½ã"©Û(ˇúà‹ï ÚüÁœÀÈ8Ûž3yo|Ú+ô¬óU[÷vö›_ÿüË/"oÆ«Ÿ¬9’;)êpmßÛ~¯å§µ7M­žY•º„ç½õñÍŸ~þyÎŽ¼ í¯ýôó/o|t3Ðqd`Øq烲2¹à†ç¾õÅÔõ'§®>vââ›Ê3ev‹ o£²‹†[N\»-öLîkï}ÿƒTü—ì7¿’;ãâ=Ô5QQš¨sóÖµmÃrÃæ],Ì꬚(§s®‰î¼÷ø¾ûªøIuGíYÔZˆ8*HÝ´õ´8ÔÍï~úñ§Ÿ#w&8ŽŒˆˆ;Öv¸sh¶áU+1»'ç_ýpúšø Ûþ€ˆƒâΈð£Ï‡'ö ÍÔÞ4µzU³!ëßßÝúú›o¿øæÖÍo\¸1~Š}ï ðDçƒ8×DøðË[²Ù’“mû ¶´ÅÉu Í2»E†·Ñìà†Í@-”å¡áñ¶óÖÉ»þná[Ua§­eØD]Di¢ÎÍ[×¶ Ë ›w±0¬³NF³:«ÜóyÚÐ|-Åõ]ݱEÐÞç¶|¡RØ÷mºl]({é* èÞ¯{ï³ï^>óÏÙQ{'Ú÷ù„UÊç:¶¹ÝÔ;†æË8¹ $r÷[’¯­ ÕýðÓí/u +œ-.\±kxD¼wXFO[žòè$û¾®a92Â×]—ôz“lûº†^p>‹ZòlØm=•‹C9ß»õÃR"ýÑë~3kÏõ~é½ÂÎY\õ8ÛaÝ£áñï^çc9‚*ûµVÉ÷‹<Û54»chžse”‹*É^±çßQ “³^ŸæØ3–୹·êA ‘žU6›·bÏðð8yF:‡æø„évÞâYÜF3 ·ìn¿|èíS¯~öÝíþýµw>z9)sª}¯<›ÖGsn¢.¢4Qçæ­kÛ†å†Í»X8×ùn#ÙtY]6¬³ŠÅçç‹íû[LÚ7pëZÆo¾¬ÛK)Ômd/çÏ «Oôdû¾qö#B ý` ýРˆ”áYꣽÃO{†åËöï^0`Ýt Oø©ë®*ýû,ûNŸðÂÁä–#}ÃÓ<Ãr‡l¾^ÐÍÝør–c§wx¦ÒO…nÜ?ÅþÒxûaa†cÏìÈ]òÊà|–»Í/üŒ®žRbq(ÙrLä±Õ»ÎÜ/ÿõ}Ïðó†–žîØ#GSPÏ¢2Ò¼þ`ljÎ[|®ÌßÓ¯é|ÓÔ-ª4"æ5y!ý𳛟|öÕ?þºõxïð3žayÎ1D9räÖXyáêžgQWn£Î[¦]ÿR¦3Rxýƒ›ÛN\Ÿ¹>q²cŸ\] ý@‘Gsn¢Í[»™ÒD÷Õ6c³rÃæ],Ìê¬zdQgÃÏÏw ¿¢Eë{HHUšU©2¢ÕwuÇ–SømýB‡î6J uÈ^º …OtäöQöxa¤=a˜=i`DZψOÍ£½#2”í£O},%¹¯]•yèbÁ›–GR/Îtì~6¢Ð÷ëo¾?v]f¿5¯fþó¦¬îKÎR]sâCY½tý­ik“W%­8páêÛŸŠVÏFd8Ÿå«o úh[Ì!µD»Å¡Î¼þõ”W‡9RBwLFn|qs¢ý€L¢/ÜÏ–ª\² žE¥gDös¶ôQö„ û¡%Ññ g®|pãëA¶³ê™Ui`Ôùw?û^ÄY¾õ¸m[¢ŒväåqàŠ,ò*åÙìßþ `Cæ³+¯¾|á†+·È¬Ä ç-ßúô»}§ß˜¿ùDC^ÿŽ·ejOéqº[D®õÑœ›¨…ïÚ†ª4ÑûÙ÷~0<¯"»s¡Ùyïñ=â-÷öïUtÈž^À]ßïìè1íðóÛ¾tfBô-ºGe/]„;OôŽÞ¶LWíl¿zèÌë7¾øúÖ?½÷ù÷;Òþ93rïÇ!_[ásRÆûŸ~%-\Ýzüštsö#>¶ó²ïÆøü÷?ºñí­ÿ}맬7o.|ùú{ŠáY¢Žð¯¯”ÖÄìPs¼sí½/¤?ýæûŸ®¾ûåê]ÇfFîñ8ç|i®Ð)â²wÄ?{Úh{¼4ûi‘û¼lÙ†Õ3«Rò+_Ê61Çò§G¾4Ò‘°9¡`äœuí.ù†1dC\Þ{ÞøîÖ7þõCdÒûòBäÊ-*òÉÕn£úP ãðÇ‘1ö£ÃìÉì§{DätЏââ­sn¢ºÆiØP•&z?ûÞfçµ.ÔWë»§íš–âú®îØjzì m_ÙKW…‘/ÍÜÙÛ~ÎÅG½íÙöØi‘/ÝnãíGüíi=lw怑;ÇÙD pÄEžëg?ÕÝ–/;zÙrÆ:â§:dÇCãq#íIƒm)Þ¶lóȣ³#wËY±Î5±8Ô Gúx©€#vBdÜ$ÇQÕ×–exi®ÓÅvÅ×~A.Ó×vÁ¬zfUdO“ Ù¬Ÿ=£‡=”㘌óG;Žu²]u>ˆ!^ö‹cìrä}Ç8âÛS{Úr‹¼E®<¹ ãGeË)‘ûeY)ïo?;Ð~Z®«³í•âÞ±ûi¢¥Û¼LUîñÝþê=ÜóyZÓñ¼úûwuÇÖ³FÜqÜ/òLw[ž”«¾û9ÎøÙÓ‡Û“åÑçgºÛóÕ}{Úó:Nw¤Œp$ qœìë8ßÍ~Åð,½ì¹ƒ#ÓF:’ÔrÝ6f‡êa¿$‘”t$K+Ûwu\5¼´ûÁ¹zfUêí¸0,2EÄéf¿¤l3Øqr°#ÕË‘kxCd/¹ÏräáŽäçì§»ß>T‘·¨È'W»ëí]á~šhé6ïSg•{|w¼V*´ >Û1$Ã/æã¡;¾rÿ˜:†œmœQZ0¤Ð÷¨ÒÂËôD•ãZU„ƒ—z}XÍ»TÎ{ï÷Y½^*xF^o÷¹ÖóŽ·ž›ìóRÚ½ÙÉq½´*`ÆŒ¨}ó¢vö‰Ì.ëUJ¢â©/Ý&ú°šw©œ÷ߣþY¹ñÊu¼OTN¥¿Ò²»{:Jëf–éÁAEë{çoOÏK€J†b·Îw)¿v9 ²òŸò”yáŠòø”ìåª>UªT)¾¿ÿÎ[•• tuTµÔ)W¾oZ³¢<ø.·%îÀK•¹ÃTõ‘­*¾?R¾ÏYQZ&UÅw|G"ªŠïøŽDTßñ‰¨*¾ã;UÅw|ÇwªŠï÷CÕÇÿï´ÌòSUiøŽïø^ɪjæ5¾[K‘œï÷Ü€†õëÕ¬^­“g‡MëÖâ{ôºÕ>½zÔ¯S»FµªmŸ~ê……ó*‡ïeáB‰{[‹ª6¬_÷ðK»ÔUŸžÝÔåC/íjX¯îžm1¥~%«ª²£Ž‡8\±ö=%)¡q#·%Á‹ÓO¤\º˜}èå—üxÄ}q÷úõ¦lÞ ­n#Â׫¾?H‰¼{taÁ\eù¥[ª=ñøÞí/*«‹çÍ–GËb<?¾?”X߇´pÞ\ÇDÿIäÕ@YUÊ/çæŽ+ã)Y´Põý•üÜsçx4oÖ ^ÝÑ#†ç^8_A}ïëë8n´áC¢ÿÐçýåÕ@µ’›0kê¤fÝe<Ъeó¶°ù³¦·hÚ¤VõjíÛµ‘ÑB±6³<Ëä¦înÊö›V¯(•–³a¼ É`¦î“µ|zvWÌêÔ¾]ðüÙê6òÒçÖ°þþ[-êæ|"ë.Ï¢ªK/ìÕ½«²²Hv_²PYíÞÙSÕžñȾ݃ýHý¥J“&ŒSË¥nƒöw.?º£›º7ªWûÉ}ûسã~ªjxWå5ªAÝ:ûvnÕ–È EJ Ïnöä:×ʺ¤ÍS²l9wÆÔâú.Φ&'>4gæôg½½N§ž¼{õœ;k†R>oöÌ‚ò´“J¹êûÒž^½NOºyvøÁS&UPߥylݸÎð¡q£†wíä¹#f“ÐÙ³ÃøQ#Ô'«g·.[7®•§/hÜè:OÖòêÞM¢¬vêðL±6³8‹Œl·m^/ÛŒÙñ™¶¥â{k–‘¡KíÝ):ñè׿¯F,}¡UófÒ8•müúõ0Öºn†'*Y§»o·¼¼ìÙZ0h=l¨8>jè`YÞùâ&·õåQí‘F*ÉCJ•Ôòq#‡õèÚy×–M‚A-ŸÐÕ³ãÖMëľ~½}F ~¾,úwy©Qî˜ÂÄ€1ÃùYŸÝðÉÕ\nË’…óå¥L^åI)®ïÒÑäçd>äѲEbüQeùØÑ#­»Ù“kX+yjÂ^X,S›’¼?ïî¶,$X&ã—.fÞ¿O}~öŒiêüÝÇ«—LçÕy}oï‚ù{ÚIÙ@õ}ù’YMŠ»œ›“{xˆ¿~¾Aý©Ad>Xðþ|¤M}~ìˆaêìUúD™!–…ï%;K‰[¦\ìÒÅ åJeT#WªÝFº'Y;óîûBfu“ñ¶Ì:eî)3S¯îÝÔƒ4¬WwóºU%ó]ÆóÒ‘-šS0§X0kFíZ5•¾îZÆ.Ós™¿ R7ím¼;ïr·|ú¤ ²™ÔJ^Ää%«·×}VÕb`ЪeóS‚ätj‰ÙÙÍž\]­úøxËk—ì+¾7jР¿Cýô¯_·NÍêÕ:{vTÿ.cõ €ñÊûó² Žáåe!`ìèõ꺻5Ô½?¶l‰ÌâeÄÒ¾]Û˜M*îïßåûôì^·v-™ËË4Výý» ‡øTÞ–…C–ïN—Ø÷’¥Ä3Ͱ‚¥Ó©^­ªÌ7eÜ®=¬\¸ŒÕÎÝ¢nÒt¥SÞ7ž5u’öÍ1¹%¨ª°g[ŒÔJ^XdYúDYÖþÚ]÷>¼ÌGÖ¯«}^êæ? ŸR>aÌ(Ù]íå2e- ^02m¹ÏªZüþ}ÒAKG¯íš Ïnöäêj%Sy²ä>·yÊ#2t)ŸŸçóu¥øI0¯î]Ï›] > ¸quT³Æî|¾ßñÝé†dî,ú+¹Šèû°A~»·lÞ¶yCWÏŽÃûã;¾ã»Ùµ©{£uQö ýQ™,7vk ãyÿ}Õ·ñßñªâ;¾ã;UÅw|§eRU|ÇwZ&UÅw|§eRU|X¾ÿ‡JšGöÿWÊ ‹…ïücA€Ê¾<"(|Àw|ÀwÀwÀwÀwÀwxX¾Ë6*ÊGt´%P!PÌuÅwݧù4&!+Åõ±@…Éã;¾ã;¾¾WÔÿ÷á öímíáQ¬]JëÔåzßeß{vë½q}YŸºT”,Óƒ¾ë•ŽrÛãëìõëÔ¾t1»´ÎU±úw^(ðÝÂ÷ŠÒdUñîÿés…òà{ÀØÑ+6u5Ê!%Ε”…e!ÁÍš4®öÄã²z<1Áà€†õëIßê7 ÿ¹³§|%ï✙Ó[4kR¿n%Á‹•Béˆ'NPþ_§,¨ýòåÜœÀñcå€R®û æÎñhÞ¬A½º£G ϽpÞâV[_W³Ý•[XhËfMŸ¬Y½[—NÇŽÑݽÝ;¶y¶F•m"máºúücñ¸XeyU¤CYå?«1»^åÿ–*åÁ‹X߇’µ%( ß‹üM9ñ]^¯Ý6¬]-Ëë×®’å+¹9†½ÞÀþýΤŸTVÛ·k»wçö¼œ Ùç2‚Æ5ÒùÈ çÍõêÙãdRâ…̳“ƒ&(…ò  þ?nï^=çΚ¡”Ï›=³ <í¤R®ž}iÈb_¯^''ÉA†cêù)Ëf¤8nxØìó™Òo:—?åÑRíUá|Lñæçd[Ê‚¬–«gÝ´/PÕN¤­ªÙñuõw}þ®ç^û¡2pkP¯µ‡ÇöctG»˜uN¦0ÊhkÌæî·‡R¢ŽÀ­¯WÊÕ9ˆ+÷ßñ½¸¾Ç9$tôÆõÍ»ŸH:¦:Ïsu³ÔUQ‘Yg®äçÊOÃ#‹%ëße¶{·_{ª• ­]ÏÊ¢7ÛÝúJ}WWѹ±»›óe#ó£.þR9Zi§üŸð½"6õžÝºFo\_Öõ)%ËôàPQ|—§[G%î J½þõëÔ¾t1»´êS±úw^(*¨ïÎS\êõ¿Ïâ;”߯Ž^á°©«QŽ)qȲàfMW{âqY=ž˜à?p@Ãúõ¤×óÐÿÜÙÓ†§ ^´ÀÝ­¡l0îrnŽá¡¤Óœ8¡q#7AÔ>Ôl÷WòsÌãѼYƒzuGž{á¼óa ëo½ûîÛ<Û?ódÍê-›5´…[ ¬ë¬½4³Ý•[X¨œKÎØ­K§cGèêi]ŸV-ãb•åU‘eAJ¤\{¹iãÇÊ ”z†,Z¨–K…åYVÊå&[ß„P!|—&Ñ«G· kWËòúµ«dùÊm³œû£ýûI?©¬¶o×vïÎíy9²ÏeŒ;j¤áéžõö:vR…y³gjÎÌ雥ž¼{õœ;k†õîKCûzõ:y<éBæÙáCO™dxX³þÔl÷&î6¯_'"¤ŸH;r„õݳ¨³¶Öý»ß€~©)ÉâÔü9³{tí¢Û̺>bqDèrY Ô«S;ç|¦,‡/_&/ŒÚƒÌ›=³ðÞ®§Z.õïÛÛWê)ôöñ.òæ`zeš¿gœJkÕ¢ùŒ©Sä§,›µÏ´Ç ›}>Sz4ÃÓ%ÆÕu=·òhÙBÝLº9íf†»·iÝ*ùX¼Zséþ kæ»ÙîÍ›6 [¶äÔÉWÆ´u6»KÎõÉH/¼ÕyÙYµkÖÐmf]Ÿ7oâï/ ! ç»7l  ûûm‰Þ¨=HÁ0@SOµ\ꟜPxdƒ"o¾—ßuѱ~Ö¤‡’G—/¶hŸW/å©«±öûxõ’QŸòºQ£ê†-³ÎµhÖDhmÙÜýöð@JÔ¸a=µåêD[nqoÕS+ÿ€òöù:í÷ØX¿JÇ9$tôÆõÍ»ŸH:¦:Ï@uóÇUQ‘Yg®äçÊOÃ#ßÓAÇÕv‚ÚÍ\êß5»·yª• ƒ‹ʬþf»+ˆ­¢Ocw·÷ïfG¶¾ŸÎ¾Y¯ž=dÖ¥“§,ËϘMdÄ®;ˆ¶—1RÑý»ÉÍÑUž¼=ÈOÖ•øïe [£ôÒGìÛ½K–e4èÙþ™•˲Œ“âãÌö•½qƒô©É‰þ˜ù.sCe. ÚI®v³Ù3¦©sa3ÈÔÒz÷åKBd{©ÛåÜœ„ØÃʰÖù°fõ7Û}èóþÒò¥Püjêîní»EÍ|·¾ŸÎ¾YÉË볌ùe9té òмhî R1õJ…Õr©ÿÝù»¯O‘7GWy¨g89lHdÄÝ·—…1\yë¦~Ý:fýζ˜hé jT¯&cHirf¾+o°Ë°¸1Ú7±µ›Éx2(`¼ò^·,¨ãO³Ý_ÉÏ•3ÊL³VêòJ%ýšáaÍêo¶ûº5«äŠd +¯x{wn·öÝ¢ÎfOœõýt./²>qGÕ¨V5óÌ)YÎ<.Ë2NÓDy^n ÜFíûóRáqcF)å æÎ‘çÑúæè*ü=lYÿÂÊéÇ[µhÎ}Àw|¯ÄLš‘ž–vⸯW¯É¹!øŽï•™ªË”_ÆócGÌËÎâ†TbßËç[‘ºÿ‚ñˆ¼Ëÿþ€à{ùüDA9¯ä¸j|ÇwÀw|ÇwÀw|ÇwÀw|ÇwÀ÷2ý훋¿VÃw|ÇwÀ÷ì{È¢…5ª>!?˧ïꟸ5¨×¿O||/™ï¯äç¶jÑéß•¯€¸fùml2ì?™”(V.š?·^ÚÏõ뛚\¸êÕ³»²™á—ÔŒ²p¾zêà…ó'M°8¾Cò],poØ@ùûnù)ËÒ¤•‡Ì¾ͬüÌß…&îÔoh±ø6¶³é©Êr^v–ÙWÉ~‰ôþ-š5¹’wQ–å§tèé'R,Î…ïP|Ÿ6y¢î+2¦O™¤v,.ö±Çûãÿ˜}.Cíˆÿú׿ʖ ±GJ×÷¬Ì³úÓŸ¤ò™§O)%§ÓeU /Ü9ûÜÙ³¤VR%¹KÏ è¯ÖJ{'uwU»jqð´ïé©Î¾÷íÓ;ëÎÿY˜7g¶” 28+ãÌAÏ˲(¯ÝسC‡ô“)2TY ]ºDytñ²ÚÛ×G5aü8YY¼Ðì,ºZuëÚUVƒïüO«ëÖ*'*‹ù»ŒmäàÒÑ+«3§O+ð ªn0)(0îÈ¡¼ì Ë–„ÈCƒž÷7ô]yyt~Èâ>à;<Üñ¼òè©ÔêöÒkKIÚí¯cM=ž$ËR¢Ý8áhaŸ+ ²Z¯n]eU†²šwíöÿ†e˜EçûË{wËjýúõ”Uo¯^²º5fsYøž’tì¿{¬fÒí 5jT—Õɉóýü\©Æãw¾òNç»ìex9÷ßáA¿_W«Öä‰AêûuÎsÒßÿîwRr97çÚío§”eØk7ÎϹ ¬J¨}TFźú¯ýk³³8—´~ê))Ù³c{ÎùL9fà Êîýù^=zȹ^ܼ)fÓFYUõ¡—vïlÛæé¿ü÷Ëx^©äcw¼vÑw‹û€ïð€ÇóE>*_Éú÷jU«ìxâ¸+gq.‰Ù´AJžõñ ]®¼KPv¾‹ÔrŠîݺ*óˆ}{v©U}â )Ù°vµ¼âÉ+Ùœ]y5PÞÙKÖ>dqðÊ›ïS'O*œ¿gžUæï2£×ÍßO|mûIÏŽeU&¹Ú‰¿w¯ž§Ó³ÏelZ¿®]Û¶fg‘TJŽßù'M n JçØ´I“ÿû·¿YüưT~ÿÞ¢yóÿº–-ZhËÿþ÷¿KÅvnÛ"— \¾¡ïÊ =Êa“{ß>½µYÜ|‡òæû•¼‹S&M”^^ö2øŸ;k¦þýùeK4¨¯¼ù¬{'ÊÞØÝýÿüéOB‡öϨßÓî|–Å üõ/Ñ•GÚ#”yÍ)ëÏÛ¬^¥œK´å;¶n‘«ûÍo~#Óvå7CßeÞ!3¹EuëÔQÞÖÓ^ˆÙ}Àw¨@Ÿ¯+ë_@_ÉÏýóŸÿ,“÷sgNñyZ|Ç÷JìûÕKykW­tå³@øø^Ñ}âñÇe6íѲ¥ú;z|Çw|çïeððßñßùÆ'¾Ï ©þR!‚ï„à;¾‚ïøN¾Bð‚ï„|'„à;!ß !øNÁwBðß Áw|'ßñ|'„à;!ß !øNÁwB¾Bð‚ï„à;¾‚ïøN¾ã;!øNÁwB¾Bð‚ï„|'„à;!ß Áw|'ßñ|ç‚ï„|'„à;!ß !øNÁwB¾Bð|ÇwBðß ÁwB¾Bð‚ï„|'„à;!ß !øN¾ã;!øŽï„à;¾‚ï„|'„à;!ß !øNÁwB¾Bð|ÇwBðß Áw|'ß !øNÁwB¾Bð‚ï„|'„à;!øŽï„à;¾‚ïÜCBð‚ï„|'„à;!ß !øNÁwB¾‚ïøN¾ã;!øNÁwB¾Bð‚ï„|'„à;!ß Áw|'ßñ|ÇwBð‚ï„|'„à;!ß !øNÁwB¾‚ïøN¾ã;!øŽï„à;!ß !øNÁwB¾Bð‚ï„|'ßñ|ÇwBð{H¾Bð‚ï„|'„à;!ß !øNÁwBðß Áw|'ß !øNÁwB¾Bð‚ï„|'„à;!øŽï„à;¾‚ïøN¾Bð‚ï„|'„à;!äáú|Àw|xÄ}€ŠŽ‹¾ó¦!•#EúΫ"@eÂÂ÷*„JCßå ’¡Øíì;TV´¾Ë2TnDvÞ+Ö@åFdÿÿ¿( ; endstream endobj 654 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 494 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 1181 /Filter /FlateDecode >> stream xÚíÝKlTUðom¬ìÆ#­idS6.[Åðp# #‰ThÕØWðA¬-o¬;£P^ºQCEÚš€Æµ‘‡( î0¡ £Æ&@ÅnJ“"3±„Öf†Ê0méï—œdî¹Ó{Ï|íýßÓ;ɽ7ÉšåÌnA•r/” «åœ®æäz‡õ ÑÖ¶'õzßÞ½QWW?- ÑyìXܾåñâÚµñó… qúÔ©¬î#???ª««ccccÔÔÔ¤–ï444_ttÄÙs?Æößng~8GޤÖçr¼£òòòâÃ>Žw6½ƒƒƒÌ,9úÊÊåÑßß_=Q±lÙ”áÊ•+±cû¶Øºu[j9‘HÄû­Ħ[Ávýúõ¬î«®¾!~ýí÷¨à×ÝÕK–. Œé/**Ч/ޝº»s>ÞQ .Œ—Ö­‹-›[50ÛƒþñÇæÿ§Ý)JÉYü[o¾¯×Öæìƒ¦WKó»Q¹üÙxrÑ¢Û}É׫W?ÍMM9c{ûᨪzyÂu몪Rë';ÞtŸ;Óïj¼õªãòåËŽ˜aæfscÉË wãù5kR-Ûº›ŸË´­?™°¿¹¥%+cËôþÑõ'¾þ&íBÉ6™ñ¦ÛïÝŽiüIúÓÏ>wÔÀlŸÑðÏèï§t—þïì6Œ `ÆýtLaLg.Ýz=‚€©qÏ_Æöööª"þ6àAúòòrU˜Æ\ºôz=ÓJá#…©›â®_¿A1À\.³ú†Æ8°ŒŒŒŒéŽöÇszWòñ b߃ñÞÎqéÒ¥øåâÅhݵ+ößêK®Ë†ÚÚºhÛ½{L_ÛžÝ>[©çäɘ7o^êÎß………ñ]OOÎÇ›´«µ5Úо¾>G úÌÊÊÊ¢¸¸(N?>¦¿«³3ž^²$JJJ¦´Égç´lÞ¯½úJªmß±3JKK³¶ý•«VÅÕ«qþüO©å³gÎĵ¿®ÅŠ•+ÿ}Gòaƒó‡æz|#pO|é8U…à~Z‘±±ô…Šdí+®¬»©iš¦¥oɼüû‰¼xh»s Ìs'êü¾·Ge& ‰DBU& ?ZÏ4}«*HfdÚèø7aÚî¨jÀ8s”@€P @ @€P:ü÷çA@ endstream endobj 658 0 obj << /Length 2300 /Filter /FlateDecode >> stream xÚÕZ[oã¶~ϯPsŽrPsIQÔeó°=›[l¶]·@±]ŒMÛBe)•äMüï;ÔŠdKI¼ªhòÀ‹Éápæãð¢:+‡:×g?LÏ^]…±“8ðgºtD@‚˜;a iÈœéÂùäÞ?\§r¡.&ž îFf[™^|žþøê*¢N=®{ú‘G"ܺ“@û0r_aÂ…îrv9=ûóŒAê°Ç± #Î|söé3uðÛ%~9÷uË#% Ÿ:Ï~:£Ïê/‰}ÔDe•*@‹@¸Š¬ÈÅ„ îJ¬(“Í]ªgøn¶ÝÜÚ†y–î°V–Xs¯Ò´[#±8ÏkL¸Ff%+µQñ÷zL4WÐRÔ }£ؚ‹~¯[GMzÎαSgv\››Û>yÑQd¹ÍæU’gX9—ijæúöº[3Ó¹,Ôr›¦»ïtßýí‚1êæÛÂh¬ ¦z|gÂ'\x΄E…À‘KõçVes‰û¤6 änMM’•ª¨@„)aZ­ÍÏ% õعZ終P™¶ã óµÌVªÄ“<3ݪ¼©¨­Û@¦¤‚øÂwBÏ#At€4ÞB ŽDqÔ ­FXÄZ8·²’~¡=þŸWªgIЮÕ~÷<~ùP`l‰Ëbž/TûX’Ù3=-ïŠüN£Ó‡¹'ª|ìt¯åÙ¿+,Ö.ÀösU–ÊH\^pŠ€:B÷M+UÙJ·ù’¨ ÜrP—®Y3û a±eÉ}ÙÔJf‘ qÂâP‹†a …?›´òõžÀak_½Û°Øy›Ã€? 1±cLZƒÆÀñàGA„³w•¬¶…ô^ÃÒÃTºªBbÝUížÇ¦‰XÂóI$ؾECÐc( "6ƒÃè'˜ "6Š_>HãjÍEOX‚а +×*S…lVï‡,P³‚5\1·¬±¤×²ªª$[ÎzO5ñ.zŒ]7òá½ÊVÕºOpÚ´„•Þ# ,á{¶ £=R˜Hm¤Hã¦4±„ùƒ;’€UëùáSè>Ø‘`™kïêäº-‘“úŽ !¡0{¨ë ˆÇ|Ç#1l…r–íÒÕ_{0€6ƒÔ €‚™n=V>šdO¾þKFhË HìÅ㕵kÖ‡ž O>x Çà%slafíéÿbå`æçk½fB Òþ!Næ©,˽E»/Àù4 (uovW…ܨNcå© #×g©ýöd¸ñ|ö+;¶éÙ âóÅéPÑ•?c•DEŸ{æ\ú2TpNâ° 0 µ|&f³$KªÙì8P”*]î÷ø¾>~1êA ˆ`ç""ˆQ™ÿ p tZ e±*ûÅr †êH .ƒ¶Ü?îå(TÂVÀ œŸ •]ù#Q9VÙAT†!áhRnö¸6aWöã‚ÿ„O ¼[µ‚cö‹0j¯s{|ýôÑî‰èÕ»^€Ž€Ï O‡Ž®ü‘è«ì :`8Æ¡ïý—Ŭ.`úVé§ó'‚PµKÜ{þù¢öþŸÇQ»ÚÛË«7¿¼ŸÎ®~~ss9û8ýíýå±"\’O‘®ü‘«ì DÀßB˜S¾øˆŒ?Œ»üÇl…^L ÿ[áKwBn˜p=»òGy¬²ƒ@†DÀ=·¶hð5@îCÍЬÔC5›WE:c{½þö`7…¡þ#ý« }ÂLæüü q¸¾žðÐ?f#UDénìÂo€²Ù¬TÕÌ<‰$ª/NÐc\Èðn{2våtâXe½¨ŸpC}£oâÅE>KåN¿Qt ÅkèÉØ•?Òc•t c$4wñxì­Ge‹¯¿ó<ï1ãíTÛ“?Îc£•íñ¸Ê×XÐÇÖ~k}ÁJ@üÇçÞ#PžšÇí›Ç¼Lðo]'sxWþH‡UvÐá<ŠIDÍ"e¬o•†Ð‡ÿ“ß&ž€Ù pâÕëd8éʉ“±Êã$ŒHäsƒ“¾¬v¡sänüQUÓ¤J{ÝŸxÛXjxöÝcNÐ<ÀKÊÉ\Þ•?Òåc•vy’(2ïRŒ—_ÖžJçã>XØ1'7.ðêp2ßwåôýXe‡}/ôæÁ ?ŸŽÙN}x”~<æ“ë^zè7ß#~tÔgâ¶#¦?>ÆL?ó6ßî9å„Zæ•ù\ß~ `,ò¡€óš…S"ãm"Ó|Õó%œ:|d…Z¶îºs™aFÎ5_ó† Ôµ í u^Sw:íCw£2#7©Ôs¿j*‰f•÷µƒÈÔb[Œ0.,h¾ëÿ”Ͻ¦EK'MpŠYÿŒw¾ÎóÒ(Væ“[¨y^HC”‚r~§ó¥æ]E¾›&Ô†Eò“r8ÅþýZÁtkªT€4$HËuŽó«KÉšl†©6Œ©ÊMß,¯ô !4ãIZ+ÓÒ «5’+´ˆ¼æŸ@œƒ-Õ¼Jt拦ž¨šì¹Wº`‡@RJÍÿ0Cíj+ÁOh¥Zì"YîÌtÖf„G.è»ÄÔhYé¹iëì±›ê™Æ qàÞH[õA«!SUUZK_P÷ÝÛ :º×îÎt“XñEÏL¦[…ÅÜt`” ,sM˜ã4¶’ MÐÄJóÚ€±vVžÞÊBOcÒø¹ncU zTm+¶àŠ7é* ³öä¸@å6­úŒu'륣ùo€%ÃHÁ)hNÔ:¢[M«6ówJ½Ôã,geX;‡ ;MÚ!¡¹9±½"’¡Õ¶Ô”@#óÎ,MÞ+»„;•É[Ë&2\§ö\‘˜ +·vœf™.E¾ÍVÉMCÔ<´z9ƒ wYC5mÓeiç ‹¢´•Y—yØž†Uy}`N8üw-â„Fh•)˲’ UV²¨z|Òð¡:¬EÛ¯’ Ú´ ›åÛ¥.îï œ&|zv/z÷‚iCækôÂÊôˆÛ'¶¯‡Ý»–VH€}tòRÙ'¬- Ó¢ÜHK­Ã\wV}+Ø7cäÿËøý ¸Œè› endstream endobj 655 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 110 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 677 0 R /Length 4275 /Filter /FlateDecode >> stream xÚíyPWÇ94q+•¸nEE@Q.A¼Å A¼Å+Þ7jTT‚€âm¢Èå‰x$®Q@E.AEP#f“˜ÍõÇF+©$VÅ$nŒû•§ÎÌt3Kœ¾¿úÖÔë_w¿÷ú1Ÿþý^ÏðÆÚ;hJêý·Þî¶"çÑ£GU×+ßÝ* ‚¿Q£FÚ~Š¢ž¡”h…_0 ´¸C`œµw5y§(òNÞ)мs„)мSEÞ)Š"ïE7ïh4šñ™!x§(ÊTDÞ)м“wŠ"ï1Š"ïE‘wŠ¢L”wŠ¢L]zòÎO3i4ó0}x§(Êl²zò^Ï:vô°§»»E«–uR[]ÕcüRäÝßêC LNˆ7têIƒVN™ ïøskÈŒcA÷ß®½Íµ«¥uÕÓŠï¼Q˜(ï çO\çýÿ‹’wÊxŸ;kÆÖM¤Í-›âàÑÎPˆŽŒpqîÔ¦u+lfŸ98v´ƒ-¢Þ¸Ñ£.]<¯³¹ˆÕ«œpØü¹³¯——é¬ Asáüy::B(H1Téô+ËW……º»ºØÛv˜1uJù•ËÚÕêì¿úéiöyõîÕÎÚ²‹KçÍÖ«¤Fê}–_šÒé³a],ÚB‹ƒô;~B£Ÿêýñpw;“qR”·oÞ$ ðÀ/¯ƒ6Î, ú¹:\ò£Ãø+ ?Y}pôL)“ào ŸÁƒvíxåøÛQ¾QM–v<;jä…‚<±Ù»géû+Ê®”^*Z0wάéÓt67l¨ïùsy +B–ë¬*4xéãÃòs¡¡>C–/S?}mä_Ÿ¼ì¬+ŧLš¸8hÎj•â©ÒéÎN“âw„‚ÜœYÓ¦ªžJŸå}PïãFÌÏ9 ¦V†† 8@ã0õþ€â¸ØÐÛö6e—‹Q^£¼’!ÁOưºŸ’ýà~B~Ck’nNó÷¢Âsn®ËÞZŒW”•ÞŸçr³uV[z¹Mgsg2Ó5BvUî]ܤÃæä‡é<½»§ÇÙÓ™RÏþtV«Ä»Òé®×EGæåè“ÓªôYi”´ûSTðd¨+JKl¬­4SïÏI(D†¯tr° ÀÄÀq{’ä•Ëû ÿü]{Þ¡ÞŸ«%—Ü\œE¢µ7%É»:=€GÊÀuöSî—æ r¿ÊØJM‹¯PÆöý:ù:6êwéÌÇ “â]:9åfNí¨Æüqû–Í%EnT–ãUgÍ Йéò (?L¯ø.;½{W¤Á5¥Ô¥Ó…@+ðéääXëø®T³úxjó^c|‡ Æ,l@?/”ñš’¸ »F%òøŽ©æø®08çÞêó›uµþïFDĈ£iQF6èÕ»få(#KÌÊÌP:ïÀä„]ˆùgÏŽ­Ä;æ†bŽ‚|’+?,dÙi.ŒœSKõÓc¢"q<úv½¼ìÔÉDZ«]­Rÿ•NŸ<>ï|8ÁWg''uÞUú¬Ä»úxjó^cÉãþŒœ娵o㎱z•F%è˜4†è°äGÿÿ˜¿ûûÕ88§LâÿãtÎß§½9isÜ£##fL"ÝØuh¯wö¥$#XY¶A‰·œïâ;Òþy³gÊbËC>¹`îñ¬)ÿT:ýÃÊr´ˆ™f[+KÜ©×tV«Ô¥Ów¾»W„Dw¼Ã©ûÕyWé³ÒN}<µý5ö'ãÄq«6Å Q.>_€2ò4JÄsx †Qþ|ž=sºð¯ ÅßQ}p4:Oñÿa ý5e !Ž{¸¹rÈ;y7c-Z0¯¨àܹÜl_ŸEAó9 ä¼›±0UÇ”ùü¬Ó*JK8 fÌ»q>ŠÔøŒò–¿ýAÕïÆù#ïd=\5E‘wòN‘wòNÞ)òNÞÉ;EÞÉ;y§È»A?}Óóc5òNQä¼S佞y\neѯÆÉ»ôïŽö¶£†äd"ïy¯ïV–{¸¹®‹Žrï↲qò. —/^ ^ê= ?y§È{íxß›’Ô¯Ooú{õÝ—’,ù•ÖFSò×ïPÙåbi­••îâbcp³¶lÓ³{·÷§mÛ´ÑÓÝ],%'ýc¸ö"u%E:ÚÛ])¾(5“£³ž+Ý)m*-R—ºox$ˆÉ~úÿ|’K¨.‹GÞ)ãçöQ#†k8ÝÄ(­¦ä¯Þ¡ñãÆl\[¥÷JwJ›J‹ÔA=»w[…½’G©-òN™ ïý¼úh¯„¼'9¡¿Wß*åµÑ”üõÆ;â¯ø@AÏ•î”6•©ƒ6oXŒ É?µÔÙy§øýy~¿Ž¼Sä¼Sy'ïy'ïä"ïä¼S伓wªaòn„¿ƒ©Í{CøõOòNš÷FÆj&ÑIƒ^5EÕ9ïE‘wŠ¢Ìƒ÷­›6Rf,¢AÞå¼?jH†÷C»^¢AÞ5xo8£$xoP×K4È;y'ïy'ïÒ³ú|¼“wýy—ܤÉKíÚµ]¼0èÚÕÒg{¥…Zó~£âjË–-ÑîÁý{å~l‰]bå:òN™:ï¢|>?Ïo¨/6§LžÔy‡–/[Švýý†ÊbLB‚—1¾SæÄ;t±ð6[´ø»|oøŠ0D·çž{®ªz-lÚØ´kÚ´)’•a¡ÒïPˆƒ×ÅD··±yé¥Ç©BTd„TóÍkQkìlm_~ùåvmÛ®^¹­h|ítÆÉÆ¿òÊ+¥—Ф@ܼysyê䉺彤øb³fÍÐùâó…ÂSt¾›p^yÚzXÈrô ]Â(=Jê•|$5FU¾©2äªoÞ òµy1< äéï,¬ çÍIKŠ.Lš0e /?Ø«OŸ‚¼¤ (`3vm”Ø»&|6üýPÕ¼9³QŽ\®ÔŠF¯ ˆÍˆ§¿i•°s‡hÈówä6¨^l/]ò8áys²tÀÂó3N¯(½‰]Æêä]ܵw©Œy§žm>/öæçJÇ#jÃs®z9Öüì,”á‘|*ýIÌE›¶:ˆM¤ØÌĘ̂ªþm”‘(µ¢Áû{‡Ó°igg+6‡úú`soJ’!xÏÉ:ý|ãÆÖVV»••%6sÏžÑ1߯,G7Z=]òNƒwœ¥órTƼSõý¼®mÛEA ¤çuÚsÒ¦MšÀs½¼¬ªzuJ”‘ØË®,»"6å{‘k$ê/¼ð‚R+ÚÏ®]á9t`ÙåbÔé`oo¸çó>ƒ£­ÝI‰)‰ (`SÚu$-µG÷n¯¿öòyÑÉÆO¹Ö“w•q ïT=çó5îEà«]|ocañøÄÜl}ZÑö¤$î‚g˜ŸßúØñ”Àp¼j4á=h ˜G=tPÚeѺ5<»v¼ƒ;îCŠÎ”^*JŒßÙ³G¥V@áÉ~ú#MBŽŽÿÑ¢…Ê'†uòù»›«ëóÕÖÅÍMîã7бÔ}{p âòuò.’ö-›6 c1<@¾KeÈ;el¼ß¨¸ºxa¢<{$ÿa˃5ŸÏG¯µ··Ÿ5žDmŠ[ßÉÉéoÍšA}z÷’Öi×neMøªæ¯¿®áß¼1NxpÏ1ô÷mÞÙ¶E´…‚Ü`ï\Ý‹/¾ˆi»xò¦“wÌ;0ãÀuhß^<Ö“_ˆÒ8wÊ„¾_gè oT–¿ú꫘¼_ºPÈïÓ’wònƼ߼V±cû6}¾ DÞ)ònê¼·nÕ ³i÷.]¤ÏèÉ;y'ïüòN‘wòNÞ©Â;W|âzVTÃá½QC²ÂµžUC»^³7òNÞÉ;yÿy7û"ï4òn¼[´jIÞÉ;y'ïäŒw¼ƒšþ^}ÿýw©r”ûõí£Mµc°®¯5ï8QHîÄUÇFG;ÚÛut°_+òN3'Þ}}†äädK•geeÁcƼë<ý`jªÏ`ï/« …ÇÒÈ;Í,yÏÌÈ0Lª|˜¿ß©ÌL ‡Ï>ûlö¬™NŽv¶3gLÿî»ïà\zôèé”#GãÄàÇ·oÛÖݳ+Bç²%K~úé'‰¸Ôºuõ°ikFÿõÑGÂÿ믿¢6´èÚÙ9>~§¨S ÊRJ§×Ž÷ÿsùù¢Œ‚|@È;Íœx½{ö,++Åæ¥âb”á‘p4`@qQÑÏ?ÿ|ïÇW¯Zµ<8ÎŒ9"#=åôô“(ÿ÷Á%Þ“ÇŽEÜüá‡- Šz;R"næôi_}õî[·l‘Û¸!nò¤‰ß|óhâø@9àÀê<½v¼ãn&ne°o¿ý‰=y§™%ïxM;xpúÔ©(Lœ0þPZš¹÷îÝóèâ&ÊwïÞíÑÍS]¼¢¬’c{õé}ûömé,Ddéà»wîˆòýû÷Û·k+Ê=ºwûôÓOEùã?Vá]çéµãÝÒ¢µ¸eÁP°jcAÞiæÊ;Rh7W—'>À+Êr®_»6nì¤â"—–ƒ°yÓFxÔçÔ Qžƒ,õù8òsÑØ/¿ü¢Â{ÓyÆwy׿¶sǻ֖mâwîÐÀ¡gîÇÞÿûï¿ÿí·ßð*ù«ªn"Ög9ãîæúùçÿV®oï^Ⱥõþ¦ßÛ´ne8Þ9§5(Þ•ppu霕•…€ûå_Ìž5Sø1e8 ÉåË(çädñ„ ¾Rm»S’Ç÷É'Ÿ`ÖÿÑ­[óçÎUvCÜú?æïÆKþΜP‰xO=p€Ïçiä=?/ÚÚÊÒÓÃ}ïžÝÂÿÖâEbš/,9)iÙ’%þü]z–þðáCœˆY|;k+Ü%ΞÍR9|hÈrÌ \œ;mÛºMKÏýfë™Þ«ð®ÝÃGÕŸ¿ÇD¯EýPlL ?§™%ïFn·nUõèæYëÓùý:y7~Þ##Öܽsç믿;öíÈòNÞÉ»óŽ)¿G7äó!˃ïß¿OÞÉ;yçÿÃ’wòNÞÉ;y'#伓wZCæëY‘wy'ïäfN¼ÒÌÚÈyôçß› ÑhäF£‘wFÞi4y§ÑhäF£‘wFÞi4òNÞi4ò.xÿÛw¶® endstream endobj 677 0 obj << /Type /XObject /Subtype /Image /Width 336 /Height 110 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 94 /Filter /FlateDecode >> stream xÚíÁ1 þ©g  ào`þ° endstream endobj 680 0 obj << /Length 1159 /Filter /FlateDecode >> stream xÚ­XKs£8¾ûW°7\=ãn6Ézjj&3öÎLU2bd›* ^qòï·…Bvå„Ôênuý’­µ…­ëÉ_‹Éù•Z! =êY‹•Å=ä…ÌòCøúÄZÄÖ­½¼N£XLʱ½²*J§¿ŸÎ¯l é1%é$½µõßìsýa\‰L.“ÿ&x°Ew ãÖr;¹ý­Î>Y¹a`íkέŠF”y°N­ùäÛûq×€XÀæó°ç'(tµI yˆÔf4rÖ­C0Æöb#´™W³Ï—zµÙ”`»Òžö0–C]Ä<®ÕÎ2%Al©•ÐV QJ*MƒÃBhbÔ,Ze•e²ÔÔ«$úÒÐï\J|†x‹î#fŠhè5_Ä”r{?õ¸}¦û/)v1ò8SqËñu'2„ÐÔa¾kGYl|Wîù€{¿òy4¥Ø~˜n)¶e}·n„Á:#’l­ïÎ M,µ°¡Ðú83HÔ´;Œi*Δ!–ÃH€ÜÀµIÂM8uT î­JQèÕ&ßÖ±T‰^#ãid^Ôrø(dTsè:‚.ñB:0Ž\ß{#ˆï7×"E$ÒeÞ4!•zµ+ò¸ÒnÂNnž±®Š|;<¬ ÀFêM,Êd¡^[öÇõ¡F$ CêvM7¡¯w“³ËŸ'u“®µF‰j½ÐMÎôRç‘ò%2üå&oÒvuIÀw“48´úd!ÌjŸdqWHs—Ð݉B& ¾‰g)À†ö'åÁìÕÑB6ŒY·mÒáï¦è”DcHÓ׃…Ÿ‡‰½¦.?ߦ6ÓpÏO€Mé€_Ž8œïÍWS†‡I[¯ï0ÇDã|YÁm2’IžÁyŽQŸòìJÕdþ¼Ï+©:¹_ï]£»} bŠBBx1 ~Ú ìâ;ßÔY·.+è”…^[æ#ðC+¼Eê\zÁ€H„؇Äã0ÜÉë½â­pýï¬Û ^³Óiïåkgï¶ÖTÉv—/  ¸2§ùÊ„R~}¿h2¢žN'YûåXlç2j¬5v†êGAøõH¿‹(î™4Šã!ú‘y³öUÞ'n;Ðþq=RúÔC.& Ó;€'<€yáŽ89?ùþƒèÝYÜ+ûQ×E>#îzà"̾ëóM²’Α|¤ÿY®Þßc(@¤HÀ?ŠCøýÂFàæØPÏí^šïŠºô’nGùªyŒ£%ó“j55²i£%^ yZù~;2°—‰ì¿“®½8Ï‹|§FüÓžR¤ð¶ñá}i^Z@W£Öìš×·Ùªéy’Ù?Ž< ^Ë4ÙÝçQ7“.“*°'Ùñëhøš¹ôÁÈý1à‹»§ü/ð?ê–| endstream endobj 686 0 obj << /Length 330 /Filter /FlateDecode >> stream xÚ­“;oƒ0…wÿŠ;ÂÇoìµR)SÛ°¥8‰G Déϯ$-(ªš¦“ ¾çú;çÊÞ€À=„h¾ lSî@*¬ ‡À¸5 &°ñŽËL/Úïó,î¦5…jn§’7õbwµmÒINMì¦VŽZ]{K‚¹~â/OéMRñ„ endstream endobj 690 0 obj << /Length 1158 /Filter /FlateDecode >> stream xÚ½WKo¤8¾÷¯àÒÄÁó8nf6£Œ´Ò¬ÒÒhÍÁiœÆ `è™_¿å4:Ù¬´{rµ©w}U®½½zŸ7WÛÍåuš{9Ê“(ñ¶MP’/ÍáL±·-¼;|þ\±‚ ýš5V?¶_.¯³ÐË@2!J2Î"”á ôj¡(þ4ó/ÍA¨Ùü¾ÝüµÁÀzx¶‚„z»zs÷#ô øöÅ QœgÞ¨9kâE$ºòn7nÂcÿ3ìá Ñ<ÁG€ó(ЉñåcÉÚwÆ“Øú޽(B$Ì"%z”¢4·ßÚV*þÐxaäFQìƒ ú|èu,Î ãA„rŒ©Õ•dˆÄ±Ñ#¼`÷î@Iú7ÍÐ`@‡Ý dcÜZ4Eà4Z©C¯]Wô/fŽæPßë8–æT~ó‰¯) Qòªµw?åÁƒ4'/Ä`oJk­ídË»AðS=O¢WpÐt%åãÒ6g»ÒÞ4½•5±âÜe-ZÍÚ·¹ ¦,•臷Sw`ê˪’ADýñ$8“!ƒRgB´¡º\°¶å¬s—Í©Že¸ï£h k3¡þZB”t]Ê2eà r®;Vó31Lj$Ô(Ø–By›Dªzu«!`ÿAn™m„ôHEš ,v-<>Ÿ³Ç(¦Øñ½¦§('é¬ñO7KQç4g9J’É\˜ú¿ýOªˆ …»i›Š3Bì“©+ù|+~A;¼´’@çgıº4© 7/¬Õ›Æ\›CæMŽŠ««F[ªŒ9ô¿w1Ê©­ÆŽYHìJ){~Ÿ~øY½è­©1'YVŽÇâp'›w£j½³> Vɽi*igå×€([¼ú§h#„Ìh#$2hS·«hSÅ>‡uá¥-Š&ñ1ÞΩÄù™ãó×3ÞÇa:™Víª4²5nW\ÕÕ®>Ú’Ŷîoj'«2©çõû¦yã[4ðjò^iÖw§0^Mám[‰aZNŒGXyôŽŒB\°DLóc¥-ŠhJæ¶pV¿){k¶ò :.rÓHÆÞ^W„¾—;Á̆äêÔ/_Ï‘WªH}°’}-Å‹ oö»Í”²¿d3¸û^ š=²‘”†ôÿÀÉ´ž¿²Þ.=­ì…ZíVÑy¥ØI¦:þp¨ÌF†Ð@‡³=è‹Ü`ÊHièŠuÎü½ÕÀÌ1­1@ëýcþÔÏ S:UÔ¼ˆ±ÏwìÐ[E#¼Ì–VQ-ö¥%ÍäüìjV-m™Qð^ìãêrÒF!í%·2îÉ —#­;4SAº©t{ئmr¹h.pyŒÃQTnt°GÅç!tR6¦–ñ'å*»¯\5[¶ãçJ-êN õe'šÇ弚$jшúPÏãkBJ/Àær¨¬ý[ŠaeãógéoGx\ endstream endobj 703 0 obj << /Length 1373 /Filter /FlateDecode >> stream xÚÝXMoã6½ûWèV °REéØl»Áî¡@_É™¶…È¢kÑ›äß—I‰Rä4I›`Ñ‹ÍÏ™á¼7á`° `p1;_ÎÎ>Ó<ÈAžÆi°\$iŽš«Š‚å*¸ï.*¶âÑ"&0ܱúȪèûòëÙç ™Ú™b½3Éb¡LÉm7a¨ÖÓ,<3˜è-³ß—³¿fH­êu©˜Ånvý+5÷5€ ɳà¾]¹ ‚ Æ©jWÁÕìÏ´öCÿ Ô2JòÁAybLJ@ Œn_p½@Âð!ù­wæX‡À`':_,·ec±?ˆÕ±à¶Ç¬G¨·5%€PìrÿðŒ–4qJÝRV¯ŒTQ[¯ïYÍ+Ó\‹ƒipVlMK²Û(!ЂƒŠ)ÈõOAŠs#ñKmWnygýždéì¿/땈bÞ›þ£8šFÁìV¶²FuÖøNDˆ„?ôïLiæVä¶t²ýž3kvé䙿ªl¤1MþMÔ¿D( elÕÛpÛ—ÂÚW•ÅóÖè7qŒÝï«GÕHÌÐmÃð(e·ÖŠ‘V7knm,¶¬Þ8×È-“#§l™ãŸ{×H9¶BŸp¤ÌM­xSnê'¤Ä`ÙñtLnå*ŒA’Ä=±ÓIbŸ›£ž¦uìӣأ5FxšÖ$ ¤ŽÖ'u$Ї1r A´Hr~‹RPü–]Z-¯¥v¾n27µ—¥°Ó-çôhë:=¢±]ñu¤„±c% ÂzÅ „˜E(ÜD ä”~Y›MNï}»¯–fXãÒjYY-ΪrÇ6Ü Ù­qXsîV™ÛRîØÞÆ"*õ?È 1SîØpË€+^´§Ôà™¼xئqÙ¨i|³¾Z z5Kè$K–Q¦ ÙhŸl*n¶gõ Ù󶤸¥ó$‡2 ÒŒzÂÊÈžCƒ e9ä%—ŽCƒ¼Õ…_#™<6=*&—(ÑÜå_+®R»Û®GbzW=Ç%yËŽ1*Ùtì^½ ?–áÉXF”x±Üê|ÔhŠüˆ†.¢•òFgj=bBVL‡¬žÐ!»1«…Ý®]ßö×:'®'t%!«èÂt:ÅÅVˆ†tÛ m×FvâfñȽ (A–¢a+þØ›M´¬bUõ¨Sõ|L‡›Y÷)¿lØmåfhi}É» ÈÝ/Jèö Ú3iïäfÏ‹Ry>.˜VѼ:—ä'rIªâGߌÒp·µÔ„-8H÷vñ¥¸ãÎ5´¹+†¼­¿íÁÚÇM»©ª¬R÷É¥íl¹Úæ4[¢àL•&à ¥‘âÀG¸¶É_ØoÌQוÄRJ[üðW(™DýÓ–Zä-]E„aøð¾Oë¼;?ÉÕ?þÅ1w_øÉçÆü_¿5NÞKÓŸÀ.Ùª¯xl AÃþc#Æäh&=h­Ê“o J…¹4Ѫ•­=nx­zÞà†íó@¯p¸ùR|Üpfqóô¸©éá3›·Šþ·¸ð$¿N} MT]­|ô†o¡ôÕ|ô endstream endobj 638 0 obj << /Type /ObjStm /N 100 /First 877 /Length 1446 /Filter /FlateDecode >> stream xÚ­XÉŽ7 ½÷W蘢I‰”€/Ç@‚œ |ðÒœ8ÝÆ,€ó÷y¬;íé²Í¶çÒÅR?‰¯žHjaÑT[Iµ&N½ã!‰`ªÔD¦x¶Ä\’rO¬’´RªÿWIž55­+­-iAÿŠ>ð´¤mµ'Çdý[ImÆt®q\“4Ú€oMTЬX †R ŒáP´0x范C–cø7P¢ ʪWC/EKcôR†¡þ¾ WŠr¿ª Æa…SƒU¸°î`ŒÜÝ—ÂW7€! Ø}9UE+ƒ* Qm¥Va€*<¤SK2ç ý˜¬0Ô€!†ø›+øj§ÄÍiB0žÕìpª+9ž©BCvª„‰`§J˜™ªÁÅLµÃéÀvKRð£ÀÉ<­}$a,E¨`dÑ fRdà»'©h&H,Õ»`š¸S…¯Ô°Rw±a@cŸl±!1ãb­¬œ®Øp†pÚÅÜ»Óf°&C(ÕB>àHÕ)XA8r÷¿*â’}ö<@¡˜•–j#Z‚§6pvµ¡+¦:UI+œ UM-æìˆY+ðÕ]g QÆ0‚‹Έàl˜˜V<¾u­€³#âÙÇé0FÈL3Z _È ô3Äv“>VGG«éA:Uȹ'izöûHœìÒ"ϲá‹7—oß>_ݹóE,kfzC-3ºWÊ}<‡×gDô þðl{ù.¹Xþº#U¥ÿ¥ú‰4 â¶[Ï©¿§ë.øZWS†Ç ¶QFH‡ µä2ÂJÉ…9†¥‘‹J [zFåaQQ²¥¶kF)a ‹šÂjͨÍ1¬ëÐbãR—,¦æÎÇ|:Törj!|Ù·’9­ïeNÓÛÍœf»™C™}ãò¹ÌÙ_ËÚLЧưÌy)º– (ŠÅz K%K A±eÃöž«p k–«ÅT¨ª¹Qok¹µ˜dµÖ܆Ű"Y%&/6 Ù7U!,"È‚’•’McS?÷W¼½J «–{M…0e rÀ¾1wŽÉK©›A`õ;ÖÿݶSÛ|'Ùøs ›Xlín£ õ²WЬKAÛÑÉÆk¿…µëy‘t„cXœucÃb\n¶!ÙÏd!¬ÔL/z;A²_ÚI.ÆÄ×bA÷bçªï‹…Þ‚«Y„­½`}[mœKìÓæ}‹aeàt¡â^ùåc+†#|L^,w98ÈLDCL]nP—,†…d…[K³_²†°˜µ¥ƒÞ"–%“ÄäEÕ,u'pþˆB†¤ endstream endobj 720 0 obj << /Length 1631 /Filter /FlateDecode >> stream xÚåXK“Ó8¾çWø˜T£‡_:2ÔBAqY& 88±gâŶ²Ž³~ý¶Ô-[ö&šÃÖ>.‰,µº[Ý_?$<,x½¸Û,ž¿JU B•ˆ$Ø<q&J©‚ÿ”›"ø¸<}]çE¹Z‹˜-›¼=åõêóæíóW 2Ø™H³3ÊD˜ñ øÚM’}š-ŸãŸŒÍ–Å/›Åï 4,à£,Ø(ã`×,>~fAkoF* Ζ² bÎB!×Áýâ×#ý™ŽŒ@–Æjr˜‡*B•¢P„<±z¸ÁÇ5gŒ-ßçE¥QÓ­^I¶üŠ'œØ†k…2‰‘Ýf_Wk™ªå¡ÓÅiWÒWNÆI½­‰ #)œmÎ_­¼;}IJ¬Â4Mi¸Z'*]¾i‘w¿7ÈŒ‘‡²ë+'ô\µ…^‰xyÆïoú„ƒ]N[˶/;Ÿ Šª)Ûc¥[³Ù¯Ö|I‹Çþ[íèJØÛTí m_#Xs¡BÁ2€Íc²Ò ácLfþ­ fОš­ádÆúÿ;< ‘jZÝéúÔ´ÇÐ _ð4TR¢”+ÎÎ,D¶Ìë£q¦HñôfêXö88ï«Ý·+Á–§¾×Dcu³´u¹ëË©ÎU¿ÇyÔ¦> !ï-œ >"Úw¨œ´>ß´HþÐéçØY29Q×S²,*Ò²_ñ¥ó…!©«#­X™M{]äžÁ—”î(¸Ô•Miê å¹£×d̺Ú}!û¶3—˜ã½8êot4˜š˜ÊÐ:6º=êº*òžöîöyûX¢“†(›Ç&è$e˜%Ò‹Ëôb\¾´§¼5E{±(Òär,&¡jŒÅ«2¢4Ì÷"Qf‰D#­…‡H4"ýH4ë6ÍÝ ‰S.úXõ%ðe ”òIøªú²Ah0O@ƒ#m= ‘©< yLÈHð|>„:/2=Ô¨  u¨›䟀3áá,»Œ3Ýl)ÿßý4ÿ'Ì© æTt sŠ%挼óEˆ:à¶S3ÔÁ÷u@ˆ¨Su0ãP§bˈ: °N—#uj@™Q§Ô)D]yéÊ”âLLóªŽüŸÀN]„Ý;<éPsu±¸Œº8L¸×uqW@'ÃTe~ªã:D–tP›*'v‚; EÜÁ€,ÜŒ¸;øB/‹qÙÃ|î€ÀÃÌî`ÄHa/Û‘”í ûâSüý‡açUUÁ.Âî¾Ïûj÷ú¹›»\îg9ÉMeµ“¬àÇ$¢\ ì‚i×ÌÊ^wÕwÝöÃeÁG&ãPfÑͪ”ò0•~!Žb#›Y>M‰faÒs*Äf[b˜éËš”®8fzìn FŠc¯;Z^h¶B>ÔQ2˜ÞþàE¿åÔºd—÷}W‘×Ë)Öœž]Œhˆõ±œ6«µ‹É3ñÐÊvåÐÅ!ôhÀ8yÛ«ËÜèŽÝ$½öSNÃîÓ±^‹Y$^z_Žܽ£§> stream xÚUÉnÛ0½û+xèAFb†‹¨½Õh‚=¤Hs %Ú ­7ýúEʱ\E{âh8ófã<´GÝ,>lW×aŒb,@›bŽÂ΢MнÃÏ›B¦j¹b‚x¥¬zY,Ÿ6·W×AxÜxúÃwpâ ìÃÈ»²Æeñq³ø± `C}Ž\ ¤\<>”ÂÝ-"Ø#t,K$(ÁŒ è~ñeA\þä´Žˆ"0 E<)DPû6%3Ìl£#z\QBˆ·î;]—6Õ‡<Ý/Aí)mËœ4ˆ ó1„Å|ÈTnAè½Ô½"¯éµÕH{$#6Ü[¹ë¼²:)«HU—ïÚ!¯ÒzÉ„w°FÝ\…•¶ÊÅkë²Ñ*µÚ]ÝZõ½]gÅJ– /W<`Þ§óØÒ¨VçªûKüDV¦+¦Z+\:S§Ô„5GÕ—[ÕZ¹ÞÙslÄ`¦u›o—Œx½619ô[gÒØ"»¦QÒᘆ™sHz¬«N·}¢kg‘È¢€ ý˜{›LuêíX™4ßÏK*´ã|úÒÙ=˜™µí¬ótÄsBŸá˜øÿó#ü =†ü÷ endstream endobj 740 0 obj << /Length 1507 /Filter /FlateDecode >> stream xÚ½XKÛ6¾ûWèV ˆ‰InŠiš ÐM6‡"É–¸6Yr%9^÷×wÈ!õ²Ü,‚¢—553œùf8üHnäí¼È{½úånõôUºñ6á&!‰wwïñ$L6ÔK7ð›ÆÞ]á}ôϯKQÈ`MxäDueðùîíÓWYäe03¡z&ËH˜Åø5“(û4óŸâåzÊêåÝê¯U 6‘±`"å^~X}üyèÞzQÈ6™w6–ÇQHhãÒ{¿úcñg±g!ß$ñ(n¸MàÅ^;Ù n±Ç!!2¢gEÞšó0Ê(NøMVAù§'8å.È"¿®Ë­°>DUàà}'ºS«å:; 1‘pÇÜzOÒ0ŒwÆsïã:Ž¢ÈSuM@ RqÊ;UWt²<à‰d!IØÂÊìeylqx©O8èjü-d«v••íÝRÊÊša>c]×§ ÷uÓûµ#q<–*f¨qjdqÂÙŸA t0racç|Žqxa³j»^/ʺ²³óR´­´&Û‹ªü‹ªv³HyÝ4²=ÖUÑ붺⧮«-BuU%áDgUu@¸î/¦ý¼„>« ,Úìks_–RÛ5#Ñž¿è.“(Æ€0ÐåЗ°QW0hû¦3Ÿ~+(«UŸU··Ûê騃h‡œ%n›ž^5â ZÅaƨ³³€L}K+K =jŠ8ÆÞÈr’ïeþe[?˜2´(S¦«½5å4¤Ùª§÷©­žvs8fa’ðGf!¥ÌÙ›ú(›N¹ÎXX¼›ûuÍÖ6ަá&JÝ®%‹»ÖqÅ·wë³îÄU‹¸ÆOè-hFhÍ·égšF…)½—O„З…êŸm†Ai CéÐåa°¦,õŸ£¼P°“vèð¬Ê¥¥´ÎlÏ_öþ-€½Žd¼%þ‡V.€z^Kú}3^yÍS)Ž}èó‡¤Ð.<´8t&°Ïà+£0² ¥ØÊÒpxê›MÊú¨9K”hQéV2rKéÄÐ(ŠÚ®×)¦|Lh©ÛÃ`}jíüêtØÊ¦Eim‘|ÕK(%¶¥Ú„D;I“]*Ž*4ˆþæ~Fï]ó!þÌâDÇ{2›µz-¦Ç´¡–~UîL‘úó¡k„ãO§¸¢É¬dc÷¾æjh“\³Ùòž®ÛùiÐ]ŽvTßÏTº@?b)~¯›ƒ(mf/4Ñ 9»Óê(TýÓ‰’“’Ä?`ö¶0Z…;Tël'j!¬ê.ÿpÄ&×ÓDNñ+nàjP{ }‚§ŸpYS¨û M´p¯ ÈM¾¸oUºHZcMÈsœ?Ý€ù³‘/´Ýmø­ë!ÊÌ%]$Êñ-ê6WÒ½?XZ¸©üpî÷…‹ë…þưUÝA­^ý}«ql\u±åfž!7óÔ¹ËÆÜ _ꌛy:»dv3f}®™s—ޝEÙt}Ö”RKÃã SžLƒ–(Š+¯S8sÏìÉ`ywœµåÝ…žÂudc†e³, r»\ܱ0ˆ&tÒܵs<ÈG,¬ƒ4(œ³"ëYXGlÑÈ‚g³ q˾Ù—9å.*Cö½ÇpTâf±)ûŽK”ŒŽÂÿ‘‹Ù÷qñP¦ÿ˜‘'û}ÊÈW/ƒY³FîîË£ 5Oˆàššgžïö Úoõ½°ÓOkËÓ?^ú—Ueª×¿sà~ëeVÃhþ.èëÔîûe7n³y'ï{”à{Ù¿9í½Ùy8xg8\ÁC}Níc’= ·íQæêS|/>ò4é¯Ýlñ4™¼¼qïfî^Èf$Ïâém›¹›s×<X.f®Ô *UÛáÈì PéeYX§¸r8C5(ÓnF]áI#R—ÅY£Ô]úuˆy †Øá ~±- º qÝ@ÉëRúá½@Éù^T;9[”¥ÿÓ0X£ˆ}Ï¿iþ*åÉS endstream endobj 749 0 obj << /Length 1221 /Filter /FlateDecode >> stream xÚV[w¢H~÷WpòÔœ“.‚°OK#3\ “33¨­²«ÜÌüû­êjŒ:î>ìKºªëöÕW]D]Ù(ºò8xÈ÷Ó‘§xšç˜Ž’¯ÛÑÏRFœ#CÉWÊööýqW¬¸zgÚ:ÛÕ¡Ø©ßò÷SWW\ˆt,Œº¦æ.äAÖüG.»§Ã²1d䃿øèŠñ^ -[Yî_¾éÊ l]z®ò&<÷Šmèši9 ï”lðÛ@?ÅïŠáj¶ç' xÍZ„Å}åÕªüNP| ÞPLS³t×Ä0]¹³mmäýÔ2Då’W­TüMÃùžWe9#’8¦fJ2®_UCg?šr³íˆ½¯º­/áAª©ëæü‘êï¼éjR!lSÖ‚6d ™øSé¥å‹p+6ä÷ë¡åM«µõ¡Yòuݨ†Ë6\«x'3cˆÑižeÆ9oöeÛ–uU•-[ÞðÅ’7MQu|u‹šÉÖÐ?Ý×k:—ÛB–.-€¡¨TÃf2Ë+Àë«Ô‹®(«²ÚH?™Gò…ý{ÇìݶÇÔÖëî =І÷VRhÛzY€’ôU½<àŠîØÙWàzÇ[dC`hžm 8•nË üMvRæg%ºrdW[qxÿB*+¢ä›] ´Ø[ÙmëCGJÃÛ®)—ˆIæ,«åî°’D\xïÊ}ùÞÀIñžÚSª-Ó—),:6“WûzU®Ï.øq`§tÈwûzXìÊv+|‡lU"è…jêìÐqyÙ¢K¿Žƒ¸‡7'ä–ïv$”’·„žÆiô]g\ɬrœ†ìÊÀ7Pz?í¹ÃÛ¶ÞÿG^Š,eÐúÐTп(²ª¯½‰¶¾¥=„VÿàK¹¿ýrR5ÖõnW«¦ £C´ñ÷ÇÖþrLŒ'?FyZ,j\¿ñïCúbTuDËÁ}Ü ['†úý½po·…˜ˆ yEï¯zMæíÝŽYŒ“úo;ø”…tz­Ñt[_0rÊ¿vF€üää³@½³ôË’iþ¢ð°üT\¹,ÌÈ4OÕ¡Îò} 'Á„noü¬w»éX¦Á^Â|–<çtÝ'Ký8ÿL!É”N?þL>ÃxrKwÁïó4ÈdÅ$•©ŸæQô.a<Žž'w×¶$Œñ?‚ðY„€Jœ p¡Ø, ŸÂÁ£%ÇK¤Œ pŠ8 2 CÌh| Òñ ªg1ÿ!ŒBhÊ0=±Ä`ž†y,à ñ£àS޹ê™W…_ŽŸ#_šçÏé<É‚k/Þ‘f‹“8Œ§)4<P~4dZ,è¹÷ 3ø„v!f3?ŠÈ‹ŒõUÛffIšÑ… Îq2ÿœ†3;K¢I@>{ÁQè?DRÆî®"†¡š¦ËÆ‘>!-æˆMpþ“Ç£ ;`¤éÌ‚”®±Æ9¯àó2 Þ=°c<ý˜Œ"í8y/f÷ã$ÎSiDÂnÉLC§1üàè%̂۫¦aFm,ÐRˆFAÏ^Sy¦t ÌCd9Žƒ+è¸+(É áÕÅ žf9ú> stream xÚÅZßsšJ~÷¯`údfnPú†Š‘Ö€Is;½}@X•[ X›ÿþžeÑ(‰É!¥ÓÉËrÎîÙó}çÇf¸'p7­ÛêŒû§ñš")œ»äd…W´.××àÙ97ྴ÷?o"/ W×’,´7^¼ó¢«¯î‡ÎX84•.Õ쩯Š*¬[(ueï«í{À+¨´ ·õ½%‚ŒÀ‰{bWæüMëËW àÛNà{šÊí É '‹/uGܼõwK8µ_9QåeMOÆóR¯ËlÑ·[áOfÊ 4^ä$‰ï ªDÕîZ–ù¾Vyú$ÎH¢Ôö†tÿJÚßâäJ”Ûûˆ««kQh“ ‰óRvI%’”½˜±Ÿ¤Û$õrÐ]é6’Æ«ªÊ¶™'Ë|籠YtH*/÷d&é®ÃŒ?“˜½Da–g‡áÑdxc&ÓOÍ•Js–—ea% òu˜×[/ÍÊ-¨YWp0jZ1ž¤œaÏ’|ïŠÄk¢(—‡éS$v–/žIs_À‰‚жS껀¤$…~þ¼S$X§/œBÍ”¶]BÚ?‘•z|¿{¤cúÒ²ŠÈ«’võ#/ËØº?(Î$͘¿aBÓ‹ÁÚ+E„”ßÂ8'T~Ux‰‡IMy4ñdÕ°| —8JÀ›[¦É¦t “oÜaô‘:ªØ;Ï·ï;-Eèaòl¯“˜HEµ½:~ë$ìàAyðGŸ_« /+}îZyM.YvdŸÄ¹ÆG¦D³5ŒWl*NràÛûrMú—®86p üûç°A„v»ep “íC®Öy• à_A.¬J±©¨Pq@„*J‚ ]T,$ïa“ÄÁÙ…'$Ïá´$}Mœr²K™Î7#é&Ì Æ ö2 äÖãâ' ŒËŒsê«¿^vÏ2%·~²ÄÉùk/]‘šfä nq/Fzc ü:Ây$$ ÊJwœ1H‡ó›uq¾Æ(;©5ï"ã²Zâ‡^•nåƒÄßÑ"äåèY†$Q±}~Ð*b/'Ž|MžË6ï.kÌŸóÌ¿£)§!„µRˆ4cù€x^‹ûÊË.Ç §$ËÓÐðK±_úh Ã¯–yQ¸ ëÐíÒ¢¦!£Ë]V7>É1¯«l’ \ÖV"Os;)áínÍëºæ¦AH©µØåu½’Ñ특¦b5‚FçrÒHRd2&Q„.!Éš.¿’$p0+e£±¥ýU^§ò7‘ûõ±Cÿ3¹[ð—»4†# $Ø~ã­Ébõ?âçÍš£¸ììÑ¥nJAH‹IV=î¥ËW^صáñ&‹k·É‚o6Ÿ^³.г]ÃÝ!¾=ÝÖ¼7Õ17[{Øt» 5/ ¬SÁ¶ó~KyÀ§Ý"Ëáb›Óm’>€?^¥Úü ùæôÊîN äFöؽפ´9ÇÉÍû“92F5ï'úüMfÐÌ+-ϽéNì;·<øÃÑ-÷3NÚãät ¹àGÓ½µÎÿÌcŽt£í Ý};›šÆ¨f—iZÃéÝÈ´np› °èX6RpjÞšnÅì‹Â®”ÃVI"Ó˜×̾X>ÝÎp;èsjVÈú::cÓµÐDc™¢#Óƒî¸æðnª#—Ý93{n`ãlTÓã–m™Öت·†å¢sîçXÞâäŒOU.'ï‰>6Ì[ý2¥Ópڳώy3qk"3±§#kÌÀÀæ}05šf>6»§ºy[3XGú­~c4Œ‰ ”pð«—d*8ÞO ünØ€Ò±rC×´­f‹ùж\® ¤k;îo@ñÞ¬$Ç×-ÑsŽ¨Í•}Œ».wÑ]ÖõvÃ4(-£Eh+Ùpέׄc€ÞþnÞØÎÕ^õ#CŸ!çÍ‚ûkœÿƒúùó¹ß~ô$^zoùéÇÿ¥æ¾) endstream endobj 716 0 obj << /Type /ObjStm /N 100 /First 879 /Length 1563 /Filter /FlateDecode >> stream xÚ½X]O7}Ÿ_áÇä¡\ûÚJK‚’FjÚˆÒñ°a'0ê2³ÝUÈ¿ï¹CH `’Š´ž™sís?| «Œb›UJøaå,UžXÙˆßìðìùˆgü&ùîUp„güFØa­«,gCÄsPlŒ²‚%Â3Þß&«’>V‰Á—œÊNø’Ê|É+kŒf Þš s:ë3Ö2ˆ¬c‹0žaš‚²„ïìe€ÅÚ„I‚sLå-ÙW .“˜³,„„OY^'¼É23Öì Çä0`!ÌPÈ‚<‹ÊF9ghܨs”*›-"å¼—ÙÁã!ƒ¨\cMŽ¡™…KðCx—`ÊSd¸‚Ü`kAyg½,ƒ%2)ï æ…÷`åÀ`QŒÏž  ‡,ÞÄ.°\àK¿†ˆ) ‘&W Oú䣎Ï^DâfÁ±nŸà:†Ë}å#˜³ƒ9cÆ[2"&Ä"C\1C’0“"ë05䜀‘%H Yg 20ð‘“>`8†(î¦Ñ¹ðh,1Fka쟢Ȃ‰°‚b¡ C1ŠØc“3¬2Ì% óöT%Ä.3* xë”ÄÉÞ“Á¤ "%LL æ ñJûJæŠ&l€2ÈÄ2$G²„AŒÕÖVU¿è»Amm©ú…h€ìÛÅP&»" ÍŘU°ãøéÓª~³êöšA¨úÍÎ Uï7gƒ:¬ðIx÷?/|˜7Uýs4ݰF&TU½Û¬ûÍê¨Y4¾zÝÌÛÙ³þL&ä <’Èê”1Ûl %ðí®ëÁx0– YÒ•™ÇïU½·ù0ŒÏ¿µÝßUý¬_Í›Õ8ƒ9¬­_ÕÏìø k:ÂfàL ‚UG¬¢×.I„’F´·=ʵ§ê—ý~¯êõh ˶ï´Óé±Hóe!;ê@J٨ݟïÿR?Ù¨½‘b“´A,w›Åâð&pˆ:f s«3Ü]„…VÞ•acÌ:"ÊŠ°àuÈ…lÈYS 2,[mb™Áe-åµkŒN¨µ%X Y$jÖͦLŸüʰÑè`ËtðáéÊôuˆ3ŸÊ4ÃQ¡¥haÑ6”Å$íË–`%ÔÝɶ©ëåçe«—Ÿ‡T:8o|®ÇU4óy{tÕ‘Áߣò]ßUù&°Á¦:Û ,yT‡©ŽyµÜ芰H8µ ká‚ʰè‚s™ c³Êe´žY›2Åp…G_HÈYümûvt2[ÍJÛ±y{ôªVý|3VA5ôêÓÙËÅlÞ<®njûì…廓٠Úõ…ÅÏ·™¸K&ÏgzßoÔ&k‡“"{?9¥úýý[ÍèÜìÙlÝ­o†sànóϦ]5§ã)7ëæjo³\ö«¡™«7‹Ù€SüôVšxN³Óêýl~”/ä_³¸ñv¾ùpÉâ?—6mw¬ ÇëöhÕ¯ûƒz×vóþÓúN7Eó¶kÏähÜœÝiï¯Ù\õ§jol¦­¯\ìdÆ‹FI§¤Úo”øn· endstream endobj 816 0 obj << /Type /ObjStm /N 100 /First 861 /Length 1188 /Filter /FlateDecode >> stream xÚ•UÛNÜH}Ÿ¯¨ÇDÑ‚ûÞ-E‘BB$’e²ÙWãi+ƶìv¿§<6³« žAbp¹»N]Ωn{a(#/¬¥àxÝQ¨ÃšôH.2F;0‘1N‘àÌ;C»•w†Eça„q€KÎë™G&Â>2…ìB2ð‘+ï` aU¡¸[¤:C䏿2’jë]hî ©áàF³¤%„ pØ`õ”¸5è ëÍ*d€;ü ¨@8Å΀;ð’:ä Bx¨’zÍ[€Ü ÇóÀ[€8Iƒö+¦U0$’†À†&™q($3Ðx|2Î% x€Ê JÂc#…)ž9®C$å胩“£O`>è_J0ÊbJÅ>Iy˜• óЀä!D•0@[0Hª•^lK·Ž·7šIÃqP®4˜¯€¹•‚p“Ò‚¿í¥Å¨P#-ûX$µA­^¿¦ãK:þØ\5tüž^ôÃ5ÿÅ"•M}$ŽÜ‘:’/é͛ՋÏC•JúØQY÷)¯ªœè7ú‘we^'/Ч'ÿ¯¸ÍÛ»¹¦Óû¶jº²ÞÐÏûU¾Ž¿¨`Ê-ÄóÇPß »´ä=e8Éû²è©¹9$ÃÔÙIì]t9–‹E½õ?ÏëÍo"õm,Ê›² <‡ª ©Œý¯YÝ™»xH·M½×{jì¼ìÛ¥ÚÌÖí]sw—×kªÊ:B§M1ª´„´[äמuI·h«º"RÑü’½Wgç^> U@º¦¢ë‡òÿ Ÿš»¼Í»¸žìEMºý>¤vHÔæé–¸ç›²Šu~·W; ùvHÍø)0ÌTt1O¨âçýÛ¶ÝÎx]ìoaG|[VLá»W¯žâîæ¶ O({Äüýç»±ü~ ä'²Æ©{˜ÕÛǼ_—é.oû§ÏàÄÚ$ }å“|Vcç&_{5kü9/kºÈ«˜Ò¢û¤éU#}+ëuósÉ{ªê}ìËM}€ÿ$ÝE×´±ããö4f§“Ú:h[•ÛCA» {Ñrw¼žTóñÐ é9À©ÑoåzŸœòôG¬Sÿ {Ät,Â1f#ÞÄ.â´ôô¾Ì«f³šÒ\avçYüëaOyW ã>œŸÒÝ! ¹ýuvúí0Ú>ž_<zD¸ùkºT iá N¢^m _¾lFyH~Ü3¾×C±|?Nê47UÙ§Å~õîKû¡Ãå¹×yŠ¿Õ™šWB«½°‰ÓÜgšpTqÙt`iï×»oà—&Åë¦ù¾×šÄ“!¥=b½»³¯šÍ¦Št}hº³OÆËùPP˜2ÅûtÐ7qÔ0›9Ã-}0hRþ²*×±Ûï>iÿ16”NM²: endstream endobj 1044 0 obj << /Length1 1428 /Length2 5932 /Length3 0 /Length 6897 /Filter /FlateDecode >> stream xÚwTÓ}Û?RÂP i¦7ÍF‰twH£ä6ŒØÆ6¤Ké.%U¤[JIARiPQ:Þ÷ó<÷óÿŸó¾gçl¿«¯Ï÷ú\ßóϵÛ&ÂÊ((\…Ä ƒE@2@U}}m0‰‹€@bSÎ þ·ÀcÇ`(¤Ìx¨bàQ§ÁõQH Î=7 X–’ß”€b Э¿Q ÄáÔê p,€G…ÆcNÎ8b¿|0~ øÖ­›B¿ÂÊîp Aõ!8g¸;±" â4AÁpþ)øäœq8´Œ¨¨———Ä+‚Â8)ð ½8g 1 Çx€?! îð?ÐD<@Sgö·Áåˆó‚`à@¢Â ƒ#±Ä{H8H¬4ÑÖ¢áÈßÎz¿„€ÿ+ݟ蟉È_Á 历 ñ¤Ðájè‰à¼qB@Òá§#Ä ‹"ÆCЏ"Èÿvµ€ÿÞh}¸âžû[µqâ’(#ˆDKˆ€$~ëX „7Üá6sþM¦¿§A¬á†@Âo£°ˆŸ1 ú/q÷`®ÄËKœÙoK\Dܯñþ”áÄUûgêHÊáçNŠIJ!  R‚(I}ÀÄåu€{ÿâN[OòØ"Y…S¦ÓIr›#Š®ZÑÁ©Ó„‡Ö÷¯Êö ^¼ŒÅ7uBš ZÚÊ‹3õ˜Øo™þhŒk€ö˜.Kî0ÿ•óÑýQÐb´uDŠAúu]¹–C@¼WÝ|woÏ4}Ç«¨@ÏË߸Cqôê²=ìjçȨ̈Ÿ\ú‘S乑ÎàÕ¼¬´áÐù|Ž?ù Ò`ËyikÃæ_bÛMgûDÇhðgÂ!=zšQ%“›·é0•ÆEV×­°5oOCh½ž}ñ‘ÃU',D?9Ú>4ÿãžnжÕ`W0Ÿ~¼üiÉÒg¿žæOÇPÒÆ¿Ê“é—Ô™2ù×ýƒžtq»eMïñ…ŒZˆYI§:7™*Nß n °¤¿è‰H-5»$Zó©û|Á=‚Äé“í–ÞI²(d C4a¾jÚ7=ÿñÑ&XôM5,­"Z•àå¾°ç[æ½`£×íŽ*ð{Ahr—ü2ÿžþa4JÈ•ýt½528†Y¤1âú‹©ÅŽð]ÎÒX’bƒÜçG;Lo»PM$âÏâÀè£ ÂÉi:Ѐ®&P<»}EÖ|¸ÕIªûI' ©Â„ÐÙw…ÆÃ wePÿ‰±xíxƒcO‹à¦Æ%†[ô !ˆ{˃ú‰K†J´Î~—§ø^|ÀhÔ´ÿ(ºIy~§!'Ф‚môË…¦bù@*‘[O?enìˆ;±±ngÊ_â²j±ã:ƒž¡ì®|Sa7ÏŸ;êzÐw¾vËâ:×Ò¥Ú¬Œ×ó­5Ô] ¬apb>ϦƒØVƒW´ÁË#Z »j~»ß¨¦²â:ï$]júR]v¹[äT|‰² miÈÔyñµoqŽ)‚Þçåu'hfÅ rIüViIrผêÌbRò„—â¾úTxxÝqÜ9·t²¹IÌ×¶W‘ÆÛó­v1p¥²*R‚or\’B¤îV?ÿÃî´ •P“‡sXñÁG\s…l£¡ñéß} Tš¾ ;ÊÅõË ÓÇ]GàMÁ¡Iú‘s´Ÿ-j*ÅzѨLµãÌçd-Þ ½ŽïµªŽ¬¸lLÕ÷^¹¤÷Dú‹ Ó,-1­ÓSéfܤ—–ÓñèÊœŒ,­kæûÓµ×jd$žä™ÐNHÊ-y2Þ€é>˜—$ ^9o]Æ@¸è ¼šo42çÕ©ñè‚J-ƒc´téxCáïÆöãäÃ×jå¾¹èþx8ÂíZï¶7Ëc·ãÎmC—vkQ¸#(wùª+D¯ï>ëôaªéàm°Ï»ÀˬŒÈ܈‡cÙ“>PÓæþ&GÊÐ_r_øDè oð†·µz-³n-öÎí­™SP ¼<¹Tmšû¡õÕØ+}dAÆ™o؈nQG4®r°¿bf©¿äœ†[™´|ÔxýfÀ–.xÞñȯae(‘¿j݉)ï"÷ödh¾ì°¤!Ìq=Êx¯†àªfd ÅÉVu_ZsɯïÈr¥Y2`Ù“x1B)q˜¶3W5}æ¢,aï4fô¬¢’š¯ð“l_`¹ÑE3®`U4tõ­’ìA»*É-ø¯†_àÉÃØÃBÅæ Iä—Ô¦F»ÒóôÃŽ†T³ïH‹sŠï‚föãb\EãKyË$w/¼.>¬û@X!<§wÇüî3èg Ël«~н~&õQ×Ê€Êk–mz±-µ»ãÌRÊ÷2úanG¦Zì=ÈáS|Fܬ«ëì6D™|:3"Î5àkÃ,³I[Za#4Δò&±&jŽ™•jBEDo‘ÊviŸ[Ô $r¶˜}Õ%%s{ï(åí1ŸËATzùU<ÐÒ­à9š‚&¹&”ý¸SGy¿«u)ýšâWiÒœJf¯áG^UlÌ6_} SËÂyH)ÈÕÃæ ɵb"L÷;¦V0¤¼wÔ˜±rd‘'Õg`áçiúþ´”.ÁãYi­!E«µðÝkÑ,œÙ:í-~vŒÑ^l ‡‘ä^Þ}Sf¨žŸ¨Â€¤+Ãgæ}y#¯'†§7™$„ß`“Iz/ôÄÌŽIï¶b\MwïUÕÒý½1ÄæØÅI…¤Kô]ƒûáË–¿‹ ¼w¹aÑž¥¶.½Ž5⻕}­N#r®·?²þ”umR/AÖî>ÀÁ(YG›»¶1¹ýNßf&wcÕËûy:VÌñþŽãtd·„’ŸKU}¼j>Êñ÷Ò¼ÜxÊn"D¡~¤DE³=®<Ú9‡wã{°¨w®a÷2—‹lÓ,–áëçUê6–çîJÃLDZ¦Œ·b§ÔH , „'“Ç_EÓ–k­¡W˜/A´(9¯SYòO^Ó‰p«»˜Sød#¶ÁýA¦Iæz'Ã’x ]_BÀðöbÊ7ßÉZÜù|‡µsùR„ød›é¸ŽÓŠUeKÍ阸ý‰gî)‰ 2» onñ,cOäÓå;¸մԵò•b„¬±ïqÁ$a9)¸Æ­cÆþ%4}%’$§‘D{ƒiˆÃŽ?ënÚö¨œNý’ îbLòó[Õ¥¨¨NIºno=µ·­Ê©‘µ÷O: 9ÞSõ¢¾d:vy¯ˆ©ñ%?èGæVNŽgN!¦cž =Æ^lŸhŠ úx$‚™¥*'ãÜV·z*LVrR÷y÷ÒjPq ¡9yù¦”‚v}~˜»@å©hdì'™z¦]àøì{ÞM¶ìáð=) Ö>¿“ä›Þ˜ÀWÁ$‘3WÄ·öM¥òD˜ÞµéeCvW²kÁÂÎñK]ÎR÷¨¥Y»|å¿VÞ·Ýmic â6†S»ªY‘½ˆi‹Aû÷}+ýACi9 |"í®L˜Øý”IîÐb {})ÍŸ™r(¾¸=×´—r¥žEU³ðR@‚Á»œò‡s¾²@Ýó_¥èÚ”çöG»íí—Z\dDiH¯’Ü­zpvjVÈ#p$Åfýa»Vee!a2N®w}ùv47šÌåE@[ךW;.DQ<‹(Í×y6š]÷cØlVÐÙ÷ »z§1Ë%Äï Àú5NKuýüfï!gš(@maø²—ÚïX¼FV"÷¸Œ­e}ðÄ÷µˆO ¬<Ìíô0/œ¯ˆiò¾*Uªà×·ìõìwëOÑÜ@Þït"ÚjnõgñZ1î$üsWgóÅ)JpsÆËˆ 7n·ëµÕ4™€[kŸì„_ú¹úë )}úRòúbŸ¦|‡ísçëü®e jièHÜÖöê·æ™H\(í³á~húݨ¯.e‹Œ¦ÓMï. qC6ƒX§Ê°Ž‰Õyù¬Ý`®`T…àÊ}ª°þ•9ò€WêëaÐÍ(!ÕRívÞÐËËÚy]£©ä˜fë©Ú×Þœ}<6†£ì=ã1WÑŠŸGKË2ÇT®PV<o° ØC‡Žn»R> èQÎå¢ã›°Ñ_byOOKMǸ7købhÌ0©Âmfð^ž}§Ø– ©ÈBà>}Ðû2 ês5‰D?jVþFê\„ÁÒ„4‡ÛSè¼M8ujjè×Twå]U¼Ì»<_ÊfŸ”µ¨t+êZ*ÊZI/bšbcŒ£ùLKh-û‹UàÕ¾™l¨°úërHê¥)ôãL«äRY]ëf±Ä…çŸu½=ÄÛ æßØáŠ8^d¬Å¾ó²xÏÊë—_QS*kLÙ³ÇTÈäðqh)”ÀW'o÷ÏTÊ–íè~ÿ8ØÏÝ"sMø{þ‚òk…úÅfGOœ´cë•í°M¢¤)Ù‹á­Á´†ñꯟ§¸}šu¶Ö´‡žÛƒpJç§×qóÍnõØš‰_.óH¯ÝÝ\ÜV¥¸þü̳5ª~×唞$F15çhºO™c¤nER¤+ÓbÓÍ&«%VÒ\©èÖZ] cdX:%¹]°¿s N•7µ.Œ?ü Ê*Ú• MJ˜>q=]ö™£\JDe ä^~ô¶‹lñs´&}z éÍFWþw™‘¤#äÉkn˜IÀ›äµgñÙ ¤È“J!×’ký—Ô¨GnHË^¸ÿx«úlKΑc»^.ï¤úíI\uàŒâáêÆ{ÂyÙ;›„&Œ?ñŸVBY„(îMûöª”êÓ›šNRß°ÉЪÈßâÞ=ÿ½{ƒ™;C N*n÷¨ÇC»{-ˆš ^"»Úw)`Ø¢S¤ØÁ_󤞺0@M’?«^ª-ˆñF”Gš?ó¸×__ö<ñÝ8ú“S¾Á9/¼Íܸuæ4VÌÃýë©b¶È‡ÝÚ£=YŸÝ]Ó‰t¡m9¯<Ù¥›§lqݘïp˜÷~¥í¬.ßT^`oƒšÆ·ù]lüªýàøK†Ø Ké‹aäi§ëVÔå)€±xؽ|ƒ™q ëZÔ{-ÞB²ññŽÙã ŠRû\ ðé¾2Í‹3é®îNT¬{ýð¢zÁž›kT i$¸Ý/k̎Æ–1OÔúq¾\Õ]û kntã¹4ëBtvZ]¦Å«7+{ˆIÆ@“Ó^Ò.¯½»Q¤ÓmÿíM¢%¿±÷ælüZ,Y‡7µäȤsñ ªF5-–õœ P)¬ÆÿU“NÁ…ÅÐúÍÀr¦®g¼îLõ©†¬Ü³œw!?üÛ}·ž×ÍQÒ_Þ1Å´žr•m*w@×›ºóª—ÜJxÜ; tˆ?öS‚ÚmU ]ëÚ™­Eõß‘ÃûI××\oÌäìÄ+™äùêÐðŸíhY“³Q2ú %{š)ªÉñô%oÚägœäMzù-¾äãìšæ»núW $ué¦Ü«Úú{ ø(’ti& Q}ßòºÖ9òöR¬]¤q¸‹—¤]{9OV)å ‡I™9 ç‹9Ìႜ²ò3È5§îß'HÓÝ4Á yC+¹#\w—Þ*-RÕ¦FAôÂ_'_e¼Ñ[ ÷=NÝ–}äL£¹€Ó “ª¥ô†ûެ·ròÏy¼[¦ÓHÂQ'ææÉ{W4vRDM^üPh·Ò)–@w"˜R6lxk9TÙ¯Ÿù±5ÍÞ–VHÞÛ.úÕs3Š—ÚæKR…¹¨L.J+†(ZV£xCÇnõp¯–8ÑzÞÝ¢ÐîF<4 r–ìëÅO¯m?Oû¢øBº°ÍÂ":Y¦èëâ=ÊJ¼+x¥æ/LGˆRR†¶%£D÷á†Xi¼i’¶wû™nÖnj ÚÉí0ƒ=±† A¦çª¦\Ç$S,±GÉZ+‚\-Ð7—=ðÆÃrÝœ Þ4ò;™žáä?4ýÊï4|%ÀÒFwÊ…ù¤ßÝÍÇçøJôÒ“-œ¢žž;Å È‹Vжò‚5LýÔm¾7‰?ž+2áaçÕ¯ÇÇäÝQÍO¤†.ÖÆR+{]ÑÍì7Ù_ÄeRç©K-q¸Y`Âä(%Nô{íXmLÃÓüÿJõ,ã8V4Â\æCÞeç/$ÞE“ê+\Ó£#Þ©6%§ÏùJðï¡§'Í© 1«›ý{¥„ÜR烠‰«@ÞÂNÞ°¶³•Ñ"¥Q½­3ï ®v lt»%š{‹ïšf=»°Ç£%°RBM#Õr(™Ø1“f¤ðU„—ïmý±ã¨+ª¬¼o5ï‡+Ã<ÏøølðL [E/f § æ40ˆ ”Ø'Óõ– ø«…³ ¿àø•s’·Îß«­ÉÉV"•Aí²•t¯3ö-<¡¡ÉV^é”ñ6’¬·:žkpëŽk:mbBhê2âÓy³Ì‘‘¨ÁWa–/#¹×·®¿£˜oîÑ¥k~;Ë“µ±eÛÆ–1P›ãwhïjLzÕÀ :c-xØ®25¨ÑçÛUÐs9.üÄÕF€³Ë¢LÀRðéàÂÐIž$ˆx Zº B꜒f95*qÊíÙXƒF‘ÏêK±kò÷þ¢cŸå §3ô9ex¶W“Æ3ze´KÒÝW¡Ox[ð?Ûfg endstream endobj 1046 0 obj << /Length1 1429 /Length2 6121 /Length3 0 /Length 7090 /Filter /FlateDecode >> stream xÚxT“[Ó5ÒEz“N@z/Ò¥wi¡ƒH !@H„Ò«ti‚ t"¥JoÒDAz_,÷Þ÷¾ÿ¿Ö÷­¬•î0G'4¦Î_0/@TFFJàW8@Ùâƒ=Ú âŠ©ÁÆH0 ‚öùW ž;Nh´›¬°°———È%„twTàxÁÐN# âî qü¤ йBþP"â˜8ÁP¿ÆH(Ú ä` p‚@aB<w¦:ÀX[`àAüëþþ@THôït¢&‚!~ƒÀ`¤«áC8 08` ¡+„öF @‡Ÿ@…ÄăˆüP Oíî ðûOÇ¿WD¢¢ °‡8ÂDÿdǘ!ÐßkLÿÝaÞ+ŒüD"?_?Ycæ€DÀ}þÿj±°¶…‰®9ÿÊ;UTÞ?A1€ Œ¤@TTT %%øwž¿Oà/ö¿¬@ìÏîþ#£6ŠÈü&9½¿ˆxþQÏŸ±áü»‚>£g€çùß‘cÞDÿÏCð+äÿ§ýŸYþWùÿ÷Ž4<àð_~žß€ÿÇr…Á}þ 0zö@cfC‰™ÄCÍ!¿Zâópýo¯6„™e„#Fç‚¢·…Dnÿ¶ÃP0oˆ†;ýÖÒ_ÍÀԀà ûyï`¢DDþˇ=° ænAaZöËÁLÖ¿ëª#ÀH‡Ÿ#(&! ¹»ƒ|ˆ0 À¬$~¢˜Yu€xÿ’8@XDcBŽ(ÒègcÅŘ(¤Eÿtý¶Šÿ±þnâO󿪂=ÜÝ1ƒùK˜-ýµþu @ Þ0ÑÌ$,æü:¬ù¬R™ÑKpe~¡5:Ѳ+JÍ5õÌÏI— SsìŠÃKºþ'Àé’ˆÑIF¾Ý³!ïûﲃçÒ´rÑXê]K*û‚y½ßŽÞ9BX ŽÃRO¢—(ö’ ™Éì¬p­¸SÌ'/Â¥ÚÅ×^­¾¸lE­Ý“Ù¸ OÈÙÒÑqÊ9­[Ø,Ù8Ð}–÷Éã)Ý­Ò=L´M‡/±ÁâOUšcé¿ù,YÅgô}þü>»»ë‰øa¾NG…äË*zjß»l9ýÉ=ô4IÙwß °¸T$NTKRÙé \#¸æpì¤æ¾çw7%õˆ{Ô:ê«ß0x8PçQ”˜”ÏiŸ;d²]Î2ù&LBWŸí$Pù„C…³Âë¤/}¯BžÛKËÀ¯ný¡7Ž,*>µÔÅþXKð0TÜfu„îÌ..3ITÌ:U.Ýó幊$ÎâÖ5ÿxq'@ÅÀIÔÆÑgs^ðè¿% ôõy¬Ì‚5q¼^ÿ¾¹¯=rɱËL3œhÑ’¹Õ¹™ôF[âä…Ÿº$ºJg ÙfË›“0h”›ƒ ljÕ”»§$3=ž`&N–gB1e¢»†•®ÝR6\9hœœ”Êe·„ùÕÇrÉgò!õò©ÒA"gGö¯©n'W-Ý0lÿ†g“hï¾/,Fh£“ÛzÏÉ®HŸû.úv"¬n+ñb]År,x_jr.WåÊ4Жªøáý\hÜ÷ø¯kǵ{¹ÊÕQ÷àÑÛÆ—lŸ0·ÜëŽgJ;²ÝѺæ­U{~‚»Oeß§)ÛÃV/«KhTýÜMmjÕ Òm>®'to€Ö#µ:•»½ìf³^«¿çö½ôŠ€’Œ{:\F|é¥^—Œ.q”Y ÉWiJÐHmˆØ$BË ZG´ WÔùH›¿eÅñ¨>†¢ú\Ómÿ¤ƒé3Uc“ðÝ_ð)NAˆ†ôwO ø§/Â’ï}”‘mU»·Ö¬Í0ª…è5àGYÞž/:Ѝ§È·L˜È·ªïë^Š-ÙŠ5ÜxÙP‚ÔJõ#½é=FOÝ»ÉÝÖìAïß„$9;97×ge6ÊT|X¸“Ñ0Ž}üëñR:œUãíý@] l#'ÑW,9ö…/‡ø#á$ªgր‚ÙvÂ0&Oè2”:L—­·µÃZp WdóÍE±ï¾´ 4*_µ.uX&ÿ+ Ó)5è‹gÓ¾ûzüõ÷5º¯FW¶èqs¹Œ¶ƒô%ž[¥h¾"ªñ¦Ï²ýü—¾~5 ‰¯hÃqR[¤½qË ^Œ¡“µÌ•‹Û_.ÊU³}4›¹"Qmì£5CV?™õlÌÙNVl¯~Ì*÷8»J¾ÿ“‚@X÷RQYë}ö²ou©™7Gvðs‹•¶=¯Æ_)YƒY¤Sª R¸CéW¯éD]Üv1¿¹sU¦4i H.þø Dª?š»¹ê‚ý!ƒTŠðŽÕG6üíÓó7CÓëã÷‘M!6So¸bWŽ­)¤á© ËoP \aaï„mx3ÙLV:ƒ@$GØ å»3#Õ ´Á-Æìyr ë©6XÆÑDʇ’*ò³ùžˆÙ “%— UÃÍìᣧ%TÖÂøƒ‚~Q£Ý½J¹ãiü˜2a¤×.KÀ !7DïìRÍø— ¿Rý’¬='NÔ·ÒýVÃÔ‚þ Úå•r³ËC=¡m ’LëãuÅ bìC{t<%݉\2é‡A”g»m¾ÑÆ@µL¢1À¸Ãfèvzý]"ãiƒ»äió;¹‚ê{iëmÝËžÓ,2.Ä>ñ´µZÉ>nr j½SK€gúÑìÙ}£0ëòÏYö¾šªŠìœ!þÏ^lëUiƒ’qýFÀuŽÕ7 ²?Z>ðö¶Ä«ßš^/pà.ïXicl¨#~/†%ÌØà<ˆˆœicŒþt“ص?¼âÞCg¾.©ôðÛã™8pÿQí0’z»<&KW«àC£Î§ã£ºÞô¯rø§fÁ–>©]ƒM¹Y׈¨lõb/핪 D(Íð/¹³‡«FNJÐÆÅ½/È?WYÐàRñ„Z††wžºè›×Z¾Ýј¾³®P¶áR=ÛA0o´ÃóqbØFlš“\[ùârÛ5¬ +vˆlî]r›Þp¥‘æeXžÏS*ÿ”„ž¬”{ü_ä²t>V¯Çx=ƒ“¬×½5%üò„™v =Žs¡ÉŒ˜ªÖlxêï®±kJn“ìäæX׊æ)ßL|û˜ß­’g¹Álâ`>F³¸.¢e4§ösϵݑÿ®ÉîÇ]z»?ÂBPÈÓFבZ±Gï+ü©ºnÆwL·ã^˜C´Ú5–îÛ‚dßDÔwÜêbîŸ×)÷,D–FU¿_ Ÿ®W^~Üð® o­Һ̳Â2 öF éå3‡£ùjžA % …ÐÂV,/—‘t,gZ¢¼R„Å 0ö¸‘޽æé«àš²3EX%e´ïÑštw—[‚Ãg“̸àŽZ3מÕ' ôŠUû蓎’ö¦ß6f^“ñÅkZ1‰R îD?lLêJÀ+B2óí<‘‰ívžÐ~”‡t®0ÝÑ9¡òvÎkº.€?xÆo/Z9ùú€¸C; ®¦»gxG<ø´(ˆ@7¶pß±l™Ç‡n‹ Ÿ‘ÆæJÇò©KÜzâyðŸæg­ZªÀq…£qÝבm$Šï9²kÏ9惠þ÷àÁ‚Á—ÈCé„./CÇÏqnÙ|¢6T¤!B“1QO‡Ú·ªˆuÍ¢¿ÿqqæJB  ‘XsRo ±Ú%6•ؾ2|c dXv{{ÒÏÒG@€JÆ–ð²MÀa|Å{°Ê”o’·ƒUxâ ª“›ïRV6ãü9°,Ÿ!â{³Tóóëƒè7 [ sà Nß°qº»¯¦-^0ä·‹£µ}D:[Ÿ áŽßŠî²J¹õ‚9Tí–ú‡d7· ¾²â¯Uséž{îãC)Äc8P™P¾ Æm Ù¯­k =Í™²|ƒsºÌPìÁ8š™d.P²³?³M“HäuÞ‘ÊÉŽ•:|›Á:íØ³fuܾ3÷Ž”™?ò^Gìž ß¨ž0i~LÑ‘‘8«;4OzwkïpÃF V|iU¸/‹ºóôS½X;Ûõœiä¹VÚ-üofa[ÐQÓ˜ÍÀà€Ó‹1ù±™˜ß3íþÀüuT¦ÌAK|ÀòJ 3¿£›r@¥À;yç21 ÕÞ©¬¯ÄÉ{iµO¦™È…6„5Š{úEòÓÐFÙ 1ØBìL^b'ú6R`Ð3Èò¤«ÛáîÝHdReÕbZðÛýMå±@ñ¢ECš6³ã‡û2êù´‰ÎòD¬eëOý¼ð*lÉ$ÄO 4vÇÛªo?UÉX_ÎÚV..£\hyðzx¿ŸŒuþíÜèíZ‚–ȉ#»¢¯€Pº×Ë&»r%—šñ˜ž¹¿(²JúüÎÓî qsmÕ÷¸›ÇmÞ§š?rà 6‡…ò†n <~S|óÓp«Æ`ÆcpeUfRˆ<ÝËwP¶›×Xùú[J…ð…×¼ð;£¤y”ffeú’€ë[”:ô¹´]Ÿä|~®`ÁöÞ5rЧ4§%5ÿÁ>f¦ªµ~öTúƒË͉$¼;>gÙú$ Ç›Å-]B…Ý{Øhýš‚Î(¸ØkòzemëHÞ›zgduÆù«?,Ófµ !qøø \Å|6ñÌ=IÜ`%,²Eº ®7½þw懺^<9meeØ©¤ü±9SÊÿLú2¨îNÞCn×mÔ Ó`76ÛVì"Ãæ_—¹ õ³4köðÒH±»Šß:[×P"ŽÄ-îæù*ΨíÉ럅_k±G0Çù=¸ioÉ£À>#Í·þ¨µwÐ¥ØGü ¹s†õ t­µÔN’ æµØpfý"ˆ¸…1‘fËᙟz2M_AÇ#¯àú… !³…5'tö‰¯ ‡‹ ‡õí­ Ü}0´>"¼I×zR¥ñÕô ÈÞ¤3Á_Ö£O¨sœòM!í=Ý*‘ø'3'yš:Ó@§ê‡ú5Võ¸Ú}¶›QAª„û&´¾scÐëk×=޽¾fwó­¬.:y—»ùrá3‡]€Ñu|²‚÷‹ƒ(õÅ\ ù #¤Ç])ñ§ä›5‡ž ›mÇ:³æ~ÙzãsâŠS q%z‡ÖßdÍéå¨) <Ê BoõJPìç›-ö—Tó—S¼)ùö‚Y*¦Ú’ùj²¤Ûgm¥¯3…À$7VUâBÓÝqÑ¿“\b€#!òI,—eBm[ áÃÔÏš¥ËÓÒ9O6Iò*ðõùâåO^ú+O«AðRÙhŽ3‰yàr˜W‡íH´ºH ›ÎœxôH?»ÍÊè7ÇW2"UPõn97vù«>(xJ(ËEµ3¡Ú¿¼sÝàÛÁ–ea‘[rº_ý|±¶äMÕ4KUa¯Ê§®ÔeŸúŒ?p¼2üÎ2ªª{œ”TOëîuýKk!s¸Fý\ÉCö°eõ…Áÿ:9;\².bÏïœg¬+L¬vÀ“øÖ{!ìvÍ'¦ Îqóeøa>1ûhOï YÃ$Z{>¶Ô¯MØSJŸÛó¯½3ˆ°ž†Wxá–ô:\’´x­JÞ¦¦Ãb@@ÿ.šÅã¨äe -4Ëèo·Ú |¸+ªñmƒÅ†LYܳüzÏ¢A–çXSØ5Ob"ßó“ú¹ó~‘™ÏÔö·N²®Yeùú 'OpàBDËg]&$ž8)oÛñt…+ù%Êãù˜+´íG-+œ'U¬ù(­výh0]8'üõ—B‡–\Ø/mÿŽŠ½T œË;¡qO©$òÃ^*¡ Cîl‹Çòæ}¬öAìUöôÀSnÝ>6…Yñï"5q7;šŸÛL¼zLÇ;‘!è÷Æ ¡¡Ò`ò\ŒÜ¨¸½†Ìûýú!k”aá±—ŠãHÒbó¥ñeSNûT)<Ë~ÿÄW®¡*]Ûgâ¾úÞ»þÍh7÷b=â7JøJí®·ÏÄSÓá}ÑhãÓÕNNæàÞua7£ž³¹™·¥ìtbµDéêd‰3þΙJTѽCnBꪆ¢¯é_Öì£ _3ïWÃ)s»N‰ô ¾žôXäsA‹9…¨t|ïëSçÅ„­],Òªo,AÌÄÆ(äõn"©x©ƒï‚{̾¼c0­WèšzŸÂNÖfhÞø,ÔàòëhÒm>ßïBàú#gðã2K®‹ùOÓÓÃT Û›ò[R”-é2jNÎÞïo (K ú´ç5bR…³/b2H¬A(¡}¾µ×&Õ€Q™ÄƒuŠò&,c _Ø×]ç,åŽ×ž¹—z:|Ö÷Fw.ó8 ¨Í=Í¢n·-n_÷$ô9`¢ZH·ãߘ1WDâ:È•½bªãÊÁz_¦üT»ÃÎ…¢êìáãåE¿ÚÕ,ÑÖW8.øaN…Séóô*ýœøÌ˜þÞ·äÙT‰:Ö»Âtõ´eÜú¬3Òy0P°z¸ïHÕÜ ò"o ÛÉYÒn+=ç]S«tsŸtPÈ5•0zeZW¯àÓÄ1ZSZS·iÎåÎÞMrìš±mEÜ ®¿2â¿yyÎ¥Ö-ÉÉãØËï@yãÕÕжÖ\?¹tÂÄêmqÖÏ•¦– ìyõwZÆ€‘|ú‡HW{v®Ž ßž Þfèv^}VÝ)â½w{À éÏ™o @7àn·Î+C–ç ìd a©¯{LNß‹i€:¿d â’Ò·$.‚ ëV×¹¿¬2b=Óö—Õ c»¯‚¯55ß_ =\ {£ëi5iù:ÀÈ}¯àHjRöúv1׳ýÕ,ê1ÿvŽéŠá$•аï3ôWŸ®ßÞ^‹'s’Qe´Î-zÎÜ«¯)œöf¾A #¡žëx0@¢ö5ûÑ„õ*Óý:â8ZsÿæÏô‡»›Æ-çg²¥×è ŒL¢MU1Ü_Ô‰ÜζҥÄYÍÆ¾ôd—±=RaZÂb^epK&ÎÈFqÿ­>ÃD endstream endobj 1048 0 obj << /Length1 1606 /Length2 1786 /Length3 0 /Length 2556 /Filter /FlateDecode >> stream xÚ­T{k$—BŸª?ï„øöP Èò€0fÀfÀøŒÄþí äÁâZŠÇP ôõļà f"ºñ|DX ™ãòˆyÓü¶:yoq"/|MÅY¸ê˜w,'ö{®(ëOC„acƒÆq”FÅÐÄØdj˜š$üM51ŒÁgÛ•ñ ÀoYß@Üøïßg+pÌ„‰²D[â…1¾X:Da¦€ÇÃõßu¼á?lñŠƒ` È$ ö£Ló}áy'O`çWŸvÙù_k2X"Lå–V{&U¢{òÒžÐ+‚çªR©5ÝfŸ.ÇÞ}Íýõ¹ó†¡ö&%X»ñ8ø¶`}‚†ns¡âC­òP -¨TáÄߌ¸Ñ>—Ç’~›ô}†žvmó *™“Vén0âÉŽNé&iD&}¥9É]–È̽˜µê?ÄšE+ν~£uôåÔ¤vKG›°µq\ªù¹2ùt–Éœ±:ñØkµ,6˜÷¾šùIj&ÊD°ìç WÓÐø•aƒÝð!y'…¹Wu9 VxvðJx⪳ìÛ Õ®‡Ùå¶Vñ/. FKü&,«eržõnÊp/péê|T%¡We1°Ë9G_B‰ÑÜ(åì¥ðÀwÌpø·Zdbé«ÝQ2®ÅË7Ô~¸±uo³fJ[ˆbeƒ÷àñ¢èuF‹’·ÔlG¶-²ˆâ¿š3kOÊÆ¾SàÉ壌€ÞÜïýFœ³K^F„O-š{Þ©oÉ<¬Õæ¾öah‘× Â«šÞÕÓúM7œ¡ ï6’|Þ²è4ùú؃·¹í¦Êmazœo’Í î@¬¡ºò¤DÄ xÌN N¿Hœ¯ÐÖ´øö¬±‰9¶Þ<`ký±£}föŒâ½èkÝgR–õæ‘ûzRó>wøôfÍXF.{ŸzØ{£ƒ{Cüûóµf^‰Ÿd`­2’Ê–ôƒàìå`˜=:7Zöä@AiúOF*¦Ö28ܲø,Xç›J+bÙ›hiÉzpV!1PÚÌ®Q»âèPkS%ÙÝ|«íî0YõѼ7H‰FÞžÐÌöSH¬­Û[2:•¢é#ÕÕ¥*é9¿çyJ ªïš1æxO¸z†±/t0wNË©'gv©\2¼$oJ³`NBÅXÐ+RÚÝO¹ G7­´"t»æØ'Û>Õ~ëö›òÊRnþoåïã(ËßÉøü,GÌÕÚ-XLq–î:Ò/¥4eä{þ´BÍäE/¿’ÙZÝbªù£±ªž¤{òÿUÈœbÆE *El´¨¾Šm…bÛ£‡òö+’ÒVß©ï½ÕfKŒ;5{/´rz}ˆš®{N^1qGW‡ŒIþGÕ4m‡e3êg]d¦Û§W®“%õ¥?Hè×ýæö±™ïó‹ÿ kvÐ38‚ðßÚ­vÉÖ_zì–{{áÞžDÊC)EmÒÄÔàsÞ˜EñÚ*‰:¹³«®r—d6 ³,¤Õî¬ITWQ6VŠÝËq]w0{æÖ/º'®mËE^ëÑ8:ûè ßÍ&S»e'š®çiBª‘ÀKœÛÓOß]©Ý\ÉŽ·É0ª”ÿéGõ뿾Ÿ~ŸD5:Hd%zåíæ_eWeæP9Ál§ê"`óé»g²z”`@¬ÞAÚPØàƒ*È&÷Z)¬z:P¢¦ù„¸½£rÈwèhý±ö‡‡ëcä]š‰7#‰ÜUé/æzF" Õ󌴗¾i P¢ºžç7…8©f›"º× s CÆRê«gH%îÓõ×b“½íƒŒ¶þyÑþ”ñéÈl§È"Ú‡¢Ê‰Qe:×c¾Û_å3«A”Ðr£Î/±d™ä®}üÓH參ÅËoM¿t&”SG¬xŠT~Fú*µ_ëebþì9¦û¥ø|‰> rú˼WU%„cíÔÉäŒ<) áyŒÓ¥Ž0w&]ÂŽŽ¬h½ù5ô«°­v*e›ÛËGÓ´ÃîIáudª×>@Bš{„L\ sêµYù+%·ì¸è9™öô“$=GžX¶(;èì¶ÑëÙç²x™Rí1~ß‚ýK M{nÑÖë}Ím­Ø©ÿ5#o¶8•õ‚\—kRH±—zºÔêµ·ðü .gÛ#×Ê=JÂËw|aà±ë¹ŒsiWÞ¤íã«ÑÔ•'LúoZ:vÝÛüíÝøãU95]Ž·./æ»ñ5äÌO)Ee—ïn 7¶¶¼ï`Ü)g׫N Œ®Ñéö\L¶ò Ú$æ:¾SùŸW~ü endstream endobj 1050 0 obj << /Length1 1612 /Length2 18404 /Length3 0 /Length 19227 /Filter /FlateDecode >> stream xÚ¬»ctä_·.;éØéTlÛ¶tŒŠmulÛv:¶;¶m«c[·ÿï{öÞgì{î—s÷‡£Öœs=ó™ó™kýªjŒ"#RT¡2±3ŠÛÙ:Ó1Ñ3rä-lŒ\œäìleé”f.€¿F6822G ¡³…­¨¡3 4ˆÌÌ&...82€ˆ½‡£…™¹3€RMYƒŠ††ö¿,ÿ„Œ<þÃów§“…™-€üïW µ½ ÐÖù/ÄÿõF àl˜ZX" ŠZRòJ y5€Ðèhh Pt1²¶0ÈZm€TS;G€õ¿c;[‹Js¢ÿ‹%ä08Ù-þnºíÿqÑìŽ6NNß,œfކ¶Î{àl°°5¶v1ù‡À_»©Ý¿Ù;Úý°ùëû ¦hçäìdìhaï ø›UQTüß<Í ÿÉídñ× °3ýibgìòOIÿòý…ùëu6´°u8ÝÿÉe˜X8Ù[züÍýÌÞÑâ_4\œ,lÍþ‹-Àhfèhb trú óûŸîüW€ÿ­zC{{kí¶ûWÔr°pvZ›ÒÃ11ÿÍiìü7·™…-Ã?ƒ"ekj`bü·ÝÄÅþ?|®@Ç5ˆòŸ™¡úKÂÐÄÎÖÚ`4…c·sþ›@ù§2ýÿœÈÿÿü?"ïÿ?qÿ»FÿÛ!þÿ{žÿ;´¸‹µµ¼¡Íßø÷ø{ÃØdÿÜ1Ö†Žÿ¯pC kÿÆÿ¨ü7Éÿ)gÿͲ5û+#=ã¿Nâî@E gcs€©¡õßNýË®fkt´¶°þUô_ÍÐ112þ7Ÿª¹…±•í?­gû· hkòßÉÿé_Ôd¥ä„Å´hþûú¯(Å¿Ú;«zØÿ%ö¿J‘³3ùÏÅ?ÂÂvî/º¿'Ž™…Àþ7!'ÓÏÿC¶Á0ý×ZÎÐÙÑ ý·dF¦þ¿^ÿµÒýo0b¶Æv&ÿÌŠŠ³¡­ÉßñúOÃ?ncGÇ¿ªþëÄÿ-ø?Öÿt Ðh ·ºdgÌd™–™î\‹•;4!ªÝ×Ã>l_Ú ZTàWm×í›¶ÃUað^Lß8ÅýÙæ±xjÿq M}8ÒƒiMѼÌÇÿIBÕ[€²IÞÁAsÀ WŠ˜~¦åuµ » ñƒQýpwBIY¯äŠ`ªƒÅæê‰ÊĵÀôÑÉÇ8µ>£¹µ¶ðôŒ<ñÏÓ#ÅÀèðÐ`÷ dïMN,,!–Oò)Q’³‡ã}ƒñ'ä«+‡Û.R r%8ýYRkÔÏgÂ+­A¡&/¡¡°Ž‚fKl²ôY%ßœçr•\LæÑâ|?Â%ñ&ª©¾FÆ›I€þÕl#,ÕNKƒ#ºî¶$mL‹ûÆa ¿{Ù{$ë¾m“HÏRû^àw’ÁþÛvbIcîs—öhëßž5Ð7#ñ ?Ø¢»rf¡Û;YÇuÃcÐ g ÓcÙ„D]Ó¶wwNÕC•LÜ3þì-lˆÐÛ›ÍÁCÞÄ8pZÆ¥ÕDg™ÙIOK¶JKùêìhñím6Óÿ.‡.CÅî3Gzš£¯4ÎÏš=‹-L³i¹½‡•Gøí˜&°ôJB›~H¥Fãl-뺭p=\ïÛ™Ÿ4¤h– Ñó^ƒ`›ôƒÌøBb2˜óbA¨û2qCÈ@õêhœy7†`w@üL¯¯dDí@4•é‚/¿ÿ¬“÷ ¨Òóû'òÔv½¨¢Éñô4ÞÏ'×’DÉ„±7MÀ¥µâX¿‡BâA›iç¥,yqÂ̧ô'<¥9nÓQC% {äw)-ùlp_…¢Ÿc¥q ÜûÞË*~%!]ûCŸÚ9äæ_2¦JVøæQ;ÄŽZº‰0°4ºyàï&‰5Øï>_ö]V>iᔾ² #2µMKkžÞÃ([©‹i¬ae½Ñù˜‹£yͪBIažh«[—©Ô'Ê¢'hz¸àX’n6yH—}ƒï\ (´ájl %Ÿ¶kãEE<<±è¼ØÞ™{åo­³p$€B8d3|š–k©Ûþû>üª²R`[I¬4]¿²%•·'-J:euöÌÛeÙÕ¡ÐÑ7}ã(£ÚxƒêŒÑl1ò Kà%ªÈ2J¡T\O&(ß 'a,¥“tàÉ<À*©yloœt—7/FGÌ ‘võl¢*o»ó»Y«¿—æ ˜‘7Ί` JÚ|EÂÕë&óUÿ@Û¥Œ„óSK÷l×7ò ß§Ø‚DAY=žemB¶h2}19Bå˜4x‡˜ÇÖ”>n²ô _Ûnÿ¼“¯Ù·a‚XÛÒe¼Eå<»® ¤ÑI->XBuD­ Ö§ÔXÐÜ"  ¢Íóå’l!?™ß°ãÎÏ H†ð´X-|«ÎýJ´0O˜g³ÐZ7< »äò¿ì\Øšxôû%4¸žùðÐ>ÿ“(Ÿƒíí§’7«ôçP,#f¯Œš’*çîM'Ú.¶j÷‹Î{Q ‘øH†‰3€¼©–òýLº-ØOÆØáÏ€jÔ¹-âz@BÊFíÃ2h ˜¼–5‚8 oé…xH šÂÀȧ<ñú.§מµÙ”8ì}uŠ€:ø/å¹ 4Ñ̷®5ìÀãJüa-³5’üÁíÙr fÃ’ƒ6B[„³º·zïxJÚ/›hŒB ¶ôûõ a5Îv’A¢WEKL»ñH>ôÞ/c{®€˜œ¢zÌ]ˆ)fÂa%›(Þײ«>Ê?ô ¶3½ÕŸZ»cÁ`•° îÚÑnOEeꆻÛžžwºB…,͇é p›SÁïÓáÐîu÷¢uë ÙÙr–b¦"íg-0F˜¥{ÌXÖJ¯GúvE¤U×¶Øpç}â§>0qú(TüI-^O0Îât6îL˜o£²Î ˆCÐ>} ùƒIÅ\+é<ÉðÔ–ÐiÖó‰J²â ½l_gztåÉ·^<¾á'›lÊœ ³fÏ ãŠ? ý ÍÇŽµž'H/}ù_øšžªVýÀ±€œ5Å$Å KófYÂÄÎB@tà­TÃ:êÆñIlÜŸÍhöÕS‚"`*$«š¡]FÈj\\9Ý‹åÊð| '7š@˜é:ÁÙMxé=JÔ9™‚Sí[ ïAdf­ïxhŠî>ññŸ©1pò–ýÓ0•!ª±KKëa¦yì/ E&›’~/÷ߎØüÌÝqãÑ#y‹ëO,Ü)ê €¡>vJ$š4MîéôEÞ!yçXø“ÄN­?·¶sû²oþ´ªÖÊ¢dñ£‚lž¬í/ÏRCPãQÛÈÅ]yßF^“\ò¢ë@æ,0-BÚpei—"Ö24Ð^!á‘p±Çrwk‘Äé·“öâúŇ ÇuPÙ‹¥ ‡î* æ 2‰NuXMjIõçÞçK ·Cwkó°„ÍÈŒ A«pýgJÕãLÎÐG$UË­GG–'±°†8ó=²UŒ@¨å-ð2è żºMâNÎûI O¹ñb› HQÏGŠÏЀ‰"³%GßËêY± Ccz!Ã8Ì©DlŠÕ^–þä7;DYÝx†³•~¬·hßßöëÈo£ÌóŽJÚ×ütYͶmaM*QO[©wÁ< ½Èi±ìn2(K æ/$pëq íóðfØwþÔ;= 2\ áÓ¥´†0é7€;KšèU›ÿÚ~@Ÿ päáR¹LWÍ5%·$ÀšÈvWäˆSÍ' ¢À0OŒÞÃ…qïµÍ+L?§MyMõ>zߌ½„‚ámV™Îï³Aü¨"X ºÅpU£[ÉnÙ|¨EUøãŸ€W‘Í¿×Ó¾œ5ì2ImÞ _xÏ'úd$}&Ѱ Å•6êzL€þòÉD$£(¥ôü£dfSèÊÕM‹C;¥"®fB´¸×uóáÊJ>|êwÄp” n¶iØ cD„GA¡„9=XcÕYðVðJžf¹£|.g×}(Ûõ0¯Ô䈡…ç!‹'ä%”&.'^¨Aâ‚@à÷UAþF>/ç0>¿ô(e#Hí°±Žd‘*܇“¨J€æ‚ò1‡\0.ìHÏòÍÏÒ¸ÿ×f&óK‚-ª85$šÂìL5ëF€|ƒÓ¦z%ŒÖ2öË~ò™—Ó·Éý*F7ñ?Ó+³oG,¨á0†µ’ž¶áè!7/’¬\ë°œýUX÷æõ…õ°U° šÌŸY,c_Ч-S“™•)–•¨TîF7d¥HñV  ù/ÊVJ'R yÁK'fïI"¤%•'…UjavíwÃ_Iß°“ ahÍ(¡ÔìVÔeeVöŽ?²ró~è!Ð_ÎU‚°›T»âÚ‰œç#k)ÍB.©©tÏrh@lvQeÎá>[¶ì/…LãwŒdøžV+w\èààÍ}®Èõ“Vðâ $^Ðü^J)õ-zzwý!Oدf%Ù­r1•d‹Vd¯ôƒ†‡^záñPcšþ`yÐpiŠðèÜ<ûJ c­u¥A”tIÒWæbÂB–[ÀpÊF”6ÕóÄ´)Ãõ‰È§àŸ˜?° «CúÑ;®\ožk¢ ߨ-“e°4‡âûèµ:¢yŒö=énë›÷Ø1: ç·HÖ̃ßê´›É^MM€%ìê›PÝLdŽê—ZûºéÏ:Ð Ìã§Ñ×÷o"<MdÍö«.±,Äp UÉ“]Ñ÷ݽ߇*RMkÿðþȲ»Z%œ¤ÓCJ÷aäöQ³¸ÝrbÏd²Xt ¼çª{Jhak™%×Ý>Ö*÷™m¬eºÒà–üsÖ´c üE’Ö¤Ò:›ù˜ÖÑú È»åÏÏWÅWÚ€.ǹHpÙÑ_2ÊÛ܉&$ÁĬÕ´<ÌÀ†Œ 5±h62•›ÜˆÉSö *ÚÕWâVh„J2’‹œ¯¾# g—À”ÞÏþIü'6é–ЬãØXVrå…©¨ñ‰µn¢Ý ñv|(º9HF£¢8Ü_±ùuîSýs6Žä*K¢æ™²Å|ä틱æä˜/'×âÝAbéJ¦Ä@½ˆêA†ƒ ¬î'‚ ¤‹À»ÜÔ9çcFœÜä¥ú©û'ŒYê“B¨e2Î܃PjN "¾¥•±Ãô6Y,®ö-+O²D„¢";„˜éwøy•¢gîÝ–û ˜‰¥u´3zSÁös…:grÃsƒ… ÉQÅtù·.¨bÑ4¦»¾Ùxjä$á¿_\ÚIS“ ùV,YÖ¢ºJïóCVÛ !¥v«éÄü8Œ ÊD`ïr+ˆFÌí‚f¬(àËa…)£ÞZÍõÄTŸÚOÍ|ó à3Ñ”Åöú‚‰Ë¾ê¶¬¬Û¬“Ô)/»x¯ô^òÕËÿnaçW¹JdS'OÈÏbZO‡¨`{¹Î5À/KÏ‘¥åJ7ù\+_jLfãÕ$Pw¢¹§/ž×;ÛC%ì—âvÖ)Û^U#UOÜ-Ó>¯ïqÔ]¢žêLy‡þà2Þ³wr€—QäÃ/ Z³o.ZXdwá ï´GKÿöÆY²~.ËèÜî˜âÌãF>?vØÉŒÇ%yvò‡ôžòQçxG³ª²émׄiÏkå`NþT¿P[Š Dùçi)Ñ*8´ÁAÌ듃>J PwwRëL™bíò>/>•OÈŒŒ°ŒI .Kɤ÷¤«¸$f9»ñAÅc4 Æ’Vw£ÊìVz Pa´û<o?}³ª<^iÁõøH7˰ýD•“@¤I„áHœŸU'½²[ËI©æµo-ÎV'Q+“Á㈠r!»‰†¶–¦ÞbQ>kâÛˆb³Ç¯³Ƚm0ÉZY@.ž]T‹‘MG‰Qc22‹ê3æIåô®þߘ„²„í™Á’é]]¹dð;Á K@˜õÞi8Hþ»°2¸þqœ ¹¯»Œƒ¹øX¼’‰³ZÚn‚²¥Q} ôú08NrÌÔ³§ñᔎCû¥3ÔŽö“åDð1A&¾HÌY‘#•!¶Æè‡Ðñ354ƒ¼þ…&¢xëŸ#~Ûù—ß)¾ ðóˆI"Šc°—©FDÞâ>Ô‘v‚†g«¨;8+%C®Þ$„)_0>ñ«ÒfNYæïÍKêå? Œä‹Úu„ ©iN•„ü;ûà *b ßôÁ9 f¶cg@íÒÙã‚L~VÖobÙB œŠ׎ÑYóÕ4É,·^¾÷#P“(ªÿÌλù•ŒN}¤‡žNß÷vlÇ‚u íð=aæšúq:¶¦nFôzÅ MìŽH‚L ÜDz¡K¯ä³=QQ¯U'm\-êQ/Mù[iWý0Ê~G;L0%IÀ¶ê“g‡áêm´£MªÙOÓæÀa’1;E.÷¨íÏ8•TM´L+ÿƒ4º¬P;۵ØÀ6nBêptƒ»ù.‘|–Ó&½e­Û?%zmÍZœ8n ¬ ûçLu]”BóþºîCp…0¡Ê(RÛÂ×:)ÛÉð{à-Ù•êFûI=ø¬ïÏÞ¹{3V¿X€ï=&áªï€UÃxòcï7´Ø‘<4B Ññâ%Δbzç@+7r¾Ùe…hŠsx¡u±žð~å~%/êù¥“ó6(|”_TY!‚Åã2ƒí¡D:þ“b7f{Ñ »òÖ&©-g}ðNøW³ÖÛH ååØà¶°íÉ… ?¬‡¦œø|²„ì oŸcž‘k1w ±ø!v‡qÈ¡2Ûã8¹îQ<ª¯DâèÒ3Ïd7y‚PÏšÙáïÁrÍ:™†å äQ3‘ßïlˆ L`íè’}EÞTJ3§žF òjjR.³?càP)N¢@ë4©ÂvºžYãˆp8(D“1<Í%ce»Rɶ®_êÏí¬Ã¶’¥æØ3ðôV}ð£WüìªqÅÞ[©(uÍZ{š9”¡©éFŽ ·5mB¿×Ôr}Žˆ…Æ%¸ò¹T±6 _±UD¨{ÃEÅ~B E¸ÔÒv-:YþŒÍ(W+P4hÇ0 üýŠjn!ƒ7xLž«‚5Óû-ùÚú Ïsà™ìÏœŒ·Ã÷ññRV( fön( œ•<ƒÚ®“‘bÝ•†O¾3ÕD´U3®°±k-¥!Œ7ÙÒR™¥NÞ•M¿ò÷Šî™÷1—û÷p¨>Zûß,¦Ó ù ù19m‘;˜ÚРŶßùÑIÞžû`È¡êÅ%”!b¨Ö©Šf‰¥Ùßg¼øº›…[ï‚¥l4 |º>Nú$ƺ½8£‡‹a4=»^ ß1]CNЦÇsó^¸_Èœ6ÐyÖ/WÍ‘Ã鞀3oj˜¦u4˜z Û„#MíGB+Ág¾\ì/ê¼?ƒzZFl+EWX®HØ»·ZÅ7¥bX¡¡d!É ßw–(O%zO°[ wヨ òÃãœÄ‘õÄÏ„5Ö(²ÿ~ÝòŒáEÞËcéo¿™˜Ç|?å:ãõΩnXp’ø™9Øzl`›ÄŒ f4ºÅÖ¤ÕjLå—Ï­Û¨ä#l”U#÷H^áÖÇžYƪàßEú¢œÎƒÁˆF%¢_ÈÀ÷IxbÛGÕ*ÝòûÁÛåz^‚öÇ~)}ß%XÞ>A^âwnNÓÊß*f¥ÕAmÌbp³­Ó9õ1™ÌÇ3HŒ…U¯«ÍLƒH»nÿlÀ9dw{À£®™w¹R8ÃjÞó"Æ^t¥=aVŸ*Õ˜ã\Œ~|°RÂìù‹ gOû*0áägûª]jÁÃÌ+šTìO|³âWëU‘3r&‹|èÖ=µ!’ ÃgKx÷sª×жónй<#UÁ>Nò|ð¸×îHDPªÉPª ò ØãV!V4“¡Ô¿ÑùÅÿÊ/ú‘u<ñZCsý€§>HÇxüê"fZ }’J+æŒd޾[„`Êyû‘¤Œ'éã¨™Çæ+ÃñyÝÅ(öãceAd a74Ä|¡µ­\µÍq ‚¯Ärÿ~ ¢µü0Þ~(.M9£×>§=ï ®í=V”ïÎjd„.C^¹ã< '.ã#¥B0 Â¥Â4Úº©l_J¡†`µ%”‚]ÒG»Vc¾Wk¬˜i,-8w~‰?Ð-±¡€B‹Ôμ›—-<™>“73csõ`ƒ¢Éš&Zë‹!;žX_Òü!˜4eõð0`Øò(lãQ»1j·8¬“¿†Þ>·ìâ&cU \G0S3k_aÖ½h){!Üt'·'}þ„Ás`“:r°pÔù¡ \²rÂÔð«A¨¡ìZ48ÿ#ûTÖö¬žA³ðäíVÇ24šéåò›˜`ÜîÖLYhÓﮓ¤1ÀлFò®~ S­ß5Ò—Ë©?,×¢èða˃¢óÞþ‡\H¯¥öi“—|Màל)ì^%ê¸ã¸äùLÀ¥›~D^°™cÀ|&­Ã»îË»øK –äãVÛ;jÔßÙ‡®6{4úij»]È5iÁ,F_ÎÔ6P[)rº¢'zïeÓl7f?. ;$ÚË\ˆ,âëîPŽFnŠ!‹ ZæšyFckÉ.¸ås ÕÇœO:ëз55s@š¡N¾k§ú НñækåŠNIšÌÂc6¸¥Ë÷à0lW=Ä‹…ø$€o’”ëôâzÙbÀç6ª{Žo°ÚÒœÄ?¸+5KeüTse ƒO¯}±‰#f·yN<>¡ÙþØǂʽ‘îŽþ¹@ý)űËR»`´±Š¯¾]4Ó? V“š#ÛÆl[—´ ¨;‹ DÖvT˜¨ˆ¶R«¯ó æn~rk§ŽþH#@:<ãÒ8‡ð}{t½ÜCÞ@9Ó±VFø‘S[p XD+eD1C¿›äq'|:néïY™šÃ2¦‰ó’âÆLá­*,\zŸüÊS÷æjŽâ..Sà— 1ÂmßîDï𹵨eÖJXŸ(åÑÇjá‰+Ä#PBÿ—Á¦y½¡2Tâ—Eܯu©8ƒX~eh0Ôi”‰Ô¸òû/%9´Sn½;¡Ý²Ë´Ü/ÀÞgðàE°e{=^×Fº&…Ý…êôiâ}2”õö :Æ”÷Éíí¶¦à4h[²ßý~ÅŒãûM»ƒO";äIÍ×Ç0≬¶ŠÂ&³žõõN€qò·Ýž¿j+W§ãã~Jrŧ@zèÙŽWÄk˜\?dé0qÂ\¼W¿uQ)%š éyàëTéZ;P¦PûÇ#ØŽ$#eW²)ËèàE½*S eE¶ÔØ{Ñ@MQ \Å[YÒ×4+ÍÄ•fµJJ4ó¿\ÕL°ž‰ºëxÿÑóûùgwjû³üØÛÕôÈCăÁIôãœôÂse À» Wi¼  g Q +U3ŸßL™ä‚k] 0ÅP½d3t:Ñ›A†,Ïj M"p -x¡¶›ÿ*¯VËfYF êF7?Ž ›v"`(¶A 82CüfÅÌ*)†Cé XA•Ú0ÇnçÁxd·W@J6æµ–(z6Þ£Õ½%¦Š… ¦wú¤Î¼M[LM¹ÐFòš¶/v¬u.ÛÇ (¡cŒÙs•÷Äy Æ/ŸÍ+Âü‘–¹”m%]¿Öð¶(½ 6N}‰Ùgœ¸ÿÑû¾ÔpõH`¯6…;¡ºã¼Èè?½h_K´½2Tšõ(ÏìëÝû°ü9‘¤–¯ÄÖIš<¢Vñ¬Ç/: ÃóyŸéíHºáN(óD<ä%ÔŒêFIÓØÑå–òÞÁ)Œes*ŒT6nêÑ£uT–õ‹L¬ÝÙl}]š†Y’t@VsšÜ”Y¼ý}Ñ{£zôqòg£B4Î×–(Ç5ýÜóU•õB¹ö¬ï&£'têöÀ“Ä‹ùÈh•©o¦ÆÀ.Ÿ@Vw:¿ö› 3´;ù-sdÓˆÑψÀ„+OIúF\Ø/iÔÄâÝBÄy£)ÌF¢Oû¸UÁÝf¹‡‘Z%ña., ÅÌé¤ôYpøÖÑ.H®56èÜhª/#>J¦Ôµ}9©.¦Ý˜ûzðBø³äªÌ¬¶œxÑ w©-êû{ËMÿ€Å8)r¡ ¶Ú„P•ZnoäirÜW¸BRo­G¸…ÆšEsÎ`Šø%†ä7Ì|¤pÙwšs)³?·T‘½$ ˜ûëÓí”áÃÍ©œ‚¦WE ïcõãòÔN¾ù›úVw V';ô÷«X—ÀfJ¥ÙÁPÛ†¢™L÷ PÓÚav±S”K svÈ2gDŸHÜÝL:ñ¨'øfÌLf ¹l(hÛÒzdáÄ’ p¢5yÖ„k%Vë5ÐxPL¹CéqF¡=,Å&XgØíahê<³X,¹ CÛ’7¢30‡¬á>´d£æöm¼?¥ys©â2@2MÉ&UrâÒ×îÕ¶›rTP|Û «à7í£XZ“Ë#KÙ±òù`Øc:T_DÖnˆý a.^—âÛõ~ß°;×¥|ý[§á ,\¥@ù^ŸÓ¬¥üo}× ÌKJó¯ò1¨§j-é䞥Ýð!ÉÔÕ”þ6ééj¦Ì;¦e’Ô=éÈgù%žÕÎì0¤ÓGϧö=òØ¿¾ wŽ\ÆU<ËaXÍ@¦~ilýì–`æ½ÏÄ•]5[ÒÖÿ‰¨šú!J4ùxS¡¥ ݼKìÿ¸:ÒcÝÅ[_ó›1A¸»ÌƒNhPVqÎøñ·%þXVáB‘D0»û3QÖåŸw4EŒØ0c†þR…Ò²ªr. W+\Å3"B¤¨‹U³fÞJ»Œ¾¡ 1h¬Á —ßïéC ‡ì›ËR”V~ÅL–a½ý˜àN°%q’?ÒQ†G¾Ð~!Ò™Á÷Á¨ YÁL~µØÐÃLÎææÎŠ/¢ºuBäL: ¦,2µñ~#E"gê/õ‹=X­Çd×7'Y¾7„,\‚%¤ ˆâ¥ÈqÔÌTÍ=Q¶¨ Íì–Ù¦Ž³®#Z/½Ð Œ–ã¿m&ŸÔƒ3›[ĬÈÄìŒøÝ3€° źæ[É£V=ÿ¹‰Ž†„ÂB0í‘‹ý¸¢ùP_J •¹>VþQ‡"s=Óøm4\±±„V…²AÛÆÆ­_-æ°žkgÉÐÖ/ ﯺ!Òú>•§9¿{‰^lñ´lŠò´b:Û!ç•ø^2©ƒUVÿz™—ùéGœû© o5ÙÉâ<º•Þ>IM`¿´²vêËkj&Où†KFITb¸?‰ 6Ͼvôw’=Nw¾š­- ZS–áEBБüóW‰—\©bf ô—ðÁÉP5yBɶçV¡ˆß•ßíÐ/#¹YxŒä? Á ¡»*Ûg7¬ ›ÔCĦ÷ÉmjwÂî 5ĶV­Ò3\®ÉHeøA¾sé½* Ô~LmÙª Û]@IÑ`®0íŽéW~ù6SMÉCgèafÑ)x4jìHÙ¥róóOUî6†¡Ì ªµéÆ¥”rI… ý†FÏï´6²Ð”0ÿ?Z5/³9,2D+½r&¢Ê'2 h563º#ÓJ±é–,[&hOÌ \ƒÐeúvB#¿"Y~¿$X€àµçæîKb+ìsž[Ú- ÀªÀ}süÐcù‡ŽnVŠ =•?­(ÚqJpÆ4®ŽFÝÓ-J“}¥6jé³ô'³_*ºŽ±Ý‹Ü#?"i÷#n|:ã+©=Nõ+ß=ûï#=Xý¢è›¿¿ ºGçQØ@Qçó¥ºF!$ -‹Ä++@ !ÞÏ ƒ…Dß«$˜0f·Š‘žÌý—4Æ<^xšmGd¯`”Ã6U°Ï1~ChÓ¨’:§ë¸1t*›;fâkÕŸñOV…I½z¾iá´ÌD…œ޾g7´\ônÙ;j\l7å—&¼`›‚ÜWm´.––ûR~~1Þ%¦ØP¡/³ª7”œ£o§‹ìklþU#OG¡¾ç‡—0Q-ª­gT"b+GÎ ÝlÄe—‰›‡ˆ+%ÜÅÁþp¬o U[å¬ÍÍòÓš†´ xÎJã$I`ºO(W8|U-Óè ƒ®ª*PZ2Ñj^,T7 úš(vØl˜ÑúÛ2/‚TÊûB3–±$ÿ]uç×H¯SÃäï•þýSµð& ,Kþ©¨a¼Wl•ÂHs?'Tg‰d%¡6Äês6œÍ ;û4}[g'¶L" Ë`ö‘­í/‘º;Ÿ\/£ü„°?ÖÜ|è4<Ã޵#4&Àèòe´½ö<œ¶‚{$XÒÔÌüÊѺò‹I!£øÕ€÷ègóÙ”eí7Í+Ü‚QưðüKÔH«öŒ¿®ê­Y¥lªëòÙÁpKªûê[ŒpnM˜v³h{Œ²Ÿ´ë;"+¤•Âï´›O5%®v÷Ã\3ýª ^‘uØDÃ!ιþ~!= ¡G0î׎aù|n!ŸÜy^yfh÷Ò"”‘åÇqfÛ7ã3ûjá2é nÈùëTíÆœ‹œ;n£}?žû~ Éê<Á¹ ìñȼ)V*RR%ÌN|ªúj׈TŠ}i&N÷ãåÒáª92òG¼c,£5‚¤‘>ªÊaaϵtJ¼måØ˜Žªšƒ”f‹w¥t ŠÇj¯Åâ׋W1ü|ƒRf*‡4w¿É.Ęü:݈_xnñƒƒ$\ú£àrÝ,ÈȾý\Ùà—­ÝÉtéÎpcñ¶RëÍÄ Ñu̦‰¤aðÜ^Îᛟã¯+†è(¿”OŒ“lØÝΦ Ê†PäÇ^&‡Î®0(·Æ<²„Á–SÏ·jks»¢„öC†ª'[‚å*TWÊ%QŽ{Ñ¢ƒŒÚ4¨Ïå“{«5_¯Ç>³ã5Zå‹ %íñHåNo¹+Û麴cʳ}ÐY( „³SSÜiŽðÜóú2b6§à ÄÈ|vhÆ•m?u/£å¾åj ®9 ^Ko¨áìÉMóh2— *Ñ'ÃU^¥îÔ'¯Uƒ®€Ž¥þ˜¬¬ò2¿¡;}¶ÉÁî5Öž¼r¦hÝ•n>_ ø‘aÍ:}ùziÚÌÖ•b\̾òvàõZr…9>úV.³ÕÇ¢À1aÜà rôqnqÀš´±jB<÷”®“­‡ÏºõšôƒWwœ k¿°Ò:[sø;û;ö+œ$åòFZ®•6æa¨:¯n+Îþ<'Îöw¦ðXM—@´Èj)>1óØ$ÌpeÝMMïË„ˆÈ½4¼W¸7˜^•~]G¼ØC§Ú8;ªÃÛˆ%ˆt‚‚âÉ'+vDUÈ×Ê2üeá¹Dµðg®oŒ—Ý9òèX‚Î*íñÓOöÞl™¸ –î ÍØñð=-zz3úë«Ó¶€é¼ÅÙVœ9VÕ´²vË~‡›¸ÐóãNǹô¦jÊ7WœéFÔVx­Ù“<€b¼Z&ÔZó5ÁL”º"”þÏMš¤|ôæ`‹àFu0Ûý@§P1í¯—þ­Ç—]klG–<'˜ò±g¨¦š1‡O8¶aì 4¥7u:†ü¥›´ô\M6¹ÖG†ñŸ´õ¿šMã5ï k‡~ïh.ªõò«ÐËÏãC^_jÌñ¤Æ³9 ž¤Éu {û0`°¨¾Šš0&˜®RMê›`Õ<‰ZKqMϲŒÙo¡,ÿ´š‰9ºÎNıÂG©¯:)¯?[ÇSTè߉‹ SÎÄÎeEÞ€îñwz©6éóCµüÖR½3%ó7ïr›ø¨ÃÕÞdˆÓ¥ Ð`B%z"P³¶;¡ÛœM~žŽ')¿àСáÓB>:šC°àáõÒsûî›~0ŵ¾œ˜˜(’º·8øÃ;1>ÄcöˆY³ÂpP"©0H‡¢ÆÆ÷ùRn­¦‰EÙ­yÐD±9<8«íøq*"H)骀‰+môUCðÍĺYèòÈìJ¤täÎjðåô ž#o×Y“𦟂ԸÎÙè®;×»=sv.Ñ–…§$•¯¶sN¤‹lô<ß>-N GUý .çZšbÍ'ñ6¶ÈEò2p»•@§Žwfç°íõØ|ãÃQ½¹BpÄHÿã!Û2´ŠýoñU,XIÃé%PÍ:î3&Ð"³\€:)¡°¸ ³2Mã ¢>"÷>v¢ I~¬°OÒU9«»¿+·Å½jãôźù*ÝÃèàOêo¿Æ‡ž—ަßH}S[B=;¼¼“ß3¦½‘8‹Ä¹†)QKò/ÌÃpîðÉæÉhý¶úB„ÊkxÁIÜ8ñ 2ï›·Ѽì†sE¯ ";28+,‘¤GæH_,+õiiµ½b¯AÝ´ÖÉ 4:È –h°a†ñ½ç@Ä'‹6)Ê•w—Ui¿Öצˆ7‡ ²)ýc7òݳöÕ<0ØŸô3®V(Ä¢d.¶Æûb­+€‰Uqj5Ò`;¦úÇû ¡¶SÁ™zËLf³–¨ÛCdóú‰ò¤I(1á7¢v×Û˜Ù3¡z<µu„ê8ËRÃÕÕ%é b{èÒ󯬣$ÛŽßÃß3ôS²ü“VÙ“KŒòD)Ûˆ^A©*IHÛðÂD‰ †·Ðq‰-žâ=^¥_ÂØ L h‹] ÁhSçõvÃ䋆;EE·ÊÞ.ÄA1šG]8Fcù3#×,$5LDîî¡(÷˜³þŒN œ±;ç)$eŸŸ¬ÂÐXLNwâ#I碲f"(û*úæÎÕ¢‰v>ãmÜ‚f°‰ n;Œã¯v(…¥€Ä9ð1 TïùÏóÂ¥*óT—í|EƒŸ8i±AÄ«±í”T·¶¢=fÐüŒSÜÝ}±°.Y¦¬1;¨ÍOÔëÛ'Öa‘´1êÉ”ðĪTfèìVˆ©Ñƒc²änM­þ\Q<8чÜT±˸¿]RWÀ,÷9åf.¿«Ê4lywÅ%C€ÃˆU …N&IõÀØž Íù ™%eGi‰Ь¢ÄŸÑ]ó äßD4»Ð7HåßÛ?¸;ÒO 4}žðÂ7A:‚YÐóDõ?á&DËëXò(QŸ‡"8ô'NN#À5}j„è>n+¯Éq2hJÓË<ó‚¼Ío¼£ä/r¯‘!ØÂúýi°å¨ It˜è¢õ™´ L.½‘3ËQ & -‚=ùƒ>3MvÞ™¾kpÞ‚LVŽÜ2ÕÉ€(iWñæTU¼‡úe3 ÏFÀãÚt+ø,¹¿dx_Ï +Fw…D`l¶ú"ø ~i£×k•UÃé¹³SZa5h¬,mÓ GÅîZð:Óø;³6_™_ íUúÒƒÀ?W[Æ;KŽåФaØg‡c׋¢™¦aR0ŒzÒÌñ\Ìr„‚ú­lÙ(6ç×­3c« ”:·[½/N¦zm·~šŒ`ÿ÷N)Xm÷âIë(÷Êò'ÏûWª…xjta–#„LÒåè2ø˜„Vêñ$Èïvc/C|áï€Q\",þT`Q6‚(—Á›xGÖԞËö•Çâ“×-4Læìð¬žlG5$º^ØM¶û)ózO#žq÷nsוvnž"ýP}Яr#ŸzF‘¨Sò¥ã”‰!‹}û7Á)Ä™u×nà_ÞPDWLØ1)¾ó•st²Ä^<åPUí*FˆR:å¿Å5ÙGÇdÞ´sÒ³Õm²â©'=‘m;ºæeE‚£ÄçèW3%•™Û wÙ´h‰ñ’øƒ™Rv¨q²§Ìß®èãl”¹ 8õÞ2¾|3ÚM×Ö6DŠ;f}[hí2#ð—Ž-ÃËÙŒuðä/€X·®·³œ3Âègˆ¥…²ùœÉʼø©"<g¯+Ö _¦P˜$“6ÙÏ2ƒBåý|®§¶/m“@þĨOÐ"±^Þ'9 ˜ŽÄO‚“×èt7’ÝQ/qiÔ 3‰´T¸U©bÖØ£ -|ªIÍýŒ-;žM´l¤_ Óãîj5BuK”RLT£;³V;JÎ+ä;¥VÕ1ð¾z¹UeRˆ(9#W7QAžŒ){«l3 %&µ/3‹©é¼cÕÓùΪæð´û“·Ӷa2Úlï0ÿ“Rîóù»|ñš ›¹×ÅMìÌ¬ì Œ0;QBøkÜ*\¡ƒ™¬nTýnõ—ÀÂU¶ŠF3-Oæè(  ¶GaúñB„*B ŒÂ1ÀL÷kõ3ÛдÓÍÜ&û}åµÚ¡Ú©2V´fG »MšåP<;ï6p*&arV9•UsÛm¾ªìjøOti'Îxà"÷—lW'©ë^3ÍCÔ2è*UUké" T@#nêþ‡YULýÄØÖ“¬ù¡&”(Sù¢ùM0„„∠ˆz/ Ï5>^c(?Uü£«í”ÄUCLíâñ,_ÄyXHl…€èìÎZqòx®DúÖ4ÁQrZY:Ò`ëÐyÒ4U:äË3¤±à¨‡Kþ2ˆi+ˆ:1b×Ôn/'å^ÚÍÝš‚þ(¦ç 8?÷}¬Ò‚Auq âp}okÏ¥¯)³@vÑ¿Î)Òõá7ÄèCé2Ô‡ÞïiŽkEÙÍC(»2ÓAŠ0ù®&k–¢-ïêxdž^@8~å:ð.ðq×å;tÕ`Þ>²T<íì5ð §(ç*>þû¬:V4jøãü¼Rˆ‹5$IÞzÿü½q2[1¤ï`>ÐÁlv—·7ºÐ¤RÓ»â°ækÝgZ9.[~‹ícŸ¼DFg±y¶~ ´èføSlH¿y)Qr» ¯ =ënX;Õê›ûæÊB–Nݺ­‹uizÙÕÿ ÷õ—xöÀ¦¦ï‰·”ˆ¶_++¦ÍiÔ)€Ý#À ÁÁ“ÈŠLó?–«#%Ø’æév!Ý1Œ…Ü!t„Ò¤c½O‚ìÿ¬^ùŽ1Ô› lð`¬ó P»Nl 97¼‰õHзÞÌá@IfŸ•úH¢¦ßqý{Q†Dþo?€¾{ß[.ᕱ$°›Üa¯;#q¢Wu´²/"`ÖºÑOÓûïöÌ Àh8ý<0qršqÝ…àô“hœM[®“»6³l k@ÈÓºàpÔç‘ÆN¤MãžÎê}抗*D$zôWzPé;L½Ëv¿a…7­S4{ !¾èÔø ¥J KÖr›·ŒaîNqƒ—Í`m3,9{öñæ ‚P'ã|½Êã#ø^²§ nñô“à·Çõ^ÚIh¾i´ÒÅŽ¶ }±††xFâÇž.šn# ³Ú… OãC·2á@ "!žòfÈ "§tÏ4S£g' U.ÞÉ£¤º;•òÀ-­­ƒJC!l‘ñÌгìEcò*wng/Î…¯Ä`«ó{D¸ýÆ“Ê#0kr$ñåVM} ‹^øâ6ó?]ÂÇa¶F‚‘ÇuäTä.Td¥+[펅 b<ŠâÀ@#ÿ¡Ä1ŸËlåÊ+¬< _)R•­Œqd¼¨¬å$Â[œõX„hÝwv ŸVŽ5¦êÃ÷$º´ü]ø#uÿòÜ [;ãØój%Ëuîe <äѽÂ2Ñ?ûP}hÖ¿u=¾ 9üÐ1‡lWÊZ‘SlŒˆ[y'«Ð{©'˜c™Ÿ†Ñ;–Ù““ôaÆÙ†f6ëˆ+`./…gx’/œ …ÿ"ÑÁA]Jµ]ü”ÙaeNäkµÌ¼RäÝGòÒ쵺¨‰À&³µ—UC»†Ó<ÖmœGÄÔÇ—âìú—93ìOÊäjþA/ JæÏ"a N–›Ç7ùAe@›?ÕÆ!Ž ß¬B,øW_'=æ¨D”2!<û¶6v,Êe›TöÅ™aŸ2r#x é|×±éIs¹I¿‰˜Dà‡¹>ÙPí ½d5($% µ½jÉ|aýiä·ðµÙáE¬¾û»jµœ\8¿79¿¯-zF!UÍsNм ™£ÿiI±,5WŒS|±rø~RÂ`è>7üOΔ’¾lŸM«Å?ÇMXC^B²5xH8Gñ¼/ ‰Ò/fp¬ÔBªb 0çÝJËÜÓ‡(µ¾qÕ¬þبіr!µ¼m0‹; ïN¾¹Äô]ªwª•…òu‚äÂ1Õ5‚œ–áÈíXf7•ò³ÍÛEƒÞ‚j Èdã]…òp×Ê el9άüȺ¿dÖ`&í„á­¡‚wÜçØ4Ê1Iù÷CyðL¸>ƒ”Än(&‰®mÿ·Ï½Ö¼©ª7FÏH]þA£Ôݚأäø[±³ 3iÓÍL²Š­ª°´8ÆŠÉøÄ/8ú7$F,VÌ‘eõŠÚ~`g)‘PêÖ¨L©¿_^""hÓº¥¦ ´w޲}ò]t×™Õ®Ý=«AîØÛ] ÿ´Lp/¬"Ôº<;ë´Ó[8e*>GòØÊðUÓØu”XÆ"‰=²ÛÏ‹ŒœV åòíDÌ$‹=¿uXE|Ƈ‡…>%ªÁò„¥Bó·^u¸.ÆO+#ʃ¡zÇyXqZйùý?ŽÛ‚šj¾‰Ùh"&?Fy1Ôôâù«øD¥ ¬uÑèUÈr˫͠À{oÃÝ×;’S±öÿ–^v7»VÏ‘½CWÝ=ë.ŒL&ÚÒ÷„ý•ØQ¦Â5‰×ßͤ…«´Ÿ7T¸5˜Ú ×a–/*dúÿ–0eÞÿleÈèwë p‰ÄEhUMxæ©OZIÙlu\²„kýˆñÝÃw¿Á1pÖ,Î|Qí^lU¸¯Å.}HT®ìù…îúÄôÌèâ/¢Ò¨ÖŠ\;ìÁz×ìBàÅ.Oµ ‚R/ì=¥Þ‡Ž8?b%›Ób>Í‹k)'1¾·½n¾§d³Éúè È'V¹œ5Àf“{Ò!›AƒYúßÐÙñÙpñtk0ýóéMW tؘ>ß`g{*‡P®*‘-'†Ä´ŒO…¸S cýî• °µÉÌõ&û@bÀYßqd4På‚Ë 8ììýôÁ5îŠ`Ñ_XÎ4`ÓƒW kVíN4b¿v{Rý¥"Ë_yõ鯵õ=ÅÅQ@Nb×N‹ªv Z‘§‰û7Ü(˜6´M´´¡’`,¬_h\E\aÚæ¬{Š>îˆôd;‘9ç¬ „25žå‚²Ð·&…‰)UqùY\¹_“µþÔ.–sd’Æ¡'*8Ú“úœc·³¿?þËltõ¤ê)ÎVM] P qè¢XË‹?5øìÀ,è4ŠzðÌ P¾€Ñ 2³üfý M›š5öÿ³òAwXJ¬®k¢F#lëet^YiŽßäko‰º!Dvñˆ”uí}ÕlöºC!cV?Zߪ\¥8د¶ÆŽÝ6&ÿ_zù!é 0œãþÐ…W ñCI„†Af 3‹bä=¢‘%ù5f…™kÝÿ¤á0E=„Ó©í endstream endobj 1052 0 obj << /Length1 1608 /Length2 11368 /Length3 0 /Length 12200 /Filter /FlateDecode >> stream xÚ­yeTœÝ’5înÁiÜ]ÜÝÝ Ö@c Ýhp  ¸K€,@àw‡`ÁÝÝýã}ï̽³î7¿fæÇ³ÖsªêìÚU»ÎYÝë¡§ÖÐf—´[åÀÎnìÜ\B5“¥;TÛÂY…] ìh x5ò£ÑÓKC€n °³Œ…P ´È­<<nAAA4z€4ØÅ²µs0éjé3³²²ýËòWÀÒû?=¯;¡ [gÃë‹Ðìâtv{…øoÔnv@€ ÈV×0TT“0É«éäÎ@ˆ…#@ÃÝÒdPY¡@f€ püÇ`v¶ýU”ãK °@]€V ×m@/+ Ë_.6€ â‚B_ß (ÀbáìöÚ70älåènýW» øoB.ðk„Ó«ïL uƒZA@.n€×¬2rÿàéfgáöWn(èÕ Û¼FZƒ­Üÿ*éoß+Ì«×Íä ¸½ÜþÊe Xƒ .ŽÞ¯¹_Á\  ¿i¸CAζÿbÀ€m- ÖŽ@(ôæû¯îü«NÀ©ÞÂÅÅÑûïÝà¿£þÉä:Úp q󼿴r{Ím rFãükPmÀn®Ø­Ý]þÓç„üÝ ¦¿f†ù•„…5ØÙÑ` ´AãT»½¦0ýÏTæø¿ùÿ@âÿÿOäý߉ûïý—Cü¿=Ïÿ-çîè¨fáô:ÿ¸`¯7  øëŽùÿb-œ@ŽÞÿMô¿êÿÁð¿Qt³xmƒ¤³í«\\ÿ0‚ r / µÈÍÊ`cáøÚ£¿íºÎÖ@ˆ#Èøªåßm°sóóÿ›OÇdåàüWÓÿv­ÿù«<óæ”V2T–Uaý÷Ûôï(WÕÝt¼]^‰ýGª`ë.þÂ’{|عßòØy¹Þ¾6.^€ Ÿ ß“ïo î­U-Ü /€ñkÑ\Ü—þÏ¿V¦ÿ#ël¶þkN´Ý,œ­_G럆¿ÜVîÈ«¢Ÿö×’ÿsý÷^@+´ù°•p¨}ZfºÛ7¹½Ã2ÆíÜð½]Šjt¾æV€ÛÒ"VËÌ+?rÔŽ =7zOï»{¸O’O®É~™´ÅàøÖ>¸·F´ÞéŒ)ï»ye Ô¢íQ©Â¡ÿ˜#Žòž—sï4ñýfKŸŒ¯ær‚Ù˜”! FC>#! >çá“yot©àz<“ì$$ºNÊ·÷›löøü+œMçIä UXñ¦O¡8rÁ£ç¹ÚÇŽ6  å¾£/hy¦Š2ÿY)>\DlþnÜêÄq£¢N€@›[%ö'T¿°ÚRaÐäëÔmÊaP ‚1Ú"}­è Ìz06—oïõ ç×/öQNÑM*?&þ Š—uô7á*ΓKqÊ‘JåŒJÔ ¼áµÏ½OŠ»+ë¡¢5üuÝ{NØc`Î;ˆT2ä-j,ïîbõ"Ùó¸–ºo„îùg.IJìÐáÿ€ÔŒ5æE܈óºZNS~Fª™ &Äâü(;`N6YÈ]LâLð™Öž;‚´ y¦“„ûñ®\óâä÷M˲ˆôõ„\Ì`Ê¥ªØ´ð!ÿX¡Õ_ø†Ç¥¢ÞuK%½mÙ:Q>¸¹V; #LJ³ÑHÔó(:ÉFO:ËsuWŒt Çn‘Û(¶fÀ×µŒh¸‰VWøöOÑk’–%#é¶O& WÂ]¹y*eZèñ'˜µ‚͸6Žø1öʽ3«PIÑ9…×ï¦ÈFjJ'„ðÒ[kÎJ í금­9Ìu}éô{á|_•‚TƒÕ6µCz¢e#h"ÇX´Õë=Ôùõöš˜h·`B® ¦¾`´Çó`îèºÕÊâ/gæÈ1C‚è['5ŒVkçs=$c^=‘?]4üè±ÿBô ¶ô[œ¡8M§™sÉä²KCsâðÈ®äd#mm†ïðSG7ÌÖÔ,ùµD>¬`êš(ãý¡)YvœŒmw´÷PhBƒÕq]®ÁÚZ˜š`T£-•aÜz±‹älRÓÙÆN²³¢Â¤oÓî\lwG¸ª‰Ÿ3¶Î2Ð goZ«Æ™ÐNÀô=NS‘«dO C±9æ;ÿdÑ^¨FVLcB«éüûEŒãóñ¦“îÑÏëÀ-Çèø5o¿Ó¸âˆ7È2 ñŽEÚ-j ¹Ýy¿øMŒ¦bô9ôahüаú ¡"}ïGŒÑÜÄÿ «¼?µºhr†zñ~IJˆš·UÅþAB¼Û~@]ZÝôzE3šÂÎFe¤Nzª]N?ôÃ3ëÚd"€6tÓÔÇTÐ#±Ô¢^éãÏãgñÃ)ôiMNÐÓªÚ›Cg©w";Ç ÔBØ:ÝÎ!ÃÒãyäꯜ„¢ðÖÙ1™Ö\ßmõkL›|mªÿÀÞ¸ sq^1‹7„§þöÃéåcb~lHQ¯9J…luZö]z.î#ö’½³rpSåGxcyÂaBúá˜R¬n쬜Á8#/—UW ÈÌÄü›0±s¸öò;†_ä!È?]Ù’þœ Û³±-DjHv½XЃj¾á1J©_mé°ê.WH+ˆßm|ÀË À¹éo?¤:Æ^CïÇŸ÷ØÞR‰-®(}“Ê8Åû>̆uŠ˜»…[1,ÿ. >kDO †þx¿¬--ˆ`„cÄ?wYj¸DAYÏcv¯#ðìí¢;¢ž‚ë?k¥» 4Û½ÂÔ ¢/í8 ˆ¨ŠdRªŒ$.e[ß½ÓJ»•ÒÆTljˆ9 +iJí2*9,GûLöjÿwGÅ©LüMÖÔè²KE^ÓYúš ò!xµï`S®Š!:Æ åîãrýÛê/8ó*ҙɰaX°# ü”)¡å¿ž%f­ û>ëE¡¡MŠÖK3Ñj·P£-ñVÊ%pœ´Ü‘12"¬;,ÒýžšÏƵæƒö ÅY•âlíu¾† L,ûn¦&ʤÚÇ»¹Žõ›i^Hû7+ƒc3™Yýj„WKö§aùÅÅ|On—èæè½üä¦úÉÙ±žÒN*ÀbÂÛ|¥j©N me£ßC’±ãõ8-ôü3ñ‘ßsœ«Mú>»˜¥¼5V”0ÒQâg~lºzL~R´Y*¤-PÎIjJÔ̱­1¹‹h&†ËHCW-b—Ëáû‘§BU– !)ä(&µ³È+©ÐS¶%¬êÚií‰îG ßšŒÈY×ñ›ó¾5ŠB:/òîy×Ù[FåJ\9ŒQ{U£ä~Zwêý*†®À÷ØÒlQáÑòs„(ïüøb¨°ß:ˆtNJË1¡‘¬„ÕqÊ­/]‚ß-(íÕû>&Ό Ýë9…ŸõK?.˜&¤÷~BŸù@Š8´Îy£ð/Õˆ`>›U¦:þ‹CM莛·¹yË“ K®Xºn›cŪ•)-Þ/"/T&[Û›b;:Ššé¶K#b û¢ÞÝáftÉõ®#åÕìÍ®D%dÙÁÓ®e7­*Þ³)ºN'Ó¼U_DŠ8:IP%ð¢pS8dJÜ»Š:²«ÕÇSKØS8õ¾Ö&¯óìÄ6öž“qOä|Úž|Ig¾Q*?•“dŠR«lfXè'·*À…ô«f‡î¶E:ô‹LbívOæÀ¥ûì¡|q›8 Ó+ÀF}×Íå}Lð*,c|: êÈÄÿíÖ‹bM>L +$ëî0€ð3”û&,/ócoì¶$IUm3÷=Ä %Ô7«DíTxöµñKJD´p”÷¢×јfÕ FxÓT½9ÀòÞ ©‡0o™ô.¸º³/¯ q®Iðýí)›1ÏûX”O¼Uï‚l”ÀRx6öù]‚°;ò¸#IÀ—Žká%c­÷Š %“øzîÛØø6ÚŠÑ‰ÜØ$"¢Š– qd¶d¡…žÓýÑÜÔQüî XúUqçF²B=!Åa1åRÑ|-|¥ ‹ŽŽµïˆ°Í¢À!uÊ_Ù€š³ŸÃXY~‹ˆq–l^åùyðÒÒ…šÂèg¾Íˆ¶í Èš×ð­Õv-›¡œ=/¦Â¼s/Yš‡uE_äë‚}aÌRòäŽZš)`$ŽKˆ!!ᥡ¹Û³›¿=%†ç­[üÄ’€=ph“ˆ¥Ëû"e:µÕÆÛf³õXí—ù²Æ#Ê vwÃÔu,£öD¤x¯‹§-žäêK|‚!¨Ûá ¦D°ç[\gXÊöK¿Œ¸×„Ì{‹Ÿö¾GTf5Ä•]*m×YibÕü³«KÓÒ ÈõG&ÅOÏË*ÁyÐÜq—Åë ÆÒE?ác 6÷-]¢²²/P[ýÈPg¿¤–=ZI[YÔüþKÅ=FÃxN1íùPe£qy"gúWH2H7Õ÷+4ï‰v75k%Tf8ä¬Ò‡a§¶¸ŒD`ûAf¤JÙ®:2d6ñ@èi‚ §%W0"Ê=$·2å®…U¿Uvõ“ Cªò4qª¥LpÛ ÀÊ΋Õ—øžƒ“6:DÆ2v¼ô—¾ì9í$z~ 0àM˜ÂiSßnx”9[ i/Öá4aøf™‰ÍœÀ>©ìF1 í—”†ÈdĈX^üä@§š¹Hr!WŸ,›ÊkÆGs“öIéK(.aϊݽÿtnŽD$ÊàAŽéq""»iœBq‰¯[YX2RÓæ¡;飼6F£‹$\_÷eü(ºßØ=wZÝýì°qFÞ7æž©Ôð¡` †à;ë^$Ä×Î/3jêóS´Å¥ÜøGû¿‰E*–šÇP`¤³¥øÊb IpgHg§m ŒŸÖý}è‹´ y(tþq µr¬ag¾î[Ê…pŽºfýåƒHРݤÔf68#‚%Ëצ>ЮŒ;àMk"l˜Õ›ô^|õÐ^z”&MÎrÞç0-‰ƒPlCí–©´ºKŠRL;ÊÆ®àÌ©n6«‰u\|Ïea²x"J­Ž?®Ÿ¯Äv7ñá¶RÃq¯š'°Ó(ýÏúè<‡9}^bwÁ Š9×.Fr0È;z†®ÔâVL\ÝÝýô·‡ ¦ &¿Œ¿1Ÿã²Ï Óõ0~™£Ív±5…ý¨Â–vÖ`Å+[´­:øsxGµËó‰ÎÕ•2WXNôXf¨øe¨ä+ôá@M¶ñ1Iúí‹0Ÿ6*h/5"êzoœSOJš3:öbǛٯfÀö õ`…[Áu®T'd|Ù³·«èŸS·ÃéÖ 7©‘ØÖ›#Ⱥ¸œ{WöœÀwPcÛ))Úó+úfþœv’Ÿä )’©r0aó3žµ¸ìGžÌ´eÞã†9ûTÏš-s(-uBƒÌ½è ÝJx'¼…ª´ßá²N½¢ Ò]rÔCb@H¡@•òq_¾öw9÷NU£HUþ1.¦±ã”a×i¶\¿ÚûŽo¢ÙÆñÍÉiÓ¢Ê/†µüN5oLY쟎÷’Ñ:÷O“Ç~ a¾pR!ÚˆJ% 6ë:M7 õZ:#ô~H+’“ÄTGÅ"-Âå'8©¦ÃñuØ'ÓÅjLâ' ÷I+àÀíÓhD¤Wn¢OK̮Йd¿åéããX2Œ:8ÀNß'ÙVD˜ÝÀsƘiæÊhbAÏŠËs¦ƒ³> IÒ[1w?<¶s]¹—Å0º37šÞÂæj7H"§Ôö\}®†?w-Y7YXþLÄñ2¾² &ø±õø@I%½KsÌH½ºùrk±«µêÓõ]©†DR¦Ðf`ú.Odœ9t]÷õmã’%à‹t(bº´ï ;ymwPPž%WÏ0í‚B|³\ý©#`X-ônà£ødçÆ¢÷Vàõ¢.Õ86s°ßÛšSópÁ=lËO¡¾]*Êo¥áPT&uû}mÓø¦ànñî5¥ÊÕ½¾fLð^dܙ࢑2缋=KujOwÈ·Ñ:N=xÚÿçEH&Ë]f”x)R½ZÛgtv'«„™M!sþÀwœ'úâ ¼y <É×l¾±›Âå­ØGŸ7Õks$xc)ÙR .í’¡IŒ;¹æoþÔ N™ ö‰Í„C˜`J*œ*à&0Ý~Ð0éHáÛËÓ‰.Û6­Ù¨µ({¢iD,͉äq =…´Ïoµd¦ÛmÜ?[{¨‹›ÔÛb·“Çi‘­é17\ÈjDˆl†õ¦ Šœl”\íÎ8XÙÏë<=×sÝËœ9“šÈ0æŽt…ALÑEÍá,2ß•BEÞ›=‘?å}Ž Ä?lê1R݉+“îÀŽ9œ«ãù°];6áÈSËv‡Â•PcB(ÒïSòÙHò£ÈÔÀ~°cª²* þfÒ¾1]æd¨‘Ô7}­~Aüðh ¿€OŠfkYi—”’¨’Wç\!,?xciUí×Öíh×Ó¾@5쎛![7Œíº-9]õù¨46D—‰h›ìñbÃ:•ûÅœ¢Fv¨á§º(”yÅ"ò‡/‚Y!¶ù–Ò¦u7>•2DÆ@š^¡ËWö÷J˜5l…^´ ÑªÎ9T0ûÏùJ…;ÊšoP!I†~“0ƒ(qœC°¼^oŘ蒚µ¿¹±gY!UØi_67wü$«rÝünëê+š )ê#ÌÕ‹ªA,kaÕËRÌYV-îM>ë¶…C8ù‡ûƒ0±ÑšŸñt;˜zyÜýÍ„z-dû‹ú´B´®°¸Jî²e9·å M¦–ßR×ÀNÉ,§C#h< ß ´í$©¤†28Ùû•²R:p‡Ñïªð9rD GG*%<ÖÁ0¾‰ÙÑm!.† 5 àüé9“¥)û$áäÀïÈéù~n®ùb ¾“ýâvˆú>aAýãIzA%;·«lºâPô{.ÌbmI‘ …R¢Ñ¨ªë%­_4bmÇRoè8¬ŸÝLi\pëÇ͇úb3Ï Na5”’ŸD(e¿!’t‡!HôOÿbn¯“Q]ý}‹ÉO!Tå‚$šÞ®ÀayB8¹"vú|n„ã;·¥'½Òv“„2Œ€}ñ·ˆ¤H;ä·û/¤OÓJ÷}„s¿]ì&ªK”ëÚÀèÖW‡î¢G׌}§ŸÛ+Sîã™n~T`åȃÌ*Ô§ Ÿæ~?œñ`„¾ÿ4{<4^¬Ë¿¾>¡ë¬ z¼ÂÄ|ÓZ=Ñ5s’¬mägÍ!ä)fŒÿ»&ï-•òÅ#ú׫XïÌ¢›§|±Ô¤¤hÀ¾å¾^É€Æs3OÚ›·_°J”ËÄ6žCœÄ(¼0å3½×`+c]qÊå›Ö~ìê©Eß’3jÝž Ëáè„KÓe E;ÄS[ÞjX&6 {]6ø0³G8½Çbq›¾ïc9;ZªW•Hýˆmø^(§²L`>­[öØ`3öð©í˜ÿÐ)¹6zRDUœ›V_jÁb·ô9ôõ¼ý–G ß(>Ê”ŠVtýæ‰W•û˜Fn7A@4§Iû"Ú6Ä?iÓ˜æÇy-aKØÔq=Û¯‘F/&ÎîoaJ>f–_‘jrˆöý¡ßlÞGväSϸ Ð5κëeéˆP3÷‹"2:üC(Õçfß™à¦é’¨4!p*âj¢,9E[8—*q7g7hþ¼'XÎ3`ÐM5™¼ÖÀô{ËçÕV z^[ ›§V¨°;Õ+Ï&޲¢§N~—öPìôŽò·õ}Ôhwá{RöTd˜’/FiØâl¬ñ¦0+®ËYã»ßh”ï›gótX%´×-H“À£,!$oò¶8¾Ñ‚5ÅëçMÜ+¹—DL WÁ»[Q”Pó>ʨä0¯ŸŽMDÖžFÖ§¨/SUôêK¾QÚm¼vÎJˆ¸l|îw éÚø¶À ˜÷•Áà²Ùf݀ų²¾2£‡jS»@ŠêûÏÎäyë/û+9kšØ ÙÈÔhŒÉkéË’‚ÐõÆôß5ïh"¬| íž›÷¬ªï6ÓÕ'=Í ^›¥ ×"Ìãà)_ÎöÛl%/õ:ÎKiQðáܱåøß„®ÌßÛ(¹µÒôÖ„#K}4q:þv¯PθýÁh!K¿N‘ ÛV/?míȘsªUºár“ËòñÖvk­÷˽p2!‰”JÖï_±y>ÍŽ&æ]™)LpÍœEzF ØUW1¦‹ße2÷ ÕŒ3[—ÌñSÃãŒI¬g²*ýò8Rˆ‹ ¢Šýµ× Ë2¸?§C¡so¢8̇Fš¿×Z vÇUèÛd€|?D!ú‰ ɺÕÙ—tš2,õ±ÛÏyaÌž/¿Ö4I$b¿Ãv'/ÿÜùõS_Åðס™N¤:!}4&'…­Âr#¸DÚþú¥ñ;0Ö‹‚ürÍb™*äìÊûBŽ0] ,°ÃLŽ(cÁ(·9<»%›lÔoß#˜Øy^ËOσHz¾Úf'²$—#$<ß}ÂÙBkåNïK~Áû(í¥ô~þ¥Çôô1ż”o®‰õºC|9$xÝèícô—Ýç)ÛòU•¨SÑCæ´þ´!'Dþ}º`†HºÉH¿ÐŒ\,¦Áß‘,çiFlýÓPD(/UT"HðÀæ~ÜwÕ;È“³Db‰þ c²×ÑÐv½2œA*æP:s#É£fãõÛJhz/†™(ÎJý¬ÎÏ&ÝÕÅc¾Hrø¶b]gHvU½ªd“~h޼Zb†b¤>ªÓî[{ßö27G6Ø¿~ŸjÉi"~aAlK­Ú×Ì«1ý\é~ý–¯k¢ƒÁ–a“œ{Μ¯ÈÁ‰©¢2â!tæˆ~"uG°#ïÐeÆŠÐ »ØOo⣿ ·Ç³%ƒˆÿÆ£~ከe®·0­<¾¾CJ]`X¡yíí¯UgëñVÊ,Íçb{úìÅÉ¥Á"Jq\ÈÆ„ ^>)¯>²KF|ú6ÕTß#÷­«Çݯ}]c|±ÉžKÏG›'á[ò]ÕöVç8G”ÜÌ`§l[#~ HØ”hgGI½A—¬CN‰²'ÏvQåÑôUñêP½*²­»ª óå'0;½’œ‘%V˜(Oâ£S Ø0+‹4ÃJ=A?|S…pÂ"^?&"e>{>Ca®×åi mJÚFeœÃWe ›.’òñÿHÅ ´÷¹Æ_µ£ÿ½ÏÚ5´ŠÍ}É$”0t¦{²Ÿ«K³ö+ò=Y›Ç—6£ú™îq"‹N/„çìÛt¢{Èø¬1Pn«¼ƒj«‚Œ?µ¿4 R b­÷«f ‘·‘…Üb%Î¸Þ ðÇ»œÛ÷ž•}­:Ë»üxºÔ¥´V‡ Z¯øbH3—e·¬ý–gÄîÁtz—»a=Å‚„mXÆ©0c‘]­nÝA“ÎàÁ„%–~ã·–h •Q<@—í¿ƒc¾FV‘ÒÓ†+¤~FdÕµk͉w\«ü¢IµÄœV¿äê‹^–!AŽbÆÃ‚Iß¼e6aïŸì3âœk" Áø¢bÔ5ë¦nWì\´Óš5˜Ë´ŽYg¾QŒ¼4HGã68Ÿi¿ùÄÔh(RuBüé¹šŠ‡ÈûPôSž=ŠþB¦ùNÕT_Ôû'»Ø+"²ùß RÕÀ͇HOG:*£ê𹞾\3뉬e›0“Ò§†O²Œ¬†Žã 'z6â®ÈÔùh6Übx‚A$}¯^£ØÊ g•YèHÂ{Ôá푳 ƒ÷Ìo–d“¢]¡Ow—‡àÙ@61ý÷;»s‰e;zá¿ÛEÏÑá >Z0s?Þ~P²¯V(wâÝ$FÒNäzö\-Ê'´3 ÀóFcêÁTºN Eoúq|šÁ·¢Ø¦ºU4‹>WujßáÌLĽ™¼WÎÌ]«ޞ'›kp€ÛhK›ÉM†ƒ@WžßPÇüÜüØ\Óëƒï½vá Èýg$dr›èégÒ9.#n½{28¦™¦5&‘ݸp¹“D· °“¼ï ñk½4É”SÎΫ;ƒÈ>] ¹0š}¿[®ˆO‘ «%FºpüæÅ*ùÑË’Ãþû†Y†[H—Y%°ŠËzýY×öëwfWW`F2F 4£½u,Ýí@å3bG…K3¾Ð<}'Ï èÇBðÌÕ‰6ÛˆZs×}W̧k ÒÈÎt›˜Ð qä‰ Ÿk)•î-¼šb¤Jºêd ¤éY~!›‘©€€åÞ¹1æ«Ý$ béù«Š2u¹“ÑùûKôiõdJd±N0±ÇÕ.")D7ݪy¢þ÷âÛ|Äj±k$b} ï ¤Ôɼ“K g êŠ]¤Ž)†¶óöbÇtr[–EºKt¾ÓJˆÜÑ1×íœ.ÕÕnNÝÚG"BHtx5ž7½…v‰r²×þõ~÷?nÐ –M–è­+ôA•:¤ïb°FÄ¥ýií™.»iJ]›ÉT«iwH0ëã ùì¡ Y6Z6öå-œ³HRÕ¬¨Ç³ùfÚ®Â'Çz¥Ôp$–è“ñAˆ+ĘRR3¿ke‹1[Æ#iºÌ–‡C.CÕ™®–Ÿnu´éa´ô½XÄ/åŠä͆=’ïÐιôB2ØWQ¢Î $LË÷ÿÜ|•"^p{‡A ÅbÅò§N”F|wå¶U}zù–Ž,Wc¯¾;£‹Íìý¡ÜÓÛ5Ý nÛÆdÚòlŠšÏ.Ó=«Üúeb˼å—jMg{]~É2+YS®µn»§ à:]MÒÆ»¹öïLC¼›;Þô@•)rˆëËáw½¶fѲ§z¤ºmœ¢á}†TÊM™ÅyᲂAª æL–ÿ#³ñn.Jò#ùg­ùuÖ²Ö´Ï x4±¢Ix)5ŸL¹+¡^ xVfñ3,n?»ex£nko ÎŒ©ŸiçÂÕð¢Où—I{Ñç{"]†¸Ÿ©eØ"¥¸D ž(íÒä¥6<¶Ù¥Ö«“¸>cô—vè{å'’9foz(ÕÎYêþZ×oŒ]yžu¯C²±<ý­Ý½t£ÁŸÉfU••B¾VyP‘~{1i±Ë¸ßøáΗ÷¢aEÀç¾|Ì5¥û¶ãpwž±Íg›Î1ŒK|†É 'E51à¯ïžƒÐ‹X¹±øÕl†µEÓe5FNc¼‹‰µÌ“Þ£¯AøžGH— ­4[:Cšút5 Ú£Ãb%ˆ^4 ¼¢ˆ\žÏ×ë7S’žvÎôåa{¾ñ fmÉcD%{k¨68ÊóÉêî©ù·³$?ïÚ|–VŠÙ†&r©Dªü `UíÝ÷{°äæ¦×œˆŒ·Ò??Em@Œ)Öã{~‘«f'2Qì ËØ|ÄØt¹ò0úå ô'%¦íš-`ó•â… )œùÒÿˆÙ€sä°Ò“ÌÑîdÒ„²S3£§aĆ -ýÈøÝ鉼Iíò³hMfv¯e¶1;‚d(:j‘@Z‹g…å<Šþ@އ>ªhLÉ—›èýõ)­få el ©MëmÅß2®u;ÉÍrGߘíZjd~QX4Oè=‡ïÒŸ¦ÈÄ·;. f·è¶Xwâà4 ðíıJ’‚¤]èÅ4¯M)>¡Ð¨d °ŠëÞ4µt`ŠSÙͬúJ/Mײ ñ5£5UŸ~†Ç ÃQ˜#`ña ßq`±­L£—NÏOø¤ 3ƒ³$¢Ú–È~(†?a¼à—ÏS»öÜøÞ ÍPëL*f¼¢–÷&¸Lnž\?±–éì×Uߌз³úø¢Ácÿc|¼‡Œ6Õ÷ào ör¤ÅI%ìØ>sÐ|LÃwÃÜÞ;ª23¶úãz™µCÒ •Ö­ˆz÷֨ߤãkŠáq&YÍl =†¡V‹‹V,›Ht…GÏöÐÚöqY&ãÿ4Ý¿„™ÇÊûµŠŽŒb›• f)rþpÁ9Š"JòâpM Œå,&fc¨!ÔêÇièJ¾Y¦3Ü1HàÑ'€ò‰E Æ M|©³ÚNþp|Õá²A„¾#.ð&™“¡R]ýB± Fˆ}ùò‘gŸ0Û÷›Ö"oCÞQäØóB;ª—„›©—/TÖÜ—ÎD‚î÷0…êû² 6Öº­1$­@´¾Ï¿jP$xcÚnû¹å6ãlº 5‚DL!z1¢>c–™ÔTÊ÷³×û™µ‰ÓÇ|#V9[Õ #pBÎÐÆ²Uw‚†Ò¡v%wD(Cun•4F¡}ëR:qV HÇÁùýUtª&Ò³"÷Œµå†Unû‰Êà4¡JZªÈRA[ʔ͂K³g^Ï ¨îŸaøo²"ƒÐòtè8Yádxvî© VhÜpe(øŠL/L¦KÄ(¯9ö_&Ú¿B%–éËQë,Q(²¯SôN<¤†Ñp­ªï1TyzÞœÞ}éÜ%kÔ‰vŸp &Ý‘GýJ°ð“ycŒ«eGIz C8ó„”ÚAõÄm¥VÁîþ'·ƒña+^–YàÉ|âÕšógôTiÒ²1‡zÏ·ª.·N.È#Ò° ˆ×vŒ[µš‹ãÝQ¬¥äѪp\JRÄ ÿGsŒäЬ¤¤ðE mù¹eòÁ_Ùò¤pÎÑR´Í¿Á]ç%¶¢K~Mæ'¡&&k³·g¯£Ï꛲I‹“m‹#ß¡#ÔùnŽóàbÑøÿÄ#>… endstream endobj 1054 0 obj << /Length1 1166 /Length2 7508 /Length3 0 /Length 8278 /Filter /FlateDecode >> stream xÚuweX[Ûº5VŠ—âN€â\ ww- X ÁÝÝ E[ ´¸[‹K¡¸{i±âî^ä²÷¹ûìïìs¿'?Öœc¼ë•1ÇZë #¦§f ‘‡9¹ròpEêPGK7„ÈI•Sbãx@XŒŒºPWÈÑ„ r…œdA®¼®­@ ð<@Q °¨ÏãÈ÷W . ЄCaÞMˆ+îuz¤daVnŽ'W7gg(¬ AÀÜàV„(Àú±³ÿ® 9{Á¡6¶®=mVvvŽ¿€¥×_ @‚€Ú8˜î˜ó•S(@œ ðǦÁÄjZƒäÀP×?ưغº:‹rs;[ƒ ÂšË âÊÍúبœXæøGÖšÉBá«Ç¡¼¸ÿ©›½ÌÃÉç¿`k¨øÏ‘ÀnÎÜzNP7ˆ’ìÿ?BXc6W€(ä@\O+[î?Jêz9Cþ$yþ€AN`?g˜3À䀀øA­!,Èp…»Aü|þ_â?wX<<0ÔÊ` ±y<†¿³?ÂëíÕ@®p¨'ÀÈò€üþ½2{ºæñÂóZê?øÿÓXÿ¬!ïæàð§*,ÿ’𨠠øCü¿ÂAŽP¯ÿã†@þåþÿO%WÔJÊÉÆáß2AòPOXêjeû/»ü¥2øÏç¢ C@ÿx’œ<<ÿàtm¡VöNâñ,þ¤ Nà””s²‚¡N6×GW‚ààÐVnpø£<Ðã½í­¡ B ž+¬¹˜ÕËP»šÐ–«*)JÎõ¾.A½‹7Z~¬8äU.”Nu2ûbJþÜsá”,YÍA[‰ T5TäðDJ¹8!{éV®§„a(ŠQ{\µbê¢8G,cÇÀ.Š7±diÙÛ2^=Їt¥FŒ2Ã:á0âê+ãÍ- tJšÒOå˜[3¬"$7ÁŠþZ¢èSým²@»àˆ4låö/ã×ÌÊÆØ_ö. Ë[ ,¦g¾Iã L…+`¹ÖYR ‰¶ ·óÞØ¶ªH¶!wpäGç0ožraß/÷³Má “%¿¡^ÀÁ## Pu|9g…A™9ýñ[ë8K?ŽðwN)'‹]ËJúèEïâ9 dnªO–W~^5 ñζ~‡YŸÚ˜Å†öµ4|»ÎÔŸq$]˜0Üp—élSùµ:„TmJƒ¤E«Lv‡}ÙñUÒ1ÿú)CP!¡‰ßND*Oì°Î‚ÐV‘˜•„A»ózsTçðõÉk¦'š¥ß|f)VoËE`ªy-‹,¹Š ³êN3ueªÐ¨Òœ´j14^–CÜx6u®[…™ƒj.Â:±œ.L¨^¸u1ì›ÂKÄLú¯µ‹B™ÀìôÓÃT‹Òâ4-À0íg™4Ìਸ<ÔŸ9Š ÛÓ+1W¿£t#?èN/Øsb#Qq>2«#åU&“ñoÞWHt:”¼eLˆü†H)¾ÏÓûª:“XåÜ ŠÏBùÌ»È2]\}HUŸ¹:én©Í­öÒQ"™cç›N“d!›ÍFÍ×§Ô¶%‚¯˜.ÈTÍëžM /Œ¦†e½i$µ´Ç‹žÝ%èã®ÀËêeü:¿2BŠÂ.'ª®hìη£ «ySj #j%Jâl“wXÊ­CÚHTÚF¨rF›£‰~÷„t†ˆ§>c°á•0ÎSã$®&2 @qmcõ"ª—w‡·ÈA’Ö¡Cc½øf ׇˆÏi›¡[÷êóU-^hA“vŠpQܵFº‡æ}v›Ñ¢òåb¯+½@~UR, ê,eyzzQ„3¾ÆZvÉVñ"¡Áùp|e• ¡Ã@_4êå‹VñÎDÀ‡¶£–¡1“Â6£P£jì×uCD æñ?F u½wËç4$í©S޵ГBb7‘§*¹_²Ä›¡ó1õ¨ýÚ;ãz~c«Æd>,‚T±4’U”<©å2¸¥)ú^G&zÆèyë ‹¬èî÷ R<¶WZcÓ¡å§£§4;HY¤Ö'n&MhÎww f†‚XªùZ®èW/ÑŒDçºÊ%퉟éHÌ Í¨}j³~BF(6Úuæ_®(Ú /d]7%É”ðÌ΋•ÓiY„®l'Me&q"1÷”Âw\|Ñ?ŒUý,ág¤Š~[:Þ\ñ”—g¿ ß{mžáK u'õ(aʼnpÖ˜²À‰_Ü´S_¥á‰Í³_ß³(©ë0Û|úÝË î0å*ÖTüÁ(†³Â Ô"X@¼üÉ3÷F|ú¤Äª=¬}ÍRÌw§”0fjx£æ<¾¸©ãû*ž±ü«ÔWLîÐ,¿ £9œý×U·O•™ÆÍ¿%Lÿ•ŽGÕ¡Q\]¡¡Ž¯€ó‚ªœI&†AѬö`ħ&”dµ·Ü8!!áÿ{Ñi®à·7â¢ûÑRÈ}áæäïoçG­†˜l‘,¾ÜpôŠ•b¬TRîìä–¨NÆëò“ðµQ’μú™Veãg)˜+˜ý~7ÌοKk~Xïø¿ÒÐWi"²û û²·òõªX’s{xTZ&ÍM/ôõy±ƒÁÃÁUà÷øÑ~käƒ)¬ò•ò~js f—ñÕL/V6‡4»+c—ÌÖΈºÜ®ª¼¿¶ÈžSÏçl"FaÓ}ðÓ—í_ÚÙúŽ úCñÒk‘V¡ák’|™A؆‘ý¿¬™“Àh9³¥üŠ3‹Ù–M°ìIr¸ÐøÂÑ%£y‡7þ2C4~_koáE.tYv3Pøk]úS»¤$½P2¢Cêlð þç+´ Ã—z„Ö™K¾“¤RÛèR¯€›ziƒïAóè<=¨¥>’ µ5Aˉ ɹ4î°ŽEÅŽw¼0ðán…BcÛ$sñÔ5Œï²LV`’¶…#z!kðA{MÝþÇ{;‡étþ"æ¹°Z½#h=/ØJfƒ|:áç$Oÿ™Q¾A¹ÔÑ|á¡‚]ÍÂyÄ ¡3‹C !}þ•*Zd¯DgŽ¥Ú®Ûd+)g Ŏ(&J¦É–¼–q¿ro/úñÝqÃÃ~‡MòÅï; øp燱¬®òLÕw‚ÑêÏ' pL“j)µ‹º Ö,ÊÜQ/~ÒqAþò’¤Á>Q@Ž[ùM!—_µ©R€HÐ*¤Ü?º·/Z”é}§¯ú–8<üp^\{ñDß9uv-bëÙ`¥è:"†ü´6¨D‡9‡ëFÔ$v.%Ýd](º^l¢84~ÀˆªÓØ(ådðs᪺Awº1º[ôõt]&~+-SrS‡kKä’úÝŒW™%)ct)³‰tä×{$ÔIWׄ”1ëUX=_Óø,p´æR:Öìã=PýŽjzª6íÏÔ´P^#¡d²9`Í*O»âèÖùàÂýe¨šm¾Nƒ‘0ùYx®¶U¡úß"Áç¸~È0¶Íµ÷öÈ7¡Z¢oÛb_£³EžZÉN9fkK­EjÛfÏRfHÆjWš—ÐÞ&b 6¤¿¢õŸ=¼7{~"“Í·ÅHXÍrÿjÝ›=ÞòN^ÖwF0—k†ÎíãèJ È›3^—•ë­¢i Jhsü»öuO›¡dÀ¯î~ManYêã6£›yÐ\xw?Çbk2ãçoJ¾·éœïŽ\éÙ^g6 xÄùr™ÉÍÓoÑ´=[pT E3ci–<ó‹Âõ½¹úð&”nþŽ¡_32IS‹ŽïäsY(¸Îé7n ºÙí³× ^ª4bY ˜…"ÇÄ…»sý5»˜)x0Ï9U f„âÏ‚î ôêñ2þtO0[Ÿ’`_ƒ?…0©‚Ù>/>'‹sV,'“­ÕT"¬™¥¤ç`ð— E¥/é&Mž>ž>W/CGu³•ÆB¬äó©Ë¦—ÈÝæ•e¯|ô>€ è®$Ûù&žLÂÓ¯¨¦F­íDŹø*«J‘Dû—v:ê ýâ((¥Bù<˜øº÷úÖÅò¦ùeN[zAz’¢¦ëÅŽþ­Ã„÷¢Z™QDv¿áiïOw†§)‡XBž€æôzZл q7¥ ÐåùŒ±Ÿóël6Lon(ì>XuØ\ä·7-TŽ€‰uo=ý"‚-Ë\*ÄtPR[îÑ*Ä*Q×ï¶Æ´˜6Ý#݈\™b'îÞ„…eœk G£XÂX\ÉTõ’ßÒw‡”Ùu®õ˜,×r?ßYÊßô•ÿì ÅTÈïN`9ñHõ²¢ä í`3xqhxŸæÁeÑ첸™&ÐPŸû’7PÕ¾îxI”±î#µ¤XÊÑ;§ÔðBP¢Šö›lËÜ­Ñ£À”Ñ2m¯õ ›ÃÖ2’L¾ä.ÝójVa_'EuuYÌ jfÝ·›áíG(ãr7þ­ºNdÁù4ÁƒJò•ÆÞ¾á·ÃHÇ8Kh.F¼§S3̸ݭÆ:ò•Ñ¥Š“ŸøŠ~i5y;“‘q«Ëðß?™H(öø„ „NW|É‘~¤¸©Š4öÚ«±¨æ6üDQ‘áÑÇÈýôAß³«—NÙd­ñŠc±$£»ª\K›G!ÎëuM-h¬GxfùRf&¹Ìá˨hÿ`HT‹PŸí+Ÿh7…æ ƒðGc­Íp2\œ¯è¦4àæ¾zºÍß.[§-ùÍ —ÕoÇ´5¡I‰ÞC@®b(œlq.Tƒãáp2ÓU4‹ôL볓@ ±Œ‡Þ&ƒiصˆ [YS]|4ÜZ±lçUÕ1a)MQKÝE ]¨ „‹]ùŽE}Ô„ûCQù®É ŽØhç3 ”!ïi |%ðÃù³eŒRu3¥+Y®‰ö“¤uIT÷­À+fÕ"ªÌKÁjÎæ•î¹R~ÁY ‘Î’+¥¾ˆW¿ý f‘Vû™õ¶úoáÂÆïìÎöfåwŠ“ã¢Ì°DqFhÖ¸@8±–ozÃ)Ï|E\@î³´Þ’ÜšHÍ-:#¼\ŠaÆ¢jöƒûÃÊ$é{ 2}žØ±üðxÕKC¬~õ‡Š||«×Ÿ3¤a„7h¯ò=|H„’$2“á½Ôøþsl0î› ÙT®èØ›“—fôsÎ#2£=î’Îvœ±~ä8˜½Y©÷ƒE£jkò^®Ò·o'ÔráK_a!1'-û*•z{lhÄ­ÊFs¦vE»1„‹…s¿±¢÷Ó«óH«^,•h6N‚ZÐŽöŒ¼SOÞP {E×:+¹M÷ÅböÄ ýø¹(H…›ÕŸ}µ’"ðKñÊ@¡u^mÜ.wØUÿ…²V¢å'še[G'0ÆÚ†w4FzY€Dcµ°Ò Í ÿºçü|ÔKÑ^ƒ&-„gû‚WcÔS3ˆ™( “ý;€„Vµæ-<ã+³Äq;`§ß—>|Ó)ÑYU¼ÞLB H§»:S‹:ÎÊj|:Ÿø‰Â]@ Ê0º~GñÑriÊ*5h<1ÇqíYñµ"+3k„žQ]'»Ê˜ÿGWДÉTŸ;=Ãuø:šž@Ÿ6˜:Ør☦+¿i 'I$¹Bàé©Éõ&;¾×Ï_’~®"{sµô;ù}!Ó ž2”^UÏT¹¦> Æ;~½Níen¬<µY“¶ºŽ¼)=5"žŠј̘NÍE75—4\ê%ü>¢Ãî²äžÅŽŸ&OŸÏp$ïf/ßÌ—v)o¿A/¨eØÛ Ê lïPL”4l·à„:š£ýÚ÷q0T©„´ªÞÅä fRåKGŽLJ~Ïñ.-økfzoCt’îÞ&!˜¯ ‘£s9öE'Ì'âíó§ÛuöÓS]®êý8F(ðñ+f,—#"Gâ»FR9pà¢ÅÚMïéú¶•|,Îâ…R¬ŸÀÒ«Ïʳ* wqK·¥Û‡O|ø!Z© Ž“¯ÙYáüâ—×·„^wM>OoLâœJ• “wzí\m³m«C_5†K†4Ï÷ŧPÔ…EjÊI‘#Eäáów»Éƒo²¦ô½ <²ÈNy´Ýßicp°ÿâ˜Á¾Çç†%MçGᜠ[]ÏY&‘ð¶Œî U?î}³OÛâ0k>ßhá£>ÄÄÒÈ_6}ìAáØµÕ¹¯ÿs/µò:Ô7ùc†êëBüÏNýVŒäK“dtê³MGЏ:Óˆ´÷“ËŸg'Î- }lzµm‰†òxÏ®uoÎêšæ>ðÊì̸z ˜Ùx©“òÌÀß°@=–à«A3G*mäwr¸ó™ÿå í(4kIsæÉxô[¤-ýí/}cJ%ôÍjùʽ˜Qƒ/.¬s“z.DtSö†¢OÜqGAÿ[”9º÷Õ×;Å9-¶0¸®;½û€yœ÷ÄX€y1Rú¿êÁ¼ÚŠaÁ=>d_öÖã½m_kƒžö(¦´BñùŒ×9/ŒÎó5žÊj•¹àOÞACìÏgÝ%«Ê§—ßÜ1ŒxX+$ßÊú»ÑEm M—Wë4£uÜ£Pà%‰˜ä  îe]-aF^ƒuë›n$ 'T–âŸy6ÿØéÂî X;x6~kÃj^ÜðäU‰GDo½b׿K “Òúò1 ‰O×=èF)>_—HèŒúáÇ’NòRþíA"¶VÖ±w„Ãú9W]‚ѕ…yÚÅê°›o¾ ©Ëä$NŴתÖQ*,‡J,dÆ‹&÷„»½M;)*bw JÈÑE;œ"dà€)ÀWŸ ñ‹±|º$žÒ(a¾zÅ*«Ö`à”Ÿc Á=ùðœ«ó ëʼ×ÙƒÉ "“ÁÃ,á.]á`¥ñ3Î;ÚΚn7î·‡÷¾ü]&Z’6ž|’¶›ÀöØOè"öµxŸá k÷:ÈÊzO°/r“’VÆ‹•Änu¸‚DßüXèÕ×Gã$Ò[W«œu¸ü¬Þºkšþæ Т7l3(óFþ€v—m%Ø[^g~•ÈNº–Vô]påkâ÷|ØÛ>æ„$’ÕU«4£%ˆ,[\Žþ ›.&°VÞgKâ¦)<¼ä¢õ/jµž¾U)¿ý¼CàK¥¹ÕdcÂEv¨‘bþ¨U!_4r.GŸ’ÊÓèžÂ¯÷™lïMÝàÚG¡©µ1±öï5¯DçqL8˜qÈU/TöŸ<)X¼¦£z._:ÒLޝZ./b§ß /1ræÖó=c£ÔëÆÕ´qÔ.Ø7—Ë¢Ä]P)*Õ·ßlÏmž]Š´§êE!f5`%"™µ"“fˆyÓóýDgãá3…H¢‰„W;C¼e¸ðàTïüKKC—¹‹ä7I牰ÿó^:)ïcsÅ_¬ŸiF&“%"áL(œñ!t–О"ü©{ÁòÒÎef4ì·ZXkî&Y·ápËîg²èLm¸¾‹ã)÷m÷6â–=ÑjÈ;Ÿ>µ‡ñ´Äf‘ç:÷©¬® .žd¿# KË5üLt4Ö)<^}Œ¿ôér$ý„’á endstream endobj 1056 0 obj << /Length1 1626 /Length2 16707 /Length3 0 /Length 17553 /Filter /FlateDecode >> stream xÚ¬¹ctem·&œ¤bÛØ±mWl;©Ø¶mÛ¶m[Tl§bÛê<ïÛ§Oóõ÷§ûüØc¬{òšóš÷c­MJ(¯D+`dk`,jkãDËHÇÀ5·6pvT´µ–µå”¦•162|ËY¡II…ŒõÌmm„õŒ¹jÆFacC€‘““š dkçî`njæ PQT£¤¦¦ùOÉ?&÷ÿÐ|{:š›ÚȾ\Œ­lí¬mœ¾Cü_;*œÌŒ&æVÆ!9y Y1…˜¬ @ÌØÆØAß ïl`en674¶q4¦˜Ø:¬þ}ÚÚ™ÿSš#Ýw,G€>ÀÑÎØÐüÛÍØÍÐØî ÀÎØÁÚÜÑñû`î0uзqúî“-ÀÜÆÐÊÙèßrÛ²s°ý¶°þÖ}“·utr4t0·s|g•ý7N'3}§r;š«¶&ß–F¶†Îÿ”ô/Ýw˜o­“¾¹#ÀÉØÍéŸ\Æ#sG;+}÷ïÜßÁìÌÿÃÙÑÜÆô?ÐŒMõŒ¬Œ¿Ã|Çþ§;ÿY'à«^ßÎÎÊý_Þ¶ÿ²ú_Ì­Lè ™¾s:}ç65·¦ÿgV$lLlŒ ÿ–9Ûý‡ÎÅØá_ ¢øgf(¿AèÙÚX¹ŒŒM éem¾S(þïX¦ûï#ù¿âÿ‚ÿ[èý#÷¿rô¿]âÿ×ûü_C‹:[YÉê[À¿w à{ÉèÛ¾÷ @ðÏ¢q¶þÿ¸è[›[¹ÿÿ9ýWk5㣴µ2ú¯: 'ýï–ؘ~ÓÂ@Çðo¡¹£¨¹›±‘¼¹“¡ÀDßê»_ÿ’«Ø;X™Ûóú¯–hþ‹NÙÌÜÐÒæXÿ­2¶1ú¯ð¿©úxzaUUMêÿÃrý—¡ü÷8)»Û}cûŸ¥ÈØý¯Ã?amÝž´ŒlZfÆï»÷ ˆ“Áûÿò_ÿó,£ïä`îÐú®›ñ_ÕÿÏßž´ÿKC[£ÆFÉI߯è{Òþ—ൡ³ƒÃ7ÁÿºüßUÿÇù_3olìfl½ºdkÈd‘–™îT‡‘;2)¬5ÐÇøc$Ø®´Q¹¨À¯Æ¶×7-l‡³Rï½6˜®iŠë³Ý}ñÔîc_’êàwºyoŠñe>®71eÒ&Y';õA½N)\ú™Z”çÕ‚ô6¨&ƒêÁ¢NÉ;8ÞT'³äÕ¥±K*É£¼ajC,Zbr]áéYâñÓ#ùÐØèÈpï Xÿ>uN,)·>†Oò)a’“»žÃ}£á'Ø« »ʘ³¦äª]¼QsG†ŒIõ&•o&ý uµ:ÝîbmÍãµL²j€v” õc‰°‚síñ\½˜=hëÐÐ"Pc\a9Ø«J\ßSt³hèØá#ô ;+}˜$sU]E¸iJø -h™”Kܘ/kòt‘½«ì;ŸAÆA¤q÷}ÿ 0—`ç¨F†Çʵÿoðµbõ È‚h‘¦ÎegÌ?価i9\Òyœk×[¿ FÓ~ä!ƒÿ¼çŽO S©Þ1àÂø]üHTø¾•ËE[3s¼få1e¾¶„š~°•¢~oZE»ùÅ‹óµˆE7ñŒ»P<+M}Að)Š d\É ûÀð&‹Wa §`7AÅiºÎ Ðâ€DNÔ±—jŸálîÇÜDÏÞ5'+MMË»HM;Á_ ëGk rz“a‘3_BNÎ;ZWp÷wæÍìÆ–‹pÂ)µŸ™Ûj’s€ÄËŠ8?´¤ëâþÙæÅæû“ô¾©ÊÌÏ¥Û²7+\ù‚W}vJ=žúçœâOOsqf (͸4«™¯Ymq÷Ö¡º@î8‹ùGQ#alîhºJU ]½_sö*Éà¯ýëtNqÙŽ§&°P6½“|« 6ÇoÛ@ÚŸš1÷ñÍ^YqµÛ&ìb0~;•ôÂEÃü ™'7‘fTÁºŸ&½¿éíR«Æ­3Jîšo6/™h•°ŸÆ;ÈlßX «½pæƒ×ôÀ ]©]9Õò0fÐ:ÜâsVƒõã(õðR.ʘ],pxù©êžÖ°I~¶õ *­ÑŸ8æØ•úö>qºë2?)Aúí@¥ÛÚlfhˆWk1h½6üXJüøÚÀìÕAß.2òާջ›âÑVMeøñ•jæ$9Uz` SÎ×±âwíÖy‚üZf°Š+¿_ßÜYë&6Ô%ÃEljÚBFÓoÖØ t¸„ÏqôûË4°É##gwa8Agˆ¹ê7{ñ…é‹dé(¥Øø¬‘°äü¹²ÌFñî—Y.hÔQU'3Ù)?‰¯•_ŠzÝ…µ†Žö2áþ—WËÝ"…3;K›LÁ>—² Õo^Ýü¦ï'?ñ¦@[eu/Á·u[?®«XÄR·ÈŸ0æý¦ö* ÉÇâ¦øéØwf»{¯ï‡OT4ØáYÒÊÛ[­…ºÞ)Z4® Ï»}Rcâz7åW gþÔB·4ÕWŠªævÔ¥TŽÆ @åeù¸ÊU$Ç7j5“{U¿ áN’Vìò—£nNÖzÿÄÛt'9w`>³ì†"Ûbë›g«áø©èË];pžÝG•¼ÔÇyóÆîÅMEõø¡ò.‚ôv Ÿ=Ú×G|eÒÎê …+y¸“ë3XÈ Kˆ1pÛiq«û™¯Ïhù"ÍÍ_{þnOçÖé«r6Eå©w*þ¬3²C°z°³3'—ƹ>~NnVð‡!,±°9hûÑÊøëéFéÚdRòd6ÿŸÂ÷5Þ]B UŒÛˆ­†8LÈêxkD¸2?:ò§BFm¡€"´ÝÎñÀPçÀ½ç†mtNŒïÌx* .Q›AExuñE¦šVÿ¥V£xx©?„ _õ­¢±/Ôa}vfçùÊü”ârFTc´ú|’ƒrô*”¸dB¼§IÜlÿÝûÛ‚¼ù+“3»¾Vª¼ØNäAGzÚéÎBK¡f*hxGÊR§ý¯ü“RÏ`aüHÉÍ|6’)LY&eô>|üìDͦÊ[ÉÖ†±qµ;éššÃ}Å’>]ëoGrST9êiH>7àþ…Pv¼°¢¿Š"†˜¡q?l ±gyc•ñÆ6Ñ"|ß#[±´¤Ú:_‚ó¶ú“3Ü €TëóòÚo姯óˆrMS ÿ¼JÒÇúÖ5•‘ª@L_\Íqpð|^+9,§ˆ)ûIû‚¤Ê—@[²oW:í8ÒndíV§|þHBôCÉŠiÞ&.Å`$Óf=ùÚÀ?Ú°öeÀöÇ•9dÏàÜ·ÿ)+Ïâ×…ÒΙ`Wœh  eoçÝrn€š‹0LšÑ‘è=³ËóC÷CÏÕÍ ?^𯋞 Ø¥Ü†à]ŠÈãæi}?­ú¤1KàUô¼u¦B†àqpeöØ.9"hÝ‘‰¯ñƒŸF6cª0¼—º—WRÚÕÍB.'¿r‡È¥¬BÃÅ¿Ê8ï¾G•/áa”=áY¾|a„®äf»prÀXu.%²`ÊE&¸ƒÏ}§£xªšÉ,r³ç‚–âÂN‚16Y«îz/ÉÏú–0õgÉß £\Žrw¿_pðº5±x§šåÆ J¾gRq™ð·À™(&õEß"Ìs7ÛV™ïÌí –¿±€rš†ÓP,œê|QŽèvõF0÷Ùƒ?hÒøÊ…}Øx”hÎr¼jnÉ`ßlÉ­…òÕl?lõ•¹¦HÚËüXla¥]”;o‰<Ù(`O#C ÓTßÄ£B-üýZ ÞŒ+¥†F#ÏžŒŽ'ar/ Ó‡ªODõ—XH“]PæW+Ù„Àõa\ZoK„Kv’(¥-¥p2¤–{V¶ yvîàù#ψm¬é¬Á‡6faÈNá^êÒ&™nµFn?cÒÀÃÇÇØ4RGÙëpÓQ¥ÉxîEò2›9Q`Ne!ßùp£ƒ‰ [‡lÃOQ 'cØW,ãÜÖg{[ ³œ<ßH_ÅÛ¦0=gÍt†ößXäöq½XëßÉÝSWNØG¼så`™“DGÍÂMµþ‡oÐ$æ_íô>Ùu.]ÀÉú¶ïÏ Ü©°Ï¯è¨5^cª2|âÅÆ ¢7.8Þf;|iôÀ~t½5BçÛ ³x±ã}¸þ‡û¤n¯ôQîÉ¢˜¾¡rÞB-˜ZŠ$¯°ãÁ=PšUÚÀ·ÝôEj½5p–óà鸥å“|ë/ö-nwp%µ­¥ðn qæç œ‡;–L´Š6Ï?s›‘làÔôOªÚ&F•’ìF 5¯ˆòÓŽg”‘€ö¶ocNjƷ{%!Oeø÷+» Z!Œ‡Ê¨êçtò©¤9¬¶LâHöày ÕR"Rô †¶l…• /—[ý±&U¼Nš oà )A2# aOyž.(бºÎ ÄCc "·sèì‘…‡A«Ø×àÑoö¢ ÝÀ^á]ÅOšuaŽÏ±3‚ ó¥ÃôoÚ+žù9ŸL{¢µJf¯HJïôÙi„ ß„¢þX¢7PP”·/yøÅ¨.¿ÿ5Û'|Rë¤þá‹Õé±hVóÀ»µÿi§¼[ 99,Œ×¨Ül›s~½µ½Š‚.9Gq'Ò'¿ˆ¥ò!Fú·±¹M¡a†çÆÂ^ÝcRÌ}$>tdβäQhš¬»àcvs0Öó°Hr’C»02‘@৆¤Oñó7‹º_d5´h¨vžúñDס%0©*!Ù½U2£dK}ͯþ–“|åpl6, +¹ èײԅý…VÁ Sœ|ïQ/™•×$)µß‚&øšøñIn.25\úiì³,×ußaU#“ ËÉU@yvëJØ¿Š Ðö´ÖŒÄ÷š.£±,=¨¯où“!'/KªÃ¸¯þ7,v舂°äæ ƒ#)»í…MbÉÅO¾–œz¦­«÷~…GaŠš),tðhÃ- ñ¥cû+0"L›í ê|概 ì‘rTTêr\4ïd>Î7uÝ¢äªqœ4ÔCïó#)Š“1q…ÿzÐ °#€_Aº®¡þÜ ¶I½^A_ÕZƒYÍJ¤Ã­Kò©ŸâGÄkÆ%I¦P[¾m·ÑfõW#¢nÊ Fò%Öby›Fq.'Ç7Cb.Le“[/6¨/lÒ¼gå݈üOÊÕHĦK±‚ü‚Ñï(”Œ`¼IˆÒ‚V8Ý|#„“â»fzÛeྃ¬èK› 9d»áéQ“¼/°¥>ó„pè‡ÕLQÜnñP3tGžAH‡`#¡‡› íHä? ·”rñüÛÀM^s5vÏ#Ú¹ãù|/‹SRk´ÖmQѢǯ+yFâÂS(УâpøbœÜøÝÃ~ ]8Ì«[]¡Ÿ/ÝýûŒ92„¾³*XÂŒr?(•®2+ža Ls}^°Lkq¨U¹”¼üã¯-úÚ\–FÀõ$„1afÿR©ƒæÚ'eà3¼À9¸ÐÕåK2IÈ7£Âî$ dž0Þ<ñÏuÚùwÁnÌÜí£èi½: ž.Σj¢i? Ì÷¸ÙF['¿®¥ÈçJ2 ùGŸÑlh°Ù_nYÁôc(Tñò'¢¦dDÁëxÛÁCæØÁÉ Ýõx}–0ÑÕJ‡y¿†)œCƒ1ì”dÌÞî'O̼µ”ò[×eͼoÎʉZi¿=ŸTÿ¶<=ʼ€~¿ù„ðÚ”ÖÕž°ÑÀ^Üxê^?ÂöT¦¼Pº=çç¯ÚqlŽ#†BˆiJôéˆçäXè÷”iíJ*ÁË£‘ˆÝÅm"Å çÒÚøL~žYöÏ>å>-ÆÀ鵋1ô쿟¦åÈPä;ª-G{\q&6fˆ”xFð*…8©NtµCµ нÂWÒ-üXi'ŒÔ#ãîªêv2WJÄëlä\9ªêòÂQÝ?ÕõA܃î_×û 6Û8&U@8$½Î¤ ; Ž:ÚLaÒß.aÍ:-éó…êx Ή)3úêþUI®Ô£èÞÝeoûøì‘]`D¦p<‘8¥<™©!e¥BK Ó7y¦ÿmîC>sy‘”•8Ç b˜jÈ—~Ua{£‹!m •¢pÈð†ÿ˜ï6Îâ’Ô¤ÕìyÖÚ7ʲõw@ÝSNÞœÇV› kIeP‰ÿÆk´Ìó¦í,¢üÎ+hVhkã¼Ú…ÇÉuíiÓ¬Œ¼†êyÏ=ÖôÆå¦+—Út\寧í:>·¥PF¤p¢ÏÈÊËÆåÝ{à.ÏX§ò%’U’ò5'…vDÇx;c04ž<ê•>ë,lÃͨ-ÔøìÌì]ò£ÆR,œy›V~ØtX  ELj¿š5Õ¼¯è_`oº]+ŠœÈ¦’­Ïƒ©ö²Éå(è2†£Þ9ý’k/)¨;üŽý2õs⵨b¸,ËòG©ä’·¢®/y؃ùm’Ìbš+:Œ‚ÁúË?ÒJ¨þ¾yÔ:-sˆýMlO½…`bB0ÚþùÑc§;Á'‚J°ÃzÝ›KvÔüèˆÈo´ãS2dÞ$·\Ò‰N‹# ŠÁ·ÄªÕ䫜æ§×tN o.ÿn‚KïMé® çö”ëI¿$Ú/œ¿_‹Šk< ñ7Þ¸Èæ³.·è¹–K‘wÞä€a…yꑨ±ƒ+ôV¾6ë­?³ãï×tF#ÖØ]WžR«§±¼Í*讣ÊkÖîSÈ2íÙ™þ™GWÞ1U©2Au£vÿÖ³ê/“: '-ñÙ)+FÁ*îdg›3BãΟâ9câ6ضp³²ÉÉì†i«Ë£†¥¿’›üÁ8ºÓ¿Ó–!T¸ÊÁô*˜zûßP”VŽ;Á,ÇíJ÷ZÕÊP`îº "14à 8‹q!W‡¢:Ö‘‘wåõÈ´$¾„|ùD¥Cðú _ŒzÒHä\úТvl€‚`­#ñ:ë_#§Ù«W.´=Ãt›Å^£cèzИ­ph€¬ ‘Ô*Ëz΃Ú4Éü:FXR‡Ç (êɉøÄ\ãâ›$¤}÷Z á¯<¬_?YÅr6Ïó`Ü/Œï(Hw5[bÆ~•P'ìNr ©]"¶hxþ0þÄ¢QyÜÇÌ”cb4a^®&Q3—ÙÁ•ò¸“PI2|ô7Š'€„9 ¯Ë‹"õYôi1ó­¬ ÈK³wÇéÉU– Ž9ºC<°–wcHJË@€õ _ÒEN\B ãœMyˆ=ÃlÏ)-Ô$©×ÒêÀTK†Ý±hSYB±JÓ*,È<1zI{sÊþè?áêÈ0'zXz-.Ag^w5zÌx\Y êÁcRzŒ›j®^³¦‘3DP-„Hñ¡òÌu¤ìT%(Û°I±ù û;ÓÕ'Úéc±jŠCú}($[$OÛ¤tó«3ÔˆMö€‰5ú›a'4úí$?¹Ö“©Òp@S`fñId=Wx[:ñM@¨'”çð¶½Ê‚-ôã,[‰h÷éï“Èžç[õB›qi5ñnKlo÷ÑäÈæ <ûXÎi’@3Šl?Òý¸uf†Ã¶!³ÔŰÚ Ô‡:Û¼Ðo9@,°ïìÄ ÊŸr­‰Ã\C„3B;^Jî× \ù8™9b·(qÁB¹¥X¸l›k%1 ÀYþñ¤´¿Ìȧ1âaZÙ°Ö@_ßïNj†_S¿`fÑôÅÊ1“¨…"Ùw Êz€!{Ë©Zϯ¸½œðÙX “XÚÇ‹hÿÌuƒÿ…æ¶:ˆeÊUÂ&Sc¤@Î1gþÉ è#›tDBR4©Nf LºB¬D»&ó°è =×ÏÚFÜ"FýîLð6@ç_9´è󀬈r„°&Ö“µÿbs@AjîQô· äAA4û£!%ÿѹùƒGxõà)¼5ÔƒžÁÒ}°éç[1Vs°Ž u%*© ȹÁ) !ôfv¨)XË{q¥ê{Ê–ŒÕº€ 7H8–?j X˜=¨¬á¹Û®­adcªó‚‘-`<àôWÀŸ Wh¸]­ èƒ&ûqí¬xà°FÖ,“9í­NÌx|¶ñbòzXÏ£úg&ïoøÝ5Ÿ&Ùm†5úu÷.³±M˜VkŒÛ@:ÓHDeÄa mûS·KÙÀxŸêQ4kŸž’Èϰ£òîÙÔôŒ3IiX_N²X²7”Qᨚè±,–¾ª8ËzÈ ùꃃêî |F÷šu¶4n£ÖËߣx „,‰ƒ"TÍ~Øá´‚Ç´U¯‹â^Üï²tqn!7P]îÇÝ«¶ˆ¿Mi½BüŽëàç¢Æ„2dzžoÊ’­¬a QŸ~=Øï}f-'Š$w§gq1®»¾k=ê¡„|Ñ™§Ý5=¼¿whA´f†kÆ-à(ºï¾bcžü`,ÁnaVý+ ¼ŸÎ¢âæEI6<ûvÄödí1ëí< {Võvžë{FÔŸ¯­¯ã”ƒã N~ûödʿӊ“]TV`³T!“…­÷Œm4Ìä©á Í/î«wàìß# N%½EI˜ä=MÅBHåÀlm]Á.ׇÀÍZ¢Ÿ/‹7š¹8µÑÿ4‘@Èè믒޼=‚Û¾ZóT°ÎL€EnRƒrúI~ûŠixa½%Ÿ5Ê2*-–Q´j†×‰E™Ø¬tï¤Á(kô³ÛÁ}ArB†Ó(óN¬–çÙó@ âØ4¶U—–rï»ÅJ*Š^ÙQI5dƒ¾ñô̒®Výä/8ˆTèØíÏ2IË»O’’Ó¬ç’+™Ú¨”Û$‘<Ѽ‰/†Ñ³¹ÔpÕ¼´ÏÅÜ¢Ña¬f&Âðì(rè Öí1KNs~Ö%axr ͗ıœ§~èõguZ0KuÅß]Üë2)~†a4Íɘ6utOAϼŠkO6=å©åPã)w"®ˆÉ»9,ÜFÆ(ž¿)®iòн3‘Xk.ïÛ,t§Âü^=iâîa.bþî>tlÏZ©oâښȋ|ÁÔœ„ûQ݈¢”°65…ùô6W®¹¢'ðÜÙëc¸™Y">¦7úX‚¾ý±GQZÞÏןÕ”ÁjœÚDÀ†!FÈÆo$’Ž«SÌFÊ’Ë¢áiPÖ!q¹¢ç ¯0É;¦ì>)™ ¢Ý}Q¾Q Ìý…­âHÔ7A|¼±nxMðñ+ÖÇd_b“e6oÂÅ{¸åzÇè4Tp†ª/ôFˆÝ.û¢“ êmÒÚQH=UÃ{¬õ…?¡Zµ7™¸ú+)Òseè¥@ŠÔÐOØÄŠúkõf ýð(“8o$FòA;ï ²÷ìÑDéWØ¢»ª˜ÁúaÂ2”c@÷„Ñ–ÛаK$xu5óúÑç{‚ÍL F×›‘ˆ—cËf±õ¦ö<Òõ%•v‡½¸p¥Ù…TCÕ©°ß«"Õ¥³Å/¬´æ§ËËy1Óa¦8úß¹ ü7ò¸›ºá 6tSÁê@æü¦ “”,Gµ¹Došõ+=ÕTÁD:ðšßTDc5ñŸ–¸U@ãqºÌbÖšÁnðó¯ƒølbû®Š¢Z4¢w2‘6S¨n‘z’bñ2wš¨4Þ,·}fê[CIm_,Föé$A¥=Š¿XH@CLÕ¹ÒÂþ>‘Ic¹£<¦#`uãÈcÐiÕ|`W—7K¬]áâ©5Ð ý1Rµ/ÃÏ£RøúFZÖÊHg»pôx†3u ¿”³Â¼` éT0Ûo§í÷áh±ÓöÜ_¯ZqN †„ôêü²Å¹C‡÷›#îO¼‡‚ŸpÞ80ά†ò…³öîg/å| „J(Í7›ÅWi²\Œ3oB/”[š–d¿éJcû¹eŒ:ë{’ª&f¹AÔQZ­0b{ª„‘ñáù(P°4è]p@h„*…Vš}£Ï¶¡àh€…"¸} ¹A”ÇÃZÞ< Y”<Òø²ž-õûüÚ {ú³ žC9Ò@û;*3#Š^›/šíçÁ(ïÒ‘=8Ãôúz |á0·£¬$õS+è“΀Q‡Åô´Cvä—þ6Fïêã3_‘@>Ú.96ãx¡ý=M_¨ô1d"µF’ã´‹Øð©…&5§à]lÙ‡»Q¨,ÔÊ{½d— n-Íž@êÄC@´±Šºó6dC¸ŒJ³žw ®×]dHFøÑmUÙé샞³³„ Ÿ[/þ»øèÓÍ‘þOOóõÙ°'6Ïë_ÁO„B'qRÃÞ”"š›V6™Üã…"™ôÂfmò~óÑ‘,abu£%ªG2ÆÉ.´SŽblPøe×aFpTX–W(ò”Z¸ø&,mî@$ï& ö^VÛŽD‹_ˆÝ³;Îÿb„9»éÍ«ƒ‰Ž¯§›LÁøŒr†ÙY û›Mí#E¾¤ƒªÇì…~‹á|p9 ’Ó‹È6¹º ìs380K¹3j§Üì£á·oª:hÝ`B8›|¸”QËê+0)H>b!è¯R<­N1ìwOû9«T‰ NÀùSÊ|…Ñ·RzüwÓ šË! ·+ù¼v?[·æ&ìZÅ’/®Ð³ˆliGOÙ`Ÿ‰ï‰.±aÆCŸf=¯&.E¾÷FÌ+?⧺0βí³xºQiPìÈÝt‘”¯R‹ÂeA×MÀÁ ¦*)Æ!<†FÖW¯¨$ôÏÜà1šä9|ìy=ØÏ”±`YRäÕÍøcÚÏzåê¼ÑR-@Y»Ì“ÎfªP¦ ?Wj%%!V¢—XÜ|wuKañžïò'õ–‹±ˆÁ`Gå‘!× Q<6¡óÍêxd[c![á܆°¶rL):ÉlûgöûKžÊ1¯“¨8Z‘ácøq×ä´ûÿ…`YóFŸ®ì`²õ0ñ¢WR>+®ÂçN.ેM¿Ú„b¡¡úØ Æ”zÛ™{:öV_¸¥¹TÈ;‹Eš…hØ­IÔ“!çvq–¡Û’y©¨áýI‚Ú=Õ’BÒ19ÏÆOKW‰ó Öí+{1 +Ý,·zÄ¢»î'ÄÑÅ)ù;k´JTyÎê9HŒÔ,»‡7¿¶dÛn3[^E´—=än“¾pý« ýNúA¹´(–ŸîH4|`ÀˆŽí€Ymöî¦dwJcng'¿à§sE.]C™ýCØÌýÏwsËcK;B嘂Sù:/í|jó_ùwó—Ô Ò=ÈïékIodâm¢eDƒ¹õðËPÚ;´€ô/­+»#ëܯÍgõ)33ÐÁ¬ð\­Æè½”¸æÜ9{ 2€„ÿ´HcU¬™qç%üºP3|çu Éâ‡@•:éï0O à‹ý¯?ç t™Ãn“M:w —Ð]ºBÕÚ9"§.±_ªk³rL~rb…#GÌÐzPæBXµÞª5ryˆá3 =Ó÷©cÅ7øšGƒ†(2¥ÎÊR†sþK‘ëIŽ_«ÑÁ¸)”ín¯ˆST}‚¿Ü8Óñë©PåÒÔ%ÇÝÕ iηw+óžüLçvPר1e `£r)XFªìä¹ßî.Uʳ¶ ›æhXàBSŸÒâØòôˆân"Ãâ⟚™Œ\Âon¯è(ÛçÁñÝ¡9f÷‹‹f#üp ,RŽ&]±òÏÁh?ŽW%!Ò¹•\¥ˆÚ¨Ó¢¡ÂWÝJŽ 1,8,G0ï>Þ<:œ>´Ã£Ÿ”9/Ÿ£Dyö)ä@PN°+$uέq°'Yf":!\;ƒgȦ8«<²›éºŒæËµ±è9nÿþ‹Cø|gt§ÌñwS+§)DPX\¸–p!ùPédMµÂá`ù¥x³è\¢cr±O6 Ô´RöWJø}\%Ì>ÃÐd™’ Å½mp°«&:†S_ÕïÍ‹_§=k®±ž'@y£Fÿó«Æºƒ\¢§•OÅÑ,05IXJ€v žƒ Œt‰˜:MÈññ§—,δ–™y\GLðß+L\¯É^,³Þ;Ú‡TŸ%»Ø#*N^öFi[Ú1Jž¬ÁªXéÏ}…çr¤Ý˜`ãœÖ"1áh×—OÕ6-?mÈi0Ÿ?sþbk#>mÎN‘5¤»ñû$d|¯Z ÑÑ•ö~¤PÕXŒ7Bˆ:[×屓 Õ|ÚÙqÄ:Ü5‹î’œd¡Á¿èÇv45ôH äpÆÖKÖ‡ð.Ý7½ÉR"¢O&Æú"Z«|Ò•±9“¶]xmñDK6qx 0£L–givÝ `çA‚w+Ý“ Õk……í#XO¯ÖÛéc¹V'[²’YTϦ¡ vO‚­öBà•+Ü„NgO{Ý4\wºn|¡Ó—qžCyˆ~Ô3-ض&*Ú>Ü%ÃjÚÐÜùN#o1z¬ú>Ñ~¡¹YK…sÙhÕG1HáÖ:NÎòPÚôŽÄáÅæÈé¼³R›ëÖ5øCYÕ²JX º 0ŽÓ¸YŸ¾åP¦a„D<µ²A)2\÷2¨Í04ÒºXwíl6×Rn2^¯ÌɘnÍW?hñ›ú/*Ò,£ecÛ1„ÿ¼èˆ×¡€Ù víµNÄ3s»ŽÂ})9–3ŽKE±™c ¦|áq7Õë- \ÍÁ6:0ÔÄ!÷ĤÃáÁw©¦K²Ï%„Ô÷§¹ÀU¼ÿajÓ¶Ý©yü9ŽÒJž%}N\PïU®ÄÔÂd.üfî*bçísƒ»ÀD?‡<âφ WWnÂ^¢TaØ]X†"­¨a=Ã7\?œ·ZLïaêšÑ\¸Bx‡E„F/žXEä‚¥‹QoÄÀX²˜;Û“P 62§QW–Y³²"8gDB—¡]úëHtÀJÿMÅ . Â Iv¨­5fm>±rbª'G‰¾ 2™Ôg6òiYÙ(Hî¼xjC…Þ×P¤}Ù•|>2ç¯ÒNÒXm‚Ý0·N±}f`†öôi"y–ƒ˜¸µ{a …ßæz ŽúŸ?l&¯)Êî ÅÏš¯Ê™—´Û’ìÝtÕIº#•Ó|‚™5Ç+äœ 7ÞÔ'Œ\ žîÞØïŒë¨#‚$­rœÂœQhIŸ@©þª“æ‹¶z‘ã½ç£T_PvSÎV 4„d‚îÅTJ̧.€Þôþ¦[Ș!.æŒ9Êžh´<œŽzcÖ¼òñ šHfø`îd'G…±$äÛ78ñwc¸6sOEB>ÿ4L ¿3×Ñ(øóÁO‘&jÈÔ…Ûî±EÝVµ£f0Ó!D0ˆ’1|]âK5Á¦\qt&Æ ¸ì®Ô‹ €­‡âÐm¦?¼°µdÀ娧ˆuFêj ×6t6ÒÄt ¸äQK}ýÒ¿# Siç…ñôìzë]6°hâ™Æ3ÐV¥êÈŒÑÂ#`ïvBùI1Œ´uB‰…iÐÐß2TÑ,‰ÝÊÊ^ûuàƒ ¾Ê b¢Ñ*²ÇŒg#‚òå–Üž-ù=£1Ý3t3! 'TO¼ÑAÒ5_SœÙeÍáø¬ÌNû¦ÛÄ*DeìjôÝO–Â/ƒkÈZck¸ª(?é£e õÔTŒ/øä×P˜ÎÏI)#d§Áç¢~’$Ê׺ë½#Ï4ûhÕd¬}B!Eç6S£|¿Z§UîDñûy~ø,ƒùÄ"¤(¤Ð@Jîß]ò`‚‡ ²ÿLºíÀK÷¤$£[°7’.ZÓÞÎãƒ1@ÙÆ•¿§ Y%ä쉀z:àÿùÂ×¶Ä ÆCàVf¶=ïdйNœ3[24Ó±ËÊ" y ‘z馑4•`%|ÙÅÚpkúqÛxÜŽâ+Ðvh¦1‘ O’ MEÄÉ  <½¾® æÆÍÑ\}Vïë$Ϭ§'fç±ËáÓ˜tÒ¤žÕF*Úkƒ†5á%.âí£)®õ³ç3é縈;_ÞŸ!›åÜôí´º%ÏûqNH²~ 2X,4„‹ÔNÆg2ÆšLÖ;~¯¬UC¤åíú~ê¼YJHÊÚ§øƒ€´¾œiʾïTz³?ª÷4äý¢Ï Eç K¶Êy=„Ik˜ñ0Öì’!,üMFö«£?ÈŇç9µå!ßëÔ¸m+_L"zd×H £FÓ¤~i¦y¹ÜÞ{¢µŸVwÏ” {7pÉ4Éq<8\L„ þš.¡ÝÉ•w:­ ða/Š>ÔI®=Ç¿²Â’Bœ r§ã=oøxÍePâÙŒêú£€l) ÊRÛŠ·Î˜qÅ›# RíGöÊ.Ãð…¸î*FàÎÛ#g*j” íÚÄp²tOþ¹½ÇWùcË•MMËÒN(3Lѵ¿»ü‚ ñ¨r†Ë½)¸)Yƒ¹£]1»\õ/¼O‘£Ðýe.F¬‘+¼Ì§›n> ÚÐÝÀj¤Ò¼ÒEU —¢¢lL„jD¬³ùÞ[šÚyWdÔmý0ÊŠLJ&Uv&z5nÞÝ&uâb’MQ¬`ˆÃ!?k ¼è/mêÞ§G<üùZ=èµÁ=gDLÌÅyæØ6Úg#"/'è\6œš«5pp妤¶¯&ÇŽN]ጸ—1 ±ÈÖÁ “@ cÒmåzù.Oé5ó×ÄñÊQÏWN0¨ða“î§>|LTԷ꾫ˆ¡½î^Þ ¨F]@¶gAèïHSGP&yõ†6RU—neQyg˜—î÷OŽ£µßo2fW¿nÓÎìöA¬ôÒ#ò³ð(ËŽ|çù £˜:™6V'Aàkà¿«¢ájWÅ1çðþšÆºo]åüÜÖˆÍE¥djuîÉIÞLœ4Yágdª»1Ù5cOÈH(x-wŒ´º]Yí¤ÉâÖ½ >_ý¸ÛM¦AGSwÕ–†¡½KE-dª~<ýìsé’zùL¡CÙ‚-Y÷{f×8èî™’-à« üÄf=tš¹wоeYâ-w«ÁõÝx¢SEã(CÎþK)¿.\WÚ"(8Äïò=ù4‘ç2¯–·ó»v e±¯\ïµØ‹§­Ò§×GB0U;§ëKš*LÈ3FæÜ²paæåf·”V†ŠCXI#öÃ|Å£çàHYÆe£¢Kà) äþkOîpBéh •Æ+Ù¦!ÎYe*~Ôb*ÒµwƒôÚðªM–ƒìL×?:`:¿}¹%cÕ _ôHUéuË*©‘¹6è+­oâJˆ˜Cõ+cž$Oç‹ÓýÝM`%Q¡#}^î×FfQšNfbƒÈ)”^uïœÃ[CšãÔˆtÕ-—ÙÆÓ%¯¢ü®i¿u#DTFYJ!ï)¾Ï»¶þ‰\Ñ•ãzRo¶÷VddÉ_œ-cgÂÄ•.¸¾l†¸z=ä±Qû $«¿º"iøfÏk‚*"ÂêoÖÜ=3xܱœ}u+¶®gE×Ç·&,rgø<íúšñåsù^ˆìàÅÖ+Áóî !FŽûC×zh:³ñîJ‹˜ÅJùs´³ßûçbœK¬q; 5½¶"Ó“/(ÐV‘¶Ð_C_µe2`VÅ.î MSQÌݨÙQ,¼ý—^:1s@ïâé±ïò¡Áè¼ÂòØDP‚†{orhMW†OÕúq¥¬¾2J¬‚w›í:€ƒÔÌ–¯ Jz¯‚é;‘£‘MäC /Â{ˆañ äu\޳?rêf;GŸæKøû{˜PˆJâډϔc#E檇æV'`H$w‚åpÁ&{"^)xÂó×¶«¡¸Ÿ )1®ÀÓ¦_bèD˜4½+ÚbŽo#×1®Å•d5FHþÖ¿è×ÒÿâY,,B¢õ¨Ý ¥ÞˆJØí{8!P/]Úö4/%­è©æÕ·G‡{‰=Îæ…;R¥’î ÁtÖ\´l¿¬ÔÉrëï~ŸM£:úJ+·-LšNÖh¬Mµˆ†»ÜAfßÕ»0gwiõnhâℨ†æ¸°kÏÑžoΦç+ÛØnÄáØ_ƒ6a2Š SÒò£ˆÑ¡ˆ;5Ð#Fºœ :ó/æC:ÿÍgÓŽ/Ð瑚¹¥b)…ÄQ†Éñ@>“\0/öº¨/Y]ô Ñ“¦¼ øÙ>~×(0ÖN#mTúP»‚êì—¬Wjµ{µdÀ_óÕè•O…›[œÔn¾Â(®Q•¾Òñ)&æu/ÞÍ«¤q\(ËédÁÂ1£B~Ïø ÐÖL™ñ>àˆN5.·5T¯X¼Jyà7SЋÚez”kø›K®,OâiÅú)„[QÎÒT¬†8Fhi²îûáZl‰lõR˜êÝÀLbzŸwB•©RÈ?…¸ Qš¯2ÌÕ[SQáÞ[4š¯uÏB1 ´oÆòÄÕ!®þ–°‡ %ç —´~s¿ýÜy& ‹Êj—µxb™:#«± +ãÝü‘QÊZâmWA71,n«±)’Wlÿ´ÞÑÑæB="ùÛüD改ÎWŸðC=•êÆ<‡—rÁ½…Ü’CÓ~V‹fN§{™œ½CÿÕ:‰:Úc\Ù\eïèÕ†7îO( |XlBªq½’¦½#3$•$ a×Úù±éöÀw6¯î˜êaµmÅŽn ¦…æØèwD¹ö Kdgša 1öÑ{A¢‹]—?v‹àDQ…ðÑŠQ¼Ç·®²ª¾û‰ø.ý5 pM6­ £¶=q(#ê¤ ÷>9æËqœI0áŒ[ï"®»ÇÐÄÊb±@~¸=Â<ÏŽ@w§ìTt„iƒ_½;ý|*ò³ƒÜï†[áè}Êð ' äj·²âÁ=“Ò)2°™.ŽMn1b¶jAÎ0)ö¦Pf8ª/¾Ökü<(Ñ™,Ã>¾òLc›áÖLZ¦ö=ˆNÜ ¸o'ižÖÉæs’_j^‡wçLôÈ8áüôWÑñ•pô4… ^{wü·e’ ð¨ÎCf#a õ=ôŒŒ®ËòG“dz2ø8Áo蕬›é0d;¶ªâ­Ò°3X±ß…©*¯dt#5Rc,dº¨e±/áeG|­#ÛžðéÂ(âÕãb¢5¡aôáÎ2ùGáŸ:é‚£þ) *aåIöm{Э¡è;\?9ËzöñœÚpœ¬åõÜ?£U¢þF":§üìñð3å"‡½V]ÏŒÓØÒ„ªÓ]@ÀæÇîî?kTÏ×4f¸³­ ì®ú:èQ¢/°D(—Øi•ð§ÿÔ†úy%kôCñ‹óU uy÷-‚±Éà–›’ø FX‡;Å\¡ Þd49×.î0ûÕFt´!µ¾òX×ËP1…†Ü<*°ëíi:¤ÐQ#,‹w_NìÊ9#¿y™ƒjž$þXYÐHѸ£s G†ìrçX麴Ð4eÜ?4¤úO¤¸AuCXL‘Äò_Øb½6¸×»¡+}zž¢ƒÕëôÛ¦uD@Á u ƒ@ÅÁʳSc(;|ßh×ͬNêÝêäÐ3ÿì´ö¯îwµ.=`\Zfå5)y±¶=÷CüþH¾ŽõpiÃÍPtbõe}´û*ô9ŽÀP´„±Ó` «‰gæq £“ªüê'xëOÑì$µœh½>7tRy¤¸xœØÚ©À„´ äü1ÈÌùÒ)± 4wÐÚF¡côwc¤Ee• 8ªgK$èöbfð„ø²#D„LïSÎ>Zœ™n+Ú~:IGÓ;d!0·À¼…寠¶3ÇŒœŸá´Ç¨0VDSÖr¸- Në="¥9¸‡f·ââ«U«Â#Χ±êŒ«t Y{ ë¦-!ZE­tÈ%ͳ$.R*:æÝîyÛl´5@ó¸`cRsâm´iÜ´:¶R¿/lOÉù†K©*XÙ-UË ê)ü£˜üë"… N8«»> W }°[¾ÔÙ¾Z¥–ÕœsALgºè‡ÜîÀþõ*Üy¢EÀåÁ™ëÖ“Ãý»µJ€ý£+%m3¡TôbšDVñ+3ûŸ_,²RÐt{Ù½‹pÎHj׃8 ü .gÇ5Jóµ›Ål³g§5Òº‹è”Í¿úÇlKWè.0å“çgxÈõR1d¹JœÕø‘×ì¨Ò÷‘Ÿs.¤7vM– Ël†îîHãÂbnù2»õßLl®øß ºØƒñùÇ\á¼ùSPm6r1ŒpZŽáLF»`;5ðüáãêÂúóÃ}š¬Ž»aþ‚ßJ#od‹I'5¿È³Éß^5Üq&²To³Pá|X i@§A€`2ïY7*"¼ˆwDC—kç!\=õýzæQÐÇS¹,aYIvtÃ$×ê&\Yv>„eÛí©_£‡ðÕÇh> ‘”ƒËÝ>­fAJÝ­Û.#HHÂé,09;nšWê-í¥QìÆÇÎryÀvà5„Ø?Üž]T(¡ÏE]D¸óÂìÍüðÂ!F¸ï§]ùQÿ®óÎfB‰JŠqÝš@Ñr-hÞk,᳉jÜÃÓ±€Ö¤?<Óª·z,¡ÄŽ"éfv„ªð®nÒÜu„2û¼:@“ë*ÜkJWx^q5žD“¨•Vk}.èMaÉr=-坿$x»ÞV¦—œW⊠_ÆZø"[ÿö̽Ák^r *Ê?8<ÿ•ÑCÙê4O!sšÍ˜ŠþË<¼,ò|à~-OÑW»®&<™˜(îÕ¯!Š:Þ¶^(ÝÒÀ­+¾õ?þ€U˜€+𣭕6Qå„܃›p¢擸XPêD&®˜wá‘Ú!Œ²©ÿ ß’ãvR’9çä_ûÑÒlYÀÉø‡Å- }ò¼€@v… . IÇÎã!ŠåvToû]mqV›s¤ÀÜ Æ7ú´XkÂÈ²ÍØ =ÎØ²¡y¸1º¢L[º¤Ápñ½}]+s”ˆdiÆê¾\ªÞ;1S È*À‰×68³ò"óFñXÊFÞl þª^[@Pr}µø`’Øçù Ø\^Á~W<è78JK·‰³Ï:HcŸ˜Õ]«ÍÔhPnniñèd}!ž«Øë$È@¦u1;d¼\Xmƒ{R‹Àü-ËŽ «›x,€ñ®=Ê’zâÔ¥´éêŒ`­ÒF¨óqw :jîpA>k骈ý±b­®Tëh/¡=aM8Âw=QŠsWÇK 6¶ìýBl+Î@Œ´Ò›+$*;à?ÜQ.ÚýËÿÏ4crƒ>6¦o†hÛÍ}Vݧ±Ÿí>²<% Ô¬`©,„l °£7E0ˬ" Í”>ý—´$5 ^´OhI÷Ý—ÛaD©7ÄHPœ&)¹ÀNÈSòJžñ®©¢‡†Ú£IS‰0=±I)gÑyB¹êMÄ™»·Ó >6Y×s>Ú÷ZÊVûºAEÝ¢NåI$B"/ÜEuȵøñòÏÝ |å/–r¿"_3Pr{èÄ×ðl°¦¡–µù]ýYÙÅ–„qAˆz”€±Ó^8Õ09ã³ÌÈ’é–K/"!Œ8.6èå­KÎ1ð½Ö½],‡wì%YŽ ,Žz~?ŒºŒ©5px)îTs°M-¸kÐöÁ‰kÓ? M5z8%¯¨¸û FíÂÄ{Ú-`‹Åtñ7I•’npž1ùµÒ™?x?­zMc—ë¦,åêèL(z)y0YÍ`,f±ÂlÌêTƒÌS¿“zqäH‹¨ês dùÿŽ<Šåá©‚ô¼ßyhˆþЉN¦x_u;n¨%ÞbÈ`ëž`†3Œicæ{FÁY'ï§fFÐaªCÓ®ç#´“B£(ßLBÜÛ‚²©×XÌ,Œ`/ÞšHÇwvÐ(Ë*ðòñDàUï]Ä«…g²¯“Ð †÷ârÿ msyVú1§ÕiïpbWR¾ D$½g(b6˜~´¶Ç·Xñ‰YQö?ƒ|üg‡ùпJ¶«‹&#~fFÝÐôƒ¥ìb×\qíóF0ZŠl!Cÿf#ÐsÄÈ"ƒ†mâ^ü.*Ìù;zƒ‚I9è·³ÙdÔ:kÖ“Nˆ1®|“ýq†ÿªk”?„|ÖêîLÓÒ‹ô Þ:¡òeËÎþtbñg9Äè⺌ºé6„>[À:Ac‚ûVDpäÔcÊe4-U¨–±\³AlfF8ä|øݴÊgþÅ›¿Ù7މ‚Ò^êÀŸÙ6WŽÞÇ™{_ Ç@‡ÕubÂ%ñ :=€ÃèÀ€58`'[ )(%@ýMJ%~ÑLLe¤0•÷‰³]—KRa2$"ä“î9ÍãèDû¼p¹î3ëxF(‹ñX™u‚9eªMŽíþ«ñÛèÔ22™ÉNzƒâú}8 ° âF—có»Œû^ûê\X™Sßc~¥ÒöÖ$Üx¯Øy•ªÑ|ÔlÒ“‰Ã43€Æ}Gy>CgŸë_ι³¿$UýØwÈÜS×¢±Š¢++}3x´R#ÑV•¶íglÕ#e|-“t¯`â­Ð!¨èi8 X×øÐ,8}Q$"ßÓ5âÒÝ ï;éÆZ²â „«¹Óà%g¥ÜØ)ŠÉQcSyÖ.R"ê©CõL;Ïät6îòPÔûëË[(ìÖÇQãPúÓ\Ÿ¯4Ε¤à9ȰGÉ[³VA8³—àC›HýùxÕôˆFæ¤t¯×‚® endstream endobj 1058 0 obj << /Length1 1642 /Length2 3906 /Length3 0 /Length 4725 /Filter /FlateDecode >> stream xÚ­Ty<”}×'$C”,¹‰KȾï[ö}É.K1f“1»e[Y Ù#²&){¶,Ù#…R$;‘]–wè½ïûùô¾Ï?Ïsÿq]Ÿëw¾ç|Ï9¿ï¹·™¥¨åÓE!ñ¢’bJ€)ÜÓÅ gò4E)‹šÀ p<0YŸÆÃQHm0¦ØÂ €6 HI’ŠŠŠ >@ …&`ánîx@ÀÚÂVPXXäoË‘ àBø!EâànHàéÆ@¡=aH<‰â?´„Á¼; p…#`€Ö3;S=@@ÏÔЃ!aXRf^.80†C`HLpEaįA!¡ð£Öpb$. phN ƒùB`è#H@ðžpŽô Àq€ŒÄ“îàH zTÉîŠ:.E‘<^¤Æÿ<Ï? æ ƒ€>¾GA”Co¤¤§âŸ±fµ¿Övhi’¤h¿.(·ÊÍ zŠz˜1®Xì¼Wz[¬¢Oéàah½?m(4ÓÙÄ‚à™ûžÍáÏ#Øœsöó¥:yá™`ñë§Sm£‰ËƒÆ_(íå$lf&^›[\Ïß;y¡¯N{jyK0ˆÇ;'ˆ‰wMI.‹c®?SAÆøìÑÂ⥄ù­MþW]ím/W©š§Ù…3ãhø”Á¬÷¸ñgìz9ä€j×[»µ¡êY€íŒø¶À‹Ô[ÌÔô2¯n*J¨ôš#¢®}ŒÒ~±ë¤£ëxm·»âwr–ÉSW´|äÕ¢‹øä£TQj¦5Ç üõ+e‡LʧSO°Çu¾!´èŠÎ•ôƒœ&=æöõ‰¡juÔ0Ó¾îß4yXà‡ùTQuãÊÞRùX“ óᙽ@¢hž-¦³ò\´Š¿L ;¾…¤ñ+ÿØ<‰Ñ£u;+àÏ$n¥P'LU:ÆI8øCÍèÓþMŽä’òÄ%vm´üÐÍOl=irn"–_$™Ë÷²ƒ”O«“QîC¯ òYªkçAŽ™ôl'Ä:ßCfâ…ê·÷ 6÷ »›²O©ÙÛ€a|€?(ÎRâcãu|Pü“ç³k– •!©Á ãW¬¬øñÉ›ÍÝ—èLfž;n‡ë‚?+š›­å‘ýôœÔH endstream endobj 1060 0 obj << /Length1 1630 /Length2 19190 /Length3 0 /Length 20019 /Filter /FlateDecode >> stream xÚ¬¸cpfm´&'ÛxbÛ騶mÛ¶íŽmÛ¶m£cwì¯ß÷ÌÌ™:ßÌŸ™ù±«ö½p-\ë^U{“Ê+Ñ ÛšˆÚÙ:Ó2Ò1pd-l ]œíldí8¥iMÌ\å¬Ð¤¤BŽ&Îv¶ÂÎ&\5c€°‰€‰ ÀÈÉÉ M ²³÷p´03wP¨(ªQRSÓü§ä€¡Ç×üõt²0³ý}q5±¶³·1±uþ ñì¨dbp67˜ZX›„ää5$dÅb²*1[Gk€¼‹¡µ…@ÚÂÈÄÖÉ„`jç°þÀÈÎÖØâŸÒœèþb 8 Nö&FÝLÜLìÿQÑìMm,œœþ¾,œf޶Î{àl°°5²v1þ'¿rS»²w´ûkaóW÷LÞÎÉÙÉÈÑÂÞð7ª¼°èäélnàüOl'‹¿j€é_Kc;#—JúW÷æ¯ÖÙÀÂÖ àlâîüO,C€±…“½µÇߨÁì-þMÃÅÉÂÖì?3 8š˜8[›89ý…ù‹ýOwþ³NÀÿT½½½µÇ¿ÞvÿZý,œL¬Mé ™þÆ4rþÛÌšþŸY‘°5µ02ü‡ÜØÅþ¿ë\MÿmÅ?3Cù7 c;[k€±‰)4½¬óߊÿ3–éþß‘üÿ€âÿ'ÿ?¡÷ÿŽÜÿÊÑÿt‰ÿoïó…u±¶–5°ù;ÿ±c—Œ-àïžHþY4ÖŽÿ? kÿ×µV3ùtÿ7`ÎÛ"`kö—:†ÿZ8‰Z¸›Ë[8™L ¬ÿöì_¹Š­±‰£µ…­É_nÿm+€–‘á¿è”Í-Œ¬lÿ!õ?T&¶Æÿµ‚¿tý›?½’””´¬$õÿbÁþk(ÿwœ•=ìÿæöߪ‘±3þ‡`íÜ^´ŒlZ&Æ¿÷ïoBœL,>ÿ‹ÿ1þçYÆÀÙÑ õ·nÆ«ÿoÏžtþ Œˆ­‘ñ?££äl`küwÚþ‡àµ‘‹£ã_’ÿ]«þïççÞÄÄÝÄz}ÅÎèg°eZfºsFîÈ”°Ö@#èHˆ}i£rQ]¯_Zøg¥þGm]Ó ×W»Çò¹ýçoIª£±>tkòÞT“ë|\bÊþ¤m²Nvê£@zÝR¸ô µh¯›%é]0M6Õ£ý)EÝ’¼™NfG¨›gJb×T’'{x_£_ qh]ˆM@Èu…çdI§ÏOäCã£#ýwàý¿q¨sâ~þ4ÀðM9'LvöÐw|h4úsewªZÎjU«AJRqóÄy_q! yŒÝCaL¿bÆ7û>dà_1Œ“r» …‰e*Jä¥!˜šU–Ô­ïZ‘¸XcÛ¸làåJ³Ê\㌵€9nŠZK#.bÝùBR¥àZÊÔ M0Weà@LWÐPâ™eg©Çæ#á…â¯ó¯HÞç/ŽÑítöÁ‡âéªVN¬Ï¾§á±¥a$e~à Cß¶i"àŠ–È%½÷¾OÑmíÕêîIa „[äÓŸ=h’*Ù‡òhÑï¹*“úÁ+›çË’¢yñ ¿dX;ÜÔD£uª½W‰“Õ!˜šÙÉvü/ðtÂ~@æÊ§’Ÿ:êi¿;\‡,9ü¨GoÆ`}&Y£þ£ð³S3 SË´á%?RÄ$ÎpmßOúcz RèDÕ$¹Òm+¯Ý>ŠŒÔþð‡·«kær|^n5ña7þòg°K_³W 0†Æ|±¶}cºýÖ¬+DÖfj¼y‘¡Õ˜Q žZ*0Šò4o·B³$N¹{®«»²ÕΓt–¤‰4©ZôO)oêÞj1câJõa?ñ†bélájVD›€Ð2½÷z'UÄ'W÷ {TÆÇyf y@ çƒ:¢0½ÀU‘ÚK5 x$³°±"¦^pÎ?ˆqžì†/X[íÕS¢m^õ«ðïk[f'=[w t–ýh?q›f¼ý–Ô?x/Š ¾÷—úóEly«Áq€ÇeurΤC´ïqÚŽ„Ãþ”ç®…j.ɶS Á/fô¥éJjsСWÐÚþä´;3f$ÙR÷Ûù±¸fvv³#1´-üÉ\'Ut>}Ðx²øÜ—­ªiŒ\ÅðÐNXŠ)¯– 2óe ëMdPêëôÈA§^ƒ$T¼óQ*_B¿G†PñXîé¨\—@…é9CYe¹[”åcÇ:]™TͤÂÈÎö³àv«ã“ÿ-îÍMì"³o˜§Ï‰qsëܧA:d<—f {-Šy®Ž•šÕ:)ÍwÝ€0K}Xoîè)4>aQ*b塃vqè±f•â’ÞËè0=b‰ uËV!)¡a]I«&©?×È MP¢G¶#G‡,¿” ¦Ô¾Á•S[ñ²uð~—`8ü–ß0#«*$‹Éà†‚2™}ñÔ¤“qŠmÁyÎCCˆhgCT•LVʲîh#×çãDm¤G¾m5ü›íÏžéF¼…/ðÝc=¼Gæv–èð½ÇrU`÷¨ºÁsøø#”+p!ìÚJuQ¥7O„´%–;á&R/ï±Þ†èË×½LŸibsT&fx¦"8мg¤Î¦ÀJð:ßêôŸ“±Ž•oDåÞ†Öôñ%>º8Cj™½ŸAÇïÞ®iñÚÆË_~AFÁ´ôöÅ#î\ñS317w^d=ê̺àé¨É y?€£>ùïjwjì}¹*Ä€,ï^å3ˆ cQ͉I籩xøŒãÇo3,Rš/9ÜÐf«Åüqttõ†í¨qÛ;÷¨Û°\0áv$ÔYUxn"»ÑùbŽ¡E<R'`AS~"ÐR±øó¾×ÂÂO¡„MË‹õjÙYÎmï°ùu¨¶]ÉzÞ>¨gW`é^(ÒMïoãrÄÿt¿ïŒ‹§Ä–Ç‹ë'Fæ£-Ë t >Ñ$£w¸DŒl|”JWùÔ6uüU”=RJαZЙ,sæmÔ¸é {±T,Úaµ¼ ê@3Ó`‚nº?,“•Ú³ÿIküǤˉa§+įËx¡r$ÅBç ½ñwîIÁ¢ÝîÓ õ|u{(Dq x½F“%Àuq•©Ë½9£°J¡WYæ¹FÊaŒ¢?©XV1Þc%ImØÓD®Ì!q œ[måügb oº¬vkHô3û‡¨D»X^­Ñ’Žÿ}òç ,\_ºW©ËLlê7Þ0PºZRä\7ï×JùœSC™Dá   k6vÙVu9vjì°CüIäæf8:bF¢fr7IçJÆE—Qt+BÂ+SÎWÌàYûZ¤ÜWÎO{õIоŸqùÞ¶ælI$žweLjS®ßC}ëYHârøSØæézSNæ°ÙžfÙP©¦¡æü‹Ö¤œh°³Ÿâtûíå2`ÕH17fÍØÓÌF5LGC2Q{DÁfâ~¨]„ªcƒÃÌŸFäì¤*ÆL8Å«­¡ú¼þ~ïßÙ>Á‡î±3w?¦[0±„<Ó¬7Ö’Y`Fd£ÇjR×mê2–cáŸ_;bA%œ% g‹HNM÷‘´Q6k\¾Õ)Ûäab‚ºóμ{áÕó[ÛñeìsÂò EzJçñÎÞ6 U¾¸ó¥n!ÌrË2Ã!Ç5N"ÇÖÍSÈh‡‰Sac¿²ÊD_ŒMÂÄ_P5‰‰þ 54Aýù–§<4Ý¥j1•3 ÛAÞ°!+qXö/Š!¨bÑ?XìÍ é¤O}*K©’{#§ˆm‹ðF£ä› 0i6!ý’6”‘y飤´o#8²ÈŸ//䪖´¨»j6²œ„ëZs†ýée¼¡ÿ¹ö ¶=z!°ì;©[|vÉ üŠ'ó8"ÏÉO'Áµû]P‚™k_A1;7÷€EdÊM÷EpFmþ¶•\ê@r0IÞ‹øûf㳓ÖG0TéëIçU$Ê~¡,ça¿E'Á­yÏëþ×)â~œ1x鈵ýz@ð#RL…£5켑æz…f/#ŸY#ÚÔZ¤œ‰Ÿ¯¨˜N5Asö»¼¨€¿÷¶ašåÒŽôâê÷I– Ûr¬[ÆûO³pyXG>ƦW=éJŠÚC0®ãHƒ {Œ>—ïMÜШ!ïkd¿=ˆ{„y)ÓUèRïþRã¹Ï¶”a]+—œ7°àÖþ°Ö?Ö°Î9ËRC}:»¡¹¡ò‚¨Çõ¾Xh¨6¢Ë÷ið†t¬ëEÛ·&ÜC£èàG³ç¡yp¤þÖOÞ.råN(BŽ¿ …Ì`U+AÎJP’ÊɳCù½ˆgî(­eƒæeÈèGý½ J ÆQ ÌY •àlEB³-ê›pwB4Y;æãšªòlBWŒ‡Ûû-ÚTÀùŠ¿l6aBê#æEx„ —¡ÛPƒ¹ÆºÐyú¡'£ÄLFRù¶žï¥m¹ ÓDH”Ï÷LFk”?¸ò‘š–£”ô¨¶Xð…MEXîzvx7Á>ŒŸß5‹»h‡…‘è¬Æ=(ºk.zföP•¬L×é–¬Qµcj1S Açc•T•mù7ýL0“æÎÙE–Ø^þY2Br%&gI S¬kË]¸yAî°2CT÷ûOm}}Zzäá¬{Bà÷í¼Åðf_3r˜ vºûAËÙ¥’†‡v]XcCTVzËbº›‚aQp0L¦çb 4ìè+ý¨¯IEÏ’ßV¥±&Ó¾mLX¯Ÿvk¿|¸ó$ߝĸp%¶¾B~Ëã@pXškà -Žåª2nLJQÛË6b$¢5ªì/ïº/-}áq<1o“áìJýÁ^†\óe¨Ä>Úα}é¢úNmÖVËtpÔ,kR²üð~3Ö(Z|º:­°{ ¾ïš™e*Ø'˜Û¹S󡇧õº…µ  4ÊÝ„’¸qhB}¤w]HͶvnÁlR[Eh«°äPšÄWÂVîië’›0ª'Çõhà³Ü~†õ±¡•ùU •.FÈ(Å™HÊb‡ ƒÁ,«3S-±’䆿¶ÁËVåaõ–ÜXIË P¾:lô/é=G\I¬µ…Ä›÷O¸„ãlZ•nZh —_K¿‡Âp¯ƒTò¢{}Ñ¡IIÒ¸¿c&«so_ûÝÒ ¤R©æ¸Àú¤ÌÁóþ¼þˆ¶ÒÑP5Љ‡{‘*† HÚ$ˆhœªCÍÚû2Æím,MÀxxõÌq…~Á×àoÃ0òn× dºË­€L»ÉÕæËÂϦ3qºF€é©ég…׈Iz›Óki!7:kzd ¨£ÇZ7U ¼\z4±§þàØ–äTAI_¶›½„²o½ŸVo<¼{^ò|f67?ì»ÙÇ}&½¾µÑ£TÖ*Å Ð dÁçb7 wG™~›ø~°ÛCp)@"ÜCª¶ 7¿ú¯¢ ¶Ãˆ»âty°SŸ¶*§m46@h¢é׬wœk/ ¦ ÿÆ]€o#òÃÜ AÕbÐã²»Kú~\O«Æat†ÐÔÓel íðQCçœ6¡¹hƒo‰éÒ ü£ôÂg˜$Fh¯ÖÉ—œRËd‘¶D”ëáëÁùžâG»{סù­š+Ñ®†÷E26Oéùxò)¹¶|ëµÞ™‡SЭN,R¸ö¡©°Ø//[Tý„d˜ð[Ó÷2þqGà\éÐ7 …¹Q^-Uû;.‡1 ¸X×#ÀûÚ¶ì´y±Û>‡Wž5$¿˜ª¦ÙõO±H{JÎ œ¦ÐÞ. më`?š°;µ°uáQ#P6 ‚êÜt‚œy¹ØçVab›,‘wQßý¬W!8H …Þ‰ V5!ˆàÌP”ä!&nc)×y’…ÆÁôÇd‰Ë¥ ŠX pô=mý3Y$öq-’Z ´/E›­Ú¡JúÛ\[U¨×ú¬q1÷$†‹´*aÍ}÷ÂO>Êý[ŒuÕiXÚì”çSBÿÖ«@±PϯVÙøŸ’ôŸ·ù¼ (ÒáÔÜÜëÓQǽ¢/öhö^âS ÐEVWE€¸ hOwÛ „¿c¥‡9ïn'ÖIôU…0ÄØ=‚<¡¢[bMq,Ÿ®óëÓŠ$Qz!ö:Uo:|>aïQݵÚÌ[¡_ «x1×­:ïDìÊ9—ë‰Zû`Ðð‡žâú®¿Ðëõ¥`¥î¸’wnKÝž,¥ã^÷™‹8’_ÝÓuLY'”ÍOc@;Á™1¸9‚õþ=)–ÚºK*¶&^k®#8*Ÿ©-ùœ‘íÁ®…ó…ßI_H‚A!^c? Y˜|r#<ØéѨ!Þk›àO„¿ =Uìž޶ˆUëé’+zµÎ c`+emâ ‚©/Sj†È»dg„ÎJf70¡ÛîdâZ0S’›#C2]"8ÑÍ,¥7,ðhK?Å{~n1ûžVm o5Q¨ RÁ©£•œ†ÂEöaQzÅGQÀwRºë'{¼ m\ƒñ<ʺIR)—êö~ô3Ñ9¥ñƬ¦:x*jàPNó~Åj!Cö‘H;-ß+—÷fßkýÕ§C.¢¡ý胫X¿ÙtŽÇÉSc´‘ºú|HôC DæØ2z$ÝŠä F!I¦Úûx¶ˆ9ˆnXéñoæM‹ÑmÑq~k¢)3ð%cÕ!þ}ÞâÒö`’à$¿¬/î‡C·TùÕ-ö`RY~\ \ÏKÓyjf§|æd)GÓkJ/ÐK–Q繆;¥XØhç'ß "4)F”Ã>¹èZ’ÔÿÓ›1ÍlÓ×aÎÂX®x”½Ç\ÔRÙaá;¶Ž,íu!Fè&ÄP¦þx÷÷ó t>£F›Œä+ˆ‰î—óï&Qôð/véZSlèÄ%‘B¦Ï9ŽußkiÍògqO<ˆ©³^}<û o汤ùñÑ~¹y&G: %dÅwMš` ÃYî%IXÇ;N¡Sç!” kíDá“\ý,˜.4ýë™r­K”ö„s´É‚h Èï}˜Ý!Hsâ½W/µ5½zþ,K‚#[_½jÚAr®a&fèiž’. ßæYÔ£Ënv¢£è¦A…Mä¨æÚ°ÂÐŒ¾Om³¨‚Z›*«ªqZS°ƒpl"‚U~ÎïòÙI)«äˆnöAŽÜEê,›g¨@"nç:“«ºR-süt¬cù°ô(磚ò-Ømµ;‘!!’ ô^°úQ¨1¡Æñ?2³·û½¢1ä;‡´JGºqM×0ØJLÑý}&å,G${;+–3"vµ={‚ôr”ˆâ­w%áæ{¦ÖàÐ2$$ŸQ‚éOµÀì^ÁÜúsOú}ncwÍnã¶U?†Ó~Câƒôªæ!{fgBºÎÇ;›°–ïš f·ƒAWùæÅL¿2ÖÖRDm„á>¡ óÎz§ø–uCŒðÕ”ªz*WW1»%^98O¬l½¢¦‡®²ÅE¾*ˆ¹7¹Âdßs,|ÊÔW ;ùDƒª(‰Â)6‡‡"ÇŸ€U¼,¦ÆRlç¬%†Pò˜ÏÅKï×Ïo?I-€¨€ë9)޲‡ýÏäQ~W¯Û/æ\ê(¡Tí:¾{=rû&ÁÃT|¡dvGväž<ÐkaĽ¼‚;±en, £XS”µüŠ1¬zqoDË”§À»G݈á•^g[Ì(œœ¹&˜V0Zæ„•R–NÝ›x´Ÿ_0ÞóØé¶òzº'¬›ñÆàøu,qECe‡„×·µ¾©6~DéDŸ¾Õëíh»1fæ6Úý,Ž5zqpw}”ÁcË7ðÓ¤fA0þŒ¸×Öñ«‚pX£}ùa5T'˜¿øM‚\ßêT÷åáÅÔY5ë1>^€Ç½Sv-lAµkGJ‡Ý6Á$êw‚y±?Ы]¥¦•Ÿó­¨ã{X]íÒ”åõ{"c?$ÇÎr*"ý6ˆÁô¯t¢•Ò0¹ …±zªuÉ©ò%éÈ–óO_¶Œ5’½ƒ«¢mz³%&ëéÝ8þ‚ÿñ¼ñj‰Þ§~¢ËNì±w:-è{8”­(l}ƒcXÒB¤šx¼èrÙ§•üˆ£4¼äX„>ÂÔþJÏ÷O‹‹–Ee2U.¨½Õï!IäæbâšC¿BJ¨ F½”ü²J¥Â­ ÖpRÉílñ=U3²~˽J¾öµ®b›¿XÉzÒfærÌϺ L`jjå4(|uë9×`‚³¼Ü–S_nok½&‘Oã{µ¼5;OY %öÎLVîÝéÁÝi*8'_ðø^HüÇ‚æ”Zº.ù8T§áTZó¿ÒêF}ø9-]›08«`ÃâfsÚ÷ n`š×;–ïSÑ&ƒ~û }(,G §[÷õ¸s<©ÊÈÈö(ÈE«Éh}·ÁmR]zê!aò4ðîA« %ôãƒËÖîãxBÓO­œ  ö7ïo»ˆ¨f[mþú…žô·CPÓ5µè[V,ãîã[ŠP¯¬»Æ|O˜•#«X9Ð"Ù¬û-.³K|hŸr¢Mª­T TœD±”åuè"åþ³ì Öªuÿ¬Ùzÿ`Ï૜âdø ×É87H¥"Ùñ£€¶„>òwàž\§`û®sź!ÿ I/Û+{nòš™­ï˜Å$èžòù·ð>3Û?$H< ^œoÆ«3Ï1 K$ü,,Ô% ÊÔþö?Àù±«ÉŽžÂ,ìAjÃÕã6ü S;_£’<-&×#2!7Ä "µu“±¹ífZp¥sÉ$#²‚Ò5áŸä-ÆÍßù‚£9`A—Hº*ÖL‰GÒ>z˜YÙÙÑÖí,Ýk Gj¥Ž[ÝìÑÈ–Ö­Ì  -a I_}OWÌRæw¡¸œƒÈÀ9ø62 ï‹Û"CpX…ìg«Û¾fÓkÂËbQoä&…ðÈ7“]ðÆf¿RWBÖ%:ùÔkƒlÇhƒœh% Ýu&‡â¹„ ÈNo=<Ÿå©J\Ù€8æ€bo3§õ“Ð#ûî‚Iñ9n[ä7Ú8•©5oh5£C-~ —([!BŠüPŸüô}( \Z]#Ä„]°«Îô›Êõày ¨„µ¿›Ç+¤áǼsÁeó‡Ï!IKûj²SG†eJZËžBÍtµzŠ<I<–D¼âÖ™Ü5.š—¯ü†hãE¤·wö‡Â€jD»¬ð|Ò#Ü·,!™¦OëOáÄ×à[(zÛÙy”½º¦°a |¹“ÆcAz"~ò½K³Ÿé§RaBùYˆìÕèÆ ÅU¡–’X³ÐöZQ¢€ŽÑUî¾[àðb†áu–‚ç»ÖJ²Èà=¾†%¯«”±QScÉNæ› 7מ¾áýi&Í„"«¬Ø ýY›WÑvåËù#ÞÉð@Ëé;G¹C9ö…­áä8~¡E’ÉôX•X+Ÿ9Ëà¿ìΩ÷;Eݰ¥Q{Ù¤A=kí¨o.ìn}D°*ÉbÇÚ·±<-ƒŸ¾)9ß5gpËóO]¹$.¨|-ùÑÓ¨E„KyóR Ÿ¹¬ühPWªD ý Ù.¾ÐôÈS:DTSkuy‰hŸÉJ†³ï= ¾ëÍ«gÝKÓ!VdÌQ;É\Àt3¶b`)‡§ÇƒH|øùòë ¶uøRŽ4/隸S»o£í\“¬“ž²ŠÈd©0,ä­ÂÏx±C³ç^•ê-,»? ¯J†ÇSW’\.£É»¸K?},r"º¾ô³‡ñ ”¿Ó˲“îH¢&)pîé®.ÍL댊WuL(S‰$œäM­¯»Dî7á†ã‚4kÀó]ÍäÎä#JŠÜ<ûµ ™á÷˜Å;> YmŽ–GK„ºžBxyÏ0f*™L JÅó´äG:ŸqÉï¶íÞ+?fگܹ>ÑÝ©»t&›¥×ù–BÐ(Œ¸‡%T¿•:£tka³T#—â´—hÄrä;$l½°Ÿ](ŸOæÅ è<6È\D8{Å‚1¿Ý†dý7@…gP&Dó#”û`ô!ë!áЫæšt†™üSC³®,–6fápÿì:Ü‘5ѲuI ñJ(±¸%Œ&:ËEƒwÙîÒF7'šO¹  Õ8VˆljÕÕÛM²˜äVzj9aײÑ%9«Á]†À«žŠÛ”ìæº*×pˆâsrÜcñ£3û5Ž‚§ä¦n«²ßªsE1©„‹ÓKô½-’Q«§jlÖqÇ)ýÛXáãó {›—>®U¾/Ê6 ©@7)¼Š˜X8;:Ž_òIxW±û(n1ëYßc¯ïS³ð#æg¼Äž²5Yγ SmìRŒ­”î{BXo¶%ÕƒµB§#’œUËߊd~„ .Ï<¸eÝ·€?z¦‚«æu*0å-Ý=VÓÏyTÐ}>zÔcê÷)`8ú1/àtöø®qÝÉ`Hî_òFg ‡Ådm:ÈÒ¢ÃØpÞÄ+g!U¿N‘ý—|&§qýÇ×u¾Ò4Ä€TWâÄ>µ2y;°u`©2dèÃ̈±ý•”9•nSð¬Æ‘Z†Ïj·b ä.¢ñ"­<¯á¿wÓÜfŽ )/q?o¸ÎðÑ;n‡…æOkþîǘxkAÕ.]‘¬ç`:ÉáÕáeH¼daâ]šYÒ“$2Ž"äf.«duOŒ³Ò੾ ýtûƒKÃ'lø„°£wÒà‚‡¸À²'?ÄÇW»Áßê4jèÍššÍQM^óý÷ú~ ]Nù1óꦫĸ3iž¦(²ñäwXŒRô ÙþèÆ:Ó•–}‰b³MP³²eù5ŽÚêù{%¹_ ,õÁ}c¬Uì ÌUߨ!x¢³ÎN-ëá&4¾ Þ)Mù齓ŒRƒÃJ³ŸÒòS›ÿ›¬ŠbTM<Ü2iÝóÞÑ'ëU›Ãé?=¾·I3èˆø‹Z#% Z‚U®´T¼”`¼ãF AŸSsEƒÝŸ„ÁïU#Y³¯pœk8šÂJÑN!‘?¶æ¦]þððª `I­XÉ/dI’7YÑTÂÜÃÒ=PõvÖXcLƒn‘½ ”"›ˆ¶KÁSÛ7§óŒÁ Šù GÇw’W(u•ÿð•uØÆÚ Ø3'jGÈÿõX0¨aŒ) íš“òÊgJ¹q‡z7™s®Ÿñ£cmã†tä^%‹GE“榻@âˆUûM·lh‘Õ†ëü+¹ˆOb^™­ ”G>j+läô‰„>¥(S 0‹Œ·S,ž_T ƒ°x‚ †”¿Ž`Dš[r·©ÚE—µU©©-Ç}§íט<Œ…Ÿ÷þ¬—鳌#öU—ûfxÕ5’E§(Bˆ*A –ŒÚs¶¢Ýiy7S‹Ây¢+0e¨]N_+Ûœ[ÇŽ%3‚o~xÙVH0ÖJjâÅýyõrñV  DÙ‚Ä$²ØZn»¥¾ìÉs¾ÜrªO1­ öôélc4ƒ9Z§Àà“Vû°V73¡c}8éi’âÈü”Q³½Þ¾2dj^ý’ÝSÄ{¯¦m3;‹§ÄÉÙ]¶‹ÁμFy™Tެ¾%åm|ˆÁ/ß:ö¶lÓs9÷y|C5m–‰*”º ÁælÞUÔŠëÈ}óøiëµppf%˜†Õ\]CÚ誃‚ÓyØ™.?Açã ~Ch£dJ2ó!'SIr0Ùíß-6§IzâlÓ†7jdÜ;¼‚†•ì-'@øú—^gáæ9Ãj¼’6²—VopãÓSTÇöæ&@Ðiä”—ë¯ÍÅšiþÑQ}ÕÀG4 Ä¿e‹5h0ùTò{ñI¶üþT„u^˜«Í*FªìòÓþ°žù‡Y%O?~©cwTá¨Ãd°¦ˆ-G&Ø•L…”N¶Ô;#¼ºÅ”'¾æ°Ab sƒAÒ•ÄpËÉnß`V@ÝùS’êO© …ÞÁ7²÷ëÁ™Õ!KMÒݲ„o#£<üG/×;¡C8VÄ~¾K®Þ±;H^8…%๙‹§í3Ö C‡èrúêÁëCR摟cÁMƒJçŽRì=þ•¤ù1t| Q§DsÞÛM´’|¤GÿŽÛé£zÌAîÍ,h‚výˆ€X"ÖH ©`†ØäXæ>×~é;ïªà|×¹ P©®ð§ŸU©º'¡ÒE' @ óR¦ÇÕãyºe»O‚£ˆ&Ù?É0‹¹LŠºõ>®H+üG-Æ5"1ØŸÇôü ÿ§Z®µ©Ù)ÿK‡ç¨îÂT6ÖÎÄ]kgº–Ûlu`:é•|²§ïšßŠ/uVÞbòÀˆ{øf%÷k•®Î+¥Ùáîæ¨È¦Yø•…ÕŽ zåaƒoä…·~ç6?‰KwÉOÉ Šè·‡³T.Y£ûcŒ'7©ül'þÛ6Õ`Rÿ-‡å–h»cÝ*¥A®‚ª–á’ã´€7ç} )½(­+7g‚bnIâJr»NA–YhŸŠqÕ¥d¶W¹Tp§¢ù+S¹%Ò -Õ~íïR½çp ‚ŒÎO¸Œ±º7ï¥å3üœ1ʤ¸|;æ•_Ì k³JEq#ˈš¨Z½<× $[½o¸>sç,7bnÎ|PWw÷í °­1VW )œÍÃFz.ÿª¤t…¼IÛô H·uÜÉ˦»pinâ£MCÌhÓÕyšî‰Ö²Û]‹4üäÄ‚æá~‚Œ“?/³ù$…UÚžË,qµÍÏÞÔ1²²ùb$ßÝÂÉ"J…œE4›Î1$¹þek2#=¼Œ•×÷–íWÞ!$¹¨M:Q=è䓆Ft hmL9¤’ª![uŠ¢­é_ÉišŒYªÙWÅz’Î=XÚKÞ£ED„ÈzËŒî,d¾Îþèú ç^µT³q;Š/h;D‹·â0j}æ]íp¾ZS2€0jÝ¢V¾`½ª3¦ùI ýUKý¤ÀÀèùEš}y‰ã®{~Ë»5GRú¸•ÇsrOêøL@+6Ûÿ¤qEu.¿üäG—†[K²'g/ÑYæÞPû(õxwþö­Îd†þ6â'MC,D™ÐçZW÷ÚÞFmá<9{°ÕU_›c® VŒgç’˜E¤ÜÝõ@–¨—>¨šy‹†™2î5KHו™6S~ð`7Šù™¡®C[mðz–~•'u˜lmHñîðä `öZÉ¢`ƒLuÛåHWñŠFpÝ,ÃÛTßGQ8ûôª ià³ Îa#G>ñ(ûvœäÛaè6“-YÃÓÙå$©§ Ÿµ³Í˜eŸZ.«… 1µ RK+³ B͆sŠÒ[ÓN?‚ßü‘HÀ uÛä¢ÞtÑpã»ý(;t·oÇÍ¥ä‰=æS_E­áŠÏ˜?¹¦¥v昼ù"+.ÔâE”x˜9Ïõô,­U% Ž{úÌ:«O¥7E·è㛿=¢„®2žt÷å¼< R¢®ÈQüíL:n|£­ |Äá„#yWžboƒ,0Õ",YÞ‰†É‰÷{‰¨£@ˆW„Û³û¶öI‚–U­”ºÊx8\x)Lµ?qd‡µ•ŸÜvÈžÆ5@VÕ5uk¼ÀÂÆ‚«¦+Ë>PÍøé+ˆê©qàFAÑ\CŠÂÛ¡ p×¶ÐD™ yp¿ñ”ø¡0» çðÒMôÆà‹RÿUlùª«§¼ÂŒÌ5ÐÓ9«ý¹„GJ ™ËBFû ѽ¢tôáVc}Elð)ú£tÅÀžêOÝmU.öÞUg0ÜË0K‹p„UóŽ"{5°:):,úÆÖ#fÈ‹[*ÂpϤڅV`¤iüMoÅsVâ#åi`d<[ü]çõŒ:oàêCéýí,¹YQΗ‚‹Þá1­?Œ±ÚH ¤£þ(Š!`÷¾f½£ñbÆJdØdöW ºJÖ”³*ÂwIßÕÌô[SfõáòBR¹§4Ÿérôd㘠¾&9Bã)OØ=x Ѿ¾ö‰•VȹeWÕ‘ÝtìL¯»tÊ­‡2yi!n™¢7Ks ò­: ©5}ß|ÖÌW4 ©™íš6¹%ôÅjaÎ3s¦ ƒõwø#ärö=RÿÑ/*’EtGK|_yï퀢®†Í©Façûw=nì™S¦jêNÂG>i)b°øKæ¶ñßLSŠqYöÏ>[ë{à“i–¼¨úÇf®ßáÎüc}û#|hÕ§ÅO¿€ìb7/d`j÷¿Jõxéj_P"’$Uaíwaé´xDÕ%$Bvi3†Þªw¾ŒH‘Í,¦ ÆAžì7Ùo{…~XuÛØ=ø­Å-‹„D Ñ>éÌŽ\ëDѾç2DÁÊ-`uµGæ{ª)Ék{6 €Ygîø]~ñ«¶ÇHW+Þ×/ã‹ÆðœrÜKY2x÷GΙÉ$õ|„ÇN v8`EY°°Æ’0Â4› àÛVÅŸÑ_Á¿)æ(+ÉfF¯ò0[Z¶@Ì.Pj9·{%h¥S$çôÚz„‡ Di0j¯eœqôÃÁ¢ÁŸÃåy %S§J¾…èm’?¸¤&T£€í=bpE<—¸>ïQ—Ý‘¼™­Ÿ5ê§Å$‚Ú=\0&3ädzè»;eéüÈjkE(;¨a±äéj0b)Ú]íâP%Á’‰O’ÞT ð êúÏ{ÛWâÈši#áÛ[wñÁžØŠ°Ç_?š†¥[ÊжâȦÊGtØÃk®þnþ<Ò ªJ?…£i°g»‡f£pJ”ðÀ.G{á·vhàWi¯@—òÙ\òzútLÄ^‡ÊžÀµªÀÚ Pì¯^r]»ÑÌëQŸÓÄ@Я1ª´%Ö›*ZÔ÷jCà`¨^FÛfŠì”³¾be_võ&óê9P·’ß„Iµþвò7/ü¯á‡óÙŸDxV:‹Ç$â3óøV4×]j$#§òßàf+Ça†°®’ÐWõN&êᘃ @£Î‰¡®Ä,Ð$ûÃ÷ä&˜*° Æp·û¥¬ugVÉ÷ADÈLÄz:LŽØ|LËDäšgà™C—Á÷–©IBQj]‚ Í´ÍÒ/FÁÍ}Œ¦ÆÆª ÖÚÚ°<¤5ˆµúvÉS-›ƒÍ+¡Î?§x¢‘©í¤—z(eWÌmTƒ ÙÒ矣¿ó±³ '¶¢ýý„l% 4ÁûÀ4=W"–S ²:VË+¶£f¯¼‘Ù•Éç ºzŠmzÝË{ŠœÕ»AÃ%Fµ rÚSC‰ loˆVN²¦,¤‡Ï#†EuÛ{†îÌlÙñÁõïuǬ#± Úç´õ[J¾Tíôqœioø=Qä¿å<½ø¥/?C7g,’íE°;ÊgvÑDQB2EÍÈ(ä§P#?? E¤H$Ú(ÑõŽSôº¨‹žÎ…Ô–Rô°[áRÁѾ5ž»ÅÛ&§¿C1 šeþÞ¨)ê1ïú>âŽSÓ Fí˜Õà0Æzo þKK”tQ8Ä eÄÃw¨†•5}­ –¡=£oÿ'zö*"ÏÎü+ yÒšŠwÿÁPù®gk$žM;ª‡ÅM–M!þÉNIÒ|ÿ¥ÕaNS©–q ÈŸ §gkÒÝÂD±›ïçØƒüañÅp"yvÍX® ¥HÊæ@—Ì: YMAË´—)ÏÉN÷$™Çý¸ 5d+EÁvO:‰ˆôÞã¿7p ­tFO‹£¡U—bÆNô-+ð­‹ârŸŒ6¥àÞy¿: QuUá¡Þ¾1Gj!,·òI­«{ön²â§Ä’güâ­ðŸ’¶3½0ŽÖgP̳ jü`t_:½’#ètc®3R'¡ÅšÎ —®~ïƒQ^ŽkFØÉ.ýâIN˜:c[$å³=¦‡w/e×õfUx#Ó<#`BGr;¸ËhË¿Yl¦gŽЂÌWè8­çÒÐðÿžY¤ÊVà•W¾€#ÑLt»)S+üi èØ–bò`e¼…!ˆ»¢’:ËÖ(ÁÉUé ÉF;qYK15gÚóøÙ®2ZYÙ[ZDåð$²=ëUöºDåNk‡ðŠÎͺO–yÍL׆£6w9+#§~µ!.w}YÝ‘ŠöÓ­Áø ܲJîñ*>®Î‚¼®Óáû,6îÊ÷ÉÇa†Ý$4ɯUl?XƒbÓII«%1ËO]£5¾a“iÿ 7°þ`Ã[‘¢h«zrðp¥&îàe']TÕ¾h•à§ù¡^ÏRu&uÞÕÝ8¹M¬ú/pV8j•õVçü]h¼=Å*ó>ÓÂZ9ÙI"!YwŽ9Éx~æ:Îe`qÂpƒÅtJàÜ ×Y`ýÅ9>š6’ê¢ê+y à“éÚô4ðp?øÆR"ǽy a áØÎ+eá½þê&Rº{ $ ™ Á•íÂK?†jSÇŠ¢NF~zIêà$‚нšјqN8E~ îÕ…ú6mâÇÞ¾ÕsŒ úÅÅñ{©?ñ{]¼›÷Š[»Ôœ±e|›WuFª~=TêŒ4UŸKri¶+oÃ-b7ºU¿“ØþT#‰OÝy•ƒjïU¤#ŸêRM¬ «åQ\­ÎÕ”¿O¯rÿÛËT7Ëå)£OÛ5g[ð÷/l°ˆf|×lM—;Ô³Š'¨è@ÔŽÞÚ8lÚ±W,øþ¼{½n†ÅŸÁhiÁöïŠ~Wrd­ŠæªûŽEÞ{W¤ö•à줴÷.Víàú=4£wÄn,zR·èô¼eZ§2ñØš„£eç¡+ä”z°>‹‰(áëüóo/…gÚ‚‡‚¨´ÎC¾WÉNšÂ?ïâ&²KÀÊÏË ihåXÆÀ+Œû&|eIÌë·V©¨àüÅ–q1‘|l[JÓ=ó6Qè‚F¨–©÷É-ÓË ëdq1É]2⣴˜øÖ;{‘ãqâ] 3‹€íOÑ@\âY’~ÖD÷€Ù͹‹5jv8gkH^• #<÷h3Eíló¾–t9;:fܺ¶”áBÆg Îå]LùD¤5'ªdueýP6g׊¦¥‰$¿*{ (*RH¯O|¡ßÒ gw$ŠÌ®šÄK‰’J[é 5yA+ðî6·òºß.«sq9dB› Éõ­¼¶\U?§9![’9àòwAôÌÄ]hkªâ}ƒBÏi"ð¶•‹ÒB›ZÓÃkæá#¼w0‘å*‚&À8sÉO=i ·ßd:¯“úеÛ¤í.2fYÁ&ÕÉ”°$0ÎC_]\±ºq øBF&þö„Ø­¹ €ù!"šðùHÖ¤ÈWó‡_“‚GaزW5¢þòSѼû´/ÉBžæSè”l#ÔÌÍì”Lejl{O$ÿ­!ñ[¾K‚çg™T;&”} é*GÌÄ´Õë˜BdKà‰;ÒRîVâ>enllØ?ˆ­ÒJK´YN‹E<5[c›–¾ãT¸^Y¥L€Ùp¿§”˜db áõ©?¦›~á¬É5púº„‹ÈŸ'³¬ÃßÀÙ„³p^â]~4¬‡QKžä·þ¶:å §e4xÏaª·)®ô®¾ºš¼n :¦:«n¾ÿ½5Ô9c@Ë´ç3žÈ÷Ã.—ͽ·Ó EøøzŽKÅ"Ϥ,s½/ªÁ1±mÕJ²=uæ’âq“2xÏïxväÄö\Ç^ §i¼j­é'$hÁ¹g¸Êyi.ç^9åØÊ¹»›D©Ë^ï-XÄ%“Åþç.H'm© 5´ë7Q¦üÈÁ‡’òù{ßsØÉ‹¾ÖÚC›ª)ùÃ[^š³l¦‚Ž¡ã £ÿ/* ÕòmM­õOµrÃB]O—:šJÃ8ÏYƒôÊð‹hô3¸¡iØ(z5wY‚žÄTõš£;úÌG–.‰¹}¥ÜÌ«ô¬·ŽëßP¢²¬½?ÒÜ\&+‘s·¥áî]*‹N^Mé$cù‚?ê,Ó àŸÚþÜÑ·¤¢¾zÓ¨‘ì“Çîò'ÞyÙËJ§ŸNê²ÃÌMgæß5•Ââ&\â ‘m[ûdóPã*uýbš €ÉBv î:¦¢ùçæ9¨­k·9_¦}Ãrq¥hî›J ÉÑc¯÷‚mN8œ*w´ˆ-uš¶‹ü °„¿Ä9ÖÕzš$ã Õ–” Û”Œ¦î‚nM&%ÆÝ"*Á¥òíÛÞ[ÿšªêî`» `(°n•&]‹íÑ~ÝÁ< jNnB˜Ûrå¤ëߥ* WˆÕy€œ3Î3´î<é%ªÆ/éeJð1ZëNä;ïPøÜ6kÌD/ [ÚjI!uü,Ò|Õ)T^„V0ìHú;«Ævà§7ï¥âšÅEGzõíÌáò.Ö@¡ùšóÆš4e²Ýä;,QTñ^\ÓôõUMÁçIâ…F Je«öQÕrœ'ׯó=—dç˜2]~¶¯Ö‘–þŽcÃZcÃøŽ ÕÅ}AVj¢æ¯ÚíYfVõú¹Ê¨dô·bï5åùæ&†Ì0mÆ^±øîá`ÌÖL>V.ÝÊ"5¢¿—»w2¥;÷{à]6\R~=9>U@´B>;ÞÙ·šôLþqÓ–é}éJ&Ó‘ ¸§µð.Z ì#pa| à­Ðwž®`y‡;ñ_1væªCÏ}…0)gaü¯¶×ÓT‡u’UÜÔ­?7óÀøÈ´ÊíŠS&ÿp’™¶æl QïÁj’%bý¯îÞ›^D(e Äô¼ ð][J¹m½7Δ+±¸¡|nÉ åxtÖ›¶»¢‘”ߢÊüvTÞwÃ.X4&öüš>÷e+jgŸâ’í¯KÂc©·og›„^NùÃ7rHÿ©£õÚYŽÆn—°`áà8rCJ]˜¼„ OíLà÷IZáb×TFO‰¾ Q_Мº! 0ýÈmý8HbdMNn…vpÂ^YÔŸ1’OZ4ò·›†qùïÞ'3Œýò‘W+ŒbŸ g®±Í­f±ÿ­é}*8¿)úv„‚ªÇ4•xñsˆ{Þ&é"!zÅMÜÏ‘®ä©ùqÃý­P‘Œ¸hï' rcÏïãoOãôÆE¡yÆIa‹âÙkoÃAÓÏjÈñ 6ç'K#cVË/p‡” e©3T¬ 5bnþqNya‚뤂Y œ›™VsâXEŸ(r#>Rµ-ßóµll˜ðØЉÊýs(‘ÿoù›ä›` ®Sd‰X6Fs7@›©“ ËÑ¡újêë­ ¢énV/ ›ÿ}7IЦá-iÀ{1¤–uróç^ñu8~r%2€VH–Tï «u€;óÛ„oÐe18nœ ÍìäøN·b¨"QŠanä Õ!‡Çyr}0ŒÝýÚ=÷H*oŒ’0ÃÈxÝŸ6#æ4Ø/Ùmž@@8ˇd!âñHe·®¯7óÓ†öµÀ´Ç„Ɉ×Ì« ÿsh¹™¤æq¡ìWN£¿Šºðz3Œ2 çG¯«AÛÙ%LPxXÝÐérÊËf‰S©ˆT}'"æiÌÛ·H˜´Å’N|¸ KwÑžïædØñ×ÈuÀå˜ÆÖXðA_WÐ|mXþX9¹¯Ü¢Ká)ô^1‚?æ)bŽ3t˜hVF/<ÐäÖ¬š~W¨+¼¾BÚíÇ 2"–/î '–;=;ý¢ËÛûÇ•ÂÏw'n›… ¶pôž g»(À^/·\ê+»6ª¾ò#°™®ˆï/`ÃE¤Ð'±C›C°ÎYRûWW²$?û iÙ„ñTÉeçô¯ÄdÓÊ6<*PêaÁïº\œHôõ8o÷Ö$MöŒäñEÁà,ásjà܃V~º>¾´ãï…AGS¿½]}vºuvö"?Œ24‘5}J8Iñ8h‰»zŽá¾‡Tó‚Ê„kQ^!Ò‹C¡c; S$¦Ï?Ï1¶3G7 \¿–u±R'wÂÃâ lM¾Ñ¨þHS>d¼ö‘³¢±ãâØáiPbúR„¾¡½ßQFÉήÁöô¢ýξoƘÖédÔé QŒ³–á8Æu!T™ŠÉò>0ó¬M³×˱^j°\~l¿Mì¹^¶Yhþ>Ÿ{eo-LHr0,BSW•Æl«h×UØ{œ±=‘V••©- rB?w«ˆ¹½IþànbP½E£@zG}ô²Cô•Mº¦Aü“"”xDí¾3M+Ô¼› ñ+ÎÛ›ìð´ò—ƒºÕÚ– DsòBœH £c*x_Cr‡v;­­íÞÚ0|ODuô^•wS]Vï/Ú»QÊ.#¢a×› Yæ䨻på¤ÍyÎ#4™Ç@põˆfŸ<±y#èö¡©Šhÿˆ g· €Ÿs),’¿n¡TÈÂ…Ûï‚åWë^¾*ЖCG¦à©žt©û| ´F“ ÃB?Ó~XmAo«øûÓ 5„í…sPý¾ÞZâù„Šqüf9.2×sº@zWY)3Ã#\-µžÍ$ùZß¹y8¹ppñ>¬4\aÛS¿ÛvU‹]ŽÙ}¤&rïê„ßgÌöÆÒ¹T@w]3‚b<µÖ¥&ò©@¦¯?îKš,mŽã™ øâ{jŽV›rý9%g!ß…YÓ^i‡Œ_ý¶Ô•{MJ1Q¯ÕFGŽ yèÈ ƒóKš)¶³½Úú’Qœ¥í„~;×'MJGæ_û½}bsS‹™þÁõàÜ¡äüݹl3ªi³Wr; eðåšóí}´‘µ@ápÁ*5· 8VNéÂÕ$­zíµÁ4)ª§Êë3ŸB¸0Åo˶j8þûÌ—ÖÑ¿ss›çnk{Ùvˆ\SbËã¦2n³4·2•4%ÒüäJ5ú&V¦f¶P%%®‚SVŒ„(]]qš‘è«¡&Ådn_ Ã„ÊŸ£¹’RØsåˆÐwl09)l<·½vX­ ׋‘=£g‚J¦„i3†‘‹n?¬gVÓØ_"öÎJ`žäŒ{‚~Ç¥û¾0‹ÂI%¿Ç;FöôÐV_n–˜„„\+Àjȉz¥êŠ¶ß¿ô Y2ìÍi&–åJ%Œdã]êšÖ‚ùæ|(1b Nß›cK šÆÛOR2êiD¿Í±èžFàÔ¶²Ã5|pwM½ðû¯'<'¸ -†”}€¿z‰õßp¤ƒ*ÒÒO!¡l0t—wMçÖ?dF‰´ آ󛉌§¿ì8pÝY€ ƒ)—Xž4‰k’­?{:¿ÍéÛÑ{¼ú›ãR/ªJ ÈñøÆ÷¯ïçC'ÏXÊY.Cü„޹ “×93Ó©G¥…Yú¹'¤- ù¦·š¼7°FèØqf4Ò+'VšßÁ•YÙaÙ pŸ(% èÛ!îô;S¿XA‚—Ã>´öJ 5\5™ƒ EVRÈjÔ¾éÒð®`5v|›©›‚ÂBSBW¿.Ùm€*ÇT„1@rW.•ScM¡—F7> stream xÚ­weXœÝ’-îîNãîîîî. 4ÜÝÝ=Xp îînÁ]Cp.`áò}gΜyνógîüè~Þ]kתª½j×ÛME¦ªÁ$fáh’vtpcbcfå(ÛØ›¹»ª;Ú+;ò)2©ƒ¬ÜåÜ€v€Œ ŠJÂt³qtºø: €$ÈÀÎ`ãããC H8:y»ØXY»hµÔuèÿeùk ÀÌûŸÈ‡§«•€úãÁdçèdrpû ø;j€@7kÀÒÆPQÕ“S–ÐÊ(kd@ —"TÝÍìlÌŠ6æ WÀÒÑ`÷ÀÜÑÁÂæ¯Ò\™?¸Ä\@€«ÈÜæÃ äerú b8\ìm\]?ž6®+ ƒÛǸ9lÌíÜ-þJàÃnéøwBN.Ž;ì?°2UGW7Ws'7ÀGTUIéäéf tû+¶«Í p´üØiáhîþWIc4¨ÐÆÁàòrû+–`aãêdôþˆýAæäbówî®6Vÿʀ಺XØ\]?h>¸ÿ:Õ ø/Õœì¼ÿövü{׿`ãæ ²³dF`cÿˆiîöÛÊÆå¯~‘s°t°±þÃnáîôOÌäò÷ÑþÕ3tI-ì¼ KeG·Úÿ™ÊÌÿ{"ÿ/Hü¿"ðÿмÿâþ»FÿåÿÿÞç§–v·³SÚ4À?æ àcг økØØ] óÿËhocçýß9ÿûnÐ?²þ·ÿBÌÁêC!&6.f®˜m\¥m¼@ª6næÖK ÝÇáým×r°¹ØÙ8€>Dþû|?œXYÿ Ó´¶1·uøK ®@ ‹¯áC·¿+`‘Ó×QSaøo¦íß›U?ºÂMÓÛ øH:JŽÿ¹ø‹J\ÜÑ àËÄÆÍ`bçaý¸ŒבÓÿÿöo"¶­•€n.6^VfVV6ÀÇ÷??ÿZý”ƒ¹£Å_}¤át°øh½ÿ4ü›»»¸|(þ÷4ø¨üŸë¿/ä2GX_q4û”™“åV›?:%i0ØÏ9îôµI³¤(¨Ö±/03ê_•ék]8só ÿŸïåŸNoòô‡ãý8v4}ŸA—…DþtEèÛÔ]< ‡!,Æ_‘³Îtâ|¯–w ô¹Yµw§ÔÔË^aˆgº8\à®é‚(<Š‚°(œPÌ3±»ÑšÁ0ꋞQ§ž<>Ð OŒŽôÝ@2ä%ÂS qÒ’¥¹y›ºÜ7™ÿ~öàqGôDöÅÌzs§v Ït”hðYxb¢íúz:c(žáÚ´nÝÌês5zo-!Dˆ$ Íæñ –®§H0¸½F;ø…ÊJ”þA^+»ÇC7èWÓÚgd?iZŽìs9¯[`P—ÓºM@zƒV}“8QãAÜ]­õ$+¥0wÕmj´p®/ž´®Qa ©ÔAŠ&ùä%¦hbÇóD¶ÌOiLsŽÝ.Œ Ã'9ÿù”üáÜE\½VÃ’EøgÃfkYÕ§õ¸[Ÿ×FkÙ€u¬^ÌBÌãa¹jp¿±–Ç6¶ÖÚ"I³»¾c‰ï=xyÜsá5Ü—©y‚ô¢/éj÷‡§P: ñ×µe»ðhËÃd_©ú¹{ÅÊ,á²WfÜŸíÂfUM¸¸M³«¡ špŠ•DôJøIÖÑjȦ㈲K䋟À JƱbKq Úð°9wô|§‰ŸW$ß„ùá‹ëñúÌÌPä”ÏÂu ¶œÁͰvs‘… còjË£È/3Ö:ß{XÔ™øïäh>“àå árw‰Eê,€1,·œH÷ÜЀÇh~±“¨í‡ó¿wZe–& ò¾9)ÅðVòDæ#€X¢}¬Tž¾šÅhÑX{ÕÓM¡U x7æÎÌ”R)­ŠðÆvÈ”ÜØ¡ÐÄÿ,$e8´¯i®—èó"mÁ&P¢Lî+ZâƒcŽ{,0ìãã¯`!†¯#±¹±€vSÇV»´(mzk°¼kÝÕëq˜x ü72ÍI¯›‡:¿lЦœ‚KÚ‹ÂÃL"‰Xä{[7¿/Œj€ÙQ´žñSyÜo# ôÑÐgïÆî4º;ƒuxaáOçØG´Zžïí/²óåÖ¨;ûûÛÅBNÉh^׫BÙ¿WÑQ»Ÿ†u dxß%þ±®qåÅz=Æ´ù4¦0KF…CwŸ/# søvUÕ_$<é a+t«ì?ZÃãÿîÚ„u. Áƒ–îfËY‡mâÆç3 îf&˜Í(¶#cæô±¯Ñ’6ý¯Þ.…Ý€N1v‘»Î‰h-ùB’œì»Î7îˆ}¨·¾è¡=d;Óoc¸wõú¡5ëG(ДW‚ôüÚ”<•án|}8¹[çðáý|wC,@°©4ßyÚ(˜K®^â’†‰$Î̘^I÷1± £éæ 1c«\Ð0vSÖ D–mKøÐÛÔvñœ"ËXc¡Ú79zÚtÊ ZÒTc-*<Dsì³Ù®…¾„Ä:ªM{«Ï¯34è©ñ¦úÕÐoTݘ )nVÅŒ€jÞùëoy%nÓ¬kñç”M~F/Ë O«8¢©ü÷îáN~c˜ tô-–”Ÿé‡ç‡ Û¸YrÏÁí_ÊÇqµi”-3‰ÙcÝÇ }\t£i•Ì×wl‡k~cÒ–/§@¤-x¨¿ÐFéš^ÆÓfÜ 1«UúìJ›éN·Caçþ'XÜ.`P´¢¸ªë¶Øœnp9еSÁi[;Ïìs¨ã—Ëßûá l‡åˆ£~þ>˜ZȨ¡!ó?æòñ.‚èÒ‡BCa±ì‹¥Â Q?Eupç>`Öf âÜ ÷vmªÖá¬S©)äuÇ8Y¬YA(ÿÕØG¶Ê©¸vR6ÆmQu«)G€hÊ}ü ¹ûo¼~töRíwk@74ÍÞŽÆ!ž†b]ýÌ'ü¹ËÃm✌£=ºeá7úÈhé:4<"25ôðX”fz!4ï=€°Ù­`<™°k)çh;&œ»;;Ÿübmn•3®Í1‹Î =뽎-hã~‚7ãšÃÂP9¶°ÕèLG8¬¢É¦íÁU1ÉÂâżBu"”KÅ& Ö›xÏ)™„Š*«0…¼ákhùý¸?g«¨;y‡ɤR´†÷û< %%ÜÙÜaòŸ¹¸U©˜¦)0FÑG.†ºe|³´?¸Â¥Þ†Èš1Uqµ8Á-gTˆS–ºò§°ÃØõ^_Ø~4;7(Hd¸À–Û³«~7²ÎXʦ_‰’*CŒBÏÂnÙ&Í4%÷D3IÞ·Úˆz¬ÎÒ§"™‹yåÔÆVò[l7G«'VýÎ蘜d47"œâyÉÀeå!}@Õ{júìÎ?oEÇð éá}\PÙçGG:¯¾v#i©‡ýB GìöNN!áíh7óøb-…N½Ó:PJHÞðþˆ¸tp÷yØ ¡^h´ªxw¸QÎT‚{b±a5û…÷ÅG¦Rbä:W˜ê&äà8þMqÛ]! ;¹øn©bRå˜Ùq»‚(©õdŒ¦ºŠ.δ ¢>@©ƒûÏì ¸È<$‡½Œ†7Q¬aÜ1xÏí(º½Ã*µG•A¼Ò¦T|ù"ŸYTÃyKƅǼ¤žŽ]u?,£±™vÆ­u‡©Òª•”s[gÖâÜ®z5 ³P­(ÉMƒ¬4>/<­ž?ý¼j+Gc5÷\²>eþT}•¸ø‚Æ›±=|µãRV’¦‰Šu¼O“±¤œ[¢éuQ¯qÍçË䆸4?|Öö6h@ìÖ´75~¼š"æ.̵«SüÊ*då“’IY”•Öj‰ }†qþžV;f0ëMlèZ-’Á•c²v °V »œDÉ+™Ù‹íåŽZ¤ar.š‡Ý0‰ÒÐOoÁIºÈ§vY…ž4`¸UØ>‚¯[Pßð¦|Åž{wÒ:Ê`º ÁøK’3³+ó°¹úa†Õä¹L7Zxùʪ u,Eìhð^ô«çW¾Ñå¬Á%YôdÿиäMíbÙ­>Qh :ûžµ8Zó–//ÄΩÆÞþ•¿d¸ò°JM'™¦á9>_ïË[’4·°çb.LÕaßÓ@œ•ÙZkßíÜå#I³ô;×ù¿‚LÒJ6Qƒ úˆ5Dý)+lnÆâÁ&-ô€CZÝˉ)Ò)ºÅ'¼ËƒÇ—Å´­D.S˜¿\úõ&¿˜=Du9A$Ôuk‰ÙÛ#MêXÝêøj ¶ÌaÀe–öZ(`oÆfwÖ¦ etd=®”ó±ÍjŽJf$‘Q¡Q¦´3¼ÕfjsHmð¶¦P¡éUø’CvW¶ˆïYS9bbàÏ¿zÛ‡5¬,>'Ubè÷o Ö¹&šø·„µÕ—˜í¨èpÅÆZ.°q)õKNLN3qí x«¬)ÒÈ+}¡–8;ÇÞL¥]w$K®m^ºpâÓ&!:£)sI¼Ë&tÑ5¦&é©q*É«€úÜÉŠ ½¾ \û¬óŠD‚“ñÀ¦‡Ð”•M( ‚(¹Ôoˆµ=¢ç*ì"ÓhoøðŒw‹½AFc¥BQãîÅç§UÕ)¨ÚèÞƒý×Ðįc»«QeË8hòÔÆ»ЍÛõгøíB›Ï¿5*ù½E |p “t=L˜™‹|kCà‰­›ÀïîEÛªýüzE³ÎùÂD…8ýüŸFÿ }Ú”;6l¹Ë¼¦°;QÍ:l!dƽG†Öñ›‹·¬Å½¼ÆxÓÿ’ƒÔlè›ö5×]½˜˜+»C é30\©xñhþçIìö†´„°RxíKÝ¢ ¥í$5'j-±/S´t™ævP (r;Œ*Œ&Gú×kÿmäXŠUL€'ëRäåK7J¤NÖ”íø-¢§;½„ÛÚŸ$¡§”×@¨×ÐHüè×Qê€i¦ û,èvÔ'Ο§\&îV¶dËì0U mRq6OèÏøbÄu1‘¬9Ï!’ÊÆ»®\MÌAåFh\´_³t®‡e»v,eº’Ô:ÐNY ‡§€Ñ“§Œ¤èoL<㎂ëÑN‘Øhûœ»ç'KuVbÜNÚ 9Z­þwHòíNáé•«Ò´k-¼8wxSÚ;`ëYÅóÀFrÆI,Ü”$Žg%úãØˆX|Iý‚_¿ȶ2¶zÚdÖÝa}yfáOÛZ”—W\÷>Q+LæÚÿ®:ŽÇÛê.“r<¶ç¬1RbS™Òˆ»ƒ.H õëÕ: ޱ‰ê"HÒ$$j·ýMö°‘EQå†OP?’/?ûR8¦2A×Y=°Nc (8üÕ1×P‚´S`ª <¦„Ó~V¼.\F?Å "Kƒ! qcÃþ5Q<‹rÝ? &ðÇ;‰ù¥Ímª©-Ú\-õ¹zo…WÎõ°5 †HÚ)µQGöb {)×Î墌ѾÈwL§À³ðémÊËQÖI:šð¾ Ôní ZìJy§þö´uî“á*ÁQoJ½~£ÍœÑ8Æxêö߸ҒRûA•Á¿0îV=´ 6ìú¿í`ÿ­gÕò °VÒKëî:é•}²Ä,ûN ]’G1™DûZ‹›¼.ÎgkŸðËÄu«H½L Î* nÅ9æûóWi æ7σ9굈á–P«6÷;ž¤Iókr ¡6¶xøpšt}Vs›²Í¢ÞjhSƒŠsvgm$8¤0Z¯HúÖ=³Ç¸‚â*gIµXœ…ïúgíX‚ëÓD7öÏ™C) «§z'…îcJõ¥²Õ7Ö8¿â›™Ò™•1Ìg91ÕJèQ$úU'küÛêŹ®ßžŠ#÷"Mï÷Æj$)ÛÓÓ&Æ_.|—ú¿ß$˜ä ]‡²œhŽH jwÃ76 ý¹x2ç. µÛ’gPN×ñZßñÕþö…Æl:½¹7Ž\ «EJ'QýöKÛâ#ð1d+bA0Bzt Á &,Jï|L \_°"a{ˆ]rØo(§¡ÁG‘9ÜÁö¦=?ü^g¨W*\¿úÌVÜËË#l³Ö½ÊÀ p»Ø¤ý4xèqHÞ*Þê~jdŠ9·¶3E)3ˆìÒA¨ì ݘÎgP›}jjo’˜Þ}½àFsÉ÷hô™7ü3ör’ÛW©´=ùF"&ËN”å±î x|@-°Ë‚ÑDüñ7²éG«D ³ÈA”°” oMþoð–o“xÖJï@K«y¹žðJ8î6üo>RúîÄã.?K×%,RržÎ®1N[CSæä®îé J “Ë<£4ªÇý^ß'´-~ë[„·÷á—YG^Öå ¬®»Fdœœ¬{¶K±ƒRmºi¢U²»šqDô% "~þ ½4ÑL`'}Gó4aGN©>'eÞyĵøMÇG/7ÈÆoOˆDÌÚÀåÇÉŽy 5!-Ôaù«@6̯;æ@–jÉ~D§µ 1ïz+,»ü± âô_ñˆFOÕ}-Š|нö'·k÷êóFe,QÔd§?ìAP¥ÂÅ*Â~Œ-ý„ÏÌÙ›u‰¡!JWºmÚÑÉ,¼ÜÚ$] ¸·_³…q.+FØÌ´ÍTµðdEq~q~KP¾z뻑ù|sqEЙ„Wln1“\ qŒB°Ú -<3¡ fCÌw¾"†.wÇS@ì' <‹±½ ‘ö™Ý¯79"°è3Úl&ãøVV?›é¸N|¬Éoî/˲‡ w3Úë™P}ç‡ÄæUCö@&E¨òúwô¶_|©LXW>é¾ü2ˆq†¦£ÕX>ëö¦ ðƒI6‹Ú§]±/÷gÜVùhH6V±<„áÛvÙ1ádok(bÌHA‡DÐVšBþq¢ ,¿¼~ð–$O`f3C²ÏÅȼJj¦ía}xg^·÷å±4"èÖñÜÓM œ§øÆ/Äˈ,·éy!Ž¡Y®iZô6·}]’×óiTåGh‚W i" ǹâXà§ùuy‡£ÓÛ8¢JÊ™ÛÙí Q1Nh°þ‘Cí¨†ˆm÷"¨¼#TæË?êØH³k@buüª¾•xê qü À:é ñð†i\€yŸ`œì•ÓaýåÕ)æ{Ö=7Ÿ¿Ò„¦êT¤'7I¾=0óyÙ·¦˜•¯'zpÖ0|J̵ãákã¼^·ÁhßñÌ «I*EâØfD6¼Ãœ·CÄ÷ÍDmßúdd“ò>GÅ4?’ñždR¥ œÙTCÈ+NU;üçï¥D&"Ÿ·‘k`ž9<Å´)ÉçãŠ×ØÊÞ̽#>€ç8eÚïýὤ°«Ê?8¦¯»ßfÞb’€ØzSAlbxÅÒ¨åÏ=wùÙáêrÍìsÝ3'fc€1 Ž›nèÙ‰ýÀb3÷E‘èLq^0Ó œÅòNS2ù1Ã5ÛÑ|T¬H ü·'ûJyàÄŽ¶È€×d.#Ñ‹@•±JŸž]èÍù™Ìâ…ÊúØÉU)’ ËmàXmæêoßä+,ÇÃ=ÿìQN0´íNÒIór»” ÿßÃw®¡I Ê8 +dOÜ/~’¶í¬–ŠŒ°FÜõ(œÀG|C†ˆöMÜáÆçÜýô²+s–»I¢ÃAO©›8–Ýú𱸛ÜbÞ½>îÐbȘºû4'¢ûv;{Áþã×i0å7Ø7¶âÞ;gßigt)ÝjVº !Ñ´fY ÏÌäŒÕþ_%[δ©E­X®qL²ÐßzÃèw¼>þ âK ˆª9{+äÜß Þ{?ƒHÁ¡¡\#Gv~Q®|¿mЦ9âØúÕ©+o\WžX+íØÒlMgCæ| €dÆPhœŠ(vø@’ëο‹q"É€eë¡ZÝT‘rø¥ÈÍÁ8ýf:‚ÈØx.-¿ Þ\ßš~¢šøÛjjCÞé‚ü¾O«aǹº}_N¿  €¼7l‚‰Vëz4­„ûûA1NÛCd­A ªpÕ³É&øbB™MŒ¯Š°ƒý8οÓJV‘4H4WÍ1—]¸Èç&Ñ âù‘ev`7{VFBç™á;—•L“¼5b±$ÚüþD)»ÀÚaÜKAÂX£,2LìKF²¾¦ÕéÔWÁ=¦ñõ˜Áz­g!ÌJ}[¦9Ñìa=›ëœº«`˜” tpÂU˜ )É(ùXÈ­ªEÝ=€-ÿqÒq(¡Hé5È™óR~&È™Ëî†J·xjƒá»ŒŸ,ìÃízVÎÍ ËûÔˆZûœ:t]¶û5“„Z²¯kë“{HL,}½áY"|q¶¨|jW—.Ôym’é G¼&葵¬åò»ˆ•*´ÑMíPÕXƒkÆ5Yl~¯À×aNŠ…ï‚ëMÄ`­½BŸù»¡´˜DiaFª€}åù+1ï]”|²ÒÆ®D¾‹ú² ñÇŒ¶ÈûÁð¢µËѽ²`®•\9âÊÓ’ç\ªfµ“]?‰‘ kÙ€EÂÅ¢`ߥ‚†eÏyÉkEqÎù©²ª_PpWØŸB[Én:ŽÐù‰ØÀzÐôû5m­2¥°T¶R·Y8œL*Vg;¦Š-eÈ%d“:ï|BÒ.aUÒÛÕÎjŸY[Ù‡þ9`ÊÞ1åT¹÷9Óúáöƒ1VÃ2„}þ›Ì¡§´+RÎ| Uxj£Ð)\F@ý£hÏ] >ÃÍ‘Î/T,P(z½þ'¡%½Ø$ݨ[ÑúÔ?Á>ÕŒÆã³‡Ò%n,âœË’T˜¹f< ÜVT"äËO…q”¼Îë•Ú­•qþ[Cb?¶aîÒ†ôß³|¦ÍV¾œ³x¡;Œëò÷ž9¯ëÑÿ!¶ˆzo{D€Ù甯ÿ ÷z6âÂU¥T¼ðu=àhµ×½“N1’Ù¸\Œ¹ËÆèü×ôÈ„¤»ýƒÁa²8F'¯ôбèÛ"b¼ùbTGœZ¦ìÏ£Ü(uK ïÙÐËN×îÎ7}"tÓ×ÔgžI¦ÌE.Ù{x÷ J9Scª¾Œä6]ôó5‹K=†Ñ§º-atñ£¡¨l{Ax† ¼yøœ‰ï.”üïQÌ0DÐ45ëGIÕI7#yî©ÛÜø˜ô…­Ãã˜[.«Û‹*ºRLr©ª §W󵿾Ööþ«‡%(#09™ßª„0˜ÎªcÏÔ¬½Sl±‘žj`áÉŒz¯ÄÚ¤ô¿æÑ~¨Rx\rLìfúÕÓxJwåR!†ùFî¼Õþá ¾äª³]Ú6è,}®jëÚ+aÚö³ˆõOîßkY<ÀÏ̇ò§#°Ñ347ΣF&¡lµœÀjÏ7Ø£`Å;L%)ÙgD}èÀàJS”¹ù¾ÑuqÍázŒÆ!…È?}Þ¾O¤=8]UèPlŽ4ù‰ª$㉉ϞhÅh€u½W›LÊhŒ fww—ÆSZ¡f¾„Rý'<‡ûT¤Kñ=}­MçWõu¥+êuÍEÚ뛩Ùº©UÑÊp‘îÕ)/‘28ãSW€öÈÀ]X^d4 üv0ò|tQ²Wz Gm mæŸõéá{êG'-4ìZÄÎâ%Þœ{=â°a³)knøæ›gÒKu¡pÛ¶ŒÕ<)ËxWä]‘3`zÕwŒb"Ûr¢š±÷ßt²àÎ`VS#ï¢ËØ•í…Ö ­º©Æl˜;#”ÌPsØeuw÷–®–Ô¸yÚäf¨°pCˆ!ÂÑBáEŒÒ:«˜³cnEµ/–´ò§_Ò¡Xïéñiˆ÷Á—]—æ~…fîô<±žŒ:.§˜Þ4IãUA+ƒ=[ðÀŸoŸJŒRIšˆP9^öp„³·IüB¢hèÛùž¦éï…ð$Ç•#,O`´YÁ òÎÎ` 3{Ç[¹ÅáˆzÈw=½—`zAH½™®Ÿoo¥pÁ?•Kuõëòy6*-¥Ý¸ƒ Z?Åä ïßvmÓp£t¨‘j±bçöÔX¶¹æ¹,Ö¸oj3fe€ÕR.DxÞ·N\Åt8 W®ûÅið>et ”¶”ɱ¤Ý'rò°7*PÓ°Ñ“cé<⑺ûKŒ—È>Âì¸î'ÎðXD`_ɩŠ–XŒ_>9RS[z†¨gj\n¿†ð#<éÍùz E€ìi‡cIˆÑ“¯ªGôޤwÿÌ*T‰@Œû{[ýžãÖCÁëh«SðÌšÉL‘'i©Ì:F‰æ9fZ9*¡ ‰é‹0jQÄ”YW‰®œïÁ$âú)ÆâMô—ÔüøÞÌo¼ÔÍ¡«â¢ÑÜÈjµÏr‹ß@!q¬Ã4饷j©ø°ÏÚWe&[Â×#N,¦`—ì”ÅC8Ñè¦ÎêZò‘Õ‹>ðÔY Ê–˜+PˆAæ ú¡k¤·g|’ë‡Ñm‘>È/O ½üÕ<l’F1gC ÚJhê¡Ìö‚½[¼îሓ°Íï>P®Ûà n!:Q—Å(ÓOzÅã'æ ÅÌ¡8ô¥ä õz޹D¸6©:"Œ¬9©ËSÒØÃ{ñZ~²Í¯Û»´#àx÷¯Öçqôj{ kдÊ*4ì¸+]VÜg|Kۆ𼱖ÄÍ…£,ߪØ8%6Ç8Ðú Ù³ÔØ|ÂóÇù*Ay±±&M"¿£¹Îë„Y¡u"ƒÆlÇÂËÈPÐ`Ýí@Yz¨+LTöÑë+Ù¨g#9V±MæwOemn˜8ŒB(rÊ´¶ï%‡¿lvúÖ3Iøå±¶?/P é›û7AœV³Ö&¹fä5ô‡ìäåUF-Z^hÕß]…Ë™Nn;{™Nmò"jo- Aqòý$^‚üå×€M÷¬ 3´Vdmµä^«µ‡ïU#ç¾9QOb²îm$×é†`Ñc¢ÏW„¿4—hY(Ø×šÃÅ7(æ,žÏ¶ÎO¦Ë£b ɱéSáÕ˜Q,—ÚtÐ;Š¿íÞGí-Vh—…âÝò^ag •*MÞ¯ä]%Šâ@¿ŒyoþèVàÞ.3™4¥UCu¤ÍãŒNî1¸é7žëÞç#u˜ O‹«ÓþUŽŸ Uöy5š{HVß'“ÜÂñðÞe‰k5’&2-_æeÀ‹nr³WTšíËQanÆŸZˆGïÝ·ÝúJœB&%Rí ú§l½¶\38±AWWc޵"p´ÐÃS†žzú:ÉIj±†²ôÌ41ÚꦦÂ@rŒ½óÉ@\šÎ5«çP½*E"(b^[Û„ÝaçC:M'Zä[ͤ°¢OÅ.µ4gµ–LÜòWÐ¥Æ+Š_דÁ¾;.|ºo­ÀýÍË¢l> ö©c­ø:Æ÷§÷ÀKNûúPY`ÓgĨ£j¬‚âVü½„pcÌ?3®US“d•ÑQ«"øµ{ß»^ì~µðoÚêû,Vú ³ùï1½Ø„R-µ›<¶¦ô±ÖóŸó Û²ÔÆÌß dCCÈŠŸé1Tá|XMA§iÙ!üp!íý kì]˜Ü‰=ÄÈ¡‘’n¢É—-)òZl„…ÁõÓFÚV`4›Šo ÏÐPóô±9{ž‚ÝSñŒW d®pª+u¡™­ÉÓ†›Òî“ÞHüu:˜SúÝÙò\@6Ð˰Œ#s†‰ïº”SÆñ×Ö?³_[Æ'v»!•ù‚# ØyNVØnøãf É{¬$ÿÀ‚º‘>ìzpôœú`@ öŠÚÑe™©—8GÔg MebsÈUp,üUJ\¤¥)&I`Wž©ùоÓDEÍœ"‚{Pó;¼ÐX|φê'“'tÂÛ'ã€,š`)~Òç@.c³Äpâ'¬Âsÿݨ  cö\²õ&/'u6Wµ^”rx”7ûœjƒ ©Ú£U¸dͪ¿ÑSI-D$®…!MBv˜I¦NÓÏh`#:û¾(Áuã$©1=<;o²•q’®`­ñ©óNy;"NKã7ÓùöÚ:P¯Ë©3RëW‹Ø„³ëQv(E½ü!­òsúÍ‹_Ÿ°yÊÁmÂAмÍêþ^³Z±ï8‹€lL4ÞâZšhÖ(À«¬_ž¯ƒqßè$þŒCqÌpÆ"à’ÝW'U 'íù=Zj€.[LG1;fÀ†ÝgÃè1npdζQ{CMºnz%ºÍÄŠ£_ðçNéLžüHI!°öûí!™jxïäR)Ú,\eT#L— _¤ä/Þ§cÕp¨9Jß9rÖk¼~ump 6ïyƒáªç“ç,‘_øD ¿·¯§^­CÊÐÚ¬¢Éoë,PžOsõ ¸š:Ï7|BȺÚóbת¶CÝ!ÖäïhÍÝÄÈÓû Ý í±,hû3ŠÌ§¶€£Øæ¸›ydÖÕ o:ñ§o¤†»še¸;ºve¾Í#>ʨy¼&4WTÌqTœ·×‰?ï ox¯Lá£ÁEž¡:ùZœ?ÕÛxä´fsp/h6ò"åI=ì°o6,Ho¥áLâ´Þ?翲õbŠ ¸z¬­56ºí؉n&,µÆºC¶=ñà[·]¶ëþB—'Äñ™ò‚m6CçÃÍ ß[B‡Ï÷e®z- ê“ãûœ&XŽ/ÔwÚÓÓ»ò& }c‘`"y™JpÜ¿Da"mù|‚í7v[ËŸNžHòÛ~ƒ.Üe ËÌÕ8“ö»\› vnž)’5æÈ]]¾MêëÝNòèÝ‘Ê1%‰Û°Õ³huAIwÉä¿åá¤Ï%ý,>)ÌVV¹WOÀŽýQ2²§ã ë\Ú¶nNWq%‡€ƒ}ޝ”Œ8¾í˜Šéa9ßÔ—Žã©VOát¢?x†öyúÏÏ^’9iÔ¼ aÑ$⟄y9ƒ›m64ÇMº!’#óȘ¹BïjRù!žÜ&ˆÚ°9ÁîNµ+ÓÐòL˜Åç%µŽ1„Ú#ñ2õйmÚÔŒ›8‹ :ÏÍ‘›øœrlƒfÆcéÁ|ÿÎÑØ"ŠZ¶Ó‡ú¥Í|çOìGÖ+ fÉ. Ôò¥ÎCõyÚÔüù?ÆK…³‚+‹Àj"Ñ%œ%À|â¢"Iäüœê<3¼o ŒÄ¦qÁm[àcD€ÍN²/Pi̸O¿ý8È76n|WgÅÒ•9¦û8†&ẫ9`µÃžI_èçÇ¡¡#&þÜœ¡dîܺájž ÙÖͳñ’ˆÁÀ£`½|¡âö ^ÚïèÒ»äý”(ãfúØfÖȈ¨%ÙŽ™lp._ËÏ ?¬ƒO‚”\ýf×åHZ^TÖ^Ñ5[ÑÚ‚€Bcñ7mTv¯ˆ;‹ ©o± » ¹ÃÁ ÍÀ»4¤1–€ŸÂh‡Á 룿i¡¡Üíb9wSõ” êÍ0cpÜŠ÷kZz3¡(u`̉´>wÀú¼‰1õѬ!D‹€úKaþ¤ Ûçë±ã‘ëÐ÷CSj[*5Hçí¥ëxÚ]ÛPYfR'&ìĵî<¶b‚¿ˆÑ¿™UtpÍI·?·%àç|#Û«G5ƒ+ŠÆñ³‘¦¢r‘ÎDGÙº`s«X‹W<ù’sO…Òq!ω؇•ÿº-Ë]½6ʾŒ¶µ“ä­~Èyáb›|޲c<;)‡ËÙ]“¡q{mî$ö4²uñÙ†úcš¹‘Yov'_ˆçÖä{‹éZ裤‰oaÔ¯Ö0Ç¿Zt,{ø{Å–jæžçSÈïK1ž…êÕa¸"geºi¢ÈNö‰»r²qý.AA"&ºðFzPºGäBÑÈŽUØ¥‘¹oc—åÀác.œ]ƒ£Z—îôP†«°6õÐvåtÁ„m(Ïó>LÔ<ô mƒcVÌmm¹ßר¼F¬KH_V©OÑx,ö¾Ññzraõtƒå¹=ÔíGdŠÙêòî·ö”¯zùDWQÖ-/Þ|iÚGs‚ªú³Bï±Tá‹! [ؿ҉RcÑ;’WÔ>²µxTÞJØò²Öé€0n´4Õ Ó10,$¸N´”ÁÉró=6V‰†€)f¤:cøIíá”ÍH0©*¸ŒÐ5ÏËV©žcÂÒÕ3(ðhoNò NÈÒ?ÑDú›;Éê(§L¼…Ïu%Y¸G¾ŽÌS*bø¼ôÀÓm¦Bn{·…Ó6¶o°L Q³R”Å2£kh½æ–„w4 ÍV ‘mÔS~BGs`¯ÚrCP¸`˜ÛÑŸ …ØÆ^RÖwd»y(Ôýƒ?(I žNê;¶©y1ðLyFhÀ‘¸eÉQ´ÑXÿg]Ë{“u[kÂë+,žîY¤Œ¹÷ðŸºü^¹ó.e̸R¬‚ë÷^´s_‡VYØõûú¦å_N!šafÐJ¦ngZOo(NWé½Yy±ÊS¯·ß—#F`ªròY\0„XÕ—iü½fYWÍ*±£í»ýv– ušˆw|Ÿ0aЗ»2p*¨~÷{ÄÃuþLÍ0ÂEp5Ã|òônŠ D"xP3&Pß}³®€å Õcó¨ÂÝ6a΃½Áˆa¢ÎÚ¸ Ñ,XWU)?‹—г"¸á @ ÍRC7š8J#ך&ÿœÄ–ʳaoÿJF¹ë4 >Ôk¬??oÝ·²1¿óèÓèÔ(0T‰|m—‘Pub+Œb\‹÷Ï ¶ªQ„þñ©²7Ì&¦0ÎYߤ ÷›júͳýÓÛ5V€–ó”–èÇ]8Œ×ôNeä’e"¤Ñw·LÑ*MJ!,SÏ÷%ý0_–×-b³;Øÿx“% endstream endobj 967 0 obj << /Type /ObjStm /N 100 /First 932 /Length 3352 /Filter /FlateDecode >> stream xÚÝ[[sÛ¶~ׯÀc;=6ˆ Îd:c;NêÄNÒ8—¦™>Pm³‘D…¤§¿þìâBusrfÎ4‰½»XÊJÇ$"iœ¡IšDDqà‚›‰ ,Â¥"Lâ:&L)5a©€1%<‚µf„K1H5'ɵ$éµ"éuBÒkM„b$…gB§02"ñ9ð’ø<•DªƘÈTÒ4!*Â})Q2]"P/æ8á$†LLÌ#Eb©p“8f8Ñ$J˜¤$‹#‰Ð˜p’ÄæŽ$ÚðaŠh†ä,!ÚÈbšh%ÑÑ:Æ #:5°#9—$•HÎcôpæFÏQ´@w¤¨¶€_ŒÇî3¤¤*¢<Ð iE‚3ÃÄhaî³g ȸL‘B2p°D’ƒ‹SÔI‚3#‰2ÀR…Á iÍ“àÊÈÈ…@(®P†ÀXCpc®Ð•€cä [–à>ðj"9Þ‹IRã@!ˆàôZ b‘ ¼Ä@Œ87ꂳÌb‡2€¤hØ—‚Kç*Ò£ ÌØæj£ P‰u#cÌxªL˜ÀsƒØø6…ðÆè "°E´Â?£7z!œ£Xa(ÑQŒ’„Oœ˜°˜¸0œ$a¬™bAŽd1K1ÔÌÄ¢'Å)ò‰2s—2 Ц)ê€håÌ-àLG2œÇ˜°Ÿ °‡=\²xðè¡×„>-ß”„>&?Õ‹aš¢œËc~ÌÄÏä×_?]7YSŒH“ß7?螺–æì.}"Ãò~7…²¯³qQ’á¢iÊÙn¢¸C´˜Ä+V£|÷ví¶—ÓaIN÷ZŠË¢nö"àQèÞËb¶[+Î:Í4›ï¦âfg嬩ÊÉn"ü7UžïOä¢ÿ´*Æ»7»ÀŸ-ꦜ’÷Åø6ß 0î"=ÏFyµ¾}t—Í›¼:v̯òÙâ?äMYN†YE²Ù˜ ï5¬zD99êØùùÍ/ÌÝmÛùRضmÞ¥V›m;å2ÎtÍæó|6.î³ã»ùëýÓI6ÎÉ%à{VçääB7ÍgÍVâS CTŒ>Íʯ“‚ô5¹)+r1•Õ¼¬²&'–7Í׬Ê7Ûœ½_Vã¼ÊÇ‹¨òQ¹§"{ia먀Ñ_x?†RÊ¡ãGžè–f×åù áýäÆPùÍõ8:ë×8Ç é$œ{ø\AÇ€ú…{ýhdÁs¿6ûð>Üà »ÔG {¼^^G”áÇÐ6œãåï'޶cŸN[þžêˆ#^F¦á¥Ì¨à0ÌO«Z¦ÓŽÇlä)°‰‚gÖ_ƒØý‹/°'ɱ†Ñ8ÁüØ)luýe ÎMxüe Ì{¼p‚µ‡d ;Épû< ^&]\:yù›`‚ÁÃÎCu21ß;xÖ¦‰ñпÿ§Xõå†A„+U<(§Q‹„¨-#цÿÜ—_¥T‹“:¨Õ-ˆ@Ä÷ÖëÕÄIáõƽMöÄÔ'Îñ.ŸTí>¬¡˜8cHÈ´“9šu3ǡݫ™c½dçÚÍýó–³'xvóZxŽŠG«Ûû~½bãaã’mwbjºâЂæ= ÑXòýÙ¶H„nùÈD¶æúâÊ0qÒ²½×G³ëj1<ü…ºâ'>Œ½qz¬žÕ-Fn_Kçæ©+pþ~"² ¹/Êáèýì}í÷ˆ`Ñö}ˆ/Ü蟀Îè»ôOpù(n®cùž(²t©¡ÀT¢hÊI ã{£Øî¢hÊ~JÒ97…Ñ‘¾5{H½¦ÍŠÓÖ‘­¢Aæ†Æáî²Ç6ÓW`êÏоL·AÆv´á¯A'±;7|•ZËt¾ã ?Óc‘}ü$ÁWwéÝ;JxèiÐbxø õL9[kÚL ºwáªÏjÕV€•6 ¯öÔpta¦ˆ¸\ Û§µ6*Ô=l£úN» {ï; $ú纯{—æs¹m‡Úư}3PpÔ À¨fÓT×´$4M&L“¡eè€Ð²SzFÓsú„>¥¿Ñ úŒ>§—ôо /é+úš^Ó7ô-}GßÓ?èšÑ¬nòª¨?Ѭ¡C:ÌFŸêIVßÁ¬¢Ã*åffð`¦Ÿò¦½ sû`DG夜Áïé4£c:.'`’S£)Í?/² ÍïG“lJoèMñ%§7墢·ô¶Ê3ЂÞÑ»oó»|F ú7ýD't’×5Ò³œÎÓa^ÕÅ팖´„s:Ϫ|fT13«È4-Çt>YÔô3ý¼Èkü&e“‡;1Dff‰*ZÓ:ŸÖ†:ÿjÔÅ=µÞhhsWå9m¾–tA³1è1*«œ~A ÑoôúO^•]D©èD=ûðüüÒ!ê:Ûš,,löoBøIÔÎCL™e‹)Î6aŠ… R‚oÕP¿÷@jh `Aà£ïÄ<ˆ5Fº rÙþ Ú0m N‘õxðCâñìêÃÛn<¶d8¼sqó®Þ”âÁºñ`Ýxˆ ñÐ*‡©€m8ÎÁùèztúûýݽÉÏ2ôAð™³ÌXØkôÀÐtp>~÷îÏ«sš×åôE™^]åãbCtb Ù"™íLà8 „î)ŠËet¢tc¶„‡hÌš-Aù kïj%í–еØîY>÷¯™ý³»£¾oµ<¨µx}öìÙÅI0^z)>ôŠÒüí=e€­»½”Þ†‚#¦Zð:Uó)Dþ%Dû­«‹èüµ¦CÔt\?~ùâÙŠÑ[ªâžk{Zœt-V¬S•â=ª’4 èÞGßA‘Mvu6»æcÛÝG,;—“ÿY"– ì&¶%E|P ñìäÏ÷¿¿ìÁÇæ¤`ðN }wdÿ~ßÅHœv0‚Ëà ClÌ ÄV‹¹VψŠWï»]è°¯ø¹²gO1{†íÃýËW(ž…k=B=MÅùlTŽ‹Ù-ø«¸¹ÉA¯Q^“Ü@vïÅÄ­†AkëàîàeŽð굺õ¡Á®uŸËçkÚ`¼‡VZ šü1Éd@jàj³Í$ŒG±w“I'Ÿrm¢@&\ Hʺ¯Ë·àúª0$Ë.Þ¶@ˆ‘¿Û^§Œ|6Qn:©¼Úø+^»¶áÅÖ¨¿Ö3À¿6f‰7õ§Yã“õÏ0: l¿Ä„¢OŠªn0Y ¸èe,Þãæ®¶_ ê­Ûä¯~а&?Y•/­|!BùÉáò7~°¦HºªH:·KMœ×|¶Ùoj¬ÜÆ7ùUå[ó’è(× SúC”ÛøR¸¦œXUŽwtcn’ýÝ6¾ ­é¦¶ê&u¨ÿ!ºm{CXS/9@½è‡¨·«{]Sq-/dº9/ôÑq[³¹ª_̶»0 ](~ úvô:k*®%ˆÃ,ä^:¾ÊnóÚ›ríÒÖ6Gæ;˜†þy1†sßPûÑ)~ïÑŽ‰]s¦ìh_ÿzî™i7¦& DD©Ùwqb™$ީެa‘*™Í·­(DEVså4VŽ©âÖMJp;Ú3óB”¢œXÛQ[æøÕ]3~»bî˜q+$¶eN4ëÆ8q÷õa–¨Žm™$‘–0·vnJ„[ÛO·· a…$öpÙF,:*Æ!5cšÒ¡'r–.Ò¹i'j’2ð›ÐÆÌd§™R´Š¹€µö®½\4è~kW3àµÆ,öÓfé•óÄEc^ „;ÉNì·ãͼUŸwßû O—$> stream xÚ…YM$· ½Ï¯¨ãv€mK¤DQ€aÀIS`InaôŽÛN=˜éM6ÿ>¤ªºURqÔ§­Å'>~Hofs†ÉM™ó”Hþ¡ÉGq`ù×Mè”SšP¾s Sˆ²/ù)¢ì#žÈÉ> qxÈäFöEže_ŒSö²¯`ʾ'ïdsr²3àäÁËVùÁƒ“1M8c˜|‚Š^£’Í’,{ NžXÀ&ŸB’S™Y°|ô‚\õn‚r¨Kx5 %€à²ó Og–”å#N$l–P ÊÉ,©W–äIfX³“‚ì‘” _–ü@Â, Bçá%Cèä'&è³ì¡8!H"˜`B*³|¨IRŠÄ=â„1Èž(‰'/{„›$CöAN9>pd…gäŒ r–ÀYJ¼ÐeÈò!ñ²° 2à$É£$Uöí˜$Q!&~`ñ ¤&a’œÃ’¨ YXò“$QAÛBB™¢“À“$*z99I¢¤J,$ä¥MÈ=$qZ Å—MQâð.ÉZ’ìÈ—tSFmytú…¡ú%½]Y‹%‰M¾Hú-+žd> èƒ|ÉÉŠ‡ÄŠUM…¥3Kk9VÊQ#ÐZ"•5IŒ£_’FÙ¨_Ú(^Ï夦g”.M,d3‘~eVYúÔùâRNGPìcY-¼“.d *[ÖYW°’ŽÐÃ÷ß?|÷ÏÓå|œt›þþðÝòéçϿގϗ2óÏoÇÿ”.?ýtü&69@úá‡Ëݰ˜‡XÔ`%Y¹aÅ!®±–(;¬P±`ˆå,²°ü +åVJ X‰+ ±Bƒå,¬X±pˆå×XK”T,7Â"n°‚Eù†ECŽÔp\¢ì°*Gr¤†ãe‡U9Òcl8’Å1VŽ1 ±bƒeqŒT±Â ÖXÑâëlÇál‡f¶£5Û±ÎvÎvhf;Z³êl‡ál‡f¶ƒ5Û¡ÎvÎvhf;X³êlãp¶±™í`Í6ÖÙÆaßcÓ÷Ášm¬}þǦïÑšm¬}ôýâmu:ÔN‡¾Óa ,!ÿåôö~©ýõ ?yçß?½|×Ïò"uÇÔ!€`3 VÛCm{hÛ^BZEÉÍ]èõ9^}åP‚¾eçshßÎÇí”93ÎªŠ¯ỉpëˆUvÞu< ½›ðÖ ø:.ÛX‹·‰«]ïh˜…¦ë}n sNüæ5ñØY‡ÃáàHn…‚YW‡ÃµÃqóž±²ÑwœoÃÁ9 ½›gÀy ‹*Vb­çჸ°bùV#ñØ’x\%w¯Ç¢Ëx¸J<î$^[+¶DWQǨëëÞ4ýµñæV»…9·ÚRŠk«Qäm6¸Ó~Ý‘öcKûqÕ~œhˆ,gaÅŠõÁÌÞ–Úãªö¸S{ýu Í]oâ%“×8—¡ÍM&SwfU…Lݨ@ÓFd5!Õá 0òM,ÈT‡ƒºá ùh5!Õqˆ<ônƬqˆubb5ÃaÆëpDb¹‹,¬Úõ!ÛX‹·Õç¡öy a­š>§F?ÜÂ,ÍuMßµ¹bd‡€£#q}_ÉtXu8B÷"\½,«¹°¶9&Û{9Ûz°¶9Û›7 ´7ÜUˆÎ© ~¤bë4  ÍSÖ”b à!V3hÍÔÙ€hcÍÞ`MÔiÝp©y+n—ç’I ¦ [=Èý™uj|75Wy3³÷VÛù:5ì½[öÖëPÕ!wê=øA$•G§Ù5ïÔU.ɺ6'몎m ÇU6r/»CšKÂ[t«ä^ºæ1´ WȼõÆÜ)‹ÒºÒuë×ï–W›nªB1uB±?¤¹$,¡˜ªPLPì±Ö—D²„bªB1uB±Ãj„b²„bªB1uB±Ç¢˘þT…bê„bµž†dÉÆTecêdc;üÉúë_ª 0u °Þ$Ë(âº?n‘ÍýÑéÌ›:úéðt|ŸþõéÏ/Ÿÿq9¼]vS9eútx}=>ÿzú¶?ìÜéAl–ÿ¨Ë¸,½¼<.§ÇÃùü¿ýãÛñp9þºÿï7Ù¾?=¿_ÏÇýûññrzyÞMa¾!¦O_ï§Çý—Óåéðú¾²ÏÍ"öãûeÿúvõµ?Îögawz:]:xýÜs~ü÷áõr|ûÃÞë‰ó·5ØMà¹[DYœEÓj1ÈbjÝ1B»$€´‰zÂjçG¡j~~êv9ßl×¢¬ñ5З§§—gÉÇËëñír:®òi òøíðôz>ûUÍÆ,ûŒè5ªfï&ü« ü,a§ÕªÂÏZx½ªÙî„’nÂ~5êjèWIWcvM³{xR(jÀ™NêW îW ܯ–îqýªÒ™µ€xÚµ»? ü°ããùðþ.eÿíô»”|¾Ï¦OòÓ×·kÅÁ5‹31ðý¢“UÜlÕ½¸Ù«I˜••AaW㹡SšEÄþ0Í"†~U³ˆ±_Õ¦@êWµ¾˜úUÖUîI4Ñ4»?\ÓÐá+èÉ(è¹(è©(è™(‘Y¼š!îÙûqÀJ¸Ϻ¸ôðo_ÏçýãËóåíå¼¾Ú—þ8¾Ï¿<Ÿ¿.ç¿óûå|z¿œž—æû,̓>Y‰ƒÿˆÄ·qذYm€ýgI72nÎKÐÀ³e‘Ä4-’ýp½ä[KR [ :Ì0YsÚD¹ñºC,+ì6H”ôÊÈÆ¦I)&Ó$¹M“„Gh}âܘ]Þn#z¢3d”!Åëó×§/òð|.·z¶ Â!YõÓG{²eÑÞÁ·[œG‹ÝjCPdoÕ–…Ô‚–%©%XVK´,Y-dpk£Üx‰i.½•KÐÊ UÐÊ UP44Ñ´2Á5€Ò‚ÝÆgLJ‹V±´V`ÕJKV©´R`UJ V¡´N0®Ó¦LwªäŠTMF|N“S°,¨–hY‚ZȲDµE/#9h•(7^Cb¥¶‘Ù:PÃçlY4üì,‹†Ÿ½e!µ•/ò2ο"DlÛp”›Z'–{;ZåœÉ²ÎɲÎlY ç/ ’‚éÕGÜæ87nw¸‘â’u¢V4$Ë¢ lY´¢Á˜ÏP*JÞ´hE“S£á6¤æ~Hö™Zœ¦I«c]«¡<¥dÝ«aþ‰§p„#vs¤·;ìŠd3cÑV¡hY´ØD–E‹Mɲh±‰-‹›ò˜YØm½†Ä¢vJŠF(±tJ²â%ƒ‰l/P›&TS6MyweܼmÅí=ÄVWÆ"“Õ•±¨Ãdue,ò0Y]‹>LÖsµaSä;ôânëv‡žJĔ̩FLɬ‘Ö!šuÐ2³,šG2ó¨i$s·ÛºÝá¦5 ³Z2K 0†±H `TdGoYÔ'†1±îƒ{ïÌ¿;E3FâÆ/o0ÿîcL)Ì¿ûD¶,*¨*Ãü»† 6[ñºCLõ8™™TANVöËß.Ð2hYÈ´hYŒêé†!ŒiñnãTXýBâN‹ endstream endobj 1162 0 obj << /Author(Marcello Semboli, Alberto Griggio, and Carsten Grohmann)/Title(wxGlade manual)/Subject()/Creator(DBLaTeX-0.3.4-3)/Producer(pdfTeX-1.40.13)/Keywords() /CreationDate (D:20130708210245+02'00') /ModDate (D:20130708210245+02'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012/Debian) kpathsea version 6.1.0) >> endobj 1099 0 obj << /Type /ObjStm /N 63 /First 636 /Length 2767 /Filter /FlateDecode >> stream xÚµZKo#¹¾ûWðX¹ù(>€$sËf7È&§ÅÀåOceÉZãM~}Xl•Ì&«é™Ã^ º¬ú¾â[-»àE'¤ì:¡º€ )Œ2ØPÂê$ÑÂ(î¬Â©\RZ!OZ'¤‹Þ±ÿ ²»‰­ ””h'cÿZ¡”BvØRB9“´Z¨`-¶ŒÐÒ%-­CÒZ¡—Ò í°å…é:cÄî´S0Zb*‚0)S¥„±˜®TZ7ÙIv &ƒ-+ÀèäáØ©/Àˆ1T<ò¤;aU—ZRX“°E7kM’ia½ÅhÚ×…Ôá&äÚ )ƒß9(µ¾S!ƈ\{-Ñ#våÁc.1Iï-æg”ÐÃhŒD6Œ$öl@›b+‚3É׉à'/Bp2Æ@²»Îc‡óíd@Î!‚ít*DÏnB…´t`0¤ÂÛdìœOÑ·ó3Æ0q$aXH5î\Œ– Ê€Ñl—øÄ¿©Ý©›nnÚ<÷'ñëŸv§q~~èëÔÚ¬„Žˆ:ñ/1W*,£°¨pŒÂ¡Â3 ŠÀ(BTDn¢âÓÍíÃó0rù•>Ÿnîî–鵌}zS‹Š.j"AŒ}ë£PœF£Ær¤4¸ª”dåô,¬Gð\<,Hœ&V$N\NãQ#9M@b4H…‡6,XUNmXÈ¢çXD½cȃçx@ƒ%7ªãj§AÍú(ÔHN£Q£š Âªvj¡2iL­¹x€Ãi,j€Óà¸Ô–Óà¸ÔŽÓà¸Ô¾kʲòjCÇ#Ò¨¸:"Šc‰Pȃâx@”mBR«Ê§  TÈŸªç ¤i:N“Y·a˜Àú ¡ ›˜üªvj‚T%#™pX%£VÉhFU2†Q`•˜R•L«JPV Þ©¤*1{(¤*1{¨MUÍ(á†Q 7Œ¹6 ¢DèÓd­PrSÞQ`Þ¶c˜·•Œó¶ŠQ`p«€R~¥O KÃÁryãpp\ÞXSÇå5uuÞ>qã £@n\k«Mù•>-@>Ñê, iuŽQ ­®‹!åí;N+³‡iÅ­£ž/÷ÚäÔ¦Õ&H.Âeöá0meÌ10L[s ÓVÆô•…Öd𲬼Þ†ƒ)8& "öbì9Àˆ×sx®çà"ÚæIoJ°tjCB¢˜“^HóÆsPqÞÐIï¹ßŸ×Ÿ‡]¿>õÛq8ìWñò§2ݰ‡7¥3¹2ýÉtº‰-fʸUèæZš[“xÜŒçÓÃæ˜G…Ì`<v…Údê¯Cÿš#½”ïp_Îãúe3~Idì1•7;#/ _ûãëqûuÿûp‡ýÓút8·Ñø¡?ÅŽ›è²ÍÈÔ®º°Ìñ}Ÿa/›§×E³oàša}.‰6ÐÍlâ¨)s‰FÉÌ+ŽsP z5ZH+N cì$‰³hž$q`ÌòŠcì,¯8h¶‡$ÁkS|Z°ºñi©Hø<-±X9  PbsI$Ǫ™W$Çêž5w™•¦Càiø_¼¿œqÝR~ LƒîPc;?d3,M'Â7פ «I“J£¦Ú9Éjpÿæ|Ò›H}K®³¬ÝZÐÐCZ6$«Á™îY N÷PiôeÀjɪp$Öϸužµ_ ZàÀ¤§ÜB•f³aUiJ«JSÔ2*; ¬*MË®ð’kíטj$Mͪ™¶i,¯ŠO ÀëÐü8^‡©€o‚´%È‹c e2ÁbAàãbµ˜É™tX.»@®«ÌM::ÍëžC'eÌx¾4 ž_¼¨HÏãTi…çqª´Îó8ñò$=¯QÒ›wpªçø.L¬™çÇ^|¤çÇ_ížUa¶†! xâ0Vý‚Ïd[;¾‡‡ð´ãèžu\­JÅ–’6"½¬ÆÝ¨á[¼ƒÖ­–|+ÄçÓÛËHܳ7Ó]jñ:<>õãiý0ŒÏ›—û‡ó8Æ.ßž‚èÚwµ« ìÜ`û¥ßþöpø=3‘¦49Ì|ý†u58æõG%¾fGË,%ãݰŸÍí‚ìª ¢\‹ÆÃS¼S0kQr<ö}9‹®^±ú9¡Ë0É/ts%àïÃcìBv—»¶ì.÷ëØÔPÔÐÔ¨³‡í¿Œ›ã#ÆÛÎùدõì‡hŠsylŠ K G O Ê¥¾¬¿õ]ü¼%g‡<Šæ ƒ' ž0\žcƒ2ò­ßdõ9„œmÑ׈„ÆOh1(«Ðú°DNe.Ù‹;… )¤@‘(­Ðúæ@ã ±KDyù*}qyi(jhjjÀ÷|»5û$ãÏR_Žžv¥¤œäw}.1ÿY”J‚# Ž$8—…<}Úyi¸÷¯,–¸"’p(¡ˆ[EɨÖï ßòJQQFE +ÊL…ï|§\x÷ àšj¨  &¶5%¨¿óA¢¼\ƒ>Mø4áÓļ¡ÄÌ7׿i¡øFý‹¶4Ä—!¾ Ô`C€o-ÚïMAC,±T> ò¥S?mWSð»Øø#Ø¢ˆ"hRôN·ûSt‘—G’þû¿/½¸ýÛfÄøÍí?ã„=¥/’“ÑíÏç“O"7‰¦#‰¼<8L.ÿˆ×ƒÛÿœz2OÂ7ýîôáÃíOççÓ¯]lür{¼»ó©ññîîSLáöç—~ÿ—”©”×ÿJ´ endstream endobj 1163 0 obj << /Type /XRef /Index [0 1164] /Size 1164 /W [1 3 1] /Root 1161 0 R /Info 1162 0 R /ID [<9E57268C01CD11D47617C9770BF863FD> <9E57268C01CD11D47617C9770BF863FD>] /Length 2689 /Filter /FlateDecode >> stream xÚ˜Kl]W†Ï:÷\ûÄŽ¿bÇŽãØN?c_;~¿â8Ç>±‡ãø‘‡ T¤R-h3bÖBQE  Ej¨Äk° ÚB»eRi#Ê  Q  *T©œoM>­uï¹çž½þ­½ï¢(ú<Ž¢8’¨æ³ˆH@"QtLÓ8Ž v\#-]i()8*@%8 ª@58j@-¨õ   œÍ œ­àh§A;èà è½ œE‰äŒ®è,èb KàJž† 0 ®––Àu° ÖÁMp ÜwÀ]°™Wð°ô!P£` LipÜÛ`<Èá;ÀàÎq?çÁ %0 FÀ0 ÆÀ8`E1+ЧÀ4˜³`̃‹`\‹à2 .1ÕˆUxªS˜jÄ+@-p¬êS—XŸ~Pœ˜ÒÅÝÿ­¬±Àû@ý(ÎÝsT‚cà,¸ ¶—˜zÐ úA Œ€Q0fÁ¸.Ëà*Xkà&àöfl‚-°`<ÎáPÔè›àØÛ`ì‚ûàx=ðÜ”¨âE-Ä>÷«GA5¨u 4ƒ“ tŠãÎ0.,¸s ‰C E@Ã6°Ž@Ã6а† 4l a hØ@Ã6h›HTõ‚~ý$z÷Ïšâqÿ [Ê«LY[ÚxúÓó`,‚{àà† a˜É4b2&C`2&C`2&C`2&C`2&C`2z?tƒF‰ZþªÏܘa‡F<.€Ç¬£tºÛOÌ•Röt¨ÃèS1xƒ'п6 =µ}]¿v´s íJÌ¡ë€f *ãˆD]:Éú·4¢‰Ã˜DÝßÔ”>´s íhç@;Ú9ÐÎv4l˜‘èg­úYzúm´nÀÊ!“èWoê»k`ƒh]¶$úM‹¾Ñx<àñ€Çx<쌸[Ë¡€@Š  ”ƒ U Ô€ZPPæ°  œÍ …š.‚K¤'A+8ÚÀiо‡(}xœ]"ñ.¡ä3콿hÚÃMW‰Îƒq0 џ껃`Œ€[`LHôÑ€^‚‘gÀ,˜óà"XúÌ‹à2¸®‚k` \Ë`dàÐGcÐÞwÀ#OŸçï먾ºom5ÿ}–¥ß¦M¬;ØžDŸNê'öªzRªU=ªzTõ¨êQÕ£ªGUªU=ªzTõ¨êQÕÓoi=Òz¤õ¨êQÕ£ªGUªU} @K–-=Zz´ôhéQУ ïç@7èlÑAý@Ad~Hdï3][´I¿¢)2z†‚g?÷ìçͽ<6u–-=Zz´ôÈè‘Ñ#£§°=2zdôÈè‘Ñ#£GFŒ=2zÝ/±¿ p“GU¿Zú ô›"õƒú¸÷xcM¤å¹¦;"Kok´¶EŸhº+²h"‘Ýßåxq]ǵ º/rY]âÙýR‘ÂßGòK¾öm½„Í0-ö­´ òÅWõ 6È4¿úõ‹ùÅßÿP_c/K«D¾ë4e“KkE>zCSf{z4‚&p4‹üëª^Âî—Ö‹<ýŸ¦- Câîgšž­"Ïú4=ÅÊ×%îÜÓ´Sâ/} [eÚ.ñY«éк%ÞÿF$ñ 9þ0­ïr˜H{óÖÿ‘¦}` Né0àø‘²õ¦£ÿà§ù ž¼œããD?¶Æ%þõ/5S`pVI9«¤ó@÷”À©%½8µ¤×G—ô:X+ 7À*X“øé#)T¼–£ö‰~åpS •ïjz Ü•ÂÆ4å°“nH¡zWSNAé––'ò¼±˜ãŸèœ‚Ò])ÜzYSŽGéCêœßùÕOt‹Vá÷¥ð?é%˜ÆÄ ð‹)Jáíõü¦{?’dµ"žÿ^?‹ú¦\ ÿèÑ4 gÙÐ`3S°áˆh8L˜ZP'IË'ùM{_Óp¢0’´/hŠ¥ ¦1É´‚S€ƒˆÁ>¦p¾2œ¯ Þ0² 1œUL7ÀC3˜Iò½”h J2[§)1xÃ` ƒÜfB’…껜s šiI¿¥¯aƒ êNAõ Â= ›AnƒÜÚGfE’¥û¡¾ÁkF¯Cssp–2œŸÍ.àTeô$͹ÓHòå·¸C(Gû9‘äN‡¾†nŽwßz8¤p¨àÀQ{ǡܡ £¦®I’í÷ô4±£ìŽŠ;êì(k“äÁ5½„²;Ší¨³£ÄŽó½£Õ•tý’¼¢£ª£°ŽB¸’$/¼®oÐƒŽ†uHáè2GµwÐ%vô›£ßÅvô›£âŽ~s”ÝqsÔÞÑyçè<‡nn=øåàr)’½Ü©~ )ÜMR½¢¸Û¤z{äq¤ú•å6Iõ1Ìm‘ê£!žÛ!ÕÇEFwŸT—€ î!©. iÝ©.U\<&ÕåçÛv¡”7ÉK—"^›&“NñÛ¾”NAéQ9HIÇ‰Ž€ Ò1¢Jp”t”¨ T“^ :jHGˆjAé0Q=h å \:I‡ˆšÀ ÒA¢fÐBzžè$h% bü—ÚHû‰NƒvÒ>¢ÐIÚKtœ%å4Wâ/Ò9Òn"Eé9"ýD©^§· =K¤Ï2Hª7Õ/‘vé*GHõ ´$£¤íDZ¿qR}\-ö$i‘*3Mªk›³¤­Ds`žT q,rò-]‹¤ZµËà é "þÅ)]#ÕógHé:i#ù”VHU ¨åˆVZ^Å[jù:¢[@-¯Jßjù¢»@-¯¶à¬RRËWmµ¼zh¨å=jy5Ü# –¯ Újyu'–·‘”~¬–OI±¼UËãg«g©åˈ°¼UËk¤—¨å"njÕòú1žÀªåõ?2תåõ;X›UËGDÂR«OEÕ,•´%¶”ݲ‹ì@<«?eX¯Ei‹úV7a=ñ`Kq,²øÊêYÃYLh©¤ÅÇÚ ÿ‚aoKÙ-–·úËf `yKãX=Oby»h5‹å--iq»Õß°ÝÒâ[F“ä•M­Á¸$ßû­FùŽø‹gMJòΞFSR,ÿ¯FÓRœlÒhFŠ[O5š•âÿ£Ñœþ¡FóRüüUð½ÅfVÄ8ÌnJÙâWUø% Î^jê ¨ŸWZy¨‹o5ð Þ½ Ô¶÷€:v¨YwúôP‹>êÎ} ÆÌÕO²Ü“ëcSpecifying the path of bitmaps

Specifying the path of bitmaps

In wxGlade some widgets need to specify a bitmap path. You can use any graphic format supported by wxWidgets.

The bitmap can be specified in several ways:

Usually you can type an absolute path in a text box or browse for a bitmap with a file dialog. This will produce a wxBitmap object with the typed string as bitmap path (e.g. wxBitmap("/usr/share/icons/application.png", wxBITMAP_TYPE_ANY))

You can enter a variable name using the var: tag in the text box. This will produce a wxBitmap object with the variable name as bitmap path (e.g. var:my_bitmap_path produces wxBitmap(my_bitmap_path, wxBITMAP_TYPE_ANY)). In Perl code generation a $ sign is added if you omit it.

You can enter a code chunk returning a wxBitmap, by using the code: tag. This inserts verbatim the code you enter in brackets and nothing more (e.g.: if wxSomeWidget needs a wxBitmap as an argument, the string code:if (x == 0) get_bitmap1() else get_bitmap2(); produces wxSomeWidget((if (x == 0) get_bitmap1() else get_bitmap2();), option1, option2)).

wxGlade never declares or assigns variable or function names, so after code generation, you have to provide extra code to declare your variables or functions.

If you use var: or code: tags the preview window shows an empty bitmap of fixed size.

wxglade-0.6.8.orig/docs/html/ch02s07.html0000644000175000017500000000665412167336636020215 0ustar georgeskgeorgeskHandling XRC files

Handling XRC files

wxGlade is able to save projects as XRC files and to convert XRC files into wxGlade projects.

One way for converting XRC files is the usage of the Python script xrc2wxg.py at command line. The script is part of wxGlade.

Example 2.6. Converting a XRC file into a wxGlade project

# ./xrc2wxg.py FontColour.xrc

# ls -l FontColour.*
-rw-r--r-- 1 carsten carsten 5554 Dez  4 20:36 FontColour.wxg
-rw-r--r-- 1 carsten carsten 4992 Dez  4 20:13 FontColour.xrc

The File menu provides a menu item Import from XRC... to import and open a XRC file directly.

The following example shows how to load and show the frame Main from XRC file test.xrc.

Example 2.7. wxPython code to load and show a XRC resource

#!/usr/bin/env python

import wx
from wx import xrc

GUI_FILENAME = "test.xrc"
GUI_MAINFRAME_NAME = "Main"

class MyApp(wx.App):
    def OnInit(self):
        self.res = xrc.XmlResource(GUI_FILENAME)
        self.frame = self.res.LoadFrame(None, GUI_MAINFRAME_NAME)
        self.frame.Show()
        return True

if __name__ == '__main__':
    app = MyApp()
    app.MainLoop()

wxglade-0.6.8.orig/docs/html/ch02s04.html0000644000175000017500000000475212167336636020207 0ustar georgeskgeorgeskLanguage specific peculiarities

Language specific peculiarities

Python

It's not recommended to use nested classed and functions in combination with disabled feature Overwrite existing sources. Use derived classes to implement your functionality. See the section called “Best Practice” also.

Lisp

The Lisp code generated by wxGlade may or may not working with a current Lisp dialect.

Help to improve the Lisp support is really welcome.

wxglade-0.6.8.orig/docs/html/ch03s07.html0000644000175000017500000001001412167336636020177 0ustar georgeskgeorgeskShortcuts

Shortcuts

Ctrl-G

Generate code from the current GUI design

Ctrl-I

Import GUI design out of a XRC file

Ctrl-N

Start a new GUI design

Ctrl-O

Read a GUI design from a .wxg file

Ctrl-S

Save the current GUI design to a .wxg file

Shift-Ctrl-S

Save the current GUI design to another .wxg file

Ctrl-P

Open a preview window for the current top-level widget

Ctrl-Q

Exit wxGlade

Ctrl-C

Copy the selected item, element, text, ...

Ctrl-V

Insert clipboard content

Ctrl-X

Cut the selected item, element, text, ...

F1

Show the wxGlade user manual (this documentation)

F2

Show the Tree window

F3

Show the Properties window

F4

Show all application windows

F5

Refresh the screen

wxglade-0.6.8.orig/docs/html/properties_window_tab_4.png0000644000175000017500000003575612166606326023603 0ustar georgeskgeorgesk‰PNG  IHDRzïZ `sBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´ tEXtTitelProperties - ˆKË IDATxœíÝy\åðÏìr*·ŠÞ¦fe‚Š¥Xá‘xi©å™ ý²PKQK1-;=+¯Ô<ñÖì’¼¯DSÑ4oEAäe÷÷Çʺ {ËŸ÷ëEÉÏóö³Ã³ÃŒ„GêŒQˆˆ„qý×ï$°Ô!ï7pVÙVDDD ¨®ÿú$å‡üí”´²®‰ˆˆ,èöŸõà¦úŒò²3˲""*%ƒ>§”ƒ^™‡´;|ªäú?÷ϼ÷TP¡f› Ø88™ÝN>ÅÃt<¸°©·Î£rõ†E^Ÿˆ*KgEyÏkÔ§ z}ï$þ"ý;@DDD¡e ‰ˆˆÀ^­6sÒ“P³uwØcCÀÎÑ U›½„;o‡*¯n±Ú ¢òÏÒYQÞ³Çõi‚’¬X¥Ý¦Ø9:—¨9ÛJ.ê†J£V"*,å={¬PŸ&è%I*QGúh·)I2X¢I’•J­DT>X:+Ê{öX£>£gôûüüáï¯þ÷¾}f ÝLŸ¾êAŸ}h7­³VórÈ ±}x•BÓº/MÔ»¬$“?±gô#^´8\Æ•PA<6–c,+ŠÚ$™ÞöôeNA3¨´²ÇX}úrÐÐU·tæ-õ¼fž™Ìä»êðÈ×ÊèóêóþJÔpRá³=wK¼IÖô´ý-Äæ<þpå¥ÇÐÆá"<ä ¸É3‘¬,Þ‡7¥©¦›=^{¶ ž­‚A‹þ)4¿à6YRi´]Ô6=äéf›—fÃÓv7°4¼·Þ~V¾û~=›ˆßÎ&".9»xÅWTz²¢¸í@’loÈ¢ÓWýñÝç!IÐ]ÏŒì)nëëù}¢&· ¯¢ó= ®½(õi½eÞ©üüöÁß?ûöíƒBê¦Õ¼†F¢ª*náþ³ ‚ó$In²Vyî*Ü‘®ÀšßþAÛæuàÿL5¬ýýÜTxbÿÇmó÷\Ç›íj¢š‹:Ì<™µöDPkOÔpµÇ½”l9MÇïAùèâÀ£u?Ùzoµ«Ú¸“”ŸÜÅöS ëÐݧBÚTGmw{ħæ`ã±{ˆ:¯y³9 §í-Ë—f×ZÞƒgo$ ’$™ìã™ÚNýšU¯[¹„Ó7Ò°îÈ=ý/Åè>, ʶx¥¹^{ÖÏz9!;W‰“ÿÝGC»»¸’[S³ú¶ÉÔ~šÔ½ºµ¬Šù{®cÓñx@ß¶Õ1¶S]ì8•€@ïjÛ6啿xãŨ[ÅY9yXö×lû;Áh½úŽY‡‚ýzê—¤|üœ‡< nò ÍÄõćx§CMŒ|Å çn¥aïÙøó|däšµm™±¬(j;ê׉þö$À`îäÏ×^Ïœì)núê úþ¢†y€NÈ]tZS»v¬«OkèÆ2ïTùÃ=ø]«Mõ¯ú×1öº(8OÝŽ©Z%눩kcà&¥bØëÏãÃÀú°G66Ťzµª†ÿu­‹?ÏÞÃÜÕ§ضÞëÚÈÆÚ©:¥]‡­¤À’‚Î]Ž,•=šÛÙ#6·žfy{™)y.èÕÚtÓ‚¢–»=æo:K×âP¿¦ÞjÛ ç¯Å#]éhb?×õù*xÆ­8#G¡ÂÉË÷ñÍ–ñï•ëP*rPY&ƒ‹, >9‰ýµÒ»M¦öÓ{n¢yM{ŒíTwã ]U c^«ƒÿî¦a×ï±rO%¬ŸÔÉèþÒ'¤'Æw®ƒ¿¯&ᣎŠl¶o†ýò £õê;fÍíòß$Í€¦ÜSVÕúNw½©›®àùʷк¡Z4«Ñ¯za\çº8y5¿žKÂîÓú?ñ¬(z;2ƒí™z?.^ö·Nýó‚x€ÍC=4ß[¬>“`S§Ð[ƒ±ú,~F¯Û³ö½á_Ç$#Ýœ'Éd¦k}´’‡³ƼVpêÂuØHy°•_ÛÿÇ#pUØ EY J™„àVêwÍ#'NA‘‹íGþë­¡g+Oì=ywó¿«þ}•*ŸçŒµœG‹F5Ðï…êøëìm$乡wO@ô῜ ì8öÛ5E°ouü~ú&âóÜ Ö¡½©ÊÊ7yºf²»<nÊtônóŒÉ>œm ÈSB™yJUÎßLÆù›‡àe£Ä /äª ÿ%Ýþ)>:ßwøôo½»yr÷úêý‡õ¿DvVòT2(% 9JGdÃJÉæÑÑ¿Mælç›Ïãëw¼1%¤ò Gfv–m‰†­* 6’½Á¶“•†/Yë×¶:`ÇÇ“žŠL•=~úýjØ(©Ðz4p Œ3sÏèuèYïúC7¤Ä¦àÈÅ£pw´Aß´iVmºâðÙårèÎŒeEQÛ$lÏXîè›oVöƒ±íÝ4ÄCçûïG>èý}ÇX}?£×éXûŒÞȯc$³çI’éwÕ9ï¿ @ýaì½”¬ß'ŽŸÂCØë¬›žñ*O$«\‘•W Õ\y™©È”ª .Ãàî\ 5å‰HV¹jÖMNÉ@–Ê ipÆ©¤J€ª®N¨-O@ªÊµÜÕ1¼«NmÕÜQKv)Z!T°ím tG²J7°¤G{Åœ>ÿyc_«‰ÿ ì¥J…Ëw3±ôÏ›øïæ]ØK (`kt_ÀÓ¶×qAÑ ÐôÈ7Ðë9{ø6«ŸÆ]púJ<ÅÆãÐéHTØ#6PAÒ}±Ø&s¶áR’~‰CÏÔgÔ¿ýé©HQ¹"EkßlÛØkÒÓE½ÝY©‰ÈP:#QåŽL•*IY°‘ÿîfè;fdE~=é[/ÛÆ ÕÃ+O;£mc7ØÙÈpñú]œŽ½‚F6·qVñrT6FZ­˜,9t£¾äÐÐÐáÜÑ7ßœì)núêØ0äñÉàˆÅg°dd êðïóc’ÞvÊüŒ^ß}—%Á=÷¦fôÍÓÿƒñZÃç­@¦Ê¡ä°G²Ò¹’n°¥¡2J• ‚„„Ô\xyØÃÅÉéIŽptVŸ1%¥e¹°×úmÀÝÕ çâ+#ŽðrSŸ&¦¤ÃAʽ”ƒûi¹¨éf‡Y‹6à^Zž¦') Žr%ìór Ö¡»5ÿ)4Ýœ>¶Å<À…óÿ EuÕ¯ƒn/µÀ” ðÆ·ÉÈ„£Þ¦_ž}­mÏÁê=d€›, É*åvý“„‹ço¢®S6|šÕC‹f 1®WK¼›«ÄáÿR15êºþ¤µMælƒW5Wtm]q‰iC‰W[5ÂÉó×påž#2PÙ¼ýU@|ªºßªn•q1Þ¨Œ<ȪïÏ@›E>f¦h­7=¨^lä[.ÜIÃÏÑ—pöß«ÈÉL…¤R!¶¨$e!.F›¬ôdÅúwÜõ/«¥ï²á—Ÿ†Îè‹8tcNö‹‰í¹ä $I½}ùÓ7 q7¼½zéŒ>"B#Ó·h©þ÷´úï‡#£×³n²­þCÜsojæi¯gÖ8™¤«Ô ‚„‡pÀC¥=RáŒlèþªIÔµíþ'ÃýªÃ¯Í3ˆÝŸ„ jÅ\‚J’Aû7ônþ­qa÷ HJGŒ~E=<}ò"TA.O$"쵚èæßË»yðTmtjÝóÖ…\çSÝ:R²pu´‡›3¤D$Ø^I½oÍéãÓ ØxÄ'îÞA:’Ñí%@‘›ƒÆò[ˆÍkôŸÞVÖ@eéñîÔÔQx¿Ç©ª#==7OÞÃÞ“7PÝÍ­šÕƒ÷Óõà%Çm¥zÚ&SÛPÙ^ŽAõ¡T?n; [)Þ À°ž/ fE,TÙ6¦÷—ëßǸ€Zèѱ .í¾E¶ÞjWßýg´^CǬà±1§†‚íi¯W¿Š¶¾ŠÓ®"%5*§’!Wª„\8 Ci,©rÑû©Š{9¤vfhÚɣ׳üâ…O0 ÕR°®Ò£70oä’3Ô9)è·, ë…½¡íÕ§Hgô†.£Ÿ~ ÀÛ¾Ù§5£Àuô†þ¢ÿòd¸åÞÔ™&“$½Ë«ÿ(ÀT­U…Î@ÍÒýF’4×»*²¼ülmüТ î¥*°òÏË8sê_dÀ*­øÏ¿×1­ï³¨ê挄´\,Û{gÿùªÊPJ2l<™Û‡÷ØÚ ³F¼$üs+kÝF®d­a ‚uü°?#^ª‚†©?”õ›s¶ðFH’Y}ì8“„‘k¡qͧ‘›§Â¹Éøý¯Cpå ’ò!R¡û®Ê³ðåµzv{‘¥rÄ}•*á!î'gàú‘ëØuô_T—+ 7d¨ n“©mÚ©êV±Ç÷»bøà’TÎX¶÷,Ftk‰ÿu®ÉÛ“ÌØ_…mþûìÞC`ë:ør¨/ÒsTXqàz±:Û1´œRüp${ÄÂQ–•-” T9"®Èƒ¦“ç®à×!“PIK (¥ÊHR¹!$¶Wàä…#¨ŒLä¹°E®Ê*•NR–Á:¶Å$ãŸÓgPM–ˆ\Øâi¹=.(ŸÒ»¼©>Ž^‘áæµ«pV¥B’T$lTÙÈT¹Å9ó4@2à„ •î#•…ʪ È¡îÓÐ60º _ﺄ»ÓQ],•#RTnØt8» U¥¨/÷Àö[ƒm³ý‚'/“”lðö°“*Á9E:Æ~¦ ñÿì<šÊ.œ¤LØ"Yp@3¹=.*A%ÒU•ðPBó]ÃPVèˈBël'ÿË‚íYš©úÌg¬>£gôÚ·=PÿÛ@¥1–?Zçšz}ûöÝúi‘Ém È͆­ƒ¾Ì’›“Inkô]õ–ª&*#Ï¬Š¶\&œpSU ®ªtØ!*eŽHÊsBŽöR$w@™d°G&‘gÍr™¨Œ›ªÚp‘ÒàˆlHȃB²E¦T9*’Á:îÂ9°‡*Tp•R‘×BË›ÓG¢Ê9¡2²!S)‘«r@œ‘%sT–Œ<Ø ÎHƒ³ÎO¢¡m2µ ’ ‰ðÀC•=Òà„\ØáŽªæ£a8 ޲lÜUéoÛ˜LTÂ-Ô†«”ÕCJäÀJI@2ûä3÷g/_2\Q™HRéÖ™ßO"]å%rªëa鬰Vö—5êÓRPç"êÌø+ø±ù|×#* Í[´,ëJÝù31e]YÙµWtÂ^¼¿Ÿ&2Só-Ÿˆ|æyoœ;}ª¬Ë 2¤7è]\ù£)©))Âï§'aE·?úO÷5šb¹Ûi?É ½‹«+N?ZµT(=úôǶ k˺ŒR%ú6zÕkPÖ%XME}M÷èÓŸ¿X/)†'N”u ¥îIØF*ßø3h9 z""Á1艈Ç '"ƒžˆHp z""Á1è©Ü5vBY—@ÆcZ>ð/cÉjF€…_Ï/ë2ЬS—®z§ïݳÛ*}[£[‰‚þî½xlݱ—.]ÆÃìlÔ®] _{>-Ÿ·T}Zy 6KÕõÁ”1kú4ØØ<þ1Züý9l¨æû\…S¦NÇÇ“?´ê¾°ô¾–¯gq;èã0ÿëoðê+èÜ .Îθuë6öþñ0ž ë7À™ÎÂÇ[}c°ŒÌLœþçÒ32àTYýpö˜ÓgаA8;9•e©¥"-- C†ò€“Öö¥¥¥aèðøñû¥¨T©Öþ¼¿üò Ò32о];Œ= êLtêÒcðnÝ:$%'¡Q£F˜0nêׯ¯ùM"ÿÿùo6§bb°té÷¸qóÜÝÜ1`@tíÒ¥DÛÂ׳؊ô;vý¿xíÍ´úõëaÄw4ß+ lÞº'ÿþÐÊÇÁ=5g€£ÆN@ÿ¾½ñëï")9žžÕ0 __$$$`ÏÞß””¯:^4 ?jT÷,ö:æÕÑ{û ©©iðªã…·úõE­Z5‹»{Lº—€­Ûwàß/C©T¢i“§ðfÿ~pª\_|õ ^îЭ}|4Ë?HJœ/¾ÄôÉá°±µ5¹=Ïfó§å™æÿ¿$g½/´õÅ¡#G4AåÊU¨T*\¹z-žU?üúÈÑcèðÒK…êÊËËÆÍQ8qòär9^}Å_§m…B ›£pòïÍü¨­Û5ë«T*ìÞû>‚¬¬,´lÑ}ûÃÞÎ΢ÛhŒ³³3:tx »víBß¾}5ÓwíÞW:úÃÉÉ ›6oÆ™3g0gN$œœðÝ‚…X±rFŽ®Yþäɘ;÷3¸¹ºbã¦Íøêëo0ÿ‹Ï±wÏn½C7s>›‹ÐѣѶ­/’’’±zõê½%^Ï¦Ž©±cF¥«ØÆ^ü÷_´Ñ "}vïýqwï"|âÿ>ñ¸w{öþ¦³Ì?çÎcܘwñùœYðmåƒï-AÌé6j$æF~ŠÏ4ÇšuëK´Ž9uÄ^ˆÅ„±¡˜ù)žyºÖ¬ßPÜ]c–¥?,‡ÿK/aöÌÌš>n®nزm K§Nص{/TZO›Ùµ{/^õ{ŽŽfm!ù¡·ðëù%ÀÏ<ë7o"--ðß•khÞ¬)þûï* 9%·îÄ¡Å3OZwÏÞ_q/þ>>šôÂ'þçb/èÌßýË^$>HÂÇ“?Àäÿ‡‹uŸØôû¾h\ºtãÃFcfÄÇP(رs·Å·1_§.] }@P¯ lÛ±yyyÔa·sç.P‡~hèÔ¬QNNN1|8 ÓöØÐ0Ô¨^èÓ;—/_6Z‹\.GâƒD$?:Ñ™0a|‰·Ï¯gSÇÔØ1£ÒUì ÏÈÌ„«›ñ;â;q}CzÁÝÍîn®è„£'Nê,3ð~¨Zµ*ìíìðŠ¿>|ˆ7ß胪U«h¦]»~£Dë˜SGÿ¾}PÅÃövvx¥#nܼUÜ]c–Â'¢I“§`kk GGôèþ:ÎÇÆš?Ývö8ñèÌ)>!ç/ÄÂÿåfo5Èär´jéã'Õu^¹zÝ^ï‚ÿ®ªƒþè±ãhåí ™\^hÝ#ÇÕÛàæúx´;ù7zõ‚«‹+\]\Ñ;¸—Îüƒ‡ã¾!¨Z¥ *9:"¤WOœ:}º”¶T=lRð êÔñB½zõ°ÿ :¼ÿ:pO7oOOõsâïÅcè°áš7‡~ý áþ}¶Ý=Ü5ÿ¶··GvNŽÑZ"¦MELL Fƒw† Ãñã%¿'Œ%^Ï¦Ž©µ=V졛ʕ*!%9U«V1¸Œzþã‡ÕV󬆔äde\\]4ÿ¶{ô+œ‹‹î´ÜÜÜ­cV&ú´´7nbó¶í¸yó2³²2Ùã÷Ý®^CÔÖhåí»ö Ók¯j¶Õœí±–_ðŪŸVïC{dde¡aýúÈÌÈ„B¡Àá£Ç1ôÁz×KIN.´ ºóSPµŠ‡æ{íe ñA">™­3-ÿ)iÖ„U«~‚ÿË~زe ÂBC5ó<==ñé§Ÿ FõêÅj[ß6=Õ¸1¦M •J…cÇcÞü/°nÍšb×Xæõlꘖ§cö¤)vÐ7mÒ'OBç€× .ãêæŠû÷ï£f€„ø¸ºYÿY™å¥mK—¯D·.0|ÈÛptp@ÖÇx?|Šf~‹gŸÅ¶»±uûN\¹z ƒß ™gj{lml““£ycHMMÕéÛ’/®:µk=†uëPíîûëlmm5ó rusÓÙ†û ÷ ÌwÅýÄšÏYî8 öpwGØè‘¨âá}¬ ­||°hñlݶ ŽŽhܨ‘f^``7|ùåW=jjÕª‰›7obíÚu˜<9ܬ¶]]\pãÆMÔ­[G3möìH xsj×Rï[™þƯgSÇÔÔ1£ÒSìŸÀ×;ãèýøýÏh$%§@¡PàÚõXòã2Í2m||°~Ó$%§ )9ë7GÁ·•·E /ŠòR‡¶œœ888ÂÞÎ$aõÏëtæK’„®°÷÷?еKäZæ¶§nÝ:øõ?‘“ƒû‰‰Xý³îç N•+#îÞ=‹mË mÛbËöhòTc@“Ʊc÷¼ØÖ×à:¾­}°qó$§¤ 9%ë7oÑ™ßÆÇ£¶ %5)©)Ø¥;߯C;ü´v=âîÝC^^î܉ÃËV–Ú6£ÏÔ -FŸ>½u¦÷ìÑ/¾ø¦ÏœžAÁˆül.ü;ú™Ýo¿~}1nÂþ^h÷"f̘‰^ÁÁX±b%Â?œX²ƒe^Ï¦Ž©©cF¥§ØgôžÕªa|ØhlÛ¾;÷ìANN.¼¼j£Ó«¯h–éÚ¥6oنȹŸ|¼[¢KçN%¯ºˆÊ²}¸ðëùØÿ lŒÚ‚¥Ë–ÃÍůvÄ©˜3:ËÉ$<«Uà mÚèL7µ=úöÁOëÖã—½¿ÁÅÅ^{gΞÕÌïð*æ~ñ%²²ZäÃÊ6­}°ië6<õ(èŸzªr ´imøÃ½®°asfΚ¹¯½Ò.^ÔÙÆõ7cƧêùþ:à¿?¤ôùeH’ K¾ÿ÷ÀÓ³zt{†–ÜFs®¡ïÚ¥‹Þ+_d2zöèž=z˜Ý¶ö´à`„ëÌïè燎~æ¿Y˜Ã¯gSÇÔÔ1£Ò#Õ £ò8 7ï' 3þ 6¾Û¸Â>ÆZNœ8s>/õ§/-\ò=Z·òA›VƯ†( ÖÚFsݾs‹–þˆ™Ó>²X›Ý{¿!ü3c÷Gÿ‰wǾWnŽcQäÿ ò SE7dm*y6DÜÑÈzp“÷º)T*:Œû µOÙ1•¥ ›£ššŠÄIظy+žoñlY—DT!ñ^7åÐèq‡F yû‰¾*¡jDÎûм<<ÿܳèÑíõ².‰¨BbЗCåñþ8e¡4Æ¢‰žDº!"ƒžˆHp z""Á1艈Wè:ú#³ʺ&"«ýzmÍ[´,ëÈJ$IBÛð½:×Ñë½êæIz= øš~²q膈Hû£ÿÔ;AOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚³ÈmŠ >?3Ÿ9`³DßÖ臈¨¢²Øýè¶DDåS©ݤ¥¥¡Oß~HOO/4½ïý‘žž¥R‰ÕkÖbÐà·Ü»>ÿb>>|¨Y¶S—®Ø±sŒÀ=0nÂ\»vM3/ÿÿÚ¿UœŠ‰Áè1¡ìÑ Æî={Js3‰ˆÊµR zgggtèðvíÚ¥3}×îÝx¥£?œœœµe Μ9ƒ9s"±rù2( ¬X¹Jgù“'O`îÜϰqýz´iÝ_}ý €Ç¿Eìݳ[ç7Š9ŸÍÅ€þýµi>Ÿ7b/”æf•k úü³jí/ê„m;v //——‡;w!8(€:ôCCÇ fprrˆáÃpàÀ¶Ç††¡Fõêppp@ŸÞ!¸|ù²ÑZär9$"99žžÕ0aÂxKm&Q…S¤1ú‚7Ì6AsW•ˆ*6íì5G‘?Œ6Aóos;  ªU?Áÿe?lÙ²a¡¡šyžžžøôÓOP£zõ¢–@}ï傞jÜÓ¦N…J¥Â±ãÇ1oþX·f¦Q™B8IDAT Ο‰Ñ©Ÿˆ¨¢)ÎÉj±®º)ê½­[ùø`Ñâ%غmѸQ#ͼÀÀnøò˯0zÔ(ÔªU7oÞÄÚµë0yr¸Ym»º¸àÆ›¨[·ŽfÚìÙ‘ðæÔ®U Ó¡â}¹‰èIc±Ë+õ]K¯=œÔ _}ý >ýd¦Î2={ô€L&Ãô™3p÷î=xyyað f÷Û¯__Œ›0šþ^h÷"f̘‰{ñ÷P·N]„8±˜[EDTñY$è͹†¾k—.èÚ¥K¡é2™ ={ô@Ï=Ìn[{ZHp0B‚ƒuæwôóCG??“5= x ""Á1艈Wâ¡›_öþj‰:ˆ„×¹S@Y—@O¨ý„÷ùA'6Þ\þlh™?onY—@O0‹|ËKÉþl•=ŽÑ ŽAOO´gž÷Æ3Ï{üžHûƒ©ŠÊØ‹úÜéSV¬äq-Öî×ÚŒm瓲ˆ¬é‰ú| "‡nŒHIIA+ßлîß×LOH@ ïVhåûRRR R©°qÓfõî‹Ö/´C`Ï ¬ýyT*•fü!-[·áõî=áݦ-Bú¾˜˜Óšù—%µ•?­Æ3Ï{ã9ïVð{õ5L›1šù¦öm¾›6£{P0¼Û´E lݾÃdßE9¶kÖþŒW;wų-},·ñDÀ 7ÂÕÕÝ^GžR‰í;vj¦oß±yJ%»ÁÕÕë6lÄ´3ѬiüùÛ^tî€OfGbæM…ÚîßÇÜy_˜\ÏRÇ–¨,ñŒþ}ãÃùC 2™ ú¿¹Ÿ«ƒaèwtžk;ðͨâá«~B—×ÞÞ-ñÎ`ó ¡cFã» ѹ[wþŸdŸÍž…Ysæ`èˆwQµj 2¤Xíô FžR‰U«W£K·î¨W¯.¿õ¢÷ï7ºž¥Ž-QYzâƒÞÜ0}{Ð@Íqú¼Þµ ^ïZøÁ*Æú)8í¾}ðFß>fÕS‘ÛççµnåƒÍë×éL+¸ÌٷЯOoôëÓ[gZÏÝM®WœcKTžp膈Hp z""Á1艈Ç '"\‰?Œå“sÈþl•|” •Šèèhøùù•uåFtt4š·hYÖePUÒ'µq膈Hp z""Á1艈Ç '"œEoàU«¦Þé8ˆà 9z ööö…槦¦"8¨.ÄÆlûÖ¸"÷›¿ž¡ùùmN?’$á‹ù_êÌמnª"¢òÊâ÷º1z¾¾¾X÷óÏ4xp¡y«V®€··~ûýÍ4¯Z5ÍPíå ­g¬­Y³#Ñ­klܰ½û¨ï£²víœ9s;vî2»"¢òÈj75 ‹Q#Gâ­uîü˜››‹åË–a݆Ö*¥GGG,Z²}B‚ñ|Ë–ÈS(9k6Em££c™ÕEDd V úçž{õêÕÅ®;Øýñ·DE¡¥·76lh­RôjÒ¤ ¦|ô1FŽŽ<…Óg ñ£'HUdÿ0Ö«VÍB_ùBÃÆbáÂ:Ë/^¼cÆ„ZºŒ"Õ•ÏÏßövvËåèXê5YƒÕÆèàÅví —ËqèàA´kßÑûöÁÝÝ-½õ?ÚZuå ÿàC„OšŒÛ·o#rö,LQêu•6«_^† ¾,Z¸Ð*góæˆÚ¼9¹9ðó÷Gÿsê8PÖe•˜Õƒ>  âââ°iãF$&&¿cGk—PHBB¦GLÃÔ©Ó’$aväLœø>RSS˸:"¢’±øÐ¾±oíaI’0fL(Þ›0ó¿üÊÒÝ«®)“'! Sg4mÖL3¯i³f ìŽÉááøvÁ‚BëU zs¯- ApHˆEÚ2g=Sm-Yú½Þé“§L1»"¢òŠ·@ "œÕ®£/)Þ‚€ˆ¨x*LÐ3̉ˆŠ‡C7DD‚cÐ ŽAOD$8=‘àJüaltt´%ê ñgƒ¨|(qÐûùùY¢Ltt46´ðMʇnˆˆÇ '"ƒžˆHp z""ÁYô†îGó׃ ‘£Ç`oo_h~jj*‚ƒzáBl¬Á¶ÝÁÔ}p ÍÏosÂøq$ _ÌÿRg¾öô’ÜkÇTÿ^µjÂÏß?­^I’ ­klòÛ1§|îîîðiÕ Ó§£Aƒ²}V/•>«=JÐ××ë~þƒ.4oÕÊðööÁo¿ÿ¡™–pEíÓÐzÆÚš5;ݺvÁÆ лOÀÚµkpæÌìØ¹Ëì>Ì­Qw7w,_¾ ï¼3ÄäúÅÙFíùIIIøáû¥?v¶nßnªt"ªà¬6t6K/†R©Ô™ž››‹åË–aÔèÑÖ*¥GGG,Z²3gLÇ¥K—p!6‘³fañ’¥ptt´J ³"#±üÇqùòåRïËÝÝïŽsçΖz_DTö¬ôÏ=÷êÕ«‹];wêLß…–ÞÞhذl‡š4i‚)}Œ‘#†cäˆáˆ˜>7¶Zÿ...ˆœóƆ…B‘›[ª}%''cá‚ïÐìé§Kµ"*¬ú(Áа±øä“™ìÞ]3oñâE˜7ïsK—Q¤ºòùùûaÙ? [¥B·À@«÷ÿb»vhß¾=æÍ›‡ðI“,Þ‡ö|ÏêÕ±u‡mˆžV£ÔA&—ËqèàA´kßÑûöÁÝÝ-½½-]F‘êÊþÁ‡Ÿ4·oßFäìY˜:-ªýÀ†£g÷@¼òê«ðõõµh·îÄA¥RáÆõë˜0~Î=‹:uê©"ªx¬~yehX,ø°háBŒjíôŠÚ¼9¹9ðó÷Gÿsê8`õ:lmmñå×ßàÉï#==ÝâíK’„zõëã›ï`Ò¤ðR郈Ê«}@@'ÄÅÅaÓÆHLL„ÇŽÖ.¡„„L˜†©S§P‡áìÈ9˜8ñ}¤¦¦Z½ž&Mš`à Aøø#ý'·„ÚµkÃ××[¢¢J­"*¬:F¨Ct̘P¼7a<æù•¥»/V]S&OB@§ÎhÚ¬™f^ÓfÍØ“ÃÃñí‚¥Ú¿>ï Š·ÞPª} xó-DÎúo X¤~ˆ¨b±hЛ;‚à‹´eÎz¦ÚZ²ô{½Ó'OÑFmékèõÍ—$ «×¬5{ùâôáççÇ;L=x ""ÁY|覴”䥭<×FDTa‚¾<fy®ˆˆC7DD‚cÐ ŽAOD$8=‘àJüa,ŸnO†ðgƒ¨|(qÐónHŸèèhþlhᛕ%Ý ŽAOD$8=‘àôDD‚³è- Ýó寄#GÁÞÞ¾ÐüÔÔTõÂ…ØXƒm»Í€©{ÍšŸßæ„ñã I¾˜ÿ¥Î|íé%¹ŸW­š—Ñž§Ý‡»»;|ZµBÄôéhР¡Évˆˆ ±Ú£}}}±îçŸ1hðàBóV­\ooüöûšiE µ‚ÏE-êm|gÍŽD·®]°qÃôîÓ°víœ9s;vî2»KÈo7)) ?|¿ãÇŽÃÖí|¶+ŸÕ†nBÃÆbÉâÅP*•:Ósss±|Ù2Œ=ÚZ¥âèèˆEK–bæŒé¸té.ÄÆ"rÖ,,^²ŽŽŽeR“»»;Þ5çÎ-“þ‰HV»{åsÏ=‡zõêb×ÎìÞ]3}KTZz{£aÆÖ*E¯&Mš`ÊGcäˆáÈS(1}7n\fõ$''cé’ÅhöôÓeV‰Áª ‹O>™©ô‹/¼yŸ[ºŒ"Õ•ÏÏßË~üÙ*º–zMúh×éY½:¶nã° •ŒÕÆèàÅví —ËqèàA´kßÑûöÁÝÝ-½½-]F‘êÊþÁ‡Ÿ4·oßFäìY˜:-Â"}ÛØÚ"''vvv:Ó³³³!“鎞ݺ•J…ׯcÂøq8wö,êÔ©c‘:ˆèÉdõË+Cð`Áw€E b̘Pk— WÔæÍÈÉÍŸ¿?ú€˜S§pðÀ‹´Ý ~}œ;[x¬ýÜÙ³¨]»v¡é’$¡^ýúøæ»˜4)éé驃ˆžLVú€€Nˆ‹‹Ã¦‘˜˜ÿŽ­]B! ˜1 S§N ÚÙ‘s0qâûHMM-qûo¿3'¾#‡#-- iii8|è&N|ƒ¿mp½ÚµkÃ××[¢¢J\=¹¬:F¨Ct̘P¼7a<æù•¥»/V]S&OB@§ÎhÚ¬™f^ÓfÍØ“ÃÃñí‚%ê{ÐàÁpttÄŒÓqõêU@ƒ 0jÔhÍ圆 xó-DÎúo hr;ˆˆô±hЛ8Á!! ±H[æ¬gª­%K¿×;}ò”)f÷aŒ$IèÛ¯úöëgt9}íúùùiîÉ@'¢âà-ˆˆgµëèKª$· (må¹6"¢ ôå90ËsmDDº!"ƒžˆHp z""Á1艈Wâcùt{2„?DåC‰ƒ>ÿyˆ´EGGógC ßô¨,q膈Hp z""Á1艈Ç '"œEo`èž/8ˆà 9z ööö…槦¦"8¨.ÄÆlÛØmLÝkÆÐüü6'ŒI’ðÅü/uækO/Éýl¼jÕD“&MðûŸû I’fºJ¥Â+þ~¸téR¡6.X€ÈÙ³>ir¡§›So~¿†j3µO¼jÕ„Ÿ¿?~Z½F§fSíQùcµG úúúbÝÏ?cÐàÁ…æ­Z¹ÞÞ>øí÷?4ÓŠ&ÚËZÏX[³fG¢[×.ظaƒæþðk×®Á™3g°cç.³û0ÆÁÑ¿ýö+:i¦ýòË/p¬T©Ð²J¥«V®@ÄôéXºt)F¾û®Î#ͩצ¶ÁÝÍË—/Ã;ï 1»M"*¬6t6K/†R©Ô™ž››‹åË–:kµ&GGG,Z²3gLÇ¥K—p!6‘³fañ’¥ptt´H£GÁ‚o¿Õ™¶à»oõ>JñÏ?þ€««+Þ2îîîØ÷çŸV¯fEFbù?âòåËk“ˆ¬ÏjAÿÜsÏ¡^½ºØµs§Îô-QQhéí† Z«½š4i‚)}Œ‘#†cäˆáˆ˜>7¶Xû¯wë†û÷qâÄqÀáC‡ô ]_½Ð²+V,ÇÛCÔgу¿åË—Y½^pqqAäœÏ06,ŠÜ\‹¶MDÖcñ ÷ªU³ÐW¾Ð°±X¸P÷±|‹/²ÊÂÕ•ÏÏßövvËåèhÑþe2Þ5 ¾U?ýÛo¿Á¨Ñ£u†dàÆõë8ƒ^½‚={õÂé˜ܸqÃâõš³O^l×í۷ǼyóŠÜ>•ú[wâ }å{±];Èår:x½oÜÝÝÑÒÛÛÒe©®|á|ˆðI“1løDΞeñúô틘Ó1ز% ±±±zŸ»rå $&&¢QƒúðªUÔGbb"V­\añzÍÙ'ðÁ‡áø+zŽ;Vä>ˆ¨ìYýòÊа0,X >«]´p¡UÎæÍµy3rrsàçïþ æÔ)Ýž áÏQùPâ ÷óó³DDDTJ8tCD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àôDD‚cÐ ŽAOD$8=‘àlJÚÀù31–¨ƒˆˆJ Ï艈Ç '"\‘‡n3¿4ê "¢RR¤ 6¡´ê "¢RR¤ ç¯DDÇ艈Ç '"ƒžˆHp z""Áéý0vôŸÖ®ƒˆˆJI¡ —$©,ê "¢R¢ô•<¢møÞ²ª…ˆˆ, ’gCï Ñ\€ˆˆ*6MÐÇÝX–uQ)‘ ^ÀUYBDD–wý×ï¤ÿ‹øækõT—IEND®B`‚wxglade-0.6.8.orig/docs/html/ch02s02.html0000644000175000017500000000512612167336636020201 0ustar georgeskgeorgeskBasics of wxGlade

Basics of wxGlade

The program wxGlade is a tool for designing Graphical User Interfaces (GUI). It is intended to be used with the wxWidgets framework in all its flavors: C++, Lisp, Perl, Python and XRC.

You use a visual editor for creating forms, menus and toolbars with the mouse.

Your design is saved in a .wxg file, which is the wxGlade file format. Then you generate source code or XRC by using visual tools or invoking wxGlade at the command line. You can also use wxGlade in your makefile by generating source code only when the .wxg file changes.

A .wxg file can contain multiple forms, panels, menus and toolbars and generate either a single file containing all classes or multiple files containing one class each.

wxGlade does not manage events, file inclusion, function names, stubs or anything else but graphic interface code.

wxglade-0.6.8.orig/docs/html/ch01s06.html0000644000175000017500000000435612167336636020210 0ustar georgeskgeorgeskDownload

Download

Source and binary packages for stable versions are available at http://sourceforge.net/projects/wxglade.

You can get the development version from Bitbucket.org at https://bitbucket.org/agriggio/wxglade/overview using anonymous Mercurial (hg) access.

wxglade-0.6.8.orig/docs/html/example_baseclasses.png0000644000175000017500000003037112166606326022736 0ustar georgeskgeorgesk‰PNG  IHDRz ÀsRGB®ÎébKGDÿÿÿ ½§“ pHYsÄÄ•+ IDATxÚíw|×ÇßϽÙ{”šõCÍ*šP£J³ãg‹bVu˜‰Tu-Šš±:ð£-j† ¶ˆQ#d‹$’›{„+—›äf¹ÉuÞ¯×å>g|Ï÷{ÎÍç9Ïy–Ä*¶ P!ƒáæÞï$#ÈyŸÞ3õí“@ J º¹÷;Iz*ò·“êÛ'@ ” ·­%=!:gFý8Mß>  x&ô™¥,ôÊlÞ¹Ìã¤{¨²…®.Éä˜Ú»c]¡Èä/½£ÁK¢¤µ¢¬kÏKð/׌þÑ ™ÆÓšáûäû~ÀwÊß¿?Y¾ÏÖýÓb¯¡B…{#?ŒÌ¬ Œ"#•„ËI‰¹ˆ¥kå’é`@Pæ(i­(ëÚó2üS ½¶=‰/0õÉ÷©ÀÔ©SÑ•©S§²'—ÍÌÔDÜ~€q01·Â©Fsîœú U¶w1»V ”UJZ+ʺö¼ ÿÔB$+ñ4lJ`bn],sÆ69†JÃW@P6(i­(ëÚóüS ½$I%ï.›’$£$Z$Y©ø*Ê%­e]{^†ùÎè÷ûø0Õ×7çûþý:-ÝL›¶ŸœEŸý¼=¥].órdy8ñ›¿ã i,׌LþÊÎèOm @³©GõíJ‘h^ÝžÀv•p·7C&•ß8¥K~ZQX;H2­ö´iÎó<¯A¥¥=ùù§MóÊËÏ¿|gô¾¾¾jqŸ:uªŽB?•'+úš3z™¼P{-'E ñFžZ;%¯½Ö¡)oilg*”ÜMzÌž³q¬;r‡¬ìòqóïÓ8šO;¦5¿–Y —{éÛÍB3öý×pµ5åËåq?.Zf”Ë8àÅßZ^c%(<…ÕŠ|íHR‘í=¯AùiOiÅû›¿#r ú¯¹vP…ñ/ÿ5úâêbn›2Ïû°cPŽÓŒÇQ£‘·rX]už2Y{UÿÙ¡ØZšÑãݺø·òÂÍJÅÜÝ÷ŠÒˤ¦i —2Ÿ\i>ý8Ì"q+°“§‘¤,ÚÉ›ÒÄÝΔֵiSÛ‘>KÎiä¹Úšžx%–(TR™£ šO?NM“[,ŸØxq¬Vý{ÏÇóçùxî&=Ö·»å -ZQT;H²<í Xr&Ϫ+†ÖE’Ь§ƒö”T¼ŒWëã¯þŽÛO}/Œ¹„¾döT>>ûñõÊþýûQHr™—“×J”“"†#/ò$I^ ¯ò‡ÜSØó UÁº?ÏѤ–¾o8³þ¯sD+\88© wßä“·Ýq¶1¡EÐ dø5tÁ¯¡ n¶¦Ä&g²ýä}¶œˆEùdqèIÝà7øïÛnx8˜q'ñ1ŽÝã·Óžù |Pß™n\ñ°7å~J&¡ÇcÙ~_½³9¤ÅÜ‘=‘æA'r•oLßYÛA’$©À6Þð°bxkOª¸Z`,—8së!Åv-¹DÆÀÁÒ˜Vµh]ÛÚžV<ÎRròZ•Mîq=Ë]#V€zçüV‚Â80©‰Ö±èÙÄ•À¶Þ(Uô(‹CW’øvo4i™Ù6çþñ/½›¹ãdm­ø –üM57Küº`m.çZl:ówÝ$òî#ÇF•ÏN 9Èb'¤Þi݌Ϡ w†´òäBÌCöœO`ßÅDe•X¿*ùiEaíäüh·'Ažºó4?w=]´§$ãõû1mƒ4D~à’3jßeÏÙ¡ ½TB{ª§Ë=S§Nå¯\6s+ò órìä«D‚ÊŽ$¥5ŽÙÏn p‘'§´Wo7ñ€ÀåÇ1W$PËTAízlëÅo'b˜{ø<ÝZTeT»*XÈ2Y–¬!k›3y}vR ƒÞ¯Ëg+aÊc¶D¤Ð¥3ãÚ{³ï|,ó~9MÇ&¯1¶}uÌxÌúð rûa,)X6¡+ŸÍ[EºÊ”Z&¦\ʪ¨.o*S’œmC—†·1ů2ìMY¸%œ¨ïRÉÝŽÿ6©ÁÅ4/ÖX·¯ëH›7hðš5™ '¯Æ±xû®\¿‰R‘‰¥L†,‡*KZŸäàW 4âªnbšçX\ʬˆ¥©#–Gõð.kyÒ·}LUÌÜue®Ÿxso‰1+Nðv%»6fÞGÕØ{6–QËФ¢Ýš0­³ý—#CeZ¨±ÉX¥“Æoîé‰?€É[®S×2††•¨S£ÃßõdT;oNÞHaï…Dv‰×©W‘ü´¢ðvdyÚËOw´åë¦=%oןØ:ÐA½=hiÎL>ÁÈë…]C~þåRbéÅO±#xfKzrx¢Í¼ºçÉdÚ}ÕRÉÁÚ„€¶9‡Ó§/ßÄHÊÆXzvmÿ߇Ža«ˆ%]iÌc•1]äì5…ŸFñ8ߎ] s\4򿧣XdÄp?UÅú¿/Ðë-Wœ’A’èÞÈ€GOAf*¿ϱյ±+.ÆÉ¶ž÷#w)*K21ÂNžªN¶—§`'OÕ© ks#ÙJ”iq(UÙ\ŒNbQè<`,Sjíǃ_5ÐøäÕß_|P‰F•m8~ù_,Ùɺßp!ò*)ÍIRZ¡”Œ´ŽÏÓ¸òê;y*«Ý#>!T…œÎÝ qU¼ŒîküÌöÃ6+–דÔiÅ83‰°k‰x8YQÅøF2•nc£ë'ŸñÍ ;þº”̲aL]òg"£iTÙ–/>¨„üQáÚy…>Ú´¢HŸ'Z‘—öhÓ|óóÓžRŠ7·Èü8¤.‰Æ^ùÆ«í÷Yâ3zMϽÉûpLBÒ9O’ Þ«ÎßÈ9›œÉ¦ƒW ?qš L5ê¦>Êà‘Ê…$•-éÙ8Ûš–BšäÈÝG¶Ø[[à.'Ie«®›”üˆt•±æt¢N¶VxÈ¢²¡‚}Îluª{ ßœí­© ‹#9×aÿó~äŽ=AiO’Jó[éI¯èÒÆÒ}wlíθÞï¡T©¸z/åû¢¹}SIc ¢¦ñM.+^{!}öï·èòS×p£þëïqæú}Ž\ºÏ‘k©Ä+LÉÂÒ smq=ß5+X0ÅÇjnÿÁÚÌXmÃÎÚ'y2”Ïe¦¦óHåB|æ³µþÌGÉdK.$(lžün$l¤4,¤Ç:õ[&&ö‹¶1ÉýûzldOå*iUÓš&¯Ûab$#òæ=Î\ºN£ÛœWT%SeT¨v^Jré&ç’ü–n¤|Û)Šö”d¼›<[}¼ô,ˆÔ`Ëz¬HÌ3^m”øýs-?û®å„CÏ•‰ØgE«Ж§ý„Cþ¾N ù™4•˜> 20%IiM–¤)l±$C²@…ă”,<L±±2%5ÑsëáH|˜†)Y˜æ:°·µâÂ}Kaާ]ÎH|r*fR&¦R&q³p·3aæ’ÍÄ>ÌVûb%¥c.Wbš•§š}¨þç…t]Úø5"ËÏQÇUE•J^th^‡/;½Æ‡ß&‘†¹VÓïÌ:CC㠘㣃 ìdIRÙh”Ûy.‘È‹Ñx[=¦~ŠÔ©Q™Q]ê14KÉÑk)LÞv3ŸßÆ‹qå~•p³5aþ–“DÞ¸‹©‘ŠÅ£?@’$L¤,ŒeÙÏÕµ ]²ÐHKQi¦Éd*ä’R§~ËÄ”B“+¦i~iZÅ3c—ï+Z—»žNëd¤ª,P!‘JSR°æqî?` ä¨Èñm×¹$ü}\ñiô—&â÷–G"¢PI2d¹éàÛË»n!)ÍÞÊ€'#Q!C.Ahx<#[»ÓÁ·!«þŒDž U=hÛð5B6…!—‘§Éé lÍp°³FŠ—!!{!>I’éÔÆ ¿×=fDø½;¤’D‡æ ÈÊäuy —²« @ûŒò¶Ò KéÙƒîrnêx±ßïª\IM}DôÉXöœ¼…« jTäÍšñ”ßç¶ÒMëø¼`ï¹>?él“¬$LåtnQS]T&IÈ%ž«k„ yþièÞo’ª3·çbªähÆŽ£78sùÉ)ɨT­’‘%Y…”¦¤K–ZûôU§¨—CæÖ µ§kôZÊ/\§@›…ÖžŽwȲ³@ŽNJ@¯•‰l|"öyÅ«BÍèóºŒ~Ú¿@¿'ûsGë°'Ÿ› >Z•„]V´FšL’´–Ϲ)  _%âU/Ì@ŸdinH’:qýñ8eɼSÛƒŸêT#6EÁê}W9{ú 0G•«Ï]¹É”žµq²³æÁÃ,Vî¹Èùs×x¤²D)É=qF,z2spkTHœ‹IcýñÛdI¦$çZzÞŸÞgpsG& Ê9)ë3çü‹AH’Nmü~6‘!-+ðº{M²²U\¸•Ä_ÿÁL–‰…2ƒ´ßz}OåòâåµZº=sÒUæÄ©° ƒ¸¤GÜCã_ ïÅu1…‹æ+5.¢N»9S«N=}ûYæ¹x6Bß.V¬¿®!ö/Ü-S«N=!b:ðFÝ7¹p派݂Ú(ìÀÆÖ°OĦ$'—ÛS’Kî1ÌAyG}18}"Lß.”*z|į›×ëÛ"û.ޏ‚Ä%#­„‡‡ëÛ…WÒw 4B/Žz@ 0p„Ð #„^  !ô@`à¡/' £oD¼A9¥X×ÑGGǰbÕ*Ξ=Kzz:¯U~{ô¤E‹æúŽ«Ü1,p ?|³Pßn¤È3úÛwn3~ÂÞ¨U‹¾ûŽÛ¶2røpöدï˜Ê¾œ„B¡ÐH[úãOÛY ¾˜ÄÃÔÔ—*ò%=[¾{Ÿ¥?­düÄ/1f<³Bp*âÌK‹G äO‘gô«×üBçNèÞ­«:­FLþê+õvVV?þ´‚ýàëãà066 í{í9b¡¡¡<ˆ‹ÃÃÃQ#¹sûë7läAÜ}ªT©Âø±ãðòò,r]ü9’7’˜”H•*U3j•*U*rÇV®ôgϧþ›9ˆ{”–Æ™sH}ô+Ëœ×ÔEœ9Kå×^ÃÚÊêåŽz rÿÁ~ó-mÞmE®]°±¶&&æ6{þþ›úõêêÛ=@@1„>""‚þ}zç[fÝúõܼy“ïÀœy!¬ß°>½ŸÕ;~ü8³gÎÄÞÁžmÛ·óÕ¤ÉÔ­S‡Y3‚°³ÏI[´øBæÎ-r]ü8y2œyóæbgkKè–­,úf1 Ì/rǾդ1GŽS ýõë7P©T\¿qƒ:µs^,},ì8-šç,så^ºÉÎÎfóÖm„Ÿ<\.çÝV¾¶ ›·nãä©uþ¶¿©ë«T*víù“#G‘žžN½:uèÙ£+¦&&êÙüÓÿ‹{$ñûÎÿáëÓ‚Ö¹|¬T©"ƒô×ðwëŽß9yê ê×§kçŽéo~ñ‚‚)òÒMJJ Žù¿Vë¯}û6l(NNN8990l(íÛ§QfÌèQ¸WpÇÌÌŒ®~~¤¥¥1:07÷gi‘—#‹UG?GŒÄÍÕ333ztïÆÕ«W‹Õ±uÞ¨ÉÍèh>LàÚõ©U£:×®Ý )9™˜;w©óFÍêîÞ³—Øûq|õù&~:Ž —.käïúßâ™ôžøl‘‘šoCúkÿ¢¢®2zäp‚¦NB¡Tðû»€gÂþÃ7 Kd¹(òÊÕ¯Ÿo™]{ör÷Þ=&~:މŸŽãöÝ;ìÞó§Îñæ@ (˜" ½ ñqù–IˆÃÝÍ]½]¡‚ñqšuÔßMMs^ªmï`¯‘ö83³Xutñ£ 6 ݱr9 ê½É‰“9³Øë7®Óáý÷¸v#GèÃŽŸ Á›o"“Ë_¨{ìÄIzvë‚­-öv¶ôêê§‘üä)ºûuÁÖÆ[[ºwí¢‘øÈQ>ìÙ 'GG,ÌÍéÖ¥3§Ï”Κù£´4líòÂåñðœxìížÅ~Rçx_f<!R䥛zõê±ÿŸø°W¯<Ë88:q÷Þ]*z{pçÎm^þ‹½õåGÓ·³fí/ø´hÆ£ôt*WªDÚ£4 GÃN0°_­õ’“’pÊ埳‹ósùÉ89>ÛÙ9=K|B"Sƒgi¤I¥ðözK ‹œó,““¯OrR’Îñ¾ÌxC¤ÈBß§÷'Œÿ)&Æ&¼óN lmm¹~ý:7oVŸmåëÃ?,aü¸±|¿d)­|}_zúòÃË£GÃŽóšwE gýzÿ?‡066Vç?­qqq¸»¹÷ î¹|[ââpsuÉÉþ(ÉÞž‘Çà˜ëÈ'7%)’Õ«UãäéÓ´kÓ:Ï2¶v¶ñ<¸ÿ[;»\ùùÇ[P< мtãQÁƒy³çpîüyü‡ ¥³_W÷=-}|Õe>þèc¼¼¼HÀÈ@*z{óч½ô õéÇ[Mš°ý·ß©Võuª½þ:¿ïÚMÓ&ó¬Ó¸a}B·n')9™¤äd6mÝ®‘ߨ~}B·m'9%™ä”dB·iæû´x›µë7q76–ììlîܹËO+W«ó­,-¹["ñu|¿8È_û˜”ŒB¡àß›·X¶b¥†¿›¶l'1)™Ä¤d6mÝFãoêoAñ‚ü)Ö SÞÞ^L™<)Ï|c†#`ø0­ù{vï*tZQê””E¡QÃúlÙñ+UŸ}ÕªUÈR(hÔ0ï˜íÛ¶aóÖmÍœƒÜHNëV-¹ùìärû÷Ú²)t+Ógääû¶hÁå+ÏNû¾ó’$cÙ+ˆ‹OÀÅÅ™NÚ«óÛ¶y—y ¾&==£Ø'd]œ=r8¿þöìÞMffžž´}·•†¿[·ÿÊìy9W1Õ³ïµk«s¼Å#òGªØ&@åÓ{&ÑqH»c³ÚˆwÆÀÁû8¶Ì¼}éö;,Y¾‚ )_ߨÂÃÙ>g~™‰±(¾‹7L ^U¬€…Ke’ž-žuS^Ù¼u)))Ä'$ºuuëÔÖ·K Œ"Þ[Nqrt`vÈÙÙÔýOm:ux_ß. ‚2ŠúrJKZúøèÛ @PK7@`à¡G½@ 8BèÀÀ×уZuêéÛ@ Ð@’$šLÜ£q½¸ê¦ˆ¢@ (ˆ¥@ 0ا5]½@ 8BèÀÀkô@^‡kÀðiáÓ²À2Bè „¡cõí‚@ xɨT*. Bo@¨T*}» ^…¹êO¬Ñ #„^  !ôJxø š5m‚»«³¾]zF½4}_MšÌÝØúvE è…¾í{íùü˯´žðkûžxQsYãÒÅ‹¼Ûº¾Ý(4î®Îê@ ( 5£·±¶æ×ß~Ó·Ïxøð!&&&úv£ÐÜ} ŽB‚¦PB8r¿þúÑÑ1y–‰¹}›éÁÁtëÑ¿®Ý˜6=ˆä”u~Û÷ÚóÛïз_ÞïøþC†rþÂöìÙKÿƒèØ©£ÆŒÑhC©Tò˺õôéÛ®Ý{0ÁB222ôÝwe–§³áÜ3cwWg–-]Bý7ëRÁÍ€ë×®1h`jV¯Fµ×+3 ?4ìü¼j%M5ÀÛÓßwZp<,Œ6Ьi*y{Òñýö\ŠR×Q*•|½pÖ§FõªŒHZZš¾»D x¥)”Ð[ZZ2*p$³çÍ%[¡ÐZ&(x?ø€u¿¬eíšÕ899±bÅJ2ÇgöÌ™l ÝL«–¾|5i2‡aÖŒ B7mâ­&MX´øuùmÛ·söìYæÌ™ÍêU+Q(ü¼z¾û®ÌòtFüüìøè‘#ìÜõ?îÜ»€ÿ ô0ÓgÎ~*wwwfiØúóϽlܼ…ËW¢ðëÖO>þ];ÿ`݆M\¼|…6íÚ1aÂxuùåË–räðaB·n',ìYY æÎ™­ï.^i }2¶N:¼Y·.?¯Y«5éßS·n]LML°´´¤_¿¾œ×(3fô(Ü+¸cffFW??ÒÒÒˆ›û³´ÈË‘êò;wíbĈÜÝܰ²²b°ÿ :¤ï¾+w͘›››zû¯}hÖ¬9fffØØØ0ñó/ø{ßßuBæ/¤R¥JXXX0xðRSS™2ŸŠ+ªÓNŸ:¥.¿vífÍžƒ··7¶vvL™:?~ÿ]ß¡ ¯4Eº3¶_ß¾Œ3†ÆQû74ò¢®D±|Å ®^½Jjj*r™æþÄÁÁAýÝÔÔ{{´Ç™™êíû±÷8È_ÆL&.*,žÛg""šÎ¹óçHNJ@.—k”quuU777ÀÅÅE#-÷2ZLt4Í›5Õ°!ÆJ Ð/Ez###>ýôS‚‚ƒùæë¯5ò‚gÏ⿤/¿ÀÂÒ’´GèÖ£g±œtqqaÆŒ`Ür‰Ž ðH’¤±=tˆ?cÇgùO?ammÃÇ)Ô¬^­Xmxxz²~Ã&¼¼¼ô®@ xB‘§Z½½éØ¡ßýðƒFzFF˜™™ñ 6–…‹ÛÉŽ;ðõ׋¸u+…BÁ7˜9S¬û—´´4¬­­±°°$&&†ñãŠÿ`´¾ýú3~좢®••É¥K—:Ø¿ØvAÑ)ÖCÍ:wêÄ_MÒH7z K—-#xæLìéѽ;‡.–“;uB&“1-h:÷îÅâééIß>½õÝwåž 1eÊ$ûÂÅÅ•aÃнž>pà d’ŒýûqëæMªT©Â„‰Ÿë\?÷õóO¿‹Ë-‚â!^n<°¡cÅÓ+‚Wˆ‹g#¨U§ž†^?Õ‚ç_.Î’ #žG/xiä÷X±<#”Bè/ !æ~K7@`àˆ½!N¢ m¡7Ä7 /„Ð-|ZŠÙ¼@ ȱF/Žz@ 0p„Ð #„^  !ô@`àˆ«n €ƒöéÛ@ 'Zø´,°Œzah`ñŸ%/Ê*•J§K«…Ðâ¦)àÕ¡0÷Έ5z@ 0p„Ð S¢Bßö½öúŽG Ï!fô@`àêdltt +V­âìÙ³¤§§óZå×ø°GOZ´h®ï8ÏáîêLµjÕÙÿÏA$IR§«T*|Z4'*êŠN/ÑöV(ñ |¡³Ðß¾s›ñ&У{w† ‚½½×®]cSh¨ú2й…9{÷î¡mÛvê´ÿíÞ……¥E¡ìaÊ7:/ݬ^ó ;u¢{·®¸¸8cllL5˜üÕWZËÇܾÍôà`ºõè‰_×nL›DrJŠ:ÿtDÃFбS'=ð@Õ€IDATz÷éˮݻuÊèN@ÀH¾]üFÚ·‹3bD z»Kçؾ}›F™Û·c¨W§6)¹ÆKî®Î,[º„úoÖ¥‚› ׯ]cÐÀþÔ¬^j¯Wf@ÿ~$$$hÔùyÕJš4j€·§¾ï´àxX7l YÓ&Tòö¤ãûí¹¥®£T*ùzá7¬OêU3:´´4}w¯@PnÐYè#""hå룳á àtþàÖý²–µkVãääÄŠ+ÕùsæÎãã>bÛ–-Ì áò¥Ë:å t§CÇŽÄÇÅqâÄ Ž9Lbbïwè .3zôX„„ T*Õi BBä?›Û8zä;wý;÷îà?hý äô™³„ŸŠÀÝÝ™ÁAuþüs/7oáò•(üºuã“?d×Î?X·a/_¡M»vL˜0^]~ù²¥9|˜Ð­Û ;AV–‚¹sfë»{‚rƒÎBŸ’’‚ƒ£“Ά—þð=uëÖÅÔÄKKKúõëˉðpu¾\.'>!ž¤¤$\\œ3f´NyÝ‘Éd ÀwOfõ‹¿YÄð€ÈdφݷeK,--Õ³úëׯ³oÿ>òW—qwuÖøä&hÆ ÜÜÜÔÛí;@³fÍ133ÃÆÆ†‰ŸÁßûþÖ¨2!•*U‚Áƒ‡ššÊÜùT¬XQvúÔ)uùµk×0kö¼½½±µ³cÊÔiüñûïúî^ Ü ó½ ñq¸¹»ëT>êJËW¬àêÕ«¤¦¦ Ï%0S§Lfݺu¬Y»k+†J£F ÌŽž½>$dÞ\¶mÛÊ¥‹ùyõÚÊŒ3†à étîÜ…¹s‰¹¹¹:?¿5zOí3MçÜùs$'%9;îܸººª¿?mÇÅÅE#-##C½MófM5läÞY ‚üÑù¯¥^½zìÿç ÏžE›Ö­ùyå víüƒ-›7‘ky êë¯3eòd6oÜÈСƒ Y¸@§½?aÛŽlݺ¸¸8²²²ˆŒŒdzp°ÖòXXX`ffƃØX.Z¤‘?kÖlnÞº¥Y.WòËž‘£ˆ¾}—#µæK’Ĩ1cùþ»o=vÆÆ&…láiiiX[[caaILL ãÇÿak}ûõgüØ1DE]!++“K—.1t°±í ¯ :/ÝxTð`Þì9¬\µŠ5¿üÂãÇ©\¹2½zôÐZ~Üè1,]¶Œà™3qt°§G÷î:tXÿÖÛM™>=ˆØû±x{y3ñ³OuÊ”r™œÊ•+Ó³g¯bÙY°pS¦Lb°ÿ \\\6< ØëéB&Éп·nÞ¤J•*L˜ø¹¾»L (7HÛ¨|zÏ$:îi÷¯slV›B=M ØÇÐÀ±ÅzzeßÞÿ¥K×®øùuÕw8@.ž VzzýT šL܃…Ke’ž-Süª£T*Y÷ËZ¢£oѹs}»#J!ô¯8î®xyy±üÇâJÀ@BÿŠ#o >b 'Ž˜Ñâ$º@ ІzA¼/V ä…z …OK1›y"ÖèÀÀB/Žz@ 0p„Ð #„^  qÕ ÌqðÀ>}» ”Zø´,°ŒzA™dh`ñŸc/:*•J§K«…Ð Ê,â&0 o sïŒX£G½@ hÁÝÕYß.”¹tÓö½öìÙ½«ÔÛY¿a/^"hú´bÛúrÒ$êüç?ôêÙ³Xq–—ÑO@¿¤Ð¿ 222غu_½ Dì <„qãÇÓ¥KLMŠþrî˜;wu.ëYÁ½ÔûIðrpwuÖéݺ–: }îÙ¢$IØÙÙQ¯Nüýáää¤ï8^:‡¡V­ZxTð({^^žT­V•#GÒÒÇGßá<ÚËËšº»:S­ZuöÿsI’Ôé*• ŸÍ‰Šº¢öYWßËRŒåa …BÍèŸæ+•J“Ù²e+3gÍfÁü}ÇñÒ9vŒwÞiQ¢6}Z¼Ã±£ÇJUèÌá­¦Myûíf¥ÝEežò *ææìÝ»‡¶mÛ©Óþ·{–úv­D(c`éd¬L&ÃÑÁ‘O>þ˜¨¨(uzÌíÛL¦[žøuíÆ´éA$§¤¨óOGD0<`;u¢wŸ¾ìÚ½[§T*ùeÝzúôíG×î=˜¿`!yúÍÏ«Wóß>}ðëÖÐ-[µ–+ŽOùåE]‰¢VšmC~öÞ¨]‹ËW"Km°¿ûv1W£¢¨^½F©µQZ¸»:óóª•4iÔoO|ßiÁñ°06nØ@³¦M¨äíIÇ÷ÛsõÉï±Kçؾ}›†Û·c¨W§6)¹Æ?¯¶–-]Bý7ëRÁÍ€ë×®1h`jV¯Fµ×+3 ?Šìäü^¾^¸€Æ ëS£zUÆŒ$--M×€€‘|»ø´o/fĈÀ|øl§lX¿^#oýºu|6áSrO¿¯þyÔWûwùò%Æ£i“FDF^VooÚ¸Aý=2ò2M›4*Зò2†@‘„^©T’˜Èú›¨^£º:=(x?ø€u¿¬eíšÕ899±bÅJuþœ¹óøø£Ø¶e óCB¸|éÙeÛöíœ={–9sf³zÕJ ?¯^“§7mæÜù Ì›=‡5?¯".NûÌ 8>å——€ƒ£ƒF[ÅŸ=GGââKe W­\Á­[·ø~ÉRK¥ÒæÏ?÷²qó._‰Â¯[7>ùøCvíüƒu6qñòÚ´kÇ„ ã=z, BBP*•êú BBä?›Û:zä;wý;÷îà?hý äô™³„ŸŠÀÝÝ™ÁAEö`ù²¥9|˜Ð­Û ;AV–‚¹sfkØìб#ñqqœ8q€#G“˜˜Àû:hõ;xÆ 6n\ϯ;v°cÇv6mÚ@ðŒ™ZËïÛ·­ÛwpñòZ½û.>.ø¶lű£G¸{ç_~ñ9©©©ê¾kÙêÝBûRVÇÀ(”з}¯=mßkÏ{ïw ×dzsçNF¨ó—þð=uëÖÅÔÄKKKúõëˉðpu¾\.'>!ž¤¤$\\œ3f´:oç®]Œ€»›VVV öÄ¡C‡òôeÏÞ½Œ> ÷ îXYY1tÈ­åŠãS~y*^¼™§ ò³WÒl ÝÌ;·8}ú«^EðŒ¥ÖÞË dþB*Uª„……ƒ!55•¹!ó©X±¢:íô©Sø¶l‰¥¥¥zVýúuöíßÇÀAþj{î®ÎŸÜ͘›››zû¯}hÖ¬9fffØØØ0ñó/ø{ßßEö`íÚ5Ìš=ooolíì˜2uüþ»†M™Lưá|÷dV¿ø›E L¦ýO×ØØ„eËbFðtfÎffpË–ÿ„±±±ÖòsæÎÃËË † àÜÙ³:…oË–=r€-[B155eÇŽí=zß–-uò¥<Œ!P¤5z€¤äd¶oßÎw?,aîìY@ÎrÆò+¸zõªzï.Ïõƒœ:e2ëÖ­cÍÚµX[Ù0|ØP5jÀýØû„@ž?f€¸¸TÐáDhq|Ê/ÏÑÁ‘øøx*T¨ ¶UP ùÙˆOˆÇ¾„fÛë×­ãó‰ŸñÑÇŸpëÖ-FŒ ÄØ¸èWó”\]]ÕßÍÍÍpqqÑH˽T6jÌ‚ƒ¦Ó¹sBæÎ! `¤ºä¿>ìáᩱ}&"‚à éœ;Žä¤$ gÇ]ÿb¢£iÞ¬©† m¿ùž½>$dÞ\¶mÛÊ¥‹ùyõÚ|ûÉÙÙ™î=z²`~S¦NÃÙ9ïëÁóó/?š7oÁ—ŸÀÖ-¡|½h1ß,ZÈ'Ÿü—“á'Yøõ7:ùR^Æ ¼SäˆìlméÙ£—.^T§ÏžE›Ö­ùyå víüƒ-›7‘ëйêë¯3eòd6oÜÈСƒ YøìÒDVÿ¼Š=»w©?»wþ‘gûÎN.êk~ǧ|óªUåÂ…‹mC~ö.œ¿HÍjÕJd`C·nãïý¸r%’ÇÒñƒN%b·<Ñ®Ý{˜3sF0áá'èÓ·Îus_å0tˆ?={õâXØqbîÜãRä²³³‹åŸ‡§'ÇÃOq7öúsûnì åLLL8ÈŸÀ òŒI—ß^¸põë×±bå*–.]Â7J¼o---©X±"¿îØ™™9­Û´A¡Èf÷î]êuq})KcPÞ)²Ð§¤å—÷V“·øç¹¥¥‚bÈÏÀÁC‡xë­&%4´àééÅÚ_Ö3jô˜ÅÁ‘$‰QcÆòýwß2zì¸bѤ¥¥amm……%111ŒWü‡®õíןñcÇu…¬¬L.]ºÄÐÁþZËŽ Eôí»Œ˜¯Í´´4F ãûï—ÐþýÌ™;Áþuž©?O~w‡¶lÕŠ)S&Ñ­{ºvëΟO¤e«V¥â‹¾Ç †Ž-‘§Wöíý_ºt튟_W}‡UîèÞÕ1ãÆÑ¬Ys}»¢Êú]ÄÏFP«N= ½~ú·Ódâ,\*s7,”ô„hñ„âða¯âÍsS; 5xŠR©dÝ/k‰Ž¾EçÎ]ôíN¹$të¶â” „Ðeqv®/<Ü]ñòòbù+ ò*  0¡$eù[P>0¤ß˜ê#fô‚2‹¸(@ („Ð Ê$â}±AÉ!„^PæháÓRÌæ‚D¬Ñ #„^  !ô@`àü:ÿÄw©­7…IEND®B`‚wxglade-0.6.8.orig/docs/html/pr01.html0000644000175000017500000000525612167336636017706 0ustar georgeskgeorgeskPreface

Preface

This manual describes Alberto Griggio's wxGlade program, a Python, Perl, Lisp, C++ and XRC Graphical User Interface (GUI) editor for UNIX and Microsoft Windows. Each of the chapters in this manual is designed as a tutorial for using wxGlade and a reference for widgets supported until now.

Contacts

Check the project homepage http://wxglade.sourceforge.net for the mailing list to discuss the project. Use the lists for questions, proposals, bug reports and collaboration. Information, support and bug reports can be addressed to the wxGlade mailing list too.

Any kind of feedback is always welcome.

Marcello Semboli has written the original version of this document. The current version of this document is maintained by Carsten Grohmann.

wxglade-0.6.8.orig/docs/html/example_eventhandler.png0000644000175000017500000003216012166606326023123 0ustar georgeskgeorgesk‰PNG  IHDRzÂGN <sRGB®Îé pHYsÄÄ•+ IDATxÚíwxTE‡ß»› ©”ÐBG@T$”  &¨4 % EP@©ÒáS4€B… ب*M@z/"jPz‘P‚´ÐCHOHÛýþY²d7»!›BrÞçá!;sïÌ9S~wîÙ»sRµå-‚ B‘áêoß+V"ïÕsŠ´Š Bbh¯þö½¢dˆüèXiA„"Ľ?“x?,}E–” ­"‚Py$ôÉy,ôš4bož#)ê6Ú´ÔŸ®¨ÔغVÀ±b]P©¥ç¡¨bi­(ìÚ“öeZÑÇgÉ´žØï‡Þ&˜]ypp0)Þâþ wþC‹– M|±²sȱ3©â¸îob®Ÿ¥d¹2¡ˆbi­(ìÚ“öé„ÞЕÄ|øw hvåìÊTfr\$·Çú °±w LÝW¸ùÏ´iUd6BÅÒZQص'?ì³Ê´þ·|e.S{Ç\g]Â)½ ¼°U„Â¥µ¢°kO>اzEQ,o¦2E…b‘2Uyb« …Dç-¬…]{òþlWôÁ^^z{§ÿlVèfâÄ`Òƒ>Á4›Ð:SñjTFŒØÒ¿t–´ö #ŒÜ$¨‹íŠ~_àË4< j }St…>­Èi9(*ƒåÒS”WÚ“}†tÐX^vöe»¢÷ööÖ‰{`` ™BÈȾþŠ^¥ÎÑU«Lêu"¬Ü 6б«ÖÞ /é}NNÕp+*‰]'ï±bÿMRÒžŽÿføñÊăóëÙ]'4©òS5yMùTØÊ~Ò2Íí›ÇÇj^´ËÓ,ôŠ¥ÊQ”'.ïq ÊN{òÊß-ýKÓ!“ oÎtʉ}ÙÇèµ¹öàÑß*Û°©_ºÑˆ têu½¼Eƒ^Ôåé¡R™¼ªöZ €sI;º¼ñ"ý_¯Ly-_î¼ÍÓ´Ïó¶× M~ôåÊ+“ÓÄî<¥Ô©¸¨ˆÒ8:›+¸Øòæó¥iù|izÍ;eÒ§¼l¯‚(³”:ά¾yeÒažµ¹ÆÂ€ÎëYúÁ üv:‚ݧ#¸•T¼”Þ€VEÓz•ñ~®,+?EXªÖ€Y;¯òN³ ”u²áÕÉGP)àÛØ ߯n”w¶åNt2ÝeÝ‘;h^!ö><÷óM—y·Yy*•²ãfd¿¼Í–ãáìÚ7,‹“rTrµånL2kßaÃÑ»º‹Í^vdö,C^™|$ÓñžôžºEQLÖñ\%¿éNÍr%°V+œ¸˪ƒw8ô_´ÅÆi©’Ö¼^¯o>_ŠçÝHJÑpì¿{Ô°¹Í¥” :? ùdªÆ´¯N»e˜µó*ëŽÜ kÓr oU…­ÇÃññ(k´lS¼^¯o¿\ž*¥íHLNcÑ_7ÙüOx¶öî52vô8ŠYó)Rã¨7f]Ôñº ÄÕˆ¼ÿj¾îΙë±ì:}Ÿ?ÏFr?>¥è¯è³ÑŠœ–“>O —§€QÝÉÈÏ|ž9ÚcI}¸Ï†~¥ôÅ}çÐÙ®2௉Ðe®TážÀÀ@~ÏTfúm…1G1;/½S¶*Ü׺¥q¤tÚ£¸©£¸§qÕ}nZ †/<Œ}ê}êÙ¦ò|ƒ& oU™-G®óå¾Óø¿ú #Zפ„*™e‡¢õî:>oÏø•!¸(1ô{ëE>ñ©†-I¬ ‰ S£²|ض ž¾ÃôåÇñiZÿµ­ƒI¬<£çTf;¬•T|ìÀ'Ó“¨µ¥ž-¡)UuÇÛª4D§9Ñ©±é:&øÖ ¢«-³Öå•[T«à»MëröÊ]â4ö¹êë¶/–¦ås¥hTÝ‘äT-Ç.ÞãÛÿò參hR“)©Rá¤JäÕÏñ÷§ údªfî £^[†·ªÌí»÷‰Ó–`È›•ùïv,ÛßÇÒ%X=¦U¶íeÿ&nŒl]™.Gòé!5 Ÿæuù[Ÿ­½ÆÆ4ѽŒ/MqGSFoÌf>oüºK¼Xò:k”¢~Ýj ~í«pìr ¿‰dljˆ¢ºQ,UŽÊhy¦®ÇO¦=–õ×ïÇû¬ï[J÷¹ßüô•ü}«ÊY. ÙÙgñ}––ÒaüvLɦúÇó•Ê´­O*åhÃ7+püÜU¬”4¬•GÏöÿ±÷ ΩVDkJ Q)ø5J¿j¥ô>ÿ0ðEüºoð~';û,¾¢××y•Y·c ŠÙyŠbúª:í£÷€ô/cïD'³úï‹=rœØêÿ€x­QZgÓJPÖÙ€´„”ÒÜŠwNVÇTPG¥uÖO¢Ö…X9Y"=Ìäì@%u81Z'*º¦ P`ÿ¶z¶•uu¤¢êÑ™Dèq;2û~_ãJ”Ö1K›(¨ÌªcþŸ7þf>ìÙVËÅÛ ,ü3ŒÿÂnc«¤’еé8µõUÎ¥VÏ’´õ^°Å³nyÖjÉKwÙz—ýÿÅ‘jK VhQô'Ëc>™ãÃ…H~ ¹EÇ—ÒWÔ¿ú—ø¸¢µÎDgj›ÇËÎnNº9¥ûA¼Æ‘­+ Z;J(‰X)Z“}]Ÿ)¨r<Ÿ —dåJšUyýYGšÖrÁÆJÅù«·9z‰šV78ú ÉZ+ ÝdSNú#‡ÆB7J¶õ<‰öXÒß5}-Ì?É‚õuâßå§H£þèŠÞÐ]E⚦sÀPžá/²·5`Æ´v<Àö¡“i€-QGR}a‹¥$”hQIÁ½”-N¶ÄEÚcbŠŒMÀ–l3Ý ¸:;pænIâ±ÇÝ%}‡’Œ­’̽Ø*¸Ø0eÞîĦélqP±Wk°MK1jG–e†—#æÔ±9ä>çΞ¢~9-5«U¦Ý+õס:oEö‹~mê [ŸÁ†tK©ÀEK”ÖIï¸í§"96Œ*I4¬[•úuk0¢S>HÑpà¿Æo¸j|©ô°bs|p/ëLÛÆ•¹‹ o4ªÉ±³W¸tÇžxJš×^q7&½Þ2.%9בxJ’†ŠC>#eæ¸ÏÌYÕ?™ò¡¤­šI¾ÕÐhá§Í°VÒõNKúu|‰%¡h“¬L·—V¹Çˆ–éТ v\!5Ɇw›•ãû?nek¯±>{¼o̱lΫVÚŽM.sâÜe¢c¢Ñj!M«"E)A vÄklITJ漞§%FÿçeÖŒ,1zÇÏPß¼ko~Äèä \pR§“ ÐmQ$«н1s½¢7öýÄ+À{?‹ÑÿD÷ÅQ¸¤„é_œÅàñé? PLvO„¶T–h–ž#ã’ž¸òð=J«¢yíùJüX¿6wbRYúçENÿ—xìÑfjÄSÿ^eB×ç)ãâHxl ‹våô©ÿˆ×–D£¨X{,ëwðiìΔo¢EáÔõV¾AŠbKt¦0Ðãvüø÷]¼Ršû¥)ë5í´!U0«Ž­'#Ø¢"µ*ì­WÏ{?]ä9õ´(¤h­IÆ–ÅžXM ’±E“Q~ü‘¸!­0¤YÆiF†VXº¼üôW¥(DYë?]“9Ï\ûò1FŸ}Ô-ÚÀÊ^1R¦1[½¿ÈéØÓ…-q¦$ Djõį́'‚ÒE_Õ ­¤-¬ù¥=…Å_ƒ“ŒW ^½s+O;/96kE¡¼{-lžÀ¡”äDn]¿HŠVÁƱL Âàê0s¡š:&ÅD(Ø~2¸šžq¾ÈÖ]°´VvíÉKûîÝHâý°GBíîí<í<-Râ"I} Ú'؈@QaeW›’¥ |S³†ÊqlH&T[W„¾SGù×hÞymí"[÷ÓŽ¥µ¢°kO^ÚwûÈýwÆæµx*¨°q,‹cÙ§~ ÞÀ’Ä?¼M’½ñ +Q¸¦÷“ÒÃ#.E²î§KkEaמü°/Ëî• w/ÉH3Á•‡Ý‘ÿ …»Ÿ ‘·}Wu B ·†…>Cäê^VZI(6Ô«ß Èûxödˆtt1£ÏÊKzbo%M"g‘/"øÜ‹œ9q\:¼cPèœå FSÄDGùv*>uþÞóçS=§c¢£¥óBèœ9~ä´Œ :téÎæ5+Åǧ÷ªÕ‹Íx}Zçt‡.ÝånÄÈ##OÀÑ£GÅGA1(B/‚ ˆÐ ‚ "ô‚ ‚½ ‚ B/‚ B/…€AÃGI#HŸ y€ü2VÈ×I?÷›YOÝ­Ú´5˜¾kçŽ|©;?êDèrûÎ]6mÝÆ… y”D¥Jiýæ4lð¢´l!6KÙõñ¸Ï˜2qVV†Ñü~d`¿¾ºÏ)©©Œ?‘ÏÆ~’¯maé¶/b+óY„> wÃÙõÍw´|ãuºøuÂÉÑ‘ë×o°ë?d`jT«ÎÉS§i葾1X|B'N!.>‡’é/g9q’Õ«ãèàPäü¥Oß~,úéG2ùKßþøé‡…”(Q‚•¿¬â×_%.>žæÍš1dð ìììt+öáÆ±jÕ*"£"©Y³&£FŒ Zµjº;‰Œÿ3.6ÇCBX¸ð®…]ÃÕÅ•=ºÓ¶M›\ù"óY„Þ [·ÿз׫¼ùº·.­Zµª èó¾îsjj*ë7måØ?ÿШaCü:úèV€ƒ†¢{×ÎüöûŸDFEáæV–ݺÎÎ]»‰ŒŒÄ½²;½zt§|9·'>Ç<;º°k÷nbbbq¯ìλݺR±b…¸8?òAoìû‡Î¾pvrÆÙÉ™Î~ôò÷í?ÀÛ]ý)Sº4%ìíñïÔ‘ã'N䙯»vîÈò rewªV­ÊßûÒÅû¯½{y¶^=ÜÜÒßëp÷Î]úö믻8tëÞƒð{÷ôÊv-åªûÛÖÖ–¤äälm œ0ž Âû}úqäHî÷„±Ä|6Õ§ùÝg‚B7%K” :*š2eJ=&=ÿÑËj˺•%:*Jï'g'Ýß6o᜜ôÓRRRruŽYv˜¨ÓÒ\»ÆúÍ[ »NBbbºpª]wÛ¶z“ ›¶ÒÈíÛwÒêÍ7t¾šãO~ñòKž,ûy9^¯6'>1‘Õª‘Ÿ@jj*¡ïû½Œ¨,>d;¥Ké>g> â~$ŸOÕKËxKZ~ãçë˲e?ãýš7ndØÐ¡º<777¾øâsÊ—+÷Deòé™Zµ˜0~‹¸¯ûžåÞc«àR®® <Ò¥J™-yE£† ™7›6oÆÞΞZ5kêò||Ú1{ö× 4ˆŠ+ÆÊ•«;6À¼±ëäĵkaT©RY—6uj=ÞéA¥ŠÞ–çþç0–˜Ï¦úÔTŸ …0tãóVkþØó7¿ÿ¹‡È¨hRSS¹rõ ~Z¤;¦IƬ^·‘Ȩh"£¢Y½~ž<òÝÉÂbGf’““±³³ÇÖÆ†û÷#Yþ˪,BÕ¶uKvýþmÛ´D)üaÊŸ*U*óÛ’”œÌ½ˆ–ÿ¢ÿ}ƒCɒܺsÇb¾¼Ô´)·l¥ö3µ¨]«[wìä妞FÏñlܵë7MTt4«×oÌÒgk7l$:&šè˜hÖnÐÏ÷zµ?¯\Í­;wHKKãæÍ[ü¸hižùh,FÿhU߉¹óæÓ¥Kg½ôŽ:ðòË/1qò$:úúôåt¼[x™]o·n]1j”^}/5{™I“&ÓÉÏ%K–ðÉè\ûg‰ùlªOMõ™PWôneË2rØ`6oÙÆ¶;INNÁݽ­ÞxýQø¡M+ÖoÜLÐô¯hèÑ€6­[廓i‡¡_Îýf=»¿ÍÚ Y¸h1.NN´|£ÇCNê_…neËòR“&9ò§G×.ü¼j5¿îÚ““#­Þ|ƒ“§O?­–o0}ælXäËÊ&²nÓfžy(ôÏú’Òûµ×P ~ø‰{÷qs+K‡vmóÄGsž¡oÛ¦Á'_T*;t c‡f—9ÍßÏ??½ü^^´ðò²è8µÄ|6Õ§¦úLÈ;”ª-‡h½zN!ì^8 w/±öƒZò†)=z”IÓ¾Êó·/Í]ð5¤I£†EÖGs¹qó&óþÄä ŸZ¬Ìöß.òïŒý{ÏŸ|0üOå›Â2Æ ¼a*çôYN ·Ü:´–Äûa²×MaD«Õ²wÿîÝ¿Oã†ŶÖ¬ß@LL ÷#Y»~/Ö^‡ ägèFÈ;ø¥K•b@Ÿ÷ŠõS eJ—"hÆLRÓÒxñ…çéÐî-‚ B_4x7þÊ ò"-Å Ý‚ ˆÐ ‚ "ô‚ ‚½ ‚P0dyŽþàÔ–Ò*B± ¨?CŸ™zõH‡QWšìÒ{ŽÞª¸OA‹šPÔ‘Ð Báï=ŠÐ ‚ ÈŠ^A¡ADèAzAA„^A¡ALc‘mŠf漂ÍuçG=‚ ÅZèóKÔA„œ“§¡›ØØXºtíF\\\–ô®ow'..FÃò+éÕû=ü:wá«™³xðàÞŠ}ë¶íôìÕŸ1jW®\Ñ»“hÕ¦­Þ]ÅñŠO‡ôìÕ›;wJO ‚ BŸ8::òꫯ°}ûv½ôí;vðz oذq#'OždÚ´ –.^Djj*K–.Ó;þر£LŸþ%kW¯¦Iã&|ýÍ·zw»vîл£˜öåtztïΆuëøjÆ Î…ž“žA„>·d¬ª3ÿðíäËæ­[IKK --mÛ¶ãçë§ý¡C‡P¡|yп{÷îÕ+{øÐa”/W;;;ºtöçâÅ‹ÙÚ¢V«‰¸ATTnne5j¤ô´ Å–Åèß0gà°Qº]ñŒÅè+Wv§jÕªü½o/Þ¯yñ×Þ½<[¯nne¸{ç.}ûõ׿ú¨ô¯?®¥\uÛÚÚ’”œœ­ƳbÅ –ýü3ŽN ôMš4¦^ýÌÿVÞÇ*ÂÓMfíµ¸ÐgT¹ùùú²lÙÏx¿æÅÆ6t¨.ÏÍÍ/¾øœòåÊ=‘Ê¢dI{¦V-&ŒV«åð‘#̘5“U+Vpödˆžý‚ OO²X}¢§nrº·u£† ™7›6oÆÞΞZ5kêò||Ú1{ö× 4ˆŠ+ÆÊ•«;6À¬²œ¸v-Œ*U*ëÒ¦N ¢Ç;=¨T±búB¦•ìË-BqÃbWz–>s8ÇÏ·_ó-_|>Y: R©˜8y·oßÁÝÝÞ½zš]o·n]1jñññºú^jö2“&MæÎÝ;T©\…€OFKO ‚ BŸÌy†¾m›6´mÓ&KºJ¥¢c‡tìÐÁì²3§ùûùáïç§—ßÂË‹^^Ò»‚ È‚ "ô‚ ÂÓM®C7¿îúMZQ €Ö­ZJ#ù#ô£>’/:…¬Ìš1]ÆF·¯ ä›Ðƒ<²(ÈØ„ÂŒÄèADèAxîEž{ÑÃègA(ÌXÉ6>YÏœ8^ ¶äw½…½o µ‡´• ˆÐç AŠ*ºÉ†èèhy¾D}F„ß»§K¿]Nžl IDATN}F4ò|‰èèh´Z-k×­Ç·sW¿Ô ŸŽ¾¬üeZ­6Ë­þÆM›y«}G<š4Å¿ëÛ„„œÈrg!a'céÏËyîE^ðh„×o2aÒdâããÍîƒ Ö®[O{_?<š4¥ƒ¯?›¶l5YwNÆÀŠ•¿ðFë¶<ß ¡tš B_Ð8;;ãÓî-Ò4¶lݦKß²ui >>ípvvfÕšµL˜4™ºujóçî]´nՒϧ±fݺ,e>r„U+~æó‰œ;žÏ&NÌrGqæÄq¹ÃxâããÙ¼aG`İ¡¬]·žY_RcN¬]¿ “&S¹’;»vlãÇ…óùõ×]&ëÎÉ8ÊÆuk8òtš BŸŸd¬¶2ÿx§Gw¸gz€wæ-_¹€AâèàÀ{7eûyùÊ,õŒ> GGGÝ]®\¹*ÿ„}ó8ƒ fØÚÚèöN Þ³'G}°ìçåŒþè”-S†²eÊ0ú£ÿ™´1'c`äða8:8HÇ ù†Äè3­¢ Qû™gðlÒ„ÃGŽzîZ­– /ÒÔÓ“gjÕàúõ´m¯¿1ÛÕkײ”WÎÍ-½á­Ò›^£ÑHã?Aß<.ö'Oâ›ï¾çܹóDÇÄèÚõλ9êƒë7Òû2c‹k€Š*š´1'c l™2Ò©‚}aãÝÝ9|ä›·lÕÅ\3VóneËrýÆ þøíWˆùËGpãæMæ|û5Í›5#99™&/7Ïñ…Ô½R%.þ÷7nÞ¤zµjܼuÓäy2 Ý<å´ðö¢RÅŠlݾƒmÛwà^©Þ^¯=º¼Ó€_Í$2*ŠøøxþÞ»þ ÎQ=®..W‡×¥ÑsHêÃw;88””Äl±ysèù°/§Ï˜Iø½{„ß»Çô3M/,4AVôyˆ¡¸oFÈ@¥RÑ£ûÛLÿ*}Â÷íó¾Þ{m{¾ÓƒÒ¥J±dÙÏ´y˼߻gŽl:d0ßÏ™Këví†,Ã|9u S¦M£ï€(S¦4ýúôy¢r:ûû‘¦Ñ°lùrÚ´kOÕªUèýî»ìùûo“KŒA¡ÏÌÓ÷zõÔ}Áfˆ·Ú¶á­¶mrTÏãiowíÂÛ]»È¨4£oÏkܨ!ëW¯ÊÒž9í€n]:Ó­Kg½´ŽÚ›<ïIÆ€ äºA¡ADèAzA¡`Èõ—±ò¦AƆ q¡—×Å †Ø³gÞÞÞÒyDpp0õê7†(&äöMmºA½ äŽÌ[õ ¹CQiAVô‚ ‚½ B±Â¢¡÷Š ¦ÿµwþ~¾}U«U£D‰ôë?€¸¸8¦}ù%UªVÕ¥…?þ°/¼)Q²$›®ê/_¾DpðŸ¼ß§o¡k2ž„§‰|‹Ñ¼Ü¬jµšýûöѬysöãêêJ>íÀwsæÈH) Ô*5Õ«× K—®…j¬ÉxŠ­Ð›û,°Ÿ¿?~þþ)ËœóL•µ`áÓÇŽgQÛŠ3æöËãik׬áÃÑaeeU cMÆ“ B/y„F£a劄]£C‡ŽÒ ‚P„^~2^¼¨â^‰Ê•+3ÁBT*Ù’IŠ…Ð‹˜/¤¿ÁrÈRIA„^Axš‘/c…˜ëcæ|WWW6jDàĉT¯^Cf ˆÐç c¢çééɪ_~¡WïÞYò–-]‚‡GCvÿþGËiÆÎË®¬)Sƒh×¶ k׬¡s—.¬\¹‚“'O²uÛv³ëx’vщ¯‹+‹/âý÷û䉙ó###ùñ‡…Œ>‚M[¶È,„"N¾…n†΂ùóÑh4zé))),^´ˆAƒX#ØÛÛ3oÁB&OšÈ… 8JД)Ì_°Pï¥yÉ”  ÿô/^Ìóº\]]ù`Ð`Μ9-3@Dè-Ç /¼@ÕªUؾm›^úÆ hàáAB¨]»6ã>ýŒú3p@'N¢V­ZùV¿““AÓ¾dø°¡¤¦¤äi]QQQÌó=uŸ}Vf€ òõU‚C‡ çóÏ'ãÓ¾½.oþüy̘ñUž;jêµs^Þ^,úéG’´ZÚùøä{ý/7kFóæÍ™1ccÆX¼ŽÌùnåʱi³„mA„þ È.Nür³f¨ÕjöïÛG³æÍÙŒ««+ <<òÜQsbêBÀ˜±Ü¸qƒ ©S?!0_ëøø“:¶÷áõ7ÞÀÓÓÓ¢u\¿y ­V˵«W5rgNŸ¦råÊ2 ¡ˆ“ïW6Œ9s¾`Þܹ 2´P4ĆõëINIÆËÛ›î=zrü8ûöîÍw;¬­­™ýÍ·|2ú#âââ,^¾¢(T­Vo¿ŸÃ˜1yR‡ Å\è[¶lÅ­[·X·v-x·hQàÎÄÀ Œ?A'†Sƒ¦1zôGÄÄÄä»=µkצg¯^|öé¸<«£R¥Jxzz²qÙ‚PÄÉ×}†ˆ2”ÿɬÙ_監ÙÙ5nìZ¶jMºuuyuêÖÅǧ=cønΜuŸ}VF© …Kè³{ÝÐaÃùüóÉzB?þMåÊ•e¤ ‚ðÄäûã•C‡ cΜï˜7w.C† - ±aýz’S’ñòö¦{„?ξ½{-RvõjÕ8s:k¬ýÌéÓTªT)Kº¢(T­Vo¿ŸÃ˜1ÄÅÅÉHáéú–-[qëÖ-Ö­]KDDÞ-Zx#„‡‡31pãÇOÐ íÔ iŒý111¹.ÿ½÷û0zôGãÇ<‚ð¸ÈËØ‹¨P8Ð ‚½ ‚ B/‚ ˆÐ ‚ ƒE·@0¶çË_{÷áïçËÁC‡±µµÍ’ƒŸo'Î…†-;»mLí5c,?£ÌQ#G ( 3gÍÖËÏœž›ýlÜ+V víÚüþg0Š¢èÒµZ-¯{{qáÂ…,eÌ3‡ ©S36Ë‹Óͱ7£^c¶™j÷Šðòöæçå+ôl6U® E\è³=OOOVýò ½z÷Î’·lé<<²û÷?žHL2gì¼ìÊš25ˆvmÛ°vÍÝþð+W®àäÉ“lݶÝì:²ÃÎޞݻ£eËVº´_ýû%²«ÑhX¶t '²páB~ðÞ+ͱ77}•«‹+‹/âý÷ûÈL„§˜| Ý 6œóç£ÑhôÒSRRX¼hQ–Uk~booϼ ™l(©))2[A„þQXãñ™Wõsçê¿–oþüyùò‚ðììÊÀËÛ [Ôj5í||,ÛÐ* ÄœïÒ_ŒþÝwß2hð`½ Àµ«W9B§N¾tìÔ‰!!\»vÍâöšÓ&/7kFóæÍ™1c†ÌA¡OçúÍ[Yþe µZÍþ}ûØŒ««+ <<òÜÑììÊ àãO3–~ý4uŠÅmèÒµ+!'Bظq¡¡¡ß»té"""¨Y½î+P³z5"""X¶t‰Åí5§M>þ$€¿ösøða™1‚ Boš¡Ã†1gNúªvÞܹù²š7‡ ëדœ’Œ—·7Ý{ô äøqöíÝkÑ:lllèÛ·/#‡§_¿~ØØØèå'%%±fõj:¬'¾ûbõªU$%%嫽X[[3û›oùdôGÄÅÅɬúìiÙ²·nÝbÝÚµDDDàÝ¢E7Bxx8'0~ü ýeÞSƒ¦1zôGÄÄÄX´®!C‡qåZƒ \à6m܈GÆT®\Y/½J•*ÔñE6oÚ”ïöfP»vmzöêÅgŸŽ“Y#Å]èMÅ}EaÈ¡|ø¿Qùú¤Mvv;†–­ZS§n]]ZºuññiÏØ€€|³qñâEôîýžÁ¼^½{뾔͉½ÙùmNŒ>3ï÷éËÝ»weÖÂS†EŸ£7÷Ùr?üüý-R–9ç™*kÁ ¦7Î"¶™:>#ûŽÙÞ e<ƒo®½ÙÕk®M_¤—¯X)³FŠûŠ^A(Â+ú¼$7[gÛAž¡/Ì‚)b.BaFB7‚ "ô‚ ‚½ ‚ B/‚  ¹þ2VÞF/ÈØ„".ô^^^ÒŠ‚ … Ý‚ ˆÐ ‚ "ô‚ ‚½ ‚ B/‚ äÿö”º0+)IEND®B`‚wxglade-0.6.8.orig/docs/html/select_frame.png0000644000175000017500000002555312166606326021372 0ustar georgeskgeorgesk‰PNG  IHDRä®&”¡‡sBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´tEXtTitelSelect frame classÊ,Û IDATxœíw|Õ€¿Ù’l*%¤Ñ‹ A@@úH/¶$¡—'}†§„&(  * ‘"("%€©IÒ{²»óþH²d“Íûñ2;÷Þ3gîÜ3÷Þ)çHäÑ Ûx@p_¸¾g© ‚\côy-øþj$<Äü òõ=K%)ߣ“Rî·NÁCKô¡µdÄGæöº¬ôû©@ €™]Á©×‘sž¬Ä[È:m‰‹K %ö5¼qñ~Ê PPpß±õ6R úè!ÓŠ$ªg¾€oÞz8àûá‡Vï<<<œß{óÒôÛW™ÚÏõG¥q¶ZN>ÚÌTâÎ$9úNK\^`ûØz© ý iÊâ} ¼õ ((¨Hžâ bw™9) x·ö+Õ¨5ÎÔz¼1í@v«_*ÛÆÖÛHeèg0H$E©vb–‚2%;‡ÒH>vŽÎEå l½T‚~ƒ”$©L;2EA™’BY.û(/9ÛÃÖÛHeèg¶‡ ÷ñ!È×7w=<ܪ!ëÌ™áävÃiÿa{ ÅÊη"ÛüBâLgV(*¼‡<ô</©Ðý˜ãÅÇk0©GC¼khPH÷W—JÃL)©œ i#&ôËo»¦Úk±ifô3ÛCúúúŒ0((ÈJƒ "oÆiÜCJJ%¨mw]qªºE¶KRñW—Nj&ÿ«­WÃY£"-KGlb#WDX¿ã<©‰âï¬z¥*[˜C¶àÅ™G­ÊÿfÏFxV³gFÈ^nßçI 妋­RÒ6bNNÅŒøŠ×og€}WÞ3¼0ÿ{Lá¶lN?ósȲ¾LW@¦¤P"º¾l÷¯ ÀË+ã©©4JûjLsCš±He±W—·{7¦ã5˜¿é8—®EQßÃ…žÏ?A#»Û\Íñ*±ú5•©TW¦“¨/Û¼¡ Mí£ø;Ûò Ïjöd$ÜDZY*w]l Sm¤´r*¢‡4¥ßË+ã í8ÌßÍè7ÀÈe§rËb<}³ØCRNWŸp|}ƒG+õ* „¢Ø]¸é"‰W›¾ú»é"‰WÝK“ŠbumÙÈ€ä;7Ðê៛É,Ýr”jŠ,\•™$ë¿–î xΓ:5ì¹œÍæ?bÙöçmÓ×IB’$«Êt~²&CŸ÷¢¾›†Œl«ÜdÇ_w8ôÁs†zÓr8t1‘%{"IÏÖÉœ÷Ã5^{Á›Z.v܈ËdÙÞHór¢_k\”\ŽÍ`Á®ë\ˆÉ} Vâú²¢>ŠÃ\) æÚHYåšÛoU<ÛFåaAcµü’ñªzFflN?ƒ™J’¢ÈRò‡¹¾¾¾Æ²$%-†}›XŠKCRšÔU’¤fä6¾÷Fôäžmyú™gHÔ4$Zï…žÜÆ”RÑ¥¬%)”($Éh1dC²:-·»7¡«$ññŽkDÆ&àè`O³Ú¼Õ«1ë'µ õ“õIÃ$‰Ïyðë‘¿ ;•ïÿ¸ @ÿ6žx¨“Œ[Âê2CÚzðý¾?ÈN'1CËÚ½gñR%`§ÐÉL–ÈFEuej±Çb*>û¥š6– ½š,YMue*kÝ".>žT­’7hóhMê©n’ý‡§ZN,Ç®$¶<|uv"¿_N N-gš¨o¢RÈÖÕ—‰Åb}˜(cª”f1×Fʲ˜Óo먚Fõ¼rtsÕõ­×/7u*`Ìm4‡,~8bÎþ‹´OEñ½÷é¨tÞ]óO¸¦Ñì‘ÚôèÐGã:׿÷s7I”]¨]#wnð’QY÷.ÔVÜ%Iïro_¹—«Êx¸ªÈHŽ#MïBœ\ƒtYƒ£”J’dÆëk(»ŽÏ…ó¤¦e’&{(W#CçHÓÚŽ|èãÍc^ÍpѨ 2«»8RK™Äý½ )©¤ÉÄeß›‹f§%¡“<ˆ×ºæé$á*¥ã(eYuìÙØÑÛR}äPô–çµBÚs1úmQð¸â4+Ÿ`óÈ ZP"ýÊ}i¼gã‰lá ñàÕ‰Ôȉ4€©4)ï_A9æt½-»‘bǵw9}c?ŽêÆNICÕMÎéšp7%ïêv/ÛDlŠŽLrœ³”ƒR½.§Ð1`U™ÛɹyjUwâÂmÒpB‡‚dÔ&êÅðŸu˜ÈŸ‚™’#2AýâUÍŽ[Žsáj ö*™ÅSü$ ;)µBW¨¬#’£Ñ¶dÙx›B!£”ôV{vÞ¶‚X¬‡oªlQÝbõ ^hôÛR)-–ô½" ‰Á« Û7¨Q"ýJ4‡ ’L.R éß¹‹ÑŽäåÞ2.¼$Ù™¾™SSI’]=’ìêå—ÌÌ¿úšz uð"JQ•[#.]»‰F‘ƒƒ”Ãæ?soM÷òm¡:J;žhT‡‘»qGW¥ñIRXUfã±»ôéô®v¸hì˜Ð¥ŽA·¤ŒÜakÍê.ÖÍW éPx’9¯.”y÷âír±W+éÛ±Ù½,I( ž TÈ’Òü6¬?vSú[ªÓKÑ6b 5µ‘V·‘²-Åë7&$)¯=+$º&±DúåS¢²¸Ç3¯ÿÎû^ ¡ L3}‡­I¤zŽñcø0fîP¥eéë㎫cT*ñ©Zv¸ÅáÃ’%«™ÍÇãPgÆÒ»u]‚»"#•NèÑäHö$ÉÕŒµ$«Êlý+»ÌXz·®Çg£Úš-óõ¡X<qÜ–k±êàm_tãÿþøÌ=SLm&Ì.»í£Q¼Û­ãu"1-›uGïÐÕHDñe-m³ª¾LœKõamÄTÛ(L‘¶RAwYÍé'‰j㻩Ó¬Õ¯çæÖ&Ù}6g*w®ÓºNßÉÊ˨ålt’ 2 U¤Ê®èöH²‚ç´?'ÒÉAEjrd5²¬ÄYÊÀwÞ9Z)O£Îk”–ˤáÄÎózŽŸ?㔆™Øc'9â@6;N&qê4îŠ8rPÓTiÏyý£ÅÖ‡)Lm8•Á;«/ã­¼ƒVV.91üäê*cQäåµV^iÝæê#M1ç¶èY7Õ6Š”-"§‚žCšÑÏT{5•fN?³=dÁ×år׋Ñô$°&¯ÌµÜ2áááÐkˆ!‹B©D—“‰Ú®è‰°–œì $¥ÊìÕï–Þg)¥¬G!ëÐK ²±' 2pI"'"å:¸J)8…„­¤&]r"[ÖQ²7N¤“ßSXS&G¢¨C5)œ èÉF…^R·ð {ìä,$dªIÉ$Q­Øc)¬CqÛîàAŽl#éÈ2ä(칉vr¶!¯µòJs즰T…©¬6RZ*C?ƒ ë±1¥Þ‰5d§ÜÁN’ð¬ûv¥8 œì nEýCŽ,¡v)fÈ#¨ÒØz©HýbÿÜn죢¿ °s­…65ë—Oƒ\Šwò$JvÎ5+f~ ¸ïØz© ý*ö{È‚º @íâŽÚŽB÷#¨ºØz© ýŠô¹n AeàXÈ•‡Á o{ç:V÷¨t¥‚‡•ë®ÐÕk:[Èýè@øÂla ! R °!„A 6„0HÀ†(“AööëS^zT(UEO@ô ! R °!„A 6„ÊrólÙ²•mÛ¶¡ÓëñéØÿQ¨T¹b£££ùæ›o9N§£yóæLœ0W×\ß-§N⫯VEõêÕ2d0=ºw@–e6lÜÈžÝ{HKO§]»vŒˆFcú-{NGèúõìÝ»ôôt†B¿~/ÉWÌ¥ åA™{È'O°hÑg,Yü9QÑQlÜ´É6{Î\zõêÅ×kV³ú«¯ps«É×_cH_°p!ƒ‡ fÃúPæÎ™Í…ó iaaaDDœ!8x+CV ÓiYûݺbõؼe gÏž#xÖ,V­ ánÜ]“ùÊ¢“¹4 <(³Aâææ†››ì߿߶dñç<óL3ìììprräõ×^ãø_ÝÛ¹BI|\2ŒøHñb€@`Kƒla ! R °!„A 6„0HÀ†)Øe~1 ""‚ïø‘ÇàäìLnÝèÕ»—Õ¯¾ ‚2öiii¼7}[·mçµ7ÞàÄé._»Î?ýL»^`Æû¶£¼txÊÔC¾7}:ÍžiÎÂÏm¯[·.u¢[÷ 8'g'ºvéR&E-aÊ‘Õ÷;ÅÅ@Pµ(µAîÛ·Ÿ†1Æ‚¸ºº²aó^êÞ­Â „ ª>¥6Èu¡¡lؼÅðûÜÙ³ø":*ŠnÝ{²jk”ÿêÙÓ¬¬€À@>xÿ}ê×Ï ÿ¼wï>ºté À7øèãiÑâYìQºvíj(·gÏ/\¼t‰ñãÆš”›Oo¿>øûbûö0âââØ¹#Ì¢+Þ~}7v,[¶n%..ŽÚµk3aü8nÆÄ°qã&îÞ½KãF˜2e2uëÖJîvD (L©ç·nÝ24D€!ƒÀžÝ?åm×®YY-ŸmÉ™3g¸{÷.Ë–/'##€ˆ3ghÕ²£øeï^:ÀÁƒÙ»o/£­Ò÷LÄ.ø„;ÂË®<ŽýyŒ?úˆõ¡ëðõñáà™9r„ÿÍ bÝwkiÓ¦ K–~aÈ_R·#AaÊí±GJJŠÑï—zÜsþT§n=&Nš\lÙ–-[qæ áá¿bggǃ\CjÙòYT*ÓÞ}—5k¾æë¯¿aÍ×ß0íÝwQ©”9½ýú-  fÍ{O[rå0qÂD¼½½Ðh4ôíÛ‡ŒŒ &Œ—×½m/^4ä/©Û 0åòØÀÅÅÅÈ(wý¼Û°ÉâÏ‹Ÿk6oþ Ë–/ ü×p¦LžÌÆMéѽ;ç/\`rÞÐÕ«W§s§N„®_Ϩ‘#©^½º‘ssHww㨷–\yÔ¬Yðnoo@ÆÛ²³³ ¿KêvD (L© ÒËË‹¨¨(ðuæÍÌ ú€ºy.=ò9zô(M¸dÌG£ÑàååÅÁC‡°³³ç¹çZº~=GÿÝÐC\½z•=¿üÂŒéï±lù Úµkk•(j–\y”†’º Sê!ëðaØùá ¿Ÿ|ê)6lÚ̆M›Y°ðSÃöääd~úñG‹òZµlÉÊ•«èäë €¯¯Ë–-§UË\S™™™,X¸·¦NåùçŸgü¸±Ì™3ר‡* …]y,Y²´Tr ’ïv$22­V˵k×™;o~™å Jm;wâÚÕ+¼9¥ø¹arr2C(ÖFAZ¶lIbb";v cÇŽ$$$вå³|ñå2üz÷æé§Ÿ M›6tê܉/¾\V*ý'OšÈš5_3hð`Þ›>ƒ§Ÿ~ºTr âç×›¶mÚ2+x6ƒá“ŸàãÓ±Ìrerá‘––ÆÇ³‚Ñh4Œ  m»çquu%**Šßaá‚øõêEß¾"ú”àá¥$.<ÊtSÇÉɉÙÁ³ˆˆˆàÛ¯¿fLÞ#ˆüwYg}ü‘˜O % \î²6kÖŒfÍš•‡(à¡F|~%Ø B¤@`Cƒla ! R °!„A 6„0HÀ†)Ø ¢\ 2""‚Ùsæ¾Ô2l8_}µšØÛ·ËC|•Á”ç»Òæ-‰,ÁƒƒðËZ‰#XâòËZ¿^=–.]bä@–eÆŸ@dd¤ÁÅG¾aH’„ƒƒ^^^´lù,ý^~™jÕªÉ,è$**Šo¾ý–ˆˆ3dddШQCÀ /¼`•Ž¥uS)|Î><]ÈñãÇ­Ò7ásöÁ¡R{T–_VI’è߯›·l`Óæ- èßÏjWŒ5jÔ$%%ÙdZJJŠ‘_×â?n,žh4ú÷ëÇ?—/[,³?|?¸¹¹Q«V-“Ο…ÏÙ‡ƒróËjŽÊòË Ð¥KgÖ…®ã׸ví*¼?Ãj=â ú¸¸¸———Yæü¶G\\<^žž†ß¦\[ Ÿ³¥î!óý²ZÃÑ£Gͦ›ò˪ÓéÍúeÝFLLLYjµ???.ü”>~}P«ÕVÓÏ»wÓ¢y “i-š7çàÁCVË* nn5¹kø}ëÖ­•7ås¶K—΄¬XÎŽ°í„®û½^_&=ÜÝYµj%ßïÜaXò‡È‚ò£Üü²ÇýðË:hà@¶ocàÀ÷›••Åå+WXÂîÝ{xåUÓÎ’‡ÆŽ;ÙÆÝ»wÉÉÉáâŋ̞=Çâ>,áããCHÈJââ∋‹cEHH™ä Ÿ³U—RY;wîÄö°í¼9er±>Jê—õÛµkü²®Zõ•Y¿¬7cbøâËeLÉÒ–„Þ~}$ {{{¼½½iÙòY>ÿ|Õ <‡,HíÚµ žõ1ß|»–ÐÐõdeeѨQ#è_â}fÈàÁ¬YÉø Q)•ôë߯؛KÖ0yÒDV®\Åœ¹s©Q£&ýûõãpç{~~½‘$‰YÁ³‰¥NÚ¼úê«e’)(ŠðË*T0Â/«@PE~YB|~%Ø B¤@`Cƒl«oê¬XüYEê!°Ò 'N©h=V¤©š üsHÀ†)Ø B¤@`Cƒla ! R °!*ÅÉUUã`øþû­‚ঃo§bÓ„AÃèIÿ¹ß*@dY6û¢0H3Ȳ|¿U<@XóÆ›˜C 6„0HA‰hXϺð‚ÒQ.)â åƒè!ª›:e Tú а^]}ô1vïÝ[$ l·.ùçÒ%®EZ­`jÈgM¹Ê¦ ž¶¨ßƒŠEƒ¼ßJm öþò ]»u3lÛ³ûgK$§*4ð|Åœ±r±8d-¨ÔÝݵZm2Pi>ÑÑÑÌž=‡aÃ_að¡Ì žMrò½o§Nbòä)ô0‘£üùy÷n«ÒlÑcDzìKãx_~ñcÆ3ü<`@‘ 47££iÓª%)))få7¬W—U!!<ßæ9Õ¯ÀÕ+W;:Ížæé¦MàO||¼Q™µß~C‡öíy´q#ºwé̱c°yÓF:uìÀã4¡_ß>\þçC½^ÏâÏñâóÏÓüé§x{êTÒÓÓK]/‚òâAZ¨4KÁB,\Èà!ƒÙ°>”¹sfsáü«Òl—zö$îî]Žÿù'G!1!½ô’!Ï„I“XôÙgFѦ}ö#FùãââbqGeûÎï¹z#€±cFóúÿæè±?9òÇxyy3oÎl£2ûöîemh(§Îœ¥ïËýø÷ë¯óó®Ÿøzíwœ8A׮ݘ^àúÕª•=r„Ð8pø7´Ú~òI™êFP>X4Hk•æc)X¨B¡$>.ž¤¤$ÜÝÝ™4i¢Ui¶€B¡ `ô–}‘ÛK~±t cÆÅ^ìèビ£#;wäÆs¼zõ*~ çß#Fò4¬W×h)HÐÌ™xˆùÓî=<ß¾=Þ~÷~ 7*3gÞ|4h€££##ýýIKM%xî\êׯoØvêäICþÐuëøèãYÔ«WŸjÕª1ãƒصËr„2AÅcqim Ò|, ýàý„®ßÀºÐP\\\  u«VÓl…ƒñÙÂìÛÎù¿ÿfåW«‹ä™0i³ƒƒéíçǧ 0zì8 éææµëÔ1ú}úôiæÏâì™3$%% T*òxˆŸ’¿Ÿ‚A\ÈÌÌ4üŽŽŠ¢³¯‘ŒÂ]÷‹g¡¤J- mÒ¤ ïϘκïÖàïÏ¢EŸ[•f+ØÙÙ1bä(Þœ2…£ü±³³+’§k·îØ©ÕÌ›3‡¿Žç•„m+|u⸱ 8ˆ_æòµëœŒ8ƒN§+Ó1Ô®S‡CGŽp-2ʰ\¹~£L2åƒEƒ,i RKÁBçÍŸÏÈHC£*ØÍ¥ÙcÇ矫×[àfNA$Ib¤I,_ö%'O*Q礧§ãâ⌣£#ÑÑѼ÷î;¥–•Ï«¯½Î´wÞáŸ.‘““Ãùóç™P̱*‹CÖ’*µ,´]ÛvÏ æö;Ô«[—·¦Nµ*­ª¡P(iÔ¨*“œyŸ,à£ÿÍdܘ1xxz8z »¬ˆHmŽB¡`t@‘7nиqc¦¾ý¶Qž‚sÛüõªð¸¦ªcUÀÖ‡ƒáû=é?eúÚÃäúôíKŸ¾/—£f÷Ÿ†õê Ã,%Gœ¢i³æF_}”kÀVAQôz=ëCC‰ŠŒïø JŒ0Èr¦qƒúÔ­[/–/w.%Fd9ó çôã»ßˆK¸@`CˆÒ "È ²Y ŸŽà~ Ò|;‰ÞQp_sHÀ†)Ø B¤@`Cƒla ! R °!„A 6„Õ/4mÖ¼"õ”I’8wú¤É4q®l sçª0%zSG¼½bXPVœ+Û ¤ÁÅU °!„A 6„0HÀ†xà¾öøù¯hB\E§=² ä}IÕþIOÆ÷|ü¾êgkdÇÜâæÜ¹¤üq ¯Ñ¸¿ñz‘<ú¬,$µI¸$©p(ƒÔéeÖ†_å£Ñ]pÒØ£“%´zÐËœ®eöª] pwãFb—|ÁÓÿú^S§²wÑ"\;ùb_¿¾!OÂÏ»¹1}öuêÐdå ÔÂ+aERå/y‘wÓÐç}LœÿMq5' ‡#"9p:’ý'#ÙýWN5â“ã{ÈZ-Q³çÒíwhТ''žéу˜¹ó y2¯\%fölzL›F³_äâ°WÈÊ $¨ª´Aþqé.ÿ]wEž‡sIʦêeÈÑC¶V&G'“£•ÉÌÎ1䀤RaïåEfB¤¤ ''S÷…ȹüi§O£OOçêø ´6“u[µ¢U÷î\›òŸRíÏ’KÌÊv™i«.:«¤AÊÀÆC×Ùp8’¬ì{qC$ È¢jõ ÓƒV/¡ÓCb’ùØŒ#Þo¿ÅÉ;ÁÓ9;))‰½ý¸9g.7Þ›N“V­¨Õ¤ rJ rVØÛ£°/ËDP~T9ƒÌÌÑ1ë9®ÜÍaêk]Ò$$d@/ça¶RÒ2‘³Sxªa-“ò®_¿NPÐLÌÀAƒ šÉµk×ò¾š^»~ôú‹ ½IDATv×ßxƒmÛ¶—ë±U6Õ;w"¸û÷ßHè““ñxæìtzì“x¬Kô·n,“žšÊñmÛ¨?on±ò¶lÝJŸ¾/³eëÖÊ;ˆŒ*uS'61ƒ9[Îòôc èÖ®)öêܰlÃ?9`”ï?ŸæÆfT*%º=÷(Ó^ëÌݤÔ"òbbb˜>ã} ÀäÉ“øõÀf¼ÿ>ŸÌŸ‡··w‘2çÏŸçãYÁøûÂ×ǧHzU£ö{Ó8ñÞtºM›))裢è8j¨TÈ—/#''£ê).X@½ÙÁØ×«gRŽ,Ëüøã.üý Û±ƒþýúÙl°$[¦Êä™ë ,þþ/ù´¢ic/.ŤҼa5–NŒJ*¥„ìÕJìU ìÕ8;Ú#I—”ŽN§/2‡ün](½zöäå—ïÅßx¹o_ÒRÓXÊÔ7ß4ÊâäI.ü”·¦N¥E‹ã}Qçg[ jЀ˜cÇðjÐ!''×cbPuíÊo!+¨>x®íŸ/VΟÇÙÙ?¿ÞìÛ¿ŸãÇÓºuk£<[¶leÛ¶mèôz|:vÄß*•ʪôÞ~}ð÷ÅöíaÄÅűsG²,³aãFöìÞCZz:íÚµcÌè@4 :ŽÐõëÙ»wééé 2„~ýîë]»v±ióiܨ'N Aƒe÷öëÃøqc‹-_ZªÄõ‡?£ùò§Ë éݑڞµøçf*z½Ì¹I\ˆJâbT—¢ùçf£¸ǹk·¸—„T.\E–óæ˜8yò$:u*²¿Î;sò¤ñ» ‡ûE‹>'èÃÿ>0Æ OO'+:•³3È2rv6ú˜tçÏ£îÔ‰ˆ;Ðzzáé?ʬœ~ü¿Þ½èÕ«'ßÿP4B׉“'X´è3–,þœ¨è(6nÚT¢ô3gX¸àvî ,,Œˆˆ3ÏbeÈ t:-k¿[gÈ¿yËΞ=Gð¬Y¬ZÂݸ»FòŽÿu‚Ù³ƒY÷ÝZZµnÅÒ¥_Ò,ɶT¾´Ø¼A~þý^LfxßNä æÚ d@R(òTKÈHèåÜ›8:½ŒV/£ÓÉÈÈÈ2¨” ²r´hìŒ#'''ãæV4\»›[M’““¶Í›7ŸÀ€š4iRG[ÉÈ2צ¾EÃgžÁ½Q#ôQQȉ‰è¯_GQ«IññDž;Gý9ÁfÅܺu‹K—.ѱcG:vèÀ¥K—ˆ5ʈ››nnn°ÿþ¦P³æ½óõÓÏ»;v žžž8;;3jäH~+úð—_ö2ft ÞÞ^8;;àïo$oü¸±xzx Ñhè߯ÿ\¾lµlKåK‹ÍYsr_¹Aäèd²uzT:r¶Ž¤4-2*…ŒƒZB£–Ш†uY/ƒ4öjnÅ¥P§–“‘lWâââñö6׫««Ñ¶ ãdzxÉ\]]yúé§*ú°+…˜EŸã”™Å]º ?~²³A­…Y«Å±Z5äôt´‰‰Ø™ iÿã»HJJ¢ÿ€E¶ñoÃo/OÏ{ë^^ÄÅÅå·”^0L;ÀíÛ·3f¬Ñ¶‚óÖ¸¸8“÷ò©Q£†aÝÞÞžììl«e[*_ZlÞ §ömʶ£‘„†í§o·öÔwsäÚí4Ò²r°W’g„Zy‹ŒV:èôzUjª99ðÅæßi÷˜ñÖæÍ›³ÿ~†f´}ß¾}4on<,íÖ­+®®®|™gRNvv6{÷ícÕª•xx‹'66–7§¾Å+¯ 7„}¿Ký¼›B·bc‹ŒN,¥6wwfþo¦Ñ~ R«V-bbbJ5¯³$»¢°ù!+@¿võèÖ˜-»s'Ž'꺠THtiî…O3O^xÒ“¶OxÐêQš7ñàɆî[´ˆ_öî­¬Ã/w2.\$fî<^ €ˆt11¨ž}–‹{öðãÿKJJ ÊGAwü8^x‘ô'H?{Τ¬òøci¸žžž<úÈ#…BBR(P*(”JTJ%J¥•Jebüam$:Ž­çáÃÈV*ù}ËVœÆ%§a²óê±QCôÞÞÜ8tÏfÍ8±i·££©?q<:¥òÞ㣇µ+Š*a:Žœœr´Z´Z-ڜܿOxªÝÉ“¤ä$ôz= …"×ø”JT*5*• •Z…J¥B¯×£¶³Cùd«Í«¿üzÔøù¡ü׿Ðjµ¤¦¤¢Õi‘õ2’BB1j$§¦OGÿÓO¸¾ñ:Þ³g!ÛÛ“““`d”‚ò£JdþPT‘¿(ò¥’zntz½aÈšß3òä•Q*•µ1( £zT*èå\Ã’J½ÒPŠúõpZ÷J• µJ…"¯þT*•0Æ ¤J¤B¡ÀÞÞ;;;ô²Œ¬×£Óér½½N‡,ƒR©0ô’ù%I2ª>̬GY–ÑçÕcî_=z½Y– Ægø›oÈ¢+œ*aùH’„R’ ïJ-(†‡¨G›C\òB¤@`C”h¼RR·è‚û‡8WU« R|ý]uçªêbµAZ½Gpÿçªê"æ ! R °!„A 6„0HÀ†)؆»¬¯åú±îÊ}SF xØpôhÌoúõ@®ç ƒA¶—òÜz>@n‚*–¼¿ƒÜr´ø˜  rt/B' ÷™ë{–JÿοêLÍŸIEND®B`‚wxglade-0.6.8.orig/docs/html/ch02s03.html0000644000175000017500000001220212167336636020173 0ustar georgeskgeorgeskBest Practice

Best Practice

The main goal of the recommendations is to improve the usability and maintainability of code generated by wxGlade. The recommendations combine the experience of many wxGlade users.

Always overwrite existing sources

wxGlade is able to adapt existing source files after the design has changed. This feature have some limitations e.g. in case of name changes and changed dependencies. Thereby it’s recommended to overwrite existing sources always and extend derived classes with your functionality.

Use new namespace for Python projects

It’s generally recommended to use the new namespace (import wx) for wxPython projects. The old one (from wxPython.wx import *) has some significant drawbacks like potential namespace conflicts.

Use the C++ naming convention

Use the C++ names for all wx identifies like classes, colours or events of the wx framework. Please don’t enter identifiers already formatted in a language specific form. wxGlade is able to transform the entered original identifiers in language-specific terms. You can use your own style for your object certainly.

Example 2.1. Correct entered wx constant

Enter wxID_CANCEL even for wxPython instead of wx.ID_CANCEL


Always use UTF-8 encoding

It's generally recommended to use Unicode encoding for all non-ASCII character sets.

Always use gettext support

Enable internationalisation support. There are no disadvantages if internationalization is active but not used.

It's hard to add i18n and Unicode afterwards from project point of view.

Suggestion on naming

The wxWidgets are written in C++ and follow the C++ naming convention. This naming convention may differ from the language specific and / or project specific naming convention.

For consistency's sake, it's recommended to use the wxWidgets style.

Prevent language specific statements

Usage of language specific codes e.g. for Extra code for this widget or in generic input fields complicated changing the output langauge later e.g. to re-use GUI elements in another project too.

wxglade-0.6.8.orig/docs/html/properties_window_tab_3.png0000644000175000017500000005202412166606326023565 0ustar georgeskgeorgesk‰PNG  IHDRPîÉ(TÜsBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´ tEXtTitelProperties - ˆKË IDATxœìÝwxåÚÇñï¤÷ !!ÁB †@J‘v@B@@¢Hµ X=¾ ŠHQ…ƒˆtÅH ” ¨¨p€AÔX%@zHHÝ}ÿY²Éîf3i“x® ÍNyæ™ÙÌ)»óS¸¡yß'ô!„(×ßû–)vPT<{Œ™[»=Bˆ:â èÿÞ·LQŠ‹ç…ôÌÚî“BÔ mäzJBÑ(@anvmöG!ꜛ4¯š ¨®Ì‹¿›–ˆ¾° Â³+6¶8zàÞ¸5ØØVC…¨çªzÔú>]ý+qšUf¤ýì{éyãç çk¯Y½ð˜˜ò{Þ¼®š}9=zº ÁÎÉÍêvŠä\#å—oÉ8‡k£–ž_ˆºªÞµ¾O×Dÿ ÔT…î ̺ñó,`Ö¬Ye¦1gÖ¬YD—h3ïZ*a¯bEœÝhÐú>.þ/ }a3UmñOVÕû Ö÷éšèŸ¡€¢Ø¨ZˆE%ÛTÀÁÙ½RÍÙ»x5T}¢¾«ê}Pëût ôÏP@E©Ô‚L)Ù¦¢ØPKP›jé«õ]UïƒZß§k¢@czô`VÏžE?ÇÄXu ?{v E'ÿ1ÜóÚ¿K4o‹™NDMô-3lÐÊd“Ó*6¶ÿØ#Ðïfý €{gýPË=¥Õ…÷ÆÒ>XÑvPlL¶gj_.­ô¾]]û´¥þ™ª/æÆYêŸÅ#О={Šæ¬Y³¬, ³¸qÅÔøÔÆ¶B œ'Ù®I™áŠ­Ù¿‡^»Ûèu^ŽKi¹DÇ&ññ÷É/¬_¶*^ûf69¾­ÓyÎä6­É.UZy뤵¶Õ¶ií{Súwµ:¶KiÝ-¶£(ªÛ+½o[Ú§+ÃRÿ¢&úV¢Pî,Qø+Ò?Ë×@+[oJ¶icCé>ì˜PÔéÁ%ã[pÞhÜš©í ãŒØØ”û×jâ¼H<]ˆèÝž‰½šâï¦gÁÞÄJ¯RMjãxž3y7/^ß÷úOtq:‹m^¶Ù¤éÔ]¯N^ŽôiçKßv¾Œýàd™ñ¥×©*UGÛmÓÇöšUïÍ}¯ÿD‡s¬œ9ÌärÖO¹“}§’Ù*™Ki¹ê:_š‰}Pm;(6fÛÿÁ ³³®žÒEÁx>+öiµý,Ý¿Á%êÎΉ¾F¯¡¨ïé_‰Z5zôˆ¡gÏYÄÄÄP  ,Ѽ-æ®H4(8OŠé¿Ú¥Ç)Šm¹}õ±Í$±À›«× øxÿIîjÛ”žA ÙüÕI üøöÿº°hïß<|O =èöÆÏØ(0¤³C:ûáïéÈåô<¶½Âç?_Fw£òº1ïœ2ú}œ¸˜šË'‡‰:võf?A2´K#½¹’‘GäO—Ùv䊡ˆ2Ñ’kV¼sÝ÷ÆÏ%¦ïʸ·¶ƒ¢ (J¹Ë tãñ>M¸µ‘ ö¶ 'ÎeòéáËüŸnqV„«=½ÚúЧ횸‘›¯ãh|-ù#?À°ž¦Ö©¼íôÒ  ìЀE{ÿæóŸ¯0ü®FLë׌]Ǯڱ¡Ù¶ËÓ«­ýËŸf¾N\Ï+dÍ7Ùù¿«ûkê=ëVzyeö@ÓRu7opøØfâe›e(¼'çðh·&÷jÂéó™DŸJá@\*)YùV­›)–öÁжSôûgº=ÌîÏÅãKÎgÍ>­¶Ÿ¦ú7䣶Mð0*ž}pÂÐ÷’åÒRÿJœÂWÍ_€âÓþY³fñU‰6‹ƒMÏcé÷­ô¸¢vÊë«BŠÞ‹4;¾…7?ëg›F’ÎÛðú®@˜¶ò'œ RhëX@»]˜Ö¯)Q?ŸgÁw§Úívžþ÷­¸Øä±áÇt££×Áíœyuóq¼” &<ОCoÁ‘\>?~ €CòÜ€f8u™…›ŽzW žÐ 'rÙ|$Ãh¥JöÃ^)àÃἸp-×õŽ´upäL~sÃôŽ6:Ò =x°sùËxmHK{;²èó#üö×%n ðbô]­‰ûë ×tÎålGË´÷¥o!-ÜÉ+Ðsô÷$Þßþ+¿þñ7º‚<\mlð°¹N·9Gùö•“ëTÞvzwom™Ö¯)‰WR¸¦wá‰>M‰OÌ䋯¾cý^¶¼ÔÏâö2eh?žùwSþ÷g*¯¬: ¹„ÞÛšom³,ö×Ô{ÖÖ±(.ºŠáKy.ë”xe<ß«ŸÿA{×ótnéCpë[x¼wžþw3Žþ™Á¾Ó©ì9aú%–öÁŠ·cc¶½òþ~¨Û§ÕöÓô¸ðU)l}ÌÇðzŠ¢#Ï»¦eJ®¥þUù¨ñ’K^5ú XX|éqŠMù}½1“»Oô àØ/c§b¯ÜülêׇãY`GºÎBxHÑ_£ÃGŽQ›OÔáxz‡ÜÊà?¢þIbáÍ¿V_ü—œ®º³ùë8‚oõgÄÝøæÔ®z1¬‹øäe±ë§xBïiEx×F|u"+…ÞfûQr=2t®xÙ^3 ö¶ÍÀKwa]‚Ê]†»³…:tÙIèô…Ä%¤—ð=MìtÄ4!__ößþ§“ÑënoþÏäf~yÐ-EÛëÌ%¶ì?JîõëêmÐ) y:gr±G§ØÝxCL¯“5ëðæÖ8Þ{´#ÿÚšBlÉÎ-dÍöƒØë¯c§8šm;Mgþ#,#îjÀ®¯"ïZÙzG6~u»² Jüa1óXzϬ=5bb¾¿s¼H?“Îá³?âílÇð¾èÒº]Zzòés¾„ci¬h;(ŠÙö,íϦÆ[µO«`i}?ïcôú£Éíº:Åäñ¹¥þUù¨Ñ‚KZ8}PP¬§(åÿµšÿü#@ÑM¤ËéylùöwŽü|Œæ½–•C–Þ4½'× ]hèé@avÙŠ/—²<ðvw!À6™4½§aÞ´ô,®ë½ÈÄc©.4ðt#Ðö*z{íØ³&0ê[CowÛ$‘^bç.ݒ랢ó&Mo\”[Åše¬8p‘i}xnLtz=¿'f³ò@ñ ‰8*`oq[´±ÿ›_ Z”>o×9¼Ó‘®­ýét[Nüq…ïÏ\áûøk$8’zã¥Ô:Y³¿¥:°ïø%ß]tøå¿’u-ƒt½'é%¶Mé¶-í“~Eë}=#™,;Ézo²õN¸(×±Snžk˜{,½g 6ÞŸLÍ—kçMË[›Ó«;wÝæ…ƒ gÿNäÄ™?¸Õî§ n'Oog¡ÕR˨ÂSø¢ö˜;…7¿?›oÍ>­¶Ÿ¦úñÙø›/“VÄòáä` ¨¨F¬N5ÙN­šº ;|M*Þù †05Îô]Ë}ùö:²õNäP´sÚQ8’¦s'_1.™¸’£¸ GájF>M|ñpsäZª3ÎîEáS3³q$ÇG¯Þžnœ¾âJÎ4ñ*:bIN¿†“’‡£’GRf>^Ìýà3.gúâ¦\ÇÙV‡ca¾Ù~oCÃÊ ·f;§ðKÜI‚é¹õ–¦ ¼/˜ÿ„µà¡¥idãl²éîo ³ýi(ê£ xÙd’¦÷0šî‹“©œK ™[.Z7'¸uKž~°SòuüŸÁ«Ûþ6ý•X'kÖ¡ICOtnÊ¥äLlÑÑ;äVŽÆýÅ—ÉÂÕºíUÊ•Œ¢å6ðråìw²p¥2LýA1Óf…ß³ò”˜oöæüëVœìmøåb&ŸüS¿þI^vŠ^O>ö¸(×ÉÃÃb“FLìƒ[õ6=m Ã×”**Åû ¹#Ð žÂ[³O«RÎúNþ0E)Z¿âáŸ÷6¿¾&TètÖ,ÓÌÞt(úùµ[n~_^)} Ôļiö¦/6{ç'Æ•œÏªë% \ÓíXzrp"GçHîäb|ʇb‹ž¢¾í9™ÆÄèÑ%ˆ3ߦ2än¾?þzņ’gj{væ—=çPtÎ<Þ«è2ÁÁ£gÑcƒ­‘G’yªO{vfíþ³ØÂí>ôëÜ‚··üˆ­ÑUjã~¤_/ÀÓÙ/w”dJ­¯R´m­YÆ›CZyØŽ#‰¹Fü_fL(º™Ôcþ©²+¡(V-cWl*“ïoÌmmÈ/Ôsú\_}ó=N6y¸èrÈÀôuÂD½_Ù±™Øì×qæºÞ™$½.ä”–Å߇ÿæ‹¥‘mix‘¥w6»Nå­ÃcýZÓÌב¾8NrJ ©zwÖDŸbÒÀ<÷o^ŽJµb{•µõ)8ä\&´sS?Ö•kyzÖºŒŸM2Wô ¬~ÊnsÃ|±ÑëyÏ3ZÎ#«'Èö7ô(äëíÉÑlÅ™L y8¢+n¿ÑÔ>hjß+­ô¾X¼Vu{UÍRÿl…4{ã»í%ÇYÛ¿¼jùêKº‰#Q“tó×—z.ˆ#Ä6û¿Äæþ:››N§‡U‡Ó‰>|g›\òôöèPÐéIÇ“<œ m=ýûN&ccèl•tŠ+©z/òpBQlØWÀÑ_ãJ6ùØ‘=ùz{ôz[Ü”ëfû±óx'OÄÒÐ&™|ìicëÈ/ºÛMN_Þ2~üÆ„¿þÄ]Ÿ¢èQìô¹dë=@Í‘’zlÈÂ,½IâÂu\õYØR´LsëX\‡÷¾øu{®ÑÈæ ×õÎ¤ë½ø<Ÿù‚J ·ØúuÜÞlÛ–Dý¢ãè/‡qS²(ÀŽqP\p&¯Bï¥ß)sz.ˆ£•Íï¸)ÙØ“ÏuœhmëÈYÝm\Ö7Ä×ô.äà„TÔMsû ©}¯Ì¼¥Û)þW…íUµòúgí8Ký³xZòë›E?›ééq`íyþ*š'&&Ž0LbckGA~.öN¦Z°J~Þu[{‹­Îëp%››G›.7ôñÔ_Ã|ô@Ž3©…n䕼㠤+Þ +ĉ\À‘lœIÇÝ0]6®$èñP2q&…B {²WòôN€b¶‰ø‘‡#ú\ôx*¤ãYfzk–‘¬÷&\ÉÅF¯#_ïD&î\·q}Õÿå/ÄŽLÜÉÄÝè7ÑÜ:•·YŠžd|ÈÑ;’‰ù8pQpãrŒ‚³M.‰zÓm[’ ç ÄS¹†“>Б‡:ÅP¬~ŠYû»W, O\É&UoÜÏâå$sãSUôUõ>XSû´Z5Ñ?C¤Çß—/©^ˆ5ò2¯b¯(ø7¹ +”ŸwKç'_¯ààÞ üªIÌó­˜ùîÎèZ•»“ŠÚQü>™Òóí³õvÙ–Tõ>¨õ}º:ûwùÈv®§$Ü, ç®$VU¿MÒ£#ÿZ*9™ Wñ…JÅ;'W\}¨í‡‰tRŽá@gô­¥€jX+åW³ãÎê嘆Ë6§ª÷A­ïÓÕÙ¿ÄŸ·g"UwQR°ÁÁ½!î ËŸXã.ÐW²nÖÿ3Ÿ U¤á]ô>™PtšìU/—mNUïƒZß§k¢ežÆ”}åj[X}ñPta*õÆ?¡Eæ/ Vï{W›ËÕÇÅÏ8ÚÃèC€ÙWþ`õHmþ55¯mp‡ÚîBµ‹‹=^Û]uÈøÍQë¿&þQÚwøG— ö9}âXmwCÔQ& ¨‡§Ü)OFzºl§:îÛƒ€úÿû^—W3ҫաLõðôäØÏ?ÖF_ê”°ˆ‘ìülsmw£Ú4iÞ¢¶»Pcêûï{]þ] ‹©é3¹…¬Â‘#Gj» BX¥.ÿ®Ö…¾KB•¤€ !„JR@…B%) B¡’P¡ýú("!4D ¨¨1R ÿy¦N›^Û]¨VR@…jÃI~¾q¶Óì×_7z——Ïð‘–žNôÞ=5Ö7)Ö¢&Tꫜ‰—¯°c×n~ûíwrrs lÌ¿ûô¦S‡öUÕ¿:mê´é,oQmw£ŒªêWÛ6møá‡ÃtïÞ €ÌÌL~8ü#éxzÅ©|÷ýw´mÛ¯:úM0UïmMþÉþ\qª è•«WYôÞRúöîEDøƒx¸»sþü¢¿þZ6ø?Dß¾}Ùûå—†‡N§#..ŽÝ}7ÑÑû ŠŽ ‹B ø`Å ÄÄÎÎŽ¡ááFmççç³üƒ8øÍ·ØÙÙ>„U«Væ×étlþäS¾üòK®eeqï=÷ðÄãSqrr2}ÿ¿*Ž|µø‡°*Éþ¬Žêºë‹/éÙ£}zõ4 »å–æLÿ¨áuAA[wìâèÿþ@H§N„Åήh±S§Mgäðaìûê©iiøù5dÔˆá\½z•½ÑûIMM¥IÓ&Œ5ÿF~ªç±®DïßOFF&Mš6aôˆá4n vó”ëòÕ«ìˆÚů¿þŽN§£Õ·óðȸ¹ºòî’÷éÞí^:wêd˜>%5•ùï.föË3±³·/w}JïðÅʦŠÿ_™Âpw×.¼¿t)iiixyyqêt!:wº¨€&%'óÇ_rw×.eæÝüÉ'œ?,½žù ß6ÿñæÍ\¾r…W,àí·ß5¿mûvbcc™?înn,ûïrÖ­ßÀäI‰Þ»Ç¨XW—¬ìlf½1—Ù¯þgg£á³ß|‹Y¯¼Œ³“{¢÷óý‡¹~ý:‚ƒŽ£ƒ`ùwÏÜ{õ˯¿²uûN/ãáá΀÷ãÞÝ]©u©Šý¹°°Ï¶nãÈÑcØÚÚÒ»D[z½Þⶨ‹T_=ûë¯t)±ƒ›²'z—™ùÂsÌ|á9.\ºÈÞèýFÓœ<ÇÓOLáùséÒ‰e|Èñ'yjêdÎ{“à ¶|üé–JÍcM?Îür†éÓždá¼7 jÓš·|¦vÓXe媵ô¼ï>Þzcsg¿Š—§Ûwî ¿~|±'}‰§h±'šÞ=ºãäìlÕú˜S¼.oQ¥ªlíìèѽ;_ˆŠŽ@ÇŒͩӧØ¿?=»÷ÀÖ®ìßéý_ÍÔ©ShàëKƒ xbê£ñ_ˆaÊ¤ÉøúøâëãË”)“ƱgO>ùþþ¸¹¹1iâ:T©õ©(W:ulÏ¡ï¾7~èûïéÒ gg¾Š9Èo¿ýÎ3O=γþ]»vvs¿{æÞ«561 _?Þ]ðÏ>ýþùw¥×¥*öç½Ñû¸|%‰W^šÁÌžãô™_Œæ·f[Ô5ª hVv6ž^–¯kýtä(Ç>ˆ·—'Þ^žŒÂGŽM3æ¡4hÐGzõìANN?Aƒ¾†aý}®RóXÓ‘Ã#ðõñÁÑÁ¾½îç\Âyµ›Æ*¯Ì|;î¸{{{œœ ôqgÎжM+œ9rã/ý•«W‰ûå =oœ*[³>5¥_¿¾ìÛ·‚‚2¯]£m›6d^Ë$??Ÿ}ûöÓ¯__“ó%'%àó¿qã@£ñ)ÉIøû72¼.9-À•ËWxlÂDúõ@¿þ1rW“’ªpÍŒM6½Ì?€û{ôàà·ßQXX…}{èzß߀ï¾ÿ‡†¥¯/.ÎÎ }p0ÇNœ0j»¢¿{¶Š ééd^»†·7£G°8½5ªb>üsÑx/Ï›ãK²f[Ô5ªOá]]\HOK§A_³Ó¿ÆÔЯ!éiiFÓxxÞÌnw¸q(ïáa<¬ôÞŠÎcU?ÊYfU;w.­;£HH8OöõëØØÜü{6 _¶íØEHÇŽìúb/ýúô6¬«5ëSSnmYôpÙèè}´iU¦ÖºukvìŒÂÞÁÁ0¾4ß ¸”x‰æÍšpéÒE£ñ>¾ HL¼LÓ¦MŠÆ'‡úùùñæ›sðoÔS”*Ny4w´îßÈ€ŽÅÆÒ¹cGŽ8AË-ðñö 9%•Ys޲طŠþîM™ø{¾ü’]{öâêâÊð¡CjÛFÍjTÅþœž–Vf|IÖl‹ºFumuÇ=vŒ÷ícvO/O’’’ð÷àê•«xzÕ|ŒVúQÒʵëØ¿Ç?‚³“×srx~æ ãƒÛµcçî=ìˆÚÍþŸѣ ãÊ[{;;òòò 7##ÃhÙUýKÛ·o_V¯]ÃÔ)E§áíï féÿ˸±cÍÎÓ«gO>ø`Ï=÷,Ë?XQj|>øpÏN€V|h4>4t ‹/áñ©SiÜ8€„„6oþ”—_ž €§‡çÎ%ЬYùå•Õ«gv±—Î;òõÁo1Ì0ÎÇÛ›§ŸŒ¯ª¶M½WÍš6aò„ÇÐëõœŽ;Ãú?aþœÙªûU³?{zyOºj|FPÙm¡EªOáCø7_ü–¯$5-‚‚þúû®^c˜¦K§Nlù|;©i餦¥³eë6º†t¬’ŽW„VúQR^^NNÎ8:8’’ʦO>5¯( þݗ课f@ÿ¾ØÚÚÆ•·>Íš5eß×ÈÍË#)9™MŸ_ÏusuåÒåËU¶.½zÝOVöuÚpgðäåçÓ«×ýfç5r$þLš<…ÇŸx’N¥®¿9І 2qÒ¦>þ$í‚‚Œ®¥ ã_ÿº›Ùo¼Îà!áÌ[°ž÷÷0Œ1b8OOŸ^#ŸmÛº×ssˆùö[iÚäæåˆÝîaãæ-\º|™ÂÂB.^¼Äª5ë­nÛÔ{µjí.%&¢ÓéPª 8¾*öç®;¹u;ié餥§³eëv£eTv[h‘ê#P¿† yæ©ÇÙµ›Ý{÷’——O“&ôëÝË0Í€þýغ}'ó¾@§Žèÿï~•ïuÕf?L}†pù{‹3ò!"·mgåšµxyxз÷ý;k4bƒ_ÆÜÝÅø.vyë3jx?Ý—Ñûñðp§_ŸÞÄž:e߯oo¾»˜ë×sªäã9^žžìÙexíߨ‘Ñëb%ïŠÛÛÛ3í©§˜öÔS†aÃK¹98ØóÌ´i<3mþù'ÑÑцñ666  cpX˜É> /óѨÊ0÷>ëݳ›>Ù“SovõìÞE±áÃV“”œ‚Ÿ_CÂZ_ÔM½W탃XñÑRRRð÷oÄø±«\«›ªbЯ/ŸmÝÆsçckgKŸ^÷óËÙ³†ñ•ÝZdÈ…OHºJö•?ˆœr[½Bwe9r„×ç¿SíOù^þáGtéD—ËwG«Ã aÕz&Ò+V0"b8yù¼ûî"Z´lÁ”I“ª¬ýo`Ê´gëìÓÚ­QS¿«Õ¡¸ïZz"ýøÍWqñkÉ¥#Kå ÍÐëõ|÷Ãa’RRèÜ©v/5Ô¦FñÄ´ið¯ÝÍ£ãÆÕv—„0"TƒúY|}|˜4þ‘:—²2†<ø C|°¶»!„YR@5¨¾mPˆúBžÆ$„*IB•¤€ !„JR@…B¥2Ÿ=ü–é‡?ˆ–Úþ hMjÜ¡¶» êEQ¸kftùŸý'íýì3Ú·oÏg‘ŸóÐðá†qsæ½ÅèQóÿyWW²³²1Üd;öäææâ]‹¶ú IDATèè@jJªÑx???Þ|sþUt}„¢ÆTè°îî»î"))™ý_}MZz:;‡Æåääàââ‚““W/_fÑ’%fÛ¹ý¶Ûù,òsrrr¸”˜Èâ÷Þ3:Å‹—pî\üùçŸÌ;¯‚«&„Õ«BG Š¢0bxo¿ó./<÷œÑ¸çž™ÎŠ?dÎܹøúx1lX™›NÅžžö‹–,á“O?ÁÛË›áÇóÃáÆñƒÃ°±±aö¯“˜x™&Mš0nì«'„Õ§B w¯^ôîÕ«Ìð®]»Ðµk£aƒÃ ?GïÝcøù–[naÉ¢EFÓ høÙÆÆ†ÁaaFó !„ÖÈ!„PI ¨B¨$T!T’*„*IB•¤€ !„JR@…B%) B¡’P!„PI ¨B¨$T!T’*„*IB•¤€ !„JR@…B¥ ?TÔœ¸ØãµÝ!„R@5J¯××v„åªAÝzÜ/GŸBÔr T!T’*„*IB•¤€ !„JR@…B%) B¡’P!„PI ¨B¨¤ÙÚ¯ÿ€Úî‚BX¤Ù*„ZW%_åÌÊÊâ“O·pèÐw$%]ÅÞÁà;ïdðà0:vèQFïÝS‹BM¨’:gî[øù5dΜÙ4òkĵ¬,Nœ8Á¦?6P!„¨oªäþÔÉ“Lš0ÀÆØÙÙáåéIîÝy{ÁàæõÌ~ý~~îù8pð Q;W®\å¡Q“••e4\§Ó±éãÍŒ÷áÃ"xçÝEäääTE×…Bµ*) ÁíƒY¼ä=NÇÅ‘›—Wf|ñ©{ôÞ=†ŸG|ˆM›6¡Óé ÓmÚ´‰ðãêêj4ÿ¶íÛ‰eþüy¬_»†‚‚Ö­ßP]BÕª¤€¾üÒK4iÈûK—1tØ0Æ>:ž•}TæH²¤œœœ9xã(ôÂÅ ü|ô(ƒ.3í{öðä“Oàï››“&NàСCUÑu!„P­B×@¿=xÀèõ䧦{WÆ˸±cÑëõœ;wŽ-‘‘Ì›¿€7^Ÿm¶½Q#bÕªÕtïуõë72bxŽŽŽe¦»rù M˜h4ÌÆ¦¨ö· îÀŠ÷Ud5„¤âšf­ ßDšüÔtÃϦ¤( Í›7çñ)SxxÌX£á¥ýëî»Y·~kÖ¬áÌ™3¼ðüs&—éççÇ›oÎÁ¿Q£2ãâbõI!ÔPs ¦ê.|éÂùüŒ %øÎ;ñpwçJR[¶|FPP[Ã4žœ;—@³fM ÃEaäÈÌ;éÓŸÁÎÎtwBC²xñŸ:•ÆHHH`óæOyùå™&û#„5¡J>Æ4zÔ(vìŒbÉ{ï“——‹¯/]ºva挆iFŒÎÓÓ§“••eôyP[Å–ÀÆôëÓÇlûƒÃ°±±aö¯“˜x™&Mš0n옪èºB¨V%´C‡t(çóžCÃÃ^fø¾ý_1vìhlmm†—,²666  cpXXUtW!ªD­…Êét:öîý’ËW.Ó£{÷Úê†B¨Vk´ÿñoÔˆÿûÏ wÔ…¢.©µ*ß‹BÔurè'„*IB•¤€ !„JUv TÍäå:¨¢.«Ò›Hç/^²zÚ&ªrÑBQãjí.|u²t4½wÙñÖ—œ×ÛÛ›Î!˜þ8G19ÞÃÈaÈ7 [¿q#ƒ…24<oo¼}¼ Bhè@6lÜtsº ›ư¡áøù5ÄÞÞžÖ­[óê+¯XÝ¿ò’¬¦²¦=õ$;wF‘p¾ÊÚ4ÇÔ6¢ºh²€v !öä)’’’X¶|9ÙÙÙœˆ=I—Îy|êT¢÷íãà7ßóÍAöíÛÏS§ÖZ¿KËÌÌä³ÈHn)qj~ìØqúôê]fÚ¾½ûð¿ãÇ ¯?N¯ž=*µüò’¬¦²\]]yzÚSÌ[¸€Â‚‚jYF1SÛ\ˆê¢ÉSø|àÐ|ýõ×8ØÛsð›oп?'Ož¤wïû±³³ã•—_æ™éÏòûïñ|óÍ7,^ô.¶f‰Wš©ëj=­ONIæÃ+ éØÉlÛ>>>F§’ééø6hP¦-Ÿ¾d¤gÜœ.#ß²Ó•fi=^~é%"##yé2ΟOÀÇ·ÝQ#GbS¬™¦2}(LÇöíY·a#ã}Īv+² KÛ\ˆê¢ÉÚ¡}{–ý÷¿|u †çž{–ÍŸ|Ê€þý9óËž{¶èÊÞÞÞôîÝ‹›>fÒĉx{{[½ŒÊ\-ÞY½¼¼èÔ©#S&O.Ó¶^¯'ñR" ßy‡øøxÃàÝ=gÏžåõ9s¬^öó3fpð›oHMM¥° €K‰‰|´jµQR€5ÓT¥æÍš:p Ë–/¯–ö¡ì6¢ºhò ¤sgÖ¬[OE7RzöèÁŠWÒ%¤¨€¾¿t)†…qçí¸û®»¹xáK—.3œâ[R×@­õÀ€¬^½†<@Ó&MX0+W­bíúõ1Þ[4 ¼ù¹ÅÀÆ,œ7Ÿ5kײaÓ&rssiÙ²%#""¬^k’¬™¦<Ý–ƒÃÂxù•ÿ³º}5Ë(¹Í…¨.Jó¾Oè{Œ™KBÒU²¯üÁá·úšÍúö೩uýú¨ð7‘䫜B­°Tß¾=x€)Ӟ宙ѸøµäÒ‘\OI¨Ú#Pùz¦âŸ¤Ê h}9š,ïk…ÿ4²=„0O³×@k‹c²=„0O³wá…B뤀 !„JR@…B%) B¡’P!„PI ¨B¨$¡rB¡’„Ê !„Jõòƒô*W3¡rÖ|KiËg‘¬Y³†G}”áÃÌί( ^^^tfâÄ 40ñÐi!´¦^P •+RÝ¡råmgNÇîÝ»™2e2ŸoÛΰ¡áØØØ˜lC§Ó‘š–ÊçŸoeî[óx÷·-.[-ÐäM$ •«¡r?9‚››ƒÃÂðpwçÈ‘£f§µ±±Á×Ç—‡Gâ·ß~«ô²…¨ š, *W?Bå¢ví",la¡¡ìÜevZNGjJ*›?ÝB«Ö­ª´BTMžÂK¨\Ý •3%ñÒ%~=û+¯ÞxprÏž=ùhÕ*.%&àïo¶ÿnnn,’ÓwQGh²€J¨\Ý •3%j÷nÒÒÓ 3¾{÷n&<ö˜Éþ§¥§³}ûv–-ÿ€óÞR½l!jŠ&Oá%T®n‡Êååå³oß~Ö¯[kØVÑ{÷°ní¢£÷‘——or>/OO†GDp&.Nõ²…¨Iš,  ¡ru9T.&&†V­[—‰ð÷çö;nçàÁƒ&çËÈ(ºfÜòÖ–ª—-DMÒä)£ÇŒáÃWàåéÉ_ýÅÊU«8uê4íÚ1aüxZ´harý<<ÜiÓº S¦L"°q ÑxEQpqvÆßߟÎ64/OÏr·ŸõI½, Õ*Wß¶aCà¦N}‚E‹ÞÁ¿Q#ÕÛUˆºF“7‘´*W¬¯/O>þ8G1þó‘#¸¹¹18, wwŽ9j4þÔÉ“Lš0ÀÆØÙÙáåéIîÝy{Á«§éÛ·/û¾úÊ0}\\:ÎÓ½¾}û°~ãF ehx8Þ>Þxûx>„ÐÐlظÉäúyx¸1l˜É‡B899qÛ­·òøÔ)ôïßuëÖW`ë Q÷i²€j=T®˜ÅKÞãt\œÙ@—7ÍÝ]»ðÛo¿‘––À©Óq„têDÜ颚”œÌýÉÝ]»pìØqúôê]¦¾½ûð¿ãÇLö!33“Ï"#¹¥Ä)¾9ú0ÛŽõ•&Oáµ*W,9%™W¬$¤c'ðÄK—øõ쯼zã!Å={öä£U«¸”˜H€¿?/¿ô‘‘‘¼¿tçÏ'àãÛ€n÷Þè‘#quuµj[;;ztïÎ×bò qqq<öØxV®ü€ýû÷Ó³{ÃöÈHOÇ·Aƒ2ëàÓÀ—Œô ³ÛÆÇÇÇèôÝ_o222+²ù„¨ó4Y@µ*W\`¼¼¼èÔ©#S&O6Œ‹Ú½›´ôtBÃÂŒæÙ½{7{ WÆ˸±cÑëõœ;wŽ-‘‘Ì›¿€7^Ÿmõ4ýúõåí·ß!lP(™×®Ñ¶M2¯e’ŸŸÏ¾}ûyùå— Ëw÷ð 9)‰€RŸ~HIJÆÃӣ̶Ñëõ$^Jdá;ï_îµÍä”TõW!þ)4Y@M…ÊmÜô±ÅP¹eËþË=ÿºÛèfHu1W|óòŠ ×úuk Î¥ÄDž~úÆŽ‹ƒƒqøœ¢(4oޜǧLáá1cM¶knš[[¶,êOô>Ú´j@ëÖ­Ù±3 {Ãx€Ž:°ÿë¯3z´QÛû¾Úo¸qUz™˜ùâ‹<õÌÓtìгÛdÏÞ=têX¶!ê3M^…º*WZLL ­Z·.s´àïÏíwÜÎÁƒx~Æ ~ó ©©©p)1‘V­&(¨­ak¦¢›I«×®!¸}0íï fÃÆô»qó¨Øèѳsg[·n#5%•Ô”T¶nÝFTÔ.F?ü°ÙuòókH»  ÄÄ”—››Ëïññ,ÿ`{÷F3v¬é?BÔWš<…º*·cW˜9Š:›6Ó·oFÅŽQ,yï}òòrñõñ¥K×.Ìœqó£PÖLЫ×ý¬\µŠöÁEôÎà;ÉËϧW¯û¦kÚ¤ æÏcåªU¬]_t·<((ˆùóÞ¢I` Åõz`ÀV¯^ÃÀж¢(899@—–ÿw)^^^Û`BÔq*'„H¨œBÔ( •+EBå„ÖÒì5ÐÚ"ERa-ÍÞ…B­“*„*IB•¤€ !„JR@…B%) B¡’„Ê !„J*'„*ÕËÒ×T¨œ¥ÐµòÚ¶:W‘à6kƒâBBB˜;ç E)³¬â¾™Êš1ó%î½ç_ .ñ|Ó;wòý÷?0Þ[f¶’ÿ õ²€ÖT¨\y¡kæ”:W² KÁm ŠópwggT”Q!´ÆøGÆñæÜ·8[[[ ˆŒüœWþór…Ú¢>ÒäM¤º*W^èš9å…Εd)¸­"AqÓžz’;£HH8_¡¾¶nÝš–-[òõ¾>í·ÞJ«pâŸL“´®„ÊU$t­¤òBçÌ)ÜV‘ 8WWWžžöó. °  Bý}ô‘q|I¡NÇ–ÈH'N4z ¯õP¹òB×,µmMèœ9¥ƒÛ*LÇöíY·a#ã}Äâ²Jºå–[hÙ²ï.ZÄm·ÞÊ-·Übõ¼BÔgš, Z•+/tÍRÛքΙS:¸­"AqÅ7Žg¦O§k×.´ ²¸<£ùÆŒaì£ãY¿fµÕóQßiòÞT¨\aa¡ÅP¹­[·rñâÅëcÉе÷–.5\b°¤dè\ôÞ=†ëÖ®!:zyyùç/ÜVWš¹ 8;;;^xá/YbUŸ‹ùý_¡Ñ u'TÎRèZiֆΕd)¸MmP\ófÍ8eË—[¿¢Bˆ24y u+TÎTèš©¶­ +n£¼à¶ÊÅ  ãå×aKªŽ°=!ê+ •B$TN!j”„Ê•"¡rBkiöhm‘")„°–fï !„ÖIB•¤€ !„JR@…B%) B¡’P!„PIBå„B% •B•êíéÍe!•—••Å'ŸnáСïHJºŠ½ƒÁwÞÉàÁaF„KH8Ïêµk‰åúõë´hÙ‚‡"†Ó­Û}†6‹™ ›ëà¬é·¢öÕÛj­9sßÂϯ!sæÌ¦‘_#®eeqâÄ 6}ü±¡€^¸xçgÌ bØ0¦NžŒ··ñññl‰Œ4P°6W‘8!DÝ É›H5*wêäI&M˜@`ã@ìììðòô¤G÷î¼½`ašõ618,ŒaCÃñókˆ½½=­[·æÕW^1Ù¦©°¹ŠÀ !êMК • nÌâ%ïq:.ÎìØ?N¯ž=¬nÓTØ\Eà„uƒ&Oá«*TΚO¼üÒKDFFòþÒeœ?Ÿ€oºÝ{£FŽÄÕÕ€ŒŒ ||ˆ·•f)l®¢pBíÓd­ªP9K7cйº¸0nìXÆ‹^¯çܹsl‰ŒdÞü¼ñúl<<e 'O2 ïС17.XÓ†©°95pBmÓd…š •{~Æ ~ó ©©©p)1‘V­&(¨­aš±cfÛŽlݺ¤¤$òóó9{ö,¯Ï™c¶ÝÒasjà„Ú¥ÉSx¨þP¹b£GbÇÎ(–¼÷>yy¹øúøÒ¥kfΘa˜&°q çÍgÍÚµlØ´‰ÜÜ\Z¶lɈˆ‹m— ›«Hœ¥`7 }B;4[@omÙ’=»w^{yy½~áùçËÌ>Äð³¥¢Rr\‡è`Å)t³fMyíÕ²)–––Ò©!:^·hÑ‚¹ŽZ͵cÍ8!DÍ“P9!„PIBå„B%ÍÞDB­“*„*IB•¤€ !„JR@…B%) B¡’P!„PIBå„B% •B•4û]øÊ°t4½wÙñÖ—W:øÍš0: ‘¢nª—´dÑ1W„*S˜,…Ç•dm¢nÒäM¤š •« Sáq%U4ŒNQ·h²€Öd¨\e˜ +©¢atBˆºE“§ðU*gIeLl)<®$5atBˆºC“´ªBå,©ì5Psáq%U$ŒÎ)¬Bh›&Oák+T®"Ì…Ç•T‘0:!DÝ£É 5*WY¥ÃãJRF'„¨;4[@C:w&5-Í(T.55Õb¨\ŸÞ½Yºt™Uí÷ë? Ì?µ0€/¾({^FwòÔ)&NžÂà!Ἷì¿Üߣ§êe !´C“×@¡ò¡rŪë3 %• +=^M5ㄵOBå„B% •+¥¼¯ !D1ÍžÂ×)’Bkiö&’BhP!„PI ¨B¨$T!T’*„*IB•$TN!T’P9!„P©^~¾>†Ê9r”-‘‘ÄÅÆÍÍ»ºtá±ÇÃÃýÜ> !ªG½, õ1Tîó­[‰:”v¯½Jnn.ëÖo`áÛoóÆë³U¯‡¢r4yIBåÊzkî›téÒggg¼¼¼˜8á1NÄÆVv„• É*¡rå;~âwÜqGµ´-„°Ž&Oá%TβßããY±âCÞ|Sžl/DmÒd•P¹"¦ kll, Þ~›ÿûÏh¨n„UB“§ð*gZÌ7ykÞ^ý¿WiÕªU•µ+„PG“$T®´Ï·nå£V±`þ<î¸ý¶*è¹¢²4y E¡rkÖ­7 •[ñáJ‹¡r/\béÒe†S|K*s ´´ `õê5 |à£áÅ¡rkÖ®eæMäææÒ²eKFDDTx+>\ Àc' ß±m+ÎÎΪú-„¨ÍP •3'_{B{$TN!T’P¹R$TNa-ÍžÂ×)’Bkiö.¼BhP!„PI ¨B¨$T!T’*„*IB•$TN!T’P9!„P©^~¾:CåŠmù,’5kÖðè£2r777‡…ááîΑ#G«|ë7ndРP††‡ãíã·7ááC Ȇ›ª|yÅÊ ÊBܤɪõP¹¨]» @Xh(;wEUù2Ž;NŸ^½Ë ïÛ»ÿ;~¬Ê—W¬¼ ¡ï1f. IWɾò‡ßêK\ìq“{𓟚nr|¿þ*üM$Ù…Za©¾}{ðS¦=Ë]3£qñkÉ¥#¹ž’ ¡rB¡–„Ê•R—BåêR_…¨4{ ´¶Ô¥ÂS—ú*D}¤Ù»ðB¡uR@…B%) B¡’P!„PI ¨B¨$T!T’P9!„PIBå„B¥zùAúê •ë×!!!ÌóŠ¢”W² kBá*üV:NQ\œñ÷÷'¤sg† ÇËÓÓh~K뙕•Å'ŸnáСïHJºŠ½ƒÁwÞÉàÁa†Gæ•׆Ή²zY@«;TÎÃÝQQ .õPå’ª;®¸ÿ999œ¿pèè}Lú‹½cô¸=Kë9gî[øù5dΜÙ4òkĵ¬,Nœ8Á¦?6zæ¨H!LÓäM$­‡ÊM{êIvîŒ"!á¼Ùij*ÎÉɉÛn½•ǧN¡ÿ~¬[·ÞêyO<ɤ lˆ^žžôèÞ·,¨²þ QŸi²€j=TÎÕÕ•§§=ż… (,(09Mm„ è? Bm·fñ’÷8W­¢¢¾Òä)¼–CåŠÓ±}{ÖmØÈøG)3¾"¡pj>Á`Н7™å¶]¼ž/¿ô‘‘‘¼¿tçÏ'àãÛ€n÷Þè‘#quuµª !þÉ4Y@µ*WÒ#ãÆñÌôétíÚ…vAAFã* gé&RE$§¤âéa]Û®..Œ;–qcÇ¢×ë9wî["#™7o¼>Ûª6„ø'Óä)¼VCåJ³³³ã…^`ñ’%eت"®¢öìÝC§ŽêÚV…æÍ›óø”)œžå¬`ïÞhÆŽ5ÙdÊó3fpð›oHMM¥° €K‰‰|´j5AAm«¬BÔgš<…m†Ê™38,Œ—_ù?£aU gI¿þP'''èÂòÿ.ÅËË«Ìt¥¯çèQ£Ø±3Š%ï½O^^.¾>¾téÚ…™3fX݆5ã…¨¯$TN!P9!„¨Q*Wе !¬¥Ùk µEФÂZš½ /„Z'T!T’*„*IB•¤€ !„JR@…B% •B•$TN!Tª—¤¯ÎP9€„„ó¬^»–ØØX®_¿N‹–-x(b8ݺÝgqù%ƒØÊ ¦«È:xx¸Ó¦u¦L™D`ã@«ú „¨¼zY@«3TîÂÅ ‹Œä–yóBˆê§ÉSx-‡Êeddàã[6,NMûåÓUd>>>F§ïÖöA¡ž& ¨–Cå<<gÏžåõ9sT·i.˜®"üüÒ.(ˆ11ªÛBTŒ&OáA»¡rY8o>kÖ®eæMäææÒ²eKFDDTª}SÁtõÀ€¬^½†< ªBˆŠÑl½µeKöìÞexíååeôú…çŸ/3Oxø2êò3 Åš5kÊk¯š/våµoj¼¢(¼õ¦é£Xk×!¤S'B:u²ªBˆÊ“P9!„PIBåJ‘P9!„µ4{ _[¤H !¬¥Ù»ðB¡uR@…B%) B¡’P!„PI ¨B¨$T!T’P9!„PIBå„B¥zùAúê •³&Ì­d;©)©lÚü1?ýô3W““qvr¢uëV<6˜®]»˜œ§ôò¬ ™BÔ¼zY@«3T®ä¼æÂÜŠ%%'3}ú³tëvsÞxƒFþÈÍÉåÌ™8¶íØa( Y&X.¸Bˆš£É›HZ•+©¼0·õë6pÿý÷3iâDš5kŠ£ƒîÜu×]fŸ¼$„¨;4Y@µ*WRyan?ù™~ýúÖX„5K“§ðZ•+=¯©0·bééé4lØÐì¼¥OË…u‹& ¨–CåŠçµæVÌÃÓƒ«W¯Ò$0°ÌrKLK7‘„Ú¤ÉSx-‡Ê³&Ì­sH_~mbn!D} É Ú •+ÍR˜ÛØ1cØ¿ÿ+>\¹’sçÈÍËãÚµküøã5ÚG!DõÐl éܙԴ4£P¹ÔÔT‹¡r}z÷féÒeVµß¯ÿ€2ÿÔz`À¾ø¢ì)x#??–,^ĵÌ,^œù ç‘ñãÙûe´Ùë¦BˆºC“×@A»¡r sóókȳÏ>Sá6-“Ï€ ¡ *'Äÿ·wçÁQ–Ç‹A Ç( …)Ôrs@Û™"›&,­ÜAäÓEFíT@A›!‚ Õˆ L@`«Ž NGƒ•bé „i 9°^@èq“½³ïÑ7áû™ÉL²ûîó<›?~³Ïûîî0D©œ>2 \¶ÝÂ7B@¸l{ ìŽC("@À †P0D©¢T 5Ë7Ò_îR¹† àÜ¿'%%iÉâ§äp8Bȶ­¯êiÓµeó&µlÙ²îö??ù¤þôÄuÿøãY?^ëÖ­Õ˜{î­»=Pá]ÝØ}M6lÐäÉ“5æî»üÖæÖ¾}{ Hê¯iLSTTdÐÿ pµj–z¹Kå©‚ÂBr¹Bl-}ûôÑûï Áƒ#©¶Bäý>TUuµ¢£¢$Iïýí=õíÛW1ÑÑ^c+¼«©©QQQ‘¦OŸ¦×ߨ®»î­-¼O…»Ç8U^®Ö®UVv¶}äaƒÿмÙò"RS)•kȜٳTPP¨cǾ6z¼ÓéTÉž=u—––ª¦¦F¥¥¥u·—Èéôï] Vx÷Ñj×®F¹\ŠŠŒÔƒÎß©cGÍš9S0Z?ÐÜÙ2@›J©\CÚ¶m«¹sfkÙ3ËuþÜ9Ë¿uÐ@>|X•••’¤Ï>/URÿþ*ý¼6@O•—ë«£ÿÒ­ꑃÞîØ!—+]’äJKSÁŽBËëPË–[x»—ÊY§ÄøxmÜœ§ŒÉ“,­åšˆÝ6x°ÞÙ»O£ïøJKK5eJ†rr^”$íÞ½[CßæõœCÞ,+Ó—ÿøRO<ö¸$iÈ!z17We'OªKçÎ~k(?]®uks””Øßè¹Í-Ôî¥rVMš8QóæÏ× AÕ/6ÖÒZ’“Z±b¥\éi:óÍ7êÛ§Î|sFgÏžUIÉn-Zô¨ßXÁ ï ‹ŠTYU¥4Ÿs²EEEºÊ”ú9 ᘘõéÓ¦?w 9³e€*•ËÛòrÈR¹¬¬5úõ¯nU×®]yõþ"""´`Á=µx±ž_½ÚÒc{öè!©ö\gŸ^½$I½{÷Ö›…jÙªUÝýž< ïfÏ›«Ä„ED´TIÉnmÚø’WƒhÙÉ“š;wž&ŒŸ V­j¯öóþ\ <¶<*5R¹puïÖMi#G*+;ÛòcN§Ö¿´Aqñq’¤ø›ã´9/OÉ.yò,¼Û·oŸzõîíW¿Ü¥sgÝôË›´ÿ~Ëë®v¶|*Õ–ÊmظɫTníºœ¥r'Ž—)33«n‹ÊÅœ5}ì(—K‹~:ÿhe¼¡CoWNn®âãjô減õãÙ³:ôö瑚ªõë7H-š4~BÀcÒÓF*oË+r:‡78€zŽîÎ/Ü6~‰Žú¯¾ýÏWú`©S¥ÿ4àÁïîß«i³ç¼?9%Õò'‘Ø*°‹Pùöîþ½š>ç!ݲ°Xm®ë¡²_Ów§Q*¦(•óA©€pÙöhc!$„˶WáÀîP0D€€!  `ˆC”Ê€!JåÀP³|#ýå(•«¬ª²\ò­£G*'7WŸ}ö¹$©_¿XÝŸ‘¡Ÿ{|S¼çz•Á¹ïw8jsíµêܹ³’ Ð]wŽVLt´ÑÚ( .^³ ÐËQ*m¹äíĉzø‘…ºçž1úãü‡$I{÷íÓ# ÕêUÏz}wiCepîû¿ÿþ{}}ü¸Š‹K4cƃZµj¥:_=t@#°åE$»–ÊY-yÛ”—§ôô4Ý9z´Úwh¯öÚkôè;”–6R›ó¶œ#Xœ[ëÖ­õ‹ž=5sÆt¥¤$kãÆMFk gN è€Ðl v-•³ZòöÉ'ŸjøÐa~ã8‡ ×ÇŸ~pŽ`ep¤¦¤ÖCpåÙr o×R9«%oÕUUêØ©“ß8:uTuUuÐõø–ÁÓ±C{UWŸ1Z[CsR@4Ì–¯@âãUúEí+'w©ÜÛÅ%’¤C_RB|‚¤úR¹­Û¶)==Ýr©œïO8’“*))ѹsç–¼%'×o‘#£¢T~ê”ß§O•+*:Êo=oï|KׯW×.]‚ná=•Ÿ®¨;¿ium ÍéY@—œ’ª4—K•UU***òþ¤¤*9%U3fÎ’ãšš1Ó>µÒÀåfËW v.•³Rò–˜ ÝïìÑøqã¼Æ(Ù³[‰ ~c*ƒkÓ¦MеìܵSýëÇ¡€¸²lù T²w©\¸%oãÆUAA¡òóßPÅé Uœ®P~þ*,Ü¡qcÇß³ Î×?ü 9¢ìÖj×®bM˜àÝsDpåØ6@“ PEe¥W©\EEEÈR¹áÆ)33+¬ñÝ[OÏŸp z»þ÷íw –¼ýìÆµüée:ðñAMÌÈÐÄŒ }tð ž^¶T7ÞpC ¡ëŒHMÕ[oy¿ë·©#4æÞßkÅÊgÕªeKe¯Éô ¹p×jÎ7wÊ•–ð˜ô´‘z³‹I€D©H¢T®(Jå|P* \¶¼ ߘIá²íE$°;  `ˆC("@À¥r`ˆR90ÔlßHŸœ’ª¤¤$-Yü”‡ß}ž¯~Ã)~kh.7‡Ã¡˜˜%ÄÅiêÔûÕÉã •¯DÁ\ q<¹ŸwCóhX³ PIŠŠŒTAa¡F¹\A±RüŠ;˜jjjTQY¡×_Ï×’¥ËôìÊ–ç¹Ø‚9ßãZs°y„fË‹H—ªTnÎìY*((Ô±c_ˤø-”-Z¨c‡Ž{ß}:|øðEÍcZ0gUCóÌ–z©JåÚ¶m«¹sfkÙ3Ëuþܹ€s™¿…RSS£ŠÓzeë6õêÝë¢æ1-˜³ÊÊ<êÙr )Kåââ┯›ó”1y’ß\VŠßBñ=çØ®];­úiûnuž‹-˜ ¶&É{[o2€z¶ Єøxe­Y#©¾Tî•W·*5%E‡¾8¤?<4_R}©\Þ–—õÀÔ©AKå&Mœ¨yóçkРêëuŸ»ø­‹Ï»¿…âL•UUÚ¾}»²²_ÐòeK-ÏS¼k§.\¸ “e'õÌÊ•:räˆß7Ïûò-˜ó]S°5[@=[ná•Ê?>d©\~~¾Nœ8p¼ˆˆ-X°@«Ÿ{®îT€›»øÍW°â·pÄDGkÌÝwëPi©ñ<žeoÏgfú­Û—oÁ\¸¬Î ž-Tºô¥rÝ»uSÚÈ‘ÊÊÎöºÝ´ø-”êêÚsŠ=zÖ·`6FÁœ¡æ˜-·ðRm©Ü†›¼JåÖ®Ë Y*wâx™23³ê¶ø¾F¹\ZôØã^·¹‹ßrrsõҦګر±±a¿yò<Ÿ©~±±Z¸àáK2ψÔT­_¿A#GŒ¨›Ëáp¨uëÖêÒ¥‹&%){M¦bbb‚®É-Ô¶Þw¡Q*¢T®(JåÂ@Ñ€@l{ÔNIØö*<Ø †P0D€€! Y¾ ¿ö/«.Ç: É± Ófþˆ$\,h°xÀÕˆs `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€! EºñÝý{¯ô: Éñ P‡ÃÑë€&Ç+@Û\×C·,,n¬µ€­µ¹®‡×ß~¯@}V e¾Ö˜ë€&Ç!IÝ^hì…@Sòï’,ÇÿG„–˜ÌIEND®B`‚wxglade-0.6.8.orig/docs/html/ch05.html0000644000175000017500000000421612167336636017656 0ustar georgeskgeorgeskChapter 5. Menu, Toolbar and Statusbar

Chapter 5. Menu, Toolbar and Statusbar

Introduction

wxGlade helps you to design the menu and the toolbar for your application.

You can create the menu and toolbar as stand alone classes by clicking the corresponding button in the main window.

Alternatively you can make the menu, toolbar and statusbar associated with a wxFrame, by selecting the related checkboxes in the wxFrame properties window.

wxglade-0.6.8.orig/docs/html/example_subclassed.png0000644000175000017500000002600512166606326022575 0ustar georgeskgeorgesk‰PNG  IHDRz ÀsRGB®Îé pHYsÄÄ•+ IDATxÚíwxU‡ßÙM€‘¦‚ Ò»â‡DšE”N¨Š X("UQA,€ R%tBÒH'Ífçû#°dÉ&YH€$œ÷yöIfνwιwö7wÎÌÎ(Ü JÛá*‚ B™áÒoK«›"ضôŠ Bb'¨—~[¢(7EþJò5éA„2Ä•Ý+ÈHÏ™Ñd_O—^A(ƒÜzÝ=zC6×"Os=)5[ÇÕ[w_œýê€F+#'e•âÖŠ’®=÷Á¿\3ú´;xrê³¹š×¢ÉljÍÁžyÖuþ<>Ÿ“íC;£ÿ{Ú<5íŸ2ÓÝÄXûå¡ú´âNÛAјmÏœæ¦A÷J{ òÏœæg+È¿gôAAAFqŸ6mš…B?}Ó½F{GG-/}ñVÍvJ~G­ÝS››,ëô¢’®³íh«öD’•]:~ü{3ŽÓ÷šµ×µ‹àÔõJeêË}{Lwãƒè—Û÷¹üÆL¸3áSŠ«E¹ëön× ‚´ç^Å»9Ø“.¹ýÇ\¨;ñ¯à½Zäný¯Ñp»? Îqºëñxê#LlË_k`´™ ÑzT ž»WG;z?Ó€àÖ•ðqRywk4¥é9ØFpJwëâJ‹ûib†‡V›6$ƒS‰óÙ×Í–6õ=i[ß“—>=fq=m*nÚô"Åx³ûÙ/-fìç›Ë|>¡—Ù1ûfè£üv<žßÇ•t]TÜÌhÅݶƒ¢É·½AŸɷ겡 PLëY =Åo×/âúøc°§ÉòMßïÄ¿\B_“-}yµuEND\cÛñ¶ŸL$!-K=¿ùaZq§íä|OÌ·§@¾ºsÓž»ž%ÚSœñvÿ"ƒ=L&ů|zÄè»ÆL¼…¤nŠçHu3Ý3mÚ4þÈÕfÎiE~b±-§Â|UHPÝH28ã™}ëÞÚ$â îÆåf`Ôçû±×'P×VOý†MÕ®›DðîßÇéÙ²&¯?[Žo÷%›œ t­oϔա¸)) ~®ouªŠ-×Yš @·ÇË1®Ce¶ὕ‡éÔ¬c;ÔÆŽë¬>˜bTn?¬=ŸïÀ[ï}E†jK]eU1–·ÕHÎv¡[ã·1µ»?~î¶,\³ÿEQÕ×ÿ5«ÃÉÿbI5Øi¬;4ð¤m=¯æŒN¯rè\n:Ù —0èu8j4¸h2¸¦:Òé1/Æw¬Âsñ,Z³+ôôoßÈdÌrŸvÞŒQQÀÑÖŠŸíG½EÓºÐáqlÕLfo‰Æ`º«£( ½šø:Žx2¡SUO`ÑšÝX£gÀso¥lÂMú¼ b ^y|¸¹NYŽ4ö÷  NU†=S‘ן­Ì¡‹)üv"‘-GâEÙͦ\Š«M¾í¤;w¯=Åo/ØðЇqyðÒœ™|‚U¥<‡†‚üÓä‰*÷§è‡*ãG¹qzb®y,·i4æ}5SÉÃÙ†áírN£Ÿ¾„•’µrëÞþ?wïÅUC†Ášëª5=Ï9jî=xýõt6ï=Ÿ#ê{SÞ*Ád¿îü‡ÌbSUVÿy€¾ÍËSÎ*…^M¼ØùÏ¿ Kå§ý9mõhZoëd“¶n÷#w)ª#:¬pÓ¦W»kSpÓ¦Z´ g{+ôÙ éqÔlN†'±xÝ*Z]ÅZc0Û»&=nòɯ¿ßé\•&þ.ì?Í;ŸþªÍ;9v‘ëz•4ƒ=I' ŠUά¼iy¶ì8€.-‰¸k:Výq"ï@ß#ŠÂW»£‰OH U¯å¯c‘4­éA%«Ø¼S0E¡ëãå Çç›çøóóŽ}d¥%qõšŽ•7»}‹>ìÌ—2ÝøãT2Ÿý°iŸnæHX8Mü]y§sUÜ´i–oã!ù˜ÓŠ»úÜЊü´G¡àá¼#í¹Gñæy€/^m@¢u¥ã5·_ûŒÞTç5Ž)(Û¥ð£ê¼7^r.ÆÆ$ëø~×98L&¶&uSÓ2IS½IR]ÉÈv œ«Ùé)¤+žD¥¹æ|éðÕÆ“¤ºë&%§‘¡ºq g':䤙\¨ ½JŠê‚Ÿ»-Ó‚;˜øVÎÝ?MɹN÷o÷#wì w’Tç<}¢ ±hK·G2ª/ãú·Ç ªœ‹NçóíáœÆVѣǺðkÖ—8­¯–gýÜŸ.ÓíQ[šÖñ¡Qö¹ËžS±ì9ŸJ¼Þ–,¬PQPðu³ =%4Õ…8Õè$‡<1ݾ\¯‚ƒ}©åó(ÎvÖÆ}×ÍÙ/m2W žyêø¸Ú:Ž~n9}—‘’DªêœãOB^îô{a®Þu+wü«W¡õ#Î4«á†•†°KÑ9uêVW8®¯‰Nµ’©ü=HÝäÜr˜_êF)p;w£=ÅïÚA·²C–å³WX?ȃÞËó÷¾äèóÌè ¸àÐgy"îYáÆÌÙÌ_p(Ø× ó¿&]µ#ÛAf¶$œÉRL…íŽd*¨(\MÉ¢¢‡-.N¶¤&ÚcgM¼–Ž-YØæ:pwuâD¬#iØSÑ-'ŸœŠ¢ÃVÑw- _7fº–˜kÙF_œ” ìµl³³òõ#Ï,ÕÜΨ`Ñ6~ MàôÉc”W©^µ[0±K5žÿ(‰tìÍ6ýôœ#4¶> 9>zhÀMs$ÕŤÜ/Ç ;Ne§ë4ªS…€:þ¼Þ­!C³ üs>…)/ËF%ë¨æe‡—›a·õ›i¬¦ËÓºWÅÇÕ†÷×"ìb¶V*ŽîŒ¢(Ø(YXk²óÔ±d£’tT+g‡‡‹=aqN¤aOewËú¾pµ7Ö›Þ½ OTwÁÎZÃéÈk|·ó,ÇÏ\D—ž‚¢ªdaƒ’Qø´âûî…Vë³<ÑÌÅX%ß‹±wšº±D{îE¼¯~vEɉïæúµƒÜó·¨9úiÓÌ72}Ð0çÿ©U§šŸÑçs Q’µù‹!îYáF›ba*÷-Uu@E!;2 ¶¤àÌõbxëÜL‹JŽo[Ž%XžÀ&õ8µ+‘îÍ}ØzUÑ ÉåHÇ ÆœÞrÅ`ϰÖrR(‡ÂPÑ U`ÝÁxF¶ñ¥cPc¾ú= m6Ô¬àA»ÆÕ˜ÿý>´òõ#9C«½nÎ(ñ“™îÍòŠ¢±h³ºWcÝ^+FG’J[€>KG m§²«£ÇüLòŠÁG%Ýd,óøD©åIMM#üP Û]¦¼› שÂcT¡¢6–+†œ>\w0ž7ÛW SPc¶\F£Ú3ü™ ybº}Y{£Óm²’°µÖÒµå#·ökEA«äíKÆqÍþ8&t¬Èsszëe480¢_ž¶ÌÅ\ؾ—»^UO;~øç"GN_$9%U…lUC–â@v¤lÉPï|;e=GõrkFž½™òK‡Xv̾9ú|l¯~vÔ¨“ Ðwy"knˆ}~ñyFŸßmôÓÿ^¾±°ÃüŒ¾ A¼ðUnYá¦'E1[>çGJ¡Ã¯z䙿5Þ^nÎ\½–Åòm'9~ì¹ÇÚìaBÆ_(‘8xû›ú›"¿ì…rÔ h(=U'†J'‚P"´ú‚‰ØçùµLÝ€†"bP¯Ácœ8rX:B„<`ã.صs;.®eûBlJrr©1%9YvTA¡/:‡ì+Óñuéý?®]]j}—3.AÈAnÌrðàAñ]DèAzAA„^A¡ADèAúRÎk£ÆH¼‚ ÜEº><<‚e_}ÅÑ£GÉÈÈ š5žï݇–-[HÏÞ…°}òÁBéAJÎŒþJäÞ?žzuëòÉ’%ü°q#‡ cûÎÒ«Àø‰“Ñëõ&ë–~ñ¥Ér–^Ïøw&s-5õ¾Š|qÏ–£cbYúårÞ˜0‘cÞ`ÎüüzDvA(í3úo¾]I×.]èÕ³‡q]:u˜2iÒ-!ËÊâ‹/—±cçN‚üÊ ¬­­h×¾#GŒ`ݺu\‹£B… ¼>j$‘W"YýÝ®ÆÅR½zuÞ;ŽJ•*ÞuKü5r$kÖ¬!1)‘êÕ«3æõשZµê]w¬Õj=vœFå< .-=#ÇN𖆓c΋ËCÅ¿Z5œœJí{õ* ?øˆ¶Ï´¦wn¸8;q…mþI£† ä&¥YèCCCøRÿˬZ½šK—.±äØ÷Þ|V÷/õ¿UoÿþýÌ=ww6nÚĤÉShÀœY!¸¹ç¬[üáÌ÷Ý»®c‰‡ä½÷ÞÅÍÕ•uë7°øƒY¸àý»îØæÍš²gï^£Ð_¸pUU¹pñ"õs^(½wß~Z¶h‘'u“ÍÚ 9xè0Z­–gZ™´­×ëY»a#‡þ 5Ú7þ°ÙX_UU¶lû=ÿì%##ƒ†ôéÝ[ãlþæß¢žIüô˯¶¤M.«V­ÂAMüÝðÃOú÷_oÔˆ];aeeeQ¼Å#Â=Lݤ¤¤àáYðkµþؾƒ×^Š——^^^ m(lßnRfÌè×ñõóÅÎÎŽÝ»“žžÎèQ£ðñ½µ.ìtX‘êXâǨ#ñ)_;;;z÷êɹsçŠÔ±õáRx8×®¥pþÂÔ­S›óç/”œLDdõÉSwë¶ßˆ‰cÒÛã™ðæ8Nœ:mbßòë6â™üÎxÞykaagLû}ÇNΞ=Çè‘Ù6½AÏO?o1öO>XX,颰3ghÒ¨Qe¶lû¨èh&¼9Ž oŽãJT$[·ýnq¼Å#Â=zâã ,“‡¯¯qÙϯñq¦u<<<ŒÿÛÚæ¼´ÙÝÃÝdÝu®Hu,ñ£°mÞqÇjµ<Þð1Ê™Å^¸xŽÏµçüš߷ÿ?ö­6Oݽѧg7Ü\]qws¥oî&öý‡þ¥W÷n¸º¸âêâJ¯ÝLìïù‡çûôÄËÓ{{zvëÊá#÷&gž–žŽ«[ÁO¸Ü0'w·[ñì;xÈâxïg<‚ ©›\4lØýÅó}ûæ[ÆÃÓ‹¨è(ªT® @dä<½îÿ‹½”O4oÊ·+VØò)Ò22ð¯Z•ô´tôz=ÿì;À+˜­—œ”„W.ÿÊy—»ÍžŒ—ç­ƒ×m±Ä'$2mæ“uÊ=x{=€£ƒCŽ?^žù–ɱ›Æ“œ”dq¼÷3A¡ÏÅKý_dìobcmÃÓO·ÄÕÕ• .°fíZãÙÖA|òɧ¼1n,º”ÖAA÷=ÈåG¥ ~ü³o?Õ*Wrò×;þÚµµµÑ~;®nnÄÅÅáëã@ÜÕ¸Ûì®ÄÅ'àSÞ;Ç~ûY’»;#‡½Šg®3Ÿ{%’µkÕâÐáÃ<Û¶M¾e\Ý\Mâ¹{W77‹ã-,AîQꦂ_Þ›;cÇüêPºvïÁ‡K>¦Uà-í÷B?*UªÄð‘£>rU*Wæ…ç_¸ïA>H?š7kƦÍ?Q«f jÕ¨ÁO[¶òD³¦ùÖiÚ¸ë6l")9™¤äd¾ß°ÉÄÞ¤Q#ÖmÜDrJ2É)ɬÛhjlù$+VOTL ÙÙÙDFFñåòoŒv'GG¢bbŠ%¾NÏ=ËŸ;wñÇö$&%£×ëùïÒe>[¶ÜÄßï×o"1)™Ä¤d¾ß°‘¦?fq¼…Å#Â=šÑT®\‰©S&çk·±±fø°×>ì5³öm[·Üñº»©S\~Ü M7bý?Ró†Ð׬Y,½ž&ó¿€Ù¡][ÖnØHÈìyh­´´iÝŠÓa·..whߎï×m`Ƭ{PË–œ>sëâqÐÓO£(>ûbqñ x{—£KÇF{»¶ÏðÞ‚Edddù‚¬w¹rŒ9Œ7ÿÌÏ[·¢ÓeQ±bÚ=ÓÚÄß ›~dî{9w15z¬!íŸmgq¼…Å#BÁ(UÚWûÏ&<î*鱨;§­¼3¶víÜÎÐQcKÌÛ—®DFòéçË™:©ØÚtïÑ“é3BHNI1™ýoþég¼<ç:u&øÕ¡?q‚mÛ~cà ÁtêÒ…×ÇŒ1Ù†Á``åªÕ¼4àezôêÍû ’™™)£WYY:ÞžðÔ®E@ýº|¼ä£<3ç›\8žÁ¯ ä‘Úµ¨UßA_&!!Ál»:Ž)“&P¿.õë2eÒDt:‰ý­ño·»ä£ev.¥Ièy}ÔHæ¾÷.Ùz½Ù2!3gѵsgV­\ÁŠo¿ÁËË‹eË–›”Ù¿?sgÏfúµ´nĤÉSø{ÏæÌ aÝ÷ßÓ¼Y3ø±üÆM›8zô(óæÍ囯–£×ëùú›oeô `ñ¢E\8ží;vòë¶ßùó?ò->>øøø0#$DC0wõËØ— `ô˜14mÚ„úõê™ØÎž9ËçË–qîÜ9RSSÐjL'Æÿmmmp÷p7Yw=W: 6&–W›¡4rÃPADEEQ¥JUãrµjþù–=ÊÌ;~Œä¤¤œ1ÓjÍ–ŽŽÎÓnTT”‰½r•*ÆåÜeA(%3z+++Þ|óM-^Lzzº‰mæÜ9´mÓ†¯—/cË/?³~í÷d ErÒÛÛ›o¾þŠm[·?[ùYF¯|}}¹té?ãòÿ]Ì·ìÐWƒéÓ·/{÷í'"2šSagÈÎÎ6[ÖÇÇǤ݋/àëëkb¿|é’q9wYAJ‘ÐT©\™N;²ä“OLÖgffâàà€WcbX¸xq‘ìÔ©#‹-æòåpôz=/^döì¹2zнGO¦LžLtTÑQQL™4)ß²ééé8;;ãààHDDoŒËÿiݺ÷`òĉDEFÉä‰éÖ½‡‰}êÔÉDGGÍÔ)“e0¡´ =@×.]HHH4Y7nô–-[F—î=xã­·hPd'»véÂO4gzÈ ºvïÁÜwß#¨U Œ^Œ3–*Uªô4mÛ´&0((ß² .fæÌjøW¥g÷n<ñÄSù–3v5kÕäÙvmx¶]jשÍè1cMì~~ lIÛgZÑ´i3¬­­-?Éu½ÜO/Ѽ¼ °kçv†Ž["Ÿ^yòäIèϾ‡d ¡8¿[GC©ÐÐD¯ojÁí/—+šB±3eò$bcc‰ˆgڔɴïðœtŠ <@äyôB±S©reÚ?Û–,ŽgÛw`ÂÛï?_G~ +"ôB)"8xÁÁCDÌ¡„ ©A™Ñ ¥¹ˆ.‚}FÞ+‚}¦e`+™Í ‚/’£A¡ADèAzAA„^A¸È]7e€];·K'ÂCJËÀV"ô CG•N„‡ UU-ºµZ„¾Œ º wòÛÉÑ ‚ ”qDèADè-§]ûÒ£B¡ÈëAfô‚ˆ· ÅÈ]Œ `ÙW_qôèQ222¨æ_ç{÷¡eËÒ“%Pxkժ͎¿v¡(Šq½ªª¶lÁÙ³gE‘1m žIDAT,zÈMW'''*W©B«V­úÚ0<==åä¥"‚PfôW"¯ðÆøñÔ«[—O–,á‡9lÛwî^,¡Ø;ØóÛoÛLÖýºu ŽwÔNTÌU"£c =zœE‹> 33ƒ6­ƒ—N„²$ôß|»’®]ºÐ«g¼½ËammM:u˜2i’ÙòW®0cæLzöîC÷=™>#„䔣ýph(Æ S—.ôi[¶nµÈ&XÎðá#ùèÃLÖ}ôᇌ1ʸܭkg6mÚhzP¿AÀú¤ä/ê?ú(!3góB¿™7wNž™?À…óçüÊ@©]‹Z5ü4ðeÌú¨Óé˜2i"õëP¿.S&MD§Ó™Øßÿ&Ô®E@ýº,ùèCI ½úÐÐPZZÜpÈÌYtíÜ™U+W°âÛoðòòbÙ²åFû¼wß£ß /°qýzÞŸ?ŸÓ§N[d,§c§NÄÇÅqàÀöìù›ÄÄžëØÑXfôè±,˜?ƒÁ`\·`þ|ÁÅÅ%ß¶_üßÿØõ×N³¶àÁƒ8è9ÊÁCñõõeö̳e-\@XX¿nû_·ýÎÉ“'Y¼h¡Ñ¾pÁûDD„³}ç_lûýOvíÚ%+÷JèSRRððô²¸á¥Ÿ|Lƒ °µ±ÁÑÑ‘—_Àƒv­VK|B>>Ì ‘„{%ô...$ÄÇYÜðÙ3g?ámzôêM»öèÞ£'‰¹Nß§MBhh(¯ ÎÀAƒ9pà E6áÎèÓ÷yBC³qãN}ó”y}̼?Ÿììlæ¿;áÃGboo_`»±±1xxx˜µ ¥wÏÔ©]3ç¢p bcbÌ–ŽŽ¦J•ªÆåjÕü‰ŠŠ2±W®RŸœ»¬ Å,ô 6dÇ_YÜð̹shÛ¦ _/_Æ–_~fýÚïÉΕ¨Y£S§Laíš5 :„ù Xdî ^̨Ã<›gÎ\.]¾lM.W ² wÎÈQ¯~%Š#G™µ+ŠÂëcÆòñ’=vÖÖ6fËeddpüØ1¦LšÈêU+ÿÖ³åÒÓÓqvvÆÁÁ‘ˆˆÞ—ÿ׺uïÁä‰‰ŠŒ$*2’É'Ò­{ûÔ©“‰ŽŽ&::š©S&Ë€ Âbñ}ôü*ðÞÜy,ÿê+¾]¹’ëׯãïïOß޽͖7z K?ûŒ™³gãéáNï^½Ø½ûo£½ù“O0cF1±1T®T™ o½i‘M¸7h5Züýýéc&µã[¾Š¢ààà@ÕªU jÕšßþØŽ——ùk6 .fêÔÉ Œ·wy^6œŸúÉlÙ1cÇ2c϶k@—®]=f¬‰}ÒÄw l‰µ•ƒ^Ìß»wË€  Ti;\ ì?›ð¸«¤Ç^`wôT4áÁ³kçv†Ž[¤§Wèÿ?ºõèA÷\³é’ÈÉ“'8 ?û’jN ¥n@C½¾©Í&lÃÁÛŸ¨}ëÈH—œÈÃŽÁ``Å·ß~™®]»•H§LžDll,áL›2™öž“„;@žGÿSÁ·<•*Uâó/–™ÜvY’¨T¹2íŸmK–Ndzí;0áíwdàA„^°”ÒðŒšàà!‘Á„»DR7‚ 2£J r]ú2Œ¼/Vú2LËÀV2›!_$G/‚ B/‚ ˆÐ ‚ "ô‚ ‚½ ‚p»n„ǮۥÁBZ¶¡J'CG•N„BPUÕ¢[«Eè…ˉ#‡¥¡½ ‚½ ‚Pš)“©›ví;°më–{¾Õß}ÇÉ“§™1½ÈmMœ<™€G¥oŸ>EŠûN¹ý$‚}©$33“ 6²hÑ‚bioèW÷ÆtëÖ [›»n'"2Êâ²ý|e A„ÞülQQÜÜÜh@pðà|_]–Ùý÷êÖ­K¿ ÅÒ^¥J©Y«&{þù‡V²g ‚PlÜQŽ~ÛÖ-lÛº…-?ÿÄÇK>ÄÓË“Ùsæ>”·wß^ž~ºe±¶Øòiöþ³WöJAÌŒÞäè ÑàéáÉ‹ýúñü ýn¥ ®\aÙòå9rCv6 6dôè×quqàph(Ÿþ—Ã/ãîæN¿~/С}{ ç%Õ«¿[ï¿þJjZO=ù$ǽ†Y²³³Y±r%¿ýþ;ii鼨¯½zöÈ›Ê(‚OÙΞ9Ë+/4ÙVa1Ô@½úuYùÝjÙ+Axp3úÜ‚–˜Èê5ßS»Nmãú™³èÚ¹3«V®`Å·ßàååŲeËöyï¾G¿^`ãúõ¼?>§O6Ú6nÚÄÑ£G™7o.ß|µ½^Ï×ß|›¯k¾_˱ã'xoî<¾ýú+ââÌ¿û´(>dKHHÀÃÓÃd[…ÅPP{žž$ÄÅË^)ƒúví;Ю}Ú?ב¾ýúñË/¿0røp£}é'Ó Almlpttäå—pààA£]«ÕŸORRÞÞå3f´ÑöË–-Œ1_œœœ<˜Ý»wçŸFúí7F { _?_œœœúê«fËŧ‚l*yßèTX µ'‚P"R7¹oÅKJNfÓ¦M,ùäSÞ;Ç˜Îø|Ù2Î;GjjjޏinK¦MªU«øvÅ œ\öÚPš4i @lL,¯ Γ"ʸ¸«øYp!´(>dóôð$>>???c[…ÅPP{ñ ñ¸{zÊ^)ƒúܸ¹ºÒ§woú>ÿ‚qÝ̹sø_¿™<ñIOK£gï[÷…׬Qƒ©S¦ ª*û`þ¬Yµ ooofÍš‰Oùòm¿œ—7‘‘W¨ZµjåŠâS¶Z59q⤉ÐCAíœ8~’GjÕ’½R„—ºÉMJÊ5Ö®[‡uãºÌÌL°³³ãjL /6©3gÎ\.]¾LvvößÚ|§NY´h1—/‡£×ë¹xñ"³gçGO»vmøèãOˆŽŠ"55•O—.5[®(>dkÞ¬9Ý–Z*,†‚Úص{7Í›7“½R„7£Ï}/½³³3õëÕc›ãëÆÃÒÏ>cæìÙxz¸Ó»W/vïþû–8>ù3f„CåJ•™ðÖ›F[×.]Ðh4L™Att +VdÀKýóõ¥O¯^df^gì›ãÉÌÌäýú™-WŸ ²µlñK—.%âÊ*V¨`Q µAXX“&M”½R„bE©Òv¸Ø6áqWI½ÀÞ9m-zì¥ß­YÃñ'˜9cF‘Ûš4e Ö¯_äG Üé/cKâ#víÜÎÐQcåé•‚PušèõÍïN³ Ûpðö'jß:2ÂåEáù¾}‹­­â8XÜoA„܈З!äe‚ ˜CS,‚ B/‚ ˆÐ ‚ %ÉÑ %UU¥A„^(«´ l%·ø B1"©AzAA„^A(±üµ+(ÍÀ”v5IEND®B`‚wxglade-0.6.8.orig/docs/html/properties_window_tab_1.png0000644000175000017500000005526212166606326023572 0ustar georgeskgeorgesk‰PNG  IHDRPîÉ(TÜsBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´ tEXtTitelProperties - ˆKË IDATxœìÝw|Sõþøñ×IWšîÝÒ2«ÈE€®+¶ Tp [ñ^'C†q z½ ²ÝÂW)¨àfÈT/(@  CeoJwÚ¦#M›4ùýQš6MÓÊûùxrÎç|>çýIrÞùœ‘…sÚö`A!DN}û¶à É3áþÙM‘B\$¶‚åÔ·o+Jeò<«+lꘄâ¢pö§O(É=S1(/Õ7eÍ»S‡Ú]ÏGcÿßþ¥å»¿´¤ç—º|uv¶AWÛAQÕÚÞ#){k­ºdlWÛzNlÓ®ÆY=¾»ßÓZóΣÃl¦¡"öúÄW%ºç !a ‰‰Óزe &åŽ*Í{PÛ‰pS*¹žö?µ«—)ŠG±†z’a !»ÈÄgßýÉu[“xe˾ÿ“3¦H¶ý·'o|}ŠÝCD 7½füŽJA="Ô#’è 2ue¬Û•Åêß31ŸË¼?«;sý þ}c4±¡jÒòJY¾=ƒ/wgŸ¸«{CzFâCVA«~ËdíÎ,kÿÉNU{V¹qÝ4ã÷*Ë_˃sÖ¢ (Jë¸2ÖŸñ·Æ¥ÁËCaïéBVlÏdÇ1Ãç°>Bý¼èÓ9”[¯ åª8JfvË¡ƒwÇ1Ö~ÚëS]ÏÓ³wµçŽná¼ñõ)VÿžÀðë¢HNjÃW»³¹óêˆZÛ®KŸÎ¡Ü{C4mÂÔ””•³ôÇ4¾ø#Ûa¼ö^³^Õ×Wc ´/Ï|þG¨G!ÁÅÖÄ{Jkàá^1<Ú'Ž¿S ÙôW.›÷ç‘[ltªoö8ÚëÛNÅûÏ~{ Ôº=W–W­çÌ6íjœöâô^.kG…Ø$Ï‘){­±WM—Žâ«² ïžO€ÊÝþiÓ¦ñ}•6+†Áöë8z¿U/«h§®Xr-Áä›+?l¤G>9æëôu±üîoøšréìcâªn=INjÍ—¿§òòÏ1¤×åLº-ªŒwèlF¯w_åË Ëö¬0êö® ÄâCgoÛZ—÷Q™Ñ•2°GÝëxqPZ…øðÆê9™N»˜`þ}]'öŸÌ¢Èì[ÇóèXÿ®aô½2”kÚPf²°ëh ÖæðñS˜Meø©TªJè5sÛž¿ÆnŸêzž^ÿú c|HNjMFV.E nmͱŒB6|ÿ3}­aå³IŸ/{†ôŒäñÛZólj<ž;˜J¹óŸØæQì0^{¯YgP™të –ºdšÃ«LÙÖ{aõqºú¥Ò£C(]:µcü-qLº­ »NðíßylÜkÿ#޶Áú·£ªµ½º>?\Û¦]Ó~Ùà÷sY32Ô:=jQÅÈ3׳u”ë(>·@m×\õhí»ŠƒÕW/STªºc=W)4À› ·Æ°ûà)<•r¼”óצþðÓv‚LžèÌÌ*…Á×T|mß¹S©‘/·ã–kâ¹ûšH6í:AFùùO«o¶þŠÆ`"«<€e?ì§K|4÷\Å%»<˜¡=#ØúëPVÌW¿ãί`ðµQ|¿÷ Yå!µÆQµf?‚=Ь³C< 61´ç•u®#À×S¹³>³¥œýgòÙæâ<Í3Åa´Ôü†Å¶ÿt·™î5ë»Oóswµ«x¾¤³ò»]”–”PnQaVÊ̾”â…Yñ<÷‚Øï“3}˜µf?ó¾šÿ éD9èKËYºn+^–<ŸZÛÎ7×~ Ë=×EðÕ¿QVT€ÞâÃ'ßÿM´§ ½©ÊK-¯£×ÌÙ¨ ;õN‚ÑбýÐB|=Þ·;=;µ¡g‡ ~ýët½á8ÚëÛŠRk{޶g{åNmÓ.pÔßÕ„ÚL¿÷hW†,ɵ;>wŸÛG 6+®:u°û  8]¦(uZÍ{ê! â$R¦®Œ•ÛŽ²ó÷Ýð±©[Tl ØI¾%ˆ’r AjÊõè•0Ò‹ƒ Ðã¡%ßd­›¯+¦ÄL!ìÎÓäO¬G6–@Z…TlØÓF÷·‰-"$€VªtU6îêqTí{®9„|‹m"PÎ=+άcÑæ4’oáÉûûa¶X8š¡çÝÍg8v&Å„ /‡Ï%À?¼NqÐÔ¾Æü¹_fàÿóáÚNÑt¿¬{gñË,~9V„ÖäƒO,(¶Kµ>9Ó‡#yÞ|»'»¯¯~³ã0ÅEè,Aèª<7ÕÛv´MFVô»¤@K±9­%½EF)ÁS9¿¯QÛkàè5SPÕ{{²W¯Ô3„ñméó®»,oO‡Ne°÷Àqâ=Ïò—érÊ,žZ­¶7îÂW\ÚSÛ.|íÛ³½rg¶iWã´Ç眼ŒY´Åv*’ê°%yvÛiò¨½ºÃ—æbPji³Þ¯Y]ªÔ›>¨-7Ä¢öRq0­å[ð×á”é P,Œx¡QJ(#Ða“6ìlƒ+±¿l×VK*•Û`m#ÐzîÂ;³M»¤Žþ>ºxŠRÑ¿ÊùŸ?R{í¨×tÚ4ûL_t«xüb»óß—WªµS7ßËþÁæãkYÕzN/Q ÈR±aYP0 Æ`ö¡€J±ÝåCñÀBElÿÌgtB =¯äÀ¶<] À/{Ž`QTTÝS»#±7žF1û2¾OÅa‚­»aA…‡«vj™xk w$öàƒïáQ—dž’Ô£=¯®Ü‡ÍQjÛ8t%&‚|= @ѪP¨Ö_¥â¹uf³µgÕvOvf¤QD>wÜ&c—y¤r <öG0gÍÑø)ç`¦â¢äšÏ{º%Š¢¢bÎìÊdÓ®ÓD{sM§¶\ý¶ÄydqÖ\ñÖÖ§ºúàçãÁKƒÚa¶À’/~ÅK)gò¿ú2êîëÙóá,¥žu?_v¬ü=‡I}[1 wOŽl<‰©Ô›ßÅÛ?¤;Œ·¶×¬úkãL ÕÛ«Z¯]˜šõ¿ž`ïÁè tX,PnQaT4QSlö¡Dñ«×z\½ì¨ê¶hm§ò¨å©9 ªKõ¸êh-e.ÞTä¸gi+Î%ÑÚúkO½F µ]:ý$ðй‰-U ª]ZÛE¼#>È'ØxÆfžJQì._qQk]±*h-¡5FLçŠl'Å:sÙo9„©tÜ|U,ïwéHf‰6eßîÃ㋥ʓøçáS¼8ü*ƒÈ.4²tÓ~þúóÅ?ÌŠŠU»´x2¹³G³ÇÜŠ…?Sõ,ûí,FÅ]•ÃÕãx[cn cÊ¨Š“I óþªÙ Eqj_íËãÑÞ­¸,æË-ü}:Ÿïüµª Ù@öfX"k^Æfçi/Á—‹/9–P4ÈÉ/æÔöSlØq˜(ùSlñ­µOuõadR'Ú„ùðÞ†=hssɳ°tÓ_Œ¹£OÞÍs_æ9ñ|Õ´æ\¼ ™ÜÙ£5o޼–¢2 þ”I¤JK–%Üé× æ“RÛ|[[Ÿ¹Êfzî“Ú¬ç¡%G¹ÒãŒ/ÊðA¯øRhÖP†æÊöë‘ímƒö¶½êªo‹•Û »Ûs7Gñ©…|/Û³íUËœ¯:>ú¢³3µ{@W©ýøRâËû¹Æc^çÞĵ}:×¶œÙïo×±iû|U¥”Y¼0£`¶ø¢#ˆ2ÔÖ6vý}œoÿÔ¢RÅ„Yñ#ÏLjEÅûMì:¸?ôñĈF‹‹þJI­q|±'Ÿ?÷î#B¥Åˆÿððá ùr»Ë×µŽÇUœ9y‚KŠbAQTxZJÑ[Á•‘R-,¨(ÆŸb‹?9”£¡?K1T¬³¶>û0Ã>ÜXD”*‹‹/:K0«÷ÃöWriçÊ—{¼jmÛ‘/šÙup;þJ1&<1àƒ·¢Á—²z½ŽÞSµI|y?W¨Žà¯èñÂH j:yøpÈ|™–<0SdÑ`@.äM«Ú¶A{Û^ºÕÛ©üsc{îVW|Ζ9ŠÏá´ê×7+×éàƒsuNVÔÙ²e Üqu•‡'&c)^Þj{-8ÅXV‚âáåðÓ*ÕƒzÎê·œÎXZd)Â#À ò%¯ÜŸ²ªg|ærÔ”>èñEG€u9=~œ±Ä¨âK) å˜/ôŠe5 ÔG‘”ჷ¥ AJ:‚j,ïÌ:´–ÊPáG)*‹£EM!”¨üÁâþOþr<)$€BlÞ‰µõ©®>+´„b°øPˆ?F¼I³Äœ;£à«*%Ãb¿mGôhH%– ¥µÅ˜)óâ(N¿•œ}ïUÊ'?ôäYlã¬\–sW}¸é%r÷6ØXÛ´«#>ë-=Ne¦»¼g”fã¥(DÇ]†· 2–•žz£EÁ; ¼î dËSW0õõ9`¾¢ÎT4Ê×ÉžÄWµØu;âîm°¹oÓ _æÎu”äž9Ÿ@Oge¸+n»,˜1åa2‚Å…/T**<Õ~xû…ÒÔ?&Ò]Ù7e°t’ÚŒ]¡®µì¥c‹]wmܽ 6÷mº!ãËø}­í=‘:))¨ðˆÀ; ¢î…›¹³ÄáGñ¹aý¥ùËPƒ|B*^';*v“ƒ[äºkãîm°¹oÓ__cÒgo°•µ'ŠSyçþDst¨ýbþvM¹nÑp4‘¶·ö°¹PŸuœ%#"èÜ¥[£u1Ú¿oOS‡ „hd,;n“Dk\EݹK7IN¸²ëÕü½wwS‡!„hBΑVXmÛº€À –}©@§“>¶s tîûÙņ ôìþ}GS‡Ð  ÁŸ/kê0”ô±y0lD³ÞÓ“SÈ®;w6u Núؼ] ±KBIBIBIBIBIÍÆ¸äÉM‚p³–þš^Ðu gΤ²äƒØ·o%%%´ïО{‡ §W¯›ÜŸhAÆ%Ofáü7š: !ÜÆåèÙ´³<5e WvîÌ·ßfýÚ5L?žÍ[·¸1¼‹[sýôuW\Sþó_L&“ͼEï½o3m4™˜òÜ),*jÔäéÎç~\òd»¡1ßC™Y,z)OMýM~Š9¯¾Î{ö6Úú/F.@?úøSî0€¡C[çuêÔ‰žÞ:m4yïý%lÙº€Ä„F|/¯Š;&õëÏÄÇcÕªUdçäˤ䉤McÙòdçdÏSO=uÊÌÎfý—_qøðQÌf3Wt¼œ¸??^k7÷ú'=ºw·.Ÿ›—Ǽ×ßdúsSñôòbÍú¯ØõÇ\Ó½;ƒï¾OÏŠ—ÓÞ®rå¼ÊMåÿ’®¿îZ~پݚ@?Åbáø‰t¹ªâ¦iÛwüF¯›nªWyy9Ÿ¯YËÎ]»ñððà–>‰6m›L&>_³–]ì±–¯]ÿ¥µ¾Åbaã¦ïøå×í”””ЭK†Œ··[ûèH±^Ï´³™þÂÐøúÚÌŸ>kÓž_µºÖ8+c1|›¾ûŽ‚‚BâZÇñï{†ÓªUL­ý8xø0kÖ}AFF&ô¿-‰Þpýõå« ß˜Ð‹[û$Zçµk×–1‰˜V1¨Õj„^¯çñäd¢cÎÏ;tðÐÕq&ŽäÇ&…Z­fØÐ!=zÔÕ§Æ)ï¾ÿ‰7ÝĜӘ=ý‚ƒ‚Y÷ÅWôKJbÃÆMXªüŠö†›¸%áfÔ¾¾lÜô-éL}úI¦>ý$gÓÓøzÓwN­·r#\8ÿ N,]®ü§Îœ¡°°€cÇOÒ¹Ó;v€|ŽÔ´tº\ùu¿Þô-™Y9<ÿì¦>ý$8hS¾ñ›MhsóøïsSxî™'9tÈöÞ¿ß²•#GŽòøÄñ̘ö_Lf_ýo£Ûû舟FC÷«»òÓÏ¿ØÌÿé—_èyMw4¾¾ã¬tàà&'?Æ+sgqå?:ñÙÊÏöcéÇŸÒ?)‰×_žÃ“&râÄ© îˡÇéYåÛžºÞwu½¦Î<—h`` ¹Ú‡Ëäjsˆ‰Ž±N·j‹6ǶNhh¨õ±OÅÍØBBClæ•–•]Pgâ¨kîöüÔ§éØñr¼¼¼Pûú2à®ÛÙàÿqÞjvžû¤ÏÊÎfÿÁ$ÞÜ €ßvîbø„Ä=ƒ±cç®×•‡×t»šßwUÄyüÄqÇNT$пýÎ5W_ÊãFÝí¿Wô!8è|ªúm× 4 À ‚ƒ:x MùÏ¿üʽdžÆ×—!ïf÷Þ†;^WÛ1ÐÞ lÝö3ååå@Å(lÛO¿rKïD§ã1|a¡¡øx{Ó·OoNŸIu‹‡¢BW £°¨ˆÐþ}ß=—wF±^OP°ã_lªë}W×kÚØ¯Ycpy¾[·nlùñGî½§ö/4,œôŒtÚ¶i@ZÚYÂÂÿ†pÍ%ŽªNŸ>Ú/¾äÌ™Tô%%¨Tç?Ïú'ÝÊÚõ_qÍÕWóÕ†¯Iºõ¼Ïíêèòu„W‰?"2]~~ãvàœ®¿–?ù”„^ÿ¤¸¤„íÚ¡/Öc2™øuÇïŒ|øA»õtùù5ú`[®#<ìüexµ×K››Ç´™slæ) pgÇJµd££"‰‰‰f÷¾}ô¸újvïÝK‡öí q:ÎÀÀ@ëcoooŒF£ÃXÆŽÉÆo¾á«_ã§ñcøA\Ù¹æ(¿>ü4šsï«°Z—©ë}W×kÚØ¯Ycp9>pÿ¿xâ©§ñöòææ›{ÄñãÇYñùçÖI}X¸0…§ž|€wRÑ'1Ñ-×Gs‰£ªw?øˆ;ú%1ú‘‡ðU«)1xjê¬å]®ºŠ/þ·‘õ_þã'Nòà¿ï³–‘““CLt4ÙYÙŸ¿ÇŽ—§'eeeÖ„[PP`³nw¾i[Ƕà׿ѾM[ âØÙ–ÂËËËZ^]Pp°Mr²sª•‘£Í%:*²¢¼úžKHÇ?JX•½‘ªsÃ쓘Àÿ6|M«¯æ‡­Û1l¨µ¬®8ëb¯mZÇñ訑X,þÞ€>[μ™Ó]ŽàŠŽÙµ{7·õ½µÖeêzßÕõš^èsѹ¼ Û*–WæÎãÏ¿þbô£c¹{Ð`¼ý½­ËÜ7â>Z·nÍ„‰ÉL˜˜LÛ6mqïwÄ]/Í%ŽªÊÊÊP«}ññö&77O—¯°)W…þ·õeÓ÷?п__<ªì÷ìÞ•«×‘—¯#/_ÇÊ5k¹öš«­åmÚ´æÛ6SZVFŽV˧Ë?·iÛßÏôÌL·õåúë®cÝ—_ÑñòËèxÙe|µñkn¸îÚZë\Û£;«Ö¬#_§#_§cåšu6å=»wgÕÚuè tè t¬Zk[žÐëF>Y¶’ôÌLÊËËIKKçý¥5XéÜé JJ lÙ¶ oZÇÅ:g]ìõãý>&=#³Ù €â†Çßyûmü°ußoÞJ^¾“ÉÄÉS§Y¼d©u™ºÞwu½¦ú\4Gt!}›6­yñ…ÿÖZîííÅ„ñã˜0~œÝòM_×<€\×Í‘õ¾ðgr²Ñggûœ¾rO¤:lÛº™±ÉO4ø¯|/\ü=®éNÏkŸm;wîä¥y¯5›_2?›–FÊ»K˜ñâóu/ì¤æÖdžp1÷±2öæô‹ô,ËFÙô«(É=#ß…oŽ, ?ýò+9¹¹ôè~uÝZ¨Ï׬¥  mn«Ö¬§k—«š:$!lÈ=‘š¡ñ“ž ,4”1ýl<øƒ‡ãµ×ßÀ`0¸ÐÝ‹Så(¬úˆÌl6óæ¯smîtºâr&?žŒ^¯à™)O³|™í—}öÏLyºÖö1™L¼³f¾ÄìY3™=s‹ß}///—Öµbù2fÍ™C»ví æ¥3ë¬3cÖ,¢££]ZŸ—¾‰ôЃòøäÉ\{mO®ºòJ›²#‡ðî’%=z”¢¢"cÉÒxî¹g¹­_Ú·o_k{ŽÄÆÆrâÄq:uú‡S±¹²!.6.ãÚ¶iÃwÜÁÛ ÚÌ7 h4Ôj5Ù™™¼ñÖ[äwÞÁ›o¾ÅéÓg0™Lœ8q‚Ù³ç^p»“ÐÐPŽ9l3ïÁ‡æ©'&säÈaŒÆ28ÀØ1#u½^ÏÄ ãxçúß~ó^~…1£GZO¾ÙkÏ‘á÷Žà?Ï>Ë©S§ÐåçóŸw›—‚ ú1‘» à¹çÿk3ïÉÇ'³hñbfΞMXhÆå§Ÿ~¾  ï0•JÅô/‘‘‘I\\>pÿµy±™˜<‰;ï¸Îz²fäÈQ¨<ü§O">>ž)SŸ`ê3S9j4×ßP±‹Ÿ”t'OœàÙ©SxãÍùvÛsdüø ”3hàôz=O<ñ¤ÃØ.Tõ3ú€\Ö$š¹©\3´mëfÆ&?!¿Æ$DØ¿o»t³Éƒ•Ûdõ›ÊÉ™!„p‘ü¨Óݻι.!’$P4nâ’$)Z Ù…BÉ´““yB4o’@›)9/Dó' ´ê•Ð[FŸB\ä¨B¸H¨B¸H¨B¸H¨B¸H¨B¸HÎÂ7CÛ¶nnꄸäõJè]ç2’@›©±ÉO4uB\²,‹S—JmÆäbz!_}®Á–c Bá"I Bá"·&Ф~ýÝÙœ¸Ä9úÝP!š !„‹êuéÌ™T–|ðûöí£¤¤„öÚsï°áôêuSCÅ'Ü ¡~>&*Âný£GŽ0gÎl~ùùgŠ‹‹é|eg{,™;ïºËa=!.6N@Ϧå©)S¸²sg¾ý6ë×®aâøñlÞº¥Ãîž™mý³7íNÇgð »éÙ³'ßýðGŸ`öœ¹¬[·Æí뢩9@?úøSî0€¡C——:uâ…矷»|êÙ³¼4s&C† gÐà!Liº‚kùî={?á1î0€ûx_íTÙ¥è†ëzrèÐAëôÊË­:È ×õä™)O³|Ù2›zË>ûŒg¦<í°m³ÙÌ›o¼Îµ=ºÓéŠË™üx2z½Àa›•£Ú˜¨›îk¯¼ÌÈQ£;n<±±qx{{Ó½û5¼÷þRëòöêÅDE°xQ ݯîJ«èH§Ÿ!š’Ó tÏž=ôILpºá3gq÷]wñÙ§ŸðÉÇÎ’%K­åó^~…ûFŒ`íêÕ¼öê«lÿõWÒÓÒøÏsÏRTTÀ¯¿üBï>·0sÖ,V¬XÆë×°~ý:V®\ÎÌY³¶ýîâEüòóϬZ³Ž;~Çh4ñò¼¹Û¬>š­´mÛ 4¸ÖõÕV¯²/6~CZF–ÓÏMÉéc „†…;Ýð¢…ïXûx{óÐC2zÌ£ÖyhsµäççÁäÉ;Uv)JìÝ›µ«WóàC³zõ*|||X¿~ÿú׿ùõ×_2t^^Þ,~÷}î¼½ýõ'ë×­å« _ãååå°íO>ù˜>øˆ6mÚðâ´éÜÞï6¦MÉ¥6óòòˆŽŽv©Ÿ3fÍr¹®MÁéh`` ¹Ú§>røS¦>Ëà¡ÃHêןAƒ‡—›k-Ÿöâ ìÙ³‡q&ðð#£øý÷N•]Šnº©;wV<kV¯âÍ·°bÙgìÚ¹‹›nê@DDC‡ gÁü·xø‘‘DDÔ}Pê™3ÜôϬ»Ô]®êLZÚYky}Û !##Ã¥~ÆÆÆ¹TOˆ¦âtíÖ­[~üÑé†gÎCß[oåÃ¥Kظá¬þ|%åf³µüòË.ãÅ^àó+;v ¯¾ñºSe—"???Ú¶mËë×£Vûrkß¾˜Lå|ýõFÚµk‡F£àï¿ÿfÙ²ÏX²ô-Jáĉu¶Ço;ÿ°9±t6=ÓZî¨MEQj´×«×ͬ_·Öá:íÕs4_ˆæÊéúÀýÿbíúõ¬Y³–œœŒF#‡⥙3í.o0Ðh4¨Õj²33yã­·lÊç̙˩ӧ)//?ˆÊ©²KUï>}xñÅÿ2dè0ÊsÏN¥wŸ>èõz&NÇ;ï¤Ðÿö;˜÷ò+Œ=ƒÁà°Ýz˜§ž˜Ì‘#‡1Ë8pàcÇŒvªÍÐÐPŽ9lÓÞ“OOáý÷Þeñ¢ÒÓÒ(++c÷î?5òaë2öê q1r:3ŶŠå•¹óøó¯¿ýèXî4˜o¿Cï„D»Ë?ùød–,Y€Aƒyê™gèÚ¥‹Mùõ7ÞÀK/Í`ààÁ|øáGL}æi§Ê.U½{÷!';›ƒ0pÐ ²³²Hì]‘@§>3…‘£Fsý 7”tÆ çÙ©S¶;rä(’nëÇ#?ÄeÚ3aÜ£ <Ø©6'&OâÎ;n·9›Þ¡CV­YËöíÛIL¼™Ë:´ç¹©S8ðü‰%{õ„¸)mûN°$Ü?›39Ù賎³}N_¹#dÛ¶u3c“Ÿ_c¢ ìß·‡Î]ºÙäÁÊmòº©›ÐDv }Ç*JrÏȾ±B¸J¨B¸H¨B¸H¨B¸HnéÑŒÉÉH~n®Ýu¦¥¦:Œ'-õ º¼<›2]~i©§ë‹¸xÉ1PqQ‰ï؉øŽh×á2"££±˜Í¤ž:Ñhtº ‹ÅB.°È(tº|»?èᡪ‘ « '?ï|òµX,äçæ.w½”¸´ o2™HY´ˆÍ[¶âééÉÁƒë®$.9§O#ºUÞÞ>è  ¬¬”Œ´T|}ýP«}  ²Ö+(ȧ´Ä@DTt­m+*>>j|"Õ¨T*òrrˆŒqî†^_ŒJåAPp…:%úb4~þ6ËDDEqöô)4~~xy{×hC­öÅGíCaAà£öÁGíëT ¢epiºlùrRSϲ(e!o/˜Ïï;wº;.Ñh4þ”èK(7ÉÉÊÄl6P¢×ã«ñ'<2ŠÂ‚|ŠŠ (*, H§#<2Êéõ… /)rzù‚ü|‚‚C A—Ÿ_c•ʃˆ¨h23ÒjýqëÐðòsµX¨8$*£ÏKŽK ô»~`ܸ±„‡…΄qcÝ—h|5~Jô ( E…‰Ò /ÁÏOƒ¢(DÅÄ’›6'‹Üœl¢bbQÅéõxxz`.7;µ¬ÉXF©¡ÿ€@ü)5”Ø= öÕà«Ñ§Í±Û–··Þj²3ÒññQ[GÚâÒáRÕæä}~w©U«X·$Z_ƒ¡"CaC©__?<<=ñ $?7—Àà<<ëwd©ÜTއÊéeuùù”——süè!Ž>Èñ£‡(//§@gÿxghXz}±õƒ º°°p t„†‡Õ+fÑ2¸t 4,<œôŒtÚ¶i@zzš[ƒ-ƒJ¥ÂÓÓ»b÷\Qðóó'O«¥¸¨/OoUÅçwYi)º¢[Å’“•‰Ÿ_^Þ^N¯§@—‡¯Ÿ¦Îå,f …:Ú´ÇËë|ûF£‘³§O¢²ù*ŠBdt+2ÒS‰kÝ®F›ž^Þ6ÿ‹K‹K#Ð>‰‰¤¤,"G«%G«eaÊ"wÇ%Z???´YYVì2’•‰¯_ÅèÓb6“•‘NTL+üüˆˆŠ"3ý,æ:nªg±X(-5 ÍΤ°@GHXÝÇ+NôøÚ$O///|ÔjëqØê¼½½ !'+Ó™.‹KˆK ô¾#ˆ‰‰fÌ£c?á1ºwïîî¸D ¡ñóÃd2U9æ@¹Éˆß¹³ÞÙYãëë{nùÉÉʰÛ^åu '!+#EQ×¶]¤hN—g=yT]Pp°ÃË–‚‚C0™ê½©hٜޅ¯úA///’'N$yâDë¼áƺ72Ñ"xû¨‰ïØÉ:íáái3ݪF PëãªËV}슸6íj-Óø ñ p¸žVqqvç_h\ââ%_ålæäë™B4_’@›1ùaú«úÕÏêd¤(ÜM¨hQ$IŠÆ$ß…BIBÉ.¼p«Ú¾7.DK$ T¸M¯„ÞNÝÉPˆ–Bvá…ÂE’@…ÂE’@…ÂE’@…ÂE’@…ÂEr^¸Í¶­››:!ܦWBï:—‘*ÜjlòM‚Ìb±8uIž$PávïÝÝÔ!Ñ(ä¨B¸H¨B¸Hvá›±¤~ýë]G~CTˆÆãÖšÔ¯¿lÀn–š–îô²òëõB4.§hqq1ËW¬ä§Ÿ~&''/ooºü¿ÿÇÝwàênÝýˆšLÆ2²³²0”” öõ%"2Òæ6À¹9ÙèòóAÀ  ÂÂ#n__\L~^.ƒÅ¿¡á‘xxxœ+/"?W‹Á`ÀC察aáõ¾÷¼ö8ý.š9{‘‘Ìœ9¨È(ŠŠ‹Ù»w/Ÿ~ö™5 Q]fF:¾ Q1£ãüÜ\23Ò‰mݨ¸§»¾¸˜¸¶í*–O;KW>AÁNµ¯ËÏ%8$µo,‹™Ü-ÙéDÇÆY×J´F(èòòÈÌH§U\k·÷U\zœN ýù'Ë—}†ß¹ûy‘póÍ$Ü|³u™ª»ðöŽßU–™Íf–-_Á7ß|CQq1ÿ¼ñF&Œ‡Z­¾ Îˆæ§Ô` &¶5*UÅùÊàÐ0òåZË  °Þ–84<‚/½4ƒ§žz‚¨HÛ³ª‘‘‘Ìš5“è( ´t†’¢ZÅÙ=y숵ÜÛLJRƒ͹cë¥Þv #E…h³³ˆngs8 :•JEpH(ùy¹µ.#D}8=ì{jʶþø#yyy”›L¤gdðÞûK¸òÊÎv—qútî½ç®ì\³üÎ;ïàÍ7ßâôé3˜L&Nœ8ÁìÙs]ï…h¶¼Õjòór1›Ë+ŽæjmŽQ‘›“ÑhÄh4’›“M@PMǬµ}]^.Úœ,Zŵ±›<³2Ò0––a±X0äj³Ñøjì´$Dý9=ý÷}÷±þ‹/ykþÊÊJ £çµ=™:eŠÝå8Èyåµ×¬ó*ÏÂß=`*•Šé3^"##“¸¸8|àþ ìŠhŽ"£cÈÉÊäôñŠQŸ¯/‘Ñ­¬åAÁe¤ž:Y1lsÞ`(A­ö­µýœì,NŸùôS¾ýî;Š‹õüë¾û:dpö9Ê´iÓ6l(ƒÄh4²0%…­?nÃÓÓ“ÁƒñþûK¬ =©_ÆŽê5kÐjµ|³qF£‘÷Þ_–­[HLH`ÔÈGðòò²Ö©~¼°ê¼¤~ýIž8‘+V—ŸG||<“'M¢]»v˜L&R-bó–­xzz2dpÍ~Ðëõ¤§ž¶NŸ9uÒúøäñcÄwìıìÿWr×´ Á¥j6›ÑåëX½nWtºÂ:ÆÌYŒû(ÏL™‚Éhäƒ?bÉ’¥L~|+V~ΟýÍ+sçÀ'Ÿ~Z£í;vðÚëoðøã“¸ñ†ølÙ22³²X¼h!¯¾úzzûþü“óß$,4ÌZçÔ©S¼½`>ó^y•eË—óÀý÷;ÝÏ]»vòÊ+/ĪÕkxkþÞxý5–-_NjêY¥,‹…y¯È(ÜFC|ÇNP¨+ &6]~¥¥"£Î³­L¢U»§…p·z]Ɣԯ?IýúÓïö;¸ç¾ûذa'L°–/Zø]»vÅÇÛ???zèA~ß¹ÓZ¾éÛoylü8bZÅàïïÏØGµiÿ‹/¾äÍ·0sÆKÖä ðýæ-Œó(a¡a„…†1v¬m=€qãÆZ“geqãÆNxx8ÆåûÍõûªaòc‰ŽŠB­V3lèŽ=j-ûî‡*Ú ³¶/j§/Öã«ñ D¯Gãë×Ä qá\: ¯Ó±nÝ:Þ^˜ÂËsçpäðÞ]²„£GRTT€‡ê|ŽÎÉɦU«ØZÛ_µv-}ûÞJÇŽmæçjsˆŽŽ²NÇD×<ÛQ£NÕåZµŠE›“ãL7­BBC¬}||(-+³Nksj¶/jª¾K­ÍΠ¸¨ÌŒ4bâÚ Ñhš"4!.˜ËÒ1|Ø0ìßo7sîúÞz+.]ÂÆ ÿcõç+)7›­åᑤ¥­µÍ×_y™·mcåç«l懆…“‘‘iNϨyiOõ“¡aá6Ë¥¥%¬ÊÕÞÞ^”––Z§óróu·†°pÛöÓÓÓêUÿRß±íâ/GåáA|ÇNĵm‡—·ñ;ß±“$OqQs9òùªUtˆï`g0Ðh4¨Õj²33yã­·lê$%ÝÊÿ½³ŒôtŠŠŠHY´È¦<<<œ×^}™o¾ù†å+VXç÷IL eñ"´¹Z´¹ZR-®3¾>‰ ,\˜BNN999¼“²ˆ>‰‰ÖòË/»œÏW­Æ`0ž‘Á›óç׫ÿ}IIYDŽVKŽVË”EuWºDJJðñ©¸|©´Ä€ZíÛĉ‹]}O&6—Ž&õëÏÃ#Grüø ¦>=ÅZþäã“Y²d  æ©gž¡k—.6õ‡Ê•;óÄÓSxࡇ‰¬ru¥°Ð0^}ùe¾ûþ{>ýl÷¸ˆˆF˸ñqÕ•WâáéøèÃ}#î£uëÖL˜˜Ì„‰É´mÓ†÷ް–OJžÈï;gèðáL™ò =zô¨ÏSÁ}#F͘GÇ2~ÂctïÞ½^õ/%ƒµoÅ%K†ÒÔ¾2ê®ú¯Ú×5Ý”¶}'XîŸÍ™œlôYÇÙ>§o³ÿ ª'N0múK|øÁÒ¦¥A%õë_ïo"5åW9·mÝÌØä'äטP‘ÀjË%ŽÊ\m¿®igÙ{Wλnê&4‘H߱ВÜ3ÏW9S-âžaÃ)3IY´˜n¼¡îJ-@sÿz¦M¥zr¬kº!\4 4**Š ÉɘL&n¸áz~ðÁ¦©Á]Ì? "Ä¥à¢I ƒdÐÀM†BXÉï !„‹$ !„‹.š]xqq°X,M‚F¨p›^ ½›ý%pB¸“ì !„‹d*„hÛ¶Öï×Ñš#I BˆF×Rî TÑèZÊ×}å¨B¸H¨B¸H¨B¸H¨B¸H¨B¸HΠ!]cüZü…PÅ©+$ !šDsýÚo}.ð—]x!„p‘Œ@…Û´„¯æ ÷ê•л©ChP’@…[M~¢©CÍ„Åbi¶»éî" T¸]Kùšžu‘c Bá"I Bá"Ù…¿@Iýú7Øí‡“úõ¯w–|+äc‡ß±SS‡!„•$Ðf.5-ÝéeãZÅ4`$®@—A_BdL y¹ZÌåå„ED6uXB¸Ìéjo4Ô’G;Âý %%øøúž{¬'00¸Æ2Ç´>ve´é¨¾Ù\NNV&ÅÅÅ(@`p¡aáN×7ËÈÎÊÂPR€Ú×—ˆÈH<½¼ë§hê5•„).D©¡„à ‘QêËT&­ª‰¬>ÕÏÉ΋…6mÛWLgeQ¨ÓäTýÌŒt|5¢b*Fúù¹¹df¤Ûº­K±Š‹Ÿ[váF#ソ„-[·˜À¨‘àååTŒ^ÇŽê5kÐjµ|³qf³™eËWðÍ7ßPT\Ì?o¼‘ ãÇ¡V«­m.LIaëÛðôôdðàA¼ÿþk·×¦3qTÿ¨:/©_’'NdÅŠäåçÏäI“h×®&“‰”E‹Ø¼e+žžž <ØO_‹¦×ëIO=m>sê¤õñÉãÇ€ú4órµèòò°`Á? ðˆH§o¡/*¢u»öxxT¼íÃ##ÉHO³I Ž” ÄĶF¥ª8÷Fþ±\§c-[ζl§Nâíóy{Á|ŽŸ8Á²åËm–Ù÷çŸ,˜ÿ&ßlÜÀÚuëØ·oóæÍ壖b2™øð£mÚÌÌÊbñ¢…¼óööì®yAnõ6‰£.»víä•W^fÕÊ•ôìÑ“·æ/°–-[¾œÔÔ³,JYÈÛ æóûÎõjûR¤Ñhˆï؉¨V­Ðøùß±á‘Qß±S½wÓ úbâÚ¶£uÛö˜ÊJÉÏÕÖ3"ÅæaYi©Ó55þþäçi)7›1›ËÉÏËEãï_Ïõ‹–¤^ 4©_›¿JßoÞ¸qc '<<œ ãÆòýfÛ¯õ7–°Ð0ëô†yì± ÄDGãïïϘѣøé§ŸlÚ;æQÂBà cìØGkÄS½Mgâ¨Kòc‰ŽŠB­V3lèŽ=j-ûî‡*Ú ³¶/œ£/Öã«ñ D¯GãëçR;a‘ÑxzzâééIXd……:§ëjüüÈÉΤ¼ÜDy¹‰œì,Ìær§ë‡GDQ¨+àäÑÜ8z„BŽðˆ(Wº!Z·ÍÕæ}þ p«V±hsrl–‰Œˆ°™ÎÊÌbä¨Ñ6ó*w*ÛŒŽ>ÿæ¬Ú~mm:G]BBC¬}||(-+³Nksj¶/«~,Q› @qQ!™iÄĵA£Ñ8Ýž—§W•ÇÞ˜L&§ë†GD‘Éé“'P… à<<=œ®Ÿ‘F@` Á¡¡@Å1Ðìs}—&· '=#¶m*ÞHiig ·=»YýMÞȦðIDAT8Udd$³fÍ$:Êþ'xhX8™´n@zFÍËyª·YWÞÞ^”––âãã@^n^}ºIX¸mûééiõª)Šï؉òòrNŸƒÉdâĉÌž=×¦Í”Å‹ÐæjÑæjIY´ø‚ã¸ü²Ëù|Õj é¼9~=û™HJÊ"r´Zr´Z¦,ªWýK•¡¤ŸŠË—JK ¨Õ¾.·•“•‰ÉdÂd2‘“•‰@ Óu33Ò(71›Ë),,$?/—Ððº+žã­V“Ÿ—‹Ù\^q 4W‹OÍ+ Dë¾gS×tCqËô¾÷ñî{ï1ab27÷êň{G8¬s÷€¨T*¦Ïx‰ŒŒLâââxðûmÚ|'e!£ÇŒÅÓÓ“» `ÏÞ½Ǥ䉼ñÖ[,_±œà†ί۷ףŸ#X˜’˜G+b:dì–Ψ‹Á Gí[‘h ¥%¨}kße¯úƯ|\õD“¯FCê©“X°P#:ªï«Ñzúåååøj4D·ŠµŽf©CNV&§Wœy÷ñõ%²ÊˆV4®Î]ºÙüÚS]Ó AiÛw‚%áþÙœÉÉFŸuœísú6ËŸ :qâÓ¦¿Ä‡,mêPMR¿þõþ&RS^«»mëfÆ&?!¿Æ$Ç ÌÉ­¡¨½÷qå¼ë¦nBÙô«(É=Ó¼¿Ê™²h÷ N™ÉHÊ¢ÅÜpã MR£kî_Ï¢©TOŽuM7„f@£¢¢˜œŒÉd↮çálê•|óKˆæ­Y'ÐA2hàÀ¦C!ì’ßBIB5ë]xqñ±X,M‚F¨p›^ ½›å%pB4Ù…BÉTÑ$¶m­ß/¥5G’@…ÎÙÁnî$ !]Kùº¯BIBIBIBIBÉYx!D£ëÜ¥[S‡à¢(N]) TÑ$šë×~ës¿ì !„‹d*ܦ%|5O¸W¯„ÞMBƒ’*ÜjlòM‚h&,K³ÝMwI ÂíZÊ×ô„¨‹BIBÉ.|3–Ô¯½ëÈ­]wìðAâ;vrjYCI YéeN×q׺Eó! ´™KMKwzÙ¸V1 ‰kŽ>h}Ü’„6'›°ˆüüš:Ñ„œN öFCîí$õë/#§¬zâ¬>Úª+Éææd£Ëσ‚ ¬µ-GÜ9Ê++5 ñówK[ÕÙ‹³©ú)«×T’œh•{ÕDZ©@—‡¾¸˜¸¶íÈL;KW>AÁb f³¹Åüªºp[váF#ソ„-[·˜À¨‘àååTŒ0“'NdÅŠäåçÏäI“h×®ud[ù¿$iQUaA¡áÖ÷RhxyÚœ N ‹mv……(ŠBpphòü\-…:ÊÍfüüý‰ˆˆBQ©¬‰¾òÿøŽ0–•¡Íɦ¤D ¾?"¢¢ñðð°.ę̈òÿ·wïÁQ—÷Ç?»Ù\„@.»I6ìéœ?N驌-J &™Z! &­Ú©ˆY(ž±uΙ£­.j«€M¡^Ð’ Rý« ‘3G+Šåœ¶N‹¦¹Àæ²› $°»ÉùCÙdaCvŸlHï×LÆì~¿ç÷<;øÉïöì/RÛÃñéß>QVŽS>Ÿ‚½%'%+Ë™«¤¤äÐ8Û½­:}ú´$iÒ¤IÊtd‡þ8|ú·OäÈÊVGG‡‚¿f|íë_¾—íÔç>%&&)+'Gþs~u´ûú5}æ? «ßWЏ\…ßY]­úúzmÙ¼I[6oÒguuª®© [æÃè©§žÔ믾ªÙ7ÌÖÆM›%õæ¾·öž¸È¹ž%§¤„^'§¤èܹsÃn·£Ý'ÿ¹M+¸NÓò t¦«3¬þÅ©={F¹SóUpít©Wòù¼’úCmÆ×¾ú½ÙsBi*˜>SùÓgÊ–hS»·-æ~Ej{¸Îtu)oZ¾®›~½&Lœ¤¶ææP­ÃçÕ¹žMË/дüõt÷¨£Ý¶þÙ³g45¿ ¬?g»:•;%_×͸^©“'Ës¢I]]§•7uª®›~}\ú}%ˆ)@‡ýœ·¿ö \®r99U¸Êµ¿6|Zßê•«äÌÉQJJŠ–.)ÑñãÇã3\qb †¾¾>Y­ýÿL­V«úzƒFm \¶óôç²g;e³Ù”`K”#''lÙÏ??%G¶S‰‰‰²&$Èž•¥®¯öÒ"™Vp®¹f‚¬‹¬VeÚ³ÔÕÕußbé{¬Ëf}5‹ÕªôÌLëéÕNŸ>-{¶S ¶ÄÐçÐyú‹°õÙ9²ÙÂVN§“¾j3#S½½½ÊÊΕ-1IëÕswd\ζû¼Êuö_ÎË›"Ÿ7ü¯XFfFè÷äädõÄa/ãŸÅbQoooèP¸··WkÂ°Û J´%†^'Ú’ÂêA¿_ÿøì¢¾ ¦§»[>o›zzºÕü2àÇÊÒ[ÿçe±XÔÛ×z ú/ú@Øú¶õÐ{ ýÑqþs¸«E\ÎfÚò4{TŸ/I:yò„ìGÔës2ƒIJNVOw·&Lœ(éË JJJb­¡Ùl6ùþP[þ@øt[b¢œS¦…ν¥¥ù„22³äœ˜'KB‚ú‚AÕ}ú÷PÝbµ¨¯¯/ôo=ÖÔe•xÑçpáÞ&—}í…óTYé–×ë•×ëÕVw•F½~ÚäÉjhhŒGW0ÎLšœ¦vo›ü~¿ü~¿Ú½mš”–6èò‘®äG’š:YÞÖùZ[·›–!o‹GþžsêëëSOO·Z<'m¯··WV«E«UAÿ9µ¶4‡Õ““Rtª½]}½½òûýjküþÞ„„ù{.}„í8‡2iò$ùZ› ø øåmmUê¤Á?ß±âÂñõz¤ÄåOMYi™¶mß®ŠU«%Iß›;W¥·—F½þm·ÝªûÖ¬QWW’®Bÿ±_xõyrZºüþsjªÿÇ—¯ÓÓ½ßÝ}V))×DµÍ »CÞÖ5Ö×É"‹Ò32uæÌ™P=-=]‹äñ4)à÷+))YöÁª²sråkkU‹ç¤l Jϰ««³ÿœi–Ó©¶f::¼J°Ú”žiWWggĶ22íjj¬Woo0â¹ÏXÆ9”Œ ‡|ÁV56ÔK’RS')#×¶GÚ?ÿˬ°o{êõHˆ:@/lII‰ªXáRÅ WÔë|¯dñb•,^mW0Î uÄîÈ»y~0ímmÊÌÊŠj›‹EY9Neå8Cï¥gf†ÕÓÒ3”–žiõ‹úKàòõÊÕ°M'=Q/;žà \I¢ ÐKí Å3Ü"…å՞ƶ¨t`ˆ]í{„pÞ°áý~¿¶ÿöy¯rýWóò¦ÈçõF]ÕÀ¶rsó†Õ ǰ4Óî§¹ÿV›“'OÈîpD](šç¤ lËÓì´-iÃÐ…óTYé–×ë•×ëÕVw•F](mòd544^r{nw•¼>Ÿ¼>ŸÜî*}þÐߘ#aØ—¯ËJË´mûvU¬Z-IúÞܹ*½½4êú@·Ýv«î[³F]]]ƒ^HšõÍYZQ±R@@ó ç©ôöÛ‡;0s€^lII‰ªXáRÅ WÄ凪l¯dñb•,^|Éíݶt©n[º4Ön@ÜqåÇôL`ì"@Ç0f|cÛõuv €±äŠ PKP0Ä9PÄU__ßhw¸lPÄÍÜyó£z’!0^p†P0D€€!  `ˆC("@À †ÆìL¤Ïƒ7©·}WŽEEÅ1¯ÿÿã €ÑÐtÒ3ôB_‰×•G çÞb±hÂ5×Èétê[7Ü %%‹•ž–ZŽðpµˆiô|8vww«éÄ íÛ÷¶\® =ó̯äÌÉ‘ÀXetŸ’’¢™3fh¦k†&Nœ —^Ú¡ŸÿìAIá‡ðG?þXÛ¶mWCcƒ2Ò3TVVªâ¢"IRÓ‰zþ…ô§?So0¨Y³féþûïSÚäÉ¡íìzí5íÞý{ƒAÍŸ_¨òåËe³]ÜåÞÞ^U×ìÒÞ½{ÕÙÕ¥ïΙ£Š.¥¤¤H’€ÜUUª=xH6›í¢×€‰a_…/.*ÖGXÛðäS*+-Õ»wëWO?­OþúI¨öØãOè–þP;÷Š^yy‡‡žþ…°õ~tT[·<§*w¥š›T]³+âvÞxóM;vL6¬×Ž_P ÐK;^Õ«kjÔÔtBUîJmÙ¼I92ÜaÀðÔž™¡/¾8±– _»O§NRvv–Ö¬¹?T«ªÜªo|ãJNJÒĉõ“ŸÜuQ°¹\årØírØír•ß«wì¸?ìÙ£•++”ët*55UËïY¦Ã‡‡êï8Ðߖá Wùp‡ ÿ ïkï;ìè<¬;wêåW^ѤÔÉZá*×ìÙ7H’þþ·¿kÛóÏëøñãêìì”$%XÃó<×Ù¥,77O>¯7âvZ[Zu÷²{ÂÞ³hËçõ†µ•—7%†@dÃÐ=oíÑ¿~sVÄÚõ3gꑇV__ŸþøÁzú™_k×Î’¤ÇׯÓË~¤ÿúÏÿЄ‰u¦«K%Ko [ßÓìQA~~èw»Ãq;ÙÙÙzâ‰Ç½ew8ÂÛòœ4+ dtßÓÓ£ãŸ~ªJw•ÞzkŸî¼óΈ˭[·^õ ƒ_m¬sÝÝÝš0a‚RRRÔÖÒ¢g6n¼h}·»J^ŸO^ŸOnw•¾?~ÄíÜtÓôì³ÕÐШ@  ºº:­]»>T_PXÖV¥»ÊdØ&¦=ÐEEŲX,JIIQnn®fë[ªÜúœÒÓÓ#.ÿí9ßÑ£>¦–ÖåOË×C?0Tû÷ûרê7¿Ñãk×Êž™¡¥K–èðáÿ[Ö7giEÅJÍ/œ§ÒÛo¸[n¾YV«U¿|ìQ57·hêÔ©ºëÎ;Bõ²ÒRUºÝZ~o¹l6›–””裣‘/|@´, +úæÝ±VÞ6iýLï­[ȃÁ\QÇ<)–I?ïªUùêtãCû4!{º<ï¿®³ícw.<Ä"^Ó3cA€¸âÖr¾Î  `ˆC("@À †P0D€€!  `ˆC("@ÀÐU÷mL» `|XTTó:ñÈ«.@ŒO±~¡ry}>Uº«ñ—=вÒ2mÛ¾]«VK’¾7w®Jo/ Õo]²DÝÝ=zàÁŸ©»»[?.+ Õî[½JÏlܨš]5ÊHÏЭ·Þªÿyï½PýÛs¾£G}L-­-ÊŸ–¯‡~þ`¨vËÍ7Ëjµê—=ªææM:UwÝyÇ€~•ªÒíÖò{Ëe³Ù´¤¤D=!€, +úæÝ±VÞ6iýLï­[¨¿ûx´ûQ[TTóL¤Xîk÷P­ÊW? Ú§ ÙÓåyÿumod*'€ñ!^Ó3cA€¸âÖ,I¾Î  `ˆC("@À †P0D€€!  `ˆC("@ÀÐeÿ6¦H1Ž¥øËhÅ#gâ  €Ñë*ÇCÔ‡ð—Jø5ÂÀÕ‚s `hDá€ÜUUª=xH6›M%‹‡-;T½··WÕ5»´wï^uvué»sæ¨b…K)))¡m­^µJ»víRÇ©͘1Ckî»/âã“ ÞFt´º¦FMM'Tå®Ô–Í›ôÁ‘#1ÕßxóM;vL6¬×Ž_P ÐK;^[æÃè©§žÔ믾ªÙ7ÌÖÆM›GrHS€.**Žø3˜wËU.‡Ý.‡Ã¡ WyLõ?ìÙ£•++”ët*55UËïY¦Ã‡‡-³zå*9sr”’’¢¥KJtüøñX†Æb:„ìÑ`!êóz•ëì¿Ú•—7%¦zkK«î^vOØ{Vkxægdf„~ONNVϹs—ÄψÞjw8äiö¨ ?_’äñœŒ©ž­'žx\Μœ‘ì&Ñs  åvWÉëóÉëó©Ò]Sý¦›~ gŸÝ¨††FÕÕÕiíÚõ#ÙeˆÚˆî–•–ªÒíÖò{Ëe³Ù´¤¤D=uý–›o–ÕjÕ/{TÍÍ-š:uªîºóŽ‘ì2DÍR°°¢oÞkÕèmÓ™ÖÏôÞº…ú˱G»_µEEÅ1ÏDŠeÒÏ»‡jU¾úÝøÐ>MÈž.Ïû¯ël{ãåŸ #!^Ó3cA€¸âÖr¦r€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0D€€!  `ˆC("@À †P0d‹ô滇j/w?àŠsQ€Z,–Ñè\qÂtBötÝøÐ¾Ñê Œi²§‡½¾hô‘…Ôóþë£Ù¸âX$©`aEßhw®$õoo±ü?þ«e‰—5‘}IEND®B`‚wxglade-0.6.8.orig/docs/html/ch02s05.html0000644000175000017500000001061212167336636020200 0ustar georgeskgeorgeskCommand line invocation

Command line invocation

You can run wxGlade without parameters to start the GUI on an empty application as follows:

wxglade

Run wxGlade GUI on an existing application specifying the .wxg file as follow:

wxglade <WXG File>

If you only want to generate the code without starting the GUI, use the -g or --generate-code option with the language as argument as follows:

wxglade -g <LANGUAGE> <WXG File>

wxglade --generate-code=<LANGUAGE> <WXG File>

Possible values for LANGUAGE are "XRC", "python", "perl", "lisp" or "C++".

You can also specify the destination of the generated code with -o or --output option:

wxglade -g <LANGUAGE> -o <DESTINATION> <WXG File>

The DESTINATION argument can be a file or a directory. If DESTINATION is a file, wxGlade will generate single-file source code. In case DESTINATION is a directory wxGlade will generate multiple-file source code.

This is the complete description of the command line:

# wxglade --help
Usage: wxglade <WXG File>             start the wxGlade GUI
 or:   wxglade <Options> <WXG File>   generate code from command line
 or:   wxglade --version              show programs version number and exit
 or:   wxglade -h|--help              show this help message and exit
Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -g LANG, --generate-code=LANG
                        (required) output language, valid languages are: C++,
                        XRC, lisp, perl, python
  -o PATH, --output=PATH
                        (optional) output file in single-file mode or output
                        directory in multi-file mode
Example: Generate Python code out of myapp.wxg
   wxglade -o temp -g python myapp.wxg
Report bugs to:    <wxglade-general@lists.sourceforge.net> or at
                   <http://sourceforge.net/projects/wxglade/>
wxGlade home page: <http://wxglade.sourceforge.net/>

Note

Use wxglade.pyw instead of wxglade on Microsoft Windows.

wxglade-0.6.8.orig/docs/html/ch01s03.html0000644000175000017500000000422612167336636020201 0ustar georgeskgeorgeskWhat is wxGlade NOT?

What is wxGlade NOT?

wxGlade is not a full featured IDE and will never be one. wxGlade is just a graphical user interface builder. The generated code does nothing apart from displaying the created widgets.

If you are looking for a complete IDE, maybe Boa Constructor http://boa-constructor.sourceforge.net or PythonCard http://www.pythoncard.org is the right tool.

wxglade-0.6.8.orig/docs/html/design_window_empty_slot.png0000644000175000017500000002572312166606326024057 0ustar georgeskgeorgesk‰PNG  IHDRºÓ÷{Ö£sBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´tEXtTitel - dialog_1Åi-² IDATxœíÝy|TÕá÷ñÏÉ2Ù ûÈfmDú<’¨U[‘ ¸¶àŠaÅ¥­}Úþ*ú+ZÁ¶*Ñ"Jp±¥B}¢¸ŠA „-1 Ù“™¹Ï1C&™LfBBHø¾ûêËÌýÞ{î97zNî{î5øAï«g˜ˆˆˆtÖ?o@Ý —:iNÇÖHDD¤ móÀúç £~;\RÚÑui3‡?XFeQnÝ€£º¢#ë#""Ò.Nt5í<Ð9”ýšêâc˜»ß›+ÁQID$ ‹µ*("rhë¾òLï{OCýœÑ•·¾¢>¨Èߘ$_r#¶p¿··W•QøõfNÞEX|¿¶¯ ˆÈ ­ûÊ3½ï=õs t­IýQ[zœ¤ai­j@ -œØóGrtûÛ˜1ç´qíDDÎ mÝWžé}ï騟k Ã°x\!Á8FDù·X0Œ‚-QTWZœTT”BEÅ LÃN‰3ˆÃ¶óšd˜…´®!õ‚BýÖUD¤Ókë¾òLï{OCý\aW¦’][V‘zå…òÎïšÌ‰’2¾Ë9†Ø¸HœTÑÍÆá#9trÉ?çÞ‹µÙ}ø£­Ê9µu_y¦÷½§£~-žÑaµKbr»w}Cú”‰\ôã‹ÙúÙ.V­z»£šô'<ÌFï¾=Y¼dU†‡ò,škÊš{bš,K[\èye‹¥SžÑ}øèOø¿~ÔÁ5i{ÛÖš¶våã#â/}¥¿å`X<–ç©Ïm¬IÜ^}¯—úyšÍ¼Ô¯Å3ºÚê¦Í˜Ibb"—_~%FMVgW\5ŒŸ]})55µÛ±×Ö`w:غmæ™MÊ3 +?~{qŽCôl²Ü0ÚfôÿàO#0M¨q8)©°ó]~ë² XŸ]€³žs¡í»«{µOá¬qÛZÓÖŽ8>õÿ.Ô»löǧuÿ" ùÛWz+Ç0ŒV—׸n«¾·1oõ[sO ×/99 ­ž|r€ö§~-žÑÙBBøQ¿þ$õL¦²¢›5{u5!!!TUUÚŠòÂÂÂ0M+¦égt†ÅŠÑhÜ^59€–mÏuË^œ:Ø•5.ÇŸ¿*’"ƒ¹ê'1\ý“nû{v“<}Þë„ÎCÎåcÏeôàh~ýÚ~ªìNŸ÷Ó’Ëû”Kl{ˆ¶Ú‰´VPì<µkÒ ½Îã“}%|ðÇK€áÜ>wU]ý ƒÑÇ1aD=¢l.ªbÙ–cüáú¾\öøg ¶ƒ9oÇm—%‘Ð=˜œï+Y°öÙ‡Ê8PXÅ#“˜reO¾:TʺElØuœ¢òZ¯Ç©5Æ ‰cÜ¥îuvc|ð?Û´uÜ¥ ÜwÍ98M(.¯åƒ½Å,ZŸKE£éN ‹Å`ì°xÆ‹'±{0y%5¬Ú–ÏŸå¹mûr }qÜáú9ÚZJ¤µü´¶"õ¼õ•þ–ƒa4[žaàÖ·zÊnçKßÛÚzz*vì?ŠxëîºÁ­á w÷ ;\uo¸™·ú5¸tÙÌHí41œNbºu'&²;j0M;v»“›nº‘š;7Ý<Lƒêj;àüá5*ϰ6û7ŠñÃÿ}Ê k³u½vp Wÿ8š¡}#¨±›lû¶€…«ö²wÿœöÂ,ºY*)5ÃÜöPdFRâÇjÚYñY!)ŸËÈ'³bÓ·ä:â¹~h<]{væñÔ+Ÿ3úÒ¾lÛWij+> ;·æZï \v×öv}¾¢Ÿ•‡3·sùlLMÂÇô⎿I¥Ìÿ¼±ŸÁa‡Ö/šAú0ýg=¹ÿçç°í»¬ÿê8kw4ó}§ŸF_Ëo®ëÍgßòìŠÀΤ_ q;– /Ô·Õ0 ,8€{3>Å,=Êð {rûµC 6«˜³öN,Mʸù’Dk>;ÄüwrÓÈqÿÏûj©áŸŸ”`þðûöçz“çŒmR‡fÿ›iO^úJ¿Ë1,Í–ç­ßõ˜{é{O‰—öÞø"Þ¼ûä 7ù…4äZª_‹gtÖ¬N(/)eï7{Yó¯Uôè™Ä¤‰·³qã¶oû‚óÏÀرcpz,ϰX±4³Ãç¬îôÔóºÿ/­ï>JÖ·Q]Y‰Ã´à4 jœ!TˆÓÀí×gÔÕÕ4,Ø öרná¡Ä”oFqó%ñlúh;Ô”óΧûýÎçÆá ¼·#—|G!ØNœ8M»r‹Ù•»…žNöÙO^G޲ž ÒYÆ„ð¯ŸP[^F±3ˆWÞÛÉÜÉW¸­WoÃÓ½ÖÊæÝLMƒ¤è0Î :®šspÀªHJv—ðñžOˆ `ÜÕC¸dÀ9\Ò¯;í<èõìdó}ùÄvëžÀÚŸQS^J±3ˆåï}Åàþ nDzq[‹d~pŒžÖ"‚ +ïgáök‡2üGÑôZÿ%ì‰M~׫û]ný{u-k>ÞÇφöçú¡ñ¬ÛöÇ1L‘àÓ1,np¶æ“úvèî^éÞúJËᇻ.=•ç­ßõ”{ë{OµžÍÕãõ»¢Ü>/™2˜›_<ާáÌ[ýZ<£3MÓ4 #<,{ ìøbwÞJxX4{÷î'((¤î/yÃùÃÿ›þ5ìítÜ[Ÿâéô¹¹º>ùÎAnÌð‰ 9÷ìØŸÏ–ÝùlÙWF¡=˜Z01ÜË«ûuºÊL޲PRVI°QKa'9*€Gï¹ÖmqQ$[ (qFð†#ÜwUMúNÓäÛc,Þ˾Ücö&ûKެ+³òD1effÇŠB›¬WïDY%•F<Ç?ƒpÊ ³ÔPjQE¿þ½¹ò‚.=7’  {cÇîýô8ÌNû¨1Oþ]ãÍøÚÞ·Éò¤È *NQnv««sqóu®ÿüãáLNMâ¼ÄDØ]Ç?2"”Xk ß;cšl“ؽn_ŽŠT1-ï@TD(IÖBŠÍî>Cÿ mív"m¡-/]†Åë¥Koûñ§ï=õz6]¾òΓƒ\zÆ—d¤ê¿[–o¦œVžÑ†…íÛ·³sçNBÂBùéOJ­ÝɺwßÅé„ÇÞ€iš·×` °PUYí±ü´7l¾>RÊk›¾açÞ﨩8ašÔH¨QI Ý<6?eî†~EußéE[ ÒRJ±é¾þÑ’úÆÚˆ eO~å„Ð3²iÛ~tl»ñôÛØóÝQ‚LÎJÃ0 ‚ŒZ-Ž&Û|¢–žÑÁt ¦ìx!ug¤ÇK+¦–`ÃîÇ1lE¯ÑÚíDN‘§¾2ëÎÈ··´¸I9õgtžnFiÜ·¶”·ç·öNÉÈÆÀ`ÜÒb×ò•wF5Û^OZ<£;Ø—Ç_˜CÅ‘ÝPUU…éñÖ{‹ÅBuu5÷kzF×Ì-¤%Až¿ ¶çRüCæö N ׉𠔕•“»-uÛ’Äн¹ø‚Þô´æsؙ辡ÁÄG†qÓЮEvNï}œM¡˜Xy}k!3¯JâºË‡‘ùß=Xð£Ñ\3¬/Îú«žÛ—×?`ë±#”QÌu—½¶†s­‡Øíèï¶?ð°âÓ¹®'£R‡òõb!”{¯Jn²^ÃϘ¸?´Ô0,ô‰±±ú£ïØñõw”œ(Á4ÁaZ¨5B©ÅF¹3˜J#Ìíl«±ÃÎDÂŒ ·r¯ÿúÖB~ý‹Œ¾|{ÖÄb†0ãg=¼ÖÙ0,XøÅÕhåú‘¸V±V·o”ë¶Y›]Ì=© ¤^òcvo>ÎØu¿·-_|ƒiX°ø| ½µÛ£Ön'ÒZ; ÚžKqƒ›úêûÊæÊ{!}` õÀm»–úÞÖòÖÞ©‹³1 (ì…˜YÌkwÔ v͵דÏèjâF?Þº4äeä­™ÅDÖºO/hö‹Òîü©$„J3„3šPª((.çÀÇø÷'{I°Ú)&’róäYÈ܇n§ÖîäD¥ƒƒ…•ümín¾ÞõVŠÌHj ^ßVH`U£‡õdNúU˜dªàÕOSkSbvç/3åŠdÎMº€Z‡ÉW‹yïý-Ø,5„:«Ü[f¬ÝYL|@ i—ôäoSFpèx «¶0¼oNÓt­×x;÷£R·ìŽ¿åÇÖo01¨5©!˜ #„Rg(5ã¬ßÆË<ÇÌxhüL£õßÙqœxk1£†öäùôK9t¼†•Ÿ}ÏOûGœÜÀC_sˆß^Åô[® ¸¼†åÏUnûiºÍ«Ÿc)!å'=øÇ óÈ;açå ßòåç{)'Ó°øq ½÷›~û·ÏO>t;©óvzÝN¤]xè+=õ‘5ù7½¾¯lëòÚš—úÔ rF3™¯õkù®Ë6ÒÒc^J‚šÎ[ò´v]9-×ÕÄB9á”›áà ”JÂÌr¬˜†…Ëçïb¨õK©¥U¦ §ib±€é ¤ŠPJœáÔ!¼½Ëζ¯?&Œ j  –@jÍ@LÓJ¸QÉ'û-äæ|G„yèÛG€YM…Ù ÜöW×ùXX¹£Šw~@eÔšDÇ&½(<^J}'íi;OËòÌ8¬8)3C©ÂVw'cËã›ßV|QŇ;6n”QcRI(“ví!Ù’WwùÁC¿ù õ¿´¦Û¹×½nY!?ÜÐÑÎ_+UB®™L7³„£§iPi„pÈL"˜W}×ï{â©5ƒ ¥Ó„ZK0GH$Èl~› ÂÉ5“én–D-&Pe á¸#œ£îwãë1lI1Ý £‚ãfw·åÝ”н™­DÚ^[÷•Ù÷úâtÔÏè}õ 3uÒämõN|QSú=A†ABÏs jEƒjk*9vè[jMƒÀˆØ–7èR΋àÎK#èNÝ䛼J6mÿ†ƒû¾¦Ì ã0É”šš´ìMKÇðï¥5»íåÞsk*â›¶î+Ïô¾·=ë—·u•E¹'ºƒùÇš)¦m˜8±—Ç^UF3w³xgX°Ú ‹n÷³ÏÓ)Éðy \vaa!‹—,á…2xøá‡Ú¥b­¾­UUU>r„÷þû3ﻟ§žšOB¼¾Çé,üèêÅÄÄ0uêT¦M›îZfš&+²²X¿n=åŒ1‚©SÒ±Ùê&ŽNÃäÉw³jÕj YóöjvìØÁ‹/.%÷Ð!"##?~?¿æjkkYš™Éûïo %e$wÞq®òfLŸÆÊ×ß ¸¸˜~}û2sæ½ôî]÷¢ÍÇóòËÿäËìlƒfæ½3èÖÍóü›c³Ùè߯ýÓûʲeËxèÁ[ÜGýYaý?ëζª—ˆˆø¦Í¾£[½z5ÙÙ;™3ç –,ÎÀá°³ì•ånëìÌÞÉ‚§ÿÌš·Wðô‚Œ?ޝ½Ê¼'ç²çë“OªX‘•ÅÁƒyö™<ûÌrrrÈÊZéVÞ¶íŸ3wî–¿²Œ¡Ã†òüóuesŸœÇu×]ÇK™KYúâ‹ÄÄDóÒK/ŸR~Í5|ñÅŸöQ?°½³æm·Ë—íQ/i^«º¢¢"222¸øâ‹\Ëþóî:¦M›JBBáááÜ}×]lÙ²Åm»ôô{ˆŽ>ùZt‹ÅJQa%%%ÄÅÅqß}3]ÙÆ›HOO'66–ØØX¦¤§³qÓF·òfLŸFB|<6›ÇŽåÛ}û\Ù¢…Ï1hÐ@‚‚‚ å¶I“ضÝó›³}Mié‰SÚG{ÔKDDš×äÒåæÜ>§ÏœÅî캳˜úËp‘Ý»sÑÅsÏä»]ëåçç3uê4·m?‘:.Î}æûÿð{^}mË_}•ˆˆÒÓïaØÐ¡@Ý`š˜àZ7))‰ÂÂ"·í£¢N¾688˜šš×ço¾ù–ÌÌLöíßOYYË©À?^äv‰±5ûð¶Í“±ðÙSª£ˆÈÙ,}æ,`½Û2ßÑÕ­X§~¼ÞAÇìÇf{½Q£ñÀ׿þðûÿ‡išlݺ¿üå9þùòKDGGs,/szÕ½XïèÑ£ÄÄD7)³9óŸšÏ­&ðÈ#¿%,,Œòòrnýå¯|ÞÞ“w×­ã¢Á'Ïb[Ú‡§WOxÛfwö·c/""¾kîD¡Ù›Qp¾5j .dJz:III:t˜YYüö7¿nv›ùO=Å„ HNJ܆Ԕ222˜uÿýu ÈXLjJªÏõ©ªª&44›ÍF~~>K—fúÕžzÕÕÕ:|˜÷Þ{>ø§žšïó>ºuëFnn.½zõòy»ˆˆxת».=IKa<1g.yyyôè‘Ìĉ½n3âÒÌybùßO¯ž=yø¡“SÆÇÒÌLf=Pw‡ãÈ‘—1nÜ->×çþûf²dÉ?xrÞ<¢¢¢¹qìX>lô¡7£ÓÆ`ÁÁÁ$%%1dÈÅ<÷Ü_ˆl0®¥}ÜróM<üëßP^^î:>Õz‰ˆˆ\¯é©|·œƒ½vrWòWnßˉˆˆt›7n }æ,Fün}ݳ. ²(W‘®Mˆˆti>}GwÁÀÁí]¿¬]³š>}ú´¸žëŒÎb±¶g}DDDÚÌÚ5«}^ׯ».uƒŠˆˆt6>tþŒž"""g ŸnFÑ '""•Ogt¾|Ù'""r&ÒôéÒ4ЉˆH—¦NDDº4 tÒåÕ¿GQDÎNèDD¤Kk³×ôˆ4æíLÊÛK|EDÚ’:i7 ³Ñic4¸‰H‡Ð@'§Ýoù×EJÊHײï¿ÿž‡~˜¿ýõoŒŸ0;︃·Þz ‡ÓIjJ “'ßM@@Ý¿®¦i²"+‹õëÖS^QÁˆ#˜:%›ÍÖì>×®]ËÊ×ß ¸¸˜~}û2sæ½ôîÝÛ§òF§aòä»Yµj5………¬y{µ_uh©½AA,ÍÌäý÷7’2’;︃ÀÀ@×þÿ‘Ðp™§ú56:m 3¦Okö>|˜—_þ'_fgãp8ǡÇÈZ¹ÒµîêÕ«ÉÎÞÉœ9O°dq‡e¯,÷ºÏmÛ?gîÜ9,eC‡ åùçÿêWy;³w²àé?»êÐR{WdeqðàAž}fÏ>³€œœ²²Vz,«9ëçï1˜ûä<®»î:^Ê\ÊÒ_$&&š—^zÙmû϶~Æÿ>þ8¯½ºœËSSùÓ£³ùè£xlö£,eÇg‘ŸÇUätÐ@'§Ý!C°Ùllzÿ}Ž9ÂöÏ?'-m´kôôtbbbˆ‰‰!ýž{ذaƒ+ûÏ»ë˜6m* „‡‡s÷]w±e˯ûœ1} ññØl6n;–o÷íó«¼ôô{ˆŽŽnUZjïÆ›HOO'66–ØØX¦¤§³qÓFŽdóõó÷,Zøƒ $((ˆ°°Pn›4‰mÛ·»m?óÞ™$%%b³Ù¸þú1TVVrïŒ$&ž\¶wï^¿Ž‘ÎæätÐ¥KéãÇ#si&)#GòÊ+˹éÆ vå‰ 'NL¤°°Èõ9??Ÿ©S§¹•g†×ýEEE¹~¦¦¦Æ¯òâââÜ>û[oí-**rkoRR’[{}Ѹ~žx;ß|ó-™™™ìÛ¿Ÿ²²2,÷¿ƒ££Ý·o©ÌÖüžDÚƒk s:Y9Ë\:|8Ë–-㥗^æë¯¿æf¹åÇòò8§W/×Ï11'ÏVâãâ˜ýØlâãÛ¤.¾”׸ƒö·ÞÚíÖÞ£Gºµ7((ˆêêj×àrüøñëç¯ùOÍçÖ xä‘ßFyy9·þòW§Tf[ÿžDZK—.¥C†ÁøqãxãÍ7?a¼ëF“z‹/¡°°ÂÂB/^Âå©—»²Q£F±páBrss±Ûíää`Þü§Z]—Ö”çï6ÞÚ›š’BFF‘±˜Ô”TW~nÿþ¼ùÖ[TUU‘——Ç¢çŸou[›SUUMhh(6›üü|-:õ}ørŒ4™_N]º”c±XHNNægW^Ù$»hð`î¿v‡ƒ””‘Œw‹+KKa<1g.yyyôè‘Ìĉ[]֔ךmškïøñãXš™É¬`äÈËÜÚ;cÆt.\ÄÊ•¯ÉÍ7ÝÄ'Ÿ|ÚÊÖzvÿ}3Y²ä<9oQQÑÜ8v,¶ð½gKÚú÷$ÒZFï«g˜©“æPùn9{íä®ä¯HŸ9Ko—v÷ØãÿKjj ©))nË»ê-ç͵WDÚÆæHŸ9‹¿[Ϭ«–3{ñ*‹ruF'§Ÿiš¼ûî:òóóH9²å :¹³­½"g trÚ¥¹ž„øxy䑳â.¼³­½"g trÚµtY²«]¶ìjíélt×¥ˆˆtièDD¤KóéÒå»}^»f5}úôiúˆˆˆ´)¿ÏèÖ®iþ¡±"""g¿:Í­‘ÎFw]ž6oÜÐòJ""ÀÈ˯ðk} tgˆ)÷=ÐÑU9㙦é÷ÕE tg†/æw­ýú¬M¦üþ÷àwþå¶lÍšwøýþØÅ·htÚþçOz(ôtt‘³›k ³X¬­.ä¶ÛnãÍ·ÞÂá¨{§Ýîà­U«¸ý¶I§^CE„‡ó¯ýû´íODD:‡6¹tyþùçÑ·o6mÚÄ•W^ɦM›è×·/çwµµµ,ÍÌäý÷7’2’;︃ÀÀ@Àó“ê.6†É“ïfÕªÕ²æmÏÓ¦OŸÆC=ÌE ¦gÏž×9|ø0/¿üO¾ÌÎÆáp0xð`fÞ;ƒnݺ¹ö5}Ú4ÞxóM INNæÞÓ9rô(YY+)(( _߾̚u¿k¦i²"+‹õëÖS^QÁˆ#˜:%›Íæ±=""rzµÙ“Qn›4‰7Þ| §ÓÉo¾É¤IuïZ‘•ÅÁƒyö™<ûÌrrrÈÊZéWÙ;³w²àé?7;È„……1cÆtž^°»ÝóÛÒç>9ë®»Ž—2—²ôʼn‰‰æ¥—^v[ç³­Ÿñ¿?Îk¯.çòÔTþôèl>úè#›ý(Ë_YÆðáÃYôü_]ë¯^½šììÌ™óKgàpØYöÊr¿Ú'""í§ÍºÞ½{Ó·o_þòÜsôïßÞ½{°qã&ÒÓÓ‰%66–)éélܴѯ²ÓÓï!::ºÅõÈ Lª}à $IDATƒxeù+óE ŸcРÊm“&±mûv·ufÞ;“¤¤Dl6×_?†ÊÊJî1ƒÄÄ“ËöîÝëZÿ?ï®cÚ´©$$$ÎÝwÝÅ–F/¬ÔÙœˆHÇiÓ».'þê—L¾'%‹3\ËŠŠŠHLHp}NJJ¢°°È¯rãââ|^wÒ¤‰<üëßpɰa\xá…nÙ7ß|Kff&ûö溺¬ ¨{ësCÑÑQ®ŸƒƒƒˆŠr_VSSãúœŸŸÏÔ©ÓÜÊЫXDDÎm:Ð%&&ºý ::šcyyœÓ«G%&æäÙYPPÕÕÕ®AåøñãMÊõgààÁ`îÜ'YðôŸÝ²ùOÍçÖ xä‘ßFyy9·þòW¾7Ѓø¸8f?6›„øøS*GDDÚG»¿½ 5%…ŒŒ ((( #c1©)©®üÜþýyó­·¨ªª"//EÏ?Êû<§W/®½öüý…Ü–WUUŠÍf#??ŸE‹N}_£FbáÂ…äææb·ÛÉÉ9À¼ùO¹­£)""§Ý'Œ?Ž¥™™ÌzàAF޼Œqãnqå3fLgáÂE¬\ù:‘‘‘Ü|ÓM|òɧ§¼ß´Ñ£ùÓ£³Ý–ÝßL–,ùOΛGTT47ގ¾Oó{?i£1 ƒ'æÌ%//=’™8qâ)•)""mÇè}õ 3uÒª×W‘Ócw%EúÌYn3Ðë_Ó³;{999zMOÚ¼qSî{@OFñbwö.8¸Ù'¤lÞ¸ô™³ñ»õ̺j9³ ²(W/^‘®MˆˆtièDD¤KÓ@'""]š:éÒ4ЉˆH—¦NDDº4×@çtz~⿈ˆHgÖîOFßµö5ñ""Ò< tg=ED¤}h ;Œ¼ü ͉ˆ´Ÿºµkš»·ˆˆÈ™Ê§».5ȉˆHgåÓݨ17´w=DDDü¶ëË/Z\ǯïè²³³›Í¨\¹råÊ•Ÿ¶|àÀÍnÓÏƳ³³½ª\¹råÊ•wDÞ¿žŒÒÑQ®\¹råÊýå÷#À:º1Ê•+W®\¹?Zõ¬ËŽnŒråÊ•+Wî«V?Ô¹££\¹råÊ•ûâ”Þ^ÐÑQ®\¹rågoî«S~MÏ™ÐXåÊ•+W~öå¾òy ;“«\¹råÊÏÎÜ®Îb±z]±££\¹råÊ•·†æÑ)W®\¹òNŸ{£ytÊ•+W®¼KäÍÑ<:åÊ•+WÞerO4N¹råÊ•w©¼1Í£S®\¹rå2÷•æÑ)W®\¹òN™ûJóè”+W®\y§Í}¡÷Ñ)W®\¹òN·Dóè”+W®\y§Ï½Ñ<:åÊ•+WÞ%òæhråÊ•+ï2¹'šG§\¹råÊ»TÞ˜æÑ)W®\¹òN™ûJóè”+W®\y§Ì}¥ytÊ•+W®¼Óæ¾p tN§ÃëŠÝåÊ•+W®¼54N¹råÊ•wúÜÍ£S®\¹rå]"oŽæÑ)W®\¹ò.“{¢ytÊ•+W®¼KåiråÊ•+¯4N¹råÊ•wÊÜWšG§\¹råÊ;mî ½N¹råÊ•wê¼%šG§\¹råÊ;}îæÑ)W®\¹ò.‘7Góè”+W®\y—É=Ñ<:åÊ•+WÞ¥òÆ4N¹råÊ•wÊÜWšG§\¹råÊ;eî+Í£S®\¹rå6÷…k ³X¬^WìèÆ(W®\¹rå­¡ytÊ•+W®¼ÓçÞhråÊ•+ïys4N¹råÊ•w™ÜÍ£S®\¹rå]*oLóè”+W®\y§Ì½9|èëgÍ£S®\¹rå2÷¦GÏž®Ÿ5N¹råÊ•wÚÜzråÊ•+ïÔyK4N¹råÊ•wúÜÍ£S®\¹rå]"oŽæÑ)W®\¹ò.“{¢ytÊ•+W®¼KåiråÊ•+¯4N¹råÊ•wÊÜWšG§\¹råÊ;mî ×@çt:¼®ØÑQ®\¹råÊ[Cóè”+W®\y§Ï½Ñ<:åÊ•+WÞ%òæhråÊ•+ï2¹'šG§\¹råÊ»TÞ˜æÑ)W®\¹òN™ûJóè”+W®\y§Ì}¥ytÊ•+W®¼Óæ¾Ðûè”+W®\y§Î[¢ytÊ•+W®¼ÓçÞhråÊ•+ïys4N¹råÊ•w™Ü£÷Õ3ÌÔIs¨|·œƒ½vrWòW¤ÏœÅî쮕.t‘_…Šˆˆ´·ììl¬æÉç4oÞ¸ô™³ñ»õ̺j9³ ²(—_ ÛõåíVQ‘V1½¿Œ Þ)Ï£9“i ‘.ÍuéÒb±vd=D¼º`ààŽ®‚4`†¾ÒNçïèDÎ o’޳yㆎ®‚ˆ_téRDDº4×@·õsýµ,""]öϿtýìèzôèÕ!•ikÉ=OŽi®Î4Í©ŒˆˆH[3N×Ï®ÎÑ`¡ˆˆHgæð4Ð95ЉˆHáñŒÎéÐ@'""]ƒÇ3:}G'""]EÃ1íä„q£#ª"Ò¹ŒNÔ=$$$„ÄÄD† ¹˜±7Ü@÷îÝ;¸v"â‰k 34Ò‰øä5oPUUÅá#Gxï¿ï1ó¾ûyê©ù$ÄÇwpíDêþ­§3:‘V²Ùlôï×þéý eÙ²e<ôàƒÔÖÖ²43“÷ßß @JÊHî¼ãº3ÃÓ§±òõ7(..¦_߾̜y/½{÷ê.»¬ÈÊbýºõ”WT0bĦNIÇf³uLcE:1=L¤ üüškøâ‹“OZ‘•ÅÁƒyö™<ûÌrrrÈÊZé¶Í¶íŸ3wî–¿²Œ¡Ã†òüóue«W¯&;{'sæ<Á’Å8v–½²ü´µG¤³kxîfñ¼XDüMié ×ç7‘žžNll,±±±LIOgã¦nÛ̘>„øxl67ŽË·ûö¹²ÿ¼»ŽiÓ¦’@xx8wßu[¶l9]Íé<\ºÔ0'ÒzÇÑ­[7×碢"\Ÿ“’’(,,rÛ&**Êõspp0555®ÏùùùL:Ímý†ß9ˆH üç¢ïèDÚÀ»ëÖqÑà‹\Ÿ£££9–—Ç9½êž·wôèQbb¢}./>.ŽÙÍÖÍ-"­ÔðK‹§…"Ò²êêjöíßOÆâŬ[·ž_Mü•+KMI!##ƒ‚‚ ÈÈXLjJªÏe5Š… ’››‹Ýn''çóæ?ÕÍéštF'Òz£ÓÆ`ÁÁÁ$%%1dÈÅ<÷Ü_ˆl0nüøq,ÍÌdÖuwaŽyãÆÝâó>ÒÒFcOÌ™K^^=z$3qâÄ6o‹ÈÙ@oñCýº–1%=)éé>—Óp™a¤¥&-mtë**r–Ó¥KéÚ iO EDDº Í£‘.§™K—"""]„.]ŠˆÈÙB—.ED¤ËÑ¥KéÚ<]º¬ª®êˆªˆˆˆ´¹êª“cškÂxø(ò(ì ‰øbóÆ ]é$’ãO>4Ý5Ð9ΩŒˆ/ôä~ñGÃ1M“Na×—_ttD¤“ÒÆED¤KÓ@'""]š:éÒ4ЉˆH—¦NDDº4w]f,|öt×CDD¤]4èÒgÎêˆzˆˆˆ´ ×@W‘¡ôcÄïÖwd}DDDNIh|?–7xh0Ðý²Oÿºêÿ)""Ò‰=ýIÝ?]ÝÓ+æuT]DDDÚÐûêfGWDDD¤­Xÿ¼ñÿá XˆÛ…IEND®B`‚wxglade-0.6.8.orig/docs/html/properties_window_tab_1_change.png0000644000175000017500000004233312166606326025072 0ustar georgeskgeorgesk‰PNG  IHDRPÐQ/9µbKGDÿÿÿ ½§“ pHYsÄÄ•+ IDATxÚíw|EÿÇß{—ä.½÷Ð|h‚åQ$  ˆÒAÁ@‚(VzWPü) ^õĈ HÞ;ôv)—r—»ßG.¹äZzaÞ¯W^¹ÝÙ™ýÎÌÎg¿SvWâ ºŽÕ#›Üøõs À¡@<;½4G”Š@ ØÁ>ÐßøõsI*ÏÛª Q*@`·ÿZMvJ´ÁÈÏU‹R‚RP( y•, º|2bΓ›‡>_[êè’LŽÂ;÷æ “‹šª» Öô6]öñ@³J:N”ð;¿÷áS§Ú}ò½{÷¢ /WUÇ_Ažà}qPº•:3ÚœLRÎï'ýÖY\‹Æ ”’Šnƒ5½MW…}F5§ÐáÀ´;¿§Ó¦M³ûäÓ¦Mcw‘4ó2S nÿ,ŽeÈ€“³~Í#æßÑç×­A (%Ýkz›® ûŠø«_cEÓ”ÀÉÙ½\É9ºxª [‚ºNE·ÁšÞ¦«À>£€J’TñöIS’dH’¦¬Rlê¼~Vp¬émº*ì³êîíÔ‰iáá†ß{÷ÚÕ…Ÿ>}ïÎÿ^þ;õ©"ÉË‘Y0âÇ‘¾%ö=ûU²§V~×z ¦=À£Óþj ê¦ BËm°´é É̦g®-ÛjÛ•Õ¦­ÙgN_,…Y³ÏªnÍiÓ¦Ù) Ó¸3bjêÊ䥺øio‘ìf¶P,Ý þšú°éˆVGlZ.»O&ñÃÁ4ùµãa«‚|<6ýÙðÊ[œË­W«ÆVžjZÚeMÓÞº)~­VF¹˜m;•Ž$•9½âmÛZ›®¬üþ8Ò—^E„rGá/}ÖÇ@õåÎAáo™Œâ6la0º÷×Éøjo™„­ÝÚf‚Lfón5rÞ&<]• |¢5#»Ô#ÈMÏ‚]qÔ¦çUïSÜâ\^áàõc3þ¡ƒò>r-^r5i:·gs°—‚'ï÷¥ëý¾¼¼ì”ÍòL»êæ±ÿpŸÓM¾š2Àìy¾‹ø¿žNæ·ÓÉĦåVLfÌ´Á²¦ƒ$³˜Þ«ËNXŒº2¢5’„i<;ÚtEå·÷×ÉFÝÙ1Ò×d»ÀöÒØWD@+æЩÓ^Âç±wï^´RÏ"É˱4"á§½EŠC=»Â$InÓVyqZo3µüðÛ)jQð–þ¬ýýÑÚöЀŻnðƒñ÷p¢ãÌ#È$èÛ>€¾íòT¯ÊcÛÑ6‰GwGyÿºwÖök¼øß B}”Ĥæ²îP?K,´x¶?ý;ê­ !=Mÿij5*Á(â™±£hÎ ×c39þA^™» $ I’lž£e¨cž £I  Žr‰73X(žÃWTvú¸:Ò¥…OÞïÃýanäjt½’Dc§8®j‚ù4—'[åôγèÙÆÅ»n°ùHƒ $²[}~:–È3mý-¦m‹.-|xþ‘ êû*ÉÎËgÕŸ1ìø7Ѫ½Y¸vŠ šÙÕžRuî&׬—<Ë(¼7’sÖ1˜Q]Â8s+ƒÝ§SØs6•”,M9Æò,·ÁÒ¦c¸þ̧'Åö\^4ž=mº"óÛ÷ë¶Žð1qâ†/;a´]f&¿6ºðs(èöO›6ß‹¤ipƒ-e»Ã 騲U"EïEšÎßü°ò4’tÞÆí‡B!ò«pÖ¦ÐB¡åþ6ˆìVÜbÁÓôïx/ãŸj‚‹,ï«L¼×Þ÷;óáÚãxIéŒxº5“Ÿiˆ‚\6Ï Ïþ¼Õ£>{NdzpÍ1žy¨oöh†’\ÖF¥›dª¨Ž’–/'õ`òÂoÈÖ+há¤àœ¦ñx…L‡*߃>ímŸcj߯„x+X¼9ŠK×ciìÅ‹5çìõ2uÎåªë­}éÚÒ‡¹“§ÕsôrŸm»ÈÅ«7Ðióp•ÉðeÓqÖQö¿ÿ€Ù<Ù*§E»¢i¬ ²[=âRÈÔ»0öÉz\‰ËàçßðÝ.6¼ÓÍjy™£‡Þxªÿ^Kåý‡@›Ë36g¿<˪½–®è`¼ö &Xl¯ó3¹f‹ÆûpóUZ»Þ¢}cZ5oȘ'ÂÿT}Ž^Kç×3©ì<‘\Æ®wEuáeÓ³uÿ([›¦BóÛoE [†û·G,7xž)õJH®5û*Ü-QRF#,w$+§/&Éd¶m½ÉÇ݉±O†pìü ¤|¥Âµ©üuO­* :™D¿ w£CQÇÐæjøñОx  ½`÷ÑkÄåÞ­~Ù÷7.9ZòÝYûÇYZ5 ⹇ùóômó½Ð!€}ÿ yYüôÏžùo3ú=Èï'¢IÈ÷¶hGÑ|¤ë\ð’gw{ËÓñÒe2 CK›çpwv@›¯C§NB§Ïçltg£æ ãŠ6 ¾äûßkg²Ýqö¿f‹ùÝgÊë\,~;Jnv6ùz:I"OçL.Žè$‡;b>Oöäaö–³,Ö–÷ú7'9êÜ|VmÛ‡£>Ia1í4å%,Ï=ÀOüC^f:j½‚Õ¿Ÿ!ÈA‹Zël³¬Õ™½¨Ù ½H¼9^¨Î©8tá0ÞÎ êÚŽÍëÓ¡±'Ÿ¾Yê!©‚ºðmÐRz’ 9)S›.£–’ÝüªÉö×£ZÓeŠYÿÜš}îšê§Ì®îƒ„dw˜$Ù¾[ÍŸ80L"Å«òذÿ2QGŽ‘ƒÂ$nfVYúÒôždç»àï© _ŽZò%6ËÓ Xî.Ë“IÓ{㦩²ÈÖ{‘;ÇR] à žn„ÊI×{âmhØÓFö0±ÍßÛYª"»¸Eóž¢ó&Mï^¢L$dvcùž"Ÿ æ­—º£Óë¹§æ«=Ñ\‰ŽC!iÑâh{ÐñçµJìŸ÷ÓMúüGÁƒÍƒhwOwN\Màà¹^É$Y«@ƒz$ÓÆR,OöäáRª¿¥÷Ãð—ÃÉÊLG¥÷DU¤lЧm­MxòžL–Îd½7j½)Io³¬Õ™„¬ÔíÉ\¼\o7i@—ûÜyè/œd\¸ljsWiâp›ÓÚ{ÉÓ;TKÞ°´ÇR^²zž²´éŠìÂo|µÐyymùI¾ÕÊ(ªW¦ZÌoµz æt­JÅ[mÌ€¹0óºÖmòÑ·¨õJrPÜÉd>  MçŽF2Œ \É‘\Ð#‘˜®!ÌG‡›‚ÌTgœÝ wøÔ 5 4(Šx¯ÞžnœIp% g¼ K²*¥”‡BÊ#)CC°—s–m$>#ßh‹›”³\‡"_cÑŽ·kÌßæí9ÇŽã)œ?{ŠVzš4¬GÏÇZñ^¯F<ÿi¨q6›ôãsOÐÞñ Nlô‘—,ƒ4½‡Éq?ŸJåÂÙhê»åÒ®yZ5oÌø>mˆÐèøûJ:n½aÙ¹sb{òæïIöõˆMÎ@ŽŽ'hÂѳ׹ïL®ö•W1Ò çõóråB‚;Y¸’Œts7 i–ºÎìñBïě޷4ñ@é(ã|Lëö]âôÅkä©Ó‘ôz48â"e“‡G¹&U6 ó¶mЪT3“H’ÅI¤Òvá©$ÔV~G}yI2ä¯`ÿÆW½-ç·¼è´i晾 hcø=µáTó¨…%iŽæ›½5ÑÆ0ÉÎñˆ¢b¦ÞаôHä $G§ wrQëKÈÑc°mç©4Fv ¤S‡–œÛŸJ߇ƒ8xüzIFÑžZÏðöœßyIç̘.†a‚}G/ G†\‚MQÉŒ{2˜žáíùæ· ÈóáÞPºµoÄG#—aÑU¶Og|¼Ü‘’eHÈJäO’dvcvßFl:ä@T\ ™¤Ñó1Ðjò¸G~‹sùMÐbÞƒ¹­ ÂUR›Ôe ;€X} ™™YDg÷Ñ›z9ñ@󴽯aònë eh)O¶òàª3£oCtzX¹ão¥|&¼Ð•½æø·çÐç:Ø./3l8’Äø®!ôêÜK;¯£ÍuâÅÿòù±VíµTgÅëÆ°¯¡¯’í_ãÄùk¨ÒUèõ¯—¡‘\Р$K§ [r-Õyʺì¨h[,1jæøå¯µ²ï^Qc ÂF}yÒ¨?ðܪTÖßQKù-·jièôëÀÐ;{-Z^Ä;ø›4¼4Ѧ¢/If7,j•lVO²Þ§„ÇT¢æ(¸v®ý' _™ŠÇïeE«¦Ä§kùnÏeN»HÎè‹â©‹7˜:è~ü¼ÜIÌаj÷YNŸºB–Þ$cÓÑdsây¦}s^{=§n©YûÏm4’U‘á€âv¬ØŸÀkù2i„a2©ÓüÓæZ›]çøéd*£:‡pOð}hòõœ¹™ÆïD)ËÃE—C:æÇ ãô%—±™)ölœÉÖ;“¤÷Á…’Ò²¸qè?¾H \K^dé-æÉV†wkN}__ÿ|œä”Rõî¬Ú}š×z¶á­§‚x÷ÇT;Ê«$[þMÁ)'žgÚ×ã“á’™§çÛ¿â %“ ÷³»JŠ¥ý¦ì›|¿épÈ[¯˜œgèÊË´”_B„FïH Ô’3:òP +H_* oSæÚ^ G®X[,hƒ^e¨%ûd’Dš£él{Ñ0{í«Â1Pë£/*3ž¨d!MK¶†/8Ëò“8Þ¹ˆ-Ý-§ÓÊC*v:‡³,—<½#:$tzgTx’‡Ò˜ÆÑ3WùõT22 —KZt’+©z/òP"I2vœÕrôü!\Q£Á ŽhôŽèõrܤl‹vì8žÆ©'ñ—%£Á‘ûä Îëî5{¼­s¾*#úú5ÜõéH’I’á ÏE­÷0üxÜÑbÚÖøñ¼Ž£çá&e¡Å8I.8“Wª:(͵Wôl&»|g¸B#²QÒ\®à‚îÃ,½Þ9:2õ.ä D‡Œ2è¦Í6¨r´½ð_2Ó+:½ÊÐköÙfÍ>«hÑÇ7 ¿-XzøæNœë†8{÷î…žÏÞuäh5¹8:)Ë\ š¼l$¹£Õ»Õ-}0®¨‹x¥;NÑú<õ™8¡AäÈœIÍw#¯èŒ/ ’¼A—’\@gT¸SãJ´>)gr‘ÈG+9¢–\ÉÓ+É¢q‡'}.z<¥tTx–8Þžs$ë½ÉC†+¹Èô:4z%¸“-s}Åßùóq w2p7¹-åÉV²$=Éø£WœˆÑߎ‘p–å§7Ÿ¶5Ô¸p‹P<¥L”ú@Gè$9 Ù]¥½öŒÃWx⊚T½©çIÆ·ìjiÎó«à6XUmº¦ä׬H|ÒãF|,•I^F"Ž’DPØ=8•!Cš¼lbo]F£—pr÷£ºØ;±™a¢jÑ÷œÓ5³ÙHÕ[Of½¿.ÔÙsWe¬émº2í‹ÚFvJt¡€ÞLˆ«ÔÊÓ£C“™Š6'ôex R’á tÅÉÕ§Ú_&ÒN:†yœÓ7Zƒi&]´vAߴΞ»ªÚ`MoÓ•i_Ü‘­¦ßDªlQ’áäî“»­o˜· Õ¬;n½x7iM% oC=™ÁÐMöª“箪6XÓÛtUØWâmLê„«¢åÙàúêÔ;‚š]Oæ¨Üº«Îs *—€Ææ´@&®ÙÆ´tÉbQáÞŽ¹ÍÄI“hÙ¢K?ÿœí[·0nÌöìÛ+Jµ†ß}+Ê®Iï}€V«5Ù·üë&Û­–Iï~@Fff•ŠgE–ýèÈ fÿêÚ5ŸÀò«˜8å=^Ÿ0‘¹-âßã'DC® ô»ï×лW/ôïgÜ×¼ys>|ÿýÂÆ£ÑðõŠ•ìÝ·€ðN1üU _>ìÖ½ã^M›6‘˜”Dhh(ã#Çs;†µëÖ“˜”@“&M˜øæ[Ô«Væ8öØ9nëׯ'5-•&Mš0aüx6l(®+4n؈“§NÓ®­áå3Yj5'N!3+ 7WÃGýŽŸ8IãFpws«Õy­ëžsBb"‹—ü]ŸèÂÀ~}ðpwçÖ­ÛìþãÚµi-.öŠÐãÇ3ìå—¬óÃڵܸqƒÏ?[Àü…±vÝ:^~©0Þ?ÿüü9sðöñfë¶m¼ÿÁ‡´nÕŠ¹³gâåmØ÷égKøhÁ‚2DZǎ£G£X¸p^žžlÚ¼…O—|ÆâEWZÁÇ'&²ýÇŸ¸xñ2:ŽfMïå…ÁÏáæêÊ¢O?ãñŽÒ¾];ãñ)©©Ì_ô Óß‚ƒ£#[¶ÿÄÑÿàvíè×û,v• öx4ÿË# ?ô 2 èÕ«×Ðëõ\½vV÷>švèð?t|ì±våçç³qËV¢ŽC.—óD—p“´µZ-·låè¿Çá[·ÿhŒ¯×ëÙ¹û7þ}ˆììlÚ´jÅ ýP89Uh­‘¥V3mæ¦ø.ÎÎ&û§ÏžË´÷ßÅY©´hgƒ d÷o¿‘žžAX½0^|n!!ÁóqþâE¶lÛA\\<îôxª>òp¹òòÓϿީ#O©‡† ðÚ«ÃLêÄÚug«N­ÕÙ]×…OOOÇÇ×úkøß³—Ñ£#ðóóÃÏϱ£#ø}Ï“c&¼1žà`”J%ýúöE­VóFd$AÁ…û.œ¿P®8öØùú8‚Q*• П˗/WjÁµâÂ{Œ¹3§1gú‡xyz±mÇOtïÖŸwîF_ä-Ú?ïÜÍGéìÌÎݿǔ·ßbÊÛoq;6†]»+•'µtÉâr K«–÷q#:šŒŒL®\½N‹æÍ¸råi*·bbiÕò¾qwíþ•ø„$ÞgSÞ~‹3çΛ„ïüe7É)©|ðî$Þü.˜¾áý÷½û¸té2oŒÃÌi Õiùé;+<Öpuq¡]ÛÖüuà Éþ¿¤Ãípqv¶jgçΟcBäë,œ7›–÷5ç‡ ­æcÕ÷kèÑ­‹ÌåÍñã¸víF¹óráâE:¹a›ÃÖug«Ní)‹»F@=<ÞÞ¼8ä¹ ñ¦=½¬¿±ÉÖug«N«ºÎjt¾M›6ìýóOžÎråùøúKƒúõˆ‰¹¯_Õ®¦ØQ”›7£Ù²ãG¢£o¡ÎÎ6’¬ð~Ö£Û“lÝþ´mËO?ï¢Û“Oàt§«£JSáWÄ~ÿTiiÕ’G~ïW¯¡SÇGÉÊΦqƨ³ÔhµZþ>|„áÃ^1O•–V"¦á*ü| o”~Åê+9%•i³æšì“*áËŽ¶Æ@ƒâØÉ“´oÛ–c'NиQ#|¼½í¶ÓÃÃÃøÛÉÉ FcÕ–ˆ‘ÃÙùË/ü´s®.® êß—–-î+·7m¸®|-c뺳U§U]g5Z@_~éÞœø6NŽN<þxG<==¹zõ*ë7n4N$u ïÄҥ˘øÖ›|±l9]Âë<“5Å“.ü7ßѳ{7F¾:g¥’ìœ&Ny¯°{|ÿýìøßN¶ÿø?®^»Î+/1†yzy’””DpP‰ ‰xz~cÇÑÁ¼¼<£à¦§§WÚE[/4€¿ÿC£ú Œcg{ÿü GGGcxq<½¼Lò”˜T,Ü“¤ä‚ áÅ{.ÞÞŒ3 ß"½‘êj˜]Â;ñ¿ŸwѾm[þØ·ŸÁØm§-Ìå£~½0FŽ^¯çÌÙs|÷Ã:æÏš^®<4kÚ”£ÇŽñT×'-c뺳U§å-‹:Õ… eá¼ùœ:}š‘£"èÝ·Ÿ}þ; ÓÁC¨W¯cÇE2v\$ ê×gðóƒ«<“5ÅŽ¢äåå¡T:£pr"%%•5ëÖ—h8=žêÊîßÿ G÷®È‹tƒ;´kdžÍÛHMS‘š¦bÖ­<ø@ÛÂV¿¿þ±‡Ü¼<’’“Y³n£IÚn®®ÄÆÇWX^~è!¶ýøMï½€¦÷ÜÃO;wñÈCZŒó`ûvlÚ²4•Š4•Š [¶™„wh׎M[·¡JW¡JW±i«ix§ŽÿeõÚ ÄÆÇ“ŸŸOLL,+V}Wiy´F‹æÍÈÎÍaïþý(œÔ µÛN[˜ËÇŠo¾'6.Ng¸V*àÃñÏ<ýìÛÏï{ö‘š¦B«ÕrýÆM¾\¹ÊîëÎV–·,ê”ZÐP§~øÅp''GÆŽÍØ1£Í†ïÞµ³Ôûʧ¢ì(ëØ™¹îàKƒŸgÓÖm|µê¼<<èúDgŽ?izw“døûóp‡&û{tïÆ–m;˜·Ð°J ]Û6tª[á cÐ@V¯ßÀ/»ÃÃÃnO>ÁÉÓ§áݺ>ÁÂEŸS!“,Ú·cóöÜ{G@ï½· ­–í-OJôèÖ•[¶2sÎ|äržìÒ™ó.˜äqæ-̘mïØ‘ó 'öÂI’ñå×+IJN! ÀŸ^={TZ-ÕcO„wbͺ ¼>z”É1¶ì´…¹|´nÕ’å_¯"%%…  @^}ù…rç/Àߟ7ÆaÇÿã»v‘—§!,,”nOt±ûº³U§å-‹šˆñ»ðÑI‰¨®rhnWñM$ìß·‡ˆÈ7+ý-ßK¿üšö´£ÃíªQ„ îhä¸×Ù±ãG¢£oY<æÖíÛ̘5‹þÑ·_¦Ï˜‰*=ÝÄ[ýñ§ÿñÊÐa<ý̳ŒÁé3gؽûW†½:‚gzõbü„ &çÐét¬ùa-/¿2”~òñ¢ÅäääÜuÞgqL§ÓñÉâE<ؾÍ›ÝË„7"Q«ÕLžô6ëÖš~‰qí?0yÒÛÓ³†V«eÁüy´o×–fMïaÙÒ/¬ÚèÏ—Ë—Ñ®mkB‚DKuuue|ä8æ-\@¾Vkö˜™³fÓûÙgùaÍjVÿ~~~¬\¹Êä˜þù‡ysæ°eÓFºtçý>äÀÁƒÌ=“M6ððCñégKŒÇoݶ“'O2þ<¾ûfZ­–o¿ûþ®òÆÌye_}¹œƒ°iË6>‚Fc9€Y³g³~ýZvlßÀöíÛØ°a³fϱ˜ž5>ÿ¿Ï8|è›¶l埢ˆ‰‰±jÀßòóÎ_ˆ‰K¨Ý Iæÿì[™6ÿ]Ü^sÛUYn•‘ßÚ* ­Zµ¢mëÖ|ûýj³áË—~AëÖ­Q89áêêÊС¯p$*Êä˜ oŒ'8$¥RI¿¾}Q«Õ¼IPpá¾ ç/ÿyçN^},ÁAA¸¹¹ñÚÈüõ×_wýÝoõêï™;o>õë×ÇÓË‹©Ó¦ó¿Ÿ~ÀÑщ/¿ZÁìY3˜3{sfÍä˯VàèèX¦s­_·–ÙsçÒ°aC<½¼˜1s–Í83gÏ&((¨î¸^oúW]âiÉ®¢ç,ØW|»6Šg ¦LO" }åÞ˜0ìÀý-[š„]ºx‰¯V®äòåËdff —™ê´ñ·B¡ÀÛÇÛd_n^žq;!>á#Fš*¿L, ¸Íc>b±\üýý0p‹>þˆ©Ó¦ãï_ö ™˜˜5j\ª8¡¡au¿Š ”¹ßǸ¢âgm¿¥sÙ«âûÊcƒ­ýöæÝR,ŵ·,m[K£:ÔÁÁ·ß~›™³f±ä“OLÂfÍ›9úJ IDATË‹C^àƒ÷ÞÅÅÕuVý*—‘Ìž=‹ ÀÀ»V,Í}>4,Œµë6P¯^=³qΜ9ÃÚµ?°rÕ7¼ûî;<Õ½5²˜žu1 åÚµ«4o~Ÿ]¶•åµ^H  èo[ ½¸ÀXjìÖD¦h\{ÅÅ^ì9Þž¼—¦ ‹wÛK›†-{«³ _@ƒúõy¦gO>_ºÔdNN...(•JããYüé§å6ò™gzòÉ'Ÿróf4Z­–k×®1gμ»J@}||¸té¢É¾W†c⛸té"MçÎ#â5ƒ§®V«7v4_|±ŒO÷dþ‚…¼6r¸qòÍ\zÖôü`Þ{çnܸ*-?xߪmuV$-'Ve÷¸¦½#¡4örsC 5t¼³Â<Ðz÷êÅ»ï`²ï­7&°üË/™5g¾>Þ 0€¿þ:@yÏ#“ɘ>sqqñ„……ñÊË/ÝU:.r<Ïô|št•Ê8Y3|ød’ŒW‡ åæ4iÒ„ISÞ`ÊäI 1’‡1tñ»u{Šë×®ñΔI,þd‰Ùô¬1fÌX²³²èÛ§jµš7ß|˪m奸Œ>PýËš*J¸j‚8”Ö†ª²ÙO»Ù+>*WÙ¿o‘oŠ·1Õ$ÏÓ’€Zë"Ûê>Û{ŽÒœ§´]x[6TTÞm‰¤-ÛËr\9{ò8-Zµ1ÑÁ‚6Yü£rb&F ¨î!êô®JkCEt¯íóŠ*‹Jï”è2§¢»ÎUy®JíöÚjøÅ'VŠn—vXÀÒ$MYÄ«46”Õæâö–Õ¶Ò–EyÊX¨ ¬T¥pÕºG4m Ly¶K+J¥ùm)ÝÒÚ`ï~{óZÑç*Íy+Ñ…áÖ=Ädž ZG,róÐ+œDA­}ˆxAµrý:´m ‹ÃС¢<„€Ö:vê,¼OAµÒ襗qNKƒaÃHÚÿ' ã#E¡˜AŒ üV®Âùä)COHᄪW/Q(B@-”.à¿l™q;>2’ÜF EÁÖró<)×ð&´¬öíIyñQ0B@-ü—-Cqí:ùîîÄÌœ. E¨@ °…kT~E¾ÿöD4!!¢`l fák û÷í… ¨2ä-ÏÍ.|=äõVÿá/w¸Ë¯ÃŽ: ­­DD¾) AP%¬ÜïüŽ9yЏ»üúÓëõv-%ZÃ+Q ¨Tví‚=Œ›A[·Û§Ï]]$¥Yƒ-Æ@‚»•¸86¬p{èP¸Ëų´îV&L0ˆ(@ÆPìó<‚*ÐnÝ{ˆTÖÞ*('ß|ëÖn¯ZJ¥(á ›]÷  ·§LðpQ.e T“HÑÑ·XùÍ7œ|ÿ}³Çߺ}›³fÑà úöëÏô3Q¥§Ã?Θ±¯óL¯^¼ôò+ìܵˮ°»‘GêÀ… çÛÖŽ]]¸pžGêÀäIo³níZ“xkøÉ“Þ¶š¶N§ã“Å‹x°};š7»— oD¢V«¬¦YàÕú›x¸/\Àð#‰=†ÐÐ0œœœh×î¾^±ÊÄ./8П/—/£]ÛÖ„ˆ–Yœ?oÚuŸ<Ú´åRzüøqº„w²;ᙳfÓûÙgùaÍjVÿ~~~¬,ò¨Øü 2x0[7oæã>âü¹óv…Ý„wî¡¿ÿ6x11¼÷î;dffð÷Áƒtîò³fÏfýúµìؾ€íÛ·±aÃ:fÍžc5í¯¾\ÎÁØ´e‡A£Ñ²`¾á©ki÷f Ø¿ÿOúôígsÈÀœü÷Áƒü¼óbâDˬ † ƒœÃiÓD™”»Ç@ÓÓÓññõ³;áåK¿0þV891tè+Œ|m”qŸ\.'9%™´´4ü™0á »ÂîNíÌÖÍ›yeè06oÞ„B¡`ûöm¼ð‹üý÷Aúˆ££_~µ‚gžîÎéӧؾm+?ý¼ GGG«i¯^ý=ß|óõë×`ê´é<Ýý)¦MŸQ¦4SSS *S>gΞ]æ¸L›‡vÝW­eR•¨‡‡)ÉIv'|éâ%&My‡~Ò­{úöëOjJJa}NýãÇ3zìX†½:‚#G¢ì »y챎DEÊ`ËæM|òég¬_ûG£ŽòØcð÷÷gÀÀA|¶äS†½:ÛË€nEGóØ£»Ô­îoALÌmcxiÓôöö&®`ma) -²28~æÏ/Ü^¼Ø0y$¨:mÓ¦ {ÿüÓî„gÍ›K×'ŸäÛU+Ùùóÿؼqù:1üÞ{îaꇲqýz""^ã£Å‹ì »quu¥Aƒìؾ¥Ò™'»vE«Íg×®4lØΜ9ÃÚµ?°rÕ7,_¾Œk×®Ù­°0þ‰ú×dbévl¼1ÜZš’™ïwwìø8Û·mµzNÉÂw¿¥²~ë\`™œì{A×=<""D¹Tµ€¾üÒ lݾ-[¶’””„F£áÂ… ̘5ËB½åàââ‚R©$1>žÅŸ~j>wî}ûЧo_ïlÐ)“'1|ÄH~äºu{ŠñΔIVÓ>|ÝžêΫÆrOãFŒ=Š>ýúÙ•æ¸Èñ<Óói“ÙôƳiËV:DxøãÜÓ¸ïN™BŸ>…Kæâ *½{aÞ<Ó®»c®P¤]Çê;½4‡è¤DÔ W94·«ø"d5³ß""ßoc”´4Ãg‰¯_7l?ÿ¼ð>íäìÉã´hÕÆD ÚäCSvãИØÃ›ÈN‰}c N2aB¡x¼OAõuáA-aÛ6ÃËB XµJtÝ…€ ›ÄÅÁèÑ…ÛC‡B÷î¢\„€ ¡«ñIŒ˜ÌXÂgõ—,!1"‚¤W Kļ¶ï dÛ6ã17>x¬‹çEa ½û3ð«™¹y|º„€'aî\XTd¢hʼ:B”“лŽ: ïS`)7æÄøÜÖÞ½pg­.@N³f\ë×½¸†*1*Ô2Ü@Êͳ?i"z…“((!  8î/D¶@èä)¸8( J¨@ (Ž«·“9$%SÌXB>œŠ<#C˜P@ ¼pǘ»Žõܵ ÷?öˆB«DÄ$’@P›ºïv ¢&$„[óç‘Ýê?¢Ð„€ jû÷ o§²yö÷ßms½ÕØóÂóä¥&¨“2Ó±Sg! ‚ª%"òMQ•„0ÊJxððÉÉSpò”(°r ×ëíZJ(TPáœ9qLBeèöðáT‹]öØùóÙê?ŒEUeˆI$ –àrô¨Ùý]:suÃ:1ÞY T ¨%Ÿ@Ò+œˆŒ$åÅDáÔvíÖ½»wí%ZtëÞ£ÔqDÔM\£¢LÖtŠYvá ìàVL¬Ýdž…‹««Ý÷"‹ç3ºt&fÆtòÝÝEÁT3v–ÅÊË•"¯c»rñ¼ñïÚå‹D߸NrR¢ñë­¥!-%…«Ï“–’böœ1·nYµ'æV4ªÔT“0UZ*1·nVN÷}Ï^ô 'âÞžHôâEB<…*”ž&M› ×éÈÓä‘¡RqëÆ5Bê5ÀÑÑÑ®4ôz=éªT|IKMÅÓÛ»Ä7éårª;aæðñó#>&Æ®×ëIKI!($¤Âóìƒ<#ƒë_-ºìuA@µZ-Ë–/gÏÞ}888п_?Q’‚ܼ~… 0œœ†®gº wOòòr‰‹¹…³³+J¥3îžžÆxééiäfçàhù;>’L†B¡D D&“‘š”D@°}Cju2™O/o2T*²ÕY¸¸º™ãÈí›7pquÅѩ䛔JgJéé¸{x™‘ŽB©@¡t®”²¼ºað:ks¾(k×­ãÖ­Û,_¶”Ï?[‘¨(Q’‚¸¸¸‘­Î _«!)!N@¶Z³‹~d¤§‘™™@fF:™*~vŸÇÃÓuv¦Ýǧ§¥áéeð=½¼Q¥¥•l29þAÄÇÅX|¹µŸ?i)Éèï øøUÎwî5!!B<ë’€þöÇŒŸ¯/~~~Œ!JRPgWr²Õw¼Ït$I"3à ”9êl\]]$‰ÀàPRINJ %)‘ÀàÐ]jkÈäèòuöõž4yäædãæî€›»¹9Ùh4š’^¦³ Î..¤&'™MËÉI“RAb\, …Òèi „€Z%9)‰à ÂîRHH¨(Éš4.“”\CÔ…œõÏ2ÿ `2ÒUÍUãììzGpóð -%/oä¥YÊ׿#—Éí:V•–F~~>W/_àÊÅó\½|üü|ÒU©æ½L_Ôê,ã 8¾¾~d¤«ðñóžPûðõó#6®pyMl¬å×kÉ32¬¾=[P94éÓ×ðè_u^\2N†î¹$áêê†^Y™™8:8!É —_^n.éªt‚BBQ¥¦ ÉÓ”ê<éªTœ]]l§×éÉHWQ¿Qš4mnü«ß¨ *z]É®º$I…g~0¹Y9:™üµI—ðp–-[NRr2IÉÉ,]¶Üâ±:'^z¿•«ÄË]«­Ÿ/Y>JȇSi<èùj}'¤««+É ¸{ºÌî$&ÄãìêzGÔt$ÄÅ‚«›;þÄÇÞFgã£zz½žÜÜ’ãÉHWáík{üÑ0Ñã\b¶ÞÑÑ…Ri‡-ÙUwÂÓÓ›¤„xqq Ê/ C&88ˆ×FE0fìë´k×Îò…®p"­×³|º„{zô$háG5¦‹Y—I6 ½Â å… Ô›ð&=k5Lö¹¸º¢Õj‹Œ9º“¯ÕàzgÖ;1!O//œï‡I qfÓ+XzýÊ%âb‘$a Úµ„I¥J5NÇÓ˫ĺNÓpo´Ú|qa L{ öXôAGGG"Ç#rÜ8ã¾AXŒ›:p ~«VᔌÏê5ø¬^CZï^$Fn£†¢*É M8ŸÕkÛÌ IVûö$EVûöUb‡“Bi\» —;˜l•\7ééíS8Q䨢¿ËBXý†V„ÞWw«ç 3?\RN»w€–½Â‰Ø÷Þ£Þ„ÂwEzmß×ödtéLÒ°ab°¥F_ŽÇ3“† Ã{ãF“1hר(\‡G‘Ñ¥3‰£ÈiÖL²@P“ Ïïæ4k†ò“ýîìÁý=dµoOÊ CÈèÒYÔŠ¯¿"¼PsåžÑ¥3qoODS OÐTEýž¢ Î(@bÄ(/´(®QQ¸FE‘Û¨!ÉÆ‘Ö»—¨ ù…!f´¸¦õîEbĨZ/¤B$UI•¾P9£Kg2ý¯Õc×®òáTš>ñ$>«×ˆ™ûr¢ ±Ë«÷Ú¾ƒ{úô“|AMP€„ñ‘ö¹ÆIÉ-üˆ{zôÄ{ã&QSåôüíAÊÍÃgõî}úi×®‹‚jR §Y32ºt¶{m¢ÎÝݦ×*¨Ø2}ï½2¯ŽÐÛX¿)­ÈíÀ›O(iý|¹¾â«:3ÁQÝ^¨-Õ+œˆ^¼¸Ì7¬Ž:Ûõ%C@táËé¥hõ˜|wwn~ñ¹Ï öB­)¼} ¦ (>)c yFÊóD U°j ÿeËK,35P@ Ö(Z#äéV—àJï…`!ßÝÝø®IyF †"*Ôt-è2j‹¼L¯pâÖüy&OÇ-üÿ¥ËDMU ç_T²Î.¹¹k÷_eÖ»W‰òž¨@PJ4++‹uë7ð×_HJJÄÑɉVÿù½{÷¢m›6îýØjÔÁ³g›LtD²H|¢¢Ë»¨':yŠ]yZM‰ ädgâ:;ã`òà”¤DTii ‡§'¾~vÛ¦ÎÊ"-5…œ5rIŽ‹›+>~Èåò;ᙤ¥$“““ƒ\&ÇÙÕ_?ÿR{^ (—:kÎ\Ò3Ò™5k:[·lf劯éÜ9œ5?üPmºøD‡x‚¦rË;îí‰Æm·3õÖˆ‹E¡TРqc4nŒB¡ >®Ð[NW¥¢ÎÊ"¬ACÂê7$;KMº*Ín»Ti)xyûаñ½„5lÈH,’~ZJ žÞ>4lrõ5ÆÑÑÉäüA•èéS§xmÄBCBqppÀËÓ“N?ÎG ˜íÂwëÞ£Ä_:Ž5?¬ååW†ÒoÀ@>^´˜œœœR_0[\ü1Äêø|ïÝ@Ê‹/˜LäÙ#¢¹99xyû"“É‘Éäxùø’[¤®3ÒÓññóÇÑÑGGG|üüÉP©ì¶)8´.®®Èd2är|ýýQg«á!õêãêæ~çü2<½½É).T‰€¶jÝŠO>]™³gÉÍ˳yüî];Æç¡‡2†mݶ“'O2þ<¾ûfZ­–o¿û¾LÈ|ô¿fC,x‚IP±$ŽŽ0+¢–pqs#-5™|.Ÿ´Ô\ÜÜŒáy¹¹(”Jã¶B©$ÏŽëËÙj5 …Òl˜^§#=- WQ‘‚ªÐwßy‡°°P>û¿Ïé?`/{•¯¾þš¬¬,«ñþ=vŒú‰w&O2îûyçN^},ÁAA¸¹¹ñÚÈüõ×_eÎDÁ³Ü ò¥Ü<êM˜€Ç®_D W‘ˆŒÇÏ? U:×/_äÚåKd¨TøùŠš^LVxÊd2ôºü2Ù•››Crb<A%®\<ÏÕËIKMÁ·Èù‚ò`÷Hº«‹ ¯¼ü2¯¼ü2z½ž›7o²aÓ&æÍ_ÀL ϧ߸y“Ï>ûœyóæàââbÜŸŸÀð#M•\V¾9ÍšqíûïŒ3òRna“§“›+¾ðYI"*ÏÌ4¾nÐkûÂÍŒ-&ÆÅàîá—`“LŒ‹!8¬¾áf'Ièt:ã¤N§C’ÉK_ÿÙjâãb ÅÑ©äÄV“¦ÍÑét¤¥¦Kh½ú¢U' E‘$‰ 0&"‚^zÙì1iii̘1“‰ß$0ÀtV5 €Ù³gX±ž€&$„ë+¾¢þ˜±Æ¢…|8YF)/¾ j»‚‰{{"²Œ ãc¶ÍaU aË&0$Ìxƒôòñåú•KÆp'…‚Üœ\\ ÝêÜœœœJ÷ˆnfF:ɉ …„™ ”ènÉdxyû–š"*OPµ]ø‰“&±ïÏ?IMM%_«%6.ޝW¬¤eËfŸ:}:Ï?÷-[” 晞|òɧܼV«åÚµkÌ™3¯âDôûïÄ;E«ˆ˜ÓM<ü¡`òl'¥’´Ôtº|ÃhJ²É¥»‡')I‰h44 )I‰¸{z–è~[B•šBrR!aõÍŠgB\ šÜ<ôz=Z†”äD\œ]DÅ ªÖ}qÈ¶ïø‘O—|F^^.¾>¾tx°S&M2{ü¹sç9wî< ?þظ¯`hï^½ÉdLŸ9ƒ¸¸xÂÂÂxåå—*,Sﺬ?f,Î'O†wŠjBBDw¾’D´ ¿ hPäKAÁ$%ÄsóªÁëS8;TøÔ˜‡§M·nz ^^xxzz°9Ù(•ÎÏ”˜ÀÍëWMö7º§)2™ Wwâân£ÉËCîà€‹‹AÁ¢ÒU+ mÚ´¡Íó–(ºÞÚ¢z™LFï^½èÝ«òĬø;E3ý/ªîÝEW¢ˆž•Ëè»eG‹,®wtt"8´žÕ¸¾~ϧ$&âãïo1n“¦Í­¦íæîŽ›xìTPÝZ‘´hÕ¦êNöÛï0onS¦pŸ•ñ±šHiÏ´t|U}jøTøãälÙV¡i†ˆÉÐjD©„iÓDM ‚ G&Š@ j£*Iæ÷ëõ5£t$©æØRC):Ó¢UF› EP¥TÕUÍõ@õúÂ?kÂZÄ] j„ZZ³$°Å÷ëõ¦¿K›ž%Ì¥ei_YÎ_4^YÒîò^P[]úâ‚"I%»ÚÛEÃì‰gK KÛõ/~þâé[³»<ù¨I{yì2wó°'ÌÞú±ç¼å9Oeå£"l*O™«k[¶TV]Vs¾nÎÂWô…eKÄì9¿=ÞnñxµÑ³¬kÞpMÌOeÛdOLôzj€Ve—´:Ç6ËãÕÖ¤|TD¾K;$a«áÚ{ Yò¬,¥oÎã·Õ;ªì|X*OK¶Ú ³t=™ë!Yê-ÙS>uPˆkÞ$RehUž«2/˜êÊGEu ‹SX›D4ÏRÙ–e"ÒÞ›µóTw>¬¥më¼–ÏZÈ–°Û›ÏZ>Y[7×ÚS)]òÒv›jÚ³´ù¨*{ÌÙekh£&,k³ç\æ„¢ºóa-íš|ƒ­åhí-:iíNY\èì‰gé<QÉæÎ_Yù¯m ¢¢<’ʾ‘Ÿà³Ô…¯éù¨ LÁ¡F7¶ÒLÒØsLiÓ+ï~{'…J¯. àW¤G_åb©ë^ÛòQ‡¼ÊÊXÆ$IgN«ƒhußQÅìcõ”E,ó±'ÒŒ–uy[Uß\ì]¶U7Ç 8wE/cÚ¿oÝÇÖ­1ÐÊšP©m“5Õ-v–Æ@mytÖÆ­5Fsi”¦®ŠÆ·g,ÑÜyjB>ìz0g¯¥NiÅÍ^ûí-oÑ…Ü5”f£,C1¬a¯¥9ou磬ÃD•NEÄ«Å"Z-ZOð@AÙ=nA… Þ*ÂTE‡cöïÛCDä›v-ÿÔ}Z´jcq¸ÎZ˜Ð2Э{«¢« TtºuïQê8µ¹ s²³Iˆ‹E£É£IÓæ¾-ô.£4– ©ÙŸëMW¥‘£Î& 8˜Ô”dtùùøú~39)_\ÝÜ+e[ ¨6-ê I’„——mZµbäÈøùù‰’Øåa*œïüVãááež—›ƒ‹«[¥m Õêtu:©i©lÞ¼…9sç±èãDI l’›“—··A@sr4ýÌ´N§C*²x»¢·‚Ñ…—ÉdøúøòÂ!h4–.[ƾ?÷ãàà@¿~}Y±b¥QлuïAÄk¯±iË’““ùeçÏh4¾^±’½ûöÞ©#†¿Š£££1Nññ¢ûºuïAä¸q¬_¿žÔ´Tš4i„ñãiذ!Z­–eË—³gï>è߯Ÿ¸šÌ V«‰½uÓ¸}ãºñ÷õ«WhÒ´9W.ž0þ/ ¢¶Å¨ Æ¨N§C•¦bó¶m4kÞ̸æ¬ÙŒ‰ÅäI“Ðj4|óíw¬\¹Š oŒ`ý†œ:}†…óæãîáÎê5kJ¤}øða>^´˜7ÞÏy€Ö®%>!/—/ࣕˆwòÔ)>[ò ¾>¾Æ87nÜàóÏ–0áG¬]·Ž—_zÉî|=ÅÂ… ðòôdÓæ-|ºä3/ú€µëÖqëÖm–/[ z=ó /Ü...4iÚœÌÌ(¶g cIDATt2T釆¡JK%77‡€ÀÂ1Û-*t½-T4¥ZÚ­{ºuïA÷§{òÜ!üüóÏŒ;Ö¾|é´nÝ…“®®® ú G¢¢ ‡~ý•×ÇŒ&8$777"F2IÇŽùäÓϘ5s†Q<~ß³—ˆ×Fáë㋯/£JØ6zt„Q< ⌟Ÿ~~~ŒÁï{ö”ªp"_GP` J¥’úsùòecØoüaHß×ט¾ÀŠ'š¥ÆÙÅ€lµgWQ(‚»Ë-ÚåMS©Ø¶mŸ/]Æ‚ys¸tñ_­\ÉåË—ÉÌÌ@.+Ô褤DBBB-¦¿iëVºv}’¦M›šìOIN"((иTr¶9Àß¿Dœ¢Ç…„„’œ”TªÂñöñ6þV(äæå·““J¦/(Iñ.urb<Y™ÄÇÅVQP‚ºïÅËÓ“ArîìYã¾YóæÒõÉ'ùvÕJvþü?6oÜ@¾Ng ÷÷ &æ¶Å4-\ÀŸû÷³aã&“ý>¾~ÄÅÅ·cãJ.í)>Yàãëgr\LÌm|‹¬prr$77׸š’Zªüûú™¦#®&34iÚœ†MîE&—Ó¤isÂ4ÄÑÉ‘&M›Ó¤is!ž‚»S@ÓÓ3ظi›46îËÉÉÁÅÅ¥RIb|<‹?ýÔt Û“üßK‰‹%33“eË—›„ûùùññG øå—_X·~½q—ðN,ûr9É)É$§$³lù—6íëÞ‰¥K—‘””DRR_,[N—ðpcø½÷ÜËÆM›ÉÉÉ!6.ŽO–,)Uþ»„‡³lÙr’’“IJNfé²åâj²@Nv6 …aùRnvJ¥³(A…öllm×-íÖ½ÆçêÕkLy{’1ü­7&°råJzõíÇÄÉ“iݪ•IüAвE Þ|{/F@‘EÔFÏÎÇ—,à·ßgÍk2xþþþŒ|-‚Ñc^çþ–-‘;X}2xõêÕcì¸HÆŽ‹¤Aýú ~~°1||ä8ŽDaÀ ALš4™öíÛ—ªà† Lpp¯Š`ÌØ×i×®¸ª- hŽ¥³aÉRNn6Jgáu ÊOñ7ÑÛÚ® ¤]Çê;½4‡è¤DÔ W94·kFõÚµkL›>ƒo¿YU§/nÝ{”úI¤ê|”S< /(.`•ù,|ñ4lm—ç:.Ø÷Дݸ4&öð&²S¢kÏ£œË–/繃ÈÓjX¶üKùï#wÅEXÓϪ‹ââhk»2¨5ÈØÈH´Z-<ò0Ã^y¥Î_ µýå*A]§Öhß>}èÛ§¨1@Pc/T! @ ºð‚ZŒ^|‡G T (=;u_\ˆ.¼@ „*j(û÷í©õy*ªœºò¥!  Ê©+ûŠ1P@ *UËÿCKzåÜ¢IEND®B`‚wxglade-0.6.8.orig/docs/html/main_window.png0000644000175000017500000003270512166606326021251 0ustar georgeskgeorgesk‰PNG  IHDR>Ë÷ÿ.sBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´tEXtTitelwxGlade v0.6.5¾à9 IDATxœíyœSÕùÿß÷Þ¬³„YXfXiPAÔ¶ .¸T[këVüi­k­K‹ö[ë¬c·o]Új«m­ËT¨…j[­;¸!Š,ÂV6g`€Ù·L–›Üß™2™$s“Üd2Ìy¿^óšäÞsÏyîMÎ'ÏyÎ&ÑŘ97jÁaÌž·—,½Y—ßÛ· A†YÚž·—$]ôö¶´õµM@Qö¾÷W:«C@ÀëîK{ k>_†…/ mß6¼ÍûÑjÒ—K²‚½¸œÂáGƒ¬dÀ@ G1»îäz]Ì‚}_G“Ö»¿Îì®×+ÙwÝe¸ð•+WâŸ}(nè>° òã/Àâ(0œŽêi§qÛ»´ÖT‘?l\Ò× ý³ëN®×ÅlؾXÊ:¨èz]TTTôHŠŠ ÞŒÈÓ×ÞDùŒoaMáFlÎý ö}ú2Z`tJyý³ëN®×ÅlØ>$9¥B™§6gaZÙYó\¡Œ2a«@«˜]wr½.fÁ¾°ðI’”VA±ˆÌS’dÌ(A’äŒØ*ä*f×\¯‹Ù°/¡Ç·rÖ,*fϽ^¹ÒPS÷î»Wj$¯äkw‘½‚Lj—¯-íqì[jˆ™V’•œôøÞ¯8 €¯W|˜Sy ú?‰êN²ù É1ó‹U£‰®“™ª‹‰ì‹¥ ñÎ%²/¡Ç7{öì°ØUTT¾ º"‚Ý=>YIJÅ«54XFö8.ÉJV=¾B‡…+NÁÉG3l@P£ÙígçÁN~¾x[ô5lõŽ2¥l3óŠÇY“så)#)+²³¿ÙË_VÕðÖgõ½^wì¨Bn8c4Gϧ©ÃÏÓ«öòÊúƒ ¯yï®cÿÆÝkR²} lÝI˜$¥œ_tÌT]LdßË×–òíûw„`'c_â_º“Ø"ó”e¢mø×5!£Ïÿs¥jM·sOß0%|®²œ5¯(Ï“WO¢´ÀÊ3omcË÷ ¼Œ9„Óg|…QÖªÕ!Ý®)QÚ)RÜ4S Ìf*¯XLSÈŒçÕO÷q_å.™}4¿üîxÚÛÚøp?îuGÍã7WL`û¾6~þÇwÔNÎ?åÞû¬“æ@~¯å^{ÿ²nï'Øa«OtXÅ%FÝI5$9n~W=±1î¥ùÑ$‰î×eª.ưïü?7„õâß×–v{!Û“±/BøÌQîY³V2{v+W®D•ÎÈ^!^Ë}°ZC£%¶g}N’”˜¶¾pÓdFÛ¹êÏ[ø¼ÖÍÇ”PqÁ‘T¼´ƒ·77rTy>O]3‘šF/—>¾‰;¾5–s§æ‘×÷ðCžÊÅ' ã–3GóÊú:îe7ל:’Åv^xg3›7WáXJ2ëwdóÎý”Zü4i…´Ýéúôü‚4wøyïóf{«·/Núíã†pñ ÃQì`o£‡¿~°¿G^’$ñ­ã†ð½ã‡1¢ØÎÁVËÖà¥OÆümr9-¼ôÓ)X‰ ÝHC{HÄZyñ'Sð4.xt#s¿VÀÚuQ½n^[»‹YSÇñƒ¯aKÍ´c‹Ø'Çf‘ù÷Šñ¶5âZyúµ ”)ÜšŸfyN‰ÒÆ~µ¸Û±"¥#cßßITw’Í'ô}ŠŸqë¡~>òºxuÑ ;cÙwÁŸy隀n¢wõöGÊ\"û"šºæ(·Þ<®¨¨`yDž!·3ö5=”:Á¹P>=m]óE ß;~(g P}@åÔ ¡ôí‰>ÞÚÉÔÑe|¾«†ñÖZ~ÝÂÄr;·œ9Šýi×ò¸ñŒQìØßÆ«Ëßg¸%o|u*Û?ÿ‚€&ÑF!Í||š+*.Å HQöHár¾ÝÂM\‹ÖVË̉#ùÁ9Ó±kî}m?AdΛ6˜ŸŸ;†¿hàÑÞÂÊåg×#¯ïÌÆmçŒæÍø¿ç×sÞ c¹õœ£pàeÉ'­=^›'ÈÛŸ5pî´!\>ÍÂãïùPQ8ëØ!È’ÄÚ-{ØÍøa“èlo¢Ss±µ9€C‹e©g»ßI â·QgÚ˜PÛågMeØàbÜÞ«·5Q¹ò¿Xƒà&þ.ÝóÓËÑØ×ìãÕ ,]{€¦e¢$ª;Éç#ÇÍ/Q=Œu>^]4ÇÎØç¾ûT#/^]~Í“!O¯Ñ2ª‡T&²/B™¤žé‘—Ô徯Ê^ŠQ|Üs²ÓÖv†æO]ÄG'9ˆ6·cÇ ãHgSÇ„¼‰{¾¤@öà¶³èÅ*¼>•ùß;š…ŽÅí ðô?WaÕ:±HŠòC•¾³³ƒ­€fÍ…«ÏÛ NâÅ;N§ƒü¸?óÞ~iWV¶€™_)a”¥ËÜ9 €×V~Œ¯£™ú6‹—oé‘×…Ç`Õ‡Ÿ‚¯WÖîà»3‡1ÔÚóy,û¤€o3‚QÖ:d Κú¬ùt ùŠ—â®û# Ò¦åѪ†<µÂ|y²‡¬ÆÌÛ•º®ê‹jnüeV­ÿ‚óg ãÇsÆâÑl±¿K’Äš­üáïËùÕãK¸÷é×hmiáÆ3FrËiƒC0Îuý/VÝI鯫îÄ«‹‰>‚dêb&ï7Rôþ|ýš¬£Þo!_$‘y&r×%$Ãç$)¶Šoø² ÈØC9~\1«ÌÓÿúˆ.<™G–rì¨üj{ji× Q%+ÿm²ñÖ†ZÎ?q o|ô9í­´hƒhÑ ilWê²RR˜Ç¶NªdCBâ”{7°úCÞàë¶©c»Ù+!3iD×Ì*ç«eÇRè°†ŸyQaƒ•ê‚¥”Ùp·6Ò¡¹¨×ŠÙßåuEæ5¼Ø@ŵçt»ç!Å… —ëi âÃÖíÜŽ:›¿læ˜ÑÅSf¡ è`Ü'ÛöÔq°¾‘Æ@ Í*C\6,ͧ`³†„¯­ÃƒU `‘5¤Þ[S‡ÊB+®ßŠ×gãõuÕ|ç䉜xÔƼ¾‘=r´ŸçÏ_ØÉ±Ö&T-ŸWãÙ76ñðø2Î8vKWmc¯:¤Û—SÂ̦nhˆG¼¦nüzë|¼ºh†±ìXzÕ¡ðÈuOnâ×OàW•pÑ_šbæÏ>Óc|Q%z#`yñÓMû«Ã7ë\”Pw,{ÚêQ5>û²ãÆâ›'}•Ï÷µòßÝÕìØ×Èé'L¢(ÏÊÖÝûñ´kùø±2vhçÌEmC ANŸ~$ëªv³ó€“òY½½… ÌñÇ~…Þ©'Œ6JäVŠä¨•m$¨¸àÊÙxèëØ¾«»Eãw?ý’$a“üXåµ->Æv0¸(íóéÀÉÈ¢èx!Ô·ù)/²qïK9ÐÀCH ¤NœJ{À¯ëX$ÿ¸cFqÒ1£™¨¹xý6TÉB;ù|q°“!.Å®ðH Êc_]A$$´˜ÏzÇAC C"Ù¬¹ðh¡x‹ß¯2Xiæ VŠ[sô¸ &8 4h :i „ÄÚfQ(ShÔŠèÔzÞÇ€'FÝùû‹c§àâ§£Ä@¯;q:7zÔµÞÎÇ©‹iÓËý^ÿÇMHRèþôãK¯*Ž¿1HÊ㫨ˆÉÝÿBwqh>¯ã‹qm³5v0µØ_>y]¢vû‡;Ý7v£ÊJyáí 4…›ë¹ö̯ðù®½¨’vl6;¿ºà‚üåßb•Ì»lל"žÝŠæµðôû9ñ§Ì˜„[ÛÉ’ >j[ uE泌g×õ^‘CVÛüÍØ­ 矩څB›àõ×=|éXþþq=«;pYen<#Ô¹òñ–]X¥6IÅC”ð R~Y‡Âùè1¾韼®§ÒÖh»2ã‹sîú?nBº!—<ÝÄ ]âï~c‘”ÇoßÝ»+»Þ¬Œ8‘g¢A˜ß¦™"u·c²$ÅL”;Ÿ5»Ú¹ƒlýüs:%'ook㇧±(2ÿÝUƒ[s Jæ5’Ñ¥vþüêiÒ yúÍÍ\wîTn;«Œÿ}¹‰v¯Ä­­â‡Çç1í¨Ñœ1Ý…,I´{üw¿›†ƒûèR§H A’¸çånŸSÌ/:•æ‹×ÔqF·‘xecC•f¾9}$_w5M>–~\ÇIGvËkÙº¬žœ7c$÷^wŸÕ¸Y²v/~ÉN‹6ˆXß” ðÒ§ \wjH˜–¯ÜHP“hÑ\x±³¡ÚÍã¯VqÉI£xêæñìoñóûÿla÷¾:Z„Ê¡•-޶ìd[àH6Ö¸ùíË[¸ôëã8ý¤BêÚT^xë>ÚŒZÄ—-òº¿}\Ïå3 ¹ëüQHHÔ¶xynùv>Ûð)ÝÓMÝĪ;±êL4ÑuH¯;fçg6‰ì“%‰fk÷ÞÛÈsFíËbŒ/q”¢%†ç+}(FÛÖêF?ßù¿5|EÞ‚F›VJ³Wáü‡Ö1Aù/´ke$;÷½ºg_[Ï0ù š“­ˆTÁš­¯2Xj䥄Á1Ôû ùˇ ]óIEÕ(QpJ^$Í ’Ä쫘®lÂÚ%V›j:ùùÓ;(WêP5·”ÏÜ Û©Å/¤PÄä… Þßø.R;>ÍJ'y\^µáò¤ˆtÿ®RY·m ù¸ñcÁ¿fEÓ ¤ÎP'K ¯maÍºÍ –êè¤z¼þ¹ÙÇúªÕ¸¤üXj2~­€6\øegø¾Š%?Er[HdW¶úÙ¸ý} ¤TÍB4;Íš ?¶˜×}¼ËÍÞ=;qÑÑQPÑÈ£E+D•H˜ÿ=ìïÄ«;±êLk£óÑÿLÌÏlz³Ïè¹Dö%ôø"§©…^DZtðL×5»C׬\¹ν$œDV,¨~/V[ìØü¾N$ÅšðW¦]* ZŽSóЉ6ü’m$NÚñHùø±R> ”àÑì´Q€û´r¼Ø §ìÅ­9©'³riØ%A4À£9ðiJ(¾&IÔhåäâ‚$QÇPüš<Ühøe;û(æùÂiÜ8©Ö†ãÒZpJ>‚šD§”GVŽÈtùTk#pIm8ñ"@•¬¸¥||šƒØ_@’8À|š>Ü8ñÉNÐBéýةцSD3vÍ ’Dy]Ÿ$zÜ€{µri-8$h´Jƒºž_ìë(ŧÙÈ“:‘ Ôìtâ UsáÅ&<¾˜]w²US%ö…—žßs 6åBŒàk«Ã*I”-…òû:©­ù¿&a+œ ‚ÜÄ캓ëu1“öøäŸÝ—žÏôüW›k0þö&vïØZ sá$‹#{A‰ð  ³ëN®×ÅlØ—Ùõø"mAÆV8[áÞ ‚0f×\¯‹Ù°¯‡Çç>¸3c… A_7´ûôÝ&bºîdÍ}s²j@ dI’8áov¿ž3ЪM²f”@ dŠwW½ó¸4%BøÁ€CŸ@ páެß™gŸÓ{"AÒˆç*¤FÆ„/+e.Ú$²OZÂwæÙçôøÓyóõ×Ò6Î(—Ì‹Ï{W°ŽŽ®¿áÇ´··gÕ¦D$`!ÎAæ‰9Ž/rALŽ™4‰7Þ|“owns¯üç?}ÔQˆ¼Aˆ¬7uƒÁ Ï/^Â?¸’ï^x=ü'­².½äþñ⋃ÁnÇUUå_ÿ~™‹.º°‡M‰ìøÁUW±gÏžpÚ·Þz;üzÏž=üફҲ×(É<«3Ï>‡–.åâK¿Ï÷.º˜Ç~ÿ{TUÍŠA#뽺/ýóŸlÚ´‰¸ŸçžyUUyö¹Ê´òüÊøñ”—•ñÞ{ïw;þÎ;+9ꨣ9bDkÙqüôélúl3õõõ<þ‡?àv»ظé3ŽŸ1#-{’ì³Zÿéz~ÿøc<ùĨ©®aÉß^ÈŠA#má‹ã‹Ç«¯½ÆM7ÝHyY\wí5¼÷Þ{éšÁ÷/½„¿/[ÖíØ²_äÒ‹/JÚŽéÓ§óÙ¦Ð^+V¬Àfµ²jõj>ûì3fL?.fžÉ+>ýü’}V7Üð#—–2¸´”~t=o¯Xž¶ÁáHÖc|äêk®ívL–Ów<'OžŒ¢Èlܸ‘)S¦°nÝ: 9ꨣ’¶cê”)<þûß°ü•ÜvÛ­,ùÛ œsöÙlݶ•Ûn—¶½ñž[¤ø%û¬ÊËʽ.NC}}šV ‡'i _² :”E‹R6l˜éy_zÉ%¼°t)S¦Laé²péŧd‡Ó餬¬œU«Wc³Ù8aæLþúüb>øðCÊˇãp¤¾$v2$û¬j÷×2fôèðëÒÁb¥j YñwÞ¹<úèoøòËjTUe×®]Ü{ïý¦ä}â 'P_ßÀÛËWÐÜÒÂŒÓS¶cæŒé<ùä9ãôÓ8ý´Syìñß'ÌÓl’}VO<ñ$õ Ô74ðÄOrú©§fÍV ?‘uïüoY–¹ûž_±ÿFŽÉ®¸Ü”¼%Iâ’‹/â×=ÌÿÜv[ZvLŸ1ƒ§Ÿ}ŽY³f0{Ö,žüãŸ8~zö„/Ùg5uÚT~|ãM¨ªÊ©³gñýK/Íš­A"¼ÙPu}]x!R±_ÿã̳Ïɉ1•A.ñîªwøÑ-·†"­ýhY÷͆’%Qn¶+ ‘Þä\£33rÅ^àp$eáË¥Š™K¶ôF²U 8\ËR&AŒ#„O  8„ð ‚GÌ_¼‰àp ‡ðé‹ ÁáJáÛ²q}_Ø!ãª%uÝÞ‹Ÿ@ pá!|`À!„O  8²¾:Kbâ䩨ªŠÅ’ø1y½^ìv{¯ùI’d¸óhâ䩆ÒI’„¦i1ÏišF @’$Š‹‹YóÞjCy ‡;Bøàv»ùòË/ÓÎÇçó±xñâ¤vz |þùç Óüõ¯ ¿ÞºukÂtmmm†Ëw ßâ¿/ë=QÜ~ûíTïÚajž™À¬•–õ±‘íí톯1²¿žFÓ4$I" "Ërø½~Îh~A¶1[[.\hhY=ÃߢE ±4¤ù)6>¸\®¤Ç þíÅ—8PW‡Ë墣ÓÍÐÁcð·çán——GYùPjkkñxÚ;6Q>|0­m¨N®»*þ2ôñ0K,ômËÊÊLÉ/Äkjß|óÍüîw¿3tì†k¯6µìdI&´ ³dé?L)»¢¢‚í[>Kêš¾¼ïhf>ÇpÚUËßJ«¬E‹¥u½NUU•á´I5u%MtObá¡ãÒ‚ð{IZà˘8q"UUU<ÿüóÉƯyù?¯0}æñüéO¢|ȸãð»eœN;íííH²FPóSXèDV4ê›öR4È…3ÏÂo~ók¶l\›RÙ‘T²H’Žîß¿?¥<úŠxMí'Ÿ|ÒбtHÔt7Bªß3y ©`³Ùðù|@HøR¡/ï;šÕ«Å„õÖ„þ_ç”SN1¥¬xqêdHæÙ¾ùó €ù0,XÐíœþ~~ gðùçŸgþüùi}(Ö<µ{«¹úÚ'Yü·%Xl66 hàñÀøñ§ÐÜÒH±«˜ýõ5TïÞÍ”©“xãÍW9~æì)4[@¸ù˜ Š¢„7:ÏÏÏO)AöY±bEŸ•ýã ˜ì¶y<ýFøÔ¡$ÿõy®¿þZî_TAsC=¿ì üòvT¿Æý÷=ÈÏ~ös¬V;÷ÝwOèWQRIEüz¸lI’°Ùl€yÃca¦7bÆeV«ÕKb“iÑS…@ ÐMØÎ:ë,ÞxãnÏ9™ñ™FØùæ™g8pÿý´xnþñ ©Üs÷(È€ÊÂ_Uàöøð«üú×÷Ó}6žÖõ×·x<Óò’$),Lú— R¨ôJÛ×øýþŒå]UU•QñÓŸ_ä ~?v»=,ˆÉŒÏ4ÂîÈ7{öðÀwàrÂÑG{ضÍAkëj®ÜJÕÜõ— Ìê±M†H1‹îSÐÏ-\¸0í!0ýFøv~±›¬`sæuIXW€™Í--*%Ï‘Gk[ÖB;îN7yÎé5ÝŒ3L-²³r¿¾áeå}~ö<Èð#¸å'?%ȰaCøß_,`_m-‹ÿ¶¶$I¢â®ŠCKÁÐ_’$ÓÔÕÇ8%ʧ¶¶6ib±xñâðëë®»Ž|¹sçš’·Ù 4(í]ìy}«W¯îö£`‘M]ý}&è7ÂçnoG¶X>böíãˆÑcYðË;ñø¼Ü|ãÏ^>šƒšy衇ЂÁCÂ'¥æíÁ!O͉‚øú€O3¿$÷ÜsOøõwÞÉâÅ‹»‰_:ƒ®ÍÄív›’O´àE¾Ï”ú|>dYfÅŠaqÓc}ùùùáp¨Q£Ì-xlÄëbضmà`íÚa¬]{ØÅQé24ŒoõêÕ1ů/{uSI¿¾¼¼<<î, ÆçÖÛnãÖŸÝFcS……¡Á .äÁïÅç3g¼œ‘W’Á,€PüI&‰î¥ä‚èÁ!Ϩ?9C!º×ö_ÿúW8øì³ÏfΈYpÿÊûC¯ï‚û#Žg‹hñˤè%úÁŽ×Û› ýFø<>=òûöícÔ¨QÔ5Ôw Süù´Á JII õM)õmD6qÒ!=›±DBÁ÷\=AjTmð`‡—ÄI˜ÙÉÝÐÅ/ž^,Q3{ì¤aá3s`*\zñ÷˜4e‡»ÝŽÇãéÕ›Ð=¬VkJ ¸\.öíÛ—ªÉåÎ;ïŒyÜLÑ«¬¬LéºÈxgª1¾¾þ¾õ¹|ß¹:h9Q4$|·ß~;.—+éÌͦ¿î—jïp¼!)sçÎå¹çžëµó%_II’((( ½½—ËE  £££×ë¬V+ªª¢iùùù) áéKµ¢¢"åÒ%—<õúúzN8á„^Ó™±ÎcUUUÚ‹3$‹!á«Þµ£ßŠN:¤;>+z%‹ÂÂBÃ×J’”pÞW\Aee%<ð@ îG/?Ù}ùy÷eÙÉ.%e&¹TDzeKª+á¤K¿‰ñõ<óÌ3¦å—ls;rØJ,ô•_¼^o´²,SRR’TÙA60²hh&—½é‘——žsk³ÙPU•`0HQQÍÍÍÝÖaƒC1.½‡Õf³a³Ù’ò 6{¬V+‡ƒââbšššp:hš†Õj 7EÄ ÌÁ!„ð%` 6÷‚Ãႇ>@0àÂ'BøÁ€CŸ@ pá!|`À!„O  8„𠂇>@0àSÖ‚4ÅJ^^Á``0ÈW¿úU ´®à–-[9r$_~ù%û÷ïÇáp Ë2.— UUilldܸq[y$YÒŸx\pþ¹†Óοs~Je,øå‚nkN~øÞ‡|í䯺¶ßߤ)Ó¢ùº·s‡;SŽŸÁÆ{ßP` Y–¹é¦›Ð4ÚÚZ:::?~<Š¢`·Û)//géҥ̙3‡={öpíµ×’ŸŸÛío&õàƒ†WÊé/ÄóžRáƒw?HùZIê}¿\Më.”‹î ]sÚ©Æw»ë7Â'èÉ”ãgði¿d=‚ùwÎϘ·mK2ž…v»;vÐÒÒBAAÛ·ogĈÔÔÔP[[ËgœÇãaذa¸Ýn¾üòK:::(--¥¥¥…]»vQ\\LmõÃåNœ<ÕÔû$)i ֊ݾ÷aRyõ¸âÛ¼÷§‹v2‚+„¯ÿ}™)ù̽øBSò‰FAÁ¦™»\,ŒzéüÚ'B¼xv˜%€zs¶¹¹§ÓÉûï¿ÏþýûÙ¾};‹…êêjöîÝËСC©©©Áb± i@h•í„«gÇìm2—,Y’ԞнqÒ7N2”N÷¼Ò¡7/Z?|ïÔ¾s†ŸÎ¤)Ó°Ùø|BÁÁ¸ÿeYFÓ44MC–el6[·½ú[S4ÞòØ ,`Ñ¢E½~a'L˜`º4mÊL°…^û¤Î¬4yìᑬ‡`„—þõŸ°àEÛ /Øj–—™ŸÚªtРAƒA4MÃårÑÜÜÌ^îîmÎýsñx×X$ëñ¥êa¾ÒÒRêëë ¥õx<8N²,S__Oqq1Š¢Äݱ7¶l\ߣCçÅ:g6»víÊH¾©´uí¡a3gát‘$Éô-£‰·í ™•R,}Ã$Y–y¾2´óY5kÖ°råʤ7½‰$ZÔ"ß÷7/Ò T_¨9e±…~Lúª£#“ÞîíE ‚^ž~LÿÒŸô“L÷¬_\ö¢!osûöí¦–›.Æ ëkR"Y/RôŒ6É!Å_o¿fúžŠ¢pÌ1Ç`±X˜9s&·ß~ûa×è &M™†Å¦°eãzŽ6=«eG{%Ùþ<#ˈ—©“ oÓ¨ú3˜8qbøxt¸åÀ¦—Ï›Zø«…Iõ¨&"Ù_¤è%óY¾d¾à²,‡ƒ½š¦áñxp8@òÛəչI¦:²…ŦçÈ¿ôü&7ƒMŸfÖëÓ'ò;‘-Ê&º·gÔÛÌÆÞ°Ñõ°ºº€¯ýë¼ÿþû-ûƒw?è!~fˆž‘æm¼´÷øìöC=‡Fš«úŽb’$át:q8Ì;7W_}•W^y%å/Ko×I’Ôkïªîu&Ë‚æ îL—Èx^<Ž™z›7|š‘ò³íééÃT"…&ºÌLÅ÷ú[¶l‰y<™­L“åƒw?`Å;+L=HÎûƒ,x|n·;¼_«wÜqùùùÜqǼûî» 2·Ûmظh"›Ï?ÿ<—]vYøu&1ÓãL]ì´@bÏN±fví ]ü²éñ|ðî1¿ÜÙŒ±õ¥·¾™|<;JKK3Z¾™¢éå%㓤™÷ø, tttŠ÷I’Ä<óxbáÂ…IÇ%3M¬^¤¨úïáÍfÅ¿àüsÃ3¢¿ÜºfÂÛûî…ߌy›föêFŽƒGäiMÓP¿ßniEŽÂèO$Û«›ªž¾ë>N©3‰öì2íéAf*T*$jÚF£7‡ÍD÷¸ú ýsˆöøÌþ|¼^/---ƼÍ@ €¢(ø|¾”fMèã!v =V×ÓK’EÑßIeŸÎa¹HAóÍDïЀC=¸Ñ¨¾@Á3ËëKuõŒLé"½¯¤¤„@ À÷.úG}4ßÛÜ´i6›-‡Ãî ÐcËÑßæÍ› ƒØív^¯—––EÁf³%U®^y‹‹‹innføðáìÝ»×P,ÕétÒÙÙ~?hÐ Ó¼¿tH–dÇñA¨w9Yú…ðõu ¹¯ÙðÉÚ„çŲTæ¡{J±zE£ÇééS0ƒÁ`¸ÓnÈ!)y|}=ó(^(#S‹NÄ#•™©t´ä¼ðͽøÂåqú—ËÅwÜA[[ÅÅÅ Ó*ŠB Àëõ¢iZ¸0???i¯/ÉD(#™:›N+ã‹yóæ頻jÌŽŒ\[Т7úÒ±¸àüsM_SÑBø‚v~¾Í”|D+%·»¬ ‚‡>@0àÂ'BøÁ€CŸ@ pá!|`À!„O  8„𠂇˜¹!è¾G±™$; ?Ò†lMàÏ…ûd!|‚˜]lܸq½¦7n\jFhtM`_ü·Ø»íͽÔÜónºý?ÝÞ_þ*ÿÙ˜Ò±ÇHnª™; ö÷3!á¿„}Ǥ³Î4”nËofØ’> bÕ³.WIwMÓØµkm-I]wäWŽÆnµ‚`Y_¾±‰Á%¥xÚ:qä;C‰¥Ð_SSÅÅÅݶíìì$///çë·aïwÞ1­ÐSO=Õ´¼­ûëžw• É’%ÙcËÆõ=\Í—§Ä´cõÜrÆ½í˜ ¬ŠÂ®;Qƒ~x~ŠŠŠP…MŸmÁn±b—m¸;Û‘¬$òóó©©©Áé â¾}ûX³fMÖmO…¤šº³fÍ`ÕªU1ßÇJM¬´‚ô‰ö Óõ“iž¦Ü”M‚lÅüb5agžxb·ck׬1t¬?![­x½^d‹D¡Ë…¿­…ææfž}öYæÝ|­MÍa³[xø·¿á'ón¡¹¹™ââb:;;ùÓŸþÄÕW_M]]âéXèI¥‹$I†¿I _´h%1!pÙÁU6ÿ†ž_6ëÔ3Ó?3W½Ng¡ÉHÁ‹ùe-æ—K¾þ:jy9S¦˜ž¿ÍfC±ÊìÚµ‹£Ž™HGGÚü¨´´”}5û<¤„ââb$IÂb±àñxðx<ƒAƒ J©ìè5 Ÿzê©ðö±FHvã1ÃÂ×WÍÓIS¦a³9ðù<„Fßè;Pé¯ý—eºm(Ërx˜Hr=þ`”x¢àßP—¶ø¬è ÆcOý³š4eZdÈ/c« »6FóÍè13(|ýuFÞzk·cî)SØûÈ#¨eeæ„öéUƒŒ9’Í›7sÄG`µZPì®  €††ZZZƒ´´´„c|eeeȲLsssJÅ;6« ¸¾‡ÞhZ¡·Þjüת´´”úúzCi=N§3¼ç¨,‡†)êï,XÀƒ>˜¤µ¹I"ÑÓIWüŒŠV6öDÉVÌ/ךº–ýûâ·{É:§L áˆyóØcÖÎlŠ‚ÝngäèHV #Ž×ëå¾E÷áqûÈw:¸õ¦[9j8‹¿ßÏÛo¿¢(´´´àv»Q%,”ɲk×.žzê).\˜4,|óæM6­Ð¨¯„DnŒ½ß¨¾çŽÃá‹ÝG|3¿X{– b“ _<úbœ__QóðÃÝš·mgŸ ·ÞJÞF󜀺º:FÞ={h÷vâr¹8à;€ê 2¨ ’’æÌ™ƒÅÚéûßÿ> 0lØ0vïÞrSàꫯ `¦Ikß#l‰bÂ÷wߺ讻R.OµxÇTUí&l‘‘è»E%o²d`Ã5¹Ý·ú’\òøtº ­Ò ­À¼˜_®5uÕ²²ÐE0bÞ< ÔÜ5 ¿ÇÃG}ÄØ#  RYY‰$I¨ªJ¾½K/º‹ÅÂÒ¥K‘¬¼~6› Y–‘e™úúzŠ‹‹immM©üȦîÕW_qñËùÌÉ•,Ë„ßðîœ~æé,syøX2•ôàÁƒlÞ¼™½{÷¢ªjxç¬@ ЫKïõz)((Àï÷ÓÙÙÉèÑ£9餓ȷ§Öè rÑ㋌ù‘˜_®5u£1o®7ÞÀ_VÆÞG1-_gž§ÍÁ ·Üˆ7 rÉ%—0hÐ <6ÙM 5oï{à>‚HhRü–S,¥7r¶©‹èæoÂ÷wÝ)üDîéÍéÍÜè¦kô~¨Ëß\ŽWõb·„òÉÏÏ7\ö„ ˜9s&N§3\¹5M wœ$" †¯QU¯×KGG j —¯oœžujâ8ßÐñ°åýÌ÷ìöžLJ{ó6Cx×oàž2żØ^›ºžgg{;ÍÍͼøâ‹8NZ[[)q æÛçžúÁW¬|òif:qr¶©›TÓ6ú}ŠM]Y–ãÁuôŠ&Ër7oCÓ´˜;Èë¢y­ºÅû½cbÒYgR¼¿¢Çùü‘7ÒQÓóºü¯Àú÷Ó‡\ôøt2ã˵¦n$ÖýûhüÁ2V†Ýn§´´”þð‡´´´ ( l”–”âv»ñü)W4u£p»Ý8Înt¶I `þüø$ë;Þ¢ÄãòÕDZN­èq|Ë{éOaËE/Ó1¾\nê6^y%­gEçTsüÆBVš››yìÉ?0|øp<Þ?·ý4WtØŒí9œ,9ÝÔMªiý>ÅN }wúŽŽCˆ$I<ð@ü¹Bé ¦ÍU"=Á¦² ÓæíæšÇéÙe*Æ—Ë”<ó ®7Þ æá‡{tx˜FWgÅm·ÝFSSøÜ*@I’2ú#wx6uSdãºS¾V¹èñéd*Æ—ËM]ÝÓSËË3ZަiüáB±j›ìàŠËþ‡Ÿ?3­ Xb—ìlŒdÈù¦® ïÈ%OÌÕíŠíe0¾ÐÑÚŠ¢(Ü|óÍ466†:U™Îö ‘%ó×.î‹VXöšº‚´i*«Èjy¹àñ‰¹ºÙ%‹??ø^6§›b#àW))*e_m -Ð{&IÒ=ô†…ïpŒõ'úb½½¾öø¢cza®n_„ "©Ú´‰{ïÅÈ¥.S$-4#þpRCÂ7ÇL rÃãÓ(su³9Q?[ÖÚ×&dãÄd zøÑËŧº˜h*̽øÂ¤WN¤†>ArÕÃÏ´]¹zßóÛK ‚‡>@0àÂ'BøÁ€CŸ@ pá!|`À!„O  8„ð ‚GÎÏܘ8Ù¼Õf[ZZ3f ¬^ijÙFh”$IÌr€œ>€íÛ·‡_÷6‡4‘=÷Üs=6#J¦ìXTVV†w_K”¶²²²Û¾! ïèÂI2+†ÄÉLl(îó[•6©ý>AÆ8lc|ñ<Ãd¶—4ÊàÁƒ ¥Ÿ@¶Âd›ºF¨¯¯7”Nx|AnÐ/šºÏ=÷\Ÿ”«ªj¸l#ëÓUVV&<ïr¹L±K ¤‡aá3cõÛTòP…`0H^^n·»W²Z­X,–Þ•,‡œ[½#ÂN§“@ ñš¦‘ŸŸ$IX,–p9~¿?´X,¨ªš‘f¶@ Hž¤šºËW½›vÉæÐ4ŽŽ4M# &üóz½á´‘@€ÆÆFïÞÊ‹´Íï÷ãõzñz½ásúq=@ è{RnêñÞÌÚ#¡·!%Fyî¹ç°Z­¦–]YYIQQQ¯i+++“.[ d†”:7"·ü33m¥¹¹ÙP:¿ßŸaK’öø"…̨¨ecw,£dB|E1=O@9’>}›?€ßþö· ÓÞrË-átfÄs•Þ:@tG†-FH)Æ)~§Ï:9aZ]{K—3‡³X,ÉÝroCT’Iëñx’*[ d†”;7¶l\ß«§§IGôl6~¿Ÿüü|C½¢Š¢°Ûí¨ªJ @–e‚Á áÅt¬V+ªª&L£ÍS›Í7}‹Þ 6ê ‚Ì“Öf#‚–Žèñy°Fhii1<½ ŒÇ%I2$lÅÅņ˙ððñð2•‡™ÃYzóà’-»²²2Ü|îm8K&¦Ë ‚äIj8KºÞ›YyEŸEÑÛ±t1ºâK²¢+2C¿˜«I,‘‰'f™X‚*Év˜‚¾¥ßÕØt=¶Lˆ¡QáËR ¹A¿¾\΢/ˆÐ[Z±,•@ä¼ð髱ÒÖÖÖkz}èŠÍfCUÕ”†±èÎ!1µX,݆ÎDÚ£(Š˜®&ä9/|}9Õmãºû¬l@9Ü Ì@ „O  8„𠂇>@0àÂ'BøÁ€#îp–7Þ|+›véÌûÙÿPµiCã Çñu朌$™`âä©<ù»G8yÖ©qÓˆ¦®@ 8lÐE¯7„ð ‚ÂHÑKäí>@pŒè>@Ðω%z'OMx>@Ðo‰'z½Åù„ð ‚~Iª¢BøA?¤7Ñà°"]Ñ!| aTôDç†@ 8,HFôDç†@ è÷˜)z „O ä8©ˆžèÜý–Lˆá9J:¢':7A¿#]Ñ _‘iÑ!| ‡0KôDç†@ èdKô@Ÿ@ Ȳ)zÒ˜97j³.¿—êú:Üwò—ï g&ý}£¡«–Ô‘7tµ-£³±:þfC±v&‚Ãn—7tW-ÙÙW¶AFÈ:®Ûû_t@ 8Ü _íGËúÒ@ ÈÀ˜97j}mˆ@ dƒ=o=.ý½Ñ­ .dIEND®B`‚wxglade-0.6.8.orig/docs/html/pr01s03.html0000644000175000017500000000654312167336636020234 0ustar georgeskgeorgeskAbbreviations

Abbreviations

The following abbreviations are used in this manual:

GUI

Graphical User Interface

OS

Operating system

SAE

Standalone Edition

wx

abbreviation for wxWidgets

wxg

File extension used by wxGlade to store the project in a XML file.

wxWidgets

wxWidgets a widget toolkit and tools library for creating graphical user interfaces (GUIs) for cross-platform applications.

wxWidgets is open source and written in C++.

WYSIWYG

What You See Is What You Get.

X11

The X Window System version 11.

XRC

XML-based system for describing wxWidgets resources like dialogs, menus or toolbars.

Those resources are loaded into the application at run-time.

i18n

Numeronyms for internationalisation support.

Internationalisation means adapting software to different languages, regional differences, ...

gettext

Widespread internationalisation (i18n) and localisation system.

wxglade-0.6.8.orig/docs/html/ch01s07.html0000644000175000017500000002135612167336636020210 0ustar georgeskgeorgeskInstallation

Installation

wxGlade is available in 4 different package types:

  • the sources packages (.zip and .tar.gz)

  • the full installer at Microsoft Windows (wxGlade-VERSION-setup.exe)

  • the installer of the standalone edition at Microsoft Windows (wxGlade-SAE-VERSION-setup.exe)

  • development version fetched with Mercurial or downloaded the current packaged development version from https://bitbucket.org

Installing at Microsoft Windows

The default installer requires a local installation Python and wxPython. The wxWidgets are bundled with wxPython on Microsoft Windows. Thereby you don't need to install wxWidgets separately.

There is no need to install additional packages for the standalone edition, because the standalone edition includes the required parts of Python, wxPython and wxWidgets.

The installation process is quite simple. Just download the installer file, execute it and follow the installer instructions.

Installing at Unix/Linux

The current Linux distributions provide wxGlade packages. Use the distribution specific install mechanism to install the wxGlade package and all dependencies.

You may install wxGlade from the source package if your distribution doesn't contain a proper package.

Installing from Source

The installation from scratch requires Python, wxPython and wxWidgets. Those three components have to be installed first. Maybe you could use already packaged versions of those components for your operating system. Otherwise read the installation documentation of the missing components and follow the instructions.

There are two ways for installing wxGlade from source - single or multi user installation.

Download a source package or a development package in a first step.

Single user installation

Extract the downloaded package into a separate directory e.g. a subdirectory below user's home directory. Change in this directory and execute the wxglade file on Unix/Linux or wxglade.pyw on Microsoft Windows.

That's all. Installations below users home directory don't require administrative permissions.

Multi user installation - variant 1

The first variant of a multi user installation is very similar to the section called “Single user installation” except the installation directory. And probably you need administrative permissions. You could extract the wxGlade source package e.g. into c:\program file\wxglade on Microsoft Windows or into /opt/wxglade on Unix/Linux.

Multi user installation - variant 2

Extract the downloaded package into a temporary directory. Change in this directory and execute the Python setup script using python setup.py in a terminal window.

Example 1.1. Installing wxGlade at /opt/wxglade

# python setup.py install --prefix /opt/wxglade
running install
running build
running build_py
creating build
creating build/lib.linux-i686-2.7
creating build/lib.linux-i686-2.7/wxglade
creating build/lib.linux-i686-2.7/wxglade/widgets
creating build/lib.linux-i686-2.7/wxglade/widgets/combo_box
[...]
copying docs/html/ch04s23.html -> /opt/wxglade/share/doc/wxglade/doc/html
copying docs/html/ch04s26.html -> /opt/wxglade/share/doc/wxglade/doc/html
copying docs/html/ch05s02.html -> /opt/wxglade/share/doc/wxglade/doc/html
copying docs/html/pr01.html -> /opt/wxglade/share/doc/wxglade/doc/html
creating /opt/wxglade/share/doc/wxglade/doc/pdf
copying docs/pdf/manual.pdf -> /opt/wxglade/share/doc/wxglade/doc/pdf
creating /opt/share/man
creating /opt/share/man/man1
copying docs/man/wxglade.1 -> /opt/wxglade/share/man/man1
copying docs/man/manpage.xml -> /opt/wxglade/share/doc/wxglade
copying docs/src/manual.xml -> /opt/wxglade/share/doc/wxglade
running install_egg_info
Writing /opt/wxglade/lib/python2.7/site-packages/wxGlade-0.6.5_-py2.7.egg-info

After the installation has finished the wxGlade main script wxglade is located at <install directory>/bin.

Execute the script to start wxGlade

Example 1.2. Starting wxGlade at /opt/wxglade/bin/wxglade

# /opt/wxglade/bin/wxglade 
Starting wxGlade version 0.6.5 on Python 2.7.2+
Base directory:             /opt/wxglade/lib/python2.7/site-packages/wxglade
Documentation directory:    /opt/wxglade/lib/python2.7/site-packages/wxglade/docs
Icons directory:            /opt/wxglade/lib/python2.7/site-packages/wxglade/icons
Build-in widgets directory: /opt/wxglade/lib/python2.7/site-packages/wxglade/widgets
Template directory:         /opt/wxglade/lib/python2.7/site-packages/wxglade/templates
Credits file:               /opt/wxglade/share/doc/wxglade/credits.txt
License file:               /opt/wxglade/share/doc/wxglade/license.txt
Tutorial file:              /opt/wxglade/lib/python2.7/site-packages/wxglade/docs/html/index.html
Using wxPython 2.8.12.1
loaded code generator for perl
loaded code generator for XRC
loaded code generator for python
loaded code generator for lisp
loaded code generator for C++
Found widgets listing -> /opt/wxglade/lib/python2.7/site-packages/wxglade/widgets/widgets.txt
loading widget modules:
        frame
        dialog
[...]

wxglade-0.6.8.orig/docs/html/ch02.html0000644000175000017500000001210012167336636017642 0ustar georgeskgeorgeskChapter 2. Exploring wxGlade

Chapter 2. Exploring wxGlade

Quick start

We will design a simple form.

Start wxGlade by running the wxglade program on Unix platforms or the wxglade.pyw program on Microsoft Windows.

You will see a Main Palette with several buttons, and a Tree Window with an icon marked Application. A Properties Window shows the properties of the Application.

If you move the mouse over a button in the main window, a tooltip will display its function.

To add a frame in the design window, from the Main Palette choose the first button: Add a frame.

Then choose wxFrame as the base class.

Look at the tree window and see that two icons are generated under the application icon, a frame icon and a sizer icon.

If you double click with the mouse on the frame icon, the designer window appears. Notice that the sizer is displayed as a set of gray boxes: they are the slots of the grid sizer where you will place the widgets.

You put a widget on a sizer by selecting it on the Main Window, then click on an empty slot on the frame on the designer window. Try adding a static text, a text control and a button.

If you want to add something else, add empty slots on the sizer by right-clicking on the sizer on the tree window and selecting Add slot.

Play around, adding four or five widgets on the frame.

Now look at the properties form; there are three tabs. In the Common tab you can specify the name, size and color of the widget.

In the Layout tab you can adjust borders and alignments.

In the Widget tab you find the properties depending on the widget.

You can select the properties of a widget by clicking on the designer window or the corresponding icon on the tree window.

Try adjusting widgets with the properties form until you know you have played enough.

Now let's generate the code.

Select the Application icon on the tree window and go to the properties window.

Check Name and Class, choose a Top window, check Single file and choose the language and set the Output path by pushing the button for selecting a path and a filename.

Finally press the Generate code button, and the code is generated.

Compile and enjoy.

wxglade-0.6.8.orig/docs/html/properties_window_application.png0000644000175000017500000007550212166606326025106 0ustar georgeskgeorgesk‰PNG  IHDR“ýßâ‘KsBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´tEXtTitelProperties - IS—M IDATxœìÝy\TõúÀñÏa—MöD m³Tú)•]l±n æ–fei*î[«-·´›[‹»-€ŠV.¸”ÚjšÞÊÒ\0—ÜPP™AÖa˜ßèÀÈÀ ŠÀó¾/®3çû=ÏyξϜeÎQ¸¬uÏqz„Bˆ8óÓÀÊ IØ™õ›‘Bˆg'èÏü´DQ®’ssë;'!„7 s»¾¨4­E·g mšä²=]QþõËL!DƒQ I®4íêšQ^LНq1)Õ‘›z”¢ì4ôº’Ï®ØØâè€[À`c{ B4u=Ýè㛕ù9ûòKx«3­iԧžI^¥öÓ»Òãòëx Ç;ïX¼ðøøx´=ÊÏÃägœôÜtO?ìœ\-ŽsEIá%ÔGÈ9wß65ž_!®¨ëñèFßê2¿+®®†bbªZõ¦]~= ˜6mZ¥>U™6m[+ÄÔæfQ«°wrÅûöî¤þµ½W«ZÅB¨ûñèFßê2¿ûßÚ T®†b‚bSûL«R1¦¢Ç¡YíVä g×Êq…¢¦êz<ºÑǷ럡˜(ŠbÕ‚L©S±±­“eÔU!DÓU×ãÑ>¾]üªÝ3‰ cZe¯ãã-:Ì5}zKÆ·Úæyu~}b4†1xÓ/£÷Pž»¥ùU(&u3Ȇ…ÅÓ£Ç4âãã)QzUH¦ÊExé’ÑØ›þ¤í¥KFcWÞ¦ØØ˜ÍUe›KZ‰'.•ðåO¹ïΖô¸Ë‡ÕÛq¶Ä‡]ÿ¹€y?œá™àãî@÷ÿþ‰}C|éâ‹sGÒ/óõÞ 6ü™NéåÂzeÞ÷6æÙùÓBåÄù¬"ÖüžÆ–}Êó":ùÐÿ?Zx:’‘SÌú?ÒùjO†¡F›Ê£âšEO@·ÿþY¡ÿ½KÆ·Úæi*lߥ¾^V@*’áŸ0ä^q¶êò«p˜«nªá•CcÓ¦Mc»ÑÕ\¶U~P.ÿXÔ¦ØZ«‚FïAv©^¥å_ò³Í"³ÔÃðþ¾01ú𕍹ÓAGûÿ»‡‰´dËŸ)Ìùß!t¿•I¶ÅÙ¦ˆ•»sŒ–ðDûf¼½z?J.#ïÈká7ãHö_ Og^z¬;¥óÁ—û¿/ˆ»'ŠX½×øÖ5ó°GGÔkýxíƒX ôŽÜéàÈmkCG›R.êÜéb~ïômÃMžŽÌÛ°‡’Îàɳ÷ÝÎß§3ÈÓ73³«÷X°=ïRÑ9Èâ={O¨Yôõ?üsê,¥%Ÿڀ»M¹z\íõúÜTî½³%Ï?Ö G}!3¿O£”òß©¹mki¿·7œ"Ø9™¶Þt¼£5c dÒ£­øët[ÿÎâûUœ—_5ãQã(6UÆ«nl3ÙnÑøV Õ¬o¿¥6//$#>;€BåBb.¿ Ç¡”Ê?ÖªK±±ÅFQŒ~ ÝP,n+ÛÍ2‘«Qy/[¶ÊÍq”&Úwô vŠ{¥üÚèŸwýNó’t õŽaO¿ÎeÇ ß³]q>ßþq€':ûág—e´Œwþ†Ka —JYõóß ê⇷ÝEPÜã ÀÎßöBñ%¾¹«ß½~øÚeź:Šë‘£w¡;ŽJ1öj<›»r8Õ<œ ô(;\¤¾x '¥GEKf®–f~ºžôÜC.®J>NJ)ŽŠ¶Ê<Œ·¡áÿ*M·d›÷k8z8‘Ž~zÚ¶nI¯îy£wk/Î"Ÿf&C‡Î:@ˆýß8P–£Ê£=,šŽ¢(8(ZìÅÛÖÒ~oö½•ûÛºãdoÃÑó¹¬ÙyœCÿœ¦8/EÑ£Åg¥bÌTѸ˜â†yTÑ»ÜÀåÙ•â\ùäoêüÕã—¹vKÆ·Ú0·¾£¢QP¸<Û0}Ý0Ï*××”í™L›f:Èô¯»Ë^¿ssùý»ŒöLª¸4í¢ƒé“Sª’d²/·UÌL±ä˜¢—.§×£P¨w¢Grôn†÷J?[ô”Oü>1›‘a~„Ýs‡É¢o~Ý=6ØVÈ¿WŽ~}©clÀÎ½Ç ýÖïQ3áázõèÌòmǰÕÁ­-T<ćëþÀVÑW™ÇÅ‚š7³Cåᆢ¶AáªõUʶ­%˘Ñ/ˆõ¿Û³7ýOTt®Ô¥ü柊b" UïÇ¥Ü<ÎìÉ`ë_gðkîH§;ZÓ©]km38WZ¶ m/ÿò´Y8ØÛòD÷vbcô·anÛZÚïf/'6ývšGOq1'½J±A‹3E¥äÓŒ\®É'Aqc«í¥¼ª’d²+\,te<ª*Þg‘Ìäaü·oÑøV Õ­ïèèD²í[b<›Íš¡e¥ªõ5¥F{&U}Ídz0ôò›x£5(]Í—„Çfã¡5¾4XÁ䇿Ë_š1—«‚Z¯ªôIÚÄ٤˱ÊVÿ‘‰—ÍEBÛ·`YÇÛHÏ)aåŽÜ÷y4£´ÂFLüç ï l·‡rµ,ßz˜¿O’‹ ¥Š ë÷ª±/L'<$Y‘£×+$žËgõçÑâÀEšW™ÇÒ„ "»yñꈲñas™ÌÛ’e|s0‹QpKÀhuzþ>›Í¶¿â¨ãlSHÎU‡Ð®HÓûV¾4ÜÄf/ 4ÃF_J³ÒB.då‘ôÛ~Ø} _›²ð _ߌÿnIᵞžŒ}ò²óŠYõû®ºÂïÔܶµ´ßÐe'¸Óö8èA‹=E8R w"WïBŽe—‰_ƒrјLCW«4.]ê:^]«&?…²B¢TÑfi~×ñœIõ_ƹèPùæf¦z—Å1k÷ÓÙö ö—[SŸ¤«ëWª‡e¿ç°u÷šQD1ö”¢ Ç™,}s´”ŸÏØû÷)¶Ò`‹=`G ¥¸­÷ 'ņÍGtì=ú;Îä£ÃŽbìÑbØáªT™ÇæýÙ$<€¢¦ÚÙ:r´ôV“ýÍ-c÷)Î&Â\Ãö´GK¾9eWxÔÍï] ù¸’+jt8ë p%¯ì¬‰bÃÁ”^‹=…¿’N±!OïÂ3ÿ¡…’†¡˜Z¶mkò;ÈÐû`K)—ôÎâTvÕØåEIiºªLC•æ­ǦÎãÕ5sù™úoÁT[uùU»gRñ*e¯«Èt?{yž¤²yâãã¡× C[[tÚBìœLE°ˆ¶¸ÅÖ®ÚÊ¢À…|¸j€²´ß%\HÖ·À]ÉÅb@!_ïDî)ŽF1rôÍAÑãD!àD¾¾q§X);Ÿ³!V3 Q(¥;.áB‘â(Uæ‘®÷£')Dš+9\¤y¥þ–,C£W¡Uìq&¿l`Å™K¸‘ó5ù¤ÃŽ\ÜÈÅÍè/1бÇY_€Ðê8‡?Ž—·sM¶­¥ýÔ\>±/•CTP×ãÑõßjëzäWý7àÃ?+?j>ØèVEaÏVxÓþò‘®ðÁF}l›5'=å~·àP‹ÒžrûfÍMçzY:eÇèÍ ÕõËÃ<*þ1¹‹…Š“ñá*ý q¦çJóšË#òq©4©þæ–Q„E8UÙ~½ãH~¦s¸êµ%ÛÖâ~B\¥®Ç£ë5¾ÕÖõÈÏð ø³iÖæ[-=¥”\Ê¢¤ðèkqŸÅ['\T׿˜b tRöá@1Gôw\uîCXËÒm+¿aºnôñíZæ—öçWÆÏ€¿ÖwâU°ÁÞÍ{7Ÿkºœëá¸pù outÎA”±tÛÊï@X£®Ç£}|»ùUºkpÙãEu’€²ã)Y—D]I,Ù¶–öBԭݳà¹'Œ¦}É ?ãËŸö¥]‡àë—Yp$±ê;‡ !Dƒòô~†­:…s…çÕWúÆZ»Á2øÕ±;;ÞÍáƒûë; !„¸fLýYÔ™„ø¸»»›éÙ4äää˜ï$„hp¤˜\'ûþÜ]ß)Ü"ž,{iB4B]Ñ[þ­Å¿ÂØž={ê;!Ä5bøžIræò3Nñû¬žFçLÂ#zóÍ–Íõ˜bÖ¿ƒQ§°eÝêúN¥ÞíÙ³‡és>’=!a«2pömCêîõh’Íï™H!©9Ù3B45f‹‰ Œ5'XÑÔÈžÉ5 XÑÔÜÐ{& uP–,„hj̞ɵ,,u»¡A!„¨-«÷L6lÜHï'ú°aãÆ:KÊ”º*j¦Ö§® æR€«2éå×ê;!D#cÕž‰^¯ç»ï¾gäˆ|ÿýèkskãF¨6{&……lùî{Þ›ý/¿þ¯ÿg1ËWðÏñæg¾ÌT‘05mÁ‡sjœŸBTÇì7à«ûžÉž={quu%""œŸwì`ïÞ½„„„Í;lèP¾úê+t¥¥„…†2bÄpììì,j¯*NÇê5kؾýgòóóyjÐ úöíÀ¹sçX¹òs&&¢ÓéfÂøq¸»»WúRá•xckµZ–ÇÆòË/ „†vgØÐ¡ØÛÛúŽ;†uë7M›  &LOëÖ­ ¹ÖfÏ$öó/ñôð`Ôˆa¨<=)((äøÉ“ü¸m;·ÝzKã !Äõd՞ɷß}GDx/zõzœo¾ý®RŸ}û÷±`Á|/ZHʹâÖ­«Q»)ë7làï¿3sÆ –ÆD“©Î4´Íš=‡^½z±"v9Ë—-ÃËKÅŠ+Öå›-›«\¯µqqœ={–ùóæ2Þ\’’’ˆ‹3Îiï_û˜5k&«¾ü‚Î!Y²äc£öÚ왜³‡¹ª¿ûî{.^¼H¿þ*M6l¨á½¿_ù3¿ýýýQ«5Fý͵›¢V« 0Ùvüø bcc9yê—.]ÀÆÆò'ñi4£œ*åäééixíèèhØ;¸¢6· yþÙ§ùyç/¬ßø5poîNp‡ö<òðC4s*{fóo»w3bØóx©Tô gîÂÅô‰¯Ñ²®6°_ÜÝÊžyÿ`0¶ýohÛ³o£†¿@óËw=îûD8³>˜kh·±±åbN—.]ÂÓÃÁÿ„MC­Î™³ýçŸYº4?__Ãôôôt^|éežyæiHKO§UË–†×^^*£XæÚMñöö&55Õè<Åïð>ƒŸzŠ©S_ÃÅÅ…¼¼<?ýŒ¡]1ó|e•Je”SjjªE9UT›='''ôôôz=éélßÉç_®&rø04YÙ̘ó¡Ñ|æÖÇW €ƒ½½ÑžQÎżTåÅÓËËËhޑÞ㇟¶óÃÖm8;;Ó¯Ooî¼ãv«sB4,µ:gòKB·ßv›Q!ðóóãÖ[n!!a—aZtt jµµZMtt =ÂzÍc®Ý”‡zˆO?‹"--K—.ch+,,ÂÙÙ'''222X¼x‰Ñ¼îîî$''W;,4”¨¨(233ÉÌÌ$**š°Ð0³9Udí÷LEÁßß~ODpâÔiÃtOÞycªá°Õ‚ç0ÿƒÙFó™Še ÷æî¨5åÅU«ÕFí-Z0bès̘þ6}Ÿˆ`õZó缄O­Î™|ûí·<Þëq“ýü1¾ùö[Ãû»ƒƒ™4i2ãÆO ÀŸŸ4êo®Ý”~ýúÑ®ÝL}ý FŒŒÄÇÇÇÐ6iâbcWðäÀ¼þÆ›´oßÞhÞ'ôçåW^­rÀ4h -[¶dò”™<åEZµneQNÕfÏdÑ'Ÿ±ïÀArs/¡ÓéPk4lùî{ÚÝlèÓí_]X³nééèt:Χ¦ûÅ*C»‹‹3ééFqMM«‰Îÿw7_oÞÂÅœ.æäðÕæoŒÚW|±Š´ôtJKKºÙSB4<µ:g2oî\=ËÜ{ï½Ü{f÷ýû÷£ÿ~Uö¯®½â²+¾¶³³å¹!CxnÈJó„„„]ž QáœBŸ>}èÓ§O•Ëqpp`Td$£"#ÍæTÕ´Úœ3y´çÃ$ìú•¸õÑjµ¸»»sg»ÛòôS†>¡Ýº¢( KW¬D­ÉÂ×Ç›Çÿý¨¡ýá`Þâ)((0œp75­&yø!6~½™ÙÌÅÖÖ–î]ÿÅñåthKc?'++ ??_£|…M‡Uß3¦Õf{ÝvK[n»¥mµ}E!´[WB»u5Ùþ@XwënvZÅ¢bªÀTœfogÇ ý4 ¬àŸOMe÷Ÿå¹êtw0î®6o!Dã×`îÍÕ4¶{s}µi 9¹¹h²²øjó7thW}§$„¸Á\Ó=só5ÖBÕØÖK¥òä£ù‹Ðét´¿ëNz=ö¨ù™„MJ­¿g"ªÖØ †uïFX÷nõ†âvC?Ϥ¡jL…D!,aÑ9“«o(ÿZö¯B4JëžãôaCf’œyüŒSü>«'GÔw^FBüFMœÂ–u«ë;•z·gϦÏùˆÃ÷×w*B+ [•³oRw¯§@“l~ÏD!„0Çì xaî=àðÁý´ë ßÅðÓfh¾£↦( ÷MÝj4MŠÉu"‡…™æBa±„xÓÏœ’b"„ÂjRL„BXMΙˆ­ª]n!DÝéÞã³}¤˜ˆoÔÄ)õ‚–^¯·è")&¢Q/B Q¿äœ‰B«I1Ba59ÌÕDÔææ“r÷c!„¥¤˜4!'“ÎXÜ·íÍ­¯a&BˆÆÆâÃ\á½yûièõz“mB!š®3qsuåÛo¿»V¹!„h jt˜kìØ1¼ôÒËÜ}w0&ûœ;wŽ•+?ç`b":Žàà`&Œ‡»»;P¶3vÌ6l܈Z­æ¦›nbü¸±œOM%.n™™™´ bòäI†eèõzÖÆÅñÓÖŸÈËϧK—.Œ‰“““•«/#mq1êÌ òóA¯§™³ >þØÚÚpòؼ||ÉÖhУÇÍÍ/_?E±¨]QYöL\\\7n,ÍKI‰ÎdŸY³çЫW/VÄ.gù²exy©X±b¥QŸ?÷üÉ{ÿý/kV¯¢GXïL›Îo¿ýƻӧ±êË/¸÷Þ{Y¼äcCÿM›6‘˜xˆ™3g…NWÂ_®ªÅꊦ í| Í=TÜÜöVZ·½;{;42Œúäçåxs-onCqq1ÙuÚ…Æj|ip‡èØ¡#_®úÒdûâE 騱¸¸8óÜ!ìýë/£>ÆO À'''žx¢7Œ7ÿòiÿüó¡ÿ?neÌ˜ÑøùùáêêÊð^à×_­iꢉhysš9;£( 666¨¼}ÉÏË3êãíç‡vvvxûú‘{ñbÚ…Æju5×!Ïòò+¯rOHwÞy§QÛñã'ˆåä©S\ºt 㚥Ry^;::àéi<­¸¸Øð>##ƒÑ£ÇÅC¢*E……¨/dPTTH©Îô´½½CùkJJ´5jB«U1±³³ãŧ0kÖlæ~düä¼÷?xŸÁO=ÅÔ©¯áââB^^ƒŸ~ƪ$}}|˜þîtü|}­Š#š†ôóçðôöÆß¥6¶¶”êtœ>ñQ­¶GÃk;;ûµ !ŒÕúð­Z¶ä±ÇþͧŸ}f4½°°gggœœœÈÈÈ`ñâ%V'ùøã³hÑ"’““)))!)é sÞÿÀ긢q*Õ—bccƒbcƒV«%#=µRuF:%%%””” ÎHÇõò"–¶ !ŒYõ¥ÅˆðpÞ™6ÝhÚ¤‰ˆ‰YÊì9sðôTѯo_þgåùˆˆpEaÆÌY¤§§Ó¢ÅM<ûì³VÅ—¯™餟?‡­ž*òrsú4sv!%é4zô¸º¹ãéå]£v!„1‹‹‰©[k(ŠÂ»Ó§M !$$ÄhZDDxµqÌMS…ˆˆp£8BTÅÙÅ•VA®FÓš{ªŒÞ{¨¼ðPyUÃ\»˜ÜN¥ ‘[¤!®)&M„Ü´Qq-É-èE“ÓöövVµ !*“b"„ÂjRL„BXMΙˆÏÔc„×—Ñ uïñGÔwB4yr˜K!„Õ¤˜!„°š!„V“b"„ÂjRL„BXM®æ ZBüŽúNAˆF¯{Ìö‘b"¼Q§Ôw B4Zz½Þ¢Ë菱ˆFáðÁýõ‚Mšœ3Ba5)&B!¬V§‡¹Â#zËs3nPá½k<ü.…–’s&MÈɤ3÷•§2 !j¢FÅ$%%…•ŸNbâ!  º™ýûÓµk×k“µpòØiÔ¦R[òéSÕèXÙ5ê xùøÊsá…¨‚ÅçLΟ?ÏÔ×ß ÝíX¸`>ëâÖ2zÔh~ù%áZæ'D­(6 y—.MË»”‹b£Ô8VNvÞ¾~ädgÕUzB4:Zµšˆˆpúöíc˜vûí·ñúëSMö?wî+W~ÎÁÄDt:ÁÁÁL?www8À²eËINIÁÃÃAƒòè#˜mÂ*/²5™¸¸º¦ekÔx¨¼I?ŸÀ¹³ghî鉫›»¡O‰VKÊÙ$ZµÅÆÆ†ü¼KØØÚÒÜSEnNùy—pv)yòؼ||ÉÖhУÇÍÍ/_?E±¨]ˆÆÂâ=“ýjqhaW IDATàY³çЫW/VÄ.gù²exy©X±b¥¡ý£¹s8h k׬fÎìY;zÌ¢6!,áêæŽN§£° €‚ü|t:®nn†>ž^ÞdefÍ—¥ÎÄÃS…MÙ³²hîá @sO.fUÞ;ÉÏË#ðæ ZÞ܆ââb²5êµ ÑX\LrssQ©T^¼h!;vÀÁÁgž2„½ýU¾` /^ÄÇLJ‰'XÔ&„¥<<½ w¶&³Òùg.åä -.&?/ÏP<´Z-E…¸º7ÀÕݢ´Z­Qo??ììì°³³ÃÛ×Ü‹kÔ.Dc`ña.7774 þþþõ?~ü±±±œ9À¢þïð>ƒŸzŠ©S_ÃÅÅ…¼¼<?ýŒ¡½mÛ¶¼õæèõzöìÙË‚ ù|å ³mBXJQ<ÌõôÓƒÙ¼e _oÚDff&Z­–þù‡Y³f›ì_XX„³³3NNNddd°xñ£ö÷?ø€³ÉÉèt:£ÿЫk¢&III 4nÝ»Ÿ°‹ø„]tïÊÓO "))©Úø“'N ]»;ÙõÛïìúíwn¿ã&Oœ`q;” ä*zwÚ4Š‹µlÛ±ƒ­Û·sâÄqÖÅ­5»Þ¦bYºL!DeuvipxDoÆúõÈÎΦMP&Œ§uëÖèt:V¯YÃöí?“ŸŸÏSƒÑ·o´Z-Ëccùå—BC»3lèPìíí())!::†_°µµ5ÌWqÙW ›¹<´Z-QÑ1ìÚµ«,VŸ>,m²…ñÝ»ùó¯}¸¹¹ òò"<"‚ðˆCŸùs?â¹çžgÄÈHôá#G’““Âys™·`a•ñ>Ìç_|‰‹«+cÇcùÒ¥·›³}ÛOlûy^ÞÞL{÷]ÆDŽâɃ,Ž!„°^ž3Ùû×>f͚ɪ/¿ sHg–,ùØÐ¶~Ãþþû03gÌ`iL4™êLCÛÚ¸8Ξ=Ëüys™?o.IIIÄÅ­3´ÇÅ­ãÜùs,^´ùóæ²wïÞZç±vm22X²x Ìgÿ¦ý,Œ.÷ßÏ믽ʞ?ÿ¤°°ÐdŸ] »èÛ¿¥éý `WBBµñxðA¢>ûŒÜÜ\rrrøì“OyàÁ-nèÜ‘v·ÝÊ£?ÄòeËÐétF튢”¿FáØ±£f×ÛsËB«Q1 è]é§¢qcÇàçë‹““ýúöåÄÉ“†¶mÛ¶3zT$þ¸ºº2rÄC[|üN"##ñööÆÛÛ›Q‘‘ÄïŒ7´ïˆßAdd$^^^†öêT—GüÎŒ1•J…J¥bäÈÕDjüü1mÚ´å?o½Ipû»íú/f¾÷¹¹¹†>YYüýý+ÍëççGVVVµñßž6õë×ÑáÎvt¼ëN6nÜÀ;Óßµ¸=)9…¿äÀ¡¿ù`î<¾ýf 3Þû¯¡ýäÝéÓPgf¢ÎÌäÝéÓÈÏÏ·f“˜]¦¢²:=gâééixíèèHqq±á½Z­& Àd\Fƒ¿ŸŸá}@@jµ¦Â¼•Û«S]¿ ±*ÆmŠ\]Ýxñå—ùþÇ­=~‚˜å±¨5j&MoèãáéIZZZ¥yÓÓÓ¶õÍ- ?W¼üâžèÓ‡ƒæà߇y¢O^š2Ùâö+èØ±# -f}\œaúÛÓ¦£×ëy°GöìÉm·Ýn6'KUµL!De×íÒ`oooRSSM¶©T*ÒÒÓ ïSSSñòRÞ{y·›Ø,¥R©H¯«Âë¦NQn»í6Þ™6Ý»w¦wíÚ¯6l¨ÔãúõFW|™:a½çÏ?7n<îî»3vÜ8öîÙcq{¥mlppp4¼÷ðð`Á¢Å8ô7{öíý¹;ÿêÚµÚœjêêe !*»nÅäá‡âÓÏ¢HKKãÒ¥KDÇÄÚÂBC‰ŠŠ"33“ÌÌL¢¢¢ +o #::µZZ­&*:ºÖy„…†³FƒF£!&Æò“½Ñ 'ðÍ–-df^ ¤¤„ää³Ìž5“{î¹ÇÐgò”)¬\ËÒèh.\¸À… XÍç+W0irõ7‘¼ó®»øô“OÈÉÉ!''‡O>þ˜»Ú··¸}¸q;v ­VˉÇyå¥ /ÏmâRSSÉÉÉaËæM|¼d‰ÙœÌ1·L!De5ºšËÔwM,½ ª_¿~2õõ7(,,䩧ʯ¶4h Ëcc™<¥ìûÝ»wcàÀ'ËÛ$*:†qã'`gkKß~}Ù¿¿v'Î HTt4cÇÇÎÖ–ððplº'á'MžÂŠØå¼ùúT ñõõãdþÂE†>mÚ¶eÕšµÌš9ƒ>ü€{îáËÕkjÓ¦Úø͛ϴ·ÿC×.÷Ð9$„æÍ·¸ýß=Ƥ ã9uò$Dô~‚ “&ÚÿÕµ+}"ÂÉÉÉ!$äb–.£MÛ¶f×»âa¯+¯¯ì½˜[¦¢2¥uÏqú°!3Iμ@~Æ)~ŸÕ³FwŠlè’’’øï{eW˜5F ñ;5qŠÜ5XQcGЮC°QM¸2¦Ü7u+ξmHݽžMrã¸JMEÇÄ••EFFÑ1K¹¿K—úNI!´&ù<?_?¦¼ø%Z-÷uéÂ!ÏÖwJBÑ 5ÉbÒ»w½{G˜ï(„Â"Mò0—BˆºÕ$÷Lš¢¦tQ…âú“bÒÈ•\BˆkMŠI#׽DzW"„¸æäœ‰B«I1Ba5)&B!¬&ÅD!„Õ¤˜!„°š!„V“b"„ÂjRL„BXMЉB«Ý0߀è]íS͵ !„0ýD\sêbl½aЉBˆºq2éŒÅ}ÛÞܺN–iña®ðˆÞ&šSëY×ëÞ·ec\'!„i5Ú3‘ÃLBÑð­_Ç€'ÖiÌ:;ÌÑ›qcǰný²³³iÄ„ ãiݺlêܹs¬\ù9Ñét3aü8ÜÝÝ 16lØÈW_}…®´”°ÐPFŒŽ]åõz=kãâøiëOäåçÓ¥KFŠÄÉÉÉdnZ­–¨èvíÚ…­­-}ûôayl¬¡8Vïʧë+ÿ~³e³Éiæâ,ùøn¿íV~øaC^?ý´Žçûï¿7ïj`Ù²å$§¤àááÁ Ayô‘G ó^=_Åiá½6th•Û×\»V«eyl,¿ü’@hhw† н½½aþ#†óõ×›P«Õ†ÛÞ›['!Äõµ~]¿ýö[“:½škï_û˜5k&«¾ü‚Î!Y²äcCÛ¬ÙsèÕ«+b—³|Ù2¼¼T¬X±Òhþ}û÷±`Á|/ZHʹâÖ­3¹œM›6‘˜xˆ™3g…NWÂ_®ª2¯µk㸑Á’Å‹X¸`>ûß’½ºxWÁo¶l6z}õ4sqFEŽdÛöí$ìÚ@BBÛÞΨÈÈ*ã]í£¹s8h k׬fÎìY;z¬Ê¾¦˜Û¾Õµ¯‹ãìٳ̟7—ùóæ’””D\œñü‡1÷£Ù²y“Åë$„¸~Ö¯‹ࣹóêœuqq|¿uë5[Öu»4øýÞgðSO1uêk¸¸¸——Çà§Ÿ1ê“–žN«–- ¯½¼LÊõõñaú»ÓñóõµhÙ*•Šôôt ±kÏTa15Í\œÓ§OóÓ¶m¼ùÆë|úY]ºÜG@@@•ñ®Ö¶m[Þzó ôz={öìeÁ‚…|¾ráèè@VVV¥ùÍmßêÚU*•Q{jjj¥ù¯^‡Úd!DÝY»n=))ÉŒ>œ;ﺋÀÀ–×lY×íð……E8;;ãääDFF‹/©Ô'::µZZ­&::†a=LÆzüñÇY´hÉÉÉ””””t†9ïPå²ÃBC‰‰YŠF£A£Ñ³´FñÜÝÝINN6šÇÔ´êâòÑܹ¼üÒKÜÿýŒ;†Ù³çöÞLÅ»Úû|ÀÙädt:`[å² HTt4cÇÇÎÖ–ððp<`q¼'ôçåW^%//ϰ¾¦¦UçãO>%"<œöíïàÞ{ïå|j*ò)“'M4ïj]îëÂÌ3ɸp–¼üÒK†¶qãÆ²hÑbÖ­[‡‡ú÷g÷î?j´}«k4h Ëcc™<åEºwïVå狀í&„¸þ[òˆæ;ZAiÝsœ>lÈL’3/ŸqŠßgõäHâós6`IIIü÷½,‰®ïT®¹]MCxDï¾&ÿí'Äï`ÔÄ)Ü7u+ξmHݽžMrÓ¹JtL ú÷G«Õ³”û»t©ï”„⚨«[¤ÔD“)&~¾~Lyñ%J´ZîëÒ…!Cª>,&„ U}ah2Ťwïz÷ލï4ê¹?09Ä%„°†<ÏD!„Õ¤˜!„°š!„V“b"„ÂjRL„BXMЉB«I1Ba5)&B!¬Öd¾´ØTµë\ß)!0EQ8|p¿Ù~RLš€Æ~ãN!ĵ‘oúi·¦Èa.!„V“b"„HBüŽíQÔ)&BÑÈDN˜|Ý—)ÅD!„Õ¤˜!„°Z“,&¦že/„ME^^«V­®Ó˜ ²˜H1BˆÚÉËËcêëo°jõjæÍŸ_gq-úžIuƒw}<¡Ož („µÍéÓ§ؾýgÚµá‰'¬ÿ€nQ1©8x‡Gô–Á\! yóç³}ûÏFÓ¢cbꤘX}˜K«ÕͳCžãÙ!ÏV«5´‡GôfÆ<ûì?ý Ÿ~ú%%%&cŒŒäìÙ³†÷WúìÙ³ŒŒŒ4Ĭÿûï¿ç…á#è×/¿ü gΜ1´—””ðÉ'Ÿ2øégxvÈslظÑâü-ÍG!‚)“'óÍ–Í•~ê‚ÕÅdm\gÏžeþ¼¹ÌŸ7—¤¤$ââÖõÙ· Ìgñ¢…¤œK!nÝ:“±:ý_'ú€ÌÌL>ýì3 H~'‘‘‘x{{ãííͨÈHâwÆõ‰ŒŒÄËË ///"GŽdÇÓßÎìÔ©‰‡â:88ðKB‡Ñ©Óÿ™œoÜØ1øùúâääD¿¾}9qò¤¡mGüÃò¯ägiþµÍG!𫋉F£ÁßÏÏð> µZcÔ§b»¿¿¥ö+‚ƒ;rôèQâwÆ3yÒ$¶mÛÀÑcÇèØ±£Éù<== ¯)..6¼W«+çgiþµÍG!𫋉J¥"-=Ýð>55//•QŸŠíiéé•Ú¯prrÂßߟ„]»pppäž{BÐéJù}÷nüqrrªq~^^Æù¥¥¥YœÿµÈG!êË„‰“è]é§..¶º˜„…†Eff&™™™DEEfÔ'::µZZ­&::†a=ªŒ×¹S'bb–ò@²>=z„ñé§ŸÕúüDXX˜Ñò£¢£k”]ç#„õeö¬™M{è¡™2Ùú{yY]L HË–-™<åE&Oy‘V­[1pà“F}îfҤɌ?€ÿJíuêÔ‰ììlBC»JVVV­ÏO 8ÆŸÀ¤I“ù¿ÿ3Žc.ÿºÎG!ê‹‹‹ o½õ&..Î9rdÄVZ÷§2“äÌ ägœâ÷Y=ëôaJò½”úÕ®C°<Kˆ&$!~‘&Wûßý©S§‰ŠŽæ?o½‰‹‹Kµ±FMœbô¤Å+Ógß6¤î^O&Yž´(„MM›6AÌž5³Nc6È{s !„¸±\ób"‡¸„¢ñ“=!„hDêã)‹`á…B4 õuÁì™!„°šì™4 ñ¦ï…&„uEŠI#§(J}§ „h¤˜4r¿l$„׊œ3Ba5)&B!¬&ÅD!„Õ¤˜!„°š!„V“b"„ÂjRL„BXí†-&á½ë;!„ºa‹‰('…Uq£«“oÀ§¤¤°òóÏIL]ºtaô¨HœœœLæôÅ—_ÊóÏ=g˜æààÀ½÷Üý÷ÜcqÜðˆÞŒ;†uë7M›  &LOëÖ­-žĈá|ýõ&Ôj5[6oâܹs¬\ù9Ñét3aü8ÜÝÝ ‡³®ü{e¤âÞŠ¹mi.g!„¸¬>g²ÿÀÂBC«í³6.޳gÏ2Þ\æÏ›KRRqqë íqqë8wþ‹-dþ¼¹ìÝ»×hþM›6‘˜xˆ™3g…NWÂ_®ªry{÷îåá‡2›»%q÷þµY³f²êË/èÒ™%K>®Ñü‡1÷£Ù²y³fÏ¡W¯^¬ˆ]ÎòeËðòR±bÅJ ¼x|³es•‡¶ÌmKs9 !ĵ`u1ÉÍÍE¥RUÛ'>~'‘‘‘x{{ãííͨÈHâwÆÚwÄï 22///C{E?ü¸•1cFãç燫«+Ã_x_ýµÊå]¼˜ƒÑ´ðˆÞ†ŸšÄ7v ~¾¾899ѯo_Nœ¨þÊî&!aO>9 ÊùT*iéé´jÙ€ÔÔT¼¼Ê?­{y·§¥¥ÍïëãÃôw§ãçëkQž:ýÛ¶mçù矫¶_MãÖfþ«‹Ëû¼Ïà§žbêÔ×pqq!//ÁO?Seÿ«™Û–Õ9’xÀèw(„U©éÏŸ€¿ºJ=ýô`^›ú:öötëÚ•æÍ›súôi6lØh8 JTT“'M*K2*š°Ð0CŒ°°0¢£c˜óôÓ¼üÊ«”èJx¤gOüüü(..æð‘#VŽZmæ/,,ÂÙÙ'''222X¾<Ö¨ÝÝÝäädZ^.W3·-ͱôS†BÔ„ÕWsÝtÓMÌœñ+?ÿ‚Õ«×PTTDPPú÷3ô4h Ëcc™<åEºwïÆÀO–·HTt ãÆOÀÎÖ–¾ýú²ù Ž¢(̘9‹ôôtZ´¸‰gŸ}¶Êœ|}}ùèÃXµz5o¾õ.^¼ˆ³³3íÛ·çÃÞ¯uÜ«ÕfþI'³”Ùsæàé©¢_ß¾ü¯Ây–'ôçåW^%//ÏäIxsÛR!êƒÒºç8}Ø™$g^ ?ã¿ÏêiòÓkBüŽ?BÑpU5æ'Äï`ÔÄ)Ü7u+ξmHݽžM²ÜNE!„õ¤˜!„°š!„V“b"„ÂjRL„BXMЉB«I1Baµ:+&‰‰‰Ìš=Çp3ÅAƒŸfÙ²å¤gdÔÕ"êœ5O0bxÝ"°%&NªvþW_}…-øä“OyjðÓŒɲeËÉË˯ržêQ¿s'#F G¥R¡R©9rD•qjúh`K]«¸Bq#±ú|EnnnFåû·^ŸKIfѪϭ8;;óì3Ïðì3Ï ×ëINNfÃÆ|øÑ‡¼óöÛ&ç©î±º¿ ¸­ø¸Û«ÕôÑÀ–ºVq…âFbU1ñ÷÷'%%Åp¨kíºõLŸöW=)ð÷ßg@ß>ÇV…V­Z9r$C‡½P«üT*ééé†üÒÒÓ«ìkí#|¯w\!„¸‘Xu˜ëéÁƒ™þNùÃwÝÅÚuëY»n=Íg˜ž““Ãß}g6ÞÔ×ß a×.²³³))Ñ‘žžNlì îºóÎZåJLÌR4 †˜˜¥Uö½òÞäj›ï IDATädJJJHJ:Ü÷?¨Õr¯G\!„¸‘Xµgòàƒðõ¦¯yqò¤*/ÎÉÉaЀþ<õÔ ³ñ~Šo¾ù–%K>¦¸¸OOOî ᥗ^¬U~ƒ $*:š±ãÆcgkKxx8š> oí#|«r­â !ÄÄêÇöæååñÞŒ™8991|äHîër?îî¤°û÷ߘûÑGDôêÅOÔÿ7Ä“’’øï{3X]ß©!Ä ­¦íµú¼‹‹ ³fÎ 11‘ÏW¬`tddÙtWWíÙ“ïý·^ÏDÇÄ0 ´Z-Ñ1K¹ß‚K”…BÔL]ÍÕ¡C:tèPWáꌟ¯S^|‰­–ûºtaÈ9Ä$„u­N/ ¾õîAïÞõ†B4jò<!„V“b"„ÂjRL„BXMЉB«I1Ba5)&B!¬&ÅD!„Õ¤˜!„°š!„V«³b’˜˜È¬ÙsèMxDo ~šeË–“ž‘QW‹hÔŽ=Jä¨Ñ†çÊWdjZ]ĽÕež e…h ¬.&yyy¼þÆ›lüêk†<ÿ<û&r2é ßýð#]ºvåÍ·þæMÕ?']À²å± ú¼á™òu5^W!®«ïÍõúoСcp¥ç™8àIz>ò(ƒôÇÅÕ…‡z¨ÚXyyù¬_¿žÿýú+™™™888Ðþ®»ˆˆ'88ØÚT¯™ðˆÞVÖIII„„„Þ×Õàu\!„¸¬*&?ÿ¼ƒ›ƒÚTù`,wwwÖ®ßÀcô4[Læ¼ÿ>>>>L{çm|}}ÉËËã`b"«×¬½¡‹I]ÈÏÏÇÞÞ¾ÁÄBˆŠ¬*&«V¯fíú fû¹»»óïÇ7ÛïСC|¾r%..Î4oÞœîݺѽ[7C½^ÏÚ¸8~ÚúyùùtéÒ…Ñ£"qrrÊö† ÊW_}…®´”°ÐPFŒŽ]Ùªž;wŽ•+?ç`b":Žàà`&Œ‡»»»aþ#†óõ×›P«ÕlÙ¼©Úy®Žºòï•= syVd*FU{;ÖÆÕjµ,å—_ íΰ¡C ÇÔú×4sÛX§Ó±zͶoÿ™üü|ž4ˆ¾}ûâÿý÷¬[¿ììlÚ1aÂxZ·n])Kb]a.§°lÙr’SRððð`Р<úÈ#fÛ„e¬:g’––F`` E}»XðPªŽ:°xñb9Bqq±É>›6m"1ñ3gÎ &: ®„/¾\eÔgßþ},X0ŸÅ‹’r.…¸uë m³fÏ¡W¯^¬ˆ]ÎòeËðòR±bÅJ£ù%bîGÒêæ¹2à³e³ÑàoIžWT£¶ë_]ܵqqœ={–ùóæ2Þ\’’’ˆ‹[g4ßÕë_ÓÌmãõ6ð÷߇™9£ì©—™êL£ø{ÿÚǬY3YõåtéÌ’%W¹=ÌŲ4§æÎeà ¬]³š9³gqìè1‹Ú„e®Û¥Á-[2aâ¤jû¼úê+´lÁ'Ÿ|ÊSƒŸfÄÈH–-[N^^¾¡Ï?þ{÷Õ•ÿü˜/MºbŒº»©E£ägcI6 :(¤Œ ÁMIJ»1°DD±2ƒ‚fC±ƒ!1ºŠC‘AEP¿?Œ#C›ï×óì“™{Î=çsîýÜ6÷ìGXX(¬¬¬`hhˆ ñãqôèQ¥v$ ÌÌÌ`ffIH²²²eËã—áÕWí «« }¼ˆ'O6X?b±X£uR'ÎG!´Ýìì#H$077‡¹¹9&H$È>’­T§áökƒªñ:xðB'H`cc CCC„+µ>1 V––‰DðpwÇo/6‹ª¶Ô©S§Î(“—áæÍ›°°°À¤Ij•Ñ}m69ÖÕ‚|Ä/kþÞ èëë#`Ü8Œ‡ºº:äççcë¶mørñ—øÏ¿ÿ ())Ahh˜Òz:::Jß­­¬~¶¶†\^¦øþ믿!)) /]BEE S'åœjaa¡ô]uR'ÎG!´Ý²²2¥ñ±±±Q ñökƒªñ’Ëå°±±i¶}SSSÅg==½fÏRÕiKݘþ5g6RRÓ°9%FFFHB0 •eDtŸ dbmm‚‚µ.u;v ^M\ËnŽŽŽž}öYHBBðÁ‡ãË--,0÷ó¹-Î+_T\Œg{ôP|63{x”½pÑBøûù!2r PYY ÿ±ãõ]ŸªušÚ™«ç£Ú®X,VŸÂÂB¥ñT''U1¨/sss6{Dê¶¥*¦>}ú`ÎìY¨««Ã?œÀҥ˰a}²Ê2"ºOÐe®±þþ˜ûŸ«¬W^^޽{ö¨¬9sr¾ý7nÜ@MM-Š‹‹‘””Œ—_zIQgÔ¨QˆG~~>jjj—w .RjG*•A.—C.—C*•a¨óPEYUÕ]èëëC$¡¤¤Ë—¯P—ªuŒ‘ŸŸ¯´L8…Ðvœ€ÒÒR”––"!A g'g­Æ j¼F ŽÕkPTT„ŠŠ He2ú”¶TÅ´pÑ"\ÉÏGmm-å„ÚRÝ'èÌdذ7±#s>ž2¹ÙǃËËËáëå ??_•íùûûa÷bÅJÜ»w¦¦¦xmÀL›ö±¢Ž«« tttƒââbtïÞ Jíôµ·ÇäÉSPS[ '§!ðññV”Mž™,ó,€©©îîøNÅ=Uëx{ybú'Ÿ¢²²Rq£[8…Ðv}}}°.) S¦ÞÓ!CÞPmÄ j¼<<1 [¶âÆèÝ«"">BÏž=ÕÕÕHÊðí·ß¢sçÎp÷]¬KJRLÍëâêÖhšÞúËTõ¯ªýºº:¤¥§ãÀþ¨¼}ŽŽŽ H$jÍa#"êpZõÌ$fþŒ=ÉIë°níZ˜™‰‘œ¼^©Î‰“§Í›6¢ÿ€þX±b¥¢,--×JJ°by<–-Ãé3š½¹XUÿªÚÏÌÌDnîYDGGA&M@mm 6nÚü#ADôdkÕd²<~^}Õººº00ÐÇ{8qò¤Rð‰a°²´„H$‚‡»;~»xQQ–}䂃ƒ ‹!‹¬ÕþUµ¿wß~„……ÂÊÊ †††?G}„‘ "z²©}™+';Ké»$bŠÊ9N~ýõ7$%%áâ¥K¨¨¨tꤜ¿LMMŸõôôpïÞ=Å÷²²2XYY)¾[×û¬Uý«j¿¤¤¡¡aJËttt/ÚÙsæI"z¢©³Ÿ@£{&õg[T§ƒ…‹ÂßÏ‘‘3```€ÊÊJø§vb±ÅÅ۵µ+•ëêêâîÝ»ÐÓÓ\¿~]£þUµoia¹ŸÏ…•¥e£ØÎçžáì“DôÄÒô`YãðšÌ¸XUuúúú‰D())ÁºuIõåìä™,“&Ed²D¥ò¿õéƒmÛ·ÃýÝwqóæM$H¥õ¯ªýQ£F!>>$ØØØ  à*ÒÒÓ1ãÓOpöI"¢´ò4WS¿5Ù½k'&OŠ€L–ˆù ÀÔT ww|§Á=__$H¥˜þºtî üøãÃxxøDÄÇ/GFƘ˜˜ÀËÓÇÿWQ®ªUí»ºº@GGQÑ1(..F÷îÝ éð=ñ'“†æÖ7`À 0@i™««K‹ëÖ_¦««‹ÂÃñQx8 //T”÷ìÙ_~¹HiýQ£ÞQ»UíëèèÀÕÕEi""j¬ÝÿhQ*“áúõë())T–ˆ×;TûDDOƒVýÑ¢6XYZaêÇÓPS]AŽŽ Ôîe¦ÖnŸˆèiÐ››+ÜÜ\;lûDDOƒv™‹ˆˆÚ?&""ŒÉ„ˆˆc2!""Á´v>77»¿Úƒï¾û``hˆ·GŽÄh—ÑM¾Žäiñ$ŽK{ݦ¦¦$ ¢¶!øÌ¤²²3gÍÆ¶í;øþû8õc..æ]Æž½ûà8x0fÏù23Ÿ¾ÿƒ·Õ¸´åL—ü[QsŸ™Ìœ5 v¯Ú#6n©Òr[[[Øzycä[oÃ׈1|¸Êö °~ÃäæžÅ;wЫ×sðòôÄàÁƒ›¬¯ÉÑh[¹js\ZŠ»-ĵ½M˜˜˜ÀÁÁ!ÁA022j•؉¨u :39|8 ÏõêÝhçRŸ±±1Ò¶lEjjšÊöþøãDΜ…_xË–Æ!#= ¡BñÍ79BÂlsÚ—ö 5¶i÷®Ø½k'–Æ-Á½{w±fM‚¶Â%¢6&èÌdsJ Ò¶lUYÏØØÿ5Ju{›Sàêêw÷wËžþ˜93RH˜mNÛãÒ’úg-gΜÁÚµë_Pøúúàí·ÞRÔûðƒ°}ûvÔþù'œœ„.]Ôû'КÛdff†ÐÐP„…MT,S5e²‹«‚ƒƒ°cG&är9víÌÔ¨O"Ò.Ag&EEEй@TqTãW§Ïœ³““Úm‹ºÇÆÂÇ×i©)X0??_øY©üÔéSXº4Ëã—¡àjÒ32Ôn»­·I)“ÏæžEìâ/™HˆÚ6{JwÛˆŸˆøeÍ_&¹uëÄbq‹í4uùá²GêšÔ}\ÔuuêÔeò2ܼyŠyZH$033»ÿ9$_Ì›‡±þþ‚ûmHÓm*++ƒ,1ýúõU,Û»o?æÌ™­˜ 3hüx|˜3{êêêðÃ'°té2lXŸ¬(/*.Ƴ=z(>›™©TßÛÔRboiÊä&"z|Ý3ëï¹ÿù·Êzåå娻gêöÆúcç®]Ø‘™‰ÒÒRTWWã—_~ALÌ|!a¶9m‹º.Z„+ùù¨­­Ðxg+•Ê —Ë!—Ë!•Ê0Ôy¨Úm·õ6=˜29??555ÈË»Œ ©^‘ˆ Ag&ƽ‰™;ðñ”ÉÍ>2Z^^_/Oøùùªl¯[·nˆŽš‡õ6"%%wïÞE¯^½àåé!$Ì6§íqšŸ¹>ÇAŽˆŽŠFɵkèak‹éÓ¦)•÷µ·ÇäÉSPS[ '§!ðññVs‹Zg›ZÂ)“‰:ž#Ã뜣‘_z ·K.áXÌHœÏ=Ó¨bNv$S•UVVb^T4D"‚BB0Èñu£  Ç}ØÅ‹á:z4ÆŒi»_j·ím\´q¿¨½mµžæöù9ÙY˜0i*Eeoß‚;eùÂoÀ &: ¹¹¹ØœŒP‰äþò¿Þ×5ï‹û*!žÄqy·‰ˆ´CkOsÙÙÙÁÎÎN[Í=1žÄqy·‰ˆ„á+èŸíí‘h"z²0™‘`L&DD$“  ÆdBDD‚1™‘`L&DD$“  ÆdBDD‚1™‘`Z{Jnn.vµß}÷€‡ïkí2ú±½¯©=L†ÕÇ…ˆHÛŸ™TVVbæ¬Ùض}ß§~ÌÅÅ¼ËØ³wÆì9ÿBfæÓ÷*Ž =MŸ™Ìœ5 v¯Ú7šãÂÖÖ¶^ÞùÖÛðõò„¡F Þb[õçì011ƒƒB‚ƒ`dd¤2ŽöpRŸ6ÇeI\t ƒ)S&·¸¼þøá…žGHp0ºuë¦X^PP€õ6 7÷,îܹƒ^½žƒ—§',lƒ‰è©&èÌäðá,<׫w³“%€±±1Ò¶lEjjšZmîÞµ»wíÄÒ¸%¸wï.Ö¬Iâc¡íq™†_~ù‡V,Ûà~ûí"ÂÂB•ê>¿„5«Ñ§OÄ.‰S”ýñLjœ9 /¾ð"–-CFzB'„â›ora+‰ˆtf²9%i[¶*¾Ÿûé'„ájAF¾õ6¤‰‰îï8ÿ9j”Fm›™™!44aa3"gbô¨Qpr¢¨síÚ5L›>ee×<<2¯†òõ×_#cËVܸq½{õBDÄGèÙ³' ººë’’;S'§!øðƒðÌ3Ï(Ú ŸÖìúêŽKsÔ===DÎŒÄÌ™³ð÷¿ÿµµ"9y=Ìžž^“ëÁÓÃÛ¶m׿¸ººÀ½ÞüìÏ?ÿÌœ©2"¢–:3)**‚­­­â»¯·®ìß§T×ÑÑQHWðõñFJj*êêêËRRRáVïòÖƒ£òúNœ<…˜˜hlÞ´ýôÇŠ+eiéé¸rå â–Ä"nI,òòòžž¡öúÍi8.-Qw\žíÑ~øbæ/ÀüùóÔb·nÝÂÖ­ÛðÜsÏ)–>sÎNNjõGD¤ ­>|ëÖ-¥ïï¼ý–âswÛˆ˜4¹á*Í*++CBBúõë ppp€H$‘o¾pÿ’ÍÉS§àêêÒb;áÃ`ei ‘Hwwüvñ¢¢,;û$ ÌÍÍannŽ  ²d«½¾6h2.ýúá™gžA§Nš½ÇáâêW7ø‡ýöcÆŒOe·nÝ‚X,ÖJÜDDõiíÑ`àþ¥•ú åë}ûŸ¯ä#~Yó÷xp©Ê¤kWôí×!ÁAŠ2__$­K‚Ó!Ø´i3<=<š½Ì󀩩©â³žžîÝ»§ø^VVk++ÅwÈåej¯¯ êŽ ,_±ï¿ˆk×®!yýoTg÷®¨««CQQ1–ÄÅáÒÅ‹ŠGŒŒîo³µµV·ˆHЙ‰µµ5 þº¬i[0Èуáéí­T÷رcjµùàRÕÆ0}ÚÇèÚµ«¢lÐÀèòL$'¯Ç… ðÎ;ÿT”éèèh¿X,FQq±â{aa!ÌÌ„¹7—–¨;.ÙÙÙ¨©©ƒƒÞzë-üòË/8óãMÖÕÑÑ5>™> +W­Æ;w}íí‘“ó­zAD¤AÉd¬¿?æþçߊï/½ü2Ò2¶ -c Ç.Q,///ÇÞ={„tàþNÒ×Ç[·mƒ¯Ÿ/ºtyxbellŒüü|ÚsvrBBBJKKQZZŠ„)œœÇÙp\š£î¸Ü¸q2Y"‚Æàþ8„O C|ürTVV6»ž……^zé%d9r?®±þعkvdf¢´´ÕÕÕøå—_3_Í-#"jš d2lØ›Èûý>žÒü5ÿòòrøzyÂÏÏWHW :uB·nÝ0|Ø0¥åÞ^ž˜þɧJ¿µPÅ××=zôÀ”©cÊÔñlÏgáãã­zE´=.«V­Æ Aƒ”ž"ëÙ³'Þxc0V®\Õâºÿ|û-ìÝ{ÿaˆnݺ!:j~úéÂ?Š€·/V­^£ô„Ñ£Ðé92¼Î90ù¥×p»äŽÅŒÄùÜ3*ædgA1¥QYee%æEEC$!($ƒ_‡±±1 püØ÷ˆ]¼®£GcÌõwò-ùü‹ypvvj÷O%µõ¸iSsûüœì,L˜4ƒ"÷Cß²7 oÁ²|á7à …ÜÜ\lHNF¨Drù_ï Šš÷…VÞAUWW‡}ûö£¤¤NCÚÿ‘t[ Q{ µ§¹ììì`gg§­æqu+KKDFF>ÒÍöÇ¥µÇ…ˆ¨=Ðê£Á­©=½w‹ˆˆ”q>""ŒÉ„ˆˆc2!""Á4ºg’§º=uÔN&’ˆ)­u`j'“¦~ÈHDDðž i“  ÆdBDD‚1™‘`L&DD$“  ÆdBDD‚1™‘`OT2ÑdÊ^ÒŒ&cË¿ÑÓ§C%î¤Ú–6ÿfDO‡Ç–LnÞ¼‰€€@TWW+-Ÿ­ôýÞ½{ˆ›7o¶éYOÛN°©íÕd¼›«[ùÓ6¦DO“Ç–LºvíŠ^xÇÿW±ìÖ­[8~ü8ÊËË˾?v /¾ðºvíú8Â$""5J&! ®\¹¢ø~èÐaÅç+W® D"ÁŠ•«pðàA¥õ8ˆ+WaĈá8|øá:ç/\@]]Ο¿ Xvðà!Œ1€ò‘mMM V­Z ÿ±ãø¶nÛ¦ÔGuu5V¬\õ°|ë6¥õëêêš–†  `øùEÜÒe¨ªªRêÇÅÕMi3gÎ`òä)ððôÂø `ìÛ¿¿Ù±©­­ÅÆM›ðáø øúùcûöJ±%H¥|ï!A*U:CsquÞ=_#(8ïº{`bøG8wî:É„PxxzaúôOPPP ´ÎÖ­Ûÿ±ã°zõÔÔÔ(ʯ^½Š˜˜ùð;>¾~ˆŠŽQ$íæ¶·á™DKí«ºÌÕT3"gâ›or”ê_»v ï½ÿ~³ãJDí“ dâÐÏgÏþ(--Åê5kpçÎ@îÙ³èïÐ$!8xèr¾ý““ƒC‡a‚D‚^ÃoÛ7çÏG¿~ýpîü9€\.G^^ x­Qßéé¸úÇU,_†¸%±8qâ„RyZZ:®•”`Åòx,[‡Óg”ßzœ™™‰ÜܳˆŽŽ‚Lš€ÚÚlÜ´ÀÃK3»wíTºL³86>¾>HKMÁ‚ù1øùÂÏÍŽÍ–­[ñÓOç…D™¥òÒ‡±¥§ãÊ•+ˆ[‹¸%±ÈËËCzz†Òúÿûá˜÷ÅHMÙŒ¡ÎÎøÏgsñý÷ßãó¹Ÿaó¦8p –¯X©´Î©Ó§°ti–Ç/CÁÕ¤gÞ Ä‰“'[ÜÞ†ZjÿQ888@$áÈ7ßþøãœ ˆ7"9y=.\¸€©Sïÿ;Ÿ{†³{=FšÌi”L€Æ3.öwp€L–/OOÀСÎX½z \]î_ª¨ªªÂâØXLŸ6 ¯¼ò2:wîŒùó`Ñ¢…ÐÕÕ 6 Éë×C°³³Ãq ¾"|IDATªÕ«ÐlÎÎÎJe˜ò×ÙO‚Tª\îä™,Qq)J&KT*5jâãã1A" ®"-=3>ý`llŒüü|ôøkç -‚ŸŸºý•[Ú>«×$`ò¤"%5Uq©ËÙÉ ˜2yòýؤpvrn¶-uÕ©T†¡ÎCeUUw¡¯¯‘H„’’¬[—¤´nSÛ«Iûêhªøúø`ÁÂE˜4)]º<ü'ÉÙ=‰:“ICذq#œœ†œœœ˜¸ý+W­†«‹ ^yåeÀÀñGa!V®Z­Ø1 êŒuIë`g÷ à»WPSS¡C›ßÁúúø A*CøGèÒ¹3Ü=ÜqúôﯤRL ÿ]:w†‹‹ ~üña¹«« tttƒââbtïÞ õ’—·—'¦ò)*++7Œ9":*%×®¡‡­-¦O›Öl|¨º[…È™³PUU??_¥ØÖ%%aÊÔC†¼o5F»e}íí1yòÔÔÖÂÉiˆR›“'E@&KÄü `j*†‡»;¾«w¨©íÕ¤}u4×G§NЭ[7 6LÃ-&¢öB§çÈð:çÀhä—^Ãí’K83²É#œì,®Ÿµ7yyyøbÞý'«žD.®nmú£Nmúü‹ypvv‚³“Óã…ˆþÒÜ>?'; &MÅ ÈýзìÂã[p§,¿c½NESR™ ׯ_GII ¤²D¼îèø¸C¢zêêê°wï>””ÃiÈÇ ø2W{fei…©OCMu59:"0°ù{0Ôö\ÝÆÀÊÒ‘‘‘j=@Dí×LÜÜ\áææú¸ÃhñWGŒ™ˆšöD_æ""¢¶ÁdBDD‚1™‘`L&DD$˜ÖnÀçææb÷W{ðÝwß ñöÈ‘í2ºÙW–´5n"¢öDð™Iee%fΚmÛw ðý÷qêÇ\\Ì»Œ={÷Áqð`Ìžó/df¶¿§v:jÜDDí‘à3“™³fÁîU{ÄÆ-UZnkk [/oŒ|ëmøzyÂÀÐ#†o±­'NbÛ¶m8á 0 ÿ|øá022jvßÿk×%áüùóÐ××G`@FŽÑ®ã.**BB‚?»?oËË/½‰$ÖÖÖ*ã&"j™>œ…çzõn´C®ÏØØi[¶"55Me{;v쀻‡;6oÚˆeË–¡sçΈ]²¤ÙúW¯^ÅÜÏ¿Àðao"iÝZ,þrNŸ>Ýîãþrq,zõê…µ‰2¬M”¡çs=ñåâX•ýµW‚’Éæ”ügîç*ë㟣F©¬÷ÅŸc@ÿþ‰D0éÚãLjÜܳÍ÷¿9^^ž:t( aaaO>™®qÜç~ú ƒ_wÄs=lÔêqÿþûïðòò„ àíå…ßÿ]e?DDí• dRTT¤˜/DÇGx/Ö™Äßÿþ÷Ëoܸ÷ÞþcÇ!vI*++U¶Û0n_o/\ýk>õû÷µzÜ À¶mÛQYy•••ضm;  q?DDíE›=Üݶ"&MV»þÅK— •ÊðQøÄfë”——£¸¸Ë–-êU+QSS ©T¦ql·nÝRúþÎÛoµjÜ’`:|¾~~ðõóÇá¬,L„h7Q{ÑfÉäjA>â—5¢¾ÜÜ\Ì›…Ÿ~‚îÝ»7[O$!8(&]»Â¤kWH$ü÷ÿÓ8¶†7ʿ޷¿Uã^gg'¤¥¦ -5ÎÎN-Þc!"jï%kkküuyH•cÇŽ©U/''‹¾\ŒÙ³fâMãÛœçž{uõÔÕ5WUIøÓ2¶`£#9:ÂÓ[y§ֈûܹóðñöVºgrþüµú!"j%“±þþ˜ûŸ«¬W^^޽{ö¨¬·cǬ]—„è¨yøÛßþÖdW7Åç‘#F@&KÄ›7qãæM$H¥8p Æq¿ôòËHËØ‚´Œ-Xûð ¡µâîÝ»7¶n݆ÊÊJTVVbËÖ­èÓ»·Ê~ˆˆÚ+A¿36ìMìÈܧLnö1Ûòòrøzy*M[ÛYâZ@h˜òý†-é‰Dê9%%%˜81þù'¾öB‚ƒÕkoq¾~þؾ}‡Zã«*V"Rß–Œt|ÿý÷ZoWídrúôi¼ùæ›–6 §OŸ‘‘Œ½{÷)•ïÝ·ÎCahhˆÌÌLäæžEttdÒÔÖÖ`ã¦ÍJõÏæžEìâ/±kg&ú9àìÙŸ¥¥¥X½f îܹÈ={ýú7¹^}.íÞµSé’‘:±Ô×Rý ’1 V––‰DðpwÇo/*ʲAppÄb1Äb1BB‚[l«¥X²³@"‘ÀÜÜæææ˜ ‘ ûH¶F±6ü›kKYY™Òú666ËËÔŽhü7‘Ëå°±±i²®ªñ:nDO£}ûöâó¹Ÿa|P2ÒÓñu+^V;™ØÛÛ#++ cÇú+-?|ø0ìííßÇŒqæÍ)2dvî܉°‰w–˜ûù\XYZ6ÛOýˆH$‚µµ5r¾ýººzxíµHIMűãÇacc ‘HÔäz-µ©I,šÔÿý÷ßqààAÌž5«×$ÀÑqP“;Î>}ú`ÎìY¨««Ã?œÀҥ˰a}²ÊmP‡X,Fqq1lmmEÅÅ-Öo)±XŒ¢âb<Û£€û`Ô?3ÕÕÕÅÝ»w¡§§¸~ýz£ön¹¹9 ѳgãGUoK±QÓÒ2¶   !AAxéå—akÛ£ÕúRû2—ÿXìþê+ìÈÌÄõë×qýúuìÈÌÄW{öÀßÏWQ¯_¿~¸}û6vïþ ¢ÿ¡OïÞŠ²Q£F!>>ùùù¨©©A^Þe,X¸¨Å~û;8@&KÄ›C‡†uÆêÕk”î—¨bllŒüü|¥ešÆÒRýªª*,ŽÅôiÓðúë¯#|bæÏ_ tÖðÀÂE‹p%?_q)°þ·©85áìä™,eee(++ƒL–Øbý–bqvrBBBJKKQZZŠ„)œœåëÓÛ¶oGUUŠ‹‹±|Å •ñ>«×$ ¨¨ÊdŠ2U–b%¢æÙÚö€41o¿ýÏVíGí3ÛîÝ5ë’’°qã&ÀK/½„¨y_ {÷îJuÇŒqÃòå+ðùÜÏ”–»ºº@GGQÑ1(..F÷îÝÐb¿ذq#œœ†œœœ˜¸Vé~‰*Þ^ž˜þɧ¨¬¬TÜÜÖ4––ê¯\µ®..xå•—Ä……X¹j5¦Ô»Žƒ’k×ÐÃÖÓ§Mk1NMøúú A*ÅÄðÐ¥sg¸¸¸àÇ›¿ ßR,¾¾>X—”„)S? ò||¼åáá¿[`bb/OO?þßãóðð@ÕÝ*DΜ…ªª*øÕ;Qõ÷h)V"j™­mŒnùªP:=G†×9F#¿ôn—\±˜‘8ŸÛòS@Ô1äååá‹y÷Ÿœ"¢§ƒ‹«›Æ¿€×äà5'; &MÅ ÈýзìÂã[p§,ÿÉ}ÊÓJ*“ÁËÓÕÕÕÊñº£ã㉈ژ¶^‘¢ &“'Œ•¥¦~< 5ÕÕäèˆÀÀ–/#Ñ“åq½‚‰Éä ãææ 77×Ç=e8Ÿ  ÆdBDD‚1™‘`L&DD$“  ÆdBDD‚1™‘`L&DD$´HDÔJ^´³W]©ÓÑÑÁ¹O«¬ÇdBDÔŠ:ò‹ss²³Ô®ËË\DD$ÏLžpšYÑ£2ôÍÇÂcÇdò˜0iêãè‰UWWס/ei “ÉS¢®®îq‡@ôÄayˆ÷LˆˆH0&""ŒÉDW·ÇQ»ÀdBDD‚i”L._¾ŒÏ>› /oxyûà³Ïæ"/ï²F¶ÆÑ|[œ!ð,„ˆ¨yj'“ÂÂBÌš=}ûÚCš°Ò„5èÛ¯/fÏ™ƒÂÂÂÖŒ‘ˆˆÚ9µ“ɦÍ)=jÞ}÷]˜ššÂÔÔQ#Í))ŠzMÁ?XVÿ¿õ빸ºaëÖm„ÿØqX½z jjjµÙTý–ú¸zõ*bbæÃì8øøú!*:ååå*ûøúë¯1>(ž^˜>ý\¾¬Ù™Ñ“@ídrúôi¼ùfã_y6 §O«÷¬õî];ÿ}ðùS§OaéÒ8,_†‚«HÏÈÜfC-õ3Fä¤uX·v-ÌÌÄHN^¯²'O!&&›7mDÿý±bÅJµâ&"z’¨LÊËËaf&n´ÜÌL¬8‚B"‘ÀÌÌ fff„„ +Kû¯i©åñËðê«vÐÕÕ…>Þ Ä‰“'U¶>1 V––‰DðpwÇo/j=n"¢öNí_ÀA./ƒµÒr¹¼ ÆÆÆ‚±¶²zøÙÚry™à65éã×_CRR.^º„ŠŠ @§Nªs­©©©â³žžîÝ»§Åˆ‰ˆ:µÏLìíí›<[8|ø0ìí¾³_WWwïÞU|¿~ýºR}&Û/*.Vú\ÿ,èQÛÔ¤…‹bøða&¬ÁÎÌHÙ¼ þù§Æ}=ÔN&þcý±û«¯°#3ׯ_Çõë×±#3_íÙ?_E½¿õéƒmÛ·£ªª ÅÅÅX¾b…R;ÆÆÆÈÏÏoÔ¾T*ƒ\.‡\.‡T*ÃPç¡‚ÛÔ¤ªª»Ð×ׇH$BII –/´>ˆˆZSÇ€T}o+j_æ²íÞÑQó°.) 7n¼ôÒKˆš÷ºwﮨ>ññË‘‘±&&&ðòôÄñãÿU”{{ybú'Ÿ¢²²Réfv_{{Lž<5µµproÁm6ÔR“'E@&KÄü `j*†‡»;¾;zTã>ˆˆžF:=G†×9F#¿ôn—\±˜‘mþ&LW·VßA·EíQNv&LšÊ·µ‚ó¹gð¢}³ûÌ–Ê:‚ûúÓö>X6(r?ô-{£ðøÜ)ËçëTˆˆH8&""¬]$“¶¸üô4^â""j+í"™QÇÆi{Ÿù& µL&O>ÉED­Éä 7dè›<+!¢VÇ{&DD$ÏLˆˆZQN¶ö߀Þ1™µ’§é±L&DD­¤þkHžt¼gBDD‚1™‘`L&DD$“  ÆdBDD‚1™‘`L&DD$˜F¿3yÑξµâ "¢vDGGG£ßÉhü£E¾4ˆèÉö(¯€áe.""ŒÉ„ˆˆc2!""Á˜LˆˆH0&""ŒÉ„ˆˆc2!ê \\ÝwD L&DD$gZ¤6uýúu¤¦¦á‡~€¼L‘èÿðüóÿ€«‹  ð¸Ãk–‹«vïÚù¸Ã j·˜L¨ÍÈår|òé üÿðÙgÿ••îÞ½‹ó.`ç®Ýí:™Q˘L¨ÍlÜ´ ÎÎNxÿ½÷Ëtuu1ðµ×0ðµ×Ëêêê–žŽû òöm8::"t‚"‘Àý³„ð‰aÈØ²7nÜ@ï^½ñzöì©öúÁÁAر#r¹»vfâêÕ«X¿~~ÌÍEmm-ìííñQ8Œ÷&ü÷ÁŠª~ª­­EJj*:ŒÛ·oÃÏ×îî磌«±.) ß|“pr‚?øÏ<ó  ¦¦R© ßää sçΊõÔ3¢ÖÆ{&ÔfNœ8Ç«¬—™™‰ÜܳˆŽŽ‚Lš€ÚÚlÜ´Y¹­“§Í›6¢ÿ€þX±b¥FëŸÍ=‹ØÅ_b×ÎL@Ìü=z4’“ÖaÝÚµ03#9y=€‡Éc÷®J—ºÔé§¾-[·â§ŸÎ!:* ‰2)J奊²´ôt\¹rqKb·$yyyHOÏP”§§gàêW±<~â–ÄâĉQkb2¡6sóf9,,,”–¹¸º)þ÷ÀÞ}û +++"hüx=zTi½ð‰a°²´„H$‚‡»;~»xQ£õ%’ˆÅbÅ÷åñËðê«vÐÕÕ…>Þ Ä‰“'[Üuú©ïàÁC 5 ¬(ËÎ>‰Dsss˜››c‚D‚ì#ÙŠò¬ì,H$˜™™)Ê…ÄB¤m¼ÌEmÆØØ×®]C÷îÝËé×O&%%% SZWGGG黩©©â³žžîÝ»§Ñú “Ú¯¿þ†¤¤$\¼t €NZ>ÖR§Ÿúär9lllš,+++ƒµ••â» äò²zë6. ‘¶1™P›qp臃áý÷ßk±ž¥…æ~>V––Ô:ë7ÜÑ.\´þ~~ˆŒœTVVÂì¸fë?Jœæææ(,,TÜÛ©O,£¨¸Ïöè(,,„™ÙÃ3'33åò¢¢"A±i/sQ›7v,>ŒÄµk‘ŸŸ{÷î¡¢¢ÿýßÿ”ê5 ñññÈÏÏGMM òò.cÁÂEj÷ó(ëWUÝ…¾¾>D"JJJ°|ù ¥rcccäçç êgÄðáX½&EEE¨¨¨€T&S”9;9!!!¥¥¥(--EB‚ÎNÎË!•Ê —Ë!—Ë‘ • Þf"mâ™ µKKK,þr6§¤`öœáæÍ›Ð××Ç+¯¼‚/-TÔsuuŽŽ¢¢cP\\ŒîÝ»! @í~eýÉ“" “%bþ‚05ÃÃÝßÕ»çàíå‰éŸ|ŠÊÊJÅ¥9Mûñðð@ÕÝ*DΜ…ªª*øùù*Ê|}}°.) S¦~ 2ä øøx?,÷ñA‚T†ð"Ð¥sg¸{¸ãôé‡Õ 3"¡tzŽ ¯sŒF~é5Ü.¹„c1#›MñE;{δHDô„ËÉ΄IS›œ¶÷AÙ ÈýзìÂã[p§,Ÿ—¹ˆˆH8&""ŒÉ„ˆˆc2!""Á˜LˆˆH0&""ŒÉ„ˆˆc2!""Á4þ|NvVkÄADD˜FÉ„o!%"¢¦h”Lšúi=`L&DD$“  ÆdBDD‚1™‘`L&DD$“  ÆdBDD‚1™‘`Mþžïß"""M4J&|ÿiJ)™è[öÆ Èý+""ê ô-{+}otfÒ°‘*ŠdRx|Ë㌃ˆˆÚÓ¿¿ÞlÙõ_¿WúÞåò:G€ºÖŠˆˆ:SÁÍ–Ý)ËW|¾|`…Îÿ£qrSŒIEND®B`‚wxglade-0.6.8.orig/docs/html/apb.html0000644000175000017500000000637312167336636017667 0ustar georgeskgeorgeskAppendix B. Licenses and Acknowledgements for Incorporated Software

Appendix B. Licenses and Acknowledgements for Incorporated Software

This section lists licenses and acknowledgements for third-party software incorporated in wxGlade.

OrderedDict

The OrderedDict class version 1.1 has been integrated. The class is downloaded from http://pypi.python.org/pypi/ordereddict and contains following notice:

Copyright (c) 2009 Raymond Hettinger

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

wxglade-0.6.8.orig/docs/html/pr01s02.html0000644000175000017500000000405412167336636020226 0ustar georgeskgeorgeskCopyrights and Trademarks

Copyrights and Trademarks

wxGlade is Copyright 2002-2007 by Alberto Griggio. Use and distribution of wxGlade is governed by the MIT license, located in Appendix A.

wxWidgets is Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al. See: http://www.wxwidgets.org for details.

UNIX is a registered trademark of the X Open Group, Inc.

Microsoft and Windows are registered trademarks of Microsoft Corporation.

wxglade-0.6.8.orig/docs/html/ch04.html0000644000175000017500000000344712167336636017662 0ustar georgeskgeorgeskChapter 4. Supported widgets

Chapter 4. Supported widgets

Introduction

wxGlade supports a number of widgets and helps you to edit the properties and visual look of each one.

wxglade-0.6.8.orig/docs/html/ch03s03.html0000644000175000017500000000552412167336636020205 0ustar georgeskgeorgeskDesign Window

Design Window

The design window shows the frame or panel you are creating in WYSIWYG mode and allows you to select a widget from the main palette and to put it on an empty slot of a sizer. You can show the design window by double-clicking on the icon of a frame or dialog in the tree window.

Figure 3.5. The Design Window

The Design Window


By clicking with the right mouse button on a widget you can access the context menu. Notice that the sizers, which are invisible elements, have a little gray handle, that you can click to select the sizer or let the pop-up menu appear.

The pop-up menu is the same as the one you get in the Tree Window, as shown in Figure 3.3, “The menu for a widget” or in Figure 3.4, “The menu for a sizer”.

wxglade-0.6.8.orig/docs/html/properties_window_settings.png0000644000175000017500000004771012166606326024443 0ustar georgeskgeorgesk‰PNG  IHDR“ýßâ‘KsBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´tEXtTitelProperties - IS—M IDATxœìÝy\”ÕþÀñϰ ²Ë¦(™ÝÛÍ\JM©lÿ¥@® ©÷– .¸¦©™¹TbîšÚ¨h您¹t+µÄ0Û4S(­[F‚ È ¨ ²Íïdd`˜…ñûþ½ø5<ç<çùžïùÎ<Ï<ç(¸Éï™HB!„þ>°F`å‰$pXTýF$„âŽsTX£PT$’óyWë;&!„w˜óG6q='­ü“ @é‚úŒG!ÄìV2)ªãdRVÊÕ‹g¸‘›ª´ÄèÝ–غúàèó/°°¬ƒ…w sG }|» ñUúd’_­ÐzÞãô¼ù:è9gŽÁOLL¤¸ç­û0YgÍ釕]SƒÛ©PRx å™$®œÿÏ{Þ_!*˜{¾Ý†øÔÉD¡P˜t m*·©°°4Ë1ÌÕŽâîeîñ¨¡o·#>ŸL™Û³gùëÄDƒ.sÍ›—Hù²D›óÜ­ jêÊÞp÷jÛ‚c”Ú+[XܵŸL¾™û(Ïý¶ž#â§c<2¶ZÛÓ6®UUmœ««ñMG|ÚÆÚËtħó“IÏž=Õ dîܹ&“¹Ü¼Ã¢ùÉDa‰…=Òt”V¾Õ¶+5gÆ#sü5~/*)ãbî öŸÊfóÑ —ÞùWô£û¼ï´–·µKçô–·3$!cÇ#]í(ŠZ·WuœÓ5¾™BW|{ÃÝy!öVÒØ=òV4&>Ý÷LL{+µ©°°DQ%7~2Ò €>±9¸•¤i”­ÝQ]¦Ù¤¥ÞÌþNÎv |ª#áO¶Ä»©ŠEŸ_Dež÷#·Å¶éœ.ºu³«û›?ðˆÝo¸Y–àbY@n™i×@ë‚‹-O·sç™vîüûƒäzeãèöHQr0EÉÅÜõ‹hX´Gµm…Eí ÿàdûVŒq•÷3d|«mœUã뛣ƒwt×ønÅnh|•’‰yÙÀÀDzöœKbb"%ŠÞ•‚°¨ñî¥iäXk§í^šFŽÕ­2………ÞXÝ,¯’QâÊ¥k%||àÝÚ¶¤çƒlù2…s%yã–þ7CóÁÃɆoýˆ…úvñ¤oO¼mÉÌ+â“ãYìø1“²›‰µbß·wÿÅÐǼiáfÇ…Ë7Øú]{O\º'ÜɃþxÑÂÕ–¬+E$üÉ®cYê­-ŽÊ=‹™1€îoýX©~Wþ³àP(P(zñ`‹¦Œ}Ú—6^öX[*8yî*Û¾Ëäû?ótžCc¸9Xód[7žnçF;ߦÜ(.ãøŸÙÜk“ÁÙbu½Ðn^Lx¶e*ÈÍ/æÈ﹬>FAQ©QçÖÐz+ y¹‡£žôå—ô«ìOÉáЯ—ÉÉ/6[ßÅI×xdl;(5¶§P 1~i+¯¼Ÿ!ã[mãÔÖlßµ9ìQž@*'’žTÇ^y7]ñUºÌežlXqilîܹ|©ñm.Ëß(nþT¦°4 V9*rËq/»õ€—åe²Ë\Ô¿wkb~ I‰’¶6¥´{ø&<Û’½?¦³ð›ôøŸkƒ½Å 6~Eã/´kÂì-?㢸ÊÈ^˜t¶Ü`ÇÏ×èÓÙƒ)Ï·âPJ&‹?>AP·Ö¼òüýØqƒ-Ç5§®©‡5¥DOïÀôÅq\WÙÒÖÆ–ÓÅ~êú¶eä•:ѧ‹þcÌé{/Í]mY¾ã¿§^ µ+C»ÝÏ/e‘¯j¢ç<êö|GwžyÐέ)*Qqü%«>ùßÏž£¬¤ˆ¦àdq«*l­ýª«éÚ¶%ÿy¾¶ªB¢>Ë Œ[S}çÖÐz³wœ¥£}]Ú4£Ã¿üû”/ŸkÅO]aÿ/—ùìd ÷åDã§c<2º…EíéÛ´–4¾Õ‚Žþö[›ÃηÉÈO¢ z"Ñ_¥ëPŠê?¦ªÔ– …BãG] …Áe峴Ī‘ÞËíæhCä³å—‰Nœù+E)ÖŠ[Ͼ|uä;œK2)TÙrkúu.¿VøÝ±”ðéðBg/¼¬.kã‹ÃßâP˜NÖµ26õ aþ^4³Ê…‚xpøÛãPt}7Ûê×Õ O«\¶ªÆQ¹WTa…‹å­ÔÕò .–× :†c+JJË(+ÈTüšv™w¾¥¥uVŠR­ç1iVgŸšÎ÷Ìà{xä^'~8“ÁÌþËÇ{ùå÷³Ü()#_eÇå2GÊ·þ^qG2PæäpµÄ’¯“Óèú7ZYeiüùô[ƒë)ü}Õ/Ïä½û{æ~°‡“¿¥Ñå^gf߃³e~Íÿ–ä§QÿhjóS1Õ4¾iÛt•ëß꨿• @쨎äZ·ÒÙ_Ÿ›Ìþɤ2…Æ=“š?VV‰IgYy;ºc]8õ% ü|f^ñIpìÇ\ÇVcßkù…¨<ÉU9SPf‡‡³¥WÈ/sçÂUG\íin©$Oå¤Þ77/Ÿ• WqäçËö4snНe6WUŽ4wµ`nx/Ø<\ia™­ÑVÕ8Ô}EAN™+¹*GÍsRþOРc|xèžöaʰÿ£L¥âŒb¥óç¹ ØY”’¯²Ñy.°þ›3%­«mgß9ú´·£ë¿¼étßÿqòÏ,ŽžÉâ›?¯’sÃŽb¬P¡@¡€¶ÍíèÃ?½Ûãhg­þ›º8ÚÓÌò Yª[7ýô[C멬¹aåʽmZñÔNt½Ï+ ~KÍà䙳Üguž”’û(RUJàâ®`ÎË\ ……ÎË\ºŽS›ñ­öqVß¾ýeWõëˆèSDGt a¸+×_®¡ÛtÏDóÈ·ÚÔv(t}.®Åiêh+SÜü¿Êíè‹uÆ’ ¨ì(¤|°µ¤°!·Ì‘b…æÀq®Ó•BÁ¥+ÅøºÙâÔÔ–‚ËM°w(¿Á}ùj¶Š"l*}ªqunʯYMÉÇ_—òËEʼkØ)n`«(&ûj1>.6D}@æÕu,MØ)ʰUׇæ9Tÿ¿jÛ 9ÆžŸs8ók2¼T´ñkIï˜âÇàÕ—) ‰Ö¦œ¤‹õ/ØP£›¸X\%·Røoòe~û5VM‹èô¯VtøWk&öyˆÑÅe|ûçfïú[]wnß{ðv¶a鎟øí¯ ØZê‰A( lÅX+J >·†Ö{½ï?x´vÖœ¹p•­‡ÿGÊïQ”…BE1ÖØ+ )BB‹¶ñ(þe—jߺ>·Z;ïüµÝ€¯:~é+7d|« }ýŒ¡ësÕÛ·¿ìZcµ1ê“ÉܹÚ™÷ ðPùë9÷Üš¿Kã“I _M˳Ñ~sÊ­$Ü›e•#SrMQ×n^§W¡ PeÇul¹¢rT¸õPX¢¢üzâgɹ„zøÈƒüúõeúú{pôçÿ¡ÂËJñ÷îÙ…3ŸCUfÇØ'[pøøoêz Ç”ŒÚ‡Þ=;³þàoX–Â?Z¸ñl—Ö,Ùþ– Uqä]/Á¹‰n.Ž(”(¨Ò_Eù¹5äóûµ&á;kŽg^ Ÿ\z÷€Òâbî³LçtiJ*½Ÿ¨ì|™7Š[“*Zâ.ª¼¸v5Ÿ¿e±ÿ§¿ñr¶¥Ó¿üèô€¾–Yœ/+?‡–7ÿø6Å—±±¶ä…Tjúέ¡õîq·c÷·qòÌYò®\A¥‚2,(Æže6Єë8ÔÉ;AѰÕö«¼n%iäVú²PÅxTS{F´×‡æ¿}ƒÆ·ZÐÕßÑ1É(kÝ `P\.[_*O(5õW£>™Ôô˜É¼Tज़¿$jôàÖk ŽËÅ¥Xó«Á ´¾i¾ùÐŒ¾X(UnÕÞIk¹›t³­ò‚-?dãn‘G@»¬ëðO2¯”°ñМ:ñ;ù4¡¬ÒILþýoæ„¶£™‹#—®³~ÿ¯ü’ü'Wq LaAÂq%Ö…™uñeAÄÓ¨T ’Ï°å‡ cCÎ5Ʊ6)‹ˆîîLY~#>paŠÖ¸ 9ƾS—õ„÷ùü‹âR¿œËåàá£Ø*а·(äJ•Kh2TžÕ¿®å´_§ ×i‚…ªŒ&e…\ºœOê·óù÷¿áiQÂe\(P5á­½éLÆ•±Ÿ 7¿ˆÍß]âéÊMWú›ê;·†Ö{iÝ´µü¨ kn`Ëu•WUÜÀ¶ükâuð\Ü´ŒGÚÆ¡ªªK㑹Û37ñ)(O$ŠÊ ï6Þ3Ñý0NžMõÉôÕ.oG{¬=ýJgËSXßlµ½“ÖU¯Lë¾»ÂþïOÓ„aM TØsYåL1·îgÿå,ûSr°D… °¢„2ÈU¹P„ …{N—rüÌwØS@)VaM1Ö€M×kŒcÏϹ$Ÿ:‰‡BI6<`iË™²h­¯ïߟµà\êYœ¸ª>ŸÖs]åLù7<ÌówWaAM) )JJ±W]§)ùåwMœJ¿Îô¸³x+²(UX¯r`È©ßi¡ÈÀBL ;·Æü ²TXRÆ5•=…Ø•kìæ¡$ܽj´CÕö­ÖŽ…ÙÛ37}ñiûß‚¶2]ñéüdRy •ò×5Dú3wsŸÔò}¡w˜ºŠ…¥%¥Å…XÛØikÁ ÅE×QXZéÌÜé*(€*”¡õ®á@šªNŠ«ØP((PÙq'n(l5Ú¸¢r… ; ; TMÈÉ"Eù5øìÕm5¡e”`Å5¸¡°5Æ‘©òâvØRˆpV\!çjõ 9FŽÊb…5ö”¬Øs G °¯“wA¥XqG®â¨ñ/1 аÆ^uP¬²á<ÞØÞ<ÏÆœ[Cë)¹yc_2‡¨ÄÜãÑíßjëvħû ø o]µ ¬q«²À¡•~iwóJWÐ`:–MœÉLÿ/ßû°©E‡Š‹®“™þÖMœµÇzS&å×èõ ºêåãH>•.ÿhýˆ… ;ÍËUZêbO!öÕöÕGàPmmõõãvÜÀ®ÆòÛ¥[²ðÒC•׆œ[ƒë Q…¹Ç£Û5¾ÕÖíˆO½ü¹¬ SãÕIE%×.SRx Tµ˜§Ea¥6nusMÑ'°¡ˆÓªU¹÷!Le蹕¿0…¹Ç£†>¾Õe|?îÒ\¾®gâU`µ£ÖŽuzœÛá<¾8pó73Ýså =·ò7¦0÷xÔÐÇ·Û_µYƒË—wº¤å×S.ßüæ’ rn ­'„¨öU–ïÕxÈ  ë,ë_ô¼­Ý hß±¾Ch0N'×<‹ªâÎñòæ³ EûkÂlhßQÐJÚvxˆ_Oý\ßa!ÌLk2qrrÒ¶Y“$%ªï„u¤Z2qrrâÄß×G,R ¿Öõ‚BÔ9ùŒB“I2Ba2I&B!L&ÉD!„É$™!„0™$!„&kÐÉdâÔéõB£Rß!!™L*«ËÄÒ’V~~6l$bÔhúõÀ Á/òöÛó9yÒð§çµ% mÛöíÝcR¬BQ•ÉÉäËÄÃLžö_&6G<5Z¹d¡YÚÑ–8ÌÕ¶).ZÄ•«W™;g6ñÛ¶òáïØ3-[·ÕwhB¡—Iss©T*¾9ú}C‚HL:“:—æ5KIIá£qp(_äÊÙÙ™ݻӣ{wu•JŶøxì?@~AþþþŒúHÅ÷íÝ£u[Åï•_GŽÃö„äææroëÖŒ????Š‹‹‰Ž‰åÈ‘#XZZÒ·OÖÇÅ©÷?yò$ëÖ­'-=ÂÂByîÙgëút !“’ɯg~£I“&tœÿÄé3¿Ñö©Ë'NNHï^:ü5¥eet~¸#}C‚±´´4¨¼²‰S§«?A”••ñùƒüðãq oÜ๧Ÿä‰À².e³ï³ÏùßRVVÆ?ï»Aûáàà þTRñߊö*·]RRžO?ã§ŸË'#ìôÐC„ô~+++uÝÐþ}9øU"W¯^¥E‹æ ØooSN%Ú·gõêÕ‡s_›6ØØØT«³{÷n’“SˆŠšƒƒFG³éãÍŒ1\<*_ÂÒ¶M›ã?`Á‚(œœØõÉ'¬Yó‹•ŸmÛâ¹”•ÅšÕ«X¾b¥Æ¾K—-cÔ¨Qt}ärssÙ²e«$!îB&]æ:rô[º?@÷Ç%éè·ÕêüöûÿxuòfL™DVV6¾Ó¦½J ß¼ÿþ ü"#Ã#X·n=ùùê:Ÿ±Ÿ1cFãååEÓ¦M1|8G5ùØ‘cÇàåé‰ýúöå?ÿT—%>ÌÈ‘#pssÃÍÍðð‘ûZXX’£Ì!//&LorÆÉÑ‘'{pòT²ºüé'ž`ùê÷¸~ýºÖ›ðÏ>ý{öý—%+ÞàáŽyæé'õŸuìÐŽ:謣P("88HkyŸ>}èÓ§ÞmU¿ñUUåm666Œ‹Œd\d$©©©8xP]Ѓ€€:ãB4~ ¿g"UâH˾DAÖYvŒ¾Ïl+-VþÊmmʃ ƒîø5àcbcп?ÅÅŬ|w­ï¹‡‘#GÝNRâ!FM˜,kÀ Ѽ¼9 {Ï{¹ø}×sÒL{ÎDܼ<½˜üÊJŠ‹éæïϰaCë;$!D#ÉDèLHH°þŠBˆ»VNô¨ïVc¿Ä%„w‹;fÖ`!„ —$!„&“d"„Âd’L„B˜¬Ú·¹Zøµ¦…_ëúˆ¥QºÓŸ11§=Ÿà×S?ó@ûŽõŠÂ …‚n3öklÓúÕ`E]’_B4>r™K!„Á’µ¯9%ÉD!„É$™!„0™$!„&»k“Im×÷BQÝ]›L IjBˆÆÀäYƒ/_¾ÌÖ­Û8vìÊ%vvM¸ÿþD—.]Ìãm—Ÿ_@BBß=Jvv6666´{ðA‚ƒƒèØÑ°g$‚‚Cª-<¥m›¶Å©„âNcR2Q*•¼:m:?þsçÎÁËË‹7npúÌöìÝwÇ&“…‹áááÁÜ9³ñôô$??ŸSÉÉlÙºÍàd"„w“’ɦ?&00€ÿüûßêm666t}äº>òˆz›J¥b[|<ö ¿ FŠÀÎÎ(Ç9v Ûv››Ë½­[3~ü8üüü ÞäÈ|òÉn”J%{÷ìæüùólÜø§’“)--¥cÇŽŒ‰“““Þ~¥¤¤ðÑÆ88ØàììLîÝéѽ»A}ª¸tUñß}{÷hÝVñ{å׺ÎCqq1Ñ1±9rKKKúöéÃú¸8õþ'Oždݺõ¤¥§ãââBXX(Ï=«}ye!„0'“î™?~œ§ŸzJo½Ý»w“œœBTÔ|bc¢)--aÓÇ›5Ûúé D±ùãMtîÒ™5kÞ3jÿ”ä–-]ÂÞ=»XðÎBz÷î͆¸õ¬_·ww76lØhP¿:´oÏêÕ«ùõôiŠŠŠŒîSÅà¾oï×U·i£ëœ£Gjì9v ^žžØÙÙѯo_þøóO£öˆÇÍÍMýûêUïÒ¡C{lllpp°ç߯qü§Ÿ ê×´i¯Ò·ï¿ÿƒ¿ÈÈðÖ­[O~~Q1Õ†®óxø0#GŽÀÍÍ 777ÂÃGjìkaaIŽ2‡¼¼<<<<˜0a¼Éñ!„! ºÌUõñùˆñ“8|'''.]ºD‹-Ôe•/ÙTÈÊÊbôè1m( ß]]]Õ¯mmm5>²Õ¤ö¿ÿýA\\ž=˵k×°°0,wÚÛÛ3tȆ‚J¥"--;w²déæÌžmpLµ¡ë<äääàåå¥þÝ»Òk€7f½Î–­Ûؼe ŽŽŽDD„Ó¥sghß‘èU+LŽMq÷©ïõ1øžIÄøIê× wêô0~ÉþóïšvÀÓÃyoÎÃËÓÓÐýÕ|ÑâE 4ˆ3¦ãàà@~~>ƒ_bô± ­Zµ""<œ—^npLÚ‹©ÉÆÍÍÌÌL|}}ÈÈÌÔ(oÓ¦ ³^Ÿ‰J¥âرã¬\ù.mÜÀéä“?!„0„1oBº_5; yñE¦¾:’Òž}æ¼¼¼(**â×Ó§5êõêÕ‹U«V1*"ÒÓϳ->žéÓ^5踵ٿ°ðöööØÙÙ‘••Åúõq÷sÆk3éÝ»íÛµ£iSG”Êlvð`Û¶ÇäääDZZ-[¶Tï£m›1ˆ]«¾|»V£|ÑâÅ 4ˆæ>>€fò’™z…uɤosyzz²tÉb6oÙÂë³Þ //{{{ÚµkÇ’Å‹Ôõ‚ƒƒP(ÌZ@ff&-Z4gèС§6ûOœ0žØØµ¼³p!®®nôëÛ—o ¼§1xð öíû”5kÞ£¨¨WWWéÒ…)S^18¦ú3õÕiäçç«/ýiÛfŒ°°P¢cb9+KK‚‚‚8uêV’ðïæOÔü(².]¢¥¯/S§L1úBQ ¿g"UâH˾DAÖY¾[ðLµw±I‰‡ ¾n&nŸÔÔTÞz{>kccê;!D#¤mìOJ<Ĩ “é6c?öž÷rñû®ç¤Ét*wš˜ØX._¾LVV1±kyÔß¿¾CBÓ§S·——§“_™BIq1Ýüý6ÌðË…BQW$™ÜaBB‚ ®ï0„Bƒ\æBa2I&B!L&ÉD!„É$™!„0YƒO&²aÝó*„0§ŸL"ˆ…BS'“†4ðÖ&mûÈR»B¡I>™!„0Ùm}hQß²´%%%ÄÄÄòuRRù²´}ûhìoÊò¿5-›«ky_C–Ú-..f}\_@@@^~é%¬­­ ê³¶s4vÌvì܉R©¤yóæŒ‹Ë…‹‰ßNvv6÷¶nͤIÕSÑë‹ÁÔó*„úÜöO&º–¥ßÎù çY½ê]V,_ÆñãÇ5ö5eùßš–ÍÕµ¼¯!Kín‹çܹs¬X¾ŒË—‘ššJ|üvƒû¬ÍÇ~äí·Þbë–Íô dÎÜy|ûí·¼9o.›?ÞD×®]Y]y9_=1˜ã¼ !„.·=™è§`‹† IDATZ–öPâ!"""pww§Y³fŒŠˆÐØ×Ôåµ1ey_€ÄÄÃDDDЬY3ủ‡MŠiü¸ñøøxcggÇ /„pýúuÆEFâí}kÛï¿ÿnp æ8¯B¡‹Ù.sÕ´´oUº–¥U*s4–¢õ¹¹ÈSS—ÿÕÆ”å}¡|)ݪ1+•9&Å俦Y__úb0å¼Ê’¿B4^æ\ZĬ÷L´-ík ww7223ius%ÂŒŒ rS—ÿÕ¶l®¾å}õ-µëæ¦óÅ‹qww«U|µ¥/SΫ,ù+Dãdî7‰f¿oJ– $&&–I'£¹è“©Ëÿj[6Wßò¾ú–Ú  ::šI'–ÇC`@ ¡]6 }1˜z^eQ4!„> j ú°ÐP¢cb‰7+KKúöëËÏ?ßÈL]þWÛ²¹ú–÷Õ·ÔnXX(ëãâ˜4¹|Iß=º:°¶§ VôÅP×çU!̶l¯,í+„wŽÚŽë²l¯Bˆ:#ÉD!„É$™!„0™$!„&“d"„Âd’L„B˜L’‰B“ݶ‡“““Ù÷éùæ›ophÚ”çžy†ÞA½k==Š¡*O_ê³oBÑÔù'“üü|^›ù:;w}°ÿü‡§’ù3õoþûùø?þ8¯ÏzƒÝ»ïÌ• sß„ÂuþÉäµ™3iß¡#ËV¬ÔØîëë‹ï€<óìs„ èCSž~ê©Ûѵän}-£k®¾äçÀ7G’ í|àà :vìX—ÝB“Õi2ùê«CÜÓúÞjƒmeNNNlKØÁóÏ>£sÀ­œ0êú²•!ÌÙ7€…‹áááÁÜ9³ñôô$??ŸSÉÉlÙºM’‰¢Á«Ód²y˶%ìÐ[ÏÉɉÿëÕ«ÖÇѵôn…;v²k×.JËÊ `äÈXY•wÿäÉ“¬[·ž´ôt\\\ å¹gŸ5ªo¿þò á#Gp>=gž}Ž˜µkê[JJ m܈ƒƒ=ÎÎÎôèÞÝ»«ë‡ðòK/ÕØ}ç¡´´”-[·òå—_QPPÀ °0õ¾ú–î­Í9BÜ=êôžIFF†zr}üýýk}]KïV8ñó V®\ÁêUï’~>øí·–µ]ºl¡a¡lÛº……ï,à·3¿é=fÕ¾… ÀùôtìÿÂè¾uhßžÕ«WóëéÓ:ÏÒÕ}ç!aÇ~ùåW¢æÏgml ÙÊlu™¾¥{ksŽ„wóÕà¾-?ab­ö5déÝŠekÝÝ݉çС[+CZXX’£Ì!//&Lot W¯^Õøýùçn½k7¤oÓ¦½J ß¼ÿþ ü"#Ã#X·n=ùù÷Cßy8xðKFŠÀÇÇ›¦M›>r¤ºLßÒ½æ8GBˆÆ«Á¬gr>=UïÖ|ÿAC–Þ­¼l­···Æ²¶oÌz-[·±yˉˆ§KçÎFÅàè訑P>ûb¿úµ!}³··gè! 2•JEZZ;vîdÉÒ%Ì™=Û ~è;J¥²Ú’½ô-‰lŽs$„h¼ê4™x{{“žžnÐ¥®ï¾ûŽ7¯ßKßÒ»€æ²µ™™ËÚ¶iÓ†Y¯ÏD¥RqìØqV®|—6nÐy̪}Û¶=ysçà[eUFcû¦P(hÕªáá¼ôòpƒû¡ï<4kÖŒ‹/âççWí˜ú–D®Í9BÜ=êô2׋ƒ3oÎl½õ®\¹Âçÿýo­SuéÝÕ«×T«‹R©D©TKÏÀžê²E‹s.-ÒÒR@ÿºïP½om|mÛض=¥Ë–Ý·¯Í$éÈrss)))%33“¸¸ <ض­ÁýÐwž~ê)>ø0šŒŒ ®]»FLl¬º¬béÞ´´4JJJHMý›…‹›tŽ„w:ýdòä“OðÉîOxeÒÄ¿B{åÊÂôgР°ZGßÒ»uìÈĉ“()-%  ‡Æ²¶þÝü‰šEÖ¥K´ôõeê”)·½oƒbß¾OY³æ=ŠŠŠpuuå‘.]˜2åƒû¡ï<ôë×Â…Ìxm&………qé[º·6çHq÷¨óe{óóóy{~vvvŒ§›ÿ£899‘žžÎ÷ß}˲¥K îÝ›^¨ù¡Ä†êv÷­!<_#„h̽lo߀wpp`AÔ|’““ùhÃFGD”o¿9Õü·ßºcç¯jÌ}BcܶosµoßžöíÛß®ÃÝV¹oBaˆóœ‰ÐO.q !*I&B!L&ÉD!„É$™!„0™YoÀG¯ZaÎæ„BÜ!Ì–L"ÆO2WSB!î0fK&º|BѸÉ=!„&“d"„Âd’L„B˜L’‰B“I2Ba2I&B!LÖ`Ö€·GRâ¡úAÑÀôèù„ÉmH2¹ š0¹¾CB4*•Ê,Ï J2¹K©TªúAaf …¨ÿm+ ³[’‰B4"õ5‰Ü€Ba²“L‚‚Cê;!„htòóóÙ¼yKG.s !D#öÖÛóIIIáZþ5"ÂÃëì8fûdÒ>Y4¤XÌ©®û•““ãݺrOKß:=ŽâöX¾b)))ìÙ³·NÕ`.s‰ú·|éR† ûw}‡!„0“É“&±oïõO]ª“Ë\AÁ!DŽÃö„äææroëÖŒ????JJJˆ‰‰åë¤$,--éÛ·Æþ*•ŠmññØ€ü‚üýý=*;;;½íW¼{¯øoM'ðüùólÜø§’“)--¥cÇŽŒ‰“““zÿ±cưcçN”J%Í›7g\äX.\¼H|üv²³³¹·uk&Mšˆ¯où;ùââbÖÇÅñõ×Iôàå—^ÂÚÚZÝfÕx*o3G¿jë?þÇׇÙÿåW,ZøŽYÛB4~uvÏäøO'X° g''v}ò kּǢE ˆßÎù çY½ê]T*Ë–/רw÷îÝ$'§5>ŒŽfÓÇ›9b¸Þö÷íÝ£uЮjÁ; ‰gÊ”W(..á£M±aÃFƧ®óã±yû­·puuaÏž½Ì™;Úóæ¼¹¸¸”o[½æ=ÞYÀ¶øxÎ;ÇŠåËX¶|9ññÛ2äE“Ï›¡ýª­ùo½Å+S_ÅÖÖ¶NÚBÜõ5ËE%“ȱcpuu _ß¾lßž .;”xˆ7ÞxwwwFED9n¼ºüó/ö3kÖëxyy0bøp^™2U#™èjß«W½«~mccÿ‡ clä8:ãÇÇÍ­ü/¼ÂÆ>b\d¤ú¸/¼ÂÖmÛÔõ3{ö4kÖLݯ·çÏ7*™˜Ú¯ÚHJúšœœB^x¡Î%„¨[Æ,¡nÎÙ0ê,™T ˆ¶¶¶©W*sð¾™(|||4öÍÊÊbôè1Ûª>©©«}CüïÇŸgÏríÚ5,,4o!U$’Šcè;nNNõ~)•9FÅej¿jcþ›oòVT”YŸ†BÔúzh±^¾ìîîFFf&­Z¶ ##C£ÜÓÃyoÎÃËÓ³Ví2(.Z¼ˆÁƒ1cÆtÈÏÏgð‹Cju¼ nnšýºxñ"îînêrnܸ¡NL—/_6ªýºìÏœ9ÃÀ~ý4¶ÝÓÒ—Ô´ô:9ž¢ñ©—os‹R©D©T£QÞ«W/V­ZEZZ%%%¤¦þÍÂE‹ nßÉɉ´´4u o`ooYYY¬^½¦V}©,0 €èèh²³³ÉÎÎ&::†À€@uù}mÚ°s×. ÉÌÌdõãŽiH¿j#5-]ã§b›âÎ6~ÂD‚‚CÔ?ËW¬¨³cÕK2 ÅÛÛ›Èqã™8q?ü°Fyppݺvc~Ô††±dé nà€þL}ušÎç2&NO\܆†òÚÌ×i×®]­ûS!,,”–-[2iò+Lšü ­üZ:P]9–ãÇŽó⡼6óu:wêlTû†ôK!*¼³ Ï›WxÚµkÇäI†ßO1–Âï™HUà°(Ò²/Qu–ï!ŸJ„f'7à…B˜L’‰B“I2Ba2I&B!L&ÉD!„É þ6Wôªº›ºX!ÄÍ dbÌ2B!î>%y.A!„.rÏD!„É$™!„0™$!„&“d"„Âd’L„B˜L’‰B“5¨dRß!!„¨…•L3I”BˆÆÌ¤Å±*...têÔ‰ð‘#ptt4hß}{÷˜rx“åçÀ7G’ í|àà :vìhPÚú¡m[}÷U!ê’É+-V ’J¥’˜ØX>ü0š©S§˜Øí°pÑ"<<<˜;g6žžžäççs*9™-[·œL„B˜qÙ^wwwF͘1c˜>ã5z÷êE@@uK—.1eêTrr.·>ÙT~×þÙgŸ±=a¹¹¹ÜÛº5ãÇÃÏÏ€ââbÖÇÅñõ×Iôàå—^ÂÚÚZÝ^äØ15î_UJJ m܈ƒƒ=ÎÎÎôèÞÝ»«ë¨T*¶ÅÇs`ÿò ð÷÷gô¨ìììÔñWm¿W~­+Îââb¢cb9rä–––ôíÓ‡õqqêýOž<ɺuëIKOÇÅÅ…°°Pž{öY£þ^BaNuvÏ$,t [¶nE¥R©·mÙ²•Jƒê¾½{ª]þ9þÓ ,ˆbóÇ›èÜ¥3kÖ¼§.ÛϹsçX±|+–/#55•øøíï_U‡öíY½z5¿ž>MQQ‘Ö:»wï&99…¨¨ùÄÆDSZZ¦7«ã¯Ú]}3¸ŸÛâ¹”•ÅšÕ«xwå ~>©97ÚÒeË eÛÖ-,|g¿ù­Æã!Äí`¶d’““Ctt4?ü:uÂÎÎŽÃ_ À… øéÄ ‚ƒƒt¶9v ^žžØÙÙѯo_þøóOuYbâa"""h͚֬5cTD‰‡ Þ¿ªiÓ^¥…o Þÿ ~‘‘á¬[·žüüuÏ¿ØÏ˜1£ñòò¢iÓ¦Œ>œ£G{zŒëçáÃŒ9777ÜÜÜ©±¯……%9Êòòòððð`„ñ&Ç#„¦0è2WRâ!ß#ÆORÏ$\q9ÇÅÙ™‡~˜ð‘#ÔõÂÂB‰[G@|üñfú÷뇭­­Îc¹ººª_ÛÚÚj|bÈÉÉÁÛËKý»JeŽÁûWeooÏÐ!C:d*•Š´´4vìÜÉ’¥K˜3{6YYYŒ=Fc?…B¡³†Ð×O¯Jý¬Üg€7f½Î–­Ûؼe ŽŽŽDD„Ó¥sghßQÖB˜Uåñ^ƒï™T^Ó¤rú.åtëÚ•M›6±aÃFΜ9ÃäÉ·Ú¨Í€ìææFFf&­Z¶àâÅ‹¸»»ÝŽ6 …‚V­ZÎK/Wo÷ôð`Þ›óðòô¬q?C¶ÃÍÍÌÌL|}}ÈÈÌÔ(oÓ¦ ³^Ÿ‰J¥âرã¬\ù.mÜÀé䓲öŒÂlŒysjÔ xc×5Q(„…†²pÑb&L•Õ­Ã999‘––FË›‰ÁDGG3iâD¢£c 4*¦Êf¼6“Þ½{Ѿ];š6uD©Ì&!a¶m«®Ó«W/V­ZŨˆ|||HO?϶øx¦O{µÆ~Ô¦oUû»V}ù*6v­Fù¢Å‹4hÍ}|Íä%kÏ!êƒÙ¾ÍU š7oÎSO>©±}à€þL}uùùù?ƒÊú¸8&M~€=º:°Ö± <ˆ}û>eÍš÷(**ÂÕÕ•GºtaÊ”WÔu‚ƒƒP(ÌZ@ff&-Z4gèС:ûQ›¾UígtL c#ÇaeiIPP§NÝJþÝü‰šEÖ¥K´ôõeê”;ã«ØBˆÆKá÷L¤*pXiÙ—(È:Ëw ž©öî6)ñÁ×ͪzó­· 0 À\1ßuRSSyëíù¬©ïP„wmcRâ!FM˜L·û±÷¼—‹ß'p='­î¾¬R©øüó/ÈÊÊ$ Gý; 1±±\¾|™¬¬,bb×ò¨¿}‡$„5ª³Ë\Á!/àåéÉŒ3Ìòí§»—§“_™BIq1Ýüý6l¨þ„¢žÔY2‘¹¨LLHHp}‡!„‘Yƒ…B˜L’‰B“I2Ba²FLô-H% V !„y4êdb I4Ba8³%]ƒï807Äo£Ý‰çQqwO&B!LVçssU¥k•@]«j£oåÅÊJJJˆ‰‰å뤤òÕ ûöÑgÕ•ÇŽÃŽ;Q*•4oÞœq‘c¹pñ"ññÛÉÎÎæÞÖ­™4i¢z¦ß à^~é%víÚEiYŒ9B=Ù¥!«FŽ9‚O>ÙR©T/2¦muJ!„¨o·ý“‰®Uu­j¨!+/VˆßÎù çY½ê]V,_ÆñãÇŠûÇc?òö[o±uËfz2gî<¾ýö[Þœ7—Ío¢k×®¬®²ªã‰ŸO°rå V¯z—ôóéÄo¿›!±§$§°léöîÙmð ŽBQn{2ѵJ ±«²òb…C‰‡ˆˆˆÀÝÝ]]×ãÇÇÇÇ;;;^x!„ëׯ3.2oï[Û~ÿýw}*ŽçîîNDx8‡ÝZdÌØ#"Âqs3Ïz-BQ—Ìv™ËÊÊ’âââj—˜ŠŠŠ4ææªi•@0~UCCV^¬ TV¯k 77Í•AÿªŽ•çíí­›!±{xx£¢ñ«ÍqnÇÕ ³%Ÿæœ=û÷ßÿOígÿú ÏJƒbM«‚þU «2fåEwwͺF÷ÑXÇËÌÔˆÍØ«&R™0Sðgêß×ms_Fr‹ù¾Ô›U«W‘’’BAA$''³jÕjzõ·hñbÎ¥¥QZZ h«¦¥¥QRRBjêß,\´¸ÆcV¬¼˜Mvv¶Î•‰‰‰E©T¢T*‰Ž©ûµA*/&&–ž=k{…Š…¢¡1Û'“^Ï?­­-k×­ãÂ… 4oÞœþýúòd¥Uu­¨oUêŒYy1,4”è˜X"ÇÇÊÒ’¾ýúòóÏu»ÄíC;2qâ$JJK è¡[mV4uG!„¨+u¾ÒâݪòW‹…Â\‚‚CŒ¾ÌUÛ±¨A¬´(„âî!ÉD!„É$™Ô¹Ä%„¸›Ôi29sæ £FË…UÈùB46ušLÖ­ãå—þ#ïÒI†BˆªÌ>}å&55•.]º˜ëõ&(8Dý3tØ¿Y¶|W¯^5x߯¦!¾90æü0º¾CFX´x1û>ý”’’ò‡eKJJÙ·ïS-®ù¡X!„áêl úªïôöíÝSmZõ½{v4»±Ó¿WÁ³fѪU+¾üò+žzªü!ÊsçÎñÖÛoóÐCsÿ?ÿÁÓO?­ÞïÀƒüþ¿ÿ9Vs®0wwwF͘1c˜>ã5z÷êE@@uK—.1eêTrr.W;>ûì3¶'ì 77—{[·füøqøù•O{`È9‰;¦Æýë²ÿǿӦçeòd<ȼyó˜7o=þ¯Lž\­® Ýíš"Åu–L*’GÕÿaWL«^1n婨–-_N|üv† yQ½OÅôï®®.ìÙ³—9sçÑ¡C{Þœ7—òm«×¼Ç; ¢ªÅÑéáN¤¤üB«V­ÈÎÎæƒ?ä±Ç¥I“&$§¤Ð¹SgFŽÁ¬7ÞÀÖÎŽÝ»“””Ä—_}ÉÛo½­·Ÿa¡‰‰]KÝÕSÃlÙ²•à è_ãËÇ:Á‚Q8;9±ë“OX³æ=-Zhð9ѵÿíìmÿ>Óó,_±‚øíÛyqð`ƒû_õß‘!‰*Pèü]ˆ;AC¼Ì f¼ÌUy½ ]ªN«nÈTìµ™þ½B§NHNIQËÆÆ†¯“Êßñ¦$§Ð©ÓÃXYY1cútââ6°aÃFâ6ldÆôéXYYVk/''‡èèh~ø!uûvvvþúk.\¸ÀO'N¤óó5>Ù½›‹/j´Sq~Ó¦˜:åœÕeݺvÅÊÚŠ 6ræÌžþÿjì¯!ÌyNÌÕs«Ü¿š¦ç¯`îéùåÓ‡æWïOÀ×f*vcuîÔ‰ØØµ<ѳ'={òÁÒ¹Sù¢\………,]¶Œ©S¦ðè£9v ï¼³°ÆwûU) ÂBCÙ±s'aƒÂÔ7’¡vÓÆ›ãœTþŠk]÷¿6dz~!—zO&aa¡´lÙ’I“_aÒäWhå×JïTìÆêÔ©¹¹¹êo\pùòe:uz€÷Þÿ€à  Úµ{€®]»òÄ“OðÞû| š7oÎS•¦Û‡[ÓÆóü‚¹ÏÉí迱*¦ç¼y¿¥êôüÆö¿6çYa>2½™¼ùÖÛPß¡4x2=¿wc¦ ¯³¯ß-T*_|±Ÿ¬¬LzôпƒB4B’LLò^žžÌ˜1CÖhBܵ$™˜H.×OΙO½ß€Bqç“d"„Âd’L„B˜L’‰B“I2Ba2ƒ¿Í½jE]Æ!„âfP2‰?©®ãBq3(™È4*B!t‘{&B!L&ÉD!„É$™!„0™$!„&“d"„Âd’L„B˜L’‰B“I2©Yg\!4™¼8Vzz:?úˆää®_¿NëÖ÷0 üq­õYÿÛ˜ºùù$$$ðÍÑ£dggcccC»$88ˆŽ;ÖúxÚ¶ÉâNB¡É¤dráÂf¼6“þýú>r$...œ=û;wî¬1™Ô•…‹áááÁÜ9³ñôô$??ŸSÉÉlÙºÍàd"„¢vLJ&›7o!88ˆ¾}û¨·Ýÿ?yíµ&f¬””>Ú¸{œéѽ;=ºwW×Q©Tl‹çÀþäàïïÏèQØÙÙ©/]UüwßÞ=Z·Uü^ùuäØ1lOØAnn.÷¶nÍøñãðó󠸸˜è˜XŽ9‚¥¥%}ûôa}\œzÿ“'O²nÝzÒÒÓqqq!,,”çž}¶®O—B˜•I÷L~>y’À€sÅb’íÛ³zõj~=}š¢¢"­uvïÞMrr QQ󉉦´´„Mon%Š}{÷h¼®ºM›ã?`Á‚(6¼‰Î]:³fÍ{ê²mÛâ¹”•ÅšÕ«xwå ~>©9ÏÙÒeË eÛÖ-,|g¿ù­ö'A!ê‰IŸL®^½Š›››Î:ÚnVWÝVù]¾¡u«š6íUvîÚÅûïÀùóçqssã±G%,,Lýiåó/ö3kÖëxyy0bøp^™2•‘#†ëìƒ>‘cÇàêê @¿¾}Ù¾=A]–xø0sçÌVŸ§ð𑌩.·°°$G™C^^L˜0Þ¤X„¢>”L’iü1~§“OâèèHNNÞÞÞ5îkÈ íÚÔ­ÊÞÞž¡C†0tÈT*iiiìØ¹“%K—0göl²²²=zŒÆ~ … öu©H$¶¶¶ŸŒrrrÔÉ À»Òk€7f½Î–­Ûؼe ŽŽŽDD„Ó¥sghßQÖBÔ»Šñ^ƒ?™T^Ó¤¢á‡:v$)é¨EˆuG¡PЪU+"ÂÃyéå[Ÿ:<=<˜÷æ<¼<=kÜÏmÆpss#33___2235ÊÛ´iì×g¢R©8vì8+W¾ËG7p:ù¤¬##„¨WƼ¡5ê2WÕìô⋃™>ã5¬m¬éþøã8;;ó×_±cÇÎÛ~~Æk3éÝ»íÛµ£iSG”Êlvð`Û¶ê:½zõbÕªUŒŠˆÀÇLJôôól‹gú´Wprr"--–-[ª÷ѶÍÄÆ®U_¾Š]«Q¾hñb Ds@3yÉ:2Bˆ;…I÷Lš7oNÔü·ÙøÑ&¶lÙÊ7hݺ5ú÷3W|kccê;!„ÐIÛØŸ”xˆQ&ÓmÆ~ì=ïåâ÷ \ÏI“éTn‡˜ØX._¾LVV1±kyÔß¿¾CB³2y:¡Ÿ—§“_™BIq1Ýüý6l¨þ„â"Éä6 &$$¸¾ÃBˆ:#—¹„B˜L’‰B“Ée®»LÕÙ „¢GÏ'LnC’É]hÔ„Éõ‚¢P©TfyìC’É]J¥RÕwBˆzfÎg垉B“I2Ba2I&B!L&ÉD!„ÉÌv>?¿€„„¾9z”ììllllh÷àƒѱcGs¦Á2f!/!„hlÌ–L.Z„‡‡sçÌÆÓÓ“üü|N%'³eë¶»"™!ÄÝÌl—¹RRRþòË4oÞ+++œéѽ;ï,ˆR×)..&:&†¡ÃþÍÐaÿ&:&†ââbu¹¾5àƒ‚Cød÷n^zy8Á!/PZZʦ?æåá#4˜]»>Q×W©Tlݶ#F2hð‹¬Xù.………5öAWý5ï½ÏÁƒ5ê8p5ッŽ1(8Dkº’’–-YÂcþÝèð`[b¢?T—ÝÓÒ—ÞÎ?ÄCíÛ1{Ö,¿™¾r!ÄÝÁlɤCûö¬^½š_OŸÖX½²mññœ;wŽË—±bù2RSS‰ßnÔqR’SX¶t {÷ì aÇ~ùåW¢æ—¯’­ÌV×ݽ{7ÉÉ)DEÍ'6&šÒÒ6}¼¹Æ¶uÕÎÁ/¿$éÈ’’’øò«/¡¾¼µoïž;òR×ï¿Ç?|Ï–mñ$ý–‹/j”IJâÓÏ>çó9{öOÖ¬^eT¹¢ñ3[2™6íUZø¶àý÷?`ÐàÁºuëÉÏ/P×IL>Þ4mÚ”ð‘#ÕeŸ±Ÿ1cFãååEÓ¦M1|8G­±m]õ­¬¬˜1}:qqذa#q62cút¬¬,Š¿!JˆgÞ[oãç燳³3³çÌÕ(Ÿ3oÞÞÞx{{3{îú(‘cÇðÎ; Õ÷‡œœœHKK3ú¼5†2çYœ;w޼¼<Þœ7W£ü͹óÈÈÈ ##ƒ7çΣOß~F• !?³}2.ŽI“Ë·õèÑÐÐêòÈȱ¬ZµšíÛpqqa@ÿþ|ÿý:Û¯_? o2ãµ™2hP˜º,88…BÁü¨dffÒ¢Es†­yÉ\]õÿ¿½»‹­º¼8þë ‹!sÂ4$q ÜÆ`‘d“– ßÝd¨§0,`|¡Î+—È›“ye 87E/DMÜxYquF/pjILƆšb½²µÓ’îÊÆkù9úù$MÚ>íÓ看ÿ·ÿó9«V¯‰êªª3ftDDŒ7.>Þ·/V­^óçÍ›n¼!î»ÿhkk+»ƒð5³gGûçíqË7D{{{Ì7ÿˆñ«¿uLýÑ£óË/£zÚcNmmÆs_Å¥SætMœ±0š?9í-{âÍESŽº“d㎆(ÔÎ/ê&)Æ Q3÷žS¾kðe#†Ç‡Íÿ>íqàìõ~Ó»qùc»m?Ö¶ÿ«mÈøº-Q9tdì{ë…øüÓf·S OLHNèd/ay‰ ˆŠÀÛööRN¦ŠILz!ïÿ›˜ô2×Lšl¯(:ÇLHÒÄ€41 MLHs6W/Ó¸£¡ÔKÎ2×LšœžCLz¡š¹÷”z ÀY¢«««(— ˆI/åÂE ˜×œ9f@š˜vNĤªzZ©—PÖ.1¼ÔKÊÜ9J«h19ÑÞAoÚsèMà+öLH;ã§wuuÅs›6ÅÖ-[£­½=&L˜³j ѯ_¿ˆˆØ»wolÜøt¼×Ô‡бcÇFíÝsbÀ€ÑÙÙõõëâ¯Ñ§OŸ˜>ý'=š¿ªzZÜyçñâ‹›£µµ5^~isÖ¸rÕêõÝïĵ×^Ûýó[·n‹ìÞ¯¾új÷߈ˆxåå—Šÿ~MžyúéXµje|rð`|oôèX¼ôÑ5jT©—”‰3¾g²yóæhjÚ >ëêׯ¡CñûgþÐ=¾hñ’˜:ujlXÿT<õä“1xð Ø°ac÷ø¦MÏÇÞ÷ÆŠåOÄã¿Y;wîìÑü»švŲÇ~}ÌœlŽšÂ]±mûöh|ýõˆˆhllŒíÙ5…Bw<^yù¥² IDÄk¯½Ï=ÿ|üý½¦˜4yr<ô`]©—”‘¢Æ¤ªzÚ1?÷§?o‰Ù³gŰaÃâ‚ .ˆ;fÎŒ7Þx£{|Åò'âÊ+¯ˆóÎ;/ú÷¯ŒŸÏ˜;ß~»{¼aGC …wÌœ<á|åàðçäüóÏŽŽŽ®(7gü˜ÉÐ!Câá_=Æ=æøÒG—Æm·Þuu ¢ÿþÑÖÖ·ýôgÝナýÄ·GŒˆˆˆýû÷÷hþˆ£ãÒÓ5~ðÁ±uÛ¶xè—Æšß® ÆwGídsœ‹Îø1“ë®».–/_ÍÍÍÑÙÙ~øQ,Yúh÷xGÇ¢²²2úõë---±bÅÊ#~âĉQ_¿.Z[[£µµ5ÖÖ×÷hþì;::â±eËâ¾{ï«®º*æübv,^¼$¾øâ‹ˆˆ0`@477ŸÎSP¶ÎøžIuuUTTTÄ# Åâ’K¾·ß~{÷ø¼¹µ±nÝïbñ’%qá…ƒâúéÓão‡ó¸åæ›cmýº˜swmôíÓ'¦_?=ÞyçÝSž?»ÆU«×DuUUŒ3:""ÆïÛ«V¯‰ùóæÆM7Þ÷Ýÿ@´µµ•ÝAx€ÓUqé”9]g,ŒæOF{ËžxsÑ”£î$Ù¸£! µó‹z‡IJ£qGCÔ̽Ç]ƒx¿éݸüбÇݶkÛÿÕ6d|Ý–¨:2ö½õB|þi³‹ÈÒÄ€41 ÍÛööRN¦ŠILz!grÅ&&½Ì5“&Û+ŠÎ1ÒÄ€41 MLHÒNùl®µËÿ:×@;¥˜jçÝë ŒRL\—À‰8f@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ ib@š˜&&¤‰ i}õÍÆ gz”±£bRQQQŠuPÆŽˆIåБ1¾nK©Ö@™¨:òˆ¯Ú3ùÿ€“éŽÉ¾·^(å:(c—N™ÓUê…Pž>Úº²â¿zM»-vIEND®B`‚wxglade-0.6.8.orig/docs/html/tree_window.png0000644000175000017500000001567312166606326021271 0ustar georgeskgeorgesk‰PNG  IHDR4HQ•rbKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÓ;%Ø ±HIDATxœíÝoˆçðŸÂ,̧H°à–LqKN!»uŽZ9[­¡]7/lãÞ­ íöZs…ØÎ ge—Äk›ÃÞ†»4)×»m^¤»yaì…Ú–_ø*‡:•I´†z%s •¹šŒ  ²0+нíìhþiFI4ßËZ;óÌÌ£±¾û<óïYÚõ³(c~Ÿ;!¢Ÿ¿úi¿kÐk™å“¥Ï²ý®…½“ÇOο9Ïi?V s¹rÞ :pèÊò•®–7þ¾Ø' D”$šÛø9}&Ýr]wï Þ7 À¦Ì͌ǒ‡êAygü—ߘªzX‘ZS7£8m͵®­À`á· î®,_1f¬Ûå5xñO†LòÔÏñÚRÝðûÿœ8:4Óâ-i~ýoS.åmg©ªúõø:=óµgþú¿%"ÓVz·VûÞxçj‹_“Ú\U[êàËã‡^N¤Ïß(=¬ûçdòE)}>[z(ŸøYªº¦æWJ'‘’åÊɳ™h4úöëû¯ç37‹?92A#tåZáêµÆwå>enyÃokž#qkôØÑ¤´5F#$ÿ­²ðþJñsY«êÌщäNI©‘ ­7Þ‚ô¬8sd\Ú«¬)W¯³‰è¿ÿ}ZàhúØ¢ñ=Ȫ2U‰ˆÖ‰F¨ø@Ö7:wz’ˆò÷åäóâɳÛuÚNÔ?+ÇÇÞËM~?^ü¬Ì;´ã/H¢(,.¯è’/HÆw½ ÎÝÛ",¼Ÿ×61¹/>¹'{Z¨ü]É|PÌÜjlW«sæfqêÈ8Ï K—óêš:ud<Æo.ëTg}£N{Õ¸µ ]Y^ñX1iktæHRz.¦¿ëéYtªŒÓÊ•ÔßéOŽ&«Ueþ­¬ü¸jܦé:ÓuúNÓA“RS´;;ô‰«…Uûÿ9CycmY}–©üjaU+ ÅR_ܶ<=±ñ‚'âõLºLîÝ“›=Þ»'§-Uü¬JDñç$">¾mŒˆâÏññmb±XY¹_É},‹blrßøÌá ù±’¹U"âq‘ˆ²wJÚJ,_Šðœ»+§/d/½“¿›9²K+pðÀDr—tãƒÒ¹‹YZoŽn‰Î¾’ŠFù¹7s¥GÕ™MDGE"¾ZUäªâ°¡Ímé_c£1髱ä Rî¾l»N§ é_rY™Ø)¥vÇSß’ÊÉiÓq‘ˆJ+ÚÑQQŠ*ZÐôá]+÷Ê4B_Žñ“ûƧO”UÓç³¥GÕéÓûÆu>øýñÜGea„fOh¯õeêlܨí^5í"mC+ÆóÑÙWöÅNžÉÎüüF¥¢¸ÿOÙ®ÜTI­ÌÞ½ñâç²( S‡'Œ³N׿¬T#uCˉú,SãÛòªª~šoºáçÓü§Në§ÍprDœ×–Sëý&w'µ¥J+DßÇb±-B¥¢HÛbÒ³1á)Ê.G‹ËyE¡é$&ÆÅ…Ë+DÄGª®©ÄQt”^Ô¾´uêµ*=ªd>,ªDªJŠBѨ Hî#¢Ì­B©\QjÂ;EA Ü½r©\Yù‹LDÏG‰£“g3'™i¬ÙúeØÆ)é7³W¯m×é´!ýKU)ûa)s»˜ù TYSœ6åõ@%ÇÇ ŸWŒ§ÁçÞÊ.\ÎÓ:ŶÄÑ䉈––‹¥G•…Ëy"šü®d¬óÜ[٥弲N4²ùZ[Ö©ÎÆÚîUó.òS±‰¢ðݽW’WTý„£selWn»gæ“[x?ODñíMŸ›é_¦ªùc]Ûøj9QŸe*S³Ìêdýæ³µÞZNm®ñlm©T‰oÇ·W +êš6*ÇÇdY!•xŽW×èî'rj·(ÿ])}^á9^¯8«T•‰íÒÌÚ”™_Ü0n(¾Mœùqœç…rYR¾ll=ˆHU7«ÊsüØÓ1"Ú¿WÚ¿WÒ&ŽÅb<çé,™ù-¯“VyÛuj»Í}CÙÛ%žã³·K®û“'"žoìñçÅ•ûòfáuR׈çx¥FG<ÇÇ¢UªŠ¶WµýÐT^Û!5ÚÜ9µÆ¯]§cܨí^µÙEž+¦mTQÍëqûŸ²¬ÜvÏP´ µž¾ÁøA5Íro]fY˸¬ê¥o¿dœøÍüæŸÿôg§M4 yl9µ¹Æ2…Ï«’Kí•ò÷ʪªLŒ‹ÉRñAY›Rß…ħ…äN1÷‰L5*+‰xlïnéêµBî“Rî“ÒÂü~íF%£éÃñ/›ÍªªòësûõéŠB‚@±-‚ö_¨©V"ÊÞ)-^.¸ÔßÛu¦vKl¨ú¸J‹m*U…ç…D<ö»÷OQ¥ªÄžÄQA~¬4òP±?\±Ù–Ý1mÔv¯záT1uM!"1ªýx^p©Œ§=£µ~Ö=`š®mTUjþ š–Ò?ÏÌþÑ:ÑJŸeÊ›ÓRjMýNê;ÆMh?¾ôí—Œ[4jº ÁoË©/ý°T!’DQ(.W´•ˆ_®Þ¬h~rd\.+ —WÒÇ“S&ò²ªª\½VLlKîß'‰£üJ±BÔ¸…°é×…Ö!¡ä‹cŸ"¢™ã7¨ùƒjú¿PT¯¿æZ–·¥¨ÊõÌõLþàzæºVÀô£•Þ­¨¹åœ{#¢ÖˆçHÿ~îÑ7ˆ8šÝ:«•Ñ–"¢Ò£FªËTeãТôHå9!ùâXâ¹Ø¥ÿÈËe5{GNí§Ä/åÇêÜ[ùƒû¤øvqb\$¢JEÑÑ+ÇsÂÕåâÔáøôáDîc9{[Ní'÷ÅÞ_É\+J£ãñgcW— ÒÖ˜ÀÏ T£ùß侟Ü# ‚T©(™ÿ)ñœÝ"4 8³ÎmL±[§Ó†\Öo«ôP-•”ÉÝRþ^y׸X|P6­Ä´7rwË<'¤þi,}ÉyÜtY¡{ã„P7´ð2¨1ÚÓiËée,ÌNÆÑì ù ê(œîc”2ŽföV×ÜÆ€—hK¡ÂÛ­ šPèžrâ4à¥Çò]¯„UwÃÙûë%îœÎñxð²í±-`hOÞq4m;·È$thºµ.÷â19„n`=œ³§fŸüÊ“ý®@°Ná)í„.¥0 á` À(„€Q! §û­v¸XÃúÙZ¿JŸ•l§/¼» ½WÛ ï.ð<ßÕŠø¢–“jn3UUíU=< Q8££Q—¹h95! gõqÕe.ZN`Íps®Ó» îEœ ð[|·œ¶—ùU¨£ቶáÀJ8G3òdÄåÀ’çùH$²ùŽõ’Q­nm ýn$ã VÂIAŒ£Y_wû ºRm/¥8 ½g8ÓX²e%M%­ÃsšæZ§¸?Ž4 †Â—K)ÑhÔ©€~¡ÅÈ66dr§’VNá’] ÝÇìl¹!BP\˜NUÝN¹ô‡]†Mp/驤—àyÙJ½^7§ƒ¨§-g·ÇÑd¤ã(ÕÖ¹¶mrjìé]8{0Žf'zvÓ©[ëRØœÃvÌÙö¥—ëœÞ›/ïÇœ¾fµœ Ci¨Âq¼”¢]ÆŒD"<Ï7rȵ¸¡Ïô‡R/iSÿæs³íÁ‰‘;‡Cáì|ÍN.¥Äb1›ZÊ; éý«8^²]н7Š•p5ŽfÛO¥T×Ìçr;éIö`°LŒÇ9ôX g/¸vb­s;éö $ÈáÐ S8ý¿Wú(D7!ðœÛÅ<2¬¶–ÓåRŠv’¶K)}1Tát¹”BDÄ9\‡luM /†*œî—RKˆŽ9  À(„€Q'£N{‘¿§ö¨uð;}ºiäK “NÎ&÷бž!(ìvk½Œ…Ù û‘8ócµÆ”6þüIà%!„Ø gï¡Õþ’Šò¥BÔ¼cüì$ëßhpæ\ [kÀEF"ÖãÌΛ8üÑ{ð‹Ý–³Ç¬9ìÏûÉ4òÞZÅÄ–àálb¾ø¡7¡5ŠŒD\žu2ÓøÝes¶SZV†ÂIäåzIo÷†½B8iã<‘Ý`%ͽ\÷Æ3@È!N5!ÔtÛÀH¿» ðésy#A¡å` À(„€Q8æìÈ€ÞÙƒ³ÁáìÔä‘ß÷» þdÞÿa¿«ž [ À¨ð¶œé×Ò­ 9˜;ßéáh)¼á$¢sε±Ôja5ðšX…½[[÷¯ßU†°{8}q97{ciÚתü–wZÄËzÚØ° ÔÝZ~‡&ab9ÐÐr@Ë€ž„KÓÚ—q®±°©¼Ó:­+±~w·jqÿÔ¢Ïw¬@8"ô)…bÁã ÎZ´ï7–¦µHìŸZÔò£¿0ÎÕËÛ²]‰q­@»ïºµDD‘Hdµ°šˆ'´@jÚ‰õz=ýZºó.®)c~—õ8† »áìöИFzöñ„iâÜù9¿W\p¤`7œÝ3{«)üÞ%kmÖô^(º£àŽ9‰6ºµ_ÆÔÏÜè4úZ „»-'#¼ßå§ŸÅÑãäÞHº´¢N+AÃ*'Qó²:_ƒÊ3cÊí-3f-`l~]ŠyY „³Á”ÀÞÜ`Ûem#KA­˜‚púxbƒÊr8”BÎÕÂj¡Xèw-ì…7œx&‡K)ŒB8ÞnmP0^t ÂÙ‘!x昅n-£NF!œŒB8íµþ[×]†pÚˆŒD¨†|BŸ!œŽxâ½vVÛû“Ü-KZÇ:‚a…pšéŸ{•TÖOm4# ò9ôpÓ‚3|o‹Óƒ ÚtãD_Œz/Ã-§Q­ñÒoãéÔ¸éÓõ‰4ƒÃ1æ5¸C8›X7¿œ– 0KHfH°Û­íöИö£ûqÄóçj)~ÃàéÛEÌ`7œÝÓ*‰GÊ— QóŽñ³“Œái™=¿1C2CÝZŽˆ(2±gv~j4¨k-ì¶œ=ÖdÍa—xÞOƳ;Úk­­Ó§ëMŸ©¤×zbŒVt¸!œMÌ?ô&´F‘‘H}Ý1 Æ­¯ß]6g;Åû\2'‘—ë%½ÝO¶½\$3lÎÆy ¢Ík››š{¹îg€C œ""â ·o‰àwô>}äÔö¦‘p‚–€Q'£NF!œŒB8…p0*¼—R¼ÿ=y+ü…2èð†“ˆÎ]8ׯR«…ÕÀk`önmÝ¿~WÂ"ìáôÅå©Ë6 dëJsˆ!œö†ãÓŒ¡4ÂísoVÏØX™R¡Ïj96‚u%ÖïîÐ hgƒµûW(&h97íHìØ‘Ø¡¿6½ðÂÔ|Y_ëßÝGÓ´–t4+„³aGbÇjauµ°jL£6Ñã¬#!XéOZ»¦é}…Ö x¬-°átä+™Ôï§=‘ÌáÃî1g·‡Æl9ºŸÖŠÄßC2‡»áìöИ^ D>‘ÌaÅn8{L?Úl;Š.!ÁEh¹ÉKýµ÷¬šþ®‰iŠõLÙòi¯ Äø—C á †Ó€—Öñ,=Žp‰ñ/áÿ2lÂκW9 ›P‡çi€e¡'Ú"`î` À(„€Q'£NF!œŒB8…pú†[ 7B}ahL`ZÎ``hL\Ø[Î!€¡1‡ZÎM˜‚–³A+È8hPCc’kó¥ z`*æÔôyY¡që„ ´œŽkhL_#ÜÂ@`·åÄИrŒ†“…q1i@ò‰“@ÊÑpö†ÆÖ œ›thÌÎGÖ6!œÁèãИ^ À B8†Æ ›°‡s€î•EÃ&ÔáÄy`Y¨Ã‰¶X†;„…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(„€Q'£NF!œŒB8…p0 á` À(Îô³,Ë}©˜4…sþâ|¿ê&pŠ¢xéW—ü.|òøÉ6–ƒÎÓÑgöv¶íU ' ओdá„£NF!œŒŠщWNô»ÐdþÍyÛÃ÷»`ÝÆÿ?`4º4î.ÄJIEND®B`‚wxglade-0.6.8.orig/docs/html/preview_window.png0000644000175000017500000000701112166606326021776 0ustar georgeskgeorgesk‰PNG  IHDR¼|\ÃMHbKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÓÈ%"ê –IDATxœíœ_h׽ǿ 8˜v„<Á½xU¢MRªMRªíM©íøÁy°]÷r㆒*/‰œ–ç^Z»½pmaJ®Ƚº}0NŠ$h¹Ôí:ÔéÚzW[[“17³p³Ð…s@êìF³³ÿfVZ­äý}0ÖÙs~gÎoÏ|çÌofg~˜ø}šÕÕUeò»ù¿q«ÓžëÌÏž2¿HwÚ‹ÚœzýTOOâ~¸·]½ìN,Ëê´ (‹@ú£_¨}:À H1»$Ƙä`¶”Óz¥L:`Åå|êð™ºþ`“¹™ o|ÃíE´‰ù+ó!-ÇŽŒm½‡âÿ«©,5̙©õ2ö˜Â¸(ÌØ#™Â8ƒº‹I)™Â®}ä“Ѧޟjl0=;íß÷í¶w)ïv¦0vQÞøL]åǨÉgdÿoK@ïÓe´¿²˜ªj½šì‘êªn¯-æÌ›¡°·ÏÌlýÐ!j|Ón{Ö 1c7‡¦¬e‹Å’ p ì’­)Ì’ eÓ­OOt£¥5ÿÄÔ¥tîv!ª—AœæCo×í±49 #aìÅúø¿˜þÊó?5 íâû™ô§y·füåÔÉ—+z:GrÐÿhÍ–ûÿw¿¦=€þGûý­¼Ó )@ ÖË…Ua€„Âᦨ€ä ¤[†Âf¥YÁÙwÒPXòq=5bŒ¿œúáƉ·Ï¥=‡Û˦qæÍC\ÁØ*qñRîü¿¥^::”Y°¤”ñýzê9#ÐQ†88CÚ×l’R>öOè´ÿË¿} ð±ïôTþ[( Î8ëeLÊ"sËÅ¢ÍzUÆóõªÀØ­¦F¦.­ÿù¿Zîÿ©CÓ¸ÛëìÛdo[ÉAýÔ™yc¯~òè±[³Kbæ£|úÓüÄ+©Ä~þÝLnÁ0zd(õMãÕŸÎüϯŽsÇÇ/¨î5zxhìðÀé_~lÞ+Ž¿œL>mœþeÚ¼gM¼’*–d6gê{Ôô53Ìžðû9=›;ybXëåSfÝUÁ­Ÿ¿’éD²X“來å"¿{^ùØÑ$ç0ý¿Ç]ßÜ!¬%+}ÝL=g;ÿ`67~b8› ž,„#ÜÂ×¾îUÞY¼SÏmÏÞoãöõšöw︮\¼î5í<äM‘{¥=´Ç÷Á04»d– æ’)‹¶½l¹eQ’V¡\†³Ökퟱ[Ÿx%uöÍC¢ä5•7Θ:z À4m·)Ö§{´äFæ¶¥öªo½–RUvöBÆ\*žüABíÓÓ7L©aõO=ednüÛ¬Ù+ÿE@ükÀâûbâ_‹,¾OÏçíBÉAã¿~1vðÀcjÀß¿õ9qý<þâpn¡€‡1z8çïZºÎ½˜¨îë•ç¯,Š`§~ž¶–*æíòì¢8ôüÀø‰”Úǧ>Ìö\£i¥×°ñ×Ô´—RÞÊVÜཕ½Uoû\=A²Ì‚ ©"ùÄ€n,ËR¦íÒ˜¦‹Å¸{Ô°õÞÆnmô@<1¨ü©9þÖÇÅ’\–Æå÷Ël–%.^Êùã¨ÓÒ²$SÏœ#}³`ìÜç,ñ¸žTÓ7M!ÔY/3bš¶‹_ûÌ\ï« ñ”^Ý+sÓ߯å>×´^nÛÂØ§_hüdïZ²$O_HÇ÷ëÇÇGÿy`æ‹éëõWŸŸgßI‹2õ¬¡õrýä{ÆxüP|¿^V–‹% P`ì@«”òƒÙìÉc‰ä°~ù7‹ÅR•35cšŽSß&ü¦RWO¼W|NsckÙ’%! á@Å‚% !am®0é^x`Œˆ'†ôlκvÕ”WU+8ÿßYÅ¢t§l½u` ‹íÒ1”Ïè1Mc°r VrXO=eè{4ë+a/ ¯o½^€ešv|Ÿ>´ß^¼gË’ŒïU­x̲Ö3ïÚÓWÌñÚè÷¤@æfEpêá÷S–À&p¥Ò²œW|ë0eÌMëä1H_7« /' šªmlê™o=ã¯|òOþùO®7DETb—Øüu€¦Šñ£å•ƶ,ÔZick£Š‹¿ÎêW´ÑÆùŸ¥ÒŸšóWM»´~:tcš‹@úºyù7‹þúÌgfrXO뱘6ó»Å½ï CKÙ…‚”"1¤'Ÿ2ò-_²Å÷ëcŒXŸ6ÿÉbúzAÊÚ§íðh½€m·£õrΕp[Yÿ2Ó\»TücúÕ• ì:¨×K:ò;©ïø‡p?>ó­gü#ú©8=1&“ƒã°‹6LHRGÊRQ¢dî Æ¸ +$g-Û/ÙzL=`¼õæð©OWRoüL®0ú½Ôs†]Bá+›iLþ]fo[ù{¶m ÃÐär…Àš_¯×=Ó ]çùYÛ&}Ÿ¹bCAbPéÅÄü'‹éë9éFyÍ|k\6öjɧu™…²{R ®ñã/¸•g/K‚ïâ‰A}q©(Ku”ZËQÖ ìk6 )ææç^8øÂÜüœkøX×M¦ppX~I0pÖ+Oj_ ŠËMUU((, UÕcPe­—{YN]Êë}ÌßTmlr0ù^fôpüà· Î Ûó0ݦÜB15Âó¶n³N/s©|<–¤@¹l.I¦pkI¾ýáÈÆ^U»]»ü0N¿žÄ ²9ëÚUË­Ÿÿ¤püch0öÁ¬ùÒѾ6K3WÍcGÆÿ5qþ½¬Yg™¨íRôû4s¿«×T¯rî·sþÖÀÇmK•qéθp„t$À„\/¯`-—geü­º?žW,E€µ,/þ:Wm6}%?}%_¯cÍ^BÊñŸ¬ÛøËvu˜Y ¿Ûþá>c¥ÆÌÜ037Ì5ûõÛ˜Ù…Bv¡î]ÍzégÅ-°w©¸¹Çã½ÐÎp²Td “R@ánY8’I)ÉgKî°msÚ<áSÜ{—²h¸ù»ù³g^À¦õ­…º¤#Ëe7ŽY3NhaÄ„™9kóÖÆŽŒ~[Ÿ?~ãVä=ç@4bâ‰És““&•@m§"¶9“ç&½òC ì¢&$"2$"2$"2ô”oXÒW»ë-ŸÔó©zM$š|ÿ_¾ßi¶ˆÕÕÕÏ“h¢±ººÚiÚNÓGÍ›Ä4ýUxõa†¯iV]rkÄ6¡ùJsÿ~§ÒkV†§¿¿ƒ[ :H‹WO%Çÿ±^“Ÿû÷ï×[]KZÍ!Ûíf.¹½eÃ-x‚p+#­(Þªrë]qø›jÚ“€ÚMóÓ“„y·³~;ˆ‡¼{îI ‰ð<„îxF„ØD(¦!"COîEc›' ßH4 ó¸ ‰&,©çS´Ì¸PLCD†DCD†DCD†DCD†DCD†DCD†DCD†DCD†DCD†î‡…òÓxh"@ùi\H4Ñè†ß,7!?MËcSr𕤒Nëùiª³ÂPrš.¡•˜&ðš~ॖš’ÓÔ+{/üVXÓ ¢}´²Ò4}¿:̪—JN³Shñê©æ.§ä4]Â&œž¼zJNÓ%lÚÕ%§éZɹW3‹ %§é6šŸõUJNó B¿r‘!Ñ‘!Ñ‘!Ñ‘!Ñ‘!Ñ‘!Ñ‘¡'÷¢A‰#@¢‰D7<ëMX(?Å4DdH4DdH4Dd*bšn{‰°) Þ2ìf*DÓ=o†¡ñ[†ÝLðꉞG!šB1   ™Fw„u]ß2?¶=== Bº®šÆSÑägº|ðC³áB§§2tÊ£éThˆÈhˆÈhˆÈl‹çiªßüõê#½ä»ý©÷MÛ1Pû¶ßyÑ„Tƃ¡˜ãè°hª'®^Þš:¿5¿©¿5PÈÿÕÀ²^eûèüJÓ”@1iœ7®f¡ie[Ùîp7$ž “š#jk[Ùî+M—¤_Ü౱ŇÖvK ¹Bw-ä °Å3ÓáÓSuµzâØÄ\k¡æ7ÝÈC&„o_i³Ùà ÙéëM½o>o\ÍŒq5+ÛJçEƒ(‘àÎUŒKøtt³Ê5Ýl['j»_=Û   ™æ0=Òæ‡fEÓÓÓ³e~lh6<‰f§_ßn.4Ó‘!Ñ‘!Ñ‘©ˆi(!† ÑœzýT§ü v«­2ñÚDË}‰N±‘½6ñÚ¼•&}­õ{Vô†óNd#{œa"2$"2$"2=Üè† Â0ya{_ˆuÚ b'qgñÎ?ßo³ã7“"öIEND®B`‚wxglade-0.6.8.orig/docs/html/example_variableassigment.png0000644000175000017500000002740712166606326024154 0ustar georgeskgeorgesk‰PNG  IHDRz ÀsRGB®Îé pHYsÄÄ•+ IDATxÚíy|L×ûÇßw²'"{$ÖÐZŠAµ¿ÒDì¥H,ýêF{íªj+µ/µµJ7T‹Ú×–ªZJÕE J Ùw‘D2™ùý™I&DD<ï×+¯Ìœsï¹Ïóœs?÷ÜçÞ¹Wá.ÕÚ Ö"‚ ”®ý¾D0Ïyß·gHTAÊA{í÷%Š’+ò7“oITAÊ7ÿDzBxÎŒ ûNšDE¡ rOè3±Ðk²¹ʤ(´Ùê"¯®¨Ì°ròľbP™IÏ BY¥¸µ¢´kO Ø—gF;_¥Å”—ñ»ûùà÷é§&oüÀdùÝËû§Eÿ‹-žM0·.WdgÔ©$„"åFvjÈÎ e”âÖŠÒ®=%aŸNè Iü€Éw?O&OžlòÆ'OžÌžó<óÿâï±¼m*`icÿPÍYØ–ÏièQØ*Bé ¸µ¢´kO اzEQŠßþø¿OÛåiÞ •#vôuÉWöÚ·ñFNÌžÚý_“_àåÉ‹íBÙú´¢¨í ¨ ¶gHs Ó G¥=ÙgHÕd_3z???¸Ož<ÙD¡ŸÌÝŒ¾þŒ^eV¤£–«úñæ• ÅØQëð§/ê}ÏTkˆLºÃžà8Ö‰ +ûÉøño®ͧ5X_×úîTy"wââ°ÝX| ‹[Iõ[.ËŽ² ôJqµ£(ÜÞýTö<*wôu¡sAßžçUû ÎÑkÚƒ{ŸU*î·aÛ9Fwù.õ ½ºèêôP© =ªöµ;kz´j@_ÿ*x”Ó2gwOÒsž³ºÁ…Ì{Wšvœ¦Öa8›©q4K#IS®ÔÙìéhEëú.´©ïÂ;ËÎæ«w6K-6ÛïOaåšæŸç9Ëë|;¶»A;V xžßÏų÷\<‘IwDÑa@+´•ÑöÞ[vÆèªË4@QÐ_Ïí).»|¯ÓÇí}]ô¾çÚ^ûò}ñ©|}àç7™ V:æiÞ c™(Wõ Ì«˜T§(f…Úêlv‹(µ±©jÖì=K³ºUð«çÆÚ?ήvçÐĦ,Ø}7ÿÏ·ò–´˜z•MÜ h⎇ƒÑÉ™l=æÑhî!ß]wÚ¶«¼õTr¶&"ñ?bÇ©Ø{v¯ù¸Ñ­i*9Y“’ÉÆãÑl ŠÑl°#¯g¹‚Ñ|ê‰<Ë¿@ï™[AQP¥ÐmÔ«TŽA­+óL[,ÌÎ\¿Åº£Ñû7¹ØÆ©³þui]ß™ú•Ëq'KÃÉã¨aÅ•,O½e×{–Á/øàédk0n¹1Éõùþ²ÜÏ÷ÇÇX9P¤~±ý*ï4÷¤‚ƒÿŦ3×5ÎÞH59‰{½qèhv[wP»ŸÁ»-<éï_™ó7n±ç\ûCI¸%âžw~X€VµœýÄp{ ÕÜú¼ë™¢=ÅéoÀw lùÀYoR ðþ²3:ÛUü-$uS ¨AE'+l âÒ‘xy:òV³:„üCªÆæ¡úºCÚÔs¦qu{2ÕZN^Žã‹­¹xåu&v*åUéÜÒÚéÖñ®SYkaN–Á¸åžHÖµ ×ó™»e-¦©84¡q¾ø+¿Uî/¸›Ü¯-k˜1zå?øÕ´fÀk>Lì\…>Ë‚I×Z™“h«Þ8̽0iÓØÝ I g¼ëx1¨Ue†µ«ÊÉ«)ü~>‘]gâEå ÑŠ¢·£2Ú^AºóàÚS¼þ~ŸÀæ÷uß?ø:g&Ÿ`^%ß¡¡ ûTù¼Êû÷ð‡*ÝŸr÷ôÄPó ˜^§R¶ÕÀJÎö– n›sê|*ôæJ6ʽ{û÷>Šƒ:štw´6Î9j :…úN;Žþ›#êÝ©`ž ·ßþmÆ bRµ¬ÝÀë/VÀÍ<…îMÝ8ø÷?™ÊÎã9m¾Pw‹d½¶î·#¯)Z;21ÇÑìž:™¥àh–jÒ6ìmÌQgkФšÑfžÄ¢G¨l‹…Jc0އ&4Öû3ïq¯yÑ´FyއF1nÙ¯¬ÙqóaW¹£Ör[cC’¦Å\Ï×N I77­V{w6œª·n®ß…Åçþò.ÝLî×ý‡âÉ¡ q9©(g;žµŒÀLÉ6>îŠ0°¯e8òÇ…d¾ÙvŒÉËvp&,œ¦5÷šŽf·MßFþ3¤ôwW+ŒiBÁ]X$íyDþæy€ïú7 Ñ¢Jþ‹Å>£××y•I§c ŠÉuŠRøQuöè>@ÎÅØèäLÖºLЉSd`¥·nêí nkÝIÒ:žm‹›ƒ5Ùi)¤).DÞvÈ{[<ÍâIÒ:èÖMJ¾MºÖ‘[Øs*Ñ6'ÍäPŽJf±¤hËSÑ)g8¹o=Ûܜ쩨Š#9Ï)þýväõ=AãD’Ö>_LT&mãëý míɨ·Û£Ñj¹•Æ·ûÃù7< +E‹Âsá×UWÏW>kçuº>oÅ u<ðy¶=g®ÄpäB GþM%^mEæhQô´¯°¸éû©ÒCwý6%>yË=,Mî×”ÔtÒw³íïŽ7…rÜÆN•É-­eÑÆîèÍãÃs'jÆŽÛØPÙ1'ŸœŠµ’‰•’IÜ­,<-™±lÑ·²u¶”SÒ±1Ó`•eÔŽ|‰BCƒQÁ¤ml?@hÈY¼+hyÆ« ›{3¾suþ÷eiØlú•™ghbqKrltV£êI÷ ñ¯g §j¹;øÔ©†w ëÚYþþ7…I[®åk»°¸i´ º;ËA¥àfgi ¦Å'·¼(ý ¬±Í‰Mž!g¦h o§pµ×­7% /=Sk ¡·øùà%Î]¼JfZ ŠVKØ*édR^.ÆÞêõï:ºZω.Æ*F/Æ5ucŠö< ûŒ¢äø—[¾á='ãþ>lŽ~òdÃLÙ 4Ìùü©×§†gôFn!J²0|1Ä)+\W§˜˜‡Ê»s¥ÞÍ kQÈÀš )Øs«ûN­ÍÐ’cÛ®³Iôõ­€oÓz\8”HÀ‹9} ­¢B•ÇŽ~MÝuEcà ÿJ9)”“ahQa¦ÀÆ x†´ö¤£_Vî Ã,jVr¦m“êÌ[ 3FíHNWã`c޳£=J¼Jo›»¼¢¨LÚÆô€êlçGJ¡Ý¯uÎ7Í?#Ì=dç®=‡‹*™WêWâ{ïZD§¨Yµÿ2Á§.r´y‚xöâ5>íYWG{boe±bOçÎþËm­EÅÆ“ñXdDÓ©Iefôk…³7ÒX{ü&YŠÉyÒ÷Ûñý¡ú5waÌ9e}gŸ3¤ &mcgp"ý[VäYÏçÈÊÖrþzüykU&¶š R0üÓë(­{þÛk „=Òµ6Äi±%ƒ¸¤Û\;z_]¤‚™š$¹­µ19nsvÝd\[gz´™W’2Xs"Ï;éùm,>ÆÊ‹Ò¯÷÷…ñ²üü¸¾~jkTo=;ú,¿L=³KhQÈÒZ‰iŠ ·4¶db…ÅhœŸ6¡¿ß7¤ù&Æ÷iF®Vw{%é¯JQH²Ð¿»&o©ö•`޾à¬[²™½b¤Mc¶úÍ ¡±Y0wwLc3#cËi´ðýÑdö½€ê™Z 4(h´6$ã@&Öº6Nž¿ÂïgãQ©­‚™¢F£Ø‘¨u$kEÅö5'CbGY˜“…YZ ´Z3Ê)éFíØ~:‰³g‚qSÅ“…Ï™Yª©ipù¶q슊ðÿ®b¯MAQ´(Š síÒ´ås~5XL³G-*nSŽÛÚrÄ‘-éØiocFÎ6ïÙžU`ÜÎGdðÑÿ੊F£UHÅž7Ï]¢’*"'©(Fãc¬Ü”~5[SÇSÞqU[uùnú, ²HÇš:fV„iž Zë†Rµ¶d`¢ïöq5¢Àø]­(îöJÚ_Së ²¯À}ÞÇä|6béi`åÝuþËYçÀÐñõ{GG3sÔYw°°´~à€de¦£˜YxT½¡õÄŽ´<³°¢-—F9µqЦbIZ CeCbv92ý[ì’'ÐdcÍÀŠ4lHÆ^·\v„k+Q^¹… wPÈF­X¦Ø‘©µ£vDáN&VXjï  ÅAI!‡|Ë›²x­™¨°ã*­†,­5·°']U´Å//Ù˜s {na¯7sm¿­”+0nqŠYsìTwÐhµÜÁ’›ZO¬ÈÔùm,>ÆÊMéWC}aêxÒ¥"qÀŽ4õÎØÐÙ‹¨za)ëbÖŠ’ÒžÒâ¯ÁƒIEG>ÒÎ˼‹…¢àQùY,À¡¬Ìt"o\&K«`iïúØáѵ;ÿG.hj“Œƒì™O¹ýnp&?/LTе¢´kÏ£´/:h+é á÷„þzLÔ#í<-²RQgÜí<ˆ@Qanm‡¥óc¨™r K2¹ ­#BÿQ[¹h´.L[KTJµ¢´kÏ£´/êÄýwÆ>jñTPai½Û?oR;îþ¸y6þÓBN9ýn€œÔŒ£©jEiמ’°/ßÓ+Ób®ÈH+„ÿîv$Þýž®~7„Œ¡ô`ë^ðÐçŠüò^nÔõn(‘*„àÓAJ%ï­½¢'öù~-S×»¡ˆ˜ ÔkЈógNI A(õ˜KŠÎ¡ƒû(ïP¶/Ħ$'‹âãc·]¡¬œ:q¬Lû×¹G/¶oX+>ŠÕv9s~xä–Á AAAâ£ø(¶‹Ð ‚ "ô‚ ‚½ ‚ B/‚ ˆÐ ‚ "ôB©gàÐéSáðP÷ч‡ß`ùÊ•“žžNõÕù_ž´hÑ\"+Üé—.^ „'eF3â&£ÇŒ¡^ݺ,]²„m[63dÐ ö< Q-å³™â²kÌø‰¨Õú/Öþú»ïõ¾g©ÕŒ7‘[©©%*òÅûCGü+kc(*:†¯¿_Áè±ãùpÄhfΛÏ?§ÏÈŽü4ÏèWý¸š.;Ó½[ ®¬N:Lš0áÞNž•Åwß/çÀÁƒøùúòÁûïaaa@Ûöòá‡lܸ‘ظ8*UªÄ°¡Cˆ¸ÁÚŸ×Ã3Ï<Ãè‘£¨R¥ò¯cŠC‡ aݺu$&%òÌ3Ï0bØ0¼¼¼d„@ ¯êŸ=‡O£œ‡àÝNKãÌÙó¤Þ¾M9»œ—³Ÿ>LêÕ±/Wî‰öµ¬Ÿ‰ÄÄÆ²`ñ—´iåOÀ®”··çÆ›ìÙ·Ÿ† d°?­BúôiÞ}çí—Y³v-×®]cÉ‹˜=wkþ™wÞ¾·ÞñãÇ™5cNÎNlÙº• 'ÑÀÛ›™Ó§âè”S¶è‹ÅÌ›3ç×1ÅŽ“'ƒ˜;wŽlÜ´™E‹¿`ÁüÏYà£ccÙ¶c'/^F£ÑP»VMÞìõ:åì옿è ^iñ2M||tË'$&2{þB¦Œ‹¹…›·íää?ÿÐØÇ‡À.0777š"É-Ë!æþ{±Ù 9zT'ôW®\E«ÕråêU¼ëç¼(ûè±ã´hÞ<Ÿ]ÙÙÙlؼ… “§033£•¿Ÿ^Ûjµš ›·pòŸÓºú-ÛvèÖ×jµìÚ³—#%==†ÞÞô숕¥e±úX·ÓÒ˜-¨Ï„RšºIIIÁÙ¥à×jý±ÿÀÕÕWWWÀû÷ë-3bø0<+zbmmM`@iii :Ï{ea¡aµŽ)v ýp*`mmMîݸ|ùò# ü·ß¯Ä¯ysfNÌŒ)“ptpdëö´oÛ–_wíA›çm3¿îÚC+ßW°¶±aמ߉ŒŠbìG£ûÑ(nFF°{ÏÞ"ÍL—.^ðÐè]ï9®…‡sëV*ÿ^ùºujóï¿WHJNæFD$ÞõžË·îî=¿Ç„OÆ0ö£Qœ¿ªW¿ë·=Ä'$2qÜÆ}<а0ý·;ýqà —.]føAL<µFÍÎ_v»agk‹O£þëˆ^ùá#GhÚØ[›íÌåBèF ý¹³¦Sï¹:¬Y¿¡@?Vü¸šmÛ2ÎLFÂÕ«×Ú—°‹išgbaˆÂÆ]a}jJ,„R&ôåË—'!>®ÀeâãðôðÔ}¯X±ñqúë8;;ë>[Y弤ÙÉÙI¯ìNfæC­cŠ…m³¸™0ö#jÕª‰……Ö66t~íUB.\ îsµ±´¶"èîÌ)&6–Ð ø½Ò"çŒ&è$=»uÅÉÑ'G^ àXÐÉ’[ZZ’••U -ú¾Ï®ß~cç®ÝØÙÚѳ[õê>÷Ðg'9ãÊÅè2…»Âú´¤ûL(¡çí79ú#,-,yå•888påÊÖmØ » ëïçËÒ¥Ë=j$_-û?¿w²´Ø¡—ºY¹ŠŽíÛÒ÷½>ØX[“ž‘Áè±ãï¥Eê×gû/»Ø¶ã®\ýÞo½¡«spt ..Obcbqp¼÷¾R ss233u†”””G¶sU©T€¿§zÕjºÜî?caa¡«¿GG=âbãî«w .> î9õ÷Ÿ :91dP\òœÝ=.ñ÷óå—_wÓ¤Q#öZ­–ó!XµægfO›òP>Ô®U‹“§NÑ®Mk£Ë6î ëÓ‡…ðR7•*Vbî¬Ùœ=w޾ýÐ% /–|EKß{úF¯7¨R¥ ƒ‡ eð¡T«Z•^ÿëUâN–;ò’™™‰µµ V––$$$²úçuùvðíÚ°ç}thß³<é¦>>¬ß´•Ĥd“’Y¿y /4ntOªVá÷}û¹“™I\|<«Þ ×v9;;"££‹Í—›5cëŽÔªù,µž}–»vóR³Œ®óB6nÞJRr2IÉɬ߼U¯¾©·l%9%™ä”d6nѯ÷mñü´v=‘ÑÑdggÉ÷+V=2 ¢nÚ¤ßÉàÀ¡CXYZQ¥r%“í, C~|¿òG"£¢Ðh49c…‡?¨uzµûâýILJF­Vóßµë|³|…Éã®°>}ØXaFŸ+(ŸNšh´ÞÒÒ‚Áƒ2xÐ@ƒõ{vï*rÙƒ¬S\v<†îƒ^ºxo÷ú·låÛ+q,_ž6­Zrêt°þQXQáîæÆ‹M›ê•whß–Í[·3knÎ]A>Ò¾]Û{¶ž=øiÝz~Û³—òåíiÛºÁçÎéêÛ¶iÅÜù IOÏ(–‹•M›ø°iÛvjÞúš5Ÿ!K­¦iã÷:´mÆÍ[˜:c6fæf´öoIhX˜žë7næ³é9õ~-ZzñÞr¿W^AQT|óÝrââpww£sÇÌGcý˜K+?_Vÿ¼žö×[¦0; à ¼ëñõw+HHHÀãï½óæCûçîæÆð!ƒØ¾ã~Ù½›ÌÌ,*W®DÛVþ&»Âúôac!<8Jµ6ƒµ¾oÏ <.–´˜+ÙFÞ[‡îgÀБü­=K¿ùŽ&}hÚØ§Ä} â³ÙŸ—š7ÝŒˆ`Ù·Ë™úé„2ëãÓÐb»¼aªè¼·6[÷DÛHzB¸<ë¦4¢Õj9|äoâhâÓè©Ã†Í[HII!>!‘›·ÑÀ»¾ A(éÔðh4l$.ÎÎô{¯ÏS}W‚«‹3³æÍGMƒçëÓ¹ã«28A„¾l þÊ¡¥¯/-}}%‚ðHêFA„^A¡ADèA„ǃÜGÿÔõn(A¡t‰º¢Ðlì½ûèå®›‡@ˆ‚ < HêF¡Œpèà~zA™Ñ ‚ eÉÑ—áÓ5AÊ>-|[ŠÐ?- :R‚ OZ­Ö¤›BDèËX§ ‚ðtP”»þ$G/‚PÆ¡A¡žD<+¸IA¡A¡ÏCÛöødüƒüÚ¶—ü> gã,Á³‚›îO„˜Ñ—··gûŽ5¡ÄˆŒŽ%2:V!%%ôC‡|Èöí;¿at™7oòÙ´itëÑ“€ÀnLùl*É))z³ÿ;¡wŸwyµÓkôí?€sçϳgÏï¼ûÞtêÜ™a#FèmC£Ñ°zÍZÞé݇Àî=ø|þ222¤÷ aÉ—_ð|½çx®v-Æ}2–¬¬L“fìyÿT™™É¤ ãñ®_ïúu™4a<™™úÛYõÃJš6öÁ«je:½ÚÐÐ Ò9‚PZ…ÞÎÎŽaC‡0kî²ÕjƒËL6.¯½ÆšÕ?ñÓ«puueùòzË?~œY3f°yãü[ú1aâ$þ:r„™Ó§²qýz^lÖŒE_,Ö-¿eëV‚ƒƒ™={«V®@­Vóê¥÷ áσù}ï>ö8È¿—/³xÑ"“gÑ÷Ϧ •,\0Ÿ°°0~Û³—ßöì%$$„E õßy»ÿ~6oÝFHèEü[µbÌG£¥s¡´ =€··74à‡2XÿõÒ¯hРV––ØÙÙѧOoNé-3bø0<+zbmmM`@iii :Ï{ea¡aºåݵ‹?Œ§‡åÊ•£_ß8|ø°ô^!L>OO<<=ùlÚ46nX_ìÛØ¼i#S§OdzbE<+VdÚŒlÞ´Qo™ÙsæR¥Jlmm8h0gƒƒ¥s¡y _ÆöéÝ›á#Fð M©_¯ž^Ý¥‹—øvùr._¾Ljj*f*ý㉳³³î³••NÎNzewòœþÇDÇðþ}õP*¹a¨0ªUóÒ}öòªNddd±o#**Jo;Õ«×È·wwwÝgI» “ ôæææ|ôÑGL6Å êÕM›5“·Þx“‰ãÇakgGÚíÛtëÑó¡ŒtwwgúôixT¨ =V®]ûZµjë>{zzêLÓÓÓ±±±É9˜ÆÄè­«(J¾ö •yxxèmçêÕ+zÛáñóÀÓâjU«Ò©cG–,]ªWž‘‘­­-ÖÖÖÄFG³ÀļpAtêÔ‘… qýz8jµš«W¯2cÆ,é½B˜4q"Q‘‘DEF2iâD»u×Õy7hÀÒ¯–––Æõë×3zT¾³®K—.ZÖ5 ‰ãÇAdDǧk@ _Ê‚ÐtéÜ™„„D½²QÃG°|ùr:2úãiàíýÐFvéÜ™—^z‘)S?£K@ ³æÌů¥¯ô^!´hÑ‚6­ýñów}³ IDAT{///† ¡«›3wûþøƒºujÑ- +-ýýõÖ2t:¾ªw‡¡²#GQ³VMÚµmM»¶­©]§6ÃGß“4ï¿óGî§„¢#//:¸ŸCGÊÓ+á)"$ø4u½êéu®Üÿrp¹¢)‚PÆ‘çÑ ‚Ò0òkXA¡Ê"æ‚P2HêFAfô“‚\DA„¾ #wÜ‚ B_†iáÛRfó‚ Erô‚ "ô‚ ‚½ ‚ B/‚ ˆÐ ‚ ¹ë¦ pèà~ ‚ <¥´ðm)Bÿ´0`èH ‚ ‡……òR³¦|<æ#~^»Vo½µkÖðñ˜ò• FŒEð™3gý÷—åý_P@ff&“&ŒÇ»~]¼ë×eÒ„ñdff굹ꇕ4mìƒWÕÊtzµ¡¡¤£¡¸…þôéÓøûùšÜðÔiÓéòÚk¬Yý?ý¸ WWW–/_¡«Ÿ=g.oôêÅ–M›ø|Þ!55€¿¡¥+¦MŸÎºukÙ¾mÛ¶meýúŸ™6}F¾ö4 111|±x||L>È{V`¬ `á‚ù„……ñÛž½ü¶g/!!!,Z¸@¯½ýû÷³yë6BB/âߪc>--&brŽ>%%gW“þzéWºÏV––ôéÓ›¾ýúëÊÌÌ̈Oˆ')) ww7FŒnR`ŠÐ·d˦Môîó.›6mÄÊÊŠmÛ¶òæ›oñ÷ßGèÖ½–|óí÷tzµ=çÎeÛÖ-ìüu7Fg쎎lÛ¾£Øíݼi#«~Z­ËýO›1ƒw{¿ÃGc>Ö;ø»»»0pÐ`¾X¼H:ZŠ{F_¾|yâãLnøÒÅKŒû Ý{ж}»‘˜ «Ÿüé$NŸ>ÍÀÁƒy÷½8q"Ȥ:¡pš7oAPPND.ú‚uk×p2è$Í›·ÀÍÍî=zòÅâE¼ûÞû¸¹¹å›•çþ ¥OŸw™0n\±ÛEµj^ºïÕ«× 22Ro™\‘°±±!##C:ZŠ[è6lÈ?ÿ4¹ái³fÒ¦uk~X±œ]¿þ¦ ëÉÖhtõ5Ÿ}–O'Mbúu Ðy æ›T'ŽÕªUcû¶mX[ÛкMÔêlvïÞ…——¶¶¶œ?žµk×°|ÅJ¾þzW¯^5Ú¦‹‹ JPЉ{gjVV¤§§ë¾ÇÄÄè­£(J¾v •yxxpíÚºïW¯^ÁÓÓS:RJZèßyûM¶lÛÆæÍ[ˆ‹‹#++‹°°0>›6ÍàòØÚÚbmmMlt4 éŸjÏœ9‹kׯ“}וIu‚i´ô÷çÓO'Ò­{»ugÜ'ciéï@ZZC䫯–ÑáÕŽÌž3—~}ß7:SNLLà«%_R¯^}]™wƒ,ýj iii\¿~1£Gé­ãììÌ¥K -ëÈÄñ㉌ˆ 2"‚‰ãÇÓ5 P:QJZè+U¬ÄÜY³9{î}û K@ _,ùŠ–¾~—5|Ë—/§s@ £?þ˜ÞÞzõ/þßK|öÙTºòëûñG&Õ & }KâbcépWLˆ‰Á¯eŽÐýx ïЗ_z €¶mÛÑ£GO>;F×FîÝ1žÜø¿_$äüy¾üj©®~ÎÜyìûãêÖ©E·€®ºƒH.C†£SÇWõrý†ÊFŒEÍZ5i×¶5íÚ¶¦vÚ !Oã„âB©Öf°Ö÷í„ÇÅ’s…£3Ûé©hÂãçÐÁý :Rž^)O!Á§©ëÝPO¯sµ ÙØ=Øº× òØFÒÂ%'"‚PÖ¡A¡ADèA„R‹¼J° !ÑA¡/ÃÈ7‚ ˆÐ—aZø¶”Ù¼ F‘½ ‚½ ‚ B/‚ ˆÐ ‚ "ô‚ Â#@îºJ‡î— ‚‰´ðm)B/<™ *)„ÂÐjµ&ÝZ-B/”êA,‚aŠòÛÉÑ ‚ ”qDèAx¬ä}Û˜ðh(¶ÔMÛöس{—Dô1Ò¶}‡"¯ó4ô™g7"£c :Á°!råÊ]™ ˆÐ O7""M^¶rEϧ.>S?›Â„‰“èðjG,ÂSƒÉ©›™- BiãBH­Z·)ѳ‰Ü¿ŠîxׯËÀþýˆŒˆ(R¦”‡­÷Û]ÑÃZÏÖ u«–LŸ6•øøøn˖ͼÒüe¼ªV¦MkN?.²´ ½P6˜ÿù<Žùë©õÿÖ­[XZZ–è6#£c‰ŒŽåFD{öîÃÃÓ“ú•úXEFÇÃéàs,\¸˜ŒŒtZûûþ@ímÚ¸¯–.#ìÒ¿ôï?€AÈYš…^­Vóå’%tëÑ“×{½Áú %’OK¾ü‚Ë—.Q»v'ÎöC‡þ¤Mk¼ªV¦icV¯þIW§ÑhX¸`>/4ñ¡N회>”´´4£3ÖÜÙª±Yí+WЬicªV®„ß+-8~ìë~þ™—_j†WÕÊtzµ—/] k—רºu‹^7oÞ ¡w}RRRôw6• FŒEð™3&ÍØ ÙlÌÌÌL&Mwýºxׯˤ ãÉÌÌÔksÕ+iÚØGçGhè…BcokkKýçŸgê´ôzãMfÏšù@}øÓêµÔþy¬¬¬ðiÜF#;eiúµ?ÿÌ7ùzÙR–|±˜AAÉRÎÊ˹~ý:_-û—'Îþ!ƒ1|øH.^¾ÂÖíÛù'Ϙûö›¯9ò×_lܼ•cÇN•¥fÎìYg¨ygØÆØ»÷wÖmØDèÅKtëÆ›oü]¿þšŸ×z‘6íÚ1fÌh†ÉüyóôDkþ¼y|зåË—×kW£ÑËÑÈÇÇäYõý6ócá‚ù„……ñÛž½ü¶g/!!!,Z¸@¯½ýû÷³yë6BB/âߪc>]¤~xó­·8ôçAƒ©)C†øï¿ÿxûÍ^Œ?^vÌÒ,ô{÷ícàÀ¸º¸àêêÊ`9+ulÚ¸ˆˆ›œ:õ«~XÉ´éÓŸXÌÌÌ‰ŠŠ"..–J•*óù‚…÷fŠ?ýÈÌY³©Zµ*ŽŽ|:y ¿ìÜùÀÛš÷ù¼¼¼°µµ¥_¿þ¤¦¦2gÞçT«VMWvêŸðkÙ;;;ݬþÊ•+ì?°Ÿ÷?è›O +yV ÁóõøñÇUÌœ5»Øc´yÓF¦NŸŽgÅŠxV¬È´3ؼIÿl{öœ¹T©R[[[ÌÙàà"mÃݽ‰‰‰ùÒRÆþ ñþ»½ùdܺuï!;jiúø¸8<=îݱQ±b%‰d)cíš5ø½Ò‚O'Mdñ¢E|8d(–O¬?+XÅáÇhíïÏË/5cßèên„‡Óüå—t‚ê]¿®î ÷ T¨PA÷ÙÆÆæ®À¹ë•eddè¾1‚ùŸÏ#;;›ysf3xðÝz÷‹á¹Púôy— ãÆ{Œ¢¢¢¨VÍK÷½zõDFFÞ'ÔÆý0…˜˜hœÊÎ .Ðéµ×d'-íBïâêJdÔ½!‘,elܼ…}rñb>D§×:?Ñþ<ïíÍŠ•?pþB(S>›ÆˆáCuu•*WæxÐ?z‚z32ºÄlk×®=–̘>  ¼ÓûãûŽ‹ JPÐ ]™••éééyÄ4FoEQòµc¨ÌÃÃk×þÓ}¿zõ žžÅ{ íêŸ~¢Å+¾•º‰ˆŠ‘ôIz??–-ûš¸øxââãYºìk‰d)¤rå*ü´z-Æ(ñ;MŠ›ýûqñbjuVÎÀUݺ½û¼Ëè‘#¸té"YY™\¸pýúšÜöÃÞª¨( ÃFŒä«%_2|ä¨ÏœøjÉ—Ô«W_WæÝ K¿ZBZZׯ_gÌèQzë8;;séÒÅB˺2qüx"#"ˆŒˆ`âøñt |èØ§§§sîìY&MÏÚ5«óñ؇JÝÈ/aKžúÁÔ½z±tÙ2úõ€¹¹9Ý»uãŸS§$š¥3338ä‰÷£]‡¼÷nn„‡S³V-¾üj©®îý÷?@¥¨xïÝ>\¿vgžy†1c?)Ù8«Ì¨Q£={¾^ °9::ѬY3=ûçÌÇè‘#Y¼h!nnî|8d¿ý¶[W?dè0:u|•”ädx*1rS?›L»¶­èÜ¥ ÃG<øS@=+¸¡( ¶¶¶xyyá×ÒŸßÿØ«««ìXOJµ6ƒµ¾oÏ <.–´˜+Ù¦HOEJmÛw(ò/cKã#ÜÏ€¡#Ÿ¨§Wö~û-ºP 3è§¼¨L'$ø4u½êéuî¾ÓlìlÝkyl#é áò„2—®y kð8Ñh4¬Yýáá×éÒ¥«D(•ˆÐ—!ä¡r%O%Ï T©R…o¿[®wÝ@D行 )‰á“€LAAdF/¹)@Dè…2Œ¼/VDè…2L ß–2›„bDrô‚ "ô‚ ‚½ ‚Pjù/àÇ 7×SIEND®B`‚wxglade-0.6.8.orig/docs/html/design_window.png0000644000175000017500000002101012166606326021561 0ustar georgeskgeorgesk‰PNG  IHDR#Œ7Ï¢sBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´tEXtTitel - dialog_1Åi-² IDATxœíÝyxTÕýøñ÷™I2“LBö• $A뎄E|~pmE‚â´W ›¨UÛÚjëöTZ7´Õ@-¢, -ä\YT0¶„¬dŸíþþ2É$³† àóòÉ#sï=ç~Î{?s—™sÇõ¼f²†BœdûV½®ÂÀ‘ˆ†ŒÚµ !ÎHkAÛ·êu¥šÑÁêš®ŽIq:øÅ\*ŠgF¶¦ú®ŒGq†kIFæNNFv5‡wÑTuÍf ¸¸Òé1ħ“~.èô öþêÇÇIˆ¯Õ™Q]ÇõC}é^@#cÀM„£.om¬¥|×ç;¸SJvð"ÁÞŸCýø8ñ9“QG²] ,5•¤÷ÏïPCÂÑ$ýb0‡7„–xV£"0ÁÞŸCýø8ñ9“JçvTu„˜ºŸÐ‡‡¡T]NF|>ÏŒÐëIJI"-#;~¤`üm\rA_6~³ƒ%K>ÆjkâÜórˆ6陕ÉÌY¯Ñ¨ÜÔ§Óá©)ËîMl7-f¹û…uºSòÌèË'/àÿ=ùUG|mÛÖ‘¶žrÛÇËþh=(ÛúÜmµ;N:ëøðŸ»cÕãÏŒŒ‘‘œCzf õõõX›šˆŒŒ¤±±‘¨¨Xêëª1™LhšM³›3#¥Ó£ÚäÖ%ã¸qV Öb—yoMèãœ×¶ž@2zœ«/Läš ¹ýmíæ<¿ˆHC8ÉñÑ\‘Û›ÇGöfxŸ~ÿþ^­v¿×ãËåOo`€q7 z+qúzªì'výÝÚ;.bÕör>Ù^Î᪦ Õ¨}-qúújksÁÜ>¾\þô΋ØÏÌGoà<Ãvš½ßv·?wDóþ쩾»ßØê±ló1Òº\ ÇG q¶ïÆYÎcxé¸D—×л¿ñµJFî7¬fµÝNS}G¢®¦œò’#ô铈 2ä*Ö®ùœÜÜ\22z€²Z»ú”Nçi$ÚŠ©wÿi˜h+¦"¬ežÒé<ÆÚ,ÁΕç'põ… \˜M“ÅΦ=edGa¯%ÝuY} Gã9v¤†Ÿÿ» »ÍB^ßÞÜ?´Œ¿­®Â~|Sæç&só€TºÇ(=ffцo,¥ùê‚îÑLº:“œÔ(ÂõŠ­ûk˜¿¾„¯÷TðÅ_¹cÚGüJ1¼o2c¥Ò=ÞÈÁŠFæ®;Âã7dpù3ß´*S?ú™Û/O'5Ö@ÑÑ^\±mjØWÞÈ]ƒÓe&ߨaåö >ÝQIEÅëvꈹɌºÔ5fJñÅ_¶kë¨KS¹ÿÚ³°kPUgዪxmU1õf[û•(…N§Ù?…‘ýSH‹5PRmfɦR>ø¦Äå¬ÕŸmèJ{Œóß úâôu^¢·ý9Íû³§ú”Âeÿw7¿u9ŽŽÆé®Ú‘ÿª`ñ=ŽÔ:ÝóæVgì­‹y‹¯Õeš‡lj×Pv;‰ÝbIŒ‹E‡M³bµÚ¹ùæ›0›­Ü|ËHÐMMVÀ~|µ©Oé=~ލã~ÍSz±^×'‘k.H _V f«Æ¦ŸÊ˜±ä~Ø»»ÕŒI§£›®Í䲆 -Žj[4zÍÊüoÊÉëÛ›Ád0íOÛR¸¡_ _wŸn/aú»ß2üÒ,ºîiâ½Ç@)ž™MF¼—>ØÈE‡é•Çm—žËŽ¢Rjí‘εtvªmÝvI"ïŦ=¼<ÿ ±rǰþÎåÎ(f§¥§óõÙz™³™¡g™ŸË_FôàÎ7¾£A3ð×öÒÇt€þÙ \|n/&]•É¿<‹M?cÕ÷•¬Øêáþ[€†÷Mâ×÷䛟Êyyþ„aeì¯r]¶eëSðæ¶*&C÷n@«9ÌÀó3¹ãº~´F¦®8‚]»:nÆý×ö`Ù7xáËíÜ<øløeQ:3ÿþºíøûÈ6ô¦ÄžÔ.ÇxÝŸÒ¼?{¨ÏÛ±áv¾—ãã„xiïMÿªàÃ{ZѸ7·¢hŸˆ|Å×2µ9Ŷù Ó‡¡·C]u ßnØÄ“O<ìYs°YŸ|ò)/¿4ƒ¥K>B§Ó`w[ŸÒéÑ)åòç\5ÊïyŽÓ<÷±þ9¿²»±a×þüÆ™·l-ßïþ™&«F=’*{4vÖæ£Ä«¦tXuüPe [tIaÕtnÀÚ¯6ƒ¹–åö8Þ„©¤„WƒRÄD†aµÙ±×—a×lì(®â•EëÈ ;J¸®år/^Œ8}-c¥ðŸ5_c©«âh™wWoo·\³O¿XO¬å0Ÿï, =ÁDïˆCè• ”b_c«wVS¸ôkž|c[w3 ;–?ç÷"N_çq›¡Ÿ?ÞÏåÏÓr£:b^±æÌuU”Õ˜™·úûvÛ²]”bÎG(¯¨ Öªç³m‡xv=ÂJÛ쬎:nè— ÀúßbmªgÙzÇ6¿¡_ ©a ”ÿÛÐKÛ]þÚ¶ÃËŸ»ý¹#Íû³§ãÃݱám¾·ããDþ¼µ·u"˜5¾Uágym¯»íîóÌHÓ44MÃd2mŠÆj†­[vs×QD›øá‡½DDD:>•ýø_ûOo§µm÷oóõ¸õ¹åû¹ñ"ÏM#·÷¯Øº·”u;KY·§–r« ah¨6ûBÑRgF¼€êÚ ÊB„²’ïHPOÞ{Ëú’ãcÈЕQmáÍOqÿÕé<<öWØ5ŸŽÔ3óÓböÁ ¬íÖ—稳áXµZ eZÚRÁ®Û¸8U#§W®¿üb‘Řת¨'²ÝúW™ÉJ6’Ð-’ÝeÑÔÉYñQí–k­ÚåR—Nz¥ñÔÈ^\–Ó c¸Ž]‡jxílÿágÌõÇPš†…p¢Tfº¹m~Þ´­ôÿž÷˜t§«¡Js]þpµ™¬$#IqQì.5QG$™qíÛÖöõ“#{‘Áß?ØÄîŸcÓ˜ñ`>J)"”…p­]™£Ç,d&èm ¶2’ÈÇý›Êšz X0(kÛ°YÃG9wûó‚»â|V;jvU»zšÏ<ÜÝÀn»ÿûšïíø8¾Ú;¾p ŨÙUÎé ïŠ÷Ø^w|ž Ïâ™7§Rh'aáa466¢¹}ì­¡Óéhjj"¦ovû3#«#ÜßœK°Su|žË×ćµTjkë(ÞTÂÊMûI‹ ß¹=é{^O2õ¥´§¹Pe'%ÎÄÍý¹îâx¶U°zý6‰BCÏ¢åL¹:ë‡ögÎ'»ÑÛàìî \Û?‹¿-ø½ž™Å¢õalV¦MÓaQQX0Rg7РL.g-m´§aRõ.õ¶]~ÑÆr~ÿ«î ÚŸÝ+ö£Ó"™|Uw¯1+¥Cü°Ta×sÃàóœ‹è”Bßz¿8^fŶ*î’ʰóóJFr¼oë¶üˆ¦tè~oCoívËr}Ÿ`-¦ªÕÚæýÙS}o\ä=T…K9_ÇGGykï„™ÛP ªÂ{ ÆÌ©âý; ÉS{ÝñyfdQ‘$¦c-hÍË—Ä~=§Š8‹ë£}…‡Ï%O ˆ¤A‹¤LK ŠFÊªêØ·~ÿýúRõVªˆ£Nkù4ŸöðX¬vŽ5ØØ_ÞÀ?Wìd׎ïQè©Ðâ°¨m*'¼±„áý3™Zp5ŠmêyoÃA,Ê@µËòï*E½ÓÏÃbÓø~«?[‡Qg&ÊÞèÚ2¥X±½Š”°jòdòÏñƒ8PifÉæ2fÅ`×4çrm˹nÇ´;ßú‰ ô?¢¡°há˜1P¯"©±GaÆ€½¹Œ—ƒçˆ–m?dÚ,¿|k%)ú*†õËäõ‚K9Pifá7G¹,'¦¥€›˜ŸYv€?^Ϥ[¯ ªÎ̼õG¹Úe=í˼·¡ŒD]5yvç_ŸCÉ1+ï|úß}ûuD¢)]ÛÐ{ÖXûÇ ]^?÷ð y~»»ÅÜìÏîöã¶ÚEÓ¼?»¾`óŸÂ‘ˆ”‡yþÆçûiZøú:yuDûïu¸[ÚQïX5tÔMM6¢hÀ¤Õ¡GC)C_ØA?ýw„c¡#𻦡Óf§‘(ªíјU$ ÅG;¬lÚµõXÃB8-MÓ­øz¯Žâ¢Ÿ‰ÑŽ¡”caZõZ7pYßñ‚èX¸µ‘õÛ¿ÀD--Œ„¤T å•54Hîʹ›V¢%£ÇN­E#FÇ*ß9(`ó·4òåÖωVµ˜µpˆbìŽÝdèJ§ñnbþî@˜½‡týQ¬šŽzeâ7[v“©/A硌]Sük}5+×ï$RׄY ǎ®ERM,fŒ(åß6ôuf4ô…üB÷Ѫ޹Oœ«7°ÛÞÛmOû³»ý¸]Ùvõè‚^_°ùŠÏÝ>ænž·ø|ž‹N¯Çfi$<ÂØá:,æ”>,àXm„QC 5ĸl™Z:&Z.MìJUÓÓ Œ³›°è Îyõ˜(ÖºÓMÕI VN½2aÖŒ€¢\‹ÇŒMè4;ÍH 14è¢AS­Öç8HþtÃÙ,ZEYY)ÝãuüúªóXýõ÷Øh~ÓÚ—sÝ1­œã7;÷m¤žHе ºiÕD*3vMÑ "9 ¥cÀ쌧m|GIÁ¢ˆ¢M‹ÎÀ!ÒˆÐ<—©'šb-ƒX­–,h@£.’J[4fåxoü݆¾T‹‰z*µX—é±êÕĶ[>ØûsWþ8ñ9»ÝWr¸Ã+ñ‡¹æ(J‘šÙ›ˆ4ÈbnàÈŸ°hŠð˜$ßNyçÄp×¥1ôHŽÆlÕø±¤µ›dÿž]Ôj&’Avò¾‰|*òµ ßx8ßcÙ¡ÛÝáõ{õã£3ã+Ù¸„†Šâ–d´¿ôˆ‡j‚CÃŽµ¶kc-î€{§tè&"L ~w2¥k‡ˆÕÕ€RhvPذ£§ŠX*‰ÇBDW‡ò|mÃlUä±ìnÍMw7~öþêÇGgÆwä›Å®}`wö/á:Âc’ IîÔõœj*U26"0ÚëСa%Œ:M-1XïêðN ¾¶añ˜pß“©ã2Ì÷#ù¶‚½?‡úñq2âk÷«}G÷’âdiZ¾¦P}üOøÃ×6,rNw§Ò¥´8y¢Út?ëLF)߯PÔ}+³“rÒƒBœyîš·—¯žÇS_Ÿ è·ÁNÃóGtuBˆVÎØd$„-þýr×3‰¸¸8rss¹wÜ=ÄÄÄx)ujjn«RŠÈÈHÒÒÒÈÍíËÈo$6¶ýwN¼Õ³|ÙG¦§¿“à<°ÊËË™9ko¾YÈ#<Ü)uµæ¶666rðÐ!V²š)÷?Àôé/š"÷Õ„¶€’Q³ÄÄD&L˜Àĉ“œÓ4Mcþ‚¬Z¹Šºúz Ä„ñŽ/H ÏÁ¸q÷°dÉRÊËËYöÑR¶nÝÊ[oͦøÀâââ=z¿¼öZ, ³çÌá³Ï> /o0wÝy'áááÎú&OšÈÂEPUUEvVS¦ÜGÏžŽÎ´<È;ïü›ï¶mÃf³Ñ§O¦Ü7™nÝÜÿrÝ£ÑHNv69ÙD™¢˜;w.?ôÏu4Ÿ]5ÿ¿9¹+.!N7A»g´téR¶mÛÎÔ©Ï2kf!6›•¹ïÎsYfû¶í¼ø÷¿±ì£¥üýÅ5zóß矛Æî]-߈¿`û÷ïçå—^äå—^¤¨¨ˆ ºÔ·ió·L›6•yïÎ¥_ÿ~¼þú?œó¦=÷<×_=oÏ™Íì·Þ"11·ß~ç„ÚøËk¯eË––>‰½­£9ù,_ö‘Ë¥ZgÄ%Äé Cɨ¢¢‚ÂÂBúö½Ä9í¯dâÄ ¤¦¦Í=wßͺuë\ÊÜKBBK¯p:žŠò ª««INNæþû§8ç­Y³–‚‚’’’HJJb|AkÖ®q©oò¤‰¤¦¤`4¹iäH~Ú³Ç9ﵯrñÅÉÅícDzióæŽ4×)>>ššc'´ŽÎˆKˆÓA»Ë´Ï×|êòº`ʃìÜæ8h¾äˆ‹å’¾}¹wÜ=ÎåJKK™0a¢KÙ¶¿òMNvýöæ_Œ÷ޟϼ÷Þ#&&†‚‚{é߯àHxi©©ÎeÓÓÓ)/w)$>¾¥—9ƒÁ€Ùlv¾þñÇŸ˜3g{öÖÑ}«£kÜŽ«¬¬p¹œêÈ:¼•9ï¢>Îxù„bâTP0åA`•Ë4·÷Œ :4'"Àë“¡”ädžzú)¯7wÛ&§œœìÏh𯯛xå•Wù÷;oÀ‘’Îêáè˜éðáÃ$&&´«Ó“¦¿À¯ÇŒáÑGÿˆÉd¢®®Ž_ÿæ·~—wçã•+¹¤OËÙ ¯u¸ërÁ[™Û¶ºl{!NGž>p=ÞÀn„ü1lØ0f̘Áø‚ÒÓÓ9pà ó,àø½Ç2/LŸÎ˜1cÈHw Ôúà’—Gaa!>ð€£…3’7Äïx›ˆŠŠÂh4RZZÊìÙsjO³¦¦&<ÈêÕ«ùâ‹/™>ý¿×Ñ­[7Š‹‹éÑ£‡ßeÝîBœ.:ô4Íüüá(¥xvê4JJJèÞ=ƒÛn»Ík™A—bê³S)=z”™™<òpË×FÅì9sxðwŽ'Wƒ_ΨQ·úÏ÷OaÖ¬ñÜóÏŸÀM#Gòe›{XÞ ÏR ƒÁ@zz:¹¹}yõÕWˆkõ=#_ë¸õ–›yä÷ ®®ÎyVy¢q qºrv!Ò´ª‘¢î[¹;ã{—ûDBLŸ¯ù”‚)2èO«¿M›y. Åòs!Dhd$„ ~Ý3:ï¢>‡â4µbÙRzõêås993BtšË–ú½l@OÓ䦶¢³øŒÉpB(¿.Ó$ !:›_gFþÜ|Bˆ!7°…!A’‘"$H2B„IF§(jIœn$ !BBк9Sx;#‘a‰„è8IFjpd\4!‚G’QüñÑ?qý°aäå vN;zô(?òÿüÇ?=f wÝy'‹/Æf·3$/qãî!,ÌñøêÉ+Vxª©#CGƒ¯öFD„ûjªm"o=Í]|mèpUÃóG0iâD>øðCÊËËÉÈÈà¾É“8tø0 ,¤¬¬Œì¬,|ð233ý~ŸäCªcäžQŒu+ï½ÿ>š¦9§½÷ÞûŒÈÉÀ·[¾å•W^浯ràà,lzÉŸ¡žÚò6TSG†Ž $_íõg¨)_ÚÆè6ðgX¨o6~Ãÿ=ó ï¿7¡C†ðÄ“OñÕW_ñôSO2ïݹ 8×Ü®¢c$Inn.F£‘µŸ}À¡C‡Øüí·äçw.SPP@bb"‰‰‰Ü{/Ÿ~Ú2‹?C=µåm¨¦Ž H ¾ÚëÏPS¾´/ÐmàϰPSî›BzzF£‘nACC÷MžLZZË´~ø! m$gE#—iA4zô(æÌžCÞàÁ¼ûî<ðÀƒXm6òò» ½Ô‘¡ž¼éH})㩽¾†ššå2M:h"tùÕ!s";·m¥¨¨@º ¢=ûŠÉÏÏw~i3§WOöíë⨄81ž~â©C~é\M$ !B‚$#!DHd$„ ’Œ„!A’‘"$H2 AòX_œ‰$ !B‚$#!DHd"¤ÿkq¦“ùC@NÏ2&8ãùŒd$Y!Dgòë2M‘¢³ùuf$¿ÐBt6¹-„ ’Œ„!Až¦u¡æNëDhPJ±ã»-]ÆK’Q“Gú¡áó5Ÿvug<¹LB„IFBˆ ÉH$ !B‚$#!DHd$„ ’Œ„!A’‘"$È—ÃóGŽo GFF’––Fnn_FÞx#±±±]8SH2,_ö—8_'$$p¤¤„³zôàðáÃ$&&ø]_Jr2O=ý”ÜnÉešpÑÔÔÄž½{)œ9“•+WñÛÛ~ëœ7$/ÂÂBÊÊÊ(++£°p&Cò†ø]÷°aØ1cÅÅÅX­VŠŠöñü Ó;£â$gFp< SJa0HOO'7·/¯¾ú q­¾g4zô(fϙÿs<]<ørFºÕïuäçG)ųS§QRRB÷îÜvÛmAo‹85I2ÎïùÁø‚Æø]OëiJ)ò󇓟?¼cŠÓš\¦ !B‚$#!DHd$“ˆ±YIDAT„ ’Œ„!A’‘"$H2B„IFBˆ ÉHäK]L†UÂA’Q’_¬ ÑB’QÚñÝ–®Aˆ!÷Œ„!A’‘"$H2B„IFBˆ ÉHÜ>M+œñòÉŽCq†k—Œ ¦<Øq!ÎpÎdTÚ·†(²ô§U]â •’Máw‹€Vɨ࢜ãÿÊqS¬küïÕœsN,éé6[˼Ï>«åüó£±X ¶ FHNr_Om-Tdd¸_¦±*+Ál†ã£1·cµBY944@Lóð•Ñ#%ÐÔÉÉå~™²r¨¯‡ØnЪÏ{UÕÁm[“zùѶÌL—¶uyÛÊ+àðaèÓššÀn‡¸8÷eNEO}íø¿êyÍdmÈØ©løÏ?»6"!Ä«¡¢ÐóšÉZW#„8sí[õºúÿå«ÃpнIEND®B`‚wxglade-0.6.8.orig/docs/html/ch03s05.html0000644000175000017500000000454212166606327020202 0ustar georgeskgeorgeskPreferences Dialog

Preferences Dialog

You can access the Preferences Dialog with the menu item ViewPreferences. You can choose some decoration options, like whether to show icons in menus or not, but also something more effective. For example, you can modify the number of buttons in the Main Palette. If you type a value of 15 or 30, you get a long toolbar-like Main Palette. You can also choose the default path where you save wxGlade files or generate source code.

Another useful option is to enable a default border of 3 around some widgets. In many cases this can be useful to have set.

You need to restart wxGlade for changes to take effect.

wxglade-0.6.8.orig/docs/html/ch03s04.html0000644000175000017500000006741312167336636020213 0ustar georgeskgeorgeskProperties Window

Properties Window

The properties window lets you see and edit the properties that apply to the selected element. This window consists up to six different tabs. All six tabs are not always present. The visibility of the single tabs depends on the widget type. Most widgets have a Common tab and a Code tab. The combination of presented tabs depends on the widget type.

For example:

  • wxFrame widgets have Common, Widget and Code tabs

  • Spacers have the tabs Layout and Code

  • wxGridSizer widgets have Common and Grid

  • wxBoxSizer widgets only have the Common tab

Editing properties is quite simple; Properties are represented by buttons, text boxes, checks and other controls. Usually they are referenced by the same name or symbol that you find writing C++ code.

Usually you get the changes in the design window in real time. In some cases you have to push the Apply button. For example, the wxNotebook widget shows in its properties window a list of child wxPanels. You have to press the Apply button to show changes you make when you add or remove panels.

You can show or hide the properties window by the menu item ViewShow Properties.

Application Properties

The page Application contains the general settings of the active wxGlade project.

Figure 3.6. Project Properties - Application settings

Project Properties - Application settings


Name

Name of the instance created from Class

the section called “Automatically created wxApp instance” provides more information

Class

Name of the automatically generated class derived from wxApp

the section called “Automatically created wxApp instance” provides more information

Encoding

Encoding of the generated source files.

The encoding to use with new projects will be determinated automatically based on the machine settings. UTF-8 will be used if the automatic detection fails.

Enable gettext support

Enable internationalisation and localisation for the generated source files

Top window

This widget is used as top window in the wxApp start code

the section called “Automatically created wxApp instance” provides more information

Code Generation

Write all source code in one file or split the source into one file per class / widget

the section called “Using the source code” provides more information

Language

Programming language to generate the source files in

wxWidgets compatibility

Generate source files for the selected wxWidgets version

Overwrite existing sources

Overwrite existing source files or modify the code sequences generated by wxGlade in place

the section called “Using the source code” provides more information

Output path

Output file or directory

the section called “Output path and filenames” provides more information

Generate code

Start generating source files

The page Settings contains the language specific settings of the active wxGlade project.

Figure 3.7. Project Properties - Language settings

Project Properties - Language settings


Indentation mode

Use spaces or tabs for indentation within the generated source files.

Indentation amount

Number of spaces or tabs used for one indentation level.

Use old import "from wxPython.wx import *"

It is generally recommended to use the new namespace.

The old one (from wxPython.wx import *) has some significant drawbacks like potential namespace conflicts.

Source ext

Extension of the source file.

The extension doesn't has a leading dot.

Header ext

Extension of the header file.

The extension doesn't has a leading dot.

Common Properties

The first tab contains the common properties that apply to all widgets. As shown in Figure 3.8, “Common Properties” the common properties are related to name, class, size, colors, fonts and tooltip.

Figure 3.8. Common Properties

Common Properties

The property name is a mangled version of the wxWidgets property name. The property input field is disabled by default. wxGlade won't use disabled properties for code generation. wxWidgets defaults are used instead.

Enable the property in the wxGlade GUI to set non-default values (see Figure 3.9, “Changing Common Properties”).

Figure 3.9. Changing Common Properties

Changing Common Properties

Name

Name of the instance created from Class

Class

Name of the subclass of the widget. How this name affects code generation depends on the output language.

Figure 3.10. Common Properties of a subclassed widget (default behaviour)

Common Properties of a subclassed widget (default behaviour)

Example 3.1. Generated Python code of a subclassed widget

class MyDialog(wxDialog):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyDialog.__init__
        kwds["style"] = wxDEFAULT_DIALOG_STYLE
        wxDialog.__init__(self, *args, **kwds)

Base class(es)

A comma-separated list of custom base classes. The first will be invoked with the same parameters as this class, while for the others the default constructor will be used. This property will be shown only for non-managed widgets for instance wxFrame, wxDialog, wxNotebook, wxPanel and wxSplitterWindow. You should probably not use this if overwrite existing sources is not set.

Figure 3.11. Common Properties with Base class(es) entry

Common Properties with Base class(es) entry

Example 3.2. Generated Python code of a widget with two base classes

class MyFrame(myFrameMixin, wxFrame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        myFrameMixin.__init__(self, *args, **kwds)
        wxFrame.__init__(self)

Id

This property could be

  • a constant numeric value

  • a predefined identifier e.g. wxID_ANY

  • a predefined variable like a class member e.g. self.myButtonID

  • a variable assignment e.g. self.myButtonID=? The pattern of a variable assignment is always variable=value. The value could be again a numeric value, a predefined identifier, another predefined variable or ? a shortcut for wxNewId()

Figure 3.12. Common Properties with a variable assignment

Common Properties with a variable assignment

Example 3.3. Generated Python code for a variable assignment

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.myButtonID = wx.NewId()
        self.button_1 = wx.Button(self, self.myButtonID, "button_1")
        self.__set_properties()
        self.__do_layout()
        # end wxGlade

Size

Set the widget size in pixels.

Background

Set the background colour of the widget.

Foreground

Set the foreground colour of the widget.

Font

Set the font for widgets text elements.

Tooltip

Set a tooltip for this widget.

Disabled

Disable the widget.

Focused

Sets the widget to receive keyboard input.

Hidden

Hide the widget.

Layout Properties

The second tab is related to layout properties that control position and resizing within the sizer.

Figure 3.13. Layout Properties

Layout Properties


These properties apply to any widget. You can check or uncheck any option related to the placement in the sizer. Many widgets may have a default value of 3 in the Border property in the Preferences Dialog (see the section called “Preferences Dialog”). If you let a widget have a default border, the wxAll option is also checked.

Widget Properties

The third tab, named Widget is different for each widget, and lets you edit properties for the specific element you have selected.

Figure 3.14. Widget Properties

Widget Properties


The set of options may also be quite complex in the case of widgets that have a great deal of methods and properties (such as grids and tree views). In this case, wxGlade greatly simplifies the process of designing forms.

Events Properties

The fourth tab, named Events lists the widgets events. wxGlade generates an event handler stub and binds the event for each added handler name.

Figure 3.15. Events Properties

Events Properties

Figure 3.16. Events Properties with entered event handler name

Events Properties with entered event handler name

Example 3.4. Generated Python code of an EVT_TEXT event handler stub at line 12

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.text_ctrl_1 = wx.TextCtrl(self, -1, "")
        self.__set_properties()
        self.__do_layout()
        self.Bind(wx.EVT_TEXT, self.myEVTTEXT, self.text_ctrl_1)
        # end wxGlade
    def myEVTTEXT(self, event):  # wxGlade: MyFrame.<event_handler>
        print "Event handler `myEVTTEXT' not implemented!"
        event.Skip()

Code Properties

The fifth and last tab is named Code and has two parts.

Figure 3.17. Properties for extra code and extra properties

Properties for extra code and extra properties

The upper part provides the ability to add additional code for that widget e.g. for importing a custom class. This Extra code will be added to the context of the source file and not to the context of the class.

The under part simplifies setting of additional widget properties. Add the property name to the Property field and not the name of the setter function. For instance add MaxLength and not SetMaxLength. The Value field is just a text field. You can enter e.g. a simple number only as well as a complex statement e.g. 0, 0, "1" or a function call. But be carefully! Your entered sequence will be inserted in the source without any changes - one to one.

Note

Extra code and Extra properties won't be processed for the widget preview.

Figure 3.18. Set extra property

Set extra property

Example 3.5. Generated Python code for setting property MaxLength to 10 at line 14

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.text_ctrl_1 = wx.TextCtrl(self, -1, "")
        self.__set_properties()
        self.__do_layout()
        # end wxGlade
    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame_1")
        self.text_ctrl_1.SetMaxLength(10)
        # end wxGlade

wxglade-0.6.8.orig/docs/html/ch02s06.html0000644000175000017500000002742512167336636020213 0ustar georgeskgeorgeskUsing the source code

Using the source code

There are a lot of options to control the source code generation process. They are bundled in the Application page of the Properties window (see Figure 3.6, “Project Properties - Application settings”). Let's talk about three of those options -Single file, Separate file for each class and Overwrite existing sources.

The first two options triggers wxGlade to generate one file with all classes inside or multiple files - one per class/widget. The Single fileoption includes source and header file for C++ certainly.

The third option Overwrite existing sources is just about control - Full control by wxGlade and Shared control. It separated the two ways to work with wxGlade.

Full control by wxGlade

If Overwrite existing sources is set, wxGlade will re-generated all source files and drop potential manual changes. You've to include the generated source files and use derived classes for implementing changes.

The files written by wxGlade are consistent always. Also if e.g. classes or attributes are renamed. Rewriting the whole files is less error-prone in comparison with the section called “Shared control”. That is the advantages of this method.

This method is the recommended one.

Shared control

Manual changes in the source files won't be overwritten if Overwrite existing sources isn't set. You can safely edit the source code of the generated class. This is because wxGlade marks the untouchable code with the special comments begin wxGlade and end wxGlade. So you can edit all you need outside these two tags. When you make changes in your forms, a new code generation will not modify the user code. wxGlade is applying most of the changes but not all changes. Especially renamed classes and attributes need additional attention.

Note

Overwriting multiple files is not recommended as well as overwriting of files with percent character (%) inside is not supported.

Output path and filenames

Output path specifies the name of the output file for Single file projects or the output directory for multi-file projects (Separate file for each class). The filename has to include the appropriate suffix of the programming language always. An exception is the Output path for Single file C++ projects. Filename don't contains the filename extension now. The extension for C++ source and header files will be appended later automatically.

Automatically created wxApp instance

wxGlade is able to extent the created source for by a code sequence to create and start an instance of projects Top window.

In case Name and Class are set, a detailed start code with a derived class of wxApp will be created. If just Name is given, a simplified start code will be generated.

There is a short explanation of Class and Namein the section called “Common Properties”.

The application start code of a multi-file project will be recreated every time the code generation is running.

In opposition the application start code of single-file projects will not updated if the name of the Top window has changed and Overwrite existing sources is not set.

Example 2.2. Detailed application start code in Perl

package MyApp;
use base qw(Wx::App);
use strict;
sub OnInit {
        my( $self ) = shift;
        Wx::InitAllImageHandlers();
        my $frame_1 = MyFrame->new();
        $self->SetTopWindow($frame_1);
        $frame_1->Show(1);
        return 1;
}
# end of class MyApp
package main;
unless(caller){
        my $local = Wx::Locale->new("English", "en", "en"); # replace with ??
        $local->AddCatalog("app"); # replace with the appropriate catalog name
        my $app = MyApp->new();
        $app->MainLoop();
}


Example 2.3. Simplified application start code in Perl

package main;
unless(caller){
        my $local = Wx::Locale->new("English", "en", "en"); # replace with ??
        $local->AddCatalog("PlOgg1_app"); # replace with the appropriate catalog name
        local *Wx::App::OnInit = sub{1};
        my $PlOgg1_app = Wx::App->new();
        Wx::InitAllImageHandlers();
        my $Mp3_To_Ogg = PlOgg1_MyDialog->new();
        $PlOgg1_app->SetTopWindow($Mp3_To_Ogg);
        $Mp3_To_Ogg->Show(1);
        $PlOgg1_app->MainLoop();
}

Compiling C++ code

You can compile your wxGlade project after the generation of the C++ source and header files. The following examples demonstrate compiling on Linux command line using g++.

Example 2.4. Compiling a single file C++ project on Linux

# g++ FontColour.cpp $(wx-config --libs) $(wx-config --cxxflags) -o FontColour
# ll FontColour*
-rwxr-xr-x 1 carsten carsten 72493 Jun 15 09:22 FontColour
-rwxr-xr-x 1 carsten carsten  1785 Mai 11 19:24 FontColour.cpp
-rwxr-xr-x 1 carsten carsten  1089 Jun 11 07:09 FontColour.h

Example 2.5. Compiling a multi file C++ project on Linux

# g++  CPPOgg2_main.cpp $(wx-config --libs) $(wx-config --cxxflags) \
       -o CPPOgg2_main CPPOgg2_MyDialog.cpp CPPOgg2_MyFrame.cpp
# ll CPPOgg2*
-rwxr-xr-x 1 carsten carsten 108354 Jun 15 09:33 CPPOgg2_main
-rwxr-xr-x 1 carsten carsten    844 Mai 11 19:25 CPPOgg2_main.cpp
-rw-r--r-- 1 carsten carsten   5287 Mai 18 19:06 CPPOgg2_MyDialog.cpp
-rw-r--r-- 1 carsten carsten   1829 Jun 11 07:11 CPPOgg2_MyDialog.h
-rw-r--r-- 1 carsten carsten   1785 Mai 11 19:25 CPPOgg2_MyFrame.cpp
-rw-r--r-- 1 carsten carsten   1290 Jun 11 07:10 CPPOgg2_MyFrame.h

wxglade-0.6.8.orig/docs/html/sizer_menu.png0000644000175000017500000000425512166606326021115 0ustar georgeskgeorgesk‰PNG  IHDR`€{¾ûíbKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÓ  .4Ug?š:IDATxœí_hÛFÇz¸@ØCœ§V¨¡…ÚOsa0»í({hÍÓBjh<Ú¸+l}ëÃh½BHM“6ÜÂÚ¦CYÙ¨3ØX «°0Vp¡Ã24`ÁÌ{P¢(§“N–­?!÷Á„ŸN?ŸN_ßN?Ý)n/Ãrc¹ ‹Rç9Í’e9Ø¢„¹.À;A#ì0(0(0(ø$ÐÀÀ€yjt=g#œ§¹ëÔjµîf800 çi´»ŽW5ûmu{Àælö·©Þ)‚áI ÒRóoküÙ1gÛæ@à±XÞöAVEwròNN»V«Õj5O»!Oj^hâIšÕñº£í¯:i«&fãÜžvÌFš¡í²òß•¹mÎC8ÝHdå¹ô Œ¨ªªn6в©ÊË‘~§Ý0—Ñmjqu‡.žX· \ÅîýŽ …^¿ª‹k¨ª -P[*:ˆFÎŒ¬¾rt¥ãÇÍæxc¥5 gHwblÙü¸ ÌeøqA˜ãùqAw°È¹S,ÇA‰cШÖeUQ òÛ†´.¥õDF‹›`ÏvV|^æx>/蛄Ã91ˆ¶!…œ³;Z;f{7«Kß/® Ÿ:;>€0Í»þ.Ÿ„i~—"]ÊÙ &u•Ÿj°¥u)’°ô´Èªø|Y/=Ÿ/|Ȇµ?~š§{v „¶·š€ª(õ"TdhÔé‹äŸN's¹Œ8òfær;–¾×lý‰‡°ñtAÓÐÄÈ™õ½¶öcõª¹¶šÍHϤôé4:4Õéñ÷X'½SO¦òSØ­ÆÄ'÷ž;½ÌïqvzËê8û8nLY«{X¢Ð²K Æ¦jå·oÙH¡1Œl ôh~u½N`k5Á¢À¢À¢à­@ö“2‰{Îãt‘³;<H›Ð‰«m@#.Ñ¡®Û±qÀ–zP×y´…W õùÐZ%2¯ÀÀ–®˜‰¹géc™cGìÀ:i‡óÛuè:>lîbïc?3ÝS¼]e“Ò.m-þè"5±¶®ñ^ ýžÏal,ÆÅæD«oYíÂöv«®yµ˜Å&…¸nÃ~1‡9ø]›×°[ L L L L L L L L L ~¿XÀÓ ½T³DÁ§æp²U ñB61fÕž‡;ÌádÃÊ&Æ.ü T{ÞÄlÊÔ­ôž|w‡ Äè—‹ÊïO :˜bæ¦áî$}TóàÐõ^wžŠ&æäe@æjâ:Pm•À8°p{!7–cëæÍÈuY|.²"&&&&&&&&&Ÿ¦àþ¾H×X T¼U€©K.Wa·þOëx“^JË—3gùØ‘!h5J÷·^JRº_’^J3%Þy÷Ú‡Ÿ‰fÛgp*b¥úê¯ì¹‘h4š<•Z{¶V^-gÏg¥^ü¶ ï9Ó#ÄØl;cä¸ó£tR'ÍõÈõ:p?UÿmHëâÄxndøìàPyµìQ9BÛ 57å³gÒ}½€ƒD"Q­V{8˜¸˜]¼»èwƒî¿p"ýEQûzâB^W¥Tò8p¨ï`oæLªxãkJ’æ† ”J¦ä·ÆF¸­KÜàÐP_/B‡ÎžIWþ¤wÕæs£žj´ Bhb¥ïJ…/®ÿñL,L]oªPœž…Aõµœú ®ìÑ4ÒÁÂÏX¢1Ýœl÷DÅÆÖ~«¤N¦c±ØÒ¥Êº?-Þ˜­þ£$ÞOL}š%~ ÃáŒgjz°Jœ©ˆ••'++OVÒ§ÓË—gçJ¹ÑÜÔ•”Ÿ… ¼ú€•@±reêŠfßüæ&¤’¾JáP¬Êg³ÃY}Ôãµ:îÖŽùƒÝͪÿµ&„°p&&&&&…PĤC2&$Ò^ rr›ªaŒ†$pá§®N|tÂa ß&&M EÃÞ w˜)Þ*Š¢83=ãE jÛ¯øð"óÎÁû 饤½_2‹GG pµ ŠâÃê{#ý‘ýs‚× -ê,¾'ó“`¨;¢(Næ''ó“â 1€b‡ÝU,{>+¾• åDêDòdžþüÔ¯‚…\ Üh®"VbÇb¹Ñœ,Ë“ŸMÞ(ހ찣(¢†9TJ\NÑA±ý(z8ªu=åÕ²ÖÜÚ’F»´›§Dº8×›Xyµ,¾g¦g´žÈÔØs‡ëü|™—ë²\——î.åFs>(lX<ÕˆÅ`_]έ ¤÷D v7O DýŸU ,Î0©e¯ð?øï)§œ±IEND®B`‚wxglade-0.6.8.orig/docs/html/index.html0000644000175000017500000003152012167336636020224 0ustar georgeskgeorgeskwxGlade manual

wxGlade manual

Marcello Semboli

Alberto Griggio

Carsten Grohmann


wxglade-0.6.8.orig/docs/html/ch05s04.html0000644000175000017500000000357712166606327020212 0ustar georgeskgeorgeskStatusbar

Statusbar

In the properties window you can edit the list of fields and their size, but remember to click on the Apply button to consolidate changes.

wxglade-0.6.8.orig/docs/html/label_menu.png0000644000175000017500000000345712166606326021043 0ustar georgeskgeorgesk‰PNG  IHDR`X…Óe¯bKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÓ  1 ÀU}¼IDATxœíœOhÛVÇ:˜ðÓóÏO?}óÞïý‘ì7î~s<Ì¡ 9“t; BY]Y¥KEwC!±&À›n‡A:ž@xYà d#ŒŒôün·žökë ÊÑÚÅiiH½Œc¹¶ÐÌÓ Åm°[ÐÈȈzµXÛhèl×q6I›]'9×oIÿºØzö“¾v±ÎÎd6+wæAG5èζ íؤ6(µ\m5:OG£ê GÒ^¡ÑÖþ5û”YIçs9ÁL±=®o­lr·Çy‹U <,ð²`OºæíIãÙ( »Tø ´ ﮆ ^²`¯%frîÆA K_Lv¢˜œùܽ`ˆcue^1ÚfÒŇknC'‚ªÙ¾Ô€…G¿ÑI‚܉‚`LÛÌÍKe" RÚ Ø¬´\`µ‡±+Å"#„6|ûG‘ÑêòµàÛÃCÈ/l â+‘¦ixUJN'ïÿb«^fæ@”rÕ’OScëæAEO‰RCœ»v%‰’(Ë< Ghv:ž»=¯øX½Àì[a•—¶Dý«5:ûcmç!^à“´¸[C”oè-ìBLjHÐjÂPÝ­ÕÍ€ÍDNa¹|‚™}¬p+z›[I€b(o™ù·UÞ±æÃƒ¹ÜÀp ô³X|X ŒdY–Íú®$5dño10l7 qù„j[†«:á…˜QìþoZhûeß@–ehÜ’Ñ 45>µþÒÖHÇÌrŠÁåm£Õ §)·cìÙÌ,ÇåÌ,Çåf–SLj>,¦ó È{!hTk¢,IÐñu]Øâg}ô:÷¤ Ù¯ŠIs\žaÒœzˆ9kkJð5÷FëÀìn±Zø®½‘Í~š=Üù¸E¦çÏ2iŽ[dÚ9¢šè¤ö™ùÉ[ØSO“ª|À¤ËjôLº¬ñÁæþúSXyöN›@hÿ¨ É’„Т@@šN¿Šÿש$>)# ˜ø¤¬;—ú®ÑÀúcOÑÁ³šš.†¯ÌææÆ9äYqm5›-ž ñ‹qt2sØóº$}ÐN2éŒn©1÷áÜý?ìóÎAF1mŽË?"€sÚ’šƒK›@õ†læwl9HÝCóв'Ðã•ã•zíà}WÞ@xYà dƒ÷1´O†õØaW˜ ”»€ÌµG7ÝÓòD=<ßú.&¼Öž¬%&˜Ðé ´êÅ{›íÅEá…`³R£:±´%j¹®Ðh÷½@¾R}ù{iЦéè…ØÆóòz™½ÌJR-÷õÜ¿W´SÐI`,$\’¦|b­„OÓò¿ua‹Ÿ›MNMNŒ‡Ëëe‡â ¶bj6ĉñ¸P‰DªÕª‚¹«ìê½Õ~èvþÒ H’ìBˆB!Ø® ±è9 ÿÄPb<–[ø²?‘ÒÝôÅ¢1ñu½¾[joˆ ýCQšWþ´NÕÆk³¼T´À‚ébÅo‹ÙÏæÎg3óMr‹ËР!¨n‹±wÃÊ  3ŠF*ºïdè µåÆBwÓ~>Úøµ;…B…;…Ê–>Mç–«ÿH‘w"™Xì§ttûm:2ó4^ ø‰ _)=-•ž–âãkOÖ–óÅät2s=ÖÏà\o>`&P…¯\Ï\Wì[_Ý€X´¯Òꀙ@ì$ËN²ê¬Çiu°B t^¬ö¿Õˆ·Ýa'ž@xYà d'DìI2'ÄÒ] ²³LUÐî²qÑvÊÞÈŽ½?fs¿Ãž4v+k»ÃHîvŽçù¥Å%'"0û!BÐç á… <7…éS4dodyžôý#õÝÀpàø¬Bô-HÙuæ7ùT:š¶Ãó|*J¥Sü&ïB˜îÑic/³ü&/íJc±±èù(<ûéY¿#½@Ééd…¯„Ά’ÓIQS§r ÀNÚÚET0n•Ó6±YY‡^ ú­¤žòzYén]I£¢Ú¿„½qØÃ‰œßÅÊëe~“_Z\R2QoXî= ÁóbMkbá^!9}ÜjÚä®F( Çj87/š‰<¼Õ¼ž@x¿d«+.<Ô2(üqPÖ±%üIEND®B`‚wxglade-0.6.8.orig/docs/html/ch01s04.html0000644000175000017500000000363112167336636020201 0ustar georgeskgeorgeskBasics

Basics

You need to know the basics of wxWidgets or wxPython, as well as the basics of C++, Python, Perl or Lisp. You can't use wxGlade if you do not have any basic understanding of programming. You can't learn wxWidgets programming from reading this manual either.

wxglade-0.6.8.orig/docs/html/ch01s05.html0000644000175000017500000000530112167336636020176 0ustar georgeskgeorgeskRequirements and Supported Platforms

Requirements and Supported Platforms

wxGlade has been tested and run on Windows, Linux, Mac OSX.

Because wxGlade is written in Python using wxPython, it can also be run on any platform that supports Python and wxPython.

Especially the wxGlade requirements are:

  • Python 2 - at least 2.3 or any later version of Python 2

  • wxPython 2.6, 2.8 or 30

  • wxWidgets 2.6, 2.8 or 3.0, the wxWidgets are often bundled with wxPython

Note

The support for wxWidgets 3.0 as well as wxPython 3.0 based currently on the development release series 2.9 of wxPython.

wxWidgets is available at http://www.wxwidgets.org and wxPython at http://www.wxpython.org.

wxglade-0.6.8.orig/docs/html/ch01.html0000644000175000017500000000527112167336636017654 0ustar georgeskgeorgeskChapter 1. Introduction to wxGlade

Chapter 1. Introduction to wxGlade

What is wxGlade?

wxGlade is an open source graphical user interface builder written in Python using popular widget toolkit wxWidgets.

Figure 1.1. wxGlade windows

wxGlade windows

wxGlade allows to create graphical user interfaces using wxWidgets. The designer can arrange different widgets using a drag and drop WYSIWYG editor. This simplifies the creation of a graphical user interface in comparison with manual coded graphical user interfaces.

wxGlade is able to generate source code for Python, Perl, Lisp, C++ and XRC based on the designed GUI.

As you can guess by the name, its model is Glade, the famous GTK+/GNOME GUI builder, with which wxGlade shares the philosophy and the look & feel (but not a line of code).

wxglade-0.6.8.orig/docs/html/apa.html0000644000175000017500000000560312167336636017661 0ustar georgeskgeorgeskAppendix A. wxGlade License Agreement

Appendix A. wxGlade License Agreement

Copyright (c) 2002-2007 Alberto Griggio

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

wxglade-0.6.8.orig/docs/html/properties_window_tab_5.png0000644000175000017500000004074112166606326023572 0ustar georgeskgeorgesk‰PNG  IHDRPîÉ(TÜsBIT|dˆ pHYsÄÄ•+tEXtFensterklassepythonC!´ tEXtTitelProperties - ˆKË IDATxœíÝy| ÷ÿð×lî[¹Ü´¥¨+âj5q¥qSZUwâ,zøéáhë(ßj)%T7u‹+A[u¡®ª” ‡ÜrI6»¿?"+›ì•Oîx=~¿v>3Ÿyf3¯Ý‘ðLn• ""½î]!€1ž^Ãç—oEDD•D ¼wt…$å…çÃä'å]Q¥ððÌFd$Dæ@ÎÓôò¬‡ˆ¨Òy Y¥ Š]õ©’Lh%:åïSL-lŠÕ‰¥mnG¥Q+QUWÒû`Eß§Ë >U€J’T¬i’¿OI’¡$Ö I²R©•¨ª+é}°¢ïÓeQŸÎ#ÐP//ÌñöÎýwh¨AoáçÎ Eî›ÿPt˜ýV¾î ÓRľ±Ž…¦õþ)^ã¼’Ìè…=ýmN{Àësþ(çJ¨ ÊðÜèÚ‹Ú$™Æþ4íËÜ·KkŸÖUŸ¦|ÑÖ¦«>G ÞÞުМ3gŽ:ÏΘªÊŒŠôjà$€xãš…¦K2#­¯gf·S{œ%W *é)BÂã°ù÷GÈΩ_¶ÊÇsÏjlolþ7žÖ*Ë’ŠMߘ*Zߢ}úÜü[-íRPQ÷AýH’p÷m]ûtqèªoßXGøæ ʽù‚¿(õé>ZܼÉß§L†‚5ü:&·è>kâá( Ö¶Î¿¹ªML¦÷ÕjìÂ;+s êÒc;ׂ«µßŽ.öÊÒ«fp#ëùÉë7惧ù-8ÉQÍ(I ±“ã¥É­šº6uD·¦Žx?àj¡ö‚c*I¥ÑwQût0J5è¹ycÞ9¼jz?ͨq=ü^ÃÑkñ8v-QIOÅŠ/HÃ>(Ú$™ÖþF\Ѻh_sHÔ—3`Ÿ­³`}}ÖÄ«rgïXGµÇ@níE©/_€–Ì+€—W(¼½ç 44r©g¾î íŒ„“üŒ5¿jl“$#½µ:=A´ÜSåØ|ì*Ú6®ï&Õ|ü*"åÎ8ý…'`éá{x·ƒªÛš¢ãWç!“€~­Ñ¯µ3\íÌ“œ…=c±ó| Ï’÷̳e¿þ5ïupE s;àö®¨íhŽŒ¬¬;õ{ÿz¬³^MÏYÇ‚ë+´j–¨xþ‡ƒÑT3JSï½øLŒìè†ñkâïOr-'¯'"!-Û ±i¢k,j?¹šû“­ûs^{þå Ù§EëÔT_¿5 Ø=ÆÔÂstÀUíùãRW}ùÞ—Ì+@ÞÛþ9sæàx¾>sƒ5/£ëï­`[n?új• ¬†$… sž_ël”„8…½êqÛÀ”ŸÎÁBž€Æfr4má‰)>µ°ïü|ûÛ5 èø2¦¾Õ–²,üòg²ÚÑkŸ¦ø2ø2ªI)óvs|Ú«.Ìð;/§úzTÇŒµqòZ oº„^mëaz†0ÇS_HQTþ:L$9VÒðéâõÈP𡱩nd×QÍo&S 9Ç}[ë_Çì~õáno†¥;/àŸÿ¢P×­ÞkÛ×ÿ‹EªÂBÏvÔ­GsGtkâz6È’+qñN–ï¹ÛwïA!Ï‚•L[Y:~}§?÷Ð8&}Ûé»Ã‘hìf†)>µ›€T¥%&v­…£Ÿààñß°á°%¶ýŸÎí¥ÉOg|øV-ü‘ˆÏמäOÑëõF8m”¦³^MÏYc39€¼Ð•T°è£pÊ÷H}¹/wÞEs«h]ßÍÕÅ„.51õ­Ú¸‘‚£'âÐÍŸè¢k,z?2­ýé{ýÛ§EëÔÜÖmvvP=˜{ä™`\«PäꪯÄ@Õלÿ¨ö·’ŽÕl“d2ýµ>[ÈÁÆ»Ö\ºyÆRL¤çצž8svrc$+,¡Ièï‘ûjtöÂ%ÈŸfcßÙÑÅ£úx8#äb¢sž¿Z û–™rÄæØ øÄu4kàŠ!í\pêÚC<Ω†žÎ€°?þ²Ò°ÿÜ¿èÕ¡!ú·qÁñ+‘ˆÍ±×ZGþq¤(¬ÕŒRU“íRPM‘ŠžMô®ÃÆÂòéqP(sp=2 ×#GMcþ•×D¶²ð7,NÖJíqÇoþÒ¸™gõ®›»½nDaÛ±‹xš‘¥ IB–ÂOa…düì Ñ<&CÆðÍ®ëX6²%>Ð90BúÓ¬ÛeŒ%3­}')´_Â2¤­ `ÿ‰sÈJMAºÒ ÿ Wc9Òåù^X´<ºž3C@ÕhXî^f5$ßHÆÙ[ÂÞƒ»µ‚g£Úð¬o‡?®Ý/ò)]û`Qû$iíO×þ¬©Ý }Z€®ñîå öxÍøæ” ñø\W}%~ª¶âüG :Þ>H n“$ý¯V‹>ú@î‡H1ÉYØvú.œ¿„L˜©-›š–‰4¥3’”vÈȱDu;s@Nz Ò%GD¥Ùìm,áf$¥jÙ¤ä4d(«á lp)ÑàdgF‘¢´…»}îŽ=glµÚªÛÛÀ]‡ä|;wÁ:ò=Aa$¥zH϶Š!ë<ùSººaÆðîP(•¸ŽŸNFâßÈh˜IrÈa¢s[À«&÷pS^¯Ðô…ûï£ïkfhÓÈ­^êŽ+wcñûXüþo*âåfȆ1”Ôw–c2d ÿ$šâèå(ôi—{xäÏÛHKMA²ÒÉù¶MÁ¾uí“ζ¹ãÎH‰GšÂñJ{¤+Ía)eÀXzþ^CÛs ë9“ +òþ¤i¹§Æö¨ß :¿jƒ¶/Uƒ©± ·îEãÊ»h`ü×ä/#Ki¬£×ë(Á·ð¹—öh{ ¯}ÖÔnÈ>-Z§¦:¶z~ð2.0«Ç7ªƒ‚5öSîG šNè^—ûìHÕ4µi>¡«»Ö™K~FºÒ™ÈÝ9‘À I dKêñVÈ”,¡„„Ç)Ù¨é`[k3¤&ZÀÂ&÷>ñI:Ì ³|G¯övÖø;Ö i°@Íj¹G,ñÉ©0—²`&e!îI6ܪ™b~ÀvÄ<ÉQÕb-eÀÂH³œl­u¨oCÕÿšnÈ:ö^NÀÍëWÑÌE‰uk¡çÍð™o=¼ócÒa¡±ë7\Ak“¿aŠÜd@5Ù$)mÕæ;x5·®G¢¶õS´jTÍÕÇÔ¾-à—­Àÿ¦àËÝ÷4?AùÆdÈjV·CÖµÿFP ‹G\¼þîÆX V†m¯bSr×ëTÍ ·bm+ä@†M/(Zú,òs¦O¾åæö«ƒö lan"ÃÍGO°%ì\»¬ôHJ%²aK)Y°ÕÙ¥ ûà¶‘öšçÍg𺡒·j;-â[xCöi!zÆ;~u8$)w|yÓ·²×>^ Št:gŽæNæîÐ"÷ß³ë>ÿ¾¼Tð¨†e“L4Ÿl¶ÏŽTµå_Πó%ªÌݱ” sd*Ì<…ú[>HFP"·¶CW“0ÖË^žMpãt"úµsü~ù(%ò¿SëéÝ7݇¤°À„ι§ Â.Þ‚2IÀŽ ñ˜ÜÕ =½[cý±[0Ê^®áŸÖõ°dÛŸ0R;K­^Gr†vÆp¨f)^ Æ+ån[CÖñM¿zØqÖ¢!Ièù ÏÎÂKFp#§äÐ|óPá +éùÌä^”\x»G)]šš†È‹1¹x.ÕLáѨZ¾Z5bñP‘» µI߬̌0¯_](”@ÐÞ?`"å`Ú»Ý0¦O;\þù”Oõo/ ¶ÃÔnîðíä‰ýùSS¼×Á+NDé¬WÛsVð¹1¤†‚ýå_®®£9~ý#WnF 9%J%£”![²D6Ì‘¦0C†dU¤õˆ^v”_Tõ“wTÃüã ª¥`]¥uTKÛøÕáróG0d]"¶> QmãÕ¤HG Ú.û€ž=Í×Pà:Pmñ]Ÿ„jÙ‘jÓd’¤qþÜ‹ZõÕ*!^éPèˆéY“úIRM >GY2ÞlZk›½‚˜96œ¼ƒðK·‘ (ómÄ«·ïaöà¦pªfƒÇO²±.ä:®]ýiJ+($v\Œ‡If zµ®‰ùãºB W¤#øÜCdKfHÎw: `kOÇbÜŽødLî‡I^‹®„$´Žýá‰ßÉ/¹½Šì%þ¾Ÿ„ã§~‡¹, –ŠL¤@óyÂh¥sáËØ4lö X Ci8¥,‘‰¸¤4Ü;{ÿ¼ #9’P iJ ­cÒ7†Ñ>PÛÑ k^F|B•6Xr ãz¶ÀŒ·\1k_¢Û«°]%À43½Z×Â÷£Û 5K‰ŸÏÄÀYX¥“ÁÏAá¢mºº°O›ª=^8c„Úz>ºƒ&Fÿ@ ÙJdÁ é’ž(,‘3(òú/B"jÚ5í{ÜóöÁ’éªO&IH2Qÿ´=›¡õ•á9PÝg_’5‰j<¡+i?¿äýíux…ÃäÙ±¶Wgmó)”ÀÚ³É9{²§ÈRš@ ¥’a‡,˜«ú¸ø÷]½™ €R‚‘$‡B²B¢²²`I’aïu9.Þ< +¤#ÆÈ† ²•&P*`-eh­cïå$\½Žê²xdï™á¦âeóë[ÇŸweˆü/6ÊH’’$ƒ±ò)Ò•¶€È‘’JÈk¤)­‡X"VÊ4!wÚÆ@ç–ü?J…‹,J $+«açuàìƒp’P×Èû.›hí[—}7¸xó,¬¥4ÈaŒL˜ÁT²„²Šôèú›ÒÆûÛëh(»°–Òa‚ldÀŒÌpKñ FYFP Ui‰L˜CrSEÛ>¨iß+´lÁ~òþ+ÁþJš¾ú mÓUŸÎ#Ðü_ßÌý·–J/Xÿl™ÿr— zQÍ"32†<û)LLÍ5õ`ì¬ HF&:_­(Ý`…tòž'M¼—ܪ²ëÖ¥¤÷ÁоO—f}1ö #!òy€Þ.©º5RBìÔDÈ3ŸJ/TJ2›[ÁÔÊåýc"­¤K0En(1@+°†Òm­m·”¯TÙukSÒû`Eß§K³¾èó»Õï‰TÚ¡$AS›ê0µ©®æ î!j iÏë_Ì_†ª ’`Ÿûû*¢ÿh?XºÏ]y®›J¥³ú­=Ô.L½‹ ¡óÕ„ˆÄ4nÖ¢¼Kv=üry— fTð]µ5ü{`DTé4n֢…PQ4iÞ_¹TÞeh¥1@míøÁˆ>)ÉÉU~;qŒTžN‡,ïô* ¶vv¸tþÏò¨¥Rñ4{·—w¥Šc¬üjÖ©WÞ%TiüYÀ… Ê»„RÇ1éÇ%"Ä%"Ä%"Ä%"Ä%¢RãÓ½‡þ™*1(UþS¦•w DEÂo"Q™ñŸ2 «–--ï2H‹ÈÈZ¿áááÈÈÈ@½úõðΠÁèØñò.­Â*ÖhtL,×®ÃG3?äiaÁ’ïð×å+%U[¥WQ¨Jª®O>ûr¹\mZàšµj³år|2ë }üK—ýˆn]:cPÿ¾°µ±ÁƒrâZµh^’5RU¿n=„_½†V-s¬"-=W®þÔ´4X[åÞÔïò•pÔ¯W6ÖE»‡yESÕœ7ü² }|}1p@Õ´FáËÏ?W=ÎÎÎÆšµA x{yaÌèQ01ɽ“©\.G@` N††ÁØØú÷W[‡B¡@ð–­8räRÓÒðz‡˜8Áææâ¿_Þ„tÿÁ#ðöꈮ½UÓêÖ­ƒq£FªËårìúu?.þõÀ£U+ôïÓ ÆÆ¹«õŸ2 CÄÑã'‘˜”gçê6d0?~ŒÃ!ǘ˜ˆšµjâýaCáêâ,¼Œau BȱcHIy‚šµjâ½!ƒáîî&ºyôŠyü¿îÛÛ·ï@¡P á+/ãÝ¡C`me…ï~XŽ7;¾ŽÖ­Z©æOHLÄ¢ï¾ÇÜY3alb¢w<wø¼iyG4yÿ_œ`h×¶ ~?{V wïF@©TânDš5ͽiÚÙ?Ï¡ãoª+''ÛwíÆ…‹—`dd„.½Õú–Ë娾k7.þuYÕ¾û×}ªå•J%…ÃïœEFFZ4k†ÁƒúÃÌÔ´DǨKZz:æ|5s¿ü –jÓç~³s>Ÿ ss­uæÕ¨íoOÛ8nÞ¾]{ö"::¶¶6èñ–^oß®Xc¹|ù2F¾?\ç<›ƒƒqïÞ=¬X¾ °hñoÙ‚÷‡ç.¼e Nç< ñqps}þ®Ìݽâãž/W¸=¿Ø˜XŒ3>Ý{À§{ : ãt¯³¢~ oei‰ä¤d899j'·ýù«ZuçêHNJR›ÇÖîù½ÛMŸ½­±µUŸ–]¬e ªCÏ:KÚýû‘صw"# =# “==ëáӻݖ-±ÿàaøtí¢«!ã)+íÛµÁ/7Á«ãëHËÈ@ýºu‘ž–¹\Ž?þ<Ñ#Gh\.9)©ÐÔÛ“áäè zœ^ˆOHÄœ¯¨M“JáÎŽy´ɺº8ÃÍÍ—ÂÃѺeK\ºrõëÕƒƒ½½ÁuõoÏoìh:rû†•¥è‡& åE‹-zêÞ¢=Œ…:µk=zÇ|Ï‹£“z{TÔ#µåñÍ7_ÃÕÅ¥XµV$ÂÚð•WpñÒ%¼Õ­«ÖyìªÙ!..n®®€Ç±aW­ìïSQêÈï§õг»ÆŽúææÈÈÌÄG3?Sµ7kÚ{¯ûànÄñÞ0U›¾ñ˜#++K¸)))jë.É ©UÃðÇŸçP¯v¹çÂCO‰‰‰ª½ »jÕÔÆ÷8®@»ââTç±ã ©8ØÛcò„ñptp€&¥¦uööƒ‡ÑºeKœ;¡ƒªÚôÕ©¦qÔ®UãÇŒ†R©Äß×o`Ãæ-Xôõ\áúàýáïbúGÃÔÄo¾Ùvvv¸{÷.¶nß®ú ©³·V­ ÀG3¦V¢³··ªÎÞÞÄŒgí«ÕÖÑ«WO|ÿý˜àïww7DFF"8x+fÍšY¬ÚË“ð[ø^o¿…a§qüd“’!—Ëñß½ûX´N5g«Vضs“’‘˜”Œm»v£GË)¼(*JùeeeÁÜÜf¦¦HHHĦ-[ÕÚ%IB·º!äø ôèÞ FùÞëOíÚµpôÄI<ÍÊB\|<6mQ?Ÿkme…¨˜˜K»¶m±gß~¼òòK€W^z ûFû¶m´.Ó¦u+ìØµIÉÉHJNƶ]{ÔÚ=[µÂŽÝ{œ’Œä”dìØ­ÞîÕ±6oCTL rrrðèQÖ®ÛPjcÔ¥q£†Èxš‰ÐÓ§afj†Z5Ÿ¿uÕW§>šÆ±vý/ˆŠŽ†B¡H%pãøî5°xá"\½v cÇû¡O¿þX¾b%:yy«æ6tjÕª…‰“§`âä)¨S»6†¾34_ûP¸¹¹bÜx?L˜8 ­ |FÒÇ×íÛ·Ãܯæ¡O¿þXøíbxwò*víåIøÔ¹zu|8yöî;€‡#++5kÖ€O—Ϊyzt÷Á®={±pñÿ­Z¶@÷·|Š_u•gš®ã[µl)†};vïÁOëÖ£š­-ºué„K—ÃÕæ“I28W¯ŽvžžjÓõgØàAظuŽ„ƒ­­ |ºvAøµkªvŸn]°ø»ï‘‘‘Y"²x¶n…¿îÅËÏôå— [.‡gkí2öðé†í»vã«ù‹`dl„®;áæ­ç÷LïÑÝÛvì¼orÛ½;vÄÍÛwTíÞo¾ I’aõš ÄÅ'ÀÙ¹:|{>ÿÚ`IQÛ󘧋·6mÙ†IþãÕæÑW§>šÆÑ¼Y®Y‡„„¸ºº`Ôûï ŽJ]íÚµ0ûË/´¶›šš`âLœà¯±ÝÄÄS&OƔɓUÓç;—Édèãë‹>¾¾%RoE º/|dÜc¤ÇÞÅ¿—ø‹ôz\¸póý¯ÔÉ|Õê5híÑ žº¯v( e5FC=|ô?á«ÙŸëŸÙ@mŒ¥¡÷Àw*í=‘N‡„ß”éêžH£‚ÃÒ¹>¢þÜŒ„H~¾"R*•8óûˆKH@ëVå{ª¡>Gㇴn®\ ‡"'-Z´À‡N…­[¶ú IDAT­Æõæää`ã¦M8zìÒÒÒñî°a8 ? ;;kÖ!4, àíå…1£G©BN.—# 0'CÃ`llŒýû«õ­P(¼e+Ž9‚Ô´4¼Þ¡&Nð‡¹¹y¡:òÆ–ŒúÖ¯iüúú̳ÿÀAlݺ‰I‰hР¦MŠºuëªæÏ›÷ÒåËøé§5¸yöÕì1lØPôèÞ½Pý#F¼ٳQ§NÀÑ£ÇЭ[WÀ½{÷ðåܹø9(H­o}Û/;;«vê4ŒÑ¿?¬]¤Z^×öÕ5vzñk‚‚ÖamÐ:¬ ZÏgÍ‚‘±îƒ^?8:8ª®Z‰æÍ›ÃÌÔVVVøàƒ…vÌüBŽŤ þpswƒµµ5üÆWµ? ?899ÁÉÉ ýýpüäóï¸;q"·ÝÑQÕžßÁC‡0iÒD¸¹ºÂÚÚãÆŽÁ™3g ÞVúÖ¯iü†š2i2\]\`nnŽAàÎ;ç322B|B<’’’àì\Ó¦}¨q>\ ¿ 8qâLMLT/†W¯^EkV…–Ñ·ýŽŸ …߸ñptp„£ƒ#üüÆ«µwû•µR=joo.]:cã¦Í7v,ìííõöç\½ºÚãnÿƒŸ‚‚pçΤ¦¦ŒdÚs?.î1ÜÝkhlKˆƒ›ëóÃyw÷ˆ‹S=Ž+Üž_lL,F«6M¦£–¢®(<~CÙ;<ß¶fffxš•¥q¾9³¿ÄæÍ›ñËÆ°±¶Å?xz>šlѼ9V¬\ 7øf̘Žà-[Ñ£{wܸy3¦þM}Û/!>®®.ªÇù犿}‰ÊZ©€»wïâð‘Ìþò ¬X±Ú·ƒ»»;€Ü{,kRpú× à½aïâ‹ÏfÁÒÊ éii0h°ÖuVwrÆ£GUçÿòsptBTtêÔ® xôè!œTíŽNêíQQÔ–wvvÆ7ß| WˆÐ·~@ûv1´]Ÿ—_z ³¿üJ¥çΟǒ¥ßaëæÍ…æ³°°€««ÂN‚©©)Ú¶iƒ›6ã÷?þ€››»Æó¾ú¶Ÿƒ£¢£cP«VÍÜöhõóXú¶oqÇNTÒJíå=33‹/Áÿ}ú)^ïÐS¦LÂ×ßÌWÙÙÚâþýHƒú±´´„¹¹9ÇÄ`é?èœßǧ+~\¹ ÑQQHMME@` ª­³·V­ @\\âââ°2 ½½óµ{# qññˆ‹Çª€@µ¾{õê‰ï¿ÿ÷ïGB.—#""óç/4x›è[¿! ÝnÚ,X°÷îßGNN@¦ãO Mk®F×.]:wÂ+V¢ukóëÛ~½½°:ñ ñˆOˆG@àjµv}Û·¸c'*iÅ>ÕtIAÈáCXþãèëë‹×^k h×¶=ŒÂ?®ÀŒéÓ0dÈ`L6 iii:OÌøpW¯Æ×óçÃÑÁƒÄ™3¿iðÀÈÌ|Šé‚ÌÌL¼7l˜ªmØÐaøiÍLœ<ðfÇŽúÎÐ|íC±* ãÆûÁØØ À_—.©ÚûøúB&“aîWóƒš5kbÄûà ÞVúÖoC·›6í:´Ç¼y_!&6µkÕÆÌO?Ö:¯GëÖX÷óxyyȽj põOðôРú¶ß°¡Ã°2`ÆŽËmïãë‹ËW®¨Úõmß⎨¤IuºMTz ŸÈ¸ÇH½‹³ ºázøeœ;‰ñ“§ñçë¨ÔDDD`ÎÜyøy½ö«*ˆ òéޣȗ1‰¾àæå`àò¥ð›2mg†ÀÒ¹>¢þÜŒ„H~•“ÊV@` ‹€ÀÕhß¡}y—D$¬T?D"*ÈÅŧL\.Gûöí0rĈò.‰H”ÊT¿¾}ѯoßò.ƒ¨D0@‰¨Ò)ͯg”ˆ*•Št?D""Ä%"Ä%"Ä%"Ä%"Ä%"Ä%"Ä%"Ä%"$üM¤Óa'õÏDDT tôê$´\±¾Êé7ezq'"*wJ¥Røw‹ý]ø¿¯\Ò?QÄs DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚ DD‚Œ‹³°R©,©:ˆˆ*áíèÕ ×Ã/—d-DD• ß b€ b€ b€ b€ Òù)|àò¥eUQ¥£5@ÇOžV–uU:Z”×xéÆs UÔõ70rÔøtïQªë)íþ‹£"×FU´œ•ÖN¾fÍZŒ3 !‡•Jÿ†*Íc@Ry+r€útï¡ñ?C—}‘ii\DDÚxz–hŸ"Ï_ixY¾8¼è»¤™ÐwáËû¨†ôKKO‡‰‰Iy—AT¥ëט Z¶|96lˆ·||TÓ‡Áí[·±ÿÀAÏ_ÉóBا{ø‡»v!>>Gㇴn®\ ‡"'-Z´À‡N…­­ÆõútïÑ£GaçÎ]ÈÉÉA§NÞð7ÆÆÆZב5kƒðöò˜ѣT¡£¯O…Bà-[qäȤ¦¥áõ0q‚?ÌÍÍ5®3ï—«4?ïßúú¼tù2~úi îGÞ‡}5{ 6=ºw׸= ®ËñÜFúú̳ÿÀAlݺ‰I‰hР¦MŠºu럡õ5 ófÏF:uGC·n]÷îÝ×sçâç  µ¾år9q24 ÆÆÆп¿ZŸÙÙÙX€°S§allŒþýûaíÚ ƒ¶½®±Ó‹­DÏNð÷GÈÑ£;u z* GÃDÕ]ÈáC…þï^Åòeß«vÚ¯¾þ}z÷ÆæM±ñ— prrBPÐ:ë¾ô×%¬\ñ#VáAäoÙªs›ƒƒqïÞ=¬X¾ +–/Ã݈oÙbpŸ»÷ìAxx8-Zˆ ë×A.—ãç ¿h]§®ñÚç¢ocØÐ¡Ø½s'þ·d nÞ¸©±Më2d¼·‘¾>ó\¼x‹‹Û¶Á³µ'~X¶\c]†Öïéáð«×qqqX±jÒÓÓW¯³uëBËoÙ‚"0`V,_†ó.¨µoFLl,V®ÂÊËqù’úU&º¶½!Ͻ˜„TÛ9Pccc|>k‚‚ÖamÐ:¬ ZÏgÍ‚‘±î]?8:8ª®Z‰æÍ›ÃÌÔVVVøàƒ…vM}89:ÂÉÑþ~ãqìÄqë8~24w''899a¢¿ŽŸ.Nç:âãÔ–qw¯Qh]}ÆÆÄbô˜±jóË ÔXpúèësÎì/±yófü²q#l¬m1Áßžž…Æ41d¼E­7½ÃóçØÌÌ O³²4Îghý-š7ÇŠ•+äߌÓ¼e+ztïŽ7o`ÆôÂ_òˆ+<¾üâãàêê¢zœ^À°ç3¿ÆÍZð›z/ˆñ“§ÊÃ<: óÉÐ ëïÞ½‹ÃGB0ûË/°bÅJthßîîîI’4.Spú× à½aïâ‹ÏfÁÒÊ éii0h°ÎõFEG¡NíÚª;:9é\‡ƒ£“Ú2=,´Œ®>ñÍ7_ÃÕÅÚ\§¶ñÚçË/½„Ù_~ ¥R‰sçÏcÉÒï°uóf}æ1d¼úêÓ×®¡õ[XXÀÕÕ a§NÁÔÔmÛ´ÁÆM›ñûÀÍÍ]uN8?G'õñEE=RkwptBtt jÕª™Û¥Ö®oÛûõðËü¶Þ @ß‹¤Þ‘Šò¤ÌÌL,Z¼ÿ÷é§xíµ¦02’áëoæcéÒï`fj ;[[Ü¿‰ÚµkéíÇÒÒæææxƒÕk×ê]w@@ f̘®úw—NtÎßÙÛ «Và£gˬ DgooƒûìÕ«'¾ÿþLð÷‡»»"##¼³fÍÔºN}ã××ç‚ 1ìÝa¨ñìIV„30†ŒWCŸ?mŠR›Ö \!Cr_8»tî„W¬DŸ>¾çïìí­ö|­ ,Ðî…€Õ˜þì´A@àjµv}Û^ÓØùm=ú^ÛõŒËü}}}ñÚkMíڶã‡Qøñǘ1}† Œ©Ó¦!--Mçi€NCàêÕøzþ|8:ØcÐÀ8sæ75µhÙ&N‚\.G'o/ }çó: ?­Yƒ‰“§ÞìØCßjpŸ}|}!“É0÷«yˆŽŽAÍš51âýá:שoüúúlס=æÍû 1±1¨]«6f~ú±Îõu¼úúüiS”ú=Z·ÆºŸ7ÀËË @îU«‚§‡‡Æù‡ ŠU7ÞÆÆÆ8`þºt)_û0¬ X…±ãrÛûøúâò•+ªv}Û¾¸c§ªIªÓm¢Òkø|DÆ=Fzì]œ]Ð ×Ã/ãtØIµóžYþËY*rŸTqDDD`ÎÜyøy½î«;èÅ–—ƒË—ÂoÊt´Kçúˆús2"ùUNzq"1!1±±\öÚ—wITÉ•è…ôD™‹‹ &N™¹\ŽöíÛaäˆå]UrÅ ÐÆÍZ”TÅòàQ”þ™t$ _¹¤6­¸}¾ˆ4mÇŠ¤_ß¾è×·oy—AUH±@+Ã9R]´]ßTþ±•%]Û‘¨ªâ9P""A P""A P""A P""A•*@õý*85œˆÊR¥ P"¢Š¤\/¤ß¶}Ö­[‡‘#Gbð åYJ‰ÉlkkƒW½ ?¿q¨QàçÕˆ¨ò+·#P…BÀÏo<ö<…BQ^¥”¸¼_.Z³/½Ô‹ÿ¯¼K"¢RPnG ç/\€µµ5úøúâè±ã¸pá"Ú´y~I}÷¸Ñ×^ØÚÚ`ÐÀرc§jš!÷RšÿâKüöûïXðÍWرmÚµm‹–/Sͯí~G666èØñ <¨~£ƒ‡¡s'oX[[TiV.…Û·n£“wî{{{ãö­ÛˆŠŽVÍ£ï7úÚËSÞ}¢ ŒC‡à³Yÿ§j3äÞ;Ó>œ 7w7˜››£¿~HOOLJS¦ÀÕíù´[7o©æ×u¿£~}ûaïþýÈÉÉäääàÀƒè߯¿Áõ‘fåò~ßHJNF/_õ_?pàÆŒ @ÿ=nôµ—§Ã‡ T*Åÿûþý÷_Õ­" ¹÷ŽƒƒƒêßffftßwH×ýŽjÕª‰:uêàôogàý¦N9ƒW7†³suƒë!"ÍÊ<@³²²qôè1løy½Úýg¢¢£1uê‡xøû055Ñ{}íåM’$¸¹»aæ§Ÿbò‡SѲE XZZt/¥¢Òw¿£þýúá—_6ÂûM/ìÙ³“'MRµ•F=D/Š2?Ô EÃF í°n®®xù•—ö샼{ÜÄÅÇ#.>^Ã=nt·WÎÎÕÑ´Iœ ðüÞ;÷ïGB.—#""óç/,Ö:òîw‡¸¸¸B÷;òhÕ iééøuï^X˜[ॠTm¥QÑ‹¢Ìô×ýûàÛ«—ƶ޽zâ×}¹& :nn®7Þ&NB«Vê÷××^‘¼Ý£̽=H__´oßs¿š‡>ýúcá·‹áÝÉ«Xý: µjÕÂÄÉS0qòÔ©]»ÐýŽú÷ë‹UTàzÛÒ¨‡èEQ¬{"5nÖ¢Òÿfæé°“ð›2½ÐW…±•%mÛ‘¨2ã=‘ˆˆJ ”ˆH”ˆH”ˆH”ˆHP±/¤¯Êwc¬Êc#¢â+V€J’TRuT8UylDT2Š Uùš¿ª<6"*<JD$¨HG GBŽ–VDz½åÓ­¼K RS¤öÑÇ¥UG•·tÉbn¿bXºdqy—@TH‘ÏòûáÅÃíGTuð(‘ (š4o‰&Í[–wD•J‰ÿ"}ÁÐÌÌîîîèݳ'F}0&&&%½ÊR‘7ŽŠx9SNN|Þî…èèhü²>­Zªoó¿.]ÂðFÁÕÕ!÷ÃÈȨœ*%ªÚJíôï+—ð÷•K9x_}Ë~\ï¾ÿ¡´V÷B122Â{Ãr0yëö…Ú·lÛþî0†'Q)*õ·ðNNŽ˜ùIî§ÏVMÏ{˸9x º¼ÕM[äþ¢¼B¡Àæà-èݯ?<Ú¶G¯¾ý°qs0 E¡eÝ·¾ý ¥g[ôêÛ;víV[·R©ÄŽ»Ðoà`´n×½úôCð–­P*•:ëÈ×þß½{x­¥<Û¿Ž´´4U{NN:vꂦ-Z!"â¿Ývº ÐVVV9z IIɪé‰II8zì8¬¬¬0p@Õô 7¡Ió–x­¥¼ºtÅìy_©£ Moé N3dûUeesTÇõ÷سs;®]þ °)x ¾Y¸¯·oÐc!èЮ,ú›·l-´ì‘#!X³:GDíšµ0{î<ìùu¯ª}ëö˜=ï+4jø N Á[>Ýðõ‚…ؾs§Î:ò¿mÏ;’®[§:wê„ôôtìv{øí÷?€7ßxõêÕ-ú¶dcmýú"++ »ýU5}÷ž_‘••…ýûÁÚÊJ5=-- {wïÄ…³`êäIرs–.[®sú¾ÎZ”íKT•z€ÆÅÅcáâ%€·»w/Ôþá”ɰ±¶V=Þº=÷íçÈïÃÆÆ£>زm[¡e?þh:œ«W‡““#>þh:`ý†_T훂ƒþãÇÃÆÚ¼?°qS°Þ:4;zd¡Zö8ñþ{:—- ï½; F2¶ïØ ¥R ¥R‰í;wÂH&Ãðw‡©Íë?~Ô¯33Sôyv;éÐg7ðÓF¦'@‹²}‰ª¢R»­qÞ[=33S¸»¹còÄ =òƒBóUÏwû]ˆzpttTûÿ¨¨èBËÖpwWýÛÝ-÷ß‘¨¦=xðУ·úýçïÝ¿¯·Mš6i‚6žž8wþ<._¾‚W^y'N†¢QÆhÛ¦ÞåKZ wwtëÚ‡CBpöÏsP*•¸?Ý}|àîöü>ñáW¯bÙ+póæ-$§¤¨N‡ÄÄÄkýEÙ¾DUQ©¨è§×...¸wÿ>âããáââ‚øøx€››k¡y>z„zuë=»/|­š5UíÎÕ«ãÁÇ8qô\œ…ê)hìè‘8wþ<¶lÛŽÚ#33ï/û£Ï<#Þ‡CB°uûvÕ™’F W›ç£Ofâá£GX¹ü¼Þ¡²²²àÙþuµóÊÉd2ä(P(Édˆ‰-¶¥±}‰*“ whß>¹G3ë~Þ€'©©Zÿ3`È A…æ]¼ä;<Ž‹C\\<ÿo)àýáïªÚß{ö6vÉÿ¾CbRÒÒÒpúÌoë7AoöÕªä;¢€íÛãÕFpäèQoÙŠêNNx»û[#-Í^{ -[´À‰“¡8ŠV-[ⵦMÕæ‘ç䬭­ñôéS|¯çÜ'Ô­[rìž@VV¯^Ű¡ï”ûµ­ŒŽœœäääh<ûí‚ùhØðŒç‡>¢~ýúzûüjöl4jØŸ}þ%Þ1­ _d_œíKT”ø[xCߺk›ÏÈÈãÇŽÁø±côöÑÇ·7úøöÖ9ÏÛ=ºãí…?¼ÒWÇ;ƒáÁ…zÀ§[7ØÚÎGVV† ¨·ÎÒÖµsgÛ½µG+ìÚ¦~CÁ±\¾E‹æØ¹m‹Ú´ü/Nyôm_¢ª¬ÂVtJ¥aa§’’‚ÁÀÎή¼K"¢rRj"UU>=z"&6­Za‚¿_y—CDå¨Rhy~?ýèáƒå¶n"ªXøžˆHP‘Ž@ù«àÅÃíGTµð–DDùå®| OD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆIИIDATJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ˆJD$ȸ(3_¿\ZuU:<%"Ä%"¤ó-|àò¥eUQ¥£5@ÇOžV–uU:ôtØIœ;YÖµU*…T’¤ò¨ƒˆ¨ÒQ PKçúh;3¤¼j!"ªÐ,ë«=.tZp""ÒL Qî(Ï:ˆˆ* êt›¨,ïBˆˆ*“{GWHÿ`ìɺÜîãIEND®B`‚wxglade-0.6.8.orig/docs/html/ch05s02.html0000644000175000017500000000543212166606327020200 0ustar georgeskgeorgeskMenu

Menu

In the menu properties window click on the Edit menus... button. A dialog will let you edit your menu. Use the Add button to add items to the menu; enter the label, an optional name and help string. You can use numbers or variable names as the item id. If you use a variable name, you have to provide extra code in the generated source code.

Choose the type of the item: Normal, Checkable or Radio.

You can move menu items with Up and Down buttons, and you can modify the hierarchy of the menu with < and > buttons.

wxglade-0.6.8.orig/docs/html/wxglade.png0000644000175000017500000012664312166606326020376 0ustar georgeskgeorgesk‰PNG  IHDRØy*Ê„sBITÛáOà pHYsÄÄ•+ IDATxœìwXW×ÀÏlï²ôfGcKQì%*Ø5ÆD_‚½Å|1‰Á^b‹ÆX£±÷Þ»Æ R¤/½î.[¿?Æe˰, ‹0¿‡‡gæÌ½÷œ;sïì™[Ͼ3º[y{ÿ/@Ð@¹ºu¶V«U*•4íû_–ÚÚ‚rÎÿ;ù­ -! °çÿ‹xöÝÇ­´µ1µÅíý¿ü÷ï¯d2ùS挛bksÊÙ¿w'ꋎü–¨›“ý{wR û¸•i…Ŷ6† ¶`ŠÜ;»´ ¯`Ü„¥JeksÊiÖ¢ ÚBÔM‚FK³m(葺Lj[Sê™\nkŒ@ÔM‚FK…#¢hŽˆF]œñ¦¬ S«6ëË!‘éBg®sK ‘k×V6£L^V#{0»4šÔ”¤¼ÜZmNx‰,²·ws÷"‘HV1€ !Q“âd«¢hu½DÝlä4æZ€µˆ”êJ©a]z@8@%Kð“Wöø†˜H³´.†Ss«ä%¹oî¥E³}j×V6  ÷ÕuaÚØ`öƒ4f zœ™žBèЃÉb™c˜L*Š|™œ” vq3'.Ž"•’ø>9þ]¬ƒ“{iI‡+ ‘'{AÄë·‰o#¡O'¨YŽj‚®%>-ýõ®"} ¢ÅÉ0îÉ 7 Ô A Y󢨧÷U\&Z Ú5wÂŽQcÌÔ[oë&ZtÙlVŸî]|[6Ó(ËâRólÞ|ò&â VNßxöäÎe…B^÷e›Å¤»‰…nbÑÍÇÑU‡Æ¥1×̱¤TuïÞ£Ghxx¸ dxõÈ̶®Búw»_ÇfHû´…kz*þzT^ göžÉ¾©yecþˆø9È{P;û—ߟx’£?ÏîçqþEöêóI“{º¹ éGnEEFEÉ54µ–ô">'2AbGVäi¸¥Z¦ÎÍ@Aи-”*ïÅl½–"UT…nñc1Œ‹ G1Ò£w»-»±ºÚõ¶'ïÔ$`^Ȥ¯PcX¦ôZöúÀ4‚´A%F]鄸˜¦-Z qá>Ÿ·f3éáOÞKÝÄ­½Ÿ½NL•ä ¸¬îZ–ÊÊ®?|ýI+Og»ˆØ”ÄÔlhâîØ¦™ÛûôÜ—oÞ·òqe3é·ïÿwûÎ=:‹M&S’S3Sä²R‘ƒ‡+(Ï5 (h\­JefNaT\šªb®§‹}wG6“^*+‹{Ÿ©ÑÓÅÞÇÍͤËÊ ©Ù¨%0¤W{8só¹Ñû&´s,-.Dó³3Å®ž0æ$ˆˆMiæ!f2hh\Séã_ÒÅÙA/_ER¨4‹ÍEÄQÄ£RÈÏŸ¿ËÊççwêÐþË/»sXÌb©<âmr^a) x¹:x»:°4Y™"15'1-K«ýÁ—o’›{:1èÔ©<:>Ïez»:P©ä¢YÄÛ”‚bi•¦êZR\˜ÇTêÜ´¸§¹¢QºR\Aô>÷1y¥f+4JWJ!â¤mS1TüöÀ©‹·ôŒ1¿EÄLj¯nb EW©Tߺûзe3/7ñ­{<|Z éÕ*—ä* Òóè¤fžNl&]*/{—œõ>=Ó‚_Å0-XxÔ¿G«Ï^í‡öî°~ëüÚ*ä±[7uåq˜$’[PŸœ••WTÝŽB§Q\…®b‘ˆÏV«5Éé’Ä·‘>-Û¢WM½gôn¹ðºi6æZ€uÍX⡇¡¡¡7ŒEô®pD'Ç/½Õ)UÏV"ìËx#kç᱉©M©.S|é³û¹gfå•hY3ú¸Çg_¼qß…ÂêÚ¼ÄÆ½ÓhÉ…Zn¡†£ÐRhˆŠ‹”’˜FôÆ’ØtÊÌÿi‹3:ûºÿo@{ºV¾üRV%ƒ²%·!#É0.Æ[W*ÉѸ5Á˜ÍÃ÷äœTî…LÞñ J^¾^ËÆÉ`‹N²(_$´Q‡¬¼"oWµ4W!׺8ú‡¦-.Ìmê!€7ocÞ¼¢PÈ,:¹MS×´´4žÀ®uS×ÜüÂcÇOpvý»øÀÓgOÉd²ÈÎ/r Ó EYa~. A>èBýf Rɧ¯Ü‰}ãÛ²Ù€¾=KРߥå“Hdg;ÿ©™Ù‡ŸQ*Ëôí¥ÑÇÍÁ¯¹{Brúë·Ûµiñyçö¥%…9EJ,o^=öýä3Ãüºz6ùp‚€ƒ³›°âs Q–ž¾|;#-Y©P h*}/{|ÕB ßsy›C¥RÀÅQX*•''';8—wÛ5iâ}ôôeW±Ý€¾Ý[û8]{ðŠÅæú¸9´nê—~÷Á§Ú¶÷o#“I >¬¯EVKÏ^»Ë¤j‡ èó™“„”Ìn²éÈÐAýÚ4qºù(ŠÁb㛪kI›–>©Y•~jRœ¬U-HÁPˆ½…àÔÅ[ ßbZo}«›¨(ºT2ZÐf¥¿W”(Ý’„_øLäÊíÇùÙ™½º}Ö®¥giIQ^‰Yå\WË‚yÓàÇ_~eqxL&«z*¥Bä ÆIªck/“~ájxì»'GûÏ?혔œÂá ªu£ÜD®b‘½€£ÖhS3²?yö::F&“‘¤¤¨ÜÃ6õžÑ» NžÍõAµ,Áb5€ZP‘ ú!ýU½èò8¡|=^Œ‚O›ð‹¥ ?±3·'’’9$CS²âdt™BµpDËå#½¥eê½§ïPµ2 ¢°) •–j8Z®è·uº¶ðó“¿ô)–N³C¹ö½÷2sóòŠUä;‘©Ð¹™HÏ„D&!HuÿÙ0.”ÿBéÿéÉѸ5ù3j3æ…Àî)þT£6}šHeªÿœË!¡“‰*§c4q]‰^,A²ó‹@ì ÊÊHrñd2¹—{fJ¼Ë€×Q¯KŠò òrîþY¦PtíÔ¦}+¥J}ðȉâ¢|•JI£Q  ?_`/Ú;±ØÜ!½;ÐuòØ!\¾P7ƒ‚ qï%éé*-&6\ì“ß½7G8wþ¢D’YV¦ºýà‰nDo7¸|åj~~î˨7ÐÄÝ)+#Aó·_. [™›Q›…˜@ÏôøÌÙsI ± &›Î`z8‹L¥£Z: ù<ˆFg BB±=ÿ]bBB¸|!ª÷ò•ë9Ù™ÉÙ ðÞE¿T«Už.öpíÚõ‚ç¯bÀÇM,I{ÿÁÚsç’Þ½ÉÌ.@OO<)ÉHM“ä€HÈ‹y¡Q«pLÕ³¤…·›žñ†ÃÐX†EÑÔS¨¹Æ*SÀÞ¿0l`Ϧ-ZãÇ2Z¹ /™¾ £‰W™ݢˠÓüZx@dT´Z¥R*†%ÙM,Ä/H'O‰ŽPjáÐÌCœ™Šà–sC-˜U<¾J£ä–p¢Õ')*•¢VkR““4ufVîɳ—RߪTJ½\õøû3¼'íZz:¹ïS¶íÚ{àà‘¯^©Uj6‡'°S(T4Œ©÷ŒÞMÐK¹1ׂµˆèÔ#Ñ_&—*ÕoWÇŽ>i *éï3§ èÔÄÎÏ«Ti’3Jµ<B˧]{™1ä3O¸ò8¶¤¸°PÃ+ÔòòJTŽ<ªˆËz#cª€† ¤n+_Þù¥´¢¾£ò.W ¤Ö®œÉÝ›;ùqT´è ¸,=«¬ÛgÊa«Õ886±ü%dgÄζpü;ᨿó m6ž •´©6=|!ÉÀ°¼©Z­ñöô|—H&“N»4vô0W±£HÀQ©Õñ‰‰B{gAerââSÚ¶nž¾ÈÊ’Ø9¸íÄe “NåñxlŸÎ`"éˆAÝÚ@ô‹G­Û¡cIÈã´ðrêûykµ¼ðy¼Iš“›7‹I€ŒŒt;gî‡$AH,¦OÀ̶‰ÒÞ¿Ú‰é ¦G“V%E¨XÅÍÓ ST\âîàbçèÂæò¹l–©ôñUWJÐjµL‡Jc IÄgÓ©”WQ &‡Î(_q¨°¨ØÝÇ™/rD *.Ì—•” -ÞÙÙ'7ƒ3ðù¼ôäx‘}yãjQQ‰»‹@TÞœ#‘HÜ}šÛ;º ‰åçKKKpLuÛëZÂdÐôîU ¥O\4•NQ´H{%-m|ÊÇ®¾>t@ðkâ•më㨛kW.F+•—=yuåú-&‹½ætK2‡ÍÜ‚”_P(vñ¸51%#· ”Áæ¡Þ?¸,Sï½›@ÔŒù€±èr•62¥¸½àçÍcÓ‹â’RÒózÚZÀ¢Æ$I”ju1°T@õvd èèž‘[LMïMžÅ$%d2K}çmáÈNöýš=¾™­J;§ˆHE’ÎvÁ„órâÓÖŸxþ61N…-sÃÆ€Ê?N4Ù"7úïÝXhË„Þ`U´µÁÈБ—·LÔS6OÙ‰2úïTrl¢ÐÐfã ÖÐì[ª²‡ô:1ûÝÛ×h±Óxf• Ðhµ9Åb;þg>ÉÊÉyó&=CÒ-à3–ø^©Tq"Îç²Ú´j’›W V«:¶ó‹ˆˆfòx¡$§ÐËÕ¾SûO3 H•WOÉÍÊÀ>•Цˆö­<˜ ÚÅkwbßÅ#Zíœéß!RV&W)2¹‚Ãbð¹\¾È‘Ëð8l݈r…’Å ­\³A¡R3Y@âÂ|µJY&—1˜,7Ϧfݺʽ³_hÏæòI$NúøªuÓGCòù\2™B&“q¶ç—)”ññ öb¡«—Sñ6×j5Z^¦d3é,&“à …B((,’I¥ee2=kžjµjZcªž%²2%¢_7+§ÖÞ`‚׉ÞhhqªÁGB ë¦q›Ï\Gx˜JÚø8Úl<ÁzV71ü²„Íå1XP+tGdïˆùÁ•JrUI$ðEŽ\¾­byù2iI™ ¯œjÁ$º ̨­)™yáá·HjY«–-{õhï뙕§ãÙ”sñnäÛçeå+îäféº;©’‚بgeÒâÖ¾Í?ñ÷ïßó µZ•WüâM ç=£wˆZ€Qu‹Hh¨¾¡a§Ú,ñZ‚ýa|i{/¾»“Ý‘ë/Ô@¹•ܯ9Ä&¦©€ª:•ÆX:ÌK£…=gÒÕ¼oúMüÙ‹½1ZåïûYŸyÑ:¶.Õ$z¥Ì(R9ò¨ùÐшÚ4e>JÐʨUæOÁ©R ¨îX,!ÆÝâg4.‚À‡‘ 5#bÔæ©»" ¨î$€1{ OµÙh‚8=‚æ<èýг¶šµh£=þm´ž]wG/X^‘TlÇwuq¾r=œJ¥%§gÖ¡ ¼£ÒèL&›Éb¶oå¡ÕÂñÓçT EȤñÃþ8ŠB¡Ä§f³¤n_p^½.QQJ5ƒN­¸ €TèB*:Ì@’‘J!“¾¨˜æ§ÕjAó>=·uS×Aú½z›Ìa1|›8ëF|Ÿ‘ÛÊÛyЀ¾žD€‹³ã'~­O]¸ZõÀ?¸|?ÊÔ]Å@*Æ©`§ …B!Nú8—ôîdQ©œÅ y{z–¨Tè«ÉÉžŸø>@Ë †¡^@ßÝ$$-« ¹§¸[×/’³‹Ñ9ÀOŸ½ “I Õe,Sõ,yŸž«ßClöäÃø·ÑØ K´8Æòeã@ç#ÁhQ¬Fm>{ù6jatbޝ·½Q›M$Xïê& ‚_h‡‘Y‡+°sd±ÙØU¬0TYõ/¯b>ÎððÑ™¤Õjp ¡…RM£’í섺 ̨­|=™m\\l†$ä2YlÔ³¶¨Ôc`Q¼šµ*)*ÿ´ÓÓ>Í ós’%‘¯±ÙÌ6¾-üÚ´NI|ëÙ¤%L¼gônB™²ÒtŠÆ\ ªn1œÁ–0Â+D&¢?J, ÖhbbãdZÆõ7Å{k(dR\bªJ„:¯¿«‡}÷Å—y¹¹ZÞÞkQÁÛýÐßiáùü’2dÞ¿Ñßub}Ò£OG AJÊÔq™Òܬôò›Y¡dÙ¹Ô}…ÓGõ,(U|”ÝǨU•³þõÞ2ŨÙèÜZtJMâÖcz€ê‡Ñ©˜Ð½8þ¯9ºr›ž~ø˜¤œ¸·¯u”>#xnA)¨Õš'OŸ°8I^±Z£!“H1oßr¸|Þ¦©+›I¿rãnzZšÈÞéÖ½Çýzvméåø>[Ž È­‡‘ö’o«ööv$„¤R« ‹¥qq±•?‚DĦz:rÆó•L^–úa 3šU#Iómî3| L®HLÍvr±ˆÉyɉïZ·h2iÜh‰”_,}óî=Á9”78G={à×±‹©«kƒNö?œâ¤_¥jŒì¼b';žÛ6×ï<Ñj5—A§FDF1˜,ƒE¥ÑqÌHJÏÍÍJoÑ¢ù§ùr…êñ³È‡ŸrùB2…ŒKïÔ”©^ÞÞz–$gêOþÔ+Nú©Ò]üð\.åT­¸Æƒ™‡q½4Ó™œ‚ ÍÑ[ë&ÚÑÙݰÈ}0¼B{•)2*ºg÷;¡P^¦¼ýàɳ/ù™B6£œÐò.%ËÓ‰ÿãü¹påÁk=Kp’JËÊoáãÜíÓ663+÷ä©ÓrY©´¸H`§ßöàæÕÌDfØ\>›ËW«ÕÒ₼ˆèø‡ÿ=W)öŽÎžç=£w®?Ž1xNU-¨Å1"’§²îasR4Å`Ÿ/']ÿ¬%9Žê­³h«.¦ÿsé…˜”%fŽEÁÃè‹HžY”¨ñÌQrÿz˜ëøèÔj «€¢„e0Az¬î@Ž ‘*[°7Á ÉR#¤R-û›ˆXW$A>©d¤ÁÂç…4“;Ò}xÅ’ÈºŽˆ¥qMÞ530¥W¯ìè qôÖv?tó–úß^º풔ʕ‡ÏÞŠ|þ@­R:¹7CÈ´“W¼úïŽJ©ðnÖšFgD½Ë¸x5<5)ŽÍÚ;¹ÊùûŽ}™iïÜ<[´éÈÚ§¤½üì¨J©¤P©*L"•–³8\!]}sïú´Ù¬ XþâùÓ´¤wd •Ç>z,x^BR^‰fßáSÅ…ù4“Ãå?|ÈHN|ƒ]-QR޾\\”O¥3èT:Á¤Òh%E…húŠ2y~N–©7µ® z&awÃTú\¾ç’®–¬¼’²2EÓ&MnßÿO­R;Ùñ•*õÛ·±{1Î2Ô«{ €¤å”Þ½T&-¡Ó™™Äá ì]L¾ñz§FMqhz–˜(•Š~AÒ-N5‰[e°ªR¨Z¯žÐ†cD,¨›FË*þUS ½úìÅË䌭F€(•e\¾ÈÞÉÉâVYÅtµ¤J n\¿ž‘öžÁ`2YÿÎÝÌ)‡%E…BzþüEA^¶V«E@+—Ëì-ÉG¡xB{žÐ^¥R–äi4ü÷ŒÞMhÛ)Àà4ÒZ`¼E[T8<<ÜÈš~/ö„'…‡†††‡‡Ã ¯LZ ÜT­ är`*š h©ZWHåÀR"T¤aåj…r-£¸ „š®u.:0‘2)0sÀ^¦eq‘”¡ |r`*€¢: HªÖ™ RÔÇËPYZ™@©¥¥“^¦Hd²Z)§š—dˆR!CÈ@šÄ5?Š!V׋ÔìAݼ¼¥‘B¦(Êt:Ý ŽIäò2 ™bôÉÚù4o]Z\Ìæò &ÁôiáWZTÀá Ð!`\¾PìâÎbqùB{:ƒéÙ¤ƒÅii1‡Ëwv÷fsù…ù9rY©F£Aa²¹t“Ád!âݬuqa>ÚìêÑ”Á`—ÉôlÒJ.“¢—8Ÿ¶€Ÿ…}òY;[H[s-°Îî»4ž½ª$ÿ}|6rª ™Á¦qD€ 5‰k+›^'YiƒM¡HTTX«Õj̳ a1ÙB ú‹ì˜É«I+6›«Õ‚LVâìîN®±ÖC·˜*-©Iq²UQ´ºÞ†]7o>‰»så‚Ú‘P‹šê1ø7¡1×{Í4D Q¹T®É9Qµ·&X]¯µ‚|úÓUC_$-5eñ¼ïlbʲú"i©)#ûthå§¿;qã!&ÒÈ®æ •ãן¡µ€¢w( ƒ»á·lmAµiåçߘ_¾mÛEG¼´µu¾#BÐèsBbk5Ýmm@=ý|âñx¶6Ä Uˆ Â! ¨/¼xòØÖ&X Q_M;æÓð'ËÔOŸ>µµ D‹A]Ð3z·9ÁnùN®mKêÖtDƒŸ?wÖŠ ~tw‡E¿VàÁÝ^‹œzϬsêVèš \óDê­:‚Æõb[›@@@@@ð굈è9è׿ÕÛÆÿߞݻh4š®°´´tÁO?­^µªnšŒ¶m 5A«]ˆà὇uc ÊõâšÏ²J"™jwÍÔÁ/±¯¯ïõë7 +¼xéR‹æ-8Nmk'€’'ç³/5z‰Äàx®¸if:ºCCV,[a*ØÂÅUø((£›³'.‰`\ IDAT·áìŽ*9k…íÁ,s ô< !øH!>«êV#bX µZí‘£G¯]½V*•~öÙgS§„0ÕØÈ~ô¨‘«×¬0àKl5~•JuáÂÅË—éª3ª%8$dñ¢EpãÆÍÞ½{@rrò²åËwíÜYóÌš™ÁÀ Á'L8uê”Z£éÞ­ÛäÉ“(”i\0§S ”œÛxôØQ___Txâø±%KÂDSþ¬VRæ AD[Õ®~ƒ}˜Û^hÆ:Wjæ&€øXÅ#!Ü‚šP+ÓwÏœ9µråŠÝ»vªÕª¬Vô&Mš899Ý¿ÿ“ܾ}§yóf®®®UjiÿIû¨¨×““³}Ç™L‘QQÚw°BÆpUëñâå‹Í›7mÝò{jZêÑcǬ¨½nàt äÍ=jttt4èx!4׿6±§³˜^¬ÔœŽ—)4Ŷœ¾>BüUsöñ@‡SA³Úq)$_®= #0Á—sp€ýéÁŽ£š±P¡‡¼ä3Á© ‡³ƒC?ðé$,Êõb,.v@%!Óý¹ÇŽ:L÷çRuÌòa`q¨ã–ž"/ÞÇäÔONœ<9xÈÐ'OZ%5Ë£Ýôs~X`kÊ©¶#4û3æò•«Ó¦M‹ÅgÒwß=xðÀTHSŒ5R·š:}jäˆæhiß¾}dT„‡ß¦ÑhwîÞ€¨È¨öí?©® º9Õ˯9 ±³³³³³ ¾uë£\póE6oÚh±¢Õ.Äÿ33ÁM˜gâep6^6¸ S÷R1mêÜàë¹î\ÊØ¬*åzŒiÁö³§þp'Üå{þú™àL¼tÌÅœ¯/eçÈÔ“Zs ¢#¦Ï ‰aÌ7-Ù^<ÊôyÓoäùð)c[²±KÅôù·ó‡ŸÏþ/³lnû†°j$ Ñjµ/^ ž<ùÒ¥ËU¶#6$drù¹‹—–¯^÷ÃÏ‹~^ºûïbãÞáGÑs5ôN7ÿ¶ÆúVXD­ŒÉÊÊš:uvjÁ¦Ï~~~d)""²m[¿çÏŸs¹¼æÍõjñ÷o»}Ç¿>wΜ£ÇŽöï×ïÍÛ·sæÌ®® F«â¨ÖÃI\þ­ìää”››W]íõ´fûÎ S·Ûª-œÙä–BjØ£B¸•*ñã8±É™¥jôꯊsdØöªxé‚}1¥ør=úy2—<,H/UÀŸ¯ŠQaÈõ\ô L ½.ÙÓ×ßÂÞŒE ²ejØú²xé‚¢KÐK›_åÉ5p4V:¦/‚ªxúô‡Ã ¼yëÖ³gÏ:vìˆÊMuWÙMŒõª¨ÕêC‡߸qS*•Žùê«aÆ@ZZÚ¾}û#"#Õjµ¿¿ÿ¬™3x<ú&Dÿ£q±D”Jåß{÷Þ¹sºu ˜8a•JE̘>íØñ>ÞÞ³fÍôôô¬VÆ÷î? ¦Lž( e2y\|ü•ë7š7kZÓJP¨•†bG‡°¥abGÇš$2jÔ¨'O´mëwò”‘æSZ †““ÓÝ{÷h4z§N>üèñcgg§j R©s2˜)‘x¸»£vv"+j¯c8QwĆù°øtÒÅ¡nø`æÎÈò_úŒ $½TmÏøÐÈgJ®‡“”^£¹ìÇiʧpi$ÐTõåiÇ ™R‡z!P¦ÖÒÉÕvÊ t¹pñbPà 4hàù 1G*ºƒ`ã¦MGûõ×ør=ŽŸ8ñúuôÊ+¸\ΡÇQáªÕkB‚ƒçÏÿ^©Tíÿwÿ?ÿì›5kæùsgM 9rôhrrò¦`ÃÆGûæ›±è¥gÏ_¬Zµ’Ïã:}ú?¶­][½‰ø„ÄeK1 àpØŸø·ýÄ¿-zI«Õ^½qóÑOä2¹_›Ö#‡ ¡ÑhhûúóokôNÑcì`ôˆa×o†»ººŒ5ÂÙÉ T*ÕÉ3ç^¼Š “I=»u;{á">6îÝ™ó$’,.—Û¯O¯Ï?í\­ŒR+cD¸eË–””•J•”ô~ÍÚu$Ò¹s§œœÜ›·nuèÐÞ|-Ú·ß½{OÏ= GîÛ·ï°îÕºìÚµ;77777w×®Ý=º÷°® œ¹»42Òß“ñí¥´O¤Ï É·—sú{2i?êÎl2vSñ«#×#[¦q©‰±èSþÕ÷²ñWrû” ;—01åäÊ5˜:\u“™™×­[7è'‘|è%4Õlf7ñõë7¦N qvvâp8Á“Ë×8Þºå÷¶mýh4›Í?nܳçÏñ- ¿booooo?%$$üv8viÆôibGGƒ1|ذwññÕÍ{³&>GŽHHJR*•úJïÜ{Ÿ0sjÈâ_¨5ê‹W®B…·±ù·5Øî©1ocgM›²ré’V-[=~ ^½~3??ÿ§æýß¼9ºÝ@ûî×»×êåa³gLMzŸ\ÝŒR+-"AA‚¬X¹J"‘¸ºº|ûí·$‚ ÈÈ#6mÞb¤®dâÄ è±©î`3»‰sssõ„qqïöîÝŸPRR$Rß®yyy˜:ggg]uB¡= Óé …?Cþ÷íØ›·ï?y:++›Ççùûµé×§7Ú@òðñãÉÿg'ÀÐÀÀ ¿oT½FÜÑ#†ñ¸\èÕ£ûõ›á¨ðé‹S&}Ççñ`ØÀUë6 r‰\XTTRR"¾=ÒD’Õ zŽˆÑ¶8Lˆ TÍ¢`HÏž=zöìaJ)->>ÞgN—»´>;®ø95¥Z7ÖˆÃGŒnêÆ ÎÊîCš0÷Fëï8— û¶uD^d)¶÷¶##žZvð͇¦äz-e‘ Ý… 2òoE°õÏŠ¦¶å,þ”’'W•¸–ÏÓ9ô¶ô÷ž"ѯzàMiˆg[oÜN•0­Ž€À2 Å›7÷ìÙu K$’ïçÿðÍ7cÑåMu›ÙMlooŸ‘‘¡7tcíºµ_óÓO Ølviié×c¿Aå¦Fþ‰D"L]FF†{¥ ÆÀþýöï§Õj%’¬á·÷82i"äå¬XóÒ‚Q‰¨4*kq)*,²•;OvvF‰OùÚËW¯³X¬áCû¶laq¦Pªáˆ&S³¶pæãÔÙ²ª8W?Ɖj5Óoù†{˜Qö0£ =>[zÄØgF嘨4ð×ë’¿^—è{œYö8³ ;=/EŽÇIÇI SS¨µ[_o}YlJÑSó¹s÷n‹æÍu‡¦‰ÅâfM›Þ½{]0i×®ÝsçÌFt»ƒMÉõèÓ»÷ö;çÌžÅáp>ŒöÎÈåe,‹Á`deeýý÷^,0ÇKIIqww×K¤{·n;wîœ;gìܹ«{·î5ϸ‚89‰‡ Z²|* Ó‚'‰*œÝ8§UÂãóróòÅŽ››‹ÉÝ\]'O¯Õj£ß¼=t䨲%‹,ÉÕpDêìØæ¿ô67 !QÇ ·4T.\¸ðÍ7ßè pèðÔ1Õlf7ñðáÃåeòŸ~þE.—ó*œ3{ÖîÝ{V¯Y#Іv¿b©‚Q#Güð?–––ê½-¿újôß{÷Î÷=tµb¯ô–?wtýâó¦>>,³ °ðÆ­ð&Þ^襮_|vøØ‰CÛÛÛI²²¯Þ¸9áÛ±Àf³$’,±¸ÜuÓ;­’Ÿ´;}öܘÑ#àÔÙó˜üŸöïÛÛÁÞ,j}!0„X^©V \”[¾“8ÙÚ ‚†ÀÆ  …;wîܹ|Ö†©î`£rÃ.u …<~ܸñãÆéëØ±£îĬ?zèСC‡5LF£M ™bJÑSsèß·ÏÝ{Ž?©T*y<žo«ãÆŽA/uëÚA=ÿìËÍËwt°øeTÞ§gÏ[·Éd2t€ªÞi•ôëÓûä鳫×m “É]¾ˆ{W>ÀÖ¯Më={÷ççç‹ÅŽ˜ 5pDjœÁVÁTgÑ B@ÐhÞ´Ió¦MŒ^B¤[×.ݺvÑ“÷ìг{€©SÌÑóK°S*…òÕÈá_韾'úGÍØ¯FuêDhhØÊ•K¦ãåîÖ¬Yó«7n`ëâhµÚ¾½{½‹‹ÃÿYºuóæŸÛþxùâ…@ èÞýç_~±·w0¥ÂPXÝß¼·oß®Z±üÉÿ@§ÎúeaË–-«•‚Q._ºÔ¡CGooo=Sííº÷è¾è×%B¡þ&¥µdÕíððÛÿ|öô)ŸÏïÙ«÷O¿ü‚£Ú²§†æA6›ãáéѽ{÷à)¢ŠÛkÉ €&M›¶mÛöÚÕ+Aƒ‡Ô’ ‚ 3{£ ž¦ß”XE‹ÈŠ … Yh¾A Ç3gU’C'NVkXÀ”I_™c€e¿÷*• œœl¼I›a×ϬY³¶lÙ‚s:=drW#FŽKûhŠŠŠ6­ß *PQ¢’h÷šZ  P( Ñ™ *5,[¶V¡(3•“ɼqýzŸ¾}ÑÓkW¯°˜¬* عcû¤ÉÁŸñ™DÚ½{×ì™3>b4$ö gñ7wRRÒ×_ž>cƺõàìéÓcÇ|uòô/// RÓåÆõk ­ÍÌÌ\úëâÍ[¶ÖU»wî ™2µÓžÎr™lýúßæÏ›‹ß[dÙSCs'•JŽ;: ¿§O»¹éoOouƒ‚®]½F8"Uv«™Zº½ê®D«@¿é——KEè1‚,Ò ý¯¯ottôÌ1,ñÄÌıÖs@S’™Y»›´™ƒa×ÏŽ;pNë#FŽzôðÑÔààƒGŒÿŠ›ÂÕÕPj•ŽB@R¹œÅbI ’BòSƒ“Ô”iÓ¶ÿ¹ ûIûsÛ¶©Ó§OŸ:=õrwûé—_víÜ©V©ºxÉ*• ‡ŽÅR˜²}Û¶jÙ¯P(V¯\qöÌY¸_C¿›¨ëˆ ÃììíOœ:]-ûOŸ:¹gï^ggg]º,dÒw8ŽH~~ž^' X,ÎÏÏGÏœ>õ÷?ûÄb1üº¤o¯^ør]L{‰D²|éҮݠ[÷îlëÜÙ³C†MLL¼s;>87ç©5Ø,‰D¯Û"""V¯\ñ:*ª°°*>Tt1õìp²&‘Hªly" hœh4ê´ädE™œB¡ðx£ãQl<‰ Ò* òóHÊå@24Z@H@¦ ¿J€ÿã êˆTk3a­V[\=×~Ö¬Y±¸,^¼¸>4äp¹\‹½pqrÖ(”é©iˆæÌž;gÞüU«× ùé’ßÖo\¿~shØÒ£ xY¦Ñh¿›ôýܹ'M6«‘œü;0žÌáp'‡GEEVË~±XŒ%›””„?ê¹K—®§*{9'ïÒµ+–TJÅüs,M¹.mýÛ>{RiURJjRJê³/7ý¾›QÒ§o?•ºvõêçÏž}óí·µdÕùsgçÌš¹c×.ÿvíLÞ pžšQƒ 9|èP×€=á¬éÓFŒuûÞýø¤÷/#£Ð®[]L=;œ¬={úÄ¿Ý'ædŠ€ ±‘“%Q”É [’©ÕVýÛdã+ ÐÅÔRf8 ‚¾ø¬¸0€ÅM…Õr¡PÐá–¶¥&^HKJHª‹««$=ÝËÃ{ѯ‹åвY3~tqöÈ’¬_¿^«Ñ„¢ôHÍ!(ÓfÌ0µäÔÒаuë×£C‡ G…ßÏ3}æL//ï쬬íþùÙçŸWËþÁC††-Y‚Î7 [òëà!CqÏ7oäða\.wðСpöôéýûþÁ:ƒºliØšu¿À²°0]FåºôîÓ÷Âùs#F·A™³gÏœ>}ͺuXá±®U»wíükÏžƒ‡4iÚß]L=5£cÈd²„øøÇ]8þÄiý>5©TÊårX,VZZÚªË 7õìpnøÅ † f~¾9AƒÍ vþÜÙÚ¶„ ¶ÉÊL/.,ÄNbßvêÒ-/''Š[Dʇȳ¦Ï QHËÂoÛºðë’…è°€U«–UÇ`-är¹eAtÜ æL¶×J¥²´àS/X,–\Zª*+»¸|?¾T*ÍÉ.àrÙ°|ùrµºL^fVÇœ9téÚeЀ/û÷éíéé9cÖ,TØ»Oߙӧ·jÞlø°¡J•ræê͉˜5gNÓ¦Mƒ 8°yóæ3gÏÆ ìÓ¤ÉÁÃGîܹݽk—î]»Ü¾~àÐa¬óbÖœ9...ýz÷øeÿŽ:a޵)¹.|ñüybBÕ«øHdoootÆumXµ|éÒô´´Þ={x¹»¡¥¥¥UZU-ƒÀËÝÍÛýã'í~˜ÿ=F¿xùŠáÜݵ¿­_½j•o‹æcFúô3#þ¥©gg*k ññ/_¾ìÿå—5ÉNc#>é=þŸ­ $°ŽN.½ûŽƒý‰]ð£Ø¸EĺÃ0ÐAªKYY Ö,@¥R!âè訷|**·,Mó©µ\¡X¿qczzº»»{vnN7ê(k4*‘H”—“oÊ)5µ°‡®|ê´éS§M× 0(0pP þ„ |tÓ¤Óé¡K—….]†^—–­Zý³ßøøM:¾rõš•«×À›˜˜cSLÉua2™“ƒC–†…þýÏ>À]Ôëä‰ãóæÏ×óf¬hUµVX1穌¯»Ú³W¯ž:ãL'Lœ¨ÀÔ³3•µeKƒCêfYÕÀ ÁíÛ· ]¢[ǃ¦øXñkÀ¤§¦¤§¦˜ÞÆŽ:, 3+ËÅÕuöœ¹@ֈſü´(=#ãàÁÃÅÅ¥‚„V ¯«rXF•]3$ÉpP+##£º¹€ƒK&„„„¬]»vìØ±$Rø|~k´:K—/C„Á`Ðét¹\®PßGmm¢R© {™Ú¥a¡Ó¦ÏP”•-[ÖïËþUÊu™>s&~âæð¡C©))f6˜[Ūš`±Á5ÇhÖP'¯Îàr8.\ T—JëŒãÇŽŽ5Úºi~,‹ø ØØ±ú°”²ªÚðíDØX¬ªs4ʲeåŸS‹/>xð æ‹Tk]5‹‘J¥µ­¢¨‡ðj¸š»ÅÑÝÜܨP*ûõë÷ÃÿýX¥¼Zøxz¸¹¹oÛ±£ºÎ\Í­²ì†XlpÍ±Ê ¯!Ó§O›?ÿ‡víüÝÜôï^ZZÚ¾}û#"#Õjµ¿¿ÿ¬™3ЃOŸ6íÄÉ“¹¹¹...3gLOÏÈ8zôXNNŽ·÷ܹsФ´Zí‘£G¯]½V*•~öÙgS§ÔQ3ÆñcG>|huG¥ž/âgj=S+.š’7l술Ã( :,àûæçåcÃÖ®]©PX2gsÝ*±ø]­Vë ¡P(uÓ/¦Ú ±J—AmGÿnÒ¤ï&M2_^-lh•…+â×Ú®1Ub•^CØlöŒÓ×oذní: ¥ÒKfÕê5!ÁÁóç¯Tªöÿ»ÿŸöÍšUÞöäé“åË– …‚³gÏ- kÛÖoiX¨@ 8{öÜÖ?¶­^µΜ9µrå 6›½cçΜ<é»:Ë×ñcG`ý†u «.⇳Ξ©ñWb´9/qkcGÄZÃô(**²À˜z—†ƒR•JeºA@@`süüüÚúµ=pðÀÿÆ×•oÝò;z@£ÑÆ7}Ƈ^¹Y3g‰DB2dð¾ýûgΘŽW2dðáŠí._¹ºhÑBtŶIß}÷ýüjÛùk÷î~_öwssGÛBjÕ ©ç‹øá¬³gjÅEœ•mNM~ìªpDªµ^»|ýÕHß¶í¬>,€Ç㥧§[ÕÒªY¼x±žÄ⳿¹[*cƒ]ÀÆûö‡ÿû±SÇŽºÓÓââÞíÝ»7>!Ý6\÷ ‰z!PÑBŒš¤Ó騛6++kêÔiX”:øpºråòÒ°Ðï&M:vô襫WkIËG±ˆÎ:{¦V\ÄY‰Ñæ˜Ù±n´Œá9" ,°`3÷êbÎ&½uƒùsmÈd²ÞšHcÇŽÝ·oŸ©A²Õú€ ‡Ã)))áñxjµg')éø IDATÆ#•JU©TZ­–Íf[<똀€à£€B¡|ÿý¼U«VoXÿa¿õµëÖ~=fÌO?-`³Ù¥¥¥_ý¦Zi::8„- ×á±GŽOMM ž4É·uëÚÛ$Ùh_^Ÿ¾ýÖ¯[‡®‰·~cyK ºˆß\îÃEüÐ…p ñ3”Àùsg—……íþûo?¿¶øFΚ>möÜyÛ¶ïàr¹ÅÅÅíüÚ`—’“ß7kÖ V\4%¯'ÔÊI õÇK¨èÇùh4ìKÂèNZº b¸2#Œ?~ÿþýkÖ¬Q«Õ111zWÑôÍYÿô#½çµ‡»û€_n×Ù|[./c±X #++ëï¿÷V7ÁnÙ²eJHˆ³³sjjÚ‘£GüøÖ´Ønnî»öì¹zùJm+Ò£¾-⇳ΞÑqä;6#RKp8œ½{÷ZלÞl²®è¾eeeFH$Ã]0Ì'(0pIè‡_¾9³gíÞ½gõš5B¡hø°a÷<¨^jA‚¬X¹J"‘¸ºº|kzí|ëâææþÝäÉu£KS‹ø­Z¹býoë c§Nz‹ø…-ùµ_ï^*õ&<¸_¾|éRèݳ–þë7oMíè¾ö·õË–†MŸ:ÕQ,™2õÒÅ‹Ø%tÅE•R4x¶â"Žüc§a:"h/‹ÅBw¡Ñh*•J£Ñ‚‚‚†u‘¢c,Ðé-4F£UÙš‚ßJ¥R †P(D‡;1™L­VK¥RÑUÎöÒVGoá2A–†…b§;vìØ±#vh4–©SA‚‚±X ƒe?Sëì‰qä; Ó©ÕÞ ¢ëÄê,Z´È⸠,¨²7€€Àæ4ñ2¾_tÝðÑ-âרh˜ŽM(**²xtóŠ … Yh~¬… ÇãÕÃeÐt±ù‚ôÝ"~ Â!°c¿}ðÈQ‹}D«-ßoH[>n A¡ÇR©É$:ú__ßèèèÚž^Nаñrw3ÿ÷à-[ž={J¬Øý‘ò-âgξK Â!°111û" ,Z°~è©YXq¼°r+É.\Hx!õŸjýÒ×X%•J÷ìÞuâô™Z2‰€ 1C8"Ödâ¤I–ù"ß|óM«V­ª«ÎèཆÐ:þ!´âNžÿîݺµk=|XZZÚª•ïÔéÓú˜v>³øæ£A6›ãáéѽ{÷à)";»*c™£Ñ«._ºÔ¡CGooo]ó û»Vׂ*©r ‚z áˆXt^\ ûhjŽ­¾Â­»“gbbâW£FM™6õ×%¡öѯ_ïØþçÇåˆÔô!J¥ÒÄ„„ãÇŽèßïÄéÓµ·>7®_XijI ÷wö¿9µms£‚(öQC8"VfÄÈQ>š|°b?‹ú€—»Ûâ_—ìÞµ333319gßËå+Wîøs{ff†··÷ŠÕ«ß'%ý±eKzzºoëÖ¿­ß€®S¤ÑhþغåÈ¡ÃÅÅEýú¶lºi³uwòÜ´aý„ï&‡LASk÷É'îØ‰+ŠÕ+Wœ=süÓ/ i4šùöãlï©{—Leóþ½{+W,gïà0köœ1_mJˆ5Qà¼båªmÛþÈÉÎömÝzõÚu-Z´Ð}p,«u›6­Û´áryë×­Cï¤QÃÐV ô?ªç)빪F×%âUÄ?ýlX®,ÞßµzK.àУ'ÑòQC,kA`eN?víê•EK–ØÚ}=ztúÜùÄä˜6uÊøÿMxôäéÃÿþsrr^»zìæÿ:ô*êõ¡Ã&ŒåÒåþ=ð""²OŸ¾¿üüæ¯=»=|xèè‘;÷¨TÊ ¿•/¹}ïî½a#Fè*>rä½»wÑclÇÎ —/ß¿w cJ~ÿÞýÁC†ÍËÖß=wñ⹋cbbþز¥ZöCÅ6ž—¯]OHˆÿcë‡èºwÉT6çÍ™=sÖìÈè˜cÇO¼xþGhŽÁ·oß>rìØ‹ˆÈ={.Ô±P1_ÝI£†¡¾ERJ*ædàurIX˜³³³³³sèÒe§O¬–ýP±§““Ó¯¡a§Nœ0z—Le“L¡H$’ÜœW×5ëÖáÍ1xŪUnnî,+dÊÔ¨ÈH£ùG;iÊ0=pž²øÆƒé–‰Dºd‰Þþ®€îïŠ.Qe´T˜²„€ B8"Ö¤>x!PñY¬ûq .®®ØqDDÄØ1_ù·iíåîÖ¦U«¬¬,ìöá‹nÎéàà€b; ¦¥¦öêÑut:~òIFÅVÏèNžº–Ôd'O@(‘HŒfP"‘`!½¼¼t•šc?˜ÞÆS÷.™Êæ®Ý{Ü¿?ðËþ=»„ߺ…#4Ç`Sê‘%‘`;$˜2Lœ§¬¾ñàè(Ö{¨ö_ö'“IaK—¢Â™³goÞ´Q­Vîïªw7LYB@Ð!«Áårëƒb ݵùgMŸ6bä¨Û÷îÇ'½etC\\]ï=|ˆù: ï“Q9º“§nHÃ<ÑcÃ< å]ºv9Öø2Pb± ™””dÁ>œXt½mtôèº5k6oÚ(“É|}}§Tìw5kΜU+– A3gÏ®î0gOSÙì׿ߔàà´ÔԦ͚mú} ŽÃƒ½ÜÝa±XžžÝ»÷¸xùн=¾aÓgÌ>dHQQÚ%gþSÆ7 ¸|iXbBö4Maæþ®Ç¯<ªò˜ÉÝp#½iu@@žVIñì;£û¸•)9ÙÒ¬„¿ÇV1,œàãbâÁ,–£OÆãã²¼”6¼‚qBJeei©)‹ç}gkÓ*±hÑ"‹4[±bÅǸ„À›˜˜àI“îlÚnJn]êç‚§õœm[·>yòßßÿìÃ6ù»‰ƒ‡ ©²ÉgÙÆ¿\ÝÜ#_>‹{ºu“˜‰Z]î†ßš2{ž­­hthµZ¬¬9°?tõoU]ôI¥&%\8{fÊìyK7ìAkÑ"BP/h$ëµ;y~¼LŸ9?€Åû»Xb_ôÂ!°= ,°á2¬uIÍwò$¨·X¼¿+A#‡pDl—Ëý»W, æ;yZ¢_¦6 î*eŽÁGI`ÐàóçŒOð®o˜Ù]õ±d‡ÀºŽA­Ÿô?@/Oü Â! ¨×¤¦¦îÛ¿?22J&“y{{1¢K—.¶6ªþÿ6†F£»{Wšh’˜ P”5iQÅÔ¼‚¼ÜÜì,;GÈ®6m$¨1¨Š€€€ þ’žžþÓÏ¿´jÙê÷Í›Ž=2uÊÔ;wîÚÚ¨úBBJK>ìp\ZRŒœðEùöŽâ¢‚üZ3ÀD‹AýåàÁCAAÆ•/LÒ¢EóŸ ö(NKKÛ·oDd¤Z­ö÷÷Ÿ5s: íÕ«WýõwJjª@ øê«Ñýûõ3%l`Dvy9l=-Èˈì%é©–üž/r¸åÓôTJejr’‡w‰$--!‘É|¡¨¸¨HZZÂb—GcçàX—§-—˳s£› ˜’T¢E„€€€ þòòÕ«îݺá‡YµzÍ AƒþÙû÷ßýeg'ú§bÕµõ6Œþjô‘Ç֬^õöÍ[aƒÃå©Õj¹L2©T­Vs¸\ô’ÐÎ>?' ™Ÿ›#ŠÐ×…ùù|øaa~¥Fii©›—·»—B¡(ÈË­RNP-ˆ‘úÅ#Ç,Ž»|ùrbMF‚Fqq1¶í°)¶nù= ÑhãÇ›>£|í5‰œ—›WXXèàà0{ö,aÃC ´+ÈËuru+ÈËÑðÁb³óH¤’¢"§T(¤¥¥ŽbP*•er™“«px¼Ül‰R©Ä6 ²‹) Ø;Š3ÓR…vöør‚jQ…#ÒÊÏß‚D1g‘»ƒG-Ù‚24446:ªÊ`µj¹.ÝzõÁpçæõj%¸bÅŠj…G‰ŽŽ¶ A=‡ËåæååáïW÷nïÞ½ñ %%% ³oßâE >rðÐ!.—ܱCS†—ÏÏËÍ.)**++sråë^ÚÙåfgqx¼¼ÜlH„HPôÿìÝwXSWÿð“A"„­ ¢ýµU+XE‹U¡ÕZû*¡,ÅÙb("ŠÚ!Š­¶ Ñ (ÚA@@Td8P;Ü(jµ¯õm­T@I$!¿?®Þ¦!{ßÏÃãsï¹çžs.µæ›³ns“H$úë÷ðl­ÍM6v/^{bbByq@¡…<¼t å="wïÞU«Dµöꎋ‹S1'…BéììDmܸQÅ[ôÚrI.\ÀºººˆD"ö'–⥬OU& v÷R÷aFaŒ»{iéÅÙ³ƒäÙ²u˼¹s×®ý‚F£ñx¼yó`éÇ]¿N,_»v}ûöØ[e&ö=ÁÊšÑP÷˜ak'5uƒfaÉm|ÊyÚÀoo·wˆ‹ÅÏZš‡ {…ü² D Ôþý¿W è¤PL±2Ù/J^:P‹á‡fΞ=«¿Â—áÐßÝãó·<}J&“×99 E(!„ÛÍ›¡²7߬Ôѧ8‘H9rdwN„~²-)ýÐüùó¾XcB1™|xðà!©ùª|~‡¹¹9•JmhhÈÊÊÆÓ·lÝ:wîÜNN!üÃXfbŸdŰ‘· ×ÚÆ¶þq­£öxÞÚjjf†G!!SªÙóÖVËBœ†z;ÇØ…Äû(䥵>Á‘Éd¡Pˆc9´ÿ|­B!ÔŒÐ-*u©ƒC,‡S‚ЄBn7o¦Š£BÑ7S•ªeE///[[[///¼D· æ ¿8p`B|ܞܽyy:::\]]ƒ¤ò¬\•‘‘¹9)ÉÚšàïéåÛ›=ßòLˆOhxúÔÅÙùÓ5k$ö? Å’þbȦ¥™Ë°µ“ÊA·²nâ4bˆ™9­¦ê¡‰-,é’A䥵¨ˆŒ9½œŽ€õ×U… ]„ ˜*„V"„º…P%…såÊúë×OÍœ9æí·»ÄbDxQ™Nê’…Ñ_,èo\\\Ö¯‹éžŽoˆîááááá§3™>Ø—×/¯)RwÉLìKäíZ&™þ¼µ™aóÏó×îùiø`y+ :]€êÔDdFº‰øàƒ:;;±ÁšiÓ¦9s!4uêT‡oÞAhÕËc·›7‡de!7·é?ÿlcf¶zìØè)CbŒ‹´šé>D'±þÿ ™Ý½{ ¡k`DzÏî­ÍÍFRz­†ft…H$‘H„3fÌ8qâþAkñ2&Õ@~”]¿ys Ÿ_VV†â¡µkËBB!d¥UÛ_ÐGÿ@¨¬¬1bÄÝ»wñA™‘#GŠÅâØØX¦‹Þó6»÷ï’ML:º!àZ"•••:‰ED"B[!SSS,4y.±S¯ºªð£¿ÿNЉ¡Ó½^ïµµõBHUB¨¡f-ZŽÑliŒRxœ1bĩĸ¸8ÍVù@¦ôu3ªß¢AQ@&m'«ê*A™››cÖÖÖ!pöìÙéÓ§kUèÙM/– ¡!÷þ:ÿÞ=ÓzX‚ð§9×ÐÖÖvíÚ5yW%n5зç´j"XÌô°w¶^¦µµ;miiAa»†œ:ujêÔ©šíºñÅB(äõ×;BB†¬][ßÚŠU r-yq•¯y ‚ÅO2;E.\¸€GWÀ‡fD$ú(õzD$CüXû¸¤³³“H$ž={‹9°™"4 ›;âââ¢yÑøThktïÞ=„¨¿ÿîðûïõÝCÖWµÞFäÂ… R±ˆ^WÍÄÆÆê¯p0.0aΨõŠ}Dð}H%WÇcsGrrt±ñŸ7Ú\²!„¾B›_¦è–d,¢“(D,wï龎ú³)ï¼ ¯Ù2j½"ÑŸÊ»/{k îvY×»¢c±ˆûB¤¢ >ô1ÊßÀbpiyÏïcÑ ã¥$ÑëÉ7ªþ;uõØìÎÆÆÆ·ÞzKÞÕgÏž©[`ee%¼Á@?¡$©,»¥¿ºÿWY¡¿ÂõÚrýU¤ú눀> Ï1:0å @¿})-9gè&}™òλ:)z´dÅ*噀±‹Åºê‡@€~Áâ¾>F·³ˆ:, @-ˆÀ` €B>L_C7ôGˆøˆH@O‚ɪÐ{u Ž;ªïJõWÅPçªê„гgϾ۵óן~ò䉩©é„·wîä™3þùGaA¾¼–Kݨ¸X  èããÃô\QXt°¹¹y˜«kTÔò!C† „D"QÞgΜmkk›ìïï‡YÙÙ.”"„¼¼¦, 111A …B6;ãBi)‰DÂrâ…c¼ZA:;ãâÅ‹$ÉßÏ/+;[Ýé÷«Wÿ{㦥¥%BˆacãÃdú0™Ø¥Ôäm}ôqX8 ; ommÝž’œ²}G÷rîVVæîÝG³°@-‹ŒÌÊÌTœ.ϙӧNŸ=gck‹Úøõ׬%³çtc;Ð è£týÆÍÄÄ„ýûöŽó·k×wXbÑÁƒwîT&ÄÇgf°9Xb~AÁ£GRS’SS’«ªª ±ô‚‚ÂÚǵ;Óv¤¦$_¿~]õZòó ž64ìÚ™¶c{ê­Ûšl)á9qbÌŸ_ûïù|¾Ô¥‹¥ý%S‚‚.––Ê,çÝ©SÓüñÙ³g­­­?~ÿûS§*NGuwñêÿÍxoZÖîÝ"‘OÇ_•J@„û÷ï©ûDòŠJA ½šÓWòO\á`oO¥Rüýÿ|ðK<}úÌÒ%,''G ‹ð°0,±¤ä<‹Å²µµµµµ]Âb•œ/ÁÒÏ•œc±X666XºÌÚeÖRrþ|XX(ƒÁ`0ááa<ÔÎï¾6lø†ØõîoŒòšôvB\þ®ò¦&®£££df‡¦¦&™å|¹qSQQáè‘#ÜFî,ýÝ©S¿Þ´‘ÓØÈilüzÓÆ¶¶6µG^±@ˆ@¯&oŽˆµµ5v`jjÚÙÙ‰s8'''©¸\®£ƒvìääÄáp_fþWºÌÚeÖÂår^Þˆ—  ËÕŸ~úˉ“÷þø3#+›Ã嬌ZŽ]²²¶®««“Ì\__7c¨‹3öƒ~ºzÕ‡~~ew*ËîT~èç·fU´ât …BqssÛ‘¶³¨ Kùrã&±X<õïÓ§¿úêkòªS¬{±@ˆ@ßakkûäÉ©DƒQW_?yòÄÆ†ÛØü“.õÙ¯ƒÁ¨Ço|y ðꫯ~µqÓÕ«W±”I“&>xP2Ï¡¢"|AÔ„Ðkÿýodär:N§Ó—EF^¿vMqú¿ª&)SìØÊÊj{ÚÎÛw®Ý¼I@{Ò$™Õ©ôDÅU@ }Ç{Ó¦ýðcz]]ÝóçÏÙX¢·—Wzzzccccccz:ÛÛËûEº·7›Ááp8N:›­z-Þ^^™\.—Ëåfd(™*Sðì ãÇŽ56> …ÕÕ6'&Œ?»½jÕžœìL6ûéÓ§OŸ>Íd³s÷䬌–ý漑£Fýðý÷­­­­­­ß÷ݨ7ÞPœyÿþ}@ðçŸ|¶fµÓçE¥+¢ž% €ßÁ_³ŽÏçÏûbÝGpðœ¬ììèU«BS¦Lž3gö‹ô9sÒÙ‘Ë£È$’€ÿ­[ªN; ž“Îf/‹\N&‘|||ÊÊÔž¯º2zUNvÖú˜µ|>ßÞÞáÝ©SSw¤a—† ¾ÿ@~bBü¶o·"„<Æß—wÀuØ0™ålKIÝøå†Ižo!„ÆyxlKIUœþÁþ³2jù_8991}?ŒZ¹K{Ò$?¦Okk«‡ÇøŒÌÝÆ—×r|˜;À:Kä Tô^ò©tü”L&}´hÑG‹I^¥P(KX¬îÓQMLL"—ED.‹ÀN¤J“W …BY¹<2!TUUuêôiãx{Ò$|ø£»×GŒÈÉÝ«J®®®2sÊKŸåã3ËGFwÅœà¹s‚çªR£ÌayÅUÀÐ µ±32šššØ™== Ý`Ä G€ÚìV­^#Þòô\´h¡¡›Œ"ÔæëËôõeº /€¡ ôˆÐ¯»åšlú Dè‘X,6t@¯}™òλÐ3ü‘‘ncFºQ%}Œ‘‘nc*ËnU–Ý’ ;d& 7q†n`4`hF—Ü<Ɖ:ÅnãÊ®]×¾´CGŽ+ͳ~Ãzèö`¼úl ²/¿Pƒ»ÏÖ²^"QÄ:{ïbì—± ®^.½¬«ŠƒPˆŒtC¡P;;ùêêþ'‘H‹Åb±˜H$R(>ŸÝXYvKÿW"..N*%666>>¾²²Rfþ#FhÓ»0Æm<¢ „P'¡]W"Há„óß.þ¦“*CQˆØØØ466*ÈÀçóÍÌÌD"‘Hlll´¶¶&‘H$IÅêñ‰ Xà"5;DûhæáÇZ– º.JBaê@€qú%‡ÃÁººd¾R©T¬SäÎ;ãÆ»råJII‰¼Ì2IFøqoèPÑ€°S„"SH!vŠH!ú(èyª®š!Ê! »ººH$Òo¼!‰&L˜Àápúá'%Þ…C$ê~!’äï³þnôaJzD”~ì‰D „X,æóùT*ÉšœÑf“IqÚÏ*Õ-2…dN¥aÇx¿Èè7Ç•ßÔM§6ƒÿç€q}ƒ’@ÄÔôÅ£-ÏŸ?G333*•:þ|¦JÝñññ*·ó_Äbq¯Z³:Òm ™BºrñBˆH&Ñ‹)2U§Ê¨¢€Æ|˜¾ÇU=ô>L_U²éûoˆ’@„H$¶··cAäåÁ¦¦^¿~}ܸq?ÿüóñãÇUÿ¤”—“@ È[Û‚uº¨"6VÑÚWÂ'…t¿4ÊýÍ;·ojY>ô…ЇU+Î0|è}·AI ÒÖÖfff¦øÃO$ÅÄÄÐh´˜˜˜ÒÒR;;»¶¶6Õ[p÷î]ì`ß¾} ,ÀT¿]{\Ô‚Åb‘ìþ’‰n¦Œ`±D!ô7Ý¿³Q†Tw‹6½/½¼ç¦—7¯—SˆÉd §`²@HJJ’JÑMë´§ÊT]‘š ‚÷Ž;EºZ>Qý|žWTX4{NÏÔ¥$)»qMß-ìÿÐU_B¨g&‘(}³ 6j£±Ë¥—a×2@w>LßÈe…E›››‡¹ºFE-2dB¨¶¶vϞܲòr‘Häîîµ<’N§c·`wFFMM5êñ¾Œ!{DŒ}ÒÃíëÿ•™®§ Uý“¼¯ÚÖÖÖØ©©igg'vüÇfgg?øë/lcÉŽ/9®Ti K—Fà§2»«¹\®^ÈËïíNÞ]VVVSß}7ïÀÐO>±²²RZΆØõyò÷çåYZZ²Xá㔌˜Ëû=ÈLçr¹xº“““d~;;;¥m3'Nüúõ¦Ÿ„†üròd×n°@dAðlø6ºµeë–ysç®]ûFãñxóæ/À/ÕÕ×vqÁll¤¿ÊÛÛÙmúz“ƒ½½‚ F}}½³³3VˆÒ{¥"©Syw=|øðÔéÓë×Åüðcº§ç[NNNÝï•4|øðØõëÄbñµk×·oß‘»'!D¡P:::°­°ššš$óËû=ÈLg0xú“'O$ó÷¥=¯ó ‹jjªÃCCGŽåììÒõxh€ñùæææT*µ¡¡açÎ]’—Øì ‡ÃápØìŒw¼ß‘ºqæÌ™iiiÕÕÕB¡°ªêï¤-[»îíå•‘‘Éår¹\nFF¦Ò{étzuu5žMêTæ]|>[rò§kÖLœ81rYÄæÍIXgÔ½’¶lÝú¨ºZ$!‰€à•áÃ>ÌçóëëëwîRé÷ 3ÝÛË+==½±±±±±1=ííå-³ šg,œ]Ø™™3f|ÐóUx²*Ť¶Q<)r动ŒŒÌÍIIÖÖŒÿKÓ5Ƹ»¯\-‰¼¼¦Ì™#ý– &Ó‡@ Ä'$Ö××4páÂ…Ý ž“Îf/‹\N&‘|||ÊÊn+¾wvPà§Ÿ}Îãñ°6Kʼë»ï`úø¼ñÆ(„Є ?yòÝ÷?D¯\!u¯$Ï·<âž>uqvþtÍ,12rYZÚÎÂÂ"++« ÀÀ«WWú{™<'+;;zÕj„Д)“»ÿÞd>©‘rvvù$,Ly>]# ™é½(¡ºñi[Ã_YóuÊ£³xƒ¹ý°'W‹Ú¹ÕoЛ…°xíµ5ÕVIO†ô¤oRvrv)¿uýû!Éÿ7e̺ªªê›¸øÌ ¶¡¢Øê^’ÓW•U•þfò÷ånÜü­Ò¿º¥%ç–¬XUSõ×OG‹—¬Xõur&öôˆP;##(0P °32'zzº9@[=°ƒ»RˆP•ƒ½ÃªÕk„Á[žž‹É¾F¤—tA @U¾¾L__¦¡[¡9y½½ä#¹‚U30D`0ˆÀ` €Á@ ƒ@  "0ØY€¾Œínè&½ •e·tR"ôÈXÞ' TWZrN‡¥A ½”Ó·{"¼ô1ˆ@/…Ç>L_ˆ?€ÎaSÞy×°Í€@Œ‰@ ÈÊξp¡!äå5eqHˆ‰‰ Bȇé»8$äðáâ®.o/¯°°P2þ…J°¢¢ >v«fÀ˜ä\]]mee%‰„BassóÎ; ;³F­X¡»?ÅÖoX¯bQ±_ÆŠÅbìø·‹¿½=åmm0 Þ^^éééÑ+W"„ÒÓÙÞ^Þø%6;#zå ìàïw ÕBù0}»¸ìÚµ“@ `)b±xYäòêêjÅK„®]»Vtðàýûÿ³´´xóÍ7‡„XYYÉ«¢{¢ºëþþûשּׁìŠ;wBoŒ2tèµJ0:élöÇBgΜæ:ìÃeüuÈ‘H\¾|¹X,~òä Ç{å•WH$’©©©““SaaáôéÓÿþûïððpÖÖÖfnnŽÚ²eKSS“ÛŒéÞ¡¢Ë¥—UÏL ÄË»$ÿ¬ÄšúîTÍš0.ÁÁs²²³£W­FM™2yÎœÙø¥1îî+WF E"/¯)’é½–)Õô¿ÿýï„ °Ó«W¯R©¦Jï:tøð‡¾¾nnnD"ñHqñ֭߯ÇÇÉÌ©ýúç'Ož¬[;;(påÊ¡ó.¬ývë''' J3 )©©gΜÅOÙ½1‘ìPúý^‘HdjjúàÁƒ–– ‹û÷ï4¨¦¦æÉ“'ï½÷ŸÏwpphkk{ôèdz±±iiiyøð¡µµu]Í#Å%k³©°ŠÛÖâ]˜ß.þ¦ôu{,$£ °¨H­`\$?D)Êk ‹Õ=[``@``@¶K[EEñ@¤¨è`P``âæ$ìTÞ‚ä„ø¾¤ùûùT«RyëŸeÚ·?oÖÌ™~~~ة߇òžóöçå­Y½+*qñâE‰äïç—•ý—’—nVEG÷ÀpŒ$õ,éÞ Y8‚Â477›™™]ºt©®®îþýûd2¹ººº¶¶ÖÞÞ¾¦¦†L&‹Åb „¥¥¥¥¥¥H$R¥ðÊÊJ š”——§ñÊû‰“'*¸Šõ[¨E^ˆd€òÛÅß ©I“ÞÞ“›{÷î½#^///o}öìí·ÿõ… [ŒJIM-(,œ?ožäU>Ÿìøq7·ÑjUНF%§¤.X0_^æ[·n-˜ÿ¯«S§Nýü‹/^•_ð´¡a×Î4„PJêöª“dRãC÷БãX"Ù€í­ß°^ƒy4 !4`À€®®.±XL§Ó›››:öžaþÂù|>ŸÇãaSIˆD¢¥¥%>𨠩Ò/¢:UzD`^Àx„ÿ¢ƒEbc ‹øKý -HF±Âÿ‰‹“ D°ùVlݺE­JKJÎùå[[[„Ð+.>^A ÒÚÚ*5íׯ†ÑÚÚú¢¨óç7~õ%ƒÁ@…‡‡-[©8Ȥö·©! ±X¬ñ§/öN(ŠÅb"‘¸/w’ÕÝâëç+ ±®³ÎÎN"Q¥%ÇAª©* …Ü¥ªÌÁ~ÿ'O„ɪôsFÔù/iÚ´©ûóöŸ¿p¡ªêá†Xéo_ $?v´­­íÈ‘âÔí;’6'ª^£‚õÏÝÑ--9®““#žÂápét:^”Þ— ÒLª"XwþÑŽÅØ)ö)8qòDm³*:¤ »åþýû—¬.‡^ó—F•< Q<0½ó…5&&&L&399eÑÂ…Ýçj(^lnnîç÷á¡Ã‡ÕªQÁúçîÜÝÝÏ;7þ?=1gÏžuwwÇ‹ª¯¯wvvÆZ(Y…Ìt£µb%¶d7mÚT½ÎÑdC3¼ëLç£$Ý»[ô1¯eäK’WëµûKóö”·¥~Ξ;«ü6Y„x™?’yð(D·£B€ÞOæÚTc4;(¨øÈá  Àî—Øì ‡Ãáp$$''§TWW …¢ÆÆÆ=¹¹£G¿¡VuØúçÆÆÆÆÆF©õÏÝÍ›?ïøO?).njjjjj:R\üÓÏ?Ï›Œ•‘‘Éår¹\nFF¦d2ÓÂæÄWWWüTßQê%/½ÃºC”t·Ü½««ê$ã§êêj„ФI“.]º¤“Â/—^–"‰û:NÝ…µ Fdºg€ú­^ؽ¡s2$O˜0!iËÖšš++«ñ«W­R«L럻s4(!>.+;{ïÞ}¡‘#GÆÇ}3hÐ ¼¨t6{Yär2‰äããSVv[qºQ Ñh±±ëW¬XÁãµ¹ºº²ÂÃõ]£&ˆX,–ŒtK²»EåKª¬¬5j”T"¶BGx,¢A"IÁÐ ‹@ÀHÉ ¤$Óe.HždÈ„P(d³3.”–’H$?¼X™i(®ËOoØA€‘9ÑÓSiº±6ÌusbBÏÔ¥^ÈåÒËRŸy:ÿ"®×îI$ [6,•Ž-ÓžÆQÞ¢t!zDèÃÆ¾9¶¢âÎàÁƒøñÇ·ßžhffV^Q1nì8©œ×oÜLLL@§>rd×®ï¶lIBÖ>®Ý™¶C,'§¤à™en¤¡z]½“–»¹k|»ƒ½ÃªÕk„Á[žž‹-TšºS# ðóÁv,•üÌÂ-»C‚ÂîW͉D±X,3¦Á7F‹Å$I H$„‡ÃѬ.SeÕLoÞU ¥±cÇ–œ??sæJJÎS(” ¥¥3Þ¿¢¼âÝwߑʹ,ÂÚÚ!àï_XX„%ž+9·aÃìËÕ+ry–.s# Õëê1jM‚ÑrƌƷûú2}}™ª§ƒîÔ[5s·üöÝòÛ'OİÍêîèè@µ´´`ÖÝ"™?‰DD"Q(ª¸í)¶7 BHªÏƒðoxbWW…ô*òVÍHö”ˆ_‚ýUè{ÜÝÝîÝ»‡*9_½råéÓ§B÷îßwss“ʉE!!SSÓÎÎNì˜Ãù׆xf™i¨^è3XQ=º•»<šLVÕÕtSSS„ƒÁ‰D³_ýu$«»¥¬¬ŒB¡P(>Ÿ/‰ðÿÇ “ÉyyyÚ´Jl⮘ŠïšÁ"*Dè{¨Tª££céÅ‹Šéøñy\¹zÕÉÉ‘J¥ªr»Í?fÔÕÕáé27Òв.`ŒzÉäNC.ßÅzD¨T*6?[ +9¥¢¢¢««ËÔÔ”J¥vtt´´´H$ …¢´dì³ÙÚÚº¹¹yàÀµµµ Öà˜™™µ··cÇ ЬkD»šªò®„PÜײ_; èÆ›‘‘ˆzçï~ø‘é£ê»½¼½½ÙìŒè•+Bélö?é^^éééÑ+W"„$7ÒЦ.4fÈ@ë{Z¥"¹_‰D¦”¶µµ!„ìììTìQåõ¹Úè>ФŸ×TÚYU˵9€ÞlìØ±¹{÷zyMAyyyefî;öMï ž3'¹<ŠL"ùøßºõÏ.27ÒЦ.JKÎi_èà ˆÐéô˜˜˜gϞᣛRH$’H$êèè‹Åd2Ù‚F£©Ò#¢Wë7¨4b"Ò®0µæŸÂûeèÛ† s->òb s«ðc$1¿Rj¢%~jbb¹,"rYvðbCyi(¨Kc0¡(eÈ@dÕªUŠG»ÏN•Úß ô:¨àçƒmÙ}€¾û§A`È@äáš,Êí%“k =M^z ˆÀ` €Á@ ƒ@  "0D ñaúº üF "ª¾Á[¼Ð@MMÍžÜÜòòŠöövWסA“&MÒ_uMMMä_»vÃåP©f¯½ö*ÓÇÇÃÃC5ÊãÃô•|ßÔÛþ€‘‚@ŒÉãÇׯ¬  ³²²ú믇‡Ò_ Âáp>ûü‹I“ÞÞ¸ñ+‡ŽŽŽ»÷î=vÜ è“ c²“éãïöÚ«11k±c@•}áB)BÈËkÊâ„P(d³3.”–’H$üF„X,Î/(8uò¯­ÍÓÓséV÷7¢ïÝ·ÏÛÛëã>ÂN)Ê„ñã'Œ¯¸¦o䲈¢ƒÍÍÍÃ\]£¢–2Dqþ°°Ð#GŠ9α£Åµµµ{öä–•—‹D"ww÷¨å‘t:ˆÁþÄúBðy.¯ W9"`Lnݾííå%óR~AÁ£GRS’SS’«ªª ±ô‚‚ÂÚǵ;Óv¤¦$_¿~Ï_\\\^^‘ŸÁN‰„{÷íï^æõë×ß›6M^c”pýÆÍÄÄ„ýûöŽó·k×wJóW”W$oûöØÑb„Pâæ¤Y³fådgeíÞmcÃÈÉÙƒ^Çí>"#ïÁå5ô*ˆ€1yöìƒÁy©¤ä<‹Å²µµµµµ]Âb•œ/ÁÒÏ•œc±X666X:žÿ×'#"–:88XXX„~òÉåË—»—ÙÒÒjgg‡Ÿú0}±¥%D.‹p°·§R©þþ>x 4?‹Ž?×δnn£) fþÑ¢E×oÜPü;‘÷àòšzš€Þ«´ä~ÌŠŠ¾[~ÛÒÒ’Ëå:::vÏÌår°c'''‡‹s8ÿJÇó744,]Ÿ„îeÒéô§OŸ4;ÅÇD”–`mm˜ššvvv*Í/îüñÇŸÙÙÙþúëùóç!"QÉwfy.³#F»§§¥*.(†ýUÔUiˆ@¯ÆŠŠÆ°úǸ»—–^œ=;¨{NƒQW_?ØÅ!ôäÉ› 66ÿ¤×ÕÕáùííì6}½ÉÁÞ^AícǾyúô™?þHæUUJP1¿dP²eë–ysç®]ûFãñxóæ/èžG’¼—énùmüW 4 ó0èí$¿}Ο?1&“É“& 0àáÇÂæ«z{y¥§§G¯\‰JOg{{yc·x{{³ÙÑ+W „ÒÙl¼¨™3g¦¥¥-a±œœœjjjó ¾øü3©ªÌŸÿégŸ EÂ÷§Owppèì쬼{W­$©˜ŸÏï077§R© YYÙx:N¯®®vqq‘Ê/ïÁåÑá·y =DÀ˜ 80!>nOîÞ¼¼®®®AØ¥àà9YÙÙÑ«V#„¦L™!>!±¾¾~Р .ì^½½ý¶o·îÏË[»¡¥¥ÅÜÜü7ÞøvëÕK¤bþ•+¢2227'%Y[3üý/½œJ2;(ðÓÏ>çñxRóUå=80 ˆ€‘qqqY¿.¦{:…BYÂbINGŘ˜˜D.‹ˆ\öbrF`À‹À…@ 0™>L¦âêìììV®X!󒼤üTÅü’û”àùýüüüüüºß%ïÁå5ô*ˆô.#ÝÆhs{eÙ-]µèˆô:ýõ—‚«Ã† “—aذaúi /Šøv®ÀÈ÷§+¸ZyòTµ0^JzDÎ;§8ƒ<ï¾û®f7‘Öº§2ÓéŽv2Ó EùÐŒ··7BèüùóRÇR$Ieè‡$ûKÔíQ:ÂC0ú åˆdT!3€°CÝÑNpë_=%&c¦«‹ˆÅbͪ–·ÕÐk) Dô7Â2Òm …Bíìä#DD¨ !ôòàÅŸDâ‹d±XL$) ŸÏÇoïPºG!!Á­§êÆ" B ±X,óªÆá `@J‘äd ·Ÿ[½Ú]q›ÆÆFø|¾™™™H$B/_4€ÇÆÆnÙ²E³Vé•Ì(£n,¢8ª€˜P^^~ü§Ÿ/]º„¢YX̘>}–Ï,Õ·Zצ¯ê›sÜ»w/9%õñãÇ’·¨Uè“”"«V¹iVîêÕJ2p8ì «« O$‘HX´¢R©XüqõòU©{%oé“ G Ç‹‹O R©¡áá;¿ÿN§×ÔÔ\½òÛúØ ÌY³>üÐWƒ2{&Ø•½8äã‰'öXÀ(¨·HJJzÈ>Þ´ !„¾úJõ2¥^«ˆŸ …B<àx{ÊÛØÁåÒËH…Éb’‰ê èŽ hs»ö G O̺u£ÝÜ“S·ã)ÎÎÎÎA³§¿?#8(fA{oÚ4™7òxmEEE—._nll¤P(oŒÅdú¸»»£žÚr´ªª ß/¢€3؆fJƒ "‘haa_.½<íýigNžÁN•~744TTTÔÖÖ …B …‚‰D&&²£“ŽŽ @ÐÞÞ>xðà‰'ZP)ê=Œ®A@¦³gÏ u&…àètz~ÑÁÿ¼?]^ ’´e‹ÝƯ¾´··çñxeååyò±@¤g´µµÉûwôgê"’#5²¿ú µ¶ªR”©©)v€w{`ã2’Ã.ÏŸ?ÇÏœ<Ó!ì0%›"„h4šâÂGŒ1aÂ333ì3[,c3^efîêê² …ÂŽŽÇm¨“™SJ÷ýBLÆÈž&bÿ ª¼¬³…3sÐoíÏËË/:(ï*Nÿ`æLyW+**r÷ì¡ÑÌB ˜2yò”É“±Kø@‰Ó7rYDaÑÁæææa®®QQˇ ‚é쌋/’H$?¿¬ìl©. ±Xœ_Ppêä)^[›§§çÒ%,*•*™Á‡é‹ÿyüØÑîC3JK}•ò@DùpŒFC3D"±½½ÝÜÜ;Å>\‰D"þu_,“H$É[°(©ðIÌápð9(Pe,6ótäûÓ­ë6J¦Óœ#y5ÿÊIû?të²zk| G S]]³³³‚ žžžò.¹½sçN¦/ó•áñ®b™®ß¸™˜˜0€N?|äÈ®]ßmÙ’„ÊÏ/xÚаkgB(EVLqqqyyEBBxèз۾ýêË/¥²Y[[c¦¦¦Ø1—ËuppÀŽ_HjhhXº4?Õà_iíKFJ×C3*+»qM“öö0G “££cMM‚Ñ™+W®ùû).„@ <˜²XÕ±ƒQ__Õ[W_ß=ƒ½Ý¦¯7i³‘‰ö%#e°¡ A>yW Ýd@O˜?oÞ¦¯¤û0p­­­¿þü³¼«kcÖ•^¼ØÜÜ,Šêëë³³sF©b½Þ^^™\.—ËåfddvÏ0sæÌ´´´êêj¡PXUõwÒ–­*–¬Ã€‘ÒõÐLÿÓä¸QçeB@¦©Sß=R|duôÊî+x[[[ƒƒçÎ –wï¼ysÿi×®ï:;;­­­Ç{x¬Y£lëÉ—‚ƒç¤³ÙË"—“I$Ÿ²2éM·™LŸX__?hÐÀ… ªõ\:))%ú§âW IDAT|ÕVL³) JÁ€<‰ qñ sg…†‡¿å9ßY5yÛ6æ¬Yò6A¹»¹¹»ÉþÒˆ/f‘ZÕ‚ŸR(”å‘‘Ë##BUUU§NŸ–Ê@ ˜L&ÓGAË% ï^£*%€>IQ Ò;_,×@@–˜_^^ž›“³”ÅB/ß5÷^'X°32‚;#s¢üE¨Ë`;«y   ÔèÑ£GÝ“5:Ø;¬Z½F(¼åé¹hŒ›@¤w^(@ïäëËôõeº ‚U30D`0ˆÀ` €Á@ ƒ@  "0DÀø”——'nNòaúú0}ƒçÍß½;«¾¡ÁÐÒ£{÷î±–,õaúJ&JjPBÓ¸vÃ6[ß cÂãñbÖ­?tøÈ¢?¾YVþ êïŸ=á9iÒúØ ÅÅG•ßoœvge/ù{U¯fŸÊ’%€^Þ5Æ$fݺÑnîÉ©Ûñgggç ÙÓߟH³ ½7mšÌy¼¶¢¢¢K—/766R(”7Fb2}ÜÝÝ{ªáÿðaúªTUUyxx`Çš’%€^0gÏžê:L2 ÁÑéôü¢ƒÿyº¼@$iË;;»_}iooÏãñÊÊËóä$Ñ@[[›‰‰‰aKzýyyùE±ãÊ;wÂÃBkkj¦¿?ƒ™‰¢ÓéÌœ)ïÞŠŠŠÜ={h4s„Ѐ¦Lž|XÔÕåíåJ&“Bµµµ{öä–•—‹D"ww÷¨å‘t:ËzäH1‡Ã9v´Xf6l`ûëÛW;Nê–î*ê– ²²³/\(EyyMY‚Å(RíW¥ y¿ ‘H”wàÀ™3gÛÚÚæûûûaåüòË/…E›››‡¹ºFE-2dˆÔ&y7bäUwûöíÝ»³ªkj¬¬¬‚ƒçÌxÿ}y‰½Ì£QWWçììŒÏª­©A:yÏàéé)ï^·Ñ£wîÜYy÷ngg§Ô¥âââòòŠ„„ø vºH$Ü»o?~éæ­›Û·§îLÛQS[SPXˆ%&nNš5kVNvVÖîÝ66Œœœ=xþŠòŠämßbŸâ2³a1ÄñcGñ`BAí˜î·¨Þ~™%䪮‰DH"–’™Ø A©Sß=R|duôÊî+x[[[ƒƒçÎ –wï¼ysÿi×®ï:;;­­­Ç{x¬Y³»Ädú„ø„ÄúúúAƒ.\¸¿kŒ»ûÊ•ÑB‘ÈËkÊœ9³±Ä•+¢2227'%Y[3üý/É™“!/Ûì ÀO?ûœÇãaSGÔ®"uKž“•½j5BhÊ”ÉøsiP…¼g àwðׯ¬ãóù þ£t§øFyÕy¾å™ŸÐðô©‹³ó§kÖ(Hì…C¦Gz/J¨n|ÚÖðWÖ|ýZ#ÝÆ`•e·tX1^¬ftÛ˜¾jñþsûaO®µs«ß 7/ añÚ;jkª7¬úÄÐM _û&e÷ g—ò[×ÿ¸_’üónùmÉœ¥%çXQÑ’‰</.>J¥††‡¿å9‘N§×ÔÔ\½ò[ò¶mÌY³>üP—{k°óèóºÿÌß—»qó·RueÞ¸dŪšª¿~:Z¼dŪ¯“3±ÿ Të‹€Ú—W(ueÁ<å¤<Ë¿ø ?^äÇÈ=ÂUñtgÒ,¥…ïË—nªŠkþD o4-1!¾¼¼<7'g)‹…¢YX̘>=>îm¦Y`(ª"/Ç–´ ;z^||¼ZùÅbñÇùÏ[•æöÊk¦&&ˆ„D]]D !Äá6Ù2løÏÚ©43„" D@MMMÖÖÖ|>Û÷¦½½ÝÜÜúrÚ=zôèÑ£ Ý t@y RYvk¤Û}||.òchvº3IÕ**++5lœB&$Òà »"â‹VVV$©¬üŽ)ÙÄ”HikN0!HˆF£ÕÔÔ˜™™!„?~|åÊ}4ôÆe@Po²ªnç‹H ¾LØð÷+WœÑĤ££ƒH&XÒé‚g-ÍÍÍ999«¢Ö´65[[[QLÉÉ;¶¯\µ¢¹¹ÙÚÚº½½Íf‡††>}úT•ÂGŒÖäÕúZU<y9]DÇóEzŒå¯¿"„„NNíÚ½ê‰B¡Lˆ>|í‘<!ÔÕÕecc󏿱­ÃÚÚš@ Éd>ŸÏç󻺺D"Ñ€T,üáÇøqffæ‚ dFíÛ·Oã´WZrN³U D°oÛ#ÝÆàK‘µ;¤_~ÿ÷È…âS Xþú«óêÕøi›»{mJŠÐÑQ“²D¢®®.±°ËÙÙ¹¢¢bèÐ¡Ø “ÚÛÛ-,,8NKKKWWWKK 6GÄÑÑ‘H$677«X¼«««d,ôfÚìS¢ÞÐŒnç‹ôäÐ ¹®‹BªòòÚÝݱ dЪUçåiR‰djjê}šD"µ´´´µµ‘H$Õß@ýðáÃÌÌ̸¸8Géi©†nJ+ÔèÃ!¤Í†fzÚ_Dj’“ñ™g|€V¯6¿­dѳOŸ>u6äï¿ÿ~ÞÑN§Óë;ë…ü®– cúôédª)BhÞ¼yÇÂÂÂÁÁ¡ªªJõ¡„Phh(ŽhÜB@ÀŠŠ6tÐ/M‘ö"#¤Å|‘žš::>ûàütЪU¡6M§‰øü«W¯ºÚÕÕ•››K „B!ÍÔrîì9d2¹°°`Bîð) ‘H$‰ÖÖÖ­­Êcð¡™ÐÐPˆEèÏ”n€±Ó$Áç‹ íæ‹jÕÌ U«è'NkSR4+ÁÌÜÌŒBXÙ!0€ÏçSˆT ‰,“»ALèê~£¼—OJ¡ý„æC3Æ2"#Å>)‰~âD›»»†³CB•—ÝBµ?ÞÜÜ|èÐ!33³ÖÖVÝÖw–H$2!™\¿yUËvÂÐ €þÀsDzxÕ Æ¤®!Äýøcí‹255µ±±Y¼xqKK ‰D"#Š Ã¦­­M hY2 Íè' 9GÄ C3ÜÖ3ÚÇhõÊ= ‘DjnnÞùã÷äóù<ÁšèU!*…ªeÉ04 ŸP;Áû?´Ÿ#bŒìlú‰5ÉÉ’sW5D$‰Ä5kÖ455YXXt¶ E"@‹ÅÚ·†fô†œ#b¡¬/Dè䤓ÒÄbñ÷ßêêꢩ-XH¥R;Z+ÀÆ©úª~÷®îÇ#]LAñZ[I$RTT—Ë¥ÑhHHlγ´´$TZ#6ûÓƥ߽kF‡hè[’Ú;ø3*…D „ +›ÇOjDb‘6Åér$@*"’óBŒè]3:™«¡ÀÝòò„ÍI!‚a‚Þ @u}ù]3=°ä¤òÖM}WôašOVÕÞΤYÇ:.|AðlþsU·TcáÃô=~쨡[€Îh¾|WK0†ì µµµ{öä–•—‹D"ww÷¨å‘t:!äÃô\QXt°¹¹y˜«kTÔò!C† „A:;ãâÅ‹$ÉßÏ/+;ëe‘ênÁOå•/¯±Xœ_Ppêä)^[›§§çÒ%,*UÛA_¥ÕBS½Aâæ¤Y³fådgeíÞmcÃÈÉÙƒ_º~ãfbbÂþ}{ÇyŒÛµë;,1?¿àiCîi;¶§Þº­ü¿òÊ—WNqqqyyEBB|;]$îÝ·_§ úDÀèíLÛáæ6šB¡Ðhæ-ZtýÆ üRä²{{*•àïÿçƒXbÉùóaa¡ ƒÁ`„‡‡i\¾¼r~=q2"b©ƒƒƒ……Eè'Ÿ\¾|Y§ úš€Þ«´ä~ÌŠŠ¾[.»÷â?þÌÎÎ~ð×_ÏŸ?G‰ÿ|É´¶¶ÆLMM;;_ìûÌår°cÇ— È+_^9 K—Fà§Ø>#F»§§¥*­ ô~ þ*jèÕXQÑØ‚ú·lÝ2oîܵk¿ Ñh<oÞüŠËd0õõõÎÎΡºúz23ã§ eydäòÈH„PUUÕ©Ó§±ô!C†|ûíV<ÿÌ™ÿQ\¾¼r“éƒg@X5ý;#£©©©¡¡‘9Q‹×›ëªÐoAôGö«V¯ oyz.Z¤ùЉ®Êý"Ðùú2}}™½§ÐoÁÐ  "0D`00YŒOyyùñŸ~¾téBˆfa1cúôY>³¤¶T7.½ü‰z¾y>L_™{Æô=Ð#Æ„ÇãŬ[èð‘E|³¬üAÕß?ÿzÂsÒ¤õ±Š‹òsK·O$µílokèzDÀ˜Ä¬[7ÚÍ=9u;žâììì4{úû3‚ƒi´÷¦M“woMMÍžÜÜòòŠöövWסA“&M’Ê£ô‹¸Î¿©küD2[¢ó^mš‡XYY;6<,ÔÒÒR·më GŒÆÙ³ç†º“üPÄÑéôü¢ƒäË»÷ñãÇkcÖx}ÄŽí©…ùK—,½p¡TŸU‰6OÔ´lÞñcG;º=5¥³³ãÇÓõÖLã="`4öçåå”w•N§0s¦Ü{÷ç1™>þþ~Øék¯½³V÷MT“6O$ÞMrûöíÝ»³ªkj¬¬¬‚ƒçÌxÿ}ìêâÇ‹ºº¼½¼ÂÂBÉdEŸƒ:ižÍÒ¥K#"–a§b±8¿ àÔÉS¼¶6OOÏ¥KXT*k[XXè‘#ÅçØÑbµžÚ¨õÍ@dÄhwÍnlii2dÈo¥ç5.œ@ ˆÅbW+ËniÖ6¨««svvVÁSþÛ^nݾ½pá=4J+Ú<‘bÛ’“—,Y2aüøæææ¼¼X ‚ºyëæöí©¡”ÔÔ‚ÂÂùóæõpóŠ‹‹ËË+âi4Úéé{÷í ý»TQ^‘¼í[ƒ¡n™F­o"¡û÷ïcAf™áž={ž?®záRrss)м ¹¹¹æææJ  rv‰Š\–¶CÆP³gÏä}ÂIMð”<Åz”fÐO¤‘Hâr¸---vvv+VDáé,ËÆÆ!Ä ÿ&.Nq ¢“æq¹ÜŒÌÌ7߃þzâdlìz„Pè'Ÿ¬^ó)ˆ°Xáý- A}8Á)èŸÀ®JE*]]]ÚT×ÙÙ©àj[[›6…€bµ5Õò>---¹\®££c÷K’Á„Ò =¼¬TÁ)¶!v}Þüýyy–––,V¸Ç¸qXº£ƒÃ‹GG‡«×æa›Õ€cÞ|3<,KlhhXº4Ï#ùdgg§e{ŒQßDëÞ_B£Ñ´)ÐÖÖVÁUèhÃÑѱ¦¦FÁ`Á•+W‚^Α2ÆÝ½´ôâìÙAzk&´y"ņ»~X,¾víúöí;r÷ä`éuõõƒ]\°%ÝZ6OfÄfog·éëM2÷ ‘×…ß·Áªiª Í(ÐØØ¨à*ôˆ´1Þ¼M_})ïjkkë¯?ÿ,÷ÞùóŽ;v¤¸¸±±Q üïÿKLܬŸfªA›'RlËÖ­ª«E"ú÷<›Ááp8›ñŽ÷;=ß¼™3g¦¥¥UWW …ªª¿“¶lU·„>¦ÏöˆìÙ³GO% …B¬p¡knn®Ìt:®§Vúƒ©Sß=R|duôÊî J[[[ƒƒçÎ –wïÀâãöäîÍË;ÐÑÑáêê çö*§Í¡n“W${ <ßòLˆOhxúÔÅÙùÓ5kðô1îî+WF E"/¯)sæÌÖkódb2}B|Bb}}ý A.\¨n }Œ’@d¤ÛuWy¨~ ÁÄtóæÍ999fffsæÌ‰ŽŽNMMÅOÃÃÃÙl6~:{öìaƒM]–D"‘ºººÌÍÍÛÚÚä… &&&d2Y²‹‚H$"„°Ù¦ ˜™™a!vwb±˜F£2™Œ•&°I*d2Y(j9î‰ qñ sg…†‡¿å9‘N§×ÔÔ\½ò[ò¶mÌY³ìf†rqqY¿.FqùJçè|‚ˆÆO$³%x¢—×/¯)Ý3ªé¶y!Àdú0™>Šó÷“ýÝ‘*="§K.¼÷Ž—Z…ªx‹XÐñÅšU999 ã‹5«BŠOU'/PPª¥¥ÅÊÊJq@ àªÒ廚5 04-1!¾¼¼<7'g)‹…^¾ú$>î›Þófµôò'êåÍëÔšQÐÕ¡Alj¾É[a«Øž={LLL4.<77‹cä-ßU¥pPjôèÑ£G6t+t©—?Q/ožQSu²êH·1Zfè'š››\UÜ›@¯úÏx‡Q©G2G÷‹ÔÖÖöž8FËXD"éª%@Ÿ§R RYv vìØ!3Ê+°«§K.hЈAƒúå'ìXADòÚ¨Ñ!!!1Ÿ­‘—¡7P<={¡0ªÎÁcy³P±EÝi­j)//W}ï[—ï*~FÞê\¥ø|¾&mú(5&«V–Ý’×á]ÒkòúnÁÁÁãÇW%3…B4ÇãÉËC"‘D"‘©©©P(‰DD"±««KñšŒ‰‰‰P(”y Û&„D"Q(,æÀVíbã5¯åú*õvVUjh…LL“¶¥ „¸\nÒ¶”‘Xò”Ûú?MØòí«¯¾ZXX8hÐ UJîìì‹ÅÏŸ?Ë' Åb1ŸÏÇD"‘X,njjRÚ#‚m "SKK BH$µ··c)Xf¡PˆÕ¢tm0Я(ùÐUÐ ¢ý-Ø>"’{„(>U‹ÆËwåõv¨Rxnn.ÇÈ[¾«åþñ@£¼GDƒ®½ŽÑ趪¼Su)~y¯*QÐôÙwÍà¤"ƒîq†âÐA]ªÌu¦ïjªÛáe\¢8177צp é³ˆ¡–ïboÑ“—Aò{ ±òòòã?ý|éÒ%ôòÕ'³|féïÕ'>L_}ïIÚÃOz¾ˆ`ï–³´´|ö왼<Øz] …" U\¸‹Q°|!D&“Éd2¾¯‹D"Áþîíñx¼¸ø*•¾óûð—Á®ÝÀœ5ëÃ} Ý@µõ½'j雈^ßÀWvãšþ ÅbÖ­íæžœºOqvvvš=ýýÁA4 š¼Óû0_|¢[YY;6<,ÔÒÒR^-=Ð‚Óø‰RRS ˆ½Rf þ¼–––¯¿þZxXØÀ±”ššš=¹¹ååííí®®Cƒ'M𤧧JiµB@O:{öÜP×a’ŸÙ8:ž_tðÀ|·?vôø±£ÛSS:;;~ü1]oÍTƒ6O´,"âÿûßÙ³g±Ó“§Nýù烈ˆ¥xìyÓüaøðáÉ)©XâãÇׯ¬ñúˆÛS ò—.YzáB©NŸ ¨§oöˆ@Ÿ´?//¿è v\yçNxXhmMÍô÷g°33Bt:ýƒ™3•bcc³téÒˆˆe¡/ÖÆÌš9ÓËk vééÓ§k>ý”ËmB/{ð~‘_~ù¥°è`ssó0Wר¨åC† A ‚¬ìlìƒÜËkÊâìÞÈeÝó+~¢î?‘©©éÚ˜µ11ëþïÿþO$êÊÉÙ“´9ÑÔÔT*›¥¥e`@À¡C‡_Ô¸?Éôñ÷÷ÃN_{íÕ˜˜µÊ~g@ GŒF]]³³3v<;¨¶¦!têä <ƒ§§§ZÏ™wà>C./ï€ïËA¬;ÏyýÆÍÄÄ„ýûöŽó·k×wXb~AÁ£GRS’SS’«ªª çWüD2)~¢Á..‹‡$nNÚ¼ysxX¨Ì¢ž={vðà¡¡C‡b§·nßöö2¦Í®ú<DÀ(INÆÿÏŒ÷±ƒAÎ.Q+Vʹã.—›žžþæ›cBcÇŽ¥R©ç/\@=~üøÆÍ›L¦Ì»"—E8ØÛS©ÔÿÿoïÞ£š¸Ö€!X¢€! è•®cm•ƒD œu$PpÙV "h‚ZZ_•§â½§¶>®ˆb“ Q_µzÎQ$ÄÛê=µUQ¡X•¥  ŠP æþ1tL“„À÷[.×ÎvÏžoGÂ|3³ggIdz±±±±±‰àñ$Eõí{A㈘nn&&&FFFÊó<ØìÀ \*ذa=QùòåKí¿? ¼5ƒBIþÁÀ_, U•OÓö©˜oA î¶XYZNus _¾Œ¨är9¢LËÛûèÑc!ÁÁÊ·6£G& ¦¦¦íííD¹±±‘agG”íííÕ·ïõ#€ýßøü³°çÏŸgeY¾l©ü??÷L&«©©Ý“šúèáCâaàQ£F5662Œ^‡„t ¯ˆ „Á`0•••Dùø‰“ž^^ž^^!óç“ ®_¿®fsânKNΑµñk,--‰JOc㬬첲²O>ù˜¨$AЈN§×ÔÖåêêjkë_i‘JêG$‘H:;;™LæÌ™3ËËËoß¹£Ð€B¡ØÛ3Ö­?p0½µµ¦ºº_ëiœ¨ÿ`"‚Bcá‚[ÿñßDùýÉ“Ÿ8yüÄÉÝ){ˆšæææ ÿúWOû¤P(\çÔéÓÜP.¹¢£……ÅÓ§O5nëÃbñùüúúúúúz>_àÃòééÞåG¤Lýˆ^¼x!f,[º„E䪕iiû[ZZ”[Ž3æý÷ß—ÀÂ… ¾;wîÛ³gëëë;::ÊËË““·÷4l¤C˜ˆ „Áðóû°âñ£5q*æL477sç…„†r{Ñ­‘‘‘ƒƒƒ¿ŸY3^ÈÚuëÉ¥8ºÃårœœœâV¯‰[½fÜøqÎ|õí•õeD¦{zz’ÏãŒ?~úô¿8pPeã?šyáÂEpppHJÜvïÞýȨèùîÁôCäCCH/pŽB’䤤m‰I¡óç- “ȶ IDAT÷ôú¹iÊîÝìÙ³»[û äÄU&¾|eÑ¢…T*•¬ ên[ò%F‹àñ"x<õûR¿6Z¯G¤üØíâÏ?ïn§nnnnnnDÙÉÉió¦jBB „2$æææÉI‰%%%G²²VðxðÇ7³$nûºßÌ"“É.^,¨««eyëíª€nG„ &"!dx\\\\\\úÞ;pŽ­mBB‚–³Sû®F„ &"!4| ØÊ Ôœ¬ŠB!½ÁD!„Bzƒ‰B!„ôçˆ „РÆOKÕwõ#LDBhðâEÇé;„ú&"!4x•–ÜÖwõ/œ#‚B!½ÁD!„Bzƒ‰B!„ôFÅ‘ Ò­ÕñëðÖ2B¡ÁOõdÕgÎà8N¼çâŠùB!‚·f†Ž÷\\q½„B†‘!³„B†‘¡€ÌB¼}?Ôw,!„P`"bð0 Aõ‡v ¾CÐ?o¾K}‡+«6…,'«"„z*€xþÜwúŽbpÑøž(7æocÀ¼PmšQ(”ÊŠG •˜ˆ0å,„Ÿ–ªÍu‘/Öö{p¡n„¯Œ˜555EFFef611!j¶%&mÙ¼‰(···/YºìÀ7ûu~ø4ÄC²BÌãWn@ÖâðuBãip±äŠÊzLD •Ê,DûÍ¿Üþ?Ú4£P(2™¬w"¤€B¡œ;‘«ï(ú‹ög„–ˆXZZNš4éÆÿ›>ýïðòåË7n477[XXÀׯ¿7i’¥¥åÀƒPw01HÝe!=š&¢}öŠ·{Pßuw24”ôúŒP{á<Þ[¶Œ7ÄâËþþ~ðäÉ“¯·m›:Õí݉™1cÑòÒ¥ÂòfÌð/(¸D$"¥ee2™¬´´ÌÓÓ ųg}rgððjq1•J;7ˆÜiGG_ ¼ví•J”)íe2ÙñüüK—Z^¿öòòZÁ333#æLÍnß¾}øpæÓÊJ+++.—ó‘Ò:UR©47/O,¾üúõëP.—ØuGGG¦Htõj1°XÞK/&®ë°W­\yêô醆‡¨ÈUϪ«óóOÔ××;O˜ëèèH4[²xñ™3g¤oÞø°XË—/366€ªªªìì#wJJ¤R©««ktT¤………rÌòW5N:­ÜOw·fºÚ°qö¬Y,–7Ñæùóçñk×fgeõñÇ`ˆÁɪ†G'YBÈ1ݘwïÞ€úúúôC‡Z[[ äîÝiÌi¼ðB±¸øÚ5(.._Gðxîîüúð×MMPz¿ÔÍÍí~é}hhh¨¨¨pwÿ@¾óüüUϪö§íKÝ“róæM²þøñüçuußìOÛ·7õÖí·ÉÖÙ³gKJî&%% |©´3çè1øã@~þÜwäqzwJ ‡Ë9ž—»c{ò/e¿(êä©S÷îÝOJLÌ êê»všŸÿäÉ“Ô=)©{R***òóOíÿóã¶}ýu^î1_Ÿ|¹õ‡~øjë—ÇŽæxxxìÿæÙìç[?ïÝ›º?m_eUeþ‰®Í“·ï˜={v–(3óðakkzVV¶Ê˜å©ì§; ]q9ósóòÈëʹ¹y8¹U &"F}òž‹k_:¯¯«ÕEŒ!(‹û£[&“Yr÷.H$E4íjq1Ü-¹Ëdº'lØ eeee‹²²6l06¦S§OŸ^$)€û¥¥‹.(½_ —/_ñöžnlL•ïüŠä dz¶¶¶±±‰àñÈzIQÑòåËèt:N_NÖ_¸X°rå ;;»‘#G.[ºôûï¿W³‘µ±¡±©©i̘111ÑÊ Å+"xööŒ‘#G†/ïê_")âñx666D0’" Ù>:*ÚÞžaff6gN`kkkTd$ƒÑõ²¼¼œlFŒÅÚÚš~åJ×µ¨ýiûþúWfn>â³°°›?ý¤ñ=WÙ–˜L¦™™YÑÕ«ðìÙ³Ÿ~þ™ÍèQ':&6€(ÿgOª†ixkÆhÌB´œ¬ªR]ͳ—MM“]™µÕUº ¡a*5uoË«–9súzú+7‡×ÖÖ–~èHŠ$q±±ù'ò?š9³ì—_bccÀÊÊÊïÃsóò–-]jeeEl5ÃFêÞ½³gÏzõêÕ¤I“^¾zÕÑÑ!‹×¯_¯°¯††F†Q¶··'ëíþ¨'@]]ÝŠ+É— E徨²97ïø±ÜÜQ£FñxáîÓ¦)í·A~wäNåƒihh$ÿ‰NMLMM`ôè·/ÛÛÛÉfäæ ƒÜüÁƒ_E"ÑÃG^½zFFšÏÆUö£=.—#ʱ¼½=ljj:ÖŸäEÇuw#r{rRÂÆM?&^úûû­Ž‹Sß&"C›,¤w=¿y#­zò¤ý÷6 ÛØ`"‚N„ÂGiü-¬/º«‡Ò’Ûfff £øÚ5ÍôƒÜsóò®ß¸A\€Ç_*,ܼicú!¾——'qtwvž……âw'N€w'N<þŸ&4Q/ÏÚš^S[;ÎÉ jjjÈz:^[[K̽¨©}{ÝÔv̘­_mµ³µUèG!#yçw¶lÞ$“É~üñæÞ½ûŽd+ΰ±±©®®?~¼|%þ6˜êêjkkzÏÞ5€·c©­%7ß¹kç‚ÐЄ„ æææ--- .R³Æ~ÔPèÊÓÃ#'''++»¬¬lõê8(-¹MþŸ"õÇssó-[6ÇÄÄ´´¼ž0a/<\c‡˜ˆ-³Þ]©©ª$²„n‰Å—ÍÍ͵ù]¬žüÙç4&S(̘¾¾>é釨ÐÖÖ¶;%em|ü”)“©Têöí;víÚI£ÑÀßÏ/+;›ÃÅÅå`zzاŸ*ïÅÇÇG ÆÅÆ_ x[Ïb …Ä]¡0ƒ¬Ÿ5kVZZZgoo_YYuŸ |¾À‡åÓÓ7‹@ ôõñ%*ÛÚ~1b„™™Y]]]f¦ˆl¬³Æ~ÔPèŠB¡p9œ;wÅÄD]a¨?`gk›œ”̾زÙÜÜ\c{LD @¿f!`mkWSù´³³Sg#„@Ë3Âa2™Grrˆ1X,VFÆa&Ó LgL™2<<<žUW8˜NA}}}2E™..S`ŠË”ÎÎ__Çu.‡Ã#£¢©Ô¹ÁsoÝê:Xr¹¾@°*2ʘJ ¸s§«žÍ P(‰IɵµµcÇ:|úGr3^ÈÚuë[ZZˆ ›^ž^I‰IuÏŸ;9:®WÞopppÛïm 7µµµ…†rÉfŠDq«×€·÷tg~Oߨ©®®±±qR)‹åMn-flß±côhzðܹÿûǼ…˜5ö£†rWFFFþ~~=‚árvž°=9IËÆ˜ˆ v=ÊBz·²ª©©™ó_&Õ<«lnz¡Ûàμ<=‰Kñºåì<áì·gˆ²•¥%Y^óç}Í™C–---¿=ÓÕÌÎÖ–,È㥉‰I䪕‘«º¦}„ — ‰z …Âf(Ͼ zûô/‹åM>¿ª’±1õ³°°ÏÂÂä+i4Z'?gV!Z/CB‚CB‚6wwwwww'_’Á+ÄLöC”ûQh _Pè Ä—¯,Z´JýÓÔ`D§fµžf!½ž&"}#µë8Ê—6BH7üýý¶hw]Ú „Âß~û­®®N Ìø›——¾Ã12™ìÂ…‹uuµ,ou©Ø0‡WD¯ËBo¤R{G§¶¶Ö¾GŽêûÕAÅÎÖnõšøÎŽO/¯°0óKJìÀ9v¶¶ j&ý^¯‘AªwYH×4“J¥”kn‡fÙl}GуäÛ^I /™&"ƒÑÀd!Úg¯Ãaqn„ú?)hx _Ù—oPR‘ˆ¬Ž_ׇxn(g¯!e•úÞ æýhz›ˆŒ°u^rL$4xŒ°uV®ëètø4^@FHŸÆ:ªX8k¬£ÓW)Êõ Iä§àOWDT·ÐУò— BHï𳉆¡®D¤úÆIýÆFÉ­›š!„~6ѰE‘Édÿ53Jßa þÅx×EÍÚ¸)Qß „þäüɘ‡+s áëÿ%°gÔ¹®ÕIEND®B`‚wxglade-0.6.8.orig/docs/html/ch05s03.html0000644000175000017500000000535312166606327020203 0ustar georgeskgeorgeskToolbar

Toolbar

You can edit the toolbar's style and bitmap size in the properties window.

Click on the Edit tools... button to edit the toolbar buttons. Use the Add button to add buttons to the toolbar; enter the label, an optional name and help string. You can use numbers or variable names as the button id. If you use a variable name, you have to provide extra code in the generated source code.

Choose the type of the button: Normal, Checkable or Radio.

You can move toolbar buttons with Up and Down buttons.

You have to enter two bitmaps, one for normal status and the other for the pushed status.

Refer to the section called “Specifying the path of bitmaps” for bitmap path specifications.

wxglade-0.6.8.orig/docs/html/ch03.html0000644000175000017500000000614612167336636017660 0ustar georgeskgeorgeskChapter 3. wxGlade User Interface

Chapter 3. wxGlade User Interface

Main Palette

The main window is a palette that hosts the menu and the widget choice buttons.

Figure 3.1. The Main Palette

The Main Palette


If you pass the mouse pointer over a button a tooltip shows the button's description.

The Add a Frame button and the Add a Dialog/Panel button bring up a dialog to add a frame, a dialog or a panel to your project.

The Add a MenuBar button asks you for the name of the class then adds a menu bar to your project.

The Add a ToolBar button asks you for the name of the class then adds a toolbar to your project.

The other buttons in the main window add widgets to a form. When you click on one, the mouse pointer changes to an arrow. Then you can click on a sizer's empty cell to add the widget to it.

wxglade-0.6.8.orig/docs/html/ch04s02.html0000644000175000017500000003235712166606327020205 0ustar georgeskgeorgeskWidget list

Widget list

Follow the widget list as it appears in the wxGlade main window.

Frame

This prompts for a wxFrame or a wxMDIChildFrame. A vertical wxBoxSizer is appended. In the properties window you can choose the styles and you can add an icon.

Dialog or Panel

This prompts for a wxDialog or a wxPanel in top level. In the properties window you can choose the styles and, for the dialog, you can add an icon.

Panel

This allows you to add a panel to a sizer.

In the properties window you can choose the styles.

Splitter window

This produces a wxSplitterWindow and two associated panels as well. You can choose vertical or horizontal splitting.

In the properties window you can choose the styles and the sash position.

Be careful not to put too large a widget in a splitter panel, because while it might appear normal in the design window, when you run your program one of two panels will take all the available space and the other will shrink to the minimum size possible.

Notebook

This produces a wxNotebook and one panel for each tab.

In the properties window you can add and remove tabs, which appear in a list.

Don't forget to click on the Apply button to transfer changes that you have made in the list to the design window.

Button

This produces a wxButton. You can enter a caption and the default flag. If you want to add an image you need a bitmap button (see the section called “Bitmap button”).

Toggle button

This produces a wxToggleButton. You can enter a caption and the status (clicked or not) of the button.

Bitmap button

This produces a wxBitmapButton. You can set the default flag on or off. You also can choose the bitmap for the button and, optionally, the bitmap for the disabled status. Refer to the section called “Specifying the path of bitmaps” for bitmap path specifications.

Text control

This produces a wxTextCtrl. In the properties window you can enter the text and also set the style.

Spin control

This produces a wxSpinCtrl. In the properties window you can enter the value, the range and also set the style.

Slider

This produces a wxSlider. In the properties window you can enter the value, the range and also set the style.

Gauge

This produces a wxGauge. In the properties window you can enter the range and set the style.

Static text

This produces a wxStaticText. In the properties window you can enter the text, set the style and tell wxGlade whether to store the control as an attribute.

Check box

This produces a wxCheckBox. In the properties window you can enter the text, and the status, checked or not, of the button.

Radio button

This produces a wxRadioButton. In the properties window you can enter the text, and the status, clicked or not, and the style.

Radio box

This produces a wxRadioBox. In the properties window you can enter the dimension. The style determines whether the dimension is the number of rows or columns.

You also can set which button is selected with the Selection spin starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.

Choice

This produces a wxChoice. In the properties window you can enter the position of the selected item starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.

Combo Box

This produces a wxComboBox. In the properties window you can enter the position of the selected item starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.

List Box

This produces a wxListBox. In the properties window you can enter the position of the selected item starting from 0. You can edit the list of choices, but remember to click on the Apply button to consolidate changes.

StaticLine

This produces a vertical or horizontal wxStaticLine. In the properties window you can tell wxGlade whether to store the object as an attribute of the frame class.

Static bitmap

This produces a wxStaticBitmap. You will be prompted for the bitmap path. Refer to the section called “Specifying the path of bitmaps” for bitmap path specifications. In the properties window you can set the style and you can tell wxGlade whether to store the object as an attribute of the frame class.

List Control

This produces a wxListCtrl. In the properties window you can set the style.

Tree Control

This produces a wxTreeCtrl. In the properties window you can set the style.

Grid

This produces a wxGrid. In the properties window you can set the style, the row number, the label size, the line and background color and the selection mode. You can edit the list of columns, but remember to click on the Apply button to consolidate changes. Also you can choose to let wxGlade to create the grid or leave it to the user code.

Custom Widget

When you put a custom widget in the design window you will be prompted for a class name. In the properties window you can set a number of custom attributes that will appear in the constructor call. These attributes have different effects in C++, Lisp, Perl, Python or XRC code generation. Four special attributes $id, $parent, $width and $height return the value you specify in the Common tab of the custom widget.

Spacer

When you put a spacer into a sizer slot in the design window you will be prompted for the size; wxGlade will generate the code to set an empty space in that slot of the sizer.

wxglade-0.6.8.orig/docs/html/example_setproperty.png0000644000175000017500000001434312166606326023047 0ustar georgeskgeorgesk‰PNG  IHDRPnqïK°sRGB®Îé pHYsÄÄ•+ˆIDATxÚíÝ{\Í÷Àñ—$$ü¨tAl6¹Nî²Y±•eÓæ*)×Ñì7Í­f“(—l†Š\G(£0 ¿¹´¹m?¦¢²2›ÕÏ¢Îïêèt꜓\’÷óñðpú~¾ßÏíû=ïóù~Ï÷|?Uš8ø(솒œñ;Ù·®r"È çÏr$áž¾“¹pþ,%9’p/¿)ü|î Bñ¼jõšÆ8çé;™°à¥xùM¡«,† ^&õ‡hþw;=é>!„x4@…B¨BHB  B!T!„ýòl¬P(¤…@˪‡]ÏRïB9…B!T!$€ !„P!„*„/$߇/•Bˆ²POßÉÒ;Bñ(TîñBÍäh%uáâEFƒ£SŸ'ZΓο²ÖMHøM¾fÍZÆŒMì¾½•6ˆI€Ï]utêSâ?9à­ýO*À]»v.;?ó€õ$øÓüp`-J¢_Ñ\ñh²²³©V­št„-€–fYp0ÖÖÖôvtT.Û»Ÿ+—¯°{OŒÊ'yavtêƒ×¸qDoÛFff&û÷ÆrãáëÖqîÜyòrs±±±aÒ¤‰Ô­S§ÔчÇh¶nÝFnn.={Úã5núúú¥–qÿþ}Ö¬ '>!{;;ÆxŒVmyæååÅþýûù;+‹×»wÇg¼75jÔ(±ÌÂ'W•ÔþÂ×Úò#zóf:wêÌ—Ë‚K¬—®õïܱ#ç ##ƒ•+ÉÎÎàÜùD:wꤶMDd$))7 ]IHð2N>­’¾)"‚ô[·X¶’!Áœ=sVç¾×eß  eºTÒ5P}}}þ=s&ááëX¾Žuá_ñï™3©ª¯y ëíí…q}cåßa+WЮ];ªP«V-FŽ¡ö†()ccLŒñöòäÀÁï4–ñÝ¡øümLL011ÁÇÛ‹ïÒ9Ϙ½{™0Á ssŒŒŒ7v GÕX¦6Úò¬Zµ*™·3¹sç ˜2yò$óÖµ½e©o!¿ ¾˜›™Q£F Ü\ó믿–¸ž®õïØ±#‰ç8xð Õª)?”éÔ±ƒÚ6|¸¿ ÚW¼ý^ã<1®oŒq}c¼¼<ËÔ÷B”éþH‚ꛫèñš>…ëÕ«Ç[oõbÃÆMŒ;–zõêi­DSS•¿¹ò «ÃÃùõ×_ùûï¿óß|zšc½…¹ÅÃ×–dfdh,ãvf†Ê6–– Õ¶Ñ”ç­ô[xŒ«úiT¬ŽÅËÔF[žŸÌbÓ¦M|³aµê0ÞÛ‹Î;é”·.í-k}•û¼þÃ}\½zuþÉÉ)q=]ëoÓ®!+V(ßÔ©SˆˆŒ¢“/]dêõydf¨·¯xûÍÍÍJÜ·ºîÏ¢Z½f#¿Ô{AxúNV‹‡:]-úk$]o¬¿zõ*ûöÇ0ëBBVÐݶ–––T©R¥ÄmŠ/Ÿ· ˆÜßç“gbX«ÙYY v¢±ÜÔ´TšXY)_›˜h,£¾±‰Ê67oÞPÛFSž 4`þüy˜›™•Z§âe–Ö~]ó|õ•W˜5 …BÁÉS§X¼ôs¢6mÒi¿èÒ^mõÓ–®®õ¯Y³&ææ$>Œ]»taÃÆM;~ Kå5ᢌMTÛ—šzS­ýiié4nÜH¹?ËÒ÷ÅÛ~áüYùµÞ @Û‡¤Ö/‘Êò‹¤{÷î±pÑb>š1ƒ¶mÛPµªóæ²téçT70 n:$%%ceÕXk>†††Ô¨QƒßÓÓYµv­Ö²CCØ:uŠòõ[={j\¿—½+W†2­`›¡aô²·×9Ï~ýÞá‹/¾d¼·7––$''ÅÌ™þ¥–©­ýÚò Z€ûûî4,ø@Ò+Ã]Ú«®û¯4e©—N [Å»ïæp¾Õ«'ËCV0`€s)í³WÙ_+CÃÔÚº*Œ)— BÃV•©ïKj»üZO<Ò·ð¥Ýϼ|9iÛ¶ ݺvãæT–/aê”ɼûî&NžLVV–ÆËS'M&lÕ*æb\¿n®®=ú½Æ:Ù´·a¼ÏLc™ÚÚ¯-ÏnÝm™3g.é·Ò±jl…ÿŒuÞgº´W]÷_iÊRÿŽ:±îëõØÙÙùw „­ZMçŽKißPV††2ÎÓ }}}\æÇ3gTÚ¿"t%cÇå§pvæì¹s:÷}yÛ.*§*M|vÃIÎøì[W9äÀ…óg9’pHåºgEVôv–Šœ§¨8®]»Æ§³çðõWë¤3D© ã`XðR¼ü¦ÐÕ?Ã/“úC4ÿ»,?å/ŽÐ°0þ¸ýé·n¶ Ûî¶Ò)âéŸÂ ñ<233ÃÇÏ`kÛQ#FH§ˆg@[½fS!‘r3µ\ÛW©R…ŸÏy¬y¾ˆJêÇŠÄeà@\”%*Îôyÿ&²´û»*CÛ*J? QYÉ5P!„*„@…B¨BH­ ´=\ž.„*„Ïgz#ýæ-Ѭ[·ŽQ£F1Ä͵RthÑQp:µiÙ¢%^^ãhXìñjB>²¼¼<öìÙƒ——'»cbÈËË«4Zøäòð5kyå•f,Z´DŽ4!dúøœ:}###8;wà;NŸþ]º<œERÛ7ÚÒ+‚:ujãæêJtôV•ms)ùN˜@tt4¿gdаaC&úùróÆM""£ø=ãÍš5cÚ”©Êg[–6ßѽ{÷í1†uák122RÖáîÝ»xŒGøšÕj¬¢Ž@¿Ý½gçþ8÷ëÇ®Ýߪ¤k›ãF[zEp÷î]¶DGÓô¥—”Ët™KéäÉ“, d[ôzõ´çߟÌâûcÇš?—èÍ›éÖµ+_/S®_Ú|GµkצG7ˆ‰Qã(fï^zõ´ÇÈÈH§ú!*PMKMåÊå+ô´Ï@±½½=W._!5-M¹Ž¶9n´¥?K…óD vÂÞ}ûùxæG*ÁKÛÜ;“'MÄÂÒ‚5j0ÈÅ…ììl&ùùanñpÙåK—•ëkšïÈe  »vï&77€ÜÜ\öì‰aË ë#„¨@§ðßîÙÃ?ÿ¤Ÿ³êÓÅ÷ìÙÃ@û7ÚÒŸ¥Ø}{Q(¤¥¦±hÉþûßÿ*§ŠÐeîúõë+_W¯^Ð<ï¦ùŽ7nD“&M8òýQìß´ãðÑ£´lÕŠ Lu®¢‚МœûÄÅ`ý×_©Ì?“š–ÆÄ‰“>l8Õ´Îq£-ýY«R¥ –øÏ˜ï¤‰´·±ÁÐÐP§¹”ÊJÛ|Gƒ\\øæ› Ø¿iÇŽ;ð0A™ö$ê#„œÂ?!ñññX·h¡ö†µ07çÕæ¯’PðEHá7™™ddf–0ÇæôŠ¢ASÚ´nÍ¡øxàáÜ;IIÉ[„}O»råï>ÔÆãã뇯M¬¬Ôæ;ä2•¡a¸»ßöIÔGˆE¹æDjõšM¥x¨—ßµW†¶U„~ây?®eN$!„¨ §ðB!T!$€ !„*„OQ¹o¤¯Ì³1ÊL“Bˆ'@«T©Ri;¦2·MQhe¾çOîgBh#×@…âiŒ@÷ÇÆI‰g¦·£ƒt‚x~èäiJ=¢¥‹Iÿ•³ÿ„x®( ¿/'é?!*¹*„@Ey´nמÖíÚKGñ$Oáuy#U½º–––ôçFAµjÕž›€óv¦ÜÜ\ûö#--o¾ §C{Õ>ÿñ̆¹¹9±1»©ZµªéBÇìÛ§vʸ)"’·z÷¡MþåóòòØI—AtìjK¿.lØA^^žÚ¶;¿Ý³Ë`ÚwîJ¿.DoÛ®R¶B¡ zë6\\‡Ð©[wú p!"2 …B¡±EGÑ…é¿]¿NÛöélû:YYY*£Á=ߢM®]ûí©í8×Áƒ¨U«±q¸sçOåò?îÜ!îÀwÔªU ×Áƒ”Ë×oØHëvíiÛ¾#vo½MÀœ¹*íÐ唾ø2]úW  å¥á õóÅ‹ìØº…ŸÎþÀƈHæ/XÈ붶Ĉ¥{·n-üŒM‘QjÛîßËšU¡ÄíÁªQcfÏaÇÎ]Êô¨-ÑÌ™K ëæ:KoGæ-`ËÖ­ëQô´½p$Ý´IzõìIvv6» ¦çøþØqn߾͛o¼ÁK/5}j;®¶‘ƒ]’““Ãö;•Ë·ïØINNƒ¹`T«–ryVV»¶oåô‰ãLô@ôÖm,]¬± m?g-Kÿ !ôddd²`Ñbú:9©¥Oòó¥¶‘Q‘7eþéç¨é]»6£GŽ(8-ݬ¶í‡Ó¦ÐÀÔc>œ6€¯Ö£L߀·§'µŒ9|6Fh­GIÆzŒR«Ë·{ö0bøO}ç}ð¾;Uõôؽ…BB¡`ËÖ­TÕÓcØûî*ëz{Ž£ÙË/S½º ¦“Ž/˜À¯ÔƒCK-Kÿ Q=±i OõªW7ÀÒÂ_ŸñxŒ©¶ži‘éwRo¦`ll¬òjjšÚ¶ --•¯--ò_'§¤(—¥¤Ü OÕùç¯'%i­GIÚ´nM—Î9yêgÏž£yóW9x(žÖÖtíÒå©ï¼†––8¼ý6ûbc9ñÃI IIÉ89:biñpžøó‰‰,[Â¥K—ù󯿔—CÒÓo•«ü²ô¯@ËàQ¿½633ãzR™™™˜™™‘™™ €……¹Úº7nÞ䥦ù§Í7 æ…oܨ‘2½©))7np0n?f <–võÅÉS§ˆÜ¼…îÝm¹wïÇ}ðÌvàˆá°/6–¨-[”WJFަ²Î´éþܸy“Á_òz÷îäääÐÙöu•ëÊj£O==róòÈËËCOOô[êÁöIô¯r _äfÖ}½ž»ÿMøW_ð®››Úº‹Îïddd²hÉR†{_å`ñ’Ïùãβ²²8rô{Æz×ZzÿúWÁ(+Eeyw[[Z¶hÁþ¸8""£051¡¯SïgÖ_¯µmK{ŠçP|<Ú·§m›6*ë<ÈÍÀÈȈþù‡/´\ûhÚ´ ±p÷î]–-)ñ£ö¯@ŸQ#ñ›àÃá#G±ïõ6ÇŽŸ`Æ´©¼?ô=µu{;:à9Þ§~ýIJJ"à“4p 2}Øûî,ZDRr N}ûÑË¡7#"Ul„V’ >ã©_¯½ßé¯öm´Çè‘äääp>1÷¡ï=ó{[GŽFnn.¹¹¹%^‹ý,(këæxŒóbÀ`W^~ùe­yÎ  …µ5ÿ{ŒEÇê7Ù—§…Sørœº—¶^ÕªUñ;ϱc´æ1À¹?œûk\§o'úöq*s=ÞâÆ{CÜJLstp N@rrrx×Íõ™ïÄ·{õÒØï:v`Ûæ(µöiê›vlÝ©²¬è‡“®ý+„Œ@…’B¡ !á0ýõC\S·n]é!d*táØçÒoÝ¢c‡Œ÷ö’BèóåYþ>=n_Œ5B9…Bˆ§6•§‚—ôŸ/pòáté±GtÄ#JHH Õk6Òâ‰+ˬr /„OcZHW¦;mO4B<¿dZF,-¤„@…â™ÐF–ô²·S;W(ô´{ó±ÔžåˆïI—ÝÈÒBù¯8…BAà¼y´jaMë–- ”K'BT¦hš59p NeÙþýû©ih(=«ƒ”›©¤<ÿ´¸6päÈaöÅÆ±w,‡≌Ø$&De  ãÇû°bùr•e+B–ãã3AeÙÕ«W7v mZµ¤¥usÆxŒæöíÛ|ä?ƒ¨(Õ‡VDFFð‘ÿ ­åçååñå_`Ûµ ­[¶`êäÉdgg«Œð¾Y¿žn]:Ó쥦8÷ïÇåK—”é999|ä?ƒ6­ZÒ¾Ýk¬X¢ ý¿øQSžË–Í›™>Ã+++¬¬¬˜>ßÍQQrÄ QYhßwÞ!##“Ó§OpüØ1þ¸ý}úöUYÏsìXFŽÅéÏpòÔi,Ì- `ÎÜylŽŠâÛ]ùsíÚµ“-›73wî<­å¯Y½šãÇŽµ%šc'~àþƒû,^ô™Ê: ñ‡Ø²u‰?_ gÏ^øÏxx/ë—_,%%%…ïb_l,ß9¢2:,m”¨)ÏÇåʕ˴³yxßãkíÚqùòe9b…¨,TOO/ooVA, $4lú:™€©©©Ne§¤¤`×ã µ ^”i‘©&j֬ɽ{÷”§§¥aee¥ü»I“&:•«)ÏÇ¥V­Züu÷.õë×àÏ¿þ¢V‘Y6…ÏùÀÀÀ&ùù1fÌ ÔÖñööÂÍmß?Áõä~ºp‘Ü‚i&.\ø™ÈˆÖ¬ gõª0~ûíšNe7lØã?œTžf§ÜL%©`¢3]˜™›“Td´ëׯ«¤?Ë›à›7·æÜÙ³*BÖÖÖrÄ Q™(€Ï_~KJf|±/ eggcT»6†††ÜHIaú‡ÓTÒü|}Y²§>}Z¸¯qãtÕ 1‚éÓ¦ñË/¿pÿþ}.]¼Èx/ÝŸÑ9pà@f@zzééiÌþ4@%½~ýúüòË/ÏdǸº¹ñÙÂ$%%‘””Äg 0äÝw刢²Pm–,ùœ ùóhþê+¸¹ÆÖÖV™6ó#Fö k·n8882ØÕ?úH¹NÑû%‹~+>j´޽ë1ëW_a¸ Ô¹^'MÆÒÒ’^ööôvp sç.*×^}&ø2 ¿'v?hѶÿ¶ÿƒaÃx£Gœprt Ç›v¼7Ô]ŽX!**M|vÃIÎøì[W9äÀ…óg9’pOßÉ*O&)œ\­²ÞÐ}ñâˆKË IDATxœìÝy|L×ûÀñϬDö ±UµýUË×–Xºø&ÖRDk-­.ŠD,-ÚRݨµÕÒÚ’P”Zj×ÚC‰ê·µVH‹R;I ²ÌüþˆŒ™d’ÌÜLñ¼_/mæž{Ï9wfî3ç®Â´¤C!D±Îm›¥ØCnð ì3ñþöH!»@wnÛ,EÉ ž—Ò®ßï> !ÄáÒo‹¹™|!w s;ã~öG!8whf)Pm×ãŽs;5]N¶Å‹+;œ<ýp­R4v¥ÐA!Ê8koƒ¶¾M߃þŒ@Ó :Œ}Ž ;GAŸ}fvãÑÑÑdÝ=®šqù:tø5~{ç fד'ûÖ ’ïæÚÅ£¸T®eñòB<쬽 Úú6}/ú§ ¦"t0æÎßc€1cƘ§0cÆŒ!Ê ÎÌ)øtÂAÅŠ8–«€Oíç‰ûs=ºœªêâafímÐÖ·é{Ñ?}EѨj¤H†u*àXεDÕ9”wË­¨4ú*DYgímÐÖ·é{Ð?}U¥D ™bX§¢h°F Š¢)•¾ QÖY{´õmú^ô¯Èht` c‚‚rÿŽŽ6k~ìØhrwþ£yö³ ª·CSH'Ö÷÷.0­ÓÜ$“ó*»‡vú¿1Ïðܘ?îsOD~ÂgSÔ6hi=(“õ™Ú–óË¿m—Ö6]TÿLÅ—ÂÊŠê_‘#Р  }Ð3fŒ™t wŽ˜@5výød_$ɾZéŠÆ®Ð_ƒß>kfô:3[K|êm¢Ž$²ô÷8²rŒ›­òÖãù±{L–?í|‘c·«ßË.•Xqëdku«­ÓÜÏ&ÿwµ4Þ—ü,Ý‹¬GQT×—Û.j›.‰¢ú·¾¿7ÁògƒÀoIÿŠ>ZÒxcX§FCþ>üÔ/·Ó¿KÂ;û¢QÙ‚õõeF4šb­úO^€»‹3Ý[Õ§ËêøVÐñå–„¯Ò½ô”ÓEŽeÞ=xýüçûhìü^vÙxØeªUwp¼4ùy8Ѻ®7mêzózDlòüëdM¥Q·¥uzÙÝ0ë³yþó}<åxž¹£º™lgQèØöWÛÿJ">õ¶ºÎçgbT[ЦÐúúF.tÑù¡õQŒ—3c›VÛÏüýëü]’>îüÜßÛè5äöÝ’þPëüF4†èèh²•ÕÛQØ Ÿì‹$Û›þÕÎ_¦(vÅöÕËî: Ùž\½‘ÍÒí±4}º:Au*²ì—X.dWb÷'˜¶å¯>ëGE7GšÛF—*ñr@%|ݸœ–ɺƒWX½ÿ2Ú;‘÷·;ËŽÿé ¯=ëKU/gâRnóãžÖºz·Ÿ@§FéÚ¸2U=¸r-“Uû.³öÀ}ÿÍD? ×,oãz~Ü~ƒù›ðƤu ((ŠRluªV ¬u5«\;…Ã篳|ÏeöžJ+ò=´„—‹-Ÿö¢u]/êV«Àí,-O%RË1ÓY~úõ4µNŽOvz” |˜¶å«÷_ GÓÊ m[ƒ ‡®Ò±aÅBë.N˧½xå_jx;s33‡¿ÆñóŸW‹ì¯©Ï¬yþö l¦¥hïžà𲻎‡]º>ðžKºÅ[ÍýiY¿/^'ê¯dvM!9=ˬu3¥¨mÐÒzr¿¦ëS Ðí9¯Üp9s¶iµý4Õ¿—¿Kfm?/£àùvÄa}ß ÃeQý3Ø…·Î/@Þnÿ˜1cøÅ ÎÜa°éeŠú¾å/Ë­§¸¾*$믌—ûtõiê»\$ –õj×$¬U5Þy¡Ï\cÛß)l>lúAQŠÚ-¯GSh}Åý~¨Û¦ÕöÓtY—yɬyÛKÿº_dîÈ3Ù¾z[Tÿ¬>5nÙðhá»JÍç/S4šâûzg!/WGµ® À¡ãç°WrpPî^›ºã·=¸gÛ“¦-V£ÐÅ?÷×hÏCdßÎbýžS´òŒÎþ•ˆ:x†„œ»¿V[wýAù[Ù\ÉqeÙŽ£Ô{Ì—žÍ*óë_—¸šãA·Æ•ØõÇŸ™Î†}§èøì“tiR™__àJŽg¡ý0\kZ<ìnè'{Ú]ÃC{ƒnëÛ†k9{²s´h3Ñêr8z!•£~§š½–SÙÕÈÒ¼Ãb÷GŒ^7Ÿð§É·yt§š¹ï×±xVl?Èí›7ÉÑiÐ* ™ÚrÜÆ­bç1½Næ¬Ã„5G™þVC>êZ›ìȸÂu»pÐÝÄ^q*´îTmá—°ôlZ€ ;ö‘yã:'ÿò7¾öÙddü°òõ™™;5bb¹s·.üsÅ•t\ÈAÃ5S?(…ÔiñgVƒåƾüÏ<憳ƒ†ãq×ùq×Iþ:q†ÌŒk(:Y8P^¹I&nEViÄÄ6¸â-OÓóè± _PÉÛ Z¸ oÎ6­J1ë2犒»~yÓWöõ,|}M°h:fŒéJÆ®äþýYÍ»÷Ë+ùšX6ÕÁôÁfϬ ú2ÃåÌ:^¢À ]CáÎÜÒ:q Wnc¼Ë‡b‡ŽÜ¾mŽM¥`e×áØî^næ Àï1'Ñ) ÷Ô:p|óym9ÂZæ&Øuðth°S`Õ$†´ö£CPßoÿ»x¢ªmå«{±3:JmÜ´›Ù¸—³ÇËÃ%IƒB¾õUrß[sÚ˜ðò£¬ÚcÏ„8nJ‡ç!;+“Çí.r,ç1²1=‚¹¤õÅE¹û€™Ü‹’ ¾ïñºÊܸ‘Î…ƒ—‰:xžÊŽø×~„†O=B5»+\Òæ¾‡…­SqëàâdÇç/×D«ƒù?ÿƒ’ðWÛЯs3bCwÛ¾ø÷Ë„ûy§M‚[4æäæ³dßväµg+3kG|‘ý-ì3ËÿÙ˜Ó‡üõ.WÓÛ™Ÿþ8ÃáãgH»–†N9: YJy²p&]ëÄMÅÅ¢vÔ^vd¸-êëÉ;jbþÈDú’¿_¥u ´²9G€Üø£=¤°üN-l}M±hZØe cÏoÞymPï:ÐÂ.âíõ}*YŒ¦iÅäü¹µ×W…$WÓ"㊢Ÿ¸l_"Þš4þ[·*óêý—¯e³hç¿9t‚tÊ¡3xcOœã³uññpåêõ,D坨S¤ë\Ð*VLÂáÖe:Tcâ€ÖèPˆ½˜Á²}—ÈRœH38¿óv_aÀóÞ|Ð/÷dRà\ E1« GRiQ…Çýž"+GÇßçSùå×ßqÖdR^{‹k˜>N˜ «Tð26oûMÊqSWŽDå¹Ebj:çöœcÓÞT¶Ë&Òuå ]§âÖáí¶µ©áíÄw›bHJN&EçÊ‚¨¿С#^ðeôú3Þ¯‚Öü™Œã­Ët ¨Î7o7áF¦Ž…¿]¦’&‰+:³?ƒ‚oJaÓíY×èõäoµóæü©cw Y:2q"C)Çumy2qB›W¿ÑÔ6hjÛË/ÿ¶˜· Z»>k+ªE!ÕÁøl»a™¹ý»‡Ç@‹>ú’fb$jò€®Røñ¥ /âow‡;_âÂ~ ›O«ƒy{ÒˆÚsŒršÛdêТ Õ•# w2qÖ×qðïÓl‹MB£t vJ6ZÅ…™8£(~>šÍÁã{p!ƒ,ìÉÂ,:”›…öãç˜Tb¡¢&‰,xÊΉãÚ'LÎ_\{Ok¸pö ®ºk(ŠEÑ`¯»M†Î ÔŒ” ¡CC:H×U ‘Ês]:vä¶YØ:E®ÃôM'Y¸ù•5W¸©+GšÎƒÕGaϱMø(ÉÔ´ób}ŒC¡ueýq-ï¡‚’N6öÜ G¥<åÈ´è3(ê;U˜ /ò¤æ_*(8ÅMœ©mçÄ?ÚǸ¬«ˆZnèÊs g´hP7õ ÛMm{–Í_OÞ?+ÖgmÅõÏܲ¢úWäÔðöÍÜ¿ éi ðýeÎæ. zêgÑØÙ“uGgS5˜%+ó&ŠC‘¿Vu~¸ÁÝ‘€eóeP º*¸ënàH:à–¦)9È4<ã ¤)ž ÍÁ™Û€”# Wý|¸pAW7å:å¸BÙŠŠ ™:g@)´ T"'u·QÐá®\# ÷ó›ÓF’ΓL4¸pNK–Ιë¸rSStÖÿåÏÁžë¸rW£obaëTÜ:¤+:’ðâ–ΉëT Gât~wÇ(”ÓÜ&Agºî¢dPž‹TÅ]¹³î %{´Š ˜ýä1÷»—'w\È EgÜϼv’¸sÕ‡•>"koƒ÷j›Vë^ôOŸÒãÜåxÕ˜#óúUßjã¨b…²2oñ_²t Ž®>Å/PJ¢ß{€QSà˜öÉb7Rqä}N¦}õO™m»(ÖÞm}›.Íþ]>°Ž›ÉîÐóW¬Õo“thɺ‘Bö­ë SqC¥¢ÁÞÙG/î÷ÃD)‡p$“cºÚ@mؓʉBËþÑý_™m»0ÖÞm}›.Íþ%ì_kœ©´ƒ’‚G׊8ºV,~fw‰j¸~gXÿp>êAŠgîçdBîn²G™l»0ÖÞm}›¾ý+ð4¦Œ+§K­±²â,{`*åÎ?a‹Î…@,ÝÏî~¶-JOùJÆ©=Œ.̸ršù½ló×ÄÖ<]¯ÁýîB©;z$æ~wA›ÒwÙi£ jþ}`Bïéz ŠàR§~Cþ>|è~wC›e2€º¹Ë‰‘‡Ýî];²ÿ]¸––&ëhî¥Yﱋ¥¡@uswçÐþ½÷£/ŒjížõmàÐaVk¯°À/ÖÇšëQÙž-§:€^¹z•iÓgÒ¦UKºwy 7WW.^¼DÔŽò†›áâ¥KÌ_°€Ã‡ ÍÉ¡Aƒ¼ûî;¸»¹1â½÷騩#-õó_¹r•¡ï¾Ë¼¹spttä»yó‰Þµ € À@ú½Ý‡ÜŒ’mÛµ'jËf£öò¦å>óþŸ>KÔªù(Gbÿ¢QÃÜ«¤gdp8öon¤§SÁ%7©_Ìá#ÔzôQ\+X–ÃÜÖÜËà?Èö¬ŽêºaÓV‚›Óºe~ZÍš0 ï[ú×ÙÙÙ¬ùiÿüÿFèÒ¹£~Ä2pè0zõèÆ¶_v’’šJ¥JéݳW¯^eKÔvRRR¨V½¯÷î…oåJª—1¯݉ھk×®S­z5^ëÙƒ*UüÔ¾=Å7~a¡!Œüಳ²ø~á"æÏ_À°wß¡w¯WŒ$°ys4šÜ£,K–,¡ËKqqqaá¢Eœ;wŽY3¦ðÅ”¯Xöã¼Þ§O±íæÑ’Î<Íš6á÷={ôôôé3èt:NŸ9C½º¹IÓöìÝGó矌GS999¬\³–aggG«–AFuggg³rÍZþ£/_ûÓzýò:ŽÍQÛùý=ܼy“õêÑ£{œõ#Ƽÿ—VðKÏÈ`̸‰Œýô#Ê—+g4}ì„IŒùx4åœ íg^ ûî¶ÇOœ`ͺŸIH¸Œ››+í_hËsÏ4+ѺXc{.î3-ê3{P©>úω4nÔ¨Èy6Gm#>!Qï`Ôû#¸Ç–¨íFóÄþ}”w…òõiâ߈Ysˆ9Ë!L™›úõëãä舋‹ o¾ùûïܺæïï³s9vÝa^Š»Äþƒéܹ3¿ìŒfàÀP|||ðññaÐÀP~Ù¹³TûkJ½:Oqî®_¿À©Ógyºö“œ:u€Ô´4.ÆÅS¯ÎS–ݵËWùøÃõþþ>vܨ|óÖ(’’SødôŒ9‚þ1~Âû/Ñ»8yò_ÞƸ1Ÿ­ÍfÃÆÜ…¼@>}Z©Ž]Ê—§QÃúüö¿ß¦ÿöûï4öoDùråŠìgžÂ¾{…­Ç‚–оm[¦~9‰áï áÌ™s%^klÏÅ}¦æ¼Õ4=#w¢Ÿð²ïÀAzt} Ow<=ÜéÙåeö8h4OŸWzâãビ£#-ƒ¹u믾Òoý´³çΗhsúÑ«Gw¼½¼prt¤MËœ¿pQí[c–“'NòÁ¨éÒ­;mÛµçå.]IINÖ—÷îõ ‹—,%G«eÑ¢ÅôìÑ'§ÜduÉI‰øùÞW©R•¤ÄÄRí¯);;ü4dÿÁÜÉé3§éðb;NÉ  {÷íÇ¿aC4vv–ݳ?÷3ñp¿û™ÚwðOº½üîn¹Ó­ËKFåÿûý^éÑooÊ—+G×—:sèðáRZÓÜQ`þ-Ùµûäää¹£°Ý¿ýA«Af÷ÓÒ!íZ×oÜÀËÓ“×z÷,r~sXc{.î3½×ŸÙ½ zÞ¥|yÒRÓðññ.tžÜò»É˜*VªHZjªÑùh4å]\ÈHO§k÷úògš5cá¢X°`ÇŽãý÷Fè˼¼}ˆOˆç‘5ˆ‹»„·Áú9::pûöm}ÀMI6~ú¹bÅ ˆÏ4k‹—Øü9ÒoÞ¤VÍšd¤gÍ{÷óö[o˜\.-5µÀgb\ž†·—þµá¼IÉ)Œ?Éhš5×+¿ÂF²¾•+áççË¡#GhØC‡SëÑGñòô4»Ÿ–~÷Bû¿Íæ­[Ù°y .å]èÑõeê<]p”o klÏÅ}¦÷ú3»TÐ'ÿïÿ8xè/´i]è<îî$&&âçë ÀÕ+Wq÷¸÷¹`l¥†nݺEùòåqvvæêåËÌ™7Ϩ\QzõêÉĉ“6ì]£3Ý-ƒ à½Ã˜IË  }ù?ÁÊU«éÖµ )©©DDDÕíîæÆùó¨Q£øüÝÅ©^µ ìÝÇ£5rEÿúúòüÜ=<Œ>“Ä«‰ùÊÝILJÖÇNÌ7ÂöòôdHXÞ^^˜r/7Ì–AlÜ´…€† Ù±k7½ºwÓ—×Ïâ˜ZÕ«Òïmt:=Æ¢¥?òÅø±ªûÖÙž‹ûLKú^Ø"Õ»ð_|»vóËÎ]¤¤¦‘ÍÙsç™3~žÆ±bõ:RRÓHIMcÅšµ4ñoh•Ž[â~ö£m»öþŒxwóçÏ'øå.¼7r$õëÕ+°¬bGÕ*UiÛÚøKÝ»WoªW¯Î !C4d(Ô¨A¯WzéËß:„ýöÓ­G>ø`$FË÷ìÙƒw† ³Úõ Íš6eÝú üßð?ΆÍ[x¦i“B—iЈUkÖ‘š–FjZ+Ö¬3*oܨ«Ö®#íZi×ÒXµÖ¸<°ù³,^¶‚øË—ÉÉÉ!..žy éË+¸¸ù²UÖ¯8O×~’›·o½{7NŽNT¯VÕì~ÇÔzÌûþâÐjµ(VHoí¹¸Ï´¤ï…-R=­T±"ï ãçõÙ¸e ™™YT«V•¶­Zêçiß®-kÖýÌä)_Шaڽж佶ÐýêGQgº›4iL“&¦u6z½mû/¼þúkØå;†èèèÀ ° h²îš5kòí4ã]ÎN;èÿîÚ¥ ]»t1kÌÑ8 «ú™'îÐ'žxŒ¬ìl~R¢}Û6¬\³–q¿ÀÎÞŽÖ-[püŸ»9ÓÛ·kËŠUkø|BnyPóæ?ñ¯¾<è¿ÿEQ4Ìùn>‰IÉTªT‘àwÚ¶iÅ”©ßpóæ-«œH2u-¨a½­‚Yòã  1š§¸~ÇÔzÔ¯W‡ÈŒ¯oeú¾þªÊµºËÛsqŸiIß [¤Ï !ñ*WN³*ôñ2ÿò’êÔí•R͉¤ÕjÙ²e+?­_Oø¬™úK™î¥Ý»v:t¸Í<ÉüR\sç3î³­Vçøü‹¯mfKüŽy}·¥'Ò÷]v•ò•j¿wU¾¼ðÂf´{±¾•+óÉGÝ—ài+V®YË ­[‘•ê5?Q¿^ÝûÝ%!ŒHµAָȽ,ðñöbòWSÉÎÉ¡þêÜáÅûÝ%!ŒH6«E` Ñí¬BØš‡wÿP!JH¨B¨$T!T’*„*¸tϤ6÷»O6¯4¯µ5O×kp¿» „MP…¦£¢Š¿ôa ¢hò]¢p² /„ÅØ½Ëôóv%€ !„J@…B%¹É¶» „¸wš¶(v  6*tèðûÝ!Z:ά¨@m˜N§»ß]â§(ŠEÛ’%Ù $€ !ʼҺON" !„J@…ôôtFü1ééé%ªÇ&hqÉͬ•üL!r´ZÆŽÏ;n<9w’ó©aö1Pà æééI€#B„àææªºñ<†O`oÛ®}'²ËÚsùU¾›g;þòÕûØ!\³gÏ&&&÷˜hLL ³gÏfÈàÁªê²è$R^ KLJ""2’Yáá|8òU ËåMÃ@*„°ÌÁƒUÌüTíÂûx{38,Œƒè§eeeIÏ^½éÙ«7á‘deeéËÅÄ6h0ƒƒéóúlÞ²E_–7º5ü¿áˆ×ðïâÚiÛ®=6n¢ÏëoÐ18˜w† ãìÙ³jVS!ŠdµË˜–.[ƹsç˜5c:_LùŠe?þÈë}úä¾þr ƒÃÂhÚ´ ))©,Y²„öíÚÕµe³É]xKÚ8xðS¦|‰‡»;«V¯áÛé3˜6õkk­ªâSZw÷©  IÉỈœ‹ÃFúi¿ìŒfÜØ1øøø0h`(Ÿ}þ¹>°ÙÙÙ‘”œDjj*•*UdذwUu¸¸v†‚§—'Ý»ueùòåªÚB” !C†™=¯%wZ@óv¥=<eéÒ¥ü°x1®ÜJãÆ–4oV;€>x899q;3Óâv„eGi]H¯ê$’)^Þ>Ä'ÄóHÄÅ]ÂûÎ(à‰Çç³O?E§Ó±oÿ~¾š6•åK—¨§¸Û¨ŠkG!î«]Ú2(ððILLdvD$-ƒ‚ôå“&MæÜùóäääÜiØ»0"Ë IDATtÓînnœ?Au;BQ”3gêOT·mמ3gª®Ëj'‘z÷êÍÜï¾cСü·ysz½ÒK_ÞìÙgøüóq\¾r™Õk0jäû&ëéÙ³ï FzzºÉoqí”e†—/åý-׃ a™°°0.\¼DLL 4 ,,Lu]&“ÊIœûk÷®„.Oc EáïÇŒ¦¥§§3aÒ$>úðC\\\ŒÊêÔoXàqvyÛ¤YIå„¢,sqqaâøñ%®Ç&î…Bˆ‘P!„PIvá…ežM݉$î 9™'DÉå?dÍù%€Ú(9/„í“jƒš¶Ñ§9‰$„*IB•$€ !„J@…B%  B¡’œ…·A¥uѯÂ|Í[;PeIZ!„uåSa$€Ú0¹˜^ˆ’SÅ¢m©¸¬†$€ !ʼҺ1EN" !„J@…ôôtFü1ééé%ªç¡ y阅"G«eì¸ñ8p±ãÆ“£Õª®Ëìc †AÈÓÓ“ÿF„ ÁÍÍUu㥡m»ö’Ñ•ŽùAb˜TN’É ¡ÎìÙ³‰‰É=&ÃìÙ³2x°ªºTå…OLJ""2’Yáá|8òU ËåMÃ@*„°ÌÁƒUÌüT…÷ñöfpXý ÐOkÛ®=¡°jÍ’’’غyYYY|7o>Ñ»vH¿·ûâàà _æí·û²zõrrrhÑ"ˆÐ°·Ïí–9˶™w©BÞh9/àŽJÍ©sè!,_¾œ”Ô{ì1†½ó5kÖTóV !Ê0«^Æt$6–Ó¿ÁÛË€¥Ë–qîÜ9f͘ÀS¾bÙ?òzŸ>úeýyˆÙ³rÛõÕ×,ûq9}^{Õìåó·ijÞ9u¹x•Œ+§Ù3©Í=ËYÜó‡Õî]; :\žÆ$„(ŠR ×{zz:&Mâ£?ÄÅÅŨ¬Ný†g—·M6EùJµˆß»Š›ÉäiLBˆ‡‹‹ Ç/q=ŽðBQîk•Ýw!ăLvá…ežM݉$î{u2Oˆ²,ÿ $kÎ/ÔFÉx!lŸPÔ<°…Œ>…xÈYx!„PI¨B¨$T!T’*„*IB•ä,¼ *­‹~…ækØ¢Øy$€Ú(KÒ !¬+ÿÓ˜ #Ô†ÉÅôB”œ¢(mKÅeµ0$TQæ•Ö)rI!T²Éš—ýS!JCzz:£?þ˜ôôôÕc“T!JKŽVËØqã9pà cÇ'G«U]—ÙÇ@ G…Š¢àááAƒzõèß¿>’¸Ôý²};3gNçσñôô$0¨ò)+V,~a!„ÞìÙ³‰‰É=&ÃìÙ³2x°ªºTå…×jµ¤¤¦°zõ&NšÌÔ¯¿RÕ¸0_øìY ÂsÏ=ÆÎŽ9‘„…†°rõšûÝ5!(CV0óSu^£ÑàíåÍ«½{óJ¯ÞúéYYY|7o>Ñ»vH¿·ûâààäŽbC `Õš5$%%±uó&²³³‰ˆŒdgô.ìííéÚ¥‹Q[Z­–e?.gëÖ­ÜHOç¹gŸePØ@œ ­³,Zµf­ÑëÐÌœ1ý>õF*¨V«%-5ÕëÖñdí'õÓ—.[ƹsç˜ugÃþbÊW,ûñG^ïÓG?Ï‘ØXfLÿo/o–ýø#/^"2"t:¾˜b<š]»nGŽá‹/&ãZ¡³f‡³pÑ„ è_he]FFóç}ÇsÏ?¿»"ÄÁ&Rzä?;^¡B¦ì¾ÿ²3šqcÇè‰ÊgŸn@ 5 tÛwìàó1cðñöÖ/3 t ¾|ÓæÍŒùì3ü|}пCßy×(€æ¯³,ó«œ{ÌÓÇLJŸ7”ÍѶÖ2d˜ÙóZr ªc ©ii¬[·ŽYá|9yÉI‰øùúéç©R¥*I‰‰FuTÊwÒ#)±à2†®\¾ÂÛýúMÓhŒ/È_gYù*ׯ_'2"œaïeÝOëïw—„°y¥u!½ê;‘<ÜÝéѽ;=_饟æåíC|B<Ô¨@\Ü%¼ó¡Ï›”·ñ2ññqFå•*Ub„ñøV®\h_,¹õª,puu%$t á³gÝï®ñPS}èµk×Y¹jµ«¥ŸÖ2(ððILLdvD$-ƒ‚Ь§eP‘$&%‘˜”DxD¤QyÇŽøæ›o9þÙÙÙœ9s†‰'«íökÈàAœÛ½k'¡C‡ËÓ˜„°EQ äzOOOg¤I|ôᇸ¸¸•Õ©ß°Àãìò¶É¦£¢(_©ñ{Wq3ù‚…xÈI$!„PI¨B¨$T!T’*„*IB•$€ !„J@…B%  B¡Ò@ó'¶Bˆûå  Ba+¬r+§á¨PQ<<Ð-ûñG.^¼DdD8³fLgÿFó¯]·Ž#GŽðÅ“Yôý²³³Y¸è‡"ëBk±ZÍ˱ÜîÅôìÝ›M›61dÐ }ù/;£80|||40”_v?%zàÀP¼½¼õ¯·ïØ‘»Œ··~C›6ofðàAøùúR¡BôïÇo¿ýVdBa-íÂç,~ÈaúçVæHMKcݺuÌ àËÉ“HNJÄÏ×O?O•*UIJL4ª¯RÅŠF¯“ .cèÊå+¼Ý¯¿Ñ4Æø7Á°Î§ë5 rÆ´¢WRñÐ2Œiæ°øhÈaú¿ kÈÃÝÝ»Óó•^úi^Þ>Ä'ÄóHÄÅ]Â;ßzEQŒ^{û/gT^©R%&LoåÊ…öװΣGbŒú/„yÔ ®TD*.B_»vµëÖRë±Zúi-ƒ à½Ã˜IË  "ëiDDD$#î,iTÞ±c¾ùæ[¤J?.\¸À²eË=z”ê¾ !„¹¬vÞðZPWWWê֩è÷?ÐOëÝ«7s¿ûŽAC†ðßæÍée0B5¥w¯^„GD0 ${{{ºuíÊŸ‡î&|êŒF£aì¸ÏIH¸LµjÕxãõ>ÖZ%!„(’U¨áñÏÂ8::0(l ƒÂš]‡ƒƒC‡ aè!úi=ºwÓÿ­ÑhèLçà`ÕýBµäVN!„PI¨B¨$T!T’*„*IB•$€ !„J¥r¨¹ä2#!ă̪³»oö¼Õªø?“Bذ2¿ ¿bå*Ú¿Ø+W(+jÔ,¹—„ʧtê×_ñûïÿ»gíiµZ6nÜHhh6mB«ÕÞ³¶…eß=  ³fÎàß“'yòÉÚÅÎûFß¾œ;wNÿzÛ¶íú¿Ï;Ç}û2}Æ ¶FE-·%j+ÓgÌпÞà*T sp0n®®8pÐ k"„¹îIý~Á|Ο?ÏìˆH¼½‹¸qcŽÄþ@bb"³ÂÃÉÈÈàð‘X6p QÛ¶±ë×_ˆþuÛ¶mgÐÀ»÷گ߰ààNwìÈÏÖ[{Õ„±R  «W­$.î‡ýÉ¢…ß3~³—÷÷÷'öH,;vìÀÑÁA(ccc ðo„½½=Íüù ˜7 æÏÇ£GcgŸ{^,!>žÿœ EP ‚‚‚8ñÏ â¬¹ªBˆ‡X©ÐeK—ôßæ|öé'Lÿö[Šƒƒ£ÙË7¨_Ÿ£Ç¹©@FŒÎÖ¨m;~ŒõàééI«V-Y¾b:uÂÓÓS_ÇúIMK£cp0mÛµ§cp0©iilܸъk*„x˜•J]µf-;¢wqâÄ?üï·Ýtìdúqs…)W®¾¾~ìúõWiÚ¤ 999üþÇøùUÑgÝ<}ú4[¶FñÙ§Ÿ°fÍâârŸXŸ™™Å¶mÛY´ð{¢¶lÖÿ[øý¢¢¶‘™™eõuB<|JíhµjÕY¼dï¼; GGóGŸyšø9‡Ö­ZЪe fΚM@€?·nÝâ‹)_ñáÈ‘<÷ì³ :˜ñ&r;3“èèhž¬]»@ª?__žø¿'Øu'µ²B”„Õó²³³cÐà!ÅÏh‚@ ."00ÈÍ#9g.ýs茙3y)8˜ÿü§.Íš6#îR<3gÎâôÙ3¼Ùçu“õvêØÅK–ѦMkÀôõžywHU&„¥@Kâ±ZµØ¼qƒþµ‡‡‡Ñë÷ß{¯À2]º¼\l½Íš6£YÓf@ÑÁP¥¢8V  r{¦âabµ*#6!ÄæÌß /„¥E¨B¨$T!T’*„*IB•$€ !„J@…B%I*'„*IR9!„PÉfï…/©¶íÚ:Â-l´\ÜCDŠeËhZˆ‡O™  Å).à™*7œVT€B<lò$’µ’Ê !Di²Éj­¤rBQšlrÞßߟ;¢éÔ±ƒQR¹öíÚK«V-ôIåÞ6œÿ=ů¿þÊ7Ó¦ê“ʧ¸‡%ç/—Ýu!D~6@ԯϬٳ»Iå–ý¸œöíÚqìø1F ÜM*·xÉRôïo”T®8jŽ !„!›Ü…/iR9!„¸l2€BÉ’Ê !Ľ`“»ðP²¤ry»ø’0NQšl6€–4©\IÆ™H%Ø !$©œB¨$Iå„B%›=‰$„¶N¨B¨$T!T’*„*IB•$€ !„J@…B%I*'„*IR9!„PÉfï…/)ñ››+OÕ~ŠÐÐT­RU_n8NINaɲ¥ìÛ·Ÿ«II”sv¦ví'y)¸3Mš46¹Lþö$ñœ—2@ánÀºví:k×­eÊ”¯ùfÚÔó%&%1lØpš7žñãÆQÙ·2·oÝæØ±£¬ýé'}µ¤MÄsB”u6yÉÚIåÜÜ\éÞ­§N2ÙÞ¢…?ТE ôïOÕqrtÄÍÍ•¦M›2iÂx+­•¢¬±Éjí¤rׯ_gåªUÔ|ôQ“íí;°Ÿ¶mÛ”ÒÚ!Ê*›Ü…·VR9Ãã‘^^^&wßÒÒÒ¨X±¢Ñ4Ãe‹J6'„xxÙdµVR¹¨-›Ñét$Ä'0åë¯9u꾕+hÏÍÝ«W¯R­jU£eÁüìœX…xøØä.¼5“Ê)Š‚_?FÉô™3õ‡ øû³ukTéBQ›  `ý¤r•*U¤n:쌎.PözŸ>lßþ sæÎåüù ÜÎÌäÆìÝ»·ÔÖOñà³Ùê@JjªQR¹”””"“ʵnÕŠ™3gZç‹íÛ³iSÁ]ðÊ•*ñí7Ó¸q=‘£>䥗»ðfß¾lÙUèqS!„°Éc P:Iåü5¿Q#“å•*Udøðw‹ì“¥‰êäP!Ê6I*'„*IR9!„PÉf !„­“*„*IB•$€ !„J@…B%  B¡’P!„PI’Ê !„J’TN!T²Ù{áKœÄngÏžeî¼yüõ×ßÔ­[‡~}ûò¨ÁSë ëñôô$À¿!Bpss-¥ž !$e2€—Ø-..ŽFŽ¢gϼ7l8;££9êC¾™6•*Uª¨+1)‰ˆÈHf…‡óáÈîÁZ!lMžD²vR¹ü-^L§NéÚ¥ ž^žxzyÒ¥ËËtìØ/1¹Œ·7ƒÃÂ8xð€ÊµB”56@­T.¿C‡bhݲUémZµæÏ˜CV\!DYf“ÔßߟØ#±FIåbcc ðo¤O*7þæÍ_À‚ùßóñèÑFIå s-- oŸÓ½|¼¹–vÍä2IÉI„‡Gàß°Q ÖLQ–ØdmP¿>Gî&•Ûµ €cÇÑ ~ànR¹å+VЩS§Iå ãêæFRbbéɉI¸¹»MkÛ®=mÛµg`Ø`; Êá !6yÉTR¹ÅK–™TnÖ¬Ù<ûL3£@…iØ ÛwüBŸ×^3š¾í—í4lÐÀhš\«*„(ŒMŽ@ÁúIå ½öÚ«üüózÖ¬YKJr )É)¬Y³–õë7ðÚ«¯–êz !Ê›  ¥‘T.OõjÕøò‹Éøó oôíË}û²ÿàA¾˜<É(7¼BÅ&wá¡äIåò¶ þè£2qüø"û »ïBˆ¢HR9!„PI’Ê !„J6{ T!lP!„PI¨B¨$T!T’*„*IB•$€ !„J’TN!T’¤rB¡’ÍÞ _R†#bEQððð A½zôï߃‡)—\NÍÈ,O^÷H̉Œ@QýtNGÿΟ¿ £u!lP™  p7ˆiµZRRSX½z 'Mfê×_æ%—+.A]Qe–$¯stvbï¾½4kÚL?í÷?öàtçÙ§BÛc“'‘¬TN£ÑàíåÍ«½{sòäIýt5Éå,aIý=»ugùò•FÓV¬\Á+Ý{”¸BˆÒa“ÔÚIå´Z-)É),[¾‚'k?©Ÿ^ÚÉå,©ÿùçŸ#55£GsS™9r„ki×yî¹gKÜ!Dé°É]xvSÇFIåÚ·kGll,­ZµÐ'•{wØpþý÷¿þú+ßL›j”T.ÿñË *0íÎî;¨K.g Kê×h4tïÖ•å+V2vÌg,[¾‚Ý»¡ÑØäoœZ+©\Ô–Íú+–ÿHp§ŽÌ З[’\N KëoÓ¦5ÿœ8ÁÎèhΜ9CëÖG¯BÛa“ÔTR¹œœœ"“Ê­Y³†¸¸¸Bëôpw§G÷‹ w“Ëåg*¹œ–ÖïààÀË/uæË)_Ñå¥Î888”¸BˆÒc“»ðp7©\Ïž¹'Qò’Êuî '•ûÏêbg§aü„‰L›6'GÇõ]»vµëÖRë±Zúi¯½ö*ÇÀ¥¼ -‚‚€Ü³äë×o`Ú´©%^5õ÷ìуž=äÄ‘›  þ,X¸È(©\䜹E&•‹»ÏÌ™³1|`| ÔÕÕ•ºuê0êýôÓò’ËÍ7ï- N:VK.WÚõ !î/›  %M*gî…çæ$—3§ÎÒL^'Ñ a›$©œB¨$Iå„B%›< /„  B¡’P!„PI¨B¨$T!T’*„*Y|SäŒi¥Ñ!„xàX@C† +­~!ÄÇ¢zôHLiõC!8r T!T’*„*IB•$€ !„J@…B%  B¡’P!„PI¨B¨$T!T’*„*ݳj˜bX!Ê‚û2•`*„( ¬@W¬\Eû;°båª"ç{Ð3xÊ€¬@µZ-7n$44„ ›6¡Õj­UµBØ$«ÐýP¡B:ãæêÊ ×p—••Åô3èÚ½={õfùÊ•FåmÛµgÃÆMôyý :óΰaœ={Ö¨|ý†¼ñæ[¼Ø±ýCBùë￉ŠÚÆ[}ûé—¹pá¢~­VË’¥Ëxý7éÒ­;_OÆ­[·Ìj3¯omÛµ—‘¨9«Ðõ6Ü €àŽùyÃz³–[ºl—¯\aNd8³gÍ æPÁgŽå¿ÿΤ ãXµbÍš6åÛÓõó¯]·Ž#GŽðÅ“Yôý²³³Y¸è³ÚÌ;üµeó(BQ2V   ññœøç-‚ZĉNŸP첿ìŒ&t@Þ^Þx{yR`ž¡ƒ‡à[¹2ÎÎÎtïÖ•ÿýר|Ø»ïàWÅgggº¼ü2¼;t(¾~w§ýsüýü›6ofðàAøùúR¡BôïÇo¿ýfQ›BaÑéwïÚiô:dÈ0މaýƤ¦¥Ñ18ب|ãÆô{ûí"ëLNJÄ×·²þµŸ¯_y<½<õ;99q;3Ó¨ÜËË˨¼¸e®\¾ÂÛýúÕ¡Ñÿ–צ¡§ë5\QB”y1Í\'•3Ì‹tôH ™™YlÛ¶E ¿Ç·òÝ@ŸÀ;ï¼Ëë}^ÇÑÑ¡Ðú¼¼}HH¸LõêÕî,oi—,V©R%&LoÔ_K(Šbôúè‘É%ÄNÍ Èâ Æ¹‘¢££y²víÁÈÏ×—'þï víÚE›6­ ­«eP s">ì]""ç¨é’E:vìÀ7ß|KØÀT©âÇ… X¶l9£G2kyw77Ο¿@ÕõÓ$_”UÔÐOÖófŸ×M–uêØÅK–@{÷êÍìˆpúÅÞÞžÎÁÁÄ>\Òn©sp0†±ã>'!á2ÕªUã×û˜½|Ïž=xgØ0ÒÓÓåD’1å‘6ƒt}&r!ñ*WN³gR›BGS»wí´ø¥Îœ9رŸ³ðû¥Ö†BäWT|Û½k'¡C‡ÓtTå+Õ"~ï*n&_°‡‰DDF’’œÂå+WˆˆœÃ3Ï>s¿»$„Å*ñ.¼5T®\™AC‡’Í3Ï4ã­7Þ¸ß]BˆbÙD}ù¥—xù¥—îw7„Â"6± /„"  B¡’P!„PÉjÇ@Õ<™H®¡B<Ȭzébœù·aV«Rðžw!„xØÄYøÒP؈8oÔ;åë¯Q…÷†7*Ï?ݰOOOü2 77W£åV¬\Å‚ xë­·èѽ[¾øûû3qü¸÷Ñ·m×^ß§¼¶E¡|¹røúúâ@·®]ðpw·ô-B”²2} 4ÿò <˜Žÿöí¿è§mÞº•“'ÿeÈ A&ë™5s·33™nTnÎÓøÝ\]ùy}ñÏHÚ²™­›7±léFŒNæíÛ 8ˆ„Ë—-]}!D)³ÉúFß¾œ;wNÿzÛ¶íú¿Ï;Ç}û2}Æ ¶FE-·%j+Óg?l¹0NNN|üñGÌ;—óç/pæÌÌ_À'}¤$^~>ÞÞ  ãàÁFÓÍyÿÐ!ƒùùçõFOÆ/г³3?öaCi×®- .2k9!Ľc“´±¿?Gbÿ 11‘YáádddpøH,8¨mÛØõë¯Dÿº‹mÛ¶3hà@³Ûy¤F ú½ý6ã&L`ü„‰„†„è«g sžÆïââÂ;C‡0yÊ—ädg[Tûvíù3æÅýB”.›  þþþĉ`ÇŽ8:8èell,þ°··çãÑ£™?óæ/`ÁüïùxôhììïÖÍË[dø¯@[ptp@£ÑмùóEö+)9‰ððü6ÒO³äiüõêÕ£aýú,üa±E—'×®]·h!Dé³É“H ê×gÖìÙ@nÊ#†³ìÇå´o׎cÇ1bxîË===iÕª%‹—,e@ÿþxzzÕcÎeRß~;“¾o½É•+W™¿à{Bô/0O^àõðð Q£†„†ÀJÂ[”IDATÜM;béÓøß|ã Þ6Œ&MS·Nbû”œ‚»››Yó !î›  åÊ•Ã××]¿þŠ££#M›4añ’¥üþÇøùUÁÙÙ€Ó§O³ekŸ}ú ³fÍæÙgšQ¥J³ÛÙ±c'YÙYøûû£ÓéñÞûÄÄÄРA£ù ÄjžÆoooÏûï¿Ï¸ñã™þÍ7fõsó–Í4jØ ø…÷”MîÂ4 ð'2r­[µ UËÌœ5›€nݺÅS¾âÑ#yîÙg:t0ã'L,2w‘¡””"æÌ!¤? ÷Ò¡¡C3õÛ餧§›U‡9Oã7å‘5èØ¡C³ù†n߾Ϳ§NÉ–-Q¼þºé‡V !î›  þ¤¤¦@P` )))4öÏ  3fÎä¥à`þóŸº4kڌ֭Z1sæ,}E1kÏ4kFÍš5õÓj֬ɛ7gúŒ™fõñ§ ë îØÑdY§Žø©ˆË–:“œœR`zÛvíy¡ý‹ôx¥_}=GÂgÏT¿IQzlrà±ZµØ¼qƒþµ‡‡‡Ñë÷ß{¯À2]º¼¬ÿ»¸ãŸŸ~ü±Ééýú¾eôº¨zfMŸ^hY³¦ÍhÖ´Y¡u(ŠÂ¤ ãÍnKa{¬@åöL!ÄÃÄjTFOBˆ‡ÍB['T!T’*„*IB•$€ !„J@…B%  B¡’$•B•$©œB¨d³÷Â[KqÉÞ ç/KINaɲ¥ìÛ·Ÿ«II”sv¦ví'y)¸3Mš4Ö/cNò¸¢ŽäÝÜ\yªöS„† j•ª%êWqëYÔ„ì)aZ™ †ÉÞV¯]G·®]Ðh,?웘”İaÃiÞüyÆGeßÊܾu›cÇŽ²ö§Ÿô î&ëœïË–È X×®]gíºµL™ò5ßL›Z¢~™Û&˜ì…xØÙäI$k%•3'Ù›9-ü-Z0 jÔ¨Ž“£#nn®4mÚ´À•,MW77WºwëÆ©S§JÜ/!„õÙdµVR9s’½™cßý´mÛÆ¬yK’<.¿ëׯ³rÕ*j>úh‰û%„°>›Ü…÷÷÷gçŽh:uì`”T®}»vÄÆÆÒªU }R¹w‡ çßOñ믿òÍ´©ú¤ryÉÞ>ýø 7ÙÛwóæŸ€Ÿ¯¯EýIKK£bÅŠFÓ æßÝ5L×÷­7-^ú½¼¼Lî¾[Ú/5WI!Šf“#ÐõësôøQànR¹­QÛ8vü êçæÊK*·|Å :uêd”TÎ0Ù[ÛvíéLjZ7n´¸?nîn\½zÕhZÔ–ÍE'|ó7øóσüõ÷ß·µe3[7obáüùTñó+tÞ’~åMÏÿO¡žMPSIårrrŠL*·fÍâââãdo†Ábá÷ ˆŠÚFff–Eý ð÷gëÖ¨âg4—<î›o¿Õ~°„¢(øUñcÔÈ‘LŸ9Ódjú%„°›  P²¤rj“½æõ>}ؾýæÌËùó¸™É7Ø»wo‘Ë™“<®8•*U¤n:쌎¶Z¿„Öa“Ç@!7©Ü‚…‹Œ’ÊEΙ[dR¹¸KñÌœ9‹ÓgÏðfÓY,;uìÀâ%ËhÓ¦5`úØ`þ]ÛÊ•*ñí7ÓX¼x #G}HjZ*..åùOÝÿz|2Oçà`Fß9«Ö‹íÛ3þ:¼ø¢Õú%„(9å‘6ƒt}&r!ñ*WN³gRމ19óî]; 2ÌdyÛví-¾IŽÁ !lEQñm÷®„NÓQQ”¯T‹ø½«¸™|A’Ê !„Z’Tî“[&…(;löhY%ARˆ²ÃfÏ !„­“*„*IB•$€ !„J@…B%  B¡’$•B•$©œB¨Tæ/¤“Ê)Š‚‡‡ êÕ£ÿ~øøøèËΞ=ËÜyóøë¯ÜçÖ­[‡~}ûòè§×«}€r^‹«?¯GjÔ`Nd„Ñúêt:ú‡„pþüÙËeZ™ zR9­VKJj «W¯aâ¤ÉLýú+âââø`ä(zöìÁ{ư3:š‘£>ä›iS©R¥ŠÙIâL•™SGg'öîÛK³¦ÍôÓ~ÿcNwžÙ*DYf“'‘$©\.Fƒ·—7¯öîÍÉ“'ïögñb:uêH×.]ðôòÄÓË“.]^¦cÇü°xI‰Ûµ¤þžÝº³|ùJ£i+V®à•î=JÜ!lMPI*—K«Õ’’œÂ²å+x²ö“úé‡Åкe«ó·iÕš?c•¨MKëþùçHMMãèÑÜ,GŽáZÚuž{îÙ÷C[g“ÔßߟØ#±FIåbcc ðo¤O*7þæÍ_À‚ùßÿ{÷U½¯üÔ­qQ“­bjXÇöÆ èTº+KOj (f\¼…—T¬Ô/‰¹w7+•ˆPM+/„yAKÐÚûìÎsì(”¦[¶çxå)ÁCBsþ°g˜ÛZ¿YŒk†÷ó<<¬Ûï;Ëáû̺Ìz±léR‹P¹¡C†¸*wæô\©¬”]­ð6ÃOs¦¡r" Û9 ñ'bÿþý˜ûâ‹Æùµ55èlr>Ô ÓÝQ[S+4¦)9Û÷òòBlÌ3ÈÍ»õ)tGnâbc„N•¹U¾Ë*w;Ç)/÷Œ…̬õÆù¾~~¸ZUe±Þµª«ðó÷“=^sr·?|ø0œ>s%¥¥8wî† ³üôJä‰TÙ@*w[€¿?âbcqê·CdèŽÏa±ì¡/>Gÿðpá±D·ïãョÇFcUê»76>>>N×@äTÙ@†ÊÔÖÞÀÎü|÷ 6N›1; ¢¢yùùÆ 8>ýá¨)¡sŽÆ0̯­½]ŸíBjjšÃ§SÉ!'ÜNj-‹ö[LÓëõHOÏ@hX¨ÐØÎîk¥Þ§äzªü_jÍ¡r}¼ ÑcÆ æ™q ì<ðÀøë²e²¶£d¸#~~¾ˆ‰AEE…¢Û Ï©%3+ Á}î5>{VîØÎîk¥Þ§äzªl ­9Tîøñãø÷!OÈ^Oé:ä¸qãÖCŸ{›Ú*A$tëÚ_}õ7³é%%¥èÛ·¯Ãgm:;~sR÷7ƒßÈUÂ3TγCå&ŒÇ›6ãñǧå yþK.ß””ýÍà7²E• ”¡rž* ­Ö 'Nœ@XXŽ;___ôíÛ×%ã›’²¿üF¶¨òž¡rž*7>>¹;wvæŠñqq.ßÀÑþfðÙ£Ê 0TÎÓCå ˆªª«øü‹Ã¸^ScüuÕøŽö7ƒßÈU •óôP9Fƒø¸X¼›öÙÈfwE¨£ýÍà7²‡¡rDD`¨‘K1TÎÅZCàZkxD€ŠÏzªÖÐ@ZÃk$T|žˆHíØ@‰ˆ± b%"ÄJD$ˆ ”ˆHC刈1TŽˆHÇÞH_WW‡OróðÕWCUÕðiÓ¡ú¢£Ç x8y¡r€ãP1ƒŽ;âAÝ$ÎJ„ŸŸ¯Å|SÍŸ+ªÑhÐþw¿C×®]¡{ðAÄ<3þþ{€ˆZšÇ6Ðåo¿ƒÀÀ.X¾üuü>ð÷ø¿º:œ8qÛ¶o76P9¤„ŠšaÕÕ«X¿a2³²òòb‹ù¶æÿòË/¸x銋áùç_DzzšìQËSåE$%Bå¾-/Ǭ3Ô=ÞÞÞð÷Ç?ŽwW­ªIN¨ØÝ;cÎ /àØ±ÿ«]»v¸¯O¼ðülDDŒÀ‡~$´"jYªl J„Ê…†…âýŒÕøîäIÔ748]Ó ‹ŒˆÄ7ÇÿÛ%c‘<ª<„W"TniJ òóó±fm&.^¼€NïÆàGÁÄ СCãXRî*võÚU|°a#tý˜MyànçNQ[{ÃaDäzªl J„ÊuhßS0%!z½çÏŸG^~>V¬\…7ßxݸœ½‹HRCÅ ë`À€þ˜˜h¶¼Èm[W¯UÃßÏOözDÔòTÙ@­…ÊmݶÝn¨\fæ:<òçAèÞ½»Åö4 zõê…fÏÆ$ñ ¶˜†Š™^ȹRY‰—^š„gЦ€–¹¯µè@ô—Ñ‹ˆZž*ÏÎ…ÊÀÂÅ‹qäèQTWW£©±W*+±is6BBþ(«Ž;*V__³ÈZ¿#!A^Ó'"×På'PÀ¹P¹ÉI˜±;úd>""½zöÄÖC£Ñ§ëõzÌLLÄùó¬Ö;"":o/Ól=¹µ7_þ©È‘ÐjµÐjµðöö†Vë­·7¼à…ë5×Ï0p¬Gän<ºÊ ‚S:ÈÍQ¨]ó§0Ém"mÚµÅ×ÿùµña&ð÷ÿøÚþö¬T[ü|}±gï^D7{8´œÚ›;X´ßbš^¯GzzBÃBͦ³Y’'QåE$%BåyApJ¹)j×\|L,rswšMËÛ™‡ñ±qv×›7wöìÙ‹ .¶hí™YYîs¯ñy®DžH• T‰P9@<N‰ 7¥Cíš{ì±Gqýz Nž< (++CmÍ <úè#v×ëС^š7+RW¡©±±Ejß”?ŒŽ–½.‘;QeÕét(/+³P9(//ǃºÆP¹ììlÎÎANö,[ºÔ*g‚:d(€[ApgNŸÁ•ÊJ‡ã+ä¶4%=zaÍÚL<ƒ„iÓ±qÓ&ÔÕÕ9µ]///ÄÆ<ƒÜ¼[ŸBwäæ!.6Æâ…5¡¡¡è†?ÞªxíÛ¶ï@C}=ž<Éêü‘?DîJ• 4<, '¿¿õÉÊ*w°øàÔ÷§vë<œ!T.7/£G6 •3 ‚‰¨1cp½¦………Ç·ä¦õöÆÍ›7-¦74Ü4k^†P»õë2±w÷n¼ùÚ«¸^Sƒ+•9„€áÇáô™3()-Źsç0lØ“’×:e ¾ùæ¾ýî;‹y¢µìú —/_Âó³m.S| Èâ‡È]©²Z •kjj²*WPP€Ë—/0‚3ýCýpKŠ‹¡¡Á²š²äÔ½***,¦WTT °K«ë˜†Ú•û­œ]a—žU©ïbÜØhøøøH^×ÛÛ‹-ÂûÆÓ#ÖH­½¨èÊÊÊœ”dq…ŸÈS©²΅ʉÁI r3z Ò3V£¬¬u?ý„ºŸ~BYYÒ32e\N©P;GâãâPT¸qqö/YÓ«gOD…̬,³érk?|¸¥GŽ`iJ ´Z­Ðë rGª½É™P¹ýÏ9ÉAprƒÜFGB»¶m±aÓF\¾tëo÷ îˆ‰Áp“Ch¥BíZZô˜1Xºì/fÓäÖžš–†¦¦&DÙ¸5ªù-[öæ¹M¯á/êŸxöm\¨ú?ýð/üãá8YvÜêÂ_)AâÜ$«óGDDÊþ&’;üáÔÕÕ!aê4|º3ïN—BD-È^ûòH fÏKÆÀ%ÅhŒ+_çãçk*gOcc#öíß»ÿþ;] ©Cåì=öiô¹·7.XàÒqùš'¹ŽjϪA‘Äï•Æ&IäT{žˆHíØ@‰ˆ± b%"ÄJD$ˆ ”ˆHC刈1TŽˆHÇÞHoD©iiÐh4X˜œl¶lóéŽѤÔ9ª™aqDîÃc( íxÞœ9˜3w}þ…ñiJEâŸÿ<‹5ïËÚžu ‹#rª¼ˆ¤T¨œm۶Ųe¯`ãÆ8þÎ;‡œìüå•Wжm[¡ú ¨cX‘ûPeU*TNª^={bÆsÏáÍ·ÞÂò·ÞÆìÄDÜsOE^‹Ü€:†Å¹UÂët:”.Åè¨Qf¡r‘(//Ç“O5†ÊÍOJÆÙ³8zô(ÞOÏ*Xž›³w˜©{pvïÙƒ½ƒ?fu‘‡Ë ¨3 ‹{ýµW…Ãâ¦O›j1iJ òóó±fm&.^¼€NïÆàGÁÄ СC»Û6„Å͘>Íê|>(™Z#U6Ðð°0d®[àv¨ÜŽOrSߟ‚ä$·Cå¶nÛŽY3gš…Êòþ€32Öbú´©øá‡‘³‰³fZ,#ÒìÔÙ2|ø0|´u«1,î×^•¼îÔ)S0?) ?üú…„˜Í3„ÅMIH€^¯Çùóç‘—Ÿ+WáÍ7^·¹MCXœ½Çú±YRk¤ÊCxgCåä:|¸7oB§Ó!"â)œ>}Ç[*¿\öêlaX‘{Peœ •“£ººë?ø‰3g¸ÕXæÍƒ÷2V g¸K ¨³‡aqDê§ÊCxÀ¹P9Ã!¾k23ñçAƒÐ»woã´Þ½{ãñÁƒ±zÍZ¤,yÙ8ÝÑy>¹u-‰aqD-¡rDD`¨‘K1TÎ…GäYT{Ô±IyÕ^…'"R;6P""Al DD‚Ø@‰ˆ± ’}~Úô–¨ƒˆÈíÈj ‰s¥E’ˆÈÓÉj ¶¾âIDÔñ(‘ 6P""Al DD‚Ø@‰ˆ± b%"ÄJD$ˆ ”ˆH(‘ 6P""Al DD‚Ø@‰ˆ± b%"ÄJD$ˆ ”ˆHÕ*y¤ÄÕu¹‹ªÑhîDDDnǬ¶ ÆÀ%Åwª""Uklö»Å'Ðæ ‘uÆzåëü;Y‘ÛÑ@¯á/êït!DDîäejþÈ:Š2›Üñ0IEND®B`‚wxglade-0.6.8.orig/docs/html/ch03s06.html0000644000175000017500000000642212167336636020206 0ustar georgeskgeorgeskThe wxGlade Menu

The wxGlade Menu

wxGlade has only a few very small menus.

The FILE menu

In the FILE menu there are the classic FileNew, FileOpen... and FileSave items. When opening or saving a new file, the file dialog defaults to the directory that you put in the Initial path textbox in the Preferences dialog, usually the user home directory.

The FileGenerate code item produces the code from the current design.

The VIEW menu

In the VIEW menu, you can show or hide the tree window and the properties window.

In this menu you access the Preferences Dialog as well.

The HELP menu

The HELP menu provides access to the wxGlade user manual (this documentation) as well as to the About... dialog.

wxglade-0.6.8.orig/docs/html/ch03s02.html0000644000175000017500000000716412167336636020206 0ustar georgeskgeorgeskTree Window

Tree Window

The tree window shows the logical hierarchy of widgets and its child-widgets. For example you can see a panel as a tree's node and the widgets on it as child nodes.

Figure 3.2. The Tree Window

The Tree Window


You can show or hide the tree window by the menu item View/Show Tree.

Usually a frame or a panel contains a sizer, so you often see a sort of panel-sizer-widgets structure. The tree gets more complex when you nest sizers within sizers.

You can navigate the visual presentation of your widget tree by mouse, expand and collapse sizers, and copy, cut or remove widgets.

A click on an icon in the tree window displays the properties of the corresponding element in the properties window. A double click in a frame, dialog or panel icon makes the designer window show it as it appears. Clicking with the right button of the mouse gives you a pop-up menu.

Figure 3.3. The menu for a widget

The menu for a widget


Figure 3.4. The menu for a sizer

The menu for a sizer


The pop-up menu for a widget allows you to copy, cut or remove the element. The pop-up menu for a sizer allows you to copy, cut or remove the element, or add or insert an empty slot.

Note

Often when you add an empty slot, you have to make the designer window larger, to show the new slot.

wxglade-0.6.8.orig/docs/html/ch01s02.html0000644000175000017500000000452012167336636020175 0ustar georgeskgeorgeskWhat Can You Do with wxGlade?

What Can You Do with wxGlade?

With wxGlade you can:

  • Design the whole GUI of your application inclusive simple or complex dialogs as well as menu bars, different kinds of buttons and text widgets, bitmaps, ...

  • Use the graphical editor for editing, cutting and pasting widgets

  • Convert your design in source code of your favorite language

  • Run wxGlade on a wide variety of operation systems since it is written in Python

wxglade-0.6.8.orig/docs/index.html0000644000175000017500000000071711621715605017253 0ustar georgeskgeorgesk wxGlade documentation
wxGlade

wxGlade documentation

wxglade-0.6.8.orig/icons/0000755000175000017500000000000012170277707015442 5ustar georgeskgeorgeskwxglade-0.6.8.orig/icons/static_line.xpm0000644000175000017500000000160211621715605020457 0ustar georgeskgeorgesk/* XPM */ static char * static_line_xpm[] = { "21 21 21 1", " c None", ". c #D5D5D5", "+ c #BFBFBF", "@ c #939393", "# c #787878", "$ c #747474", "% c #7A7A7A", "& c #777777", "* c #7C7C7C", "= c #757575", "- c #818181", "; c #737373", "> c #919191", ", c #CACACA", "' c #E8E8E8", ") c #F5F5F5", "! c #FEFEFE", "~ c #FFFFFF", "{ c #FDFDFD", "] c #FAFAFA", "^ c #F3F3F3", " ", " ", " ", " ", " ", " ", " ", " ", " ", ".....................", "+@#$%%&********=-*;>,", "')!~~!{~~~~~~~~{!!]^'", ".....................", " ", " ", " ", " ", " ", " ", " ", " "}; wxglade-0.6.8.orig/icons/icon16.xpm0000644000175000017500000000403311621715605017261 0ustar georgeskgeorgesk/* XPM */ static char *icon16[] = { /* columns rows colors chars-per-pixel */ "16 16 80 1", " c #0FA60FA65779", ". c #000000007D41", "X c #29D529D569D5", "o c #0FA645720000", "O c #00005D210000", "+ c #00006D620000", "@ c #13F6696413F6", "# c #1BE37CC30000", "$ c #1B267D901C18", "% c #29D559C51BE3", "& c #509B00000000", "* c #57790FA60FA6", "= c #7D4100000000", "- c #7D427D420000", "; c #80007DF20000", ": c #47D347D35779", "> c #47D3538C47D3", ", c #577947D347D3", "< c #5779577947D3", "1 c #509B509B509B", "2 c #5EED50FC50FC", "3 c #5BE35BE369D5", "4 c #7D4280008000", "5 c #800080007D41", "6 c #000000008FA6", "7 c #1BE31BE38B7F", "8 c #1BE31BE39BE3", "9 c #1B461B469F30", "0 c #00000000E42C", "q c blue", "w c #0000A78C0000", "e c #0000A7F50000", "r c #0000C4C10000", "t c #0000C5390000", "y c #8000951B8000", "u c #8FA600000000", "i c #87ED18511851", "p c #915400000000", "a c #9BE31BE31BE3", "s c #E1D400000000", "d c red", "f c #8FA68FA60000", "g c #8604860413F6", "h c #8DF18C1D1BE3", "j c #90B590B50000", "k c #9BE39BE31BE3", "l c #9CEF9CEF1BFE", "z c #9BE39BE38000", "x c #DF38DF380000", "c c #E41CE0680000", "v c yellow", "b c #87ED88768876", "n c #83098D7B8309", "m c #8DF18DF18B7F", "M c #8FA68FA68FA6", "N c #820A820A9EC8", "B c #9DB581648164", "V c #90FB90FB8309", "C c #911E911E911E", "Z c #915591559264", "A c #940B9341940B", "S c #9851985198D9", "D c #98D9987398D9", "F c #9BE39BE39BE3", "G c #9CEF9CEF9CEF", "H c #C203C203C65F", "J c #C2A3C6E7C6E7", "K c #C65FC31BC65F", "L c #DF40DF40DF41", "P c #E0DEE0DEE0DE", "I c #DF58DF5CE41C", "U c #E0DEE0DEE5CB", "Y c #DF38E41CE41C", "T c #E41CE41CDF88", "R c #E1AAE1AAE121", "E c #E394E1BFE41C", "W c #E394E394E122", "Q c #E5D4E211E5CB", "! c #E6CCE6CCE1C2", "~ c gray100", /* pixels */ "&pp*4CMMMMMMMMC1", "uddaY~~~~~~~~~~M", "uddaY~~~~~~~~~~M", "=ssiJPLLLLLLLTT4", ",BB2bGFFFFFGmX9 ", "M~~FL~~~~~~~T8q6", "M~~FL~~~~~~~T70.", "M~~FL~~~~~~~P3N:", "M~~GL~~~~~~~LF~M", "M~~DL~~~~~~~LF~M", "M~~DL~~~~~~~LF~M", "M~~SHIIIIIEQKF~M", "M~~Vgkkklh%w@n~M", "M~~zxvvvvc#twy~M", "M~~zcvvvvc#een~M", "1ZZ<-ffjg;o++>C1" }; wxglade-0.6.8.orig/icons/gtk/0000755000175000017500000000000012170277707016227 5ustar georgeskgeorgeskwxglade-0.6.8.orig/icons/gtk/save_as.xpm0000644000175000017500000000376611621715605020404 0ustar georgeskgeorgesk/* XPM */ static char * save_as_xpm[] = { "14 14 96 2", " c None", ". c #A6A6A6", "+ c #BEBEBE", "@ c #8E8E8E", "# c #6F6236", "$ c #3F381F", "% c #767676", "& c #455254", "* c #293E42", "= c #474747", "- c #776C46", "; c #7E6F3D", "> c #6E6D66", ", c #3E4647", "' c #96A6A9", ") c #D0DFE1", "! c #7A959A", "~ c #5B5F60", "{ c #76888B", "] c #CDDDE0", "^ c #E4ECED", "/ c #C0C0C1", "( c #7A6F4A", "_ c #333E41", ": c #79949A", "< c #CDDCE0", "[ c #D8DADA", "} c #F9F9F9", "| c #C1C1C1", "1 c #465053", "2 c #121B1D", "3 c #7E9FA5", "4 c #CBDCDF", "5 c #E3E1E0", "6 c #CECAC8", "7 c #7B704A", "8 c #7E7C76", "9 c #BCD3D8", "0 c #344F55", "a c #2D3739", "b c #ADC6CB", "c c #E1E0DF", "d c #73653B", "e c #4F4B3D", "f c #6F7878", "g c #B8CFD2", "h c #53858F", "i c #5D959F", "j c #393D3E", "k c #666A6B", "l c #69878D", "m c #EDF1F2", "n c #B9B3AF", "o c #9FA1A2", "p c #94B0B5", "q c #729AA2", "r c #3E5D63", "s c #406871", "t c #49767F", "u c #355359", "v c #364548", "w c #94BBC3", "x c #BAD2D6", "y c #64939C", "z c #748D93", "A c #CDD1D2", "B c #E9E9E9", "C c #5F7377", "D c #48747D", "E c #41666E", "F c #0C1213", "G c #6E9BA5", "H c #67A0AB", "I c #AFB9BC", "J c #9DA6A9", "K c #E2E6E7", "L c #E5E5E5", "M c #AAB2B3", "N c #638F97", "O c #1A282B", "P c #020405", "Q c #253235", "R c #669BA5", "S c #7B979D", "T c #8F9596", "U c #9EBBC0", "V c #CACECF", "W c #6C6F70", "X c #404445", "Y c #65696A", "Z c #2F4C52", "` c #65949D", " . c #BCC4C6", ".. c #788284", "+. c #333737", "@. c #989898", " . . ", " + @ . # $ ", " % & * = - ; > ", " + @ , ' ) ! # ; % ", " % ~ { ] ^ / ( ; > ", ". _ : < [ } | # ; 1 2 ", "= 3 4 5 6 | 7 ; 8 9 0 % ", " a b c 6 d e f g h i j + ", " k l m n o p q r s t u @ ", " . v w x y z A B C D E F ", " = G H I J K L M N O P ", " Q R S T U V W X % ", " Y Z ` ...+.@.+ ", " % = = % "}; wxglade-0.6.8.orig/icons/gtk/tutorial.xpm0000644000175000017500000000230611621715605020613 0ustar georgeskgeorgesk/* XPM */ static char * tutorial_xpm[] = { "14 14 61 1", " c None", ". c #8E8E8E", "+ c #A6A6A6", "@ c #767676", "# c #3A4E56", "$ c #465E67", "% c #3E555E", "& c #474747", "* c #BEBEBE", "= c #41484A", "- c #6B8E9B", "; c #5F828F", "> c #5E808D", ", c #1F2A2F", "' c #C0C0C0", ") c #445962", "! c #658896", "~ c #49636D", "{ c #5B5F60", "] c #374950", "^ c #678A98", "/ c #3E4D52", "( c #8D8D8C", "_ c #686965", ": c #678895", "< c #618491", "[ c #3C3C3C", "} c #AEAFAD", "| c #4D4E4C", "1 c #3A5058", "2 c #678A97", "3 c #B4B4B3", "4 c #777974", "5 c #524646", "6 c #373236", "7 c #212D31", "8 c #3A4746", "9 c #56696A", "0 c #5A7B87", "a c #ACACAA", "b c #323331", "c c #382828", "d c #CEB6B4", "e c #F1F0EC", "f c #B1B1AE", "g c #666664", "h c #4B4A49", "i c #6A6B68", "j c #756C6D", "k c #483C3C", "l c #6D7475", "m c #C8CFCC", "n c #E1E0DD", "o c #B2B3B1", "p c #4F504F", "q c #495153", "r c #747C7B", "s c #979B98", "t c #686F69", "u c #696D6E", "v c #0A0E0F", " ", " ......+ ", " @#$%%%%& ", " *=-;>>>,' ", " .)!>>>~{' ", " +]^>>>>/(_ ", " &:<>>>>[}| ", " .12>>>>,34@ ", " 567890~{ab ", " cdeefgh.i. ", " jklmeenop* ", " +&qrst@ ", " *.uv ", " "}; wxglade-0.6.8.orig/icons/gtk/cut.xpm0000644000175000017500000000072311621715605017544 0ustar georgeskgeorgesk/* XPM */ static char * cut_xpm[] = { "14 14 11 1", " c None", ". c #767676", "+ c #5F5F5F", "@ c #2F2F2F", "# c #BEBEBE", "$ c #8E8E8E", "% c #D6D6D6", "& c #A6A6A6", "* c #474747", "= c #171717", "- c #000000", " ", " ", " . ", " +@ ", " .@# ", "#$$# +@%%#$& ", "+$+@ .@#&*@+& ", "+$+@*=--** ", "#$$#&=$$ ", " &*= ", " &.%* ", " $+.& ", " #$& ", " "}; wxglade-0.6.8.orig/icons/gtk/prefs.xpm0000644000175000017500000000272111621715605020070 0ustar georgeskgeorgesk/* XPM */ static char * prefs_xpm[] = { "14 14 79 1", " c None", ". c #A6A6A6", "+ c #787878", "@ c #474747", "# c #727272", "$ c #B2B2B2", "% c #DFDFDF", "& c #767676", "* c #797259", "= c #BEBEBE", "- c #8E8E8E", "; c #4C4C4C", "> c #E1E1E1", ", c #E0E0E0", "' c #8B8B8B", ") c #77756F", "! c #998C61", "~ c #564F36", "{ c #606060", "] c #969696", "^ c #E5E5E5", "/ c #CBA6A6", "( c #DADADA", "_ c #DCDCDC", ": c #C9C9C9", "< c #574E2F", "[ c #5E5E5E", "} c #C7C7C7", "| c #E6E6E6", "1 c #E9E9E9", "2 c #AE7575", "3 c #BCBCBC", "4 c #AFAFAF", "5 c #D0D0D0", "6 c #7E7C76", "7 c #949494", "8 c #D5BBBB", "9 c #CEA2A2", "0 c #BC8F8F", "a c #CACACA", "b c #7F7F7F", "c c #E2DFDF", "d c #C9A2A2", "e c #C9A5A5", "f c #7D7B75", "g c #988B60", "h c #574F36", "i c #D6D6D4", "j c #5E5E5B", "k c #7B7B7B", "l c #E8E8E8", "m c #CFC198", "n c #4B401D", "o c #37311F", "p c #94948F", "q c #BABAB1", "r c #B4B4A9", "s c #909085", "t c #C7CAC5", "u c #5D605B", "v c #636560", "w c #B5B5A9", "x c #B9B9AF", "y c #B9B9B0", "z c #767670", "A c #5C5C5C", "B c #919191", "C c #CDCDC8", "D c #C4C4BF", "E c #D8D9D8", "F c #E1E1DE", "G c #DCDCDA", "H c #E3E3E3", "I c #AEAEAE", "J c #7D7D7D", "K c #494949", "L c #757575", "M c #909082", "N c #545450", " .+@. . ", " @#$%@ &*.", "=-@;>,>>'-)!~.", "{]%^/(_$:{!<. ", "[}|123456!~. ", "-7890a^b!<+. ", " @cde^fgh.ij. ", " .k^lmnopqrs@ ", " {:tuvwxyzA ", " -BCDEFG&-= ", " @H^>I@. ", " .J,KL ", " .@ ", " &MN "}; wxglade-0.6.8.orig/icons/gtk/refresh.xpm0000644000175000017500000000072711621715605020413 0ustar georgeskgeorgesk/* XPM */ static char * refresh_xpm[] = { "14 14 11 1", " c None", ". c #000000", "+ c #566B43", "@ c #4C603C", "# c #526741", "$ c #5A7046", "% c #37452B", "& c #425334", "* c #445636", "= c #475937", "- c #5C7449", " . ", " .. ", " .+@.. ", " #$##@.. ", " . .. .%. ", " . . .%. ", " .. .. ", " .. .. ", " .&. . . ", " .*...#= ", " .##-#@. ", " ...@* ", " .. ", " . "}; wxglade-0.6.8.orig/icons/gtk/paste.xpm0000644000175000017500000000320511621715605020063 0ustar georgeskgeorgesk/* XPM */ static char * paste_xpm[] = { "14 14 91 1", " c None", ". c #BEBEBE", "+ c #8E8E8E", "@ c #45443F", "# c #45433E", "$ c #A6A6A6", "% c #767676", "& c #5D5D59", "* c #8A897E", "= c #CFCCBD", "- c #CECABB", "; c #474747", "> c #2F2F2F", ", c #45453F", "' c #A2A193", ") c #A4A499", "! c #6F6F69", "~ c #6E6C68", "{ c #B3B0A5", "] c #88867C", "^ c #D1CFBE", "/ c #D0CFBE", "( c #747471", "_ c #9D9B94", ": c #6C6962", "< c #BCB9AC", "[ c #B4B2A5", "} c #5C5C58", "| c #D6D6D6", "1 c #CFCEBD", "2 c #89877F", "3 c #9E9B90", "4 c #CCC9BA", "5 c #CBC9BA", "6 c #C9C7B8", "7 c #43423D", "8 c #767674", "9 c #373731", "0 c #A19F93", "a c #CECBBB", "b c #CDCABB", "c c #CAC8B8", "d c #4B4B46", "e c #6C6C67", "f c #979788", "g c #C6C6B2", "h c #73726B", "i c #CDC9BB", "j c #CAC8B9", "k c #4C4C4A", "l c #8D8D89", "m c #BCBCAE", "n c #DADAC3", "o c #7E7E71", "p c #CAC9B9", "q c #C9C5B7", "r c #2E2E2B", "s c #868679", "t c #CECEB9", "u c #DEDEC7", "v c #BFBFAB", "w c #575753", "x c #42423C", "y c #C7C4B5", "z c #C4C1B1", "A c #BFBDAB", "B c #393933", "C c #CACAB5", "D c #E2E2CB", "E c #E9E9D1", "F c #CCCCB7", "G c #747472", "H c #969285", "I c #BDB9A7", "J c #B9B5A2", "K c #10100E", "L c #A3A392", "M c #E2E2CA", "N c #E6E6CF", "O c #EDEDD5", "P c #F2F2D9", "Q c #62625A", "R c #6A685F", "S c #69675E", "T c #65655D", "U c #E6E6CE", "V c #DADAC4", "W c #8F8F80", "X c #545450", "Y c #949485", "Z c #3E3E37", " ", " .+@#$ .. ", " %&*=-; $;>> ", "$,')!~{]+$;>> ", ";^/(_:<[}||.. ", " @123456789$ ", " 80ab5cdefg; ", " $hi4j6klmno+ ", " ;4p6qrstuvw ", " xyzABCuDEF;", " GHIJKLMNOPQ", " $RS;$TUVWX%", " $$ ;YZ+. ", " % "}; wxglade-0.6.8.orig/icons/gtk/about.xpm0000644000175000017500000000211311621715605020056 0ustar georgeskgeorgesk/* XPM */ static char * about_xpm[] = { "14 14 53 1", " c None", ". c #FFFFFF", "+ c #FFFBF7", "@ c #EFEBE7", "# c #F7F3F7", "$ c #E7E3DF", "% c #494941", "& c #F7E7D7", "* c #E7CB96", "= c #DFAE61", "- c #E7B651", "; c #E7CBA6", "> c #C7C3BE", ", c #515149", "' c #969696", ") c #D7CBC7", "! c #E7BA49", "~ c #DFAE41", "{ c #C78638", "] c #C7A68E", "^ c #DFDBD7", "/ c #C77D38", "( c #A66551", "_ c #D7D3CF", ": c #D7A641", "< c #AE5D30", "[ c #9E5D49", "} c #DFCFCF", "| c #000000", "1 c #F7EFEF", "2 c #C79249", "3 c #B67130", "4 c #A64D28", "5 c #963828", "6 c #A68679", "7 c #AEA6A6", "8 c #595951", "9 c #302C28", "0 c #E7DBCF", "a c #BE9271", "b c #9E5541", "c c #AE8E8E", "d c #A69E96", "e c #181810", "f c #BEB6B6", "g c #797569", "h c #CFCBCF", "i c #383830", "j c #282820", "k c #8E8686", "l c #BEBAB6", "m c #413C38", "n c #080C08", " ", " ... +@ ", " ++.++#.++$% ", " $+&*=-=;@>, ", " ')--!-~{]$^ ", "@+.*!!!-~/(_.+", " @.;:~!~{<[}@)", " |^12//3456789", " 1+0abb[c_de ", " +.@fgf^@+hi ", " _^'jek1+1li ", " %iee g'km9 ", " nne ", " "}; wxglade-0.6.8.orig/icons/gtk/remove.xpm0000644000175000017500000000272211621715605020247 0ustar georgeskgeorgesk/* XPM */ static char * remove_xpm[] = { "14 14 79 1", " c None", ". c #BEBEBE", "+ c #8E8E8E", "@ c #878787", "# c #545852", "$ c #757F6F", "% c #81857E", "& c #5D6557", "* c #43493E", "= c #697261", "- c #474747", "; c #A6A6A6", "> c #727B6C", ", c #BECAB6", "' c #B3BFA8", ") c #6C7664", "! c #565D50", "~ c #676F5F", "{ c #9BA98F", "] c #98A58C", "^ c #32362E", "/ c #586752", "( c #C0CCBB", "_ c #C8D1C1", ": c #ACB8A1", "< c #9FAC92", "[ c #99A68D", "} c #7D9175", "| c #252922", "1 c #434A3D", "2 c #697B63", "3 c #84997E", "4 c #7C9277", "5 c #708669", "6 c #61735B", "7 c #566552", "8 c #3A4238", "9 c #3F413E", "0 c #4B5748", "a c #3C433A", "b c #3A4038", "c c #363B34", "d c #313530", "e c #2F322E", "f c #363E34", "g c #83957E", "h c #81927B", "i c #82937E", "j c #677B63", "k c #596955", "l c #586653", "m c #455242", "n c #606060", "o c #919191", "p c #BFBFBF", "q c #050505", "r c #080808", "s c #353535", "t c #82957E", "u c #80917B", "v c #677B62", "w c #576652", "x c #455142", "y c #879D81", "z c #7B8D75", "A c #859781", "B c #6A7F64", "C c #596855", "D c #5C6D57", "E c #445141", "F c #4B5149", "G c #52634C", "H c #4F5E4A", "I c #4C5C48", "J c #495845", "K c #465443", "L c #1B1B1B", "M c #4C4C4C", "N c #A8A8A8", " ", " .+++++ ", " @#$%&*=-; ", " +>,')!~{]^ ", " +/(_:<{[}| ", " ;123456789 ", " -0abcdef+ ", " -ghijklmnop ", " -ghijklmqrs ", " -tuivkwxqrr ", " -yzABCDEqr ", " FGHIJKLM ", " .+++++N ", " "}; wxglade-0.6.8.orig/icons/gtk/exit.xpm0000644000175000017500000000151311621715605017720 0ustar georgeskgeorgesk/* XPM */ static char * exit_xpm[] = { "14 14 36 1", " c None", ". c #888888", "+ c #555555", "@ c #91918C", "# c #B6B6B0", "$ c #000000", "% c #CDCDCD", "& c #ABABAB", "* c #444444", "= c #E4E4DC", "- c #1E1213", "; c #BCBCBC", "> c #4C2E30", ", c #935B5E", "' c #605755", ") c #B8B8B2", "! c #666662", "~ c #C8C8C1", "{ c #2C1819", "] c #784244", "^ c #844A4B", "/ c #8D5254", "( c #A36366", "_ c #C2797D", ": c #AA6E71", "< c #52524F", "[ c #8C8C87", "} c #191919", "| c #BDBDB7", "1 c #767672", "2 c #2D2D2C", "3 c #92928D", "4 c #010101", "5 c #565656", "6 c #5A5A5A", "7 c #8B8B8B", " ", " ", " .++++++.", " +@####$+", " %&*#====$+", " &--#====$+", ";+++*>,'=)!~$+", "&{]^/(_:<[}|$+", "&{]^/(_:<===$+", ";+++*>,'====$+", " &--#====$+", " %&*#==12$+", " +@344445", " .+566667"}; wxglade-0.6.8.orig/icons/gtk/open.xpm0000644000175000017500000000136111621715605017711 0ustar georgeskgeorgesk/* XPM */ static char * open_xpm[] = { "14 14 30 1", " c None", ". c #767676", "+ c #BEBEBE", "@ c #8E8E8E", "# c #A6A6A6", "$ c #514F4A", "% c #333029", "& c #77705F", "* c #999489", "= c #B4B4B3", "- c #666052", "; c #474747", "> c #5B574E", ", c #88806D", "' c #DDD9CD", ") c #C6C5C0", "! c #555454", "~ c #22201B", "{ c #A49C88", "] c #BBB4A4", "^ c #FFFEF7", "/ c #AAA9A4", "( c #5A5852", "_ c #555044", ": c #99907B", "< c #555452", "[ c #AFA896", "} c #F3F1E9", "| c #11100D", "1 c #706F6C", " ", " ", " .. ", " +@ #@$%&*=@@ ", " $-;>-,'')!-~ ", " $,{]^^/(_::% ", " @-]^)<-,:::% ", " ;[}%::::::% ", " #_'%::::::% ", " $,%:::,-;# ", " @-%:::$@ ", " ;%&>; ", " #|1# ", " "}; wxglade-0.6.8.orig/icons/gtk/save.xpm0000644000175000017500000000311011621715605017700 0ustar georgeskgeorgesk/* XPM */ static char * save_xpm[] = { "14 14 87 1", " c None", ". c #8E8E8E", "+ c #4A5254", "@ c #3F4344", "# c #BEBEBE", "$ c #A6A6A6", "% c #474747", "& c #7A878A", "* c #A5B7BA", "= c #455A5F", "- c #5A5E5E", "; c #657072", "> c #C3D4D7", ", c #E2EAEC", "' c #F7F9FA", ") c #84A0A6", "! c #1D2527", "~ c #62777B", "{ c #A6B6BA", "] c #E4ECED", "^ c #FFFFFF", "/ c #CADADD", "( c #475A5E", "_ c #767676", ": c #2E3638", "< c #9CB5BB", "[ c #E5ECED", "} c #F6F9F9", "| c #9BB9BF", "1 c #6C6E6E", "2 c #788C90", "3 c #ECF2F3", "4 c #F9FBFB", "5 c #D0DEE1", "6 c #83A7B0", "7 c #424E50", "8 c #ACC4C9", "9 c #F7F9F9", "0 c #FDFDFD", "a c #F6F8F9", "b c #C4D5D9", "c c #83A1A7", "d c #617F86", "e c #5B7980", "f c #64848C", "g c #859FA5", "h c #D6E2E5", "i c #D1DEE1", "j c #9BB8BF", "k c #6B848A", "l c #A9B4B7", "m c #949B9C", "n c #6E8C93", "o c #5F7E86", "p c #485D61", "q c #2D3739", "r c #80A4AC", "s c #76989F", "t c #B6BEC1", "u c #CBD0D2", "v c #E5E6E7", "w c #D2D4D5", "x c #7C8B8E", "y c #65878E", "z c #2D3C3F", "A c #6B6F6F", "B c #6C848A", "C c #C9D0D1", "D c #607377", "E c #C4D0D2", "F c #D4D4D4", "G c #8C9395", "H c #212B2E", "I c #666768", "J c #3D4A4D", "K c #6C9199", "L c #96ACB1", "M c #CDD0D1", "N c #929697", "O c #646869", "P c #575757", "Q c #1D2729", "R c #1F2A2C", "S c #414242", "T c #6F7070", "U c #909082", "V c #545450", " ", " .+@# ", " $%&*=. ", " .-;>,')! ", " $%~{]'^^/(_ ", " :<[^^^^^}|@# ", " 123^^^^456=. ", " $7890abcdef! ", " %ghijklmnop_", " qrstuvwxyz%", " ABsCDEFGHI$", " $JKLMNOP ", " $QRST$ ", " _UV "}; wxglade-0.6.8.orig/icons/gtk/new.xpm0000644000175000017500000000260411621715605017542 0ustar georgeskgeorgesk/* XPM */ static char * new_xpm[] = { "14 14 74 1", " c None", ". c #A6A6A6", "+ c #8E8E8E", "@ c #50504D", "# c #707064", "$ c #474740", "% c #474747", "& c #7A7A6D", "* c #B1B19F", "= c #DCDCC5", "- c #B5B5A4", "; c #767676", "> c #BEBEBE", ", c #4B4B4B", "' c #52524C", ") c #CBCBB5", "! c #D6D6C0", "~ c #D8D8C1", "{ c #DDDDC5", "] c #E2E2CA", "^ c #88887A", "/ c #949494", "( c #828282", "_ c #6F6F68", ": c #CDCDB7", "< c #D7D7C0", "[ c #DADAC3", "} c #E0E0C8", "| c #E5E5CD", "1 c #D7D7C1", "2 c #6A6A64", "3 c #9D9D9B", "4 c #B2B2AF", "5 c #8F8F80", "6 c #D6D6BF", "7 c #DFDFC7", "8 c #E8E8CF", "9 c #EAEAD2", "0 c #EFEFD6", "a c #CFCFBA", "b c #9E9E99", "c c #7F7F7A", "d c #A3A392", "e c #E4E4CC", "f c #EBEBD2", "g c #F2F2D9", "h c #F3F3DA", "i c #848479", "j c #1A1A19", "k c #B9B9A5", "l c #D9D9C2", "m c #E1E1CA", "n c #E7E7CF", "o c #EEEED5", "p c #F4F4DB", "q c #E8E8D1", "r c #757569", "s c #5E5E59", "t c #DDDDC6", "u c #E9E9D0", "v c #F5F5DC", "w c #BBBBA8", "x c #D8D8C2", "y c #F0F0D7", "z c #99998E", "A c #EDEDD4", "B c #F1F1D8", "C c #68685D", "D c #63635E", "E c #D2D2BC", "F c #A9A997", "G c #71716F", "H c #909082", "I c #545450", " .. ", " +@#$ ", " .%&*=-; ", " >,')!~{]^/ ", " +(_:<[}|12 ", " +34567890a% ", " +bcd[ef0ghi. ", " +jklmnogppqr.", " +s[teu0gvvvw%", " %x]nfyhv0i% ", " .zn9ABh[C. ", " DEoynF; ", " +^BmCG ", " ;HI "}; wxglade-0.6.8.orig/icons/gtk/copy.xpm0000644000175000017500000000253011621715605017721 0ustar georgeskgeorgesk/* XPM */ static char * copy_xpm[] = { "14 14 71 1", " c None", ". c #767676", "+ c #BEBEBE", "@ c #979797", "# c #3B3B37", "$ c #A0A090", "% c #707064", "& c #8E8E8E", "* c #70706D", "= c #94948F", "- c #CACAB8", "; c #B7B7A4", "> c #555552", ", c #A6A6A6", "' c #474747", ") c #7D7D70", "! c #4F4F4C", "~ c #777773", "{ c #7E7E71", "] c #CECEB9", "^ c #E0E0C8", "/ c #4B4B43", "( c #787875", "_ c #ACACA1", ": c #D6D6C0", "< c #6E6E63", "[ c #68685D", "} c #CDCDB8", "| c #DDDDC6", "1 c #E3E3CC", "2 c #4C4C44", "3 c #B1B1AC", "4 c #8C8C81", "5 c #DADAC3", "6 c #D4D4BE", "7 c #585852", "8 c #E2E2CA", "9 c #E8E8D0", "0 c #4E4E46", "a c #919181", "b c #CECEB8", "c c #DFDFC8", "d c #969686", "e c #71716F", "f c #CACAB5", "g c #E5E5CE", "h c #ECECD4", "i c #4F4F47", "j c #B3B3A0", "k c #DCDCC5", "l c #E2E2CB", "m c #E7E7D0", "n c #E5E5CD", "o c #474740", "p c #45453D", "q c #ADAD9B", "r c #606058", "s c #44443D", "t c #DBDBC4", "u c #E7E7CF", "v c #C6C6B2", "w c #808073", "x c #70706F", "y c #D6D6D6", "z c #727270", "A c #ACAC9A", "B c #737367", "C c #545450", "D c #5F5F5F", "E c #5E5E57", "F c #000000", " ", " ", " .. ", "+@#$%& &+ ", "&*=-;>,')! ", "&~{]^/(_:<, ", "&[}|123456' ", ",7|890abc1de ", " 'fghijklmno ", " pqr'stuhvw. ", " xx,yzA5BC& ", " +&DD,E', ", " &FFF , ", " ,, "}; wxglade-0.6.8.orig/icons/gtk/generate.xpm0000644000175000017500000000272411621715605020546 0ustar georgeskgeorgesk/* XPM */ static char * generate_xpm[] = { "14 14 79 1", " c None", ". c #A6A6A6", "+ c #27251C", "@ c #28261C", "# c #4A4942", "$ c #BEBEBE", "% c #66624E", "& c #A19972", "* c #A49C74", "= c #928B67", "- c #56544A", "; c #8E8E8E", "> c #26241B", ", c #B1A87D", "' c #9C946E", ") c #8C8563", "! c #14130E", "~ c #ADA57A", "{ c #B6AD80", "] c #938C68", "^ c #65614E", "/ c #756F52", "( c #56544B", "_ c #767676", ": c #4E4A3E", "< c #6A6652", "[ c #4B4735", "} c #423E2E", "| c #958D69", "1 c #BFB687", "2 c #6C674C", "3 c #69644A", "4 c #676148", "5 c #74736E", "6 c #99926C", "7 c #CBC18F", "8 c #CDC391", "9 c #CFC592", "0 c #CEC492", "a c #C8BF8E", "b c #6B654B", "c c #C7BE8D", "d c #D2C895", "e c #D1C793", "f c #C3BA8A", "g c #D4CA96", "h c #D1C794", "i c #716B4F", "j c #5A584D", "k c #474747", "l c #BCB385", "m c #AAA278", "n c #A39C73", "o c #C2B989", "p c #D2C894", "q c #CAC08E", "r c #7F7959", "s c #7E7859", "t c #D0C693", "u c #D1C894", "v c #A9A177", "w c #D0C692", "x c #CEC592", "y c #9A926D", "z c #5F5F5F", "A c #847D5D", "B c #CCC290", "C c #CEC491", "D c #413E2D", "E c #59574D", "F c #ABA278", "G c #847E5D", "H c #B0A87D", "I c #C5BC8B", "J c #99916C", "K c #8C8562", "L c #BBB284", "M c #3D3A2B", "N c #73726D", " .+@#$ ", ".%&*=- ", ";>,')! .;$ ", ";>~{]!.^/(.. ", " _:<[]}|1234. ", " ..567890ab. ", " .3cdefghij$", " klcdmnopqr;", " _s,tuvwxy<.", " zABt9CcD. ", " EFGHIJ=K_ ", " $EzsLMNN ", " _k. ", " "}; wxglade-0.6.8.orig/icons/spinbtn.xpm0000644000175000017500000000131211621715605017634 0ustar georgeskgeorgesk/* XPM */ static char * spinbtn_xpm[] = { "21 21 7 1", " c None", ". c #141414", "+ c #D6D6D6", "@ c #D4D4D4", "# c #000000", "$ c #0A0A0A", "% c #0D0D0D", " ", " ", " ", " ........... ", " .+++@+@+++. ", " .++++#++++. ", " .+++...+++. ", " .++.....++. ", " .+.......+. ", " .+++++++++. ", " ........... ", " $+++++++++$ ", " .+.......+. ", " .++.....++. ", " .+++...+++. ", " .++++.++++. ", " .+++++++++. ", " #%%%%%%%%%# ", " ", " ", " "}; wxglade-0.6.8.orig/icons/spin_ctrl.xpm0000644000175000017500000000217711621715605020166 0ustar georgeskgeorgesk/* XPM */ static char * spin_ctrl_xpm[] = { "21 21 38 1", " c None", ". c #000000", "+ c #060608", "@ c #000002", "# c #020202", "$ c #010101", "% c #080808", "& c #131313", "* c #FFFFFF", "= c #F7F7F7", "- c #FDFDFD", "; c #EBEBEB", "> c #FCFCFC", ", c #D4D4D4", "' c #070707", ") c #CFCFCF", "! c #8F8F8F", "~ c #FBFBFB", "{ c #040404", "] c #050505", "^ c #7C7C7C", "/ c #0C0C0C", "( c #090909", "_ c #111111", ": c #6B6B6B", "< c #0B0B0B", "[ c #0A0A0A", "} c #F6F6F6", "| c #FEFEFE", "1 c #030303", "2 c #CDCDCD", "3 c #BFBFBF", "4 c #737373", "5 c #787878", "6 c #838383", "7 c #797979", "8 c #828282", "9 c #888888", " ", " ", " ", " ", " ", " ", " .+.@.@.@.@.#$.#%... ", " &**********=.-*;>*# ", " .**--------*#>,')!. ", " .**********~.*.{]^$ ", " $**********-/**=**. ", " %**---------.*.(_:< ", " [}|*********1*2.34[ ", " .*|*********.56789. ", " {<.$$$$$$$$$$$$$$$$ ", " ", " ", " ", " ", " ", " "}; wxglade-0.6.8.orig/icons/calendar_ctrl.xpm0000644000175000017500000000130011621715605020751 0ustar georgeskgeorgesk/* XPM */ static char * calendar_ctrl_xpm[] = { "21 21 8 1", " c None", ". c #000000", "+ c #BFBFBF", "@ c #FEFEFE", "# c #8E8ED1", "$ c #FFFFFF", "% c #FF8080", "& c #FFF1F1", " ", " ", ".....................", ".+++++++++++++++++++.", ".+@@++@@+++++@@@@@@+.", ".+++++++++++++++++++.", ".....................", ".###################.", ".$$$$$$$$$$$$$$$$$$$.", ".$$$$$##$$##$$##$%%$.", ".$$$$$##$$##$$##$%%$.", ".$$$$$$$$$$$$$$$$$&$.", ".$##$$##$$##$$##$%%$.", ".$##$$##$$##$$##$%%$.", ".$$$$$$$$$$$$$$$$$$$.", ".$##$$##$$##$$##$$$$.", ".$##$$##$$##$$##$$$$.", ".$$$$$$$$$$$$$$$$$$$.", ".....................", " ", " "}; wxglade-0.6.8.orig/icons/frame.xpm0000644000175000017500000000134611621715605017260 0ustar georgeskgeorgesk/* XPM */ static char * frame_xpm[] = { "21 21 11 1", " c None", ". c #7B7B7B", "+ c #F2F2F2", "@ c #00007B", "# c #FF0000", "$ c #FFFF00", "% c #000000", "& c #00FFFF", "* c #00FF00", "= c #FFFFFF", "- c #D6D6D6", " ", " ", "....................+", ".@#$@@@@@@@@@@@@@@@.%", ".@&*@===@==@@@@@-%-.%", "....................%", ".-=================.%", ".-=================.%", ".-=================.%", ".-=================.%", ".-=================.%", ".-=================.%", ".-=================.%", ".-=================.%", ".-=================.%", ".-=================.%", "....................%", "+%%%%%%%%%%%%%%%%%%%%", " ", " ", " "}; wxglade-0.6.8.orig/icons/dialog.xpm0000644000175000017500000000731411621715605017426 0ustar georgeskgeorgesk/* XPM */ static char * dialog_xpm[] = { "21 21 173 2", " c None", ". c #7D7F7E", "+ c #666A69", "@ c #747877", "# c #696F6D", "$ c #7F838C", "% c #7A7796", "& c #706B93", "* c #7A759D", "= c #928EB3", "- c #79759A", "; c #716D8E", "> c #928FAE", ", c #686580", "' c #817F94", ") c #737282", "! c #6F6F79", "~ c #787E7C", "{ c #191F1D", "] c #4C5552", "^ c #E7F0ED", "/ c #00050D", "( c #0E0D2F", "_ c #090331", ": c #120C38", "< c #06002C", "[ c #07022B", "} c #050126", "| c #120E2F", "1 c #14112E", "2 c #000013", "3 c #100F21", "4 c #191925", "5 c #000005", "6 c #7D8884", "7 c #000400", "8 c #AFBAB6", "9 c #8D9894", "0 c #040B13", "a c #FBFAFF", "b c #FEF9FF", "c c #F6F1FF", "d c #1A153D", "e c #0A062B", "f c #181437", "g c #00001B", "h c #E3E0FB", "i c #121026", "j c #CBCADC", "k c #00000B", "l c #07080D", "m c #75807C", "n c #788480", "o c #6A7672", "p c #798581", "q c #737C81", "r c #78798E", "s c #797695", "t c #747190", "u c #7B7897", "v c #827F9E", "w c #6B6885", "x c #8D8AA5", "y c #6E6C82", "z c #78768B", "A c #7A7989", "B c #80808C", "C c #06060E", "D c #67726E", "E c #F7FFFF", "F c #F3FFFB", "G c #F8FFFF", "H c #F4F7FF", "I c #FAF9FF", "J c #FEFDFF", "K c #F9F8FF", "L c #FDFCFF", "M c #FAFAFF", "N c #7D7D89", "O c #000007", "P c #828D89", "Q c #F3FEFA", "R c #E3EEEA", "S c #F9FFFF", "T c #FCFFFF", "U c #FCFDFF", "V c #F4F5F7", "W c #FEFFFF", "X c #F7F7FF", "Y c #FEFEFF", "Z c #7D7D87", "` c #707674", " . c #FBFFFF", ".. c #F5FEFB", "+. c #89928F", "@. c #F0F9F4", "#. c #787E74", "$. c #686B60", "%. c #FEFFF8", "&. c #7A7D76", "*. c #767875", "=. c #727375", "-. c #77787C", ";. c #FAFBFF", ">. c #7D7E83", ",. c #8D8F8E", "'. c #F9FDFC", "). c #F2F6F5", "!. c #F6FCFA", "~. c #F6FDF6", "{. c #FBFFF1", "]. c #FEFFF3", "^. c #FEFFF4", "/. c #FEFFF6", "(. c #F4F7F0", "_. c #F9FBF6", ":. c #FEFFFD", "<. c #7D7E82", "[. c #000004", "}. c #6B6B6B", "|. c #FFFFFF", "1. c #FEFFFB", "2. c #FDFFF3", "3. c #EDF0E5", "4. c #FEFFFA", "5. c #F0F2ED", "6. c #F4F6F5", "7. c #FAFBFD", "8. c #7D7E80", "9. c #000002", "0. c #858384", "a. c #FDF9FA", "b. c #E5E3E4", "c. c #FFFEFF", "d. c #6D6D6B", "e. c #6D7069", "f. c #84877E", "g. c #E4E6E1", "h. c #8A8C89", "i. c #7E807F", "j. c #000100", "k. c #7B7778", "l. c #FFFDFF", "m. c #E8E4E5", "n. c #8D8B8C", "o. c #090909", "p. c #010302", "q. c #F1F2F4", "r. c #747579", "s. c #010206", "t. c #FAFCFB", "u. c #7D7F7C", "v. c #858182", "w. c #F7F3F4", "x. c #FBF7F8", "y. c #EDEEF2", "z. c #F8F9FD", "A. c #7D7B7C", "B. c #848283", "C. c #6A6869", "D. c #878586", "E. c #727272", "F. c #797979", "G. c #79797B", "H. c #777777", "I. c #898989", "J. c #000000", "K. c #080808", "L. c #0F0F0F", "M. c #070707", "N. c #010101", "O. c #060606", "P. c #020202", " ", " ", " ", " . + @ # $ % & * = - ; > , ' ) ! ", " ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 ", " 6 7 8 9 0 a b c d e f g h i j k l ", " m n o p q r s t u v w x y z A B C ", " D E E F G H I J J a K L a J M N O ", " P G Q R S T U V W W X Y Y Y M Z O ", " ` ...+.@.#.$.%.&.*.W =.-.W ;.>.5 ", " ,.'.).!.~.{.].^./.(._.:.W W ;.<.[. ", " }.|.|.W 1./.2.3.%.4.5.:.6.W 7.8.9. ", " 0.a.b.c.d.e.f.4.g.h.. i.W W 7.. j. ", " k.l.c.m.n.o.p.q.W r.s.[.W W t.u.j. ", " v.w.x.c.c.|.y.W W z.W z.W W t.u.j. ", " A.B.C.D.E.F.G.G.G.G.G.G.G.H.I.}.J. ", " J.K.L.M.N.N.N.N.N.N.N.N.J.N.O.P. ", " ", " ", " ", " "}; wxglade-0.6.8.orig/icons/text_ctrl.xpm0000644000175000017500000000121711621715605020173 0ustar georgeskgeorgesk/* XPM */ static char * text_ctrl_xpm[] = { "21 21 5 1", " c None", ". c #7B7B7B", "+ c #FFFFFF", "@ c #000000", "# c #D6D6D6", " ", " ", "....................+", ".@@@@@@@@@@@@@@@@@@#+", ".@+++++++++++++++++#+", ".@+++++++++++++++@+#+", ".@++++++++@++++++@+#+", ".@++++++++@++++++@+#+", ".@+++@@@++@#@@+++@+#+", ".@++@#+#@+@@+.@++@+#+", ".@++++++@+@+++@++@+#+", ".@+++@@@@+@+++@++@+#+", ".@++@#++@+@+++@++@+#+", ".@++@#++@+@++.@++@+#+", ".@+++@@@@+@@@@+++@+#+", ".@+++++++++++++++@+#+", ".@+++++++++++++++++#+", ".###################+", "+++++++++++++++++++++", " ", " "}; wxglade-0.6.8.orig/icons/wxg_file.ico0000644000175000017500000000427611621715605017745 0ustar georgeskgeorgesk @¨( @HH¾¬ª¬þüäæäüüþüüôòô„dÿÿZ„ÿÿdZ„dtZ„ZeZdee„ƒiZZddd„„„ZZZded„i„ZdZd„d„Z„ZdZd„ d„Z„Zd Zd„!d„Z„Zd Zd„"d„Z „Zd Zd„# d„Z „Zd Zd„$ d„Z! „Zd Zd„% d„Z" „Zd Zd„& d„Z# „Zd Zd„' d„Z$„Zd Zd„(d„Z%„Zd Zd„)d„Z&„ZdZd„*d„Z'„ZdZd„+d„Z(„ZdZd„,d„Z)„ZdZd„-d„Z*„ZdZe„.deZ+„ƒdZZ„/ddZ,„„eZZe0deƒ-„eZZƒd1dZ„.„ZZe2de/„ƒðZààààààààààààààààààààààààààààà?ààÿàÿwxglade-0.6.8.orig/icons/toolbar.xpm0000644000175000017500000000123411621715605017624 0ustar georgeskgeorgesk/* XPM */ static char * toolbar_xpm[] = { "21 21 6 1", " c None", ". c #FFFFFF", "+ c #000000", "@ c #DEDEDE", "# c #7B7B7B", "$ c #D6D6D6", " ", " ", " ", " ", " ..................+ ", " .@@@@#$$$$$$$$$$$#+ ", " ..@@@#$$$$$$$$$$$#+ ", " .@#.@#$$$$$$$$$$$#+ ", " .@@@##$$$$$$$$$$$#+ ", " ..@@@#$$$$$$$$$$$#+ ", " .@#.@#$$$$$$$$$$$#+ ", " .@@@##$$$$$$$$$$$#+ ", " ..@@@#$$$$$$$$$$$#+ ", " .@#.@#$$$$$$$$$$$#+ ", " .@@@##$$$$$$$$$$$#+ ", " .#################+ ", " +++++++++++++++++++ ", " ", " ", " ", " "}; wxglade-0.6.8.orig/icons/slider.xpm0000644000175000017500000000123311621715605017443 0ustar georgeskgeorgesk/* XPM */ static char * slider_xpm[] = { "21 21 6 1", " c None", ". c #000000", "+ c #7B7B7B", "@ c #FFFFFF", "# c #D6D6D6", "$ c #DEDEDE", " ", " ", " .. .. ", " . . . . ", " . . . . ", " . . . . ", " . . . . ", " .. . .. ", " ", " ", "+++++++++++++++++++++", "+...................@", "+.@@@@@@@@.########$@", "+.@###+##+.########$@", "+.@###+##+.########$@", "+.@+++++++.########$@", "+..........########$@", "+.$$$$$$$$$$$$$$$$$$@", "+@@@@@@@@@@@@@@@@@@@@", " ", " "}; wxglade-0.6.8.orig/icons/static_bitmap.xpm0000644000175000017500000000130011621715605020777 0ustar georgeskgeorgesk/* XPM */ static char * static_bitmap_xpm[] = { "21 21 8 1", " c None", ". c #001815", "+ c #F20000", "@ c #FBE800", "# c #110C00", "$ c #110095", "% c #060400", "& c #060D00", " ", " ", " .......... ", " .++++++++. ", " .++++++++..... ", " .+++++++.@@@@@. ", " .++++++.@@@@@@@. ", " .+++++.@@@@@@@@@. ", " .+++++.@@@@@@@@@. ", " .+++++.@@@@@@@@@. ", " .+++++.@@@@@@@@@. ", " ........@@@@@@@# ", " .$$$$$%@@@@@& ", " .$$$$$$..... ", " .$$$$$$$$$. ", " .$$$$$$$$$. ", " .$$$$$$$$$. ", " ........... ", " ", " ", " "}; wxglade-0.6.8.orig/icons/grid_sizer.xpm0000644000175000017500000000154311621715605020326 0ustar georgeskgeorgesk/* XPM */ static char * grid_sizer_xpm[] = { "21 21 19 1", " c None", ". c #FFFFFF", "+ c #000000", "@ c #D8D8D8", "# c #7B7B7B", "$ c #060606", "% c #0A0A0A", "& c #141414", "* c #FBFBFB", "= c #7A7A7A", "- c #0E0E0E", "; c #040404", "> c #010101", ", c #0B0B0B", "' c #101010", ") c #050505", "! c #030303", "~ c #080808", "{ c #020202", "..........+.........+", ".@@@@@@@@#$.@@@@@@@#%", ".@@@@@@@@#+.@@@@@@@#+", ".@@@@@@@@#&.@@@@@@@#%", ".@@@@@@@@#+.@@@@@@@#+", "*==#######+.########-", ";>>>>>>>>+,+;$$>++;+,", "..........+.........+", ".@@@@@@@@#'.@@@@@@@#)", ".@@@@@@@@#+.@@@@@@@#+", ".@@@@@@@@#!.@@@@@@@#+", ".@@@@@@@@#+.@@@@@@@#~", ".#########+.########+", ";++++++++-+{~++;+!!++", "..........+.........'", ".@@@@@@@@#;.@@@@@@@#;", ".@@@@@@@@#{.@@@@@@@#+", ".@@@@@@@@#$.@@@@@@@#+", ".@@@@@@@@#%.@@@@@@@#%", ".#########+.########+", ";+++++++++;!+{+++{)++"}; wxglade-0.6.8.orig/icons/msw/0000755000175000017500000000000012170277707016250 5ustar georgeskgeorgeskwxglade-0.6.8.orig/icons/msw/save_as.xpm0000644000175000017500000000071711621715605020416 0ustar georgeskgeorgesk/* XPM */ static char * save_as_xpm[] = { "16 16 6 1", " c None", ". c #000000", "+ c #808000", "@ c #C0C0C0", "# c #FFFFFF", "$ c #808080", " ", " ", "........... ", ".+.@#@#@.@. ", ".+.#@...........", ".+.@#.+.@#@#@.@.", ".+.#$.+.#@#@#...", ".+....+.@#@#@.+.", ".+++$.+.#@#@#.+.", ".+....+.......+.", ".+.$$.+++++++++.", ".+.$$.+.......+.", " .....+.$$$.@.+.", " $.+.$$$.@.+.", " $$..........", " "}; wxglade-0.6.8.orig/icons/msw/tutorial.xpm0000644000175000017500000000073711621715605020642 0ustar georgeskgeorgesk/* XPM */ static char * tutorial_xpm[] = { "16 16 7 1", " c None", ". c #000000", "+ c #FFFFFF", "@ c #FFFF00", "# c #000080", "$ c #C0C0C0", "% c #808080", " ", " ...... ", " ..++@+@+.. ", " .@+@####+@+. ", " .++##@$##++. ", " .+@+#%++##@++. ", " .+++@+@%#%++@. ", " .+@+++%#++@++. ", " .+++@+#%@+++@. ", " .@+++@+++@+. ", " .++@+##@+++. ", " .+++@+++.. ", " .+@..... ", " .+. ", " .. ", " . "}; wxglade-0.6.8.orig/icons/msw/cut.xpm0000644000175000017500000000063611621715605017570 0ustar georgeskgeorgesk/* XPM */ static char * cut_xpm[] = { "16 16 3 1", " c None", ". c #808080", "+ c #000080", " . . ", " . . ", " + + ", " +. .+ ", " ++ ++ ", " .+ +. ", " +++ ", " .+. ", " +++ ", " + +++ ", " +++ + .+ ", " +. + + + ", " + + +. + ", " + .+ ++ ", " ++ ", " "}; wxglade-0.6.8.orig/icons/msw/prefs.xpm0000644000175000017500000000064011621715605020107 0ustar georgeskgeorgesk/* XPM */ static char * prefs_xpm[] = { "16 16 3 1", " c None", ". c #000000", "+ c #FFFFFF", " ", " ..... .. ", " .+.+++... ", " .....+.+.+++.. ", " .++.+.+.+.++.. ", " .+.+.+.+.+.... ", " .++.+++.+.. .. ", " .+++++++.+. ", " .+++++++++. ", " .+..+....+. ", " .+++++++++. ", " .+..+....+. ", " .+++++++++. ", " ........... ", " ", " "}; wxglade-0.6.8.orig/icons/msw/refresh.xpm0000644000175000017500000000051711621715605020431 0ustar georgeskgeorgesk/* XPM */ static char * refresh_xpm[] = { "14 14 2 1", " c None", ". c #000080", " ", " ...... ", " ........ ", " ... .. ", " ... .. ", "..... ", " ... . ", " . ... ", " .....", " .. ... ", " .. ... ", " ........ ", " ...... ", " "}; wxglade-0.6.8.orig/icons/msw/paste.xpm0000644000175000017500000000075311621715605020111 0ustar georgeskgeorgesk/* XPM */ static char * paste_xpm[] = { "16 16 8 1", " c None", ". c #000000", "+ c #FFFF00", "@ c #808000", "# c #C0C0C0", "$ c #808080", "% c #FFFFFF", "& c #000080", " ", " .... ", " .....++..... ", " .@#@.+..+.#@#. ", "$.#$.%%%%%%.$@. ", "$.@$........$#. ", "$.#@#@##&&&&&&. ", "$.@#@#@$&%%%%&& ", "$.#@#@#$&%%%%&%&", "$.@#@#@$&%..%&&&", "$.#@#@#$&%%%%%%&", "$.@#@#@$&%....%&", " $......&%%%%%%&", " $$$$$$&&&&&&&&", " $$$$$$$ ", " "}; wxglade-0.6.8.orig/icons/msw/remove.xpm0000644000175000017500000000067711621715605020277 0ustar georgeskgeorgesk/* XPM */ static char * remove_xpm[] = { "16 16 5 1", " c None", ". c #000000", "+ c #C0C0C0", "@ c #808080", "# c #FFFFFF", " ", " ", " ..... ", " ....++++.... ", " .@@@@@@@@@@. ", " .@+@+#@+@+@. ", " .@@@@@@@@. ", " .@+@+#@+@. ", " .@+@+#@+@. ", " .@+@+#@+@. ", " .@+@+#@+@. ", " .@+@+#@+@. ", " .@+@+#@+@. ", " .@+@+#@+@. ", " ........ ", " "}; wxglade-0.6.8.orig/icons/msw/exit.xpm0000644000175000017500000000065611621715605017750 0ustar georgeskgeorgesk/* XPM */ static char * exit_xpm[] = { "16 16 4 1", " c None", ". c #000000", "+ c #FF0000", "@ c #FFFFFF", " ", " ... ", " . .+. ", " .. .+. ", " .@. .+. ", " ....@@. .+. ", " .@@@@@@. .+. ", " ..@@@@@@@..+. ", " ..@@@@@@. .+. ", " .....@@.. .+. ", " .....@.. .+. ", " ... .+. ", " .. .+. ", " . .+. ", " ... ", " "}; wxglade-0.6.8.orig/icons/msw/open.xpm0000644000175000017500000000071411621715605017733 0ustar georgeskgeorgesk/* XPM */ static char * open_xpm[] = { "16 16 6 1", " c None", ". c #000000", "+ c #FFFF00", "@ c #FFFFFF", "# c #808080", "$ c #808000", " ", " ", " ... ", " . . .", " ... ..", " .+@+...... ...", " .@+@+@+@+. ", " #.+@+@+@+@. ", " #.@+@+.........", " #.+@+.$$$$$$$$.", " #.@+.$$$$$$$$. ", " #.+.$$..$$$$. ", " #..$$$$$$$$. ", " #.......... ", " ######### ", " "}; wxglade-0.6.8.orig/icons/msw/save.xpm0000644000175000017500000000071411621715605017730 0ustar georgeskgeorgesk/* XPM */ static char * save_xpm[] = { "16 16 6 1", " c None", ". c #000000", "+ c #808000", "@ c #C0C0C0", "# c #FFFFFF", "$ c #808080", " ", " ", " ............. ", " .+.@#@#@#@.@. ", " .+.#@#@#@#... ", " .+.@#@#@#@.+. ", " .+.#@#@#@#.+. ", " .+.@#@#@#@.+. ", " .++.......++. ", " .+++++++++++. ", " .++........+. ", " .++..$..@@.+. ", " .++.$.$.@@.+. ", " .++..$..@@.+. ", " ............ ", " "}; wxglade-0.6.8.orig/icons/msw/new.xpm0000644000175000017500000000067411621715605017570 0ustar georgeskgeorgesk/* XPM */ static char * new_xpm[] = { "16 16 5 1", " c None", ". c #000000", "+ c #FFFFFF", "@ c #808080", "# c #C0C0C0", " ", " ", " ....... ", " .+++++.. ", " @.+++++.+. ", " @.+++++.... ", " @.++++++##. ", " @.++++++++. ", " @.++++++++. ", " @.++++++++. ", " @.++++++++. ", " @.++++++++. ", " @.++++++++. ", " @.......... ", " @@@@@@@@@ ", " "}; wxglade-0.6.8.orig/icons/msw/copy.xpm0000644000175000017500000000067511621715605017752 0ustar georgeskgeorgesk/* XPM */ static char * copy_xpm[] = { "16 16 5 1", " c None", ". c #000080", "+ c #808080", "@ c #FFFFFF", "# c #000000", " ", " ...... ", "+.@@@@.. ", "+.@@@@.@# ", "+.@##@....... ", "+.@@@@+.@@@@.# ", "+.@####.@@@@.@# ", "+.@@@@+.@##@....", "+.@####.@@@@@@@.", "+.@@@@+.@#####@.", "+.......@@@@@@@.", "+++++++.@#####@.", " +.@@@@@@@.", " +.........", " ++++++++ ", " "}; wxglade-0.6.8.orig/icons/msw/generate.xpm0000644000175000017500000000072011621715605020561 0ustar georgeskgeorgesk/* XPM */ static char * generate_xpm[] = { "16 16 6 1", " c None", ". c #000080", "+ c #FFFFFF", "@ c #000000", "# c #C0C0C0", "$ c #0000FF", " ", " ", " . ", " .+ ", " .+. ", " .+.. ", " .+... ", " @@@@@@@ .+... ", " @+++++#.+... ", " @++++#.+... ", " @+++#.+... ", " @+++#.... ", " @++#.+.. ", " @++#$$ ", " @@#$ ", " "}; wxglade-0.6.8.orig/icons/choice.xpm0000644000175000017500000000165211621715605017420 0ustar georgeskgeorgesk/* XPM */ static char * choice_xpm[] = { "21 21 24 1", " c None", ". c #FFFFFF", "+ c #000000", "@ c #D5D5D5", "# c #7C7C7C", "$ c #040404", "% c #D6D6D6", "& c #171717", "* c #D4D4D4", "= c #E2E2E2", "- c #101010", "; c #0C0C0C", "> c #D8D8D8", ", c #131313", "' c #D7D7D7", ") c #D2D2D2", "! c #FBFBFB", "~ c #070707", "{ c #111111", "] c #010101", "^ c #1B1B1B", "/ c #090909", "( c #0F0F0F", "_ c #0A0A0A", " ", " ", " ", " ", "....................+", ".@@@@@@@@@@@@@@@@@@#$", ".@@@@@@@@@@@@@@@@@@#$", ".%@@@@@@@@@@@@@@@@@#+", ".%@@@@@@@@@@@@@@@@@#&", ".%@@@@@@@@*@@...@@@#+", ".%@@@@@@@@@@@.==-@@#+", ".%@@@@@@@@@@@@+++@@#;", ".%@@@@@@@@@@@@@@@@@#+", ".%@@@@@@@@@@>%@@@@@#,", ".%@'%@@@@@@@@@@*')@#+", "!@@@@@@@%%%%%@@@@@@#+", ".###################~", "++{]^+]++++++++/+++(_", " ", " ", " "}; wxglade-0.6.8.orig/icons/gauge.xpm0000644000175000017500000000123211621715605017250 0ustar georgeskgeorgesk/* XPM */ static char * gauge_xpm[] = { "21 21 6 1", " c None", ". c #7B7B7B", "+ c #FFFFFF", "@ c #000000", "# c #D6D6D6", "$ c #DEDEDE", " ", " ", " ", " ", " ", " .................. ", " .++++++.@########+ ", " .+$$$$$.@########+ ", " .+$$$$$.@########+ ", " .+$$$$$.@########+ ", " .+$$$$$.@########+ ", " .+$$$$$.@########+ ", " ........@########+ ", " .@@@@@@@@########+ ", " ++++++++++++++++++ ", " ", " ", " ", " ", " ", " "}; wxglade-0.6.8.orig/icons/wxglade_small.png0000644000175000017500000011136611621715605020775 0ustar georgeskgeorgesk‰PNG  IHDRs[2e}bKGDtn^“ pHYs  ÒÝ~ütIMEÔ%RO^× IDATxœì½yå×uß÷¹÷·¼µ»_oÓˬHwí&•²Jv9‰#y‘ǕĎRUJUŽc%‘’Tä¤\e—âÄ’¥(%‘ËŠ–ˆKE‘I‰$H‚à€X3˜}¦·×oýmw9ùãþº§ 1À ìoU×t÷¼~ï÷»¿{Ï=ç{¾ç\%"Â!qˆCâM ýF_À!qˆCâöqhÌqˆCâ-€Cc~ˆCâoóCâ‡x ~£/ào x[!v‚ø>ßÀdç¨qã(Që(JW¨x•(m¾Ñ—{ˆC¼åphÌq[o0£g±“'©vþ7} |‰w9Þ‡×8×@T—¸q”xþßEußA³5GÚ{QÒ@©Ãñ‡¸]¨Ciâ!^ Ä;ìô<յߣÜýÜô«˜Òá½à=8'˜JH õTS1Qkhþ¯7gˆô:ªý´Ž¼f»ƒRê ¼³Câ͉Cc~ˆW —_§ØúCŠË¿‚ËOcMEY eá)JMåæpÆQúyR=ÅÇ (‰ê£(i¤ ÉðÞÃ(_Äú£¬þÀ/rôî÷277÷Fßâ!ñ¦Ã!Írˆ[†ˆ`0½øsäŸÂ›1ei˜N„¢ê’WM\1fêRÄ[<Pê¨.©R%L[³¤‘)ÈL—~ÌpºIuô"Q{­Ý™™Cý‡x84懸%x[Rmÿ)ãgÿ1åø4nj1¥Kšˆ)˜ºBd €,Š PÅZyb•ÍÚl#ª‹×hÎ\¥ÙlÒj·‰ãÃéyˆ›!"à-‚G¡@) ¥^róïêÿ{ëçeWË!^â*òËatîg1ýg(‹„±ïVLòŠÊ+P1P€€C ñ«T P <`¼Â”šÍüƒáUìö;;ÛY9·šýó¶@LJ*›owˆ³ó¥LyýigÕ˜EÍüù5T#!Ž‚IsÎ"Ʋ{ýYºwýæ×ï{ƒ¯üõÇ¡1?Ä7…wÙ¥ßg|ö©6Ï3q%ãqÉ4‹W… ¾âƒg¤"’ž8P‘„ŸáFeƒ#š¬LqV¨$f8žeUe°Ö’$ÉërO"‚·%H†_#¿úiª2gæíæÜòëò™‡¸3ç™\x ÷ü×ñí9¼¬|„(n¡"MÔŒñ~Wn0Ø*Z¬þP‡¸»ö–öÞºwvˆÛ†·Õö㌞úÌîyÆFÈG0)al¾ª]íÚh£Ä(Ð žà‚ׯ¢b±õxfyžØ9\9ÁZ‡÷ž<ËhµZwì^Dl¶<ÍÏ`6ŸÁì<„\ÆÛ1¾²˜*cbakÊáϳ¿Ÿ÷ÜËò‘#oi/îÍ / ʱåç$ÐyJ)…*PŠéÔ³™).õ5Ó‹×é½Bš¦ÌÌ̦é}¯ gë!^¡ê?Íø™_¡ÚÙ¦¬ &åòBáØc'Б  _¼r¥ë5JA¤=…‰I#‡¯ië=5Âgßë·ã«»_§ºúiÜð«ØñÜtÞâ­ÁSbÆm¬*É«.ãª`œ• û#¦O| ¶@)ÖÖÖîÀÕâNBDë(­GEá:ê|˜V ,a8ÕŒ˜Á„…Í-–—0Nù!¾sàËÃÇÿ%Õµ/0uã¡bTAžßllE‚Q8«p^#œÓ(-x¯06"M‚õO4X§16¢‘X*á½"RšÊ6Ù[bZ¿vå7ÏÿéÿB´ób?±ø2¸ Q‚)»UAá=ÖFL}…±‚­STlŸù4íõï£Ýí2ßëѼƒTÏ!nùx€ÏKlMá9+8ýÉ)2£ |å)‹)y‘cŒ Qß[‡Æü7ÁÛŠñs¿ÇöÙÿ[Á$WL‹.¦ÈðÖCή܋"ÆcœF¥ð*amX\ÆAE(­DÇ­ÓÁLSˆuÝ$F,Aœ 7 ±‚Á{!¿ö ;;pd8d~~þ-–¿¡Á#w¡1ÞíÓ~^ê\¼‡RÊ "ª6ö‚RêИâ;ftəߢÚÙ¢*ڌʛçTÞ#&¼FÅ„ï$Ê‘W ¾p ƞ뻊íé£é˜ÌDàS©Çúˆ$ŽhjK»5‹Æ2Qàªe ÛfUâ°ØnsÁ5z«ècdræÓÖÒKq,7o°'XñàT„…ržÑ`—A‡ñhô–æXߌ¨tƒÈ N±~ß3ßG=}b/`©ó6µdö-aóCìczæ×]þ4¦h0ª4EžS•>¨Ub‚‡S J£0*"v†–k»³\ì§dc!é¬Óœï' :Ži®ªvì좔pUµPR ˆH™ Ò h…Áy[}vf†åS?Àó½÷ÃöÃŒUÂ|]‘zSsãÛX-§Ø%¦^d´q‘éôʲ|Í×qˆ;Ø•x­PNð"à  í8Q8§p(¼” Þ¿…ùr84æ‡ h°§_£úcÈÄW ò¬`šÛ JàåÔ+xAB[ϰð\´¸ÒO‘(ò¥õ¬;ÆòòN?No¾G»Õ&N¼sk)‹œ,ϩʊ<sÏXÎÍͱ´´H§Ó¹í‚^¯ÇâÊ 3'ÿ<ÅÓC¬Â$šA{ÁÖ—”b'µTå‰"!O˜LÃÆSUÕ­F=Äk‡q‚¸ ñÁxYB¥±öûû4±Äk¢Jð¢Hê(O+uNJѾqhÌ¿ÃQìœgðÈïaǾtd…¦¨<¶òaexHj ŸC“:G?ö=Ûƒ”ʶé­ÝÅòÑ“=~œ'Nrâä VWטŸŸ§½g•Â;GeLðÌ«Š²,±Æ`ŒA€4M˜™™åÈ‘#·]NÇqØTîûQžyî‹h³Z¡kW<G!ŠZÍ H#…S ¦[Y¸Îl:=ì±þme+\جL N´ƒ.Ñ^ð¥#”^ãu¢Æ¾s ¿Æ\¼Å·°“M\ÿ2bÊzljQÑÚ=DÍEâ¹ttçLð[Ò˜‹xÄYP½yC,¼tkÏ;ï=“gáÕÏ¢!«bª ¬«U–š‹P!$бäžÍaÄÈ4é.­3»´ÊêÚ:'OžâäÉ“?~œµõuÆKYkñÞïM'H’„N»MÚhÜö½)¥h5›Ì­ž 1¿ˆlì |¨NõZ‘ˆGÕ’×áþp€x«(ìLYî_ë!¾=àŠ°ñÆu7 q„o&{ö³TçÂà†—°;ç`´¯ÞSÅŠÔiÔ ¤³H: 5{ýöïföÔ{ÐÝ9â´õš×û[Ò˜ûb‹ìÒ§Pº ê¾Ý^ jŸ|ÓõÚ°ƒËØjƒt!œ•y§Q ¯±ýÔÃ0í3.bÊLQнIå€SŠH 7—;¦aTn,Ò[?Åâò2ÇOçä©S¬¯¯süĉoÚñð…Ï¡Ýnßñ{hµÛÌ-­±xäú›ÏbÑ4½#òÁ;œ¹`Ф"äZ“xÌ4'/KʺrðNÀÛ f¼‰Ò­°yhE:û×2@¼ÃL/á&nÍ·æoéïL>AŠœ&Šª"«0’{Éz_Ë#+(oPâIÓ­5ÉLd›l@uõi¦_ÿ#ÌٯⷞCúˆ "V¨b¡·/“,Dˆ¶6±„¤MÚˆð®2š;Aò]‘î÷ýMæÖî~M‡ž¿¹¬Û-ÂeC&OýsÌè šÒû~’¹÷¢Nüf—ßFÚž}Ía¼79fr, Ò*j¼nö†ÿå…Oûšïû¯˜ëõPúÎ|–xÇäéQm=Š«E FW†IfˆˆÄ£•O)š¸r\ÎáÚ0bh˜[]c~q‰'OrìØqŽ=ÊñcÇ^·Öµ¯+ÇOòìÜ8H­Ûï©^xM¢B/|èÆ[ÇØi¼h\S”Ö˜×䙋¦ÿÙõsÈè<2ÜÂå}ªíçw…ÒÉüÝH«CÔ£qê‡H—ßN¤õkZÌßÎ0ëLÏ|¿û4v{ŒœÕFš éÝKëøûi½ýûI»‹/ët“]ìÆSD"¥–8]h½ìô‡OýöÌW‘ébÞxŒxŒ…B%`Æ #p¢* )¡æ¡‘@e,j÷ ùÖeì3_¢õðGÙ|ß_e郙٣¼ª(õ-iÌ'>Ju}€¨˜¢ãCñ ¢ç~‡aﵿÁìý?Jkn™8~eÃ#ÞRî^¤¸ô›TOà&σo"qº÷Òy×?¢=¿N”¶ïXWõÏR^z»=b²ù ìöÓ÷þmzë÷Òétnûý';WèŸþ=L^P–Be=åžjkž<xQ8£©¢Ì¡_h¢Æ<³K«,.-qlý(+++,.,ÜQÏçN@)EwæQœP:C3 ²Ê´vãć¾N  à]Ð%[c0ÖbŒ¡,K¯°°Ä[Üt@~þ!²3ÇmžÁõ¯!Õ)GaÇÀ‡Ï°>Ð<¢*NQ½5’ÙwÑX[#~Û_cîØÛPYâÖÌÛÄ¿•ðU†Ù½ÌøK¿‹9ûöÚã0Ù <ˆ'”×Se)掲säÝwÿ̼ûƒ4–ï%N›7¯§ñßÿ‚ˆLðÌe3¯•WÞ)* •UÄ DQ<óèöÖ¦7ÅùGþñÿŠ}æ!üh€« ¢`jy%"äõµXÊCì5Vy¤‚M8%4J ‰%wæôóçÈ¿öÌþ•Âü;?@oyý–ìÊ«2æ";½„ËK¢öIgá5Ëë‹És3n€·TÒ¡²Í¨­M†çãÊ3aé½?Éò=ïcf~éeßËÛŠÉóÈôÑÿ;ü2í`lIá³}æS´ïúæßñïÓYÿmÉê xÍÓsfz}±»áœÍ'ÿ5ãí§ÈÞý÷Y~à‡™™½èÂVL¯ŸfríqŒÊJp%x+7dˆué>*žÊÂÀ×GU´ÈÌÊIffgY[_gqi‰ååeæz½×…“¼DQDoí8Qg 5ºpC7O-eP~¯]oððê\(J)¬u7yb5Ù ¿ø%¦ý:öÚ—a4D|ØU¥p"#é¥òžDV{4AŽ?OÁódÏ€zøCŒæŽÁÉïcþmÿñÂ"ñ‘ï¦Ý[¼óƒô: ¸úã'?FùÅÿÙ<F+Xë)ñTJçHPx-Øé%äÚ%Æßx†Ýgi}÷N÷í÷Ò{ûH;uò¹˜¢Ç;h‘ ^î>g.7h·WDì×lµZܤ¯} 0ýëŒû0僦zîIÄŽ1•0±ŽÂÁ¡r g4•‰Y©µïÕâç=^A„Â>‚&M$|{T1 |fH¶ó‹ôÿü—Yý¡giý­W #_dÌÅ;Äæwr#ìäf÷1ìðfz–|¸K–i>ðßsìáÛ*¤_~„«aòÎ2kPb5$kDÄÎb¥b²ñ)6®_aõƒ?Ë]ïü—–^2ñ_œÏüØÙÂëksr3¨ý+‡Lγ±ñ+ì<óYæÞûŸÑ»÷‡YZ?õš9úbtÇ?ƒ]à U„“!îùO±qí òë?Îò{~„Þ±û_“dÎä#ü"2,°•òºš4„ŠHð8QX§(Œ0-`RE$Í”™ù %_[]cùÈ–––¾©!gqÙÎKýOH®¢ÐJ!Þ‡¸t¯áFÜ"nϾæ3ÕûIÛ«ØÁ…`¤ëDè¾>¹6ä{¥àâÁ1ƒ³6T*õM[ófç¿ÄàÓÿö܃H±¥Â!óŽÌ(2§0u±ŠØ ó‘ïÑZëp- -h$Šfg.>Iöп¦5w ½r‚ÆÂ½è#'é¾û/“´Iº½×%ŸòZáÊŒâ¹/0øøÏâÏ=Ž”Îx ãØQ‚ÉC)¾#$2%§ÆêR µ}ÊIŸòÂO‘Ϭ3ºï{éž|7œüs”g?K’åx¼ÞÒݨ¯4:JHÓ”8N^urQ¼¥Ú8Oÿ7þ;ªÓŸ 0.#IUGšÆ¡dcqªž[¬ ?G ŠX A «¹‚¦ÕT¥&‰!F_ùù>E~}Bõc?Á‘ãw333ó²×Û|_Œ Ÿ°£+˜þç0Å5üè:ÞìàË>Þ &1È›ã&-õ%ÔÜ}ÌÏÏ33;ûmᑉ£‹ŸÆ¶p.¢¨„ÊxJçТhUáà×Je!ôÏŸeÚþ$ÉÜ*:Šè½„gYäCúƒ)z¼‹UBa™ÑûÅ&IŸR»sšÝ/üä_§zßÂâ©wÒn·_Õg˜žý“‹bŒ&¯„Ü‚F‘hA›ëŒ¿öó×þ”É÷üË÷ÿÛÌÌ̼*/}zù4ÙÅoP8©B𫈦8qD€aRjò†ÓˆÒi:Ë÷2¿¸ÄòÒ ‹‹ÌÏÏÓx…h${îÏØýèO£÷ý‡PRzsã£z9ªêµðßõ·èÜýƒ4g_õ¯V™µ8+ˆ§…‰µûÇ™õ³„«ƒ‚é¹g˜»ïÝ™:΋îcR¦”•¦¨Þ+ªÂ1•ð÷Öf7ŠPiX„©é3>ýë;Ï}ï?båþ¤×ëÝò$2ÃMv¾ö«øÊa*OY EåCæ;Ò$±¦‘O)Ï}‘íþ3ä×þGÞý£,ž|à–&«ˆ08󻔣ë(§(¬'7²¯çjÖ±“P‚_Y…"+\:K{n‰ÅÅE–—0ßë1?ÿÊj„2Ë^~†n£%Ù×ÖÎ+V„ìò3Øg?Nrß±üƒ?ÅÒñS4_e[Z§4º #¦§ÕP;Qʃՠ½Py ¦&ÂÇ{Šõ’ºˆP^yœÝßýÜŧ(Ä‘B¿täV¨8¼Pݨ8ŒÕÞÂGÔCî×)!R {η¡ZAG‹­rˆšŒ(7Î1>÷Y’(E/§ù®¿ Ëï§qì½ï¸mºïÕÀô¯1øÈÿDñå߯O§d…ab„¾œ…Ì NÕ‰f¯(ö›‡ûVƒ^DB;¹™˜M<C,cr6<ËB 7ŠÜÂÐÂÄj¦6Ì·QúôQ(Q4”§C#†^*ÌjÅls©0ÅkEC+¥ÑyÉôÓç²]@þúOp÷ýÐ~‰¼YÌâryük$ÃÓtâ6 cÕ¸…äXo1ΓWŠÊ+&Ó1;ysñ3¸³‘F£I»ÝfõÛàT–éöyòKŸ?8%hBº½pÌZEQE”SOV@6v,ml°´ Ô ¹Ûü*Åx e…Ê„8’àÁIåÈ;´ƒ6 “ƤU‰Ë>Ïµí³øÑO3|Û_â艓¯HIy[Òä—©®<‹”B^zŠ*ðÕ¸·v >†–RØí]Ÿû§>ÇîwÿÖÞñ½Ì.ù¦Þëhç:ù¥¯csÂ?£ñÖÝTÖªëjZ€Ðè’ÇŒ\L{íÌ/.²¼´ÌÒò2 ·d4¦N¸œy:yFªFA$B郱T¾OÄQhšd$艳aIyýw¸zeÌÛì³vü³³³¯ø™{˜™ë‘´O¢yh¿„ß9ˆ48 QÅŠÊn“´Ù:Š^ôìLÿýOüsç?¥¢_:¦¥P"+áŽú1ìõøÚoÚxPS×f¡ë¤hmÜ¢J%˜2„(RL’†@3©g@EÞy–ó§–"îÒþ¾ÿwýÿ‚ùÕ¯»Ao©¶.°óëÿ)æÉG( ÃÔ{F¹gàA¬¢BÐ^‡gŒ`ªóŠÊ)në‰W4"¡AšÀ¤Ô´Sϼz«±Œø0n¢¨óÈ(N¸r‘ƒ¦õL¥î‘_Ý ¼³LÎ~™Á¯þ}ÊÓ×)Å0ÃN©¨D¨¼Ûß0ŠšN™Ån©Ø.…¡Q KÈ”h$ŠAºG)…Ž4Jit™Óª,ýÒ0ŸzVLxŸÅTèF‚Ñ ”ÇiH¢xèCœ÷%ò·þkNÝ}3/Xq«·B㮿ÎÓ{˜n« ‘xZƒQ 9…´QåqUØßŠiÁðêYFÇŽQι7ô\›=ÿELÿÖ+LÞ‡#¤ö!A¶Tab„²h ³’ÉdBQäYö"/³íàªå„Ê9¼=°÷&öàUXt±Xˆ5Úzüà:×?÷stw®!òw9zâä7•F›ç=õ)t6&3‚­4¥¹¹9T!Bá ±W4,Tg?G¿ÿ ÜÖßaþýÿ «Ç_–K¯v/2½ö4â¥å‚á`Löêgá` kaTÓÊaÒ ‹G˜ë±¸´Don޹^ï–žó &þ8Ùä©Ö(øñXÂ0FZS‰#ò ¥ÂxÆZc¼Ç;!+aüôŸ?öÃx£Oœ ÓéÜ’‡®µ×!·÷BT'ÍÄÕeà °5·iç@Ý‘ÖD‘~‘1ß}ìc Ÿø&™[¢Óaa~!äJffn9ÉÍŸD/ÜÅdç(ðÄHÝ1@< zpµ¯ƒ÷eLŒfsœãO?Jsý~Zí6­Vë–ïL®‘øàÅy¨7öÕy0F…#Éš]Ò´AÇè$_‹BõèQGi¦ÔL¬Ù÷šÂ&«qÂØxR­‰$ÏØ~øCô/^`ðÃ?É©wÿ KK7ËËËŒF£×¥Â¶Ú¾BÿßüŒ¿ü Îy¶§´:$üœÜT™élðdÇF±Ui¶ áZ¦éûÅ4{=¢ö:±—Fºn—±ãˆ–šŠ…š^n¢ÃL]Éé°y@ÈGXQáhÃHPˆ´n+ñJ}YD„és§|þ—+Œ‡Ì{r #!zRªÍ®—Š­RqÉ(lk†™“Gé.­0»´F»Óa~q‘ùÞ<Ýn‡ÙÙ¹ZQÇQ ™Œ±L&cÆã·±q÷;áщΤÜïòéöšÏ(BWÈ Ïré~ æÑn·i4BábÇ1íî,Gï{?—ù.Ší¯ Ð4š ë"û\DxJ4‘ Áp“l2d2™P–å-‡½wÎ9Š ŠäÛX'Ø=ÚSKÐAÑ”0áÄ€3Š<]¦Ûj“¤i]Tpc¦ØªàâWÿ€3ÏŸc:Дí:‰ÐÐ0‰ -JѨ'®:` ñ(xu­„fž0|ò“7Cä¹ë]Á ããÏ~î—1ÃmLy Eu —xmð”¢Bൠ»Èã¼ÇÆÀ¸ÐŒ7¿ÊÌèçˆÚËx`yy­5ÎäWž…¼»'IÔ{QW0D¡Dˆb&.†¸C·7O·Ó¥×›§Ó鼪H,NĽw’D¿Oä%$9©“Èõ¸í{°ûŠÇ€ Y¥QSa4‘gy–Ý’1Úª^n­ª@n$#÷šnY«pI‚Ö Íf“F£ItÀ£óÖ28ý»T“’Òz¬kÂ5ªzgñ!ÒÙ~¾/]ð^…b+×leŠm× ´áMÄpŒ”BÇ ËÑ” y³)x§PZpõÜ«¼ ÷e…²Ì˜N¦·¤-pÅ„á'ÿFüEY’9˜ä%Bé<û =… ÑÇN©p¹€ëUŒÑ •U:Ëët{ 4»³´ZM´Rز`°q¹|†­Ñ6Êyh+f#˜QR×Ïîw,Ð ±„¤h8™0ÝG¥¾yŸ#ñŽágÿ?ò+c¼ª WGW£ª)–‘UL¬" ËGé­§wd™¹++k,,.²´´Èììݙڭf“4Iö# ç² £ÑÅ^ÍvLÚîÓÃî§~3*È=áT*+N¥ÒQØ,+ž[¿€Ë%\(v+…^\`îÈQŽÝMwv–îì,‹‹‹tZí}=ºë†Ûïføø§Ù=ÿäa’ñ&Ç/Ÿa¦›K)åUp,D©Ðž •Iú0;ÙñQDÈ®>Çà·þÕõ>} Eý´T ž•àdìŠ+\Ì#†.fæØ½S÷1¿¼Êüâ"k««,,/¶ÝnÇ Þ{òƒÁ.+++7*@gçæX;vœ­~”éÕg±6#ÒŸ„‰³×Z9@d¢²óãñû(Š‚,Ëèv»wlòÜ l1atösdãº'CM¯ˆc¿Ï¼¼Q¸*¦²–¸s”´Ñ¤ÙjÒ|‰v­i’0?¿ÀÝ÷ÞCsî¹Slž{’þæ7`4!kz–¼Ç65¢<‰(ô 3®þëHb2eBãÌoPl}†hëŠÂ’åPUެ²ìý‰ª=ýHöm[PçV“Ù°X¶F1WGš]iÒ\^eîÄ;ö“^^ü>¯=™ä8ÛÆØ>±R/æãh" -aì"Bâͦ)n—v»C«Ù|ÕÅ;¾“î<ƌބb½Ä×MωÚIW5ÿi¡° ñ Úí.I­§On1ùªÄ¹"üpÀkÞ÷¸T­m7¦ð—4I’ÀoT •åÑàBXß^¡M«Ô7!Ô 3*u‹( £.O4×ˈªÓcáøÝ,¬Ÿ rÏ#+ÌÎÎíŸÎtÓøåÇžbÞ‘H‘YÞo]FUŠ8‚xú<¶,°ÖÞÑ\–¸Šáç—þ³g°¥ªQBî=Nd/vLPìäŠ %\Î4E³ÃÂñ{è­gáÈ*ëG²¾¶Îúú:½ùyi6›$qŒóžÉxÌteÊÂâ"‹óól¦ ¢G§æUö.ÄÈ-ïM¤µ¢‘m"Þ×Õ™ _WݾÊçN3)°s÷ÞÝP&Õ”œh+a%Ò´í5Ö;ÌM,³AëL \‰´ÄñØ’²£Ù£V°z·¨Šz¯°JðµŒ:GQõ Îê±j£àLDn`·¬  Cúýþ c®µfqq‘•û?ÈÅÇ?йö(eä1E]òc‚qêÆQz“y–Sä9ö[…z[à³]¢Î2èè¶BA;Ý&òS!ye#JëºèdïU]¬àPuøgãyZ6Ý™.ÝN—V»ý¢]»Õn3×ë±¶¾ŽRŠ™Ù6ÖsýÂýì>ýòÉ5¼¯PÆ9tSÁ#>°†öšîXëij…‹"üö&j°ÉDi²Ü3vBi<¶6¢{\ ŽêÌÌéÊ+ZiB»3C£Ñ ~Áᮬ¨òà‰ Š©…%xqê€%X…÷0‘@G\Íàr“5çX8õvzë'YY]çøñc¬¯­3×ëÑn·÷õáBP!•O=„Úy´.N ž¾ìõ”©iœD…|N\XâÉÖþùª"rGè–ñÕç?üQL–á,Œlè1³—¨S„g9õŠa¥¸V(.g7ÚÌžxËÇïaymõõuŽ=ÆñãÇC}ÇR ®¿ù^i–Ñlµh·[$—˜>©iTaªsä&B} œÂ’Õã(ûG¾dý2cwë1*aÅ#F¨T-íª_®ê|’hXð9§Š‚våi(¡‰Bé<4[ 47•Û!|}°´GÇá‚]" WÓ|(ó+:´ Õ,Äã%$˽Þ)Khàä“ UUá»aÌ•RÌḬ̀º~ŒÕ»¾Ÿ‹W#7¡»œŽ©ÐVRAŠ'A£ÉòŒlÔ'ÏsªW0æÞää—¾@~þaÜöóD³k$ §HŽ~€öÑ^íÜÂ9Ç艑 /Y(¬`«°é¨»7„ï ”•Âæ i/Й£Õjï'&^ ËKK4 º½^••UÖÖqåØ).}ýsì^x SLpÊ2o<ݶÖ:iÑa7õ¢útû ^ &R 29ë<…¼½1/5u­^+ƆZXŸ€KEÂõiƒí~…kw˜];ÊÒ]÷³¸t„£GqêäÉàý=º-9Õ¸pt¤nTÀ­jê!Å\âØ>q£µ¾á ݼ-=øËŒÿУݠ5¶aË£öÌ÷žOøƒš·'ŒE!à*ÅÄE•4[´ZMZÍæ-WO.>†^ ÅÕ ÏŸ§Da]HŠy2Ëz³A£Ñ¤ñÂ(ÄX\’©UG^7F$H*¹1ï<ä>$¦wr¸<‘Ò[;Áüú)Ž?ÁÉ“'9uêÔ~›n§³¿Q‰÷L[ ¿ö¯˜Ž8§È TNöóB{Ÿž3¬Œ˜\?Gžÿy‘3No;böÎaN?Êö׿N‘»š:rrcßòÁi™ŠJq©ÐT&‹÷½›Åcw±²ºÆ‰'9yòku§Í¥¥¥—”·¦i£A§Ó¡ÝjaÖš\çˆÊ]”¯“Õ(¤ý´‹NP£ÞXSkqÖîåËatþI&çwñU­ZÁY…Sr£žDõR!r­œ%P¢X…Ž=÷šÊ‡I{ÓŠÊí¥û÷’î‚«BDç” tN-ßÀˆ¢òÑ~Œ±BE0ì#cÖòª–U[{s£­¤æÎïþs?ÆÎ“ÿ/v2À h"h'û­'­RD@Š—#¦»×ɲŒéd‚éõ^¤ko1»ç>ö«”_ý$~t‘"È©"ëÞCãþ¿Êâ{ŒîÚÛh´nMJUŒ7Ø~ô7ÑSG.ŠÜ¸‹´Þ¶µÚ[¼5×TÁØÇ$iƒf­Un5›/Û78Næçç™evnŽù…… ËëõèÍ÷¸úì ¶¿öQúÓ]t(­XÑT¥w ¡ °NðU^pFö¯m¯Ÿu2nOXÛ; cnÈØÎS¶GBß ÉÜ"‹§îcny•Õõ£=zŒ“'Opüø Ž;vÓqgJy|â(§½÷ß·ŠýUQ³i4•ЌҠêEq+^žx‡l1øÂ'ÈþèçpÃÆz†9T®n’´G'Õë&U A‘»Àq‹ƒx~™4MI“à™¿šZˆ«ó>¶¦wtøÙH sò:I™6f‰kÙ ålž˜Êù`lëg¤ëë¸q0‚•ÞCaýB¸œk>aöø)Žœz;+kkœ:uŠ{µµ5Ö¥ÕjÝ´yØ|Äà+Œ¹tS÷±ÖߨtŒ_¸Qh{¹ü$Ùh—<ËïÕRM‡l<öeL¨ÄÊ ÆîÓÉá5ÿ?sodûu÷ýöþgž§ï\ @‚”(S%‘‘ÉVENdÙ¥DTQ’rùů©äA~I•)%§d—KŽ%ËNh‰¢R)A @ ÄHâb¼sÏ}úŒÿqï<ì}N7.îî¥TvUW¸èþk¯õ­o}_f*›±Œ#Aâ¨Ýyíµ3ôWW9}ê4§Nb°2 ×ëßP éúåû>íN‡ýÆ:‡n—1±ÊI…z+ä"Ž? @¦G Èå&y'ÿÏ4Nˆ£}’<_ö;´%w¶Mõ%ÄŽ¡Ka_Ž!ήcܺæÝ] ²\!¬ ©if¢LÖHÓÇJa.MjŸjeh¯ö³ 3­™+AÛnNÊJ ¿mK,W*tz«Ôîþ$ßù )9ž§Y\sÃ|ÐxÒfWÙùÑEæÖ×ñF —x÷޾ù»Ä/| 9dÙœ(5æÁ¸ Æ/‘l]b|ájúïé=ð÷(UÞY¼KkÅèùÏ‘]ú¾i¦2E– ß2j›å*HR›) …:…B‘J¥BÑõ›­…HO§Ó¡V«1(‹T«Uj?pGO–ýùŸ ×ß8RãØá3ýb>ël¡bŸÅ“ÁôÄ÷¹6T¹i.ˆSØš:ìo$™t(646ÏÑh÷èLÖ³¾¾ÎÊÊ ƒ•šÍæ[¯#"Ìra8»‹õz ^V–„RS–à¦Èfû¤ib<;oRºk«84»ô³oþ!óÇþ”dÌ(É)ÈíЖ«Í@„'Äñçü8è-ð”éƒL3AâúøÅÅB‰¢ÕйUè Þ¿Œž¾åC%JÛê)5ÐÏLúxAÁ²› K¥·”ÿ1fdjSÊ8ü Æã9“ɘ(šÅñ[ô²É.ïüñó‚˜%Œ1¶c3%1ûŒƒONQÏ>ÆìÍW™]~žæÿôWonõ–ì]bô½‡ÉGS¦¹ƒŽâ\/ù ØRHg Ó(É2å¿Þ§R1”½ÛÁ}ß§Ýn†¡ÍÖ« ^/\}ôϘd{¥ÑSÃ<Î –]¢·±ðXp”…4™h®L 8Œ;SÉ…‰Ëî\âx‚êúijýu:ƒzý>ëkkllž¢ßëÑív©ß@üªÔZ#¼ëçØ?ÿ{hr ÎÛ3åçA¢æjÊÙ>éµ'?Èx<&Š¢n€:K}÷Ϙ<ü;¤¯qµ! H©ñ‘8鯣weö4×NQè}Cñ ¡T†âh7 -޹–'¦Qå&8ÏSÁDVÏ8׌µéõ$™&±½Få»(é#¥ƒ8Ȱ€W*z>A±Œ—ª§®àú^Ú©Q? ]Õõ–ÆçÕZ•ÕÕ5Zí6FãÆÁ\JI£Ù¢sæö_ÑÉœLc2Z ¤ÐxvÒJgsò™™M-®šG†Oþ>ãÇþ=Ó8&‰5G±fœä†"–žc^ð SøŽm—“˜é‹O1Ÿÿs’OüÄ}7þ—öåÍfû>ó)˜E$‰2/hÌrÀIç¶ó #ÕfBO'š8P.Q*—(•Ê„–Åò^ºýžçÑn·ñ<Ïʪ*.îý8á…o*eqĉN¿¥Wf–=>±g3ŸóÌÈŒÉ(†I¡Iµ»Jµ»B³Ó£ÛëÑïØØØ ?Ði·éöz凞"„ vê*½û8zý|4¡¡—ÍÖ½Ëᘱ´Ødœ<%¼ô r÷%æßþ;… Yl ¤o£Çst4'Mbæ©b’kso¥VömÇd´¸V,{æsœ# Q_£\*Q,–Ã×¹5”V9i²…H™4åö‚ñ íÆ‘ff“O´/$,–—SÁÎõtÕæÅÁY&¯¼Læ‚g`YD~¬~h¨¨æþMr˜"pZ}*í.ín•ÁÚ–Åqýyh­™í¼Éä/?EvxÈ,IÌ^YôÒn`þ›PÄñÓÏ0¼ÿc Ûm*Õê{ÊŠ9ižf W,” 5Òf¯Ú2=¤„ðÁéJñ6Õƒgá…/¸IA²çÑ…îÚ*±¥¶¦$vBS%d»Ûˆ†æ|§1Y^¡D¡ÑÁ³AÙóC\ß7ä‹ €t$žëâ8Ží ¹æô|û,]— ðý€J¥B£Ù ÓnS,•nÌ…4êuºw}žx IDATŒËßþs&WŸÇuŽ«q2SÚd|¥ µf>I&ÛL§¢ùœùtÄüÉ?eø¥ß"?<$5‡‰fnyjw¹Ås/À(Jtm…P^~„­é²ü·Y½ûÔš<FÏ~“ìûß5ÝtelÏ20L…T¢Åý¸In ¯T´Â7F‡ýúöv–â-•Cöà/#Çß'ßÛÇævR“[çR[¨/pWì{*ÌÃãióÍ´Þ¦ÑÛñuNü-%ÀÇL[{Ò¨y’ÎQ”¦3ÃÑ0^ìsO"œ9fW•š“~NÚR|µ’è\iÍL ¢ÌŒ³_ßîÉ•ùÊÁ@‡Òv è=Ú5p™ëw£ó‚òé6*¬“!+2ˆXÊA »ydZp¨4»¹âTs$´# kUJýU\? ¬5)”Ê„¥2®çŽçQCý?¢êŸýØ/áM¯í#Þ? Šy|"[YÜ]Ë“–˜ €6]âD 満SlS)W(—ÍÃýnÞz·²Š…€¦ŽÑ¯þQrÈ QjA£™® ž Û9Iºô<ÁŠð´ÆP÷rš®GÔ첺¾ÁÚÚ§OŸ¦ßÐíõ–ì·&+)•ˬþÈ'¸ôä7]üžaÚxš&4\i³rq,ç:#7zö©`"%¡£q¥ÂEëPdYÊÔÒ#eÄÉÒç„O:æõÍ^¡¯k+X˜g® sC*ÕµJu)MpË}ŽYD<Ü5/¡°ÆÍ ­ òÜ0 Èt¡N!)Šoã˜T*5šþ;8_j‘^Û6¼ôÅPÁ‰à¦•¡ –4Z™›½Èö Y¤ÑžGéÄn G{»Kg)³¿þMÄ…—pS«™­ÀQ’ܘ²M²œc\uAu2߉¬K Š´£¹S_aËi4›¬­­³²ºJ¯×¿if÷N«\.Ó^?ÅÚßùy¾wõ%²yLÛ8ÌxÖуÔ#Ô˜ë™ m¨ÚJ1ÏÌ‹äHh ž“iM” 2%˜)ˆ®i:}ó¼6˜/ŽüFà$ĉ0‡Õ ~£GX,˜‘ïÛðMÓ}âÑä‚\¨¥.ËÉ¿F‡CK‡Bµ‹g_:Ï÷¹þÉŽCkó áæƒì<Œ“çù17~±aÁ$ žë.‡ø<ßGJI¹\66Iai· ÿ¾ã­Õª4û«4ø»ì}çO)fšT|ŒzÊüÏÓÔÒmv÷pöÿŠäÍ/1Ÿ)F‰f+âØj=+˜YjZª ÑÆçPe|ÇZlåIg'Ý| ¸uýÈ2ÊÆ¨Xsiƒs*;„r}“Й©T®ÑÊèFÇ„°LKZϳ²xÆä‰Ï2þ‹ß$»v7æ¼-­nÑìËm*¨…ÆUÒtÌ-N¬ìè·°/ßÂKb´œËZQÜûN|–bñAjÕíÒ¶·³Ç¡Óí±þ‘sñØùÖ_²3ÓÔ|AUA" tL–ãÂ[ßâËT˜ÍH)Ã(m…•2CŦ‚<Œµ¹7JBÃZ "OlUIS;˜Jj©j( adywy­F¡`zEK ½å•xèhFŽ&H]22L/ßdé‰/’Z0ÊAHX,ŒƒÖõS¦ŽãPo4XûðÇ9|ñ ’ñse‹G0Õ&˜Ka™@јѕ¯Þ÷€É¸®K T2#ºðGÿîŸ=õe²ÃãLp”Kf@žj;¸èÿ“mÏÑdÂE}<ܲ<E $)õâ·~i•kÝuŠ¥ívûÖ¯!F«¨sßOQzßCì=¶K ÔµC€Â•†èH+©ì˜€¾ÐP1Ã1æ¹1pæwžtò]Œ÷¥Æ‰XšQ¼Ó’Ú’ 0™¹!\©‘Z[ͽw™dÿJÝÿŽMP×÷XûÈǸüØ7™¼ùšq*¹¤bÉî*hM(%u¿Æ´Re°r<ÍZ«Õ ÕÙò,¸¿ðC±ŠÞi½c0÷üf§O÷®ŸæàÙ¿&šNš"Ø]×Át—}Øxõ?PIßdžæÄsÅLA™ä*OÍ.:‹à(Ä"WަY6iAÍbk\ŽrŒ3I2×(÷ñ„)ÝÒ Žl£ìmÅ_;À$¤‰ Í¥bŸ ©TL3èvø®×¯øòy†ÿÑ#Ÿ"›ÅŒ³ŒÉF¹@f‚ÈŠ, ›5,¾Î1æ‹÷yÁê°ü¡Ðà˜1C¼L &{Ìžÿmž&ÙØ I’Ûή«R­²²¾Á?÷_ñèÕvÏ?Áh–Ðr¡âC$¡cÞ9¿|;zÙóÈ3H…q¡” ‡©éKÌRÁAj²õ9•RÀ´¢²!¥<7¶^`†)Õ,3.†–¿G'hR)—)—ìÂí0’Ù!Ù4ÆÉ$™Õ¶Ï̲W©Lé,<‰ã‚Ð2 n”¾Oû¾¥r×OpðÏã)ˆ<…¯5ŽkÔ ÁJ1 ð… ºs„úò¿aV/3î÷©ÖjžÇøÅ'˜ý3DüñµkdqÄ Éa* CK›<DH¢T’`ïMuÇvRãŋ拖d ß‘¨("ùÎgØÔÃ_%‚wtz¿~I)iôW8ý ¿ÊÕ7/3½ü&‰Ö4IuJ%P& âzí½ÅÑ=ôDUš/h£¹ÉˆÍùÚqXêÌI¸Ì«Rá3Wjü\ ކDã)Óɘ8ŽozŽÕjÞû?Dï'ŠW/]D§)Ò1°\Q,DÓ ˆÆŠêþU¶æý•Ár^ ^¯S²L·EðnÒ»S룂Z­Æàî²µúöð(¾èT/åC=Ǹk{1†¯0ÓšïÍìt“J gšÁÎDr5öΪR§šÅŒbÖJ9®¯ñ¥UBS&0(G›¦\d²F;Pe¹ÆÕ’L(úF‹›+`阭ÌM¬$YX¥d1WߊºßîRIÄä…/1þÜ¿ =ÿ$I3O{9ı0“\J¿õáµN|Wf7Ä=Q¦kŽ3U¥52¤RST÷ÚÙßâZo“  全ð}ŸV½Êê™;¸ëþã¿„Ý—žà(M)'ÆÉ&ÚƒRê8«ÒbmŒžãÜLûELsƒWFZ¢”@ø.~½A£ÙÁ¯ÔÐ…"êò3¨ù¶Ý´ìÁ,Jf}ü‘ C-Ír‰ðŠÍ.AÁ4%OêAßÊÊ£fVW(x¹$±ÓZ “”Ä™0s…?,,Õ¯7+Y¬°P ½²F÷ýïgïé/OR\)H%8'| uŽc6 ¡¡´½Eðùÿƒ±Tì”Kžbþ½GH.^&›çäJ1Ò0É„µ4¬8“¦y¨‡Ê8Ú¨\:9‚†k¤UCG›iÔEïÈÒë´6ôIg4#ûìï³_è¸>ë§O›êãëºTk56ﻟËï—yéÓÈþî6‰ÔTAÓ¸Ž&Bâ¡qlvuòWëÅ3oaÐE€,AÜ^(}"ˆƒ êB“åby-õb,Ò.qâ«ßÃèÕx3Å|ÿ(Ž™N§ÄQô–Y˜åÿ)•j•µ}’7ŸxšÉsOãæéÂTÿ™i¤^®iˆˆÊó_#îTðZm‚•ÍV“Jå6*Ç¿ÁåüÆoüÆo¼Ó?Bf9‡[—8xóEÜ4ÆÁ8Ñ#Ì á Ã!Ṏ2ˆ½ÔÏr8Ê$G3Á«Óí©$­5ºçPA ætš˜ÌüÕ%÷YY–²šyfH÷Z-¬¶ôrØÄ±ØóÂØ Ô1IÃDr˜*äú½ 6N³º¶Æ ß§V«áÜF†›Œ÷}ëÏ8úãFzñ$QÌQ¬8HQ*™YQSúÙÆž2¥w¢a– ¦™dž˜Ñìyjä¢H¶”Öö™v”ÅÓµ9?5¼L–íÁà}”ÊÕ÷\²yAhæü¯Öbš+†ûûMÆ‘`/lGæc'6ßïE‚k3Év$¸óÚ‘r8Ò©[@—Êí•SwЖKÊ1=—TBºÔï}–…Bnt_ Eåºd•:WŸû.“É_ ƒ›k“íK3ëH#׿ƒ7ÏSxæiò­ H¿ˆN#ÜjéþíØõÝl½k0SbEÚaÿü7QG‡¸vC]Pur‹ýæZXwrƒ§æ æ™ M»3É¥‘äêÌAÕÚ´Î<@k°Ak°Sé’n]`š*œ\Ëzpå"Ç\ñÅÍט-Ìfb£ŸÐwV”`¬á0’ìMáP”7îaeÝõj·1|2ß~…ÃOý¯Ì?ÿ/H·F$‘à MÙŸ9D‰&ÎL“Jq̘ȩ6_ÛSÁÖ®Íàj$f0±ÚÏZ›òQJ›ÉÁ ¦‡°‰ŠÙ=Õµ#r‘µOZöÛ-ã„”Ëe”Ö„¥2•þ:y­Ï<,3Îrö£ #å3J4S7`"<&Òc†CR("+uüî€âêÕÕ ZwÜK÷ì=´7î ¿~Šîê:+k›¬ VXßX§¿²Š?ÛŽxýÖ`n³É…ô‚ÊÅß(“Ì gÞÇÀ6~»Î-³²,ã?ÿ׌^| ²Å¨´Áê%ºV‚;]™¯œ¡}Ç93^o™B7ƒ²Ì€Èr‘7Ÿx?J¹™:4Œ¥d€Î͹™†$8³ 9£RÉ<ešÝ,g/3>“¹ÅòçÊa˜ ö¸+^Ï4‡¸èn—Êé»ðWîDÅGxó¡ÅІ¹`†ã ÕFSφèWž&sòNŸ T¹©6ÑõÏL†hÅf*uŽâ;û‡Ì“œX›ÍG¸šb†ÀɱAZØ’ÓþÂüä3p\š*`¢$#‡™©c ±bÜÊϲF;Y‘(Û¼·îK‰Æ˜Ü÷~šÍæR™òFËó<¤ˆ°@¤}v/¾Îl21tZe6ß^_‰) y†3:Àyñ¢‡þœÉ3;ÿ£ÑJ(Dà¡òéüðd‹wZïš’ !(•J´VNѸ÷ç¹öƿ†•`þyXòÔ4•Â4ô¬n„Êa+’lE’Ë3IR¬Ðݼ‹fo…n¯O«ÙÄ‘ws¥à±ýì×9˜ P¤4”m–Ù]XJK5Ä”k‹ær&Ž›†æÌ.šhˆ#Á8…I* Õ§ÚìR.——ÚÉ·:x]zŽÃÿøÏˆ¾÷ùX1Ê"CÓS‚yž/G¸Û`3ç?ËãXp˜k®M$ûLµƒ–&”DÊ0RtMÓ3åcÙÕ¸ž9G³!˜ëj|:y´Ïôñϳݻ‡rÝøpÞN¶zòÞv»]´Ö8®ƒçztVVغv?‡Û˜Ï3’8~KR%¤DºŽklÕÂb ?ƒB±°·¯”+T*Êec/'´fþS\|êK0žLo›–¥™eB SûÂd /ðñ38q«²·` ¹ç™6«^`± ˆ2ÚÑ~jØÚ“AHšÆøJñÅòBXkó|ï1ö¿óæÃ1G©b„ &5̬DŠ Ì5£{¢íµ_°’æ^ç"±2ïë‘V …9nlߦ.5)(ûk´c,òº*/ÆDG (¤^&¹ø2“;îd2™Ðjµnx~ ¨¥ÓépçÏü GÛ—¹ð…¿`w–Ò´áž("m®ó‘4vv)ÎÔ³O“½ð q«Ji£…zÿOÓüɧ¸zÂq¡‹v à8,lM„NÑÖ¼Ù6]l—ÍaQ¢;å2Ž÷ö¬ÿ–ðÇq¨UËôÏ>Èe_&˜é7‰É‚%,ÚxË©G4óL0NÍ•©dê•h¾‡ÖÊ:½þ€;N§ƒ‚v·ÃùZƒ+O|žý« ž‡¡³aîúÂQ]hŒ<¥ZX<–úر6’¦ãÆs8È*ƒ5 E\ Åâ-CókçÙÿƒÿõôÓä å1ãT0É4©Ö'¨yVÒÁ¦3%¦°;\Ì$;‰$s| ýµÞ*ÒqI†û\#™0Îs¡&Ñ’J®ñ=m‡ a®OJ’ƒ}æõreÐÅó>jœ¿oƒ²·X…BÁ`@†øžO³m††ÃS †F:3ž¡ŽëØçÁÃ÷<×5Þ†O¡`iXa@Åò÷ÃBH©XÂq]´R„®äà‹0Ù¤8žä³Ã^¹2ŽÊ‚ëæF»\¾íí ½äVÛÓQ.™NLÿaáÍj7 ‘ ")P¹FúF‰1 ß>Æ£U©T¨V*lþÜ?bøÊ%†_ÆË˜™Ÿi<©-Í0ÐŒ#ªyŠ(Y°œ@efÒ5J°Ø¡‚­Tq-ÕìkÓªÓÜ8CsõÍnŸv§M«Ù¹ç¶£}Ôw¾A’ â\RðÔ2”ë| ø˜†¯†$Ò8é„ÑC_!~á ?þË >ñã´Þÿa*õwfº z½ Y½Î›¼ùØC¾ö:£Ñœ)¨æ‚–+ð€¢+q¥¡¾ Ì=– 8Ñ1pÊ<LÑfš}¥8PšC x.nÉÃÑŠƒYL#¬) ž ¦n‰k†:*žÒèL˜¯µÆ?J™Ÿ¿ÌèCGÌg3¢ùœð&Ï’ïûôû}¦³wþÝ_$Î".ù«Ì&S"!HT´CIæ(azd3møó¥)ºš0×èýmÜÝfßñè“lÿPì@-Äߨâµ6 ðDØ(‡P3tj7T?°Á¼LHo,®6:4ÏÝOó®2|öQ\mS…ÀU‚ô‘H(cX;N—¦‚KSÉX¨Ÿ:Ggm“•U3ørúôiÚžërttD) .?ôq¸¿ƒJ s5E{“ÚÕ¦ ‚á:‹üxcF˜ï'lOa'vÐÍ>Á´Z-šÍ¥ëlân¶æ»¹ô¿Åä±o òœY.‰3g¦©/Âí¿Ïµ©¦B0šÃÕXpaGÚz“î™{¨¶ºK†áù>Ñð€ƒ+¯3õ)®ŽfLƒœº/hçæ<}Í2è9ÂH«†Ú!ÚÝbø™O³å×pÉÊÊê{ èAÐëõŒxØá!íN‡£á(Š˜Ïgä¹qjÑ€çá)Ï3Ój…b‘Àr²C;(ø¾ ô'˜'JÇ#§zŠ|{ÏT[ËÔܬ…”¬RFÂÔÜ­¾ç"¤¸-KŽPŠ$3M euz”MòÔô*â\£70^‹áw[žç1 8zßìýü'yᯰw0¦aÉàÚ3Í@÷DD?Ù_4s©L%l)ÍåT³•k’BÒÚíÓwÓèôhµ;¬­®2XY¡Þ¨ãH‡ºëðƒk;Ì_ùŽ7ËYá`ðè܈™é f¾ ¤ifÌG®¾ö:Ó7ÿw^üÖñÀ?þÇœûÄϽE>ãú%¥¤aùÔ…Ð(KÖëu:k›\8ÿ2W^z’ñ¾Çî$a+†ÐÔç&¨×]ëä 6Q‰¬!ö‘V ¥f;ÕŒU-Rìw)´úøÅÒqóóW^`{oFš‚H%‰€²Rä–ýE®™óbèM@L¾ÿ£ áhm(ŽoÌ‚0¤ßë¡•Âñ~YlòúßekgH”+W’d’@@Á1ÞÈÍHÀ|nàR_k\;'Ž2B!û[8—!z bž{×g Ž«üI®9R‚mõ9¢Z•ÓÿÓ¯ó#½Ó4Ûíwž½~ùA`Uø‡/>I–Dhwè%½mœaæ©`o;3É®)öÖh 6ètz¬¯¯³±±ÁêÚ*½na'¥”ÇE¥)þC÷sE;07½¨ &(¬ â"©Ë,~/, ƒÕD0J%‘P^;K¹\¦ÑhZ-òÆ-±"&W/òê÷%å4ŠÜ:ÒØàʉ^“¥ƒE™`œ .Í×ØÇ§´q†úê)š½>­f‹N¯GµRÅ÷}Ò$axÇ9vÖV¹üÄ×nï3€ §1±-8f¨*Qʨþ¡ ×D/•/—pËÆ1©Ùj½'\n!KP.—ÉóœÃÃCÒ4%Ibò%ÅҼȎëâ8×1cÇ¥rÙhKù6•ÁÅrÇ Q4LašH'ñ›¯Ré(d* Ù¹ý j±2m|Ns@'fèI¤9¦'R£\—8>µBÍhbØ ¼[Ya¡@§ÝæÌG~† ;l=ôÇ,¬“ŠÙ1KÉqô’•aKWVNV æ5le&ˆï¤Q«Ð¼ón+ë4¬éÈ`eÀÚÚÝ^ŸjµÂÀgüÑŸä7^A¦žxÂfâ9æïbûZ€ÎŒ3R¢Mà9LÛBS÷r6œü ¸)® æy ‚€ÁÊŠ‘? ”ËÚÍ&½õ ¶îºŸ7_zŽù…7±Ÿ¦„RSˆ^f˜Hk?&™ à ]ÂN›Æ™;)5;”«uÊÕžgîI|æ.&|Ñ¥+€¦©­ Ñ$äŽiÀ:Âx1xB\ÝaþÆ ï}ÓÉĘ ßä> !¨7äyN–e¨Ÿý$ºRàâ—¿ÀÖù D©¢æ@C¤"”¦ #ð´ÂÁÀKÄæœ4.fª[bæH‚<ñ7onjÛ2`ª`_ ´`[ÃaàÐ=wçîegoá8¦¿sKO,æ% EVü—¾ò/‰.ÇL3( ƒö,z±2Ó{W­EÖ•ØÅm¶h:G»?àôéÓFs{u•~°ÌŽ»Ý.¾5²•R¤¯}õ!¶ΣÔ<ëÊÜb(h‘Ø-_V;u™*Á45|ö½X÷zÔÚ=šíN‡z½~ËMÃÂÆ=Äpéõ7ð•q†ó¤Æ]è¬XleÁwŸÇ‚a.ØžK.ÍG¸×6hnÜA»ß§?Xac}ƒþ O¥\Áõ<ò<çh8¤ÓíQîlpáÑ/pxþò©DùÐó öZ”úXÌ Óøu¢”ùŸg¯9 ÔìâÁ Å›nu-ôúý>iš’çFÒQØ`ý^ùíBDªÑÖUIÙŠ m´œP™ƒq"/(c,½Ø´oweZ’iË.²0F²H;rãæk“+¤—씞w{pN³Õb°yš{á9zýy_z‰TišRP¼¸>ÖNP‰¥XœK2!86&9 IDATÌ»J±›k®&0—’`Тu×}Ô:}ºý++«¬®®c‡®‘9.‹Kñ¨Sý(×}”éù-’’PÆØxT[8rñžŒlçp%QL ÿÎûٟͨÑîtÞ1˜/Vôû}ªÕ*kô]o4èu» NŸckk‹­ ¯0¼r£«Ø>8D¦ ­4Njîj¾øp‚Vææiš«§(×j´ZmÍõzÍÒ(%Óé„­rkñg\¹‚Ì 5Ò˜ÒXd¦QÒî«¶1*³œéãßdô#?ÊhsƒN·ûŽçæ8­v{©Ýï>~£Í…¿ú,ß{8Ë™- ($%@&åH‚TIg+÷¦YëŸx- o>׿ç©6’3|ii8ö5ìH˜”º÷݇ÿ3Ÿdìz ‡C*•Êís€jµJ«¿BçÞÿœ«W?E®gÆ…ÞÞ r˜æ‚Q{3ÍVìâ4ÚtÏÝOo°ÊúÚ:››æ¡ ÞsÔëu£W`¹Äq¡Â•¯šíKoç*—T‹%sŒQÃq`Ï3˜ç°=\ ²Rææ9Z½ƒ~o9¥u«únXäÌ/ü¯œýW_¤à(ŠjŽ5è°M^cf^̃TðF#Ç£tú.ê+§X;u†µõ5VWWY[[§×ëQ­Õð<,MF¦Ó^«Qkwxíé'=þùøˆ$“¬ŠÜUø˜ò-'Ç—ÒL”Å=ü—l·Nãº?ËÊêÚm „¼ÓZp®ÿ&–ãºäzn˜Ú670ÂEŽ¥|™lD $4â}æÃ«(õ*WÆë7­5Ù$a7óˆ3EšV—ZÂFgZt=*åªÍÊo=3ƒ!÷û}¢8fò_ÿ¾ûÿ.[/¾Â(N©9P‘’ÊÂE®˜i8Ê`'ËÙO5C ªR¢qæ,µ•ÓtúÚÝ.Ö5jÅŽôz½·lÖÝ^øž²õ÷ÿ!Ïÿ«ßfx4„B㧦Q¨¬ÚY¬¥éçh¸”çìHsæ^r·Àl:#‰ãwÔþ¾~-HÁú:ÕZZ­F»Óa0²²»ËÁ©M&£»ûL·¯p4ÆãÝ]²,E¥ a­_,Qnö¨6[Ôª5£ j­åjõ:ahâE'ôûŠ~ÀµÏü{Fwð´¢ä8Lµ$ŠX Ų̈j ®Ò¦ þæ%†Ï>ÉþÙ³4êûôƒw<731Ý]&1…B‘z»ÃËç¾ÂÕï|›Ñå]ŽM%Íie dçk–ÒÒ˜ ]qâÿâ×x>ü¶žzšQœRŠ fd]SBG¹‘+8È5û òÀ£¸Ú§¾q–zw…f§ÃêŠñp]]]¡×ëÓlµÞ¦í¦aW«×9õ‘²ýâ³\ûâç8ŒRòL’YCîB¦I„‰(3 »™æZ®ÙVš¤ßb°qŠB±H¡h„çnÇücy½]—F£A¥Ráh8¤Þ¨Ón·ƒüá•ñ˜Éø,ãñ˜élÆ|io6:Ï÷)ŠÔuš&mûÎ.6ˆjµJ–eLÆcÓÔá6oþÇ?‰3ªìJ2%r“™OµÀUÆ¡h"ÑhBòøãt?úÓt;êÆ»>ORJš­±´+,KÔ×Îråñ¯²ÿìKLG1#e  È jCOÆ~­ô±œÂÀÄ)FlL„ âC$Ë%êëë47ÏЬÒh¶h5›4›-ªµEKoëŽ !¨”Ë´O£}ïOpõòE<4žc³Ò vg‚ÝF²@ëÔ]4ôm ßØØ ÓéÒx¼ZA¹Raee!¥iD‰_çüþˆÃ7^ÄQÊè­¸oKÇ\›‹4ÏûsÉ~®ÐÕ6;h·Ú¶4íÑl6o«„öƒ€J­Á©ý{[»¼øŸb::¢íirWHMèÝña&¸2Uì qÛ-šgî¢kËãÓgN³¶¾Áúú:Õjõm™ßbÂŒk`}I_kvxã Äö¥+Dh-¨K#Â5°‹+$>õÊ |ù‹TšmŠ…n÷‡² û›^RJ”‘d©ñdM fšK æ:‹Ï&‹Lí ¿ó³ý]ò,#{ë¯ëW¡P z÷ì¸uÌÜÎiTðŠÚh{H E_Ç+ßK¶s«Ëu]:í6I“~àƒ8…ÏÔ[\úÖ7Ø?š"3[´0ås $BRèÖiž:C¥·F³Ó¥Õî0 ,¬²B·Û¥×ëÝ”a³èwt{}ÎýýÈîÖ6{}‹™VTµ š ¦–ºikÅv¦¹ 5I9¤uæÍÁ:F“F£¹”Mx/KX¨v§CµV#Ë2ö÷™÷çŒ'&ã1óùŒùÉëß}œƒó¯²Ÿ*öfóÖæ³£pÜB`÷ &€OmŸô¢R=µAmm“rÓÀMf“ÍMƒÝnw¹!Áms0ÙN¥Ý£÷àGÙyúa&»$¹6.Ç‚«3ÁžÒ8s7í3&€ml°qʸ/°Øw[•ji <Ï£\,òý¯ü GO=A’*tÁH¬–$¸®1˜+ÈwRÅ$¨Ñ¸ã~š.ƒµuVWW—Ž·»šÍ&³Á€sû$¹Šyñ‹ŸãÊî.ÅTP_À(× Åe-ð«4ÏÜMwuƒMΜ9éÓgX__W>xµV£T.íé04Î:ͯ|áÓŒ^}ù,¡ãCË—"(û9:WÍ!ûÚg¸„„¿òß. ºÿÿ´2jŒ’Ó,c–—˜©Ðx‰ 8J,õŒO"W)=ÿ÷¼þ``•÷n­ê8óÁóK¿õ/ùþkoráÒ%v·ÉóœùhŸèèˆèp©¸¾Á{†•<ßgeuÕN Üb‘Î=òý'¾Åð•óÎæ$‘‘—ò¿àÓ>}Žr£M¹V§ÓîÐéöè÷û¬¬®ÒétèÝÄðmÛóè†ô_þw<:ž²ÿ³ì'9ž€²4çPiöµf, -…´x€Îæt»]6OmÒëõ¿ hÍ·¦ Åb¥ãñØ8&M§$Ëæz¾l°;VI°n‡znÖ \4'5S‹_ûu¾1Ÿ°ýØ“ “Okc2¡M\I M.4nÁ¥Ý*piï›û´Ûxìüä V×Ö(–JT«šÍÍfƒÞïãÚëçyý©']½Âþþ!NnÄ}Œ¶Ï±ðBm,!ÁøƒFžƒ[ ñŠEÚ”Ú*õõf“f«M»Õ¦ßïÓï›*­Ûí¾¥?öž:YµZιû Oˆ½½‡˜å° ®Ì5#7 º~–ÎÆYzýVVV8uê”q¹‹r¬ „i¼)Çá%“çŸf{–Ðð ÷¡>Û?ŠÚÁïhôt:]úýÝ^÷=IÆ‚ÁÍÚ³Ù õ?OVìòòÿ„íK¯áF9Y¦™ ÁH d½Amã:«¬¯o°±¹ÉÚÆƒÁà–ÕþÇ¡Ýj!8ÎD*žËùï~…k}“­á˜4ƒª+HS—¢Vx¹ñœÅsö¾ñÄ©3Fc9þÖTÚÞË:ØßáJš²;3:$±Å’3m4x " Õ¸®ijÉ,"úÞS´?ücL7OEÑM­ñ®_õÞ€ÁÙ9‰â‹LVVÉÓ„(IÈòœx>exí_Òh6Ccø^Õ4}ß§?XVC©T¤Þê°ý«ìín3:<$ËRÂRÏs Š%ªµFÃ<§Ö´¢Õ2YØ­ž'˜÷¥×ë1¿ûnâÿæ×xê¯ÿœ«O=ÉîpŒJ”iº‰ïà5*´ÏÜIïÌ]ô« V Úëönåü°KJI­VCkM£Ù\ªšÌŵUšgé­®±¾a(ˆÝn—¾L¹%„ T.Óëõ mQJ¤üž+Ö=ñUâyFž:=Ó²¦‚m¢P¤±všz³ÍÊ`@¿? Ùl½'QþÅq”ËeVWWŽ‹ãûœÿÎ×yíù§‰GS²yЬWèÜû ÝõMúƒNŸ>eôDz=jÕêm½ Ò6^ Å…7 Ä/W(¶VøÁç?Er8c’(¢@à!ðDÂÈÐN¯ŒÿÙ§éÜóa±Èú-Š)ý±D»„>{ëÛD3²41Œ×Û)Z…íƒT*E"bv_zŽáýï¿­ W,i¶Zh­) Ìgs²,#Ï3Ò$%IÒs÷ „ ÕnS*WðߣàbA@¯¿Pç¬P«Õéöz2H’¥4…‚1Á¨VM0øÛ;ó(¹ÊóÌÿêÞªºµÞêÚ»«»ºµ¢] ˆUll³:Ç;˜™Ø!>&ÎÉ69v2'Of’Øc;°±lv,L@‹´€öÖÖ­nõZ]ûr×ùã.nÚ ˆN?çôés¤ê»|·îû½Ëó>o*•"‘L’L&OJ›{#‚@2•²1èèR€¶9KؽmÇ¡¶šˆ’D2?ƒh:K¢½‹l{;]Ìž=›lÖ2äïfjÎãym¯À;‰Ü^g'­eg!úü´Ò ¯š–fâDˆÇSøÃa‚±6äd†`8L"‘"•J¿£(LK ¶òùÑ(ñxœd2E®+ÏØ¬¹‹ÆGG¨•&hV«´ LÃjè2tÑçÅãõâÄ‚„å@À&hX^¿C¥N$¬ßñ¸5Ôüõ¾Ÿo˘‹¢H["IûYç ¤3 í?FU Ï›KvÎÒÙvzzf¸4Äîžž·lÈ'#ºfQ‰Fc싵ÓûÜjú‹Â6—¶ uáÅ‹Id;hoo·f-¦Ó§%ÝkkC°¯AE™v²‹Î¡wï«”GOëÈ“ÌæhÏå˜5s&ÝÝ=är9Ò©Ô[¨0‘H„|w·ËûÈ2R,á O0¼ûUFëMË£õØSÁMkº· 3:6F"“¥žH¼#©ßÓ‰}æ+$.:¬Þ^Ž=L¹\Ai5+gm†:Ûð`ÈÊçΜáÐ4í ?^¯—\.gy8‰„eätݦ\j(-…–ÍރĉS¢ä½|>étš`0H¬­d2IµV£åŒ/3L|>¯Õ<[´¾xœX,öŽŒ© $“IUÅDå(Éîn†‡‡)•JhºŽW‰D"´%twåéì²¼òŽ\îm•{¯àñxˆÇãnzKŠÊt/9›Baœz½Žnš% )D–­"j<'›µæè¾SÖ—Ïç#n?·J¥Âøø8åR‰r©ÄD±Hµ\¢Z®Pm6i4›hšŠ¦ªèšfÙ4ŸŸ×O8& ‡‰ÅÚh‹ÅˆD£.1"‹½i“ãÛ# cy<©lŽEWÜHÕ»†TÇ"ñÑhŒŽ‹OÞ•Ï“ïî~G†|òù:;;Ý1J¢èE#üåà   ¨¶Ün*M¢#o‘¬i<©Tê´}I#‘]]VH •e²¹¥RÃБ£2Ùövºò–òÞTÖÊÛA  “Éà³+é’ä'OЛÛÄ‘­O31Ò¢®i€€7$9oò³iªõzým…’ï¢Ñ(étšV«‰ ŠÔë5TEÅÄDðXUL5–>{ßmv÷«ãñkšææˆß”†ó®d³Yd{æg:¦Ñ¨£©x,ÊoÄN ¼‘$ì @€l6k œ ‡©”+¨ªŠaèøü¡ % …ˆÙý§«b2¼^/mñ8‘hÔJwÙTÊF³‰¡[šõº¦¹‚ àõùÁ¶'²;ÿó-Ÿû\x$%ÓÞŽéñ,Œ£j1Y&‘LÑÝÝý–Š7§ QÉd2xí‰Õ‘¨L"×Í®ô“ŒÞoéQç¬îÒT2Eò¤8NG J–e2™,µjEU‘$‰x>Îã_½•r±HêœsPUõ¤âg§Ó4Ùò“óã[þ˜¶30Ã"³f»ç~/yqhˆ?½ú*ž>áT î{¼úÌ3|í¦?äЫ¯2ùrLÛ37 ƒ»ÿñxæÑG8kÅ ~~Ûwؽ{7úðeVkü¤µ2M“M«Wóç_ú7üÑ¡(Šëå¿Ýw¼46ÆßÜr r2Iº½ÝõøO—Í8-—É!Å4B¡¹‘h”t­†¦ëw=:x?Àãñé1M“f³i¥"Þgžø»'Mâ„þNÈÿz/ÆØ¶­lù“?&}ãï¼ö:ÊŠ‚Þh ´Z(¿x”þïzWÙsÏC,—1 ƒññqêÇ[:#¶¬Û…ä±±1&ŽG`xd˜b0èv6;é5‡?=::J1B–eLÓti‡¯g'§yt]ç‚¿ý;Êå2år™R©äž¯.Ë$m…Lç¾­±AµZ¥¿¿ßÕŸ|ž72 “µX&§P ÃàØ–-¤ººXtË—™˜˜àèÑ£är9÷½Ÿ¼þSSUSSÎÏ©¤Ö¦>ë©ÇnëîfƬYìxæ—„ìÎê¶XŒg~ˆ³V¬àèÞ½lüå/Y|É%tuuòûéݶܬYTM“kÿô«ø|>FFFˆF£®çí<;UU@Eâvt\ƒ?õ¾&_óÔ5`õš5œ»r%CCV‡²|¼ÉÏç­ù÷ÆŸfH’5Æéît¾Üÿ™àD*¿é0 ƒâ+¯pøÞS>|Ó0ˆŸé+®$ÚÓãr‡E»{XkµØÿÝÛÌ_€÷Ê1T,Òh4¬4$!\{­ƒ”††ñŒŒ*•\ àÒк®[l»‹ P( Jĉ FGFýV伜Ž!4M“‘Ý»©Þû„J…ÎË/gæu×#çrH’Ä«ßù6Ùó–“>ï<A@«Õ8ðÓ{Iu6ñeË8òäZ ýýD/¼ˆFÃ꣎ 7›ŒnÚÈÀSOâr¾ UiQ.—éïï'‹a ìܰž‘;ðC̾ê*º/YA0¡9:Jï“ki›1“—Wý¹³“ nýSv.Ýëõ²ùGwrlûËÔÊe6ß~þeg‘ÌçiìÝËË{÷P!·x)‹®ºŠìüùøý~ŽoÝÊØáCè¦É«O>É™×^ÇÂÜV¤ô1~è;žxœ3¯½¹½ðâÏF bÉ'®BE&úúxñÁÈ/\Dïö—9çêkÈžq^¯—C›7sð¥—XtùåœqÁlÝ´‰+‹F£AmlŒ#{ö°üêkÐ…=ë×Éç­ÉQÀ+;vð¥Oý.Çûû9òâ‹#Îú­ßÂçóqlï^^xl5‡wïfÁ¹çѲ׻¯¯¿ßO£\fÝ}÷±gëV"±ùßáÀŽ,[±‚¹K– Š"}ðÔý÷Ó»g‰L†Ë¯¿ž…眃®ªüøöÛiµZ¬½ï>jÅ"K—/§V(ðÒ¿ÿ;G{{éÈçYyÝu,:ûlëz%ÉÍ÷Ÿ Þqšåý‚É©Ž÷CQfï&^}•õŸ¾Z¡€0s&õf“ÝIep–.ÃÄŠc^ëïgÿwoÃwîyTóÝT«U‚Á KYÈ2âyË1/w¢@uã´ iÊ1‹'³äWëƒûñ=˜—\JÝçÃG]÷,ú%+hù-®p[[›kÌ'àÈÏVQß¿ª×‹âó1úè#”Ž÷h†ÇÃsŸý}¼©Á ­Qlccni`€ýÂMdfÏ!ÚÕÅÄñãüèϾÊ^`ÁWÒR^¼ï>Vßq;g\| ýàûôîØNnñ*ããüßÏýår™y—]F¹XäÀæÍ´Ï_€7däða6>üÿÞ ìÙ´‰ü9ç‰DÙ¿ŸmÏ>Ë…ŸúÕj•ç|€Áƒœyé¥hõ:߸ù Ù·Ÿ™ ²uÃFž_·ŽjµÊ‚‹.¢Õhðì}÷±zÕ*ò3gÒlµ¸çöÛY»f ™ž²]]ìÚ´‰¯ßr £ÃÃtΚÅýûùé]wÑÙÑðÐ]wqt`SU‘ÂaTEáÿ}ã 2wÞ<¶nÛÆÝwß͇Î:‹€]ƒ|+ißÏ|ÿ9`š&ã;¶#uåÉ}ó)PŠE0a|Ëfê/½Dç’%n ¢1>†RœÀ“ˆS«Õ,IÓtšPß1(A×ñÖëc1¤E‹1íˆÎ ³ˆÛéUUñÚiMÓ0mÝ÷ÉŸ5MKÙÒX¸˜ÂòóñI±|žá5ÁòådÎ;Ý0(–Jô÷÷‰DðÛ]‚•r…jÕª¦R*•hÖj˜€ª©hõ:…‡ {ñ%tßt3•ZF:ÃÀ·[½…åõÏ!àá̯ý-ªß¿R¡%Çxùß~ˆ8b¥‚ª(t,?ŸôÕ× ë:'††,ÕJÛ‹þðqìÐÓSIDATÿø ##ìÛ¸ÿµ×S/—_»–ü…²èó7¡‘åç³ùï¿É†ïßñi]k³Éâ?ƒÐÞŽ  Yù±Å‹9±cåáaölÛF8góÓO’œ3±½ >óYüÛ¯ŒÅ©—KT –ßøÆJ%¢ííŠÂX_Ñl–Þž§½³O(D[W>A 18H=ŸgÛ3Ï0óŒ3ÐígV¤W«ÕØöÄã4ªUþÛÿü¡l–\È}ßú'††Ål6Ùøä“|ú¦›X²r¥ÕŸàõ²úþû`ß¾}Üõ­o‘éìä ý×”«U^z)þÛ¿qçw¿Ëÿ«¿â†/|­»w³dŠ䎶íØÁàð0ßøò—‰ærÌ<ë,ž~è!z{{ ´µaš¦5ãaRêîd˜6æÓøÀÀ4Mr×]°pG^|‘#4óu ºª188ˆiÓB¼´i‚@Ó¦æYíõ1Ê›7SÞµUU©<€tö‡ð-XhuŸN¡/NÎešLÊO2ÚoHwóû–-C3 DÃ@Xv&Ú#3¶};­Ž àT,¡?N2™$¦i5ø P«ÕP[ …ñqT;g®ª*æñã(ccxÏ<›ÃôZ-<íøRiºN«X¤uø!ÉÏî;hÑát­\¦U­räÅ'’ Šh²ÌÀÀ€ÚOŽpÐas(µ‘ab‹—2Z(`†¥Gsæ™yî9˜(A)IÁAdY&‹½¦¸xεױö‡?`Öõ‡Ù¿î9:,¤®©¼üØj’K—qì•W¸è÷?ËðØžl–¥û|<.úü2R¯# "§RÄRiŠÇ£,]ÊöõëYöÑ•4 b„Òi }}ÔæÍãHïAòó Ú…RAP5ñ‘ömÛF²»M’Â0 f/\Èþ}ûPU•â‘#”+:–,ahhMÓ˜¹p!áH„B¡À;9ÔÛËì9s¸çŸþÉ]ïâè('Nœ`ß΄ƒA‹gnw!·§ÓDC!þ×׿Β¥KÉôôpîŠøe™R©D[[ªMw>Lói| PÚ³›=·~…ÚÈ0ša@<Ž b´¬\±T(P­VQÅrLâk‹S;z sáb—¦6ëO¾L³VcllŒ£v+Z‘‘¤jÕ*>ªê¯fCQì9_–÷>µ„÷zE= „B}~b±Ùކ¼^Ìfƒ²]l­7ê(Å¢Õ hSèZŠB³RAQ ]§R­bÚ9\Ã00šMjš†§V³Fòµ·3¢û­yŽº®Ñ¨*´ÐuÝ ÙE‘à‚Ô ­TÂ0 Í&‚¢¸´âXÌJ/y½^wv« ȲŒ'¤ ih‚€Ùl …H&“”“IZÍ&õzz­†išT«U<¥“Hµ™W=g îÚÅÀ+¯Ðqî¹è…}ûöQ×uj¥Þ\'år¿ßOvÎ\k°· P•$Œ'èèè ³èâ‹xuýzjË–¡+ ±\EQˆÆãÌ]¼˜¾}ûÈÍ›Gu|œLw·UÙé Ã0¨U«4j5„PˆR¥@<'ck1ƒAÆÅZïf‡ÃÒiD;§]-—Ñ4R¡€iw;ÅÒùóæÑRU°k(^ŸH$B*•âæ[oåùµkÙòÊ+¨[¶ˆDøô7’´›ë&sûß ÓÆ|ï9´V¯tjý{ÿþ›¨õ:‘[¿Ê¸ Þjá]ý <Û_¶P7,h¿l–øòó)?ò0æ¥ưç: á°ÕÚlbŠ¢012B̰gg a,\äzQº®3öÒ‹–gžJaÚÞƒ7bºŽ¿Z%’ï&‘H† o:CÓîTU½ÕBUUT]G©Vñë:š¢`˜Ö}hšfM ÇNßD­6ôæðR*E8FÖuh6­áÑ(5Ÿ1™ÄøÈG-–W$BÈçCoµ0$ }hÈ*|¶qèÅ@ÀR*5 DApeÌX )F™(êì$“N§é-‘S)ÔI) §Žà4Òùý~ àsÁbíí ìÜÁÄð9†$ziíØÎX¹L²+OU× ©*Ñ`]¿x”@ @£Ù¤ÿùçéZ±Q´d æ]xë￟Áýû$ O$‚¦iÄb1ξâJ^X³†®¾>jþtEQˆÙM}¦¦ax<ˆá0R‰F¥B4n©Xªõ:&–$C0™`üèQ3f‰D(£¶ZVJ*Ä#ŠäçÍ£ûÌ31 ƒh4ŠÐ ÁïÇ(—‹°‡­ï^µÊ _ü"ç8@_o/O=ó O>ñg,ZD#“qJ§ÂGÿÏEù˜ÆûÎT©7ƒa¨å2„ÃÔêÕ*ÆžÝø·lžt¬×ÒA ësŸÇ !þè‡4wí¤<:J­R¡ÞÛKéî»Ð÷ïLjÊVhœJá™1qíãðÂóÔz{ß»—ƒwÝIïmßAºèb;!ŠÖl¤“¾dŠB멵x*<­#?½1CšcñÚ=‘Æþ}èå2B_ü‚V¡`vûEvï_EYÆ?ggžÆÇTŸXCùØ1뾃AK—ÒܱýÀ~k"–®S{ò Æ¿ó¯Dup8ŒÇ.²9RËÎী쨕:œ£ííÈsæpìé§Q8¾n{Ÿ}–ž‹/~Í­‹¢ˆ$IƒA€{\Q‰wt0{Ù™ô=¿ o$‚*Šx²Y”J•±þ>üÝÝTªUtEaÏCRž˜à²¯ÜÊœË.gdÛVGZ:M>3g’îêâåÇV“éî¡n×9¢Ñ(ù¹séÈåØþø2Ù,U{£®W-ˆ"s/aäèQ޽ü2¦a0tà¿|üqÀ¢ fº»9cÞ<Ö?ò…#G=tˆû3Š…xÃa,XÀæuë( âEôz5«VñØ=÷ôZÙ‚ÇšÝë÷û9rø0ÿòÏÿÌÞIutŸ39Dôx˜(™˜˜°êöý¼¦=ói¼çðNMÑÑ4Mr7ÜÀÞüÔ¿ù+ÂS’З,Ásø’¡ÿ[E"]]Ìøßÿ‡cßþZ÷ÜMÿOîaÈçÃPUt€ïÓ7Ò8cž+dýÌg©ßùCXý(ÍÇã°×kyâ3gá¹êZ­–e Âa게O’0&±ã.ø|øR)LŸãûwPÀŠÝvãgP’I|­þ•WP_û8Ú·ÿ…±¨L »›@OŠi ) ¿1Bôz1}>ÄH¯ß’DèSŸ¦tÿ}LÜñ]Ê~Y&:{6º €®:÷<Äâ•õëÐ6mdÂãÁçõ’ÿÝOÍçÑ"Qü¶îCéœÊžð‡B¢Qkmc1~öxå¶o³ïûwp DÐ4Ú—-£ý×QQUüÁ Û w(ŽÎæàl>Ÿeû8/<úÁl;¦$á I÷ôP81ˆÜ݃iš÷íãàK/rù|9Ÿ'­idz2¾sÍ . Ùl’H$èœ?Ÿ¾ƒi›=MÓÜH#™H°ô²ËxjÕ*=3PQ­²ŒnÓTóË–qÎÐÛŸýw¶¬[GX’˜9cõrEQð‡Ã\|Í5<ûÐC¬½÷^kðK2I(¤ÑhÐjµ8û#¡Ñj±aõj4¯Á4‰†B\÷¹Ï‘ÈfñÙl–_Üwñá•+9ÿ‚ øéªU¨<€hš¿újtpõžNu«Ç|+ìýiLã=„ªªÆÆèݰž#6Pi41ººb1Ôþ>šQ™D>Ï¢E‹˜5k‰DAh6›ŒŒŒpìðaF_~e`Ñ^YFÈwÓ©Õjx½^:::,°‰ NlÚH}xiâËf0»ò´ìâ`&“!¢>D9ž@:;;™1c‰DÂâJrpãŽTkŒlÛ ÍÑ3ÎÀ×Ù‰n–ªa8L£·—ÂhÁ¡9s1FG¨{} ËDI0R)LUE‚\Ó糸ï¥{v£* ¡Ùsh‹Tl ìH @yÿ>ÊCC˜rÏ ¤\¯ÏGÈëEÁe<¡íííÌœ9“t:ívq«ªÊÑ;èëí¥dç»#‘ÑQúwí¤Z*M¥‰Î˜fo¢~EA/—ñuu …èéé¡§§ç5ãEathˆÍ?Îñb‘ªíIGL“êø85¿×K\’óç3::J¹\¦11V,’˜1ƒYóçÓÞÞNyx˜½Û¶Q  §§‡yóæ‘L&Ÿ±±1Ñ4ŽŽWµµÙlrüøqúûûi6›d³Y:;; ít†Çãq×bbb‚jµê¦º<‰ ~ðµ¯ñ‰ßþmæ®XañÔ~˜½¯¼Â%×]G²»›Y³f‘ËåÐuÝ¥g:õç:%I¢\.366æ ¡y<Êå²›Rqjôôô¸Zæo–3ŸN³LãA$‰¤=9(ÓjµÜæ ¯—ŒÇã.ÅÎÉm;/£cã0^œ—-d·Û;/ŽªªÖÔûXÌý¬ ®TD<' ¡ë:’$¡Û9h§ÕÛ1ü±XŒîîndY¦Õj¹úŽk(r)“¥RÉ’öXsoù™ŽÜ¢$àÞc"‘°<ÖFÃÕ ØSŽÂá0ªª’H$\åsGGÉÉÉ:9óÉœfg͉„ë­;†ÅÑcªÙycgmuB'¥‡M¯ÉYËd2én|N~]Ó4wĤ£ìèpþü¾¦i(Š‚Ïç#»éœp8ìeYF’$DQ¤½½ÝÝÿs6VçzãÆãq*•ŠÛÎïõzñ Õ›ofõªU¬yì1tà  rÉ'>AzÆ d[^!“É IÕj•FÚjå÷û‰D"î&)Ë2²,cØÑ™ 4 k˜†®ãóùܵD"øNqòÕ´g> Ã@Ó47Oéx¬NaÍ1‚N³ÅT­EQPÅõb÷¥vŠteÍùœsÇÈ:ÚòND Ú4Fç8Îykm6›®ì©ãy;çsèιt]w7 gƒrï¦óŒÙNÑøT0m̧ñƒÃX™JÙ:™ØÖýíÔ¿›lpœÏMóš\Ì{=]ô©ç›Ì°y#Q°×;Ïs2œkx½ã;çx³óŸìú§Þ‡ó¹Ék9y£™zÌS=îTêÝÔs½Þ=Oý·ÉÇ›ú˜,|5Uðk깜{rRk`mLõz'N000`Ͱ£ÂP(DGG¤ìü¸s縓¿[¯'Â5uÞŽ4É´1ŸÆ4¦17Ý”Ëe …‚=˜ÛJ#9MQŽ.Ï{¥ ;m̧1iLã09]å¤Þœ”Õä”È{%ô7m̧1iLãñz)¾×Kѽ˜6æÓ˜Æ4¦ñ€ÿÚäp1‰X³.IEND®B`‚wxglade-0.6.8.orig/icons/grid.xpm0000644000175000017500000000127611621715605017115 0ustar georgeskgeorgesk/* XPM */ static char * C:\devel\wxGlade\icons\grid_xpm[] = { "21 21 5 1", " c None", ". c #000000", "+ c #6C77B5", "@ c #C9C7C7", "# c #FFFFFF", ".....................", ".++++@++++@++++@++++.", ".++++@++++@++++@++++.", ".@@@@@@@@@@@@@@@@@@@.", ".++++@####@####@####.", ".++++@####@####@####.", ".@@@@@@@@@@@@@@@@@@@.", ".++++@####@####@####.", ".++++@####@####@####.", ".@@@@@@@@@@@@@@@@@@@.", ".++++@####@####@####.", ".++++@####@####@####.", ".@@@@@@@@@@@@@@@@@@@.", ".++++@####@####@####.", ".++++@####@####@####.", ".@@@@@@@@@@@@@@@@@@@.", ".++++@####@####@####.", ".++++@####@####@####.", ".@@@@@@@@@@@@@@@@@@@.", ".++++@####@####@####.", "....................."}; wxglade-0.6.8.orig/icons/splitter_window.xpm0000644000175000017500000000177611621715605021432 0ustar georgeskgeorgesk/* XPM */ static char * splitter_window_xpm[] = { "21 21 29 1", " c None", ". c #FFFFFF", "+ c #000000", "@ c #FEFEFE", "# c #FBFBFB", "$ c #FCFCFC", "% c #0D0D0D", "& c #D6D6D6", "* c #7A7A7A", "= c #7C7C7C", "- c #D7D7D7", "; c #D5D5D5", "> c #020202", ", c #7D7D7D", "' c #DADADA", ") c #D3D3D3", "! c #7E7E7E", "~ c #161616", "{ c #F2F2F2", "] c #D9D9D9", "^ c #787878", "/ c #797979", "( c #D8D8D8", "_ c #F8F8F8", ": c #121212", "< c #050505", "[ c #111111", "} c #090909", "| c #080808", "..........+......@#$%", "$&&&&&&&&*+.&&&&&&&*+", "@&&&&&&&&=+@-;-&--&*>", "@&&&&&&&&=+@-;-&--&*>", "@&&&&&&&&=+@-;-&--&*>", "@&&&&&&&&=+@-;-&--&*>", "@&&&&&&&&=+@-;-&--&*>", "@&&&&&&&&=+@-;-&--&*>", "@&&&&&&&&=+@-;-&--&*>", "@&&&&&&&&=+@-;&&--&*>", "@&&&&&&&-,+.&&&&'-&*>", "@&&&&&&&)!~{&&&&&-&*>", "@&&&&&&=====&&&&&-&*>", "@&&&&&&=...==&&&;-&*>", "@&&&&&&=$..==&'&&-&*>", "@&&&&&&=...==&;&&-&*>", "@&&&&&&======&&&&-&*>", "@]&&&&&&^====&&&&&&*>", ".&&&&&&&&/>.&&&&&&(*+", ".=========+_========:", "++++++++++<+[++}|%++>"}; wxglade-0.6.8.orig/icons/button.xpm0000644000175000017500000000121411621715605017473 0ustar georgeskgeorgesk/* XPM */ static char * button_xpm[] = { "21 21 5 1", " c None", ". c #FFFFFF", "+ c #000000", "@ c #D6D6D6", "# c #7B7B7B", " ", " ", " ", " ..................+ ", " .@@@@@@@@@@@@@@@@#+ ", " .@@@@@@@@@@@@@@@@#+ ", " .@@@@@@@@@@@@@@@@#+ ", " .@@@@++@@+@@+@@@@#+ ", " .@@@+@@+@+@+@@@@@#+ ", " .@@@+@@+@++@@@@@@#+ ", " .@@@+@@+@+@+@@@@@#+ ", " .@@@+@@+@+@@+@@@@#+ ", " .@@@@++@@+@@+@@@@#+ ", " .@@@@@@@@@@@@@@@@#+ ", " .@@@@@@@@@@@@@@@@#+ ", " .@@@@@@@@@@@@@@@@#+ ", " .#################+ ", " +++++++++++++++++++ ", " ", " ", " "}; wxglade-0.6.8.orig/icons/static_text.xpm0000644000175000017500000000137311621715605020521 0ustar georgeskgeorgesk/* XPM */ static char * static_text_xpm[] = { "21 21 12 1", " c None", ". c #040603", "+ c #010002", "@ c #040005", "# c #0A050C", "$ c #060005", "% c #000000", "& c #020202", "* c #0E0E0E", "= c #030303", "- c #010101", "; c #050505", " ", " ", " ", " . ", " .+. ", " .@# ", " $.@.. ", " ..... ", " .%%... ", " %. &... ", " .* &%%.= ", " %. ..... ", " .........- ", " ..=........ ", " .. ...%. ", " ... ..... ", " %..% %..... ", " ;=.%% ....... ", " ", " ", " "}; wxglade-0.6.8.orig/icons/panel.xpm0000644000175000017500000000213511621715605017262 0ustar georgeskgeorgesk/* XPM */ static char * panel_xpm[] = { "21 21 36 1", " c None", ". c #FFFFFF", "+ c #FBFBFB", "@ c #F8F8F8", "# c #000000", "$ c #F5F5F5", "% c #D7D7D7", "& c #D1D1D1", "* c #777777", "= c #0C0C0C", "- c #FDFDFD", "; c #D2D2D2", "> c #CECECE", ", c #181818", "' c #D6D6D6", ") c #D8D8D8", "! c #FCFCFC", "~ c #DBDBDB", "{ c #D0D0D0", "] c #0B0B0B", "^ c #090909", "/ c #DADADA", "( c #080808", "_ c #191919", ": c #D9D9D9", "< c #D4D4D4", "[ c #0A0A0A", "} c #F1F1F1", "| c #F3F3F3", "1 c #D5D5D5", "2 c #0D0D0D", "3 c #0F0F0F", "4 c #060606", "5 c #020202", "6 c #101010", "7 c #040404", ".+........@.........#", "$%%%%%%%%%%%%%%%%%&*=", "-%%%%%%%%%%%%%%%%%;*#", ".%%%%%%%%%%%%%%%%%>*,", ".%'%%%%%%%%%%%%%%);*#", "!%)%%%%%%%%%%%%%%~{*]", ".%%%%%%%%%%%%%)%%~%*^", "-%'%%%%%%%%%%%%%%%/*#", "+%%%%%%%%%%%%%%%%'&*#", ".%%%%%%%%%%%%%%%%%%*(", ".%%%%%%%%%%%%%%%%%%*#", "+%%%%%%%%%%%%%%%%%{*_", ".%%%%%%%%%%:%%%%%%<*#", "@%%%%%%%%%%%%%%%%%'*[", ".%%%%%%%%%%%%%%%%%'*#", "}%%%%%%%%%%%%%%%%%~*#", ".%%%%%%%%%%%%%%%%%~*#", ".%%%%%%%%%%%%%%%%%%*#", "|%%%%%%%%%%%%%%%1%%*2", ".*******************3", "##[^#45#6#4###5#7#4=#"}; wxglade-0.6.8.orig/icons/list_ctrl.xpm0000644000175000017500000000120011621715605020152 0ustar georgeskgeorgesk/* XPM */ static char * list_ctrl_xpm[] = { "21 21 4 1", " c None", ". c #000000", "+ c #DEDEDE", "@ c #FFFFFF", ".....................", ".++++++++++.++++++++.", ".++++++++++.++++++++.", ".++++++++++.++++++++.", ".....................", ".@@@@@@@@@@@@@@@@@@@.", ".@.........@.......@.", ".@@@@@@@@@@@@@@@@@@@.", ".@.........@.......@.", ".@@@@@@@@@@@@@@@@@@@.", ".@.........@.......@.", ".@@@@@@@@@@@@@@@@@@@.", ".@.........@.......@.", ".@@@@@@@@@@@@@@@@@@@.", ".@.........@.......@.", ".@@@@@@@@@@@@@@@@@@@.", ".@.........@.......@.", ".@@@@@@@@@@@@@@@@@@@.", ".@.........@.......@.", ".@@@@@@@@@@@@@@@@@@@.", "....................."}; wxglade-0.6.8.orig/icons/statusbar.xpm0000644000175000017500000000302411621715605020171 0ustar georgeskgeorgesk/* XPM */ static char * statusbar_xpm[] = { "21 21 65 1", " c None", ". c #F7F7F7", "+ c #DBDBDB", "@ c #D6D6D6", "# c #8D8D8D", "$ c #FDFDFD", "% c #DADADA", "& c #D4D4D4", "* c #737373", "= c #FEFEFE", "- c #808080", "; c #7A7A7A", "> c #FFFFFF", ", c #FAFAFA", "' c #F2F2F2", ") c #F9F9F9", "! c #F5F5F5", "~ c #D5D5D5", "{ c #DEDEDE", "] c #D8D8D8", "^ c #D9D9D9", "/ c #D2D2D2", "( c #DCDCDC", "_ c #C9C9C9", ": c #D1D1D1", "< c #D0D0D0", "[ c #D7D7D7", "} c #CFCFCF", "| c #E0E0E0", "1 c #888888", "2 c #727272", "3 c #7E7E7E", "4 c #838383", "5 c #797979", "6 c #6D6D6D", "7 c #777777", "8 c #8A8A8A", "9 c #787878", "0 c #CECECE", "a c #E2E2E2", "b c #E1E1E1", "c c #DDDDDD", "d c #E4E4E4", "e c #E3E3E3", "f c #E5E5E5", "g c #818181", "h c #8B8B8B", "i c #C6C6C6", "j c #EEEEEE", "k c #E6E6E6", "l c #DFDFDF", "m c #F0F0F0", "n c #FBFBFB", "o c #F1F1F1", "p c #E9E9E9", "q c #CDCDCD", "r c #B9B9B9", "s c #CCCCCC", "t c #080808", "u c #010101", "v c #000000", "w c #020202", "x c #070707", "y c #060606", "z c #0A0A0A", " ", " ", " ", " .+@# ", " $%&* ", " =@@- ", " =@@; ", " =@@>>,'=>=)!>>> ", " =@@~&{%]^/%(~_] ", " =@@:<+[&~}[^^|@ ", " =@@-1;23435-678 ", " =@@90ab|:+cdef| ", " =@@g|([d%f%+|]e ", " >}]hije~{k{l^f~ ", " ,&/m=>=n>=.>>$> ", " ob+p%:~%][%q+@r ", " >(s&q0@[:~l~ c #2ECECE", ", c #20FFFF", "' c #30FFFF", ") c #2AF9F9", "! c #A6E6E6", "~ c #BECD3E", "{ c #8FFFFF", "] c #1FAEAE", "^ c #36C5C5", "/ c #2ECDCD", "( c #BECE3E", "_ c #4D4D4D", ": c #8ECECE", "< c #4ECDCD", "[ c #009F9F", "} c #172727", "| c #1F1F1F", "1 c #10FFFF", "2 c #008080", "3 c #A0A0A0", "4 c #AEAEDE", "5 c #00BD80", "6 c #005F40", "7 c #8686E5", "8 c #00DE00", "9 c #006F00", "0 c #3636F5", "a c #00FF00", "b c #008000", "c c #787878", "d c #7878A8", "e c #0000BF", "f c #00BF00", "g c #007F00", " ", " ", " ", " ..................+ ", " .@@@@@@@@@@@@@@@@#+ ", " .@$%&*=-$&;;>>;@@#+ ", " .@,$';)!;';>~~>@@#+ ", " .@;{{;;]#^'/((/@@#+ ", " .@$;;;>_##:;/<$@@#+ ", " .@,;;[}|||}[;1,@@#+ ", " .@;;;234@432;;;@@#+ ", " .@555637@736555@@#+ ", " .@8889340439888@@#+ ", " .@aaabcdedcbaaa@@#+ ", " .@aaafgggggfaaa@@#+ ", " .@@@@@@@@@@@@@@@@#+ ", " .#################+ ", " +++++++++++++++++++ ", " ", " ", " "}; wxglade-0.6.8.orig/icons/menubar.xpm0000644000175000017500000000755511621715605017627 0ustar georgeskgeorgesk/* XPM */ static char * menubar_xpm[] = { "21 21 183 2", " c None", ". c #F8F6F7", "+ c #FFFBFC", "@ c #FFFEFC", "# c #FCFCFA", "$ c #FEFFFD", "% c #EBEDEC", "& c #FFFFFF", "* c #F7F2F6", "= c #FFFDFF", "- c #FFFEFF", "; c #EEEEEE", "> c #F7F7F7", ", c #F6F6F6", "' c #000000", ") c #FDF9FA", "! c #DED8DA", "~ c #DAD6D5", "{ c #D7D7D5", "] c #CFD4D0", "^ c #DFE4E0", "/ c #E2E7E3", "( c #D1D2D4", "_ c #D8D6D9", ": c #DFD8DF", "< c #D5CFD3", "[ c #D6D4D7", "} c #D7D7D7", "| c #E2E2E2", "1 c #D2D2D2", "2 c #DBDBDB", "3 c #C1C1C1", "4 c #898989", "5 c #D7D1D3", "6 c #D9D5D4", "7 c #E4E4E2", "8 c #D2D7D3", "9 c #707571", "0 c #E1E2E4", "a c #D3D1D4", "b c #E9E2E9", "c c #E5DFE3", "d c #737174", "e c #E3E3E3", "f c #DADADA", "g c #757575", "h c #D8D8D8", "i c #747474", "j c #DDD7D9", "k c #E0DCDB", "l c #C3C3C1", "m c #EAEFEB", "n c #DFE0E2", "o c #E6E4E7", "p c #CFC8CF", "q c #E3DDE1", "r c #848285", "s c #D6D6D6", "t c #737373", "u c #D5D5D5", "v c #838383", "w c #DBD5D7", "x c #DCD8D7", "y c #DFDFDD", "z c #BEC3BF", "A c #DEE3DF", "B c #757A76", "C c #DDDBDE", "D c #DBD4DB", "E c #D0CACE", "F c #757376", "G c #E1E1E1", "H c #C7C7C7", "I c #CACACA", "J c #8B8B8B", "K c #E2DCDE", "L c #FEFAF9", "M c #FFFFFD", "N c #FAFFFB", "O c #F3F8F4", "P c #FCFFFD", "Q c #F4F5F7", "R c #716A71", "S c #8D878B", "T c #79777A", "U c #DCDCDC", "V c #868686", "W c #777777", "X c #6D6D6D", "Y c #787878", "Z c #CDC7C9", "` c #FFFEFD", " . c #E0E0DE", ".. c #D4D9D5", "+. c #DCE1DD", "@. c #D8D9DB", "#. c #E7E5E8", "$. c #837C83", "%. c #D2CCD0", "&. c #C9C9C9", "*. c #ECECEC", "=. c #CCCCCC", "-. c #878787", ";. c #FAF6F7", ">. c #969092", ",. c #EEEAE9", "'. c #DEDEDC", "). c #777C78", "!. c #787D79", "~. c #747975", "{. c #7F8082", "]. c #D7D5D8", "^. c #878087", "/. c #7D777B", "(. c #7E7C7F", "_. c #7D7D7D", ":. c #7F7F7F", "<. c #818181", "[. c #7E7E7E", "}. c #707070", "|. c #030000", "1. c #0C0608", "2. c #E7E7E5", "3. c #CED3CF", "4. c #DDE2DE", "5. c #D5DAD6", "6. c #DBDCDE", "7. c #E1DFE2", "8. c #827B82", "9. c #040002", "0. c #020003", "a. c #010101", "b. c #020202", "c. c #F6F2F1", "d. c #7C817D", "e. c #858A86", "f. c #898A8C", "g. c #7F787F", "h. c #090307", "i. c #FDF9F8", "j. c #EAEAE8", "k. c #D1D6D2", "l. c #D5D6D8", "m. c #EAE8EB", "n. c #756E75", "o. c #FFFCFB", "p. c #DADAD8", "q. c #6E736F", "r. c #888D89", "s. c #808581", "t. c #797A7C", "u. c #ECEAED", "v. c #0C060A", "w. c #DCDCDA", "x. c #E1E6E2", "y. c #D0D5D1", "z. c #D6D7D9", "A. c #E9E7EA", "B. c #766F76", "C. c #0B0509", "D. c #DBDBD9", "E. c #767B77", "F. c #7C7D7F", "G. c #DAD8DB", "H. c #7E777E", "I. c #050003", "J. c #F4F0EF", "K. c #E5EAE6", "L. c #D3D8D4", "M. c #DEDFE1", "N. c #D5D3D6", "O. c #8B848B", "P. c #070105", "Q. c #7A7A78", "R. c #717370", "S. c #7D7F7E", "T. c #7A7A7A", "U. c #8C8A8D", "V. c #716B6F", "W. c #000201", "X. c #020001", "Y. c #040001", "Z. c #050001", " ", " ", " . + @ # $ $ % & * = = - & ; & > & & , ' ", " ) ! ~ { ] ^ / ( _ : < [ } | 1 2 2 3 4 ' ", " - 5 6 7 8 ] 9 0 a b c d | 1 e f g h i ' ", " - j k l m ^ 9 n o p q r e s 2 1 t u v ' ", " + w x y z A B n C D E F G H h I J } t ' ", " - K L M N O P Q - R S T U v V W X f Y ' ", " - Z ` .../ +.@.#.$.%.[ U U &.u *.=.-.' ", " ;.>.,.'.).!.~.{.].^./.(.W _.:.<.X [.}.' ", " |.1.` 2.3.4.5.6.7.8.9.0.a.a.a.a.a.a.a.b.", " c.{ d.e.).f.].g.h. ", " i.j.4.3.k.l.m.n.9. ", " o.p.q.r.s.t.u.n.v. ", " ` w.x.y.+.z.A.B.C. ", " ` D.!.!.E.F.G.H.I. ", " J.'.K.L.A M.N.O.P. ", " M Q.R.).S.T.U.V.9. ", " W.W.a.a.X.Y.Z.Y. ", " ", " "}; wxglade-0.6.8.orig/icons/icon.xpm0000644000175000017500000000250011621715605017107 0ustar georgeskgeorgesk/* XPM */ static char *mondrian_xpm[] = { /* columns rows colors chars-per-pixel */ "32 32 6 1", " c Black", ". c Blue", "X c #00bf00", "o c Red", "O c Yellow", "+ c Gray100", /* pixels */ " ", " oooooo +++++++++++++++++++++++ ", " oooooo +++++++++++++++++++++++ ", " oooooo +++++++++++++++++++++++ ", " oooooo +++++++++++++++++++++++ ", " oooooo +++++++++++++++++++++++ ", " oooooo +++++++++++++++++++++++ ", " oooooo +++++++++++++++++++++++ ", " ", " ++++++ ++++++++++++++++++ .... ", " ++++++ ++++++++++++++++++ .... ", " ++++++ ++++++++++++++++++ .... ", " ++++++ ++++++++++++++++++ .... ", " ++++++ ++++++++++++++++++ .... ", " ++++++ ++++++++++++++++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++++++++++++++++ ++++ ", " ++++++ ++++ ", " ++++++ OOOOOOOOOOOO XXXXX ++++ ", " ++++++ OOOOOOOOOOOO XXXXX ++++ ", " ++++++ OOOOOOOOOOOO XXXXX ++++ ", " ++++++ OOOOOOOOOOOO XXXXX ++++ ", " ++++++ OOOOOOOOOOOO XXXXX ++++ ", " ++++++ OOOOOOOOOOOO XXXXX ++++ ", " " }; wxglade-0.6.8.orig/icons/tree_ctrl.xpm0000644000175000017500000000123611621715605020147 0ustar georgeskgeorgesk/* XPM */ static char * tree_ctrl_xpm[] = { "21 21 6 1", " c None", ". c #000000", "+ c #00FFFF", "@ c #7B797B", "# c #FFFF00", "$ c #00FF00", " ... ", " .+. @@@@@@ ", " ... ", " . ", " . ... ", " ....#. @@@@@@ ", " . ... ", " . . ", " . . ... ", " . ....$. @@@@@@ ", " . . ... ", " . . ", " . . ... ", " . ....$. @@@@@@ ", " . ... ", " . ", " . ... ", " ....#. @@@@@@ ", " ... ", " . ", " . "}; wxglade-0.6.8.orig/icons/closed_folder.xpm0000644000175000017500000000072511621715605020772 0ustar georgeskgeorgesk/* XPM */ static char * closed_folder_xpm[] = { "16 16 6 1", " c None", ". c #808080", "+ c #FFFF00", "@ c #C0C0C0", "# c #FFFFFF", "$ c #000000", " ", " ", " ..... ", " .+@+@+. ", " .+@+@+@+...... ", " .############.$", " .#+@+@+@+@+@+.$", " .#@+@+@+@+@+@.$", " .#+@+@+@+@+@+.$", " .#@+@+@+@+@+@.$", " .#+@+@+@+@+@+.$", " .#@+@+@+@+@+@.$", " .#+@+@+@+@+@+.$", " ..............$", " $$$$$$$$$$$$$$", " "}; wxglade-0.6.8.orig/icons/notebook.xpm0000644000175000017500000000154111621715605020003 0ustar georgeskgeorgesk/* XPM */ static char * notebook_xpm[] = { "21 21 19 1", " c None", ". c #FFFFFF", "+ c #6C6C6C", "@ c #D9D9D9", "# c #989898", "$ c #020202", "% c #D8D8D8", "& c #7C7C7C", "* c #000000", "= c #050505", "- c #010101", "; c #101010", "> c #060606", ", c #7E7E7E", "' c #0F0F0F", ") c #0C0C0C", "! c #0E0E0E", "~ c #0B0B0B", "{ c #030303", " ", " ", " ", " ......+....+....+ ", " .@@@@@+####+####+ ", " .@@@@@+####+####+ ", " .@@@@@+####+####+ ", " .@@@@@+...........$ ", " .%@@@@@@@@@@@@@@@&* ", " .@@@@@@@@@@@@@@@@&= ", " .@@@@@@@@@@@@@@@@&* ", " .@@@@@@@@@@@@@@@@&- ", " .@@@@@@@@@@@@@@@@&; ", " .@@@@@@@@@@@@@@@@&> ", " .@@@@@@@@@@@@@@@@&* ", " .@@@@@@@@@@@@@@@@&* ", " .&&&&&&&&&&&&&&,&&' ", " *)*!~*********=-*~{ ", " ", " ", " "}; wxglade-0.6.8.orig/icons/custom.xpm0000644000175000017500000000144311621715605017476 0ustar georgeskgeorgesk/* XPM */ static char * custom_xpm[] = { "21 21 15 1", " c None", ". c #7B7B7B", "+ c #000000", "@ c #FFFFFF", "# c #DEDEDE", "$ c #D6D6D6", "% c #E38E8E", "& c #DFA7A7", "* c #FF0000", "= c #F52F2F", "- c #DABEBE", "; c #F14747", "> c #FA1818", ", c #EC5F5F", "' c #E87777", " ", " ................... ", " .++++++++++++++++@# ", " .+$$$$$$$$$$$$$$$@# ", " .+$$$$$$$$$$$$$$$@# ", " .+$$$$$$%%&$$$$$$@# ", " .+$$$$%****=-$$$$@# ", " .+$$$-**&$%*=$$$$@# ", " .+$$$-%&$$$**$$$$@# ", " .+$$$$$$$$;*=$$$$@# ", " .+$$$$$$$;*>-$$$$@# ", " .+$$$$$$,*=$$$$$$@# ", " .+$$$$$$;*%$$$$$$@# ", " .+$$$$$$&%-$$$$$$@# ", " .+$$$$$$;*%$$$$$$@# ", " .+$$$$$$';&$$$$$$@# ", " .+$$$$$$$$$$$$$$$@# ", " .+$$$$$$$$$$$$$$$@# ", " .@@@@@@@@@@@@@@@@@# ", " .################## ", " "}; wxglade-0.6.8.orig/icons/list_box.xpm0000644000175000017500000000123511621715605020006 0ustar georgeskgeorgesk/* XPM */ static char * list_box_xpm[] = { "21 21 6 1", " c None", ". c #848284", "+ c #000000", "@ c #FFFFFF", "# c #C6C3C6", "$ c #000084", " ", "...............++++++", ".@@@@@@@@@@@@@@+@@@#+", ".@@@$$$$$$$$$@@+@..#+", ".@@@@@@@@@@@@@@+@++#+", ".@@@$$$$$$$$@@@+####+", ".@@@@@@@@@@@@@@++++++", ".@@@$$$$$$$$$@@+@#@#+", ".@@@@@@@@@@@@@@+#@#@+", ".@@@$$$$$$$$@@@+@#@#+", ".$$$$$$$$$$$$$$+#@#@+", ".$$$@@@@@@@@@$$+@#@#+", ".$$$$$$$$$$$$$$+#@#@+", ".@@@$$$$$$$$@@@+@#@#+", ".@@@@@@@@@@@@@@++++++", ".@@@$$$$$$$$$@@+@@@#+", ".@@@@@@@@@@@@@@+@++#+", ".@@@$$$$$$$$@@@+@..#+", ".@@@@@@@@@@@@@@+####+", ".++++++++++++++++++++", " "}; wxglade-0.6.8.orig/icons/sizer.xpm0000644000175000017500000000161311621715605017317 0ustar georgeskgeorgesk/* XPM */ static char * sizer_xpm[] = { "21 21 22 1", " c None", ". c #FFFFFF", "+ c #F0F0F0", "@ c #0F0F0F", "# c #D8D8D8", "$ c #D9D9D9", "% c #7A7A7A", "& c #030303", "* c #D7D7D7", "= c #010101", "- c #0C0C0C", "; c #000000", "> c #020202", ", c #0A0A0A", "' c #060606", ") c #050505", "! c #040404", "~ c #0B0B0B", "{ c #070707", "] c #DADADA", "^ c #D6D6D6", "/ c #0D0D0D", "...................+@", ".###$$$$$$$$#######%&", ".#############*####%=", ".##################%-", ".##################%;", ".%%%%%%%%%%%%%%%%%%%;", ">;,;========',;;;;>>'", "...................+;", ".##################%)", ".##################%)", ".##################%;", ".##################%;", ".%%%%%%%%%%%%%%%%%%%!", ");~;;;;;;;;;&;{&;>;=;", "...................+!", ".##################%;", ".##############]###%>", ".###^^^^^##########%>", ".##################%;", ".%%%%%%%%%%%%%%%%%%%!", ";;/;;;;;;;;;>;'>;=;;;"}; wxglade-0.6.8.orig/icons/spacer.xpm0000644000175000017500000000115611621715605017442 0ustar georgeskgeorgesk/* XPM */ static char * spacer_xpm[] = { "21 21 3 1", " c None", ". c #000000", "+ c #929292", " ", " ", " ", " ", " ", " ", " . . ", " .+ .+ ", " .+ . . .+ ", " .+ .. .. .+ ", " .+.............. .+ ", " .+ ..++++++++..++.+ ", " .+ .+ .++ .+ ", " .+ + + .+ ", " .+ .+ ", " + + ", " ", " ", " ", " ", " "}; wxglade-0.6.8.orig/icons/toggle_button.xpm0000644000175000017500000000162311621715605021040 0ustar georgeskgeorgesk/* XPM */ static char * toggle_button_xpm[] = { "21 21 22 1", " c None", ". c #7C7C7C", "+ c #FCFCFC", "@ c #000000", "# c #060606", "$ c #BEBEBE", "% c #C2C2C2", "& c #BFBFBF", "* c #010101", "= c #C1C1C1", "- c #050505", "; c #0C0C0C", "> c #040404", ", c #070707", "' c #0E0E0E", ") c #111111", "! c #080808", "~ c #030303", "{ c #020202", "] c #BCBCBC", "^ c #0D0D0D", "/ c #1D1D1D", " ", " ", " ", " ..................+ ", " .@@@@@@@@@@@@@@#@@+ ", " .@$$$$$$$$$$$$$$$$+ ", " .@$$$%$$$&&$$$$$$$+ ", " .@$$$$$$$$$$$$$$$$+ ", " .@$$$$#@$$*$$@$$$$+ ", " .@$=$@$$-$@$$;$$$$+ ", " .@$$$>$$@$,@$@$$$$+ ", " .@$$$'$$)$!$~@$$$$+ ", " .@$%$@$${${$$@$$$$+ ", " .@$]$$@@$$^=$/$$$$+ ", " .@$$$$$$$$$$$$$$$$+ ", " .@$$$$$$$$$$$$$$$$+ ", " .@$$$$$$$$$$$$$$$$+ ", " +++++++++++++++++++ ", " ", " ", " "}; wxglade-0.6.8.orig/icons/radio_box.xpm0000644000175000017500000000327111621715605020133 0ustar georgeskgeorgesk/* XPM */ static char * radio_box_xpm[] = { "21 21 76 1", " c None", ". c #D4D4D4", "+ c #DEDEDE", "@ c #DCDCDC", "# c #DADADA", "$ c #000000", "% c #0F0F0F", "& c #E4E4E4", "* c #E2E2E2", "= c #CACACA", "- c #D2D2D2", "; c #CCCCCC", "> c #EEEEEE", ", c #D8D8D8", "' c #DDDDDD", ") c #7A7A7A", "! c #8C8C8C", "~ c #7F7F7F", "{ c #C9C9C9", "] c #0B0B0B", "^ c #D7D7D7", "/ c #080808", "( c #E0E0E0", "_ c #8F8F8F", ": c #727272", "< c #828282", "[ c #7B7B7B", "} c #6B6B6B", "| c #FFFFFF", "1 c #7C7C7C", "2 c #F8F8F8", "3 c #F7F7F7", "4 c #030303", "5 c #191919", "6 c #C4C4C4", "7 c #090909", "8 c #C1C1C1", "9 c #F4F4F4", "0 c #F5F5F5", "a c #898989", "b c #797979", "c c #CDCDCD", "d c #0C0C0C", "e c #E5E5E5", "f c #C2C2C2", "g c #EAEAEA", "h c #D6D6D6", "i c #CBCBCB", "j c #CFCFCF", "k c #686868", "l c #6C6C6C", "m c #D5D5D5", "n c #D1D1D1", "o c #D9D9D9", "p c #E3E3E3", "q c #C8C8C8", "r c #757575", "s c #FCFCFC", "t c #777777", "u c #DBDBDB", "v c #DFDFDF", "w c #848284", "x c #D3D3D3", "y c #FDFDFD", "z c #787878", "A c #C6C3C6", "B c #717171", "C c #808080", "D c #D0D0D0", "E c #7D7D7D", "F c #F9F9F9", "G c #868686", "H c #747474", "I c #848484", "J c #888888", "K c #FBFBFB", " ", " .+@#$$%&$*=-.*+;>,' ", " )!~{]@$^$$/(_:<~[}| ", " 123+$$4+56789|0||a> ", " b|@cde$f$/$,ghi+jk| ", " l|;mnco'pq+f@m^+@rs ", " t|uo.vjwwww+h=@nx c #787878", ", c #C6C3C6", "' c #FBFBFB", ") c #0C0C0C", "! c #090909", "~ c #BFBFBF", "{ c #0B0B0B", "] c #0A0A0A", "^ c #F6F6F6", "/ c #030303", "( c #FEFEFE", "_ c #040404", " ", " ", " ", " ", " ", " ", ".+.@..@.@.@#$$.#%....", "&**********=.--**;;>#", ".**----.---*#-,,,,,>.", ".******.***'.-,...,>$", "$******.***-)-,,!,,>.", "%**---.-----.-,,,~,>{", "]^...*.*...*/-,,,,,>]", ".*(*********.>>>>>>>.", "_{.$$$$$$$$$$$$$$$$$$", " ", " ", " ", " ", " ", " "}; wxglade-0.6.8.orig/icons/combo_box.xpm0000644000175000017500000000121711621715605020132 0ustar georgeskgeorgesk/* XPM */ static char * combo_box_xpm[] = { "21 21 5 1", " c None", ". c #848284", "+ c #000000", "@ c #C6C3C6", "# c #FFFFFF", " ", " ", ".....................", ".+++++++++++++++++++@", ".+#####@@@@@@@@@@@@+@", ".+#####@##########.+@", ".+#####@#@@@@@@@@@.+@", ".+#####@#@@@@@@@@@.+@", ".+#####@#@@@@@@@@@.+@", ".+#####@#@++++++.@.+@", ".+#####@#@@++++.@@.+@", ".+#####@#@@@++.@@@.+@", ".+#####@#@@@@.@@@@.+@", ".+#####@#@@@@@@@@@.+@", ".+#####@#@@@@@@@@@.+@", ".+#####@#@@@@@@@@@.+@", ".+#####@...........+@", ".+#####+++++++++++++@", ".@@@@@@@@@@@@@@@@@@@@", "#####################", " "}; wxglade-0.6.8.orig/setup.py0000644000175000017500000001407612167336636016054 0ustar georgeskgeorgesk# -*- coding: Latin-1 -*- # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY from distutils.core import setup import distutils.command.sdist from distutils.util import convert_path import os from types import * from glob import glob import common # distutils sdisk command is broken because it doesn't copy data_files # Bug: http://bugs.python.org/issue2279 def add_defaults_fixed(self): """Add all the default files to self.filelist: - README or README.txt - setup.py - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) - all files defined in data_files. - all files defined as scripts. - all C sources listed as part of extensions or C libraries in the setup script (doesn't catch C headers!) Warns if (README or README.txt) or setup.py are missing; everything else is optional. """ standards = [('README', 'README.txt'), self.distribution.script_name] for fn in standards: if isinstance(fn, tuple): alts = fn got_it = False for fn in alts: if os.path.exists(fn): got_it = True self.filelist.append(fn) break if not got_it: self.warn("standard file not found: should have one of " + ', '.join(alts)) else: if os.path.exists(fn): self.filelist.append(fn) else: self.warn("standard file '%s' not found" % fn) optional = ['test/test*.py', 'setup.cfg'] for pattern in optional: files = filter(os.path.isfile, glob(pattern)) self.filelist.extend(files) # build_py is used to get: # - python modules # - files defined in package_data build_py = self.get_finalized_command('build_py') # getting python files if self.distribution.has_pure_modules(): self.filelist.extend(build_py.get_source_files()) # getting package_data files # (computed in build_py.data_files by build_py.finalize_options) for pkg, src_dir, build_dir, filenames in build_py.data_files: for filename in filenames: self.filelist.append(os.path.join(src_dir, filename)) # getting distribution.data_files if self.distribution.has_data_files(): for item in self.distribution.data_files: if isinstance(item, str): # plain file item = convert_path(item) if os.path.isfile(item): self.filelist.append(item) else: # a (dirname, filenames) tuple dirname, filenames = item for f in filenames: f = convert_path(f) if os.path.isfile(f): self.filelist.append(f) if self.distribution.has_ext_modules(): build_ext = self.get_finalized_command('build_ext') self.filelist.extend(build_ext.get_source_files()) if self.distribution.has_c_libraries(): build_clib = self.get_finalized_command('build_clib') self.filelist.extend(build_clib.get_source_files()) if self.distribution.has_scripts(): build_scripts = self.get_finalized_command('build_scripts') self.filelist.extend(build_scripts.get_source_files()) # Replace old implementation by the new own distutils.command.sdist.sdist.add_defaults = add_defaults_fixed def is_package(path): return ( os.path.isdir(path) and os.path.isfile(os.path.join(path, '__init__.py')) ) def find_packages(path, base="" ): """ Find all packages in path """ packages = {} for item in os.listdir(path): dir = os.path.join(path, item) if is_package( dir ): if base: module_name = "%(base)s.%(item)s" % vars() else: module_name = item packages[module_name] = dir packages.update(find_packages(dir, module_name)) return packages classifiers = """\ Development Status :: 4 - Beta Intended Audience :: Developers License :: OSI Approved :: MIT License Natural Language :: English Operating System :: OS Independent (Written in an interpreted language) Programming Language :: Python :: 2 Topic :: Software Development :: Code Generators User Interface :: Textual :: Command-line User Interface :: Toolkits/Libraries :: wxWidgets""" description = \ 'GUI designer written in Python with the popular GUI toolkit wxPython' data_files = [[ 'share/doc/wxglade', ['CHANGES.txt', 'credits.txt', 'epydoc.conf', 'license.txt', 'Makefile', 'NEWS.txt', 'README.txt', 'TODO.txt',], ],[ 'share/doc/wxglade/doc', glob('docs/*.html'), ],[ 'share/doc/wxglade/doc/img', glob('docs/img/*.*'), ],[ 'share/doc/wxglade/doc', glob('docs/*.txt'), ],[ 'share/doc/wxglade/doc/html', glob('docs/html/*.*'), ],[ 'share/doc/wxglade/doc/pdf', glob('docs/pdf/*.pdf'), ],[ 'share/man/man1', ['docs/man/wxglade.1'], # documentation source files :-) ],[ 'share/doc/wxglade', ['docs/man/manpage.xml'], ],[ 'share/doc/wxglade', ['docs/src/manual.xml'], ]] scripts = ['wxglade',] packages = find_packages(path=".", base='wxglade').keys() packages.append('wxglade') version = common.version setup( name='wxGlade', version=version, author='Alberto Griggio', author_email='agriggio@users.sourceforge.net', url='http://wxglade.sourceforge.net/', classifiers=classifiers.split("\n"), description=description, license='MIT License', platforms = ['WIN32', 'OSX', 'POSIX'], scripts=scripts, packages=packages, package_dir={'wxglade': '.'}, package_data={'wxglade.widgets': ['widgets.txt'], 'wxglade' : ['icons/*.*', 'icons/gtk/*.*', 'icons/msw/*.*', 'res/*.*', ]}, data_files=data_files, ) wxglade-0.6.8.orig/templates_ui.py0000755000175000017500000001745712150154266017405 0ustar georgeskgeorgesk#!/usr/bin/env python # -*- coding: ISO-8859-1 -*- # # generated by wxGlade 11b82132ec86 on Sun Apr 7 09:46:05 2013 # import wx # begin wxGlade: dependencies import gettext # end wxGlade # begin wxGlade: extracode try: ID_EDIT = wx.ID_EDIT except AttributeError: ID_EDIT = wx.NewId() # end wxGlade class TemplateInfoDialog(wx.Dialog): def __init__(self, *args, **kwds): # begin wxGlade: TemplateInfoDialog.__init__ kwds["style"] = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER | wx.MAXIMIZE_BOX | wx.THICK_FRAME wx.Dialog.__init__(self, *args, **kwds) self.template_name = wx.TextCtrl(self, wx.ID_ANY, "") self.author = wx.TextCtrl(self, wx.ID_ANY, "") self.sizer_2_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Author")) self.description = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE) self.sizer_3_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Description")) self.instructions = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE) self.sizer_3_copy_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Instructions")) self.button_1 = wx.Button(self, wx.ID_OK, "") self.button_2 = wx.Button(self, wx.ID_CANCEL, "") self.__set_properties() self.__do_layout() # end wxGlade def __set_properties(self): # begin wxGlade: TemplateInfoDialog.__set_properties self.SetTitle(_("wxGlade template information")) self.SetSize(wx.DLG_SZE(self, (250, 264))) self.template_name.SetFocus() # end wxGlade def __do_layout(self): # begin wxGlade: TemplateInfoDialog.__do_layout sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_4 = wx.BoxSizer(wx.HORIZONTAL) self.sizer_3_copy_staticbox.Lower() sizer_3_copy = wx.StaticBoxSizer(self.sizer_3_copy_staticbox, wx.HORIZONTAL) self.sizer_3_staticbox.Lower() sizer_3 = wx.StaticBoxSizer(self.sizer_3_staticbox, wx.HORIZONTAL) self.sizer_2_staticbox.Lower() sizer_2 = wx.StaticBoxSizer(self.sizer_2_staticbox, wx.HORIZONTAL) sizer_8 = wx.BoxSizer(wx.HORIZONTAL) template_name_copy = wx.StaticText(self, wx.ID_ANY, _("wxGlade template: ")) template_name_copy.SetFont(wx.Font(-1, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) sizer_8.Add(template_name_copy, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 10) sizer_8.Add(self.template_name, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 10) sizer_1.Add(sizer_8, 0, wx.EXPAND, 0) sizer_2.Add(self.author, 1, 0, 0) sizer_1.Add(sizer_2, 0, wx.ALL | wx.EXPAND, 5) sizer_3.Add(self.description, 1, wx.EXPAND, 0) sizer_1.Add(sizer_3, 1, wx.ALL | wx.EXPAND, 5) sizer_3_copy.Add(self.instructions, 1, wx.EXPAND, 0) sizer_1.Add(sizer_3_copy, 1, wx.ALL | wx.EXPAND, 5) sizer_4.Add(self.button_1, 0, 0, 0) sizer_4.Add(self.button_2, 0, wx.LEFT, 10) sizer_1.Add(sizer_4, 0, wx.ALL | wx.ALIGN_RIGHT, 10) self.SetSizer(sizer_1) self.Layout() self.Centre() # end wxGlade # end of class TemplateInfoDialog class TemplateListDialog(wx.Dialog): def __init__(self, *args, **kwds): # begin wxGlade: TemplateListDialog.__init__ kwds["style"] = wx.DEFAULT_DIALOG_STYLE wx.Dialog.__init__(self, *args, **kwds) self.template_names = wx.ListBox(self, wx.ID_ANY, choices=[]) self.sizer_7_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Available templates")) self.template_name = wx.StaticText(self, wx.ID_ANY, _("wxGlade template:\n")) self.author = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_READONLY) self.sizer_2_copy_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Author")) self.description = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY) self.sizer_3_copy_1_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Description")) self.instructions = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY) self.sizer_3_copy_copy_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Instructions")) self.btn_open = wx.Button(self, wx.ID_OPEN, "") self.btn_edit = wx.Button(self, ID_EDIT, _("&Edit")) self.btn_delete = wx.Button(self, wx.ID_DELETE, "") self.btn_cancel = wx.Button(self, wx.ID_CANCEL, "") self.__set_properties() self.__do_layout() self.Bind(wx.EVT_LISTBOX_DCLICK, self.on_open, self.template_names) self.Bind(wx.EVT_LISTBOX, self.on_select_template, self.template_names) self.Bind(wx.EVT_BUTTON, self.on_open, self.btn_open) self.Bind(wx.EVT_BUTTON, self.on_edit, id=ID_EDIT) self.Bind(wx.EVT_BUTTON, self.on_delete, self.btn_delete) # end wxGlade def __set_properties(self): # begin wxGlade: TemplateListDialog.__set_properties self.SetTitle(_("wxGlade template list")) self.SetSize(wx.DLG_SZE(self, (300, 200))) self.template_name.SetFont(wx.Font(-1, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) # end wxGlade def __do_layout(self): # begin wxGlade: TemplateListDialog.__do_layout sizer_5 = wx.BoxSizer(wx.VERTICAL) sizer_4_copy = wx.BoxSizer(wx.HORIZONTAL) sizer_6 = wx.BoxSizer(wx.HORIZONTAL) sizer_1_copy = wx.BoxSizer(wx.VERTICAL) self.sizer_3_copy_copy_staticbox.Lower() sizer_3_copy_copy = wx.StaticBoxSizer(self.sizer_3_copy_copy_staticbox, wx.HORIZONTAL) self.sizer_3_copy_1_staticbox.Lower() sizer_3_copy_1 = wx.StaticBoxSizer(self.sizer_3_copy_1_staticbox, wx.HORIZONTAL) self.sizer_2_copy_staticbox.Lower() sizer_2_copy = wx.StaticBoxSizer(self.sizer_2_copy_staticbox, wx.HORIZONTAL) self.sizer_7_staticbox.Lower() sizer_7 = wx.StaticBoxSizer(self.sizer_7_staticbox, wx.VERTICAL) sizer_7.Add(self.template_names, 1, wx.ALL | wx.EXPAND, 3) sizer_6.Add(sizer_7, 1, wx.ALL | wx.EXPAND, 5) sizer_1_copy.Add(self.template_name, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 7) sizer_2_copy.Add(self.author, 1, 0, 0) sizer_1_copy.Add(sizer_2_copy, 0, wx.ALL | wx.EXPAND, 5) sizer_3_copy_1.Add(self.description, 1, wx.EXPAND, 0) sizer_1_copy.Add(sizer_3_copy_1, 1, wx.ALL | wx.EXPAND, 5) sizer_3_copy_copy.Add(self.instructions, 1, wx.EXPAND, 0) sizer_1_copy.Add(sizer_3_copy_copy, 1, wx.ALL | wx.EXPAND, 5) sizer_6.Add(sizer_1_copy, 2, wx.EXPAND, 0) sizer_5.Add(sizer_6, 1, wx.EXPAND, 0) sizer_4_copy.Add(self.btn_open, 0, 0, 0) sizer_4_copy.Add(self.btn_edit, 0, wx.LEFT, 10) sizer_4_copy.Add(self.btn_delete, 0, wx.LEFT, 10) sizer_4_copy.Add(self.btn_cancel, 0, wx.LEFT, 10) sizer_5.Add(sizer_4_copy, 0, wx.ALL | wx.ALIGN_RIGHT, 10) self.SetSizer(sizer_5) self.Layout() self.Centre() # end wxGlade def on_open(self, event): # wxGlade: TemplateListDialog. print "Event handler 'on_open' not implemented!" event.Skip() def on_select_template(self, event): # wxGlade: TemplateListDialog. print "Event handler 'on_select_template' not implemented!" event.Skip() def on_edit(self, event): # wxGlade: TemplateListDialog. print "Event handler 'on_edit' not implemented!" event.Skip() def on_delete(self, event): # wxGlade: TemplateListDialog. print "Event handler 'on_delete' not implemented!" event.Skip() # end of class TemplateListDialog if __name__ == "__main__": gettext.install("app") # replace with the appropriate catalog name app = wx.PySimpleApp(0) wx.InitAllImageHandlers() template_info_dialog = TemplateInfoDialog(None, wx.ID_ANY, "") app.SetTopWindow(template_info_dialog) template_info_dialog.Show() app.MainLoop() wxglade-0.6.8.orig/msgdialog.py0000644000175000017500000000401712167336636016654 0ustar georgeskgeorgesk#!/usr/bin/env python # -*- coding: iso-8859-1 -*- # generated by wxGlade 0.6 on Sat Sep 1 01:40:08 2007 import wx # begin wxGlade: extracode # end wxGlade class MessageDialog(wx.Dialog): def __init__(self, *args, **kwds): # begin wxGlade: MessageDialog.__init__ kwds["style"] = wx.DEFAULT_DIALOG_STYLE wx.Dialog.__init__(self, *args, **kwds) self.msg_title = wx.StaticText(self, -1, _("wxGlade message")) self.msg_image = wx.StaticBitmap(self, -1, (wx.ArtProvider_GetBitmap(wx.ART_TIP, wx.ART_MESSAGE_BOX, (48, 48)))) self.msg_list = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.LC_NO_HEADER|wx.LC_SINGLE_SEL|wx.SUNKEN_BORDER) self.OK = wx.Button(self, wx.ID_OK, "") self.__set_properties() self.__do_layout() # end wxGlade def __set_properties(self): # begin wxGlade: MessageDialog.__set_properties self.SetTitle(_("wxGlade message")) self.SetSize(wx.DLG_SZE(self, (250, 112))) self.msg_title.SetFont(wx.Font(-1, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) self.msg_image.SetMinSize((48, 48)) # end wxGlade def __do_layout(self): # begin wxGlade: MessageDialog.__do_layout sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_2 = wx.BoxSizer(wx.HORIZONTAL) sizer_1.Add(self.msg_title, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5) sizer_2.Add(self.msg_image, 0, wx.ALIGN_CENTER_HORIZONTAL, 0) sizer_2.Add(self.msg_list, 1, wx.LEFT|wx.EXPAND, 10) sizer_1.Add(sizer_2, 1, wx.LEFT|wx.RIGHT|wx.EXPAND, 5) sizer_1.Add(self.OK, 0, wx.ALL|wx.ALIGN_RIGHT, 10) self.SetSizer(sizer_1) self.Layout() self.Centre() # end wxGlade # end of class MessageDialog if __name__ == "__main__": import gettext gettext.install("app") # replace with the appropriate catalog name app = wx.PySimpleApp(0) wx.InitAllImageHandlers() dialog_1 = MessageDialog(None, -1, "") app.SetTopWindow(dialog_1) dialog_1.Show() app.MainLoop() wxglade-0.6.8.orig/events_mixin.py0000644000175000017500000001142212150154266017401 0ustar georgeskgeorgesk""" Mixin class for 'events' property @copyright: 2002-2004 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import wx import wx.grid import re from widget_properties import GridProperty from xml.sax.saxutils import escape, quoteattr class EventsProperty(GridProperty): def __init__(self, owner): cols = [(_('Event'), GridProperty.STRING), (_('Handler'), GridProperty.STRING)] GridProperty.__init__(self, owner, 'events', None, cols, len(owner.events), False, False, False, label=_('events')) self._pos = {} for index, name in enumerate(owner.events): self._pos[name] = index self.validator_re = re.compile(r'^\s*[\w-]+\s*$') self.set_value([[name, ''] for name in owner.events]) def display(self, parent): GridProperty.display(self, parent) attr = wx.grid.GridCellAttr() attr.SetReadOnly(True) self.grid.SetColAttr(0, attr) self.grid.AutoSizeColumn(0, False) self.grid.AutoSizeColumn(1, False) wx.grid.EVT_GRID_CELL_CHANGE(self.grid, self.on_change_val) szr = self.panel.GetSizer() szr.Show(self.btn_sizer, False) szr.Layout() def set_value_dict(self, values_dict): val = self.get_value() for row in val: row[1] = values_dict.get(row[0], "") self.set_value(val) def write(self, outfile, tabs): if self.getter: handlers = self.getter() else: handlers = self.owner[self.name][0]() if handlers: written = False write = outfile.write #write(' ' * tabs + '\n') stab = ' ' * (tabs+1) for event, handler in handlers: if handler: if not written: written = True write(' ' * tabs + '\n') write('%s%s\n' % (stab, quoteattr(event), escape(handler.strip()))) if written: write(' ' * tabs + '\n') def on_change_val(self, event): val = self.get_value() for i in range(len(val)): handler = val[i][1].strip() if handler and self.validator_re.match(handler) is None: self.set_value(self.val) return event.Skip() GridProperty.on_change_val(self, event) # end of class EventsProperty class EventsPropertyHandler(object): def __init__(self, owner): #print 'EventsPropertyHandler', owner.name self.owner = owner self.handlers = {} self.event_name = None self.curr_handler = [] def start_elem(self, name, attrs): if name == 'handler': self.event_name = attrs['event'] def end_elem(self, name): if name == 'handler': if self.event_name and self.curr_handler: self.handlers[self.event_name] = ''.join(self.curr_handler) self.event_name = None self.curr_handler = [] elif name == 'events': self.owner.properties['events'].set_value_dict(self.handlers) self.owner.set_events_dict(self.handlers) return True # to remove this handler def char_data(self, data): data = data.strip() if data: self.curr_handler.append(data) # end of class EventsPropertyHandler default_events = [] class EventsMixin: def __init__(self): if not hasattr(self, 'events'): self.events = default_events self.handlers = {} if self.events: self.access_functions['events'] = self.get_events, self.set_events self.properties['events'] = EventsProperty(self) def get_events(self): ret = [] for e in self.events: ret.append([e, self.handlers.get(e, '')]) return ret def set_events(self, handlers_list): self.handlers = {} for event, val in handlers_list: if val.strip(): self.handlers[event] = val def set_events_dict(self, handlers): self.handlers = handlers def create_events_property(self): if not self.events: return panel = wx.Panel(self.notebook, -1) self.properties['events'].display(panel) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.properties['events'].panel, 1, wx.ALL|wx.EXPAND, 5) panel.SetSizerAndFit(sizer) self.notebook.AddPage(panel, _('Events')) def get_property_handler(self, name): if name == 'events': return EventsPropertyHandler(self) return None # end of class EventsMixin wxglade-0.6.8.orig/test.py0000755000175000017500000000402012150154266015647 0ustar georgeskgeorgesk#!/usr/bin/env python """ Create a test suites and run all tests @see: L{wxglade.tests} @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import general python modules import gettext import imp import os import unittest from optparse import OptionParser t = gettext.translation(domain="wxglade", localedir="locale", fallback=True) t.install("wxglade") def run_tests(gui_tests=False): """\ Create test suites and run all tests @param gui_tests: Test GUI components or test internal functionality @type gui_tests: Boolean """ suites = [] # get a list of all test modules modules = os.listdir('./tests') if '__init__.py' in modules: modules.remove('__init__.py') # try to import all files as modules for module_name in modules: if (not module_name.endswith('.py')) or \ (gui_tests and not module_name.endswith('_gui.py')) or \ (not gui_tests and module_name.endswith('_gui.py')): continue module_name = os.path.splitext(module_name)[0] fp, path, info = imp.find_module(module_name, ['./tests']) try: module = imp.load_module(module_name, fp, path, info) finally: # Make sure fp is closed properly if fp: fp.close() # search all testcases in the loaded module suites.append(unittest.findTestCases(module)) # summarise all suites and run tests all_tests = unittest.TestSuite(suites) unittest.TextTestRunner(verbosity=2).run(all_tests) if __name__ == '__main__': # evaluate command line options first parser = OptionParser( usage="%prog [options] Test wxGlade components", ) parser.add_option( '-g', '--gui', dest='gui_tests', default=False, action='store_true', help=_('Test GUI components instead of non-GUI components'), ) (options, args) = parser.parse_args() run_tests(options.gui_tests) wxglade-0.6.8.orig/tree.py0000644000175000017500000006541512150154266015643 0ustar georgeskgeorgesk# tree.py: classes to handle and display the structure of a wxGlade app # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import os.path import wx from xml.sax.saxutils import quoteattr import misc import common try: set except NameError: from sets import Set as set class Tree: """\ A class to represent a hierarchy of widgets. """ class Node: __empty_win = None def __init__(self, widget=None, children=None): self.widget = widget self.children = children self.parent = None def remove(self): def remove_rec(node): if node.children is not None: map(remove_rec, node.children) node.children = None if node.widget is not None: # replace the just destroyed notebook with an empty window pw = node.widget.property_window pw.SetTitle(_('Properties - <>')) if Tree.Node.__empty_win is None: Tree.Node.__empty_win = wx.Window(pw, -1) pw.GetSizer().GetChildren()[0].SetWindow( Tree.Node.__empty_win) #wxNotebook(node.widget.property_window, -1)) # call the widget's ``destructor'' node.widget.delete() node.widget = None remove_rec(self) try: self.parent.children.remove(self) except: pass def __repr__(self): try: return self.widget.name except AttributeError: return repr(self.widget) def write(self, outfile, tabs, class_names=None): """\ Writes the xml code for the widget to the given output file """ import edit_sizers fwrite = outfile.write assert self.widget is not None w = self.widget classname = getattr(w, '_classname', w.__class__.__name__) # ALB 2005-11-19: to disable custom class code generation # (for panels...) no_custom = "" if getattr(w, 'no_custom_class', False): no_custom = ' no_custom_class="1"' fwrite(' ' * tabs + '\n' % (quoteattr(w.klass), quoteattr(w.name), quoteattr(classname), no_custom)) def write_by_omitter(widget, name, file, tabs): """ Write to given output file: - value of property - values of properties that previous can block - any omitter can be blocked as well """ widget.properties[name].write(file, tabs) if getattr(widget, 'get_property_blocking', None): items = widget.get_property_blocking(name) if items: for name in items: write_by_omitter(widget, name, file, tabs) for p in w.properties: if not getattr(w.properties[p], '_omitter', None): write_by_omitter(w, p, outfile, tabs+1) if class_names is not None and \ w.__class__.__name__ != 'CustomWidget': class_names.add(w.klass) if isinstance(w, edit_sizers.SizerBase): maxpos = len(w.children) children = self.children is not None and self.children or [] tmp = {} for c in children: tmp[c.widget.pos] = c children = [] class SlotNode: def write(self, outfile, tabs): fwrite(' ' * tabs + '\n') for i in range(1, maxpos): children.append(tmp.get(i, SlotNode())) #if self.children is not None: # for c in self.children: for c in children: if hasattr(c, 'widget'): fwrite(' ' * (tabs+1) + '\n') sp = c.widget.sizer_properties for p in sp: sp[p].write(outfile, tabs+2) c.write(outfile, tabs+2, class_names) fwrite(' ' * (tabs+1) + '\n') else: c.write(outfile, tabs+1) elif self.children is not None: for c in self.children: c.write(outfile, tabs+1, class_names) fwrite(' ' * tabs + '\n') # end of class Node def __init__(self, root=None, app=None): self.root = root if self.root is None: self.root = Tree.Node() self.current = self.root self.app = app # reference to the app properties self.names = {} # dictionary of names of the widgets: each entry is # itself a dictionary, one for each toplevel widget... def _find_toplevel(self, node): assert node is not None, _("None node in _find_toplevel") if node.parent is self.root: return node while node.parent is not self.root: node = node.parent return node def has_name(self, name, node=None): if node is None: #print '\nname to check:', name for n in self.names: #print 'names of %s: %s' % (n.widget.name, self.names[n]) if name in self.names[n]: return True return False else: node = self._find_toplevel(node) #print '\nname to check:', name #print 'names of node %s: %s' % (node.widget.name, self.names[node]) return name in self.names[node] #return self.names.has_key(name) def add(self, child, parent=None): if parent is None: parent = self.root if parent.children is None: parent.children = [] parent.children.append(child) child.parent = parent self.current = child #self.names[str(child.widget.name)] = 1 #self.names.setdefault(parent, {})[str(child.widget.name)] = 1 self.names.setdefault(self._find_toplevel(child), {})[ str(child.widget.name)] = 1 if parent is self.root and \ getattr(child.widget.__class__, '_is_toplevel', False): self.app.add_top_window(child.widget.name) def insert(self, child, parent, index): if parent is None: parent = self.root if parent.children is None: parent.children = [] parent.children.insert(index, child) child.parent = parent self.current = child #self.names[str(child.widget.name)] = 1 #self.names.setdefault(parent, {})[str(child.widget.name)] = 1 self.names.setdefault(self._find_toplevel(child), {})[ str(child.widget.name)] = 1 if parent is self.root: self.app.add_top_window(child.widget.name) def remove(self, node=None): if node is not None: def clear_name(n): try: #del self.names[str(n.widget.name)] del self.names[self._find_toplevel(n)][str(n.widget.name)] except (KeyError, AttributeError): pass if n.children: for c in n.children: clear_name(c) clear_name(node) if node.parent is self.root: self.app.remove_top_window(node.widget.name) node.remove() elif self.root.children: for n in self.root.children: n.remove() self.root.children = None self.names = {} def write(self, outfile=None, tabs=0): """\ Writes the xml equivalent of this tree to the given output file """ if outfile is None: import sys outfile = sys.stdout from time import asctime outfile.write('\n\n\n' % (common.version, asctime())) outpath = os.path.expanduser(self.app.output_path.strip()) name = self.app.get_name() klass = self.app.get_class() option = str(self.app.codegen_opt) top_window = self.app.get_top_window() language = self.app.get_language() encoding = self.app.get_encoding() use_gettext = str(int(self.app.use_gettext)) is_template = str(int(self.app.is_template)) overwrite = str(int(self.app.overwrite)) indent_amount = str(int(self.app.indent_amount)) indent_symbol = int(self.app.indent_mode) if indent_symbol == 0: indent_symbol = "tab" else: indent_symbol = "space" source_ext = '.' + self.app.source_ext header_ext = '.' + self.app.header_ext # ALB 2004-01-18 #use_new_namespace = str(int(self.app.get_use_new_namespace())) use_new_namespace = str(int(not self.app.get_use_old_namespace())) # ALB 2004-12-05 for_version = str(self.app.for_version) outfile.write('\n' \ % tuple([quoteattr(common._encode_to_xml(i)) for i in (outpath, name, klass, option, language, top_window, encoding, use_gettext, overwrite, use_new_namespace, for_version, is_template, indent_amount, indent_symbol, source_ext, header_ext)])) if self.app.is_template and getattr(self.app, 'template_data', None): self.app.template_data.write(outfile, tabs+1) class_names = set() if self.root.children is not None: for c in self.root.children: c.write(outfile, tabs+1, class_names) outfile.write('\n') return class_names def change_node(self, node, widget): """\ Changes the node 'node' so that it refers to 'widget' """ try: #del self.names[node.widget.name] del self.names[self._find_toplevel(node)][node.widget.name] except KeyError: pass node.widget = widget #self.names[widget.name] = 1 self.names.setdefault(self._find_toplevel(node), {})[widget.name] = 1 def change_node_pos(self, node, new_pos, index=None): if index is None: index = node.parent.children.index(node) if index >= new_pos: node.parent.children.insert(new_pos, node) del node.parent.children[index+1] else: del node.parent.children[index] node.parent.children.insert(new_pos+1, node) # end of class Tree class WidgetTree(wx.TreeCtrl, Tree): """\ Tree with the ability to display the hierarchy of widgets """ images = {} # dictionary of icons of the widgets displayed def __init__(self, parent, application): id = wx.NewId() style = wx.TR_DEFAULT_STYLE|wx.TR_HAS_VARIABLE_ROW_HEIGHT if wx.Platform == '__WXGTK__': style |= wx.TR_NO_LINES|wx.TR_FULL_ROW_HIGHLIGHT elif wx.Platform == '__WXMAC__': style &= ~wx.TR_ROW_LINES wx.TreeCtrl.__init__(self, parent, id, style=style) root_node = Tree.Node(application) self.cur_widget = None # reference to the selected widget Tree.__init__(self, root_node, application) image_list = wx.ImageList(21, 21) image_list.Add(wx.Bitmap(os.path.join(common.icons_path, 'application.xpm'), wx.BITMAP_TYPE_XPM)) for w in WidgetTree.images: ## WidgetTree.images[w] = image_list.Add(wx.Bitmap( ## WidgetTree.images[w], wx.BITMAP_TYPE_XPM)) WidgetTree.images[w] = image_list.Add( misc.get_xpm_bitmap(WidgetTree.images[w])) self.AssignImageList(image_list) root_node.item = self.AddRoot(_('Application'), 0) self.SetPyData(root_node.item, root_node) self.skip_select = 0 # necessary to avoid an infinite loop on win32, as # SelectItem fires an EVT_TREE_SEL_CHANGED event self.title = ' ' self.set_title(self.title) self.auto_expand = True # this control the automatic expansion of # nodes: it is set to False during xml loading self._show_menu = misc.wxGladePopupMenu('widget') # popup menu to # show toplevel # widgets SHOW_ID = wx.NewId() self._show_menu.Append(SHOW_ID, _('Show')) wx.EVT_TREE_SEL_CHANGED(self, id, self.on_change_selection) wx.EVT_RIGHT_DOWN(self, self.popup_menu) wx.EVT_LEFT_DCLICK(self, self.show_toplevel) wx.EVT_MENU(self, SHOW_ID, self.show_toplevel) def on_key_down(event): evt_flags = 0 if event.ControlDown(): evt_flags = wx.ACCEL_CTRL evt_key = event.GetKeyCode() for flags, key, function in misc.accel_table: if evt_flags == flags and evt_key == key: wx.CallAfter(function) break event.Skip() wx.EVT_KEY_DOWN(self, on_key_down) def _build_label(self, node): s = node.widget.name if node.widget.klass != node.widget.base and \ node.widget.klass != 'wxScrolledWindow': # special case... s += ' (%s)' % node.widget.klass return s def add(self, child, parent=None, image=None): # is image still used? """\ appends child to the list of parent's children """ Tree.add(self, child, parent) name = child.widget.__class__.__name__ index = WidgetTree.images.get(name, -1) if parent is None: parent = parent.item = self.GetRootItem() child.item = self.AppendItem(parent.item, self._build_label(child), index) self.SetPyData(child.item, child) if self.auto_expand: self.Expand(parent.item) self.select_item(child) child.widget.show_properties() self.app.check_codegen(child.widget) def insert(self, child, parent, pos, image=None): """\ inserts child to the list of parent's children, before index """ if parent.children is None: self.add(child, parent, image) return name = child.widget.__class__.__name__ image_index = WidgetTree.images.get(name, -1) if parent is None: parent = parent.item = self.GetRootItem() index = 0 item, cookie = self.GetFirstChild(parent.item) while item.IsOk(): item_pos = self.GetPyData(item).widget.pos if pos < item_pos: break index += 1 item, cookie = self.GetNextChild(parent.item, cookie) Tree.insert(self, child, parent, index) child.item = self.InsertItemBefore(parent.item, index, self._build_label(child), image_index) self.SetPyData(child.item, child) if self.auto_expand: self.Expand(parent.item) self.select_item(child) child.widget.show_properties() self.app.check_codegen(child.widget) def remove(self, node=None): self.app.saved = False # update the status of the app Tree.remove(self, node) if node is not None: try: self.cur_widget = None self.SelectItem(node.parent.item) except: self.SelectItem(self.GetRootItem()) self.Delete(node.item) else: wx.TreeCtrl.Destroy(self) def clear(self): self.app.reset() self.skip_select = True if self.root.children: while self.root.children: c = self.root.children[-1] if c.widget: c.widget.remove() self.root.children = None self.skip_select = False app = self.GetPyData(self.GetRootItem()) app.widget.show_properties() def refresh_name(self, node, oldname=None): #, name=None): if oldname is not None: try: #del self.names[self.GetItemText(node.item)] del self.names[self._find_toplevel(node)][oldname] except KeyError: pass #self.names[name] = 1 #self.SetItemText(node.item, name) #self.names[node.widget.name] = 1 self.names.setdefault(self._find_toplevel(node), {})[ node.widget.name] = 1 self.SetItemText(node.item, self._build_label(node)) def select_item(self, node): self.skip_select = True self.SelectItem(node.item) self.skip_select = False if self.cur_widget: self.cur_widget.update_view(False) self.cur_widget = node.widget self.cur_widget.update_view(True) self.cur_widget.show_properties() misc.focused_widget = self.cur_widget def on_change_selection(self, event): if not self.skip_select: item = event.GetItem() try: if self.cur_widget: self.cur_widget.update_view(False) self.cur_widget = self.GetPyData(item).widget misc.focused_widget = self.cur_widget self.cur_widget.show_properties(None) self.cur_widget.update_view(True) except AttributeError: pass except Exception: common.message.exception(_('Internal Error')) def popup_menu(self, event): node = self._find_item_by_pos(*event.GetPosition()) if not node: return else: self.select_item(node) item = node.widget if not item.widget or not item.is_visible(): #import edit_windows #if isinstance(item, edit_windows.TopLevelBase): if node.parent is self.root: self._show_menu.SetTitle(item.name) self.PopupMenu(self._show_menu, event.GetPosition()) return try: x, y = self.ClientToScreen(event.GetPosition()) x, y = item.widget.ScreenToClient((x, y)) event.m_x, event.m_y = x, y item.popup_menu(event) except AttributeError: common.message.exception(_('Internal Error')) def expand(self, node=None, yes=True): """\ expands or collapses the given node """ if node is None: node = self.root if yes: self.Expand(node.item) else: self.Collapse(node.item) def set_title(self, value): if value is None: value = "" self.title = value try: self.GetParent().SetTitle(_('wxGlade: Tree %s') % value) except: pass def get_title(self): if not self.title: self.title = ' ' return self.title def show_widget(self, node, toplevel=False): """\ Shows the widget of the given node and all its children """ if toplevel: if not wx.IsBusy(): wx.BeginBusyCursor() if not node.widget.widget: node.widget.create_widget() node.widget.finish_widget_creation() if node.children: for c in node.children: self.show_widget(c) node.widget.post_load() node.widget.show_widget(True) node.widget.show_properties() node.widget.widget.Raise() # set the best size for the widget (if no one is given) props = node.widget.properties if 'size' in props and not props['size'].is_active() and \ node.widget.sizer: node.widget.sizer.fit_parent() if wx.IsBusy(): wx.EndBusyCursor() else: import edit_sizers def show_rec(node): node.widget.show_widget(True) self.expand(node, True) if node.children: for c in node.children: show_rec(c) node.widget.post_load() ## w = node.widget ## if isinstance(w, edit_sizers.SizerBase): return ## elif not w.properties['size'].is_active() and \ ## w.sizer and w.sizer.toplevel: ## w.sizer.fit_parent() show_rec(node) def show_toplevel(self, event): """\ Event handler for left double-clicks: if the click is above a toplevel widget and this is hidden, shows it """ try: x, y = event.GetPosition() except AttributeError: # if we are here, event is a CommandEvent and not a MouseEvent node = self.GetPyData(self.GetSelection()) self.expand(node) # if we are here, the widget must be shown else: node = self._find_item_by_pos(x, y, True) if node is not None: if not node.widget.is_visible(): # added by rlawson to expand node on showing top level widget self.expand(node) self.show_widget(node, True) else: node.widget.show_widget(False) #self.select_item(self.root) # added by rlawson to collapse only the toplevel node, # not collapse back to root node self.select_item(node) self.app.show_properties() event.Skip() #event.Skip() def _find_item_by_pos(self, x, y, toplevels_only=False): """\ Finds the node which is displayed at the given coordinates. Returns None if there's no match. If toplevels_only is True, scans only root's children """ item, flags = self.HitTest((x, y)) if item and flags & (wx.TREE_HITTEST_ONITEMLABEL | wx.TREE_HITTEST_ONITEMICON): node = self.GetPyData(item) if not toplevels_only or node.parent is self.root: return node return None def change_node(self, node, widget): Tree.change_node(self, node, widget) self.SetItemImage(node.item, self.images.get( widget.__class__.__name__, -1)) self.SetItemText(node.item, self._build_label(node)) #widget.name) def change_node_pos(self, node, new_pos): if new_pos >= self.GetChildrenCount(node.parent.item, False): return index = node.parent.children.index(node) Tree.change_node_pos(self, node, new_pos, index) old_item = node.item image = self.GetItemImage(node.item) self.Freeze() #print self._build_label(node), index, new_pos if index >= new_pos: node.item = self.InsertItemBefore( node.parent.item, new_pos, self._build_label(node), image) else: node.item = self.InsertItemBefore( node.parent.item, new_pos+1, self._build_label(node), image) self.SetPyData(node.item, node) def append(parent, node): idx = WidgetTree.images.get(node.widget.__class__.__name__, -1) node.item = self.AppendItem(parent.item, self._build_label(node), idx) self.SetPyData(node.item, node) if node.children: for c in node.children: append(node, c) self.Expand(node.item) if node.children: for c in node.children: append(node, c) self.Expand(node.item) self.Delete(old_item) self.Thaw() def get_selected_path(self): """\ returns a list of widget names, from the toplevel to the selected one Example: ['frame_1', 'sizer_1', 'panel_1', 'sizer_2', 'button_1'] if button_1 is the currently selected widget. """ from edit_sizers import SizerBase ret = [] w = self.cur_widget oldw = None while w is not None: oldw = w ret.append(w.name) sizer = getattr(w, 'sizer', None) if getattr(w, 'parent', "") is None: w = w.parent elif sizer is not None and not sizer.is_virtual(): w = sizer else: if isinstance(w, SizerBase): w = w.window else: w = w.parent ret.reverse() # ALB 2007-08-28: remember also the position of the toplevel window in # the selected path if oldw is not None: assert oldw.widget pos = misc.get_toplevel_parent(oldw.widget).GetPosition() ret[0] = (ret[0], pos) return ret def select_path(self, path): """\ sets the selected widget from a path_list, which should be in the form returned by get_selected_path """ index = 0 item, cookie = self._get_first_child(self.GetRootItem()) itemok = None parent = None pos = None while item.Ok() and index < len(path): widget = self.GetPyData(item).widget name = path[index] if index == 0 and type(name) == type(()): name, pos = name if misc.streq(widget.name, name): #print 'OK:', widget.name #self.EnsureVisible(item) itemok = item if parent is None: parent = self.GetPyData(itemok) self.cur_widget = widget item, cookie = self._get_first_child(item) index += 1 else: #print 'NO:', widget.name item = self.GetNextSibling(item) if itemok is not None: node = self.GetPyData(itemok) if parent is not None: self.show_widget(parent, True) if pos is not None: misc.get_toplevel_parent(parent.widget).SetPosition(pos) self.select_item(node) def _get_first_child(self, item): return self.GetFirstChild(item) # end of class WidgetTree wxglade-0.6.8.orig/config.py0000644000175000017500000001636112150154266016145 0ustar georgeskgeorgesk""" Configuration related stuff @see: L{configdialog} @copyright: 2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import general python modules import os.path import sys from ConfigParser import * import common import misc # default configuration values default_encoding = 'UTF-8' """\ Default value for encoding @type: String """ default_indent_amount = 4 """\ Default value for indentation @type: Integer """ default_indent_symbol = ' ' """\ Default value for indentation symbol @type: String """ default_multiple_files = 0 """\ Default value for writing multiple files (each class in a separate file) @type: Integer """ default_overwrite = 1 """\ Default value for overwriting existing sources @type: Integer """ default_use_gettext = 1 """\ Default value to usage of gettext @type: Integer """ def _get_home(default=common.wxglade_path): h = os.path.expanduser('~') if h not in ('~', '%USERPROFILE%'): return h if os.name == 'nt' and h == '%USERPROFILE%': return os.environ.get('USERPROFILE', default) return default def _get_appdatapath(default=common.wxglade_path): if os.name == 'nt': result = os.environ.get('APPDATA') if result: return result return _get_home(default) class Preferences(ConfigParser): _has_home = os.path.expanduser('~') != '~' _defaults = { 'use_menu_icons': common.use_gui and common.platform != '__WXGTK__', 'frame_tool_win': True, 'open_save_path': _get_home(), 'codegen_path': _get_home(), 'use_dialog_units': False, 'number_history': 4, 'show_progress': True, 'wxg_backup': True, 'codegen_backup': True, 'backup_suffix': sys.platform == 'win32' and '.bak' or '~', 'buttons_per_row': 5, 'remember_geometry': False, 'local_widget_path': (_get_appdatapath('') and \ os.path.join(_get_appdatapath(), '.wxglade', 'widgets') or ''), 'default_border' : False, 'default_border_size' : 3, 'show_sizer_handle': True, 'allow_duplicate_names': False, 'autosave': True, 'autosave_delay': 120, # in seconds 'use_kde_dialogs': False, 'show_completion': True, 'write_timestamp': True, 'write_generated_from': False, } def __init__(self, defaults=None): self.def_vals = defaults if self.def_vals is None: self.def_vals = Preferences._defaults self.changed = False ConfigParser.__init__(self) #self.default_border_size = 3 def __getattr__(self, attr): val = self.def_vals.get(attr, "") # UGLY!!! cast = type(val) if cast is bool: cast = self._cast_to_bool # ...but I haven't found a better way: the problem is that # bool('0') == True, while int('0') == False, and we want the # latter behaviour try: return cast(self.get('wxglade', attr)) except (NoOptionError, ValueError): return val def __iter__(self): def do_iter(): for key in self.def_vals: yield key, self[key] return do_iter() def _cast_to_bool(self, val): try: return int(val) except ValueError: val = val.lower().strip() if val in ('true', 'on'): return 1 elif val in ('false', 'off'): return 0 else: raise def __getitem__(self, attr): return self.__getattr__(attr) def __setitem__(self, attr, val): self.set('wxglade', attr, str(val)) self.changed = True def set_geometry(self, name, geometry): if geometry is not None: section = 'geometry_%s' % name if not self.has_section(section): self.add_section(section) self.set(section, 'x', geometry[0]) self.set(section, 'y', geometry[1]) self.set(section, 'w', geometry[2]) self.set(section, 'h', geometry[3]) def get_geometry(self, name): section = 'geometry_%s' % name if self.has_section(section): x = self.get(section, 'x') y = self.get(section, 'y') w = self.get(section, 'w') h = self.get(section, 'h') return (x, y, w, h) else: return None # end of class Preferences preferences = None if sys.platform == 'win32': _rc_name = 'wxglade.ini' else: _rc_name = 'wxgladerc' _use_file_history = False if common.use_gui: _use_file_history = True def init_preferences(): global preferences if preferences is None: preferences = Preferences() h = _get_appdatapath('') search_path = [os.path.join(common.wxglade_path, _rc_name)] if h: search_path.append(os.path.join(h, '.wxglade', _rc_name)) if 'WXGLADE_CONFIG_PATH' in os.environ: search_path.append( os.path.expandvars('$WXGLADE_CONFIG_PATH/%s' % _rc_name)) preferences.read(search_path) if not preferences.has_section('wxglade'): preferences.add_section('wxglade') def save_preferences(): # let the exception be raised if 'WXGLADE_CONFIG_PATH' in os.environ: path = os.path.expandvars('$WXGLADE_CONFIG_PATH') else: path = _get_appdatapath() if path != common.wxglade_path: path = os.path.join(path, '.wxglade') if not os.path.isdir(path): os.makedirs(path) # always save the file history if _use_file_history: fh = common.palette.file_history count = fh.GetCount() encoding = 'utf-8' filenames = [common._encode_to_xml(fh.GetHistoryFile(i), encoding) for i in range(min(preferences.number_history, count))] outfile = open(os.path.join(path, 'file_history.txt'), 'w') print >> outfile, "# -*- coding: %s -*-" % encoding for filename in filenames: print >> outfile, filename outfile.close() if preferences.changed: outfile = open(os.path.join(path, _rc_name), 'w') # let the exception be raised to signal abnormal behaviour preferences.write(outfile) outfile.close() def load_history(): """\ Loads the file history and returns a list of paths """ if 'WXGLADE_CONFIG_PATH' in os.environ: path = os.path.expandvars('$WXGLADE_CONFIG_PATH') else: path = _get_appdatapath() if path != common.wxglade_path: path = os.path.join(path, '.wxglade') try: history = open(os.path.join(path, 'file_history.txt')) l = history.readlines() if l and l[0].startswith('# -*- coding:'): try: encoding = 'utf-8' #l = [common._encode_from_xml(e, encoding) for e in l[1:]] l = [e.decode(encoding) for e in l[1:]] except Exception, e: print _("ERR:"), e l = l[1:] history.close() if common.use_gui: l = [misc.wxstr(e, 'utf-8') for e in l] return l except IOError: # don't consider this an error return [] wxglade-0.6.8.orig/edit_widget.py0000644000175000017500000001027312060442727017166 0ustar georgeskgeorgesk# edit_widget.py: base class for EditFoo objects # # Copyright (c) 2002-2004 Richard Lawson # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, config from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditWidget(ManagedBase): def __init__(self, name, klass, parent, id, label, sizer, pos, property_window, show=True): """\ Class to handle wxFoo objects """ self.label = label self.default = False ManagedBase.__init__(self, name, klass, parent, id, sizer, pos, property_window, show=show) # introspect subclass looking for properties # and widgets self.property_names = [] self.property_proportion = {} attrs = dir(self) for attr in attrs: prefix = attr[0:4] if prefix == 'get_': getter = attr #print 'found getter ', getter # extract the property name prefix, name = attr.split('_', 1) #print 'getter ', name # check for a setter setter = 'set_%s' % name if not hasattr(self, setter): #print 'no setter for %s, skipping ' % name continue # check for a get_name_widget getter_widget = 'get_%s_widget' % name if not hasattr(self, getter_widget): #print 'no widget getter for %s, skipping ' % name continue #print 'adding property: %s' % name self.property_names.append(name) self.access_functions[name] = (getattr(self, getter), getattr(self, setter)) prop = getattr(self, getter_widget)() try: prop, proportion = prop except TypeError: proportion = 0 self.properties[name] = prop self.property_proportion[name] = proportion def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) szr = wx.BoxSizer(wx.VERTICAL) for name in self.property_names: self.properties[name].display(panel) szr.Add(self.properties[name].panel, self.property_proportion[name], wx.EXPAND) panel.SetAutoLayout(1) panel.SetSizer(szr) szr.Fit(panel) w, h = panel.GetClientSize() self.notebook.AddPage(panel, 'Widget') import math panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) # end of class EditWidget def increment_label(label, number=[1]): _label = '%s_%d' % (label, number[0]) while common.app_tree.has_name(_label): number[0] += 1 _label = '%s_%d' % (label, number[0]) return _label def add_widget_node(widget, sizer, pos, from_xml=False, option=0, flag=0, border=0): node = Tree.Node(widget) widget.node = node if not border and config.preferences.default_border: flag |= wx.ALL border = config.preferences.default_border_size if option: widget.set_option(option) if flag: widget.set_int_flag(flag) if border: widget.set_border(border) if not from_xml: widget.show_widget(True) sizer.set_item(widget.pos, option, flag, border) if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) def get_label_from_xml(attrs): from xml_parse import XmlParsingError try: return attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") def initialize(edit_klass, builder, xml_builder, icon_path): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets[edit_klass] = builder common.widgets_from_xml[edit_klass] = xml_builder return common.make_object_button(edit_klass, icon_path) wxglade-0.6.8.orig/PKG-INFO0000644000175000017500000000146012170277707015425 0ustar georgeskgeorgeskMetadata-Version: 1.1 Name: wxGlade Version: 0.6.8 Summary: GUI designer written in Python with the popular GUI toolkit wxPython Home-page: http://wxglade.sourceforge.net/ Author: Alberto Griggio Author-email: agriggio@users.sourceforge.net License: MIT License Description: UNKNOWN Platform: WIN32 Platform: OSX Platform: POSIX Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Natural Language :: English Classifier: Operating System :: OS Independent (Written in an interpreted language) Classifier: Programming Language :: Python :: 2 Classifier: Topic :: Software Development :: Code Generators Classifier: User Interface :: Textual :: Command-line Classifier: User Interface :: Toolkits/Libraries :: wxWidgets wxglade-0.6.8.orig/NEWS.txt0000644000175000017500000002273012167341675015652 0ustar georgeskgeorgeskVersion 0.6.8 - 2013-07-13: General: - Add comfortable exception handler for more detailed bug reports Bugs: - Wrong SetSizeHint() call in Perl (Thanks to Eric McKeeth) - Fix XRC code generation for notebooks with panes - Fix too strict sanity checks for class attributes - Fix "Overwrite existing sources" for new projects - Fix an uninitialised variable in saving a project file (sf bug # 157) - Fix handling of unicode characters in strings for Perl and Python - Fix handling of style-less dialogs and frames (sf bug #145) Documentation: - minor changes API (for custom widgets): - no changes Version 0.6.7 - 2013-04-07: General: - Add a config option to suppress the code generation success message - Improve usability of some dialogs Bugs: - Remove empty line between shebang and encoding statement in Python files - Regression in generated Python code for bindung events Documentation: - no changes API (for custom widgets): - no changes Note: - See CHANGES.txt for a full list of changes Version 0.6.6 - 2013-03-29: General: - Add i18n support to C++ code generator - Add more test cases - Add more tooltips to gui - Add new widget HyperlinkCtrl - Add Perl support to CalendarCtrl - Add simple application start code to C++ code generator - Add "Store as attribute" for sizers - Change default widget ID from -1 to wxID_ANY and adapt codegen - Change some default settings and reorg internal handling - Fix exceptions during widget preview triggered by keyboard shortcut - Improve error handling - Improve message logging - Internal rework of code generator parts, this causes minor changes in the generated code - Join code templates for application startup code in class variables and unify the code generation of this piece - Minor GUI improvements - Rework and unify code generators, all code generators support extracode and extraproperties now - Set "Overwrite existing sources" for new projects - Show existing tooltips at all elements of a property - When pasting: only search current top-level window for duplicate names - Write isolation directives at beginning in C++ header files Bugs: - Don't add unsupported widgets to a sizer - Encoding detection for Mac OS X - Prevent caching effects in Lisp code generator - Prevent deleting last notebook tab (sf bug #3126974) - Same default names for multiple notebooks (sf bug #2000566) - Setting invalid windows names hasn't blocked fully (sf bug #154) - String formatting issue for event handlers in Lisp code generator - UnicodeEncodeError in xml.sax.expatreader (sf bug #149) Documentation: - Update wxGlade user manual API (for custom widgets): - Add support for widget builder that don't support all wx versions supported by wxGlade Note: - See CHANGES.txt for a full list of changes Version 0.6.5 - 2012-01-08: General: - remove support for Python 2.2 - remove support for wxPython < 2.6 - add a small test suite - add tooltip for CheckBoxProperty (Davorin Kunstelj) - add column sizes parameter to GridProperty init parameters (Davorin Kunstelj) - Improve searching and executeing of wxglade.py in shell script wxglade - some minor changes / improvements Bugs: - Various bugs in Lisp code generators - Typo in Perl code generators - Allow saving of generated code to filenames without directory part - Solve issue "C++ CalendarControl issues in 0.6.3" (sf bug #2782306) Documentation: - Update usage message and manpage API (for custom widgets): - no changes Note: - See CHANGES.txt for a full list of changes Version 0.6.4 till version 0.5: No summary of changes available - see CHANGES.txt for a full list of changes Version 0.5 - 2007-04-02: - with some improvements - code ported to the "new" wx namespace - wxWidgets 2.8 support - and more... Version 0.4.1 - 2006-03-02: - Note that this file isn't very much up to date anymore... Version 0.4 - 2005-10-10: - edit_sizers/edit_sizers.py: updated layout() to work with wx2.6 - widgets/frame/frame.py: fixed a segfault when deleting a frame with a statusbar on wx2.6 - widgets/notebook/notebook.py: updated notebook virtual sizer to fix broken layout on wx2.6 - edit_windows.py: fixed property_panel layout which was broken on wx2.6 - tree.py: - added wxBegin/EndBusyCursor() calls when showing a toplevel widget - called fit_parent at the end of show_widget for toplevel widgets without a specific size - added event handlers support (not for perl at the moment) - better sizers layout - many bugs fixed - updated copyright information - ... Version 0.3.5.1 - 2004-11-08: - released, due to a bug in version 0.3.5 (size property not updating correctly) Version 0.3.5 - 2004-11-04: - kdefiledialog.py: support for native file and dir dialogs on KDE - debian/: support for Debian package (by Georges Khaznadar) - common.py, config.py, configUI.py, main.py, res/preferences.wxg: auto save support (i.e. now wxg files can be saved automatically periodically) - edit_sizers/sizers_codegen.py, edit_sizers/perl_sizers_codegen.py, codegen/*.py: fixed issue with wxStaticBoxSizer code generation - edit_sizers/edit_sizers.py, edit_windows.py: fixed segfault on wxGTK2 when removing a widget from the popup menu - *.py: updated copyright information Version 0.3.4.1 - 2004-09-04: - introduce of a workaround for a bug in wxPython 2.5.2.8 (about wxGrid and its default size...) Version 0.3.4 - 2004-09-01: - common.py: minor UI tweak - edit_windows.py, config.py, configUI.py: added `show "handles" of sizers' option added `allow duplicate widget names' option - widgets/menubar/codegen.py: changed python code generator to be smarter about menu items with a user defined name - edit_windows.py, widget_properties.py: fixed a couple of wxMac issues - widgets/frame/codegen.py: added xrc code generator for wxStatusBar - widgets/choice/choice.py, widgets/combo_box/combo_box.py, widgets/list_box/list_box.py: removed default entry in Choices property - widgets/combo_box/codegen.py, widgets/spin_ctrl/codegen.py: applied patch #944642 - widgets/list_ctrl/list_ctrl.py: added a couple of extra styles - widgets/button/*: added wxButton styles - widgets/panel/panel.py: fixed (hopefully) bug #880674 - clipboard.py, main.py: added Drag&Drop of wxg files for opening them (thanks to Chris Liechti) - main.py, docs/index.html, docs/html/*: new manual added - config.py: config path is now under APPDATA ok windows - widgets/bitmap_button/*, widgets/toolbar/*, widgets/static_bitmap/*: added "code:" tag - xrc2wxg.py: added wxSplitterWindow support - tree.py: partially fixed bug #798041 (renaming of cut widgets) - widgets/panel/panel.py: added ability to paste a sizer inside a panel, notebook page and splitter pane - codegen/py_codegen.py, widgets/*/codegen.py, edit_sizers/sizers_codegen.py: changes to the python code generator to support new wx namespace Version 0.3.1 - 2003-08-30: - we found an annoying bug on pl_codegen.py right after releasing 0.3 :-( Version 0.3 - 2003-08-29: - codegen/pl_codegen.py, toolbar/perl_codegen.py, menubar/perl_codegen.py: brought Perl code generator up to date: - multiple files support - ``keep contents'' support - automatic ids generation (ID_FOO=?) support everything is still *experimental* and NEEDS EXTENSIVE TESTING - widgets/toolbar/codegen.py, widgets/bitmap_button/codegen.py, widgets/static_bitmap/codegen.py: added (limited) support to xpm data (not on files). I.e. if the bitmap property is something like var:variable_name, variable_name is taken to be a variable that holds xpm data - codegen/xrc_codegen.py, xml_parse.py, docs/turorial.html: added subclass support to XRC output - application.py, tree.py, xml_parse.py, codegen/py_codegen.py, codegen/cpp_codegen.py: added "overwrite" property to Application, to allow re-generation of (C++ and python) code from scratch (as opposed to updating wxGlade blocks). - docs/tutorial.html: updated notes - codegen/py_codegen.py, codegen/cpp_codegen.py: enhanced generate_code_id, to recognize ID_SOMETHING=? and generate a "unique" id automatically - codegen/cpp_codegen.py: fixed ids code generation when the output file already exists - widgets/toolbar.py: fixed xrc code generation - common.py: updated version number to 0.3pre1 - edit_windows.py, application.py: added validation code for `name' and `class' properties (fixed bug #764186) - credits.txt: updated developer names - codegen/py_codegen.py, codegen/cpp_codegen.py: fixed bug in quote_str - tree.py, widgets/panel/*: added scrolled window support (this required a small change in Tree.Node.write in tree.py) - perl generation support added - nearly all around: fixed various Unicode-related bugs - misc.py added functions, streq and wxstr, to fix some Unicode issues - edit_windows.py, edit_sizers/edit_sizers.py, xml_parse.py: added cut&paste support for toplevel sizers - common.py, main.py: added ToggleButtonBox to separate the "core" components from the "custom" ones (similar to Glade and QT-Designer) - common.py, config.py: added local widgets path support See VCS revision history for change details of older version. Check especially revisions of CHANGES.txt earlier then December 2011 wxglade-0.6.8.orig/layout_option_property.py0000644000175000017500000001276112150154266021551 0ustar georgeskgeorgesk""" Property class for the 'option' layout property of widgets and non-toplevel sizers. @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import wx import widget_properties #from edit_sizers import EditGridBagSizer def _is_gridbag(dummy): return False class LayoutOptionProperty(widget_properties.Property): def __init__(self, owner, sizer, parent=None): self.is_gridbag = _is_gridbag(sizer) widget_properties.Property.__init__(self, owner, 'option', parent) self.panel = None if parent is not None: self.display(parent) self.val = owner['option'][0]() def display(self, parent): if not self.is_gridbag: self._display_spin(parent) def _display_spin(self, parent): """\ Actually builds the spin control to set the value of the property interactively """ self.id = wx.NewId() self.val_range = (0, 1000) size = (widget_properties._label_initial_width, -1) label = widget_properties.wxGenStaticText(parent, -1, _('Proportion'), size=size) self.spin = wx.SpinCtrl(parent, self.id, min=self.val_range[0], max=self.val_range[1]) val = int(self.owner[self.name][0]()) if not val: self.spin.SetValue(1) # needed for GTK to display a '0' self.spin.SetValue(val) #int(self.owner[self.name][0]())) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 2, wx.ALL|wx.ALIGN_CENTER, 3) option = 5 sizer.Add(self.spin, option, wx.ALL|wx.ALIGN_CENTER, 3) self.panel = sizer self.bind_event(self.on_change_val) def _display_gridbag(self, parent): sizer = wx.BoxSizer(wx.VERTICAL) size = (widget_properties._label_initial_width, -1) val = self.owner[self.name][0]() szr = wx.BoxSizer(wx.HORIZONTAL) label = widget_properties.wxGenStaticText(parent, -1, _('Position'), size=size) szr.Add(label, 2, wx.ALL|wx.ALIGN_CENTER, 3) self.position = wx.TextCtrl(parent, -1) self.position.SetValue(val[:2]) szr.Add(self.position, 5, wx.ALL|wx.ALIGN_CENTER, 3) sizer.Add(szr, 0, wx.EXPAND) szr = wx.BoxSizer(wx.HORIZONTAL) label = widget_properties.wxGenStaticText(parent, -1, _('Span'), size=size) szr.Add(label, 2, wx.ALL|wx.ALIGN_CENTER, 3) self.span = wx.TextCtrl(parent, -1) self.span.SetValue(val[2:]) szr.Add(self.span, 5, wx.ALL|wx.ALIGN_CENTER, 3) sizer.Add(szr, 0, wx.EXPAND) self.panel = sizer self.bind_event(self.on_change_val) def bind_event(self, function): if not self.is_gridbag: self._bind_event_spin(function) else: self._bind_event_gridbag(function) def _bind_event_spin(self, function): def func_2(event): if self.spin.IsBeingDeleted(): return function(event) wx.EVT_KILL_FOCUS(self.spin, func_2) if wx.Platform == '__WXMAC__': wx.EVT_TEXT(self.spin, self.spin.GetId(), func_2) wx.EVT_SPINCTRL(self.spin, self.spin.GetId(), func_2) def _bind_event_gridbag(self, function): def func_2(event): if self.position.IsBeingDeleted(): return function(event) wx.EVT_KILL_FOCUS(self.position, func_2) def func_3(event): if self.span.IsBeingDeleted(): return function(event) wx.EVT_KILL_FOCUS(self.span, func_3) def get_value(self): if not self.is_gridbag: try: return self.spin.GetValue() except AttributeError: return self.val else: try: return ", ".join([self.position.GetValue(), self.span.GetValue()]) except AttributeError: return self.val def set_value(self, value): if not self.is_gridbag: self.val = int(value) try: self.spin.SetValue(int(value)) except AttributeError: pass else: self.val = value try: self.position.SetValue(value[:2]) self.span.SetValue(value[2:]) except AttributeError: pass def set_range(self, min_v, max_v): if not self.is_gridbag: self.val_range = (min_v, max_v) try: self.spin.SetRange(min_v, max_v) except AttributeError: pass def set_sizer(self, sizer): self.is_gridbag = _is_gridbag(sizer) # end of class LayoutOptionProperty class LayoutPosProperty(widget_properties.SpinProperty): def __init__(self, owner, sizer, parent=None): self.is_gridbag = _is_gridbag(sizer) widget_properties.SpinProperty.__init__( self, owner, 'pos', parent, 0, (0, 1000))#, immediate=True) self.label = _('Position') def set_sizer(self, sizer): self.is_gridbag = _is_gridbag(sizer) def display(self, parent): if not self.is_gridbag: widget_properties.SpinProperty.display(self, parent) else: self.panel = (0, 0) def write(self, *args, **kwds): pass # end of class LayoutPosProperty wxglade-0.6.8.orig/edit_windows.py0000644000175000017500000014203512150154266017375 0ustar georgeskgeorgesk""" Base classes for windows used by wxGlade @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import general python modules import math import re import wx try: set except NameError: from sets import Set as set # import project modules from widget_properties import * import misc import common import config # event handling support from events_mixin import EventsMixin class EditBase(EventsMixin): """\ Base class of every window available in the builder. @ivar custom_class: If true, the user can chage the value of the 'class' property @ivar name: Name of the object @ivar klass: Name of the object's class @ivar property_window: Widget inside which Properties of this object are displayed @ivar widget: This is the reference to the actual wxWindow widget; it is created only if needed, i.e. when it should become visible @ivar _rmenu: Popup menu """ def __init__(self, name, klass, parent, id, property_window, show=True, custom_class=True): """\ Dictionary of properties relative to this object; the properties that control the layout (i.e. the behaviour when inside a sizer) are not contained here, but in a separate list (see L{ManagedBase}) the keys of the dict are the names of the properties @param property_window: Widget inside which Properties of this object are displayed @param name: Name of the object @param klass: Name of the object's class @param custom_class: If true, the user can chage the value of the 'class' property """ self.properties = {} self.property_blocking = {} self.parent = parent # id used for internal purpose events self.id = id self.name = name self.klass = klass self.base = klass self.custom_class = custom_class self._dont_destroy = False self.access_functions = { 'name' : (lambda : self.name, self.set_name), 'class' : (lambda : self.klass, self.set_klass) } # these two properties are special and are not listed in # 'self.properties' self.name_prop = TextProperty(self, 'name', None, label=_("name")) self.name_prop.tooltip = _("Name of the variable for assigning " \ "the reference to the created widget " \ "instance.") self.klass_prop = TextProperty(self, 'class', None, readonly=not custom_class, label=_("class")) if custom_class: self.klass_prop.tooltip = _("If you change the default value, " \ "it will be interpreted as the name " \ "of the subclass of the widget. " \ "How this name affects code generation "\ "depends on the kind (i.e. language) " \ "of output. See the docs for " \ "more details.") # ALB 2007-08-31: custom base classes support if getattr(self, '_custom_base_classes', False): self.custom_base = "" def get_custom_base(): return self.custom_base def set_custom_base(val): self.custom_base = val self.access_functions['custom_base'] = (get_custom_base, set_custom_base) p = self.properties['custom_base'] = TextProperty( self, 'custom_base', can_disable=True, enabled=False) p.label = _('Base class(es)') p.tooltip = _("""\ A comma-separated list of custom base classes. The first will be invoked \ with the same parameters as this class, while for the others the default \ constructor will be used. You should probably not use this if \ "overwrite existing sources" is not set.""") self.notebook = None self.property_window = property_window # popup menu self._rmenu = None # this is the reference to the actual wxWindow widget; it is created # only if needed, i.e. when it should become visible self.widget = None if show: self.show_widget(True) property_window.SetSize((250, 340)) property_window.Show(True) # ALB 2004-12-05 EventsMixin.__init__(self) # code property import code_property self.properties['extracode'] = code_property.CodeProperty(self) self.properties['extraproperties'] = code_property.ExtraPropertiesProperty(self) def show_widget(self, yes): if yes and self.widget is None: self.create_widget() self.finish_widget_creation() if self.widget: self.widget.Show(yes) def create_widget(self): """\ Initializes self.widget and shows it """ raise NotImplementedError def finish_widget_creation(self, *args, **kwds): """\ Creates the popup menu and connects some event handlers to self.widgets """ wx.EVT_RIGHT_DOWN(self.widget, self.popup_menu) def delete(self): """\ Destructor. Deallocates the popup menu, the notebook and all the properties. Why we need explicit deallocation? Well, basically because otherwise we get a lot of memory leaks... :) """ # first, destroy the popup menu... if wx.Platform != '__WXMAC__': if self._rmenu: self._rmenu.Destroy() # ...then, destroy the property notebook... if self.notebook: nb_szr = self.notebook.sizer self.notebook.DeleteAllPages() self.notebook.Destroy() if nb_szr is not None: nb_szr.Destroy() # ...finally, destroy our widget (if needed) if self.widget and not self._dont_destroy: self.widget.Destroy() if misc.focused_widget is self: misc.focused_widget = None def create_properties(self): """\ Creates the notebook with the properties of self """ self.notebook = wx.Notebook(self.property_window, -1) self.notebook.sizer = None self.notebook.SetAutoLayout(True) self.notebook.Hide() self._common_panel = panel = wx.ScrolledWindow( self.notebook, -1, style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE) self.name_prop.display(panel) self.klass_prop.display(panel) if getattr(self, '_custom_base_classes', False): self.properties['custom_base'].display(panel) def __getitem__(self, value): return self.access_functions[value] def set_name(self, value): value = "%s" % value if not config.preferences.allow_duplicate_names and \ (self.widget and common.app_tree.has_name(value, self.node)): wx.CallAfter( wx.MessageBox, _('Name "%s" is already in use.\n' 'Please enter a different one.') % value, _("Error"), wx.OK|wx.ICON_ERROR) self.name_prop.set_value(self.name) return if not re.match(self.set_name_pattern, value): wx.CallAfter( wx.MessageBox, _( 'The new name "%s" contains invalid characters. The\n' 'old name "%s" will be retain.\n' '\n' 'Valid characters are alphanumeric characters, minus sign\n' 'and the underscore. Names start always with an alphabetic\n' 'character or an underscore.\n' '\n' 'Please enter a different name.') % (value, self.name), _("Error"), wx.OK|wx.ICON_ERROR) self.name_prop.set_value(self.name) else: oldname = self.name self.name = value if self._rmenu: self._rmenu.SetTitle(self.name) try: common.app_tree.refresh_name(self.node, oldname) #, self.name) except AttributeError: pass self.property_window.SetTitle(_('Properties - <%s>') % self.name) set_name_pattern = re.compile(r'^[a-zA-Z_]+[\w-]*(\[\w*\])*$') def set_klass(self, value): value = "%s" % value if not re.match(self.set_klass_pattern, value): self.klass_prop.set_value(self.klass) else: self.klass = value try: common.app_tree.refresh_name(self.node) #, self.name) except AttributeError: pass set_klass_pattern = re.compile('^[a-zA-Z_]+[\w:.0-9-]*$') def popup_menu(self, event): if self.widget: if not self._rmenu: COPY_ID, REMOVE_ID, CUT_ID = [wx.NewId() for i in range(3)] self._rmenu = misc.wxGladePopupMenu(self.name) misc.append_item(self._rmenu, REMOVE_ID, _('Remove\tDel'), wx.ART_DELETE) misc.append_item(self._rmenu, COPY_ID, _('Copy\tCtrl+C'), wx.ART_COPY) misc.append_item(self._rmenu, CUT_ID, _('Cut\tCtrl+X'), wx.ART_CUT) self._rmenu.AppendSeparator() PREVIEW_ID = wx.NewId() misc.append_item(self._rmenu, PREVIEW_ID, _('Preview')) def bind(method): return lambda e: wx.CallAfter(method) wx.EVT_MENU(self.widget, REMOVE_ID, bind(self.remove)) wx.EVT_MENU(self.widget, COPY_ID, bind(self.clipboard_copy)) wx.EVT_MENU(self.widget, CUT_ID, bind(self.clipboard_cut)) wx.EVT_MENU(self.widget, PREVIEW_ID, bind(self.preview_parent)) self.setup_preview_menu() self.widget.PopupMenu(self._rmenu, event.GetPosition()) def remove(self, *args): self._dont_destroy = False # always destroy when explicitly asked common.app_tree.remove(self.node) def setup_preview_menu(self): p = misc.get_toplevel_widget(self) if p is not None: item = list(self._rmenu.GetMenuItems())[-1] if p.preview_is_visible(): item.SetText(_('Close preview') + ' (%s)\tCtrl+P' % p.name) else: item.SetText(_('Preview') + ' (%s)\tCtrl+P' % p.name) def preview_parent(self): widget = misc.get_toplevel_widget(self) if widget is not None: widget.preview(None) def show_properties(self, *args): """\ Updates property_window to display the properties of self """ # Begin Marcello 13 oct. 2005 if self.klass == 'wxPanel': # am I a wxPanel under a wxNotebook? if self.parent and self.parent.klass == 'wxNotebook': #pdb.set_trace() nb = self.parent if nb.widget: i = 0 for tn, ep in nb.tabs: # tn=tabname, ep = editpanel try: if ep and self.name == ep.name: # If I am under this tab... nb.widget.SetSelection(i) # ...Show that tab. except AttributeError: pass i = i + 1 if self.parent and self.parent.klass == 'wxPanel': # am I a widget under a wxPanel under a wxNotebook? if self.parent.parent and self.parent.parent.klass == 'wxNotebook': #pdb.set_trace() nb = self.parent.parent if nb.widget: i = 0 for tn, ep in nb.tabs: # tn=tabname, ep = editpanel try: if ep and self.parent.name == ep.name: nb.widget.SetSelection(i) except AttributeError: pass i = i + 1 # End Marcello 13 oct. 2005 if not self.is_visible(): return # don't do anything if self is hidden # create the notebook the first time the function is called: this # allows us to create only the notebooks we really need if self.notebook is None: self.create_properties() # ALB 2004-12-05 self.create_events_property() self.create_extracode_property() sizer_tmp = self.property_window.GetSizer() #sizer_tmp = wxPyTypeCast(sizer_tmp, "wxBoxSizer") #child = wxPyTypeCast(sizer_tmp.GetChildren()[0], "wxSizerItem") child = sizer_tmp.GetChildren()[0] w = child.GetWindow() if w is self.notebook: return try: index = -1 title = w.GetPageText(w.GetSelection()) for i in range(self.notebook.GetPageCount()): if self.notebook.GetPageText(i) == title: index = i break except AttributeError, e: #print e index = -1 w.Hide() if 0 <= index < self.notebook.GetPageCount(): self.notebook.SetSelection(index) self.notebook.Reparent(self.property_window) child.SetWindow(self.notebook) w.Reparent(misc.hidden_property_panel) # ALB moved this before Layout, it seems to be needed for wx2.6... self.notebook.Show() self.notebook.SetSize(self.property_window.GetClientSize()) self.property_window.Layout() self.property_window.SetTitle(_('Properties - <%s>') % self.name) try: common.app_tree.select_item(self.node) except AttributeError: pass self.widget.SetFocus() def on_set_focus(self, event): """\ Event handler called when a window receives the focus: this in fact is connected to a EVT_LEFT_DOWN and not to an EVT_FOCUS, but the effect is the same """ self.show_properties() misc.focused_widget = self #if wxPlatform != '__WXMSW__': event.Skip() def get_property_handler(self, prop_name): """\ Returns a custom handler function for the property 'prop_name', used when loading this object from an xml file. handler must provide three methods: 'start_elem', 'end_elem' and 'char_data' """ # ALB 2004-12-05 return EventsMixin.get_property_handler(self, prop_name) def clipboard_copy(self, *args): """\ Returns a copy of self to be inserted in the clipboard """ import clipboard clipboard.copy(self) def clipboard_cut(self, *args): import clipboard clipboard.cut(self) def is_visible(self): if not self.widget: return False if not self.widget.IsShown(): return False if self.widget.IsTopLevel(): return self.widget.IsShown() parent = self.parent if parent: return parent.is_visible() return self.widget.IsShown() def update_view(self, selected): """\ Updates the widget's view to reflect its state, i.e. shows which widget is currently selected; the default implementation does nothing. """ pass def post_load(self): """\ Called after the loading of an app from an XML file, before showing the hierarchy of widget for the first time. The default implementation does nothing. """ pass def create_extracode_property(self): try: self.properties['extracode']._show(self.notebook) self.properties['extraproperties']._show(self.notebook) except KeyError: pass def set_property_blocking(self, key, item): if self.property_blocking.has_key(key): self.property_blocking[key].append(item) else: self.property_blocking[key] = [item] def get_property_blocking(self, key): if self.property_blocking.has_key(key): return self.property_blocking[key] return None def remove_property_blocking(self, key, item): if self.property_blocking.has_key(key): for i in range(self.property_blocking[key].count(item)): self.property_blocking[key].remove(item) if not len(self.property_blocking[key]): del self.property_blocking[key] # end of class EditBase class WindowBase(EditBase): """\ Extends EditBase with the addition of the common properties available to almost every window: size, background and foreground colors, and font """ def __init__(self, name, klass, parent, id, property_window, show=True): EditBase.__init__(self, name, klass, parent, id, property_window, show=False) # 'property' id (editable by the user) self.window_id = "wxID_ANY" def set_id(value): self.window_id = value self.access_functions['id'] = (lambda s=self: s.window_id, set_id) self.size = '-1, -1' self.access_functions['size'] = (self.get_size, self.set_size) self.background = '' self.access_functions['background'] = (self.get_background, self.set_background) self.foreground = '' self.access_functions['foreground'] = (self.get_foreground, self.set_foreground) # this is True if the user has selected a custom font self._font_changed = False self.font = self._build_from_font(wx.SystemSettings_GetFont( wx.SYS_DEFAULT_GUI_FONT)) self.font[1] = 'default' self.access_functions['font'] = (self.get_font, self.set_font) # properties added 2002-08-15 self.tooltip = '' self.access_functions['tooltip'] = (self.get_tooltip, self.set_tooltip) self._original = {'background': None, 'foreground': None, 'font': None} prop = self.properties prop['id'] = TextProperty(self, 'id', None, can_disable=True) prop['id'].tooltip = _("""\ The "Id" property could be 1) a constant numeric value 2) a predefined identifier e.g. wxID_ANY 3) a predefined variable like a class member e.g. self.myButtonID 4) a variable assignment e.g. self.myButtonID=? The pattern of a variable assignment is always "variable=value". The \ value could be again a numeric value, a predefined identifier, \ another predefined variable or "?" a shortcut for "wxNewId()". \ """) prop['size'] = TextProperty(self, 'size', None, can_disable=True, label=_("size")) prop['background'] = ColorDialogProperty(self, "background", None, label=_("background")) prop['foreground'] = ColorDialogProperty(self, "foreground", None, label=_("foreground")) prop['font'] = FontDialogProperty(self, "font", None, label=_("font")) # properties added 2002-08-15 prop['tooltip'] = TextProperty(self, 'tooltip', None, can_disable=True, label=_('tooltip')) # properties added 2003-05-15 self.disabled_p = False self.access_functions['disabled'] = (self.get_disabled, self.set_disabled) prop['disabled'] = CheckBoxProperty(self, 'disabled', None, _('disabled')) self.focused_p = False self.access_functions['focused'] = (self.get_focused, self.set_focused) prop['focused'] = CheckBoxProperty(self, 'focused', None, _('focused')) self.hidden_p = False self.access_functions['hidden'] = (self.get_hidden, self.set_hidden) prop['hidden'] = CheckBoxProperty(self, 'hidden', None, _('hidden')) def finish_widget_creation(self, *args, **kwds): self._original['background'] = self.widget.GetBackgroundColour() self._original['foreground'] = self.widget.GetForegroundColour() fnt = self.widget.GetFont() if not fnt.Ok(): fnt = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) self._original['font'] = fnt prop = self.properties size = prop['size'].get_value() if size: #self.widget.SetSize([int(s) for s in size.split(',')]) self.set_size(size) else: prop['size'].set_value('%s, %s' % tuple(self.widget.GetSize())) if prop['background'].is_active(): self.set_background(prop['background'].get_value()) else: color = misc.color_to_string(self.widget.GetBackgroundColour()) self.background = color prop['background'].set_value(color) if prop['foreground'].is_active(): self.set_foreground(prop['foreground'].get_value()) else: color = misc.color_to_string(self.widget.GetForegroundColour()) self.foreground = color prop['foreground'].set_value(color) if prop['font'].is_active(): self.set_font(prop['font'].get_value()) EditBase.finish_widget_creation(self) wx.EVT_SIZE(self.widget, self.on_size) # after setting various Properties, we must Refresh widget in order to # see changes self.widget.Refresh() def on_key_down(event): evt_flags = 0 if event.ControlDown(): evt_flags = wx.ACCEL_CTRL evt_key = event.GetKeyCode() done = False for flags, key, function in misc.accel_table: if evt_flags == flags and evt_key == key: wx.CallAfter(function) done = True break if not done: event.Skip() wx.EVT_KEY_DOWN(self.widget, on_key_down) def create_properties(self): EditBase.create_properties(self) panel = self._common_panel prop = self.properties prop['id'].display(panel) prop['size'].display(panel) prop['background'].display(panel) prop['foreground'].display(panel) try: prop['font'].display(panel) except KeyError: pass prop['tooltip'].display(panel) prop['disabled'].display(panel) prop['focused'].display(panel) prop['hidden'].display(panel) sizer_tmp = wx.BoxSizer(wx.VERTICAL) sizer_tmp.Add(self.name_prop.panel, 0, wx.EXPAND) sizer_tmp.Add(self.klass_prop.panel, 0, wx.EXPAND) if getattr(self, '_custom_base_classes', False): sizer_tmp.Add(prop['custom_base'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['id'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['size'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['background'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['foreground'].panel, 0, wx.EXPAND) try: sizer_tmp.Add(prop['font'].panel, 0, wx.EXPAND) except KeyError: pass sizer_tmp.Add(prop['tooltip'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['disabled'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['focused'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['hidden'].panel, 0, wx.EXPAND) # add a note if the widget don't support all supported wx versions all_versions = set(common.app_tree.app.all_supported_versions) supported = set( [misc.format_for_version(version) \ for version in getattr(self, 'supported_by', [])] ) not_supported = all_versions.difference(supported) # hint text only if we have support information (supported_by) and # not all versions are supported (not_supported) if supported and not_supported: text_supported = ', '.join(supported) text_not_supported = ', '.join(not_supported) note = wx.StaticText( panel, -1, _("This widget is only supported for wx %s") % \ text_supported ) note.SetToolTip(wx.ToolTip( _("This widgets is supported for wx versions %(supported)s " "and not at %(not_supported)s." ) % { 'supported': text_supported, 'not_supported': text_not_supported, } )) sizer_tmp.Add(note, 0, wx.ALL | wx.EXPAND, 3) panel.SetAutoLayout(1) panel.SetSizer(sizer_tmp) sizer_tmp.Layout() sizer_tmp.Fit(panel) w, h = panel.GetClientSize() self.notebook.AddPage(panel, _("Common")) self.property_window.Layout() panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def on_size(self, event): """\ update the value of the 'size' property """ try: w_1, h_1 = 0, 0 sz = self.properties['size'] if sz.is_active(): # try to preserve the user's choice try: use_dialog_units = (sz.get_value().strip()[-1] == 'd') except IndexError: use_dialog_units = False val = sz.get_value() if use_dialog_units: val = val[:-1] w_1, h_1 = [int(t) for t in val.split(',')] else: use_dialog_units = config.preferences.use_dialog_units #False if use_dialog_units: w, h = self.widget.ConvertPixelSizeToDialog( self.widget.GetSize()) else: w, h = self.widget.GetSize() if w_1 == -1: w = -1 if h_1 == -1: h = -1 size = "%s, %s" % (w, h) if use_dialog_units: size += "d" self.size = size self.properties['size'].set_value(size) except KeyError: pass event.Skip() def get_tooltip(self): return self.tooltip def set_tooltip(self, value): self.tooltip = misc.wxstr(value) def get_background(self): return self.background def get_foreground(self): return self.foreground def set_background(self, value): oldval = self.background self.background = value if not self.widget: return value = value.strip() if value in ColorDialogProperty.str_to_colors: self.widget.SetBackgroundColour(wx.SystemSettings_GetColour( ColorDialogProperty.str_to_colors[value])) else: try: color = misc.string_to_color(value) self.widget.SetBackgroundColour(color) except: self.background = oldval self.properties['background'].set_value(self.get_background()) return self.widget.Refresh() def set_foreground(self, value): oldval = self.foreground self.foreground = value if not self.widget: return value = value.strip() if value in ColorDialogProperty.str_to_colors: self.widget.SetForegroundColour(wx.SystemSettings_GetColour( ColorDialogProperty.str_to_colors[value])) else: try: color = misc.string_to_color(value) self.widget.SetForegroundColour(color) except: self.foreground = oldval self.properties['foreground'].set_value(self.get_foreground()) return self.foreground = value self.widget.Refresh() def get_font(self): return str(self.font) def _build_from_font(self, font): families = FontDialogProperty.font_families_from styles = FontDialogProperty.font_styles_from weights = FontDialogProperty.font_weights_from return [ str(font.GetPointSize()), families.get(font.GetFamily(), 'default'), styles.get(font.GetStyle(), 'normal'), weights.get(font.GetWeight(), 'normal'), str(int(font.GetUnderlined())), font.GetFaceName() ] def set_font(self, value): #if not self.widget: return families = FontDialogProperty.font_families_to styles = FontDialogProperty.font_styles_to weights = FontDialogProperty.font_weights_to try: value = eval(value) f = wx.Font(int(value[0]), families[value[1]], styles[value[2]], weights[value[3]], int(value[4]), value[5]) except: #common.message.exception(_('Internal Error')) self.properties['font'].set_value(self.get_font()) else: self.font = value if self.widget: old_size = self.widget.GetSize() self.widget.SetFont(f) size = self.widget.GetSize() if size != old_size: self.sizer.set_item(self.pos, size=size) def set_width(self, value): self.set_size((int(value), -1)) def set_height(self, value): self.set_size((-1, int(value))) def set_size(self, value): #if not self.widget: return if self.properties['size'].is_active(): v = self.properties['size'].get_value().strip() use_dialog_units = v and v[-1] == 'd' else: use_dialog_units = config.preferences.use_dialog_units #False try: "" + value except TypeError: pass else: # value is a string-like object if value and value.strip()[-1] == 'd': use_dialog_units = True value = value[:-1] try: size = [int(t.strip()) for t in value.split(',', 1)] except: self.properties['size'].set_value(self.size) else: if use_dialog_units and value[-1] != 'd': value += 'd' self.size = value if self.widget: if use_dialog_units: size = wx.DLG_SZE(self.widget, size) self.widget.SetMinSize(size) self.widget.SetSize(size) try: #self.sizer.set_item(self.pos, size=self.widget.GetSize()) self.sizer.set_item(self.pos, size=size) except AttributeError: pass def get_size(self): return self.size def get_property_handler(self, name): if name == 'font': class FontHandler: def __init__(self, owner): self.owner = owner self.props = [ '' for i in range(6) ] self.index = 0 def start_elem(self, name, attrs): index = { 'size': 0, 'family': 1, 'style': 2, 'weight': 3, 'underlined': 4, 'face': 5 } self.index = index.get(name, 5) def end_elem(self, name): if name == 'font': self.owner.properties['font'].set_value( repr(self.props)) self.owner.properties['font'].toggle_active(True) self.owner.set_font(repr(self.props)) return True # to remove this handler def char_data(self, data): self.props[self.index] = str(data.strip()) # end of class FontHandler return FontHandler(self) elif name == 'extraproperties': import code_property return code_property.ExtraPropertiesPropertyHandler(self) return EditBase.get_property_handler(self, name) def get_disabled(self): return self.disabled_p def set_disabled(self, value): try: self.disabled_p = bool(int(value)) except ValueError: pass def get_focused(self): return self.focused_p def set_focused(self, value): try: self.focused_p = bool(int(value)) except ValueError: pass def get_hidden(self): return self.hidden_p def set_hidden(self, value): try: self.hidden_p = bool(int(value)) except ValueError: pass # end of class WindowBase class ManagedBase(WindowBase): """\ Base class for every managed window used by the builder: extends WindowBase with the addition of properties relative to the layout of the window: option, flag, and border """ def __init__(self, name, klass, parent, id, sizer, pos, property_window, show=True): WindowBase.__init__(self, name, klass, parent, id, property_window, show=show) # if True, the user is able to control the layout of the widget # inside the sizer (proportion, borders, alignment...) self._has_layout = not sizer.is_virtual() # selection markers self.sel_marker = None # dictionary of properties relative to the sizer which # controls this window self.sizer_properties = {} # attributes to keep the values of the sizer_properties self.option = 0 self.flag = 0 self.border = 0 self.sizer = sizer self.pos = pos self.access_functions['option'] = (self.get_option, self.set_option) self.access_functions['flag'] = (self.get_flag, self.set_flag) self.access_functions['border'] = (self.get_border, self.set_border) self.access_functions['pos'] = (self.get_pos, self.set_pos) self.flags_pos = (wx.ALL, wx.LEFT, wx.RIGHT, wx.TOP, wx.BOTTOM, wx.EXPAND, wx.ALIGN_RIGHT, wx.ALIGN_BOTTOM, wx.ALIGN_CENTER_HORIZONTAL, wx.ALIGN_CENTER_VERTICAL, wx.SHAPED, wx.ADJUST_MINSIZE) flag_labels = (u'#section#' + _('Border'), 'wxALL', 'wxLEFT', 'wxRIGHT', 'wxTOP', 'wxBOTTOM', u'#section#' + _('Alignment'), 'wxEXPAND', 'wxALIGN_RIGHT', 'wxALIGN_BOTTOM', 'wxALIGN_CENTER_HORIZONTAL', 'wxALIGN_CENTER_VERTICAL', 'wxSHAPED', 'wxADJUST_MINSIZE') # ALB 2004-08-16 - see the "wxPython migration guide" for details... self.flag = wx.ADJUST_MINSIZE #wxFIXED_MINSIZE self.flags_pos += (wx.FIXED_MINSIZE, ) flag_labels += ('wxFIXED_MINSIZE', ) sizer.add_item(self, pos) szprop = self.sizer_properties #szprop['option'] = SpinProperty(self, _("option"), None, 0, (0, 1000)) from layout_option_property import LayoutOptionProperty, \ LayoutPosProperty szprop['option'] = LayoutOptionProperty(self, sizer) szprop['flag'] = CheckListProperty(self, 'flag', None, flag_labels) szprop['border'] = SpinProperty(self, 'border', None, 0, (0, 1000), label=_('border')) ## pos_p = szprop['pos'] = SpinProperty(self, 'pos', None, 0, (0, 1000)) ## def write(*args, **kwds): pass ## pos_p.write = write # no need to save the position szprop['pos'] = LayoutPosProperty(self, sizer) def finish_widget_creation(self, sel_marker_parent=None): if sel_marker_parent is None: sel_marker_parent = self.parent.widget self.sel_marker = misc.SelectionMarker(self.widget, sel_marker_parent) WindowBase.finish_widget_creation(self) wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) wx.EVT_MOVE(self.widget, self.on_move) # re-add the item to update it self.sizer.add_item(self, self.pos, self.option, self.flag, self.border, self.widget.GetSize()) # set the value of the properties szp = self.sizer_properties szp['option'].set_value(self.get_option()) szp['flag'].set_value(self.get_flag()) szp['border'].set_value(self.get_border()) szp['pos'].set_value(self.pos-1) ## if self.properties['size'].is_active(): ## self.sizer.set_item(self.pos, size=self.widget.GetSize()) def create_properties(self): WindowBase.create_properties(self) if not self._has_layout: return panel = wx.ScrolledWindow( self.notebook, -1, style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE) szprop = self.sizer_properties szprop['pos'].display(panel) szprop['option'].display(panel) szprop['border'].display(panel) szprop['flag'].display(panel) sizer_tmp = wx.BoxSizer(wx.VERTICAL) sizer_tmp.Add(szprop['pos'].panel, 0, wx.EXPAND) sizer_tmp.Add(szprop['option'].panel, 0, wx.EXPAND) sizer_tmp.Add(szprop['border'].panel, 0, wx.EXPAND) sizer_tmp.Add(szprop['flag'].panel, 0, wx.EXPAND, 5) panel.SetAutoLayout(True) panel.SetSizer(sizer_tmp) sizer_tmp.Layout() sizer_tmp.Fit(panel) w, h = panel.GetClientSize() self.notebook.AddPage(panel, _("Layout")) panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def update_view(self, selected): if self.sel_marker: self.sel_marker.Show(selected) def on_move(self, event): self.sel_marker.update() def on_size(self, event): old = self.size WindowBase.on_size(self, event) sz = self.properties['size'] if (sz.is_active() and (int(self.get_option()) != 0 or self.get_int_flag() & wx.EXPAND)): self.properties['size'].set_value(old) self.size = old self.sel_marker.update() def set_option(self, value): self.option = value = int(value) if not self.widget: return try: sz = self.properties['size'] if value or sz.is_active(): size = sz.get_value().strip() if size[-1] == 'd': size = size[:-1] use_dialog_units = True else: use_dialog_units = False w, h = [ int(v) for v in size.split(',') ] if use_dialog_units: w, h = wx.DLG_SZE(self.widget, (w, h)) if value: w, h = 1, 1 else: w, h = self.widget.GetBestSize() self.sizer.set_item(self.pos, option=value, size=(w, h)) except AttributeError, e: print e def set_flag(self, value): value = self.sizer_properties['flag'].prepare_value(value) flags = 0 for v in range(len(value)): if value[v]: flags |= self.flags_pos[v] self.set_int_flag(flags) def set_int_flag(self, flags): self.flag = flags if not self.widget: return try: try: sp = self.properties['size'] size = sp.get_value().strip() if size[-1] == 'd': size = size[:-1] use_dialog_units = True else: use_dialog_units = False w, h = [ int(v) for v in size.split(',') ] if use_dialog_units: w, h = wx.DLG_SZE(self.widget, (w, h)) size = [w, h] except ValueError: size = None if not (flags & wx.EXPAND) and \ not self.properties['size'].is_active(): size = list(self.widget.GetBestSize()) self.sizer.set_item(self.pos, flag=flags, size=size) except AttributeError, e: common.message.exception(_('Internal Error')) def set_border(self, value): self.border = int(value) if not self.widget: return try: sp = self.properties['size'] size = sp.get_value().strip() if size[-1] == 'd': size = size[:-1] use_dialog_units = True else: use_dialog_units = False w, h = [ int(v) for v in size.split(',') ] if use_dialog_units: w, h = wx.DLG_SZE(self.widget, (w, h)) if w == -1: w = self.widget.GetSize()[0] if h == -1: h = self.widget.GetSize()[1] self.sizer.set_item(self.pos, border=int(value), size=(w, h)) except AttributeError, e: common.message.exception(_('Internal Error')) def get_option(self): return self.option def get_flag(self): retval = [0] * len(self.flags_pos) try: for i in range(len(self.flags_pos)): if self.flag & self.flags_pos[i]: retval[i] = 1 # patch to make wxALL work if retval[1:5] == [1, 1, 1, 1]: retval[0] = 1; retval[1:5] = [0, 0, 0, 0] else: retval[0] = 0 except AttributeError: pass return retval def get_int_flag(self): return self.flag def get_border(self): return self.border def delete(self): if self.sel_marker: self.sel_marker.Destroy() # destroy the selection markers WindowBase.delete(self) def remove(self, *args): self.sizer.free_slot(self.pos) WindowBase.remove(self) def get_pos(self): return self.pos-1 def set_pos(self, value): """setter for the 'pos' property: calls self.sizer.change_item_pos""" self.sizer.change_item_pos(self, min(value + 1, len(self.sizer.children) - 1)) def update_pos(self, value): """\ called by self.sizer.change_item_pos to update the item's position when another widget is moved """ #print 'update pos', self.name, value self.sizer_properties['pos'].set_value(value-1) self.pos = value # end of class ManagedBase class PreviewMixin: """\ Mixin class used to add preview to a widget @ivar preview_button: Button to show or close the preview window @ivar preview_widget: Widget to be represented """ def __init__(self): self.preview_button = None self.preview_widget = None def create_properties(self): panel = self.notebook.GetPage(0) sizer_tmp = panel.GetSizer() # add a preview button to the Common panel for top-levels self.preview_button = btn = wx.Button(panel, -1, _('Preview')) wx.EVT_BUTTON(btn, -1, self.preview) sizer_tmp.Add(btn, 0, wx.ALL|wx.EXPAND, 5) sizer_tmp.Layout() sizer_tmp.Fit(panel) w, h = panel.GetClientSize() self.property_window.Layout() panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def preview(self, event): """\ Create a preview of the selected widget """ #print 'frame class _> ', self.klass if self.preview_widget is None: self.preview_widget = common.app_tree.app.preview(self) self.preview_button.SetLabel(_('Close Preview')) else: # Close triggers the EVT_CLOSE that does the real work # (see application.py -> preview) self.preview_widget.Close() def preview_is_visible(self): """\ True if the L{preview_button} is created @rtype: Boolean """ return self.preview_widget is not None # end of class PreviewMixin class TopLevelBase(WindowBase, PreviewMixin): """\ Base class for every non-managed window (i.e. Frames and Dialogs). """ _is_toplevel = True _custom_base_classes = True def __init__(self, name, klass, parent, id, property_window, show=True, has_title=True, title=None): WindowBase.__init__(self, name, klass, parent, id, property_window, show=show) self.has_title = has_title if self.has_title: if title is None: title = self.name self.title = title self.access_functions['title'] = (self.get_title, self.set_title) self.properties['title'] = TextProperty(self, 'title', None, label=_("title")) self.sizer = None # sizer that controls the layout of the children # of the window PreviewMixin.__init__(self) def finish_widget_creation(self, *args, **kwds): WindowBase.finish_widget_creation(self) self.widget.SetMinSize = self.widget.SetSize if self.has_title: self.widget.SetTitle(misc.design_title( self.properties['title'].get_value())) elif hasattr(self.widget, 'SetTitle'): self.widget.SetTitle(misc.design_title(self.name)) wx.EVT_LEFT_DOWN(self.widget, self.drop_sizer) wx.EVT_ENTER_WINDOW(self.widget, self.on_enter) wx.EVT_CLOSE(self.widget, self.hide_widget) if wx.Platform == '__WXMSW__': # MSW isn't smart enough to avoid overlapping windows, so # at least move it away from the 3 wxGlade frames self.widget.Center() # ALB 2004-10-15 self.widget.SetAcceleratorTable(common.palette.accel_table) def show_widget(self, yes): WindowBase.show_widget(self, yes) if yes and wx.Platform == '__WXMSW__': # more than ugly, but effective hack to properly layout the window # on Win32 if self.properties['size'].is_active(): w, h = self.widget.GetSize() self.widget.SetSize((-1, h+1)) self.widget.SetSize((-1, h)) elif self.sizer: self.sizer.fit_parent() def popup_menu(self, event): if self.widget: if not self._rmenu: REMOVE_ID, HIDE_ID = [wx.NewId() for i in range(2)] self._rmenu = misc.wxGladePopupMenu(self.name) misc.append_item(self._rmenu, REMOVE_ID, _('Remove\tDel'), wx.ART_DELETE) misc.append_item(self._rmenu, HIDE_ID, _('Hide')) def bind(method): return lambda e: wx.CallAfter(method) wx.EVT_MENU(self.widget, REMOVE_ID, bind(self.remove)) wx.EVT_MENU(self.widget, HIDE_ID, bind(self.hide_widget)) # paste PASTE_ID = wx.NewId() misc.append_item(self._rmenu, PASTE_ID, _('Paste\tCtrl+V'), wx.ART_PASTE) wx.EVT_MENU(self.widget, PASTE_ID, bind(self.clipboard_paste)) PREVIEW_ID = wx.NewId() self._rmenu.AppendSeparator() misc.append_item(self._rmenu, PREVIEW_ID, _('Preview')) wx.EVT_MENU(self.widget, PREVIEW_ID, bind(self.preview_parent)) self.setup_preview_menu() self.widget.PopupMenu(self._rmenu, event.GetPosition()) def clipboard_paste(self, *args): if self.sizer is not None: print _('\nwxGlade-WARNING: sizer already set for this window') return import clipboard, xml_parse size = self.widget.GetSize() try: if clipboard.paste(self, None, 0): common.app_tree.app.saved = False self.widget.SetSize(size) except xml_parse.XmlParsingError, e: print _('\nwxGlade-WARNING: only sizers can be pasted here') def create_properties(self): WindowBase.create_properties(self) # don't display the title ourselves anymore, now it's a # duty of the subclass! ## if self.has_title: ## panel = self.notebook.GetPage(0) ## sizer_tmp = panel.GetSizer() ## self.properties['title'].display(panel) ## sizer_tmp.Add(self.properties['title'].panel, 0, wxEXPAND) PreviewMixin.create_properties(self) def get_title(self): return self.title def set_title(self, value): self.title = misc.wxstr(value) if self.widget: self.widget.SetTitle(misc.design_title(value)) def set_sizer(self, sizer): self.sizer = sizer if self.sizer and self.sizer.widget and self.widget: self.widget.SetAutoLayout(True) self.widget.SetSizer(self.sizer.widget) self.widget.Layout() def on_enter(self, event): if not self.sizer and common.adding_sizer: self.widget.SetCursor(wx.CROSS_CURSOR) else: self.widget.SetCursor(wx.STANDARD_CURSOR) def drop_sizer(self, event): if self.sizer or not common.adding_sizer: self.on_set_focus(event) # default behaviour: call show_properties return common.adding_widget = common.adding_sizer = False self.widget.SetCursor(wx.STANDARD_CURSOR) common.widgets[common.widget_to_add](self, None, None) common.widget_to_add = None def hide_widget(self, *args): self.widget.Hide() common.app_tree.expand(self.node, False) common.app_tree.select_item(self.node.parent) common.app_tree.app.show_properties() def on_size(self, event): WindowBase.on_size(self, event) if self.sizer and self.widget: self.sizer.refresh() def set_name(self, name): oldname = self.name # check and set name WindowBase.set_name(self, name) # update top window name if not misc.streq(oldname, self.name): common.app_tree.app.update_top_window_name(oldname, self.name) def delete(self, *args): if self.preview_widget is not None: self.preview_widget.Destroy() self.preview_widget = None WindowBase.delete(self, *args) # end of class TopLevelBase wxglade-0.6.8.orig/xml_parse.py0000644000175000017500000011257312150161534016670 0ustar georgeskgeorgesk""" Parsers used to load an app and to generate the code from an xml file. NOTE: custom tag handler interface (called by XmlWidgetBuilder):: class CustomTagHandler: def start_elem(self, name, attrs): pass def end_elem(self, name): return True -> the handler must be removed from the Stack def char_data(self, data): return False -> no further processing needed @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import os from cStringIO import StringIO from xml.sax import SAXException, make_parser from xml.sax.handler import ContentHandler import common import config import edit_sizers import errors # ALB 2005-03-10: importing the module here prevents a segfault with python 2.4 # hmmm... need to investigate this more (it seems that import of # xml.sax.expatreader should happen before something else... but what?) import xml.sax.expatreader if common.use_gui: import wx class XmlParsingError(SAXException): """\ Custom exception to report problems during parsing """ locator = None def __init__(self, msg): if self.locator: l = self.locator msg += ' _((line: %s, column: %s))' % (l.getLineNumber(), l.getColumnNumber()) SAXException.__init__(self, msg) # end of class XmlParsingError class XmlParser(ContentHandler): """\ 'abstract' base class of the parsers used to load an app and to generate the code @ivar _curr_prop: Name of the current property @ivar _curr_prop_val: Value of the current property (list into which the various pieces of char data collected are inserted) @ivar _objects: Stack of 'alive' objects @ivar _sizer_item: Stack of sizer items @ivar _sizers: Stack of sizer objects @ivar _windows: Stack of window objects (derived by wxWindow) @ivar locator: Document locator """ def __init__(self): self._objects = Stack() self._windows = Stack() self._sizers = Stack() self._sizer_item = Stack() self._curr_prop = None self._curr_prop_val = [] self._appl_started = False self.top = self._objects.top self.parser = make_parser() self.parser.setContentHandler(self) self.locator = None def parse(self, source): # Permanent workaround for Python bug "Sax parser crashes if given # unicode file name" (http://bugs.python.org/issue11159). # # This bug causes a UnicodeEncodeError if the SAX XML parser wants to # store an unicode filename internally. # # That's not a general file handling issue because the parameter # source is an open file already. source = StringIO(source.read()) self.parser.parse(source) source.close() def parse_string(self, source): source = StringIO(source) self.parser.parse(source) source.close() def setDocumentLocator(self, locator): self.locator = locator XmlParsingError.locator = locator def startElement(self, name, attrs): raise NotImplementedError def endElement(self, name, attrs): raise NotImplementedError def characters(self, data): raise NotImplementedError def pop(self): try: return self._objects.pop().pop() except AttributeError: return None # end of class XmlParser class XmlWidgetBuilder(XmlParser): """\ parser used to build the tree of widgets from an xml file """ def startElement(self, name, attrs): if name == 'application': # get properties of the app self._appl_started = True app = common.app_tree.app encoding = attrs.get("encoding") if encoding: try: unicode('a', encoding) except LookupError: pass else: app.encoding = encoding app.encoding_prop.set_value(encoding) path = attrs.get("path") if path: app.output_path = path app.outpath_prop.set_value(path) name = attrs.get("name") if name: app.name = name app.name_prop.toggle_active(True) app.name_prop.set_value(name) klass = attrs.get("class") if klass: app.klass = klass app.klass_prop.toggle_active(True) app.klass_prop.set_value(klass) option = attrs.get("option") if option: try: option = int(option) except ValueError: option = config.default_multiple_files app.codegen_opt = option app.codegen_prop.set_value(option) language = attrs.get('language') if language: app.codewriters_prop.set_str_value(language) app.set_language(language) top_win = attrs.get("top_window") if top_win: self.top_window = top_win try: use_gettext = int(attrs["use_gettext"]) except (KeyError, ValueError): use_gettext = config.default_use_gettext if use_gettext: app.use_gettext = True app.use_gettext_prop.set_value(True) try: is_template = int(attrs["is_template"]) except (KeyError, ValueError): is_template = False app.is_template = is_template try: overwrite = int(attrs['overwrite']) except (KeyError, ValueError): overwrite = config.default_overwrite if overwrite: app.overwrite = True app.overwrite_prop.set_value(True) else: app.overwrite = False app.overwrite_prop.set_value(False) try: use_new_namespace = int(attrs['use_new_namespace']) except (KeyError, ValueError): use_new_namespace = False app.set_use_old_namespace(not use_new_namespace) app.use_old_namespace_prop.set_value(not use_new_namespace) indent_symbol = attrs.get("indent_symbol") if indent_symbol == 'space': app.indent_mode = 1 elif indent_symbol == 'tab': app.indent_mode = 0 app.indent_mode_prop.set_value(app.indent_mode) indent = attrs.get("indent_amount") if indent: try: indent_amount = int(indent) except (KeyError, ValueError): indent_amount = config.default_indent_amount else: app.indent_amount = indent_amount app.indent_amount_prop.set_value(indent_amount) source_extension = attrs.get("source_extension") if source_extension and source_extension[0] == '.': app.source_ext = source_extension[1:] app.source_ext_prop.set_value(source_extension[1:]) header_extension = attrs.get("header_extension") if header_extension and header_extension[0] == '.': app.header_ext = header_extension[1:] app.header_ext_prop.set_value(header_extension[1:]) try: for_version = attrs['for_version'] app.for_version = for_version app.for_version_prop.set_str_value(for_version) except KeyError: pass return if not self._appl_started: raise XmlParsingError( _("the root of the tree must be ") ) if name == 'object': # create the object and push it on the appropriate stacks XmlWidgetObject(attrs, self) else: # handling of the various properties try: # look for a custom handler to push on the stack handler = self.top().obj.get_property_handler(name) if handler: self.top().prop_handlers.push(handler) # get the top custom handler and use it if there's one handler = self.top().prop_handlers.top() if handler: handler.start_elem(name, attrs) except AttributeError: pass self._curr_prop = name def endElement(self, name): if name == 'application': self._appl_started = False if hasattr(self, 'top_window'): common.app_tree.app.top_window = self.top_window common.app_tree.app.top_win_prop.SetStringSelection( self.top_window) return if name == 'object': # remove last object from the stack obj = self.pop() if obj.klass in ('sizeritem', 'sizerslot'): return si = self._sizer_item.top() if si is not None and si.parent == obj.parent: sprop = obj.obj.sizer_properties # update the values sprop['option'].set_value(si.obj.option) sprop['flag'].set_value(si.obj.flag_str()) sprop['border'].set_value(si.obj.border) # call the setter functions obj.obj['option'][1](si.obj.option) obj.obj['flag'][1](si.obj.flag_str()) obj.obj['border'][1](si.obj.border) else: # end of a property or error # 1: set _curr_prop value data = common._encode_from_xml("".join(self._curr_prop_val)) if data: try: handler = self.top().prop_handlers.top() if not handler or handler.char_data(data): # if char_data returned False, # we don't have to call add_property self.top().add_property(self._curr_prop, data) except AttributeError: pass # 2: call custom end_elem handler try: # if there is a custom handler installed for this property, # call its end_elem function: if this returns True, remove # the handler from the Stack handler = self.top().prop_handlers.top() if handler.end_elem(name): self.top().prop_handlers.pop() except AttributeError: pass self._curr_prop = None self._curr_prop_val = [] def characters(self, data): if not data or data.isspace(): return if self._curr_prop is None: raise XmlParsingError(_("character data can be present only " "inside properties")) self._curr_prop_val.append(data) # end of class XmlWidgetBuilder class ProgressXmlWidgetBuilder(XmlWidgetBuilder): """\ Adds support for a progress dialog to the widget builder parser """ def __init__(self, *args, **kwds): self.input_file = kwds.get('input_file') if self.input_file: del kwds['input_file'] self.size = len(self.input_file.readlines()) self.input_file.seek(0) self.progress = wx.ProgressDialog( _("Loading..."), _("Please wait while loading the app"), 20 ) self.step = 4 self.i = 1 else: self.size = 0 self.progress = None XmlWidgetBuilder.__init__(self, *args, **kwds) def endElement(self, name): if self.progress: if name == 'application': self.progress.Destroy() else: if self.locator: where = self.locator.getLineNumber() value = int(round(where * 20.0 / self.size)) else: # we don't have any information, so we update the progress # bar ``randomly'' value = (self.step * self.i) % 20 self.i += 1 self.progress.Update(value) XmlWidgetBuilder.endElement(self, name) def parse(self, *args): try: XmlWidgetBuilder.parse(self, *args) finally: if self.progress: self.progress.Destroy() def parse_string(self, *args): try: XmlWidgetBuilder.parse_string(self, *args) finally: if self.progress: self.progress.Destroy() # end of class ProgressXmlWidgetBuilder class ClipboardXmlWidgetBuilder(XmlWidgetBuilder): """\ Parser used to cut&paste widgets. The differences with XmlWidgetBuilder are: - No tag in the piece of xml to parse - Fake parent, sizer and sizeritem objects to push on the three stacks: they keep info about the destination of the hierarchy of widgets (i.e. the target of the 'paste' command) - The first widget built must be hidden and shown again at the end of the operation """ def __init__(self, parent, sizer, pos, option, flag, border): XmlWidgetBuilder.__init__(self) self.parent_node = parent.node class XmlClipboardObject(object): def __init__(self, **kwds): self.__dict__.update(kwds) par = XmlClipboardObject(obj=parent, parent=parent) # fake window obj if sizer is not None: # fake sizer object szr = XmlClipboardObject(obj=sizer, parent=parent) sizeritem = Sizeritem() sizeritem.option = option sizeritem.flag = flag sizeritem.border = border sizeritem.pos = pos # fake sizer item si = XmlClipboardObject(obj=sizeritem, parent=parent) # push the fake objects on the stacks self._objects.push(par) self._windows.push(par) if sizer is not None: self._objects.push(szr) self._sizers.push(szr) self._objects.push(si) self._sizer_item.push(si) self.depth_level = 0 self._appl_started = True # no application tag when parsing from the # clipboard def startElement(self, name, attrs): if name == 'object' and attrs.has_key('name'): # generate a unique name for the copy oldname = str(attrs['name']) newname = oldname i = 0 while common.app_tree.has_name(newname,node=self.parent_node ): if not i: newname = '%s_copy' % oldname else: newname = '%s_copy_%s' % (oldname, i) i += 1 attrs = dict(attrs) attrs['name'] = newname XmlWidgetBuilder.startElement(self, name, attrs) if name == 'object': if not self.depth_level: common.app_tree.auto_expand = False try: self.top_obj = self.top().obj except AttributeError: common.message.exception( _('Exception! obj: %s') % self.top_obj ) self.depth_level += 1 def endElement(self, name): if name == 'object': obj = self.top() self.depth_level -= 1 if not self.depth_level: common.app_tree.auto_expand = True try: # show the first object and update its layout common.app_tree.show_widget(self.top_obj.node) self.top_obj.show_properties() common.app_tree.select_item(self.top_obj.node) except AttributeError: common.message.exception( _('Exception! obj: %s') % self.top_obj ) XmlWidgetBuilder.endElement(self, name) # end of class ClipboardXmlWidgetBuilder class XmlWidgetObject(object): """\ A class to encapsulate a widget read from an xml file: its purpose is to store various widget attributes until the widget can be created @ivar in_sizers: If True, the widget is a sizer, opposite of L{in_windows} @type in_sizers: Boolean @ivar in_windows: If True, the wiget is not a sizer, pposite of L{in_sizers} @type in_windows: Boolean @ivar prop_handlers: Is a stack of custom handler functions to set properties of this object """ def __init__(self, attrs, parser): self.prop_handlers = Stack() self.parser = parser self.in_windows = self.in_sizers = False try: base = attrs.get('base', None) self.klass = attrs['class'] except KeyError: raise XmlParsingError(_("'object' items must have a 'class' " "attribute")) if base is not None: # if base is not None, the object is a widget (or sizer), and # not a sizeritem sizer = self.parser._sizers.top() parent = self.parser._windows.top() if parent is not None: parent = self.parent = parent.obj else: self.parent = None sizeritem = self.parser._sizer_item.top() if sizeritem is not None: sizeritem = sizeritem.obj if sizer is not None: # we must check if the sizer on the top of the stack is # really the one we are looking for: to check this if sizer.parent != parent: sizer = None else: sizer = sizer.obj if hasattr(sizeritem, 'pos'): pos = sizeritem.pos else: pos = None if parent and hasattr(parent, 'virtual_sizer') and \ parent.virtual_sizer: sizer = parent.virtual_sizer sizer.node = parent.node sizeritem = Sizeritem() if pos is None: pos = sizer.get_itempos(attrs) # build the widget if pos is not None: pos = int(pos) self.obj = common.widgets_from_xml[base](attrs, parent, sizer, sizeritem, pos) try: #self.obj.klass = self.klass self.obj.set_klass(self.klass) self.obj.klass_prop.set_value(self.klass) except AttributeError: pass # push the object on the appropriate stack if isinstance(self.obj, edit_sizers.SizerBase): self.parser._sizers.push(self) self.in_sizers = True else: self.parser._windows.push(self) self.in_windows = True elif self.klass == 'sizeritem': self.obj = Sizeritem() self.parent = self.parser._windows.top().obj self.parser._sizer_item.push(self) elif self.klass == 'sizerslot': sizer = self.parser._sizers.top().obj assert sizer is not None, \ _("malformed wxg file: slots can only be inside sizers!") sizer.add_slot() self.parser._sizer_item.push(self) # push the object on the _objects stack self.parser._objects.push(self) def pop(self): if self.in_windows: return self.parser._windows.pop() elif self.in_sizers: return self.parser._sizers.pop() else: return self.parser._sizer_item.pop() def add_property(self, name, val): """\ adds a property to this widget. This method is not called if there was a custom handler for this property, and its char_data method returned False """ if name == 'pos': # sanity check, this shouldn't happen... print 'add_property pos' return try: self.obj[name][1](val) # call the setter for this property try: prop = self.obj.properties[name] prop.set_value(val) prop.toggle_active(True) except AttributeError: pass except KeyError: # unknown property for this object # issue a warning and ignore the property import sys print >> sys.stderr, _("Warning: property '%s' not supported " "by this object ('%s') ") % (name, self.obj) #end of class XmlWidgetObject class CodeWriter(XmlParser): """\ Parser used to produce the source from a given XML file @ivar _toplevels: Toplevel objects, i.e. instances of a custom class @ivar app_attrs: Attributes of the app (name, class, top_window) @type app_attrs: Dictionary @ivar top_win: Class name of the top window of the app (if any) @type top_win: String @ivar out_path: This allows to override the output path specified in the XML file @ivar preview: If True, we are generating the code for the preview @type preview: Boolean """ def __init__(self, writer, input, from_string=False, out_path=None, preview=False, class_names=None): # writer: object that actually writes the code XmlParser.__init__(self) self._toplevels = Stack() self.app_attrs = {} self.top_win = '' self.out_path = out_path self.code_writer = writer self.preview = preview # used in the CustomWidget preview code, to generate better previews # (see widgets/custom_widget/codegen.py) self.class_names = class_names if self.class_names is None: self.class_names = set() if from_string: self.parse_string(input) else: inputfile = None try: inputfile = open(input) self.parse(inputfile) finally: if inputfile: inputfile.close() def startElement(self, name, attrs_impl): attrs = {} try: encoding = self.app_attrs['encoding'] unicode('a', encoding) except (KeyError, LookupError): if name == 'application': encoding = str(attrs_impl.get( 'encoding', config.default_encoding )) else: encoding = config.default_encoding # turn all the attribute values from unicode to str objects for attr, val in attrs_impl.items(): attrs[attr] = common._encode_from_xml(val, encoding) if name == 'application': # get the code generation options self._appl_started = True self.app_attrs = attrs try: attrs['option'] = bool(int(attrs['option'])) use_multiple_files = attrs['option'] except (KeyError, ValueError): use_multiple_files = attrs['option'] = \ config.default_multiple_files if self.out_path is None: try: self.out_path = attrs['path'] except KeyError: raise XmlParsingError(_("'path' attribute missing: could " "not generate code")) else: attrs['path'] = self.out_path # Prevent empty output path if not self.out_path: raise XmlParsingError( _("'path' attribute empty: could not generate code") ) # Check if the values of use_multiple_files and out_path agree if use_multiple_files: if not os.path.isdir(self.out_path): raise errors.WxgOutputDirectoryNotExist(self.out_path) if not os.access(self.out_path, os.W_OK): raise errors.WxgOutputDirectoryNotWritable(self.out_path) else: if os.path.isdir(self.out_path): raise errors.WxgOutputPathIsDirectory(self.out_path) directory = os.path.dirname(self.out_path) if directory: if not os.path.isdir(directory): raise errors.WxgOutputDirectoryNotExist(directory) if not os.access(directory, os.W_OK): raise errors.WxgOutputDirectoryNotWritable(directory) # initialize the writer self.code_writer.initialize(attrs) return if not self._appl_started: raise XmlParsingError( _("the root of the tree must be ") ) if name == 'object': # create the CodeObject which stores info about the current widget CodeObject(attrs, self, preview=self.preview) if attrs.has_key('name') and \ attrs['name'] == self.app_attrs.get('top_window', ''): self.top_win = attrs['class'] else: # handling of the various properties try: # look for a custom handler to push on the stack w = self.top() handler = self.code_writer.get_property_handler(name, w.base) if handler: w.prop_handlers.push(handler) # get the top custom handler and use it if there's one handler = w.prop_handlers.top() if handler: handler.start_elem(name, attrs) except AttributeError: common.message.exception(_('ATTRIBUTE ERROR!!')) self._curr_prop = name def endElement(self, name): if name == 'application': self._appl_started = False if self.app_attrs: self.code_writer.add_app(self.app_attrs, self.top_win) # call the finalization function of the code writer self.code_writer.finalize() return if name == 'object': obj = self.pop() if obj.klass in ('sizeritem', 'sizerslot'): return # at the end of the object, we have all the information to add it # to its toplevel parent, or to generate the code for the custom # class if obj.is_toplevel and not obj.in_sizers: self.code_writer.add_class(obj) topl = self._toplevels.top() if topl: self.code_writer.add_object(topl, obj) # if the object is not a sizeritem, check whether it # belongs to some sizer (in this case, # self._sizer_item.top() doesn't return None): if so, # write the code to add it to the sizer at the top of # the stack si = self._sizer_item.top() if si is not None and si.parent == obj.parent: szr = self._sizers.top() if not szr: return self.code_writer.add_sizeritem(topl, szr, obj, si.obj.option, si.obj.flag_str(), si.obj.border) else: # end of a property or error # 1: set _curr_prop value try: encoding = self.app_attrs['encoding'] unicode('a', encoding) except (KeyError, LookupError): encoding = config.default_encoding data = common._encode_from_xml(u"".join(self._curr_prop_val), encoding) if data: handler = self.top().prop_handlers.top() if not handler or handler.char_data(data): # if char_data returned False, # we don't have to call add_property self.top().add_property(self._curr_prop, data) # 2: call custom end_elem handler try: # if there is a custom handler installed for this property, # call its end_elem function: if this returns True, remove # the handler from the stack obj = self.top() handler = obj.prop_handlers.top() if handler.end_elem(name, obj): obj.prop_handlers.pop() except AttributeError: pass self._curr_prop = None self._curr_prop_val = [] def characters(self, data): if not data or data.isspace(): return if self._curr_prop is None: raise XmlParsingError(_("character data can only appear inside " "properties")) self._curr_prop_val.append(data) # end of class CodeWriter class CodeObject(object): """\ A class to store information needed to generate the code for a given object. @ivar in_sizers: If True, the widget is a sizer, opposite of L{in_windows} @type in_sizers: Boolean @ivar in_windows: If True, the wiget is not a sizer, pposite of L{in_sizers} @type in_windows: Boolean @ivar is_container: If True, the widget is a container (frame, dialog, panel, ...) @type is_container: Boolean @ivar is_toplevel: If True, the object is a toplevel one: for window objects, this means that they are instances of a custom class, for sizers, that they are at the top of the hierarchy. @type is_toplevel: Boolean @ivar properties: Properties of the widget sizer @type properties: Dictionary @ivar prop_handlers: Is a stack of custom handler functions to set properties of this object """ def __init__(self, attrs, parser, preview=False): self.parser = parser self.in_windows = self.in_sizers = False self.is_toplevel = False self.is_container = False self.properties = {} self.prop_handlers = Stack() self.preview = preview try: base = attrs.get('base', None) self.klass = attrs['class'] except KeyError: raise XmlParsingError(_("'object' items must have a 'class' " "attribute")) self.parser._objects.push(self) self.parent = self.parser._windows.top() if self.parent is not None: self.parent.is_container = True self.base = None if base is not None: # this is a ``real'' object, not a sizeritem self.name = attrs['name'] self.base = common.class_names[base] can_be_toplevel = common.toplevels.has_key(base) if (self.parent is None or self.klass != self.base) and \ can_be_toplevel: #self.base != 'CustomWidget': self.is_toplevel = True # ALB 2005-11-19: for panel objects, if the user sets a # custom class but (s)he doesn't want the code # to be generated... if int(attrs.get('no_custom_class', False)) and \ not self.preview: self.is_toplevel = False #print 'OK:', str(self) #self.in_windows = True #self.parser._windows.push(self) else: self.parser._toplevels.push(self) elif self.preview and not can_be_toplevel and \ self.base != 'CustomWidget': # if this is a custom class, but not a toplevel one, # for the preview we have to use the "real" class # # ALB 2007-08-04: CustomWidgets handle this in a special way # (see widgets/custom_widget/codegen.py) self.klass = self.base # temporary hack: to detect a sizer, check whether the name # of its class contains the string 'Sizer': TODO: find a # better way!! if base.find('Sizer') != -1: self.in_sizers = True if not self.parser._sizers.count(): self.is_toplevel = True else: # the sizer is a toplevel one if its parent has not a # sizer yet sz = self.parser._sizers.top() if sz.parent != self.parent: self.is_toplevel = True self.parser._sizers.push(self) else: self.parser._windows.push(self) self.in_windows = True else: # the object is a sizeritem self.obj = Sizeritem() self.obj.flag_s = '0' self.parser._sizer_item.push(self) def __str__(self): return "" % (self.name, self.base, self.klass) def add_property(self, name, value): if hasattr(self, 'obj'): # self is a sizeritem try: if name == 'flag': ## flag = 0 ## for f in value.split('|'): ## flag |= Sizeritem.flags[f.strip()] ## setattr(self.obj, name, flag) self.obj.flag_s = value.strip() else: setattr(self.obj, name, int(value)) except: raise XmlParsingError(_("property '%s' not supported by " "'%s' objects") % (name, self.klass)) self.properties[name] = value def pop(self): if self.is_toplevel and not self.in_sizers: self.parser._toplevels.pop() if self.in_windows: return self.parser._windows.pop() elif self.in_sizers: return self.parser._sizers.pop() else: return self.parser._sizer_item.pop() # end of class CodeObject class Stack(object): def __init__(self): self._repr = [] def push(self, elem): self._repr.append(elem) def pop(self): try: return self._repr.pop() except IndexError: return None def top(self): try: return self._repr[-1] except IndexError: return None def count(self): return len(self._repr) # end of class Stack class Sizeritem(object): if common.use_gui: flags = {'wxALL': wx.ALL, 'wxEXPAND': wx.EXPAND, 'wxALIGN_RIGHT': wx.ALIGN_RIGHT, 'wxALIGN_BOTTOM': wx.ALIGN_BOTTOM, 'wxALIGN_CENTER_HORIZONTAL': wx.ALIGN_CENTER_HORIZONTAL, 'wxALIGN_CENTER_VERTICAL': wx.ALIGN_CENTER_VERTICAL, 'wxLEFT': wx.LEFT, 'wxRIGHT': wx.RIGHT, 'wxTOP': wx.TOP, 'wxBOTTOM': wx.BOTTOM, 'wxSHAPED': wx.SHAPED, 'wxADJUST_MINSIZE': wx.ADJUST_MINSIZE, } flags['wxFIXED_MINSIZE'] = wx.FIXED_MINSIZE def __init__(self): self.option = self.border = 0 self.flag = 0 def __getitem__(self, name): if name != 'flag': return (None, lambda v: setattr(self, name, v)) def get_flag(v): val = reduce(lambda a, b: a | b, [Sizeritem.flags[t] for t in v.split("|")]) setattr(self, name, val) return (None, get_flag) ## lambda v: setattr(self, name, ## reduce(lambda a,b: a|b, ## [Sizeritem.flags[t] for t in ## v.split("|")]))) def flag_str(self): """\ Returns the flag attribute as a string of tokens separated by a '|' (used during the code generation) """ if hasattr(self, 'flag_s'): return self.flag_s else: try: tmp = {} for k in self.flags: if self.flags[k] & self.flag: tmp[k] = 1 # patch to make wxALL work remove_wxall = 4 for k in ('wxLEFT', 'wxRIGHT', 'wxTOP', 'wxBOTTOM'): if k in tmp: remove_wxall -= 1 if remove_wxall: try: del tmp['wxALL'] except KeyError: pass else: for k in ('wxLEFT', 'wxRIGHT', 'wxTOP', 'wxBOTTOM'): try: del tmp[k] except KeyError: pass tmp['wxALL'] = 1 tmp = '|'.join(tmp.keys()) except: print 'EXCEPTION: self.flags = %s, self.flag = %s' % \ (self.flags, repr(self.flag)) raise if tmp: return tmp else: return '0' # end of class Sizeritem wxglade-0.6.8.orig/codegen/0000755000175000017500000000000012170277707015733 5ustar georgeskgeorgeskwxglade-0.6.8.orig/codegen/pl_codegen.py0000644000175000017500000006463612167341277020423 0ustar georgeskgeorgesk"""\ Perl code generator How the code is generated: every time the end of an object is reached during the parsing of the xml tree, either the function 'add_object' or the function 'add_class' is called: the latter when the object is a toplevel one, the former when it is not. In the last case, 'add_object' calls the appropriate ``writer'' function for the specific object, found in the 'obj_builders' dict. Such function accepts one argument, the CodeObject representing the object for which the code has to be written, and returns 3 lists of strings, representing the lines to add to the '__init__', '__set_properties' and '__do_layout' methods of the parent object. Like all other perl parts, based on the pre-existing python generators @copyright: 2002-2004 D.H. aka crazyinsomniac on sourceforge.net @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import os import os.path import re from codegen import BaseCodeWriter, \ BaseSourceFileContent, \ BaseWidgetHandler class SourceFileContent(BaseSourceFileContent): rec_block_start = re.compile( r'^(?P\s*)' # leading spaces r'#\s*' # comment sign r'begin\s+wxGlade:\s*' # "begin wxGlade:" statement and tailing spaces r'(?P[a-zA-Z_]+[\w:]*?)??' # class or function name (non-greedy) r'(?::{2}|\s*)' # separator between class and function / block (non-greedy) r'(?P\w+)' # function / block name r'\s*$' # tailing spaces ) rec_block_end = re.compile( r'^\s*' # leading spaces r'#\s*' # comment sign r'end\s+wxGlade' # "end exGlade" statement r'\s*$' # tailing spaces ) # Less precise regex, but working :-P # Should match: package Foo; or package Foo::bar::baz ; rec_class_decl = re.compile( r'^\s*' # leading spaces r'package\s+([a-zA-Z_][\w:]*)\s*;' # "package " statement r'.*$' # any character till eol ) rec_event_handler = re.compile( r'^\s*' # leading spaces r'#\s*wxGlade:\s*(?P[\w:]+)::(?P\w+) ' # wxGlade event handler # statement with class and # event handler name r'\s*$' # tailing spaces ) rec_pod = re.compile( r'^\s*' # leading spaces r'=[A-Za-z_]+\w*' # match POD statement r'.*$' # any character till eol ) """\ Regexp to match Perl's Plain Old Documentation format @see: manpage perlpod """ def build_untouched_content(self): """\ Builds a string with the contents of the file that must be left as is, and replaces the wxGlade blocks with tags that in turn will be replaced by the new wxGlade blocks WARNING: NOT YET COMPLETE -- crazyinsomniac alb - almost done :) WARNING: There is *NO* support for here documents: if you put wxGlade blocks inside a here document, you're likely going into troubles... """ BaseSourceFileContent.build_untouched_content(self) inside_block = False inside_pod = False tmp_in = self._load_file(self.name) out_lines = [] for line in tmp_in: result = self.rec_pod.match(line) if result: inside_pod = True if inside_pod: out_lines.append(line) if line.startswith('=cut'): inside_pod = False continue result = self.rec_class_decl.match(line) if result: ## print ">> class %r" % result.group(1) if not self.class_name: # this is the first class declared in the file: insert the # new ones before this out_lines.append('<%swxGlade insert new_classes>' % self.nonce) self.new_classes_inserted = True self.class_name = result.group(1) self.class_name = self.format_classname(self.class_name) self.classes[self.class_name] = 1 # add the found class to the list # of classes of this module out_lines.append(line) elif not inside_block: result = self.rec_block_start.match(line) if result: ## print ">> block %r %r %r" % ( ## result.group('spaces'), result.group('classname'), result.group('block')) # replace the lines inside a wxGlade block with a tag that # will be used later by add_class spaces = result.group('spaces') which_class = result.group('classname') which_block = result.group('block') if not which_class: which_class = self.class_name else: which_class = self.format_classname(which_class) self.spaces[which_class] = spaces inside_block = True if not self.class_name: out_lines.append('<%swxGlade replace %s>' % \ (self.nonce, which_block)) else: out_lines.append('<%swxGlade replace %s %s>' % \ (self.nonce, which_class, which_block)) else: result = self.rec_event_handler.match(line) if result: which_handler = result.group('handler') which_class = self.format_classname(result.group('class')) self.event_handlers.setdefault( which_class, {})[which_handler] = 1 if self.class_name and self.is_end_of_class(line): # add extra event handlers here... out_lines.append('<%swxGlade event_handlers %s>' % (self.nonce, self.class_name)) out_lines.append(line) if self.is_import_line(line): # add a tag to allow extra modules out_lines.append('<%swxGlade extra_modules>\n' % self.nonce) else: # ignore all the lines inside a wxGlade block if self.rec_block_end.match(line): ## print 'end block' inside_block = False if not self.new_classes_inserted: # if we are here, the previous ``version'' of the file did not # contain any class, so we must add the new_classes tag at the # end of the file out_lines.append('<%swxGlade insert new_classes>' % self.nonce) # set the ``persistent'' content of the file self.content = "".join(out_lines) def is_import_line(self, line): return line.lstrip().startswith('use Wx') # end of class SourceFileContent class WidgetHandler(BaseWidgetHandler): """\ Interface the various code generators for the widgets must implement """ new_signature = [] """\ Constructor signature ($self->SUPER::new(@stuff)) @see: L{PerlCodeWriter.new_defaults} """ # end of class WidgetHandler class PerlCodeWriter(BaseCodeWriter): """\ Code writer class for writing Perl code out of the designed GUI elements @cvar _perl_constant_list: Incomplete list of wx constants used in wxPerl Constants don't follow the Wx::ObjectName name schema. There is a need to handle constants separately. See also L{cn}. @type _perl_constant_list: List of strings @see: L{BaseCodeWriter} """ default_extensions = ['pl', 'pm'] language = "perl" code_statements = { 'backgroundcolour': "%(objname)s->SetBackgroundColour(%(value)s);\n", 'disabled': "%(objname)s->Enable(0);\n", 'extraproperties': "%(objname)s->Set%(propname)s(%(value)s);\n", 'focused': "%(objname)s->SetFocus();\n", 'foregroundcolour': "%(objname)s->SetForegroundColour(%(value)s);\n", 'hidden': "%(objname)s->Show(0);\n", 'setfont': "%(objname)s->SetFont(Wx::Font->new(%(size)s, %(family)s, " "%(style)s, %(weight)s, %(underlined)s, %(face)s));\n", 'tooltip': "%(objname)s->SetToolTipString(%(tooltip)s);\n", 'wxcolour': "Wx::Colour->new(%(value)s)", 'wxsystemcolour': "Wx::SystemSettings::GetColour(%(value)s)", } class_separator = '::' classattr_always = ['wxBoxSizer', 'wxStaticBoxSizer', 'wxGridSizer', 'wxFlexGridSizer'] comment_sign = '#' global_property_writers = { 'font': BaseCodeWriter.FontPropertyHandler, 'events': BaseCodeWriter.EventsPropertyHandler, 'extraproperties': BaseCodeWriter.ExtraPropertiesPropertyHandler, } indent_amount = 1 indent_symbol = '\t' indent_level_func_body = 1 language_note = '# To get wxPerl visit http://wxPerl.sourceforge.net/\n' \ '#\n' name_ctor = 'new' new_defaults = [] """\ Default class members, will be initialised during L{initialize()} """ shebang = '#!/usr/bin/perl -w -- \n#\n' SourceFileContent = SourceFileContent tmpl_name_do_layout = '__do_layout' tmpl_name_set_properties = '__set_properties' tmpl_cfunc_end = '%(tab)sreturn $self;\n' \ '\n' \ '}\n' \ '\n' tmpl_class_end = '\n' \ '%(comment)s end of class %(klass)s\n' \ '\n' \ '1;\n' \ '\n' tmpl_ctor_call_layout = '\n' \ '%(tab)s$self->__set_properties();\n' \ '%(tab)s$self->__do_layout();\n\n' tmpl_func_do_layout = '\n' \ 'sub __do_layout {\n' \ '%(tab)smy $self = shift;\n' \ '%(content)s' \ '}\n' tmpl_func_event_stub = """\ sub %(handler)s { %(tab)smy ($self, $event) = @_; %(tab)s# wxGlade: %(klass)s::%(handler)s %(tab)swarn "Event handler (%(handler)s) not implemented"; %(tab)s$event->Skip; %(tab)s# end wxGlade } """ tmpl_func_set_properties = '\n' \ 'sub __set_properties {\n' \ '%(tab)smy $self = shift;\n' \ '%(content)s' \ '}\n' tmpl_func_empty = '%(tab)sreturn;\n' tmpl_sizeritem = '%s->Add(%s, %s, %s, %s);\n' tmpl_style = \ '%(tab)s$style = %(style)s \n' \ '%(tab)s%(tab)sunless defined $style;\n' \ '\n' tmpl_appfile = """%(overwrite)s%(header_lines)s""" tmpl_detailed = """\ package %(klass)s; use base qw(Wx::App); use strict; %(pl_import)s sub OnInit { %(tab)smy( $self ) = shift; %(tab)sWx::InitAllImageHandlers(); %(tab)smy $%(top_win)s = %(top_win_class)s->new(); %(tab)s$self->SetTopWindow($%(top_win)s); %(tab)s$%(top_win)s->Show(1); %(tab)sreturn 1; } # end of class %(klass)s package main; unless(caller){ %(tab)smy $%(name)s = %(klass)s->new(); %(tab)s$%(name)s->MainLoop(); } """ tmpl_gettext_detailed = """\ package %(klass)s; use base qw(Wx::App); use strict; %(pl_import)s sub OnInit { %(tab)smy( $self ) = shift; %(tab)sWx::InitAllImageHandlers(); %(tab)smy $%(top_win)s = %(top_win_class)s->new(); %(tab)s$self->SetTopWindow($%(top_win)s); %(tab)s$%(top_win)s->Show(1); %(tab)sreturn 1; } # end of class %(klass)s package main; unless(caller){ %(tab)smy $local = Wx::Locale->new("English", "en", "en"); # replace with ?? %(tab)s$local->AddCatalog("%(name)s"); # replace with the appropriate catalog name %(tab)smy $%(name)s = %(klass)s->new(); %(tab)s$%(name)s->MainLoop(); } """ tmpl_simple = """\ 1; package main; %(pl_import)s unless(caller){ %(tab)slocal *Wx::App::OnInit = sub{1}; %(tab)smy $%(name)s = Wx::App->new(); %(tab)sWx::InitAllImageHandlers(); %(tab)smy $%(top_win)s = %(top_win_class)s->new(); %(tab)s$%(name)s->SetTopWindow($%(top_win)s); %(tab)s$%(top_win)s->Show(1); %(tab)s$%(name)s->MainLoop(); } """ tmpl_gettext_simple = """\ 1; package main; %(pl_import)s unless(caller){ %(tab)smy $local = Wx::Locale->new("English", "en", "en"); # replace with ?? %(tab)s$local->AddCatalog("%(name)s"); # replace with the appropriate catalog name %(tab)slocal *Wx::App::OnInit = sub{1}; %(tab)smy $%(name)s = Wx::App->new(); %(tab)sWx::InitAllImageHandlers(); %(tab)smy $%(top_win)s = %(top_win_class)s->new(); %(tab)s$%(name)s->SetTopWindow($%(top_win)s); %(tab)s$%(top_win)s->Show(1); %(tab)s$%(name)s->MainLoop(); } """ _perl_constant_list = [ "wxALL", "wxTOP", "wxBOTTOM", "wxLEFT", "wxRIGHT", "wxNORTH", "wxSOUTH", "wxWEST", "wxEAST", "wxEXPAND", "wxGROW", "wxSHAPED", "wxFIXED_MINSIZE", "wxCAPTION", "wxMINIMIZE_BOX", "wxMAXIMIZE_BOX", "wxRESIZE_BORDER", "wxYES_NO", "wxYES", "wxNO", "wxCANCEL", "wxOK", "wxICON_EXCLAMATION", "wxICON_HAND", "wxICON_ERROR", "wxICON_QUESTION", "wxICON_INFORMATION", "wxBLACK", "wxWHITE", "wxRED", "wxBLUE", "wxGREEN", "wxCYAN", "wxLIGHT_GREY", 'wxDEFAULT', 'wxDECORATIVE', 'wxROMAN', 'wxSWISS', 'wxSCRIPT', 'wxMODERN', 'wxTELETYPE', 'wxNORMAL', 'wxSLANT', 'wxITALIC', 'wxNORMAL', 'wxLIGHT', 'wxBOLD', 'wxHORIZONTAL', 'wxVERTICAL', 'wxALIGN_CENTER', 'wxALIGN_CENTRE', 'wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_TOP', 'wxALIGN_BOTTOM','wxALIGN_CENTER_VERTICAL', 'wxALIGN_CENTRE_VERTICAL', 'wxALIGN_CENTER_HORIZONTAL', 'wxALIGN_CENTRE_HORIZONTAL', ] _quote_str_pattern = re.compile(r'\\(?![nrt])') def cn(self, name): """\ Return the name properly formatted. @see: L{self._perl_constant_list} """ # handles constants like event or language identifiers if name.startswith('wxID_') or \ name.startswith('wxK_') or \ name.startswith('wxMOD_') or \ name.startswith('wxLANGUAGE_') or \ name.startswith('wxALIGN_') or \ name in self._perl_constant_list: return name # don't process already formatted items again if name.startswith('Wx::'): return name # use default for remaining names if name[:2] == 'wx': return 'Wx::' + name[2:] elif name[:4] == 'EVT_': return 'Wx::' + name return name def initialize(self, app_attrs): """\ Writer initialization function. @keyword path: Output path for the generated code (a file if multi_files is False, a dir otherwise) @keyword option: If True, generate a separate file for each custom class """ # initialise parent class BaseCodeWriter.initialize(self, app_attrs) out_path = app_attrs['path'] # initial new defaults late to use the proper indent characters tab = self.tabs(1) self.new_defaults = { '$parent' : '%s$parent = undef unless defined $parent;\n' % tab, '$id' : '%s$id = -1 unless defined $id;\n' % tab, '$title' : '%s$title = "" unless defined $title;\n' % tab, '$pos' : '%s$pos = wxDefaultPosition unless defined $pos;\n' % tab, '$size' : '%s$size = wxDefaultSize unless defined $size;\n' % tab, '$name' : '%s$name = "" unless defined $name;\n\n' % tab, #'$style' is a special case } self.header_lines = [ 'use Wx 0.15 qw[:allclasses];\n', 'use strict;\n' ] self._initialize_stage2(out_path) def setup(self): """\ Load language specific code generators and sizer code generators @see: L{_setup()} """ # load perl_codegen's ... self._setup() # ... then, the sizers import edit_sizers.perl_sizers_codegen edit_sizers.perl_sizers_codegen.initialize() def add_app(self, app_attrs, top_win_class): # add language specific mappings if self.multiple_files: self.lang_mapping['pl_import'] = "\nuse %s;\n" % top_win_class else: self.lang_mapping['pl_import'] = '' BaseCodeWriter.add_app(self, app_attrs, top_win_class) def generate_code_ctor(self, code_obj, is_new, tab): code_lines = [] write = code_lines.append builder = self.obj_builders[code_obj.base] mycn = getattr(builder, 'cn', self.cn) mycn_f = getattr(builder, 'cn_f', self.cn_f) # custom base classes support custom_base = getattr(code_obj, 'custom_base', code_obj.properties.get('custom_base', None)) if code_obj.preview or (custom_base and not custom_base.strip()): custom_base = None new_signature = getattr(builder, 'new_signature', [] ) # generate constructor code if is_new: write('package %s;\n\n' % code_obj.klass) write('use Wx qw[:everything];\nuse base qw(%s);\nuse strict;\n\n' % code_obj.base.replace('wx', 'Wx::', 1)) if self._use_gettext: if self.multiple_files: self.classes[code_obj.klass].dependencies[ "use Wx::Locale gettext => '_T';\n"] = 1 else: write("use Wx::Locale gettext => '_T';\n") if self.multiple_files: # write the module dependecies for this class (package) dep_list = self.classes[code_obj.klass].dependencies.keys() dep_list.sort() code = self._tagcontent('dependencies', dep_list, True) write('\n') write('sub new {\n') write(tab + "my( $self, %s ) = @_;\n" % ", ".join(new_signature)) if new_signature: for k in new_signature: if self.new_defaults.has_key(k): write(self.new_defaults[k]) else: new_signature = ['@_[1 .. $#_]'] # shift(@_)->SUPER::new(@_); print code_obj.klass + " did not declare self.new_defaults " elif custom_base: # custom base classes set, but "overwrite existing sources" not # set. Issue a warning about this self.warning( '%s has custom base classes, but you are not overwriting ' 'existing sources: please check that the resulting code is ' 'correct!' % code_obj.name ) # __init__ begin tag write(self.tmpl_block_begin % { 'class_separator': self.class_separator, 'comment_sign': self.comment_sign, 'function': self.name_ctor, 'klass': self.cn_class(code_obj.klass), 'tab': tab, }) prop = code_obj.properties style = prop.get("style", None) if style: stmt_style = self._format_style(style, code_obj) write(stmt_style % { 'style': mycn_f(style), 'tab': tab, }) # class parent constructor write(tab + '$self = $self->SUPER::new( %s );\n' % ", ".join(new_signature)) # classes[code_obj.klass].deps now contains a mapping of child to # parent for all children we processed... object_order = [] for obj in self.classes[code_obj.klass].child_order: # Don't add it again if already present if obj in object_order: continue object_order.append(obj) # Insert parent and ancestor objects before the current object current_object = obj for child, parent in self.classes[code_obj.klass].deps[:]: if child is current_object: if parent not in object_order: idx = object_order.index(current_object) object_order.insert(idx, parent) current_object = parent # We processed the dependency: remove it self.classes[code_obj.klass].deps.remove((child, parent)) # Write out the initialisation in the order we just generated for obj in object_order: if obj in self.classes[code_obj.klass].init_lines: for l in self.classes[code_obj.klass].init_lines[obj]: write(tab + l) return code_lines def generate_code_event_bind(self, code_obj, tab, event_handlers): code_lines = [] write = code_lines.append for win_id, event, handler in event_handlers: if win_id.startswith('#'): win_id = '$self->{%s}->GetId' % win_id[8:] # remove leading "Wx::" for already formatted event names if event.startswith('Wx::EVT'): event = event[4:] write('%(tab)sWx::Event::%(event)s($self, %(win_id)s, \\&%(handler)s);\n' % { 'tab': tab, 'event': event, 'win_id': win_id, 'handler': handler, }) if event_handlers: write('\n') return code_lines def generate_code_id(self, obj, id=None): if id is None: id = obj.properties.get('id') if not id: return '', self.cn('wxID_ANY') tokens = id.split('=', 1) if len(tokens) == 2: name, val = tokens else: return '', self.cn(tokens[0]) # we assume name is declared elsewhere if not name: return '', self.cn(val) name = name.strip() val = val.strip() if val == '?': val = self.cn('wxNewId()') else: val = self.cn(val) # check to see if we have to make the var global or not... return ('use constant %s => %s;\n' % (name, val), name) def generate_code_size(self, obj): objname = self._get_code_name(obj) size = obj.properties.get('size', '').strip() use_dialog_units = (size[-1] == 'd') if not obj.parent: method = 'SetSize' else: method = 'SetMinSize' if use_dialog_units: return '%s->%s(%s->ConvertDialogSizeToPixels(Wx::Size->new(%s)));\n' % ( objname, method, objname, size[:-1], ) else: return '%s->%s(Wx::Size->new(%s));\n' % (objname, method, size) def quote_str(self, s, translate=True, escape_chars=True): if not s: return '""' s = self._quote_str_pattern.sub(r'\\\\', s ) s = s.replace('"', r'\"') s = s.replace('$', r'\$') s = s.replace('@', r'\@') try: dummy = unicode(s, 'ascii') except UnicodeDecodeError: # convert byte string to unicode, escape unicode characters and # convert string back to ascii s = s.decode('utf8') s = s.encode('unicode-escape') # convert Python style to Perl style s = re.sub(r'\\u([0-9]{4})\b', r'\\N{U+\1}', s) if self._use_gettext and translate: return '_T("%s")' % s else: return '"%s"' % s def quote_key(self, s): """\ returns a possibly quoted version of 's', suitable to insert in a perl source file as a hask key. Takes care also of gettext support """ if not s: return '""' t = s s = self._quote_str_pattern.sub(r'\\\\', s) s = s.replace('"', r'\"') s = s.replace('$', r'\$') s = s.replace('@', r'\@') if self._use_gettext: return '_T("%s")' %s if t == s and s.find(' ') < 0: return s else: return '"%s"' % s def _add_object_format_name(self, name): return '#$self->%s' % name def _format_classattr(self, obj): res = BaseCodeWriter._format_classattr(self, obj) if not res: return res elif obj.name.startswith('$self->'): return obj.name elif obj.name.startswith('$'): return obj.name # spacer.name is ", " already elif obj.klass == 'spacer': return obj.name # Perl stores sizers always in class attributes elif self.test_attribute(obj) or obj.in_sizers: return '$self->{%s}' % obj.name return '$%s' % obj.name def _format_import(self, klass): stmt = 'use %s;\n' % klass return stmt def _get_class_filename(self, klass): """ Returns the name for a Perl module (.pm) to store a single class in multi file projects. @param klass: Class name @type klass: String @rtype: String """ filename = os.path.join( self.out_dir, klass.replace('::', os.sep) + '.pm' ) return filename def _get_code_name(self, obj): if obj.is_toplevel: return '$self' else: return self._format_classattr(obj) # end of class PerlCodeWriter writer = PerlCodeWriter() """\ The code writer is an instance of L{PerlCodeWriter}. """ language = writer.language """\ Language generated by this code generator """ wxglade-0.6.8.orig/codegen/lisp_codegen.py0000644000175000017500000006301412150161240020722 0ustar georgeskgeorgesk"""\ Lisp code generator How the code is generated: every time the end of an object is reached during the parsing of the xml tree, either the function 'add_object' or the function 'add_class' is called: the latter when the object is a toplevel one, the former when it is not. In the last case, 'add_object' calls the appropriate ``writer'' function for the specific object, found in the 'obj_builders' dict. Such function accepts one argument, the CodeObject representing the object for which the code has to be written, and returns 3 lists of strings, representing the lines to add to the '__init__', '__set_properties' and '__do_layout' methods of the parent object. @copyright: 2005 Surendra K Singhi @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import os import os.path import re import types from codegen import BaseCodeWriter, \ BaseSourceFileContent, \ BaseWidgetHandler class SourceFileContent(BaseSourceFileContent): rec_block_start = re.compile( r'^(?P\s*)' # leading spaces r';;;\s*' # comment sign r'begin\s+wxGlade:\s*' # "begin wxGlade:" statement and tailing spaces r'(?P[a-zA-Z_]+\w*)??' # class or function name (non-greedy) r'[.]?' # separator between class and function / block (non-gready) r'(?P\w+)' # function / block name r'\s*$' # tailing spaces ) rec_block_end = re.compile( r'^\s*' # leading spaces r';;;\s*' # comment sign r'end\s+wxGlade' # "end exGlade" statement r'\s*$' # tailing spaces ) rec_class_decl = re.compile( r'^\s*' # leading spaces r'\(defclass\s+([a-zA-Z_]\w*)\s*(\(\s*\))' # "class " statement r'\s*$' # tailing spaces ) rec_event_handler = re.compile( r'^\s+' # leading spaces (mandatory) r'def\s+(?P[A-Za-z_]+\w*)' # event handler name r'\s*' # optional spaces r'\(.*\):' # function parameters r'\s*' # optional spaces r';;;\s*wxGlade:\s*(?P\w+)\.' # wxGlade event handler statement with class name r'\s*$' # tailing spaces ) def build_untouched_content(self): BaseSourceFileContent.build_untouched_content(self) inside_block = False inside_triple_quote = False triple_quote_str = None tmp_in = self._load_file(self.name) out_lines = [] for line in tmp_in: quote_index = -1 if not inside_triple_quote: triple_dquote_index = line.find('"""') triple_squote_index = line.find("'''") if triple_squote_index == -1: quote_index = triple_dquote_index tmp_quote_str = '"""' elif triple_dquote_index == -1: quote_index = triple_squote_index tmp_quote_str = "'''" else: quote_index, tmp_quote_str = min( (triple_squote_index, "'''"), (triple_dquote_index, '"""')) if not inside_triple_quote and quote_index != -1: inside_triple_quote = True triple_quote_str = tmp_quote_str if inside_triple_quote: end_index = line.rfind(triple_quote_str) if quote_index < end_index and end_index != -1: inside_triple_quote = False result = self.rec_class_decl.match(line) if not inside_triple_quote and result: ## print ">> class %r" % result.group(1) if not self.class_name: # this is the first class declared in the file: insert the # new ones before this out_lines.append('<%swxGlade insert new_classes>' % self.nonce) self.new_classes_inserted = True self.class_name = result.group(1) self.class_name = self.format_classname(self.class_name) self.classes[self.class_name] = 1 # add the found class to the list # of classes of this module out_lines.append(line) elif not inside_block: result = self.rec_block_start.match(line) if not inside_triple_quote and result: ## print ">> block %r %r %r" % ( ## result.group('spaces'), result.group('classname'), result.group('block')) # replace the lines inside a wxGlade block with a tag that # will be used later by add_class spaces = result.group('spaces') which_class = result.group('classname') which_block = result.group('block') if not which_class: which_class = self.class_name else: which_class = self.format_classname(which_class) self.spaces[which_class] = spaces inside_block = True if not self.class_name: out_lines.append('<%swxGlade replace %s>' % \ (self.nonce, which_block)) else: out_lines.append('<%swxGlade replace %s %s>' % \ (self.nonce, which_class, which_block)) else: result = self.rec_event_handler.match(line) if not inside_triple_quote and result: which_handler = result.group('handler') which_class = self.format_classname(result.group('class')) self.event_handlers.setdefault( which_class, {})[which_handler] = 1 if self.class_name and self.is_end_of_class(line): # add extra event handlers here... out_lines.append('<%swxGlade event_handlers %s>' % (self.nonce, self.class_name)) out_lines.append(line) if self.is_import_line(line): # add a tag to allow extra modules out_lines.append('<%swxGlade extra_modules>\n' % self.nonce) else: # ignore all the lines inside a wxGlade block if self.rec_block_end.match(line): ## print 'end block' inside_block = False if not self.new_classes_inserted: # if we are here, the previous ``version'' of the file did not # contain any class, so we must add the new_classes tag at the # end of the file out_lines.append('<%swxGlade insert new_classes>' % self.nonce) # set the ``persistent'' content of the file self.content = "".join(out_lines) def is_import_line(self, line): return line.startswith('(use-package :wx') # end of class SourceFileContent class WidgetHandler(BaseWidgetHandler): pass # end of class WidgetHandler class LispCodeWriter(BaseCodeWriter): """\ Code writer class for writing Lisp code out of the designed GUI elements @see: L{BaseCodeWriter} """ default_extensions = ['lisp'] language = "lisp" code_statements = { 'backgroundcolour': "(wxWindow_SetBackgroundColour %(objname)s %(value)s)\n", 'disabled': "(wxWindow_IsEnabled %(objname)s0)\n", 'extraproperties': "(%(klass)s_Set%(propname)s (slot-%(objname)s obj) %(value)s)\n", 'focused': "(wxWindow_SetFocus %(objname)s)\n", 'foregroundcolour': "(wxWindow_SetForegroundColour %(objname)s %(value)s)\n", 'hidden': "(wxWindow_Hide %(objname)s)\n", 'setfont': "(wxWindow_SetFont %(objname)s (wxFont_Create %(size)s %(family)s " "%(style)s %(weight)s %(underlined)s %(face)s wxFONTENCODING_DEFAULT))\n", 'tooltip': "(wxWindow_SetToolTip %(objname)s%(tooltip)s)\n", 'wxcolour': "(wxColour_CreateRGB %(value)s)", 'wxsystemcolour': "(wxSystemSettings_GetColour %(value)s)", } class_separator = '.' classattr_always = ['wxBoxSizer', 'wxStaticBoxSizer', 'wxGridSizer', 'wxFlexGridSizer'] comment_sign = ';;;' global_property_writers = { 'font': BaseCodeWriter.FontPropertyHandler, 'events': BaseCodeWriter.EventsPropertyHandler, 'extraproperties': BaseCodeWriter.ExtraPropertiesPropertyHandler, } indent_level_func_body = 2 name_ctor = '__init__' shebang = '#!/usr/bin/env lisp\n;;;\n' SourceFileContent = SourceFileContent tmpl_name_do_layout = '__do_layout' tmpl_name_set_properties = '__set_properties' tmpl_cfunc_end = '%(tab)s)\n' tmpl_class_end = '\n' \ '%(comment)s end of class %(klass)s\n' \ '\n' \ '\n' tmpl_func_do_layout = '\n' \ '(defmethod do-layout ((obj %(klass)s))\n' \ '%(content)s' \ '%(tab)s)\n' tmpl_func_event_stub = """\ (defun %(handler)s (function data event) ;;; wxGlade: %(klass)s. %(tab)s(print "Event handler '%(handler)s' not implemented!") %(tab)s(when event %(tab)s%(tab)s(wxEvent:wxEvent_Skip event))) """ tmpl_func_set_properties = '\n' \ '(defmethod set-properties ((obj %(klass)s))\n' \ '%(content)s' \ '%(tab)s)\n' tmpl_func_empty = '%(tab)spass\n' tmpl_appfile = """\ %(overwrite)s\ %(header_lines)s\ (require "%(top_win_class)s") """ tmpl_detailed = """\ (defun init-func (fun data evt) %(tab)s%(tab)s(let ((%(top_win)s (make-%(top_win_class)s))) %(tab)s%(tab)s(ELJApp_SetTopWindow (slot-top-window %(top_win)s)) %(tab)s%(tab)s(wxWindow_Show (slot-top-window %(top_win)s)))) ;;; end of class %(klass)s (unwind-protect %(tab)s(Eljapp_initializeC (wxclosure_Create #'init-func nil) 0 nil) %(tab)s(ffi:close-foreign-library "../miscellaneous/wxc-msw2.6.2.dll")) """ tmpl_gettext_detailed = """\ (defun init-func (fun data evt) %(tab)s%(tab)s(let ((%(top_win)s (make-%(top_win_class)s))) %(tab)s%(tab)s(ELJApp_SetTopWindow (slot-top-window %(top_win)s)) %(tab)s%(tab)s(wxWindow_Show (slot-top-window %(top_win)s)))) ;;; end of class %(klass)s %(tab)s(setf (textdomain) "%(name)s") ;; replace with the appropriate catalog name %(tab)s(defun _ (msgid) (gettext msgid "%(name)s")) (unwind-protect %(tab)s(Eljapp_initializeC (wxclosure_Create #'init-func nil) 0 nil) %(tab)s(ffi:close-foreign-library "../miscellaneous/wxc-msw2.6.2.dll")) """ tmpl_simple = """\ (defun init-func (fun data evt) %(tab)s(let ((%(top_win)s (make-%(top_win_class)s))) %(tab)s(ELJApp_SetTopWindow (slot-top-window %(top_win)s)) %(tab)s(wxWindow_Show (slot-top-window %(top_win)s)))) (unwind-protect %(tab)s(Eljapp_initializeC (wxclosure_Create #'init-func nil) 0 nil) %(tab)s(ffi:close-foreign-library "../miscellaneous/wxc-msw2.6.2.dll")) """ tmpl_gettext_simple = """\ (defun init-func (fun data evt) %(tab)s(setf (textdomain) "%(name)s") ;; replace with the appropriate catalog name %(tab)s(defun _ (msgid) (gettext msgid "%(name)s")) %(tab)s(let ((%(top_win)s (make-%(top_win_class)s))) %(tab)s(ELJApp_SetTopWindow (slot-top-window %(top_win)s)) %(tab)s(wxWindow_Show (slot-top-window %(top_win)s)))) (unwind-protect %(tab)s(Eljapp_initializeC (wxclosure_Create #'init-func nil) 0 nil) %(tab)s(ffi:close-foreign-library "../miscellaneous/wxc-msw2.6.2.dll")) """ def cn(self, name): """\ Return the name properly formatted. """ if name[:2] == 'wx': return 'wx' + name[2:] elif name[:4] == 'EVT_': return 'wx' + name return name def cn_f(self, flags): """\ Return the flags properly formatted. @see: L{cn()} """ # don't process integer values if type(flags) == types.IntType: return flags # format single flags first flags = [self.cn(f) for f in flags.split('|')] if len(flags) == 1: flags = flags[0] else: flags = '(logior %s)' % ' '.join(flags) return flags def initialize(self, app_attrs): """\ Writer initialization function. @keyword path: Output path for the generated code (a file if multi_files is False, a dir otherwise) @keyword option: If True, generate a separate file for each custom class """ # initialise parent class BaseCodeWriter.initialize(self, app_attrs) out_path = app_attrs['path'] self.class_lines = [] self.header_lines = [ """(asdf:operate 'asdf:load-op 'wxcl)\n""", """(use-package "FFI")\n""", """(ffi:default-foreign-language :stdc)\n\n""", ] self.dependencies = { '(use-package :wxCL)': 1, '(use-package :wxFrame)': 1, '(use-package :wx_main)': 1, '(use-package :wx_wrapper)': 1, '(use-package :wxWindow)': 1, '(use-package :wxColour)': 1, '(use-package :wxEvtHandler)': 1, '(use-package :wxEvent)': 1, } self._initialize_stage2(out_path) def setup(self): """\ Load language specific code generators and sizer code generators @see: L{_setup()} """ # load lisp_codegen's ... self._setup() # ... then, the sizers import edit_sizers.lisp_sizers_codegen edit_sizers.lisp_sizers_codegen.initialize() def add_app(self, app_attrs, top_win_class): top_win = app_attrs.get('top_window') # do nothing if there is no top window if not top_win: return # add language specific mappings self.lang_mapping = { 'top_win': self._format_name(top_win), } BaseCodeWriter.add_app(self, app_attrs, top_win_class) def add_object(self, top_obj, sub_obj): # the lisp code gen add some hard coded depedencies # TODO: Move the hard coded dependencies to the widgets resp. sizers sub_obj.name = self._format_name(sub_obj.name) sub_obj.parent.name = self._format_name(sub_obj.parent.name) # get top level source code object and the widget builder instance klass, builder = self._add_object_init(top_obj, sub_obj) if not klass or not builder: return if(sub_obj.name != "spacer"): self.class_lines.append(sub_obj.name) if (sub_obj.klass == "wxBoxSizer" or \ sub_obj.klass == "wxStaticBoxSizer" or \ sub_obj.klass == "wxGridSizer" or \ sub_obj.klass == "wxFlexGridSizer"): self.dependencies['(use-package :wxSizer)'] = 1 else: if (sub_obj.klass != "spacer"): key = '(use-package :%s)' % sub_obj.klass self.dependencies[key] = 1 if (sub_obj.klass == "wxMenuBar"): self.dependencies['(use-package :wxMenu)'] = 1 BaseCodeWriter.add_object(self, top_obj, sub_obj) def add_sizeritem(self, toplevel, sizer, obj, option, flag, border): if obj.in_sizers: self.tmpl_sizeritem = '(wxSizer_AddSizer (%s obj) (%s obj) %s %s %s nil)\n' else: self.tmpl_sizeritem = '(wxSizer_AddWindow (%s obj) (%s obj) %s %s %s nil)\n' BaseCodeWriter.add_sizeritem( self, toplevel, sizer, obj, option, flag, border, ) def generate_code_background(self, obj): self.dependencies['(use-package :wxColour)'] = 1 return BaseCodeWriter.generate_code_background(self, obj) def generate_code_ctor(self, code_obj, is_new, tab): code_lines = [] write = code_lines.append builder = self.obj_builders[code_obj.base] mycn = getattr(builder, 'cn', self.cn) mycn_f = getattr(builder, 'cn_f', self.cn_f) # custom base classes support custom_base = getattr(code_obj, 'custom_base', code_obj.properties.get('custom_base', None)) if code_obj.preview or (custom_base and not custom_base.strip()): custom_base = None # generate constructor code if is_new: base = mycn(code_obj.base) klass = code_obj.klass write('\n(defclass %s()\n' % klass) write(tab + "((top-window :initform nil :accessor slot-top-window)") for l in self.class_lines: write("\n") write(tab + "(" + l + " :initform nil :accessor slot-" + l + ")") write("))\n") write("\n(defun make-%s ()\n" % klass) write(tab + "(let ((obj (make-instance '%s)))\n" % klass) write(tab + " (init obj)\n") write(tab + " (set-properties obj)\n") write(tab + " (do-layout obj)\n") write(tab + " obj))\n") write('\n(defmethod init ((obj %s))\n' % klass) write("\"Method creates the objects contained in the class.\"\n") elif custom_base: # custom base classes set, but "overwrite existing sources" not # set. Issue a warning about this self.warning( '%s has custom base classes, but you are not overwriting ' 'existing sources: please check that the resulting code is ' 'correct!' % code_obj.name ) # __init__ begin tag write(self.tmpl_block_begin % { 'class_separator': self.class_separator, 'comment_sign': self.comment_sign, 'function': self.name_ctor, 'klass': self.cn_class(code_obj.klass), 'tab': tab, }) prop = code_obj.properties style = prop.get("style", None) if style: stmt_style = self._format_style(style, code_obj) write(stmt_style % { 'style': mycn_f(style), 'tab': tab, }) # classes[code_obj.klass].deps now contains a mapping of child to # parent for all children we processed... object_order = [] for obj in self.classes[code_obj.klass].child_order: # Don't add it again if already present if obj in object_order: continue object_order.append(obj) # Insert parent and ancestor objects before the current object current_object = obj for child, parent in self.classes[code_obj.klass].deps[:]: if child is current_object: if parent not in object_order: idx = object_order.index(current_object) object_order.insert(idx, parent) current_object = parent # We processed the dependency: remove it self.classes[code_obj.klass].deps.remove((child, parent)) # Write out the initialisation in the order we just generated for obj in object_order: if obj in self.classes[code_obj.klass].init_lines: for l in self.classes[code_obj.klass].init_lines[obj]: write(tab + l) return code_lines def generate_code_event_bind(self, code_obj, tab, event_handlers): code_lines = [] write = code_lines.append if event_handlers: write('\n') for win_id, event, handler in event_handlers: if win_id.startswith('#'): win_id = win_id[1:] write( "%(tab)s(wxEvtHandler_Connect (slot-top-window obj) %(win_id)s (exp%(event)s)" \ "\n%(tab2)s" \ "(wxClosure_Create #'%(handler)s obj))\n" % { 'tab': tab, 'tab2': self.tabs(2), 'win_id': win_id, 'event': event, 'handler': handler, } ) return code_lines def generate_code_font(self, obj): self.dependencies['(use-package :wxFont)'] = 1 return BaseCodeWriter.generate_code_font(self, obj) def generate_code_foreground(self, obj): self.dependencies['(use-package :wxColour)'] = 1 return BaseCodeWriter.generate_code_foreground(self, obj) def generate_code_id(self, obj, id=None): if id is None: id = obj.properties.get('id') if not id: return '', self.cn('wxID_ANY') tokens = id.split('=', 1) if len(tokens) == 2: name, val = tokens else: return '', self.cn(tokens[0]) # we assume name is declared elsewhere if not name: return '', self.cn(val) name = name.strip() val = val.strip() if val == '?': val = self.cn('wxNewId()') else: val = self.cn(val) # check to see if we have to make the var global or not... if '.' in name: return ('%s = %s\n' % (name, val), name) return ('global %s; %s = %s\n' % (name, name, val), name) def generate_code_size(self, obj): objname = self._get_code_name(obj) size = obj.properties.get('size', '').strip() use_dialog_units = (size[-1] == 'd') if not obj.parent: method = 'wxWindow_SetSize' else: method = 'SetMinSize' if use_dialog_units: return '(%s %s(%s(%s (%s))))\n' % ( method, objname, self.cn('wxDLG_SZE'), objname, size[:-1], ) else: return '%s.%s((%s))\n' % (objname, method, size) def quote_str(self, s, translate=True, escape_chars=True): if not s: return '""' s = s.replace('"', r'\"') if escape_chars: s = self._quote_str_pattern.sub(self._do_replace, s) else: s = s.replace('\\', r'\\') # just quote the backslashes if self._use_gettext and translate: return '(_"%s")' % s else: return '"%s"' % s def _add_object_format_name(self, name): return '#obj.%s' % name def _format_classattr(self, obj): res = BaseCodeWriter._format_classattr(self, obj) if not res: return res elif obj.name.startswith('slot-'): return obj.name # spacer.name is ", " already, but wxLisp expect # a tuple instead of two single values elif obj.klass == 'spacer': return '(%s)' % obj.name # wxList use class attributes always (unfortunately) # elif self.test_attribute(obj): # return "slot-%s" % self._format_name(obj.name) # return self._format_name(obj.name) return 'slot-%s' % self._format_name(obj.name) def _format_import(self, klass): stmt = '(require "%s")\n' % klass return stmt def _format_style(self, style, code_obj): builder = self.obj_builders[code_obj.base] mycn_f = getattr(builder, 'cn_f', self.cn_f) if not style: return '' style = mycn_f(style) style = style.strip().replace('.', '') if code_obj.base == "wxFrame": stmt = '%%(tab)s(setf (slot-top-window obj) (wxFrame_create nil ' \ 'wxID_ANY \"\" -1 -1 -1 -1 %s))\n' % style elif code_obj.base == "wxDialog": stmt = '%%(tab)s(setf (slot-top-window obj) (wxDialog_create ' \ 'nil wxID_ANY \"\" -1 -1 -1 -1 %s))\n' % style self.dependencies['(use-package :wxButton)'] = 1 return stmt def _get_class_filename(self, klass): filename = os.path.join( self.out_dir, klass.replace('.', '_') + '.lisp' ) return filename def _get_code_name(self, obj): if obj.is_toplevel: return '(slot-top-window obj)' else: if self.test_attribute(obj): return '(slot-%s obj)' % obj.name else: return obj.name def _format_name(self, name): return name.replace('_', '-') # end of class LispCodeWriter writer = LispCodeWriter() """\ The code writer is an instance of L{LispCodeWriter}. """ language = writer.language """\ Language generated by this code generator """ wxglade-0.6.8.orig/codegen/cpp_codegen.py0000644000175000017500000017274112150154266020557 0ustar georgeskgeorgesk"""\ C++ code generator How the code is generated: every time the end of an object is reached during the parsing of the xml tree, either the function 'add_object' or the function 'add_class' is called: the latter when the object is a toplevel one, the former when it is not. In the last case, 'add_object' calls the appropriate ``writer'' function for the specific object, found in the 'obj_builders' dict. Such function accepts one argument, the CodeObject representing the object for which the code has to be written, and returns 3 lists of strings, representing the lines to add to the '__init__', '__set_properties' and '__do_layout' methods of the parent object. @copyright: 2002-2007 Alberto Griggio @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import cStringIO import os import os.path import re from codegen import BaseCodeWriter, \ BaseSourceFileContent, \ BaseWidgetHandler class SourceFileContent(BaseSourceFileContent): """\ Keeps info about an existing file that has to be updated, to replace only the lines inside a wxGlade block, an to keep the rest of the file as it was @ivar event_handlers: List of event handlers for each class @ivar header_content: Content of the header file @ivar source_content: Content of the source file """ rec_block_start = re.compile( r'^(?P\s*)' # leading spaces r'//\s*' # comment sign r'begin\s+wxGlade:\s*' # "begin wxGlade:" statement and tailing spaces r'(?P\w*)' # class or function name r'::' # separator between class and function / block (non-greedy) r'(?P\w+)' # function / block name r'\s*$' # tailing spaces ) rec_block_end = re.compile( r'^\s*' # leading spaces r'//\s*' # comment sign r'end\s+wxGlade' # "end exGlade" statement r'\s*$' # tailing spaces ) rec_class_end = re.compile( r'^\s*};\s*' # closing curly brackets r'//\s*' # comment sign r'wxGlade:\s+end\s+class' # "wxGlade: end class" statement r'\s*$' # tailing spaces ) """\ Regexp to match last line of a class statement """ rec_class_decl = re.compile( r'^\s*' # leading spaces r'class\s+([a-zA-Z_]\w*)' # "class " statement r'\s*' # tailing spaces ) """\ Regexp to match class declarations This isn't very accurate - doesn't match template classes, nor virtual inheritance, but should be enough for most cases """ rec_decl_event_table = re.compile( r'^\s*' # leading spaces r'DECLARE_EVENT_TABLE\s*\(\s*\)\s*;?' # declaration of the event table r'\s*$' # tailing spaces ) """\ Regexp to match declaration of event table """ rec_def_event_table = re.compile( r'^\s*' # leading spaces r'BEGIN_EVENT_TABLE\s*\(\s*(\w+)\s*,\s*(\w+)\s*\)' r'\s*$' # tailing spaces ) """\ Regexp to match event table """ rec_event_handler = re.compile( r'^\s*' # leading spaces r'(?:virtual\s+)?' r'void\s+(?P[A-Za-z_]+\w*)' # event handler name r'\s*' # optional spaces r'\([A-Za-z_:0-9]+\s*&\s*\w*\)\s*;' r'\s*' # optional spaces r'//\s*wxGlade:\s*' # wxGlade event handler statement r'\s*$' # tailing spaces ) rec_event_handlers_marker = re.compile( r'^\s*' # leading spaces r'//\s*wxGlade:\s*add\s+' r'((?:\w|:)+)\s+event handlers' r'\s*$' # tailing spaces ) """\ Regexp to match wxGlade comment of event handlers """ def __init__(self, name, code_writer): # initialise new variables first self.header_content = None self.source_content = None self.event_table_decl = {} self.event_table_def = {} self.header_extension = code_writer.header_extension self.source_extension = code_writer.source_extension # call inherited constructor BaseSourceFileContent.__init__(self, name, code_writer) def build_untouched_content(self): BaseSourceFileContent.build_untouched_content(self) self._build_untouched(self.name + self.header_extension, True) BaseSourceFileContent.build_untouched_content(self) self._build_untouched(self.name + self.source_extension, False) def _build_untouched(self, filename, is_header): prev_was_handler = False events_tag_added = False inside_block = False inside_comment = False tmp_in = self._load_file(filename) out_lines = [] for line in tmp_in: comment_index = line.find('/*') if not inside_comment and comment_index != -1 \ and comment_index > line.find('//'): inside_comment = True if inside_comment: end_index = line.find('*/') if end_index > comment_index: inside_comment = False if not is_header: result = None else: result = self.rec_class_decl.match(line) if not inside_comment and not inside_block and result: ## print ">> class %r" % result.group(1) if not self.class_name: # this is the first class declared in the file: insert the # new ones before this out_lines.append('<%swxGlade insert new_classes>' % self.nonce) self.new_classes_inserted = True self.class_name = result.group(1) self.class_name = self.format_classname(self.class_name) self.classes[self.class_name] = 1 # add the found class to the list # of classes of this module out_lines.append(line) elif not inside_block: result = self.rec_block_start.match(line) if not inside_comment and result: ## print ">> block %r %r %r" % ( ## result.group('spaces'), result.group('classname'), result.group('block')) # replace the lines inside a wxGlade block with a tag that # will be used later by add_class spaces = result.group('spaces') which_class = result.group('classname') which_block = result.group('block') if not which_class: which_class = self.class_name else: which_class = self.format_classname(which_class) self.spaces[which_class] = spaces inside_block = True out_lines.append('<%swxGlade replace %s %s>' % ( self.nonce, result.group('classname'), result.group('block') )) else: dont_append = False # ALB 2004-12-08 event handling support... if is_header and not inside_comment: result = self.rec_event_handler.match(line) if result: prev_was_handler = True which_handler = result.group('handler') which_class = self.class_name self.event_handlers.setdefault( which_class, {})[which_handler] = 1 else: if prev_was_handler: # add extra event handlers here... out_lines.append('<%swxGlade event_handlers %s>' % (self.nonce, self.class_name) ) prev_was_handler = False events_tag_added = True elif not events_tag_added and \ self.is_end_of_class(line): out_lines.append( '<%swxGlade event_handlers %s>' % \ (self.nonce, self.class_name) ) # now try to see if we already have a # DECLARE_EVENT_TABLE result = self.rec_decl_event_table.match(line) if result: self.event_table_decl[self.class_name] = True elif not inside_comment: result = self.rec_event_handlers_marker.match(line) if result: out_lines.append('<%swxGlade add %s event ' 'handlers>' % \ (self.nonce, result.group(1))) dont_append = True result = self.rec_def_event_table.match(line) if result: which_class = result.group(1) self.event_table_def[which_class] = True # ---------------------------------------- if not dont_append: out_lines.append(line) else: # ignore all the lines inside a wxGlade block if self.rec_block_end.match(line): inside_block = False if is_header and not self.new_classes_inserted: # if we are here, the previous ``version'' of the file did not # contain any class, so we must add the new_classes tag at the # end of the file out_lines.append('<%swxGlade insert new_classes>' % self.nonce) # set the ``persistent'' content of the file if is_header: self.header_content = "".join(out_lines) else: self.source_content = "".join(out_lines) def is_end_of_class(self, line): """\ Return True if the line is the last line of a class Not really, but for wxglade-generated code it should work... """ return self.rec_class_end.match(line) # end of class SourceFileContent class WidgetHandler(BaseWidgetHandler): """\ Interface the various code generators for the widgets must implement """ constructor = [] """\ ``signature'' of the widget's constructor """ extra_headers = [] """\ If not None, list of extra header file, in the form or "header.h" """ def __init__(self): BaseWidgetHandler.__init__(self) self.constructor = [] self.extra_headers = [] def get_ids_code(self, obj): """\ Handler for the code of the ids enum of toplevel objects. Returns a list of strings containing the code to generate. Usually the default implementation is ok (i.e. there are no extra lines to add) """ return [] # end of class WidgetHandler class CPPCodeWriter(BaseCodeWriter): """\ Code writer class for writing C++ code out of the designed GUI elements @ivar source_extension: Extension of the source file @type source_extension: String @ivar header_extension: Extension of the header file @type header_extension: String @ivar last_generated_id: Last generated Id number (wxNewId() is not used yet) @type last_generated_id: Integer @cvar tmpl_init_gettext: Template for inclusion of i18n headers and defining APP_CATALOG constant @type tmpl_init_gettext: None or string @see: L{BaseCodeWriter} """ default_extensions = ['cpp', 'cc', 'C', 'cxx', 'c++', 'h', 'hh', 'hpp', 'H', 'hxx', ] language = "C++" code_statements = { 'backgroundcolour': "%(objname)sSetBackgroundColour(%(value)s);\n", 'disabled': "%(objname)sEnable(0);\n", 'extraproperties': "%(objname)sSet%(propname)s(%(value)s);\n", 'focused': "%(objname)sSetFocus();\n", 'foregroundcolour': "%(objname)sSetForegroundColour(%(value)s);\n", 'hidden': "%(objname)sHide();\n", 'setfont': "%(objname)sSetFont(wxFont(%(size)s, %(family)s, " "%(style)s, %(weight)s, %(underlined)s, wxT(%(face)s)));\n", 'tooltip': "%(objname)sSetToolTip(%(tooltip)s);\n", 'wxcolour': "wxColour(%(value)s)", 'wxsystemcolour': "wxSystemSettings::GetColour(%(value)s)", } class_separator = '::' comment_sign = '//' global_property_writers = { 'font': BaseCodeWriter.FontPropertyHandler, 'events': BaseCodeWriter.EventsPropertyHandler, 'extraproperties': BaseCodeWriter.ExtraPropertiesPropertyHandler, } language_note = \ '// Example for compiling a single file project under Linux using g++:\n' \ '// g++ MyApp.cpp $(wx-config --libs) $(wx-config --cxxflags) -o MyApp\n' \ '//\n' \ '// Example for compiling a multi file project under Linux using g++:\n' \ '// g++ main.cpp $(wx-config --libs) $(wx-config --cxxflags) -o MyApp Dialog1.cpp Frame1.cpp\n' \ '//\n' last_generated_id = 1000 output_name = None """\ If not None, name (without extension) of the file to write into @type: String """ output_header = None """\ Temporary storage of header file for writing into @type: StringIO """ output_file = None """\ Temporary storage of source file for writing into @type: StringIO """ shebang = '// -*- C++ -*-\n//\n' tmpl_cfunc_end = '}\n\n' tmpl_name_do_layout = 'do_layout' tmpl_name_set_properties = 'set_properties' tmpl_sizeritem = '%s->Add(%s, %s, %s, %s);\n' tmpl_ctor_call_layout = '\n' \ '%(tab)sset_properties();\n' \ '%(tab)sdo_layout();\n' tmpl_func_do_layout = '\n' \ 'void %(klass)s::do_layout()\n{\n' \ '%(content)s' \ '}\n\n' tmpl_func_set_properties = '\n' \ 'void %(klass)s::set_properties()\n{\n' \ '%(content)s' \ '}\n\n' tmpl_appfile = """\ %(overwrite)s\ %(header_lines)s\ #include "%(top_win_class)s.h" """ tmpl_init_gettext = """\ #include "wx/intl.h" #ifndef APP_CATALOG #define APP_CATALOG "%(name)s" // replace with the appropriate catalog name #endif """ tmpl_detailed = """\ class %(klass)s: public wxApp { public: %(tab)sbool OnInit(); }; IMPLEMENT_APP(%(klass)s) bool %(klass)s::OnInit() { %(tab)swxInitAllImageHandlers(); %(tab)s%(top_win_class)s* %(top_win)s = new %(top_win_class)s(NULL, wxID_ANY, wxEmptyString); %(tab)sSetTopWindow(%(top_win)s); %(tab)s%(top_win)s->Show(); %(tab)sreturn true; }""" tmpl_gettext_detailed = """\ class %(klass)s: public wxApp { public: %(tab)sbool OnInit(); protected: %(tab)swxLocale m_locale; // locale we'll be using }; IMPLEMENT_APP(%(klass)s) bool %(klass)s::OnInit() { %(tab)sm_locale.Init(); #ifdef APP_LOCALE_DIR %(tab)sm_locale.AddCatalogLookupPathPrefix(wxT(APP_LOCALE_DIR)); #endif %(tab)sm_locale.AddCatalog(wxT(APP_CATALOG)); %(tab)swxInitAllImageHandlers(); %(tab)s%(top_win_class)s* %(top_win)s = new %(top_win_class)s(NULL, wxID_ANY, wxEmptyString); %(tab)sSetTopWindow(%(top_win)s); %(tab)s%(top_win)s->Show(); %(tab)sreturn true; }""" tmpl_simple = """\ class MyApp: public wxApp { public: %(tab)sbool OnInit(); }; IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { %(tab)swxInitAllImageHandlers(); %(tab)s%(top_win_class)s* %(top_win)s = new %(top_win_class)s(NULL, wxID_ANY, wxEmptyString); %(tab)sSetTopWindow(%(top_win)s); %(tab)s%(top_win)s->Show(); %(tab)sreturn true; }""" tmpl_gettext_simple = """\ class MyApp: public wxApp { public: %(tab)sbool OnInit(); protected: %(tab)swxLocale m_locale; // locale we'll be using }; IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { %(tab)sm_locale.Init(); #ifdef APP_LOCALE_DIR %(tab)sm_locale.AddCatalogLookupPathPrefix(wxT(APP_LOCALE_DIR)); #endif %(tab)sm_locale.AddCatalog(wxT(APP_CATALOG)); %(tab)swxInitAllImageHandlers(); %(tab)s%(top_win_class)s* %(top_win)s = new %(top_win_class)s(NULL, wxID_ANY, wxEmptyString); %(tab)sSetTopWindow(%(top_win)s); %(tab)s%(top_win)s->Show(); %(tab)sreturn true; }""" class ClassLines(BaseCodeWriter.ClassLines): """\ Stores the lines of C++ code for a custom class @ivar ids: Ids declared in the source (to use for Event handling): these are grouped together into a public enum in the custom class @ivar sub_objs: List of 2-tuples (type, name) of the sub-objects which are attributes of the toplevel object @ivar extra_code_h: Extra header code to output @ivar extra_code_cpp: Extra source code to output """ def __init__(self): BaseCodeWriter.ClassLines.__init__(self) self.ids = [] self.sub_objs = [] self.extra_code_h = [] self.extra_code_cpp = [] self.dependencies = [] # List not dictionary # end of class ClassLines def initialize(self, app_attrs): """\ Writer initialization function. @keyword path: Output path for the generated code (a file if multi_files is False, a dir otherwise) @keyword option: If True, generate a separate file for each custom class """ # initialise parent class BaseCodeWriter.initialize(self, app_attrs) self.app_filename = 'main.cpp' out_path = app_attrs['path'] self.last_generated_id = 1000 # Extensions based on Project options when set self.source_extension = app_attrs.get('source_extension', '.cpp') self.header_extension = app_attrs.get('header_extension', '.h') self.header_lines = [ '#include \n', '#include \n', ] # include i18n / gettext if self._use_gettext: self.header_lines.append( self.tmpl_init_gettext % {'name': self.app_name} ) # extra lines to generate (see the 'extracode' property of top-level # widgets) self._current_extra_code_h = [] self._current_extra_code_cpp = [] if self.multiple_files: self.previous_source = None if not os.path.isdir(out_path): raise IOError("'path' must be a directory when generating"\ " multiple output files") self.out_dir = out_path else: name = os.path.splitext(out_path)[0] self.output_name = name if not self._overwrite and self._file_exists(name + self.header_extension): # the file exists, we must keep all the lines not inside a wxGlade # block. NOTE: this may cause troubles if out_path is not a valid # source file, so be careful! self.previous_source = SourceFileContent(name, self) else: # if the file doesn't exist, create it and write the ``intro'' self.previous_source = None self.output_header = cStringIO.StringIO() self.output_file = cStringIO.StringIO() # isolation directives oh = os.path.basename(name + self.header_extension).upper().replace( '.', '_') self.output_header.write('#ifndef %s\n#define %s\n' % (oh, oh)) self.output_header.write('\n') for line in self.header_lines: self.output_header.write(line) self.output_header.write('\n') # now, write the tags to store dependencies and extra code self.output_header.write('<%swxGlade replace dependencies>' % self.nonce) self.output_header.write('\n<%swxGlade replace extracode>' % self.nonce) self.output_header.write('\n') self.output_file.write('#include "%s%s"\n\n' % \ (os.path.basename(name), self.header_extension)) self.output_file.write('<%swxGlade replace extracode>\n\n' % self.nonce) def finalize(self): if self.previous_source: # insert all the new custom classes inside the old file tag = '<%swxGlade insert new_classes>' % self.nonce if self.previous_source.new_classes: code = "".join([c[0] for c in self.previous_source.new_classes]) else: code = "" header_content = self.previous_source.header_content.replace(tag, code) extra_source = "".join([c[1] for c in self.previous_source.new_classes]) source_content = self.previous_source.source_content # extra code (see the 'extracode' property of top-level widgets) tag = '<%swxGlade replace extracode>' % self.nonce code = self._tagcontent( '::extracode', self._current_extra_code_h ) header_content = header_content.replace(tag, code) code = self._tagcontent( '::extracode', self._current_extra_code_cpp ) source_content = source_content.replace(tag, code) # -------------------------------------------------------------- # now remove all the remaining <123415wxGlade ...> tags from the # source: this may happen if we're not generating multiple files, # and one of the container class names is changed tags = re.findall( '(<%swxGlade replace ([a-zA-Z_]*\w*) (\w+)>)' % self.nonce, header_content ) for tag in tags: if tag[2] == 'dependencies': #print 'writing dependencies' deps = [] for code in self.classes.itervalues(): deps.extend(code.dependencies) lines = self._format_dependencies(deps) elif tag[2] == 'methods': lines = '%svoid set_properties();\n%svoid do_layout();\n' \ % (self.tabs(1), self.tabs(1)) else: lines = '// content of this block (%s) not found: ' \ 'did you rename this class?\n' % tag[2] header_content = header_content.replace(tag[0], lines) # remove all the remaining <123415wxGlade ...> tags in source file source_content = self._content_notfound( source_content, ) # ALB 2004-12-08 tags = re.findall('<%swxGlade event_handlers \w+>' % self.nonce, header_content) for tag in tags: header_content = header_content.replace(tag, "") tags = re.findall('<%swxGlade add \w+ event_handlers>' % self.nonce, source_content) for tag in tags: source_content = source_content.replace(tag, "") # write the new file contents to disk self.save_file( self.previous_source.name + self.header_extension, header_content, content_only=True ) if extra_source: extra_source = '\n\n' + extra_source self.save_file( self.previous_source.name + self.source_extension, source_content + extra_source, content_only=True ) elif not self.multiple_files: oh = os.path.basename(self.output_name).upper() + '_H' self.output_header.write('\n#endif // %s\n' % oh) # write the list of include files header_content = self.output_header.getvalue() source_content = self.output_file.getvalue() tags = re.findall('<%swxGlade replace dependencies>' % self.nonce, header_content) deps = [] for code in self.classes.itervalues(): deps.extend(code.dependencies) code = self._format_dependencies(deps) header_content = header_content.replace( '<%swxGlade replace dependencies>' % self.nonce, code) # extra code (see the 'extracode' property of top-level widgets) tag = '<%swxGlade replace extracode>' % self.nonce code = self._tagcontent('::extracode', self._current_extra_code_h) header_content = header_content.replace(tag, code) code = self._tagcontent('::extracode', self._current_extra_code_cpp) source_content = source_content.replace(tag, code) # -------------------------------------------------------------- self.save_file( self.output_name + self.header_extension, header_content, self._app_added ) self.save_file( self.output_name + self.source_extension, source_content, self._app_added ) def add_class(self, code_obj): if self.classes.has_key(code_obj.klass) and \ self.classes[code_obj.klass].done: return # the code has already been generated if self.multiple_files: # let's see if the file to generate exists, and in this case # create a SourceFileContent instance filename = os.path.join(self.out_dir, code_obj.klass.replace('::', '_') + self.header_extension) if self._overwrite or not self._file_exists(filename): prev_src = None else: prev_src = SourceFileContent( os.path.join(self.out_dir, code_obj.klass), self, ) else: # in this case, previous_source is the SourceFileContent instance # that keeps info about the single file to generate prev_src = self.previous_source try: builder = self.obj_builders[code_obj.base] mycn = getattr(builder, 'cn', self.cn) mycn_f = getattr(builder, 'cn_f', self.cn_f) except KeyError: print code_obj raise # this is an error, let the exception be raised if prev_src and prev_src.classes.has_key(code_obj.klass): is_new = False else: # this class wasn't in the previous version of the source (if any) is_new = True header_buffer = [] source_buffer = [] hwrite = header_buffer.append swrite = source_buffer.append if not self.classes.has_key(code_obj.klass): # if the class body was empty, create an empty ClassLines self.classes[code_obj.klass] = self.ClassLines() # collect all event handlers event_handlers = self.classes[code_obj.klass].event_handlers if hasattr(builder, 'get_events'): for id, event, handler in builder.get_events(code_obj): event_handlers.append((id, mycn(event), handler)) # try to see if there's some extra code to add to this class extra_code = getattr(builder, 'extracode', code_obj.properties.get('extracode', "")) if extra_code: extra_code = re.sub(r'\\n', '\n', extra_code) extra_code = re.split(re.compile(r'^###\s*$', re.M), extra_code, 1) self.classes[code_obj.klass].extra_code_h.append(extra_code[0]) if len(extra_code) > 1: self.classes[code_obj.klass].extra_code_cpp.append(extra_code[1]) if not is_new: self.warning( '%s has extra code, but you are not overwriting ' 'existing sources: please check that the resulting ' 'code is correct!' % code_obj.name ) if not self.multiple_files and extra_code: if self.classes[code_obj.klass].extra_code_h: self._current_extra_code_h.append("".join( self.classes[code_obj.klass].extra_code_h[::-1])) if self.classes[code_obj.klass].extra_code_cpp: self._current_extra_code_cpp.append("".join( self.classes[code_obj.klass].extra_code_cpp[::-1])) default_sign = [('wxWindow*', 'parent'), ('int', 'id')] sign = getattr(builder, 'constructor', default_sign) defaults = [] for t in sign: if len(t) == 3: defaults.append(t[2]) else: defaults.append(None) tmp_sign = [t[0] + ' ' + t[1] for t in sign] sign_decl2 = ', '.join(tmp_sign) for i in range(len(tmp_sign)): if defaults[i]: tmp_sign[i] += '=%s' % defaults[i] sign_decl1 = ', '.join(tmp_sign) sign_inst = ', '.join([t[1] for t in sign]) # custom base classes support custom_base = getattr(code_obj, 'custom_base', code_obj.properties.get('custom_base', None)) if custom_base and not custom_base.strip(): custom_base = None # generate constructor code if is_new: pass elif custom_base: # custom base classes set, but "overwrite existing sources" not # set. Issue a warning about this self.warning( '%s has custom base classes, but you are not overwriting ' 'existing sources: please check that the resulting code is ' 'correct!' % code_obj.name ) if is_new: # header file base = code_obj.base if custom_base: base = ", public ".join([b.strip() for b in custom_base.split(',')]) hwrite('\nclass %s: public %s {\n' % (code_obj.klass, base)) hwrite('public:\n') # the first thing to add it the enum of the various ids hwrite(self.tabs(1) + '// begin wxGlade: %s::ids\n' % code_obj.klass) ids = self.classes[code_obj.klass].ids # let's try to see if there are extra ids to add to the enum if hasattr(builder, 'get_ids_code'): ids.extend(builder.get_ids_code(code_obj)) if ids: hwrite(self.tabs(1) + 'enum {\n') ids = (',\n' + self.tabs(2)).join(ids) hwrite(self.tabs(2) + ids) hwrite('\n' + self.tabs(1) + '};\n') hwrite(self.tabs(1) + '// end wxGlade\n\n') # constructor prototype hwrite(self.tabs(1) + '%s(%s);\n' % (code_obj.klass, sign_decl1)) hwrite('\nprivate:\n') # set_properties and do_layout prototypes hwrite(self.tabs(1) + '// begin wxGlade: %s::methods\n' % code_obj.klass) hwrite(self.tabs(1) + 'void set_properties();\n') hwrite(self.tabs(1) + 'void do_layout();\n') hwrite(self.tabs(1) + '// end wxGlade\n') # declarations of the attributes hwrite('\n') hwrite('protected:\n') hwrite(self.tabs(1) + '// begin wxGlade: %s::attributes\n' % code_obj.klass) for o_type, o_name in self.classes[code_obj.klass].sub_objs: hwrite(self.tabs(1) + '%s* %s;\n' % (o_type, o_name)) hwrite(self.tabs(1) + '// end wxGlade\n') # ALB 2004-12-08 event handling if event_handlers: t = self.tabs(1) hwrite('\n' + t + 'DECLARE_EVENT_TABLE();\n') hwrite('\npublic:\n') already_there = {} for tpl in event_handlers: if len(tpl) == 4: win_id, event, handler, evt_type = tpl else: win_id, event, handler = tpl evt_type = 'wxCommandEvent' if handler not in already_there: # Sebastien JEFFROY & Steve MULLER contribution # Adding virtual attribute permits to derivate from the # class generated by wxGlade hwrite(t + 'virtual void %s(%s &event); ' '// wxGlade: \n' % (handler, evt_type)) already_there[handler] = 1 hwrite('}; // wxGlade: end class\n\n') elif prev_src: hwrite(self.tabs(1) + '// begin wxGlade: %s::ids\n' % code_obj.klass) ids = self.classes[code_obj.klass].ids # let's try to see if there are extra ids to add to the enum if hasattr(builder, 'get_ids_code'): ids.extend(builder.get_ids_code(code_obj)) if ids: hwrite(self.tabs(1) + 'enum {\n') ids = (',\n' + self.tabs(2)).join(ids) hwrite(self.tabs(2) + ids) hwrite('\n' + self.tabs(1) + '};\n') hwrite(self.tabs(1) + '// end wxGlade\n') tag = '<%swxGlade replace %s ids>' % (self.nonce, code_obj.klass) if prev_src.header_content.find(tag) < 0: # no ids tag found, issue a warning and do nothing self.warning( "wxGlade ids block not found for %s, ids declarations " "code NOT generated" % code_obj.name ) else: prev_src.header_content = prev_src.header_content.\ replace(tag, "".join(header_buffer)) header_buffer = [ self.tabs(1) + '// begin wxGlade: %s::methods\n' % \ code_obj.klass, self.tabs(1) + 'void set_properties();\n', self.tabs(1) + 'void do_layout();\n', self.tabs(1) + '// end wxGlade\n', ] tag = '<%swxGlade replace %s methods>' % (self.nonce, code_obj.klass) if prev_src.header_content.find(tag) < 0: # no methods tag found, issue a warning and do nothing self.warning( "wxGlade methods block not found for %s, methods " "declarations code NOT generated" % code_obj.name ) else: prev_src.header_content = prev_src.header_content.\ replace(tag, "".join(header_buffer)) header_buffer = [] hwrite = header_buffer.append hwrite(self.tabs(1) + '// begin wxGlade: %s::attributes\n' % code_obj.klass) for o_type, o_name in self.classes[code_obj.klass].sub_objs: hwrite(self.tabs(1) + '%s* %s;\n' % (o_type, o_name)) hwrite(self.tabs(1) + '// end wxGlade\n') tag = '<%swxGlade replace %s attributes>' % (self.nonce, code_obj.klass) if prev_src.header_content.find(tag) < 0: # no attributes tag found, issue a warning and do nothing self.warning( "wxGlade attributes block not found for %s, attributes " "declarations code NOT generated" % code_obj.name ) else: prev_src.header_content = prev_src.header_content.\ replace(tag, "".join(header_buffer)) header_buffer = [] hwrite = header_buffer.append # ALB 2004-12-08 event handling if event_handlers: already_there = prev_src.event_handlers.get(code_obj.klass, {}) t = self.tabs(1) for tpl in event_handlers: if len(tpl) == 4: win_id, event, handler, evt_type = tpl else: win_id, event, handler = tpl evt_type = 'wxCommandEvent' if handler not in already_there: # Sebastien JEFFROY & Steve MULLER contribution : # Adding virtual attribute permits to derivate from the # class generated by wxGlade hwrite(t + 'virtual void %s(%s &event); // wxGlade: ' '\n' % (handler, evt_type)) already_there[handler] = 1 if code_obj.klass not in prev_src.event_table_def: hwrite('\nprotected:\n') hwrite(self.tabs(1) + 'DECLARE_EVENT_TABLE()\n') tag = '<%swxGlade event_handlers %s>' % (self.nonce, code_obj.klass) if prev_src.header_content.find(tag) < 0: # no attributes tag found, issue a warning and do nothing self.warning( "wxGlade events block not found for %s, event table code " "NOT generated" % code_obj.name ) else: prev_src.header_content = prev_src.header_content.\ replace(tag, "".join(header_buffer)) # source file # set the window's style prop = code_obj.properties style = prop.get("style", None) if style: sign_inst = sign_inst.replace('style', '%s' % style) # constructor if is_new: base = "%s(%s)" % (code_obj.base, sign_inst) if custom_base: bases = [b.strip() for b in custom_base.split(',')] if bases: base = "%s(%s)" % (bases[0], sign_inst) rest = ", ".join([b + "()" for b in bases[1:]]) if rest: base += ", " + rest swrite('\n%s::%s(%s):\n%s%s\n{\n' % (code_obj.klass, code_obj.klass, sign_decl2, self.tabs(1), base)) swrite(self.tabs(1) + '// begin wxGlade: %s::%s\n' % (code_obj.klass, code_obj.klass)) tab = self.tabs(1) init_lines = self.classes[code_obj.klass].init parents_init = self.classes[code_obj.klass].parents_init parents_init.reverse() for l in parents_init: swrite(tab + l) for l in init_lines: swrite(tab + l) # now check if there are extra lines to add to the constructor if hasattr(builder, 'get_init_code'): for l in builder.get_init_code(code_obj): swrite(tab + l) swrite(self.tmpl_ctor_call_layout % { 'tab': tab, }) # end tag swrite('%s%s end wxGlade\n' % (tab, self.comment_sign)) # write class function end statement if self.tmpl_cfunc_end and is_new: swrite(self.tmpl_cfunc_end % { 'tab': tab, }) # replace code inside existing constructor block if prev_src and not is_new: # replace the lines inside the ctor wxGlade block # with the new ones tag = '<%swxGlade replace %s %s>' % (self.nonce, code_obj.klass, code_obj.klass) if prev_src.source_content.find(tag) < 0: # no constructor tag found, issue a warning and do nothing self.warning( "wxGlade %s::%s block not found, relative code NOT " "generated" % (code_obj.klass, code_obj.klass) ) else: prev_src.source_content = prev_src.source_content.\ replace(tag, "".join(source_buffer)) source_buffer = [] swrite = source_buffer.append # generate code for __set_properties() code_lines = self.generate_code_set_properties( builder, code_obj, is_new, tab ) source_buffer.extend(code_lines) # replace code inside existing __set_properties() function if prev_src and not is_new: # replace the lines inside the set_properties wxGlade block # with the new ones tag = '<%swxGlade replace %s set_properties>' % (self.nonce, code_obj.klass) if prev_src.source_content.find(tag) < 0: # no set_properties tag found, issue a warning and do nothing self.warning( "wxGlade %s::set_properties block not found, relative " "code NOT generated" % code_obj.klass ) else: prev_src.source_content = prev_src.source_content.\ replace(tag, "".join(source_buffer)) source_buffer = [] swrite = source_buffer.append # generate code for __do_layout() code_lines = self.generate_code_do_layout( builder, code_obj, is_new, tab ) source_buffer.extend(code_lines) # replace code inside existing do_layout() function if prev_src and not is_new: # replace the lines inside the do_layout wxGlade block # with the new ones tag = '<%swxGlade replace %s %s>' % (self.nonce, code_obj.klass, 'do_layout') if prev_src.source_content.find(tag) < 0: # no do_layout tag found, issue a warning and do nothing self.warning( "wxGlade do_layout block not found for %s, do_layout " "code NOT generated" % code_obj.name ) else: prev_src.source_content = prev_src.source_content.\ replace(tag, "".join(source_buffer)) source_buffer = [] swrite = source_buffer.append # generate code for event table code_lines = self.generate_code_event_table( code_obj, is_new, tab, prev_src, event_handlers, ) if prev_src and not is_new: tag = '<%swxGlade replace %s event_table>' % (self.nonce, code_obj.klass) if prev_src.source_content.find(tag) < 0: # no constructor tag found, issue a warning and do nothing self.warning( "wxGlade %s::event_table block not found, relative " "code NOT generated" % code_obj.klass ) else: prev_src.source_content = prev_src.source_content.replace( tag, "".join(code_lines), ) else: source_buffer.extend(code_lines) # generate code for event handler stubs code_lines = self.generate_code_event_handler( code_obj, is_new, tab, prev_src, event_handlers, ) # replace code inside existing event handlers if prev_src and not is_new: tag = '<%swxGlade add %s event handlers>' % \ (self.nonce, code_obj.klass) if prev_src.source_content.find(tag) < 0: # no constructor tag found, issue a warning and do nothing self.warning( "wxGlade %s event handlers marker not found, relative " "code NOT generated" % code_obj.klass ) else: prev_src.source_content = prev_src.source_content.replace( tag, "".join(code_lines), ) else: source_buffer.extend(code_lines) # the code has been generated self.classes[code_obj.klass].done = True if not self.multiple_files and prev_src: # if this is a new class, add its code to the new_classes list of the # SourceFileContent instance if is_new: prev_src.new_classes.append( ("".join(header_buffer), "".join(source_buffer)) ) return if self.multiple_files: if code_obj.base in self.obj_builders: self.classes[code_obj.klass].dependencies.extend( getattr(self.obj_builders[code_obj.base], 'extra_headers', [])) if prev_src: tag = '<%swxGlade insert new_classes>' % self.nonce prev_src.header_content = prev_src.header_content.replace(tag, "") # insert the module dependencies of this class extra_modules = self.classes[code_obj.klass].dependencies #print 'extra_modules:', extra_modules, code_obj.base # WARNING: there's a double space ' ' between 'replace' and # 'dependencies' in the tag below, because there is no class name # (see SourceFileContent, line ~147) tag = '<%swxGlade replace dependencies>' % self.nonce code = self._format_dependencies(extra_modules) prev_src.header_content = prev_src.header_content.\ replace(tag, code) # insert the extra code of this class extra_code_h = "".join(self.classes[code_obj.klass].extra_code_h[::-1]) extra_code_cpp = \ "".join(self.classes[code_obj.klass].extra_code_cpp[::-1]) # if there's extra code but we are not overwriting existing # sources, warn the user if extra_code_h or extra_code_cpp: self.warning( '%s (or one of its chilren) has extra code classes, ' 'but you are not overwriting existing sources: please ' 'check that the resulting code is correct!' % \ code_obj.name ) extra_code_h = self._tagcontent("::extracode", extra_code_h) extra_code_cpp = self._tagcontent("::extracode", extra_code_cpp) tag = '<%swxGlade replace extracode>' % self.nonce prev_src.header_content = prev_src.header_content.replace( tag, extra_code_h) prev_src.source_content = prev_src.source_content.replace( tag, extra_code_cpp) # store the new file contents to disk name = os.path.join(self.out_dir, code_obj.klass) self.save_file( name + self.header_extension, prev_src.header_content, content_only=True ) self.save_file( name + self.source_extension, prev_src.source_content, content_only=True ) return # create the new source file header_file = os.path.join(self.out_dir, code_obj.klass + self.header_extension) source_file = os.path.join(self.out_dir, code_obj.klass + self.source_extension) hout = cStringIO.StringIO() sout = cStringIO.StringIO() # header file hwrite = hout.write # isolation directives hn = os.path.basename(header_file).upper().replace('.', '_') hwrite('#ifndef %s\n#define %s\n' % (hn, hn)) hwrite('\n') # write the common lines for line in self.header_lines: hwrite(line) hwrite('\n') # write the module dependecies for this class #extra_headers = classes[code_obj.klass].dependencies extra_modules = self.classes[code_obj.klass].dependencies code = self._format_dependencies(extra_modules) hwrite(code) hwrite('\n') # insert the extra code of this class extra_code_h = "".join(self.classes[code_obj.klass].extra_code_h[::-1]) extra_code_h = self._tagcontent('::extracode', extra_code_h) hwrite(extra_code_h) hwrite('\n') # write the class body for line in header_buffer: hwrite(line) hwrite('\n#endif // %s\n' % hn) # source file swrite = sout.write # write the common lines #for line in self.header_lines: # swrite(line) swrite(self.header_lines[0]) swrite('#include "%s"\n\n' % os.path.basename(header_file)) # insert the extra code of this class extra_code_cpp = "".join(self.classes[code_obj.klass].extra_code_cpp[::-1]) extra_code_cpp = self._tagcontent('::extracode', extra_code_cpp) swrite(extra_code_cpp) swrite('\n') # write the class implementation for line in source_buffer: swrite(line) # store source to disk self.save_file(header_file, hout.getvalue()) self.save_file(source_file, sout.getvalue()) hout.close() sout.close() else: # not self.multiple_files # write the class body onto the single source file hwrite = self.output_header.write for line in header_buffer: hwrite(line) swrite = self.output_file.write for line in source_buffer: swrite(line) def add_object(self, top_obj, sub_obj): # get top level source code object and the widget builder instance klass, builder = self._add_object_init(top_obj, sub_obj) if not klass or not builder: return try: init, ids, props, layout = builder.get_code(sub_obj) except: print sub_obj raise # this shouldn't happen if sub_obj.in_windows: # the object is a wxWindow instance if sub_obj.is_container and not sub_obj.is_toplevel: init.reverse() klass.parents_init.extend(init) else: klass.init.extend(init) if hasattr(builder, 'get_events'): klass.event_handlers.extend(builder.get_events(sub_obj)) elif 'events' in sub_obj.properties: id_name, id = self.generate_code_id(sub_obj) for event, handler in sub_obj.properties['events'].iteritems(): klass.event_handlers.append((id, event, handler)) # try to see if there's some extra code to add to this class extra_code = getattr(builder, 'extracode', sub_obj.properties.get('extracode', "")) if extra_code: extra_code = re.sub(r'\\n', '\n', extra_code) extra_code = re.split(re.compile(r'^###\s*$', re.M), extra_code, 1) klass.extra_code_h.append(extra_code[0]) if len(extra_code) > 1: klass.extra_code_cpp.append(extra_code[1]) # if we are not overwriting existing source, warn the user # about the presence of extra code if not self.multiple_files and self.previous_source: self.warning( '%s has extra code, but you are not ' 'overwriting existing sources: please check ' 'that the resulting code is correct!' % \ sub_obj.name ) klass.ids.extend(ids) if sub_obj.klass != 'spacer': # attribute is a special property which control whether # sub_obj must be accessible as an attribute of top_obj, # or as a local variable in the do_layout method if self.test_attribute(sub_obj): klass.sub_objs.append((sub_obj.klass, sub_obj.name)) else: # the object is a sizer # ALB 2004-09-17: workaround (hack) for static box sizers... if sub_obj.base == 'wxStaticBoxSizer': klass.sub_objs.insert(0, ('wxStaticBox', '%s_staticbox' % sub_obj.name)) klass.parents_init.insert(1, init.pop(0)) if self.test_attribute(sub_obj): klass.sub_objs.append((sub_obj.klass, sub_obj.name)) klass.sizers_init.extend(init) klass.props.extend(props) klass.layout.extend(layout) if self.multiple_files and \ (sub_obj.is_toplevel and sub_obj.base != sub_obj.klass): #print top_obj.name, sub_obj.name klass.dependencies.append(sub_obj.klass) else: if sub_obj.base in self.obj_builders: headers = getattr(self.obj_builders[sub_obj.base], 'extra_headers', []) klass.dependencies.extend(headers) def generate_code_event_handler(self, code_obj, is_new, tab, prev_src, \ event_handlers): """\ Generate the event handler stubs @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param is_new: Indicates if previous source code exists @type is_new: Boolean @param tab: Indentation of function body @type tab: String @param prev_src: Previous source code @type prev_src: Instance of L{SourceFileContent} @param event_handlers: List of event handlers @rtype: List of strings @see: L{tmpl_func_event_stub} """ code_lines = [] swrite = code_lines.append if not event_handlers: return [] tmpl_handler = """ void %(klass)s::%(handler)s(%(evt_type)s &event) { %(tab)sevent.Skip(); %(tab)s// notify the user that he hasn't implemented the event handler yet %(tab)swxLogDebug(wxT("Event handler (%(klass)s::%(handler)s) not implemented yet")); } """ if prev_src: already_there = prev_src.event_handlers.get(code_obj.klass, {}) else: already_there = {} for tpl in event_handlers: if len(tpl) == 4: win_id, event, handler, evt_type = tpl else: win_id, event, handler = tpl evt_type = 'wxCommandEvent' if handler not in already_there: swrite(tmpl_handler % { 'evt_type': evt_type, 'handler': handler, 'klass': code_obj.klass, 'tab': tab, }) already_there[handler] = 1 if is_new or not prev_src: swrite('\n\n') swrite('// wxGlade: add %s event handlers\n' % code_obj.klass) if is_new or not prev_src: swrite('\n') return code_lines def generate_code_event_table(self, code_obj, is_new, tab, prev_src, event_handlers): """\ Generate code for event table declaration. @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param is_new: Indicates if previous source code exists @type is_new: Boolean @param tab: Indentation of function body @type tab: String @param prev_src: Previous source code @type prev_src: Instance of L{SourceFileContent} @param event_handlers: List of event handlers @rtype: List of strings """ code_lines = [] swrite = code_lines.append if not event_handlers: return [] if prev_src and code_obj.klass in prev_src.event_table_decl: has_event_table = True else: has_event_table = False if is_new or not has_event_table: swrite('\nBEGIN_EVENT_TABLE(%s, %s)\n' % \ (code_obj.klass, code_obj.base)) swrite(tab + '// begin wxGlade: %s::event_table\n' % code_obj.klass) for tpl in event_handlers: win_id, event, handler = tpl[:3] swrite(tab + '%s(%s, %s::%s)\n' % \ (event, win_id, code_obj.klass, handler)) swrite(tab + '// end wxGlade\n') if is_new or not has_event_table: swrite('END_EVENT_TABLE();\n\n') return code_lines def generate_code_id(self, obj, id=None): if id is None: id = obj.properties.get('id') if not id: return '', 'wxID_ANY' tokens = id.split('=', 1) if len(tokens) == 2: name, val = tokens else: return '', tokens[0] # we assume name is declared elsewhere if not name: return '', val name = name.strip() val = val.strip() if val == '?': val = 'wxID_HIGHEST + %d' % self.last_generated_id self.last_generated_id += 1 else: val = val return '%s = %s' % (name, val), name def generate_code_size(self, obj): objname = self._get_code_name(obj) if obj.is_toplevel: name2 = 'this' else: name2 = obj.name size = obj.properties.get('size', '').strip() use_dialog_units = (size[-1] == 'd') if not obj.parent: method = 'SetSize' else: method = 'SetMinSize' if use_dialog_units: return '%s%s(wxDLG_UNIT(%s, wxSize(%s)));\n' % \ (objname, method, name2, size[:-1]) else: return '%s%s(wxSize(%s));\n' % (objname, method, size) def get_events_with_type(self, obj, evt_type): """\ Returns the list of event handlers defined for `obj', setting the type of the argument of the handlers (i.e. the event parameter) to `evt_type' """ ret = [] if 'events' not in obj.properties: return ret id_name, id = self.generate_code_id(obj) for event, handler in obj.properties['events'].iteritems(): ret.append((id, event, handler, evt_type)) return ret def quote_str(self, s, translate=True, escape_chars=True): if not s: return 'wxEmptyString' s = s.replace('"', r'\"') if escape_chars: s = self._quote_str_pattern.sub(self._do_replace, s) else: s = s.replace('\\', r'\\') # just quote the backslashes if self._use_gettext and translate: return '_("%s")' % s else: return 'wxT("%s")' % s def _get_code_name(self, obj): if obj.is_toplevel: return '' else: return '%s->' % obj.name def _unique(self, sequence): """\ Strips all duplicates from sequence. Works only if items of sequence are hashable """ tmp = {} for item in sequence: tmp[item] = 1 return tmp.keys() def _format_dependencies(self, dependencies): """\ Format the dependecies output @param dependencies: List if header files @type dependencies: List of strings @return: Changed content @rtype: String @see: L{_tagcontent()} """ dep_list = [] for dependency in self._unique(dependencies): if dependency and ('"' != dependency[0] != '<'): dep_list.append('#include "%s.h"\n' % dependency) else: dep_list.append('#include %s\n' % dependency) code = self._tagcontent( '::dependencies', dep_list, ) return code # end of class CPPCodeWriter writer = CPPCodeWriter() """\ The code writer is an instance of L{CPPCodeWriter}. """ language = writer.language """\ Language generated by this code generator """ wxglade-0.6.8.orig/codegen/xrc_codegen.py0000644000175000017500000004016012150154266020556 0ustar georgeskgeorgesk"""\ XRC code generator Generates the xml code for the app in XRC format. Calls the appropriate ``writers'' of the various objects. These functions return an instance of XrcObject @copyright: 2002-2007 Alberto Griggio @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import cStringIO import common from xml.sax.saxutils import escape, quoteattr from codegen import BaseCodeWriter, \ EventsPropertyHandler, \ ExtraPropertiesPropertyHandler from ordereddict import OrderedDict class FontPropertyHandler: def __init__(self): self.props = {'size': '', 'family': '', 'style': '', 'weight': '', 'underlined': '', 'face': ''} self.current = None def start_elem(self, name, attrs): self.current = name def end_elem(self, name, code_obj): if name == 'font': code_obj.properties['font'] = self.props return True # to remove this handler def char_data(self, data): self.props[self.current] = str(data.strip()) # end of class FontHandler class XRCCodeWriter(BaseCodeWriter): """\ Code writer class for writing XRC XML code out of the designed GUI elements """ default_extensions = ['xrc'] language = "XRC" xrc_objects = None """\ dictionary of active L{XrcObject} instances: during the code generation it stores all the non-sizer objects that have children (i.e. frames, dialogs, panels, notebooks, etc.), while at the end of the code generation, before L{finalize} is called, it contains only the true toplevel objects (frames and dialogs), and is used to write their XML code (see L{finalize}). The other objects are deleted when L{add_object} is called with their corresponding code_object as argument (see L{add_object}) """ global_property_writers = { 'font': FontPropertyHandler, 'events': EventsPropertyHandler, 'extraproperties': ExtraPropertiesPropertyHandler, } """\ Dictionary whose items are custom handlers for widget properties """ property_writers = {} """\ Dictionary of dictionaries of property handlers specific for a widget the keys are the class names of the widgets Example: property_writers['wxRadioBox'] = {'choices', choices_handler} """ obj_builders = {} """\ Dictionary of ``writers'' for the various objects """ tmpl_encoding = '\n' tmpl_generated_by = '' # Nested classes class XrcObject(object): """\ Class to produce the XRC code for a given widget. This is a base class which does nothing """ def __init__(self): self.properties = {} self.children = [] # sub-objects def write_child_prologue(self, child, out_file, ntabs): pass def write_child_epilogue(self, child, out_file, ntabs): pass def write_property(self, name, val, outfile, ntabs): pass def write(self, out_file, ntabs): pass def warning(self, msg): """\ Show a warning message @param msg: Warning message @type msg: String @see: L{common.MessageLogger.warn()} """ common.message.warn(msg) # end of class XrcObject class SizerItemXrcObject(XrcObject): """\ XrcObject to handle sizer items """ def __init__(self, obj, option, flag, border): XRCCodeWriter.XrcObject.__init__(self) self.obj = obj # the XrcObject representing the widget self.option = option self.flag = flag self.border = border def write(self, out_file, ntabs): write = out_file.write write(self.tabs(ntabs) + '\n') if self.option != '0': write(self.tabs(ntabs + 1) + '\n' % \ self.option) if self.flag and self.flag != '0': write(self.tabs(ntabs + 1) + '%s\n' % self.flag) if self.border != '0': write(self.tabs(ntabs + 1) + '%s\n' % \ self.border) # write the widget self.obj.write(out_file, ntabs + 1) write(self.tabs(ntabs) + '\n') # end of class SizerItemXrcObject class SpacerXrcObject(XrcObject): """\ XrcObject to handle widgets """ def __init__(self, size_str, option, flag, border): XRCCodeWriter.XrcObject.__init__(self) self.size_str = size_str self.option = option self.flag = flag self.border = border def write(self, out_file, ntabs): write = out_file.write write(self.tabs(ntabs) + '\n') write(self.tabs(ntabs + 1) + \ '%s\n' % self.size_str.strip()) if self.option != '0': write(self.tabs(ntabs + 1) + '\n' % \ self.option) if self.flag and self.flag != '0': write(self.tabs(ntabs + 1) + '%s\n' % self.flag) if self.border != '0': write(self.tabs(ntabs + 1) + '%s\n' % \ self.border) write(self.tabs(ntabs) + '\n') # end of class SpacerXrcObject class DefaultXrcObject(XrcObject): """\ Standard XrcObject for every widget, used if no specific XrcObject is available """ def __init__(self, code_obj): XRCCodeWriter.XrcObject.__init__(self) self.properties = code_obj.properties self.code_obj = code_obj self.name = code_obj.name self.klass = code_obj.base # custom classes aren't allowed in XRC self.subclass = code_obj.klass def write_property(self, name, val, outfile, ntabs): if val: name = escape(name) outfile.write(self.tabs(ntabs) + '<%s>%s\n' % \ (name, escape(val), name)) def write(self, out_file, ntabs): write = out_file.write if self.code_obj.in_sizers: write(self.tabs(ntabs) + \ '\n' % quoteattr(self.klass)) else: if self.subclass and self.subclass != self.klass: write(self.tabs(ntabs) + '\n' % \ (quoteattr(self.klass), quoteattr(self.name), quoteattr(self.subclass))) else: write(self.tabs(ntabs) + '\n' % \ (quoteattr(self.klass), quoteattr(self.name))) tab_str = self.tabs(ntabs + 1) # write the properties if self.properties.has_key('foreground'): if self.properties['foreground'].startswith('#'): # XRC does not support colors from system settings self.properties['fg'] = self.properties['foreground'] del self.properties['foreground'] if self.properties.has_key('background'): if self.properties['background'].startswith('#'): # XRC does not support colors from system settings self.properties['bg'] = self.properties['background'] del self.properties['background'] if self.properties.has_key('font'): font = self.properties['font'] del self.properties['font'] else: font = None style = str(self.properties.get('style', '')) if style and style == '0': del self.properties['style'] if 'id' in self.properties: del self.properties['id'] # id has no meaning for XRC # ALB 2004-12-05 if 'events' in self.properties: #del self.properties['events'] # no event handling in XRC for handler, event in self.properties['events'].iteritems(): write(tab_str + '%s\n' % \ (quoteattr(handler), escape(event))) del self.properties['events'] # 'disabled' property is actually 'enabled' for XRC if 'disabled' in self.properties: try: val = int(self.properties['disabled']) except: val = False if val: self.properties['enabled'] = '0' del self.properties['disabled'] # ALB 2007-08-31 extracode property if 'extracode' in self.properties: write(self.properties['extracode'].replace('\\n', '\n')) del self.properties['extracode'] # custom base classes are ignored for XRC... if 'custom_base' in self.properties: del self.properties['custom_base'] if 'extraproperties' in self.properties: prop = self.properties['extraproperties'] del self.properties['extraproperties'] self.properties.update(prop) for name, val in self.properties.iteritems(): self.write_property(str(name), val, out_file, ntabs + 1) # write the font, if present if font: write(tab_str + '\n') tab_str = self.tabs(ntabs + 2) for key, val in font.iteritems(): if val: write(tab_str + '<%s>%s\n' % \ (escape(key), escape(val), escape(key))) write(self.tabs(ntabs + 1) + '\n') # write the children for c in self.children: self.write_child_prologue(c, out_file, ntabs + 1) c.write(out_file, ntabs + 1) self.write_child_epilogue(c, out_file, ntabs + 1) write(self.tabs(ntabs) + '\n') # end of class DefaultXrcObject class NotImplementedXrcObject(XrcObject): """\ XrcObject used when no code for the widget can be generated (for example, because XRC does not currently handle such widget) """ def __init__(self, code_obj): XRCCodeWriter.XrcObject.__init__(self) self.code_obj = code_obj def write(self, outfile, ntabs): m = 'code generator for %s objects not available' % \ self.code_obj.base self.warning('%s' % m) outfile.write(self.tabs(ntabs) + '\n' % m) # end of class NotImplementedXrcObject def __init__(self): BaseCodeWriter.__init__(self) # Inject to all classed derivated from WrcObject XRCCodeWriter.XrcObject.tabs = self.tabs def initialize(self, app_attrs): # initialise parent class BaseCodeWriter.initialize(self, app_attrs) out_path = app_attrs['path'] if self.multiple_files: # for now we handle only single-file code generation raise IOError("XRC code cannot be split into multiple files") self.output_file_name = out_path self.out_file = cStringIO.StringIO() # open(out_path, 'w') self.out_file.write('\n\n') self.curr_tab = 1 self.xrc_objects = OrderedDict() def finalize(self): # write the code for every toplevel object for obj in self.xrc_objects.itervalues(): obj.write(self.out_file, 1) self.out_file.write('\n') # store the contents to file self.save_file( self.output_file_name, self.out_file.getvalue() ) def add_app(self, app_attrs, top_win_class): """\ In the case of XRC output, there's no wxApp code to generate """ pass def add_object(self, unused, sub_obj): """\ Adds the object sub_obj to the XRC tree. The first argument is unused. """ # what we need in XRC is not top_obj, but sub_obj's true parent top_obj = sub_obj.parent builder = self.obj_builders.get( sub_obj.base, XRCCodeWriter.DefaultXrcObject ) try: # check whether we already created the xrc_obj xrc_obj = sub_obj.xrc except AttributeError: xrc_obj = builder(sub_obj) # builder functions must return a # subclass of XrcObject sub_obj.xrc = xrc_obj else: # if we found it, remove it from the self.xrc_objects dictionary # (if it was there, i.e. the object is not a sizer), because this # isn't a true toplevel object if sub_obj in self.xrc_objects: del self.xrc_objects[sub_obj] # let's see if sub_obj's parent already has an XrcObject: if so, it is # temporairly stored in the self.xrc_objects dict... if top_obj in self.xrc_objects: top_xrc = self.xrc_objects[top_obj] else: # ...otherwise, create it and store it in the self.xrc_objects dict top_xrc = self.obj_builders.get( top_obj.base, XRCCodeWriter.DefaultXrcObject)(top_obj) top_obj.xrc = top_xrc self.xrc_objects[top_obj] = top_xrc top_obj.xrc.children.append(xrc_obj) def add_sizeritem(self, unused, sizer, obj, option, flag, border): """\ Adds a sizeritem to the XRC tree. The first argument is unused. """ # what we need in XRC is not toplevel, but sub_obj's true parent toplevel = obj.parent top_xrc = toplevel.xrc obj_xrc = obj.xrc try: sizer_xrc = sizer.xrc except AttributeError: # if the sizer has not an XrcObject yet, create it now sizer_xrc = self.obj_builders.get( sizer.base, XRCCodeWriter.DefaultXrcObject)(sizer) sizer.xrc = sizer_xrc # we now have to move the children from 'toplevel' to 'sizer' index = top_xrc.children.index(obj_xrc) if obj.klass == 'spacer': w = obj.properties.get('width', '0') h = obj.properties.get('height', '0') obj_xrc = XRCCodeWriter.SpacerXrcObject( '%s, %s' % (w, h), str(option), str(flag), str(border) ) sizer.xrc.children.append(obj_xrc) else: sizeritem_xrc = XRCCodeWriter.SizerItemXrcObject( obj_xrc, str(option), str(flag), str(border) ) sizer.xrc.children.append(sizeritem_xrc) del top_xrc.children[index] def add_class(self, code_obj): """\ Add class behaves very differently for XRC output than for other lanaguages (i.e. pyhton): since custom classes are not supported in XRC, this has effect only for true toplevel widgets, i.e. frames and dialogs. For other kinds of widgets, this is equivalent to add_object """ if not self.xrc_objects.has_key(code_obj): builder = self.obj_builders.get( code_obj.base, XRCCodeWriter.DefaultXrcObject ) xrc_obj = builder(code_obj) code_obj.xrc = xrc_obj # add the xrc_obj to the dict of the toplevel ones self.xrc_objects[code_obj] = xrc_obj def _format_comment(self, msg): return '' % escape(msg.rstrip()) # end of class XRCCodeWriter writer = XRCCodeWriter() """\ The code writer is an instance of L{XRCCodeWriter}. """ language = writer.language """\ Language generated by this code generator """ wxglade-0.6.8.orig/codegen/py_codegen.py0000644000175000017500000006346112167341277020433 0ustar georgeskgeorgesk"""\ Python code generator How the code is generated: every time the end of an object is reached during the parsing of the xml tree, either the function 'add_object' or the function 'add_class' is called: the latter when the object is a toplevel one, the former when it is not. In the last case, 'add_object' calls the appropriate ``writer'' function for the specific object, found in the 'obj_builders' dict. Such function accepts one argument, the CodeObject representing the object for which the code has to be written, and returns 3 lists of strings, representing the lines to add to the '__init__', '__set_properties' and '__do_layout' methods of the parent object. @copyright: John Dubery @copyright: 2002-2007 Alberto Griggio @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import os import os.path import random import re import types from codegen import BaseCodeWriter, \ BaseSourceFileContent, \ BaseWidgetHandler class SourceFileContent(BaseSourceFileContent): rec_block_start = re.compile( r'^(?P\s*)' # leading spaces r'#\s*' # comment sign r'begin\s+wxGlade:\s*' # "begin wxGlade:" statement and tailing spaces r'(?P[a-zA-Z_]+\w*)??' # class or function name (non-greedy) r'[.]?' # separator between class and function / block (non-gready) r'(?P\w+)' # function / block name r'\s*$' # tailing spaces ) rec_block_end = re.compile( r'^\s*' # leading spaces r'#\s*' # comment sign r'end\s+wxGlade' # "end exGlade" statement r'\s*$' # tailing spaces ) # Less precise regex, but matches definitions with base classes having # module qualified names. rec_class_decl = re.compile( r'^\s*' # leading spaces r'class\s+([a-zA-Z_]\w*)\s*(\([\s\w.,]*\))?:' # "class " statement r'\s*$' # tailing spaces ) rec_event_handler = re.compile( r'^\s+' # leading spaces (mandatory) r'def\s+(?P[A-Za-z_]+\w*)' # event handler name r'\s*' # optional spaces r'\(.*\):' # function parameters r'\s*' # optional spaces r'#\s*wxGlade:\s*(?P\w+)\.' # wxGlade event handler statement with class name r'\s*$' # tailing spaces ) def __init__(self, name, code_writer): # initialise new variables first self.use_new_namespace = code_writer.use_new_namespace # call inherited constructor BaseSourceFileContent.__init__(self, name, code_writer) def build_untouched_content(self): BaseSourceFileContent.build_untouched_content(self) inside_block = False inside_triple_quote = False triple_quote_str = None tmp_in = self._load_file(self.name) out_lines = [] for line in tmp_in: quote_index = -1 if not inside_triple_quote: triple_dquote_index = line.find('"""') triple_squote_index = line.find("'''") if triple_squote_index == -1: quote_index = triple_dquote_index tmp_quote_str = '"""' elif triple_dquote_index == -1: quote_index = triple_squote_index tmp_quote_str = "'''" else: quote_index, tmp_quote_str = min( (triple_squote_index, "'''"), (triple_dquote_index, '"""')) if not inside_triple_quote and quote_index != -1: inside_triple_quote = True triple_quote_str = tmp_quote_str if inside_triple_quote: end_index = line.rfind(triple_quote_str) if quote_index < end_index and end_index != -1: inside_triple_quote = False result = self.rec_class_decl.match(line) if not inside_triple_quote and not inside_block and result: ## print ">> class %r" % result.group(1) if not self.class_name: # this is the first class declared in the file: insert the # new ones before this out_lines.append('<%swxGlade insert new_classes>' % self.nonce) self.new_classes_inserted = True self.class_name = result.group(1) self.class_name = self.format_classname(self.class_name) self.classes[self.class_name] = 1 # add the found class to the list # of classes of this module out_lines.append(line) elif not inside_block: result = self.rec_block_start.match(line) if not inside_triple_quote and result: ## print ">> block %r %r %r" % ( ## result.group('spaces'), result.group('classname'), result.group('block')) # replace the lines inside a wxGlade block with a tag that # will be used later by add_class spaces = result.group('spaces') which_class = result.group('classname') which_block = result.group('block') if not which_class: which_class = self.class_name else: which_class = self.format_classname(which_class) self.spaces[which_class] = spaces inside_block = True if not self.class_name: out_lines.append('<%swxGlade replace %s>' % \ (self.nonce, which_block)) else: out_lines.append('<%swxGlade replace %s %s>' % \ (self.nonce, which_class, which_block)) else: result = self.rec_event_handler.match(line) if not inside_triple_quote and result: which_handler = result.group('handler') which_class = self.format_classname(result.group('class')) self.event_handlers.setdefault( which_class, {})[which_handler] = 1 if self.class_name and self.is_end_of_class(line): # add extra event handlers here... out_lines.append('<%swxGlade event_handlers %s>' % (self.nonce, self.class_name)) out_lines.append(line) if self.is_import_line(line): # add a tag to allow extra modules out_lines.append('<%swxGlade extra_modules>\n' % self.nonce) else: # ignore all the lines inside a wxGlade block if self.rec_block_end.match(line): ## print 'end block' inside_block = False if not self.new_classes_inserted: # if we are here, the previous ``version'' of the file did not # contain any class, so we must add the new_classes tag at the # end of the file out_lines.append('<%swxGlade insert new_classes>' % self.nonce) # set the ``persistent'' content of the file self.content = "".join(out_lines) def is_import_line(self, line): if self.use_new_namespace: return line.startswith('import wx') else: return line.startswith('from wxPython.wx import *') def format_classname(self, class_name): """\ Format class name read from existing source file. If we're in a subpackage, we should include the package name in the class name. @param class_name: Class name @type class_name: String @rtype: String """ if not self.multiple_files: return class_name name = self.name if self.out_dir: name = name.replace(self.out_dir, '') pkg = os.path.dirname(name).replace(os.sep, '.') if pkg.startswith('.'): pkg = pkg[1:] if pkg: return pkg + '.' + class_name else: return class_name # end of class SourceFileContent class WidgetHandler(BaseWidgetHandler): pass # end of class WidgetHandler class PythonCodeWriter(BaseCodeWriter): """\ Code writer class for writing Python code out of the designed GUI elements @ivar use_new_namespace: If True use the new name space (import wx) @type use_new_namespace: Boolean @see: L{BaseCodeWriter} """ default_extensions = ['py', 'pyw'] language = "python" code_statements = { 'backgroundcolour': "%(objname)s.SetBackgroundColour(%(value)s)\n", 'contentnotfound': "pass", 'disabled': "%(objname)s.Enable(False)\n", 'extraproperties': "%(objname)s.Set%(propname)s(%(value)s)\n", 'focused': "%(objname)s.SetFocus()\n", 'foregroundcolour': "%(objname)s.SetForegroundColour(%(value)s)\n", 'hidden': "%(objname)s.Hide()\n", 'setfont': "%(objname)s.SetFont(%(cnfont)s(%(size)s, %(family)s, " "%(style)s, %(weight)s, %(underlined)s, %(face)s))\n", 'tooltip': "%(objname)s.SetToolTipString(%(tooltip)s)\n", 'wxcolour': "wxColour(%(value)s)", 'wxsystemcolour': "wxSystemSettings_GetColour(%(value)s)", } class_separator = '.' comment_sign = '#' global_property_writers = { 'font': BaseCodeWriter.FontPropertyHandler, 'events': BaseCodeWriter.EventsPropertyHandler, 'extraproperties': BaseCodeWriter.ExtraPropertiesPropertyHandler, } indent_level_func_body = 2 name_ctor = '__init__' shebang = '#!/usr/bin/env python\n' SourceFileContent = SourceFileContent tmpl_name_do_layout = '__do_layout' tmpl_name_set_properties = '__set_properties' tmpl_encoding = "# -*- coding: %s -*-\n#\n" tmpl_class_end = '\n' \ '%(comment)s end of class %(klass)s\n' tmpl_ctor_call_layout = '\n' \ '%(tab)sself.__set_properties()\n' \ '%(tab)sself.__do_layout()\n' tmpl_func_empty = '%(tab)spass\n' tmpl_sizeritem = '%s.Add(%s, %s, %s, %s)\n' tmpl_style = '%(tab)skwds["style"] = %(style)s\n' tmpl_appfile = """\ %(overwrite)s\ %(header_lines)s\ %(import_gettext)s\ from %(top_win_class)s import %(top_win_class)s\n\n""" tmpl_detailed = """\ class %(klass)s(%(cn_wxApp)s): %(tab)sdef OnInit(self): %(tab)s%(tab)s%(cn_wxInitAll)s() %(tab)s%(tab)s%(top_win)s = %(top_win_class)s(None, %(cn_wxIDANY)s, "") %(tab)s%(tab)sself.SetTopWindow(%(top_win)s) %(tab)s%(tab)s%(top_win)s.Show() %(tab)s%(tab)sreturn 1 # end of class %(klass)s if __name__ == "__main__": %(tab)s%(name)s = %(klass)s(0) %(tab)s%(name)s.MainLoop()""" tmpl_gettext_detailed = """\ class %(klass)s(%(cn_wxApp)s): %(tab)sdef OnInit(self): %(tab)s%(tab)s%(cn_wxInitAll)s() %(tab)s%(tab)s%(top_win)s = %(top_win_class)s(None, %(cn_wxIDANY)s, "") %(tab)s%(tab)sself.SetTopWindow(%(top_win)s) %(tab)s%(tab)s%(top_win)s.Show() %(tab)s%(tab)sreturn 1 # end of class %(klass)s if __name__ == "__main__": %(tab)sgettext.install("%(name)s") # replace with the appropriate catalog name %(tab)s%(name)s = %(klass)s(0) %(tab)s%(name)s.MainLoop()""" tmpl_simple = """\ if __name__ == "__main__": %(tab)s%(name)s = %(cn_wxPySimpleApp)s(0) %(tab)s%(cn_wxInitAll)s() %(tab)s%(top_win)s = %(top_win_class)s(None, %(cn_wxIDANY)s, "") %(tab)s%(name)s.SetTopWindow(%(top_win)s) %(tab)s%(top_win)s.Show() %(tab)s%(name)s.MainLoop()""" tmpl_gettext_simple = """\ if __name__ == "__main__": %(tab)sgettext.install("%(name)s") # replace with the appropriate catalog name %(tab)s%(name)s = %(cn_wxPySimpleApp)s(0) %(tab)s%(cn_wxInitAll)s() %(tab)s%(top_win)s = %(top_win_class)s(None, %(cn_wxIDANY)s, "") %(tab)s%(name)s.SetTopWindow(%(top_win)s) %(tab)s%(top_win)s.Show() %(tab)s%(name)s.MainLoop()""" def __init__(self): BaseCodeWriter.__init__(self) def _init_vars(self): self.use_new_namespace = True BaseCodeWriter._init_vars(self) def cn(self, name): """\ Return the name properly formatted for the selected name space. @see: L{use_new_namespace} @see: L{cn_f()} """ if self.use_new_namespace: # don't process already formatted items again if name.startswith('wx.'): return name if name.startswith('wx'): return 'wx.' + name[2:] elif name.startswith('EVT_'): return 'wx.' + name return name def cn_f(self, flags): """\ Return the flags properly formatted. @see: L{cn()} """ # don't process integer values if type(flags) == types.IntType: return flags # format single flags first flags = [self.cn(f) for f in flags.split('|')] return ' | '.join(flags) def cn_class(self, klass): """\ Return the short class name """ return self.without_package(klass) def initialize(self, app_attrs): """\ Writer initialization function. @keyword path: Output path for the generated code (a file if multi_files is False, a dir otherwise) @keyword option: If True, generate a separate file for each custom class """ # initialise parent class BaseCodeWriter.initialize(self, app_attrs) out_path = app_attrs['path'] try: self.use_new_namespace = int(app_attrs['use_new_namespace']) except (KeyError, ValueError): self.use_new_namespace = True if self.use_new_namespace: self.header_lines.append('import wx\n') else: self.header_lines.append('from wxPython.wx import *\n') self._initialize_stage2(out_path) def add_app(self, app_attrs, top_win_class): # add language specific mappings self.lang_mapping = { 'cn_wxApp': self.cn('wxApp'), 'cn_wxIDANY': self.cn('wxID_ANY'), 'cn_wxInitAll': self.cn('wxInitAllImageHandlers'), 'cn_wxPySimpleApp': self.cn('wxPySimpleApp'), 'import_gettext': '', } # Add gettext import statements if self._use_gettext: if self.multiple_files: self.lang_mapping['import_gettext'] = 'import gettext\n' else: self.dependencies['import gettext\n'] = 1 BaseCodeWriter.add_app(self, app_attrs, top_win_class) def generate_code_ctor(self, code_obj, is_new, tab): code_lines = [] write = code_lines.append builder = self.obj_builders[code_obj.base] mycn = getattr(builder, 'cn', self.cn) mycn_f = getattr(builder, 'cn_f', self.cn_f) # custom base classes support custom_base = getattr(code_obj, 'custom_base', code_obj.properties.get('custom_base', None)) if code_obj.preview or (custom_base and not custom_base.strip()): custom_base = None # generate constructor code if is_new: base = mycn(code_obj.base) if custom_base: base = ", ".join([b.strip() for b in custom_base.split(',')]) if code_obj.preview and code_obj.klass == base: klass = code_obj.klass + \ ('_%d' % random.randrange(10 ** 8, 10 ** 9)) else: klass = code_obj.klass write('\nclass %s(%s):\n' % (self.without_package(klass), base)) write(self.tabs(1) + 'def __init__(self, *args, **kwds):\n') elif custom_base: # custom base classes set, but "overwrite existing sources" not # set. Issue a warning about this self.warning( '%s has custom base classes, but you are not overwriting ' 'existing sources: please check that the resulting code is ' 'correct!' % code_obj.name ) # __init__ begin tag write(self.tmpl_block_begin % { 'class_separator': self.class_separator, 'comment_sign': self.comment_sign, 'function': self.name_ctor, 'klass': self.cn_class(code_obj.klass), 'tab': tab, }) prop = code_obj.properties style = prop.get("style", None) if style: stmt_style = self._format_style(style, code_obj) write(stmt_style % { 'style': mycn_f(style), 'tab': tab, }) # initialise custom base class if custom_base: bases = [b.strip() for b in custom_base.split(',')] for i, b in enumerate(bases): if not i: write(tab + '%s.__init__(self, *args, **kwds)\n' % b) else: write(tab + '%s.__init__(self)\n' % b) else: write(tab + '%s.__init__(self, *args, **kwds)\n' % \ mycn(code_obj.base)) # classes[code_obj.klass].deps now contains a mapping of child to # parent for all children we processed... object_order = [] for obj in self.classes[code_obj.klass].child_order: # Don't add it again if already present if obj in object_order: continue object_order.append(obj) # Insert parent and ancestor objects before the current object current_object = obj for child, parent in self.classes[code_obj.klass].deps[:]: if child is current_object: if parent not in object_order: idx = object_order.index(current_object) object_order.insert(idx, parent) current_object = parent # We processed the dependency: remove it self.classes[code_obj.klass].deps.remove((child, parent)) # Write out the initialisation in the order we just generated for obj in object_order: if obj in self.classes[code_obj.klass].init_lines: for l in self.classes[code_obj.klass].init_lines[obj]: write(tab + l) return code_lines def generate_code_do_layout(self, builder, code_obj, is_new, tab): # Python has two indentation levels # 1st) for function declaration # 2nd) for function body self.tmpl_func_do_layout = '\n' + \ self.tabs(1) + 'def __do_layout(self):\n' + \ '%(content)s' + \ '' return BaseCodeWriter.generate_code_do_layout( self, builder, code_obj, is_new, tab, ) def generate_code_event_bind(self, code_obj, tab, event_handlers): code_lines = [] write = code_lines.append if event_handlers: write('\n') if not self.use_new_namespace: for win_id, event, handler in event_handlers: if win_id.startswith('#'): win_id = '%s.GetId()' % win_id[1:] write('%(tab)s%(event)s(self, %(win_id)s, self.%(handler)s)\n' % { 'tab': tab, 'event': event, 'win_id': win_id, 'handler': handler, }) else: for win_id, event, handler in event_handlers: if win_id.startswith('#'): win_id = win_id[1:] else: win_id = 'id=%s' % win_id write('%(tab)sself.Bind(%(event)s, self.%(handler)s, %(win_id)s)\n' % { 'tab': tab, 'event': event, 'handler': handler, 'win_id': win_id, }) return code_lines def generate_code_event_handler(self, code_obj, is_new, tab, prev_src, \ event_handlers): # Python has two indentation levels # 1st) for function declaration # 2nd) for function body self.tmpl_func_event_stub = self.tabs(1) + """\ def %(handler)s(self, event): # wxGlade: %(klass)s. %(tab)sprint "Event handler '%(handler)s' not implemented!" %(tab)sevent.Skip() """ return BaseCodeWriter.generate_code_event_handler( self, code_obj, is_new, tab, prev_src, event_handlers, ) def generate_code_id(self, obj, id=None): if obj and obj.preview: return '', '-1' # never generate ids for preview code if id is None: id = obj.properties.get('id') if not id: return '', self.cn('wxID_ANY') tokens = id.split('=', 1) if len(tokens) == 2: name, val = tokens else: return '', self.cn(tokens[0]) # we assume name is declared elsewhere if not name: return '', self.cn(val) name = name.strip() val = val.strip() if val == '?': val = self.cn('wxNewId()') else: val = self.cn(val) # check to see if we have to make the var global or not... if '.' in name: return ('%s = %s\n' % (name, val), name) return ('global %s; %s = %s\n' % (name, name, val), name) def generate_code_set_properties(self, builder, code_obj, is_new, tab): # Python has two indentation levels # 1st) for function declaration # 2nd) for function body self.tmpl_func_set_properties = '\n' + \ self.tabs(1) + 'def __set_properties(self):\n' + \ '%(content)s' + \ '' return BaseCodeWriter.generate_code_set_properties( self, builder, code_obj, is_new, tab, ) def generate_code_size(self, obj): objname = self._get_code_name(obj) size = obj.properties.get('size', '').strip() use_dialog_units = (size[-1] == 'd') if not obj.parent: method = 'SetSize' else: method = 'SetMinSize' if use_dialog_units: return '%s.%s(%s(%s, (%s)))\n' % ( objname, method, self.cn('wxDLG_SZE'), objname, size[:-1] ) else: return '%s.%s((%s))\n' % (objname, method, size) def quote_str(self, s, translate=True, escape_chars=True): if not s: return '""' s = s.replace('"', r'\"') if escape_chars: s = self._quote_str_pattern.sub(self._do_replace, s) else: s = s.replace('\\', r'\\') # just quote the backslashes try: dummy = unicode(s, 'ascii') if self._use_gettext and translate: return '_("%s")' % s else: return '"%s"' % s except UnicodeDecodeError: # convert byte string to unicode, escape unicode characters and # convert string back to ascii s = s.decode('utf8') s = s.encode('unicode-escape') if self._use_gettext and translate: return '_(u"%s")' % s else: return 'u"%s"' % s def without_package(self, class_name): """\ Removes the package name from the given class name """ return class_name.split('.')[-1] def _add_object_format_name(self, name): return '#self.%s' % name def _format_classattr(self, obj): res = BaseCodeWriter._format_classattr(self, obj) if not res: return res elif obj.name.startswith('self.'): return obj.name # spacer.name is ", " already, but wxPython expect # a tuple instead of two single values elif obj.klass == 'spacer': return '(%s)' % obj.name elif self.test_attribute(obj): return 'self.%s' % obj.name return obj.name def _format_import(self, klass): stmt = 'from %s import %s\n' % (klass, self.without_package(klass)) return stmt def _get_class_filename(self, klass): filename = os.path.join( self.out_dir, klass.replace('.', os.sep) + '.py' ) return filename def _get_code_name(self, obj): if obj.is_toplevel: return 'self' else: return self._format_classattr(obj) # end of class PythonCodeWriter writer = PythonCodeWriter() """\ The code writer is an instance of L{PythonCodeWriter}. """ language = writer.language """\ Language generated by this code generator """ wxglade-0.6.8.orig/codegen/__init__.py0000644000175000017500000025617512167336636020067 0ustar georgeskgeorgesk"""\ Common code used by all code generators @copyright: 2011-2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import cStringIO import os import os.path import random import re import sys import time import types import common import config import misc from xml_parse import XmlParsingError class DummyPropertyHandler(object): """Empty handler for properties that do not need code""" def __init__(self): self.handlers = {} self.event_name = None self.curr_handler = [] def start_elem(self, name, attrs): pass def end_elem(self, name, code_obj): return True def char_data(self, data): pass # end of class DummyPropertyHandler class EventsPropertyHandler(DummyPropertyHandler): """\ Handler for event properties """ def start_elem(self, name, attrs): if name == 'handler': self.event_name = attrs['event'] def end_elem(self, name, code_obj): if name == 'handler': if self.event_name and self.curr_handler: self.handlers[self.event_name] = ''.join(self.curr_handler) self.event_name = None self.curr_handler = [] elif name == 'events': code_obj.properties['events'] = self.handlers return True def char_data(self, data): data = data.strip() if data: self.curr_handler.append(data) # end of class EventsPropertyHandler class ExtraPropertiesPropertyHandler(DummyPropertyHandler): def __init__(self): DummyPropertyHandler.__init__(self) self.props = {} self.curr_prop = [] self.prop_name = None def start_elem(self, name, attrs): if name == 'property': name = attrs['name'] if name and name[0].islower(): name = name[0].upper() + name[1:] self.prop_name = name def end_elem(self, name, code_obj): if name == 'property': if self.prop_name and self.curr_prop: self.props[self.prop_name] = ''.join(self.curr_prop) self.prop_name = None self.curr_prop = [] elif name == 'extraproperties': code_obj.properties['extraproperties'] = self.props return True # to remove this handler def char_data(self, data): data = data.strip() if data: self.curr_prop.append(data) # end of class ExtraPropertiesPropertyHandler # custom property handlers class FontPropertyHandler(object): """Handler for font properties""" font_families = {'default': 'wxDEFAULT', 'decorative': 'wxDECORATIVE', 'roman': 'wxROMAN', 'swiss': 'wxSWISS', 'script': 'wxSCRIPT', 'modern': 'wxMODERN', 'teletype': 'wxTELETYPE'} font_styles = {'normal': 'wxNORMAL', 'slant': 'wxSLANT', 'italic': 'wxITALIC'} font_weights = {'normal': 'wxNORMAL', 'light': 'wxLIGHT', 'bold': 'wxBOLD'} def __init__(self): self.dicts = {'family': self.font_families, 'style': self.font_styles, 'weight': self.font_weights} self.attrs = {'size': '0', 'style': '0', 'weight': '0', 'family': '0', 'underlined': '0', 'face': ''} self.current = None self.curr_data = [] def start_elem(self, name, attrs): self.curr_data = [] if name != 'font' and name in self.attrs: self.current = name else: self.current = None def end_elem(self, name, code_obj): if name == 'font': code_obj.properties['font'] = self.attrs return True elif self.current is not None: decode = self.dicts.get(self.current) if decode: val = decode.get("".join(self.curr_data), '0') else: val = "".join(self.curr_data) self.attrs[self.current] = val def char_data(self, data): self.curr_data.append(data) # end of class FontPropertyHandler class BaseSourceFileContent(object): """\ Keeps info about an existing file that has to be updated, to replace only the lines inside a wxGlade block, an to keep the rest of the file as it was @ivar classes: Classes declared in the file @ivar class_name: Name of the current processed class @ivar content: Content of the source file, if it existed before this session of code generation @ivar event_handlers: List of event handlers for each class @ivar name: Name of the file @type name: String @ivar new_classes: New classes to add to the file (they are inserted BEFORE the old ones) @ivar new_classes_inserted: Flag if the placeholder for new classes has been inserted in source file already @type new_classes_inserted: Boolean @ivar code_writer: Reference to the parent code writer object @type code_writer: Instance of L{BaseCodeWriter} or of a derived class @ivar spaces: Indentation level for each class @type spaces: String @cvar rec_block_start: Regexp to match the begin of a wxglade block @cvar rec_block_end: Regexp to match the end of a wxGlade block @cvar rec_class_decl: Regexp to match class declarations @cvar rec_event_handler: Regexp to match event handlers """ def __init__(self, name, code_writer): self.name = name self.code_writer = code_writer self.content = None self.new_classes = [] self.classes = {} self.spaces = {} self.event_handlers = {} self.nonce = code_writer.nonce self.out_dir = code_writer.out_dir self.multiple_files = code_writer.multiple_files if not self.content: self.build_untouched_content() self.class_name = None self.new_classes_inserted = False def build_untouched_content(self): """\ Builds a string with the contents of the file that must be left as is, and replaces the wxGlade blocks with tags that in turn will be replaced by the new wxGlade blocks """ self.class_name = None self.new_classes_inserted = False def format_classname(self, class_name): """\ Format class name read from existing source file @param class_name: Class name @type class_name: String @rtype: String @note: You may overwrite this function in the derivated class """ return class_name def is_end_of_class(self, line): """\ True if the line is the marker for class end. @rtype: Boolean """ return line.strip().startswith('# end of class ') def is_import_line(self, line): """\ True if the line imports wx @note: You may overwrite this function in the derivated class @rtype: Boolean """ return False def _load_file(self, filename): """\ Load a file and return the content @note: Separated for debugging purposes @rtype: List of strings """ fh = open(filename) lines = fh.readlines() fh.close() return lines # end of class BaseSourceFileContent class BaseWidgetHandler(object): """\ Interface the various code generators for the widgets must implement """ import_modules = [] """\ List of modules to import (eg. ['use Wx::Grid;\n']) """ def __init__(self): """\ Initialise instance variables """ self.import_modules = [] def get_code(self, obj): """\ Handler for normal widgets (non-toplevel): returns 3 lists of strings, init, properties and layout, that contain the code for the corresponding methods of the class to generate """ return [], [], [] def get_properties_code(self, obj): """\ Handler for the code of the set_properties method of toplevel objects. Returns a list of strings containing the code to generate """ return [] def get_init_code(self, obj): """\ Handler for the code of the constructor of toplevel objects. Returns a list of strings containing the code to generate. Usually the default implementation is ok (i.e. there are no extra lines to add). The generated lines are appended at the end of the constructor """ return [] def get_layout_code(self, obj): """\ Handler for the code of the do_layout method of toplevel objects. Returns a list of strings containing the code to generate. Usually the default implementation is ok (i.e. there are no extra lines to add) """ return [] # end of class BaseWidgetHandler class BaseCodeWriter(object): """\ Dictionary of objects used to generate the code in a given language. A code writer object B{must} implement those interface and set those variables: - L{initialize()} - L{finalize()} - L{language} - L{add_app()} - L{add_class()} - L{add_object()} - L{add_property_handler()} - L{add_sizeritem()} - L{add_widget_handler()} - L{generate_code_background()} - L{generate_code_font()} - L{generate_code_foreground()} - L{generate_code_id()} - L{generate_code_size()} - L{_get_code_name()} - L{code_statements} A code writer object B{could} implement those interfaces and set those variables: - L{setup()} - L{quote_str()} - L{quote_path()} - L{cn()} - L{cn_f()} @ivar app_encoding: Encoding of the application; will be initialised with L{config.default_encoding} @type app_encoding: String @ivar app_filename: File name to store the application start code within multi file projects @type app_filename: String @ivar app_mapping: Default mapping of template variables for substituting in templates (see L{lang_mapping}, L{add_app()}) @type app_mapping: Dictionary @ivar lang_mapping: Language specific mapping of template variables for substituting in templates (see L{app_mapping}, L{add_app()}) @type lang_mapping: Dictionary @ivar app_name: Application name @type app_name: String @ivar blacklisted_widgets: Don't add those widgets to sizers because they are not supported for the requested wx version or there is no code generator available. @type blacklisted_widgets: Dictionary @ivar classes: Dictionary that maps the lines of code of a class to the name of such class: the lines are divided in 3 categories: '__init__', '__set_properties' and '__do_layout' @type classes: Dictionary @ivar curr_tab: Current indentation level @type curr_tab: Integer @ivar for_version: wx version we are generating code for (e.g. C{(2, 6)}) @type for_version: Tuple of major and minor version number @ivar header_lines: Lines common to all the generated files (import of wxCL, ...) @type header_lines: List of strings @ivar indent_amount: An indentation level is L{indent_symbol} * L{indent_amount}; will be initialised with L{config.default_indent_amount} @type indent_amount: Integer @ivar indent_symbol: Character to use for identation; will be initialised with L{config.default_indent_symbol} @type indent_symbol: String @ivar multiple_files: If True, generate a file for each custom class @type multiple_files: Boolean @ivar nonce: Random number used to be sure that the replaced tags in the sources are the right ones (see L{BaseSourceFileContent}, L{add_class} and L{create_nonce}) @type nonce: String @ivar obj_builders: "writers" for the various objects @type obj_builders: Dictionary @ivar obj_properties: "property writer" functions, used to set the properties of a toplevel object @type obj_properties: Dictionary @ivar out_dir: If not None, it is the directory inside which the output files are saved @type out_dir: None or string @ivar output_file: Output string buffer for the code @type output_file: None or StringIO @ivar output_file_name: Name of the output file @type output_file_name: String @ivar previous_source: If not None, it is an instance of L{BaseSourceFileContent} that keeps info about the previous version of the source to generate @type previous_source: None or a derivated class of L{BaseSourceFileContent} @ivar _app_added: True after wxApp instance has been generated @type _app_added: Boolean @ivar _current_extra_code: Set of lines for extra code to add to the current file @type _current_extra_code: List of strings @ivar _current_extra_modules: Set of lines of extra modules to add to the current file @type _current_extra_modules: List of strings @ivar _overwrite: If True, overwrite any previous version of the source file instead of updating only the wxGlade blocks; will be initialised with L{config.default_overwrite} @type _overwrite: Boolean @ivar _property_writers: Dictionary of dictionaries of property handlers specific for a widget the keys are the class names of the widgets (E.g. _property_writers['wxRadioBox'] = {'choices', choices_handler}) @type _property_writers: Dictionary @ivar _use_gettext: If True, enable gettext support; will be initialised with L{config.default_use_gettext} @type _use_gettext: Boolean @ivar _widget_extra_modules: Map of widget class names to a list of extra modules needed for the widget (e.g. C{'wxGrid': 'from wxLisp.grid import *\\n'}). @type _widget_extra_modules: Dictionary """ code_statements = {} """\ Language specific code templates for for small statements @type: Dictionary of strings @see: L{_generic_code()} @see: L{generate_code_extraproperties()} """ classattr_always = [] """\ List of classes to store always as class attributes @type: List of strings @see: L{test_attribute()} """ class_separator = '' """\ Separator between class and attribute or between different name space elements. E.g "." for Python or "->" for Perl. @type: String """ comment_sign = '' """\ Character(s) to start a comment (e.g. C{#} for Python and Perl or C{;;;} for lisp). @type: String """ default_extensions = [] """\ Default extensions for generated files: a list of file extensions @type: List of strings """ global_property_writers = {} """\ Custom handlers for widget properties @type: Dictionary """ indent_level_func_body = 1 """\ Indentation level for bodies of class functions. @type: Integer """ language = None """\ Language generated by this code generator @type: String """ language_note = "" """\ Language specific notice written into every file header @note: Please add a newline sequence to the end of the language note. @type: String @see: L{save_file()} """ name_ctor = '' """\ Name of the constructor. E.g. "__init__" in Python or "new" in Perl. @type: String """ shebang = None """\ Shebang line, the first line of the generated main files. @note: Please add a newline sequence to the end of the shebang. @type: String @see: L{save_file()} """ SourceFileContent = None """\ Just a reference to the language specific instance of SourceFileContent @type: L{BaseSourceFileContent} or a derived class """ tmpl_encoding = None """\ Template of the encoding notices The file encoding will be added to the output in L{save_file()}. @type: String """ tmpl_block_begin = \ '%(tab)s%(comment_sign)s begin wxGlade: ' \ '%(klass)s%(class_separator)s%(function)s\n' tmpl_cfunc_end = '' """\ Statement to add at the end of a class function. e.g. 'return $self;' for Perl. @type: String """ tmpl_class_end = '' """\ Statement to add at the end of a class. @type: String """ tmpl_ctor_call_layout = '' """\ Code add to the contructor to call '__do_layout()' and '__set_properties()'. @type: String """ tmpl_name_do_layout = '' """\ Name of the function __do_layout() in wxGlade begin tag. This name differs between the various code generators. @type: String @see: L{generate_code_do_layout()} """ tmpl_name_set_properties = '' """\ Name of the function __set_properties() in wxGlade begin tag. This name differs between the various code generators. @type: String @see: L{generate_code_set_properties()} """ tmpl_func_empty = '' """\ Statement for an empty function e.g. "pass" for Python or "return;" for perl. @note: This statement differs between the various code generators. @type: String """ tmpl_func_do_layout = '' """\ Statement for the __do_layout() function. @note: This statement differs between the various code generators. @type: String @see: L{generate_code_do_layout()} """ tmpl_func_event_stub = '' """\ Statement for a event handler stub. @note: This statement differs between the various code generators. @type: String @see: L{generate_code_event_handler()} """ tmpl_func_set_properties = '' """\ Statement for the __set_properties() function. @note: This statement differs between the various code generators. @type: String @see: L{generate_code_set_properties()} """ tmpl_generated_by = \ "%(comment_sign)s %(generated_by)s\n%(comment_sign)s\n" """\ Template of the "generated by ..." message @type: String @see: L{create_generated_by()} @see: L{save_file()} """ tmpl_overwrite = \ "%(comment_sign)s This is an automatically generated file.\n" \ "%(comment_sign)s Manual changes will be overwritten without " \ "warning!\n\n" """\ Template of the overwrite message in all standalone app files. @type: String @see: L{add_app()} """ tmpl_sizeritem = '' """\ Template for adding a widget to a sizer. @type: String @see: L{add_sizeritem()} """ tmpl_style = '' """\ Template for setting style in constructor @type: String @see: L{_format_style()} """ tmpl_appfile = None """\ Template of the file header for standalone files with application start code. A standalone file will be created if a separate file for each class is selected. @type: None or string @see: L{add_app} """ tmpl_detailed = None """\ Template for detailed application start code without gettext support @type: None or string @see: L{add_app} """ tmpl_gettext_detailed = None """\ Template for detailed application start code with gettext support @type: None or string @see: L{add_app} """ tmpl_simple = None """\ Template for simplified application start code without gettext support @type: None or string @see: L{add_app} """ tmpl_gettext_simple = None """\ Template for simplified application start code with gettext support @type: None or string @see: L{add_app} """ _quote_str_pattern = re.compile(r'\\[natbv"]?') _show_warnings = True """\ Enable or disable printing of warning messages @type: Boolean @see: L{self.warning()} """ class ClassLines(object): """\ Stores the lines of source code for a custom class @ivar dependencies: Names of the modules this class depends on @ivar event_handlers: Lines to bind events @ivar extra_code: Extra code to output before this class @ivar done: If True, the code for this class has already been generated @ivar init: Lines of code to insert in the __init__ method (for children widgets) @ivar layout: Lines to insert in the __do_layout method @ivar parents_init: Lines of code to insert in the __init__ for container widgets (panels, splitters, ...) @ivar props: Lines to insert in the __set_properties method @ivar sizers_init : Lines related to sizer objects declarations """ def __init__(self): self.child_order = [] self.dependencies = {} self.deps = [] self.done = False self.event_handlers = [] self.extra_code = [] self.init = [] self.init_lines = {} self.layout = [] self.parents_init = [] self.props = [] self.sizers_init = [] # end of class ClassLines DummyPropertyHandler = DummyPropertyHandler EventsPropertyHandler = EventsPropertyHandler ExtraPropertiesPropertyHandler = ExtraPropertiesPropertyHandler FontPropertyHandler = FontPropertyHandler def __init__(self): """\ Initialise only instance variables using there defaults. """ self.obj_builders = {} self.obj_properties = {} self._property_writers = {} self._init_vars() def _init_vars(self): """\ Set instance variables (back) to default values during class instantiation (L{__init__}) and before loading new data (L{initialize()}). """ self.app_encoding = config.default_encoding self.app_filename = None self.app_mapping = {} self.app_name = None self.classes = {} self.curr_tab = 0 self.dependencies = {} self.for_version = (2, 6) self.header_lines = [] self.indent_symbol = config.default_indent_symbol self.indent_amount = config.default_indent_amount self.blacklisted_widgets = {} self.lang_mapping = {} self.multiple_files = False # this is to be more sure to replace the right tags self.nonce = self.create_nonce() self.out_dir = None self.output_file_name = None self.output_file = None self.previous_source = None self._app_added = False self._current_extra_code = [] self._current_extra_modules = {} self._overwrite = config.default_overwrite self._use_gettext = config.default_use_gettext self._widget_extra_modules = {} def initialize(self, app_attrs): """\ Code generator initialization function. @see: L{_initialize_stage2()} """ # set (most of) instance variables back to default values self._init_vars() self.multiple_files = app_attrs['option'] # application name self.app_name = app_attrs.get('name') if not self.app_name: self.app_name = 'app' self.app_filename = '%s.%s' % ( self.app_name, self.default_extensions[0], ) # file encoding try: self.app_encoding = app_attrs['encoding'].upper() # wx doesn't like latin-1 if self.app_encoding == 'latin-1': self.app_encoding = 'ISO-8859-1' except (KeyError, ValueError): # set back to default self.app_encoding = config.default_encoding # Inentation level based on the project options try: self.indent_symbol = app_attrs['indent_symbol'] if self.indent_symbol == 'tab': self.indent_symbol = '\t' elif self.indent_symbol == 'space': self.indent_symbol = ' ' else: self.indent_symbol = config.default_indent_symbol except (KeyError, ValueError): self.indent_symbol = config.default_indent_symbol try: self.indent_amount = int(app_attrs['indent_amount']) except (KeyError, ValueError): self.indent_amount = config.default_indent_amount try: self._use_gettext = int(app_attrs['use_gettext']) except (KeyError, ValueError): self._use_gettext = config.default_use_gettext try: self._overwrite = int(app_attrs['overwrite']) except (KeyError, ValueError): self._overwrite = config.default_overwrite try: self.for_version = tuple([int(t) for t in app_attrs['for_version'].split('.')[:2]]) except (KeyError, ValueError): if common.app_tree is not None: self.for_version = common.app_tree.app.for_version def _initialize_stage2(self, out_path): """\ Second stage for code generator initialization. @param out_path: Output path @type out_path: String @see: L{initialize()} """ if self.multiple_files: self.previous_source = None if not os.path.isdir(out_path): raise IOError("'path' must be a directory when generating"\ " multiple output files") self.out_dir = out_path else: if not self._overwrite and self._file_exists(out_path): # the file exists, we must keep all the lines not inside a # wxGlade block. NOTE: this may cause troubles if out_path is # not a valid source file, so be careful! self.previous_source = self.SourceFileContent(out_path, self) else: # if the file doesn't exist, create it and write the ``intro'' self.previous_source = None self.output_file = cStringIO.StringIO() self.output_file_name = out_path for line in self.header_lines: self.output_file.write(line) self.output_file.write('<%swxGlade extra_modules>\n' % self.nonce) self.output_file.write('\n') self.output_file.write('<%swxGlade replace dependencies>\n' % self.nonce) self.output_file.write('<%swxGlade replace extracode>\n' % self.nonce) def finalize(self): """\ Code generator finalization function. """ if self.previous_source: # insert all the new custom classes inside the old file tag = '<%swxGlade insert new_classes>' % self.nonce if self.previous_source.new_classes: code = "".join(self.previous_source.new_classes) else: code = "" self.previous_source.content = self.previous_source.content.replace(tag, code) tag = '<%swxGlade extra_modules>\n' % self.nonce code = "".join(self._current_extra_modules.keys()) self.previous_source.content = self.previous_source.content.replace(tag, code) # module dependecies of all classes tag = '<%swxGlade replace dependencies>' % self.nonce dep_list = self.dependencies.keys() dep_list.sort() code = self._tagcontent('dependencies', dep_list) self.previous_source.content = \ self.previous_source.content.replace(tag, code) # extra code (see the 'extracode' property of top-level widgets) tag = '<%swxGlade replace extracode>' % self.nonce code = self._tagcontent( 'extracode', self._current_extra_code ) self.previous_source.content = \ self.previous_source.content.replace(tag, code) # now remove all the remaining <123415wxGlade ...> tags from the # source: this may happen if we're not generating multiple files, # and one of the container class names is changed self.previous_source.content = self._content_notfound( self.previous_source.content ) tags = re.findall( '<%swxGlade event_handlers \w+>' % self.nonce, self.previous_source.content ) for tag in tags: self.previous_source.content = self.previous_source.content.replace(tag, "") # write the new file contents to disk self.save_file( self.previous_source.name, self.previous_source.content, content_only=True ) elif not self.multiple_files: em = "".join(self._current_extra_modules.keys()) content = self.output_file.getvalue().replace( '<%swxGlade extra_modules>\n' % self.nonce, em) # module dependecies of all classes tag = '<%swxGlade replace dependencies>' % self.nonce dep_list = self.dependencies.keys() dep_list.sort() code = self._tagcontent('dependencies', dep_list) content = content.replace(tag, code) # extra code (see the 'extracode' property of top-level widgets) tag = '<%swxGlade replace extracode>' % self.nonce code = self._tagcontent('extracode', self._current_extra_code) content = content.replace(tag, code) self.output_file.close() self.save_file(self.output_file_name, content, self._app_added) del self.output_file def add_app(self, app_attrs, top_win_class): """\ Generates the code for a wxApp instance. If the file to write into already exists, this function does nothing. If gettext support is requested and there is not template with gettext support but there is a template without gettext support, template without gettext support will be used. This fallback mechanism works bidirectional. L{app_mapping} will be reset to default values and updated with L{lang_mapping}. @see: L{tmpl_appfile} @see: L{tmpl_detailed} @see: L{tmpl_gettext_detailed} @see: L{tmpl_simple} @see: L{tmpl_gettext_simple} @see: L{app_mapping} @see: L{lang_mapping} """ self._app_added = True if not self.multiple_files: prev_src = self.previous_source else: # overwrite apps file always prev_src = None # do nothing if the file exists if prev_src: return klass = app_attrs.get('class') top_win = app_attrs.get('top_window') # do nothing if there is no top window if not top_win: return # check for templates for detailed startup code if klass and self._use_gettext: if self.tmpl_gettext_detailed: tmpl = self.tmpl_gettext_detailed elif self.tmpl_detailed: tmpl = self.tmpl_detailed else: self.warning( _("Skip generating detailed startup code " "because no suitable template found.") ) return elif klass and not self._use_gettext: if self.tmpl_detailed: tmpl = self.tmpl_detailed elif self.tmpl_gettext_detailed: tmpl = self.tmpl_gettext_detailed else: self.warning( _("Skip generating detailed startup code " "because no suitable template found.") ) return # check for templates for simple startup code elif not klass and self._use_gettext: if self.tmpl_gettext_simple: tmpl = self.tmpl_gettext_simple elif self.tmpl_simple: tmpl = self.tmpl_simple else: self.warning( _("Skip generating simple startup code " "because no suitable template found.") ) return elif not klass and not self._use_gettext: if self.tmpl_simple: tmpl = self.tmpl_simple elif self.tmpl_gettext_simple: tmpl = self.tmpl_gettext_simple else: self.warning( _("Skip generating simple startup code " "because no suitable template found.") ) return else: self.warning( _('No application code template for klass "%(klass)s" ' 'and gettext "%(gettext)s" found!' % { 'klass': klass, 'gettext': self._use_gettext, } )) return # map to substitude template variables self.app_mapping = { 'comment_sign': self.comment_sign, 'header_lines': ''.join(self.header_lines), 'klass': klass, 'name': self.app_name, 'overwrite': self.tmpl_overwrite % {'comment_sign': self.comment_sign}, 'tab': self.tabs(1), 'top_win_class': top_win_class, 'top_win': top_win, } # extend default mapping with language specific mapping if self.lang_mapping: self.app_mapping.update(self.lang_mapping) code = tmpl % (self.app_mapping) if self.multiple_files: filename = os.path.join(self.out_dir, self.app_filename) code = "%s%s" % ( self.tmpl_appfile % (self.app_mapping), code, ) # write the wxApp code self.save_file(filename, code, True) else: self.output_file.write(code) def add_class(self, code_obj): """\ Add class behaves very differently for XRC output than for other lanaguages (i.e. pyhton): since custom classes are not supported in XRC, this has effect only for true toplevel widgets, i.e. frames and dialogs. For other kinds of widgets, this is equivalent to add_object """ if self.classes.has_key(code_obj.klass) and \ self.classes[code_obj.klass].done: return # the code has already been generated if self.multiple_files: # let's see if the file to generate exists, and in this case # create a SourceFileContent instance filename = self._get_class_filename(code_obj.klass) if self._overwrite or not self._file_exists(filename): prev_src = None else: prev_src = self.SourceFileContent(filename, self) self._current_extra_modules = {} else: # in this case, previous_source is the SourceFileContent instance # that keeps info about the single file to generate prev_src = self.previous_source try: builder = self.obj_builders[code_obj.base] mycn = getattr(builder, 'cn', self.cn) mycn_f = getattr(builder, 'cn_f', self.cn_f) except KeyError: print code_obj raise # this is an error, let the exception be raised if prev_src and prev_src.classes.has_key(code_obj.klass): is_new = False indentation = prev_src.spaces[code_obj.klass] else: # this class wasn't in the previous version of the source (if any) is_new = True indentation = self.tabs(self.indent_level_func_body) mods = getattr(builder, 'extra_modules', []) if mods: for m in mods: self._current_extra_modules[m] = 1 buffer = [] write = buffer.append if not self.classes.has_key(code_obj.klass): # if the class body was empty, create an empty ClassLines self.classes[code_obj.klass] = self.ClassLines() # collect all event handlers event_handlers = self.classes[code_obj.klass].event_handlers if hasattr(builder, 'get_events'): for id, event, handler in builder.get_events(code_obj): event_handlers.append((id, mycn(event), handler)) # try to see if there's some extra code to add to this class if not code_obj.preview: extra_code = getattr(builder, 'extracode', code_obj.properties.get('extracode', "")) if extra_code: extra_code = re.sub(r'\\n', '\n', extra_code) self.classes[code_obj.klass].extra_code.append(extra_code) if not is_new: self.warning( '%s has extra code, but you are not overwriting ' 'existing sources: please check that the resulting ' 'code is correct!' % code_obj.name ) # Don't add extra_code to self._current_extra_code here, that is # handled later. Otherwise we'll emit duplicate extra code for # frames. tab = indentation # generate code for first constructor stage code_lines = self.generate_code_ctor(code_obj, is_new, tab) buffer.extend(code_lines) # now check if there are extra lines to add to the constructor if hasattr(builder, 'get_init_code'): for l in builder.get_init_code(code_obj): write(tab + l) write(self.tmpl_ctor_call_layout % { 'tab': tab, }) # generate code for binding events code_lines = self.generate_code_event_bind( code_obj, tab, event_handlers, ) buffer.extend(code_lines) # end tag write('%s%s end wxGlade\n' % (tab, self.comment_sign)) # write class function end statement if self.tmpl_cfunc_end and is_new: write(self.tmpl_cfunc_end % { 'tab': tab, }) # end of ctor generation # replace code inside existing constructor block if prev_src and not is_new: # replace the lines inside the ctor wxGlade block # with the new ones tag = '<%swxGlade replace %s %s>' % (self.nonce, code_obj.klass, self.name_ctor) if prev_src.content.find(tag) < 0: # no __init__ tag found, issue a warning and do nothing self.warning( "wxGlade %(ctor)s block not found for %(name)s, %(ctor)s code " "NOT generated" % { 'name': code_obj.name, 'ctor': self.name_ctor, } ) else: prev_src.content = prev_src.content.replace(tag, "".join(buffer)) buffer = [] write = buffer.append # generate code for __set_properties() code_lines = self.generate_code_set_properties( builder, code_obj, is_new, tab ) buffer.extend(code_lines) # replace code inside existing __set_properties() function if prev_src and not is_new: # replace the lines inside the __set_properties wxGlade block # with the new ones tag = '<%swxGlade replace %s %s>' % (self.nonce, code_obj.klass, '__set_properties') if prev_src.content.find(tag) < 0: # no __set_properties tag found, issue a warning and do nothing self.warning( "wxGlade __set_properties block not found for %s, " "__set_properties code NOT generated" % code_obj.name ) else: prev_src.content = prev_src.content.replace(tag, "".join(buffer)) buffer = [] write = buffer.append # generate code for __do_layout() code_lines = self.generate_code_do_layout( builder, code_obj, is_new, tab ) buffer.extend(code_lines) # replace code inside existing __do_layout() function if prev_src and not is_new: # replace the lines inside the __do_layout wxGlade block # with the new ones tag = '<%swxGlade replace %s %s>' % (self.nonce, code_obj.klass, '__do_layout') if prev_src.content.find(tag) < 0: # no __do_layout tag found, issue a warning and do nothing self.warning( "wxGlade __do_layout block not found for %s, __do_layout " "code NOT generated" % code_obj.name ) else: prev_src.content = prev_src.content.replace(tag, "".join(buffer)) # generate code for event handler stubs code_lines = self.generate_code_event_handler( code_obj, is_new, tab, prev_src, event_handlers, ) # replace code inside existing event handlers if prev_src and not is_new: tag = \ '<%swxGlade event_handlers %s>' % (self.nonce, code_obj.klass) if prev_src.content.find(tag) < 0: # no event_handlers tag found, issue a warning and do nothing self.warning( "wxGlade event_handlers block not found for %s, " "event_handlers code NOT generated" % code_obj.name ) else: prev_src.content = prev_src.content.replace( tag, "".join(code_lines), ) else: buffer.extend(code_lines) # the code has been generated self.classes[code_obj.klass].done = True # write "end of class" statement if self.tmpl_class_end: write( self.tmpl_class_end % { 'klass': self.cn_class(code_obj.klass), 'comment': self.comment_sign, } ) if self.multiple_files: if prev_src: tag = '<%swxGlade insert new_classes>' % self.nonce prev_src.content = prev_src.content.replace(tag, "") # insert the extra modules tag = '<%swxGlade extra_modules>\n' % self.nonce code = "".join(self._current_extra_modules.keys()) prev_src.content = prev_src.content.replace(tag, code) # insert the module dependencies of this class tag = '<%swxGlade replace dependencies>' % self.nonce dep_list = self.classes[code_obj.klass].dependencies.keys() dep_list.extend(self.dependencies.keys()) dep_list.sort() code = self._tagcontent('dependencies', dep_list) prev_src.content = prev_src.content.replace(tag, code) # insert the extra code of this class extra_code = "".join(self.classes[code_obj.klass].extra_code[::-1]) # if there's extra code but we are not overwriting existing # sources, warn the user if extra_code: self.warning( '%s (or one of its chilren) has extra code classes, ' 'but you are not overwriting existing sources: please ' 'check that the resulting code is correct!' % \ code_obj.name ) tag = '<%swxGlade replace extracode>' % self.nonce code = self._tagcontent('extracode', extra_code) prev_src.content = prev_src.content.replace(tag, code) # store the new file contents to disk self.save_file(filename, prev_src.content, content_only=True) return # create the new source file filename = self._get_class_filename(code_obj.klass) out = cStringIO.StringIO() write = out.write # write the common lines for line in self.header_lines: write(line) # write the module dependecies for this class dep_list = self.classes[code_obj.klass].dependencies.keys() dep_list.extend(self.dependencies.keys()) dep_list.sort() code = self._tagcontent('dependencies', dep_list, True) write(code) # insert the extra code of this class code = self._tagcontent( 'extracode', self.classes[code_obj.klass].extra_code[::-1], True ) write(code) # write the class body for line in buffer: write(line) # store the contents to filename self.save_file(filename, out.getvalue()) out.close() else: # not self.multiple_files if prev_src: # if this is a new class, add its code to the new_classes # list of the SourceFileContent instance if is_new: prev_src.new_classes.append("".join(buffer)) elif self.classes[code_obj.klass].extra_code: self._current_extra_code.extend(self.classes[code_obj.klass].extra_code[::-1]) return else: # write the class body onto the single source file for dep in self.classes[code_obj.klass].dependencies: self._current_extra_modules[dep] = 1 if self.classes[code_obj.klass].extra_code: self._current_extra_code.extend(self.classes[code_obj.klass].extra_code[::-1]) write = self.output_file.write for line in buffer: write(line) def add_object(self, top_obj, sub_obj): """\ Adds the code to build 'sub_obj' to the class body of 'top_obj'. @see: L{_add_object_init()} @see: L{_add_object_format_name()} """ sub_obj.name = self._format_name(sub_obj.name) sub_obj.parent.name = self._format_name(sub_obj.parent.name) # get top level source code object and the widget builder instance klass, builder = self._add_object_init(top_obj, sub_obj) if not klass or not builder: return try: init, props, layout = builder.get_code(sub_obj) except: print sub_obj raise # this shouldn't happen if sub_obj.in_windows: # the object is a wxWindow instance if sub_obj.is_container and not sub_obj.is_toplevel: init.reverse() klass.parents_init.extend(init) else: klass.init.extend(init) # Add a dependency of the current object on its parent klass.deps.append((sub_obj, sub_obj.parent)) klass.child_order.append(sub_obj) klass.init_lines[sub_obj] = init mycn = getattr(builder, 'cn', self.cn) if hasattr(builder, 'get_events'): evts = builder.get_events(sub_obj) for id, event, handler in evts: klass.event_handlers.append((id, mycn(event), handler)) elif 'events' in sub_obj.properties: id_name, id = self.generate_code_id(sub_obj) if id == '-1' or id == self.cn('wxID_ANY'): id = self._add_object_format_name(sub_obj.name) for event, handler in sub_obj.properties['events'].iteritems(): klass.event_handlers.append((id, mycn(event), handler)) # try to see if there's some extra code to add to this class if not sub_obj.preview: extra_code = getattr(builder, 'extracode', sub_obj.properties.get('extracode', "")) if extra_code: extra_code = re.sub(r'\\n', '\n', extra_code) klass.extra_code.append(extra_code) # if we are not overwriting existing source, warn the user # about the presence of extra code if not self.multiple_files and self.previous_source: self.warning( '%s has extra code, but you are not ' 'overwriting existing sources: please check ' 'that the resulting code is correct!' % \ sub_obj.name ) else: # the object is a sizer if sub_obj.base == 'wxStaticBoxSizer': i = init.pop(0) klass.parents_init.insert(1, i) # Add a dependency of the current object on its parent klass.deps.append((sub_obj, sub_obj.parent)) klass.child_order.append(sub_obj) klass.init_lines[sub_obj] = [i] klass.sizers_init.extend(init) klass.props.extend(props) klass.layout.extend(layout) if self.multiple_files and \ (sub_obj.is_toplevel and sub_obj.base != sub_obj.klass): key = self._format_import(sub_obj.klass) klass.dependencies[key] = 1 for dep in getattr(self.obj_builders.get(sub_obj.base), 'import_modules', []): klass.dependencies[dep] = 1 def _add_object_init(self, top_obj, sub_obj): """\ Perform some initial actions for L{add_object()} Widgets without code generator or widget that are not supporting the requested wx version are blacklisted at L{blacklisted_widgets}. @return: Top level source code object and the widget builder instance or C{None, None} in case of errors. """ # initialise internal variables first klass = None builder = None # Check for proper source code instance if top_obj.klass in self.classes: klass = self.classes[top_obj.klass] else: klass = self.classes[top_obj.klass] = self.ClassLines() # Check for widget builder object try: builder = self.obj_builders[sub_obj.base] except KeyError: # no code generator found: write a comment about it msg = _("""\ Code for instance "%s" of "%s" not generated: no suitable writer found""") % ( sub_obj.name, sub_obj.klass, ) self._source_warning(klass, msg, sub_obj) self.warning(msg) # ignore widget later too self.blacklisted_widgets[sub_obj] = 1 return None, None # check for supported versions supported_by = getattr(builder, 'supported_by', ()) if supported_by and self.for_version not in supported_by: supported_versions = ', '.join( [misc.format_for_version(version) for version in supported_by] ) msg = _("""\ Code for instance "%(name)s" of "%(klass)s" was not created, because the widget is not available for wx version %(requested_version)s. It is available for wx versions %(supported_versions)s only.""") % { 'name': sub_obj.name, 'klass': sub_obj.klass, 'requested_version': str(misc.format_for_version(self.for_version)), 'supported_versions': str(supported_versions), } self._source_warning(klass, msg, sub_obj) self.warning(msg) # ignore widget later too self.blacklisted_widgets[sub_obj] = 1 return None, None return klass, builder def add_property_handler(self, property_name, handler, widget_name=None): """\ Sets a function to parse a portion of XML to get the value of the property property_name. If widget_name is not None, the function is called only if the property in inside a widget whose class is widget_name. """ if not widget_name: self.global_property_writers[property_name] = handler else: try: self._property_writers[widget_name][property_name] = handler except KeyError: self._property_writers[widget_name] = {property_name: handler} def add_sizeritem(self, toplevel, sizer, obj, option, flag, border): """\ Writes the code to add the object 'obj' to the sizer 'sizer' in the 'toplevel' object. All widgets in L{blacklisted_widgets} are ignored. @see: L{tmpl_sizeritem} """ # don't process widgets listed in blacklisted_widgets if obj in self.blacklisted_widgets: return # the name attribute of a spacer is already formatted # ", ". This string can simply inserted in Add() call. obj_name = self._format_classattr(obj) if toplevel.klass in self.classes: klass = self.classes[toplevel.klass] else: klass = self.classes[toplevel.klass] = self.ClassLines() # check if sizer has to store as a class attribute sizer_name = self._format_classattr(sizer) stmt = self.tmpl_sizeritem % ( sizer_name, obj_name, option, self.cn_f(flag), border, ) klass.layout.append(stmt) def add_widget_handler(self, widget_name, handler, *args, **kwds): self.obj_builders[widget_name] = handler def create_generated_by(self): """\ Create I{generated by wxGlade} string without leading comment characters and without tailing new lines @rtype: String """ if config.preferences.write_timestamp: msg = 'generated by wxGlade %s on %s%s' % ( common.version, time.asctime(), common.generated_from(), ) else: msg = 'generated by wxGlade %s%s' % ( common.version, common.generated_from(), ) return msg def create_nonce(self): """\ Create a random number used to be sure that the replaced tags in the sources are the right ones (see SourceFileContent and add_class) @return: A random nonce @rtype: String """ nonce = '%s%s' % (str(time.time()).replace('.', ''), random.randrange(10 ** 6, 10 ** 7)) return nonce def get_property_handler(self, property_name, widget_name): """\ Return the widget specific property handler @see: L{add_property_handler} @see: L{global_property_writers} @see: L{_property_writers} """ try: cls = self._property_writers[widget_name][property_name] except KeyError: cls = self.global_property_writers.get(property_name, None) if cls: return cls() return None def generate_code_background(self, obj): """\ Returns the code fragment that sets the background colour of the given object. @rtype: String @see: L{_get_colour()} """ # check if there is an code template for this property if 'backgroundcolour' not in self.code_statements: msg = " %s WARNING: no code template for property '%s' " \ "registered!\n" % (self.comment_sign, 'backgroundcolour') self.warning(msg) return msg objname = self._get_code_name(obj) color = self._get_colour(obj.properties['background']) tmpl = self.code_statements['backgroundcolour'] stmt = tmpl % { 'objname': objname, 'value': color, } return stmt def generate_code_ctor(self, code_obj, is_new, tab): """\ Generate constructor code for top-level object @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param is_new: Flag if a new file is creating @type is_new: Boolean @param tab: Indentation @type tab: String @rtype: List of strings """ return [] def generate_code_disabled(self, obj): """\ Returns the code fragment that disables the given object. @rtype: String """ return self._generic_code(obj, 'disabled') def generate_code_do_layout(self, builder, code_obj, is_new, tab): """\ Generate code for the function C{__do_layout()}. If C{is_new} is set, this function returns source code for the whole function. Otherwise it returns just the function body framed by "begin wxGlade" and "end wxGlade". @param builder: Widget specific builder @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param is_new: Indicates if previous source code exists @type is_new: Boolean @param tab: Indentation of function body @type tab: String @rtype: List of strings @see: L{tmpl_name_do_layout} @see: L{tmpl_func_do_layout} @see: L{tmpl_func_empty} @see: L{_generate_function()} """ code_lines = [] write = code_lines.append # generate content of function body first layout_lines = self.classes[code_obj.klass].layout sizers_init_lines = self.classes[code_obj.klass].sizers_init # check if there are extra layout lines to add if hasattr(builder, 'get_layout_code'): extra_layout_lines = builder.get_layout_code(code_obj) else: extra_layout_lines = [] if layout_lines or sizers_init_lines or extra_layout_lines: sizers_init_lines.reverse() for l in sizers_init_lines: write(l) for l in layout_lines: write(l) for l in extra_layout_lines: write(l) code_lines = self._generate_function( code_obj, is_new, tab, self.tmpl_name_do_layout, self.tmpl_func_do_layout, code_lines, ) return code_lines def generate_code_event_bind(self, code_obj, tab, event_handlers): """\ Generate to bind event handlers. This function is used for interpreted languages only. @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param tab: Indentation of function body @type tab: String @param event_handlers: List of event handlers @rtype: List of strings """ return [] def generate_code_event_handler(self, code_obj, is_new, tab, prev_src, \ event_handlers): """\ Generate the event handler stubs @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param is_new: Indicates if previous source code exists @type is_new: Boolean @param tab: Indentation of function body @type tab: String @param prev_src: Previous source code @type prev_src: Language specific instance of SourceFileContent @param event_handlers: List of event handlers @rtype: List of strings @see: L{tmpl_func_event_stub} """ code_lines = [] write = code_lines.append if prev_src and not is_new: already_there = prev_src.event_handlers.get(code_obj.klass, {}) else: already_there = {} for name, event, handler in event_handlers: # don't create handler twice if handler in already_there: continue # add an empty line for # TODO: Remove later if self.language in ['python', 'lisp',]: if not (prev_src and not is_new): write('\n') write(self.tmpl_func_event_stub % { 'tab': tab, 'klass': self.cn_class(code_obj.klass), 'handler': handler, }) already_there[handler] = 1 return code_lines def generate_code_extraproperties(self, obj): """\ Returns a code fragment that set extra properties for the given object @rtype: List of strings """ if not 'extraproperties' in self.code_statements: return [] objname = self._get_code_name(obj) prop = obj.properties['extraproperties'] ret = [] for name in sorted(prop): tmpl = self.code_statements['extraproperties'] stmt = tmpl % { 'klass': obj.klass, 'objname': objname, 'propname': name, 'value': prop[name], } ret.append(stmt) return ret def generate_code_focused(self, obj): """\ Returns the code fragment that get the focus to the given object. @rtype: String """ return self._generic_code(obj, 'focused') def generate_code_font(self, obj): """\ Returns the code fragment that sets the font of the given object. @rtype: String """ stmt = None # check if there is an code template for this property if 'setfont' not in self.code_statements: msg = " %s WARNING: no code template for property '%s' " \ "registered!\n" % (self.comment_sign, 'setfont') self.warning(msg) return msg objname = self._get_code_name(obj) cnfont = self.cn('wxFont') font = obj.properties['font'] family = self.cn(font['family']) face = '"%s"' % font['face'].replace('"', r'\"') size = font['size'] style = self.cn(font['style']) underlined = font['underlined'] weight = self.cn(font['weight']) tmpl = self.code_statements['setfont'] stmt = tmpl % { 'objname': objname, 'cnfont': cnfont, 'face': face, 'family': family, 'size': size, 'style': style, 'underlined': underlined, 'weight': weight, } return stmt def generate_code_foreground(self, obj): """\ Returns the code fragment that sets the foreground colour of the given object. @rtype: String @see: L{_get_colour()} """ # check if there is an code template for this property if 'foregroundcolour' not in self.code_statements: msg = " %s WARNING: no code template for property '%s' " \ "registered!\n" % (self.comment_sign, 'foregroundcolour') self.warning(msg) return msg objname = self._get_code_name(obj) color = self._get_colour(obj.properties['foreground']) tmpl = self.code_statements['foregroundcolour'] stmt = tmpl % { 'objname': objname, 'value': color, } return stmt def generate_code_hidden(self, obj): """\ Returns the code fragment that hides the given object. @rtype: String """ return self._generic_code(obj, 'hidden') def generate_code_id(self, obj, id=None): """\ Generate the code for the widget ID. The parameter C{id} is evaluated first. An empty string for C{id} returns C{'', 'wxID_ANY'}. Returns a tuple of two string. The two strings are: 1. A line to the declare the variable. It's empty if the object id is a constant 2. The value of the id @param obj: An instance of L{xml_parse.CodeObject} @param id: Widget ID definition as String. @rtype: Tuple of two strings """ raise NotImplementedError def generate_code_set_properties(self, builder, code_obj, is_new, tab): """\ Generate code for the function C{__set_properties()}. If C{is_new} is set, this function returns source code for the whole function. Otherwise it returns just the function body framed by "begin wxGlade" and "end wxGlade". @param builder: Widget specific builder @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param is_new: Indicates if previous source code exists @type is_new: Boolean @param tab: Indentation of function body @type tab: String @rtype: List of strings @see: L{tmpl_name_set_properties} @see: L{tmpl_func_set_properties} @see: L{tmpl_func_empty} @see: L{_generate_function()} """ # check if there are property lines to add _get_properties = getattr( builder, 'get_properties_code', self.generate_common_properties) property_lines = _get_properties(code_obj) property_lines.extend(self.classes[code_obj.klass].props) code_lines = self._generate_function( code_obj, is_new, tab, self.tmpl_name_set_properties, self.tmpl_func_set_properties, property_lines, ) return code_lines def generate_code_size(self, obj): """\ Returns the code fragment that sets the size of the given object. @rtype: String """ raise NotImplementedError def generate_code_tooltip(self, obj): """\ Returns the code fragment that sets the tooltip of the given object. @rtype: String """ return self._generic_code(obj, 'tooltip') def generate_common_properties(self, widget): """\ generates the code for various properties common to all widgets (background and foreground colors, font, ...) @return: a list of strings containing the generated code @rtype: List of strings @see: L{generate_code_background()} @see: L{generate_code_disabled()} @see: L{generate_code_extraproperties()} @see: L{generate_code_focused()} @see: L{generate_code_font()} @see: L{generate_code_foreground()} @see: L{generate_code_hidden()} @see: L{generate_code_size()} @see: L{generate_code_tooltip()} """ prop = widget.properties out = [] if prop.get('size', '').strip(): out.append(self.generate_code_size(widget)) if prop.get('background'): out.append(self.generate_code_background(widget)) if prop.get('foreground'): out.append(self.generate_code_foreground(widget)) if prop.get('font'): out.append(self.generate_code_font(widget)) # tooltip if prop.get('tooltip'): out.append(self.generate_code_tooltip(widget)) # trivial boolean properties if prop.get('disabled'): out.append(self.generate_code_disabled(widget)) if prop.get('focused'): out.append(self.generate_code_focused(widget)) if prop.get('hidden'): out.append(self.generate_code_hidden(widget)) if prop.get('extraproperties') and not widget.preview: out.extend(self.generate_code_extraproperties(widget)) return out def cn(self, name): """\ Return the class name properly formatted for the selected name space. @see: L{cn_f()} @see: L{cn_class} """ return name def cn_f(self, flags): """\ Return the flags properly formatted for the selected name space. """ return flags def cn_class(self, klass): """\ Return the klass name @see: L{cn()} """ return klass def quote_str(self, s, translate=True, escape_chars=True): """\ returns a quoted version of 's', suitable to insert in a python source file as a string object. Takes care also of gettext support @param s: String to quote @param translate: Encapsulate string into a gettext statement, if L{_use_gettext} is True @param escape_chars: Escape special meaning characters like backspace or quotes @rtype: String """ raise NotImplementedError def quote_path(self, s): """\ escapes all quotation marks and backslashes, thus making a path suitable to insert in a list source file @note: You may overwrite this function in the derivated class @rtype: String """ # " ALB: to avoid emacs going insane with colorization.. s = s.replace('\\', '\\\\') s = s.replace('"', r'\"') s = s.replace('$', r'\$') # sigh s = s.replace('@', r'\@') return '"%s"' % s def save_file(self, filename, content, mainfile=False, content_only=False): """\ Store the content in a file. A L{shebang} is added in top of all mainfiles. The permissions of mainfiles will be set to C{0755} too. L{common.save_file()} is used for storing content. @param filename: File name @type filename: String @param content: File content @type content: String @param mainfile: Mainfiles gets a L{shebang} and C{0755} permissions. @type mainfile: Boolean @param content_only: Write only content to the file @type content_only: Boolean @see: L{common.save_file()} """ # create an temporary StringIO file to add header tmp = "" # write additional information to file header if not content_only: # add shebang to main file if self.shebang and mainfile or self.language == 'C++': tmp += self.shebang # add file encoding notice if self.tmpl_encoding and self.app_encoding: tmp += self.tmpl_encoding % self.app_encoding # add created by notice if self.tmpl_generated_by: tmp += self.tmpl_generated_by % { 'comment_sign': self.comment_sign, 'generated_by': self.create_generated_by(), } # add language specific note if self.language_note: tmp += "%s" % self.language_note # add a empty line tmp += "\n" # add original file content tmp += content # check for sub necessary directories e.g. for Perl or Python modules dirname = os.path.dirname(filename) if dirname and not os.path.isdir(dirname): try: os.makedirs(dirname) except: common.message.exception( _('Can not create output directory "%s"'), dirname ) # save the file now try: common.save_file(filename, tmp, 'codegen') except IOError, e: raise XmlParsingError(str(e)) except: common.message.exception(_('Internal Error')) if mainfile and sys.platform in ['linux2', 'darwin']: try: # make the file executable os.chmod(filename, 0755) except OSError, e: # this isn't necessarily a bad errror self.warning( _('Changing permission of main file "%s" failed: %s') % ( filename, str(e) ) ) def test_attribute(self, obj): """\ Returns True if 'obj' should be added as an attribute of its parent's class, False if it should be created as a local variable of C{__do_layout}. The function returns True of the object klass is listed in L{classattr_always}. The function returns True for all widgets except sizers, if - the property exists and is an integer greater equal 1 - the property does not exists - the property contains a non-integer value The function returns True for sizers, if - the property exists and is an integer greater equal 1 @rtype: Boolean @see: L{classattr_always} """ if obj.klass in self.classattr_always: return True try: return int(obj.properties['attribute']) except (KeyError, ValueError): if obj.in_sizers: return False return True # this is the default def tabs(self, number): """\ Return a proper formatted string for indenting lines @rtype: String """ return self.indent_symbol * self.indent_amount * number def warning(self, msg): """\ Show a warning message @param msg: Warning message @type msg: String @see: L{common.MessageLogger.warn()} """ if self._show_warnings: common.message.warn(msg) def _content_notfound(self, source): """\ Remove all the remaining <123415wxGlade ...> tags from the source and add a warning instead. This may happen if we're not generating multiple files, and one of the container class names is changed. The indentation of the string depends values detected during the initial parsing of the source file. Those values are stored in L{BaseSourceFileContent.spaces}. @param source: Source content with tags to replace @type source: String @return: Changed content @rtype: String """ tags = re.findall( '(<%swxGlade replace ([a-zA-Z_]\w*) +[.\w]+>)' % self.nonce, source ) for tag in tags: # re.findall() returned a list of tuples (caused by grouping) # first element in tuple: the whole match # second element in tuple: the class / block name indent = self.previous_source.spaces.get(tag[1], "") comment = '%(indent)s%(comment_sign)s Content of this block not found. ' \ 'Did you rename this class?\n' if 'contentnotfound' in self.code_statements: comment += '%(indent)s%(command)s\n' command = self.code_statements['contentnotfound'] else: command = "" comment = comment % { 'command': command, 'comment_sign': self.comment_sign, 'indent': indent, } source = source.replace(tag[0], comment) return source def _do_replace(self, match): """\ Escape double backslashed in first RE match group """ if match.group(0) == '\\': return '\\\\' else: return match.group(0) def _file_exists(self, filename): """\ Check if the file exists @note: Separated for debugging purposes @rtype: Boolean """ return os.path.isfile(filename) def _add_object_format_name(self, name): """\ Format a widget name to use in L{add_object()}. @note: This function is for use in L{add_object()} only! @param name: Widget name @type name: String @rtype: String @see: L{add_object()} """ return name def _format_classattr(self, obj): """\ Format the object name to store as a class attribute. @param obj: Instance of L{xml_parse.CodeObject} @rtype: String """ if not obj: return '' elif not getattr(obj, 'name', None): return '' return obj.name def _format_comment(self, msg): """\ Return message formatted to add as a comment string in generating source code. Trailing spaces will be removed. Leading spaces e.g. identation won't be added. @type msg: String @rtype: String """ return "%s %s" % (self.comment_sign, msg.rstrip()) def _format_import(self, klass): """\ Return formatted import statement for the given class @param klass: Class name @type klass: String @rtype: String """ return klass def _format_name(self, name): """\ Format a class or a widget name by replacing forbidden characters. @rtype: String """ return name def _format_style(self, style, code_obj): """\ Return the formatted styles to insert into constructor code. The function just returned L{tmpl_style}. Write a derived version implementation if more logic is needed. @see: L{tmpl_style} @rtype: String """ return self.tmpl_style def _generic_code(self, obj, prop_name): """\ Create a code statement for calling a method e.g. to hide a widget. @param obj: Instance of L{xml_parse.CodeObject} @param prop_name: Name of the property to set @type prop_name: String @return: Code statement or None @rtype: String @see: L{code_statements} """ stmt = None value = None # check if there is an code template for this prop_name if prop_name not in self.code_statements: msg = " %s WARNING: no code template for property '%s' " \ "registered!\n" % (self.comment_sign, prop_name) self.warning(msg) return msg # collect detail informaton if prop_name in ['disabled', 'focused', 'hidden']: try: value = int(obj.properties[prop_name]) except (KeyError, ValueError): # nothing to do return None elif prop_name == 'tooltip': value = self.quote_str(obj.properties['tooltip']) else: raise AssertionError("Unknown property name: %s" % prop_name) objname = self._get_code_name(obj) tmpl = self.code_statements[prop_name] stmt = tmpl % { 'objname': objname, 'tooltip': value, } return stmt def _get_code_name(self, obj): """\ Returns the language specific name of the variable e.g. C{self} or C{$self}. @rtype: String """ raise NotImplementedError def _get_colour(self, colourvalue): """\ Returns the language specific colour statement @rtype: String """ # check if there is an code template for this properties if 'wxcolour' not in self.code_statements: msg = " %s WARNING: no code template for property '%s' " \ "registered!\n" % (self.comment_sign, 'wxcolour') self.warning(msg) return msg if 'wxsystemcolour' not in self.code_statements: msg = " %s WARNING: no code template for property '%s' " \ "registered!\n" % (self.comment_sign, 'wxsystemcolour') self.warning(msg) return msg try: value = self._string_to_colour(colourvalue) func = self.cn(self.code_statements['wxcolour']) except (IndexError, ValueError): # the color is from system settings value = self.cn(colourvalue) func = self.cn(self.code_statements['wxsystemcolour']) stmt = func % { 'value': value, } return stmt def _get_class_filename(self, klass): """\ Returns the filename to store a single class in multi file projects. @param klass: Class name @type klass: String @rtype: String """ return '' def _generate_function(self, code_obj, is_new, tab, fname, ftmpl, body): """\ Generic function to generate a complete function from given parts. @param code_obj: Object to generate code for @type code_obj: Instance of L{CodeObject} @param is_new: Indicates if previous source code exists @type is_new: Boolean @param tab: Indentation of function body @type tab: String @param fname: Name of the function @type fname: String @param ftmpl: Template of the function @type ftmpl: String @param body: Content of the function @type body: List of strings @rtype: List of strings """ code_lines = [] write = code_lines.append # begin tag write(self.tmpl_block_begin % { 'class_separator': self.class_separator, 'comment_sign': self.comment_sign, 'function': fname, 'klass': self.cn_class(code_obj.klass), 'tab': tab, }) if body: for l in body: write(tab + l) else: write(self.tmpl_func_empty % {'tab': tab}) # end tag write('%s%s end wxGlade\n' % (tab, self.comment_sign)) # embed the content into function template if is_new: stmt = ftmpl % { 'tab': tab, 'klass': code_obj.klass, 'content': ''.join(code_lines), } code_lines = ["%s\n" % line.rstrip() for line in stmt.split('\n')] # remove newline at last line code_lines[-1] = code_lines[-1].rstrip() return code_lines def _setup(self): """\ Load language specific code generators """ # scan widgets.txt for widgets, load language specific code generators widgets_file = os.path.join(common.widgets_path, 'widgets.txt') if not os.path.isfile(widgets_file): self.warning("widgets file (%s) doesn't exist" % widgets_file) return sys.path.append(common.widgets_path) modules = open(widgets_file) for line in modules: module_name = line.strip() if not module_name or module_name.startswith('#'): continue module_name = module_name.split('#')[0].strip() try: fqmn = "%s.%s_codegen" % (module_name, self.language) m = __import__( fqmn, {}, {}, ['initialize']) m.initialize() except (ImportError, AttributeError): pass ## print 'ERROR loading "%s"' % module_name ## common.message.exception(_('Internal Error')) ## else: ## print 'initialized %s generator for %s' % (self.language, module_name) modules.close() def _source_warning(self, klass, msg, sub_obj): """\ Format and add a warning message to the source code. The message msg will be split into single lines and every line will be proberly formatted added to the source code. @param klass: Instance of L{ClassLines} to add the code in @param msg: Multiline message @type msg: String @param sub_obj: Object to generate code for @type sub_obj: Instance of L{CodeObject} @see: L{_format_comment()} """ code_lines = [] # add leading empty line code_lines.append('\n') # add a leading "WARNING:" to the message if not msg.upper().startswith(_('WARNING:')): msg = "%s %s" % (_('WARNING:'), msg) # add message text for line in msg.split('\n'): code_lines.append( "%s\n" % self._format_comment(line.rstrip()) ) # add tailing empty line code_lines.append('\n') # Add warning message to source code # TODO: Remove next three lines after C++ code gen uses dependencies # like Python, Perl and Lisp if self.language == 'C++': klass.init.extend(code_lines) else: klass.deps.append((sub_obj, sub_obj.parent)) klass.child_order.append(sub_obj) klass.init_lines[sub_obj] = code_lines def _string_to_colour(self, s): """\ Convert a colour values out of a hex string to comma separated decimal values. Example:: >>> self._string_to_colour('#FFFFFF') '255, 255, 255' >>> self._string_to_colour('#ABCDEF') '171, 205, 239' @rtype: String """ return '%d, %d, %d' % ( int(s[1:3], 16), int(s[3:5], 16), int(s[5:], 16) ) def _tagcontent(self, tag, content, newline=False): """\ Content embeded between C{begin wxGlade} and C{end wxGlade} sequence. @return: Embedded content @rtype: String @param tag: Tag is used in C{begin wxGlade} statement for separate different blocks @type tag: String @param content: Content to enter @type content: String or List of strings @param newline: Add a tailing empty line @type newline: Boolean """ code_list = [] code_list.append( '%s begin wxGlade: %s' % (self.comment_sign, tag) ) if type(content) == types.ListType: for entry in content: code_list.append(entry.rstrip()) elif type(content) in types.StringTypes: # don't append empty content _content = content.rstrip() if _content: code_list.append(_content) else: raise AssertionError('Unknown content type: %s' % type(content)) code_list.append( '%s end wxGlade' % self.comment_sign ) # newline for "end wxGlade" line code_list.append('') if newline: code_list.append('') return "\n".join(code_list) # end of class BaseCodeWriter wxglade-0.6.8.orig/configdialog.py0000644000175000017500000001353412150154266017324 0ustar georgeskgeorgesk""" Dialog for editing wxGlade preferences @see: L{config.preferences} @copyright: 2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import general python modules import os import wx import misc from configUI import wxGladePreferencesUI class wxGladePreferences(wxGladePreferencesUI): def __init__(self, preferences): wxGladePreferencesUI.__init__(self, None, -1, "") wx.EVT_BUTTON(self, self.choose_widget_path.GetId(), self.on_widget_path) self.preferences = preferences self.set_values() # disable CheckBox for selecting usage of KDE file dialogs if wx.Platform != '__WXGTK__': self.use_kde_dialogs.SetValue(False) self.use_kde_dialogs.Enable(False) def set_values(self): try: self.use_menu_icons.SetValue(self.preferences.use_menu_icons) self.frame_tool_win.SetValue(self.preferences.frame_tool_win) self.open_save_path.SetValue(self.preferences.open_save_path) self.codegen_path.SetValue(self.preferences.codegen_path) self.use_dialog_units.SetValue( self.preferences.use_dialog_units) self.number_history.SetValue(self.preferences.number_history) self.show_progress.SetValue(self.preferences.show_progress) self.wxg_backup.SetValue(self.preferences.wxg_backup) self.codegen_backup.SetValue(self.preferences.codegen_backup) self.default_border.SetValue(self.preferences.default_border) self.default_border_size.SetValue( self.preferences.default_border_size) if self.preferences.backup_suffix == '.bak': self.backup_suffix.SetSelection(1) self.buttons_per_row.SetValue(self.preferences.buttons_per_row) self.remember_geometry.SetValue( self.preferences.remember_geometry) self.local_widget_path.SetValue( self.preferences.local_widget_path) self.show_sizer_handle.SetValue( self.preferences.show_sizer_handle) self.allow_duplicate_names.SetValue( self.preferences.allow_duplicate_names) self.autosave.SetValue(self.preferences.autosave) self.autosave_delay.SetValue(self.preferences.autosave_delay) self.use_kde_dialogs.SetValue(self.preferences.use_kde_dialogs) self.show_completion.SetValue(self.preferences.show_completion) self.write_timestamp.SetValue(self.preferences.write_timestamp) self.write_generated_from.SetValue( self.preferences.write_generated_from) self._fix_spin_ctrls() except Exception, e: wx.MessageBox( _('Error reading config file:\n%s') % e, _('Error'), wx.OK | wx.CENTRE | wx.ICON_ERROR ) def _fix_spin_ctrls(self): """\ Workaround to a wxGTK 2.8.4.2 bug in wx.SpinCtrl.GetValue """ done = {} for name in ('buttons_per_row', 'autosave_delay', 'number_history', 'default_border_size'): def fix(n): done[n] = False def update(e): done[n] = True e.Skip() def get_val(): if not done[n]: return getattr(self.preferences, n) else: return wx.SpinCtrl.GetValue(getattr(self, n)) return update, get_val spin = getattr(self, name) if spin.GetValue() != getattr(self.preferences, name): update, get_val = fix(name) spin.GetValue = get_val spin.Bind(wx.EVT_SPINCTRL, update) def set_preferences(self): prefs = self.preferences prefs['use_menu_icons'] = self.use_menu_icons.GetValue() prefs['frame_tool_win'] = self.frame_tool_win.GetValue() prefs['open_save_path'] = self.open_save_path.GetValue() prefs['codegen_path'] = self.codegen_path.GetValue() prefs['use_dialog_units'] = self.use_dialog_units.GetValue() prefs['number_history'] = self.number_history.GetValue() prefs['show_progress'] = self.show_progress.GetValue() prefs['wxg_backup'] = self.wxg_backup.GetValue() prefs['codegen_backup'] = self.codegen_backup.GetValue() prefs['default_border'] = self.default_border.GetValue() prefs['default_border_size'] = self.default_border_size.GetValue() if self.backup_suffix.GetSelection(): prefs['backup_suffix'] = '.bak' else: prefs['backup_suffix'] = '~' prefs['buttons_per_row'] = self.buttons_per_row.GetValue() prefs['remember_geometry'] = self.remember_geometry.GetValue() prefs['local_widget_path'] = self.local_widget_path.GetValue() prefs['show_sizer_handle'] = self.show_sizer_handle.GetValue() prefs['allow_duplicate_names'] = \ self.allow_duplicate_names.GetValue() prefs['autosave'] = self.autosave.GetValue() prefs['autosave_delay'] = self.autosave_delay.GetValue() prefs['use_kde_dialogs'] = self.use_kde_dialogs.GetValue() prefs['show_completion'] = self.show_completion.GetValue() prefs['write_timestamp'] = self.write_timestamp.GetValue() prefs['write_generated_from'] = self.write_generated_from.GetValue() def on_widget_path(self, event): """\ Create a file choice dialog """ pth = misc.DirSelector(_("Choose a directory:"), os.getcwd(), style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON) if pth: self.local_widget_path.SetValue(pth) # end of class wxGladePreferences wxglade-0.6.8.orig/about.py0000644000175000017500000001273211677675750016033 0ustar georgeskgeorgesk# about.py: about box with general info # $Id: about.py,v 1.24 2007/03/27 07:02:07 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import wx.html import wx.lib.wxpTag import common, misc, os.path class wxGladeAboutBox(wx.Dialog): text = '''
Version %s on Python %s and wxPython %s

License: MIT (see license.txt)

Home page: http://wxglade.sourceforge.net

For credits, see credits.txt.

''' def __init__(self, parent=None): wx.Dialog.__init__(self, parent, -1, _('About wxGlade')) class HtmlWin(wx.html.HtmlWindow): def OnLinkClicked(self, linkinfo): href = linkinfo.GetHref() if href == 'show_license': if common.license_file: from wx.lib.dialogs import ScrolledMessageDialog try: license_file = open(common.license_file) dlg = ScrolledMessageDialog( self, license_file.read(), _("wxGlade - License") ) license_file.close() dlg.ShowModal() dlg.Destroy() except IOError: wx.MessageBox(_("Can't find the license!\n" "You can get a copy at \n" "http://www.opensource.org/licenses/" "mit-license.php"), _("Error"), wx.OK|wx.CENTRE|wx.ICON_EXCLAMATION) else: wx.MessageBox(_("Can't find the license!\n" "You can get a copy at \n" "http://www.opensource.org/licenses/" "mit-license.php"), _("Error"), wx.OK|wx.CENTRE|wx.ICON_EXCLAMATION) elif href == 'show_credits': if common.credits_file: from wx.lib.dialogs import ScrolledMessageDialog try: credits_file = open(common.credits_file) dlg = ScrolledMessageDialog( self, credits_file.read(), _("wxGlade - Credits") ) credits_file.close() dlg.ShowModal() dlg.Destroy() except IOError: wx.MessageBox(_("Can't find the credits file!\n"), _("Error"), wx.OK|wx.CENTRE|wx.ICON_EXCLAMATION) else: wx.MessageBox(_("Can't find the credits file!\n"), _("Error"), wx.OK|wx.CENTRE|wx.ICON_EXCLAMATION) else: import webbrowser webbrowser.open(linkinfo.GetHref(), new=True) html = HtmlWin(self, -1, size=(400, -1)) # it's recommended at least for GTK2 based wxPython if "gtk2" in wx.PlatformInfo: html.SetStandardFonts() bgcolor = misc.color_to_string(self.GetBackgroundColour()) icon_path = os.path.join(common.icons_path, 'wxglade_small.png') html.SetPage(self.text % (bgcolor, icon_path, common.version, common.py_version, wx.__version__)) ir = html.GetInternalRepresentation() ir.SetIndent(0, wx.html.HTML_INDENT_ALL) html.SetSize((ir.GetWidth(), ir.GetHeight())) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(html, 0, wx.TOP|wx.ALIGN_CENTER, 10) szr.Add(wx.StaticLine(self, -1), 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 20) szr2 = wx.BoxSizer(wx.HORIZONTAL) btn = wx.Button(self, wx.ID_OK, _("OK")) btn.SetDefault() szr2.Add(btn) if wx.Platform == '__WXGTK__': extra_border = 5 # border around a default button else: extra_border = 0 szr.Add(szr2, 0, wx.ALL|wx.ALIGN_RIGHT, 20 + extra_border) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.Layout() if parent: self.CenterOnParent() else: self.CenterOnScreen() # end of class wxGladeAboutBox if __name__ == '__main__': wx.InitAllImageHandlers() app = wx.PySimpleApp() d = wxGladeAboutBox() app.SetTopWindow(d) d.ShowModal() wxglade-0.6.8.orig/template.py0000644000175000017500000001735012150154266016512 0ustar georgeskgeorgesk""" Handles the template tags and description @copyright: 2002-2007 Alberto Griggio @author: Guy Rutenberg @author: Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ from xml.dom import minidom from xml.sax import saxutils import config import templates_ui import common, misc import os, glob import wx class Template: """ \ A class that handles the specific aspects of template files. """ def __init__(self, filename=None): self.author = '' self.description = '' self.instructions = '' self.filename = filename if filename is not None: filexml = minidom.parse(filename) # we have no use for all the xml data in the file. We only care # about what is between the "description" tags templatedata = filexml.getElementsByTagName('templatedata') if len(templatedata): desc_xml = templatedata[0] try: self.author = saxutils.unescape( desc_xml.getElementsByTagName( 'author')[0].firstChild.data) except (IndexError, AttributeError): self.author = '' try: self.description = saxutils.unescape( desc_xml.getElementsByTagName( 'description')[0].firstChild.data) except (IndexError, AttributeError): self.description = '' try: self.instructions = saxutils.unescape( desc_xml.getElementsByTagName( 'instructions')[0].firstChild.data) except (IndexError, AttributeError): self.instructions = '' else: self.author = '' self.description='' self.instructions='' def write(self, outfile, tabs): fwrite = outfile.write t1 = ' ' * tabs t2 = ' ' * (tabs+1) fwrite(t1 + '\n') fwrite(t2 + '%s\n' % \ saxutils.escape(common._encode_to_xml(self.author))) fwrite(t2 + '%s\n' % \ saxutils.escape(common._encode_to_xml(self.description))) fwrite(t2 + '%s\n' % \ saxutils.escape(common._encode_to_xml(self.instructions))) fwrite(t1 + '\n') # end of class Template class TemplateListDialog(templates_ui.TemplateListDialog): def __init__(self): templates_ui.TemplateListDialog.__init__(self, None, -1, "") self.templates = [] self.fill_template_list() self.selected_template = None def get_selected(self): index = self.template_names.GetSelection() if index >= 0: return self.templates[index] else: return None def on_open(self, event): self.selected_template = self.get_selected() self.EndModal(wx.ID_OPEN) def on_select_template(self, event): self.selected_template = self.get_selected() if self.selected_template is not None: t = Template(self.selected_template) self.set_template_name(self.template_names.GetStringSelection()) self.author.SetValue(misc.wxstr(t.author)) self.description.SetValue(misc.wxstr(t.description)) self.instructions.SetValue(misc.wxstr(t.instructions)) if os.path.dirname(self.selected_template) == common.templates_path: self.btn_delete.Disable() self.btn_edit.Disable() else: self.btn_delete.Enable() self.btn_edit.Enable() else: self.set_template_name("") self.author.SetValue("") self.description.SetValue("") self.instructions.SetValue("") if event: event.Skip() def set_template_name(self, name): self.template_name.SetLabel(_("wxGlade template:\n") + misc.wxstr(name)) def on_edit(self, event): self.selected_template = self.get_selected() self.EndModal(wx.ID_EDIT) def on_delete(self, event): self.selected_template = self.get_selected() if self.selected_template is not None: name = self.template_names.GetStringSelection() if wx.MessageBox(_("Delete template '%s'?") % misc.wxstr(name), _("Are you sure?"), style=wx.YES|wx.NO|wx.CENTRE) == wx.YES: try: os.unlink(self.selected_template) except Exception, e: print e self.fill_template_list() self.selected_template = None def fill_template_list(self): self.templates = load_templates() self.template_names.Clear() if self.templates: for n in self.templates: self.template_names.Append( os.path.splitext(os.path.basename(n))[0] ) # show details of first template self.template_names.SetSelection(0) self.on_select_template(None) # end of class TemplateListDialog def load_templates(): """\ Finds all the available templates. """ d = os.path.join(config._get_appdatapath(), '.wxglade') if d != common.wxglade_path: extra = glob.glob(os.path.join(d, "templates", "*.wgt")) else: extra = [] return sorted(glob.glob(os.path.join(common.templates_path, "*.wgt"))) + \ sorted(extra) def select_template(): """\ Returns the filename of a template to load """ dlg = TemplateListDialog() dlg.btn_delete.Hide() dlg.btn_edit.Hide() if dlg.ShowModal() == wx.ID_OPEN: ret = dlg.selected_template else: ret = None dlg.Destroy() return ret def save_template(data=None): """\ Returns an out file name and template description for saving a template """ dlg = templates_ui.TemplateInfoDialog(None, -1, "") if data is not None: dlg.template_name.SetValue( misc.wxstr(os.path.basename(os.path.splitext(data.filename)[0]))) dlg.author.SetValue(misc.wxstr(data.author)) dlg.description.SetValue(misc.wxstr(data.description)) dlg.instructions.SetValue(misc.wxstr(data.instructions)) ret = None retdata = Template() if dlg.ShowModal() == wx.ID_OK: ret = dlg.template_name.GetValue().strip() retdata.author = dlg.author.GetValue() retdata.description = dlg.description.GetValue() retdata.instructions = dlg.instructions.GetValue() if not ret: wx.MessageBox(_("Can't save a template with an empty name"), _("Error"), wx.OK|wx.ICON_ERROR) dlg.Destroy() name = ret if ret: d = os.path.join(config._get_appdatapath(), '.wxglade', 'templates') if not os.path.exists(d): try: os.makedirs(d) except (OSError, IOError), e: print _("ERROR creating %s: %s") % (d, e) return None, retdata ret = os.path.join(d, ret + '.wgt') if ret and os.path.exists(ret) and \ wx.MessageBox(_("A template called '%s' already exists:\ndo you want to" " overwrite it?") % name, _("Question"), wx.YES|wx.NO|wx.ICON_QUESTION) != wx.YES: ret = None return ret, retdata def manage_templates(): dlg = TemplateListDialog() dlg.btn_open.Hide() #dlg.btn_edit.Hide() ret = None if dlg.ShowModal() == templates_ui.ID_EDIT: ret = dlg.selected_template dlg.Destroy() return ret wxglade-0.6.8.orig/common.py0000644000175000017500000005022312167574501016171 0ustar georgeskgeorgesk""" Global variables @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import os import pprint import sys import traceback import types use_gui = True """\ If False, the program is invoked from the command-line in "batch" mode (for code generation only) """ nohg_version = '0.6.8' """\ Version number to return if no hg repo has been found """ def _get_version(): """\ Create the version identification string Try to query the local hg repository to build the version string or return L{nohg_version}. @return: The current wxGlade version number @rtype: String @see: L{nohg_version} """ # main_version = '' main_version = nohg_version repo_changed = [] # try: # from mercurial.hg import repository # from mercurial.ui import ui # from mercurial.node import short # from mercurial.error import RepoError # except ImportError: # # no mercurial module available # main_version = nohg_version # except: # # unkown failure # main_version = nohg_version # else: # # try to open local hg repository # try: # repo = repository(ui(), os.path.dirname(__file__)) # except RepoError: # # no mercurial repository found # main_version = nohg_version # else: # ctx = repo[None] # parents = ctx.parents() # repo_changed = ctx.files() + ctx.deleted() # if len(parents) == 1 and not repo_changed: # # release tag isn't at tip it's -2 (one below tip) # parents = parents[0].parents() # node = parents[0].node() # tags = repo.nodetags(node) # # look for the special 'rel_X.X' tag # for tag in tags: # if tag.startswith('rel_') and len(tag) > 4: # main_version = tag[4:] # break # # handle untagged version e.g. tip # if not main_version: # main_version = short(node) # else: # main_version = '%s' % \ # '+'.join([short(p.node()) for p in parents]) suffix_changed = repo_changed and '+' or '' suffix_edition = hasattr(sys, 'frozen') \ and ' (standalone edition)' \ or '' ver = "%s%s%s" % (main_version, suffix_changed, suffix_edition) return ver version = _get_version() """\ wxGlade version string @see: L{_get_version()} """ py_version = sys.version.split()[0] """\ Python version """ platform = None """\ Current platform (mostly wx.Platform) """ wxglade_path = '.' """\ Program path, set in wxglade.py """ docs_path = 'docs' """\ Path to wxGlade documentation (e.g. html tuturial, license.txt, credits.txt) @note: This path will be set during initialisation """ icons_path = 'icons' """\ Path to wxGlade icons @note: This path will be set during initialisation """ templates_path = 'templates' """\ Path to wxGlade templates @note: This path will be set during initialisation """ widgets_path = 'widgets' """\ Path to wxGlade "built-in" widgets @note: This path will be set during initialisation """ credits_file = None """\ Path of the credits file "credits.txt" """ license_file = None """\ Path of the license file "license.txt" """ tutorial_file = 'docs/html/index.html' """\ Path to wxGlade tutorial (HTML) @note: This path will be set during initialisation """ widgets = {} """\ Widgets dictionary: each key is the name of some EditWidget class; the mapped value is a 'factory' function which actually builds the object. Each of these functions accept 3 parameters: the parent of the widget, the sizer by which such widget is controlled, and the position inside this sizer. """ widgets_from_xml = {} """\ Widgets_from_xml dictionary: table of factory functions to build objects from an xml file """ property_panel = None """\ property_panel wxPanel: container inside which Properties of the current focused widget are displayed """ app_tree = None """\ app_tree Tree: represents the widget hierarchy of the application; the root is the application itself """ adding_widget = False """\ If True, the user is adding a widget to some sizer """ adding_sizer = False """\ Needed to add toplevel sizers """ widget_to_add = None """\ Reference to the widget that is being added: this is a key in the 'widgets' dictionary """ palette = None """\ Reference to the main window (the one which contains the various buttons to add the different widgets) """ refs = {} """\ Dictionary which maps the ids used in the event handlers to the corresponding widgets: used to call the appropriate builder function when a dropping of a widget occurs, knowing only the id of the event """ class_names = {} """\ Dictionary which maps the name of the classes used by wxGlade to the correspondent classes of wxWindows """ toplevels = {} """\ Names of the Edit* classes that can be toplevels, i.e. widgets for which to generate a class declaration in the code """ code_writers = {} """\ Dictionary of objects used to generate the code in a given language. @note: A code writer object must implement this interface: - initialize(out_path, multi_files) - language - setup - add_widget_handler(widget_name, handler[, properties_handler]) - add_property_handler(property_name, handler[, widget_name]) - add_object(top_obj, sub_obj) - add_class(obj) - add_sizeritem(toplevel, sizer, obj_name, option, flag, border) - add_app(app_attrs, top_win_class) - ... """ def load_code_writers(): """\ Fills the common.code_writers dictionary: to do so, loads the modules found in the 'codegen/' subdir """ codegen_path = os.path.join(wxglade_path, 'codegen') sys.path.insert(0, codegen_path) for module in os.listdir(codegen_path): name, ext = os.path.splitext(module) # skip __init__ if name == "__init__": continue # allow regular files only if not os.path.isfile(os.path.join(codegen_path, module)): continue # ignore none python files if ext not in ['.py', '.pyo', '.pyc']: continue # skip already imported modules if name in sys.modules: continue # import file and initiate code writer try: writer = __import__(name).writer except (AttributeError, ImportError, NameError, SyntaxError, ValueError): message.exception( _('"%s" is not a valid code generator module') % module ) else: code_writers[writer.language] = writer if hasattr(writer, 'setup'): writer.setup() if use_gui: print _('loaded code generator for %s') % writer.language def load_widgets(): """\ Scans the 'widgets/' directory to find the installed widgets, and returns 2 lists of buttons to handle them: the first contains the ``core'' components, the second the user-defined ones """ import config buttons = [] # load the "built-in" widgets buttons.extend(__load_widgets(widgets_path)) # load the "local" widgets local_widgets_dir = config.preferences.local_widget_path return buttons, __load_widgets(local_widgets_dir) def __load_widgets(widget_dir): buttons = [] # test if the "widgets.txt" file exists widgets_file = os.path.join(widget_dir, 'widgets.txt') if not os.path.isfile(widgets_file): return buttons # add the dir to the sys.path sys.path.append(widget_dir) modules = open(widgets_file) if use_gui: print _('Found widgets listing -> %s') % widgets_file print _('loading widget modules:') for line in modules: module = line.strip() if not module or module.startswith('#'): continue module = module.split('#')[0].strip() try: try: b = __import__(module).initialize() except ImportError: # try importing from a zip archive if os.path.exists(os.path.join(widget_dir, module + '.zip')): sys.path.append(os.path.join(widget_dir, module + '.zip')) try: b = __import__(module).initialize() finally: sys.path.pop() else: raise except (AttributeError, ImportError, NameError, SyntaxError, ValueError): message.exception(_('ERROR loading "%s"') % module) else: if use_gui: print '\t' + module buttons.append(b) modules.close() return buttons def load_sizers(): import edit_sizers return edit_sizers.init_all() def add_object(event): """\ Adds a widget or a sizer to the current app. """ global adding_widget, adding_sizer, widget_to_add adding_widget = True adding_sizer = False tmp = event.GetId() widget_to_add = refs[tmp] # TODO: find a better way if widget_to_add.find('Sizer') != -1: adding_sizer = True def add_toplevel_object(event): """\ Adds a toplevel widget (Frame or Dialog) to the current app. """ widgets[refs[event.GetId()]](None, None, 0) app_tree.app.saved = False def make_object_button(widget, icon_path, toplevel=False, tip=None): """\ Creates a button for the widgets toolbar. Function used by the various widget modules to add a button to the widgets toolbar. @param widget: (name of) the widget the button will add to the app @param icon_path: path to the icon used for the button @param toplevel: true if the widget is a toplevel object (frame, dialog) @param tip: tool tip to display @return: The newly created wxBitmapButton """ import wx from tree import WidgetTree id = wx.NewId() if not os.path.isabs(icon_path): icon_path = os.path.join(wxglade_path, icon_path) if wx.Platform == '__WXGTK__': style = wx.NO_BORDER else: style = wx.BU_AUTODRAW import misc bmp = misc.get_xpm_bitmap(icon_path) tmp = wx.BitmapButton(palette, id, bmp, size=(31, 31), style=style) if not toplevel: wx.EVT_BUTTON(tmp, id, add_object) else: wx.EVT_BUTTON(tmp, id, add_toplevel_object) refs[id] = widget if not tip: tip = _('Add a %s') % widget.replace(_('Edit'), '') tmp.SetToolTip(wx.ToolTip(tip)) WidgetTree.images[widget] = icon_path # add support for ESC key. We bind the handler to the button, because # (at least on GTK) EVT_CHAR are not generated for wxFrame objects... def on_char(event): #print 'on_char' if event.HasModifiers() or event.GetKeyCode() != wx.WXK_ESCAPE: event.Skip() return global adding_widget, adding_sizer, widget_to_add adding_widget = False adding_sizer = False widget_to_add = None import misc if misc._currently_under_mouse is not None: misc._currently_under_mouse.SetCursor(wx.STANDARD_CURSOR) event.Skip() wx.EVT_CHAR(tmp, on_char) return tmp def exceptionHandler(exc_type, exc_value, exc_tb): """\ Logs detailed information about uncatched exceptions @param exc_type: Type of the exception (normally a class object) @param exc_value: The "value" of the exception @param exc_tb: Call stack of the exception """ try: tb = exc_tb while tb.tb_next: tb = tb.tb_next frame_locals = tb.tb_frame.f_locals # log exception details message.error(_('An unexpected error occurs!')) message.error(_('Error type: %s'), exc_type) message.error(_('Error details: %s'), exc_value) message.error(_('Stack Trace:')) lines = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb)).split('\n') for line in lines: if not line: continue message.error(line) message.error(_('Local variables of the last stack entry:')) for varname in frame_locals.keys(): # convert variablen name and value to ascii var = frame_locals[varname] vartype = type(var) if vartype == types.UnicodeType: varvalue = frame_locals[varname] varvalue = varvalue.encode('unicode_escape') else: varvalue = pprint.pformat(frame_locals[varname]) varvalue = varvalue message.error(_('%s (%s): %s'), varname, vartype, varvalue) # delete local references of tracebacks or part of tracebacks # to avoid cirular references finally: del tb del frame_locals def _encode_from_xml(label, encoding=None): """\ Returns a str which is the encoded version of the unicode label """ if encoding is None: encoding = app_tree.app.encoding return label.encode(encoding, 'replace') def _encode_to_xml(label, encoding=None): """\ returns a utf-8 encoded representation of label. This is equivalent to: str(label).decode(encoding).encode('utf-8') """ if encoding is None: encoding = app_tree.app.encoding if type(label) == type(u''): return label.encode('utf-8') return str(label).decode(encoding).encode('utf-8') _backed_up = {} """\ Set of filenames already backed up during this session """ def save_file(filename, content, which='wxg'): """\ Save I{content} to file named I{filename} and, if user's preferences say so and I{filename} exists, makes a backup copy of it. @note: Exceptions that may occur while performing the operations are not handled. @param filename: Name of the file to create @param content: String to store into 'filename' @param which: Kind of backup: 'wxg' or 'codegen' """ import config if which == 'wxg': do_backup = config.preferences.wxg_backup elif which == 'codegen': do_backup = config.preferences.codegen_backup else: raise NotImplementedError( 'Unknown value "%s" for parameter "which"!' % which ) try: if do_backup and \ filename not in _backed_up and \ os.path.isfile(filename): # make a backup copy of filename infile = open(filename) outfile = open(filename + config.preferences.backup_suffix, 'w') outfile.write(infile.read()) infile.close() outfile.close() _backed_up[filename] = True # save content to file (but only if content has changed) savecontent = True if os.path.isfile(filename): oldfile = open(filename) savecontent = (oldfile.read() != content) oldfile.close() if savecontent: directory = os.path.dirname(filename) if directory and not os.path.isdir(directory): os.makedirs(directory) outfile = open(filename, 'w') outfile.write(content) outfile.close() finally: if 'infile' in locals(): infile.close() if 'outfile' in locals(): outfile.close() if 'oldfile' in locals(): oldfile.close() #------------------------------------------------------------------------------ # Autosaving, added 2004-10-15 #------------------------------------------------------------------------------ def get_name_for_autosave(filename=None): if filename is None: filename = app_tree.app.filename if not filename: import config path, name = config._get_home(), "" else: path, name = os.path.split(filename) ret = os.path.join(path, "#~wxg.autosave~%s#" % name) return ret def autosave_current(): if app_tree.app.saved: return False # do nothing in this case... try: outfile = open(get_name_for_autosave(), 'w') app_tree.write(outfile) outfile.close() except Exception, e: print e return False return True def remove_autosaved(filename=None): autosaved = get_name_for_autosave(filename) if os.path.exists(autosaved): try: os.unlink(autosaved) except OSError, e: print e def check_autosaved(filename): """\ Returns True iff there are some auto saved data for filename """ if filename is not None and filename == app_tree.app.filename: # this happens when reloading, no autosave-restoring in this case... return False autosaved = get_name_for_autosave(filename) try: if filename: orig = os.stat(filename) auto = os.stat(autosaved) return orig.st_mtime < auto.st_mtime else: return os.path.exists(autosaved) except OSError, e: if e.errno != 2: print e return False def restore_from_autosaved(filename): autosaved = get_name_for_autosave(filename) # when restoring, make a backup copy (if user's preferences say so...) if os.access(autosaved, os.R_OK): try: save_file(filename, open(autosaved).read(), 'wxg') except OSError, e: print e return False return True return False def generated_from(): import config if config.preferences.write_generated_from and app_tree and \ app_tree.app.filename: return ' from "' + app_tree.app.filename + '"' return "" class MessageLogger(object): """\ Small own logging facility @ivar disabled: If True log messages won't be processed @type disabled: Boolean @ivar lines: Message buffer @type lines: List of strings @ivar logger: Reference to an instance of L{msgdialog.MessageDialog} """ def __init__(self): self.disabled = False self.lines = [] self.logger = None def _setup_logger(self): """\ Create L{msgdialog.MessageDialog} instance. """ import msgdialog self.logger = msgdialog.MessageDialog(None, -1, "") self.logger.msg_list.InsertColumn(0, "") def __call__(self, kind, fmt, *args): if self.disabled: return kind = kind.upper() if use_gui: import misc if args: msg = misc.wxstr(fmt) % tuple([misc.wxstr(a) for a in args]) else: msg = misc.wxstr(fmt) self.lines.extend(msg.splitlines()) # show errors and exceptions always at console if not use_gui or kind in [_("EXCEPTION"), _("ERROR")]: if args: msg = fmt % tuple(args) else: msg = fmt print "%s: %s" % (kind, msg) def debug(self, fmt, *args): """\ Show debug messages """ self.__call__(_("DEBUG"), fmt, *args) def info(self, fmt, *args): """\ Show informational messages """ self.__call__(_("INFO"), fmt, *args) def warn(self, fmt, *args): """\ Show warning messages """ self.__call__(_("WARNING"), fmt, *args) def error(self, fmt, *args): """\ Show error messages """ self.__call__(_("ERROR"), fmt, *args) def exception(self, fmt, *args): """\ Show exception details """ self.__call__(_("EXCEPTION"), fmt, *args) if not sys.exc_info()[0]: return exceptionHandler(*sys.exc_info()) sys.exc_clear() def flush(self): """\ Show log messages if L{use_gui} is True """ if self.lines and use_gui: if not self.logger: self._setup_logger() self.logger.msg_list.Freeze() self.logger.msg_list.DeleteAllItems() for line in self.lines: self.logger.msg_list.Append([line]) self.lines = [] self.logger.msg_list.SetColumnWidth(0, -1) self.logger.msg_list.Thaw() self.logger.ShowModal() # end of class MessageLogger message = MessageLogger() """\ L{MessageLogger} instance """ wxglade-0.6.8.orig/color_dialog.py0000644000175000017500000001011111621715605017322 0ustar georgeskgeorgesk# generated by wxGlade 0.2 on Sat Dec 7 14:30:59 2002 # $Id: color_dialog.py,v 1.11 2007/01/27 19:59:29 dinogen Exp $ import wx from wx.lib.colourchooser import PyColourChooser import misc class wxGladeColorDialog(wx.Dialog): def __init__(self, colors_dict): wx.Dialog.__init__(self, None, -1, "") self.colors_dict = colors_dict choices = self.colors_dict.keys() choices.sort() # begin wxGlade: wxGladeColorDialog.__init__ self.panel_1 = wx.Panel(self, -1) self.use_sys_color = wx.RadioButton(self.panel_1, -1, _("System colour"), style=wx.RB_SINGLE) self.sys_color = wx.ComboBox(self.panel_1, -1, choices=choices, style=wx.CB_DROPDOWN|wx.CB_READONLY) self.use_chooser = wx.RadioButton(self.panel_1, -1, _("Custom colour"), style=wx.RB_SINGLE) self.color_chooser = PyColourChooser(self, -1) self.ok = wx.Button(self, wx.ID_OK, _("OK")) self.cancel = wx.Button(self, wx.ID_CANCEL, _("Cancel")) self.__set_properties() self.__do_layout() # end wxGlade wx.EVT_RADIOBUTTON(self, self.use_sys_color.GetId(), self.on_use_sys_color) wx.EVT_RADIOBUTTON(self, self.use_chooser.GetId(), self.on_use_chooser) def on_use_sys_color(self, event): self.sys_color.Enable(True) self.color_chooser.Enable(False) self.use_chooser.SetValue(0) def on_use_chooser(self, event): self.sys_color.Enable(False) self.color_chooser.Enable(True) self.use_sys_color.SetValue(0) def get_value(self): if self.use_sys_color.GetValue(): return self.sys_color.GetStringSelection() else: return misc.color_to_string(self.color_chooser.GetValue()) def set_value(self, value): value = value.strip() if value in self.colors_dict: self.use_sys_color.SetValue(1) self.use_chooser.SetValue(0) self.sys_color.SetValue(value) self.sys_color.Enable(True) self.color_chooser.Enable(False) else: self.use_chooser.SetValue(1) self.use_sys_color.SetValue(0) try: self.color_chooser.SetValue(misc.string_to_color(value)) except: pass self.sys_color.Enable(False) self.color_chooser.Enable(True) def __set_properties(self): # begin wxGlade: wxGladeColorDialog.__set_properties self.SetTitle(_("Select widget colour")) self.use_sys_color.SetValue(1) self.sys_color.SetSelection(0) self.ok.SetDefault() # end wxGlade self.use_chooser.SetValue(0) self.color_chooser.Enable(False) def __do_layout(self): # begin wxGlade: wxGladeColorDialog.__do_layout sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_3 = wx.BoxSizer(wx.HORIZONTAL) sizer_2 = wx.BoxSizer(wx.VERTICAL) sizer_2.Add(self.use_sys_color, 0, wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5) sizer_2.Add(self.sys_color, 0, wx.ALL|wx.EXPAND, 5) static_line_1 = wx.StaticLine(self.panel_1, -1) sizer_2.Add(static_line_1, 0, wx.ALL|wx.EXPAND, 5) sizer_2.Add(self.use_chooser, 0, wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5) self.panel_1.SetAutoLayout(1) self.panel_1.SetSizer(sizer_2) sizer_2.Fit(self.panel_1) sizer_2.SetSizeHints(self.panel_1) sizer_1.Add(self.panel_1, 0, wx.EXPAND, 0) sizer_1.Add(self.color_chooser, 0, wx.ALL, 5) static_line_1_copy = wx.StaticLine(self, -1) sizer_1.Add(static_line_1_copy, 0, wx.ALL|wx.EXPAND, 5) sizer_3.Add(self.ok, 0, wx.RIGHT, 13) sizer_3.Add(self.cancel, 0, 0, 5) sizer_1.Add(sizer_3, 0, wx.ALL|wx.ALIGN_RIGHT, 10) self.SetAutoLayout(1) self.SetSizer(sizer_1) sizer_1.Fit(self) sizer_1.SetSizeHints(self) self.Layout() # end wxGlade self.CenterOnScreen() # end of class wxGladeColorDialog wxglade-0.6.8.orig/main.py0000644000175000017500000011463012167336636015635 0ustar georgeskgeorgesk""" Main wxGlade module: defines wxGladeFrame which contains the buttons to add widgets and initializes all the stuff (tree, property_frame, etc.) @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import general python modules import os import os.path import sys import wx # import project modules from widget_properties import * from tree import WidgetTree import common import application import misc import config import configdialog import clipboard import template class wxGladePropertyPanel(wx.Panel): """\ Panel used to display the Properties of the various widgets """ def SetTitle(self, title): try: self.GetParent().SetTitle(title) except AttributeError: pass def Layout(self): if self.is_visible(): wx.Panel.Layout(self) self.GetParent().Layout() def is_visible(self): return self.GetParent().IsShown() # end of class wxGladePropertyPanel TOGGLE_BOX_EVENT = wx.NewEventType() def EVT_TOGGLE_BOX(win, id, func): win.Connect(id, -1, TOGGLE_BOX_EVENT, func) class ToggleBoxEvent(wx.PyCommandEvent): def __init__(self, id, value, strval): wx.PyCommandEvent.__init__(self) self.SetId(id) self.SetEventType(TOGGLE_BOX_EVENT) self.value = value self.strval = strval def GetValue(self): return self.value def GetStringValue(self): return self.strval # end of class ToggleBoxEvent class ToggleButtonBox(wx.Panel): def __init__(self, parent, id, choices=None, value=0): wx.Panel.__init__(self, parent, id) if choices is None: choices = [] self.buttons = [wx.ToggleButton(self, -1, c) for c in choices] self.selected = None self.SetValue(value) for b in self.buttons: def handler(event, b=b): self.on_toggle(b, event) wx.EVT_TOGGLEBUTTON(self, b.GetId(), handler) sizer = wx.BoxSizer(wx.VERTICAL) for b in self.buttons: sizer.Add(b, 0, wx.ALL|wx.EXPAND, 1) self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) sizer.SetSizeHints(self) def on_toggle(self, button, event): if self.selected is button: self.selected.SetValue(True) return if self.selected is not None: self.selected.SetValue(False) self.selected = button wx.PostEvent(self, ToggleBoxEvent(self.GetId(), self.GetValue(), self.GetStringValue())) def GetValue(self): if self.selected is not None: return self.buttons.index(self.selected) return -1 def GetStringValue(self): if self.selected is None: return None return self.selected.GetLabel() def SetValue(self, index): if self.selected is not None: self.selected.SetValue(False) if -1 < index < len(self.buttons): self.selected = self.buttons[index] self.selected.SetValue(True) def SetStringValue(self, strval): index = -1 for i in range(len(self.buttons)): if self.buttons[i].GetLabel() == strval: index = i break self.SetValue(index) # end of class ToggleButtonBox class wxGladeArtProvider(wx.ArtProvider): def CreateBitmap(self, artid, client, size): if wx.Platform == '__WXGTK__' and artid == wx.ART_FOLDER: return wx.Bitmap(os.path.join(common.icons_path, 'closed_folder.xpm'), wx.BITMAP_TYPE_XPM) return wx.NullBitmap # end of class wxGladeArtProvider class wxGladeFrame(wx.Frame): """\ Main frame of wxGlade (palette) @ivar cur_dir: Last visited directory, used for wxFileDialog and not for KDE dialogs @type cur_dir: String """ def __init__(self, parent=None): style = wx.SYSTEM_MENU|wx.CAPTION|wx.MINIMIZE_BOX|wx.RESIZE_BORDER style |= wx.CLOSE_BOX wx.Frame.__init__(self, parent, -1, "wxGlade v%s" % common.version, style=style) self.CreateStatusBar(1) if parent is None: parent = self common.palette = self # to provide a reference accessible # by the various widget classes icon = wx.EmptyIcon() bmp = wx.Bitmap( os.path.join(common.icons_path, "icon.xpm"), wx.BITMAP_TYPE_XPM ) icon.CopyFromBitmap(bmp) self.SetIcon(icon) self.SetBackgroundColour(wx.SystemSettings_GetColour( wx.SYS_COLOUR_BTNFACE)) menu_bar = wx.MenuBar() file_menu = wx.Menu(style=wx.MENU_TEAROFF) view_menu = wx.Menu(style=wx.MENU_TEAROFF) help_menu = wx.Menu(style=wx.MENU_TEAROFF) wx.ToolTip_SetDelay(1000) # load the available code generators common.load_code_writers() # load the available widgets and sizers core_btns, custom_btns = common.load_widgets() sizer_btns = common.load_sizers() append_item = misc.append_item self.TREE_ID = TREE_ID = wx.NewId() append_item(view_menu, TREE_ID, _("Show &Tree\tF2")) self.PROPS_ID = PROPS_ID = wx.NewId() self.RAISE_ID = RAISE_ID = wx.NewId() append_item(view_menu, PROPS_ID, _("Show &Properties\tF3")) append_item(view_menu, RAISE_ID, _("&Raise All\tF4")) NEW_ID = wx.NewId() append_item(file_menu, NEW_ID, _("&New\tCtrl+N"), wx.ART_NEW) NEW_FROM_TEMPLATE_ID = wx.NewId() append_item(file_menu, NEW_FROM_TEMPLATE_ID, _("New from &Template...\tShift+Ctrl+N")) OPEN_ID = wx.NewId() append_item(file_menu, OPEN_ID, _("&Open...\tCtrl+O"), wx.ART_FILE_OPEN) SAVE_ID = wx.NewId() append_item(file_menu, SAVE_ID, _("&Save\tCtrl+S"), wx.ART_FILE_SAVE) SAVE_AS_ID = wx.NewId() append_item(file_menu, SAVE_AS_ID, _("Save As...\tShift+Ctrl+S"), wx.ART_FILE_SAVE_AS) SAVE_TEMPLATE_ID = wx.NewId() append_item(file_menu, SAVE_TEMPLATE_ID, _("Save As Template...")) file_menu.AppendSeparator() RELOAD_ID = wx.ID_REFRESH #wx.NewId() append_item(file_menu, RELOAD_ID, _("&Refresh\tf5")) #, wx.ART_REDO) GENERATE_CODE_ID = wx.NewId() append_item(file_menu, GENERATE_CODE_ID, _("&Generate Code\tCtrl+G"), wx.ART_EXECUTABLE_FILE) file_menu.AppendSeparator() IMPORT_ID = wx.NewId() append_item(file_menu, IMPORT_ID, _("&Import from XRC...\tCtrl+I")) EXIT_ID = wx.NewId() file_menu.AppendSeparator() append_item(file_menu, EXIT_ID, _('E&xit\tCtrl+Q'), wx.ART_QUIT) PREFS_ID = wx.ID_PREFERENCES #NewId() view_menu.AppendSeparator() MANAGE_TEMPLATES_ID = wx.NewId() append_item(view_menu, MANAGE_TEMPLATES_ID, _('Templates Manager...')) view_menu.AppendSeparator() append_item(view_menu, PREFS_ID, _('Preferences...')) #wx.ART_HELP_SETTINGS) menu_bar.Append(file_menu, _("&File")) menu_bar.Append(view_menu, _("&View")) TUT_ID = wx.NewId() append_item(help_menu, TUT_ID, _('Contents\tF1'), wx.ART_HELP) ABOUT_ID = wx.ID_ABOUT #wx.NewId() append_item(help_menu, ABOUT_ID, _('About...'))#, wx.ART_QUESTION) menu_bar.Append(help_menu, _('&Help')) parent.SetMenuBar(menu_bar) # Mac tweaks... if wx.Platform == "__WXMAC__": wx.App_SetMacAboutMenuItemId(ABOUT_ID) wx.App_SetMacPreferencesMenuItemId(PREFS_ID) wx.App_SetMacExitMenuItemId(EXIT_ID) wx.App_SetMacHelpMenuTitleName(_('&Help')) # file history support self.file_history = wx.FileHistory( config.preferences.number_history) self.file_history.UseMenu(file_menu) files = config.load_history() files.reverse() for path in files: self.file_history.AddFileToHistory(path.strip()) def open_from_history(event): if not self.ask_save(): return infile = self.file_history.GetHistoryFile( event.GetId() - wx.ID_FILE1) # ALB 2004-10-15 try to restore possible autosave content... if common.check_autosaved(infile) and \ wx.MessageBox(_("There seems to be auto saved data for " "this file: do you want to restore it?"), _("Auto save detected"), style=wx.ICON_QUESTION|wx.YES_NO) == wx.YES: common.restore_from_autosaved(infile) else: common.remove_autosaved(infile) self._open_app(infile) wx.EVT_MENU_RANGE(self, wx.ID_FILE1, wx.ID_FILE9, open_from_history) wx.EVT_MENU(self, TREE_ID, self.show_tree) wx.EVT_MENU(self, PROPS_ID, self.show_props_window) wx.EVT_MENU(self, RAISE_ID, self.raise_all) wx.EVT_MENU(self, NEW_ID, self.new_app) wx.EVT_MENU(self, NEW_FROM_TEMPLATE_ID, self.new_app_from_template) wx.EVT_MENU(self, OPEN_ID, self.open_app) wx.EVT_MENU(self, SAVE_ID, self.save_app) wx.EVT_MENU(self, SAVE_AS_ID, self.save_app_as) wx.EVT_MENU(self, SAVE_TEMPLATE_ID, self.save_app_as_template) def generate_code(event): common.app_tree.app.generate_code() wx.EVT_MENU(self, GENERATE_CODE_ID, generate_code) wx.EVT_MENU(self, EXIT_ID, lambda e: self.Close()) wx.EVT_MENU(self, TUT_ID, self.show_tutorial) wx.EVT_MENU(self, ABOUT_ID, self.show_about_box) wx.EVT_MENU(self, PREFS_ID, self.edit_preferences) wx.EVT_MENU(self, MANAGE_TEMPLATES_ID, self.manage_templates) wx.EVT_MENU(self, IMPORT_ID, self.import_xrc) wx.EVT_MENU(self, RELOAD_ID, self.reload_app) PREVIEW_ID = wx.NewId() wx.EVT_MENU(self, PREVIEW_ID, self.preview) self.accel_table = wx.AcceleratorTable([ (wx.ACCEL_CTRL, ord('N'), NEW_ID), (wx.ACCEL_CTRL, ord('O'), OPEN_ID), (wx.ACCEL_CTRL, ord('S'), SAVE_ID), (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('S'), SAVE_AS_ID), (wx.ACCEL_CTRL, ord('G'), GENERATE_CODE_ID), (wx.ACCEL_CTRL, ord('I'), IMPORT_ID), (0, wx.WXK_F1, TUT_ID), (wx.ACCEL_CTRL, ord('Q'), EXIT_ID), (0, wx.WXK_F5, RELOAD_ID), (0, wx.WXK_F2, TREE_ID), (0, wx.WXK_F3, PROPS_ID), (0, wx.WXK_F4, RAISE_ID), (wx.ACCEL_CTRL, ord('P'), PREVIEW_ID), ]) # Tutorial window ## self.tut_frame = None # layout # if there are custom components, add the toggle box... if custom_btns: main_sizer = wx.BoxSizer(wx.VERTICAL) show_core_custom = ToggleButtonBox( self, -1, [_("Core components"), _("Custom components")], 0) core_sizer = wx.FlexGridSizer( 0, config.preferences.buttons_per_row ) custom_sizer = wx.FlexGridSizer( 0, config.preferences.buttons_per_row ) self.SetAutoLayout(True) # core components for b in core_btns: core_sizer.Add(b) for sb in sizer_btns: core_sizer.Add(sb) # custom components for b in custom_btns: custom_sizer.Add(b) custom_sizer.Show(b, False) custom_sizer.Layout() main_sizer.Add(show_core_custom, 0, wx.EXPAND) main_sizer.Add(core_sizer, 0, wx.EXPAND) main_sizer.Add(custom_sizer, 0, wx.EXPAND) self.SetSizer(main_sizer) #main_sizer.Show(1, False) main_sizer.Fit(self) # events to display core/custom components def on_show_core_custom(event): show_core = True show_custom = False if event.GetValue() == 1: show_core = False show_custom = True for b in custom_btns: custom_sizer.Show(b, show_custom) for b in core_btns: core_sizer.Show(b, show_core) for b in sizer_btns: core_sizer.Show(b, show_core) core_sizer.Layout() custom_sizer.Layout() main_sizer.Layout() EVT_TOGGLE_BOX(self, show_core_custom.GetId(), on_show_core_custom) # ... otherwise (the common case), just add the palette of core buttons else: sizer = wx.GridSizer(0, config.preferences.buttons_per_row) self.SetAutoLayout(True) # core components for b in core_btns: sizer.Add(b) for sb in sizer_btns: sizer.Add(sb) self.SetSizer(sizer) sizer.Fit(self) # Properties window frame_style = wx.DEFAULT_FRAME_STYLE frame_tool_win = config.preferences.frame_tool_win if frame_tool_win: frame_style |= wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT frame_style &= ~wx.MINIMIZE_BOX if wx.Platform != '__WXGTK__': frame_style |= wx.FRAME_TOOL_WINDOW self.frame2 = wx.Frame(self, -1, _('Properties - '), style=frame_style) self.frame2.SetBackgroundColour(wx.SystemSettings_GetColour( wx.SYS_COLOUR_BTNFACE)) self.frame2.SetIcon(icon) sizer_tmp = wx.BoxSizer(wx.VERTICAL) property_panel = wxGladePropertyPanel(self.frame2, -1) #---- 2003-06-22 Fix for what seems to be a GTK2 bug (notebooks) misc.hidden_property_panel = wx.Panel(self.frame2, -1) sz = wx.BoxSizer(wx.VERTICAL) sz.Add(property_panel, 1, wx.EXPAND) sz.Add(misc.hidden_property_panel, 1, wx.EXPAND) self.frame2.SetSizer(sz) sz.Show(misc.hidden_property_panel, False) self.property_frame = self.frame2 #-------------------------------------------------------- property_panel.SetAutoLayout(True) self.hidden_frame = wx.Frame(self, -1, "") self.hidden_frame.Hide() sizer_tmp.Add(property_panel, 1, wx.EXPAND) self.frame2.SetAutoLayout(True) self.frame2.SetSizer(sizer_tmp) sizer_tmp = wx.BoxSizer(wx.VERTICAL) def hide_frame2(event): #menu_bar.Check(PROPS_ID, False) self.frame2.Hide() wx.EVT_CLOSE(self.frame2, hide_frame2) wx.EVT_CLOSE(self, self.cleanup) common.property_panel = property_panel # Tree of widgets self.tree_frame = wx.Frame(self, -1, _('wxGlade: Tree'), style=frame_style) self.tree_frame.SetIcon(icon) app = application.Application(common.property_panel) common.app_tree = WidgetTree(self.tree_frame, app) self.tree_frame.SetSize((300, 300)) app.notebook.Show() sizer_tmp.Add(app.notebook, 1, wx.EXPAND) property_panel.SetSizer(sizer_tmp) sizer_tmp.Fit(property_panel) def on_tree_frame_close(event): #menu_bar.Check(TREE_ID, False) self.tree_frame.Hide() wx.EVT_CLOSE(self.tree_frame, on_tree_frame_close) # check to see if there are some remembered values prefs = config.preferences if prefs.remember_geometry: #print 'initializing geometry' try: x, y, w, h = prefs.get_geometry('main') misc.set_geometry(self, (x, y)) except Exception, e: pass misc.set_geometry(self.frame2, prefs.get_geometry('properties')) misc.set_geometry(self.tree_frame, prefs.get_geometry('tree')) else: if wx.Platform == '__WXMAC__': self.frame2.SetSize((345, 384)) # I've been told this is OK... self.SetPosition((0, 45)) # to avoid the OS X menubar else: self.frame2.SetSize((max(self.GetSize()[0], 250), 350)) self.SetPosition((0, 0)) x, y = self.GetPosition() h = self.GetSize()[1] w = self.frame2.GetSize()[0] if wx.Platform != '__WXMSW__': # under X, IceWM (and Sawfish, too), GetSize seems to ignore # window decorations h += 60 w += 10 self.frame2.SetPosition((x, y+h)) self.tree_frame.SetPosition((x+w, y)) self.Show() self.tree_frame.Show() self.frame2.Show() #self._skip_activate = False ## if frame_tool_win: ## def on_iconize(event): ## if event.Iconized(): ## self.hide_all() ## else: ## self.show_and_raise() ## event.Skip() ## wx.EVT_ICONIZE(self, on_iconize) if wx.Platform == '__WXMSW__': import about # I'll pay a beer to anyone who can explain to me why this prevents # a segfault on Win32 when you exit without doing anything!! self.about_box = about.wxGladeAboutBox(self.GetParent()) else: self.about_box = None # last visited directory, used on GTK for wxFileDialog self.cur_dir = config.preferences.open_save_path # set a drop target for us... self._droptarget = clipboard.FileDropTarget(self) self.SetDropTarget(self._droptarget) #self.tree_frame.SetDropTarget(self._droptarget) #self.frame2.SetDropTarget(self._droptarget) # ALB 2004-10-15, autosave support... self.autosave_timer = None if config.preferences.autosave: TIMER_ID = wx.NewId() self.autosave_timer = wx.Timer(self, TIMER_ID) wx.EVT_TIMER(self, TIMER_ID, self.on_autosave_timer) self.autosave_timer.Start( int(config.preferences.autosave_delay) * 1000) # ALB 2004-10-15 CLEAR_SB_TIMER_ID = wx.NewId() self.clear_sb_timer = wx.Timer(self, CLEAR_SB_TIMER_ID) wx.EVT_TIMER(self, CLEAR_SB_TIMER_ID, self.on_clear_sb_timer) self.frame2.SetAcceleratorTable(self.accel_table) self.tree_frame.SetAcceleratorTable(self.accel_table) self.Raise() # ALB 2004-10-16 if common.check_autosaved(None) and \ wx.MessageBox(_("There seems to be auto saved data " "from last wxGlade session: " "do you want to restore it?"), _("Auto save detected"), style=wx.ICON_QUESTION|wx.YES_NO) == wx.YES: if self._open_app(common.get_name_for_autosave(), add_to_history=False): common.app_tree.app.saved = False common.app_tree.app.filename = None self.user_message(_("Recovery from auto save complete")) common.remove_autosaved() else: common.remove_autosaved() def on_autosave_timer(self, event): if common.autosave_current(): self.user_message(_("Auto saving... done")) def edit_preferences(self, event): dialog = configdialog.wxGladePreferences(config.preferences) if dialog.ShowModal() == wx.ID_OK: wx.MessageBox(_('Changes will take effect after wxGlade is restarted'), _('Preferences saved'), wx.OK|wx.CENTRE|wx.ICON_INFORMATION) dialog.set_preferences() dialog.Destroy() def preview(self, event): """\ Generate preview of the current loaded project. A preview can be triggered by keyboard shortcut or by pressing the preview button. The preview can be triggered for all selected widgets. This doesn't mean that the widget is opened for editing. A good indicator for editing is the availability of the preview button. @see: L{edit_windows.PreviewMixin.preview_button} """ # Show preview only, if preview_button is available # if not getattr(common.app_tree.cur_widget, 'preview_button', None): return preview_widget = misc.get_toplevel_widget(common.app_tree.cur_widget) if preview_widget is not None: preview_widget.preview(None) def show_tree(self, event): self.tree_frame.Show() self.tree_frame.Raise() common.app_tree.SetFocus() def show_props_window(self, event): self.frame2.Show() self.frame2.Raise() try: c = self.frame2.GetSizer().GetChildren() if c: c[0].GetWindow().SetFocus() except (AttributeError, TypeError): self.frame2.SetFocus() def raise_all(self, event): children = self.GetChildren() for child in children: child = misc.get_toplevel_parent(child) if child.IsShown() and child.GetTitle(): child.Raise() self.Raise() def user_message(self, msg): sb = self.GetStatusBar() if sb: sb.SetStatusText(msg) self.clear_sb_timer.Start(5000, True) def on_clear_sb_timer(self, event): sb = self.GetStatusBar() if sb: sb.SetStatusText("") def ask_save(self): """\ checks whether the current app has changed and needs to be saved: if so, prompts the user; returns False if the operation has been cancelled """ if not common.app_tree.app.saved: ok = wx.MessageBox(_("Save changes to the current app?"), _("Confirm"), wx.YES_NO|wx.CANCEL|wx.CENTRE|wx.ICON_QUESTION) if ok == wx.YES: self.save_app(None) return ok != wx.CANCEL return True def new_app(self, event): """\ creates a new wxGlade project """ if self.ask_save(): common.app_tree.clear() common.app_tree.app.filename = None common.app_tree.app.saved = True self.user_message("") # ALB 2004-10-15 common.remove_autosaved() if config.preferences.autosave and self.autosave_timer is not None: self.autosave_timer.Start() def new_app_from_template(self, event): """\ creates a new wxGlade project from an existing template file """ if not self.ask_save(): return infile = template.select_template() if infile: self._open_app(infile, add_to_history=False) common.app_tree.app.template_data = None def reload_app(self, event): self.ask_save() if not common.app_tree.app.filename: wx.MessageBox(_("Impossible to reload an unsaved application"), _("Alert"), style=wx.OK|wx.ICON_INFORMATION) return path = common.app_tree.get_selected_path() #print 'path:', path self._open_app(common.app_tree.app.filename, add_to_history=False) common.app_tree.select_path(path) def open_app(self, event_unused): """\ loads a wxGlade project from an xml file NOTE: this is very slow and needs optimisation efforts NOTE2: the note above should not be True anymore :) """ if not self.ask_save(): return from xml_parse import XmlWidgetBuilder, ProgressXmlWidgetBuilder infile = misc.FileSelector(_("Open file"), wildcard="wxGlade files (*.wxg)|*.wxg|" "wxGlade Template files (*.wgt)|*.wgt|" "XML files (*.xml)|*.xml|All files|*", flags=wx.OPEN|wx.FILE_MUST_EXIST, default_path=self.cur_dir) if infile: # ALB 2004-10-15 try to restore possible autosave content... if common.check_autosaved(infile) and \ wx.MessageBox(_("There seems to be auto saved data for " "this file: do you want to restore it?"), _("Auto save detected"), style=wx.ICON_QUESTION|wx.YES_NO) == wx.YES: common.restore_from_autosaved(infile) else: common.remove_autosaved(infile) self._open_app(infile) self.cur_dir = os.path.dirname(infile) def _open_app(self, infilename, use_progress_dialog=True, is_filelike=False, add_to_history=True): import time from xml_parse import XmlWidgetBuilder, ProgressXmlWidgetBuilder, \ XmlParsingError from xml.sax import SAXParseException start = time.clock() common.app_tree.clear() if not is_filelike: common.app_tree.app.filename = infilename else: common.app_tree.filename = getattr(infilename, 'name', None) common.property_panel.Reparent(self.hidden_frame) # prevent the auto-expansion of nodes common.app_tree.auto_expand = False old_dir = os.getcwd() try: if not is_filelike: os.chdir(os.path.dirname(infilename)) infile = open(infilename) print _('Read wxGlade project from file "%s"') % infilename else: infile = infilename infilename = getattr(infile, 'name', None) print _('Read wxGlade project from file-like object') if use_progress_dialog and config.preferences.show_progress: p = ProgressXmlWidgetBuilder(input_file=infile) else: p = XmlWidgetBuilder() p.parse(infile) except (IOError, OSError, SAXParseException, XmlParsingError), msg: if locals().has_key('infile') and not is_filelike: infile.close() common.app_tree.clear() common.property_panel.Reparent(self.frame2) common.app_tree.app.saved = True wx.MessageBox(_("Error loading file %s: %s") % \ (misc.wxstr(infilename), misc.wxstr(msg)), _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR) # reset the auto-expansion of nodes common.app_tree.auto_expand = True os.chdir(old_dir) return False except Exception, msg: common.message.exception( _('An exception occurred while loading file "%s".') % \ infilename.encode('ascii', 'replace') ) if locals().has_key('infile') and not is_filelike: infile.close() common.app_tree.clear() common.property_panel.Reparent(self.frame2) common.app_tree.app.saved = True wx.MessageBox( _("An exception occurred while loading file \"%s\".\n" "This is the error message associated with it:\n" " %s\n" "For more details, look at the full traceback " "on the console.\n" "If you think this is a wxGlade bug," " please report it.") % \ (misc.wxstr(infilename), misc.wxstr(msg)), _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR ) # reset the auto-expansion of nodes common.app_tree.auto_expand = True os.chdir(old_dir) return False if not is_filelike: infile.close() common.app_tree.select_item(common.app_tree.root) common.app_tree.root.widget.show_properties() common.property_panel.Reparent(self.frame2) # reset the auto-expansion of nodes common.app_tree.auto_expand = True common.app_tree.expand() if common.app_tree.app.is_template: print _("Loaded template") common.app_tree.app.template_data = template.Template(infilename) common.app_tree.app.filename = None end = time.clock() print _('Loading time: %.5f') % (end-start) common.app_tree.app.saved = True if hasattr(self, 'file_history') and infilename is not None and \ add_to_history and (not common.app_tree.app.is_template): self.file_history.AddFileToHistory(misc.wxstr(infilename)) # ALB 2004-10-15 if config.preferences.autosave and self.autosave_timer is not None: self.autosave_timer.Start() self.user_message(_("Loaded %s (%.2f seconds)") % \ (misc.wxstr(common.app_tree.app.filename), end-start)) return True def save_app(self, event): """\ saves a wxGlade project onto an xml file """ if not common.app_tree.app.filename or \ common.app_tree.app.is_template: self.save_app_as(event) else: # check whether we are saving a template ext = os.path.splitext(common.app_tree.app.filename)[1].lower() if ext == ".wgt": common.app_tree.app.is_template = True self._save_app(common.app_tree.app.filename) def _save_app(self, filename): try: from cStringIO import StringIO buffer = StringIO() common.app_tree.write(buffer) common.save_file(filename, buffer.getvalue(), 'wxg') except (IOError, OSError), msg: common.app_tree.app.saved = False wx.MessageBox(_("Error saving app:\n%s") % msg, _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR) except Exception, msg: common.message.exception( _('An exception occurred while saving file "%s".') % \ filename.encode('ascii', 'replace') ) common.app_tree.app.saved = False wx.MessageBox(_("An exception occurred while saving file " "\"%s\".\n" "This is the error message associated with it:" "\n %s\n" "For more details, look at the full traceback " "on the console.\nIf you think this is a " "wxGlade bug," " please report it.") % (filename, msg), _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR ) else: common.app_tree.app.saved = True common.remove_autosaved() if config.preferences.autosave and \ self.autosave_timer is not None: self.autosave_timer.Start() self.user_message(_("Saved %s") % filename) def save_app_as(self, event): """\ saves a wxGlade project onto an xml file chosen by the user """ # wx.SAVE & wx.OVERWRITE_PROMPT are wx2.6 # both flags occurs several times fn = misc.FileSelector(_("Save project as..."), wildcard="wxGlade files (*.wxg)|*.wxg|" "wxGlade Template files (*.wgt) |*.wgt|" "XML files (*.xml)|*.xml|All files|*", flags=wx.SAVE|wx.OVERWRITE_PROMPT, default_path=self.cur_dir) if fn: # check for file extension and add default extension if missing ext = os.path.splitext(fn)[1].lower() if not ext: fn = "%s.wxg" % fn common.app_tree.app.filename = fn #remove the template flag so we can save the file. common.app_tree.app.is_template = False self.save_app(event) self.cur_dir = os.path.dirname(fn) self.file_history.AddFileToHistory(fn) def save_app_as_template(self, event): """\ save a wxGlade project as a template """ data = getattr(common.app_tree.app, 'template_data', None) outfile, data = template.save_template(data) if outfile: common.app_tree.app.is_template = True common.app_tree.app.template_data = data self._save_app(outfile) def cleanup(self, event): if self.ask_save(): # first, let's see if we have to save the geometry... prefs = config.preferences if prefs.remember_geometry: prefs.set_geometry('main', misc.get_geometry(self)) prefs.set_geometry('tree', misc.get_geometry(self.tree_frame)) prefs.set_geometry('properties', misc.get_geometry(self.frame2)) prefs.changed = True common.app_tree.clear() if self.about_box: self.about_box.Destroy() try: config.save_preferences() except Exception, e: wx.MessageBox(_('Error saving preferences:\n%s') % e, _('Error'), wx.OK|wx.CENTRE|wx.ICON_ERROR) #self._skip_activate = True self.frame2.Destroy() self.tree_frame.Destroy() self.Destroy() common.remove_autosaved() # ALB 2004-10-15 wx.CallAfter(wx.GetApp().ExitMainLoop) def show_about_box(self, event): """\ show the about dialog @see: L{about.wxGladeAboutBox} """ if self.about_box is None: import about self.about_box = about.wxGladeAboutBox(None) self.about_box.ShowModal() def show_tutorial(self, event): """\ show the wxGlade user manual """ if wx.Platform == "__WXMAC__": os.system('open -a Help\ Viewer.app %s' % common.tutorial_file) else: import webbrowser, threading # ALB 2004-08-15: why did this block the program????? # (at least on linux - GTK) def go(): webbrowser.open_new(common.tutorial_file) t = threading.Thread(target=go) t.setDaemon(True) t.start() def show_and_raise(self): self.frame2.Show()#self.GetMenuBar().IsChecked(self.PROPS_ID)) self.tree_frame.Show()#self.GetMenuBar().IsChecked(self.TREE_ID)) self.frame2.Raise() self.tree_frame.Raise() self.Raise() def hide_all(self): self.tree_frame.Hide() self.frame2.Hide() def import_xrc(self, event): import xrc2wxg, cStringIO if not self.ask_save(): return infilename = misc.FileSelector(_("Import file"), wildcard="XRC files (*.xrc)" "|*.xrc|All files|*", flags=wx.OPEN|wx.FILE_MUST_EXIST, default_path=self.cur_dir) if infilename: buf = cStringIO.StringIO() try: xrc2wxg.convert(infilename, buf) buf.seek(0) self._open_app(buf, is_filelike=True) common.app_tree.app.saved = False except Exception, msg: common.message.exception( _('An exception occurred while importing file "%s".') % \ infilename.encode('ascii', 'replace') ) wx.MessageBox( _("An exception occurred while importing file " "\"%s\".\nThis is the error message associated " "with it:\n %s\n" "For more details, look at the full traceback " "on the console.\nIf you think this is a " "wxGlade bug, please report it.") % \ (infilename, msg), _("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR ) def manage_templates(self, event): to_edit = template.manage_templates() if to_edit is not None and self.ask_save(): # edit the template # TODO, you still need to save it manually... self._open_app(to_edit, add_to_history=False) wx.MessageBox(_("To save the changes to the template, edit the " "GUI as usual,\nand then click " "File->Save as Template..."), _("Information"), style=wx.OK|wx.ICON_INFORMATION) # end of class wxGladeFrame class wxGlade(wx.App): def OnInit(self): sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ # needed for wx >= 2.3.4 to disable wxPyAssertionError exceptions self.SetAssertMode(0) wx.InitAllImageHandlers() config.init_preferences() # ALB 2004-10-27 if wx.Platform == '__WXGTK__' and config.preferences.use_kde_dialogs: import kdefiledialog if kdefiledialog.test_kde(): misc.FileSelector = kdefiledialog.kde_file_selector misc.DirSelector = kdefiledialog.kde_dir_selector wx.ArtProvider.PushProvider(wxGladeArtProvider()) frame = wxGladeFrame() ## if wx.Platform == '__WXMSW__': ## def on_activate(event): ## if event.GetActive() and not frame.IsIconized(): ## frame.show_and_raise() ## event.Skip() ## wx.EVT_ACTIVATE_APP(self, on_activate) self.SetTopWindow(frame) self.SetExitOnFrameDelete(True) wx.EVT_IDLE(self, self.on_idle) return True def on_idle(self, event): common.message.flush() event.Skip() # end of class wxGlade def main(filename=None): """\ if filename is not None, loads it """ print _("Using wxPython %s") % wx.__version__ # now, silence a deprecation warining for py2.3 import warnings warnings.filterwarnings("ignore", "integer", DeprecationWarning, "wxPython.gdi") app = wxGlade() if filename is not None: app.GetTopWindow()._open_app(filename, False) app.MainLoop() wxglade-0.6.8.orig/edit_sizers/0000755000175000017500000000000012170277707016653 5ustar georgeskgeorgeskwxglade-0.6.8.orig/edit_sizers/lisp_sizers_codegen.py0000644000175000017500000000576712150154266023266 0ustar georgeskgeorgesk""" Lisp generator functions for the various wxSizerS @copyright: 2002-2004 D.H. aka crazyinsomniac on sourceforge.net @copyright: 2013 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import common from edit_sizers import BaseSizerBuilder class BaseLispSizerBuilder(BaseSizerBuilder): """\ Lisp base class for all sizer code generators """ language = 'lisp' tmpl_SetSizer = '(wxWindow_SetSizer %(parent_widget)s ' \ '(%(sizer_name)s obj))\n' tmpl_Fit = '(wxSizer_Fit (%(sizer_name)s obj) %(parent_widget)s)\n' tmpl_SetSizeHints = '(wxSizer_SetSizeHints (slot-%(sizer_name)s obj) ' \ '%(parent_widget)s)\n' tmpl_wparent = '(slot-frame obj)' """\ Only in Lisp the widgets parent statement differs between C{slot-frame obj} and C{slot-top-window obj}. @todo: Clarify why the widget parent differs between different sizers in Lisp. @see: L{_get_wparent()} @type: String """ def _get_wparent(self, obj): if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = self.tmpl_wparent return parent # end of class BaseLispSizerBuilder class LispBoxSizerBuilder(BaseLispSizerBuilder): klass = 'wxBoxSizer' init_stmt = [ '(setf (%(sizer_name)s obj) (wxBoxSizer_Create %(orient)s))\n' ] tmpl_wparent = '(slot-top-window obj)' # end of class LispBoxSizerBuilder class LispStaticBoxSizerBuilder(BaseLispSizerBuilder): klass = 'wxStaticBoxSizer' init_stmt = [ '(setf (%(sizer_name)s obj) (StaticBoxSizer_Create ' '(wxStaticBox:wxStaticBox_Create %(parent_widget)s %(label)s) ' '%(orient)s))\n', ] # end of class LispStaticBoxSizerBuilder class LispGridSizerBuilder(BaseLispSizerBuilder): klass = 'wxGridSizer' init_stmt = [ '(setf (%(sizer_name)s obj) (wxGridSizer_Create %(rows)s ' '%(cols)s %(vgap)s %(hgap)s))\n', ] # end of class LispGridSizerBuilder class LispFlexGridSizerBuilder(LispGridSizerBuilder): klass = 'wxFlexGridSizer' tmpl_AddGrowableRow = '(wxFlexGridSizer_AddGrowableRow ' \ '(%(sizer_name)s obj) %(row)s)\n' tmpl_AddGrowableCol = '(wxFlexGridSizer_AddGrowableCol ' \ '(%(sizer_name)s obj) %(col)s)\n' # end of class LispFlexGridSizerBuilder def initialize(): cn = common.class_names cn['EditBoxSizer'] = 'wxBoxSizer' cn['EditStaticBoxSizer'] = 'wxStaticBoxSizer' cn['EditGridSizer'] = 'wxGridSizer' cn['EditFlexGridSizer'] = 'wxFlexGridSizer' lispgen = common.code_writers.get("lisp") if lispgen: awh = lispgen.add_widget_handler awh('wxBoxSizer', LispBoxSizerBuilder()) awh('wxStaticBoxSizer', LispStaticBoxSizerBuilder()) awh('wxGridSizer', LispGridSizerBuilder()) awh('wxFlexGridSizer', LispFlexGridSizerBuilder()) wxglade-0.6.8.orig/edit_sizers/edit_sizers.py0000644000175000017500000026744712150154266021565 0ustar georgeskgeorgesk""" Hierarchy of Sizers supported by wxGlade @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import general python modules import math import re # import project modules import wx from widget_properties import * from tree import Tree, WidgetTree import common import config import misc class BaseSizerBuilder(object): """\ Language independen base class for all sizer builders @cvar klass: Sizer class @type klass: String @cvar language: Language to generate the code for @type language: String @cvar init_stmt: Statements to generate the sizer from; lines have to end with a newline character @type init_stmt: List of strings @cvar tmpl_AddGrowableRow: Template for wxFlexGridSizer to set growable rows @type tmpl_AddGrowableRow: String @cvar tmpl_AddGrowableCol: Template for wxFlexGridSizer to set growable columns @type tmpl_AddGrowableCol: String @cvar tmpl_SetSizer: Template to call SetSizer() @type tmpl_SetSizer: String @cvar tmpl_Fit: Template to call Fit() @type tmpl_Fit: String @cvar tmpl_StaticBox: Template for staticbox name used in combination with wxStaticBoxSizer. @type tmpl_StaticBox: String @cvar tmpl_SetSizeHints: Template to set the size hints @type tmpl_SetSizeHints: String @ivar codegen: Language specific code generator @type codegen: Instance of L{codegen.BaseCodeWriter} @ivar props_get_code: Properties to replace in L{init_stmt} @type props_get_code: Dictionary """ init_stmt = [] klass = '' language = None tmpl_SetSizer = '' tmpl_Fit = '' tmpl_SetSizeHints = '' tmpl_StaticBox = '' tmpl_AddGrowableRow = '' tmpl_AddGrowableCol = '' def __init__(self): """\ Initialise sizer builder """ self.props_get_code = {} self.codegen = common.code_writers[self.language] def _get_wparent(self, obj): """\ Return the parent widget or a reference to it. @rtype: String """ raise NotImplementedError def _get_code(self, obj): """\ Generates the language specific code for sizer specified in L{klass} """ if not self.init_stmt: return [], [], [] init = [] layout = [] # append default properties self.props_get_code['sizer_name'] = obj.name self.props_get_code['klass'] = self.codegen.cn(self.klass) self.props_get_code['wxIDANY'] = self.codegen.cn('wxID_ANY') self.props_get_code['parent_widget'] = self._get_wparent(obj) self.props_get_code['sizer_name'] = \ self.codegen._format_classattr(obj) if self.klass == 'wxStaticBoxSizer' and self.tmpl_StaticBox: self.props_get_code['staticbox_name'] = \ self.tmpl_StaticBox % obj.name # generate init lines from init_stmt filled with props_get_code for line in self.init_stmt: init.append(line % self.props_get_code) # generate layout lines if obj.is_toplevel: layout.append(self.tmpl_SetSizer % self.props_get_code) if not obj.parent.properties.has_key('size') and \ obj.parent.is_toplevel: layout.append(self.tmpl_Fit % self.props_get_code) if obj.parent.properties.get('sizehints', False): layout.append(self.tmpl_SetSizeHints % self.props_get_code) return init, [], layout def get_code(self, obj): """\ Generates the language specific code for sizer specified in L{klass} """ if self.klass == 'wxBoxSizer': return self.get_code_wxBoxSizer(obj) if self.klass == 'wxStaticBoxSizer': return self.get_code_wxStaticBoxSizer(obj) if self.klass == 'wxGridSizer': return self.get_code_wxGridSizer(obj) if self.klass == 'wxFlexGridSizer': return self.get_code_wxFlexGridSizer(obj) return self._get_code(obj) def get_code_wxStaticBoxSizer(self, obj): """\ Set sizer specific properties and generate the code """ self.props_get_code.clear() self.props_get_code['orient'] = self.codegen.cn( obj.properties.get('orient', 'wxHORIZONTAL') ) self.props_get_code['label'] = self.codegen.quote_str( obj.properties.get('label', '') ) self.props_get_code['wxStaticBox'] = self.codegen.cn('wxStaticBox') return self._get_code(obj) def get_code_wxBoxSizer(self, obj): """\ Set sizer specific properties and generate the code """ self.props_get_code.clear() self.props_get_code['orient'] = self.codegen.cn( obj.properties.get('orient', 'wxHORIZONTAL') ) return self._get_code(obj) def get_code_wxGridSizer(self, obj): """\ Set sizer specific properties and generate the code """ self.props_get_code.clear() self.props_get_code['rows'] = obj.properties.get('rows', '0') self.props_get_code['cols'] = obj.properties.get('cols', '0') self.props_get_code['vgap'] = obj.properties.get('vgap', '0') self.props_get_code['hgap'] = obj.properties.get('hgap', '0') return self._get_code(obj) def get_code_wxFlexGridSizer(self, obj): """\ Set sizer specific properties and generate the code """ result = self.get_code_wxGridSizer(obj) # convert tuple to list result = list(result) # extract layout lines layout = result[-1] del result[-1] props = obj.properties if props.has_key('growable_rows'): for row in props['growable_rows'].split(','): self.props_get_code['row'] = row.strip() layout.append(self.tmpl_AddGrowableRow % self.props_get_code) if props.has_key('growable_cols'): for col in props['growable_cols'].split(','): self.props_get_code['col'] = col.strip() layout.append(self.tmpl_AddGrowableCol % self.props_get_code) # reappend layout lines result.append(layout) return result # end of class BaseSizerBuilder class SizerSlot: "a window to represent a slot in a sizer" def __init__(self, parent, sizer, pos=0): self.widget = None # reference to the widget resembling the slot self.sizer = sizer self.parent = parent self.pos = pos self.menu = None def create_widget(self): style = wx.FULL_REPAINT_ON_RESIZE self.widget = wx.Window(self.parent.widget, -1, size=(20, 20), style=style) self.widget.SetBackgroundColour(wx.LIGHT_GREY) self.widget.SetAutoLayout(True) wx.EVT_PAINT(self.widget, self.on_paint) wx.EVT_RIGHT_DOWN(self.widget, self.popup_menu) wx.EVT_LEFT_DOWN(self.widget, self.drop_widget) wx.EVT_MIDDLE_DOWN(self.widget, self.select_and_paste) wx.EVT_ENTER_WINDOW(self.widget, self.on_enter) wx.EVT_LEAVE_WINDOW(self.widget, self.on_leave) def on_key_down(event): evt_flags = 0 if event.ControlDown(): evt_flags = wx.ACCEL_CTRL evt_key = event.GetKeyCode() for flags, key, function in misc.accel_table: if evt_flags == flags and evt_key == key: wx.CallAfter(function) break #event.Skip() wx.EVT_KEY_DOWN(self.widget, on_key_down) def show_widget(self, yes): if yes and not self.widget: self.create_widget() if self.widget: self.widget.Show(yes) def on_enter(self, event): # hack. definitely. but... misc._currently_under_mouse = self.widget if common.adding_widget and \ (not common.adding_sizer or not self.sizer.is_virtual()): self.widget.SetCursor(wx.CROSS_CURSOR) else: self.widget.SetCursor(wx.STANDARD_CURSOR) event.Skip() def on_leave(self, event): # _currently_under_mouse is used to restore the normal cursor, if the # user cancelled the addition of a widget and the cursor is over this # slot misc._currently_under_mouse = None event.Skip() def on_paint(self, event): dc = wx.PaintDC(self.widget) dc.BeginDrawing() dc.SetBrush(wx.Brush("black", wx.FDIAGONAL_HATCH)) dc.SetPen(wx.BLACK_PEN) w, h = self.widget.GetClientSize() dc.DrawRectangle(0, 0, w, h) dc.EndDrawing() def on_size(self, event): self.widget.Refresh() def popup_menu(self, event): if not self.menu: self.menu = wx.Menu(_('Options')) REMOVE_ID, PASTE_ID = wx.NewId(), wx.NewId() if not self.sizer.is_virtual(): # we cannot remove items from virtual sizers misc.append_item(self.menu, REMOVE_ID, _('Remove\tDel'), wx.ART_DELETE) misc.append_item(self.menu, PASTE_ID, _('Paste\tCtrl+V'), wx.ART_PASTE) def bind(method): return lambda e: wx.CallAfter(method) wx.EVT_MENU(self.widget, REMOVE_ID, bind(self.remove)) wx.EVT_MENU(self.widget, PASTE_ID, bind(self.clipboard_paste)) PREVIEW_ID = wx.NewId() self.menu.AppendSeparator() misc.append_item(self.menu, PREVIEW_ID, _('Preview')) wx.EVT_MENU(self.widget, PREVIEW_ID, bind(self.preview_parent)) self.setup_preview_menu() self.widget.PopupMenu(self.menu, event.GetPosition()) def remove(self, *args): if not self.sizer.is_virtual(): self.sizer.remove_item(self) self.delete() def drop_widget(self, event): """\ replaces self with a widget in self.sizer. This method is called to add every non-toplevel widget or sizer, and in turn calls the appropriate builder function (found in the ``common.widgets'' dict) """ if not common.adding_widget: misc.focused_widget = self self.widget.SetFocus() return if common.adding_sizer and self.sizer.is_virtual(): return common.adding_widget = False common.adding_sizer = False self.widget.SetCursor(wx.NullCursor) # call the appropriate builder common.widgets[common.widget_to_add](self.parent, self.sizer, self.pos) common.widget_to_add = None common.app_tree.app.saved = False # update the status of the app def clipboard_paste(self, *args): import clipboard if clipboard.paste(self.parent, self.sizer, self.pos): common.app_tree.app.saved = False # update the status of the app #print misc.focused_widget def select_and_paste(self, *args): """\ Middle-click event handler: selects the slot and, if the clipboard is not empty, pastes its content here """ misc.focused_widget = self self.widget.SetFocus() self.clipboard_paste() def delete(self, delete_widget=True): if self.menu: self.menu.Destroy() if misc._currently_under_mouse is self.widget: misc._currently_under_mouse = None if delete_widget and self.widget: self.widget.Destroy() if misc.focused_widget is self: misc.focused_widget = None common.app_tree.app.saved = False # update the status of the app def update_pos(self, value): """\ called by self.sizer.change_item_pos to update the item's position when another widget is moved """ self.pos = value def setup_preview_menu(self): p = misc.get_toplevel_widget(self.sizer) if p is not None: item = list(self.menu.GetMenuItems())[-1] if p.preview_is_visible(): item.SetText(_('Close preview') + ' (%s)\tCtrl+P' % p.name) else: item.SetText(_('Preview') + ' (%s)\tCtrl+P' % p.name) def preview_parent(self): p = misc.get_toplevel_widget(self.sizer) if p is not None: p.preview(None) # end of class SizerSlot if 0: #wxPlatform != '__WXMAC__': Button = wx.Button else: #from wxPython.lib.buttons import wxGenButton as Button from wx.lib.buttons import GenButton as Button class SizerHandleButton(Button): """\ Provides a ``handle'' to activate a Sizer and to access its popup menu """ def __init__(self, parent, id, sizer, menu): # menu: list of 2-tuples: (label, function) Button.__init__(self, parent.widget, id, '', size=(5, 5)) self.sizer = sizer self.menu = menu self._rmenu = None try: self.SetUseFocusIndicator(False) except AttributeError: pass ## # provide popup menu for removal ## REMOVE_ID = wxNewId() ## self._rmenu = misc.wxGladePopupMenu(sizer.name) ## #self._rmenu.Append(REMOVE_ID, 'Remove\tDel') ## misc.append_item(self._rmenu, REMOVE_ID, 'Remove\tDel', 'remove.xpm') ## EVT_MENU(self, REMOVE_ID, self._remove) ## for item in menu: ## id = wxNewId() ## #self._rmenu.Append(id, item[0]) ## bmp = None ## if len(item) > 2: bmp = item[2] ## misc.append_item(self._rmenu, id, item[0], bmp) ## EVT_MENU(self, id, item[1]) ## self.sizer._rmenu = self._rmenu wx.EVT_RIGHT_DOWN(self, self.popup_menu) ## def remove(): ## if common.focused_widget is not None: ## common.focused_widget.remove() ## table = [(0, WXK_DELETE, remove)] def on_key_down(event): evt_flags = 0 if event.ControlDown(): evt_flags = wx.ACCEL_CTRL evt_key = event.GetKeyCode() for flags, key, function in misc.accel_table: if evt_flags == flags and evt_key == key: wx.CallAfter(function) break #event.Skip() wx.EVT_KEY_DOWN(self, on_key_down) def on_set_focus(event): misc.focused_widget = self event.Skip() wx.EVT_SET_FOCUS(self, on_set_focus) def set_menu_title(self, title): if self._rmenu: self._rmenu.SetTitle(title) def popup_menu(self, event): if not self._rmenu: # provide popup menu for removal REMOVE_ID = wx.NewId() self._rmenu = misc.wxGladePopupMenu(self.sizer.name) def bind(method): return lambda e: wx.CallAfter(method) #self._rmenu.Append(REMOVE_ID, 'Remove\tDel') misc.append_item(self._rmenu, REMOVE_ID, _('Remove\tDel'), wx.ART_DELETE) wx.EVT_MENU(self, REMOVE_ID, bind(self._remove)) for item in self.menu: id = wx.NewId() #self._rmenu.Append(id, item[0]) bmp = None if len(item) > 2: bmp = item[2] misc.append_item(self._rmenu, id, item[0], bmp) wx.EVT_MENU(self, id, bind(item[1])) self._rmenu.AppendSeparator() PREVIEW_ID = wx.NewId() misc.append_item(self._rmenu, PREVIEW_ID, _('Preview')) wx.EVT_MENU(self, PREVIEW_ID, bind(self.preview_parent)) self.sizer._rmenu = self._rmenu del self.menu self.setup_preview_menu() self.PopupMenu(self._rmenu, event.GetPosition()) def _remove(self, *args): # removes the sizer from his parent, if it has one if self.sizer.toplevel: window = self.sizer.window common.app_tree.remove(self.sizer.node) window.set_sizer(None) return self.sizer.sizer.free_slot(self.sizer.pos) common.app_tree.remove(self.sizer.node) # needed for consistency (common.focused_widget.remove) remove = _remove def Destroy(self): if self._rmenu: self._rmenu.Destroy() Button.Destroy(self) if misc.focused_widget is self: misc.focused_widget = None def setup_preview_menu(self): p = misc.get_toplevel_widget(self.sizer) if p is not None: item = list(self._rmenu.GetMenuItems())[-1] if p.preview_is_visible(): item.SetText(_('Close preview') + ' (%s)\tCtrl+P' % p.name) else: item.SetText(_('Preview') + ' (%s)\tCtrl+P' % p.name) def preview_parent(self): p = misc.get_toplevel_widget(self.sizer) p.preview(None) # end of class SizerHandleButton class SizerItem: """\ Represents a child of a sizer """ def __init__(self, item, pos, option=0, flag=0, border=0, size=None): self.item = item self.item.pos = pos self.option = option self.flag = flag self.border = border self.size = size # end of class SizerItem #---------- 2002-10-07 -------------------------------------------------------- class SizerClassDialog: choices = [ ('EditBoxSizerV', 'wxBoxSizer (wxVERTICAL)'), ('EditBoxSizerH', 'wxBoxSizer (wxHORIZONTAL)'), ('EditStaticBoxSizerV', 'wxStaticBoxSizer (wxVERTICAL)'), ('EditStaticBoxSizerH', 'wxStaticBoxSizer (wxHORIZONTAL)'), ('EditGridSizer', 'wxGridSizer'), ('EditFlexGridSizer', 'wxFlexGridSizer') ] def __init__(self, owner, parent): self.owner = owner self.parent = parent self.dialog = None def ShowModal(self): name = self.owner.__class__.__name__ if hasattr(self.owner, 'orient'): if self.owner.orient == wx.HORIZONTAL: name += 'H' else: name += 'V' choices = [ b for a, b in self.choices if a != name ] self.dialog = wx.SingleChoiceDialog(self.parent, _("Select sizer type"), _("Select sizer type"), choices) self.dialog.CenterOnScreen() return self.dialog.ShowModal() def get_value(self): return self.dialog.GetStringSelection() # end of class SizerClassDialog def change_sizer(old, new, which_page=0, _hidden=[None]): """\ changes 'old' sizer to 'new' Params: - old: SizerBase instance to replace - new: string selection that identifies the new instance - which_page: index of the notebook page of the property window to display: this is used only by set_growable_(rows|cols) """ constructors = { 'wxBoxSizer (wxVERTICAL)': lambda : EditBoxSizer(old.name, old.window, wx.VERTICAL, 0, old.toplevel), 'wxBoxSizer (wxHORIZONTAL)': lambda : EditBoxSizer(old.name, old.window, wx.HORIZONTAL, 0, old.toplevel), 'wxStaticBoxSizer (wxVERTICAL)': lambda : EditStaticBoxSizer(old.name, old.window, wx.VERTICAL, getattr(old, 'label', old.name), 0, old.toplevel), 'wxStaticBoxSizer (wxHORIZONTAL)': lambda : EditStaticBoxSizer(old.name, old.window, wx.HORIZONTAL, getattr(old, 'label', old.name), 0, old.toplevel), 'wxGridSizer': lambda : EditGridSizer(old.name, old.window, rows=0, cols=0, toplevel=old.toplevel), 'wxFlexGridSizer': lambda : EditFlexGridSizer(old.name, old.window, rows=0, cols=0, toplevel=old.toplevel) } szr = constructors[new]() szr.children.extend(old.children[1:]) szr.node = old.node if isinstance(szr, GridSizerBase): szr.set_rows(getattr(old, 'rows', 1)) szr.set_cols(getattr(old, 'cols', len(szr.children)-1)) szr.set_hgap(getattr(old, 'hgap', 0)) szr.set_vgap(getattr(old, 'vgap', 0)) if isinstance(szr, EditFlexGridSizer): try: grow_r = old.grow_rows grow_c = old.grow_cols if grow_r: szr.grow_rows = grow_r szr.properties['growable_rows'].toggle_active(True) szr.properties['growable_rows'].set_value( szr.get_growable_rows()) if grow_c: szr.grow_cols = grow_c szr.properties['growable_cols'].toggle_active(True) szr.properties['growable_cols'].set_value( szr.get_growable_cols()) except (AttributeError, KeyError): pass szr.show_widget(True, dont_set=True) if _hidden[0] is None: _hidden[0] = wx.Frame(None, -1, _("HIDDEN FRAME FOR CHANGE SIZER")) for c in szr.children[1:]: widget = c.item widget.sizer = szr if not isinstance(widget, SizerSlot): # ALB 2007-09-04. This is necessary as a workaround to a # wx.StaticBoxSizer issue: it seems that the wx.StaticBox needs to # come before any other widget managed by the wx.StaticBoxSizer in # the GetChildren() list. Explicitly reparenting the widgets seems # to solve the problem if hasattr(widget.widget, 'GetParent'): p = widget.widget.GetParent() widget.widget.Reparent(_hidden[0]) widget.widget.Reparent(p) szr.widget.Insert(widget.pos, widget.widget, int(widget.get_option()), widget.get_int_flag(), int(widget.get_border())) if not szr.toplevel: szr.sizer = old.sizer szr.option = old.option szr.flag = old.flag szr.border = old.border szr.pos = old.pos szr.sizer.children[szr.pos].item = szr if szr.sizer.widget: elem = szr.sizer.widget.GetChildren()[szr.pos] elem.SetSizer(szr.widget) common.app_tree.change_node(szr.node, szr) old.toplevel = False szr.show_properties() szr.notebook.SetSelection(which_page) for c in old.widget.GetChildren(): if c and c.IsSizer(): c.SetSizer(None) old.widget.Clear() old.children = old.children[:1] old.delete() if szr.toplevel: szr.window.set_sizer(szr) szr.layout(True) #------------------------------------------------------------------------------ class InsertDialog(wx.Dialog): def __init__(self, max_val): wx.Dialog.__init__(self, None, -1, _("Select a position")) self.pos = 0 pos_prop = SpinProperty(self, 'position', self, r=(0, max_val), label=_("position")) pos_prop.spin.SetFocus() pos_prop.spin.SetSelection(-1, -1) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(pos_prop.panel, 0, wx.ALL|wx.EXPAND, 5) szr2 = wx.BoxSizer(wx.HORIZONTAL) szr2.Add(wx.Button(self, wx.ID_OK, _("OK")), 0, wx.ALL, 5) szr2.Add(wx.Button(self, wx.ID_CANCEL, _("Cancel")), 0, wx.ALL, 5) szr.Add(szr2, 0, wx.ALIGN_CENTER) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def __getitem__(self, name): def set_pos(v): self.pos = int(v) return (lambda : self.pos, set_pos) # end of class InsertDialog class Sizer: """\ Base class for every Sizer handled by wxGlade """ def __init__(self, window): self.window = window # window this sizer is responsible # for the layout of def set_item(self, pos, option=None, flag=None, border=None, size=None, force_layout=True): """\ Updates the layout of the item at the given pos. """ raise NotImplementedError def add_item(self, item, pos=None, option=0, flag=0, border=0, size=None, force_layout=True): """\ Adds an item to self. """ raise NotImplementedError def remove_item(self, elem, force_layout=True): """\ Removes elem from self. """ pass def free_slot(self, pos, force_layout=True): """\ Replaces the element at pos with an empty slot """ raise NotImplementedError def _fix_notebook(self, pos, notebook_sizer, force_layout=True): """\ Internal method used to replace a notebook widget with its notebook sizer. """ pass def is_virtual(self): """\ Return true if sizer is virtual (f.e. SplitterWindowSizer) """ return False def get_itempos(self, attrs): """\ For virtual sizers only, returns the position of the item in the parent: this is used when loading a wxg file, to build the tree of widgets correctly """ raise NotImplementedError # end of class Sizer class SizerBase(Sizer): """\ Base class for every non-virtual Sizer handled by wxGlade """ def __init__(self, name, klass, window, toplevel=True, show=True, menu=None): Sizer.__init__(self, window) self.attribute = 0 self.id = wx.NewId() self.name = name self.klass = klass self.base = klass self.pos = 0 # for sub-sizers, the position inside the parent self.properties = {} self.property_window = window.property_window self.widget = None # this is the actual wxSizer instance # toplevel: if True, self is not inside another sizer, but it is the # responsible of the layout of self.window self.toplevel = toplevel if not self.toplevel: self.option = 1 self.flag = wx.EXPAND self.border = 0 self.sizer = None self.menu = menu if self.menu is None: self.menu = [(_('Add slot'), self.add_slot), (_('Insert slot...'), self.insert_slot)] #if not self.toplevel: self.menu.extend([(_('Copy\tCtrl+C'), self.clipboard_copy, wx.ART_COPY), (_('Cut\tCtrl+X'), self.clipboard_cut, wx.ART_CUT), ]) self._btn = None # SizerHandleButton self.notebook = None self._property_setup() self.children = [] # list of widgets added to the sizer def create_widget(self): """\ Creates the wxSizer self.widget """ raise NotImplementedError def show_widget(self, yes, dont_set=False): if not yes or self.widget: return # nothing to do if the sizer has already been created self._btn = SizerHandleButton(self.window, self.id, self, self.menu) # ScreenToClient used by WidgetTree for the popup menu wx.EVT_BUTTON(self._btn, self.id, self.show_properties) self.create_widget() self.widget.Refresh = self.refresh self.widget.GetBestSize = self.widget.GetMinSize self.widget.ScreenToClient = self._btn.ScreenToClient if self.toplevel and not dont_set: self.window.set_sizer(self) # ALB 2004-08-11 if not config.preferences.show_sizer_handle: self.widget.Show(self._btn, False) if misc.focused_widget is self: self.update_view(True) def _property_setup(self): """\ Setup of the Properties of self. """ self.flags_pos = [ wx.ALL, wx.LEFT, wx.RIGHT, wx.TOP, wx.BOTTOM, wx.EXPAND, wx.ALIGN_RIGHT, wx.ALIGN_BOTTOM, wx.ALIGN_CENTER_HORIZONTAL, wx.ALIGN_CENTER_VERTICAL, wx.SHAPED, wx.ADJUST_MINSIZE ] self.access_functions = { 'name' : (lambda : self.name, self.set_name), 'class': (lambda: self.klass, self.change), 'attribute': (self.get_attribute, self.set_attribute), } if not self.toplevel: self.access_functions['option'] = (self.get_option, self.set_option) self.access_functions['flag'] = (self.get_flag, self.set_flag) self.access_functions['border'] = (self.get_border, self.set_border) self.access_functions['pos'] = (self.get_pos, self.set_pos) self.name_prop = TextProperty(self, 'name', None, label=_('name')) #self.klass_prop = TextProperty(self, 'class', None, readonly=True) dialog = SizerClassDialog(self, None) self.klass_prop = DialogProperty(self, 'class', None, dialog, label=_('class')) self.attr_prop = CheckBoxProperty( self, 'attribute', None, _('Store as attribute'), write_always=False, ) self.properties['attribute'] = self.attr_prop if not self.toplevel: prop = self.sizer_properties = {} #prop['option'] = SpinProperty(self, 'option', None, 0, (0, 1000)) from layout_option_property import LayoutOptionProperty, \ LayoutPosProperty prop['option'] = LayoutOptionProperty(self, self.sizer) flag_labels = ['#section#' + _('Border'), 'wxALL', 'wxLEFT', 'wxRIGHT', 'wxTOP', 'wxBOTTOM', '#section#' + _('Alignment'), 'wxEXPAND', 'wxALIGN_RIGHT', 'wxALIGN_BOTTOM', 'wxALIGN_CENTER_HORIZONTAL', 'wxALIGN_CENTER_VERTICAL', 'wxSHAPED', 'wxADJUST_MINSIZE' ] prop['flag'] = CheckListProperty(self, 'flag', None, flag_labels) prop['border'] = SpinProperty(self, 'border', None, 0, (0, 1000), label=_('border')) prop['pos'] = LayoutPosProperty(self, self.sizer) def set_containing_sizer(self, sizer): self.sizer = sizer self.sizer_properties['option'].set_sizer(sizer) self.sizer_properties['pos'].set_sizer(sizer) def get_pos(self): return self.pos - 1 def set_pos(self, value): wx.CallAfter(self.sizer.change_item_pos, self, min(value + 1, len(self.sizer.children) - 1)) def get_attribute(self): return self.attribute def set_attribute(self, value): self.attribute = int(value) def update_pos(self, value): #print 'update pos', self.name, value self.sizer_properties['pos'].set_value(value-1) self.pos = value def change(self, *args): wx.CallAfter(change_sizer, self, self.klass_prop.get_value()) def create_properties(self): """\ Displays the Properties of self """ self.notebook = wx.Notebook(common.property_panel, -1) self.notebook.sizer = None self.notebook.SetAutoLayout(True) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) sizer_tmp = wx.BoxSizer(wx.VERTICAL) self.name_prop.display(panel) self.klass_prop.display(panel) self.klass_prop.text.SetEditable(False) self.attr_prop.display(panel) sizer_tmp.Add(self.name_prop.panel, 0, wx.EXPAND) sizer_tmp.Add(self.klass_prop.panel, 0, wx.EXPAND) sizer_tmp.Add(self.attr_prop.panel, 0, wx.EXPAND) if not self.toplevel: prop = self.sizer_properties prop['pos'].display(panel) prop['option'].display(panel) prop['border'].display(panel) prop['flag'].display(panel) sizer_tmp.Add(prop['pos'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['option'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['border'].panel, 0, wx.EXPAND) sizer_tmp.Add(prop['flag'].panel, 0, wx.EXPAND) else: # button to Fit parent FIT_ID = wx.NewId() self.fit_btn = wx.Button(panel, FIT_ID, _('Fit parent')) self.fit_btn.SetToolTip(wx.ToolTip( _('Sizes the window so that it fits around its subwindows') )) wx.EVT_BUTTON(self.fit_btn, FIT_ID, self.fit_parent) sizer_tmp.Add(self.fit_btn, 0, wx.ALL|wx.EXPAND, 5) panel.SetAutoLayout(True) panel.SetSizer(sizer_tmp) sizer_tmp.Fit(panel) w, h = panel.GetClientSizeTuple() self.notebook.AddPage(panel, _("Common")) panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def popup_menu(self, event): """\ pops up a menu to add or remove slots from self, or to remove self from the application. """ if self._btn: self._btn.popup_menu(event) #self._btn.PopupMenu(self._btn._rmenu, event.GetPosition()) def set_name(self, value): value = "%s" % value if not config.preferences.allow_duplicate_names and \ (self.widget and common.app_tree.has_name(value, self.node)): wx.CallAfter( wx.MessageBox, _('Name "%s" is already in use.\n' 'Please enter a different one.') % value, _("Error"), wx.OK|wx.ICON_ERROR) self.name_prop.set_value(self.name) return if not re.match(self.set_name_pattern, value): self.name_prop.set_value(self.name) else: oldname = self.name self.name = value self._btn.set_menu_title(value) try: common.app_tree.refresh_name(self.node, oldname) except AttributeError: common.message.exception(_('Internal Error')) self.property_window.SetTitle(_('Properties - <%s>') % self.name) set_name_pattern = re.compile('^[a-zA-Z_]+[\w0-9]*$') def __getitem__(self, value): return self.access_functions[value] def show_properties(self, *args): """\ Updates common.property_panel to show the notebook with the Properties of self """ if not self.window.is_visible(): return if not self.notebook: self.create_properties() sizer_tmp = self.property_window.GetSizer() #sizer_tmp = wxPyTypeCast(sizer_tmp, "wxBoxSizer") #child = wxPyTypeCast(sizer_tmp.GetChildren()[0], "wxSizerItem") child = sizer_tmp.GetChildren()[0] #w = wxPyTypeCast(child.GetWindow(), "wxWindow") w = child.GetWindow() if w is self.notebook: return try: index = -1 title = w.GetPageText(w.GetSelection()) for i in range(self.notebook.GetPageCount()): if self.notebook.GetPageText(i) == title: index = i break except AttributeError, e: #print e index = -1 w.Hide() if 0 <= index < self.notebook.GetPageCount(): self.notebook.SetSelection(index) self.notebook.Reparent(self.property_window) child.SetWindow(self.notebook) w.Reparent(misc.hidden_property_panel) # ALB moved this before Layout, it seems to be needed for wx2.6... self.notebook.Show() self.notebook.SetSize(self.property_window.GetClientSize()) self.property_window.Layout() self.property_window.SetTitle(_('Properties - <%s>') % self.name) if hasattr(self, 'node'): common.app_tree.select_item(self.node) try: self._btn.SetFocus() except AttributeError: pass def fit_parent(self, *args): """\ Tell the sizer to resize the window to match the sizer's minimal size """ if self.widget and self.window.widget: self.widget.Fit(self.window.widget) #self.widget.SetSizeHints(self.window.widget) self.window.widget.Layout() def add_item(self, item, pos=None, option=0, flag=0, border=0, size=None, force_layout=True): """\ Adds an item to self. """ option = int(option); flag = int(flag); border = int(border) if pos is None: pos = len(self.children) ## self.children.append(SizerItem(item, pos, option, flag, border, ## size)) self.add_slot() try: old_child = self.children[pos] if isinstance(old_child.item, SizerSlot): old_child.item.delete(False) self.children[pos] = SizerItem(item, pos, option, flag, border, size) except IndexError: # this shouldn't happen! common.message.exception(_('Internal Error')) print self.children, pos raise SystemExit if hasattr(item, 'set_containing_sizer'): item.set_containing_sizer(self) else: item.sizer = self item.pos = pos self._add_item_widget(item, pos, option, flag, border, size, force_layout) def _add_item_widget(self, item, pos, option, flag, border, size, force_layout): if not self.widget: return # nothing more to do if not item.widget: return try: elem = self.widget.GetChildren()[pos] except IndexError: # this happens after loading from xml # I have to set wxADJUST_MINSIZE to handle a bug that I'm not # able to detect (yet): if the width or height of a widget is -1, # the layout is messed up! self.widget.Add(item.widget, option, flag, border) if size: w, h = size else: w, h = item.widget.GetBestSize() if w == -1: w = item.widget.GetBestSize()[0] if h == -1: h = item.widget.GetBestSize()[1] self.widget.SetItemMinSize(item.widget, w, h) return self.widget.Insert(pos, item.widget, option, flag, border) self.widget.Remove(pos+1) if elem.IsWindow(): w = elem.GetWindow() w.SetContainingSizer(None) w.Destroy() try: # if the item was a window, set its size to a reasonable value ## if elem.IsWindow(): if size: w, h = size else: w, h = item.widget.GetBestSize() if w == -1: w = item.widget.GetBestSize()[0] if h == -1: h = item.widget.GetBestSize()[1] option = 0 option = elem.GetProportion() flag = elem.GetFlag() if not size or (option == 0 or not (flag & wx.EXPAND)): self.widget.SetItemMinSize(item.widget, w, h) else: w, h = item.widget.GetBestSize() self.widget.SetItemMinSize(item.widget, w, h) #*item.widget.GetBestSize()) #self.widget.SetItemMinSize(item.widget, w, h) except Exception: #common.message.exception(_('Internal Error')) pass if force_layout: self.layout() # update the layout of self def _fix_notebook(self, pos, notebook_sizer, force_layout=True): """\ Replaces the widget at 'pos' with 'notebook_sizer': this is intended to be used by wxNotebook widgets, to add the notebook sizer to this sizer. This is a hack, but it's the best I could find without having to rewrite too much code :-( """ # no error checking at all, this is a "protected" method, so it should # be safe to assume the caller knows how to use it item = self.widget.GetChildren()[pos] if item.IsWindow(): w = item.GetWindow() w.SetContainingSizer(None) item.SetSizer(notebook_sizer) if force_layout: self.layout() def set_item(self, pos, option=None, flag=None, border=None, size=None, force_layout=True): """\ Updates the layout of the item at the given pos. """ try: item = self.children[pos] except IndexError: # this shouldn't happen common.message.exception(_('Internal Error')) raise SystemExit if option is not None: option = int(option) item.option = option if flag is not None: flag = int(flag) item.flag = flag if border is not None: border = int(border) item.border = border if size is not None: item.size = size self._set_item_widget(pos, option, flag, border, size, force_layout) def _set_item_widget(self, pos, option, flag, border, size, force_layout): if not self.widget: return try: elem = self.widget.GetChildren()[pos] except IndexError: return # this may happen during xml loading if option is not None: elem.SetProportion(option) if flag is not None: elem.SetFlag(flag) if border is not None: elem.SetBorder(border) if elem.IsWindow(): item = elem.GetWindow() if size is None: size = elem.GetSize() w, h = size if w == -1: w = item.GetBestSize()[0] if h == -1: h = item.GetBestSize()[1] newelem = wx.SizerItem() newelem.SetWindow(item) newelem.SetFlag(elem.GetFlag()) newelem.SetBorder(elem.GetBorder()) newelem.SetProportion(elem.GetProportion()) newelem.SetInitSize(w, h) self.widget.InsertItem(pos, newelem) #self.children[pos] = newelem self.widget.Remove(pos+1) if force_layout: self.layout(True) #try: self.sizer.Layout() #except AttributeError: pass def remove_item(self, elem, force_layout=True): """\ Removes elem from self. """ if elem: for c in self.children[elem.pos+1:]: c.item.pos -= 1 del self.children[elem.pos] if self.widget and elem.widget: self.widget.Remove(elem.widget) if force_layout: self.layout(True) #if not self.toplevel: self.sizer.Layout() Remove = remove_item # maybe this is needed, I have to check... def layout(self, recursive=True): #if not self.widget or not self.window.is_visible(): return if not self.widget: return from edit_windows import TopLevelBase if self.toplevel and not isinstance(self.window, TopLevelBase) and \ hasattr(self.window.sizer, 'widget'): if not self.window.properties['size'].is_active(): szr = self.window.sizer.widget w, h = self.window.widget.GetBestSize() szr.SetItemMinSize(self.window.widget, w, h) if self.window.sizer is not self: self.window.sizer.layout(False) else: szr.Layout() return elif self.toplevel and isinstance(self.window, TopLevelBase): #self.window.widget.Layout() self.widget.Layout() evt = wx.SizeEvent(self.window.widget.GetSize(), self.window.widget.GetId()) wx.PostEvent(self.window.widget, evt) # don't change the size of the window if not misc.check_wx_version(2, 6, 0): # this seems to work bad for 2.4.0 (and 2.6 too... 2005-05-01) self.widget.FitInside(self.window.widget) return self.widget.SetMinSize(self.widget.CalcMin()) self.widget.Layout() for c in self.children: try: c.item.widget.Refresh() except Exception: pass if recursive: if getattr(self, 'sizer', None) is not None: self.sizer.layout(recursive) # 2002-10-09 ------------------------------------------------------------- def change_item_pos(self, item, new_pos, force_layout=True): """\ Changes the position of the 'item' so that it is at 'new_pos' 'new_pos' must be a valid position """ if not self.widget: return #print old_pos = item.pos import copy new_item = copy.copy(self.children[old_pos]) if old_pos > new_pos: for c in self.children[new_pos:old_pos]: c.item.update_pos(c.item.pos + 1) self.children.insert(new_pos, new_item) del self.children[old_pos+1] else: for c in self.children[old_pos+1:new_pos+1]: c.item.update_pos(c.item.pos - 1) del self.children[old_pos] #self.children.insert(new_pos+1, new_item) self.children.insert(new_pos, new_item) item.update_pos(new_pos) elem = self.widget.GetChildren()[old_pos] # always set the sizer to None because otherwise it will be Destroy'd elem.SetSizer(None) # this fake_win trick seems necessary because wxSizer::Remove(int pos) # doesn't seem to work with grid sizers :-\ fake_win = wx.Window(self.window.widget, -1) elem.SetWindow(fake_win) self.widget.Remove(fake_win) fake_win.Destroy() self.widget.Insert(new_pos, item.widget, int(item.get_option()), item.get_int_flag(), int(item.get_border())) common.app_tree.change_node_pos(item.node, new_pos-1) common.app_tree.select_item(item.node) if force_layout: self.layout() if wx.Platform == '__WXMSW__': self.window.widget.Refresh() #print [c.item.name for c in self.children] # ------------------------------------------------------------------------ def set_option(self, value): """\ If self is not a toplevel sizer, update the layout to reflect the value of the option property """ self.option = int(value) try: self.sizer.set_item(self.pos, option=self.option) #print self.name, 'set_option', self.option except AttributeError: pass self.finish_set() def set_flag(self, value): """\ If self is not a toplevel sizer, update the layout to reflect the value of the flag property """ value = self.sizer_properties['flag'].prepare_value(value) flags = 0 for v in range(len(value)): if value[v]: flags |= self.flags_pos[v] self.flag = flags try: self.sizer.set_item(self.pos, flag=flags) except AttributeError: pass self.finish_set() def set_border(self, value): """\ If self is not a toplevel sizer, update the layout to reflect value of the border property """ self.border = int(value) try: self.sizer.set_item(self.pos, border=self.border) except AttributeError, e: print e def get_option(self): if not hasattr(self, 'sizer'): return '1' return str(self.option) def get_flag(self): retval = [0] * len(self.flags_pos) if not hasattr(self, 'sizer'): return retval try: flag = self.flag for i in range(len(self.flags_pos)): if flag & self.flags_pos[i]: retval[i] = 1 # patch to make wxALL work if retval[1:5] == [1, 1, 1, 1]: retval[0] = 1; retval[1:5] = [0, 0, 0, 0] else: retval[0] = 0 except AttributeError: pass return retval def get_int_flag(self): try: return self.flag except AttributeError: return wx.EXPAND def get_border(self): if not hasattr(self, 'sizer'): return '0' return str(self.border) def remove(self): # this function is here for clipboard compatibility if not self._btn: return self._btn._remove() def delete(self): """\ ``Destructor'' """ self._rmenu = None if self._btn: self._btn.Destroy() if self.notebook: ## for p in self.properties.itervalues(): ## if p.panel: p.panel.Destroy() ## if self.name_prop.panel: self.name_prop.panel.Destroy() ## if self.klass_prop.panel: self.klass_prop.panel.Destroy() ## if hasattr(self, 'sizer_properties'): ## for p in self.sizer_properties.itervalues(): ## if p.panel: p.panel.Destroy() nb_szr = self.notebook.sizer self.notebook.DeleteAllPages() self.notebook.Destroy() if nb_szr is not None: nb_szr.Destroy() for c in self.children: if c.item and isinstance(c.item, SizerSlot): c.item.delete() if self.toplevel: self.window.set_sizer(None) if wx.Platform == '__WXMSW__': def finish_set(self): for c in self.children: if c.item.widget: try: c.item.widget.Refresh() except AttributeError: pass # sizers have no Refresh else: def finish_set(self): pass def refresh(self, *args): # this will be self.widget.Refresh for c in self.children: if c.item.widget: try: c.item.widget.Refresh() except AttributeError: pass def update_view(self, selected): if self._btn is not None: color = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNFACE) if selected: color = wx.RED self._btn.SetBackgroundColour(color) self._btn.Refresh(True) def add_slot(self, *args, **kwds): """\ adds a slot to the sizer, i.e. a fake window that will accept the dropping of widgets """ tmp = SizerSlot(self.window, self, len(self.children)) item = SizerItem(tmp, len(self.children), 1, wx.EXPAND) self.children.append(item) if not self.widget: return tmp.show_widget(True) # create the actual SizerSlot widget self.widget.Add(tmp.widget, 1, wx.EXPAND) self.widget.SetItemMinSize(tmp.widget, 20, 20) force_layout = kwds.get('force_layout', True) if force_layout: self.layout(True) common.app_tree.app.saved = False def insert_slot(self, *args, **kwds): """\ inserts a slot into the sizer: the user will be asked for a position before which to insert the SizerSlot object. This method is meaningful only in an interactive session """ if not self.widget: return dialog = InsertDialog(len(self.children)-1) if dialog.ShowModal() == wx.ID_OK: pos = dialog.pos + 1 tmp = SizerSlot(self.window, self, pos) for c in self.children[pos:]: c.item.pos += 1 self.children.insert(pos, SizerItem(tmp, pos, 1, wx.EXPAND, 0)) tmp.show_widget(True) # create the actual SizerSlot self.widget.Insert(pos, tmp.widget, 1, wx.EXPAND) self.widget.SetItemMinSize(tmp.widget, 20, 20) force_layout = kwds.get('force_layout', True) if force_layout: self.layout(True) common.app_tree.app.saved = False dialog.Destroy() def free_slot(self, pos, force_layout=True): """\ Replaces the element at pos with an empty slot """ tmp = SizerSlot(self.window, self, pos) item = SizerItem(tmp, pos, 1, wx.EXPAND, 0) self.children[pos] = item if self.widget: tmp.show_widget(True) # create the actual SizerSlot self.widget.Insert(pos+1, tmp.widget, 1, wx.EXPAND) self.widget.Detach(pos) if force_layout: self.layout() def is_visible(self): return self.window.is_visible() def clipboard_copy(self, *args): """\ returns a copy of self to be inserted in the clipboard """ #if not self.toplevel: import clipboard clipboard.copy(self) def clipboard_cut(self, *args): #if not self.toplevel: import clipboard clipboard.cut(self) def post_load(self): """\ Called after the loading of an app from an XML file, before showing the hierarchy of widget for the first time. This is used only for container widgets, to adjust their size appropriately. """ if not self.toplevel: return if not self.window.properties['size'].is_active(): self.fit_parent() w, h = self.widget.GetSize() prefix = '' if config.preferences.use_dialog_units: w, h = self.window.widget.ConvertPixelSizeToDialog( self.widget.GetSize()) prefix = 'd' self.window.set_size('%s, %s%s' % (w, h, prefix)) # end of class SizerBase class wxGladeBoxSizer(wx.BoxSizer): def SetItemMinSize(self, item, w, h): try: w2, h2 = item.GetBestSize() if w == -1: w = w2 if h == -1: h = h2 except AttributeError: pass wx.BoxSizer.SetItemMinSize(self, item, w, h) # end of class wxGladeBoxSizer class EditBoxSizer(SizerBase): """\ Class to handle wxBoxSizer objects """ def __init__(self, name, window, orient=wx.VERTICAL, elements=3, toplevel=True, show=True): SizerBase.__init__(self, name, 'wxBoxSizer', window, toplevel, show) self.access_functions['orient'] = (self.get_orient, self.set_orient) self.properties['orient'] = HiddenProperty( self, 'orient', (orient == wx.HORIZONTAL and 'wxHORIZONTAL' or 'wxVERTICAL'), ) class Dummy: widget = None name = "" # add to self.children the SizerItem for self._btn self.children = [SizerItem(Dummy(), 0, 0, wx.EXPAND)] for i in range(1, elements+1): tmp = SizerSlot(self.window, self, i) self.children.append(SizerItem(tmp, i, 1, wx.EXPAND)) self.orient = orient def create_widget(self): self.widget = wxGladeBoxSizer(self.orient) self.widget.Add(self._btn, 0, wx.EXPAND) to_lay_out = [] for c in self.children[1:]: # we've already added self._btn c.item.show_widget(True) if isinstance(c.item, SizerSlot): self.widget.Add(c.item.widget, 1, wx.EXPAND) self.widget.SetItemMinSize(c.item.widget, 20, 20) else: sp = c.item.properties.get('size') if sp and sp.is_active(): if (c.option != 0 or (c.flag & wx.EXPAND)) and \ not (c.flag & wx.FIXED_MINSIZE): c.item.widget.Layout() w, h = c.item.widget.GetBestSize() #print "HERE:", w, h c.item.widget.SetMinSize((w, h)) else: size = sp.get_value().strip() if size[-1] == 'd': size = size[:-1] use_dialog_units = True else: use_dialog_units = False w, h = [ int(v) for v in size.split(',') ] if use_dialog_units: w, h = wx.DLG_SZE(c.item.widget, (w, h)) # now re-set the item to update the size correctly... to_lay_out.append((c.item.pos, (w, h))) for pos, size in to_lay_out: self.set_item(pos, size=size, force_layout=False) self.layout(True) if not self.toplevel and getattr(self, 'sizer'): # hasattr(self, 'sizer') is False only in case of a 'change_sizer' # call self.sizer.add_item(self, self.pos, self.option, self.flag, self.border, self.widget.GetMinSize()) def get_orient(self): od = { wx.HORIZONTAL: 'wxHORIZONTAL', wx.VERTICAL: 'wxVERTICAL' } return od.get(self.orient) def set_orient(self, value): od = { 'wxHORIZONTAL': wx.HORIZONTAL, 'wxVERTICAL': wx.VERTICAL } self.orient = od.get(value, wx.VERTICAL) # end of class EditBoxSizer class wxGladeStaticBoxSizer(wx.StaticBoxSizer): def SetItemMinSize(self, item, w, h): try: w2, h2 = item.GetBestSize() if w == -1: w = w2 if h == -1: h = h2 except AttributeError: pass wx.StaticBoxSizer.SetItemMinSize(self, item, w, h) # end of class wxGladeStaticBoxSizer class EditStaticBoxSizer(SizerBase): """\ Class to handle wxStaticBoxSizer objects """ def __init__(self, name, window, orient=wx.VERTICAL, label='', elements=3, toplevel=True, show=True): self.label = label self.orient = orient SizerBase.__init__(self, name, 'wxStaticBoxSizer', window, toplevel, show) self.access_functions['orient'] = (self.get_orient, self.set_orient) self.properties['orient'] = HiddenProperty( self, 'orient', (orient==wx.HORIZONTAL and 'wxHORIZONTAL' or 'wxVERTICAL'), ) class Dummy: widget = None # add to self.children the SizerItem for self._btn self.children = [SizerItem(Dummy(), 0, 0, wx.EXPAND)] for i in range(1, elements+1): tmp = SizerSlot(self.window, self, i) self.children.append(SizerItem(tmp, i, 1, wx.EXPAND)) def create_widget(self): self.widget = wxGladeStaticBoxSizer(wx.StaticBox(self.window.widget, -1, self.label), self.orient) self.widget.Add(self._btn, 0, wx.EXPAND) for c in self.children[1:]: # we've already added self._btn c.item.show_widget(True) if isinstance(c.item, SizerSlot): self.widget.Add(c.item.widget, 1, wx.EXPAND) self.widget.SetItemMinSize(c.item.widget, 20, 20) else: sp = c.item.properties.get('size') if sp and sp.is_active() and \ (c.option == 0 or not (c.flag & wx.EXPAND)): size = sp.get_value().strip() if size[-1] == 'd': size = size[:-1] use_dialog_units = True else: use_dialog_units = False w, h = [ int(v) for v in size.split(',') ] if use_dialog_units: w, h = wx.DLG_SZE(c.item.widget, (w, h)) else: w, h = c.item.widget.GetBestSize() self.widget.SetItemMinSize(c.item.widget, w, h) self.layout() if not self.toplevel and getattr(self, 'sizer'): # getattr(self, 'sizer') is False only in case of a 'change_sizer' # call self.sizer.add_item(self, self.pos, self.option, self.flag, self.border, self.widget.GetMinSize()) def _property_setup(self): SizerBase._property_setup(self) self.access_functions['label'] = (self.get_label, self.set_label) lbl = self.properties['label'] = TextProperty(self, 'label', None, label=_("label")) def write(outfile, tabs): import widget_properties outfile.write(' ' * tabs + '\n') # we must consider also "" a valid value lbl.write = write def create_properties(self): SizerBase.create_properties(self) panel = self.notebook.GetPage(0) sizer = panel.GetSizer() self.properties['label'].display(panel) sizer.Add(self.properties['label'].panel, 0, wx.EXPAND) sizer.Layout() w, h = sizer.GetMinSize() panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def set_label(self, value): """\ Sets the label of the static box """ self.label = misc.wxstr(value) if self.widget: self.widget.GetStaticBox().SetLabel(self.label) self.layout() def get_label(self): return self.label def delete(self): if self.widget: self.widget.GetStaticBox().Destroy() SizerBase.delete(self) def get_orient(self): od = { wx.HORIZONTAL: 'wxHORIZONTAL', wx.VERTICAL: 'wxVERTICAL' } return od.get(self.orient) def set_orient(self, value): od = { 'wxHORIZONTAL': wx.HORIZONTAL, 'wxVERTICAL': wx.VERTICAL } self.orient = od.get(value, wx.VERTICAL) # end of class EditStaticBoxSizer class CustomSizer(wx.BoxSizer): """\ Custom wxSizer class used to implement a GridSizer with an additional handle button """ def __init__(self, parent, factory, rows, cols, vgap, hgap): wx.BoxSizer.__init__(self, wx.VERTICAL) self.parent = parent self._grid = factory(rows, cols, vgap, hgap) wx.BoxSizer.Add(self, self.parent._btn, 0, wx.EXPAND) wx.BoxSizer.Add(self, self._grid, 1, wx.EXPAND) def __getattr__(self, name): return getattr(self._grid, name) def GetBestSize(self): return self._grid.GetMinSize() def Add(self, *args, **kwds): self._grid.Add(*args, **kwds) def Insert(self, pos, *args, **kwds): self._grid.Insert(pos-1, *args, **kwds) def Remove(self, *args, **kwds): try: pos = int(args[0])-1 self._grid.Remove(pos) except TypeError: self._grid.Remove(*args, **kwds) def RemovePos(self, pos): self._grid.Remove(pos-1) def Detach(self, pos_or_obj): try: pos = int(pos_or_obj) - 1 self._grid.Detach(pos) except TypeError: self._grid.Detach(pos_or_obj) def SetItemMinSize(self, item, w, h): #*args, **kwds): try: w2, h2 = item.GetBestSize() if w == -1: w = w2 if h == -1: h = h2 except AttributeError: pass self._grid.SetItemMinSize(item, w, h) def GetChildren(self): return [None] + list(self._grid.GetChildren()) def Layout(self): self._grid.Layout() wx.BoxSizer.Layout(self) # end of class CustomSizer class GridSizerBase(SizerBase): """\ Base class for Grid sizers. Must not be instantiated. """ def __init__(self, name, klass, window, rows=3, cols=3, vgap=0, hgap=0, toplevel=True, show=True): self.rows = rows; self.cols = cols self.vgap = vgap; self.hgap = hgap if self.cols or self.rows: if not self.rows: self.rows = 1 elif not self.cols: self.cols = 1 menu = [(_('Add slot'), self.add_slot), (_('Insert slot...'), self.insert_slot), (_('Add row'), self.add_row), (_('Add column'), self.add_col), (_('Insert row...'), self.insert_row), (_('Insert column...'), self.insert_col)] SizerBase.__init__(self, name, klass, window, toplevel, show, menu) class Dummy: widget = None # add to self.children the SizerItem for self._btn self.children = [SizerItem(Dummy(), 0, 0, wx.EXPAND)] for i in range(1, self.rows*self.cols+1): tmp = SizerSlot(self.window, self, i) self.children.append(SizerItem(tmp, i, 1, wx.EXPAND)) def create_widget(self): """\ This must be overriden and called at the end of the overriden version """ to_lay_out = [] for c in self.children[1:]: # we've already added self._btn c.item.show_widget(True) if isinstance(c.item, SizerSlot): self.widget.Add(c.item.widget, 1, wx.EXPAND) self.widget.SetItemMinSize(c.item.widget, 20, 20) else: sp = c.item.properties.get('size') if sp and sp.is_active(): if (c.option != 0 or (c.flag & wx.EXPAND)) and \ not (c.flag & wx.FIXED_MINSIZE): c.item.widget.Layout() w, h = c.item.widget.GetBestSize() c.item.widget.SetMinSize((w, h)) else: size = sp.get_value().strip() if size[-1] == 'd': size = size[:-1] use_dialog_units = True else: use_dialog_units = False w, h = [ int(v) for v in size.split(',') ] if use_dialog_units: w, h = wx.DLG_SZE(c.item.widget, (w, h)) # now re-set the item to update the size correctly... to_lay_out.append((c.item.pos, (w, h))) ## sp = c.item.properties.get('size') ## if sp and sp.is_active() and \ ## (c.option == 0 or not (c.flag & wxEXPAND)): ## size = sp.get_value().strip() ## if size[-1] == 'd': ## size = size[:-1] ## use_dialog_units = True ## else: use_dialog_units = False ## w, h = [ int(v) for v in size.split(',') ] ## if use_dialog_units: ## w, h = wxDLG_SZE(c.item.widget, (w, h)) ## else: ## w, h = c.item.widget.GetBestSize() ## self.widget.SetItemMinSize(c.item.widget, w, h) for pos, size in to_lay_out: #print 'set_item:', pos, size self.set_item(pos, size=size, force_layout=False) self.layout(True) def _property_setup(self): SizerBase._property_setup(self) self.access_functions['rows'] = (self.get_rows, self.set_rows) self.access_functions['cols'] = (self.get_cols, self.set_cols) self.access_functions['hgap'] = (self.get_hgap, self.set_hgap) self.access_functions['vgap'] = (self.get_vgap, self.set_vgap) props = { 'rows': SpinProperty(self, 'rows', None, label=_("rows")), 'cols': SpinProperty(self, 'cols', None, label=_("cols")), 'hgap': SpinProperty(self, 'hgap', None, label=_("hgap")), 'vgap': SpinProperty(self, 'vgap', None, label=_("vgap")) } props['rows'].set_tooltip(_('Numbers of sizer rows')) props['cols'].set_tooltip(_('Numbers of sizer columns')) props['vgap'].set_tooltip( _('Vertical extra space between all children') ) props['hgap'].set_tooltip( _('Horizontal extra space between all children') ) self.properties.update(props) def create_properties(self): SizerBase.create_properties(self) page = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) sizer = wx.BoxSizer(wx.VERTICAL) props = self.properties props['rows'].display(page) props['cols'].display(page) props['vgap'].display(page) props['hgap'].display(page) sizer.Add(props['rows'].panel, 0, wx.EXPAND) sizer.Add(props['cols'].panel, 0, wx.EXPAND) sizer.Add(props['vgap'].panel, 0, wx.EXPAND) sizer.Add(props['hgap'].panel, 0, wx.EXPAND) page.SetAutoLayout(True) page.SetSizer(sizer) sizer.Fit(page) self.notebook.AddPage(page, _("Grid")) def get_rows(self): return self.rows def get_cols(self): return self.cols def get_vgap(self): return self.vgap def get_hgap(self): return self.hgap def _set_rows_cols(self, rows, cols): self.rows = rows self.cols = cols self.properties['rows'].set_value(rows) self.properties['cols'].set_value(cols) if self.widget: self.widget.SetRows(self.rows) self.widget.SetCols(self.cols) self.layout(True) def set_rows(self, rows): self.rows = int(rows) if self.widget: self.widget.SetRows(self.rows) self.layout(True) def set_cols(self, cols): self.cols = int(cols) if self.widget: self.widget.SetCols(self.cols) self.layout(True) def set_hgap(self, hgap): self.hgap = int(hgap) if self.widget: self.widget.SetHGap(self.hgap) self.layout() def set_vgap(self, vgap): self.vgap = int(vgap) if self.widget: self.widget.SetVGap(self.vgap) self.layout() def fit_parent(self, *args): """\ Tell the sizer to resize the window to match the sizer's minimal size """ if self.widget and self.window.widget: self.widget.Fit(self.window.widget) self.widget.SetSizeHints(self.window.widget) def insert_slot(self, *args, **kwds): """\ inserts a slot into the sizer: the user will be asked for a position before which to insert the SizerSlot object """ if not self.widget: return if kwds.get('interactive', True): dialog = InsertDialog(len(self.children)) ok = dialog.ShowModal() == wx.ID_OK pos = dialog.pos+1 dialog.Destroy() else: pos = kwds['pos'] ok = True if ok: tmp = SizerSlot(self.window, self, pos) for c in self.children[pos:]: c.item.pos += 1 self.children.insert(pos, SizerItem(tmp, pos, 1, wx.EXPAND, 0)) tmp.show_widget(True) # create the actual SizerSlot self.widget.Insert(pos, tmp.widget, 1, wx.EXPAND) self.widget.SetItemMinSize(tmp.widget, 20, 20) force_layout = kwds.get('force_layout', True) if force_layout: self.layout(True) common.app_tree.app.saved = False def add_row(self, *args, **kwds): if not self.widget: return self._insert_row(self.widget.GetRows()+1) def insert_row(self, *args): if not self.widget: return dialog = InsertDialog(self.widget.GetRows()) if dialog.ShowModal() == wx.ID_OK: self._insert_row(dialog.pos + 1) dialog.Destroy() def _insert_row(self, pos): rows = self.widget.GetRows() cols = self.widget.GetCols() pos = (pos-1) * cols + 1 if pos >= len(self.children): # fix the out of bounds index... tot = len(self.children) - 1 rows = tot / cols if tot % cols: rows += 1 # print 'fixed rows:', rows if rows * cols > tot: for i in range(rows * cols - tot): self.insert_slot(interactive=False, pos=tot+i+1, force_layout=False) pos = rows * cols + 1 self.set_rows(rows+1) for i in range(cols): self.insert_slot(interactive=False, pos=pos+i, force_layout=False) self.properties['rows'].set_value(self.rows) self.layout(True) common.app_tree.app.saved = False def add_col(self, *args, **kwds): if not self.widget: return self._insert_col(self.widget.GetCols()+1) def insert_col(self, *args): if not self.widget: return dialog = InsertDialog(self.widget.GetCols()) if dialog.ShowModal() == wx.ID_OK: self._insert_col(dialog.pos + 1) dialog.Destroy() def _insert_col(self, pos): rows = self.widget.GetRows() cols = self.widget.GetCols() if pos >= len(self.children): # fix the out of bounds index... tot = len(self.children) - 1 cols = tot / rows if tot % rows: cols += 1 # print 'fixed cols:', cols if rows * cols > tot: for i in range(rows * cols - tot): self.insert_slot(interactive=False, pos=tot+i+1, force_layout=False) pos = rows * cols + 1 self.set_cols(cols+1) for i in range(rows): self.insert_slot(interactive=False, pos=pos + self.cols * i, #pos=cols + self.cols * i, force_layout=False) self.properties['cols'].set_value(self.cols) self.layout(True) common.app_tree.app.saved = False def _set_item_widget(self, pos, option, flag, border, size, force_layout): if not self.widget: return try: elem = self.widget.GetChildren()[pos] except IndexError: return # this may happen during xml loading if option is not None: elem.SetProportion(option) if flag is not None: elem.SetFlag(flag) if border is not None: elem.SetBorder(border) if elem.IsWindow(): if size is None: size = elem.GetSize() item = elem.GetWindow() w, h = size if w == -1: w = item.GetBestSize()[0] if h == -1: h = item.GetBestSize()[1] self.widget.SetItemMinSize(item, w, h) if force_layout: self.layout(True) #try: self.sizer.Layout() #except AttributeError: pass # end of class GridSizerBase class EditGridSizer(GridSizerBase): """\ Class to handle wxGridSizer objects """ def __init__(self, name, window, rows=3, cols=3, vgap=0, hgap=0, toplevel=True, show=True): GridSizerBase.__init__(self, name, 'wxGridSizer', window, rows, cols, vgap, hgap, toplevel, show) def create_widget(self): self.widget = CustomSizer(self, wx.GridSizer, self.rows, self.cols, self.vgap, self.hgap) if not self.toplevel and getattr(self, 'sizer', None): # getattr(self, 'sizer') is False only in case of a 'change_sizer' # call self.sizer.add_item(self, self.pos, self.option, self.flag, self.border) #, self.widget.GetMinSize()) GridSizerBase.create_widget(self) # end of class EditGridSizer class CheckListDialogProperty(DialogProperty): dialog = [None] def __init__(self, owner, name, parent, title, message, callback, can_disable=True): self.title = title self.message = message if not self.dialog[0]: class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, parent, -1, title) sizer = wx.BoxSizer(wx.VERTICAL) self.message = wx.StaticText(self, -1, "") sizer.Add(self.message, 0, wx.TOP|wx.LEFT|wx.RIGHT|wx.EXPAND, 10) self.choices = wx.CheckListBox(self, -1, choices=['dummy']) sizer.Add(self.choices, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 10) sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 10) sz2 = wx.BoxSizer(wx.HORIZONTAL) sz2.Add(wx.Button(self, wx.ID_OK, ""), 0, wx.ALL, 10) sz2.Add(wx.Button(self, wx.ID_CANCEL, ""), 0, wx.ALL, 10) sizer.Add(sz2, 0, wx.ALIGN_CENTER) self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) self.CenterOnScreen() def get_value(self): ret = [] for c in range(self.choices.GetCount()): if self.choices.IsChecked(c): ret.append(str(c)) return ",".join(ret) def set_choices(self, values): if wx.Platform != '__WXGTK__': self.choices.Set(values) else: self.choices.Clear() for v in values: self.choices.Append(v) def set_descriptions(self, title, message): self.SetTitle(title) self.message.SetLabel(message) # end of class Dialog self.dialog[0] = Dialog() DialogProperty.__init__(self, owner, name, parent, self.dialog[0], can_disable, label=title) self.choices_setter = callback def display_dialog(self, event): self.set_choices(self.choices_setter()) self.dialog.set_descriptions(self.title, self.message) DialogProperty.display_dialog(self, event) def set_choices(self, values): self.dialog.set_choices(values) # end of class CheckListDialogProperty class EditFlexGridSizer(GridSizerBase): """\ Class to handle wxFlexGridSizer objects """ def __init__(self, name, window, rows=3, cols=3, vgap=0, hgap=0, toplevel=True, show=True): GridSizerBase.__init__(self, name, 'wxFlexGridSizer', window, rows, cols, vgap, hgap, toplevel, show) def create_widget(self): self.widget = CustomSizer(self, wx.FlexGridSizer, self.rows, self.cols, self.vgap, self.hgap) GridSizerBase.create_widget(self) for r in self.grow_rows: self.widget.AddGrowableRow(r) for c in self.grow_cols: self.widget.AddGrowableCol(c) if not self.toplevel and getattr(self, 'sizer', None) is not None: # hasattr(self, 'sizer') is False only in case of a 'change_sizer' # call self.sizer.add_item(self, self.pos, self.option, self.flag, self.border) def _property_setup(self): GridSizerBase._property_setup(self) self.grow_rows = [] self.access_functions['growable_rows'] = (self.get_growable_rows, self.set_growable_rows) self.grow_cols = [] self.access_functions['growable_cols'] = (self.get_growable_cols, self.set_growable_cols) def rows_setter(): return map(str, range(self.get_rows())) pr = CheckListDialogProperty(self, 'growable_rows', None, _('Growable Rows'), _('Select growable rows'), rows_setter) self.properties['growable_rows'] = pr def cols_setter(): return map(str, range(self.get_cols())) pr = CheckListDialogProperty(self, 'growable_cols', None, _('Growable Columns'), _('Select growable columns'), cols_setter) self.properties['growable_cols'] = pr def create_properties(self): GridSizerBase.create_properties(self) page = self.notebook.GetPage(1) sizer = page.GetSizer() props = self.properties props['growable_rows'].display(page) props['growable_cols'].display(page) sizer.Add(props['growable_rows'].panel, 0, wx.EXPAND) sizer.Add(props['growable_cols'].panel, 0, wx.EXPAND) sizer.Layout() sizer.Fit(page) def set_growable_rows(self, value): try: self.grow_rows = [int(i) for i in value.split(',')] except: if not value.strip(): self.grow_rows = [] else: self.properties['growable_rows'].set_value( self.get_growable_rows()) return if self.widget: if self.notebook: page = self.notebook.GetSelection() else: page = 0 wx.CallAfter(change_sizer, self, self.klass_prop.get_value(), page) def set_growable_cols(self, value): try: self.grow_cols = [int(i) for i in value.split(',')] except: if not value.strip(): self.grow_cols = [] else: self.properties['growable_cols'].set_value( self.get_growable_cols()) return if self.widget: if self.notebook: page = self.notebook.GetSelection() else: page = 0 wx.CallAfter(change_sizer, self, self.klass_prop.get_value(), page) def get_growable_rows(self): return ','.join(map(str, self.grow_rows)) def get_growable_cols(self): return ','.join(map(str, self.grow_cols)) def _insert_row(self, pos): for i in range(len(self.grow_rows)): if self.grow_rows[i] >= pos-1: self.grow_rows[i] += 1 GridSizerBase._insert_row(self, pos) self.set_growable_rows(self.get_growable_rows()) def _insert_col(self, pos): for i in range(len(self.grow_cols)): if self.grow_cols[i] >= pos-1: self.grow_cols[i] += 1 GridSizerBase._insert_col(self, pos) self.set_growable_cols(self.get_growable_cols()) # end of class EditFlexGridSizer def _builder(parent, sizer, pos, orientation=wx.VERTICAL, slots=1, is_static=False, label="", number=[1], show=True): num = slots name = 'sizer_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'sizer_%d' % number[0] if sizer is not None: topl = 0 else: topl = 1 if is_static: sz = EditStaticBoxSizer(name, parent, orientation, label, num, topl) else: sz = EditBoxSizer(name, parent, orientation, num, topl) if sizer is not None: sizer.add_item(sz, pos, 1, wx.EXPAND) node = Tree.Node(sz) sz.node = node common.app_tree.insert(node, sizer.node, pos-1) common.adding_sizer = False else: parent.set_sizer(sz) node = Tree.Node(sz) sz.node = node if pos is None: common.app_tree.add(node, parent.node) else: common.app_tree.insert(node, parent.node, pos-1) sz.pos = pos sz.show_widget(show) if sizer is not None: sz.sizer_properties['flag'].set_value('wxEXPAND') sz.sizer_properties['pos'].set_value(pos-1) def builder(parent, sizer, pos, number=[1], show=True): """\ factory function for box sizers. """ class SizerDialog(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, misc.get_toplevel_parent(parent), -1, _('Select sizer type')) self.orientation = wx.RadioBox(self, -1, _('Orientation'), choices=[_('Horizontal'), _('Vertical')]) self.orientation.SetSelection(0) tmp = wx.BoxSizer(wx.HORIZONTAL) tmp.Add(wx.StaticText(self, -1, _('Slots: ')), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) self.num = wx.SpinCtrl(self, -1) self.num.SetRange(1, 100) self.num.SetValue(1) tmp.Add(self.num, 1, wx.ALL, 3) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.orientation, 0, wx.ALL|wx.EXPAND, 4) szr.Add(tmp, 0, wx.EXPAND) CHECK_ID = wx.NewId() self.check = wx.CheckBox(self, CHECK_ID, _('Has a Static Box')) self.label = wx.TextCtrl(self, -1, "") self.label.Enable(False) wx.EVT_CHECKBOX(self, CHECK_ID, self.on_check_statbox) szr.Add(self.check, 0, wx.ALL|wx.EXPAND, 4) tmp = wx.BoxSizer(wx.HORIZONTAL) tmp.Add(wx.StaticText(self, -1, _("Label: ")), 0, wx.ALIGN_CENTER) tmp.Add(self.label, 1) szr.Add(tmp, 0, wx.ALL|wx.EXPAND, 4) btn = wx.Button(self, wx.ID_OK, _('OK')) btn.SetDefault() szr.Add(btn, 0, wx.ALL|wx.ALIGN_CENTER, 10) self.SetAutoLayout(1) self.SetSizer(szr) szr.Fit(self) self.Layout() self.CenterOnScreen() def reset(self): self.orientation.SetSelection(0) self.num.SetValue(1) self.check.SetValue(0) self.label.SetValue("") self.label.Enable(False) def on_check_statbox(self, event): self.label.Enable(event.IsChecked()) # end of class SizerDialog dialog = SizerDialog(parent) dialog.ShowModal() if dialog.orientation.GetStringSelection() == _('Horizontal'): orientation = wx.HORIZONTAL else: orientation = wx.VERTICAL num = dialog.num.GetValue() _builder(parent, sizer, pos, orientation, num, dialog.check.GetValue(), dialog.label.GetValue()) dialog.Destroy() def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory function to build EditBoxSizer objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") orientation = wx.VERTICAL # default value if sizer is not None: topl = False else: topl = True if attrs['base'] == 'EditStaticBoxSizer': sz = EditStaticBoxSizer(name, parent, orientation, '', 0, topl) else: sz = EditBoxSizer(name, parent, orientation, 0, topl) if sizer is not None: if sizeritem is None: raise XmlParsingError, _("'sizeritem' object not found") sizer.add_item(sz, pos=pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(sz) sz.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) else: parent.set_sizer(sz) node = Tree.Node(sz) sz.node = node common.app_tree.add(node, parent.node) return sz def grid_builder(parent, sizer, pos, number=[1], show=True): """\ factory function for grid sizers """ class Dialog(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, misc.get_toplevel_parent(parent), -1, _('Select sizer attributes')) self.rows = SpinProperty(self, 'rows', self, label=_("rows")) self.cols = SpinProperty(self, 'cols', self, label=_("cols")) self.vgap = SpinProperty(self, 'vgap', self, label=_("vgap")) self.hgap = SpinProperty(self, 'hgap', self, label=_("hgap")) self.rows.set_tooltip(_('Numbers of sizer rows')) self.cols.set_tooltip(_('Numbers of sizer columns')) self.vgap.set_tooltip( _('Vertical extra space between all children') ) self.hgap.set_tooltip( _('Horizontal extra space between all children') ) self.rows.spin.SetFocus() self.rows.spin.SetSelection(-1, -1) self.flex = CheckBoxProperty( self, 'flex', self, _('Flexible'), write_always=True, ) self.flex.set_tooltip( _('Create a wxFlexGridSizer instead of a wxGridSizer') ) self.rows.set_value(3) self.cols.set_value(3) self.vgap.set_value(0) self.hgap.set_value(0) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.rows.panel, 0, wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 10) sizer.Add(self.cols.panel, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 10) sizer.Add(self.vgap.panel, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 10) sizer.Add(self.hgap.panel, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 10) sizer.Add(self.flex.panel, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 10) szr = wx.BoxSizer(wx.HORIZONTAL) btn = wx.Button(self, wx.ID_OK, _('OK')) btn.SetDefault() szr.Add(btn) sizer.Add(szr, 0, wx.ALL|wx.ALIGN_CENTER, 10) self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) self.Layout() self.CentreOnParent() def __getitem__(self, name): return (lambda : 0, lambda v: None) # end of inner class dialog = Dialog(parent) dialog.ShowModal() rows = int(dialog.rows.get_value()) cols = int(dialog.cols.get_value()) vgap = int(dialog.vgap.get_value()) hgap = int(dialog.hgap.get_value()) name = 'grid_sizer_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'grid_sizer_%d' % number[0] topl = True if dialog.flex.get_value(): constructor = EditFlexGridSizer else: constructor = EditGridSizer if sizer is not None: topl = False sz = constructor(name, parent, rows, cols, vgap, hgap, topl) if sizer is not None: sizer.add_item(sz, pos, 1, wx.EXPAND) node = Tree.Node(sz) sz.node = node common.app_tree.insert(node, sizer.node, pos-1) common.adding_sizer = False else: parent.set_sizer(sz) node = Tree.Node(sz) sz.node = node if pos is None: common.app_tree.add(node, parent.node) else: common.app_tree.insert(node, parent.node, pos-1) sz.pos = pos sz.show_widget(show) #True) if sizer is not None: sz.sizer_properties['flag'].set_value('wxEXPAND') sz.sizer_properties['pos'].set_value(pos-1) dialog.Destroy() def grid_xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory function to build EditGridSizer objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if attrs['base'] == 'EditGridSizer': constructor = EditGridSizer else: constructor = EditFlexGridSizer if sizer is not None: sz = constructor(name, parent, rows=0, cols=0, toplevel=False) if sizeritem is None: raise XmlParsingError, _("'sizeritem' object not found") sizer.add_item(sz, pos=pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(sz) sz.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) else: sz = constructor(name, parent, rows=0, cols=0, toplevel=True) parent.set_sizer(sz) node = Tree.Node(sz) sz.node = node common.app_tree.add(node, parent.node) return sz def init_all(): """\ module initialization function: returns a list of buttons (to add to the main palette) to add the various sizers """ cw = common.widgets cw['EditBoxSizer'] = builder cw['EditGridSizer'] = grid_builder cwx = common.widgets_from_xml cwx['EditBoxSizer'] = xml_builder cwx['EditStaticBoxSizer'] = xml_builder cwx['EditGridSizer'] = grid_xml_builder cwx['EditFlexGridSizer'] = grid_xml_builder import os.path WidgetTree.images['EditStaticBoxSizer'] = os.path.join( common.icons_path, 'sizer.xpm' ) WidgetTree.images['EditFlexGridSizer'] = os.path.join( common.icons_path, 'grid_sizer.xpm' ) return [common.make_object_button('EditBoxSizer', 'icons/sizer.xpm'), common.make_object_button('EditGridSizer', 'icons/grid_sizer.xpm')] wxglade-0.6.8.orig/edit_sizers/sizers_codegen.py0000644000175000017500000001364712150154266022233 0ustar georgeskgeorgesk""" Code generation functions for the various wxSizerS @copyright: 2002-2007 Alberto Griggio @copyright: 2013 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import common from edit_sizers import BaseSizerBuilder class BasePythonSizerBuilder(BaseSizerBuilder): """\ Python base class for all sizer code generators """ language = 'python' tmpl_SetSizer = '%(parent_widget)s.SetSizer(%(sizer_name)s)\n' tmpl_Fit = '%(sizer_name)s.Fit(%(parent_widget)s)\n' tmpl_SetSizeHints = '%(sizer_name)s.SetSizeHints(%(parent_widget)s)\n' tmpl_StaticBox = 'self.%s_staticbox' def _get_wparent(self, obj): if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' return parent # end of class BasePythonSizerBuilder class BaseCPPSizerBuilder(BaseSizerBuilder): """\ C++ base class for all sizer code generators """ language = 'C++' tmpl_SetSizer = '%(parent_ref)sSetSizer(%(sizer_name)s);\n' tmpl_Fit = '%(sizer_name)s->Fit(%(parent_widget)s);\n' tmpl_SetSizeHints = '%(sizer_name)s->SetSizeHints(%(parent_widget)s);\n' tmpl_StaticBox = '%s_staticbox' def _get_wparent(self, obj): if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' return parent def _get_parent_ref(self, obj): if not obj.parent.is_toplevel: parent_ref = '%s->' % obj.parent.name else: parent_ref = '' return parent_ref def _get_code(self, obj): self.props_get_code['parent_ref'] = self._get_parent_ref(obj) result = BaseSizerBuilder._get_code(self, obj) # get_code() for C++ has different return values result = list(result) result.insert(2, []) return result # end of class BaseCPPSizerBuilder class PythonBoxSizerBuilder(BasePythonSizerBuilder): klass = 'wxBoxSizer' init_stmt = [ '%(sizer_name)s = %(klass)s(%(orient)s)\n', ] # end of class PythonBoxSizerBuilder class PythonStaticBoxSizerBuilder(BasePythonSizerBuilder): klass = 'wxStaticBoxSizer' init_stmt = [ '%(staticbox_name)s = %(wxStaticBox)s(%(parent_widget)s, ' '%(wxIDANY)s, %(label)s)\n', '%(sizer_name)s = %(klass)s(%(staticbox_name)s, %(orient)s)\n', '%(staticbox_name)s.Lower()\n', ] # end of class PythonStaticBoxSizerBuilder class PythonGridSizerBuilder(BasePythonSizerBuilder): klass = 'wxGridSizer' init_stmt = [ '%(sizer_name)s = %(klass)s(%(rows)s, %(cols)s, ' '%(vgap)s, %(hgap)s)\n', ] # end of class PythonGridSizerBuilder class PythonFlexGridSizerBuilder(PythonGridSizerBuilder): klass = 'wxFlexGridSizer' tmpl_AddGrowableRow = '%(sizer_name)s.AddGrowableRow(%(row)s)\n' tmpl_AddGrowableCol = '%(sizer_name)s.AddGrowableCol(%(col)s)\n' # end of class PythonFlexGridSizerBuilder class CppBoxSizerBuilder(BaseCPPSizerBuilder): klass = 'wxBoxSizer' init_stmt = [ '%(klass)s* %(sizer_name)s = new %(klass)s(%(orient)s);\n', ] # end of class CppBoxSizerBuilder class CppStaticBoxSizerBuilder(BaseCPPSizerBuilder): klass = 'wxStaticBoxSizer' init_stmt = [ '%(staticbox_name)s = new wxStaticBox(%(parent_widget)s, ' 'wxID_ANY, %(label)s);\n', '%(klass)s* %(sizer_name)s = new %(klass)s(%(staticbox_name)s, ' '%(orient)s);\n', '%(staticbox_name)s->Lower();\n' ] # end of class CppStaticBoxSizerBuilder class CppGridSizerBuilder(BaseCPPSizerBuilder): klass = 'wxGridSizer' init_stmt = [ '%(klass)s* %(sizer_name)s = new %(klass)s(%(rows)s, %(cols)s, ' '%(vgap)s, %(hgap)s);\n', ] # end of class CppGridSizerBuilder class CppFlexGridSizerBuilder(CppGridSizerBuilder): klass = 'wxFlexGridSizer' tmpl_AddGrowableRow = '%(sizer_name)s->AddGrowableRow(%(row)s);\n' tmpl_AddGrowableCol = '%(sizer_name)s->AddGrowableCol(%(col)s);\n' # end of class CppFlexGridSizerBuilder def xrc_wxFlexGridSizer_builder(obj): xrcgen = common.code_writers['XRC'] class FlexGridSizerXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if val and name in ('growable_rows', 'growable_cols'): if name == 'growable_rows': name2 = 'growablerows' else: name2 = 'growablecols' outfile.write(' ' * tabs + '<%s>%s\n' % (name2, val, name2)) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class FlexGridSizerXrcObject return FlexGridSizerXrcObject(obj) def initialize(): cn = common.class_names cn['EditBoxSizer'] = 'wxBoxSizer' cn['EditStaticBoxSizer'] = 'wxStaticBoxSizer' cn['EditGridSizer'] = 'wxGridSizer' cn['EditFlexGridSizer'] = 'wxFlexGridSizer' pygen = common.code_writers.get("python") if pygen: awh = pygen.add_widget_handler awh('wxBoxSizer', PythonBoxSizerBuilder()) awh('wxStaticBoxSizer', PythonStaticBoxSizerBuilder()) awh('wxGridSizer', PythonGridSizerBuilder()) awh('wxFlexGridSizer', PythonFlexGridSizerBuilder()) cppgen = common.code_writers.get("C++") if cppgen: awh = cppgen.add_widget_handler awh('wxBoxSizer', CppBoxSizerBuilder()) awh('wxStaticBoxSizer', CppStaticBoxSizerBuilder()) awh('wxGridSizer', CppGridSizerBuilder()) awh('wxFlexGridSizer', CppFlexGridSizerBuilder()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxFlexGridSizer', xrc_wxFlexGridSizer_builder) wxglade-0.6.8.orig/edit_sizers/perl_sizers_codegen.py0000644000175000017500000000504712150160715023244 0ustar georgeskgeorgesk""" Perl generator functions for the various wxSizerS @copyright: 2002-2004 D.H. aka crazyinsomniac on sourceforge.net @copyright: 2013 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import common from edit_sizers import BaseSizerBuilder class BasePerlSizerBuilder(BaseSizerBuilder): """\ Perl base class for all sizer code generators """ language = 'perl' tmpl_SetSizer = '%(parent_widget)s->SetSizer(%(sizer_name)s);\n' tmpl_Fit = '%(sizer_name)s->Fit(%(parent_widget)s);\n' tmpl_SetSizeHints = '%(sizer_name)s->SetSizeHints(' \ '%(parent_widget)s);\n' tmpl_StaticBox = '$self->{%s_staticbox}' def _get_wparent(self, obj): if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' return parent # end of class BasePerlSizerBuilder class PerlBoxSizerBuilder(BasePerlSizerBuilder): klass = 'wxBoxSizer' init_stmt = [ '%(sizer_name)s = %(klass)s->new(%(orient)s);\n' ] # end of class PerlBoxSizerBuilder class PerlStaticBoxSizerBuilder(BasePerlSizerBuilder): klass = 'wxStaticBoxSizer' init_stmt = [ '%(staticbox_name)s = %(wxStaticBox)s->new(' '%(parent_widget)s, wxID_ANY, %(label)s );\n', '%(sizer_name)s = %(klass)s->new(%(staticbox_name)s, %(orient)s);\n', '%(staticbox_name)s->Lower();\n', ] # end of class PerlStaticBoxSizerBuilder class PerlGridSizerBuilder(BasePerlSizerBuilder): klass = 'wxGridSizer' init_stmt = [ '%(sizer_name)s = %(klass)s->new(%(rows)s, %(cols)s, ' '%(vgap)s, %(hgap)s);\n' ] # end of class PerlGridSizerBuilder class PerlFlexGridSizerBuilder(PerlGridSizerBuilder): klass = 'wxFlexGridSizer' tmpl_AddGrowableRow = '%(sizer_name)s->AddGrowableRow(%(row)s);\n' tmpl_AddGrowableCol = '%(sizer_name)s->AddGrowableCol(%(col)s);\n' # end of class PerlFlexGridSizerBuilder def initialize(): cn = common.class_names cn['EditBoxSizer'] = 'wxBoxSizer' cn['EditStaticBoxSizer'] = 'wxStaticBoxSizer' cn['EditGridSizer'] = 'wxGridSizer' cn['EditFlexGridSizer'] = 'wxFlexGridSizer' plgen = common.code_writers.get("perl") if plgen: awh = plgen.add_widget_handler awh('wxBoxSizer', PerlBoxSizerBuilder()) awh('wxStaticBoxSizer', PerlStaticBoxSizerBuilder()) awh('wxGridSizer', PerlGridSizerBuilder()) awh('wxFlexGridSizer', PerlFlexGridSizerBuilder()) wxglade-0.6.8.orig/edit_sizers/__init__.py0000644000175000017500000000146512150154266020762 0ustar georgeskgeorgesk""" Sizers module initialization @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ Sizer = None """\ Shortcut for L{edit_sizers.Sizer} """ SizerSlot = None """\ Shortcut for L{edit_sizers.SizerSlot} """ SizerBase = None """\ Shortcut for L{edit_sizers.SizerBase} """ _builder = None """\ Shortcut for L{edit_sizers._builder} """ def init_all(): import sizers_codegen sizers_codegen.initialize() import common if common.use_gui: import edit_sizers global Sizer, SizerSlot, SizerBase, _builder Sizer = edit_sizers.Sizer SizerSlot = edit_sizers.SizerSlot SizerBase = edit_sizers.SizerBase _builder = edit_sizers._builder return edit_sizers.init_all() wxglade-0.6.8.orig/widgets/0000755000175000017500000000000012170277707015775 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/calendar_ctrl/0000755000175000017500000000000012170277707020572 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/calendar_ctrl/perl_codegen.py0000644000175000017500000000240312150154266023561 0ustar georgeskgeorgesk""" Perl generator functions for wxCalendarCtrl objects @copyright: 2012 Eric McKeeth @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not(style): style = '' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, Wx::DateTime->new, \ wxDefaultPosition, wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, style)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] #end of code generator def initialize(): common.class_names['EditCalendarCtrl'] = 'wxCalendarCtrl' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxCalendarCtrl', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/calendar_ctrl/calendar_ctrl.py0000644000175000017500000001404512150154266023735 0ustar georgeskgeorgesk# calendar_ctrl.py: wxCalendarCtrl objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx from edit_windows import ManagedBase from tree import Tree import common from widget_properties import * #import needed modules for the wxCalendarCtrl from wx.calendar import * class EditCalendarCtrl(ManagedBase): events = [ 'EVT_CALENDAR', 'EVT_CALENDAR_SEL_CHANGED', 'EVT_CALENDAR_DAY', 'EVT_CALENDAR_MONTH', 'EVT_CALENDAR_YEAR', 'EVT_CALENDAR_WEEKDAY_CLICKED'] def __init__(self, name, parent, id, sizer, pos, property_window, show=True): """\ Class to handle wxCalendarCtrl objects """ import config self.default = False ManagedBase.__init__(self, name, 'wxCalendarCtrl', parent, id, sizer, pos, property_window, show=show) #self.access_functions['label'] = (self.get_label, self.set_label) #self.properties['label'] = TextProperty(self, 'label', None, # multiline=True) self.access_functions['default'] = (self.get_default, self.set_default) self.access_functions['style'] = (self.get_style, self.set_style) self.properties['default'] = CheckBoxProperty(self, 'default', None, label=_("default")) style_labels = ('#section#' + _('Style'), 'wxCAL_SUNDAY_FIRST', 'wxCAL_MONDAY_FIRST', 'wxCAL_SHOW_HOLIDAYS', 'wxCAL_NO_YEAR_CHANGE', 'wxCAL_NO_MONTH_CHANGE', 'wxCAL_SHOW_SURROUNDING_WEEKS','wxCAL_SEQUENTIAL_MONTH_SELECTION') self.style_pos = (CAL_SUNDAY_FIRST, CAL_MONDAY_FIRST, CAL_SHOW_HOLIDAYS, CAL_NO_YEAR_CHANGE, CAL_NO_MONTH_CHANGE, CAL_SHOW_SURROUNDING_WEEKS, CAL_SEQUENTIAL_MONTH_SELECTION) self.tooltips = (_("Show Sunday as the first day in the week"), _("Show Monday as the first day in the week"), _("Highlight holidays in the calendar"), _("Disable the year changing"), _("Disable the month (and, implicitly, the year) changing"), _("Show the neighbouring weeks in the previous and next months"), _("Use alternative, more compact, style for the month and year selection controls.")) self.properties['style'] = CheckListProperty(self, 'style', None, style_labels,tooltips=self.tooltips) if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) #self.properties['label'].display(panel) self.properties['default'].display(panel) self.properties['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) #szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['default'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(1) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def create_widget(self): try: #TODO add all the other parameters for the CalendarCtrl especialy style=self.style and the initial date self.widget = CalendarCtrl(self.parent.widget, self.id, style=self.style) except AttributeError: self.widget = CalendarCtrl(self.parent.widget, self.id) def get_default(self): return self.default def set_default(self, value): self.default = bool(int(value)) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) # end of class EditCalendarCtrl def builder(parent, sizer, pos, number=[1]): """\ factory function for EditCalendarCtrl objects. """ label = 'calendar_ctrl_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'calendar_ctrl_%d' % number[0] calendar_ctrl = EditCalendarCtrl(label, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(calendar_ctrl) calendar_ctrl.node = node calendar_ctrl.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditCalendarCtrl objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") calendar_ctrl = EditCalendarCtrl(label, parent, wx.NewId(), sizer, pos, common.property_panel, show=False) node = Tree.Node(calendar_ctrl) calendar_ctrl.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return calendar_ctrl def initialize(): """\ initialization function for the module. @rtype: wxBitmapButton @return: an icon to be added to the main palette. """ common.widgets['EditCalendarCtrl'] = builder common.widgets_from_xml['EditCalendarCtrl'] = xml_builder return common.make_object_button('EditCalendarCtrl', 'icons/calendar_ctrl.xpm') wxglade-0.6.8.orig/widgets/calendar_ctrl/codegen.py0000644000175000017500000001173712150154266022551 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxCalendarCtrl objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator(object): def __init__(self): self.pygen = common.code_writers['python'] self.real_class_name = 'CalendarCtrl' def __get_import_modules(self): if self.pygen.use_new_namespace: return ['import wx.calendar\n'] else: return ['from wxPython.calendar import *\n'] import_modules = property(__get_import_modules) def cn(self, c): """ Create names according to if the new namescace (wx) was selected @type c: string @param c: the name which should be altered @rtype: string @return: the orignial name with a prefix according to which namespace the user selected """ if self.pygen.use_new_namespace: if c[:2] == 'wx': c = c[2:] return 'wx.calendar.' + c else: return c def cn_f(self, flags): """ Same as cn(c) but for flags @rtype: string """ if self.pygen.use_new_namespace: return "|".join([self.cn(f) for f in str(flags).split('|')]) else: return str(flags) def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) #label = pygen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % self.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base or klass == self.real_class_name: klass = self.cn(klass) init.append('self.%s = %s(%s, %s%s)\n' % # (obj.name, klass, parent, id, label, style)) (obj.name, klass,parent, id, style)) props_buf = pygen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('self.%s.SetDefault()\n' % obj.name) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class CalendarCtrlXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'label': # translate & into _ as accelerator marker val2 = val.replace('&', '_') if val.count('&&') > 0: while True: index = val.find('&&') if index < 0: break val = val2[:index] + '&&' + val2[index+2:] else: val = val2 xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class CalendarCtrlXrcObject return CalendarCtrlXrcObject(obj) class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ fuction that generates python code for wxCalendarCtrl objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, %s'\ % style #label = cppgen.quote_str(prop.get('label', '')) init = [ '%s = new %s(%s, %s%s);\n' % # (obj.name, obj.klass, parent, id, label, extra) ] (obj.name, obj.klass, parent, id, extra) ] props_buf = cppgen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('%s->SetDefault();\n' % obj.name) return init, ids, props_buf, [] def get_events(self, obj): """\ wxCalendarCtrl uses wxCalendarEvent for event handling """ cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxCalendarEvent') # end of class CppCodeGenerator def initialize(): common.class_names['EditCalendarCtrl'] = 'wxCalendarCtrl' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxCalendarCtrl', PythonCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxCalendarCtrl', xrc_code_generator) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxCalendarCtrl', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/calendar_ctrl/__init__.py0000644000175000017500000000077311621715605022704 0ustar georgeskgeorgesk# __init__.py: calendar_ctrl widget module initialization # $Header: /home/alb/tmp/wxglade_cvs_backup/wxGlade/widgets/calendar_ctrl/__init__.py,v 1.2 2007/03/27 07:02:04 agriggio Exp $ # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import calendar_ctrl return calendar_ctrl.initialize() wxglade-0.6.8.orig/widgets/choice/0000755000175000017500000000000012170277707017227 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/choice/perl_codegen.py0000644000175000017500000000331611677431645022236 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxChoice objects # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) choices = ', '.join([plgen.quote_str(c) for c in choices]) init.append('$self->{%s} = %s->new(%s, %s, wxDefaultPosition, \ wxDefaultSize, [%s], %s);\n' % (obj.name, klass, parent, id, choices, style)) props_buf = plgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('$self->{%s}->SetSelection(%s);\n' % (obj.name, selection)) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditChoice'] = 'wxChoice' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxChoice', PerlCodeGenerator()) plgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/choice/choice.py0000644000175000017500000001332011621715605021024 0ustar georgeskgeorgesk# choice.py: wxChoice objects # $Id: choice.py,v 1.18 2007/03/27 07:02:03 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * from ChoicesProperty import * if wx.Platform == '__WXMSW__': # On windows GetBestSize considers also the drop down menu, while we # don't want it to be included. class wxChoice2(wx.Choice): def GetBestSize(self): w, h = wx.Choice.GetBestSize(self) n = self.GetCount() return w, h/(n+1) def GetSize(self): return self.GetClientSize() else: wxChoice2 = wx.Choice class EditChoice(ManagedBase): events = ['EVT_CHOICE'] def __init__(self, name, parent, id, choices, sizer, pos, property_window, show=True): """\ Class to handle wxChoice objects """ import config ManagedBase.__init__(self, name, 'wxChoice', parent, id, sizer, pos, property_window, show=show) self.choices = choices self.selection = 0 self.access_functions['choices'] = (self.get_choices, self.set_choices) self.properties['choices'] = ChoicesProperty(self, 'choices', None, [('Label', GridProperty.STRING)], len(choices),label=_('choices')) self.access_functions['selection'] = (self.get_selection, self.set_selection) self.properties['selection'] = SpinProperty(self, 'selection', None, r=(0, len(choices)-1), label=_('selection')) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = wxChoice2(self.parent.widget, self.id, choices=self.choices) self.set_selection(self.selection) wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['choices'].display(panel) self.properties['selection'].display(panel) szr.Add(self.properties['selection'].panel, 0, wx.EXPAND) szr.Add(self.properties['choices'].panel, 1, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') self.properties['choices'].set_col_sizes([-1]) def get_choices(self): return zip(self.choices) def set_choices(self, values): self.choices = [ misc.wxstr(v[0]) for v in values ] self.properties['selection'].set_range(0, len(self.choices)-1) if self.widget: self.widget.Clear() for c in self.choices: self.widget.Append(c) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) self.widget.SetSelection( int(self.properties['selection'].get_value())) def get_property_handler(self, prop_name): if prop_name == 'choices': return ChoicesHandler(self) return ManagedBase.get_property_handler(self, prop_name) def get_selection(self): return self.selection def set_selection(self, value): value = int(value) if value != self.selection: self.selection = value if self.widget: self.widget.SetSelection(value) # end of class EditChoice def builder(parent, sizer, pos, number=[1]): """\ factory function for EditChoice objects. """ name = 'choice_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'choice_%d' % number[0] choice = EditChoice(name, parent, wx.NewId(), [], #[misc._encode('choice 1')], sizer, pos, common.property_panel) node = Tree.Node(choice) #sizer.set_item(pos, size=choice.GetBestSize()) choice.node = node choice.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditChoice objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") choice = EditChoice(name, parent, wx.NewId(), [], sizer, pos, common.property_panel) #, show=False) sizer.set_item(choice.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) ## size=choice.GetBestSize()) node = Tree.Node(choice) choice.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return choice def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditChoice'] = builder common.widgets_from_xml['EditChoice'] = xml_builder return common.make_object_button('EditChoice', 'icons/choice.xpm') wxglade-0.6.8.orig/widgets/choice/lisp_codegen.py0000644000175000017500000000335012150154266022225 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxChoice objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:58:29 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) length = len(choices) choices = ' '.join([codegen.quote_str(c) for c in choices]) init.append('(setf (slot-%s obj) (wxChoice_Create %s %s -1 -1 -1 -1 %s (vector %s) %s))\n' % (obj.name, parent, id, length, choices, style)) props_buf = codegen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('(wxChoice_SetSelection (slot-%s obj) %s)\n' % (obj.name, selection)) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditChoice'] = 'wxChoice' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxChoice', LispCodeGenerator()) codegen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/choice/codegen.py0000644000175000017500000000764012072605532021204 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxChoice objects # $Id: codegen.py,v 1.14 2007/03/27 07:02:03 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) choices = ', '.join([pygen.quote_str(c) for c in choices]) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, choices=[%s]%s)\n' % (obj.name, klass, parent, id, choices, style)) props_buf = pygen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None and len(prop.get('choices', [])): props_buf.append('self.%s.SetSelection(%s)\n' % (obj.name, selection)) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class ChoiceXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'choices': xrc_write_choices_property(self, outfile, tabs) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class ChoiceXrcObject return ChoiceXrcObject(obj) class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxChoice objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' number = len(choices) ch_arr = '{\n %s\n };\n' % \ ',\n '.join([cppgen.quote_str(c) for c in choices]) style = prop.get("style", "0") init = [] if number: init.append('const wxString %s_choices[] = %s' % (obj.name, ch_arr)) else: init.append('const wxString *%s_choices = NULL;\n' % obj.name) init.append('%s = new %s(%s, %s, wxDefaultPosition, wxDefaultSize, ' '%s, %s_choices, %s);\n' % \ (obj.name, obj.klass, parent, id, number, obj.name, style)) props_buf = cppgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None and len(prop.get('choices', [])): props_buf.append('%s->SetSelection(%s);\n' % (obj.name, selection)) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditChoice'] = 'wxChoice' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxChoice', PythonCodeGenerator()) pygen.add_property_handler('choices', ChoicesCodeHandler) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxChoice', xrc_code_generator) xrcgen.add_property_handler('choices', ChoicesCodeHandler) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxChoice', CppCodeGenerator()) cppgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/choice/__init__.py0000644000175000017500000000064411621715605021336 0ustar georgeskgeorgesk# __init__.py: choice widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:02:03 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import choice return choice.initialize() wxglade-0.6.8.orig/widgets/grid/0000755000175000017500000000000012170277707016722 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/grid/perl_codegen.py0000644000175000017500000001007111646103723021712 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxGrid objects # $Id: perl_codegen.py,v 1.7 2005/08/15 07:38:56 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from codegen import ColsCodeHandler, _check_label class PerlCodeGenerator: import_modules = ['use Wx::Grid;\n'] def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s);\n' % (obj.name, klass, parent, id)) props_buf = self.get_properties_code(obj) return init, props_buf, [] def get_properties_code(self, obj): plgen = common.code_writers['perl'] out = [] name = '$self' if not obj.is_toplevel: name += '->{%s}' % obj.name prop = obj.properties try: create_grid = int(prop['create_grid']) except (KeyError, ValueError): create_grid = False if not create_grid: return [] columns = prop.get('columns', [['A', '-1']]) out.append('%s->CreateGrid(%s, %s);\n' % (name, prop.get('rows_number', '1'), len(columns))) if prop.get('row_label_size'): out.append('%s->SetRowLabelSize(%s);\n' % (name, prop['row_label_size'])) if prop.get('col_label_size'): out.append('%s->SetColLabelSize(%s);\n' % (name, prop['col_label_size'])) enable_editing = prop.get('enable_editing', '1') if enable_editing != '1': out.append('%s->EnableEditing(0);\n' % name) enable_grid_lines = prop.get('enable_grid_lines', '1') if enable_grid_lines != '1': out.append('%s->EnableGridLines(0);\n' % name) enable_col_resize = prop.get('enable_col_resize', '1') if enable_col_resize != '1': out.append('%s->EnableDragColSize(0);\n' % name) enable_row_resize = prop.get('enable_row_resize', '1') if enable_row_resize != '1': out.append('%s->EnableDragRowSize(0);\n' % name) enable_grid_resize = prop.get('enable_grid_resize', '1') if enable_grid_resize != '1': out.append('%s->EnableDragGridSize(0);\n' % name) if prop.get('lines_color', False): out.append('%s->SetGridLineColour(Wx::Colour->new(%s));\n' % (name, plgen._string_to_colour(prop['lines_color']))) if prop.get('label_bg_color', False): out.append('%s->SetLabelBackgroundColour(Wx::Colour->new(%s));\n' % (name, plgen._string_to_colour(prop['label_bg_color']))) sel_mode = prop.get('selection_mode') if sel_mode and sel_mode != 'wxGridSelectCells': out.append('%s->SetSelectionMode(%s);\n' % (name, sel_mode.replace('wxGrid.',''))) i = 0 for label, size in columns: if _check_label(label, i): out.append('%s->SetColLabelValue(%s, %s);\n' % \ (name, i, plgen.quote_str(label))) try: if int(size) > 0: out.append('%s->SetColSize(%s, %s);\n' % \ (name, i, size)) except ValueError: pass i += 1 out.extend(plgen.generate_common_properties(obj)) return out # end of class PerlCodeGenerator def initialize(): common.class_names['EditGrid'] = 'wxGrid' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxGrid', PerlCodeGenerator()) plgen.add_property_handler('columns', ColsCodeHandler) wxglade-0.6.8.orig/widgets/grid/lisp_codegen.py0000644000175000017500000001022211621715605021716 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxGrid objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:59:42 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from codegen import ColsCodeHandler, _check_label class LispCodeGenerator: # import_modules = ['use Wx::Grid;\n'] def get_code(self, obj): plgen = common.code_writers['lisp'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxGrid_Create %s %s -1 -1 -1 -1 wxWANTS_CHARS))\n' % (obj.name, parent, id)) props_buf = self.get_properties_code(obj) return init, props_buf, [] def get_properties_code(self, obj): plgen = common.code_writers['lisp'] out = [] name = obj.name prop = obj.properties try: create_grid = int(prop['create_grid']) except (KeyError, ValueError): create_grid = False if not create_grid: return [] columns = prop.get('columns', [['A', '-1']]) out.append('(wxGrid_CreateGrid (slot-%s obj) %s %s 0)\n' % (name, prop.get('rows_number', '1'), len(columns))) if prop.get('row_label_size'): out.append('(wxGrid_SetRowLabelSize (slot-%s obj) %s)\n' % (name, prop['row_label_size'])) if prop.get('col_label_size'): out.append('(wxGrid_SetColLabelSize (slot-%s obj) %s)\n' % (name, prop['col_label_size'])) enable_editing = prop.get('enable_editing', '1') if enable_editing != '1': out.append('(wxGrid_EnableEditing (slot-%s obj) 0)\n' % name) enable_grid_lines = prop.get('enable_grid_lines', '1') if enable_grid_lines != '1': out.append('(wxGrid_EnableGridLines (slot-%s obj) 0)\n' % name) enable_col_resize = prop.get('enable_col_resize', '1') if enable_col_resize != '1': out.append('(wxGrid_EnableDragColSize (slot-%s obj) 0)\n' % name) enable_row_resize = prop.get('enable_row_resize', '1') if enable_row_resize != '1': out.append('(wxGrid_EnableDragRowSize (slot-%s obj) 0)\n' % name) enable_grid_resize = prop.get('enable_grid_resize', '1') if enable_grid_resize != '1': out.append('(wxGrid_EnableDragGridSize (slot-%s obj) 0)\n' % name) if prop.get('lines_color', False): out.append('(wxGrid_SetGridLineColour (slot-%s obj) (wxColour:wxColour_CreateFromStock %s))\n' % (name, plgen._string_to_colour(prop['lines_color']))) if prop.get('label_bg_color', False): out.append('(wxGrid_SetLabelBackgroundColour (slot-%s obj) (wxColour:wxColour_CreateFromStock %s))\n' %(name, plgen._string_to_colour(prop['label_bg_color']))) sel_mode = prop.get('selection_mode') if sel_mode and sel_mode != 'wxGridSelectCells': out.append('(wxGrid_SetSelectionMode (slot-%s obj) %s)\n' % (name, sel_mode.replace('wxGrid.',''))) i = 0 for label, size in columns: if _check_label(label, i): out.append('(wxGrid_SetColLabelValue (slot-%s obj) %s %s)\n' % \ (name, i, plgen.quote_str(label))) try: if int(size) > 0: out.append('(wxGrid_SetColSize (slot-%s obj) %s %s)\n' % \ (name, i, size)) except ValueError: pass i += 1 out.extend(plgen.generate_common_properties(obj)) return out # end of class LispCodeGenerator def initialize(): common.class_names['EditGrid'] = 'wxGrid' plgen = common.code_writers.get('lisp') if plgen: plgen.add_widget_handler('wxGrid', LispCodeGenerator()) plgen.add_property_handler('columns', ColsCodeHandler) wxglade-0.6.8.orig/widgets/grid/codegen.py0000644000175000017500000002527412072605532020702 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxGrid objects # $Id: codegen.py,v 1.25 2007/03/27 07:01:58 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class ColsCodeHandler: def __init__(self): self.columns = [] self.col_name = '' self.col_size = '' def start_elem(self, name, attrs): if name == 'column': s = attrs.get('size', '') self.col_size = s self.col_name = '' def end_elem(self, name, code_obj): if name == 'columns': code_obj.properties['columns'] = self.columns return True elif name == 'column': self.columns.append([self.col_name, self.col_size]) return False def char_data(self, data): self.col_name = self.col_name + data # end of class ColsCodeHandler def _check_label(label, col): """\ Checks if 'label' is not the default one for the columns 'col': returns True if the label is a custom one, False otherwise """ # build the default value s = [] while True: s.append(chr(ord('A') + col % 26)) col = col/26 - 1 if col < 0: break s.reverse() # then compare it with label return label != "".join(s) class PythonCodeGenerator(object): def __init__(self): self.pygen = common.code_writers['python'] def __get_import_modules(self): if self.pygen.use_new_namespace: return ['import wx.grid\n'] else: return ['from wxPython.grid import *\n'] import_modules = property(__get_import_modules) def cn(self, c): #print 'PythonCodeGenerator.cn with arg:', c if self.pygen.use_new_namespace: if c[:2] == 'wx': c = c[2:] return 'wx.grid.' + c else: return c def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = self.cn(klass) init.append('self.%s = %s(%s, %s, size=(1, 1))\n' % (obj.name, klass, parent, id)) props_buf = self.get_properties_code(obj) return init, props_buf, [] def get_properties_code(self, obj): pygen = common.code_writers['python'] out = [] name = 'self' if not obj.is_toplevel: name += '.%s' % obj.name prop = obj.properties try: create_grid = int(prop['create_grid']) except (KeyError, ValueError): create_grid = False if not create_grid: return [] columns = prop.get('columns', [['A', '-1']]) out.append('%s.CreateGrid(%s, %s)\n' % (name, prop.get('rows_number', '1'), len(columns))) if prop.get('row_label_size'): out.append('%s.SetRowLabelSize(%s)\n' % (name, prop['row_label_size'])) if prop.get('col_label_size'): out.append('%s.SetColLabelSize(%s)\n' % (name, prop['col_label_size'])) enable_editing = prop.get('enable_editing', '1') if enable_editing != '1': out.append('%s.EnableEditing(0)\n' % name) enable_grid_lines = prop.get('enable_grid_lines', '1') if enable_grid_lines != '1': out.append('%s.EnableGridLines(0)\n' % name) enable_col_resize = prop.get('enable_col_resize', '1') if enable_col_resize != '1': out.append('%s.EnableDragColSize(0)\n' % name) enable_row_resize = prop.get('enable_row_resize', '1') if enable_row_resize != '1': out.append('%s.EnableDragRowSize(0)\n' % name) enable_grid_resize = prop.get('enable_grid_resize', '1') if enable_grid_resize != '1': out.append('%s.EnableDragGridSize(0)\n' % name) if prop.get('lines_color', False): out.append(('%s.SetGridLineColour(' + pygen.cn('wxColour') + '(%s))\n') % (name, pygen._string_to_colour(prop['lines_color']))) if prop.get('label_bg_color', False): out.append(('%s.SetLabelBackgroundColour(' + pygen.cn('wxColour') + '(%s))\n') % (name, pygen._string_to_colour(prop['label_bg_color']))) sel_mode = prop.get('selection_mode') if sel_mode and sel_mode != 'wxGrid.wxGridSelectCells': out.append('%s.SetSelectionMode(%s)\n' % \ (name, self.cn('wxGrid') + sel_mode[6:])) i = 0 for label, size in columns: if _check_label(label, i): out.append('%s.SetColLabelValue(%s, %s)\n' % \ (name, i, pygen.quote_str(label))) try: if int(size) > 0: out.append('%s.SetColSize(%s, %s)\n' % \ (name, i, size)) except ValueError: pass i += 1 out.extend(pygen.generate_common_properties(obj)) return out # end of class PythonCodeGenerator class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ generates C++ code for wxGrid objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' init = [ '%s = new %s(%s, %s);\n' % (obj.name, obj.klass, parent, id) ] props_buf = self.get_properties_code(obj) return init, ids, props_buf, [] def get_properties_code(self, obj): cppgen = common.code_writers['C++'] out = [] name = 'this' if not obj.is_toplevel: name = obj.name prop = obj.properties try: create_grid = int(prop['create_grid']) except (KeyError, ValueError): create_grid = False if not create_grid: return [] columns = prop.get('columns', [['A', '-1']]) out.append('%s->CreateGrid(%s, %s);\n' % (name, prop.get('rows_number', '1'), len(columns))) if prop.get('row_label_size'): out.append('%s->SetRowLabelSize(%s);\n' % \ (name, prop['row_label_size'])) if prop.get('col_label_size'): out.append('%s->SetColLabelSize(%s);\n' % \ (name, prop['col_label_size'])) enable_editing = prop.get('enable_editing', '1') if enable_editing != '1': out.append('%s->EnableEditing(false);\n' % name) enable_grid_lines = prop.get('enable_grid_lines', '1') if enable_grid_lines != '1': out.append('%s->EnableGridLines(false);\n' % name) enable_col_resize = prop.get('enable_col_resize', '1') if enable_col_resize != '1': out.append('%s->EnableDragColSize(false);\n' % name) enable_row_resize = prop.get('enable_row_resize', '1') if enable_row_resize != '1': out.append('%s->EnableDragRowSize(false);\n' % name) enable_grid_resize = prop.get('enable_grid_resize', '1') if enable_grid_resize != '1': out.append('%s->EnableDragGridSize(false);\n' % name) if prop.get('lines_color', False): out.append('%s->SetGridLineColour(wxColour(%s));\n' % (name, cppgen._string_to_colour(prop['lines_color']))) if prop.get('label_bg_color', False): out.append('%s->SetLabelBackgroundColour(wxColour(%s));\n' % (name, cppgen._string_to_colour(prop['label_bg_color']))) sel_mode = prop.get('selection_mode', '').replace('.', '::') if sel_mode and sel_mode != 'wxGrid::wxGridSelectCells': out.append('%s->SetSelectionMode(%s);\n' % (name, sel_mode)) i = 0 for label, size in columns: if _check_label(label, i): out.append('%s->SetColLabelValue(%s, %s);\n' % \ (name, i, cppgen.quote_str(label))) try: if int(size) > 0: out.append('%s->SetColSize(%s, %s);\n' % \ (name, i, size)) except ValueError: pass i += 1 out.extend(cppgen.generate_common_properties(obj)) return out def get_events(self, obj): cppgen = common.code_writers['C++'] ret = cppgen.get_events_with_type(obj, 'wxGridEvent') evt_different_types = { 'EVT_GRID_CMD_COL_SIZE': 'wxGridSizeEvent', 'EVT_GRID_CMD_ROW_SIZE': 'wxGridSizeEvent', 'EVT_GRID_CMD_RANGE_SELECT': 'wxGridRangeSelectEvent', 'EVT_GRID_CMD_EDITOR_CREATED': 'wxGridEditorCreatedEvent', } for i in xrange(len(ret)): e = ret[i] if e[1] in evt_different_types: ret[i] = e[:3] + (evt_different_types[e[1]],) return ret # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class GridXrcObject(xrcgen.DefaultXrcObject): unsupported = set(['column', 'create_grid', 'rows_number', 'row_label_size', 'col_label_size', 'enable_editing', 'enable_grid_lines', 'enable_col_resize', 'enable_row_resize', 'enable_grid_resize', 'lines_color', 'label_bg_color', 'selection_mode']) def write_property(self, name, val, outfile, tabs): if name not in self.unsupported: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) return GridXrcObject(obj) def initialize(): common.class_names['EditGrid'] = 'wxGrid' pygen = common.code_writers.get('python') if pygen: pygen.add_property_handler('columns', ColsCodeHandler, 'wxGrid') pygen.add_widget_handler('wxGrid', PythonCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxGrid', xrc_code_generator) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_property_handler('columns', ColsCodeHandler, 'wxGrid') cppgen.add_widget_handler('wxGrid', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/grid/grid.py0000644000175000017500000004655711646103712020231 0ustar georgeskgeorgesk# Grid.py: wxGrid objects # $Id: grid.py,v 1.33 2007/03/27 07:01:58 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx from wx.grid import * import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * class GridColsProperty(GridProperty): def write(self, outfile, tabs): from xml.sax.saxutils import escape, quoteattr write = outfile.write write(' ' * tabs + '\n') tab_s = ' ' * (tabs+1) import widget_properties value = self.get_value() # this is a list for i in range(len(value)): val = value[i] # this is another list _label = escape(widget_properties._encode(val[0])) _size = escape(widget_properties._encode(val[1])) write('%s%s\n' % (tab_s, quoteattr(_size), _label )) write(' ' * tabs + '\n') def _get_label(self, col): s = [] while True: s.append(chr(ord('A') + col%26)) col = col/26 - 1 if col < 0: break s.reverse() return "".join(s) def add_row(self, event): GridProperty.add_row(self, event) label = self._get_label(self.rows-1) self.grid.SetCellValue(self.rows-1, 0, label) self.grid.SetCellValue(self.rows-1, 1, '-1') def insert_row(self, event): GridProperty.insert_row(self, event) label = self._get_label(self.cur_row) self.grid.SetCellValue(self.cur_row, 0, label) self.grid.SetCellValue(self.cur_row, 1, '-1') # end of class GridColumnsProperty class ColsHandler: def __init__(self, parent): self.parent = parent self.columns = [] self.curr_col = [] self.curr_size = '-1' def start_elem(self, name, attrs): if name == 'column': self.curr_size = attrs.get('size', '-1') def end_elem(self, name): if name == 'columns': self.parent.set_columns(self.columns) self.parent.properties['columns'].set_value(self.columns) return True elif name == 'column': self.columns.append(["".join(self.curr_col), self.curr_size]) self.curr_col = [] return False def char_data(self, data): self.curr_col.append(data) # end of class ColsHandler class EditGrid(ManagedBase): events = [ 'EVT_GRID_CMD_CELL_LEFT_CLICK', 'EVT_GRID_CMD_CELL_RIGHT_CLICK', 'EVT_GRID_CMD_CELL_LEFT_DCLICK', 'EVT_GRID_CMD_CELL_RIGHT_DCLICK', 'EVT_GRID_CMD_LABEL_LEFT_CLICK', 'EVT_GRID_CMD_LABEL_RIGHT_CLICK', 'EVT_GRID_CMD_LABEL_LEFT_DCLICK', 'EVT_GRID_CMD_LABEL_RIGHT_DCLICK', 'EVT_GRID_CMD_CELL_CHANGE', 'EVT_GRID_CMD_SELECT_CELL', 'EVT_GRID_CMD_EDITOR_HIDDEN', 'EVT_GRID_CMD_EDITOR_SHOWN', 'EVT_GRID_CMD_COL_SIZE', 'EVT_GRID_CMD_ROW_SIZE', 'EVT_GRID_CMD_RANGE_SELECT', 'EVT_GRID_CMD_EDITOR_CREATED', ] def __init__(self, name, parent, id, sizer, pos, property_window, show=True): """\ Class to handle wxGrid objects """ # values of properties for the grid: self.row_label_size = 30 self.col_label_size = 30 self.enable_editing = True self.enable_grid_lines = True self.rows_number = 10 self.enable_col_resize = True self.enable_row_resize = True self.enable_grid_resize = True self.lines_color = '#000000' self.label_bg_color = '#C0C0C0' self.selection_mode = 0 # == wxGrid.wxGridSelectCells self.create_grid = True self.columns = [ ['A','-1'] , ['B','-1'] , ['C','-1'] ] ManagedBase.__init__(self, name, 'wxGrid', parent, id, sizer, pos, property_window, show=show) props = self.properties af = self.access_functions af['create_grid'] = (self.get_create_grid, self.set_create_grid) props['create_grid'] = CheckBoxProperty( self, 'create_grid', None, write_always=True, label=_("create_grid")) af['row_label_size'] = (self.get_row_label_size, self.set_row_label_size) props['row_label_size'] = SpinProperty( self, 'row_label_size', None, can_disable=True, label=_("row_label_size"), omitter='create_grid') af['col_label_size'] = (self.get_col_label_size, self.set_col_label_size) props['col_label_size'] = SpinProperty( self, 'col_label_size', None, can_disable=True, label=_("col_label_size"), omitter='create_grid') af['enable_editing'] = (self.get_enable_editing, self.set_enable_editing) props['enable_editing'] = CheckBoxProperty( self, 'enable_editing', None, write_always=True, label=_("enable_editing"), omitter='create_grid') af['enable_grid_lines'] = (self.get_enable_grid_lines, self.set_enable_grid_lines) props['enable_grid_lines']= CheckBoxProperty( self, 'enable_grid_lines', None, write_always=True, label=_("enable_grid_lines"), omitter='create_grid') af['rows_number'] = (self.get_rows_number, self.set_rows_number) props['rows_number'] = SpinProperty( self, 'rows_number', None, label=_("rows_number"), omitter='create_grid') af['enable_col_resize'] = (self.get_enable_col_resize, self.set_enable_col_resize) props['enable_col_resize']= CheckBoxProperty( self, 'enable_col_resize', None, write_always=True, label=_("enable_col_resize"), omitter='create_grid') af['enable_row_resize'] = (self.get_enable_row_resize, self.set_enable_row_resize) props['enable_row_resize'] = CheckBoxProperty( self, 'enable_row_resize', None, write_always=True, label=_("enable_row_resize"), omitter='create_grid') af['enable_grid_resize'] = (self.get_enable_grid_resize, self.set_enable_grid_resize) props['enable_grid_resize'] = CheckBoxProperty( self, 'enable_grid_resize', None, write_always=True, label=_("enable_grid_resize"), omitter='create_grid') af['lines_color'] = (self.get_lines_color, self.set_lines_color) props['lines_color']= ColorDialogProperty( self, 'lines_color', None, label=_("lines_color"), omitter='create_grid') af['label_bg_color'] = (self.get_label_bg_color, self.set_label_bg_color) props['label_bg_color']= ColorDialogProperty( self, 'label_bg_color', None, label=_("label_bg_color"), omitter='create_grid') af['selection_mode'] = (self.get_selection_mode, self.set_selection_mode) props['selection_mode'] = RadioProperty( self, 'selection_mode', None, ['wxGrid.wxGridSelectCells', 'wxGrid.wxGridSelectRows', 'wxGrid.wxGridSelectColumns'], label=_("selection_mode"), omitter='create_grid') af['columns'] = (self.get_columns, self.set_columns) props['columns'] = GridColsProperty( self, 'columns', None, [ ('Label', GridProperty.STRING), ('Size', GridProperty.INT) ], label=_("columns"), omitter='create_grid') def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) self.properties['create_grid'].display(panel) self.properties['columns'].display(panel) self.properties['rows_number'].display(panel) self.properties['row_label_size'].display(panel) self.properties['col_label_size'].display(panel) self.properties['enable_editing'].display(panel) self.properties['enable_grid_lines'].display(panel) self.properties['enable_col_resize'].display(panel) self.properties['enable_row_resize'].display(panel) self.properties['enable_grid_resize'].display(panel) self.properties['lines_color'].display(panel) self.properties['label_bg_color'].display(panel) self.properties['selection_mode'].display(panel) self.toggle_blocked_properties() szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.properties['create_grid'].panel, 0, wx.EXPAND) szr.Add(wx.StaticLine(panel, -1), 0, wx.ALL|wx.EXPAND, 5) szr.Add(wx.StaticText(panel, -1, _("The following properties are " "meaningful\nonly if 'Create grid' is selected")), 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 10) szr.Add(wx.StaticLine(panel, -1), 0, wx.ALL|wx.EXPAND, 5) szr.Add(self.properties['columns'].panel, 0, wx.ALL|wx.EXPAND, 2) szr.SetItemMinSize(self.properties['columns'].panel, 1, 150) szr.Add(self.properties['rows_number'].panel, 0, wx.EXPAND) szr.Add(self.properties['row_label_size'].panel, 0, wx.EXPAND) szr.Add(self.properties['col_label_size'].panel, 0, wx.EXPAND) szr.Add(self.properties['lines_color'].panel, 0, wx.EXPAND) szr.Add(self.properties['label_bg_color'].panel, 0, wx.EXPAND) szr.Add(self.properties['enable_editing'].panel, 0, wx.EXPAND) szr.Add(self.properties['enable_grid_lines'].panel, 0, wx.EXPAND) szr.Add(self.properties['enable_col_resize'].panel, 0, wx.EXPAND) szr.Add(self.properties['enable_row_resize'].panel, 0, wx.EXPAND) szr.Add(self.properties['enable_grid_resize'].panel, 0, wx.EXPAND) szr.Add(self.properties['selection_mode'].panel, 0, wx.ALL|wx.EXPAND, 5) panel.SetAutoLayout(1) panel.SetSizer(szr) szr.Fit(panel) w, h = panel.GetClientSize() self.notebook.AddPage(panel, _('Widget')) import math panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) self.properties['columns'].set_col_sizes([-1, 0]) def create_widget(self): self.widget = Grid(self.parent.widget, self.id, (200, 200)) self.widget.CreateGrid(self.rows_number, len(self.columns)) if not self.properties['label_bg_color'].is_active(): self.label_bg_color = misc.color_to_string( self.widget.GetLabelBackgroundColour()) self.properties['label_bg_color'].set_value(self.label_bg_color) if not self.properties['lines_color'].is_active(): self.lines_color = misc.color_to_string( self.widget.GetGridLineColour()) self.properties['lines_color'].set_value(self.lines_color) self.widget.SetRowLabelSize(self.row_label_size) self.widget.SetColLabelSize(self.col_label_size) self.widget.EnableEditing(self.enable_editing) self.widget.EnableGridLines(self.enable_grid_lines) self.widget.EnableDragColSize(self.enable_col_resize) self.widget.EnableDragRowSize(self.enable_row_resize) self.widget.EnableDragGridSize(self.enable_grid_resize) self.widget.SetGridLineColour(misc.string_to_color(self.lines_color)) self.widget.SetLabelBackgroundColour(misc.string_to_color( self.label_bg_color)) i = 0 for l, s in self.columns: try: s1 = int(s) except: s1 = 0 self.widget.SetColLabelValue(i, l) if s1 > 0: self.widget.SetColSize(i, s1) i += 1 self.set_selection_mode(self.selection_mode) # following two events are to permit select grid from designer frame EVT_GRID_CELL_LEFT_CLICK(self.widget, self.on_set_focus) EVT_GRID_LABEL_LEFT_CLICK(self.widget, self.on_set_focus) # these are to show the popup menu on right click EVT_GRID_CELL_RIGHT_CLICK(self.widget, self.popup_menu) EVT_GRID_LABEL_RIGHT_CLICK(self.widget, self.popup_menu) def toggle_blocked_properties(self): to_block = not self.get_create_grid() for name in self.get_property_blocking('create_grid'): widget = self.properties[name] if getattr(widget, 'toggle_blocked', None): widget.toggle_blocked(to_block) def get_create_grid(self): return self.create_grid def set_create_grid(self, value): self.create_grid = bool(int(value)) self.toggle_blocked_properties() def get_row_label_size(self): return self.row_label_size def set_row_label_size(self, value): self.row_label_size = int(value) if value and self.widget: self.widget.SetRowLabelSize(self.row_label_size) def get_col_label_size(self): return self.col_label_size def set_col_label_size(self, value): self.col_label_size = int(value) if value and self.widget: self.widget.SetColLabelSize(self.col_label_size) def get_enable_editing(self): return self.enable_editing def set_enable_editing(self, value): self.enable_editing = bool(int(value)) # Do nothing. ## if value and self.widget: ## self.widget.EnableEditing(self.enable_editing) # NO! def get_enable_grid_lines(self): return self.enable_grid_lines def set_enable_grid_lines(self, value): self.enable_grid_lines = bool(int(value)) if self.widget: self.widget.EnableGridLines(self.enable_grid_lines) #self.widget.Update() def get_rows_number(self): return self.rows_number def set_rows_number(self, value): self.rows_number = int(value) # the value the user entered if value > 0 and self.widget: # the value that the grid has actual_rows_number = self.widget.GetNumberRows() if self.rows_number > actual_rows_number: # we have to add rows self.widget.AppendRows(self.rows_number - actual_rows_number) if actual_rows_number > self.rows_number: # we have to delete rows self.widget.DeleteRows(self.rows_number, actual_rows_number - self.rows_number) #self.widget.Update() def get_enable_col_resize(self): return self.enable_col_resize def set_enable_col_resize(self, value): self.enable_col_resize = bool(int(value)) if self.widget: self.widget.EnableDragColSize(self.enable_col_resize) def get_enable_row_resize(self): return self.enable_row_resize def set_enable_row_resize(self, value): self.enable_row_resize = bool(int(value)) if self.widget: self.widget.EnableDragRowSize(self.enable_row_resize) def get_enable_grid_resize(self): return self.enable_grid_resize def set_enable_grid_resize(self, value): self.enable_grid_resize = bool(int(value)) if self.widget: self.widget.EnableDragGridSize(self.enable_grid_resize) def get_lines_color(self): return self.lines_color def set_lines_color(self, value): self.lines_color = str(value) if self.widget: self.widget.SetGridLineColour(misc.string_to_color( self.lines_color)) def get_label_bg_color(self): return self.label_bg_color def set_label_bg_color(self, value): self.label_bg_color = str(value) if self.widget: self.widget.SetLabelBackgroundColour(misc.string_to_color( self.label_bg_color)) def get_selection_mode(self): return self.selection_mode ## if self.selection_mode == wxGrid.wxGridSelectCells: return 0 ## if self.selection_mode == wxGrid.wxGridSelectRows: return 1 ## if self.selection_mode == wxGrid.wxGridSelectColumns: return 2 def set_selection_mode(self, value): _sel_modes = { 'wxGrid.wxGridSelectCells': 0, 'wxGrid.wxGridSelectRows': 1, 'wxGrid.wxGridSelectColumns': 2, } if value in _sel_modes: self.selection_mode = _sel_modes[value] else: try: value = int(value) except: pass else: self.selection_mode = value ## if value == 0: ## self.selection_mode = wxGrid.wxGridSelectCells ## elif value == 1: ## self.selection_mode = wxGrid.wxGridSelectRows ## else: ## self.selection_mode = wxGrid.wxGridSelectColumns # no operation on the grid. def get_columns(self): return self.columns def set_columns(self, cols): # first of all, adjust col number _oldcolnum = len(self.columns) _colnum = len(cols) self.columns = cols if not self.widget: return if _colnum > _oldcolnum: self.widget.AppendCols(_colnum - _oldcolnum) if _colnum < _oldcolnum: self.widget.DeleteCols(0, _oldcolnum - _colnum) i = 0 for l, s in cols: try: s1 = int(s) except: s1 = 0 self.widget.SetColLabelValue(i, misc.wxstr(l)) if s1 > 0: self.widget.SetColSize(i, s1) i += 1 self.widget.ForceRefresh() def get_property_handler(self, name): if name == 'columns': return ColsHandler(self) return ManagedBase.get_property_handler(self, name) # end of class EditGrid def builder(parent, sizer, pos, number=[1]): """\ factory function for EditGrid objects. """ label = 'grid_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'grid_%d' % number[0] grid = EditGrid(label, parent, wx.NewId(), sizer, pos, common.property_panel) # A grid should be wx.EXPANDed and 'option' should be 1, # or you can't see it. grid.set_option(1) grid.set_flag("wxEXPAND") node = Tree.Node(grid) grid.node = node grid.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditGrid objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") grid = EditGrid(label, parent, wx.NewId(), sizer, pos, common.property_panel, show=False) sizer.set_item(grid.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) #, size=(100,100)) #HELP# node = Tree.Node(grid) grid.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return grid def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditGrid'] = builder common.widgets_from_xml['EditGrid'] = xml_builder return common.make_object_button('EditGrid', 'icons/grid.xpm') wxglade-0.6.8.orig/widgets/grid/__init__.py0000644000175000017500000000063711621715605021033 0ustar georgeskgeorgesk# __init__.py: grid widget module initialization # $Id: __init__.py,v 1.7 2007/03/27 07:01:58 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import grid return grid.initialize() wxglade-0.6.8.orig/widgets/menubar/0000755000175000017500000000000012170277707017426 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/menubar/perl_codegen.py0000644000175000017500000001224111646103755022424 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxMenuBar objects # $Id: perl_codegen.py,v 1.11 2007/06/23 10:57:58 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from MenuTree import * from codegen import MenuHandler class PerlCodeGenerator: def get_properties_code(self, obj): return [] def get_init_code(self, obj): prop = obj.properties plgen = common.code_writers['perl'] out = [] append = out.append menus = obj.properties['menubar'] ids = [] # We need to keep track of tmpnames used. tmpsused = {} def append_items(menu, items): for item in items: if item.name == '---': # item is a separator append('%s->AppendSeparator();\n' % menu) continue name, val = plgen.generate_code_id(None, item.id) if not name and ( not val or val == '-1'): id = 'Wx::NewId()' else: if name: ids.append(name) id = val if item.children: if item.name: name = item.name else: name = '%s_sub' % menu if not tmpsused.has_key(name): tmpsused[name] = 1 append('my %s;\n' % name) append('%s = Wx::Menu->new();\n' % name) append_items(name, item.children) append('%s->Append(%s, %s, %s, %s);\n' % (menu, id, plgen.quote_str(item.label), name, plgen.quote_str(item.help_str))) else: item_type = 0 if item.checkable == '1': item_type = 1 elif item.radio == '1': item_type = 2 if item.name: itemname = '$self->{%s} = ' % plgen.quote_key(item.name) else: itemname = '' if item_type: append('%s%s->Append(%s, %s, %s, %s);\n' % (itemname, menu, id, plgen.quote_str(item.label), plgen.quote_str(item.help_str), item_type)) else: append('%s%s->Append(%s, %s, %s);\n' % (itemname, menu, id, plgen.quote_str(item.label), plgen.quote_str(item.help_str))) #print 'menus = %s' % menus if obj.is_toplevel: obj_name = '$self' else: obj_name = '$self->{%s}' % plgen.quote_key(obj.name) append('my $wxglade_tmp_menu;\n') # NOTE below name = for m in menus: menu = m.root if menu.name: name = '$self->{%s}' % plgen.quote_key(menu.name) else: name = '$wxglade_tmp_menu' append('%s = Wx::Menu->new();\n' % name) if menu.children: append_items(name, menu.children) append('%s->Append(%s, %s);\n' % (obj_name, name, plgen.quote_str(menu.label))) return ids + out def get_code(self, obj): """\ function that generates Perl code for the menubar of a wxFrame. """ klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) plgen = common.code_writers['perl'] init = [ '\n\n', '# Menu Bar\n\n', '$self->{%s} = %s->new();\n' % (obj.name, klass) ] ## '$self->SetMenuBar($self->{%s});\n' % obj.name ] init.extend(self.get_init_code(obj)) init.append('$self->SetMenuBar($self->{%s});\n' % obj.name) init.append('\n# Menu Bar end\n\n') return init, [], [] # 2004-12-05 def get_events(self, obj): pygen = common.code_writers['perl'] cn = pygen.cn out = [] #print 'get_events', obj.properties['menubar'] def do_get(item): ret = [] if item.name: #val = '#self.%s' % item.name # see py_codegen.py, ~480 val = item.name else: name, val = pygen.generate_code_id(None, item.id) if not val: val = '-1' # but this is wrong anyway... if item.handler: ret.append((val, 'EVT_MENU', item.handler)) if item.children: for c in item.children: ret.extend(do_get(c)) return ret for menu in obj.properties['menubar']: out.extend(do_get(menu.root)) return out # end of class PerlCodeGenerator def initialize(): common.class_names['EditMenuBar'] = 'wxMenuBar' common.toplevels['EditMenuBar'] = 1 plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxMenuBar', PerlCodeGenerator()) plgen.add_property_handler('menus', MenuHandler) wxglade-0.6.8.orig/widgets/menubar/lisp_codegen.py0000644000175000017500000000711411621715605022430 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxMenuBar objects # $Id: lisp_codegen.py,v 1.2 2005/09/25 08:23:37 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from MenuTree import * from codegen import MenuHandler class LispCodeGenerator: def get_properties_code(self, obj): return [] def get_init_code(self, obj): prop = obj.properties plgen = common.code_writers['lisp'] out = [] append = out.append menus = obj.properties['menubar'] ids = [] def append_items(menu, items): for item in items: if item.name == '---': # item is a separator append('(wxMenu_AppendSeparator %s)\n' % menu) continue name, val = plgen.generate_code_id(None, item.id) if not name and ( not val or val == '-1'): id = '-1' else: if name: ids.append(name) id = val if item.children: if item.name: name = item.name else: name = '%s_sub' % menu append('(let ((%s (wxMenu_Create "" 0)))\n' % name) append_items(name, item.children) append('(wxMenuBar_AppendSub %s %s %s %s %s))\n' % (menu, id, plgen.quote_str(item.label), name, plgen.quote_str(item.help_str))) else: item_type = 0 if item.checkable == '1': item_type = 1 elif item.radio == '1': item_type = 2 append('(wxMenu_Append %s %s %s %s %s)\n' % (menu, id, plgen.quote_str(item.label), plgen.quote_str(item.help_str), item_type)) #print 'menus = %s' % menus # if obj.is_toplevel: obj_name = '$self' # else: obj_name = '$self->{%s}' % obj.name # append('my $wxglade_tmp_menu;\n') # NOTE below name = for m in menus: menu = m.root if menu.name: name = menu.name else: name = 'wxglade_tmp_menu' append('(let ((%s (wxMenu_Create "" 0)))\n' % name) if menu.children: append_items(name, menu.children) append('\t\t(wxMenuBar_Append (slot-%s obj) %s %s))\n' % (obj.name, name, plgen.quote_str(menu.label))) return ids + out def get_code(self, obj): """\ function that generates Lisp code for the menubar of a wxFrame. """ plgen = common.code_writers['lisp'] init = [ '\n', ';;; Menu Bar\n', '(setf (slot-%s obj) (wxMenuBar_Create 0))\n' % (obj.name) ] ## '(wxFrame_SetMenuBar (slot-top-window obj) (slot-%s obj))\n' % obj.name ] init.extend(self.get_init_code(obj)) init.append('(wxFrame_SetMenuBar (slot-top-window obj) ' \ '(slot-%s obj))\n' % obj.name) init.append(';;; Menu Bar end\n\n') return init, [], [] # end of class LispCodeGenerator def initialize(): common.class_names['EditMenuBar'] = 'wxMenuBar' common.toplevels['EditMenuBar'] = 1 plgen = common.code_writers.get('lisp') if plgen: plgen.add_widget_handler('wxMenuBar', LispCodeGenerator()) plgen.add_property_handler('menus', MenuHandler) wxglade-0.6.8.orig/widgets/menubar/codegen.py0000644000175000017500000004003612150154266021377 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxMenuBar objects # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from MenuTree import * class PythonCodeGenerator: def get_properties_code(self, obj): return [] def get_init_code(self, obj): prop = obj.properties pygen = common.code_writers['python'] cn = pygen.cn out = [] append = out.append menus = obj.properties['menubar'] ids = [] def append_items(menu, items): for item in items: if item.name == '---': # item is a separator append('%s.AppendSeparator()\n' % menu) continue name, val = pygen.generate_code_id(None, item.id) if obj.preview or (not name and ( not val or val == '-1')): id = cn('wxNewId()') else: if name: ids.append(name) id = val if item.children: if item.name: name = item.name else: name = '%s_sub' % menu append(('%s = ' + cn('wxMenu') + '()\n') % name) ## if not obj.preview and item.id: # generating id ## tokens = item.id.split('=') ## if len(tokens) > 1: ## id = tokens[0] ## ids.append(' = '.join(tokens) + '\n') ## else: ## id = item.id ## else: id = 'wxNewId()' append_items(name, item.children) append('%s.AppendMenu(%s, %s, %s, %s)\n' % (menu, id, pygen.quote_str(item.label), name, pygen.quote_str(item.help_str))) else: ## if not obj.preview and item.id: # no ids for preview ## tokens = item.id.split('=') ## if len(tokens) > 1: ## id = tokens[0] ## ids.append(' = '.join(tokens) + '\n') ## else: ## id = item.id ## else: id = 'wxNewId()' item_type = cn('wxITEM_NORMAL') if item.checkable == '1': item_type = cn('wxITEM_CHECK') elif item.radio == '1': item_type = cn('wxITEM_RADIO') if item.name: # ALB 2004-18-07 name = 'self.%s' % item.name if item_type: append('%s = %s(%s, %s, %s, %s, %s)\n' % (name, cn('wxMenuItem'), menu, id, pygen.quote_str(item.label), pygen.quote_str(item.help_str), item_type)) else: append('%s = %s(%s, %s, %s, %s)\n' % (name, cn('wxMenuItem'), menu, id, pygen.quote_str(item.label), pygen.quote_str(item.help_str))) append('%s.AppendItem(%s)\n' % (menu, name)) else: if item_type: append('%s.Append(%s, %s, %s, %s)\n' % (menu, id, pygen.quote_str(item.label), pygen.quote_str(item.help_str), item_type)) else: append('%s.Append(%s, %s, %s)\n' % (menu, id, pygen.quote_str(item.label), pygen.quote_str(item.help_str))) #print 'menus = %s' % menus if obj.is_toplevel: obj_name = 'self' else: obj_name = 'self.' + obj.name for m in menus: menu = m.root if menu.name: name = 'self.' + menu.name else: name = 'wxglade_tmp_menu' append(('%s = ' + cn('wxMenu') + '()\n') % name) if menu.children: append_items(name, menu.children) append('%s.Append(%s, %s)\n' % (obj_name, name, pygen.quote_str(menu.label))) return ids + out def get_code(self, obj): """\ function that generates Python code for the menubar of a wxFrame. """ pygen = common.code_writers['python'] if obj.klass == obj.base: klass = pygen.cn(obj.klass) else: klass = obj.klass init = [ '\n', '# Menu Bar\n', 'self.%s = %s()\n' % (obj.name, klass) ] ## 'self.SetMenuBar(self.%s)\n' % obj.name ] init.extend(self.get_init_code(obj)) init.append('self.SetMenuBar(self.%s)\n' % obj.name) init.append('# Menu Bar end\n') return init, [], [] def get_events(self, obj): pygen = common.code_writers['python'] cn = pygen.cn out = [] #print 'get_events', obj.properties['menubar'] def do_get(item): ret = [] if item.name: val = '#self.%s' % item.name # see py_codegen.py, ~480 else: name, val = pygen.generate_code_id(None, item.id) if not val: val = '-1' # but this is wrong anyway... if item.handler: ret.append((val, 'EVT_MENU', item.handler)) if item.children: for c in item.children: ret.extend(do_get(c)) return ret for menu in obj.properties['menubar']: out.extend(do_get(menu.root)) return out # end of class PythonCodeGenerator class MenuHandler: """Handler for menus and menu items of a menubar""" item_attrs = ('label', 'id', 'name', 'help_str', 'checkable', 'radio', 'handler') def __init__(self): self.menu_depth = 0 self.menus = [] self.curr_menu = None self.curr_item = None self.attr_val = [] def start_elem(self, name, attrs): if name == 'menu': self.menu_depth += 1 label = attrs['label'] if self.menu_depth == 1: t = MenuTree(attrs['name'], label) self.curr_menu = t.root self.menus.append(t) return id = attrs.get('itemid', '') handler = attrs.get('handler', '') node = MenuTree.Node(label=label, name=attrs['name'], id=id, handler=handler) node.parent = self.curr_menu self.curr_menu.children.append(node) self.curr_menu = node elif name == 'item': self.curr_item = MenuTree.Node() def end_elem(self, name, code_obj): if name == 'menus': code_obj.properties['menubar'] = self.menus return True if name == 'item' and self.curr_menu: self.curr_menu.children.append(self.curr_item) self.curr_item.parent = self.curr_menu elif name == 'menu': self.menu_depth -= 1 self.curr_menu = self.curr_menu.parent elif name in self.item_attrs: setattr(self.curr_item, name, "".join(self.attr_val)) self.attr_val = [] def char_data(self, data): self.attr_val.append(data) # end of class MenuHandler def xrc_code_generator(obj): """\ function that generates XRC code for the menubar of a wxFrame. """ from xml.sax.saxutils import escape, quoteattr xrcgen = common.code_writers['XRC'] class MenuBarXrcObject(xrcgen.DefaultXrcObject): def append_item(self, item, outfile, tabs): write = outfile.write if item.name == '---': # item is a separator write(' '*tabs + '\n') else: if item.children: name = self.get_name(item) if name: write(' '*tabs + '\n' % quoteattr(name)) else: write(' '*tabs + '\n') else: name = self.get_name(item) if name: write(' '*tabs + '\n' % quoteattr(name)) else: write(' '*tabs + '\n') if item.label: # translate & into _ as accelerator marker val = item.label.replace('&', '_') write(' '*(tabs+1) + '\n' % \ escape(val)) if item.help_str: write(' '*(tabs+1) + '%s\n' % \ escape(item.help_str)) if item.children: for c in item.children: self.append_item(c, outfile, tabs+1) elif item.checkable == '1': write(' '*(tabs+1) + '1\n') elif item.radio == '1': write(' '*(tabs+1) + '1\n') write(' '*tabs + '\n') def get_name(self, item): if item.name: return item.name.strip() tokens = item.id.split('=') if tokens: return tokens[0].strip() def write(self, outfile, tabs): menus = self.code_obj.properties['menubar'] write = outfile.write write(' '*tabs + '\n' % \ quoteattr(self.name)) for m in menus: self.append_item(m.root, outfile, tabs+1) write(' '*tabs + '\n') # end of class MenuBarXrcObject return MenuBarXrcObject(obj) class CppCodeGenerator: constructor = [] def get_code(self, obj): """\ generates C++ code for the menubar of a wxFrame. """ cppgen = common.code_writers['C++'] menus = obj.properties['menubar'] init = [ '%s = new %s();\n' % (obj.name, obj.klass) ] init.extend(self.get_properties_code(obj)) init.append('SetMenuBar(%s);\n' % obj.name) ids = self.get_ids_code(obj) return init, ids, [], [] def get_properties_code(self, obj): cppgen = common.code_writers['C++'] menus = obj.properties['menubar'] out = [] append = out.append def append_items(menu, items): for item in items: if item.name == '---': # item is a separator append('%s->AppendSeparator();\n' % menu) continue name, val = cppgen.generate_code_id(None, item.id) if not name and val == '-1': id = 'wxNewId()' else: #if name: ids.append(name) id = val if item.children: if item.name: name = item.name else: name = '%s_sub' % menu append('wxMenu* %s = new wxMenu();\n' % name) ## if item.id: # generating id ## tokens = item.id.split('=') ## if len(tokens) > 1: ## id = tokens[0] ## else: ## id = item.id ## else: id = 'wxNewId()' append_items(name, item.children) append('%s->Append(%s, %s, %s, %s);\n' % (menu, id, cppgen.quote_str(item.label), name, cppgen.quote_str(item.help_str))) else: ## if item.id: ## tokens = item.id.split('=') ## if len(tokens) > 1: ## id = tokens[0] ## else: ## id = item.id ## else: ## id = 'wxNewId()' item_type = 'wxITEM_NORMAL' if item.checkable == '1': item_type = 'wxITEM_CHECK' elif item.radio == '1': item_type = 'wxITEM_RADIO' if item_type: append('%s->Append(%s, %s, %s, %s);\n' % (menu, id, cppgen.quote_str(item.label), cppgen.quote_str(item.help_str), item_type)) else: append('%s->Append(%s, %s, %s);\n' % (menu, id, cppgen.quote_str(item.label), cppgen.quote_str(item.help_str))) #print 'menus = %s' % menus if obj.is_toplevel: obj_name = '' else: obj_name = obj.name + '->' i = 1 for m in menus: menu = m.root if menu.name: name = menu.name else: name = 'wxglade_tmp_menu_%s' % i i += 1 append('wxMenu* %s = new wxMenu();\n' % name) if menu.children: append_items(name, menu.children) append('%sAppend(%s, %s);\n' % (obj_name, name, cppgen.quote_str(menu.label))) return out def get_ids_code(self, obj): cppgen = common.code_writers['C++'] ids = [] menus = obj.properties['menubar'] def collect_ids(items): for item in items: if item.name == '---': # item is a separator continue # do nothing name, val = cppgen.generate_code_id(None, item.id) if name.find('=') != -1: ids.append(name) if item.children: ## if item.id: # generating id ## tokens = item.id.split('=') ## if len(tokens) > 1: ## id = tokens[0] ## ids.append(' = '.join(tokens)) collect_ids(item.children) ## else: ## if item.id: ## tokens = item.id.split('=') ## if len(tokens) > 1: ## id = tokens[0] ## ids.append(' = '.join(tokens)) for m in menus: if m.root.children: collect_ids(m.root.children) return ids def get_events(self, obj): cppgen = common.code_writers['C++'] out = [] def do_get(item): ret = [] name, val = cppgen.generate_code_id(None, item.id) if not val: val = '-1' # but this is wrong anyway... if item.handler: ret.append((val, 'EVT_MENU', item.handler, 'wxCommandEvent')) if item.children: for c in item.children: ret.extend(do_get(c)) return ret for menu in obj.properties['menubar']: out.extend(do_get(menu.root)) return out # end of class CppCodeGenerator def initialize(): common.class_names['EditMenuBar'] = 'wxMenuBar' common.toplevels['EditMenuBar'] = 1 pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxMenuBar', PythonCodeGenerator()) pygen.add_property_handler('menus', MenuHandler) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxMenuBar', xrc_code_generator) xrcgen.add_property_handler('menus', MenuHandler) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxMenuBar', CppCodeGenerator()) cppgen.add_property_handler('menus', MenuHandler) wxglade-0.6.8.orig/widgets/menubar/menubar.py0000644000175000017500000010300711700370023021411 0ustar georgeskgeorgesk# menubar.py: wxMenuBar objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from tree import Tree from MenuTree import * from widget_properties import * from edit_windows import EditBase, PreviewMixin class MenuItemDialog(wx.Dialog): def __init__(self, parent, owner, items=None): wx.Dialog.__init__(self, parent, -1, _("Menu editor"), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) ADD_ID, REMOVE_ID, NAME_ID, LABEL_ID, ID_ID, CHECK_RADIO_ID, LIST_ID, \ ADD_SEP_ID, MOVE_LEFT_ID, MOVE_RIGHT_ID, MOVE_UP_ID, \ MOVE_DOWN_ID, HELP_STR_ID = [wx.NewId() for i in range(13)] self._staticbox = wx.StaticBox(self, -1, _("Menu item:")) self.owner = owner self.menu_items = wx.ListCtrl(self, LIST_ID, style=wx.LC_REPORT | \ wx.LC_SINGLE_SEL|wx.SUNKEN_BORDER) # ALB 2004-09-26: workaround to make the scroll wheel work... wx.EVT_MOUSEWHEEL(self.menu_items, lambda e: e.Skip()) self.menu_items.InsertColumn(0, _("Label")) self.menu_items.InsertColumn(1, _("Id")) self.menu_items.InsertColumn(2, _("Name")) self.menu_items.InsertColumn(3, _("Help String")) self.menu_items.InsertColumn(4, _("Type")) # ALB 2004-12-05 self.menu_items.InsertColumn(5, _("Event Handler")) self.menu_items.SetColumnWidth(0, 250) self.menu_items.SetColumnWidth(2, 250) self.menu_items.SetColumnWidth(3, 250) self.menu_items.SetColumnWidth(5, 250) # menu item fields self.id = wx.TextCtrl(self, ID_ID) self.label = wx.TextCtrl(self, LABEL_ID) self.name = wx.TextCtrl(self, NAME_ID) self.help_str = wx.TextCtrl(self, HELP_STR_ID) # ALB 2004-12-05 self.event_handler = wx.TextCtrl(self, -1) import re self.handler_re = re.compile(r'^\s*\w*\s*$') #self.checkable = wx.CheckBox(self, CHECK_ID, "") #Checkable") self.check_radio = wx.RadioBox( self, CHECK_RADIO_ID, _("Type"), choices=['Normal', 'Checkable', 'Radio'], majorDimension=3) self.add = wx.Button(self, ADD_ID, _("Add")) self.remove = wx.Button(self, REMOVE_ID, _("Remove")) self.add_sep = wx.Button(self, ADD_SEP_ID, _("Add separator")) # menu items navigation self.move_up = wx.Button(self, MOVE_UP_ID, _("Up")) self.move_down = wx.Button(self, MOVE_DOWN_ID, _("Down")) self.move_left = wx.Button(self, MOVE_LEFT_ID, " < ") self.move_right = wx.Button(self, MOVE_RIGHT_ID, " > ") self.ok = wx.Button(self, wx.ID_OK, _("OK")) self.apply = wx.Button(self, wx.ID_APPLY, _("Apply")) self.cancel = wx.Button(self, wx.ID_CANCEL, _("Cancel")) self.do_layout() self.selected_index = -1 # index of the selected element in the # wx.ListCtrl menu_items # event handlers wx.EVT_BUTTON(self, ADD_ID, self.add_menu_item) wx.EVT_BUTTON(self, REMOVE_ID, self.remove_menu_item) wx.EVT_BUTTON(self, ADD_SEP_ID, self.add_separator) wx.EVT_BUTTON(self, MOVE_LEFT_ID, self.move_item_left) wx.EVT_BUTTON(self, MOVE_RIGHT_ID, self.move_item_right) wx.EVT_BUTTON(self, MOVE_UP_ID, self.move_item_up) wx.EVT_BUTTON(self, MOVE_DOWN_ID, self.move_item_down) wx.EVT_BUTTON(self, wx.ID_APPLY, self.on_apply) wx.EVT_KILL_FOCUS(self.name, self.update_menu_item) wx.EVT_KILL_FOCUS(self.label, self.update_menu_item) wx.EVT_KILL_FOCUS(self.id, self.update_menu_item) wx.EVT_KILL_FOCUS(self.help_str, self.update_menu_item) # ALB 2004-12-05 wx.EVT_KILL_FOCUS(self.event_handler, self.update_menu_item) #wx.EVT_CHECKBOX(self, CHECK_ID, self.update_menu_item) wx.EVT_RADIOBOX(self, CHECK_RADIO_ID, self.update_menu_item) wx.EVT_LIST_ITEM_SELECTED(self, LIST_ID, self.show_menu_item) if items: self.add_items(items) def do_layout(self): self.label.Enable(False) self.id.Enable(False) self.name.Enable(False) self.help_str.Enable(False) self.event_handler.Enable(False) self.check_radio.Enable(False) sizer = wx.BoxSizer(wx.VERTICAL) sizer2 = wx.StaticBoxSizer(self._staticbox, wx.VERTICAL) self.label.SetSize((150, -1)) self.id.SetSize((150, -1)) self.name.SetSize((150, -1)) self.help_str.SetSize((150, -1)) self.event_handler.SetSize((150, -1)) szr = wx.FlexGridSizer(0, 2) flag = wx.FIXED_MINSIZE label_flag = wx.ALIGN_CENTER_VERTICAL szr.Add(wx.StaticText(self, -1, _("Id ")), flag=label_flag) szr.Add(self.id, flag=flag) szr.Add(wx.StaticText(self, -1, _("Label ")), flag=label_flag) szr.Add(self.label, flag=flag) szr.Add(wx.StaticText(self, -1, _("Name ")), flag=label_flag) szr.Add(self.name, flag=flag) szr.Add(wx.StaticText(self, -1, _("Help String ")), flag=label_flag) szr.Add(self.help_str, flag=flag) szr.Add(wx.StaticText(self, -1, _("Event Handler ")), flag=label_flag) szr.Add(self.event_handler, flag=flag) sizer2.Add(szr, 1, wx.ALL|wx.EXPAND, 5) sizer2.Add(self.check_radio, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM, 4) szr = wx.GridSizer(0, 2, 3, 3) szr.Add(self.add, 0, wx.EXPAND); szr.Add(self.remove, 0, wx.EXPAND) sizer2.Add(szr, 0, wx.EXPAND) sizer2.Add(self.add_sep, 0, wx.TOP|wx.EXPAND, 3) sizer3 = wx.BoxSizer(wx.VERTICAL) sizer3.Add(self.menu_items, 1, wx.ALL|wx.EXPAND, 5) sizer4 = wx.BoxSizer(wx.HORIZONTAL) sizer4.Add(self.move_up, 0, wx.LEFT|wx.RIGHT, 3) sizer4.Add(self.move_down, 0, wx.LEFT|wx.RIGHT, 5) sizer4.Add(self.move_left, 0, wx.LEFT|wx.RIGHT, 5) sizer4.Add(self.move_right, 0, wx.LEFT|wx.RIGHT, 5) sizer3.Add(sizer4, 0, wx.ALIGN_CENTER|wx.ALL, 5) szr = wx.BoxSizer(wx.HORIZONTAL) szr.Add(sizer3, 1, wx.ALL|wx.EXPAND, 5) szr.Add(sizer2, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5) sizer.Add(szr, 1, wx.EXPAND) sizer2 = wx.BoxSizer(wx.HORIZONTAL) sizer2.Add(self.ok, 0, wx.ALL, 5) sizer2.Add(self.apply, 0, wx.ALL, 5) sizer2.Add(self.cancel, 0, wx.ALL, 5) sizer.Add(sizer2, 0, wx.ALL|wx.ALIGN_CENTER, 3) self.SetAutoLayout(1) self.SetSizer(sizer) sizer.Fit(self) self.SetSize((-1, 350)) self.CenterOnScreen() def _enable_fields(self, enable=True): for s in (self.label, self.id, self.name, self.help_str, self.check_radio, self.event_handler): s.Enable(enable) def add_menu_item(self, event): """\ Event handler called when the Add button is clicked """ index = self.selected_index = self.selected_index+1 if not self.menu_items.GetItemCount(): self._enable_fields() ## for s in (self.label, self.id, self.name, self.help_str, ## self.check_radio, self.event_handler): ## s.Enable(True) if index < 0: index = self.menu_items.GetItemCount() elif index > 0: indent = " " * self.item_level(index-1) else: indent = "" name, label, id, check_radio = "", "item", "", "0" self.menu_items.InsertStringItem(index, indent + label) self.menu_items.SetStringItem(index, 1, id) self.menu_items.SetStringItem(index, 2, name) self.menu_items.SetStringItem(index, 4, check_radio) # fix bug 698074 self.menu_items.SetItemState(index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) self.name.SetValue(name) self.label.SetValue(label) self.id.SetValue(id) self.check_radio.SetSelection(int(check_radio)) self.event_handler.SetValue("") def add_separator(self, event): """\ Event handler called when the Add Separator button is clicked """ index = self.selected_index+1 if not self.menu_items.GetItemCount(): self._enable_fields() ## for s in (self.label, self.id, self.name, self.help_str, ## self.check_radio, self.event_handler): ## s.Enable(True) if index < 0: index = self.menu_items.GetItemCount() elif index > 0: label = " " * self.item_level(index-1) + '---' else: label = '---' self.menu_items.InsertStringItem(index, label) self.menu_items.SetStringItem(index, 1, '---') self.menu_items.SetStringItem(index, 2, '---') # fix bug 698074 self.menu_items.SetItemState(index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) def show_menu_item(self, event): """\ Event handler called when a menu item in the list is selected """ self.selected_index = index = event.GetIndex() if not misc.streq(self.menu_items.GetItem(index, 2).m_text, '---'): # skip if the selected item is a separator for (s, i) in ((self.label, 0), (self.id, 1), (self.name, 2), (self.help_str, 3), (self.event_handler, 5)): s.SetValue(self.menu_items.GetItem(index, i).m_text) self.label.SetValue(self.label.GetValue().lstrip()) try: self.check_radio.SetSelection( int(self.menu_items.GetItem(index, 4).m_text)) except: self.check_radio.SetSelection(0) event.Skip() def update_menu_item(self, event): """\ Event handler called when some of the properties of the current menu item changes """ set_item = self.menu_items.SetStringItem index = self.selected_index val = self.event_handler.GetValue() if not self.handler_re.match(val): event.GetEventObject().SetFocus() return if index < 0: return event.Skip() set_item(index, 0, " " * self.item_level(index) + \ self.label.GetValue().lstrip()) set_item(index, 1, self.id.GetValue()) set_item(index, 2, self.name.GetValue()) set_item(index, 3, self.help_str.GetValue()) set_item(index, 4, str(self.check_radio.GetSelection())) set_item(index, 5, self.event_handler.GetValue()) event.Skip() def item_level(self, index, label=None): """\ returns the indentation level of the menu item at the given index """ label = self.menu_items.GetItem(index, 0).m_text return (len(label) - len(label.lstrip())) / 4 def remove_menu_item(self, event): """\ Event handler called when the Remove button is clicked """ if self.selected_index >= 0: index = self.selected_index+1 if index < self.menu_items.GetItemCount() and \ (self.item_level(self.selected_index) < self.item_level(index)): self._move_item_left(index) self.selected_index = index-1 for s in (self.name, self.id, self.label, self.help_str, self.event_handler): s.SetValue("") self.check_radio.SetSelection(0) self.menu_items.DeleteItem(self.selected_index) if not self.menu_items.GetItemCount(): self._enable_fields(False) ## for s in (self.name, self.id, self.label, \ ## self.help_str, self.check_radio, self.event_handler): ## s.Enable(False) def add_items(self, menus): """\ adds the content of 'menus' to self.menu_items. menus is a sequence of trees which describes the structure of the menus """ indent = " " * 4 set_item = self.menu_items.SetStringItem add_item = self.menu_items.InsertStringItem index = [0] def add(node, level): i = index[0] add_item(i, misc.wxstr(indent * level + node.label.lstrip())) set_item(i, 1, misc.wxstr(node.id)) set_item(i, 2, misc.wxstr(node.name)) set_item(i, 3, misc.wxstr(node.help_str)) # ALB 2004-12-05 set_item(i, 5, misc.wxstr(node.handler)) item_type = 0 try: if node.checkable and int(node.checkable): item_type = 1 elif int(node.radio): item_type = 2 except ValueError: pass set_item(i, 4, misc.wxstr(item_type)) index[0] += 1 for item in node.children: add(item, level+1) for tree in menus: add(tree.root, 0) if self.menu_items.GetItemCount(): self._enable_fields() ## for s in (self.name, self.id, self.label, \ ## self.help_str, self.check_radio, self.event_handler): ## s.Enable(True) def get_menus(self): """\ returns the contents of self.menu_items as a list of trees which describe the structure of the menus in the format used by EditMenuBar """ def get(i, j): return self.menu_items.GetItem(i, j).m_text trees = [] def add(node, index): label = get(index, 0).lstrip() id = get(index, 1) name = get(index, 2) help_str = get(index, 3) event_handler = get(index, 5) try: item_type = int(get(index, 4)) except ValueError: item_type = 0 checkable = item_type == 1 and misc.wxstr("1") or misc.wxstr("") radio = item_type == 2 and misc.wxstr("1") or misc.wxstr("") n = MenuTree.Node(label, id, name, help_str, checkable, radio, handler=event_handler) node.children.append(n) n.parent = node return n level = 0 curr_item = None for index in range(self.menu_items.GetItemCount()): label = get(index, 0) lvl = self.item_level(index) # get the indentation level if not lvl: t = MenuTree(get(index, 2), label, id=get(index, 1), handler=get(index, 5)) curr_item = t.root level = 1 trees.append(t) continue elif lvl < level: for i in range(level-lvl): curr_item = curr_item.parent level = lvl elif lvl > level: curr_item = curr_item.children[-1] level = lvl add(curr_item, index) return trees def _move_item_left(self, index): if index > 0: if (index+1 < self.menu_items.GetItemCount() and \ (self.item_level(index) < self.item_level(index+1))): return label = self.menu_items.GetItem(index, 0).m_text if misc.streq(label[:4], " " * 4): self.menu_items.SetStringItem(index, 0, label[4:]) self.menu_items.SetItemState(index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) def move_item_left(self, event): """\ moves the selected menu item one level up in the hierarchy, i.e. shifts its label 4 spaces left in self.menu_items """ self.menu_items.SetFocus() self._move_item_left(self.selected_index) def _move_item_right(self, index): if index > 0 and (self.item_level(index) <= self.item_level(index-1)): label = self.menu_items.GetItem(index, 0).m_text self.menu_items.SetStringItem(index, 0, misc.wxstr(" " * 4) + label) self.menu_items.SetItemState(index, wx.LIST_STATE_SELECTED, \ wx.LIST_STATE_SELECTED) def move_item_right(self, event): """\ moves the selected menu item one level down in the hierarchy, i.e. shifts its label 4 spaces right in self.menu_items """ self.menu_items.SetFocus() self._move_item_right(self.selected_index) def move_item_up(self, event): """\ moves the selected menu item before the previous one at the same level in self.menu_items """ self.menu_items.SetFocus() index = self._do_move_item(event, self.selected_index, False) if index is not None: state = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED self.menu_items.SetItemState(index, state, state) def _do_move_item(self, event, index, is_down): """\ internal function used by move_item_up and move_item_down. Returns the new index of the moved item, or None if no change occurred """ #index = self.selected_index if index <= 0: return None def get(i, j): return self.menu_items.GetItem(i, j).m_text def getall(i): return [get(i, j) for j in range(6)] level = self.item_level(index) items_to_move = [ getall(index) ] i = index+1 while i < self.menu_items.GetItemCount(): # collect the items to move up if level < self.item_level(i): items_to_move.append(getall(i)) i += 1 else: break i = index-1 while i >= 0: lvl = self.item_level(i) if level == lvl: break elif level > lvl: return None i -= 1 delete = self.menu_items.DeleteItem insert = self.menu_items.InsertStringItem set = self.menu_items.SetStringItem for j in range(len(items_to_move)-1, -1, -1): delete(index+j) items_to_move.reverse() for label, id, name, help_str, check_radio, event_handler in \ items_to_move: i = insert(i, label) set(i, 1, id) set(i, 2, name) set(i, 3, help_str) set(i, 4, check_radio) set(i, 5, event_handler) ret_idx = i if is_down: ret_idx += len(items_to_move) return ret_idx def move_item_down(self, event): """\ moves the selected menu item after the next one at the same level in self.menu_items """ self.menu_items.SetFocus() index = self.selected_index self.selected_index = -1 if index < 0: return def get(i, j): return self.menu_items.GetItem(i, j).m_text def getall(i): return [get(i, j) for j in range(6)] level = self.item_level(index) i = index+1 while i < self.menu_items.GetItemCount(): # collect the items to move down if level < self.item_level(i): i += 1 else: break if i < self.menu_items.GetItemCount(): # _do_move_item works with selected_index, so we must assing to # it the rigth value before the call #self.selected_index = i self.selected_index = self._do_move_item(event, i, True) # fix bug 698071 state = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED self.menu_items.SetItemState(self.selected_index, state, state) else: # restore the selected index self.selected_index = index def on_apply(self, event): self.owner.set_menus(self.get_menus()) common.app_tree.app.saved = False #end of class MenuItemDialog class MenuProperty(Property): """\ Property to edit the menus of an EditMenuBar instance. """ def __init__(self, owner, name, parent): Property.__init__(self, owner, name, parent) self.panel = None self.menu_items = {} if parent is not None: self.display(parent) def display(self, parent): self.panel = wx.Panel(parent, -1) edit_btn_id = wx.NewId() self.edit_btn = wx.Button(self.panel, edit_btn_id, _("Edit menus...")) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.edit_btn, 1, wx.EXPAND|wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM, 4) self.panel.SetAutoLayout(1) self.panel.SetSizer(sizer) self.panel.SetSize(sizer.GetMinSize()) wx.EVT_BUTTON(self.panel, edit_btn_id, self.edit_menus) def bind_event(*args): pass def edit_menus(self, event): dialog = MenuItemDialog(self.panel, self.owner, items=self.owner.get_menus()) if dialog.ShowModal() == wx.ID_OK: self.owner.set_menus(dialog.get_menus()) common.app_tree.app.saved = False # update the status of the app def write(self, outfile, tabs): fwrite = outfile.write fwrite(' ' * tabs + '\n') for menu in self.owner[self.name][0](): menu.write(outfile, tabs+1) fwrite(' ' * tabs + '\n') # end of class MenuProperty class EditMenuBar(EditBase, PreviewMixin): __hidden_frame = None # used on GTK to reparent a menubar before deletion def __init__(self, name, klass, parent, property_window): custom_class = parent is None EditBase.__init__(self, name, klass, parent, wx.NewId(), property_window, custom_class=custom_class, show=False) self.base = 'wxMenuBar' def nil(*args): return () self.menus = [] # list of MenuTree objects self._mb = None # the real menubar self.access_functions['menus'] = (self.get_menus, self.set_menus) prop = self.properties['menus'] = MenuProperty(self, 'menus', None) ## self.node = Tree.Node(self) ## common.app_tree.add(self.node, parent.node) PreviewMixin.__init__(self) def create_widget(self): if wx.Platform == '__WXGTK__' and not EditMenuBar.__hidden_frame: EditMenuBar.__hidden_frame = wx.Frame(common.palette, -1, "") EditMenuBar.__hidden_frame.Hide() if self.parent: self.widget = self._mb = wx.MenuBar() if self.parent.widget: self.parent.widget.SetMenuBar(self.widget) if wx.Platform == '__WXMSW__' or wx.Platform == '__WXMAC__': self.widget.SetFocus = lambda : None else: # "top-level" menubar self.widget = wx.Frame(None, -1, misc.design_title(self.name)) self.widget.SetClientSize((400, 30)) self._mb = wx.MenuBar() self.widget.SetMenuBar(self._mb) self.widget.SetBackgroundColour(self._mb.GetBackgroundColour()) import os icon = wx.EmptyIcon() xpm = os.path.join(common.icons_path, 'menubar.xpm') icon.CopyFromBitmap(misc.get_xpm_bitmap(xpm)) self.widget.SetIcon(icon) wx.EVT_CLOSE(self.widget, lambda e: self.hide_widget()) wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) self.set_menus(self.menus) # show the menus def create_properties(self): EditBase.create_properties(self) page = self._common_panel sizer = page.GetSizer() self.properties['menus'].display(page) if not sizer: sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.name_prop.panel, 0, wx.EXPAND) sizer.Add(self.klass_prop.panel, 0, wx.EXPAND) page.SetAutoLayout(1) page.SetSizer(sizer) sizer.Add(self.properties['menus'].panel, 0, wx.ALL|wx.EXPAND, 3) sizer.Fit(page) page.SetSize(self.notebook.GetClientSize()) sizer.Layout() self.notebook.AddPage(page, _("Common")) if self.parent is not None: self.property_window.Layout() else: PreviewMixin.create_properties(self) def __getitem__(self, key): return self.access_functions[key] def get_menus(self): return self.menus def set_menus(self, menus): self.menus = menus if not self._mb: return # nothing left to do for i in range(self._mb.GetMenuCount()): self._mb.Remove(0) def append(menu, items): for item in items: if misc.streq(item.name, '---'): # item is a separator menu.AppendSeparator() elif item.children: m = wx.Menu() append(m, item.children) menu.AppendMenu(wx.NewId(), misc.wxstr(item.label), m, misc.wxstr(item.help_str)) else: check_radio = 0 try: if int(item.checkable): check_radio = 1 except: check_radio = 0 if not check_radio: try: if int(item.radio): check_radio = 2 except: check_radio = 0 menu.Append(wx.NewId(), misc.wxstr(item.label), misc.wxstr(item.help_str), check_radio) first = self._mb.GetMenuCount() for menu in self.menus: m = wx.Menu() append(m, menu.root.children) if first: self._mb.Replace(0, m, misc.wxstr(menu.root.label)) first = 0 else: self._mb.Append(m, misc.wxstr(menu.root.label)) self._mb.Refresh() def remove(self, *args, **kwds): if self.parent is not None: self.parent.properties['menubar'].set_value(0) if kwds.get('gtk_do_nothing', False) and wx.Platform == '__WXGTK__': # workaround to prevent some segfaults on GTK: unfortunately, # I'm not sure that this works in all cases, and moreover it # could probably leak some memory (but I'm not sure) self.widget = None else: if self.parent.widget: self.parent.widget.SetMenuBar(None) else: if self.widget: self.widget.Destroy() self.widget = None EditBase.remove(self) def popup_menu(self, event): if self.parent is not None: return # do nothing in this case if self.widget: if not self._rmenu: REMOVE_ID, HIDE_ID = [wx.NewId() for i in range(2)] self._rmenu = misc.wxGladePopupMenu(self.name) misc.append_item(self._rmenu, REMOVE_ID, _('Remove\tDel'), wx.ART_DELETE) misc.append_item(self._rmenu, HIDE_ID, _('Hide')) def bind(method): return lambda e: wx.CallAfter(method) wx.EVT_MENU(self.widget, REMOVE_ID, bind(self.remove)) wx.EVT_MENU(self.widget, HIDE_ID, bind(self.hide_widget)) self.widget.PopupMenu(self._rmenu, event.GetPosition()) def hide_widget(self, *args): if self.widget and self.widget is not self._mb: self.widget.Hide() common.app_tree.expand(self.node, False) common.app_tree.select_item(self.node.parent) common.app_tree.app.show_properties() ## def show_widget(self, yes): ## EditBase.show_widget(self, yes) ## if self._frame: ## self._frame.Show(yes) def set_name(self, name): EditBase.set_name(self, name) if self.widget is not self._mb: self.widget.SetTitle(misc.design_title(misc.wxstr(self.name))) def get_property_handler(self, name): class MenuHandler: itemattrs = ['label', 'id', 'name', 'help_str', 'checkable', 'radio', 'handler'] def __init__(self, owner): self.owner = owner self.menu_items = [] self.curr_menu = [] self.curr_item = None self.curr_index = 0 self.menu_depth = 0 def start_elem(self, name, attrs): if name == 'menus': return if name == 'menu': self.menu_depth += 1 label = misc._encode(attrs['label']) if self.menu_depth == 1: t = MenuTree(attrs['name'], label, attrs.get('itemid', ''), attrs.get('help_str', ''), handler=attrs.get('handler', '')) self.curr_menu.append( (t.root,) ) self.owner.menus.append(t) return node = MenuTree.Node(label=label, name=attrs['name'], id=attrs.get('itemid', ''), help_str=attrs.get('help_str', ''), handler=attrs.get('handler', '')) cm = self.curr_menu[-1] cm[0].children.append(node) node.parent = cm[0] menu = wx.Menu() self.curr_menu.append( (node, menu) ) elif name == 'item': self.curr_item = MenuTree.Node() else: try: self.curr_index = self.itemattrs.index(name) except ValueError: # ignore unknown attributes... self.curr_index = -1 pass ## from xml_parse import XmlParsingError ## raise XmlParsingError, _("invalid menu item attribute") def end_elem(self, name): if name == 'item': try: cm = self.curr_menu[-1] except IndexError: from xml_parse import XmlParsingError raise XmlParsingError, _("menu item outside a menu") cm[0].children.append(self.curr_item) self.curr_item.parent = cm[0] elif name == 'menu': self.menu_depth -= 1 self.curr_menu.pop() elif name == 'menus': self.owner.set_menus(self.owner.menus) return True def char_data(self, data): setattr(self.curr_item, self.itemattrs[self.curr_index], data) if name == 'menus': return MenuHandler(self) return None # end of class EditMenuBar def builder(parent, sizer, pos, number=[0]): """\ factory function for EditMenuBar objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, _('Select menubar class')) if common.app_tree.app.get_language().lower() == 'xrc': self.klass = 'wxMenuBar' else: if not number[0]: self.klass = 'MyMenuBar' else: self.klass = 'MyMenuBar%s' % number[0] number[0] += 1 klass_prop = TextProperty(self, 'class', self, label=_('class')) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(klass_prop.panel, 0, wx.EXPAND) sz2 = wx.BoxSizer(wx.HORIZONTAL) sz2.Add(wx.Button(self, wx.ID_OK, _('OK')), 0, wx.ALL, 3) sz2.Add(wx.Button(self, wx.ID_CANCEL, _('Cancel')), 0, wx.ALL, 3) szr.Add(sz2, 0, wx.ALL|wx.ALIGN_CENTER, 3) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) if self.GetBestSize()[0] < 150: self.SetSize((150, -1)) self.CenterOnScreen() def undo(self): if number[0] > 0: number[0] -= 1 def __getitem__(self, value): if value == 'class': def set_klass(c): self.klass = c return (lambda : self.klass, set_klass) # end of inner class dialog = Dialog() if dialog.ShowModal() == wx.ID_CANCEL: # cancel the operation dialog.undo() dialog.Destroy() return name = 'menubar_%d' % (number[0] or 1) while common.app_tree.has_name(name): number[0] += 1 name = 'menubar_%d' % number[0] mb = EditMenuBar(name, dialog.klass, parent, common.property_panel) mb.node = Tree.Node(mb) common.app_tree.add(mb.node) mb.show_widget(True) mb.show_properties() def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditMenuBar objects from an xml file """ name = attrs.get('name') if parent is not None: if name: parent.menubar.set_name(name) parent.menubar.name_prop.set_value(name) return parent.menubar else: mb = EditMenuBar(name, attrs.get('class', 'wxMenuBar'), None, common.property_panel) mb.node = Tree.Node(mb) common.app_tree.add(mb.node) return mb def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ cwx = common.widgets_from_xml cwx['EditMenuBar'] = xml_builder common.widgets['EditMenuBar'] = builder return common.make_object_button('EditMenuBar', 'icons/menubar.xpm', 1) wxglade-0.6.8.orig/widgets/menubar/__init__.py0000644000175000017500000000074511621715605021537 0ustar georgeskgeorgesk# __init__.py: menubar widget module initialization # $Id: __init__.py,v 1.5 2007/03/27 07:01:57 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import menubar global EditMenuBar; EditMenuBar = menubar.EditMenuBar return menubar.initialize() wxglade-0.6.8.orig/widgets/ChoicesProperty.py0000644000175000017500000000433711621715605021472 0ustar georgeskgeorgesk# ChoicesProperty.py: defines a Property and two handlers used by choice, # combo_box, radio_box, list_box # $Id: ChoicesProperty.py,v 1.8 2007/03/27 07:02:05 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import widget_properties class ChoicesProperty(widget_properties.GridProperty): def write(self, outfile, tabs): from xml.sax.saxutils import escape write = outfile.write write(' ' * tabs + '\n') tab_s = ' ' * (tabs+1) for val in self.get_value(): v = widget_properties._encode(val[0]) try: checked = int(val[1]) except (IndexError, ValueError): checked = None if checked is None: write('%s%s\n' % (tab_s, escape(v))) else: write('%s%s\n' % \ (tab_s, checked, escape(v))) write(' ' * tabs + '\n') # end of class ChoicesProperty class ChoicesHandler: def __init__(self, owner): self.choices = [] self.curr_choice = [] self.cur_checked = None self.owner = owner def start_elem(self, name, attrs): if name == 'choice': try: self.cur_checked = int(attrs['checked']) except (KeyError, ValueError): self.cur_checked = None def end_elem(self, name): if name == 'choice': if self.cur_checked is None: self.choices.append(["".join(self.curr_choice)]) else: self.choices.append(["".join(self.curr_choice), self.cur_checked]) self.curr_choice = [] self.cur_checked = None elif name == 'choices': self.owner.set_choices(self.choices) self.owner.properties['choices'].set_value( self.owner.get_choices()) self.choices = [] return True # remove the handler def char_data(self, data): self.curr_choice.append(data) # end of class ChoicesHandler wxglade-0.6.8.orig/widgets/list_ctrl/0000755000175000017500000000000012170277707017774 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/list_ctrl/perl_codegen.py0000644000175000017500000000251111677431747023002 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxListCtrl objects # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not(style and style != 'wxLC_ICON'): # default style style = '' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, style)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditListCtrl'] = 'wxListCtrl' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxListCtrl', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/list_ctrl/list_ctrl.py0000644000175000017500000002261411677431710022347 0ustar georgeskgeorgesk# text_ctrl.py: wxListCtrl objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx from edit_windows import ManagedBase from tree import Tree import common from widget_properties import * class EditListCtrl(ManagedBase): """\ Class to handle wxListCtrl objects """ events = [ 'EVT_LIST_BEGIN_DRAG', 'EVT_LIST_BEGIN_RDRAG', 'EVT_LIST_BEGIN_LABEL_EDIT', 'EVT_LIST_END_LABEL_EDIT', 'EVT_LIST_DELETE_ITEM', 'EVT_LIST_DELETE_ALL_ITEMS', 'EVT_LIST_ITEM_SELECTED', 'EVT_LIST_ITEM_DESELECTED', 'EVT_LIST_ITEM_ACTIVATED', 'EVT_LIST_ITEM_FOCUSED', 'EVT_LIST_ITEM_MIDDLE_CLICK', 'EVT_LIST_ITEM_RIGHT_CLICK', 'EVT_LIST_KEY_DOWN', 'EVT_LIST_INSERT_ITEM', 'EVT_LIST_COL_CLICK', 'EVT_LIST_COL_RIGHT_CLICK', 'EVT_LIST_COL_BEGIN_DRAG', 'EVT_LIST_COL_DRAGGING', 'EVT_LIST_COL_END_DRAG', 'EVT_LIST_CACHE_HINT', ] def __init__(self, name, parent, id, sizer, pos, property_window, show=True, style=wx.LC_REPORT|wx.SUNKEN_BORDER): ManagedBase.__init__(self, name, 'wxListCtrl', parent, id, sizer, pos, property_window, show=show) self.style = style self.access_functions['style'] = (self.get_style, self.set_style) # style property self.style_pos = (wx.LC_LIST, wx.LC_REPORT, wx.LC_ICON, wx.LC_VIRTUAL, wx.LC_SMALL_ICON, wx.LC_ALIGN_TOP, wx.LC_ALIGN_LEFT, wx.LC_AUTOARRANGE, wx.LC_EDIT_LABELS, wx.LC_NO_HEADER, wx.LC_SINGLE_SEL, wx.LC_SORT_ASCENDING, wx.LC_SORT_DESCENDING, wx.LC_HRULES, wx.LC_VRULES, wx.SIMPLE_BORDER, wx.DOUBLE_BORDER, wx.SUNKEN_BORDER, wx.RAISED_BORDER, wx.STATIC_BORDER, wx.NO_BORDER, wx.WANTS_CHARS, wx.NO_FULL_REPAINT_ON_RESIZE, wx.FULL_REPAINT_ON_RESIZE) style_labels = ('#section#' + _('Style'), 'wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_VIRTUAL', 'wxLC_SMALL_ICON', 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER', 'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING', 'wxLC_HRULES', 'wxLC_VRULES', 'wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER', 'wxWANTS_CHARS', 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE') self.style_tooltips = (_("Multicolumn list view, with optional small icons. Columns are computed automatically, i.e. you don't set columns as in wxLC_REPORT. In other words, the list wraps, unlike a wxListBox."), _("Single or multicolumn report view, with optional header."), _("Large icon view, with optional labels."), _("The application provides items text on demand. May only be used with wxLC_REPORT."), _("Small icon view, with optional labels."), _("Icons align to the top. Win32 default, Win32 only."), _("Icons align to the left."), _("Icons arrange themselves. Win32 only."), _("Labels are editable: the application will be notified when editing starts."), _("No header in report mode."), _("Single selection (default is multiple)."), _("Sort in ascending order (must still supply a comparison callback in SortItems."), _("Sort in descending order (must still supply a comparison callback in SortItems."), _("Draws light horizontal rules between rows in report mode."), _("Draws light vertical rules between columns in report mode"), _("Displays a thin border around the window. wxBORDER is the old name for this style."), _("Displays a double border. Windows and Mac only."), _("Displays a sunken border."), _("Displays a raised border."), _("Displays a border suitable for a static control. Windows only."), _("Displays no border, overriding the default border style for the window."), _("Use this to indicate that the window wants to get all char/key events for all keys - even for keys like TAB or ENTER which are usually used for dialog navigation and which wouldn't be generated without this style. If you need to use this style in order to get the arrows or etc., but would still like to have normal keyboard navigation take place, you should create and send a wxNavigationKeyEvent in response to the key events for Tab and Shift-Tab."), _("On Windows, this style used to disable repainting the window completely when its size is changed. Since this behaviour is now the default, the style is now obsolete and no longer has an effect."), _("Use this style to force a complete redraw of the window whenever it is resized instead of redrawing just the part of the window affected by resizing. Note that this was the behaviour by default before 2.5.1 release and that if you experience redraw problems with code which previously used to work you may want to try this. Currently this style applies on GTK+ 2 and Windows only, and full repainting is always done on other platforms.")) self.properties['style'] = CheckListProperty( self, 'style', None, style_labels, tooltips=self.style_tooltips) def create_widget(self): self.widget = wx.ListCtrl(self.parent.widget, self.id, style=wx.LC_REPORT|wx.SUNKEN_BORDER) # add a couple of columns just for a better appearence (for now) self.widget.InsertColumn(0, _('List Control:')) self.widget.InsertColumn(1, self.name) wx.EVT_LIST_COL_CLICK(self.widget, self.widget.GetId(), self.on_set_focus) def finish_widget_creation(self): ManagedBase.finish_widget_creation(self, sel_marker_parent=self.widget) def set_name(self, name): ManagedBase.set_name(self, name) if self.widget: col = self.widget.GetColumn(1) col.SetText(self.name) self.widget.SetColumn(1, col) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) prop = self.properties prop['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) w, h = panel.GetClientSize() self.notebook.AddPage(panel, 'Widget') self.property_window.Layout() import math panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] # end of class EditListCtrl def builder(parent, sizer, pos, number=[1]): """\ factory function for EditListCtrl objects. """ name = 'list_ctrl_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'list_ctrl_%d' % number[0] list_ctrl = EditListCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(list_ctrl) list_ctrl.node = node list_ctrl.set_option(1) list_ctrl.set_flag("wxEXPAND") list_ctrl.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) sizer.set_item(list_ctrl.pos, 1, wx.EXPAND) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory function to build EditListCtrl objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") list_ctrl = EditListCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel, style=0) sizer.set_item(list_ctrl.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(list_ctrl) list_ctrl.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return list_ctrl def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditListCtrl'] = builder common.widgets_from_xml['EditListCtrl'] = xml_builder return common.make_object_button('EditListCtrl', 'icons/list_ctrl.xpm') wxglade-0.6.8.orig/widgets/list_ctrl/lisp_codegen.py0000644000175000017500000000247512150154266023001 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxListCtrl objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:59:48 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not(style and style != 'wxLC_ICON'): # default style style = '0' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxListCtrl_Create %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, style)) props_buf = codegen.generate_common_properties(obj) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditListCtrl'] = 'wxListCtrl' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxListCtrl', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/list_ctrl/codegen.py0000644000175000017500000000463612072605532021753 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxListCtrl objects # $Id: codegen.py,v 1.8 2007/03/27 07:01:57 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style and style != 'wxLC_ICON': # default style style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s%s)\n' % (obj.name, klass, parent, id, style)) props_buf = pygen.generate_common_properties(obj) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ generates C++ code for wxListCtrl objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get('style') if style and style != 'wxLC_ICON': extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s%s);\n' % (obj.name, obj.klass, parent, id, extra)] props_buf = cppgen.generate_common_properties(obj) return init, ids, props_buf, [] def get_events(self, obj): cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxListEvent') # end of class CppCodeGenerator def initialize(): common.class_names['EditListCtrl'] = 'wxListCtrl' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxListCtrl', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxListCtrl', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/list_ctrl/__init__.py0000644000175000017500000000065511621715605022105 0ustar georgeskgeorgesk# __init__.py: list ctrl widget module initialization # $Id: __init__.py,v 1.5 2007/03/27 07:01:57 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import list_ctrl return list_ctrl.initialize() wxglade-0.6.8.orig/widgets/radio_box/0000755000175000017500000000000012170277707017743 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/radio_box/perl_codegen.py0000644000175000017500000000362211646104105022732 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxRadioBox objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:41:59 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) label = plgen.quote_str(prop.get('label', '')) choices = prop.get('choices', []) major_dim = prop.get('dimension', '0') if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) choices = ', '.join([plgen.quote_str(c) for c in choices]) init.append('$self->{%s} = %s->new(%s, %s, %s, wxDefaultPosition, \ wxDefaultSize, [%s], %s, %s);\n' % (obj.name, klass, parent, id, label, choices, major_dim, style)) props_buf = plgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('$self->{%s}->SetSelection(%s);\n' % (obj.name, selection)) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditRadioBox'] = 'wxRadioBox' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxRadioBox', PerlCodeGenerator()) plgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/radio_box/lisp_codegen.py0000644000175000017500000000357412150154266022751 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxRadioBox objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 07:00:20 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) label = codegen.quote_str(prop.get('label', '')) choices = prop.get('choices', []) major_dim = prop.get('dimension', '0') if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) length = len(choices) choices = ' '.join([codegen.quote_str(c) for c in choices]) init.append('(setf (slot-%s obj) (wxRadioBox_Create %s %s %s -1 -1 -1 -1 %s (vector %s) %s %s))\n' % (obj.name, parent, id, label, length, choices, major_dim, style)) props_buf = codegen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('(wxRadioBox_SetSelection (slot-%s obj) %s)\n' % (obj.name, selection)) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditRadioBox'] = 'wxRadioBox' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxRadioBox', LispCodeGenerator()) codegen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/radio_box/codegen.py0000644000175000017500000001021111621715605021706 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxRadioBox objects # $Id: codegen.py,v 1.13 2007/03/27 07:01:55 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) label = pygen.quote_str(prop.get('label', '')) choices = prop.get('choices', []) major_dim = prop.get('dimension', '0') if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) choices = ', '.join([pygen.quote_str(c) for c in choices]) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, %s, choices=[%s], ' 'majorDimension=%s%s)\n' % (obj.name, klass, parent, id, label, choices, major_dim, style)) props_buf = pygen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('self.%s.SetSelection(%s)\n' % (obj.name, selection)) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class RadioBoxXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'choices': xrc_write_choices_property(self, outfile, tabs) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class RadioBoxXrcObject return RadioBoxXrcObject(obj) class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxRadioBox objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] choices = prop.get('choices', []) major_dim = prop.get('dimension', '0') if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' number = len(choices) ch_arr = '{\n %s\n };\n' % \ ',\n '.join([cppgen.quote_str(c) for c in choices]) label = cppgen.quote_str(prop.get('label', '')) style = prop.get("style", "0") init = [] init.append('const wxString %s_choices[] = %s' % (obj.name, ch_arr)) init.append('%s = new %s(%s, %s, %s, wxDefaultPosition, ' 'wxDefaultSize, %s, %s_choices, %s, %s);\n' % \ (obj.name, obj.klass, parent, id, label, number, obj.name, major_dim, style)) props_buf = cppgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('%s->SetSelection(%s);\n' % (obj.name, selection)) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditRadioBox'] = 'wxRadioBox' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxRadioBox', PythonCodeGenerator()) pygen.add_property_handler('choices', ChoicesCodeHandler) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxRadioBox', xrc_code_generator) xrcgen.add_property_handler('choices', ChoicesCodeHandler) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxRadioBox', CppCodeGenerator()) cppgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/radio_box/radio_box.py0000644000175000017500000002631211621715605022261 0ustar georgeskgeorgesk# radio_box.py: wxRadioBox objects # $Id: radio_box.py,v 1.18 2007/03/28 12:40:12 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * from misc import wxGladeRadioButton from ChoicesProperty import * class EditRadioBox(ManagedBase): events = ['EVT_RADIOBOX'] def __init__(self, name, parent, id, label, choices, major_dim, style, sizer, pos, property_window, show=True): """\ Class to handle wxRadioBox objects """ ManagedBase.__init__(self, name, 'wxRadioBox', parent, id, sizer, pos, property_window, show=show) self.static_box = None self.selection = 0 self.choices = choices self.buttons = None self.major_dim = major_dim if not style: self.style = wx.RA_SPECIFY_ROWS else: self.style = style self.label = label # properties self.access_functions['label'] = (self.get_label, self.set_label) self.access_functions['choices'] = (self.get_choices, self.set_choices) self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['dimension'] = (self.get_major_dimension, self.set_major_dimension) self.access_functions['selection'] = (self.get_selection, self.set_selection) self.properties['label'] = TextProperty(self, 'label', None, label=_("label")) self.properties['selection'] = SpinProperty(self, 'selection', None, r=(0, len(choices)-1), label=_("selection")) self.properties['choices'] = ChoicesProperty(self, 'choices', None, [('Label', GridProperty.STRING)], len(choices), label=_("choices")) self.style_pos = [wx.RA_SPECIFY_ROWS, wx.RA_SPECIFY_COLS] self.properties['style'] = RadioProperty(self, 'style', None, ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS'], label=_("style")) self.properties['dimension'] = SpinProperty(self, 'dimension', None, label=_("dimension")) def create_widget(self): self.widget = wx.Panel(self.parent.widget, self.id) self.static_box = self.create_static_box() self.buttons = [ self.create_button(c) for c in self.choices ] if self.buttons: self.buttons[0].SetValue(True) self.widget.GetBestSize = self.GetBestSize self.widget.SetForegroundColour = self.SetForegroundColour self.widget.SetBackgroundColour = self.SetBackgroundColour self.widget.SetFont = self.SetFont self.set_selection(self.selection) self.do_layout() def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['label'].display(panel) self.properties['style'].display(panel) self.properties['dimension'].display(panel) self.properties['selection'].display(panel) self.properties['choices'].display(panel) self.properties['style'].set_value(self.get_style()) szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.ALL|wx.EXPAND, 3) szr.Add(self.properties['dimension'].panel, 0, wx.EXPAND) szr.Add(self.properties['selection'].panel, 0, wx.EXPAND) szr.Add(self.properties['choices'].panel, 1, wx.ALL|wx.EXPAND, 3) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') self.properties['choices'].set_col_sizes([-1]) def create_button(self, label): r = wxGladeRadioButton(self.widget, -1, label) wx.EVT_LEFT_DOWN(r, self.on_set_focus) wx.EVT_RIGHT_DOWN(r, self.popup_menu) return r def create_static_box(self): sb = wx.StaticBox(self.widget, -1, self.label) wx.EVT_LEFT_DOWN(sb, self.on_set_focus) wx.EVT_RIGHT_DOWN(sb, self.popup_menu) return sb def do_layout(self): """\ Lays out the radio buttons according to the values of self.style and self.major_dim """ if not self.widget: return buttons_layout = self.buttons if self.major_dim: if self.style & wx.RA_SPECIFY_COLS: cols = self.major_dim; rows = 0 else: cols = 0; rows = self.major_dim sizer = wx.GridSizer(rows, cols) if wx.Platform == '__WXGTK__': # we need to reorder self.buttons 'cos wxRadioBox lays out its # elements by colums, while wxGridSizer by rows import math if not rows: step = int(math.ceil(1.0*len(self.buttons)/cols)) else: step = rows start = 0 tmp = [ [] for i in range(step) ] for i in range(len(self.buttons)): tmp[i%step].append(self.buttons[i]) buttons_layout = [] for t in tmp: buttons_layout.extend(t) else: sizer = wx.BoxSizer(wx.VERTICAL) for button in buttons_layout: w, h = button.GetBestSize() sizer.Add(button, 0, wx.EXPAND) sizer.SetItemMinSize(button, w, h) self.widget.SetAutoLayout(True) sb_sizer = wx.StaticBoxSizer(self.static_box, wx.VERTICAL) self.widget.SetSizer(sb_sizer) sb_sizer.Add(sizer, 1, wx.EXPAND) sb_sizer.SetMinSize(sizer.GetMinSize()) sb_sizer.Fit(self.widget) sp = self.sizer_properties self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def get_label(self): return self.label def set_label(self, value): value = misc.wxstr(value) if not misc.streq(value, self.label): self.label = value if self.static_box: self.static_box.SetLabel(value) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def get_style(self): if self.style == wx.RA_SPECIFY_ROWS: return 0 else: return 1 def set_style(self, value): if value == 0 or value == 'wxRA_SPECIFY_ROWS': self.style = wx.RA_SPECIFY_ROWS else: self.style = wx.RA_SPECIFY_COLS self.set_choices(self.get_choices()) #self.do_layout() def get_major_dimension(self): return self.major_dim def set_major_dimension(self, value): self.major_dim = int(value) self.set_choices(self.get_choices()) #self.do_layout() def get_choices(self): return zip(self.choices) def set_choices(self, values): self.choices = [ misc.wxstr(v[0]) for v in values ] self.properties['selection'].set_range(0, len(self.choices)-1) if not self.widget: return ## delta = len(values) - len(self.buttons) ## if delta > 0: ## self.buttons.extend([ self.create_button("") ## for i in range(delta) ]) ## elif delta < 0: ## to_remove = self.buttons[delta:] ## self.buttons = self.buttons[:delta] ## for b in to_remove: b.Hide(); b.Destroy() for b in self.buttons: b.Hide() b.Destroy() self.static_box = self.create_static_box() self.buttons = [ self.create_button("") for i in range(len(values)) ] for i in range(len(values)): self.buttons[i].SetLabel(values[i][0]) self.do_layout() def get_selection(self): return self.selection def set_selection(self, index): self.selection = int(index) if self.widget: for b in self.buttons: b.SetValue(False) try: self.buttons[self.selection].SetValue(True) except IndexError: pass def get_property_handler(self, prop_name): if prop_name == 'choices': return ChoicesHandler(self) return ManagedBase.get_property_handler(self, prop_name) def GetBestSize(self): w, h = self.widget.GetSizer().GetMinSize() w2, h2 = self.static_box.GetBestSize() return max(w, w2), h def SetBackgroundColour(self, colour): wx.Panel.SetBackgroundColour(self.widget, colour) self.static_box.SetBackgroundColour(colour) for b in self.buttons: b.SetBackgroundColour(colour) self.widget.Refresh() def SetForegroundColour(self, colour): wx.Panel.SetForegroundColour(self.widget, colour) self.static_box.SetForegroundColour(colour) for b in self.buttons: b.SetForegroundColour(colour) self.widget.Refresh() def SetFont(self, font): wx.Panel.SetFont(self.widget, font) self.static_box.SetFont(font) for b in self.buttons: b.SetFont(font) self.widget.Refresh() # end of class EditRadioBox def builder(parent, sizer, pos, number=[1]): """\ factory function for EditRadioBox objects. """ label = 'radio_box_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'radio_box_%d' % number[0] radio_box = EditRadioBox(label, parent, wx.NewId(), label, [misc._encode('choice 1')], 0, 0, sizer, pos, common.property_panel) #sizer.set_item(pos, 0, 0, size=radio_box.GetSize()) node = Tree.Node(radio_box) radio_box.node = node radio_box.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditRadioBox objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") radio_box = EditRadioBox(label, parent, wx.NewId(), '', [], 0, 0, sizer, pos, common.property_panel) sizer.set_item(radio_box.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) ## size=radio_box.GetBestSize()) node = Tree.Node(radio_box) radio_box.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return radio_box def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditRadioBox'] = builder common.widgets_from_xml['EditRadioBox'] = xml_builder return common.make_object_button('EditRadioBox', 'icons/radio_box.xpm') wxglade-0.6.8.orig/widgets/radio_box/__init__.py0000644000175000017500000000065511621715605022054 0ustar georgeskgeorgesk# __init__.py: radio box widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:55 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import radio_box return radio_box.initialize() wxglade-0.6.8.orig/widgets/text_ctrl/0000755000175000017500000000000012170277707020005 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/text_ctrl/perl_codegen.py0000644000175000017500000000263411646104546023007 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxTextCtrl objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:48:47 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) value = plgen.quote_str(prop.get('value', '')) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, value, style)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditTextCtrl'] = 'wxTextCtrl' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxTextCtrl', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/text_ctrl/lisp_codegen.py0000644000175000017500000000253012150154266023002 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxTextCtrl objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:42:16 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) value = codegen.quote_str(prop.get('value', '')) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxTextCtrl_Create %s %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, value, style)) props_buf = codegen.generate_common_properties(obj) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditTextCtrl'] = 'wxTextCtrl' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxTextCtrl', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/text_ctrl/codegen.py0000644000175000017500000000441612072605532021760 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxTextCtrl objects # $Id: codegen.py,v 1.13 2007/03/27 07:01:51 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) value = pygen.quote_str(prop.get('value', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, %s%s)\n' % (obj.name, klass, parent, id, value, style)) props_buf = pygen.generate_common_properties(obj) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, obj): """\ generates C++ code for wxTextCtrl objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] value = cppgen.quote_str(prop.get('value', '')) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get('style') if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s, %s%s);\n' % (obj.name, obj.klass, parent, id, value, extra)] props_buf = cppgen.generate_common_properties(obj) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditTextCtrl'] = 'wxTextCtrl' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxTextCtrl', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxTextCtrl', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/text_ctrl/text_ctrl.py0000644000175000017500000001431611755504662022375 0ustar georgeskgeorgesk# text_ctrl.py: wxTextCtrl objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx from edit_windows import ManagedBase from tree import Tree import common, misc from widget_properties import * class EditTextCtrl(ManagedBase): """\ Class to handle wxTextCtrl objects """ events = [ 'EVT_TEXT', 'EVT_TEXT_ENTER', 'EVT_TEXT_URL', 'EVT_TEXT_MAXLEN', ] def __init__(self, name, parent, id, sizer, pos, property_window, show=True): import config ManagedBase.__init__(self, name, 'wxTextCtrl', parent, id, sizer, pos, property_window, show=show) self.value = "" self.style = 0 self.access_functions['value'] = (self.get_value, self.set_value) self.access_functions['style'] = (self.get_style, self.set_style) prop = self.properties # value property prop['value'] = TextProperty(self, 'value', None, multiline=True, label=_("value")) # style property self.style_pos = (wx.TE_PROCESS_ENTER, wx.TE_PROCESS_TAB, wx.TE_MULTILINE,wx.TE_PASSWORD, wx.TE_READONLY, wx.HSCROLL, wx.TE_RICH, wx.TE_RICH2, wx.TE_AUTO_URL, wx.TE_NOHIDESEL, wx.TE_CENTRE, wx.TE_RIGHT, wx.TE_LINEWRAP, wx.TE_WORDWRAP, wx.NO_BORDER) style_labels = ('#section#' + _('Style'), 'wxTE_PROCESS_ENTER', 'wxTE_PROCESS_TAB', 'wxTE_MULTILINE', 'wxTE_PASSWORD', 'wxTE_READONLY', 'wxHSCROLL', 'wxTE_RICH', 'wxTE_RICH2', 'wxTE_AUTO_URL', 'wxTE_NOHIDESEL', 'wxTE_CENTRE', 'wxTE_RIGHT', 'wxTE_LINEWRAP', 'wxTE_WORDWRAP', 'wxNO_BORDER') prop['style'] = CheckListProperty(self, 'style', None, style_labels) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): value = self.value if self.style & wx.TE_MULTILINE: value = value.replace('\\n', '\n') self.widget = wx.TextCtrl(self.parent.widget, self.id, value=value, style=self.style & wx.TE_MULTILINE) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) prop = self.properties prop['value'].display(panel) prop['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop['value'].panel, 0, wx.EXPAND) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, _('Widget')) import math panel.SetScrollbars( 1, 5, 1, int(math.ceil(panel.GetClientSize()[1]/5.0))) def get_value(self): return self.value def set_value(self, value): value = misc.wxstr(value) if not misc.streq(value, self.value): self.value = value if self.style & wx.TE_MULTILINE: value = value.replace('\\n', '\n') if self.widget: self.widget.SetValue(value) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): old = self.style & wx.TE_MULTILINE value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: new = self.style & wx.TE_MULTILINE if old != new: focused = misc.focused_widget is self self.sel_marker.Destroy() w = self.widget self.create_widget() if not self.properties['size'].is_active(): self.widget.SetSize(self.widget.GetBestSize()) self.finish_widget_creation() self.sizer.layout() if focused: misc.focused_widget = self self.sel_marker.Show(True) # end of class EditTextCtrl def builder(parent, sizer, pos, number=[1]): """\ factory function for EditTextCtrl objects. """ name = 'text_ctrl_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'text_ctrl_%d' % number[0] text = EditTextCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(text) text.node = node text.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory function to build EditTextCtrl objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") text = EditTextCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel) sizer.set_item(text.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(text) text.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return text def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditTextCtrl'] = builder common.widgets_from_xml['EditTextCtrl'] = xml_builder return common.make_object_button('EditTextCtrl', 'icons/text_ctrl.xpm') wxglade-0.6.8.orig/widgets/text_ctrl/__init__.py0000644000175000017500000000065511621715605022116 0ustar georgeskgeorgesk# __init__.py: text ctrl widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:52 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import text_ctrl return text_ctrl.initialize() wxglade-0.6.8.orig/widgets/toolbar/0000755000175000017500000000000012170277707017437 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/toolbar/perl_codegen.py0000644000175000017500000001135111646104613022430 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxMenuBar objects # $Id: perl_codegen.py,v 1.11 2005/08/15 08:03:02 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from tool import * # yay from codegen import ToolsHandler class PerlCodeGenerator: def get_properties_code(self, obj): prop = obj.properties plgen = common.code_writers['perl'] out = [] append = out.append if obj.is_toplevel: obj_name = '$self' else: obj_name = '$self->{%s}' % obj.name bitmapsize = prop.get('bitmapsize') if bitmapsize: try: w, h = [int(i) for i in bitmapsize.split(',')] append('%s->SetToolBitmapSize(wxSIZE(%s, %s));\n' % \ (obj_name, w, h)) except: pass margins = prop.get('margins') if margins: try: w, h = [int(i) for i in margins.split(',')] append('%s->SetMargins(%s, %s);\n' % (obj_name, w, h)) except: pass packing = prop.get('packing') if packing: append('%s->SetToolPacking(%s);\n' % (obj_name, packing)) separation = prop.get('separation') if separation: append('%s->SetToolSeparation(%s);\n' % (obj_name, separation)) append('%s->Realize();\n' % obj_name) return out def get_init_code(self, obj): prop = obj.properties plgen = common.code_writers['perl'] out = [] append = out.append tools = obj.properties['toolbar'] ids = [] if obj.is_toplevel: obj_name = '$self' else: obj_name = '$self->{%s}' % obj.name def _get_bitmap(bitmap): if not bitmap: return 'wxNullBitmap' elif bitmap.startswith('var:'): # this is a variable holding bitmap path var = bitmap[4:].strip() if var[0] != "$": var = "$" + var return 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY)' % var elif bitmap.startswith('code:'): return '(%s)' % bitmap[5:].strip() else: return 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY)' % \ plgen.quote_path(bitmap) for tool in tools: if tool.id == '---': # item is a separator append('%s->AddSeparator();\n' % obj_name) else: name, val = plgen.generate_code_id(None, tool.id) if not name and (not val or val == '-1'): id = 'Wx::NewId()' else: if name: ids.append(name) id = val kinds = ['wxITEM_NORMAL', 'wxITEM_CHECK', 'wxITEM_RADIO'] try: kind = kinds[int(tool.type)] except (IndexError, ValueError): kind = 'wxITEM_NORMAL' bmp1 = _get_bitmap(tool.bitmap1) bmp2 = _get_bitmap(tool.bitmap2) # append('%s->AddLabelTool(%s, %s, %s, %s, %s, %s, %s);\n' % append('%s->AddTool(%s, %s, %s, %s, %s, %s, %s);\n' % (obj_name, id, plgen.quote_str(tool.label), bmp1, bmp2, kind, plgen.quote_str(tool.short_help), plgen.quote_str(tool.long_help))) return ids + out def get_code(self, obj): """\ function that generates Perl code for the menubar of a wxFrame. """ plgen = common.code_writers['perl'] style = obj.properties.get('style') if style: style = 'wxTB_HORIZONTAL|' + style else: style = '' klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init = [ '\n# Tool Bar\n', '$self->{%s} = %s->new($self, -1, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (obj.name, klass, style), '$self->SetToolBar($self->{%s});\n' % obj.name ] init.extend(self.get_init_code(obj)) init.append('# Tool Bar end\n') return init, self.get_properties_code(obj), [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditToolBar'] = 'wxToolBar' common.toplevels['EditToolBar'] = 1 plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxToolBar', PerlCodeGenerator()) plgen.add_property_handler('tools', ToolsHandler) wxglade-0.6.8.orig/widgets/toolbar/lisp_codegen.py0000644000175000017500000001143112150154266022434 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxMenuBar objects # $Id: lisp_codegen.py,v 1.2 2005/09/25 08:23:40 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from tool import * # yay from codegen import ToolsHandler class LispCodeGenerator: def get_properties_code(self, obj): prop = obj.properties codegen = common.code_writers['lisp'] out = [] append = out.append obj_name = '(slot-%s obj)' % obj.name bitmapsize = prop.get('bitmapsize') if bitmapsize: try: w, h = [int(i) for i in bitmapsize.split(',')] append('(wxToolBar_SetToolBitmapSize %s %s %s)\n' % \ (obj_name, w, h)) except: pass margins = prop.get('margins') if margins: try: w, h = [int(i) for i in margins.split(',')] append('(wxToolBar_SetMargins %s %s %s)\n' % (obj_name, w, h)) except: pass packing = prop.get('packing') if packing: append('(wxToolBar_SetToolPacking %s %s)\n' % (obj_name, packing)) separation = prop.get('separation') if separation: append('(wxToolBar_SetToolSeparation %s %s)\n' % (obj_name, separation)) append('(wxToolBar_Realize %s)\n' % obj_name) return out def get_init_code(self, obj): prop = obj.properties codegen = common.code_writers['lisp'] out = [] append = out.append tools = obj.properties['toolbar'] ids = [] obj_name = '(slot-%s obj)' % obj.name def _get_bitmap(bitmap): if not bitmap: return 'wxNullBitmap' elif bitmap.startswith('var:'): # this is a variable holding bitmap path var = bitmap[4:].strip() if var[0] != "$": var = "$" + var return '(wxBitmap:wxBitmap_CreateLoad %s wxBITMAP_TYPE_ANY)' % var elif bitmap.startswith('code:'): return '(%s)' % bitmap[5:].strip() else: return '(wxBitmap:wxBitmap_CreateLoad %s wxBITMAP_TYPE_ANY)' % \ codegen.quote_str(bitmap) for tool in tools: if tool.id == '---': # item is a separator append('(wxToolBar_AddSeparator %s)\n' % obj_name) else: name, val = codegen.generate_code_id(None, tool.id) if not name and (not val or val == '-1'): id = 'Wx::NewId()' else: if name: ids.append(name) id = val kinds = ['wxITEM_NORMAL', 'wxITEM_CHECK', 'wxITEM_RADIO'] try: kind = kinds[int(tool.type)] except (IndexError, ValueError): kind = 'wxITEM_NORMAL' bmp1 = _get_bitmap(tool.bitmap1) bmp2 = _get_bitmap(tool.bitmap2) # append('%s->AddLabelTool(%s, %s, %s, %s, %s, %s, %s);\n' % append('(wxToolBar_AddTool %s %s %s %s %s %s %s %s)\n' % (obj_name, id, codegen.quote_str(tool.label), bmp1, bmp2, kind, codegen.quote_str(tool.short_help), codegen.quote_str(tool.long_help))) return ids + out def get_code(self, obj): """\ function that generates Lisp code for the toolbar of a wxFrame. """ codegen = common.code_writers['lisp'] prop = obj.properties style = prop.get("style") if not style: style = 'wxTB_HORIZONTAL' else: style += "|wxTB_HORIZONTAL" style = codegen.cn_f(style) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' init = [ '\n\t;;; Tool Bar\n', '(setf (slot-%s obj) (wxToolBar_Create %s -1 -1 -1 -1 -1 %s))\n' % (obj.name, parent, style), '(wxFrame_SetToolBar (slot-top-window obj) (slot-%s obj))\n' % obj.name ] init.extend(self.get_init_code(obj)) init.append(';;; Tool Bar end\n') return init, self.get_properties_code(obj), [] # end of class LispCodeGenerator def initialize(): common.class_names['EditToolBar'] = 'wxToolBar' common.toplevels['EditToolBar'] = 1 codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxToolBar', LispCodeGenerator()) codegen.add_property_handler('tools', ToolsHandler) wxglade-0.6.8.orig/widgets/toolbar/tool.py0000644000175000017500000000320212072607746020764 0ustar georgeskgeorgesk# tool.py: Tool objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY from xml.sax.saxutils import escape from common import _encode_to_xml class Tool: def __init__(self, id='', label='', type=0, short_help='', long_help='', bitmap1='', bitmap2='', handler=''): self.id = id self.label = label self.type = type self.short_help = short_help self.long_help = long_help self.bitmap1 = bitmap1 self.bitmap2 = bitmap2 self.handler = handler def write(self, outfile, tabs): fwrite = outfile.write fwrite(" " * tabs + '\n') tab_s = " " * (tabs+1) fwrite(tab_s + '%s\n' % escape(_encode_to_xml(self.id))) fwrite(tab_s + '\n' % \ escape(_encode_to_xml(self.label))) fwrite(tab_s + '%s\n' % escape(str(self.type))) fwrite(tab_s + '%s\n' % \ escape(_encode_to_xml(self.short_help))) fwrite(tab_s + '%s\n' % \ escape(_encode_to_xml(self.long_help))) fwrite(tab_s + '%s\n' % \ escape(_encode_to_xml(self.bitmap1))) fwrite(tab_s + '%s\n' % \ escape(_encode_to_xml(self.bitmap2))) if self.handler: fwrite(tab_s + '%s\n' % \ escape(_encode_to_xml(self.handler.strip()))) fwrite(" " * tabs + '\n') # end of class Tool wxglade-0.6.8.orig/widgets/toolbar/codegen.py0000644000175000017500000003612312072607746021423 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxToolBar objects # $Id: codegen.py,v 1.23 2007/03/27 07:01:51 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common, os from tool import * class PythonCodeGenerator: def get_properties_code(self, obj): prop = obj.properties pygen = common.code_writers['python'] out = [] append = out.append if obj.is_toplevel: obj_name = 'self' else: obj_name = 'self.' + obj.name bitmapsize = prop.get('bitmapsize') if bitmapsize: try: w, h = [int(i) for i in bitmapsize.split(',')] append('%s.SetToolBitmapSize((%s, %s))\n' % (obj_name, w, h)) except: pass margins = prop.get('margins') if margins: try: w, h = [int(i) for i in margins.split(',')] append('%s.SetMargins((%s, %s))\n' % (obj_name, w, h)) except: pass packing = prop.get('packing') if packing: append('%s.SetToolPacking(%s)\n' % (obj_name, packing)) separation = prop.get('separation') if separation: append('%s.SetToolSeparation(%s)\n' % (obj_name, separation)) append('%s.Realize()\n' % obj_name) return out def get_init_code(self, obj): prop = obj.properties pygen = common.code_writers['python'] cn = pygen.cn out = [] append = out.append tools = obj.properties['toolbar'] ids = [] if obj.is_toplevel: obj_name = 'self' else: obj_name = 'self.' + obj.name def _get_bitmap(bitmap): bmp_preview_path = os.path.join(common.icons_path, "icon.xpm") if not bitmap: return cn('wxNullBitmap') elif bitmap.startswith('var:'): if obj.preview: return "%s('%s', %s)" % (cn('wxBitmap'), bmp_preview_path, cn('wxBITMAP_TYPE_XPM') ) else: return (cn('wxBitmap') + '(%s,' + cn('wxBITMAP_TYPE_ANY') + ')') % (bitmap[4:].strip()) elif bitmap.startswith('code:'): if obj.preview: return "%s('%s', %s)" % (cn('wxBitmap'), bmp_preview_path, cn('wxBITMAP_TYPE_XPM') ) else: return '(%s)' % bitmap[5:].strip() else: if obj.preview: import misc bitmap = misc.get_relative_path(bitmap, True) return cn('wxBitmap') + \ ('(%s, ' + cn('wxBITMAP_TYPE_ANY') + ')') % \ pygen.quote_str(bitmap, False, False) for tool in tools: if tool.id == '---': # item is a separator append('%s.AddSeparator()\n' % obj_name) else: name, val = pygen.generate_code_id(None, tool.id) if obj.preview or (not name and (not val or val == '-1')): id = cn('wxNewId()') else: if name: ids.append(name) id = val kinds = ['wxITEM_NORMAL', 'wxITEM_CHECK', 'wxITEM_RADIO'] try: kind = kinds[int(tool.type)] except (IndexError, ValueError): kind = 'wxITEM_NORMAL' bmp1 = _get_bitmap(tool.bitmap1) bmp2 = _get_bitmap(tool.bitmap2) append('%s.AddLabelTool(%s, %s, %s, %s, %s, %s, %s)\n' % (obj_name, id, pygen.quote_str(tool.label), bmp1, bmp2, cn(kind), pygen.quote_str(tool.short_help), pygen.quote_str(tool.long_help))) return ids + out def get_code(self, obj): """\ function that generates Python code for the menubar of a wxFrame. """ pygen = common.code_writers['python'] style = obj.properties.get('style') if style: style = ', style=' + pygen.cn_f('wxTB_HORIZONTAL|' + style) else: style = '' klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init = [ '\n', '# Tool Bar\n', 'self.%s = %s(self, -1%s)\n' % (obj.name, klass, style), 'self.SetToolBar(self.%s)\n' % obj.name ] init.extend(self.get_init_code(obj)) init.append('# Tool Bar end\n') return init, self.get_properties_code(obj), [] def get_events(self, obj): pygen = common.code_writers['python'] cn = pygen.cn out = [] def do_get(tool): ret = [] name, val = pygen.generate_code_id(None, tool.id) if not val: val = '-1' # but this is wrong anyway... if tool.handler: ret.append((val, 'EVT_TOOL', tool.handler)) return ret for tool in obj.properties['toolbar']: out.extend(do_get(tool)) return out # end of class PythonCodeGenerator class ToolsHandler: """Handler for tools of a toolbar""" item_attrs = ('label', 'id', 'short_help', 'type', 'long_help', 'bitmap1', 'bitmap2', 'handler') def __init__(self): self.tools = [] self.curr_tool = None self.attr_val = [] def start_elem(self, name, attrs): if name == 'tool': self.curr_tool = Tool() def end_elem(self, name, code_obj): if name == 'tools': code_obj.properties['toolbar'] = self.tools return True if name == 'tool' and self.curr_tool: self.tools.append(self.curr_tool) elif name in self.item_attrs: setattr(self.curr_tool, name, "".join(self.attr_val)) self.attr_val = [] def char_data(self, data): self.attr_val.append(data) # end of class ToolsHandler def xrc_code_generator(obj): """\ function that generates XRC code for a toolbar """ from xml.sax.saxutils import escape, quoteattr xrcgen = common.code_writers['XRC'] class ToolBarXrcObject(xrcgen.DefaultXrcObject): def append_item(self, item, outfile, tabs): write = outfile.write if item.id == '---': # item is a separator write(' '*tabs + '\n') else: if item.id: name = item.id.split('=', 1)[0] if name: write(' '*tabs + '\n' % quoteattr(name)) else: write(' '*tabs + '\n') else: write(' '*tabs + '\n') # why XRC seems to ignore label?? # this has been fixed on CVS, so add it (it shouldn't hurt...) if item.label: write(' '*(tabs+1) + '\n' % escape(item.label)) if item.short_help: write(' '*(tabs+1) + '%s\n' % \ escape(item.short_help)) if item.long_help: write(' '*(tabs+1) + '%s\n' % \ escape(item.long_help)) if item.bitmap1: write(' '*(tabs+1) + '%s\n' % \ escape(item.bitmap1)) if item.bitmap2: write(' '*(tabs+1) + '%s\n' % \ escape(item.bitmap2)) try: # again, it seems that XRC doesn't support "radio" tools if int(item.type) == 1: write(' '*(tabs+1) + '1\n') # the above has been fixed on CVS, so add a radio if # it's there elif int(item.type) == 2: write(' '*(tabs+1) + '1\n') except ValueError: pass write(' '*tabs + '\n') def write(self, outfile, tabs): tools = self.code_obj.properties['toolbar'] write = outfile.write write(' '*tabs + '\n' % \ quoteattr(self.name)) for prop_name in 'bitmapsize', 'margins': prop = self.code_obj.properties.get(prop_name) if prop: try: w, h = [int(i) for i in prop.split(',')] write(' ' * (tabs+1) + '<%s>%s, %s\n' \ % (prop_name, w, h, prop_name)) except: pass for prop_name in 'packing', 'separation': prop = self.code_obj.properties.get(prop_name) if prop: write(' ' * (tabs+1) + '<%s>%s\n' % \ (prop_name, escape(prop), prop_name)) style = self.code_obj.properties.get('style') if style: style = style.split('|') style.append('wxTB_HORIZONTAL') write(' '*(tabs+1) + '\n' % \ escape('|'.join(style))) for t in tools: self.append_item(t, outfile, tabs+1) write(' '*tabs + '\n') # end of class ToolBarXrcObject return ToolBarXrcObject(obj) class CppCodeGenerator: constructor = [('wxWindow*', 'parent'), ('int', 'id'), ('const wxPoint&', 'pos', 'wxDefaultPosition'), ('const wxSize&', 'size', 'wxDefaultSize'), ('long', 'style', 'wxTB_HORIZONTAL|wxTB_NOBORDER')] def get_code(self, obj): """\ generates C++ code for the toolbar of a wxFrame. """ cppgen = common.code_writers['C++'] style = obj.properties.get('style') if style: style = ', wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL|' + \ style else: style = '' init = [ '%s = new %s(this, -1%s);\n' % (obj.name, obj.klass, style), 'SetToolBar(%s);\n' % obj.name ] init.extend(self.get_properties_code(obj)) ids = self.get_ids_code(obj) return init, ids, [], [] def get_properties_code(self, obj): cppgen = common.code_writers['C++'] tools = obj.properties['toolbar'] out = [] append = out.append prop = obj.properties if obj.is_toplevel: obj_name = '' else: obj_name = obj.name + '->' bitmapsize = obj.properties.get('bitmapsize') if bitmapsize: try: w, h = [int(i) for i in bitmapsize.split(',')] append('%sSetToolBitmapSize(wxSize(%s, %s));\n' % \ (obj_name, w, h)) except: pass margins = obj.properties.get('margins') if margins: try: w, h = [int(i) for i in margins.split(',')] append('%sSetMargins(wxSize(%s, %s));\n' % \ (obj_name, w, h)) except: pass packing = prop.get('packing') if packing: append('%sSetToolPacking(%s);\n' % (obj_name, packing)) separation = prop.get('separation') if separation: append('%sSetToolSeparation(%s);\n' % (obj_name, separation)) def _get_bitmap(bitmap): if not bitmap: return 'wxNullBitmap' elif bitmap.startswith('var:'): return 'wxBitmap(%s, wxBITMAP_TYPE_ANY)' % bitmap[4:].strip() elif bitmap.startswith('code:'): return '(%s)' % bitmap[5:].strip() else: return 'wxBitmap(%s, wxBITMAP_TYPE_ANY)' % \ cppgen.quote_str(bitmap, False, False) for tool in tools: if tool.id == '---': # item is a separator append('%sAddSeparator();\n' % obj_name) else: name, val = cppgen.generate_code_id(None, tool.id) if not name and (not val or val == '-1'): id = 'wxNewId()' else: id = val kinds = ['wxITEM_NORMAL', 'wxITEM_CHECK', 'wxITEM_RADIO'] try: kind = kinds[int(tool.type)] except (IndexError, ValueError): kind = 'wxITEM_NORMAL' bmp1 = _get_bitmap(tool.bitmap1) bmp2 = _get_bitmap(tool.bitmap2) append('%sAddTool(%s, %s, %s, %s, %s, %s, %s);\n' % (obj_name, id, cppgen.quote_str(tool.label), bmp1, bmp2, kind, cppgen.quote_str(tool.short_help), cppgen.quote_str(tool.long_help))) append('%sRealize();\n' % obj_name) return out def get_ids_code(self, obj): cppgen = common.code_writers['C++'] ids = [] tools = obj.properties['toolbar'] for item in tools: if item.id == '---': # item is a separator pass # do nothing else: name, val = cppgen.generate_code_id(None, item.id) if name.find('=') != -1: ids.append(name) ## if item.id: ## tokens = item.id.split('=') ## if len(tokens) > 1: ## id = tokens[0] ## ids.append(' = '.join(tokens)) return ids def get_events(self, obj): cppgen = common.code_writers['C++'] out = [] def do_get(tool): ret = [] name, val = cppgen.generate_code_id(None, tool.id) if not val: val = '-1' # but this is wrong anyway... if tool.handler: ret.append((val, 'EVT_TOOL', tool.handler, 'wxCommandEvent')) return ret for tool in obj.properties['toolbar']: out.extend(do_get(tool)) return out # end of class CppCodeGenerator def initialize(): common.class_names['EditToolBar'] = 'wxToolBar' common.toplevels['EditToolBar'] = 1 pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxToolBar', PythonCodeGenerator()) pygen.add_property_handler('tools', ToolsHandler) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxToolBar', xrc_code_generator) xrcgen.add_property_handler('tools', ToolsHandler) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxToolBar', CppCodeGenerator()) cppgen.add_property_handler('tools', ToolsHandler) wxglade-0.6.8.orig/widgets/toolbar/toolbar.py0000644000175000017500000010675612072607746021473 0ustar georgeskgeorgesk# toolbar.py: wxToolBar objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx #from wxPython.lib.filebrowsebutton import FileBrowseButton from wx.lib.filebrowsebutton import FileBrowseButton import common import math import misc import os from tree import Tree from tool import * from widget_properties import * from edit_windows import EditBase, PreviewMixin class _MyBrowseButton(FileBrowseButton): def createBrowseButton( self): """Create the browse-button control""" ID = wx.NewId() button =wx.Button(self, ID, misc.wxstr(self.buttonText)) button.SetToolTipString(misc.wxstr(self.toolTip)) w = button.GetTextExtent(self.buttonText)[0] + 10 button.SetMinSize((w, -1)) wx.EVT_BUTTON(button, ID, self.OnBrowse) return button def OnBrowse (self, event=None): """ Going to browse for file... """ current = self.GetValue() directory = os.path.split(current) if os.path.isdir(current): directory = current current = '' elif directory and os.path.isdir(directory[0]): current = directory[1] directory = directory [0] else: directory = self.startDirectory value = misc.FileSelector(self.dialogTitle, directory, current, wildcard=self.fileMask, flags=self.fileMode) if value: self.SetValue(value) # end of class _MyBrowseButton class ToolsDialog(wx.Dialog): def __init__(self, parent, owner, items=None): wx.Dialog.__init__(self, parent, -1, _("Toolbar editor"), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) ADD_ID, REMOVE_ID, NAME_ID, LABEL_ID, ID_ID, CHECK_RADIO_ID, LIST_ID, \ ADD_SEP_ID, MOVE_UP_ID, MOVE_DOWN_ID, HELP_STR_ID, \ LONG_HELP_STR_ID, BITMAP1_ID, BITMAP2_ID \ = [wx.NewId() for i in range(14)] self._staticbox = wx.StaticBox(self, -1, _("Tool:")) self.owner = owner self.tool_items = wx.ListCtrl(self, LIST_ID, style=wx.LC_REPORT | \ wx.LC_SINGLE_SEL|wx.SUNKEN_BORDER, size=(300, -1)) self.selected_index = -1 # index of the selected element in the # wxListCtrl self.tool_items.InsertColumn(0, _("Label")) self.tool_items.InsertColumn(1, _("Id")) self.tool_items.InsertColumn(2, _("Normal Bitmap")) self.tool_items.InsertColumn(3, _("Second Bitmap")) self.tool_items.InsertColumn(4, _("Short Help")) self.tool_items.InsertColumn(5, _("Long Help")) self.tool_items.InsertColumn(6, _("Type")) # ALB 2004-12-05 self.tool_items.InsertColumn(7, _("Event Handler")) self.tool_items.SetColumnWidth(0, 100) self.tool_items.SetColumnWidth(2, 100) self.tool_items.SetColumnWidth(3, 150) self.tool_items.SetColumnWidth(4, 150) self.tool_items.SetColumnWidth(5, 100) self.tool_items.SetColumnWidth(6, 150) self.tool_items.SetColumnWidth(7, 150) # tool fields self.id = wx.TextCtrl(self, ID_ID) self.label = wx.TextCtrl(self, LABEL_ID) self.help_str = wx.TextCtrl(self, HELP_STR_ID) self.long_help_str = wx.TextCtrl(self, LONG_HELP_STR_ID) # ALB 2004-12-05 self.event_handler = wx.TextCtrl(self, -1) import re self.handler_re = re.compile(r'^\s*\w*\s*$') self.bitmap1 = _MyBrowseButton( self, BITMAP1_ID, labelText=_('Normal Bitmap'), buttonText='...', changeCallback=self.update_tool) self.bitmap2 = _MyBrowseButton( self, BITMAP2_ID, labelText=_('Second Bitmap'), buttonText='...', changeCallback=self.update_tool) self.check_radio = wx.RadioBox( self, CHECK_RADIO_ID, _("Type"), choices=['Normal', 'Checkable', 'Radio'], majorDimension=3) self.add = wx.Button(self, ADD_ID, _("Add")) self.remove = wx.Button(self, REMOVE_ID, _("Remove")) self.add_sep = wx.Button(self, ADD_SEP_ID, _("Add separator")) # tools navigation self.move_up = wx.Button(self, MOVE_UP_ID, _("Up")) self.move_down = wx.Button(self, MOVE_DOWN_ID, _("Down")) self.ok = wx.Button(self, wx.ID_OK, _("OK")) self.apply = wx.Button(self, wx.ID_APPLY, _("Apply")) self.cancel = wx.Button(self, wx.ID_CANCEL, _("Cancel")) self.do_layout() # event handlers wx.EVT_BUTTON(self, ADD_ID, self.add_tool) wx.EVT_BUTTON(self, REMOVE_ID, self.remove_tool) wx.EVT_BUTTON(self, ADD_SEP_ID, self.add_separator) wx.EVT_BUTTON(self, MOVE_UP_ID, self.move_item_up) wx.EVT_BUTTON(self, MOVE_DOWN_ID, self.move_item_down) wx.EVT_BUTTON(self, wx.ID_APPLY, self.on_apply) wx.EVT_KILL_FOCUS(self.label, self.update_tool) wx.EVT_KILL_FOCUS(self.id, self.update_tool) wx.EVT_KILL_FOCUS(self.help_str, self.update_tool) wx.EVT_KILL_FOCUS(self.long_help_str, self.update_tool) wx.EVT_KILL_FOCUS(self.event_handler, self.update_tool) wx.EVT_RADIOBOX(self, CHECK_RADIO_ID, self.update_tool) wx.EVT_LIST_ITEM_SELECTED(self, LIST_ID, self.show_tool) if items: self.add_tools(items) def do_layout(self): self.label.Enable(False) self.id.Enable(False) self.help_str.Enable(False) self.long_help_str.Enable(False) self.event_handler.Enable(False) self.bitmap1.Enable(False) self.bitmap2.Enable(False) self.check_radio.Enable(False) sizer = wx.BoxSizer(wx.VERTICAL) sizer2 = wx.StaticBoxSizer(self._staticbox, wx.VERTICAL) self.label.SetSize((150, -1)) self.id.SetSize((150, -1)) self.help_str.SetSize((150, -1)) self.long_help_str.SetSize((150, -1)) self.event_handler.SetSize((150, -1)) szr = wx.FlexGridSizer(0, 2) flag = wx.FIXED_MINSIZE label_flag = wx.ALIGN_CENTER_VERTICAL szr.Add(wx.StaticText(self, -1, _("Id ")), flag=label_flag) szr.Add(self.id, flag=flag) szr.Add(wx.StaticText(self, -1, _("Label ")), flag=label_flag) szr.Add(self.label, flag=flag) szr.Add(wx.StaticText(self, -1, _("Short Help ")), flag=label_flag) szr.Add(self.help_str, flag=flag) szr.Add(wx.StaticText(self, -1, _("Long Help ")), flag=label_flag) szr.Add(self.long_help_str, flag=flag) szr.Add(wx.StaticText(self, -1, _("Event Handler ")), flag=label_flag) szr.Add(self.event_handler, flag=flag) sizer2.Add(szr, 1, wx.ALL|wx.EXPAND, 5) label_w = self.bitmap1.browseButton.GetTextExtent('...')[0] sizer2.Add(self.bitmap1, 0, wx.EXPAND) sizer2.Add(self.bitmap2, 0, wx.EXPAND) sizer2.Add(self.check_radio, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM, 4) szr = wx.GridSizer(0, 2, 3, 3) szr.Add(self.add, 0, wx.EXPAND); szr.Add(self.remove, 0, wx.EXPAND) sizer2.Add(szr, 0, wx.EXPAND) sizer2.Add(self.add_sep, 0, wx.TOP|wx.EXPAND, 3) sizer3 = wx.BoxSizer(wx.VERTICAL) sizer3.Add(self.tool_items, 1, wx.ALL|wx.EXPAND, 5) sizer4 = wx.BoxSizer(wx.HORIZONTAL) sizer4.Add(self.move_up, 0, wx.LEFT|wx.RIGHT, 3) sizer4.Add(self.move_down, 0, wx.LEFT|wx.RIGHT, 5) sizer3.Add(sizer4, 0, wx.ALIGN_CENTER|wx.ALL, 5) szr = wx.BoxSizer(wx.HORIZONTAL) szr.Add(sizer3, 1, wx.ALL|wx.EXPAND, 5) szr.Add(sizer2, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5) sizer.Add(szr, 1, wx.EXPAND) sizer2 = wx.BoxSizer(wx.HORIZONTAL) sizer2.Add(self.ok, 0, wx.ALL, 5) sizer2.Add(self.apply, 0, wx.ALL, 5) sizer2.Add(self.cancel, 0, wx.ALL, 5) sizer.Add(sizer2, 0, wx.ALL|wx.ALIGN_CENTER, 3) self.SetAutoLayout(1) self.SetSizer(sizer) sizer.Fit(self) #self.SetSize((-1, 350)) self.CenterOnScreen() def add_tool(self, event): """\ Event handler called when the Add button is clicked """ index = self.selected_index = self.selected_index+1 if not self.tool_items.GetItemCount(): for s in (self.label, self.id, self.help_str, self.long_help_str, self.bitmap1, self.bitmap2, self.check_radio, self.event_handler): s.Enable(True) if index < 0: index = self.tool_items.GetItemCount() name, label, id, check_radio = "", "item", "", "0" bitmap1, bitmap2, help_str, long_help_str = [""] * 4 self.tool_items.InsertStringItem(index, label) self.tool_items.SetStringItem(index, 1, id) self.tool_items.SetStringItem(index, 2, bitmap1) self.tool_items.SetStringItem(index, 3, bitmap2) self.tool_items.SetStringItem(index, 4, help_str) self.tool_items.SetStringItem(index, 5, long_help_str) self.tool_items.SetStringItem(index, 6, check_radio) self.tool_items.SetItemState(index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) self.label.SetValue(label) self.id.SetValue(id) self.check_radio.SetSelection(int(check_radio)) self.bitmap1.SetValue(bitmap1, False) self.bitmap2.SetValue(bitmap2, False) self.help_str.SetValue(help_str) self.long_help_str.SetValue(long_help_str) self.event_handler.SetValue("") def add_separator(self, event): """\ Event handler called when the Add Separator button is clicked """ index = self.selected_index+1 if not self.tool_items.GetItemCount(): for s in (self.label, self.id, self.help_str, self.long_help_str, self.bitmap1, self.bitmap2, self.check_radio, self.event_handler): s.Enable(True) if index < 0: index = self.tool_items.GetItemCount() self.tool_items.InsertStringItem(index, '---')#label) for i in range(1, 5): self.tool_items.SetStringItem(index, i, '---') self.tool_items.SetItemState(index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) def show_tool(self, event): """\ Event handler called when a tool in the list is selected """ self.selected_index = index = event.GetIndex() get_item = self.tool_items.GetItem if not self.tool_items.GetItem(index, 2).m_text == '---': # skip if the selected item is a separator for (s, i) in ((self.label, 0), (self.id, 1), (self.help_str, 4), (self.long_help_str, 5), (self.event_handler, 7)): s.SetValue(get_item(index, i).m_text) self.bitmap1.SetValue(get_item(index, 2).m_text, False) self.bitmap2.SetValue(get_item(index, 3).m_text, False) try: self.check_radio.SetSelection( int(self.tool_items.GetItem(index, 6).m_text)) except: self.check_radio.SetSelection(0) event.Skip() def update_tool(self, event): """\ Event handler called when some of the properties of the current tool changes """ set_item = self.tool_items.SetStringItem index = self.selected_index handler = self.event_handler.GetValue() if not self.handler_re.match(handler): event.GetEventObject().SetFocus() return if index < 0: return event.Skip() set_item(index, 0, self.label.GetValue()) set_item(index, 1, self.id.GetValue()) set_item(index, 2, self.bitmap1.GetValue()) set_item(index, 3, self.bitmap2.GetValue()) set_item(index, 4, self.help_str.GetValue()) set_item(index, 5, self.long_help_str.GetValue()) set_item(index, 6, str(self.check_radio.GetSelection())) set_item(index, 7, self.event_handler.GetValue()) try: event.Skip() except AttributeError: # this happens on wx2.4.0.1 for FileBrowseButton events pass # update the directory of the browse buttons directory = os.path.split(self.bitmap1.GetValue())[0] if not os.path.isdir(directory): directory = os.path.split(self.bitmap2.GetValue())[0] if os.path.isdir(directory): self.bitmap1.startDirectory = directory self.bitmap2.startDirectory = directory def remove_tool(self, event): """\ Event handler called when the Remove button is clicked """ if self.selected_index >= 0: for s in (self.id, self.label, self.help_str, self.long_help_str, self.event_handler): s.SetValue("") for s in (self.bitmap1, self.bitmap2): s.SetValue("", False) self.check_radio.SetSelection(0) self.tool_items.DeleteItem(self.selected_index) if not self.tool_items.GetItemCount(): for s in (self.id, self.label, self.help_str, self.long_help_str, self.bitmap1, self.bitmap2, self.check_radio, self.event_handler): s.Enable(False) def add_tools(self, tools): """\ adds the content of 'tools' to self.tool_items. tools is a sequence of (simple) tool items for the toolbar. At the moment there is no control support, but I hope to add it soon """ set_item = self.tool_items.SetStringItem add_item = self.tool_items.InsertStringItem index = [0] def add(tool): i = index[0] add_item(i, misc.wxstr(tool.label)) set_item(i, 1, misc.wxstr(tool.id)) set_item(i, 2, misc.wxstr(tool.bitmap1)) set_item(i, 3, misc.wxstr(tool.bitmap2)) set_item(i, 4, misc.wxstr(tool.short_help)) set_item(i, 5, misc.wxstr(tool.long_help)) set_item(i, 7, misc.wxstr(tool.handler)) item_type = 0 set_item(i, 6, misc.wxstr(tool.type)) index[0] += 1 for tool in tools: add(tool) if self.tool_items.GetItemCount(): for s in (self.id, self.label, self.help_str, self.long_help_str, self.bitmap1, self.bitmap2, self.check_radio, self.event_handler): s.Enable(True) def get_tools(self): """\ returns the contents of self.tool_items as a list of tools that describes the contents of the ToolBar """ def get(i, j): return self.tool_items.GetItem(i, j).m_text tools = [] def add(index): label = get(index, 0) id = get(index, 1) bitmap1 = get(index, 2) bitmap2 = get(index, 3) short_help = get(index, 4) long_help = get(index, 5) event_handler = get(index, 7) try: item_type = int(get(index, 6)) except ValueError: item_type = 0 tools.append(Tool(label=label, id=id, type=item_type, short_help=short_help, long_help=long_help, bitmap1=bitmap1, bitmap2=bitmap2, handler=event_handler)) for index in range(self.tool_items.GetItemCount()): add(index) return tools def move_item_up(self, event): """\ moves the selected tool before the previous one at the same level in self.tool_items """ self.tool_items.SetFocus() if self.selected_index > 0: index = self.selected_index - 1 vals1 = [ self.tool_items.GetItem(self.selected_index, i).m_text \ for i in range(8) ] vals2 = [ self.tool_items.GetItem(index, i).m_text \ for i in range(8) ] for i in range(8): self.tool_items.SetStringItem(index, i, vals1[i]) self.tool_items.SetStringItem(self.selected_index, i, vals2[i]) state = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED self.tool_items.SetItemState(index, state, state) self.selected_index = index def move_item_down(self, event): """\ moves the selected tool after the next one at the same level in self.tool_items """ self.tool_items.SetFocus() if self.selected_index < self.tool_items.GetItemCount()-1: index = self.selected_index + 1 vals1 = [ self.tool_items.GetItem(self.selected_index, i).m_text \ for i in range(8) ] vals2 = [ self.tool_items.GetItem(index, i).m_text \ for i in range(8) ] for i in range(8): self.tool_items.SetStringItem(index, i, vals1[i]) self.tool_items.SetStringItem(self.selected_index, i, vals2[i]) state = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED self.tool_items.SetItemState(index, state, state) self.selected_index = index def on_apply(self, event): self.owner.set_tools(self.get_tools()) common.app_tree.app.saved = False # end of class ToolsDialog class ToolsProperty(Property): """\ Property to edit the tools of an EditToolBar instance. """ def __init__(self, owner, name, parent): Property.__init__(self, owner, name, parent) self.panel = None self.tools = {} if parent is not None: self.display(parent) def display(self, parent): self.panel = wx.Panel(parent, -1) edit_btn_id = wx.NewId() self.edit_btn = wx.Button(self.panel, edit_btn_id, _("Edit tools...")) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.edit_btn, 1, wx.EXPAND|wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM, 4) self.panel.SetAutoLayout(1) self.panel.SetSizer(sizer) self.panel.SetSize(sizer.GetMinSize()) wx.EVT_BUTTON(self.panel, edit_btn_id, self.edit_tools) def bind_event(*args): pass def edit_tools(self, event): dialog = ToolsDialog(self.panel, self.owner, items=self.owner.get_tools()) if dialog.ShowModal() == wx.ID_OK: self.owner.set_tools(dialog.get_tools()) common.app_tree.app.saved = False # update the status of the app def write(self, outfile, tabs): fwrite = outfile.write fwrite(' ' * tabs + '\n') for tool in self.owner[self.name][0](): tool.write(outfile, tabs+1) fwrite(' ' * tabs + '\n') # end of class ToolsProperty class EditToolBar(EditBase, PreviewMixin): def __init__(self, name, klass, parent, property_window): custom_class = parent is None EditBase.__init__(self, name, klass, parent, wx.NewId(), property_window, custom_class=custom_class, show=False) self.base = 'wx.ToolBar' def nil(*args): return () self.tools = [] # list of Tool objects self._tb = None # the real toolbar self.style = 0 self.access_functions['style'] = (self.get_style, self.set_style) self.style_pos = [wx.TB_FLAT, wx.TB_DOCKABLE, wx.TB_3DBUTTONS] self.style_pos += [wx.TB_TEXT, wx.TB_NOICONS, wx.TB_NODIVIDER, wx.TB_NOALIGN] self.style_pos += [wx.TB_HORZ_LAYOUT, wx.TB_HORZ_TEXT] style_labels = ['#section#' + _('Style'), 'wxTB_FLAT', 'wxTB_DOCKABLE', 'wxTB_3DBUTTONS'] style_labels += ['wxTB_TEXT', 'wxTB_NOICONS', 'wxTB_NODIVIDER', 'wxTB_NOALIGN'] style_labels += ['wxTB_HORZ_LAYOUT', 'wxTB_HORZ_TEXT'] self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) self.bitmapsize = '16, 15' self.access_functions['bitmapsize'] = (self.get_bitmapsize, self.set_bitmapsize) self.properties['bitmapsize'] = TextProperty(self, 'bitmapsize', None, can_disable=True, label=_("bitmapsize")) self.margins = '0, 0' self.access_functions['margins'] = (self.get_margins, self.set_margins) self.properties['margins'] = TextProperty(self, 'margins', None, can_disable=True, label=_("margins")) self.access_functions['tools'] = (self.get_tools, self.set_tools) prop = self.properties['tools'] = ToolsProperty(self, 'tools', None) self.packing = 1 self.access_functions['packing'] = (self.get_packing, self.set_packing) self.properties['packing'] = SpinProperty(self, 'packing', None, r=(0, 100), can_disable=True, label=_("packing")) self.separation = 5 self.access_functions['separation'] = (self.get_separation, self.set_separation) self.properties['separation'] = SpinProperty( self, 'separation', None, r=(0, 100), can_disable=True, label=_("separation")) # 2003-05-07 preview support PreviewMixin.__init__(self) def create_widget(self): tb_style = wx.TB_HORIZONTAL|self.style if wx.Platform == '__WXGTK__': tb_style |= wx.TB_DOCKABLE|wx.TB_FLAT if self.parent: self.widget = self._tb = wx.ToolBar( self.parent.widget, -1, style=tb_style) self.parent.widget.SetToolBar(self.widget) else: # "top-level" toolbar self.widget = wx.Frame(None, -1, misc.design_title(self.name)) self.widget.SetClientSize((400, 30)) self._tb = wx.ToolBar(self.widget, -1, style=tb_style) self.widget.SetToolBar(self._tb) self.widget.SetBackgroundColour(self._tb.GetBackgroundColour()) icon = wx.EmptyIcon() xpm = os.path.join(common.icons_path, 'toolbar.xpm') icon.CopyFromBitmap(misc.get_xpm_bitmap(xpm)) self.widget.SetIcon(icon) wx.EVT_CLOSE(self.widget, lambda e: self.hide_widget()) wx.EVT_LEFT_DOWN(self._tb, self.on_set_focus) if wx.Platform == '__WXMSW__': # MSW isn't smart enough to avoid overlapping windows, so # at least move it away from the 3 wxGlade frames self.widget.CenterOnScreen() wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) # set the various property values prop = self.properties if prop['bitmapsize'].is_active(): self.set_bitmapsize(self.bitmapsize, refresh=False) if prop['margins'].is_active(): self.set_margins(self.margins, refresh=False) if prop['packing'].is_active(): self.set_packing(self.packing, refresh=False) if prop['separation'].is_active(): self.set_separation(self.separation, refresh=False) self.set_tools(self.tools) # show the menus def create_properties(self): EditBase.create_properties(self) page = self._common_panel sizer = page.GetSizer() self.properties['bitmapsize'].display(page) self.properties['margins'].display(page) self.properties['packing'].display(page) self.properties['separation'].display(page) self.properties['style'].display(page) self.properties['tools'].display(page) if not sizer: sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.name_prop.panel, 0, wx.EXPAND) sizer.Add(self.klass_prop.panel, 0, wx.EXPAND) page.SetAutoLayout(1) page.SetSizer(sizer) sizer.Add(self.properties['bitmapsize'].panel, 0, wx.EXPAND) sizer.Add(self.properties['margins'].panel, 0, wx.EXPAND) sizer.Add(self.properties['packing'].panel, 0, wx.EXPAND) sizer.Add(self.properties['separation'].panel, 0, wx.EXPAND) sizer.Add(self.properties['style'].panel, 0, wx.EXPAND) sizer.Add(self.properties['tools'].panel, 0, wx.ALL|wx.EXPAND, 3) sizer.Layout() sizer.Fit(page) w, h = page.GetClientSize() self.notebook.AddPage(page, _("Common")) if self.parent is not None: self.property_window.Layout() page.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) else: PreviewMixin.create_properties(self) def __getitem__(self, key): return self.access_functions[key] def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if (self.style & self.style_pos[i]) == self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value, refresh=True): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self._tb: self._tb.SetWindowStyleFlag(self.style) if refresh: self._refresh_widget() def get_margins(self): return self.margins def set_margins(self, value, refresh=True): try: margins = [int(t.strip()) for t in value.split(',')] except: self.properties['margins'].set_value(self.margins) else: self.margins = value if self._tb: self._tb.SetMargins(margins) if refresh: self._refresh_widget() def get_packing(self): return self.packing def set_packing(self, value, refresh=True): try: value = int(value) except: self.properties['packing'].set_value(self.packing) else: self.packing = value if self._tb: self._tb.SetToolPacking(self.packing) if refresh: self._refresh_widget() def get_separation(self): return self.separation def set_separation(self, value, refresh=True): try: value = int(value) except: self.properties['separation'].set_value(self.separation) else: self.separation = value if self._tb: self._tb.SetToolSeparation(self.separation) if refresh: self._refresh_widget() def get_bitmapsize(self): return self.bitmapsize def set_bitmapsize(self, value, refresh=True): try: size = [int(t.strip()) for t in value.split(',')] except: self.properties['bitmapsize'].set_value(self.bitmapsize) else: self.bitmapsize = value if self._tb: self._tb.SetToolBitmapSize(size) if refresh: self._refresh_widget() def get_tools(self): return self.tools def set_tools(self, tools): self.tools = tools if not self._tb: return # nothing left to do while self._tb.DeleteToolByPos(0): pass # clear the toolbar # now add all the tools for tool in self.tools: if misc.streq(tool.id, '---'): # the tool is a separator self._tb.AddSeparator() else: if tool.bitmap1: bmp1 = None if not (tool.bitmap1.startswith('var:') or tool.bitmap1.startswith('code:')): bmp1 = wx.Bitmap( misc.get_relative_path(misc.wxstr(tool.bitmap1)), wx.BITMAP_TYPE_ANY) if not bmp1 or not bmp1.Ok(): bmp1 = wx.EmptyBitmap(1, 1) else: bmp1 = wx.NullBitmap if tool.bitmap2: bmp2 = None if not (tool.bitmap2.startswith('var:') or tool.bitmap2.startswith('code:')): bmp2 = wx.Bitmap( misc.get_relative_path(misc.wxstr(tool.bitmap2)), wx.BITMAP_TYPE_ANY) if not bmp2 or not bmp2.Ok(): bmp2 = wx.EmptyBitmap(1, 1) else: bmp2 = wx.NullBitmap kinds = [wx.ITEM_NORMAL, wx.ITEM_CHECK, wx.ITEM_RADIO] try: kind = kinds[int(tool.type)] except (ValueError, IndexError): kind = wx.ITEM_NORMAL self._tb.AddLabelTool(wx.NewId(), misc.wxstr(tool.label), bmp1, bmp2, kind, misc.wxstr(tool.short_help), misc.wxstr(tool.long_help)) # this is required to refresh the toolbar properly self._refresh_widget() def _refresh_widget(self): self._tb.Realize() self._tb.SetSize((-1, self._tb.GetBestSize()[1])) if self.parent: widget = self.parent.widget w, h = widget.GetClientSize() widget.SetClientSize((w, h+1)) widget.SetClientSize((w, h)) else: widget = self.widget w = widget.GetClientSize()[0] h = self._tb.GetSize()[1] / 2 widget.SetClientSize((w, h)) def remove(self, *args, **kwds): if self.parent is not None: self.parent.properties['toolbar'].set_value(0) if kwds.get('do_nothing', False): # and wxPlatform == '__WXGTK__': # this probably leaks memory, but avoids segfaults self.widget = None else: if self.parent.widget: self.parent.widget.SetToolBar(None) else: if self.widget: self.widget.Destroy() self.widget = None EditBase.remove(self) def popup_menu(self, event): if self.parent is not None: return # do nothing in this case if self.widget: if not self._rmenu: REMOVE_ID, HIDE_ID = [wx.NewId() for i in range(2)] self._rmenu = misc.wxGladePopupMenu(self.name) misc.append_item(self._rmenu, REMOVE_ID, _('Remove\tDel'), wx.ART_DELETE) misc.append_item(self._rmenu, HIDE_ID, _('Hide')) def bind(method): return lambda e: wx.CallAfter(method) wx.EVT_MENU(self.widget, REMOVE_ID, bind(self.remove)) wx.EVT_MENU(self.widget, HIDE_ID, bind(self.hide_widget)) self.widget.PopupMenu(self._rmenu, event.GetPosition()) def hide_widget(self, *args): if self.widget and self.widget is not self._tb: self.widget.Hide() common.app_tree.expand(self.node, False) common.app_tree.select_item(self.node.parent) common.app_tree.app.show_properties() def set_name(self, name): EditBase.set_name(self, name) if self.widget is not self._tb: self.widget.SetTitle(misc.design_title(misc.wxstr(self.name))) def get_property_handler(self, name): class ToolsHandler: itemattrs = ['label', 'id', 'short_help', 'long_help', 'bitmap1', 'bitmap2', 'type', 'handler'] def __init__(self, owner): self.owner = owner self.tools = [] self.curr_tool = None self.curr_index = -1 def start_elem(self, name, attrs): if name == 'tools': return if name == 'tool': self.curr_tool = Tool() else: try: self.curr_index = self.itemattrs.index(name) except ValueError: self.curr_index = -1 pass # just ignore the attributes we don't know ## from xml_parse import XmlParsingError ## raise XmlParsingError, _("invalid tool attribute") def end_elem(self, name): if name == 'tool': self.tools.append(self.curr_tool) if name == 'tools': self.owner.set_tools(self.tools) return True def char_data(self, data): if self.curr_index >= 0: setattr(self.curr_tool, self.itemattrs[self.curr_index], data) if name == 'tools': return ToolsHandler(self) return None # end of class EditToolBar def builder(parent, sizer, pos, number=[0]): """\ factory function for EditToolBar objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, _('Select toolbar class')) if common.app_tree.app.get_language().lower() == 'xrc': self.klass = 'wxToolBar' else: if not number[0]: self.klass = 'MyToolBar' else: self.klass = 'MyToolBar%s' % number[0] number[0] += 1 klass_prop = TextProperty(self, 'class', self) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(klass_prop.panel, 0, wx.EXPAND) sz2 = wx.BoxSizer(wx.HORIZONTAL) sz2.Add(wx.Button(self, wx.ID_OK, _('OK')), 0, wx.ALL, 3) sz2.Add(wx.Button(self, wx.ID_CANCEL, _('Cancel')), 0, wx.ALL, 3) szr.Add(sz2, 0, wx.ALL|wx.ALIGN_CENTER, 3) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) #self.SetSize((150, -1)) def undo(self): if number[0] > 0: number[0] -= 1 def __getitem__(self, value): if value == 'class': def set_klass(c): self.klass = c return (lambda : self.klass, set_klass) # end of inner class dialog = Dialog() if dialog.ShowModal() == wx.ID_CANCEL: # cancel the operation dialog.undo() dialog.Destroy() return name = 'toolbar_%d' % (number[0] or 1) while common.app_tree.has_name(name): number[0] += 1 name = 'toolbar_%d' % number[0] tb = EditToolBar(name, dialog.klass, parent, common.property_panel) tb.node = Tree.Node(tb) common.app_tree.add(tb.node) tb.show_widget(True) tb.show_properties() def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditMenuBar objects from an xml file """ name = attrs.get('name') if parent is not None: if name: parent.toolbar.set_name(name) parent.toolbar.name_prop.set_value(name) return parent.toolbar else: tb = EditToolBar(name, attrs.get('class', 'wxMenuBar'), None, common.property_panel) tb.node = Tree.Node(tb) common.app_tree.add(tb.node) return tb def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ cwx = common.widgets_from_xml cwx['EditToolBar'] = xml_builder common.widgets['EditToolBar'] = builder return common.make_object_button('EditToolBar', 'icons/toolbar.xpm', 1) wxglade-0.6.8.orig/widgets/toolbar/__init__.py0000644000175000017500000000074511621715605021550 0ustar georgeskgeorgesk# __init__.py: toolbar widget module initialization # $Id: __init__.py,v 1.5 2007/03/27 07:01:51 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import toolbar global EditToolBar; EditToolBar = toolbar.EditToolBar return toolbar.initialize() wxglade-0.6.8.orig/widgets/panel/0000755000175000017500000000000012170277707017074 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/panel/perl_codegen.py0000644000175000017500000000577111646104071022074 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxPanel objects # $Id: perl_codegen.py,v 1.11 2007/08/07 12:15:21 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: #wxScrolledWindow(parent, id, pos, size, style, name ) new_signature = [ '$parent', '$id', '$pos', '$size', '$style', '$name' ] def get_code(self, panel): plgen = common.code_writers['perl'] prop = panel.properties try: scrollable = int(prop['scrollable']) except: scrollable = False id_name, id = plgen.generate_code_id(panel) if not panel.parent.is_toplevel: parent = '$self->{%s}' % panel.parent.name else: parent = '$self' if panel.is_toplevel: l = [] if id_name: l.append(id_name) klass = panel.base if klass != panel.klass: klass = panel.klass else: klass = klass.replace('wx', 'Wx::', 1) l.append('$self->{%s} = %s->new(%s, %s);\n' % (panel.name, klass, parent, id)) return l, [], [] init = [] if id_name: init.append(id_name) style = prop.get("style", 'wxTAB_TRAVERSAL') if not( scrollable or style != 'wxTAB_TRAVERSAL' ): style = '' # ALB 2005-11-19 if not int(panel.properties.get('no_custom_class', False)): if scrollable: klass = 'Wx::ScrolledWindow' else: klass = 'Wx::Panel' else: klass = plgen.cn(panel.klass) init.append('$self->{%s} = %s->new(%s, %s, \ wxDefaultPosition, wxDefaultSize, %s);\n' % (panel.name, klass, parent, id, style)) props_buf = plgen.generate_common_properties(panel) if scrollable: sr = prop.get('scroll_rate', '0, 0') props_buf.append('$self->{%s}->SetScrollRate(%s);\n' % (panel.name, sr)) return init, props_buf, [] def get_properties_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties try: scrollable = int(prop['scrollable']) except: scrollable = False props_buf = plgen.generate_common_properties(obj) if scrollable: sr = prop.get('scroll_rate', '0, 0') props_buf.append('$self->SetScrollRate(%s);\n' % sr) return props_buf # end of class PerlCodeGenerator def initialize(): common.class_names['EditPanel'] = 'wxPanel' common.class_names['EditTopLevelPanel'] = 'wxPanel' common.toplevels['EditPanel'] = 1 common.toplevels['EditTopLevelPanel'] = 1 plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxPanel', PerlCodeGenerator()) plgen.add_widget_handler('wxScrolledWindow', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/panel/lisp_codegen.py0000644000175000017500000000551312150154266022075 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxPanel objects # $Id: lisp_codegen.py,v 1.2 2007/08/07 12:15:21 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: #wxScrolledWindow(parent, id, pos, size, style, name ) new_signature = [ '$parent', '$id', '$pos', '$size', '$style', '$name' ] def get_code(self, panel): codegen = common.code_writers['lisp'] prop = panel.properties try: scrollable = int(prop['scrollable']) except: scrollable = False id_name, id = codegen.generate_code_id(panel) if not panel.parent.is_toplevel: parent = '(slot-%s obj)' % panel.parent.name else: parent = '(slot-top-window obj)' if panel.is_toplevel: l = [] if id_name: l.append(id_name) l.append('(setf (slot-%s obj) (wxPanel_Create %s %s -1 -1 -1 -1))\n' % (panel.name, parent, id)) return l, [], [] init = [] if id_name: init.append(id_name) style = prop.get("style", 'wxTAB_TRAVERSAL') if not( scrollable or style != 'wxTAB_TRAVERSAL' ): style = 'wxTAB_TRAVERSAL' else: style = codegen.cn_f(style) init.append('(setf (slot-%s obj) ' '(wxPanel_Create %s %s -1 -1 -1 -1 %s))\n' % (panel.name, parent, id, style)) props_buf = codegen.generate_common_properties(panel) if scrollable: sr = prop.get('scroll_rate', '0 0') sr = sr.replace(',',' ') props_buf.append('(wxScrolledWindow:wxScrolledWindow_SetScrollRate' ' (slot-%s obj) %s)\n' % (panel.name, sr)) return init, props_buf, [] def get_properties_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties try: scrollable = int(prop['scrollable']) except: scrollable = False props_buf = codegen.generate_common_properties(obj) if scrollable: sr = prop.get('scroll_rate', '0 0') props_buf.append('(wxScrolledWindow:wxScrolledWindow_SetScrollRate ' '(slot-%s obj))\n' % sr) return props_buf # end of class LispCodeGenerator def initialize(): common.class_names['EditPanel'] = 'wxPanel' common.class_names['EditTopLevelPanel'] = 'wxPanel' common.toplevels['EditPanel'] = 1 common.toplevels['EditTopLevelPanel'] = 1 codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxPanel', LispCodeGenerator()) codegen.add_widget_handler('wxScrolledWindow', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/panel/codegen.py0000644000175000017500000001437612072605532021055 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxPanel objects # $Id: codegen.py,v 1.19 2007/08/07 12:15:21 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, panel): pygen = common.code_writers['python'] cn = pygen.cn cn_f = pygen.cn_f prop = panel.properties try: scrollable = int(prop['scrollable']) except: scrollable = False id_name, id = pygen.generate_code_id(panel) if not panel.parent.is_toplevel: parent = 'self.%s' % panel.parent.name else: parent = 'self' if panel.is_toplevel: l = [] if id_name: l.append(id_name) l.append('self.%s = %s(%s, %s)\n' % (panel.name, pygen.without_package(panel.klass), parent, id)) return l, [], [] init = [] if id_name: init.append(id_name) style = prop.get("style", 'wxTAB_TRAVERSAL') if scrollable or style != 'wxTAB_TRAVERSAL': style = ", style=%s" % cn_f(style) else: style = '' # ALB 2005-11-19 if not int(panel.properties.get('no_custom_class', False)) \ or panel.preview: if scrollable: klass = cn('wxScrolledWindow') else: klass = cn('wxPanel') else: klass = panel.klass if klass in ('wxPanel', 'wxScrolledWindow'): klass = cn(klass) init.append('self.%s = %s(%s, %s%s)\n' % \ (panel.name, klass, parent, id, style)) props_buf = pygen.generate_common_properties(panel) if scrollable: sr = prop.get('scroll_rate', '0, 0') props_buf.append('self.%s.SetScrollRate(%s)\n' % (panel.name, sr)) return init, props_buf, [] def get_properties_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties try: scrollable = int(prop['scrollable']) except: scrollable = False props_buf = pygen.generate_common_properties(obj) if scrollable: sr = prop.get('scroll_rate', '0, 0') props_buf.append('self.SetScrollRate(%s)\n' % sr) return props_buf # end of class PythonCodeGenerator class CppCodeGenerator: constructor = [('wxWindow*', 'parent'), ('int', 'id'), ('const wxPoint&', 'pos', 'wxDefaultPosition'), ('const wxSize&', 'size', 'wxDefaultSize'), ('long', 'style', '0')] def get_code(self, panel): """\ generates the C++ code for wxPanel objects """ cppgen = common.code_writers['C++'] prop = panel.properties try: scrollable = int(prop['scrollable']) except: scrollable = False id_name, id = cppgen.generate_code_id(panel) if id_name: ids = [ id_name ] else: ids = [] if not panel.parent.is_toplevel: parent = '%s' % panel.parent.name else: parent = 'this' if panel.is_toplevel: l = ['%s = new %s(%s, %s);\n' % (panel.name, panel.klass, parent, id)] return l, ids, [], [] extra = '' style = prop.get("style", 'wxTAB_TRAVERSAL') if scrollable or style != 'wxTAB_TRAVERSAL': extra = ', wxDefaultPosition, wxDefaultSize, %s' % style # ALB 2005-11-19 if not int(panel.properties.get('no_custom_class', False)): if scrollable: klass = 'wxScrolledWindow' else: klass = 'wxPanel' else: klass = panel.klass init = ['%s = new %s(%s, %s%s);\n' % (panel.name, klass, parent, id, extra) ] props_buf = cppgen.generate_common_properties(panel) if scrollable: sr = prop.get('scroll_rate', '0, 0') props_buf.append('%s->SetScrollRate(%s);\n' % (panel.name, sr)) return init, ids, props_buf, [] def get_properties_code(self, obj): cppgen = common.code_writers['C++'] prop = obj.properties try: scrollable = int(prop['scrollable']) except: scrollable = False props_buf = cppgen.generate_common_properties(obj) if scrollable: sr = prop.get('scroll_rate', '0, 0') props_buf.append('SetScrollRate(%s);\n' % sr) return props_buf # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class XrcCodeGenerator(xrcgen.DefaultXrcObject): def write(self, *args, **kwds): if 'scrollable' in self.properties: style = self.properties.get('style', '').split('|') try: style.remove('wxTAB_TRAVERSAL') except ValueError: pass self.properties['style'] = '|'.join(style) for prop in ('scrollable', 'scroll_rate'): try: del self.properties[prop] except KeyError: pass if 'no_custom_class' in self.properties: del self.properties['no_custom_class'] xrcgen.DefaultXrcObject.write(self, *args, **kwds) return XrcCodeGenerator(obj) def initialize(): common.class_names['EditPanel'] = 'wxPanel' common.class_names['EditTopLevelPanel'] = 'wxPanel' common.toplevels['EditPanel'] = 1 common.toplevels['EditTopLevelPanel'] = 1 common.class_names['EditScrolledWindow'] = 'wxScrolledWindow' common.class_names['EditTopLevelScrolledWindow'] = 'wxScrolledWindow' common.toplevels['EditScrolledWindow'] = 1 common.toplevels['EditTopLevelScrolledWindow'] = 1 # python code generation functions pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxPanel', PythonCodeGenerator()) pygen.add_widget_handler('wxScrolledWindow', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxPanel', CppCodeGenerator()) cppgen.add_widget_handler('wxScrolledWindow', CppCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxPanel', xrc_code_generator) xrcgen.add_widget_handler('wxScrolledWindow', xrc_code_generator) wxglade-0.6.8.orig/widgets/panel/panel.py0000644000175000017500000004343011677701470020551 0ustar georgeskgeorgesk# panel.py: wxPanel objects # $Id: panel.py,v 1.38 2007/08/07 12:15:21 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from tree import Tree from widget_properties import * from edit_windows import ManagedBase, TopLevelBase class PanelBase(object): _custom_base_classes = True def __init__(self, style=wx.TAB_TRAVERSAL): """\ Class to handle wxPanel objects """ super(PanelBase, self).__init__() self.top_sizer = None # sizer to handle the layout of children # ------ ALB 2005-11-19: option to disable custom class code generation self.no_custom_class = False self.access_functions['no_custom_class'] = (self.get_no_custom_class, self.set_no_custom_class) self.properties['no_custom_class'] = CheckBoxProperty( self, 'no_custom_class', label=_("Don't generate code for this custom class")) # ------ self.style = style self.access_functions['style'] = (self.get_style, self.set_style) self.style_pos = [wx.SIMPLE_BORDER, wx.DOUBLE_BORDER, wx.SUNKEN_BORDER, wx.RAISED_BORDER, wx.STATIC_BORDER, wx.NO_BORDER, wx.NO_3D, wx.TAB_TRAVERSAL, wx.WANTS_CHARS, wx.NO_FULL_REPAINT_ON_RESIZE, wx.FULL_REPAINT_ON_RESIZE, wx.CLIP_CHILDREN] style_labels = ('#section#' + _('Style'), 'wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER', 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxWANTS_CHARS', 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE', 'wxCLIP_CHILDREN') self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) self.access_functions['scrollable'] = (self.get_scrollable, self.set_scrollable) self.scrollable = False self.properties['scrollable'] = CheckBoxProperty( self, 'scrollable', None, label=_("scrollable")) self.scroll_rate = (10, 10) self.access_functions['scroll_rate'] = (self.get_scroll_rate, self.set_scroll_rate) self.properties['scroll_rate'] = TextProperty( self, 'scroll_rate', None, can_disable=True, label=_("scroll_rate")) def finish_widget_creation(self): super(PanelBase, self).finish_widget_creation( sel_marker_parent=self.widget) if not self.scrollable: self.widget.SetScrollRate(0, 0) else: self.widget.SetScrollRate(*self.scroll_rate) # this must be done here since ManagedBase.finish_widget_creation # normally sets EVT_LEFT_DOWN to update_wiew if not self.widget.Disconnect(-1, -1, wx.wxEVT_LEFT_DOWN): print _("EditPanel: Unable to disconnect the event hanlder") wx.EVT_LEFT_DOWN(self.widget, self.drop_sizer) #wx.EVT_SCROLLWIN(self.widget, self._update_markers) def _update_markers(self, event): def get_pos(): x, y = self.widget.GetPosition() xx, yy = self.widget.GetViewStart() return x+xx, y+yy old = self.widget.GetPosition self.widget.GetPosition = get_pos #print self.widget, self.sel_marker.owner self.sel_marker.update() self.widget.GetPosition = old event.Skip() def create_properties(self): super(PanelBase, self).create_properties() panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) panel.SetScrollRate(5, 5) szr = wx.BoxSizer(wx.VERTICAL) self.properties['no_custom_class'].display(panel) szr.Add(self.properties['no_custom_class'].panel, 0, wx.EXPAND) label = self.properties['no_custom_class'].cb label.SetToolTip( wx.ToolTip(_('If this is a custom class, setting this property ' 'prevents wxGlade\nfrom generating the class definition' ' code'))) self.properties['style'].display(panel) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) self.properties['scrollable'].display(panel) szr.Add(self.properties['scrollable'].panel, 0, wx.EXPAND) self.properties['scroll_rate'].display(panel) szr.Add(self.properties['scroll_rate'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def on_enter(self, event): if not self.top_sizer and common.adding_sizer: self.widget.SetCursor(wx.CROSS_CURSOR) else: self.widget.SetCursor(wx.STANDARD_CURSOR) def set_sizer(self, sizer): self.top_sizer = sizer if self.top_sizer and self.top_sizer.widget and self.widget: self.widget.SetAutoLayout(True) self.widget.SetSizer(self.top_sizer.widget) self.widget.Layout() elif self.top_sizer is None and self.widget: self.widget.SetSizer(None) def drop_sizer(self, event): if self.top_sizer or not common.adding_sizer: self.on_set_focus(event) # default behaviour: call show_properties return self.widget.SetCursor(wx.NullCursor) common.widgets[common.widget_to_add](self, None, None) common.adding_widget = common.adding_sizer = False common.widget_to_add = None common.app_tree.app.saved = False def get_widget_best_size(self): if self.top_sizer and self.widget.GetSizer(): self.top_sizer.fit_parent() return self.widget.GetSize() return wx.ScrolledWindow.GetBestSize(self.widget) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] def get_scrollable(self): return self.scrollable def set_scrollable(self, value): self.scrollable = bool(int(value)) if self.scrollable: if self.klass == 'wxPanel': self.klass = 'wxScrolledWindow' self.klass_prop.set_value(self.klass) else: if self.klass == 'wxScrolledWindow': self.klass = 'wxPanel' self.klass_prop.set_value(self.klass) if not self.widget: return if self.scrollable: self.properties['scroll_rate'].toggle_active(True) self.widget.SetScrollRate(*self.scroll_rate) else: self.properties['scroll_rate'].toggle_active(False) self.widget.SetScrollRate(0, 0) def get_scroll_rate(self): return '%d, %d' % self.scroll_rate def set_scroll_rate(self, value): invalid = False try: srx, sry = [int(t) for t in value.split(',', 1)] if srx < 0 or sry < 0: invalid = True except: invalid = True if invalid: self.properties['scroll_rate'].set_value(self.get_scroll_rate()) return self.scroll_rate = srx, sry if self.widget: self.widget.SetScrollRate(srx, sry) def get_no_custom_class(self): return self.no_custom_class def set_no_custom_class(self, value): self.no_custom_class = bool(int(value)) # end of class PanelBase class EditPanel(PanelBase, ManagedBase): def __init__(self, name, parent, id, sizer, pos, property_window, show=True, style=wx.TAB_TRAVERSAL): """\ Class to handle wxPanel objects """ ManagedBase.__init__(self, name, 'wxPanel', parent, id, sizer, pos, property_window, show=show) PanelBase.__init__(self, style) def create_widget(self): #self.widget = wx.Panel(self.parent.widget, self.id, style=0) self.widget = wx.ScrolledWindow(self.parent.widget, self.id, style=0) wx.EVT_ENTER_WINDOW(self.widget, self.on_enter) self.widget.GetBestSize = self.get_widget_best_size if self.sizer.is_virtual(): def GetBestSize(): if self.widget and self.widget.GetSizer(): return self.widget.GetSizer().GetMinSize() #return wx.Panel.GetBestSize(self.widget) return wx.ScrolledWindow.GetBestSize(self.widget) self.widget.GetBestSize = GetBestSize def set_sizer(self, sizer): super(EditPanel, self).set_sizer(sizer) if self.top_sizer and self.top_sizer.widget and self.widget: self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def set_scrollable(self, value): super(EditPanel, self).set_scrollable(value) if self.scrollable: # 2003-06-26 ALB: change the "class name", to allow code generation # for a wxScrolledWindow (see Tree.Node.write and # common.class_names usage in xml_parse.py) self._classname = 'EditScrolledWindow' else: self._classname = self.__class__.__name__ def popup_menu(self, event): if self.widget: if not self._rmenu: COPY_ID, REMOVE_ID, CUT_ID = [wx.NewId() for i in range(3)] self._rmenu = misc.wxGladePopupMenu(self.name) misc.append_item(self._rmenu, REMOVE_ID, _('Remove\tDel'), wx.ART_DELETE) misc.append_item(self._rmenu, COPY_ID, _('Copy\tCtrl+C'), wx.ART_COPY) misc.append_item(self._rmenu, CUT_ID, _('Cut\tCtrl+X'), wx.ART_CUT) def bind(method): return lambda e: wx.CallAfter(method) wx.EVT_MENU(self.widget, REMOVE_ID, bind(self.remove)) wx.EVT_MENU(self.widget, COPY_ID, bind(self.clipboard_copy)) wx.EVT_MENU(self.widget, CUT_ID, bind(self.clipboard_cut)) # paste PASTE_ID = wx.NewId() misc.append_item(self._rmenu, PASTE_ID, _('Paste\tCtrl+V'), wx.ART_PASTE) wx.EVT_MENU(self.widget, PASTE_ID, bind(self.clipboard_paste)) PREVIEW_ID = wx.NewId() self._rmenu.AppendSeparator() misc.append_item(self._rmenu, PREVIEW_ID, _('Preview')) wx.EVT_MENU(self.widget, PREVIEW_ID, bind(self.preview_parent)) self.setup_preview_menu() self.widget.PopupMenu(self._rmenu, event.GetPosition()) def clipboard_paste(self, *args): import clipboard, xml_parse size = self.widget.GetSize() try: if clipboard.paste(self, None, 0): common.app_tree.app.saved = False self.widget.SetSize(size) except xml_parse.XmlParsingError, e: print _('\nwxGlade-WARNING: only sizers can be pasted here') # end of class EditPanel class EditTopLevelPanel(PanelBase, TopLevelBase): _is_toplevel = False # used to avoid to appear in the "Top Window" property # of the app def __init__(self, name, parent, id, property_window, klass='wxPanel', show=True, style=wx.TAB_TRAVERSAL): TopLevelBase.__init__(self, name, klass, parent, id, property_window, show=show, has_title=False) PanelBase.__init__(self, style) self.base = 'wxPanel' self.skip_on_size = False def create_widget(self): win = wx.Frame(common.palette, -1, misc.design_title(self.name), size=(400, 300)) import os icon = wx.EmptyIcon() xpm = os.path.join(common.icons_path, 'panel.xpm') icon.CopyFromBitmap(misc.get_xpm_bitmap(xpm)) win.SetIcon(icon) #self.widget = wx.Panel(win, self.id, style=0) self.widget = wx.ScrolledWindow(win, self.id, style=0) wx.EVT_ENTER_WINDOW(self.widget, self.on_enter) self.widget.GetBestSize = self.get_widget_best_size #self.widget.SetSize = win.SetSize wx.EVT_CLOSE(win, self.hide_widget) if wx.Platform == '__WXMSW__': win.CentreOnScreen() def show_widget(self, yes): oldval = self.get_size() super(EditTopLevelPanel, self).show_widget(yes) if self.widget: if yes and not self.properties['size'].is_active() \ and self.top_sizer: self.top_sizer.fit_parent() self.widget.GetParent().Show(yes) self.set_size(oldval) def hide_widget(self, *args): super(EditTopLevelPanel, self).hide_widget(*args) self.widget.GetParent().Hide() def set_name(self, name): super(EditTopLevelPanel, self).set_name(name) if self.widget: self.widget.GetParent().SetTitle(misc.design_title(self.name)) def delete(self): win = None if self.widget: win = self.widget.GetParent() super(EditTopLevelPanel, self).delete() if win is not None: win.Destroy() def on_size(self, event): w, h = event.GetSize() if self.skip_on_size: self.skip_on_size = False return super(EditTopLevelPanel, self).on_size(event) self.skip_on_size = True if self.widget.GetParent().GetClientSize() != (w, h): self.widget.GetParent().SetClientSize((w+2, h+2)) def set_scrollable(self, value): super(EditTopLevelPanel, self).set_scrollable(value) if self.scrollable: # 2003-06-26 ALB: change the "class name", to allow code generation # for a wxScrolledWindow (see Tree.Node.write and # common.class_names usage in xml_parse.py) self._classname = 'EditTopLevelScrolledWindow' else: self._classname = self.__class__.__name__ # end of class EditTopLevelPanel def builder(parent, sizer, pos, number=[1]): """\ factory function for EditPanel objects. """ name = 'panel_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'panel_%d' % number[0] panel = EditPanel(name, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(panel) panel.node = node panel.set_option(1) panel.set_flag("wxEXPAND") panel.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) sizer.set_item(panel.pos, 1, wx.EXPAND) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditPanel objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if not sizer or not sizeritem: raise XmlParsingError, _("sizer or sizeritem object cannot be None") panel = EditPanel(name, parent, wx.NewId(), sizer, pos, common.property_panel, True, style=0) sizer.set_item(panel.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(panel) panel.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return panel def xml_toplevel_builder(attrs, parent, sizer, sizeritem, pos=None): from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") panel = EditTopLevelPanel(label, parent, wx.NewId(), common.property_panel, show=False, style=0) node = Tree.Node(panel) panel.node = node common.app_tree.add(node) return panel def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditPanel'] = builder common.widgets_from_xml['EditPanel'] = xml_builder #common.widgets['EditScrolledWindow'] = builder common.widgets_from_xml['EditScrolledWindow'] = xml_builder common.widgets_from_xml['EditTopLevelPanel'] = xml_toplevel_builder common.widgets_from_xml['EditTopLevelScrolledWindow'] = \ xml_toplevel_builder from tree import WidgetTree import os.path icon = os.path.join(common.icons_path, 'panel.xpm') WidgetTree.images['EditTopLevelPanel'] = icon WidgetTree.images['EditScrolledWindow'] = icon WidgetTree.images['EditTopLevelScrolledWindow'] = icon # these are for backwards compatibility (may be removed someday...) common.widgets_from_xml['SplitterPane'] = xml_builder WidgetTree.images['SplitterPane'] = os.path.join( common.icons_path, 'panel.xpm' ) common.widgets_from_xml['NotebookPane'] = xml_builder WidgetTree.images['NotebookPane'] = os.path.join( common.icons_path, 'panel.xpm' ) return common.make_object_button('EditPanel', 'icons/panel.xpm', tip='Add a Panel/ScrolledWindow') wxglade-0.6.8.orig/widgets/panel/__init__.py0000644000175000017500000000104611621715605021200 0ustar georgeskgeorgesk# __init__.py: panel widget module initialization # $Id: __init__.py,v 1.10 2007/03/27 07:01:56 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import panel global EditTopLevelPanel; EditTopLevelPanel = panel.EditTopLevelPanel global EditPanel; EditPanel = panel.EditPanel return panel.initialize() wxglade-0.6.8.orig/widgets/static_bitmap/0000755000175000017500000000000012170277707020620 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/static_bitmap/perl_codegen.py0000644000175000017500000000502411677432041023614 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxStaticBitmap objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common #this should be in common _bmp_str_types = { '.bmp' : 'wxBITMAP_TYPE_BMP', '.gif' : 'wxBITMAP_TYPE_GIF', '.xpm' : 'wxBITMAP_TYPE_XPM', '.jpg' : 'wxBITMAP_TYPE_JPEG', '.jpeg': 'wxBITMAP_TYPE_JPEG', '.png' : 'wxBITMAP_TYPE_PNG', '.pcx' : 'wxBITMAP_TYPE_PCX' } class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties attribute = plgen.test_attribute(obj) id_name, id = plgen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' bmp_file = prop.get('bitmap', '') if not bmp_file: bmp = 'wxNullBitmap' elif bmp_file.startswith('var:'): # this is a variable holding bitmap path var = bmp_file[4:].strip() if var[0] != "$": var = "$" + var bmp = 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY)' % var elif bmp_file.startswith('code:'): bmp = '(%s)' % bmp_file[5:].strip() else: bmp = 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY)' % \ plgen.quote_path(bmp_file) if id_name: init.append(id_name) if attribute: prefix = '$self->{%s}' % obj.name else: prefix = '$self' style = prop.get('style') if not style: style = '' klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('%s = %s->new(%s, %s, %s, wxDefaultPosition, wxDefaultSize,' ' %s);\n' % (prefix, klass, parent, id, bmp, style)) props_buf = plgen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditStaticBitmap'] = 'wxStaticBitmap' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxStaticBitmap', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/static_bitmap/static_bitmap.py0000644000175000017500000001541411677432046024022 0ustar georgeskgeorgesk# static_bitmap.py: wxStaticBitmap objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditStaticBitmap(ManagedBase): def __init__(self, name, parent, id, bmp_file, sizer, pos, property_window, show=True): """\ Class to handle wxStaticBitmap objects """ self.attribute = True ManagedBase.__init__(self, name, 'wxStaticBitmap', parent, id, sizer, pos, property_window, show=show) self.set_bitmap(bmp_file) # bitmap property self.access_functions['bitmap'] = (self.get_bitmap, self.set_bitmap) def set_attribute(v): self.attribute = int(v) self.access_functions['attribute'] = (lambda : self.attribute, set_attribute) self.bitmap_prop = FileDialogProperty(self, 'bitmap', None, #panel, style=wx.OPEN|wx.FILE_MUST_EXIST, can_disable=False, label=_("bitmap")) self.properties['bitmap'] = self.bitmap_prop self.properties['attribute'] = CheckBoxProperty( self, 'attribute', None, _('Store as attribute'), write_always=True) self.style = 0 self.access_functions['style'] = (self.get_style, self.set_style) self.style_pos = (wx.SIMPLE_BORDER, wx.DOUBLE_BORDER, wx.SUNKEN_BORDER, wx.RAISED_BORDER, wx.STATIC_BORDER, wx.NO_3D, wx.TAB_TRAVERSAL, wx.WANTS_CHARS, wx.NO_FULL_REPAINT_ON_RESIZE, wx.FULL_REPAINT_ON_RESIZE, wx.CLIP_CHILDREN) style_labels = (u'#section#' + _('Style'), 'wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxWANTS_CHARS', 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE', 'wxCLIP_CHILDREN') self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) def create_widget(self): bmp = self.load_bitmap() self.widget = wx.StaticBitmap(self.parent.widget, self.id, bmp) if wx.Platform == '__WXMSW__': def get_best_size(): bmp = self.widget.GetBitmap() if bmp and bmp.Ok(): return bmp.GetWidth(), bmp.GetHeight() return wx.StaticBitmap.GetBestSize(self.widget) self.widget.GetBestSize = get_best_size def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) szr = wx.BoxSizer(wx.VERTICAL) self.properties['bitmap'].display(panel) self.properties['attribute'].display(panel) self.properties['style'].display(panel) szr.Add(self.properties['bitmap'].panel, 0, wx.EXPAND) szr.Add(self.properties['attribute'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) w, h = panel.GetClientSize() self.notebook.AddPage(panel, "Widget") self.property_window.Layout() import math panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def get_bitmap(self): return self.bitmap def set_bitmap(self, value): self.bitmap = value if self.widget: bmp = self.load_bitmap() self.widget.SetBitmap(bmp) self.set_size("%s, %s" % tuple(self.widget.GetBestSize())) def load_bitmap(self, empty=[None]): if self.bitmap and \ not (self.bitmap.startswith('var:') or self.bitmap.startswith('code:')): path = misc.get_relative_path(self.bitmap) print "LOADING FROM:", path return wx.Bitmap(path, wx.BITMAP_TYPE_ANY) else: if empty[0] is None: empty[0] = wx.EmptyBitmap(1, 1) return empty[0] def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] # end of class EditStaticBitmap def builder(parent, sizer, pos, number=[1]): """\ factory function for EditStaticBitmap objects. """ name = 'bitmap_%s' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'bitmap_%s' % number[0] bitmap = misc.FileSelector("Select the image") static_bitmap = EditStaticBitmap(name, parent, wx.NewId(), bitmap, sizer, pos, common.property_panel) node = Tree.Node(static_bitmap) static_bitmap.node = node static_bitmap.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditStaticBitmap objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, "'name' attribute missing" if sizer is None or sizeritem is None: raise XmlParsingError, "sizer or sizeritem object cannot be None" bitmap = EditStaticBitmap(label, parent, wx.NewId(), '', sizer, pos, common.property_panel) sizer.set_item(bitmap.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) #, size=bitmap.GetBestSize()) node = Tree.Node(bitmap) bitmap.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return bitmap def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditStaticBitmap'] = builder common.widgets_from_xml['EditStaticBitmap'] = xml_builder return common.make_object_button('EditStaticBitmap', 'icons/static_bitmap.xpm') wxglade-0.6.8.orig/widgets/static_bitmap/lisp_codegen.py0000644000175000017500000000472012150154266023620 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxStaticBitmap objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common #this should be in common _bmp_str_types = { '.bmp' : 'wxBITMAP_TYPE_BMP', '.gif' : 'wxBITMAP_TYPE_GIF', '.xpm' : 'wxBITMAP_TYPE_XPM', '.jpg' : 'wxBITMAP_TYPE_JPEG', '.jpeg': 'wxBITMAP_TYPE_JPEG', '.png' : 'wxBITMAP_TYPE_PNG', '.pcx' : 'wxBITMAP_TYPE_PCX' } class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties attribute = codegen.test_attribute(obj) id_name, id = codegen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' bmp_file = prop.get('bitmap', '') if not bmp_file: bmp = 'wxNullBitmap' elif bmp_file.startswith('var:'): # this is a variable holding bitmap path var = bmp_file[4:].strip() if var[0] != "$": var = "$" + var bmp = '(wxBitmap_CreateLoad %s wxBITMAP_TYPE_ANY)' % var elif bmp_file.startswith('code:'): bmp = '(%s)' % bmp_file[5:].strip() else: bmp = '(wxBitmap_CreateLoad %s wxBITMAP_TYPE_ANY)' % \ codegen.quote_path(bmp_file) if id_name: init.append(id_name) if attribute: prefix = '(slot-%s obj)' % obj.name else: prefix = '$self' style = prop.get('style') if not style: style = '0' else: style = codegen.cn_f(style) init.append('(setf %s (wxStaticBitmap_Create %s %s %s -1 -1 -1 -1 %s))\n' % (prefix, parent, id, bmp, style)) props_buf = codegen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditStaticBitmap'] = 'wxStaticBitmap' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxStaticBitmap', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/static_bitmap/codegen.py0000644000175000017500000001143411676431606022601 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxStaticBitmap objects # $Id: codegen.py,v 1.26 2007/03/27 07:01:53 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common, os class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] cn = pygen.cn prop = obj.properties attribute = pygen.test_attribute(obj) id_name, id = pygen.generate_code_id(obj) bmp_file = prop.get('bitmap', '') bmp_preview_path = os.path.join(common.icons_path, "icon.xpm") if not bmp_file: bmp = cn('wxNullBitmap') elif bmp_file.startswith('var:'): if obj.preview: bmp = "%s('%s',%s)" % (cn('wxBitmap'), bmp_preview_path, cn('wxBITMAP_TYPE_XPM') ) else: bmp = cn('wxBitmap') + '(%s, %s)' % (bmp_file[4:].strip(), cn('wxBITMAP_TYPE_ANY')) elif bmp_file.startswith('code:'): if obj.preview: bmp = "%s('%s',%s)" % (cn('wxBitmap'), bmp_preview_path, cn('wxBITMAP_TYPE_XPM') ) else: bmp = '(%s)' % bmp_file[5:].strip() else: if obj.preview: import misc bmp_file = misc.get_relative_path(bmp_file, True) bmp = (cn('wxBitmap') + '(%s, ' + cn('wxBITMAP_TYPE_ANY') + ')') % pygen.quote_str(bmp_file, False, False) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' init = [] if id_name: init.append(id_name) if attribute: prefix = 'self.' else: prefix = '' style = prop.get('style') if style: style = ', style=%s' % pygen.cn_f(style) else: style = '' klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('%s%s = %s(%s, %s, %s%s)\n' % (prefix, obj.name, klass, parent, id, bmp, style)) props_buf = pygen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, obj): cppgen = common.code_writers['C++'] prop = obj.properties attribute = cppgen.test_attribute(obj) id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] bmp_file = prop.get('bitmap', '') if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' if not bmp_file: bmp = 'wxNullBitmap' elif bmp_file.startswith('var:'): bmp = 'wxBitmap(%s,wxBITMAP_TYPE_ANY)' % bmp_file[4:].strip() elif bmp_file.startswith('code:'): bmp = '(%s)' % bmp_file[5:].strip() else: bmp = 'wxBitmap(%s, wxBITMAP_TYPE_ANY)' % \ cppgen.quote_str(bmp_file, False, False) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' if attribute: prefix = '' else: prefix = '%s* ' % obj.klass style = prop.get('style') if style: style = ', wxDefaultPosition, wxDefaultSize, ' + style else: style = '' init = [ '%s%s = new %s(%s, %s, %s%s);\n' % (prefix, obj.name, obj.klass, parent, id, bmp, style) ] props_buf = cppgen.generate_common_properties(obj) if not attribute: return [], ids, [], init + props_buf return init, ids, props_buf, [] # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class XrcCodeGenerator(xrcgen.DefaultXrcObject): def write(self, *args, **kwds): try: del self.properties['attribute'] except KeyError: pass xrcgen.DefaultXrcObject.write(self, *args, **kwds) return XrcCodeGenerator(obj) def initialize(): common.class_names['EditStaticBitmap'] = 'wxStaticBitmap' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxStaticBitmap', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxStaticBitmap', CppCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxStaticBitmap', xrc_code_generator) wxglade-0.6.8.orig/widgets/static_bitmap/__init__.py0000644000175000017500000000067111621715605022727 0ustar georgeskgeorgesk# __init__.py: static bitmap widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:53 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import static_bitmap return static_bitmap.initialize() wxglade-0.6.8.orig/widgets/frame/0000755000175000017500000000000012170277707017067 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/frame/perl_codegen.py0000644000175000017500000000770311621715605022070 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxFrame objects # $Id: perl_codegen.py,v 1.10 2007/03/27 07:01:59 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from MenuTree import * from codegen import StatusFieldsHandler class PerlStatusBarCodeGenerator: def get_code(self, obj): """\ function that generates code for the statusbar of a wxFrame. """ plgen = common.code_writers['perl'] labels, widths = obj.properties['statusbar'] style = obj.properties.get("style") if not style: style = '0' init = [ '$self->{%s} = $self->CreateStatusBar(%s, %s);\n' % (obj.name, len(labels), style) ] props = [] append = props.append append('$self->{%s}->SetStatusWidths(%s);\n' % (obj.name, ','.join(map(str, widths)))) labels = ',\n\t\t'.join([plgen.quote_str(l) for l in labels]) append('\n\tmy( @%s_fields ) = (\n\t\t%s\n\t);\n\n' % (obj.name, labels)) append('if( @%s_fields ) {\n' % obj.name) append('\t$self->{%s}->SetStatusText($%s_fields[$_], $_) ' % (obj.name, obj.name) ) append('\n\t\tfor 0 .. $#%s_fields ;\n\t}\n' % obj.name) return init, props, [] # end of class PerlStatusBarCodeGenerator class PerlFrameCodeGenerator: #wxFrame( parent, id, title, pos , size , style , name ) new_signature = [ '$parent', '$id', '$title', '$pos', '$size', '$style', '$name' ] def get_code(self, obj): return [], [], [], [] # the frame can't be a children def get_properties_code(self, frame): """\ generates the code for the various wxFrame specific properties. Returns a list of strings containing the generated code """ prop = frame.properties plgen = common.code_writers['perl'] out = [] title = prop.get('title') if title: out.append('$self->SetTitle(%s);\n' % plgen.quote_str(title)) icon = prop.get('icon') if icon: out.append('my $icon = Wx::Icon->new();\n') out.append('$icon->CopyFromBitmap(Wx::Bitmap->new(%s, ' 'wxBITMAP_TYPE_ANY));\n' % plgen.quote_str(icon)) out.append('$self->SetIcon($icon);\n') out.extend(plgen.generate_common_properties(frame)) return out def get_layout_code(self, frame): ret = ['$self->Layout();\n'] try: if int(frame.properties['centered']): ret.append('$self->Centre();\n') except (KeyError, ValueError): pass plgen = common.code_writers['perl'] if frame.properties.get('size', '').strip() and \ plgen.for_version < (2, 8): ret.append(plgen.generate_code_size(frame)) return ret # end of class PerlFrameCodeGenerator class PerlMDIChildFrameCodeGenerator(PerlFrameCodeGenerator): extra_headers = ['Wx::MDI'] #wxMDIChildFrame(parent, id, title, pos, size, style, name ) # end of class PerlMDIChildFrameCodeGenerator def initialize(): cn = common.class_names cn['EditFrame'] = 'wxFrame' cn['EditMDIChildFrame'] = 'wxMDIChildFrame' cn['EditStatusBar'] = 'wxStatusBar' common.toplevels['EditFrame'] = 1 common.toplevels['EditMDIChildFrame'] = 1 plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxFrame', PerlFrameCodeGenerator()) plgen.add_widget_handler('wxMDIChildFrame', PerlMDIChildFrameCodeGenerator()) plgen.add_widget_handler('wxStatusBar', PerlStatusBarCodeGenerator()) plgen.add_property_handler('fields', StatusFieldsHandler) plgen.add_property_handler('menubar', plgen.DummyPropertyHandler) plgen.add_property_handler('statusbar', plgen.DummyPropertyHandler) wxglade-0.6.8.orig/widgets/frame/frame.py0000644000175000017500000005320412161625061020525 0ustar georgeskgeorgesk# frame.py: wxFrame and wxStatusBar objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, math, misc from tree import Tree #from MenuTree import * from widget_properties import * from edit_windows import EditBase, TopLevelBase class EditStatusBar(EditBase): _hidden_frame = None def __init__(self, parent, property_window): EditBase.__init__(self, parent.name + '_statusbar', 'wxStatusBar', parent, id, property_window, custom_class=False, show=False) # style property self.style_pos = (wx.ST_SIZEGRIP,) style_labels = ('#section#' + _('Style'), 'wxST_SIZEGRIP') self.access_functions['style'] = (self.get_style, self.set_style) self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) self.node = Tree.Node(self) common.app_tree.add(self.node, parent.node) self.fields = [ [self.name, "-1"] ] # list of 2-lists label, size # for the statusbar fields self.access_functions['fields'] = (self.get_fields, self.set_fields) prop = self.properties['fields'] = GridProperty( self, 'fields', None, [("Text", GridProperty.STRING), ("Size", GridProperty.INT)]) # replace the default 'write' method of 'prop' with a custom one def write_prop(outfile, tabs): from xml.sax.saxutils import escape, quoteattr fwrite = outfile.write fwrite(' ' * tabs + '\n') tabs += 1 import widget_properties for label, width in self.fields: fwrite(' ' * tabs + '%s\n' % (quoteattr(width), escape(widget_properties._encode(label)))) tabs -= 1 fwrite(' ' * tabs + '\n') prop.write = write_prop def create_widget(self): self.widget = wx.StatusBar(self.parent.widget, wx.NewId()) wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) self.set_fields(self.fields) if self.parent.widget: self.parent.widget.SetStatusBar(self.widget) def create_properties(self): EditBase.create_properties(self) page = self._common_panel self.properties['style'].display(page) prop = self.properties['fields'] prop.display(page) sizer = page.GetSizer() if not sizer: sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.name_prop.panel, 0, wx.EXPAND) sizer.Add(self.klass_prop.panel, 0, wx.EXPAND) page.SetAutoLayout(1) page.SetSizer(sizer) sizer.Add(self.properties['style'].panel, 0, wx.EXPAND) sizer.Add(prop.panel, 1, wx.ALL|wx.EXPAND, 3) sizer.Fit(page) page.SetSize(self.notebook.GetClientSize()) sizer.Layout() self.notebook.AddPage(page, _("Common")) self.property_window.Layout() prop.set_col_sizes([190, 0]) def set_fields(self, values): # values is a list of lists self.fields = [] if self.widget: self.widget.SetFieldsCount(len(values)) for i in range(len(values)): try: v = int(values[i][1]) except: v = 0 s = misc.wxstr(values[i][0]) self.fields.append([s, str(v)]) if self.widget: self.widget.SetStatusText(s, i) if self.widget: self.widget.SetStatusWidths([int(i[1]) for i in self.fields]) def get_fields(self): return self.fields def __getitem__(self, key): return self.access_functions[key] def remove(self, *args, **kwds): if not kwds.get('do_nothing', False): if self.parent.widget: self.parent.widget.SetStatusBar(None) try: self.parent.properties['statusbar'].set_value(0) except KeyError: pass if self.widget: self.widget.Hide() EditBase.remove(self) else: if EditStatusBar._hidden_frame is None: EditStatusBar._hidden_frame = wx.Frame(None, -1, "") if self.widget is not None: self.widget.Reparent(EditStatusBar._hidden_frame) self.widget = None def popup_menu(self, *args): pass # to avoid strange segfault :) def get_property_handler(self, name): class FieldsHandler: """\ custom Property handler for statusbar fields. """ def __init__(self, owner): self.owner = owner self.width = -1 self.value = [] def start_elem(self, name, attrs): if name == 'fields': self.fields = [] else: # name == 'field' self.value = [] self.width = attrs.get('width', '-1') def end_elem(self, name): if name == 'field': self.fields.append(["".join(self.value), self.width]) else: # name == 'fields' self.owner.fields = self.fields self.owner.set_fields(self.owner.fields) self.owner.properties['fields'].set_value( self.owner.fields) return True def char_data(self, data): self.value.append(data) return False # tell there's no need to go further # (i.e. to call add_property) if name == 'fields': return FieldsHandler(self) return None def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] # end of class EditStatusBar class EditFrame(TopLevelBase): def __init__(self, name, parent, id, title, property_window, style=wx.DEFAULT_FRAME_STYLE, show=True, klass='wxFrame'): TopLevelBase.__init__(self, name, klass, parent, id, property_window, show=show, title=title) self.base = 'wxFrame' self.style = style self.statusbar = None self.icon = '' self.access_functions['statusbar'] = (self.get_statusbar, self.set_statusbar) self.menubar = None self.access_functions['menubar'] = (self.get_menubar, self.set_menubar) self.toolbar = None self.access_functions['toolbar'] = (self.get_toolbar, self.set_toolbar) self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['icon'] = (self.get_icon, self.set_icon) prop = self.properties style_labels = ['#section#' + _('Style'), 'wxDEFAULT_FRAME_STYLE', 'wxICONIZE', 'wxCAPTION', 'wxMINIMIZE', 'wxMINIMIZE_BOX', 'wxMAXIMIZE', 'wxMAXIMIZE_BOX', 'wxSTAY_ON_TOP', 'wxSYSTEM_MENU', 'wxSIMPLE_BORDER', 'wxRESIZE_BORDER', 'wxFRAME_TOOL_WINDOW', 'wxFRAME_NO_TASKBAR', 'wxFRAME_FLOAT_ON_PARENT', 'wxNO_BORDER', 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] self.style_pos = [wx.DEFAULT_FRAME_STYLE, wx.ICONIZE, wx.CAPTION, wx.MINIMIZE, wx.MINIMIZE_BOX, wx.MAXIMIZE, wx.MAXIMIZE_BOX, wx.STAY_ON_TOP, wx.SYSTEM_MENU, wx.SIMPLE_BORDER, wx.RESIZE_BORDER, wx.FRAME_TOOL_WINDOW, wx.FRAME_NO_TASKBAR, wx.FRAME_FLOAT_ON_PARENT, wx.NO_BORDER, wx.NO_FULL_REPAINT_ON_RESIZE, wx.FULL_REPAINT_ON_RESIZE, wx.TAB_TRAVERSAL, wx.CLIP_CHILDREN] style_labels.insert(5, 'wxCLOSE_BOX') self.style_pos.insert(4, wx.CLOSE_BOX) prop['style'] = CheckListProperty(self, 'style', None, style_labels) # menubar property prop['menubar'] = CheckBoxProperty(self, 'menubar', None, _('Has MenuBar')) # statusbar property prop['statusbar'] = CheckBoxProperty(self, 'statusbar', None, _('Has StatusBar')) # toolbar property prop['toolbar'] = CheckBoxProperty(self, 'toolbar', None, _('Has ToolBar')) # icon property prop['icon'] = FileDialogProperty(self, 'icon', None, style=wx.OPEN|wx.FILE_MUST_EXIST, can_disable=True, label=_("icon")) # centered property self.centered = False self.access_functions['centered'] = (self.get_centered, self.set_centered) prop['centered'] = CheckBoxProperty(self, 'centered', None, label=_("centered")) # size hints property self.sizehints = False self.access_functions['sizehints'] = (self.get_sizehints, self.set_sizehints) prop['sizehints'] = CheckBoxProperty(self, 'sizehints', None, label=_('Set Size Hints')) def create_widget(self): if self.parent: w = self.parent.widget else: w = common.palette self.widget = wx.Frame(w, self.id, self.get_title()) self.set_icon(self.icon) def finish_widget_creation(self): TopLevelBase.finish_widget_creation(self) if not self.properties['size'].is_active(): #if self.sizer: self.sizer.fit_parent() #else: self.widget.SetSize((400, 300)) if wx.Platform == '__WXMSW__': self.widget.CenterOnScreen() if self.menubar and self.menubar.widget: self.widget.SetMenuBar(self.menubar.widget) if self.statusbar and self.statusbar.widget: self.widget.SetStatusBar(self.statusbar.widget) if self.toolbar and self.toolbar.widget: self.widget.SetToolBar(self.toolbar.widget) def create_properties(self): TopLevelBase.create_properties(self) prop = self.properties panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) prop['title'].display(panel) prop['icon'].display(panel) prop['centered'].display(panel) prop['sizehints'].display(panel) prop['menubar'].display(panel) prop['toolbar'].display(panel) try: sbprop = prop['statusbar'] sbprop.display(panel) except KeyError: sbprop = None prop['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop['title'].panel, 0, wx.EXPAND) szr.Add(prop['icon'].panel, 0, wx.EXPAND) szr.Add(prop['centered'].panel, 0, wx.EXPAND) szr.Add(prop['sizehints'].panel, 0, wx.EXPAND) szr.Add(prop['menubar'].panel, 0, wx.EXPAND) szr.Add(prop['toolbar'].panel, 0, wx.EXPAND) if sbprop: szr.Add(sbprop.panel, 0, wx.EXPAND) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') w, h = panel.GetClientSizeTuple() panel.SetScrollbars(5, 5, int(math.ceil(w/5.0)), int(math.ceil(h/5.0))) def get_menubar(self): return self.menubar is not None def set_menubar(self, value): if value: from menubar import EditMenuBar self.menubar = EditMenuBar(self.name + '_menubar', 'wxMenuBar', self, common.property_panel) self.menubar.node = Tree.Node(self.menubar) common.app_tree.add(self.menubar.node, self.node) if self.widget: self.menubar.show_widget(True) self.menubar.show_properties() else: self.menubar = self.menubar.remove() self.show_properties(None) def get_statusbar(self): return self.statusbar is not None def set_statusbar(self, value): if value: self.statusbar = EditStatusBar(self, common.property_panel) if self.widget: self.statusbar.show_widget(True) self.statusbar.show_properties() else: self.statusbar = self.statusbar.remove() self.show_properties(None) if self.widget: # this is needed at least on win32 wx.PostEvent(self.widget, wx.SizeEvent(self.widget.GetSize(), self.widget.GetId())) def get_toolbar(self): return self.toolbar is not None def set_toolbar(self, value): if value: from toolbar import EditToolBar self.toolbar = EditToolBar(self.name + '_toolbar', 'wxToolBar', self, common.property_panel) self.toolbar.node = Tree.Node(self.toolbar) common.app_tree.add(self.toolbar.node, self.node) if self.widget: self.toolbar.show_widget(True) self.toolbar.show_properties() else: self.toolbar = self.toolbar.remove() self.show_properties(None) def get_style(self): retval = [0] * len(self.style_pos) try: if self.style == wx.DEFAULT_FRAME_STYLE: retval[0] = 1 else: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 retval[0] = 0 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) style = 0 for v in range(len(value)): if value[v]: style |= self.style_pos[v] self.style = style if self.widget: self.widget.SetWindowStyleFlag(style) def remove(self, *args): if self.menubar: self.menubar = self.menubar.remove(gtk_do_nothing=True) if self.statusbar: self.statusbar = self.statusbar.remove(do_nothing=True) if self.toolbar: self.toolbar = self.toolbar.remove(do_nothing=True) TopLevelBase.remove(self, *args) def get_icon(self): # is a string that holds the filename (for example: icon.png) return self.icon def set_icon(self, value): self.icon = value.strip() if self.widget: if self.icon and not (self.icon.startswith('var:') or self.icon.startswith('code:')): # setting icon icon = misc.get_relative_path(self.icon) bmp = wx.Bitmap(icon, wx.BITMAP_TYPE_ANY) if not bmp.Ok(): self.set_icon("") else: icon = wx.EmptyIcon() icon.CopyFromBitmap(bmp) self.widget.SetIcon(icon) else: # removing icon icon = wx.EmptyIcon() import os xpm = os.path.join(common.icons_path, 'frame.xpm') icon.CopyFromBitmap(misc.get_xpm_bitmap(xpm)) self.widget.SetIcon(icon) def get_centered(self): return self.centered def set_centered(self, value): try: self.centered = bool(int(value)) except ValueError: pass def get_sizehints(self): return self.sizehints def set_sizehints(self, value): try: self.sizehints = bool(int(value)) except ValueError: pass # end of class EditFrame class EditMDIChildFrame(EditFrame): _is_toplevel = False # used to avoid to appear in the "Top Window" property # of the app def __init__(self, *args, **kwds): EditFrame.__init__(self, *args, **kwds) del self.properties['statusbar'] self.base = 'wxFrame' # end of class EditMDIChildFrame def builder(parent, sizer, pos, number=[0]): """\ factory function for EditFrame objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, _('Select frame class')) if common.app_tree.app.get_language().lower() == 'xrc': self.klass = 'wxFrame' else: if not number[0]: self.klass = 'MyFrame' else: self.klass = 'MyFrame%s' % number[0] number[0] += 1 self.base = 0 base_prop = RadioProperty(self, 'base class', self, ['wxFrame', 'wxMDIChildFrame'], label=_("base class")) klass_prop = TextProperty(self, 'class', self, label=_("class")) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(base_prop.panel, 0, wx.ALL|wx.EXPAND, 5) szr.Add(klass_prop.panel, 0, wx.EXPAND) btnbox = wx.BoxSizer(wx.HORIZONTAL) btnOK = wx.Button(self, wx.ID_OK, _('OK')) btnCANCEL = wx.Button(self, wx.ID_CANCEL, _('Cancel')) btnbox.Add(btnOK, 0, wx.ALL, 3) btnbox.Add(btnCANCEL, 0, wx.ALL, 3) btnOK.SetFocus() szr.Add(btnbox, 0, wx.ALL|wx.ALIGN_CENTER, 3) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def undo(self): if number[0] > 0: number[0] -= 1 def __getitem__(self, value): if value == 'class': def set_klass(c): self.klass = c return (lambda : self.klass, set_klass) else: def set_base(b): self.base = b return (lambda : self.base, set_base) # end of inner class dialog = Dialog() # Check if the user hit Cancel, if so then bail out if dialog.ShowModal() == wx.ID_CANCEL: # restore state dialog.undo() # clean up resources dialog.Destroy() return label = 'frame_%d' % (number[0] or 1) while common.app_tree.has_name(label): number[0] += 1 label = 'frame_%d' % number[0] if dialog.base == 0: base_class = EditFrame else: base_class = EditMDIChildFrame frame = base_class(label, parent, wx.NewId(), label, common.property_panel, klass=dialog.klass) node = Tree.Node(frame) frame.node = node common.app_tree.add(node) frame.show_widget(True) # add a default vertical sizer to the frame import edit_sizers edit_sizers._builder(frame, None, 0) # now select the frame's node in the tree common.app_tree.select_item(node) dialog.Destroy() if wx.Platform == '__WXMSW__': #frame.widget.CenterOnScreen() frame.widget.Raise() def _make_builder(base_class): def xml_builder(attrs, parent, sizer, sizeritem, pos=None): from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") frame = base_class(label, parent, wx.NewId(), "", common.property_panel, show=False, style=0) node = Tree.Node(frame) frame.node = node common.app_tree.add(node) return frame return xml_builder ## def xml_builder(attrs, parent, sizer, sizeritem, pos=None): ## """\ ## factory to build EditFrame objects from an xml file ## """ ## from xml_parse import XmlParsingError ## try: label = attrs['name'] ## except KeyError: raise XmlParsingError, _("'name' attribute missing") ## frame = EditFrame(label, parent, wx.NewId(), label, common.property_panel, ## show=False) ## node = Tree.Node(frame) ## frame.node = node ## common.app_tree.add(node) ## return frame def statusbar_xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditStatusBar objects from an xml file """ parent.statusbar.set_fields([]) name = attrs.get('name') if name: parent.statusbar.set_name(name) parent.statusbar.name_prop.set_value(name) return parent.statusbar def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ cwx = common.widgets_from_xml cwx['EditStatusBar'] = statusbar_xml_builder cwx['EditFrame'] = _make_builder(EditFrame) cwx['EditMDIChildFrame'] = _make_builder(EditMDIChildFrame) common.widgets['EditFrame'] = builder # add statusbar icon to WidgetTree from tree import WidgetTree import os.path WidgetTree.images['EditStatusBar'] = os.path.join( common.icons_path, 'statusbar.xpm' ) WidgetTree.images['EditMDIChildFrame'] = os.path.join( common.icons_path, 'frame.xpm' ) return common.make_object_button('EditFrame', 'icons/frame.xpm', 1) wxglade-0.6.8.orig/widgets/frame/lisp_codegen.py0000644000175000017500000000717112150154266022072 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxFrame objects # $Id: lisp_codegen.py,v 1.3 2007/03/27 07:02:00 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from MenuTree import * from codegen import StatusFieldsHandler class LispStatusBarCodeGenerator: def get_code(self, obj): """\ function that generates code for the statusbar of a wxFrame. """ lispgen = common.code_writers['lisp'] labels, widths = obj.properties['statusbar'] style = obj.properties.get("style") if not style: style = '0' init = [ '(setf (slot-%s obj) (wxFrame_CreateStatusBar (slot-top-window obj) %s %s))\n' % (obj.name, len(labels), style) ] props = [] append = props.append append('(wxStatusBar_SetStatusWidths (slot-%s obj) %s (vector %s))\n' % (obj.name, len(widths),' '.join(map(str, widths)))) i = 0 for l in labels: append('\t (wxStatusBar_SetStatusText (slot-%s obj) %s %s)\n' % (obj.name, lispgen.quote_str(l),i) ) i=i+1 return init, props, [] # end of class LispStatusBarCodeGenerator class LispFrameCodeGenerator: #wxFrame( parent, id, title, pos , size , style , name ) new_signature = [ '$parent', '$id', '$title', '$pos', '$size', '$style', '$name' ] def get_code(self, obj): return [], [], [], [] # the frame can't be a children def get_properties_code(self, frame): """\ generates the code for the various wxFrame specific properties. Returns a list of strings containing the generated code """ prop = frame.properties lispgen = common.code_writers['lisp'] out = [] title = prop.get('title') if title: out.append('(wxFrame_SetTitle (slot-top-window obj) %s)\n' % \ lispgen.quote_str(title)) icon = prop.get('icon') if icon: out.append( ';;; generating code for setting icons is not implemented\n' ) out.extend(lispgen.generate_common_properties(frame)) return out def get_layout_code(self, frame): ret = ['(wxFrame_layout (slot-%s slef))\n' % frame.name] try: if int(frame.properties['centered']): ret.append('(wxFrame_Centre (slot-top-window obj) wxBOTH)\n') except (KeyError, ValueError): pass return ret # end of class LispFrameCodeGenerator class LispMDIChildFrameCodeGenerator(LispFrameCodeGenerator): extra_headers = ['Wx::MDI'] #wxMDIChildFrame(parent, id, title, pos, size, style, name ) # end of class LispMDIChildFrameCodeGenerator def initialize(): cn = common.class_names cn['EditFrame'] = 'wxFrame' cn['EditMDIChildFrame'] = 'wxMDIChildFrame' cn['EditStatusBar'] = 'wxStatusBar' common.toplevels['EditFrame'] = 1 common.toplevels['EditMDIChildFrame'] = 1 lispgen = common.code_writers.get('lisp') if lispgen: lispgen.add_widget_handler('wxFrame', LispFrameCodeGenerator()) lispgen.add_widget_handler('wxMDIChildFrame', LispMDIChildFrameCodeGenerator()) lispgen.add_widget_handler('wxStatusBar', LispStatusBarCodeGenerator()) lispgen.add_property_handler('fields', StatusFieldsHandler) lispgen.add_property_handler('menubar', lispgen.DummyPropertyHandler) lispgen.add_property_handler('statusbar', lispgen.DummyPropertyHandler) wxglade-0.6.8.orig/widgets/frame/codegen.py0000644000175000017500000002541611621715605021047 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxFrame objects # $Id: codegen.py,v 1.24 2007/03/27 07:02:00 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from MenuTree import * class PythonStatusbarCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] labels, widths = obj.properties['statusbar'] style = obj.properties.get("style") if style: style = pygen.cn_f(style) else: style = '0' init = [ 'self.%s = self.CreateStatusBar(%s, %s)\n' % \ (obj.name, len(labels), style) ] props = [] append = props.append append('self.%s.SetStatusWidths(%s)\n' % (obj.name, repr(widths))) append('# statusbar fields\n') append('%s_fields = [%s]\n' % \ (obj.name, ', '.join([pygen.quote_str(l) for l in labels]))) append('for i in range(len(%s_fields)):\n' % obj.name) append(' self.%s.SetStatusText(%s_fields[i], i)\n' % \ (obj.name, obj.name)) return init, props, [] # end of class PythonStatusbarCodeGenerator class PythonFrameCodeGenerator: def get_code(self, obj): return [], [], [] def get_properties_code(self, frame): prop = frame.properties pygen = common.code_writers['python'] cn = pygen.cn out = [] title = prop.get('title') if title: out.append('self.SetTitle(%s)\n' % pygen.quote_str(title)) icon = prop.get('icon') if icon: if icon.startswith('var:'): if not frame.preview: out.append('_icon = ' + cn('wxEmptyIcon') + '()\n') out.append(('_icon.CopyFromBitmap(' + cn('wxBitmap') + '(%s, ' + cn('wxBITMAP_TYPE_ANY') + '))\n') % \ icon[4:].strip()) out.append('self.SetIcon(_icon)\n') elif icon.startswith('code:'): if not frame.preview: out.append('_icon = ' + cn('wxEmptyIcon') + '()\n') out.append(('_icon.CopyFromBitmap(%s)\n') % \ icon[5:].strip()) out.append('self.SetIcon(_icon)\n') else: if frame.preview: import misc icon = misc.get_relative_path(icon, True) out.append('_icon = ' + cn('wxEmptyIcon') + '()\n') out.append(('_icon.CopyFromBitmap(' + cn('wxBitmap') + '(%s, ' + cn('wxBITMAP_TYPE_ANY') + '))\n') % \ pygen.quote_str(icon, False, False)) out.append('self.SetIcon(_icon)\n') out.extend(pygen.generate_common_properties(frame)) return out def get_layout_code(self, frame): ret = ['self.Layout()\n'] try: if int(frame.properties['centered']): ret.append('self.Centre()\n') except (KeyError, ValueError): pass pygen = common.code_writers['python'] if frame.properties.get('size', '').strip() and \ pygen.for_version < (2, 8): ret.append(pygen.generate_code_size(frame)) return ret # end of class PythonFrameCodeGenerator # property handlers for code generation class StatusFieldsHandler: """Handler for statusbar fields""" def __init__(self): self.labels = [] self.widths = [] self.curr_label = [] def start_elem(self, name, attrs): if name == 'field': self.widths.append(int(attrs.get('width', -1))) def end_elem(self, name, code_obj): if name == 'fields': code_obj.properties['statusbar'] = (self.labels, self.widths) return True self.labels.append("".join(self.curr_label)) self.curr_label = [] def char_data(self, data): self.curr_label.append(data) # end of class StatusFieldsHandler def xrc_frame_code_generator(obj): xrcgen = common.code_writers['XRC'] class FrameXrcObject(xrcgen.DefaultXrcObject): def write(self, outfile, tabs): if 'menubar' in self.properties: del self.properties['menubar'] if 'statusbar' in self.properties: del self.properties['statusbar'] if 'toolbar' in self.properties: del self.properties['toolbar'] xrcgen.DefaultXrcObject.write(self, outfile, tabs) def write_property(self, name, val, outfile, ntabs): if name != 'sizehints': xrcgen.DefaultXrcObject.write_property( self, name, val, outfile, ntabs) # end of class FrameXrcObject return FrameXrcObject(obj) def xrc_statusbar_code_generator(obj): xrcgen = common.code_writers['XRC'] class StatusbarXrcObject(xrcgen.DefaultXrcObject): def write(self, outfile, tabs): if 'statusbar' in self.properties: fields, widths = self.properties['statusbar'] self.properties['fields'] = str(len(fields)) self.properties['widths'] = ', '.join([str(w) for w in widths]) del self.properties['statusbar'] xrcgen.DefaultXrcObject.write(self, outfile, tabs) # end of class StatusbarXrcObject return StatusbarXrcObject(obj) class CppStatusBarCodeGenerator: def get_code(self, obj): """\ function that generates code for the statusbar of a wxFrame. """ cppgen = common.code_writers['C++'] labels, widths = obj.properties['statusbar'] style = obj.properties.get("style") if not style: style = '0' init = [ '%s = CreateStatusBar(%s, %s);\n' % (obj.name, len(labels), style) ] props = [] append = props.append append('int %s_widths[] = { %s };\n' % (obj.name, ', '.join(map(str, widths)))) append('%s->SetStatusWidths(%s, %s_widths);\n' % \ (obj.name, len(widths), obj.name)) labels = ',\n '.join([cppgen.quote_str(l) for l in labels]) append('const wxString %s_fields[] = {\n %s\n };\n' % (obj.name, labels)) append('for(int i = 0; i < %s->GetFieldsCount(); ++i) {\n' % obj.name) append(' %s->SetStatusText(%s_fields[i], i);\n }\n' % \ (obj.name, obj.name)) return init, [], props, [] # end of class CppStatusBarCodeGenerator class CppFrameCodeGenerator: constructor = [('wxWindow*', 'parent'), ('int', 'id'), ('const wxString&', 'title'), ('const wxPoint&', 'pos', 'wxDefaultPosition'), ('const wxSize&', 'size', 'wxDefaultSize'), ('long', 'style', 'wxDEFAULT_FRAME_STYLE')] def get_code(self, obj): return [], [], [], [] # the frame can't be a children def get_properties_code(self, frame): """\ generates the code for the various wxFrame specific properties. Returns a list of strings containing the generated code """ prop = frame.properties cppgen = common.code_writers['C++'] out = [] title = prop.get('title') if title: out.append('SetTitle(%s);\n' % cppgen.quote_str(title)) icon = prop.get('icon') if icon: out.append('wxIcon _icon;\n') if icon.startswith('var:'): out.append('_icon.CopyFromBitmap(wxBitmap(' + '%s, wxBITMAP_TYPE_ANY));\n' % \ icon[4:].strip()) elif icon.startswith('code:'): out.append('_icon.CopyFromBitmap(%s);\n' % \ icon[5:].strip()) else: out.append('_icon.CopyFromBitmap(wxBitmap(%s, ' 'wxBITMAP_TYPE_ANY));\n' % \ cppgen.quote_str(icon, False, False)) out.append('SetIcon(_icon);\n') out.extend(cppgen.generate_common_properties(frame)) return out def get_layout_code(self, frame): ret = ['Layout();\n'] try: if int(frame.properties['centered']): ret.append('Centre();\n') except (KeyError, ValueError): pass cppgen = common.code_writers['C++'] if frame.properties.get('size', '').strip() and \ cppgen.for_version < (2, 8): ret.append(cppgen.generate_code_size(frame)) return ret # end of class CppFrameCodeGenerator class CppMDIChildFrameCodeGenerator(CppFrameCodeGenerator): extra_headers = [''] constructor = [('wxMDIParentFrame*', 'parent'), ('int', 'id'), ('const wxString&', 'title'), ('const wxPoint&', 'pos', 'wxDefaultPosition'), ('const wxSize&', 'size', 'wxDefaultSize'), ('long', 'style', 'wxDEFAULT_FRAME_STYLE')] # end of class CppMDIChildFrameCodeGenerator def initialize(): cn = common.class_names cn['EditFrame'] = 'wxFrame' cn['EditMDIChildFrame'] = 'wxMDIChildFrame' cn['EditStatusBar'] = 'wxStatusBar' common.toplevels['EditFrame'] = 1 common.toplevels['EditMDIChildFrame'] = 1 pygen = common.code_writers.get('python') if pygen: awh = pygen.add_widget_handler awh('wxFrame', PythonFrameCodeGenerator()) awh('wxMDIChildFrame', PythonFrameCodeGenerator()) awh('wxStatusBar', PythonStatusbarCodeGenerator()) aph = pygen.add_property_handler aph('statusbar', pygen.DummyPropertyHandler) aph('fields', StatusFieldsHandler) aph('menubar', pygen.DummyPropertyHandler) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxFrame', xrc_frame_code_generator) xrcgen.add_widget_handler('wxMDIChildFrame', xrcgen.NotImplementedXrcObject) xrcgen.add_widget_handler('wxStatusBar', xrc_statusbar_code_generator) #xrcgen.NotImplementedXrcObject) xrcgen.add_property_handler('fields', StatusFieldsHandler) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxFrame', CppFrameCodeGenerator()) cppgen.add_widget_handler('wxMDIChildFrame', CppMDIChildFrameCodeGenerator()) cppgen.add_widget_handler('wxStatusBar', CppStatusBarCodeGenerator()) cppgen.add_property_handler('fields', StatusFieldsHandler) cppgen.add_property_handler('menubar', cppgen.DummyPropertyHandler) cppgen.add_property_handler('statusbar', cppgen.DummyPropertyHandler) wxglade-0.6.8.orig/widgets/frame/__init__.py0000644000175000017500000000064112060624724021172 0ustar georgeskgeorgesk# __init__.py: frame widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:02:00 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import frame return frame.initialize() wxglade-0.6.8.orig/widgets/tree_ctrl/0000755000175000017500000000000012170277707017760 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/tree_ctrl/perl_codegen.py0000644000175000017500000000261511646104623022755 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxTreeCtrl objects # $Id: perl_codegen.py,v 1.4 2005/08/15 08:04:00 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not( style and style != 'wxLI_HORIZONTAL' ): # default style style = '' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, style)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditTreeCtrl'] = 'wxTreeCtrl' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxTreeCtrl', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/tree_ctrl/lisp_codegen.py0000644000175000017500000000251112150154266022754 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxTreeCtrl objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:39:48 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '(object-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not( style and style != 'wxLI_HORIZONTAL' ): # default style style = '' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxTreeCtrl_Create %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, style)) props_buf = codegen.generate_common_properties(obj) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditTreeCtrl'] = 'wxTreeCtrl' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxTreeCtrl', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/tree_ctrl/tree_ctrl.py0000644000175000017500000001553111677432100022311 0ustar georgeskgeorgesk# text_ctrl.py: wxTreeCtrl objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx from edit_windows import ManagedBase from tree import Tree import common from widget_properties import * class EditTreeCtrl(ManagedBase): """\ Class to handle wx.TreeCtrl objects """ events = [ 'EVT_TREE_BEGIN_DRAG', 'EVT_TREE_BEGIN_RDRAG', 'EVT_TREE_END_DRAG', 'EVT_TREE_END_RDRAG', 'EVT_TREE_BEGIN_LABEL_EDIT', 'EVT_TREE_END_LABEL_EDIT', 'EVT_TREE_DELETE_ITEM', 'EVT_TREE_GET_INFO', 'EVT_TREE_SET_INFO', 'EVT_TREE_ITEM_ACTIVATED', 'EVT_TREE_ITEM_COLLAPSED', 'EVT_TREE_ITEM_COLLAPSING', 'EVT_TREE_ITEM_EXPANDED', 'EVT_TREE_ITEM_EXPANDING', 'EVT_TREE_SEL_CHANGED', 'EVT_TREE_SEL_CHANGING', 'EVT_TREE_KEY_DOWN', 'EVT_TREE_ITEM_GETTOOLTIP', ] def __init__(self, name, parent, id, sizer, pos, property_window, show=True, style=wx.TR_HAS_BUTTONS|wx.SUNKEN_BORDER): ManagedBase.__init__(self, name, 'wxTreeCtrl', parent, id, sizer, pos, property_window, show=show) self.style = style self.access_functions['style'] = (self.get_style, self.set_style) # style property self.style_pos = (wx.TR_HAS_BUTTONS, wx.TR_NO_LINES, wx.TR_LINES_AT_ROOT, wx.TR_EDIT_LABELS, wx.TR_MULTIPLE, wx.TR_NO_BUTTONS, wx.TR_TWIST_BUTTONS, wx.TR_FULL_ROW_HIGHLIGHT, wx.TR_HIDE_ROOT, wx.TR_ROW_LINES, wx.TR_HAS_VARIABLE_ROW_HEIGHT, wx.TR_SINGLE, wx.TR_MULTIPLE, wx.TR_EXTENDED, wx.TR_DEFAULT_STYLE, wx.SIMPLE_BORDER, wx.DOUBLE_BORDER, wx.SUNKEN_BORDER, wx.RAISED_BORDER, wx.STATIC_BORDER, wx.NO_BORDER, wx.WANTS_CHARS, wx.NO_FULL_REPAINT_ON_RESIZE, wx.FULL_REPAINT_ON_RESIZE) style_labels = ('#section#' + _('Style'), 'wxTR_HAS_BUTTONS', 'wxTR_NO_LINES', 'wxTR_LINES_AT_ROOT', 'wxTR_EDIT_LABELS', 'wxTR_MULTIPLE', 'wxTR_NO_BUTTONS', 'wxTR_TWIST_BUTTONS', 'wxTR_FULL_ROW_HIGHLIGHT', 'wxTR_HIDE_ROOT', 'wxTR_ROW_LINES', 'wxTR_HAS_VARIABLE_ROW_HEIGHT','wxTR_SINGLE', 'wxTR_MULTIPLE', 'wxTR_EXTENDED', 'wxTR_DEFAULT_STYLE', 'wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER', 'wxWANTS_CHARS', 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE') self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) self._item_with_name = None def create_widget(self): self.widget = wx.TreeCtrl(self.parent.widget, self.id, style=wx.TR_HAS_BUTTONS|wx.SUNKEN_BORDER) # add a couple of items just for a better appearence root = self.widget.AddRoot(_(' Tree Control:')) self._item_with_name = self.widget.AppendItem(root, ' ' + self.name) self.widget.AppendItem(self._item_with_name, _(' on wxGlade %s') % common.version) self.widget.Expand(root) self.widget.Expand(self._item_with_name) def finish_widget_creation(self): ManagedBase.finish_widget_creation(self, sel_marker_parent=self.widget) def set_name(self, name): ManagedBase.set_name(self, name) if self.widget and self._item_with_name: self.widget.SetItemText(self._item_with_name, ' ' + self.name) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) prop = self.properties prop['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) w, h = panel.GetClientSize() self.notebook.AddPage(panel, _('Widget')) self.property_window.Layout() import math panel.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] # end of class EditTreeCtrl def builder(parent, sizer, pos, number=[1]): """\ factory function for EditTreeCtrl objects. """ name = 'tree_ctrl_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'tree_ctrl_%d' % number[0] tree_ctrl = EditTreeCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(tree_ctrl) tree_ctrl.node = node tree_ctrl.set_option(1) tree_ctrl.set_flag("wxEXPAND") tree_ctrl.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) sizer.set_item(tree_ctrl.pos, 1, wx.EXPAND) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory function to build EditTreeCtrl objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, "'name' attribute missing" if sizer is None or sizeritem is None: raise XmlParsingError, "sizer or sizeritem object cannot be None" tree_ctrl = EditTreeCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel, style=0) sizer.set_item(tree_ctrl.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(tree_ctrl) tree_ctrl.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return tree_ctrl def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditTreeCtrl'] = builder common.widgets_from_xml['EditTreeCtrl'] = xml_builder return common.make_object_button('EditTreeCtrl', 'icons/tree_ctrl.xpm') wxglade-0.6.8.orig/widgets/tree_ctrl/codegen.py0000644000175000017500000000465012072605532021733 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxTreeCtrl objects # $Id: codegen.py,v 1.8 2007/03/27 07:01:50 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style and style != 'wxTR_HAS_BUTTONS': # default style style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s%s)\n' % (obj.name, klass, parent, id, style)) props_buf = pygen.generate_common_properties(obj) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ generates C++ code for wxTreeCtrl objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get('style') if style and style != 'wxTR_HAS_BUTTONS': extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s%s);\n' % (obj.name, obj.klass, parent, id, extra)] props_buf = cppgen.generate_common_properties(obj) return init, ids, props_buf, [] def get_events(self, obj): cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxTreeEvent') # end of class CppCodeGenerator def initialize(): common.class_names['EditTreeCtrl'] = 'wxTreeCtrl' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxTreeCtrl', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxTreeCtrl', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/tree_ctrl/__init__.py0000644000175000017500000000065511621715605022071 0ustar georgeskgeorgesk# __init__.py: tree ctrl widget module initialization # $Id: __init__.py,v 1.5 2007/03/27 07:01:50 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import tree_ctrl return tree_ctrl.initialize() wxglade-0.6.8.orig/widgets/combo_box/0000755000175000017500000000000012170277707017744 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/combo_box/perl_codegen.py0000644000175000017500000000353711646103554022747 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxComboBox objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:36:35 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style", None) if not style: style = 'wxCB_DROPDOWN' else: style = 'wxCB_DROPDOWN|' + style if id_name: init.append(id_name) choices = ', '.join([plgen.quote_str(c) for c in choices]) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, "", wxDefaultPosition, \ wxDefaultSize, [%s], %s);\n' % (obj.name, klass, parent, id, choices, style)) props_buf = plgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('$self->{%s}->SetSelection(%s);\n' % (obj.name, selection)) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditComboBox'] = 'wxComboBox' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxComboBox', PerlCodeGenerator()) plgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/combo_box/lisp_codegen.py0000644000175000017500000000341312150154266022742 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxComboBox objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:58:36 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '(object-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style", None) if not style: style = 'wxCB_DROPDOWN' else: style = codegen.cn_f(style) if id_name: init.append(id_name) length = len(choices) choices = ', '.join([codegen.quote_str(c) for c in choices]) init.append('(setf (slot-%s obj) (wxComboBox_Create %s %s "" -1 -1 -1 -1 %s (vector %s) %s))\n' % (obj.name, parent, id, length, choices, style)) props_buf = codegen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('(wxComboBox_SetSelection (slot-%s obj) %s)\n' % (obj.name, selection)) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditComboBox'] = 'wxComboBox' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxComboBox', LispCodeGenerator()) codegen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/combo_box/codegen.py0000644000175000017500000001007712072605532021717 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxComboBox objects # $Id: codegen.py,v 1.15 2007/03/27 07:02:02 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style", None) if not style: style = pygen.cn('wxCB_DROPDOWN') else: style = pygen.cn_f('wxCB_DROPDOWN|' + style) init = [] if id_name: init.append(id_name) choices = ', '.join([pygen.quote_str(c) for c in choices]) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, choices=[%s], style=%s)\n' % (obj.name, klass, parent, id, choices, style)) props_buf = pygen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None and len(prop.get('choices', [])): props_buf.append('self.%s.SetSelection(%s)\n' % (obj.name, selection)) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class ComboBoxXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'choices': xrc_write_choices_property(self, outfile, tabs) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class ComboBoxXrcObject return ComboBoxXrcObject(obj) class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxComboBox objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' number = len(choices) ch_arr = '{\n %s\n };\n' % \ ',\n '.join([cppgen.quote_str(c) for c in choices]) style = prop.get("style") if not style: style = 'wxCB_DROPDOWN' else: style = 'wxCB_DROPDOWN|' + style init = [] if number: init.append('const wxString %s_choices[] = %s' % (obj.name, ch_arr)) else: init.append('const wxString *%s_choices = NULL;\n' % obj.name) init.append('%s = new %s(%s, %s, wxT(""), wxDefaultPosition, ' 'wxDefaultSize, %s, %s_choices, %s);\n' % \ (obj.name, obj.klass, parent, id, number, obj.name, style)) props_buf = cppgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None and len(prop.get('choices', [])): props_buf.append('%s->SetSelection(%s);\n' % (obj.name, selection)) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditComboBox'] = 'wxComboBox' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxComboBox', PythonCodeGenerator()) pygen.add_property_handler('choices', ChoicesCodeHandler) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxComboBox', xrc_code_generator) xrcgen.add_property_handler('choices', ChoicesCodeHandler) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxComboBox', CppCodeGenerator()) cppgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/combo_box/combo_box.py0000644000175000017500000001752311700405164022261 0ustar georgeskgeorgesk# combo_box.py: wxComboBox objects # $Id: combo_box.py,v 1.28 2007/03/27 07:02:02 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * from ChoicesProperty import * if wx.Platform == '__WXMSW__': # why on Windows combo boxes give segfaults? Need to investigate, but # for now replace them with choices # this seems to be because of the style of wxPanel: if there's a # wxTAB_TRAVERSAL, we have troubles -- now it should be fixed... class wxComboBox2(wx.ComboBox): # on windows GetBestSize considers also the drop down menu, while we # don't want it to be included def GetBestSize(self): w, h = wx.ComboBox.GetBestSize(self) n = self.GetCount() return w, h/(n+1) def GetSize(self): return self.GetClientSize() else: wxComboBox2 = wx.ComboBox class EditComboBox(ManagedBase): events = ['EVT_COMBOBOX', 'EVT_TEXT', 'EVT_TEXT_ENTER'] def __init__(self, name, parent, id, choices, sizer, pos, property_window, show=True): """\ Class to handle wxComboBox objects """ import config ManagedBase.__init__(self, name, 'wxComboBox', parent, id, sizer, pos, property_window, show=show) self.choices = choices if len(choices): self.selection = 0 else: self.selection = -1 self.style = 0 # properties self.access_functions['choices'] = (self.get_choices, self.set_choices) self.access_functions['style'] = (self.get_style, self.set_style) style_labels = ('#section#' + _('Style'), 'wxCB_SIMPLE', 'wxCB_DROPDOWN', 'wxCB_READONLY', 'wxCB_SORT') self.style_pos = [ eval('wx.' + s[2:]) for s in style_labels[1:] ] self.tooltips = (_("Creates a combobox with a permanently displayed list." " Windows only."), _("Creates a combobox with a drop-down list."), _("Same as wxCB_DROPDOWN but only the strings specified " "as the combobox choices can be selected, it is " "impossible to select (even from a program) a string " "which is not in the choices list."), _("Sorts the entries in the list alphabetically.")) self.properties['style'] = CheckListProperty(self, 'style', None, style_labels, tooltips=self.tooltips) self.properties['choices'] = ChoicesProperty(self, 'choices', None, [('Label', GridProperty.STRING)], len(choices), label=_("choices")) self.access_functions['selection'] = (self.get_selection, self.set_selection) self.choices = list(choices) self.properties['selection'] = SpinProperty(self, 'selection', None, r=(0, len(choices)-1), label=_("selection")) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = wxComboBox2(self.parent.widget, self.id, choices=self.choices) self.set_selection(self.selection) wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['choices'].display(panel) self.properties['style'].display(panel) self.properties['selection'].display(panel) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) szr.Add(self.properties['selection'].panel, 0, wx.EXPAND) szr.Add(self.properties['choices'].panel, 1, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') self.properties['choices'].set_col_sizes([-1]) def get_selection(self): return self.selection def set_selection(self, value): value = int(value) if self.selection != value: self.selection = value if self.widget: self.widget.SetSelection(value) def get_choices(self): return zip(self.choices) def set_choices(self, values): self.choices = [ misc.wxstr(v[0]) for v in values ] self.properties['selection'].set_range(0, len(self.choices)-1) if self.widget: self.widget.Clear() for c in self.choices: self.widget.Append(c) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] ## if self.widget: ## self.SetWindowStyleFlag(style) def get_property_handler(self, prop_name): if prop_name == 'choices': return ChoicesHandler(self) return ManagedBase.get_property_handler(self, prop_name) # end of class EditComboBox def builder(parent, sizer, pos, number=[1]): """\ factory function for EditComboBox objects. """ name = 'combo_box_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'combo_box_%d' % number[0] choice = EditComboBox(name, parent, wx.NewId(), #[misc._encode('choice 1')], [], sizer, pos, common.property_panel) node = Tree.Node(choice) # sizer.set_item(pos, size=choice.GetBestSize()) choice.node = node choice.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditComboBox objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") choice = EditComboBox(name, parent, wx.NewId(), [], sizer, pos, common.property_panel) sizer.set_item(choice.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) ## size=choice.GetBestSize()) node = Tree.Node(choice) choice.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return choice def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditComboBox'] = builder common.widgets_from_xml['EditComboBox'] = xml_builder return common.make_object_button('EditComboBox', 'icons/combo_box.xpm') wxglade-0.6.8.orig/widgets/combo_box/__init__.py0000644000175000017500000000065511621715605022055 0ustar georgeskgeorgesk# __init__.py: combo box widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:02:02 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import combo_box return combo_box.initialize() wxglade-0.6.8.orig/widgets/gauge/0000755000175000017500000000000012170277707017065 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/gauge/perl_codegen.py0000644000175000017500000000264711646103676022076 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxGauge objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:38:14 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) g_range = prop.get('range', '10') if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, g_range, style)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditGauge'] = 'wxGauge' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxGauge', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/gauge/lisp_codegen.py0000644000175000017500000000247312150154266022070 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxGauge objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:59:38 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) g_range = prop.get('range', '10') if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxGauge_Create %s %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, g_range, style)) props_buf = codegen.generate_common_properties(obj) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditGauge'] = 'wxGauge' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxGauge', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/gauge/codegen.py0000644000175000017500000000451211725730242021036 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxGauge objects # $Id: codegen.py,v 1.10 2007/03/27 07:01:59 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) g_range = prop.get('range', '10') if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style and style != 'wxGA_HORIZONTAL': style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, %s%s)\n' % (obj.name, klass, parent, id, g_range, style)) props_buf = pygen.generate_common_properties(obj) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxGauge objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] g_range = prop.get('range', '10') if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style and style != 'wxGA_HORIZONTAL': extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s, %s%s);\n' % (obj.name, obj.klass, parent, id, g_range, extra)] props_buf = cppgen.generate_common_properties(obj) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditGauge'] = 'wxGauge' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxGauge', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxGauge', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/gauge/gauge.py0000644000175000017500000001537611677431676020553 0ustar georgeskgeorgesk# gauge.py: wxGauge objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditGauge(ManagedBase): def __init__(self, name, parent, id, style, sizer, pos, property_window, show=True): """\ Class to handle wxGauge objects """ ManagedBase.__init__(self, name, 'wxGauge', parent, id, sizer, pos, property_window, show=show) self.style = style self.range = 10 prop = self.properties self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['range'] = (self.get_range, self.set_range) style_labels = ('#section#' + _('Style'), 'wxGA_HORIZONTAL', 'wxGA_VERTICAL', 'wxGA_PROGRESSBAR', 'wxGA_SMOOTH') self.style_pos = (wx.GA_HORIZONTAL, wx.GA_VERTICAL, wx.GA_PROGRESSBAR, wx.GA_SMOOTH) self.tooltips = (_("Creates a horizontal gauge."), _("Creates a vertical gauge."), _("Under Windows 95, creates a horizontal progress bar."), _("Creates smooth progress bar with one pixel wide update step (not supported by all platforms).")) prop['style'] = CheckListProperty(self, 'style', None, style_labels, tooltips=self.tooltips) prop['range'] = SpinProperty(self, 'range', None, label=_("range")) def create_widget(self): self.widget = wx.Gauge(self.parent.widget, self.id, self.range, style=self.style) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) prop = self.properties szr = wx.BoxSizer(wx.VERTICAL) prop['range'].display(panel) prop['style'].display(panel) szr.Add(prop['range'].panel, 0, wx.EXPAND) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_range(self): return self.range def set_range(self, val): self.range = int(val) self.properties['range'].set_value(self.range) if self.widget: self.widget.SetRange(self.range) # end of class EditGauge def builder(parent, sizer, pos, number=[1]): """\ factory function for EditStaticLine objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, _('Select style')) self.orientations = [ wx.GA_HORIZONTAL, wx.GA_VERTICAL ] self.orientation = wx.GA_HORIZONTAL prop = RadioProperty(self, 'orientation', self, ['wxGA_HORIZONTAL', 'wxGA_VERTICAL'], label=_("orientation")) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop.panel, 0, wx.ALL|wx.EXPAND, 10) style_labels = ('#section#', 'wxGA_PROGRESSBAR', 'wxGA_SMOOTH') self.style_pos = (wx.GA_PROGRESSBAR, wx.GA_SMOOTH) self.style = 0 self.style_prop = CheckListProperty(self, 'style', self, style_labels) szr.Add(self.style_prop.panel, 0, wx.ALL|wx.EXPAND, 10) btn = wx.Button(self, wx.ID_OK, _('OK')) btn.SetDefault() szr.Add(btn, 0, wx.BOTTOM|wx.ALIGN_CENTER, 10) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def __getitem__(self, value): if value == 'orientation': def set_orientation(o): self.orientation = self.orientations[o] return (lambda: self.orientation, set_orientation) else: return (self.get_style, self.set_style) def get_style(self): retval = [0] * len(self.style_pos) try: style = self.style for i in range(len(self.style_pos)): if style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.style_prop.prepare_value(value) style = 0 for v in range(len(value)): if value[v]: style |= self.style_pos[v] self.style = style # end of inner class dialog = Dialog() dialog.ShowModal() label = 'gauge_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'gauge_%d' % number[0] gauge = EditGauge(label, parent, wx.NewId(), dialog.orientation | dialog.style, sizer, pos, common.property_panel) node = Tree.Node(gauge) gauge.node = node gauge.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditGauge objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") style = 0 if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") gauge = EditGauge(name, parent, wx.NewId(), style, sizer, pos, common.property_panel) sizer.set_item(gauge.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(gauge) gauge.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return gauge def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditGauge'] = builder common.widgets_from_xml['EditGauge'] = xml_builder return common.make_object_button('EditGauge', 'icons/gauge.xpm') wxglade-0.6.8.orig/widgets/gauge/__init__.py0000644000175000017500000000064111621715605021171 0ustar georgeskgeorgesk# __init__.py: gauge widget module initialization # $Id: __init__.py,v 1.6 2007/03/27 07:01:59 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import gauge return gauge.initialize() wxglade-0.6.8.orig/widgets/static_text/0000755000175000017500000000000012170277707020330 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/static_text/perl_codegen.py0000644000175000017500000000346111646104533023325 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxStaticText objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:47:30 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D. H. aka crazyinsomniac on sourceforge # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties attribute = plgen.test_attribute(obj) id_name, id = plgen.generate_code_id(obj) label = plgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' if id_name: init.append(id_name) if attribute: prefix = '$self->{%s}' % obj.name else: prefix = 'my $%s' % obj.name obj.name = '$' + obj.name klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('%s = %s->new(%s, %s, %s, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (prefix, klass, parent, id, label, style)) props_buf = plgen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditStaticText'] = 'wxStaticText' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxStaticText', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/static_text/static_text.py0000644000175000017500000001343511621715605023235 0ustar georgeskgeorgesk# static_text.py: wxStaticText objects # $Id: static_text.py,v 1.16 2007/03/27 07:01:52 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * try: import wx.lib.stattext StaticText = wx.lib.stattext.GenStaticText except ImportError: StaticText = wx.StaticText class EditStaticText(ManagedBase): def __init__(self, name, parent, id, label, sizer, pos, property_window, show=True): """\ Class to handle wxStaticText objects """ import config ManagedBase.__init__(self, name, 'wxStaticText', parent, id, sizer, pos, property_window, show=show) self.label = label self.style = 0 self.attribute = True self.access_functions['label'] = (self.get_label, self.set_label) self.access_functions['style'] = (self.get_style, self.set_style) def set_attribute(v): self.attribute = int(v) self.access_functions['attribute'] = (lambda : self.attribute, set_attribute) self.properties['label'] = TextProperty(self, 'label', None, multiline=True, label=_('label')) self.style_pos = (wx.ALIGN_LEFT, wx.ALIGN_RIGHT, wx.ALIGN_CENTRE, wx.ST_NO_AUTORESIZE) style_labels = ('#section#' + _('Style'), 'wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_CENTRE', 'wxST_NO_AUTORESIZE') self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) self.properties['attribute'] = CheckBoxProperty( self, 'attribute', None, _('Store as attribute'), write_always=True) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = StaticText(self.parent.widget, self.id, self.label.replace('\\n', '\n')) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['label'].display(panel) self.properties['style'].display(panel) self.properties['attribute'].display(panel) szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) szr.Add(self.properties['attribute'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, _('Widget')) def get_label(self): return self.label def set_label(self, value): value = misc.wxstr(value) if not misc.streq(value, self.label): self.label = value if self.widget: self.widget.SetLabel(value.replace('\\n', '\n')) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) # end of class EditStaticText def builder(parent, sizer, pos, number=[1]): """\ factory function for EditStaticText objects. """ label = 'label_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'label_%d' % number[0] static_text = EditStaticText(label, parent, wx.NewId(), misc._encode(label), sizer, pos, common.property_panel) node = Tree.Node(static_text) static_text.node = node static_text.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditStaticText objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") static_text = EditStaticText(label, parent, wx.NewId(), "", sizer, pos, common.property_panel) sizer.set_item(static_text.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) ## size=static_text.GetBestSize()) node = Tree.Node(static_text) static_text.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return static_text def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditStaticText'] = builder common.widgets_from_xml['EditStaticText'] = xml_builder return common.make_object_button('EditStaticText', 'icons/static_text.xpm') wxglade-0.6.8.orig/widgets/static_text/lisp_codegen.py0000644000175000017500000000315012150154266023324 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxStaticText objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:43:12 efuzzyone Exp $ # # Copyright (c) 2002-2004 D. H. aka crazyinsomniac on sourceforge # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties attribute = codegen.test_attribute(obj) id_name, id = codegen.generate_code_id(obj) label = codegen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxStaticText_Create %s %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, label, style)) props_buf = codegen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditStaticText'] = 'wxStaticText' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxStaticText', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/static_text/codegen.py0000644000175000017500000000643011717671216022310 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxStaticText objects # $Id: codegen.py,v 1.14 2007/03/27 07:01:52 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties attribute = pygen.test_attribute(obj) id_name, id = pygen.generate_code_id(obj) label = pygen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) if attribute: prefix = 'self.' else: prefix = '' klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('%s%s = %s(%s, %s, %s%s)\n' % (prefix, obj.name, klass, parent, id, label, style)) props_buf = pygen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxStaticText objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] attribute = cppgen.test_attribute(obj) label = cppgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style if attribute: prefix = '' else: prefix = '%s* ' % obj.klass init = ['%s%s = new %s(%s, %s, %s%s);\n' % (prefix, obj.name, obj.klass, parent, id, label, extra) ] props_buf = cppgen.generate_common_properties(obj) if not attribute: return [], ids, [], init + props_buf return init, ids, props_buf, [] # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class XrcCodeGenerator(xrcgen.DefaultXrcObject): def write(self, *args, **kwds): try: del self.properties['attribute'] except KeyError: pass xrcgen.DefaultXrcObject.write(self, *args, **kwds) return XrcCodeGenerator(obj) def initialize(): common.class_names['EditStaticText'] = 'wxStaticText' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxStaticText', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxStaticText', CppCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxStaticText', xrc_code_generator) wxglade-0.6.8.orig/widgets/static_text/__init__.py0000644000175000017500000000066311621715605022440 0ustar georgeskgeorgesk# __init__.py: static text widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:52 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import static_text return static_text.initialize() wxglade-0.6.8.orig/widgets/splitter_window/0000755000175000017500000000000012170277707021232 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/splitter_window/perl_codegen.py0000644000175000017500000000763211646104502024227 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxSplitterWindow objects # $Id: perl_codegen.py,v 1.8 2007/08/07 12:15:21 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: #wxSplitterWindow( parent, id, pos , size , style , name ) new_signature = [ '$parent', '$id', '$pos', '$size', '$style', '$name' ] def get_code(self, window): plgen = common.code_writers['perl'] prop = window.properties id_name, id = plgen.generate_code_id(window) if not window.parent.is_toplevel: parent = '$self->{%s}' % window.parent.name else: parent = '$self' if window.is_toplevel: l = [] if id_name: l.append(id_name) klass = window.base if klass != window.klass: klass = window.klass else: klass = klass.replace('wx', 'Wx::', 1) l.append('$self->{%s} = %s->new(%s, %s);\n' % (window.name, plgen.cn(klass), parent,id)) return l, [], [] style = prop.get("style") if not( style and style != 'wxSP_3D' ): # default style style = '' init = [] if id_name: init.append(id_name) init.append('$self->{%s} = %s->new(%s, %s, wxDefaultPosition, ' 'wxDefaultSize, %s);\n' % (window.name, plgen.cn(window.klass), parent, id, style)) props_buf = plgen.generate_common_properties(window) layout_buf = [] win_1 = prop.get('window_1') win_2 = prop.get('window_2') orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' layout_buf.append('$self->{%s}->%s($self->{%s}, $self->{%s}, %s);\n' % (window.name, f_name, win_1, win_2, sash_pos)) else: def add_sub(win): layout_buf.append('$self->{%s}->SetSplitMode(%s);\n' % (window.name, orientation)) layout_buf.append('$self->{%s}->Initialize($self->{%s});\n' % (window.name, win)) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return init, props_buf, layout_buf def get_layout_code(self, obj): plgen = common.code_writers['perl'] props_buf = [] prop = obj.properties orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') win_1 = prop.get('window_1') win_2 = prop.get('window_2') if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' props_buf.append('$self->%s($self->{%s}, $self->{%s}, %s);\n' % (f_name, win_1, win_2, sash_pos)) else: def add_sub(win): props_buf.append('$self->SetSplitMode(%s);\n' % orientation) props_buf.append('$self->Initialize($self->{%s});\n' % win) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return props_buf # end of class PerlCodeGenerator def initialize(): common.class_names['EditSplitterWindow'] = 'wxSplitterWindow' common.class_names['SplitterPane'] = 'wxPanel' common.toplevels['EditSplitterWindow'] = 1 common.toplevels['SplitterPane'] = 1 plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxSplitterWindow', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/splitter_window/lisp_codegen.py0000644000175000017500000000765512150154266024244 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxSplitterWindow objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 07:00:47 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: #wxSplitterWindow( parent, id, pos , size , style , name ) new_signature = [ '$parent', '$id', '$pos', '$size', '$style', '$name' ] def get_code(self, window): codegen = common.code_writers['lisp'] prop = window.properties id_name, id = codegen.generate_code_id(window) if not window.parent.is_toplevel: parent = '(slot-%s obj)' % window.parent.name else: parent = '(slot-top-window obj)' if window.is_toplevel: l = [] if id_name: l.append(id_name) l.append('(setf (slot-%s obj) (wxSplitterWindow_Create %s %s))\n' % (window.name, parent,id)) return l, [], [] style = prop.get("style") if not( style and style != 'wxSP_3D' ): # default style style = '' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxSplitterWindow_Create %s %s -1 -1 -1 -1 %s))\n' % (window.name, parent, id, style)) props_buf = codegen.generate_common_properties(window) layout_buf = [] win_1 = prop.get('window_1') win_2 = prop.get('window_2') orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' layout_buf.append('(%s %s %s %s %s)\n' % (f_name, window.name, win_1, win_2, sash_pos)) else: def add_sub(win): layout_buf.append('(wxSplitterWindow_SetSplitMode (slot-%s obj) %s)\n' % (window.name, orientation)) layout_buf.append('(wxSplitterWindow_Initialize (slot-%s obj) %s)\n' % (window.name, win)) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return init, props_buf, layout_buf def get_layout_code(self, obj): codegen = common.code_writers['lisp'] props_buf = [] prop = obj.properties orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') win_1 = prop.get('window_1') win_2 = prop.get('window_2') if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' props_buf.append('$self->%s($self->{%s}, $self->{%s}, %s);\n' % (f_name, win_1, win_2, sash_pos)) else: def add_sub(win): props_buf.append('(wxSplitterWindow_SetSplitMode (slot-%s obj) %s)\n' % (obj.name,orientation)) props_buf.append('(wxSplitterWindow_Initialize (slot-%s obj) %s)\n' % (obj.name,win)) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return props_buf # end of class LispCodeGenerator def initialize(): common.class_names['EditSplitterWindow'] = 'wxSplitterWindow' common.class_names['SplitterPane'] = 'wxPanel' common.toplevels['EditSplitterWindow'] = 1 common.toplevels['SplitterPane'] = 1 codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxSplitterWindow', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/splitter_window/codegen.py0000644000175000017500000002034711621715605023210 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxSplitterWindow objects # $Id: codegen.py,v 1.18 2007/08/07 12:15:21 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, window): pygen = common.code_writers['python'] prop = window.properties id_name, id = pygen.generate_code_id(window) if not window.parent.is_toplevel: parent = 'self.%s' % window.parent.name else: parent = 'self' if window.is_toplevel: l = [] if id_name: l.append(id_name) l.append('self.%s = %s(%s, %s)\n' % (window.name, pygen.without_package(window.klass), parent,id)) return l, [], [] style = prop.get("style") if style and style != 'wxSP_3D': style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = window.klass if window.preview: klass = 'wxSplitterWindow' init.append(('self.%s = ' + pygen.cn(klass) + '(%s, %s%s)\n') % (window.name, parent, id, style)) props_buf = pygen.generate_common_properties(window) layout_buf = [] win_1 = prop.get('window_1') win_2 = prop.get('window_2') orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if sash_pos: sash_pos = ', %s' % sash_pos if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' layout_buf.append('self.%s.%s(self.%s, self.%s%s)\n' % \ (window.name, f_name, win_1, win_2, sash_pos)) else: def add_sub(win): layout_buf.append('self.%s.SetSplitMode(%s)\n' % \ (window.name, pygen.cn(orientation))) layout_buf.append('self.%s.Initialize(self.%s)\n' % \ (window.name, win)) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return init, props_buf, layout_buf def get_layout_code(self, obj): prop = obj.properties pygen = common.code_writers['python'] win_1 = prop.get('window_1') win_2 = prop.get('window_2') orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') props_buf = [] if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if sash_pos: sash_pos = ', %s' % sash_pos if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' props_buf.append('self.%s(self.%s, self.%s%s)\n' % (f_name, win_1, win_2, sash_pos)) else: def add_sub(win): props_buf.append('self.SetSplitMode(%s)\n' % pygen.cn(orientation)) props_buf.append('self.Initialize(self.%s)\n' % win) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return props_buf # end of class PythonCodeGenerator class CppCodeGenerator: constructor = [('wxWindow*', 'parent'), ('int', 'id'), ('const wxPoint&', 'pos', 'wxDefaultPosition'), ('const wxSize&', 'size', 'wxDefaultSize'), ('long', 'style', 'wxSP_3D')] extra_headers = [''] def get_code(self, window): """\ generates the C++ code for wxSplitterWindow """ cppgen = common.code_writers['C++'] prop = window.properties id_name, id = cppgen.generate_code_id(window) if id_name: ids = [ id_name ] else: ids = [] if not window.parent.is_toplevel: parent = '%s' % window.parent.name else: parent = 'this' if window.is_toplevel: l = ['%s = new %s(%s, %s);\n' % (window.name, window.klass, parent, id)] return l, ids, [], [] extra = '' style = prop.get("style") if style and style != 'wxSP_3D': extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s%s);\n' % (window.name, window.klass, parent, id, extra) ] props_buf = cppgen.generate_common_properties(window) layout_buf = [] win_1 = prop.get('window_1') win_2 = prop.get('window_2') orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if sash_pos: sash_pos = ', %s' % sash_pos if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' layout_buf.append('%s->%s(%s, %s%s);\n' % \ (window.name, f_name, win_1, win_2, sash_pos)) else: def add_sub(win): layout_buf.append('%s->SetSplitMode(%s);\n' % (window.name, orientation)) layout_buf.append('%s->Initialize(%s);\n' % (window.name, win)) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return init, ids, props_buf, layout_buf def get_layout_code(self, obj): prop = obj.properties cppgen = common.code_writers['C++'] win_1 = prop.get('window_1') win_2 = prop.get('window_2') orientation = prop.get('orientation', 'wxSPLIT_VERTICAL') props_buf = [] if win_1 and win_2: sash_pos = prop.get('sash_pos', '') if sash_pos: sash_pos = ', %s' % sash_pos if orientation == 'wxSPLIT_VERTICAL': f_name = 'SplitVertically' else: f_name = 'SplitHorizontally' props_buf.append('%s(%s, %s%s);\n' % \ (f_name, win_1, win_2, sash_pos)) else: def add_sub(win): props_buf.append('SetSplitMode(%s);\n' % orientation) props_buf.append('Initialize(%s);\n' % win) if win_1: add_sub(win_1) elif win_2: add_sub(win_2) return props_buf def get_events(self, obj): cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxSplitterEvent') # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class XrcCodeGenerator(xrcgen.DefaultXrcObject): props_map = { 'sash_pos': 'sashpos', 'window_1': '', 'window_2': '', } orient_map = { 'wxSPLIT_VERTICAL': 'vertical', 'wxSPLIT_HORIZONTAL': 'horizontal', } def write_property(self, name, val, outfile, ntabs): try: prop = self.props_map.get(name, name) if not prop: return if prop == 'orientation': val = self.orient_map[val] xrcgen.DefaultXrcObject.write_property( self, prop, val, outfile, ntabs) except KeyError: return def write(self, *args, **kwds): if 'no_custom_class' in self.properties: del self.properties['no_custom_class'] xrcgen.DefaultXrcObject.write(self, *args, **kwds) # end of class XrcCodeGenerator return XrcCodeGenerator(obj) def initialize(): common.class_names['EditSplitterWindow'] = 'wxSplitterWindow' common.class_names['SplitterPane'] = 'wxPanel' common.toplevels['EditSplitterWindow'] = 1 common.toplevels['SplitterPane'] = 1 pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxSplitterWindow', PythonCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxSplitterWindow', xrc_code_generator)#xrcgen.NotImplementedXrcObject) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxSplitterWindow', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/splitter_window/splitter_window.py0000644000175000017500000003573511677432030025047 0ustar georgeskgeorgesk# splitter_window.py: wxSplitterWindow objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common from tree import Tree from widget_properties import * from edit_windows import ManagedBase from edit_sizers.edit_sizers import Sizer, SizerSlot class SplitterWindowSizer(Sizer): """\ "Virtual sizer" responsible for the management of a SplitterWindow. """ def set_item(self, pos, option=None, flag=None, border=None, size=None, force_layout=True): """\ Updates the layout of the item at the given pos. """ #print 'set_item' if self.window.widget and \ self.window.window_old and self.window.window_old.widget: self.window.widget.Unsplit(self.window.window_old.widget) self.window.window_old = None if self.window.window_1 and self.window.window_2: self.window.split() def add_item(self, item, pos=None, option=0, flag=0, border=0, size=None, force_layout=True): """\ Adds an item to self.window. """ #print 'add_item', item.name if pos == 1: self.window.window_old = self.window.window_1 self.window.window_1 = item self.window.properties['window_1'].set_value(item.name) else: self.window.window_old = self.window.window_2 self.window.window_2 = item self.window.properties['window_2'].set_value(item.name) def free_slot(self, pos, force_layout=True): """\ Replaces the element at pos with an empty slot """ if pos == 1: if self.window.widget and \ self.window.window_1 and self.window.window_1.widget: self.window.widget.Unsplit(self.window.window_1.widget) self.window.window_1 = SizerSlot(self.window, self, pos) w = self.window.window_1 else: if self.window.widget and \ self.window.window_2 and self.window.window_2.widget: self.window.widget.Unsplit() self.window.window_2 = SizerSlot(self.window, self, pos) w = self.window.window_2 self.window.split() w.widget.SetFocus() def get_itempos(self, attrs): """\ Get position of sizer item (used in xml_parse) """ if hasattr(self.window.properties['window_1'], 'value') and \ attrs['name'] == self.window.properties['window_1'].value: pos = 1 else: pos = 2 return pos def is_virtual(self): return True # end of class SplitterWindowSizer class EditSplitterWindow(ManagedBase): _custom_base_classes = True events = [ 'EVT_SPLITTER_SASH_POS_CHANGING', 'EVT_SPLITTER_SASH_POS_CHANGED', 'EVT_SPLITTER_UNSPLIT', 'EVT_SPLITTER_DCLICK', ] def __init__(self, name, parent, id, style, win_1, win_2, orientation, sizer, pos, property_window, show=True): """\ Class to handle wxSplitterWindow objects """ ManagedBase.__init__(self, name, 'wxSplitterWindow', parent, id, sizer, pos, property_window, show=show) self.virtual_sizer = SplitterWindowSizer(self) if style is None: style = wx.SP_3D self.style = style self.window_1 = win_1 self.window_2 = win_2 self.orientation = orientation self.sash_pos = 0 self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['sash_pos'] = (self.get_sash_pos, self.set_sash_pos) self.style_pos = (wx.SP_3D, wx.SP_3DSASH, wx.SP_3DBORDER, #wx.SP_FULLSASH, wx.SP_BORDER, wx.SP_NOBORDER, wx.SP_PERMIT_UNSPLIT, wx.SP_LIVE_UPDATE, wx.CLIP_CHILDREN) style_labels = ('#section#' + _('Style'), 'wxSP_3D', 'wxSP_3DSASH', 'wxSP_3DBORDER', #'wxSP_FULLSASH', 'wxSP_BORDER', 'wxSP_NOBORDER', 'wxSP_PERMIT_UNSPLIT', 'wxSP_LIVE_UPDATE', 'wxCLIP_CHILDREN') self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) if self.orientation == wx.SPLIT_HORIZONTAL: od = 'wxSPLIT_HORIZONTAL' else: od = 'wxSPLIT_VERTICAL' self.access_functions['orientation'] = (self.get_orientation, self.set_orientation) self.properties['orientation'] = HiddenProperty(self, 'orientation', label=_("orientation")) self.access_functions['window_1'] = (self.get_win_1, lambda v: None) self.access_functions['window_2'] = (self.get_win_2, lambda v: None) self.properties['window_1'] = HiddenProperty(self, 'window_1') self.properties['window_2'] = HiddenProperty(self, 'window_2') self.window_1 = SizerSlot(self, self.virtual_sizer, 1) self.window_2 = SizerSlot(self, self.virtual_sizer, 2) self.properties['sash_pos'] = SpinProperty(self, 'sash_pos', None, r=(0, 20), can_disable=True, label=_("sash_pos")) self.no_custom_class = False self.access_functions['no_custom_class'] = (self.get_no_custom_class, self.set_no_custom_class) self.properties['no_custom_class'] = CheckBoxProperty( self, 'no_custom_class', label=_("Don't generate code for this custom class")) def create_widget(self): self.widget = wx.SplitterWindow(self.parent.widget, self.id, style=self.style) self.split() def finish_widget_creation(self): ManagedBase.finish_widget_creation(self, sel_marker_parent=self.widget) sp = self.properties['sash_pos'] if sp.is_active(): sp.set_value(self.sash_pos) self.widget.SetSashPosition(self.sash_pos) else: sp.set_value(self.widget.GetSashPosition()) wx.EVT_SPLITTER_SASH_POS_CHANGED(self.widget, self.widget.GetId(), self.on_sash_pos_changed) def on_set_focus(self, event): self.show_properties() # here we must call event.Skip() also on Win32 as this we should be # able to move the sash event.Skip() def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) sizer = wx.BoxSizer(wx.VERTICAL) self.properties['no_custom_class'].display(panel) self.properties['style'].display(panel) self.properties['sash_pos'].display(panel) sizer.Add(self.properties['no_custom_class'].panel, 0, wx.ALL|wx.EXPAND, 3) sizer.Add(self.properties['style'].panel, 0, wx.EXPAND) sizer.Add(self.properties['sash_pos'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(sizer) sizer.Fit(panel) self.notebook.AddPage(panel, 'Widget') def split(self): if not self.widget: return if self.window_1 and self.window_2: self.window_1.show_widget(True) self.window_2.show_widget(True) sp = self.properties['sash_pos'].get_value() if not self.properties['sash_pos'].is_active(): if self.orientation == wx.SPLIT_VERTICAL: max_pos = self.widget.GetClientSize()[0] else: max_pos = self.widget.GetClientSize()[1] sp = max_pos/2 if self.orientation == wx.SPLIT_VERTICAL: self.widget.SplitVertically(self.window_1.widget, self.window_2.widget, sp) else: self.widget.SplitHorizontally(self.window_1.widget, self.window_2.widget, sp) for w in self.window_1, self.window_2: if hasattr(w, 'sel_marker'): w.sel_marker.update() def get_style(self): retval = [0] * len(self.style_pos) if not self.style: # style is wxSP_NOBORDER #retval[5] = 1 retval[4] = 1 try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass if retval[1] and retval[2]: # wx.SP_3D == wx.SP_3DSASH | wx.SP_3DBORDER retval[0] = 1 retval[1] = retval[2] = 0 elif retval[1] or retval[2]: retval[0] = 0 return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_sash_pos(self): return self.sash_pos def set_sash_pos(self, value): try: value = int(value) except ValueError: return self.sash_pos = value if self.widget: self.widget.SetSashPosition(value) def on_size(self, event): if not self.widget: return try: if self.orientation == wx.SPLIT_VERTICAL: max_pos = self.widget.GetClientSize()[0] else: max_pos = self.widget.GetClientSize()[1] self.properties['sash_pos'].set_range(-max_pos, max_pos) if not self.properties['sash_pos'].is_active(): self.widget.SetSashPosition(max_pos/2) self.sash_pos = self.widget.GetSashPosition() self.properties['sash_pos'].set_value(self.sash_pos) except (AttributeError, KeyError): pass ManagedBase.on_size(self, event) def on_sash_pos_changed(self, event): self.sash_pos = self.widget.GetSashPosition() self.properties['sash_pos'].set_value(self.sash_pos) event.Skip() def get_orientation(self): od = { wx.SPLIT_HORIZONTAL: 'wxSPLIT_HORIZONTAL', wx.SPLIT_VERTICAL: 'wxSPLIT_VERTICAL' } return od.get(self.orientation, 'wxSPLIT_VERTICAL') def set_orientation(self, value): od = { 'wxSPLIT_HORIZONTAL': wx.SPLIT_HORIZONTAL, 'wxSPLIT_VERTICAL': wx.SPLIT_VERTICAL } self.orientation = od.get(value, wx.SPLIT_VERTICAL) def get_win_1(self): if not isinstance(self.window_1, SizerSlot): return self.window_1.name return '' def get_win_2(self): if not isinstance(self.window_2, SizerSlot): return self.window_2.name return '' def get_no_custom_class(self): return self.no_custom_class def set_no_custom_class(self, value): self.no_custom_class = bool(int(value)) # end of class EditSplitterWindow def builder(parent, sizer, pos, number=[1]): """\ factory function for EditSplitterWindow objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, 'Select orientation') self.orientations = [ wx.SPLIT_VERTICAL, wx.SPLIT_HORIZONTAL ] self.orientation = wx.SPLIT_VERTICAL prop = RadioProperty(self, 'orientation', self, ['wxSPLIT_VERTICAL', 'wxSPLIT_HORIZONTAL'], label=_("orientation")) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop.panel, 0, wx.ALL|wx.EXPAND, 10) btn = wx.Button(self, wx.ID_OK, _('OK')) btn.SetDefault() szr.Add(btn, 0, wx.BOTTOM|wx.ALIGN_CENTER, 10) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def __getitem__(self, value): def set_orientation(o): self.orientation = self.orientations[o] return (lambda: self.orientation, set_orientation) # end of inner class dialog = Dialog() dialog.ShowModal() name = 'window_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'window_%d' % number[0] window = EditSplitterWindow(name, parent, wx.NewId(), None, None, None, dialog.orientation, sizer, pos, common.property_panel, show=False) try: from panel import EditPanel have_panels = True except ImportError: have_panels = False if have_panels: pane1 = EditPanel(name + '_pane_1', window, wx.NewId(), window.virtual_sizer, 1, common.property_panel) pane2 = EditPanel(name + '_pane_2', window, wx.NewId(), window.virtual_sizer, 2, common.property_panel) window.window_1 = pane1 window.window_2 = pane2 node = Tree.Node(window) window.node = node window.virtual_sizer.node = node window.set_option(1) window.set_flag("wxEXPAND") window.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) if have_panels: node2 = Tree.Node(window.window_1) window.window_1.node = node2 common.app_tree.add(node2, window.node) node3 = Tree.Node(window.window_2) window.window_2.node = node3 common.app_tree.add(node3, window.node) sizer.set_item(window.pos, 1, wx.EXPAND) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditSplitterWindow objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if not sizer or not sizeritem: raise XmlParsingError, _("sizer or sizeritem object cannot be None") window = EditSplitterWindow(name, parent, wx.NewId(), None, None, None, wx.SPLIT_VERTICAL, sizer, pos, common.property_panel, True) sizer.set_item(window.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(window) window.node = node window.virtual_sizer.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return window def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditSplitterWindow'] = builder common.widgets_from_xml['EditSplitterWindow'] = xml_builder return common.make_object_button('EditSplitterWindow', 'icons/splitter_window.xpm') wxglade-0.6.8.orig/widgets/splitter_window/__init__.py0000644000175000017500000000067711621715605023347 0ustar georgeskgeorgesk# __init__.py: splitter window widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:53 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import splitter_window return splitter_window.initialize() wxglade-0.6.8.orig/widgets/radio_button/0000755000175000017500000000000012170277707020466 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/radio_button/perl_codegen.py0000644000175000017500000000305211646104116023454 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxRadioButton objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:42:18 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) label = plgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, label, style)) props_buf = plgen.generate_common_properties(obj) clicked = prop.get('clicked') if clicked: props_buf.append('$self->{%s}->SetValue(1);\n' % obj.name) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditRadioButton'] = 'wxRadioButton' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxRadioButton', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/radio_button/lisp_codegen.py0000644000175000017500000000275512150154266023474 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxRadioButton objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 07:00:24 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) label = codegen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxRadioButton_Create %s %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, label, style)) props_buf = codegen.generate_common_properties(obj) clicked = prop.get('clicked') if clicked: props_buf.append('(wxRadioButton_SetValue (slot-%s obj) 1)\n' % obj.name) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditRadioButton'] = 'wxRadioButton' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxRadioButton', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/radio_button/codegen.py0000644000175000017500000000614212072605532022437 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxRadioButton objects # $Id: codegen.py,v 1.14 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) label = pygen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, %s%s)\n' % (obj.name, klass, parent, id, label, style)) props_buf = pygen.generate_common_properties(obj) clicked = prop.get('clicked') if clicked: props_buf.append('self.%s.SetValue(1)\n' % obj.name) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxRadioButton objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] label = cppgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s, %s%s);\n' % (obj.name, obj.klass, parent, id, label, extra) ] props_buf = cppgen.generate_common_properties(obj) clicked = prop.get('clicked') if clicked: props_buf.append('%s->SetValue(1);\n' % obj.name) return init, ids, props_buf, [] # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class XrcCodeGenerator(xrcgen.DefaultXrcObject): def write(self, *args, **kwds): try: self.properties['value'] = self.properties['clicked'] del self.properties['clicked'] except KeyError: pass xrcgen.DefaultXrcObject.write(self, *args, **kwds) return XrcCodeGenerator(obj) def initialize(): common.class_names['EditRadioButton'] = 'wxRadioButton' # python code generation functions pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxRadioButton', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxRadioButton', CppCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxRadioButton', xrc_code_generator) wxglade-0.6.8.orig/widgets/radio_button/radio_button.py0000644000175000017500000001444211621715605023530 0ustar georgeskgeorgesk# radio_button.py: wxRadioButton objects # $Id: radio_button.py,v 1.20 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * from misc import wxGladeRadioButton class EditRadioButton(ManagedBase): events = ['EVT_RADIOBUTTON'] def __init__(self, name, parent, id, label, sizer, pos, property_window, show=True): """\ Class to handle wxRadioButton objects """ import config ManagedBase.__init__(self, name, 'wxRadioButton', parent, id, sizer, pos, property_window, show=show) self.label = label self.value = 0 # if nonzero, che radio button is selected self.style = 0 # label and checked properties self.access_functions['label'] = (self.get_label, self.set_label) self.access_functions['clicked'] = (self.get_value, self.set_value) self.access_functions['style'] = (self.get_style, self.set_style) self.properties['label'] = TextProperty(self, 'label', None, multiline=True, label=_("label")) self.properties['clicked'] = CheckBoxProperty(self, 'clicked', None, _('Clicked')) self.style_pos = [wx.RB_GROUP, wx.RB_SINGLE, wx.RB_USE_CHECKBOX] self.properties['style'] = CheckListProperty( self, 'style', None, ['#section#' + _('Style'), 'wxRB_GROUP', 'wxRB_SINGLE', 'wxRB_USE_CHECKBOX'], tooltips=[_('Marks the beginning of a new group of radio buttons.'), _('In some circumstances, radio buttons that are not consecutive siblings trigger a hang bug in Windows (only). If this happens, add this style to mark the button as not belonging to a group, and implement the mutually-exclusive group behaviour yourself.'), _('Use a checkbox button instead of radio button (currently supported only on PalmOS).')]) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = wxGladeRadioButton(self.parent.widget, self.id, self.label) try: self.widget.SetValue(self.value) # self.clicked? except AttributeError: raise wx.EVT_CHECKBOX(self.widget, self.id, lambda e: self.widget.SetValue(self.value)) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['label'].display(panel) self.properties['clicked'].display(panel) self.properties['style'].display(panel) szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['clicked'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, _('Widget')) def get_label(self): return self.label def get_value(self): return self.value def set_label(self, value): value = misc.wxstr(value) if not misc.streq(value, self.label): self.label = value if self.widget: self.widget.SetLabel(value.replace('\\n', '\n')) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def set_value(self, value): self.value = int(value) if self.widget: self.widget.SetValue(self.value) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] # end of class EditRadioButton def builder(parent, sizer, pos, number=[1]): """\ factory function for EditRadioButton objects. """ label = 'radio_btn_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'radio_btn_%d' % number[0] radio = EditRadioButton(label, parent, wx.NewId(), misc._encode(label), sizer, pos, common.property_panel) node = Tree.Node(radio) radio.node = node radio.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditRadioButton objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") radio = EditRadioButton(label, parent, wx.NewId(), "", sizer, pos, common.property_panel) sizer.set_item(radio.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) ## size=radio.GetBestSize()) node = Tree.Node(radio) radio.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return radio def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditRadioButton'] = builder common.widgets_from_xml['EditRadioButton'] = xml_builder return common.make_object_button('EditRadioButton', 'icons/radio_button.xpm') wxglade-0.6.8.orig/widgets/radio_button/__init__.py0000644000175000017500000000066611621715605022601 0ustar georgeskgeorgesk# __init__.py: radio button widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import radio_button return radio_button.initialize() wxglade-0.6.8.orig/widgets/toggle_button/0000755000175000017500000000000012170277707020651 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/toggle_button/perl_codegen.py0000644000175000017500000000272711646104557023660 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxToggleButton objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:53:15 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) label = plgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s);\n' % (obj.name, klass, parent, id, label)) props_buf = plgen.generate_common_properties(obj) value = prop.get('value') if value: props_buf.append('$self->{%s}->SetValue(%s);\n' % (obj.name, value)) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditToggleButton'] = 'wxToggleButton' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxToggleButton', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/toggle_button/toggle_button.py0000644000175000017500000001137211621715605024075 0ustar georgeskgeorgesk# toggle_button.py: wxToggleButton objects # $Id: toggle_button.py,v 1.14 2007/03/27 07:01:51 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditToggleButton(ManagedBase): events = ['EVT_TOGGLEBUTTON'] def __init__(self, name, parent, id, label, sizer, pos, property_window, show=True): """\ Class to handle wxToggleButton objects """ import config ManagedBase.__init__(self, name, 'wxToggleButton', parent, id, sizer, pos, property_window, show=show) self.label = label self.value = 0 self.access_functions['label'] = (self.get_label, self.set_label) self.access_functions['value'] = (self.get_value, self.set_value) self.properties['label'] = TextProperty(self, 'label', None, multiline=True, label=_("label")) self.properties['value'] = CheckBoxProperty(self, 'value', None, _('Clicked')) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = wx.ToggleButton(self.parent.widget, self.id, self.label) self.widget.SetValue(self.value) wx.EVT_TOGGLEBUTTON(self.widget, self.id, self.on_set_focus) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['label'].display(panel) self.properties['value'].display(panel) szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['value'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def get_label(self): return self.label def set_label(self, value): value = misc.wxstr(value) if not misc.streq(value, self.label): self.label = value if self.widget: self.widget.SetLabel(value.replace('\\n', '\n')) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def get_value(self): return self.value def set_value(self, value): # !!! This should be done with bool. # 2003-03-21 NO! bools are evil here: bool('0') == True != int('0') value = int(value) if value != self.value: self.value = value if self.widget: self.widget.SetValue(value) # end of class EditToggleButton def builder(parent, sizer, pos, number=[1]): """\ factory function for EditToggleButton objects. """ label = 'button_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'button_%d' % number[0] button = EditToggleButton(label, parent, wx.NewId(), misc._encode(label), sizer, pos, common.property_panel) node = Tree.Node(button) button.node = node button.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditToggleButton objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") button = EditToggleButton(label, parent, wx.NewId(), '', sizer, pos, common.property_panel) sizer.set_item(button.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) #, size=button.GetBestSize()) node = Tree.Node(button) button.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return button def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditToggleButton'] = builder common.widgets_from_xml['EditToggleButton'] = xml_builder return common.make_object_button('EditToggleButton', 'icons/toggle_button.xpm') wxglade-0.6.8.orig/widgets/toggle_button/lisp_codegen.py0000644000175000017500000000256711621715605023662 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxToggleButton objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:41:28 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['lisp'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) label = plgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxToggleButton_Create %s %s %s -1 -1 -1 -1 0))\n' % (obj.name, parent, id, label)) props_buf = plgen.generate_common_properties(obj) value = prop.get('value') if value: props_buf.append('(wxToggleButton_SetValue (slot-%s obj) %s)\n' % (obj.name, value)) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditToggleButton'] = 'wxToggleButton' plgen = common.code_writers.get('lisp') if plgen: plgen.add_widget_handler('wxToggleButton', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/toggle_button/codegen.py0000644000175000017500000000455611621715605022633 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxToggleButton objects # $Id: codegen.py,v 1.13 2007/03/27 07:01:51 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) label = pygen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, %s)\n' % (obj.name, klass, parent, id, label)) props_buf = pygen.generate_common_properties(obj) value = prop.get('value') if value: props_buf.append('self.%s.SetValue(%s)\n' % (obj.name, value)) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ generates C++ code for wxToggleButton objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] label = cppgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' init = [ '%s = new %s(%s, %s, %s);\n' % (obj.name, obj.klass, parent, id, label) ] props_buf = cppgen.generate_common_properties(obj) value = prop.get('value') if value: props_buf.append('%s->SetValue(%s);\n' % (obj.name, value)) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditToggleButton'] = 'wxToggleButton' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxToggleButton', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxToggleButton', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/toggle_button/__init__.py0000644000175000017500000000067111621715605022760 0ustar georgeskgeorgesk# __init__.py: toggle button widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:51 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import toggle_button return toggle_button.initialize() wxglade-0.6.8.orig/widgets/datepicker_ctrl/0000755000175000017500000000000012170277707021134 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/datepicker_ctrl/datepicker_ctrl.py0000644000175000017500000001400511677431671024650 0ustar georgeskgeorgesk# datepicker_ctrl.py: wxDatePickerCtrl objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx from edit_windows import ManagedBase from tree import Tree import common from widget_properties import * class EditDatePickerCtrl(ManagedBase): events = ['EVT_DATE_CHANGED'] def __init__(self, name, parent, id, sizer, pos, property_window, show=True): """\ Class to handle wxDatePickerCtrl objects """ import config self.default = False ManagedBase.__init__(self, name, 'wxDatePickerCtrl', parent, id, sizer, pos, property_window, show=show) #self.access_functions['label'] = (self.get_label, self.set_label) #self.properties['label'] = TextProperty(self, 'label', None, # multiline=True, label=_("label")) self.access_functions['default'] = (self.get_default, self.set_default) self.access_functions['style'] = (self.get_style, self.set_style) self.properties['default'] = CheckBoxProperty(self, 'default', None, label=_("default")) style_labels = ('#section#' + _('Style'), 'wxDP_SPIN', 'wxDP_DROPDOWN', 'wxDP_DEFAULT', 'wxDP_ALLOWNONE', 'wxDP_SHOWCENTURY') self.style_pos = (wx.DP_SPIN, wx.DP_DROPDOWN, wx.DP_DEFAULT, wx.DP_ALLOWNONE, wx.DP_SHOWCENTURY) self.tooltips = (_("Creates a control without a month calendar drop down but with spin-control-like arrows to change individual date components. This style is not supported by the generic version."), _("Creates a control with a month calendar drop-down part from which the user can select a date."), _("Creates a control with the style that is best supported for the current platform (currently wxDP_SPIN under Windows and wxDP_DROPDOWN elsewhere)."), _("With this style, the control allows the user to not enter any valid date at all. Without it - the default - the control always has some valid date."), _("Forces display of the century in the default date format. Without this style the century could be displayed, or not, depending on the default date representation in the system.")) self.properties['style'] = CheckListProperty(self, 'style', None, style_labels,tooltips=self.tooltips) if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) #self.properties['label'].display(panel) self.properties['default'].display(panel) self.properties['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) #szr.Add(self.properties['label'].panel, 0, wxEXPAND) szr.Add(self.properties['default'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(1) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def create_widget(self): try: #TODO add all the other parameters for the DatePickerCtrl intial date self.widget = wx.DatePickerCtrl(self.parent.widget, self.id, style=self.style) except AttributeError: self.widget = wx.DatePickerCtrl(self.parent.widget, self.id) def get_default(self): return self.default def set_default(self, value): self.default = bool(int(value)) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) # end of class EditDatePickerCtrl def builder(parent, sizer, pos, number=[1]): """\ factory function for EditDatePickerCtrl objects. """ label = 'datepicker_ctrl_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'datepicker_ctrl_%d' % number[0] datepicker_ctrl = EditDatePickerCtrl(label, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(datepicker_ctrl) datepicker_ctrl.node = node datepicker_ctrl.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditDatePickerCtrl objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") datepicker_ctrl = EditDatePickerCtrl(label, parent, wx.NewId(), sizer, pos, common.property_panel, show=False) node = Tree.Node(datepicker_ctrl) datepicker_ctrl.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return datepicker_ctrl def initialize(): """\ initialization function for the module. @rtype: wxBitmapButton @return: an icon to be added to the main palette. """ common.widgets['EditDatePickerCtrl'] = builder common.widgets_from_xml['EditDatePickerCtrl'] = xml_builder return common.make_object_button('EditDatePickerCtrl', 'icons/datepicker_ctrl.xpm') wxglade-0.6.8.orig/widgets/datepicker_ctrl/codegen.py0000644000175000017500000001137112103502354023076 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxDatePickerCtrl objects # $Header: /home/alb/tmp/wxglade_cvs_backup/wxGlade/widgets/datepicker_ctrl/codegen.py,v 1.2 2007/03/27 07:02:01 agriggio Exp $ # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: #def __init__(self): #self.pygen = common.code_writers['python'] #def __get_import_modules(self): #if self.pygen.use_new_namespace: #return ['import wx.calendar\n'] #else: #return ['from wxPython.calendar import *\n'] #import_modules = property(__get_import_modules) #def cn(self, c): #""" Create names according to if the new namescace (wx) was selected #@type c: string #@param c: the name which should be altered #@rtype: string #@return: the orignial name with a prefix according to which namespace the user selected #""" #if self.pygen.use_new_namespace: #if c[:2] == 'wx': #c = c[2:] #return 'wx.calendar.' + c #else: #return c #def cn_f(self, flags): #""" Same as cn(c) but for flags #@rtype: string #""" #if self.pygen.use_new_namespace: #return "|".join([self.cn(f) for f in str(flags).split('|')]) #else: #return str(flags) def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) #label = pygen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s%s)\n' % # (obj.name, klass, parent, id, label, style)) (obj.name, klass,parent, id, style)) props_buf = pygen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('self.%s.SetDefault()\n' % obj.name) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class DatePickerCtrlXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'label': # translate & into _ as accelerator marker val2 = val.replace('&', '_') if val.count('&&') > 0: while True: index = val.find('&&') if index < 0: break val = val2[:index] + '&&' + val2[index+2:] else: val = val2 xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class DatePickerCtrlXrcObject return DatePickerCtrlXrcObject(obj) class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ fuction that generates python code for wxDatePickerCtrl objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, %s' % style #label = cppgen.quote_str(prop.get('label', '')) init = [ '%s = new %s(%s, %s%s);\n' % # (obj.name, obj.klass, parent, id, label, extra) ] (obj.name, obj.klass, parent, id, extra) ] props_buf = cppgen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('%s->SetDefault();\n' % obj.name) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditDatePickerCtrl'] = 'wxDatePickerCtrl' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxDatePickerCtrl', PythonCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxDatePickerCtrl', xrc_code_generator) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxDatePickerCtrl', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/datepicker_ctrl/__init__.py0000644000175000017500000000100311621715605023231 0ustar georgeskgeorgesk# __init__.py: datepicker_ctrl widget module initialization # $Header: /home/alb/tmp/wxglade_cvs_backup/wxGlade/widgets/datepicker_ctrl/__init__.py,v 1.2 2007/03/27 07:02:01 agriggio Exp $ # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import datepicker_ctrl return datepicker_ctrl.initialize() wxglade-0.6.8.orig/widgets/ChoicesCodeHandler.py0000644000175000017500000000361711621715605022016 0ustar georgeskgeorgesk# ChoicesCodeHandler.py: handler for the 'choices' property of various elements # $Id: ChoicesCodeHandler.py,v 1.8 2007/03/27 07:02:05 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY class ChoicesCodeHandler: """\ handler for the 'choices' property of various elements """ def __init__(self): self.choices = [] self.curr_choice = [] self.cur_checked = None def start_elem(self, name, attrs): if name == 'choice': try: self.cur_checked = int(attrs['checked']) except (KeyError, ValueError): self.cur_checked = None def end_elem(self, name, code_obj): if name == 'choice': c = "".join(self.curr_choice) if self.cur_checked is None: self.choices.append(c) else: self.choices.append((c, self.cur_checked)) self.curr_choice = [] self.cur_checked = None elif name == 'choices': code_obj.properties['choices'] = self.choices return True def char_data(self, data): self.curr_choice.append(data) # end of class ChoicesCodeHandler def xrc_write_choices_property(xrc_obj, outfile, tabs): """\ function used to write the XRC code for a ``choices'' property """ from xml.sax.saxutils import escape choices = xrc_obj.properties['choices'] write = outfile.write write(' '*tabs + '\n') tab_s = ' ' * (tabs+1) for choice in choices: if isinstance(choice, tuple): write(tab_s + '%s\n' % \ (choice[1], escape(choice[0]))) else: write(tab_s + '%s\n' % escape(choice)) write(' '*tabs + '\n') wxglade-0.6.8.orig/widgets/button/0000755000175000017500000000000012170277707017310 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/button/perl_codegen.py0000644000175000017500000000353111646103372022303 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxButton objects # $Id: perl_codegen.py,v 1.8 2007/04/01 12:29:50 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): """\ fuction that generates perl code for wxButton objects. """ init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) stockitem = prop.get('stockitem', 'None') if stockitem != 'None': label = plgen.quote_str('') id = "wxID_" + stockitem else: label = plgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: extra = '' else: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s%s);\n' % (obj.name, klass, parent, id, label, extra)) props_buf = plgen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('$self->{%s}->SetDefault();\n' % obj.name) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditButton'] = 'wxButton' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxButton', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/button/lisp_codegen.py0000644000175000017500000000333012150154266022304 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxButton objects # $Id: lisp_codegen.py,v 1.3 2007/04/01 12:29:50 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): """\ fuction that generates lisp code for wxButton objects. """ init = [] codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) stockitem = prop.get('stockitem', 'None') if stockitem != 'None': label = codegen.quote_str('') id = "wxID_" + stockitem else: label = codegen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxButton_Create %s %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, label, style)) props_buf = codegen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('(wxButton_SetDefault (slot-%s obj))\n' % obj.name) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditButton'] = 'wxButton' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxButton', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/button/codegen.py0000644000175000017500000001020312072605532021252 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxButton objects # $Id: codegen.py,v 1.18 2007/04/01 12:42:16 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] cn = pygen.cn prop = obj.properties id_name, id = pygen.generate_code_id(obj) stockitem = prop.get('stockitem', 'None') if stockitem != 'None': id = pygen.cn("wxID_" + stockitem) label = pygen.quote_str('') else: label = pygen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = cn(klass) init.append('self.%s = %s(%s, %s, %s%s)\n' % (obj.name, klass, parent, id, label, style)) props_buf = pygen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('self.%s.SetDefault()\n' % obj.name) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class ButtonXrcObject(xrcgen.DefaultXrcObject): def write(self, out_file, ntabs): stockitem = self.properties.get('stockitem', 'None') if stockitem != 'None': self.name = 'wxID_' + stockitem del self.properties['stockitem'] try: del self.properties['label'] except KeyError: pass xrcgen.DefaultXrcObject.write(self, out_file, ntabs) def write_property(self, name, val, outfile, tabs): if name == 'label': # translate & into _ as accelerator marker val2 = val.replace('&', '_') if val.count('&&') > 0: while True: index = val.find('&&') if index < 0: break val = val2[:index] + '&&' + val2[index+2:] else: val = val2 xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class ButtonXrcObject return ButtonXrcObject(obj) class CppCodeGenerator: def get_code(self, obj): """\ fuction that generates python code for wxButton objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style stockitem = prop.get('stockitem', 'None') if stockitem != 'None': label = cppgen.quote_str('') id = "wxID_" + stockitem else: label = cppgen.quote_str(prop.get('label', '')) init = [ '%s = new %s(%s, %s, %s%s);\n' % (obj.name, obj.klass, parent, id, label, extra) ] props_buf = cppgen.generate_common_properties(obj) if prop.get('default', False): props_buf.append('%s->SetDefault();\n' % obj.name) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditButton'] = 'wxButton' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxButton', PythonCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxButton', xrc_code_generator) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxButton', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/button/button_stockitems.py0000644000175000017500000000424511621715605023441 0ustar georgeskgeorgeskclass ButtonStockItems: stock_ids = { "ADD" : "Add", "APPLY" : "&Apply", "BOLD" : "&Bold", "CANCEL" : "&Cancel", "CLEAR" : "&Clear", "CLOSE" : "&Close", "COPY" : "&Copy", "CUT" : "Cu&t", "DELETE" : "&Delete", "FIND" : "&Find", "REPLACE" : "Find and rep&lace", "BACKWARD" : "&Back", "DOWN" : "&Down", "FORWARD" : "&Forward", "UP" : "&Up", "HELP" : "&Help", "HOME" : "&Home", "INDENT" : "Indent", "INDEX" : "&Index", "ITALIC" : "&Italic", "JUSTIFY_CENTER" : "Centered", "JUSTIFY_FILL" : "Justified", "JUSTIFY_LEFT" : "Align Left", "JUSTIFY_RIGHT" : "Align Right", "NEW" : "&New", "NO" : "&No", "OK" : "&OK", "OPEN" : "&Open", "PASTE" : "&Paste", "PREFERENCES" : "&Preferences", "PRINT" : "&Print", "PREVIEW" : "Print previe&w", "PROPERTIES" : "&Properties", "EXIT" : "&Quit", "REDO" : "&Redo", "REFRESH" : "Refresh", "REMOVE" : "Remove", "REVERT_TO_SAVED" : "Revert to Saved", "SAVE" : "&Save", "SAVEAS" : "Save &As...", "STOP" : "&Stop", "UNDELETE" : "Undelete", "UNDERLINE" : "&Underline", "UNDO" : "&Undo", "UNINDENT" : "&Unindent", "YES" : "&Yes", "ZOOM_100" : "&Actual Size", "ZOOM_FIT" : "Zoom to &Fit", "ZOOM_IN" : "Zoom &In", "ZOOM_OUT" : "Zoom &Out", } wxglade-0.6.8.orig/widgets/button/button.py0000644000175000017500000001771712150154266021202 0ustar georgeskgeorgesk""" wxButton objects @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * from button_stockitems import * class EditButton(ManagedBase): events = ['EVT_BUTTON'] def __init__(self, name, parent, id, label, sizer, pos, property_window, show=True): """\ Class to handle wxButton objects """ import config self.label = label self.default = False self.stockitem = "None" ManagedBase.__init__(self, name, 'wxButton', parent, id, sizer, pos, property_window, show=show) self.access_functions['label'] = (self.get_label, self.set_label) self.properties['label'] = TextProperty(self, 'label', None, multiline=True) self.access_functions['stockitem'] = (self.get_stockitem, self.set_stockitem) self.access_functions['default'] = (self.get_default, self.set_default) self.access_functions['style'] = (self.get_style, self.set_style) self.properties['default'] = CheckBoxProperty(self, 'default', None, label=_("Default")) self.properties['default'].tooltip = \ _("This sets the button to be the default " "item for the panel or dialog box.") #Get the list of items, and add a 'None' choices = ButtonStockItems.stock_ids.keys() choices.sort() choices[:0] = ['None'] self.properties['stockitem'] = ComboBoxProperty( self, 'stockitem', choices, can_disable=True, label=_("Stock item")) self.properties['stockitem'].tooltip = \ _("Standard IDs for button identifiers") self.style_pos = (wx.BU_LEFT, wx.BU_RIGHT, wx.BU_TOP, wx.BU_BOTTOM, wx.BU_EXACTFIT,wx.NO_BORDER) style_labels = ('#section#' + _('Style'), 'wxBU_LEFT', 'wxBU_RIGHT', 'wxBU_TOP', 'wxBU_BOTTOM', 'wxBU_EXACTFIT','wxNO_BORDER') #The tooltips tuple style_tooltips=(_("Left-justifies the label. Windows and GTK+ only."), _("Right-justifies the bitmap label. Windows and GTK+ " "only."), _("Aligns the label to the top of the button. Windows " "and GTK+ only."), _("Aligns the label to the bottom of the button. " "Windows and GTK+ only."), _("Creates the button as small as possible instead of " "making it of the standard size (which is the default " "behaviour )."), _("Creates a flat button. Windows and GTK+ only.")) self.properties['style'] = CheckListProperty( self, 'style', None, style_labels, tooltips=style_tooltips) # the tooltips tuple is # passed as the last # argument # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) self.properties['label'].display(panel) self.properties['stockitem'].display(panel) self.properties['default'].display(panel) self.properties['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['stockitem'].panel, 0, wx.EXPAND) szr.Add(self.properties['default'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(1) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') if self.stockitem != "None": s = common.app_tree.app.saved self.set_stockitem(self.stockitem) common.app_tree.app.saved = s def get_label(self): return self.label def set_label(self, value): value = misc.wxstr(value) if not misc.streq(value, self.label): if self.widget: self.widget.SetLabel(value.replace('\\n', '\n')) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) self.label = value def create_widget(self): try: self.widget = wx.Button(self.parent.widget, self.id, self.label, style=self.style) except AttributeError: self.widget = wx.Button(self.parent.widget, self.id, self.label) def get_default(self): return self.default def set_default(self, value): self.default = bool(int(value)) def get_stockitem(self): return self.stockitem def set_stockitem(self, value): self.stockitem = misc.wxstr(value) if self.stockitem != "None": l = ButtonStockItems.stock_ids[self.stockitem] self.set_label(l) self.properties['label'].set_value(l) if self.properties['label'].panel is not None: self.properties['label'].text.Enable(False) self.window_id = "wxID_" + self.stockitem self.properties['id'].set_value(self.window_id) self.properties['id'].toggle_active(False) else: if self.properties['label'].panel is not None: self.properties['label'].text.Enable(True) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) # end of class EditButton def builder(parent, sizer, pos, number=[1]): """\ factory function for EditButton objects. """ label = 'button_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'button_%d' % number[0] button = EditButton(label, parent, wx.NewId(), misc._encode(label), sizer, pos, common.property_panel) node = Tree.Node(button) button.node = node button.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditButton objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") button = EditButton(label, parent, wx.NewId(), '', sizer, pos, common.property_panel, show=False) node = Tree.Node(button) button.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return button def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditButton'] = builder common.widgets_from_xml['EditButton'] = xml_builder return common.make_object_button('EditButton', 'icons/button.xpm') wxglade-0.6.8.orig/widgets/button/__init__.py0000644000175000017500000000064411621715605021417 0ustar georgeskgeorgesk# __init__.py: button widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:02:05 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import button return button.initialize() wxglade-0.6.8.orig/widgets/static_line/0000755000175000017500000000000012170277707020273 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/static_line/perl_codegen.py0000644000175000017500000000320711677432054023274 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxStaticLine objects # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties attribute = plgen.test_attribute(obj) id_name, id = plgen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not( style and style != 'wxLI_HORIZONTAL' ): # default style style = '' init = [] if id_name: init.append(id_name) if attribute: prefix = '$self->{%s}' % obj.name else: prefix = 'my $%s' % obj.name obj.name = '$' + obj.name # the yuck (needed for pl_codegen.py) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('%s = %s->new(%s, %s, wxDefaultPosition, wxDefaultSize, \ %s);\n' % (prefix, klass , parent, id, style)) props_buf = plgen.generate_common_properties(obj) if not attribute: return [], [], init + props_buf return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditStaticLine'] = 'wxStaticLine' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxStaticLine', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/static_line/lisp_codegen.py0000644000175000017500000000321012150154266023264 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxStaticLine objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:50:08 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties attribute = codegen.test_attribute(obj) id_name, id = codegen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not( style and style != 'wxLI_HORIZONTAL' ): # default style style = '0' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) if attribute: prefix = '(slot-%s obj)' % obj.name else: prefix = 'my $%s' % obj.name obj.name = '$' + obj.name # the yuck (needed for pl_codegen.py) init.append('(setf %s (wxStaticLine_Create %s %s -1 -1 -1 -1 %s))\n' % (prefix, parent, id, style)) props_buf = codegen.generate_common_properties(obj) if not attribute: return [], [], init + props_buf return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditStaticLine'] = 'wxStaticLine' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxStaticLine', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/static_line/codegen.py0000644000175000017500000000626611621715605022255 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxStaticLine objects # $Id: codegen.py,v 1.14 2007/03/27 07:01:52 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties attribute = pygen.test_attribute(obj) id_name, id = pygen.generate_code_id(obj) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style and style != 'wxLI_HORIZONTAL': style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) if attribute: prefix = 'self.' else: prefix = '' klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('%s%s = %s(%s, %s%s)\n' % (prefix, obj.name, klass, parent, id, style)) props_buf = pygen.generate_common_properties(obj) if not attribute: return [], [], init + props_buf return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ generates the C++ code for wxStaticLine objects """ cppgen = common.code_writers['C++'] prop = obj.properties attribute = cppgen.test_attribute(obj) id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style and style != 'wxLI_HORIZONTAL': extra = ', wxDefaultPosition, wxDefaultSize, %s' % style if attribute: prefix = '' else: prefix = '%s* ' % obj.klass init = ['%s%s = new %s(%s, %s%s);\n' % (prefix, obj.name, obj.klass, parent, id, extra) ] if id_name: init.append(id_name) props_buf = cppgen.generate_common_properties(obj) if not attribute: return [], ids, [], init + props_buf return init, ids, props_buf, [] # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class XrcCodeGenerator(xrcgen.DefaultXrcObject): def write(self, *args, **kwds): try: del self.properties['attribute'] except KeyError: pass xrcgen.DefaultXrcObject.write(self, *args, **kwds) return XrcCodeGenerator(obj) def initialize(): common.class_names['EditStaticLine'] = 'wxStaticLine' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxStaticLine', PythonCodeGenerator()) cppgen = common.code_writers.get("C++") if cppgen: cppgen.add_widget_handler('wxStaticLine', CppCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxStaticLine', xrc_code_generator) wxglade-0.6.8.orig/widgets/static_line/static_line.py0000644000175000017500000001314411621715605023140 0ustar georgeskgeorgesk# static_line.py: wxStaticLine objects # $Id: static_line.py,v 1.13 2007/08/07 12:18:34 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditStaticLine(ManagedBase): def __init__(self, name, parent, id, orientation, sizer, pos, property_window, show=True): """\ Class to handle wxStaticLine objects """ self.orientation = orientation self.attribute = True ManagedBase.__init__(self, name, 'wxStaticLine', parent, id, sizer, pos, property_window, show=show) self.access_functions['style'] = (self.get_orientation, self.set_orientation) def set_attribute(v): self.attribute = int(v) self.access_functions['attribute'] = (lambda : self.attribute, set_attribute) self.properties['style'] = HiddenProperty(self, 'style', label=_("style")) self.properties['attribute'] = CheckBoxProperty( self, 'attribute', None, _('Store as attribute'), write_always=True) self.removed_p = self.properties['font'] def create_widget(self): #self.orientation = int(self.property['style'].get_value()) self.widget = wx.StaticLine(self.parent.widget, self.id, style=self.orientation) wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) def finish_widget_creation(self): ManagedBase.finish_widget_creation(self) self.sel_marker.Reparent(self.parent.widget) del self.properties['font'] def create_properties(self): ManagedBase.create_properties(self) if self.removed_p.panel: self.removed_p.panel.Hide() panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['attribute'].display(panel) szr.Add(self.properties['attribute'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def __getitem__(self, key): if key != 'font': return ManagedBase.__getitem__(self, key) return (lambda : "", lambda v: None) def get_orientation(self): od = { wx.LI_HORIZONTAL: 'wxLI_HORIZONTAL', wx.LI_VERTICAL: 'wxLI_VERTICAL' } return od.get(self.orientation, 'wxLI_HORIZONTAL') def set_orientation(self, value): od = { 'wxLI_HORIZONTAL': wx.LI_HORIZONTAL, 'wxLI_VERTICAL': wx.LI_VERTICAL } self.orientation = od.get(value, wx.LI_HORIZONTAL) # end of class EditStaticLine def builder(parent, sizer, pos, number=[1]): """\ factory function for EditStaticLine objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, 'Select orientation') self.orientations = [ wx.LI_HORIZONTAL, wx.LI_VERTICAL ] self.orientation = wx.LI_HORIZONTAL prop = RadioProperty(self, 'orientation', self, ['wxLI_HORIZONTAL', 'wxLI_VERTICAL'], label=_("orientation")) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop.panel, 0, wx.ALL|wx.EXPAND, 10) btn = wx.Button(self, wx.ID_OK, _('OK')) btn.SetDefault() szr.Add(btn, 0, wx.BOTTOM|wx.ALIGN_CENTER, 10) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def __getitem__(self, value): def set_orientation(o): self.orientation = self.orientations[o] return (lambda: self.orientation, set_orientation) # end of inner class dialog = Dialog() dialog.ShowModal() label = 'static_line_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'static_line_%d' % number[0] static_line = EditStaticLine(label, parent, wx.NewId(), dialog.orientation, sizer, pos, common.property_panel) node = Tree.Node(static_line) static_line.node = node static_line.set_flag("wxEXPAND") static_line.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditStaticLine objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") static_line = EditStaticLine(name, parent, wx.NewId(), 0, sizer, pos, common.property_panel) sizer.set_item(static_line.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(static_line) static_line.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return static_line def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditStaticLine'] = builder common.widgets_from_xml['EditStaticLine'] = xml_builder return common.make_object_button('EditStaticLine', 'icons/static_line.xpm') wxglade-0.6.8.orig/widgets/static_line/__init__.py0000644000175000017500000000066311621715605022403 0ustar georgeskgeorgesk# __init__.py: static line widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:52 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import static_line return static_line.initialize() wxglade-0.6.8.orig/widgets/checkbox/0000755000175000017500000000000012170277707017563 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/checkbox/perl_codegen.py0000644000175000017500000000306111646103442022552 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxCheckBox objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:35:44 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) label = plgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s, \ wxDefaultPosition, wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, label, style)) props_buf = plgen.generate_common_properties(obj) checked = prop.get('checked') if checked: props_buf.append('$self->{%s}->SetValue(1);\n' % obj.name) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditCheckBox'] = 'wxCheckBox' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxCheckBox', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/checkbox/checkbox.py0000644000175000017500000001133511621715605021720 0ustar georgeskgeorgesk# checkbox.py: wxCheckBox objects # $Id: checkbox.py,v 1.14 2007/03/27 07:02:03 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditCheckBox(ManagedBase): events = ['EVT_CHECKBOX'] def __init__(self, name, parent, id, label, sizer, pos, property_window, show=True): """\ Class to handle wxCheckBox objects """ import config ManagedBase.__init__(self, name, 'wxCheckBox', parent, id, sizer, pos, property_window, show=show) self.label = label self.value = 0 # if nonzero, che checkbox is checked self.access_functions['label'] = (self.get_label, self.set_label) self.access_functions['checked'] = (self.get_value, self.set_value) self.properties['label'] = TextProperty(self, 'label', None, multiline=True, label=_("label")) self.properties['checked'] = CheckBoxProperty(self, 'checked', None, _('Checked')) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = wx.CheckBox(self.parent.widget, self.id, self.label) self.widget.SetValue(self.value) def on_checkbox(event): self.set_value(self.value) wx.EVT_CHECKBOX(self.widget, self.id, on_checkbox) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) self.properties['label'].display(panel) self.properties['checked'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['checked'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def get_label(self): return self.label def set_label(self, value): value = misc.wxstr(value) if not misc.streq(value, self.label): self.label = value if self.widget: self.widget.SetLabel(value.replace('\\n', '\n')) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def get_value(self): return self.value def set_value(self, value): self.value = int(value) if self.widget: self.widget.SetValue(self.value) self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) # end of class EditCheckBox def builder(parent, sizer, pos, number=[1]): """\ factory function for EditCheckBox objects. """ label = 'checkbox_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'checkbox_%d' % number[0] checkbox = EditCheckBox(label, parent, wx.NewId(), label, sizer, pos, common.property_panel) node = Tree.Node(checkbox) checkbox.node = node checkbox.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditCheckBox objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") checkbox = EditCheckBox(label, parent, wx.NewId(), "", sizer, pos, common.property_panel, show=False) sizer.set_item(checkbox.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) #, ## size=checkbox.GetBestSize()) node = Tree.Node(checkbox) checkbox.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return checkbox def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditCheckBox'] = builder common.widgets_from_xml['EditCheckBox'] = xml_builder return common.make_object_button('EditCheckBox', 'icons/checkbox.xpm') wxglade-0.6.8.orig/widgets/checkbox/lisp_codegen.py0000644000175000017500000000317712150154266022570 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxCheckBox objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:58:25 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) label = codegen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('(setf (slot-%s obj) (wxCheckBox_Create %s %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, label, style)) props_buf = codegen.generate_common_properties(obj) checked = prop.get('checked') if checked: props_buf.append('(wxCheckBox_SetValue (slot-%s obj) 1);\n' % obj.name) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditCheckBox'] = 'wxCheckBox' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxCheckBox', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/checkbox/codegen.py0000644000175000017500000000473412072605532021541 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxCheckBox objects # $Id: codegen.py,v 1.13 2007/03/27 07:02:03 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) label = pygen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % style else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, %s%s)\n' % (obj.name, klass, parent, id, label, style)) props_buf = pygen.generate_common_properties(obj) checked = prop.get('checked') if checked: props_buf.append('self.%s.SetValue(1)\n' % obj.name) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxCheckBox objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] label = cppgen.quote_str(prop.get('label', '')) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s, %s%s);\n' % (obj.name, obj.klass, parent, id, label, extra) ] props_buf = cppgen.generate_common_properties(obj) checked = prop.get('checked') if checked: props_buf.append('%s->SetValue(1);\n' % obj.name) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditCheckBox'] = 'wxCheckBox' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxCheckBox', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxCheckBox', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/checkbox/__init__.py0000644000175000017500000000065211621715605021671 0ustar georgeskgeorgesk# __init__.py: checkbox widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:02:03 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import checkbox return checkbox.initialize() wxglade-0.6.8.orig/widgets/dialog/0000755000175000017500000000000012170277707017234 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/dialog/perl_codegen.py0000644000175000017500000000325511621715605022233 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxDialog objects # $Id: perl_codegen.py,v 1.3 2004/09/17 13:09:53 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: #wxDialog( parent, id, title, pos, size, style, name ) new_signature = [ '$parent', '$id', '$title', '$pos', '$size', '$style', '$name' ] def get_code(self, obj): return [], [], [] def get_properties_code(self, dialog): prop = dialog.properties plgen = common.code_writers['perl'] out = [] title = prop.get('title') if title: out.append('$self->SetTitle(%s);\n' % plgen.quote_str(title)) icon = prop.get('icon') if icon: out.append('my $icon = &Wx::wxNullIcon();\n') out.append('$icon->CopyFromBitmap(Wx::Bitmap->new(%s, ' 'wxBITMAP_TYPE_ANY));\n' % plgen.quote_str(icon)) out.append('$self->SetIcon($icon);\n') out.extend(plgen.generate_common_properties(dialog)) return out def get_layout_code(self, dialog): ret = ['$self->Layout();\n'] try: if int(dialog.properties['centered']): ret.append('$self->Centre();\n') except (KeyError, ValueError): pass return ret # end of class PerlCodeGenerator def initialize(): cn = common.class_names cn['EditDialog'] = 'wxDialog' common.toplevels['EditDialog'] = 1 plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxDialog', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/dialog/lisp_codegen.py0000644000175000017500000000326212150154266022234 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxDialog objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:59:14 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: #wxDialog( parent, id, title, pos, size, style, name ) new_signature = [ '$parent', '$id', '$title', '$pos', '$size', '$style', '$name' ] def get_code(self, obj): return [], [], [] def get_properties_code(self, dialog): prop = dialog.properties lispgen = common.code_writers['lisp'] out = [] title = prop.get('title') if title: out.append('(wxWindow_SetTitle (slot-%s self) %s)\n' % (dialog.name, lispgen.quote_str(title))) icon = prop.get('icon') if icon: out.append( ';;; generating code for setting icons is not implemented\n' ) out.extend(lispgen.generate_common_properties(dialog)) return out def get_layout_code(self, dialog): ret = ['(wxWindow_layout (slot-%s slef))\n' % dialog.name] try: if int(dialog.properties['centered']): ret.append('(wxWindow_Centre (slot-%s slef) wxBOTH)\n' % dialog.name) except (KeyError, ValueError): pass return ret # end of class LispCodeGenerator def initialize(): cn = common.class_names cn['EditDialog'] = 'wxDialog' common.toplevels['EditDialog'] = 1 lispgen = common.code_writers.get('lisp') if lispgen: lispgen.add_widget_handler('wxDialog', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/dialog/codegen.py0000644000175000017500000001166211621715605021212 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxDialog objects # $Id: codegen.py,v 1.15 2007/03/27 07:02:00 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): return [], [], [] def get_properties_code(self, dialog): prop = dialog.properties pygen = common.code_writers['python'] cn = pygen.cn out = [] title = prop.get('title') if title: out.append('self.SetTitle(%s)\n' % pygen.quote_str(title)) icon = prop.get('icon') if icon: if icon.startswith('var:'): if not dialog.preview: out.append('_icon = ' + cn('wxEmptyIcon') + '()\n') out.append(('_icon.CopyFromBitmap(' + cn('wxBitmap') + '(%s, ' + cn('wxBITMAP_TYPE_ANY') + '))\n') % \ icon[4:].strip()) out.append('self.SetIcon(_icon)\n') elif icon.startswith('code:'): if not dialog.preview: out.append('_icon = ' + cn('wxEmptyIcon') + '()\n') out.append(('_icon.CopyFromBitmap(%s)\n') % \ icon[5:].strip()) out.append('self.SetIcon(_icon)\n') else: if dialog.preview: import misc icon = misc.get_relative_path(icon, True) out.append('_icon = ' + cn('wxEmptyIcon') + '()\n') out.append(('_icon.CopyFromBitmap(' + cn('wxBitmap') + '(%s, ' + cn('wxBITMAP_TYPE_ANY') + '))\n') % \ pygen.quote_str(icon, False, False)) out.append('self.SetIcon(_icon)\n') out.extend(pygen.generate_common_properties(dialog)) return out def get_layout_code(self, dialog): ret = ['self.Layout()\n'] try: if int(dialog.properties['centered']): ret.append('self.Centre()\n') except (KeyError, ValueError): pass return ret # end of class PythonCodeGenerator class CppCodeGenerator: constructor = [('wxWindow*', 'parent'), ('int', 'id'), ('const wxString&', 'title'), ('const wxPoint&', 'pos', 'wxDefaultPosition'), ('const wxSize&', 'size', 'wxDefaultSize'), ('long', 'style', 'wxDEFAULT_DIALOG_STYLE')] def get_code(self, obj): return [], [], [], [] def get_properties_code(self, dialog): """\ generates the code for the various wxDialog specific properties. Returns a list of strings containing the generated code """ prop = dialog.properties cppgen = common.code_writers['C++'] out = [] title = prop.get('title') if title: out.append('SetTitle(%s);\n' % cppgen.quote_str(title)) icon = prop.get('icon') if icon: out.append('wxIcon _icon;\n') if icon.startswith('var:'): out.append('_icon.CopyFromBitmap(wxBitmap(' + '%s, wxBITMAP_TYPE_ANY));\n' % \ icon[4:].strip()) elif icon.startswith('code:'): out.append('_icon.CopyFromBitmap(%s);\n' % \ icon[5:].strip()) else: out.append('_icon.CopyFromBitmap(wxBitmap(%s, ' 'wxBITMAP_TYPE_ANY));\n' % \ cppgen.quote_str(icon, False, False)) out.append('SetIcon(_icon);\n') out.extend(cppgen.generate_common_properties(dialog)) return out def get_layout_code(self, dialog): ret = ['Layout();\n'] try: if int(dialog.properties['centered']): ret.append('Centre();\n') except (KeyError, ValueError): pass return ret # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class DialogXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, ntabs): if name != 'sizehints': xrcgen.DefaultXrcObject.write_property( self, name, val, outfile, ntabs) # end of class DialogXrcObject return DialogXrcObject(obj) def initialize(): cn = common.class_names cn['EditDialog'] = 'wxDialog' common.toplevels['EditDialog'] = 1 pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxDialog', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxDialog', CppCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxDialog', xrc_code_generator) wxglade-0.6.8.orig/widgets/dialog/dialog.py0000644000175000017500000003263712161625061021046 0ustar georgeskgeorgesk# dialog.py: wxDialog objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, math, misc from tree import Tree from widget_properties import * from edit_windows import TopLevelBase class EditDialog(TopLevelBase): def __init__(self, name, parent, id, title, property_window, style=wx.DEFAULT_DIALOG_STYLE, show=True, klass='wxDialog'): TopLevelBase.__init__(self, name, klass, parent, id, property_window, show=show, title=title) self.base = 'wxDialog' self.style = style prop = self.properties # style property self.access_functions['style'] = (self.get_style, self.set_style) style_labels = ('#section#' + _('Style'), 'wxDEFAULT_DIALOG_STYLE', 'wxDIALOG_MODAL', 'wxCAPTION', 'wxRESIZE_BORDER', 'wxSYSTEM_MENU') style_labels += ('wxCLOSE_BOX', 'wxMAXIMIZE_BOX', 'wxMINIMIZE_BOX') style_labels += ('wxTHICK_FRAME', 'wxSTAY_ON_TOP', 'wxNO_3D', 'wxDIALOG_NO_PARENT', 'wxNO_FULL_REPAINT_ON_RESIZE', 'wxFULL_REPAINT_ON_RESIZE', 'wxCLIP_CHILDREN') #note that the tooltips are only for wxPython>=2.5 self.tooltips = (_("Equivalent to a combination of wxCAPTION, " "wxCLOSE_BOX and wxSYSTEM_MENU " "(the last one is not used under Unix)"), _("NO DESCRIPTION"), _("Puts a caption on the dialog box."), _("Display a resizeable frame around the window."), _("Display a system menu."), _("Displays a close box on the frame."), _("Displays a maximize box on the dialog."), _("Displays a minimize box on the dialog."), _("Display a thick frame around the window."), _("The dialog stays on top of all other windows."), _("Under Windows, specifies that the child controls should " "not have 3D borders unless specified in the control."), _("By default, a dialog created with a NULL parent window " "will be given the application's top level window as parent. " "Use this style to prevent this from happening and create " "an orphan dialog. " "This is not recommended for modal dialogs."), _("NO DESCRIPTION"), _("NO DESCRIPTION"), _("NO DESCRIPTION")) self.style_pos = (wx.DEFAULT_DIALOG_STYLE, wx.DIALOG_MODAL, wx.CAPTION, wx.RESIZE_BORDER, wx.SYSTEM_MENU) self.style_pos += (wx.CLOSE_BOX, wx.MAXIMIZE_BOX, wx.MINIMIZE_BOX) self.style_pos += (wx.THICK_FRAME, wx.STAY_ON_TOP, wx.NO_3D, wx.DIALOG_NO_PARENT, wx.NO_FULL_REPAINT_ON_RESIZE, wx.FULL_REPAINT_ON_RESIZE, wx.CLIP_CHILDREN) prop['style'] = CheckListProperty(self, 'style', None, style_labels, tooltips=self.tooltips) # icon property self.icon = "" self.access_functions['icon'] = (self.get_icon, self.set_icon) prop['icon'] = FileDialogProperty(self, 'icon', None, style=wx.OPEN|wx.FILE_MUST_EXIST, can_disable=True, label=_("icon")) # centered property self.centered = False self.access_functions['centered'] = (self.get_centered, self.set_centered) prop['centered'] = CheckBoxProperty(self, 'centered', None, label=_("centered")) # size hints property self.sizehints = False self.access_functions['sizehints'] = (self.get_sizehints, self.set_sizehints) prop['sizehints'] = CheckBoxProperty(self, 'sizehints', None, label=_('Set Size Hints')) def create_widget(self): if self.parent: w = self.parent.widget else: w = common.palette # we set always a default style because this is the best one for # editing the dialog (for example, a dialog without a caption would # be hard to move, etc.) default_style = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER # change 2002-10-09: now we create a wxFrame instead of a wxDialog, # because the latter gives troubles I wasn't able to solve when using # wxPython 2.3.3.1 :-/ self.widget = wx.Frame(w, self.id, "", style=default_style) self.widget.SetBackgroundColour(wx.SystemSettings_GetColour( wx.SYS_COLOUR_BTNFACE)) self.set_icon(self.icon) def finish_widget_creation(self): TopLevelBase.finish_widget_creation(self) if not self.properties['size'].is_active(): self.widget.SetSize((400, 300)) def create_properties(self): TopLevelBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) szr = wx.BoxSizer(wx.VERTICAL) self.properties['title'].display(panel) self.properties['icon'].display(panel) self.properties['centered'].display(panel) self.properties['style'].display(panel) szr.Add(self.properties['title'].panel, 0, wx.EXPAND) szr.Add(self.properties['icon'].panel, 0, wx.EXPAND) szr.Add(self.properties['centered'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') w, h = panel.GetClientSizeTuple() panel.SetScrollbars(5, 5, int(math.ceil(w/5.0)), int(math.ceil(h/5.0))) def get_style(self): retval = [0] * len(self.style_pos) style = self.style try: default = 0 if style & wx.DEFAULT_DIALOG_STYLE == wx.DEFAULT_DIALOG_STYLE: default = 1 style = style & ~wx.DEFAULT_DIALOG_STYLE for i in range(len(self.style_pos)): if style & self.style_pos[i]: retval[i] = 1 retval[0] = default except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_icon(self): return self.icon def set_icon(self, value): self.icon = value.strip() if self.widget: if self.icon and not (self.icon.startswith('var:') or self.icon.startswith('code:')): icon = misc.get_relative_path(self.icon) bmp = wx.Bitmap(icon, wx.BITMAP_TYPE_ANY) if not bmp.Ok(): self.set_icon("") else: icon = wx.EmptyIcon() icon.CopyFromBitmap(bmp) self.widget.SetIcon(icon) else: import os icon = wx.EmptyIcon() xpm = os.path.join(common.icons_path, 'dialog.xpm') icon.CopyFromBitmap(misc.get_xpm_bitmap(xpm)) self.widget.SetIcon(icon) def get_centered(self): return self.centered def set_centered(self, value): try: self.centered = bool(int(value)) except ValueError: pass def get_sizehints(self): return self.sizehints def set_sizehints(self, value): try: self.sizehints = bool(int(value)) except ValueError: pass # end of class EditDialog def builder(parent, sizer, pos, number=[0]): """\ factory function for EditDialog objects. """ try: import panel has_panel = True except ImportError: has_panel = False class Dialog(wx.Dialog): def __init__(self): if has_panel: title = 'Select widget type' else: title = 'Select dialog class' wx.Dialog.__init__(self, None, -1, title) if common.app_tree.app.get_language().lower() == 'xrc': self.klass = 'wxDialog' else: if not number[0]: self.klass = 'MyDialog' else: self.klass = 'MyDialog%s' % number[0] number[0] += 1 self.klass_prop = TextProperty(self, 'class', None) #self) self.widget = 0 szr = wx.BoxSizer(wx.VERTICAL) if has_panel: widget_prop = RadioProperty(self, 'widget', self, ['wxDialog', 'wxPanel']) szr.Add(widget_prop.panel, 0, wx.ALL|wx.EXPAND, 5) self.klass_prop.display(self) szr.Add(self.klass_prop.panel, 0, wx.ALL|wx.EXPAND, 5) btnbox = wx.BoxSizer(wx.HORIZONTAL) btnOK = wx.Button(self, wx.ID_OK, _('OK')) btnCANCEL = wx.Button(self, wx.ID_CANCEL, _('Cancel')) btnbox.Add(btnOK, 0, wx.ALL, 3) btnbox.Add(btnCANCEL, 0, wx.ALL, 3) btnOK.SetFocus() szr.Add(btnbox, 0, wx.ALL|wx.ALIGN_CENTER, 3) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) if self.GetSize()[0] < 150: self.SetSize((150, -1)) self.klass_modified = False self.CenterOnScreen() def undo(self): if number[0] > 0: number[0] -= 1 def set_klass(self, c): self.klass = c self.klass_modified = True def set_widget(self, c): self.widget = int(c) if not self.klass_modified: try: number = str(int(self.klass[-1])) except ValueError: number = '' if common.app_tree.app.get_language().lower() == 'xrc': if self.widget == 0: self.klass = 'wxDialog' else: self.klass = 'wxPanel' else: if self.widget == 0: self.klass = 'MyDialog' + number else: self.klass = 'MyPanel' + number self.klass_prop.set_value(self.klass) def __getitem__(self, value): if value == 'class': return (lambda : self.klass, self.set_klass) else: return (lambda : self.widget, self.set_widget) # end of inner class class_dialog = Dialog() # Check if the user hit Cancel, if so then bail out if class_dialog.ShowModal() == wx.ID_CANCEL: # restore state class_dialog.undo() # clean up resources class_dialog.Destroy() return if class_dialog.widget == 0: name = 'dialog' else: name = 'panel' label = '%s_%d' % (name, (number[0] or 1)) while common.app_tree.has_name(label): number[0] += 1 label = '%s_%d' % (name, number[0]) if class_dialog.widget == 0: is_panel = False dialog = EditDialog(label, parent, wx.NewId(), label, common.property_panel, klass=class_dialog.klass) else: is_panel = True import panel dialog = panel.EditTopLevelPanel(label, parent, wx.NewId(), common.property_panel, klass=class_dialog.klass) node = Tree.Node(dialog) dialog.node = node dialog.show_widget(True) common.app_tree.add(node) class_dialog.Destroy() if wx.Platform == '__WXMSW__': if not is_panel: w = dialog.widget else: w = dialog.widget.GetParent() w.CenterOnScreen() w.Raise() def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditDialog objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") dialog = EditDialog(label, parent, wx.NewId(), "", common.property_panel, show=False, style=0) node = Tree.Node(dialog) dialog.node = node common.app_tree.add(node) return dialog def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ cwx = common.widgets_from_xml cwx['EditDialog'] = xml_builder common.widgets['EditDialog'] = builder return common.make_object_button('EditDialog', 'icons/dialog.xpm', 1, tip='Add a Dialog/Panel') wxglade-0.6.8.orig/widgets/dialog/__init__.py0000644000175000017500000000064411621715605021343 0ustar georgeskgeorgesk# __init__.py: dialog widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:02:00 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import dialog return dialog.initialize() wxglade-0.6.8.orig/widgets/spin_button/0000755000175000017500000000000012170277707020341 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/spin_button/perl_codegen.py0000644000175000017500000000305511646104462023336 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxSpinButton objects # $Id: perl_codegen.py,v 1.2 2005/08/15 07:42:55 crazyinsomniac Exp $ # # Copyright (c) 2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) # value = prop.get('value', '') # try: min_v, max_v = [ s.strip() for s in \ # prop.get('range', '0, 100').split(',') ] # except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = 'wxSP_ARROW_KEYS' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, wxDefaultPosition, \ wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, style)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditSpinButton'] = 'wxSpinButton' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxSpinButton', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/spin_button/lisp_codegen.py0000644000175000017500000000276712150154266023352 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxSpinButton objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 07:00:39 efuzzyone Exp $ # # Copyright (c) 2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) # value = prop.get('value', '') # try: min_v, max_v = [ s.strip() for s in \ # prop.get('range', '0, 100').split(',') ] # except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = 'wxSP_ARROW_KEYS' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxSpinButton_Create %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, style)) props_buf = codegen.generate_common_properties(obj) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditSpinButton'] = 'wxSpinButton' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxSpinButton', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/spin_button/codegen.py0000644000175000017500000000717511621715605022323 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxSpinButton objects # $Id: codegen.py,v 1.2 2004/12/13 18:45:13 agriggio Exp $ # # Copyright (c) 2004 D.H. aka crazyinsomniac at users.sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY # based on wxGlade/widgets/spin_ctrl/ import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) # value = prop.get('value', '') # try: min_v, max_v = [ s.strip() for s in \ # prop.get('range', '0, 100').split(',') ] # except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s %s)\n' % (obj.name, klass, parent, id, style)) props_buf = pygen.generate_common_properties(obj) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class SpinButtonXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'range': try: min, max = val.split(',') except ValueError: pass else: tab_s = ' '*tabs outfile.write(tab_s + '%s\n' % min) outfile.write(tab_s + '%s\n' % max) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class SpinButtonXrcObject return SpinButtonXrcObject(obj) class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ generates C++ code for wxSpinButton objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] # value = prop.get('value', '') # try: min_v, max_v = [ s.strip() for s in \ # prop.get('range', '0, 100').split(',') ] # except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' style = prop.get('style') if not style: style = 'wxSP_ARROW_KEYS' init = ['%s = new %s(%s, %s, wxDefaultPosition, wxDefaultSize,' ' %s);\n' % (obj.name, obj.klass, parent, id, style)] props_buf = cppgen.generate_common_properties(obj) return init, ids, props_buf, [] def get_events(self, obj): cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxSpinEvent') # end of class CppCodeGenerator def initialize(): common.class_names['EditSpinButton'] = 'wxSpinButton' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxSpinButton', PythonCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxSpinButton', xrc_code_generator) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxSpinButton', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/spin_button/spin_button.py0000644000175000017500000001312511677432015023255 0ustar georgeskgeorgesk# spin_button.py: wxSpinButton objects # # Copyright (c) 2004 D.H. aka crazyinsomniac at users.sourceforge.net # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY # # based on wxGlade/widgets/spin_ctrl/ import wx from edit_windows import ManagedBase from tree import Tree import common from widget_properties import * class EditSpinButton(ManagedBase): """\ Class to handle wxSpinButton objects """ events = ['EVT_SPIN', 'EVT_SPIN_UP', 'EVT_SPIN_DOWN'] def __init__(self, name, parent, id, sizer, pos, property_window, show=True): import config ManagedBase.__init__(self, name, 'wxSpinButton', parent, id, sizer, pos, property_window, show=show) self.style = 0 self.value = 0 self.range = (0, 100) # Default values in wxSpinButton constructor. prop = self.properties self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['value'] = (self.get_value, self.set_value) self.access_functions['range'] = (self.get_range, self.set_range) style_labels = ('#section#' + _('Style'), 'wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP') self.style_pos = (wx.SP_HORIZONTAL, wx.SP_VERTICAL, wx.SP_ARROW_KEYS, wx.SP_WRAP) prop['style'] = CheckListProperty(self, 'style', None, style_labels) prop['range'] = TextProperty(self, 'range', None, can_disable=True, label=_("range")) prop['value'] = SpinProperty(self, 'value', None, can_disable=True, label=_("value")) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): try: self.widget = wx.SpinButton(self.parent.widget, self.id , style=self.style) except AttributeError: self.widget = wx.SpinButton(self.parent.widget, self.id ) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) szr = wx.BoxSizer(wx.VERTICAL) prop = self.properties prop['range'].display(panel) prop['value'].display(panel) prop['style'].display(panel) szr.Add(prop['range'].panel, 0, wx.EXPAND) szr.Add(prop['value'].panel, 0, wx.EXPAND) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_range(self): # we cannot return self.range since this would become a "(0, 100)" # string, and we don't want the parens return "%s, %s" % self.range def set_range(self, val): try: min_v, max_v = map(int, val.split(',')) except: self.properties['range'].set_value(self.get_range()) else: self.range = (min_v, max_v) self.properties['value'].set_range(min_v, max_v) if self.widget: self.widget.SetRange(min_v, max_v) def get_value(self): return self.value def set_value(self, value): value = int(value) if self.value != value: self.value = value if self.widget: self.widget.SetValue(self.value) # end of class EditSpinButton def builder(parent, sizer, pos, number=[1]): """\ factory function for EditSpinButton objects. """ name = 'spin_button_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'spin_button_%d' % number[0] text = EditSpinButton(name, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(text) text.node = node text.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory function to build EditSpinButton objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") text = EditSpinButton(name, parent, wx.NewId(), sizer, pos, common.property_panel) sizer.set_item(text.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(text) text.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return text def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditSpinButton'] = builder common.widgets_from_xml['EditSpinButton'] = xml_builder return common.make_object_button('EditSpinButton', 'icons/spinbtn.xpm') wxglade-0.6.8.orig/widgets/spin_button/__init__.py0000644000175000017500000000066111621715605022447 0ustar georgeskgeorgesk# __init__.py: spin ctrl widget module initialization # $Id: __init__.py,v 1.3 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import spin_button return spin_button.initialize() wxglade-0.6.8.orig/widgets/spin_ctrl/0000755000175000017500000000000012170277707017772 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/spin_ctrl/perl_codegen.py0000644000175000017500000000315011646104472022764 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxSpinCtrl objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:43:17 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) value = prop.get('value', '') try: min_v, max_v = [ s.strip() for s in \ prop.get('range', '0, 100').split(',') ] except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = 'wxSP_ARROW_KEYS' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, "%s", wxDefaultPosition, \ wxDefaultSize, %s, %s, %s, %s);\n' % (obj.name, klass, parent, id, value, style, min_v, max_v, value)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditSpinCtrl'] = 'wxSpinCtrl' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxSpinCtrl', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/spin_ctrl/lisp_codegen.py0000644000175000017500000000302512150154266022767 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxSpinCtrl objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 07:00:42 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) value = prop.get('value', '') try: min_v, max_v = [ s.strip() for s in \ prop.get('range', '0, 100').split(',') ] except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = 'wxSP_ARROW_KEYS' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxSpinCtrl_Create %s %s %s -1 -1 -1 -1 %s %s %s %s))\n' % (obj.name, parent, id, value, style, min_v, max_v, value)) props_buf = codegen.generate_common_properties(obj) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditSpinCtrl'] = 'wxSpinCtrl' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxSpinCtrl', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/spin_ctrl/codegen.py0000644000175000017500000000725012072605532021744 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxSpinCtrl objects # $Id: codegen.py,v 1.15 2007/03/27 07:01:53 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) value = prop.get('value', '') try: min_v, max_v = [ s.strip() for s in \ prop.get('range', '0, 100').split(',') ] except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, "%s", min=%s, max=%s%s)\n' % (obj.name, klass, parent, id, value, min_v, max_v, style)) props_buf = pygen.generate_common_properties(obj) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class SpinCtrlXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'range': try: min, max = val.split(',') except ValueError: pass else: tab_s = ' '*tabs outfile.write(tab_s + '%s\n' % min) outfile.write(tab_s + '%s\n' % max) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class SpinCtrlXrcObject return SpinCtrlXrcObject(obj) class CppCodeGenerator: extra_headers = [''] def get_code(self, obj): """\ generates C++ code for wxSpinCtrl objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] value = prop.get('value', '') try: min_v, max_v = [ s.strip() for s in \ prop.get('range', '0, 100').split(',') ] except: min_v, max_v = '0', '100' if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' style = prop.get('style') if not style: style = 'wxSP_ARROW_KEYS' init = ['%s = new %s(%s, %s, wxT("%s"), wxDefaultPosition, ' 'wxDefaultSize, %s, %s, %s);\n' % (obj.name, obj.klass, parent, id, value, style, min_v, max_v)] props_buf = cppgen.generate_common_properties(obj) return init, ids, props_buf, [] def get_events(self, obj): cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxSpinEvent') # end of class CppCodeGenerator def initialize(): common.class_names['EditSpinCtrl'] = 'wxSpinCtrl' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxSpinCtrl', PythonCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxSpinCtrl', xrc_code_generator) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxSpinCtrl', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/spin_ctrl/spin_ctrl.py0000644000175000017500000001414111755504662022343 0ustar georgeskgeorgesk# spin_ctrl.py: wxSpinCtrl objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx from edit_windows import ManagedBase from tree import Tree import common from widget_properties import * class EditSpinCtrl(ManagedBase): """\ Class to handle wxSpinCtrl objects """ events = ['EVT_SPINCTRL'] def __init__(self, name, parent, id, sizer, pos, property_window, show=True): import config ManagedBase.__init__(self, name, 'wxSpinCtrl', parent, id, sizer, pos, property_window, show=show) self.style = 0 self.value = 0 self.range = (0, 100) # Default values in wxSpinCtrl constructor. prop = self.properties self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['value'] = (self.get_value, self.set_value) self.access_functions['range'] = (self.get_range, self.set_range) style_labels = ('#section#' + _('Style'), 'wxSP_ARROW_KEYS', 'wxSP_WRAP', 'wxTE_PROCESS_ENTER', 'wxTE_PROCESS_TAB', 'wxTE_MULTILINE', 'wxTE_PASSWORD', 'wxTE_READONLY', 'wxHSCROLL', 'wxTE_RICH', 'wxTE_RICH2', 'wxTE_AUTO_URL', 'wxTE_NOHIDESEL', 'wxTE_CENTRE', 'wxTE_RIGHT', 'wxTE_LINEWRAP', 'wxTE_WORDWRAP', 'wxNO_BORDER') self.style_pos = (wx.SP_ARROW_KEYS, wx.SP_WRAP, wx.TE_PROCESS_ENTER, wx.TE_PROCESS_TAB, wx.TE_MULTILINE,wx.TE_PASSWORD, wx.TE_READONLY, wx.HSCROLL, wx.TE_RICH, wx.TE_RICH2, wx.TE_AUTO_URL, wx.TE_NOHIDESEL, wx.TE_CENTRE, wx.TE_RIGHT, wx.TE_LINEWRAP, wx.TE_WORDWRAP, wx.NO_BORDER) prop['style'] = CheckListProperty(self, 'style', None, style_labels) prop['range'] = TextProperty(self, 'range', None, can_disable=True, label=_("range")) prop['value'] = SpinProperty(self, 'value', None, can_disable=True, label=_("value")) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = wx.SpinCtrl(self.parent.widget, self.id, min=self.range[0], max=self.range[1], initial=self.value) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) szr = wx.BoxSizer(wx.VERTICAL) prop = self.properties prop['range'].display(panel) prop['value'].display(panel) prop['style'].display(panel) szr.Add(prop['range'].panel, 0, wx.EXPAND) szr.Add(prop['value'].panel, 0, wx.EXPAND) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_range(self): # we cannot return self.range since this would become a "(0, 100)" # string, and we don't want the parens return "%s, %s" % self.range def set_range(self, val): try: min_v, max_v = map(int, val.split(',')) except: self.properties['range'].set_value(self.get_range()) else: self.range = (min_v, max_v) self.properties['value'].set_range(min_v, max_v) if self.widget: self.widget.SetRange(min_v, max_v) def get_value(self): return self.value def set_value(self, value): value = int(value) if self.value != value: self.value = value if self.widget: self.widget.SetValue(self.value) # end of class EditSpinCtrl def builder(parent, sizer, pos, number=[1]): """\ factory function for EditSpinCtrl objects. """ name = 'spin_ctrl_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'spin_ctrl_%d' % number[0] text = EditSpinCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(text) text.node = node text.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory function to build EditSpinCtrl objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") text = EditSpinCtrl(name, parent, wx.NewId(), sizer, pos, common.property_panel) sizer.set_item(text.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(text) text.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return text def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditSpinCtrl'] = builder common.widgets_from_xml['EditSpinCtrl'] = xml_builder return common.make_object_button('EditSpinCtrl', 'icons/spin_ctrl.xpm') wxglade-0.6.8.orig/widgets/spin_ctrl/__init__.py0000644000175000017500000000065511621715605022103 0ustar georgeskgeorgesk# __init__.py: spin ctrl widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import spin_ctrl return spin_ctrl.initialize() wxglade-0.6.8.orig/widgets/hyperlink_ctrl/0000755000175000017500000000000012170277707021026 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/hyperlink_ctrl/perl_codegen.py0000644000175000017500000000377312150154266024030 0ustar georgeskgeorgesk""" Perl code generator functions for wxHyperlinkCtrl objects @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import common class PerlCodeGenerator: supported_by = ((2, 8), (3, 0),) """\ wxHyperlinkCtrl is only available at wx 2.8 and newer """ def get_code(self, obj): init = [] plgen = common.code_writers['perl'] prop = obj.properties attribute = plgen.test_attribute(obj) id_name, id = plgen.generate_code_id(obj) label = plgen.quote_str(prop.get('label', '')) url = plgen.quote_str(prop.get('url', '')) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' if id_name: init.append(id_name) if attribute: prefix = '$self->{%s}' % obj.name else: prefix = 'my $%s' % obj.name obj.name = '$' + obj.name klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = plgen.cn(klass) init.append('%s = %s->new(%s, %s, %s, %s, wxDefaultPosition, ' 'wxDefaultSize, %s);\n' % ( prefix, klass, parent, id, label, url, style ) ) props_buf = plgen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditHyperlinkCtrl'] = 'wxHyperlinkCtrl' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxHyperlinkCtrl', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/hyperlink_ctrl/lisp_codegen.py0000644000175000017500000000344512150154266024031 0ustar georgeskgeorgesk""" Lisp code generator functions for wxHyperlinkCtrl objects @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import common class LispCodeGenerator: supported_by = ((2, 8), (3, 0),) """\ wxHyperlinkCtrl is only available at wx 2.8 and newer """ def get_code(self, obj): init = [] codegen = common.code_writers['lisp'] prop = obj.properties attribute = codegen.test_attribute(obj) id_name, id = codegen.generate_code_id(obj) label = codegen.quote_str(prop.get('label', '')) url = codegen.quote_str(prop.get('url', '')) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxHyperlinkCtrl %s %s %s ' '%s -1 -1 -1 -1 %s))\n' % ( obj.name, parent, id, label, url, style ) ) props_buf = codegen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditHyperlinkCtrl'] = 'wxHyperlinkCtrl' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxHyperlinkCtrl', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/hyperlink_ctrl/hyperlink_ctrl.py0000644000175000017500000001547712150154266024437 0ustar georgeskgeorgesk""" wxHyperlinkCtrl objects @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import wx import common import misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditHyperlinkCtrl(ManagedBase): events = [ 'EVT_HYPERLINK', ] supported_by = ((2, 8), (3, 0),) """\ wxHyperlinkCtrl is only available at wx 2.8 and newer """ def __init__(self, name, parent, id, label, sizer, pos, property_window, show=True): """\ Class to handle wxHyperlinkCtrl objects """ import config ManagedBase.__init__(self, name, 'wxHyperlinkCtrl', parent, id, sizer, pos, property_window, show=show) self.attribute = True self.label = label self.style = 0 self.url = "" self.access_functions['label'] = (self.get_label, self.set_label) self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['url'] = (self.get_url, self.set_url) self.access_functions['attribute'] = (self.get_attribute, self.set_attribute) self.properties['label'] = TextProperty( self, 'label', None, multiline=False, label=_('label') ) self.properties['label'].set_tooltip( _("Label of the hyperlink") ) self.properties['url'] = TextProperty( self, 'url', None, multiline=False, label=_('url') ) self.properties['url'].set_tooltip( _("URL associated with the given label") ) self.style_pos = ( wx.HL_ALIGN_LEFT, wx.HL_ALIGN_RIGHT, wx.HL_ALIGN_CENTRE, wx.HL_CONTEXTMENU, wx.HL_DEFAULT_STYLE, ) style_labels = ( '#section#' + _('Style'), 'wxHL_ALIGN_LEFT', 'wxHL_ALIGN_RIGHT', 'wxHL_ALIGN_CENTRE', 'wxHL_CONTEXTMENU', 'wxHL_DEFAULT_STYLE', ) self.properties['style'] = CheckListProperty(self, 'style', None, style_labels) self.properties['attribute'] = CheckBoxProperty( self, 'attribute', None, _('Store as attribute'), write_always=True ) if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL def create_widget(self): self.widget = wx.HyperlinkCtrl( self.parent.widget, self.id, self.label.replace('\\n', '\n'), self.url, ) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) self.properties['label'].display(panel) self.properties['style'].display(panel) self.properties['url'].display(panel) self.properties['attribute'].display(panel) szr.Add(self.properties['label'].panel, 0, wx.EXPAND) szr.Add(self.properties['url'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) szr.Add(self.properties['attribute'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, _('Widget')) def get_attribute(self): return self.attribute def set_attribute(self, value): self.attribute = int(value) def get_label(self): return self.label def set_label(self, value): value = misc.wxstr(value) if not misc.streq(value, self.label): self.label = value if self.widget: self.widget.SetLabel(value.replace('\\n', '\n')) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_url(self): return self.url def set_url(self, url): self.url = url # end of class EditHyperlinkCtrl def builder(parent, sizer, pos, number=[1]): """\ factory function for EditHyperlinkCtrl objects. """ name = 'hyperlink_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'hyperlink_%d' % number[0] hyperlink_ctrl = EditHyperlinkCtrl(name, parent, wx.NewId(), misc._encode(name), sizer, pos, common.property_panel) node = Tree.Node(hyperlink_ctrl) hyperlink_ctrl.node = node hyperlink_ctrl.show_widget(True) common.app_tree.insert(node, sizer.node, pos - 1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditHyperlinkCtrl objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError(_("'name' attribute missing")) if sizer is None or sizeritem is None: raise XmlParsingError(_("sizer or sizeritem object cannot be None")) hyperlink_ctrl = EditHyperlinkCtrl(name, parent, wx.NewId(), "", sizer, pos, common.property_panel) sizer.set_item(hyperlink_ctrl.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(hyperlink_ctrl) hyperlink_ctrl.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos - 1) return hyperlink_ctrl def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditHyperlinkCtrl'] = builder common.widgets_from_xml['EditHyperlinkCtrl'] = xml_builder return common.make_object_button( 'EditHyperlinkCtrl', 'icons/hyperlink_ctrl.xpm' ) wxglade-0.6.8.orig/widgets/hyperlink_ctrl/codegen.py0000644000175000017500000000746012150154266023003 0ustar georgeskgeorgesk""" Code generator functions for wxHyperlinkCtrl objects @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import common class PythonCodeGenerator: supported_by = ((2, 8), (3, 0),) """\ wxHyperlinkCtrl is only available at wx 2.8 and newer """ def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties attribute = pygen.test_attribute(obj) id_name, id = pygen.generate_code_id(obj) label = pygen.quote_str(prop.get('label', '')) url = pygen.quote_str(prop.get('url', '')) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) if attribute: prefix = 'self.' else: prefix = '' klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('%s%s = %s(%s, %s, %s, %s%s)\n' % (prefix, obj.name, klass, parent, id, label, url, style)) props_buf = pygen.generate_common_properties(obj) if not attribute: # the object doesn't have to be stored as an attribute of the # custom class, but it is just considered part of the layout return [], [], init + props_buf return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: extra_headers = [''] supported_by = ((2, 8), (3, 0),) """\ wxHyperlinkCtrl is only available at wx 2.8 and newer """ def get_code(self, obj): """\ generates the C++ code for wxHyperlinkCtrl objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [id_name] else: ids = [] attribute = cppgen.test_attribute(obj) label = cppgen.quote_str(prop.get('label', '')) url = cppgen.quote_str(prop.get('url', '')) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style if attribute: prefix = '' else: prefix = '%s* ' % obj.klass init = ['%s%s = new %s(%s, %s, %s, %s%s);\n' % (prefix, obj.name, obj.klass, parent, id, label, url, extra)] props_buf = cppgen.generate_common_properties(obj) if not attribute: return [], ids, [], init + props_buf return init, ids, props_buf, [] # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class XrcCodeGenerator(xrcgen.DefaultXrcObject): def write(self, *args, **kwds): try: del self.properties['attribute'] except KeyError: pass xrcgen.DefaultXrcObject.write(self, *args, **kwds) return XrcCodeGenerator(obj) def initialize(): common.class_names['EditHyperlinkCtrl'] = 'wxHyperlinkCtrl' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxHyperlinkCtrl', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxHyperlinkCtrl', CppCodeGenerator()) xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxHyperlinkCtrl', xrc_code_generator) wxglade-0.6.8.orig/widgets/hyperlink_ctrl/__init__.py0000644000175000017500000000055012150154266023127 0ustar georgeskgeorgesk""" HyperlinkCtrl widget module initialization @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ def initialize(): import common import codegen codegen.initialize() if common.use_gui: import hyperlink_ctrl return hyperlink_ctrl.initialize() wxglade-0.6.8.orig/widgets/spacer/0000755000175000017500000000000012170277707017252 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/spacer/perl_codegen.py0000644000175000017500000000147011621715605022246 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for spacers # $Id: perl_codegen.py,v 1.2 2004/09/17 13:09:50 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, spacer): prop = spacer.properties width = prop.get('width', '0') height = prop.get('height', '0') # we must use the hack in plgen.add_sizeritem (see pl_codegen.py) spacer.name = '%s, %s' % (width, height) return [], [], [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditSpacer'] = 'spacer' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('spacer', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/spacer/lisp_codegen.py0000644000175000017500000000147011621715605022253 0ustar georgeskgeorgesk # lisp_codegen.py : lisp generator functions for spacers # $Id: lisp_codegen.py,v 1.2 2007/02/09 22:24:06 dinogen Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, spacer): prop = spacer.properties width = prop.get('width', '0') height = prop.get('height', '0') # we must use the hack in plgen.add_sizeritem (see pl_codegen.py) spacer.name = '%s, %s' % (width, height) return [], [], [] # end of class LispCodeGenerator def initialize(): common.class_names['EditSpacer'] = 'spacer' plgen = common.code_writers.get('lisp') if plgen: plgen.add_widget_handler('spacer', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/spacer/codegen.py0000644000175000017500000000261111621715605021222 0ustar georgeskgeorgesk# codegen.py: code generator functions for spacers # $Id: codegen.py,v 1.9 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, spacer): prop = spacer.properties width = prop.get('width', '0') height = prop.get('height', '0') # we must use the hack in pygen.add_sizeritem (see py_codegen.py) spacer.name = '%s, %s' % (width, height) return [], [], [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, spacer): """\ generates the C++ code for a spacer """ prop = spacer.properties width = prop.get('width', '0') height = prop.get('height', '0') # we must use the hack in cppgen.add_sizeritem (see cpp_codegen.py) spacer.name = '%s, %s' % (width, height) return [], [], [], [] # end of class CppCodeGenerator def initialize(): common.class_names['EditSpacer'] = 'spacer' # python code generation functions pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('spacer', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('spacer', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/spacer/spacer.py0000644000175000017500000001407012150154266021073 0ustar georgeskgeorgesk# spacer.py: spacers to use in sizers # $Id: spacer.py,v 1.13 2007/08/07 12:18:34 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from tree import Tree from widget_properties import * from edit_windows import ManagedBase class EditSpacer(ManagedBase): def __init__(self, name, parent, id, width, height, sizer, pos, property_window, show=True): """\ Class to handle spacers for sizers """ ManagedBase.__init__(self, name, 'spacer', parent, id, sizer, pos, property_window, show=show) self.__size = [width, height] self.access_functions['width'] = (self.get_width, self.set_width) self.access_functions['height'] = (self.get_height, self.set_height) self.properties['width'] = SpinProperty(self, 'width', None, label=_("width")) self.properties['height'] = SpinProperty(self, 'height', None, label=_("height")) def create_widget(self): self.widget = wx.Window(self.parent.widget, self.id, size=self.__size, style=wx.SIMPLE_BORDER) self.widget.GetBestSize = self.widget.GetSize wx.EVT_PAINT(self.widget, self.on_paint) def create_properties(self): ManagedBase.create_properties(self) page = self.notebook.GetPage(1) wp = self.properties['width'] hp = self.properties['height'] wp.display(page) hp.display(page) szr = page.GetSizer() szr.Insert(0, hp.panel, 0, wx.EXPAND) szr.Insert(0, wp.panel, 0, wx.EXPAND) szr.Layout() szr.Fit(page) import math w, h = page.GetClientSize() page.SetScrollbars(1, 5, 1, int(math.ceil(h/5.0))) common_page = self.notebook.GetPage(0) common_page.Hide() self.notebook.RemovePage(0) self.notebook.SetSelection(0) def get_width(self): return self.__size[0] def get_height(self): return self.__size[1] def set_width(self, value): value = int(value) self.__size[0] = value if self.widget: self.widget.SetSize(self.__size) self.sizer.set_item(self.pos, size=self.__size) def set_height(self, value): value = int(value) self.__size[1] = value if self.widget: self.widget.SetSize(self.__size) self.sizer.set_item(self.pos, size=self.__size) def set_flag(self, value): ManagedBase.set_flag(self, value) if not (self.get_int_flag() & wx.EXPAND): self.sizer.set_item(self.pos, size=self.__size) def on_paint(self, event): dc = wx.PaintDC(self.widget) dc.BeginDrawing() brush = wx.TheBrushList.FindOrCreateBrush( self.widget.GetBackgroundColour()) dc.SetBrush(brush) dc.SetPen(wx.ThePenList.FindOrCreatePen(wx.BLACK, 1, wx.SOLID)) dc.SetBackground(brush) dc.Clear() w, h = self.widget.GetClientSize() dc.DrawLine(0, 0, w, h) dc.DrawLine(w, 0, 0, h) text = _('Spacer') tw, th = dc.GetTextExtent(text) x = (w - tw)/2 y = (h - th)/2 dc.SetPen(wx.ThePenList.FindOrCreatePen(wx.BLACK, 0, wx.TRANSPARENT)) dc.DrawRectangle(x-1, y-1, tw+2, th+2) dc.DrawText(text, x, y) dc.EndDrawing() # end of class EditSpacer def builder(parent, sizer, pos): """\ factory function for EditSpacer objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, misc.get_toplevel_parent(parent), -1, _("Enter size")) self.width = SpinProperty(self, 'width', self, label=_("width")) self.height = SpinProperty(self, 'height', self, label=_("height")) self.width.set_value(20) self.width.spin.SetFocus() self.width.spin.SetSelection(-1, -1) self.height.set_value(20) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.width.panel, 0, wx.EXPAND) szr.Add(self.height.panel, 0, wx.EXPAND) sz = wx.BoxSizer(wx.HORIZONTAL) sz.Add(wx.Button(self, wx.ID_OK, _('OK'))) szr.Add(sz, 0, wx.ALL|wx.ALIGN_CENTER, 4) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def __getitem__(self, name): return (lambda : 0, lambda v: None) # end of inner class dialog = Dialog() dialog.ShowModal() name = 'spacer' spacer = EditSpacer(name, parent, wx.NewId(), dialog.width.get_value(), dialog.height.get_value(), sizer, pos, common.property_panel) node = Tree.Node(spacer) spacer.node = node spacer.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) #sizer.set_item(spacer.pos, size=spacer.GetSize()) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditSpacer objects from an xml file """ from xml_parse import XmlParsingError if not sizer or not sizeritem: raise XmlParsingError, _("sizer or sizeritem object cannot be None") spacer = EditSpacer('spacer', parent, wx.NewId(), 1, 1, sizer, pos, common.property_panel, True) sizer.set_item(spacer.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(spacer) spacer.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return spacer def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['EditSpacer'] = builder common.widgets_from_xml['EditSpacer'] = xml_builder return common.make_object_button('EditSpacer', 'icons/spacer.xpm') wxglade-0.6.8.orig/widgets/spacer/__init__.py0000644000175000017500000000064411621715605021361 0ustar georgeskgeorgesk# __init__.py: spacer widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import spacer return spacer.initialize() wxglade-0.6.8.orig/widgets/MenuTree.py0000644000175000017500000000612111621715605020065 0ustar georgeskgeorgesk# MenuTree.py: A class to represent a menu on a wxMenuBar # $Id: MenuTree.py,v 1.12 2007/03/27 07:02:05 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY class MenuTree: """\ A class to represent a menu on a wxMenuBar """ class Node: def __init__(self, label="", id="", name="", help_str="", checkable="", radio="", handler=""): self.label = label self.id = id self.name = name self.help_str = help_str self.checkable = checkable self.radio = radio self.handler = handler self.children = [] self.parent = None def write(self, outfile, tabs, top=False): from xml.sax.saxutils import escape, quoteattr import common fwrite = outfile.write tstr = ' ' * (tabs+1) label = common._encode_to_xml(self.label) help_str = common._encode_to_xml(self.help_str) if not top and not self.children: fwrite('%s\n' % (' ' * tabs)) label = escape(label) if label: fwrite('%s\n' % (tstr, label)) id = escape(self.id) if id: fwrite('%s%s\n' % (tstr, id)) name = escape(self.name) if name: fwrite('%s%s\n' % (tstr, name)) help_str = escape(help_str) if help_str: fwrite('%s%s\n' % (tstr, help_str)) try: checkable = int(self.checkable) except: checkable = 0 if checkable: fwrite('%s%s\n' % (tstr, checkable)) try: radio = int(self.radio) except: radio = 0 if radio: fwrite('%s%s\n' % (tstr, radio)) # ALB 2004-12-05 handler = escape(self.handler.strip()) if handler: fwrite('%s%s\n' % (tstr, handler)) fwrite('%s\n' % (' ' * tabs)) else: name = quoteattr(self.name) fwrite(' ' * tabs + '\n' % (quoteattr(label))) for c in self.children: c.write(outfile, tabs+1) fwrite(' ' * tabs + '\n') #end of class Node def __init__(self, name, label, id="", help_str="", handler=""): self.root = self.Node(label, id, name, help_str, handler=handler) def write(self, outfile, tabs): self.root.write(outfile, tabs, top=True) #end of class MenuTree wxglade-0.6.8.orig/widgets/widgets.txt0000644000175000017500000000066512150154266020203 0ustar georgeskgeorgesk# list of widget modules available (one per line, without extension) # lines starting with a '#' are comments frame dialog panel splitter_window notebook button toggle_button bitmap_button spin_button text_ctrl spin_ctrl slider gauge static_text checkbox radio_button radio_box choice combo_box list_box calendar_ctrl datepicker_ctrl static_line static_bitmap list_ctrl tree_ctrl grid custom_widget menubar toolbar spacer hyperlink_ctrl wxglade-0.6.8.orig/widgets/bitmap_button/0000755000175000017500000000000012170277707020644 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/bitmap_button/perl_codegen.py0000644000175000017500000000643411677431621023651 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxBitmapButton objects # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common #this should be in common _bmp_str_types = { '.bmp' : 'wxBITMAP_TYPE_BMP', '.gif' : 'wxBITMAP_TYPE_GIF', '.xpm' : 'wxBITMAP_TYPE_XPM', '.jpg' : 'wxBITMAP_TYPE_JPEG', '.jpeg': 'wxBITMAP_TYPE_JPEG', '.png' : 'wxBITMAP_TYPE_PNG', '.pcx' : 'wxBITMAP_TYPE_PCX' } class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) bmp_file = prop.get('bitmap', '') if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' if not bmp_file: bmp = 'wxNullBitmap' elif bmp_file.startswith('var:'): # this is a variable holding pathname of bitmap var = bmp_file[4:].strip() if var[0] != "$": var = "$" + var bmp = 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY)' % var elif bmp_file.startswith('code:'): # this is a code chunk bmp = '(%s)' % bmp_file[5:].strip() else: bmp = 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY)' % \ plgen.quote_path(bmp_file) init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s);\n' % ( obj.name, klass, parent, id, bmp) ) props_buf = plgen.generate_common_properties(obj) disabled_bmp = prop.get('disabled_bitmap') if disabled_bmp: if disabled_bmp.startswith('var:'): var = disabled_bmp[4:].strip() if var[0] != "$": var = "$" + var props_buf.append( '$self->{%s}->SetBitmapDisabled(' 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY));\n' % (obj.name, var)) elif disabled_bmp.startswith('code:'): var = disabled_bmp[5:].strip() props_buf.append( '$self->{%s}->SetBitmapDisabled(' '%s);\n' % (obj.name, var)) else: props_buf.append( '$self->{%s}->SetBitmapDisabled(' 'Wx::Bitmap->new(%s, wxBITMAP_TYPE_ANY));\n' % \ (obj.name, plgen.quote_path(disabled_bmp))) if not prop.has_key('size'): props_buf.append( '$self->{%s}->SetSize($self->{%s}->GetBestSize());\n' % (obj.name, obj.name) ) if prop.get('default', False): props_buf.append('$self->{%s}->SetDefault();\n' % obj.name) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditBitmapButton'] = 'wxBitmapButton' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxBitmapButton', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/bitmap_button/lisp_codegen.py0000644000175000017500000000611012150154266023637 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxBitmapButton objects # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common #this should be in common _bmp_str_types = { '.bmp' : 'wxBITMAP_TYPE_BMP', '.gif' : 'wxBITMAP_TYPE_GIF', '.xpm' : 'wxBITMAP_TYPE_XPM', '.jpg' : 'wxBITMAP_TYPE_JPEG', '.jpeg': 'wxBITMAP_TYPE_JPEG', '.png' : 'wxBITMAP_TYPE_PNG', '.pcx' : 'wxBITMAP_TYPE_PCX' } class LispCodeGenerator: def get_code(self, obj): plgen = common.code_writers['lisp'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) bmp_file = prop.get('bitmap', '') if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' if not bmp_file: bmp = 'wxNullBitmap' elif bmp_file.startswith('var:'): # this is a variable holding pathname of bitmap var = bmp_file[4:].strip() if var[0] != "$": var = "$" + var bmp = '(wxBitmap_CreateLoad %s wxBITMAP_TYPE_ANY)' % var elif bmp_file.startswith('code:'): # this is a code chunk bmp = '(%s)' % bmp_file[5:].strip() else: bmp = '(wxBitmap_CreateLoad %s, wxBITMAP_TYPE_ANY)' % \ plgen.quote_path(bmp_file) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxBitmapButton_Create %s %s %s -1 -1 -1 -1 0))\n' % ( obj.name, parent, id, bmp)) props_buf = plgen.generate_common_properties(obj) disabled_bmp = prop.get('disabled_bitmap') if disabled_bmp: if disabled_bmp.startswith('var:'): var = disabled_bmp[4:].strip() if var[0] != "$": var = "$" + var props_buf.append( '(wxBitmapButton_SetBitmapDisabled (slot-%s obj) %s)\n' %(obj.name, var)) elif disabled_bmp.startswith('code:'): var = disabled_bmp[5:].strip() props_buf.append( '(wxBitmapButton_SetBitmapDisabled (slot-%s obj) %s)\n' % (obj.name, var)) else: props_buf.append( '(wxBitmapButton_SetBitmapDisabled (slot-%s obj) %s)\n' % (obj.name, plgen.quote_path(disabled_bmp))) if not prop.has_key('size'): props_buf.append('(wxButton_SetDefault (slot-%s obj))\n' %(obj.name)) if prop.get('default', False): props_buf.append('(wxButton_SetDefault (slot-%s obj))\n' %(obj.name)) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditBitmapButton'] = 'wxBitmapButton' plgen = common.code_writers.get('lisp') if plgen: plgen.add_widget_handler('wxBitmapButton', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/bitmap_button/codegen.py0000644000175000017500000001530111676432252022620 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxBitmapButton objects # $Id: codegen.py,v 1.26 2007/08/07 12:18:34 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common, os class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] cn = pygen.cn prop = obj.properties id_name, id = pygen.generate_code_id(obj) bmp_file = prop.get('bitmap', '') bmp_preview_path = os.path.join(common.icons_path, "icon.xpm") if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' if not bmp_file: bmp = cn('wxNullBitmap') elif bmp_file.startswith('var:'): if obj.preview: bmp = "%s('%s', %s)" % (cn('wxBitmap'), bmp_preview_path, cn('wxBITMAP_TYPE_XPM')) else: bmp = (cn('wxBitmap') + '(%s,' + cn('wxBITMAP_TYPE_ANY)')) % \ bmp_file[4:].strip() elif bmp_file.startswith('code:'): if obj.preview: bmp = "%s('%s', %s)" % (cn('wxBitmap'), bmp_preview_path, cn('wxBITMAP_TYPE_XPM')) else: bmp = '(%s)' % \ bmp_file[5:].strip() else: if obj.preview: import misc bmp_file = misc.get_relative_path(bmp_file, True) bmp = (cn('wxBitmap') + '(%s, ' + cn('wxBITMAP_TYPE_ANY') + ')') % pygen.quote_str(bmp_file, False, False) init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = cn(klass) init.append('self.%s = %s(%s, %s, %s%s)\n' % (obj.name, klass, parent, id, bmp,style)) props_buf = pygen.generate_common_properties(obj) disabled_bmp = prop.get('disabled_bitmap') if disabled_bmp: if disabled_bmp.startswith('var:'): if not obj.preview: var = disabled_bmp[4:].strip() props_buf.append( ('self.%s.SetBitmapDisabled(' + cn('wxBitmap') +'(%s,' + cn('wxBITMAP_TYPE_ANY') + '))\n') % (obj.name, var)) elif disabled_bmp.startswith('code:'): if not obj.preview: var = disabled_bmp[5:].strip() props_buf.append( ('self.%s.SetBitmapDisabled(' + '(%s))\n') % \ (obj.name, var)) else: props_buf.append(('self.%s.SetBitmapDisabled(' + cn('wxBitmap') + '(%s, ' + cn('wxBITMAP_TYPE_ANY') + '))\n') % \ (obj.name, pygen.quote_str(disabled_bmp, False, False))) if not prop.has_key('size'): props_buf.append('self.%s.SetSize(self.%s.GetBestSize())\n' % \ (obj.name, obj.name)) if prop.get('default', False): props_buf.append('self.%s.SetDefault()\n' % obj.name) return init, props_buf, [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, obj): """\ fuction that generates C++ code for wxBitmapButton objects. """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] bmp_file = prop.get('bitmap', '') if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style if not bmp_file: bmp = 'wxNullBitmap' elif bmp_file.startswith('var:'): bmp = 'wxBitmap(%s, wxBITMAP_TYPE_ANY)' % bmp_file[4:].strip() elif bmp_file.startswith('code:'): bmp = '(%s)' % bmp_file[5:].strip() else: bmp = 'wxBitmap(%s, wxBITMAP_TYPE_ANY)' % \ cppgen.quote_str(bmp_file, False, False) init = [ '%s = new %s(%s, %s, %s%s);\n' % (obj.name, obj.klass, parent, id, bmp,extra) ] props_buf = cppgen.generate_common_properties(obj) disabled_bmp = prop.get('disabled_bitmap') if disabled_bmp: if disabled_bmp.startswith('var:'): var = disabled_bmp[4:].strip() props_buf.append('%s->SetBitmapDisabled(' 'wxBitmap(%s,wxBITMAP_TYPE_ANY));\n' % (obj.name, var)) elif disabled_bmp.startswith('code:'): var = disabled_bmp[5:].strip() props_buf.append('%s->SetBitmapDisabled(' '(%s));\n' % (obj.name, var)) else: props_buf.append( '%s->SetBitmapDisabled(' 'wxBitmap(%s, wxBITMAP_TYPE_ANY));\n' % \ (obj.name, cppgen.quote_str(disabled_bmp, False, False))) if not prop.has_key('size'): props_buf.append('%s->SetSize(%s->GetBestSize());\n' % \ (obj.name, obj.name)) if prop.get('default', False): props_buf.append('%s->SetDefault();\n' % obj.name) return init, ids, props_buf, [] # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class BitmapButtonXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'disabled_bitmap': name = 'disabled' xrcgen.DefaultXrcObject.write_property( self, name, val, outfile, tabs) # end of class BitmapButtonXrcObject return BitmapButtonXrcObject(obj) def initialize(): common.class_names['EditBitmapButton'] = 'wxBitmapButton' pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxBitmapButton', PythonCodeGenerator()) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxBitmapButton', CppCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxBitmapButton', xrc_code_generator) wxglade-0.6.8.orig/widgets/bitmap_button/bitmap_button.py0000644000175000017500000002025011677431607024066 0ustar georgeskgeorgesk# bitmap_button.py: wxBitmapButton objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common import misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditBitmapButton(ManagedBase): events = ['EVT_BUTTON'] def __init__(self, name, parent, id, bmp_file, sizer, pos, property_window, show=True): """\ Class to handle wxBitmapButton objects """ import config ManagedBase.__init__(self, name, 'wxBitmapButton', parent, id, sizer, pos, property_window, show=show) self.default = False self.set_bitmap(bmp_file) # bitmap property self.access_functions['bitmap'] = (self.get_bitmap, self.set_bitmap) self.properties['bitmap'] = FileDialogProperty(self, 'bitmap', None, style=wx.OPEN | wx.FILE_MUST_EXIST, can_disable=False, label=_("bitmap")) self.access_functions['default'] = (self.get_default, self.set_default) self.access_functions['style'] = (self.get_style, self.set_style) self.properties['default'] = CheckBoxProperty(self, 'default', None, label=_("default")) # 2003-08-07: added 'disabled_bitmap' property self.disabled_bitmap = "" self.access_functions['disabled_bitmap'] = (self.get_disabled_bitmap, self.set_disabled_bitmap) self.properties['disabled_bitmap'] = FileDialogProperty( self, 'disabled_bitmap', None, style=wx.OPEN|wx.FILE_MUST_EXIST, label=_("disabled bitmap")) # 2003-09-04 added default_border if config.preferences.default_border: self.border = config.preferences.default_border_size self.flag = wx.ALL self.style_pos = (wx.BU_AUTODRAW, wx.BU_LEFT, wx.BU_RIGHT, wx.BU_TOP, wx.BU_BOTTOM, wx.NO_BORDER) style_labels = ('#section#' + _('Style'), 'wxBU_AUTODRAW', 'wxBU_LEFT', 'wxBU_RIGHT', 'wxBU_TOP', 'wxBU_BOTTOM', 'wxNO_BORDER') #The tooltips tuple self.tooltips=(_("If this is specified, the button will be drawn " "automatically using the label bitmap only, providing" " a 3D-look border. If this style is not specified, the " "button will be drawn without borders and using all " "provided bitmaps. WIN32 only."), _("Left-justifies the bitmap label. WIN32 only."), _("Right-justifies the bitmap label. WIN32 only."), _("Aligns the bitmap label to the top of the button." " WIN32 only."), _("Aligns the bitmap label to the bottom of the button." " WIN32 only."), _("Creates a flat button. Windows and GTK+ only.")) self.properties['style'] = CheckListProperty(self, 'style', None, style_labels,tooltips=self.tooltips) def create_properties(self): ManagedBase.create_properties(self) panel = wx.Panel(self.notebook, -1) self.properties['bitmap'].display(panel) self.properties['disabled_bitmap'].display(panel) self.properties['default'].display(panel) self.properties['style'].display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.properties['bitmap'].panel, 0, wx.EXPAND) szr.Add(self.properties['disabled_bitmap'].panel, 0, wx.EXPAND) szr.Add(self.properties['default'].panel, 0, wx.EXPAND) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_bitmap(self): return self.bitmap def set_bitmap(self, value): self.bitmap = value if self.widget: bmp = self.load_bitmap() self.widget.SetBitmapLabel(bmp) self.widget.SetBitmapSelected(bmp) self.widget.SetBitmapFocus(bmp) self.set_size("%s, %s" % tuple(self.widget.GetBestSize())) def get_disabled_bitmap(self): return self.disabled_bitmap def set_disabled_bitmap(self, value): self.disabled_bitmap = value if self.widget: bmp = self.load_bitmap(self.disabled_bitmap) self.widget.SetBitmapDisabled(bmp) self.set_size("%s, %s" % tuple(self.widget.GetBestSize())) def create_widget(self): bmp = self.load_bitmap() try: self.widget = wx.BitmapButton(self.parent.widget, self.id, bmp, style=self.style) except AttributeError: self.widget = wx.BitmapButton(self.parent.widget, self.id, bmp) def load_bitmap(self, which=None, empty=[None]): if which is None: which = self.bitmap if which and \ not (which.startswith('var:') or which.startswith('code:')): which = misc.get_relative_path(which) return wx.Bitmap(which, wx.BITMAP_TYPE_ANY) else: if empty[0] is None: empty[0] = wx.EmptyBitmap(1, 1) return empty[0] def get_default(self): return self.default def set_default(self, value): self.default = bool(int(value)) ## if value and self.widget: ## self.widget.SetDefault() # end of class EditBitmapButton def builder(parent, sizer, pos, number=[1]): """\ factory function for EditBitmapButton objects. """ name = 'bitmap_button_%s' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'bitmap_button_%s' % number[0] bitmap = misc.FileSelector(_("Select the image for the button")) button = EditBitmapButton(name, parent, wx.NewId(), bitmap, sizer, pos, common.property_panel) node = Tree.Node(button) button.node = node button.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditBitmapButton objects from an xml file """ from xml_parse import XmlParsingError try: label = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") button = EditBitmapButton(label, parent, wx.NewId(), '', sizer, pos, common.property_panel, show=False) sizer.set_item(button.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) #, size=button.GetBestSize()) node = Tree.Node(button) button.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return button def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditBitmapButton'] = builder common.widgets_from_xml['EditBitmapButton'] = xml_builder return common.make_object_button('EditBitmapButton', 'icons/bitmap_button.xpm') wxglade-0.6.8.orig/widgets/bitmap_button/__init__.py0000644000175000017500000000066211621715605022753 0ustar georgeskgeorgesk# __init__.py: button widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:02:05 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import bitmap_button return bitmap_button.initialize() wxglade-0.6.8.orig/widgets/list_box/0000755000175000017500000000000012170277707017620 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/list_box/perl_codegen.py0000644000175000017500000000327211677431703022623 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxListBox objects # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not style: style = '' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) choices = ', '.join([plgen.quote_str(c) for c in choices]) init.append('$self->{%s} = %s->new(%s, %s, wxDefaultPosition, \ wxDefaultSize, [%s], %s);\n' % (obj.name, klass, parent, id, choices, style)) props_buf = plgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('$self->{%s}->SetSelection(%s);\n' % (obj.name, selection)) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditListBox'] = 'wxListBox' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxListBox', PerlCodeGenerator()) plgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/list_box/list_box.py0000644000175000017500000001656711621715605022026 0ustar georgeskgeorgesk# list_box.py: wxListBox objects # $Id: list_box.py,v 1.22 2007/03/27 07:01:58 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from edit_windows import ManagedBase from tree import Tree from widget_properties import * from ChoicesProperty import * class EditListBox(ManagedBase): events = ['EVT_LISTBOX', 'EVT_LISTBOX_DCLICK'] def __init__(self, name, parent, id, choices, sizer, pos, property_window, show=True): """\ Class to handle wxListBox objects """ ManagedBase.__init__(self, name, 'wxListBox', parent, id, sizer, pos, property_window, show=show) self.selection = 0 self.choices = choices # properties self.access_functions['choices'] = (self.get_choices, self.set_choices) self.properties['choices'] = ChoicesProperty(self, 'choices', None, [(_('Label'), GridProperty.STRING)], len(choices), label=_('choices')) self.access_functions['selection'] = (self.get_selection, self.set_selection) self.style = 0 self.access_functions['style'] = (self.get_style, self.set_style) self.properties['selection'] = SpinProperty(self, 'selection', None, r=(0, len(choices)-1), label=_('selection')) self.style_pos = (wx.LB_SINGLE, wx.LB_MULTIPLE, wx.LB_EXTENDED, wx.LB_HSCROLL, wx.LB_ALWAYS_SB, wx.LB_NEEDED_SB, wx.LB_SORT) style_labels = ('#section#' + _('Style'), 'wxLB_SINGLE', 'wxLB_MULTIPLE', 'wxLB_EXTENDED', 'wxLB_HSCROLL', 'wxLB_ALWAYS_SB', 'wxLB_NEEDED_SB', 'wxLB_SORT') self.style_tooltips = (_('Single-selection list.'), _('Multiple-selection list: the user can toggle multiple items on ' 'and off.'), _('Extended-selection list: the user can select multiple items ' 'using the SHIFT key and the mouse or special key combinations.'), _('Create horizontal scrollbar if contents are too wide ' '(Windows only).'), _('Always show a vertical scrollbar.'), _('Only create a vertical scrollbar if needed.'), _('The listbox contents are sorted in alphabetical order.')) self.properties['style'] = CheckListProperty( self, 'style', None, style_labels, tooltips=self.style_tooltips) def create_widget(self): self.widget = wx.ListBox(self.parent.widget, self.id, choices=self.choices) self.set_selection(self.selection) wx.EVT_LEFT_DOWN(self.widget, self.on_set_focus) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) szr = wx.BoxSizer(wx.VERTICAL) self.properties['choices'].display(panel) self.properties['style'].display(panel) self.properties['selection'].display(panel) szr.Add(self.properties['style'].panel, 0, wx.EXPAND) szr.Add(self.properties['selection'].panel, 0, wx.EXPAND) ch = self.properties['choices'].panel ch.SetSize((ch.GetSize()[0]-20, 200)) szr.Add(self.properties['choices'].panel, 1, wx.ALL|wx.EXPAND, 5) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) w, h = panel.GetSize() from math import ceil panel.SetScrollbars(5, 5, int(ceil(w/5.0)), int(ceil(h/5.0))) self.notebook.AddPage(panel, 'Widget') self.properties['choices'].set_col_sizes([-1]) def get_property_handler(self, prop_name): if prop_name == 'choices': return ChoicesHandler(self) return ManagedBase.get_property_handler(self, prop_name) def get_choices(self): return zip(self.choices) def set_choices(self, values): self.choices = [ misc.wxstr(v[0]) for v in values ] self.properties['selection'].set_range(0, len(self.choices)-1) if self.widget: self.widget.Clear() for c in self.choices: self.widget.Append(c) if not self.properties['size'].is_active(): self.sizer.set_item(self.pos, size=self.widget.GetBestSize()) self.widget.SetSelection( int(self.properties['selection'].get_value())) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_selection(self): return self.selection def set_selection(self, value): value = int(value) if value != self.selection: self.selection = value if self.widget: self.widget.SetSelection(value) # end of class EditListBox def builder(parent, sizer, pos, number=[1]): """\ factory function for EditListBox objects. """ name = 'list_box_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'list_box_%d' % number[0] list_box = EditListBox(name, parent, wx.NewId(), #[misc._encode('choice 1')], sizer, pos, [], sizer, pos, common.property_panel) node = Tree.Node(list_box) ## sizer.set_item(pos, size=list_box.GetBestSize()) list_box.node = node list_box.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditListBox objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") list_box = EditListBox(name, parent, wx.NewId(), [], sizer, pos, common.property_panel) sizer.set_item(list_box.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) ## size=list_box.GetBestSize()) node = Tree.Node(list_box) list_box.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return list_box def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditListBox'] = builder common.widgets_from_xml['EditListBox'] = xml_builder return common.make_object_button('EditListBox', 'icons/list_box.xpm') wxglade-0.6.8.orig/widgets/list_box/lisp_codegen.py0000644000175000017500000000335612150154266022624 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxListBox objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:59:46 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not style: style = '0' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) length = len(choices) choices = ' '.join([codegen.quote_str(c) for c in choices]) init.append('(setf (slot-%s obj) (wxListBox_Create %s %s -1 -1 -1 -1 %s (vector %s) %s))\n' % (obj.name, parent, id, length, choices, style)) props_buf = codegen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None: props_buf.append('(wxListBox_SetSelection (slot-%s obj) %s 1)\n' % (obj.name, selection)) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditListBox'] = 'wxListBox' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxListBox', LispCodeGenerator()) codegen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/list_box/codegen.py0000644000175000017500000001021312072605532021563 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxListBox objects # $Id: codegen.py,v 1.14 2007/03/27 07:01:58 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from ChoicesCodeHandler import * class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) choices = ', '.join([pygen.quote_str(c) for c in choices]) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, choices=[%s]%s)\n' % (obj.name, klass, parent, id, choices, style)) props_buf = pygen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None and choices: props_buf.append('self.%s.SetSelection(%s)\n' % (obj.name, selection)) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class ListBoxXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'choices': xrc_write_choices_property(self, outfile, tabs) elif name == 'selection': choices = self.properties['choices'] if choices: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class ListBoxXrcObject return ListBoxXrcObject(obj) class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxListBox objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] choices = prop.get('choices', []) if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' number = len(choices) ch_arr = '{\n %s\n };\n' % \ ',\n '.join([cppgen.quote_str(c) for c in choices]) style = prop.get("style", "0") init = [] if number: init.append('const wxString %s_choices[] = %s' % (obj.name, ch_arr)) else: init.append('const wxString *%s_choices = NULL;\n' % obj.name) init.append('%s = new %s(%s, %s, wxDefaultPosition, wxDefaultSize, ' '%s, %s_choices, %s);\n' % \ (obj.name, obj.klass, parent, id, number, obj.name, style)) props_buf = cppgen.generate_common_properties(obj) selection = prop.get('selection') if selection is not None and choices: props_buf.append('%s->SetSelection(%s);\n' % (obj.name, selection)) return init, ids, props_buf, [] # end of class CppCodeGenerator def initialize(): common.class_names['EditListBox'] = 'wxListBox' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxListBox', PythonCodeGenerator()) pygen.add_property_handler('choices', ChoicesCodeHandler) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxListBox', xrc_code_generator) xrcgen.add_property_handler('choices', ChoicesCodeHandler) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxListBox', CppCodeGenerator()) cppgen.add_property_handler('choices', ChoicesCodeHandler) wxglade-0.6.8.orig/widgets/list_box/__init__.py0000644000175000017500000000065211621715605021726 0ustar georgeskgeorgesk# __init__.py: list box widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:58 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import list_box return list_box.initialize() wxglade-0.6.8.orig/widgets/notebook/0000755000175000017500000000000012170277707017615 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/notebook/perl_codegen.py0000644000175000017500000000524311677431773022627 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxNotebook objects # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from codegen import TabsCodeHandler class PerlCodeGenerator: #wxNotebook(parent, id, pos, size, style, name) new_signature = [ '$parent', '$id', '$pos', '$size', '$style', '$name' ] def get_code(self, window): plgen = common.code_writers['perl'] prop = window.properties id_name, id = plgen.generate_code_id(window) layout_props = [] tabs = prop.get('tabs', []) for label, tab_win in tabs: layout_props.append('$self->{%s}->AddPage($self->{%s}, %s);\n' % \ (window.name, tab_win, plgen.quote_str(label))) if not window.parent.is_toplevel: parent = '$self->{%s}' % window.parent.name else: parent = '$self' if window.is_toplevel: klass = window.base if klass != window.klass: klass = window.klass else: klass = plgen.cn(klass) #klass.replace('wx','Wx::',1) l = [] if id_name: l.append(id_name) l.append('$self->{%s} = %s->new(%s, %s);\n' % (window.name, klass, parent,id)) return l, [], [] style = prop.get("style") if style: style = "%s" % style else: style = '' init = [] if id_name: init.append(id_name) init.append('$self->{%s} = %s->new(%s, %s, ' 'wxDefaultPosition, wxDefaultSize, %s);\n' % (window.name, plgen.cn(window.klass), parent, id, style)) props_buf = plgen.generate_common_properties(window) return init, props_buf, layout_props def get_properties_code(self, obj): prop = obj.properties plgen = common.code_writers['perl'] props_buf = [] tabs = prop.get('tabs', []) for label, window in tabs: props_buf.append('$self->AddPage($self->{%s}, %s);\n' % \ (window, plgen.quote_str(label))) props_buf.extend(plgen.generate_common_properties(obj)) return props_buf # end of class PerlCodeGenerator def initialize(): common.class_names['EditNotebook'] = 'wxNotebook' common.class_names['NotebookPane'] = 'wxPanel' common.toplevels['EditNotebook'] = 1 common.toplevels['NotebookPane'] = 1 plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxNotebook', PerlCodeGenerator()) plgen.add_property_handler('tabs', TabsCodeHandler, 'wxNotebook') wxglade-0.6.8.orig/widgets/notebook/lisp_codegen.py0000644000175000017500000000531312150154266022614 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxNotebook objects # $Id: lisp_codegen.py,v 1.2 2005/09/27 02:20:44 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from codegen import TabsCodeHandler class LispCodeGenerator: #wxNotebook(parent, id, pos, size, style, name) new_signature = [ '$parent', '$id', '$pos', '$size', '$style', '$name' ] def get_code(self, window): codegen = common.code_writers['lisp'] prop = window.properties id_name, id = codegen.generate_code_id(window) layout_props = [] tabs = prop.get('tabs', []) for label, tab_win in tabs: tab_win = tab_win.replace('_','-') layout_props.append('(wxNotebook_AddPage (slot-%s obj) (slot-%s obj) %s 1 -1)\n' % \ (window.name, tab_win, codegen.quote_str(label))) if not window.parent.is_toplevel: parent = '(slot-%s obj)' % window.parent.name else: parent = '(slot-top-window obj)' if window.is_toplevel: l = [] if id_name: l.append(id_name) l.append('(setf (slot-%s obj) (wxNotebook_Create %s %s -1 -1 -1 -1 wxNB_TOP))\n' % (window.name, parent,id)) return l, [], [] style = prop.get("style") if not style: style = 'wxNB_TOP' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxNotebook_Create %s %s -1 -1 -1 -1 %s))\n' % (window.name, parent, id, style)) props_buf = codegen.generate_common_properties(window) return init, props_buf, layout_props def get_properties_code(self, obj): prop = obj.properties codegen = common.code_writers['lisp'] props_buf = [] tabs = prop.get('tabs', []) for label, window in tabs: props_buf.append('(wxNotebook_AddPage (slot-%s obj) page %s 1 -1);\n' % \ (window, codegen.quote_str(label))) props_buf.extend(codegen.generate_common_properties(obj)) return props_buf # end of class LispCodeGenerator def initialize(): common.class_names['EditNotebook'] = 'wxNotebook' common.class_names['NotebookPane'] = 'wxPanel' common.toplevels['EditNotebook'] = 1 common.toplevels['NotebookPane'] = 1 codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxNotebook', LispCodeGenerator()) codegen.add_property_handler('tabs', TabsCodeHandler, 'wxNotebook') wxglade-0.6.8.orig/widgets/notebook/codegen.py0000644000175000017500000001614312150161160021557 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxNotebook objects # $Id: codegen.py,v 1.21 2007/08/07 12:15:21 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class TabsCodeHandler: def __init__(self): self.tabs = [] self.curr_tab_name = [] self.tab_window = None def start_elem(self, name, attrs): if name == 'tab': window = attrs.get('window') if not window: return self.tab_window = window self.curr_tab_name = [] def end_elem(self, name, code_obj): if name == 'tabs': code_obj.properties['tabs'] = self.tabs return True elif name == 'tab': tab_name = "".join(self.curr_tab_name) if self.tab_window: self.tabs.append((tab_name, self.tab_window)) return False def char_data(self, data): self.curr_tab_name.append(data) # end of class TabsCodeHandler class PythonCodeGenerator: def get_code(self, window): pygen = common.code_writers['python'] prop = window.properties id_name, id = pygen.generate_code_id(window) layout_props = [] tabs = prop.get('tabs', []) for label, tab_win in tabs: layout_props.append('self.%s.AddPage(self.%s, %s)\n' % \ (window.name, tab_win, pygen.quote_str(label))) if not window.parent.is_toplevel: parent = 'self.%s' % window.parent.name else: parent = 'self' if window.is_toplevel: l = [] if id_name: l.append(id_name) l.append('self.%s = %s(%s, %s)\n' % (window.name, pygen.without_package(window.klass), parent,id)) return l, [], [] style = prop.get("style") if style: style = ", style=%s" % pygen.cn_f(style) else: style = '' klass = window.klass if window.preview: klass = 'wxNotebook' init = [] if id_name: init.append(id_name) init.append(('self.%s = ' + pygen.cn(klass) + '(%s, %s%s)\n') % (window.name, parent, id, style)) props_buf = pygen.generate_common_properties(window) return init, props_buf, layout_props def get_properties_code(self, obj): prop = obj.properties pygen = common.code_writers['python'] props_buf = [] tabs = prop.get('tabs', []) for label, window in tabs: props_buf.append('self.AddPage(self.%s, %s)\n' % \ (window, pygen.quote_str(label))) props_buf.extend(pygen.generate_common_properties(obj)) return props_buf # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] from xml.sax.saxutils import escape class NotebookXrcObject(xrcgen.DefaultXrcObject): def write(self, outfile, ntabs): # the "tabs" property contains the pages of a notebook # be carefully: tabs in context of code generation are white # spaces used for indenting lines!! if self.properties.has_key('tabs'): self.pages = self.properties['tabs'] del self.properties['tabs'] else: self.pages = [] self.index = 0 # always use a wxNotebookSizer self.properties['usenotebooksizer'] = '1' if 'no_custom_class' in self.properties: del self.properties['no_custom_class'] xrcgen.DefaultXrcObject.write(self, outfile, ntabs) def write_child_prologue(self, child, outfile, ntabs): if self.pages: tab_s = ' ' * ntabs outfile.write(tab_s + '\n') outfile.write(tab_s + '\n' % \ escape(self.pages[self.index][0])) self.index += 1 def write_child_epilogue(self, child, outfile, ntabs): if self.tabs: outfile.write(' '*ntabs + '\n') return NotebookXrcObject(obj) class CppCodeGenerator: constructor = [('wxWindow*', 'parent'), ('int', 'id'), ('const wxPoint&', 'pos', 'wxDefaultPosition'), ('const wxSize&', 'size', 'wxDefaultSize'), ('long', 'style', '0')] extra_headers = [''] def get_code(self, window): """\ generates the C++ code for wxNotebook """ cppgen = common.code_writers['C++'] prop = window.properties id_name, id = cppgen.generate_code_id(window) if id_name: ids = [ id_name ] else: ids = [] layout_props = [] tabs = prop.get('tabs', []) for label, tab_win in tabs: layout_props.append('%s->AddPage(%s, %s);\n' % \ (window.name, tab_win, cppgen.quote_str(label))) if not window.parent.is_toplevel: parent = '%s' % window.parent.name else: parent = 'this' if window.is_toplevel: l = ['%s = new %s(%s, %s);\n' % (window.name, window.klass, parent, id)] return l, ids, [], [] extra = '' style = prop.get('style') if style: extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s%s);\n' % (window.name, window.klass, parent, id, extra) ] props_buf = cppgen.generate_common_properties(window) return init, ids, props_buf, layout_props def get_properties_code(self, obj): prop = obj.properties cppgen = common.code_writers['C++'] props_buf = [] tabs = prop.get('tabs', []) for label, window in tabs: props_buf.append('AddPage(%s, %s);\n' % \ (window, cppgen.quote_str(label))) props_buf.extend(cppgen.generate_common_properties(obj)) return props_buf def get_events(self, obj): cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxNotebookEvent') # end of class CppCodeGenerator def initialize(): common.class_names['EditNotebook'] = 'wxNotebook' common.class_names['NotebookPane'] = 'wxPanel' common.toplevels['EditNotebook'] = 1 common.toplevels['NotebookPane'] = 1 # python code generation functions pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('wxNotebook', PythonCodeGenerator()) pygen.add_property_handler('tabs', TabsCodeHandler, 'wxNotebook') xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('wxNotebook', xrc_code_generator) xrcgen.add_property_handler('tabs', TabsCodeHandler, 'wxNotebook') cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxNotebook', CppCodeGenerator()) cppgen.add_property_handler('tabs', TabsCodeHandler, 'wxNotebook') wxglade-0.6.8.orig/widgets/notebook/notebook.py0000644000175000017500000004224012150154266022001 0ustar georgeskgeorgesk"""\ wxNotebook objects @copyright: 2002-2007 Alberto Griggio @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import wx import common import misc from tree import Tree from widget_properties import * from edit_windows import ManagedBase from edit_sizers.edit_sizers import Sizer, SizerSlot from xml_parse import XmlParsingError try: from panel import EditPanel _has_panel = True except ImportError: _has_panel = False def _ugly_hack_for_win32_notebook_bug(notebook_widget): """\ The name should say all. The problem is hard to explain, so let me just illustrate a way to reproduce the bug: 1. create a frame in wxGlade, add a notebook with two pages 2. put a button on the first page, and a text ctrl on the second one 3. save the app 4. exit wxGlade, and comment out the body of this function 5. restart wxGlade and load the previous app 6. Try to click on the button on the first page of the notebook, and see what happens... If you don't see what I mean, please drop me an email with your version of Windows, Python and wxPython, because I really want to understand what's going on... So far I've not been able to reproduce the problem on a standalone minimal app, but as time permits I'll try again... if you succeed, please let me know. """ #print '_ugly_hack_for_win32_notebook_bug' index_ok = notebook_widget.GetSelection() for i in range(notebook_widget.GetPageCount()): notebook_widget.GetPage(i).Hide() notebook_widget.GetPage(index_ok).Show() class NotebookVirtualSizer(Sizer): '''\ "Virtual sizer" responsible for the management of the pages of a Notebook. ''' def __init__(self, *args, **kwds): Sizer.__init__(self, *args, **kwds) self._itempos = 0 def set_item(self, pos, option=None, flag=None, border=None, size=None, force_layout=True): """\ Updates the layout of the item at the given pos. """ if not self.window.widget: return pos -= 1 label, item = self.window.tabs[pos] if not item or not item.widget: return if not (pos < self.window.widget.GetPageCount()): self.window.widget.AddPage(item.widget, label) elif self.window.widget.GetPage(pos) is not item.widget: #self.window.widget.RemovePage(pos) self.window.widget.DeletePage(pos) self.window.widget.InsertPage(pos, item.widget, label) self.window.widget.SetSelection(pos) try: wx.CallAfter(item.sel_marker.update) except AttributeError, e: #print e pass if self.window.sizer is not None: self.window.sizer.set_item( self.window.pos, size=self.window.widget.GetBestSize()) def add_item(self, item, pos=None, option=0, flag=0, border=0, size=None, force_layout=True): """\ Adds an item to self.window. """ #print 'pos:', pos, 'item.name:', item.name try: self.window.tabs[pos - 1][1] = item except IndexError: raise XmlParsingError( _('Notebook widget "%s" does not have any tabs!') % \ self.window.name ) item._dont_destroy = True def free_slot(self, pos, force_layout=True): """\ Replaces the element at pos with an empty slot """ if self.window._is_removing_pages or not self.window.widget: return slot = SizerSlot(self.window, self, pos) #print 'free:', slot, slot.pos, pos slot.show_widget(True) pos = pos - 1 label, item = self.window.tabs[pos] self.window.widget.RemovePage(pos) self.window.widget.InsertPage(pos, slot.widget, label) self.window.widget.SetSelection(pos) def get_itempos(self, attrs): """\ Get position of sizer item (used in xml_parse) """ self._itempos += 1 return self._itempos def is_virtual(self): return True # end of class NotebookVirtualSizer class NotebookPagesProperty(GridProperty): def write(self, outfile, tabs): from xml.sax.saxutils import escape, quoteattr write = outfile.write write(' ' * tabs + '\n') tab_s = ' ' * (tabs + 1) import widget_properties value = self.get_value() for i in range(len(value)): val = value[i] v = escape(widget_properties._encode(val[0])) window = None try: t = self.owner.tabs[i] if t[0] == val[0]: window = t[1] except: pass if window: write('%s' % (tab_s, quoteattr(window.name))) write(v) write('\n') write(' ' * tabs + '\n') # end of class NotebookPagesProperty class TabsHandler: def __init__(self, parent): self.parent = parent self.tab_names = [] self.curr_tab = [] def start_elem(self, name, attrs): pass def end_elem(self, name): if name == 'tabs': self.parent.tabs = [[misc.wxstr(name), None] for name in \ self.tab_names] self.parent.properties['tabs'].set_value([[name] for name in \ self.tab_names]) return True elif name == 'tab': self.tab_names.append("".join(self.curr_tab)) self.curr_tab = [] return False def char_data(self, data): self.curr_tab.append(data) # end of class TabsHandler class EditNotebook(ManagedBase): _custom_base_classes = True notebook_number = 1 """\ @cvar: Next free number for notebook names. The number is continuously. Each notebook gets an own number. It's very useful for labeling panes. Deleting notebooks won't decrease this number. @see: L{self.next_notebook_name()} @type: Integer @note: Use only C{+=1} for increasing! """ pane_number = 1 """\ @ivar: Free number for pane names. This number is is continuously. Each pane get an own number. It's very useful for labelung. Deleting oanes won't decrease this number. @see: L{self.next_pane_name()} @type: Integer """ events = ['EVT_NOTEBOOK_PAGE_CHANGED', 'EVT_NOTEBOOK_PAGE_CHANGING'] def __init__(self, name, parent, id, style, sizer, pos, property_window, show=True): """\ Class to handle wxNotebook objects """ # create new and (still) unused notebook name if not name: name = self.next_notebook_name() # Increase number of created notebooks EditNotebook.notebook_number += 1 ManagedBase.__init__(self, name, 'wxNotebook', parent, id, sizer, pos, property_window, show=show) self.virtual_sizer = NotebookVirtualSizer(self) self._is_removing_pages = False self.style = style self.tabs = [['tab1', None]] # list of pages of this notebook # (actually a list of # 2-list label, window) self.access_functions['style'] = (self.get_tab_pos, self.set_tab_pos) self.properties['style'] = HiddenProperty( self, 'style', label=_("style"), ) self.access_functions['tabs'] = (self.get_tabs, self.set_tabs) tab_cols = [('Tab label', GridProperty.STRING)] self.properties['tabs'] = NotebookPagesProperty( self, 'tabs', None, tab_cols, label=_("tabs"), can_remove_last=False, ) del tab_cols self.nb_sizer = None self._create_slots = False self.no_custom_class = False self.access_functions['no_custom_class'] = (self.get_no_custom_class, self.set_no_custom_class) self.properties['no_custom_class'] = CheckBoxProperty( self, 'no_custom_class', label=_("Don't generate code for this custom class")) # first pane should have number 1 self.pane_number = 1 def create_widget(self): self.widget = wx.Notebook( self.parent.widget, self.id, style=self.style, ) def show_widget(self, yes): ManagedBase.show_widget(self, yes) if yes and wx.Platform in ('__WXMSW__', '__WXMAC__'): wx.CallAfter(_ugly_hack_for_win32_notebook_bug, self.widget) if self._create_slots: self._create_slots = False for i in range(len(self.tabs)): if self.tabs[i][1] is None: self.tabs = self.tabs[:i] self.properties['tabs'].set_value(self.get_tabs()) def finish_widget_creation(self): ManagedBase.finish_widget_creation(self) # replace 'self' with 'self.nb_sizer' in 'self.sizer' def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow( self.notebook, wx.ID_ANY, style=wx.TAB_TRAVERSAL, ) self.properties['no_custom_class'].display(panel) self.properties['tabs'].display(panel) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.properties['no_custom_class'].panel, 0, wx.ALL | wx.EXPAND, 3) sizer.Add(self.properties['tabs'].panel, 1, wx.ALL | wx.EXPAND, 3) panel.SetAutoLayout(True) panel.SetSizer(sizer) sizer.Fit(panel) self.notebook.AddPage(panel, _('Widget')) self.properties['tabs'].set_col_sizes([-1]) def on_set_focus(self, event): self.show_properties() event.Skip() def _add_tab(self, window, pos): if window is None: window = SizerSlot(self, self.virtual_sizer, pos) self.tabs[pos - 1][1] = window else: window._dont_destroy = True node = Tree.Node(window) window.node = node common.app_tree.add(node, self.node) if self.widget: window.show_widget(True) self.virtual_sizer.set_item(pos) try: wx.CallAfter(window.sel_marker.update) except AttributeError, e: #print e pass def get_tabs(self): return [[n] for n, w in self.tabs] def set_tabs(self, tabs): delta = len(self.tabs) - len(tabs) if delta > 0: self._is_removing_pages = True # we have to remove some pages i = len(tabs) if self.widget: for n, window in self.tabs[i:]: self.widget.RemovePage(i) window.remove(False) del self.tabs[i:] if self.widget: self.widget.SetSelection(0) self._is_removing_pages = False elif delta < 0: # we have to add some pages pos = len(self.tabs) for i in range(-delta): self.tabs.append(['', None]) pos += 1 if _has_panel: window = EditPanel( self.next_pane_name(), self, wx.ID_ANY, self.virtual_sizer, pos, self.property_window, ) self._add_tab(window, pos) else: self._add_tab(None, pos) if self.widget: self.widget.SetSelection(self.widget.GetPageCount() - 1) # finally, we must update the labels of the tabs for i in range(len(tabs)): tt = misc.wxstr(tabs[i][0]) if self.widget: self.widget.SetPageText(i, tt) self.tabs[i][0] = tt def delete(self): if self.widget: self.widget.DeleteAllPages() ManagedBase.delete(self) def get_property_handler(self, name): if name == 'tabs': return TabsHandler(self) return ManagedBase.get_property_handler(self, name) def find_page(self, page): """\ returns the index of the given page in the notebook, or -1 if the page cannot be found """ if not self.widget: return -1 for i in range(len(self.tabs)): if self.tabs[i][1] is page: if i < self.widget.GetPageCount(): return i else: return -1 return -1 def get_tab_pos(self): styles = {wx.NB_LEFT: 'wxNB_LEFT', wx.NB_RIGHT: 'wxNB_RIGHT', wx.NB_BOTTOM: 'wxNB_BOTTOM'} return styles.get(self.style, '0') def set_tab_pos(self, value): styles = {'wxNB_LEFT': wx.NB_LEFT, 'wxNB_RIGHT': wx.NB_RIGHT, 'wxNB_BOTTOM': wx.NB_BOTTOM} self.style = styles.get(value, 0) def get_no_custom_class(self): return self.no_custom_class def set_no_custom_class(self, value): self.no_custom_class = bool(int(value)) def next_notebook_name(self): """\ Return new and (still) unused notebook name @see: L{self.notebook_number} """ while True: name = 'notebook_%d' % EditNotebook.notebook_number if not common.app_tree.has_name(name): break EditNotebook.notebook_number += 1 return name def next_pane_name(self): """\ Return new and (still) unused pane name @see: L{self.pane_number} """ while True: pane_name = "%s_pane_%d" % (self.name, self.pane_number) self.pane_number += 1 if not common.app_tree.has_name(pane_name): break return pane_name # end of class EditNotebook def builder(parent, sizer, pos, number=[1]): """\ factory function for EditNotebook objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__( self, None, wx.ID_ANY, _('Select tab placement'), ) self.styles = [0, wx.NB_BOTTOM, wx.NB_LEFT, wx.NB_RIGHT] self.style = 0 prop = RadioProperty( self, 'tab_placement', self, [_('Top'), _('Bottom'), _('Left'), _('Right')], columns=2, label=_('tab_placement'), ) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop.panel, 0, wx.ALL | wx.EXPAND, 10) btn = wx.Button(self, wx.ID_OK, _('OK')) btn.SetDefault() szr.Add(btn, 0, wx.BOTTOM | wx.ALIGN_CENTER, 10) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def __getitem__(self, value): def set_style(s): self.style = self.styles[s] return (lambda: self.style, set_style) # end of inner class dialog = Dialog() dialog.ShowModal() window = EditNotebook(None, parent, wx.ID_ANY, dialog.style, sizer, pos, common.property_panel, show=False) if _has_panel: pane1 = EditPanel( window.next_pane_name(), window, wx.ID_ANY, window.virtual_sizer, 1, common.property_panel, ) node = Tree.Node(window) window.node = node window.virtual_sizer.node = node window.set_option(1) window.set_flag("wxEXPAND") window.show_widget(True) common.app_tree.insert(node, sizer.node, pos - 1) if _has_panel: window._add_tab(pane1, 1) sizer.set_item(window.pos, 1, wx.EXPAND) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditNotebook objects from an xml file """ try: name = attrs['name'] except KeyError: raise XmlParsingError(_("'name' attribute missing")) if not sizer or not sizeritem: raise XmlParsingError(_("sizer or sizeritem object cannot be None")) window = EditNotebook(name, parent, wx.ID_ANY, 0, sizer, pos, common.property_panel, True) window._create_slots = True sizer.set_item(window.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(window) window.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos - 1) return window def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditNotebook'] = builder common.widgets_from_xml['EditNotebook'] = xml_builder return common.make_object_button('EditNotebook', 'icons/notebook.xpm') wxglade-0.6.8.orig/widgets/notebook/__init__.py0000644000175000017500000000065211621715605021723 0ustar georgeskgeorgesk# __init__.py: notebook widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:56 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import notebook return notebook.initialize() wxglade-0.6.8.orig/widgets/custom_widget/0000755000175000017500000000000012170277707020652 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/custom_widget/perl_codegen.py0000644000175000017500000000311311646103573023644 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for CustomWidget objects # $Id: perl_codegen.py,v 1.4 2004/09/17 13:09:53 agriggio Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from codegen import ArgumentsCodeHandler, _fix_arguments class PerlCodeGenerator: def get_code(self, widget): init = [] plgen = common.code_writers['perl'] prop = widget.properties id_name, id = plgen.generate_code_id(widget) if not widget.parent.is_toplevel: parent = '$self->{%s}' % widget.parent.name else: parent = '$self' if id_name: init.append(id_name) arguments = _fix_arguments(prop.get('arguments', []), parent, id, prop.get('size', "-1, -1")) ctor = widget.klass + '->new' cust_ctor = prop.get('custom_ctor', '').strip() if cust_ctor: ctor = cust_ctor init.append('$self->{%s} = %s(%s);\n' % (widget.name, ctor, ", ".join(arguments))) props_buf = plgen.generate_common_properties(widget) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['CustomWidget'] = 'CustomWidget' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('CustomWidget', PerlCodeGenerator()) plgen.add_property_handler('arguments', ArgumentsCodeHandler, 'CustomWidget') wxglade-0.6.8.orig/widgets/custom_widget/lisp_codegen.py0000644000175000017500000000271412070323733023651 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for CustomWidget objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 06:59:00 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common from codegen import ArgumentsCodeHandler, _fix_arguments class LispCodeGenerator: def get_code(self, widget): init = [] plgen = common.code_writers['lisp'] prop = widget.properties id_name, id = plgen.generate_code_id(widget) if not widget.parent.is_toplevel: parent = '(object-%s self)' % widget.parent.name else: parent = 'nil' if id_name: init.append(id_name) arguments = _fix_arguments(prop.get('arguments', []), parent, id, prop.get('size', "-1, -1")) init.append('use %s;\n' % widget.klass ) # yuck init.append('$self->{%s} = %s->new(%s);\n' % (widget.name, widget.klass, ", ".join(arguments))) props_buf = plgen.generate_common_properties(widget) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['CustomWidget'] = 'CustomWidget' plgen = common.code_writers.get('lisp') if plgen: plgen.add_widget_handler('CustomWidget', LispCodeGenerator()) plgen.add_property_handler('arguments', ArgumentsCodeHandler, 'CustomWidget') wxglade-0.6.8.orig/widgets/custom_widget/codegen.py0000644000175000017500000001453211621715605022627 0ustar georgeskgeorgesk# codegen.py: code generator functions for CustomWidget objects # $Id: codegen.py,v 1.13 2007/08/07 12:13:43 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class ArgumentsCodeHandler: def __init__(self): self.arguments = [] self.curr_arg = [] def start_elem(self, name, attrs): pass def end_elem(self, name, code_obj): if name == 'arguments': code_obj.properties['arguments'] = self.arguments return True elif name == 'argument': tab_name = "".join(self.curr_arg) self.arguments.append(tab_name) self.curr_arg = [] return False def char_data(self, data): self.curr_arg.append(data) # end of class ArgumentsCodeHandler def _fix_arguments(arguments, parent, id, size): # Dinogen, 29 oct 2003 # adding $width e $height: vSize = size.split(',') for i in range(len(arguments)): if arguments[i] == '$parent': arguments[i] = parent elif arguments[i] == '$id': arguments[i] = id elif arguments[i] == '$width': arguments[i] = vSize[0] elif arguments[i] == '$height': arguments[i] = vSize[1] return arguments class PythonCodeGenerator: def get_code(self, widget): if widget.preview and widget.klass not in widget.parser.class_names: # if this CustomWidget refers to another class in the same wxg # file, use that for the preview return self.get_code_preview(widget) pygen = common.code_writers['python'] prop = widget.properties id_name, id = pygen.generate_code_id(widget) if not widget.parent.is_toplevel: parent = 'self.%s' % widget.parent.name else: parent = 'self' init = [] if id_name: init.append(id_name) arguments = _fix_arguments( prop.get('arguments', []), parent, id, prop.get('size', '-1, -1').strip()) ctor = widget.klass cust_ctor = prop.get('custom_ctor', '').strip() if cust_ctor: ctor = cust_ctor init.append('self.%s = %s(%s)\n' % (widget.name, ctor, ", ".join(arguments))) props_buf = pygen.generate_common_properties(widget) return init, props_buf, [] def get_code_preview(self, widget): pygen = common.code_writers['python'] if not widget.parent.is_toplevel: parent = 'self.%s' % widget.parent.name else: parent = 'self' init = [] append = init.append append('self.%s = wx.Window(%s, -1)\n' % (widget.name, parent)) on_paint_code = """\ def self_%s_on_paint(event): widget = self.%s dc = wx.PaintDC(widget) dc.BeginDrawing() dc.SetBrush(wx.WHITE_BRUSH) dc.SetPen(wx.BLACK_PEN) dc.SetBackground(wx.WHITE_BRUSH) dc.Clear() w, h = widget.GetClientSize() dc.DrawLine(0, 0, w, h) dc.DrawLine(w, 0, 0, h) text = 'Custom Widget: %s' tw, th = dc.GetTextExtent(text) x = (w - tw)/2 y = (h - th)/2 dc.SetPen(wx.ThePenList.FindOrCreatePen(wx.BLACK, 0, wx.TRANSPARENT)) dc.DrawRectangle(x-1, y-1, tw+2, th+2) dc.DrawText(text, x, y) dc.EndDrawing() """ % ((widget.name,) * 3) for line in on_paint_code.splitlines(): append(line + '\n') append('wx.EVT_PAINT(self.%s, self_%s_on_paint)\n' % (widget.name, widget.name)) return init, [], [] # end of class PythonCodeGenerator class CppCodeGenerator: def get_code(self, widget): cppgen = common.code_writers['C++'] prop = widget.properties id_name, id = cppgen.generate_code_id(widget) if id_name: ids = [ id_name ] else: ids = [] if not widget.parent.is_toplevel: parent = '%s' % widget.parent.name else: parent = 'this' arguments = _fix_arguments( prop.get('arguments', []), parent, id, prop.get('size', '-1, -1').strip()) ctor = 'new ' + widget.klass cust_ctor = prop.get('custom_ctor', '').strip() if cust_ctor: ctor = cust_ctor init = ['%s = %s(%s);\n' % (widget.name, ctor, ", ".join(arguments)) ] props_buf = cppgen.generate_common_properties(widget) return init, ids, props_buf, [] # end of class CppCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class CustomXrcObject(xrcgen.DefaultXrcObject): from xml.sax.saxutils import escape def write(self, outfile, ntabs): # first, fix the class: self.klass = obj.klass # delete the custom constructor property if 'custom_ctor' in self.properties: del self.properties['custom_ctor'] # then, the attributes: if 'arguments' in self.properties: args = self.properties['arguments'] del self.properties['arguments'] for arg in args: try: name, val = [s.strip() for s in arg.split(':', 1)] except Exception, e: print 'Exception:', e continue # silently ignore malformed arguments self.properties[name] = val xrcgen.DefaultXrcObject.write(self, outfile, ntabs) return CustomXrcObject(obj) def initialize(): common.class_names['CustomWidget'] = 'CustomWidget' # python code generation functions pygen = common.code_writers.get('python') if pygen: pygen.add_widget_handler('CustomWidget', PythonCodeGenerator()) pygen.add_property_handler('arguments', ArgumentsCodeHandler, 'CustomWidget') cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('CustomWidget', CppCodeGenerator()) cppgen.add_property_handler('arguments', ArgumentsCodeHandler, 'CustomWidget') xrcgen = common.code_writers.get('XRC') if xrcgen: xrcgen.add_widget_handler('CustomWidget', xrc_code_generator) xrcgen.add_property_handler('arguments', ArgumentsCodeHandler, 'CustomWidget') wxglade-0.6.8.orig/widgets/custom_widget/custom_widget.py0000644000175000017500000002046111621715605024076 0ustar georgeskgeorgesk# custom_widget.py: custom wxWindow objects # $Id: custom_widget.py,v 1.21 2007/08/07 12:13:43 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common, misc from tree import Tree from widget_properties import * from edit_windows import ManagedBase class ArgumentsProperty(GridProperty): def write(self, outfile, tabs): from xml.sax.saxutils import escape if self.getter: values = self.getter() else: values = self.owner[self.name][0]() if values: write = outfile.write write(' ' * tabs + '\n') stab = ' ' * (tabs+1) for value in values: write('%s%s\n' % (stab, escape(value[0]))) write(' ' * tabs + '\n') # end of class ArgumentsProperty class ArgumentsHandler: def __init__(self, parent): self.parent = parent self.arguments = [] self.curr_arg = [] def start_elem(self, name, attrs): pass def end_elem(self, name): if name == 'arguments': self.parent.arguments = self.arguments self.parent.properties['arguments'].set_value(self.arguments) return True elif name == 'argument': self.arguments.append(["".join(self.curr_arg)]) self.curr_arg = [] return False def char_data(self, data): self.curr_arg.append(data) # end of class ArgumentsHandler class CustomWidget(ManagedBase): def __init__(self, name, klass, parent, id, sizer, pos, property_window, show=True): ManagedBase.__init__(self, name, klass, parent, id, sizer, pos, property_window, show) self.arguments = [['$parent'], ['$id']] #,['$width'],['$height']] self.access_functions['arguments'] = (self.get_arguments, self.set_arguments) cols = [('Arguments', GridProperty.STRING)] self.properties['arguments'] = ArgumentsProperty( self, 'arguments', None, cols, 2, label=_("arguments")) self.custom_ctor = "" # if not empty, an arbitrary piece of code that # will be used instead of the constructor name self.access_functions['custom_ctor'] = (self.get_custom_ctor, self.set_custom_ctor) self.properties['custom_ctor'] = TextProperty( self, 'custom_ctor', None, True, label=_('Custom constructor')) def set_klass(self, value): ManagedBase.set_klass(self, value) if self.widget: self.widget.Refresh() def create_widget(self): self.widget = wx.Window(self.parent.widget, self.id, style=wx.SUNKEN_BORDER|wx.FULL_REPAINT_ON_RESIZE) wx.EVT_PAINT(self.widget, self.on_paint) def finish_widget_creation(self): ManagedBase.finish_widget_creation(self, sel_marker_parent=self.widget) def on_paint(self, event): dc = wx.PaintDC(self.widget) dc.BeginDrawing() dc.SetBrush(wx.WHITE_BRUSH) dc.SetPen(wx.BLACK_PEN) dc.SetBackground(wx.WHITE_BRUSH) dc.Clear() w, h = self.widget.GetClientSize() dc.DrawLine(0, 0, w, h) dc.DrawLine(w, 0, 0, h) text = _('Custom Widget: %s') % self.klass tw, th = dc.GetTextExtent(text) x = (w - tw)/2 y = (h - th)/2 dc.SetPen(wx.ThePenList.FindOrCreatePen(wx.BLACK, 0, wx.TRANSPARENT)) dc.DrawRectangle(x-1, y-1, tw+2, th+2) dc.DrawText(text, x, y) dc.EndDrawing() def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1) szr = wx.BoxSizer(wx.VERTICAL) ctor = self.properties['custom_ctor'] ctor.display(panel) szr.Add(ctor.panel, 0, wx.EXPAND) args = self.properties['arguments'] args.display(panel) szr.Add(args.panel, 1, wx.ALL|wx.EXPAND, 5) help_btn = wx.Button(panel, -1, _('Help on "Arguments" property')) text = _("""\ The 'Arguments' property behaves differently when generating XRC code wrt C++ or python: you can use it to add custom attributes to the resource object. To do so, arguments must have the following format: ATTRIBUTE_NAME: ATTRIBUTE_VALUE For instance: default_value: 10 is translated to: 10 Invalid entries are silently ignored""") def show_help(event): wx.MessageBox(text, _('Help on "Arguments" property'), wx.OK|wx.CENTRE|wx.ICON_INFORMATION) wx.EVT_BUTTON(help_btn, -1, show_help) szr.Add(help_btn, 0, wx.BOTTOM|wx.LEFT|wx.RIGHT|wx.EXPAND, 5) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, 'Widget') args.set_col_sizes([-1]) def get_arguments(self): return self.arguments def set_arguments(self, value): self.arguments = [[misc.wxstr(v) for v in val] for val in value] def get_property_handler(self, name): if name == 'arguments': return ArgumentsHandler(self) return ManagedBase.get_property_handler(self, name) def get_custom_ctor(self): return self.custom_ctor def set_custom_ctor(self, value): self.custom_ctor = value.strip() # end of class CustomWidget def builder(parent, sizer, pos, number=[1]): """\ factory function for CustomWidget objects. """ class Dialog(wx.Dialog): def __init__(self, number=[0]): title = _('Select widget class') wx.Dialog.__init__(self, None, -1, title) self.klass = 'CustomWidget' if number[0]: self.klass = 'CustomWidget%s' % (number[0]-1) number[0] += 1 klass_prop = TextProperty(self, 'class', self, label=_("class")) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(klass_prop.panel, 0, wx.ALL|wx.EXPAND, 5) szr.Add(wx.Button(self, wx.ID_OK, _('OK')), 0, wx.ALL|wx.ALIGN_CENTER, 5) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) w = self.GetTextExtent(title)[0] + 50 if self.GetSize()[0] < w: self.SetSize((w, -1)) self.CenterOnScreen() def __getitem__(self, value): def set_klass(c): self.klass = c return (lambda : self.klass, set_klass) # end of inner class dialog = Dialog() dialog.ShowModal() name = 'window_%d' % number[0] while common.app_tree.has_name(name): number[0] += 1 name = 'window_%d' % number[0] win = CustomWidget(name, dialog.klass, parent, wx.NewId(), sizer, pos, common.property_panel) node = Tree.Node(win) win.node = node win.set_option(1) win.set_flag("wxEXPAND") win.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) sizer.set_item(win.pos, 1, wx.EXPAND) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build CustomWidget objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") if not sizer or not sizeritem: raise XmlParsingError, _("sizer or sizeritem object cannot be None") win = CustomWidget(name, 'CustomWidget', parent, wx.NewId(), sizer, pos, common.property_panel, True) sizer.set_item(win.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(win) win.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return win def initialize(): """\ initialization function for the module: returns a wx.BitmapButton to be added to the main palette. """ common.widgets['CustomWidget'] = builder common.widgets_from_xml['CustomWidget'] = xml_builder return common.make_object_button('CustomWidget', 'icons/custom.xpm', tip='Add a custom widget') wxglade-0.6.8.orig/widgets/custom_widget/__init__.py0000644000175000017500000000066211621715605022761 0ustar georgeskgeorgesk# __init__.py: custom widget module initialization # $Id: __init__.py,v 1.7 2007/03/27 07:02:01 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import custom_widget return custom_widget.initialize() wxglade-0.6.8.orig/widgets/slider/0000755000175000017500000000000012170277707017257 5ustar georgeskgeorgeskwxglade-0.6.8.orig/widgets/slider/perl_codegen.py0000644000175000017500000000316211646104451022251 0ustar georgeskgeorgesk# perl_codegen.py : perl generator functions for wxSlider objects # $Id: perl_codegen.py,v 1.4 2005/08/15 07:42:36 crazyinsomniac Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PerlCodeGenerator: def get_code(self, obj): plgen = common.code_writers['perl'] prop = obj.properties id_name, id = plgen.generate_code_id(obj) value = prop.get('value', '0') try: min_v, max_v = [ s.strip() for s in prop['range'].split(',') ] except: min_v, max_v = '0', '10' if not obj.parent.is_toplevel: parent = '$self->{%s}' % obj.parent.name else: parent = '$self' style = prop.get("style") if not( style and style != 'wxSL_HORIZONTAL'): # default style style = '' init = [] if id_name: init.append(id_name) klass = obj.base if klass != obj.klass: klass = obj.klass else: klass = klass.replace('wx', 'Wx::', 1) init.append('$self->{%s} = %s->new(%s, %s, %s, %s, %s, \ wxDefaultPosition, wxDefaultSize, %s);\n' % (obj.name, klass, parent, id, value, min_v, max_v, style)) props_buf = plgen.generate_common_properties(obj) return init, props_buf, [] # end of class PerlCodeGenerator def initialize(): common.class_names['EditSlider'] = 'wxSlider' plgen = common.code_writers.get('perl') if plgen: plgen.add_widget_handler('wxSlider', PerlCodeGenerator()) wxglade-0.6.8.orig/widgets/slider/lisp_codegen.py0000644000175000017500000000302512150154266022254 0ustar georgeskgeorgesk# lisp_codegen.py : lisp generator functions for wxSlider objects # $Id: lisp_codegen.py,v 1.1 2005/09/22 07:00:30 efuzzyone Exp $ # # Copyright (c) 2002-2004 D.H. aka crazyinsomniac on sourceforge.net # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class LispCodeGenerator: def get_code(self, obj): codegen = common.code_writers['lisp'] prop = obj.properties id_name, id = codegen.generate_code_id(obj) value = prop.get('value', '0') try: min_v, max_v = [ s.strip() for s in prop['range'].split(',') ] except: min_v, max_v = '0', '10' if not obj.parent.is_toplevel: parent = '(slot-%s obj)' % obj.parent.name else: parent = '(slot-top-window obj)' style = prop.get("style") if not( style and style != 'wxSL_HORIZONTAL'): # default style style = '0' else: style = codegen.cn_f(style) init = [] if id_name: init.append(id_name) init.append('(setf (slot-%s obj) (wxSlider_Create %s %s %s %s %s -1 -1 -1 -1 %s))\n' % (obj.name, parent, id, value, min_v, max_v, style)) props_buf = codegen.generate_common_properties(obj) return init, props_buf, [] # end of class LispCodeGenerator def initialize(): common.class_names['EditSlider'] = 'wxSlider' codegen = common.code_writers.get('lisp') if codegen: codegen.add_widget_handler('wxSlider', LispCodeGenerator()) wxglade-0.6.8.orig/widgets/slider/codegen.py0000644000175000017500000000711612072605532021232 0ustar georgeskgeorgesk# codegen.py: code generator functions for wxSlider objects # $Id: codegen.py,v 1.15 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import common class PythonCodeGenerator: def get_code(self, obj): pygen = common.code_writers['python'] prop = obj.properties id_name, id = pygen.generate_code_id(obj) value = prop.get('value', '0') try: min_v, max_v = [ s.strip() for s in prop['range'].split(',') ] except: min_v, max_v = '0', '10' if not obj.parent.is_toplevel: parent = 'self.%s' % obj.parent.name else: parent = 'self' style = prop.get("style") if style and style != 'wxSL_HORIZONTAL': style = ", style=%s" % pygen.cn_f(style) else: style = '' init = [] if id_name: init.append(id_name) klass = obj.klass if klass == obj.base: klass = pygen.cn(klass) init.append('self.%s = %s(%s, %s, %s, %s, %s%s)\n' % (obj.name, klass, parent, id, value, min_v, max_v, style)) props_buf = pygen.generate_common_properties(obj) return init, props_buf, [] # end of class PythonCodeGenerator def xrc_code_generator(obj): xrcgen = common.code_writers['XRC'] class SliderXrcObject(xrcgen.DefaultXrcObject): def write_property(self, name, val, outfile, tabs): if name == 'range': try: min, max = val.split(',') except ValueError: pass else: tab_s = ' '*tabs outfile.write(tab_s + '%s\n' % min) outfile.write(tab_s + '%s\n' % max) else: xrcgen.DefaultXrcObject.write_property(self, name, val, outfile, tabs) # end of class SliderXrcObject return SliderXrcObject(obj) class CppCodeGenerator: def get_code(self, obj): """\ generates the C++ code for wxSlider objects """ cppgen = common.code_writers['C++'] prop = obj.properties id_name, id = cppgen.generate_code_id(obj) if id_name: ids = [ id_name ] else: ids = [] value = prop.get('value', '0') try: min_v, max_v = [ s.strip() for s in prop['range'].split(',') ] except: min_v, max_v = '0', '10' if not obj.parent.is_toplevel: parent = '%s' % obj.parent.name else: parent = 'this' extra = '' style = prop.get("style") if style and style != 'wxSL_HORIZONTAL': extra = ', wxDefaultPosition, wxDefaultSize, %s' % style init = ['%s = new %s(%s, %s, %s, %s, %s%s);\n' % (obj.name, obj.klass, parent, id, value, min_v, max_v, extra)] props_buf = cppgen.generate_common_properties(obj) return init, ids, props_buf, [] def get_events(self, obj): cppgen = common.code_writers['C++'] return cppgen.get_events_with_type(obj, 'wxScrollEvent') # end of class CppCodeGenerator def initialize(): common.class_names['EditSlider'] = 'wxSlider' pygen = common.code_writers.get("python") if pygen: pygen.add_widget_handler('wxSlider', PythonCodeGenerator()) xrcgen = common.code_writers.get("XRC") if xrcgen: xrcgen.add_widget_handler('wxSlider', xrc_code_generator) cppgen = common.code_writers.get('C++') if cppgen: cppgen.add_widget_handler('wxSlider', CppCodeGenerator()) wxglade-0.6.8.orig/widgets/slider/slider.py0000644000175000017500000002132511677432002021106 0ustar georgeskgeorgesk# slider.py: wxSlider objects # # Copyright (c) 2002-2007 Alberto Griggio # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY import wx import common from edit_windows import ManagedBase from tree import Tree from widget_properties import * class EditSlider(ManagedBase): events = [ 'EVT_COMMAND_SCROLL', 'EVT_COMMAND_SCROLL_TOP', 'EVT_COMMAND_SCROLL_BOTTOM', 'EVT_COMMAND_SCROLL_LINEUP', 'EVT_COMMAND_SCROLL_LINEDOWN', 'EVT_COMMAND_SCROLL_PAGEUP', 'EVT_COMMAND_SCROLL_PAGEDOWN', 'EVT_COMMAND_SCROLL_THUMBTRACK', 'EVT_COMMAND_SCROLL_THUMBRELEASE', 'EVT_COMMAND_SCROLL_ENDSCROLL', ] def __init__(self, name, parent, id, style, sizer, pos, property_window, show=True): """\ Class to handle wxSlider objects """ ManagedBase.__init__(self, name, 'wxSlider', parent, id, sizer, pos, property_window, show=show) self.style = style self.value = 0 self.range = (0, 10) prop = self.properties self.access_functions['style'] = (self.get_style, self.set_style) self.access_functions['value'] = (self.get_value, self.set_value) self.access_functions['range'] = (self.get_range, self.set_range) style_labels = ('#section#' + _('Style'), 'wxSL_HORIZONTAL', 'wxSL_VERTICAL', 'wxSL_AUTOTICKS', 'wxSL_LABELS', 'wxSL_LEFT', 'wxSL_RIGHT', 'wxSL_TOP', 'wxSL_BOTTOM', 'wxSL_SELRANGE', 'wxSL_INVERSE') self.style_pos = (wx.SL_HORIZONTAL, wx.SL_VERTICAL, wx.SL_AUTOTICKS, wx.SL_LABELS, wx.SL_LEFT, wx.SL_RIGHT, wx.SL_TOP, wx.SL_BOTTOM, wx.SL_SELRANGE, wx.SL_INVERSE) tooltips = (_("Displays the slider horizontally (this is the default)."), _("Displays the slider vertically."), _("Displays tick marks."), _("Displays minimum, maximum and value labels."), _("Displays ticks on the left and forces the slider to be vertical."), _("Displays ticks on the right and forces the slider to be vertical."), _("Displays ticks on the top."), _("Displays ticks on the bottom (this is the default)."), _("Allows the user to select a range on the slider. Windows only."), _("Inverses the mininum and maximum endpoints on the slider. Not compatible with wxSL_SELRANGE.")) prop['style'] = CheckListProperty(self, 'style', None, style_labels, tooltips=tooltips) prop['range'] = TextProperty(self, 'range', None, can_disable=True, label=_("range")) prop['value'] = SpinProperty(self, 'value', None, can_disable=True, label=_("value")) def create_widget(self): self.widget = wx.Slider(self.parent.widget, self.id, self.value, self.range[0], self.range[1], style=self.style) def create_properties(self): ManagedBase.create_properties(self) panel = wx.ScrolledWindow(self.notebook, -1, style=wx.TAB_TRAVERSAL) prop = self.properties szr = wx.BoxSizer(wx.VERTICAL) prop['range'].display(panel) prop['value'].display(panel) prop['style'].display(panel) szr.Add(prop['range'].panel, 0, wx.EXPAND) szr.Add(prop['value'].panel, 0, wx.EXPAND) szr.Add(prop['style'].panel, 0, wx.EXPAND) panel.SetAutoLayout(True) panel.SetSizer(szr) szr.Fit(panel) self.notebook.AddPage(panel, _('Widget')) def get_style(self): retval = [0] * len(self.style_pos) try: for i in range(len(self.style_pos)): if self.style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.properties['style'].prepare_value(value) self.style = 0 for v in range(len(value)): if value[v]: self.style |= self.style_pos[v] if self.widget: self.widget.SetWindowStyleFlag(self.style) def get_range(self): return "%s, %s" % self.range def set_range(self, val): try: min_v, max_v = map(int, val.split(',')) except: self.properties['range'].set_value(self.get_range()) else: self.range = (min_v, max_v) self.properties['value'].set_range(min_v, max_v) if self.widget: self.widget.SetRange(min_v, max_v) def get_value(self): return self.value def set_value(self, value): value = int(value) if value != self.value: self.value = value if self.widget: self.widget.SetValue(value) # end of class EditSlider def builder(parent, sizer, pos, number=[1]): """\ factory function for EditStaticLine objects. """ class Dialog(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, _('Select style')) self.orientations = [ wx.SL_HORIZONTAL, wx.SL_VERTICAL ] self.orientation = wx.SL_HORIZONTAL prop = RadioProperty(self, 'orientation', self, ['wxSL_HORIZONTAL', 'wxSL_VERTICAL'], label=_("orientation")) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(prop.panel, 0, wx.ALL|wx.EXPAND, 10) style_labels = ('#section#', 'wxSL_AUTOTICKS', 'wxSL_LABELS', 'wxSL_LEFT', 'wxSL_RIGHT', 'wxSL_TOP') self.style_pos = (wx.SL_AUTOTICKS, wx.SL_LABELS, wx.SL_LEFT, wx.SL_RIGHT, wx.SL_TOP) self.style = 0 self.style_prop = CheckListProperty(self, 'style', self, style_labels) szr.Add(self.style_prop.panel, 0, wx.ALL|wx.EXPAND, 10) btn = wx.Button(self, wx.ID_OK, _('OK')) btn.SetDefault() szr.Add(btn, 0, wx.BOTTOM|wx.ALIGN_CENTER, 10) self.SetAutoLayout(True) self.SetSizer(szr) szr.Fit(self) self.CenterOnScreen() def __getitem__(self, value): if value == 'orientation': def set_orientation(o): self.orientation = self.orientations[o] return (lambda: self.orientation, set_orientation) else: return (self.get_style, self.set_style) def get_style(self): retval = [0] * len(self.style_pos) try: style = self.style for i in range(len(self.style_pos)): if style & self.style_pos[i]: retval[i] = 1 except AttributeError: pass return retval def set_style(self, value): value = self.style_prop.prepare_value(value) style = 0 for v in range(len(value)): if value[v]: style |= self.style_pos[v] self.style = style # end of inner class dialog = Dialog() dialog.ShowModal() label = 'slider_%d' % number[0] while common.app_tree.has_name(label): number[0] += 1 label = 'slider_%d' % number[0] slider = EditSlider(label, parent, wx.NewId(), dialog.orientation | dialog.style, sizer, pos, common.property_panel) node = Tree.Node(slider) slider.node = node slider.show_widget(True) common.app_tree.insert(node, sizer.node, pos-1) def xml_builder(attrs, parent, sizer, sizeritem, pos=None): """\ factory to build EditSlider objects from an xml file """ from xml_parse import XmlParsingError try: name = attrs['name'] except KeyError: raise XmlParsingError, _("'name' attribute missing") style = 0 if sizer is None or sizeritem is None: raise XmlParsingError, _("sizer or sizeritem object cannot be None") slider = EditSlider(name, parent, wx.NewId(), style, sizer, pos, common.property_panel) sizer.set_item(slider.pos, option=sizeritem.option, flag=sizeritem.flag, border=sizeritem.border) node = Tree.Node(slider) slider.node = node if pos is None: common.app_tree.add(node, sizer.node) else: common.app_tree.insert(node, sizer.node, pos-1) return slider def initialize(): """\ initialization function for the module: returns a wxBitmapButton to be added to the main palette. """ common.widgets['EditSlider'] = builder common.widgets_from_xml['EditSlider'] = xml_builder return common.make_object_button('EditSlider', 'icons/slider.xpm') wxglade-0.6.8.orig/widgets/slider/__init__.py0000644000175000017500000000064411621715605021366 0ustar georgeskgeorgesk# __init__.py: slider widget module initialization # $Id: __init__.py,v 1.8 2007/03/27 07:01:54 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY def initialize(): import common import codegen codegen.initialize() if common.use_gui: import slider return slider.initialize() wxglade-0.6.8.orig/widgets/__init__.py0000644000175000017500000000036511621715605020104 0ustar georgeskgeorgesk# __init__.py: here to please SPE... # $Id: __init__.py,v 1.2 2007/03/27 07:02:05 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY wxglade-0.6.8.orig/credits.txt0000644000175000017500000000403712150154266016521 0ustar georgeskgeorgesk Main Developer: --------------------------------------------------------------------------- - Carsten Grohmann Other Developers: --------------------------------------------------------------------------- - Alberto Griggio - Marcello Semboli - Guy Rutenberg - D.H. (Perl code generation) - Georges Khaznadar (debian package maintainer) Former Developers: --------------------------------------------------------------------------- - Marco Barisione - Kevin Walzer (OSX app bundle maintainer) Contributors: --------------------------------------------------------------------------- - Johan Vromans - Richard Lawson - Alex Thuering : general virtual sizers support and porting of the SplitterWindow to this new model - Brendan Oakley : editor of the new user's manual - Jack Thomasson : assist with port to wx namespace - Roel van Os : for some patches integrated from his Elentirmo repository Many thanks to: --------------------------------------------------------------------------- - Guido van Rossum and all the people at PSF for the excellent language - Robin Dunn, Julian Smart, Vadim Zeitlin, Robert Roebling and the wxWidgets team for their great libary - Glade developers for the inspiration they gave me and for the icons - Boa-constructor developers for some of the icons - Vaclav Slavik for the suggestions about XRC - Michael Gilfix for his wxPyColorChooser, used in the color dialog - ... and, of course, all the people who provided feedback, comments, critics and support (John Dubery in particular for his huge amount of bug reports). (We apologize with all the people that should be mentioned here but in fact aren't: if you think you are one of them, tell us and your name will be added ASAP) wxglade-0.6.8.orig/code_property.py0000644000175000017500000001535512150154266017560 0ustar georgeskgeorgesk# code_property.py: Property class for the 'code' property of toplevel widgets # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY from xml.sax.saxutils import escape, quoteattr import wx import wx.grid import widget_properties from widget_properties import GridProperty class CodeProperty(widget_properties.TextProperty): def __init__(self, owner, name='extracode'): setattr(owner, name, "") def get(): return getattr(owner, name) def set(val): return setattr(owner, name, val) owner.access_functions[name] = (get, set) widget_properties.TextProperty.__init__(self, owner, name, None, True, multiline=True) def _show(self, notebook, label=_('Code')): panel, new = _find_or_create_page(notebook, label) self.display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.panel, 1, wx.EXPAND) if new: panel.SetSizerAndFit(szr) notebook.AddPage(panel, label) else: sizer = panel.GetSizer() sizer.Add(szr, 1, wx.EXPAND) panel.Layout() def display(self, parent): self.id = wx.NewId() val = self.get_value() val = val.replace('\\n', '\n') sb = wx.StaticBox(parent, -1, "") label = widget_properties.wxGenStaticText(parent, -1, _('Extra code for this widget')) self._enabler = wx.CheckBox(parent, self.id+1, '') tooltip = """\ You can use this property to add some extra code to that generated by wxGlade. Please note that you should use this ability only if you have the \ "Overwrite existing sources" option set.""" style = wx.TE_MULTILINE|wx.HSCROLL self.text = wx.TextCtrl(parent, self.id, val, style=style, size=(1, -1)) font = wx.Font(12, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self.text.SetFont(font) label.SetToolTip(wx.ToolTip(tooltip)) wx.EVT_CHECKBOX(self._enabler, self.id+1, lambda event: self.toggle_active(event.IsChecked())) self.text.Enable(self.is_active()) self._enabler.SetValue(self.is_active()) self._target = self.text szr = wx.BoxSizer(wx.HORIZONTAL) szr.Add(label, 1, wx.ALL|wx.EXPAND, 3) szr.Add(self._enabler, 0, wx.ALL|wx.EXPAND, 3) sizer = wx.StaticBoxSizer(sb, wx.VERTICAL) sizer.Add(szr, 0, wx.EXPAND) sizer.Add(self.text, 1, wx.ALL|wx.EXPAND, 3) h = self.text.GetCharHeight() sizer.SetItemMinSize(self.text, -1, h*3) self.panel = sizer self.bind_event(self.on_change_val) wx.EVT_CHAR(self.text, self.on_char) # end of class CodeProperty class ExtraPropertiesProperty(GridProperty): def __init__(self, owner): setattr(owner, 'extraproperties', []) def get(): return getattr(owner, 'extraproperties') def set(val): return setattr(owner, 'extraproperties', val) owner.access_functions['extraproperties'] = (get, set) cols = [(_('Property'), GridProperty.STRING), (_('Value'), GridProperty.STRING)] self.label = _('Extra properties for this widget') GridProperty.__init__(self, owner, 'extraproperties', None, cols, can_insert=False) def write(self, outfile, tabs): if self.getter: props = self.getter() else: props = self.owner[self.name][0]() if props: written = False write = outfile.write stab = ' ' * (tabs+1) for name, value in props: if value: if not written: written = True write(' ' * tabs + '\n') write('%s%s\n' % (stab, quoteattr(name), escape(value.strip()))) if written: write(' ' * tabs + '\n') def display(self, panel): GridProperty.display(self, panel) self.btn.Hide() wx.grid.EVT_GRID_CELL_CHANGE(self.grid, self.on_change_val) tooltip = """\ You can use this property to add some extra custom properties to this widget. For each property "prop" with value "val", wxGlade will generate a \ "widget.SetProp(val)" line (or a "val" line for XRC).""" self.grid.SetToolTip(wx.ToolTip(tooltip)) def add_row(self, event): GridProperty.add_row(self, event) self.on_change_val(event) def remove_row(self, event): GridProperty.remove_row(self, event) self.on_change_val(event) def set_value(self, val): if isinstance(val, dict): val = [[k, val[k]] for k in sorted(val.keys())] GridProperty.set_value(self, val) def _show(self, notebook, label=_('Code')): panel, new = _find_or_create_page(notebook, label) self.display(panel) szr = wx.BoxSizer(wx.VERTICAL) szr.Add(self.panel, 1, wx.EXPAND) if new: panel.SetSizerAndFit(szr) notebook.AddPage(panel, _('Code')) else: sizer = panel.GetSizer() sizer.Add(szr, 1, wx.EXPAND) sizer.Layout() # end of class ExtraPropertiesProperty class ExtraPropertiesPropertyHandler(object): def __init__(self, owner): self.owner = owner self.props = {} self.prop_name = None self.curr_prop = [] def start_elem(self, name, attrs): if name == 'property': self.prop_name = attrs['name'] def end_elem(self, name): if name == 'property': if self.prop_name and self.curr_prop: self.props[self.prop_name] = ''.join(self.curr_prop) self.prop_name = None self.curr_prop = [] elif name == 'extraproperties': self.owner.properties['extraproperties'].set_value(self.props) val = [[k, self.props[k]] for k in sorted(self.props.keys())] self.owner.extraproperties = val return True # to remove this handler def char_data(self, data): data = data.strip() if data: self.curr_prop.append(data) # end of class ExtraPropertiesPropertyHandler def _find_or_create_page(notebook, label): """\ Searches the given notebook for a page whose label is "label". """ for i in xrange(notebook.GetPageCount()): if notebook.GetPageText(i) == label: return notebook.GetPage(i), False return wx.Panel(notebook, -1, style=wx.TAB_TRAVERSAL), True wxglade-0.6.8.orig/epydoc.conf0000644000175000017500000000207511647100573016457 0ustar georgeskgeorgesk#epydoc.conf - configuration file for epydoc used to generate the developer documentation for wxGlade [epydoc] # Epydoc section marker (required by ConfigParser) # Information about the project. name: wxGlade url: http://wxglade.sourceforge.net/ # The list of modules to document. Modules can be named using # dotted names, module filenames, or package directory names. # This option may be repeated. modules: ./ # Write html output to the directory "apidocs" output: html target: docs/apidocs # imports # Whether or not to list each module's imports. imports: yes # parse # Whether or not parsing should be used to examine objects. parse: yes # introspect # Whether or not introspection should be used to examine objects. introspect: no #for some reason using introspect creates many errors - Guy # graph # The list of graph types that should be automatically included # in the output. Graphs are generated using the Graphviz "dot" # executable. Graph types include: "classtree", "callgraph", # "umlclass". Use "all" to include all graph types graph: all wxglade-0.6.8.orig/ordereddict.py0000644000175000017500000001017512150154266017165 0ustar georgeskgeorgesk# Copyright (c) 2009 Raymond Hettinger # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. from UserDict import DictMixin class OrderedDict(dict, DictMixin): def __init__(self, *args, **kwds): if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: self.__end except AttributeError: self.clear() self.update(*args, **kwds) def clear(self): self.__end = end = [] end += [None, end, end] # sentinel node for doubly linked list self.__map = {} # key --> [key, prev, next] dict.clear(self) def __setitem__(self, key, value): if key not in self: end = self.__end curr = end[1] curr[2] = end[1] = self.__map[key] = [key, curr, end] dict.__setitem__(self, key, value) def __delitem__(self, key): dict.__delitem__(self, key) key, prev, next = self.__map.pop(key) prev[2] = next next[1] = prev def __iter__(self): end = self.__end curr = end[2] while curr is not end: yield curr[0] curr = curr[2] def __reversed__(self): end = self.__end curr = end[1] while curr is not end: yield curr[0] curr = curr[1] def popitem(self, last=True): if not self: raise KeyError('dictionary is empty') if last: key = reversed(self).next() else: key = iter(self).next() value = self.pop(key) return key, value def __reduce__(self): items = [[k, self[k]] for k in self] tmp = self.__map, self.__end del self.__map, self.__end inst_dict = vars(self).copy() self.__map, self.__end = tmp if inst_dict: return (self.__class__, (items,), inst_dict) return self.__class__, (items,) def keys(self): return list(self) setdefault = DictMixin.setdefault update = DictMixin.update pop = DictMixin.pop values = DictMixin.values items = DictMixin.items iterkeys = DictMixin.iterkeys itervalues = DictMixin.itervalues iteritems = DictMixin.iteritems def __repr__(self): if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, self.items()) def copy(self): return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): if isinstance(other, OrderedDict): if len(self) != len(other): return False for p, q in zip(self.items(), other.items()): if p != q: return False return True return dict.__eq__(self, other) def __ne__(self, other): return not self == other wxglade-0.6.8.orig/wxglade0000755000175000017500000000227512150154266015706 0ustar georgeskgeorgesk#!/bin/sh # # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY # # Copyright 2011-2012 Carsten Grohmann # # Shell script to start wxGlade # # The wxGlade main script is called wxglade.py. It will be searched at # three places: # 1. parallel to this script # 2. in the module directory of the current Python # 3. in a parallel Python module directory # determinate current python version PY_VERSION=$(python -c 'import sys; print sys.version[:3]') # determinate prefix of the Python module directory structure if [ -e /etc/debian_version ]; then WXGLADE_MODULE_PATH="/usr/lib/pymodules/python${PY_VERSION}/wxglade" else WXGLADE_MODULE_PATH="/usr/lib/python${PY_VERSION}/wxglade" fi CURR_DIR=$(dirname $0) # search wxglade.py if [ -e "${CURR_DIR}/wxglade.py" ]; then WXG_PATH="${CURR_DIR}/wxglade.py" elif [ -e "${WXGLADE_MODULE_PATH}/wxglade.py" ]; then WXG_PATH="${WXGLADE_MODULE_PATH}/wxglade.py" elif [ -e "${CURR_DIR}/../lib/python${PY_VERSION}/site-packages/wxglade/wxglade.py" ]; then WXG_PATH="${CURR_DIR}/../lib/python${PY_VERSION}/site-packages/wxglade/wxglade.py" else echo "ERROR: wxglade.py not found!" exit 1 fi # exec wxGlade exec python "${WXG_PATH}" "$@" wxglade-0.6.8.orig/configUI.py0000755000175000017500000002210012150154266016372 0ustar georgeskgeorgesk#!/usr/bin/env python # -*- coding: ISO-8859-15 -*- # # generated by wxGlade 5a9daca7f1cd+ on Sun Mar 31 10:51:16 2013 # import wx # begin wxGlade: dependencies import gettext # end wxGlade # begin wxGlade: extracode import common import os _icon_path = os.path.join(common.icons_path, 'icon.xpm') # end wxGlade class wxGladePreferencesUI(wx.Dialog): def __init__(self, *args, **kwds): # begin wxGlade: wxGladePreferencesUI.__init__ kwds["style"] = wx.DEFAULT_DIALOG_STYLE wx.Dialog.__init__(self, *args, **kwds) self.notebook_1 = wx.Notebook(self, wx.ID_ANY, style=0) self.notebook_1_pane_1 = wx.Panel(self.notebook_1, wx.ID_ANY) self.use_menu_icons = wx.CheckBox(self.notebook_1_pane_1, wx.ID_ANY, _("Use icons in menu items")) self.frame_tool_win = wx.CheckBox(self.notebook_1_pane_1, wx.ID_ANY, _("Show properties and tree windows as small frames")) self.show_progress = wx.CheckBox(self.notebook_1_pane_1, wx.ID_ANY, _("Show progress dialog when loading wxg files")) self.remember_geometry = wx.CheckBox(self.notebook_1_pane_1, wx.ID_ANY, _("Remember position and size of wxGlade windows")) self.show_sizer_handle = wx.CheckBox(self.notebook_1_pane_1, wx.ID_ANY, _("Show \"handles\" of sizers")) self.use_kde_dialogs = wx.CheckBox(self.notebook_1_pane_1, wx.ID_ANY, _("Use native file dialogs on KDE")) self.show_completion = wx.CheckBox(self.notebook_1_pane_1, wx.ID_ANY, _("Show success message for code generation")) self.open_save_path = wx.TextCtrl(self.notebook_1_pane_1, wx.ID_ANY, "") self.codegen_path = wx.TextCtrl(self.notebook_1_pane_1, wx.ID_ANY, "") self.number_history = wx.SpinCtrl(self.notebook_1_pane_1, wx.ID_ANY, "4", min=0, max=100) self.buttons_per_row = wx.SpinCtrl(self.notebook_1_pane_1, wx.ID_ANY, "5", min=1, max=100) self.notebook_1_pane_2 = wx.Panel(self.notebook_1, wx.ID_ANY) self.use_dialog_units = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Use dialog units by default for size properties")) self.wxg_backup = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Create backup wxg files")) self.codegen_backup = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Create backup files for generated source")) self.allow_duplicate_names = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Allow duplicate widget names")) self.default_border = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Default border width for widgets")) self.default_border_size = wx.SpinCtrl(self.notebook_1_pane_2, wx.ID_ANY, "", min=0, max=20) self.autosave = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Auto save wxg files every ")) self.autosave_delay = wx.SpinCtrl(self.notebook_1_pane_2, wx.ID_ANY, "120", min=30, max=300) self.write_timestamp = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Insert timestamp on generated source files")) self.write_generated_from = wx.CheckBox(self.notebook_1_pane_2, wx.ID_ANY, _("Insert .wxg file name on generated source files")) self.backup_suffix = wx.RadioBox(self.notebook_1_pane_2, wx.ID_ANY, _("Backup options"), choices=[_("append ~ to filename"), _("append .bak to filename")], majorDimension=2, style=wx.RA_SPECIFY_COLS) self.local_widget_path = wx.TextCtrl(self.notebook_1_pane_2, wx.ID_ANY, "") self.choose_widget_path = wx.Button(self.notebook_1_pane_2, wx.ID_ANY, _("..."), style=wx.BU_EXACTFIT) self.sizer_6_staticbox = wx.StaticBox(self.notebook_1_pane_2, wx.ID_ANY, _("Local widget path")) self.ok = wx.Button(self, wx.ID_OK, "") self.cancel = wx.Button(self, wx.ID_CANCEL, "") self.__set_properties() self.__do_layout() # end wxGlade def __set_properties(self): # begin wxGlade: wxGladePreferencesUI.__set_properties self.SetTitle(_("wxGlade: preferences")) _icon = wx.EmptyIcon() _icon.CopyFromBitmap(wx.Bitmap(_icon_path, wx.BITMAP_TYPE_ANY)) self.SetIcon(_icon) self.use_menu_icons.SetValue(1) self.frame_tool_win.SetValue(1) self.show_progress.SetValue(1) self.remember_geometry.SetValue(1) self.show_sizer_handle.SetValue(1) self.use_kde_dialogs.SetValue(1) self.show_completion.SetValue(1) self.open_save_path.SetMinSize((196, -1)) self.codegen_path.SetMinSize((196, -1)) self.number_history.SetMinSize((196, -1)) self.buttons_per_row.SetMinSize((196, -1)) self.wxg_backup.SetValue(1) self.codegen_backup.SetValue(1) self.allow_duplicate_names.Hide() self.default_border_size.SetMinSize((45, 22)) self.autosave_delay.SetMinSize((45, 22)) self.write_timestamp.SetValue(1) self.backup_suffix.SetSelection(0) self.ok.SetDefault() # end wxGlade def __do_layout(self): # begin wxGlade: wxGladePreferencesUI.__do_layout sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_2 = wx.BoxSizer(wx.HORIZONTAL) sizer_5 = wx.BoxSizer(wx.VERTICAL) self.sizer_6_staticbox.Lower() sizer_6 = wx.StaticBoxSizer(self.sizer_6_staticbox, wx.HORIZONTAL) sizer_7_copy = wx.BoxSizer(wx.HORIZONTAL) sizer_7 = wx.BoxSizer(wx.HORIZONTAL) sizer_3 = wx.BoxSizer(wx.VERTICAL) sizer_4 = wx.FlexGridSizer(4, 2, 0, 0) sizer_3.Add(self.use_menu_icons, 0, wx.ALL | wx.EXPAND, 5) sizer_3.Add(self.frame_tool_win, 0, wx.ALL | wx.EXPAND, 5) sizer_3.Add(self.show_progress, 0, wx.ALL | wx.EXPAND, 5) sizer_3.Add(self.remember_geometry, 0, wx.ALL | wx.EXPAND, 5) sizer_3.Add(self.show_sizer_handle, 0, wx.ALL | wx.EXPAND, 5) sizer_3.Add(self.use_kde_dialogs, 0, wx.ALL | wx.EXPAND, 5) sizer_3.Add(self.show_completion, 0, wx.ALL | wx.EXPAND, 5) label_1 = wx.StaticText(self.notebook_1_pane_1, wx.ID_ANY, _("Initial path for \nfile opening/saving dialogs:")) sizer_4.Add(label_1, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) sizer_4.Add(self.open_save_path, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) label_2_copy = wx.StaticText(self.notebook_1_pane_1, wx.ID_ANY, _("Initial path for \ncode generation file dialogs:")) sizer_4.Add(label_2_copy, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) sizer_4.Add(self.codegen_path, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) label_2 = wx.StaticText(self.notebook_1_pane_1, wx.ID_ANY, _("Number of items in file history")) sizer_4.Add(label_2, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) sizer_4.Add(self.number_history, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) label_2_copy_1 = wx.StaticText(self.notebook_1_pane_1, wx.ID_ANY, _("Number of buttons per row\nin the main palette")) sizer_4.Add(label_2_copy_1, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) sizer_4.Add(self.buttons_per_row, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) sizer_4.AddGrowableCol(1) sizer_3.Add(sizer_4, 0, wx.EXPAND, 3) self.notebook_1_pane_1.SetSizer(sizer_3) sizer_5.Add(self.use_dialog_units, 0, wx.ALL | wx.EXPAND, 5) sizer_5.Add(self.wxg_backup, 0, wx.ALL | wx.EXPAND, 5) sizer_5.Add(self.codegen_backup, 0, wx.ALL | wx.EXPAND, 5) sizer_5.Add(self.allow_duplicate_names, 0, wx.ALL | wx.EXPAND, 5) sizer_7.Add(self.default_border, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) sizer_7.Add(self.default_border_size, 0, wx.ALL, 5) sizer_5.Add(sizer_7, 0, wx.EXPAND, 0) sizer_7_copy.Add(self.autosave, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, 5) sizer_7_copy.Add(self.autosave_delay, 0, wx.TOP | wx.BOTTOM, 5) label_3 = wx.StaticText(self.notebook_1_pane_2, wx.ID_ANY, _(" seconds")) sizer_7_copy.Add(label_3, 0, wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL | wx.FIXED_MINSIZE, 5) sizer_5.Add(sizer_7_copy, 0, wx.EXPAND, 0) sizer_5.Add(self.write_timestamp, 0, wx.ALL | wx.EXPAND, 5) sizer_5.Add(self.write_generated_from, 0, wx.ALL | wx.EXPAND, 5) sizer_5.Add(self.backup_suffix, 0, wx.ALL | wx.EXPAND, 5) sizer_6.Add(self.local_widget_path, 1, wx.ALL, 3) sizer_6.Add(self.choose_widget_path, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) sizer_5.Add(sizer_6, 0, wx.ALL | wx.EXPAND, 5) self.notebook_1_pane_2.SetSizer(sizer_5) self.notebook_1.AddPage(self.notebook_1_pane_1, _("Interface")) self.notebook_1.AddPage(self.notebook_1_pane_2, _("Other")) sizer_1.Add(self.notebook_1, 1, wx.ALL | wx.EXPAND, 5) sizer_2.Add(self.ok, 0, 0, 0) sizer_2.Add(self.cancel, 0, wx.LEFT, 10) sizer_1.Add(sizer_2, 0, wx.ALL | wx.ALIGN_RIGHT, 10) self.SetSizer(sizer_1) sizer_1.Fit(self) self.Layout() self.Centre() # end wxGlade # end of class wxGladePreferencesUI if __name__ == "__main__": gettext.install("app") # replace with the appropriate catalog name app = wx.PySimpleApp(0) wx.InitAllImageHandlers() dialog_1 = wxGladePreferencesUI(None, wx.ID_ANY, "") app.SetTopWindow(dialog_1) dialog_1.Show() app.MainLoop() wxglade-0.6.8.orig/res/0000755000175000017500000000000012170277707015120 5ustar georgeskgeorgeskwxglade-0.6.8.orig/res/preferences.wxg0000644000175000017500000005347212150154266020153 0ustar georgeskgeorgesk import common\nimport os\n\n_icon_path = os.path.join(common.icons_path, 'icon.xpm')\n var:_icon_path wxGlade: preferences 1 wxVERTICAL wxALL|wxEXPAND 5 Interface Other wxVERTICAL wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxEXPAND 3 0 4 1 2 0 wxALL|wxALIGN_CENTER_VERTICAL 5 0 wxALL|wxALIGN_CENTER_VERTICAL 5 196, -1 wxALL|wxALIGN_CENTER_VERTICAL 5 0 wxALL|wxALIGN_CENTER_VERTICAL 5 196, -1 wxALL|wxALIGN_CENTER_VERTICAL 5 0 wxALL|wxALIGN_CENTER_VERTICAL 5 0, 100 4 196, -1 wxALL|wxALIGN_CENTER_VERTICAL 5 0 wxALL|wxALIGN_CENTER_VERTICAL 5 1, 100 5 196, -1 wxVERTICAL wxALL|wxEXPAND 5 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 1 wxEXPAND 0 wxHORIZONTAL wxALL|wxALIGN_CENTER_VERTICAL 5 wxALL 5 0, 20 45, 22 wxEXPAND 0 wxHORIZONTAL wxLEFT|wxTOP|wxBOTTOM|wxALIGN_CENTER_VERTICAL 5 wxTOP|wxBOTTOM 5 30, 300 120 45, 22 wxTOP|wxBOTTOM|wxALIGN_CENTER_VERTICAL|wxFIXED_MINSIZE 5 0 wxALL|wxEXPAND 5 1 wxALL|wxEXPAND 5 wxALL|wxEXPAND 5 0 2 append ~ to filename append .bak to filename wxALL|wxEXPAND 5 wxHORIZONTAL wxALL 3 wxALL|wxALIGN_CENTER_VERTICAL 3 wxALL|wxALIGN_RIGHT 10 wxHORIZONTAL 0 OK 1 wxLEFT 10 CANCEL wxglade-0.6.8.orig/res/messagedialog.wxg0000644000175000017500000000605512167336636020464 0ustar georgeskgeorgesk wxGlade message 1 250, 112d wxVERTICAL wxALL|wxALIGN_CENTER_HORIZONTAL 5 1 -1 default bold 0 wxLEFT|wxRIGHT|wxEXPAND 5 wxHORIZONTAL wxALIGN_CENTER_HORIZONTAL 0 1 code:wx.ArtProvider_GetBitmap(wx.ART_TIP, wx.ART_MESSAGE_BOX, (48, 48)) 48, 48 wxLEFT|wxEXPAND 10 wxALL|wxALIGN_RIGHT 10 OK wxglade-0.6.8.orig/res/templates_ui.wxg0000644000175000017500000003526312150154266020343 0ustar georgeskgeorgesk wxGlade template information 1 250, 264d wxVERTICAL wxEXPAND 0 wxHORIZONTAL wxALL|wxALIGN_CENTER_VERTICAL 10 0 -1 default bold 0 wxALL|wxALIGN_CENTER_VERTICAL 10 1 wxALL|wxEXPAND 5 wxHORIZONTAL 0 wxALL|wxEXPAND 5 wxHORIZONTAL wxEXPAND 0 wxALL|wxEXPAND 5 wxHORIZONTAL wxEXPAND 0 wxALL|wxALIGN_RIGHT 10 wxHORIZONTAL 0 OK wxLEFT 10 CANCEL wxGlade template list 1 300, 200d wxVERTICAL wxEXPAND 0 wxHORIZONTAL wxALL|wxEXPAND 5 wxVERTICAL wxALL|wxEXPAND 3 0 on_select_template on_open wxEXPAND 0 wxVERTICAL wxALL|wxALIGN_CENTER_VERTICAL 7 1 -1 default bold 0 wxALL|wxEXPAND 5 wxHORIZONTAL 0 wxALL|wxEXPAND 5 wxHORIZONTAL wxEXPAND 0 wxALL|wxEXPAND 5 wxHORIZONTAL wxEXPAND 0 wxALL|wxALIGN_RIGHT 10 wxHORIZONTAL 0 OPEN on_open wxLEFT 10 try:\n ID_EDIT = wx.ID_EDIT\nexcept AttributeError:\n ID_EDIT = wx.NewId()\n ID_EDIT on_edit wxLEFT 10 DELETE on_delete wxLEFT 10 CANCEL wxglade-0.6.8.orig/tests/0000755000175000017500000000000012170277707015471 5ustar georgeskgeorgeskwxglade-0.6.8.orig/tests/test_gui.py0000755000175000017500000002443312161625061017665 0ustar georgeskgeorgesk""" @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import test base class from tests import WXGladeBaseTest # import general python modules import cStringIO import sys import wx # import project modules import config import common class TestGui(WXGladeBaseTest): """\ Test GUI functionality Since Python created an own instance for each test, we use class varaibles for persistent storing L{app} and L{frame}. @cvar app: Reference to a wx.App object. he object is persistent after the creation in L{setUp()}. @cvar frame: Reference to L{main.wxGladeFrame}. The object is persistent after the creation in L{setUp()}. @ivar orig_stdout: Original fd for stdout. """ init_stage1 = True init_use_gui = True app = None frame = None orig_stdout = None def mockMessageBox(self, message, caption, *args, **kwargs): """\ Mock object for wx.MessageBox """ self._messageBox = [message, caption] def setUp(self): # redirect stdout self.orig_stdout = sys.stdout sys.stdout = cStringIO.StringIO() # initialse base class WXGladeBaseTest.setUp(self) import main import wx # inject mock object for wxMessageBox self._messageBox = [] wx.MessageBox = self.mockMessageBox # create an simply application if not TestGui.app: TestGui.app = wx.PySimpleApp() wx.InitAllImageHandlers() wx.ArtProvider.PushProvider(main.wxGladeArtProvider()) if not TestGui.frame: self.frame = main.wxGladeFrame() # hide all windows self.frame.Hide() self.frame.hide_all() TestGui.frame = self.frame # show dialog "Code generation completed successfully" config.preferences.show_completion = True def tearDown(self): # restore original stdout if self.orig_stdout: sys.stdout = self.orig_stdout # initialse base class WXGladeBaseTest.tearDown(self) def _FindWindowByName(self, name): """\ Search and return a widget with the given name in the top window widget tree. """ app = wx.GetApp() top = app.GetTopWindow() return top.FindWindowByName(name) def _generate_code(self): """\ Search button with label "Generate code" and press it """ # search wx.Button "Generate code" btn_codegen = self._FindWindowByName("BtnGenerateCode") self.failUnless( btn_codegen, 'Button with label "Generate code" not found' ) # press button to generate code self._press_button(btn_codegen) def _press_button(self, button): """\ Simulate pressing the button by sending a button clicked event """ event = wx.CommandEvent( wx.wxEVT_COMMAND_BUTTON_CLICKED, button.GetId() ) button.GetEventHandler().ProcessEvent(event) def _set_lang(self, lang): """\ Set "Language" and simulate clicking radio button @param lang: Language to set @type lang: StringIO """ radiobox= common.app_tree.app.codewriters_prop.options radiobox.SetStringSelection(lang) event = wx.CommandEvent( wx.wxEVT_COMMAND_RADIOBOX_SELECTED, radiobox.GetId() ) radiobox.GetEventHandler().ProcessEvent(event) def testNotebookWithoutTabs(self): """\ Test loading Notebook without tabs """ self._messageBox = None infile = cStringIO.StringIO( self._load_file('Notebook_wo_tabs.wxg') ) self.frame._open_app( infilename=infile, use_progress_dialog=False, is_filelike=True, add_to_history=False, ) err_msg = u'Error loading file None: Notebook widget' \ ' "notebook_1" does not have any tabs! ' \ '_((line: 18, column: 20))' err_caption = u'Error' self.failUnless( [err_msg, err_caption] == self._messageBox, '''Expected wxMessageBox(message=%s, caption=%s)''' % ( err_msg, err_caption ) ) def testNotebookWithTabs(self): """\ Test loading Notebook with tabs """ self._messageBox = None infile = cStringIO.StringIO( self._load_file('Notebook_w_tabs.wxg') ) self.frame._open_app( infilename=infile, use_progress_dialog=False, is_filelike=True, add_to_history=False, ) self.failIf( self._messageBox, 'Loading test wxg file caused an error message: %s' % \ self._messageBox ) def testCodeGeneration(self): """\ Test GUI code generation """ source = self._load_file('FontColour.wxg') source = self._modify_attrs( source, path='', ) infile = cStringIO.StringIO(source) self.frame._open_app( infilename=infile, use_progress_dialog=False, is_filelike=True, add_to_history=False, ) # generate code self._generate_code() # first test should fail because no output file is given #print self._messageBox err_msg = u'You must specify an output file\n' \ 'before generating any code' err_caption = u'Error' self.failUnless( [err_msg, err_caption] == self._messageBox, '''Expected wxMessageBox(message=%s, caption=%s)''' % ( err_msg, err_caption ) ) self._messageBox = None # now test full code generation for filename, language in [ ['FontColour.lisp', 'lisp'], ['FontColour.pl', 'perl'], ['FontColour.py', 'python'], ['FontColour.xrc', 'XRC'], ['FontColour', 'C++'], ]: # check for langage first self.failUnless( language in common.code_writers, "No codewriter loaded for %s" % language ) # prepare and open wxg source = self._prepare_wxg(language, source) infile = cStringIO.StringIO(source) self.frame._open_app( infilename=infile, use_progress_dialog=False, is_filelike=True, add_to_history=False, ) # set "Output path", language and generate code common.app_tree.app.output_path = filename self._set_lang(language) self._generate_code() success_msg = u'Code generation completed successfully' success_caption = u'Information' self.failUnless( [success_msg, success_caption] == self._messageBox, '''Expected wxMessageBox(message=%s, caption=%s)''' % ( success_msg, success_caption ) ) self._messageBox = None if language == 'C++': name_h = '%s.h' % filename name_cpp = '%s.cpp' % filename result_cpp = self._load_file(name_cpp) result_h = self._load_file(name_h) generated_cpp = self.vFiles[name_cpp].getvalue() generated_h = self.vFiles[name_h].getvalue() self._compare(result_cpp, generated_cpp, 'C++ source') self._compare(result_h, generated_h, 'C++ header') else: expected = self._load_file(filename) generated = self.vFiles[filename].getvalue() self._compare(expected, generated) def test_StylelessDialog(self): """\ Test code generation for a style less dialog """ source = self._load_file('styleless-dialog.wxg') # now test full code generation for filename, language in [ ['styleless-dialog.lisp', 'lisp'], ['styleless-dialog.pl', 'perl'], ['styleless-dialog.py', 'python'], ['styleless-dialog.xrc', 'XRC'], ['styleless-dialog', 'C++'], ]: # check for langage first self.failUnless( language in common.code_writers, "No codewriter loaded for %s" % language ) # prepare and open wxg source = self._prepare_wxg(language, source) infile = cStringIO.StringIO(source) self.frame._open_app( infilename=infile, use_progress_dialog=False, is_filelike=True, add_to_history=False, ) # set "Output path", language and generate code common.app_tree.app.output_path = filename self._set_lang(language) self._generate_code() success_msg = u'Code generation completed successfully' success_caption = u'Information' self.failUnless( [success_msg, success_caption] == self._messageBox, '''Expected wxMessageBox(message=%s, caption=%s)''' % ( success_msg, success_caption ) ) self._messageBox = None if language == 'C++': name_h = '%s.h' % filename name_cpp = '%s.cpp' % filename result_cpp = self._load_file(name_cpp) result_h = self._load_file(name_h) generated_cpp = self.vFiles[name_cpp].getvalue() generated_h = self.vFiles[name_h].getvalue() self._compare(result_cpp, generated_cpp, 'C++ source') self._compare(result_h, generated_h, 'C++ header') else: expected = self._load_file(filename) generated = self.vFiles[filename].getvalue() self._compare(expected, generated) wxglade-0.6.8.orig/tests/test_codegen.py0000644000175000017500000013400012167341476020505 0ustar georgeskgeorgesk""" @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ import cStringIO import re # import test base class from tests import WXGladeBaseTest # import project modules import common import misc class MockCodeObject(object): """\ Mock object for L{xml_parse.CodeObject} """ preview = False properties = {} in_sizers = False in_windows = False name = '' klass = '' class MockSourceFileContent(object): """\ Mock object for L{codegen.BaseSourceFileContent} """ spaces = {} class TestCodeGen(WXGladeBaseTest): """\ Test code generation """ def tearDown(self): """\ Cleanup """ common.code_writers['python'].use_new_namespace = 1 WXGladeBaseTest.tearDown(self) def test_CPP_wxCalendarCtrl(self): """\ Test CPP code generation with a small wxCalendarCtrl example The test also tests for Sourceforge bug #2782306 @see: L{wxglade.widgets.calendar_ctrl.calendar_ctrl} """ self._generate_and_compare_cpp( 'CPP_wxCalendarCtrl.wxg', 'CPP_wxCalendarCtrl' ) def test_CPP_Preferences(self): """\ Test C++ code generation with preferences dialog @see: L{codegen.cpp_codegen} """ self._generate_and_compare_cpp( 'CPP_Preferences.wxg', 'CPP_Preferences' ) def test_Lisp_quote_path(self): """\ Test codegen.lisp_codegen.quote_path() @see: L{codegen.lisp_codegen.LispCodeWriter.quote_path()} """ quote_path = common.code_writers['lisp'].quote_path examples = [ ('icon.png', '"icon.png"'), ('/usr', '"/usr"'), ('/usr/shar/icons/iso.png', '"/usr/shar/icons/iso.png"'), (r'C:\Temp', r'"C:\\Temp"'), ('/tmp/wx""glade', r'"/tmp/wx\"\"glade"'), ] for unquoted, tquoted in examples: aquoted = quote_path(unquoted) self.assertEqual( aquoted, tquoted, "Lisp quotation for '%s' returned '%s' expected '%s'" % ( unquoted, aquoted, tquoted, ) ) def test_Lisp_Preferences(self): """\ Test Lisp code generation with preferences dialog @see: L{codegen.lisp_codegen} """ self._generate_and_compare( 'lisp', 'Lisp_Preferences.wxg', 'Lisp_Preferences.lisp' ) def test_Lisp_wxBitmapButton(self): """\ Test Lisp code generation with small wxBitmapButton example @see: L{wxglade.widgets.bitmap_button.lisp_codegen} """ self._generate_and_compare( 'lisp', 'Lisp_wxBitmapButton.wxg', 'Lisp_wxBitmapButton.lisp' ) def test_Perl_Preferences(self): """\ Test Perl code generation with preferences dialog @see: L{codegen.pl_codegen} """ self._generate_and_compare( 'perl', 'Perl_Preferences.wxg', 'Perl_Preferences.pl' ) def test_Python_Preferences(self): """\ Test Python code generation with preferences dialog @see: L{codegen.py_codegen} """ self._generate_and_compare( 'python', 'Preferences.wxg', 'Python_Preferences.py' ) def test_CalendarCtrl(self): """\ Test code generation for a CalendarCtrl """ self._generate_and_compare( 'perl', 'CalendarCtrl.wxg', 'CalendarCtrl.pl' ) self._generate_and_compare( 'python', 'CalendarCtrl.wxg', 'CalendarCtrl.py' ) self._generate_and_compare( 'XRC', 'CalendarCtrl.wxg', 'CalendarCtrl.xrc' ) self._generate_and_compare_cpp( 'CalendarCtrl.wxg', 'CalendarCtrl' ) def test_FontColour(self): """\ Test code generation for fonts and colours """ self._test_all('FontColour') def test_Grid(self): """\ Test code generation with a grid widgets and handling events """ self._test_all('Grid') def test_Gauge(self): """\ Test code generation for a wxGauge """ self._test_all('Gauge') def test_HyperlinkCtrl(self): """\ Test code generation for a HyperlinkCtrl for wxWidgets 2.6 and 2.8 """ # test for wxWidgets 2.6.X self._test_all('HyperlinkCtrl_26') # test for wxWidgets 2.8.X self._test_all('HyperlinkCtrl_28') def test_generate_code_id(self): """\ Test id code generation of all code generators @see: L{codegen.cpp_codegen.CPPCodeWriter.generate_code_id()} @see: L{codegen.lisp_codegen.LispCodeWriter.generate_code_id()} @see: L{codegen.pl_codegen.PerlCodeWriter.generate_code_id()} @see: L{codegen.py_codegen.PythonCodeWriter.generate_code_id()} """ # create dummy code object first obj = MockCodeObject() obj.preview = False obj.properties = {'id': 'wxID_ANY'} gen_id = common.code_writers['python'].generate_code_id cn = common.code_writers['python'].cn # check preview mode first obj.preview = True name, value = gen_id(obj) self.failUnless( (name, value) == ('', '-1'), """Expect "('s', '-1')" got "('%s', '%s')"!""" % (name, value) ) # now we check non-preview only obj.preview = False # test for Python for test_id, target_decl, target_value in [ ['wxID_ANY', '', cn('wxID_ANY')], # id => "wxID_ANY" ['=wxID_ANY', '', cn('wxID_ANY')], # id => "=wxID_ANY" (ugly!) ['', '', cn('wxID_ANY')], # id => "" ['self.myid', '', 'self.myid'], # id => "self.myid" (predefined class member) ['self.myid=1', 'self.myid = 1\n', 'self.myid'], # id => "self.myid=1" ['self.myid=?', 'self.myid = %s\n' % cn('wxNewId()') , 'self.myid'], # id => "self.myid=?" ['myid', '', 'myid'], # id => "myid" (global value and not a class member) ['myid = 1', 'global myid; myid = 1\n', 'myid'], # id => "myid=1" (declare new global variable and store value) ]: obj.properties['id'] = test_id act_decl, act_value = gen_id(obj) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For Python expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) act_decl, act_value = gen_id(None, test_id) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For Python expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) # test for C++ gen_id = common.code_writers['C++'].generate_code_id for test_id, target_decl, target_value in [ ['wxID_ANY', '', 'wxID_ANY'], # id => "wxID_ANY" ['=wxID_ANY', '', 'wxID_ANY'], # id => "=wxID_ANY" (ugly!) ['', '', 'wxID_ANY'], # id => "" ['myid', '', 'myid'], # id => "myid" (predefined variable) ['myid=1', 'myid = 1', 'myid'], # id => "myid=1" ['myid=?', 'myid = wxID_HIGHEST + 1000', 'myid'], # id => "myid=?" ['myid=?', 'myid = wxID_HIGHEST + 1001', 'myid'], # id => "myid=?" ]: obj.properties['id'] = test_id act_decl, act_value = gen_id(obj) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For C++ expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) for test_id, target_decl, target_value in [ ['wxID_ANY', '', 'wxID_ANY'], # id => "wxID_ANY" ['=wxID_ANY', '', 'wxID_ANY'], # id => "=wxID_ANY" (ugly!) ['', '', 'wxID_ANY'], # id => "" ['myid', '', 'myid'], # id => "myid" (predefined variable) ['myid=1', 'myid = 1', 'myid'], # id => "myid=1" ['myid=?', 'myid = wxID_HIGHEST + 1002', 'myid'], # id => "myid=?" ['myid=?', 'myid = wxID_HIGHEST + 1003', 'myid'], # id => "myid=?" ]: act_decl, act_value = gen_id(None, test_id) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For C++ expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) # test for Perl lang = 'Perl' gen_id = common.code_writers['perl'].generate_code_id cn = common.code_writers['perl'].cn for test_id, target_decl, target_value in [ ['wxID_ANY', '', cn('wxID_ANY')], # id => "wxID_ANY" ['=wxID_ANY', '', cn('wxID_ANY')], # id => "=wxID_ANY" (ugly!) ['', '', cn('wxID_ANY')], # id => "" ['myid', '', 'myid'], # id => "myid" (predefined variable) ['myid=1', 'use constant myid => 1;\n', 'myid'], # id => "myid=1" ['myid=?', 'use constant myid => %s;\n' % cn('wxNewId()') , 'myid'], # id => "myid=?" ]: obj.properties['id'] = test_id act_decl, act_value = gen_id(obj) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For Perl expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) act_decl, act_value = gen_id(None, test_id) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For Perl expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) # test for Lisp gen_id = common.code_writers['lisp'].generate_code_id cn = common.code_writers['lisp'].cn for test_id, target_decl, target_value in [ ['wxID_ANY', '', cn('wxID_ANY')], # id => "wxID_ANY" ['=wxID_ANY', '', cn('wxID_ANY')], # id => "=wxID_ANY" (ugly!) ['', '', cn('wxID_ANY')], # id => "" ['myid', '', 'myid'], # id => "myid" (predefined variable) ['myid=1', 'global myid; myid = 1\n', 'myid'], # id => "myid=1" ['myid=?', 'global myid; myid = %s\n' % cn('wxNewId()') , 'myid'], # id => "myid=?" ]: obj.properties['id'] = test_id act_decl, act_value = gen_id(obj) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For Lisp expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) act_decl, act_value = gen_id(None, test_id) self.failUnless( (act_decl, act_value) == (target_decl, target_value), """For Lisp expected "('%s', '%s')" got "('%s', '%s')"!""" % \ (target_decl, target_value, act_decl, act_value) ) def test_Python_Ogg1(self): """\ Test Python code generation with overwriting a single existing file @see: L{codegen.py_codegen.PythonCodeWriter} """ self._generate_and_compare( 'python', 'PyOgg1.wxg', 'PyOgg1.py' ) # load XML input file source = self._load_file('PyOgg1.wxg') expected = self._load_file('PyOgg1_oldnamespace.py') source = self._modify_attrs(source, name='app', overwrite='1', path='PyOgg1_oldnamespace.py', use_new_namespace='0', ) # generate code self._generate_code('python', source, 'PyOgg1_oldnamespace.py') generated = self.vFiles['PyOgg1_oldnamespace.py'].getvalue() self._compare(expected, generated) def test_Python_Ogg2(self): """\ Test Python code generation with overwriting two existing files @see: L{codegen.py_codegen.PythonCodeWriter} """ source = self._load_file('PyOgg2.wxg') source = self._modify_attrs(source, overwrite='0', ) result_app = self._load_file('PyOgg2_app.py') result_dialog = self._load_file('PyOgg2_MyDialog.py') result_frame = self._load_file('PyOgg2_MyFrame.py') self._generate_code('python', source, './') generated_app = self.vFiles['./PyOgg2_app.py'].getvalue() generated_dialog = self.vFiles['./PyOgg2_MyDialog.py'].getvalue() generated_frame = self.vFiles['./PyOgg2_MyFrame.py'].getvalue() self._compare(result_app, generated_app, 'PyOgg2_app.py') self._compare(result_dialog, generated_dialog, 'PyOgg2_MyDialog.py') self._compare(result_frame, generated_frame , 'PyOgg2_MyFrame.py') def test_Python_Ogg3(self): """\ Test Python code generation with overwriting a single existing file @see: L{codegen.py_codegen.PythonCodeWriter} """ source = self._load_file('PyOgg2.wxg') expected = self._load_file('PyOgg3.py') # rename all occurencies of PyOgg2 to PyOgg3 source = source.replace('PyOgg2', 'PyOgg3') # set option="0" for writing into a single file source = self._modify_attrs(source, option='0', path='PyOgg3.py' ) # generate and compare code self._generate_code('python', source, 'PyOgg3.py') generated = self.vFiles['PyOgg3.py'].getvalue() self._compare(expected, generated, 'PyOgg3.py') def test_Lisp_Ogg1(self): """\ Test Lisp code generation with overwriting a single existing file @see: L{codegen.py_codegen.LispCodeWriter} """ self._generate_and_compare( 'lisp', 'LispOgg1.wxg', 'LispOgg1.lisp' ) def test_Lisp_Ogg2(self): """\ Test Lisp code generation with overwriting two existing files @see: L{codegen.py_codegen.LispCodeWriter} """ source = self._load_file('LispOgg2.wxg') source = self._modify_attrs(source, overwrite='0', ) result_app = self._load_file('LispOgg2_app.lisp') result_dialog = self._load_file('LispOgg2_MyDialog.lisp') result_frame = self._load_file('LispOgg2_MyFrame.lisp') self._generate_code('lisp', source, './') generated_app = self.vFiles['./LispOgg2_app.lisp'].getvalue() generated_dialog = self.vFiles['./LispOgg2_MyDialog.lisp'].getvalue() generated_frame = self.vFiles['./LispOgg2_MyFrame.lisp'].getvalue() self._compare(result_app, generated_app, 'LispOgg2_app.lisp') self._compare(result_dialog, generated_dialog, 'LispOgg2_MyDialog.lisp') self._compare(result_frame, generated_frame , 'LispOgg2_MyFrame.lisp') def test_Lisp_Ogg3(self): """\ Test Lisp code generation with overwriting a single existing file @see: L{codegen.py_codegen.LispCodeWriter} """ source = self._load_file('LispOgg2.wxg') expected = self._load_file('LispOgg3.lisp') # rename all occurencies of LispOgg2 to LispOgg3 source = source.replace('LispOgg2', 'LispOgg3') # set option="0" for writing into a single file source = self._modify_attrs(source, option='0', path='LispOgg3.lisp' ) # generate and compare code self._generate_code('lisp', source, 'LispOgg3.lisp') generated = self.vFiles['LispOgg3.lisp'].getvalue() self._compare(expected, generated, 'LispOgg3.lisp') def test_Perl_Ogg1(self): """\ Test Perl code generation with overwriting a single existing file @see: L{codegen.pl_codegen.PerlCodeWriter} """ self._generate_and_compare( 'perl', 'PlOgg1.wxg', 'PlOgg1.pl' ) def test_Perl_Ogg2(self): """\ Test Perl code generation with overwriting two existing files @see: L{codegen.pl_codegen.PerlCodeWriter} """ source = self._load_file('PlOgg2.wxg') source = self._modify_attrs(source, overwrite='0', ) result_app = self._load_file('PlOgg2_app.pl') result_dialog = self._load_file('PlOgg2_MyDialog.pm') result_frame = self._load_file('PlOgg2_MyFrame.pm') self._generate_code('perl', source, './') generated_app = self.vFiles['./PlOgg2_app.pl'].getvalue() generated_dialog = self.vFiles['./PlOgg2_MyDialog.pm'].getvalue() generated_frame = self.vFiles['./PlOgg2_MyFrame.pm'].getvalue() self._compare(result_app, generated_app, 'PlOgg2_app.pl') self._compare(result_dialog, generated_dialog, 'PlOgg2_MyDialog.pm') self._compare(result_frame, generated_frame , 'PlOgg2_MyFrame.pm') def test_Perl_Ogg3(self): """\ Test Perl code generation with overwriting a single existing file @see: L{codegen.pl_codegen.PerlCodeWriter} """ source = self._load_file('PyOgg2.wxg') expected = self._load_file('PyOgg3.py') # rename all occurencies of PyOgg2 to PyOgg3 source = source.replace('PyOgg2', 'PyOgg3') # set option="0" for writing into a single file source = self._modify_attrs(source, option='0', path='PyOgg3.py' ) # generate and compare code self._generate_code('python', source, 'PyOgg3.py') generated = self.vFiles['PyOgg3.py'].getvalue() self._compare(expected, generated, 'PyOgg3.py') def test_CPP_Ogg1(self): """\ Test C++ code generation with overwriting a single existing file @see: L{codegen.cpp_codegen.PythonCodeWriter} """ self._generate_and_compare_cpp( 'CPPOgg1.wxg', 'CPPOgg1' ) def test_CPP_Ogg2(self): """\ Test C++ code generation with overwriting two existing files @see: L{codegen.cpp_codegen.CPPCodeWriter} """ source = self._load_file('CPPOgg2.wxg') source = self._modify_attrs(source, overwrite='0', ) result_app = self._load_file('CPPOgg2_main.cpp') result_dialog_cpp = self._load_file('CPPOgg2_MyDialog.cpp') result_dialog_h = self._load_file('CPPOgg2_MyDialog.h') result_frame_cpp = self._load_file('CPPOgg2_MyFrame.cpp') result_frame_h = self._load_file('CPPOgg2_MyFrame.h') self._generate_code('C++', source, './') generated_app = self.vFiles['./main.cpp'].getvalue() generated_dialog_cpp = self.vFiles['./CPPOgg2_MyDialog.cpp'].getvalue() generated_dialog_h = self.vFiles['./CPPOgg2_MyDialog.h'].getvalue() generated_frame_cpp = self.vFiles['./CPPOgg2_MyFrame.cpp'].getvalue() generated_frame_h = self.vFiles['./CPPOgg2_MyFrame.h'].getvalue() self._compare(result_app, generated_app, 'main.cpp') self._compare(result_dialog_cpp, generated_dialog_cpp, 'CPPOgg2_MyDialog.cpp') self._compare(result_dialog_h, generated_dialog_h, 'CPPOgg2_MyDialog.h') self._compare(result_frame_cpp, generated_frame_cpp , 'CPPOgg2_MyFrame.cpp') self._compare(result_frame_h, generated_frame_h, 'CPPOgg2_MyFrame.h') def test_CPP_Ogg3(self): """\ Test C++ code generation with overwriting a single existing file @see: L{codegen.cpp_codegen.CPPCodeWriter} """ source = self._load_file('CPPOgg2.wxg') result_cpp = self._load_file('CPPOgg3.cpp') result_h = self._load_file('CPPOgg3.h') # rename all occurencies of CPPOgg2 to CPPOgg3 source = source.replace('CPPOgg2', 'CPPOgg3') # set option="0" for writing into a single file source = self._modify_attrs(source, option='0', path='CPPOgg3' ) # generate and compare code self._generate_code('C++', source, 'CPPOgg3') generated_cpp = self.vFiles['CPPOgg3.cpp'].getvalue() generated_h = self.vFiles['CPPOgg3.h'].getvalue() self._compare(result_cpp, generated_cpp, 'CPPOgg3.cpp') self._compare(result_h, generated_h, 'CPPOgg3.h') def test_PerlSourceFileContent_regexp(self): """\ Test some regular expessions used in L{codegen.pl_codegen.SourceFileContent} """ import codegen.pl_codegen lang = 'Perl' source = codegen.pl_codegen.SourceFileContent re = source.rec_block_start for line, expected in [ ('# begin wxGlade: extracode', ('', None, 'extracode')), (' # begin wxGlade: ::extracode', (' ', None, 'extracode')), ('#begin wxGlade: dependencies', ('', None, 'dependencies')), ('#begin wxGlade: ::dependencies', ('', None, 'dependencies')), (' # begin wxGlade: wxGladePreferencesUI::new', (' ', 'wxGladePreferencesUI', 'new')), (' # begin wxGlade: wxGladePreferencesUI::__do_layout', (' ', 'wxGladePreferencesUI', '__do_layout')), (' # begin wxGlade: wxGladePreferencesUI::__set_properties', (' ', 'wxGladePreferencesUI', '__set_properties')), ]: result = re.match(line) self.failUnless( result, '%s: Line "%s" does not fit pattern!' % (lang, line) ) self.failUnless( result.groups() == expected, '%s: Unexpected result for line "%s":\n got: "%s"\nexpect: "%s"' % (lang, line, result.groups(), expected) ) def test_PythonSourceFileContent_regexp(self): """\ Test some regular expessions used in L{codegen.py_codegen.SourceFileContent} """ import codegen.py_codegen lang = 'Python' source = codegen.py_codegen.SourceFileContent re = source.rec_block_start for line, expected in [ ('# begin wxGlade: extracode', ('', None, 'extracode')), (' # begin wxGlade: extracode', (' ', None, 'extracode')), ('#begin wxGlade: dependencies', ('', None, 'dependencies')), (' # begin wxGlade: PyOgg3_MyDialog.__init__', (' ', 'PyOgg3_MyDialog', '__init__')), (' # begin wxGlade: PyOgg3_MyFrame.__do_layout', (' ', 'PyOgg3_MyFrame', '__do_layout')), (' # begin wxGlade: PyOgg3_MyFrame.__set_properties', (' ', 'PyOgg3_MyFrame', '__set_properties')), ]: result = re.match(line) self.failUnless( result, '%s: Line "%s" does not fit pattern!' % (lang, line) ) self.failUnless( result.groups() == expected, '%s: Unexpected result for line "%s":\n got: "%s"\nexpect: "%s"' % (lang, line, result.groups(), expected) ) re = source.rec_event_handler for line, expected in [ (' def myEVT_GRID_CELL_LEFT_CLICK(self, event): # wxGlade: MyFrame.', ('myEVT_GRID_CELL_LEFT_CLICK', 'MyFrame')), (' def startConverting(self, event): # wxGlade: PyOgg1_MyDialog.', ('startConverting', 'PyOgg1_MyDialog')), ]: result = re.match(line) self.failUnless( result, '%s: Line "%s" does not fit pattern!' % (lang, line) ) self.failUnless( result.groups() == expected, '%s: Unexpected result for line "%s":\n got: "%s"\nexpect: "%s"' % (lang, line, result.groups(), expected) ) def test_content_notfound(self): """\ Test replacement of not found blocks with a warning message @see: L{codegen.BaseCodeWriter._content_notfound()} """ import codegen base_codegen = codegen.BaseCodeWriter() base_codegen.previous_source = MockSourceFileContent() # this is to be more sure to replace the right tags base_codegen.nonce = '12G34' base_codegen.comment_sign = "#" source_sample = """\ <12G34wxGlade replace %(pattern)s> """ expected_sample = """\ %(indent)s# Content of this block not found. Did you rename this class? """ for pattern, indent in [ ('MissingClass method', ' '), ('MissingClass method', ' '), ('MissingClass Method', '---'), ('MissingClass method', '\t'), ('MissingClass method', ''), ('MissingClass .', ''), ]: source = source_sample % { 'pattern': pattern, 'indent': indent, } expected = expected_sample % { 'pattern': pattern, 'indent': indent, } if indent: base_codegen.previous_source.spaces['MissingClass'] = indent else: base_codegen.previous_source.spaces = {} result = base_codegen._content_notfound( source, ) self.failUnless( result == expected, 'Unexpected result for pattern "%s":\n got: "%s"\nexpect: "%s"' % (pattern, result, expected) ) def test_add_app(self): """\ Test the generation of application start code @see: L{codegen.py_codegen.PythonCodeWriter.add_app()} """ for language, prefix, suffix in [ ['python', 'Py', '.py'], ['perl', 'Pl', '.pl'], ['C++', 'CPP', '.cpp'], ['lisp', 'Lisp', '.lisp'] ]: for multiple_files in [0, 1]: for klass in ['MyStartApp', None]: # prepare code writer codewriter = common.code_writers[language] # path must be a directory for multiple files if multiple_files: path = './' else: path = 'myoutputfile' for use_gettext in [0, 1]: codewriter.initialize({ 'indent_amount': '4', 'indent_symbol': 'space', 'language': language, 'name': 'myapp', 'option': multiple_files, 'overwrite': 1, 'path': path, 'use_gettext': use_gettext, 'use_new_namespace': 1, }) # clear output_file if codewriter.output_file: codewriter.output_file.close() codewriter.output_file = cStringIO.StringIO() # generate application start code codewriter.add_app({ 'class': klass, 'top_window': 'appframe', }, 'MyAppFrame') if use_gettext: fn_gettext = '_gettext' else: fn_gettext = '' if klass: simple = '_detailed' else: simple = '_simple' if language == 'C++': app_filename = './main.cpp' else: app_filename = './myapp%s' % suffix if multiple_files: generated = self.vFiles[app_filename].getvalue() multiple = '_multi' else: generated = codewriter.output_file.getvalue() multiple = '_single' filename = '%sAddApp%s%s%s%s' % \ (prefix, multiple, fn_gettext, simple, suffix) expected = self._load_file(filename) self._compare( expected, generated, '%s (%s)' % (misc.capitalize(language), filename), ) # close open virtual files for name in self.vFiles.keys(): self.vFiles[name].close() del self.vFiles[name] def test_no_suitable_writer(self): """\ Test the generation of a warning if no suitable writer has been found for a specific widget. This tests only the case of a known widget but the language specific widget handler is missing. This test doesn't cover the missing of a whole widget. @see: L{codegen.BaseCodeWriter._add_object_init()} """ for lang, ext in [ ('python', '.py'), ('perl', '.pl'), ('lisp', '.lisp'), ('XRC', '.xrc'), ('C++', ''), ]: codegen = common.code_writers.get(lang) handler = codegen.obj_builders['wxButton'] del codegen.obj_builders['wxButton'] # don' use _generate_and_compare() resp. # _generate_and_compare_cpp() because a failure wouldn't restore # the temporarily removed widget if lang == 'C++': inname = 'no_suitable_writer.wxg' outname = 'no_suitable_writer' name_h = '%s.h' % outname name_cpp = '%s.cpp' % outname # load XML input file source = self._load_file(inname) result_cpp = self._load_file(name_cpp) result_h = self._load_file(name_h) # generate and compare C++ code self._generate_code('C++', source, outname) generated_cpp = self.vFiles[name_cpp].getvalue() generated_h = self.vFiles[name_h].getvalue() # restore deleted handler codegen.obj_builders['wxButton'] = handler # compare generated and expected code self._compare(result_cpp, generated_cpp, 'C++ source') self._compare(result_h, generated_h, 'C++ header') else: # load XML input file inname = 'no_suitable_writer.wxg' outname = 'no_suitable_writer%s' % ext source = self._load_file(inname) expected = self._load_file(outname) # generate code self._generate_code(lang, source, outname) generated = self.vFiles[outname].getvalue() # restore deleted handler codegen.obj_builders['wxButton'] = handler # compare generated and expected code self._compare(expected, generated) def test_add_class_inplace(self): """\ Test appending of a new class to an existing file without overwriting. """ # Test Lisp code generator #========================= # load XML input file source = self._load_file('add_class_inplace_extended.wxg') expected = self._load_file('add_class_inplace_extended.lisp') # generate code self._generate_code('lisp', source, 'add_class_inplace_orig.lisp') generated = self.vFiles['add_class_inplace_orig.lisp'].getvalue() self._compare(expected, generated) # Test Perl code generator #========================= # load XML input file source = self._load_file('add_class_inplace_extended.wxg') expected = self._load_file('add_class_inplace_extended.pl') # generate code self._generate_code('perl', source, 'add_class_inplace_orig.pl') generated = self.vFiles['add_class_inplace_orig.pl'].getvalue() self._compare(expected, generated) # Test Python code generator #=========================== # load XML input file source = self._load_file('add_class_inplace_extended.wxg') expected = self._load_file('add_class_inplace_extended.py') # generate code self._generate_code('python', source, 'add_class_inplace_orig.py') generated = self.vFiles['add_class_inplace_orig.py'].getvalue() self._compare(expected, generated) # Test XRC code generator #======================== # load XML input file source = self._load_file('add_class_inplace_extended.wxg') expected = self._load_file('add_class_inplace_extended.xrc') # generate code self._generate_code('XRC', source, 'add_class_inplace_orig.xrc') generated = self.vFiles['add_class_inplace_orig.xrc'].getvalue() self._compare(expected, generated) # Test C++ code generator #======================== # load XML input file source = self._load_file('add_class_inplace_extended.wxg') expected_cpp = self._load_file('add_class_inplace_extended.cpp') expected_h = self._load_file('add_class_inplace_extended.h') # generate code self._generate_code('C++', source, 'add_class_inplace_orig.xrc') gen_cpp = self.vFiles['add_class_inplace_orig.cpp'].getvalue() gen_h = self.vFiles['add_class_inplace_orig.h'].getvalue() self._compare(expected_cpp, gen_cpp, 'C++ source') self._compare(expected_h, gen_h, 'C++ header') def test_remove_class_inplace(self): """\ Test class removal in an existing file without overwriting. """ # Test Lisp code generator #========================= # load XML input file source = self._load_file('remove_class_inplace.wxg') expected = self._load_file('remove_class_inplace_expected.lisp') # generate code self._generate_code('lisp', source, 'remove_class_inplace_input.lisp') generated = self.vFiles['remove_class_inplace_input.lisp'].getvalue() self._compare(expected, generated) # Test Perl code generator #========================= # load XML input file source = self._load_file('remove_class_inplace.wxg') expected = self._load_file('remove_class_inplace_expected.pl') # generate code self._generate_code('perl', source, 'remove_class_inplace_input.pl') generated = self.vFiles['remove_class_inplace_input.pl'].getvalue() self._compare(expected, generated) # Test Python code generator #=========================== # load XML input file source = self._load_file('remove_class_inplace.wxg') expected = self._load_file('remove_class_inplace_expected.py') # generate code self._generate_code('python', source, 'remove_class_inplace_input.py') generated = self.vFiles['remove_class_inplace_input.py'].getvalue() self._compare(expected, generated) # Test XRC code generator #======================== # load XML input file source = self._load_file('remove_class_inplace.wxg') expected = self._load_file('remove_class_inplace_expected.xrc') # generate code self._generate_code('XRC', source, 'remove_class_inplace_input.xrc') generated = self.vFiles['remove_class_inplace_input.xrc'].getvalue() self._compare(expected, generated) # Test C++ code generator #======================== # load XML input file source = self._load_file('remove_class_inplace.wxg') expected_cpp = self._load_file('remove_class_inplace_expected.cpp') expected_h = self._load_file('remove_class_inplace_expected.h') # generate code self._generate_code('C++', source, 'remove_class_inplace_input.xrc') gen_cpp = self.vFiles['remove_class_inplace_input.cpp'].getvalue() gen_h = self.vFiles['remove_class_inplace_input.h'].getvalue() self._compare(expected_cpp, gen_cpp, 'C++ source') self._compare(expected_h, gen_h, 'C++ header') def test_format_classattr(self): """\ Test formatting names as class attributes @see: L{codegen.BaseCodeWriter._format_classattr()} """ details = {} details['python'] = [ ('', ''), ('self.mywidget', 'self.mywidget'), ('1myclass', 'self.1myclass'), ('_myclass', 'self._myclass'), ('myclass', 'self.myclass'), ('label1', 'self.label1'), ('label_1', 'self.label_1'), ('_label', 'self._label'), ('_label_1', 'self._label_1'), ('20, 30', '(20, 30)'), ] details['perl'] = [ ('', ''), ('$self->{mywidget}', '$self->{mywidget}'), ('1myclass', '$self->{1myclass}'), ('_myclass', '$self->{_myclass}'), ('$mybox', '$mybox'), ('myclass', '$self->{myclass}'), ('label1', '$self->{label1}'), ('label_1', '$self->{label_1}'), ('_label', '$self->{_label}'), ('_label_1', '$self->{_label_1}'), ('20, 30', '20, 30'), ] details['lisp'] = [ ('', ''), ('slot-mywidget', 'slot-mywidget'), ('1myclass', 'slot-1myclass'), ('_myclass', 'slot--myclass'), ('myclass', 'slot-myclass'), ('my_class', 'slot-my-class'), ('label1', 'slot-label1'), ('label_1', 'slot-label-1'), ('_label', 'slot--label'), ('_label_1', 'slot--label-1'), ('20, 30', '(20, 30)'), ] details['C++'] = [ ('', ''), ('mywidget', 'mywidget'), ('1myclass', '1myclass'), ('_myclass', '_myclass'), ('myclass', 'myclass'), ('my_class', 'my_class'), ('label1', 'label1'), ('label_1', 'label_1'), ('_label', '_label'), ('_label_1', '_label_1'), ('20, 30', '20, 30'), ] for lang in ['python', 'perl', 'lisp', 'C++']: codegen = common.code_writers.get(lang) ret = codegen._format_classattr(None) self.failUnlessEqual( '', ret, '%s: Unexpected result got: "%s" expect: "%s"' % ( lang.capitalize(), ret, '' ) ) for name, expected in details[lang]: obj = MockCodeObject() obj.name = name if name == '20, 30': obj.klass = 'spacer' else: obj.klass = 'wxButton' ret = codegen._format_classattr(obj) self.failUnlessEqual( expected, ret, '%s: Unexpected result got: "%s" expect: "%s"' % ( lang.capitalize(), ret, expected, ) ) def test_sizer_references(self): """\ Test storing references to sizers in class attributes """ # don't store sizer references self._test_all('Sizers_no_classattr') # store sizer references self._test_all('Sizers_classattr') def test_cn(self): """\ Test formatting of names with cn(). @see: L{codegen.cpp_codegen.CPPCodeWriter.cn()} @see: L{codegen.lisp_codegen.LispCodeWriter.cn()} @see: L{codegen.pl_codegen.PerlCodeWriter.cn()} @see: L{codegen.py_codegen.PythonCodeWriter.cn()} """ details = {} details['python_new'] = [ # new namespace ('wxID_OK', 'wx.ID_OK'), ('wxALL', 'wx.ALL'), ('wxBLUE', 'wx.BLUE'), ('wxALIGN_CENTER', 'wx.ALIGN_CENTER'), ('wxFrame', 'wx.Frame'), ('EVT_BUTTON', 'wx.EVT_BUTTON'), ] details['python_old'] = [ # old namespace ('wxID_OK', 'wxID_OK'), ('wxALL', 'wxALL'), ('wxBLUE', 'wxBLUE'), ('wxALIGN_CENTER', 'wxALIGN_CENTER'), ('wxFrame', 'wxFrame'), ('EVT_BUTTON', 'EVT_BUTTON'), ] details['perl'] = [ ('wxID_OK', 'wxID_OK'), ('wxALL', 'wxALL'), ('wxBLUE', 'wxBLUE'), ('wxALIGN_CENTER', 'wxALIGN_CENTER'), ('wxFrame', 'Wx::Frame'), ('EVT_BUTTON', 'Wx::EVT_BUTTON'), ] details['lisp'] = [ ('wxID_OK', 'wxID_OK'), ('wxALL', 'wxALL'), ('wxBLUE', 'wxBLUE'), ('wxALIGN_CENTER', 'wxALIGN_CENTER'), ('wxFrame', 'wxFrame'), ('EVT_BUTTON', 'wxEVT_BUTTON'), ] details['C++'] = [ ('wxID_OK', 'wxID_OK'), ('wxALL', 'wxALL'), ('wxBLUE', 'wxBLUE'), ('wxALIGN_CENTER', 'wxALIGN_CENTER'), ('wxFrame', 'wxFrame'), ('EVT_BUTTON', 'EVT_BUTTON'), ] for lang in ['python_new', 'python_old', 'perl', 'lisp', 'C++']: if lang.startswith('python'): if lang == 'python_old': common.code_writers['python'].use_new_namespace = 0 elif lang == 'python_new': common.code_writers['python'].use_new_namespace = 1 cn = common.code_writers['python'].cn else: cn = common.code_writers[lang].cn for unformatted, formatted in details[lang]: ret = cn(unformatted) self.failUnlessEqual( formatted, ret, '%s: Unexpected result got: "%s" expect: "%s"' % ( lang, ret, formatted, ) ) # test for prevent double formatting ret = cn(formatted) self.failUnlessEqual( formatted, ret, '%s: Unexpected result got: "%s" expect: "%s"' % ( lang, ret, formatted, ) ) def test_ComplexExample(self): """\ Test code generation for a complex example """ self._test_all('ComplexExample') def test_StylelessDialog(self): """\ Test code generation for a style less dialog """ self._test_all('styleless-dialog') def test_quote_str(self): """\ Test string quotation for Perl and Python @see: L{codegen.pl_codegen.PerlCodeWriter.quote_str()} @see: L{codegen.py_codegen.PythonCodeWriter.quote_str()} """ details = {} details['python'] = [ (None, '""'), ('', '""'), ('My 1st and simple ascii test!', '_("My 1st and simple ascii test!")'), ('\xe2\x99\xa5 Love this song', '_(u"\\u2665 Love this song")'), ('\xe2\x99\xa5 Love \xe2\x99\xa5', '_(u"\\u2665 Love \\u2665")'), ] details['perl'] = [ (None, '""'), ('', '""'), ('My 1st and simple ascii test!', '_T("My 1st and simple ascii test!")'), ('\xe2\x99\xa5 Love this song', '_T("\\N{U+2665} Love this song")'), ('\xe2\x99\xa5 Love \xe2\x99\xa5', '_T("\\N{U+2665} Love \\N{U+2665}")'), ('\xe2\x99\xa52 Love \xe2\x99\xa5', '_T("\u26652 Love \N{U+2665}")'), ] for lang in ['python', 'perl']: codegen = common.code_writers.get(lang) codegen._use_gettext = True for unformatted, formatted in details[lang]: ret = codegen.quote_str(unformatted) self.failUnlessEqual( formatted, ret, '%s: Unexpected result got: "%s" expect: "%s"' % ( lang, ret, formatted, ) )wxglade-0.6.8.orig/tests/__init__.py0000644000175000017500000003402112150154266017572 0ustar georgeskgeorgesk""" @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ # import general python modules import cStringIO import difflib import glob import os.path import re import unittest # import project modules import codegen import common import wxglade from xml_parse import CodeWriter class WXGladeBaseTest(unittest.TestCase): """\ Provide basic functions for all tests All test cases uses an own implementation to L{common.save_file()} to catch the results. This behaviour is limitied to single file creation. """ vFiles = {} """\ Dictionary to store the content of the files generated by the code generators. The filename is the key and the content is a StringIO instance. """ orig_file_exists = None """\ Reference to the original L{codegen.BaseCodeWriter._file_exists()} implementation """ orig_load_file = None """\ Reference to the original L{codegen.BaseSourceFileContent._load_file()} implementation """ orig_os_access = None """\ Reference to original C{os.access()} implementation @see: L{_os_access()} """ orig_os_makedirs = None """\ Reference to original C{os.makedirs()} implementation @see: L{_os_makedirs()} """ orig_os_path_isdir = None """\ Reference to original C{os.path.isdir()} implementation @see: L{_os_path_isdir()} """ orig_save_file = None """\ Reference to the original L{common.save_file()} implementation """ caseDirectory = 'casefiles' """\ Directory with input files and result files """ init_stage1 = False """\ Initialise the first stage of wxGlade e.g. path settings """ init_use_gui = False """\ Initialise the GUI part of wxGlade """ def setUp(self): """\ Initialise parts of wxGlade only """ # initialise path settings if self.init_stage1: wxglade.init_stage1() # initialise sizers, widgets, codewriter wxglade.init_stage2(use_gui=self.init_use_gui) # initialise wxGlade configuration import config config.init_preferences() # set some useful preferences config.preferences.autosave = False config.preferences.write_timestamp = False config.preferences.show_progress = False # initiate empty structure to store files and there content self.vFiles = {} # replace some original implementations by test specific implementation self.orig_save_file = common.save_file common.save_file = self._save_file self.orig_load_file = codegen.BaseSourceFileContent._load_file codegen.BaseSourceFileContent._load_file = self._load_lines self.orig_file_exists = codegen.BaseCodeWriter._file_exists self.orig_os_access = os.access os.access = self._os_access self.orig_os_makedirs = os.makedirs os.makedirs = self._os_makedirs self.orig_os_path_isdir = os.path.isdir os.path.isdir = self._os_path_isdir codegen.BaseCodeWriter._file_exists = self._file_exists codegen.BaseCodeWriter._show_warnings = False # set own version string to prevent diff mismatches common.version = '"faked test version"' # Determinate case directory self.caseDirectory = os.path.join( os.path.dirname(__file__), self.caseDirectory, ) def tearDown(self): """\ Cleanup """ # cleanup virtual files for filename in self.vFiles: self.vFiles[filename].close() self.vFiles = {} # restore original implementations common.save_file = self.orig_save_file codegen.BaseSourceFileContent._load_file = self.orig_load_file codegen.BaseCodeWriter._file_exists = self.orig_file_exists os.access = self.orig_os_access os.makedirs = self.orig_os_makedirs os.path.isdir = self._os_path_isdir def _generate_code(self, language, document, filename): """\ Generate code for the given language. @param language: Language to generate code for @type language: String @param document: XML document to generate code for @type document: String @param filename: Name of the virtual output file @type filename: String """ self.failUnless( language in common.code_writers, "No codewriter loaded for %s" % language ) document = self._prepare_wxg(language, document) # generate code CodeWriter( writer=common.code_writers[language], input=document, from_string=True, out_path=filename, ) return def _file_exists(self, filename): """\ Check if the file is a test case file @rtype: Boolean """ fullpath = os.path.join(self.caseDirectory, filename) exists = os.path.isfile(fullpath) self.failIf( not exists, 'Case file %s does not exist' % filename ) return exists def _load_file(self, filename): """\ Load a file need by a test case. @param filename: Name of the file to load @type filename: String @return: File content @rtype: String """ casename, extension = os.path.splitext(filename) if extension == '.wxg': filetype = 'input' else: filetype = 'result' file_list = glob.glob( os.path.join(self.caseDirectory, "%s%s" % (casename, extension)) ) self.failIf( len(file_list) == 0, 'No %s file "%s" for case "%s" found!' % ( filetype, filename, casename, ) ) self.failIf( len(file_list) > 1, 'More than one %s file "%s" for case "%s" found!' % ( filetype, filename, casename, ) ) fh = open(file_list[0]) content = fh.read() fh.close() # replacing path entries content = content % { 'wxglade_path': common.wxglade_path, 'docs_path': common.docs_path, 'icons_path': common.icons_path, 'widgets_path': common.widgets_path, 'templates_path': common.templates_path, 'tutorial_file': common.tutorial_file, } return content def _load_lines(self, filename): """\ Return file content as a list of lines """ casename, extension = os.path.splitext(filename) if extension == '.wxg': filetype = 'input' else: filetype = 'result' file_list = glob.glob( os.path.join(self.caseDirectory, "%s%s" % (casename, extension)) ) self.failIf( len(file_list) == 0, 'No %s file for case "%s" found!' % (filetype, casename) ) self.failIf( len(file_list) > 1, 'More than one %s file for case "%s" found!' % (filetype, casename) ) fh = open(file_list[0]) content = fh.readlines() fh.close() return content def _modify_attrs(self, content, **kwargs): """\ Modify general options inside a wxg (XML) file """ modified = content for option in kwargs: # create regexp first pattern = r'%s=".*?"' % option modified = re.sub( pattern, '%s="%s"' % (option, kwargs[option]), modified, 1 ) return modified def _os_access(self, path, mode): """\ Fake implementation for C{os.access()} - returns always C{True} """ return True def _os_makedirs(self, path, mode): """\ Fake implementation for C{os.makedirs()} - do nothing """ pass def _os_path_isdir(self, s): """\ Fake implementation for C{os.path.isdir()} """ if s in [".", "./"]: return True return False def _prepare_wxg(self, language, document): """\ Set test specific options inside a wxg (XML) file @param language: Language to generate code for @type language: String @param document: XML document to generate code for @type document: String @return: Modified XML document @rtype: String """ if language == "perl": _document = self._modify_attrs( document, language='perl', indent_amount='8', indent_symbol='space', ) else: _document = self._modify_attrs( document, language=language, indent_amount='4', indent_symbol='space', ) return _document def _save_file(self, filename, content, which='wxg'): """\ Test specific implementation of L{common.save_file()} to get the result of the code generation without file creation. The file content is stored in a StringIO instance. It's accessible at L{self.vFiles} using the filename as key. @note: The signature is as same as L{wxglade.common.save_file()} but the functionality differs. @param filename: Name of the file to create @param content: String to store into 'filename' @param which: Kind of backup: 'wxg' or 'codegen' """ self.failIf( filename in self.vFiles, "Virtual file %s already exists" % filename ) self.failUnless( filename, "No filename given", ) outfile = cStringIO.StringIO() outfile.write(content) self.vFiles[filename] = outfile def _test_all(self, base): """\ Generate code for all languages based on the base file name @param base: Base name of the test files @type base: String """ for lang, ext in [ ['lisp', '.lisp'], ['perl', '.pl'], ['python', '.py'], ['XRC', '.xrc'], ['C++', ''], ]: name_wxg = '%s.wxg' % base name_lang = '%s%s' % (base, ext) if lang == 'C++': self._generate_and_compare_cpp(name_wxg, name_lang) else: self._generate_and_compare(lang, name_wxg, name_lang) def _diff(self, text1, text2): """\ Compare two lists, tailing spaces will be removed @param text1: Expected text @type text1: String @param text2: Generated text @type text2: String @return: Changes formatted as unified diff @rtype: String """ self.assertEqual(type(text1), type("")) self.assertEqual(type(text2), type("")) # split into lists, because difflib needs lists and remove # tailing spaces list1 = [x.rstrip() for x in text1.splitlines()] list2 = [x.rstrip() for x in text2.splitlines()] # compare source files diff_gen = difflib.unified_diff( list1, list2, fromfile='expected source', tofile='created source', lineterm='' ) return '\n'.join(diff_gen) def _generate_and_compare(self, lang, inname, outname): """\ Generate code and compare generated and expected code @param lang: Language to generate code for @type lang: String @param inname: Name of the XML input file @type inname: String @param outname: Name of the output file @type outname: String """ # load XML input file source = self._load_file(inname) expected = self._load_file(outname) # generate code self._generate_code(lang, source, outname) generated = self.vFiles[outname].getvalue() self._compare(expected, generated) def _generate_and_compare_cpp(self, inname, outname): """\ Generate C++ code and compare generated and expected code @param inname: Name of the XML input file @type inname: String @param outname: Name of the output file without extension @type outname: String """ name_h = '%s.h' % outname name_cpp = '%s.cpp' % outname # load XML input file source = self._load_file(inname) result_cpp = self._load_file(name_cpp) result_h = self._load_file(name_h) # generate and compare C++ code self._generate_code('C++', source, outname) generated_cpp = self.vFiles[name_cpp].getvalue() generated_h = self.vFiles[name_h].getvalue() self._compare(result_cpp, generated_cpp, 'C++ source') self._compare(result_h, generated_h, 'C++ header') def _compare(self, expected, generated, filetype=None): """\ Compare expected and generated content using a diff algorithm @param expected: Expected content @type expected: Multiline String @param generated: Generated content @type generated: Multiline String @param filetype: Short description of the content @type filetype: String """ # compare files delta = self._diff(expected, generated) if filetype: self.failIf( delta, "Generated %s file and expected result differs:\n%s" % ( filetype, delta, ) ) else: self.failIf( delta, "Generated file and expected result differs:\n%s" % delta ) wxglade-0.6.8.orig/errors.py0000644000175000017500000000230212150154266016202 0ustar georgeskgeorgesk"""\ wxGlade internal exceptions @copyright: 2012 Carsten Grohmann @license: MIT (see license.txt) - THIS PROGRAM COMES WITH NO WARRANTY """ class WxgBaseException(Exception): """\ Base class for all individual wxGlade exceptions """ msg = None def __str__(self): if not self.msg: return "" if len(self.args) == 1: text = self.msg % self.args[0] else: text = "%s: %s" % (self.msg, self.args) return text class WxgOutputDirectoryNotExist(WxgBaseException): """\ Raised if output path is not an existing directory """ msg = _('Output path "%s" must be an existing directory when generating' ' multiple files') class WxgOutputDirectoryNotWritable(WxgBaseException): """\ Raised if the output path exists but the directory is not writable """ msg = _('Output path "%s" exists but the directory is not writable') class WxgOutputPathIsDirectory(WxgBaseException): """\ Raised if the output path is a directory when generating a single file """ msg = _('Output path "%s" can not be a directory when generating a ' 'single file') wxglade-0.6.8.orig/__init__.py0000644000175000017500000000037611621715605016440 0ustar georgeskgeorgesk# __init__.py: to turn wxGlade into a package # $Id: __init__.py,v 1.4 2007/03/27 07:02:07 agriggio Exp $ # # Copyright (c) 2002-2007 Alberto Griggio # License: MIT (see license.txt) # THIS PROGRAM COMES WITH NO WARRANTY