ContainerCompanions.py :  » IDE » Boa-Constructor » boa-constructor-0.6.1 » Companions » 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 » IDE » Boa Constructor 
Boa Constructor » boa constructor 0.6.1 » Companions » ContainerCompanions.py
#-----------------------------------------------------------------------------
# Name:        ContainerCompanions.py
# Purpose:
#
# Author:      Riaan Booysen
#
# Created:     2002
# RCS-ID:      $Id: ContainerCompanions.py,v 1.19 2007/07/02 15:01:09 riaan Exp $
# Copyright:   (c) 2002 - 2007
# Licence:     GPL
#-----------------------------------------------------------------------------
print 'importing Companions.ContainerCompanions'

import copy

import wx

import Preferences, Utils
from Utils import _

from BaseCompanions import ContainerDTC,CollectionDTC,CollectionIddDTC
import PaletteStore

import Constructors
from EventCollections import *

from PropEdit.PropertyEditors import *
from PropEdit.Enumerations import *

import methodparse, sourceconst

EventCategories['PanelEvent'] = ('wx.EVT_SYS_COLOUR_CHANGED',)

class PanelDTC(Constructors.WindowConstr, ContainerDTC):
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors['DefaultItem'] = ButtonClassLinkPropEdit
        self.windowStyles.insert(0, 'wx.TAB_TRAVERSAL')

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos':   position,
                'size': self.getDefCtrlSize(),
                'style': 'wx.TAB_TRAVERSAL',
                'name':  `self.name`}

    def events(self):
        return ContainerDTC.events(self) + ['PanelEvent']

    def dependentProps(self):
        return ContainerDTC.dependentProps(self) + ['DefaultItem']

EventCategories['SashEvent'] = ('wx.EVT_SASH_DRAGGED', )
commandCategories.append('SashEvent')
class SashWindowDTC(Constructors.WindowConstr, ContainerDTC):
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors.update({'SashVisibleLeft' : SashVisiblePropEdit,
                             'SashVisibleTop' : SashVisiblePropEdit,
                             'SashVisibleRight' : SashVisiblePropEdit,
                             'SashVisibleBottom' : SashVisiblePropEdit})
        self.windowStyles = ['wx.SW_3D', 'wx.SW_3DSASH', 'wx.SW_3DBORDER',
                             'wx.SW_BORDER'] + self.windowStyles
        self.edgeNameMap = {'SashVisibleLeft'  : wx.SASH_LEFT,
                            'SashVisibleTop'   : wx.SASH_TOP,
                            'SashVisibleRight' : wx.SASH_RIGHT,
                            'SashVisibleBottom': wx.SASH_BOTTOM}
        for name in self.edgeNameMap.keys() + ['SashVisible']:
            self.customPropEvaluators[name] = self.EvalSashVisible
        #self.customPropEvaluators['SashVisible'] = self.EvalSashVisible

    def properties(self):
        props = ContainerDTC.properties(self)
        prop = ('NameRoute', self.GetSashVisible, self.SetSashVisible)
        for name in self.edgeNameMap.keys():
            props[name] = prop
        return props

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos':   position,
                'size': self.getDefCtrlSize(),
                'style': 'wx.CLIP_CHILDREN | wx.SW_3D',
                'name':  `self.name`}

    def events(self):
        return ContainerDTC.events(self) + ['SashEvent']

    def GetSashVisible(self, name):
        return self.edgeNameMap[name], self.control.GetSashVisible(self.edgeNameMap[name])

    def SetSashVisible(self, name, value):
        self.control.SetSashVisible(self.edgeNameMap[name], value[1])

    def EvalSashVisible(self, exprs, objects):
        res = []
        for expr in exprs:
            res.append(self.eval(expr))
        return tuple(res)

    def persistProp(self, name, setterName, value):
        if setterName == 'SetSashVisible':
            edge, visbl = value.split(',')
            for prop in self.textPropList:
                if prop.prop_setter == setterName and prop.params[0] == edge:
                    prop.params = [edge.strip(), visbl.strip()]
                    return
            self.textPropList.append(methodparse.PropertyParse( None, self.name,
                setterName, [edge.strip(), visbl.strip()], 'SetSashVisible'))
        else:
            ContainerDTC.persistProp(self, name, setterName, value)

class SashLayoutWindowDTC(SashWindowDTC):
    def __init__(self, name, designer, parent, ctrlClass):
        SashWindowDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors.update({'Alignment'   : EnumPropEdit,
                             'Orientation' : EnumPropEdit,
                            })
        self.options.update({'Alignment'   : sashLayoutAlignment,
                             'Orientation' : sashLayoutOrientation
                            })
        self.names.update({'Alignment'   : sashLayoutAlignmentNames,
                           'Orientation' : sashLayoutOrientationNames
                          })

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos':   position,
                'size': self.getDefCtrlSize(),
                'style': 'wx.CLIP_CHILDREN | wx.SW_3D',
                'name':  `self.name`}

    def properties(self):
        props = SashWindowDTC.properties(self)
        props.update({'DefaultSize': ('CompnRoute', self.GetDefaultSize,
          self.SetDefaultSize)})
        return props

    def getSizeDependentProps(self):
        return SashWindowDTC.getSizeDependentProps(self)+[('prop', 'DefaultSize')]

##    def events(self):
##        return ContainerDTC.events(self) + ['SashEvent']

    def GetDefaultSize(self, something):
        if self.control:
            return self.control.GetSize()
        else:
            return wx.Size(15, 15)

    def SetDefaultSize(self, size):
        if self.control:
            self.control.SetSize(size)

    def defaultAction(self):
        # should be called from 'Relayout' command
        self.control.SetDefaultSize(self.control.GetSize())
        wx.LayoutAlgorithm().LayoutWindow(self.control.GetParent())

