[gcompris: 4/9] Sugar sharing and additional Journal integration (administration-activity)



commit 9a3104e80de7912f79f03d1e95ea213dd32c4f9a
Author: Aleksey Lim <alsroot sugarlabs org>
Date:   Sun Mar 11 11:28:02 2012 +0000

    Sugar sharing and additional Journal integration (administration-activity)
    
    Tune Administration activity to support running in Sugar mode when
    all network interactions will happen in Sugar way.

 po/POTFILES.in                                     |    5 +
 src/administration-activity/admin/Makefile.am      |    5 +-
 src/administration-activity/admin/board_list.py    |   28 +-
 src/administration-activity/admin/log_list.py      |    5 +-
 .../admin/module_activities.py                     |  103 +++++++
 src/administration-activity/admin/module_boards.py |    7 +-
 src/administration-activity/admin/module_logins.py |   94 ++++++
 src/administration-activity/admin/profile_edit.py  |  291 +------------------
 .../admin/profile_widget.py                        |  308 ++++++++++++++++++++
 src/administration-activity/administration.py      |    8 +-
 .../resources/administration/Makefile.am           |    4 +-
 .../administration/config_activities.svgz          |  Bin 0 -> 19831 bytes
 .../resources/administration/config_logins.svgz    |  Bin 0 -> 7255 bytes
 13 files changed, 558 insertions(+), 300 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1c7baba..d7af270 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -55,6 +55,11 @@ src/administration-activity/admin/profile_list.py
 src/administration-activity/admin/user_edit.py
 src/administration-activity/admin/user_list.py
 src/administration-activity/admin/wordlist.py
+src/administration-activity/administration.py
+src/administration-activity/admin/module_activities.py
+src/administration-activity/admin/module_logins.py
+src/administration-activity/admin/profile_widget.py
+src/administration-activity/administration.xml.in
 src/advanced_colors-activity/advanced_colors.xml.in
 src/advanced_colors-activity/resources/advanced_colors/activity.desktop.in
 src/algebra_by-activity/algebra_by.xml.in
diff --git a/src/administration-activity/admin/Makefile.am b/src/administration-activity/admin/Makefile.am
index d5d6776..6b1c710 100644
--- a/src/administration-activity/admin/Makefile.am
+++ b/src/administration-activity/admin/Makefile.am
@@ -23,5 +23,8 @@ dist_python_DATA= \
 	user_edit.py \
 	user_list.py \
         group_list.py \
-	wordlist.py
+	wordlist.py \
+	module_logins.py \
+	module_activities.py \
+	profile_widget.py
 
diff --git a/src/administration-activity/admin/board_list.py b/src/administration-activity/admin/board_list.py
index f550346..02361ef 100644
--- a/src/administration-activity/admin/board_list.py
+++ b/src/administration-activity/admin/board_list.py
@@ -37,11 +37,14 @@ class Board_list:
 
 
   # area is the drawing area for the list
-  def __init__(self, db_connect, db_cursor, frame):
+  def __init__(self, db_connect, db_cursor, frame, default_profile_id,
+          hide_profiles=False):
 
       self.frame = frame
       self.cur = db_cursor
       self.con = db_connect
+      self.default_profile_id = default_profile_id
+      self.hide_profiles = hide_profiles
 
   def init(self):
 
@@ -56,12 +59,6 @@ class Board_list:
       if not self.profiles_list:
         return
 
-      # Get default pofile id.
-      self.cur.execute('SELECT profile_id FROM informations;')
-      self.con.commit()
-
-      self.default_profile_id = self.cur.fetchall()[0][0]
-
       self.out_dict = self.get_boards_out_by_profile()
 
       self.difficulty = [1, 6]
@@ -80,8 +77,9 @@ class Board_list:
       box3 = gtk.VBox(False, 8)
       box3.show()
 
-      top_box.pack_start(box1, False, False, 0)
-      top_box.pack_start(box2, True, True, 0)
+      if not self.hide_profiles:
+        top_box.pack_start(box1, False, False, 0)
+      top_box.pack_end(box2, True, True, 0)
 
       box2.pack_end(box3, False, False, 0)
 
@@ -98,10 +96,14 @@ class Board_list:
         if profile.profile_id == self.default_profile_id:
           combobox.set_active(self.profiles_list.index(profile))
 
-      self.active_profile = self.profiles_list[combobox.get_active()]
+      self.active_profile = filter(lambda x:
+              x.profile_id == self.default_profile_id, self.profiles_list)[0]
 
+      self.progressbar_box = gtk.Alignment(0.5, 0.5, 0.5, 0)
       self.progressbar = gtk.ProgressBar(adjustment=None)
-      box1.pack_start(self.progressbar, False, False, 0)
+      self.progressbar.show();
+      self.progressbar_box.add(self.progressbar)
+      box2.pack_start(self.progressbar_box)
 
       # Create the table
       sw = gtk.ScrolledWindow()
@@ -225,7 +227,7 @@ class Board_list:
     self.board_dict = {}
     height = 24
 
-    self.progressbar.show()
+    self.progressbar_box.show()
     index = 0.0
     for board_cell in menu_list:
       self.board_dict['%s/%s' % (board_cell[1].section,board_cell[1].name)] = board_cell[1]
@@ -250,7 +252,7 @@ class Board_list:
                                        _(board_cell[1].title) + '\n' + '%s/%s' % (board_cell[1].section,board_cell[1].name),
                                        not board_cell[1].board_id in self.out_dict[self.active_profile.profile_id],
                                        '%s/%s' % (board_cell[1].section,board_cell[1].name), self.pixbuf_configurable(board_cell[1])])
-    self.progressbar.hide()
+    self.progressbar_box.hide()
 
   def pixbuf_admin_at_height(self, file, height):
     pixbuf = gcompris.utils.load_pixmap(file)
diff --git a/src/administration-activity/admin/log_list.py b/src/administration-activity/admin/log_list.py
index ab2ae7c..bb56160 100644
--- a/src/administration-activity/admin/log_list.py
+++ b/src/administration-activity/admin/log_list.py
@@ -104,7 +104,7 @@ class Log_list:
 
       for auser in user_list:
 
-        if(auser[0] == -1):
+        if(auser[0] == -1 or not auser[0]):
           self.combo_user.append_text(_("Default"))
           self.user_list.append(-1)
           continue
@@ -197,6 +197,9 @@ class Log_list:
     # Grab the log data
     if self.current_user_id == -2:
       self.cur.execute('SELECT date, user_id, board_id, level, sublevel, duration, status FROM logs ORDER BY date')
+    elif self.current_user_id == -1:
+      self.cur.execute('SELECT date, user_id, board_id, level, sublevel, duration, status FROM logs ' +
+                       'WHERE user_id=-1 OR user_id is NULL ORDER BY date')
     else:
       self.cur.execute('SELECT date, user_id, board_id, level, sublevel, duration, status FROM logs ' +
                        'WHERE user_id=? ORDER BY date', (self.current_user_id, ) )
