params.py :  » GUI » wxPython » wxPython-src-2.8.11.0 » wxPython » wx » tools » XRCed » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » wxPython 
wxPython » wxPython src 2.8.11.0 » wxPython » wx » tools » XRCed » params.py
# Name:         params.py
# Purpose:      Classes for parameter introduction
# Author:       Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created:      22.08.2001
# RCS-ID:       $Id: params.py 64107 2010-04-22 14:05:36Z ROL $

'''
Visual C{Param*} classes for populating C{AtrtibutePanel} with attribute editing
blocks. 
'''

import string
import os
import wx.combo
from globals import *

WARenameDict = {'fg': 'foreground', 'bg': 'background'}

def InitParams(panel):
    '''Set pixel common size based on parent window.'''

    global Presenter
    from presenter import Presenter
    global Listener
    from listener import Listener

    dc = wx.ClientDC(panel)
    global textH, textB
    textH = -1
    if wx.Platform == '__WXMAC__':
        textB = 3               # bigger text border needed for mac highlighting
    else:
        textB = 2
    dc.Destroy()

    # make a custom bitmap showing "..."
    bw, bh = 14, 16
    bmp = wx.EmptyBitmap(bw,bh)
    dc = wx.MemoryDC(bmp)
    
    # clear to a specific background colour
    bgcolor = wx.Colour(255,254,255)
    dc.SetBackground(wx.Brush(bgcolor))
    dc.Clear()

    # draw the label onto the bitmap
    label = "..."
    font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
    font.SetWeight(wx.FONTWEIGHT_BOLD)
    dc.SetFont(font)
    tw,th = dc.GetTextExtent(label)
    dc.DrawText(label, (bw-tw)/2, (bw-tw)/2)
    del dc

    # now apply a mask using the bgcolor
    bmp.SetMaskColour(bgcolor)
    global bmpEdit
    bmpEdit = bmp

    # Set known encodings
    for i in range(wx.FontMapper.GetSupportedEncodingsCount()):
        ParamEncoding.values.append(wx.FontMapper.GetEncodingName(
                wx.FontMapper.GetEncoding(i)))
    ParamEncoding.values.sort()


# Class that can properly disable children
class PPanel(wx.Panel):
    '''Abstract base class creating an empty C{wx.Panel}.'''
    isCheck = False
    def __init__(self, parent, name):
        wx.Panel.__init__(self, parent, -1, name=name)
        self.name = name
    def Enable(self, value):
        self.enabled = value
        # Something strange is going on with enable so we make sure...
        for w in self.GetChildren():
            w.Enable(value)
        #wx.Panel.Enable(self, value)
    # Common method to set modified state
    def OnChange(self, evt):
        Presenter.setApplied(False)
        evt.Skip()
    def OnKillFocus(self, evt):
        # Refresh test window if auto refresh policy on focus
        if Listener.testWin.IsShown() and g.conf.autoRefresh and \
                g.conf.autoRefreshPolicy == AUTO_REFRESH_POLICY_FOCUS:
            wx.CallAfter(Presenter.refreshTestWin)
        evt.Skip()

class ParamBinaryOr(PPanel):
    '''Editing binary flag attributes defined by a string separated by '|'.'''
    def __init__(self, parent, name):
        PPanel.__init__(self, parent, name)
        self.freeze = False
        sizer = wx.BoxSizer()
        popup = CheckListBoxComboPopup(self.values)
        self.combo = wx.combo.ComboCtrl(self, size=(220,-1))
        self.combo.SetPopupControl(popup)
        if wx.Platform == '__WXMAC__':
            sizer.Add(self.combo, 1, wx.ALL, 0)
        else:
            sizer.Add(self.combo, 1, wx.ALL, 2)
        self.SetSizerAndFit(sizer)
        self.combo.Bind(wx.EVT_TEXT, self.OnChange)
        self.combo.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
    def GetValue(self):
        return self.combo.GetValue()
    def SetValue(self, value):
        self.freeze = True
        self.combo.SetValue(value)
        self.freeze = False
    def SetValues(self):
        self.combo.InsertItems(self.values, 0)
    def OnChange(self, evt):
        # ComboCtrl still generates events in SetValue
        if self.freeze: return
        Presenter.setApplied(False)
        evt.Skip()        

class ParamFlag(ParamBinaryOr):
    '''Sizer flag editing.'''
    values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
              'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxSTRETCH_NOT',
              'wxALIGN_CENTRE', 'wxALIGN_LEFT', 'wxALIGN_RIGHT',
              'wxALIGN_TOP', 'wxALIGN_BOTTOM', 
              'wxALIGN_CENTRE_VERTICAL', 'wxALIGN_CENTRE_HORIZONTAL', 
              'wxADJUST_MINSIZE', 'wxFIXED_MINSIZE',
              'wxRESERVE_SPACE_EVEN_IF_HIDDEN',
              ]
    equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
             'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
             'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL',
             'wxUP': 'wxTOP', 'wxDOWN': 'wxBOTTOM', 'wxNORTH': 'wxTOP',
             'wxSOUTH': 'wxBOTTOM', 'wxWEST': 'wxLEFT', 'wxEAST': 'wxRIGHT'}

