xref: /trunk/main/sd/source/ui/func/fudraw.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 
31 #include <sot/object.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <vcl/waitobj.hxx>
34 
35 #include <editeng/flditem.hxx>
36 #include <svx/svdogrp.hxx>
37 #include <tools/urlobj.hxx>
38 #include <vcl/help.hxx>
39 #include <svx/bmpmask.hxx>
40 #include <svx/svdotext.hxx>
41 #include <sfx2/app.hxx>
42 #include <sfx2/dispatch.hxx>
43 #include <sfx2/bindings.hxx>
44 #include <svx/svdpagv.hxx>
45 #include <svtools/imapobj.hxx>
46 #include <svx/svxids.hrc>
47 #include <svx/obj3d.hxx>
48 #include <svx/polysc3d.hxx>
49 #include <svx/svdpagv.hxx>
50 
51 #include <sfx2/viewfrm.hxx>
52 
53 #include "anminfo.hxx"
54 #include "anmdef.hxx"
55 #include "imapinfo.hxx"
56 #include "app.hrc"
57 #include "glob.hrc"
58 #include "strings.hrc"
59 #include "res_bmp.hrc"
60 
61 #include "app.hxx"
62 #include "GraphicDocShell.hxx"
63 #include "fudraw.hxx"
64 #include "ViewShell.hxx"
65 #include "FrameView.hxx"
66 #include "View.hxx"
67 #ifndef SD_WINDOW_SHELL_HXX
68 #include "Window.hxx"
69 #endif
70 #include "drawdoc.hxx"
71 #include "DrawDocShell.hxx"
72 #include "Client.hxx"
73 #include "sdresid.hxx"
74 #include "drawview.hxx"
75 #include "fusel.hxx"
76 #include <svl/aeitem.hxx>
77 #include <vcl/msgbox.hxx>
78 #include "slideshow.hxx"
79 #include <svx/sdrhittesthelper.hxx>
80 
81 using namespace ::com::sun::star;
82 
83 namespace sd {
84 
85 TYPEINIT1( FuDraw, FuPoor );
86 
87 /*************************************************************************
88 |*
89 |* Base-class for all drawmodul-specific functions
90 |*
91 \************************************************************************/
92 
93 FuDraw::FuDraw(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
94                SdDrawDocument* pDoc, SfxRequest& rReq) :
95     FuPoor(pViewSh, pWin, pView, pDoc, rReq),
96     bMBDown(sal_False),
97     bDragHelpLine(sal_False),
98     bPermanent(sal_False)
99 {
100 }
101 
102 /*************************************************************************
103 |*
104 |* Destruktor
105 |*
106 \************************************************************************/
107 
108 FuDraw::~FuDraw()
109 {
110     mpView->BrkAction();
111 }
112 
113 /*************************************************************************
114 |*
115 |* MouseButtonDown-event
116 |*
117 \************************************************************************/
118 
119 sal_Bool FuDraw::MouseButtonDown(const MouseEvent& rMEvt)
120 {
121     // #95491# remember button state for creation of own MouseEvents
122     SetMouseButtonCode(rMEvt.GetButtons());
123 
124     sal_Bool bReturn = sal_False;
125 
126     bDragHelpLine = sal_False;
127 
128     aMDPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
129 
130     if ( rMEvt.IsLeft() )
131     {
132         FrameView* pFrameView = mpViewShell->GetFrameView();
133 
134 //        sal_Bool bOrtho = mpView->IsOrthoDesired() || pFrameView->IsOrtho();
135 //        bOrtho = bOrtho != rMEvt.IsShift();
136         sal_Bool bOrtho = sal_False;
137 
138         sal_Bool bRestricted = sal_True;
139 
140         if (mpView->IsDragObj())
141         {
142             // object is dragged (move, resize,...)
143             const SdrHdl* pHdl = mpView->GetDragStat().GetHdl();
144 
145             if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
146             {
147                 // Move
148                 bRestricted = sal_False;
149             }
150         }
151 
152         // #i33136#
153         if(bRestricted && doConstructOrthogonal())
154         {
155             // Restrict movement:
156             // rectangle->quadrat, ellipse->circle etc.
157             bOrtho = !rMEvt.IsShift();
158         }
159         else
160         {
161             bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho();
162         }
163 
164         if (!mpView->IsSnapEnabled())
165             mpView->SetSnapEnabled(sal_True);
166         sal_Bool bSnapModPressed = rMEvt.IsMod1();
167 
168         sal_Bool bGridSnap = pFrameView->IsGridSnap();
169         bGridSnap = (bSnapModPressed != bGridSnap);
170 
171         if (mpView->IsGridSnap() != bGridSnap)
172             mpView->SetGridSnap(bGridSnap);
173 
174         sal_Bool bBordSnap = pFrameView->IsBordSnap();
175         bBordSnap = (bSnapModPressed != bBordSnap);
176 
177         if (mpView->IsBordSnap() != bBordSnap)
178             mpView->SetBordSnap(bBordSnap);
179 
180         sal_Bool bHlplSnap = pFrameView->IsHlplSnap();
181         bHlplSnap = (bSnapModPressed != bHlplSnap);
182 
183         if (mpView->IsHlplSnap() != bHlplSnap)
184             mpView->SetHlplSnap(bHlplSnap);
185 
186         sal_Bool bOFrmSnap = pFrameView->IsOFrmSnap();
187         bOFrmSnap = (bSnapModPressed != bOFrmSnap);
188 
189         if (mpView->IsOFrmSnap() != bOFrmSnap)
190             mpView->SetOFrmSnap(bOFrmSnap);
191 
192         sal_Bool bOPntSnap = pFrameView->IsOPntSnap();
193         bOPntSnap = (bSnapModPressed != bOPntSnap);
194 
195         if (mpView->IsOPntSnap() != bOPntSnap)
196             mpView->SetOPntSnap(bOPntSnap);
197 
198         sal_Bool bOConSnap = pFrameView->IsOConSnap();
199         bOConSnap = (bSnapModPressed != bOConSnap);
200 
201         if (mpView->IsOConSnap() != bOConSnap)
202             mpView->SetOConSnap(bOConSnap);
203 
204         sal_Bool bAngleSnap = rMEvt.IsShift() == !pFrameView->IsAngleSnapEnabled();
205 
206         if (mpView->IsAngleSnapEnabled() != bAngleSnap)
207             mpView->SetAngleSnapEnabled(bAngleSnap);
208 
209         if (mpView->IsOrtho() != bOrtho)
210             mpView->SetOrtho(bOrtho);
211 
212         sal_Bool bCenter = rMEvt.IsMod2();
213 
214         if ( mpView->IsCreate1stPointAsCenter() != bCenter ||
215              mpView->IsResizeAtCenter() != bCenter )
216         {
217             mpView->SetCreate1stPointAsCenter(bCenter);
218             mpView->SetResizeAtCenter(bCenter);
219         }
220 
221         SdrPageView* pPV = 0;
222         sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
223 
224         // #76572# look only for HelpLines when they are visible (!)
225         sal_Bool bHelpLine(sal_False);
226         if(mpView->IsHlplVisible())
227             bHelpLine = mpView->PickHelpLine(aMDPos, nHitLog, *mpWindow, nHelpLine, pPV);
228         sal_Bool bHitHdl = (mpView->PickHandle(aMDPos) != NULL);
229 
230         if ( bHelpLine
231             && !mpView->IsCreateObj()
232             && ((mpView->GetEditMode() == SDREDITMODE_EDIT && !bHitHdl) || (rMEvt.IsShift() && bSnapModPressed)) )
233         {
234             mpWindow->CaptureMouse();
235             mpView->BegDragHelpLine(nHelpLine, pPV);
236             bDragHelpLine = mpView->IsDragHelpLine();
237             bReturn = sal_True;
238         }
239     }
240     ForcePointer(&rMEvt);
241 
242     return bReturn;
243 }
244 
245 /*************************************************************************
246 |*
247 |* MouseMove-event
248 |*
249 \************************************************************************/
250 
251 sal_Bool FuDraw::MouseMove(const MouseEvent& rMEvt)
252 {
253     FrameView* pFrameView = mpViewShell->GetFrameView();
254     Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
255 
256 //    sal_Bool bOrtho = mpView->IsOrthoDesired() || pFrameView->IsOrtho();
257 //    bOrtho = bOrtho != rMEvt.IsShift();
258     sal_Bool bOrtho = sal_False;
259 
260     sal_Bool bRestricted = sal_True;
261 
262     if (mpView->IsDragObj())
263     {
264         // object is dragged (move, resize, ...)
265         const SdrHdl* pHdl = mpView->GetDragStat().GetHdl();
266 
267         if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
268         {
269             // Move
270             bRestricted = sal_False;
271         }
272     }
273 
274     if (mpView->IsAction())
275     {
276         // #i33136#
277         if(bRestricted && doConstructOrthogonal())
278         {
279             // Restrict movement:
280             // rectangle->quadrat, ellipse->circle etc.
281             bOrtho = !rMEvt.IsShift();
282         }
283         else
284         {
285             bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho();
286         }
287 
288         sal_Bool bSnapModPressed = rMEvt.IsMod2();
289         mpView->SetDragWithCopy(rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
290 
291         sal_Bool bGridSnap = pFrameView->IsGridSnap();
292         bGridSnap = (bSnapModPressed != bGridSnap);
293 
294         if (mpView->IsGridSnap() != bGridSnap)
295             mpView->SetGridSnap(bGridSnap);
296 
297         sal_Bool bBordSnap = pFrameView->IsBordSnap();
298         bBordSnap = (bSnapModPressed != bBordSnap);
299 
300         if (mpView->IsBordSnap() != bBordSnap)
301             mpView->SetBordSnap(bBordSnap);
302 
303         sal_Bool bHlplSnap = pFrameView->IsHlplSnap();
304         bHlplSnap = (bSnapModPressed != bHlplSnap);
305 
306         if (mpView->IsHlplSnap() != bHlplSnap)
307             mpView->SetHlplSnap(bHlplSnap);
308 
309         sal_Bool bOFrmSnap = pFrameView->IsOFrmSnap();
310         bOFrmSnap = (bSnapModPressed != bOFrmSnap);
311 
312         if (mpView->IsOFrmSnap() != bOFrmSnap)
313             mpView->SetOFrmSnap(bOFrmSnap);
314 
315         sal_Bool bOPntSnap = pFrameView->IsOPntSnap();
316         bOPntSnap = (bSnapModPressed != bOPntSnap);
317 
318         if (mpView->IsOPntSnap() != bOPntSnap)
319             mpView->SetOPntSnap(bOPntSnap);
320 
321         sal_Bool bOConSnap = pFrameView->IsOConSnap();
322         bOConSnap = (bSnapModPressed != bOConSnap);
323 
324         if (mpView->IsOConSnap() != bOConSnap)
325             mpView->SetOConSnap(bOConSnap);
326 
327         sal_Bool bAngleSnap = rMEvt.IsShift() == !pFrameView->IsAngleSnapEnabled();
328 
329         if (mpView->IsAngleSnapEnabled() != bAngleSnap)
330             mpView->SetAngleSnapEnabled(bAngleSnap);
331 
332         if (mpView->IsOrtho() != bOrtho)
333             mpView->SetOrtho(bOrtho);
334 
335         sal_Bool bCenter = rMEvt.IsMod2();
336 
337         if ( mpView->IsCreate1stPointAsCenter() != bCenter ||
338              mpView->IsResizeAtCenter() != bCenter )
339         {
340             mpView->SetCreate1stPointAsCenter(bCenter);
341             mpView->SetResizeAtCenter(bCenter);
342         }
343 
344         if ( mpView->IsDragHelpLine() )
345             mpView->MovDragHelpLine(aPos);
346     }
347 
348     sal_Bool bReturn = mpView->MouseMove(rMEvt, mpWindow);
349 
350     if (mpView->IsAction())
351     {
352         // Because the flag set back if necessary in MouseMove
353         if (mpView->IsOrtho() != bOrtho)
354             mpView->SetOrtho(bOrtho);
355     }
356 
357     ForcePointer(&rMEvt);
358 
359     return bReturn;
360 }
361 
362 /*************************************************************************
363 |*
364 |* MouseButtonUp-event
365 |*
366 \************************************************************************/
367 
368 sal_Bool FuDraw::MouseButtonUp(const MouseEvent& rMEvt)
369 {
370     if ( mpView->IsDragHelpLine() )
371         mpView->EndDragHelpLine();
372 
373     if ( bDragHelpLine )
374     {
375         Rectangle aOutputArea(Point(0,0), mpWindow->GetOutputSizePixel());
376 
377         if ( !aOutputArea.IsInside(rMEvt.GetPosPixel()) )
378             mpView->GetSdrPageView()->DeleteHelpLine(nHelpLine);
379 
380         mpWindow->ReleaseMouse();
381     }
382 
383     FrameView* pFrameView = mpViewShell->GetFrameView();
384     mpView->SetOrtho( pFrameView->IsOrtho() );
385     mpView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() );
386     mpView->SetSnapEnabled(sal_True);
387     mpView->SetCreate1stPointAsCenter(sal_False);
388     mpView->SetResizeAtCenter(sal_False);
389     mpView->SetDragWithCopy(pFrameView->IsDragWithCopy());
390     mpView->SetGridSnap(pFrameView->IsGridSnap());
391     mpView->SetBordSnap(pFrameView->IsBordSnap());
392     mpView->SetHlplSnap(pFrameView->IsHlplSnap());
393     mpView->SetOFrmSnap(pFrameView->IsOFrmSnap());
394     mpView->SetOPntSnap(pFrameView->IsOPntSnap());
395     mpView->SetOConSnap(pFrameView->IsOConSnap());
396 
397     bIsInDragMode = sal_False;
398     ForcePointer(&rMEvt);
399     FuPoor::MouseButtonUp(rMEvt);
400 
401     return sal_False;
402 }
403 
404 /*************************************************************************
405 |*
406 |* Process keyboard-events
407 |*
408 |* When processing a KeyEvent the returnvalue is sal_True, otherwise sal_False.
409 |*
410 \************************************************************************/
411 
412 sal_Bool FuDraw::KeyInput(const KeyEvent& rKEvt)
413 {
414     sal_Bool bReturn = sal_False;
415 
416     switch ( rKEvt.GetKeyCode().GetCode() )
417     {
418         case KEY_ESCAPE:
419         {
420             bReturn = FuDraw::cancel();
421         }
422         break;
423 
424         case KEY_DELETE:
425         case KEY_BACKSPACE:
426         {
427             if (!mpDocSh->IsReadOnly())
428             {
429                 if ( mpView && mpView->IsPresObjSelected(sal_False, sal_True, sal_False, sal_True) )
430                 {
431                     InfoBox(mpWindow, String(SdResId(STR_ACTION_NOTPOSSIBLE) ) ).Execute();
432                 }
433                 else
434                 {
435                     // Falls IP-Client aktiv, werden die Pointer
436                     // auf das OLE- und das alte Graphic-Object
437                     // am SdClient zurueckgesetzt, damit bei
438                     // ::SelectionHasChanged nach dem Loeschen
439                     // nicht mehr versucht wird, ein Grafik-Objekt
440                     // zu restaurieren, das gar nicht mehr existiert.
441                     // Alle anderen OLE-Objekte sind davon nicht
442                     // betroffen (KA 06.10.95)
443                     OSL_ASSERT (mpViewShell->GetViewShell()!=NULL);
444                     Client* pIPClient = static_cast<Client*>(
445                         mpViewShell->GetViewShell()->GetIPClient());
446                     if (pIPClient && pIPClient->IsObjectInPlaceActive())
447                         pIPClient->SetSdrGrafObj(NULL);
448 
449                     // wait-mousepointer while deleting object
450                     WaitObject aWait( (Window*)mpViewShell->GetActiveWindow() );
451                     // delete object
452                     mpView->DeleteMarked();
453                 }
454             }
455             bReturn = sal_True;
456         }
457         break;
458 
459         case KEY_TAB:
460         {
461             KeyCode aCode = rKEvt.GetKeyCode();
462 
463             if ( !aCode.IsMod1() && !aCode.IsMod2() )
464             {
465                 // #105336# Moved next line which was a bugfix itself into
466                 // the scope which really does the object selection travel
467                 // and thus is allowed to call SelectionHasChanged().
468 
469                 // Switch to FuSelect.
470                 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
471                     SID_OBJECT_SELECT,
472                     SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
473 
474                 // changeover to the next object
475                 if(!mpView->MarkNextObj( !aCode.IsShift() ))
476                 {
477                     // #97016# No next object: go over open end and
478                     // get first from the other side
479                     mpView->UnmarkAllObj();
480                     mpView->MarkNextObj(!aCode.IsShift());
481                 }
482 
483                 // #97016# II
484                 if(mpView->AreObjectsMarked())
485                     mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
486 
487                 bReturn = sal_True;
488             }
489         }
490         break;
491 
492         case KEY_END:
493         {
494             KeyCode aCode = rKEvt.GetKeyCode();
495 
496             if ( aCode.IsMod1() )
497             {
498                 // #97016# mark last object
499                 mpView->UnmarkAllObj();
500                 mpView->MarkNextObj(sal_False);
501 
502                 // #97016# II
503                 if(mpView->AreObjectsMarked())
504                     mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
505 
506                 bReturn = sal_True;
507             }
508         }
509         break;
510 
511         case KEY_HOME:
512         {
513             KeyCode aCode = rKEvt.GetKeyCode();
514 
515             if ( aCode.IsMod1() )
516             {
517                 // #97016# mark first object
518                 mpView->UnmarkAllObj();
519                 mpView->MarkNextObj(sal_True);
520 
521                 // #97016# II
522                 if(mpView->AreObjectsMarked())
523                     mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
524 
525                 bReturn = sal_True;
526             }
527         }
528         break;
529 
530         default:
531         break;
532     }
533 
534     if (!bReturn)
535     {
536         bReturn = FuPoor::KeyInput(rKEvt);
537     }
538     else
539     {
540         mpWindow->ReleaseMouse();
541     }
542 
543     return (bReturn);
544 }
545 
546 /*************************************************************************
547 |*
548 |* Fade out the selection-presentation before scrolling
549 |*
550 \************************************************************************/
551 
552 void FuDraw::ScrollStart()
553 {
554 }
555 
556 /*************************************************************************
557 |*
558 |* After scrolling show the selection-presentation again
559 |*
560 \************************************************************************/
561 
562 void FuDraw::ScrollEnd()
563 {
564 }
565 
566 /*************************************************************************
567 |*
568 |* Aktivate function
569 |*
570 \************************************************************************/
571 
572 void FuDraw::Activate()
573 {
574     FuPoor::Activate();
575     ForcePointer();
576 }
577 
578 /*************************************************************************
579 |*
580 |* Deaktivate function
581 |*
582 \************************************************************************/
583 
584 void FuDraw::Deactivate()
585 {
586     FuPoor::Deactivate();
587 }
588 
589 
590 /*************************************************************************
591 |*
592 |* Toggle mouse-pointer
593 |*
594 \************************************************************************/
595 
596 void FuDraw::ForcePointer(const MouseEvent* pMEvt)
597 {
598     Point aPnt;
599     sal_uInt16 nModifier = 0;
600     sal_Bool bLeftDown = sal_False;
601     sal_Bool bDefPointer = sal_True;
602 
603     if (pMEvt)
604     {
605         aPnt = mpWindow->PixelToLogic(pMEvt->GetPosPixel());
606         nModifier = pMEvt->GetModifier();
607         bLeftDown = pMEvt->IsLeft();
608     }
609     else
610     {
611         aPnt = mpWindow->PixelToLogic(mpWindow->GetPointerPosPixel());
612     }
613 
614     if (mpView->IsDragObj())
615     {
616         if (SD_MOD()->GetWaterCan() && !mpView->PickHandle(aPnt))
617         {
618             /******************************************************************
619             * Giesskannenmodus
620             ******************************************************************/
621             bDefPointer = sal_False;
622             mpWindow->SetPointer(Pointer(POINTER_FILL));
623         }
624     }
625     else
626     {
627         SdrHdl* pHdl = mpView->PickHandle(aPnt);
628 
629         if (SD_MOD()->GetWaterCan() && !pHdl)
630         {
631             /******************************************************************
632             * Giesskannenmodus
633             ******************************************************************/
634             bDefPointer = sal_False;
635             mpWindow->SetPointer(Pointer(POINTER_FILL));
636         }
637         else if (!pHdl &&
638                  mpViewShell->GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()))
639         {
640             /******************************************************************
641             * Pipettenmodus
642             ******************************************************************/
643             SvxBmpMask* pMask = (SvxBmpMask*) mpViewShell->GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId())->GetWindow();
644 
645             if (pMask && pMask->IsEyedropping())
646             {
647                 bDefPointer = sal_False;
648                 mpWindow->SetPointer(Pointer(POINTER_REFHAND));
649             }
650         }
651         else if (!mpView->IsAction())
652         {
653             SdrObject* pObj = NULL;
654             SdrPageView* pPV = NULL;
655             SdrViewEvent aVEvt;
656             SdrHitKind eHit = SDRHIT_NONE;
657             SdrDragMode eDragMode = mpView->GetDragMode();
658 
659             if (pMEvt)
660             {
661                 eHit = mpView->PickAnything(*pMEvt, SDRMOUSEMOVE, aVEvt);
662             }
663 
664             if ((eDragMode == SDRDRAG_ROTATE) && (eHit == SDRHIT_MARKEDOBJECT))
665             {
666                 // The goal of this request is show always the rotation-arrow for 3D-objects at rotation-modus
667                 // Independent of the settings at Extras->Optionen->Grafik "Objekte immer verschieben"
668                 // 2D-objects acquit in an other way. Otherwise, the rotation of 3d-objects around any axises
669                 // wouldn't be possible per default.
670                 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
671                 SdrObject* pObject = rMarkList.GetMark(0)->GetMarkedSdrObj();
672                 if ((pObject->ISA(E3dObject)) && (rMarkList.GetMarkCount() == 1))
673                 {
674                     mpWindow->SetPointer(Pointer(POINTER_ROTATE));
675                     bDefPointer = sal_False;     // Otherwise it'll be calles Joes routine and the mousepointer will reconfigurate again
676                 }
677             }
678 
679             if (eHit == SDRHIT_NONE)
680             {
681                 // found nothing -> look after at the masterpage
682                 mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER);
683             }
684             else if (eHit == SDRHIT_UNMARKEDOBJECT)
685             {
686                 pObj = aVEvt.pObj;
687             }
688             else if (eHit == SDRHIT_TEXTEDITOBJ && this->ISA(FuSelection))
689             {
690                 sal_uInt16 nSdrObjKind = aVEvt.pObj->GetObjIdentifier();
691 
692                 if ( nSdrObjKind != OBJ_TEXT        &&
693                      nSdrObjKind != OBJ_TITLETEXT   &&
694                      nSdrObjKind != OBJ_OUTLINETEXT &&
695                      aVEvt.pObj->IsEmptyPresObj() )
696                 {
697                     pObj = NULL;
698                     bDefPointer = sal_False;
699                     mpWindow->SetPointer(Pointer(POINTER_ARROW));
700                 }
701             }
702 
703             if (pObj && pMEvt && !pMEvt->IsMod2() && this->ISA(FuSelection))
704             {
705                 // Auf Animation oder ImageMap pruefen
706                 bDefPointer = !SetPointer(pObj, aPnt);
707 
708                 if (bDefPointer && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
709                 {
710                     // In die Gruppe hineinschauen
711                     if (mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER | SDRSEARCH_DEEP))
712                         bDefPointer = !SetPointer(pObj, aPnt);
713                 }
714             }
715         }
716     }
717 
718     if (bDefPointer)
719     {
720         mpWindow->SetPointer(mpView->GetPreferedPointer(
721                             aPnt, mpWindow, nModifier, bLeftDown));
722     }
723 }
724 
725 /*************************************************************************
726 |*
727 |* Set cursor for animaton or imagemap
728 |*
729 \************************************************************************/
730 
731 sal_Bool FuDraw::SetPointer(SdrObject* pObj, const Point& rPos)
732 {
733     sal_Bool bSet = sal_False;
734 
735     sal_Bool bAnimationInfo = (!mpDocSh->ISA(GraphicDocShell) &&
736                           mpDoc->GetAnimationInfo(pObj)) ? sal_True:sal_False;
737 
738     sal_Bool bImageMapInfo = sal_False;
739 
740     if (!bAnimationInfo)
741         bImageMapInfo = mpDoc->GetIMapInfo(pObj) ? sal_True:sal_False;
742 
743     if (bAnimationInfo || bImageMapInfo)
744     {
745         const SetOfByte* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
746         sal_uInt16 nHitLog(sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width()));
747         long  n2HitLog(nHitLog * 2);
748         Point aHitPosR(rPos);
749         Point aHitPosL(rPos);
750         Point aHitPosT(rPos);
751         Point aHitPosB(rPos);
752 
753         aHitPosR.X() += n2HitLog;
754         aHitPosL.X() -= n2HitLog;
755         aHitPosT.Y() += n2HitLog;
756         aHitPosB.Y() -= n2HitLog;
757 
758         if ( !pObj->IsClosedObj() ||
759             ( SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
760               SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
761               SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
762               SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false)))
763         {
764             /**********************************************************
765             * hit inside the object (without margin) or open object
766             ********************************************************/
767 
768             if (bAnimationInfo)
769             {
770                 /******************************************************
771                 * Click-Action
772                 ******************************************************/
773                 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
774 
775                 if ((mpView->ISA(DrawView) &&
776                       (pInfo->meClickAction == presentation::ClickAction_BOOKMARK  ||
777                        pInfo->meClickAction == presentation::ClickAction_DOCUMENT  ||
778                        pInfo->meClickAction == presentation::ClickAction_PREVPAGE  ||
779                        pInfo->meClickAction == presentation::ClickAction_NEXTPAGE  ||
780                        pInfo->meClickAction == presentation::ClickAction_FIRSTPAGE ||
781                        pInfo->meClickAction == presentation::ClickAction_LASTPAGE  ||
782                        pInfo->meClickAction == presentation::ClickAction_VERB      ||
783                        pInfo->meClickAction == presentation::ClickAction_PROGRAM   ||
784                        pInfo->meClickAction == presentation::ClickAction_MACRO     ||
785                        pInfo->meClickAction == presentation::ClickAction_SOUND))
786                                                                     ||
787                     (mpView->ISA(DrawView) &&
788                         SlideShow::IsRunning( mpViewShell->GetViewShellBase() )   &&
789                          (pInfo->meClickAction == presentation::ClickAction_VANISH            ||
790                           pInfo->meClickAction == presentation::ClickAction_INVISIBLE         ||
791                           pInfo->meClickAction == presentation::ClickAction_STOPPRESENTATION ||
792                          (pInfo->mbActive &&
793                           ( pInfo->meEffect != presentation::AnimationEffect_NONE ||
794                             pInfo->meTextEffect != presentation::AnimationEffect_NONE )))))
795                     {
796                         // Animations-Objekt
797                         bSet = sal_True;
798                         mpWindow->SetPointer(Pointer(POINTER_REFHAND));
799                     }
800             }
801             else if (bImageMapInfo &&
802                      mpDoc->GetHitIMapObject(pObj, rPos, *mpWindow))
803             {
804                 /******************************************************
805                 * ImageMap
806                 ******************************************************/
807                 bSet = sal_True;
808                 mpWindow->SetPointer(Pointer(POINTER_REFHAND));
809             }
810         }
811     }
812 
813     return bSet;
814 }
815 
816 
817 
818 /*************************************************************************
819 |*
820 |* Response of doubleclick
821 |*
822 \************************************************************************/
823 
824 void FuDraw::DoubleClick(const MouseEvent& rMEvt)
825 {
826     sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
827 
828     if ( mpView->AreObjectsMarked() )
829     {
830         const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
831 
832         if (rMarkList.GetMarkCount() == 1)
833         {
834             SdrMark* pMark = rMarkList.GetMark(0);
835             SdrObject* pObj = pMark->GetMarkedSdrObj();
836 
837             sal_uInt32 nInv = pObj->GetObjInventor();
838             sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
839 
840             if (nInv == SdrInventor && nSdrObjKind == OBJ_OLE2)
841             {
842                 DrawDocShell* pDocSh = mpDoc->GetDocSh();
843 
844                 if ( !pDocSh->IsUIActive() )
845                 {
846                     /**********************************************************
847                     * aktivate OLE-object
848                     **********************************************************/
849                     //HMHmpView->HideMarkHdl();
850                     mpViewShell->ActivateObject( (SdrOle2Obj*) pObj, 0);
851                 }
852             }
853             else if (nInv == SdrInventor &&  nSdrObjKind == OBJ_GRAF && pObj->IsEmptyPresObj() )
854             {
855                 mpViewShell->GetViewFrame()->
856                     GetDispatcher()->Execute( SID_INSERT_GRAPHIC,
857                                               SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
858             }
859             else if ( ( pObj->ISA(SdrTextObj) || pObj->ISA(SdrObjGroup) ) &&
860                       !SD_MOD()->GetWaterCan()                            &&
861                       mpViewShell->GetFrameView()->IsDoubleClickTextEdit() &&
862                       !mpDocSh->IsReadOnly())
863             {
864                 SfxUInt16Item aItem(SID_TEXTEDIT, 2);
865                 mpViewShell->GetViewFrame()->GetDispatcher()->
866                                  Execute(SID_TEXTEDIT, SFX_CALLMODE_ASYNCHRON |
867                                          SFX_CALLMODE_RECORD, &aItem, 0L);
868             }
869             else if (nInv == SdrInventor &&  nSdrObjKind == OBJ_GRUP)
870             {
871                 // hit group -> select subobject
872                 mpView->UnMarkAll();
873                 mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift(), sal_True);
874             }
875         }
876     }
877     else
878         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
879 }
880 
881 /*************************************************************************
882 |*
883 |* Help-event
884 |*
885 \************************************************************************/
886 
887 sal_Bool FuDraw::RequestHelp(const HelpEvent& rHEvt)
888 {
889     sal_Bool bReturn = sal_False;
890 
891     if (Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled())
892     {
893         SdrViewEvent aVEvt;
894 
895         MouseEvent aMEvt(mpWindow->GetPointerPosPixel(), 1, 0, MOUSE_LEFT);
896 
897         SdrHitKind eHit = mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
898 
899         SdrObject* pObj = aVEvt.pObj;
900 
901         if (eHit != SDRHIT_NONE && pObj != NULL)
902         {
903             Point aPosPixel = rHEvt.GetMousePosPixel();
904 
905             bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
906 
907             if (!bReturn && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
908             {
909                 // In die Gruppe hineinschauen
910                 SdrPageView* pPV = NULL;
911 
912                 Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(aPosPixel)));
913 
914                 if (mpView->PickObj(aPos, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER | SDRSEARCH_DEEP))
915                     bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
916             }
917         }
918     }
919 
920     if (!bReturn)
921     {
922         bReturn = FuPoor::RequestHelp(rHEvt);
923     }
924 
925     return(bReturn);
926 }
927 
928 
929 
930 /*************************************************************************
931 |*
932 |* Command-event
933 |*
934 \************************************************************************/
935 
936 sal_Bool FuDraw::SetHelpText(SdrObject* pObj, const Point& rPosPixel, const SdrViewEvent& rVEvt)
937 {
938     sal_Bool bSet = sal_False;
939     String aHelpText;
940     Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(rPosPixel)));
941 
942     // URL fuer IMapObject unter Pointer ist Hilfetext
943     if ( mpDoc->GetIMapInfo(pObj) )
944     {
945         IMapObject* pIMapObj = mpDoc->GetHitIMapObject(pObj, aPos, *mpWindow );
946 
947         if ( pIMapObj )
948         {
949             // show name
950             aHelpText = pIMapObj->GetAltText();
951 
952             if (aHelpText.Len() == 0)
953             {
954                 // show url if no name is available
955                 aHelpText = INetURLObject::decode( pIMapObj->GetURL(), '%', INetURLObject::DECODE_WITH_CHARSET );
956             }
957         }
958     }
959     else if (!mpDocSh->ISA(GraphicDocShell) && mpDoc->GetAnimationInfo(pObj))
960     {
961         SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
962 
963         switch (pInfo->meClickAction)
964         {
965             case presentation::ClickAction_PREVPAGE:
966             {
967                 // jump to the prior page
968                 aHelpText = String(SdResId(STR_CLICK_ACTION_PREVPAGE));
969             }
970             break;
971 
972             case presentation::ClickAction_NEXTPAGE:
973             {
974                 // jump to the next page
975                 aHelpText = String(SdResId(STR_CLICK_ACTION_NEXTPAGE));
976             }
977             break;
978 
979             case presentation::ClickAction_FIRSTPAGE:
980             {
981                 // jump to the first page
982                 aHelpText = String(SdResId(STR_CLICK_ACTION_FIRSTPAGE));
983             }
984             break;
985 
986             case presentation::ClickAction_LASTPAGE:
987             {
988                 // jump to the last page
989                 aHelpText = String(SdResId(STR_CLICK_ACTION_LASTPAGE));
990             }
991             break;
992 
993             case presentation::ClickAction_BOOKMARK:
994             {
995                 // jump to object/page
996                 aHelpText = String(SdResId(STR_CLICK_ACTION_BOOKMARK));
997                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
998                 aHelpText.Append( String(INetURLObject::decode( pInfo->GetBookmark(), '%', INetURLObject::DECODE_WITH_CHARSET ) ));
999             }
1000             break;
1001 
1002             case presentation::ClickAction_DOCUMENT:
1003             {
1004                 // jump to document (object/page)
1005                 aHelpText = String(SdResId(STR_CLICK_ACTION_DOCUMENT));
1006                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
1007                 aHelpText.Append( String(INetURLObject::decode( pInfo->GetBookmark(), '%', INetURLObject::DECODE_WITH_CHARSET ) ));
1008             }
1009             break;
1010 
1011             case presentation::ClickAction_PROGRAM:
1012             {
1013                 // execute program
1014                 aHelpText = String(SdResId(STR_CLICK_ACTION_PROGRAM));
1015                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
1016                 aHelpText.Append( String(INetURLObject::decode( pInfo->GetBookmark(), '%', INetURLObject::DECODE_WITH_CHARSET ) ));
1017             }
1018             break;
1019 
1020             case presentation::ClickAction_MACRO:
1021             {
1022                 // execute program
1023                 aHelpText = String(SdResId(STR_CLICK_ACTION_MACRO));
1024                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
1025 
1026                 if ( SfxApplication::IsXScriptURL( pInfo->GetBookmark() ) )
1027                 {
1028                     aHelpText.Append( pInfo->GetBookmark() );
1029                 }
1030                 else
1031                 {
1032                     String sBookmark( pInfo->GetBookmark() );
1033                     sal_Unicode cToken = '.';
1034                     aHelpText.Append( sBookmark.GetToken( 2, cToken ) );
1035                     aHelpText.Append( cToken );
1036                     aHelpText.Append( sBookmark.GetToken( 1, cToken ) );
1037                     aHelpText.Append( cToken );
1038                     aHelpText.Append( sBookmark.GetToken( 0, cToken ) );
1039                 }
1040             }
1041             break;
1042 
1043             case presentation::ClickAction_SOUND:
1044             {
1045                 // play-back sound
1046                 aHelpText = String(SdResId(STR_CLICK_ACTION_SOUND));
1047             }
1048             break;
1049 
1050             case presentation::ClickAction_VERB:
1051             {
1052                 // execute OLE-verb
1053                 aHelpText = String(SdResId(STR_CLICK_ACTION_VERB));
1054             }
1055             break;
1056 
1057             case presentation::ClickAction_STOPPRESENTATION:
1058             {
1059                 // quit presentation
1060                 aHelpText = String(SdResId(STR_CLICK_ACTION_STOPPRESENTATION));
1061             }
1062             break;
1063             default:
1064                 break;
1065         }
1066     }
1067     else if (rVEvt.pURLField)
1068     {
1069         /**************************************************************
1070         * URL-Field
1071         **************************************************************/
1072         aHelpText = INetURLObject::decode( rVEvt.pURLField->GetURL(), '%', INetURLObject::DECODE_WITH_CHARSET );
1073     }
1074 
1075     if (aHelpText.Len())
1076     {
1077         bSet = sal_True;
1078         Rectangle aLogicPix = mpWindow->LogicToPixel(pObj->GetLogicRect());
1079         Rectangle aScreenRect(mpWindow->OutputToScreenPixel(aLogicPix.TopLeft()),
1080                               mpWindow->OutputToScreenPixel(aLogicPix.BottomRight()));
1081 
1082         if (Help::IsBalloonHelpEnabled())
1083             Help::ShowBalloon( (Window*)mpWindow, rPosPixel, aScreenRect, aHelpText);
1084         else if (Help::IsQuickHelpEnabled())
1085             Help::ShowQuickHelp( (Window*)mpWindow, aScreenRect, aHelpText);
1086     }
1087 
1088     return bSet;
1089 }
1090 
1091 
1092 /** is called when the currenct function should be aborted. <p>
1093     This is used when a function gets a KEY_ESCAPE but can also
1094     be called directly.
1095 
1096     @returns true if a active function was aborted
1097 */
1098 bool FuDraw::cancel()
1099 {
1100     bool bReturn = false;
1101 
1102     if ( mpView->IsAction() )
1103     {
1104         mpView->BrkAction();
1105         bReturn = true;
1106     }
1107     else if ( mpView->IsTextEdit() )
1108     {
1109         mpView->SdrEndTextEdit();
1110         bReturn = true;
1111 
1112         SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
1113         rBindings.Invalidate( SID_PARASPACE_INCREASE );
1114         rBindings.Invalidate( SID_PARASPACE_DECREASE );
1115     }
1116     else if ( mpView->AreObjectsMarked() )
1117     {
1118         // #97016# II
1119         const SdrHdlList& rHdlList = mpView->GetHdlList();
1120         SdrHdl* pHdl = rHdlList.GetFocusHdl();
1121 
1122         if(pHdl)
1123         {
1124             ((SdrHdlList&)rHdlList).ResetFocusHdl();
1125         }
1126         else
1127         {
1128             mpView->UnmarkAll();
1129         }
1130 
1131         // Switch to FuSelect.
1132         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
1133             SID_OBJECT_SELECT,
1134             SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
1135 
1136         bReturn = true;
1137     }
1138 
1139     return bReturn;
1140 }
1141 
1142 } // end of namespace sd
1143