Bug 2616. Fixes for memory leaks in event editor
svn: r12116
This commit is contained in:
parent
99376d8691
commit
2334b8058d
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -64,6 +65,7 @@ class BackRefList(EmbeddedList):
|
||||
_('_References'), refmodel)
|
||||
self._callback = callback
|
||||
self.model.connect('row-inserted', self.update_label)
|
||||
self.track_ref_for_deletion("model")
|
||||
|
||||
def update_label(self, *obj):
|
||||
if self.model.count > 0:
|
||||
@ -99,6 +101,11 @@ class BackRefList(EmbeddedList):
|
||||
self.add_btn = None
|
||||
self.del_btn = None
|
||||
|
||||
self.track_ref_for_deletion("edit_btn")
|
||||
self.track_ref_for_deletion("tooltips")
|
||||
self.track_ref_for_deletion("add_btn")
|
||||
self.track_ref_for_deletion("del_btn")
|
||||
|
||||
def _selection_changed(self, obj=None):
|
||||
if self.dirty_selection:
|
||||
return
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -99,6 +100,7 @@ class ButtonTab(GrampsTab):
|
||||
self.dirty_selection = False
|
||||
GrampsTab.__init__(self,dbstate, uistate, track, name)
|
||||
self.tooltips = gtk.Tooltips()
|
||||
self.track_ref_for_deletion("tooltips")
|
||||
self.create_buttons(share_button, move_buttons, jump_button)
|
||||
|
||||
def create_buttons(self, share_button, move_buttons, jump_button):
|
||||
@ -112,6 +114,9 @@ class ButtonTab(GrampsTab):
|
||||
self.add_btn = SimpleButton(gtk.STOCK_ADD, self.add_button_clicked)
|
||||
self.edit_btn = SimpleButton(gtk.STOCK_EDIT, self.edit_button_clicked)
|
||||
self.del_btn = SimpleButton(gtk.STOCK_REMOVE, self.del_button_clicked)
|
||||
self.track_ref_for_deletion("add_btn")
|
||||
self.track_ref_for_deletion("edit_btn")
|
||||
self.track_ref_for_deletion("del_btn")
|
||||
|
||||
self.tooltips.set_tip(self.add_btn, self._MSG['add'])
|
||||
self.tooltips.set_tip(self.edit_btn, self._MSG['edit'])
|
||||
@ -120,6 +125,7 @@ class ButtonTab(GrampsTab):
|
||||
if share_button:
|
||||
self.share_btn = SimpleButton(gtk.STOCK_INDEX, self.share_button_clicked)
|
||||
self.tooltips.set_tip(self.share_btn, self._MSG['share'])
|
||||
self.track_ref_for_deletion("share_btn")
|
||||
else:
|
||||
self.share_btn = None
|
||||
|
||||
@ -129,6 +135,8 @@ class ButtonTab(GrampsTab):
|
||||
self.down_btn = SimpleButton(gtk.STOCK_GO_DOWN,
|
||||
self.down_button_clicked)
|
||||
self.tooltips.set_tip(self.down_btn, self._MSG['down'])
|
||||
self.track_ref_for_deletion("up_btn")
|
||||
self.track_ref_for_deletion("down_btn")
|
||||
else:
|
||||
self.up_btn = None
|
||||
self.down_btn = None
|
||||
@ -146,6 +154,7 @@ class ButtonTab(GrampsTab):
|
||||
|
||||
if jump_button:
|
||||
self.jump_btn = SimpleButton(gtk.STOCK_JUMP_TO, self.jump_button_clicked)
|
||||
self.track_ref_for_deletion("jump_btn")
|
||||
self.tooltips.set_tip(self.jump_btn, self._MSG['jump'])
|
||||
else:
|
||||
self.jump_btn = None
|
||||
|
@ -73,6 +73,7 @@ class EmbeddedList(ButtonTab):
|
||||
# handle the selection
|
||||
self.selection = self.tree.get_selection()
|
||||
self.selection.connect('changed', self._selection_changed)
|
||||
self.track_ref_for_deletion("selection")
|
||||
|
||||
# build the columns
|
||||
self.columns = []
|
||||
@ -341,6 +342,7 @@ class EmbeddedList(ButtonTab):
|
||||
self.tree.set_rules_hint(True)
|
||||
self.tree.connect('button_press_event', self.double_click)
|
||||
self.tree.connect('key_press_event', self.key_pressed)
|
||||
self.track_ref_for_deletion("tree")
|
||||
|
||||
# create the scrolled window, and attach the treeview
|
||||
scroll = gtk.ScrolledWindow()
|
||||
@ -428,6 +430,7 @@ class EmbeddedList(ButtonTab):
|
||||
column.set_sort_column_id(self._column_names[pair[1]][1])
|
||||
self.columns.append(column)
|
||||
self.tree.append_column(column)
|
||||
self.track_ref_for_deletion("columns")
|
||||
|
||||
def rebuild(self):
|
||||
"""
|
||||
@ -450,4 +453,3 @@ class EmbeddedList(ButtonTab):
|
||||
#model and tree are reset, allow _selection_changed again, and force it
|
||||
self.dirty_selection = False
|
||||
self._selection_changed()
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -72,8 +73,8 @@ class GalleryTab(ButtonTab):
|
||||
|
||||
def __init__(self, dbstate, uistate, track, media_list, update=None):
|
||||
self.iconlist = gtk.IconView()
|
||||
|
||||
ButtonTab.__init__(self, dbstate, uistate, track, _('_Gallery'), True)
|
||||
self.track_ref_for_deletion("iconlist")
|
||||
self.media_list = media_list
|
||||
self.update = update
|
||||
|
||||
@ -146,6 +147,7 @@ class GalleryTab(ButtonTab):
|
||||
def _build_icon_model(self):
|
||||
self.iconmodel = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING,
|
||||
object)
|
||||
self.track_ref_for_deletion("iconmodel")
|
||||
|
||||
def _connect_icon_model(self):
|
||||
self.iconlist.set_model(self.iconmodel)
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -70,6 +71,7 @@ class GrampsTab(gtk.VBox):
|
||||
self.uistate = uistate
|
||||
self.track = track
|
||||
self.changed = False
|
||||
self.__refs_for_deletion = []
|
||||
|
||||
self._add_db_signal = None
|
||||
|
||||
@ -77,7 +79,9 @@ class GrampsTab(gtk.VBox):
|
||||
# for the label
|
||||
|
||||
self.tab_name = name
|
||||
self.track_ref_for_deletion("tab_name")
|
||||
self.label_container = self.build_label_widget()
|
||||
self.track_ref_for_deletion("label_container")
|
||||
|
||||
# build the interface
|
||||
self.share_btn = None
|
||||
@ -116,7 +120,9 @@ class GrampsTab(gtk.VBox):
|
||||
name = icon
|
||||
|
||||
self.tab_image = func(name, gtk.ICON_SIZE_MENU)
|
||||
self.track_ref_for_deletion("tab_image")
|
||||
self.label = gtk.Label(self.tab_name)
|
||||
self.track_ref_for_deletion("label")
|
||||
hbox.pack_start(self.tab_image)
|
||||
hbox.set_spacing(6)
|
||||
hbox.add(self.label)
|
||||
@ -213,6 +219,7 @@ class GrampsTab(gtk.VBox):
|
||||
|
||||
def set_parent_notebook(self, book):
|
||||
self.parent_notebook = book
|
||||
self.track_ref_for_deletion("parent_notebook")
|
||||
|
||||
def next_page(self):
|
||||
if self.parent_notebook:
|
||||
@ -222,3 +229,19 @@ class GrampsTab(gtk.VBox):
|
||||
if self.parent_notebook:
|
||||
self.parent_notebook.prev_page()
|
||||
|
||||
def track_ref_for_deletion(self, ref):
|
||||
"""
|
||||
Record references of instance variables that need to be removed
|
||||
from scope so that the class can be garbage collected
|
||||
"""
|
||||
if ref not in self.__refs_for_deletion:
|
||||
self.__refs_for_deletion.append(ref)
|
||||
|
||||
def clean_up(self):
|
||||
"""
|
||||
Remove any instance variables from scope which point to non-glade
|
||||
GTK objects so that the class can be garbage collected.
|
||||
"""
|
||||
while len(self.__refs_for_deletion):
|
||||
attr = self.__refs_for_deletion.pop()
|
||||
delattr(self, attr)
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# 2009 Gary Burton
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -154,38 +154,53 @@ class EditEvent(EditPrimary):
|
||||
window.
|
||||
"""
|
||||
notebook = gtk.Notebook()
|
||||
|
||||
self.srcref_list = self._add_tab(
|
||||
notebook,
|
||||
SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj))
|
||||
|
||||
self.note_tab = self._add_tab(
|
||||
notebook,
|
||||
NoteTab(self.dbstate, self.uistate, self.track,
|
||||
self.obj.get_note_list(), notetype=gen.lib.NoteType.EVENT))
|
||||
|
||||
self.gallery_tab = self._add_tab(
|
||||
notebook,
|
||||
GalleryTab(self.dbstate, self.uistate, self.track,
|
||||
self.obj.get_media_list()))
|
||||
|
||||
self.attr_ref_list = self._add_tab(
|
||||
notebook,
|
||||
AttrEmbedList(self.dbstate, self.uistate, self.track,
|
||||
self.obj.get_attribute_list()))
|
||||
self.source_list = SourceEmbedList(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
self.obj)
|
||||
self._add_tab(notebook, self.source_list)
|
||||
|
||||
self.note_list = NoteTab(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
self.obj.get_note_list(),
|
||||
notetype=gen.lib.NoteType.EVENT)
|
||||
self._add_tab(notebook, self.note_list)
|
||||
|
||||
|
||||
self.backref_tab = self._add_tab(
|
||||
notebook,
|
||||
EventBackRefList(self.dbstate, self.uistate, self.track,
|
||||
self.dbstate.db.find_backlink_handles(self.obj.handle)))
|
||||
self.gallery_list = GalleryTab(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
self.obj.get_media_list())
|
||||
self._add_tab(notebook, self.gallery_list)
|
||||
|
||||
self._setup_notebook_tabs( notebook)
|
||||
self.attr_list = AttrEmbedList(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
self.obj.get_attribute_list())
|
||||
self._add_tab(notebook, self.attr_list)
|
||||
|
||||
handle_list = self.dbstate.db.find_backlink_handles(self.obj.handle)
|
||||
self.backref_list = EventBackRefList(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
handle_list)
|
||||
self._add_tab(notebook, self.backref_list)
|
||||
|
||||
self._setup_notebook_tabs(notebook)
|
||||
|
||||
notebook.show_all()
|
||||
self.top.get_widget('vbox').pack_start(notebook, True)
|
||||
|
||||
self.track_ref_for_deletion("source_list")
|
||||
self.track_ref_for_deletion("note_list")
|
||||
self.track_ref_for_deletion("gallery_list")
|
||||
self.track_ref_for_deletion("attr_list")
|
||||
self.track_ref_for_deletion("backref_list")
|
||||
|
||||
def _cleanup_on_exit(self):
|
||||
self.backref_tab.close()
|
||||
self.backref_list.close()
|
||||
|
||||
def build_menu_names(self, event):
|
||||
return (_('Edit Event'), self.get_menu_title())
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
# 2009 Gary Burton
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -334,6 +334,7 @@ class ManagedWindow:
|
||||
self.isWindow = None
|
||||
self.width_key = None
|
||||
self.height_key = None
|
||||
self.__refs_for_deletion = []
|
||||
|
||||
if uistate.gwm.get_item_from_id(window_key):
|
||||
uistate.gwm.get_item_from_id(window_key).present()
|
||||
@ -466,6 +467,7 @@ class ManagedWindow:
|
||||
|
||||
Takes care of closing children and removing itself from menu.
|
||||
"""
|
||||
self.clean_up()
|
||||
self._save_size()
|
||||
self.uistate.gwm.close_track(self.track)
|
||||
self.opened = False
|
||||
@ -500,6 +502,26 @@ class ManagedWindow:
|
||||
Config.set(self.width_key, width)
|
||||
Config.set(self.height_key, height)
|
||||
Config.sync()
|
||||
|
||||
def track_ref_for_deletion(self, ref):
|
||||
"""
|
||||
Record references of instance variables that need to be removed
|
||||
from scope so that the class can be garbage collected
|
||||
"""
|
||||
if ref not in self.__refs_for_deletion:
|
||||
self.__refs_for_deletion.append(ref)
|
||||
|
||||
def clean_up(self):
|
||||
"""
|
||||
Remove any instance variables from scope which point to non-glade
|
||||
GTK objects so that the class can be garbage collected.
|
||||
Run the clean_up method on the object first before removing it.
|
||||
"""
|
||||
while len(self.__refs_for_deletion):
|
||||
attr = self.__refs_for_deletion.pop()
|
||||
obj = getattr(self, attr)
|
||||
obj.clean_up()
|
||||
delattr(self, attr)
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Helper functions
|
||||
|
Loading…
Reference in New Issue
Block a user