Commit 70d5d91e authored by Bruno Coudoin's avatar Bruno Coudoin
Browse files

Hopefully completed the user/group/profile edition.

	Completed the code, added some checkings.
	Still need some testing.
	Made the icons.
parent 3b745b3f
2005-07-31 Bruno coudoin <bruno.coudoin@free.fr>
Hopefully completed the user/group/profile edition.
Completed the code, added some checkings.
Still need some testing.
* boards/skins/default/config_boards.png:
* boards/skins/default/config_groups.png:
* boards/skins/default/config_profiles.png:
* boards/skins/default/config_users.png:
* src/boards/python/admin/class_edit.py:
* src/boards/python/admin/constants.py:
* src/boards/python/admin/group_edit.py:
* src/boards/python/admin/group_list.py:
* src/boards/python/admin/group_user_list.py:
* src/boards/python/admin/module_groups.py:
* src/boards/python/admin/module_profiles.py:
* src/boards/python/admin/module_users.py:
* src/boards/python/admin/profile_edit.py:
* src/boards/python/admin/profile_group_list.py:
* src/boards/python/admin/profile_list.py:
* src/boards/python/admin/user_edit.py:
* src/boards/python/admin/user_list.py:
* src/boards/python/administration.py:
2005-07-30 Bruno coudoin <bruno.coudoin@free.fr>
Completed management of the wholegroup. Now after editing class users
......
boards/skins/default/config_groups.png

2.71 KB | W: | H:

boards/skins/default/config_groups.png

4.83 KB | W: | H:

boards/skins/default/config_groups.png
boards/skins/default/config_groups.png
boards/skins/default/config_groups.png
boards/skins/default/config_groups.png
  • 2-up
  • Swipe
  • Onion skin
boards/skins/default/config_users.png

2.71 KB | W: | H:

boards/skins/default/config_users.png

5.47 KB | W: | H:

boards/skins/default/config_users.png
boards/skins/default/config_users.png
boards/skins/default/config_users.png
boards/skins/default/config_users.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -69,6 +69,8 @@ class ClassEdit(gtk.Window):
self.new_class = True
# Connect the "destroy" event to close
# FIXME: This makes the close code beeing called twice
# because the close destroy also call close again.
frame.connect("destroy", self.close)
self.add(frame)
......@@ -93,7 +95,7 @@ class ClassEdit(gtk.Window):
self.entry_class.insert_text(class_name, position=0)
table.attach(self.entry_class, 1, 2, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
# FIXME: How to remove the selection
# FIXME: How to remove the default selection
# Label and Entry for the teacher name
label = gtk.Label(_('Teacher:'))
......@@ -371,12 +373,38 @@ class ClassEdit(gtk.Window):
#
def ok(self, button):
# Tell the user he must provide enough information
if(self.entry_class.get_text() == ""):
dialog = gtk.MessageDialog(None,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
_("You need to provide at least a name for your class"))
dialog.run()
dialog.destroy()
return
#
# Now everything is correct, create the class
#
class_data = (self.class_id,
self.entry_class.get_text(),
self.entry_teacher.get_text()
)
if(self.new_class):
# Check the login do not exist already
self.cur.execute('SELECT name FROM class WHERE name=?',
(self.entry_class.get_text(),))
if(self.cur.fetchone()):
dialog = gtk.MessageDialog(None,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
_("There is already a class with this name"))
dialog.run()
dialog.destroy()
return
# Create its Whole group
group_id = constants.get_next_group_id(self.con, self.cur)
self.cur.execute('INSERT INTO groups (group_id, name, class_id, description) ' +
......
......@@ -29,7 +29,7 @@ COLUMN_WIDTH_CLASSNAME = 100
COLUMN_WIDTH_TEACHER = 300
COLUMN_WIDTH_GROUPNAME = 100
COLUMN_WIDTH_GROUPDESCRIPTION = 300
COLUMN_WIDTH_GROUPDESCRIPTION = 200
COLUMN_WIDTH_GROUPDESCRIPTION_EDIT = 150
COLUMN_WIDTH_PROFILENAME = 100
......@@ -68,3 +68,47 @@ def get_next_group_id(con, cur):
return group_id
# Return the next profile id in the base
# Params are db_connect, db_cursor
def get_next_profile_id(con, cur):
cur.execute('select max(profile_id) from profiles')
profile_id = cur.fetchone()[0]
if(profile_id == None):
profile_id=0
else:
profile_id += 1
return profile_id
# get_wholegroup_id
# From the given class_id, return it's wholegroup_id
# Params are db_connect, db_cursor, class_id
def get_wholegroup_id(con, cur, class_id):
cur.execute('SELECT wholegroup_id FROM class WHERE class_id=?',
(class_id,))
return(cur.fetchone()[0])
# get_class_name_for_group_id
# From the given group_id, return it's class name
# Or "" if not found
def get_class_name_for_group_id(con, cur, group_id):
class_name = ""
# Extract the class name of this group
cur.execute('SELECT class_id FROM groups WHERE group_id=?',
(group_id,))
result = cur.fetchall()
if(result):
class_id = result[0][0]
cur.execute('SELECT name FROM class WHERE class_id=?',
(class_id,))
result = cur.fetchall()
if(result):
class_name = result[0][0]
return class_name
......@@ -42,7 +42,7 @@ class GroupEdit(gtk.Window):
def __init__(self, db_connect, db_cursor,
class_id, class_name,
group_id, group_name,
group_id, group_name, group_description,
group_user):
# Create the toplevel window
gtk.Window.__init__(self)
......@@ -52,7 +52,6 @@ class GroupEdit(gtk.Window):
self.group_id = group_id
self.class_id = class_id
print "Editing group_id = " + str(self.group_id) + " In class " + str(self.class_id)
# A pointer to the group_user_list class
# Will be called to refresh the list when edit is done
......@@ -62,14 +61,53 @@ class GroupEdit(gtk.Window):
self.set_border_width(8)
self.set_default_size(320, 350)
frame = gtk.Frame(_("Editing group: ") + group_name
+ _(" for class: ") + class_name)
if(group_name and group_description):
frame = gtk.Frame(_("Editing group: ") + group_name +
_(" for class: ") + class_name)
self.new_group = False
else:
frame = gtk.Frame(_("Editing a new group"))
self.new_group = True
group_name =""
group_description = ""
self.add(frame)
# Main VBOX
vbox = gtk.VBox(False, 8)
vbox.set_border_width(8)
frame.add(vbox)
# Label and Entry for the group and description
table = gtk.Table(2, 2, homogeneous=False)
table.set_border_width(0)
table.set_row_spacings(0)
table.set_col_spacings(20)
vbox.pack_start(table, True, True, 0)
label = gtk.Label(_('Group:'))
label.set_alignment(0, 0)
table.attach(label, 0, 1, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
self.entry_group = gtk.Entry()
self.entry_group.set_max_length(20)
self.entry_group.insert_text(group_name, position=0)
table.attach(self.entry_group, 1, 2, 0, 1,
xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
# FIXME: How to remove the selection
# Label and Entry for the first name
label = gtk.Label(_('Description:'))
label.set_alignment(0, 0)
table.attach(label, 0, 1, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
self.entry_description = gtk.Entry()
self.entry_description.set_max_length(30)
self.entry_description.insert_text(group_description, position=0)
table.attach(self.entry_description, 1, 2, 1, 2,
xoptions=gtk.SHRINK, yoptions=gtk.EXPAND)
# Top message gives instructions
label = gtk.Label(_('Assign all the users bellonging to this group'))
vbox.pack_start(label, False, False, 0)
......@@ -148,20 +186,22 @@ class GroupEdit(gtk.Window):
# --------------------
vbox.pack_start(gtk.HSeparator(), False, False, 0)
bbox = gtk.HButtonBox()
bbox.set_border_width(5)
bbox.set_layout(gtk.BUTTONBOX_EDGE)
bbox.set_spacing(40)
bbox = gtk.HBox(homogeneous=False, spacing=8)
button = gtk.Button(stock='gtk-help')
bbox.add(button)
bbox.pack_start(button, expand=False, fill=False, padding=0)
button = gtk.Button(stock='gtk-ok')
bbox.pack_end(button, expand=False, fill=False, padding=0)
button.connect("clicked", self.ok)
button = gtk.Button(stock='gtk-close')
bbox.add(button)
bbox.pack_end(button, expand=False, fill=False, padding=0)
button.connect("clicked", self.close)
vbox.pack_start(bbox, False, False, 0)
# Missing callbacks
button_delete.connect("clicked", self.remove_user, treeview2)
......@@ -170,7 +210,7 @@ class GroupEdit(gtk.Window):
# -------------------
# User Management
# GROUP Management
# -------------------
# Add user in the model
......@@ -303,6 +343,61 @@ class GroupEdit(gtk.Window):
# Done, can quit this dialog
#
def close(self, button):
self.group_user.reload(self.group_id)
self.group_user.reload_group()
self.destroy()
# Done, can quit this dialog with saving
#
def ok(self, button):
# Tell the user he must provide enough information
if(self.entry_group.get_text() == ""):
dialog = gtk.MessageDialog(None,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
_("You need to provide at least a name for your group"))
dialog.run()
dialog.destroy()
return
# Check the login do not exist already
self.cur.execute('SELECT name FROM groups WHERE name=?',
(self.entry_group.get_text(),))
if(self.cur.fetchone()):
dialog = gtk.MessageDialog(None,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
_("There is already a group with this name"))
dialog.run()
dialog.destroy()
return
#
# Now everything is correct, create the group
#
group_data = (self.group_id,
self.entry_group.get_text(),
self.class_id,
self.entry_description.get_text()
)
if(self.new_group):
# Create the new group
group_id = constants.get_next_group_id(self.con, self.cur)
self.cur.execute('INSERT INTO groups (group_id, name, class_id, description) ' +
'VALUES ( ?, ?, ?, ?)',
(group_data));
else:
# Save the group changes
self.cur.execute('UPDATE groups SET name=?, description=? where group_id=?',
(self.entry_group.get_text(),
self.entry_description.get_text(),
self.group_id));
self.con.commit()
# Close the dialog window now
self.group_user.reload_group()
self.destroy()
......@@ -39,9 +39,8 @@ import constants
(
COLUMN_GROUPID,
COLUMN_NAME,
COLUMN_DESCRIPTION,
COLUMN_GROUP_EDITABLE
) = range(4)
COLUMN_DESCRIPTION
) = range(3)
class Group_list:
"""GCompris Group List Table"""
......@@ -142,15 +141,17 @@ class Group_list:
vbox_button.pack_start(button, False, False, 0)
button.show()
button = gtk.Button(stock='gtk-edit')
button.connect("clicked", self.on_edit_group_clicked, treeview_group)
vbox_button.pack_start(button, False, False, 0)
button.show()
button = gtk.Button(stock='gtk-remove')
button.connect("clicked", self.on_remove_group_clicked, treeview_group)
vbox_button.pack_start(button, False, False, 0)
button.show()
self.button_edit = gtk.Button(stock='gtk-edit')
self.button_edit.connect("clicked", self.on_edit_group_clicked, treeview_group)
vbox_button.pack_start(self.button_edit, False, False, 0)
self.button_edit.show()
self.button_edit.set_sensitive(False)
self.button_remove = gtk.Button(stock='gtk-remove')
self.button_remove.connect("clicked", self.on_remove_group_clicked, treeview_group)
vbox_button.pack_start(self.button_remove, False, False, 0)
self.button_remove.show()
self.button_remove.set_sensitive(False)
# User list for the group
user_hbox = gtk.HBox(False, 8)
......@@ -188,6 +189,8 @@ class Group_list:
for agroup in self.group_data:
self.add_group_in_model(self.group_model, agroup)
self.group_user.reload(self.current_group_id)
# Create the model for the group list
def __create_model_group(self):
......@@ -209,8 +212,7 @@ class Group_list:
renderer.connect("edited", self.on_cell_group_edited, model)
renderer.set_data("column", COLUMN_NAME)
column = gtk.TreeViewColumn(_('Group'), renderer,
text=COLUMN_NAME,
editable=COLUMN_GROUP_EDITABLE)
text=COLUMN_NAME)
column.set_sort_column_id(COLUMN_NAME)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_GROUPNAME)
......@@ -221,8 +223,7 @@ class Group_list:
renderer.connect("edited", self.on_cell_group_edited, model)
renderer.set_data("column", COLUMN_DESCRIPTION)
column = gtk.TreeViewColumn(_('Description'), renderer,
text=COLUMN_DESCRIPTION,
editable=COLUMN_GROUP_EDITABLE)
text=COLUMN_DESCRIPTION)
column.set_sort_column_id(COLUMN_DESCRIPTION)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_GROUPDESCRIPTION)
......@@ -235,8 +236,7 @@ class Group_list:
model.set (iter,
COLUMN_GROUPID, agroup[COLUMN_GROUPID],
COLUMN_NAME, agroup[COLUMN_NAME],
COLUMN_DESCRIPTION, agroup[COLUMN_DESCRIPTION],
COLUMN_GROUP_EDITABLE, True
COLUMN_DESCRIPTION, agroup[COLUMN_DESCRIPTION]
)
......@@ -244,9 +244,11 @@ class Group_list:
def on_add_group_clicked(self, button, model):
group_id = constants.get_next_group_id(self.con, self.cur)
new_group = [group_id, "?", "?", 0]
self.add_group_in_model(model, new_group)
group_edit.GroupEdit(self.con, self.cur,
self.current_class_id, self.get_active_text(self.combo_class),
group_id, None, None,
self)
def on_remove_group_clicked(self, button, treeview):
......@@ -258,7 +260,6 @@ class Group_list:
group_id = model.get_value(iter, COLUMN_GROUPID)
model.remove(iter)
# Remove it from the base
print "Deleting group_id=" + str(group_id)
self.cur.execute('delete from groups where group_id=?', (group_id,))
self.con.commit()
......@@ -302,12 +303,14 @@ class Group_list:
if iter:
path = model.get_path(iter)[0]
group_id = model.get_value(iter, COLUMN_GROUPID)
group_name = model.get_value(iter, COLUMN_NAME)
group_id = model.get_value(iter, COLUMN_GROUPID)
group_name = model.get_value(iter, COLUMN_NAME)
group_description = model.get_value(iter, COLUMN_DESCRIPTION)
group_edit.GroupEdit(self.con, self.cur,
self.current_class_id, self.get_active_text(self.combo_class),
group_id, group_name,
self.group_user)
group_description,
self)
else:
# Tell the user to select a group first
......@@ -320,7 +323,6 @@ class Group_list:
def group_changed_cb(self, selection, group_user):
print "group_changed_cb"
model, iter = selection.get_selected()
if iter:
......@@ -329,9 +331,28 @@ class Group_list:
group_user.reload(self.current_group_id)
# Set the default button on if needed
# The wholegroup is not editable
wholegroup_id = constants.get_wholegroup_id(self.con,
self.cur,
self.current_class_id)
if(wholegroup_id == self.current_group_id):
self.button_edit.set_sensitive(False)
self.button_remove.set_sensitive(False)
else:
self.button_edit.set_sensitive(True)
self.button_remove.set_sensitive(True)
def class_changed_cb(self, combobox):
active = combobox.get_active()
if active < 0:
self.button_edit.set_sensitive(False)
self.button_remove.set_sensitive(False)
return
self.current_class_id = self.class_list[active]
self.reload_group()
......@@ -41,8 +41,7 @@ from pysqlite2 import dbapi2 as sqlite
COLUMN_FIRSTNAME,
COLUMN_LASTNAME,
COLUMN_BIRTHDATE,
COLUMN_USER_EDITABLE
) = range(6)
) = range(5)
class Group_user_list:
......@@ -79,6 +78,7 @@ class Group_user_list:
treeview_group.show()
treeview_group.set_rules_hint(True)
treeview_group.set_search_column(COLUMN_FIRSTNAME)
treeview_group.get_selection().set_mode(gtk.SELECTION_NONE)
sw.add(treeview_group)
......@@ -98,19 +98,18 @@ class Group_user_list:
# Retrieve data from the database for the given group_id
def reload(self, group_id):
print "Reloading group_user_list for group_id=" + str(group_id)
self.group_id = group_id
# Remove all entries in the list
self.model.clear()
self.cur.execute('select user_id from list_users_in_groups where group_id=?', (self.group_id,))
self.cur.execute('SELECT user_id FROM list_users_in_groups WHERE group_id=?', (self.group_id,))
list_user_id = self.cur.fetchall()
# Now retrieve users detail
print list_user_id
for user_id in list_user_id:
self.cur.execute('select user_id,login,firstname,lastname,birthdate from users where user_id=?',
self.cur.execute('SELECT user_id,login,firstname,lastname,birthdate ' +
'FROM users WHERE user_id=?',
user_id)
user = self.cur.fetchall()[0]
self.add_user_in_model(self.model, user)
......@@ -125,8 +124,7 @@ class Group_user_list:
COLUMN_LOGIN, user[COLUMN_LOGIN],
COLUMN_FIRSTNAME, user[COLUMN_FIRSTNAME],
COLUMN_LASTNAME, user[COLUMN_LASTNAME],
COLUMN_BIRTHDATE, user[COLUMN_BIRTHDATE],
COLUMN_USER_EDITABLE, True
COLUMN_BIRTHDATE, user[COLUMN_BIRTHDATE]
)
......@@ -137,8 +135,7 @@ class Group_user_list:
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_BOOLEAN)
gobject.TYPE_STRING)
return model
......@@ -153,8 +150,7 @@ class Group_user_list:
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_LOGIN)
column = gtk.TreeViewColumn(_('Login'), renderer,
text=COLUMN_LOGIN,
editable=COLUMN_USER_EDITABLE)
text=COLUMN_LOGIN)
column.set_sort_column_id(COLUMN_LOGIN)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_LOGIN)
......@@ -164,8 +160,7 @@ class Group_user_list:
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_FIRSTNAME)
column = gtk.TreeViewColumn(_('First Name'), renderer,
text=COLUMN_FIRSTNAME,
editable=COLUMN_USER_EDITABLE)
text=COLUMN_FIRSTNAME)
column.set_sort_column_id(COLUMN_FIRSTNAME)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_FIRSTNAME)
......@@ -175,8 +170,7 @@ class Group_user_list:
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_LASTNAME)
column = gtk.TreeViewColumn(_('Last Name'), renderer,
text=COLUMN_LASTNAME,
editable=COLUMN_USER_EDITABLE)
text=COLUMN_LASTNAME)
column.set_sort_column_id(COLUMN_LASTNAME)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_LASTNAME)
......@@ -186,8 +180,7 @@ class Group_user_list:
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_BIRTHDATE)
column = gtk.TreeViewColumn(_('Birth Date'), renderer,
text=COLUMN_BIRTHDATE,
editable=COLUMN_USER_EDITABLE)
text=COLUMN_BIRTHDATE)
column.set_sort_column_id(COLUMN_BIRTHDATE)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_BIRTHDATE)
......
......@@ -38,7 +38,7 @@ class Groups(module.Module):
def __init__(self, canvas):
print("Gcompris_administration __init__ groups panel.")
module.Module.__init__(self, canvas, "groups", _("Groups list"))
module.Module.__init__(self, canvas, "groups", _("Groups"))
# Return the position it must have in the administration menu
# The smaller number is the highest.
......@@ -64,7 +64,7 @@ class Groups(module.Module):
# Call our parent start
module.Module.start(self)
frame = gtk.Frame(_("Group"))
frame = gtk.Frame(_("Groups"))
frame.show()
self.rootitem.add(
......
......@@ -38,7 +38,7 @@ class Profiles(module.Module):
def __init__(self, canvas):
print("Gcompris_administration __init__ profiles panel.")