class ScrolledWindowDTC(Constructors.WindowConstr, ContainerDTC):
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors['TargetWindow'] = WindowClassLinkPropEdit

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos':   position,
                'size': self.getDefCtrlSize(),
                'style': 'wx.HSCROLL | wx.VSCROLL',
                'name':  `self.name`}

    def dependentProps(self):
        return ContainerDTC.dependentProps(self) + ['TargetWindow']

    def events(self):
        return ContainerDTC.events(self) + ['ScrollWinEvent']
    
    def hideDesignTime(self):
        return ContainerDTC.hideDesignTime(self) + ['TargetRect']


    def notification(self, compn, action):
        ContainerDTC.notification(self, compn, action)
        if action == 'delete':
            if self.control.GetTargetWindow() == compn.control:
                self.propRevertToDefault('TargetWindow', 'SetTargetWindow')
                self.control.SetTargetWindow(self.control)

class BookCtrlDTC(Constructors.WindowConstr, ContainerDTC):
    bookCtrlName = 'wx.BookCtrl'
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors.update({'Pages':     CollectionPropEdit,
                             'ImageList': ImageListClassLinkPropEdit})
        self.subCompanions['Pages'] = BookCtrlPagesCDTC
        self.letClickThru = True

    def properties(self):
        props = ContainerDTC.properties(self)
        props.update({'Pages': ('NoneRoute', None, None)})
        del props['Sizer']
        return props

    def designTimeControl(self, position, size, args = None):
        ctrl = ContainerDTC.designTimeControl(self, position, size, args)
        ctrl.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged, id=ctrl.GetId())
        return ctrl

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos':   position,
                'size':  self.getDefCtrlSize(),
                'style': '0',
                'name':  `self.name`}

    def dependentProps(self):
        return ContainerDTC.dependentProps(self) + ['ImageList', 'Pages']

    def dontPersistProps(self):
        return ContainerDTC.dontPersistProps(self) + ['Selection']

    def defaultAction(self):
        self.designer.inspector.props.getNameValue('Pages').propEditor.edit(None)

    def OnPageChanged(self, event):
        try:
            if self.collections.has_key('Pages'):
                self.collections['Pages'].updateSelection(event.GetSelection())
                wx.PostEvent(self.control, wx.SizeEvent( self.control.GetSize() ))
        except Exception, err:
            print 'OnPageChanged exception', str(err)
        event.Skip()

    def notification(self, compn, action):
        ContainerDTC.notification(self, compn, action)
        if action == 'delete':
            if self.control.GetImageList() == compn.control:
                self.propRevertToDefault('ImageList', 'SetImageList')
                self.control.SetImageList(None)

class BookCtrlPagesCDTC(CollectionDTC):
    propName = 'Pages'
    displayProp = 'text'
    indexProp = '(None)'
    insertionMethod = 'AddPage'
    deletionMethod = 'RemovePage'

    def __init__(self, name, designer, parentCompanion, ctrl):
        CollectionDTC.__init__(self, name, designer, parentCompanion, ctrl)
        self.editors = {'Page': ClassLinkConstrPropEdit,
                        'Text': StrConstrPropEdit,
                        'Selected' : BoolConstrPropEdit,
                        'ImageId': IntConstrPropEdit}

        self.tempPlaceHolders = []

    def constructor(self):
        return {'Page': 'page', 'Text': 'text',
                'Selected' : 'select', 'ImageId': 'imageId'}

    def properties(self):
        props = CollectionDTC.properties(self)
        props.update({'Page': ('NoneRoute', None, None),
                      'Text': ('IndexRoute', wx.Notebook.GetPageText.im_func, wx.Notebook.SetPageText.im_func),
                      'Selected' : ('CompnRoute', self.GetPageSelected, self.SetPageSelected),
                      'ImageId': ('IndexRoute', wx.Notebook.GetPageImage.im_func, wx.Notebook.SetPageImage.im_func)})
        return props

