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