class ParamColour(PPanel):
    '''Color attribute editing.'''
    def __init__(self, parent, name):
        PPanel.__init__(self, parent, name)
        sizer = wx.BoxSizer()
        self.text = wx.TextCtrl(self, size=(80,textH))
        sizer.Add(self.text, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, textB)
        self.button = wx.Panel(self, size=(20, 20))
        sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 3)
        self.SetSizer(sizer)
        self.textModified = False
        self.button.Bind(wx.EVT_PAINT, self.OnPaintButton)
        self.text.Bind(wx.EVT_TEXT, self.OnChange)
        self.text.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
        self.button.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
    def GetValue(self):
        return self.text.GetValue()
    def SetValue(self, value):
        self.text.ChangeValue(value)  # update text ctrl
        self.UpdateColour(value)
    def UpdateColour(self, value):
        try:
            colour = wx.Colour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16))
            self.button.SetBackgroundColour(colour)
        except:                         # ignore errors
            self.button.SetBackgroundColour(self.GetBackgroundColour())
        self.button.Refresh()
    def OnChange(self, evt):
        Presenter.setApplied(False)
        self.UpdateColour(evt.GetString())
        evt.Skip()
    def OnPaintButton(self, evt):
        dc = wx.PaintDC(self.button)
        dc.SetBrush(wx.TRANSPARENT_BRUSH)
        if self.IsEnabled(): dc.SetPen(wx.BLACK_PEN)
        else: dc.SetPen(wx.GREY_PEN)
        size = self.button.GetSize()
        dc.DrawRectangle(0, 0, size.width, size.height)
    def OnLeftDown(self, evt):
        data = wx.ColourData()
        data.SetColour(self.GetValue())
        dlg = wx.ColourDialog(self, data)
        if dlg.ShowModal() == wx.ID_OK:
            self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get())
            Presenter.setApplied(False)
        dlg.Destroy()

################################################################################

# Mapping from wx constants to XML strings
fontFamiliesWx2Xml = {wx.DEFAULT: 'default', wx.DECORATIVE: 'decorative',
                wx.ROMAN: 'roman', wx.SCRIPT: 'script', wx.SWISS: 'swiss',
                wx.MODERN: 'modern'}
fontStylesWx2Xml = {wx.NORMAL: 'normal', wx.SLANT: 'slant', wx.ITALIC: 'italic'}
fontWeightsWx2Xml = {wx.NORMAL: 'normal', wx.LIGHT: 'light', wx.BOLD: 'bold'}
def ReverseMap(m):
    rm = {}
    for k,v in m.items(): rm[v] = k
    return rm
fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml)
fontStylesXml2wx = ReverseMap(fontStylesWx2Xml)
fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml)

class ParamFont(PPanel):
    '''Font attribute editing.'''
    def __init__(self, parent, name):
        PPanel.__init__(self, parent, name)
        sizer = wx.BoxSizer()
        self.button = wx.FontPickerCtrl(
            self, style=wx.FNTP_FONTDESC_AS_LABEL | wx.FNTP_USE_TEXTCTRL
            )
        self.text = self.button.GetTextCtrl()
        if wx.Platform == '__WXMAC__':
            sizer.Add(self.button, 0, wx.LEFT, -2)
        else:
            sizer.Add(self.button, 0, wx.LEFT, textB)
        self.SetSizer(sizer)
        self.Bind(wx.EVT_FONTPICKER_CHANGED, self.OnPickFont)
        self.text.Bind(wx.EVT_TEXT, self.OnText)
        self.text.Bind(wx.EVT_KILL_FOCUS, self.OnTextKillFocus)
    def OnText(self, evt):
        Presenter.setApplied(False)
        if evt.GetString():
            evt.Skip()
        else:
            self.text.ChangeValue('')
    def OnTextKillFocus(self, evt):
        if self.text.GetValue():
            evt.Skip()
    def GetValue(self):
        return self.value
    def dict2font(self, d):
        error = False
        if 'size' in d:
            try:                size = int(d['size'])
            except ValueError:  error = True; wx.LogError('Invalid size specification')
        else:
            size = g.sysFont().GetPointSize()
        if 'family' in d:
            try:                family = fontFamiliesXml2wx[d['family']]
            except KeyError:    error = True; wx.LogError('Invalid family specification')
        else:
            family = wx.DEFAULT
        if 'style' in d:
            try:                style = fontStylesXml2wx[d['style']]
            except KeyError:    error = True; wx.LogError('Invalid style specification')
        else:
            style = wx.NORMAL
        if 'weight' in d:
            try:                weight = fontWeightsXml2wx[d['weight']]
            except KeyError:    error = True; wx.LogError('Invalid weight specification')
        else:
            weight = wx.NORMAL
        try: underlined = bool(int(d.get('underlined', '0')))
        except ValueError: error = True; wx.LogError('Invalid underlined flag specification')
        face = d.get('face','')
        enc = wx.FONTENCODING_DEFAULT
        mapper = wx.FontMapper()
        if 'encoding' in d and d['encoding'] != 'default': 
            enc = mapper.CharsetToEncoding(d['encoding'])
        if error: wx.LogError('Invalid font specification')
        if enc == wx.FONTENCODING_DEFAULT: enc = wx.FONTENCODING_SYSTEM
        font = wx.Font(size, family, style, weight, underlined, face, enc)
        return font
        
    def SetValue(self, value):
        if not value:
            self.text.ChangeValue('')
        else:
            self.button.SetSelectedFont(self.dict2font(value))
        self.value = value
    def OnPickFont(self, evt):
        font = evt.GetFont()
        if font.GetEncoding() == wx.FONTENCODING_SYSTEM:
            encName = ''
        else:
            encName = wx.FontMapper.GetEncodingName(font.GetEncoding()).encode()
        value = {'size': str(font.GetPointSize()),
                 'family': fontFamiliesWx2Xml.get(font.GetFamily(), "default"),
                 'style': fontStylesWx2Xml.get(font.GetStyle(), "normal"),
                 'weight': fontWeightsWx2Xml.get(font.GetWeight(), "normal"),
                 'underlined': str(int(font.GetUnderlined())),
                 'face': font.GetFaceName().encode(),
                 'encoding': encName}
        self.SetValue(value)
        Presenter.setApplied(False)