##    def appendItem(self):
##        tph = wx.Window(self.control, -1)
##        self.tempPlaceHolders.append(tph)
##        CollectionDTC.appendItem(self)

    def designTimeSource(self, wId, method=None):
        return {'page': 'None',
                'text': `'%s%d'%(self.propName, wId)`,
                'select': 'True',
                'imageId': `-1`}

    def initDesignTimeEvents(self, ctrl):
        ctrlEvtHandler = self.designer.ctrlEvtHandler
        ctrl.Bind(wx.EVT_MOTION, ctrlEvtHandler.OnMouseOver)
        ctrl.Bind(wx.EVT_LEFT_DOWN, ctrlEvtHandler.OnControlSelect)
        ctrl.Bind(wx.EVT_LEFT_UP, ctrlEvtHandler.OnControlRelease)
        ctrl.Bind(wx.EVT_LEFT_DCLICK, ctrlEvtHandler.OnControlDClick)
        ctrl.Bind(wx.EVT_SIZE, ctrlEvtHandler.OnControlResize)

    def applyDesignTimeDefaults(self, params, method=None):
        prms = copy.copy(params)

        page = BlankWindowPage(self.control, self.designer, params, 'page')
        self.tempPlaceHolders.append(page)
        if params['page'] != 'None':
            ctrl = self.designer.objects[prms['page'][5:]][1]
            ctrl.Reparent(page)
            page.ctrl = ctrl

        del prms['page']
        params = self.designTimeDefaults(prms, method)
        params['page'] = page

        getattr(self.control, self.insertionMethod)(**params)

    def moveItem(self, idx, dir):
        newIdx = CollectionDTC.moveItem(self, idx, dir)
        if newIdx != idx:
            focus = self.control.GetSelection() == idx
            text = self.control.GetPageText(idx)
            img = self.control.GetPageImage(idx)
            page = self.control.GetPage(idx)
            if self.control.RemovePage(idx):
                self.control.InsertPage(newIdx, page, text, focus, img)
        return newIdx

    def deleteItem(self, idx):
        activePageDeleted = self.control.GetSelection() == idx

        CollectionDTC.deleteItem(self, idx)

        # Delete BlankWindow
        self.tempPlaceHolders[idx].Destroy()
        del self.tempPlaceHolders[idx]

        # Set new active page if necesary
        if activePageDeleted:
            newIdx = idx
            if idx == len(self.textConstrLst):
                newIdx = newIdx - 1
            elif len(self.textConstrLst) == 0:
                newIdx = None

            if newIdx is not None:
                if newIdx < self.control.GetPageCount():
                    self.updateSelection(newIdx)
                    self.control.SetSelection(newIdx)
                    self.control.Refresh()

        del self.textConstrLst[idx]

    def updateSelection(self, newSelection):
        idx = 0
        for constr in self.textConstrLst:
            constr.params['select'] = newSelection == idx and 'True' or 'False'
            idx = idx + 1

    def defaultAction(self):
        self.SetPageSelected(True)

    def GetPageSelected(self, compn):
        pass

    def SetPageSelected(self, value):
        if value:
            self.control.SetSelection(self.index)

    def notification(self, compn, action):
        if action == 'delete':
            if compn == self:
                # Notebook page being deleted
                # XXX Consider overwriting deleteItem for this
                constr = self.textConstrLst[compn.index]
                if constr.params['page'] != 'None':
                    self.designer.deleteCtrl(Utils.ctrlNameFromSrcRef(constr.params['page']))
            else:
                for constr in self.textConstrLst:
                    if Utils.srcRefFromCtrlName(compn.name) == constr.params['page']:
                        constr.params['page'] == 'None'

                for tph in self.tempPlaceHolders:
                    if tph.ctrl == compn.control:
                        tph.clearCtrl()

    def writeCollectionItems(self, output, stripFrmId=''):
        CollectionDTC.writeCollectionItems(self, output, stripFrmId)
        warn = 0
        for constr in self.textConstrLst:
            if constr.params['page'] == 'None':
                wx.LogWarning('No control for %s, page %s'%(
                      self.parentCompanion.name, constr.params['text']))
                warn = 1
        if warn:
            wx.LogWarning(_('The red-dashed area of a %s page must contain\n'\
            'a control or the generated source will be invalid outside the '\
            'Designer')% self.parentCompanion.bookCtrlName)

[wxID_CTRLPARENT, wxID_EDITPASTE, wxID_EDITDELETE] = Utils.wxNewIds(3)

class BlankWindowPage(wx.Window):
    """ Window representing uninitialised space, it grabs the first control
        dropped onto it and replaces None with new ctrl in code.

        Used by BookCtrls for a default page
    """

    # XXX A delete of this object should remove the page from the notebook

    # XXX Copy/Cutting a blank page does not make sense ???

    def __init__(self, parent, designer, params, nameKey):
        wx.Window.__init__(self, parent, -1)
        self.params = params
        self.designer = designer

        # XXX how/when can I delete this menu, it will leak !!
        self.menu = wx.Menu()
        self.menu.Append(wxID_CTRLPARENT, 'Up')
        self.menu.AppendSeparator()
        self.menu.Append(wxID_EDITPASTE, 'Paste')
        self.menu.Append(wxID_EDITDELETE, 'Delete')
        self.Bind(wx.EVT_MENU, self.OnCtrlParent, id=wxID_CTRLPARENT)
        self.Bind(wx.EVT_MENU, self.OnCtrlPaste, id=wxID_EDITPASTE)
        self.Bind(wx.EVT_MENU, self.OnCtrlDelete, id=wxID_EDITDELETE)

        ctrlEvtHandler = self.designer.ctrlEvtHandler
        self.Bind(wx.EVT_MOTION, ctrlEvtHandler.OnMouseOver)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnControlSelect)
        self.Bind(wx.EVT_LEFT_UP, ctrlEvtHandler.OnControlRelease)
        self.Bind(wx.EVT_LEFT_DCLICK, ctrlEvtHandler.OnControlDClick)
        self.Bind(wx.EVT_SIZE, self.OnControlResize)
        self.Bind(wx.EVT_MOVE, self.OnControlMove)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_RIGHT_UP, self.OnPopupMenu)

        self.SetName(parent.GetName())
        self.ctrl = None
        self.nameKey = nameKey

        self.proxyContainer = True

    def clearCtrl(self):
        self.ctrl = None
        self.params[self.nameKey] = 'None'

    def OnControlSelect(self, event):
        """ Select parent of proxy container or create new control, update
            page reference to it and resize new ctrl to fill proxy container
        """
        dsgn = self.designer
        new = dsgn.compPal.selection
        if self.ctrl:
            dsgn.selectControlByPos(self.ctrl, event.GetPosition(), event.ShiftDown())
        else:
            dsgn.ctrlEvtHandler.OnControlSelect(event)

        if new:
            self.linkToNewestControl()

    def OnControlResize(self, event):
        """ Child ctrl of the proxy container should be sized to fill the control
        """
        if self.ctrl:
            p = self.GetPosition()
            s = self.GetSize()
            self.ctrl.SetDimensions(0, 0, s.x, s.y)
        else:
            self.designer.ctrlEvtHandler.OnControlResize(event)

    dashSize = 8
    def OnPaint(self, event):
        """ Draw red dash pattern, hopefully implying danger are that must be
            filled
        """
        try:
            if self.ctrl is None:
                dc = wx.PaintDC(self)
                sze = self.GetClientSize()

                dc.SetPen(wx.RED_PEN)
                dc.BeginDrawing()
                try:
                    for i in range((sze.x + sze.y) / self.dashSize):
                        dc.DrawLine(0, i*self.dashSize, i*self.dashSize, 0)
                finally:
                    dc.EndDrawing()
        finally:
            event.Skip()

    def OnControlMove(self, event):
        """ When moved or sized, ignore and fill the proxy container
        """
        parent = self.GetParent()
        wx.PostEvent(parent, wx.SizeEvent( parent.GetSize() ))

    def OnCtrlParent(self, event):
        self.designer.OnSelectParent(event)

    def OnCtrlPaste(self, event):
        self.designer.OnPasteSelected(event)

    def OnCtrlDelete(self, event):
        self.designer.OnControlDelete(event)

    def OnPopupMenu(self, event):
        self.PopupMenu(self.menu, event.GetPosition())

    def linkToNewestControl(self):
        self.ctrl = self.designer.objects[self.designer.objectOrder[-1:][0]][1]
        self.params[self.nameKey] = Utils.srcRefFromCtrlName(self.ctrl.GetName())
        self.OnControlResize(None)


