1
# gcompris - profile_edit.py
3
# Copyright (C) 2005, 2008 Bruno Coudoin and Yves Combe
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, see <http://www.gnu.org/licenses/>.
23
from gcompris import gcompris_gettext as _
25
import profile_group_list
30
from pysqlite2 import dbapi2 as sqlite
41
class ProfileEdit(gtk.Window):
43
def __init__(self, db_connect, db_cursor,
44
profile_id, profile_name, profile_description,
47
# Create the toplevel window
48
gtk.Window.__init__(self)
53
self.profile_id = profile_id
55
# A pointer to the profile_list_list class
56
# Will be called to refresh the list when edit is done
57
self.profile_list = profile_list
59
self.set_title(_("Editing a Profile"))
60
self.set_border_width(8)
61
self.set_default_size(320, 350)
64
frame = gtk.Frame(_("Editing profile: ") + profile_name)
65
self.new_profile = False
67
frame = gtk.Frame(_("Editing a new profile"))
68
self.new_profile = True
70
profile_description = ""
75
vbox = gtk.VBox(False, 8)
76
vbox.set_border_width(8)
79
# Label and Entry for the group and description
80
table = gtk.Table(2, 2, homogeneous=False)
81
table.set_border_width(0)
82
table.set_row_spacings(0)
83
table.set_col_spacings(20)
84
vbox.pack_start(table, True, True, 0)
86
label = gtk.Label(_('Profile:'))
87
label.set_alignment(0, 0)
88
table.attach(label, 0, 1, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
89
self.entry_profile = gtk.Entry()
90
self.entry_profile.set_max_length(20)
91
self.entry_profile.insert_text(profile_name, position=0)
92
table.attach(self.entry_profile, 1, 2, 0, 1,
93
xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
95
# FIXME: How to remove the selection
97
# Label and Entry for the first name
98
label = gtk.Label(_('Description:'))
99
label.set_alignment(0, 0)
100
table.attach(label, 0, 1, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
101
self.entry_description = gtk.Entry()
102
self.entry_description.set_max_length(30)
103
self.entry_description.insert_text(profile_description, position=0)
104
table.attach(self.entry_description, 1, 2, 1, 2,
105
xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
108
# Top message gives instructions
109
label = gtk.Label(_('Assign all the groups belonging to this profile'))
110
vbox.pack_start(label, False, False, 0)
111
vbox.pack_start(gtk.HSeparator(), False, False, 0)
114
hbox = gtk.HBox(False, 8)
115
vbox.pack_start(hbox, True, True, 0)
121
sw = gtk.ScrolledWindow()
122
sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
123
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
126
self.model_left = self.__create_model(False, profile_id)
129
treeview = gtk.TreeView(self.model_left)
130
treeview.set_rules_hint(True)
131
treeview.set_search_column(COLUMN_GROUPNAME)
132
treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
136
# add columns to the tree view
137
self.__add_columns(treeview)
139
hbox.pack_start(sw, True, True, 0)
144
vbox2 = gtk.VBox(False, 8)
145
vbox2.set_border_width(8)
146
hbox.pack_start(vbox2, True, True, 0)
148
button = gtk.Button(stock='gtk-add')
149
button.connect("clicked", self.add_group, treeview)
150
vbox2.pack_start(button, False, False, 0)
153
button_delete = gtk.Button(stock='gtk-remove')
154
vbox2.pack_start(button_delete, False, False, 0)
162
sw2 = gtk.ScrolledWindow()
163
sw2.set_shadow_type(gtk.SHADOW_ETCHED_IN)
164
sw2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
167
self.model_right = self.__create_model(True, profile_id)
170
treeview2 = gtk.TreeView(self.model_right)
171
treeview2.set_rules_hint(True)
172
treeview2.set_search_column(COLUMN_GROUPNAME)
173
treeview2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
177
# add columns to the tree view
178
self.__add_columns(treeview2)
180
hbox.pack_start(sw2, True, True, 0)
182
# Confirmation Buttons
183
# --------------------
184
vbox.pack_start(gtk.HSeparator(), False, False, 0)
186
bbox = gtk.HBox(homogeneous=False, spacing=8)
188
button = gtk.Button(stock='gtk-help')
189
bbox.pack_start(button, expand=False, fill=False, padding=0)
191
button = gtk.Button(stock='gtk-ok')
192
bbox.pack_end(button, expand=False, fill=False, padding=0)
193
button.connect("clicked", self.ok)
195
button = gtk.Button(stock='gtk-close')
196
bbox.pack_end(button, expand=False, fill=False, padding=0)
197
button.connect("clicked", self.close)
199
vbox.pack_start(bbox, False, False, 0)
203
button_delete.connect("clicked", self.remove_group, treeview2)
209
# -------------------
211
# -------------------
213
# Add user in the model
214
def add_group_in_model(self, model, group):
215
iter = model.append()
217
COLUMN_GROUPID, group[COLUMN_GROUPID],
218
COLUMN_CLASSNAME, group[COLUMN_CLASSNAME],
219
COLUMN_GROUPNAME, group[COLUMN_GROUPNAME],
220
COLUMN_DESCRIPTION, group[COLUMN_DESCRIPTION]
223
# profile_id: only groups in this profile are inserted
224
# If gwith = True, create a list only with groups in the given profile_id
225
# False, create a list only with groups NOT this profile_id
226
def __create_model(self, gwith, profile_id):
228
model = gtk.ListStore(
234
# Grab the all the groups
235
self.cur.execute('SELECT group_id,name,description FROM groups ORDER BY name')
236
group_data = self.cur.fetchall()
238
for group in group_data:
241
# Check our group is already in the profile
242
self.cur.execute('SELECT * FROM list_groups_in_profiles ' +
243
'WHERE profile_id=? AND group_id=?',
244
(profile_id, group_id))
245
group_is_already = self.cur.fetchall()
247
# Extract the class name of this group
248
class_name = constants.get_class_name_for_group_id(self.con,
252
# Insert the class name in the group
253
group = (group[0], class_name, group[1], group[2])
255
if(gwith and group_is_already):
256
self.add_group_in_model(model, group)
257
elif(not gwith and not group_is_already):
258
self.add_group_in_model(model, group)
262
def __add_columns(self, treeview):
264
model = treeview.get_model()
266
# columns for class name
267
renderer = gtk.CellRendererText()
268
renderer.set_data("column", COLUMN_CLASSNAME)
269
column = gtk.TreeViewColumn(_('Class'), renderer,
270
text=COLUMN_CLASSNAME)
271
column.set_sort_column_id(COLUMN_CLASSNAME)
272
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
273
column.set_fixed_width(constants.COLUMN_WIDTH_CLASSNAME)
274
treeview.append_column(column)
276
# columns for group name
277
renderer = gtk.CellRendererText()
278
renderer.set_data("column", COLUMN_GROUPNAME)
279
column = gtk.TreeViewColumn(_('Group'), renderer,
280
text=COLUMN_GROUPNAME)
281
column.set_sort_column_id(COLUMN_GROUPNAME)
282
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
283
column.set_fixed_width(constants.COLUMN_WIDTH_GROUPNAME)
284
treeview.append_column(column)
286
# column for description
287
renderer = gtk.CellRendererText()
288
renderer.set_data("column", COLUMN_DESCRIPTION)
289
column = gtk.TreeViewColumn(_('Description'), renderer,
290
text=COLUMN_DESCRIPTION)
291
column.set_sort_column_id(COLUMN_DESCRIPTION)
292
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
293
column.set_fixed_width(constants.COLUMN_WIDTH_GROUPDESCRIPTION_EDIT)
294
treeview.append_column(column)
297
# Add a group from the left list to the right list
299
def add_group(self, button, treeview):
301
model = treeview.get_model()
303
treestore, paths = treeview.get_selection().get_selected_rows()
309
iter = treestore.get_iter(path)
311
path = model.get_path(iter)[0]
312
group_id = model.get_value(iter, COLUMN_GROUPID)
313
class_name = model.get_value(iter, COLUMN_CLASSNAME)
314
group_name = model.get_value(iter, COLUMN_GROUPNAME)
315
group_description = model.get_value(iter, COLUMN_DESCRIPTION)
318
# Add in the the right view
319
self.add_group_in_model(self.model_right,
320
(group_id, class_name, group_name, group_description))
322
# Save the change in the base
323
self.cur.execute('INSERT OR REPLACE INTO list_groups_in_profiles ' +
324
'(profile_id, group_id) VALUES (?, ?)',
325
(self.profile_id, group_id))
329
# Add a group from the left list to the right list
331
def remove_group(self, button, treeview):
333
model = treeview.get_model()
335
treestore, paths = treeview.get_selection().get_selected_rows()
341
iter = treestore.get_iter(path)
343
path = model.get_path(iter)[0]
344
group_id = model.get_value(iter, COLUMN_GROUPID)
345
class_name = model.get_value(iter, COLUMN_CLASSNAME)
346
group_name = model.get_value(iter, COLUMN_GROUPNAME)
347
group_description = model.get_value(iter, COLUMN_DESCRIPTION)
350
# Add in the the left view
351
self.add_group_in_model(self.model_left,
352
(group_id, class_name, group_name, group_description))
354
# Save the change in the base
355
self.cur.execute('DELETE FROM list_groups_in_profiles ' +
356
'WHERE profile_id=? AND group_id=?',
357
(self.profile_id, group_id))
362
# Done, can quit this dialog
364
def close(self, button):
365
self.profile_list.reload_profile()
368
# Done, can quit this dialog with saving
370
def ok(self, button):
372
# Tell the user he must provide enough information
373
if(self.entry_profile.get_text().strip() == ""):
374
dialog = gtk.MessageDialog(None,
375
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
376
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
377
_("You need to provide at least a name for your profile"))
383
# Now everything is correct, create the profile
386
profile_data = (self.profile_id,
387
self.entry_profile.get_text().strip(),
388
self.entry_description.get_text()
391
if(self.new_profile):
392
# Check the login do not exist already
393
self.cur.execute('SELECT name FROM profiles WHERE name=?',
394
(self.entry_profile.get_text(),))
395
if(self.cur.fetchone()):
396
dialog = gtk.MessageDialog(None,
397
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
398
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
399
_("There is already a profile with this name"))
404
# Create the new profile
405
profile_id = constants.get_next_profile_id(self.con, self.cur)
406
self.cur.execute('INSERT INTO profiles (profile_id, name, description) ' +
410
# Save the profile changes
411
self.cur.execute('UPDATE profiles SET name=?, description=? where profile_id=?',
412
(self.entry_profile.get_text(),
413
self.entry_description.get_text(),
417
# Close the dialog window now
418
self.profile_list.reload_profile()