0001981: Update plugin status when reloading plugins
Plus some cleanup. svn: r10439
This commit is contained in:
parent
e7a6115c91
commit
bfe3ee1590
@ -95,7 +95,7 @@ def load_plugins(direct):
|
|||||||
responsible for registering itself in the correct manner. No attempt
|
responsible for registering itself in the correct manner. No attempt
|
||||||
is done in this routine to register the tasks. Returns True on error. """
|
is done in this routine to register the tasks. Returns True on error. """
|
||||||
|
|
||||||
global success_list,attempt_list,loaddir_list,failmsg_list
|
global success_list, attempt_list, loaddir_list, failmsg_list
|
||||||
|
|
||||||
# if the directory does not exist, do nothing
|
# if the directory does not exist, do nothing
|
||||||
if not os.path.isdir(direct):
|
if not os.path.isdir(direct):
|
||||||
@ -132,6 +132,71 @@ def load_plugins(direct):
|
|||||||
|
|
||||||
return len(failmsg_list) != 0 # return True if there are errors
|
return len(failmsg_list) != 0 # return True if there are errors
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# reload_plugins
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def reload_plugins():
|
||||||
|
""" Reload previously loaded plugins """
|
||||||
|
global success_list, attempt_list, loaddir_list, failmsg_list
|
||||||
|
|
||||||
|
pymod = re.compile(r"^(.*)\.py$")
|
||||||
|
|
||||||
|
oldfailmsg = failmsg_list[:]
|
||||||
|
failmsg_list = []
|
||||||
|
|
||||||
|
# attempt to reload all plugins that have succeeded in the past
|
||||||
|
for plugin in success_list:
|
||||||
|
filename = plugin[0]
|
||||||
|
filename = filename.replace('pyc','py')
|
||||||
|
filename = filename.replace('pyo','py')
|
||||||
|
try:
|
||||||
|
reload(plugin[1])
|
||||||
|
except:
|
||||||
|
failmsg_list.append((filename, sys.exc_info()))
|
||||||
|
|
||||||
|
# Remove previously good plugins that are now bad
|
||||||
|
# from the registered lists
|
||||||
|
purge_failed()
|
||||||
|
|
||||||
|
# attempt to load the plugins that have failed in the past
|
||||||
|
for (filename, message) in oldfailmsg:
|
||||||
|
name = os.path.split(filename)
|
||||||
|
match = pymod.match(name[1])
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
attempt_list.append(filename)
|
||||||
|
plugin = match.groups()[0]
|
||||||
|
try:
|
||||||
|
# For some strange reason second importing of a failed plugin
|
||||||
|
# results in success. Then reload reveals the actual error.
|
||||||
|
# Looks like a bug in Python.
|
||||||
|
a = __import__(plugin)
|
||||||
|
reload(a)
|
||||||
|
success_list.append((filename, a))
|
||||||
|
except:
|
||||||
|
failmsg_list.append((filename, sys.exc_info()))
|
||||||
|
|
||||||
|
# attempt to load any new files found
|
||||||
|
for directory in loaddir_list:
|
||||||
|
for filename in os.listdir(directory):
|
||||||
|
name = os.path.split(filename)
|
||||||
|
match = pymod.match(name[1])
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
if filename in attempt_list:
|
||||||
|
continue
|
||||||
|
attempt_list.append(filename)
|
||||||
|
plugin = match.groups()[0]
|
||||||
|
try:
|
||||||
|
a = __import__(plugin)
|
||||||
|
if a not in [plugin[1]
|
||||||
|
for plugin in success_list]:
|
||||||
|
success_list.append((filename, a))
|
||||||
|
except:
|
||||||
|
failmsg_list.append((filename, sys.exc_info()))
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Plugin registering
|
# Plugin registering
|
||||||
|
@ -55,16 +55,17 @@ import _Tool as Tool
|
|||||||
class PluginStatus(ManagedWindow.ManagedWindow):
|
class PluginStatus(ManagedWindow.ManagedWindow):
|
||||||
"""Displays a dialog showing the status of loaded plugins"""
|
"""Displays a dialog showing the status of loaded plugins"""
|
||||||
|
|
||||||
def __init__(self, state, uistate, track=[]):
|
def __init__(self, uistate, track=[]):
|
||||||
|
self.__uistate = uistate
|
||||||
self.title = _("Plugin Status")
|
self.title = _("Plugin Status")
|
||||||
ManagedWindow.ManagedWindow.__init__(self,uistate,track,self.__class__)
|
ManagedWindow.ManagedWindow.__init__(self, uistate, track,
|
||||||
|
self.__class__)
|
||||||
|
|
||||||
self.set_window(gtk.Dialog("",uistate.window,
|
self.set_window(gtk.Dialog("", uistate.window,
|
||||||
gtk.DIALOG_DESTROY_WITH_PARENT,
|
gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
|
(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
|
||||||
None, self.title)
|
None, self.title)
|
||||||
self.window.set_size_request(600,400)
|
self.window.set_size_request(600, 400)
|
||||||
self.window.connect('response', self.close)
|
self.window.connect('response', self.close)
|
||||||
|
|
||||||
scrolled_window = gtk.ScrolledWindow()
|
scrolled_window = gtk.ScrolledWindow()
|
||||||
@ -88,8 +89,19 @@ class PluginStatus(ManagedWindow.ManagedWindow):
|
|||||||
|
|
||||||
scrolled_window.add(self.list)
|
scrolled_window.add(self.list)
|
||||||
self.window.vbox.add(scrolled_window)
|
self.window.vbox.add(scrolled_window)
|
||||||
|
|
||||||
|
if __debug__:
|
||||||
|
# Only show the "Reload" button when in debug mode
|
||||||
|
# (without -O on the command line)
|
||||||
|
self.__reload_btn = gtk.Button("Reload")
|
||||||
|
self.window.action_area.add(self.__reload_btn)
|
||||||
|
self.__reload_btn.connect('clicked', self.__reload)
|
||||||
|
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
self.__populate_list()
|
||||||
|
|
||||||
|
def __populate_list(self):
|
||||||
|
""" Build the list of plugins """
|
||||||
for i in PluginMgr.failmsg_list:
|
for i in PluginMgr.failmsg_list:
|
||||||
err = i[1][0]
|
err = i[1][0]
|
||||||
|
|
||||||
@ -110,6 +122,7 @@ class PluginStatus(ManagedWindow.ManagedWindow):
|
|||||||
i[0], descr, None])
|
i[0], descr, None])
|
||||||
|
|
||||||
def button_press(self, obj, event):
|
def button_press(self, obj, event):
|
||||||
|
""" Callback function from the user clicking on a line """
|
||||||
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
|
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
|
||||||
model, node = self.selection.get_selected()
|
model, node = self.selection.get_selected()
|
||||||
data = model.get_value(node, 3)
|
data = model.get_value(node, 3)
|
||||||
@ -118,8 +131,16 @@ class PluginStatus(ManagedWindow.ManagedWindow):
|
|||||||
PluginTrace(self.uistate, self.track, data, name)
|
PluginTrace(self.uistate, self.track, data, name)
|
||||||
|
|
||||||
def build_menu_names(self, obj):
|
def build_menu_names(self, obj):
|
||||||
return ( _('Summary'),self.title)
|
return (self.title, "")
|
||||||
|
|
||||||
|
def __reload(self, obj):
|
||||||
|
""" Callback function from the "Reload" button """
|
||||||
|
PluginMgr.reload_plugins()
|
||||||
|
self.__uistate.emit('plugins-reloaded',
|
||||||
|
(PluginMgr.tool_list, PluginMgr.report_list))
|
||||||
|
self.model.clear()
|
||||||
|
self.__populate_list()
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Details for an individual plugin that failed
|
# Details for an individual plugin that failed
|
||||||
@ -133,15 +154,15 @@ class PluginTrace(ManagedWindow.ManagedWindow):
|
|||||||
title = "%s: %s" % (_("Plugin Status"), name)
|
title = "%s: %s" % (_("Plugin Status"), 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,
|
||||||
gtk.DIALOG_DESTROY_WITH_PARENT,
|
gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
|
(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
|
||||||
None, title)
|
None, title)
|
||||||
self.window.set_size_request(600,400)
|
self.window.set_size_request(600, 400)
|
||||||
self.window.connect('response', self.close)
|
self.window.connect('response', self.close)
|
||||||
|
|
||||||
scrolled_window = gtk.ScrolledWindow()
|
scrolled_window = gtk.ScrolledWindow()
|
||||||
scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
|
scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||||
self.text = gtk.TextView()
|
self.text = gtk.TextView()
|
||||||
scrolled_window.add(self.text)
|
scrolled_window.add(self.text)
|
||||||
self.text.get_buffer().set_text(
|
self.text.get_buffer().set_text(
|
||||||
@ -189,18 +210,18 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
self.style_button = None
|
self.style_button = None
|
||||||
|
|
||||||
window = gtk.Dialog('Tool')
|
window = gtk.Dialog('Tool')
|
||||||
self.set_window(window,None,self.get_title())
|
self.set_window(window, None, self.get_title())
|
||||||
#self.window.set_has_separator(False)
|
#self.window.set_has_separator(False)
|
||||||
|
|
||||||
#self.window.connect('response', self.close)
|
#self.window.connect('response', self.close)
|
||||||
self.cancel = self.window.add_button(gtk.STOCK_CLOSE,
|
self.cancel = self.window.add_button(gtk.STOCK_CLOSE,
|
||||||
gtk.RESPONSE_CANCEL)
|
gtk.RESPONSE_CANCEL)
|
||||||
self.cancel.connect('clicked',self.close)
|
self.cancel.connect('clicked', self.close)
|
||||||
|
|
||||||
self.ok = self.window.add_button(gtk.STOCK_APPLY, gtk.RESPONSE_OK)
|
self.ok = self.window.add_button(gtk.STOCK_APPLY, gtk.RESPONSE_OK)
|
||||||
self.ok.connect('clicked',self.on_ok_clicked)
|
self.ok.connect('clicked', self.on_ok_clicked)
|
||||||
|
|
||||||
self.window.set_default_size(600,-1)
|
self.window.set_default_size(600, -1)
|
||||||
|
|
||||||
# Set up and run the dialog. These calls are not in top down
|
# Set up and run the dialog. These calls are not in top down
|
||||||
# order when looking at the dialog box as there is some
|
# order when looking at the dialog box as there is some
|
||||||
@ -208,7 +229,7 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
|
|
||||||
self.setup_title()
|
self.setup_title()
|
||||||
self.setup_header()
|
self.setup_header()
|
||||||
self.tbl = gtk.Table(4,4,False)
|
self.tbl = gtk.Table(4, 4, False)
|
||||||
self.tbl.set_col_spacings(12)
|
self.tbl.set_col_spacings(12)
|
||||||
self.tbl.set_row_spacings(6)
|
self.tbl.set_row_spacings(6)
|
||||||
self.tbl.set_border_width(6)
|
self.tbl.set_border_width(6)
|
||||||
@ -241,7 +262,7 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
# Callback functions from the dialog
|
# Callback functions from the dialog
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
def on_cancel(self,*obj):
|
def on_cancel(self, *obj):
|
||||||
pass # cancel just closes
|
pass # cancel just closes
|
||||||
|
|
||||||
def on_ok_clicked(self, obj):
|
def on_ok_clicked(self, obj):
|
||||||
@ -266,7 +287,8 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
iter = view.get_iter_at_location(*buffer_location)
|
iter = view.get_iter_at_location(*buffer_location)
|
||||||
for (tag, person_handle) in self.tags:
|
for (tag, person_handle) in self.tags:
|
||||||
if iter.has_tag(tag):
|
if iter.has_tag(tag):
|
||||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(self.link_cursor)
|
_window = view.get_window(gtk.TEXT_WINDOW_TEXT)
|
||||||
|
_window.set_cursor(self.link_cursor)
|
||||||
return False # handle event further, if necessary
|
return False # handle event further, if necessary
|
||||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(self.standard_cursor)
|
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(self.standard_cursor)
|
||||||
return False # handle event further, if necessary
|
return False # handle event further, if necessary
|
||||||
@ -299,7 +321,7 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
self.results_write(text)
|
self.results_write(text)
|
||||||
start = buffer.get_iter_at_offset(offset)
|
start = buffer.get_iter_at_offset(offset)
|
||||||
end = buffer.get_end_iter()
|
end = buffer.get_end_iter()
|
||||||
self.tags.append((LinkTag(person_handle, buffer),person_handle))
|
self.tags.append((LinkTag(person_handle, buffer), person_handle))
|
||||||
buffer.apply_tag(self.tags[-1][0], start, end)
|
buffer.apply_tag(self.tags[-1][0], start, end)
|
||||||
|
|
||||||
def results_write(self, text):
|
def results_write(self, text):
|
||||||
@ -366,7 +388,7 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
label.set_use_markup(True)
|
label.set_use_markup(True)
|
||||||
self.window.vbox.pack_start(label, True, True, self.border_pad)
|
self.window.vbox.pack_start(label, True, True, self.border_pad)
|
||||||
|
|
||||||
def add_frame_option(self,frame_name,label_text,widget,tooltip=None):
|
def add_frame_option(self, frame_name, label_text, widget, tooltip=None):
|
||||||
"""Similar to add_option this method takes a frame_name, a
|
"""Similar to add_option this method takes a frame_name, a
|
||||||
text string and a Gtk Widget. When the interface is built,
|
text string and a Gtk Widget. When the interface is built,
|
||||||
all widgets with the same frame_name are grouped into a
|
all widgets with the same frame_name are grouped into a
|
||||||
@ -377,12 +399,12 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
the add_user_options task."""
|
the add_user_options task."""
|
||||||
|
|
||||||
if self.frames.has_key(frame_name):
|
if self.frames.has_key(frame_name):
|
||||||
self.frames[frame_name].append((label_text,widget))
|
self.frames[frame_name].append((label_text, widget))
|
||||||
else:
|
else:
|
||||||
self.frames[frame_name] = [(label_text,widget)]
|
self.frames[frame_name] = [(label_text, widget)]
|
||||||
self.frame_names.append(frame_name)
|
self.frame_names.append(frame_name)
|
||||||
if tooltip:
|
if tooltip:
|
||||||
self.add_tooltip(widget,tooltip)
|
self.add_tooltip(widget, tooltip)
|
||||||
|
|
||||||
def set_current_frame(self, name):
|
def set_current_frame(self, name):
|
||||||
if name == None:
|
if name == None:
|
||||||
@ -396,7 +418,7 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
self.notebook.set_current_page(page)
|
self.notebook.set_current_page(page)
|
||||||
return
|
return
|
||||||
|
|
||||||
def add_results_frame(self,frame_name="Results"):
|
def add_results_frame(self, frame_name="Results"):
|
||||||
if frame_name not in self.frames:
|
if frame_name not in self.frames:
|
||||||
window = gtk.ScrolledWindow()
|
window = gtk.ScrolledWindow()
|
||||||
window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||||
@ -423,18 +445,18 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
|
|||||||
the add_user_options task."""
|
the add_user_options task."""
|
||||||
for key in self.frame_names:
|
for key in self.frame_names:
|
||||||
flist = self.frames[key]
|
flist = self.frames[key]
|
||||||
table = gtk.Table(3,len(flist))
|
table = gtk.Table(3, len(flist))
|
||||||
table.set_col_spacings(12)
|
table.set_col_spacings(12)
|
||||||
table.set_row_spacings(6)
|
table.set_row_spacings(6)
|
||||||
table.set_border_width(6)
|
table.set_border_width(6)
|
||||||
l = gtk.Label("<b>%s</b>" % key)
|
l = gtk.Label("<b>%s</b>" % key)
|
||||||
l.set_use_markup(True)
|
l.set_use_markup(True)
|
||||||
self.notebook.append_page(table,l)
|
self.notebook.append_page(table, l)
|
||||||
row = 0
|
row = 0
|
||||||
for (text,widget) in flist:
|
for (text, widget) in flist:
|
||||||
if text:
|
if text:
|
||||||
text_widget = gtk.Label('%s:' % text)
|
text_widget = gtk.Label('%s:' % text)
|
||||||
text_widget.set_alignment(0.0,0.5)
|
text_widget.set_alignment(0.0, 0.5)
|
||||||
table.attach(text_widget, 1, 2, row, row+1,
|
table.attach(text_widget, 1, 2, row, row+1,
|
||||||
gtk.SHRINK|gtk.FILL, gtk.SHRINK)
|
gtk.SHRINK|gtk.FILL, gtk.SHRINK)
|
||||||
table.attach(widget, 2, 3, row, row+1,
|
table.attach(widget, 2, 3, row, row+1,
|
||||||
@ -467,7 +489,7 @@ class ToolManagedWindowBatch(Tool.BatchTool, ToolManagedWindowBase):
|
|||||||
# This constructor will ask a question, set self.fail:
|
# This constructor will ask a question, set self.fail:
|
||||||
self.dbstate = dbstate
|
self.dbstate = dbstate
|
||||||
self.uistate = uistate
|
self.uistate = uistate
|
||||||
Tool.BatchTool.__init__(self,dbstate, options_class, name)
|
Tool.BatchTool.__init__(self, dbstate, options_class, name)
|
||||||
if not self.fail:
|
if not self.fail:
|
||||||
ToolManagedWindowBase.__init__(self, dbstate, uistate,
|
ToolManagedWindowBase.__init__(self, dbstate, uistate,
|
||||||
options_class, name, callback)
|
options_class, name, callback)
|
||||||
@ -476,6 +498,6 @@ class ToolManagedWindow(Tool.Tool, ToolManagedWindowBase):
|
|||||||
def __init__(self, dbstate, uistate, options_class, name, callback=None):
|
def __init__(self, dbstate, uistate, options_class, name, callback=None):
|
||||||
self.dbstate = dbstate
|
self.dbstate = dbstate
|
||||||
self.uistate = uistate
|
self.uistate = uistate
|
||||||
Tool.Tool.__init__(self,dbstate, options_class, name)
|
Tool.Tool.__init__(self, dbstate, options_class, name)
|
||||||
ToolManagedWindowBase.__init__(self, dbstate, uistate, options_class,
|
ToolManagedWindowBase.__init__(self, dbstate, uistate, options_class,
|
||||||
name, callback)
|
name, callback)
|
||||||
|
@ -41,9 +41,6 @@ from gtk import glade
|
|||||||
# Standard Python modules
|
# Standard Python modules
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
@ -52,12 +49,9 @@ from gettext import gettext as _
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
import const
|
import const
|
||||||
import Config
|
|
||||||
import Errors
|
|
||||||
from ReportBase import report, standalone_categories
|
from ReportBase import report, standalone_categories
|
||||||
import _Tool
|
import _Tool
|
||||||
import _PluginMgr
|
import _PluginMgr
|
||||||
import _PluginWindows
|
|
||||||
import ManagedWindow
|
import ManagedWindow
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
@ -74,13 +68,12 @@ UNSUPPORTED = _("Unsupported")
|
|||||||
# PluginDialog interface class
|
# PluginDialog interface class
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
class PluginDialog(ManagedWindow.ManagedWindow):
|
class PluginDialog(ManagedWindow.ManagedWindow):
|
||||||
"""Displays the dialog box that allows the user to select the
|
"""Displays the dialog box that allows the user to select the
|
||||||
report that is desired."""
|
report that is desired."""
|
||||||
|
|
||||||
def __init__(self,state, uistate, track, item_list,categories,msg,
|
def __init__(self, state, uistate, track, item_list, categories, msg,
|
||||||
label=None,button_label=None,tool_tip=None,content=REPORTS):
|
label=None, button_label=None, tool_tip=None, content=REPORTS):
|
||||||
"""Display the dialog box, and build up the list of available
|
"""Display the dialog box, and build up the list of available
|
||||||
reports. This is used to build the selection tree on the left
|
reports. This is used to build the selection tree on the left
|
||||||
hand side of the dailog box."""
|
hand side of the dailog box."""
|
||||||
@ -90,12 +83,12 @@ class PluginDialog(ManagedWindow.ManagedWindow):
|
|||||||
self.msg = msg
|
self.msg = msg
|
||||||
self.content = content
|
self.content = content
|
||||||
|
|
||||||
ManagedWindow.ManagedWindow.__init__(self,uistate,[],self.__class__)
|
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__)
|
||||||
|
|
||||||
self.state = state
|
self.state = state
|
||||||
self.uistate = uistate
|
self.uistate = uistate
|
||||||
|
|
||||||
self.dialog = glade.XML(const.PLUGINS_GLADE,"report","gramps")
|
self.dialog = glade.XML(const.PLUGINS_GLADE, "report", "gramps")
|
||||||
self.dialog.signal_autoconnect({
|
self.dialog.signal_autoconnect({
|
||||||
"on_report_apply_clicked" : self.on_apply_clicked,
|
"on_report_apply_clicked" : self.on_apply_clicked,
|
||||||
"destroy_passed_object" : self.close,
|
"destroy_passed_object" : self.close,
|
||||||
@ -110,7 +103,7 @@ class PluginDialog(ManagedWindow.ManagedWindow):
|
|||||||
self.store = gtk.TreeStore(str)
|
self.store = gtk.TreeStore(str)
|
||||||
self.selection = self.tree.get_selection()
|
self.selection = self.tree.get_selection()
|
||||||
self.selection.connect('changed', self.on_node_selected)
|
self.selection.connect('changed', self.on_node_selected)
|
||||||
col = gtk.TreeViewColumn('',gtk.CellRendererText(),text=0)
|
col = gtk.TreeViewColumn('', gtk.CellRendererText(), text=0)
|
||||||
self.tree.append_column(col)
|
self.tree.append_column(col)
|
||||||
self.tree.set_model(self.store)
|
self.tree.set_model(self.store)
|
||||||
|
|
||||||
@ -130,34 +123,35 @@ class PluginDialog(ManagedWindow.ManagedWindow):
|
|||||||
self.apply_button.set_use_underline(True)
|
self.apply_button.set_use_underline(True)
|
||||||
if tool_tip:
|
if tool_tip:
|
||||||
try:
|
try:
|
||||||
tt = gtk.tooltips_data_get(self.apply_button)
|
tttips = gtk.tooltips_data_get(self.apply_button)
|
||||||
if tt:
|
if tttips:
|
||||||
tt[0].set_tip(self.apply_button,tool_tip)
|
tttips[0].set_tip(self.apply_button, tool_tip)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.item = None
|
self.item = None
|
||||||
self.build_plugin_tree(item_list,categories)
|
self.build_plugin_tree(item_list, categories)
|
||||||
uistate.connect('plugins-reloaded',self.rebuild)
|
uistate.connect('plugins-reloaded', self.rebuild)
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
def rebuild(self,tool_list,report_list):
|
def rebuild(self, tool_list, report_list):
|
||||||
# This method needs to be overridden in the subclass
|
# This method needs to be overridden in the subclass
|
||||||
assert False, "This method needs to be overridden in the subclass."
|
assert False, "This method needs to be overridden in the subclass."
|
||||||
|
|
||||||
def build_menu_names(self, obj):
|
def build_menu_names(self, obj):
|
||||||
return (self.msg,None)
|
return (self.msg, None)
|
||||||
|
|
||||||
def on_apply_clicked(self, obj):
|
def on_apply_clicked(self, obj):
|
||||||
"""Execute the selected report"""
|
"""Execute the selected report"""
|
||||||
try:
|
try:
|
||||||
(item_class, options_class,title,category,
|
(item_class, options_class, title, category,
|
||||||
name,require_active) = self.item
|
name, require_active) = self.item
|
||||||
if self.content == REPORTS:
|
if self.content == REPORTS:
|
||||||
report(self.state,self.uistate,self.state.active,
|
report(self.state, self.uistate, self.state.active,
|
||||||
item_class, options_class,title, name,category,require_active)
|
item_class, options_class, title, name,
|
||||||
|
category, require_active)
|
||||||
else:
|
else:
|
||||||
_Tool.gui_tool(self.state,self.uistate,
|
_Tool.gui_tool(self.state, self.uistate,
|
||||||
item_class, options_class,title, name,category,
|
item_class, options_class,title, name,category,
|
||||||
self.state.db.request_rebuild)
|
self.state.db.request_rebuild)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
@ -174,7 +168,7 @@ class PluginDialog(ManagedWindow.ManagedWindow):
|
|||||||
return
|
return
|
||||||
data = self.imap[path]
|
data = self.imap[path]
|
||||||
|
|
||||||
(report_class, options_class,title,category, name,
|
(report_class, options_class, title, category, name,
|
||||||
doc,status,author,email,unsupported,require_active) = data
|
doc,status,author,email,unsupported,require_active) = data
|
||||||
self.description.set_text(doc)
|
self.description.set_text(doc)
|
||||||
if unsupported:
|
if unsupported:
|
||||||
@ -185,10 +179,10 @@ class PluginDialog(ManagedWindow.ManagedWindow):
|
|||||||
self.title.set_use_markup(1)
|
self.title.set_use_markup(1)
|
||||||
self.author_name.set_text(author)
|
self.author_name.set_text(author)
|
||||||
self.author_email.set_text(email)
|
self.author_email.set_text(email)
|
||||||
self.item = (report_class, options_class,title,category,
|
self.item = (report_class, options_class, title, category,
|
||||||
name,require_active)
|
name, require_active)
|
||||||
|
|
||||||
def build_plugin_tree(self,item_list,categories):
|
def build_plugin_tree(self, item_list, categories):
|
||||||
"""Populates a GtkTree with each menu item assocated with a entry
|
"""Populates a GtkTree with each menu item assocated with a entry
|
||||||
in the lists. The list must consist of a tuples with the following
|
in the lists. The list must consist of a tuples with the following
|
||||||
format:
|
format:
|
||||||
@ -225,25 +219,25 @@ class PluginDialog(ManagedWindow.ManagedWindow):
|
|||||||
if item_hash.has_key(UNSUPPORTED):
|
if item_hash.has_key(UNSUPPORTED):
|
||||||
key = UNSUPPORTED
|
key = UNSUPPORTED
|
||||||
data = item_hash[key]
|
data = item_hash[key]
|
||||||
node = self.store.insert_after(None,prev)
|
node = self.store.insert_after(None, prev)
|
||||||
self.store.set(node,0,key)
|
self.store.set(node, 0, key)
|
||||||
next = None
|
next = None
|
||||||
data.sort(lambda x,y: cmp(x[2],y[2]))
|
data.sort(lambda x, y: cmp(x[2], y[2]))
|
||||||
for item in data:
|
for item in data:
|
||||||
next = self.store.insert_after(node, next)
|
next = self.store.insert_after(node, next)
|
||||||
ilist.append((next,item))
|
ilist.append((next, item))
|
||||||
self.store.set(next,0,item[2])
|
self.store.set(next, 0, item[2])
|
||||||
for key in key_list:
|
for key in key_list:
|
||||||
data = item_hash[key]
|
data = item_hash[key]
|
||||||
node = self.store.insert_after(None,prev)
|
node = self.store.insert_after(None, prev)
|
||||||
self.store.set(node,0,key)
|
self.store.set(node, 0, key)
|
||||||
next = None
|
next = None
|
||||||
data.sort(lambda x,y: cmp(x[2],y[2]))
|
data.sort(lambda x, y: cmp(x[2], y[2]))
|
||||||
for item in data:
|
for item in data:
|
||||||
next = self.store.insert_after(node, next)
|
next = self.store.insert_after(node, next)
|
||||||
ilist.append((next,item))
|
ilist.append((next, item))
|
||||||
self.store.set(next,0,item[2])
|
self.store.set(next, 0, item[2])
|
||||||
for next,tab in ilist:
|
for next, tab in ilist:
|
||||||
path = self.store.get_path(next)
|
path = self.store.get_path(next)
|
||||||
self.imap[path] = tab
|
self.imap[path] = tab
|
||||||
|
|
||||||
@ -256,7 +250,7 @@ class ReportPlugins(PluginDialog):
|
|||||||
"""Displays the dialog box that allows the user to select the
|
"""Displays the dialog box that allows the user to select the
|
||||||
report that is desired."""
|
report that is desired."""
|
||||||
|
|
||||||
def __init__(self,dbstate,uistate,track):
|
def __init__(self, dbstate, uistate, track):
|
||||||
"""Display the dialog box, and build up the list of available
|
"""Display the dialog box, and build up the list of available
|
||||||
reports. This is used to build the selection tree on the left
|
reports. This is used to build the selection tree on the left
|
||||||
hand side of the dailog box."""
|
hand side of the dailog box."""
|
||||||
@ -273,8 +267,8 @@ class ReportPlugins(PluginDialog):
|
|||||||
_("_Generate"), _("Generate selected report"),
|
_("_Generate"), _("Generate selected report"),
|
||||||
REPORTS)
|
REPORTS)
|
||||||
|
|
||||||
def rebuild(self,tool_list,report_list):
|
def rebuild(self, tool_list, report_list):
|
||||||
self.build_plugin_tree(report_list,standalone_categories)
|
self.build_plugin_tree(report_list, standalone_categories)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -288,7 +282,7 @@ class ToolPlugins(PluginDialog):
|
|||||||
__signals__ = {
|
__signals__ = {
|
||||||
'plugins-reloaded' : (list,list),
|
'plugins-reloaded' : (list,list),
|
||||||
}
|
}
|
||||||
def __init__(self,dbstate,uistate,track):
|
def __init__(self, dbstate, uistate, track):
|
||||||
"""Display the dialog box, and build up the list of available
|
"""Display the dialog box, and build up the list of available
|
||||||
reports. This is used to build the selection tree on the left
|
reports. This is used to build the selection tree on the left
|
||||||
hand side of the dailog box."""
|
hand side of the dailog box."""
|
||||||
@ -306,117 +300,5 @@ class ToolPlugins(PluginDialog):
|
|||||||
_("Run selected tool"),
|
_("Run selected tool"),
|
||||||
TOOLS)
|
TOOLS)
|
||||||
|
|
||||||
def rebuild(self,tool_list,report_list):
|
def rebuild(self, tool_list, report_list):
|
||||||
self.build_plugin_tree(tool_list,_Tool.tool_categories)
|
self.build_plugin_tree(tool_list, _Tool.tool_categories)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Reload plugins
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
class Reload(_Tool.Tool):
|
|
||||||
def __init__(self, dbstate, uistate, options_class, name, callback=None):
|
|
||||||
"""
|
|
||||||
Treated as a callback, causes all plugins to get reloaded.
|
|
||||||
This is useful when writing and debugging a plugin.
|
|
||||||
"""
|
|
||||||
_Tool.Tool.__init__(self,dbstate, options_class, name)
|
|
||||||
|
|
||||||
pymod = re.compile(r"^(.*)\.py$")
|
|
||||||
|
|
||||||
oldfailmsg = _PluginMgr.failmsg_list[:]
|
|
||||||
_PluginMgr.failmsg_list = []
|
|
||||||
|
|
||||||
# attempt to reload all plugins that have succeeded in the past
|
|
||||||
for plugin in _PluginMgr.success_list:
|
|
||||||
filename = plugin[0]
|
|
||||||
filename = filename.replace('pyc','py')
|
|
||||||
filename = filename.replace('pyo','py')
|
|
||||||
try:
|
|
||||||
reload(plugin[1])
|
|
||||||
except:
|
|
||||||
_PluginMgr.failmsg_list.append((filename,sys.exc_info()))
|
|
||||||
|
|
||||||
# Remove previously good plugins that are now bad
|
|
||||||
# from the registered lists
|
|
||||||
_PluginMgr.purge_failed()
|
|
||||||
|
|
||||||
# attempt to load the plugins that have failed in the past
|
|
||||||
for (filename,message) in oldfailmsg:
|
|
||||||
name = os.path.split(filename)
|
|
||||||
match = pymod.match(name[1])
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
_PluginMgr.attempt_list.append(filename)
|
|
||||||
plugin = match.groups()[0]
|
|
||||||
try:
|
|
||||||
# For some strange reason second importing of a failed plugin
|
|
||||||
# results in success. Then reload reveals the actual error.
|
|
||||||
# Looks like a bug in Python.
|
|
||||||
a = __import__(plugin)
|
|
||||||
reload(a)
|
|
||||||
_PluginMgr.success_list.append((filename,a))
|
|
||||||
except:
|
|
||||||
_PluginMgr.failmsg_list.append((filename,sys.exc_info()))
|
|
||||||
|
|
||||||
# attempt to load any new files found
|
|
||||||
for directory in _PluginMgr.loaddir_list:
|
|
||||||
for filename in os.listdir(directory):
|
|
||||||
name = os.path.split(filename)
|
|
||||||
match = pymod.match(name[1])
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
if filename in _PluginMgr.attempt_list:
|
|
||||||
continue
|
|
||||||
_PluginMgr.attempt_list.append(filename)
|
|
||||||
plugin = match.groups()[0]
|
|
||||||
try:
|
|
||||||
a = __import__(plugin)
|
|
||||||
if a not in [plugin[1]
|
|
||||||
for plugin in _PluginMgr.success_list]:
|
|
||||||
_PluginMgr.success_list.append((filename,a))
|
|
||||||
except:
|
|
||||||
_PluginMgr.failmsg_list.append((filename,sys.exc_info()))
|
|
||||||
|
|
||||||
if Config.get(Config.POP_PLUGIN_STATUS) \
|
|
||||||
and len(_PluginMgr.failmsg_list):
|
|
||||||
try:
|
|
||||||
_PluginWindows.PluginStatus(dbstate,uistate)
|
|
||||||
except Errors.WindowActiveError:
|
|
||||||
old_win = uistate.gwm.get_item_from_id(
|
|
||||||
_PluginWindows.PluginStatus)
|
|
||||||
old_win.close()
|
|
||||||
_PluginWindows.PluginStatus(dbstate,uistate)
|
|
||||||
|
|
||||||
# Emit signal to re-generate tool and report menus
|
|
||||||
uistate.emit('plugins-reloaded',
|
|
||||||
(_PluginMgr.tool_list,_PluginMgr.report_list))
|
|
||||||
|
|
||||||
class ReloadOptions(_Tool.ToolOptions):
|
|
||||||
"""
|
|
||||||
Defines options and provides handling interface.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, name,person_id=None):
|
|
||||||
_Tool.ToolOptions.__init__(self, name,person_id)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Register the plugin reloading tool
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
_PluginMgr.register_tool(
|
|
||||||
name = 'reload',
|
|
||||||
category = _Tool.TOOL_DEBUG,
|
|
||||||
tool_class = Reload,
|
|
||||||
options_class = ReloadOptions,
|
|
||||||
modes = _Tool.MODE_GUI,
|
|
||||||
translated_name = _("Reload Plugins"),
|
|
||||||
status=(_("Stable")),
|
|
||||||
author_name = "Donald N. Allingham",
|
|
||||||
author_email = "don@gramps-project.org",
|
|
||||||
description=_("Attempt to reload plugins. "
|
|
||||||
"Note: This tool itself is not reloaded!"),
|
|
||||||
)
|
|
||||||
|
@ -402,7 +402,7 @@ class ViewManager:
|
|||||||
('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 Status'), 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),
|
||||||
('UserManual', gtk.STOCK_HELP, _('_User Manual'), 'F1', None,
|
('UserManual', gtk.STOCK_HELP, _('_User Manual'), 'F1', None,
|
||||||
@ -607,14 +607,8 @@ class ViewManager:
|
|||||||
error |= load_plugins(const.USER_PLUGINS)
|
error |= load_plugins(const.USER_PLUGINS)
|
||||||
|
|
||||||
# get to ssee if we need to open the plugin status window
|
# get to ssee if we need to open the plugin status window
|
||||||
if Config.get(Config.POP_PLUGIN_STATUS) and error:
|
if error and Config.get(Config.POP_PLUGIN_STATUS):
|
||||||
try:
|
self.__plugin_status()
|
||||||
PluginWindows.PluginStatus(self.state, self.uistate, [])
|
|
||||||
except Errors.WindowActiveError:
|
|
||||||
old_win = self.uistate.gwm.get_item_from_id(
|
|
||||||
PluginWindows.PluginStatus)
|
|
||||||
old_win.close()
|
|
||||||
PluginWindows.PluginStatus(self.state, self.uistate, [])
|
|
||||||
|
|
||||||
self.uistate.push_message(self.state, _('Ready'))
|
self.uistate.push_message(self.state, _('Ready'))
|
||||||
|
|
||||||
@ -734,17 +728,17 @@ class ViewManager:
|
|||||||
import TipOfDay
|
import TipOfDay
|
||||||
TipOfDay.TipOfDay(self.uistate)
|
TipOfDay.TipOfDay(self.uistate)
|
||||||
|
|
||||||
def plugin_status(self, obj):
|
def __plugin_status(self, obj=None):
|
||||||
"""
|
"""
|
||||||
Display plugin status dialog
|
Display plugin status dialog
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
PluginWindows.PluginStatus(self.state, self.uistate, [])
|
PluginWindows.PluginStatus(self.uistate, [])
|
||||||
except Errors.WindowActiveError:
|
except Errors.WindowActiveError:
|
||||||
old_win = self.uistate.gwm.get_item_from_id(
|
old_win = self.uistate.gwm.get_item_from_id(
|
||||||
PluginWindows.PluginStatus)
|
PluginWindows.PluginStatus)
|
||||||
old_win.close()
|
old_win.close()
|
||||||
PluginWindows.PluginStatus(self.state, self.uistate, [])
|
PluginWindows.PluginStatus(self.uistate, [])
|
||||||
|
|
||||||
def sidebar_toggle(self, obj):
|
def sidebar_toggle(self, obj):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user