EventCategories['NotebookEvent'] = ('wx.EVT_NOTEBOOK_PAGE_CHANGED',
                                    'wx.EVT_NOTEBOOK_PAGE_CHANGING')
commandCategories.append('NotebookEvent')
class NotebookDTC(BookCtrlDTC):
    bookCtrlName = 'wx.Notebook'
    def __init__(self, name, designer, parent, ctrlClass):
        BookCtrlDTC.__init__(self, name, designer, parent, ctrlClass)
        self.windowStyles = ['wx.NB_FIXEDWIDTH', 'wx.NB_LEFT', 'wx.NB_RIGHT',
                             'wx.NB_BOTTOM', 'wx.NB_MULTILINE'] + self.windowStyles
    def events(self):
        return BookCtrlDTC.events(self) + ['NotebookEvent']


EventCategories['ListbookEvent'] = ('wx.EVT_LISTBOOK_PAGE_CHANGED', 
                                    'wx.EVT_LISTBOOK_PAGE_CHANGING')
commandCategories.append('ListbookEvent')
class ListbookDTC(BookCtrlDTC):
    bookCtrlName = 'wx.Listbook'
    def __init__(self, name, designer, parent, ctrlClass):
        BookCtrlDTC.__init__(self, name, designer, parent, ctrlClass)
        self.windowStyles = ['wx.LB_DEFAULT', 'wx.LB_TOP', 'wx.LB_LEFT', 
              'wx.LB_RIGHT', 'wx.LB_BOTTOM', 'wx.LB_ALIGN_MASK'] + self.windowStyles
    def events(self):
        return BookCtrlDTC.events(self) + ['ListbookEvent']


EventCategories['ChoicebookEvent'] = ('wx.EVT_CHOICEBOOK_PAGE_CHANGED', 
                                      'wx.EVT_CHOICEBOOK_PAGE_CHANGING')
commandCategories.append('ListbookEvent')
class ChoicebookDTC(BookCtrlDTC):
    bookCtrlName = 'wx.Choicebook'
    def __init__(self, name, designer, parent, ctrlClass):
        BookCtrlDTC.__init__(self, name, designer, parent, ctrlClass)
        self.windowStyles = ['wx.CHB_DEFAULT', 'wx.CHB_TOP', 'wx.CHB_LEFT', 
              'wx.CHB_RIGHT', 'wx.CHB_BOTTOM', 'wx.CHB_ALIGN_MASK'] + self.windowStyles
    def events(self):
        return BookCtrlDTC.events(self) + ['ChoicebookEvent']

EventCategories['TreebookEvent'] = ('wx.EVT_TREEBOOK_PAGE_CHANGED', 
                                    'wx.EVT_TREEBOOK_PAGE_CHANGING',
                                    'wx.EVT_TREEBOOK_NODE_COLLAPSED',
                                    'wx.EVT_TREEBOOK_NODE_EXPANDED')
commandCategories.append('TreebookEvent')
class TreebookDTC(BookCtrlDTC):
    bookCtrlName = 'wx.Treebook'
    def __init__(self, name, designer, parent, ctrlClass):
        BookCtrlDTC.__init__(self, name, designer, parent, ctrlClass)
        self.windowStyles = ['wx.BK_DEFAULT', 'wx.BK_TOP', 'wx.BK_LEFT', 
              'wx.BK_RIGHT', 'wx.BK_BOTTOM'] + self.windowStyles
    def events(self):
        return BookCtrlDTC.events(self) + ['TreebookEvent']

EventCategories['ToolbookEvent'] = ('wx.EVT_TOOLBOOK_PAGE_CHANGED', 
                                    'wx.EVT_TOOLBOOK_PAGE_CHANGING')
commandCategories.append('ToolbookEvent')
class ToolbookDTC(BookCtrlDTC):
    bookCtrlName = 'wx.Toolbook'
    def __init__(self, name, designer, parent, ctrlClass):
        BookCtrlDTC.__init__(self, name, designer, parent, ctrlClass)
        self.windowStyles = ['wx.BK_DEFAULT'] + self.windowStyles
    def events(self):
        return BookCtrlDTC.events(self) + ['ToolbookEvent']


EventCategories['SplitterWindowEvent'] = ('wx.EVT_SPLITTER_SASH_POS_CHANGING',
                                          'wx.EVT_SPLITTER_SASH_POS_CHANGED',
                                          'wx.EVT_SPLITTER_UNSPLIT',
                                          'wx.EVT_SPLITTER_DOUBLECLICKED')
commandCategories.append('SplitterWindowEvent')

