Changeset 1467

Show
Ignore:
Timestamp:
07/07/08 18:01:07 (2 months ago)
Author:
rob
Message:

Fixed #483: added substring matching in autocomplete minibuffer
* refactored textctrl_autocomplete to use the HtmlListBox? to highlight matched text in bold

Location:
trunk/peppy
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/peppy/actions/minibuffer.py

    r1418 r1467  
    413413        found = [] 
    414414        for match in self.sorted: 
    415             if match.startswith(text): 
     415            if match.find(text) >= 0: 
    416416                found.append(match) 
    417417        return found 
  • trunk/peppy/lib/textctrl_autocomplete.py

    r1419 r1467  
    88""" 
    99import locale, wx, sys, cStringIO 
    10 import  wx.lib.mixins.listctrl  as  listmix 
    11 from wx import ImageFromStream, BitmapFromImage 
    12 #---------------------------------------------------------------------- 
    13 def getSmallUpArrowData(): 
    14     return \ 
    15 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
    16 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
    17 \x00\x00<IDAT8\x8dcddbf\xa0\x040Q\xa4{h\x18\xf0\xff\xdf\xdf\xffd\x1b\x00\xd3\ 
    18 \x8c\xcf\x10\x9c\x06\xa0k\xc2e\x08m\xc2\x00\x97m\xd8\xc41\x0c \x14h\xe8\xf2\ 
    19 \x8c\xa3)q\x10\x18\x00\x00R\xd8#\xec\xb2\xcd\xc1Y\x00\x00\x00\x00IEND\xaeB`\ 
    20 \x82' 
    21  
    22 def getSmallUpArrowBitmap(): 
    23     return BitmapFromImage(getSmallUpArrowImage()) 
    24  
    25 def getSmallUpArrowImage(): 
    26     stream = cStringIO.StringIO(getSmallUpArrowData()) 
    27     return ImageFromStream(stream) 
    28  
    29 def getSmallDnArrowData(): 
    30     return \ 
    31 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ 
    32 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ 
    33 \x00\x00HIDAT8\x8dcddbf\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16t\x81\ 
    34 \xff\xff\xfe\xfe'\xa4\x89\x91\x89\x99\x11\xa7\x0b\x90%\ti\xc6j\x00>C\xb0\x89\ 
    35 \xd3.\x10\xd1m\xc3\xe5*\xbc.\x80i\xc2\x17.\x8c\xa3y\x81\x01\x00\xa1\x0e\x04e\ 
    36 ?\x84B\xef\x00\x00\x00\x00IEND\xaeB`\x82" 
    37  
    38 def getSmallDnArrowBitmap(): 
    39     return BitmapFromImage(getSmallDnArrowImage()) 
    40  
    41 def getSmallDnArrowImage(): 
    42     stream = cStringIO.StringIO(getSmallDnArrowData()) 
    43     return ImageFromStream(stream) 
    44  
    4510 
    4611 
     
    171136 
    172137 
    173 #---------------------------------------------------------------------- 
    174 class myListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): 
    175     def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, 
    176                  size=wx.DefaultSize, style=0): 
    177         wx.ListCtrl.__init__(self, parent, ID, pos, size, style) 
    178         listmix.ListCtrlAutoWidthMixin.__init__(self) 
    179  
    180 class TextCtrlAutoComplete (wx.TextCtrl, listmix.ColumnSorterMixin ): 
    181     def __init__ ( self, parent, colNames=None, choices = None, 
    182                   multiChoices=None, showHead=True, dropDownClick=True, 
    183                   colFetch=-1, colSearch=0, hideOnNoMatch=True, 
    184                   selectCallback=None, entryCallback=None, matchFunction=None, 
     138class HighlightListBox(wx.HtmlListBox): 
     139    """Virtual List Box used to highlight partial matches in the ListCtrl""" 
     140    def setChoices(self, choices): 
     141        self.choices = choices 
     142        self.clearBold() 
     143        self.SetItemCount(len(choices)) 
     144         
     145    def setBold(self, index, start, count): 
     146        self.bold[index] = (start, start+count) 
     147        #print(self.bold[index]) 
     148        self.RefreshLine(index) 
     149         
     150    def clearBold(self): 
     151        self.bold = [None] * len(self.choices) 
     152        if len(self.choices) > 0: 
     153            self.RefreshLines(0, len(self.choices) - 1) 
     154         
     155    def OnGetItem(self, n): 
     156        if hasattr(self, 'bold') and self.bold[n] is not None: 
     157            text = self.choices[n] 
     158            start = self.bold[n][0] 
     159            end = self.bold[n][1] 
     160            val = "%s<b>%s</b>%s" % (text[0:start], text[start:end], text[end:]) 
     161            #print "index %d: %s" % (n, val) 
     162            return val 
     163        return self.choices[n] 
     164     
     165    def selectNextMatch(self): 
     166        """Set the selection to the next match in the list. 
     167         
     168        A match is determined by any item that exists in the bold list.  The 
     169        selection will wrap around to the top of the list. 
     170        """ 
     171        start = self.GetSelection() 
     172        index = start + 1 
     173        count = self.GetLineCount() 
     174        while index < count: 
     175            if self.bold[index] is not None: 
     176                break 
     177            index += 1 
     178        if index >= count: 
     179            index = 0 
     180            while index < start: 
     181                if self.bold[index] is not None: 
     182                    break 
     183                index += 1 
     184            if index == start and self.bold[index] is None: 
     185                index += 1 
     186                if index >= count: 
     187                    index = 0 
     188        if index < count: 
     189            self.SetSelection(index) 
     190     
     191    def selectPrevMatch(self): 
     192        """Set the selection to the previous match in the list. 
     193         
     194        A match is determined by any item that exists in the bold list.  The 
     195        selection will wrap around to the bottom of the list. 
     196        """ 
     197        start = self.GetSelection() 
     198        index = start - 1 
     199        count = self.GetLineCount() 
     200        while index >= 0: 
     201            if self.bold[index] is not None: 
     202                break 
     203            index -= 1 
     204        if index < 0: 
     205            index = count - 1 
     206            while index > start: 
     207                if self.bold[index] is not None: 
     208                    break 
     209                index -= 1 
     210            if index == start and self.bold[index] is None: 
     211                index -= 1 
     212                if index < 0: 
     213                    index = count - 1 
     214        if index >= 0: 
     215            self.SetSelection(index) 
     216 
     217    def getLargestCommon(self, input): 
     218        """Get the largest common string from the list of already matched strings. 
     219         
     220        Using the list of strings that already have been matched, see if there 
     221        are any more characters that can be matched that are in common among 
     222        all of the strings. 
     223        """ 
     224        found = None 
     225        start = len(input) 
     226        most = None 
     227        for index, bold in enumerate(self.bold): 
     228            if bold is not None: 
     229                text = self.choices[index][bold[0]:] 
     230                if found is None: 
     231                    # get first match 
     232                    found = text 
     233                    most = len(found) 
     234                else: 
     235                    for j in range(start, most): 
     236                        if text[j] != found[j]: 
     237                            most = j 
     238                            break 
     239                #print "after %d %s: found=%s most=%d" % (index, text, found, most) 
     240        if not found: 
     241            found = input 
     242        else: 
     243            found = found[0:most] 
     244        return found 
     245 
     246 
     247class TextCtrlAutoComplete(wx.TextCtrl): 
     248    def __init__ (self, parent, choices=None, dropDownClick=True, 
     249                  hideOnNoMatch=True, entryCallback=None, matchFunction=None, 
    185250                   mac=False, 
    186251                  **therest) : 
     
    197262        #Some variables 
    198263        self._dropDownClick = dropDownClick 
    199         self._colNames = colNames 
    200         self._multiChoices = multiChoices 
    201         self._showHead = showHead 
    202264        self._choices = choices 
    203265        self._lastinsertionpoint = 0 
    204266        self._hideOnNoMatch = hideOnNoMatch 
    205         self._selectCallback = selectCallback 
    206267        self._entryCallback = entryCallback 
    207268        self._matchFunction = matchFunction 
    208269        self._screenheight = wx.SystemSettings.GetMetric( wx.SYS_SCREEN_Y ) 
    209270        self._tabCount = 0 
    210         #sort variable needed by listmix 
    211         self.itemDataMap = dict() 
    212         #Load and sort data 
    213 ##        if not (self._multiChoices or self._choices): 
    214 ##            raise ValueError, "Pass me at least one of multiChoices OR choices" 
    215         #widgets 
     271        self._onlyAtStart = False 
     272 
    216273        self._mac = mac | bool(wx.Platform == '__WXMAC__') 
    217274        if self._mac: 
     
    219276        else: 
    220277            self.dropdown = wx.PopupWindow( self ) 
    221         #Control the style 
    222         flags = wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_SORT_ASCENDING 
    223         if not (showHead and multiChoices) : 
    224             flags = flags | wx.LC_NO_HEADER 
    225         #Create the list and bind the events 
    226         self.dropdownlistbox = myListCtrl( self.dropdown, style=flags, 
    227                                  pos=wx.Point( 0, 0) ) 
     278 
     279        self.dropdownlistbox = HighlightListBox(self.dropdown) 
    228280        if mac: 
    229281            self.dropdown.setList(self.dropdownlistbox) 
     
    233285            self.Bind( wx.EVT_KILL_FOCUS, self.onControlChanged, self ) 
    234286         
    235         #initialize the parent 
    236         if multiChoices: ln = len(multiChoices) 
    237         else: ln = 1 
    238         #else: ln = len(choices) 
    239         listmix.ColumnSorterMixin.__init__(self, ln) 
    240         #load the data 
    241         if multiChoices: self.SetMultipleChoices (multiChoices, colSearch=colSearch, colFetch=colFetch) 
    242         else: self.SetChoices ( choices ) 
    243 ##        gp = self 
    244 ##        while ( gp != None ) : 
    245 ##            gp.Bind ( wx.EVT_MOVE , self.onControlChanged, gp ) 
    246 ##            gp.Bind ( wx.EVT_SIZE , self.onControlChanged, gp ) 
    247 ##            gp = gp.GetParent() 
     287        self.SetChoices(choices) 
     288 
    248289        self.Bind( wx.EVT_TEXT , self.onEnteredText, self ) 
    249290        self.Bind( wx.EVT_KEY_DOWN , self.onKeyDown, self ) 
     
    255296        self.dropdownlistbox.Bind(wx.EVT_LEFT_DOWN, self.onListClick) 
    256297        self.dropdownlistbox.Bind(wx.EVT_LEFT_DCLICK, self.onListDClick) 
    257         self.dropdownlistbox.Bind(wx.EVT_LIST_COL_CLICK, self.onListColClick) 
    258         self.il = wx.ImageList(16, 16) 
    259         self.sm_dn = self.il.Add(getSmallDnArrowBitmap()) 
    260         self.sm_up = self.il.Add(getSmallUpArrowBitmap()) 
    261         self.dropdownlistbox.SetImageList(self.il, wx.IMAGE_LIST_SMALL) 
    262         self._ascending = True 
    263  
    264     #-- methods called from mixin class 
    265     def GetSortImages(self): 
    266         return (self.sm_dn, self.sm_up) 
    267  
    268     def GetListCtrl(self): 
    269         return self.dropdownlistbox 
    270     # -- event methods 
    271298 
    272299    def onListClick(self, evt): 
    273         toSel, flag = self.dropdownlistbox.HitTest( evt.GetPosition() ) 
     300        toSel = self.dropdownlistbox.HitTest( evt.GetPosition() ) 
    274301        #no values on poition, return 
    275302        if toSel == -1: return 
    276         self.dropdownlistbox.Select(toSel) 
     303        self.dropdownlistbox.SetSelection(toSel) 
    277304 
    278305    def onListDClick(self, evt): 
    279306        self._setValueFromSelected() 
    280  
    281     def onListColClick(self, evt): 
    282         col = evt.GetColumn() 
    283         #reverse the sort 
    284         if col == self._colSearch: 
    285             self._ascending = not self._ascending 
    286         self.SortListItems( evt.GetColumn(), ascending=self._ascending ) 
    287         self._colSearch = evt.GetColumn() 
    288         evt.Skip() 
    289307 
    290308    def onEnteredText(self, event): 
     
    292310        if self._entryCallback: 
    293311            self._entryCallback() 
     312        self.dropdownlistbox.clearBold() 
    294313        if not text: 
    295314            # control is empty; hide dropdown if shown: 
     
    298317            event.Skip() 
    299318            return 
     319        best = None 
    300320        found = False 
    301         if self._multiChoices: 
    302             #load the sorted data into the listbox 
    303             dd = self.dropdownlistbox 
    304             choices = [dd.GetItem(x, self._colSearch).GetText() 
    305                 for x in xrange(dd.GetItemCount())] 
    306         else: 
    307             choices = self._choices 
     321        nchar = len(text) 
     322        choices = self._choices 
    308323        for numCh, choice in enumerate(choices): 
    309             if self._matchFunction and self._matchFunction(text, choice): 
    310                 found = True 
    311             elif choice.lower().startswith(text.lower()) : 
    312                 found = True 
     324            if self._matchFunction: 
     325                index, count = self._matchFunction(text, choice) 
     326                if count > 0: 
     327                    found = True 
     328                    self.dropdownlistbox.setBold(numCh, index, count) 
     329            else: 
     330                if self._onlyAtStart: 
     331                    if choice.lower().startswith(text.lower()): 
     332                        found = True 
     333                        self.dropdownlistbox.setBold(numCh, 0, nchar) 
     334                else: 
     335                    index = choice.lower().find(text.lower()) 
     336                    if index >= 0: 
     337                        found = True 
     338                        self.dropdownlistbox.setBold(numCh, index, nchar) 
    313339            if found: 
    314                 self._showDropDown(True) 
    315                 item = self.dropdownlistbox.GetItem(numCh) 
    316                 toSel = item.GetId() 
    317                 self.dropdownlistbox.Select(toSel) 
    318                 #self.SetFocus() 
    319                 break 
    320         if not found: 
    321             self.dropdownlistbox.Select(self.dropdownlistbox.GetFirstSelected(), False) 
     340                if best is None: 
     341                    best = numCh 
     342        #print("best = %s" % best) 
     343        if best is not None: 
     344            self._showDropDown(True) 
     345            self.dropdownlistbox.SetSelection(best) 
     346            #self.SetFocus() 
     347        else: 
     348            self.dropdownlistbox.SetSelection(-1) 
    322349            if self._hideOnNoMatch: 
    323350                self._showDropDown(False) 
     
    331358        """ 
    332359        skip = True 
    333         sel = self.dropdownlistbox.GetFirstSelected() 
     360        dd = self.dropdownlistbox 
     361        sel = dd.GetSelection() 
    334362        visible = self.dropdown.IsShown() 
    335363        KC = event.GetKeyCode() 
    336364        if KC == wx.WXK_DOWN : 
    337             if sel < (self.dropdownlistbox.GetItemCount () - 1) : 
    338                 self.dropdownlistbox.Select ( sel+1 ) 
     365            if sel < (dd.GetItemCount () - 1) : 
     366                dd.SetSelection ( sel+1 ) 
    339367                self._listItemVisible() 
    340368            self._showDropDown () 
     
    342370        elif KC == wx.WXK_UP : 
    343371            if sel > 0 : 
    344                 self.dropdownlistbox.Select ( sel - 1 ) 
     372                dd.SetSelection ( sel - 1 ) 
    345373                self._listItemVisible() 
    346374            self._showDropDown () 
    347375            skip = False 
    348         elif KC == wx.WXK_LEFT : 
    349             if not self._multiChoices: 
    350                 event.Skip() 
    351                 return 
    352             if self._colSearch > 0: 
    353                 self._colSearch -=1 
    354             self._showDropDown () 
    355         elif KC == wx.WXK_RIGHT: 
    356             if not self._multiChoices: 
    357                 event.Skip() 
    358                 return 
    359             if self._colSearch < self.dropdownlistbox.GetColumnCount() -1: 
    360                 self._colSearch += 1 
    361             self._showDropDown() 
     376        elif KC == wx.WXK_PAGEDOWN: 
     377            if sel == -1: 
     378                dd.SetSelection(0) 
     379            else: 
     380                first = dd.GetVisibleBegin() 
     381                last = dd.GetVisibleEnd() 
     382                if not dd.IsVisible(last): 
     383                    last -= 1 
     384                dd.ScrollPages(1) 
     385                dd.SetSelection(last) 
     386        elif KC == wx.WXK_PAGEUP: 
     387            if sel == -1: 
     388                dd.SetSelection(dd.GetLineCount() - 1) 
     389            else: 
     390                first = dd.GetVisibleBegin() 
     391                last = dd.GetVisibleEnd() 
     392                dd.ScrollPages(-1) 
     393                dd.SetSelection(first) 
    362394        if KC == wx.WXK_TAB: 
    363395            #print self._choices 
     
    367399                # Find the largest common match in the list of choices 
    368400                # and expand to that 
    369                 start = len(self.GetValue()) 
    370                 matched = self._choices[0] 
    371                 most = len(matched) 
    372                 #print "before start=%d most=%d" % (start, most) 
    373                 for match in self._choices[1:]: 
    374                     for j in range(start, most): 
    375                         if match[j] != matched[j]: 
    376                             most = j 
    377                             break 
    378                     #print "after %s: start=%d most=%d" % (match, start, most) 
    379                     if most == start: 
    380                         break 
    381                 if most > start: 
    382                     self.AppendText(matched[start:most]) 
     401                input = self.GetValue() 
     402                text = dd.getLargestCommon(input) 
     403                if text != input: 
     404                    self.SetValue(text) 
    383405                    self.SetInsertionPointEnd() 
     406                else: 
     407                    self._tabCount = 1 
    384408                self._tabCount += 1 
    385409                if self._tabCount > 1: 
    386410                    # scroll the list on multiple consecutive tabs 
    387                     dd = self.dropdownlistbox 
    388                     count = dd.GetItemCount() 
    389                     page = dd.GetCountPerPage() 
    390                     sel = dd.GetFirstSelected() 
    391                     sel += page 
    392                     if sel >= count: 
    393                         sel = 0 
    394                     dd.Select(sel) 
    395                     dd.EnsureVisible(sel) 
    396  
    397                     # Lacking some "EnsureVisibleIsAtTop" method, make 
    398                     # the selected item at the top of the list by 
    399                     # forcing some more entries to be visible. 
    400                     bot = sel + page - 1 
    401                     if bot >= count: 
    402                         bot = count - 1 
    403                     dd.EnsureVisible(bot) 
     411                    if event.GetModifiers() & wx.MOD_SHIFT: 
     412                        dd.selectPrevMatch() 
     413                    else: 
     414                        dd.selectNextMatch() 
    404415                         
    405416            skip = False 
     
    446457        event.Skip() 
    447458 
    448     # -- Interfaces methods 
    449     def SetMultipleChoices(self, choices, colSearch=0, colFetch=-1): 
    450         """ Set multi-column choice 
    451         """ 
    452         self._multiChoices = choices 
    453         self._choices = None 
    454         if not isinstance(self._multiChoices, list): 
    455             self._multiChoices = [ x for x in self._multiChoices] 
    456         flags = wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_SORT_ASCENDING 
    457         if not self._showHead: 
    458             flags |= wx.LC_NO_HEADER 
    459         self.dropdownlistbox.SetWindowStyleFlag(flags) 
    460         #prevent errors on "old" systems 
    461         if sys.version.startswith("2.3"): 
    462             self._multiChoices.sort(lambda x, y: cmp(x[0].lower(), y[0].lower())) 
    463         else: 
    464             self._multiChoices.sort(key=lambda x: locale.strxfrm(x[0]).lower() ) 
    465         self._updateDataList(self._multiChoices) 
    466         lChoices = len(choices) 
    467         if lChoices < 2: 
    468             raise ValueError, "You have to pass me a multi-dimension list" 
    469         for numCol, rowValues in enumerate(choices[0]): 
    470             if self._colNames: colName = self._colNames[numCol] 
    471             else: colName = "Select %i" % numCol 
    472             self.dropdownlistbox.InsertColumn(numCol, colName) 
    473         for numRow, valRow in enumerate(choices): 
    474             for numCol, colVal in enumerate(valRow): 
    475                 if numCol == 0: 
    476                     index = self.dropdownlistbox.InsertImageStringItem(sys.maxint, colVal, -1) 
    477                 self.dropdownlistbox.SetStringItem(index, numCol, colVal) 
    478                 self.dropdownlistbox.SetItemData(index, numRow) 
    479         self._setListSize() 
    480         self._colSearch = colSearch 
    481         self._colFetch = colFetch 
    482  
    483459    def SetChoices(self, choices): 
    484460        """ 
     
    486462        The items will be sorted case insensitively. 
    487463        """ 
    488         self._choices = choices 
    489         self._multiChoices = None 
    490         flags = wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_SORT_ASCENDING | wx.LC_NO_HEADER 
    491         self.dropdownlistbox.SetWindowStyleFlag(flags) 
    492464        if not isinstance(choices, list): 
    493465            self._choices = [ x for x in choices] 
     466        else: 
     467            self._choices = choices 
     468        self.dropdownlistbox.setChoices(self._choices) 
    494469        #prevent errors on "old" systems 
    495470        if sys.version.startswith("2.3"): 
     
    500475            except UnicodeEncodeError: 
    501476                self._choices.sort(key=lambda x: locale.strxfrm(x.encode("UTF-8")).lower()) 
    502         self._updateDataList(self._choices) 
    503         self.dropdownlistbox.InsertColumn(0, "") 
    504         for num, colVal in enumerate(self._choices): 
    505             index = self.dropdownlistbox.InsertImageStringItem(sys.maxint, colVal, -1) 
    506             self.dropdownlistbox.SetStringItem(index, 0, colVal) 
    507             self.dropdownlistbox.SetItemData(index, num) 
    508477        self._setListSize() 
    509         # there is only one choice for both search and fetch if setting a single column: 
    510         self._colSearch = 0 
    511         self._colFetch = -1 
    512478 
    513479    def GetChoices(self): 
    514         if self._choices: 
    515             return self._choices 
    516         else: 
    517             return self._multiChoices 
     480        return self._choices 
    518481 
    519482    def SetSelectCallback(self, cb=None): 
     
    528491    #-- Internal methods 
    529492    def _setValueFromSelected( self ) : 
    530          """ 
    531          Sets the wx.TextCtrl value from the selected wx.ListCtrl item. 
    532          Will do nothing if no item is selected in the wx.ListCtrl. 
    533          """ 
    534          sel = self.dropdownlistbox.GetFirstSelected() 
    535          if sel > -1: 
    536             if self._colFetch != -1: col = self._colFetch 
    537             else: col = self._colSearch 
    538             itemtext = self.dropdownlistbox.GetItem(sel, col).GetText() 
    539             if self._selectCallback: 
    540                 dd = self.dropdownlistbox 
    541                 values = [dd.GetItem(sel, x).GetText() 
    542                     for x in xrange(dd.GetColumnCount())] 
    543                 self._selectCallback( values ) 
     493        """ 
     494        Sets the wx.TextCtrl value from the selected wx.ListCtrl item. 
     495        Will do nothing if no item is selected in the wx.ListCtrl. 
     496        """ 
     497        sel = self.dropdownlistbox.GetSelection() 
     498        if sel > -1: 
     499            itemtext = self._choices[sel] 
    544500            self.SetValue (itemtext) 
    545501            self.SetInsertionPointEnd () 
    546             self.SetSelection ( -1, -1 ) 
     502            self.SetSelection(-1, -1) 
    547503            self._showDropDown ( False ) 
    548504 
     
    569525        Moves the selected item to the top of the list ensuring it is always visible. 
    570526        """ 
    571         toSel =  self.dropdownlistbox.GetFirstSelected () 
     527        toSel =  self.dropdownlistbox.GetSelection () 
    572528        if toSel == -1: return 
    573         self.dropdownlistbox.EnsureVisible( toSel ) 
    574  
    575     def _updateDataList(self, choices): 
    576         #delete, if need, all the previous data 
    577         if self.dropdownlistbox.GetColumnCount() != 0: 
    578             self.dropdownlistbox.DeleteAllColumns() 
    579             self.dropdownlistbox.DeleteAllItems() 
    580         #and update the dict 
    581         if choices: 
    582             for numVal, data in enumerate(choices): 
    583                 self.itemDataMap[numVal] = data 
    584         else: 
    585             numVal = 0 
    586         self.SetColumnCount(numVal) 
     529        self.dropdownlistbox.SetSelection( toSel ) 
    587530 
    588531    def _setListSize(self): 
    589         if self._multiChoices: 
    590             choices = self._multiChoices 
    591         else: 
    592             choices = self._choices 
     532        choices = self._choices 
    593533        longest = 0 
    594534        for choice in choices : 
     
    694634        if c.startswith(t): return True 
    695635        if c.startswith('www.'): c = c[4:] 
    696         return c.startswith(t) 
     636        if c.startswith(t): 
     637            return 0, len(t) 
     638        return -1, 0 
    697639 
    698640    def setDynamicChoices(self): 
     
    715657                    'aegis', 'ascertain', 'asteroid', 
    716658                    'beautiful', 'bold', 'classic', 
    717                     'daring', 'dazzling', 'debonair', 'definitive', 
     659                    'daring', 'daft', 'debonair', 'definitive', 'defective', 
    718660                    'effective', 'elegant', 
    719661                    'http://python.org', 'http://www.google.com', 
    720662                    'fabulous', 'fantastic', 'friendly', 'forgiving', 'feature', 
    721663                    'sage', 'scarlet', 'scenic', 'seaside', 'showpiece', 'spiffy', 
    722                     'www.wxPython.org', 'www.osafoundation.org' 
     664                    'www.wxPython.org', 'www.osafoundation.org', 
     665                    'zqqqq1', 'zqqqq2222', 'zqqqq2228', 
    723666                    ] 
    724667    app = wx.PySimpleApp()