/[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 1956 - (show annotations)
Tue Nov 18 15:37:38 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/Thuban/UI/dbdialog.py
File MIME type: text/x-python
File size: 12610 byte(s)
(DBFrame.conns_changed): Fix doc-string
(DBFrame.OnAdd): Use the new MatchesParameters method when looking
for existing connections with the same parameters and break out of
the loop correctly.

1 # Copyright (c) 2001, 2003 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 from wxPython.wx import *
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.postgisdb import ConnectionError, PostGISConnection
24 from Thuban.Model.messages import DBCONN_ADDED, DBCONN_REMOVED
25 from messages import SESSION_REPLACED
26
27
28 ID_DB_ADD = 9101
29 ID_DB_REMOVE = 9102
30
31 ID_DBCHOOSE_RETRIEVE = 9201
32 ID_DBCHOOSE_OK = 9202
33 ID_DBCHOOSE_CANCEL = 9203
34 ID_LB_DCLICK = 9204
35
36
37 class ChooseDBTableDialog(wxDialog):
38
39 def __init__(self, parent, session):
40 wxDialog.__init__(self, parent, -1, _("Choose layer from database"),
41 style = wxDIALOG_MODAL|wxCAPTION)
42 self.session = session
43 self.dbconns = self.session.DBConnections()
44 self.tables = []
45 self.list_box_4 = wxListBox(self, -1)
46 for i in range(len(self.dbconns)):
47 self.list_box_4.Append(self.dbconns[i].BriefDescription())
48 if self.list_box_4.GetCount() > 0:
49 self.list_box_4.SetSelection(0, True)
50 self.DB_CHOOSE_RETRIEVE = wxButton(self, ID_DBCHOOSE_RETRIEVE,
51 _("Retrieve"))
52 self.list_box_5 = wxListBox(self, ID_LB_DCLICK)
53 self.DB_CHOOSE_OK = wxButton(self, ID_DBCHOOSE_OK, _("OK"))
54 self.DB_CHOOSE_CANCEL = wxButton(self, ID_DBCHOOSE_CANCEL, _("Cancel"))
55 self.__do_layout()
56
57 EVT_BUTTON(self, ID_DBCHOOSE_OK, self.OnOK)
58 EVT_BUTTON(self, ID_DBCHOOSE_CANCEL, self.OnCancel)
59 EVT_BUTTON(self, ID_DBCHOOSE_RETRIEVE, self.OnRetrieve)
60 EVT_LISTBOX_DCLICK(self, ID_LB_DCLICK, self.OnLBDClick)
61
62 def __do_layout(self):
63 grid_sizer_1 = wxFlexGridSizer(2, 1, 0, 0)
64 grid_sizer_3 = wxFlexGridSizer(1, 2, 0, 0)
65 grid_sizer_2 = wxFlexGridSizer(1, 3, 0, 0)
66 sizer_4 = wxStaticBoxSizer(wxStaticBox(self, -1, _("Tables")),
67 wxHORIZONTAL)
68 grid_sizer_4 = wxFlexGridSizer(3, 1, 0, 0)
69 sizer_3 = wxStaticBoxSizer(wxStaticBox(self, -1, _("Databases")),
70 wxHORIZONTAL)
71 sizer_3.Add(self.list_box_4, 0, wxEXPAND, 0)
72 grid_sizer_2.Add(sizer_3, 1, wxEXPAND, 0)
73 grid_sizer_4.Add(20, 80, 0, wxEXPAND, 0)
74 grid_sizer_4.Add(self.DB_CHOOSE_RETRIEVE, 0, wxALL
75 |wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4)
76 grid_sizer_4.Add(20, 80, 0, wxEXPAND, 0)
77 grid_sizer_2.Add(grid_sizer_4, 1, wxEXPAND, 0)
78 sizer_4.Add(self.list_box_5, 0, wxEXPAND, 0)
79 grid_sizer_2.Add(sizer_4, 1, wxEXPAND, 0)
80 grid_sizer_1.Add(grid_sizer_2, 1, wxEXPAND, 0)
81 grid_sizer_3.Add(self.DB_CHOOSE_OK, 0, wxALL|wxALIGN_RIGHT, 4)
82 grid_sizer_3.Add(self.DB_CHOOSE_CANCEL, 0, wxALL, 4)
83 grid_sizer_1.Add(grid_sizer_3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL, 4)
84 self.SetAutoLayout(1)
85 self.SetSizer(grid_sizer_1)
86 grid_sizer_1.Fit(self)
87 grid_sizer_1.SetSizeHints(self)
88 self.Layout()
89
90 def GetTable(self):
91 i = self.list_box_5.GetSelection()
92 if i >= 0:
93 return self.selected_conn, self.tables[i]
94 return None
95
96 def OnRetrieve(self, event):
97 i = self.list_box_4.GetSelection()
98 if i >= 0:
99 self.selected_conn = self.dbconns[i]
100 self.tables = self.selected_conn.GeometryTables()
101 self.list_box_5.Set(self.tables)
102
103 def OnLBDClick(self, event):
104 if self.list_box_5.GetSelection() >= 0:
105 self.EndModal(wxID_OK)
106 self.Show(False)
107
108 def OnOK(self, event):
109 self.EndModal(wxID_OK)
110 self.Show(False)
111
112 def OnCancel(self, event):
113 self.EndModal(wxID_CANCEL)
114 self.Show(False)
115
116
117 class DBDialog(wxDialog):
118
119 """Dialog for the parameters of a database connection"""
120
121 def __init__(self, parent, title, parameters, message = ""):
122 """Initialize the dialog box.
123
124 The parameters argument should be a dictionary containing known
125 connection parameters.
126
127 The optional message parameter will be displayed at the top of
128 the dialog box and can be used to display error messages when
129 using the dialog to ask for correct parameters when the
130 connection can't be established.
131 """
132 wxDialog.__init__(self, parent, -1, title)
133
134 top = wxBoxSizer(wxVERTICAL)
135
136 if message:
137 top.Add(wxStaticText(self, -1, message), 0,
138 wxALL|wxALIGN_CENTER_VERTICAL, 4)
139
140 box = wxBoxSizer(wxHORIZONTAL)
141 box.Add(wxStaticText(self, -1, _("Hostname:")), 0,
142 wxALL|wxALIGN_CENTER_VERTICAL, 4)
143 self.text_host = wxTextCtrl(self, -1, parameters.get("host", ""))
144 box.Add(self.text_host, 2, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 4)
145 box.Add(wxStaticText(self, -1, _("Port:")), 0,
146 wxALL|wxALIGN_CENTER_VERTICAL, 4)
147 self.text_port = wxTextCtrl(self, -1, parameters.get("port", ""))
148 box.Add(self.text_port, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 4)
149 top.Add(box, 0, wxEXPAND)
150
151 box = wxBoxSizer(wxHORIZONTAL)
152 box.Add(wxStaticText(self, -1, _("Database Name:")), 0,
153 wxALL|wxALIGN_CENTER_VERTICAL, 4)
154 self.text_dbname = wxTextCtrl(self, -1,
155 parameters.get("dbname", ""))
156 box.Add(self.text_dbname, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 4)
157 top.Add(box, 0, wxEXPAND)
158
159 box = wxBoxSizer(wxHORIZONTAL)
160 box.Add(wxStaticText(self, -1, _("User:")), 0,
161 wxALL|wxALIGN_CENTER_VERTICAL, 4)
162 self.text_user = wxTextCtrl(self, -1,
163 parameters.get("user", ""))
164 box.Add(self.text_user, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 4)
165 box.Add(wxStaticText(self, -1, _("Password:")), 0,
166 wxALL|wxALIGN_CENTER_VERTICAL, 4)
167 self.text_password = wxTextCtrl(self, -1,
168 parameters.get("password", ""),
169 style = wxTE_PASSWORD)
170 box.Add(self.text_password, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND,
171 4)
172 top.Add(box, 0, wxEXPAND)
173
174 buttons = wxBoxSizer(wxHORIZONTAL)
175 button = wxButton(self, wxID_OK, _("OK"))
176 buttons.Add(button, 0, wxALL, 4)
177 button = wxButton(self, wxID_CANCEL, _("Cancel"))
178 buttons.Add(button, 0, wxALL, 4)
179 top.Add(buttons, 0, wxALIGN_RIGHT, 4)
180
181 self.SetAutoLayout(1)
182 self.SetSizer(top)
183 top.Fit(self)
184 top.SetSizeHints(self)
185
186 EVT_BUTTON(self, wxID_OK, self.OnOK)
187 EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
188
189 def RunDialog(self):
190 self.ShowModal()
191 self.Destroy()
192 return self.result
193
194 def end_dialog(self, result):
195 self.result = result
196 if result is not None:
197 self.EndModal(wxID_OK)
198 else:
199 self.EndModal(wxID_CANCEL)
200 self.Show(False)
201
202 def OnOK(self, event):
203 result = {}
204 for name in ("host", "port", "dbname", "user", "password"):
205 result[name] = getattr(self, "text_" + name).GetValue()
206 self.end_dialog(result)
207
208 def OnCancel(self, event):
209 self.end_dialog(None)
210
211
212
213 class DBFrame(NonModalDialog):
214
215 """Databse connection management dialog"""
216
217 def __init__(self, parent, name, session, *args, **kwds):
218 kwds["style"] = wxICONIZE|wxCAPTION|wxMINIMIZE
219 NonModalDialog.__init__(self, parent, name, "")
220 self.session = session
221 self.app = self.parent.application
222
223 self.app.Subscribe(SESSION_REPLACED, self.session_replaced)
224 self.subscribe_session()
225
226 self.DB_ListBox = wxListBox(self, -1,
227 style=wxLB_SINGLE|wxLB_HSCROLL|wxLB_ALWAYS_SB)
228 self.DB_Add = wxButton(self, ID_DB_ADD, _("Add"))
229 self.DB_Remove = wxButton(self, ID_DB_REMOVE, _("Remove"))
230 self.DB_CLOSE = wxButton(self, wxID_CLOSE, _("Close"))
231 self.__set_properties()
232 self.__do_layout()
233 EVT_BUTTON(self, ID_DB_ADD, self.OnAdd)
234 EVT_BUTTON(self, ID_DB_REMOVE, self.OnRemove)
235 EVT_BUTTON(self, wxID_CLOSE, self.OnClose)
236
237 self.conns_changed()
238
239 def __set_properties(self):
240 self.SetTitle(_("Database Management"))
241 self.DB_ListBox.SetSize((200, 157))
242
243 def __do_layout(self):
244 top = wxBoxSizer(wxVERTICAL)
245
246 box = wxBoxSizer(wxHORIZONTAL)
247
248 box.Add(self.DB_ListBox, 1, wxALL|wxEXPAND
249 |wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4)
250
251 buttons = wxBoxSizer(wxVERTICAL)
252 buttons.Add(self.DB_Add, 0, wxALL, 4)
253 buttons.Add(self.DB_Remove, 0, wxALL, 4)
254
255 box.Add(buttons, 0, wxEXPAND)
256 top.Add(box, 1, wxEXPAND)
257
258 buttons = wxBoxSizer(wxHORIZONTAL)
259 buttons.Add(self.DB_CLOSE, 1, wxALL|wxALIGN_RIGHT, 4)
260 top.Add(buttons, 0, wxALIGN_RIGHT)
261
262 self.SetAutoLayout(1)
263 self.SetSizer(top)
264 top.Fit(self)
265 top.SetSizeHints(self)
266
267 def subscribe_session(self):
268 """Internal: Subscribe to some session messages"""
269 self.session.Subscribe(DBCONN_ADDED, self.conns_changed)
270 self.session.Subscribe(DBCONN_REMOVED, self.conns_changed)
271
272 def unsubscribe_session(self):
273 """Internal: Subscribe from messages subscribe in subscribe_session"""
274 self.session.Subscribe(DBCONN_ADDED, self.conns_changed)
275 self.session.Subscribe(DBCONN_REMOVED, self.conns_changed)
276
277 def session_replaced(self, *args):
278 """Internal: resubscribe the session messages
279
280 This method is a subscriber for the application's
281 SESSION_REPLACED messages.
282 """
283 self.unsubscribe_session()
284 self.session = self.app.Session()
285 self.subscribe_session()
286 self.conns_changed()
287
288 def conns_changed(self, *args):
289 """Internal: update the db connection list box
290
291 Subscribed to the DBCONN_ADDED and DBCONN_REMOVED messages.
292 """
293 self.DB_ListBox.Clear()
294 for conn in self.session.DBConnections():
295 self.DB_ListBox.Append(conn.BriefDescription(), conn)
296
297 def OnClose(self, event):
298 self.unsubscribe_session()
299 self.app.Unsubscribe(SESSION_REPLACED, self.session_replaced)
300 NonModalDialog.OnClose(self, event)
301
302 def RunMessageBox(self, title, text, flags = wxOK | wxICON_INFORMATION):
303 """Run a modal message box with the given text, title and flags
304 and return the result"""
305 dlg = wxMessageDialog(self, text, title, flags)
306 dlg.CenterOnParent()
307 result = dlg.ShowModal()
308 dlg.Destroy()
309 return result
310
311 def OnAdd(self, event):
312 message = ""
313 parameters = {}
314 while 1:
315 dialog = DBDialog(self, _("Add Database"), parameters, message)
316 parameters = dialog.RunDialog()
317 if parameters is not None:
318 for conn in self.session.DBConnections():
319 if conn.MatchesParameters(parameters):
320 self.RunMessageBox(_("Add Database"),
321 _("Connection '%s' already exists")
322 % conn.BriefDescription())
323 break
324 else:
325 try:
326 conn = PostGISConnection(**parameters)
327 except ConnectionError, val:
328 message = str(val)
329 else:
330 self.session.AddDBConnection(conn)
331 break
332 else:
333 break
334
335 def OnRemove(self, event):
336 i = self.DB_ListBox.GetSelection()
337 if i >= 0:
338 conn = self.DB_ListBox.GetClientData(i)
339 if self.session.CanRemoveDBConnection(conn):
340 self.session.RemoveDBConnection(conn)
341 else:
342 self.RunMessageBox(_("Remove Database Connection"),
343 _("The connection %s\nis still in use")
344 % 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