1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sal/config.h>
23 #include <controller/SlsSelectionFunction.hxx>
25 #include <SlideSorter.hxx>
26 #include <SlideSorterViewShell.hxx>
27 #include "SlsDragAndDropContext.hxx"
28 #include <controller/SlideSorterController.hxx>
29 #include <controller/SlsPageSelector.hxx>
30 #include <controller/SlsFocusManager.hxx>
31 #include <controller/SlsScrollBarManager.hxx>
32 #include <controller/SlsClipboard.hxx>
33 #include <controller/SlsCurrentSlideManager.hxx>
34 #include <controller/SlsInsertionIndicatorHandler.hxx>
35 #include <controller/SlsSelectionManager.hxx>
36 #include <controller/SlsProperties.hxx>
37 #include <controller/SlsVisibleAreaManager.hxx>
38 #include <model/SlideSorterModel.hxx>
39 #include <model/SlsPageDescriptor.hxx>
40 #include <model/SlsPageEnumerationProvider.hxx>
41 #include <view/SlideSorterView.hxx>
42 #include <view/SlsLayouter.hxx>
43 #include <framework/FrameworkHelper.hxx>
44 #include <osl/diagnose.h>
47 #include <drawdoc.hxx>
49 #include <ViewShell.hxx>
50 #include <FrameView.hxx>
52 #include <o3tl/deleter.hxx>
53 #include <sfx2/dispatch.hxx>
54 #include <vcl/ptrstyle.hxx>
59 const sal_uInt32
SINGLE_CLICK (0x00000001);
60 const sal_uInt32
DOUBLE_CLICK (0x00000002);
61 const sal_uInt32
LEFT_BUTTON (0x00000010);
62 const sal_uInt32
RIGHT_BUTTON (0x00000020);
63 const sal_uInt32
MIDDLE_BUTTON (0x00000040);
64 const sal_uInt32
BUTTON_DOWN (0x00000100);
65 const sal_uInt32
BUTTON_UP (0x00000200);
66 const sal_uInt32
MOUSE_MOTION (0x00000400);
67 const sal_uInt32
MOUSE_DRAG (0x00000800);
68 // The rest leaves the lower 16 bit untouched so that it can be used with
70 const sal_uInt32
OVER_SELECTED_PAGE (0x00010000);
71 const sal_uInt32
OVER_UNSELECTED_PAGE (0x00020000);
72 const sal_uInt32
SHIFT_MODIFIER (0x00200000);
73 const sal_uInt32
CONTROL_MODIFIER (0x00400000);
75 // Some absent events are defined so they can be expressed explicitly.
76 const sal_uInt32
NO_MODIFIER (0x00000000);
77 const sal_uInt32
NOT_OVER_PAGE (0x00000000);
80 const sal_uInt32
MODIFIER_MASK (SHIFT_MODIFIER
| CONTROL_MODIFIER
);
82 } // end of anonymous namespace
84 // Define some macros to make the following switch statement more readable.
85 #define ANY_MODIFIER(code) \
87 case code|SHIFT_MODIFIER: \
88 case code|CONTROL_MODIFIER
90 namespace sd::slidesorter::controller
{
92 //===== SelectionFunction::EventDescriptor ====================================
94 class SelectionFunction::EventDescriptor
97 Point maMousePosition
;
98 Point maMouseModelPosition
;
99 model::SharedPageDescriptor mpHitDescriptor
;
101 sal_uInt32 mnEventCode
;
102 InsertionIndicatorHandler::Mode meDragMode
;
106 sal_uInt32 nEventType
,
107 const MouseEvent
& rEvent
,
108 SlideSorter
const & rSlideSorter
);
110 sal_uInt32 nEventType
,
111 const AcceptDropEvent
& rEvent
,
112 const sal_Int8 nDragAction
,
113 SlideSorter
const & rSlideSorter
);
116 /** Compute a numerical code that describes a mouse event and that can
117 be used for fast look up of the appropriate reaction.
119 sal_uInt32
EncodeMouseEvent (const MouseEvent
& rEvent
) const;
121 /** Compute a numerical code that describes the current state like
122 whether the selection rectangle is visible or whether the page under
123 the mouse or the one that has the focus is selected.
125 sal_uInt32
EncodeState() const;
128 //===== SelectionFunction::ModeHandler ========================================
130 class SelectionFunction::ModeHandler
134 SlideSorter
& rSlideSorter
,
135 SelectionFunction
& rSelectionFunction
,
136 const bool bIsMouseOverIndicatorAllowed
);
137 virtual ~ModeHandler() COVERITY_NOEXCEPT_FALSE
;
139 virtual Mode
GetMode() const = 0;
140 virtual void Abort() = 0;
141 virtual void ProcessEvent (EventDescriptor
& rDescriptor
);
143 /** Set the selection to exactly the specified page and also set it as
146 void SetCurrentPage (const model::SharedPageDescriptor
& rpDescriptor
);
148 /// Deselect all pages.
149 void DeselectAllPages();
150 void SelectOnePage (const model::SharedPageDescriptor
& rpDescriptor
);
152 /** When the view on which this selection function is working is the
153 main view then the view is switched to the regular editing view.
155 void SwitchView (const model::SharedPageDescriptor
& rpDescriptor
);
158 const Point
& rMousePosition
);
160 bool IsMouseOverIndicatorAllowed() const { return mbIsMouseOverIndicatorAllowed
;}
163 SlideSorter
& mrSlideSorter
;
164 SelectionFunction
& mrSelectionFunction
;
166 virtual bool ProcessButtonDownEvent (EventDescriptor
& rDescriptor
);
167 virtual bool ProcessButtonUpEvent (EventDescriptor
& rDescriptor
);
168 virtual bool ProcessMotionEvent (EventDescriptor
& rDescriptor
);
169 virtual bool ProcessDragEvent (EventDescriptor
& rDescriptor
);
170 virtual bool HandleUnprocessedEvent (EventDescriptor
& rDescriptor
);
172 void ReprocessEvent (EventDescriptor
& rDescriptor
);
175 const bool mbIsMouseOverIndicatorAllowed
;
180 /** This is the default handler for processing events. It activates the
181 multi selection or drag-and-drop when the right conditions are met.
183 class NormalModeHandler
: public SelectionFunction::ModeHandler
187 SlideSorter
& rSlideSorter
,
188 SelectionFunction
& rSelectionFunction
);
190 virtual SelectionFunction::Mode
GetMode() const override
;
191 virtual void Abort() override
;
193 void ResetButtonDownLocation();
196 virtual bool ProcessButtonDownEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
197 virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
198 virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
199 virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
202 ::std::optional
<Point
> maButtonDownLocation
;
204 /** Select all pages between and including the selection anchor and the
207 void RangeSelect (const model::SharedPageDescriptor
& rpDescriptor
);
210 /** Handle events during a multi selection, which typically is started by
211 pressing the left mouse button when not over a page.
213 class MultiSelectionModeHandler
: public SelectionFunction::ModeHandler
216 /** Start a rectangle selection at the given position.
218 MultiSelectionModeHandler (
219 SlideSorter
& rSlideSorter
,
220 SelectionFunction
& rSelectionFunction
,
221 const Point
& rMouseModelPosition
,
222 const sal_uInt32 nEventCode
);
224 virtual ~MultiSelectionModeHandler() override
;
226 virtual SelectionFunction::Mode
GetMode() const override
;
227 virtual void Abort() override
;
228 virtual void ProcessEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
230 enum SelectionMode
{ SM_Normal
, SM_Add
, SM_Toggle
};
232 void SetSelectionMode (const SelectionMode eSelectionMode
);
233 void SetSelectionModeFromModifier (const sal_uInt32 nEventCode
);
236 virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
237 virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
238 virtual bool HandleUnprocessedEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
241 SelectionMode meSelectionMode
;
242 Point maSecondCorner
;
243 PointerStyle maSavedPointer
;
244 bool mbAutoScrollInstalled
;
245 sal_Int32 mnAnchorIndex
;
246 sal_Int32 mnSecondIndex
;
248 void UpdateModelPosition (const Point
& rMouseModelPosition
);
249 void UpdateSelection();
251 /** Update the rectangle selection so that the given position becomes
252 the new second point of the selection rectangle.
254 void UpdatePosition (
255 const Point
& rMousePosition
,
256 const bool bAllowAutoScroll
);
258 void UpdateSelectionState (
259 const model::SharedPageDescriptor
& rpDescriptor
,
260 const bool bIsInSelection
) const;
263 /** Handle events during drag-and-drop.
265 class DragAndDropModeHandler
: public SelectionFunction::ModeHandler
268 DragAndDropModeHandler (
269 SlideSorter
& rSlideSorter
,
270 SelectionFunction
& rSelectionFunction
,
271 const Point
& rMousePosition
,
272 vcl::Window
* pWindow
);
273 virtual ~DragAndDropModeHandler() override
;
275 virtual SelectionFunction::Mode
GetMode() const override
;
276 virtual void Abort() override
;
279 virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
280 virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor
& rDescriptor
) override
;
283 std::unique_ptr
<DragAndDropContext
, o3tl::default_delete
<DragAndDropContext
>> mpDragAndDropContext
;
288 //===== SelectionFunction =====================================================
291 SelectionFunction::SelectionFunction (
292 SlideSorter
& rSlideSorter
,
293 SfxRequest
& rRequest
)
295 rSlideSorter
.GetViewShell(),
296 rSlideSorter
.GetContentWindow(),
297 &rSlideSorter
.GetView(),
298 rSlideSorter
.GetModel().GetDocument(),
300 mrSlideSorter(rSlideSorter
),
301 mrController(mrSlideSorter
.GetController()),
302 mnShiftKeySelectionAnchor(-1),
303 mpModeHandler(std::make_shared
<NormalModeHandler
>(rSlideSorter
, *this))
307 SelectionFunction::~SelectionFunction()
309 mpModeHandler
.reset();
312 rtl::Reference
<FuPoor
> SelectionFunction::Create(
313 SlideSorter
& rSlideSorter
,
314 SfxRequest
& rRequest
)
316 rtl::Reference
<FuPoor
> xFunc( new SelectionFunction( rSlideSorter
, rRequest
) );
320 bool SelectionFunction::MouseButtonDown (const MouseEvent
& rEvent
)
322 // remember button state for creation of own MouseEvents
323 SetMouseButtonCode (rEvent
.GetButtons());
324 aMDPos
= rEvent
.GetPosPixel();
326 // mpWindow->CaptureMouse();
328 ProcessMouseEvent(BUTTON_DOWN
, rEvent
);
333 bool SelectionFunction::MouseMove (const MouseEvent
& rEvent
)
335 ProcessMouseEvent(MOUSE_MOTION
, rEvent
);
339 bool SelectionFunction::MouseButtonUp (const MouseEvent
& rEvent
)
341 mrController
.GetScrollBarManager().StopAutoScroll ();
343 ProcessMouseEvent(BUTTON_UP
, rEvent
);
348 void SelectionFunction::NotifyDragFinished()
350 SwitchToNormalMode();
353 bool SelectionFunction::KeyInput (const KeyEvent
& rEvent
)
355 view::SlideSorterView::DrawLock
aDrawLock (mrSlideSorter
);
356 PageSelector::BroadcastLock
aBroadcastLock (mrSlideSorter
);
357 PageSelector::UpdateLock
aLock (mrSlideSorter
);
358 FocusManager
& rFocusManager (mrController
.GetFocusManager());
359 bool bResult
= false;
361 const vcl::KeyCode
& rCode (rEvent
.GetKeyCode());
362 switch (rCode
.GetCode())
366 model::SharedPageDescriptor
pDescriptor (rFocusManager
.GetFocusedPageDescriptor());
367 ViewShell
* pViewShell
= mrSlideSorter
.GetViewShell();
368 if (rFocusManager
.HasFocus() && pDescriptor
&& pViewShell
!=nullptr)
370 // The Return key triggers different functions depending on
371 // whether the slide sorter is the main view or displayed in
373 if (pViewShell
->IsMainViewShell())
375 mpModeHandler
->SetCurrentPage(pDescriptor
);
376 mpModeHandler
->SwitchView(pDescriptor
);
378 else if (pViewShell
->GetDispatcher() != nullptr)
380 // tdf#111737 - add new (master) page depending on the edit mode
381 pViewShell
->GetDispatcher()->Execute(
382 mrSlideSorter
.GetModel().GetEditMode() == EditMode::Page
384 : SID_INSERT_MASTER_PAGE
,
385 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
393 if ( ! rFocusManager
.IsFocusShowing())
395 rFocusManager
.ShowFocus();
401 // When there is an active multiselection or drag-and-drop
402 // operation then stop that.
403 mpModeHandler
->Abort();
404 SwitchToNormalMode();
410 // Toggle the selection state.
411 model::SharedPageDescriptor
pDescriptor (rFocusManager
.GetFocusedPageDescriptor());
412 if (pDescriptor
&& rCode
.IsMod1())
414 if (pDescriptor
->HasState(model::PageDescriptor::ST_Selected
))
415 mrController
.GetPageSelector().DeselectPage(pDescriptor
, false);
417 mrController
.GetPageSelector().SelectPage(pDescriptor
);
423 // Move the focus indicator left.
425 MoveFocus(FocusManager::FocusMoveDirection::Left
, rCode
.IsShift(), rCode
.IsMod1());
429 // Move the focus indicator right.
431 MoveFocus(FocusManager::FocusMoveDirection::Right
, rCode
.IsShift(), rCode
.IsMod1());
435 // Move the focus indicator up.
437 MoveFocus(FocusManager::FocusMoveDirection::Up
, rCode
.IsShift(), rCode
.IsMod1());
441 // Move the focus indicator down.
443 MoveFocus(FocusManager::FocusMoveDirection::Down
, rCode
.IsShift(), rCode
.IsMod1());
447 // Go to previous page. No wrap around.
453 // Go to next page. No wrap around...
465 GotoPage(mrSlideSorter
.GetModel().GetPageCount()-1);
472 mrController
.GetSelectionManager()->DeleteSelectedPages(rCode
.GetCode()==KEY_DELETE
);
474 mnShiftKeySelectionAnchor
= -1;
482 mpModeHandler
->SelectOnePage(
483 mrSlideSorter
.GetController().GetFocusManager().GetFocusedPageDescriptor());
492 bResult
= FuPoor::KeyInput(rEvent
);
497 void SelectionFunction::MoveFocus (
498 const FocusManager::FocusMoveDirection eDirection
,
499 const bool bIsShiftDown
,
500 const bool bIsControlDown
)
502 // Remember the anchor of shift key multi selection.
505 if (mnShiftKeySelectionAnchor
<0)
507 model::SharedPageDescriptor
pFocusedDescriptor (
508 mrController
.GetFocusManager().GetFocusedPageDescriptor());
509 mnShiftKeySelectionAnchor
= pFocusedDescriptor
->GetPageIndex();
512 else if ( ! bIsControlDown
)
513 ResetShiftKeySelectionAnchor();
515 mrController
.GetFocusManager().MoveFocus(eDirection
);
517 PageSelector
& rSelector (mrController
.GetPageSelector());
518 model::SharedPageDescriptor
pFocusedDescriptor (
519 mrController
.GetFocusManager().GetFocusedPageDescriptor());
522 // When shift is pressed then select all pages in the range between
523 // the currently and the previously focused pages, including them.
524 if (pFocusedDescriptor
)
526 sal_Int32
nPageRangeEnd (pFocusedDescriptor
->GetPageIndex());
527 model::PageEnumeration
aPages (
528 model::PageEnumerationProvider::CreateAllPagesEnumeration(
529 mrSlideSorter
.GetModel()));
530 while (aPages
.HasMoreElements())
532 model::SharedPageDescriptor
pDescriptor (aPages
.GetNextElement());
535 const sal_Int32
nPageIndex(pDescriptor
->GetPageIndex());
536 if ((nPageIndex
>=mnShiftKeySelectionAnchor
&& nPageIndex
<=nPageRangeEnd
)
537 || (nPageIndex
<=mnShiftKeySelectionAnchor
&& nPageIndex
>=nPageRangeEnd
))
539 rSelector
.SelectPage(pDescriptor
);
543 rSelector
.DeselectPage(pDescriptor
);
549 else if (bIsControlDown
)
551 // When control is pressed then do not alter the selection or the
552 // current page, just move the focus.
556 // Without shift just select the focused page.
557 mpModeHandler
->SelectOnePage(pFocusedDescriptor
);
561 void SelectionFunction::DoCut()
563 mrController
.GetClipboard().DoCut();
566 void SelectionFunction::DoCopy()
568 mrController
.GetClipboard().DoCopy();
571 void SelectionFunction::DoPaste()
573 mrController
.GetClipboard().DoPaste();
576 bool SelectionFunction::cancel()
578 mrController
.GetFocusManager().ToggleFocus();
582 void SelectionFunction::GotoNextPage (int nOffset
)
584 model::SharedPageDescriptor pDescriptor
585 = mrController
.GetCurrentSlideManager()->GetCurrentSlide();
588 SdPage
* pPage
= pDescriptor
->GetPage();
589 assert(pPage
!=nullptr);
590 sal_Int32 nIndex
= (pPage
->GetPageNum()-1) / 2;
591 GotoPage(nIndex
+ nOffset
);
593 ResetShiftKeySelectionAnchor();
596 void SelectionFunction::GotoPage (int nIndex
)
598 sal_uInt16 nPageCount
= static_cast<sal_uInt16
>(mrSlideSorter
.GetModel().GetPageCount());
600 if (nIndex
>= nPageCount
)
601 nIndex
= nPageCount
- 1;
605 mrController
.GetFocusManager().SetFocusedPage(nIndex
);
606 model::SharedPageDescriptor
pNextPageDescriptor (
607 mrSlideSorter
.GetModel().GetPageDescriptor (nIndex
));
608 if (pNextPageDescriptor
)
609 mpModeHandler
->SetCurrentPage(pNextPageDescriptor
);
612 OSL_ASSERT(pNextPageDescriptor
);
614 ResetShiftKeySelectionAnchor();
617 void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType
, const MouseEvent
& rEvent
)
619 // #95491# remember button state for creation of own MouseEvents
620 SetMouseButtonCode (rEvent
.GetButtons());
622 EventDescriptor
aEventDescriptor (nEventType
, rEvent
, mrSlideSorter
);
623 ProcessEvent(aEventDescriptor
);
626 void SelectionFunction::MouseDragged (
627 const AcceptDropEvent
& rEvent
,
628 const sal_Int8 nDragAction
)
630 EventDescriptor
aEventDescriptor (MOUSE_DRAG
, rEvent
, nDragAction
, mrSlideSorter
);
631 ProcessEvent(aEventDescriptor
);
634 void SelectionFunction::ProcessEvent (EventDescriptor
& rDescriptor
)
636 // The call to ProcessEvent may switch to another mode handler.
637 // Prevent the untimely destruction of the called handler by acquiring a
638 // temporary reference here.
639 std::shared_ptr
<ModeHandler
> pModeHandler (mpModeHandler
);
640 pModeHandler
->ProcessEvent(rDescriptor
);
644 const sal_uInt32 nEventCode
,
645 const sal_uInt32 nPositivePattern
)
647 return (nEventCode
& nPositivePattern
)==nPositivePattern
;
650 void SelectionFunction::SwitchToNormalMode()
652 if (mpModeHandler
->GetMode() != NormalMode
)
653 SwitchMode(std::make_shared
<NormalModeHandler
>(mrSlideSorter
, *this));
656 void SelectionFunction::SwitchToDragAndDropMode (const Point
& rMousePosition
)
658 if (mpModeHandler
->GetMode() == DragAndDropMode
)
661 SwitchMode(std::make_shared
<DragAndDropModeHandler
>(mrSlideSorter
, *this, rMousePosition
, mpWindow
));
664 void SelectionFunction::SwitchToMultiSelectionMode (
665 const Point
& rMousePosition
,
666 const sal_uInt32 nEventCode
)
668 if (mpModeHandler
->GetMode() != MultiSelectionMode
)
669 SwitchMode(std::make_shared
<MultiSelectionModeHandler
>(mrSlideSorter
, *this, rMousePosition
, nEventCode
));
672 void SelectionFunction::SwitchMode (const std::shared_ptr
<ModeHandler
>& rpHandler
)
674 // Not all modes allow mouse over indicator.
675 if (mpModeHandler
->IsMouseOverIndicatorAllowed() != rpHandler
->IsMouseOverIndicatorAllowed())
677 if ( ! rpHandler
->IsMouseOverIndicatorAllowed())
679 mrSlideSorter
.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
682 mrSlideSorter
.GetView().UpdatePageUnderMouse();
685 mpModeHandler
= rpHandler
;
688 void SelectionFunction::ResetShiftKeySelectionAnchor()
690 mnShiftKeySelectionAnchor
= -1;
693 void SelectionFunction::ResetMouseAnchor()
695 if (mpModeHandler
&& mpModeHandler
->GetMode() == NormalMode
)
697 std::shared_ptr
<NormalModeHandler
> pHandler (
698 std::dynamic_pointer_cast
<NormalModeHandler
>(mpModeHandler
));
700 pHandler
->ResetButtonDownLocation();
704 //===== EventDescriptor =======================================================
706 SelectionFunction::EventDescriptor::EventDescriptor (
707 const sal_uInt32 nEventType
,
708 const MouseEvent
& rEvent
,
709 SlideSorter
const & rSlideSorter
)
710 : maMousePosition(rEvent
.GetPosPixel()),
712 mnEventCode(nEventType
),
713 meDragMode(InsertionIndicatorHandler::MoveMode
),
716 maMouseModelPosition
= rSlideSorter
.GetContentWindow()->PixelToLogic(maMousePosition
);
717 mpHitDescriptor
= rSlideSorter
.GetController().GetPageAt(maMousePosition
);
720 mpHitPage
= mpHitDescriptor
->GetPage();
723 mnEventCode
|= EncodeMouseEvent(rEvent
);
724 mnEventCode
|= EncodeState();
726 // Detect the mouse leaving the window. When not button is pressed then
727 // we can call IsLeaveWindow at the event. Otherwise we have to make an
729 mbIsLeaving
= rEvent
.IsLeaveWindow()
730 || ! ::tools::Rectangle(Point(0,0),
731 rSlideSorter
.GetContentWindow()->GetOutputSizePixel()).Contains(maMousePosition
);
734 SelectionFunction::EventDescriptor::EventDescriptor (
735 const sal_uInt32 nEventType
,
736 const AcceptDropEvent
& rEvent
,
737 const sal_Int8 nDragAction
,
738 SlideSorter
const & rSlideSorter
)
739 : maMousePosition(rEvent
.maPosPixel
),
741 mnEventCode(nEventType
),
742 meDragMode(InsertionIndicatorHandler::GetModeFromDndAction(nDragAction
)),
745 maMouseModelPosition
= rSlideSorter
.GetContentWindow()->PixelToLogic(maMousePosition
);
746 mpHitDescriptor
= rSlideSorter
.GetController().GetPageAt(maMousePosition
);
749 mpHitPage
= mpHitDescriptor
->GetPage();
752 mnEventCode
|= EncodeState();
754 // Detect the mouse leaving the window. When not button is pressed then
755 // we can call IsLeaveWindow at the event. Otherwise we have to make an
757 mbIsLeaving
= rEvent
.mbLeaving
758 || ! ::tools::Rectangle(Point(0,0),
759 rSlideSorter
.GetContentWindow()->GetOutputSizePixel()).Contains(maMousePosition
);
762 sal_uInt32
SelectionFunction::EventDescriptor::EncodeMouseEvent (
763 const MouseEvent
& rEvent
) const
765 // Initialize with the type of mouse event.
766 sal_uInt32
nEventCode (mnEventCode
& (BUTTON_DOWN
| BUTTON_UP
| MOUSE_MOTION
));
768 // Detect the affected button.
769 switch (rEvent
.GetButtons())
771 case MOUSE_LEFT
: nEventCode
|= LEFT_BUTTON
; break;
772 case MOUSE_RIGHT
: nEventCode
|= RIGHT_BUTTON
; break;
773 case MOUSE_MIDDLE
: nEventCode
|= MIDDLE_BUTTON
; break;
776 // Detect the number of clicks.
777 switch (rEvent
.GetClicks())
779 case 1: nEventCode
|= SINGLE_CLICK
; break;
780 case 2: nEventCode
|= DOUBLE_CLICK
; break;
783 // Detect pressed modifier keys.
784 if (rEvent
.IsShift())
785 nEventCode
|= SHIFT_MODIFIER
;
787 nEventCode
|= CONTROL_MODIFIER
;
792 sal_uInt32
SelectionFunction::EventDescriptor::EncodeState() const
794 sal_uInt32
nEventCode (0);
796 // Detect whether the event has happened over a page object.
797 if (mpHitPage
!=nullptr && mpHitDescriptor
)
799 if (mpHitDescriptor
->HasState(model::PageDescriptor::ST_Selected
))
800 nEventCode
|= OVER_SELECTED_PAGE
;
802 nEventCode
|= OVER_UNSELECTED_PAGE
;
808 //===== SelectionFunction::ModeHandler ========================================
810 SelectionFunction::ModeHandler::ModeHandler (
811 SlideSorter
& rSlideSorter
,
812 SelectionFunction
& rSelectionFunction
,
813 const bool bIsMouseOverIndicatorAllowed
)
814 : mrSlideSorter(rSlideSorter
),
815 mrSelectionFunction(rSelectionFunction
),
816 mbIsMouseOverIndicatorAllowed(bIsMouseOverIndicatorAllowed
)
820 SelectionFunction::ModeHandler::~ModeHandler() COVERITY_NOEXCEPT_FALSE
824 void SelectionFunction::ModeHandler::ReprocessEvent (EventDescriptor
& rDescriptor
)
826 mrSelectionFunction
.ProcessEvent(rDescriptor
);
829 void SelectionFunction::ModeHandler::ProcessEvent (
830 SelectionFunction::EventDescriptor
& rDescriptor
)
832 PageSelector::BroadcastLock
aBroadcastLock (mrSlideSorter
);
833 PageSelector::UpdateLock
aUpdateLock (mrSlideSorter
);
835 bool bIsProcessed (false);
836 switch (rDescriptor
.mnEventCode
& (BUTTON_DOWN
| BUTTON_UP
| MOUSE_MOTION
| MOUSE_DRAG
))
839 bIsProcessed
= ProcessButtonDownEvent(rDescriptor
);
843 bIsProcessed
= ProcessButtonUpEvent(rDescriptor
);
847 bIsProcessed
= ProcessMotionEvent(rDescriptor
);
851 bIsProcessed
= ProcessDragEvent(rDescriptor
);
856 HandleUnprocessedEvent(rDescriptor
);
859 bool SelectionFunction::ModeHandler::ProcessButtonDownEvent (EventDescriptor
&)
864 bool SelectionFunction::ModeHandler::ProcessButtonUpEvent (EventDescriptor
&)
866 mrSelectionFunction
.SwitchToNormalMode();
870 bool SelectionFunction::ModeHandler::ProcessMotionEvent (EventDescriptor
& rDescriptor
)
872 if (mbIsMouseOverIndicatorAllowed
)
873 mrSlideSorter
.GetView().UpdatePageUnderMouse(rDescriptor
.maMousePosition
);
875 if (rDescriptor
.mbIsLeaving
)
877 mrSelectionFunction
.SwitchToNormalMode();
878 mrSlideSorter
.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
886 bool SelectionFunction::ModeHandler::ProcessDragEvent (EventDescriptor
&)
891 bool SelectionFunction::ModeHandler::HandleUnprocessedEvent (EventDescriptor
&)
896 void SelectionFunction::ModeHandler::SetCurrentPage (
897 const model::SharedPageDescriptor
& rpDescriptor
)
899 SelectOnePage(rpDescriptor
);
900 mrSlideSorter
.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor
);
903 void SelectionFunction::ModeHandler::DeselectAllPages()
905 mrSlideSorter
.GetController().GetPageSelector().DeselectAllPages();
906 mrSelectionFunction
.ResetShiftKeySelectionAnchor();
909 void SelectionFunction::ModeHandler::SelectOnePage (
910 const model::SharedPageDescriptor
& rpDescriptor
)
913 mrSlideSorter
.GetController().GetPageSelector().SelectPage(rpDescriptor
);
916 void SelectionFunction::ModeHandler::SwitchView (const model::SharedPageDescriptor
& rpDescriptor
)
918 // Switch to the draw view. This is done only when the current
919 // view is the main view.
920 ViewShell
* pViewShell
= mrSlideSorter
.GetViewShell();
921 if (pViewShell
==nullptr || !pViewShell
->IsMainViewShell())
924 if (rpDescriptor
&& rpDescriptor
->GetPage()!=nullptr)
926 mrSlideSorter
.GetModel().GetDocument()->SetSelected(rpDescriptor
->GetPage(), true);
927 pViewShell
->GetFrameView()->SetSelectedPage(
928 (rpDescriptor
->GetPage()->GetPageNum()-1)/2);
930 if (mrSlideSorter
.GetViewShellBase() != nullptr)
931 framework::FrameworkHelper::Instance(*mrSlideSorter
.GetViewShellBase())->RequestView(
932 framework::FrameworkHelper::msImpressViewURL
,
933 framework::FrameworkHelper::msCenterPaneURL
);
936 void SelectionFunction::ModeHandler::StartDrag (
937 const Point
& rMousePosition
)
939 // Do not start a drag-and-drop operation when one is already active.
940 // (when dragging pages from one document into another, pressing a
941 // modifier key can trigger a MouseMotion event in the originating
942 // window (focus still in there). Together with the mouse button pressed
943 // (drag-and-drop is active) this triggers the start of drag-and-drop.)
944 if (SdModule::get()->pTransferDrag
!= nullptr)
947 mrSelectionFunction
.SwitchToDragAndDropMode(rMousePosition
);
950 //===== NormalModeHandler =====================================================
952 NormalModeHandler::NormalModeHandler (
953 SlideSorter
& rSlideSorter
,
954 SelectionFunction
& rSelectionFunction
)
955 : ModeHandler(rSlideSorter
, rSelectionFunction
, true)
959 SelectionFunction::Mode
NormalModeHandler::GetMode() const
961 return SelectionFunction::NormalMode
;
964 void NormalModeHandler::Abort()
968 bool NormalModeHandler::ProcessButtonDownEvent (
969 SelectionFunction::EventDescriptor
& rDescriptor
)
971 // Remember the location where the left button is pressed. With
972 // that we can filter away motion events that are caused by key
973 // presses. We also can tune the minimal motion distance that
974 // triggers a drag-and-drop operation.
975 if ((rDescriptor
.mnEventCode
& BUTTON_DOWN
) != 0)
976 maButtonDownLocation
= rDescriptor
.maMousePosition
;
978 switch (rDescriptor
.mnEventCode
)
980 case BUTTON_DOWN
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_SELECTED_PAGE
:
983 case BUTTON_DOWN
| LEFT_BUTTON
| DOUBLE_CLICK
| OVER_SELECTED_PAGE
:
984 case BUTTON_DOWN
| LEFT_BUTTON
| DOUBLE_CLICK
| OVER_UNSELECTED_PAGE
:
985 // A double click always shows the selected slide in the center
986 // pane in an edit view.
987 SetCurrentPage(rDescriptor
.mpHitDescriptor
);
988 SwitchView(rDescriptor
.mpHitDescriptor
);
991 case BUTTON_DOWN
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_SELECTED_PAGE
| SHIFT_MODIFIER
:
992 case BUTTON_DOWN
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_UNSELECTED_PAGE
| SHIFT_MODIFIER
:
993 // Range selection with the shift modifier.
994 RangeSelect(rDescriptor
.mpHitDescriptor
);
997 // Right button for context menu.
998 case BUTTON_DOWN
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_UNSELECTED_PAGE
:
999 case BUTTON_DOWN
| RIGHT_BUTTON
| SINGLE_CLICK
| OVER_UNSELECTED_PAGE
:
1000 // Single right click and shift+F10 select as preparation to
1001 // show the context menu. Change the selection only when the
1002 // page under the mouse is not selected. In this case the
1003 // selection is set to this single page. Otherwise the
1004 // selection is not modified.
1005 SetCurrentPage(rDescriptor
.mpHitDescriptor
);
1008 case BUTTON_DOWN
| RIGHT_BUTTON
| SINGLE_CLICK
| OVER_SELECTED_PAGE
:
1009 // Do not change the selection. Just adjust the insertion indicator.
1012 case BUTTON_DOWN
| RIGHT_BUTTON
| SINGLE_CLICK
| NOT_OVER_PAGE
:
1013 case ANY_MODIFIER(BUTTON_DOWN
| LEFT_BUTTON
| SINGLE_CLICK
| NOT_OVER_PAGE
):
1014 // Remember the current selection so that when a multi selection
1015 // is started, we can restore the previous selection.
1016 mrSlideSorter
.GetModel().SaveCurrentSelection();
1020 case BUTTON_DOWN
| LEFT_BUTTON
| DOUBLE_CLICK
| NOT_OVER_PAGE
:
1022 // Insert a new slide:
1023 // First of all we need to set the insertion indicator which sets the
1024 // position where the new slide will be inserted.
1025 std::shared_ptr
<InsertionIndicatorHandler
> pInsertionIndicatorHandler
1026 = mrSlideSorter
.GetController().GetInsertionIndicatorHandler();
1028 pInsertionIndicatorHandler
->Start(false);
1029 pInsertionIndicatorHandler
->UpdatePosition(
1030 rDescriptor
.maMousePosition
,
1031 InsertionIndicatorHandler::MoveMode
);
1033 mrSlideSorter
.GetController().GetSelectionManager()->SetInsertionPosition(
1034 pInsertionIndicatorHandler
->GetInsertionPageIndex());
1036 mrSlideSorter
.GetViewShell()->GetDispatcher()->Execute(
1038 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
1040 pInsertionIndicatorHandler
->End(Animator::AM_Immediate
);
1051 bool NormalModeHandler::ProcessButtonUpEvent (
1052 SelectionFunction::EventDescriptor
& rDescriptor
)
1054 bool bIsProcessed (true);
1055 switch (rDescriptor
.mnEventCode
)
1057 case BUTTON_UP
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_SELECTED_PAGE
:
1058 SetCurrentPage(rDescriptor
.mpHitDescriptor
);
1061 // Multi selection with the control modifier.
1062 case BUTTON_UP
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_SELECTED_PAGE
| CONTROL_MODIFIER
:
1063 mrSlideSorter
.GetController().GetPageSelector().DeselectPage(
1064 rDescriptor
.mpHitDescriptor
);
1067 case BUTTON_UP
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_UNSELECTED_PAGE
| CONTROL_MODIFIER
:
1068 mrSlideSorter
.GetController().GetPageSelector().SelectPage(
1069 rDescriptor
.mpHitDescriptor
);
1070 mrSlideSorter
.GetView().SetPageUnderMouse(rDescriptor
.mpHitDescriptor
);
1072 case BUTTON_UP
| LEFT_BUTTON
| SINGLE_CLICK
| NOT_OVER_PAGE
:
1076 bIsProcessed
= false;
1079 mrSelectionFunction
.SwitchToNormalMode();
1080 return bIsProcessed
;
1083 bool NormalModeHandler::ProcessMotionEvent (
1084 SelectionFunction::EventDescriptor
& rDescriptor
)
1086 if (ModeHandler::ProcessMotionEvent(rDescriptor
))
1089 bool bIsProcessed (true);
1090 switch (rDescriptor
.mnEventCode
)
1092 // A mouse motion without visible substitution starts that.
1093 case ANY_MODIFIER(MOUSE_MOTION
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_UNSELECTED_PAGE
):
1094 case ANY_MODIFIER(MOUSE_MOTION
| LEFT_BUTTON
| SINGLE_CLICK
| OVER_SELECTED_PAGE
):
1096 if (maButtonDownLocation
)
1098 const sal_Int32
nDistance(std::max(
1099 std::abs(maButtonDownLocation
->X() - rDescriptor
.maMousePosition
.X()),
1100 std::abs(maButtonDownLocation
->Y() - rDescriptor
.maMousePosition
.Y())));
1102 StartDrag(rDescriptor
.maMousePosition
);
1107 // A mouse motion not over a page starts a rectangle selection.
1108 case ANY_MODIFIER(MOUSE_MOTION
| LEFT_BUTTON
| SINGLE_CLICK
| NOT_OVER_PAGE
):
1109 mrSelectionFunction
.SwitchToMultiSelectionMode(
1110 rDescriptor
.maMouseModelPosition
,
1111 rDescriptor
.mnEventCode
);
1115 bIsProcessed
= false;
1118 return bIsProcessed
;
1121 bool NormalModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor
& rDescriptor
)
1123 mrSelectionFunction
.SwitchToDragAndDropMode(rDescriptor
.maMousePosition
);
1124 ReprocessEvent(rDescriptor
);
1128 void NormalModeHandler::RangeSelect (const model::SharedPageDescriptor
& rpDescriptor
)
1130 PageSelector::UpdateLock
aLock (mrSlideSorter
);
1131 PageSelector
& rSelector (mrSlideSorter
.GetController().GetPageSelector());
1133 model::SharedPageDescriptor
pAnchor (rSelector
.GetSelectionAnchor());
1139 // Select all pages between the anchor and the given one, including
1141 const sal_uInt16
nAnchorIndex ((pAnchor
->GetPage()->GetPageNum()-1) / 2);
1142 const sal_uInt16
nOtherIndex ((rpDescriptor
->GetPage()->GetPageNum()-1) / 2);
1144 // Iterate over all pages in the range. Start with the anchor
1145 // page. This way the PageSelector will recognize it again as
1146 // anchor (the first selected page after a DeselectAllPages()
1147 // becomes the anchor.)
1148 const sal_Int16
nStep ((nAnchorIndex
< nOtherIndex
) ? +1 : -1);
1149 sal_uInt16
nIndex (nAnchorIndex
);
1152 rSelector
.SelectPage(nIndex
);
1153 if (nIndex
== nOtherIndex
)
1155 nIndex
= nIndex
+ nStep
;
1159 void NormalModeHandler::ResetButtonDownLocation()
1161 maButtonDownLocation
= ::std::optional
<Point
>();
1164 //===== MultiSelectionModeHandler =============================================
1166 MultiSelectionModeHandler::MultiSelectionModeHandler (
1167 SlideSorter
& rSlideSorter
,
1168 SelectionFunction
& rSelectionFunction
,
1169 const Point
& rMouseModelPosition
,
1170 const sal_uInt32 nEventCode
)
1171 : ModeHandler(rSlideSorter
, rSelectionFunction
, false),
1172 meSelectionMode(SM_Normal
),
1173 maSecondCorner(rMouseModelPosition
),
1174 maSavedPointer(mrSlideSorter
.GetContentWindow()->GetPointer()),
1175 mbAutoScrollInstalled(false),
1180 mrSlideSorter
.GetContentWindow()->SetPointer(PointerStyle::Text
);
1181 SetSelectionModeFromModifier(nEventCode
);
1184 MultiSelectionModeHandler::~MultiSelectionModeHandler()
1186 if (mbAutoScrollInstalled
)
1188 //a call to this handler's MultiSelectionModeHandler::UpdatePosition
1189 //may be still waiting to be called back
1190 mrSlideSorter
.GetController().GetScrollBarManager().clearAutoScrollFunctor();
1192 mrSlideSorter
.GetContentWindow()->SetPointer(maSavedPointer
);
1195 SelectionFunction::Mode
MultiSelectionModeHandler::GetMode() const
1197 return SelectionFunction::MultiSelectionMode
;
1200 void MultiSelectionModeHandler::Abort()
1202 mrSlideSorter
.GetView().RequestRepaint(mrSlideSorter
.GetModel().RestoreSelection());
1205 void MultiSelectionModeHandler::ProcessEvent (
1206 SelectionFunction::EventDescriptor
& rDescriptor
)
1208 // During a multi selection we do not want sudden jumps of the
1209 // visible area caused by moving newly selected pages into view.
1210 // Therefore disable that temporarily. The disabled object is
1211 // released at the end of the event processing, after the focus and
1212 // current slide have been updated.
1213 VisibleAreaManager::TemporaryDisabler
aDisabler (mrSlideSorter
);
1215 ModeHandler::ProcessEvent(rDescriptor
);
1218 bool MultiSelectionModeHandler::ProcessButtonUpEvent (
1219 SelectionFunction::EventDescriptor
& rDescriptor
)
1221 if (mbAutoScrollInstalled
)
1223 //a call to this handler's MultiSelectionModeHandler::UpdatePosition
1224 //may be still waiting to be called back
1225 mrSlideSorter
.GetController().GetScrollBarManager().clearAutoScrollFunctor();
1226 mbAutoScrollInstalled
= false;
1229 if (Match(rDescriptor
.mnEventCode
, BUTTON_UP
| LEFT_BUTTON
| SINGLE_CLICK
))
1231 mrSelectionFunction
.SwitchToNormalMode();
1238 bool MultiSelectionModeHandler::ProcessMotionEvent (
1239 SelectionFunction::EventDescriptor
& rDescriptor
)
1241 // The selection rectangle is visible. Handle events accordingly.
1242 if (Match(rDescriptor
.mnEventCode
, MOUSE_MOTION
| LEFT_BUTTON
| SINGLE_CLICK
))
1244 SetSelectionModeFromModifier(rDescriptor
.mnEventCode
);
1245 UpdatePosition(rDescriptor
.maMousePosition
, true);
1252 bool MultiSelectionModeHandler::HandleUnprocessedEvent (
1253 SelectionFunction::EventDescriptor
& rDescriptor
)
1255 if ( ! ModeHandler::HandleUnprocessedEvent(rDescriptor
))
1257 // If the event has not been processed then stop multi selection.
1258 mrSelectionFunction
.SwitchToNormalMode();
1259 ReprocessEvent(rDescriptor
);
1264 void MultiSelectionModeHandler::UpdatePosition (
1265 const Point
& rMousePosition
,
1266 const bool bAllowAutoScroll
)
1268 VisibleAreaManager::TemporaryDisabler
aDisabler (mrSlideSorter
);
1270 // Convert window coordinates into model coordinates (we need the
1271 // window coordinates for auto-scrolling because that remains
1272 // constant while scrolling.)
1273 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
1274 const Point
aMouseModelPosition (pWindow
->PixelToLogic(rMousePosition
));
1276 bool bDoAutoScroll
= bAllowAutoScroll
&& mrSlideSorter
.GetController().GetScrollBarManager().AutoScroll(
1278 [this, &rMousePosition
] () { return this->UpdatePosition(rMousePosition
, false); });
1281 UpdateModelPosition(aMouseModelPosition
);
1283 mbAutoScrollInstalled
|= bDoAutoScroll
;
1286 void MultiSelectionModeHandler::SetSelectionModeFromModifier (
1287 const sal_uInt32 nEventCode
)
1289 switch (nEventCode
& MODIFIER_MASK
)
1292 SetSelectionMode(SM_Normal
);
1295 case SHIFT_MODIFIER
:
1296 SetSelectionMode(SM_Add
);
1299 case CONTROL_MODIFIER
:
1300 SetSelectionMode(SM_Toggle
);
1305 void MultiSelectionModeHandler::SetSelectionMode (const SelectionMode eSelectionMode
)
1307 if (meSelectionMode
!= eSelectionMode
)
1309 meSelectionMode
= eSelectionMode
;
1314 void MultiSelectionModeHandler::UpdateSelectionState (
1315 const model::SharedPageDescriptor
& rpDescriptor
,
1316 const bool bIsInSelection
) const
1318 // Determine whether the page was selected before the rectangle
1319 // selection was started.
1320 const bool bWasSelected (rpDescriptor
->HasState(model::PageDescriptor::ST_WasSelected
));
1322 // Combine the two selection states depending on the selection mode.
1323 bool bSelect (false);
1324 switch(meSelectionMode
)
1327 bSelect
= bIsInSelection
;
1331 bSelect
= bIsInSelection
|| bWasSelected
;
1336 bSelect
= !bWasSelected
;
1338 bSelect
= bWasSelected
;
1342 // Set the new selection state.
1344 mrSlideSorter
.GetController().GetPageSelector().SelectPage(rpDescriptor
);
1346 mrSlideSorter
.GetController().GetPageSelector().DeselectPage(rpDescriptor
);
1349 void MultiSelectionModeHandler::UpdateModelPosition (const Point
& rMouseModelPosition
)
1351 maSecondCorner
= rMouseModelPosition
;
1355 void MultiSelectionModeHandler::UpdateSelection()
1357 view::SlideSorterView::DrawLock
aLock (mrSlideSorter
);
1359 model::SlideSorterModel
& rModel (mrSlideSorter
.GetModel());
1360 const sal_Int32
nPageCount (rModel
.GetPageCount());
1362 const sal_Int32
nIndexUnderMouse (
1363 mrSlideSorter
.GetView().GetLayouter().GetIndexAtPoint (
1367 if (nIndexUnderMouse
< 0 || nIndexUnderMouse
>= nPageCount
)
1370 if (mnAnchorIndex
< 0)
1371 mnAnchorIndex
= nIndexUnderMouse
;
1372 mnSecondIndex
= nIndexUnderMouse
;
1374 Range
aRange (mnAnchorIndex
, mnSecondIndex
);
1377 for (sal_Int32 nIndex
=0; nIndex
<nPageCount
; ++nIndex
)
1379 UpdateSelectionState(rModel
.GetPageDescriptor(nIndex
), aRange
.Contains(nIndex
));
1383 //===== DragAndDropModeHandler ================================================
1385 DragAndDropModeHandler::DragAndDropModeHandler (
1386 SlideSorter
& rSlideSorter
,
1387 SelectionFunction
& rSelectionFunction
,
1388 const Point
& rMousePosition
,
1389 vcl::Window
* pWindow
)
1390 : ModeHandler(rSlideSorter
, rSelectionFunction
, false)
1392 SdModule
* mod
= SdModule::get();
1393 SdTransferable
* pDragTransferable
= mod
->pTransferDrag
;
1394 if (pDragTransferable
==nullptr && mrSlideSorter
.GetViewShell() != nullptr)
1396 SlideSorterViewShell
* pSlideSorterViewShell
1397 = dynamic_cast<SlideSorterViewShell
*>(mrSlideSorter
.GetViewShell());
1398 if (pSlideSorterViewShell
!= nullptr)
1399 pSlideSorterViewShell
->StartDrag(rMousePosition
, pWindow
);
1400 pDragTransferable
= mod
->pTransferDrag
;
1403 mpDragAndDropContext
.reset(new DragAndDropContext(mrSlideSorter
));
1404 mrSlideSorter
.GetController().GetInsertionIndicatorHandler()->Start(
1405 pDragTransferable
!= nullptr
1406 && pDragTransferable
->GetView()==&mrSlideSorter
.GetView());
1409 DragAndDropModeHandler::~DragAndDropModeHandler()
1411 if (mpDragAndDropContext
)
1413 // Disconnect the substitution handler from this selection function.
1414 mpDragAndDropContext
->SetTargetSlideSorter();
1415 mpDragAndDropContext
.reset();
1417 mrSlideSorter
.GetController().GetInsertionIndicatorHandler()->End(Animator::AM_Animated
);
1420 SelectionFunction::Mode
DragAndDropModeHandler::GetMode() const
1422 return SelectionFunction::DragAndDropMode
;
1425 void DragAndDropModeHandler::Abort()
1427 mrSlideSorter
.GetController().GetClipboard().Abort();
1428 if (mpDragAndDropContext
)
1429 mpDragAndDropContext
->Dispose();
1430 // mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection());
1433 bool DragAndDropModeHandler::ProcessButtonUpEvent (
1434 SelectionFunction::EventDescriptor
& rDescriptor
)
1436 if (Match(rDescriptor
.mnEventCode
, BUTTON_UP
| LEFT_BUTTON
))
1438 // The following Process() call may lead to the destruction
1439 // of rDescriptor.mpHitDescriptor so release our reference to it.
1440 rDescriptor
.mpHitDescriptor
.reset();
1441 mrSelectionFunction
.SwitchToNormalMode();
1448 bool DragAndDropModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor
& rDescriptor
)
1450 OSL_ASSERT(mpDragAndDropContext
);
1452 if (rDescriptor
.mbIsLeaving
)
1454 mrSelectionFunction
.SwitchToNormalMode();
1456 else if (mpDragAndDropContext
)
1458 mpDragAndDropContext
->UpdatePosition(
1459 rDescriptor
.maMousePosition
,
1460 rDescriptor
.meDragMode
, true);
1466 } // end of namespace ::sd::slidesorter::controller
1468 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */