controls/CustomTable.py
changeset 814 5743cbdff669
child 1342 c17507a10807
equal deleted inserted replaced
813:1460273f40ed 814:5743cbdff669
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This library is free software; you can redistribute it and/or
       
     5 #modify it under the terms of the GNU General Public
       
     6 #License as published by the Free Software Foundation; either
       
     7 #version 2.1 of the License, or (at your option) any later version.
       
     8 #
       
     9 #This library is distributed in the hope that it will be useful,
       
    10 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12 #General Public License for more details.
       
    13 #
       
    14 #You should have received a copy of the GNU General Public
       
    15 #License along with this library; if not, write to the Free Software
       
    16 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    17 
       
    18 import wx
       
    19 import wx.grid
       
    20 
       
    21 class CustomTable(wx.grid.PyGridTableBase):
       
    22     
       
    23     """
       
    24     A custom wx.grid.Grid Table using user supplied data
       
    25     """
       
    26     def __init__(self, parent, data, colnames):
       
    27         # The base class must be initialized *first*
       
    28         wx.grid.PyGridTableBase.__init__(self)
       
    29         self.data = data
       
    30         self.colnames = colnames
       
    31         self.Highlights = {}
       
    32         self.Parent = parent
       
    33         # XXX
       
    34         # we need to store the row length and collength to
       
    35         # see if the table has changed size
       
    36         self._rows = self.GetNumberRows()
       
    37         self._cols = self.GetNumberCols()
       
    38     
       
    39     def GetNumberCols(self):
       
    40         return len(self.colnames)
       
    41         
       
    42     def GetNumberRows(self):
       
    43         return len(self.data)
       
    44 
       
    45     def GetColLabelValue(self, col, translate=True):
       
    46         if col < len(self.colnames):
       
    47             if translate:
       
    48                 return _(self.colnames[col])
       
    49             return self.colnames[col]
       
    50 
       
    51     def GetRowLabelValue(self, row, translate=True):
       
    52         return row
       
    53 
       
    54     def GetValue(self, row, col):
       
    55         if row < self.GetNumberRows():
       
    56             return self.data[row].get(self.GetColLabelValue(col, False), "")
       
    57     
       
    58     def SetValue(self, row, col, value):
       
    59         if col < len(self.colnames):
       
    60             self.data[row][self.GetColLabelValue(col, False)] = value
       
    61     
       
    62     def GetValueByName(self, row, colname):
       
    63         if row < self.GetNumberRows():
       
    64             return self.data[row].get(colname)
       
    65 
       
    66     def SetValueByName(self, row, colname, value):
       
    67         if row < self.GetNumberRows():
       
    68             self.data[row][colname] = value
       
    69 
       
    70     def ResetView(self, grid):
       
    71         """
       
    72         (wx.grid.Grid) -> Reset the grid view.   Call this to
       
    73         update the grid if rows and columns have been added or deleted
       
    74         """
       
    75         grid.CloseEditControl()
       
    76         grid.BeginBatch()
       
    77         for current, new, delmsg, addmsg in [
       
    78             (self._rows, self.GetNumberRows(), wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
       
    79             (self._cols, self.GetNumberCols(), wx.grid.GRIDTABLE_NOTIFY_COLS_DELETED, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
       
    80         ]:
       
    81             if new < current:
       
    82                 msg = wx.grid.GridTableMessage(self,delmsg,new,current-new)
       
    83                 grid.ProcessTableMessage(msg)
       
    84             elif new > current:
       
    85                 msg = wx.grid.GridTableMessage(self,addmsg,new-current)
       
    86                 grid.ProcessTableMessage(msg)
       
    87                 self.UpdateValues(grid)
       
    88         grid.EndBatch()
       
    89 
       
    90         self._rows = self.GetNumberRows()
       
    91         self._cols = self.GetNumberCols()
       
    92         # update the column rendering scheme
       
    93         self._updateColAttrs(grid)
       
    94 
       
    95         # update the scrollbars and the displayed part of the grid
       
    96         grid.AdjustScrollbars()
       
    97         grid.ForceRefresh()
       
    98 
       
    99     def UpdateValues(self, grid):
       
   100         """Update all displayed values"""
       
   101         # This sends an event to the grid table to update all of the values
       
   102         msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
   103         grid.ProcessTableMessage(msg)
       
   104 
       
   105     def _updateColAttrs(self, grid):
       
   106         """
       
   107         wx.grid.Grid -> update the column attributes to add the
       
   108         appropriate renderer given the column name.
       
   109 
       
   110         Otherwise default to the default renderer.
       
   111         """
       
   112         for row in range(self.GetNumberRows()):
       
   113             row_highlights = self.Highlights.get(row, {})
       
   114             for col in range(self.GetNumberCols()):
       
   115                 colname = self.GetColLabelValue(col, False)
       
   116                 
       
   117                 grid.SetReadOnly(row, col, True)
       
   118                 grid.SetCellEditor(row, col, None)
       
   119                 grid.SetCellRenderer(row, col, None)
       
   120                 
       
   121                 highlight_colours = row_highlights.get(colname.lower(), [(wx.WHITE, wx.BLACK)])[-1]
       
   122                 grid.SetCellBackgroundColour(row, col, highlight_colours[0])
       
   123                 grid.SetCellTextColour(row, col, highlight_colours[1])
       
   124             self.ResizeRow(grid, row)
       
   125     
       
   126     def ResizeRow(self, grid, row):
       
   127         if wx.Platform == '__WXMSW__':
       
   128             grid.SetRowMinimalHeight(row, 20)
       
   129         else:
       
   130             grid.SetRowMinimalHeight(row, 28)
       
   131         grid.AutoSizeRow(row, False)
       
   132     
       
   133     def SetData(self, data):
       
   134         self.data = data
       
   135     
       
   136     def GetData(self):
       
   137         return self.data
       
   138     
       
   139     def GetCurrentIndex(self):
       
   140         return self.CurrentIndex
       
   141     
       
   142     def SetCurrentIndex(self, index):
       
   143         self.CurrentIndex = index
       
   144     
       
   145     def AppendRow(self, row_content):
       
   146         self.data.append(row_content)
       
   147 
       
   148     def InsertRow(self, index, row_content):
       
   149         self.data.insert(index, row_content)
       
   150 
       
   151     def MoveRow(self, row_index, move):
       
   152         new_index = max(0, min(row_index + move, len(self.data) - 1))
       
   153         if new_index != row_index:
       
   154             self.data.insert(new_index, self.data.pop(row_index))
       
   155         return new_index
       
   156 
       
   157     def RemoveRow(self, row_index):
       
   158         self.data.pop(row_index)
       
   159 
       
   160     def GetRow(self, row_index):
       
   161         return self.data[row_index]
       
   162 
       
   163     def Empty(self):
       
   164         self.data = []
       
   165 
       
   166     def AddHighlight(self, infos, highlight_type):
       
   167         row_highlights = self.Highlights.setdefault(infos[0], {})
       
   168         col_highlights = row_highlights.setdefault(infos[1], [])
       
   169         col_highlights.append(highlight_type)
       
   170 
       
   171     def RemoveHighlight(self, infos, highlight_type):
       
   172         row_highlights = self.Highlights.get(infos[0])
       
   173         if row_highlights is not None:
       
   174             col_highlights = row_highlights.get(infos[1])
       
   175             if col_highlights is not None and highlight_type in col_highlights:
       
   176                 col_highlights.remove(highlight_type)
       
   177             if len(col_highlights) == 0:
       
   178                 row_highlights.pop(infos[1])
       
   179 
       
   180     def ClearHighlights(self, highlight_type=None):
       
   181         if highlight_type is None:
       
   182             self.Highlights = {}
       
   183         else:
       
   184             for row, row_highlights in self.Highlights.iteritems():
       
   185                 row_items = row_highlights.items()
       
   186                 for col, col_highlights in row_items:
       
   187                     if highlight_type in col_highlights:
       
   188                         col_highlights.remove(highlight_type)
       
   189                     if len(col_highlights) == 0:
       
   190                         row_highlights.pop(col)