Fix for: 1277: database corroption on delete outside of DisplayTabs while tab open

Introduces the concept of callman.py as one single way to follow handles an
interface is interested in. 
dbguielement.py contains a small base class using that, usable for all windows/
guielements that need to track database changes to handles


svn: r12881
This commit is contained in:
Benny Malengier
2009-08-05 10:32:05 +00:00
parent f34d4656a7
commit ee69317b62
30 changed files with 1048 additions and 107 deletions

View File

@@ -21,9 +21,25 @@
# $Id$
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GTK modules
#
#-------------------------------------------------------------------------
import gtk
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import ManagedWindow
import DateHandler
from BasicUtils import name_displayer
@@ -31,8 +47,9 @@ import Config
import GrampsDisplay
from QuestionDialog import SaveDialog
import gen.lib
from gui.dbguielement import DbGUIElement
class EditPrimary(ManagedWindow.ManagedWindow):
class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement):
QR_CATEGORY = -1
@@ -52,19 +69,23 @@ class EditPrimary(ManagedWindow.ManagedWindow):
self.uistate = uistate
self.db = state.db
self.callback = callback
self.signal_keys = []
self.ok_button = None
self.get_from_handle = get_from_handle
self.get_from_gramps_id = get_from_gramps_id
self.contexteventbox = None
self.__tabs = []
ManagedWindow.ManagedWindow.__init__(self, uistate, track, obj)
DbGUIElement.__init__(self, self.db)
self._local_init()
self._set_size()
self._create_tabbed_pages()
self._setup_fields()
self._connect_signals()
#if the database is changed, all info shown is invalid and the window
# should close
self.dbstate.connect('database-changed', self._do_close)
self.show()
self._post_init()
@@ -80,18 +101,15 @@ class EditPrimary(ManagedWindow.ManagedWindow):
"""
pass
def _add_db_signal(self, name, callback):
self.signal_keys.append(self.db.connect(name, callback))
def _connect_signals(self):
pass
def _setup_fields(self):
pass
def _create_tabbed_pages(self):
pass
def _connect_signals(self):
pass
def build_window_key(self, obj):
if obj and obj.get_handle():
return obj.get_handle()
@@ -126,8 +144,8 @@ class EditPrimary(ManagedWindow.ManagedWindow):
notebook.set_current_page(page_no)
def _add_tab(self, notebook, page):
self.__tabs.append(page)
notebook.insert_page(page, page.get_tab_widget())
page.add_db_signal_callback(self._add_db_signal)
page.label.set_use_underline(True)
return page
@@ -151,11 +169,31 @@ class EditPrimary(ManagedWindow.ManagedWindow):
section))
def _do_close(self, *obj):
for key in self.signal_keys:
self.db.disconnect(key)
self._cleanup_db_connects()
self._cleanup_on_exit()
ManagedWindow.ManagedWindow.close(self)
def _cleanup_db_connects(self):
"""
All connects that happened to signals of the db must be removed on
closed. This implies two things:
1. The connects on the main view must be disconnected
2. Connects done in subelements must be disconnected
"""
#cleanup callbackmanager of this editor
self._cleanup_callbacks()
for tab in [tab for tab in self.__tabs if hasattr(tab, 'callman')]:
tab._cleanup_callbacks()
def check_for_close(self, handles):
"""
Callback method for delete signals.
If there is a delete signal of the primary object we are editing, the
editor (and all child windows spawned) should be closed
"""
if self.obj.get_handle() in handles:
self._do_close()
def close(self, *obj):
"""If the data has changed, give the user a chance to cancel
the close window"""