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