################################################################################

# This is a replacement for SpinCtrl to make ParamUnit looking similar.
# Unfortunately there is no SpinCtrl::GetStringValue...
class ParamInt(PPanel):
    '''TextCtrl with SpinButton for integer parameters.'''
    default = 0
    range = (-2147483648, 2147483647)
    def __init__(self, parent, name):
        PPanel.__init__(self, parent, name)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.spin = wx.SpinButton(self, style = wx.SP_VERTICAL, size=(-1,10))
        textW = 60 - self.spin.GetSize()[0]
        self.text = wx.TextCtrl(self, size=(textW,textH))
        self.spin.SetRange(*self.range)
        if wx.Platform == '__WXMAC__':
            sizer.Add(self.text, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND | wx.ALL, textB)
        else:
            sizer.Add(self.text, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND | \
                          wx.LEFT | wx.TOP | wx.BOTTOM, textB)
        sizer.Add(self.spin, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
        self.SetSizer(sizer)
        self.spin.Bind(wx.EVT_SPIN_UP, self.OnSpinUp)
        self.spin.Bind(wx.EVT_SPIN_DOWN, self.OnSpinDown)
        self.text.Bind(wx.EVT_TEXT, self.OnChange)
        self.text.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
        
    def GetValue(self):
        return self.text.GetValue()
    def SetValue(self, value):
        self.text.ChangeValue(value)
        self.SyncSpin(value)
    def SyncSpin(self, value):
        try:
            intValue = int(value)
            self.spin.SetValue(intValue)
        except:
            self.spin.SetValue(self.default)
    def OnChange(self, evt):
        self.SyncSpin(evt.GetString())
        Presenter.setApplied(False)
        evt.Skip()
    def SyncText(self, spinValue):
        if self.range[0] <= spinValue <= self.range[1]:
            self.text.ChangeValue(str(spinValue))
            Presenter.setApplied(False)
    def OnSpinUp(self, evt):
        self.SyncText(evt.GetPosition())
        evt.Skip()
    def OnSpinDown(self, evt):
        self.SyncText(evt.GetPosition())
        evt.Skip()

def MetaParamInt(**kargs):
    '''Create ParamInt class with default value.'''
    return type('ParamInt', (ParamInt,), kargs)

ParamIntNN = MetaParamInt(default=0, range=(0, 2147483647)) # non-negative
ParamIntP = MetaParamInt(default=1, range=(1, 2147483647)) # positive

# Same as ParamInt but allows dialog units (XXXd)
class ParamUnit(ParamInt):
    '''Similar to L{ParamInt}, 'd' can be appended to the value to specify
    dialog units mode.'''
    def _splitValue(self, value):
        units = ''
        if value[-1:].upper() == 'D':
            units = value[-1]
            value = value[:-1]
        return value,units
    def SyncSpin(self, value):
        try:
            value,units = self._splitValue(value)
            intValue = int(value)
            self.spin.SetValue(intValue)
        except:
            self.spin.SetValue(self.default)
    def SyncText(self, spinValue):
        if self.range[0] <= spinValue <= self.range[1]:
            value,units = self._splitValue(self.text.GetValue())
            self.text.ChangeValue(str(spinValue)+units)
            Presenter.setApplied(False)

class ParamMultilineText(PPanel):
    '''Multiline text editing.'''
    def __init__(self, parent, name, textWidth=-1):
        PPanel.__init__(self, parent, name)
        sizer = wx.BoxSizer()
        self.text = wx.TextCtrl(self, size=wx.Size(200,textH))
        sizer.Add(self.text, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, textB)
        self.button = wx.BitmapButton(self, bitmap=bmpEdit, size=(-1,textH))
        sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
        self.SetSizer(sizer)
        self.button.Bind(wx.EVT_BUTTON, self.OnButtonEdit)
        self.text.Bind(wx.EVT_TEXT, self.OnChange)
        self.text.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
    def GetValue(self):
        return self.text.GetValue()
    def SetValue(self, value):
        self.text.ChangeValue(value)
    def OnButtonEdit(self, evt):
        dlg = g.res.LoadDialog(self, 'DIALOG_TEXT')
        textCtrl = xrc.XRCCTRL(dlg, 'TEXT')
        textCtrl.SetValue(self.text.GetValue())
        if dlg.ShowModal() == wx.ID_OK:
            self.text.ChangeValue(textCtrl.GetValue())
            Presenter.setApplied(False)
        dlg.Destroy()

class ParamText(PPanel):
    '''Text attribute.'''
    textWidth = -1
    proportion = 0
    def __init__(self, parent, name, **kargs):
        PPanel.__init__(self, parent, name)
        style = kargs.pop('style', 0)
        textWidth = kargs.pop('textWidth', self.textWidth)
        option = kargs.pop('proportion', self.proportion)
        if textWidth == -1: option = 1
        # We use sizer even here to have the same size of text control
        sizer = wx.BoxSizer()
        self.text = wx.TextCtrl(self, size=wx.Size(textWidth,textH), style=style)
        sizer.Add(self.text, option, wx.ALIGN_CENTER_VERTICAL | wx.ALL, textB)
        self.SetSizer(sizer)
        self.text.Bind(wx.EVT_TEXT, self.OnChange)
        self.text.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
    def GetValue(self):
        return self.text.GetValue()
    def SetValue(self, value):
        self.text.ChangeValue(value)

def MetaParamText(textWidth, proportion=0):
    '''Return a L{ParamText} class with specified width and proportion.'''
    return type('ParamText__length', (ParamText,),
                {'textWidth': textWidth, 'proportion': proportion})

ParamLongText = MetaParamText(200, 1)
ParamAccel = MetaParamText(100)
ParamHelp = MetaParamText(200, 1)
ParamPosSize = MetaParamText(80)

class ParamComment(ParamText):
    '''Comment node editing.'''
    def __init__(self, parent, name):
        ParamText.__init__(self, parent, name, textWidth=330,
                           style=wx.TE_PROCESS_ENTER)

class ContentDialog(wx.Dialog):
    '''Dialog for editing content attributes.'''
    def __init__(self, parent, value):
        # Load from resource
        pre = wx.PreDialog()
        g.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT')
        self.PostCreate(pre)
        self.list = xrc.XRCCTRL(self, 'LIST')
        # Set list items
        for v in value:
            self.list.Append(v)
        self.SetAutoLayout(True)
        self.GetSizer().Fit(self)
        # Callbacks
        self.ID_BUTTON_APPEND = xrc.XRCID('BUTTON_APPEND')
        self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE')
        self.ID_BUTTON_UP = xrc.XRCID('BUTTON_UP')
        self.ID_BUTTON_DOWN = xrc.XRCID('BUTTON_DOWN')
        wx.EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
        wx.EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
        wx.EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
        wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
        wx.EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
        wx.EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
        wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
    def OnButtonUp(self, evt):
        i = self.list.GetSelection()
        str = self.list.GetString(i)
        self.list.Delete(i)
        self.list.InsertItems([str], i-1)
        self.list.SetSelection(i-1)
    def OnButtonDown(self, evt):
        i = self.list.GetSelection()
        str = self.list.GetString(i)
        self.list.Delete(i)
        self.list.InsertItems([str], i+1)
        self.list.SetSelection(i+1)
    def OnButtonAppend(self, evt):
        str = wx.GetTextFromUser('Enter new item:', 'Append', '', self)
        self.list.Append(str)
    def OnButtonRemove(self, evt):
        self.list.Delete(self.list.GetSelection())
    def OnUpdateUI(self, evt):
        if evt.GetId() == self.ID_BUTTON_REMOVE:
            evt.Enable(self.list.GetSelection() != -1)
        elif evt.GetId() == self.ID_BUTTON_UP:
            evt.Enable(self.list.GetSelection() > 0)
        elif evt.GetId() == self.ID_BUTTON_DOWN:
            evt.Enable(self.list.GetSelection() != -1 and \
                       self.list.GetSelection() < self.list.GetCount() - 1)

class ContentCheckListDialog(wx.Dialog):
    '''Dialog for editing content checklist attributes.'''
    def __init__(self, parent, value):
        pre = wx.PreDialog()
        g.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT_CHECKLIST')
        self.PostCreate(pre)
        self.list = xrc.XRCCTRL(self, 'CHECK_LIST')
        # Set list items
        i = 0
        for v,ch in value:
            self.list.Append(v)
            self.list.Check(i, ch)
            i += 1
        self.SetAutoLayout(True)
        self.GetSizer().Fit(self)
        # Callbacks
        self.ID_BUTTON_APPEND = xrc.XRCID('BUTTON_APPEND')
        self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE')
        self.ID_BUTTON_UP = xrc.XRCID('BUTTON_UP')
        self.ID_BUTTON_DOWN = xrc.XRCID('BUTTON_DOWN')
        wx.EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck)
        wx.EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
        wx.EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
        wx.EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
        wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
        wx.EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
        wx.EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
        wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
    def OnCheck(self, evt):
        # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
        self.list.Deselect(evt.GetSelection())
    def OnButtonUp(self, evt):
        i = self.list.GetSelection()
        str, ch = self.list.GetString(i), self.list.IsChecked(i)
        self.list.Delete(i)
        self.list.InsertItems([str], i-1)
        self.list.Check(i-1, ch)
        self.list.SetSelection(i-1)
    def OnButtonDown(self, evt):
        i = self.list.GetSelection()
        str, ch = self.list.GetString(i), self.list.IsChecked(i)
        self.list.Delete(i)
        self.list.InsertItems([str], i+1)
        self.list.Check(i+1, ch)
        self.list.SetSelection(i+1)
    def OnButtonAppend(self, evt):
        str = wx.GetTextFromUser('Enter new item:', 'Append', '', self)
        self.list.Append(str)
    def OnButtonRemove(self, evt):
        self.list.Delete(self.list.GetSelection())
    def OnUpdateUI(self, evt):
        if evt.GetId() == self.ID_BUTTON_REMOVE:
            evt.Enable(self.list.GetSelection() != -1)
        elif evt.GetId() == self.ID_BUTTON_UP:
            evt.Enable(self.list.GetSelection() > 0)
        elif evt.GetId() == self.ID_BUTTON_DOWN:
            evt.Enable(self.list.GetSelection() != -1 and \
                       self.list.GetSelection() < self.list.GetCount() - 1)