diff --git a/src/administration-activity/admin/module_activities.py b/src/administration-activity/admin/module_activities.py
new file mode 100644
index 0000000..c47b75b
--- /dev/null
+++ b/src/administration-activity/admin/module_activities.py
@@ -0,0 +1,103 @@
+#  gcompris - module_activities.py
+#
+# Copyright (C) 2005, 2008 Yves Combe
+# Copyright (C) 2012, Aleksey Lim
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+#
+
+import goocanvas
+import gcompris
+import gcompris.utils
+import gcompris.skin
+import gcompris.admin
+import gtk
+import gtk.gdk
+from gcompris import gcompris_gettext as _
+import sys;
+
+# Database
+try:
+  from sqlite3 import dbapi2 as sqlite # python 2.5
+except:
+  try:
+    from pysqlite2 import dbapi2 as sqlite
+  except:
+    print 'This program requires pysqlite2\n',\
+        'http://initd.org/tracker/pysqlite/'
+    sys.exit(1)
+
+import module
+import board_list
+
+class Activities(module.Module):
+  """Administrating GCompris Boards"""
+
+  already_loaded = False
+
+  def __init__(self, canvas):
+    module.Module.__init__(self, canvas, "activities", _("Activities"))
+
+  # Return the position it must have in the administration menu
+  # The smaller number is the highest.
+  def position(self):
+    return 3
+
+  def start(self, area):
+    # Connect to our database
+    self.con = sqlite.connect(gcompris.get_database())
+    self.cur = self.con.cursor()
+
+    if Activities.already_loaded:
+      self.rootitem.props.visibility = goocanvas.ITEM_VISIBLE
+      self.boardList.show(self.con, self.cur)
+      return
+
+    Activities.already_loaded = True
+
+    # 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.
+
+    self.rootitem = goocanvas.Group(
+      parent = self.canvas,
+      )
+
+    module.Module.start(self)
+
+    self.frame = gtk.Frame(_("Activities"))
+    self.frame.show()
+
+    goocanvas.Widget(
+      parent = self.rootitem,
+      widget=self.frame,
+      x=area[0]+self.module_panel_ofset,
+      y=area[1]+self.module_panel_ofset,
+      width=area[2]-area[0]-2*self.module_panel_ofset,
+      height=area[3]-area[1]-2*self.module_panel_ofset,
+      anchor=gtk.ANCHOR_NW)
+
+    self.boardList = board_list.Board_list(self.con, self.cur, self.frame,
+            gcompris.sugar_get_profile_id(), hide_profiles=True)
+    self.boardList.init()
+
+  def stop(self):
+    module.Module.stop(self)
+
+    # This module is slow to start, we just hide it
+    self.rootitem.props.visibility = goocanvas.ITEM_INVISIBLE
+    self.boardList.hide()
+
+    # Close the database
+    self.cur.close()
+    self.con.close()
diff --git a/src/administration-activity/admin/module_boards.py b/src/administration-activity/admin/module_boards.py
index 330aca9..4941d9c 100644
--- a/src/administration-activity/admin/module_boards.py
+++ b/src/administration-activity/admin/module_boards.py
@@ -86,8 +86,13 @@ class Boards(module.Module):
       height=area[3]-area[1]-2*self.module_panel_ofset,
       anchor=gtk.ANCHOR_NW)
 
+    # Get default pofile id.
+    self.cur.execute('SELECT profile_id FROM informations;')
+    self.con.commit()
+    default_profile_id = self.cur.fetchall()[0][0]
+
     self.boardList = board_list.Board_list(self.con, self.cur,
-                                           self.frame)
+                                           self.frame, default_profile_id)
     self.boardList.init()
 
   def stop(self):
