1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <fusel.hxx>
21 #include <svx/svddrgmt.hxx>
22 #include <svx/svdpagv.hxx>
23 #include <svx/svdogrp.hxx>
24 #include <svx/scene3d.hxx>
25 #include <vcl/imapobj.hxx>
26 #include <unotools/securityoptions.hxx>
27 #include <svx/svxids.hrc>
28 #include <svx/xfillit0.hxx>
29 #include <svx/ImageMapInfo.hxx>
30 #include <sfx2/viewfrm.hxx>
31 #include <svl/stritem.hxx>
32 #include <svl/intitem.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <editeng/flditem.hxx>
36 
37 #include <svx/svdotable.hxx>
38 
39 #include <app.hrc>
40 
41 #include <sdmod.hxx>
42 #include <DrawDocShell.hxx>
43 #include <stlpool.hxx>
44 #include <fudraw.hxx>
45 #include <ViewShell.hxx>
46 #include <ViewShellBase.hxx>
47 #include <FrameView.hxx>
48 #include <View.hxx>
49 #include <Window.hxx>
50 #include <drawdoc.hxx>
51 #include <DrawViewShell.hxx>
52 #include <ToolBarManager.hxx>
53 #include <Client.hxx>
54 
55 #include <svx/svdundo.hxx>
56 
57 #include <svx/sdrhittesthelper.hxx>
58 
59 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
60 #include <comphelper/lok.hxx>
61 
62 using namespace ::com::sun::star;
63 
64 namespace sd {
65 
FuSelection(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)66 FuSelection::FuSelection (
67     ViewShell* pViewSh,
68     ::sd::Window* pWin,
69     ::sd::View* pView,
70     SdDrawDocument* pDoc,
71     SfxRequest& rReq)
72     : FuDraw(pViewSh, pWin, pView, pDoc, rReq),
73       bTempRotation(false),
74       bSelectionChanged(false),
75       pHdl(nullptr),
76       bSuppressChangesOfSelection(false),
77       bMirrorSide0(false),
78       nEditMode(SID_BEZIER_MOVE),
79       pWaterCanCandidate(nullptr)
80      //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point,
81      //and SHIFT+ENTER key to decide the position and draw the new insert point
82     ,bBeginInsertPoint(false),
83       oldPoint(0,0)
84   ,bMovedToCenterPoint(false)
85 {
86 }
87 
Create(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)88 rtl::Reference<FuPoor> FuSelection::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
89 {
90     rtl::Reference<FuPoor> xFunc( new FuSelection( pViewSh, pWin, pView, pDoc, rReq ) );
91     xFunc->DoExecute(rReq);
92     return xFunc;
93 }
94 
DoExecute(SfxRequest & rReq)95 void FuSelection::DoExecute( SfxRequest& rReq )
96 {
97     FuDraw::DoExecute( rReq );
98 
99     // Select object bar
100     SelectionHasChanged();
101 }
102 
~FuSelection()103 FuSelection::~FuSelection()
104 {
105     mpView->UnmarkAllPoints();
106     mpView->ResetCreationActive();
107 
108     if ( mpView->GetDragMode() != SdrDragMode::Move )
109     {
110         mpView->SetDragMode(SdrDragMode::Move);
111     }
112 }
113 
114 namespace {
lcl_followHyperlinkAllowed(const MouseEvent & rMEvt)115     bool lcl_followHyperlinkAllowed(const MouseEvent& rMEvt) {
116         SvtSecurityOptions aSecOpt;
117         if (!rMEvt.IsMod1() && aSecOpt.IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink))
118             return false;
119         if (rMEvt.IsMod1() && !aSecOpt.IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink))
120             return false;
121         return true;
122     }
123 }
124 
MouseButtonDown(const MouseEvent & rMEvt)125 bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt)
126 {
127     pHdl = nullptr;
128     bool bReturn = FuDraw::MouseButtonDown(rMEvt);
129     bool bWaterCan = SD_MOD()->GetWaterCan();
130     const bool bReadOnly = mpDocSh->IsReadOnly();
131     // When the right mouse button is pressed then only select objects
132     // (and deselect others) as a preparation for showing the context
133     // menu.
134     const bool bSelectionOnly = rMEvt.IsRight();
135 
136     bMBDown = true;
137     bSelectionChanged = false;
138 
139     if ( mpView->IsAction() )
140     {
141         if ( rMEvt.IsRight() )
142             mpView->BckAction();
143         return true;
144     }
145 
146     sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
147     sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
148 
149     if (comphelper::LibreOfficeKit::isActive())
150     {
151         // When tiled rendering, we always work in logic units, use the non-pixel constants.
152         nDrgLog = DRGLOG;
153         nHitLog = HITLOG;
154     }
155 
156     // The following code is executed for right clicks as well as for left
157     // clicks in order to modify the selection for the right button as a
158     // preparation for the context menu.  The functions BegMarkObject() and
159     // BegDragObject(), however, are not called for right clicks because a)
160     // it makes no sense and b) to have IsAction() return sal_False when called
161     // from Command() which is a prerequisite for the context menu.
162     if ((rMEvt.IsLeft() || rMEvt.IsRight())
163         && !mpView->IsAction()
164         && (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints()))
165     {
166         /******************************************************************
167         * NO BEZIER_EDITOR
168         ******************************************************************/
169         mpWindow->CaptureMouse();
170         pHdl = mpView->PickHandle(aMDPos);
171 
172         Degree100 nAngle0  = GetAngle(aMDPos - mpView->GetRef1());
173         nAngle0 -= 27000_deg100;
174         nAngle0 = NormAngle36000(nAngle0);
175         bMirrorSide0 = nAngle0 < 18000_deg100;
176 
177         if (!pHdl && mpView->Is3DRotationCreationActive())
178         {
179             /******************************************************************
180             * If 3D-rotation bodies are about to be created,
181             * end creation now.
182             ******************************************************************/
183             bSuppressChangesOfSelection = true;
184             mpWindow->EnterWait();
185             mpView->End3DCreation();
186             bSuppressChangesOfSelection = false;
187             mpView->ResetCreationActive();
188             mpWindow->LeaveWait();
189         }
190 
191         bool bTextEdit = false;
192         SdrViewEvent aVEvt;
193         SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
194 
195         if ( eHit == SdrHitKind::TextEditObj && ( mpViewShell->GetFrameView()->IsQuickEdit() || dynamic_cast< sdr::table::SdrTableObj* >( aVEvt.pObj ) != nullptr ) )
196         {
197             bTextEdit = true;
198         }
199 
200         // When clicking into a URl field, also go to text edit mode (when not following the link)
201         if (!bTextEdit && eHit == SdrHitKind::UrlField && !rMEvt.IsMod2() && !lcl_followHyperlinkAllowed(rMEvt))
202             bTextEdit = true;
203 
204         bool bPreventModify = mpDocSh->IsReadOnly();
205         if (bPreventModify && mpDocSh->GetSignPDFCertificate().is())
206         {
207             // If the just added signature line shape is selected, allow moving / resizing it.
208             bPreventModify = false;
209         }
210 
211         if(!bTextEdit
212             && !bPreventModify
213             && ((mpView->IsMarkedHit(aMDPos, nHitLog) && !rMEvt.IsShift() && !rMEvt.IsMod2()) || pHdl != nullptr)
214             && (rMEvt.GetClicks() != 2)
215             )
216         {
217             if (!pHdl && mpView->Is3DRotationCreationActive())
218             {
219                 // Switch between 3D-rotation body -> selection
220                 mpView->ResetCreationActive();
221             }
222             else if (bWaterCan)
223             {
224                 // Remember the selected object for proper handling in
225                 // MouseButtonUp().
226                 pWaterCanCandidate = pickObject (aMDPos);
227             }
228             else
229             {
230                 // hit handle or marked object
231                 bFirstMouseMove = true;
232                 aDragTimer.Start();
233             }
234 
235             if ( ! rMEvt.IsRight())
236                 if (mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog))
237                     mpView->GetDragMethod()->SetShiftPressed( rMEvt.IsShift() );
238             bReturn = true;
239         }
240         else
241         {
242             SdrPageView* pPV = nullptr;
243             SdrObject* pObj = !rMEvt.IsMod2() ? mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO) : nullptr;
244             if (pObj)
245             {
246                 mpView->BegMacroObj(aMDPos, nHitLog, pObj, pPV, mpWindow);
247                 bReturn = true;
248             }
249             else if ( bTextEdit )
250             {
251                 sal_uInt16 nSdrObjKind = aVEvt.pObj->GetObjIdentifier();
252 
253                 if (aVEvt.pObj->GetObjInventor() == SdrInventor::Default &&
254                     (nSdrObjKind == OBJ_TEXT ||
255                      nSdrObjKind == OBJ_TITLETEXT ||
256                      nSdrObjKind == OBJ_OUTLINETEXT ||
257                      !aVEvt.pObj->IsEmptyPresObj()))
258                 {
259                     // Seamless Editing: branch to text input
260                     if (!rMEvt.IsShift())
261                         mpView->UnmarkAll();
262 
263                     SfxUInt16Item aItem(SID_TEXTEDIT, 1);
264                     mpViewShell->GetViewFrame()->GetDispatcher()->
265                     ExecuteList(SID_TEXTEDIT,
266                             SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
267                             { &aItem });
268                     return bReturn; // CAUTION, due to the synchronous slot the object is deleted now
269                 }
270             }
271             else if ( !rMEvt.IsMod2() && rMEvt.GetClicks() == 1 &&
272                       aVEvt.eEvent == SdrEventKind::ExecuteUrl )
273              {
274                 mpWindow->ReleaseMouse();
275 
276                 // If tiled rendering, let client handles URL execution and early returns.
277                 if (comphelper::LibreOfficeKit::isActive())
278                 {
279                     SfxViewShell& rSfxViewShell = mpViewShell->GetViewShellBase();
280                     rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_HYPERLINK_CLICKED, aVEvt.pURLField->GetURL().toUtf8().getStr());
281                     return true;
282                 }
283 
284                 if (!lcl_followHyperlinkAllowed(rMEvt))
285                     return true;
286 
287                 SfxStringItem aStrItem(SID_FILE_NAME, aVEvt.pURLField->GetURL());
288                 SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName());
289                 SfxBoolItem aBrowseItem( SID_BROWSE, true );
290                 SfxViewFrame* pFrame = mpViewShell->GetViewFrame();
291                 mpWindow->ReleaseMouse();
292 
293                 if (rMEvt.IsMod1())
294                 {
295                     // Open in new frame
296                     pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
297                         SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
298                         { &aStrItem, &aBrowseItem, &aReferer });
299                 }
300                 else
301                 {
302                     // Open in current frame
303                     SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
304                     pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC,
305                         SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
306                         { &aStrItem, &aFrameItem, &aBrowseItem, &aReferer });
307                 }
308 
309                 bReturn = true;
310             }
311             else if(!rMEvt.IsMod2()
312                 && dynamic_cast< const DrawViewShell *>( mpViewShell ) !=  nullptr
313                 )
314             {
315                 pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER);
316                 if (pObj)
317                 {
318                     // Handle ImageMap click when not just selecting
319                     if (!bSelectionOnly)
320                     {
321                         if (lcl_followHyperlinkAllowed(rMEvt))
322                             bReturn = HandleImageMapClick(pObj, aMDPos);
323                     }
324 
325                     if (!bReturn
326                         && (dynamic_cast<const SdrObjGroup*>(pObj) != nullptr
327                             || dynamic_cast<const E3dScene*>(pObj) != nullptr))
328                     {
329                         if (rMEvt.GetClicks() == 1)
330                         {
331                             // Look into the group
332                             pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV,
333                                                    SdrSearchOptions::ALSOONMASTER
334                                                        | SdrSearchOptions::DEEP);
335                             if (pObj && lcl_followHyperlinkAllowed(rMEvt))
336                                 bReturn = HandleImageMapClick(pObj, aMDPos);
337                         }
338                         else if (!bReadOnly && rMEvt.GetClicks() == 2)
339                         {
340                             // New: double click on selected Group object
341                             // enter group
342                             if (!bSelectionOnly
343                                 && pObj->getSdrPageFromSdrObject() == pPV->GetPage())
344                                 bReturn = pPV->EnterGroup(pObj);
345                         }
346                     }
347                 }
348 
349                 // #i71727# replaced else here with two possibilities, once the original else (!pObj)
350                 // and also ignoring the found object when it's on a masterpage
351                 if(!pObj || (pObj->getSdrPageFromSdrObject() && pObj->getSdrPageFromSdrObject()->IsMasterPage()))
352                 {
353                     if(mpView->IsGroupEntered() && 2 == rMEvt.GetClicks())
354                     {
355                         // New: double click on empty space/on obj on MasterPage, leave group
356                         mpView->LeaveOneGroup();
357                         bReturn = true;
358                     }
359                 }
360             }
361 
362             if (!bReturn)
363             {
364                 if (bWaterCan)
365                 {
366                     if ( ! (rMEvt.IsShift() || rMEvt.IsMod2()))
367                     {
368                         // Find the object under the current mouse position
369                         // and store it for the MouseButtonUp() method to
370                         // evaluate.
371                         pWaterCanCandidate = pickObject (aMDPos);
372                     }
373                 }
374                 else
375                 {
376                     bReturn = true;
377                     bool bDeactivateOLE = false;
378 
379                     if ( !rMEvt.IsShift() && !rMEvt.IsMod2() )
380                     {
381                         OSL_ASSERT (mpViewShell->GetViewShell()!=nullptr);
382                         Client* pIPClient = static_cast<Client*>(
383                             mpViewShell->GetViewShell()->GetIPClient());
384 
385                         if (pIPClient && pIPClient->IsObjectInPlaceActive())
386                         {
387                             // OLE-object gets deactivated in subsequent UnmarkAll()
388                             bDeactivateOLE = true;
389                         }
390 
391                         mpView->UnmarkAll();
392                     }
393 
394                     bool bMarked = false;
395 
396                     if ( !rMEvt.IsMod1() && !bDeactivateOLE)
397                     {
398                         if ( rMEvt.IsMod2() )
399                         {
400                             bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift() );
401                         }
402                         else
403                         {
404                             bool bToggle = false;
405 
406                             if (rMEvt.IsShift() && mpView->GetMarkedObjectList().GetMarkCount() > 1)
407                             {
408                                 // No Toggle on single selection
409                                 bToggle = true;
410                             }
411 
412                             bMarked = mpView->MarkObj(aMDPos, nHitLog, bToggle);
413                         }
414                     }
415 
416                     if( !bDeactivateOLE )
417                     {
418                         if ( !bReadOnly &&
419                              bMarked                                                   &&
420                              (!rMEvt.IsShift() || mpView->IsMarkedHit(aMDPos, nHitLog)))
421                         {
422                             /**********************************************************
423                              * Move object
424                              **********************************************************/
425                             aDragTimer.Start();
426 
427                             pHdl=mpView->PickHandle(aMDPos);
428                             if ( ! rMEvt.IsRight())
429                                 mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
430                         }
431                         else
432                         {
433                             /**********************************************************
434                              * Select object
435                              **********************************************************/
436                             if ( ! rMEvt.IsRight())
437                                 mpView->BegMarkObj(aMDPos);
438                         }
439                     }
440 
441                     if( bMarked && bTempRotation && (nSlotId == SID_OBJECT_ROTATE) && !rMEvt.IsShift() && (rMEvt.GetClicks() != 2) )
442                     {
443                         nSlotId = SID_OBJECT_SELECT;
444                         Activate();
445                     }
446                 }
447             }
448         }
449     }
450     else if ( !bReadOnly
451               && (rMEvt.IsLeft() || rMEvt.IsRight())
452               && !mpView->IsAction())
453     {
454         /**********************************************************************
455         * BEZIER-EDITOR
456         **********************************************************************/
457         mpWindow->CaptureMouse();
458         SdrViewEvent aVEvt;
459         SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
460 
461         if (eHit == SdrHitKind::Handle && aVEvt.pHdl->GetKind() == SdrHdlKind::BezierWeight)
462         {
463             /******************************************************************
464             * Drag Handle
465             ******************************************************************/
466             if ( ! rMEvt.IsRight())
467                 mpView->BegDragObj(aMDPos, nullptr, aVEvt.pHdl, nDrgLog);
468         }
469         else if (eHit == SdrHitKind::MarkedObject && nEditMode == SID_BEZIER_INSERT)
470         {
471             /******************************************************************
472             * Insert glue point
473             ******************************************************************/
474             mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1());
475         }
476         else if (eHit == SdrHitKind::MarkedObject && rMEvt.IsMod1())
477         {
478             /******************************************************************
479             * Select glue point
480             ******************************************************************/
481             if (!rMEvt.IsShift())
482                 mpView->UnmarkAllPoints();
483 
484             if ( ! rMEvt.IsRight())
485                 mpView->BegMarkPoints(aMDPos);
486         }
487         else if (eHit == SdrHitKind::MarkedObject && !rMEvt.IsShift() && !rMEvt.IsMod2())
488         {
489             /******************************************************************
490             * Move object
491             ******************************************************************/
492             if ( ! rMEvt.IsRight())
493                 mpView->BegDragObj(aMDPos, nullptr, nullptr, nDrgLog);
494         }
495         else if (eHit == SdrHitKind::Handle)
496         {
497             /******************************************************************
498             * Select glue point
499             ******************************************************************/
500             if (!mpView->IsPointMarked(*aVEvt.pHdl) || rMEvt.IsShift())
501             {
502                 if (!rMEvt.IsShift())
503                 {
504                     mpView->UnmarkAllPoints();
505                     pHdl = mpView->PickHandle(aMDPos);
506                 }
507                 else
508                 {
509                     if (mpView->IsPointMarked(*aVEvt.pHdl))
510                     {
511                         mpView->UnmarkPoint(*aVEvt.pHdl);
512                         pHdl = nullptr;
513                     }
514                     else
515                     {
516                         pHdl = mpView->PickHandle(aMDPos);
517                     }
518                 }
519 
520                 if (pHdl)
521                 {
522                     mpView->MarkPoint(*pHdl);
523                     if ( ! rMEvt.IsRight())
524                         mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
525 
526                 }
527             }
528             else
529             {
530                 // Point IS marked and NO shift is pressed. Start
531                 // dragging of selected point(s)
532                 pHdl = mpView->PickHandle(aMDPos);
533                 if(pHdl && ! rMEvt.IsRight())
534                     mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
535             }
536         }
537         else
538         {
539             /******************************************************************
540             * Select or drag object
541             ******************************************************************/
542             if (!rMEvt.IsShift() && !rMEvt.IsMod2() && eHit == SdrHitKind::UnmarkedObject)
543             {
544                mpView->UnmarkAllObj();
545             }
546 
547             bool bMarked = false;
548 
549             if (!rMEvt.IsMod1())
550             {
551                 if (rMEvt.IsMod2())
552                 {
553                     bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift());
554                 }
555                 else
556                 {
557                     bMarked = mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift());
558                 }
559             }
560 
561             if (bMarked &&
562                 (!rMEvt.IsShift() || eHit == SdrHitKind::MarkedObject))
563             {
564                 // Move object
565                 if ( ! rMEvt.IsRight())
566                     mpView->BegDragObj(aMDPos, nullptr, aVEvt.pHdl, nDrgLog);
567             }
568             else if (mpView->AreObjectsMarked())
569             {
570                 /**************************************************************
571                 * Select glue point
572                 **************************************************************/
573                 if (!rMEvt.IsShift())
574                     mpView->UnmarkAllPoints();
575 
576                 if ( ! rMEvt.IsRight())
577                     mpView->BegMarkPoints(aMDPos);
578             }
579             else
580             {
581                 /**************************************************************
582                 * Select object
583                 **************************************************************/
584                 if ( ! rMEvt.IsRight())
585                     mpView->BegMarkObj(aMDPos);
586             }
587 
588             ForcePointer(&rMEvt);
589         }
590     }
591 
592     if (!bIsInDragMode)
593     {
594         ForcePointer(&rMEvt);
595     }
596 
597     return bReturn;
598 }
599 
MouseMove(const MouseEvent & rMEvt)600 bool FuSelection::MouseMove(const MouseEvent& rMEvt)
601 {
602     bool bReturn = FuDraw::MouseMove(rMEvt);
603 
604     if (aDragTimer.IsActive())
605     {
606         if(bFirstMouseMove)
607         {
608             bFirstMouseMove = false;
609         }
610         else
611         {
612             aDragTimer.Stop();
613         }
614     }
615 
616     if (mpView->IsAction())
617     {
618         Point aPix(rMEvt.GetPosPixel());
619         Point aPnt(mpWindow->PixelToLogic(aPix));
620 
621         ForceScroll(aPix);
622 
623         if (mpView->IsInsObjPoint())
624         {
625             mpView->MovInsObjPoint(aPnt);
626         }
627         else
628         {
629             mpView->MovAction(aPnt);
630         }
631     }
632 
633     ForcePointer(&rMEvt);
634 
635     return bReturn;
636 }
637 
MouseButtonUp(const MouseEvent & rMEvt)638 bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt)
639 {
640     bool bReturn = false;
641     // When the right mouse button is pressed then only select objects
642     // (and deselect others) as a preparation for showing the context
643     // menu.
644     const bool bSelectionOnly = rMEvt.IsRight();
645 
646     if (aDragTimer.IsActive() )
647     {
648         aDragTimer.Stop();
649         bIsInDragMode = false;
650     }
651 
652     if( !mpView )
653         return false;
654 
655     Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
656     sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
657     sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
658 
659     if (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints())
660     {
661         /**********************************************************************
662         * NO BEZIER_EDITOR
663         **********************************************************************/
664         if ( mpView->IsDragObj() )
665         {
666             /******************************************************************
667             * Object was moved
668             ******************************************************************/
669             FrameView* pFrameView = mpViewShell->GetFrameView();
670             bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
671 
672             if (bDragWithCopy)
673             {
674                 bDragWithCopy = !mpView->IsPresObjSelected(false);
675             }
676 
677             mpView->SetDragWithCopy(bDragWithCopy);
678             mpView->EndDragObj( mpView->IsDragWithCopy() );
679 
680             mpView->ForceMarkedToAnotherPage();
681 
682             if (!rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() &&
683                 !bSelectionChanged                   &&
684                 std::abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
685                 std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
686             {
687                 /*************************************************************
688                 * If a user wants to click on an object in front of a marked
689                 * one, he releases the mouse button immediately
690                 **************************************************************/
691                 SdrPageView* pPV;
692                 SdrObject* pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::BEFOREMARK);
693                 if (pObj && pPV->IsObjMarkable(pObj))
694                 {
695                     mpView->UnmarkAllObj();
696                     mpView->MarkObj(pObj,pPV);
697                     return true;
698                 }
699                 /**************************************************************
700                 * Toggle between selection and rotation
701                 **************************************************************/
702                 SdrObject* pSingleObj = nullptr;
703 
704                 if (mpView->GetMarkedObjectList().GetMarkCount()==1)
705                 {
706                     pSingleObj = mpView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
707                 }
708 
709                 if (nSlotId == SID_OBJECT_SELECT
710                     && !comphelper::LibreOfficeKit::isActive()
711                     && mpView->IsRotateAllowed()
712 
713                     && (rMEvt.GetClicks() != 2)
714                     && (mpViewShell->GetFrameView()->IsClickChangeRotation()
715                         || (pSingleObj
716                             && pSingleObj->GetObjInventor()==SdrInventor::E3d))
717                     && ! bSelectionOnly)
718 
719                 {
720                     bTempRotation = true;
721                     nSlotId = SID_OBJECT_ROTATE;
722                     Activate();
723                 }
724                 else if (nSlotId == SID_OBJECT_ROTATE)
725                 {
726                     nSlotId = SID_OBJECT_SELECT;
727                     Activate();
728                 }
729             }
730             else if (nSlotId == SID_CONVERT_TO_3D_LATHE)
731             {
732                 if (!pHdl)
733                 {
734                     bSuppressChangesOfSelection = true;
735                     mpView->Start3DCreation();
736                     bSuppressChangesOfSelection = false;
737                 }
738                 else if (pHdl->GetKind() != SdrHdlKind::MirrorAxis &&
739                          pHdl->GetKind() != SdrHdlKind::Ref1 &&
740                          pHdl->GetKind() != SdrHdlKind::Ref2 && mpView->Is3DRotationCreationActive())
741                 {
742                     /*********************************************************
743                     * If 3D-rotation bodies are about to be created,
744                     * end creation now
745                     **********************************************************/
746                      Degree100 nAngle1  = GetAngle(aPnt - mpView->GetRef1());
747                      nAngle1 -= 27000_deg100;
748                      nAngle1 = NormAngle36000(nAngle1);
749                      bool bMirrorSide1 = nAngle1 < 18000_deg100;
750 
751                      if (bMirrorSide0 != bMirrorSide1)
752                      {
753                          bSuppressChangesOfSelection = true;
754                          mpWindow->EnterWait();
755                          mpView->End3DCreation();
756                          bSuppressChangesOfSelection = false;
757                          nSlotId = SID_OBJECT_SELECT;
758                          mpWindow->LeaveWait();
759                          Activate();
760                     }
761                 }
762             }
763         }
764         else if (rMEvt.IsMod1()
765             && !rMEvt.IsMod2()
766             && std::abs(aPnt.X() - aMDPos.X()) < nDrgLog
767             && std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
768         {
769             // Enter group
770             mpView->MarkObj(aPnt, nHitLog, rMEvt.IsShift(), rMEvt.IsMod1());
771         }
772 
773         if (mpView->IsAction() )
774         {
775             mpView->EndAction();
776         }
777 
778         if( SD_MOD()->GetWaterCan() )
779         {
780             if( rMEvt.IsRight() )
781             {
782                 // In watering-can mode, on press onto right mouse button, an undo is executed
783                 mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_UNDO, SfxCallMode::ASYNCHRON );
784             }
785             else if (pWaterCanCandidate != nullptr)
786             {
787                 // Is the candidate object still under the mouse?
788                 if (pickObject (aPnt) == pWaterCanCandidate)
789                 {
790                     SdStyleSheetPool* pPool = static_cast<SdStyleSheetPool*>(
791                         mpDocSh->GetStyleSheetPool());
792                     if (pPool != nullptr)
793                     {
794                         SfxStyleSheet* pStyleSheet = static_cast<SfxStyleSheet*>(
795                             pPool->GetActualStyleSheet());
796                         if (pStyleSheet != nullptr && mpView->IsUndoEnabled() )
797                         {
798                             // Added UNDOs for the WaterCan mode. This was never done in
799                             // the past, thus it was missing all the time.
800                             std::unique_ptr<SdrUndoAction> pUndoAttr = mpDoc->GetSdrUndoFactory().CreateUndoAttrObject(*pWaterCanCandidate, true, true);
801                             mpView->BegUndo(pUndoAttr->GetComment());
802                             mpView->AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoGeoObject(*pWaterCanCandidate));
803                             mpView->AddUndo(std::move(pUndoAttr));
804 
805                             pWaterCanCandidate->SetStyleSheet (pStyleSheet, false);
806 
807                             mpView->EndUndo();
808                         }
809                     }
810                 }
811             }
812             // else when there has been no object under the mouse when the
813             // button was pressed then nothing happens even when there is
814             // one now.
815         }
816 
817         sal_uInt16 nClicks = rMEvt.GetClicks();
818 
819         if (nClicks == 2 && rMEvt.IsLeft() && bMBDown &&
820             !rMEvt.IsMod1() && !rMEvt.IsShift() )
821         {
822             DoubleClick(rMEvt);
823         }
824 
825         bMBDown = false;
826 
827         ForcePointer(&rMEvt);
828         pHdl = nullptr;
829         mpWindow->ReleaseMouse();
830         SdrObject* pSingleObj = nullptr;
831         const size_t nMarkCount = mpView->GetMarkedObjectList().GetMarkCount();
832 
833         if (nMarkCount==1)
834         {
835             pSingleObj = mpView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
836         }
837 
838         if ( (nSlotId != SID_OBJECT_SELECT && nMarkCount==0)                    ||
839              ( mpView->GetDragMode() == SdrDragMode::Crook &&
840               !mpView->IsCrookAllowed( mpView->IsCrookNoContortion() ) ) ||
841              ( mpView->GetDragMode() == SdrDragMode::Shear &&
842               !mpView->IsShearAllowed() && !mpView->IsDistortAllowed() ) ||
843              ( nSlotId==SID_CONVERT_TO_3D_LATHE && pSingleObj &&
844               (pSingleObj->GetObjInventor() != SdrInventor::Default         ||
845                pSingleObj->GetObjIdentifier() == OBJ_MEASURE) ) )
846         {
847             bReturn = true;
848             ForcePointer(&rMEvt);
849             pHdl = nullptr;
850             mpWindow->ReleaseMouse();
851             FuDraw::MouseButtonUp(rMEvt);
852             mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::SYNCHRON);
853             return bReturn; // CAUTION, due to the synchronous slot, the object is deleted now.
854         }
855 
856         FuDraw::MouseButtonUp(rMEvt);
857     }
858     else
859     {
860         /**********************************************************************
861         * BEZIER_EDITOR
862         **********************************************************************/
863         if ( mpView->IsAction() )
864         {
865             if ( mpView->IsInsObjPoint() )
866             {
867                 mpView->EndInsObjPoint(SdrCreateCmd::ForceEnd);
868             }
869             else if ( mpView->IsDragObj() )
870             {
871                 FrameView* pFrameView = mpViewShell->GetFrameView();
872                 bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
873 
874                 if (bDragWithCopy)
875                 {
876                     bDragWithCopy = !mpView->IsPresObjSelected(false);
877                 }
878 
879                 mpView->SetDragWithCopy(bDragWithCopy);
880                 mpView->EndDragObj( mpView->IsDragWithCopy() );
881             }
882             else
883             {
884                 mpView->EndAction();
885 
886                 sal_uInt16 nDrgLog2 = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
887                 Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
888 
889                 if (std::abs(aMDPos.X() - aPos.X()) < nDrgLog2 &&
890                     std::abs(aMDPos.Y() - aPos.Y()) < nDrgLog2 &&
891                     !rMEvt.IsShift() && !rMEvt.IsMod2())
892                 {
893                     SdrViewEvent aVEvt;
894                     SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
895 
896                     if (eHit == SdrHitKind::NONE)
897                     {
898                         // Click on the same place - unselect
899                         mpView->UnmarkAllObj();
900                     }
901                 }
902             }
903         }
904         else if (!rMEvt.IsShift() && rMEvt.IsMod1() && !rMEvt.IsMod2() &&
905                  std::abs(aPnt.X() - aMDPos.X()) < nDrgLog &&
906                  std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog)
907         {
908             // Enter group
909             mpView->MarkObj(aPnt, nHitLog, false, rMEvt.IsMod1());
910         }
911 
912         ForcePointer(&rMEvt);
913         pHdl = nullptr;
914         mpWindow->ReleaseMouse();
915 
916         FuDraw::MouseButtonUp(rMEvt);
917     }
918 
919     return bReturn;
920 }
921 
922 /**
923  * Process keyboard input
924  * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
925  */
KeyInput(const KeyEvent & rKEvt)926 bool FuSelection::KeyInput(const KeyEvent& rKEvt)
927 {
928     bool bReturn = false;
929 
930     switch (rKEvt.GetKeyCode().GetCode())
931     {
932         case KEY_ESCAPE:
933         {
934             bReturn = FuSelection::cancel();
935         }
936         break;
937         //add keyboard operation for insert points in drawing curve
938         case KEY_UP:
939         case KEY_DOWN:
940         case KEY_LEFT:
941         case KEY_RIGHT:
942         {
943             if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT)){
944                 ::tools::Long nX = 0;
945                 ::tools::Long nY = 0;
946                 sal_uInt16  nCode = rKEvt.GetKeyCode().GetCode();
947                 if (nCode == KEY_UP)
948                 {
949                     // scroll up
950                     nX = 0;
951                     nY =-1;
952                 }
953                 else if (nCode == KEY_DOWN)
954                 {
955                     // scroll down
956                     nX = 0;
957                     nY = 1;
958                 }
959                 else if (nCode == KEY_LEFT)
960                 {
961                     // scroll left
962                     nX =-1;
963                     nY = 0;
964                 }
965                 else if (nCode == KEY_RIGHT)
966                 {
967                     // scroll right
968                     nX = 1;
969                     nY = 0;
970                 }
971 
972                 Point centerPoint;
973                 ::tools::Rectangle rect = mpView->GetMarkedObjRect();
974                 centerPoint = mpWindow->LogicToPixel(rect.Center());
975                 Point aPoint = bMovedToCenterPoint? oldPoint:centerPoint;
976                 Point ePoint = aPoint + Point(nX,nY);
977                 mpWindow->SetPointerPosPixel(ePoint);
978                 //simulate mouse move action
979                 MouseEvent eMevt(ePoint, 1, MouseEventModifiers::DRAGMOVE, MOUSE_LEFT, 0);
980                 MouseMove(eMevt);
981                 oldPoint = ePoint;
982                 bMovedToCenterPoint = true;
983                 bReturn = true;
984             }
985         }
986         break;
987         case KEY_RETURN:
988             if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT))
989             {
990                 if(!bBeginInsertPoint)
991                 {
992                     //simulate mouse button down action
993                     MouseEvent aMevt(oldPoint, 1,
994                                      MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::DRAGMOVE,
995                                      MOUSE_LEFT, KEY_SHIFT);
996                     MouseButtonDown(aMevt);
997                     mpWindow->CaptureMouse();
998                     bBeginInsertPoint = true;
999                 }
1000                 else
1001                 {
1002                     //simulate mouse button up action
1003                     MouseEvent rMEvt(oldPoint, 1,
1004                                      MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::ENTERWINDOW,
1005                                      MOUSE_LEFT, KEY_SHIFT);
1006                     MouseButtonUp(rMEvt);
1007                     bBeginInsertPoint = false;
1008                 }
1009                 bReturn= true;
1010             }
1011             break;
1012     }
1013     if (!bReturn)
1014     {
1015         bReturn = FuDraw::KeyInput(rKEvt);
1016 
1017         if(mpView->GetMarkedObjectList().GetMarkCount() == 0)
1018         {
1019             mpView->ResetCreationActive();
1020 
1021             mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
1022         }
1023     }
1024 
1025     return bReturn;
1026 
1027 }
1028 
Activate()1029 void FuSelection::Activate()
1030 {
1031     SdrDragMode eMode;
1032     mpView->ResetCreationActive();
1033     mpView->SetEditMode(SdrViewEditMode::Edit);
1034 
1035     switch( nSlotId )
1036     {
1037         case SID_OBJECT_ROTATE:
1038         {
1039             eMode = SdrDragMode::Rotate;
1040 
1041             if ( mpView->GetDragMode() != eMode )
1042                 mpView->SetDragMode(eMode);
1043         }
1044         break;
1045 
1046         case SID_OBJECT_MIRROR:
1047         {
1048             eMode = SdrDragMode::Mirror;
1049 
1050             if ( mpView->GetDragMode() != eMode )
1051                 mpView->SetDragMode(eMode);
1052         }
1053         break;
1054 
1055         case SID_OBJECT_CROP:
1056         {
1057             eMode = SdrDragMode::Crop;
1058 
1059             if ( mpView->GetDragMode() != eMode )
1060                 mpView->SetDragMode(eMode);
1061         }
1062         break;
1063 
1064         case SID_OBJECT_TRANSPARENCE:
1065         {
1066             eMode = SdrDragMode::Transparence;
1067 
1068             if ( mpView->GetDragMode() != eMode )
1069                 mpView->SetDragMode(eMode);
1070         }
1071         break;
1072 
1073         case SID_OBJECT_GRADIENT:
1074         {
1075             eMode = SdrDragMode::Gradient;
1076 
1077             if ( mpView->GetDragMode() != eMode )
1078                 mpView->SetDragMode(eMode);
1079         }
1080         break;
1081 
1082         case SID_OBJECT_SHEAR:
1083         {
1084             eMode = SdrDragMode::Shear;
1085 
1086             if ( mpView->GetDragMode() != eMode )
1087                 mpView->SetDragMode(eMode);
1088         }
1089         break;
1090 
1091         case SID_OBJECT_CROOK_ROTATE:
1092         {
1093             eMode = SdrDragMode::Crook;
1094 
1095             if ( mpView->GetDragMode() != eMode )
1096             {
1097                 mpView->SetDragMode(eMode);
1098                 mpView->SetCrookMode(SdrCrookMode::Rotate);
1099             }
1100         }
1101         break;
1102 
1103         case SID_OBJECT_CROOK_SLANT:
1104         {
1105             eMode = SdrDragMode::Crook;
1106 
1107             if ( mpView->GetDragMode() != eMode )
1108             {
1109                 mpView->SetDragMode(eMode);
1110                 mpView->SetCrookMode(SdrCrookMode::Slant);
1111             }
1112         }
1113         break;
1114 
1115         case SID_OBJECT_CROOK_STRETCH:
1116         {
1117             eMode = SdrDragMode::Crook;
1118 
1119             if ( mpView->GetDragMode() != eMode )
1120             {
1121                 mpView->SetDragMode(eMode);
1122                 mpView->SetCrookMode(SdrCrookMode::Stretch);
1123             }
1124         }
1125         break;
1126 
1127         case SID_CONVERT_TO_3D_LATHE:
1128         {
1129             eMode = SdrDragMode::Mirror;
1130             bSuppressChangesOfSelection = true;
1131 
1132             if ( mpView->GetDragMode() != eMode )
1133                 mpView->SetDragMode(eMode);
1134 
1135             if (!mpView->Is3DRotationCreationActive())
1136                 mpView->Start3DCreation();
1137 
1138             bSuppressChangesOfSelection = false;
1139         }
1140         break;
1141 
1142         default:
1143         {
1144             eMode = SdrDragMode::Move;
1145 
1146             if ( mpView->GetDragMode() != eMode )
1147                 mpView->SetDragMode(eMode);
1148         }
1149         break;
1150     }
1151 
1152     if (nSlotId != SID_OBJECT_ROTATE)
1153     {
1154         bTempRotation = false;
1155     }
1156 
1157     FuDraw::Activate();
1158 }
1159 
SelectionHasChanged()1160 void FuSelection::SelectionHasChanged()
1161 {
1162     bSelectionChanged = true;
1163 
1164     FuDraw::SelectionHasChanged();
1165 
1166     if (mpView->Is3DRotationCreationActive() && !bSuppressChangesOfSelection)
1167     {
1168         // Switch rotation body -> selection
1169         mpView->ResetCreationActive();
1170         nSlotId = SID_OBJECT_SELECT;
1171         Activate();
1172     }
1173 
1174     // Activate the right tool bar for the current context of the view.
1175     mpViewShell->GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*mpViewShell, *mpView);
1176 }
1177 
1178 /**
1179  * Set current bezier edit mode
1180  */
SetEditMode(sal_uInt16 nMode)1181 void FuSelection::SetEditMode(sal_uInt16 nMode)
1182 {
1183     nEditMode = nMode;
1184 
1185     if (nEditMode == SID_BEZIER_INSERT)
1186     {
1187         mpView->SetInsObjPointMode(true);
1188     }
1189     else
1190     {
1191         mpView->SetInsObjPointMode(false);
1192     }
1193 
1194     ForcePointer();
1195 
1196     SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
1197     rBindings.Invalidate(SID_BEZIER_MOVE);
1198     rBindings.Invalidate(SID_BEZIER_INSERT);
1199 }
1200 
1201 /**
1202  * Execute ImageMap interaction
1203  */
HandleImageMapClick(const SdrObject * pObj,const Point & rPos)1204 bool FuSelection::HandleImageMapClick(const SdrObject* pObj, const Point& rPos)
1205 {
1206     bool bClosed = pObj->IsClosedObj();
1207     bool bFilled = false;
1208 
1209     if (bClosed)
1210     {
1211         SfxItemSet aSet(mpDoc->GetPool());
1212 
1213         aSet.Put(pObj->GetMergedItemSet());
1214 
1215         const XFillStyleItem& rFillStyle = aSet.Get(XATTR_FILLSTYLE);
1216         bFilled = rFillStyle.GetValue() != drawing::FillStyle_NONE;
1217     }
1218 
1219     const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
1220     sal_uInt16 nHitLog = sal_uInt16(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width());
1221     const ::tools::Long n2HitLog = nHitLog * 2;
1222     Point aHitPosR(rPos);
1223     Point aHitPosL(rPos);
1224     Point aHitPosT(rPos);
1225     Point aHitPosB(rPos);
1226 
1227     aHitPosR.AdjustX(n2HitLog);
1228     aHitPosL.AdjustX(-n2HitLog);
1229     aHitPosT.AdjustY(n2HitLog);
1230     aHitPosB.AdjustY(-n2HitLog);
1231 
1232     if (!bClosed || !bFilled
1233         || (SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer,
1234                                   false)
1235             && SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(),
1236                                      pVisiLayer, false)
1237             && SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(),
1238                                      pVisiLayer, false)
1239             && SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(),
1240                                      pVisiLayer, false)))
1241     {
1242         if (SvxIMapInfo::GetIMapInfo(pObj))
1243         {
1244             const IMapObject* pIMapObj = SvxIMapInfo::GetHitIMapObject(pObj, rPos);
1245 
1246             if (pIMapObj && !pIMapObj->GetURL().isEmpty())
1247             {
1248                 // Jump to Document
1249                 mpWindow->ReleaseMouse();
1250                 SfxStringItem aStrItem(SID_FILE_NAME, pIMapObj->GetURL());
1251                 SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName());
1252                 SfxViewFrame* pFrame = mpViewShell->GetViewFrame();
1253                 SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame);
1254                 SfxBoolItem aBrowseItem(SID_BROWSE, true);
1255                 mpWindow->ReleaseMouse();
1256                 pFrame->GetDispatcher()->ExecuteList(
1257                     SID_OPENDOC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
1258                     { &aStrItem, &aFrameItem, &aBrowseItem, &aReferer });
1259 
1260                 return true;
1261             }
1262         }
1263     }
1264 
1265     return false;
1266 }
1267 
1268 /** is called when the current function should be aborted. <p>
1269     This is used when a function gets a KEY_ESCAPE but can also
1270     be called directly.
1271 
1272     @returns true if an active function was aborted
1273 */
cancel()1274 bool FuSelection::cancel()
1275 {
1276     if (mpView->Is3DRotationCreationActive())
1277     {
1278         mpView->ResetCreationActive();
1279         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
1280         return true;
1281     }
1282     else
1283     {
1284         return false;
1285     }
1286 }
1287 
pickObject(const Point & rTestPoint)1288 SdrObject* FuSelection::pickObject (const Point& rTestPoint)
1289 {
1290     SdrPageView* pPageView;
1291     sal_uInt16 nHitLog = sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width());
1292     return mpView->PickObj(rTestPoint, nHitLog, pPageView, SdrSearchOptions::PICKMARKABLE);
1293 }
1294 
ForcePointer(const MouseEvent * pMEvt)1295 void FuSelection::ForcePointer(const MouseEvent* pMEvt)
1296 {
1297     if(bMovedToCenterPoint && !bBeginInsertPoint && pMEvt)
1298     {
1299         MouseEvent aMEvt(pMEvt->GetPosPixel(), pMEvt->GetClicks(),
1300             pMEvt->GetMode(), pMEvt->GetButtons(), pMEvt->GetModifier() & ~KEY_SHIFT);
1301         FuDraw::ForcePointer(&aMEvt);
1302     }
1303     else
1304     {
1305         FuDraw::ForcePointer(pMEvt);
1306     }
1307 }
1308 
1309 } // end of namespace sd
1310 
1311 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1312