class ParamContent(PPanel):
    '''Editing of content attribute.'''
    def __init__(self, parent, name):
        PPanel.__init__(self, parent, name)
        sizer = wx.BoxSizer()
        self.text = wx.TextCtrl(self, size=wx.Size(200,textH))
        sizer.Add(self.text, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, textB)
        self.button = wx.BitmapButton(self, bitmap=bmpEdit, size=(-1,textH))
        sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
        self.SetSizer(sizer)
        self.textModified = False
        self.button.Bind(wx.EVT_BUTTON, self.OnButtonEdit)
        self.text.Bind(wx.EVT_TEXT, self.OnChange)
    def OnChange(self, evt):
        Presenter.setApplied(False)
        self.textModified = True
        evt.Skip()
    def GetValue(self):
        if self.textModified:           # text has newer value
            try:
                return self.text.GetValue().split('|')
            except ValueError:
                return []
        return self.value
    def SetValue(self, value):
        if not value: value = []
        self.value = value
        repr_ = '|'.join(map(str, value))
        self.text.ChangeValue(repr_)  # update text ctrl
    def OnButtonEdit(self, evt):
        if self.textModified:           # text has newer value
            self.value = self.GetValue()
        dlg = ContentDialog(self, self.value)
        if dlg.ShowModal() == wx.ID_OK:
            value = []
            for i in range(dlg.list.GetCount()):
                value.append(dlg.list.GetString(i))
            self.SetValue(value)
            Presenter.setApplied(False)
            self.textModified = False
        dlg.Destroy()

