LibreOffice Module sd (master) 1
SlsSelectionFunction.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <memory>
21#include <sal/config.h>
22
24
25#include <SlideSorter.hxx>
42#include <view/SlsLayouter.hxx>
44#include <osl/diagnose.h>
45#include <Window.hxx>
46#include <sdpage.hxx>
47#include <drawdoc.hxx>
48#include <sdxfer.hxx>
49#include <ViewShell.hxx>
50#include <FrameView.hxx>
51#include <app.hrc>
52#include <o3tl/deleter.hxx>
53#include <sfx2/dispatch.hxx>
54#include <vcl/ptrstyle.hxx>
55#include <optional>
56#include <sdmod.hxx>
57
58namespace {
59const sal_uInt32 SINGLE_CLICK (0x00000001);
60const sal_uInt32 DOUBLE_CLICK (0x00000002);
61const sal_uInt32 LEFT_BUTTON (0x00000010);
62const sal_uInt32 RIGHT_BUTTON (0x00000020);
63const sal_uInt32 MIDDLE_BUTTON (0x00000040);
64const sal_uInt32 BUTTON_DOWN (0x00000100);
65const sal_uInt32 BUTTON_UP (0x00000200);
66const sal_uInt32 MOUSE_MOTION (0x00000400);
67const sal_uInt32 MOUSE_DRAG (0x00000800);
68// The rest leaves the lower 16 bit untouched so that it can be used with
69// key codes.
70const sal_uInt32 OVER_SELECTED_PAGE (0x00010000);
71const sal_uInt32 OVER_UNSELECTED_PAGE (0x00020000);
72const sal_uInt32 SHIFT_MODIFIER (0x00200000);
73const sal_uInt32 CONTROL_MODIFIER (0x00400000);
74
75// Some absent events are defined so they can be expressed explicitly.
76const sal_uInt32 NO_MODIFIER (0x00000000);
77const sal_uInt32 NOT_OVER_PAGE (0x00000000);
78
79// Masks
80const sal_uInt32 MODIFIER_MASK (SHIFT_MODIFIER | CONTROL_MODIFIER);
81
82} // end of anonymous namespace
83
84// Define some macros to make the following switch statement more readable.
85#define ANY_MODIFIER(code) \
86 code|NO_MODIFIER: \
87 case code|SHIFT_MODIFIER: \
88 case code|CONTROL_MODIFIER
89
91
92//===== SelectionFunction::EventDescriptor ====================================
93
95{
96public:
101 sal_uInt32 mnEventCode;
104
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);
114
115private:
119 sal_uInt32 EncodeMouseEvent (const MouseEvent& rEvent) const;
120
125 sal_uInt32 EncodeState() const;
126};
127
128//===== SelectionFunction::ModeHandler ========================================
129
131{
132public:
134 SlideSorter& rSlideSorter,
135 SelectionFunction& rSelectionFunction,
136 const bool bIsMouseOverIndicatorAllowed);
137 virtual ~ModeHandler() COVERITY_NOEXCEPT_FALSE;
138
139 virtual Mode GetMode() const = 0;
140 virtual void Abort() = 0;
141 virtual void ProcessEvent (EventDescriptor& rDescriptor);
142
146 void SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor);
147
149 void DeselectAllPages();
150 void SelectOnePage (const model::SharedPageDescriptor& rpDescriptor);
151
155 void SwitchView (const model::SharedPageDescriptor& rpDescriptor);
156
157 void StartDrag (
158 const Point& rMousePosition);
159
161
162protected:
165
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);
171
172 void ReprocessEvent (EventDescriptor& rDescriptor);
173
174private:
176};
177
178namespace {
179
183class NormalModeHandler : public SelectionFunction::ModeHandler
184{
185public:
186 NormalModeHandler (
187 SlideSorter& rSlideSorter,
188 SelectionFunction& rSelectionFunction);
189
190 virtual SelectionFunction::Mode GetMode() const override;
191 virtual void Abort() override;
192
193 void ResetButtonDownLocation();
194
195protected:
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;
200
201private:
202 ::std::optional<Point> maButtonDownLocation;
203
207 void RangeSelect (const model::SharedPageDescriptor& rpDescriptor);
208};
209
213class MultiSelectionModeHandler : public SelectionFunction::ModeHandler
214{
215public:
218 MultiSelectionModeHandler (
219 SlideSorter& rSlideSorter,
220 SelectionFunction& rSelectionFunction,
221 const Point& rMouseModelPosition,
222 const sal_uInt32 nEventCode);
223
224 virtual ~MultiSelectionModeHandler() override;
225
226 virtual SelectionFunction::Mode GetMode() const override;
227 virtual void Abort() override;
228 virtual void ProcessEvent (SelectionFunction::EventDescriptor& rDescriptor) override;
229
230 enum SelectionMode { SM_Normal, SM_Add, SM_Toggle };
231
232 void SetSelectionMode (const SelectionMode eSelectionMode);
233 void SetSelectionModeFromModifier (const sal_uInt32 nEventCode);
234
235protected:
236 virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor) override;
237 virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor) override;
238 virtual bool HandleUnprocessedEvent (SelectionFunction::EventDescriptor& rDescriptor) override;
239
240private:
245 sal_Int32 mnAnchorIndex;
246 sal_Int32 mnSecondIndex;
247
248 void UpdateModelPosition (const Point& rMouseModelPosition);
249 void UpdateSelection();
250
254 void UpdatePosition (
255 const Point& rMousePosition,
256 const bool bAllowAutoScroll);
257
258 void UpdateSelectionState (
259 const model::SharedPageDescriptor& rpDescriptor,
260 const bool bIsInSelection) const;
261};
262
265class DragAndDropModeHandler : public SelectionFunction::ModeHandler
266{
267public:
268 DragAndDropModeHandler (
269 SlideSorter& rSlideSorter,
270 SelectionFunction& rSelectionFunction,
271 const Point& rMousePosition,
272 vcl::Window* pWindow);
273 virtual ~DragAndDropModeHandler() override;
274
275 virtual SelectionFunction::Mode GetMode() const override;
276 virtual void Abort() override;
277
278protected:
279 virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor) override;
280 virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor) override;
281
282private:
283 std::unique_ptr<DragAndDropContext, o3tl::default_delete<DragAndDropContext>> mpDragAndDropContext;
284};
285
286}
287
288//===== SelectionFunction =====================================================
289
290
292 SlideSorter& rSlideSorter,
293 SfxRequest& rRequest)
294 : FuPoor (
295 rSlideSorter.GetViewShell(),
296 rSlideSorter.GetContentWindow(),
297 &rSlideSorter.GetView(),
298 rSlideSorter.GetModel().GetDocument(),
299 rRequest),
300 mrSlideSorter(rSlideSorter),
302 mnShiftKeySelectionAnchor(-1),
303 mpModeHandler(std::make_shared<NormalModeHandler>(rSlideSorter, *this))
304{
305}
306
308{
309 mpModeHandler.reset();
310}
311
313 SlideSorter& rSlideSorter,
314 SfxRequest& rRequest)
315{
316 rtl::Reference<FuPoor> xFunc( new SelectionFunction( rSlideSorter, rRequest ) );
317 return xFunc;
318}
319
321{
322 // remember button state for creation of own MouseEvents
324 aMDPos = rEvent.GetPosPixel();
325
326 // mpWindow->CaptureMouse();
327
328 ProcessMouseEvent(BUTTON_DOWN, rEvent);
329
330 return true;
331}
332
334{
335 ProcessMouseEvent(MOUSE_MOTION, rEvent);
336 return true;
337}
338
340{
342
343 ProcessMouseEvent(BUTTON_UP, rEvent);
344
345 return true;
346}
347
349{
351}
352
354{
358 FocusManager& rFocusManager (mrController.GetFocusManager());
359 bool bResult = false;
360
361 const vcl::KeyCode& rCode (rEvent.GetKeyCode());
362 switch (rCode.GetCode())
363 {
364 case KEY_RETURN:
365 {
366 model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
367 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
368 if (rFocusManager.HasFocus() && pDescriptor && pViewShell!=nullptr)
369 {
370 // The Return key triggers different functions depending on
371 // whether the slide sorter is the main view or displayed in
372 // the right pane.
373 if (pViewShell->IsMainViewShell())
374 {
375 mpModeHandler->SetCurrentPage(pDescriptor);
376 mpModeHandler->SwitchView(pDescriptor);
377 }
378 else if (pViewShell->GetDispatcher() != nullptr)
379 {
380 pViewShell->GetDispatcher()->Execute(
381 SID_INSERTPAGE,
382 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
383 }
384 bResult = true;
385 }
386 break;
387 }
388
389 case KEY_TAB:
390 if ( ! rFocusManager.IsFocusShowing())
391 {
392 rFocusManager.ShowFocus();
393 bResult = true;
394 }
395 break;
396
397 case KEY_ESCAPE:
398 // When there is an active multiselection or drag-and-drop
399 // operation then stop that.
400 mpModeHandler->Abort();
402 bResult = true;
403 break;
404
405 case KEY_SPACE:
406 {
407 // Toggle the selection state.
408 model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
409 if (pDescriptor && rCode.IsMod1())
410 {
411 if (pDescriptor->HasState(model::PageDescriptor::ST_Selected))
412 mrController.GetPageSelector().DeselectPage(pDescriptor, false);
413 else
415 }
416 bResult = true;
417 }
418 break;
419
420 // Move the focus indicator left.
421 case KEY_LEFT:
423 bResult = true;
424 break;
425
426 // Move the focus indicator right.
427 case KEY_RIGHT:
429 bResult = true;
430 break;
431
432 // Move the focus indicator up.
433 case KEY_UP:
435 bResult = true;
436 break;
437
438 // Move the focus indicator down.
439 case KEY_DOWN:
441 bResult = true;
442 break;
443
444 // Go to previous page. No wrap around.
445 case KEY_PAGEUP:
446 GotoNextPage(-1);
447 bResult = true;
448 break;
449
450 // Go to next page. No wrap around...
451 case KEY_PAGEDOWN:
452 GotoNextPage(+1);
453 bResult = true;
454 break;
455
456 case KEY_HOME:
457 GotoPage(0);
458 bResult = true;
459 break;
460
461 case KEY_END:
463 bResult = true;
464 break;
465
466 case KEY_DELETE:
467 case KEY_BACKSPACE:
468 {
469 mrController.GetSelectionManager()->DeleteSelectedPages(rCode.GetCode()==KEY_DELETE);
470
472 bResult = true;
473 }
474 break;
475
476 case KEY_F10:
477 if (rCode.IsShift())
478 {
479 mpModeHandler->SelectOnePage(
481 }
482 break;
483
484 default:
485 break;
486 }
487
488 if ( ! bResult)
489 bResult = FuPoor::KeyInput(rEvent);
490
491 return bResult;
492}
493
495 const FocusManager::FocusMoveDirection eDirection,
496 const bool bIsShiftDown,
497 const bool bIsControlDown)
498{
499 // Remember the anchor of shift key multi selection.
500 if (bIsShiftDown)
501 {
503 {
504 model::SharedPageDescriptor pFocusedDescriptor (
506 mnShiftKeySelectionAnchor = pFocusedDescriptor->GetPageIndex();
507 }
508 }
509 else if ( ! bIsControlDown)
511
513
515 model::SharedPageDescriptor pFocusedDescriptor (
517 if (bIsShiftDown)
518 {
519 // When shift is pressed then select all pages in the range between
520 // the currently and the previously focused pages, including them.
521 if (pFocusedDescriptor)
522 {
523 sal_Int32 nPageRangeEnd (pFocusedDescriptor->GetPageIndex());
527 while (aPages.HasMoreElements())
528 {
529 model::SharedPageDescriptor pDescriptor (aPages.GetNextElement());
530 if (pDescriptor)
531 {
532 const sal_Int32 nPageIndex(pDescriptor->GetPageIndex());
533 if ((nPageIndex>=mnShiftKeySelectionAnchor && nPageIndex<=nPageRangeEnd)
534 || (nPageIndex<=mnShiftKeySelectionAnchor && nPageIndex>=nPageRangeEnd))
535 {
536 rSelector.SelectPage(pDescriptor);
537 }
538 else
539 {
540 rSelector.DeselectPage(pDescriptor);
541 }
542 }
543 }
544 }
545 }
546 else if (bIsControlDown)
547 {
548 // When control is pressed then do not alter the selection or the
549 // current page, just move the focus.
550 }
551 else
552 {
553 // Without shift just select the focused page.
554 mpModeHandler->SelectOnePage(pFocusedDescriptor);
555 }
556}
557
559{
561}
562
564{
566}
567
569{
571}
572
574{
576 return true;
577}
578
580{
582 = mrController.GetCurrentSlideManager()->GetCurrentSlide();
583 if (pDescriptor)
584 {
585 SdPage* pPage = pDescriptor->GetPage();
586 OSL_ASSERT(pPage!=nullptr);
587 sal_Int32 nIndex = (pPage->GetPageNum()-1) / 2;
588 GotoPage(nIndex + nOffset);
589 }
591}
592
594{
595 sal_uInt16 nPageCount = static_cast<sal_uInt16>(mrSlideSorter.GetModel().GetPageCount());
596
597 if (nIndex >= nPageCount)
598 nIndex = nPageCount - 1;
599 if (nIndex < 0)
600 nIndex = 0;
601
603 model::SharedPageDescriptor pNextPageDescriptor (
605 if (pNextPageDescriptor)
606 mpModeHandler->SetCurrentPage(pNextPageDescriptor);
607 else
608 {
609 OSL_ASSERT(pNextPageDescriptor);
610 }
612}
613
614void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEvent& rEvent)
615{
616 // #95491# remember button state for creation of own MouseEvents
618
619 EventDescriptor aEventDescriptor (nEventType, rEvent, mrSlideSorter);
620 ProcessEvent(aEventDescriptor);
621}
622
624 const AcceptDropEvent& rEvent,
625 const sal_Int8 nDragAction)
626{
627 EventDescriptor aEventDescriptor (MOUSE_DRAG, rEvent, nDragAction, mrSlideSorter);
628 ProcessEvent(aEventDescriptor);
629}
630
632{
633 // The call to ProcessEvent may switch to another mode handler.
634 // Prevent the untimely destruction of the called handler by acquiring a
635 // temporary reference here.
636 std::shared_ptr<ModeHandler> pModeHandler (mpModeHandler);
637 pModeHandler->ProcessEvent(rDescriptor);
638}
639
640static bool Match (
641 const sal_uInt32 nEventCode,
642 const sal_uInt32 nPositivePattern)
643{
644 return (nEventCode & nPositivePattern)==nPositivePattern;
645}
646
648{
649 if (mpModeHandler->GetMode() != NormalMode)
650 SwitchMode(std::make_shared<NormalModeHandler>(mrSlideSorter, *this));
651}
652
654{
655 if (mpModeHandler->GetMode() == DragAndDropMode)
656 return;
657
658 SwitchMode(std::make_shared<DragAndDropModeHandler>(mrSlideSorter, *this, rMousePosition, mpWindow));
659}
660
662 const Point& rMousePosition,
663 const sal_uInt32 nEventCode)
664{
665 if (mpModeHandler->GetMode() != MultiSelectionMode)
666 SwitchMode(std::make_shared<MultiSelectionModeHandler>(mrSlideSorter, *this, rMousePosition, nEventCode));
667}
668
669void SelectionFunction::SwitchMode (const std::shared_ptr<ModeHandler>& rpHandler)
670{
671 // Not all modes allow mouse over indicator.
672 if (mpModeHandler->IsMouseOverIndicatorAllowed() != rpHandler->IsMouseOverIndicatorAllowed())
673 {
674 if ( ! rpHandler->IsMouseOverIndicatorAllowed())
675 {
677 }
678 else
680 }
681
682 mpModeHandler = rpHandler;
683}
684
686{
688}
689
691{
692 if (mpModeHandler && mpModeHandler->GetMode() == NormalMode)
693 {
694 std::shared_ptr<NormalModeHandler> pHandler (
695 std::dynamic_pointer_cast<NormalModeHandler>(mpModeHandler));
696 if (pHandler)
697 pHandler->ResetButtonDownLocation();
698 }
699}
700
701//===== EventDescriptor =======================================================
702
704 const sal_uInt32 nEventType,
705 const MouseEvent& rEvent,
706 SlideSorter const & rSlideSorter)
707 : maMousePosition(rEvent.GetPosPixel()),
708 mpHitPage(),
709 mnEventCode(nEventType),
710 meDragMode(InsertionIndicatorHandler::MoveMode),
711 mbIsLeaving(false)
712{
713 maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition);
715 if (mpHitDescriptor)
716 {
717 mpHitPage = mpHitDescriptor->GetPage();
718 }
719
720 mnEventCode |= EncodeMouseEvent(rEvent);
722
723 // Detect the mouse leaving the window. When not button is pressed then
724 // we can call IsLeaveWindow at the event. Otherwise we have to make an
725 // explicit test.
726 mbIsLeaving = rEvent.IsLeaveWindow()
727 || ! ::tools::Rectangle(Point(0,0),
728 rSlideSorter.GetContentWindow()->GetOutputSizePixel()).Contains(maMousePosition);
729}
730
732 const sal_uInt32 nEventType,
733 const AcceptDropEvent& rEvent,
734 const sal_Int8 nDragAction,
735 SlideSorter const & rSlideSorter)
736 : maMousePosition(rEvent.maPosPixel),
737 mpHitPage(),
738 mnEventCode(nEventType),
739 meDragMode(InsertionIndicatorHandler::GetModeFromDndAction(nDragAction)),
740 mbIsLeaving(false)
741{
742 maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition);
744 if (mpHitDescriptor)
745 {
746 mpHitPage = mpHitDescriptor->GetPage();
747 }
748
750
751 // Detect the mouse leaving the window. When not button is pressed then
752 // we can call IsLeaveWindow at the event. Otherwise we have to make an
753 // explicit test.
754 mbIsLeaving = rEvent.mbLeaving
755 || ! ::tools::Rectangle(Point(0,0),
756 rSlideSorter.GetContentWindow()->GetOutputSizePixel()).Contains(maMousePosition);
757}
758
760 const MouseEvent& rEvent) const
761{
762 // Initialize with the type of mouse event.
763 sal_uInt32 nEventCode (mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION));
764
765 // Detect the affected button.
766 switch (rEvent.GetButtons())
767 {
768 case MOUSE_LEFT: nEventCode |= LEFT_BUTTON; break;
769 case MOUSE_RIGHT: nEventCode |= RIGHT_BUTTON; break;
770 case MOUSE_MIDDLE: nEventCode |= MIDDLE_BUTTON; break;
771 }
772
773 // Detect the number of clicks.
774 switch (rEvent.GetClicks())
775 {
776 case 1: nEventCode |= SINGLE_CLICK; break;
777 case 2: nEventCode |= DOUBLE_CLICK; break;
778 }
779
780 // Detect pressed modifier keys.
781 if (rEvent.IsShift())
782 nEventCode |= SHIFT_MODIFIER;
783 if (rEvent.IsMod1())
784 nEventCode |= CONTROL_MODIFIER;
785
786 return nEventCode;
787}
788
790{
791 sal_uInt32 nEventCode (0);
792
793 // Detect whether the event has happened over a page object.
794 if (mpHitPage!=nullptr && mpHitDescriptor)
795 {
796 if (mpHitDescriptor->HasState(model::PageDescriptor::ST_Selected))
797 nEventCode |= OVER_SELECTED_PAGE;
798 else
799 nEventCode |= OVER_UNSELECTED_PAGE;
800 }
801
802 return nEventCode;
803}
804
805//===== SelectionFunction::ModeHandler ========================================
806
808 SlideSorter& rSlideSorter,
809 SelectionFunction& rSelectionFunction,
810 const bool bIsMouseOverIndicatorAllowed)
811 : mrSlideSorter(rSlideSorter),
812 mrSelectionFunction(rSelectionFunction),
813 mbIsMouseOverIndicatorAllowed(bIsMouseOverIndicatorAllowed)
814{
815}
816
818{
819}
820
822{
823 mrSelectionFunction.ProcessEvent(rDescriptor);
824}
825
828{
831
832 bool bIsProcessed (false);
833 switch (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION | MOUSE_DRAG))
834 {
835 case BUTTON_DOWN:
836 bIsProcessed = ProcessButtonDownEvent(rDescriptor);
837 break;
838
839 case BUTTON_UP:
840 bIsProcessed = ProcessButtonUpEvent(rDescriptor);
841 break;
842
843 case MOUSE_MOTION:
844 bIsProcessed = ProcessMotionEvent(rDescriptor);
845 break;
846
847 case MOUSE_DRAG:
848 bIsProcessed = ProcessDragEvent(rDescriptor);
849 break;
850 }
851
852 if ( ! bIsProcessed)
853 HandleUnprocessedEvent(rDescriptor);
854}
855
857{
858 return false;
859}
860
862{
863 mrSelectionFunction.SwitchToNormalMode();
864 return false;
865}
866
868{
869 if (mbIsMouseOverIndicatorAllowed)
871
872 if (rDescriptor.mbIsLeaving)
873 {
874 mrSelectionFunction.SwitchToNormalMode();
876
877 return true;
878 }
879 else
880 return false;
881}
882
884{
885 return false;
886}
887
889{
890 return false;
891}
892
894 const model::SharedPageDescriptor& rpDescriptor)
895{
896 SelectOnePage(rpDescriptor);
897 mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor);
898}
899
901{
903 mrSelectionFunction.ResetShiftKeySelectionAnchor();
904}
905
907 const model::SharedPageDescriptor& rpDescriptor)
908{
909 DeselectAllPages();
911}
912
914{
915 // Switch to the draw view. This is done only when the current
916 // view is the main view.
917 ViewShell* pViewShell = mrSlideSorter.GetViewShell();
918 if (pViewShell==nullptr || !pViewShell->IsMainViewShell())
919 return;
920
921 if (rpDescriptor && rpDescriptor->GetPage()!=nullptr)
922 {
923 mrSlideSorter.GetModel().GetDocument()->SetSelected(rpDescriptor->GetPage(), true);
924 pViewShell->GetFrameView()->SetSelectedPage(
925 (rpDescriptor->GetPage()->GetPageNum()-1)/2);
926 }
927 if (mrSlideSorter.GetViewShellBase() != nullptr)
931}
932
934 const Point& rMousePosition)
935{
936 // Do not start a drag-and-drop operation when one is already active.
937 // (when dragging pages from one document into another, pressing a
938 // modifier key can trigger a MouseMotion event in the originating
939 // window (focus still in there). Together with the mouse button pressed
940 // (drag-and-drop is active) this triggers the start of drag-and-drop.)
941 if (SD_MOD()->pTransferDrag != nullptr)
942 return;
943
944 mrSelectionFunction.SwitchToDragAndDropMode(rMousePosition);
945}
946
947//===== NormalModeHandler =====================================================
948
949NormalModeHandler::NormalModeHandler (
950 SlideSorter& rSlideSorter,
951 SelectionFunction& rSelectionFunction)
952 : ModeHandler(rSlideSorter, rSelectionFunction, true)
953{
954}
955
956SelectionFunction::Mode NormalModeHandler::GetMode() const
957{
959}
960
961void NormalModeHandler::Abort()
962{
963}
964
965bool NormalModeHandler::ProcessButtonDownEvent (
966 SelectionFunction::EventDescriptor& rDescriptor)
967{
968 // Remember the location where the left button is pressed. With
969 // that we can filter away motion events that are caused by key
970 // presses. We also can tune the minimal motion distance that
971 // triggers a drag-and-drop operation.
972 if ((rDescriptor.mnEventCode & BUTTON_DOWN) != 0)
973 maButtonDownLocation = rDescriptor.maMousePosition;
974
975 switch (rDescriptor.mnEventCode)
976 {
977 case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE:
978 SetCurrentPage(rDescriptor.mpHitDescriptor);
979 break;
980
981 case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
982 break;
983
984 case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_SELECTED_PAGE:
985 case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_UNSELECTED_PAGE:
986 // A double click always shows the selected slide in the center
987 // pane in an edit view.
988 SetCurrentPage(rDescriptor.mpHitDescriptor);
989 SwitchView(rDescriptor.mpHitDescriptor);
990 break;
991
992 case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | SHIFT_MODIFIER:
993 case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | SHIFT_MODIFIER:
994 // Range selection with the shift modifier.
995 RangeSelect(rDescriptor.mpHitDescriptor);
996 break;
997
998 // Right button for context menu.
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);
1006 break;
1007
1008 case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
1009 // Do not change the selection. Just adjust the insertion indicator.
1010 break;
1011
1012 case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE:
1013 // Remember the current selection so that when a multi selection
1014 // is started, we can restore the previous selection.
1016 DeselectAllPages();
1017 break;
1018
1019 case ANY_MODIFIER(BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
1020 // Remember the current selection so that when a multi selection
1021 // is started, we can restore the previous selection.
1022 mrSlideSorter.GetModel().SaveCurrentSelection();
1023 DeselectAllPages();
1024 break;
1025
1026 case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | NOT_OVER_PAGE:
1027 {
1028 // Insert a new slide:
1029 // First of all we need to set the insertion indicator which sets the
1030 // position where the new slide will be inserted.
1031 std::shared_ptr<InsertionIndicatorHandler> pInsertionIndicatorHandler
1033
1034 pInsertionIndicatorHandler->Start(false);
1035 pInsertionIndicatorHandler->UpdatePosition(
1036 rDescriptor.maMousePosition,
1038
1039 mrSlideSorter.GetController().GetSelectionManager()->SetInsertionPosition(
1040 pInsertionIndicatorHandler->GetInsertionPageIndex());
1041
1043 SID_INSERTPAGE,
1044 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
1045
1046 pInsertionIndicatorHandler->End(Animator::AM_Immediate);
1047
1048 break;
1049 }
1050
1051 default:
1052 return false;
1053 }
1054 return true;
1055}
1056
1057bool NormalModeHandler::ProcessButtonUpEvent (
1058 SelectionFunction::EventDescriptor& rDescriptor)
1059{
1060 bool bIsProcessed (true);
1061 switch (rDescriptor.mnEventCode)
1062 {
1063 case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
1064 SetCurrentPage(rDescriptor.mpHitDescriptor);
1065 break;
1066
1067 // Multi selection with the control modifier.
1068 case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER:
1070 rDescriptor.mpHitDescriptor);
1071 break;
1072
1073 case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | CONTROL_MODIFIER:
1075 rDescriptor.mpHitDescriptor);
1076 mrSlideSorter.GetView().SetPageUnderMouse(rDescriptor.mpHitDescriptor);
1077 break;
1078 case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE:
1079 break;
1080
1081 default:
1082 bIsProcessed = false;
1083 break;
1084 }
1085 mrSelectionFunction.SwitchToNormalMode();
1086 return bIsProcessed;
1087}
1088
1089bool NormalModeHandler::ProcessMotionEvent (
1090 SelectionFunction::EventDescriptor& rDescriptor)
1091{
1092 if (ModeHandler::ProcessMotionEvent(rDescriptor))
1093 return true;
1094
1095 bool bIsProcessed (true);
1096 switch (rDescriptor.mnEventCode)
1097 {
1098 // A mouse motion without visible substitution starts that.
1099 case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE):
1100 case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE):
1101 {
1103 {
1104 const sal_Int32 nDistance(std::max(
1105 std::abs(maButtonDownLocation->X() - rDescriptor.maMousePosition.X()),
1106 std::abs(maButtonDownLocation->Y() - rDescriptor.maMousePosition.Y())));
1107 if (nDistance > 3)
1108 StartDrag(rDescriptor.maMousePosition);
1109 }
1110 break;
1111 }
1112
1113 // A mouse motion not over a page starts a rectangle selection.
1114 case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
1115 mrSelectionFunction.SwitchToMultiSelectionMode(
1116 rDescriptor.maMouseModelPosition,
1117 rDescriptor.mnEventCode);
1118 break;
1119
1120 default:
1121 bIsProcessed = false;
1122 break;
1123 }
1124 return bIsProcessed;
1125}
1126
1127bool NormalModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor)
1128{
1129 mrSelectionFunction.SwitchToDragAndDropMode(rDescriptor.maMousePosition);
1130 ReprocessEvent(rDescriptor);
1131 return true;
1132}
1133
1134void NormalModeHandler::RangeSelect (const model::SharedPageDescriptor& rpDescriptor)
1135{
1136 PageSelector::UpdateLock aLock (mrSlideSorter);
1137 PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
1138
1139 model::SharedPageDescriptor pAnchor (rSelector.GetSelectionAnchor());
1140 DeselectAllPages();
1141
1142 if (!pAnchor)
1143 return;
1144
1145 // Select all pages between the anchor and the given one, including
1146 // the two.
1147 const sal_uInt16 nAnchorIndex ((pAnchor->GetPage()->GetPageNum()-1) / 2);
1148 const sal_uInt16 nOtherIndex ((rpDescriptor->GetPage()->GetPageNum()-1) / 2);
1149
1150 // Iterate over all pages in the range. Start with the anchor
1151 // page. This way the PageSelector will recognize it again as
1152 // anchor (the first selected page after a DeselectAllPages()
1153 // becomes the anchor.)
1154 const sal_uInt16 nStep ((nAnchorIndex < nOtherIndex) ? +1 : -1);
1155 sal_uInt16 nIndex (nAnchorIndex);
1156 while (true)
1157 {
1158 rSelector.SelectPage(nIndex);
1159 if (nIndex == nOtherIndex)
1160 break;
1161 nIndex = nIndex + nStep;
1162 }
1163}
1164
1165void NormalModeHandler::ResetButtonDownLocation()
1166{
1167 maButtonDownLocation = ::std::optional<Point>();
1168}
1169
1170//===== MultiSelectionModeHandler =============================================
1171
1172MultiSelectionModeHandler::MultiSelectionModeHandler (
1173 SlideSorter& rSlideSorter,
1174 SelectionFunction& rSelectionFunction,
1175 const Point& rMouseModelPosition,
1176 const sal_uInt32 nEventCode)
1177 : ModeHandler(rSlideSorter, rSelectionFunction, false),
1178 meSelectionMode(SM_Normal),
1179 maSecondCorner(rMouseModelPosition),
1180 maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()),
1181 mbAutoScrollInstalled(false),
1182 mnAnchorIndex(-1),
1183 mnSecondIndex(-1)
1184{
1185
1186 mrSlideSorter.GetContentWindow()->SetPointer(PointerStyle::Text);
1187 SetSelectionModeFromModifier(nEventCode);
1188}
1189
1190MultiSelectionModeHandler::~MultiSelectionModeHandler()
1191{
1193 {
1194 //a call to this handler's MultiSelectionModeHandler::UpdatePosition
1195 //may be still waiting to be called back
1197 }
1199}
1200
1201SelectionFunction::Mode MultiSelectionModeHandler::GetMode() const
1202{
1204}
1205
1206void MultiSelectionModeHandler::Abort()
1207{
1209}
1210
1211void MultiSelectionModeHandler::ProcessEvent (
1212 SelectionFunction::EventDescriptor& rDescriptor)
1213{
1214 // During a multi selection we do not want sudden jumps of the
1215 // visible area caused by moving newly selected pages into view.
1216 // Therefore disable that temporarily. The disabled object is
1217 // released at the end of the event processing, after the focus and
1218 // current slide have been updated.
1219 VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
1220
1221 ModeHandler::ProcessEvent(rDescriptor);
1222}
1223
1224bool MultiSelectionModeHandler::ProcessButtonUpEvent (
1225 SelectionFunction::EventDescriptor& rDescriptor)
1226{
1228 {
1229 //a call to this handler's MultiSelectionModeHandler::UpdatePosition
1230 //may be still waiting to be called back
1232 mbAutoScrollInstalled = false;
1233 }
1234
1235 if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK))
1236 {
1237 mrSelectionFunction.SwitchToNormalMode();
1238 return true;
1239 }
1240 else
1241 return false;
1242}
1243
1244bool MultiSelectionModeHandler::ProcessMotionEvent (
1245 SelectionFunction::EventDescriptor& rDescriptor)
1246{
1247 // The selection rectangle is visible. Handle events accordingly.
1248 if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK))
1249 {
1250 SetSelectionModeFromModifier(rDescriptor.mnEventCode);
1251 UpdatePosition(rDescriptor.maMousePosition, true);
1252 return true;
1253 }
1254 else
1255 return false;
1256}
1257
1258bool MultiSelectionModeHandler::HandleUnprocessedEvent (
1259 SelectionFunction::EventDescriptor& rDescriptor)
1260{
1261 if ( ! ModeHandler::HandleUnprocessedEvent(rDescriptor))
1262 {
1263 // If the event has not been processed then stop multi selection.
1264 mrSelectionFunction.SwitchToNormalMode();
1265 ReprocessEvent(rDescriptor);
1266 }
1267 return true;
1268}
1269
1270void MultiSelectionModeHandler::UpdatePosition (
1271 const Point& rMousePosition,
1272 const bool bAllowAutoScroll)
1273{
1274 VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
1275
1276 // Convert window coordinates into model coordinates (we need the
1277 // window coordinates for auto-scrolling because that remains
1278 // constant while scrolling.)
1280 const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
1281
1282 bool bDoAutoScroll = bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll(
1283 rMousePosition,
1284 [this, &rMousePosition] () { return this->UpdatePosition(rMousePosition, false); });
1285
1286 if (!bDoAutoScroll)
1287 UpdateModelPosition(aMouseModelPosition);
1288
1289 mbAutoScrollInstalled |= bDoAutoScroll;
1290}
1291
1292void MultiSelectionModeHandler::SetSelectionModeFromModifier (
1293 const sal_uInt32 nEventCode)
1294{
1295 switch (nEventCode & MODIFIER_MASK)
1296 {
1297 case NO_MODIFIER:
1298 SetSelectionMode(SM_Normal);
1299 break;
1300
1301 case SHIFT_MODIFIER:
1302 SetSelectionMode(SM_Add);
1303 break;
1304
1305 case CONTROL_MODIFIER:
1306 SetSelectionMode(SM_Toggle);
1307 break;
1308 }
1309}
1310
1311void MultiSelectionModeHandler::SetSelectionMode (const SelectionMode eSelectionMode)
1312{
1313 if (meSelectionMode != eSelectionMode)
1314 {
1315 meSelectionMode = eSelectionMode;
1316 UpdateSelection();
1317 }
1318}
1319
1320void MultiSelectionModeHandler::UpdateSelectionState (
1321 const model::SharedPageDescriptor& rpDescriptor,
1322 const bool bIsInSelection) const
1323{
1324 // Determine whether the page was selected before the rectangle
1325 // selection was started.
1326 const bool bWasSelected (rpDescriptor->HasState(model::PageDescriptor::ST_WasSelected));
1327
1328 // Combine the two selection states depending on the selection mode.
1329 bool bSelect (false);
1330 switch(meSelectionMode)
1331 {
1332 case SM_Normal:
1333 bSelect = bIsInSelection;
1334 break;
1335
1336 case SM_Add:
1337 bSelect = bIsInSelection || bWasSelected;
1338 break;
1339
1340 case SM_Toggle:
1341 if (bIsInSelection)
1342 bSelect = !bWasSelected;
1343 else
1344 bSelect = bWasSelected;
1345 break;
1346 }
1347
1348 // Set the new selection state.
1349 if (bSelect)
1351 else
1353}
1354
1355void MultiSelectionModeHandler::UpdateModelPosition (const Point& rMouseModelPosition)
1356{
1357 maSecondCorner = rMouseModelPosition;
1358 UpdateSelection();
1359}
1360
1361void MultiSelectionModeHandler::UpdateSelection()
1362{
1363 view::SlideSorterView::DrawLock aLock (mrSlideSorter);
1364
1365 model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
1366 const sal_Int32 nPageCount (rModel.GetPageCount());
1367
1368 const sal_Int32 nIndexUnderMouse (
1371 false,
1372 false));
1373 if (nIndexUnderMouse < 0 || nIndexUnderMouse >= nPageCount)
1374 return;
1375
1376 if (mnAnchorIndex < 0)
1377 mnAnchorIndex = nIndexUnderMouse;
1378 mnSecondIndex = nIndexUnderMouse;
1379
1381 aRange.Normalize();
1382
1383 for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
1384 {
1385 UpdateSelectionState(rModel.GetPageDescriptor(nIndex), aRange.Contains(nIndex));
1386 }
1387}
1388
1389//===== DragAndDropModeHandler ================================================
1390
1391DragAndDropModeHandler::DragAndDropModeHandler (
1392 SlideSorter& rSlideSorter,
1393 SelectionFunction& rSelectionFunction,
1394 const Point& rMousePosition,
1395 vcl::Window* pWindow)
1396 : ModeHandler(rSlideSorter, rSelectionFunction, false)
1397{
1398 SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
1399 if (pDragTransferable==nullptr && mrSlideSorter.GetViewShell() != nullptr)
1400 {
1401 SlideSorterViewShell* pSlideSorterViewShell
1402 = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
1403 if (pSlideSorterViewShell != nullptr)
1404 pSlideSorterViewShell->StartDrag(rMousePosition, pWindow);
1405 pDragTransferable = SD_MOD()->pTransferDrag;
1406 }
1407
1408 mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter));
1410 pDragTransferable != nullptr
1411 && pDragTransferable->GetView()==&mrSlideSorter.GetView());
1412}
1413
1414DragAndDropModeHandler::~DragAndDropModeHandler()
1415{
1417 {
1418 // Disconnect the substitution handler from this selection function.
1419 mpDragAndDropContext->SetTargetSlideSorter();
1420 mpDragAndDropContext.reset();
1421 }
1423}
1424
1425SelectionFunction::Mode DragAndDropModeHandler::GetMode() const
1426{
1428}
1429
1430void DragAndDropModeHandler::Abort()
1431{
1434 mpDragAndDropContext->Dispose();
1435 // mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection());
1436}
1437
1438bool DragAndDropModeHandler::ProcessButtonUpEvent (
1439 SelectionFunction::EventDescriptor& rDescriptor)
1440{
1441 if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON))
1442 {
1443 // The following Process() call may lead to the destruction
1444 // of rDescriptor.mpHitDescriptor so release our reference to it.
1445 rDescriptor.mpHitDescriptor.reset();
1446 mrSelectionFunction.SwitchToNormalMode();
1447 return true;
1448 }
1449 else
1450 return false;
1451}
1452
1453bool DragAndDropModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor)
1454{
1455 OSL_ASSERT(mpDragAndDropContext);
1456
1457 if (rDescriptor.mbIsLeaving)
1458 {
1459 mrSelectionFunction.SwitchToNormalMode();
1460 }
1461 else if (mpDragAndDropContext)
1462 {
1463 mpDragAndDropContext->UpdatePosition(
1464 rDescriptor.maMousePosition,
1465 rDescriptor.meDragMode, true);
1466 }
1467
1468 return true;
1469}
1470
1471} // end of namespace ::sd::slidesorter::controller
1472
1473/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SlideSorterController & mrController
PointerStyle maSavedPointer
#define ANY_MODIFIER(code)
sal_Int32 mnAnchorIndex
bool mbAutoScrollInstalled
Point maSecondCorner
std::unique_ptr< DragAndDropContext, o3tl::default_delete< DragAndDropContext > > mpDragAndDropContext
SelectionMode meSelectionMode
::std::optional< Point > maButtonDownLocation
sal_Int32 mnSecondIndex
SlideSorter & mrSlideSorter
const vcl::KeyCode & GetKeyCode() const
bool IsMod1() const
bool IsLeaveWindow() const
sal_uInt16 GetClicks() const
sal_uInt16 GetButtons() const
const Point & GetPosPixel() const
bool IsShift() const
SAL_DLLPRIVATE void SetSelected(SdPage *pPage, bool bSelect)
Definition: drawdoc2.cxx:461
const ::sd::View * GetView() const
Definition: sdxfer.hxx:54
sal_uInt16 GetPageNum() const
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
SfxDispatcher * GetDispatcher() const
reference_type * get() const
void SetSelectedPage(sal_uInt16 nPage)
Definition: frmview.cxx:907
Base class for all functions.
Definition: fupoor.hxx:48
virtual bool KeyInput(const KeyEvent &rKEvt)
handle keyboard events
Definition: fupoor.cxx:175
VclPtr< ::sd::Window > mpWindow
Definition: fupoor.hxx:146
Point aMDPos
position of MouseButtonDown
Definition: fupoor.hxx:159
void SetMouseButtonCode(sal_uInt16 nNew)
Definition: fupoor.hxx:57
Base class of the stacked shell hierarchy.
Definition: ViewShell.hxx:92
bool IsMainViewShell() const
Return <TRUE> when the called view shell is the main sub shell of its ViewShellBase object,...
Definition: viewshel.cxx:1493
FrameView * GetFrameView()
Definition: ViewShell.hxx:221
An SdWindow contains the actual working area of ViewShell.
Definition: Window.hxx:45
static const OUString msCenterPaneURL
static ::std::shared_ptr< FrameworkHelper > Instance(ViewShellBase &rBase)
Return the FrameworkHelper object that is associated with the given ViewShellBase.
static const OUString msImpressViewURL
Show previews for all the slides in a document and allow the user to insert or delete slides and modi...
Definition: SlideSorter.hxx:62
SD_DLLPUBLIC controller::SlideSorterController & GetController() const
ViewShell * GetViewShell() const
Return the view shell that was given at construction.
ViewShellBase * GetViewShellBase() const
Return the ViewShellBase object.
const VclPtr< sd::Window > & GetContentWindow() const
Return the content window.
Definition: SlideSorter.hxx:99
model::SlideSorterModel & GetModel() const
view::SlideSorterView & GetView() const
This class manages the focus of the slide sorter.
void MoveFocus(FocusMoveDirection eDirection)
Move the focus from the currently focused page to one that is displayed adjacent to it,...
bool ToggleFocus()
Toggle the focused state of the current slide.
model::SharedPageDescriptor GetFocusedPageDescriptor() const
Return the descriptor of the page that currently has the focus.
bool SetFocusedPage(const model::SharedPageDescriptor &rDescriptor)
Set the focused page to the one described by the given page descriptor.
void ShowFocus(const bool bScrollToFocus=true)
Show the focus indicator of the current slide.
bool IsFocusShowing() const
Return <TRUE> when the focus indicator is currently shown.
bool HasFocus() const
Return whether the window managed by the called focus manager has the input focus of the application.
Manage the visibility and location of the insertion indicator.
Use the UpdateLock whenever you do a complex selection, i.e.
A sub-controller that handles page selection of the slide browser.
void DeselectPage(int nPageIndex)
Deselect the descriptor that is associated with the given page.
void SelectPage(int nPageIndex)
Select the specified descriptor.
bool AutoScroll(const Point &rMouseWindowPosition, const ::std::function< void()> &rAutoScrollFunctor)
Call this method to scroll a window while the mouse is in dragging a selection.
EventDescriptor(sal_uInt32 nEventType, const MouseEvent &rEvent, SlideSorter const &rSlideSorter)
sal_uInt32 EncodeMouseEvent(const MouseEvent &rEvent) const
Compute a numerical code that describes a mouse event and that can be used for fast look up of the ap...
sal_uInt32 EncodeState() const
Compute a numerical code that describes the current state like whether the selection rectangle is vis...
void SetCurrentPage(const model::SharedPageDescriptor &rpDescriptor)
Set the selection to exactly the specified page and also set it as the current page.
virtual bool ProcessMotionEvent(EventDescriptor &rDescriptor)
ModeHandler(SlideSorter &rSlideSorter, SelectionFunction &rSelectionFunction, const bool bIsMouseOverIndicatorAllowed)
void SwitchView(const model::SharedPageDescriptor &rpDescriptor)
When the view on which this selection function is working is the main view then the view is switched ...
virtual bool ProcessButtonUpEvent(EventDescriptor &rDescriptor)
virtual bool HandleUnprocessedEvent(EventDescriptor &rDescriptor)
virtual bool ProcessDragEvent(EventDescriptor &rDescriptor)
virtual bool ProcessButtonDownEvent(EventDescriptor &rDescriptor)
void SelectOnePage(const model::SharedPageDescriptor &rpDescriptor)
void MoveFocus(const FocusManager::FocusMoveDirection eDirection, const bool bIsShiftDown, const bool bIsControlDown)
void GotoPage(int nIndex)
Make the slide with the given index the new current slide.
void SwitchToDragAndDropMode(const Point &rMousePosition)
std::shared_ptr< ModeHandler > mpModeHandler
The selection function can be in one of several mutually exclusive modes.
virtual void DoCopy() override
Forward to the clipboard manager.
sal_Int32 mnShiftKeySelectionAnchor
Remember the slide where the shift key was pressed and started a multiselection via keyboard.
void NotifyDragFinished()
Turn of substitution display and insertion indicator.
virtual void DoPaste() override
Forward to the clipboard manager.
void MouseDragged(const AcceptDropEvent &rEvent, const sal_Int8 nDragAction)
void ResetMouseAnchor()
Special case handling for when the context menu is hidden.
void GotoNextPage(int nOffset)
Make the slide nOffset slides away of the current one the new current slide.
virtual void DoCut() override
Forward to the clipboard manager.
void SwitchToMultiSelectionMode(const Point &rMousePosition, const sal_uInt32 nEventCode)
SelectionFunction(const SelectionFunction &)=delete
virtual bool KeyInput(const KeyEvent &rKEvt) override
handle keyboard events
static rtl::Reference< FuPoor > Create(SlideSorter &rSlideSorter, SfxRequest &rRequest)
void SwitchMode(const std::shared_ptr< ModeHandler > &rpHandler)
virtual bool MouseMove(const MouseEvent &rMEvt) override
virtual bool cancel() override
is called when the current function should be aborted.
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
void ProcessMouseEvent(sal_uInt32 nEventType, const MouseEvent &rEvent)
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
model::SharedPageDescriptor GetPageAt(const Point &rPixelPosition)
Return the descriptor of the page that is rendered under the given position.
std::shared_ptr< CurrentSlideManager > const & GetCurrentSlideManager() const
std::shared_ptr< SelectionManager > const & GetSelectionManager() const
ScrollBarManager & GetScrollBarManager()
Return the object that manages the scroll bars.
std::shared_ptr< InsertionIndicatorHandler > const & GetInsertionIndicatorHandler() const
SD_DLLPUBLIC controller::Clipboard & GetClipboard()
static PageEnumeration CreateAllPagesEnumeration(const SlideSorterModel &rModel)
The returned enumeration of slides iterates over all slides of the given model.
Public class of page enumerations that delegates its calls to an implementation object that can filte...
virtual SharedPageDescriptor GetNextElement() override
Return the next element of the enumeration.
virtual bool HasMoreElements() const override
Return <TRUE> when the enumeration has more elements, i.e.
SdDrawDocument * GetDocument()
This method is present to let the view create a ShowView for displaying slides.
sal_Int32 GetPageCount() const
Return the number of slides in the document regardless of whether they are visible or not or whether ...
SharedPageDescriptor GetPageDescriptor(const sal_Int32 nPageIndex, const bool bCreate=true) const
Return a page descriptor for the page with the specified index.
void SaveCurrentSelection()
The current selection is saved by copying the ST_Selected state into ST_WasSelected for slides.
vcl::Region RestoreSelection()
The current selection is restored from the ST_WasSelected state from the slides.
sal_Int32 GetIndexAtPoint(const Point &rModelPosition, const bool bIncludePageBorders, const bool bClampToValidRange=true) const
Return the index of the page object that is rendered at the given point.
void SetPageUnderMouse(const model::SharedPageDescriptor &rpDescriptor)
void UpdatePageUnderMouse()
The page under the mouse is not highlighted in some contexts.
bool Contains(const Point &rPOINT) const
bool IsMod1() const
sal_uInt16 GetCode() const
bool IsShift() const
virtual std::shared_ptr< SfxDialogController > GetController() override
#define MOUSE_LEFT
#define MOUSE_MIDDLE
#define MOUSE_RIGHT
sal_Int32 nIndex
constexpr sal_uInt16 KEY_RETURN
constexpr sal_uInt16 KEY_ESCAPE
constexpr sal_uInt16 KEY_HOME
constexpr sal_uInt16 KEY_LEFT
constexpr sal_uInt16 KEY_PAGEDOWN
constexpr sal_uInt16 KEY_TAB
constexpr sal_uInt16 KEY_UP
constexpr sal_uInt16 KEY_F10
constexpr sal_uInt16 KEY_RIGHT
constexpr sal_uInt16 KEY_DELETE
constexpr sal_uInt16 KEY_DOWN
constexpr sal_uInt16 KEY_SPACE
constexpr sal_uInt16 KEY_PAGEUP
constexpr sal_uInt16 KEY_BACKSPACE
constexpr sal_uInt16 KEY_END
std::shared_ptr< T > make_shared(Args &&... args)
static bool Match(const sal_uInt32 nEventCode, const sal_uInt32 nPositivePattern)
std::shared_ptr< PageDescriptor > SharedPageDescriptor
PointerStyle
#define SD_MOD()
Definition: sdmod.hxx:184
signed char sal_Int8
SelectionMode