1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_sd.hxx"
25 
26 #include "controller/SlsSelectionFunction.hxx"
27 
28 #include "SlideSorter.hxx"
29 #include "SlideSorterViewShell.hxx"
30 #include "SlsDragAndDropContext.hxx"
31 #include "controller/SlsTransferableData.hxx"
32 #include "controller/SlideSorterController.hxx"
33 #include "controller/SlsPageSelector.hxx"
34 #include "controller/SlsFocusManager.hxx"
35 #include "controller/SlsScrollBarManager.hxx"
36 #include "controller/SlsClipboard.hxx"
37 #include "controller/SlsCurrentSlideManager.hxx"
38 #include "controller/SlsInsertionIndicatorHandler.hxx"
39 #include "controller/SlsSelectionManager.hxx"
40 #include "controller/SlsProperties.hxx"
41 #include "controller/SlsProperties.hxx"
42 #include "controller/SlsSlotManager.hxx"
43 #include "controller/SlsVisibleAreaManager.hxx"
44 #include "model/SlideSorterModel.hxx"
45 #include "model/SlsPageDescriptor.hxx"
46 #include "model/SlsPageEnumerationProvider.hxx"
47 #include "view/SlideSorterView.hxx"
48 #include "view/SlsLayouter.hxx"
49 #include "view/SlsPageObjectLayouter.hxx"
50 #include "view/SlsButtonBar.hxx"
51 #include "framework/FrameworkHelper.hxx"
52 #include "ViewShellBase.hxx"
53 #include "DrawController.hxx"
54 #include "Window.hxx"
55 #include "sdpage.hxx"
56 #include "drawdoc.hxx"
57 #include "DrawDocShell.hxx"
58 #include "sdxfer.hxx"
59 #include "ViewShell.hxx"
60 #include "ViewShellBase.hxx"
61 #include "FrameView.hxx"
62 #include "app.hrc"
63 #include "sdresid.hxx"
64 #include "strings.hrc"
65 #include <vcl/sound.hxx>
66 #include <sfx2/viewfrm.hxx>
67 #include <sfx2/dispatch.hxx>
68 #include <svx/svdpagv.hxx>
69 #include <vcl/msgbox.hxx>
70 #include <svx/svxids.hrc>
71 #include <boost/bind.hpp>
72 #include <boost/optional.hpp>
73 
74 namespace {
75 static const sal_uInt32 SINGLE_CLICK             (0x00000001);
76 static const sal_uInt32 DOUBLE_CLICK             (0x00000002);
77 static const sal_uInt32 LEFT_BUTTON              (0x00000010);
78 static const sal_uInt32 RIGHT_BUTTON             (0x00000020);
79 static const sal_uInt32 MIDDLE_BUTTON            (0x00000040);
80 static const sal_uInt32 BUTTON_DOWN              (0x00000100);
81 static const sal_uInt32 BUTTON_UP                (0x00000200);
82 static const sal_uInt32 MOUSE_MOTION             (0x00000400);
83 static const sal_uInt32 MOUSE_DRAG               (0x00000800);
84 // The rest leaves the lower 16 bit untouched so that it can be used with
85 // key codes.
86 static const sal_uInt32 OVER_SELECTED_PAGE       (0x00010000);
87 static const sal_uInt32 OVER_UNSELECTED_PAGE     (0x00020000);
88 static const sal_uInt32 OVER_FADE_INDICATOR      (0x00040000);
89 static const sal_uInt32 OVER_BUTTON_AREA         (0x00080000);
90 static const sal_uInt32 OVER_BUTTON              (0x00100000);
91 static const sal_uInt32 SHIFT_MODIFIER           (0x00200000);
92 static const sal_uInt32 CONTROL_MODIFIER         (0x00400000);
93 
94 static const sal_uInt32 KEY_EVENT                (0x10000000);
95 
96 // Some absent events are defined so they can be expressed explicitly.
97 static const sal_uInt32 NO_MODIFIER              (0x00000000);
98 static const sal_uInt32 NOT_OVER_PAGE            (0x00000000);
99 
100 // Masks
101 static const sal_uInt32 MODIFIER_MASK            (SHIFT_MODIFIER | CONTROL_MODIFIER);
102 static const sal_uInt32 BUTTON_MASK              (LEFT_BUTTON | RIGHT_BUTTON | MIDDLE_BUTTON);
103 
104 } // end of anonymous namespace
105 
106 
107 
108 // Define some macros to make the following switch statement more readable.
109 #define ANY_MODIFIER(code)                  \
110          code|NO_MODIFIER:                  \
111     case code|SHIFT_MODIFIER:               \
112     case code|CONTROL_MODIFIER
113 
114 namespace sd { namespace slidesorter { namespace controller {
115 
116 //===== SelectionFunction::EventDescriptor ====================================
117 
118 class SelectionFunction::EventDescriptor
119 {
120 public:
121     Point maMousePosition;
122     Point maMouseModelPosition;
123     model::SharedPageDescriptor mpHitDescriptor;
124     SdrPage* mpHitPage;
125     sal_uInt32 mnEventCode;
126     bool mbIsOverButton;
127     InsertionIndicatorHandler::Mode meDragMode;
128     bool mbMakeSelectionVisible;
129     bool mbIsLeaving;
130 
131     EventDescriptor (
132         sal_uInt32 nEventType,
133         const MouseEvent& rEvent,
134         SlideSorter& rSlideSorter);
135     EventDescriptor (
136         sal_uInt32 nEventType,
137         const AcceptDropEvent& rEvent,
138         const sal_Int8 nDragAction,
139         SlideSorter& rSlideSorter);
140     EventDescriptor (
141         const KeyEvent& rEvent,
142         SlideSorter& rSlideSorter);
143 
144     void SetDragMode (const InsertionIndicatorHandler::Mode eMode);
145 
146 private:
147     /** Compute a numerical code that describes a mouse event and that can
148         be used for fast look up of the appropriate reaction.
149     */
150     sal_uInt32 EncodeMouseEvent (const MouseEvent& rEvent) const;
151 
152     /** Compute a numerical code that describes a key event and that can
153         be used for fast look up of the appropriate reaction.
154     */
155     sal_uInt32 EncodeKeyEvent (const KeyEvent& rEvent) const;
156 
157     /** Compute a numerical code that describes the current state like
158         whether the selection rectangle is visible or whether the page under
159         the mouse or the one that has the focus is selected.
160     */
161     sal_uInt32 EncodeState (void) const;
162 };
163 
164 
165 
166 
167 //===== SelectionFunction::ModeHandler ========================================
168 
169 class SelectionFunction::ModeHandler
170 {
171 public:
172     ModeHandler (
173         SlideSorter& rSlideSorter,
174         SelectionFunction& rSelectionFunction,
175         const bool bIsMouseOverIndicatorAllowed);
176     virtual ~ModeHandler (void);
177 
178     virtual Mode GetMode (void) const = 0;
179     virtual void Abort (void) = 0;
180     virtual void ProcessEvent (EventDescriptor& rDescriptor);
181 
182     /** Set the selection to exactly the specified page and also set it as
183         the current page.
184     */
185     void SetCurrentPage (const model::SharedPageDescriptor& rpDescriptor);
186 
187     /// Deselect all pages.
188     void DeselectAllPages (void);
189     void SelectOnePage (const model::SharedPageDescriptor& rpDescriptor);
190 
191         /** When the view on which this selection function is working is the
192         main view then the view is switched to the regular editing view.
193     */
194     void SwitchView (const model::SharedPageDescriptor& rpDescriptor);
195 
196     void StartDrag (
197         const Point& rMousePosition,
198         const InsertionIndicatorHandler::Mode eMode);
199 
200     bool IsMouseOverIndicatorAllowed (void) const;
201 
202 protected:
203     SlideSorter& mrSlideSorter;
204     SelectionFunction& mrSelectionFunction;
205 
206     virtual bool ProcessButtonDownEvent (EventDescriptor& rDescriptor);
207     virtual bool ProcessButtonUpEvent (EventDescriptor& rDescriptor);
208     virtual bool ProcessMotionEvent (EventDescriptor& rDescriptor);
209     virtual bool ProcessDragEvent (EventDescriptor& rDescriptor);
210     virtual bool HandleUnprocessedEvent (EventDescriptor& rDescriptor);
211 
212     void ReprocessEvent (EventDescriptor& rDescriptor);
213 
214 private:
215     const bool mbIsMouseOverIndicatorAllowed;
216 };
217 
218 
219 /** This is the default handler for processing events.  It activates the
220     multi selection or drag-and-drop when the right conditions are met.
221 */
222 class NormalModeHandler : public SelectionFunction::ModeHandler
223 {
224 public:
225     NormalModeHandler (
226         SlideSorter& rSlideSorter,
227         SelectionFunction& rSelectionFunction);
228     virtual ~NormalModeHandler (void);
229 
230     virtual SelectionFunction::Mode GetMode (void) const;
231     virtual void Abort (void);
232 
233     void ResetButtonDownLocation (void);
234 
235 protected:
236     virtual bool ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor);
237     virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
238     virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor);
239     virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor);
240 
241 private:
242     ::boost::optional<Point> maButtonDownLocation;
243 
244     /** Select all pages between and including the selection anchor and the
245         specified page.
246     */
247     void RangeSelect (const model::SharedPageDescriptor& rpDescriptor);
248 };
249 
250 
251 /** Handle events during a multi selection, which typically is started by
252     pressing the left mouse button when not over a page.
253 */
254 class MultiSelectionModeHandler : public SelectionFunction::ModeHandler
255 {
256 public:
257     /** Start a rectangle selection at the given position.
258     */
259     MultiSelectionModeHandler (
260         SlideSorter& rSlideSorter,
261         SelectionFunction& rSelectionFunction,
262         const Point& rMouseModelPosition,
263         const sal_uInt32 nEventCode);
264     virtual ~MultiSelectionModeHandler (void);
265 
266     virtual SelectionFunction::Mode GetMode (void) const;
267     virtual void Abort (void);
268     virtual void ProcessEvent (SelectionFunction::EventDescriptor& rDescriptor);
269 
270     enum SelectionMode { SM_Normal, SM_Add, SM_Toggle };
271 
272     void SetSelectionMode (const SelectionMode eSelectionMode);
273     void SetSelectionModeFromModifier (const sal_uInt32 nEventCode);
274 
275 protected:
276     virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
277     virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor);
278     virtual bool HandleUnprocessedEvent (SelectionFunction::EventDescriptor& rDescriptor);
279 
280 private:
281     SelectionMode meSelectionMode;
282     Point maSecondCorner;
283     Pointer maSavedPointer;
284     sal_Int32 mnAnchorIndex;
285     sal_Int32 mnSecondIndex;
286     view::ButtonBar::Lock maButtonBarLock;
287 
288     virtual void UpdateModelPosition (const Point& rMouseModelPosition);
289     virtual void UpdateSelection (void);
290 
291     /** Update the rectangle selection so that the given position becomes
292         the new second point of the selection rectangle.
293     */
294     void UpdatePosition (
295         const Point& rMousePosition,
296         const bool bAllowAutoScroll);
297 
298     void UpdateSelectionState (
299         const model::SharedPageDescriptor& rpDescriptor,
300         const bool bIsInSelection) const;
301 };
302 
303 
304 /** Handle events during drag-and-drop.
305 */
306 class DragAndDropModeHandler : public SelectionFunction::ModeHandler
307 {
308 public:
309     DragAndDropModeHandler (
310         SlideSorter& rSlideSorter,
311         SelectionFunction& rSelectionFunction,
312         const Point& rMousePosition,
313         ::Window* pWindow);
314     virtual ~DragAndDropModeHandler (void);
315 
316     virtual SelectionFunction::Mode GetMode (void) const;
317     virtual void Abort (void);
318 
319 protected:
320     virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
321     virtual bool ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor);
322 
323 private:
324     ::boost::scoped_ptr<DragAndDropContext> mpDragAndDropContext;
325 };
326 
327 
328 /** Handle events while the left mouse button is pressed over the button
329     bar.
330 */
331 class ButtonModeHandler : public SelectionFunction::ModeHandler
332 {
333 public:
334     ButtonModeHandler (
335         SlideSorter& rSlideSorter,
336         SelectionFunction& rSelectionFunction);
337     virtual ~ButtonModeHandler (void);
338     virtual void Abort (void);
339 
340     virtual SelectionFunction::Mode GetMode (void) const;
341 
342 protected:
343     virtual bool ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor);
344     virtual bool ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor);
345     virtual bool ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor);
346 };
347 
348 
349 
350 
351 //===== SelectionFunction =====================================================
352 
353 TYPEINIT1(SelectionFunction, FuPoor);
354 
355 
SelectionFunction(SlideSorter & rSlideSorter,SfxRequest & rRequest)356 SelectionFunction::SelectionFunction (
357     SlideSorter& rSlideSorter,
358     SfxRequest& rRequest)
359     : FuPoor (
360         rSlideSorter.GetViewShell(),
361         rSlideSorter.GetContentWindow().get(),
362         &rSlideSorter.GetView(),
363         rSlideSorter.GetModel().GetDocument(),
364         rRequest),
365       mrSlideSorter(rSlideSorter),
366       mrController(mrSlideSorter.GetController()),
367       mbDragSelection(false),
368       maInsertionMarkerBox(),
369       mbProcessingMouseButtonDown(false),
370       mnShiftKeySelectionAnchor(-1),
371       mpModeHandler(new NormalModeHandler(rSlideSorter, *this))
372 {
373 }
374 
375 
376 
377 
~SelectionFunction(void)378 SelectionFunction::~SelectionFunction (void)
379 {
380     mpModeHandler.reset();
381 }
382 
383 
384 
385 
Create(SlideSorter & rSlideSorter,SfxRequest & rRequest)386 FunctionReference SelectionFunction::Create(
387     SlideSorter& rSlideSorter,
388     SfxRequest& rRequest)
389 {
390 	FunctionReference xFunc( new SelectionFunction( rSlideSorter, rRequest ) );
391 	return xFunc;
392 }
393 
394 
395 
396 
MouseButtonDown(const MouseEvent & rEvent)397 sal_Bool SelectionFunction::MouseButtonDown (const MouseEvent& rEvent)
398 {
399 	// #95491# remember button state for creation of own MouseEvents
400 	SetMouseButtonCode (rEvent.GetButtons());
401     aMDPos = rEvent.GetPosPixel();
402     mbProcessingMouseButtonDown = true;
403 
404     //	mpWindow->CaptureMouse();
405 
406     ProcessMouseEvent(BUTTON_DOWN, rEvent);
407 
408 	return sal_True;
409 }
410 
411 
412 
413 
MouseMove(const MouseEvent & rEvent)414 sal_Bool SelectionFunction::MouseMove (const MouseEvent& rEvent)
415 {
416     ProcessMouseEvent(MOUSE_MOTION, rEvent);
417 	return sal_True;
418 }
419 
420 
421 
422 
MouseButtonUp(const MouseEvent & rEvent)423 sal_Bool SelectionFunction::MouseButtonUp (const MouseEvent& rEvent)
424 {
425     mrController.GetScrollBarManager().StopAutoScroll ();
426 
427     ProcessMouseEvent(BUTTON_UP, rEvent);
428 
429     mbProcessingMouseButtonDown = false;
430 //    mpWindow->ReleaseMouse();
431 
432 	return sal_True;
433 }
434 
435 
436 
437 
NotifyDragFinished(void)438 void SelectionFunction::NotifyDragFinished (void)
439 {
440     SwitchToNormalMode();
441 }
442 
443 
444 
445 
KeyInput(const KeyEvent & rEvent)446 sal_Bool SelectionFunction::KeyInput (const KeyEvent& rEvent)
447 {
448     view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter);
449     PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter);
450     PageSelector::UpdateLock aLock (mrSlideSorter);
451     FocusManager& rFocusManager (mrController.GetFocusManager());
452 	sal_Bool bResult = sal_False;
453 
454     const KeyCode& rCode (rEvent.GetKeyCode());
455 	switch (rCode.GetCode())
456 	{
457         case KEY_RETURN:
458         {
459             model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
460             ViewShell* pViewShell = mrSlideSorter.GetViewShell();
461             if (rFocusManager.HasFocus() && pDescriptor && pViewShell!=NULL)
462             {
463                 // The Return key triggers different functions depending on
464                 // whether the slide sorter is the main view or displayed in
465                 // the right pane.
466                 if (pViewShell->IsMainViewShell())
467                 {
468                     mpModeHandler->SetCurrentPage(pDescriptor);
469                     mpModeHandler->SwitchView(pDescriptor);
470                 }
471                 else
472                 {
473                     pViewShell->GetDispatcher()->Execute(
474                         SID_INSERTPAGE,
475                         SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
476                 }
477 		        bResult = sal_True;
478             }
479             break;
480         }
481 
482         case KEY_TAB:
483             if ( ! rFocusManager.IsFocusShowing())
484             {
485                 rFocusManager.ShowFocus();
486                 bResult = sal_True;
487             }
488             break;
489 
490 		case KEY_ESCAPE:
491             // When there is an active multiselection or drag-and-drop
492             // operation then stop that.
493             mpModeHandler->Abort();
494             SwitchToNormalMode();
495             bResult = sal_True;
496             break;
497 
498         case KEY_SPACE:
499         {
500             // Toggle the selection state.
501             model::SharedPageDescriptor pDescriptor (rFocusManager.GetFocusedPageDescriptor());
502             if (pDescriptor && rCode.IsMod1())
503             {
504                 if (pDescriptor->HasState(model::PageDescriptor::ST_Selected))
505                     mrController.GetPageSelector().DeselectPage(pDescriptor, false);
506                 else
507                     mrController.GetPageSelector().SelectPage(pDescriptor);
508             }
509             bResult = sal_True;
510         }
511         break;
512 
513 
514         // Move the focus indicator left.
515 		case KEY_LEFT:
516             MoveFocus(FocusManager::FMD_LEFT, rCode.IsShift(), rCode.IsMod1());
517             bResult = sal_True;
518             break;
519 
520         // Move the focus indicator right.
521 		case KEY_RIGHT:
522             MoveFocus(FocusManager::FMD_RIGHT, rCode.IsShift(), rCode.IsMod1());
523             bResult = sal_True;
524             break;
525 
526         // Move the focus indicator up.
527 		case KEY_UP:
528             MoveFocus(FocusManager::FMD_UP, rCode.IsShift(), rCode.IsMod1());
529             bResult = sal_True;
530             break;
531 
532         // Move the focus indicator down.
533 		case KEY_DOWN:
534             MoveFocus(FocusManager::FMD_DOWN, rCode.IsShift(), rCode.IsMod1());
535             bResult = sal_True;
536             break;
537 
538         // Go to previous page.  No wrap around.
539 		case KEY_PAGEUP:
540             GotoNextPage(-1);
541             bResult = sal_True;
542             break;
543 
544         // Go to next page.  No wrap around..
545 		case KEY_PAGEDOWN:
546             GotoNextPage(+1);
547             bResult = sal_True;
548             break;
549 
550         case KEY_HOME:
551             GotoPage(0);
552             bResult = sal_True;
553             break;
554 
555         case KEY_END:
556             GotoPage(mrSlideSorter.GetModel().GetPageCount()-1);
557             bResult = sal_True;
558             break;
559 
560         case KEY_DELETE:
561         case KEY_BACKSPACE:
562         {
563             if (mrSlideSorter.GetProperties()->IsUIReadOnly())
564                 break;
565 
566             mrController.GetSelectionManager()->DeleteSelectedPages(rCode.GetCode()==KEY_DELETE);
567 
568             mnShiftKeySelectionAnchor = -1;
569             bResult = sal_True;
570         }
571         break;
572 
573         case KEY_F10:
574             if (rCode.IsShift())
575             {
576                 mpModeHandler->SelectOnePage(
577                     mrSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
578             }
579             break;
580 
581         default:
582             break;
583 	}
584 
585     if ( ! bResult)
586         bResult = FuPoor::KeyInput(rEvent);
587 
588 	return bResult;
589 }
590 
591 
592 
593 
MoveFocus(const FocusManager::FocusMoveDirection eDirection,const bool bIsShiftDown,const bool bIsControlDown)594 void SelectionFunction::MoveFocus (
595     const FocusManager::FocusMoveDirection eDirection,
596     const bool bIsShiftDown,
597     const bool bIsControlDown)
598 {
599     // Remember the anchor of shift key multi selection.
600     if (bIsShiftDown)
601     {
602         if (mnShiftKeySelectionAnchor<0)
603         {
604             model::SharedPageDescriptor pFocusedDescriptor (
605                 mrController.GetFocusManager().GetFocusedPageDescriptor());
606             mnShiftKeySelectionAnchor = pFocusedDescriptor->GetPageIndex();
607         }
608     }
609     else if ( ! bIsControlDown)
610         ResetShiftKeySelectionAnchor();
611 
612     mrController.GetFocusManager().MoveFocus(eDirection);
613 
614     PageSelector& rSelector (mrController.GetPageSelector());
615     model::SharedPageDescriptor pFocusedDescriptor (
616         mrController.GetFocusManager().GetFocusedPageDescriptor());
617     if (bIsShiftDown)
618     {
619         // When shift is pressed then select all pages in the range between
620         // the currently and the previously focused pages, including them.
621         if (pFocusedDescriptor)
622         {
623             sal_Int32 nPageRangeEnd (pFocusedDescriptor->GetPageIndex());
624             model::PageEnumeration aPages (
625                 model::PageEnumerationProvider::CreateAllPagesEnumeration(
626                     mrSlideSorter.GetModel()));
627             while (aPages.HasMoreElements())
628             {
629                 model::SharedPageDescriptor pDescriptor (aPages.GetNextElement());
630                 if (pDescriptor)
631                 {
632                     const sal_Int32 nPageIndex(pDescriptor->GetPageIndex());
633                     if ((nPageIndex>=mnShiftKeySelectionAnchor && nPageIndex<=nPageRangeEnd)
634                         || (nPageIndex<=mnShiftKeySelectionAnchor && nPageIndex>=nPageRangeEnd))
635                     {
636                         rSelector.SelectPage(pDescriptor);
637                     }
638                     else
639                     {
640                         rSelector.DeselectPage(pDescriptor);
641                     }
642                 }
643             }
644         }
645     }
646     else if (bIsControlDown)
647     {
648         // When control is pressed then do not alter the selection or the
649         // current page, just move the focus.
650     }
651     else
652     {
653         // Without shift just select the focused page.
654         mpModeHandler->SelectOnePage(pFocusedDescriptor);
655     }
656 }
657 
658 
659 
660 
Activate()661 void SelectionFunction::Activate()
662 {
663 	FuPoor::Activate();
664 }
665 
666 
667 
668 
Deactivate()669 void SelectionFunction::Deactivate()
670 {
671 	FuPoor::Deactivate();
672 }
673 
674 
675 
ScrollStart(void)676 void SelectionFunction::ScrollStart (void)
677 {
678 }
679 
680 
681 
682 
ScrollEnd(void)683 void SelectionFunction::ScrollEnd (void)
684 {
685 }
686 
687 
688 
689 
DoCut(void)690 void SelectionFunction::DoCut (void)
691 {
692     if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly())
693     {
694         mrController.GetClipboard().DoCut();
695     }
696 }
697 
698 
699 
700 
DoCopy(void)701 void SelectionFunction::DoCopy (void)
702 {
703     mrController.GetClipboard().DoCopy();
704 }
705 
706 
707 
708 
DoPaste(void)709 void SelectionFunction::DoPaste (void)
710 {
711     if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly())
712     {
713         mrController.GetClipboard().DoPaste();
714     }
715 }
716 
717 
718 
719 
cancel(void)720 bool SelectionFunction::cancel (void)
721 {
722     mrController.GetFocusManager().ToggleFocus();
723     return true;
724 }
725 
726 
727 
728 
GotoNextPage(int nOffset)729 void SelectionFunction::GotoNextPage (int nOffset)
730 {
731     model::SharedPageDescriptor pDescriptor
732         = mrController.GetCurrentSlideManager()->GetCurrentSlide();
733     if (pDescriptor.get() != NULL)
734     {
735         SdPage* pPage = pDescriptor->GetPage();
736         OSL_ASSERT(pPage!=NULL);
737         sal_Int32 nIndex = (pPage->GetPageNum()-1) / 2;
738         GotoPage(nIndex + nOffset);
739     }
740     ResetShiftKeySelectionAnchor();
741 }
742 
743 
744 
745 
GotoPage(int nIndex)746 void SelectionFunction::GotoPage (int nIndex)
747 {
748     sal_uInt16 nPageCount = (sal_uInt16)mrSlideSorter.GetModel().GetPageCount();
749 
750     if (nIndex >= nPageCount)
751         nIndex = nPageCount - 1;
752     if (nIndex < 0)
753         nIndex = 0;
754 
755     mrController.GetFocusManager().SetFocusedPage(nIndex);
756     model::SharedPageDescriptor pNextPageDescriptor (
757         mrSlideSorter.GetModel().GetPageDescriptor (nIndex));
758     if (pNextPageDescriptor.get() != NULL)
759         mpModeHandler->SetCurrentPage(pNextPageDescriptor);
760     else
761     {
762         OSL_ASSERT(pNextPageDescriptor.get() != NULL);
763     }
764     ResetShiftKeySelectionAnchor();
765 }
766 
767 
768 
769 
ProcessMouseEvent(sal_uInt32 nEventType,const MouseEvent & rEvent)770 void SelectionFunction::ProcessMouseEvent (sal_uInt32 nEventType, const MouseEvent& rEvent)
771 {
772 	// #95491# remember button state for creation of own MouseEvents
773 	SetMouseButtonCode (rEvent.GetButtons());
774 
775     EventDescriptor aEventDescriptor (nEventType, rEvent, mrSlideSorter);
776     ProcessEvent(aEventDescriptor);
777 }
778 
779 
780 
781 
MouseDragged(const AcceptDropEvent & rEvent,const sal_Int8 nDragAction)782 void SelectionFunction::MouseDragged (
783     const AcceptDropEvent& rEvent,
784     const sal_Int8 nDragAction)
785 {
786     EventDescriptor aEventDescriptor (MOUSE_DRAG, rEvent, nDragAction, mrSlideSorter);
787     ProcessEvent(aEventDescriptor);
788 }
789 
790 
791 
792 
ProcessKeyEvent(const KeyEvent & rEvent)793 void SelectionFunction::ProcessKeyEvent (const KeyEvent& rEvent)
794 {
795     EventDescriptor aEventDescriptor (rEvent, mrSlideSorter);
796     ProcessEvent(aEventDescriptor);
797 }
798 
799 
800 
801 
ProcessEvent(EventDescriptor & rDescriptor)802 void SelectionFunction::ProcessEvent (EventDescriptor& rDescriptor)
803 {
804     // The call to ProcessEvent may switch to another mode handler.
805     // Prevent the untimely destruction of the called handler  by aquiring a
806     // temporary reference here.
807     ::boost::shared_ptr<ModeHandler> pModeHandler (mpModeHandler);
808     pModeHandler->ProcessEvent(rDescriptor);
809 }
810 
811 
812 
813 
Match(const sal_uInt32 nEventCode,const sal_uInt32 nPositivePattern)814 bool Match (
815     const sal_uInt32 nEventCode,
816     const sal_uInt32 nPositivePattern)
817 {
818     return (nEventCode & nPositivePattern)==nPositivePattern;
819 }
820 
821 
822 
823 
SwitchToNormalMode(void)824 void SelectionFunction::SwitchToNormalMode (void)
825 {
826     if (mpModeHandler->GetMode() != NormalMode)
827         SwitchMode(::boost::shared_ptr<ModeHandler>(
828             new NormalModeHandler(mrSlideSorter, *this)));
829 }
830 
831 
832 
833 
SwitchToDragAndDropMode(const Point aMousePosition)834 void SelectionFunction::SwitchToDragAndDropMode (const Point aMousePosition)
835 {
836     if (mpModeHandler->GetMode() != DragAndDropMode)
837     {
838         SwitchMode(::boost::shared_ptr<ModeHandler>(
839             new DragAndDropModeHandler(mrSlideSorter, *this, aMousePosition, mpWindow)));
840     }
841 }
842 
843 
844 
845 
SwitchToMultiSelectionMode(const Point aMousePosition,const sal_uInt32 nEventCode)846 void SelectionFunction::SwitchToMultiSelectionMode (
847     const Point aMousePosition,
848     const sal_uInt32 nEventCode)
849 {
850     if (mpModeHandler->GetMode() != MultiSelectionMode)
851         SwitchMode(::boost::shared_ptr<ModeHandler>(
852             new MultiSelectionModeHandler(mrSlideSorter, *this, aMousePosition, nEventCode)));
853 }
854 
855 
856 
857 
SwitchToButtonMode(void)858 bool SelectionFunction::SwitchToButtonMode (void)
859 {
860     // Do not show the buttons for draw pages.
861     ::boost::shared_ptr<ViewShell> pMainViewShell (mrSlideSorter.GetViewShellBase()->GetMainViewShell());
862     if (pMainViewShell
863         && pMainViewShell->GetShellType()!=ViewShell::ST_DRAW
864         && mpModeHandler->GetMode() != ButtonMode)
865     {
866         SwitchMode(::boost::shared_ptr<ModeHandler>(new ButtonModeHandler(mrSlideSorter, *this)));
867         return true;
868     }
869     else
870         return false;
871 }
872 
873 
874 
875 
SwitchMode(const::boost::shared_ptr<ModeHandler> & rpHandler)876 void SelectionFunction::SwitchMode (const ::boost::shared_ptr<ModeHandler>& rpHandler)
877 {
878     // Not all modes allow mouse over indicator.
879     if (mpModeHandler->IsMouseOverIndicatorAllowed() != rpHandler->IsMouseOverIndicatorAllowed())
880     {
881         if ( ! rpHandler->IsMouseOverIndicatorAllowed())
882         {
883             mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
884             mrSlideSorter.GetView().GetButtonBar().ResetPage();
885         }
886         else
887             mrSlideSorter.GetView().UpdatePageUnderMouse(false);
888     }
889 
890     mpModeHandler = rpHandler;
891 }
892 
893 
894 
895 
ResetShiftKeySelectionAnchor(void)896 void SelectionFunction::ResetShiftKeySelectionAnchor (void)
897 {
898     mnShiftKeySelectionAnchor = -1;
899 }
900 
901 
902 
903 
ResetMouseAnchor(void)904 void SelectionFunction::ResetMouseAnchor (void)
905 {
906     if (mpModeHandler && mpModeHandler->GetMode() == NormalMode)
907     {
908         ::boost::shared_ptr<NormalModeHandler> pHandler (
909             ::boost::dynamic_pointer_cast<NormalModeHandler>(mpModeHandler));
910         if (pHandler)
911             pHandler->ResetButtonDownLocation();
912     }
913 }
914 
915 
916 
917 
918 //===== EventDescriptor =======================================================
919 
EventDescriptor(const sal_uInt32 nEventType,const MouseEvent & rEvent,SlideSorter & rSlideSorter)920 SelectionFunction::EventDescriptor::EventDescriptor (
921     const sal_uInt32 nEventType,
922     const MouseEvent& rEvent,
923     SlideSorter& rSlideSorter)
924     : maMousePosition(rEvent.GetPosPixel()),
925       maMouseModelPosition(),
926       mpHitDescriptor(),
927       mpHitPage(),
928       mnEventCode(nEventType),
929       mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
930       meDragMode(InsertionIndicatorHandler::MoveMode),
931       mbMakeSelectionVisible(true),
932       mbIsLeaving(false)
933 {
934     maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition);
935     mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition);
936     if (mpHitDescriptor)
937     {
938         mpHitPage = mpHitDescriptor->GetPage();
939     }
940 
941     mnEventCode |= EncodeMouseEvent(rEvent);
942     mnEventCode |= EncodeState();
943 
944     // Detect the mouse leaving the window.  When not button is pressed then
945     // we can call IsLeaveWindow at the event.  Otherwise we have to make an
946     // explicit test.
947     mbIsLeaving = rEvent.IsLeaveWindow()
948         || ! Rectangle(Point(0,0),
949              rSlideSorter.GetContentWindow()->GetOutputSizePixel()).IsInside(maMousePosition);
950 }
951 
952 
953 
954 
EventDescriptor(const sal_uInt32 nEventType,const AcceptDropEvent & rEvent,const sal_Int8 nDragAction,SlideSorter & rSlideSorter)955 SelectionFunction::EventDescriptor::EventDescriptor (
956     const sal_uInt32 nEventType,
957     const AcceptDropEvent& rEvent,
958     const sal_Int8 nDragAction,
959     SlideSorter& rSlideSorter)
960     : maMousePosition(rEvent.maPosPixel),
961       maMouseModelPosition(),
962       mpHitDescriptor(),
963       mpHitPage(),
964       mnEventCode(nEventType),
965       mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
966       meDragMode(InsertionIndicatorHandler::GetModeFromDndAction(nDragAction)),
967       mbMakeSelectionVisible(true),
968       mbIsLeaving(false)
969 {
970     maMouseModelPosition = rSlideSorter.GetContentWindow()->PixelToLogic(maMousePosition);
971     mpHitDescriptor = rSlideSorter.GetController().GetPageAt(maMousePosition);
972     if (mpHitDescriptor)
973     {
974         mpHitPage = mpHitDescriptor->GetPage();
975     }
976 
977     mnEventCode |= EncodeState();
978 
979     // Detect the mouse leaving the window.  When not button is pressed then
980     // we can call IsLeaveWindow at the event.  Otherwise we have to make an
981     // explicit test.
982     mbIsLeaving = rEvent.mbLeaving
983         || ! Rectangle(Point(0,0),
984              rSlideSorter.GetContentWindow()->GetOutputSizePixel()).IsInside(maMousePosition);
985 }
986 
987 
988 
989 
EventDescriptor(const KeyEvent & rEvent,SlideSorter & rSlideSorter)990 SelectionFunction::EventDescriptor::EventDescriptor (
991     const KeyEvent& rEvent,
992     SlideSorter& rSlideSorter)
993     : maMousePosition(),
994       maMouseModelPosition(),
995       mpHitDescriptor(),
996       mpHitPage(),
997       mnEventCode(KEY_EVENT),
998       mbIsOverButton(rSlideSorter.GetView().GetButtonBar().IsMouseOverButton()),
999       meDragMode(InsertionIndicatorHandler::MoveMode),
1000       mbMakeSelectionVisible(true),
1001       mbIsLeaving(false)
1002 {
1003     model::SharedPageDescriptor pHitDescriptor (
1004         rSlideSorter.GetController().GetFocusManager().GetFocusedPageDescriptor());
1005     if (pHitDescriptor.get() != NULL)
1006     {
1007         mpHitPage = pHitDescriptor->GetPage();
1008         mpHitDescriptor = pHitDescriptor;
1009     }
1010 
1011     mnEventCode |= EncodeKeyEvent(rEvent) | EncodeState();
1012 }
1013 
1014 
1015 
1016 
SetDragMode(const InsertionIndicatorHandler::Mode eMode)1017 void SelectionFunction::EventDescriptor::SetDragMode (const InsertionIndicatorHandler::Mode eMode)
1018 {
1019     meDragMode = eMode;
1020 }
1021 
1022 
1023 
1024 
EncodeMouseEvent(const MouseEvent & rEvent) const1025 sal_uInt32 SelectionFunction::EventDescriptor::EncodeMouseEvent (
1026     const MouseEvent& rEvent) const
1027 {
1028     // Initialize with the type of mouse event.
1029     sal_uInt32 nEventCode (mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION));
1030 
1031     // Detect the affected button.
1032 	switch (rEvent.GetButtons())
1033     {
1034         case MOUSE_LEFT:   nEventCode |= LEFT_BUTTON; break;
1035         case MOUSE_RIGHT:  nEventCode |= RIGHT_BUTTON; break;
1036         case MOUSE_MIDDLE: nEventCode |= MIDDLE_BUTTON; break;
1037     }
1038 
1039     // Detect the number of clicks.
1040     switch (rEvent.GetClicks())
1041     {
1042         case 1: nEventCode |= SINGLE_CLICK; break;
1043         case 2: nEventCode |= DOUBLE_CLICK; break;
1044     }
1045 
1046     // Detect pressed modifier keys.
1047     if (rEvent.IsShift())
1048         nEventCode |= SHIFT_MODIFIER;
1049     if (rEvent.IsMod1())
1050         nEventCode |= CONTROL_MODIFIER;
1051 
1052     // Detect whether the mouse is over one of the active elements inside a
1053     // page object.
1054     if (mbIsOverButton)
1055         nEventCode |= OVER_BUTTON;
1056 
1057     return nEventCode;
1058 }
1059 
1060 
1061 
1062 
EncodeKeyEvent(const KeyEvent & rEvent) const1063 sal_uInt32 SelectionFunction::EventDescriptor::EncodeKeyEvent (const KeyEvent& rEvent) const
1064 {
1065     // The key code in the lower 16 bit.
1066     sal_uInt32 nEventCode (rEvent.GetKeyCode().GetCode());
1067 
1068     // Detect pressed modifier keys.
1069     if (rEvent.GetKeyCode().IsShift())
1070         nEventCode |= SHIFT_MODIFIER;
1071     if (rEvent.GetKeyCode().IsMod1())
1072         nEventCode |= CONTROL_MODIFIER;
1073 
1074     return nEventCode;
1075 }
1076 
1077 
1078 
1079 
EncodeState(void) const1080 sal_uInt32 SelectionFunction::EventDescriptor::EncodeState (void) const
1081 {
1082     sal_uInt32 nEventCode (0);
1083 
1084     // Detect whether the event has happened over a page object.
1085     if (mpHitPage!=NULL && mpHitDescriptor)
1086     {
1087         if (mpHitDescriptor->HasState(model::PageDescriptor::ST_Selected))
1088             nEventCode |= OVER_SELECTED_PAGE;
1089         else
1090             nEventCode |= OVER_UNSELECTED_PAGE;
1091 
1092         // Detect whether the mouse is over one of the active elements
1093         // inside a page object.
1094         if (mbIsOverButton)
1095             nEventCode |= OVER_BUTTON;
1096     }
1097 
1098     return nEventCode;
1099 }
1100 
1101 
1102 
1103 
1104 //===== SelectionFunction::ModeHandler ========================================
1105 
ModeHandler(SlideSorter & rSlideSorter,SelectionFunction & rSelectionFunction,const bool bIsMouseOverIndicatorAllowed)1106 SelectionFunction::ModeHandler::ModeHandler (
1107     SlideSorter& rSlideSorter,
1108     SelectionFunction& rSelectionFunction,
1109     const bool bIsMouseOverIndicatorAllowed)
1110     : mrSlideSorter(rSlideSorter),
1111       mrSelectionFunction(rSelectionFunction),
1112       mbIsMouseOverIndicatorAllowed(bIsMouseOverIndicatorAllowed)
1113 {
1114 }
1115 
1116 
1117 
1118 
~ModeHandler(void)1119 SelectionFunction::ModeHandler::~ModeHandler (void)
1120 {
1121 }
1122 
1123 
1124 
1125 
ReprocessEvent(EventDescriptor & rDescriptor)1126 void SelectionFunction::ModeHandler::ReprocessEvent (EventDescriptor& rDescriptor)
1127 {
1128     mrSelectionFunction.ProcessEvent(rDescriptor);
1129 }
1130 
1131 
1132 
1133 
ProcessEvent(SelectionFunction::EventDescriptor & rDescriptor)1134 void SelectionFunction::ModeHandler::ProcessEvent (
1135     SelectionFunction::EventDescriptor& rDescriptor)
1136 {
1137     PageSelector::BroadcastLock aBroadcastLock (mrSlideSorter);
1138     PageSelector::UpdateLock aUpdateLock (mrSlideSorter);
1139 
1140     bool bIsProcessed (false);
1141     switch (rDescriptor.mnEventCode & (BUTTON_DOWN | BUTTON_UP | MOUSE_MOTION | MOUSE_DRAG))
1142     {
1143         case BUTTON_DOWN:
1144             bIsProcessed = ProcessButtonDownEvent(rDescriptor);
1145             break;
1146 
1147         case BUTTON_UP:
1148             bIsProcessed = ProcessButtonUpEvent(rDescriptor);
1149             break;
1150 
1151         case MOUSE_MOTION:
1152             bIsProcessed = ProcessMotionEvent(rDescriptor);
1153             break;
1154 
1155         case MOUSE_DRAG:
1156             bIsProcessed = ProcessDragEvent(rDescriptor);
1157             break;
1158     }
1159 
1160     if ( ! bIsProcessed)
1161         HandleUnprocessedEvent(rDescriptor);
1162 }
1163 
1164 
1165 
1166 
ProcessButtonDownEvent(EventDescriptor &)1167 bool SelectionFunction::ModeHandler::ProcessButtonDownEvent (EventDescriptor&)
1168 {
1169     return false;
1170 }
1171 
1172 
1173 
1174 
ProcessButtonUpEvent(EventDescriptor &)1175 bool SelectionFunction::ModeHandler::ProcessButtonUpEvent (EventDescriptor&)
1176 {
1177     mrSelectionFunction.SwitchToNormalMode();
1178     return false;
1179 }
1180 
1181 
1182 
1183 
ProcessMotionEvent(EventDescriptor & rDescriptor)1184 bool SelectionFunction::ModeHandler::ProcessMotionEvent (EventDescriptor& rDescriptor)
1185 {
1186     if (mbIsMouseOverIndicatorAllowed)
1187         mrSlideSorter.GetView().UpdatePageUnderMouse(
1188             rDescriptor.maMousePosition,
1189             (rDescriptor.mnEventCode & LEFT_BUTTON) != 0,
1190             true);
1191 
1192     if (rDescriptor.mbIsLeaving)
1193     {
1194         mrSelectionFunction.SwitchToNormalMode();
1195         mrSlideSorter.GetView().SetPageUnderMouse(model::SharedPageDescriptor());
1196 
1197         return true;
1198     }
1199     else
1200         return false;
1201 }
1202 
1203 
1204 
1205 
ProcessDragEvent(EventDescriptor &)1206 bool SelectionFunction::ModeHandler::ProcessDragEvent (EventDescriptor&)
1207 {
1208     return false;
1209 }
1210 
1211 
1212 
1213 
HandleUnprocessedEvent(EventDescriptor &)1214 bool SelectionFunction::ModeHandler::HandleUnprocessedEvent (EventDescriptor&)
1215 {
1216     return false;
1217 }
1218 
1219 
1220 
1221 
SetCurrentPage(const model::SharedPageDescriptor & rpDescriptor)1222 void SelectionFunction::ModeHandler::SetCurrentPage (
1223     const model::SharedPageDescriptor& rpDescriptor)
1224 {
1225     SelectOnePage(rpDescriptor);
1226     mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide(rpDescriptor);
1227 }
1228 
1229 
1230 
1231 
DeselectAllPages(void)1232 void SelectionFunction::ModeHandler::DeselectAllPages (void)
1233 {
1234     mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
1235     mrSelectionFunction.ResetShiftKeySelectionAnchor();
1236 }
1237 
1238 
1239 
1240 
SelectOnePage(const model::SharedPageDescriptor & rpDescriptor)1241 void SelectionFunction::ModeHandler::SelectOnePage (
1242     const model::SharedPageDescriptor& rpDescriptor)
1243 {
1244     DeselectAllPages();
1245     mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor);
1246 }
1247 
1248 
1249 
1250 
SwitchView(const model::SharedPageDescriptor & rpDescriptor)1251 void SelectionFunction::ModeHandler::SwitchView (const model::SharedPageDescriptor& rpDescriptor)
1252 {
1253     // Switch to the draw view.  This is done only when the current
1254     // view is the main view.
1255     ViewShell* pViewShell = mrSlideSorter.GetViewShell();
1256     if (pViewShell!=NULL && pViewShell->IsMainViewShell())
1257     {
1258         if (rpDescriptor.get()!=NULL && rpDescriptor->GetPage()!=NULL)
1259         {
1260             mrSlideSorter.GetModel().GetDocument()->SetSelected(rpDescriptor->GetPage(), sal_True);
1261             pViewShell->GetFrameView()->SetSelectedPage(
1262                 (rpDescriptor->GetPage()->GetPageNum()-1)/2);
1263         }
1264         if (mrSlideSorter.GetViewShellBase() != NULL)
1265         framework::FrameworkHelper::Instance(*mrSlideSorter.GetViewShellBase())->RequestView(
1266             framework::FrameworkHelper::msImpressViewURL,
1267             framework::FrameworkHelper::msCenterPaneURL);
1268     }
1269 }
1270 
1271 
1272 
1273 
StartDrag(const Point & rMousePosition,const InsertionIndicatorHandler::Mode eMode)1274 void SelectionFunction::ModeHandler::StartDrag (
1275     const Point& rMousePosition,
1276     const InsertionIndicatorHandler::Mode eMode)
1277 {
1278     (void)eMode;
1279     // Do not start a drag-and-drop operation when one is already active.
1280     // (when dragging pages from one document into another, pressing a
1281     // modifier key can trigger a MouseMotion event in the originating
1282     // window (focus still in there).  Together with the mouse button pressed
1283     // (drag-and-drop is active) this triggers the start of drag-and-drop.)
1284     if (SD_MOD()->pTransferDrag != NULL)
1285         return;
1286 
1287 	if ( ! mrSlideSorter.GetProperties()->IsUIReadOnly())
1288 	{
1289         mrSelectionFunction.SwitchToDragAndDropMode(rMousePosition);
1290 	}
1291 }
1292 
1293 
1294 
1295 
IsMouseOverIndicatorAllowed(void) const1296 bool SelectionFunction::ModeHandler::IsMouseOverIndicatorAllowed (void) const
1297 {
1298     return mbIsMouseOverIndicatorAllowed;
1299 }
1300 
1301 
1302 
1303 
1304 //===== NormalModeHandler =====================================================
1305 
NormalModeHandler(SlideSorter & rSlideSorter,SelectionFunction & rSelectionFunction)1306 NormalModeHandler::NormalModeHandler (
1307     SlideSorter& rSlideSorter,
1308     SelectionFunction& rSelectionFunction)
1309     : ModeHandler(rSlideSorter, rSelectionFunction, true),
1310       maButtonDownLocation()
1311 {
1312 }
1313 
1314 
1315 
1316 
~NormalModeHandler(void)1317 NormalModeHandler::~NormalModeHandler (void)
1318 {
1319 }
1320 
1321 
1322 
1323 
GetMode(void) const1324 SelectionFunction::Mode NormalModeHandler::GetMode (void) const
1325 {
1326     return SelectionFunction::NormalMode;
1327 }
1328 
1329 
1330 
1331 
Abort(void)1332 void NormalModeHandler::Abort (void)
1333 {
1334 }
1335 
1336 
1337 
1338 
ProcessButtonDownEvent(SelectionFunction::EventDescriptor & rDescriptor)1339 bool NormalModeHandler::ProcessButtonDownEvent (
1340     SelectionFunction::EventDescriptor& rDescriptor)
1341 {
1342     // Remember the location where the left button is pressed.  With
1343     // that we can filter away motion events that are caused by key
1344     // presses.  We also can tune the minimal motion distance that
1345     // triggers a drag-and-drop operation.
1346     if ((rDescriptor.mnEventCode & BUTTON_DOWN) != 0)
1347         maButtonDownLocation = rDescriptor.maMousePosition;
1348 
1349     switch (rDescriptor.mnEventCode)
1350     {
1351         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE:
1352             SetCurrentPage(rDescriptor.mpHitDescriptor);
1353             break;
1354 
1355         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
1356             break;
1357 
1358         case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_SELECTED_PAGE:
1359         case BUTTON_DOWN | LEFT_BUTTON | DOUBLE_CLICK | OVER_UNSELECTED_PAGE:
1360             // A double click allways shows the selected slide in the center
1361             // pane in an edit view.
1362             SetCurrentPage(rDescriptor.mpHitDescriptor);
1363             SwitchView(rDescriptor.mpHitDescriptor);
1364             break;
1365 
1366         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | SHIFT_MODIFIER:
1367         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | SHIFT_MODIFIER:
1368             // Range selection with the shift modifier.
1369             RangeSelect(rDescriptor.mpHitDescriptor);
1370             break;
1371 
1372         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON:
1373         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON:
1374             OSL_ASSERT(mrSlideSorter.GetView().GetButtonBar().IsMouseOverButton());
1375 
1376             // Switch to button mode only when the buttons are visible
1377             // (or being faded in.)
1378             if (mrSlideSorter.GetView().GetButtonBar().IsVisible(rDescriptor.mpHitDescriptor))
1379             {
1380                 if (mrSelectionFunction.SwitchToButtonMode())
1381                     ReprocessEvent(rDescriptor);
1382             }
1383             else
1384             {
1385                 // When the buttons are not (yet) visible then behave like
1386                 // the left button had been clicked over any other part of
1387                 // the slide.
1388                 SetCurrentPage(rDescriptor.mpHitDescriptor);
1389             }
1390             break;
1391 
1392             // Right button for context menu.
1393         case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE:
1394             // Single right click and shift+F10 select as preparation to
1395             // show the context menu.  Change the selection only when the
1396             // page under the mouse is not selected.  In this case the
1397             // selection is set to this single page.  Otherwise the
1398             // selection is not modified.
1399             SetCurrentPage(rDescriptor.mpHitDescriptor);
1400             rDescriptor.mbMakeSelectionVisible = false;
1401             break;
1402 
1403         case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
1404             // Do not change the selection.  Just adjust the insertion indicator.
1405             rDescriptor.mbMakeSelectionVisible = false;
1406             break;
1407 
1408         case BUTTON_DOWN | RIGHT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE:
1409             // Remember the current selection so that when a multi selection
1410             // is started, we can restore the previous selection.
1411             mrSlideSorter.GetModel().SaveCurrentSelection();
1412             DeselectAllPages();
1413             break;
1414 
1415         case ANY_MODIFIER(BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
1416             // Remember the current selection so that when a multi selection
1417             // is started, we can restore the previous selection.
1418             mrSlideSorter.GetModel().SaveCurrentSelection();
1419             DeselectAllPages();
1420             break;
1421 
1422         default:
1423             return false;
1424     }
1425     return true;
1426 }
1427 
1428 
1429 
1430 
ProcessButtonUpEvent(SelectionFunction::EventDescriptor & rDescriptor)1431 bool NormalModeHandler::ProcessButtonUpEvent (
1432     SelectionFunction::EventDescriptor& rDescriptor)
1433 {
1434     bool bIsProcessed (true);
1435     switch (rDescriptor.mnEventCode)
1436     {
1437         case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE:
1438             SetCurrentPage(rDescriptor.mpHitDescriptor);
1439             break;
1440 
1441             // Multi selection with the control modifier.
1442         case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | CONTROL_MODIFIER:
1443             mrSlideSorter.GetController().GetPageSelector().DeselectPage(
1444                 rDescriptor.mpHitDescriptor);
1445             break;
1446 
1447         case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | CONTROL_MODIFIER:
1448             mrSlideSorter.GetController().GetPageSelector().SelectPage(
1449                 rDescriptor.mpHitDescriptor);
1450             mrSlideSorter.GetView().UpdatePageUnderMouse(
1451                 rDescriptor.mpHitDescriptor,
1452                 rDescriptor.maMousePosition,
1453                 false);
1454             break;
1455         case BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE:
1456             break;
1457 
1458         default:
1459             bIsProcessed = false;
1460             break;
1461     }
1462     mrSelectionFunction.SwitchToNormalMode();
1463     return bIsProcessed;
1464 }
1465 
1466 
1467 
1468 
1469 
ProcessMotionEvent(SelectionFunction::EventDescriptor & rDescriptor)1470 bool NormalModeHandler::ProcessMotionEvent (
1471     SelectionFunction::EventDescriptor& rDescriptor)
1472 {
1473     if (ModeHandler::ProcessMotionEvent(rDescriptor))
1474         return true;
1475 
1476     bool bIsProcessed (true);
1477     switch (rDescriptor.mnEventCode)
1478     {
1479         case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE):
1480             //            SetCurrentPage(rDescriptor.mpHitDescriptor);
1481             // Fallthrough
1482 
1483         // A mouse motion without visible substitution starts that.
1484         case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE):
1485         {
1486             if (maButtonDownLocation)
1487             {
1488                 const sal_Int32 nDistance (maButtonDownLocation
1489                     ? ::std::max (
1490                         abs(maButtonDownLocation->X() - rDescriptor.maMousePosition.X()),
1491                         abs(maButtonDownLocation->Y() - rDescriptor.maMousePosition.Y()))
1492                     : 0);
1493                 if (nDistance > 3)
1494                     StartDrag(
1495                         rDescriptor.maMousePosition,
1496                         (rDescriptor.mnEventCode & CONTROL_MODIFIER) != 0
1497                             ? InsertionIndicatorHandler::CopyMode
1498                             : InsertionIndicatorHandler::MoveMode);
1499             }
1500         }
1501         break;
1502 
1503             // A mouse motion not over a page starts a rectangle selection.
1504         case ANY_MODIFIER(MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK | NOT_OVER_PAGE):
1505             mrSelectionFunction.SwitchToMultiSelectionMode(
1506                 rDescriptor.maMouseModelPosition,
1507                 rDescriptor.mnEventCode);
1508             break;
1509 
1510         default:
1511             bIsProcessed = false;
1512             break;
1513     }
1514     return bIsProcessed;
1515 }
1516 
1517 
1518 
1519 
ProcessDragEvent(SelectionFunction::EventDescriptor & rDescriptor)1520 bool NormalModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor)
1521 {
1522     mrSelectionFunction.SwitchToDragAndDropMode(rDescriptor.maMousePosition);
1523     ReprocessEvent(rDescriptor);
1524     return true;
1525 }
1526 
1527 
1528 
1529 
RangeSelect(const model::SharedPageDescriptor & rpDescriptor)1530 void NormalModeHandler::RangeSelect (const model::SharedPageDescriptor& rpDescriptor)
1531 {
1532     PageSelector::UpdateLock aLock (mrSlideSorter);
1533     PageSelector& rSelector (mrSlideSorter.GetController().GetPageSelector());
1534 
1535     model::SharedPageDescriptor pAnchor (rSelector.GetSelectionAnchor());
1536     DeselectAllPages();
1537 
1538     if (pAnchor.get() != NULL)
1539     {
1540         // Select all pages between the anchor and the given one, including
1541         // the two.
1542         const sal_uInt16 nAnchorIndex ((pAnchor->GetPage()->GetPageNum()-1) / 2);
1543         const sal_uInt16 nOtherIndex ((rpDescriptor->GetPage()->GetPageNum()-1) / 2);
1544 
1545         // Iterate over all pages in the range.  Start with the anchor
1546         // page.  This way the PageSelector will recognize it again as
1547         // anchor (the first selected page after a DeselectAllPages()
1548         // becomes the anchor.)
1549         const sal_uInt16 nStep ((nAnchorIndex < nOtherIndex) ? +1 : -1);
1550         sal_uInt16 nIndex (nAnchorIndex);
1551         while (true)
1552         {
1553             rSelector.SelectPage(nIndex);
1554             if (nIndex == nOtherIndex)
1555                 break;
1556             nIndex = nIndex + nStep;
1557         }
1558     }
1559 }
1560 
1561 
1562 
1563 
ResetButtonDownLocation(void)1564 void NormalModeHandler::ResetButtonDownLocation (void)
1565 {
1566     maButtonDownLocation = ::boost::optional<Point>();
1567 }
1568 
1569 
1570 
1571 
1572 //===== MultiSelectionModeHandler =============================================
1573 
MultiSelectionModeHandler(SlideSorter & rSlideSorter,SelectionFunction & rSelectionFunction,const Point & rMouseModelPosition,const sal_uInt32 nEventCode)1574 MultiSelectionModeHandler::MultiSelectionModeHandler (
1575     SlideSorter& rSlideSorter,
1576     SelectionFunction& rSelectionFunction,
1577     const Point& rMouseModelPosition,
1578     const sal_uInt32 nEventCode)
1579     : ModeHandler(rSlideSorter, rSelectionFunction, false),
1580       meSelectionMode(SM_Normal),
1581       maSecondCorner(rMouseModelPosition),
1582       maSavedPointer(mrSlideSorter.GetContentWindow()->GetPointer()),
1583       mnAnchorIndex(-1),
1584       mnSecondIndex(-1),
1585       maButtonBarLock(rSlideSorter)
1586 {
1587     const Pointer aSelectionPointer (POINTER_TEXT);
1588     mrSlideSorter.GetContentWindow()->SetPointer(aSelectionPointer);
1589     SetSelectionModeFromModifier(nEventCode);
1590 }
1591 
1592 
1593 
1594 
1595 
~MultiSelectionModeHandler(void)1596 MultiSelectionModeHandler::~MultiSelectionModeHandler (void)
1597 {
1598     mrSlideSorter.GetContentWindow()->SetPointer(maSavedPointer);
1599 }
1600 
1601 
1602 
1603 
GetMode(void) const1604 SelectionFunction::Mode MultiSelectionModeHandler::GetMode (void) const
1605 {
1606     return SelectionFunction::MultiSelectionMode;
1607 }
1608 
1609 
1610 
1611 
Abort(void)1612 void MultiSelectionModeHandler::Abort (void)
1613 {
1614     mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection());
1615 }
1616 
1617 
1618 
1619 
ProcessEvent(SelectionFunction::EventDescriptor & rDescriptor)1620 void MultiSelectionModeHandler::ProcessEvent (
1621     SelectionFunction::EventDescriptor& rDescriptor)
1622 {
1623     // During a multi selection we do not want sudden jumps of the
1624     // visible area caused by moving newly selected pages into view.
1625     // Therefore disable that temporarily.  The disabler object is
1626     // released at the end of the event processing, after the focus and
1627     // current slide have been updated.
1628     VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
1629 
1630     ModeHandler::ProcessEvent(rDescriptor);
1631 }
1632 
1633 
1634 
1635 
ProcessButtonUpEvent(SelectionFunction::EventDescriptor & rDescriptor)1636 bool MultiSelectionModeHandler::ProcessButtonUpEvent (
1637     SelectionFunction::EventDescriptor& rDescriptor)
1638 {
1639     if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON | SINGLE_CLICK))
1640     {
1641         mrSelectionFunction.SwitchToNormalMode();
1642         return true;
1643     }
1644     else
1645         return false;
1646 }
1647 
1648 
1649 
1650 
ProcessMotionEvent(SelectionFunction::EventDescriptor & rDescriptor)1651 bool MultiSelectionModeHandler::ProcessMotionEvent (
1652     SelectionFunction::EventDescriptor& rDescriptor)
1653 {
1654     // The selection rectangle is visible.  Handle events accordingly.
1655     if (Match(rDescriptor.mnEventCode, MOUSE_MOTION | LEFT_BUTTON | SINGLE_CLICK))
1656     {
1657         SetSelectionModeFromModifier(rDescriptor.mnEventCode);
1658         UpdatePosition(rDescriptor.maMousePosition, true);
1659         rDescriptor.mbMakeSelectionVisible = false;
1660         return true;
1661     }
1662     else
1663         return false;
1664 }
1665 
1666 
1667 
HandleUnprocessedEvent(SelectionFunction::EventDescriptor & rDescriptor)1668 bool MultiSelectionModeHandler::HandleUnprocessedEvent (
1669     SelectionFunction::EventDescriptor& rDescriptor)
1670 {
1671     if ( ! ModeHandler::HandleUnprocessedEvent(rDescriptor))
1672     {
1673         // If the event has not been processed then stop multi selection.
1674         mrSelectionFunction.SwitchToNormalMode();
1675         ReprocessEvent(rDescriptor);
1676     }
1677     return true;
1678 }
1679 
1680 
1681 
1682 
UpdatePosition(const Point & rMousePosition,const bool bAllowAutoScroll)1683 void MultiSelectionModeHandler::UpdatePosition (
1684     const Point& rMousePosition,
1685     const bool bAllowAutoScroll)
1686 {
1687     VisibleAreaManager::TemporaryDisabler aDisabler (mrSlideSorter);
1688 
1689     // Convert window coordinates into model coordinates (we need the
1690     // window coordinates for auto-scrolling because that remains
1691     // constant while scrolling.)
1692     SharedSdWindow pWindow (mrSlideSorter.GetContentWindow());
1693     const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition));
1694 
1695     if ( ! (bAllowAutoScroll && mrSlideSorter.GetController().GetScrollBarManager().AutoScroll(
1696         rMousePosition,
1697         ::boost::bind(
1698             &MultiSelectionModeHandler::UpdatePosition,
1699             this,
1700             rMousePosition,
1701             false))))
1702     {
1703         UpdateModelPosition(aMouseModelPosition);
1704     }
1705 }
1706 
1707 
1708 
1709 
SetSelectionModeFromModifier(const sal_uInt32 nEventCode)1710 void MultiSelectionModeHandler::SetSelectionModeFromModifier (
1711     const sal_uInt32 nEventCode)
1712 {
1713     switch (nEventCode & MODIFIER_MASK)
1714     {
1715         case NO_MODIFIER:
1716             SetSelectionMode(SM_Normal);
1717             break;
1718 
1719         case SHIFT_MODIFIER:
1720             SetSelectionMode(SM_Add);
1721             break;
1722 
1723         case CONTROL_MODIFIER:
1724             SetSelectionMode(SM_Toggle);
1725             break;
1726     }
1727 }
1728 
1729 
1730 
1731 
SetSelectionMode(const SelectionMode eSelectionMode)1732 void MultiSelectionModeHandler::SetSelectionMode (const SelectionMode eSelectionMode)
1733 {
1734     if (meSelectionMode != eSelectionMode)
1735     {
1736         meSelectionMode = eSelectionMode;
1737         UpdateSelection();
1738     }
1739 }
1740 
1741 
1742 
1743 
UpdateSelectionState(const model::SharedPageDescriptor & rpDescriptor,const bool bIsInSelection) const1744 void MultiSelectionModeHandler::UpdateSelectionState (
1745     const model::SharedPageDescriptor& rpDescriptor,
1746     const bool bIsInSelection) const
1747 {
1748     // Determine whether the page was selected before the rectangle
1749     // selection was started.
1750     const bool bWasSelected (rpDescriptor->HasState(model::PageDescriptor::ST_WasSelected));
1751 
1752     // Combine the two selection states depending on the selection mode.
1753     bool bSelect (false);
1754     switch(meSelectionMode)
1755     {
1756         case SM_Normal:
1757             bSelect = bIsInSelection;
1758             break;
1759 
1760         case SM_Add:
1761             bSelect = bIsInSelection || bWasSelected;
1762             break;
1763 
1764         case SM_Toggle:
1765             if (bIsInSelection)
1766                 bSelect = !bWasSelected;
1767             else
1768                 bSelect = bWasSelected;
1769             break;
1770     }
1771 
1772     // Set the new selection state.
1773     if (bSelect)
1774         mrSlideSorter.GetController().GetPageSelector().SelectPage(rpDescriptor);
1775     else
1776         mrSlideSorter.GetController().GetPageSelector().DeselectPage(rpDescriptor);
1777 }
1778 
1779 
1780 
1781 
UpdateModelPosition(const Point & rMouseModelPosition)1782 void MultiSelectionModeHandler::UpdateModelPosition (const Point& rMouseModelPosition)
1783 {
1784     maSecondCorner = rMouseModelPosition;
1785     UpdateSelection();
1786 }
1787 
1788 
1789 
1790 
UpdateSelection(void)1791 void MultiSelectionModeHandler::UpdateSelection (void)
1792 {
1793     view::SlideSorterView::DrawLock aLock (mrSlideSorter);
1794 
1795     model::SlideSorterModel& rModel (mrSlideSorter.GetModel());
1796     const sal_Int32 nPageCount (rModel.GetPageCount());
1797 
1798     const sal_Int32 nIndexUnderMouse (
1799         mrSlideSorter.GetView().GetLayouter().GetIndexAtPoint (
1800             maSecondCorner,
1801             false,
1802             false));
1803     if (nIndexUnderMouse>=0 && nIndexUnderMouse<nPageCount)
1804     {
1805         if (mnAnchorIndex < 0)
1806             mnAnchorIndex = nIndexUnderMouse;
1807         mnSecondIndex = nIndexUnderMouse;
1808 
1809         Range aRange (mnAnchorIndex, mnSecondIndex);
1810         aRange.Justify();
1811 
1812         for (sal_Int32 nIndex=0; nIndex<nPageCount; ++nIndex)
1813         {
1814             UpdateSelectionState(rModel.GetPageDescriptor(nIndex), aRange.IsInside(nIndex));
1815         }
1816     }
1817 }
1818 
1819 
1820 
1821 
1822 //===== DragAndDropModeHandler ================================================
1823 
DragAndDropModeHandler(SlideSorter & rSlideSorter,SelectionFunction & rSelectionFunction,const Point & rMousePosition,::Window * pWindow)1824 DragAndDropModeHandler::DragAndDropModeHandler (
1825     SlideSorter& rSlideSorter,
1826     SelectionFunction& rSelectionFunction,
1827     const Point& rMousePosition,
1828     ::Window* pWindow)
1829     : ModeHandler(rSlideSorter, rSelectionFunction, false)
1830 {
1831     SdTransferable* pDragTransferable = SD_MOD()->pTransferDrag;
1832     if (pDragTransferable==NULL && mrSlideSorter.GetViewShell() != NULL)
1833     {
1834         SlideSorterViewShell* pSlideSorterViewShell
1835             = dynamic_cast<SlideSorterViewShell*>(mrSlideSorter.GetViewShell());
1836         if (pSlideSorterViewShell != NULL)
1837             pSlideSorterViewShell->StartDrag(rMousePosition, pWindow);
1838         pDragTransferable = SD_MOD()->pTransferDrag;
1839     }
1840 
1841     mpDragAndDropContext.reset(new DragAndDropContext(mrSlideSorter));
1842     mrSlideSorter.GetController().GetInsertionIndicatorHandler()->Start(
1843         pDragTransferable != NULL
1844             && pDragTransferable->GetView()==&mrSlideSorter.GetView());
1845 }
1846 
1847 
1848 
1849 
~DragAndDropModeHandler(void)1850 DragAndDropModeHandler::~DragAndDropModeHandler (void)
1851 {
1852     if (mpDragAndDropContext)
1853     {
1854         // Disconnect the substitution handler from this selection function.
1855         mpDragAndDropContext->SetTargetSlideSorter();
1856         mpDragAndDropContext.reset();
1857     }
1858     mrSlideSorter.GetController().GetInsertionIndicatorHandler()->End(Animator::AM_Animated);
1859 }
1860 
1861 
1862 
1863 
GetMode(void) const1864 SelectionFunction::Mode DragAndDropModeHandler::GetMode (void) const
1865 {
1866     return SelectionFunction::DragAndDropMode;
1867 }
1868 
1869 
1870 
1871 
Abort(void)1872 void DragAndDropModeHandler::Abort (void)
1873 {
1874     mrSlideSorter.GetController().GetClipboard().Abort();
1875     if (mpDragAndDropContext)
1876         mpDragAndDropContext->Dispose();
1877     //    mrSlideSorter.GetView().RequestRepaint(mrSlideSorter.GetModel().RestoreSelection());
1878 }
1879 
1880 
1881 
1882 
ProcessButtonUpEvent(SelectionFunction::EventDescriptor & rDescriptor)1883 bool DragAndDropModeHandler::ProcessButtonUpEvent (
1884     SelectionFunction::EventDescriptor& rDescriptor)
1885 {
1886     if (Match(rDescriptor.mnEventCode, BUTTON_UP | LEFT_BUTTON))
1887     {
1888         // The following Process() call may lead to the desctruction
1889         // of rDescriptor.mpHitDescriptor so release our reference to it.
1890         rDescriptor.mpHitDescriptor.reset();
1891         mrSelectionFunction.SwitchToNormalMode();
1892         return true;
1893     }
1894     else
1895         return false;
1896 }
1897 
1898 
1899 
1900 
ProcessDragEvent(SelectionFunction::EventDescriptor & rDescriptor)1901 bool DragAndDropModeHandler::ProcessDragEvent (SelectionFunction::EventDescriptor& rDescriptor)
1902 {
1903     OSL_ASSERT(mpDragAndDropContext);
1904 
1905     if (rDescriptor.mbIsLeaving)
1906     {
1907         mrSelectionFunction.SwitchToNormalMode();
1908     }
1909     else if (mpDragAndDropContext)
1910     {
1911         mpDragAndDropContext->UpdatePosition(
1912             rDescriptor.maMousePosition,
1913             rDescriptor.meDragMode);
1914     }
1915 
1916     return true;
1917 }
1918 
1919 
1920 
1921 
1922 //===== ButtonModeHandler =====================================================
1923 
ButtonModeHandler(SlideSorter & rSlideSorter,SelectionFunction & rSelectionFunction)1924 ButtonModeHandler::ButtonModeHandler (
1925     SlideSorter& rSlideSorter,
1926     SelectionFunction& rSelectionFunction)
1927     : ModeHandler(rSlideSorter, rSelectionFunction, true)
1928 {
1929 }
1930 
1931 
1932 
1933 
~ButtonModeHandler(void)1934 ButtonModeHandler::~ButtonModeHandler (void)
1935 {
1936 }
1937 
1938 
1939 
1940 
GetMode(void) const1941 SelectionFunction::Mode ButtonModeHandler::GetMode (void) const
1942 {
1943     return SelectionFunction::ButtonMode;
1944 }
1945 
1946 
1947 
1948 
Abort(void)1949 void ButtonModeHandler::Abort (void)
1950 {
1951 }
1952 
1953 
1954 
1955 
ProcessButtonDownEvent(SelectionFunction::EventDescriptor & rDescriptor)1956 bool ButtonModeHandler::ProcessButtonDownEvent (SelectionFunction::EventDescriptor& rDescriptor)
1957 {
1958     switch (rDescriptor.mnEventCode)
1959     {
1960         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_UNSELECTED_PAGE | OVER_BUTTON:
1961         case BUTTON_DOWN | LEFT_BUTTON | SINGLE_CLICK | OVER_SELECTED_PAGE | OVER_BUTTON:
1962             // Remember page and button index.  When mouse button is
1963             // released over same page and button then invoke action of that
1964             // button.
1965             mrSlideSorter.GetView().GetButtonBar().ProcessButtonDownEvent(
1966                 rDescriptor.mpHitDescriptor,
1967                 rDescriptor.maMouseModelPosition);
1968             return true;
1969 
1970         default:
1971             return false;
1972     }
1973 }
1974 
1975 
1976 
1977 
ProcessButtonUpEvent(SelectionFunction::EventDescriptor & rDescriptor)1978 bool ButtonModeHandler::ProcessButtonUpEvent (SelectionFunction::EventDescriptor& rDescriptor)
1979 {
1980     switch (rDescriptor.mnEventCode & BUTTON_MASK)
1981     {
1982         case LEFT_BUTTON:
1983             mrSlideSorter.GetView().GetButtonBar().ProcessButtonUpEvent(
1984                 rDescriptor.mpHitDescriptor,
1985                 rDescriptor.maMouseModelPosition);
1986             mrSelectionFunction.SwitchToNormalMode();
1987             return true;
1988     }
1989 
1990     return false;
1991 }
1992 
1993 
1994 
1995 
ProcessMotionEvent(SelectionFunction::EventDescriptor & rDescriptor)1996 bool ButtonModeHandler::ProcessMotionEvent (SelectionFunction::EventDescriptor& rDescriptor)
1997 {
1998     switch (rDescriptor.mnEventCode & (MOUSE_MOTION | BUTTON_MASK))
1999     {
2000         case MOUSE_MOTION | LEFT_BUTTON:
2001             mrSlideSorter.GetView().GetButtonBar().ProcessMouseMotionEvent(
2002                 rDescriptor.mpHitDescriptor,
2003                 rDescriptor.maMouseModelPosition,
2004                 true);
2005             return true;
2006 
2007         case MOUSE_MOTION:
2008             mrSlideSorter.GetView().GetButtonBar().ProcessMouseMotionEvent(
2009                 rDescriptor.mpHitDescriptor,
2010                 rDescriptor.maMouseModelPosition,
2011                 false);
2012             return true;
2013     }
2014 
2015     return false;
2016 }
2017 
2018 
2019 
2020 
2021 } } } // end of namespace ::sd::slidesorter::controller
2022