/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <svl/itempool.hxx>
#include <vcl/dialog.hxx>
#include <vcl/wrkwin.hxx>
#include <unotools/syslocale.hxx>
#include <rtl/math.hxx>
#include <unotools/localedatawrapper.hxx>
#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif
#include <vcl/svapp.hxx>
#include <osl/mutex.hxx>

#include <svx/graphctl.hxx>
#include "GraphCtlAccessibleContext.hxx"
#include "svx/xoutbmp.hxx"
#include <svx/svxids.hrc>
#include <svx/svdpage.hxx>

// #i72889#
#include "svx/sdrpaintwindow.hxx"

/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrlUserCall::Changed( const SdrObject& rObj, SdrUserCallType eType, const Rectangle& /*rOldBoundRect*/ )
{
	switch( eType )
	{
		case( SDRUSERCALL_MOVEONLY ):
		case( SDRUSERCALL_RESIZE ):
			rWin.SdrObjChanged( rObj );
		break;

		case( SDRUSERCALL_INSERTED ):
			rWin.SdrObjCreated( rObj );
		break;

		default:
		break;
	}
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

GraphCtrl::GraphCtrl( Window* pParent, const WinBits nWinBits ) :
			Control			( pParent, nWinBits ),
			aMap100			( MAP_100TH_MM ),
            eObjKind        ( OBJ_NONE ),
			nPolyEdit		( 0 ),
			bEditMode		( sal_False ),
			bSdrMode		( sal_False ),
            mpAccContext    ( NULL ),
            pModel          ( NULL ),
            pView           ( NULL )
{
	pUserCall = new GraphCtrlUserCall( *this );
	aUpdateTimer.SetTimeout( 200 );
	aUpdateTimer.SetTimeoutHdl( LINK( this, GraphCtrl, UpdateHdl ) );
	aUpdateTimer.Start();

	SetWinStyle( nWinBits );

	EnableRTL( sal_False );
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

GraphCtrl::GraphCtrl( Window* pParent, const ResId& rResId ) :
			Control			( pParent, rResId ),
			aMap100			( MAP_100TH_MM ),
            nWinStyle       ( 0 ),
            eObjKind        ( OBJ_NONE ),
			nPolyEdit		( 0 ),
            bEditMode       ( sal_False ),
            bSdrMode        ( sal_False ),
            bAnim           ( sal_False ),
            mpAccContext    ( NULL ),
            pModel          ( NULL ),
            pView           ( NULL )
{
	pUserCall = new GraphCtrlUserCall( *this );
	aUpdateTimer.SetTimeout( 500 );
	aUpdateTimer.SetTimeoutHdl( LINK( this, GraphCtrl, UpdateHdl ) );
	aUpdateTimer.Start();
	EnableRTL( sal_False );
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

GraphCtrl::~GraphCtrl()
{
	if( mpAccContext )
	{
		mpAccContext->disposing();
		mpAccContext->release();
	}
	delete pView;
	delete pModel;
	delete pUserCall;
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::SetWinStyle( WinBits nWinBits )
{
	nWinStyle = nWinBits;
	bAnim = ( nWinStyle & WB_ANIMATION ) == WB_ANIMATION;
	bSdrMode = ( nWinStyle & WB_SDRMODE ) == WB_SDRMODE;

	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
	SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) );
	SetMapMode( aMap100 );

	delete pView;
	pView = NULL;

	delete pModel;
	pModel = NULL;

	if ( bSdrMode )
		InitSdrModel();
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::InitSdrModel()
{
	::vos::OGuard aGuard (Application::GetSolarMutex());

	SdrPage* pPage;

	// alten Kram zerstoeren
	delete pView;
	delete pModel;

	// Model anlegen
	pModel = new SdrModel;
	pModel->GetItemPool().FreezeIdRanges();
	pModel->SetScaleUnit( aMap100.GetMapUnit() );
	pModel->SetScaleFraction( Fraction( 1, 1 ) );
	pModel->SetDefaultFontHeight( 500 );

	pPage = new SdrPage( *pModel );

	pPage->SetSize( aGraphSize );
	pPage->SetBorder( 0, 0, 0, 0 );
	pModel->InsertPage( pPage );
	pModel->SetChanged( sal_False );

	// View anlegen
	pView = new GraphCtrlView( pModel, this );
	pView->SetWorkArea( Rectangle( Point(), aGraphSize ) );
	pView->EnableExtendedMouseEventDispatcher( sal_True );
	pView->ShowSdrPage(pView->GetModel()->GetPage(0));
//	pView->ShowSdrPage(pView->GetModel()->GetPage(0));
	pView->SetFrameDragSingles( sal_True );
	pView->SetMarkedPointsSmooth( SDRPATHSMOOTH_SYMMETRIC );
	pView->SetEditMode( sal_True );

	// #i72889# set needed flags
	pView->SetPagePaintingAllowed(false);
	pView->SetBufferedOutputAllowed(true);
	pView->SetBufferedOverlayAllowed(true);

    // Tell the accessibility object about the changes.
    if (mpAccContext != NULL)
        mpAccContext->setModelAndView (pModel, pView);
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::SetGraphic( const Graphic& rGraphic, sal_Bool bNewModel )
{
	// Bitmaps dithern wir ggf. fuer die Anzeige
	if ( !bAnim && ( rGraphic.GetType() == GRAPHIC_BITMAP )  )
	{
		if ( rGraphic.IsTransparent() )
		{
			Bitmap	aBmp( rGraphic.GetBitmap() );

			DitherBitmap( aBmp );
			aGraphic = Graphic( BitmapEx( aBmp, rGraphic.GetBitmapEx().GetMask() ) );
		}
		else
		{
			Bitmap aBmp( rGraphic.GetBitmap() );
			DitherBitmap( aBmp );
			aGraphic = aBmp;
		}
	}
	else
		aGraphic = rGraphic;

	if ( aGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
		aGraphSize = Application::GetDefaultDevice()->PixelToLogic( aGraphic.GetPrefSize(), aMap100 );
	else
		aGraphSize = OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), aMap100 );

	if ( bSdrMode && bNewModel )
		InitSdrModel();

	if ( aGraphSizeLink.IsSet() )
		aGraphSizeLink.Call( this );

	Resize();
	Invalidate();
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::Resize()
{
	Control::Resize();

	if ( aGraphSize.Width() && aGraphSize.Height() )
	{
		MapMode			aDisplayMap( aMap100 );
		Point           aNewPos;
		Size			aNewSize;
		const Size		aWinSize = PixelToLogic( GetOutputSizePixel(), aDisplayMap );
		const long		nWidth = aWinSize.Width();
		const long		nHeight = aWinSize.Height();
		double          fGrfWH = (double) aGraphSize.Width() / aGraphSize.Height();
		double          fWinWH = (double) nWidth / nHeight;

		// Bitmap an Thumbgroesse anpassen
		if ( fGrfWH < fWinWH)
		{
			aNewSize.Width() = (long) ( (double) nHeight * fGrfWH );
			aNewSize.Height()= nHeight;
		}
		else
		{
			aNewSize.Width() = nWidth;
			aNewSize.Height()= (long) ( (double) nWidth / fGrfWH );
		}

		aNewPos.X() = ( nWidth - aNewSize.Width() )  >> 1;
		aNewPos.Y() = ( nHeight - aNewSize.Height() ) >> 1;

		// MapMode fuer Engine umsetzen
		aDisplayMap.SetScaleX( Fraction( aNewSize.Width(), aGraphSize.Width() ) );
		aDisplayMap.SetScaleY( Fraction( aNewSize.Height(), aGraphSize.Height() ) );

		aDisplayMap.SetOrigin( LogicToLogic( aNewPos, aMap100, aDisplayMap ) );
		SetMapMode( aDisplayMap );
	}

	Invalidate();
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::Paint( const Rectangle& rRect )
{
	// #i72889# used splitted repaint to be able to paint an own background
	// even to the buffered view
	const bool bGraphicValid(GRAPHIC_NONE != aGraphic.GetType());

	if(bSdrMode)
	{
		SdrPaintWindow* pPaintWindow = pView->BeginCompleteRedraw(this);

		if(bGraphicValid)
		{
			OutputDevice& rTarget = pPaintWindow->GetTargetOutputDevice();

			rTarget.SetBackground(GetBackground());
			rTarget.Erase();

			aGraphic.Draw(&rTarget, Point(), aGraphSize);
		}

		const Region aRepaintRegion(rRect);
		pView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion);
		pView->EndCompleteRedraw(*pPaintWindow, true);
	}
	else
	{
		// #i73381# in non-SdrMode, paint to local directly
		if(bGraphicValid)
		{
			aGraphic.Draw(this, Point(), aGraphSize);
		}
	}
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::SdrObjChanged( const SdrObject&  )
{
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::SdrObjCreated( const SdrObject& )
{
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::MarkListHasChanged()
{
	if ( aMarkObjLink.IsSet() )
		aMarkObjLink.Call( this );
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::KeyInput( const KeyEvent& rKEvt )
{
	KeyCode aCode( rKEvt.GetKeyCode() );
	sal_Bool	bProc = sal_False;

	switch ( aCode.GetCode() )
	{
		case KEY_DELETE:
		case KEY_BACKSPACE:
		{
			if ( bSdrMode )
			{
				pView->DeleteMarked();
				bProc = sal_True;
				if( !pView->AreObjectsMarked() )
					((Dialog*)GetParent())->GrabFocusToFirstControl();
			}
		}
		break;

		case KEY_ESCAPE:
		{
			if ( bSdrMode )
			{
				if ( pView->IsAction() )
				{
					pView->BrkAction();
				}
				else if ( pView->AreObjectsMarked() )
				{
					const SdrHdlList& rHdlList = pView->GetHdlList();
					SdrHdl* pHdl = rHdlList.GetFocusHdl();

					if(pHdl)
					{
						((SdrHdlList&)rHdlList).ResetFocusHdl();
					}
					else
					{
						((Dialog*)GetParent())->GrabFocusToFirstControl();
					}
				}
				else
				{
					((Dialog*)GetParent())->GrabFocusToFirstControl();
				}
				bProc = sal_True;
			}
		}
		break;

		case KEY_F11:
		case KEY_TAB:
		{
			if( bSdrMode )
			{
				if( !aCode.IsMod1() && !aCode.IsMod2() )
				{
					bool bForward = !aCode.IsShift();
					// select next object
					if ( ! pView->MarkNextObj( bForward ))
                    {
                        // At first or last object.  Cycle to the other end
                        // of the list.
                        pView->UnmarkAllObj();
                        pView->MarkNextObj (bForward);
                    }
					bProc = sal_True;
				}
				else if(aCode.IsMod1())
				{
					// select next handle
					const SdrHdlList& rHdlList = pView->GetHdlList();
					sal_Bool bForward(!aCode.IsShift());

					((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);

					bProc = true;
				}
			}
		}
		break;

		case KEY_END:
		{

			if ( aCode.IsMod1() )
			{
				// #97016# mark last object
				pView->UnmarkAllObj();
				pView->MarkNextObj(sal_False);

				bProc = true;
			}
		}
		break;

		case KEY_HOME:
		{
			if ( aCode.IsMod1() )
			{
				pView->UnmarkAllObj();
				pView->MarkNextObj(sal_True);

				bProc = true;
			}
		}
		break;

		case KEY_UP:
		case KEY_DOWN:
		case KEY_LEFT:
		case KEY_RIGHT:
		{
			long nX = 0;
			long nY = 0;

			if (aCode.GetCode() == KEY_UP)
			{
				// Scroll nach oben
				nX = 0;
				nY =-1;
			}
			else if (aCode.GetCode() == KEY_DOWN)
			{
				// Scroll nach unten
				nX = 0;
				nY = 1;
			}
			else if (aCode.GetCode() == KEY_LEFT)
			{
				// Scroll nach links
				nX =-1;
				nY = 0;
			}
			else if (aCode.GetCode() == KEY_RIGHT)
			{
				// Scroll nach rechts
				nX = 1;
				nY = 0;
			}

			if (pView->AreObjectsMarked() && !aCode.IsMod1() )
			{
				if(aCode.IsMod2())
				{
					// #97016# move in 1 pixel distance
					Size aLogicSizeOnePixel = PixelToLogic(Size(1,1));
					nX *= aLogicSizeOnePixel.Width();
					nY *= aLogicSizeOnePixel.Height();
				}
				else
				{
					// old, fixed move distance
					nX *= 100;
					nY *= 100;
				}

				// #97016# II
				const SdrHdlList& rHdlList = pView->GetHdlList();
				SdrHdl* pHdl = rHdlList.GetFocusHdl();

				if(0L == pHdl)
				{
					// #90129# restrict movement to WorkArea
					const Rectangle& rWorkArea = pView->GetWorkArea();

					if(!rWorkArea.IsEmpty())
					{
						Rectangle aMarkRect(pView->GetMarkedObjRect());
						aMarkRect.Move(nX, nY);

						if(!aMarkRect.IsInside(rWorkArea))
						{
							if(aMarkRect.Left() < rWorkArea.Left())
							{
								nX += rWorkArea.Left() - aMarkRect.Left();
							}

							if(aMarkRect.Right() > rWorkArea.Right())
							{
								nX -= aMarkRect.Right() - rWorkArea.Right();
							}

							if(aMarkRect.Top() < rWorkArea.Top())
							{
								nY += rWorkArea.Top() - aMarkRect.Top();
							}

							if(aMarkRect.Bottom() > rWorkArea.Bottom())
							{
								nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
							}
						}
					}

					// no handle selected
					if(0 != nX || 0 != nY)
					{
						pView->MoveAllMarked(Size(nX, nY));
					}
				}
				else
				{
					// move handle with index nHandleIndex
					if(pHdl && (nX || nY))
					{
						// now move the Handle (nX, nY)
						Point aStartPoint(pHdl->GetPos());
						Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
						const SdrDragStat& rDragStat = pView->GetDragStat();

						// start dragging
						pView->BegDragObj(aStartPoint, 0, pHdl, 0);

					    if(pView->IsDragObj())
						{
							FASTBOOL bWasNoSnap = rDragStat.IsNoSnap();
							sal_Bool bWasSnapEnabled = pView->IsSnapEnabled();

							// switch snapping off
							if(!bWasNoSnap)
								((SdrDragStat&)rDragStat).SetNoSnap(sal_True);
							if(bWasSnapEnabled)
								pView->SetSnapEnabled(sal_False);

							pView->MovAction(aEndPoint);
							pView->EndDragObj();

							// restore snap
							if(!bWasNoSnap)
								((SdrDragStat&)rDragStat).SetNoSnap(bWasNoSnap);
							if(bWasSnapEnabled)
								pView->SetSnapEnabled(bWasSnapEnabled);
						}
					}
				}

				bProc = true;
			}
		}
		break;

		case KEY_SPACE:
		{
			const SdrHdlList& rHdlList = pView->GetHdlList();
			SdrHdl* pHdl = rHdlList.GetFocusHdl();

			if(pHdl)
			{
				if(pHdl->GetKind() == HDL_POLY)
				{
					// rescue ID of point with focus
					sal_uInt32 nPol(pHdl->GetPolyNum());
					sal_uInt32 nPnt(pHdl->GetPointNum());

					if(pView->IsPointMarked(pHdl))
					{
						if(rKEvt.GetKeyCode().IsShift())
						{
							pView->UnmarkPoint(*pHdl);
						}
					}
					else
					{
						if(!rKEvt.GetKeyCode().IsShift())
						{
							pView->UnmarkAllPoints();
						}

						pView->MarkPoint(*pHdl);
					}

					if(0L == rHdlList.GetFocusHdl())
					{
						// restore point with focus
						SdrHdl* pNewOne = 0L;

						for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++)
						{
							SdrHdl* pAct = rHdlList.GetHdl(a);

							if(pAct
								&& pAct->GetKind() == HDL_POLY
								&& pAct->GetPolyNum() == nPol
								&& pAct->GetPointNum() == nPnt)
							{
								pNewOne = pAct;
							}
						}

						if(pNewOne)
						{
							((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
						}
					}

					bProc = sal_True;
				}
			}
		}
		break;

		default:
		break;
	}

	if ( !bProc )
		Control::KeyInput( rKEvt );
	else
		ReleaseMouse();
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::MouseButtonDown( const MouseEvent& rMEvt )
{
	if ( bSdrMode && ( rMEvt.GetClicks() < 2 ) )
	{
		const Point aLogPt( PixelToLogic( rMEvt.GetPosPixel() ) );

		if ( !Rectangle( Point(), aGraphSize ).IsInside( aLogPt ) && !pView->IsEditMode() )
			Control::MouseButtonDown( rMEvt );
		else
		{
			// Focus anziehen fuer Key-Inputs
			GrabFocus();

			if ( nPolyEdit )
			{
				SdrViewEvent	aVEvt;
				SdrHitKind		eHit = pView->PickAnything( rMEvt, SDRMOUSEBUTTONDOWN, aVEvt );

				if ( nPolyEdit == SID_BEZIER_INSERT && eHit == SDRHIT_MARKEDOBJECT )
					pView->BegInsObjPoint( aLogPt, rMEvt.IsMod1());
				else
					pView->MouseButtonDown( rMEvt, this );
			}
			else
				pView->MouseButtonDown( rMEvt, this );
		}

		SdrObject* pCreateObj = pView->GetCreateObj();

		// Wir wollen das Inserten mitbekommen
		if ( pCreateObj && !pCreateObj->GetUserCall() )
			pCreateObj->SetUserCall( pUserCall );

		SetPointer( pView->GetPreferedPointer( aLogPt, this ) );
	}
	else
		Control::MouseButtonDown( rMEvt );
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::MouseMove(const MouseEvent& rMEvt)
{
	const Point	aLogPos( PixelToLogic( rMEvt.GetPosPixel() ) );

	if ( bSdrMode )
	{
		pView->MouseMove( rMEvt, this );

		if( ( SID_BEZIER_INSERT == nPolyEdit ) &&
			!pView->PickHandle( aLogPos ) &&
			!pView->IsInsObjPoint() )
		{
			SetPointer( POINTER_CROSS );
		}
		else
			SetPointer( pView->GetPreferedPointer( aLogPos, this ) );
	}
	else
		Control::MouseButtonUp( rMEvt );

	if ( aMousePosLink.IsSet() )
	{
		if ( Rectangle( Point(), aGraphSize ).IsInside( aLogPos ) )
			aMousePos = aLogPos;
		else
			aMousePos = Point();

		aMousePosLink.Call( this );
	}
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::MouseButtonUp(const MouseEvent& rMEvt)
{
	if ( bSdrMode )
	{
		if ( pView->IsInsObjPoint() )
			pView->EndInsObjPoint( SDRCREATE_FORCEEND );
		else
			pView->MouseButtonUp( rMEvt, this );

		ReleaseMouse();
		SetPointer( pView->GetPreferedPointer( PixelToLogic( rMEvt.GetPosPixel() ), this ) );
	}
	else
		Control::MouseButtonUp( rMEvt );
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

SdrObject* GraphCtrl::GetSelectedSdrObject() const
{
	SdrObject* pSdrObj = NULL;

	if ( bSdrMode )
	{
		const SdrMarkList&	rMarkList = pView->GetMarkedObjectList();

		if ( rMarkList.GetMarkCount() == 1 )
			pSdrObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
	}

	return pSdrObj;
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::SetEditMode( const sal_Bool _bEditMode )
{
	if ( bSdrMode )
	{
        bEditMode = _bEditMode;
		pView->SetEditMode( bEditMode );
        eObjKind = OBJ_NONE;
		pView->SetCurrentObj( sal::static_int_cast< sal_uInt16 >( eObjKind ) );
	}
	else
		bEditMode = sal_False;
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::SetPolyEditMode( const sal_uInt16 _nPolyEdit )
{
	if ( bSdrMode && ( _nPolyEdit != nPolyEdit ) )
	{
		nPolyEdit = _nPolyEdit;
		pView->SetFrameDragSingles( nPolyEdit == 0 );
	}
	else
		nPolyEdit = 0;
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

void GraphCtrl::SetObjKind( const SdrObjKind _eObjKind )
{
	if ( bSdrMode )
	{
        bEditMode = sal_False;
		pView->SetEditMode( bEditMode );
        eObjKind = _eObjKind;
		pView->SetCurrentObj( sal::static_int_cast< sal_uInt16 >( eObjKind ) );
	}
	else
		eObjKind = OBJ_NONE;
}


/*************************************************************************
|*
|*
|*
\************************************************************************/

String GraphCtrl::GetStringFromDouble( const double& rDouble )
{
    sal_Unicode cSep =
        SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0);
    String aStr( ::rtl::math::doubleToUString( rDouble,
                rtl_math_StringFormat_F, 2, cSep ));
    return aStr;
}


/*************************************************************************
www|*
|*
|*
\************************************************************************/

IMPL_LINK( GraphCtrl, UpdateHdl, Timer*, pTimer )
{
	if ( aUpdateLink.IsSet() )
		aUpdateLink.Call( this );

	pTimer->Start();

	return 0L;
}


::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > GraphCtrl::CreateAccessible()
{
	if( mpAccContext == NULL )
	{
		Window* pParent = GetParent();

		DBG_ASSERT( pParent, "-GraphCtrl::CreateAccessible(): No Parent!" );

		if( pParent )
		{
			::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAccParent( pParent->GetAccessible() );

            // #103856# Disable accessibility if no model/view data available
			if( pView &&
                pModel &&
                xAccParent.is() )
			{
				mpAccContext = new SvxGraphCtrlAccessibleContext( xAccParent, *this );
				mpAccContext->acquire();
			}
		}
	}

	return mpAccContext;
}