# CheckList content
class ParamContentCheckList(ParamContent):
    '''Editing of content check list attribute.'''
    def __init__(self, parent, name):
        ParamContent.__init__(self, parent, name)
    def OnButtonEdit(self, evt):
        if self.textModified:           # text has newer value
            self.value = self.GetValue()
        dlg = ContentCheckListDialog(self, self.value)
        if dlg.ShowModal() == wx.ID_OK:
            value = []
            for i in range(dlg.list.GetCount()):
                value.append((dlg.list.GetString(i), int(dlg.list.IsChecked(i))))
            self.SetValue(value)
            Presenter.setApplied(False)
            self.textModified = False
        dlg.Destroy()
    def SetValue(self, value):
        if not value: value = []
        self.value = value
        repr_ = '|'.join(map(str,value))
        self.text.ChangeValue(repr_)  # update text ctrl

class IntListDialog(wx.Dialog):
    '''Dialog for editing integer lists.'''
    def __init__(self, parent, value):
        pre = wx.PreDialog()
        g.res.LoadOnDialog(pre, parent, 'DIALOG_INTLIST')
        self.PostCreate(pre)
        self.list = xrc.XRCCTRL(self, 'LIST')
        # Set list items
        value.sort()
        for v in value:
            self.list.Append(v)
        self.SetAutoLayout(True)
        self.GetSizer().Fit(self)
        # Callbacks
        self.spinCtrl = xrc.XRCCTRL(self, 'SPIN')
        wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_ADD'), self.OnButtonAdd)
        self.ID_BUTTON_REMOVE = xrc.XRCID('BUTTON_REMOVE')
        wx.EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
        wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_CLEAR'), self.OnButtonClear)
        wx.EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
    def OnButtonAdd(self, evt):
        # Check that it's unique
        try:
            v = self.spinCtrl.GetValue()
            s = str(v)                  # to be sure
            i = self.list.FindString(s)
            if i == -1:                 # ignore non-unique
                # Find place to insert
                found = False
                for i in range(self.list.GetCount()):
                    if int(self.list.GetString(i)) > v:
                        found = True
                        break
                if found: self.list.InsertItems([s], i)
                else: self.list.Append(s)
        except ValueError:
            wx.LogError('List item is not an int!')
    def OnButtonRemove(self, evt):
        self.list.Delete(self.list.GetSelection())
    def OnButtonClear(self, evt):
        self.list.Clear()
    def OnUpdateUI(self, evt):
        if evt.GetId() == self.ID_BUTTON_REMOVE:
            evt.Enable(self.list.GetSelection() != -1)

