/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/tableview.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/tableview.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/thuban/Thuban/UI/tableview.py revision 1892 by bh, Thu Oct 30 18:16:53 2003 UTC branches/WIP-pyshapelib-bramz/Thuban/UI/tableview.py revision 2734 by bramz, Thu Mar 1 12:42:59 2007 UTC
# Line 11  import os.path Line 11  import os.path
11    
12  from Thuban import _  from Thuban import _
13    
14  from wxPython.wx import *  import wx
15  from wxPython.grid import *  from wx import grid
16    
17  from Thuban.Lib.connector import Publisher  from Thuban.Lib.connector import Publisher
18  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
# Line 23  from messages import SHAPES_SELECTED, SE Line 23  from messages import SHAPES_SELECTED, SE
23  from Thuban.Model.messages import TABLE_REMOVED, MAP_LAYERS_REMOVED  from Thuban.Model.messages import TABLE_REMOVED, MAP_LAYERS_REMOVED
24  from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor  from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
25    
26  wx_value_type_map = {FIELDTYPE_INT: wxGRID_VALUE_NUMBER,  wx_value_type_map = {FIELDTYPE_INT: grid.GRID_VALUE_NUMBER,
27                       FIELDTYPE_DOUBLE: wxGRID_VALUE_FLOAT,                       FIELDTYPE_DOUBLE: grid.GRID_VALUE_FLOAT,
28                       FIELDTYPE_STRING: wxGRID_VALUE_STRING}                       FIELDTYPE_STRING: grid.GRID_VALUE_STRING}
29    
30  ROW_SELECTED = "ROW_SELECTED"  ROW_SELECTED = "ROW_SELECTED"
31    
32  QUERY_KEY = 'S'  QUERY_KEY = 'S'
33    
34  class DataTable(wxPyGridTableBase):  class DataTable(grid.PyGridTableBase):
35    
36      """Wrapper around a Thuban table object suitable for a wxGrid"""      """Wrapper around a Thuban table object suitable for a wxGrid"""
37    
38      def __init__(self, table = None):      def __init__(self, table = None):
39          wxPyGridTableBase.__init__(self)          grid.PyGridTableBase.__init__(self)
40          self.num_cols = 0          self.num_cols = 0
41          self.num_rows = 0          self.num_rows = 0
42          self.columns = []          self.columns = []
# Line 71  class DataTable(wxPyGridTableBase): Line 71  class DataTable(wxPyGridTableBase):
71      # Renderer understands the type too,) not just strings as in the      # Renderer understands the type too,) not just strings as in the
72      # C++ version.      # C++ version.
73      def GetValue(self, row, col):      def GetValue(self, row, col):
74          record = self.table.ReadRowAsDict(row, row_is_ordinal = 1)          try:
75                record = self.table.ReadRowAsDict(row, row_is_ordinal = 1)
76            except UnicodeError:
77                record = dict()
78                for (key, val) in self.table.ReadRowAsDict(row, \
79                                  row_is_ordinal = 1).items():
80                    if isinstance(val, str):
81                        record[key] = val.decode('iso-8859-1')
82                    else:
83                        record[key] = val
84          return record[self.columns[col][0]]          return record[self.columns[col][0]]
85    
86      def SetValue(self, row, col, value):      def SetValue(self, row, col, value):
# Line 112  class DataTable(wxPyGridTableBase): Line 121  class DataTable(wxPyGridTableBase):
121          return self.table.RowOrdinalToId(ordinal)          return self.table.RowOrdinalToId(ordinal)
122    
123    
124  class NullRenderer(wxPyGridCellRenderer):  class NullRenderer(grid.PyGridCellRenderer):
125    
126      """Renderer that draws NULL as a gray rectangle      """Renderer that draws NULL as a gray rectangle
127    
# Line 121  class NullRenderer(wxPyGridCellRenderer) Line 130  class NullRenderer(wxPyGridCellRenderer)
130      """      """
131    
132      def __init__(self, non_null_renderer):      def __init__(self, non_null_renderer):
133          wxPyGridCellRenderer.__init__(self)          grid.PyGridCellRenderer.__init__(self)
134          self.non_null_renderer = non_null_renderer          self.non_null_renderer = non_null_renderer
135    
136      def Draw(self, grid, attr, dc, rect, row, col, isSelected):      def Draw(self, grid, attr, dc, rect, row, col, isSelected):
137          value = grid.table.GetValue(row, col)          value = grid.table.GetValue(row, col)
138          if value is None:          if value is None:
139              dc.SetBackgroundMode(wxSOLID)              dc.SetBackgroundMode(wx.SOLID)
140              dc.SetBrush(wxBrush(wxColour(192, 192, 192), wxSOLID))              dc.SetBrush(wx.Brush(wx.Colour(192, 192, 192), wx.SOLID))
141              dc.SetPen(wxTRANSPARENT_PEN)              dc.SetPen(wx.TRANSPARENT_PEN)
142              dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)              dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
143          else:          else:
144              self.non_null_renderer.Draw(grid, attr, dc, rect, row, col,              self.non_null_renderer.Draw(grid, attr, dc, rect, row, col,
# Line 142  class NullRenderer(wxPyGridCellRenderer) Line 151  class NullRenderer(wxPyGridCellRenderer)
151          return NullRenderer(self.non_null_renderer)          return NullRenderer(self.non_null_renderer)
152    
153    
154  class TableGrid(wxGrid, Publisher):  class TableGrid(grid.Grid, Publisher):
155    
156      """A grid view for a Thuban table      """A grid view for a Thuban table
157    
# Line 155  class TableGrid(wxGrid, Publisher): Line 164  class TableGrid(wxGrid, Publisher):
164      """      """
165    
166      def __init__(self, parent, table = None):      def __init__(self, parent, table = None):
167          wxGrid.__init__(self, parent, -1)          grid.Grid.__init__(self, parent, -1)
168    
169          self.allow_messages_count = 0          self.allow_messages_count = 0
170    
# Line 178  class TableGrid(wxGrid, Publisher): Line 187  class TableGrid(wxGrid, Publisher):
187          # long time.          # long time.
188          #self.AutoSizeColumns(False)          #self.AutoSizeColumns(False)
189    
190          self.SetSelectionMode(wxGrid.wxGridSelectRows)          self.SetSelectionMode(grid.Grid.wxGridSelectRows)
191    
192          self.ToggleEventListeners(True)          self.ToggleEventListeners(True)
193          EVT_GRID_RANGE_SELECT(self, self.OnRangeSelect)          self.Bind(grid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect)
194          EVT_GRID_SELECT_CELL(self, self.OnSelectCell)          self.Bind(grid.EVT_GRID_SELECT_CELL, self.OnSelectCell)
195    
196          # Replace the normal renderers with our own versions which          # Replace the normal renderers with our own versions which
197          # render NULL/None values specially          # render NULL/None values specially
198          self.RegisterDataType(wxGRID_VALUE_STRING,          self.RegisterDataType(grid.GRID_VALUE_STRING,
199                                NullRenderer(wxGridCellStringRenderer()), None)                                NullRenderer(grid.GridCellStringRenderer()), None)
200          self.RegisterDataType(wxGRID_VALUE_NUMBER,          self.RegisterDataType(grid.GRID_VALUE_NUMBER,
201                                NullRenderer(wxGridCellNumberRenderer()), None)                                NullRenderer(grid.GridCellNumberRenderer()), None)
202          self.RegisterDataType(wxGRID_VALUE_FLOAT,          self.RegisterDataType(grid.GRID_VALUE_FLOAT,
203                                NullRenderer(wxGridCellFloatRenderer()), None)                                NullRenderer(grid.GridCellFloatRenderer()), None)
204    
205            self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
206    
207        def OnDestroy(self, event):
208            Publisher.Destroy(self)
209    
210      def SetTableObject(self, table):      def SetTableObject(self, table):
211          self.table.SetTable(table)          self.table.SetTable(table)
# Line 301  class TableFrame(ThubanFrame): Line 315  class TableFrame(ThubanFrame):
315    
316      def __init__(self, parent, name, title, table):      def __init__(self, parent, name, title, table):
317          ThubanFrame.__init__(self, parent, name, title)          ThubanFrame.__init__(self, parent, name, title)
318          self.panel = wxPanel(self, -1)          self.panel = wx.Panel(self, -1)
319    
320          self.table = table          self.table = table
321          self.grid = self.make_grid(self.table)          self.grid = self.make_grid(self.table)
# Line 359  class QueryTableFrame(TableFrame): Line 373  class QueryTableFrame(TableFrame):
373      def __init__(self, parent, name, title, table):      def __init__(self, parent, name, title, table):
374          TableFrame.__init__(self, parent, name, title, table)          TableFrame.__init__(self, parent, name, title, table)
375    
376          self.combo_fields = wxComboBox(self.panel, -1, style=wxCB_READONLY)          self.combo_fields = wx.ComboBox(self.panel, -1, style=wx.CB_READONLY)
377          self.choice_comp = wxChoice(self.panel, -1,          self.choice_comp = wx.Choice(self.panel, -1,
378                                choices=["<", "<=", "==", "!=", ">=", ">"])                                choices=["<", "<=", "==", "!=", ">=", ">"])
379          self.combo_value = wxComboBox(self.panel, ID_COMBOVALUE)          self.combo_value = wx.ComboBox(self.panel, ID_COMBOVALUE)
380          self.choice_action = wxChoice(self.panel, -1,          self.choice_action = wx.Choice(self.panel, -1,
381                                  choices=[_("Replace Selection"),                                  choices=[_("Replace Selection"),
382                                          _("Refine Selection"),                                          _("Refine Selection"),
383                                          _("Add to Selection")])                                          _("Add to Selection")])
384    
385          button_query = wxButton(self.panel, ID_QUERY, _("Query"))          button_query = wx.Button(self.panel, ID_QUERY, _("Query"))
386          button_export = wxButton(self.panel, ID_EXPORT, _("Export"))          button_export = wx.Button(self.panel, ID_EXPORT, _("Export"))
387          button_exportSel = wxButton(self.panel, ID_EXPORTSEL, _("Export Selection"))          button_exportSel = wx.Button(self.panel, ID_EXPORTSEL, _("Export Selection"))
388          button_close = wxButton(self.panel, wxID_CLOSE, _("Close"))          button_close = wx.Button(self.panel, wx.ID_CLOSE, _("Close"))
389    
390          self.CreateStatusBar()          self.CreateStatusBar()
391    
# Line 393  class QueryTableFrame(TableFrame): Line 407  class QueryTableFrame(TableFrame):
407    
408          self.UpdateStatusText()          self.UpdateStatusText()
409    
410          topBox = wxBoxSizer(wxVERTICAL)          topBox = wx.BoxSizer(wx.VERTICAL)
411    
412          sizer = wxStaticBoxSizer(wxStaticBox(self.panel, -1,          sizer = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1,
413                                    _("Selection")),                                    _("Selection")),
414                                    wxHORIZONTAL)                                    wx.HORIZONTAL)
415          sizer.Add(self.combo_fields, 1, wxEXPAND|wxALL, 4)          sizer.Add(self.combo_fields, 1, wx.EXPAND|wx.ALL, 4)
416          sizer.Add(self.choice_comp, 0, wxALL, 4)          sizer.Add(self.choice_comp, 0, wx.ALL, 4)
417          sizer.Add(self.combo_value, 1, wxEXPAND|wxALL, 4)          sizer.Add(self.combo_value, 1, wx.EXPAND|wx.ALL, 4)
418          sizer.Add(self.choice_action, 0, wxALL, 4)          sizer.Add(self.choice_action, 0, wx.ALL, 4)
419          sizer.Add(button_query, 0, wxALL | wxALIGN_CENTER_VERTICAL, 4)          sizer.Add(button_query, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 4)
420          sizer.Add(40, 20, 0, wxALL, 4)          sizer.Add( (40, 20), 0, wx.ALL, 4)
421    
422          topBox.Add(sizer, 0, wxEXPAND|wxALL, 4)          topBox.Add(sizer, 0, wx.EXPAND|wx.ALL, 4)
423          topBox.Add(self.grid, 1, wxEXPAND|wxALL, 0)          topBox.Add(self.grid, 1, wx.EXPAND|wx.ALL, 0)
424    
425          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wx.BoxSizer(wx.HORIZONTAL)
426          sizer.Add(button_export, 0, wxALL, 4)          sizer.Add(button_export, 0, wx.ALL, 4)
427          sizer.Add(button_exportSel, 0, wxALL, 4)          sizer.Add(button_exportSel, 0, wx.ALL, 4)
428          sizer.Add(60, 20, 1, wxALL|wxEXPAND, 4)          sizer.Add( (60, 20), 1, wx.ALL|wx.EXPAND, 4)
429          sizer.Add(button_close, 0, wxALL|wxALIGN_RIGHT, 4)          sizer.Add(button_close, 0, wx.ALL|wx.ALIGN_RIGHT, 4)
430          topBox.Add(sizer, 0, wxALL | wxEXPAND, 4)          topBox.Add(sizer, 0, wx.ALL | wx.EXPAND, 4)
431    
432          self.panel.SetAutoLayout(True)          self.panel.SetAutoLayout(True)
433          self.panel.SetSizer(topBox)          self.panel.SetSizer(topBox)
434          topBox.Fit(self.panel)          topBox.Fit(self.panel)
435          topBox.SetSizeHints(self.panel)          topBox.SetSizeHints(self.panel)
436    
437          panelSizer = wxBoxSizer(wxVERTICAL)          panelSizer = wx.BoxSizer(wx.VERTICAL)
438          panelSizer.Add(self.panel, 1, wxEXPAND, 0)          panelSizer.Add(self.panel, 1, wx.EXPAND, 0)
439          self.SetAutoLayout(True)          self.SetAutoLayout(True)
440          self.SetSizer(panelSizer)          self.SetSizer(panelSizer)
441          panelSizer.Fit(self)          panelSizer.Fit(self)
# Line 429  class QueryTableFrame(TableFrame): Line 443  class QueryTableFrame(TableFrame):
443    
444          self.grid.SetFocus()          self.grid.SetFocus()
445    
446          EVT_BUTTON(self, ID_QUERY, self.OnQuery)          self.Bind(wx.EVT_BUTTON, self.OnQuery, id=ID_QUERY)
447          EVT_BUTTON(self, ID_EXPORT, self.OnExport)          self.Bind(wx.EVT_BUTTON, self.OnExport, id=ID_EXPORT)
448          EVT_BUTTON(self, ID_EXPORTSEL, self.OnExportSel)          self.Bind(wx.EVT_BUTTON, self.OnExportSel, id=ID_EXPORTSEL)
449          EVT_BUTTON(self, wxID_CLOSE, self.OnClose)          self.Bind(wx.EVT_BUTTON, self.OnClose, id=wx.ID_CLOSE)
450          EVT_KEY_DOWN(self.grid, self.OnKeyDown)          self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown, self.grid)
451    
452          self.grid.Subscribe(ROW_SELECTED, self.UpdateStatusText)          self.grid.Subscribe(ROW_SELECTED, self.UpdateStatusText)
453    
454      def UpdateStatusText(self, rows=None):      def UpdateStatusText(self, rows=None):
455          self.SetStatusText(_("%i rows (%i selected), %i columns")          self.SetStatusText(_("%i rows (%i selected), %i columns")
456              % (self.grid.GetNumberRows(),              % (self.grid.GetNumberRows(),
457                 self.grid.GetNumberSelected(),                 self.grid.GetNumberSelected(),
458                 self.grid.GetNumberCols()))                 self.grid.GetNumberCols()))
459    
# Line 463  class QueryTableFrame(TableFrame): Line 477  class QueryTableFrame(TableFrame):
477                  value = self.table.Column(text)                  value = self.table.Column(text)
478    
479              ids = self.table.SimpleQuery(              ids = self.table.SimpleQuery(
480                      self.table.Column(self.combo_fields.GetStringSelection()),                      self.table.Column(self.combo_fields.GetStringSelection()),
481                      self.choice_comp.GetStringSelection(),                      self.choice_comp.GetStringSelection(),
482                      value)                      value)
483    
484              choice = self.choice_action.GetSelection()              choice = self.choice_action.GetSelection()
485                
486              #              #
487              # what used to be nice code got became a bit ugly because              # what used to be nice code got became a bit ugly because
488              # each time we select a row a message is sent to the grid              # each time we select a row a message is sent to the grid
# Line 515  class QueryTableFrame(TableFrame): Line 529  class QueryTableFrame(TableFrame):
529    
530          finally:          finally:
531              ThubanEndBusyCursor()              ThubanEndBusyCursor()
532            
533      def doExport(self, onlySelected):      def doExport(self, onlySelected):
534            
535          dlg = wxFileDialog(self, _("Export Table To"), ".", "",          dlg = wx.FileDialog(self, _("Export Table To"), ".", "",
536                             _("DBF Files (*.dbf)|*.dbf|") +                             _("DBF Files (*.dbf)|*.dbf|") +
537                             _("CSV Files (*.csv)|*.csv|") +                             _("CSV Files (*.csv)|*.csv|") +
538                             _("All Files (*.*)|*.*"),                             _("All Files (*.*)|*.*"),
539                             wxSAVE|wxOVERWRITE_PROMPT)                             wx.SAVE|wx.OVERWRITE_PROMPT)
540          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wx.ID_OK:
541              filename = dlg.GetPath()              filename = dlg.GetPath()
542              type = os.path.basename(filename).split('.')[-1:][0]              type = os.path.basename(filename).split('.')[-1:][0]
543              dlg.Destroy()              dlg.Destroy()
# Line 538  class QueryTableFrame(TableFrame): Line 552  class QueryTableFrame(TableFrame):
552              elif type.upper() == 'CSV':              elif type.upper() == 'CSV':
553                  table_to_csv(self.table, filename, records)                  table_to_csv(self.table, filename, records)
554              else:              else:
555                  dlg = wxMessageDialog(None, "Unsupported format: %s" % type,                  dlg = wx.MessageDialog(None, "Unsupported format: %s" % type,
556                                        "Table Export", wxOK|wxICON_WARNING)                                        "Table Export", wx.OK|wx.ICON_WARNING)
557                  dlg.ShowModal()                  dlg.ShowModal()
558                  dlg.Destroy()                  dlg.Destroy()
559          else:          else:
# Line 586  class LayerTableFrame(QueryTableFrame): Line 600  class LayerTableFrame(QueryTableFrame):
600    
601      def OnDestroy(self, event):      def OnDestroy(self, event):
602          """Extend inherited method to unsubscribe messages"""          """Extend inherited method to unsubscribe messages"""
603            # There's no need to unsubscribe from self.grid's messages
604            # because it will get a DESTROY event too (since destroying the
605            # frame basically means that all child windows are also
606            # destroyed) and this it will clear all subscriptions
607            # automatically.  It may even have been destroyed already (this
608            # does happen on w2000 for instance) so calling any of its
609            # methods here would be an error.
610          self.parent.Unsubscribe(SHAPES_SELECTED, self.select_shapes)          self.parent.Unsubscribe(SHAPES_SELECTED, self.select_shapes)
         self.grid.Unsubscribe(ROW_SELECTED, self.rows_selected)  
611          self.map.Unsubscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)          self.map.Unsubscribe(MAP_LAYERS_REMOVED, self.map_layers_removed)
612          QueryTableFrame.OnDestroy(self, event)          QueryTableFrame.OnDestroy(self, event)
613    

Legend:
Removed from v.1892  
changed lines
  Added in v.2734

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26