diff --git a/src/administration-activity/admin/module_logins.py b/src/administration-activity/admin/module_logins.py
new file mode 100644
index 0000000..8a7ee36
--- /dev/null
+++ b/src/administration-activity/admin/module_logins.py
@@ -0,0 +1,94 @@
+#  gcompris - module_logins.py
+#
+# Copyright (C) 2005, 2008 Bruno Coudoin and Yves Combe
+# Copyright (C) 2012, Aleksey Lim
+#
+#   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 3 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, see <http://www.gnu.org/licenses/>.
+
+import goocanvas
+import gcompris
+import gcompris.utils
+import gcompris.skin
+import gtk
+import gtk.gdk
+from gcompris import gcompris_gettext as _
+
+import module
+import profile_list
+import profile_edit
+import profile_widget
+
+# Database
+try:
+  from sqlite3 import dbapi2 as sqlite # python 2.5
+except:
+  try:
+    from pysqlite2 import dbapi2 as sqlite
+  except:
+    print 'This program requires pysqlite2\n',\
+        'http://initd.org/tracker/pysqlite/'
+    sys.exit(1)
+
+class Logins(module.Module):
+  """Administrating GCompris Profiles"""
+
+
+  def __init__(self, canvas):
+    module.Module.__init__(self, canvas, "logins", _("Logins"))
+
+  # Return the position it must have in the administration menu
+  # The smaller number is the highest.
+  def position(self):
+    return 2
+
+  def start(self, area):
+    # 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.
+
+    self.rootitem = goocanvas.Group(
+      parent = self.canvas,
+      )
+
+    module.Module.start(self)
+
+    frame = gtk.Frame(_("Logins"))
+
+    goocanvas.Widget(
+      parent = self.rootitem,
+      widget=frame,
+      x=area[0]+self.module_panel_ofset,
+      y=area[1]+self.module_panel_ofset,
+      width=area[2]-area[0]-2*self.module_panel_ofset,
+      height=area[3]-area[1]-2*self.module_panel_ofset,
+      anchor=gtk.ANCHOR_NW)
+
+    self.profile_widget = profile_widget.ProfileWidget(self.con, self.cur,
+            gcompris.sugar_get_profile_id(), False)
+    frame.add(self.profile_widget)
+
+    frame.show_all()
+
+  def stop(self):
+    module.Module.stop(self)
+
+    # Remove the root item removes all the others inside it
+    self.rootitem.remove()
+
+    # Close the database
+    self.cur.close()
+    self.con.close()
diff --git a/src/administration-activity/admin/profile_edit.py b/src/administration-activity/admin/profile_edit.py
index 2b06e8d..421126f 100644
--- a/src/administration-activity/admin/profile_edit.py
+++ b/src/administration-activity/admin/profile_edit.py
@@ -18,21 +18,9 @@
 
 
 import gtk
-import gobject
-import gcompris
 from gcompris import gcompris_gettext as _
 
-import profile_group_list
-
-import constants
-
-# Group Management
-(
-  COLUMN_GROUPID,
-  COLUMN_CLASSNAME,
-  COLUMN_GROUPNAME,
-  COLUMN_DESCRIPTION,
-) = range(4)
+import profile_widget
 
 
 class ProfileEdit(gtk.Window):
@@ -44,14 +32,7 @@ class ProfileEdit(gtk.Window):
         # 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_list_list class
-        # Will be called to refresh the list when edit is done
-        self.profile_list = profile_list
+        self.profile_list = profile_list;
 
         self.set_title(_("Editing a Profile"))
         self.set_border_width(8)
@@ -59,10 +40,10 @@ class ProfileEdit(gtk.Window):
 
         if(profile_name):
             frame = gtk.Frame(_("Editing profile: ") + profile_name)
-            self.new_profile = False
+            new_profile = False
         else:
             frame = gtk.Frame(_("Editing a new profile"))
-            self.new_profile = True
+            new_profile = True
             profile_name =""
             profile_description = ""
 
@@ -108,73 +89,9 @@ class ProfileEdit(gtk.Window):
         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_GROUPNAME)
-        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_group, treeview)
-        vbox2.pack_start(button, False, False, 0)
-        button.show()
-
-        button_delete = gtk.Button(stock='gtk-remove')
-        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_GROUPNAME)
-        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)
+        self.profile_widget = profile_widget.ProfileWidget(db_connect,
+                db_cursor, profile_id, new_profile)
+        vbox.pack_start(self.profile_widget, True, True, 0)
 
         # Confirmation Buttons
         # --------------------
@@ -192,167 +109,9 @@ class ProfileEdit(gtk.Window):
 
         vbox.pack_start(bbox, False, False, 0)
 
-
-        # Missing callbacks
-        button_delete.connect("clicked", self.remove_group, treeview2)
-
         # Ready GO
         self.show_all()
 
