xref: /aoo42x/main/sd/source/ui/func/fudraw.cxx (revision cdf0e10c)
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