xref: /aoo41x/main/svx/source/dialog/graphctl.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <svl/itempool.hxx>
31 #include <vcl/dialog.hxx>
32 #include <vcl/wrkwin.hxx>
33 #include <unotools/syslocale.hxx>
34 #include <rtl/math.hxx>
35 #include <unotools/localedatawrapper.hxx>
36 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
37 #include <comphelper/processfactory.hxx>
38 #endif
39 #include <vcl/svapp.hxx>
40 #include <osl/mutex.hxx>
41 
42 #include <svx/graphctl.hxx>
43 #include "GraphCtlAccessibleContext.hxx"
44 #include "svx/xoutbmp.hxx"
45 #include <svx/svxids.hrc>
46 #include <svx/svdpage.hxx>
47 
48 // #i72889#
49 #include "svx/sdrpaintwindow.hxx"
50 
51 /*************************************************************************
52 |*
53 |*
54 |*
55 \************************************************************************/
56 
57 void GraphCtrlUserCall::Changed( const SdrObject& rObj, SdrUserCallType eType, const Rectangle& /*rOldBoundRect*/ )
58 {
59 	switch( eType )
60 	{
61 		case( SDRUSERCALL_MOVEONLY ):
62 		case( SDRUSERCALL_RESIZE ):
63 			rWin.SdrObjChanged( rObj );
64 		break;
65 
66 		case( SDRUSERCALL_INSERTED ):
67 			rWin.SdrObjCreated( rObj );
68 		break;
69 
70 		default:
71 		break;
72 	}
73 }
74 
75 
76 /*************************************************************************
77 |*
78 |*
79 |*
80 \************************************************************************/
81 
82 GraphCtrl::GraphCtrl( Window* pParent, const WinBits nWinBits ) :
83 			Control			( pParent, nWinBits ),
84 			aMap100			( MAP_100TH_MM ),
85             eObjKind        ( OBJ_NONE ),
86 			nPolyEdit		( 0 ),
87 			bEditMode		( sal_False ),
88 			bSdrMode		( sal_False ),
89             mpAccContext    ( NULL ),
90             pModel          ( NULL ),
91             pView           ( NULL )
92 {
93 	pUserCall = new GraphCtrlUserCall( *this );
94 	aUpdateTimer.SetTimeout( 200 );
95 	aUpdateTimer.SetTimeoutHdl( LINK( this, GraphCtrl, UpdateHdl ) );
96 	aUpdateTimer.Start();
97 
98 	SetWinStyle( nWinBits );
99 
100 	EnableRTL( sal_False );
101 }
102 
103 
104 /*************************************************************************
105 |*
106 |*
107 |*
108 \************************************************************************/
109 
110 GraphCtrl::GraphCtrl( Window* pParent, const ResId& rResId ) :
111 			Control			( pParent, rResId ),
112 			aMap100			( MAP_100TH_MM ),
113             nWinStyle       ( 0 ),
114             eObjKind        ( OBJ_NONE ),
115 			nPolyEdit		( 0 ),
116             bEditMode       ( sal_False ),
117             bSdrMode        ( sal_False ),
118             bAnim           ( sal_False ),
119             mpAccContext    ( NULL ),
120             pModel          ( NULL ),
121             pView           ( NULL )
122 {
123 	pUserCall = new GraphCtrlUserCall( *this );
124 	aUpdateTimer.SetTimeout( 500 );
125 	aUpdateTimer.SetTimeoutHdl( LINK( this, GraphCtrl, UpdateHdl ) );
126 	aUpdateTimer.Start();
127 	EnableRTL( sal_False );
128 }
129 
130 
131 /*************************************************************************
132 |*
133 |*
134 |*
135 \************************************************************************/
136 
137 GraphCtrl::~GraphCtrl()
138 {
139 	if( mpAccContext )
140 	{
141 		mpAccContext->disposing();
142 		mpAccContext->release();
143 	}
144 	delete pView;
145 	delete pModel;
146 	delete pUserCall;
147 }
148 
149 
150 /*************************************************************************
151 |*
152 |*
153 |*
154 \************************************************************************/
155 
156 void GraphCtrl::SetWinStyle( WinBits nWinBits )
157 {
158 	nWinStyle = nWinBits;
159 	bAnim = ( nWinStyle & WB_ANIMATION ) == WB_ANIMATION;
160 	bSdrMode = ( nWinStyle & WB_SDRMODE ) == WB_SDRMODE;
161 
162 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
163 	SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
164 	SetMapMode( aMap100 );
165 
166 	delete pView;
167 	pView = NULL;
168 
169 	delete pModel;
170 	pModel = NULL;
171 
172 	if ( bSdrMode )
173 		InitSdrModel();
174 }
175 
176 
177 /*************************************************************************
178 |*
179 |*
180 |*
181 \************************************************************************/
182 
183 void GraphCtrl::InitSdrModel()
184 {
185 	::vos::OGuard aGuard (Application::GetSolarMutex());
186 
187 	SdrPage* pPage;
188 
189 	// alten Kram zerstoeren
190 	delete pView;
191 	delete pModel;
192 
193 	// Model anlegen
194 	pModel = new SdrModel;
195 	pModel->GetItemPool().FreezeIdRanges();
196 	pModel->SetScaleUnit( aMap100.GetMapUnit() );
197 	pModel->SetScaleFraction( Fraction( 1, 1 ) );
198 	pModel->SetDefaultFontHeight( 500 );
199 
200 	pPage = new SdrPage( *pModel );
201 
202 	pPage->SetSize( aGraphSize );
203 	pPage->SetBorder( 0, 0, 0, 0 );
204 	pModel->InsertPage( pPage );
205 	pModel->SetChanged( sal_False );
206 
207 	// View anlegen
208 	pView = new GraphCtrlView( pModel, this );
209 	pView->SetWorkArea( Rectangle( Point(), aGraphSize ) );
210 	pView->EnableExtendedMouseEventDispatcher( sal_True );
211 	pView->ShowSdrPage(pView->GetModel()->GetPage(0));
212 //	pView->ShowSdrPage(pView->GetModel()->GetPage(0));
213 	pView->SetFrameDragSingles( sal_True );
214 	pView->SetMarkedPointsSmooth( SDRPATHSMOOTH_SYMMETRIC );
215 	pView->SetEditMode( sal_True );
216 
217 	// #i72889# set neeeded flags
218 	pView->SetPagePaintingAllowed(false);
219 	pView->SetBufferedOutputAllowed(true);
220 	pView->SetBufferedOverlayAllowed(true);
221 
222     // Tell the accessibility object about the changes.
223     if (mpAccContext != NULL)
224         mpAccContext->setModelAndView (pModel, pView);
225 }
226 
227 
228 /*************************************************************************
229 |*
230 |*
231 |*
232 \************************************************************************/
233 
234 void GraphCtrl::SetGraphic( const Graphic& rGraphic, sal_Bool bNewModel )
235 {
236 	// Bitmaps dithern wir ggf. fuer die Anzeige
237 	if ( !bAnim && ( rGraphic.GetType() == GRAPHIC_BITMAP )  )
238 	{
239 		if ( rGraphic.IsTransparent() )
240 		{
241 			Bitmap	aBmp( rGraphic.GetBitmap() );
242 
243 			DitherBitmap( aBmp );
244 			aGraphic = Graphic( BitmapEx( aBmp, rGraphic.GetBitmapEx().GetMask() ) );
245 		}
246 		else
247 		{
248 			Bitmap aBmp( rGraphic.GetBitmap() );
249 			DitherBitmap( aBmp );
250 			aGraphic = aBmp;
251 		}
252 	}
253 	else
254 		aGraphic = rGraphic;
255 
256 	if ( aGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
257 		aGraphSize = Application::GetDefaultDevice()->PixelToLogic( aGraphic.GetPrefSize(), aMap100 );
258 	else
259 		aGraphSize = OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), aMap100 );
260 
261 	if ( bSdrMode && bNewModel )
262 		InitSdrModel();
263 
264 	if ( aGraphSizeLink.IsSet() )
265 		aGraphSizeLink.Call( this );
266 
267 	Resize();
268 	Invalidate();
269 }
270 
271 
272 /*************************************************************************
273 |*
274 |*
275 |*
276 \************************************************************************/
277 
278 void GraphCtrl::Resize()
279 {
280 	Control::Resize();
281 
282 	if ( aGraphSize.Width() && aGraphSize.Height() )
283 	{
284 		MapMode			aDisplayMap( aMap100 );
285 		Point           aNewPos;
286 		Size			aNewSize;
287 		const Size		aWinSize = PixelToLogic( GetOutputSizePixel(), aDisplayMap );
288 		const long		nWidth = aWinSize.Width();
289 		const long		nHeight = aWinSize.Height();
290 		double          fGrfWH = (double) aGraphSize.Width() / aGraphSize.Height();
291 		double          fWinWH = (double) nWidth / nHeight;
292 
293 		// Bitmap an Thumbgroesse anpassen
294 		if ( fGrfWH < fWinWH)
295 		{
296 			aNewSize.Width() = (long) ( (double) nHeight * fGrfWH );
297 			aNewSize.Height()= nHeight;
298 		}
299 		else
300 		{
301 			aNewSize.Width() = nWidth;
302 			aNewSize.Height()= (long) ( (double) nWidth / fGrfWH );
303 		}
304 
305 		aNewPos.X() = ( nWidth - aNewSize.Width() )  >> 1;
306 		aNewPos.Y() = ( nHeight - aNewSize.Height() ) >> 1;
307 
308 		// MapMode fuer Engine umsetzen
309 		aDisplayMap.SetScaleX( Fraction( aNewSize.Width(), aGraphSize.Width() ) );
310 		aDisplayMap.SetScaleY( Fraction( aNewSize.Height(), aGraphSize.Height() ) );
311 
312 		aDisplayMap.SetOrigin( LogicToLogic( aNewPos, aMap100, aDisplayMap ) );
313 		SetMapMode( aDisplayMap );
314 	}
315 
316 	Invalidate();
317 }
318 
319 
320 /*************************************************************************
321 |*
322 |*
323 |*
324 \************************************************************************/
325 
326 void GraphCtrl::Paint( const Rectangle& rRect )
327 {
328 	// #i72889# used splitted repaint to be able to paint an own background
329 	// even to the buffered view
330 	const bool bGraphicValid(GRAPHIC_NONE != aGraphic.GetType());
331 
332 	if(bSdrMode)
333 	{
334 		SdrPaintWindow* pPaintWindow = pView->BeginCompleteRedraw(this);
335 
336 		if(bGraphicValid)
337 		{
338 			OutputDevice& rTarget = pPaintWindow->GetTargetOutputDevice();
339 
340 			rTarget.SetBackground(GetBackground());
341 			rTarget.Erase();
342 
343 			aGraphic.Draw(&rTarget, Point(), aGraphSize);
344 		}
345 
346 		const Region aRepaintRegion(rRect);
347 		pView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion);
348 		pView->EndCompleteRedraw(*pPaintWindow, true);
349 	}
350 	else
351 	{
352 		// #i73381# in non-SdrMode, paint to local directly
353 		if(bGraphicValid)
354 		{
355 			aGraphic.Draw(this, Point(), aGraphSize);
356 		}
357 	}
358 }
359 
360 
361 /*************************************************************************
362 |*
363 |*
364 |*
365 \************************************************************************/
366 
367 void GraphCtrl::SdrObjChanged( const SdrObject&  )
368 {
369 }
370 
371 
372 /*************************************************************************
373 |*
374 |*
375 |*
376 \************************************************************************/
377 
378 void GraphCtrl::SdrObjCreated( const SdrObject& )
379 {
380 }
381 
382 
383 /*************************************************************************
384 |*
385 |*
386 |*
387 \************************************************************************/
388 
389 void GraphCtrl::MarkListHasChanged()
390 {
391 	if ( aMarkObjLink.IsSet() )
392 		aMarkObjLink.Call( this );
393 }
394 
395 
396 /*************************************************************************
397 |*
398 |*
399 |*
400 \************************************************************************/
401 
402 void GraphCtrl::KeyInput( const KeyEvent& rKEvt )
403 {
404 	KeyCode aCode( rKEvt.GetKeyCode() );
405 	sal_Bool	bProc = sal_False;
406 
407 	switch ( aCode.GetCode() )
408 	{
409 		case KEY_DELETE:
410 		case KEY_BACKSPACE:
411 		{
412 			if ( bSdrMode )
413 			{
414 				pView->DeleteMarked();
415 				bProc = sal_True;
416 				if( !pView->AreObjectsMarked() )
417 					((Dialog*)GetParent())->GrabFocusToFirstControl();
418 			}
419 		}
420 		break;
421 
422 		case KEY_ESCAPE:
423 		{
424 			if ( bSdrMode )
425 			{
426 				if ( pView->IsAction() )
427 				{
428 					pView->BrkAction();
429 				}
430 				else if ( pView->AreObjectsMarked() )
431 				{
432 					const SdrHdlList& rHdlList = pView->GetHdlList();
433 					SdrHdl* pHdl = rHdlList.GetFocusHdl();
434 
435 					if(pHdl)
436 					{
437 						((SdrHdlList&)rHdlList).ResetFocusHdl();
438 					}
439 					else
440 					{
441 						((Dialog*)GetParent())->GrabFocusToFirstControl();
442 					}
443 				}
444 				else
445 				{
446 					((Dialog*)GetParent())->GrabFocusToFirstControl();
447 				}
448 				bProc = sal_True;
449 			}
450 		}
451 		break;
452 
453 		case KEY_F11:
454 		case KEY_TAB:
455 		{
456 			if( bSdrMode )
457 			{
458 				if( !aCode.IsMod1() && !aCode.IsMod2() )
459 				{
460 					bool bForward = !aCode.IsShift();
461 					// select next object
462 					if ( ! pView->MarkNextObj( bForward ))
463                     {
464                         // At first or last object.  Cycle to the other end
465                         // of the list.
466                         pView->UnmarkAllObj();
467                         pView->MarkNextObj (bForward);
468                     }
469 					bProc = sal_True;
470 				}
471 				else if(aCode.IsMod1())
472 				{
473 					// select next handle
474 					const SdrHdlList& rHdlList = pView->GetHdlList();
475 					sal_Bool bForward(!aCode.IsShift());
476 
477 					((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);
478 
479 					bProc = true;
480 				}
481 			}
482 		}
483 		break;
484 
485 		case KEY_END:
486 		{
487 
488 			if ( aCode.IsMod1() )
489 			{
490 				// #97016# mark last object
491 				pView->UnmarkAllObj();
492 				pView->MarkNextObj(sal_False);
493 
494 				bProc = true;
495 			}
496 		}
497 		break;
498 
499 		case KEY_HOME:
500 		{
501 			if ( aCode.IsMod1() )
502 			{
503 				pView->UnmarkAllObj();
504 				pView->MarkNextObj(sal_True);
505 
506 				bProc = true;
507 			}
508 		}
509 		break;
510 
511 		case KEY_UP:
512 		case KEY_DOWN:
513 		case KEY_LEFT:
514 		case KEY_RIGHT:
515 		{
516 			long nX = 0;
517 			long nY = 0;
518 
519 			if (aCode.GetCode() == KEY_UP)
520 			{
521 				// Scroll nach oben
522 				nX = 0;
523 				nY =-1;
524 			}
525 			else if (aCode.GetCode() == KEY_DOWN)
526 			{
527 				// Scroll nach unten
528 				nX = 0;
529 				nY = 1;
530 			}
531 			else if (aCode.GetCode() == KEY_LEFT)
532 			{
533 				// Scroll nach links
534 				nX =-1;
535 				nY = 0;
536 			}
537 			else if (aCode.GetCode() == KEY_RIGHT)
538 			{
539 				// Scroll nach rechts
540 				nX = 1;
541 				nY = 0;
542 			}
543 
544 			if (pView->AreObjectsMarked() && !aCode.IsMod1() )
545 			{
546 				if(aCode.IsMod2())
547 				{
548 					// #97016# move in 1 pixel distance
549 					Size aLogicSizeOnePixel = PixelToLogic(Size(1,1));
550 					nX *= aLogicSizeOnePixel.Width();
551 					nY *= aLogicSizeOnePixel.Height();
552 				}
553 				else
554 				{
555 					// old, fixed move distance
556 					nX *= 100;
557 					nY *= 100;
558 				}
559 
560 				// #97016# II
561 				const SdrHdlList& rHdlList = pView->GetHdlList();
562 				SdrHdl* pHdl = rHdlList.GetFocusHdl();
563 
564 				if(0L == pHdl)
565 				{
566 					// #90129# restrict movement to WorkArea
567 					const Rectangle& rWorkArea = pView->GetWorkArea();
568 
569 					if(!rWorkArea.IsEmpty())
570 					{
571 						Rectangle aMarkRect(pView->GetMarkedObjRect());
572 						aMarkRect.Move(nX, nY);
573 
574 						if(!aMarkRect.IsInside(rWorkArea))
575 						{
576 							if(aMarkRect.Left() < rWorkArea.Left())
577 							{
578 								nX += rWorkArea.Left() - aMarkRect.Left();
579 							}
580 
581 							if(aMarkRect.Right() > rWorkArea.Right())
582 							{
583 								nX -= aMarkRect.Right() - rWorkArea.Right();
584 							}
585 
586 							if(aMarkRect.Top() < rWorkArea.Top())
587 							{
588 								nY += rWorkArea.Top() - aMarkRect.Top();
589 							}
590 
591 							if(aMarkRect.Bottom() > rWorkArea.Bottom())
592 							{
593 								nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
594 							}
595 						}
596 					}
597 
598 					// no handle selected
599 					if(0 != nX || 0 != nY)
600 					{
601 						pView->MoveAllMarked(Size(nX, nY));
602 					}
603 				}
604 				else
605 				{
606 					// move handle with index nHandleIndex
607 					if(pHdl && (nX || nY))
608 					{
609 						// now move the Handle (nX, nY)
610 						Point aStartPoint(pHdl->GetPos());
611 						Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
612 						const SdrDragStat& rDragStat = pView->GetDragStat();
613 
614 						// start dragging
615 						pView->BegDragObj(aStartPoint, 0, pHdl, 0);
616 
617 					    if(pView->IsDragObj())
618 						{
619 							FASTBOOL bWasNoSnap = rDragStat.IsNoSnap();
620 							sal_Bool bWasSnapEnabled = pView->IsSnapEnabled();
621 
622 							// switch snapping off
623 							if(!bWasNoSnap)
624 								((SdrDragStat&)rDragStat).SetNoSnap(sal_True);
625 							if(bWasSnapEnabled)
626 								pView->SetSnapEnabled(sal_False);
627 
628 							pView->MovAction(aEndPoint);
629 							pView->EndDragObj();
630 
631 							// restore snap
632 							if(!bWasNoSnap)
633 								((SdrDragStat&)rDragStat).SetNoSnap(bWasNoSnap);
634 							if(bWasSnapEnabled)
635 								pView->SetSnapEnabled(bWasSnapEnabled);
636 						}
637 					}
638 				}
639 
640 				bProc = true;
641 			}
642 		}
643 		break;
644 
645 		case KEY_SPACE:
646 		{
647 			const SdrHdlList& rHdlList = pView->GetHdlList();
648 			SdrHdl* pHdl = rHdlList.GetFocusHdl();
649 
650 			if(pHdl)
651 			{
652 				if(pHdl->GetKind() == HDL_POLY)
653 				{
654 					// rescue ID of point with focus
655 					sal_uInt32 nPol(pHdl->GetPolyNum());
656 					sal_uInt32 nPnt(pHdl->GetPointNum());
657 
658 					if(pView->IsPointMarked(*pHdl))
659 					{
660 						if(rKEvt.GetKeyCode().IsShift())
661 						{
662 							pView->UnmarkPoint(*pHdl);
663 						}
664 					}
665 					else
666 					{
667 						if(!rKEvt.GetKeyCode().IsShift())
668 						{
669 							pView->UnmarkAllPoints();
670 						}
671 
672 						pView->MarkPoint(*pHdl);
673 					}
674 
675 					if(0L == rHdlList.GetFocusHdl())
676 					{
677 						// restore point with focus
678 						SdrHdl* pNewOne = 0L;
679 
680 						for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++)
681 						{
682 							SdrHdl* pAct = rHdlList.GetHdl(a);
683 
684 							if(pAct
685 								&& pAct->GetKind() == HDL_POLY
686 								&& pAct->GetPolyNum() == nPol
687 								&& pAct->GetPointNum() == nPnt)
688 							{
689 								pNewOne = pAct;
690 							}
691 						}
692 
693 						if(pNewOne)
694 						{
695 							((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
696 						}
697 					}
698 
699 					bProc = sal_True;
700 				}
701 			}
702 		}
703 		break;
704 
705 		default:
706 		break;
707 	}
708 
709 	if ( !bProc )
710 		Control::KeyInput( rKEvt );
711 	else
712 		ReleaseMouse();
713 }
714 
715 
716 /*************************************************************************
717 |*
718 |*
719 |*
720 \************************************************************************/
721 
722 void GraphCtrl::MouseButtonDown( const MouseEvent& rMEvt )
723 {
724 	if ( bSdrMode && ( rMEvt.GetClicks() < 2 ) )
725 	{
726 		const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );
727 
728 		if ( !Rectangle( Point(), aGraphSize ).IsInside( aLogPt ) && !pView->IsEditMode() )
729 			Control::MouseButtonDown( rMEvt );
730 		else
731 		{
732 			// Focus anziehen fuer Key-Inputs
733 			GrabFocus();
734 
735 			if ( nPolyEdit )
736 			{
737 				SdrViewEvent	aVEvt;
738 				SdrHitKind		eHit = pView->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
739 
740 				if ( nPolyEdit == SID_BEZIER_INSERT && eHit == SDRHIT_MARKEDOBJECT )
741 					pView->BegInsObjPoint( aLogPt, rMEvt.IsMod1());
742 				else
743 					pView->MouseButtonDown( rMEvt, this );
744 			}
745 			else
746 				pView->MouseButtonDown( rMEvt, this );
747 		}
748 
749 		SdrObject* pCreateObj = pView->GetCreateObj();
750 
751 		// Wir wollen das Inserten mitbekommen
752 		if ( pCreateObj && !pCreateObj->GetUserCall() )
753 			pCreateObj->SetUserCall( pUserCall );
754 
755 		SetPointer( pView->GetPreferedPointer( aLogPt, this ) );
756 	}
757 	else
758 		Control::MouseButtonDown( rMEvt );
759 }
760 
761 
762 /*************************************************************************
763 |*
764 |*
765 |*
766 \************************************************************************/
767 
768 void GraphCtrl::MouseMove(const MouseEvent& rMEvt)
769 {
770 	const Point	aLogPos( PixelToLogic( rMEvt.GetPosPixel() ) );
771 
772 	if ( bSdrMode )
773 	{
774 		pView->MouseMove( rMEvt, this );
775 
776 		if( ( SID_BEZIER_INSERT == nPolyEdit ) &&
777 			!pView->PickHandle( aLogPos ) &&
778 			!pView->IsInsObjPoint() )
779 		{
780 			SetPointer( POINTER_CROSS );
781 		}
782 		else
783 			SetPointer( pView->GetPreferedPointer( aLogPos, this ) );
784 	}
785 	else
786 		Control::MouseButtonUp( rMEvt );
787 
788 	if ( aMousePosLink.IsSet() )
789 	{
790 		if ( Rectangle( Point(), aGraphSize ).IsInside( aLogPos ) )
791 			aMousePos = aLogPos;
792 		else
793 			aMousePos = Point();
794 
795 		aMousePosLink.Call( this );
796 	}
797 }
798 
799 
800 /*************************************************************************
801 |*
802 |*
803 |*
804 \************************************************************************/
805 
806 void GraphCtrl::MouseButtonUp(const MouseEvent& rMEvt)
807 {
808 	if ( bSdrMode )
809 	{
810 		if ( pView->IsInsObjPoint() )
811 			pView->EndInsObjPoint( SDRCREATE_FORCEEND );
812 		else
813 			pView->MouseButtonUp( rMEvt, this );
814 
815 		ReleaseMouse();
816 		SetPointer( pView->GetPreferedPointer( PixelToLogic( rMEvt.GetPosPixel() ), this ) );
817 	}
818 	else
819 		Control::MouseButtonUp( rMEvt );
820 }
821 
822 
823 /*************************************************************************
824 |*
825 |*
826 |*
827 \************************************************************************/
828 
829 SdrObject* GraphCtrl::GetSelectedSdrObject() const
830 {
831 	SdrObject* pSdrObj = NULL;
832 
833 	if ( bSdrMode )
834 	{
835 		const SdrMarkList&	rMarkList = pView->GetMarkedObjectList();
836 
837 		if ( rMarkList.GetMarkCount() == 1 )
838 			pSdrObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
839 	}
840 
841 	return pSdrObj;
842 }
843 
844 
845 /*************************************************************************
846 |*
847 |*
848 |*
849 \************************************************************************/
850 
851 void GraphCtrl::SetEditMode( const sal_Bool _bEditMode )
852 {
853 	if ( bSdrMode )
854 	{
855         bEditMode = _bEditMode;
856 		pView->SetEditMode( bEditMode );
857         eObjKind = OBJ_NONE;
858 		pView->SetCurrentObj( sal::static_int_cast< sal_uInt16 >( eObjKind ) );
859 	}
860 	else
861 		bEditMode = sal_False;
862 }
863 
864 
865 /*************************************************************************
866 |*
867 |*
868 |*
869 \************************************************************************/
870 
871 void GraphCtrl::SetPolyEditMode( const sal_uInt16 _nPolyEdit )
872 {
873 	if ( bSdrMode && ( _nPolyEdit != nPolyEdit ) )
874 	{
875 		nPolyEdit = _nPolyEdit;
876 		pView->SetFrameDragSingles( nPolyEdit == 0 );
877 	}
878 	else
879 		nPolyEdit = 0;
880 }
881 
882 
883 /*************************************************************************
884 |*
885 |*
886 |*
887 \************************************************************************/
888 
889 void GraphCtrl::SetObjKind( const SdrObjKind _eObjKind )
890 {
891 	if ( bSdrMode )
892 	{
893         bEditMode = sal_False;
894 		pView->SetEditMode( bEditMode );
895         eObjKind = _eObjKind;
896 		pView->SetCurrentObj( sal::static_int_cast< sal_uInt16 >( eObjKind ) );
897 	}
898 	else
899 		eObjKind = OBJ_NONE;
900 }
901 
902 
903 /*************************************************************************
904 |*
905 |*
906 |*
907 \************************************************************************/
908 
909 String GraphCtrl::GetStringFromDouble( const double& rDouble )
910 {
911     sal_Unicode cSep =
912         SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0);
913     String aStr( ::rtl::math::doubleToUString( rDouble,
914                 rtl_math_StringFormat_F, 2, cSep ));
915     return aStr;
916 }
917 
918 
919 /*************************************************************************
920 www|*
921 |*
922 |*
923 \************************************************************************/
924 
925 IMPL_LINK( GraphCtrl, UpdateHdl, Timer*, pTimer )
926 {
927 	if ( aUpdateLink.IsSet() )
928 		aUpdateLink.Call( this );
929 
930 	pTimer->Start();
931 
932 	return 0L;
933 }
934 
935 
936 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > GraphCtrl::CreateAccessible()
937 {
938 	if( mpAccContext == NULL )
939 	{
940 		Window* pParent = GetParent();
941 
942 		DBG_ASSERT( pParent, "-GraphCtrl::CreateAccessible(): No Parent!" );
943 
944 		if( pParent )
945 		{
946 			::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAccParent( pParent->GetAccessible() );
947 
948             // #103856# Disable accessibility if no model/view data available
949 			if( pView &&
950                 pModel &&
951                 xAccParent.is() )
952 			{
953 				mpAccContext = new SvxGraphCtrlAccessibleContext( xAccParent, *this );
954 				mpAccContext->acquire();
955 			}
956 		}
957 	}
958 
959 	return mpAccContext;
960 }
961