-
-    # -------------------
-    # User Management
-    # -------------------
-
-    # Add user in the model
-    def add_group_in_model(self, model, group):
-        iter = model.append()
-        model.set (iter,
-                   COLUMN_GROUPID,      group[COLUMN_GROUPID],
-                   COLUMN_CLASSNAME,    group[COLUMN_CLASSNAME],
-                   COLUMN_GROUPNAME,    group[COLUMN_GROUPNAME],
-                   COLUMN_DESCRIPTION,  group[COLUMN_DESCRIPTION]
-                   )
-
-    # profile_id: only groups in this profile are inserted
-    # If gwith = True,  create a list only with groups in the given profile_id
-    #           False, create a list only with groups NOT this profile_id
-    def __create_model(self, gwith, profile_id):
-
-        model = gtk.ListStore(
-            gobject.TYPE_INT,
-            gobject.TYPE_STRING,
-            gobject.TYPE_STRING,
-            gobject.TYPE_STRING)
-
-        # Grab the all the groups
-        self.cur.execute('SELECT group_id,name,description FROM groups ORDER BY name')
-        group_data = self.cur.fetchall()
-
-        for group in group_data:
-
-            group_id = group[0]
-            # Check our group is already in the profile
-            self.cur.execute('SELECT * FROM list_groups_in_profiles ' +
-                             'WHERE profile_id=? AND group_id=?',
-                             (profile_id, group_id))
-            group_is_already = self.cur.fetchall()
-
-            # Extract the class name of this group
-            class_name = constants.get_class_name_for_group_id(self.con,
-                                                               self.cur,
-                                                               group_id)
-
-            # Insert the class name in the group
-            group = (group[0], class_name, group[1], group[2])
-
-            if(gwith and group_is_already):
-                self.add_group_in_model(model, group)
-            elif(not gwith and not group_is_already):
-                self.add_group_in_model(model, group)
-
-        return model
-
-    def __add_columns(self, treeview):
-
-        model = treeview.get_model()
-
-        # columns for class name
-        renderer = gtk.CellRendererText()
-        renderer.set_data("column", COLUMN_CLASSNAME)
-        column = gtk.TreeViewColumn(_('Class'), renderer,
-                                    text=COLUMN_CLASSNAME)
-        column.set_sort_column_id(COLUMN_CLASSNAME)
-        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-        column.set_fixed_width(constants.COLUMN_WIDTH_CLASSNAME)
-        treeview.append_column(column)
-
-        # columns for group name
-        renderer = gtk.CellRendererText()
-        renderer.set_data("column", COLUMN_GROUPNAME)
-        column = gtk.TreeViewColumn(_('Group'), renderer,
-                                    text=COLUMN_GROUPNAME)
-        column.set_sort_column_id(COLUMN_GROUPNAME)
-        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-        column.set_fixed_width(constants.COLUMN_WIDTH_GROUPNAME)
-        treeview.append_column(column)
-
-        # column for description
-        renderer = gtk.CellRendererText()
-        renderer.set_data("column", COLUMN_DESCRIPTION)
-        column = gtk.TreeViewColumn(_('Description'), renderer,
-                                    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_EDIT)
-        treeview.append_column(column)
-
-
-    # Add a group from the left list to the right list
-    #
-    def add_group(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]
-            group_id           = model.get_value(iter, COLUMN_GROUPID)
-            class_name         = model.get_value(iter, COLUMN_CLASSNAME)
-            group_name         = model.get_value(iter, COLUMN_GROUPNAME)
-            group_description  = model.get_value(iter, COLUMN_DESCRIPTION)
-            model.remove(iter)
-
-            # Add in the the right view
-            self.add_group_in_model(self.model_right,
-                                    (group_id, class_name, group_name, group_description))
-
-            # Save the change in the base
-            self.cur.execute('INSERT OR REPLACE INTO list_groups_in_profiles ' +
-                             '(profile_id, group_id) VALUES (?, ?)',
-                             (self.profile_id, group_id))
-            self.con.commit()
-
-
-    # Add a group from the left list to the right list
-    #
-    def remove_group(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]
-            group_id           = model.get_value(iter, COLUMN_GROUPID)
-            class_name         = model.get_value(iter, COLUMN_CLASSNAME)
-            group_name         = model.get_value(iter, COLUMN_GROUPNAME)
-            group_description  = model.get_value(iter, COLUMN_DESCRIPTION)
-            model.remove(iter)
-
-            # Add in the the left view
-            self.add_group_in_model(self.model_left,
-                                    (group_id, class_name, group_name, group_description))
-
-            # Save the change in the base
-            self.cur.execute('DELETE FROM list_groups_in_profiles ' +
-                             'WHERE profile_id=? AND group_id=?',
-                             (self.profile_id, group_id))
-            self.con.commit()
-
-
-
     # Done, can quit this dialog
     #
     def close(self, button):
