~ml-launchpad/ubuntu/natty/gcompris/fix-for-777349

« back to all changes in this revision

Viewing changes to src/boards/python/admin/class_edit.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Gariepy, Marc Gariepy, Stephane Graber
  • Date: 2010-01-04 17:42:49 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20100104174249-7bupatd9dtxyhvs4
Tags: 9.0-0ubuntu1
[Marc Gariepy]
* New upstream release (9.0).
* Remove cache.c from POTFILES to avoid FTBFS
* Remove unneeded rm in debian/rules (file no longer exists upstream)

[Stephane Graber]
* Bump Debian standards to 3.8.3
* Add patch system (dpatch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#  gcompris - class_edit.py
2
 
#
3
 
# Copyright (C) 2005 Bruno Coudoin and Yves Combe
4
 
#
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.
9
 
#
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.
14
 
#
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/>.
17
 
#
18
 
 
19
 
 
20
 
import gtk
21
 
import gobject
22
 
import gcompris
23
 
from gcompris import gcompris_gettext as _
24
 
 
25
 
# Database
26
 
try:
27
 
  import sqlite3 as sqlite
28
 
except ImportError:
29
 
  try:
30
 
    from pysqlite2 import dbapi2 as sqlite
31
 
  except ImportError:
32
 
    raise ImportError, "no module named sqlite3 or pysqlite2.dbapi2"
33
 
 
34
 
import user_list
35
 
 
36
 
import constants
37
 
 
38
 
# User List Management
39
 
(
40
 
  COLUMN_USERID,
41
 
  COLUMN_FIRSTNAME,
42
 
  COLUMN_LASTNAME,
43
 
  COLUMN_USER_EDITABLE
44
 
) = range(4)
45
 
 
46
 
 
47
 
class ClassEdit(gtk.Window):
48
 
 
49
 
    def __init__(self, db_connect, db_cursor,
50
 
                 class_id, class_name, teacher_name,
51
 
                 list_class):
52
 
        # Create the toplevel window
53
 
        gtk.Window.__init__(self)
54
 
 
55
 
        self.cur = db_cursor
56
 
        self.con = db_connect
57
 
 
58
 
        self.class_id = class_id
59
 
        self.class_name = class_name
60
 
        self.teacher_name = teacher_name
61
 
 
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
65
 
 
66
 
        self.set_title(_("Editing a Class"))
67
 
        self.set_border_width(8)
68
 
        self.set_default_size(320, 350)
69
 
 
70
 
        if(self.class_name):
71
 
            frame = gtk.Frame(_("Editing class: ") + self.class_name)
72
 
            self.new_class = False
73
 
        else:
74
 
            frame = gtk.Frame(_("Editing a new class"))
75
 
            self.new_class = True
76
 
 
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)
81
 
 
82
 
        self.add(frame)
83
 
 
84
 
        # Main VBOX
85
 
        vbox = gtk.VBox(False, 8)
86
 
        vbox.set_border_width(8)
87
 
        frame.add(vbox)
88
 
 
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)
95
 
 
96
 
        label = gtk.Label(_('Class:'))
97
 
        label.set_alignment(0, 0)
98
 
        table.attach(label, 0, 1, 0, 1, xoptions=gtk.SHRINK,
99
 
                     yoptions=gtk.EXPAND)
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)
105
 
 
106
 
        # FIXME: How to remove the default selection
107
 
 
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)
116
 
 
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)
122
 
 
123
 
        # Lower area
124
 
        hbox = gtk.HBox(False, 8)
125
 
        vbox.pack_start(hbox, True, True, 0)
126
 
 
127
 
        # Left list
128
 
        # ---------
129
 
 
130
 
        # Create the table
131
 
        sw = gtk.ScrolledWindow()
132
 
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
133
 
        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
134
 
 
135
 
        # create tree model
136
 
        self.model_left = self.__create_model(False, class_id)
137
 
 
138
 
        # create tree view
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)
143
 
 
144
 
        sw.add(treeview)
145
 
 
146
 
        # add columns to the tree view
147
 
        self.__add_columns(treeview)
148
 
 
149
 
        hbox.pack_start(sw, True, True, 0)
150
 
 
151
 
 
152
 
        # Middle Button
153
 
        # -------------
154
 
        vbox2 = gtk.VBox(False, 8)
155
 
        vbox2.set_border_width(8)
156
 
        hbox.pack_start(vbox2, True, True, 0)
157
 
 
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)
161
 
 
162
 
        button_delete = gtk.Button(stock='gtk-remove')
163
 
        vbox2.pack_start(button_delete, False, False, 0)
164
 
 
165
 
        # Right List
166
 
        # ----------
167
 
 
168
 
        # Create the table
169
 
        sw2 = gtk.ScrolledWindow()
170
 
        sw2.set_shadow_type(gtk.SHADOW_ETCHED_IN)
171
 
        sw2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
172
 
 
173
 
        # create tree model
174
 
        self.model_right = self.__create_model(True, class_id)
175
 
 
176
 
        # create tree view
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)
181
 
 
182
 
        sw2.add(treeview2)
183
 
 
184
 
        # add columns to the tree view
185
 
        self.__add_columns(treeview2)
186
 
 
187
 
        hbox.pack_start(sw2, True, True, 0)
188
 
 
189
 
        # Confirmation Buttons
190
 
        # --------------------
191
 
        vbox.pack_start(gtk.HSeparator(), False, False, 0)
192
 
 
193
 
        bbox = gtk.HBox(homogeneous=False, spacing=8)
