bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / func / fudraw.cxx
blobb50fe2c87836f7c89f4149f28af9111e550ebe3e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <sot/object.hxx>
21 #include <editeng/eeitem.hxx>
22 #include <vcl/waitobj.hxx>
24 #include <editeng/flditem.hxx>
25 #include <svx/svdogrp.hxx>
26 #include <svx/svdoole2.hxx>
27 #include <tools/urlobj.hxx>
28 #include <vcl/help.hxx>
29 #include <svx/bmpmask.hxx>
30 #include <svx/svdotext.hxx>
31 #include <sfx2/app.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <svx/svdpagv.hxx>
35 #include <svtools/imapobj.hxx>
36 #include <svx/svxids.hrc>
37 #include <svx/obj3d.hxx>
38 #include <svx/polysc3d.hxx>
40 #include <sfx2/viewfrm.hxx>
42 #include "anminfo.hxx"
43 #include "imapinfo.hxx"
44 #include "app.hrc"
45 #include "glob.hrc"
46 #include "strings.hrc"
47 #include "res_bmp.hrc"
49 #include "sdmod.hxx"
50 #include "GraphicDocShell.hxx"
51 #include "fudraw.hxx"
52 #include "ViewShell.hxx"
53 #include "FrameView.hxx"
54 #include "View.hxx"
55 #include "Window.hxx"
56 #include "drawdoc.hxx"
57 #include "DrawDocShell.hxx"
58 #include "Client.hxx"
59 #include "sdresid.hxx"
60 #include "drawview.hxx"
61 #include "fusel.hxx"
62 #include <svl/aeitem.hxx>
63 #include <vcl/msgbox.hxx>
64 #include "slideshow.hxx"
65 #include <svx/sdrhittesthelper.hxx>
67 using namespace ::com::sun::star;
69 namespace sd {
71 TYPEINIT1( FuDraw, FuPoor );
73 /**
74 * Base-class for all drawmodul-specific functions
76 FuDraw::FuDraw(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
77 SdDrawDocument* pDoc, SfxRequest& rReq)
78 : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
79 , bMBDown(false)
80 , bDragHelpLine(false)
81 , nHelpLine(0)
82 , bPermanent(false)
83 , bIsImageSelected(false)
87 FuDraw::~FuDraw()
89 mpView->BrkAction();
93 /**
94 * Code shared by MouseButtonDown and MouseMove
96 void FuDraw::DoModifiers(const MouseEvent& rMEvt, bool bSnapModPressed)
98 FrameView* pFrameView = mpViewShell->GetFrameView();
99 bool bGridSnap = pFrameView->IsGridSnap();
100 bGridSnap = (bSnapModPressed != bGridSnap);
102 if (mpView->IsGridSnap() != bGridSnap)
103 mpView->SetGridSnap(bGridSnap);
105 bool bBordSnap = pFrameView->IsBordSnap();
106 bBordSnap = (bSnapModPressed != bBordSnap);
108 if (mpView->IsBordSnap() != bBordSnap)
109 mpView->SetBordSnap(bBordSnap);
111 bool bHlplSnap = pFrameView->IsHlplSnap();
112 bHlplSnap = (bSnapModPressed != bHlplSnap);
114 if (mpView->IsHlplSnap() != bHlplSnap)
115 mpView->SetHlplSnap(bHlplSnap);
117 bool bOFrmSnap = pFrameView->IsOFrmSnap();
118 bOFrmSnap = (bSnapModPressed != bOFrmSnap);
120 if (mpView->IsOFrmSnap() != bOFrmSnap)
121 mpView->SetOFrmSnap(bOFrmSnap);
123 bool bOPntSnap = pFrameView->IsOPntSnap();
124 bOPntSnap = (bSnapModPressed != bOPntSnap);
126 if (mpView->IsOPntSnap() != bOPntSnap)
127 mpView->SetOPntSnap(bOPntSnap);
129 bool bOConSnap = pFrameView->IsOConSnap();
130 bOConSnap = (bSnapModPressed != bOConSnap);
132 if (mpView->IsOConSnap() != bOConSnap)
133 mpView->SetOConSnap(bOConSnap);
135 bool bAngleSnap = rMEvt.IsShift() == !pFrameView->IsAngleSnapEnabled();
137 if (mpView->IsAngleSnapEnabled() != bAngleSnap)
138 mpView->SetAngleSnapEnabled(bAngleSnap);
140 bool bCenter = rMEvt.IsMod2();
142 if ( mpView->IsCreate1stPointAsCenter() != bCenter ||
143 mpView->IsResizeAtCenter() != bCenter )
145 mpView->SetCreate1stPointAsCenter(bCenter);
146 mpView->SetResizeAtCenter(bCenter);
151 bool FuDraw::MouseButtonDown(const MouseEvent& rMEvt)
153 // remember button state for creation of own MouseEvents
154 SetMouseButtonCode(rMEvt.GetButtons());
156 bool bReturn = false;
157 bDragHelpLine = false;
158 aMDPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
160 // Check whether an image is selected
161 bIsImageSelected = false;
162 if (mpView->AreObjectsMarked())
164 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
165 if (rMarkList.GetMarkCount() == 1)
167 SdrMark* pMark = rMarkList.GetMark(0);
168 // tdf#89758 Extra check to avoid interactive crop preview from being
169 // proportionally scaled by default.
170 if (mpView->GetDragMode() != SDRDRAG_CROP)
172 bIsImageSelected = pMark->GetMarkedSdrObj()->GetObjIdentifier() == OBJ_GRAF;
177 if ( rMEvt.IsLeft() )
179 FrameView* pFrameView = mpViewShell->GetFrameView();
181 bool bOrtho = false;
183 bool bRestricted = true;
185 if (mpView->IsDragObj())
187 // object is dragged (move, resize,...)
188 const SdrHdl* pHdl = mpView->GetDragStat().GetHdl();
190 if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
192 // Move
193 bRestricted = false;
197 // #i33136#
198 if(bRestricted && doConstructOrthogonal())
200 // Restrict movement:
201 // rectangle->quadrat, ellipse->circle etc.
202 bOrtho = !rMEvt.IsShift();
204 else
206 bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho();
208 if (!mpView->IsSnapEnabled())
209 mpView->SetSnapEnabled(true);
211 bool bSnapModPressed = rMEvt.IsMod1();
212 if (mpView->IsOrtho() != bOrtho)
213 mpView->SetOrtho(bOrtho);
215 DoModifiers(rMEvt, bSnapModPressed);
217 SdrPageView* pPV = 0;
218 sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
220 // look only for HelpLines when they are visible (!)
221 bool bHelpLine(false);
222 if(mpView->IsHlplVisible())
223 bHelpLine = mpView->PickHelpLine(aMDPos, nHitLog, *mpWindow, nHelpLine, pPV);
224 bool bHitHdl = (mpView->PickHandle(aMDPos) != NULL);
226 if ( bHelpLine
227 && !mpView->IsCreateObj()
228 && ((mpView->GetEditMode() == SDREDITMODE_EDIT && !bHitHdl) || (rMEvt.IsShift() && bSnapModPressed)) )
230 mpWindow->CaptureMouse();
231 mpView->BegDragHelpLine(nHelpLine, pPV);
232 bDragHelpLine = mpView->IsDragHelpLine();
233 bReturn = true;
236 ForcePointer(&rMEvt);
238 return bReturn;
241 bool FuDraw::MouseMove(const MouseEvent& rMEvt)
243 FrameView* pFrameView = mpViewShell->GetFrameView();
244 Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
246 bool bOrtho = false;
247 bool bRestricted = true;
249 if (mpView->IsDragObj())
251 // object is dragged (move, resize, ...)
252 const SdrHdl* pHdl = mpView->GetDragStat().GetHdl();
254 if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
256 // Move
257 bRestricted = false;
261 if (mpView->IsAction())
263 // #i33136# and fdo#88339
264 if(bRestricted && (bIsImageSelected || doConstructOrthogonal()))
266 // Scale proportionally by default:
267 // rectangle->quadrat, ellipse->circle, Images etc.
268 bOrtho = !rMEvt.IsShift();
270 else
272 bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho();
275 bool bSnapModPressed = rMEvt.IsMod2();
276 mpView->SetDragWithCopy(rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
278 if (mpView->IsOrtho() != bOrtho)
279 mpView->SetOrtho(bOrtho);
280 DoModifiers(rMEvt, bSnapModPressed);
283 if ( mpView->IsDragHelpLine() )
284 mpView->MovDragHelpLine(aPos);
287 bool bReturn = mpView->MouseMove(rMEvt, mpWindow);
289 if (mpView->IsAction())
291 // Because the flag set back if necessary in MouseMove
292 if (mpView->IsOrtho() != bOrtho)
293 mpView->SetOrtho(bOrtho);
296 ForcePointer(&rMEvt);
298 return bReturn;
301 bool FuDraw::MouseButtonUp(const MouseEvent& rMEvt)
303 if (mpView && mpView->IsDragHelpLine())
304 mpView->EndDragHelpLine();
306 if ( bDragHelpLine )
308 Rectangle aOutputArea(Point(0,0), mpWindow->GetOutputSizePixel());
310 if (mpView && !aOutputArea.IsInside(rMEvt.GetPosPixel()))
311 mpView->GetSdrPageView()->DeleteHelpLine(nHelpLine);
313 mpWindow->ReleaseMouse();
316 if (mpView)
318 FrameView* pFrameView = mpViewShell->GetFrameView();
319 mpView->SetOrtho( pFrameView->IsOrtho() );
320 mpView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() );
321 mpView->SetSnapEnabled(true);
322 mpView->SetCreate1stPointAsCenter(false);
323 mpView->SetResizeAtCenter(false);
324 mpView->SetDragWithCopy(pFrameView->IsDragWithCopy());
325 mpView->SetGridSnap(pFrameView->IsGridSnap());
326 mpView->SetBordSnap(pFrameView->IsBordSnap());
327 mpView->SetHlplSnap(pFrameView->IsHlplSnap());
328 mpView->SetOFrmSnap(pFrameView->IsOFrmSnap());
329 mpView->SetOPntSnap(pFrameView->IsOPntSnap());
330 mpView->SetOConSnap(pFrameView->IsOConSnap());
333 bIsInDragMode = false;
334 ForcePointer(&rMEvt);
335 FuPoor::MouseButtonUp(rMEvt);
337 return false;
341 * Process keyboard input
342 * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
344 bool FuDraw::KeyInput(const KeyEvent& rKEvt)
346 bool bReturn = false;
348 switch ( rKEvt.GetKeyCode().GetCode() )
350 case KEY_ESCAPE:
352 bReturn = FuDraw::cancel();
354 break;
356 case KEY_DELETE:
357 case KEY_BACKSPACE:
359 if (!mpDocSh->IsReadOnly())
361 if (mpView->IsPresObjSelected(false, true, false, true))
363 ScopedVclPtr<InfoBox>::Create(mpWindow, SD_RESSTR(STR_ACTION_NOTPOSSIBLE) )->Execute();
365 else
367 /* If IP-Client active, we reset the pointer to the OLE- and
368 to the old graphic object of SdClient. With this, we
369 avoid the restoration of an no more existing object in
370 ::SelectionHasChanged after deletion. All other OLE
371 objects are not affected. */
372 OSL_ASSERT (mpViewShell->GetViewShell()!=NULL);
373 Client* pIPClient = static_cast<Client*>(
374 mpViewShell->GetViewShell()->GetIPClient());
375 if (pIPClient && pIPClient->IsObjectInPlaceActive())
376 pIPClient->SetSdrGrafObj(NULL);
378 // wait-mousepointer while deleting object
379 WaitObject aWait( (vcl::Window*)mpViewShell->GetActiveWindow() );
380 // delete object
381 mpView->DeleteMarked();
384 bReturn = true;
386 break;
388 case KEY_TAB:
390 vcl::KeyCode aCode = rKEvt.GetKeyCode();
392 if ( !aCode.IsMod1() && !aCode.IsMod2() )
394 // Moved next line which was a bugfix itself into
395 // the scope which really does the object selection travel
396 // and thus is allowed to call SelectionHasChanged().
398 // Switch to FuSelect.
399 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
400 SID_OBJECT_SELECT,
401 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
403 // changeover to the next object
404 if(!mpView->MarkNextObj( !aCode.IsShift() ))
406 //If there is only one object, don't do the UnmarkAlllObj() & MarkNextObj().
407 if ( mpView->GetMarkableObjCount() > 1 && mpView->AreObjectsMarked() )
409 // No next object: go over open end and get first from
410 // the other side
411 mpView->UnmarkAllObj();
412 mpView->MarkNextObj(!aCode.IsShift());
416 if(mpView->AreObjectsMarked())
417 mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
419 bReturn = true;
422 break;
424 case KEY_END:
426 vcl::KeyCode aCode = rKEvt.GetKeyCode();
428 if ( aCode.IsMod1() )
430 // mark last object
431 mpView->UnmarkAllObj();
432 mpView->MarkNextObj(false);
434 if(mpView->AreObjectsMarked())
435 mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
437 bReturn = true;
440 break;
442 case KEY_HOME:
444 vcl::KeyCode aCode = rKEvt.GetKeyCode();
446 if ( aCode.IsMod1() )
448 // mark first object
449 mpView->UnmarkAllObj();
450 mpView->MarkNextObj(true);
452 if(mpView->AreObjectsMarked())
453 mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
455 bReturn = true;
458 break;
460 default:
461 break;
464 if (!bReturn)
466 bReturn = FuPoor::KeyInput(rKEvt);
468 else
470 mpWindow->ReleaseMouse();
473 return bReturn;
476 void FuDraw::Activate()
478 FuPoor::Activate();
479 ForcePointer();
482 void FuDraw::Deactivate()
484 FuPoor::Deactivate();
488 * Toggle mouse-pointer
490 void FuDraw::ForcePointer(const MouseEvent* pMEvt)
492 Point aPnt;
493 sal_uInt16 nModifier = 0;
494 bool bLeftDown = false;
495 bool bDefPointer = true;
497 if (pMEvt)
499 aPnt = mpWindow->PixelToLogic(pMEvt->GetPosPixel());
500 nModifier = pMEvt->GetModifier();
501 bLeftDown = pMEvt->IsLeft();
503 else
505 aPnt = mpWindow->PixelToLogic(mpWindow->GetPointerPosPixel());
508 if (mpView->IsDragObj())
510 if (SD_MOD()->GetWaterCan() && !mpView->PickHandle(aPnt))
512 // water can mode
513 bDefPointer = false;
514 mpWindow->SetPointer(Pointer(PointerStyle::Fill));
517 else
519 SdrHdl* pHdl = mpView->PickHandle(aPnt);
521 if (SD_MOD()->GetWaterCan() && !pHdl)
523 // water can mode
524 bDefPointer = false;
525 mpWindow->SetPointer(Pointer(PointerStyle::Fill));
527 else if (!pHdl &&
528 mpViewShell->GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()))
530 // pipette mode
531 SfxChildWindow* pWnd = mpViewShell->GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
532 SvxBmpMask* pMask = pWnd ? static_cast<SvxBmpMask*>(pWnd->GetWindow()) : NULL;
533 if (pMask && pMask->IsEyedropping())
535 bDefPointer = false;
536 mpWindow->SetPointer(Pointer(PointerStyle::RefHand));
539 else if (!mpView->IsAction())
541 SdrObject* pObj = NULL;
542 SdrPageView* pPV = NULL;
543 SdrViewEvent aVEvt;
544 SdrHitKind eHit = SDRHIT_NONE;
545 SdrDragMode eDragMode = mpView->GetDragMode();
547 if (pMEvt)
549 eHit = mpView->PickAnything(*pMEvt, SdrMouseEventKind::MOVE, aVEvt);
552 if ((eDragMode == SDRDRAG_ROTATE) && (eHit == SDRHIT_MARKEDOBJECT))
554 // The goal of this request is show always the rotation-arrow for 3D-objects at rotation-modus
555 // Independent of the settings at Extras->Optionen->Grafik "Objekte immer verschieben"
556 // 2D-objects acquit in an other way. Otherwise, the rotation of 3d-objects around any axises
557 // wouldn't be possible per default.
558 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
559 SdrObject* pObject = rMarkList.GetMark(0)->GetMarkedSdrObj();
560 if ((pObject->ISA(E3dObject)) && (rMarkList.GetMarkCount() == 1))
562 mpWindow->SetPointer(Pointer(PointerStyle::Rotate));
563 bDefPointer = false; // Otherwise it'll be calles Joes routine and the mousepointer will reconfigurate again
567 if (eHit == SDRHIT_NONE)
569 // found nothing -> look after at the masterpage
570 mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER);
572 else if (eHit == SDRHIT_UNMARKEDOBJECT)
574 pObj = aVEvt.pObj;
576 else if (eHit == SDRHIT_TEXTEDITOBJ && this->ISA(FuSelection))
578 sal_uInt16 nSdrObjKind = aVEvt.pObj->GetObjIdentifier();
580 if ( nSdrObjKind != OBJ_TEXT &&
581 nSdrObjKind != OBJ_TITLETEXT &&
582 nSdrObjKind != OBJ_OUTLINETEXT &&
583 aVEvt.pObj->IsEmptyPresObj() )
585 pObj = NULL;
586 bDefPointer = false;
587 mpWindow->SetPointer(Pointer(PointerStyle::Arrow));
591 if (pObj && pMEvt && !pMEvt->IsMod2() && this->ISA(FuSelection))
593 // test for animation or ImageMap
594 bDefPointer = !SetPointer(pObj, aPnt);
596 if (bDefPointer && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
598 // take a glance into the group
599 if (mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::DEEP))
600 bDefPointer = !SetPointer(pObj, aPnt);
606 if (bDefPointer)
608 mpWindow->SetPointer(mpView->GetPreferredPointer(
609 aPnt, mpWindow, nModifier, bLeftDown));
614 * Set cursor for animaton or imagemap
616 bool FuDraw::SetPointer(SdrObject* pObj, const Point& rPos)
618 bool bSet = false;
620 bool bAnimationInfo = !mpDocSh->ISA(GraphicDocShell) &&
621 mpDoc->GetAnimationInfo(pObj);
623 bool bImageMapInfo = false;
625 if (!bAnimationInfo)
626 bImageMapInfo = mpDoc->GetIMapInfo(pObj) != nullptr;
628 if (bAnimationInfo || bImageMapInfo)
630 const SetOfByte* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
631 sal_uInt16 nHitLog(sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width()));
632 long n2HitLog(nHitLog * 2);
633 Point aHitPosR(rPos);
634 Point aHitPosL(rPos);
635 Point aHitPosT(rPos);
636 Point aHitPosB(rPos);
638 aHitPosR.X() += n2HitLog;
639 aHitPosL.X() -= n2HitLog;
640 aHitPosT.Y() += n2HitLog;
641 aHitPosB.Y() -= n2HitLog;
643 if ( !pObj->IsClosedObj() ||
644 ( SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
645 SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
646 SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
647 SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false)))
649 /**********************************************************
650 * hit inside the object (without margin) or open object
651 ********************************************************/
653 if (bAnimationInfo)
655 /******************************************************
656 * Click-Action
657 ******************************************************/
658 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
660 if ((mpView->ISA(DrawView) &&
661 (pInfo->meClickAction == presentation::ClickAction_BOOKMARK ||
662 pInfo->meClickAction == presentation::ClickAction_DOCUMENT ||
663 pInfo->meClickAction == presentation::ClickAction_PREVPAGE ||
664 pInfo->meClickAction == presentation::ClickAction_NEXTPAGE ||
665 pInfo->meClickAction == presentation::ClickAction_FIRSTPAGE ||
666 pInfo->meClickAction == presentation::ClickAction_LASTPAGE ||
667 pInfo->meClickAction == presentation::ClickAction_VERB ||
668 pInfo->meClickAction == presentation::ClickAction_PROGRAM ||
669 pInfo->meClickAction == presentation::ClickAction_MACRO ||
670 pInfo->meClickAction == presentation::ClickAction_SOUND))
672 (mpView->ISA(DrawView) &&
673 SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) &&
674 (pInfo->meClickAction == presentation::ClickAction_VANISH ||
675 pInfo->meClickAction == presentation::ClickAction_INVISIBLE ||
676 pInfo->meClickAction == presentation::ClickAction_STOPPRESENTATION ||
677 (pInfo->mbActive &&
678 ( pInfo->meEffect != presentation::AnimationEffect_NONE ||
679 pInfo->meTextEffect != presentation::AnimationEffect_NONE )))))
681 // Animation object
682 bSet = true;
683 mpWindow->SetPointer(Pointer(PointerStyle::RefHand));
686 else if (bImageMapInfo &&
687 mpDoc->GetHitIMapObject(pObj, rPos, *mpWindow))
689 /******************************************************
690 * ImageMap
691 ******************************************************/
692 bSet = true;
693 mpWindow->SetPointer(Pointer(PointerStyle::RefHand));
698 return bSet;
702 * Response of doubleclick
704 void FuDraw::DoubleClick(const MouseEvent& rMEvt)
706 sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
708 if ( mpView->AreObjectsMarked() )
710 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
712 if (rMarkList.GetMarkCount() == 1)
714 SdrMark* pMark = rMarkList.GetMark(0);
715 SdrObject* pObj = pMark->GetMarkedSdrObj();
717 sal_uInt32 nInv = pObj->GetObjInventor();
718 sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
720 if (nInv == SdrInventor && nSdrObjKind == OBJ_OLE2)
722 DrawDocShell* pDocSh = mpDoc->GetDocSh();
724 if ( !pDocSh->IsUIActive() )
726 /**********************************************************
727 * activate OLE-object
728 **********************************************************/
729 mpViewShell->ActivateObject( static_cast<SdrOle2Obj*>(pObj), 0);
732 else if (nInv == SdrInventor && nSdrObjKind == OBJ_GRAF && pObj->IsEmptyPresObj() )
734 mpViewShell->GetViewFrame()->
735 GetDispatcher()->Execute( SID_INSERT_GRAPHIC,
736 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
738 else if ( ( pObj->ISA(SdrTextObj) || pObj->ISA(SdrObjGroup) ) &&
739 !SD_MOD()->GetWaterCan() &&
740 mpViewShell->GetFrameView()->IsDoubleClickTextEdit() &&
741 !mpDocSh->IsReadOnly())
743 SfxUInt16Item aItem(SID_TEXTEDIT, 2);
744 mpViewShell->GetViewFrame()->GetDispatcher()->
745 Execute(SID_TEXTEDIT, SfxCallMode::ASYNCHRON |
746 SfxCallMode::RECORD, &aItem, 0L);
748 else if (nInv == SdrInventor && nSdrObjKind == OBJ_GRUP)
750 // hit group -> select subobject
751 mpView->UnMarkAll();
752 mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift(), true);
756 else
757 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
760 bool FuDraw::RequestHelp(const HelpEvent& rHEvt)
762 bool bReturn = false;
764 if (Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled())
766 SdrViewEvent aVEvt;
768 MouseEvent aMEvt(mpWindow->GetPointerPosPixel(), 1, MouseEventModifiers::NONE, MOUSE_LEFT);
770 SdrHitKind eHit = mpView->PickAnything(aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
772 SdrObject* pObj = aVEvt.pObj;
774 if (eHit != SDRHIT_NONE && pObj != NULL)
776 Point aPosPixel = rHEvt.GetMousePosPixel();
778 bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
780 if (!bReturn && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
782 // take a glance into the group
783 SdrPageView* pPV = NULL;
785 Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(aPosPixel)));
787 if (mpView->PickObj(aPos, mpView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::DEEP))
788 bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
793 if (!bReturn)
795 bReturn = FuPoor::RequestHelp(rHEvt);
798 return bReturn;
801 bool FuDraw::SetHelpText(SdrObject* pObj, const Point& rPosPixel, const SdrViewEvent& rVEvt)
803 bool bSet = false;
804 OUString aHelpText;
805 Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(rPosPixel)));
807 // URL for IMapObject underneath pointer is help text
808 if ( mpDoc->GetIMapInfo(pObj) )
810 IMapObject* pIMapObj = mpDoc->GetHitIMapObject(pObj, aPos, *mpWindow );
812 if ( pIMapObj )
814 // show name
815 aHelpText = pIMapObj->GetAltText();
817 if (aHelpText.isEmpty())
819 // show url if no name is available
820 aHelpText = INetURLObject::decode( pIMapObj->GetURL(), INetURLObject::DECODE_WITH_CHARSET );
824 else if (!mpDocSh->ISA(GraphicDocShell) && mpDoc->GetAnimationInfo(pObj))
826 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
828 switch (pInfo->meClickAction)
830 case presentation::ClickAction_PREVPAGE:
832 // jump to the prior page
833 aHelpText = SD_RESSTR(STR_CLICK_ACTION_PREVPAGE);
835 break;
837 case presentation::ClickAction_NEXTPAGE:
839 // jump to the next page
840 aHelpText = SD_RESSTR(STR_CLICK_ACTION_NEXTPAGE);
842 break;
844 case presentation::ClickAction_FIRSTPAGE:
846 // jump to the first page
847 aHelpText = SD_RESSTR(STR_CLICK_ACTION_FIRSTPAGE);
849 break;
851 case presentation::ClickAction_LASTPAGE:
853 // jump to the last page
854 aHelpText = SD_RESSTR(STR_CLICK_ACTION_LASTPAGE);
856 break;
858 case presentation::ClickAction_BOOKMARK:
860 // jump to object/page
861 aHelpText = SD_RESSTR(STR_CLICK_ACTION_BOOKMARK);
862 aHelpText += ": ";
863 aHelpText += INetURLObject::decode( pInfo->GetBookmark(), INetURLObject::DECODE_WITH_CHARSET );
865 break;
867 case presentation::ClickAction_DOCUMENT:
869 // jump to document (object/page)
870 aHelpText = SD_RESSTR(STR_CLICK_ACTION_DOCUMENT);
871 aHelpText += ": ";
872 aHelpText += INetURLObject::decode( pInfo->GetBookmark(), INetURLObject::DECODE_WITH_CHARSET );
874 break;
876 case presentation::ClickAction_PROGRAM:
878 // execute program
879 aHelpText = SD_RESSTR(STR_CLICK_ACTION_PROGRAM);
880 aHelpText += ": ";
881 aHelpText += INetURLObject::decode( pInfo->GetBookmark(), INetURLObject::DECODE_WITH_CHARSET );
883 break;
885 case presentation::ClickAction_MACRO:
887 // execute program
888 aHelpText = SD_RESSTR(STR_CLICK_ACTION_MACRO);
889 aHelpText += ": ";
891 if ( SfxApplication::IsXScriptURL( pInfo->GetBookmark() ) )
893 aHelpText += pInfo->GetBookmark();
895 else
897 OUString sBookmark( pInfo->GetBookmark() );
898 aHelpText += sBookmark.getToken( 2, '.' );
899 aHelpText += ".";
900 aHelpText += sBookmark.getToken( 1, '.' );
901 aHelpText += ".";
902 aHelpText += sBookmark.getToken( 0, '.' );
905 break;
907 case presentation::ClickAction_SOUND:
909 // play-back sound
910 aHelpText = SD_RESSTR(STR_CLICK_ACTION_SOUND);
912 break;
914 case presentation::ClickAction_VERB:
916 // execute OLE-verb
917 aHelpText = SD_RESSTR(STR_CLICK_ACTION_VERB);
919 break;
921 case presentation::ClickAction_STOPPRESENTATION:
923 // quit presentation
924 aHelpText = SD_RESSTR(STR_CLICK_ACTION_STOPPRESENTATION);
926 break;
927 default:
928 break;
931 else if (rVEvt.pURLField)
933 /**************************************************************
934 * URL-Field
935 **************************************************************/
936 aHelpText = INetURLObject::decode( rVEvt.pURLField->GetURL(), INetURLObject::DECODE_WITH_CHARSET );
939 if (!aHelpText.isEmpty())
941 bSet = true;
942 Rectangle aLogicPix = mpWindow->LogicToPixel(pObj->GetLogicRect());
943 Rectangle aScreenRect(mpWindow->OutputToScreenPixel(aLogicPix.TopLeft()),
944 mpWindow->OutputToScreenPixel(aLogicPix.BottomRight()));
946 if (Help::IsBalloonHelpEnabled())
947 Help::ShowBalloon( (vcl::Window*)mpWindow, rPosPixel, aScreenRect, aHelpText);
948 else if (Help::IsQuickHelpEnabled())
949 Help::ShowQuickHelp( (vcl::Window*)mpWindow, aScreenRect, aHelpText);
952 return bSet;
955 /** is called when the current function should be aborted. <p>
956 This is used when a function gets a KEY_ESCAPE but can also
957 be called directly.
959 @returns true if a active function was aborted
961 bool FuDraw::cancel()
963 bool bReturn = false;
965 if ( mpView->IsAction() )
967 mpView->BrkAction();
968 bReturn = true;
970 else if ( mpView->IsTextEdit() )
972 mpView->SdrEndTextEdit();
973 bReturn = true;
975 SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
976 rBindings.Invalidate( SID_PARASPACE_INCREASE );
977 rBindings.Invalidate( SID_PARASPACE_DECREASE );
979 else if ( mpView->AreObjectsMarked() )
981 const SdrHdlList& rHdlList = mpView->GetHdlList();
982 SdrHdl* pHdl = rHdlList.GetFocusHdl();
984 if(pHdl)
986 ((SdrHdlList&)rHdlList).ResetFocusHdl();
988 else
990 mpView->UnmarkAll();
993 // Switch to FuSelect.
994 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
995 SID_OBJECT_SELECT,
996 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
998 bReturn = true;
1001 return bReturn;
1004 } // end of namespace sd
1006 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */