diff options
author | Michael Stahl <mstahl@redhat.com> | 2017-04-26 11:10:41 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2017-04-26 12:39:34 +0200 |
commit | 8cd1ae22eb2d464516717d767bd3e5f6c2f4bd34 (patch) | |
tree | 60766ab763991087ca46a9a933f0e96b2e017d84 /sw | |
parent | 93bf0b1ba11c7710f80a7773eaf0b5ca816d82a7 (diff) |
tdf#107427 sw: fix crash with stale entries in SwNavigationMgr
When deleting a header, the sw::UnoCursorPointer of SwNavigationMgr
spontaneously self-destructs, but SwNavigationMgr expects its cursors
to always be alive, so add another SfxListener to remove dying cursors.
(probably regression from a2c467a58ade9f55e0154b2935c747bb283ebd45)
Change-Id: I1055ea3cfc47114dc36002198f1ddffea87d2d85
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/uibase/inc/navmgr.hxx | 11 | ||||
-rw-r--r-- | sw/source/uibase/wrtsh/navmgr.cxx | 30 |
2 files changed, 35 insertions, 6 deletions
diff --git a/sw/source/uibase/inc/navmgr.hxx b/sw/source/uibase/inc/navmgr.hxx index 733fd35f6208..dffe1cb32ca9 100644 --- a/sw/source/uibase/inc/navmgr.hxx +++ b/sw/source/uibase/inc/navmgr.hxx @@ -21,7 +21,7 @@ class SwWrtShell; struct SwPosition; class SwUnoCursor; -class SwNavigationMgr final +class SwNavigationMgr final : public SfxListener { private: /* @@ -43,11 +43,7 @@ private: public: /* Constructor that initializes the shell to the current shell */ SwNavigationMgr( SwWrtShell & rShell ); - ~SwNavigationMgr() - { - SolarMutexGuard g; - m_entries.clear(); - } + ~SwNavigationMgr(); /* Can we go back in the history ? */ bool backEnabled() ; /* Can we go forward in the history ? */ @@ -58,6 +54,9 @@ public: void goForward() ; /* The method that adds the position pPos to the navigation history */ bool addEntry(const SwPosition& rPos); + /* to get notified if our cursors self-destruct */ + virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override; }; #endif + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/wrtsh/navmgr.cxx b/sw/source/uibase/wrtsh/navmgr.cxx index 3852e1959de9..b507c7c2ffac 100644 --- a/sw/source/uibase/wrtsh/navmgr.cxx +++ b/sw/source/uibase/wrtsh/navmgr.cxx @@ -46,6 +46,34 @@ SwNavigationMgr::SwNavigationMgr(SwWrtShell & rShell) { } +SwNavigationMgr::~SwNavigationMgr() +{ + SolarMutexGuard g; + for (auto & it : m_entries) + { + EndListening(it.get()->m_aNotifier); + } + m_entries.clear(); +} + +void SwNavigationMgr::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) +{ + // our cursors may now spontaneously self-destruct: remove from + // m_entries if that happens + if (typeid(rHint) == typeid(sw::UnoCursorHint)) + { + for (auto it = m_entries.begin(); it != m_entries.end(); ++it) + { + if (!it->get() || & rBC == & it->get()->m_aNotifier) + { + EndListening(rBC); + m_entries.erase(it); + break; + } + } + } +} + // This method is used by the navigation shell - defined in sw/source/uibase/inc/navsh.hxx // and implemented in sw/source/uibase/shells/navsh.cxx // It is called when we want to check if the back button should be enabled or not. @@ -163,6 +191,7 @@ bool SwNavigationMgr::addEntry(const SwPosition& rPos) { if (*m_entries.back()->GetPoint() != rPos) { sw::UnoCursorPointer pCursor(m_rMyShell.GetDoc()->CreateUnoCursor(rPos)); + StartListening(pCursor->m_aNotifier); m_entries.push_back(pCursor); } bRet = true; @@ -170,6 +199,7 @@ bool SwNavigationMgr::addEntry(const SwPosition& rPos) { else { if ( (!m_entries.empty() && *m_entries.back()->GetPoint() != rPos) || m_entries.empty() ) { sw::UnoCursorPointer pCursor(m_rMyShell.GetDoc()->CreateUnoCursor(rPos)); + StartListening(pCursor->m_aNotifier); m_entries.push_back(pCursor); bRet = true; } |