# For growable list
class ParamIntList(ParamContent):
    '''Editing integer list attribute.'''
    def __init__(self, parent, name):
        ParamContent.__init__(self, parent, name)
    def OnButtonEdit(self, evt):
        if self.textModified:           # text has newer value
            try:
                self.value = self.text.GetValue().split('|')
            except ValueError:
                self.value = []
        dlg = IntListDialog(self, self.value)
        if dlg.ShowModal() == wx.ID_OK:
            value = []
            for i in range(dlg.list.GetCount()):
                value.append(dlg.list.GetString(i))
            self.SetValue(value)
            Presenter.setApplied()
            self.textModified = False
        dlg.Destroy()

# Boxless radiobox
class RadioBox(PPanel):
    def __init__(self, parent, name='radiobox'):
        PPanel.__init__(self, parent, name)
        topSizer = wx.BoxSizer()
        self.choicesInv = {}
        for i,v in self.choices.items():
            self.choicesInv[v] = i
            button = wx.RadioButton(self, -1, i, name=i)
            topSizer.Add(button, 0, wx.RIGHT, 5)
            wx.EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice)
        self.SetSizer(topSizer)
    def SetStringSelection(self, value):
        for i in self.choices.keys():
            self.FindWindowByName(i).SetValue(i == value)
        self.value = value
    def OnRadioChoice(self, evt):
        if evt.GetSelection():
            self.value = evt.GetEventObject().GetName()
            Presenter.setApplied(False)
    def GetStringSelection(self):
        return self.value
    def GetValue(self):
        return self.choices[self.GetStringSelection()]
    def SetValue(self, value):
        if not value: value = self.default
        self.SetStringSelection(self.choicesInv[value])

# Base type for checkable parameters
class CheckBox(PPanel):
    isCheck = True
    def __init__(self, parent, name='checkbox'):
        PPanel.__init__(self, parent, name)
        topSizer = wx.BoxSizer()
        self.check = wx.CheckBox(self, -1, name, size=(-1,textH))
        topSizer.Add(self.check, 0, wx.TOP | wx.BOTTOM, textB)
        self.check.Bind(wx.EVT_CHECKBOX, self.OnCheck)
        self.SetSizer(topSizer)
    def OnCheck(self, evt):
        Presenter.setApplied(False)
        if Presenter.panelIsDirty():
            Presenter.registerUndoEdit()
        if Listener.testWin.IsShown() and g.conf.autoRefresh and \
                g.conf.autoRefreshPolicy == AUTO_REFRESH_POLICY_FOCUS:
            Listener.testWin.isDirty = True
            wx.CallAfter(Presenter.refreshTestWin)
        evt.Skip()

class ParamBool(CheckBox):
    '''Editing on/off attributes.'''
    defaultString = '(default is OFF)'
    def GetValue(self):
        return ('', '1')[self.check.IsChecked()]
    def SetValue(self, value):
        self.check.SetValue(value == '1')

class ParamInverseBool(CheckBox):
    '''like L{ParamBool} but defined if unchecked'''
    defaultString = '(default is ON)'
    def GetValue(self):
        return ('0', '')[self.check.IsChecked()]
    def SetValue(self, value):
        self.check.SetValue(not value or value == '1')

class ParamOrient(RadioBox):
    '''Orientation attribute editing for sizers.'''
    choices = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
    default = 'wxHORIZONTAL'

class ParamOrientation(RadioBox):
    '''Orientaiton attribute editing for C{wx.SplitterWindow}.'''
    choices = {'horizontal': 'horizontal', 'vertical': 'vertical'}
    default = 'vertical'

class ParamBitmap(PPanel):
    def __init__(self, parent, name):
        pre = wx.PrePanel()
        g.res.LoadOnPanel(pre, parent, 'PANEL_BITMAP')
        self.PostCreate(pre)
        self.modified = False
        self.radio_std = xrc.XRCCTRL(self, 'RADIO_STD')
        self.radio_file = xrc.XRCCTRL(self, 'RADIO_FILE')
        self.combo = xrc.XRCCTRL(self, 'COMBO_STD')
        self.text = xrc.XRCCTRL(self, 'TEXT_FILE')
        self.button = xrc.XRCCTRL(self, 'BUTTON_BROWSE')
        self.textModified = False
        wx.EVT_RADIOBUTTON(self, xrc.XRCID('RADIO_STD'), self.OnRadioStd)
        wx.EVT_RADIOBUTTON(self, xrc.XRCID('RADIO_FILE'), self.OnRadioFile)
        wx.EVT_BUTTON(self, xrc.XRCID('BUTTON_BROWSE'), self.OnButtonBrowse)
        wx.EVT_COMBOBOX(self, xrc.XRCID('COMBO_STD'), self.OnCombo)
        wx.EVT_TEXT(self, xrc.XRCID('COMBO_STD'), self.OnChange)
        wx.EVT_TEXT(self, xrc.XRCID('TEXT_FILE'), self.OnChange)
    def OnRadioStd(self, evt):
        Presenter.setApplied(False)
        self.SetValue(['wxART_MISSING_IMAGE',''])
    def OnRadioFile(self, evt):
        Presenter.setApplied(False)
        self.SetValue(['',''])
    def updateRadios(self):
        if self.value[0]:
            self.radio_std.SetValue(True)
            self.radio_file.SetValue(False)
            self.text.Enable(False)
            self.button.Enable(False)
            self.combo.Enable(True)
        else:
            self.radio_std.SetValue(False)
            self.radio_file.SetValue(True)
            self.text.Enable(True)
            self.button.Enable(True)
            self.combo.Enable(False)
    def OnChange(self, evt):
        Presenter.setApplied(False)
        self.textModified = True
        evt.Skip()
    def OnCombo(self, evt):
        Presenter.setApplied(False)
        self.value[0] = self.combo.GetValue()
    def GetValue(self):
        return [self.combo.GetValue(), self.text.GetValue()]
    def SetValue(self, value):
        if not value:
            self.value = ['', '']
        else:
            self.value = value
        self.combo.SetValue(self.value[0])
        self.text.ChangeValue(self.value[1])  # update text ctrl
        self.updateRadios()
    def OnButtonBrowse(self, evt):
        if self.textModified:           # text has newer value
            self.value[1] = self.text.GetValue()
        dlg = wx.FileDialog(self,
                           defaultDir = os.path.abspath(os.path.dirname(self.value[1])),
                           defaultFile = os.path.basename(self.value[1]))
        if dlg.ShowModal() == wx.ID_OK:
            # Get common part of selected path and current
            if Presenter.path:
                curpath = os.path.abspath(Presenter.path)
            else:
                curpath = os.path.join(os.getcwd(), '')
            common = os.path.commonprefix([curpath, dlg.GetPath()])
            self.SetValue(['', dlg.GetPath()[len(common):]])
            Presenter.setApplied(False)
            self.textModified = False
        dlg.Destroy()

class ParamImage(PPanel):
    '''Image selector.'''
    def __init__(self, parent, name):
        PPanel.__init__(self, parent, name)
        sizer = wx.BoxSizer()
        self.text = wx.TextCtrl(self, size=wx.Size(200,textH))
        sizer.Add(self.text, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, textB)
        self.button = wx.Button(self, -1, 'Browse...')
        sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL)
        self.SetSizer(sizer)
        self.button.Bind(wx.EVT_BUTTON, self.OnButtonBrowse)
        self.text.Bind(wx.EVT_TEXT, self.OnChange)
    def OnChange(self, evt):
        Presenter.setApplied(False)
        evt.Skip()
    def GetValue(self):
        return self.text.GetValue()
    def SetValue(self, value):
        self.text.ChangeValue(value)
    def OnButtonBrowse(self, evt):
        value = self.text.GetValue()
        dlg = wx.FileDialog(self,
                           defaultDir = os.path.abspath(os.path.dirname(value)),
                           defaultFile = os.path.basename(value))
        if dlg.ShowModal() == wx.ID_OK:
            # Get common part of selected path and current
            if Presenter.path:
                curpath = os.path.abspath(Presenter.path)
            else:
                curpath = os.path.join(os.getcwd(), '')
            common = os.path.commonprefix([curpath, dlg.GetPath()])
            self.SetValue(dlg.GetPath()[len(common):])
            Presenter.setApplied(False)
            self.textModified = False
        dlg.Destroy()

class ParamCombo(PPanel):
    values = []
    '''Combo box.'''
    def __init__(self, parent, name):
        PPanel.__init__(self, parent, name)
        sizer = wx.BoxSizer()
        self.combo = wx.ComboBox(self, size=(220,-1))
        if wx.Platform == '__WXMAC__':
            sizer.Add(self.combo, 0, wx.ALL, 0)
        else:
            sizer.Add(self.combo, 0, wx.ALL, 2)
        self.SetSizerAndFit(sizer)
        self.combo.Bind(wx.EVT_TEXT, self.OnChange)
        self.SetValues()
    def GetValue(self):
        return self.combo.GetValue()
    def SetValue(self, value):
        self.combo.SetValue(value)
    def SetValues(self):
        for v in self.values:
            self.combo.Append(v)

