summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-04-26 11:10:41 +0200
committerMichael Stahl <mstahl@redhat.com>2017-04-26 12:39:34 +0200
commit8cd1ae22eb2d464516717d767bd3e5f6c2f4bd34 (patch)
tree60766ab763991087ca46a9a933f0e96b2e017d84
parent93bf0b1ba11c7710f80a7773eaf0b5ca816d82a7 (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
-rw-r--r--sw/source/uibase/inc/navmgr.hxx11
-rw-r--r--sw/source/uibase/wrtsh/navmgr.cxx30
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;
}