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

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

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

revision 1000 by frank, Thu May 22 19:40:06 2003 UTC revision 2700 by dpinte, Mon Sep 18 14:27:02 2006 UTC
# Line 4  Line 4 
4  #  #
5  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
6  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
7                                                                                    
8  import os, sys, math  """The layer and table join dialog"""
9  from wxPython.wx import *  
10                                                                                    __version__ = "$Revision$"
11    # $Source$
12    # $Id$
13    
14    
15    import sys
16    import wx
17    
18  from Thuban import _  from Thuban import _
19    
20  from Thuban.Model.transientdb import TransientJoinedTable  from Thuban.Model.transientdb import TransientJoinedTable
21  from Thuban.UI.tableview import TableFrame, LayerTableFrame  from Thuban.Model.data import DerivedShapeStore
22                                                                                    from Thuban.UI.tableview import QueryTableFrame
23    
24    from common import ThubanBeginBusyCursor, ThubanEndBusyCursor
25    
26  ID_LEFT_TABLE = 4001  ID_LEFT_TABLE = 4001
27  ID_RIGHT_TABLE = 4002  ID_RIGHT_TABLE = 4002
28    
29  CHOICE_WIDTH = 150  CHOICE_WIDTH = 150
30    
31  class JoinDialog(wxDialog):  class JoinDialog(wx.Dialog):
32        
33      """Table join dialog.      """Table join dialog.
34    
35      Join two tables (left/right) based on the user selected fields.      Join two tables (left/right) based on the user selected fields.
36      Opens a TableFrame and registers the new table with the session.      Opens a QueryTableFrame and registers the new table with the session.
37      """      """
38    
39      def __init__(self, parent, title, session, layer = None):      def __init__(self, parent, title, session, layer = None):
40          wxDialog.__init__(self, parent, -1, title,          wx.Dialog.__init__(self, parent, -1, title,
41                            style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)                            style = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
42            self.layer = layer
43    
44            if not layer:
45                self.choice_left_table = wx.Choice(self, ID_LEFT_TABLE)
46                width, height = self.choice_left_table.GetSizeTuple()
47                self.choice_left_table.SetSize(wx.Size(CHOICE_WIDTH, height))
48                self.left_table = None
49            else:
50                self.choice_left_table = None
51                self.left_table = layer.ShapeStore().Table()
52    
53          self.choice_left_table = wxChoice(self, ID_LEFT_TABLE)          self.choice_right_table = wx.Choice(self, ID_RIGHT_TABLE)
         width, height = self.choice_left_table.GetSizeTuple()  
         self.choice_left_table.SetSize(wxSize(CHOICE_WIDTH, height))  
         self.choice_right_table = wxChoice(self, ID_RIGHT_TABLE)  
54          width, height = self.choice_right_table.GetSizeTuple()          width, height = self.choice_right_table.GetSizeTuple()
55          self.choice_right_table.SetSize(wxSize(CHOICE_WIDTH, height))          self.choice_right_table.SetSize(wx.Size(CHOICE_WIDTH, height))
56    
57          self.choice_left_field = wxChoice(self, -1)          self.choice_left_field = wx.Choice(self, -1)
58          width, height = self.choice_left_field.GetSizeTuple()          width, height = self.choice_left_field.GetSizeTuple()
59          self.choice_left_field.SetSize(wxSize(CHOICE_WIDTH, height))          self.choice_left_field.SetSize(wx.Size(CHOICE_WIDTH, height))
60          self.choice_right_field = wxChoice(self, -1)          self.choice_right_field = wx.Choice(self, -1)
61          width, height = self.choice_right_field.GetSizeTuple()          width, height = self.choice_right_field.GetSizeTuple()
62          self.choice_right_field.SetSize(wxSize(CHOICE_WIDTH, height))          self.choice_right_field.SetSize(wx.Size(CHOICE_WIDTH, height))
63    
64          self.button_join = wxButton(self, wxID_OK, _("Join"))          self.button_join = wx.Button(self, wx.ID_OK, _("Join"))
65          self.button_join.SetDefault()          self.button_join.SetDefault()
66          self.button_close = wxButton(self, wxID_CANCEL, _("Close"))          self.button_close = wx.Button(self, wx.ID_CANCEL, _("Close"))
67    
68            self.Bind(wx.EVT_BUTTON, self.OnJoin, id=wx.ID_OK)
69    
70          EVT_BUTTON(self, wxID_OK, self.OnJoin)          if self.choice_left_table is not None:
71          #EVT_BUTTON(self, wxID_CANCEL, self.OnClose)              self.choice_left_table.Append(_('Select...'), None)
72            self.choice_right_table.Append(_('Select...'), None)
73    
         self.choice_left_table.Append('Select ...', None)  
         self.choice_right_table.Append('Select ...', None)  
           
74          for t in session.Tables():          for t in session.Tables():
75              self.choice_left_table.Append(t.transient_table().tablename, t)              if self.choice_left_table is not None:
76              self.choice_right_table.Append(t.transient_table().tablename, t)                  self.choice_left_table.Append(t.Title(), t)
77    
78          EVT_CHOICE(self, ID_LEFT_TABLE, self.OnLeftTable)              # If there is no choice_left_table then self.left_table will
79          EVT_CHOICE(self, ID_RIGHT_TABLE, self.OnRightTable)              # be the keft table so we can simply leave it out on the
80                # right side.
81                if t is not self.left_table:
82                    self.choice_right_table.Append(t.Title(), t)
83    
84            if self.choice_left_table is None:
85                for col in self.left_table.Columns():
86                    self.choice_left_field.Append(col.name, col)
87    
88            if self.choice_left_table is not None:
89                self.Bind(wx.EVT_CHOICE, self.OnLeftTable, id=ID_LEFT_TABLE)
90            self.Bind(wx.EVT_CHOICE, self.OnRightTable, id=ID_RIGHT_TABLE)
91    
92          self.choice_left_table.SetSelection(0)          if self.choice_left_table is not None:
93                self.choice_left_table.SetSelection(0)
94          self.choice_right_table.SetSelection(0)          self.choice_right_table.SetSelection(0)
95          self.button_join.Enable(False)          self.button_join.Enable(False)
96    
97          topBox = wxBoxSizer(wxVERTICAL)          topBox = wx.BoxSizer(wx.VERTICAL)
98    
99          sizer = wxFlexGridSizer(2, 4)          sizer = wx.FlexGridSizer(2, 4)
100          sizer.Add(wxStaticText(self, -1, _("Table:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("Table:")), 0, wx.ALL, 4)
101          sizer.Add(self.choice_left_table, 1,          if self.choice_left_table is not None:
102                                  wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 4)              sizer.Add(self.choice_left_table, 1,
103          sizer.Add(wxStaticText(self, -1, _("Table:")), 0, wxALL, 4)                        wx.EXPAND|wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
104            else:
105                sizer.Add(wx.StaticText(self, -1, self.left_table.Title()), 0,
106                          wx.ALL, 4)
107    
108            sizer.Add(wx.StaticText(self, -1, _("Table:")), 0, wx.ALL, 4)
109          sizer.Add(self.choice_right_table, 1,          sizer.Add(self.choice_right_table, 1,
110                                  wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 4)                    wx.EXPAND|wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
111          sizer.Add(wxStaticText(self, -1, _("Field:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("Field:")), 0, wx.ALL, 4)
112          sizer.Add(self.choice_left_field, 1,          sizer.Add(self.choice_left_field, 1,
113                                  wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 4)                    wx.EXPAND|wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
114          sizer.Add(wxStaticText(self, -1, _("Field:")), 0, wxALL, 4)          sizer.Add(wx.StaticText(self, -1, _("Field:")), 0, wx.ALL, 4)
115          sizer.Add(self.choice_right_field, 1,          sizer.Add(self.choice_right_field, 1,
116                                  wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 4)                    wx.EXPAND|wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
117    
118          sizer.AddGrowableCol(1)          sizer.AddGrowableCol(1)
119          sizer.AddGrowableCol(3)          sizer.AddGrowableCol(3)
120    
121          topBox.Add(sizer, 1, wxEXPAND|wxALL, 4)          topBox.Add(sizer, 0, wx.EXPAND|wx.ALL, 4)
122    
123          sizer = wxBoxSizer(wxHORIZONTAL)          sizer = wx.BoxSizer(wx.HORIZONTAL)
124          sizer.Add(self.button_join, 0, wxEXPAND|wxRIGHT, 10)          self.check_outer_join = wx.CheckBox(self,-1,
125          sizer.Add(self.button_close, 0, wxEXPAND|wxRIGHT, 10)                                  _("Outer Join (preserves left table records)"))
126            sizer.Add(self.check_outer_join, 1, wx.ALL,4)
127            topBox.Add(sizer, 0, wx.ALIGN_LEFT|wx.ALIGN_TOP, 4)
128    
129            sizer = wx.BoxSizer(wx.HORIZONTAL)
130            sizer.Add(self.button_join, 0, wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM|wx.RIGHT,
131                      10)
132            sizer.Add(self.button_close, 0, wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM|wx.RIGHT,
133                      10)
134    
135          topBox.Add(sizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxTOP, 10)          topBox.Add(sizer, 1, wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM|wx.BOTTOM|wx.TOP, 10)
136    
137          self.SetAutoLayout(True)          self.SetAutoLayout(True)
138          self.SetSizer(topBox)          self.SetSizer(topBox)
139          topBox.Fit(self)          topBox.Fit(self)
140          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
141    
         self.valid = False  
   
142          # Save same parameters for later use.          # Save same parameters for later use.
         self.db = session.TransientDB()  
143          self.parent = parent          self.parent = parent
144          self.session = session          self.session = session
145    
146      def OnJoin(self, event):      def OnJoin(self, event):
147          """Get the table and field selections and perform the join."""          """Get the table and field selections and perform the join."""
148          # left          ThubanBeginBusyCursor()
         i = self.choice_left_table.GetSelection()  
         left_table = self.choice_left_table.GetClientData(i)  
         i = self.choice_left_field.GetSelection()  
         left_field  = self.choice_left_field.GetString(i)  
         # right  
         i = self.choice_right_table.GetSelection()  
         right_table = self.choice_right_table.GetClientData(i)  
         i = self.choice_right_field.GetSelection()  
         right_field  = self.choice_right_field.GetString(i)  
   
         result = True  
149          try:          try:
150              joined_table = TransientJoinedTable(self.db, left_table, left_field,              # left
151                                              right_table, right_field)              if self.choice_left_table is not None:
152          except:                  i = self.choice_left_table.GetSelection()
153              exc_type, exc_value, exc_traceback = sys.exc_info()                  left_table = self.choice_left_table.GetClientData(i)
154              dlg = wxMessageDialog(None, 'Join failed:\n  %s' % exc_value,              else:
155                                          'Info',wxOK|wxICON_ERROR)                  left_table = self.left_table
156              dlg.ShowModal()              i = self.choice_left_field.GetSelection()
157              dlg.Destroy              left_field  = self.choice_left_field.GetString(i)
158              result = False              # right
159                        i = self.choice_right_table.GetSelection()
160          if result:              right_table = self.choice_right_table.GetClientData(i)
161              self.session.AddTable(joined_table)              i = self.choice_right_field.GetSelection()
162                right_field  = self.choice_right_field.GetString(i)
163    
164                outer_join = self.check_outer_join.IsChecked()
165    
166                try:
167                    joined_table = TransientJoinedTable(self.session.TransientDB(),
168                                                        left_table, left_field,
169                                                        right_table, right_field,
170                                                        outer_join)
171                except:
172                    dlg = wx.MessageDialog(None,
173                                          _('Join failed:\n  %s') % sys.exc_info()[1],
174                                          _('Info'), wx.OK|wx.ICON_ERROR)
175                    dlg.ShowModal()
176                    dlg.Destroy()
177                    return
178    
179                joined_table = self.session.AddTable(joined_table)
180    
181                if self.layer is not None:
182                    needed_rows = self.layer.ShapeStore().Table().NumRows()
183                    joined_rows = joined_table.NumRows()
184                    if needed_rows == joined_rows:
185                        store = DerivedShapeStore(self.layer.ShapeStore(),
186                                              joined_table)
187                        self.session.AddShapeStore(store)
188                        self.layer.SetShapeStore(store)
189    
190            finally:
191                ThubanEndBusyCursor()
192    
193            if self.layer is not None:
194                if needed_rows != joined_rows:
195                    msg = _("The joined table has %(joined)d rows but"
196                            " it must have %(needed)d rows"
197                            " to be used with the selected layer") \
198                            % {"joined": joined_rows,
199                               "needed": needed_rows}
200                    dlg = wx.MessageDialog(None, msg, _('Join Failed'),
201                                          wx.OK|wx.ICON_ERROR)
202                    dlg.ShowModal()
203                    dlg.Destroy()
204                    return
205    
206            else:
207              name = joined_table.tablename              name = joined_table.tablename
208              dialog = TableFrame(self.parent, name,              dialog = QueryTableFrame(self.parent, name,
209                                        _("Table: %s") % name, joined_table)                                       _('Table: %s') % joined_table.Title(),
210                                         joined_table)
211              self.parent.add_dialog(name, dialog)              self.parent.add_dialog(name, dialog)
212              dialog.Show(true)              dialog.Show(True)
213    
214              self.Close()          self.Close()
215    
216      def OnClose(self, event):      def OnClose(self, event):
217          """Close the dialog."""          """Close the dialog."""
# Line 148  class JoinDialog(wxDialog): Line 222  class JoinDialog(wxDialog):
222          i = self.choice_left_table.GetSelection()          i = self.choice_left_table.GetSelection()
223          table = self.choice_left_table.GetClientData(i)          table = self.choice_left_table.GetClientData(i)
224          self.choice_left_field.Clear()          self.choice_left_field.Clear()
225          for col in table.Columns():          if table is not None:
226              self.choice_left_field.Append(col.name, col)              for col in table.Columns():
227                                self.choice_left_field.Append(col.name, col)
228          sel = self.choice_left_table.GetSelection()          self.update_sensitivity()
         rsel = self.choice_right_table.GetSelection()  
         self.valid = sel != -1 and (sel != rsel and rsel != 0)  
         self.button_join.Enable(self.valid)  
229    
230      def OnRightTable(self, event):      def OnRightTable(self, event):
231          """Get the selected table and fill the field choice."""          """Get the selected table and fill the field choice."""
232          i = self.choice_right_table.GetSelection()          i = self.choice_right_table.GetSelection()
233          table = self.choice_right_table.GetClientData(i)          table = self.choice_right_table.GetClientData(i)
234          self.choice_right_field.Clear()          self.choice_right_field.Clear()
235          for col in table.Columns():          if table is not None:
236              self.choice_right_field.Append(col.name, col)              for col in table.Columns():
237                    self.choice_right_field.Append(col.name, col)
238            self.update_sensitivity()
239    
240        def update_sensitivity(self):
241            if self.choice_left_table is not None:
242                lsel = self.choice_left_table.GetSelection()
243            else:
244                lsel = sys.maxint
245          sel = self.choice_right_table.GetSelection()          sel = self.choice_right_table.GetSelection()
246          lsel = self.choice_left_table.GetSelection()          self.button_join.Enable(sel > 0 and lsel > 0 and sel != lsel)
         self.valid = sel != -1 and (sel != lsel and lsel != 0)  
         self.button_join.Enable(self.valid)  
   

Legend:
Removed from v.1000  
changed lines
  Added in v.2700

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26