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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show 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 # Copyright (c) 2001, 2003, 2004 by Intevation GmbH
2 # 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 import wx
15
16 try:
17 import psycopg
18 except ImportError:
19 psycopg = None
20
21 from Thuban import _
22 from Thuban.UI.dialogs import NonModalDialog
23 from Thuban.Model.table import FIELDTYPE_INT
24 from Thuban.Model.postgisdb import ConnectionError, PostGISConnection
25 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 class ChooseDBTableDialog(wx.Dialog):
39
40 def __init__(self, parent, session):
41 wx.Dialog.__init__(self, parent, -1, _("Choose layer from database"),
42 style = wx.DIALOG_MODAL|wx.CAPTION)
43 self.session = session
44 self.dbconns = self.session.DBConnections()
45 self.tables = []
46
47 #
48 # Build the dialog
49 #
50
51 # Sizer for the entire dialog
52 top = wx.FlexGridSizer(2, 1, 0, 0)
53
54 # Sizer for the main part with the list boxes
55 main_sizer = wx.BoxSizer(wx.HORIZONTAL)
56 top.Add(main_sizer, 1, wx.EXPAND, 0)
57
58 # The list box with the connections
59 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
65 for i in range(len(self.dbconns)):
66 self.lb_connections.Append(self.dbconns[i].BriefDescription())
67 if self.lb_connections.GetCount() > 0:
68 self.lb_connections.SetSelection(0, True)
69
70 # The button box between the connections list box and the table
71 # list box
72 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
81 # The list box with the tables
82 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
90 # id column and geometry column selection
91 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 box.Add(self.text_id_column, 0,
96 wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
97
98 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 box.Add(self.text_geo_column, 0,
102 wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
103 main_sizer.Add(box, 1, wx.EXPAND, 0)
104
105 # The standard button box at the bottom of the dialog
106 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
115 # Autosizing
116 self.SetAutoLayout(1)
117 self.SetSizer(top)
118 top.Fit(self)
119 top.SetSizeHints(self)
120 self.Layout()
121
122
123 def GetTable(self):
124 i = self.lb_tables.GetSelection()
125 if i >= 0:
126 return (self.selected_conn, self.tables[i],
127 self.text_id_column.GetValue(),
128 self.text_geo_column.GetValue())
129 return None
130
131 def OnRetrieve(self, event):
132 i = self.lb_connections.GetSelection()
133 if i >= 0:
134 self.selected_conn = self.dbconns[i]
135 self.tables = self.selected_conn.GeometryTables()
136 self.lb_tables.Set(self.tables)
137
138 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 def OnLBDClick(self, event):
150 if self.lb_tables.GetSelection() >= 0:
151 self.EndModal(wx.ID_OK)
152 self.Show(False)
153
154 def OnOK(self, event):
155 self.EndModal(wx.ID_OK)
156 self.Show(False)
157
158 def OnCancel(self, event):
159 self.EndModal(wx.ID_CANCEL)
160 self.Show(False)
161
162
163 class DBDialog(wx.Dialog):
164
165 """Dialog for the parameters of a database connection"""
166
167 def __init__(self, parent, title, parameters, message = ""):
168 """Initialize the dialog box.
169
170 The parameters argument should be a dictionary containing known
171 connection parameters.
172
173 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 wx.Dialog.__init__(self, parent, -1, title)
179
180 top = wx.BoxSizer(wx.VERTICAL)
181
182 if message:
183 top.Add(wx.StaticText(self, -1, message), 0,
184 wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
185
186 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
197 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 parameters.get("dbname", ""))
202 box.Add(self.text_dbname, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 4)
203 top.Add(box, 0, wx.EXPAND)
204
205 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 parameters.get("user", ""))
210 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 parameters.get("password", ""),
215 style = wx.TE_PASSWORD)
216 box.Add(self.text_password, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
217 4)
218 top.Add(box, 0, wx.EXPAND)
219
220 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
227 self.SetAutoLayout(1)
228 self.SetSizer(top)
229 top.Fit(self)
230 top.SetSizeHints(self)
231
232 self.Bind(wx.EVT_BUTTON, self.OnOK, id=wx.ID_OK)
233 self.Bind(wx.EVT_BUTTON, self.OnCancel, id=wx.ID_CANCEL)
234
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 self.EndModal(wx.ID_OK)
244 else:
245 self.EndModal(wx.ID_CANCEL)
246 self.Show(False)
247
248 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 def OnCancel(self, event):
255 self.end_dialog(None)
256
257
258
259 class DBFrame(NonModalDialog):
260
261 """Databse connection management dialog"""
262
263 def __init__(self, parent, name, session, *args, **kwds):
264 kwds["style"] = wx.ICONIZE|wx.CAPTION|wx.MINIMIZE
265 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 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 self.__set_properties()
278 self.__do_layout()
279 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
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 top = wx.BoxSizer(wx.VERTICAL)
291
292 box = wx.BoxSizer(wx.HORIZONTAL)
293
294 box.Add(self.DB_ListBox, 1, wx.ALL|wx.EXPAND
295 |wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 4)
296
297 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
301 box.Add(buttons, 0, wx.EXPAND)
302 top.Add(box, 1, wx.EXPAND)
303
304 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
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 Subscribed to the DBCONN_ADDED and DBCONN_REMOVED messages.
338 """
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 def RunMessageBox(self, title, text, flags = wx.OK | wx.ICON_INFORMATION):
349 """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 message = ""
359 parameters = {}
360 while 1:
361 dialog = DBDialog(self, _("Add Database"), parameters, message)
362 parameters = dialog.RunDialog()
363 if parameters is not None:
364 for conn in self.session.DBConnections():
365 if conn.MatchesParameters(parameters):
366 self.RunMessageBox(_("Add Database"),
367 _("Connection '%s' already exists")
368 % conn.BriefDescription())
369 break
370 else:
371 try:
372 conn = PostGISConnection(**parameters)
373 except ConnectionError, val:
374 message = str(val)
375 else:
376 self.session.AddDBConnection(conn)
377 break
378 else:
379 break
380
381 def OnRemove(self, event):
382 i = self.DB_ListBox.GetSelection()
383 if i >= 0:
384 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