class SplitterWindowDTC(ContainerDTC):
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors.update({'SplitMode': EnumPropEdit,
                             'Window1'  : SplitterWindow1LinkPropEdit,
                             'Window2'  : SplitterWindow2LinkPropEdit})
        self.options['SplitMode'] = splitterWindowSplitMode
        self.names['SplitMode'] = splitterWindowSplitModeNames
        self.windowStyles = ['wx.SP_3D', 'wx.SP_3DSASH', 'wx.SP_3DBORDER',
                             'wx.SP_BORDER', 'wx.SP_NOBORDER', 
                             'wx.SP_PERMIT_UNSPLIT', 'wx.SP_LIVE_UPDATE',
                             ] + self.windowStyles 
        self.win1 = None
        self.win2 = None

    def constructor(self):
        return {'Position': 'pos', 'Size': 'size', 'Style': 'style',
                'Name': 'name'}

    def properties(self):
        props = ContainerDTC.properties(self)
        props.update({'Window1'  : ('CompnRoute', self.GetWindow1, self.SetWindow1),
                      'Window2'  : ('CompnRoute', self.GetWindow2, self.SetWindow2),
                      'SplitMode': ('CompnRoute', self.GetSplitMode, self.SetSplitMode),})
        return props

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos': position,
                'size': self.getDefCtrlSize(),
                'style': 'wx.SP_3D',
                'name':  `self.name`}

    def hideDesignTime(self):
        return ContainerDTC.hideDesignTime(self) + ['SplitMode']

    def dependentProps(self):
        return ContainerDTC.dependentProps(self) + \
          ['SplitVertically', 'SplitHorizontally']

    def events(self):
        return ContainerDTC.events(self) + ['SplitterWindowEvent']

    modeMethMap = {wx.SPLIT_VERTICAL:   'SplitVertically',
                   wx.SPLIT_HORIZONTAL: 'SplitHorizontally'}

    def renameCtrlRefs(self, oldName, newName):
        ContainerDTC.renameCtrlRefs(self, oldName, newName)
        # Check if subwindow references have changed
        # XXX should maybe be done with notification, action = 'rename'
        oldSrc = Utils.srcRefFromCtrlName(oldName)
        for prop in self.textPropList:
            if prop.prop_setter in ('SplitVertically', 'SplitHorizontally'):
                if oldSrc in prop.params:
                    prop.params[prop.params.index(oldSrc)] = \
                          Utils.srcRefFromCtrlName(newName)

    def persistProp(self, name, setterName, value):
        """ When attempting to persist the Window properties and the
            SplitMode property, add, or update a previously
            defined  SplitVertically or SplitHorizontally method."""

        if setterName in ('SetWindow1', 'SetWindow2'):
            propSN = setterName
            setterName = self.modeMethMap[self.control.GetSplitMode()]

            win1, win2 = self.GetWindow1(None), self.GetWindow2(None)
            sashPos = `self.control.GetSashPosition()`

            if win1: win1 = 'self.'+win1.GetName()
            else: win1 = 'None'
            if win2: win2 = 'self.'+win2.GetName()
            else: win2 = 'None'

            for prop in self.textPropList:
                if prop.prop_setter in ('SplitVertically', 'SplitHorizontally'):
                    prop.prop_setter = setterName
                    prop.params = [win1, win2, sashPos]
                    return
            self.textPropList.append(methodparse.PropertyParse( None, self.name,
                setterName, [win1, win2, sashPos], setterName))
        elif setterName == 'SetSplitMode':
            sm = self.control.GetSplitMode()
            setterName = self.modeMethMap[sm]
            for prop in self.textPropList:
                if prop.prop_setter == 'SplitVertically' and sm == wx.SPLIT_HORIZONTAL or \
                   prop.prop_setter == 'SplitHorizontally' and sm == wx.SPLIT_VERTICAL:
                    prop.prop_setter = setterName
                    return

        elif setterName == 'SetSashPosition':
            for prop in self.textPropList:
                if prop.prop_setter in ('SplitVertically', 'SplitHorizontally'):
                    prop.params[2] = value
                    return
        else:
            ContainerDTC.persistProp(self, name, setterName, value)

    def persistedPropVal(self, name, setterName):
        # Unlike usual properties, SashPosition is persisted as a Split* method
        # Therefore it needs to check the Split* method for the source value
        if setterName == 'SetSashPosition':
            for prop in self.textPropList:
                if prop.prop_setter in ('SplitVertically', 'SplitHorizontally'):
                    return prop.params[2]
        return ContainerDTC.persistedPropVal(self, name, setterName)

    def notification(self, compn, action):
        ContainerDTC.notification(self, compn, action)
        if action == 'delete':
            # If the splitter itself is deleted it should unsplit so that
            # deletion notifications from it's children won't cause
            # access to deleted controls
            if compn.control == self.control:
                self.win1 = self.win2 = None
                self.splitWindow(None, None)
                return
            # Win 1
            # If Window1 is None, splitter can only be unsplit
            if compn.control == self.win1:#self.GetWindow1(None):
                self.control.Unsplit(self.win1)
                if self.win2: self.win2.Show(True)
                self.win1 = self.win2 = None

                setterName = self.modeMethMap[self.control.GetSplitMode()]
                self.propRevertToDefault('Window1', setterName)
                self.designer.inspector.propertyUpdate('Window1')
                self.designer.inspector.propertyUpdate('Window2')
                return
            if compn.control == self.win2:#self.GetWindow2(None):
                self.SetWindow2(None)
                setterName = self.modeMethMap[self.control.GetSplitMode()]
                self.persistProp('Window2', setterName, None)
                self.designer.inspector.propertyUpdate('Window2')
                return

#---Split mode------------------------------------------------------------------
    def GetSplitMode(self, compn):
        return self.control.GetSplitMode()

    def SetSplitMode(self, value):
        ctrl = self.control
        ctrl.SetSplitMode(value)

        # Resplit to force splitter to update
        w1, w2 = ctrl.GetWindow1(), ctrl.GetWindow2()
        self.splitWindow(w1, w2)

