1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import pygtk
22 import gobject
23 pygtk.require('2.0')
24 import gtk
25 import sqlobject
26 from sqlobject.col import *
27 import ConfigParser
28 import datetime
29 from gettext import gettext as _
30
32 """A compound widget that displays connection settings. The settings can be read from or written
33 to a config file. You can use <i>pysqlgtk.get_connstr_from_file(filename, passw=None)</i> to
34 build an URI from the config file settings."""
36 gtk.VBox.__init__(self)
37 table = gtk.Table(rows=4,columns=2, homogeneous=True)
38 self.pack_start(table, expand=False)
39
40 label = gtk.Label(_("Database Type:"))
41 label.set_alignment(1,0.5)
42 table.attach(label,0,1,0,1)
43 dbms_list = gtk.ListStore(str,str)
44
45 list_values =[('sqlite','SQLite'),
46 ('mysql','MySQL'),
47 ('postgres','PostGres'),
48 ('firebird','FireBird'),
49 ('interbase','InterBase'),
50 ('maxdb','Max DB'),
51 ('sapdb','Sap DB'),
52 ('mssql','MSSQL Server'),
53 ('sybase','Sybase')]
54
55 for list_value in list_values:
56 dbms_list.append(list_value)
57 self.dbms = gtk.ComboBox(dbms_list)
58 cell = gtk.CellRendererText()
59 self.dbms.pack_start(cell, True)
60 self.dbms.add_attribute(cell, 'text', 1)
61 table.attach(self.dbms,1,2,0,1)
62
63 label = gtk.Label("Host:")
64 label.set_alignment(1,0.5)
65 table.attach(label,0,1,1,2)
66 self.host = gtk.Entry()
67 table.attach(self.host,1,2,1,2)
68
69 label = gtk.Label("Port:")
70 label.set_alignment(1,0.5)
71 table.attach(label,0,1,2,3)
72 self.port = gtk.Entry()
73 table.attach(self.port,1,2,2,3)
74
75 label = gtk.Label(_("Database:"))
76 label.set_alignment(1,0.5)
77 table.attach(label,0,1,3,4)
78 self.db = gtk.Entry()
79 table.attach(self.db,1,2,3,4)
80
81 label = gtk.Label(_("Username:"))
82 label.set_alignment(1,0.5)
83 table.attach(label,0,1,4,5)
84 self.user = gtk.Entry()
85 table.attach(self.user,1,2,4,5)
86
87 label = gtk.Label(_("Password:"))
88 label.set_alignment(1,0.5)
89 table.attach(label,0,1,5,6)
90 self.pw = gtk.Entry()
91 self.pw.set_visibility(False)
92 table.attach(self.pw,1,2,5,6)
93
94 self.safepw =gtk.CheckButton(label=_("safe Password"))
95 table.attach(self.safepw,1,2,6,7)
96
97 self.config_parser = ConfigParser.SafeConfigParser()
98
100 """Reads the setting from <i>filename</i> The format of the config file must be RFC 822 compliant.
101 The values are retrieved from a section [dbconn], The value names in the config file are
102 host, port, db, user, safepw and pw. If safepw is set to True, the password is retrieved from
103 pw. Passwords are stored in clear text, so they do not suggest any security, however some way of
104 simple password encryption may be thought of in the next future."""
105 self.config_parser.read(filename)
106 dbms = self.config_parser.get("dbconn","dbms")
107 model = self.dbms.get_model()
108 for i in range(0,len(model)):
109 if model[i][0] == dbms:
110 self.dbms.set_active(i)
111
112
113 self.host.set_text(self.config_parser.get("dbconn","host"))
114 self.port.set_text(self.config_parser.get("dbconn","port"))
115 self.db.set_text(self.config_parser.get("dbconn","db"))
116 self.user.set_text(self.config_parser.get("dbconn","user"))
117 self.safepw.set_active(self.config_parser.getboolean("dbconn","safepw"))
118 if self.safepw.get_active():
119 self.pw.set_text(self.config_parser.get("dbconn","pw"))
120
122 "Writes the settings into the section [dbconn] in <i>filename</i>"""
123 model = self.dbms.get_model()
124 active= self.dbms.get_active()
125 dbms = model[active][0]
126 self.config_parser.set("dbconn","dbms",dbms)
127 self.config_parser.set("dbconn","host",self.host.get_text())
128 self.config_parser.set("dbconn","port",self.port.get_text())
129 self.config_parser.set("dbconn","db",self.db.get_text())
130 self.config_parser.set("dbconn","user",self.user.get_text())
131 self.config_parser.set("dbconn","safepw",str(self.safepw.get_active()))
132 if self.safepw.get_active():
133 self.config_parser.set("dbconn","pw",self.pw.get_text())
134 else:
135 self.config_parser.set("dbconn","pw",""())
136 config_file = file(filename,'w')
137 self.config_parser.write(config_file)
138 config_file.close()
139
140
142 __col_description = None
143
144
147
149 for descriptor in self.__col_description:
150 if len(descriptor) == 2:
151 attribute, label = descriptor
152 renderer_type = gtk.CellRendererText
153 elif len(descriptor) == 3:
154 attribute, label, renderer_type = descriptor
155 column = gtk.TreeViewColumn(label)
156 self.append_column(column)
157 renderer = renderer_type()
158 column.pack_start(renderer)
159 colnum = self.get_model().get_col_by_attr(attribute)
160 column.set_attributes(renderer, text=colnum)
161
163 """takes a list of tuples, each tuple containign the column name according to the SQLObject
164 attribute name, the label that will be shown at the top of each column and optionally the type of
165 cellrenderer that has should be used. if the last one is not given, a gtk.CellRendererText will be used."""
166 if self.get_model():
167 self.__col_description = col_description
168 self.__create_cols()
169
171 """Returns an SQLObject instance for the active treeview row. Returns None if nothing is selected.
172 For convenience, the extremely strict separation of model and view as applied by gtk is broken here.
173 However, in this case it doesn't make much sense to stick too strictly
174 to the paradigm and this method really doesn't do any harm."""
175 selection = self.get_selection()
176 selected = selection.get_selected()
177 return self.get_model().get_row(selected[1])
178
183
184 -class DateEntry(gtk.HBox):
185 """A compound widget for Dates, that also does some formatting."""
186 - def __init__(self,format="dmy", separator='-'):
187 gtk.HBox.__init__(self)
188 self.__separator = separator
189 self.format = format
190 gtk.HBox.__init__(self)
191 self.entry = gtk.Entry()
192 self.pack_start(self.entry, expand=False)
193 self.entry.show()
194 self.button = gtk.Button("...")
195 self.pack_start(self.button)
196 self.button.show()
197 self.button.connect("clicked", self.show_calendar)
198
200 """Sets the way, the date is formatted, value can be 'dmy' or 'ymd'."""
201 self.format = format
202 self.format_date()
203
206
207 - def set_separator(self, separator):
208 """Sets the char used as separator for formatting date values"""
209 self.__separator = separator
210 self.format_date()
211
212 - def get_separator(self):
213 return self.separator
214
215 - def set_editable(self, is_editable):
216 self.entry.set_editable(is_editable)
217 self.button.set_sensitive(is_editable)
218
219 - def set_value(self, value):
220 if type(value) is datetime.date:
221 if self.format == "dmy":
222 datestr = str(value.day)+self.__separator+str(value.month)+self.__separator+str(value.year)
223 elif self.format == "ymd":
224 datestr = str(value.year)+self.__separator+str(value.month)+self.__separator+str(value.day)
225 self.entry.set_text(datestr)
226 if type(value) is str:
227
228 self.entry.set_text(value)
229
230 - def get_value(self):
231 self.format_date()
232 value_list = self.entry.get_text().split(self.__separator)
233 if self.format == "dmy":
234 return datetime.date(int(value_list[2]), int(value_list[1]), int(value_list[0]))
235 elif self.format =="ymd":
236 return datetime.date(value_list[0], value_list[1], value_list[2])
237 else:
238 return None
239
241 str = self.entry.get_text()
242 separators = [",",";",".",":","/"]
243 for sep in separators:
244 str = str.replace(sep,self.__separator)
245 self.entry.set_text(str)
246
247 - def show_calendar(self, w):
248 dialog = gtk.Dialog("Connection Settings",parent=None)
249 dialog.set_position(gtk.WIN_POS_MOUSE)
250 dialog.add_buttons(gtk.STOCK_OK,gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)
251 calendar = gtk.Calendar()
252 calendar.set_display_options(gtk.CALENDAR_WEEK_START_MONDAY|gtk.CALENDAR_SHOW_HEADING)
253 dialog.vbox.pack_start(calendar, expand=False)
254 calendar.show()
255 response_id = dialog.run()
256 if response_id == gtk.RESPONSE_ACCEPT:
257 if self.format == "dmy":
258 datevalue = calendar.get_date()
259
260 datestr = str(datevalue[2])+self.__separator+str(datevalue[1]+1)+self.__separator+str(datevalue[0])
261 elif self.format == "ymd":
262 datestr = str(datevalue[0])+self.__separator+str(datevalue[1]+1)+self.__separator+str(datevalue[2])
263 else:
264 datestr = str(datevalue[0])+self.__separator+str(datevalue[1]+1)+self.__separator+str(datevalue[2])
265 self.entry.set_text(datestr)
266 dialog.destroy()
267 elif response_id == gtk.RESPONSE_REJECT:
268 dialog.destroy()
269
272
275