@@ -373,40 +132,8 @@ class ProfileEdit(gtk.Window):
             dialog.destroy()
             return
 
-        #
-        # Now everything is correct, create the profile
-        #
-
-        profile_data = (self.profile_id,
-                        self.entry_profile.get_text().strip(),
-                        self.entry_description.get_text()
-                      )
-
-        if(self.new_profile):
-            # Check the login do not exist already
-            self.cur.execute('SELECT name FROM profiles WHERE name=?',
-                             (self.entry_profile.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 profile with this name"))
-                dialog.run()
-                dialog.destroy()
-                return
-
-            # Create the new profile
-            profile_id = constants.get_next_profile_id(self.con, self.cur)
-            self.cur.execute('INSERT INTO profiles (profile_id, name, description) ' +
-                             'VALUES ( ?, ?, ?)',
-                             (profile_data));
-        else:
-            # Save the profile changes
-            self.cur.execute('UPDATE profiles SET name=?, description=? where profile_id=?',
-                             (self.entry_profile.get_text(),
-                              self.entry_description.get_text(),
-                              self.profile_id));
-        self.con.commit()
+        self.profile_widget.ok(self.entry_profile.get_text().strip(),
+                self.entry_description.get_text())
 
         # Close the dialog window now
         self.profile_list.reload_profile()
diff --git a/src/administration-activity/admin/profile_widget.py b/src/administration-activity/admin/profile_widget.py
new file mode 100644
index 0000000..19e09bc
--- /dev/null
+++ b/src/administration-activity/admin/profile_widget.py
@@ -0,0 +1,308 @@
+#  gcompris - profile_edit.py
+#
+# Copyright (C) 2005, 2008 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+
+
+import gtk
+import gobject
+import gcompris
+from gcompris import gcompris_gettext as _
+
+import profile_group_list
+
+import constants
+
+# Group Management
+(
+  COLUMN_GROUPID,
+  COLUMN_CLASSNAME,
+  COLUMN_GROUPNAME,
+  COLUMN_DESCRIPTION,
+) = range(4)
+
+
+class ProfileWidget(gtk.HBox):
+
+    def __init__(self, db_connect, db_cursor, profile_id, new_profile):
+
+        # Create the toplevel window
+        gtk.HBox.__init__(self)
+
+        self.cur = db_cursor
+        self.con = db_connect
+        self.profile_id = profile_id
+        self.new_profile = new_profile
+
+
+        # 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_GROUPNAME)
+        treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+
+        sw.add(treeview)
+
+        # add columns to the tree view
+        self.__add_columns(treeview)
+
+        self.pack_start(sw, True, True, 0)
+
+
+        # Middle Button
+        # -------------
+        vbox2 = gtk.VBox(False, 8)
+        vbox2.set_border_width(8)
+        self.pack_start(vbox2, True, True, 0)
+
+        button = gtk.Button(stock='gtk-add')
+        button.connect("clicked", self.add_group, treeview)
+        vbox2.pack_start(button, False, False, 0)
+        button.show()
+
+        button_delete = gtk.Button(stock='gtk-remove')
+        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_GROUPNAME)
+        treeview2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+
+        sw2.add(treeview2)
+
+        # add columns to the tree view
+        self.__add_columns(treeview2)
+
+        self.pack_start(sw2, True, True, 0)
+
+        # Missing callbacks
+        button_delete.connect("clicked", self.remove_group, treeview2)
+
+
+    # -------------------
+    # User Management
+    # -------------------
+
+    # Add user in the model
+    def add_group_in_model(self, model, group):
+        iter = model.append()
+        model.set (iter,
+                   COLUMN_GROUPID,      group[COLUMN_GROUPID],
+                   COLUMN_CLASSNAME,    group[COLUMN_CLASSNAME],
+                   COLUMN_GROUPNAME,    group[COLUMN_GROUPNAME],
+                   COLUMN_DESCRIPTION,  group[COLUMN_DESCRIPTION]
+                   )
+
+    # profile_id: only groups in this profile are inserted
+    # If gwith = True,  create a list only with groups in the given profile_id
+    #           False, create a list only with groups NOT this profile_id
+    def __create_model(self, gwith, profile_id):
+
+        model = gtk.ListStore(
+            gobject.TYPE_INT,
+            gobject.TYPE_STRING,
+            gobject.TYPE_STRING,
+            gobject.TYPE_STRING)
+
+        # Grab the all the groups
+        self.cur.execute('SELECT group_id,name,description FROM groups ORDER BY name')
+        group_data = self.cur.fetchall()
+
+        for group in group_data:
+
+            group_id = group[0]
+            # Check our group is already in the profile
+            self.cur.execute('SELECT * FROM list_groups_in_profiles ' +
+                             'WHERE profile_id=? AND group_id=?',
+                             (profile_id, group_id))
+            group_is_already = self.cur.fetchall()
+
+            # Extract the class name of this group
+            class_name = constants.get_class_name_for_group_id(self.con,
+                                                               self.cur,
+                                                               group_id)
+
+            # Insert the class name in the group
+            group = (group[0], class_name, group[1], group[2])
+
+            if(gwith and group_is_already):
+                self.add_group_in_model(model, group)
+            elif(not gwith and not group_is_already):
+                self.add_group_in_model(model, group)
+
+        return model
+
+    def __add_columns(self, treeview):
+
+        model = treeview.get_model()
+
+        # columns for class name
+        renderer = gtk.CellRendererText()
+        renderer.set_data("column", COLUMN_CLASSNAME)
+        column = gtk.TreeViewColumn(_('Class'), renderer,
+                                    text=COLUMN_CLASSNAME)
+        column.set_sort_column_id(COLUMN_CLASSNAME)
+        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        column.set_fixed_width(constants.COLUMN_WIDTH_CLASSNAME)
+        treeview.append_column(column)
+
+        # columns for group name
+        renderer = gtk.CellRendererText()
+        renderer.set_data("column", COLUMN_GROUPNAME)
+        column = gtk.TreeViewColumn(_('Group'), renderer,
+                                    text=COLUMN_GROUPNAME)
+        column.set_sort_column_id(COLUMN_GROUPNAME)
+        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        column.set_fixed_width(constants.COLUMN_WIDTH_GROUPNAME)
+        treeview.append_column(column)
+
+        # column for description
+        renderer = gtk.CellRendererText()
+        renderer.set_data("column", COLUMN_DESCRIPTION)
+        column = gtk.TreeViewColumn(_('Description'), renderer,
+                                    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_EDIT)
+        treeview.append_column(column)
+
+
+    # Add a group from the left list to the right list
+    #
+    def add_group(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]
+            group_id           = model.get_value(iter, COLUMN_GROUPID)
+            class_name         = model.get_value(iter, COLUMN_CLASSNAME)
+            group_name         = model.get_value(iter, COLUMN_GROUPNAME)
+            group_description  = model.get_value(iter, COLUMN_DESCRIPTION)
+            model.remove(iter)
+
+            # Add in the the right view
+            self.add_group_in_model(self.model_right,
+                                    (group_id, class_name, group_name, group_description))
+
+            # Save the change in the base
+            self.cur.execute('INSERT OR REPLACE INTO list_groups_in_profiles ' +
+                             '(profile_id, group_id) VALUES (?, ?)',
+                             (self.profile_id, group_id))
+            self.con.commit()
+
+
+    # Add a group from the left list to the right list
+    #
+    def remove_group(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]
+            group_id           = model.get_value(iter, COLUMN_GROUPID)
+            class_name         = model.get_value(iter, COLUMN_CLASSNAME)
+            group_name         = model.get_value(iter, COLUMN_GROUPNAME)
+            group_description  = model.get_value(iter, COLUMN_DESCRIPTION)
+            model.remove(iter)
+
+            # Add in the the left view
+            self.add_group_in_model(self.model_left,
+                                    (group_id, class_name, group_name, group_description))
+
+            # Save the change in the base
+            self.cur.execute('DELETE FROM list_groups_in_profiles ' +
+                             'WHERE profile_id=? AND group_id=?',
+                             (self.profile_id, group_id))
+            self.con.commit()
+
+    # Done, can quit this dialog with saving
+    #
+    def ok(self, entry_profile, entry_description):
+        #
+        # Now everything is correct, create the profile
+        #
+
+        profile_data = (self.profile_id,
+                        entry_profile,
+                        entry_description
+                      )
+
+        if(self.new_profile):
+            # Check the login do not exist already
+            self.cur.execute('SELECT name FROM profiles WHERE name=?',
+                             (entry_profile,))
+            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 profile with this name"))
+                dialog.run()
+                dialog.destroy()
+                return
+
+            # Create the new profile
+            profile_id = constants.get_next_profile_id(self.con, self.cur)
+            self.cur.execute('INSERT INTO profiles (profile_id, name, description) ' +
+                             'VALUES ( ?, ?, ?)',
+                             (profile_data));
+        else:
+            # Save the profile changes
+            self.cur.execute('UPDATE profiles SET name=?, description=? where profile_id=?',
+                             (entry_profile,
+                              entry_description,
+                              self.profile_id));
+
+        self.con.commit()
diff --git a/src/administration-activity/administration.py b/src/administration-activity/administration.py
index 47905cb..bb4ddc2 100644
--- a/src/administration-activity/administration.py
+++ b/src/administration-activity/administration.py
@@ -76,6 +76,12 @@ class Gcompris_administration:
       m_list = glob.glob(gcompris.PYTHON_PLUGIN_DIR+'/admin/module_*.py')
     for file in m_list:
       m_name = file.split('/')[-1].split('.')[0].split('_')[1]
+      if gcompris.sugar_detected():
+        if (m_name == 'profiles' or m_name == 'boards'):
+          continue
+      else:
+        if (m_name == 'logins' or m_name == 'activities'):
+          continue
       list_modules.append(m_name)
 
     # Now import modules,
@@ -92,7 +98,7 @@ class Gcompris_administration:
     self.gcomprisBoard.maxlevel=1
     self.gcomprisBoard.sublevel=1
     self.gcomprisBoard.number_of_sublevel=1
-    gcompris.bar_set(0)
+    gcompris.bar_set(gcompris.BAR_JOURNAL | gcompris.BAR_SHARE)
     gcompris.set_default_background(self.gcomprisBoard.canvas.get_root_item())
     gcompris.bar_set_level(self.gcomprisBoard)
     gcompris.bar_location(25, -1, 0.6)
diff --git a/src/administration-activity/resources/administration/Makefile.am b/src/administration-activity/resources/administration/Makefile.am
index ee78dd2..4f65f50 100644
--- a/src/administration-activity/resources/administration/Makefile.am
+++ b/src/administration-activity/resources/administration/Makefile.am
@@ -11,7 +11,9 @@ img_DATA = \
 	difficulty3.svg \
 	difficulty4.svg \
 	difficulty5.svg \
-	difficulty6.svg
+	difficulty6.svg \
+	config_logins.svgz \
+	config_activities.svgz
 
 EXTRA_DIST = $(img_DATA) ${xml_in_files}
 CLEANFILES = $(xml_DATA)
diff --git a/src/administration-activity/resources/administration/config_activities.svgz b/src/administration-activity/resources/administration/config_activities.svgz
new file mode 100644
index 0000000..60b9b48
Binary files /dev/null and b/src/administration-activity/resources/administration/config_activities.svgz differ
diff --git a/src/administration-activity/resources/administration/config_logins.svgz b/src/administration-activity/resources/administration/config_logins.svgz
new file mode 100644
index 0000000..c9df374
Binary files /dev/null and b/src/administration-activity/resources/administration/config_logins.svgz differ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]