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