From 1fee4971f41ae1d9ade6c438ea613901319b6e45 Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Sun, 31 Oct 2010 07:33:17 +0000 Subject: [PATCH] 4333: memory leak in 3.2 svn: r16089 --- src/Lru.py | 3 + src/gen/db/read.py | 26 +++++- src/gen/db/undoredo.py | 4 + src/gen/db/write.py | 21 ++++- src/gen/utils/callback.py | 13 ++- src/gen/utils/configmanager.py | 16 ++-- src/gui/editors/displaytabs/nameembedlist.py | 10 +++ src/gui/editors/editfamily.py | 9 +++ src/gui/editors/editname.py | 16 ++-- src/gui/editors/editperson.py | 19 ++++- src/gui/editors/editprimary.py | 17 +++- src/gui/editors/editsecondary.py | 14 +++- src/gui/views/listview.py | 3 + src/gui/views/treemodels/eventmodel.py | 11 +++ src/gui/views/treemodels/familymodel.py | 11 +++ src/gui/views/treemodels/flatbasemodel.py | 20 +++++ src/gui/views/treemodels/mediamodel.py | 11 +++ src/gui/views/treemodels/notemodel.py | 11 +++ src/gui/views/treemodels/peoplemodel.py | 28 ++++++- src/gui/views/treemodels/placemodel.py | 26 ++++++ src/gui/views/treemodels/repomodel.py | 12 +++ src/gui/views/treemodels/sourcemodel.py | 11 +++ src/gui/views/treemodels/treebasemodel.py | 20 +++++ src/gui/widgets/buttons.py | 25 ++++++ src/gui/widgets/monitoredwidgets.py | 83 ++++++++++++++++++++ 25 files changed, 416 insertions(+), 24 deletions(-) diff --git a/src/Lru.py b/src/Lru.py index 4928cbc1f..c35dc3fed 100644 --- a/src/Lru.py +++ b/src/Lru.py @@ -151,4 +151,7 @@ class LRU(object): """ Empties LRU """ + for obj, node in self.data.iteritems(): + node.prev = None + node.next = None self.data.clear() diff --git a/src/gen/db/read.py b/src/gen/db/read.py index 7631aac1f..6bbdace68 100644 --- a/src/gen/db/read.py +++ b/src/gen/db/read.py @@ -129,6 +129,9 @@ class DbBookmarks(object): def insert(self, pos, item): self.bookmarks.insert(pos, item) + def close(self): + del self.bookmarks + #------------------------------------------------------------------------- # # GrampsDBReadCursor @@ -206,7 +209,6 @@ class DbBsddbRead(DbReadBase, Callback): """ Create a new DbBsddbRead instance. """ - DbReadBase.__init__(self) Callback.__init__(self) @@ -427,8 +429,26 @@ class DbBsddbRead(DbReadBase, Callback): The method needs to be overridden in the derived class. """ - pass - + #remove circular dependance + self.basedb = None + #remove links to functions + self.disconnect_all() + for key in self._tables: + for subkey in self._tables[key]: + self._tables[key][subkey] = None + del self._tables[key][subkey] + self._tables[key] = None + del self._tables +## self.bookmarks = None +## self.family_bookmarks = None +## self.event_bookmarks = None +## self.place_bookmarks = None +## self.source_bookmarks = None +## self.repo_bookmarks = None +## self.media_bookmarks = None +## self.note_bookmarks = None + + def is_open(self): """ Return 1 if the database has been opened. diff --git a/src/gen/db/undoredo.py b/src/gen/db/undoredo.py index 0ffa394e0..134863dd4 100644 --- a/src/gen/db/undoredo.py +++ b/src/gen/db/undoredo.py @@ -400,6 +400,10 @@ class DbUndoBSDDB(DbUndo): Close the undo/redo database """ self.undodb.close() + self.undodb = None + self.mapbase = None + self.db = None + try: os.remove(self.path) except OSError: diff --git a/src/gen/db/write.py b/src/gen/db/write.py index f0485d1d1..71c7a93fb 100644 --- a/src/gen/db/write.py +++ b/src/gen/db/write.py @@ -1013,7 +1013,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): def close(self): if not self.db_is_open: return - self.env.txn_checkpoint() self.__close_metadata() @@ -1060,6 +1059,26 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): self.env = None self.metadata = None self.db_is_open = False + self.surname_lis = None + + DbBsddbRead.close(self) + + self.person_map = None + self.family_map = None + self.repository_map = None + self.note_map = None + self.place_map = None + self.source_map = None + self.media_map = None + self.event_map = None + self.tag_map = None + self.reference_map_primary_map = None + self.reference_map_referenced_map = None + self.reference_map = None + self.undo_callback = None + self.redo_callback = None + self.undo_history_callback = None + self.undodb = None try: clear_lock_file(self.get_save_path()) diff --git a/src/gen/utils/callback.py b/src/gen/utils/callback.py index 04c98878d..50eaa031e 100644 --- a/src/gen/utils/callback.py +++ b/src/gen/utils/callback.py @@ -40,6 +40,7 @@ import sys import types import traceback import inspect +import copy log = sys.stderr.write @@ -311,8 +312,16 @@ class Callback(object): ": %s with key: %s\n" % (signal_name, str(key))) self.__callback_map[signal_name].remove(cb) - - + + def disconnect_all(self):# Find the key in the callback map. + for signal_name in self.__callback_map: + keymap = copy.copy(self.__callback_map[signal_name]) + for key in keymap: + self.__callback_map[signal_name].remove(key) + self.__callback_map[signal_name] = None + self.__callback_map = None + del self.__callback_map + def emit(self, signal_name, args=tuple()): """ Emit the signal called signal_name. The args must be a tuple of diff --git a/src/gen/utils/configmanager.py b/src/gen/utils/configmanager.py index b73d5c1fd..9aaf129d3 100644 --- a/src/gen/utils/configmanager.py +++ b/src/gen/utils/configmanager.py @@ -38,14 +38,18 @@ import ConfigParser import errno import copy -try: - from ast import literal_eval as safe_eval -except: - # PYTHON2.5 COMPATIBILITY: no ast present - # not as safe as literal_eval, but works for python2.5: - def safe_eval(exp): +def safe_eval(exp): # restrict eval to empty environment return eval(exp, {}) +##try: +## from ast import literal_eval as safe_eval +## # this leaks memory !! +##except: +## # PYTHON2.5 COMPATIBILITY: no ast present +## # not as safe as literal_eval, but works for python2.5: +## def safe_eval(exp): +## # restrict eval to empty environment +## return eval(exp, {}) #--------------------------------------------------------------- # diff --git a/src/gui/editors/displaytabs/nameembedlist.py b/src/gui/editors/displaytabs/nameembedlist.py index 44ff97a0d..657f3b06a 100644 --- a/src/gui/editors/displaytabs/nameembedlist.py +++ b/src/gui/editors/displaytabs/nameembedlist.py @@ -78,6 +78,8 @@ class NameEmbedList(GroupEmbeddedList): ] def __init__(self, dbstate, uistate, track, data, person, callback): + """callback is the function to call when preferred name changes + on the namelist """ self.data = data self.person = person self.callback = callback @@ -86,6 +88,14 @@ class NameEmbedList(GroupEmbeddedList): NameModel, move_buttons=True) self.tree.expand_all() + def _cleanup_on_exit(self): + """Unset all things that can block garbage collection. + Finalize rest + """ + self.person = None + self.callback = None + self.data = None + def get_data(self): return ([self.person.get_primary_name()], self.data) diff --git a/src/gui/editors/editfamily.py b/src/gui/editors/editfamily.py index 639b670b9..3b2f0ab40 100644 --- a/src/gui/editors/editfamily.py +++ b/src/gui/editors/editfamily.py @@ -448,6 +448,15 @@ class EditFamily(EditPrimary): else: self.add_parent = False + def _cleanup_on_exit(self): + """Unset all things that can block garbage collection. + Finalize rest + """ + #FIXME, we rebind show_all below, this prevents garbage collection of + # the dialog, fix the rebind + self.window.show_all = None + EditPrimary._cleanup_on_exit(self) + def empty_object(self): return gen.lib.Family() diff --git a/src/gui/editors/editname.py b/src/gui/editors/editname.py index a80cade52..1cf6267a7 100644 --- a/src/gui/editors/editname.py +++ b/src/gui/editors/editname.py @@ -267,16 +267,17 @@ class EditName(EditSecondary): notebook = self.top.get_object("notebook") self._add_tab(notebook, self.gennam) + self.track_ref_for_deletion("gennam") - self.srcref_list = self._add_tab( - notebook, - SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj)) + self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj) + self._add_tab(notebook, self.srcref_list) + self.track_ref_for_deletion("srcref_list") - self.note_tab = self._add_tab( - notebook, - NoteTab(self.dbstate, self.uistate, self.track, + self.note_tab = NoteTab(self.dbstate, self.uistate, self.track, self.obj.get_note_list(), - notetype=NoteType.PERSONNAME)) + notetype=NoteType.PERSONNAME) + self._add_tab(notebook, self.note_tab) + self.track_ref_for_deletion("note_tab") self._setup_notebook_tabs( notebook) @@ -442,6 +443,7 @@ class EditName(EditSecondary): if closeit: if self.callback: self.callback(self.obj) + self.callback = None self.close() def _cleanup_on_exit(self): diff --git a/src/gui/editors/editperson.py b/src/gui/editors/editperson.py index 15d872dd0..b3afea7cb 100644 --- a/src/gui/editors/editperson.py +++ b/src/gui/editors/editperson.py @@ -854,6 +854,7 @@ class EditPerson(EditPrimary): self.close() if self.callback: self.callback(self.obj) + self.callback = None def _edit_name_clicked(self, obj): """ @@ -1017,7 +1018,23 @@ class EditPerson(EditPrimary): return child_ref_list def _cleanup_on_exit(self): - pass + """Unset all things that can block garbage collection. + Finalize rest + """ +## self.private.destroy() +## self.gender.destroy() +## self.ntype_field.destroy() +## self.given.destroy() +## self.call.destroy() +## self.title.destroy() +## self.suffix.destroy() +## self.nick.destroy() +## self.surname_field.destroy() +## self.prefix.destroy() +## self.ortype_field.destroy() +## self.tags.destroy() +## self.gid.destroy() + EditPrimary._cleanup_on_exit(self) #config.save() diff --git a/src/gui/editors/editprimary.py b/src/gui/editors/editprimary.py index b6ca9a764..6aa9e1bf6 100644 --- a/src/gui/editors/editprimary.py +++ b/src/gui/editors/editprimary.py @@ -151,7 +151,13 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement): return page def _cleanup_on_exit(self): - pass + """Unset all things that can block garbage collection. + Finalize rest + """ + for tab in self.__tabs: + if hasattr(tab, '_cleanup_on_exit'): + tab._cleanup_on_exit() + self.__tabs = None def object_is_empty(self): return cmp(self.obj.serialize()[1:], @@ -173,7 +179,12 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement): self._cleanup_db_connects() self.dbstate.disconnect(self.dbstate_connect_key) self._cleanup_on_exit() + self.get_from_handle = None + self.get_from_gramps_id = None ManagedWindow.ManagedWindow.close(self) + self.dbstate = None + self.uistate = None + self.db = None def _cleanup_db_connects(self): """ @@ -236,7 +247,9 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement): self.obj.serialize()[1:]) != 0 def save(self, *obj): - pass + """ Save changes and close. Inheriting classes must implement this + """ + self.close() def set_contexteventbox(self, eventbox): """Set the contextbox that grabs button presses if not grabbed diff --git a/src/gui/editors/editsecondary.py b/src/gui/editors/editsecondary.py index cae0401ad..a2c4414d9 100644 --- a/src/gui/editors/editsecondary.py +++ b/src/gui/editors/editsecondary.py @@ -107,7 +107,19 @@ class EditSecondary(ManagedWindow.ManagedWindow, DbGUIElement): return page def _cleanup_on_exit(self): - pass + """Unset all things that can block garbage collection. + Finalize rest + """ + for tab in self.__tabs: + if hasattr(tab, '_cleanup_on_exit'): + tab._cleanup_on_exit() + self.__tabs = None + self.dbstate = None + self.uistate = None + self.obj = obj + self.db = None + self.callman.database = None + self.callman = None def define_ok_button(self,button,function): button.connect('clicked',function) diff --git a/src/gui/views/listview.py b/src/gui/views/listview.py index 41d85a7cf..d971cc5e5 100644 --- a/src/gui/views/listview.py +++ b/src/gui/views/listview.py @@ -262,6 +262,9 @@ class ListView(NavigationView): filter_info = (False, value, value[0] in self.exact_search()) if self.dirty or not self.model: + if self.model: + self.list.set_model(None) + self.model.destroy() self.model = self.make_model(self.dbstate.db, self.sort_col, search=filter_info, sort_map=self.column_order()) diff --git a/src/gui/views/treemodels/eventmodel.py b/src/gui/views/treemodels/eventmodel.py index 40425a2e2..d7e7e5c7a 100644 --- a/src/gui/views/treemodels/eventmodel.py +++ b/src/gui/views/treemodels/eventmodel.py @@ -99,6 +99,17 @@ class EventModel(FlatBaseModel): FlatBaseModel.__init__(self, db, scol, order, tooltip_column=8, search=search, skip=skip, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + FlatBaseModel.destroy(self) + def on_get_n_columns(self): return len(self.fmap)+1 diff --git a/src/gui/views/treemodels/familymodel.py b/src/gui/views/treemodels/familymodel.py index c4863a921..cc9829b27 100644 --- a/src/gui/views/treemodels/familymodel.py +++ b/src/gui/views/treemodels/familymodel.py @@ -89,6 +89,17 @@ class FamilyModel(FlatBaseModel): FlatBaseModel.__init__(self, db, scol, order, tooltip_column=9, search=search, skip=skip, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + FlatBaseModel.destroy(self) + def color_column(self): """ Return the color column. diff --git a/src/gui/views/treemodels/flatbasemodel.py b/src/gui/views/treemodels/flatbasemodel.py index a6ce7bdb3..f1599f81a 100644 --- a/src/gui/views/treemodels/flatbasemodel.py +++ b/src/gui/views/treemodels/flatbasemodel.py @@ -122,6 +122,14 @@ class FlatNodeMap(object): self._reverse = False self.__corr = (0, 1) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self._index2hndl = None + self._fullhndl = None + self._hndl2index = None + def set_path_map(self, index2hndllist, fullhndllist, identical=True, reverse=False): """ @@ -408,6 +416,18 @@ class FlatBaseModel(gtk.GenericTreeModel): _LOG.debug(self.__class__.__name__ + ' __init__ ' + str(time.clock() - cput) + ' sec') + def destroy(self): + """ + Unset all elements that prevent garbage collection + """ + self.db = None + self.sort_func = None + if self.node_map: + self.node_map.destroy() + self.node_map = None + self.rebuild_data = None + self.search = None + def set_search(self, search): """ Change the search function that filters the data in the model. diff --git a/src/gui/views/treemodels/mediamodel.py b/src/gui/views/treemodels/mediamodel.py index 21c750877..7ba1fcaae 100644 --- a/src/gui/views/treemodels/mediamodel.py +++ b/src/gui/views/treemodels/mediamodel.py @@ -89,6 +89,17 @@ class MediaModel(FlatBaseModel): FlatBaseModel.__init__(self, db, scol, order, tooltip_column=9, search=search, skip=skip, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + FlatBaseModel.destroy(self) + def color_column(self): """ Return the color column. diff --git a/src/gui/views/treemodels/notemodel.py b/src/gui/views/treemodels/notemodel.py index 99631b83d..d3ecc400a 100644 --- a/src/gui/views/treemodels/notemodel.py +++ b/src/gui/views/treemodels/notemodel.py @@ -79,6 +79,17 @@ class NoteModel(FlatBaseModel): FlatBaseModel.__init__(self, db, scol, order, search=search, skip=skip, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + FlatBaseModel.destroy(self) + def color_column(self): """ Return the color column. diff --git a/src/gui/views/treemodels/peoplemodel.py b/src/gui/views/treemodels/peoplemodel.py index 080551f7f..21f682fd5 100644 --- a/src/gui/views/treemodels/peoplemodel.py +++ b/src/gui/views/treemodels/peoplemodel.py @@ -147,6 +147,17 @@ class PeopleBaseModel(object): self.lru_bdate = LRU(PeopleBaseModel._CACHE_SIZE) self.lru_ddate = LRU(PeopleBaseModel._CACHE_SIZE) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + self.clear_local_cache() + def color_column(self): """ Return the color column. @@ -461,7 +472,6 @@ class PersonListModel(PeopleBaseModel, FlatBaseModel): """ def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None, skip=set(), sort_map=None): - PeopleBaseModel.__init__(self, db) FlatBaseModel.__init__(self, db, search=search, skip=skip, tooltip_column=13, @@ -471,6 +481,13 @@ class PersonListModel(PeopleBaseModel, FlatBaseModel): """ Clear the LRU cache """ PeopleBaseModel.clear_local_cache(self, handle) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + PeopleBaseModel.destroy(self) + FlatBaseModel.destroy(self) + class PersonTreeModel(PeopleBaseModel, TreeBaseModel): """ Hierarchical people model. @@ -482,6 +499,15 @@ class PersonTreeModel(PeopleBaseModel, TreeBaseModel): TreeBaseModel.__init__(self, db, 13, search=search, skip=skip, scol=scol, order=order, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + PeopleBaseModel.destroy(self) + self.hmap = None + self.number_items = None + TreeBaseModel.destroy(self) + def _set_base_data(self): """See TreeBaseModel, we also set some extra lru caches """ diff --git a/src/gui/views/treemodels/placemodel.py b/src/gui/views/treemodels/placemodel.py index 815478534..b91a8f8af 100644 --- a/src/gui/views/treemodels/placemodel.py +++ b/src/gui/views/treemodels/placemodel.py @@ -118,6 +118,16 @@ class PlaceBaseModel(object): self.column_handle, ] + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + def on_get_n_columns(self): return len(self.fmap)+1 @@ -224,6 +234,13 @@ class PlaceListModel(PlaceBaseModel, FlatBaseModel): FlatBaseModel.__init__(self, db, scol, order, tooltip_column=15, search=search, skip=skip, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + PlaceBaseModel.destroy(self) + FlatBaseModel.destroy(self) + def column_name(self, data): return unicode(data[2]) @@ -246,6 +263,15 @@ class PlaceTreeModel(PlaceBaseModel, TreeBaseModel): nrgroups = 3, group_can_have_handle = True) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + PlaceBaseModel.destroy(self) + self.hmap = None + self.number_items = None + TreeBaseModel.destroy(self) + def _set_base_data(self): """See TreeBaseModel, for place, most have been set in init of PlaceBaseModel diff --git a/src/gui/views/treemodels/repomodel.py b/src/gui/views/treemodels/repomodel.py index 5dfda3e32..01508efc1 100644 --- a/src/gui/views/treemodels/repomodel.py +++ b/src/gui/views/treemodels/repomodel.py @@ -95,6 +95,18 @@ class RepositoryModel(FlatBaseModel): FlatBaseModel.__init__(self, db, scol, order, tooltip_column=14, search=search, skip=skip, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.get_handles = None + self.map = None + self.fmap = None + self.smap = None + FlatBaseModel.destroy(self) + def on_get_n_columns(self): return len(self.fmap)+1 diff --git a/src/gui/views/treemodels/sourcemodel.py b/src/gui/views/treemodels/sourcemodel.py index a0bbb7c36..5be3a32ae 100644 --- a/src/gui/views/treemodels/sourcemodel.py +++ b/src/gui/views/treemodels/sourcemodel.py @@ -76,6 +76,17 @@ class SourceModel(FlatBaseModel): FlatBaseModel.__init__(self,db,scol, order,tooltip_column=7,search=search, skip=skip, sort_map=sort_map) + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + FlatBaseModel.destroy(self) + def on_get_n_columns(self): return len(self.fmap)+1 diff --git a/src/gui/views/treemodels/treebasemodel.py b/src/gui/views/treemodels/treebasemodel.py index 801db600c..3d3e24af5 100644 --- a/src/gui/views/treemodels/treebasemodel.py +++ b/src/gui/views/treemodels/treebasemodel.py @@ -173,6 +173,12 @@ class NodeMap(object): """ def __init__(self): self.id2node = {} + + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.id2node.clear() def add_node(self, node): """ @@ -310,6 +316,20 @@ class TreeBaseModel(gtk.GenericTreeModel): _LOG.debug(self.__class__.__name__ + ' __init__ ' + str(time.clock() - cput) + ' sec') + def destroy(self): + """ + Unset all elements that prevent garbage collection + """ + self.db = None + self.sort_func = None + if self.nodemap: + self.nodemap.destroy() + self.nodemap = None + self.rebuild_data = None + self._build_data = None + self.search = None + self.clear_cache() + def _set_base_data(self): """ This method must be overwritten in the inheriting class, setting diff --git a/src/gui/widgets/buttons.py b/src/gui/widgets/buttons.py index 3a3cfccd5..4bcf48d72 100644 --- a/src/gui/widgets/buttons.py +++ b/src/gui/widgets/buttons.py @@ -72,6 +72,12 @@ class IconButton(gtk.Button): self.connect('button-press-event', func, handle) self.connect('key-press-event', func, handle) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## gtk.Button.destroy(self) + #------------------------------------------------------------------------- # # WarnButton class @@ -91,6 +97,13 @@ class WarnButton(gtk.Button): self.func = None self.hide() +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.func = None +## gtk.Button.destroy(self) + def on_clicked(self, func): self.connect('button-press-event', self._button_press) self.func = func @@ -112,6 +125,12 @@ class SimpleButton(gtk.Button): self.add(gtk.image_new_from_stock(image, gtk.ICON_SIZE_BUTTON)) self.connect('clicked', func) self.show() + +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## gtk.Button.destroy(self) #------------------------------------------------------------------------- # @@ -127,6 +146,12 @@ class PrivacyButton(object): self.set_active(obj.get_privacy()) self.button.set_sensitive(not readonly) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.obj = None + def set_sensitive(self, val): self.button.set_sensitive(val) diff --git a/src/gui/widgets/monitoredwidgets.py b/src/gui/widgets/monitoredwidgets.py index bb87bf86d..9d670a3f0 100644 --- a/src/gui/widgets/monitoredwidgets.py +++ b/src/gui/widgets/monitoredwidgets.py @@ -76,6 +76,14 @@ class MonitoredCheckbox(object): self.set_val(obj.get_active()) if self.on_toggle: self.on_toggle(self.get_val()) + +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.obj = None #------------------------------------------------------------------------- # @@ -99,6 +107,14 @@ class MonitoredEntry(object): if autolist: AutoComp.fill_entry(obj, autolist) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.obj = None + def reinit(self, set_val, get_val): self.set_val = set_val self.get_val = get_val @@ -166,6 +182,14 @@ class MonitoredSpinButton(object): if autolist: AutoComp.fill_entry(obj,autolist) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.obj = None + def reinit(self, set_val, get_val): """ Reinitialize class with the specified callback functions. @@ -270,6 +294,14 @@ class MonitoredText(object): self.buf.connect('changed', self.on_change) obj.set_editable(not read_only) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.buf = None + def on_change(self, obj): s, e = self.buf.get_bounds() self.set_val(unicode(self.buf.get_text(s, e, False))) @@ -301,6 +333,14 @@ class MonitoredType(object): self.obj.set_sensitive(not readonly) self.obj.connect('changed', self.on_change) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.obj = None + def reinit(self, set_val, get_val): self.set_val = set_val self.get_val = get_val @@ -369,6 +409,14 @@ class MonitoredDataType(object): self.obj.set_sensitive(not readonly) self.obj.connect('changed', self.on_change) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.obj = None + def reinit(self, set_val, get_val): self.set_val = set_val self.get_val = get_val @@ -410,6 +458,14 @@ class MonitoredMenu(object): self.obj.connect('changed', self.on_change) self.obj.set_sensitive(not readonly) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.obj = None + def force(self, value): self.obj.set_active(value) @@ -465,6 +521,15 @@ class MonitoredStrMenu(object): self.obj.connect('changed', self.on_change) self.obj.set_sensitive(not readonly) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val = None +## self.get_val = None +## self.obj = None +## self.model = None + def on_change(self, obj): self.set_val(self.data[obj.get_active()]) @@ -531,6 +596,15 @@ class MonitoredComboSelectedEntry(object): #set correct editable self.enable(not read_only) +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.set_val_list = None +## self.get_val_list = None +## self.objcombo = None +## self.objentry = None + def __fill(self): """ Fill combo with data @@ -643,6 +717,15 @@ class MonitoredTagList(object): self._display() +## def destroy(self): +## """ +## Unset all elements that can prevent garbage collection +## """ +## self.uistate = None +## self.track = None +## self.db = None +## self.set_list = None + def _display(self): """ Display the tag list.