/[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

revision 881 by jonathan, Fri May 9 16:34:15 2003 UTC revision 1058 by frank, Tue May 27 11:30:29 2003 UTC
# Line 7  Line 7 
7    
8  __version__ = "$Revision$"  __version__ = "$Revision$"
9    
10    import os.path
11    
12  from Thuban import _  from Thuban import _
13    
14  from wxPython.wx import *  from wxPython.wx import *
# Line 14  from wxPython.grid import * Line 16  from wxPython.grid import *
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, \
19       FIELDTYPE_STRING       FIELDTYPE_STRING, table_to_dbf, table_to_csv
20  import view  import view
21  from dialogs import NonModalDialog  from dialogs import NonModalNonParentDialog
22  from messages import SHAPES_SELECTED  from messages import SHAPES_SELECTED
23    
24  wx_value_type_map = {FIELDTYPE_INT: wxGRID_VALUE_NUMBER,  wx_value_type_map = {FIELDTYPE_INT: wxGRID_VALUE_NUMBER,
# Line 25  wx_value_type_map = {FIELDTYPE_INT: wxGR Line 27  wx_value_type_map = {FIELDTYPE_INT: wxGR
27    
28  ROW_SELECTED = "ROW_SELECTED"  ROW_SELECTED = "ROW_SELECTED"
29    
30    QUERY_KEY = 'S'
31    
32  class DataTable(wxPyGridTableBase):  class DataTable(wxPyGridTableBase):
33    
# Line 120  class TableGrid(wxGrid, Publisher): Line 123  class TableGrid(wxGrid, Publisher):
123          # of the table and will destroy it when done. Otherwise you          # of the table and will destroy it when done. Otherwise you
124          # would need to keep a reference to it and call its Destroy          # would need to keep a reference to it and call its Destroy
125          # method later.          # method later.
126          self.SetTable(self.table, true)          self.SetTable(self.table, True)
127    
128          #self.SetMargins(0,0)          #self.SetMargins(0,0)
129    
# Line 128  class TableGrid(wxGrid, Publisher): Line 131  class TableGrid(wxGrid, Publisher):
131          # column widths automatically but it would cause a traversal of          # column widths automatically but it would cause a traversal of
132          # the entire table which for large .dbf files can take a very          # the entire table which for large .dbf files can take a very
133          # long time.          # long time.
134          #self.AutoSizeColumns(false)          #self.AutoSizeColumns(False)
135    
136          self.SetSelectionMode(wxGrid.wxGridSelectRows)          self.SetSelectionMode(wxGrid.wxGridSelectRows)
137    
138          EVT_GRID_RANGE_SELECT(self, self.OnRangeSelect)          #EVT_GRID_RANGE_SELECT(self, None)
139          EVT_GRID_SELECT_CELL(self, self.OnSelectCell)          #EVT_GRID_SELECT_CELL(self, None)
140            #EVT_GRID_RANGE_SELECT(self, self.OnRangeSelect)
141            #EVT_GRID_SELECT_CELL(self, self.OnSelectCell)
142    
143            self.ToggleEventListeners(True)
144    
145      def SetTableObject(self, table):      def SetTableObject(self, table):
146          self.table.SetTable(table)          self.table.SetTable(table)
# Line 156  class TableGrid(wxGrid, Publisher): Line 163  class TableGrid(wxGrid, Publisher):
163          self.issue(ROW_SELECTED, self.GetSelectedRows())          self.issue(ROW_SELECTED, self.GetSelectedRows())
164          event.Skip()          event.Skip()
165    
166        def ToggleEventListeners(self, on):
167            if on:
168                EVT_GRID_RANGE_SELECT(self, self.OnRangeSelect)
169                EVT_GRID_SELECT_CELL(self, self.OnSelectCell)
170            else:
171                EVT_GRID_RANGE_SELECT(self, None)
172                EVT_GRID_SELECT_CELL(self, None)
173                
174      def disallow_messages(self):      def disallow_messages(self):
175          """Disallow messages to be send.          """Disallow messages to be send.
176    
# Line 221  class LayerTableGrid(TableGrid): Line 236  class LayerTableGrid(TableGrid):
236                  self.allow_messages()                  self.allow_messages()
237    
238    
239  class TableFrame(NonModalDialog):  class TableFrame(NonModalNonParentDialog):
240    
241      """Frame that displays a Thuban table in a grid view"""      """Frame that displays a Thuban table in a grid view"""
242    
243      def __init__(self, parent, name, title, table):      def __init__(self, parent, name, title, table):
244          NonModalDialog.__init__(self, parent, name, title)          NonModalNonParentDialog.__init__(self, parent, name, title)
245          self.table = table          self.table = table
246          self.grid = self.make_grid(self.table)          self.grid = self.make_grid(self.table)
247    
# Line 240  class TableFrame(NonModalDialog): Line 255  class TableFrame(NonModalDialog):
255    
256    
257  ID_QUERY = 4001  ID_QUERY = 4001
258  ID_SAVEAS = 4002  ID_EXPORT = 4002
259    
260  class LayerTableFrame(TableFrame):  class QueryTableFrame(TableFrame):
261    
262      """Frame that displays a layer table in a grid view      """Frame that displays a table in a grid view and offers user actions
263        selection and export
264    
265      A LayerTableFrame is TableFrame whose selection is connected to the      A LayerTableFrame is TableFrame whose selection is connected to the
266      selected object in a map.      selected object in a map.
267      """      """
268    
269      def __init__(self, parent, name, title, layer, table):      def __init__(self, parent, name, title, table):
270          TableFrame.__init__(self, parent, name, title, table)          TableFrame.__init__(self, parent, name, title, table)
         self.layer = layer  
         self.grid.Subscribe(ROW_SELECTED, self.rows_selected)  
         self.parent.Subscribe(SHAPES_SELECTED, self.select_shapes)  
271    
272          self.combo_fields = wxComboBox(self, -1, style=wxCB_READONLY)          self.combo_fields = wxComboBox(self, -1, style=wxCB_READONLY)
273          self.choice_comp = wxChoice(self, -1,          self.choice_comp = wxChoice(self, -1,
274                                choices=["<", "<=", "=", "<>", ">=", ">"])                                choices=["<", "<=", "==", "!=", ">=", ">"])
275          self.combo_value = wxComboBox(self, -1)          self.combo_value = wxComboBox(self, -1)
276          self.choice_action = wxChoice(self, -1,          self.choice_action = wxChoice(self, -1,
277                                  choices=[_("Replace Selection"),                                  choices=[_("Replace Selection"),
# Line 266  class LayerTableFrame(TableFrame): Line 279  class LayerTableFrame(TableFrame):
279                                          _("Add to Selection")])                                          _("Add to Selection")])
280    
281          button_query = wxButton(self, ID_QUERY, _("Query"))          button_query = wxButton(self, ID_QUERY, _("Query"))
282          button_saveas = wxButton(self, ID_SAVEAS, _("Save As..."))          button_saveas = wxButton(self, ID_EXPORT, _("Export"))
283    
284          self.grid.SetSize((400, 200))          self.grid.SetSize((400, 200))
285    
286          self.combo_value.Append("")          self.combo_value.Append("")
287          for i in range(table.field_count()):          for i in range(table.NumColumns()):
288              type, name, len, decc = layer.table.field_info(i)              name = table.Column(i).name
289              self.combo_fields.Append(name)              self.combo_fields.Append(name)
290              self.combo_value.Append(name)              self.combo_value.Append(name)
291                                                                                    
292          # assume at least one field?          # assume at least one field?
293          self.combo_fields.SetSelection(0)          self.combo_fields.SetSelection(0)
294          self.combo_value.SetSelection(0)          self.combo_value.SetSelection(0)
295    
296          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
297    
298          sizer = wxStaticBoxSizer(wxStaticBox(self, -1, _("Selections")),          sizer = wxStaticBoxSizer(wxStaticBox(self, -1,
299                                      _("&Selection")),
300                                    wxHORIZONTAL)                                    wxHORIZONTAL)
301          sizer.Add(self.combo_fields, 1, wxEXPAND|wxALL, 4)          sizer.Add(self.combo_fields, 1, wxEXPAND|wxALL, 4)
302          sizer.Add(self.choice_comp, 0, wxALL, 4)          sizer.Add(self.choice_comp, 0, wxALL, 4)
303          sizer.Add(self.combo_value, 1, wxEXPAND|wxALL, 4)          sizer.Add(self.combo_value, 1, wxEXPAND|wxALL, 4)
304          sizer.Add(self.choice_action, 0, wxALL, 4)          sizer.Add(self.choice_action, 0, wxALL, 4)
305          sizer.Add(button_query, 0, wxALL, 4)          sizer.Add(button_query, 0, wxALL | wxALIGN_CENTER_VERTICAL, 4)
306          sizer.Add(40, 20, 0, wxALL, 4)          sizer.Add(40, 20, 0, wxALL, 4)
307          sizer.Add(button_saveas, 0, wxALL, 4)          sizer.Add(button_saveas, 0, wxALL | wxALIGN_CENTER_VERTICAL, 4)
308    
309          topBox.Add(sizer, 0, wxEXPAND|wxALL, 4)          topBox.Add(sizer, 0, wxEXPAND|wxALL, 4)
310          topBox.Add(self.grid, 1, wxEXPAND|wxALL, 0)          topBox.Add(self.grid, 1, wxEXPAND|wxALL, 0)
# Line 300  class LayerTableFrame(TableFrame): Line 314  class LayerTableFrame(TableFrame):
314          topBox.Fit(self)          topBox.Fit(self)
315          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
316    
317            self.grid.SetFocus()
318          EVT_BUTTON(self, ID_QUERY, self.OnQuery)          EVT_BUTTON(self, ID_QUERY, self.OnQuery)
319          EVT_BUTTON(self, ID_SAVEAS, self.OnSaveAs)          EVT_BUTTON(self, ID_EXPORT, self.OnSaveAs)
320            EVT_KEY_DOWN(self.grid, self.OnKeyDown)
321    
322        def OnKeyDown(self, event):
323            """Catch query key from grid"""
324            if event.AltDown() and event.GetKeyCode() == ord(QUERY_KEY):
325                self.combo_fields.SetFocus()
326                self.combo_fields.refocus = True
327            else:
328                event.Skip()
329    
330    
331      def OnQuery(self, event):      def OnQuery(self, event):
332          wxBeginBusyCursor()          wxBeginBusyCursor()
333    
334          if self.combo_value.GetSelection() < 1:          if self.combo_value.GetSelection() < 1:
335              value = self.combo_value.GetValue()              value = self.combo_value.GetValue()
             print value  
336          else:          else:
337              value = self.table.Column(self.combo_value.GetValue())              value = self.table.Column(self.combo_value.GetValue())
338    
339          #ids = self.table.Query(          ids = self.table.SimpleQuery(
340                  #self.table.Column(self.combo_fields.GetStringSelection()),                  self.table.Column(self.combo_fields.GetStringSelection()),
341                  #self.choice_comp.GetStringSelection(),                  self.choice_comp.GetStringSelection(),
342                  #value)                  value)
343    
344          choice = self.choice_action.GetSelection()          choice = self.choice_action.GetSelection()
345                            
346            #
347            # what used to be nice code got became a bit ugly because
348            # each time we select a row a message is sent to the grid
349            # which we are listening for and then we send further
350            # messages.
351            #
352            # now, we disable those listeners select everything but
353            # the first item, reenable the listeners, and select
354            # the first element, which causes everything to be
355            # updated properly.
356            #
357            self.grid.ToggleEventListeners(False)
358    
359          if choice == 0:          if choice == 0:
             ids = [1, 2, 3, 4, 5]  
360              # Replace Selection              # Replace Selection
361              self.grid.ClearSelection()              self.grid.ClearSelection()
             for id in ids:  
                 self.grid.SelectRow(id, True)  
362          elif choice == 1:          elif choice == 1:
             ids = [1, 3, 5]  
363              # Refine Selection              # Refine Selection
364              sel = dict([(i, 0) for i in self.parent.SelectedShapes()])              sel = self.get_selected()
365              self.grid.ClearSelection()              self.grid.ClearSelection()
366              for id in filter(sel.has_key, ids):              ids = filter(sel.has_key, ids)
                 self.grid.SelectRow(id, True)  
367          elif choice == 2:          elif choice == 2:
             ids = [2, 4]  
368              # Add to Selection              # Add to Selection
369              for id in ids:              pass
370    
371            #
372            # select the rows (all but the first)
373            #
374            firsttime = True
375            for id in ids:
376                if firsttime:
377                    firsttime = False
378                else:
379                  self.grid.SelectRow(id, True)                  self.grid.SelectRow(id, True)
380    
381            self.grid.ToggleEventListeners(True)
382    
383            #
384            # select the first row
385            #
386            if ids:
387                self.grid.SelectRow(ids[0], True)
388    
389          wxEndBusyCursor()          wxEndBusyCursor()
390                    
391      def OnSaveAs(self, event):      def OnSaveAs(self, event):
392          dlg = wxFileDialog(self, _("Save Table As"), ".", "",          dlg = wxFileDialog(self, _("Export Table To"), ".", "",
393                             "DBF Files (*.dbf)|*.dbf|" +                             _("DBF Files (*.dbf)|*.dbf|") +
394                             "CSV Files (*.csv)|*.csv|" +                             _("CSV Files (*.csv)|*.csv|") +
395                             "All Files (*.*)|*.*",                             _("All Files (*.*)|*.*"),
396                             wxSAVE|wxOVERWRITE_PROMPT)                             wxSAVE|wxOVERWRITE_PROMPT)
397          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wxID_OK:
398              pass              filename = dlg.GetPath()
399                                                                                                type = os.path.basename(filename).split('.')[-1:][0]
400          dlg.Destroy()              dlg.Destroy()
401                if type.upper() == "DBF":
402                    table_to_dbf(self.table, filename)
403                elif type.upper() == 'CSV':
404                    table_to_csv(self.table, filename)
405                else:
406                    dlg = wxMessageDialog(None, "Unsupported format: %s" % type,
407                                          "Table Export", wxOK|wxICON_WARNING)
408                    dlg.ShowModal()
409                    dlg.Destroy()
410            else:
411                dlg.Destroy()
412    
413        def OnClose(self, event):
414            TableFrame.OnClose(self, event)
415    
416        def get_selected(self):
417            """Return a dictionary of the selected rows.
418            
419            The dictionary has sthe indexes as keys."""
420            return dict([(i, 0) for i in self.grid.GetSelectedRows()])
421    
422    class LayerTableFrame(QueryTableFrame):
423    
424        """Frame that displays a layer table in a grid view
425    
426        A LayerTableFrame is a QueryTableFrame whose selection is connected to the
427        selected object in a map.
428        """
429    
430        def __init__(self, parent, name, title, layer, table):
431            QueryTableFrame.__init__(self, parent, name, title, table)
432            self.layer = layer
433            self.grid.Subscribe(ROW_SELECTED, self.rows_selected)
434            self.parent.Subscribe(SHAPES_SELECTED, self.select_shapes)
435    
436            # if there is already a selection present, update the grid
437            # accordingly
438            sel = self.get_selected().keys()
439            for i in sel:
440                self.grid.SelectRow(i, True)
441    
442      def make_grid(self, table):      def make_grid(self, table):
443          """Override the derived method to return a LayerTableGrid.          """Override the derived method to return a LayerTableGrid.
444          """          """
445          return LayerTableGrid(self, table)          return LayerTableGrid(self, table)
446    
447        def get_selected(self):
448            """Override the derived method to return a dictionary of the selected
449            rows.
450            """
451            return dict([(i, 0) for i in self.parent.SelectedShapes()])
452    
453      def OnClose(self, event):      def OnClose(self, event):
454            """Override the derived method to first unsubscribed."""
455          self.parent.Unsubscribe(SHAPES_SELECTED, self.select_shapes)          self.parent.Unsubscribe(SHAPES_SELECTED, self.select_shapes)
456          TableFrame.OnClose(self, event)          QueryTableFrame.OnClose(self, event)
457    
458      def select_shapes(self, layer, shapes):      def select_shapes(self, layer, shapes):
459          """Subscribed to the SHAPES_SELECTED message.          """Subscribed to the SHAPES_SELECTED message.
# Line 369  class LayerTableFrame(TableFrame): Line 464  class LayerTableFrame(TableFrame):
464          self.grid.select_shapes(layer, shapes)          self.grid.select_shapes(layer, shapes)
465    
466      def rows_selected(self, rows):      def rows_selected(self, rows):
467            """Return the selected rows of the layer as they are returned
468            by Layer.SelectShapes().
469            """
470          if self.layer is not None:          if self.layer is not None:
471              self.parent.SelectShapes(self.layer, rows)              self.parent.SelectShapes(self.layer, rows)

Legend:
Removed from v.881  
changed lines
  Added in v.1058

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26