text: '''
  wxPython Custom Widget Collection 20060207
  Written By: Edward Flick (eddy -=at=- cdf-imaging -=dot=- com)
              Michele Petrazzo (michele -=dot=- petrazzo -=at=- unipex -=dot=- it)
              Will Sadkin (wsadkin-=at=- nameconnector -=dot=- com)
  Copyright 2006 (c) CDF Inc. ( http://www.cdf-imaging.com )
  Contributed to the wxPython project under the wxPython project's license.
  '''
  import locale, wx, sys
  # import StringIO
  import  wx.lib.mixins.listctrl  as  listmix
  from wx import ImageFromStream, BitmapFromImage, Image
  
  import os
  
  import logging.config
  from src.view.constants import LOG_SETTINGS
  
  logging.config.dictConfig(LOG_SETTINGS)
  logger = logging.getLogger('extensive')
  
  
  #----------------------------------------------------------------------
  def getSmallUpArrowData():
      return \
  '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
  \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
  \x00\x00<IDAT8\x8dcddbf\xa0\x040Q\xa4{h\x18\xf0\xff\xdf\xdf\xffd\x1b\x00\xd3\
  \x8c\xcf\x10\x9c\x06\xa0k\xc2e\x08m\xc2\x00\x97m\xd8\xc41\x0c \x14h\xe8\xf2\
  \x8c\xa3)q\x10\x18\x00\x00R\xd8#\xec\xb2\xcd\xc1Y\x00\x00\x00\x00IEND\xaeB`\
  \x82'
  
  
  def getSmallUpArrowBitmap():
      return wx.Bitmap(getSmallUpArrowImage())
  
  
  def getSmallUpArrowImage():
      path = os.path.abspath(__file__)
      tail = None
      while tail != 'src':
          path = os.path.abspath(os.path.join(path, '..'))
          head, tail = os.path.split(path)
          
      imageLocation = os.path.join(path, "images")
      image = wx.Image(os.path.join(imageLocation, "bullet_arrow_up.png"), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
      
  #     stream = StringIO.StringIO(getSmallDnArrowData())
      return image
  #     stream = io.StringIO(getSmallUpArrowData())
  #     return wx.ImageFromStream(stream)
  
  
  def getSmallDnArrowData():
      return \
  "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
  \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
  \x00\x00HIDAT8\x8dcddbf\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16t\x81\
  \xff\xff\xfe\xfe'\xa4\x89\x91\x89\x99\x11\xa7\x0b\x90%\ti\xc6j\x00>C\xb0\x89\
  \xd3.\x10\xd1m\xc3\xe5*\xbc.\x80i\xc2\x17.\x8c\xa3y\x81\x01\x00\xa1\x0e\x04e\
  ?\x84B\xef\x00\x00\x00\x00IEND\xaeB`\x82"
  
  
  def getSmallDnArrowBitmap():
      return wx.Bitmap(getSmallDnArrowImage())
  
  
  def getSmallDnArrowImage():
      
      path = os.path.abspath(__file__)
      tail = None
      while tail != 'src':
          path = os.path.abspath(os.path.join(path, '..'))
          head, tail = os.path.split(path)
          
      imageLocation = os.path.join(path, "images")
      image = wx.Image(os.path.join(imageLocation, "bullet_arrow_down.png"), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
      
  #     stream = StringIO.StringIO(getSmallDnArrowData())
      return image
  
  
  #----------------------------------------------------------------------
  class myListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
  
      def __init__(self, parent, ID=-1, pos=wx.DefaultPosition,
                   size=wx.DefaultSize, style=0):
          wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
          listmix.ListCtrlAutoWidthMixin.__init__(self)
  
  
  class TextCtrlAutoComplete (wx.TextCtrl, listmix.ColumnSorterMixin):
      
      def __init__ (self, parent, id=-1, colNames=None, choices=None,
                    multiChoices=None, showHead=True, dropDownClick=True,
                    colFetch=-1, colSearch=0, hideOnNoMatch=True, size=wx.DefaultSize,
                    selectCallback=None, entryCallback=None, matchFunction=None,
                    **therest) :
          '''
          Constructor works just like wx.TextCtrl except you can pass in a
          list of choices.  You can also change the choice list at any time
          by calling setChoices.
          '''
          if 'style' in therest:
              therest['style'] = wx.TE_PROCESS_ENTER | therest['style']
          else:
              therest['style'] = wx.TE_PROCESS_ENTER
          wx.TextCtrl.__init__(self, parent, id=id, size=size, **therest)
          # Some variables
          self.SetToolTip('Select database')
          self._dropDownClick = dropDownClick
          self._colNames = colNames
          self._multiChoices = multiChoices
          self._showHead = showHead
          self._choices = choices
          self._lastinsertionpoint = 0
          self._hideOnNoMatch = hideOnNoMatch
          self._selectCallback = selectCallback
          self._entryCallback = entryCallback
          self._matchFunction = matchFunction
          self._screenheight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
          # sort variable needed by listmix
          self.itemDataMap = dict()
          # Load and sort data
          if not (self._multiChoices or self._choices):
              raise ValueError("Pass me at least one of multiChoices OR choices")
          # widgets
          self.dropdown = wx.PopupWindow(self)
          # Control the style
          flags = wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_SORT_ASCENDING
          if not (showHead and multiChoices) :
              flags = flags | wx.LC_NO_HEADER
          # Create the list and bind the events
          self.dropdownlistbox = myListCtrl(self.dropdown, style=flags,
                                   pos=wx.Point(0, 0))
          # initialize the parent
          if multiChoices: ln = len(multiChoices)
          else: ln = 1
          # else: ln = len(choices)
          listmix.ColumnSorterMixin.__init__(self, ln)
          # load the data
          if multiChoices: self.SetMultipleChoices (multiChoices, colSearch=colSearch, colFetch=colFetch)
          else: self.SetChoices (choices)
          gp = self
          while gp != None :
              gp.Bind (wx.EVT_MOVE , self.onControlChanged, gp)
              gp.Bind (wx.EVT_SIZE , self.onControlChanged, gp)
              gp = gp.GetParent()
          self.Bind(wx.EVT_KILL_FOCUS, self.onControlChanged, self)
          self.Bind(wx.EVT_TEXT , self.onEnteredText, self)
          self.Bind(wx.EVT_KEY_DOWN , self.onKeyDown, self)
          # If need drop down on left click
          if dropDownClick:
              self.Bind (wx.EVT_LEFT_DOWN , self.onClickToggleDown, self)
              self.Bind (wx.EVT_LEFT_UP , self.onClickToggleUp, self)
          self.dropdown.Bind(wx.EVT_LISTBOX , self.onListItemSelected, self.dropdownlistbox)
          self.dropdownlistbox.Bind(wx.EVT_LEFT_DOWN, self.onListClick)
          self.dropdownlistbox.Bind(wx.EVT_LEFT_DCLICK, self.onListDClick)
          self.dropdownlistbox.Bind(wx.EVT_LIST_COL_CLICK, self.onListColClick)
          self.il = wx.ImageList(16, 16)
          self.sm_dn = self.il.Add(getSmallDnArrowBitmap())
          self.sm_up = self.il.Add(getSmallUpArrowBitmap())
          self.dropdownlistbox.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
          self._ascending = True
  
      # -- methods called from mixin class
      def GetSortImages(self):
          return (self.sm_dn, self.sm_up)
  
      def GetListCtrl(self):
          return self.dropdownlistbox
      # -- event methods
  
      def onListClick(self, evt):
          toSel, flag = self.dropdownlistbox.HitTest(evt.GetPosition())
          # no values on poition, return
          if toSel == -1: return
          self.dropdownlistbox.Select(toSel)
  
      def onListDClick(self, evt):
          self._setValueFromSelected()
  
      def onListColClick(self, evt):
          col = evt.GetColumn()
          # reverse the sort
          if col == self._colSearch:
              self._ascending = not self._ascending
          self.SortListItems(evt.GetColumn(), ascending=self._ascending)
          self._colSearch = evt.GetColumn()
          evt.Skip()
  
      def onEnteredText(self, event):
          logger.info('onEnteredText')
          try:
              text = event.GetString()
  #             if self._entryCallback:
  #                 self._entryCallback()
              if not text:
                  # control is empty; hide dropdown if shown:
                  if self.dropdown.IsShown():
                      self._showDropDown(False)
                  event.Skip()
                  return
              found = False
              if self._multiChoices:
                  # load the sorted data into the listbox
                  dd = self.dropdownlistbox
                  choices = [dd.GetItem(x, self._colSearch).GetText()
                      for x in range(dd.GetItemCount())]
              else:
                  choices = self._choices
              for numCh, choice in enumerate(choices):
                  if self._matchFunction and self._matchFunction(text, choice):
                      found = True
                  elif choice.lower().startswith(text.lower()) :
                      found = True
                  if found:
                      self._showDropDown(True)
                      item = self.dropdownlistbox.GetItem(numCh)
                      toSel = item.GetId()
                      self.dropdownlistbox.Select(toSel)
                      break
              if not found:
                  self.dropdownlistbox.Select(self.dropdownlistbox.GetFirstSelected(), False)
                  if self._hideOnNoMatch:
                      self._showDropDown(False)
              self._listItemVisible()
              event.Skip ()
          except Exception as e:
              logger.error(e, exc_info=True)
  
      def onKeyDown (self, event) :
          """ Do some work when the user press on the keys:
              up and down: move the cursor
              left and right: move the search
          """
          logger.info('onKeyDown')
          try:
              skip = True
              sel = self.dropdownlistbox.GetFirstSelected()
              visible = self.dropdown.IsShown()
              KC = event.GetKeyCode()
              if KC == wx.WXK_DOWN :
                  if sel < self.dropdownlistbox.GetItemCount () - 1:
                      self.dropdownlistbox.Select (sel + 1)
                      self._listItemVisible()
                  self._showDropDown ()
                  skip = False
              elif KC == wx.WXK_UP :
                  if sel > 0 :
                      self.dropdownlistbox.Select (sel - 1)
                      self._listItemVisible()
                  self._showDropDown ()
                  skip = False
              elif KC == wx.WXK_LEFT :
                  if not self._multiChoices: return
                  if self._colSearch > 0:
                      self._colSearch -= 1
                  self._showDropDown ()
              elif KC == wx.WXK_RIGHT:
                  if not self._multiChoices: return
                  if self._colSearch < self.dropdownlistbox.GetColumnCount() - 1:
                      self._colSearch += 1
                  self._showDropDown()
              if visible :
                  if event.GetKeyCode() == wx.WXK_RETURN :
                      self._setValueFromSelected()
                      skip = False
                  if event.GetKeyCode() == wx.WXK_ESCAPE :
                      self._showDropDown(False)
                      skip = False
              if skip :
                  event.Skip()
          except Exception as e:
              logger.error(e, exc_info=True)
  
      def onListItemSelected (self, event):
          self._setValueFromSelected()
          event.Skip()
  
      def onClickToggleDown(self, event):
          self._lastinsertionpoint = self.GetInsertionPoint()
          event.Skip ()
  
      def onClickToggleUp (self, event) :
          if self.GetInsertionPoint() == self._lastinsertionpoint :
              self._showDropDown (not self.dropdown.IsShown())
          event.Skip ()
  
      def onControlChanged(self, event):
          if self.IsShown():
              self._showDropDown(False)
          event.Skip()
  
      # -- Interfaces methods
      def SetMultipleChoices(self, choices, colSearch=0, colFetch=-1):
          ''' Set multi-column choice
          '''
          self._multiChoices = choices
          self._choices = None
          if not isinstance(self._multiChoices, list):
              self._multiChoices = list(self._multiChoices)
          flags = wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_SORT_ASCENDING
          if not self._showHead:
              flags |= wx.LC_NO_HEADER
          self.dropdownlistbox.SetWindowStyleFlag(flags)
          # prevent errors on "old" systems
  
          self._multiChoices.sort(key=lambda x: locale.strxfrm(x[0]).lower())
          self._updateDataList(self._multiChoices)
          if len(choices) < 2 or len(choices[0]) < 2:
              raise ValueError("You have to pass me a multi-dimension list with at least two entries") 
              # with only one entry, the dropdown artifacts
          for numCol, rowValues in enumerate(choices[0]):
              if self._colNames: colName = self._colNames[numCol]
              else: colName = "Select %i" % numCol
              self.dropdownlistbox.InsertColumn(numCol, colName)
          for numRow, valRow in enumerate(choices):
              for numCol, colVal in enumerate(valRow):
                  if numCol == 0:
                      index = self.dropdownlistbox.InsertItem(0, colVal)
                  self.dropdownlistbox.SetItem(index, numCol, colVal)
                  self.dropdownlistbox.SetItemData(index, numRow)
          self._setListSize()
          self._colSearch = colSearch
          self._colFetch = colFetch
  
      def SetChoices(self, choices):
          '''
          Sets the choices available in the popup wx.ListBox.
          The items will be sorted case insensitively.
          '''
          self._choices = choices
          self._multiChoices = None
          flags = wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_SORT_ASCENDING | wx.LC_NO_HEADER
          self.dropdownlistbox.SetWindowStyleFlag(flags)
          if not isinstance(choices, list):
              self._choices = list(choices)
          # prevent errors on "old" systems
  
          self._choices.sort(key=lambda x: locale.strxfrm(x).lower())
          self._updateDataList(self._choices)
          self.dropdownlistbox.InsertColumn(0, "")
          for num, colVal in enumerate(self._choices):
              index = self.dropdownlistbox.InsertItem(0, colVal)
              self.dropdownlistbox.SetItem(index, 0, colVal)
              self.dropdownlistbox.SetItemData(index, num)
          self._setListSize()
          # there is only one choice for both search and fetch if setting a single column:
          self._colSearch = 0
          self._colFetch = -1
  
      def GetChoices(self):
          return self._choices or self._multiChoices
  
      def SetSelectCallback(self, cb=None):
          self._selectCallback = cb
  
      def SetEntryCallback(self, cb=None):
          self._entryCallback = cb
  
      def SetMatchFunction(self, mf=None):
          self._matchFunction = mf
  
      # -- Internal methods
      def _setValueFromSelected(self) :
          '''
          Sets the wx.TextCtrl value from the selected wx.ListCtrl item.
          Will do nothing if no item is selected in the wx.ListCtrl.
          '''
          sel = self.dropdownlistbox.GetFirstSelected()
          if sel > -1:
              if self._colFetch != -1: col = self._colFetch
              else: col = self._colSearch
              itemtext = self.dropdownlistbox.GetItem(sel, col).GetText()
              if self._selectCallback:
                  dd = self.dropdownlistbox
                  values = [dd.GetItem(sel, x).GetText()
                      for x in range(dd.GetColumnCount())]
                  self._selectCallback(values)
              self.SetValue (itemtext)
              self.SetInsertionPointEnd()
              self.SetSelection (-1, -1)
              self._showDropDown (False)
  
      def _showDropDown (self, show=True) :
          '''
          Either display the drop down list (show = True) or hide it (show = False).
          '''
          if show :
              size = self.dropdown.GetSize()
              width, height = self.GetSize()
              try:
                  x, y = self.ClientToScreen(0, height)
              except Exception as ex:
                  logger.error(ex, exc_info=True)
              if size.GetWidth() != width :
                  size.SetWidth(width)
                  self.dropdown.SetSize(size)
                  self.dropdownlistbox.SetSize(self.dropdown.GetClientSize())
              if y + size.GetHeight() < self._screenheight :
                  self.dropdown . SetPosition (wx.Point(x, y))
              else:
                  self.dropdown . SetPosition (wx.Point(x, y - height - size.GetHeight()))
          self.dropdown.Show (show)
  
      def _listItemVisible(self) :
          '''
          Moves the selected item to the top of the list ensuring it is always visible.
          '''
          toSel = self.dropdownlistbox.GetFirstSelected()
          if toSel == -1: return
          self.dropdownlistbox.EnsureVisible(toSel)
  
      def _updateDataList(self, choices):
          # delete, if need, all the previous data
          if self.dropdownlistbox.GetColumnCount() != 0:
              self.dropdownlistbox.DeleteAllColumns()
              self.dropdownlistbox.DeleteAllItems()
          # and update the dict
          if choices:
              for numVal, data in enumerate(choices):
                  self.itemDataMap[numVal] = data
          else:
              numVal = 0
          self.SetColumnCount(numVal)
  
      def _setListSize(self):
          if self._multiChoices:
              choices = self._multiChoices
          else:
              choices = self._choices
          longest = 0
          for choice in choices :
              longest = max(len(choice), longest)
          longest += 3
          itemcount = min(len(choices) , 7) + 2
          charheight = self.dropdownlistbox.GetCharHeight()
          charwidth = self.dropdownlistbox.GetCharWidth()
          self.popupsize = wx.Size(charwidth * longest, charheight * itemcount)
          self.dropdownlistbox.SetSize (self.popupsize)
          self.dropdown.SetClientSize(self.popupsize)
  
  
  class test:
  
      def __init__(self):
          args = {}
          if True:
              args["colNames"] = ("col1", "col2")
              args["multiChoices"] = [ ("Zoey", "WOW"), ("Alpha", "wxPython"),
                                      ("Ceda", "Is"), ("Beta", "fantastic"),
                                      ("zoebob", "!!")]
              args["colFetch"] = 1
          else:
              args["choices"] = ["123", "cs", "cds", "Bob", "Marley", "Alpha"]
          args["selectCallback"] = self.selectCallback
          self.dynamic_choices = [
                          'aardvark', 'abandon', 'acorn', 'acute', 'adore',
                          'aegis', 'ascertain', 'asteroid',
                          'beautiful', 'bold', 'classic',
                          'daring', 'dazzling', 'debonair', 'definitive',
                          'effective', 'elegant',
                          'http://python.org', 'http://www.google.com',
                          'fabulous', 'fantastic', 'friendly', 'forgiving', 'feature',
                          'sage', 'scarlet', 'scenic', 'seaside', 'showpiece', 'spiffy',
                          'www.wxPython.org', 'www.osafoundation.org'
                          ]
          app = wx.PySimpleApp()
          frm = wx.Frame(None, -1, "Test", style=wx.TAB_TRAVERSAL | wx.DEFAULT_FRAME_STYLE)
          panel = wx.Panel(frm)
          sizer = wx.BoxSizer(wx.VERTICAL)
          self._ctrl = TextCtrlAutoComplete(panel, **args)
          but = wx.Button(panel, label="Set other multi-choice")
          but.Bind(wx.EVT_BUTTON, self.onBtMultiChoice)
          but2 = wx.Button(panel, label="Set other one-colum choice")
          but2.Bind(wx.EVT_BUTTON, self.onBtChangeChoice)
          but3 = wx.Button(panel, label="Set the starting choices")
          but3.Bind(wx.EVT_BUTTON, self.onBtStartChoices)
          but4 = wx.Button(panel, label="Enable dynamic choices")
          but4.Bind(wx.EVT_BUTTON, self.onBtDynamicChoices)
          sizer.Add(but, 0, wx.ADJUST_MINSIZE, 0)
          sizer.Add(but2, 0, wx.ADJUST_MINSIZE, 0)
          sizer.Add(but3, 0, wx.ADJUST_MINSIZE, 0)
          sizer.Add(but4, 0, wx.ADJUST_MINSIZE, 0)
          sizer.Add(self._ctrl, 0, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
          panel.SetAutoLayout(True)
          panel.SetSizer(sizer)
          sizer.Fit(panel)
          sizer.SetSizeHints(panel)
          panel.Layout()
          app.SetTopWindow(frm)
          frm.Show()
          but.SetFocus()
          app.MainLoop()
  
      def onBtChangeChoice(self, event):
          # change the choices
          self._ctrl.SetChoices(["123", "cs", "cds", "Bob", "Marley", "Alpha"])
          self._ctrl.SetEntryCallback(None)
          self._ctrl.SetMatchFunction(None)
  
      def onBtMultiChoice(self, event):
          # change the choices
          self._ctrl.SetMultipleChoices([ ("Test", "Hello"), ("Other word", "World"),
                                          ("Yes!", "it work?") ], colFetch=1)
          self._ctrl.SetEntryCallback(None)
          self._ctrl.SetMatchFunction(None)
  
      def onBtStartChoices(self, event):
          # change the choices
          self._ctrl.SetMultipleChoices([ ("Zoey", "WOW"), ("Alpha", "wxPython"),
                                      ("Ceda", "Is"), ("Beta", "fantastic"),
                                      ("zoebob", "!!")], colFetch=1)
          self._ctrl.SetEntryCallback(None)
          self._ctrl.SetMatchFunction(None)
  
      def onBtDynamicChoices(self, event):
          '''
          Demonstrate dynamic adjustment of the auto-complete list, based on what's
          been typed so far:
          '''
          self._ctrl.SetChoices(self.dynamic_choices)
          self._ctrl.SetEntryCallback(self.setDynamicChoices)
          self._ctrl.SetMatchFunction(self.match)
  
      def match(self, text, choice):
          '''
          Demonstrate "smart" matching feature, by ignoring http:// and www. when doing
          matches.
          '''
          t = text.lower()
          c = choice.lower()
          if c.startswith(t): return True
          if c.startswith(r'http://'): c = c[7:]
          if c.startswith(t): return True
          if c.startswith('www.'): c = c[4:]
          return c.startswith(t)
  
      def setDynamicChoices(self):
          ctrl = self._ctrl
          text = ctrl.GetValue().lower()
          current_choices = ctrl.GetChoices()
          choices = [choice for choice in self.dynamic_choices if self.match(text, choice)]
          if choices != current_choices:
              ctrl.SetChoices(choices)
  
      def selectCallback(self, values):
          """ Simply function that receive the row values when the
              user select an item
          """
          logger.debug("Select Callback called...: %s", values)
  
  
  class TextCtrlAutoCompletePanel(wx.Panel):
  
      def __init__(self, parent=None, *args, **kw):
          wx.Panel.__init__(self, parent, id=-1)
          self.size = (200, 30)
          self.parent = parent
          
          vBox = wx.BoxSizer(wx.VERTICAL)
          ####################################################################
          args = {}
          if True:
              args["colNames"] = ("col1", "col2")
              args["multiChoices"] = [ ("Zoey", "WOW"), ("Alpha", "wxPython"),
                                      ("Ceda", "Is"), ("Beta", "fantastic"),
                                      ("zoebob", "!!")]
              args["colFetch"] = 1
          else:
              args["choices"] = ["123", "cs", "cds", "Bob", "Marley", "Alpha"]
          args["selectCallback"] = self.selectCallback        
          self.dynamic_choices = [
                  'aardvark', 'abandon', 'acorn', 'acute', 'adore',
                  'aegis', 'ascertain', 'asteroid',
                  'beautiful', 'bold', 'classic',
                  'daring', 'dazzling', 'debonair', 'definitive',
                  'effective', 'elegant',
                  'http://python.org', 'http://www.google.com',
                  'fabulous', 'fantastic', 'friendly', 'forgiving', 'feature',
                  'sage', 'scarlet', 'scenic', 'seaside', 'showpiece', 'spiffy',
                  'www.wxPython.org', 'www.osafoundation.org'
                  ]
          self._ctrl = TextCtrlAutoComplete(self, **args)
          self._ctrl.SetChoices(self.dynamic_choices)
          self._ctrl.SetEntryCallback(self.setDynamicChoices)
          self._ctrl.SetMatchFunction(self.match)
          ####################################################################
          sizer = wx.BoxSizer(wx.VERTICAL)
          sizer.Add(self._ctrl, 0, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
          sizer.Add(vBox, 1, wx.EXPAND , 0)
          self.SetSizer(sizer)
  
      def selectCallback(self, values):
          """ Simply function that receive the row values when the
              user select an item
          """
          logger.debug("selectCallback...: %s", values)
  
      def setDynamicChoices(self):
          ctrl = self._ctrl
          text = ctrl.GetValue().lower()
          current_choices = ctrl.GetChoices()
          choices = [choice for choice in self.dynamic_choices if self.match(text, choice)]
          if choices != current_choices:
              ctrl.SetChoices(choices)
  
      def match(self, text, choice):
          '''
          Demonstrate "smart" matching feature, by ignoring http:// and www. when doing
          matches.
          '''
          t = text.lower()
          c = choice.lower()
          if c.startswith(t): return True
          if c.startswith(r'http://'): c = c[7:]
          if c.startswith(t): return True
          if c.startswith('www.'): c = c[4:]
          return c.startswith(t)
  
  
  if __name__ == "__main__":
  #     test()
      app = wx.App()
      frame = wx.Frame(None, -1, "Auto complete", style=wx.TAB_TRAVERSAL | wx.DEFAULT_FRAME_STYLE, size=(200, 300))
      panel = TextCtrlAutoCompletePanel(frame)
      frame.Show()
      app.MainLoop()
  