1
# gcompris - class_edit.py
3
# Copyright (C) 2005 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 _
27
import sqlite3 as sqlite
30
from pysqlite2 import dbapi2 as sqlite
32
raise ImportError, "no module named sqlite3 or pysqlite2.dbapi2"
38
# User List Management
47
class ClassEdit(gtk.Window):
49
def __init__(self, db_connect, db_cursor,
50
class_id, class_name, teacher_name,
52
# Create the toplevel window
53
gtk.Window.__init__(self)
58
self.class_id = class_id
59
self.class_name = class_name
60
self.teacher_name = teacher_name
62
# A pointer to the user_list class
63
# Will be called to refresh the list when edit is done
64
self.list_class = list_class
66
self.set_title(_("Editing a Class"))
67
self.set_border_width(8)
68
self.set_default_size(320, 350)
71
frame = gtk.Frame(_("Editing class: ") + self.class_name)
72
self.new_class = False
74
frame = gtk.Frame(_("Editing a new class"))
77
# Connect the "destroy" event to close
78
# FIXME: This makes the close code beeing called twice
79
# because the close destroy also call close again.
80
frame.connect("destroy", self.close)
85
vbox = gtk.VBox(False, 8)
86
vbox.set_border_width(8)
89
# Label and Entry for the class name
90
table = gtk.Table(2, 2, homogeneous=False)
91
table.set_border_width(0)
92
table.set_row_spacings(0)
93
table.set_col_spacings(20)
94
vbox.pack_start(table, True, True, 0)
96
label = gtk.Label(_('Class:'))
97
label.set_alignment(0, 0)
98
table.attach(label, 0, 1, 0, 1, xoptions=gtk.SHRINK,
100
self.entry_class = gtk.Entry()
101
self.entry_class.set_max_length(20)
102
self.entry_class.insert_text(self.class_name, position=0)
103
table.attach(self.entry_class, 1, 2, 0, 1,
104
xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
106
# FIXME: How to remove the default selection
108
# Label and Entry for the teacher name
109
label = gtk.Label(_('Teacher:'))
110
label.set_alignment(0, 0)
111
table.attach(label, 0, 1, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
112
self.entry_teacher = gtk.Entry()
113
self.entry_teacher.set_max_length(30)
114
self.entry_teacher.insert_text(self.teacher_name, position=0)
115
table.attach(self.entry_teacher, 1, 2, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
117
# Top message gives instructions
118
vbox.pack_start(gtk.HSeparator(), False, False, 0)
119
label = gtk.Label(_('Assign all the users belonging to this class'))
120
vbox.pack_start(label, False, False, 0)
121
vbox.pack_start(gtk.HSeparator(), False, False, 0)
124
hbox = gtk.HBox(False, 8)
125
vbox.pack_start(hbox, True, True, 0)
131
sw = gtk.ScrolledWindow()
132
sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
133
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
136
self.model_left = self.__create_model(False, class_id)
139
treeview = gtk.TreeView(self.model_left)
140
treeview.set_rules_hint(True)
141
treeview.set_search_column(COLUMN_FIRSTNAME)
142
treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
146
# add columns to the tree view
147
self.__add_columns(treeview)
149
hbox.pack_start(sw, True, True, 0)
154
vbox2 = gtk.VBox(False, 8)
155
vbox2.set_border_width(8)
156
hbox.pack_start(vbox2, True, True, 0)
158
button_add = gtk.Button(stock='gtk-add')
159
button_add.connect("clicked", self.add_user, treeview)
160
vbox2.pack_start(button_add, False, False, 0)
162
button_delete = gtk.Button(stock='gtk-remove')
163
vbox2.pack_start(button_delete, False, False, 0)
169
sw2 = gtk.ScrolledWindow()
170
sw2.set_shadow_type(gtk.SHADOW_ETCHED_IN)
171
sw2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
174
self.model_right = self.__create_model(True, class_id)
177
treeview2 = gtk.TreeView(self.model_right)
178
treeview2.set_rules_hint(True)
179
treeview2.set_search_column(COLUMN_FIRSTNAME)
180
treeview2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
184
# add columns to the tree view
185
self.__add_columns(treeview2)
187
hbox.pack_start(sw2, True, True, 0)
189
# Confirmation Buttons
190
# --------------------
191
vbox.pack_start(gtk.HSeparator(), False, False, 0)
193
bbox = gtk.HBox(homogeneous=False, spacing=8)
195
button = gtk.Button(stock='gtk-help')
196
bbox.pack_start(button, expand=False, fill=False, padding=0)
198
button = gtk.Button(stock='gtk-ok')
199
bbox.pack_end(button, expand=False, fill=False, padding=0)
200
button.connect("clicked", self.ok)
202
button = gtk.Button(stock='gtk-close')
203
bbox.pack_end(button, expand=False, fill=False, padding=0)
204
button.connect("clicked", self.close)
206
vbox.pack_start(bbox, False, False, 0)
209
button_delete.connect("clicked", self.remove_user, treeview2)
215
# -------------------
217
# -------------------
219
# Add user in the model
220
def add_user_in_model(self, model, user):
221
iter = model.append()
223
COLUMN_USERID, user[COLUMN_USERID],
224
COLUMN_FIRSTNAME, user[COLUMN_FIRSTNAME],
225
COLUMN_LASTNAME, user[COLUMN_LASTNAME],
226
COLUMN_USER_EDITABLE, False
229
# If class_id is provided, only users in this class are inserted
230
# If with = True, create a list only with the given class_id.
231
# False, create a list only without the given class_id
232
def __create_model(self, _with, class_id):
236
self.cur.execute('SELECT user_id,firstname,lastname FROM users where class_id=? ORDER BY login', (class_id,))
238
self.cur.execute('SELECT user_id,firstname,lastname FROM users WHERE class_id!=? ORDER BY login', (class_id,))
239
user_data = self.cur.fetchall()
241
model = gtk.ListStore(
245
gobject.TYPE_BOOLEAN)
247
for user in user_data:
248
self.add_user_in_model(model, user)
252
def __add_columns(self, treeview):
254
model = treeview.get_model()
256
# columns for first name
257
renderer = gtk.CellRendererText()
258
renderer.set_data("column", COLUMN_FIRSTNAME)
259
column = gtk.TreeViewColumn(_('First Name'), renderer,
260
text=COLUMN_FIRSTNAME,
261
editable=COLUMN_USER_EDITABLE)
262
column.set_sort_column_id(COLUMN_FIRSTNAME)
263
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
264
column.set_fixed_width(constants.COLUMN_WIDTH_FIRSTNAME)
265
treeview.append_column(column)
267
# column for last name
268
renderer = gtk.CellRendererText()
269
renderer.set_data("column", COLUMN_LASTNAME)
270
column = gtk.TreeViewColumn(_('Last Name'), renderer,
271
text=COLUMN_LASTNAME,
272
editable=COLUMN_USER_EDITABLE)
273
column.set_sort_column_id(COLUMN_LASTNAME)
274
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
275
column.set_fixed_width(constants.COLUMN_WIDTH_LASTNAME)
276
treeview.append_column(column)
279
# Add a user from the left list to the right list
281
def add_user(self, button, treeview):
282
model = treeview.get_model()
283
treestore, paths = treeview.get_selection().get_selected_rows()
286
if(len(paths)>0 and self.new_class):
290
iter = treestore.get_iter(path)
291
path = model.get_path(iter)[0]
292
user_id = model.get_value(iter, COLUMN_USERID)
293
user_firstname = model.get_value(iter, COLUMN_FIRSTNAME)
294
user_lastname = model.get_value(iter, COLUMN_LASTNAME)
297
# Add in the the right view
298
self.add_user_in_model(self.model_right, (user_id, user_firstname, user_lastname))
300
# Save the change in the base
301
self.cur.execute('UPDATE users SET class_id=? WHERE user_id=?',
302
(self.class_id, user_id))
304
print "UPDATE users SET class_id=%d" %self.class_id
306
# Remove a user from the right list to the left list
308
def remove_user(self, button, treeview):
309
model = treeview.get_model()
310
treestore, paths = treeview.get_selection().get_selected_rows()
314
iter = treestore.get_iter(path)
315
path = model.get_path(iter)[0]
316
user_id = model.get_value(iter, COLUMN_USERID)
317
user_firstname = model.get_value(iter, COLUMN_FIRSTNAME)
318
user_lastname = model.get_value(iter, COLUMN_LASTNAME)
321
# Add in the the left view
322
self.add_user_in_model(self.model_left, (user_id, user_firstname, user_lastname))
324
# Save the change in the base (1 Is the 'Unselected user' class)
325
self.cur.execute('UPDATE users SET class_id=? where user_id=?', (1, user_id))
327
print "UPDATE users SET class_id=1"
329
# Done, can quit this dialog (without saving)
331
def close(self, button):
333
self.list_class.reload(self.class_id,
338
# Done, can quit this dialog with saving
340
def ok(self, button):
342
# Tell the user he must provide enough information
343
if(self.entry_class.get_text() == ""):
344
dialog = gtk.MessageDialog(None,
345
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
346
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
347
_("You need to provide at least a name for your class"))
353
# Now everything is correct, create the class
356
class_data = (self.class_id,
357
self.entry_class.get_text(),
358
self.entry_teacher.get_text()
364
# Save the changes in the base
365
self.cur.execute('UPDATE class set name=?,teacher=? where class_id=?',
366
(self.entry_class.get_text(),
367
self.entry_teacher.get_text(),
371
# Close the dialog window now
372
# (The close code will refresh the class_list)
373
self.class_name = self.entry_class.get_text()
374
self.teacher_name = self.entry_teacher.get_text()
376
print "class_edit done"
382
# Make the necessary checks and create the class in the base
384
def create_class(self):
386
# Check the login do not exist already
387
self.cur.execute('SELECT name FROM class WHERE name=?',
388
(self.entry_class.get_text(),))
389
if(self.cur.fetchone()):
390
dialog = gtk.MessageDialog(None,
391
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
392
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
393
_("There is already a class with this name"))
398
# Create its Whole group
399
group_id = constants.get_next_group_id(self.con, self.cur)
400
self.cur.execute('INSERT INTO groups (group_id, name, class_id, description) ' +
401
'VALUES ( ?, "All", ?, "All users")',
402
(group_id, self.class_id));
404
class_data = (self.class_id,
405
self.entry_class.get_text(),
406
self.entry_teacher.get_text(),
410
self.cur.execute('INSERT OR REPLACE INTO class (class_id, name, teacher, wholegroup_id) ' +
411
'values (?, ?, ?, ?)', class_data)
413
# No more need to create this class, it's done
414
self.new_class = False