class ParamEncoding(ParamCombo):
    '''Editing encoding attribute of the XML root node.'''
    pass

paramDict = {
    # sizer params
    'flag': ParamFlag, 'orient': ParamOrient, 'option': ParamInt,
    'cellpos': ParamPosSize, 'cellspan': ParamPosSize,
    'border': ParamUnit, 'borders': ParamUnit,
    'cols': ParamIntP, 'rows': ParamIntP,
    'vgap': ParamUnit, 'hgap': ParamUnit,
    # common window params
    'pos': ParamPosSize, 'size': ParamPosSize,
    'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool,
    'accel': ParamAccel, 'help': ParamHelp, 'centered': ParamBool,
    'label': ParamMultilineText, 'title': ParamLongText, 'value': ParamLongText,
    'content': ParamContent, 'selection': ParamIntNN,
    'min': ParamInt, 'max': ParamInt,
    # window attributes
    'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont,
    'enabled': ParamInverseBool, 'focused': ParamBool, 'hidden': ParamBool,
    'tooltip': ParamLongText, 
    # other
    'bitmap': ParamBitmap, 'icon': ParamBitmap,
    'comment': ParamComment,
    'wrap': ParamInt,
    }
'''Default classes for standard attributes.'''

class StylePanel(wx.Panel):
    '''Style panel.'''
    def __init__(self, parent, styles, genericStyles=[], tag='style'):
        wx.Panel.__init__(self, parent, -1)
        self.SetFont(g.smallerFont())
        self.node = None
        self.controls = []
        self.tag = tag
        topSizer = wx.BoxSizer(wx.HORIZONTAL)
        if genericStyles:
            # Generic styles
            sizer = wx.GridSizer(len(genericStyles), 1, 1, 5)
            label = wx.StaticText(self, label='Generic')
            label.SetFont(g.labelFont())
            sizer.Add(label, 0, wx.LEFT, 20)
            for s in genericStyles:
                if s[:2] == 'wx': label = s[2:]
                else:             label = s
                control = wx.CheckBox(self, label=label)
                sizer.Add(control)
                self.controls.append((s, control))
            topSizer.Add(sizer)
        if styles:
            # Specific styles
            sizer = wx.GridSizer(len(styles), 1, 1, 5)
            if genericStyles:
                label = wx.StaticText(self, label='Specific')
                label.SetFont(g.labelFont())
                sizer.Add(label, 0, wx.LEFT, 20)
            for s in styles:
                if s[:2] == 'wx': label = s[2:]
                else:             label = s
                control = wx.CheckBox(self, label=label)
                sizer.Add(control)
                self.controls.append((s, control))
            topSizer.Add(sizer)
        self.Bind(wx.EVT_CHECKBOX, self.OnCheck)
        self.SetSizerAndFit(topSizer)

    def GetValues(self):
        checked = []
        for s,check in self.controls:
            if check.IsChecked(): checked.append(s)
        return [(self.tag, '|'.join(checked))]

    def SetValues(self, values):
        styles = values[0][1].split('|')
        for s,check in self.controls:
            check.SetValue(s in styles)

    def OnCheck(self, evt):
        Presenter.setApplied(False)
        if Listener.testWin.IsShown() and g.conf.autoRefresh and \
                g.conf.autoRefreshPolicy == AUTO_REFRESH_POLICY_FOCUS:
            Listener.testWin.isDirty = True
            wx.CallAfter(Presenter.refreshTestWin)
        evt.Skip()

#############################################################################

class CheckListBoxComboPopup(wx.CheckListBox, wx.combo.ComboPopup):
        
    def __init__(self, values):
        self.values = values
        self.PostCreate(wx.PreCheckListBox())
        wx.combo.ComboPopup.__init__(self)
        
    def Create(self, parent):
        wx.CheckListBox.Create(self, parent)
        self.InsertItems(self.values, 0)
        return True

    def GetControl(self):
        return self

    def OnPopup(self):
        combo = self.GetCombo()
        value = map(string.strip, combo.GetValue().split('|'))
        if value == ['']: value = []
        self.ignored = []
        for i in value:
            try:
                self.Check(self.values.index(i))
            except ValueError:
                # Try to find equal
                if self.equal.has_key(i):
                    self.Check(self.values.index(self.equal[i]))
                else:
                    logger.warning('unknown flag: %s: ignored.', i)
                    self.ignored.append(i)

        wx.combo.ComboPopup.OnPopup(self)

    def OnDismiss(self):
        combo = self.GetCombo()
        value = []
        for i in range(self.GetCount()):
            if self.IsChecked(i):
                value.append(self.values[i])
        # Add ignored flags
        value.extend(self.ignored)
        strValue = '|'.join(value)
        if combo.GetValue() != strValue:
            combo.SetValue(strValue)
            Presenter.setApplied(False)

        wx.combo.ComboPopup.OnDismiss(self)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.