Commit ed1052e7 authored by Bruno Coudoin's avatar Bruno Coudoin
Browse files

First implementation of the profile module in the editor

	The edition of the profile's group is not yet coded.
parent 1edcdd0f
2005-07-20 Bruno coudoin <bruno.coudoin@free.fr>
First implementation of the profile module in the editor
The edition of the profile's group is not yet coded.
* src/boards/python/admin/Makefile.am:
* src/boards/python/admin/constants.py:
* src/boards/python/admin/group_edit.py:
* src/boards/python/admin/group_list.py:
* src/boards/python/admin/module_profiles.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_list.py:
* src/gcompris/gcompris_db.c:
2005-07-20 Yves Combe <yves@ycombe.net>
Put set_board_conf directly in gcompris module.
......
......@@ -16,6 +16,8 @@ dist_python_DATA= \
class_list.py \
class_edit.py \
board_list.py \
constants.py
constants.py \
profile_edit.py \
profile_group_list.py \
profile_list.py
......@@ -30,3 +30,6 @@ COLUMN_WIDTH_TEACHER = 300
COLUMN_WIDTH_GROUPNAME = 100
COLUMN_WIDTH_GROUPDESCRIPTION = 300
COLUMN_WIDTH_PROFILENAME = 100
COLUMN_WIDTH_PROFILEDESCRIPTION = 300
......@@ -47,7 +47,6 @@ class GroupEdit(gtk.Window):
# Create the toplevel window
gtk.Window.__init__(self)
print constants.COLUMN_WIDTH_LOGIN
self.cur = db_cursor
self.con = db_connect
......
......@@ -222,7 +222,7 @@ class Group_list:
renderer = gtk.CellRendererText()
renderer.connect("edited", self.on_cell_group_edited, model)
renderer.set_data("column", COLUMN_NAME)
column = gtk.TreeViewColumn(_('Name'), renderer,
column = gtk.TreeViewColumn(_('Group'), renderer,
text=COLUMN_NAME,
editable=COLUMN_GROUP_EDITABLE)
column.set_sort_column_id(COLUMN_NAME)
......
......@@ -27,6 +27,10 @@ import gtk.gdk
from gettext import gettext as _
import module
import profile_list
# Database
from pysqlite2 import dbapi2 as sqlite
class Profiles(module.Module):
"""Administrating GCompris Profiles"""
......@@ -44,6 +48,10 @@ class Profiles(module.Module):
def start(self, area):
print "starting profiles panel"
# Connect to our database
self.con = sqlite.connect(gcompris.get_database())
self.cur = self.con.cursor()
# Create our rootitem. We put each canvas item in it so at the end we
# only have to kill it. The canvas deletes all the items it contains automaticaly.
......@@ -55,14 +63,19 @@ class Profiles(module.Module):
module.Module.start(self)
item = self.rootitem.add (
gnome.canvas.CanvasText,
text=_("Profile"),
font=gcompris.skin.get_font("gcompris/content"),
x = area[0] + (area[2]-area[0])/2,
y = area[1] + 50,
fill_color="black"
)
hgap = 20
vgap = 15
# Define the area percent for each list
group_percent = 1.0
origin_y = area[1]+vgap
group_height = (area[3]-area[1])*group_percent - vgap
list_area = ( area[0], origin_y, area[2], group_height)
profile_list.Profile_list(self.rootitem,
self.con, self.cur,
list_area, hgap, vgap)
def stop(self):
print "stopping profiles panel"
......@@ -71,3 +84,6 @@ class Profiles(module.Module):
# Remove the root item removes all the others inside it
self.rootitem.destroy()
# Close the database
self.cur.close()
self.con.close()
# gcompris - profile_edit.py
#
# Copyright (C) 2005 Bruno Coudoin and Yves Combe
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import gtk
import gobject
from gettext import gettext as _
import profile_group_list
import constants
# Database
from pysqlite2 import dbapi2 as sqlite
# Group Management
(
COLUMN_GROUPID,
COLUMN_NAME,
COLUMN_DESCRIPTION,
COLUMN_GROUP_EDITABLE
) = range(4)
class ProfileEdit(gtk.Window):
def __init__(self, db_connect, db_cursor,
profile_id, profile_name,
profile_group):
# Create the toplevel window
gtk.Window.__init__(self)
self.cur = db_cursor
self.con = db_connect
self.profile_id = profile_id
# A pointer to the profile_group_list class
# Will be called to refresh the list when edit is done
self.profile_group = profile_group
self.set_title(_("Group Edition"))
self.set_border_width(8)
self.set_default_size(320, 350)
frame = gtk.Frame(_("Editing profile: ") + profile_name)
self.add(frame)
vbox = gtk.VBox(False, 8)
vbox.set_border_width(8)
frame.add(vbox)
# Top message gives instructions
label = gtk.Label(_('Assign all the groups bellonging to this profile'))
vbox.pack_start(label, False, False, 0)
vbox.pack_start(gtk.HSeparator(), False, False, 0)
# Lower area
hbox = gtk.HBox(False, 8)
vbox.pack_start(hbox, True, True, 0)
# Left list
# ---------
# Create the table
sw = gtk.ScrolledWindow()
sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
# create tree model
self.model_left = self.__create_model(False, profile_id)
# create tree view
treeview = gtk.TreeView(self.model_left)
treeview.set_rules_hint(True)
treeview.set_search_column(COLUMN_NAME)
treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
sw.add(treeview)
# add columns to the tree view
self.__add_columns(treeview)
hbox.pack_start(sw, True, True, 0)
# Middle Button
# -------------
vbox2 = gtk.VBox(False, 8)
vbox2.set_border_width(8)
hbox.pack_start(vbox2, True, True, 0)
button = gtk.Button(stock='gtk-add')
button.connect("clicked", self.add_user, treeview)
vbox2.pack_start(button, False, False, 0)
button.show()
button_delete = gtk.Button(stock='gtk-delete')
vbox2.pack_start(button_delete, False, False, 0)
button_delete.show()
# Right List
# ----------
# Create the table
sw2 = gtk.ScrolledWindow()
sw2.set_shadow_type(gtk.SHADOW_ETCHED_IN)
sw2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
# create tree model
self.model_right = self.__create_model(True, profile_id)
# create tree view
treeview2 = gtk.TreeView(self.model_right)
treeview2.set_rules_hint(True)
treeview2.set_search_column(COLUMN_NAME)
treeview2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
sw2.add(treeview2)
# add columns to the tree view
self.__add_columns(treeview2)
hbox.pack_start(sw2, True, True, 0)
# Confirmation Buttons
# --------------------
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)
button = gtk.Button(stock='gtk-help')
bbox.add(button)
button = gtk.Button(stock='gtk-close')
bbox.add(button)
button.connect("clicked", self.close)
vbox.pack_start(bbox, False, False, 0)
# Missing callbacks
button_delete.connect("clicked", self.remove_user, treeview2)
# Ready GO
self.show_all()
# -------------------
# User Management
# -------------------
# Add user in the model
def add_user_in_model(self, model, user):
iter = model.append()
model.set (iter,
COLUMN_USERID, user[COLUMN_USERID],
COLUMN_FIRSTNAME, user[COLUMN_FIRSTNAME],
COLUMN_LASTNAME, user[COLUMN_LASTNAME],
COLUMN_USER_EDITABLE, False
)
# class_id: only users in this class are inserted
# group_id: only users in this group are inserted
# If with = True, create a list only with user in the given class_id and group_id.
# False, create a list only with user in the given class_id but NOT this group_id
def __create_model(self, with, profile_id):
model = gtk.ListStore(
gobject.TYPE_INT,
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_BOOLEAN)
# Grab the all the groups from this profile
self.cur.execute('select group_id,firstname,lastname from users where class_id=?', (class_id,))
user_data = self.cur.fetchall()
for user in user_data:
# Check our user is already in the group
self.cur.execute('select * from list_users_in_groups where group_id=? and user_id=?',
(group_id, user[0]))
user_is_already = self.cur.fetchall()
if(with and user_is_already):
print "with and user_is_already"
print user_is_already
self.add_user_in_model(model, user)
elif(not with and not user_is_already):
print "not with and not user_is_already"
print user_is_already
self.add_user_in_model(model, user)
return model
def __add_columns(self, treeview):
model = treeview.get_model()
# columns for first name
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_FIRSTNAME)
column = gtk.TreeViewColumn(_('First Name'), renderer,
text=COLUMN_FIRSTNAME,
editable=COLUMN_USER_EDITABLE)
column.set_sort_column_id(COLUMN_FIRSTNAME)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_FIRSTNAME)
treeview.append_column(column)
# column for last name
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_LASTNAME)
column = gtk.TreeViewColumn(_('Last Name'), renderer,
text=COLUMN_LASTNAME,
editable=COLUMN_USER_EDITABLE)
column.set_sort_column_id(COLUMN_LASTNAME)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_LASTNAME)
treeview.append_column(column)
# Add a user from the left list to the right list
#
def add_user(self, button, treeview):
model = treeview.get_model()
treestore, paths = treeview.get_selection().get_selected_rows()
paths.reverse()
for path in paths:
iter = treestore.get_iter(path)
path = model.get_path(iter)[0]
user_id = model.get_value(iter, COLUMN_USERID)
user_firstname = model.get_value(iter, COLUMN_FIRSTNAME)
user_lastname = model.get_value(iter, COLUMN_LASTNAME)
model.remove(iter)
# Add in the the right view
self.add_user_in_model(self.model_right, (user_id, user_firstname, user_lastname))
# Save the change in the base
self.cur.execute('insert or replace into list_users_in_groups (group_id, user_id) values (?, ?)',
(self.group_id, user_id))
self.con.commit()
# Add a user from the left list to the right list
#
def remove_user(self, button, treeview):
model = treeview.get_model()
treestore, paths = treeview.get_selection().get_selected_rows()
paths.reverse()
for path in paths:
iter = treestore.get_iter(path)
path = model.get_path(iter)[0]
user_id = model.get_value(iter, COLUMN_USERID)
user_firstname = model.get_value(iter, COLUMN_FIRSTNAME)
user_lastname = model.get_value(iter, COLUMN_LASTNAME)
model.remove(iter)
# Add in the the left view
self.add_user_in_model(self.model_left, (user_id, user_firstname, user_lastname))
# Save the change in the base
self.cur.execute('delete from list_users_in_groups where group_id=? and user_id=?',
(self.group_id, user_id))
self.con.commit()
# Done, can quit this dialog
#
def close(self, button):
self.group_user.reload(self.group_id)
self.destroy()
# gcompris - profile_group_list.py
#
# Copyright (C) 2005 Bruno Coudoin and Yves Combe
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import gnome
import gnome.canvas
import gcompris
import gcompris.utils
import gcompris.skin
import gtk
import gtk.gdk
import gobject
from gettext import gettext as _
import constants
# Database
from pysqlite2 import dbapi2 as sqlite
#import group_edit
# Group Management
(
COLUMN_GROUPID,
COLUMN_NAME,
COLUMN_DESCRIPTION,
COLUMN_GROUP_EDITABLE
) = range(4)
class Profile_group_list:
"""GCompris Profile Group List Table"""
# The created list will be packed in the given container
#
def __init__(self, container, db_connect, db_cursor, profile_id):
self.cur = db_cursor
self.con = db_connect
# The profile_id to work on
self.profile_id = profile_id
# ---------------
# User Group Management
# ---------------
# create tree model
self.model = self.__create_model()
self.reload(self.profile_id)
# Create the table
sw = gtk.ScrolledWindow()
sw.show()
sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
# create tree view
treeview_group = gtk.TreeView(self.model)
treeview_group.show()
treeview_group.set_rules_hint(True)
treeview_group.set_search_column(COLUMN_NAME)
sw.add(treeview_group)
# add columns to the tree view
self.__add_columns(treeview_group)
container.pack_start(sw)
# -------------------
# Group Management
# -------------------
# clear all data in the list
def clear(self):
self.model.clear()
# Retrieve data from the database for the given group_id
def reload(self, profile_id):
print "Reloading profile_group_list for profile_id=" + str(profile_id)
self.profile_id = profile_id
# Remove all entries in the list
self.model.clear()
self.cur.execute('select group_id from list_groups_in_profiles where profile_id=?', (self.profile_id,))
list_group_id = self.cur.fetchall()
# Now retrieve group detail
print list_group_id
for group_id in list_group_id:
self.cur.execute('select group_id,name,description from groups where group_id=?',
group_id)
user = self.cur.fetchall()[0]
self.add_group_in_model(self.model, group)
# Add group in the model
def add_group_in_model(self, model, group):
iter = model.append()
model.set (iter,
COLUMN_GROUPID, group[COLUMN_GROUPID],
COLUMN_NAME, group[COLUMN_NAME],
COLUMN_DESCRIPTION, group[COLUMN_DESCRIPTION],
COLUMN_USER_EDITABLE, True
)
def __create_model(self):
model = gtk.ListStore(
gobject.TYPE_INT,
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_BOOLEAN)
return model
def __add_columns(self, treeview):
model = treeview.get_model()
# Total column lengh must be 400
# columns for name
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_NAME)
column = gtk.TreeViewColumn(_('Group'), renderer,
text=COLUMN_NAME,
editable=COLUMN_GROUP_EDITABLE)
column.set_sort_column_id(COLUMN_NAME)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_GROUPNAME)
treeview.append_column(column)
# columns for description
renderer = gtk.CellRendererText()
renderer.set_data("column", COLUMN_DESCRIPTION)
column = gtk.TreeViewColumn(_('Description'), renderer,
text=COLUMN_DESCRIPTION,
editable=COLUMN_GROUP_EDITABLE)
column.set_sort_column_id(COLUMN_DESCRIPTION)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(constants.COLUMN_WIDTH_GROUPDESCRIPTION)
treeview.append_column(column)
# gcompris - profile_list.py
#
# Copyright (C) 2005 Bruno Coudoin and Yves Combe
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License