#---Window1&2 methods---------------------------------------------------------
    def splitWindow(self, window1, window2):
        ctrl = self.control
        sm = ctrl.GetSplitMode()
        sp = ctrl.GetSashPosition()

        if ctrl.IsSplit():
            ctrl.Unsplit()

        if sm == wx.SPLIT_VERTICAL:
            splitMeth = ctrl.SplitVertically
        elif sm == wx.SPLIT_HORIZONTAL:
            splitMeth = ctrl.SplitHorizontally
        else:
            return

        if window1 and window2:
            splitMeth(window1, window2, sp)
        elif window1 or window2:
            if window1:
                ctrl.Initialize(window1)
            else:
                ctrl.Initialize(window2)

        if window1: window1.Show(True)
        if window2: window2.Show(True)

        self.designer.inspector.propertyUpdate('SashPosition')

    def getWindow(self, win, winGetter):
        if not win:
            w = winGetter()
            if w:
                wId = w.GetId()
                for cmpn, ctrl, prnt in self.designer.objects.values():
                    if ctrl.GetId() == wId:
                        return ctrl
            return None
        else:
            return win

    def GetWindow1(self, compn):
        self.win1 = self.getWindow(self.win1, self.control.GetWindow1)
        return self.win1

    def SetWindow1(self, value):
        # XXX check win1!=win2
        self.win1 = value
        w2 = self.GetWindow2(None)
        if value:
            self.splitWindow(value, w2)
        elif w2:
            self.win1 = self.win2 = None
            self.control.Unsplit()
            self.propRevertToDefault('Window1', self.modeMethMap[self.control.GetSplitMode()])
            self.designer.inspector.propertyUpdate('Window2')

    def GetWindow2(self, compn):
        self.win2 = self.getWindow(self.win2, self.control.GetWindow2)
        return self.win2

    def SetWindow2(self, value):
        self.win2 = value
        self.splitWindow(self.control.GetWindow1(), value)

EventCategories['ToolEvent'] = ('wx.EVT_TOOL', 'wx.EVT_TOOL_RCLICKED')
commandCategories.append('ToolEvent')
class ToolBarDTC(Constructors.WindowConstr, ContainerDTC):
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors.update({'Tools': CollectionPropEdit})
        self.subCompanions['Tools'] = ToolBarToolsCDTC
        self.windowStyles = ['wx.TB_FLAT', 'wx.TB_DOCKABLE', 'wx.TB_HORIZONTAL',
                             'wx.TB_VERTICAL', 'wx.TB_3DBUTTONS', 'wx.TB_TEXT',
                             'wx.TB_NOICONS', 'wx.TB_NODIVIDER', 'wx.TB_NOALIGN',
                            ] + self.windowStyles

    def properties(self):
        props = ContainerDTC.properties(self)
        props.update({'Tools': ('NoneRoute', None, None)})
        return props

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos': position,
                'size': size,
                'style': 'wx.TB_HORIZONTAL | wx.NO_BORDER',
                'name': `self.name`}

    def dependentProps(self):
        return ContainerDTC.dependentProps(self) + ['Tools']

    def defaultAction(self):
        self.designer.inspector.props.getNameValue('Tools').propEditor.edit(None)


def BlankToolBitmap(width, height):
    bmp = wx.EmptyBitmap(width, height)
    dc = wx.MemoryDC()
    dc.SelectObject(bmp)
    dc.SetBrush(wx.Brush(wx.RED, wx.BDIAGONAL_HATCH))
    dc.SetBackground(wx.Brush(wx.WHITE))
    dc.SetPen(wx.Pen(wx.WHITE, 0, wx.TRANSPARENT))
    dc.BeginDrawing()
    dc.DrawRectangle(0, 0, width, height)

    return bmp

class BlankToolControl(wx.StaticBitmap):
    def __init__(self, toolbar):
        width, height = toolbar.GetToolSize().Get()
        bmp = BlankToolBitmap(width, height)
        wx.StaticBitmap.__init__(self, toolbar, -1, bmp, style=wx.SIMPLE_BORDER)


