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