1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <basic/sbstar.hxx>
22 #include <svx/svddrgmt.hxx>
23 #include <svx/svdpagv.hxx>
24 #include <svx/svdogrp.hxx>
25 #include <svx/polysc3d.hxx>
26 #include "drawview.hxx"
27 #include <svtools/imapobj.hxx>
28 #include <svl/urihelper.hxx>
29 #include <unotools/localfilehelper.hxx>
30 #include <svx/svxids.hrc>
31 #include <svx/xfillit0.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/viewfrm.hxx>
34 #include <svl/aeitem.hxx>
35 #include <svl/stritem.hxx>
36 #include <svl/intitem.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <tools/urlobj.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <editeng/eeitem.hxx>
41 #include <editeng/flditem.hxx>
43 #include <svx/svdotable.hxx>
46 #include "strings.hrc"
47 #include "res_bmp.hrc"
48 #include "GraphicDocShell.hxx"
50 #include "DrawDocShell.hxx"
51 #include "stlpool.hxx"
52 #include "anminfo.hxx"
54 #include "ViewShell.hxx"
55 #include "ViewShellBase.hxx"
56 #include "FrameView.hxx"
59 #include "drawdoc.hxx"
61 #include "DrawViewShell.hxx"
62 #include "ToolBarManager.hxx"
64 #include <svx/globl3d.hxx>
67 #include "slideshow.hxx"
69 #include <svx/svdundo.hxx>
70 #include <avmedia/mediawindow.hxx>
72 #include <svx/sdrhittesthelper.hxx>
74 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
76 using namespace ::com::sun::star
;
80 TYPEINIT1( FuSelection
, FuDraw
);
82 FuSelection::FuSelection (
88 : FuDraw(pViewSh
, pWin
, pView
, pDoc
, rReq
),
90 bSelectionChanged(false),
91 bHideAndAnimate(false),
93 bSuppressChangesOfSelection(false),
95 nEditMode(SID_BEZIER_MOVE
),
96 pWaterCanCandidate(NULL
)
97 //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point,
98 //and SHIFT+ENTER key to decide the position and draw the new insert point
99 ,bBeginInsertPoint(false),
101 ,bMovedToCenterPoint(false)
105 rtl::Reference
<FuPoor
> FuSelection::Create( ViewShell
* pViewSh
, ::sd::Window
* pWin
, ::sd::View
* pView
, SdDrawDocument
* pDoc
, SfxRequest
& rReq
)
107 rtl::Reference
<FuPoor
> xFunc( new FuSelection( pViewSh
, pWin
, pView
, pDoc
, rReq
) );
108 xFunc
->DoExecute(rReq
);
112 void FuSelection::DoExecute( SfxRequest
& rReq
)
114 FuDraw::DoExecute( rReq
);
117 SelectionHasChanged();
120 FuSelection::~FuSelection()
122 mpView
->UnmarkAllPoints();
123 mpView
->ResetCreationActive();
125 if ( mpView
->GetDragMode() != SDRDRAG_MOVE
)
127 mpView
->SetDragMode(SDRDRAG_MOVE
);
131 bool FuSelection::MouseButtonDown(const MouseEvent
& rMEvt
)
134 bHideAndAnimate
= false;
137 bool bReturn
= FuDraw::MouseButtonDown(rMEvt
);
138 bool bWaterCan
= SD_MOD()->GetWaterCan();
139 const bool bReadOnly
= mpDocSh
->IsReadOnly();
140 // When the right mouse button is pressed then only select objects
141 // (and deselect others) as a preparation for showing the context
143 const bool bSelectionOnly
= rMEvt
.IsRight();
146 bSelectionChanged
= false;
148 if ( mpView
->IsAction() )
150 if ( rMEvt
.IsRight() )
155 sal_uInt16 nDrgLog
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(DRGPIX
,0)).Width() );
156 sal_uInt16 nHitLog
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(HITPIX
,0)).Width() );
158 if (mpDoc
->isTiledRendering())
160 // When tiled rendering, we always work in logic units, use the non-pixel constants.
165 // The following code is executed for right clicks as well as for left
166 // clicks in order to modify the selection for the right button as a
167 // preparation for the context menu. The functions BegMarkObject() and
168 // BegDragObject(), however, are not called for right clicks because a)
169 // it makes no sense and b) to have IsAction() return sal_False when called
170 // from Command() which is a prerequisite for the context menu.
171 if ((rMEvt
.IsLeft() || rMEvt
.IsRight())
172 && !mpView
->IsAction()
173 && (mpView
->IsFrameDragSingles() || !mpView
->HasMarkablePoints()))
175 /******************************************************************
177 ******************************************************************/
178 mpWindow
->CaptureMouse();
179 pHdl
= mpView
->PickHandle(aMDPos
);
183 long nAngle0
= GetAngle(aMDPos
- mpView
->GetRef1());
185 nAngle0
= NormAngle360(nAngle0
);
186 bMirrorSide0
= nAngle0
< 18000L;
188 if (!pHdl
&& mpView
->Is3DRotationCreationActive())
190 /******************************************************************
191 * If 3D-rotation bodies are about to be created,
193 ******************************************************************/
194 bSuppressChangesOfSelection
= true;
195 mpWindow
->EnterWait();
196 mpView
->End3DCreation();
197 bSuppressChangesOfSelection
= false;
198 mpView
->ResetCreationActive();
199 mpWindow
->LeaveWait();
202 bool bTextEdit
= false;
204 SdrHitKind eHit
= mpView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
206 if ( eHit
== SDRHIT_TEXTEDITOBJ
&& ( mpViewShell
->GetFrameView()->IsQuickEdit() || dynamic_cast< sdr::table::SdrTableObj
* >( aVEvt
.pObj
) != NULL
) )
212 && !mpDocSh
->IsReadOnly()
213 && ((mpView
->IsMarkedHit(aMDPos
, nHitLog
) && !rMEvt
.IsShift() && !rMEvt
.IsMod2()) || pHdl
!= NULL
)
214 && (rMEvt
.GetClicks() != 2)
217 if (!pHdl
&& mpView
->Is3DRotationCreationActive())
219 // Switch between 3D-rotation body -> selection
220 mpView
->ResetCreationActive();
224 // Remember the selected object for proper handling in
226 pWaterCanCandidate
= pickObject (aMDPos
);
230 // hit handle or marked object
231 bFirstMouseMove
= true;
235 if ( ! rMEvt
.IsRight())
236 if (mpView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, pHdl
, nDrgLog
))
237 mpView
->GetDragMethod()->SetShiftPressed( rMEvt
.IsShift() );
242 if (!rMEvt
.IsMod2() && mpView
->PickObj(aMDPos
, mpView
->getHitTolLog(), pObj
, pPV
, SdrSearchOptions::PICKMACRO
))
244 mpView
->BegMacroObj(aMDPos
, nHitLog
, pObj
, pPV
, mpWindow
);
247 else if ( bTextEdit
)
249 sal_uInt16 nSdrObjKind
= aVEvt
.pObj
->GetObjIdentifier();
251 if (aVEvt
.pObj
->GetObjInventor() == SdrInventor
&&
252 (nSdrObjKind
== OBJ_TEXT
||
253 nSdrObjKind
== OBJ_TITLETEXT
||
254 nSdrObjKind
== OBJ_OUTLINETEXT
||
255 !aVEvt
.pObj
->IsEmptyPresObj()))
257 // Seamless Editing: branch to text input
258 if (!rMEvt
.IsShift())
261 SfxUInt16Item
aItem(SID_TEXTEDIT
, 1);
262 mpViewShell
->GetViewFrame()->GetDispatcher()->
263 Execute(SID_TEXTEDIT
, SfxCallMode::SYNCHRON
|
264 SfxCallMode::RECORD
, &aItem
, 0L);
265 return bReturn
; // CAUTION, due to the synchronous slot the object is deleted now
268 else if ( !rMEvt
.IsMod2() && rMEvt
.GetClicks() == 1 &&
269 aVEvt
.eEvent
== SDREVENT_EXECUTEURL
)
271 mpWindow
->ReleaseMouse();
272 SfxStringItem
aStrItem(SID_FILE_NAME
, aVEvt
.pURLField
->GetURL());
273 SfxStringItem
aReferer(SID_REFERER
, mpDocSh
->GetMedium()->GetName());
274 SfxBoolItem
aBrowseItem( SID_BROWSE
, true );
275 SfxViewFrame
* pFrame
= mpViewShell
->GetViewFrame();
276 mpWindow
->ReleaseMouse();
278 // If tiled rendering, let client handles URL execution and early returns.
279 if (mpDoc
->isTiledRendering())
281 mpDoc
->libreOfficeKitCallback(LOK_CALLBACK_HYPERLINK_CLICKED
,
282 aVEvt
.pURLField
->GetURL().toUtf8().getStr());
289 pFrame
->GetDispatcher()->Execute(SID_OPENDOC
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
290 &aStrItem
, &aBrowseItem
, &aReferer
, 0L);
294 // Open in current frame
295 SfxFrameItem
aFrameItem(SID_DOCFRAME
, pFrame
);
296 pFrame
->GetDispatcher()->Execute(SID_OPENDOC
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
297 &aStrItem
, &aFrameItem
, &aBrowseItem
, &aReferer
, 0L);
302 else if(!rMEvt
.IsMod2()
303 && mpViewShell
->ISA(DrawViewShell
)
306 if(mpView
->PickObj(aMDPos
, mpView
->getHitTolLog(), pObj
, pPV
, SdrSearchOptions::ALSOONMASTER
))
308 // Animate object when not just selecting.
309 if ( ! bSelectionOnly
)
310 bReturn
= AnimateObj(pObj
, aMDPos
);
312 if (!bReturn
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dPolyScene
)))
314 if(rMEvt
.GetClicks() == 1)
316 // Look into the group
317 if (mpView
->PickObj(aMDPos
, mpView
->getHitTolLog(), pObj
, pPV
, SdrSearchOptions::ALSOONMASTER
| SdrSearchOptions::DEEP
))
318 bReturn
= AnimateObj(pObj
, aMDPos
);
320 else if( !bReadOnly
&& rMEvt
.GetClicks() == 2)
322 // New: double click on selected Group object
324 if ( ! bSelectionOnly
325 && pObj
->GetPage() == pPV
->GetPage())
326 bReturn
= pPV
->EnterGroup(pObj
);
331 // #i71727# replaced else here with two possibilities, once the original else (!pObj)
332 // and also ignoring the found object when it's on a masterpage
333 if(!pObj
|| (pObj
->GetPage() && pObj
->GetPage()->IsMasterPage()))
335 if(mpView
->IsGroupEntered() && 2 == rMEvt
.GetClicks())
337 // New: double click on empty space/on obj on MasterPage, leave group
338 mpView
->LeaveOneGroup();
348 if ( ! (rMEvt
.IsShift() || rMEvt
.IsMod2()))
350 // Find the object under the current mouse position
351 // and store it for the MouseButtonUp() method to
353 pWaterCanCandidate
= pickObject (aMDPos
);
359 bool bDeactivateOLE
= false;
361 if ( !rMEvt
.IsShift() && !rMEvt
.IsMod2() )
363 OSL_ASSERT (mpViewShell
->GetViewShell()!=NULL
);
364 Client
* pIPClient
= static_cast<Client
*>(
365 mpViewShell
->GetViewShell()->GetIPClient());
367 if (pIPClient
&& pIPClient
->IsObjectInPlaceActive())
369 // OLE-Objekt gets deactivated in subsequent UnmarkAll()
370 bDeactivateOLE
= true;
376 bool bMarked
= false;
378 if ( !rMEvt
.IsMod1() && !bDeactivateOLE
)
380 if ( rMEvt
.IsMod2() )
382 bMarked
= mpView
->MarkNextObj(aMDPos
, nHitLog
, rMEvt
.IsShift() );
386 bool bToggle
= false;
388 if (rMEvt
.IsShift() && mpView
->GetMarkedObjectList().GetMarkCount() > 1)
390 // No Toggle on single selection
394 bMarked
= mpView
->MarkObj(aMDPos
, nHitLog
, bToggle
, false);
398 if( !bDeactivateOLE
)
402 (!rMEvt
.IsShift() || mpView
->IsMarkedHit(aMDPos
, nHitLog
)))
404 /**********************************************************
406 **********************************************************/
409 pHdl
=mpView
->PickHandle(aMDPos
);
410 if ( ! rMEvt
.IsRight())
411 mpView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, pHdl
, nDrgLog
);
415 /**********************************************************
417 **********************************************************/
418 if ( ! rMEvt
.IsRight())
419 mpView
->BegMarkObj(aMDPos
);
423 if( bMarked
&& bTempRotation
&& (nSlotId
== SID_OBJECT_ROTATE
) && !rMEvt
.IsShift() && (rMEvt
.GetClicks() != 2) )
425 nSlotId
= SID_OBJECT_SELECT
;
433 && (rMEvt
.IsLeft() || rMEvt
.IsRight())
434 && !mpView
->IsAction())
436 /**********************************************************************
438 **********************************************************************/
439 mpWindow
->CaptureMouse();
441 SdrHitKind eHit
= mpView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
443 if (eHit
== SDRHIT_HANDLE
&& aVEvt
.pHdl
->GetKind() == HDL_BWGT
)
445 /******************************************************************
447 ******************************************************************/
448 if ( ! rMEvt
.IsRight())
449 mpView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, aVEvt
.pHdl
, nDrgLog
);
451 else if (eHit
== SDRHIT_MARKEDOBJECT
&& nEditMode
== SID_BEZIER_INSERT
)
453 /******************************************************************
455 ******************************************************************/
456 mpView
->BegInsObjPoint(aMDPos
, rMEvt
.IsMod1());
458 else if (eHit
== SDRHIT_MARKEDOBJECT
&& rMEvt
.IsMod1())
460 /******************************************************************
462 ******************************************************************/
463 if (!rMEvt
.IsShift())
464 mpView
->UnmarkAllPoints();
466 if ( ! rMEvt
.IsRight())
467 mpView
->BegMarkPoints(aMDPos
);
469 else if (eHit
== SDRHIT_MARKEDOBJECT
&& !rMEvt
.IsShift() && !rMEvt
.IsMod2())
471 /******************************************************************
473 ******************************************************************/
474 if ( ! rMEvt
.IsRight())
475 mpView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, NULL
, nDrgLog
);
477 else if (eHit
== SDRHIT_HANDLE
)
479 /******************************************************************
481 ******************************************************************/
482 if (!mpView
->IsPointMarked(*aVEvt
.pHdl
) || rMEvt
.IsShift())
484 if (!rMEvt
.IsShift())
486 mpView
->UnmarkAllPoints();
487 pHdl
= mpView
->PickHandle(aMDPos
);
491 if (mpView
->IsPointMarked(*aVEvt
.pHdl
))
493 mpView
->UnmarkPoint(*aVEvt
.pHdl
);
498 pHdl
= mpView
->PickHandle(aMDPos
);
504 mpView
->MarkPoint(*pHdl
);
505 if ( ! rMEvt
.IsRight())
506 mpView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, pHdl
, nDrgLog
);
512 // Point IS marked and NO shift is pressed. Start
513 // dragging of selected point(s)
514 pHdl
= mpView
->PickHandle(aMDPos
);
516 if ( ! rMEvt
.IsRight())
517 mpView
->BegDragObj(aMDPos
, (OutputDevice
*)NULL
, pHdl
, nDrgLog
);
522 /******************************************************************
523 * Select or drag object
524 ******************************************************************/
525 if (!rMEvt
.IsShift() && !rMEvt
.IsMod2() && eHit
== SDRHIT_UNMARKEDOBJECT
)
527 mpView
->UnmarkAllObj();
530 bool bMarked
= false;
536 bMarked
= mpView
->MarkNextObj(aMDPos
, nHitLog
, rMEvt
.IsShift());
540 bMarked
= mpView
->MarkObj(aMDPos
, nHitLog
, rMEvt
.IsShift(), false);
545 (!rMEvt
.IsShift() || eHit
== SDRHIT_MARKEDOBJECT
))
548 if ( ! rMEvt
.IsRight())
549 mpView
->BegDragObj(aMDPos
, (OutputDevice
*) NULL
, aVEvt
.pHdl
, nDrgLog
);
551 else if (mpView
->AreObjectsMarked())
553 /**************************************************************
555 **************************************************************/
556 if (!rMEvt
.IsShift())
557 mpView
->UnmarkAllPoints();
559 if ( ! rMEvt
.IsRight())
560 mpView
->BegMarkPoints(aMDPos
);
564 /**************************************************************
566 **************************************************************/
567 if ( ! rMEvt
.IsRight())
568 mpView
->BegMarkObj(aMDPos
);
571 ForcePointer(&rMEvt
);
577 ForcePointer(&rMEvt
);
583 bool FuSelection::MouseMove(const MouseEvent
& rMEvt
)
585 bool bReturn
= FuDraw::MouseMove(rMEvt
);
587 if (aDragTimer
.IsActive())
591 bFirstMouseMove
= false;
599 if (mpView
->IsAction())
601 Point
aPix(rMEvt
.GetPosPixel());
602 Point
aPnt(mpWindow
->PixelToLogic(aPix
));
606 if (mpView
->IsInsObjPoint())
608 mpView
->MovInsObjPoint(aPnt
);
612 mpView
->MovAction(aPnt
);
616 ForcePointer(&rMEvt
);
621 bool FuSelection::MouseButtonUp(const MouseEvent
& rMEvt
)
623 bool bReturn
= false;
624 // When the right mouse button is pressed then only select objects
625 // (and deselect others) as a preparation for showing the context
627 const bool bSelectionOnly
= rMEvt
.IsRight();
633 // Animation is still running -> return immediately
634 bHideAndAnimate
= false;
636 mpWindow
->ReleaseMouse();
640 if (aDragTimer
.IsActive() )
643 bIsInDragMode
= false;
649 Point
aPnt( mpWindow
->PixelToLogic( rMEvt
.GetPosPixel() ) );
650 sal_uInt16 nHitLog
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(HITPIX
,0)).Width() );
651 sal_uInt16 nDrgLog
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(DRGPIX
,0)).Width() );
653 if (mpView
->IsFrameDragSingles() || !mpView
->HasMarkablePoints())
655 /**********************************************************************
657 **********************************************************************/
658 if ( mpView
->IsDragObj() )
660 /******************************************************************
662 ******************************************************************/
663 FrameView
* pFrameView
= mpViewShell
->GetFrameView();
664 bool bDragWithCopy
= (rMEvt
.IsMod1() && pFrameView
->IsDragWithCopy());
668 bDragWithCopy
= !mpView
->IsPresObjSelected(false, true);
671 mpView
->SetDragWithCopy(bDragWithCopy
);
672 mpView
->EndDragObj( mpView
->IsDragWithCopy() );
674 mpView
->ForceMarkedToAnotherPage();
676 if (!rMEvt
.IsShift() && !rMEvt
.IsMod1() && !rMEvt
.IsMod2() &&
677 !bSelectionChanged
&&
678 std::abs(aPnt
.X() - aMDPos
.X()) < nDrgLog
&&
679 std::abs(aPnt
.Y() - aMDPos
.Y()) < nDrgLog
)
681 /*************************************************************
682 * If a user wants to click on an object in front of a marked
683 * one, he releases the mouse button immediately
684 **************************************************************/
685 if (mpView
->PickObj(aMDPos
, mpView
->getHitTolLog(), pObj
, pPV
, SdrSearchOptions::ALSOONMASTER
| SdrSearchOptions::BEFOREMARK
))
687 if (pPV
->IsObjSelectable(pObj
))
689 mpView
->UnmarkAllObj();
690 mpView
->MarkObj(pObj
,pPV
,false,false);
694 /**************************************************************
695 * Toggle between selection and rotation
696 **************************************************************/
697 SdrObject
* pSingleObj
= NULL
;
699 if (mpView
->GetMarkedObjectList().GetMarkCount()==1)
701 pSingleObj
= mpView
->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
704 if (nSlotId
== SID_OBJECT_SELECT
705 && mpView
->IsRotateAllowed()
707 && (rMEvt
.GetClicks() != 2)
708 && (mpViewShell
->GetFrameView()->IsClickChangeRotation()
710 && pSingleObj
->GetObjInventor()==E3dInventor
))
714 bTempRotation
= true;
715 nSlotId
= SID_OBJECT_ROTATE
;
718 else if (nSlotId
== SID_OBJECT_ROTATE
)
720 nSlotId
= SID_OBJECT_SELECT
;
724 else if (nSlotId
== SID_CONVERT_TO_3D_LATHE
)
728 bSuppressChangesOfSelection
= true;
729 mpView
->Start3DCreation();
730 bSuppressChangesOfSelection
= false;
732 else if (pHdl
->GetKind() != HDL_MIRX
&&
733 pHdl
->GetKind() != HDL_REF1
&&
734 pHdl
->GetKind() != HDL_REF2
&& mpView
->Is3DRotationCreationActive())
736 /*********************************************************
737 * If 3D-rotation bodies are about to be created,
739 **********************************************************/
740 long nAngle1
= GetAngle(aPnt
- mpView
->GetRef1());
742 nAngle1
= NormAngle360(nAngle1
);
743 bool bMirrorSide1
= nAngle1
< 18000L;
745 if (bMirrorSide0
!= bMirrorSide1
)
747 bSuppressChangesOfSelection
= true;
748 mpWindow
->EnterWait();
749 mpView
->End3DCreation();
750 bSuppressChangesOfSelection
= false;
751 nSlotId
= SID_OBJECT_SELECT
;
752 mpWindow
->LeaveWait();
758 else if (rMEvt
.IsMod1()
760 && std::abs(aPnt
.X() - aMDPos
.X()) < nDrgLog
761 && std::abs(aPnt
.Y() - aMDPos
.Y()) < nDrgLog
)
764 mpView
->MarkObj(aPnt
, nHitLog
, rMEvt
.IsShift(), rMEvt
.IsMod1());
767 if (mpView
->IsAction() )
772 if( SD_MOD()->GetWaterCan() )
774 if( rMEvt
.IsRight() )
776 // In watering-can mode, on press onto right mouse button, a undo is executed
777 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute( SID_UNDO
, SfxCallMode::ASYNCHRON
);
779 else if (pWaterCanCandidate
!= NULL
)
781 // Is the candidate object still under the mouse?
782 if (pickObject (aPnt
) == pWaterCanCandidate
)
784 SdStyleSheetPool
* pPool
= static_cast<SdStyleSheetPool
*>(
785 mpDocSh
->GetStyleSheetPool());
788 SfxStyleSheet
* pStyleSheet
= static_cast<SfxStyleSheet
*>(
789 pPool
->GetActualStyleSheet());
790 if (pStyleSheet
!= NULL
&& mpView
->IsUndoEnabled() )
792 // Added UNDOs for the WaterCan mode. This was never done in
793 // the past, thus it was missing all the time.
794 SdrUndoAction
* pUndoAttr
= mpDoc
->GetSdrUndoFactory().CreateUndoAttrObject(*pWaterCanCandidate
, true, true);
795 mpView
->BegUndo(pUndoAttr
->GetComment());
796 mpView
->AddUndo(mpDoc
->GetSdrUndoFactory().CreateUndoGeoObject(*pWaterCanCandidate
));
797 mpView
->AddUndo(pUndoAttr
);
799 pWaterCanCandidate
->SetStyleSheet (pStyleSheet
, false);
806 // else when there has been no object under the mouse when the
807 // button was pressed then nothing happens even when there is
811 sal_uInt16 nClicks
= rMEvt
.GetClicks();
813 if (nClicks
== 2 && rMEvt
.IsLeft() && bMBDown
&&
814 !rMEvt
.IsMod1() && !rMEvt
.IsShift() )
821 ForcePointer(&rMEvt
);
823 mpWindow
->ReleaseMouse();
824 SdrObject
* pSingleObj
= NULL
;
825 const size_t nMarkCount
= mpView
->GetMarkedObjectList().GetMarkCount();
829 pSingleObj
= mpView
->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
832 if ( (nSlotId
!= SID_OBJECT_SELECT
&& nMarkCount
==0) ||
833 ( mpView
->GetDragMode() == SDRDRAG_CROOK
&&
834 !mpView
->IsCrookAllowed( mpView
->IsCrookNoContortion() ) ) ||
835 ( mpView
->GetDragMode() == SDRDRAG_SHEAR
&&
836 !mpView
->IsShearAllowed() && !mpView
->IsDistortAllowed() ) ||
837 ( nSlotId
==SID_CONVERT_TO_3D_LATHE
&& pSingleObj
&&
838 (pSingleObj
->GetObjInventor() != SdrInventor
||
839 pSingleObj
->GetObjIdentifier() == OBJ_MEASURE
) ) )
842 ForcePointer(&rMEvt
);
844 mpWindow
->ReleaseMouse();
845 FuDraw::MouseButtonUp(rMEvt
);
846 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT
, SfxCallMode::SYNCHRON
);
847 return bReturn
; // CAUTION, due to the synchronous slot, the object is deleted now.
850 FuDraw::MouseButtonUp(rMEvt
);
854 /**********************************************************************
856 **********************************************************************/
857 if ( mpView
->IsAction() )
859 if ( mpView
->IsInsObjPoint() )
861 mpView
->EndInsObjPoint(SDRCREATE_FORCEEND
);
863 else if ( mpView
->IsDragObj() )
865 FrameView
* pFrameView
= mpViewShell
->GetFrameView();
866 bool bDragWithCopy
= (rMEvt
.IsMod1() && pFrameView
->IsDragWithCopy());
870 bDragWithCopy
= !mpView
->IsPresObjSelected(false, true);
873 mpView
->SetDragWithCopy(bDragWithCopy
);
874 mpView
->EndDragObj( mpView
->IsDragWithCopy() );
880 sal_uInt16 nDrgLog2
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(DRGPIX
,0)).Width() );
881 Point aPos
= mpWindow
->PixelToLogic( rMEvt
.GetPosPixel() );
883 if (std::abs(aMDPos
.X() - aPos
.X()) < nDrgLog2
&&
884 std::abs(aMDPos
.Y() - aPos
.Y()) < nDrgLog2
&&
885 !rMEvt
.IsShift() && !rMEvt
.IsMod2())
888 SdrHitKind eHit
= mpView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
890 if (eHit
== SDRHIT_NONE
)
892 // Click on the same place - unselect
893 mpView
->UnmarkAllObj();
898 else if (!rMEvt
.IsShift() && rMEvt
.IsMod1() && !rMEvt
.IsMod2() &&
899 std::abs(aPnt
.X() - aMDPos
.X()) < nDrgLog
&&
900 std::abs(aPnt
.Y() - aMDPos
.Y()) < nDrgLog
)
903 mpView
->MarkObj(aPnt
, nHitLog
, false, rMEvt
.IsMod1());
906 ForcePointer(&rMEvt
);
908 mpWindow
->ReleaseMouse();
910 FuDraw::MouseButtonUp(rMEvt
);
917 * Process keyboard input
918 * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
920 bool FuSelection::KeyInput(const KeyEvent
& rKEvt
)
922 bool bReturn
= false;
924 switch (rKEvt
.GetKeyCode().GetCode())
928 bReturn
= FuSelection::cancel();
931 //add keyboard operation for insert points in drawing curve
937 if(rKEvt
.GetKeyCode().IsShift()&&(nEditMode
== SID_BEZIER_INSERT
)){
940 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
947 else if (nCode
== KEY_DOWN
)
953 else if (nCode
== KEY_LEFT
)
959 else if (nCode
== KEY_RIGHT
)
961 // Scroll nach rechts
967 Rectangle rect
= mpView
->GetMarkedObjRect();
968 centerPoint
= mpWindow
->LogicToPixel(rect
.Center());
969 Point aPoint
= bMovedToCenterPoint
? oldPoint
:centerPoint
;
970 Point ePoint
= aPoint
+ Point(nX
,nY
);
971 mpWindow
->SetPointerPosPixel(ePoint
);
972 //simulate mouse move action
973 MouseEvent
eMevt(ePoint
, 1, MouseEventModifiers::DRAGMOVE
, MOUSE_LEFT
, 0);
976 bMovedToCenterPoint
= true;
982 if(rKEvt
.GetKeyCode().IsShift()&&(nEditMode
== SID_BEZIER_INSERT
))
984 if(!bBeginInsertPoint
)
986 //simulate mouse button down action
987 MouseEvent
aMevt(oldPoint
, 1,
988 MouseEventModifiers::SIMPLEMOVE
| MouseEventModifiers::DRAGMOVE
,
989 MOUSE_LEFT
, KEY_SHIFT
);
990 MouseButtonDown(aMevt
);
991 mpWindow
->CaptureMouse();
992 bBeginInsertPoint
= true;
996 //simulate mouse button up action
997 MouseEvent
rMEvt(oldPoint
, 1,
998 MouseEventModifiers::SIMPLEMOVE
| MouseEventModifiers::ENTERWINDOW
,
999 MOUSE_LEFT
, KEY_SHIFT
);
1000 MouseButtonUp(rMEvt
);
1001 bBeginInsertPoint
= false;
1009 bReturn
= FuDraw::KeyInput(rKEvt
);
1011 if(mpView
->GetMarkedObjectList().GetMarkCount() == 0)
1013 mpView
->ResetCreationActive();
1015 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
1023 void FuSelection::Activate()
1026 mpView
->ResetCreationActive();
1027 mpView
->SetEditMode(SDREDITMODE_EDIT
);
1031 case SID_OBJECT_ROTATE
:
1033 // (mapped) Slot is explicitly set to rotate
1034 if( mpViewShell
->ISA(DrawViewShell
) )
1036 sal_uInt16
* pSlotArray
=
1037 static_cast<DrawViewShell
*>(mpViewShell
)->GetSlotArray();
1038 pSlotArray
[ 1 ] = SID_OBJECT_ROTATE
;
1041 eMode
= SDRDRAG_ROTATE
;
1043 if ( mpView
->GetDragMode() != eMode
)
1044 mpView
->SetDragMode(eMode
);
1048 case SID_OBJECT_MIRROR
:
1050 eMode
= SDRDRAG_MIRROR
;
1052 if ( mpView
->GetDragMode() != eMode
)
1053 mpView
->SetDragMode(eMode
);
1057 case SID_OBJECT_CROP
:
1059 eMode
= SDRDRAG_CROP
;
1061 if ( mpView
->GetDragMode() != eMode
)
1062 mpView
->SetDragMode(eMode
);
1066 case SID_OBJECT_TRANSPARENCE
:
1068 eMode
= SDRDRAG_TRANSPARENCE
;
1070 if ( mpView
->GetDragMode() != eMode
)
1071 mpView
->SetDragMode(eMode
);
1075 case SID_OBJECT_GRADIENT
:
1077 eMode
= SDRDRAG_GRADIENT
;
1079 if ( mpView
->GetDragMode() != eMode
)
1080 mpView
->SetDragMode(eMode
);
1084 case SID_OBJECT_SHEAR
:
1086 eMode
= SDRDRAG_SHEAR
;
1088 if ( mpView
->GetDragMode() != eMode
)
1089 mpView
->SetDragMode(eMode
);
1093 case SID_OBJECT_CROOK_ROTATE
:
1095 eMode
= SDRDRAG_CROOK
;
1097 if ( mpView
->GetDragMode() != eMode
)
1099 mpView
->SetDragMode(eMode
);
1100 mpView
->SetCrookMode(SDRCROOK_ROTATE
);
1105 case SID_OBJECT_CROOK_SLANT
:
1107 eMode
= SDRDRAG_CROOK
;
1109 if ( mpView
->GetDragMode() != eMode
)
1111 mpView
->SetDragMode(eMode
);
1112 mpView
->SetCrookMode(SDRCROOK_SLANT
);
1117 case SID_OBJECT_CROOK_STRETCH
:
1119 eMode
= SDRDRAG_CROOK
;
1121 if ( mpView
->GetDragMode() != eMode
)
1123 mpView
->SetDragMode(eMode
);
1124 mpView
->SetCrookMode(SDRCROOK_STRETCH
);
1129 case SID_CONVERT_TO_3D_LATHE
:
1131 eMode
= SDRDRAG_MIRROR
;
1132 bSuppressChangesOfSelection
= true;
1134 if ( mpView
->GetDragMode() != eMode
)
1135 mpView
->SetDragMode(eMode
);
1137 if (!mpView
->Is3DRotationCreationActive())
1138 mpView
->Start3DCreation();
1140 bSuppressChangesOfSelection
= false;
1146 eMode
= SDRDRAG_MOVE
;
1148 if ( mpView
->GetDragMode() != eMode
)
1149 mpView
->SetDragMode(eMode
);
1154 if (nSlotId
!= SID_OBJECT_ROTATE
)
1156 bTempRotation
= false;
1162 void FuSelection::Deactivate()
1164 FuDraw::Deactivate();
1167 void FuSelection::SelectionHasChanged()
1169 bSelectionChanged
= true;
1171 FuDraw::SelectionHasChanged();
1173 if ((mpView
->Is3DRotationCreationActive() && !bSuppressChangesOfSelection
))
1175 // Switch rotation body -> selection
1176 mpView
->ResetCreationActive();
1177 nSlotId
= SID_OBJECT_SELECT
;
1181 // Activate the right tool bar for the current context of the view.
1182 mpViewShell
->GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*mpViewShell
, *mpView
);
1186 * Set current bezier edit mode
1188 void FuSelection::SetEditMode(sal_uInt16 nMode
)
1192 if (nEditMode
== SID_BEZIER_INSERT
)
1194 mpView
->SetInsObjPointMode(true);
1198 mpView
->SetInsObjPointMode(false);
1203 SfxBindings
& rBindings
= mpViewShell
->GetViewFrame()->GetBindings();
1204 rBindings
.Invalidate(SID_BEZIER_MOVE
);
1205 rBindings
.Invalidate(SID_BEZIER_INSERT
);
1209 * Execute animation or interaction
1211 bool FuSelection::AnimateObj(SdrObject
* pObj
, const Point
& rPos
)
1213 bool bAnimated
= false;
1214 bool bClosed
= pObj
->IsClosedObj();
1215 bool bFilled
= false;
1219 SfxItemSet
aSet(mpDoc
->GetPool());
1221 aSet
.Put(pObj
->GetMergedItemSet());
1223 const XFillStyleItem
& rFillStyle
= static_cast<const XFillStyleItem
&>( aSet
.Get(XATTR_FILLSTYLE
) );
1224 bFilled
= rFillStyle
.GetValue() != drawing::FillStyle_NONE
;
1227 const SetOfByte
* pVisiLayer
= &mpView
->GetSdrPageView()->GetVisibleLayers();
1228 sal_uInt16 nHitLog
= sal_uInt16 ( mpWindow
->PixelToLogic(Size(HITPIX
,0)).Width() );
1229 const long n2HitLog
= nHitLog
* 2;
1230 Point
aHitPosR(rPos
);
1231 Point
aHitPosL(rPos
);
1232 Point
aHitPosT(rPos
);
1233 Point
aHitPosB(rPos
);
1235 aHitPosR
.X() += n2HitLog
;
1236 aHitPosL
.X() -= n2HitLog
;
1237 aHitPosT
.Y() += n2HitLog
;
1238 aHitPosB
.Y() -= n2HitLog
;
1242 (SdrObjectPrimitiveHit(*pObj
, aHitPosR
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false) &&
1243 SdrObjectPrimitiveHit(*pObj
, aHitPosL
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false) &&
1244 SdrObjectPrimitiveHit(*pObj
, aHitPosT
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false) &&
1245 SdrObjectPrimitiveHit(*pObj
, aHitPosB
, nHitLog
, *mpView
->GetSdrPageView(), pVisiLayer
, false) ) )
1247 if ( mpDoc
->GetIMapInfo( pObj
) )
1249 const IMapObject
* pIMapObj
= mpDoc
->GetHitIMapObject( pObj
, rPos
, *mpWindow
);
1251 if ( pIMapObj
&& !pIMapObj
->GetURL().isEmpty() )
1254 mpWindow
->ReleaseMouse();
1255 SfxStringItem
aStrItem(SID_FILE_NAME
, pIMapObj
->GetURL());
1256 SfxStringItem
aReferer(SID_REFERER
, mpDocSh
->GetMedium()->GetName());
1257 SfxViewFrame
* pFrame
= mpViewShell
->GetViewFrame();
1258 SfxFrameItem
aFrameItem(SID_DOCFRAME
, pFrame
);
1259 SfxBoolItem
aBrowseItem( SID_BROWSE
, true );
1260 mpWindow
->ReleaseMouse();
1261 pFrame
->GetDispatcher()->
1262 Execute(SID_OPENDOC
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
1263 &aStrItem
, &aFrameItem
, &aBrowseItem
, &aReferer
, 0L);
1268 else if (!mpDocSh
->ISA(GraphicDocShell
) &&
1269 mpView
->ISA(DrawView
) &&
1270 mpDoc
->GetAnimationInfo(pObj
))
1272 /**********************************************************
1273 * Animation-object hit in the middle -> interaction
1274 **********************************************************/
1275 SdAnimationInfo
* pInfo
= mpDoc
->GetAnimationInfo(pObj
);
1276 DrawViewShell
* pDrViewSh
= static_cast<DrawViewShell
*>(mpViewShell
);
1277 mpWindow
->ReleaseMouse();
1279 switch (pInfo
->meClickAction
)
1281 case presentation::ClickAction_BOOKMARK
:
1283 // Jump to Bookmark (Page or Object)
1284 SfxStringItem
aItem(SID_NAVIGATOR_OBJECT
, pInfo
->GetBookmark());
1285 mpViewShell
->GetViewFrame()->GetDispatcher()->
1286 Execute(SID_NAVIGATOR_OBJECT
, SfxCallMode::SLOT
| SfxCallMode::RECORD
, &aItem
, 0L);
1291 case presentation::ClickAction_DOCUMENT
:
1293 OUString
sBookmark( pInfo
->GetBookmark() );
1295 if (!sBookmark
.isEmpty())
1297 SfxStringItem
aReferer(SID_REFERER
, mpDocSh
->GetMedium()->GetName());
1298 SfxStringItem
aStrItem(SID_FILE_NAME
, sBookmark
);
1299 SfxViewFrame
* pFrame
= mpViewShell
->GetViewFrame();
1300 SfxFrameItem
aFrameItem(SID_DOCFRAME
, pFrame
);
1301 SfxBoolItem
aBrowseItem( SID_BROWSE
, true );
1302 pFrame
->GetDispatcher()->
1303 Execute(SID_OPENDOC
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
1304 &aStrItem
, &aFrameItem
, &aBrowseItem
, &aReferer
, 0L);
1311 case presentation::ClickAction_PREVPAGE
:
1313 // Jump to the previous page
1314 SfxUInt16Item
aItem(SID_NAVIGATOR_PAGE
, PAGE_PREVIOUS
);
1315 mpViewShell
->GetViewFrame()->GetDispatcher()->
1316 Execute(SID_NAVIGATOR_PAGE
, SfxCallMode::SLOT
| SfxCallMode::RECORD
,
1322 case presentation::ClickAction_NEXTPAGE
:
1324 // Jump to the next page
1325 SfxUInt16Item
aItem(SID_NAVIGATOR_PAGE
, PAGE_NEXT
);
1326 mpViewShell
->GetViewFrame()->GetDispatcher()->
1327 Execute(SID_NAVIGATOR_PAGE
, SfxCallMode::SLOT
| SfxCallMode::RECORD
,
1333 case presentation::ClickAction_FIRSTPAGE
:
1335 // Jump to the first page
1336 SfxUInt16Item
aItem(SID_NAVIGATOR_PAGE
, PAGE_FIRST
);
1337 mpViewShell
->GetViewFrame()->GetDispatcher()->
1338 Execute(SID_NAVIGATOR_PAGE
, SfxCallMode::SLOT
| SfxCallMode::RECORD
,
1344 case presentation::ClickAction_LASTPAGE
:
1346 // Jump to the last page
1347 SfxUInt16Item
aItem(SID_NAVIGATOR_PAGE
, PAGE_LAST
);
1348 mpViewShell
->GetViewFrame()->GetDispatcher()->
1349 Execute(SID_NAVIGATOR_PAGE
, SfxCallMode::SLOT
| SfxCallMode::RECORD
,
1355 case presentation::ClickAction_SOUND
:
1359 mxPlayer
.set( avmedia::MediaWindow::createPlayer( pInfo
->GetBookmark(), ""/*TODO?*/), uno::UNO_QUERY_THROW
);
1362 catch( uno::Exception
& )
1369 case presentation::ClickAction_VERB
:
1372 mpView
->UnmarkAll();
1373 mpView
->MarkObj(pObj
, mpView
->GetSdrPageView(), false, false);
1374 pDrViewSh
->DoVerb((sal_Int16
)pInfo
->mnVerb
);
1379 case presentation::ClickAction_PROGRAM
:
1381 OUString aBaseURL
= GetDocSh()->GetMedium()->GetBaseURL();
1382 INetURLObject
aURL( ::URIHelper::SmartRel2Abs( INetURLObject(aBaseURL
), pInfo
->GetBookmark(),
1383 URIHelper::GetMaybeFileHdl(), true, false,
1384 INetURLObject::WAS_ENCODED
, INetURLObject::DECODE_UNAMBIGUOUS
) );
1386 if( INetProtocol::File
== aURL
.GetProtocol() )
1388 SfxStringItem
aUrl( SID_FILE_NAME
, aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
1389 SfxBoolItem
aBrowsing( SID_BROWSE
, true );
1391 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1393 pViewFrm
->GetDispatcher()->Execute( SID_OPENDOC
,
1394 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
1404 case presentation::ClickAction_MACRO
:
1407 OUString aMacro
= pInfo
->GetBookmark();
1409 if ( SfxApplication::IsXScriptURL( aMacro
) )
1412 uno::Sequence
< sal_Int16
> aOutArgsIndex
;
1413 uno::Sequence
< uno::Any
> aOutArgs
;
1414 uno::Sequence
< uno::Any
>* pInArgs
=
1415 new uno::Sequence
< uno::Any
>(0);
1417 ErrCode eErr
= mpDocSh
->CallXScript( aMacro
,
1418 *pInArgs
, aRet
, aOutArgsIndex
, aOutArgs
);
1420 // Check the return value from the script
1422 if ( eErr
== ERRCODE_NONE
&&
1423 aRet
.getValueType() == cppu::UnoType
<bool>::get() &&
1424 ( aRet
>>= bTmp
) &&
1436 // aMacro has got following format:
1437 // "Macroname.Modulname.Libname.Documentname" or
1438 // "Macroname.Modulname.Libname.Applicationname"
1439 OUString aMacroName
= aMacro
.getToken(0, '.');
1440 OUString aModulName
= aMacro
.getToken(1, '.');
1442 // In this moment the Call-method only
1443 // resolves modulename+macroname
1444 OUString
aExecMacro(aModulName
+ "." + aMacroName
);
1445 bAnimated
= mpDocSh
->GetBasic()->Call(aExecMacro
);
1459 mpView
->ISA(DrawView
) &&
1460 !mpDocSh
->ISA(GraphicDocShell
) &&
1461 SlideShow::IsRunning( mpViewShell
->GetViewShellBase() ) &&
1462 mpDoc
->GetAnimationInfo(pObj
))
1464 /**********************************************************
1465 * Effect-Object hit in the middle -> Play effect
1466 **********************************************************/
1467 SdAnimationInfo
* pInfo
= mpDoc
->GetAnimationInfo(pObj
);
1469 switch (pInfo
->meClickAction
)
1471 case presentation::ClickAction_VANISH
:
1472 case presentation::ClickAction_INVISIBLE
:
1485 /** is called when the current function should be aborted. <p>
1486 This is used when a function gets a KEY_ESCAPE but can also
1489 @returns true if a active function was aborted
1491 bool FuSelection::cancel()
1493 if (mpView
->Is3DRotationCreationActive())
1495 mpView
->ResetCreationActive();
1496 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
1505 SdrObject
* FuSelection::pickObject (const Point
& rTestPoint
)
1507 SdrObject
* pObject
= NULL
;
1508 SdrPageView
* pPageView
;
1509 sal_uInt16 nHitLog
= sal_uInt16 (mpWindow
->PixelToLogic(Size(HITPIX
,0)).Width());
1510 mpView
->PickObj (rTestPoint
, nHitLog
, pObject
, pPageView
, SdrSearchOptions::PICKMARKABLE
);
1514 void FuSelection::ForcePointer(const MouseEvent
* pMEvt
)
1516 if(bMovedToCenterPoint
&& !bBeginInsertPoint
&& pMEvt
)
1518 MouseEvent
aMEvt(pMEvt
->GetPosPixel(), pMEvt
->GetClicks(),
1519 pMEvt
->GetMode(), pMEvt
->GetButtons(), pMEvt
->GetModifier() & ~KEY_SHIFT
);
1520 FuDraw::ForcePointer(&aMEvt
);
1524 FuDraw::ForcePointer(pMEvt
);
1528 } // end of namespace sd
1530 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */