Changeset 3053

Show
Ignore:
Timestamp:
04/11/2007 01:16:44 PM (2 years ago)
Author:
nate
Message:

This code mostly completes the refactoring of dEditBox. However, ran into a problem with a wierd error thrown by wx when the GetValue? is called by a property setter while in the initProperties function. See my email for a better description.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/NateBranch/dabo/ui/uiwx/dEditBox.py

    r3021 r3053  
    44    dabo.ui.loadUI("wx") 
    55 
    6 import dDataControlMixin as dc
     6import dTextBoxMixin as tb
    77import dabo.dEvents as dEvents 
    88from dabo.dLocalize import _ 
     
    1212# The EditBox is just a TextBox with some additional styles. 
    1313 
    14 class dEditBox(dcm.dDataControlMixin, wx.TextCtrl): 
     14class dEditBox(tbm.dTextBoxMixinBase, wx.TextCtrl): 
    1515    """Creates an editbox, which allows editing of string data of unlimited size. 
    1616 
     
    2020    def __init__(self, parent, properties=None, attProperties=None, *args, **kwargs): 
    2121        self._baseClass = dEditBox 
    22         self._forceCase = None 
    23         self._inForceCase = False 
    24         self._flushOnLostFocus = True  ## see dabo.ui.dDataControlMixinBase::flushValue() 
    25  
     22         
    2623        preClass = wx.PreTextCtrl 
    2724        kwargs["style"] = wx.TE_MULTILINE | wx.TE_WORDWRAP 
    28         dcm.dDataControlMixin.__init__(self, preClass, parent, properties, attProperties, *args, **kwargs) 
    29  
    30  
    31     def _initEvents(self): 
    32         super(dEditBox, self)._initEvents() 
    33         self.Bind(wx.EVT_TEXT, self._onWxHit) 
    34          
    35  
    36     def selectAll(self): 
    37         """Each subclass must define their own selectAll method. This will  
    38         be called if SelectOnEntry is True when the control gets focus. 
    39         """ 
    40         self.SetSelection(-1, -1) 
    41          
    42          
    43     def getBlankValue(self): 
    44         return "" 
     25        tbm.dTextBoxMixinBase.__init__(self, preClass, parent, properties, attProperties, *args, **kwargs) 
    4526     
    4627     
     
    5132        self.Refresh() 
    5233         
    53  
     34     
    5435    def scrollToEnd(self): 
    5536        """Moves the insertion point to the end of the text""" 
     
    5940         
    6041 
    61     def __onKeyChar(self, evt): 
    62         """This handles KeyChar events when ForceCase is set to a non-empty value.""" 
    63         keyChar = evt.keyChar 
    64         if keyChar is not None and (keyChar.isalnum()  
    65                 or keyChar in """,./<>?;':"[]\\{}|`~!@#$%%^&*()-_=+"""): 
    66             dabo.ui.callAfter(self.__forceCase) 
    67          
    68      
    69     def __forceCase(self): 
    70         """If the ForceCase property is set, casts the current value of the control 
    71         to the specified case. 
    72         """ 
    73         if not isinstance(self.Value, basestring): 
    74             # Don't bother if it isn't a string type 
    75             return 
    76         case = self.ForceCase 
    77         if not case: 
    78             return 
    79         insPos = self.InsertionPosition 
    80         selLen = self.SelectionLength 
    81         changed = False 
    82         self._inForceCase = True 
    83         if case == "upper": 
    84             self.Value = self.Value.upper() 
    85             changed = True 
    86         elif case == "lower": 
    87             self.Value = self.Value.lower() 
    88             changed = True 
    89         elif case == "title": 
    90             self.Value = self.Value.title() 
    91             changed = True 
    92         if changed: 
    93             #self.SelectionStart = selStart 
    94             self.InsertionPosition = insPos 
    95             self.SelectionLength = selLen 
    96             self.refresh() 
    97         self._inForceCase = False 
    98          
    99  
    100     # property get/set functions 
    101     def _getAlignment(self): 
    102         if self._hasWindowStyleFlag(wx.TE_RIGHT): 
    103             return "Right" 
    104         elif self._hasWindowStyleFlag(wx.TE_CENTRE): 
    105             return "Center" 
    106         else: 
    107             return "Left" 
    108  
    109     def _setAlignment(self, val): 
    110         # Note: alignment doesn't seem to work, at least on GTK2 
    111         self._delWindowStyleFlag(wx.TE_LEFT) 
    112         self._delWindowStyleFlag(wx.TE_CENTRE) 
    113         self._delWindowStyleFlag(wx.TE_RIGHT) 
    114         val = val[0].lower() 
    115         if val == "l": 
    116             self._addWindowStyleFlag(wx.TE_LEFT) 
    117         elif val == "c": 
    118             self._addWindowStyleFlag(wx.TE_CENTRE) 
    119         elif val == "r": 
    120             self._addWindowStyleFlag(wx.TE_RIGHT) 
    121         else: 
    122             raise ValueError, _("The only possible values are 'Left', 'Center', and 'Right'") 
    123  
    124  
    125     def _getForceCase(self): 
    126         return self._forceCase 
    127  
    128     def _setForceCase(self, val): 
    129         if self._constructed(): 
    130             valKey = val[0].upper() 
    131             self._forceCase = {"U": "upper", "L": "lower", "T": "title"}.get(valKey) 
    132             self.__forceCase() 
    133             self.unbindEvent(dEvents.KeyChar, self.__onKeyChar) 
    134             if self._forceCase: 
    135                 self.bindEvent(dEvents.KeyChar, self.__onKeyChar) 
    136         else: 
    137             self._properties["ForceCase"] = val 
    138  
    139  
    140     def _getInsertionPosition(self): 
    141         return self.GetInsertionPoint() 
    142  
    143     def _setInsertionPosition(self, val): 
    144         self.SetInsertionPoint(val) 
    145  
    146  
    147     def _getReadOnly(self): 
    148         return not self.IsEditable() 
    149  
    150     def _setReadOnly(self, value): 
    151         if self._constructed(): 
    152             self.SetEditable(not value) 
    153         else: 
    154             self._properties["ReadOnly"] = value 
    155      
    156  
    157     def _getSelectedText(self): 
    158         return self.GetStringSelection() 
    159  
    160  
    161     def _getSelectionEnd(self): 
    162         return self.GetSelection()[1] 
    163  
    164     def _setSelectionEnd(self, val): 
    165         start, end = self.GetSelection() 
    166         self.SetSelection(start, val) 
    167         self.refresh() 
    168  
    169  
    170     def _getSelectionLength(self): 
    171         start, end = self.GetSelection() 
    172         return end - start 
    173  
    174     def _setSelectionLength(self, val): 
    175         start = self.GetSelection()[0] 
    176         self.SetSelection(start, start + val) 
    177         self.refresh() 
    178  
    179  
    180     def _getSelectionStart(self): 
    181         return self.GetSelection()[0] 
    182  
    183     def _setSelectionStart(self, val): 
    184         start, end = self.GetSelection() 
    185         self.SetSelection(val, end) 
    186         self.refresh() 
    187  
    188  
    189     def _getSelectOnEntry(self): 
    190         try: 
    191             return self._SelectOnEntry 
    192         except AttributeError: 
    193             return False 
    194     def _setSelectOnEntry(self, value): 
    195         self._SelectOnEntry = bool(value) 
    196          
    197  
    198     def _getValue(self): 
    199         try: 
    200             _value = self._value 
    201         except AttributeError: 
    202             _value = self._value = unicode("") 
    203          
    204         # Get the string value as reported by wx, which is the up-to-date  
    205         # string value of the control: 
    206         strVal = self.GetValue() 
    207  
    208         if _value is None: 
    209             if strVal == self.Application.NoneDisplay: 
    210                 # Keep the value None 
    211                 return None 
    212         return strVal 
    213      
    214     def _setValue(self, val): 
    215         if self._constructed(): 
    216             if self._inForceCase: 
    217                 # Value is changing internally. Don't update the oldval 
    218                 # setting or change the type; just set the value. 
    219                 self.SetValue(val) 
    220                 return 
    221             else: 
    222                 dabo.ui.callAfter(self.__forceCase) 
    223          
    224             if val is None: 
    225                 strVal = self.Application.NoneDisplay 
    226             else: 
    227                 strVal = val 
    228             _oldVal = self._oldVal = self.Value 
    229                  
    230             # save the actual value for return by _getValue: 
    231             self._value = val 
    232  
    233             # Update the display no matter what: 
    234             self.SetValue(strVal) 
    235          
    236             if type(_oldVal) != type(val) or _oldVal != val: 
    237                 self._afterValueChanged() 
    238         else: 
    239             self._properties["Value"] = val 
    240  
    241          
    242     # property definitions follow: 
    243     Alignment = property(_getAlignment, _setAlignment, None, 
    244             _("""Specifies the alignment of the text. (str) 
    245  
    246             Left (default) 
    247             Center 
    248             Right""")) 
    249  
    250     ForceCase = property(_getForceCase, _setForceCase, None, 
    251             _("""Determines if we change the case of entered text. Possible values are: 
    252                 None, "" (empty string): No changes made (default) 
    253                 "Upper": FORCE TO UPPER CASE 
    254                 "Lower": force to lower case 
    255                 "Title": Force To Title Case 
    256             These can be abbreviated to "u", "l" or "t"  (str)""")) 
    257      
    258     InsertionPosition = property(_getInsertionPosition, _setInsertionPosition, None, 
    259             _("Position of the insertion point within the control  (int)")) 
    260      
    261     ReadOnly = property(_getReadOnly, _setReadOnly, None,  
    262             _("Specifies whether or not the text can be edited. (bool)")) 
    263      
    264     SelectedText = property(_getSelectedText, None, None, 
    265             _("Currently selected text. Returns the empty string if nothing is selected  (str)"))    
    266      
    267     SelectionEnd = property(_getSelectionEnd, _setSelectionEnd, None, 
    268             _("""Position of the end of the selected text. If no text is 
    269             selected, returns the Position of the insertion cursor.  (int)""")) 
    270      
    271     SelectionLength = property(_getSelectionLength, _setSelectionLength, None, 
    272             _("Length of the selected text, or 0 if nothing is selected.  (int)")) 
    273      
    274     SelectionStart = property(_getSelectionStart, _setSelectionStart, None, 
    275             _("""Position of the beginning of the selected text. If no text is 
    276             selected, returns the Position of the insertion cursor.  (int)""")) 
    277      
    278     SelectOnEntry = property(_getSelectOnEntry, _setSelectOnEntry, None,  
    279             _("Specifies whether all text gets selected upon receiving focus. (bool)")) 
    280  
    281     Value = property(_getValue, _setValue, None, 
    282             _("Specifies the current state of the control (the value of the field). (varies)")) 
    283  
    284  
    285     DynamicAlignment = makeDynamicProperty(Alignment) 
    286     DynamicInsertionPosition = makeDynamicProperty(InsertionPosition) 
    287     DynamicReadOnly = makeDynamicProperty(ReadOnly) 
    288     DynamicSelectionEnd = makeDynamicProperty(SelectionEnd) 
    289     DynamicSelectionLength = makeDynamicProperty(SelectionLength) 
    290     DynamicSelectionStart = makeDynamicProperty(SelectionStart) 
    291     DynamicSelectOnEntry = makeDynamicProperty(SelectOnEntry) 
    292     DynamicValue = makeDynamicProperty(Value) 
    29342 
    29443 
  • branches/NateBranch/dabo/ui/uiwx/dTextBoxMixin.py

    r3047 r3053  
    1919from dabo.ui import makeDynamicProperty 
    2020 
    21 class dTextBoxMixin(dcm.dDataControlMixin): 
     21class dTextBoxMixinBase(dcm.dDataControlMixin): 
    2222    def __init__(self, preClass, parent, properties=None, attProperties=None, *args, **kwargs): 
    23         self._dregex = {} 
    24         self._lastDataType = unicode 
    2523        self._forceCase = None 
    2624        self._inForceCase = False 
     
    3028         
    3129        dcm.dDataControlMixin.__init__(self, preClass, parent, properties, attProperties, *args, **kwargs) 
    32          
    33         # Keep passwords, etc., from being written to disk 
    34         if self.PasswordEntry: 
    35             self.IsSecret = True 
    3630     
    3731     
    3832    def _initEvents(self): 
    39         super(dTextBoxMixin, self)._initEvents() 
     33        super(dTextBoxMixinBase, self)._initEvents() 
    4034        self.Bind(wx.EVT_TEXT, self._onWxHit) 
    41         
    42         
     35     
     36     
    4337    def flushValue(self): 
    4438        # Call the wx SetValue() directly to reset the string value displayed to the user. 
     
    5246        # Now that the dabo Value is set properly, the default behavior that flushes  
    5347        # the value to the bizobj can be called: 
    54         super(dTextBoxMixin, self).flushValue() 
     48        super(dTextBoxMixinBase, self).flushValue() 
     49     
     50    def getStringValue(self, val): 
     51        """Hook function if you want to implement dataTypes other than str""" 
     52        return val 
    5553     
    5654     
     
    6462    def getBlankValue(self): 
    6563        return "" 
     64     
     65     
     66    def __onKeyChar(self, evt): 
     67        """This handles KeyChar events when ForceCase is set to a non-empty value.""" 
     68        keyChar = evt.keyChar 
     69        if keyChar is not None and (keyChar.isalnum()  
     70                or keyChar in """,./<>?;':"[]\\{}|`~!@#$%%^&*()-_=+"""): 
     71            dabo.ui.callAfter(self._checkForceCase) 
     72            dabo.ui.callAfter(self._checkTextLength) 
     73     
     74    def _checkTextLength(self): 
     75        """If the TextLength property is set, checks the current value of the control 
     76        and truncates it if too long""" 
     77        if not isinstance(self.Value, basestring): 
     78            #Don't bother if it isn't a string type 
     79            return 
     80        length = self.TextLength 
     81        if not length: 
     82            return 
     83         
     84        insPos = self.InsertionPosition 
     85         
     86        self._inTextLength = True 
     87        if len(self.Value) > length: 
     88            self.Value = self.Value[:length] 
     89            if insPos > length: 
     90                self.InsertionPosition = length 
     91            else: 
     92                self.InsertionPosition = insPos 
     93            self.refresh() 
     94        self._inTextLength = False 
     95     
     96    def _checkForceCase(self): 
     97        """If the ForceCase property is set, casts the current value of the control 
     98        to the specified case. 
     99        """ 
     100        if not isinstance(self.Value, basestring): 
     101            # Don't bother if it isn't a string type 
     102            return 
     103        case = self.ForceCase 
     104        if not case: 
     105            return 
     106        insPos = self.InsertionPosition 
     107        selLen = self.SelectionLength 
     108        changed = False 
     109        self._inForceCase = True 
     110        if case == "upper": 
     111            self.Value = self.Value.upper() 
     112            changed = True 
     113        elif case == "lower": 
     114            self.Value = self.Value.lower() 
     115            changed = True 
     116        elif case == "title": 
     117            self.Value = self.Value.title() 
     118            changed = True 
     119        if changed: 
     120            #self.SelectionStart = selStart 
     121            self.InsertionPosition = insPos 
     122            self.SelectionLength = selLen 
     123            self.refresh() 
     124        self._inForceCase = False 
     125     
     126     
     127    # property get/set functions 
     128    def _getAlignment(self): 
     129        if self._hasWindowStyleFlag(wx.TE_RIGHT): 
     130            return "Right" 
     131        elif self._hasWindowStyleFlag(wx.TE_CENTRE): 
     132            return "Center" 
     133        else: 
     134            return "Left" 
     135 
     136    def _setAlignment(self, val): 
     137        # Note: alignment doesn't seem to work, at least on GTK2 
     138        self._delWindowStyleFlag(wx.TE_LEFT) 
     139        self._delWindowStyleFlag(wx.TE_CENTRE) 
     140        self._delWindowStyleFlag(wx.TE_RIGHT) 
     141        val = val[0].lower() 
     142        if val == "l": 
     143            self._addWindowStyleFlag(wx.TE_LEFT) 
     144        elif val == "c": 
     145            self._addWindowStyleFlag(wx.TE_CENTRE) 
     146        elif val == "r": 
     147            self._addWindowStyleFlag(wx.TE_RIGHT) 
     148        else: 
     149            raise ValueError, "The only possible values are 'Left', 'Center', and 'Right'" 
     150     
     151     
     152    def _getForceCase(self): 
     153        return self._forceCase 
     154     
     155    def _setForceCase(self, val): 
     156        if self._constructed(): 
     157            if val is None: 
     158                valKey = None 
     159            else: 
     160                valKey = val[0].upper() 
     161            self._forceCase = {"U": "upper", "L": "lower", "T": "title", None: None, 
     162                    "None": None}.get(valKey) 
     163            self._checkForceCase() 
     164            self.unbindEvent(dEvents.KeyChar, self.__onKeyChar) 
     165            if self._forceCase or self._textLength: 
     166                self.bindEvent(dEvents.KeyChar, self.__onKeyChar) 
     167        else: 
     168            self._properties["ForceCase"] = val 
     169     
     170     
     171    def _getInsertionPosition(self): 
     172        return self.GetInsertionPoint() 
     173     
     174    def _setInsertionPosition(self, val): 
     175        self.SetInsertionPoint(val) 
     176     
     177     
     178    def _getReadOnly(self): 
     179        return not self.IsEditable() 
     180         
     181    def _setReadOnly(self, val): 
     182        if self._constructed(): 
     183            self.SetEditable(not bool(val)) 
     184        else: 
     185            self._properties["ReadOnly"] = val 
     186     
     187     
     188    def _getSelectedText(self): 
     189        return self.GetStringSelection() 
     190     
     191     
     192    def _getSelectionEnd(self): 
     193        return self.GetSelection()[1] 
     194     
     195    def _setSelectionEnd(self, val): 
     196        start, end = self.GetSelection() 
     197        self.SetSelection(start, val) 
     198        self.refresh() 
     199     
     200     
     201    def _getSelectionLength(self): 
     202        start, end = self.GetSelection() 
     203        return end - start 
     204     
     205    def _setSelectionLength(self, val): 
     206        start = self.GetSelection()[0] 
     207        self.SetSelection(start, start + val) 
     208        self.refresh() 
     209     
     210     
     211    def _getSelectionStart(self): 
     212        return self.GetSelection()[0] 
     213     
     214    def _setSelectionStart(self, val): 
     215        start, end = self.GetSelection() 
     216        self.SetSelection(val, end) 
     217        self.refresh() 
     218     
     219     
     220    def _getSelectOnEntry(self): 
     221        try: 
     222            return self._SelectOnEntry 
     223        except AttributeError: 
     224            return False 
     225             
     226    def _setSelectOnEntry(self, val): 
     227        self._SelectOnEntry = bool(val) 
     228     
     229     
     230    def _getTextLength(self): 
     231        return self._textLength 
     232     
     233    def _setTextLength(self, val): 
     234        if val == None: 
     235            self._textLength = None 
     236        else: 
     237            val = int(val) 
     238            if val < 1: 
     239                raise ValueError, 'TextLength must be a positve Integer' 
     240            self._textLength = val 
     241        self._checkTextLength() 
     242         
     243        self.unbindEvent(dEvents.KeyChar, self.__onKeyChar) 
     244        if self._forceCase or self._textLength: 
     245            self.bindEvent(dEvents.KeyChar, self.__onKeyChar) 
     246     
     247     
     248    def _getValue(self): 
     249        try: 
     250            _value = self._value 
     251        except AttributeError: 
     252            _value = self._value = unicode("") 
     253         
     254        # Get the string value as reported by wx, which is the up-to-date  
     255        # string value of the control: 
     256        strVal = self.GetValue() 
     257 
     258        if _value is None: 
     259            if strVal == self.Application.NoneDisplay: 
     260                # Keep the value None 
     261                return None 
     262        return strVal 
     263     
     264    def _setValue(self, val): 
     265        if self._constructed(): 
     266            if self._inForceCase: 
     267                # Value is changing internally. Don't update the oldval 
     268                # setting or change the type; just set the value. 
     269                self.SetValue(val) 
     270                return 
     271            else: 
     272                dabo.ui.callAfter(self._checkForceCase) 
     273         
     274            if val is None: 
     275                strVal = self.Application.NoneDisplay 
     276            else: 
     277                strVal = val 
     278            _oldVal = self._oldVal = self.Value 
     279                 
     280            # save the actual value for return by _getValue: 
     281            self._value = val 
     282 
     283            # Update the display no matter what: 
     284            self.SetValue(strVal) 
     285         
     286            if type(_oldVal) != type(val) or _oldVal != val: 
     287                self._afterValueChanged() 
     288        else: 
     289            self._properties["Value"] = val 
     290         
     291        self._checkTextLength() 
     292     
     293     
     294    #Property Definitions 
     295    Alignment = property(_getAlignment, _setAlignment, None, 
     296            _("""Specifies the alignment of the text. (str) 
     297               Left (default) 
     298               Center 
     299               Right""")) 
     300     
     301    ForceCase = property(_getForceCase, _setForceCase, None, 
     302            _("""Determines if we change the case of entered text. Possible values are: 
     303                None, "" (empty string): No changes made (default) 
     304                "Upper": FORCE TO UPPER CASE 
     305                "Lower": force to lower case 
     306                "Title": Force To Title Case 
     307            These can be abbreviated to "u", "l" or "t"  (str)""")) 
     308     
     309    InsertionPosition = property(_getInsertionPosition, _setInsertionPosition, None, 
     310            _("Position of the insertion point within the control  (int)")) 
     311     
     312    ReadOnly = property(_getReadOnly, _setReadOnly, None,  
     313            _("Specifies whether or not the text can be edited. (bool)")) 
     314     
     315    SelectedText = property(_getSelectedText, None, None, 
     316            _("Currently selected text. Returns the empty string if nothing is selected  (str)"))    
     317     
     318    SelectionEnd = property(_getSelectionEnd, _setSelectionEnd, None, 
     319            _("""Position of the end of the selected text. If no text is 
     320            selected, returns the Position of the insertion cursor.  (int)""")) 
     321     
     322    SelectionLength = property(_getSelectionLength, _setSelectionLength, None, 
     323            _("Length of the selected text, or 0 if nothing is selected.  (int)")) 
     324     
     325    SelectionStart = property(_getSelectionStart, _setSelectionStart, None, 
     326            _("""Position of the beginning of the selected text. If no text is 
     327            selected, returns the Position of the insertion cursor.  (int)""")) 
     328     
     329    SelectOnEntry = property(_getSelectOnEntry, _setSelectOnEntry, None,  
     330            _("Specifies whether all text gets selected upon receiving focus. (bool)")) 
     331     
     332    TextLength = property(_getTextLength, _setTextLength, None, 
     333            _("""The maximum length the entered text can be. (int)""")) 
     334     
     335    Value = property(_getValue, _setValue, None, 
     336            _("Specifies the current state of the control (the value of the field). (string)")) 
     337     
     338     
     339    # Dynamic property declarations 
     340    DynamicAlignment = makeDynamicProperty(Alignment) 
     341    DynamicInsertionPosition = makeDynamicProperty(InsertionPosition) 
     342    DynamicReadOnly = makeDynamicProperty(ReadOnly) 
     343    DynamicSelectionEnd = makeDynamicProperty(SelectionEnd) 
     344    DynamicSelectionLength = makeDynamicProperty(SelectionLength) 
     345    DynamicSelectionStart = makeDynamicProperty(SelectionStart) 
     346    DynamicSelectOnEntry = makeDynamicProperty(SelectOnEntry) 
     347    DynamicValue = makeDynamicProperty(Value) 
     348 
     349 
     350 
     351class dTextBoxMixin(dTextBoxMixinBase): 
     352    def __init__(self, preClass, parent, properties=None, attProperties=None, *args, **kwargs): 
     353        self._dregex = {} 
     354        self._lastDataType = unicode 
     355         
     356        dTextBoxMixinBase.__init__(self, preClass, parent, properties, attProperties, *args, **kwargs) 
     357         
     358        # Keep passwords, etc., from being written to disk 
     359        if self.PasswordEntry: 
     360            self.IsSecret = True 
    66361     
    67362     
     
    200495     
    201496     
    202     def __onKeyChar(self, evt): 
    203         """This handles KeyChar events when ForceCase is set to a non-empty value.""" 
    204         keyChar = evt.keyChar 
    205         if keyChar is not None and (keyChar.isalnum()  
    206                 or keyChar in """,./<>?;':"[]\\{}|`~!@#$%%^&*()-_=+"""): 
    207             dabo.ui.callAfter(self.__forceCase) 
    208             dabo.ui.callAfter(self.__textLength) 
    209      
    210     def __textLength(self): 
    211         """If the TextLength property is set, checks the current value of the control 
    212         and truncates it if too long""" 
    213         if not isinstance(self.Value, basestring): 
    214             #Don't bother if it isn't a string type 
    215             return 
    216         length = self.TextLength 
    217         if not length: 
    218             return 
    219          
    220         insPos = self.InsertionPosition 
    221          
    222         self._inTextLength = True 
    223         if len(self.Value) > length: 
    224             self.Value = self.Value[:length] 
    225             if insPos > length: 
    226                 self.InsertionPosition = length 
    227             else: 
    228                 self.InsertionPosition = insPos 
    229             self.refresh() 
    230         self._inTextLength = False 
    231      
    232     def __forceCase(self): 
    233         """If the ForceCase property is set, casts the current value of the control 
    234         to the specified case. 
    235         """ 
    236         if not isinstance(self.Value, basestring): 
    237             # Don't bother if it isn't a string type 
    238             return 
    239         case = self.ForceCase 
    240         if not case: 
    241             return 
    242         insPos = self.InsertionPosition 
    243         selLen = self.SelectionLength 
    244         changed = False 
    245         self._inForceCase = True 
    246         if case == "upper": 
    247             self.Value = self.Value.upper() 
    248             changed = True 
    249         elif case == "lower": 
    250             self.Value = self.Value.lower() 
    251             changed = True 
    252         elif case == "title": 
    253             self.Value = self.Value.title() 
    254             changed = True 
    255         if changed: 
    256             #self.SelectionStart = selStart 
    257             self.InsertionPosition = insPos 
    258             self.SelectionLength = selLen 
    259             self.refresh() 
    260         self._inForceCase = False 
    261  
    262  
    263497    # property get/set functions 
    264     def _getAlignment(self): 
    265         if self._hasWindowStyleFlag(wx.TE_RIGHT): 
    266             return "Right" 
    267         elif self._hasWindowStyleFlag(wx.TE_CENTRE): 
    268             return "Center" 
    269         else: 
    270             return "Left" 
    271  
    272     def _setAlignment(self, val): 
    273         # Note: alignment doesn't seem to work, at least on GTK2 
    274         self._delWindowStyleFlag(wx.TE_LEFT) 
    275         self._delWindowStyleFlag(wx.TE_CENTRE) 
    276         self._delWindowStyleFlag(wx.TE_RIGHT) 
    277         val = val[0].lower() 
    278         if val == "l": 
    279             self._addWindowStyleFlag(wx.TE_LEFT) 
    280         elif val == "c": 
    281             self._addWindowStyleFlag(wx.TE_CENTRE) 
    282         elif val == "r": 
    283             self._addWindowStyleFlag(wx.TE_RIGHT) 
    284         else: 
    285             raise ValueError, "The only possible values are 'Left', 'Center', and 'Right'" 
    286      
    287      
    288     def _getForceCase(self): 
    289         return self._forceCase 
    290      
    291     def _setForceCase(self, val): 
    292         if self._constructed(): 
    293             if val is None: 
    294                 valKey = None 
    295             else: 
    296                 valKey = val[0].upper() 
    297             self._forceCase = {"U": "upper", "L": "lower", "T": "title", None: None, 
    298                     "None": None}.get(valKey) 
    299             self.__forceCase() 
    300             self.unbindEvent(dEvents.KeyChar, self.__onKeyChar) 
    301             if self._forceCase or self._textLength: 
    302                 self.bindEvent(dEvents.KeyChar, self.__onKeyChar) 
    303         else: 
    304             self._properties["ForceCase"] = val 
    305      
    306      
    307     def _getInsertionPosition(self): 
    308         return self.GetInsertionPoint() 
    309      
    310     def _setInsertionPosition(self, val): 
    311         self.SetInsertionPoint(val) 
    312      
    313      
    314498    def _getPasswordEntry(self): 
    315499        return self._hasWindowStyleFlag(wx.TE_PASSWORD) 
     
    320504            self._addWindowStyleFlag(wx.TE_PASSWORD) 
    321505            self.IsSecret = True 
    322      
    323      
    324     def _getReadOnly(self): 
    325         return not self.IsEditable() 
    326          
    327     def _setReadOnly(self, val): 
    328         if self._constructed(): 
    329             self.SetEditable(not bool(val)) 
    330         else: 
    331             self._properties["ReadOnly"] = val 
    332      
    333      
    334     def _getSelectedText(self): 
    335         return self.GetStringSelection() 
    336      
    337      
    338     def _getSelectionEnd(self): 
    339         return self.GetSelection()[1] 
    340      
    341     def _setSelectionEnd(self, val): 
    342         start, end = self.GetSelection() 
    343         self.SetSelection(start, val) 
    344         self.refresh() 
    345      
    346      
    347     def _getSelectionLength(self): 
    348         start, end = self.GetSelection() 
    349         return end - start 
    350      
    351     def _setSelectionLength(self, val): 
    352         start = self.GetSelection()[0] 
    353         self.SetSelection(start, start + val) 
    354         self.refresh() 
    355      
    356      
    357     def _getSelectionStart(self): 
    358         return self.GetSelection()[0] 
    359      
    360     def _setSelectionStart(self, val): 
    361         start, end = self.GetSelection() 
    362         self.SetSelection(val, end) 
    363         self.refresh() 
    364      
    365      
    366     def _getSelectOnEntry(self): 
    367         try: 
    368             return self._SelectOnEntry 
    369         except AttributeError: 
    370             return False 
    371              
    372     def _setSelectOnEntry(self, val): 
    373         self._SelectOnEntry = bool(val) 
    374506     
    375507     
     
    385517     
    386518     
    387     def _getTextLength(self): 
    388         return self._textLength 
    389      
    390     def _setTextLength(self, val): 
    391         if val == None: 
    392             self._textLength = None 
    393         else: 
    394             val = int(val) 
    395             if val < 1: 
    396                 raise ValueError, 'TextLength must be a positve Integer' 
    397             self._textLength = val 
    398         self.__textLength() 
    399          
    400         self.unbindEvent(dEvents.KeyChar, self.__onKeyChar) 
    401         if self._forceCase or self._textLength: 
    402             self.bindEvent(dEvents.KeyChar, self.__onKeyChar) 
    403      
    404      
     519    #Overrides the dTextBoxMixinBase getter and setters because of the data conversion 
     520    #introduced in this class 
    405521    def _getValue(self): 
    406522        # Return the value as reported by wx, but convert it to the data type as 
     
    452568                return 
    453569            else: 
    454                 dabo.ui.callAfter(self.__forceCase) 
     570                dabo.ui.callAfter(self._checkForceCase) 
    455571             
    456572            strVal = self.getStringValue(val) 
     
    473589            self._properties["Value"] = val 
    474590         
    475         self.__textLength() 
     591        self._checkTextLength() 
    476592     
    477593     
    478594    # Property definitions: 
    479     Alignment = property(_getAlignment, _setAlignment, None, 
    480             _("""Specifies the alignment of the text. (str) 
    481                Left (default) 
    482                Center 
    483                Right""")) 
    484      
    485     ForceCase = property(_getForceCase, _setForceCase, None, 
    486             _("""Determines if we change the case of entered text. Possible values are: 
    487                 None, "" (empty string): No changes made (default) 
    488                 "Upper": FORCE TO UPPER CASE 
    489                 "Lower": force to lower case 
    490                 "Title": Force To Title Case 
    491             These can be abbreviated to "u", "l" or "t"  (str)""")) 
    492      
    493     InsertionPosition = property(_getInsertionPosition, _setInsertionPosition, None, 
    494             _("Position of the insertion point within the control  (int)")) 
    495      
    496595    PasswordEntry = property(_getPasswordEntry, _setPasswordEntry, None, 
    497596            _("Specifies whether plain-text or asterisks are echoed. (bool)")) 
    498597     
    499     ReadOnly = property(_getReadOnly, _setReadOnly, None,  
    500             _("Specifies whether or not the text can be edited. (bool)")) 
    501      
    502     SelectedText = property(_getSelectedText, None, None, 
    503             _("Currently selected text. Returns the empty string if nothing is selected  (str)"))    
    504      
    505     SelectionEnd = property(_getSelectionEnd, _setSelectionEnd, None, 
    506             _("""Position of the end of the selected text. If no text is 
    507             selected, returns the Position of the insertion cursor.  (int)""")) 
    508      
    509     SelectionLength = property(_getSelectionLength, _setSelectionLength, None, 
    510             _("Length of the selected text, or 0 if nothing is selected.  (int)")) 
    511      
    512     SelectionStart = property(_getSelectionStart, _setSelectionStart, None, 
    513             _("""Position of the beginning of the selected text. If no text is 
    514             selected, returns the Position of the insertion cursor.  (int)""")) 
    515      
    516     SelectOnEntry = property(_getSelectOnEntry, _setSelectOnEntry, None,  
    517             _("Specifies whether all text gets selected upon receiving focus. (bool)")) 
    518  
    519598    StrictDateEntry = property(_getStrictDateEntry, _setStrictDateEntry, None, 
    520599            _("""Specifies whether date values must be entered in strict ISO8601 format. Default=False. 
     
    523602            which will be coerced into sensible date values automatically.""")) 
    524603     
    525     TextLength = property(_getTextLength, _setTextLength, None, 
    526             _("""The maximum length the entered text can be. (int)""")) 
    527  
    528604    Value = property(_getValue, _setValue, None, 
    529605            _("Specifies the current state of the control (the value of the field). (varies)")) 
     
    531607     
    532608    # Dynamic property declarations 
    533     DynamicAlignment = makeDynamicProperty(Alignment) 
    534     DynamicInsertionPosition = makeDynamicProperty(InsertionPosition) 
    535609    DynamicPasswordEntry = makeDynamicProperty(PasswordEntry) 
    536     DynamicReadOnly = makeDynamicProperty(ReadOnly) 
    537     DynamicSelectionEnd = makeDynamicProperty(SelectionEnd) 
    538     DynamicSelectionLength = makeDynamicProperty(SelectionLength) 
    539     DynamicSelectionStart = makeDynamicProperty(SelectionStart) 
    540     DynamicSelectOnEntry = makeDynamicProperty(SelectOnEntry) 
    541610    DynamicStrictDateEntry = makeDynamicProperty(StrictDateEntry) 
    542611    DynamicValue = makeDynamicProperty(Value)