class ToolBarToolsCDTC(CollectionIddDTC):
    propName = 'Tools'
    displayProp = 'shortHelp'
    indexProp = '(None)'
    insertionMethod = 'DoAddTool'
    deletionMethod = 'DeleteToolByPos'
    idProp = 'id'
    idPropNameFrom = 'tools'

    additionalMethods = {'AddSeparator': (_('Add separator'), '', '(None)'),
                         'AddControl': (_('Add control'), 'control', '(None)'),
                         'AddTool': (_('Old add tool'), 'shortHelpString', '(None)')
                        }

    def __init__(self, name, designer, parentCompanion, ctrl):
        CollectionIddDTC.__init__(self, name, designer, parentCompanion, ctrl)
        self.editors.update({'Bitmap': BitmapConstrPropEdit,
                             'PushedBitmap': BitmapConstrPropEdit,
                             'BitmapDisabled': BitmapConstrPropEdit,
                             'IsToggle': BoolConstrPropEdit,
                             'Label': StrConstrPropEdit,
                             'ShortHelpString': StrConstrPropEdit,
                             'LongHelpString': StrConstrPropEdit,
                             'ShortHelp': StrConstrPropEdit,
                             'LongHelp': StrConstrPropEdit,
                             'Kind': EnumConstrPropEdit,
                             'Control': WinEnumConstrPropEdit})
        self.names['Kind'] = ['wx.ITEM_NORMAL', 'wx.ITEM_CHECK', 'wx.ITEM_RADIO']

    def constructor(self):
        tcl = self.textConstrLst[self.index]
        if tcl.method == 'DoAddTool':
            return {'ItemId': 'id',
                    'Label': 'label',
                    'Bitmap': 'bitmap',
                    'BitmapDisabled': 'bmpDisabled',
                    'Kind': 'kind',
                    'ShortHelp': 'shortHelp',
                    'LongHelp': 'longHelp'}
        elif tcl.method == 'AddTool':
            return {'ItemId': 'id', 'Bitmap': 'bitmap',
                    'PushedBitmap': 'pushedBitmap',
                    'IsToggle': 'isToggle',
                    'ShortHelpString': 'shortHelpString',
                    'LongHelpString': 'longHelpString'}
        elif tcl.method == 'AddSeparator':
            return {}
        elif tcl.method == 'AddControl':
            return {'Control': 'control'}

    def properties(self):
        tcl = self.textConstrLst[self.index]
        if tcl.method in ('DoAddTool', 'AddTool'):
            return CollectionIddDTC.properties(self)
        elif tcl.method == 'AddSeparator':
            return {}
        elif tcl.method == 'AddControl':
            return {}

    def designTimeSource(self, wId, method=None):
        if method is None:
            method = self.insertionMethod

        newItemName, winId = self.newUnusedItemNames(wId)

        if method == 'DoAddTool':
            return {'id': winId,
                    'label': `''`,
                    'bitmap': 'wx.NullBitmap',
                    'bmpDisabled': 'wx.NullBitmap',
                    'kind': 'wx.ITEM_NORMAL',
                    'shortHelp': `newItemName`,
                    'longHelp': `''`}
        elif method == 'AddTool':
            return {'id': winId,
                    'bitmap': 'wx.NullBitmap',
                    'pushedBitmap': 'wx.NullBitmap',
                    'isToggle': 'False',
                    'shortHelpString': `newItemName`,
                    'longHelpString': `''`}
        elif method == 'AddSeparator':
            return {}
        elif method == 'AddControl':
            return {'control': 'None'}

    def finaliser(self):
        return ['', sourceconst.bodyIndent+'parent.Realize()']

    def appendItem(self, method=None):
        CollectionIddDTC.appendItem(self, method)
        self.control.Realize()

    def deleteItem(self, idx):
        CollectionIddDTC.deleteItem(self, idx)
        del self.textConstrLst[idx]

    def moveItem(self, idx, dir):
        newIdx = CollectionIddDTC.moveItem(self, idx, dir)
        if newIdx != idx:
            self.control.ClearTools()
            for crt in self.textConstrLst:
                self.applyDesignTimeDefaults(crt.params, crt.method)
        return newIdx

    def applyDesignTimeDefaults(self, params, method=None):
        if method is None:
            method = self.insertionMethod

        prms = copy.copy(params)
        control = None
        if 'control' in params:
            if params['control'] == 'None':
                control = BlankToolControl(self.control)
            else:
                control = self.designer.objects[Utils.ctrlNameFromSrcRef(params['control'])][1]
            del prms['control']

        bitmaps = {}
        for bmp in ('bitmap', 'bmpDisabled', 'pushedBitmap'):
            if bmp in params and params[bmp] == 'wx.NullBitmap':
                bitmaps[bmp] = BlankToolBitmap(*self.control.GetToolBitmapSize().Get())
                del prms[bmp]

        params = self.designTimeDefaults(prms)

        if method in ('AddSeparator', 'AddControl'):
            del params['id']

        if control:
            params['control'] = control

        for bmp in bitmaps:
            params[bmp] = bitmaps[bmp]

        getattr(self.control, method)(**params)

        self.control.Realize()

    def events(self):
        return ['ToolEvent']

    def defaultAction(self):
        insp = self.designer.inspector
        insp.pages.SetSelection(2)
        insp.events.doAddEvent('ToolEvent', 'wx.EVT_TOOL')

    def notification(self, compn, action):
        if action == 'delete':
            if compn != self:
                compnSrcRef = Utils.srcRefFromCtrlName(compn.name)
                for constr in self.textConstrLst:
                    if constr.params.has_key('control'):
                        if compnSrcRef == constr.params['control']:
                            constr.params['control'] = 'None'
                            idx = self.textConstrLst.index(constr)
                            self.control.DeleteToolByPos(idx)
                            del self.textConstrLst[idx]
                            return

    def writeCollectionItems(self, output, stripFrmId=''):
        CollectionIddDTC.writeCollectionItems(self, output, stripFrmId)
        warn = 0
        for constr in self.textConstrLst:
            if constr.params.has_key('control') and constr.params['control'] == 'None':
                wx.LogWarning(_("Invalid None control for toolbar %s's AddControl")%(
                      self.parentCompanion.name))
                warn = 1
        if warn:
            wx.LogWarning(_('Control may not be None or the generated source will '
                            'be invalid outside the Designer.'))

    def GetOtherWin(self):
        return self.textConstrLst[self.index].params['control']

    def SetOtherWin(self, value):
        self.textConstrLst[self.index].params['control'] = value

class ToolBarSimpleDTC(ToolBarDTC):
    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos': position,
                'size': self.getDefCtrlSize(),
                'style': 'wx.TB_HORIZONTAL | wx.NO_BORDER',
                'name': `self.name`}

class StatusBarDTC(ContainerDTC):
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.editors['Fields'] = CollectionPropEdit
        self.subCompanions['Fields'] = StatusBarFieldsCDTC
        self.windowStyles = ['wx.ST_SIZEGRIP'] + self.windowStyles

    def constructor(self):
        return {'Style': 'style', 'Name': 'name'}

    def properties(self):
        props = ContainerDTC.properties(self)
        props.update({'Fields': ('NoneRoute', None, None)})
        return props

    def designTimeSource(self, position='wx.DefaultPosition', size='wx.DefaultSize'):
        return {'style': '0',
                'name': `self.name`}

    def hideDesignTime(self):
        return ContainerDTC.hideDesignTime(self) + ['Position', 'Size', 'ClientSize']

