Back to index

gcompris  8.2.2
board_list.py
Go to the documentation of this file.
00001 #  gcompris - board_list.py
00002 #
00003 # Copyright (C) 2005 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 import gnomecanvas
00021 import gcompris
00022 import gcompris.utils
00023 import gcompris.skin
00024 import gcompris.admin
00025 import gtk
00026 import gtk.gdk
00027 import gobject
00028 from gettext import gettext as _
00029 
00030 # Database
00031 #from pysqlite2 import dbapi2 as sqlite
00032 
00033 # Board Management
00034 (
00035    COLUMN_BOARDICON,
00036    COLUMN_BOARDNAME
00037 ) = range(2)
00038 
00039 class Board_list:
00040   """GCompris Boards List Table"""
00041 
00042 
00043   # area is the drawing area for the list
00044   def __init__(self, db_connect, db_cursor, frame):
00045 
00046       self.frame = frame
00047       self.cur = db_cursor
00048       self.con = db_connect
00049 
00050       # ---------------
00051       # Boards Management
00052       # ---------------
00053 
00054 
00055       # Create the profiles Combo
00056       self.profiles_list = gcompris.admin.get_profiles_list()
00057 
00058       # Get default pofile id.
00059       self.cur.execute('SELECT profile_id FROM informations;')
00060       self.con.commit()
00061 
00062       self.default_profile_id = self.cur.fetchall()[0][0]
00063 
00064       self.out_dict = self.get_boards_out_by_profile()
00065 
00066       self.difficulty = [1, 6]
00067 
00068       #print out_dict
00069 
00070       # Main box is vertical
00071       top_box = gtk.VBox(False, 8)
00072       top_box.show()
00073       self.frame.add(top_box)
00074 
00075       box1 = gtk.HBox(False, 8)
00076       box1.show()
00077 
00078       box2 = gtk.HBox(False, 8)
00079       box2.show()
00080 
00081       box3 = gtk.VBox(False, 8)
00082       box3.show()
00083 
00084       top_box.pack_start(box1, False, False, 0)
00085       top_box.pack_start(box2, True, True, 0)
00086 
00087       box2.pack_end(box3, False, False, 0)
00088 
00089       label = gtk.Label(_('Select a profile:'))
00090       label.show()
00091       box1.pack_start(label,False, False, 0)
00092 
00093       combobox = gtk.combo_box_new_text()
00094       combobox.show()
00095       box1.pack_start(combobox, False, False, 0)
00096 
00097       i = 0
00098       for profile in self.profiles_list:
00099         combobox.append_text(profile.name)
00100         if profile.profile_id == self.default_profile_id:
00101           combobox.set_active(self.profiles_list.index(profile))
00102 
00103       self.active_profile = self.profiles_list[combobox.get_active()]
00104       print 'Active profile is now', self.active_profile.name
00105 
00106       # Create the table
00107       sw = gtk.ScrolledWindow()
00108       sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
00109 #      sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
00110       sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00111 
00112       # create tree model
00113       self.model = self.__create_model()
00114 
00115       # update the combobox
00116       combobox.connect('changed', self.changed_cb)
00117 
00118       # create tree view
00119       treeview = gtk.TreeView(self.model)
00120       treeview.set_rules_hint(True)
00121       treeview.set_search_column(COLUMN_BOARDNAME)
00122 
00123       sw.add(treeview)
00124 
00125       # Some constants for the layout
00126       #but_height = hgap * 2
00127       #but_width  = hgap * 6
00128 
00129       box2.pack_start(sw, True, True, 0)
00130 
00131       sw.show()
00132       treeview.show()
00133 
00134       # add columns to the tree view
00135       self.__add_columns(treeview)
00136 
00137       # Add buttons
00138 
00139       self.button_configure = gtk.Button(stock=gtk.STOCK_PREFERENCES)
00140       self.button_configure.connect("clicked", self.configure_board)
00141       self.button_configure.show()
00142       box3.pack_start(self.button_configure, False, False, 0)
00143       self.button_configure.set_sensitive(False)
00144 
00145       self.button_filter = gtk.Button(_('Filter'))
00146       self.button_filter.connect("clicked", self.filter_boards)
00147       self.button_filter.show()
00148       box3.pack_start(self.button_filter, False, False, 0)
00149 
00150       self.button_select_all = gtk.Button(_('Select all'))
00151       self.button_select_all.connect("clicked", self.select_all_boards, True)
00152       self.button_select_all.show()
00153       box3.pack_start(self.button_select_all, False, False, 0)
00154 
00155       self.button_unselect_all = gtk.Button(_('Unselect all'))
00156       self.button_unselect_all.connect("clicked", self.select_all_boards, False)
00157       self.button_unselect_all.show()
00158       box3.pack_start(self.button_unselect_all, False, False, 0)
00159 
00160       self.button_locales = gtk.Button(_('Locales'))
00161       self.button_locales.connect("clicked", self.locales)
00162       self.button_locales.show()
00163       box3.pack_end(self.button_locales, False, False, 0)
00164 
00165       self.button_locales_sound = gtk.Button(_('Locales sound'))
00166       self.button_locales_sound.connect("clicked", self.locales_sound)
00167       self.button_locales_sound.show()
00168       box3.pack_end(self.button_locales_sound, False, False, 0)
00169 
00170       self.button_wordlist = gtk.Button(_('Wordlist'))
00171       self.button_wordlist.connect("clicked", self.wordlist)
00172       self.button_wordlist.show()
00173       box3.pack_end(self.button_wordlist, False, False, 0)
00174       #not ready yet
00175       self.button_wordlist.set_sensitive(False)
00176 
00177       self.button_login = gtk.Button(_('Login'))
00178       self.button_login.connect("clicked", self.login_configure)
00179       self.button_login.show()
00180       box3.pack_end(self.button_login, False, False, 0)
00181 
00182 
00183   # -------------------
00184   # Board Management
00185   # -------------------
00186 
00187   # Add boards in the model
00188   def get_board_by_name(self, name, list):
00189     for board in list:
00190       if (board.section + '/' + board.name) == name:
00191         return board
00192     return None
00193 
00194   def get_board_from_menu(self, menu, list):
00195     if menu.name =='':
00196       section = ''
00197     else:
00198       section = menu.section + '/' + menu.name
00199     return_list = []
00200     for board in list:
00201       if board.section == section:
00202         return_list.append([section, board])
00203 
00204     return return_list
00205 
00206   def add_boards_in_model(self, model, boards_list):
00207     root_menu = '/'
00208     root = self.get_board_by_name(root_menu, boards_list)
00209     boards_list.remove(root)
00210     menu_list = [[ None,  root ]]
00211 
00212     list = menu_list[:]
00213     while len(list) > 0:
00214       menu = list.pop(0)[1]
00215       list_board = self.get_board_from_menu(menu, boards_list)
00216       menu_list = menu_list + list_board
00217 
00218       for board_cell in list_board:
00219         if board_cell[1].type == 'menu':
00220           list.append(board_cell)
00221 
00222 
00223     row_dict = {}
00224     self.board_dict = {}
00225     height = 24
00226 
00227     for board_cell in menu_list:
00228       self.board_dict['%s/%s' % (board_cell[1].section,board_cell[1].name)] = board_cell[1]
00229 
00230 
00231       if  board_cell[0] == None:
00232         row_dict[''] =  \
00233                      model.append(None,
00234                                   [self.pixbuf_at_height('gcompris/misc/tuxplane.png', height),
00235                                    _('Main menu') + '\n' + '/',
00236                                    not board_cell[1].board_id in self.out_dict[self.active_profile.profile_id],
00237                                    '%s/%s' % (board_cell[1].section,board_cell[1].name), self.pixbuf_configurable(board_cell[1])])
00238 
00239       else:
00240         row_dict['%s/%s' % (board_cell[1].section,board_cell[1].name)] = \
00241                          model.append(row_dict[board_cell[1].section],
00242                                       [self.pixbuf_at_height(board_cell[1].icon_name, height),
00243                                        _(board_cell[1].title) + '\n' + '%s/%s' % (board_cell[1].section,board_cell[1].name),
00244                                        not board_cell[1].board_id in self.out_dict[self.active_profile.profile_id],
00245                                        '%s/%s' % (board_cell[1].section,board_cell[1].name), self.pixbuf_configurable(board_cell[1])])
00246 
00247 
00248   def pixbuf_at_height(self,file, height):
00249     pixbuf = gcompris.utils.load_pixmap(file)
00250     width = pixbuf.get_width()* height / pixbuf.get_height()
00251     del pixbuf
00252     pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(gcompris.DATA_DIR + '/' + file, width, height)
00253     return pixbuf
00254 
00255   def __create_model(self):
00256     model = gtk.TreeStore(
00257       gtk.gdk.Pixbuf,
00258       gobject.TYPE_STRING,
00259       gobject.TYPE_BOOLEAN,
00260       gobject.TYPE_STRING,
00261       gobject.TYPE_STRING,
00262       )
00263 
00264     self.boards_list = gcompris.admin.get_boards_list()
00265 
00266     self.add_boards_in_model(model, self.boards_list)
00267 
00268     return model
00269 
00270 
00271   def __add_columns(self, treeview):
00272 
00273     model = treeview.get_model()
00274 
00275     # Render for Board name with icon.
00276     cell_board_icon = gtk.CellRendererPixbuf()
00277 
00278     cell_board_title = gtk.CellRendererText()
00279 
00280     cell_active_board = gtk.CellRendererToggle()
00281     cell_active_board.set_property('activatable', True)
00282     cell_active_board.connect( 'toggled', self.board_acive_cb, model )
00283 
00284     cell_board_configure = gtk.CellRendererPixbuf()
00285 
00286 #    columns for Board name
00287 #    column_pref = gtk.TreeViewColumn(_('Conf'))
00288 #    image = gtk.image_new_from_stock(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU)
00289 #    image.show()
00290 #    column_pref.set_widget(image)
00291 
00292     column_active = gtk.TreeViewColumn(_('Active'))
00293     column_title = gtk.TreeViewColumn(_('Board title'))
00294     column_title.pack_start(cell_board_icon, False)
00295     column_active.pack_start(cell_board_configure, False)
00296     column_title.pack_start(cell_board_title, True)
00297     column_active.pack_start(cell_active_board, False)
00298 
00299     treeview.append_column(column_active)
00300     treeview.append_column(column_title)
00301 
00302     column_title.add_attribute(cell_board_icon, 'pixbuf', 0)
00303     column_title.add_attribute(cell_board_title, 'text', 1)
00304     column_active.add_attribute(cell_active_board, 'active', 2)
00305     column_active.set_attributes(cell_board_configure, stock_id=4)
00306 
00307     treeview.connect("cursor-changed", self.row_selected, model)
00308 
00309   def board_acive_cb(self, cell, path, model):
00310     model[path][2] = not model[path][2]
00311 
00312     if model[path][2]:
00313       self.update_parent(model[path].parent)
00314     else:
00315       self.check_parent_active(model[path].parent)
00316 
00317     try:
00318       self.update_child(model[path].iterchildren().next(), model[path][2])
00319     except StopIteration:
00320       pass
00321 
00322     self.update_selected(model, path)
00323 
00324   def update_selected(self, model, path):
00325     if model[path][2]:
00326       self.cur.execute('DELETE FROM activities_out WHERE board_id=%d AND out_id=%d' % (
00327         self.board_dict[model[path][3]].board_id,
00328                                                                                        self.active_profile.profile_id
00329         ))
00330     else:
00331       self.cur.execute('INSERT INTO activities_out (board_id, out_id) VALUES (%d, %d)' % (
00332         self.board_dict[model[path][3]].board_id,
00333         self.active_profile.profile_id
00334         ))
00335 
00336     self.con.commit()
00337 
00338     # update infos
00339     self.out_dict = self.get_boards_out_by_profile()
00340 
00341     return
00342 
00343   def dict_from_list(self, list):
00344     dict = {}
00345 
00346     for profile in  self.profiles_list:
00347       dict[profile.profile_id] = []
00348 
00349     for l in list:
00350       dict[l[1]].append(l[0])
00351 
00352     return dict
00353 
00354   def changed_cb(self, combobox):
00355     index = combobox.get_active()
00356     if(index<0):
00357       return
00358     self.active_profile = self.profiles_list[index]
00359 
00360     print 'Active profile is now', self.active_profile.name
00361 
00362     self.model.foreach(self.update_active)
00363 
00364   def update_active(self, model, path, iter):
00365     model[path][2] = not self.board_dict[model[path][3]].board_id in self.out_dict[self.active_profile.profile_id]
00366 
00367   def get_boards_out_by_profile(self):
00368     # Grab the user data
00369     self.cur.execute('select board_id, out_id from activities_out')
00370 
00371     return self.dict_from_list(self.cur.fetchall())
00372 
00373   def pixbuf_configurable(self, board):
00374     if board.is_configurable and board.type != "menu":
00375       return gtk.STOCK_PREFERENCES
00376     else:
00377       return None
00378 
00379   def preference_clicked(self, widget, event, board):
00380     print 'preference', board.title
00381 
00382   def row_selected(self, treeview,  model):
00383     path = model.get_path(treeview.get_selection().get_selected()[1])
00384     print "Row selected:", model[path][3]
00385 
00386     self.selected_board = self.board_dict[model[path][3]]
00387     if self.selected_board.is_configurable:
00388       self.button_configure.set_sensitive(True)
00389     else:
00390       self.button_configure.set_sensitive(False)
00391 
00392   def configure_board(self, button):
00393     gcompris.admin.board_config_start(self.selected_board,
00394                                       self.active_profile)
00395     #unused
00396     #gcompris.admin.board_config_stop(self.selected_board)
00397 
00398   def select_all_boards(self, button, Value):
00399     self.model.foreach(self.update_all, Value)
00400 
00401   def update_all(self, model, path, iter, Value):
00402     model[path][2] = Value
00403 
00404     self.update_selected( model, path)
00405 
00406 
00407   def filter_boards(self, button):
00408     window = gtk.Window()
00409     window.set_title(_("Filter Boards difficulty for profile %s") % (self.active_profile.name))
00410     window.set_border_width(8)
00411     window.set_default_size(320, 350)
00412     window.set_transient_for(self.frame.get_toplevel())
00413     window.set_modal(True)
00414     window.show()
00415 
00416     button_close = gtk.Button(stock=gtk.STOCK_CLOSE)
00417     button_close.connect("clicked", self.filter_close, window)
00418     button_close.show()
00419 
00420     button_apply = gtk.Button(stock=gtk.STOCK_APPLY)
00421     button_apply.connect("clicked", self.filter_apply)
00422     button_apply.show()
00423 
00424     main_box = gtk.VBox(False, 8)
00425     main_box.show()
00426     window.add(main_box)
00427 
00428     box_bottom = gtk.HBox(False, 0)
00429     box_bottom.show()
00430     main_box.pack_end(box_bottom, False, False, 0)
00431 
00432     sep = gtk.HSeparator()
00433     sep.show()
00434     main_box.pack_end(sep, False, False, 8)
00435 
00436     box_bottom.pack_end(button_close, False, False, 0)
00437     box_bottom.pack_start(button_apply, False, False, 0)
00438 
00439     label = gtk.Label()
00440     label.set_markup(_("<span size='x-large'> Select the difficulty range \nfor profile <b>%s</b></span>") % self.active_profile.name)
00441     label.show()
00442     label.set_line_wrap(True)
00443     label.set_justify(gtk.JUSTIFY_CENTER)
00444     main_box.pack_start(label, False, False, 0)
00445 
00446     symbols_box = gtk.HBox(False, 0)
00447     symbols_box.show()
00448     main_box.pack_start(symbols_box, False, False, 0)
00449 
00450     arrows_box = gtk.HBox(False, 0)
00451     arrows_box.show()
00452     main_box.pack_start(arrows_box, False, False, 0)
00453 
00454     self.stars = {}
00455 
00456     for i in range(1,7):
00457       box = gtk.VBox(False, 8)
00458       box.show()
00459       symbols_box.pack_start(box, True, False, 0)
00460       self.stars[i] = gtk.Image()
00461       self.stars[i].set_from_pixbuf(gcompris.skin.load_pixmap('difficulty_star%d.png' % (i)))
00462       self.stars[i].show()
00463       box.pack_start(self.stars[i], False, False, 0)
00464       i_label = gtk.Label()
00465       i_label.set_markup("<span size='x-large'><b>%d</b></span>" % i)
00466       i_label.show()
00467       box.pack_start(i_label, False, False, 0)
00468 
00469     self.arrows = {}
00470 
00471     self.arrows[1] = self.create_arrow_button(gtk.ARROW_LEFT, gtk.SHADOW_IN)
00472     self.arrows[2] = self.create_arrow_button(gtk.ARROW_RIGHT, gtk.SHADOW_IN)
00473     self.arrows[3] = self.create_arrow_button(gtk.ARROW_LEFT, gtk.SHADOW_IN)
00474     self.arrows[4] = self.create_arrow_button(gtk.ARROW_RIGHT, gtk.SHADOW_IN)
00475 
00476     arrows_box.pack_start(self.arrows[1], False, False, 3)
00477     arrows_box.pack_start(self.arrows[2], False, False, 3)
00478     arrows_box.pack_end(self.arrows[4], False, False, 3)
00479     arrows_box.pack_end(self.arrows[3], False, False, 3)
00480 
00481     for i in range (1,5):
00482       self.arrows[i].connect("clicked", self.arrow_clicked, i)
00483 
00484     self.update_arrows_active()
00485 
00486   def filter_close(self, button, window):
00487     window.destroy()
00488 
00489   def create_arrow_button(self, arrow_type, shadow_type):
00490     button = gtk.Button();
00491     arrow = gtk.Arrow(arrow_type, shadow_type);
00492     button.add(arrow)
00493     button.show()
00494     arrow.show()
00495     return button
00496 
00497   def update_arrows_active(self):
00498     if self.difficulty[0] == 1:
00499       self.arrows[1].set_sensitive(False)
00500     else:
00501       self.arrows[1].set_sensitive(True)
00502 
00503     if self.difficulty[1] == 6:
00504       self.arrows[4].set_sensitive(False)
00505     else:
00506       self.arrows[4].set_sensitive(True)
00507 
00508     if self.difficulty[1] == 1:
00509       self.arrows[3].set_sensitive(False)
00510     else:
00511       self.arrows[3].set_sensitive(True)
00512 
00513     if self.difficulty[0] == 6:
00514       self.arrows[2].set_sensitive(False)
00515     else:
00516       self.arrows[2].set_sensitive(True)
00517 
00518     if self.difficulty[0] == self.difficulty[1]:
00519       self.arrows[2].set_sensitive(False)
00520       self.arrows[3].set_sensitive(False)
00521 
00522     for i in range(1,7):
00523       if i in range( self.difficulty[0], self.difficulty[1]+1):
00524         self.stars[i].set_sensitive(True)
00525       else:
00526         self.stars[i].set_sensitive(False)
00527 
00528   def arrow_clicked(self, arrow, i):
00529     if i < 3:
00530       value = 0
00531       limits = [1, self.difficulty[1]]
00532     else:
00533       value = 1
00534       limits = [self.difficulty[0], 6]
00535 
00536     if (i % 2 == 0):
00537       if self.difficulty[value] == limits[1]:
00538         return
00539       else:
00540         self.difficulty[value] = self.difficulty[value] + 1
00541     else:
00542       if self.difficulty[value] == limits[0]:
00543         return
00544       else:
00545         self.difficulty[value] = self.difficulty[value] - 1
00546 
00547     self.update_arrows_active()
00548 
00549   def filter_apply(self, button):
00550     self.model.foreach(self.blank)
00551     self.model.foreach(self.board_filter)
00552 
00553   # Apply the filter as asked.
00554   def board_filter(self,  model, path, iter):
00555     if self.board_dict[model[path][3]].type != "menu":
00556       model[path][2] = ( eval(self.board_dict[model[path][3]].difficulty) \
00557                          in range( self.difficulty[0],
00558                                    self.difficulty[1]+1))
00559 
00560     print self.board_dict[model[path][3]].name, self.board_dict[model[path][3]].difficulty, self.difficulty, model[path][2]
00561 
00562     if model[path][2]:
00563       self.update_parent(model[path].parent)
00564 
00565     self.update_selected( model, path)
00566 
00567   # toggled off.
00568   def blank(self,  model, path, iter):
00569     model[path][2] = False
00570 
00571   # This function toggles parents when a child is toggled.
00572   def update_parent( self, row):
00573     if row == None:
00574       return
00575 
00576     if row[2]:
00577       return
00578 
00579     row[2] = True
00580 
00581     self.update_parent( row.parent)
00582 
00583     self.update_selected(row.model, row.path)
00584 
00585   # This function toggles parents off when all childs are toggled off.
00586   def check_parent_active( self, row):
00587     if row == None:
00588       return
00589 
00590     # should never appends
00591     if not row[2]:
00592       return
00593 
00594     child = row.iterchildren().next()
00595     select = False
00596 
00597     while child != None:
00598       if child[2]:
00599         select = True
00600         break
00601       child = child.next
00602 
00603     if not select:
00604       row[2] = False
00605       self.check_parent_active(row.parent)
00606       self.update_selected(row.model, row.path)
00607 
00608   # This function recursively update childs
00609   def update_child( self, row, value):
00610     if row[2] == value:
00611       return
00612 
00613     row[2] = value
00614 
00615     try:
00616       self.update_child(row.iterchildren().next(), value)
00617     except StopIteration:
00618       pass
00619 
00620     if row.next != None:
00621       self.update_child(row.next, value)
00622 
00623     self.update_selected(row.model, row.path)
00624 
00625   ########################################################
00626   ########################################################
00627 
00628   def locales(self, button):
00629     conf_locales = self.get_configured(self.active_profile, 'locale', 'NULL')
00630     self.main_vbox = gcompris.configuration_window ( \
00631       _('<b>%s</b> configuration\n for profile <b>%s</b>') % ('Locale', self.active_profile.name ),
00632       self.ok_callback
00633       )
00634 
00635     label = gtk.Label()
00636     label.set_line_wrap(True)
00637     label.set_markup('Choose the default locale used by localizable boards for profile %s' % self.active_profile.name)
00638     label.show()
00639     self.main_vbox.pack_start (label, False, False, 8)
00640 
00641     gcompris.separator()
00642 
00643     gcompris.combo_locales( conf_locales)
00644 
00645   def locales_sound(self, button):
00646 
00647     conf_locales = self.get_configured(self.active_profile, 'locale_sound', 'NULL')
00648     self.main_vbox = gcompris.configuration_window ( \
00649       _('<b>%s</b> configuration\n for profile <b>%s</b>') % ('Locale sound', self.active_profile.name ),
00650       self.ok_callback
00651       )
00652 
00653     label = gtk.Label()
00654     label.set_line_wrap(True)
00655     label.set_markup('Choose the default locale for <b>sounds</b> used by localizable boards for profile %s' % self.active_profile.name)
00656     label.show()
00657     self.main_vbox.pack_start (label, False, False, 8)
00658 
00659     gcompris.separator()
00660 
00661     gcompris.combo_locales_asset( _("Select sound locale"),
00662                                   conf_locales,
00663                                   "sounds/$LOCALE/colors/purple.ogg" )
00664 
00665 
00666   def ok_callback(self, dict):
00667 
00668     for key, value in dict.iteritems():
00669       if key in self.already_conf:
00670         req = 'UPDATE board_profile_conf SET conf_value=\'%s\' WHERE profile_id=%d AND board_id=-1 AND conf_key=\'%s\'' % (value, self.active_profile.profile_id, key)
00671       else:
00672         req = 'INSERT INTO board_profile_conf (profile_id, board_id, conf_key, conf_value) VALUES (%d, -1, \'%s\', \'%s\')' % (self.active_profile.profile_id, key, value)
00673 
00674       self.cur.execute(req)
00675       self.con.commit()
00676 
00677   def get_configured(self, profile, key, if_not):
00678     self.cur.execute('select conf_value from board_profile_conf where profile_id=%d and board_id=-1 and conf_key =\'%s\' ' % (profile.profile_id, key))
00679 
00680     value = self.cur.fetchall()
00681 
00682     try:
00683       s = self.already_conf
00684     except:
00685       self.already_conf = []
00686 
00687     if len(value)==1:
00688       self.already_conf.append(key)
00689       return value[0][0]
00690     else:
00691       return if_not
00692 
00693 
00694   def login_configure(self, button):
00695     print "__login configure__"
00696     board_log = self.get_board_by_name('/login/login', self.boards_list)
00697     print board_log.name, board_log.is_configurable
00698     gcompris.admin.board_config_start(board_log,
00699                                       self.active_profile)
00700 
00701 
00702 
00703   def wordlist(self, button):
00704     import wordlist
00705     wordlist.Words_list(self.con, self.cur, self.active_profile)