xref: /AOO41X/main/sd/source/ui/func/fudraw.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
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                     // #97016# No next object: go over open end and
474                     // get first from the other side
475                     mpView->UnmarkAllObj();
476                     mpView->MarkNextObj(!aCode.IsShift());
477                 }
478 
479                 // #97016# II
480                 if(mpView->AreObjectsMarked())
481                     mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
482 
483                 bReturn = sal_True;
484             }
485         }
486         break;
487 
488         case KEY_END:
489         {
490             KeyCode aCode = rKEvt.GetKeyCode();
491 
492             if ( aCode.IsMod1() )
493             {
494                 // #97016# mark last object
495                 mpView->UnmarkAllObj();
496                 mpView->MarkNextObj(sal_False);
497 
498                 // #97016# II
499                 if(mpView->AreObjectsMarked())
500                     mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
501 
502                 bReturn = sal_True;
503             }
504         }
505         break;
506 
507         case KEY_HOME:
508         {
509             KeyCode aCode = rKEvt.GetKeyCode();
510 
511             if ( aCode.IsMod1() )
512             {
513                 // #97016# mark first object
514                 mpView->UnmarkAllObj();
515                 mpView->MarkNextObj(sal_True);
516 
517                 // #97016# II
518                 if(mpView->AreObjectsMarked())
519                     mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
520 
521                 bReturn = sal_True;
522             }
523         }
524         break;
525 
526         default:
527         break;
528     }
529 
530     if (!bReturn)
531     {
532         bReturn = FuPoor::KeyInput(rKEvt);
533     }
534     else
535     {
536         mpWindow->ReleaseMouse();
537     }
538 
539     return (bReturn);
540 }
541 
542 /*************************************************************************
543 |*
544 |* Fade out the selection-presentation before scrolling
545 |*
546 \************************************************************************/
547 
548 void FuDraw::ScrollStart()
549 {
550 }
551 
552 /*************************************************************************
553 |*
554 |* After scrolling show the selection-presentation again
555 |*
556 \************************************************************************/
557 
558 void FuDraw::ScrollEnd()
559 {
560 }
561 
562 /*************************************************************************
563 |*
564 |* Aktivate function
565 |*
566 \************************************************************************/
567 
568 void FuDraw::Activate()
569 {
570     FuPoor::Activate();
571     ForcePointer();
572 }
573 
574 /*************************************************************************
575 |*
576 |* Deaktivate function
577 |*
578 \************************************************************************/
579 
580 void FuDraw::Deactivate()
581 {
582     FuPoor::Deactivate();
583 }
584 
585 
586 /*************************************************************************
587 |*
588 |* Toggle mouse-pointer
589 |*
590 \************************************************************************/
591 
592 void FuDraw::ForcePointer(const MouseEvent* pMEvt)
593 {
594     Point aPnt;
595     sal_uInt16 nModifier = 0;
596     sal_Bool bLeftDown = sal_False;
597     sal_Bool bDefPointer = sal_True;
598 
599     if (pMEvt)
600     {
601         aPnt = mpWindow->PixelToLogic(pMEvt->GetPosPixel());
602         nModifier = pMEvt->GetModifier();
603         bLeftDown = pMEvt->IsLeft();
604     }
605     else
606     {
607         aPnt = mpWindow->PixelToLogic(mpWindow->GetPointerPosPixel());
608     }
609 
610     if (mpView->IsDragObj())
611     {
612         if (SD_MOD()->GetWaterCan() && !mpView->PickHandle(aPnt))
613         {
614             /******************************************************************
615             * Giesskannenmodus
616             ******************************************************************/
617             bDefPointer = sal_False;
618             mpWindow->SetPointer(Pointer(POINTER_FILL));
619         }
620     }
621     else
622     {
623         SdrHdl* pHdl = mpView->PickHandle(aPnt);
624 
625         if (SD_MOD()->GetWaterCan() && !pHdl)
626         {
627             /******************************************************************
628             * Giesskannenmodus
629             ******************************************************************/
630             bDefPointer = sal_False;
631             mpWindow->SetPointer(Pointer(POINTER_FILL));
632         }
633         else if (!pHdl &&
634                  mpViewShell->GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()))
635         {
636             /******************************************************************
637             * Pipettenmodus
638             ******************************************************************/
639             SvxBmpMask* pMask = (SvxBmpMask*) mpViewShell->GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId())->GetWindow();
640 
641             if (pMask && pMask->IsEyedropping())
642             {
643                 bDefPointer = sal_False;
644                 mpWindow->SetPointer(Pointer(POINTER_REFHAND));
645             }
646         }
647         else if (!mpView->IsAction())
648         {
649             SdrObject* pObj = NULL;
650             SdrPageView* pPV = NULL;
651             SdrViewEvent aVEvt;
652             SdrHitKind eHit = SDRHIT_NONE;
653             SdrDragMode eDragMode = mpView->GetDragMode();
654 
655             if (pMEvt)
656             {
657                 eHit = mpView->PickAnything(*pMEvt, SDRMOUSEMOVE, aVEvt);
658             }
659 
660             if ((eDragMode == SDRDRAG_ROTATE) && (eHit == SDRHIT_MARKEDOBJECT))
661             {
662                 // The goal of this request is show always the rotation-arrow for 3D-objects at rotation-modus
663                 // Independent of the settings at Extras->Optionen->Grafik "Objekte immer verschieben"
664                 // 2D-objects acquit in an other way. Otherwise, the rotation of 3d-objects around any axises
665                 // wouldn't be possible per default.
666                 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
667                 SdrObject* pObject = rMarkList.GetMark(0)->GetMarkedSdrObj();
668                 if ((pObject->ISA(E3dObject)) && (rMarkList.GetMarkCount() == 1))
669                 {
670                     mpWindow->SetPointer(Pointer(POINTER_ROTATE));
671                     bDefPointer = sal_False;     // Otherwise it'll be calles Joes routine and the mousepointer will reconfigurate again
672                 }
673             }
674 
675             if (eHit == SDRHIT_NONE)
676             {
677                 // found nothing -> look after at the masterpage
678                 mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER);
679             }
680             else if (eHit == SDRHIT_UNMARKEDOBJECT)
681             {
682                 pObj = aVEvt.pObj;
683             }
684             else if (eHit == SDRHIT_TEXTEDITOBJ && this->ISA(FuSelection))
685             {
686                 sal_uInt16 nSdrObjKind = aVEvt.pObj->GetObjIdentifier();
687 
688                 if ( nSdrObjKind != OBJ_TEXT        &&
689                      nSdrObjKind != OBJ_TITLETEXT   &&
690                      nSdrObjKind != OBJ_OUTLINETEXT &&
691                      aVEvt.pObj->IsEmptyPresObj() )
692                 {
693                     pObj = NULL;
694                     bDefPointer = sal_False;
695                     mpWindow->SetPointer(Pointer(POINTER_ARROW));
696                 }
697             }
698 
699             if (pObj && pMEvt && !pMEvt->IsMod2() && this->ISA(FuSelection))
700             {
701                 // Auf Animation oder ImageMap pruefen
702                 bDefPointer = !SetPointer(pObj, aPnt);
703 
704                 if (bDefPointer && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
705                 {
706                     // In die Gruppe hineinschauen
707                     if (mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER | SDRSEARCH_DEEP))
708                         bDefPointer = !SetPointer(pObj, aPnt);
709                 }
710             }
711         }
712     }
713 
714     if (bDefPointer)
715     {
716         mpWindow->SetPointer(mpView->GetPreferedPointer(
717                             aPnt, mpWindow, nModifier, bLeftDown));
718     }
719 }
720 
721 /*************************************************************************
722 |*
723 |* Set cursor for animaton or imagemap
724 |*
725 \************************************************************************/
726 
727 sal_Bool FuDraw::SetPointer(SdrObject* pObj, const Point& rPos)
728 {
729     sal_Bool bSet = sal_False;
730 
731     sal_Bool bAnimationInfo = (!mpDocSh->ISA(GraphicDocShell) &&
732                           mpDoc->GetAnimationInfo(pObj)) ? sal_True:sal_False;
733 
734     sal_Bool bImageMapInfo = sal_False;
735 
736     if (!bAnimationInfo)
737         bImageMapInfo = mpDoc->GetIMapInfo(pObj) ? sal_True:sal_False;
738 
739     if (bAnimationInfo || bImageMapInfo)
740     {
741         const SetOfByte* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
742         sal_uInt16 nHitLog(sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width()));
743         long  n2HitLog(nHitLog * 2);
744         Point aHitPosR(rPos);
745         Point aHitPosL(rPos);
746         Point aHitPosT(rPos);
747         Point aHitPosB(rPos);
748 
749         aHitPosR.X() += n2HitLog;
750         aHitPosL.X() -= n2HitLog;
751         aHitPosT.Y() += n2HitLog;
752         aHitPosB.Y() -= n2HitLog;
753 
754         if ( !pObj->IsClosedObj() ||
755             ( SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
756               SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
757               SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
758               SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false)))
759         {
760             /**********************************************************
761             * hit inside the object (without margin) or open object
762             ********************************************************/
763 
764             if (bAnimationInfo)
765             {
766                 /******************************************************
767                 * Click-Action
768                 ******************************************************/
769                 SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
770 
771                 if ((mpView->ISA(DrawView) &&
772                       (pInfo->meClickAction == presentation::ClickAction_BOOKMARK  ||
773                        pInfo->meClickAction == presentation::ClickAction_DOCUMENT  ||
774                        pInfo->meClickAction == presentation::ClickAction_PREVPAGE  ||
775                        pInfo->meClickAction == presentation::ClickAction_NEXTPAGE  ||
776                        pInfo->meClickAction == presentation::ClickAction_FIRSTPAGE ||
777                        pInfo->meClickAction == presentation::ClickAction_LASTPAGE  ||
778                        pInfo->meClickAction == presentation::ClickAction_VERB      ||
779                        pInfo->meClickAction == presentation::ClickAction_PROGRAM   ||
780                        pInfo->meClickAction == presentation::ClickAction_MACRO     ||
781                        pInfo->meClickAction == presentation::ClickAction_SOUND))
782                                                                     ||
783                     (mpView->ISA(DrawView) &&
784                         SlideShow::IsRunning( mpViewShell->GetViewShellBase() )   &&
785                          (pInfo->meClickAction == presentation::ClickAction_VANISH            ||
786                           pInfo->meClickAction == presentation::ClickAction_INVISIBLE         ||
787                           pInfo->meClickAction == presentation::ClickAction_STOPPRESENTATION ||
788                          (pInfo->mbActive &&
789                           ( pInfo->meEffect != presentation::AnimationEffect_NONE ||
790                             pInfo->meTextEffect != presentation::AnimationEffect_NONE )))))
791                     {
792                         // Animations-Objekt
793                         bSet = sal_True;
794                         mpWindow->SetPointer(Pointer(POINTER_REFHAND));
795                     }
796             }
797             else if (bImageMapInfo &&
798                      mpDoc->GetHitIMapObject(pObj, rPos, *mpWindow))
799             {
800                 /******************************************************
801                 * ImageMap
802                 ******************************************************/
803                 bSet = sal_True;
804                 mpWindow->SetPointer(Pointer(POINTER_REFHAND));
805             }
806         }
807     }
808 
809     return bSet;
810 }
811 
812 
813 
814 /*************************************************************************
815 |*
816 |* Response of doubleclick
817 |*
818 \************************************************************************/
819 
820 void FuDraw::DoubleClick(const MouseEvent& rMEvt)
821 {
822     sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
823 
824     if ( mpView->AreObjectsMarked() )
825     {
826         const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
827 
828         if (rMarkList.GetMarkCount() == 1)
829         {
830             SdrMark* pMark = rMarkList.GetMark(0);
831             SdrObject* pObj = pMark->GetMarkedSdrObj();
832 
833             sal_uInt32 nInv = pObj->GetObjInventor();
834             sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
835 
836             if (nInv == SdrInventor && nSdrObjKind == OBJ_OLE2)
837             {
838                 DrawDocShell* pDocSh = mpDoc->GetDocSh();
839 
840                 if ( !pDocSh->IsUIActive() )
841                 {
842                     /**********************************************************
843                     * aktivate OLE-object
844                     **********************************************************/
845                     //HMHmpView->HideMarkHdl();
846                     mpViewShell->ActivateObject( (SdrOle2Obj*) pObj, 0);
847                 }
848             }
849             else if (nInv == SdrInventor &&  nSdrObjKind == OBJ_GRAF && pObj->IsEmptyPresObj() )
850             {
851                 mpViewShell->GetViewFrame()->
852                     GetDispatcher()->Execute( SID_INSERT_GRAPHIC,
853                                               SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
854             }
855             else if ( ( pObj->ISA(SdrTextObj) || pObj->ISA(SdrObjGroup) ) &&
856                       !SD_MOD()->GetWaterCan()                            &&
857                       mpViewShell->GetFrameView()->IsDoubleClickTextEdit() &&
858                       !mpDocSh->IsReadOnly())
859             {
860                 SfxUInt16Item aItem(SID_TEXTEDIT, 2);
861                 mpViewShell->GetViewFrame()->GetDispatcher()->
862                                  Execute(SID_TEXTEDIT, SFX_CALLMODE_ASYNCHRON |
863                                          SFX_CALLMODE_RECORD, &aItem, 0L);
864             }
865             else if (nInv == SdrInventor &&  nSdrObjKind == OBJ_GRUP)
866             {
867                 // hit group -> select subobject
868                 mpView->UnMarkAll();
869                 mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift(), sal_True);
870             }
871         }
872     }
873     else
874         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
875 }
876 
877 /*************************************************************************
878 |*
879 |* Help-event
880 |*
881 \************************************************************************/
882 
883 sal_Bool FuDraw::RequestHelp(const HelpEvent& rHEvt)
884 {
885     sal_Bool bReturn = sal_False;
886 
887     if (Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled())
888     {
889         SdrViewEvent aVEvt;
890 
891         MouseEvent aMEvt(mpWindow->GetPointerPosPixel(), 1, 0, MOUSE_LEFT);
892 
893         SdrHitKind eHit = mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
894 
895         SdrObject* pObj = aVEvt.pObj;
896 
897         if (eHit != SDRHIT_NONE && pObj != NULL)
898         {
899             Point aPosPixel = rHEvt.GetMousePosPixel();
900 
901             bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
902 
903             if (!bReturn && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
904             {
905                 // In die Gruppe hineinschauen
906                 SdrPageView* pPV = NULL;
907 
908                 Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(aPosPixel)));
909 
910                 if (mpView->PickObj(aPos, mpView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER | SDRSEARCH_DEEP))
911                     bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
912             }
913         }
914     }
915 
916     if (!bReturn)
917     {
918         bReturn = FuPoor::RequestHelp(rHEvt);
919     }
920 
921     return(bReturn);
922 }
923 
924 
925 
926 /*************************************************************************
927 |*
928 |* Command-event
929 |*
930 \************************************************************************/
931 
932 sal_Bool FuDraw::SetHelpText(SdrObject* pObj, const Point& rPosPixel, const SdrViewEvent& rVEvt)
933 {
934     sal_Bool bSet = sal_False;
935     String aHelpText;
936     Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(rPosPixel)));
937 
938     // URL fuer IMapObject unter Pointer ist Hilfetext
939     if ( mpDoc->GetIMapInfo(pObj) )
940     {
941         IMapObject* pIMapObj = mpDoc->GetHitIMapObject(pObj, aPos, *mpWindow );
942 
943         if ( pIMapObj )
944         {
945             // show name
946             aHelpText = pIMapObj->GetAltText();
947 
948             if (aHelpText.Len() == 0)
949             {
950                 // show url if no name is available
951                 aHelpText = INetURLObject::decode( pIMapObj->GetURL(), '%', INetURLObject::DECODE_WITH_CHARSET );
952             }
953         }
954     }
955     else if (!mpDocSh->ISA(GraphicDocShell) && mpDoc->GetAnimationInfo(pObj))
956     {
957         SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
958 
959         switch (pInfo->meClickAction)
960         {
961             case presentation::ClickAction_PREVPAGE:
962             {
963                 // jump to the prior page
964                 aHelpText = String(SdResId(STR_CLICK_ACTION_PREVPAGE));
965             }
966             break;
967 
968             case presentation::ClickAction_NEXTPAGE:
969             {
970                 // jump to the next page
971                 aHelpText = String(SdResId(STR_CLICK_ACTION_NEXTPAGE));
972             }
973             break;
974 
975             case presentation::ClickAction_FIRSTPAGE:
976             {
977                 // jump to the first page
978                 aHelpText = String(SdResId(STR_CLICK_ACTION_FIRSTPAGE));
979             }
980             break;
981 
982             case presentation::ClickAction_LASTPAGE:
983             {
984                 // jump to the last page
985                 aHelpText = String(SdResId(STR_CLICK_ACTION_LASTPAGE));
986             }
987             break;
988 
989             case presentation::ClickAction_BOOKMARK:
990             {
991                 // jump to object/page
992                 aHelpText = String(SdResId(STR_CLICK_ACTION_BOOKMARK));
993                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
994                 aHelpText.Append( String(INetURLObject::decode( pInfo->GetBookmark(), '%', INetURLObject::DECODE_WITH_CHARSET ) ));
995             }
996             break;
997 
998             case presentation::ClickAction_DOCUMENT:
999             {
1000                 // jump to document (object/page)
1001                 aHelpText = String(SdResId(STR_CLICK_ACTION_DOCUMENT));
1002                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
1003                 aHelpText.Append( String(INetURLObject::decode( pInfo->GetBookmark(), '%', INetURLObject::DECODE_WITH_CHARSET ) ));
1004             }
1005             break;
1006 
1007             case presentation::ClickAction_PROGRAM:
1008             {
1009                 // execute program
1010                 aHelpText = String(SdResId(STR_CLICK_ACTION_PROGRAM));
1011                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
1012                 aHelpText.Append( String(INetURLObject::decode( pInfo->GetBookmark(), '%', INetURLObject::DECODE_WITH_CHARSET ) ));
1013             }
1014             break;
1015 
1016             case presentation::ClickAction_MACRO:
1017             {
1018                 // execute program
1019                 aHelpText = String(SdResId(STR_CLICK_ACTION_MACRO));
1020                 aHelpText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " ) );
1021 
1022                 if ( SfxApplication::IsXScriptURL( pInfo->GetBookmark() ) )
1023                 {
1024                     aHelpText.Append( pInfo->GetBookmark() );
1025                 }
1026                 else
1027                 {
1028                     String sBookmark( pInfo->GetBookmark() );
1029                     sal_Unicode cToken = '.';
1030                     aHelpText.Append( sBookmark.GetToken( 2, cToken ) );
1031                     aHelpText.Append( cToken );
1032                     aHelpText.Append( sBookmark.GetToken( 1, cToken ) );
1033                     aHelpText.Append( cToken );
1034                     aHelpText.Append( sBookmark.GetToken( 0, cToken ) );
1035                 }
1036             }
1037             break;
1038 
1039             case presentation::ClickAction_SOUND:
1040             {
1041                 // play-back sound
1042                 aHelpText = String(SdResId(STR_CLICK_ACTION_SOUND));
1043             }
1044             break;
1045 
1046             case presentation::ClickAction_VERB:
1047             {
1048                 // execute OLE-verb
1049                 aHelpText = String(SdResId(STR_CLICK_ACTION_VERB));
1050             }
1051             break;
1052 
1053             case presentation::ClickAction_STOPPRESENTATION:
1054             {
1055                 // quit presentation
1056                 aHelpText = String(SdResId(STR_CLICK_ACTION_STOPPRESENTATION));
1057             }
1058             break;
1059             default:
1060                 break;
1061         }
1062     }
1063     else if (rVEvt.pURLField)
1064     {
1065         /**************************************************************
1066         * URL-Field
1067         **************************************************************/
1068         aHelpText = INetURLObject::decode( rVEvt.pURLField->GetURL(), '%', INetURLObject::DECODE_WITH_CHARSET );
1069     }
1070 
1071     if (aHelpText.Len())
1072     {
1073         bSet = sal_True;
1074         Rectangle aLogicPix = mpWindow->LogicToPixel(pObj->GetLogicRect());
1075         Rectangle aScreenRect(mpWindow->OutputToScreenPixel(aLogicPix.TopLeft()),
1076                               mpWindow->OutputToScreenPixel(aLogicPix.BottomRight()));
1077 
1078         if (Help::IsBalloonHelpEnabled())
1079             Help::ShowBalloon( (Window*)mpWindow, rPosPixel, aScreenRect, aHelpText);
1080         else if (Help::IsQuickHelpEnabled())
1081             Help::ShowQuickHelp( (Window*)mpWindow, aScreenRect, aHelpText);
1082     }
1083 
1084     return bSet;
1085 }
1086 
1087 
1088 /** is called when the currenct function should be aborted. <p>
1089     This is used when a function gets a KEY_ESCAPE but can also
1090     be called directly.
1091 
1092     @returns true if a active function was aborted
1093 */
1094 bool FuDraw::cancel()
1095 {
1096     bool bReturn = false;
1097 
1098     if ( mpView->IsAction() )
1099     {
1100         mpView->BrkAction();
1101         bReturn = true;
1102     }
1103     else if ( mpView->IsTextEdit() )
1104     {
1105         mpView->SdrEndTextEdit();
1106         bReturn = true;
1107 
1108         SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
1109         rBindings.Invalidate( SID_PARASPACE_INCREASE );
1110         rBindings.Invalidate( SID_PARASPACE_DECREASE );
1111     }
1112     else if ( mpView->AreObjectsMarked() )
1113     {
1114         // #97016# II
1115         const SdrHdlList& rHdlList = mpView->GetHdlList();
1116         SdrHdl* pHdl = rHdlList.GetFocusHdl();
1117 
1118         if(pHdl)
1119         {
1120             ((SdrHdlList&)rHdlList).ResetFocusHdl();
1121         }
1122         else
1123         {
1124             mpView->UnmarkAll();
1125         }
1126 
1127         // Switch to FuSelect.
1128         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
1129             SID_OBJECT_SELECT,
1130             SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
1131 
1132         bReturn = true;
1133     }
1134 
1135     return bReturn;
1136 }
1137 
1138 } // end of namespace sd
1139