class StatusBarFieldsCDTC(CollectionDTC):
    propName = 'Fields'
    displayProp = 'text'
    indexProp = 'number'
    insertionMethod = 'SetStatusText'
    deletionMethod = '(None)'

    def __init__(self, name, designer, parentCompanion, ctrl):
        CollectionDTC.__init__(self, name, designer, parentCompanion, ctrl)
        self.editors = {'Number' : IntConstrPropEdit,
                        'Text': StrConstrPropEdit,
                        'Width': SBFWidthConstrPropEdit}
        self.widths = []

    def constructor(self):
        return {'Number': 'number', 'Text': 'text', 'Width': 'width'}

    def properties(self):
        props = CollectionDTC.properties(self)
        props.update({'Number':  ('NoneRoute', None, None),
                      'Text':  ('CompnRoute', self.GetText, self.SetText),
                      'Width': ('NoneRoute', None, None)})
        return props

    def designTimeSource(self, wId, method=None):
        return {'number': `wId`,
                'text': `'%s%d'%(self.propName, wId)`}

    def initialiser(self):
        return [sourceconst.bodyIndent+'parent.SetFieldsCount(%d)'%(
                self.getCount())]+CollectionDTC.initialiser(self)

    def finaliser(self):
        return ['', sourceconst.bodyIndent+'parent.SetStatusWidths(%s)'%`self.widths`]

    def initCollection(self):
        if self.widths:
            self.control.SetStatusWidths(self.widths)

    def appendItem(self, method=None):
        self.widths.append(-1)
        self.control.SetFieldsCount(len(self.widths))
        CollectionDTC.appendItem(self, method)

    def deleteItem(self, index):
        CollectionDTC.deleteItem(self, index)
        for idx in range(index, len(self.widths)):
            self.control.SetStatusText(self.control.GetStatusText(idx+1), idx)
        del self.widths[index]
        self.control.SetStatusWidths(self.widths)
        self.control.SetFieldsCount(len(self.widths))

    def moveItem(self, idx, dir):
        newIdx = CollectionDTC.moveItem(self, idx, dir)
        if newIdx != idx:
            w = self.widths[idx]
            del self.widths[idx]
            self.widths.insert(newIdx, w)
            self.control.SetStatusWidths(self.widths)
            oldText = self.control.GetStatusText(idx)
            newText = self.control.GetStatusText(newIdx)
            self.control.SetStatusText(newText, idx)
            self.control.SetStatusText(oldText, newIdx)
        return newIdx

    def setConstrs(self, constrLst, inits, fins):
        CollectionDTC.setConstrs(self, constrLst, inits, fins)
        if len(fins):
            self.widths = self.eval(fins[0]\
              [fins[0].find('(')+1 : fins[0].rfind(')')])
            self.control.SetFieldsCount(len(self.widths))

    def GetWidth(self):
        return `self.widths[self.index]`

    def SetWidth(self, value):
        self.widths[self.index] = int(value)
        self.control.SetStatusWidths(self.widths)

    def GetText(self):
        return `self.control.GetStatusText(self.index)`

    def SetText(self, value):
        self.control.SetStatusText(value, self.index)

# Designer support incomplete for this control
# Children created in this control need to reference their parent parameter
# as e.g. parent=self.collapsiblePane1.GetPane()
EventCategories['CollapsiblePaneEvent'] = ('wx.EVT_COLLAPSIBLEPANE_CHANGED', )
commandCategories.append('CollapsiblePaneEvent')
class CollapsiblePaneDTC(Constructors.LabeledInputConstr, ContainerDTC):
    suppressWindowId = True
    def __init__(self, name, designer, parent, ctrlClass):
        ContainerDTC.__init__(self, name, designer, parent, ctrlClass)
        self.windowStyles = ['wx.CP_DEFAULT_STYLE', 'wx.CP_NO_TLW_RESIZE'] +self.windowStyles

    def designTimeSource(self, position = 'wx.DefaultPosition', size = 'wx.DefaultSize'):
        return {'pos':   position,
                'size':  self.getDefCtrlSize(),
                'style': 'wx.CP_DEFAULT_STYLE',
                'name':  `self.name`,
                'label': `self.name`}

    def events(self):
        return ContainerDTC.events(self) + ['CollapsiblePaneEvent']

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

import Plugins

Plugins.registerPalettePage('ContainersLayout', _('Containers/Layout'))

Plugins.registerComponents('ContainersLayout',
      (wx.Panel, 'wx.Panel', PanelDTC),
      (wx.ScrolledWindow, 'wx.ScrolledWindow', ScrolledWindowDTC),
      (wx.SplitterWindow, 'wx.SplitterWindow', SplitterWindowDTC),
      (wx.SashWindow, 'wx.SashWindow', SashWindowDTC),
      (wx.SashLayoutWindow, 'wx.SashLayoutWindow', SashLayoutWindowDTC),
      (wx.ToolBar, 'wx.ToolBar', ToolBarDTC),
      (wx.StatusBar, 'wx.StatusBar', StatusBarDTC),
      (wx.Window, 'wx.Window', ContainerDTC),
      (wx.Notebook, 'wx.Notebook', NotebookDTC),
      (wx.Listbook, 'wx.Listbook', ListbookDTC),
      (wx.Choicebook, 'wx.Choicebook', ChoicebookDTC),
    )

try:
    Plugins.registerComponents('ContainersLayout',
      (wx.Treebook, 'wx.Treebook', TreebookDTC),
      (wx.Toolbook, 'wx.Toolbook', ToolbookDTC),
#      (wx.CollapsiblePane, 'wx.CollapsiblePane', CollapsiblePaneDTC),
    )  
except AttributeError:
    pass
    
    
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.