]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/lib/masked/maskededit.py
first attempt for full screen implementation
[wxWidgets.git] / wxPython / wx / lib / masked / maskededit.py
index 1c528c9c666624aac4faf61675cd09cf0959291d..a271fc4a7bd328693d73a7f98cb4b36d986ace75 100644 (file)
@@ -86,7 +86,7 @@
     provides a single "unified" interface for masked controls.  Those for
     masked.TextCtrl, masked.ComboBox and masked.IpAddrCtrl are all documented
     below; the others have their own demo pages and interface descriptions.
-    (See end of following discussion for how to configure the wxMaskedCtrl()
+    (See end of following discussion for how to configure the wx.MaskedCtrl()
     to select the above control types.)
 
 
@@ -528,7 +528,7 @@ Naming Conventions
                         the function for getting the start and end of the
                         current text selection.  The reason for this is
                         that not all controls have the same function name for
-                        doing this; eg. wxTextCtrl uses .GetSelection(),
+                        doing this; eg. wx.TextCtrl uses .GetSelection(),
                         whereas we had to write a .GetMark() function for
                         wxComboBox, because .GetSelection() for the control
                         gets the currently selected list item from the combo
@@ -1581,7 +1581,7 @@ class Field:
 class MaskedEditMixin:
     """
     This class allows us to abstract the masked edit functionality that could
-    be associated with any text entry control. (eg. wxTextCtrl, wxComboBox, etc.)
+    be associated with any text entry control. (eg. wx.TextCtrl, wx.ComboBox, etc.)
     """
     valid_ctrl_params = {
               'mask': 'XXXXXXXXXXXXX',          ## mask string for formatting this control
@@ -1915,9 +1915,8 @@ class MaskedEditMixin:
 
             if self._autofit:
 ##                dbg('setting client size to:', self._CalcSize())
-                size = self._CalcSize()
-                self.SetSizeHints(size)
-                self.SetClientSize(size)
+                self.SetClientSize(self._CalcSize())
+                self.SetSizeHints(self.GetSize())
 
             # Set value/type-specific formatting
             self._applyFormatting()
@@ -1992,9 +1991,8 @@ class MaskedEditMixin:
                 self._SetInitialValue()
 
                 if self._autofit:
-                    size = self._CalcSize()
-                    self.SetSizeHints(size)
-                    self.SetClientSize(size)
+                    self.SetClientSize(self._CalcSize())
+                    self.SetSizeHints(self.GetSize())
 
             # Set value/type-specific formatting
             self._applyFormatting()
@@ -2684,10 +2682,11 @@ class MaskedEditMixin:
 ##            dbg(indent=0)
             return bValid
 
-        ##! WS: For some inexplicable reason, every wxTextCtrl.SetValue
-        ## call is generating two (2) EVT_TEXT events.
+        ##! WS: For some inexplicable reason, every wx.TextCtrl.SetValue
+        ## call is generating two (2) EVT_TEXT events.  On certain platforms,
+        ## (eg. linux/GTK) the 1st is an empty string value.
         ## This is the only mechanism I can find to mask this problem:
-        if newvalue == self._curValue:
+        if newvalue == self._curValue or len(newvalue) == 0:
 ##            dbg('ignoring bogus text change event', indent=0)
             pass
         else:
@@ -3090,7 +3089,7 @@ class MaskedEditMixin:
     def _OnCtrl_A(self,event=None):
         """ Handles ctrl-a keypress in control. Should return False to skip other processing. """
         end = self._goEnd(getPosOnly=True)
-        if not event or event.ShiftDown():
+        if not event or (isinstance(event, wx.KeyEvent) and event.ShiftDown()):
             wx.CallAfter(self._SetInsertionPoint, 0)
             wx.CallAfter(self._SetSelection, 0, self._masklength)
         else:
@@ -3099,7 +3098,7 @@ class MaskedEditMixin:
         return False
 
 
-    def _OnErase(self, event=None):
+    def _OnErase(self, event=None, just_return_value=False):
         """ Handles backspace and delete keypress in control. Should return False to skip other processing."""
 ##        dbg("MaskedEditMixin::_OnErase", indent=1)
         sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
@@ -3317,6 +3316,11 @@ class MaskedEditMixin:
 ##            dbg(indent=0)
             return False
 
+        if just_return_value:
+##            dbg(indent=0)
+            return newstr
+
+        # else...
 ##        dbg('setting value (later) to', newstr)
         wx.CallAfter(self._SetValue, newstr)
 ##        dbg('setting insertion point (later) to', pos)
@@ -4711,11 +4715,28 @@ class MaskedEditMixin:
         newtext = ""
         newpos = pos
 
+        # if >= 2 chars selected in a right-insert field, do appropriate erase on field,
+        # then set selection to end, and do usual right insert.
+        if sel_start != sel_to and sel_to >= sel_start+2:
+            field = self._FindField(sel_start)
+            if( field._insertRight                          # if right-insert
+                and field._allowInsert                      # and allow insert at any point in field
+                and field == self._FindField(sel_to) ):     # and selection all in same field
+                text = self._OnErase(just_return_value=True)    # remove selection before insert
+##                dbg('text after (left)erase: "%s"' % text)
+                pos = sel_start = sel_to
+
         if pos != sel_start and sel_start == sel_to:
             # adjustpos must have moved the position; make selection match:
             sel_start = sel_to = pos
 
 ##        dbg('field._insertRight?', field._insertRight)
+##        dbg('field._allowInsert?', field._allowInsert)
+##        dbg('sel_start, end', sel_start, end)
+        if sel_start < end:
+##            dbg('text[sel_start] != field._fillChar?', text[sel_start] != field._fillChar)
+            pass
+
         if( field._insertRight                                  # field allows right insert
             and ((sel_start, sel_to) == field._extent           # and whole field selected
                  or (sel_start == sel_to                        # or nothing selected
@@ -4871,7 +4892,8 @@ class MaskedEditMixin:
                 if match_index is not None and partial_match:
                     matched_str = newtext
                     newtext = self._ctrl_constraints._choices[match_index]
-                    new_select_to = self._ctrl_constraints._extent[1]
+                    edit_end = self._ctrl_constraints._extent[1]
+                    new_select_to = min(edit_end, len(newvalue.rstrip()))
                     match_field = self._ctrl_constraints
                     if self._ctrl_constraints._insertRight:
                         # adjust position to just after partial match in control:
@@ -4890,7 +4912,7 @@ class MaskedEditMixin:
         """
         This event handler is currently necessary to work around new default
         behavior as of wxPython2.3.3;
-        The TAB key auto selects the entire contents of the wxTextCtrl *after*
+        The TAB key auto selects the entire contents of the wx.TextCtrl *after*
         the EVT_SET_FOCUS event occurs; therefore we can't query/adjust the selection
         *here*, because it hasn't happened yet.  So to prevent this behavior, and
         preserve the correct selection when the focus event is not due to tab,
@@ -4999,7 +5021,7 @@ class MaskedEditMixin:
                 if self._isFloat and groupcharpos > self._decimalpos:
                     # 1st one found on right-hand side is past decimal point
 ##                    dbg('groupchar in fraction; illegal')
-                    valid = False
+                    return False
                 elif self._isFloat:
                     integer = value[:self._decimalpos].strip()
                 else:
@@ -5153,7 +5175,7 @@ class MaskedEditMixin:
 
         The trouble is that, a priori, there's no explicit notification of
         why the focus event we received.  However, the whole reason we need to
-        do this is because the default behavior on TAB traveral in a wxTextCtrl is
+        do this is because the default behavior on TAB traveral in a wx.TextCtrl is
         now to select the entire contents of the window, something we don't want.
         So we can *now* test the selection range, and if it's "the whole text"
         we can assume the cause, change the insertion point to the start of
@@ -5258,11 +5280,11 @@ class MaskedEditMixin:
 ##        dbg('current value: "%s"' % value)
         sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
 ##        dbg('selected text: "%s"' % value[sel_start:sel_to].strip())
-        do = wxTextDataObject()
+        do = wx.TextDataObject()
         do.SetText(value[sel_start:sel_to].strip())
-        wxTheClipboard.Open()
-        wxTheClipboard.SetData(do)
-        wxTheClipboard.Close()
+        wx.TheClipboard.Open()
+        wx.TheClipboard.SetData(do)
+        wx.TheClipboard.Close()
 
         if sel_to - sel_start != 0:
             self._OnErase()
@@ -5274,27 +5296,27 @@ class MaskedEditMixin:
 #
 ##    def _Copy( self ):
 ##        """
-##        Override the wxTextCtrl's .Copy function, with our own
+##        Override the wx.TextCtrl's .Copy function, with our own
 ##        that does validation.  Need to strip trailing spaces.
 ##        """
 ##        sel_start, sel_to = self._GetSelection()
 ##        select_len = sel_to - sel_start
-##        textval = wxTextCtrl._GetValue(self)
+##        textval = wx.TextCtrl._GetValue(self)
 ##
-##        do = wxTextDataObject()
+##        do = wx.TextDataObject()
 ##        do.SetText(textval[sel_start:sel_to].strip())
-##        wxTheClipboard.Open()
-##        wxTheClipboard.SetData(do)
-##        wxTheClipboard.Close()
+##        wx.TheClipboard.Open()
+##        wx.TheClipboard.SetData(do)
+##        wx.TheClipboard.Close()
 
 
     def _getClipboardContents( self ):
         """ Subroutine for getting the current contents of the clipboard.
         """
-        do = wxTextDataObject()
-        wxTheClipboard.Open()
-        success = wxTheClipboard.GetData(do)
-        wxTheClipboard.Close()
+        do = wx.TextDataObject()
+        wx.TheClipboard.Open()
+        success = wx.TheClipboard.GetData(do)
+        wx.TheClipboard.Close()
 
         if not success:
             return None
@@ -5424,11 +5446,31 @@ class MaskedEditMixin:
             field = self._FindField(sel_start)
             edit_start, edit_end = field._extent
             new_pos = None
-            if field._allowInsert and sel_to <= edit_end and sel_start + len(paste_text) < edit_end:
+            if field._allowInsert and sel_to <= edit_end and (sel_start + len(paste_text) < edit_end or field._insertRight):
+                if field._insertRight:
+                    # want to paste to the left; see if it will fit:
+                    left_text = self._GetValue()[edit_start:sel_start].lstrip()
+##                    dbg('len(left_text):', len(left_text))
+##                    dbg('len(paste_text):', len(paste_text))
+##                    dbg('sel_start - (len(left_text) + len(paste_text)) >= edit_start?', sel_start - (len(left_text) + len(paste_text)) >= edit_start)
+                    if sel_start - (len(left_text) - (sel_to - sel_start) + len(paste_text)) >= edit_start:
+                        # will fit! create effective paste text, and move cursor back to do so:
+                        paste_text = left_text + paste_text
+                        sel_start -= len(left_text)
+                        paste_text = paste_text.rjust(sel_to - sel_start)
+##                        dbg('modified paste_text to be: "%s"' % paste_text)
+##                        dbg('modified selection to:', (sel_start, sel_to))
+                    else:
+##                        dbg("won't fit left;", 'paste text remains: "%s"' % paste_text)
+                        pass
+                else:
+                    paste_text = paste_text + self._GetValue()[sel_to:edit_end].rstrip()
+##                    dbg("allow insert, but not insert right;", 'paste text set to: "%s"' % paste_text)
+
+
                 new_pos = sel_start + len(paste_text)   # store for subsequent positioning
-                paste_text = paste_text + self._GetValue()[sel_to:edit_end].rstrip()
 ##                dbg('paste within insertable field; adjusted paste_text: "%s"' % paste_text, 'end:', edit_end)
-                sel_to = sel_start + len(paste_text)
+##                dbg('expanded selection to:', (sel_start, sel_to))
 
             # Another special case: paste won't fit, but it's a right-insert field where entire
             # non-empty value is selected, and there's room if the selection is expanded leftward:
@@ -5491,7 +5533,7 @@ class MaskedEditMixin:
                 if not wx.Validator_IsSilent():
                     wx.Bell()
 ##                dbg(indent=0)
-                return False
+                return None, -1
             # else...
             text = self._eraseSelection()
 
@@ -5522,17 +5564,19 @@ class MaskedEditMixin:
                     wx.CallAfter(self._SetInsertionPoint, new_pos)
             else:
 ##                dbg(indent=0)
-                return new_text
+                return new_text, replace_to
         elif just_return_value:
 ##            dbg(indent=0)
-            return self._GetValue()
+            return self._GetValue(), sel_to
 ##        dbg(indent=0)
 
-    def _Undo(self):
+    def _Undo(self, value=None, prev=None, just_return_results=False):
         """ Provides an Undo() method in base controls. """
 ##        dbg("MaskedEditMixin::_Undo", indent=1)
-        value = self._GetValue()
-        prev = self._prevValue
+        if value is None:
+            value = self._GetValue()
+        if prev is None:
+            prev = self._prevValue
 ##        dbg('current value:  "%s"' % value)
 ##        dbg('previous value: "%s"' % prev)
         if prev is None:
@@ -5589,6 +5633,7 @@ class MaskedEditMixin:
                 for next_op in range(len(code_5tuples)-1, -1, -1):
                     op, i1, i2, j1, j2 = code_5tuples[next_op]
 ##                    dbg('value[i1:i2]: "%s"' % value[i1:i2], 'template[i1:i2] "%s"' % self._template[i1:i2])
+                    field = self._FindField(i2)
                     if op == 'insert' and prev[j1:j2] != self._template[j1:j2]:
 ##                        dbg('insert found: selection =>', (j1, j2))
                         sel_start = j1
@@ -5596,9 +5641,8 @@ class MaskedEditMixin:
                         diff_found = True
                         break
                     elif op == 'delete' and value[i1:i2] != self._template[i1:i2]:
-                        field = self._FindField(i2)
                         edit_start, edit_end = field._extent
-                        if field._insertRight and i2 == edit_end:
+                        if field._insertRight and (field._allowInsert or i2 == edit_end):
                             sel_start = i2
                             sel_to = i2
                         else:
@@ -5608,23 +5652,39 @@ class MaskedEditMixin:
                         diff_found = True
                         break
                     elif op == 'replace':
-##                        dbg('replace found: selection =>', (j1, j2))
-                        sel_start = j1
-                        sel_to = j2
+                        if not prev[i1:i2].strip() and field._insertRight:
+                            sel_start = sel_to = j2
+                        else:
+                            sel_start = j1
+                            sel_to = j2
+##                        dbg('replace found: selection =>', (sel_start, sel_to))
                         diff_found = True
                         break
 
 
                 if diff_found:
                     # now go forwards, looking for earlier changes:
+##                    dbg('searching forward...')
                     for next_op in range(len(code_5tuples)):
                         op, i1, i2, j1, j2 = code_5tuples[next_op]
                         field = self._FindField(i1)
                         if op == 'equal':
                             continue
                         elif op == 'replace':
-##                            dbg('setting sel_start to', i1)
-                            sel_start = i1
+                            if field._insertRight:
+                                # if replace with spaces in an insert-right control, ignore "forward" replace
+                                if not prev[i1:i2].strip():
+                                    continue
+                                elif j1 < i1:
+##                                    dbg('setting sel_start to', j1)
+                                    sel_start = j1
+                                else:
+##                                    dbg('setting sel_start to', i1)
+                                    sel_start = i1
+                            else:
+##                                dbg('setting sel_start to', i1)
+                                sel_start = i1
+##                            dbg('saw replace; breaking')
                             break
                         elif op == 'insert' and not value[i1:i2]:
 ##                            dbg('forward %s found' % op)
@@ -5636,9 +5696,21 @@ class MaskedEditMixin:
 ##                                dbg('setting sel_start to inserted space:', j1)
                                 sel_start = j1
                                 break
-                        elif op == 'delete' and field._insertRight and not value[i1:i2].lstrip():
-                            continue
+                        elif op == 'delete':
+##                            dbg('delete; field._insertRight?', field._insertRight, 'value[%d:%d].lstrip: "%s"' % (i1,i2,value[i1:i2].lstrip()))
+                            if field._insertRight:
+                                if value[i1:i2].lstrip():
+##                                    dbg('setting sel_start to ', j1)
+                                    sel_start = j1
+##                                    dbg('breaking loop')
+                                    break
+                                else:
+                                    continue
+                            else:
+##                                dbg('saw delete; breaking')
+                                break
                         else:
+##                            dbg('unknown code!')
                             # we've got what we need
                             break
 
@@ -5692,15 +5764,22 @@ class MaskedEditMixin:
 
                 prev_sel_start, prev_sel_to = self._prevSelection
                 field = self._FindField(sel_start)
-
-                if self._signOk and (self._prevValue[sel_start] in ('-', '(', ')')
-                                     or self._curValue[sel_start] in ('-', '(', ')')):
+                if( self._signOk
+                      and sel_start < self._masklength
+                      and (prev[sel_start] in ('-', '(', ')')
+                                     or value[sel_start] in ('-', '(', ')')) ):
                     # change of sign; leave cursor alone...
+##                    dbg("prev[sel_start] in ('-', '(', ')')?", prev[sel_start] in ('-', '(', ')'))
+##                    dbg("value[sel_start] in ('-', '(', ')')?", value[sel_start] in ('-', '(', ')'))
+##                    dbg('setting selection to previous one')
                     sel_start, sel_to = self._prevSelection
 
-                elif field._groupdigits and (self._curValue[sel_start:sel_to] == field._groupChar
-                                             or self._prevValue[sel_start:sel_to] == field._groupChar):
+                elif field._groupdigits and (value[sel_start:sel_to] == field._groupChar
+                                             or prev[sel_start:sel_to] == field._groupChar):
                     # do not highlight grouping changes
+##                    dbg('value[sel_start:sel_to] == field._groupChar?', value[sel_start:sel_to] == field._groupChar)
+##                    dbg('prev[sel_start:sel_to] == field._groupChar?', prev[sel_start:sel_to] == field._groupChar)
+##                    dbg('setting selection to previous one')
                     sel_start, sel_to = self._prevSelection
 
                 else:
@@ -5712,7 +5791,13 @@ class MaskedEditMixin:
 
                     if prev_select_len >= calc_select_len:
                         # old selection was bigger; trust it:
-                        sel_start, sel_to = self._prevSelection
+##                        dbg('prev_select_len >= calc_select_len?', prev_select_len >= calc_select_len)
+                        if not field._insertRight:
+##                            dbg('setting selection to previous one')
+                            sel_start, sel_to = self._prevSelection
+                        else:
+                            sel_to = self._prevSelection[1]
+##                            dbg('setting selection to', (sel_start, sel_to))
 
                     elif( sel_to > prev_sel_to                  # calculated select past last selection
                           and prev_sel_to < len(self._template) # and prev_sel_to not at end of control
@@ -5743,27 +5828,44 @@ class MaskedEditMixin:
                             test_sel_start, test_sel_to = prev_sel_start, prev_sel_to
 
 ##                        dbg('test selection:', (test_sel_start, test_sel_to))
-##                        dbg('calc change: "%s"' % self._prevValue[sel_start:sel_to])
-##                        dbg('test change: "%s"' % self._prevValue[test_sel_start:test_sel_to])
+##                        dbg('calc change: "%s"' % prev[sel_start:sel_to])
+##                        dbg('test change: "%s"' % prev[test_sel_start:test_sel_to])
 
                         # if calculated selection spans characters, and same characters
                         # "before" the previous insertion point are present there as well,
                         # select the ones related to the last known selection instead.
                         if( sel_start != sel_to
                             and test_sel_to < len(self._template)
-                            and self._prevValue[test_sel_start:test_sel_to] == self._prevValue[sel_start:sel_to] ):
+                            and prev[test_sel_start:test_sel_to] == prev[sel_start:sel_to] ):
 
                             sel_start, sel_to = test_sel_start, test_sel_to
 
+                # finally, make sure that the old and new values are
+                # different where we say they're different:
+                while( sel_to - 1 > 0
+                        and sel_to > sel_start
+                        and value[sel_to-1:] == prev[sel_to-1:]):
+                    sel_to -= 1
+                while( sel_start + 1 < self._masklength
+                        and sel_start < sel_to
+                        and value[:sel_start+1] == prev[:sel_start+1]):
+                    sel_start += 1
+
 ##            dbg('sel_start, sel_to:', sel_start, sel_to)
-##            dbg('previous value: "%s"' % self._prevValue)
-            self._SetValue(self._prevValue)
+##            dbg('previous value: "%s"' % prev)
+##            dbg(indent=0)
+            if just_return_results:
+                return prev, (sel_start, sel_to)
+            # else...
+            self._SetValue(prev)
             self._SetInsertionPoint(sel_start)
             self._SetSelection(sel_start, sel_to)
+
         else:
 ##            dbg('no difference between previous value')
-            pass
-##        dbg(indent=0)
+##            dbg(indent=0)
+            if just_return_results:
+                return prev, self._GetSelection()
 
 
     def _OnClear(self, event):
@@ -5773,31 +5875,31 @@ class MaskedEditMixin:
 
     def _OnContextMenu(self, event):
 ##        dbg('MaskedEditMixin::OnContextMenu()', indent=1)
-        menu = wxMenu()
-        menu.Append(wxID_UNDO, "Undo", "")
+        menu = wx.Menu()
+        menu.Append(wx.ID_UNDO, "Undo", "")
         menu.AppendSeparator()
-        menu.Append(wxID_CUT, "Cut", "")
-        menu.Append(wxID_COPY, "Copy", "")
-        menu.Append(wxID_PASTE, "Paste", "")
-        menu.Append(wxID_CLEAR, "Delete", "")
+        menu.Append(wx.ID_CUT, "Cut", "")
+        menu.Append(wx.ID_COPY, "Copy", "")
+        menu.Append(wx.ID_PASTE, "Paste", "")
+        menu.Append(wx.ID_CLEAR, "Delete", "")
         menu.AppendSeparator()
-        menu.Append(wxID_SELECTALL, "Select All", "")
+        menu.Append(wx.ID_SELECTALL, "Select All", "")
 
-        EVT_MENU(menu, wxID_UNDO, self._OnCtrl_Z)
-        EVT_MENU(menu, wxID_CUT, self._OnCtrl_X)
-        EVT_MENU(menu, wxID_COPY, self._OnCtrl_C)
-        EVT_MENU(menu, wxID_PASTE, self._OnCtrl_V)
-        EVT_MENU(menu, wxID_CLEAR, self._OnClear)
-        EVT_MENU(menu, wxID_SELECTALL, self._OnCtrl_A)
+        wx.EVT_MENU(menu, wx.ID_UNDO, self._OnCtrl_Z)
+        wx.EVT_MENU(menu, wx.ID_CUT, self._OnCtrl_X)
+        wx.EVT_MENU(menu, wx.ID_COPY, self._OnCtrl_C)
+        wx.EVT_MENU(menu, wx.ID_PASTE, self._OnCtrl_V)
+        wx.EVT_MENU(menu, wx.ID_CLEAR, self._OnClear)
+        wx.EVT_MENU(menu, wx.ID_SELECTALL, self._OnCtrl_A)
 
         # ## WSS: The base control apparently handles
-        # enable/disable of wID_CUT, wxID_COPY, wxID_PASTE
-        # and wxID_CLEAR menu items even if the menu is one
+        # enable/disable of wx.ID_CUT, wx.ID_COPY, wx.ID_PASTE
+        # and wx.ID_CLEAR menu items even if the menu is one
         # we created.  However, it doesn't do undo properly,
         # so we're keeping track of previous values ourselves.
         # Therefore, we have to override the default update for
         # that item on the menu:
-        EVT_UPDATE_UI(self, wxID_UNDO, self._UndoUpdateUI)
+        wx.EVT_UPDATE_UI(self, wx.ID_UNDO, self._UndoUpdateUI)
         self._contextMenu = menu
 
         self.PopupMenu(menu, event.GetPosition())
@@ -5807,9 +5909,9 @@ class MaskedEditMixin:
 
     def _UndoUpdateUI(self, event):
         if self._prevValue is None or self._prevValue == self._curValue:
-            self._contextMenu.Enable(wxID_UNDO, False)
+            self._contextMenu.Enable(wx.ID_UNDO, False)
         else:
-            self._contextMenu.Enable(wxID_UNDO, True)
+            self._contextMenu.Enable(wx.ID_UNDO, True)
 
 
     def _OnCtrlParametersChanged(self):
@@ -6284,6 +6386,17 @@ i=1
 
 ## CHANGELOG:
 ## ====================
+##  Version 1.7
+##  1. Fixed intra-right-insert-field erase, such that it doesn't leave a hole, but instead
+##     shifts the text to the left accordingly.
+##  2. Fixed _SetValue() to place cursor after last character inserted, rather than end of
+##     mask.
+##  3. Fixed some incorrect undo behavior for right-insert fields, and allowed derived classes
+##     (eg. numctrl) to pass modified values for undo processing (to handle/ignore grouping
+##     chars properly.)
+##  4. Fixed autoselect behavior to work similarly to (2) above, so that combobox
+##     selection will only select the non-empty text, as per request.
+##
 ##  Version 1.6
 ##  1. Reorganized masked controls into separate package, renamed things accordingly
 ##  2. Split actual controls out of this file into their own files.
@@ -6352,7 +6465,7 @@ i=1
 ##      non-british spellings still supported for backward-compatibility.
 ##  20. Added '&' mask specification character for punctuation only (no letters
 ##      or digits).
-##  21. Added (in a separate file) wxMaskedCtrl() factory function to provide
+##  21. Added (in a separate file) wx.MaskedCtrl() factory function to provide
 ##      unified interface to the masked edit subclasses.
 ##
 ##
@@ -6376,7 +6489,7 @@ i=1
 ##   2. Fixed EUDATE* autoformats, fixed IsDateType mask list, and added ability to
 ##      use 3-char months for dates, and EUDATETIME, and EUDATEMILTIME autoformats.
 ##   3. Made all date autoformats automatically pick implied "datestyle".
-##   4. Added IsModified override, since base wxTextCtrl never reports modified if
+##   4. Added IsModified override, since base wx.TextCtrl never reports modified if
 ##      .SetValue used to change the value, which is what the masked edit controls
 ##      use internally.
 ##   5. Fixed bug in date position adjustment on 2 to 4 digit date conversion when