Back to index

gcompris  8.2.2
group_edit.py
Go to the documentation of this file.
00001 #  gcompris - group_edit.py
00002 # 
00003 # Copyright (C) 2005 Bruno Coudoin and Yves Combe
00004 # 
00005 #   This program is free software; you can redistribute it and/or modify
00006 #   it under the terms of the GNU General Public License as published by
00007 #   the Free Software Foundation; either version 2 of the License, or
00008 #   (at your option) any later version.
00009 # 
00010 #   This program is distributed in the hope that it will be useful,
00011 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 #   GNU General Public License for more details.
00014 # 
00015 #   You should have received a copy of the GNU General Public License
00016 #   along with this program; if not, write to the Free Software
00017 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 # 
00019 
00020 
00021 import gtk
00022 import gobject
00023 from gettext import gettext as _
00024 
00025 import group_user_list
00026 
00027 import constants
00028 
00029 # Database
00030 from pysqlite2 import dbapi2 as sqlite
00031 
00032 # User List Management
00033 (
00034   COLUMN_USERID,
00035   COLUMN_FIRSTNAME,
00036   COLUMN_LASTNAME,
00037   COLUMN_USER_EDITABLE
00038 ) = range(4)
00039 
00040 
00041 class GroupEdit(gtk.Window):
00042 
00043     def __init__(self, db_connect, db_cursor,
00044                  class_id, class_name,
00045                  group_id, group_name, group_description,
00046                  group_user):
00047         # Create the toplevel window
00048         gtk.Window.__init__(self)
00049 
00050         self.cur = db_cursor
00051         self.con = db_connect
00052 
00053         self.group_id = group_id
00054         self.class_id = class_id
00055         
00056         # A pointer to the group_user_list class
00057         # Will be called to refresh the list when edit is done
00058         self.group_user = group_user
00059         
00060         self.set_title(_("Editing a Group"))
00061         self.set_border_width(8)
00062         self.set_default_size(320, 350)
00063 
00064         self.group_name = group_name
00065         if(self.group_name):
00066             frame = gtk.Frame(_("Editing group: ") + self.group_name +
00067                               _(" for class: ") + class_name)
00068             self.new_group = False
00069         else:
00070             frame = gtk.Frame(_("Editing a new group"))
00071             self.new_group = True
00072             self.group_name =""
00073             group_description = ""
00074 
00075 
00076         self.add(frame)
00077         
00078         # Main VBOX
00079         vbox = gtk.VBox(False, 8)
00080         vbox.set_border_width(8)
00081         frame.add(vbox)
00082 
00083         # Label and Entry for the group and description
00084         table = gtk.Table(2, 2, homogeneous=False)
00085         table.set_border_width(0)
00086         table.set_row_spacings(0)
00087         table.set_col_spacings(20)
00088         vbox.pack_start(table, True, True, 0)
00089         
00090         label = gtk.Label(_('Group:'))
00091         label.set_alignment(0, 0)
00092         table.attach(label, 0, 1, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
00093         self.entry_group = gtk.Entry()
00094         self.entry_group.set_max_length(20)
00095         self.entry_group.insert_text(self.group_name, position=0)
00096         table.attach(self.entry_group, 1, 2, 0, 1,
00097                      xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
00098 
00099         # FIXME: How to remove the selection
00100         
00101         # Label and Entry for the first name
00102         label = gtk.Label(_('Description:'))
00103         label.set_alignment(0, 0)
00104         table.attach(label, 0, 1, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
00105         self.entry_description = gtk.Entry()
00106         self.entry_description.set_max_length(30)
00107         self.entry_description.insert_text(group_description, position=0)
00108         table.attach(self.entry_description, 1, 2, 1, 2,
00109                      xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
00110 
00111 
00112         # Top message gives instructions
00113         label = gtk.Label(_('Assign all the users belonging to this group'))
00114         vbox.pack_start(label, False, False, 0)
00115         vbox.pack_start(gtk.HSeparator(), False, False, 0)
00116 
00117         # Lower area
00118         hbox = gtk.HBox(False, 8)
00119         vbox.pack_start(hbox, True, True, 0)
00120 
00121         # Left list
00122         # ---------
00123 
00124         # Create the table
00125         sw = gtk.ScrolledWindow()
00126         sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
00127         sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
00128 
00129         # create tree model
00130         self.model_left = self.__create_model(False, class_id, group_id)
00131 
00132         # create tree view
00133         treeview = gtk.TreeView(self.model_left)
00134         treeview.set_rules_hint(True)
00135         treeview.set_search_column(COLUMN_FIRSTNAME)
00136         treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
00137         
00138         sw.add(treeview)
00139         
00140         # add columns to the tree view
00141         self.__add_columns(treeview)
00142 
00143         hbox.pack_start(sw, True, True, 0)
00144 
00145 
00146         # Middle Button
00147         # -------------
00148         vbox2 = gtk.VBox(False, 8)
00149         vbox2.set_border_width(8)
00150         hbox.pack_start(vbox2, True, True, 0)
00151 
00152         button = gtk.Button(stock='gtk-add')
00153         button.connect("clicked", self.add_user, treeview)
00154         vbox2.pack_start(button, False, False, 0)
00155         button.show()
00156 
00157         button_delete = gtk.Button(stock='gtk-remove')
00158         vbox2.pack_start(button_delete, False, False, 0)
00159         button_delete.show()
00160 
00161 
00162         # Right List
00163         # ----------
00164 
00165         # Create the table
00166         sw2 = gtk.ScrolledWindow()
00167         sw2.set_shadow_type(gtk.SHADOW_ETCHED_IN)
00168         sw2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
00169 
00170         # create tree model
00171         self.model_right = self.__create_model(True, class_id, group_id)
00172 
00173         # create tree view
00174         treeview2 = gtk.TreeView(self.model_right)
00175         treeview2.set_rules_hint(True)
00176         treeview2.set_search_column(COLUMN_FIRSTNAME)
00177         treeview2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
00178 
00179         sw2.add(treeview2)
00180         
00181         # add columns to the tree view
00182         self.__add_columns(treeview2)
00183 
00184         hbox.pack_start(sw2, True, True, 0)
00185 
00186         # Confirmation Buttons
00187         # --------------------
00188         vbox.pack_start(gtk.HSeparator(), False, False, 0)
00189 
00190         bbox = gtk.HBox(homogeneous=False, spacing=8)
00191         
00192         button = gtk.Button(stock='gtk-help')
00193         bbox.pack_start(button, expand=False, fill=False, padding=0)
00194 
00195         button = gtk.Button(stock='gtk-ok')
00196         bbox.pack_end(button, expand=False, fill=False, padding=0)
00197         button.connect("clicked", self.ok)
00198 
00199         button = gtk.Button(stock='gtk-close')
00200         bbox.pack_end(button, expand=False, fill=False, padding=0)
00201         button.connect("clicked", self.close)
00202 
00203         vbox.pack_start(bbox, False, False, 0)
00204 
00205 
00206         # Missing callbacks
00207         button_delete.connect("clicked", self.remove_user, treeview2)
00208 
00209         # Ready GO
00210         self.show_all()
00211 
00212 
00213     # -------------------
00214     # GROUP Management
00215     # -------------------
00216 
00217     # Add user in the model
00218     def add_user_in_model(self, model, user):
00219         iter = model.append()
00220         model.set (iter,
00221                    COLUMN_USERID,    user[COLUMN_USERID],
00222                    COLUMN_FIRSTNAME, user[COLUMN_FIRSTNAME],
00223                    COLUMN_LASTNAME,  user[COLUMN_LASTNAME],
00224                    COLUMN_USER_EDITABLE,  False
00225                    )
00226 
00227     # class_id: only users in this class are inserted
00228     # group_id: only users in this group are inserted
00229     # If with = True,  create a list only with user in the given class_id and group_id.
00230     #           False, create a list only with user in the given class_id but NOT this group_id
00231     def __create_model(self, with, class_id, group_id):
00232 
00233         model = gtk.ListStore(
00234             gobject.TYPE_INT,
00235             gobject.TYPE_STRING,
00236             gobject.TYPE_STRING,
00237             gobject.TYPE_BOOLEAN)
00238 
00239         # Grab the all the users from this class
00240         self.cur.execute('SELECT user_id,firstname,lastname FROM users WHERE class_id=? ORDER BY login', (class_id,))
00241         user_data = self.cur.fetchall()
00242 
00243         for user in user_data:
00244 
00245             # Check our user is already in the group
00246             self.cur.execute('SELECT * FROM list_users_in_groups WHERE group_id=? AND user_id=?',
00247                              (group_id, user[0]))
00248             user_is_already = self.cur.fetchall()
00249             
00250             if(with and user_is_already):
00251                 self.add_user_in_model(model, user)
00252             elif(not with and not user_is_already):
00253                 self.add_user_in_model(model, user)
00254 
00255 
00256         return model
00257 
00258     def __add_columns(self, treeview):
00259 
00260         model = treeview.get_model()
00261         
00262         # columns for first name
00263         renderer = gtk.CellRendererText()
00264         renderer.set_data("column", COLUMN_FIRSTNAME)
00265         column = gtk.TreeViewColumn(_('First Name'), renderer,
00266                                     text=COLUMN_FIRSTNAME,
00267                                     editable=COLUMN_USER_EDITABLE)
00268         column.set_sort_column_id(COLUMN_FIRSTNAME)
00269         column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
00270         column.set_fixed_width(constants.COLUMN_WIDTH_FIRSTNAME)
00271         treeview.append_column(column)
00272 
00273         # column for last name
00274         renderer = gtk.CellRendererText()
00275         renderer.set_data("column", COLUMN_LASTNAME)
00276         column = gtk.TreeViewColumn(_('Last Name'), renderer,
00277                                     text=COLUMN_LASTNAME,
00278                                     editable=COLUMN_USER_EDITABLE)
00279         column.set_sort_column_id(COLUMN_LASTNAME)
00280         column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
00281         column.set_fixed_width(constants.COLUMN_WIDTH_LASTNAME)
00282         treeview.append_column(column)
00283 
00284 
00285     # Add a user from the left list to the right list
00286     #
00287     def add_user(self, button, treeview):
00288 
00289         model = treeview.get_model()
00290         
00291         treestore, paths = treeview.get_selection().get_selected_rows()
00292         
00293         paths.reverse()
00294         
00295         for path in paths:
00296             
00297             iter = treestore.get_iter(path)
00298             
00299             path = model.get_path(iter)[0]
00300             user_id        = model.get_value(iter, COLUMN_USERID)
00301             user_firstname = model.get_value(iter, COLUMN_FIRSTNAME)
00302             user_lastname  = model.get_value(iter, COLUMN_LASTNAME)
00303             model.remove(iter)
00304 
00305             # Add in the the right view
00306             self.add_user_in_model(self.model_right, (user_id, user_firstname, user_lastname))
00307             
00308             # Save the change in the base
00309             self.cur.execute('INSERT OR REPLACE INTO list_users_in_groups (group_id, user_id) VALUES (?, ?)',
00310                              (self.group_id, user_id))
00311             self.con.commit()
00312 
00313 
00314     # Add a user from the left list to the right list
00315     #
00316     def remove_user(self, button, treeview):
00317 
00318         model = treeview.get_model()
00319         
00320         treestore, paths = treeview.get_selection().get_selected_rows()
00321         
00322         paths.reverse()
00323         
00324         for path in paths:
00325             
00326             iter = treestore.get_iter(path)
00327             
00328             path = model.get_path(iter)[0]
00329             user_id        = model.get_value(iter, COLUMN_USERID)
00330             user_firstname = model.get_value(iter, COLUMN_FIRSTNAME)
00331             user_lastname  = model.get_value(iter, COLUMN_LASTNAME)
00332             model.remove(iter)
00333 
00334             # Add in the the left view
00335             self.add_user_in_model(self.model_left, (user_id, user_firstname, user_lastname))
00336             
00337             # Save the change in the base
00338             self.cur.execute('delete from list_users_in_groups where group_id=? and user_id=?',
00339                              (self.group_id, user_id))
00340             self.con.commit()
00341 
00342 
00343 
00344     # Done, can quit this dialog
00345     #
00346     def close(self, button):
00347         self.group_user.reload_group()
00348         self.destroy()
00349         
00350     # Done, can quit this dialog with saving
00351     #
00352     def ok(self, button):
00353 
00354         # Tell the user he must provide enough information
00355         if(self.entry_group.get_text() == ""):
00356             dialog = gtk.MessageDialog(None,
00357                                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
00358                                        gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
00359                                        _("You need to provide at least a name for your group"))
00360             dialog.run()
00361             dialog.destroy()
00362             return
00363 
00364         # If the group name as changed, check it does not exists already
00365         if(self.entry_group.get_text() != self.group_name):
00366             # Check the group does not exist already
00367             self.cur.execute('SELECT name FROM groups WHERE name=?',
00368                              (self.entry_group.get_text(),))
00369             if(self.cur.fetchone()):
00370                 dialog = gtk.MessageDialog(None,
00371                                            gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
00372                                            gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
00373                                            _("There is already a group with this name"))
00374                 dialog.run()
00375                 dialog.destroy()
00376                 return
00377 
00378         #
00379         # Now everything is correct, create the group
00380         #
00381 
00382         group_data = (self.group_id,
00383                       self.entry_group.get_text(),
00384                       self.class_id,
00385                       self.entry_description.get_text()
00386                       )
00387 
00388         if(self.new_group):
00389             # Create the new group
00390             group_id = constants.get_next_group_id(self.con, self.cur)
00391             self.cur.execute('INSERT INTO groups (group_id, name, class_id, description) ' +
00392                              'VALUES ( ?, ?, ?, ?)',
00393                              (group_data));
00394         else:
00395             # Save the group changes
00396             self.cur.execute('UPDATE groups SET name=?, description=? where group_id=?',
00397                              (self.entry_group.get_text(),
00398                               self.entry_description.get_text(),
00399                               self.group_id));
00400         self.con.commit()
00401 
00402         # Close the dialog window now
00403         self.group_user.reload_group()
00404 
00405         self.destroy()
00406