Plugin Manager refinements, part 1: refactored plugin lists, renamed Plugin Status to Plugin Manager, added functionality on loaded plugin page

svn: r14086
This commit is contained in:
Doug Blank 2010-01-17 16:24:56 +00:00
parent bd15fa674a
commit b66e96b8d9
5 changed files with 103 additions and 54 deletions

View File

@ -66,7 +66,7 @@ class PluginStatus(ManagedWindow.ManagedWindow):
def __init__(self, uistate, track=[]): def __init__(self, uistate, track=[]):
self.__uistate = uistate self.__uistate = uistate
self.title = _("Plugin Status") self.title = _("Plugin Manager")
ManagedWindow.ManagedWindow.__init__(self, uistate, track, ManagedWindow.ManagedWindow.__init__(self, uistate, track,
self.__class__) self.__class__)
@ -95,13 +95,15 @@ class PluginStatus(ManagedWindow.ManagedWindow):
col0_reg = gtk.TreeViewColumn(_('Type'), gtk.CellRendererText(), text=0) col0_reg = gtk.TreeViewColumn(_('Type'), gtk.CellRendererText(), text=0)
col0_reg.set_sort_column_id(0) col0_reg.set_sort_column_id(0)
self.list_reg.append_column(col0_reg) self.list_reg.append_column(col0_reg)
self.list_reg.append_column( col = gtk.TreeViewColumn(_('Status'), gtk.CellRendererText(), markup=1)
gtk.TreeViewColumn(_('Hidden'), gtk.CellRendererText(), markup=1)) col.set_sort_column_id(1)
self.list_reg.append_column(col)
col2_reg = gtk.TreeViewColumn(_('Name'), gtk.CellRendererText(), text=2) col2_reg = gtk.TreeViewColumn(_('Name'), gtk.CellRendererText(), text=2)
col2_reg.set_sort_column_id(2) col2_reg.set_sort_column_id(2)
self.list_reg.append_column(col2_reg) self.list_reg.append_column(col2_reg)
self.list_reg.append_column( col = gtk.TreeViewColumn(_('Description'), gtk.CellRendererText(), text=3)
gtk.TreeViewColumn(_('Description'), gtk.CellRendererText(), text=3)) col.set_sort_column_id(3)
self.list_reg.append_column(col)
self.list_reg.set_search_column(2) self.list_reg.set_search_column(2)
scrolled_window_reg.add(self.list_reg) scrolled_window_reg.add(self.list_reg)
@ -110,47 +112,76 @@ class PluginStatus(ManagedWindow.ManagedWindow):
hbutbox.set_layout(gtk.BUTTONBOX_SPREAD) hbutbox.set_layout(gtk.BUTTONBOX_SPREAD)
self.__info_btn = gtk.Button(_("Info")) self.__info_btn = gtk.Button(_("Info"))
hbutbox.add(self.__info_btn) hbutbox.add(self.__info_btn)
self.__info_btn.connect('clicked', self.__info) self.__info_btn.connect('clicked', self.__info, self.list_reg, 4) # id_col
self.__hide_btn = gtk.Button(_("Hide/Unhide")) self.__hide_btn = gtk.Button(_("Hide/Unhide"))
hbutbox.add(self.__hide_btn) hbutbox.add(self.__hide_btn)
self.__hide_btn.connect('clicked', self.__hide) self.__hide_btn.connect('clicked', self.__hide,
self.list_reg, 4, 1) # list, id_col, hide_col
if __debug__: if __debug__:
self.__edit_btn = gtk.Button(_("Edit")) self.__edit_btn = gtk.Button(_("Edit"))
hbutbox.add(self.__edit_btn) hbutbox.add(self.__edit_btn)
self.__edit_btn.connect('clicked', self.__edit) self.__edit_btn.connect('clicked', self.__edit, self.list_reg, 4) # id_col
self.__load_btn = gtk.Button(_("Load")) self.__load_btn = gtk.Button(_("Load"))
hbutbox.add(self.__load_btn) hbutbox.add(self.__load_btn)
self.__load_btn.connect('clicked', self.__load) self.__load_btn.connect('clicked', self.__load, self.list_reg, 4) # id_col
vbox_reg.pack_start(hbutbox, expand=False, padding=5) vbox_reg.pack_start(hbutbox, expand=False, padding=5)
notebook.append_page(vbox_reg, notebook.append_page(vbox_reg,
tab_label=gtk.Label(_('Registered plugins'))) tab_label=gtk.Label(_('Registered plugins')))
#second page with loaded plugins #second page with loaded plugins
vbox_loaded = gtk.VBox()
scrolled_window = gtk.ScrolledWindow() scrolled_window = gtk.ScrolledWindow()
self.list = gtk.TreeView() self.list = gtk.TreeView()
self.model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, self.model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
gobject.TYPE_STRING, object) gobject.TYPE_STRING, object,
gobject.TYPE_STRING, gobject.TYPE_STRING)
self.selection = self.list.get_selection() self.selection = self.list.get_selection()
self.list.set_model(self.model) self.list.set_model(self.model)
self.list.set_rules_hint(True) self.list.set_rules_hint(True)
self.list.connect('button-press-event', self.button_press) self.list.connect('button-press-event', self.button_press)
self.list.append_column( col = gtk.TreeViewColumn(_('Loaded'), gtk.CellRendererText(),
gtk.TreeViewColumn(_('Status'), gtk.CellRendererText(), markup=0)
markup=0)) col.set_sort_column_id(0)
col1 = gtk.TreeViewColumn(_('File'), gtk.CellRendererText(), text=1) self.list.append_column(col)
col1 = gtk.TreeViewColumn(_('File'), gtk.CellRendererText(),
text=1)
col1.set_sort_column_id(1) col1.set_sort_column_id(1)
self.list.append_column(col1) self.list.append_column(col1)
col = gtk.TreeViewColumn(_('Status'), gtk.CellRendererText(),
markup=5)
col.set_sort_column_id(5)
self.list.append_column(col)
col2 = gtk.TreeViewColumn(_('Message'), gtk.CellRendererText(), text=2) col2 = gtk.TreeViewColumn(_('Message'), gtk.CellRendererText(), text=2)
col2.set_sort_column_id(2) col2.set_sort_column_id(2)
self.list.append_column(col2) self.list.append_column(col2)
self.list.set_search_column(1) self.list.set_search_column(1)
scrolled_window.add(self.list) scrolled_window.add(self.list)
notebook.append_page(scrolled_window, vbox_loaded.pack_start(scrolled_window)
hbutbox = gtk.HButtonBox()
hbutbox.set_layout(gtk.BUTTONBOX_SPREAD)
self.__info_btn = gtk.Button(_("Info"))
hbutbox.add(self.__info_btn)
self.__info_btn.connect('clicked', self.__info, self.list, 4) # id_col
self.__hide_btn = gtk.Button(_("Hide/Unhide"))
hbutbox.add(self.__hide_btn)
self.__hide_btn.connect('clicked', self.__hide,
self.list, 4, 5) # list, id_col, hide_col
if __debug__:
self.__edit_btn = gtk.Button(_("Edit"))
hbutbox.add(self.__edit_btn)
self.__edit_btn.connect('clicked', self.__edit, self.list, 4) # id_col
self.__load_btn = gtk.Button(_("Load"))
hbutbox.add(self.__load_btn)
self.__load_btn.connect('clicked', self.__load, self.list, 4) # id_col
vbox_loaded.pack_start(hbutbox, expand=False, padding=5)
notebook.append_page(vbox_loaded,
tab_label=gtk.Label(_('Loaded plugins'))) tab_label=gtk.Label(_('Loaded plugins')))
#add the notebook to the window
self.window.vbox.add(notebook) self.window.vbox.add(notebook)
if __debug__: if __debug__:
@ -176,24 +207,37 @@ class PluginStatus(ManagedWindow.ManagedWindow):
fail_list = self.__pmgr.get_fail_list() fail_list = self.__pmgr.get_fail_list()
for i in fail_list: for i in fail_list:
# i = (filename, (exception-type, exception, traceback), pdata)
err = i[1][0] err = i[1][0]
pdata = i[2]
hidden = pdata.id in self.hidden
if hidden:
hiddenstr = self.HIDDEN
else:
hiddenstr = self.AVAILABLE
if err == Errors.UnavailableError: if err == Errors.UnavailableError:
self.model.append(row=[ self.model.append(row=[
'<span color="blue">%s</span>' % _('Unavailable'), '<span color="blue">%s</span>' % _('Unavailable'),
i[0], str(i[1][1]), None]) i[0], str(i[1][1]), None, pdata.id, hiddenstr])
else: else:
self.model.append(row=[ self.model.append(row=[
'<span weight="bold" color="red">%s</span>' % _('Fail'), '<span weight="bold" color="red">%s</span>' % _('Fail'),
i[0], str(i[1][1]), i[1]]) i[0], str(i[1][1]), i[1], pdata.id, hiddenstr])
success_list = self.__pmgr.get_success_list() success_list = self.__pmgr.get_success_list()
for i in success_list: for i in success_list:
# i = (filename, module, pdata)
pdata = i[2]
modname = i[1].__name__ modname = i[1].__name__
descr = self.__pmgr.get_module_description(modname) descr = self.__pmgr.get_module_description(modname)
hidden = pdata.id in self.hidden
if hidden:
hiddenstr = self.HIDDEN
else:
hiddenstr = self.AVAILABLE
self.model.append(row=[ self.model.append(row=[
'<span weight="bold" color="#267726">%s</span>' % _("OK"), '<span weight="bold" color="#267726">%s</span>' % _("OK"),
i[0], descr, None]) i[0], descr, None, pdata.id, hiddenstr])
def __populate_reg_list(self): def __populate_reg_list(self):
""" Build list of registered plugins""" """ Build list of registered plugins"""
@ -226,6 +270,12 @@ class PluginStatus(ManagedWindow.ManagedWindow):
if data: if data:
PluginTrace(self.uistate, [], data, name) PluginTrace(self.uistate, [], data, name)
def button_press_reg(self, obj, event):
""" Callback function from the user clicking on a line in reg plugin
"""
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
self.__info(obj, self.list_reg, 4)
def build_menu_names(self, obj): def build_menu_names(self, obj):
return (self.title, "") return (self.title, "")
@ -235,21 +285,16 @@ class PluginStatus(ManagedWindow.ManagedWindow):
self.__rebuild_load_list() self.__rebuild_load_list()
self.__rebuild_reg_list() self.__rebuild_reg_list()
def button_press_reg(self, obj, event): def __info(self, obj, list_obj, id_col):
""" Callback function from the user clicking on a line in reg plugin
"""
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
self.__info(None)
def __info(self, obj):
""" Callback function from the "Info" button """ Callback function from the "Info" button
""" """
model, node = self.selection_reg.get_selected() selection = list_obj.get_selection()
model, node = selection.get_selected()
if not node: if not node:
return return
id = model.get_value(node, 4) id = model.get_value(node, id_col)
typestr = model.get_value(node, 0)
pdata = self.__preg.get_plugin(id) pdata = self.__preg.get_plugin(id)
typestr = pdata.ptype
auth = ' - '.join(pdata.authors) auth = ' - '.join(pdata.authors)
email = ' - '.join(pdata.authors_email) email = ' - '.join(pdata.authors_email)
if len(auth) > 60: if len(auth) > 60:
@ -275,42 +320,45 @@ Location: %(fpath)s
} }
InfoDialog('Detailed Info', infotxt, parent=self.window) InfoDialog('Detailed Info', infotxt, parent=self.window)
def __hide(self, obj): def __hide(self, obj, list_obj, id_col, hide_col):
""" Callback function from the "Hide" button """ Callback function from the "Hide" button
""" """
model, node = self.selection_reg.get_selected() selection = list_obj.get_selection()
model, node = selection.get_selected()
if not node: if not node:
return return
id = model.get_value(node, 4) id = model.get_value(node, id_col)
if id in self.hidden: if id in self.hidden:
#unhide #unhide
self.hidden.remove(id) self.hidden.remove(id)
model.set_value(node, 1, self.AVAILABLE) model.set_value(node, hide_col, self.AVAILABLE)
self.__pmgr.unhide_plugin(id) self.__pmgr.unhide_plugin(id)
else: else:
#hide #hide
self.hidden.add(id) self.hidden.add(id)
model.set_value(node, 1, self.HIDDEN) model.set_value(node, hide_col, self.HIDDEN)
self.__pmgr.hide_plugin(id) self.__pmgr.hide_plugin(id)
def __load(self, obj): def __load(self, obj, list_obj, id_col):
""" Callback function from the "Load" button """ Callback function from the "Load" button
""" """
model, node = self.selection_reg.get_selected() selection = list_obj.get_selection()
model, node = selection.get_selected()
if not node: if not node:
return return
id = model.get_value(node, 4) id = model.get_value(node, id_col)
pdata = self.__preg.get_plugin(id) pdata = self.__preg.get_plugin(id)
self.__pmgr.load_plugin(pdata) self.__pmgr.load_plugin(pdata)
self.__rebuild_load_list() self.__rebuild_load_list()
def __edit(self, obj): def __edit(self, obj, list_obj, id_col):
""" Callback function from the "Load" button """ Callback function from the "Load" button
""" """
model, node = self.selection_reg.get_selected() selection = list_obj.get_selection()
model, node = selection.get_selected()
if not node: if not node:
return return
id = model.get_value(node, 4) id = model.get_value(node, id_col)
pdata = self.__preg.get_plugin(id) pdata = self.__preg.get_plugin(id)
open_file_with_default_application( open_file_with_default_application(
os.path.join(pdata.fpath, pdata.fname) os.path.join(pdata.fpath, pdata.fname)
@ -326,7 +374,7 @@ class PluginTrace(ManagedWindow.ManagedWindow):
def __init__(self, uistate, track, data, name): def __init__(self, uistate, track, data, name):
self.name = name self.name = name
title = "%s: %s" % (_("Plugin Status"), name) title = "%s: %s" % (_("Plugin Error"), name)
ManagedWindow.ManagedWindow.__init__(self, uistate, track, self) ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
self.set_window(gtk.Dialog("", uistate.window, self.set_window(gtk.Dialog("", uistate.window,

View File

@ -139,12 +139,12 @@ class BasePluginManager(object):
plugin = pdata.mod_name plugin = pdata.mod_name
try: try:
_module = __import__(plugin) _module = __import__(plugin)
self.__success_list.append((filename, _module)) self.__success_list.append((filename, _module, pdata))
self.__loaded_plugins[pdata.id] = _module self.__loaded_plugins[pdata.id] = _module
self.__mod2text[_module.__name__] = pdata.description self.__mod2text[_module.__name__] = pdata.description
return _module return _module
except: except:
self.__failmsg_list.append((filename, sys.exc_info())) self.__failmsg_list.append((filename, sys.exc_info(), pdata))
return None return None
def empty_managed_plugins(self): def empty_managed_plugins(self):
@ -168,19 +168,20 @@ class BasePluginManager(object):
for plugin in self.__success_list: for plugin in self.__success_list:
filename = plugin[0] filename = plugin[0]
pdata = plugin[2]
filename = filename.replace('pyc','py') filename = filename.replace('pyc','py')
filename = filename.replace('pyo','py') filename = filename.replace('pyo','py')
try: try:
reload(plugin[1]) reload(plugin[1])
except: except:
self.__failmsg_list.append((filename, sys.exc_info())) self.__failmsg_list.append((filename, sys.exc_info(), pdata))
# Remove previously good plugins that are now bad # Remove previously good plugins that are now bad
# from the registered lists # from the registered lists
self.__purge_failed() self.__purge_failed()
# attempt to load the plugins that have failed in the past # attempt to load the plugins that have failed in the past
for (filename, message) in oldfailmsg: for (filename, message, pdata) in oldfailmsg:
name = os.path.split(filename) name = os.path.split(filename)
match = pymod.match(name[1]) match = pymod.match(name[1])
if not match: if not match:
@ -193,9 +194,9 @@ class BasePluginManager(object):
# Looks like a bug in Python. # Looks like a bug in Python.
_module = __import__(plugin) _module = __import__(plugin)
reload(_module) reload(_module)
self.__success_list.append((filename, _module)) self.__success_list.append((filename, _module, pdata))
except: except:
self.__failmsg_list.append((filename, sys.exc_info())) self.__failmsg_list.append((filename, sys.exc_info(), pdata))
def get_fail_list(self): def get_fail_list(self):
""" Return the list of failed plugins. """ """ Return the list of failed plugins. """
@ -371,7 +372,7 @@ class BasePluginManager(object):
""" """
failed_module_names = [ failed_module_names = [
os.path.splitext(os.path.basename(filename))[0] os.path.splitext(os.path.basename(filename))[0]
for filename, junk in self.__failmsg_list for filename, msg, pdata in self.__failmsg_list
] ]
self.__export_plugins[:] = [ item for item in self.__export_plugins self.__export_plugins[:] = [ item for item in self.__export_plugins

View File

@ -243,7 +243,7 @@ def construct_view_order():
#import of plugin failed #import of plugin failed
ErrorDialog( ErrorDialog(
_('Failed Loading View'), _('Failed Loading View'),
_('The view %(name)s did not load. See Help Menu, Plugin Status' _('The view %(name)s did not load. See Help Menu, Plugin Manager'
' for more info.\nUse http://bugs.gramps-project.org to' ' for more info.\nUse http://bugs.gramps-project.org to'
' submit bugs of official views, contact the view ' ' submit bugs of official views, contact the view '
'author (%(firstauthoremail)s) otherwise. ') % { 'author (%(firstauthoremail)s) otherwise. ') % {

View File

@ -440,7 +440,7 @@ class ViewManager(CLIManager):
extra_plugins_activate), extra_plugins_activate),
('About', gtk.STOCK_ABOUT, _('_About'), None, None, ('About', gtk.STOCK_ABOUT, _('_About'), None, None,
display_about_box), display_about_box),
('PluginStatus', None, _('_Plugin Status'), None, None, ('PluginStatus', None, _('_Plugin Manager'), None, None,
self.__plugin_status), self.__plugin_status),
('FAQ', None, _('_FAQ'), None, None, faq_activate), ('FAQ', None, _('_FAQ'), None, None, faq_activate),
('KeyBindings', None, _('_Key Bindings'), None, None, key_bindings), ('KeyBindings', None, _('_Key Bindings'), None, None, key_bindings),
@ -1538,7 +1538,7 @@ def run_plugin(pdata, dbstate, uistate):
#import of plugin failed #import of plugin failed
ErrorDialog( ErrorDialog(
_('Failed Loading Plugin'), _('Failed Loading Plugin'),
_('The plugin did not load. See Help Menu, Plugin Status' _('The plugin did not load. See Help Menu, Plugin Manager'
' for more info.\nUse http://bugs.gramps-project.org to' ' for more info.\nUse http://bugs.gramps-project.org to'
' submit bugs of official plugins, contact the plugin ' ' submit bugs of official plugins, contact the plugin '
'author otherwise. ')) 'author otherwise. '))

View File

@ -263,7 +263,7 @@ class PlaceBaseView(ListView):
servfunc = eval('mod.' + serv.mapservice) servfunc = eval('mod.' + serv.mapservice)
servfunc()(self.dbstate.db, places) servfunc()(self.dbstate.db, places)
else: else:
print 'Failed to load map plugin, see Plugin Status' print 'Failed to load map plugin, see Plugin Manager'
def drag_info(self): def drag_info(self):
return DdTargets.PLACE_LINK return DdTargets.PLACE_LINK