xref: /trunk/main/sc/source/ui/drawfunc/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_sc.hxx"
30 
31 //------------------------------------------------------------------------
32 
33 #include <editeng/editeng.hxx>	// EditEngine::IsSimpleCharInput
34 #include <editeng/outlobj.hxx>
35 #include <svx/svdobj.hxx>
36 #include <svx/svdoole2.hxx>
37 #include <svx/svdouno.hxx>
38 #include <svx/svdocapt.hxx>
39 #include <svx/svdpage.hxx>
40 #include <svx/svditer.hxx>
41 #include <svx/svdundo.hxx>
42 #include <sfx2/dispatch.hxx>
43 #include <sfx2/viewfrm.hxx>
44 
45 #include "sc.hrc"
46 #include "fudraw.hxx"
47 #include "futext.hxx"
48 #include "tabvwsh.hxx"
49 #include "drwlayer.hxx"
50 #include "scresid.hxx"
51 #include "userdat.hxx"
52 #include "docsh.hxx"
53 #include "postit.hxx"
54 #include "globstr.hrc"
55 #include "drawview.hxx"
56 
57 /*************************************************************************
58 |*
59 |* Basisklasse fuer alle Drawmodul-spezifischen Funktionen
60 |*
61 \************************************************************************/
62 
63 FuDraw::FuDraw(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
64 			   SdrModel* pDoc, SfxRequest& rReq) :
65     FuPoor      (pViewSh, pWin, pViewP, pDoc, rReq),
66 	aNewPointer ( POINTER_ARROW ),
67 	aOldPointer ( POINTER_ARROW )
68 {
69 }
70 
71 /*************************************************************************
72 |*
73 |* Destruktor
74 |*
75 \************************************************************************/
76 
77 FuDraw::~FuDraw()
78 {
79 }
80 
81 /*************************************************************************
82 |*
83 |* Modifier-Tasten auswerten
84 |*
85 \************************************************************************/
86 
87 void FuDraw::DoModifiers(const MouseEvent& rMEvt)
88 {
89 	//	Shift	= Ortho und AngleSnap
90 	//	Control	= Snap (Toggle)
91 	//	Alt		= zentrisch
92 
93 	sal_Bool bShift	= rMEvt.IsShift();
94 //    sal_Bool bCtrl  = rMEvt.IsMod1();
95 	sal_Bool bAlt	= rMEvt.IsMod2();
96 
97 //    ScViewData* pViewData = pViewShell->GetViewData();
98 //    const ScViewOptions& rOpt = pViewData->GetOptions();
99 //    const ScGridOptions& rGrid = rOpt.GetGridOptions();
100 //    sal_Bool bGridOpt = rGrid.GetUseGridSnap();
101 
102 	sal_Bool bOrtho		= bShift;
103 	sal_Bool bAngleSnap	= bShift;
104 //    sal_Bool bGridSnap  = ( bGridOpt != bCtrl );        // andere Snap's nicht unterstuetzt
105 	sal_Bool bCenter	= bAlt;
106 
107 	// #i33136#
108 	if(doConstructOrthogonal())
109 	{
110 		bOrtho = !bShift;
111 	}
112 
113 	if (pView->IsOrtho() != bOrtho)
114 		pView->SetOrtho(bOrtho);
115 	if (pView->IsAngleSnapEnabled() != bAngleSnap)
116 		pView->SetAngleSnapEnabled(bAngleSnap);
117 
118 /*	Control fuer Snap beisst sich beim Verschieben mit "kopieren" !!!
119 
120 	if (pView->IsGridSnap() != bGridSnap)
121 		pView->SetGridSnap(bGridSnap);
122 	if (pView->IsSnapEnabled() != bGridSnap)
123 		pView->SetSnapEnabled(bGridSnap);
124 */
125 	if (pView->IsCreate1stPointAsCenter() != bCenter)
126 		pView->SetCreate1stPointAsCenter(bCenter);
127 	if (pView->IsResizeAtCenter() != bCenter)
128 		pView->SetResizeAtCenter(bCenter);
129 
130 }
131 
132 void FuDraw::ResetModifiers()
133 {
134 	ScViewData* pViewData = pViewShell->GetViewData();
135 	const ScViewOptions& rOpt = pViewData->GetOptions();
136 	const ScGridOptions& rGrid = rOpt.GetGridOptions();
137 	sal_Bool bGridOpt = rGrid.GetUseGridSnap();
138 
139 	if (pView->IsOrtho())
140 		pView->SetOrtho(sal_False);
141 	if (pView->IsAngleSnapEnabled())
142 		pView->SetAngleSnapEnabled(sal_False);
143 
144 	if (pView->IsGridSnap() != bGridOpt)
145 		pView->SetGridSnap(bGridOpt);
146 	if (pView->IsSnapEnabled() != bGridOpt)
147 		pView->SetSnapEnabled(bGridOpt);
148 
149 	if (pView->IsCreate1stPointAsCenter())
150 		pView->SetCreate1stPointAsCenter(sal_False);
151 	if (pView->IsResizeAtCenter())
152 		pView->SetResizeAtCenter(sal_False);
153 }
154 
155 /*************************************************************************
156 |*
157 |* MouseButtonDown-event
158 |*
159 \************************************************************************/
160 
161 sal_Bool __EXPORT FuDraw::MouseButtonDown(const MouseEvent& rMEvt)
162 {
163 	// #95491# remember button state for creation of own MouseEvents
164 	SetMouseButtonCode(rMEvt.GetButtons());
165 
166 	DoModifiers( rMEvt );
167 	return sal_False;
168 }
169 
170 /*************************************************************************
171 |*
172 |* MouseMove-event
173 |*
174 \************************************************************************/
175 
176 sal_Bool __EXPORT FuDraw::MouseMove(const MouseEvent& rMEvt)
177 {
178 	//	#106438# evaluate modifiers only if in a drawing layer action
179 	//	(don't interfere with keyboard shortcut handling)
180 	if (pView->IsAction())
181 		DoModifiers( rMEvt );
182 
183 	return sal_False;
184 }
185 
186 /*************************************************************************
187 |*
188 |* MouseButtonUp-event
189 |*
190 \************************************************************************/
191 
192 sal_Bool __EXPORT FuDraw::MouseButtonUp(const MouseEvent& rMEvt)
193 {
194 	// #95491# remember button state for creation of own MouseEvents
195 	SetMouseButtonCode(rMEvt.GetButtons());
196 
197 	ResetModifiers();
198 	return sal_False;
199 }
200 
201 /*************************************************************************
202 |*
203 |* Tastaturereignisse bearbeiten
204 |*
205 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
206 |* FALSE.
207 |*
208 \************************************************************************/
209 
210 sal_Bool lcl_KeyEditMode( SdrObject* pObj, ScTabViewShell* pViewShell, const KeyEvent* pInitialKey )
211 {
212 	sal_Bool bReturn = sal_False;
213 	if ( pObj && pObj->ISA(SdrTextObj) && !pObj->ISA(SdrUnoObj) )
214 	{
215 		// start text edit - like FuSelection::MouseButtonUp,
216 		// but with bCursorToEnd instead of mouse position
217 
218 		OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
219 		sal_Bool bVertical = ( pOPO && pOPO->IsVertical() );
220 		sal_uInt16 nTextSlotId = bVertical ? SID_DRAW_TEXT_VERTICAL : SID_DRAW_TEXT;
221 
222 		// don't switch shells if text shell is already active
223 		FuPoor* pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
224 		if ( !pPoor || pPoor->GetSlotID() != nTextSlotId )
225 		{
226 			pViewShell->GetViewData()->GetDispatcher().
227 				Execute(nTextSlotId, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
228 		}
229 
230 		// get the resulting FuText and set in edit mode
231 		pPoor = pViewShell->GetViewData()->GetView()->GetDrawFuncPtr();
232 		if ( pPoor && pPoor->GetSlotID() == nTextSlotId )	 //	no RTTI
233 		{
234 			FuText* pText = (FuText*)pPoor;
235 			pText->SetInEditMode( pObj, NULL, sal_True, pInitialKey );
236 			//! set cursor to end of text
237 		}
238 		bReturn = sal_True;
239 	}
240 	return bReturn;
241 }
242 
243 sal_Bool __EXPORT FuDraw::KeyInput(const KeyEvent& rKEvt)
244 {
245 	sal_Bool bReturn = sal_False;
246     ScViewData& rViewData = *pViewShell->GetViewData();
247 
248 	switch ( rKEvt.GetKeyCode().GetCode() )
249 	{
250 		case KEY_ESCAPE:
251 
252 	/* 18.12.95: TextShell beibehalten nicht mehr gewuenscht...
253 	 *
254 	 *			if ( pView->IsAction() )
255 	 *			{
256 	 *				pView->BrkAction();
257 	 *				pWindow->ReleaseMouse();
258 	 *				bReturn = sal_True;
259 	 *			}
260 	 *			else if ( pView->IsTextEdit() )
261 	 *			{
262 	 *				pView->EndTextEdit();
263 	 *				pView->SetCreateMode();
264 	 *				pViewShell->GetScDrawView()->InvalidateDrawTextAttrs();
265 	 *				bReturn = sal_True;
266 	 *			}
267 	 *			else
268 	 */
269 
270 			if ( pViewShell->IsDrawTextShell() || aSfxRequest.GetSlot() == SID_DRAW_NOTEEDIT )
271 			{
272 				// in normale Draw-Shell, wenn Objekt selektiert, sonst Zeichnen aus
273 				rViewData.GetDispatcher().Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
274 				bReturn = sal_True;
275 			}
276 			else if ( pViewShell->IsDrawSelMode() )
277 			{
278 				pView->UnmarkAll();
279 				rViewData.GetDispatcher().Execute(SID_OBJECT_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
280 				bReturn = sal_True;
281 			}
282 			else if ( pView->AreObjectsMarked() )
283 			{
284 				// #97016# III
285 				SdrHdlList& rHdlList = const_cast< SdrHdlList& >( pView->GetHdlList() );
286                 if( rHdlList.GetFocusHdl() )
287 					rHdlList.ResetFocusHdl();
288 				else
289 					pView->UnmarkAll();
290 
291 				//	Beim Bezier-Editieren ist jetzt wieder das Objekt selektiert
292 				if (!pView->AreObjectsMarked())
293 					pViewShell->SetDrawShell( sal_False );
294 
295 				bReturn = sal_True;
296 			}
297 			break;
298 
299         case KEY_DELETE:					//! ueber Accelerator
300             pView->DeleteMarked();
301             bReturn = sal_True;
302         break;
303 
304 		case KEY_RETURN:
305 		{
306 			if( rKEvt.GetKeyCode().GetModifier() == 0 )
307 			{
308 	            // #98256# activate OLE object on RETURN for selected object
309 				// #98198# put selected text object in edit mode
310 				const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
311 				if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
312 				{
313                     sal_Bool bOle = pViewShell->GetViewFrame()->GetFrame().IsInPlace();
314 	                SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
315 	    			if( pObj && pObj->ISA( SdrOle2Obj ) && !bOle )
316 			        {
317 	                    //HMHpView->HideMarkHdl();
318 	                    pViewShell->ActivateObject( static_cast< SdrOle2Obj* >( pObj ), 0 );
319 
320 						// consumed
321 						bReturn = sal_True;
322 			        }
323 					else if ( lcl_KeyEditMode( pObj, pViewShell, NULL ) )		// start text edit for suitable object
324 						bReturn = sal_True;
325 				}
326 			}
327 		}
328 		break;
329 
330 		case KEY_F2:
331 		{
332 			if( rKEvt.GetKeyCode().GetModifier() == 0 )
333 			{
334 				// #98198# put selected text object in edit mode
335 				// (this is not SID_SETINPUTMODE, but F2 hardcoded, like in Writer)
336 				const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
337 				if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
338 				{
339 	                SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
340 					if ( lcl_KeyEditMode( pObj, pViewShell, NULL ) )			// start text edit for suitable object
341 						bReturn = sal_True;
342 				}
343 			}
344 		}
345 		break;
346 
347 		// #97016#
348 		case KEY_TAB:
349 		{
350 			// in calc do NOT start draw object selection using TAB/SHIFT-TAB when
351 			// there is not yet a object selected
352 			if(pView->AreObjectsMarked())
353 			{
354 				KeyCode aCode = rKEvt.GetKeyCode();
355 
356 				if ( !aCode.IsMod1() && !aCode.IsMod2() )
357 				{
358 					// changeover to the next object
359 					if(!pView->MarkNextObj( !aCode.IsShift() ))
360 					{
361 						// #97016# No next object: go over open end and
362 						// get first from the other side
363 						pView->UnmarkAllObj();
364 						pView->MarkNextObj(!aCode.IsShift());
365 					}
366 
367 					// #97016# II
368 					if(pView->AreObjectsMarked())
369 						pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
370 
371 					bReturn = sal_True;
372 				}
373 
374 				// #98994# handle Mod1 and Mod2 to get travelling running on different systems
375 				if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
376 				{
377 					// #97016# II do something with a selected handle?
378 					const SdrHdlList& rHdlList = pView->GetHdlList();
379 					sal_Bool bForward(!rKEvt.GetKeyCode().IsShift());
380 
381 					((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);
382 
383 					// guarantee visibility of focused handle
384 					SdrHdl* pHdl = rHdlList.GetFocusHdl();
385 
386 					if(pHdl)
387 					{
388 						Point aHdlPosition(pHdl->GetPos());
389 						Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
390 						pView->MakeVisible(aVisRect, *pWindow);
391 					}
392 
393 					// consumed
394 					bReturn = sal_True;
395 				}
396 			}
397 		}
398 		break;
399 
400 		// #97016#
401 		case KEY_END:
402 		{
403 			// in calc do NOT select the last draw object when
404 			// there is not yet a object selected
405 			if(pView->AreObjectsMarked())
406 			{
407 				KeyCode aCode = rKEvt.GetKeyCode();
408 
409 				if ( aCode.IsMod1() )
410 				{
411 					// #97016# mark last object
412 					pView->UnmarkAllObj();
413 					pView->MarkNextObj(sal_False);
414 
415 					// #97016# II
416 					if(pView->AreObjectsMarked())
417 						pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
418 
419 					bReturn = sal_True;
420 				}
421 			}
422 		}
423 		break;
424 
425 		// #97016#
426 		case KEY_HOME:
427 		{
428 			// in calc do NOT select the first draw object when
429 			// there is not yet a object selected
430 			if(pView->AreObjectsMarked())
431 			{
432 				KeyCode aCode = rKEvt.GetKeyCode();
433 
434 				if ( aCode.IsMod1() )
435 				{
436 					// #97016# mark first object
437 					pView->UnmarkAllObj();
438 					pView->MarkNextObj(sal_True);
439 
440 					// #97016# II
441 					if(pView->AreObjectsMarked())
442 						pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
443 
444 					bReturn = sal_True;
445 				}
446 			}
447 		}
448 		break;
449 
450 		// #97016#
451 		case KEY_UP:
452 		case KEY_DOWN:
453 		case KEY_LEFT:
454 		case KEY_RIGHT:
455 		{
456 			// in calc do cursor travelling of draw objects only when
457 			// there is a object selected yet
458 			if(pView->AreObjectsMarked())
459 			{
460 
461 				const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
462 				if(rMarkList.GetMarkCount() == 1)
463 				{
464                     // disable cursor travelling on note objects as the tail connector position
465                     // must not move.
466 				    SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
467                     if( ScDrawLayer::IsNoteCaption( pObj ) )
468                         break;
469 				}
470 
471 				long nX = 0;
472 				long nY = 0;
473 				sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
474 
475 				if (nCode == KEY_UP)
476 				{
477 					// Scroll nach oben
478 					nX = 0;
479 					nY =-1;
480 				}
481 				else if (nCode == KEY_DOWN)
482 				{
483 					// Scroll nach unten
484 					nX = 0;
485 					nY = 1;
486 				}
487 				else if (nCode == KEY_LEFT)
488 				{
489 					// Scroll nach links
490 					nX =-1;
491 					nY = 0;
492 				}
493 				else if (nCode == KEY_RIGHT)
494 				{
495 					// Scroll nach rechts
496 					nX = 1;
497 					nY = 0;
498 				}
499 
500 				sal_Bool bReadOnly = rViewData.GetDocShell()->IsReadOnly();
501 
502 				if(!rKEvt.GetKeyCode().IsMod1() && !bReadOnly)
503 				{
504 					if(rKEvt.GetKeyCode().IsMod2())
505 					{
506 						// #97016# move in 1 pixel distance
507 						Size aLogicSizeOnePixel = (pWindow) ? pWindow->PixelToLogic(Size(1,1)) : Size(100, 100);
508 						nX *= aLogicSizeOnePixel.Width();
509 						nY *= aLogicSizeOnePixel.Height();
510 					}
511 					else
512 					{
513 						// old, fixed move distance
514 						nX *= 100;
515 						nY *= 100;
516 					}
517 
518 					// is there a movement to do?
519 					if(0 != nX || 0 != nY)
520 					{
521 						// #97016# II
522 						const SdrHdlList& rHdlList = pView->GetHdlList();
523 						SdrHdl* pHdl = rHdlList.GetFocusHdl();
524 
525 						if(0L == pHdl)
526 						{
527 							// #107086# only take action when move is allowed
528 							if(pView->IsMoveAllowed())
529 							{
530 								// #90129# restrict movement to WorkArea
531 								const Rectangle& rWorkArea = pView->GetWorkArea();
532 
533 								if(!rWorkArea.IsEmpty())
534 								{
535 									Rectangle aMarkRect(pView->GetMarkedObjRect());
536 									aMarkRect.Move(nX, nY);
537 
538 									if(!aMarkRect.IsInside(rWorkArea))
539 									{
540 										if(aMarkRect.Left() < rWorkArea.Left())
541 										{
542 											nX += rWorkArea.Left() - aMarkRect.Left();
543 										}
544 
545 										if(aMarkRect.Right() > rWorkArea.Right())
546 										{
547 											nX -= aMarkRect.Right() - rWorkArea.Right();
548 										}
549 
550 										if(aMarkRect.Top() < rWorkArea.Top())
551 										{
552 											nY += rWorkArea.Top() - aMarkRect.Top();
553 										}
554 
555 										if(aMarkRect.Bottom() > rWorkArea.Bottom())
556 										{
557 											nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
558 										}
559 									}
560 								}
561 
562 								// now move the selected draw objects
563 								pView->MoveAllMarked(Size(nX, nY));
564 
565 								// #97016# II
566 								pView->MakeVisible(pView->GetAllMarkedRect(), *pWindow);
567 
568 								bReturn = sal_True;
569 							}
570 						}
571 						else
572 						{
573 							// move handle with index nHandleIndex
574 							if(pHdl && (nX || nY))
575 							{
576 								// now move the Handle (nX, nY)
577 								Point aStartPoint(pHdl->GetPos());
578 								Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
579 								const SdrDragStat& rDragStat = pView->GetDragStat();
580 
581 								// start dragging
582 								pView->BegDragObj(aStartPoint, 0, pHdl, 0);
583 
584 								if(pView->IsDragObj())
585 								{
586 									FASTBOOL bWasNoSnap = rDragStat.IsNoSnap();
587 									sal_Bool bWasSnapEnabled = pView->IsSnapEnabled();
588 
589 									// switch snapping off
590 									if(!bWasNoSnap)
591 										((SdrDragStat&)rDragStat).SetNoSnap(sal_True);
592 									if(bWasSnapEnabled)
593 										pView->SetSnapEnabled(sal_False);
594 
595 									pView->MovAction(aEndPoint);
596 									pView->EndDragObj();
597 
598 									// restore snap
599 									if(!bWasNoSnap)
600 										((SdrDragStat&)rDragStat).SetNoSnap(bWasNoSnap);
601 									if(bWasSnapEnabled)
602 										pView->SetSnapEnabled(bWasSnapEnabled);
603 								}
604 
605 								// make moved handle visible
606 								Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
607 								pView->MakeVisible(aVisRect, *pWindow);
608 
609 								bReturn = sal_True;
610 							}
611 						}
612 					}
613 				}
614 			}
615 		}
616 		break;
617 
618 		// #97016#
619 		case KEY_SPACE:
620 		{
621 			// in calc do only something when draw objects are selected
622 			if(pView->AreObjectsMarked())
623 			{
624 				const SdrHdlList& rHdlList = pView->GetHdlList();
625 				SdrHdl* pHdl = rHdlList.GetFocusHdl();
626 
627 				if(pHdl)
628 				{
629 					if(pHdl->GetKind() == HDL_POLY)
630 					{
631 						// rescue ID of point with focus
632 						sal_uInt32 nPol(pHdl->GetPolyNum());
633 						sal_uInt32 nPnt(pHdl->GetPointNum());
634 
635 						if(pView->IsPointMarked(*pHdl))
636 						{
637 							if(rKEvt.GetKeyCode().IsShift())
638 							{
639 								pView->UnmarkPoint(*pHdl);
640 							}
641 						}
642 						else
643 						{
644 							if(!rKEvt.GetKeyCode().IsShift())
645 							{
646 								pView->UnmarkAllPoints();
647 							}
648 
649 							pView->MarkPoint(*pHdl);
650 						}
651 
652 						if(0L == rHdlList.GetFocusHdl())
653 						{
654 							// restore point with focus
655 							SdrHdl* pNewOne = 0L;
656 
657 							for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++)
658 							{
659 								SdrHdl* pAct = rHdlList.GetHdl(a);
660 
661 								if(pAct
662 									&& pAct->GetKind() == HDL_POLY
663 									&& pAct->GetPolyNum() == nPol
664 									&& pAct->GetPointNum() == nPnt)
665 								{
666 									pNewOne = pAct;
667 								}
668 							}
669 
670 							if(pNewOne)
671 							{
672 								((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
673 							}
674 						}
675 
676 						bReturn = sal_True;
677 					}
678 				}
679 			}
680 		}
681 		break;
682 	}
683 
684 	if (!bReturn)
685 	{
686 		bReturn = FuPoor::KeyInput(rKEvt);
687 	}
688 
689 	if (!bReturn)
690 	{
691 		// #98198# allow direct typing into a selected text object
692 
693 		const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
694 		if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() && EditEngine::IsSimpleCharInput(rKEvt) )
695 		{
696             SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
697 
698 			// start text edit for suitable object, pass key event to OutlinerView
699 			if ( lcl_KeyEditMode( pObj, pViewShell, &rKEvt ) )
700 				bReturn = sal_True;
701 		}
702 	}
703 
704 	return (bReturn);
705 }
706 
707 // #97016# II
708 void FuDraw::SelectionHasChanged()
709 {
710 	const SdrHdlList& rHdlList = pView->GetHdlList();
711 	((SdrHdlList&)rHdlList).ResetFocusHdl();
712 }
713 
714 /*************************************************************************
715 |*
716 |* Vor dem Scrollen Selektionsdarstellung ausblenden
717 |*
718 \************************************************************************/
719 
720 void FuDraw::ScrollStart()
721 {
722 //		HideShownXor in Gridwin
723 }
724 
725 /*************************************************************************
726 |*
727 |* Nach dem Scrollen Selektionsdarstellung wieder anzeigen
728 |*
729 \************************************************************************/
730 
731 void FuDraw::ScrollEnd()
732 {
733 //		ShowShownXor in Gridwin
734 }
735 
736 /*************************************************************************
737 |*
738 |* Function aktivieren
739 |*
740 \************************************************************************/
741 
742 void FuDraw::Activate()
743 {
744 	FuPoor::Activate();
745 }
746 
747 /*************************************************************************
748 |*
749 |* Function deaktivieren
750 |*
751 \************************************************************************/
752 
753 void FuDraw::Deactivate()
754 {
755 	FuPoor::Deactivate();
756 }
757 
758 /*************************************************************************
759 |*
760 |* Maus-Pointer umschalten
761 |*
762 \************************************************************************/
763 
764 sal_Bool lcl_UrlHit( SdrView* pView, const Point& rPosPixel, Window* pWindow )
765 {
766 	SdrViewEvent aVEvt;
767 	MouseEvent aMEvt( rPosPixel, 1, 0, MOUSE_LEFT );
768 	SdrHitKind eHit = pView->PickAnything( aMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
769 
770 	if ( eHit != SDRHIT_NONE && aVEvt.pObj != NULL )
771 	{
772 		if ( ScDrawLayer::GetIMapInfo( aVEvt.pObj ) && ScDrawLayer::GetHitIMapObject(
773 								aVEvt.pObj, pWindow->PixelToLogic(rPosPixel), *pWindow ) )
774 			return sal_True;
775 
776 		if ( aVEvt.eEvent == SDREVENT_EXECUTEURL )
777 			return sal_True;
778 	}
779 
780 	return sal_False;
781 }
782 
783 void FuDraw::ForcePointer(const MouseEvent* pMEvt)
784 {
785 	if ( !pView->IsAction() )
786 	{
787 		Point aPosPixel = pWindow->GetPointerPosPixel();
788 		sal_Bool bAlt		= pMEvt && pMEvt->IsMod2();
789 		Point aPnt		= pWindow->PixelToLogic( aPosPixel );
790 		SdrHdl* pHdl	= pView->PickHandle(aPnt);
791 		SdrObject* pObj;
792 		SdrPageView* pPV;
793 
794         ScMacroInfo* pInfo = 0;
795         if ( pView->PickObj(aPnt, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
796         {
797             if ( pObj->IsGroupObject() )
798             {
799                 SdrObject* pHit = 0;
800                 if ( pView->PickObj(aMDPos, pView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
801                     pObj = pHit;
802             }
803             pInfo = ScDrawLayer::GetMacroInfo( pObj );
804         }
805 
806 		if ( pView->IsTextEdit() )
807 		{
808 			pViewShell->SetActivePointer(Pointer(POINTER_TEXT));		// kann nicht sein ?
809 		}
810 		else if ( pHdl )
811 		{
812 			pViewShell->SetActivePointer(
813 				pView->GetPreferedPointer( aPnt, pWindow ) );
814 		}
815 		else if ( pView->IsMarkedHit(aPnt) )
816 		{
817 			pViewShell->SetActivePointer( Pointer(POINTER_MOVE) );
818 		}
819 		else if ( !bAlt && ( !pMEvt || !pMEvt->GetButtons() )
820 						&& lcl_UrlHit( pView, aPosPixel, pWindow ) )
821 		{
822 			//	kann mit ALT unterdrueckt werden
823 			pWindow->SetPointer( Pointer( POINTER_REFHAND ) );			// Text-URL / ImageMap
824 		}
825 		else if ( !bAlt && pView->PickObj(aPnt, pView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMACRO) )
826 		{
827 			//	kann mit ALT unterdrueckt werden
828 			SdrObjMacroHitRec aHitRec;	//! muss da noch irgendwas gesetzt werden ????
829 			pViewShell->SetActivePointer( pObj->GetMacroPointer(aHitRec) );
830 		}
831 #ifdef ISSUE66550_HLINK_FOR_SHAPES
832         else if ( !bAlt && pInfo && ((pInfo->GetMacro().getLength() > 0) || (pInfo->GetHlink().getLength() > 0)) )
833 #else
834         else if ( !bAlt && pInfo && (pInfo->GetMacro().getLength() > 0) )
835 #endif
836 			pWindow->SetPointer( Pointer( POINTER_REFHAND ) );
837 		else if ( IsDetectiveHit( aPnt ) )
838 			pViewShell->SetActivePointer( Pointer( POINTER_DETECTIVE ) );
839 		else
840 			pViewShell->SetActivePointer( aNewPointer );			//! in Gridwin?
841 	}
842 }
843 
844 sal_Bool FuDraw::IsSizingOrMovingNote( const MouseEvent& rMEvt ) const
845 {
846     sal_Bool bIsSizingOrMoving = sal_False;
847     if ( rMEvt.IsLeft() )
848     {
849         const SdrMarkList& rNoteMarkList = pView->GetMarkedObjectList();
850         if(rNoteMarkList.GetMarkCount() == 1)
851         {
852             SdrObject* pObj = rNoteMarkList.GetMark( 0 )->GetMarkedSdrObj();
853             if ( ScDrawLayer::IsNoteCaption( pObj ) )
854             {
855                 Point aMPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
856                 bIsSizingOrMoving =
857                     pView->PickHandle( aMPos ) ||      // handles to resize the note
858                     pView->IsTextEditFrameHit( aMPos );         // frame for moving the note
859             }
860         }
861     }
862     return bIsSizingOrMoving;
863 }
864