xref: /trunk/main/sc/source/ui/drawfunc/fudraw.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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