Fix Glade file loading to avoid loading and leaving extra toplevels

Also deals with problems caused by fix; sometimes do need to load
some other toplevel objects.
In some cases, it was easier to remove unused toplevel objects from
glade files.
This commit is contained in:
prculley
2017-02-08 16:19:45 -06:00
parent 0c9953bb1a
commit 064ec90db0
12 changed files with 59 additions and 163 deletions

View File

@ -804,7 +804,7 @@ class EditFilter(ManagedWindow):
self.filterdb = filterdb self.filterdb = filterdb
self.selection_callback = selection_callback self.selection_callback = selection_callback
self.define_glade('define_filter', RULE_GLADE) self.define_glade('define_filter', RULE_GLADE, also_load=["model1"])
self.set_window( self.set_window(
self.get_widget('define_filter'), self.get_widget('define_filter'),

View File

@ -59,22 +59,37 @@ class Glade(Gtk.Builder):
""" """
__slots__ = ['__toplevel', '__filename', '__dirname'] __slots__ = ['__toplevel', '__filename', '__dirname']
def __init__(self, filename=None, dirname=None, toplevel=None): def __init__(self, filename=None, dirname=None, toplevel=None,
also_load=[]):
""" """
Class Constructor: Returns a new instance of the Glade class Class Constructor: Returns a new instance of the Glade class
:type filename: string :type filename: string or None
:param filename: The name of the glade file to be used. Defaults to None :param filename: The name of the glade file to be used. Defaults to None
:type dirname: string :type dirname: string or None
:param dirname: The directory to search for the glade file. Defaults to :param dirname: The directory to search for the glade file. Defaults to
None which will cause a search for the file in the default None which will cause a search for the file in the default
directory followed by the directory of the calling module. directory followed by the directory of the calling module.
:type toplevel: toplevel :type toplevel: string or None
:param toplevel: The toplevel object to search for in the glade file. :param toplevel: The toplevel object to search for in the glade file.
Defaults to None, which will cause a search for a toplevel Defaults to None, which will cause a search for a toplevel
matching the file name. matching the supplied name.
:type also_load: list of strings
:param also_load: Additional toplevel objects to load from the glade
file. These are typically liststore or other objects
needed to operate the toplevel object.
Defaults to [] (empty list), which will not load
additional objects.
:rtype: object reference :rtype: object reference
:returns: reference to the newly-created Glade instance :returns: reference to the newly-created Glade instance
This operates in two modes; when no toplevel parameter is supplied,
the entire Glade file is loaded. It is the responsibility of the user
to make sure ALL toplevel objects are destroyed.
When a toplevel parameter is supplied, only that object and any
additional objects requested in the also_load parameter are loaded.
The user only has to destroy the requested toplevel objects.
""" """
Gtk.Builder.__init__(self) Gtk.Builder.__init__(self)
self.set_translation_domain(glocale.get_localedomain()) self.set_translation_domain(glocale.get_localedomain())
@ -120,14 +135,18 @@ class Glade(Gtk.Builder):
# try to build Gtk objects from glade file. Let exceptions happen # try to build Gtk objects from glade file. Let exceptions happen
self.add_from_file(path)
self.__dirname, self.__filename = os.path.split(path) self.__dirname, self.__filename = os.path.split(path)
# try to find the toplevel widget # try to find the toplevel widget
if toplevel: # toplevel is given # toplevel is given
if toplevel:
loadlist = [toplevel] + also_load
self.add_objects_from_file(path, loadlist)
self.__toplevel = self.get_object(toplevel) self.__toplevel = self.get_object(toplevel)
else: # toplevel not given # toplevel not given
else:
self.add_from_file(path)
# first, use filename as possible toplevel widget name # first, use filename as possible toplevel widget name
self.__toplevel = self.get_object(filename.rpartition('.')[0]) self.__toplevel = self.get_object(filename.rpartition('.')[0])

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 --> <!-- Generated with glade 3.18.3 -->
<interface> <interface>
<requires lib="gtk+" version="3.10"/> <requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="top"> <object class="GtkWindow" id="top">
@ -507,6 +507,7 @@
<property name="height_request">300</property> <property name="height_request">300</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="type_hint">normal</property> <property name="type_hint">normal</property>
<signal name="delete-event" handler="on_booklist_cancel_clicked" object="dialog-vbox1" swapped="yes"/>
<child internal-child="vbox"> <child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1"> <object class="GtkBox" id="dialog-vbox1">
<property name="visible">True</property> <property name="visible">True</property>
@ -525,7 +526,7 @@
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<signal name="clicked" handler="on_booklist_delete_clicked" object="top" swapped="yes"/> <signal name="clicked" handler="on_booklist_delete_clicked" object="book" swapped="yes"/>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -541,7 +542,7 @@
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<signal name="clicked" handler="on_booklist_cancel_clicked" object="top" swapped="yes"/> <signal name="clicked" handler="on_booklist_cancel_clicked" object="book" swapped="yes"/>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -557,7 +558,7 @@
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<signal name="clicked" handler="on_booklist_ok_clicked" object="top" swapped="yes"/> <signal name="clicked" handler="on_booklist_ok_clicked" object="book" swapped="yes"/>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>

View File

@ -518,11 +518,11 @@ class ManagedWindow:
def build_window_key(self, obj): def build_window_key(self, obj):
return id(obj) return id(obj)
def define_glade(self, top_module, glade_file=None): def define_glade(self, top_module, glade_file=None, also_load=[]):
if glade_file is None: if glade_file is None:
raise TypeError("ManagedWindow.define_glade: no glade file") raise TypeError("ManagedWindow.define_glade: no glade file")
glade_file = GLADE_FILE glade_file = GLADE_FILE
self._gladeobj = Glade(glade_file, None, top_module) self._gladeobj = Glade(glade_file, None, top_module, also_load)
return self._gladeobj return self._gladeobj
def get_widget(self, name): def get_widget(self, name):

View File

@ -158,7 +158,7 @@ class BookListDisplay:
self.booklist = booklist self.booklist = booklist
self.dosave = dosave self.dosave = dosave
self.xml = Glade('book.glade') self.xml = Glade('book.glade', toplevel='book')
self.top = self.xml.toplevel self.top = self.xml.toplevel
self.unsaved_changes = False self.unsaved_changes = False
@ -233,7 +233,7 @@ class BookListDisplay:
self.unsaved_changes = True self.unsaved_changes = True
self.top.run() self.top.run()
def on_booklist_cancel_clicked(self, obj): def on_booklist_cancel_clicked(self, *obj):
""" cancel the booklist dialog """ """ cancel the booklist dialog """
if self.unsaved_changes: if self.unsaved_changes:
qqq = QuestionDialog2( qqq = QuestionDialog2(

View File

@ -216,7 +216,12 @@ class StyleEditor(ManagedWindow):
self.style = StyleSheet(style) self.style = StyleSheet(style)
self.parent = parent self.parent = parent
self.top = Glade(toplevel='editor') self.top = Glade(
toplevel='editor',
also_load=[
"adjustment1", "adjustment2", "adjustment3", "adjustment4",
"adjustment5", "adjustment6", "adjustment7", "adjustment8",
"adjustment9", "adjustment10", "adjustment11"])
self.set_window(self.top.toplevel, self.top.get_object('title'), self.set_window(self.top.toplevel, self.top.get_object('title'),
_('Style editor')) _('Style editor'))
self.setup_configs('interface.styleeditor', 550, 610) self.setup_configs('interface.styleeditor', 550, 610)

View File

@ -124,7 +124,7 @@ class EventComparison(tool.Tool,ManagedWindow):
ManagedWindow.__init__(self, uistate, [], self) ManagedWindow.__init__(self, uistate, [], self)
self.qual = 0 self.qual = 0
self.filterDialog = Glade(toplevel="filters") self.filterDialog = Glade(toplevel="filters", also_load=["liststore1"])
self.filterDialog.connect_signals({ self.filterDialog.connect_signals({
"on_apply_clicked" : self.on_apply_clicked, "on_apply_clicked" : self.on_apply_clicked,
"on_editor_clicked" : self.filter_editor_clicked, "on_editor_clicked" : self.filter_editor_clicked,
@ -230,7 +230,7 @@ class EventComparisonResults(ManagedWindow):
self.row_data = [] self.row_data = []
self.save_form = None self.save_form = None
self.topDialog = Glade() self.topDialog = Glade(toplevel="eventcmp")
self.topDialog.connect_signals({ self.topDialog.connect_signals({
"on_write_table" : self.on_write_table, "on_write_table" : self.on_write_table,
"destroy_passed_object" : self.close, "destroy_passed_object" : self.close,

View File

@ -146,10 +146,11 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="halign">center</property>
<property name="margin_left">12</property> <property name="margin_left">12</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="halign">center</property> <property name="xalign">0.5</property>
<property name="active">True</property> <property name="active">True</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
</object> </object>
@ -334,70 +335,4 @@
<action-widget response="-11">button13</action-widget> <action-widget response="-11">button13</action-widget>
</action-widgets> </action-widgets>
</object> </object>
<object class="GtkWindow" id="message">
<property name="can_focus">False</property>
<property name="modal">True</property>
<child>
<object class="GtkBox" id="vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="title">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="justify">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label44">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="label" translatable="yes">Please be patient. This may take a while.</property>
<property name="justify">center</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">20</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pulse_step">0.10000000149</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="padding">20</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface> </interface>

View File

@ -103,7 +103,7 @@ class DuplicatePeopleTool(tool.Tool, ManagedWindow):
self.update = callback self.update = callback
self.use_soundex = 1 self.use_soundex = 1
top = Glade() top = Glade(toplevel="finddupes", also_load=["liststore1"])
# retrieve options # retrieve options
threshold = self.options.handler.options_dict['threshold'] threshold = self.options.handler.options_dict['threshold']

View File

@ -146,10 +146,11 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="halign">center</property>
<property name="margin_left">12</property> <property name="margin_left">12</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="halign">center</property> <property name="xalign">0.5</property>
<property name="active">True</property> <property name="active">True</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
</object> </object>
@ -199,70 +200,4 @@
<action-widget response="-11">button14</action-widget> <action-widget response="-11">button14</action-widget>
</action-widgets> </action-widgets>
</object> </object>
<object class="GtkWindow" id="message">
<property name="can_focus">False</property>
<property name="modal">True</property>
<child>
<object class="GtkBox" id="vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="title">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="justify">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label44">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="label" translatable="yes">Please be patient. This may take a while.</property>
<property name="justify">center</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">20</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pulse_step">0.10000000149</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="padding">20</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface> </interface>

View File

@ -106,7 +106,7 @@ class MergeCitations(tool.BatchTool,ManagedWindow):
def run(self): def run(self):
top = Glade(toplevel="mergecitations") top = Glade(toplevel="mergecitations", also_load=["liststore1"])
# retrieve options # retrieve options
fields = self.options.handler.options_dict['fields'] fields = self.options.handler.options_dict['fields']

View File

@ -364,7 +364,8 @@ class Verify(tool.Tool, ManagedWindow, UpdateCallback):
o_dict[option] = self.top.get_object(option).get_value_as_int() o_dict[option] = self.top.get_object(option).get_value_as_int()
try: try:
self.v_r = VerifyResults(self.dbstate, self.uistate, self.track) self.v_r = VerifyResults(self.dbstate, self.uistate, self.track,
self.top)
self.add_results = self.v_r.add_results self.add_results = self.v_r.add_results
self.v_r.load_ignored(self.db.full_name) self.v_r.load_ignored(self.db.full_name)
except WindowActiveError: except WindowActiveError:
@ -493,7 +494,7 @@ class VerifyResults(ManagedWindow):
TRUE_COL = 8 TRUE_COL = 8
SHOW_COL = 9 SHOW_COL = 9
def __init__(self, dbstate, uistate, track): def __init__(self, dbstate, uistate, track, glade):
""" initialize things """ """ initialize things """
self.title = _('Data Verification Results') self.title = _('Data Verification Results')
@ -501,8 +502,8 @@ class VerifyResults(ManagedWindow):
self.dbstate = dbstate self.dbstate = dbstate
self._set_filename() self._set_filename()
self.top = Glade(toplevel="verify_result") self.top = glade
window = self.top.toplevel window = self.top.get_object("verify_result")
self.set_window(window, self.top.get_object('title2'), self.title) self.set_window(window, self.top.get_object('title2'), self.title)
self.setup_configs('interface.verifyresults', 500, 300) self.setup_configs('interface.verifyresults', 500, 300)
@ -724,13 +725,13 @@ class VerifyResults(ManagedWindow):
if the_type == 'Person': if the_type == 'Person':
try: try:
person = self.dbstate.db.get_person_from_handle(handle) person = self.dbstate.db.get_person_from_handle(handle)
EditPerson(self.dbstate, self.uistate, [], person) EditPerson(self.dbstate, self.uistate, self.track, person)
except WindowActiveError: except WindowActiveError:
pass pass
elif the_type == 'Family': elif the_type == 'Family':
try: try:
family = self.dbstate.db.get_family_from_handle(handle) family = self.dbstate.db.get_family_from_handle(handle)
EditFamily(self.dbstate, self.uistate, [], family) EditFamily(self.dbstate, self.uistate, self.track, family)
except WindowActiveError: except WindowActiveError:
pass pass
@ -759,7 +760,7 @@ class VerifyResults(ManagedWindow):
def build_menu_names(self, obj): def build_menu_names(self, obj):
""" build the menu names """ """ build the menu names """
return (self.title, None) return (self.title, self.title)
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #