From 2e17c9e5811fc1e0802e8739c70db80fadca7b47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Wed, 22 Aug 2012 14:20:32 +0100
Subject: [PATCH] Resolves: rhbz#842292 crash in calling callback whose
 instance was deleted

Change-Id: I4cc04d59f48b42cc105703daa9983dd7c9f7af62
---
 .../controller/SlsDragAndDropContext.cxx           |    6 +++--
 .../slidesorter/controller/SlsScrollBarManager.cxx |    8 +++---
 .../controller/SlsSelectionFunction.cxx            |   26 +++++++++++++++++---
 .../inc/controller/SlsScrollBarManager.hxx         |    2 ++
 4 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx
index b8234b5..c1bf497 100644
--- a/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsDragAndDropContext.cxx
@@ -100,11 +100,13 @@ void DragAndDropContext::UpdatePosition (
     ::boost::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler (
         mpTargetSlideSorter->GetController().GetInsertionIndicatorHandler());
 
-    if ( ! (bAllowAutoScroll
+    bool bDoAutoScroll = bAllowAutoScroll
             && mpTargetSlideSorter->GetController().GetScrollBarManager().AutoScroll(
                 rMousePosition,
                 ::boost::bind(
-                    &DragAndDropContext::UpdatePosition, this, rMousePosition, eMode, false))))
+                    &DragAndDropContext::UpdatePosition, this, rMousePosition, eMode, false));
+
+    if (!bDoAutoScroll)
     {
         pInsertionIndicatorHandler->UpdatePosition(aMouseModelPosition, eMode);
 
diff --git a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
index 7abd6e4..9410052 100644
--- a/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsScrollBarManager.cxx
@@ -617,13 +617,15 @@ bool ScrollBarManager::RepeatAutoScroll (void)
         }
     }
 
-    maAutoScrollFunctor = ::boost::function<void(void)>();
+    clearAutoScrollFunctor();
     mbIsAutoScrollActive = false;
     return false;
 }
 
-
-
+void ScrollBarManager::clearAutoScrollFunctor()
+{
+    maAutoScrollFunctor = ::boost::function<void(void)>();
+}
 
 IMPL_LINK(ScrollBarManager, AutoScrollTimeoutHandler, Timer *, EMPTYARG)
 {
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
index 605749c..7ec40f9 100644
--- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
@@ -284,6 +284,7 @@ private:
     SelectionMode meSelectionMode;
     Point maSecondCorner;
     Pointer maSavedPointer;
+    bool mbAutoScrollInstalled;
     sal_Int32 mnAnchorIndex;
     sal_Int32 mnSecondIndex;
     view::ButtonBar::Lock maButtonBarLock;
@@ -1574,6 +1575,7 @@ MultiSelectionModeHandler::MultiSelectionModeHandler (
       meSelectionMode(SM_Normal),
       maSecondCorner(rMouseModelPosition),
       maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()),
+      mbAutoScrollInstalled(false),
       mnAnchorIndex(-1),
       mnSecondIndex(-1),
       maButtonBarLock(rSlideSorter)
@@ -1594,6 +1596,12 @@ void MultiSelectionModeHandler::Initialize(const sal_uInt32 nEventCode)
 
 MultiSelectionModeHandler::~MultiSelectionModeHandler (void)
 {
+    if (mbAutoScrollInstalled)
+    {
+        //a call to this handler's MultiSelectionModeHandler::UpdatePosition
+        //may be still waiting to be called back
+        mrSlideSorter.GetController().GetScrollBarManager().clearAutoScrollFunctor();
+    }
     mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer);
 }
 
@@ -1635,6 +1643,14 @@ void MultiSelectionModeHandler::ProcessEvent (
 bool MultiSelectionModeHandler::ProcessButtonUpEvent (
     SelectionFunction::EventDescriptor& rDescriptor)
 {
+    if (mbAutoScrollInstalled)
+    {
+        //a call to this handler's MultiSelectionModeHandler::UpdatePosition
+        //may be still waiting to be called back
+        mrSlideSorter.GetController().GetScrollBarManager().clearAutoScrollFunctor();
+        mbAutoScrollInstalled = false;
+    }
+
     if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK))
     {
         mrSelectionFunction.SwitchToNormalMode();
@@ -1691,16 +1707,18 @@ void MultiSelectionModeHandler::UpdatePosition (
     SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
     const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
 
-    if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll(
+    bool bDoAutoScroll = bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll(
         rMousePosition,
         ::boost::bind(
             &MultiSelectionModeHandler::UpdatePosition,
             this,
             rMousePosition,
-            false))))
-    {
+            false));
+
+    if (!bDoAutoScroll)
         UpdateModelPosition(aMouseModelPosition);
-    }
+
+    mbAutoScrollInstalled |= bDoAutoScroll;
 }
 
 
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx
index 2ce5057..d8704d2 100644
--- a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx
+++ b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx
@@ -172,6 +172,8 @@ public:
 
     void StopAutoScroll (void);
 
+    void clearAutoScrollFunctor();
+
     enum Orientation { Orientation_Horizontal, Orientation_Vertical };
     enum Unit { Unit_Pixel, Unit_Slide };
     /** Scroll the slide sorter by setting the thumbs of the scroll bars and
-- 
1.7.10.4

