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