xref: /trunk/main/sd/source/ui/func/fupoor.cxx (revision a5b190bfa3e1bed4623e2958a8877664a3b5506c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 
31 
32 #include "fupoor.hxx"
33 
34 #include <svx/svxids.hrc>
35 #include <svl/aeitem.hxx>
36 #include <svx/svdpagv.hxx>
37 #include <svx/svdoole2.hxx>
38 #include <svx/svdograf.hxx>
39 #include <vcl/seleng.hxx>
40 #include <sfx2/app.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/request.hxx>
44 #include <vcl/dialog.hxx>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/drawing/XLayer.hpp>
47 #include <com/sun/star/drawing/XLayerManager.hpp>
48 #include <com/sun/star/container/XChild.hpp>
49 
50 #ifndef SD_FRAMW_VIEW_HXX
51 #include "FrameView.hxx"
52 #endif
53 #include "app.hrc"
54 #include "fusel.hxx"
55 #include "sdpage.hxx"
56 #include "drawview.hxx"
57 #include "DrawViewShell.hxx"
58 #ifndef SD_WINDOW_SHELL_HXX
59 #include "Window.hxx"
60 #endif
61 #include "drawdoc.hxx"
62 #include "DrawDocShell.hxx"
63 #include "zoomlist.hxx"
64 #include "Client.hxx"
65 #include "slideshow.hxx"
66 #include "LayerTabBar.hxx"
67 
68 #include <sfx2/viewfrm.hxx>
69 
70 // #97016# IV
71 #include <svx/svditer.hxx>
72 
73 // #98533#
74 #include <editeng/editeng.hxx>
75 
76 using namespace ::com::sun::star;
77 using ::com::sun::star::uno::Reference;
78 
79 namespace sd {
80 
81 TYPEINIT0( FuPoor );
82 
83 /*************************************************************************
84 |*
85 |* Konstruktor
86 |*
87 \************************************************************************/
88 
89 FuPoor::FuPoor (
90     ViewShell* pViewSh,
91     ::sd::Window* pWin,
92     ::sd::View* pView,
93     SdDrawDocument* pDrDoc,
94     SfxRequest& rReq)
95     : mpView(pView),
96       mpViewShell(pViewSh),
97       mpWindow(pWin),
98       mpDocSh( pDrDoc->GetDocSh() ),
99       mpDoc(pDrDoc),
100       nSlotId( rReq.GetSlot() ),
101       nSlotValue(0),
102       pDialog(NULL),
103       bIsInDragMode(sal_False),
104       bNoScrollUntilInside (sal_True),
105       bScrollable (sal_False),
106       bDelayActive (sal_False),
107       bFirstMouseMove (sal_False),
108       // #95491# remember MouseButton state
109       mnCode(0)
110 {
111     ReceiveRequest(rReq);
112 
113     aScrollTimer.SetTimeoutHdl( LINK(this, FuPoor, ScrollHdl) );
114     aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL);
115 
116     aDragTimer.SetTimeoutHdl( LINK(this, FuPoor, DragHdl) );
117     aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT);
118 
119     aDelayToScrollTimer.SetTimeoutHdl( LINK(this, FuPoor, DelayHdl) );
120     aDelayToScrollTimer.SetTimeout(2000);
121 }
122 
123 /*************************************************************************
124 |*
125 |* Destruktor
126 |*
127 \************************************************************************/
128 
129 FuPoor::~FuPoor()
130 {
131     aDragTimer.Stop();
132     aScrollTimer.Stop();
133     aDelayToScrollTimer.Stop ();
134 
135     if (pDialog)
136         delete pDialog;
137 }
138 
139 /*************************************************************************
140 |*
141 |* Function aktivieren
142 |*
143 \************************************************************************/
144 
145 void FuPoor::Activate()
146 {
147     if (pDialog)
148     {
149         pDialog->Show();
150     }
151 }
152 
153 /*************************************************************************
154 |*
155 |* Function deaktivieren
156 |*
157 \************************************************************************/
158 
159 void FuPoor::Deactivate()
160 {
161     aDragTimer.Stop();
162     aScrollTimer.Stop();
163     aDelayToScrollTimer.Stop ();
164         bScrollable  =
165         bDelayActive = sal_False;
166 
167     if (pDialog)
168     {
169         pDialog->Hide();
170     }
171 
172     if (mpWindow) mpWindow->ReleaseMouse ();
173 }
174 
175 /*************************************************************************
176 |*
177 |* Scrollen bei Erreichen des Fensterrandes; wird von
178 |* MouseMove aufgerufen
179 |*
180 \************************************************************************/
181 
182 void FuPoor::ForceScroll(const Point& aPixPos)
183 {
184     aScrollTimer.Stop();
185 
186     if ( !mpView->IsDragHelpLine() && !mpView->IsSetPageOrg() &&
187             !SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) )
188     {
189 /*      Size aSize = mpWindow->GetSizePixel();
190         short dx = 0, dy = 0;
191 
192         if ( aPixPos.X() <= 0              ) dx = -1;
193         if ( aPixPos.X() >= aSize.Width()  ) dx =  1;
194         if ( aPixPos.Y() <= 0              ) dy = -1;
195         if ( aPixPos.Y() >= aSize.Height() ) dy =  1;
196 */
197         Point aPos = mpWindow->OutputToScreenPixel(aPixPos);
198         const Rectangle& rRect = mpViewShell->GetAllWindowRect();
199 
200         if ( bNoScrollUntilInside )
201         {
202             if ( rRect.IsInside(aPos) )
203                 bNoScrollUntilInside = sal_False;
204         }
205         else
206         {
207             short dx = 0, dy = 0;
208 
209             if ( aPos.X() <= rRect.Left()   ) dx = -1;
210             if ( aPos.X() >= rRect.Right()  ) dx =  1;
211             if ( aPos.Y() <= rRect.Top()    ) dy = -1;
212             if ( aPos.Y() >= rRect.Bottom() ) dy =  1;
213 
214             if ( dx != 0 || dy != 0 )
215             {
216                 if (bScrollable)
217                 {
218                     // Scrollaktion in abgeleiteter Klasse
219                     ScrollStart();
220                     mpViewShell->ScrollLines(dx, dy);
221                     ScrollEnd();
222                     aScrollTimer.Start();
223                 }
224                 else if (! bDelayActive) StartDelayToScrollTimer ();
225             }
226         }
227     }
228 }
229 
230 /*************************************************************************
231 |*
232 |* Timer-Handler fuer Fensterscrolling
233 |*
234 \************************************************************************/
235 
236 IMPL_LINK_INLINE_START( FuPoor, ScrollHdl, Timer *, EMPTYARG )
237 {
238     Point aPnt(mpWindow->GetPointerPosPixel());
239 
240     // #95491# use remembered MouseButton state to create correct
241     // MouseEvents for this artifical MouseMove.
242     MouseMove(MouseEvent(aPnt, 1, 0, GetMouseButtonCode()));
243 
244     return 0;
245 }
246 IMPL_LINK_INLINE_END( FuPoor, ScrollHdl, Timer *, pTimer )
247 
248 /*************************************************************************
249 |*
250 |* Tastaturereignisse bearbeiten
251 |*
252 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
253 |* sal_False.
254 |*
255 \************************************************************************/
256 
257 sal_Bool FuPoor::KeyInput(const KeyEvent& rKEvt)
258 {
259     sal_uInt16          nCode = rKEvt.GetKeyCode().GetCode();
260     sal_Bool            bReturn = sal_False;
261     sal_Bool            bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() );
262 
263     switch (nCode)
264     {
265         // #97016# IV
266         case KEY_RETURN:
267         {
268             if(rKEvt.GetKeyCode().IsMod1())
269             {
270                 if(mpViewShell && mpViewShell->ISA(DrawViewShell))
271                 {
272                     DrawViewShell* pDrawViewShell =
273                         static_cast<DrawViewShell*>(mpViewShell);
274                     SdPage* pActualPage = pDrawViewShell->GetActualPage();
275                     SdrTextObj* pCandidate = 0L;
276 
277                     if(pActualPage)
278                     {
279                         SdrObjListIter aIter(*pActualPage, IM_DEEPNOGROUPS);
280 
281                         while(aIter.IsMore() && !pCandidate)
282                         {
283                             SdrObject* pObj = aIter.Next();
284 
285                             if(pObj && pObj->ISA(SdrTextObj))
286                             {
287                                 sal_uInt32 nInv(pObj->GetObjInventor());
288                                 sal_uInt16 nKnd(pObj->GetObjIdentifier());
289 
290                                 if(SdrInventor == nInv &&
291                                     (OBJ_TITLETEXT == nKnd || OBJ_OUTLINETEXT == nKnd || OBJ_TEXT == nKnd))
292                                 {
293                                     pCandidate = (SdrTextObj*)pObj;
294                                 }
295                             }
296                         }
297                     }
298 
299                     if(pCandidate)
300                     {
301                         mpView->UnMarkAll();
302                         mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
303 
304                         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
305                             SID_ATTR_CHAR, SFX_CALLMODE_ASYNCHRON);
306                     }
307                     else
308                     {
309                         // insert a new page with the same page layout
310                         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
311                             SID_INSERTPAGE_QUICK, SFX_CALLMODE_ASYNCHRON);
312                     }
313 
314                     // consumed
315                     bReturn = sal_True;
316                 }
317             }
318             else
319             {
320                 // #98255# activate OLE object on RETURN for selected object
321                 // #98198# activate text edit on RETURN for selected object
322                 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
323 
324                 if( !mpView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
325                 {
326                     SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
327 
328                     if( pObj && pObj->ISA( SdrOle2Obj ) && !mpDocSh->IsUIActive() )
329                     {
330                         //HMHmpView->HideMarkHdl();
331                         mpViewShell->ActivateObject( static_cast< SdrOle2Obj* >( pObj ), 0 );
332                     }
333                     else if( pObj && pObj->IsEmptyPresObj() && pObj->ISA( SdrGrafObj ) )
334                     {
335                         mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_INSERT_GRAPHIC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
336                     }
337                     else
338                     {
339                         mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_ATTR_CHAR, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
340                     }
341 
342                     // consumed
343                     bReturn = sal_True;
344                 }
345             }
346         }
347         break;
348 
349         // #97016# II
350         case KEY_TAB:
351         {
352             // #98994# handle Mod1 and Mod2 to get travelling running on different systems
353             if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
354             {
355                 // #97016# II do something with a selected handle?
356                 const SdrHdlList& rHdlList = mpView->GetHdlList();
357                 sal_Bool bForward(!rKEvt.GetKeyCode().IsShift());
358 
359                 ((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);
360 
361                 // guarantee visibility of focused handle
362                 SdrHdl* pHdl = rHdlList.GetFocusHdl();
363 
364                 if(pHdl)
365                 {
366                     Point aHdlPosition(pHdl->GetPos());
367                     Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
368                     mpView->MakeVisible(aVisRect, *mpWindow);
369                 }
370 
371                 // consumed
372                 bReturn = sal_True;
373             }
374         }
375         break;
376 
377         case KEY_ESCAPE:
378         {
379             bReturn = FuPoor::cancel();
380         }
381         break;
382 
383         case KEY_ADD:
384         {
385             if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
386             {
387                 // Zoom vergroessern
388                 mpViewShell->SetZoom(mpWindow->GetZoom() * 3 / 2);
389 
390                 if (mpViewShell->ISA(DrawViewShell))
391                     static_cast<DrawViewShell*>(mpViewShell)
392                         ->SetZoomOnPage(sal_False);
393 
394                 bReturn = sal_True;
395             }
396         }
397         break;
398 
399         case KEY_SUBTRACT:
400         {
401             if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
402             {
403                 // Zoom verringern
404                 mpViewShell->SetZoom(mpWindow->GetZoom() * 2 / 3);
405 
406                 if (mpViewShell->ISA(DrawViewShell))
407                     static_cast<DrawViewShell*>(mpViewShell)
408                         ->SetZoomOnPage(sal_False);
409 
410                 bReturn = sal_True;
411             }
412         }
413         break;
414 
415         case KEY_MULTIPLY:
416         {
417             if (!mpView->IsTextEdit() && !bSlideShow)
418             {
419                 // Zoom auf Seite
420                 mpViewShell->GetViewFrame()->GetDispatcher()->
421                 Execute(SID_SIZE_PAGE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
422                 bReturn = sal_True;
423             }
424         }
425         break;
426 
427         case KEY_DIVIDE:
428         {
429             if (!mpView->IsTextEdit() && !bSlideShow)
430             {
431                 // Zoom auf selektierte Objekte
432                 mpViewShell->GetViewFrame()->GetDispatcher()->
433                 Execute(SID_SIZE_OPTIMAL, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
434                 bReturn = sal_True;
435             }
436         }
437         break;
438 
439         case KEY_POINT:
440         {
441             ZoomList* pZoomList = mpViewShell->GetZoomList();
442 
443             if (!mpView->IsTextEdit() && pZoomList->IsNextPossible() && !bSlideShow && !mpDocSh->IsUIActive())
444             {
445                 // Naechstes ZoomRect einstellen
446                 mpViewShell->SetZoomRect(pZoomList->GetNextZoomRect());
447                 bReturn = sal_True;
448             }
449         }
450         break;
451 
452         case KEY_COMMA:
453         {
454             ZoomList* pZoomList = mpViewShell->GetZoomList();
455 
456             if (!mpView->IsTextEdit() && pZoomList->IsPreviousPossible() && !bSlideShow && !mpDocSh->IsUIActive())
457             {
458                 // Vorheriges ZoomRect einstellen
459                 mpViewShell->SetZoomRect(pZoomList->GetPreviousZoomRect());
460                 bReturn = sal_True;
461             }
462         }
463         break;
464 
465         case KEY_HOME:
466         {
467             if (!mpView->IsTextEdit()
468                 && mpViewShell->ISA(DrawViewShell)
469                 && !bSlideShow)
470             {
471                // Sprung zu erster Seite
472                static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(0);
473                bReturn = sal_True;
474             }
475         }
476         break;
477 
478         case KEY_END:
479         {
480             if (!mpView->IsTextEdit()
481                 && mpViewShell->ISA(DrawViewShell)
482                 && !bSlideShow)
483             {
484                 // Sprung zu letzter Seite
485                 SdPage* pPage =
486                     static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
487                 static_cast<DrawViewShell*>(mpViewShell)
488                     ->SwitchPage(mpDoc->GetSdPageCount(
489                         pPage->GetPageKind()) - 1);
490                 bReturn = sal_True;
491             }
492         }
493         break;
494 
495         case KEY_PAGEUP:
496         {
497             if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
498                 break;
499 
500             if(mpViewShell->ISA(DrawViewShell) && !bSlideShow)
501             {
502                 // The page-up key switches layers or pages depending on the
503                 // modifier key.
504                 if ( ! rKEvt.GetKeyCode().GetAllModifier())
505                 {
506                     // With no modifier pressed we move to the previous
507                     // slide.
508                     mpView->SdrEndTextEdit();
509 
510                     // Previous page.
511                     bReturn = sal_True;
512                     SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
513                     sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
514 
515                     if (nSdPage > 0)
516                     {
517                         // Switch the page and send events regarding
518                         // deactivation the old page and activating the new
519                         // one.
520                         TabControl* pPageTabControl =
521                             static_cast<DrawViewShell*>(mpViewShell)
522                             ->GetPageTabControl();
523                         if (pPageTabControl->IsReallyShown())
524                             pPageTabControl->SendDeactivatePageEvent ();
525                         static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage - 1);
526                         if (pPageTabControl->IsReallyShown())
527                             pPageTabControl->SendActivatePageEvent ();
528                     }
529                 }
530                 else if (rKEvt.GetKeyCode().IsMod1())
531                 {
532                     // With the CONTROL modifier we switch layers.
533                     if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive())
534                     {
535                         // Moves to the previous layer.
536                         SwitchLayer (-1);
537                     }
538                 }
539             }
540         }
541         break;
542 
543         case KEY_PAGEDOWN:
544         {
545             if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
546                 break;
547             if(mpViewShell->ISA(DrawViewShell) && !bSlideShow)
548             {
549                 // The page-down key switches layers or pages depending on the
550                 // modifier key.
551                 if ( ! rKEvt.GetKeyCode().GetAllModifier())
552                 {
553                     // With no modifier pressed we move to the next slide.
554                     mpView->SdrEndTextEdit();
555 
556                     // Next page.
557                     bReturn = sal_True;
558                     SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
559                     sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
560 
561                     if (nSdPage < mpDoc->GetSdPageCount(pPage->GetPageKind()) - 1)
562                     {
563                         // Switch the page and send events regarding
564                         // deactivation the old page and activating the new
565                         // one.
566                         TabControl* pPageTabControl =
567                             static_cast<DrawViewShell*>(mpViewShell)->GetPageTabControl();
568                         if (pPageTabControl->IsReallyShown())
569                             pPageTabControl->SendDeactivatePageEvent ();
570                         static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage + 1);
571                         if (pPageTabControl->IsReallyShown())
572                             pPageTabControl->SendActivatePageEvent ();
573                     }
574                 }
575                 else if (rKEvt.GetKeyCode().IsMod1())
576                 {
577                     // With the CONTROL modifier we switch layers.
578                     if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive())
579                     {
580                         // With the layer mode active pressing page-down
581                         // moves to the next layer.
582                         SwitchLayer (+1);
583                     }
584                 }
585             }
586         }
587         break;
588 
589         // #97016# II change select state when focus is on poly point
590         case KEY_SPACE:
591         {
592             const SdrHdlList& rHdlList = mpView->GetHdlList();
593             SdrHdl* pHdl = rHdlList.GetFocusHdl();
594 
595             if(pHdl)
596             {
597                 if(pHdl->GetKind() == HDL_POLY)
598                 {
599                     // rescue ID of point with focus
600                     sal_uInt32 nPol(pHdl->GetPolyNum());
601                     sal_uInt32 nPnt(pHdl->GetPointNum());
602 
603                     if(mpView->IsPointMarked(*pHdl))
604                     {
605                         if(rKEvt.GetKeyCode().IsShift())
606                         {
607                             mpView->UnmarkPoint(*pHdl);
608                         }
609                     }
610                     else
611                     {
612                         if(!rKEvt.GetKeyCode().IsShift())
613                         {
614                             mpView->UnmarkAllPoints();
615                         }
616 
617                         mpView->MarkPoint(*pHdl);
618                     }
619 
620                     if(0L == rHdlList.GetFocusHdl())
621                     {
622                         // restore point with focus
623                         SdrHdl* pNewOne = 0L;
624 
625                         for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++)
626                         {
627                             SdrHdl* pAct = rHdlList.GetHdl(a);
628 
629                             if(pAct
630                                 && pAct->GetKind() == HDL_POLY
631                                 && pAct->GetPolyNum() == nPol
632                                 && pAct->GetPointNum() == nPnt)
633                             {
634                                 pNewOne = pAct;
635                             }
636                         }
637 
638                         if(pNewOne)
639                         {
640                             ((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
641                         }
642                     }
643 
644                     bReturn = sal_True;
645                 }
646             }
647         }
648         break;
649 
650         case KEY_UP:
651         case KEY_DOWN:
652         case KEY_LEFT:
653         case KEY_RIGHT:
654         {
655             if (!mpView->IsTextEdit() && !bSlideShow)
656             {
657                 long nX = 0;
658                 long nY = 0;
659 
660                 if (nCode == KEY_UP)
661                 {
662                     // Scroll nach oben
663                     nX = 0;
664                     nY =-1;
665                 }
666                 else if (nCode == KEY_DOWN)
667                 {
668                     // Scroll nach unten
669                     nX = 0;
670                     nY = 1;
671                 }
672                 else if (nCode == KEY_LEFT)
673                 {
674                     // Scroll nach links
675                     nX =-1;
676                     nY = 0;
677                 }
678                 else if (nCode == KEY_RIGHT)
679                 {
680                     // Scroll nach rechts
681                     nX = 1;
682                     nY = 0;
683                 }
684 
685                 if (mpView->AreObjectsMarked() && !rKEvt.GetKeyCode().IsMod1() &&
686                     !mpDocSh->IsReadOnly())
687                 {
688                     // #97016# II
689                     const SdrHdlList& rHdlList = mpView->GetHdlList();
690                     SdrHdl* pHdl = rHdlList.GetFocusHdl();
691 
692                     // #109007#
693                     sal_Bool bIsMoveOfConnectedHandle(sal_False);
694                     sal_Bool bOldSuppress = false;
695                     SdrEdgeObj* pEdgeObj = 0L;
696 
697                     if(pHdl && pHdl->GetObj() && pHdl->GetObj()->ISA(SdrEdgeObj) && 0 == pHdl->GetPolyNum())
698                     {
699                         pEdgeObj = (SdrEdgeObj*)pHdl->GetObj();
700 
701                         if(0L == pHdl->GetPointNum())
702                         {
703                             if(pEdgeObj->GetConnection(sal_True).GetObject())
704                             {
705                                 bIsMoveOfConnectedHandle = sal_True;
706                             }
707                         }
708                         if(1L == pHdl->GetPointNum())
709                         {
710                             if(pEdgeObj->GetConnection(sal_False).GetObject())
711                             {
712                                 bIsMoveOfConnectedHandle = sal_True;
713                             }
714                         }
715                     }
716 
717                     // #109007#
718                     if(pEdgeObj)
719                     {
720                         // Suppress default connects to inside object and object center
721                         bOldSuppress = pEdgeObj->GetSuppressDefaultConnect();
722                         pEdgeObj->SetSuppressDefaultConnect(sal_True);
723                     }
724 
725                     // #109007#
726                     if(bIsMoveOfConnectedHandle)
727                     {
728                         sal_uInt16 nMarkHdSiz(mpView->GetMarkHdlSizePixel());
729                         Size aHalfConSiz(nMarkHdSiz + 1, nMarkHdSiz + 1);
730                         aHalfConSiz = mpWindow->PixelToLogic(aHalfConSiz);
731 
732                         if(100 < aHalfConSiz.Width())
733                             nX *= aHalfConSiz.Width();
734                         else
735                             nX *= 100;
736 
737                         if(100 < aHalfConSiz.Height())
738                             nY *= aHalfConSiz.Height();
739                         else
740                             nY *= 100;
741                     }
742                     else if(rKEvt.GetKeyCode().IsMod2())
743                     {
744                         // #97016# move in 1 pixel distance
745                         Size aLogicSizeOnePixel = (mpWindow) ? mpWindow->PixelToLogic(Size(1,1)) : Size(100, 100);
746                         nX *= aLogicSizeOnePixel.Width();
747                         nY *= aLogicSizeOnePixel.Height();
748                     }
749                     else if(rKEvt.GetKeyCode().IsShift())
750                     {
751                         nX *= 1000;
752                         nY *= 1000;
753                     }
754                     else
755                     {
756                         // old, fixed move distance
757                         nX *= 100;
758                         nY *= 100;
759                     }
760 
761                     if(0L == pHdl)
762                     {
763                         // #67368# only take action when move is allowed
764                         if(mpView->IsMoveAllowed())
765                         {
766                             // #90129# restrict movement to WorkArea
767                             const Rectangle& rWorkArea = mpView->GetWorkArea();
768 
769                             if(!rWorkArea.IsEmpty())
770                             {
771                                 Rectangle aMarkRect(mpView->GetMarkedObjRect());
772                                 aMarkRect.Move(nX, nY);
773 
774                                 if(!aMarkRect.IsInside(rWorkArea))
775                                 {
776                                     if(aMarkRect.Left() < rWorkArea.Left())
777                                     {
778                                         nX += rWorkArea.Left() - aMarkRect.Left();
779                                     }
780 
781                                     if(aMarkRect.Right() > rWorkArea.Right())
782                                     {
783                                         nX -= aMarkRect.Right() - rWorkArea.Right();
784                                     }
785 
786                                     if(aMarkRect.Top() < rWorkArea.Top())
787                                     {
788                                         nY += rWorkArea.Top() - aMarkRect.Top();
789                                     }
790 
791                                     if(aMarkRect.Bottom() > rWorkArea.Bottom())
792                                     {
793                                         nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
794                                     }
795                                 }
796                             }
797 
798                             // no handle selected
799                             if(0 != nX || 0 != nY)
800                             {
801                                 mpView->MoveAllMarked(Size(nX, nY));
802 
803                                 // #97016# II
804                                 mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
805                             }
806                         }
807                     }
808                     else
809                     {
810                         // move handle with index nHandleIndex
811                         if(pHdl && (nX || nY))
812                         {
813                             // now move the Handle (nX, nY)
814                             Point aStartPoint(pHdl->GetPos());
815                             Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
816                             const SdrDragStat& rDragStat = mpView->GetDragStat();
817 
818                             // start dragging
819                             mpView->BegDragObj(aStartPoint, 0, pHdl, 0);
820 
821                             if(mpView->IsDragObj())
822                             {
823                                 FASTBOOL bWasNoSnap = rDragStat.IsNoSnap();
824                                 sal_Bool bWasSnapEnabled = mpView->IsSnapEnabled();
825 
826                                 // switch snapping off
827                                 if(!bWasNoSnap)
828                                     ((SdrDragStat&)rDragStat).SetNoSnap(sal_True);
829                                 if(bWasSnapEnabled)
830                                     mpView->SetSnapEnabled(sal_False);
831 
832                                 mpView->MovAction(aEndPoint);
833                                 mpView->EndDragObj();
834 
835                                 // restore snap
836                                 if(!bWasNoSnap)
837                                     ((SdrDragStat&)rDragStat).SetNoSnap(bWasNoSnap);
838                                 if(bWasSnapEnabled)
839                                     mpView->SetSnapEnabled(bWasSnapEnabled);
840                             }
841 
842                             // make moved handle visible
843                             Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
844                             mpView->MakeVisible(aVisRect, *mpWindow);
845                         }
846                     }
847 
848                     // #109007#
849                     if(pEdgeObj)
850                     {
851                         // Restore original suppress value
852                         pEdgeObj->SetSuppressDefaultConnect(bOldSuppress);
853                     }
854                 }
855                 else
856                 {
857                     // Seite scrollen
858                     ScrollStart();
859                     mpViewShell->ScrollLines(nX, nY);
860                     ScrollEnd();
861                 }
862 
863                 bReturn = sal_True;
864             }
865         }
866         break;
867     }
868 
869     if (bReturn)
870     {
871         mpWindow->ReleaseMouse();
872     }
873 
874     // #98198# when a text-editable object is selected and the
875     // input character is printable, activate text edit on that object
876     // and feed character to object
877     if(!bReturn && !mpDocSh->IsReadOnly())
878     {
879         if(!mpView->IsTextEdit() && mpViewShell)
880         {
881             const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
882 
883             if(1 == rMarkList.GetMarkCount())
884             {
885                 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
886 
887                 // #i118485# allow TextInput for OLEs, too
888                 if(pObj->ISA(SdrTextObj) && pObj->HasTextEdit())
889                 {
890                     // #98533# use common IsSimpleCharInput from
891                     // the EditEngine.
892                     sal_Bool bPrintable(EditEngine::IsSimpleCharInput(rKEvt));
893 
894                     if(bPrintable)
895                     {
896                         // try to activate textedit mode for the selected object
897                         SfxStringItem aInputString(SID_ATTR_CHAR, String(rKEvt.GetCharCode()));
898 
899                         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
900                             SID_ATTR_CHAR,
901                             SFX_CALLMODE_ASYNCHRON,
902                             &aInputString,
903                             0L);
904 
905                         // consumed
906                         bReturn = sal_True;
907                     }
908                 }
909             }
910             else
911             {
912                 // #99039# test if there is a title object there. If yes, try to
913                 // set it to edit mode and start typing...
914                 if(mpViewShell->ISA(DrawViewShell)
915                     && EditEngine::IsSimpleCharInput(rKEvt))
916                 {
917                     DrawViewShell* pDrawViewShell =
918                         static_cast<DrawViewShell*>(mpViewShell);
919                     SdPage* pActualPage = pDrawViewShell->GetActualPage();
920                     SdrTextObj* pCandidate = 0L;
921 
922                     if(pActualPage)
923                     {
924                         SdrObjListIter aIter(*pActualPage, IM_DEEPNOGROUPS);
925 
926                         while(aIter.IsMore() && !pCandidate)
927                         {
928                             SdrObject* pObj = aIter.Next();
929 
930                             if(pObj && pObj->ISA(SdrTextObj))
931                             {
932                                 sal_uInt32 nInv(pObj->GetObjInventor());
933                                 sal_uInt16 nKnd(pObj->GetObjIdentifier());
934 
935                                 if(SdrInventor == nInv && OBJ_TITLETEXT == nKnd)
936                                 {
937                                     pCandidate = (SdrTextObj*)pObj;
938                                 }
939                             }
940                         }
941                     }
942 
943                     // when candidate found and candidate is untouched, start editing text...
944                     if(pCandidate && pCandidate->IsEmptyPresObj())
945                     {
946                         mpView->UnMarkAll();
947                         mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
948                         SfxStringItem aInputString(SID_ATTR_CHAR, String(rKEvt.GetCharCode()));
949 
950                         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
951                             SID_ATTR_CHAR,
952                             SFX_CALLMODE_ASYNCHRON,
953                             &aInputString,
954                             0L);
955 
956                         // consumed
957                         bReturn = sal_True;
958                     }
959                 }
960             }
961         }
962     }
963 
964     return(bReturn);
965 }
966 
967 sal_Bool FuPoor::MouseMove(const MouseEvent& )
968 {
969     return sal_False;
970 }
971 
972 // #97016# II
973 void FuPoor::SelectionHasChanged()
974 {
975     const SdrHdlList& rHdlList = mpView->GetHdlList();
976     ((SdrHdlList&)rHdlList).ResetFocusHdl();
977 }
978 
979 /*************************************************************************
980 |*
981 |* Cut object to clipboard
982 |*
983 \************************************************************************/
984 
985 void FuPoor::DoCut()
986 {
987     if (mpView)
988     {
989         mpView->DoCut(mpWindow);
990     }
991 }
992 
993 /*************************************************************************
994 |*
995 |* Copy object to clipboard
996 |*
997 \************************************************************************/
998 
999 void FuPoor::DoCopy()
1000 {
1001     if (mpView)
1002     {
1003         mpView->DoCopy(mpWindow);
1004     }
1005 }
1006 
1007 /*************************************************************************
1008 |*
1009 |* Paste object from clipboard
1010 |*
1011 \************************************************************************/
1012 
1013 void FuPoor::DoPaste()
1014 {
1015     if (mpView)
1016     {
1017         mpView->DoPaste(mpWindow);
1018     }
1019 }
1020 
1021 /*************************************************************************
1022 |*
1023 |* Timer-Handler fuer Drag&Drop
1024 |*
1025 \************************************************************************/
1026 
1027 IMPL_LINK( FuPoor, DragHdl, Timer *, EMPTYARG )
1028 {
1029     if( mpView )
1030     {
1031         sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
1032         SdrHdl* pHdl = mpView->PickHandle(aMDPos);
1033 
1034         if ( pHdl==NULL && mpView->IsMarkedHit(aMDPos, nHitLog)
1035              && !mpView->IsPresObjSelected(sal_False, sal_True) )
1036         {
1037             mpWindow->ReleaseMouse();
1038             bIsInDragMode = sal_True;
1039             mpView->StartDrag( aMDPos, mpWindow );
1040         }
1041     }
1042     return 0;
1043 }
1044 
1045 /*************************************************************************
1046 |*
1047 |* Command-event
1048 |*
1049 \************************************************************************/
1050 
1051 sal_Bool FuPoor::Command(const CommandEvent& rCEvt)
1052 {
1053     return( mpView->Command(rCEvt,mpWindow) );
1054 }
1055 
1056 /*************************************************************************
1057 |*
1058 |* Timer-Handler fuer Fensterscrolling
1059 |*
1060 \************************************************************************/
1061 
1062 IMPL_LINK_INLINE_START( FuPoor, DelayHdl, Timer *, EMPTYARG )
1063 {
1064     aDelayToScrollTimer.Stop ();
1065     bScrollable = sal_True;
1066 
1067     Point aPnt(mpWindow->GetPointerPosPixel());
1068 
1069     // #95491# use remembered MouseButton state to create correct
1070     // MouseEvents for this artifical MouseMove.
1071     MouseMove(MouseEvent(aPnt, 1, 0, GetMouseButtonCode()));
1072 
1073     return 0;
1074 }
1075 IMPL_LINK_INLINE_END( FuPoor, DelayHdl, Timer *, pTimer )
1076 
1077 /*************************************************************************
1078 |*
1079 |* Handler fuer Maustaste
1080 |*
1081 \************************************************************************/
1082 
1083 sal_Bool FuPoor::MouseButtonUp (const MouseEvent& rMEvt)
1084 {
1085     // #95491# remember button state for creation of own MouseEvents
1086     SetMouseButtonCode(rMEvt.GetButtons());
1087 
1088     aDelayToScrollTimer.Stop ();
1089     return bScrollable  =
1090         bDelayActive = sal_False;
1091 }
1092 
1093 sal_Bool FuPoor::MouseButtonDown(const MouseEvent& rMEvt)
1094 {
1095     // #95491# remember button state for creation of own MouseEvents
1096     SetMouseButtonCode(rMEvt.GetButtons());
1097 
1098     return sal_False;
1099 }
1100 
1101 /*************************************************************************
1102 |*
1103 |* Handler fuer Maustaste
1104 |*
1105 \************************************************************************/
1106 
1107 void FuPoor::StartDelayToScrollTimer ()
1108 {
1109     bDelayActive = sal_True;
1110     aDelayToScrollTimer.Start ();
1111 }
1112 
1113 /*************************************************************************
1114 |*
1115 |* Help-event
1116 |*
1117 \************************************************************************/
1118 
1119 sal_Bool FuPoor::RequestHelp(const HelpEvent& rHEvt)
1120 {
1121     sal_Bool bReturn = sal_False;
1122 
1123     SdrPageView* pPV = mpView->GetSdrPageView();
1124 
1125     if (pPV)
1126     {
1127         SdPage* pPage = (SdPage*) pPV->GetPage();
1128 
1129         if (pPage)
1130         {
1131             bReturn = pPage->RequestHelp(mpWindow, mpView, rHEvt);
1132         }
1133     }
1134 
1135     return(bReturn);
1136 }
1137 
1138 void FuPoor::Paint(const Rectangle&, ::sd::Window* )
1139 {
1140 }
1141 
1142 /*************************************************************************
1143 |*
1144 |* Request verarbeiten
1145 |*
1146 \************************************************************************/
1147 
1148 void FuPoor::ReceiveRequest(SfxRequest& rReq)
1149 {
1150     const SfxItemSet* pSet = rReq.GetArgs();
1151 
1152     if (pSet)
1153     {
1154         if( pSet->GetItemState( nSlotId ) == SFX_ITEM_SET )
1155         {
1156             const SfxPoolItem& rItem = pSet->Get( nSlotId );
1157 
1158             if( rItem.ISA( SfxAllEnumItem ) )
1159             {
1160                 nSlotValue = ( ( const SfxAllEnumItem& ) rItem ).GetValue();
1161             }
1162         }
1163     }
1164 }
1165 
1166 /*************************************************************************
1167 |*
1168 |* #97016#
1169 |*
1170 \************************************************************************/
1171 
1172 SdrObject* FuPoor::CreateDefaultObject(const sal_uInt16, const Rectangle& )
1173 {
1174     // empty base implementation
1175     return 0L;
1176 }
1177 
1178 void FuPoor::ImpForceQuadratic(Rectangle& rRect)
1179 {
1180     if(rRect.GetWidth() > rRect.GetHeight())
1181     {
1182         rRect = Rectangle(
1183             Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
1184             Size(rRect.GetHeight(), rRect.GetHeight()));
1185     }
1186     else
1187     {
1188         rRect = Rectangle(
1189             Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
1190             Size(rRect.GetWidth(), rRect.GetWidth()));
1191     }
1192 }
1193 
1194 
1195 
1196 
1197 void FuPoor::SwitchLayer (sal_Int32 nOffset)
1198 {
1199     if(mpViewShell && mpViewShell->ISA(DrawViewShell))
1200     {
1201         DrawViewShell* pDrawViewShell =
1202             static_cast<DrawViewShell*>(mpViewShell);
1203 
1204         // Calculate the new index.
1205         sal_Int32 nIndex = pDrawViewShell->GetActiveTabLayerIndex() + nOffset;
1206 
1207         // Make sure the new index lies inside the range of valid indices.
1208         if (nIndex < 0)
1209             nIndex = 0;
1210         else if (nIndex >= pDrawViewShell->GetTabLayerCount ())
1211             nIndex = pDrawViewShell->GetTabLayerCount() - 1;
1212 
1213         // Set the new active layer.
1214         if (nIndex != pDrawViewShell->GetActiveTabLayerIndex ())
1215         {
1216             LayerTabBar* pLayerTabControl =
1217                 static_cast<DrawViewShell*>(mpViewShell)->GetLayerTabControl();
1218             if (pLayerTabControl != NULL)
1219                 pLayerTabControl->SendDeactivatePageEvent ();
1220 
1221             pDrawViewShell->SetActiveTabLayerIndex (nIndex);
1222 
1223             if (pLayerTabControl != NULL)
1224                 pLayerTabControl->SendActivatePageEvent ();
1225         }
1226     }
1227 }
1228 
1229 /** is called when the currenct function should be aborted. <p>
1230     This is used when a function gets a KEY_ESCAPE but can also
1231     be called directly.
1232 
1233     @returns true if a active function was aborted
1234 */
1235 bool FuPoor::cancel()
1236 {
1237     if ( !this->ISA(FuSelection) )
1238     {
1239         mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);
1240         return true;
1241     }
1242 
1243     return false;
1244 }
1245 
1246 // #i33136#
1247 bool FuPoor::doConstructOrthogonal() const
1248 {
1249     return (
1250         SID_DRAW_XLINE == nSlotId ||
1251         SID_DRAW_CIRCLEARC == nSlotId ||
1252         SID_DRAW_SQUARE == nSlotId ||
1253         SID_DRAW_SQUARE_NOFILL == nSlotId ||
1254         SID_DRAW_SQUARE_ROUND == nSlotId ||
1255         SID_DRAW_SQUARE_ROUND_NOFILL == nSlotId ||
1256         SID_DRAW_CIRCLE == nSlotId ||
1257         SID_DRAW_CIRCLE_NOFILL == nSlotId ||
1258         SID_DRAW_CIRCLEPIE == nSlotId ||
1259         SID_DRAW_CIRCLEPIE_NOFILL == nSlotId ||
1260         SID_DRAW_CIRCLECUT == nSlotId ||
1261         SID_DRAW_CIRCLECUT_NOFILL == nSlotId ||
1262         SID_DRAW_XPOLYGON == nSlotId ||
1263         SID_DRAW_XPOLYGON_NOFILL == nSlotId ||
1264         SID_3D_CUBE == nSlotId ||
1265         SID_3D_SPHERE == nSlotId ||
1266         SID_3D_SHELL == nSlotId ||
1267         SID_3D_HALF_SPHERE == nSlotId ||
1268         SID_3D_TORUS == nSlotId ||
1269         SID_3D_CYLINDER == nSlotId ||
1270         SID_3D_CONE == nSlotId ||
1271         SID_3D_PYRAMID == nSlotId);
1272 }
1273 
1274 void FuPoor::DoExecute( SfxRequest& )
1275 {
1276 }
1277 
1278 } // end of namespace sd
1279