xref: /trunk/main/svx/source/dialog/graphctl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_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