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

Annotation of /branches/WIP-pyshapelib-bramz/Thuban/UI/dbdialog.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (hide annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 14367 byte(s)
made a copy
1 bh 2102 # Copyright (c) 2001, 2003, 2004 by Intevation GmbH
2 bh 1620 # Authors:
3     # Martin Mueller <[email protected]>
4     # Bernhard Herzog <[email protected]>
5     #
6     # This program is free software under the GPL (>=v2)
7     # Read the file COPYING coming with Thuban for details.
8    
9    
10     """Dialogs to manage database connections"""
11    
12     import sys, traceback
13    
14 dpinte 2700 import wx
15 bh 1620
16 bh 1625 try:
17     import psycopg
18     except ImportError:
19     psycopg = None
20 bh 1620
21     from Thuban import _
22     from Thuban.UI.dialogs import NonModalDialog
23 bh 2102 from Thuban.Model.table import FIELDTYPE_INT
24 bh 1648 from Thuban.Model.postgisdb import ConnectionError, PostGISConnection
25 bh 1620 from Thuban.Model.messages import DBCONN_ADDED, DBCONN_REMOVED
26     from messages import SESSION_REPLACED
27    
28    
29     ID_DB_ADD = 9101
30     ID_DB_REMOVE = 9102
31    
32     ID_DBCHOOSE_RETRIEVE = 9201
33     ID_DBCHOOSE_OK = 9202
34     ID_DBCHOOSE_CANCEL = 9203
35     ID_LB_DCLICK = 9204
36    
37    
38 dpinte 2700 class ChooseDBTableDialog(wx.Dialog):
39 bh 1620
40 bh 1695 def __init__(self, parent, session):
41 dpinte 2700 wx.Dialog.__init__(self, parent, -1, _("Choose layer from database"),
42     style = wx.DIALOG_MODAL|wx.CAPTION)
43 bh 1620 self.session = session
44     self.dbconns = self.session.DBConnections()
45     self.tables = []
46 bh 2102
47     #
48     # Build the dialog
49     #
50    
51     # Sizer for the entire dialog
52 dpinte 2700 top = wx.FlexGridSizer(2, 1, 0, 0)
53 bh 2102
54     # Sizer for the main part with the list boxes
55 dpinte 2700 main_sizer = wx.BoxSizer(wx.HORIZONTAL)
56     top.Add(main_sizer, 1, wx.EXPAND, 0)
57 bh 2102
58     # The list box with the connections
59 dpinte 2700 static_box = wx.StaticBoxSizer(wx.StaticBox(self, -1, _("Databases")),
60     wx.HORIZONTAL)
61     self.lb_connections = wx.ListBox(self, -1)
62     static_box.Add(self.lb_connections, 0, wx.EXPAND, 0)
63     main_sizer.Add(static_box, 1, wx.EXPAND, 0)
64 bh 2102
65 bh 1620 for i in range(len(self.dbconns)):
66 bh 2102 self.lb_connections.Append(self.dbconns[i].BriefDescription())
67     if self.lb_connections.GetCount() > 0:
68     self.lb_connections.SetSelection(0, True)
69 bh 1620
70 bh 2102 # The button box between the connections list box and the table
71     # list box
72 dpinte 2700 buttons = wx.FlexGridSizer(3, 1, 0, 0)
73     buttons.Add( (20, 80), 0, wx.EXPAND, 0)
74     retrieve_button = wx.Button(self, ID_DBCHOOSE_RETRIEVE, _("Retrieve"))
75     self.Bind(wx.EVT_BUTTON, self.OnRetrieve, id=ID_DBCHOOSE_RETRIEVE)
76     buttons.Add(retrieve_button, 0, wx.ALL
77     |wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 4)
78     buttons.Add( (20, 80), 0, wx.EXPAND, 0)
79     main_sizer.Add(buttons, 0, wx.EXPAND, 0)
80 bh 2102
81     # The list box with the tables
82 dpinte 2700 static_box = wx.StaticBoxSizer(wx.StaticBox(self, -1, _("Tables")),
83     wx.HORIZONTAL)
84     self.lb_tables = wx.ListBox(self, ID_LB_DCLICK)
85     self.Bind(wx.EVT_LISTBOX, self.OnTableSelect, id=ID_LB_DCLICK)
86     self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnLBDClick, id=ID_LB_DCLICK)
87     static_box.Add(self.lb_tables, 0, wx.EXPAND, 0)
88     main_sizer.Add(static_box, 1, wx.EXPAND, 0)
89 bh 1620
90 bh 2102 # id column and geometry column selection
91 dpinte 2700 box = wx.BoxSizer(wx.VERTICAL)
92     box.Add(wx.StaticText(self, -1, _("ID Column")), 0,
93     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
94     self.text_id_column = wx.ComboBox(self, -1, "")
95 bh 2102 box.Add(self.text_id_column, 0,
96 dpinte 2700 wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
97 bh 2102
98 dpinte 2700 box.Add(wx.StaticText(self, -1, _("Geometry Column")), 0,
99     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
100     self.text_geo_column = wx.ComboBox(self, -1, "")
101 bh 2102 box.Add(self.text_geo_column, 0,
102 dpinte 2700 wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
103     main_sizer.Add(box, 1, wx.EXPAND, 0)
104 bh 2102
105     # The standard button box at the bottom of the dialog
106 dpinte 2700 buttons = wx.FlexGridSizer(1, 2, 0, 0)
107     ok_button = wx.Button(self, ID_DBCHOOSE_OK, _("OK"))
108     self.Bind(wx.EVT_BUTTON, self.OnOK, id=ID_DBCHOOSE_OK)
109     buttons.Add(ok_button, 0, wx.ALL|wx.ALIGN_RIGHT, 4)
110     cancel_button = wx.Button(self, ID_DBCHOOSE_CANCEL, _("Cancel"))
111     self.Bind(wx.EVT_BUTTON, self.OnCancel, id=ID_DBCHOOSE_CANCEL)
112     buttons.Add(cancel_button, 0, wx.ALL, 4)
113     top.Add(buttons, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 4)
114 bh 2102
115     # Autosizing
116 bh 1620 self.SetAutoLayout(1)
117 bh 2102 self.SetSizer(top)
118     top.Fit(self)
119     top.SetSizeHints(self)
120 bh 1620 self.Layout()
121    
122 bh 2102
123 bh 1620 def GetTable(self):
124 bh 2102 i = self.lb_tables.GetSelection()
125 bh 1620 if i >= 0:
126 bh 2102 return (self.selected_conn, self.tables[i],
127     self.text_id_column.GetValue(),
128     self.text_geo_column.GetValue())
129 bh 1620 return None
130    
131     def OnRetrieve(self, event):
132 bh 2102 i = self.lb_connections.GetSelection()
133 bh 1620 if i >= 0:
134     self.selected_conn = self.dbconns[i]
135     self.tables = self.selected_conn.GeometryTables()
136 bh 2102 self.lb_tables.Set(self.tables)
137 bh 1620
138 bh 2102 def OnTableSelect(self, event):
139     i = self.lb_tables.GetSelection()
140     self.text_id_column.Clear()
141     self.text_geo_column.Clear()
142     if i >= 0:
143     for name, typ in self.selected_conn.table_columns(self.tables[i]):
144     if typ == "geometry":
145     self.text_geo_column.Append(name)
146     elif typ == FIELDTYPE_INT:
147     self.text_id_column.Append(name)
148    
149 bh 1620 def OnLBDClick(self, event):
150 bh 2102 if self.lb_tables.GetSelection() >= 0:
151 dpinte 2700 self.EndModal(wx.ID_OK)
152 bh 1695 self.Show(False)
153 bh 1620
154     def OnOK(self, event):
155 dpinte 2700 self.EndModal(wx.ID_OK)
156 bh 1695 self.Show(False)
157 bh 1620
158     def OnCancel(self, event):
159 dpinte 2700 self.EndModal(wx.ID_CANCEL)
160 bh 1695 self.Show(False)
161 bh 1620
162    
163 dpinte 2700 class DBDialog(wx.Dialog):
164 bh 1620
165     """Dialog for the parameters of a database connection"""
166    
167 bh 1648 def __init__(self, parent, title, parameters, message = ""):
168     """Initialize the dialog box.
169 bh 1620
170 bh 1648 The parameters argument should be a dictionary containing known
171     connection parameters.
172 bh 1620
173 bh 1648 The optional message parameter will be displayed at the top of
174     the dialog box and can be used to display error messages when
175     using the dialog to ask for correct parameters when the
176     connection can't be established.
177     """
178 dpinte 2700 wx.Dialog.__init__(self, parent, -1, title)
179 bh 1620
180 dpinte 2700 top = wx.BoxSizer(wx.VERTICAL)
181 bh 1620
182 bh 1648 if message:
183 dpinte 2700 top.Add(wx.StaticText(self, -1, message), 0,
184     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
185 bh 1620
186 dpinte 2700 box = wx.BoxSizer(wx.HORIZONTAL)
187     box.Add(wx.StaticText(self, -1, _("Hostname:")), 0,
188     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
189     self.text_host = wx.TextCtrl(self, -1, parameters.get("host", ""))
190     box.Add(self.text_host, 2, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
191     box.Add(wx.StaticText(self, -1, _("Port:")), 0,
192     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
193     self.text_port = wx.TextCtrl(self, -1, parameters.get("port", ""))
194     box.Add(self.text_port, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
195     top.Add(box, 0, wx.EXPAND)
196 bh 1620
197 dpinte 2700 box = wx.BoxSizer(wx.HORIZONTAL)
198     box.Add(wx.StaticText(self, -1, _("Database Name:")), 0,
199     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
200     self.text_dbname = wx.TextCtrl(self, -1,
201 bh 1648 parameters.get("dbname", ""))
202 dpinte 2700 box.Add(self.text_dbname, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
203     top.Add(box, 0, wx.EXPAND)
204 bh 1620
205 dpinte 2700 box = wx.BoxSizer(wx.HORIZONTAL)
206     box.Add(wx.StaticText(self, -1, _("User:")), 0,
207     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
208     self.text_user = wx.TextCtrl(self, -1,
209 bh 1648 parameters.get("user", ""))
210 dpinte 2700 box.Add(self.text_user, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
211     box.Add(wx.StaticText(self, -1, _("Password:")), 0,
212     wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
213     self.text_password = wx.TextCtrl(self, -1,
214 bh 1648 parameters.get("password", ""),
215 dpinte 2700 style = wx.TE_PASSWORD)
216     box.Add(self.text_password, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
217 bh 1648 4)
218 dpinte 2700 top.Add(box, 0, wx.EXPAND)
219 bh 1620
220 dpinte 2700 buttons = wx.BoxSizer(wx.HORIZONTAL)
221     button = wx.Button(self, wx.ID_OK, _("OK"))
222     buttons.Add(button, 0, wx.ALL, 4)
223     button = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
224     buttons.Add(button, 0, wx.ALL, 4)
225     top.Add(buttons, 0, wx.ALIGN_RIGHT, 4)
226 bh 1620
227 bh 1648 self.SetAutoLayout(1)
228     self.SetSizer(top)
229     top.Fit(self)
230     top.SetSizeHints(self)
231    
232 dpinte 2700 self.Bind(wx.EVT_BUTTON, self.OnOK, id=wx.ID_OK)
233     self.Bind(wx.EVT_BUTTON, self.OnCancel, id=wx.ID_CANCEL)
234 bh 1648
235     def RunDialog(self):
236     self.ShowModal()
237     self.Destroy()
238     return self.result
239    
240     def end_dialog(self, result):
241     self.result = result
242     if result is not None:
243 dpinte 2700 self.EndModal(wx.ID_OK)
244 bh 1648 else:
245 dpinte 2700 self.EndModal(wx.ID_CANCEL)
246 bh 1695 self.Show(False)
247 bh 1620
248 bh 1648 def OnOK(self, event):
249     result = {}
250     for name in ("host", "port", "dbname", "user", "password"):
251     result[name] = getattr(self, "text_" + name).GetValue()
252     self.end_dialog(result)
253    
254 bh 1620 def OnCancel(self, event):
255 bh 1648 self.end_dialog(None)
256 bh 1620
257    
258 bh 1648
259 bh 1620 class DBFrame(NonModalDialog):
260    
261     """Databse connection management dialog"""
262    
263     def __init__(self, parent, name, session, *args, **kwds):
264 dpinte 2700 kwds["style"] = wx.ICONIZE|wx.CAPTION|wx.MINIMIZE
265 bh 1620 NonModalDialog.__init__(self, parent, name, "")
266     self.session = session
267     self.app = self.parent.application
268    
269     self.app.Subscribe(SESSION_REPLACED, self.session_replaced)
270     self.subscribe_session()
271    
272 dpinte 2700 self.DB_ListBox = wx.ListBox(self, -1,
273     style=wx.LB_SINGLE|wx.LB_HSCROLL|wx.LB_ALWAYS_SB)
274     self.DB_Add = wx.Button(self, ID_DB_ADD, _("Add"))
275     self.DB_Remove = wx.Button(self, ID_DB_REMOVE, _("Remove"))
276     self.DB_CLOSE = wx.Button(self, wx.ID_CLOSE, _("Close"))
277 bh 1620 self.__set_properties()
278     self.__do_layout()
279 dpinte 2700 self.Bind(wx.EVT_BUTTON, self.OnAdd, id=ID_DB_ADD)
280     self.Bind(wx.EVT_BUTTON, self.OnRemove, id=ID_DB_REMOVE)
281     self.Bind(wx.EVT_BUTTON, self.OnClose, id=wx.ID_CLOSE)
282 bh 1620
283     self.conns_changed()
284    
285     def __set_properties(self):
286     self.SetTitle(_("Database Management"))
287     self.DB_ListBox.SetSize((200, 157))
288    
289     def __do_layout(self):
290 dpinte 2700 top = wx.BoxSizer(wx.VERTICAL)
291 bh 1620
292 dpinte 2700 box = wx.BoxSizer(wx.HORIZONTAL)
293 bh 1620
294 dpinte 2700 box.Add(self.DB_ListBox, 1, wx.ALL|wx.EXPAND
295     |wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 4)
296 bh 1620
297 dpinte 2700 buttons = wx.BoxSizer(wx.VERTICAL)
298     buttons.Add(self.DB_Add, 0, wx.ALL, 4)
299     buttons.Add(self.DB_Remove, 0, wx.ALL, 4)
300 bh 1620
301 dpinte 2700 box.Add(buttons, 0, wx.EXPAND)
302     top.Add(box, 1, wx.EXPAND)
303 bh 1620
304 dpinte 2700 buttons = wx.BoxSizer(wx.HORIZONTAL)
305     buttons.Add(self.DB_CLOSE, 1, wx.ALL|wx.ALIGN_RIGHT, 4)
306     top.Add(buttons, 0, wx.ALIGN_RIGHT)
307 bh 1620
308     self.SetAutoLayout(1)
309     self.SetSizer(top)
310     top.Fit(self)
311     top.SetSizeHints(self)
312    
313     def subscribe_session(self):
314     """Internal: Subscribe to some session messages"""
315     self.session.Subscribe(DBCONN_ADDED, self.conns_changed)
316     self.session.Subscribe(DBCONN_REMOVED, self.conns_changed)
317    
318     def unsubscribe_session(self):
319     """Internal: Subscribe from messages subscribe in subscribe_session"""
320     self.session.Subscribe(DBCONN_ADDED, self.conns_changed)
321     self.session.Subscribe(DBCONN_REMOVED, self.conns_changed)
322    
323     def session_replaced(self, *args):
324     """Internal: resubscribe the session messages
325    
326     This method is a subscriber for the application's
327     SESSION_REPLACED messages.
328     """
329     self.unsubscribe_session()
330     self.session = self.app.Session()
331     self.subscribe_session()
332     self.conns_changed()
333    
334     def conns_changed(self, *args):
335     """Internal: update the db connection list box
336    
337 bh 1956 Subscribed to the DBCONN_ADDED and DBCONN_REMOVED messages.
338 bh 1620 """
339     self.DB_ListBox.Clear()
340     for conn in self.session.DBConnections():
341     self.DB_ListBox.Append(conn.BriefDescription(), conn)
342    
343     def OnClose(self, event):
344     self.unsubscribe_session()
345     self.app.Unsubscribe(SESSION_REPLACED, self.session_replaced)
346     NonModalDialog.OnClose(self, event)
347    
348 dpinte 2700 def RunMessageBox(self, title, text, flags = wx.OK | wx.ICON_INFORMATION):
349 bh 1620 """Run a modal message box with the given text, title and flags
350     and return the result"""
351     dlg = wxMessageDialog(self, text, title, flags)
352     dlg.CenterOnParent()
353     result = dlg.ShowModal()
354     dlg.Destroy()
355     return result
356    
357     def OnAdd(self, event):
358 bh 1648 message = ""
359     parameters = {}
360 bh 1620 while 1:
361 bh 1648 dialog = DBDialog(self, _("Add Database"), parameters, message)
362     parameters = dialog.RunDialog()
363     if parameters is not None:
364 bh 1620 for conn in self.session.DBConnections():
365 bh 1956 if conn.MatchesParameters(parameters):
366 bh 1620 self.RunMessageBox(_("Add Database"),
367 bh 1956 _("Connection '%s' already exists")
368     % conn.BriefDescription())
369 bh 1620 break
370 bh 1648 else:
371 bh 1956 try:
372     conn = PostGISConnection(**parameters)
373     except ConnectionError, val:
374     message = str(val)
375     else:
376     self.session.AddDBConnection(conn)
377     break
378 bh 1620 else:
379     break
380    
381     def OnRemove(self, event):
382     i = self.DB_ListBox.GetSelection()
383     if i >= 0:
384 bh 1630 conn = self.DB_ListBox.GetClientData(i)
385     if self.session.CanRemoveDBConnection(conn):
386     self.session.RemoveDBConnection(conn)
387     else:
388     self.RunMessageBox(_("Remove Database Connection"),
389     _("The connection %s\nis still in use")
390     % conn.BriefDescription())

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26