clPlugin.py

00001 #!/usr/bin/env python
00002 # -*- coding: utf-8 -*-
00003 
00004 # ----------------------------------------------------------------------------
00005 # pyjama - python jamendo audioplayer
00006 # Copyright (c) 2009 Daniel Nögel
00007 #
00008 # This program is free software: you can redistribute it and/or modify
00009 # it under the terms of the GNU General Public License as published by
00010 # the Free Software Foundation, either version 3 of the License, or
00011 # (at your option) any later version.
00012 #
00013 # This program is distributed in the hope that it will be useful,
00014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 # GNU General Public License for more details.
00017 # You should have received a copy of the GNU General Public License
00018 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 # ----------------------------------------------------------------------------
00020 
00021 # This Script was inspired by:
00022 # http://pytute.blogspot.com/2007/04/python-plugin-system.html
00023 # Over the time I made several changes which bloat the code a bit
00024 # but gives the opportunity to influence the order of the plugins
00025 
00026 ## @package clPlugin
00027 # Classes related to the pyjama plugin system
00028 
00029 import os
00030 import sys
00031 import imp
00032 #import clEvent
00033 import traceback
00034 
00035 import functions
00036 
00037 # for the dialog
00038 import gtk
00039 import gobject
00040 #from clWidgets import StockButton
00041 
00042 ### This might become a plugin class sometime
00043 ## this'd fix a lot of issues with the actual
00044 ## plugin system
00045 #class Plugin(object):
00046 #    def __init__(self):
00047 #        self.name = "Basic Plugin"
00048 #        self.description = "This is where every plugin comes from"
00049 #        self.version = "0.1"
00050 #        self.author = "Plugin Developer"
00051 #        self.license = "GPLv3"
00052 #        self.order = 100
00053 #        self.__preferences = None
00054 
00055 #    def set_preferences(self, opt):
00056 #        if isinstance(opt, object):
00057 #            self.__preferences = opt
00058 #        else:
00059 #            print "No valid preferences Box given"
00060 #            return
00061 #    def get_preferences(self):
00062 #        return self.__preferences
00063 #    preferences = property(get_preferences, set_preferences)
00064     
00065 
00066 ## Main Plugin managment -
00067 # reads a list of plugins, generates plugin infos
00068 # and imports and loads plugins
00069 class Plugins():
00070     ## The Constructor
00071     # @param self The Object pointer
00072     # @param pyjama Reference to pyjama
00073     def __init__(self, pyjama):
00074         ## Reference to the pyjama object
00075         self.pyjama = pyjama
00076 
00077         ## Dictionary holding loaded plugins
00078         self.loaded = {}
00079         ## List holding ignored plugins
00080         self.ignored = []
00081         ## Dictionary of all plugins by name
00082         self.plugins_by_name = {}
00083         ## Pyjama's plugin directory
00084         self.pluginpath = os.path.join(os.path.dirname(imp.find_module("pyjama")[1]), "plugins/")
00085         ## TRUE if pyhama crashed last run and browser where blacklisted for that reason
00086         self.blacklisted_browser = False
00087         print("%s %s %s" % (30*"-", " <Plugins> ", 30*"-"))
00088         print ("Found Plugins in folder: %s" % self.pluginpath)
00089         #self.plugins = [fname for fname in sorted(os.listdir(self.pluginpath)) if os.path.isdir(os.path.join (self.pluginpath, fname)) and os.path.exists(os.path.join(self.pluginpath, fname, "%s.info" % fname))]
00090 
00091         # list of plugins that are blacklisted
00092         hardcoded_blacklist = ["PMC", "torrent-peer", "lastplayed", "catchERR", "bookmarks", "playlists"]
00093 
00094 
00095         #
00096         # Listing plugins not supported anymore
00097         #
00098         try:
00099             files = os.listdir(self.pluginpath)
00100             if ".py" in "".join(files):
00101                 print "############################################################"
00102                 print "#                                                          #"
00103                 print "#  Pyjama uses a new plugin system. For this reason, all   #"
00104                 print "#  files in your plugin folder can be deleted. Please      #"
00105                 print "#  delete the files listed below to save your disk space.  #"
00106                 print "#                                                          #"
00107                 print "# !!The folders in the plugin dir should NOT be deleted!!  #"
00108                 print "#                                                          #"
00109                 print "############################################################"
00110             for dat in files:
00111                 dat_pos = os.path.join(self.pluginpath, dat)
00112                 if not os.path.isdir(dat_pos) and dat != "README":
00113                     print ("Don't know what to do with file %s" % dat_pos) 
00114 #            print "\n\n\n"
00115         except:
00116             pass
00117 
00118         # Sine you cannot import from filenames
00119         # with python, I put the plugin path
00120         # at the first place in the pathlist
00121         # after all modules are imported, this
00122         # entry is removed again. (last line in this methode)
00123         sys.path.insert(0, self.pluginpath[:-1])
00124 
00125         ## List of plugin informations
00126         self.plugininfos = []
00127 
00128 #        for plugin in self.plugins:
00129         for plugin in sorted(os.listdir(self.pluginpath)):
00130             # FIX: if autoload=false an plugin should not appear in the blacklist
00131             bl = self.pyjama.settings.get_value("PLUGINS", "blacklist", "")
00132             if os.path.exists(os.path.join(self.pluginpath, plugin, "%s.info" % plugin)) :
00133                 item_infos = self.get_infos(plugin)
00134                 if plugin in bl and item_infos["autoload"] == "false":
00135                     bl = bl.replace(plugin, "")
00136                     self.pyjama.settings.set_value("PLUGINS", "blacklist", bl)
00137                     print ("Removed %s from blacklist - autoload=false" % plugin)
00138 
00139             #~ print self.pyjama.settings.get_value("PYJAMA", "crashed", False)
00140             #~ print self.pyjama.check_another_instance_running() 
00141             #~ raw_input()
00142             if self.pyjama.settings.get_value("PYJAMA", "crashed", False) and (plugin == "mozplug" or plugin == "webkit-plugin") and self.pyjama.check_another_instance_running() != True:
00143                 whitelist = self.pyjama.settings.get_value("PLUGINS", "whitelist", "")
00144                 if plugin in whitelist:
00145                     print ("Pyjama crashed on last start - removing '%s' from whitelist again" % plugin)
00146                     whitelist = whitelist.replace(plugin, "")
00147                     self.pyjama.settings.set_value("PLUGINS", 'whitelist', whitelist)
00148                     self.blacklisted_browser = True
00149 
00150             if plugin in hardcoded_blacklist:
00151                 print("!!! %s found in 'hardcoded_blacklist'" % plugin)
00152             elif "noplugins" in sys.argv and not plugin+"+" in sys.argv:
00153                 pass
00154             elif os.path.isdir(os.path.join(self.pluginpath, plugin)) and os.path.exists(os.path.join(self.pluginpath, plugin, "%s.info" % plugin)) and not plugin+"-" in sys.argv and not plugin in self.pyjama.settings.get_value("PLUGINS", 'blacklist', "") or plugin+"+" in sys.argv:
00155                 if item_infos['autoload'] == "false":
00156                     if plugin in self.pyjama.settings.get_value("PLUGINS", 'whitelist', "") or plugin+"+" in sys.argv:
00157                         self.plugininfos.append(item_infos)
00158                         self.plugins_by_name[plugin]= item_infos
00159                     else:
00160                         self.ignored.append(item_infos)
00161                         self.plugins_by_name[plugin]= item_infos 
00162                 else:
00163                     self.plugininfos.append(item_infos)
00164                     self.plugins_by_name[plugin]= item_infos
00165             elif plugin+"-" in sys.argv or plugin in self.pyjama.settings.get_value("PLUGINS", 'blacklist'):
00166                 try:
00167                     self.ignored.append(item_infos)
00168                     self.plugins_by_name[plugin]= item_infos
00169                 except Exception, inst:
00170                     print "Plugin '%s' does not meet the specification" % plugin
00171 
00172         #
00173         # Sorting Plugins by Order
00174         #
00175         for x in range(len(self.plugininfos)):
00176             for plugin in range(0, len(self.plugininfos)-1):
00177                 if int(self.plugininfos[plugin]['order']) > int(self.plugininfos[plugin+1]['order']):
00178                     self.plugininfos[plugin], self.plugininfos[plugin+1] = self.plugininfos[plugin+1], self.plugininfos[plugin]
00179 
00180         #
00181         # Importing all plugins
00182         #
00183         ## list of imported plugins
00184         self.imported_modules = []
00185         for plugin in self.plugininfos:
00186             name = plugin['name']
00187             filename = plugin['filename']
00188             order = plugin['order']
00189             version = plugin['version']
00190             if not name+"-" in sys.argv and not name in self.pyjama.settings.get_value("PLUGINS", 'blacklist') or name+"+" in sys.argv:
00191                 try:
00192                     mod = __import__ (plugin['filename'])
00193 #                    if not self.pluginpath in mod.__file__:
00194 #                        print "Error"
00195                     self.imported_modules.append({'module':mod, 'name':name, 'order':order, 'version':version})
00196                 except Exception:
00197                     print traceback.format_exc()
00198                     print "Error importing Plugin %s (%s)" % (name, filename)
00199             else:
00200                 print "Plugin %s ignored" % name
00201 
00202         #
00203         # Calling main() for each plugin
00204         #
00205         ev = self.pyjama.Events
00206         for plugin in self.imported_modules:
00207             module = plugin['module']
00208             name = plugin['name']
00209             order = plugin['order']
00210             version = plugin['version']
00211             mod_name = module.__name__
00212             try:
00213                 self.loaded[mod_name] = module.main(self.pyjama)
00214                 ev.raise_event('pluginloaded', name=name, version=version, order=order, mod_name=mod_name)
00215             except:
00216                 print traceback.format_exc()
00217                 print "Error calling Plugin %s (%s)" % (name, mod_name)
00218                 print mod.__file__
00219 
00220         # removing plugin dir form the pathlist
00221         sys.path.pop(0)
00222         print("%s %s %s" % (30*"-", " </Plugins> ", 30*"-"))
00223 
00224     ## Reads out .info file of a plugin
00225     # @param self The Object pointer
00226     # @param plugin The plugin's filename as string
00227     # @return dictionary
00228     def get_infos(self, plugin):
00229         fh = open(os.path.join(self.pluginpath, plugin, "%s.info" % plugin))
00230         content = fh.read()
00231         fh.close()
00232         infos = content.split("\n")
00233 
00234         item_infos = {}
00235         item_infos['filename'] = plugin
00236         last_line = None
00237         
00238         item_infos['name'], item_infos['version'], item_infos['order'], item_infos['author'], item_infos['homepage'], item_infos['description'], item_infos['copyright'], item_infos['license'], item_infos['autoload'] = "unnamed plugin", "0.1", "100", "", "", "", "", "", "true"
00239         for line in infos:
00240             cur_item = line[:line.find("=")].strip().lower()
00241             if cur_item == "name":
00242                 #last_line = "name"
00243                 item_infos['name'] = line[line.find("=")+1:].strip()
00244             elif cur_item == "version": 
00245                 #last_line = "version"
00246                 item_infos['version'] = line[line.find("=")+1:].strip()
00247             elif cur_item == "order":
00248                 #last_line = "order"
00249                 item_infos['order'] = line[line.find("=")+1:].strip()
00250             elif cur_item == "author":
00251                 #last_line = "author"
00252                 item_infos['author'] = line[line.find("=")+1:].strip()
00253             elif cur_item == "homepage":
00254                 #last_line = "homepage"
00255                 item_infos['homepage'] = line[line.find("=")+1:].strip()
00256             elif cur_item == "copyright":
00257                 #last_line = "copyright"
00258                 item_infos['copyright'] = line[line.find("=")+1:].strip()
00259             elif cur_item == "autoload":
00260                 item_infos['autoload'] = line[line.find("=")+1:].strip()
00261             elif cur_item == "license":
00262                 item_infos['license'] = line[line.find("=")+1:].strip()
00263             elif cur_item == "description":
00264                 last_line = "description"
00265                 item_infos['description'] = line[line.find("=")+1:].strip()
00266             elif last_line is not None and line!="":
00267                 item_infos[last_line] += "\n%s" % line.strip()
00268         return item_infos
00269 
00270 (
00271     COLUMN_SELECTED,
00272     COLUMN_NAME,
00273     COLUMN_ID
00274 ) = range(3)
00275 
00276 ## This Plugin Dialog holds a list of all plugins
00277 # in order to give the user the opportunity to
00278 # choose which plugin is going to be loaded next
00279 # time. Furthermore it shows some basic informations
00280 # for each plugin as well as a preference dialog
00281 # if the plugin has one.
00282 class PluginDialog(gtk.Dialog):
00283     ## The Constructor
00284     # @param self The Object pointer
00285     # @param pyjama Reference to pyjama
00286     def __init__(self, pyjama):
00287         ## Holds a reference to pyjama
00288         self.pyjama = pyjama
00289         
00290         gtk.Dialog.__init__(self, "", pyjama.window)
00291 
00292         self.set_modal(True)
00293         self.set_title(_("Plugins"))
00294         self.set_border_width(5)
00295         self.set_size_request(500, 400)
00296         self.set_resizable(False)
00297 
00298         label = gtk.Label(_("Deselect Plugins you don't want to be started with pyjama."))
00299         label.set_line_wrap(True)
00300         label.set_single_line_mode(False)
00301         self.vbox.pack_start(label, expand=False, fill=True)
00302 
00303         hbox = gtk.HBox()
00304         self.vbox.pack_start(hbox)
00305 
00306         sw = gtk.ScrolledWindow()
00307         sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
00308         sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00309         hbox.pack_start(sw, True, True)
00310 
00311         ## The model holding all plugins
00312         self.model = self.__create_model()
00313 
00314         # create tree view
00315         self.__treeview = gtk.TreeView(self.model)
00316         self.__treeview.set_rules_hint(True)
00317         self.__treeview.set_search_column(COLUMN_NAME)
00318         selection = self.__treeview.get_selection()
00319         selection.connect("changed", self.cb_treeview_selection_changed)
00320 
00321         sw.add(self.__treeview)
00322 
00323         # add columns
00324         self.__add_columns(self.__treeview)
00325 
00326         # some buttons for our plugins
00327         buttonbox = gtk.VButtonBox()
00328         buttonbox.set_layout(gtk.BUTTONBOX_START) #gtk.BUTTONBOX_EDGE #SPREAD
00329         buttonbox.set_spacing(30)
00330         hbox.pack_end(buttonbox, False, True)
00331         bInfos = gtk.Button("", gtk.STOCK_ABOUT)#StockButton(gtk.STOCK_ABOUT, gtk.ICON_SIZE_DND, _("More Infos"))
00332         bInfos.set_property("image-position", gtk.POS_TOP)
00333         bInfos.connect("clicked", self.cb_bInfos_clicked)
00334         buttonbox.pack_start(bInfos, False, True)
00335         self.__bConfigure = gtk.Button("", gtk.STOCK_PREFERENCES)
00336         self.__bConfigure.set_property("image-position", gtk.POS_TOP)
00337         self.__bConfigure.connect("clicked", self.cb_bConfigure_clicked)
00338         self.__bConfigure.set_sensitive(False)
00339         buttonbox.pack_start(self.__bConfigure, False, True)
00340         buttonbox.show_all()
00341 
00342         self.add_button(gtk.STOCK_CANCEL, -1)
00343         self.add_button(gtk.STOCK_OK, 1)
00344 
00345         self.populate_list()
00346 
00347         self.show_all()
00348 
00349     ## Treeview Selection Callback
00350     # called whenever the selection of the treeview changes
00351     # @param self The Object pointer
00352     # @param treeselection The treeview's treeselection
00353     # @return None
00354     def cb_treeview_selection_changed(self, treeselection):
00355 
00356         model, iter = treeselection.get_selected()
00357     
00358         if iter is not None:
00359             idstr = model.get(iter, 2)[0]
00360             plugin = self.get_plugin_by_filename(idstr)
00361             if plugin is not None:
00362                 self.__bConfigure.set_sensitive(self.pyjama.preferences.has_preferences(idstr))
00363 
00364     ## Info Callback
00365     # called when the info button is pressed
00366     # @param self The Object pointer
00367     # @param widget The Info Button widget
00368     # @return None
00369     def cb_bInfos_clicked(self, widget):
00370         selection = self.__treeview.get_selection()
00371         model, iter = selection.get_selected()
00372     
00373         if iter is not None:
00374             idstr = model.get(iter, 2)[0]
00375             plugin = self.get_plugin_by_filename(idstr)
00376             if plugin is not None:
00377                 icon = os.path.join(functions.install_dir(), "plugins", idstr, "%s.png" % idstr)
00378                 if os.path.exists(icon):
00379                     pb = gtk.gdk.pixbuf_new_from_file(icon)
00380                 else:
00381                     pb = gtk.gdk.pixbuf_new_from_file_at_size(os.path.join(functions.install_dir(), "images", "plugin.png"), 92, 92)
00382                 dialog = gtk.AboutDialog()
00383                 dialog.set_name(plugin['name'])
00384                 dialog.set_logo(pb)
00385                 dialog.set_version(plugin['version'])
00386                 if plugin['copyright'] != "": 
00387                     dialog.set_copyright(plugin['copyright'])
00388                 dialog.set_comments(plugin['description'])
00389                 if plugin['license'] != "": 
00390                     dialog.set_license(functions.license2text(plugin['license']))
00391                 if plugin['homepage'] != "": 
00392                     dialog.set_website(plugin['homepage'])
00393                 dialog.set_authors(plugin['author'].split(","))
00394                 dialog.set_logo(None)
00395                 dialog.run()
00396                 dialog.set_modal(True)
00397                 dialog.destroy()
00398 
00399     ## Returns plugin infos for a given plugin filename
00400     # @param self The Object pointer
00401     # @param filename A plugin's filename
00402     # @return Dictionary holdingplugin infos
00403     def get_plugin_by_filename(self, filename):
00404         if filename in self.pyjama.plugins.plugins_by_name:
00405             return self.pyjama.plugins.plugins_by_name[filename]
00406 #        for plugin in self.pyjama.plugins.plugininfos:
00407 #            if plugin['filename'] == filename: return plugin
00408 #        for plugin in self.pyjama.plugins.ignored:
00409 #            if plugin['filename'] == filename: return plugin
00410 #        return None
00411 
00412     ## Configure Callback
00413     # called when the configure button is pressed
00414     # @param self The Object pointer
00415     # @param widget The Configure Button widget
00416     # @return None
00417     def cb_bConfigure_clicked(self, widget):
00418         selection = self.__treeview.get_selection()
00419         model, iter = selection.get_selected()
00420     
00421         if iter is not None:
00422             idstr = model.get(iter, 2)[0]
00423             plugin = self.get_plugin_by_filename(idstr)
00424             if plugin is not None:
00425                 if self.pyjama.preferences.has_preferences(idstr):
00426                     if not plugin['filename'] in self.pyjama.plugins.loaded:
00427                         dia = gtk.MessageDialog(self.pyjama.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("This plugin was not loaded yet.\nIf you want to configure it, please check it and restart Pyjama."))
00428                         dia.run()
00429                         dia.destroy()
00430                     else:
00431                         self.pyjama.show_preferences(name=idstr)
00432 
00433     def __create_model(self):
00434 
00435         # create list store
00436         model = gtk.ListStore(
00437             gobject.TYPE_BOOLEAN,
00438             gobject.TYPE_STRING,
00439             gobject.TYPE_STRING
00440        )
00441         return model
00442 
00443     def __add_columns(self, treeview):
00444         model = treeview.get_model()
00445 
00446         # column for select toggles
00447         renderer = gtk.CellRendererToggle()
00448         renderer.connect('toggled', self.select_toggled, model)
00449         column = gtk.TreeViewColumn(_('Load'), renderer, active=COLUMN_SELECTED)
00450         column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
00451         column.set_fixed_width(50)
00452         treeview.append_column(column)
00453 
00454 
00455         # column for name
00456         column = gtk.TreeViewColumn('Name', gtk.CellRendererText(), text=COLUMN_NAME)
00457         column.set_sort_column_id(COLUMN_NAME)
00458         treeview.append_column(column)
00459 
00460     ## Populates the treemodel
00461     # Addes all loaded and ignored plugins to the treemodel
00462     # @param self The Object pointer
00463     # @return liststore
00464     def populate_list(self):
00465         lstore = self.__treeview.get_model()
00466         lstore.clear()
00467 
00468         for plugin in self.pyjama.plugins.plugininfos:
00469             name = plugin['name']
00470             idstr = plugin['filename']
00471             description = plugin['description']
00472             if len(description)>40:description=description[:40]+"..."
00473             iter = lstore.append()
00474             selected = True
00475             if plugin['filename'] in self.pyjama.settings.get_value("PLUGINS", "blacklist", ""):
00476                 selected = False
00477             lstore.set(iter,
00478                 COLUMN_SELECTED, selected,
00479                 COLUMN_NAME, "%s\n%s" % (name, description),
00480                 COLUMN_ID, idstr
00481                 )
00482 
00483         for plugin in self.pyjama.plugins.ignored:
00484             name = plugin['name']
00485             idstr = plugin['filename']
00486             description = plugin['description']
00487             if len(description)>40:description=description[:40]+"..."
00488             iter = lstore.append()
00489             selected = False
00490             if not plugin['filename'] in self.pyjama.settings.get_value("PLUGINS", "blacklist", "") and not plugin['filename']+"-" in sys.argv:
00491                 if plugin['autoload'] == "true" or plugin['filename'] in self.pyjama.settings.get_value("PLUGINS", "whitelist", ""):
00492                     selected = True
00493             lstore.set(iter,
00494                 COLUMN_SELECTED, selected,
00495                 COLUMN_NAME, "%s\n%s" % (name, description),
00496                 COLUMN_ID, idstr
00497                 )
00498 
00499         lstore.set_sort_column_id(COLUMN_NAME,gtk.SORT_ASCENDING)  
00500 
00501         return lstore
00502 
00503     ## Toggle Callback
00504     # called when a plugin is checked / unchecked
00505     # @param self The Object pointer
00506     # @param cell  
00507     # @param path Path of the toggled column
00508     # @param model Model
00509     # @return None
00510     def select_toggled(self, cell, path, model):
00511         # get toggled iter
00512         iter = model.get_iter((int(path),))
00513         fixed = model.get_value(iter, COLUMN_SELECTED)
00514 
00515         # do something with the value
00516         fixed = not fixed
00517 
00518         # set new value
00519         model.set(iter, COLUMN_SELECTED, fixed)
00520 
00521 ## Runs and evaluates the PluginDialog Class
00522 # @param pyjama Pyjama Object Reference
00523 # @return None
00524 def ShowPluginsDialog(pyjama):
00525     dialog = PluginDialog(pyjama)
00526     model = dialog.model
00527     result = dialog.run()
00528     dialog.destroy()
00529     if result == 1: # delete
00530         blacklist = pyjama.settings.get_value("PLUGINS", 'blacklist', "")
00531         whitelist = pyjama.settings.get_value("PLUGINS", "whitelist", "")
00532         changes = None
00533         iter = model.get_iter_first()
00534 
00535         activated_browser = ""
00536         
00537         while iter:
00538             checked, name, idstr = ( model.get(iter, 0, 1, 2) )
00539             if checked == True:
00540                 if pyjama.plugins.plugins_by_name[idstr]['autoload'] == "false" and not idstr in whitelist:
00541                     whitelist += " %s" % idstr
00542                     changes = True
00543                     print "added %s to whitelist" % idstr
00544                     if idstr == "mozplug":
00545                         activated_browser += "mozplug"
00546                     elif idstr == "webkit-plugin":
00547                         activated_browser += "webkit-plugin"
00548                 elif idstr in blacklist:
00549                     blacklist = blacklist.replace(idstr, "")
00550                     changes = True
00551                     print "removed %s from blacklist" % idstr
00552             else:
00553                 if pyjama.plugins.plugins_by_name[idstr]['autoload'] == "false":
00554                     if idstr in whitelist:
00555                         whitelist = whitelist.replace(idstr, "")
00556                         changes = True
00557                         print "removed %s from whitelist" % idstr      
00558                 elif not idstr in blacklist:
00559                     changes = True
00560                     blacklist += " %s" % idstr
00561                     print "added %s to blacklist" % idstr
00562             iter = model.iter_next(iter)
00563         pyjama.settings.set_value("PLUGINS", 'blacklist', blacklist)
00564         pyjama.settings.set_value("PLUGINS", 'whitelist', whitelist)
00565         if changes is True:
00566             dia = gtk.MessageDialog(pyjama.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("You (un)selected some plugins.\nPlease note, that you will need to restart pyjama\nto let the changes take effect."))
00567             dia.run()
00568             dia.destroy()
00569 #            if activated_browser != "":
00570 #                txt = _("You selected '<b>%s</b>' as an integrated browser.\nPlease notice: Both browser plugins might not work on some systems:\n\n<b>Mozplug</b> crashes pyjama on startup on some systems.\nWith <b>webkit-plugin</b> pyjama might hang from time to time.\n\nDelete ~/.pyjama/pyjama.cfg if errors occure." % activated_browser)
00571 #                pyjama.info("Warning:", txt)
00572 #                #~ dia = gtk.MessageDialog(pyjama.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, txt)
00573 #                #~ dia.run()
00574 #                #~ dia.destroy()
00575             

Generated on Thu Jun 4 19:08:24 2009 for Pyjama by  doxygen 1.5.8