Applied patch from Pim Van Heuven that modifies 4 files:
- wxPython/demo/ListCtrl_edit.py (new demo)
    - wxPython/demo/Main.py (include new demo in demo app)
    - wxPython/wx/lib/mixins/listctrl.py (several improvements to
      TextEditMixin)
    - wxPython/wx/lib/wxpTag.py (some small fixes)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29883 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
			
			
This commit is contained in:
		
							
								
								
									
										142
									
								
								wxPython/demo/ListCtrl_edit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								wxPython/demo/ListCtrl_edit.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| #---------------------------------------------------------------------------- | ||||
| # Name:         ListCtrl_edit.py | ||||
| # Purpose:      Testing editing a ListCtrl | ||||
| # | ||||
| # Author:       Pim van Heuven | ||||
| # | ||||
| # Created:      2004/10/15 | ||||
| # Copyright:    (c) Pim Van Heuven | ||||
| # Licence:      wxWindows license | ||||
| #---------------------------------------------------------------------------- | ||||
|  | ||||
| import sys | ||||
| import  wx | ||||
| import  wx.lib.mixins.listctrl  as  listmix | ||||
|  | ||||
| #--------------------------------------------------------------------------- | ||||
|  | ||||
| listctrldata = { | ||||
| 1 : ("Hey!", "You can edit", "me!"), | ||||
| 2 : ("Try changing the contents", "by", "clicking"), | ||||
| 3 : ("in", "a", "cell"), | ||||
| 4 : ("See how the length columns", "change", "?"), | ||||
| 5 : ("You can use", "TAB,", "cursor down,"), | ||||
| 6 : ("and cursor up", "to", "navigate"), | ||||
| } | ||||
|  | ||||
| #--------------------------------------------------------------------------- | ||||
|  | ||||
| class TestListCtrl(wx.ListCtrl, | ||||
|                    listmix.ListCtrlAutoWidthMixin, | ||||
|                    listmix.TextEditMixin): | ||||
|  | ||||
|     def __init__(self, parent, ID, pos=wx.DefaultPosition, | ||||
|                  size=wx.DefaultSize, style=0): | ||||
|         wx.ListCtrl.__init__(self, parent, ID, pos, size, style) | ||||
|  | ||||
|         # Divide remaining space over all columns | ||||
|         listmix.ListCtrlAutoWidthMixin.__init__(self, 0, 3) | ||||
|         self.Populate() | ||||
|         listmix.TextEditMixin.__init__(self) | ||||
|  | ||||
|     def Populate(self): | ||||
|         # for normal, simple columns, you can add them like this: | ||||
|         self.InsertColumn(0, "Column 1") | ||||
|         self.InsertColumn(1, "Column 2") | ||||
|         self.InsertColumn(2, "Column 3") | ||||
|         self.InsertColumn(3, "Len 1", wx.LIST_FORMAT_RIGHT) | ||||
|         self.InsertColumn(4, "Len 2", wx.LIST_FORMAT_RIGHT) | ||||
|         self.InsertColumn(5, "Len 3", wx.LIST_FORMAT_RIGHT) | ||||
|  | ||||
|         items = listctrldata.items() | ||||
|         for key, data in items: | ||||
|             index = self.InsertStringItem(sys.maxint, data[0]) | ||||
|             self.SetStringItem(index, 0, data[0]) | ||||
|             self.SetStringItem(index, 1, data[1]) | ||||
|             self.SetStringItem(index, 2, data[2]) | ||||
|             self.SetItemData(index, key) | ||||
|  | ||||
|         self.SetColumnWidth(0, wx.LIST_AUTOSIZE) | ||||
|         self.SetColumnWidth(1, wx.LIST_AUTOSIZE) | ||||
|         self.SetColumnWidth(2, 100) | ||||
|  | ||||
|         self.currentItem = 0 | ||||
|  | ||||
|  | ||||
|     def SetStringItem(self, index, col, data): | ||||
|         if col in range(3): | ||||
|             wx.ListCtrl.SetStringItem(self, index, col, data) | ||||
|             wx.ListCtrl.SetStringItem(self, index, 3+col, str(len(data))) | ||||
|         else: | ||||
|             try: | ||||
|                 datalen = int(data) | ||||
|             except: | ||||
|                 return | ||||
|  | ||||
|             wx.ListCtrl.SetStringItem(self, index, col, data) | ||||
|  | ||||
|             data = self.GetItem(index, col-3).GetText() | ||||
|             wx.ListCtrl.SetStringItem(self, index, col-3, data[0:datalen]) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| class TestListCtrlPanel(wx.Panel): | ||||
|     def __init__(self, parent, log): | ||||
|         wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS) | ||||
|  | ||||
|         self.log = log | ||||
|         tID = wx.NewId() | ||||
|  | ||||
|         self.list = TestListCtrl(self, tID, | ||||
|                                  style=wx.LC_REPORT | ||||
|                                  | wx.BORDER_NONE | ||||
|                                  | wx.LC_SORT_ASCENDING | ||||
|                                  ) | ||||
|  | ||||
|         self.Bind(wx.EVT_SIZE, self.OnSize) | ||||
|  | ||||
|  | ||||
|     def OnSize(self, event): | ||||
|         w,h = self.GetClientSizeTuple() | ||||
|         self.list.SetDimensions(0, 0, w, h) | ||||
|  | ||||
|  | ||||
|  | ||||
| #--------------------------------------------------------------------------- | ||||
|  | ||||
| def runTest(frame, nb, log): | ||||
|     win = TestListCtrlPanel(nb, log) | ||||
|     return win | ||||
|  | ||||
| #--------------------------------------------------------------------------- | ||||
|  | ||||
|  | ||||
| overview = """\ | ||||
| <html> | ||||
| <body> | ||||
|  | ||||
| This demo demonstrates direct editing of all cells of a ListCtrl. To | ||||
| enable it just include the <b>TextEditMixin</b>. The ListCtrl can be | ||||
| navigated with the TAB and up/down cursor keys. | ||||
|  | ||||
| <p>Another facet of this demo is that the remaining space of the | ||||
| ListCtrls is divided over the first three columns. This is achieved | ||||
| with the extended syntax of <b>ListCtrlAutoWidthMixin</b>: | ||||
| <code>listmix.ListCtrlAutoWidthMixin.__init__(self, startcol, endcol)</code> | ||||
| (Look at the general ListCtrl demo for more information about the | ||||
| ListCtrlAutoWidthMixin) | ||||
|  | ||||
| <p>Finally, the ListCtrl is automatically scrolled, if needed, when | ||||
| TAB is pressed consecutively (Windows only). | ||||
|  | ||||
| </body> | ||||
| </html> | ||||
| """ | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     import sys,os | ||||
|     import run | ||||
|     run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) | ||||
|  | ||||
| @@ -50,6 +50,7 @@ _treeList = [ | ||||
|         'StockButtons', | ||||
|         'Ticker', | ||||
|         'Choicebook', | ||||
|         'ListCtrl_edit', | ||||
|         ]), | ||||
|  | ||||
|     # managed windows == things with a (optional) caption you can close | ||||
| @@ -98,6 +99,7 @@ _treeList = [ | ||||
|         'ListBox', | ||||
|         'ListCtrl', | ||||
|         'ListCtrl_virtual', | ||||
|         'ListCtrl_edit', | ||||
|         'Listbook', | ||||
|         'Menu', | ||||
|         'Notebook', | ||||
|   | ||||
| @@ -165,6 +165,16 @@ MaskedEdit updates from Will Sadkin: | ||||
|     - lots of doc string improvements and function hiding to better | ||||
|       reflect package's public contents. | ||||
|  | ||||
| Restructured the installer packages slightly to help facilitate having | ||||
| multiple versions of wxPython installed at the same time.  See the | ||||
| Migrarion Guide for more information. | ||||
|  | ||||
| Applied patch from Pim Van Heuven that modifies 4 files: | ||||
|     - wxPython/demo/ListCtrl_edit.py (new demo) | ||||
|     - wxPython/demo/Main.py (include new demo in demo app) | ||||
|     - wxPython/wx/lib/mixins/listctrl.py (several improvements to  | ||||
|       TextEditMixin) | ||||
|     - wxPython/wx/lib/wxpTag.py (some small fixes) | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,14 @@ | ||||
| # | ||||
| # o wxColumnSorterMixin -> ColumnSorterMixin  | ||||
| # o wxListCtrlAutoWidthMixin -> ListCtrlAutoWidthMixin | ||||
| # ... | ||||
| # 13/10/2004 - Pim Van Heuven (pim@think-wize.com) | ||||
| # o wxTextEditMixin: Support Horizontal scrolling when TAB is pressed on long | ||||
| #       ListCtrls, support for WXK_DOWN, WXK_UP, performance improvements on | ||||
| #       very long ListCtrls, Support for virtual ListCtrls | ||||
| # | ||||
| # 15-Oct-2004 - Robin Dunn | ||||
| # o wxTextEditMixin: Added Shift-TAB support | ||||
| # | ||||
|  | ||||
| import  locale | ||||
| @@ -374,21 +382,34 @@ class TextEditMixin: | ||||
|         #editor = wx.TextCtrl(self, -1, pos=(-1,-1), size=(-1,-1), | ||||
|         #                     style=wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB \ | ||||
|         #                     |wx.TE_RICH2) | ||||
|  | ||||
|         self.make_editor() | ||||
|         self.Bind(wx.EVT_TEXT_ENTER, self.CloseEditor) | ||||
|         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) | ||||
|         self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown) | ||||
|         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) | ||||
|  | ||||
|  | ||||
|     def make_editor(self, col_style=wx.LIST_FORMAT_LEFT): | ||||
|         editor = wx.PreTextCtrl() | ||||
|         editor.Hide() | ||||
|         editor.Create(self, -1, style=wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB|wx.TE_RICH2) | ||||
|          | ||||
|         style =wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB|wx.TE_RICH2 | ||||
|         style |= {wx.LIST_FORMAT_LEFT: wx.TE_LEFT, wx.LIST_FORMAT_RIGHT: wx.TE_RIGHT, wx.LIST_FORMAT_CENTRE : wx.TE_CENTRE}[col_style] | ||||
|          | ||||
|         editor.Create(self, -1, style=style) | ||||
|         editor.SetBackgroundColour(wx.Colour(red=255,green=255,blue=175)) #Yellow | ||||
|         font = self.GetFont() | ||||
|         editor.SetFont(font) | ||||
|  | ||||
|         self.curRow = 0 | ||||
|         self.curCol = 0 | ||||
|  | ||||
|         editor.Hide() | ||||
|         self.editor = editor | ||||
|         self.Bind(wx.EVT_TEXT_ENTER, self.CloseEditor) | ||||
|  | ||||
|         self.col_style = col_style | ||||
|         self.editor.Bind(wx.EVT_CHAR, self.OnChar) | ||||
|         self.editor.Bind(wx.EVT_KILL_FOCUS, self.CloseEditor) | ||||
|         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) | ||||
|         self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDown) | ||||
|         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) | ||||
|         self.curRow = -1 | ||||
|          | ||||
|          | ||||
|     def OnItemSelected(self, evt): | ||||
| @@ -397,11 +418,35 @@ class TextEditMixin: | ||||
|          | ||||
|  | ||||
|     def OnChar(self, event): | ||||
|         ''' Catch the TAB key code so we can open the editor at the next column (if any).''' | ||||
|         if event.GetKeyCode() == wx.WXK_TAB: | ||||
|         ''' Catch the TAB, Shift-TAB, cursor DOWN/UP key code | ||||
|             so we can open the editor at the next column (if any).''' | ||||
|  | ||||
|         keycode = event.GetKeyCode() | ||||
|         if keycode == wx.WXK_TAB and event.ShiftDown(): | ||||
|             self.CloseEditor() | ||||
|             if self.curCol-1 >= 0: | ||||
|                 self.OpenEditor(self.curCol-1, self.curRow) | ||||
|              | ||||
|         elif keycode == wx.WXK_TAB: | ||||
|             self.CloseEditor() | ||||
|             if self.curCol+1 < self.GetColumnCount(): | ||||
|                 self.OpenEditor(self.curCol+1, self.curRow) | ||||
|  | ||||
|         elif keycode == wx.WXK_ESCAPE: | ||||
|             self.CloseEditor() | ||||
|  | ||||
|         elif keycode == wx.WXK_DOWN: | ||||
|             self.CloseEditor() | ||||
|             if self.curRow+1 < self.GetItemCount(): | ||||
|                 self._SelectIndex(self.curRow+1) | ||||
|                 self.OpenEditor(self.curCol, self.curRow) | ||||
|  | ||||
|         elif keycode == wx.WXK_UP: | ||||
|             self.CloseEditor() | ||||
|             if self.curRow > 0: | ||||
|                 self._SelectIndex(self.curRow-1) | ||||
|                 self.OpenEditor(self.curCol, self.curRow) | ||||
|              | ||||
|         else: | ||||
|             event.Skip() | ||||
|  | ||||
| @@ -432,20 +477,49 @@ class TextEditMixin: | ||||
|             loc = loc + self.GetColumnWidth(n) | ||||
|             self.col_locs.append(loc) | ||||
|  | ||||
|         col = bisect(self.col_locs, x) - 1 | ||||
|          | ||||
|         col = bisect(self.col_locs, x+self.GetScrollPos(wx.HORIZONTAL)) - 1 | ||||
|         self.OpenEditor(col, row) | ||||
|  | ||||
|  | ||||
|     def OpenEditor(self, col, row): | ||||
|         ''' Opens an editor at the current position. ''' | ||||
|  | ||||
|         if self.GetColumn(col).m_format != self.col_style: | ||||
|             self.make_editor(self.GetColumn(col).m_format) | ||||
|      | ||||
|         x0 = self.col_locs[col] | ||||
|         x1 = self.col_locs[col+1] - x0 | ||||
|  | ||||
|         scrolloffset = self.GetScrollPos(wx.HORIZONTAL) | ||||
|  | ||||
|         # scroll foreward | ||||
|         if x0+x1-scrolloffset > self.GetSize()[0]: | ||||
|             if wx.Platform == "__WXMSW__": | ||||
|                 # don't start scrolling unless we really need to | ||||
|                 offset = x0+x1-self.GetSize()[0]-scrolloffset | ||||
|                 # scroll a bit more than what is minimum required | ||||
|                 # so we don't have to scroll everytime the user presses TAB | ||||
|                 # which is very tireing to the eye | ||||
|                 addoffset = self.GetSize()[0]/4 | ||||
|                 # but be careful at the end of the list | ||||
|                 if addoffset + scrolloffset < self.GetSize()[0]: | ||||
|                     offset += addoffset | ||||
|  | ||||
|                 self.ScrollList(offset, 0) | ||||
|                 scrolloffset = self.GetScrollPos(wx.HORIZONTAL) | ||||
|             else: | ||||
|                 # Since we can not programmatically scroll the ListCtrl | ||||
|                 # close the editor so the user can scroll and open the editor | ||||
|                 # again | ||||
|                 self.CloseEditor() | ||||
|                 return | ||||
|  | ||||
|         y0 = self.GetItemRect(row)[1] | ||||
|          | ||||
|         editor = self.editor | ||||
|         editor.SetDimensions(x0,y0, x1,-1) | ||||
|         editor.SetDimensions(x0-scrolloffset,y0, x1,-1) | ||||
|          | ||||
|         editor.SetValue(self.GetItem(row, col).GetText())  | ||||
|         editor.Show() | ||||
|         editor.Raise() | ||||
| @@ -460,7 +534,26 @@ class TextEditMixin: | ||||
|         ''' Close the editor and save the new value to the ListCtrl. ''' | ||||
|         text = self.editor.GetValue() | ||||
|         self.editor.Hide() | ||||
|         self.SetStringItem(self.curRow, self.curCol, text) | ||||
|         if self.IsVirtual(): | ||||
|             # replace by whather you use to populate the virtual ListCtrl | ||||
|             # data source | ||||
|             self.SetVirtualData(self.curRow, self.curCol, text) | ||||
|         else: | ||||
|             self.SetStringItem(self.curRow, self.curCol, text) | ||||
|         self.RefreshItem(self.curRow) | ||||
|  | ||||
|     def _SelectIndex(self, row): | ||||
|         listlen = self.GetItemCount() | ||||
|         if row < 0 and not listlen: | ||||
|             return | ||||
|         if row > (listlen-1): | ||||
|             row = listlen -1 | ||||
|              | ||||
|         self.SetItemState(self.curRow, ~wx.LIST_STATE_SELECTED, | ||||
|                           wx.LIST_STATE_SELECTED) | ||||
|         self.EnsureVisible(row) | ||||
|         self.SetItemState(row, wx.LIST_STATE_SELECTED, | ||||
|                           wx.LIST_STATE_SELECTED) | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -195,7 +195,7 @@ class wxpTagHandler(wx.html.HtmlWinTagHandler): | ||||
|  | ||||
|  | ||||
|         # check for something that should be evaluated | ||||
|         elif value[0] in '[{(' or value[:2] == 'wx': | ||||
|         elif value and value[0] in '[{(' or value[:2] == 'wx': | ||||
|             saveVal = value | ||||
|             try: | ||||
|                 value = eval(value, self.ctx.classMod.__dict__) | ||||
| @@ -203,7 +203,7 @@ class wxpTagHandler(wx.html.HtmlWinTagHandler): | ||||
|                 value = saveVal | ||||
|  | ||||
|         # convert to wx.Colour | ||||
|         elif value[0] == '#': | ||||
|         elif value and value[0] == '#': | ||||
|             try: | ||||
|                 red   = int('0x'+value[1:3], 16) | ||||
|                 green = int('0x'+value[3:5], 16) | ||||
| @@ -212,7 +212,8 @@ class wxpTagHandler(wx.html.HtmlWinTagHandler): | ||||
|             except: | ||||
|                 pass | ||||
|  | ||||
|         self.ctx.kwargs[str(name)] = value | ||||
|         if self.ctx: | ||||
|           self.ctx.kwargs[str(name)] = value | ||||
|         return False | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user