summaryrefslogtreecommitdiff
path: root/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2012-05-11 20:33:23 +0200
committerLuboš Luňák <l.lunak@suse.cz>2012-05-11 20:39:01 +0200
commite4450c54aee85b295b933e91d207fd8220c01107 (patch)
treeff5973e21f6b4a4b8d1e55fa7c0f1e17adc0c585 /sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
parentee5fc5d25fe102c30daf7d181b8181d40b85a4f3 (diff)
avoid recursion that can mess up DND setup (fdo#41996)
The way too smart ctor for the DND handler started drag immediately, causing a race condition that could recurse to setting a handler again before the first one was actually set, thus immediately again causing the DND to be stopped, and then possibly later again started, depending on how the race condition turned out. Use delayed initialization to avoid this. Change-Id: I528eddbdc7c52a19675997e4c866506c662cff19
Diffstat (limited to 'sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx')
-rw-r--r--sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx45
1 files changed, 31 insertions, 14 deletions
diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
index 2a48a7c5f24c..0d3fc63bd1f3 100644
--- a/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
+++ b/sd/source/ui/slidesorter/controller/SlsSelectionFunction.cxx
@@ -251,10 +251,11 @@ public:
MultiSelectionModeHandler (
SlideSorter& rSlideSorter,
SelectionFunction& rSelectionFunction,
- const Point& rMouseModelPosition,
- const sal_uInt32 nEventCode);
+ const Point& rMouseModelPosition);
virtual ~MultiSelectionModeHandler (void);
+ void Initialize(const sal_uInt32 nEventCode);
+
virtual SelectionFunction::Mode GetMode (void) const;
virtual void Abort (void);
virtual void ProcessEvent (SelectionFunction::EventDescriptor& rDescriptor);
@@ -300,11 +301,10 @@ class DragAndDropModeHandler : public SelectionFunction::ModeHandler
public:
DragAndDropModeHandler (
SlideSorter& rSlideSorter,
- SelectionFunction& rSelectionFunction,
- const Point& rMousePosition,
- ::Window* pWindow);
+ SelectionFunction& rSelectionFunction);
virtual ~DragAndDropModeHandler (void);
+ void Initialize(const Point& rMousePosition, ::Window* pWindow);
virtual SelectionFunction::Mode GetMode (void) const;
virtual void Abort (void);
@@ -817,8 +817,13 @@ void SelectionFunction::SwitchToDragAndDropMode (const Point aMousePosition)
{
if (mpModeHandler->GetMode() != DragAndDropMode)
{
- SwitchMode(::boost::shared_ptr<ModeHandler>(
- new DragAndDropModeHandler(mrSlideSorter, *this, aMousePosition, mpWindow)));
+ ::boost::shared_ptr<DragAndDropModeHandler> handler(
+ new DragAndDropModeHandler(mrSlideSorter, *this));
+ SwitchMode(handler);
+ // Delayed initialization, only after mpModeHanler is set, otherwise DND initialization
+ // could already trigger DND events, which would recursively trigger this code again,
+ // and without mpModeHandler set it would again try to set a new handler.
+ handler->Initialize(aMousePosition, mpWindow);
}
}
@@ -830,8 +835,14 @@ void SelectionFunction::SwitchToMultiSelectionMode (
const sal_uInt32 nEventCode)
{
if (mpModeHandler->GetMode() != MultiSelectionMode)
- SwitchMode(::boost::shared_ptr<ModeHandler>(
- new MultiSelectionModeHandler(mrSlideSorter, *this, aMousePosition, nEventCode)));
+ {
+ ::boost::shared_ptr<MultiSelectionModeHandler> handler(
+ new MultiSelectionModeHandler(mrSlideSorter, *this, aMousePosition));
+ SwitchMode(handler);
+ // Delayed initialization, only after mpModeHanler is set, the handle ctor
+ // is non-trivial, so it could possibly recurse just like the DND handler above.
+ handler->Initialize(nEventCode);
+ }
}
@@ -1502,8 +1513,7 @@ void NormalModeHandler::ResetButtonDownLocation (void)
MultiSelectionModeHandler::MultiSelectionModeHandler (
SlideSorter& rSlideSorter,
SelectionFunction& rSelectionFunction,
- const Point& rMouseModelPosition,
- const sal_uInt32 nEventCode)
+ const Point& rMouseModelPosition)
: ModeHandler(rSlideSorter, rSelectionFunction, false),
meSelectionMode(SM_Normal),
maSecondCorner(rMouseModelPosition),
@@ -1512,6 +1522,11 @@ MultiSelectionModeHandler::MultiSelectionModeHandler (
mnSecondIndex(-1),
maButtonBarLock(rSlideSorter)
{
+}
+
+
+void MultiSelectionModeHandler::Initialize(const sal_uInt32 nEventCode)
+{
const Pointer aSelectionPointer (POINTER_TEXT);
mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer);
SetSelectionModeFromModifier(nEventCode);
@@ -1751,11 +1766,13 @@ void MultiSelectionModeHandler::UpdateSelection (void)
DragAndDropModeHandler::DragAndDropModeHandler (
SlideSorter& rSlideSorter,
- SelectionFunction& rSelectionFunction,
- const Point& rMousePosition,
- ::Window* pWindow)
+ SelectionFunction& rSelectionFunction)
: ModeHandler(rSlideSorter, rSelectionFunction, false)
{
+}
+
+void DragAndDropModeHandler::Initialize(const Point& rMousePosition, ::Window* pWindow)
+{
SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
if (pDragTransferable==NULL && mrSlideSorter.GetViewShell() != NULL)
{