194
 
 
195
 
        button = gtk.Button(stock='gtk-help')
196
 
        bbox.pack_start(button, expand=False, fill=False, padding=0)
197
 
 
198
 
        button = gtk.Button(stock='gtk-ok')
199
 
        bbox.pack_end(button, expand=False, fill=False, padding=0)
200
 
        button.connect("clicked", self.ok)
201
 
 
202
 
        button = gtk.Button(stock='gtk-close')
203
 
        bbox.pack_end(button, expand=False, fill=False, padding=0)
204
 
        button.connect("clicked", self.close)
205
 
 
206
 
        vbox.pack_start(bbox, False, False, 0)
207
 
 
208
 
        # Missing callbacks
209
 
        button_delete.connect("clicked", self.remove_user, treeview2)
210
 
 
211
 
        # Ready GO
212
 
        self.show_all()
213
 
 
214
 
 
215
 
    # -------------------
216
 
    # User Management
217
 
    # -------------------
218
 
 
219
 
    # Add user in the model
220
 
    def add_user_in_model(self, model, user):
221
 
        iter = model.append()
222
 
        model.set (iter,
223
 
                   COLUMN_USERID,    user[COLUMN_USERID],
224
 
                   COLUMN_FIRSTNAME, user[COLUMN_FIRSTNAME],
225
 
                   COLUMN_LASTNAME,  user[COLUMN_LASTNAME],
226
 
                   COLUMN_USER_EDITABLE,  False
227
 
                   )
228
 
 
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):
233
 
 
234
 
        # Grab the user data
235
 
        if(_with):
236
 
            self.cur.execute('SELECT user_id,firstname,lastname FROM users where class_id=? ORDER BY login', (class_id,))
237
 
        else:
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()
240
 
 
241
 
        model = gtk.ListStore(
242
 
            gobject.TYPE_INT,
243
 
            gobject.TYPE_STRING,
244
 
            gobject.TYPE_STRING,
245
 
            gobject.TYPE_BOOLEAN)
246
 
 
247
 
        for user in user_data:
248
 
            self.add_user_in_model(model, user)
249
 
 
250
 
        return model
251
 
 
252
 
    def __add_columns(self, treeview):
253
 
 
254
 
        model = treeview.get_model()
255
 
 
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)
266
 
 
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)
277
 
 
278
 
 
279
 
    # Add a user from the left list to the right list
280
 
    #
281
 
    def add_user(self, button, treeview):
282
 
        model = treeview.get_model()
283
 
        treestore, paths = treeview.get_selection().get_selected_rows()
284
 
        paths.reverse()
285
 
 
286
 
        if(len(paths)>0 and self.new_class):
287
 
            self.create_class()
288
 
 
289
 
        for path in paths:
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)
295
 
            model.remove(iter)
296
 
 
297
 
            # Add in the the right view
298
 
            self.add_user_in_model(self.model_right, (user_id, user_firstname, user_lastname))
299
 
 
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))
303
 
            self.con.commit()
304
 
            print "UPDATE users SET class_id=%d" %self.class_id
305
 
 
306
 
    # Remove a user from the right list to the left list
307
 
    #
308
 
    def remove_user(self, button, treeview):
309
 
        model = treeview.get_model()
310
 
        treestore, paths = treeview.get_selection().get_selected_rows()
311
 
        paths.reverse()
312
 
 
313
 
        for path in paths:
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)
319
 
            model.remove(iter)
320
 
 
321
 
            # Add in the the left view
322
 
            self.add_user_in_model(self.model_left, (user_id, user_firstname, user_lastname))
323
 
 
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))
326
 
            self.con.commit()
327
 
            print "UPDATE users SET class_id=1"
328
 
 
329
 
    # Done, can quit this dialog (without saving)
330
 
    #
331
 
    def close(self, button):
332
 
 
333
 
        self.list_class.reload(self.class_id,
334
 
                               self.class_name,
335
 
                               self.teacher_name)
336
 
        self.destroy()
337
 
 
338
 
    # Done, can quit this dialog with saving
339
 
    #
340
 
    def ok(self, button):
341
 
 
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"))
348
 
            dialog.run()
349
 
            dialog.destroy()
350
 
            return
351
 
 
352
 
        #
353
 
        # Now everything is correct, create the class
354
 
        #
355
 
 
356
 
        class_data = (self.class_id,
357
 
                      self.entry_class.get_text(),
358
 
                      self.entry_teacher.get_text()
359
 
                      )
360
 
 
361
 
        if(self.new_class):
362
 
            self.create_class()
363
 
 
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(),
368
 
                          self.class_id));
369
 
        self.con.commit()
370
 
 
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()
375
 
 
376
 
        print "class_edit done"
377
 
        self.destroy()
378
 
 
379
 
 
380
 
    #
381
 
    # Create a class
382
 
    # Make the necessary checks and create the class in the base
383
 
    #
384
 
    def create_class(self):
385
 
 
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"))
394
 
            dialog.run()
395
 
            dialog.destroy()
396
 
            return
397
 
 
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));
403
 
 
404
 
        class_data = (self.class_id,
405
 
                      self.entry_class.get_text(),
406
 
                      self.entry_teacher.get_text(),
407
 
                      group_id
408
 
                      )
409
 
 
410
 
        self.cur.execute('INSERT OR REPLACE INTO class (class_id, name, teacher, wholegroup_id) ' +
411
 
                         'values (?, ?, ?, ?)', class_data)
412
 
 
413
 
        # No more need to create this class, it's done
414
 
        self.new_class = False