/**************************************************************
 * 
 * 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_sc.hxx"


#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#include <com/sun/star/embed/Aspects.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

//------------------------------------------------------------------------

#include <toolkit/helper/vclunohelper.hxx>
#include <sot/exchange.hxx>
#include <svl/globalnameitem.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/docfile.hxx>
#include <svl/stritem.hxx>
#include <svx/svdoole2.hxx>
#include <svx/pfiledlg.hxx>
#include <tools/urlobj.hxx>
#include <vcl/msgbox.hxx>
#include <svl/urihelper.hxx>
#include <unotools/moduleoptions.hxx>
#include <svtools/insdlg.hxx>
#include <svtools/soerr.hxx>
#include <svx/svxdlg.hxx>
#include <sot/clsids.hxx>
#include <svx/svdpagv.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdundo.hxx>
#include <sfx2/msgpool.hxx>
#include <svx/charthelper.hxx>
#include <scmod.hxx>

// BM/IHA --
#include <cppuhelper/component_context.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/storagehelper.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <cppuhelper/bootstrap.hxx>

using namespace ::com::sun::star;
// BM/IHA --

// erAck
#include "chart2uno.hxx"
// erAck

#include "fuinsert.hxx"
#include "tabvwsh.hxx"
#include "sc.hrc"
#include "chartarr.hxx"
#include "docsh.hxx"
#include "document.hxx"
#include "undotab.hxx"
#include "chartlis.hxx"
#include "uiitems.hxx"
#include "globstr.hrc"
#include "drawview.hxx"

//------------------------------------------------------------------------

#define IS_AVAILABLE(WhichId,ppItem) \
    (pReqArgs->GetItemState((WhichId), sal_True, ppItem ) == SFX_ITEM_SET)

void lcl_ChartInit( const uno::Reference < embed::XEmbeddedObject >& xObj, ScViewData* pViewData,
                    const rtl::OUString& rRangeParam )
{
    ScDocShell* pDocShell = pViewData->GetDocShell();
    ScDocument* pScDoc = pDocShell->GetDocument();

    rtl::OUString aRangeString( rRangeParam );
    if ( !aRangeString.getLength() )
    {
        SCCOL nCol1 = 0;
        SCROW nRow1 = 0;
        SCTAB nTab1 = 0;
        SCCOL nCol2 = 0;
        SCROW nRow2 = 0;
        SCTAB nTab2 = 0;

        ScMarkData& rMark = pViewData->GetMarkData();
        if ( !rMark.IsMarked() )
            pViewData->GetView()->MarkDataArea( sal_True );

        if ( pViewData->GetSimpleArea( nCol1,nRow1,nTab1, nCol2,nRow2,nTab2 ) == SC_MARK_SIMPLE )
        {
            PutInOrder( nCol1, nCol2 );
            PutInOrder( nRow1, nRow2 );
            if ( nCol2>nCol1 || nRow2>nRow1 )
            {
                ScDocument* pDoc = pViewData->GetDocument();
                pDoc->LimitChartArea( nTab1, nCol1,nRow1, nCol2,nRow2 );

                String aStr;
                ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
                aRange.Format( aStr, SCR_ABS_3D, pScDoc );
                aRangeString = aStr;
            }
        }
    }

    if ( aRangeString.getLength() )
    {
        // connect to Calc data (if no range string, leave chart alone, with its own data)

        uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
        uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
        if( xCompSupp.is())
            xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );
        OSL_ASSERT( xReceiver.is());
        if( xReceiver.is() )
        {
            uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( pScDoc );
            xReceiver->attachDataProvider( xDataProvider );

            uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( pDocShell->GetModel(), uno::UNO_QUERY );
            xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );

            // Same behavior as with old chart: Always assume data series in columns
            chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS;
            bool bHasCategories = false;
            bool bFirstCellAsLabel = false;

            // use ScChartPositioner to auto-detect column/row headers (like ScChartArray in old version)
            ScRangeListRef aRangeListRef( new ScRangeList );
            aRangeListRef->Parse( aRangeString, pScDoc );
            if ( aRangeListRef->Count() )
            {
                pScDoc->LimitChartIfAll( aRangeListRef );               // limit whole columns/rows to used area

                // update string from modified ranges.  The ranges must be in the current formula syntax.
                String aTmpStr;
                aRangeListRef->Format( aTmpStr, SCR_ABS_3D, pScDoc, pScDoc->GetAddressConvention() );
                aRangeString = aTmpStr;

                ScChartPositioner aChartPositioner( pScDoc, aRangeListRef );
                const ScChartPositionMap* pPositionMap( aChartPositioner.GetPositionMap() );
                if( pPositionMap )
                {
                    SCSIZE nRowCount = pPositionMap->GetRowCount();
                    if( 1==nRowCount )
                        eDataRowSource = chart::ChartDataRowSource_ROWS;
                }
                if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS )
                {
                    bHasCategories = aChartPositioner.HasRowHeaders();
                    bFirstCellAsLabel = aChartPositioner.HasColHeaders();
                }
                else    // in case the default is changed
                {
                    bHasCategories = aChartPositioner.HasColHeaders();
                    bFirstCellAsLabel = aChartPositioner.HasRowHeaders();
                }
            }

            uno::Sequence< beans::PropertyValue > aArgs( 4 );
            aArgs[0] = beans::PropertyValue(
                ::rtl::OUString::createFromAscii("CellRangeRepresentation"), -1,
                uno::makeAny( aRangeString ), beans::PropertyState_DIRECT_VALUE );
            aArgs[1] = beans::PropertyValue(
                ::rtl::OUString::createFromAscii("HasCategories"), -1,
                uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE );
            aArgs[2] = beans::PropertyValue(
                ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1,
                uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE );
            aArgs[3] = beans::PropertyValue(
                ::rtl::OUString::createFromAscii("DataRowSource"), -1,
                uno::makeAny( eDataRowSource ), beans::PropertyState_DIRECT_VALUE );
            xReceiver->setArguments( aArgs );

            // don't create chart listener here (range may be modified in chart dialog)
        }
    }
}

/*************************************************************************
|*
|* FuInsertOLE::Konstruktor
|*
\************************************************************************/

FuInsertOLE::FuInsertOLE(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
		   SdrModel* pDoc, SfxRequest& rReq)
    : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
{
	if( ! rReq.IsAPI() )
		rReq.Done();

	//!	hier DLL's initalisieren, damit die Factories existieren?

    uno::Reference < embed::XEmbeddedObject > xObj;
    uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
	sal_Bool bIsFromFile = sal_False;
    ::rtl::OUString aName;

    sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
    ::rtl::OUString aIconMediaType;
    uno::Reference< io::XInputStream > xIconMetaFile;


	sal_uInt16 nSlot = rReq.GetSlot();
    SFX_REQUEST_ARG( rReq, pNameItem, SfxGlobalNameItem, SID_INSERT_OBJECT, sal_False );
    if ( nSlot == SID_INSERT_OBJECT && pNameItem )
	{
        SvGlobalName aClassName = pNameItem->GetValue();
        xObj = pViewShell->GetViewFrame()->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( aClassName.GetByteSequence(), aName );
    }
    else if ( nSlot == SID_INSERT_SMATH )
    {
        if ( SvtModuleOptions().IsMath() )
        {
            nSlot = SID_INSERT_OBJECT;
            xObj = pViewShell->GetViewFrame()->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SM_CLASSID_60 ).GetByteSequence(), aName );
            rReq.AppendItem( SfxGlobalNameItem( SID_INSERT_OBJECT, SvGlobalName( SO3_SM_CLASSID_60 ) ) );
        }
    }
    else
    {
        SvObjectServerList aServerLst;
        switch ( nSlot )
        {
            case SID_INSERT_OBJECT :
                aServerLst.FillInsertObjects();
                aServerLst.Remove( ScDocShell::Factory().GetClassId() );   // Starcalc nicht anzeigen
                //TODO/LATER: currently no inserting of ClassId into SfxRequest!
            case SID_INSERT_PLUGIN :
            case SID_INSERT_FLOATINGFRAME :
            {
                SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
                SfxAbstractInsertObjectDialog* pDlg =
                        pFact->CreateInsertObjectDialog( pViewShell->GetWindow(), SC_MOD()->GetSlotPool()->GetSlot(nSlot)->GetCommandString(),
                        xStorage, &aServerLst );
                if ( pDlg )
                {
                    pDlg->Execute();
                    xObj = pDlg->GetObject();

					xIconMetaFile = pDlg->GetIconIfIconified( &aIconMediaType );
					if ( xIconMetaFile.is() )
						nAspect = embed::Aspects::MSOLE_ICON;

                    if ( xObj.is() )
                        pViewSh->GetObjectShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
                    // damit DrawShell eingeschaltet wird (Objekt aktivieren ist unnoetig):
                    bIsFromFile = !pDlg->IsCreateNew();
                    DELETEZ( pDlg );
                }

                break;
            }
            case SID_INSERT_SOUND :
            case SID_INSERT_VIDEO :
            {
                // create special filedialog for plugins
                SvxPluginFileDlg aPluginFileDialog(pWin, nSlot);

                // open filedlg
                if ( ERRCODE_NONE == aPluginFileDialog.Execute() )
                {
                    // get URL
                    INetURLObject aURL;
                    aURL.SetSmartProtocol( INET_PROT_FILE );
                    if ( aURL.SetURL( aPluginFileDialog.GetPath() ) )
                    {
                        // create a plugin object
                        ::rtl::OUString aObjName;
                        SvGlobalName aClassId( SO3_PLUGIN_CLASSID );
                        comphelper::EmbeddedObjectContainer aCnt( xStorage );
                        xObj = aCnt.CreateEmbeddedObject( aClassId.GetByteSequence(), aObjName );
                        if ( xObj.is() && svt::EmbeddedObjectRef::TryRunningState( xObj ) )
                        {
                            // set properties from dialog
                            uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
                            if ( xSet.is() )
                            {
                                xSet->setPropertyValue( ::rtl::OUString::createFromAscii("PluginURL"),
                                        uno::makeAny( ::rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) );
                            }
                        }
                    }
                    else
                    {
                        DBG_ERROR("Invalid URL!");
                        //! error message
                        //! can this happen???
                    }
                }
            }
        }
    }

	//	SvInsertObjectDialog (alles in einem Dialog) wird nicht mehr benutzt
    if (xObj.is())
	{
		pView->UnmarkAll();

		try
		{
			::svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
			Size aSize;
			MapMode aMap100( MAP_100TH_MM );
			MapUnit aMapUnit = MAP_100TH_MM;

			if ( nAspect == embed::Aspects::MSOLE_ICON )
			{
				aObjRef.SetGraphicStream( xIconMetaFile, aIconMediaType );
				aSize = aObjRef.GetSize( &aMap100 );
			}
			else
			{
            	awt::Size aSz;
				try
				{
					aSz = xObj->getVisualAreaSize( nAspect );
				}
				catch( embed::NoVisualAreaSizeException& )
				{
					// the default size will be set later
				}

            	aSize = Size( aSz.Width, aSz.Height );

            	aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
            	if (aSize.Height() == 0 || aSize.Width() == 0)
            	{
                	// Rechteck mit ausgewogenem Kantenverhaeltnis
					aSize.Width() = 5000;
					aSize.Height() = 5000;
                	Size aTmp = OutputDevice::LogicToLogic( aSize, MAP_100TH_MM, aMapUnit );
                	aSz.Width = aTmp.Width();
                	aSz.Height = aTmp.Height();
                	xObj->setVisualAreaSize( nAspect, aSz );

                	//  re-convert aSize to 1/100th mm to avoid rounding errors in comparison below
                	aSize = Window::LogicToLogic( aTmp,
                                	MapMode( aMapUnit ), aMap100 );
				}
				else
					aSize = Window::LogicToLogic( aSize,
                                	MapMode( aMapUnit ), aMap100 );
			}

			//	Chart initialisieren ?
            if ( SvtModuleOptions().IsChart() && SotExchange::IsChart( SvGlobalName( xObj->getClassID() ) ) )
                lcl_ChartInit( xObj, pViewSh->GetViewData(), rtl::OUString() );

			ScViewData* pData = pViewSh->GetViewData();

			Point aPnt = pViewSh->GetInsertPos();
			if ( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
				aPnt.X() -= aSize.Width();		// move position to left edge
			Rectangle aRect (aPnt, aSize);
            SdrOle2Obj* pObj = new SdrOle2Obj( aObjRef, aName, aRect);
			SdrPageView* pPV = pView->GetSdrPageView();
			pView->InsertObjectAtView(pObj, *pPV);

			if ( nAspect != embed::Aspects::MSOLE_ICON )
			{
				//	#73279# Math objects change their object size during InsertObject.
				//	New size must be set in SdrObject, or a wrong scale will be set at
				//	ActivateObject.

				try
				{
            		awt::Size aSz = xObj->getVisualAreaSize( nAspect );

            		Size aNewSize( aSz.Width, aSz.Height );
            		aNewSize = OutputDevice::LogicToLogic( aNewSize, aMapUnit, MAP_100TH_MM );

            		if ( aNewSize != aSize )
					{
						aRect.SetSize( aNewSize );
						pObj->SetLogicRect( aRect );
					}
				}
				catch( embed::NoVisualAreaSizeException& )
				{}
			}

			if ( !rReq.IsAPI() )
			{
				// XXX Activate aus Makro ist toedlich !!! ???
				if (bIsFromFile)
				{
					// #45012# Objekt ist selektiert, also Draw-Shell aktivieren
					pViewShell->SetDrawShell( sal_True );
				}
				else
				{
					pViewShell->ActivateObject( (SdrOle2Obj*) pObj, SVVERB_SHOW );
				}
			}

			rReq.Done();
		}
		catch( uno::Exception& )
		{
			OSL_ASSERT( "May need error handling here!\n" );
		}
	}
	else
		rReq.Ignore();
}

/*************************************************************************
|*
|* FuInsertOLE::Destruktor
|*
\************************************************************************/

FuInsertOLE::~FuInsertOLE()
{
}

/*************************************************************************
|*
|* FuInsertOLE::Function aktivieren
|*
\************************************************************************/

void FuInsertOLE::Activate()
{
	FuPoor::Activate();
}

/*************************************************************************
|*
|* FuInsertOLE::Function deaktivieren
|*
\************************************************************************/

void FuInsertOLE::Deactivate()
{
	FuPoor::Deactivate();
}

/*************************************************************************
|*
|* FuInsertChart::Konstruktor
|*
\************************************************************************/

FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* pViewP,
		   SdrModel* pDoc, SfxRequest& rReq)
    : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
{
	const SfxItemSet*	pReqArgs	= rReq.GetArgs();

	if( ! rReq.IsAPI() )
		rReq.Done();

    if( SvtModuleOptions().IsChart() )
    {
        // ----------------------------------------
        // BM/IHA --

        // get range
        ::rtl::OUString aRangeString;
        ScRange aPositionRange;             // cell range for chart positioning
        if( pReqArgs )
        {
            const SfxPoolItem* pItem;
            if( IS_AVAILABLE( FN_PARAM_5, &pItem ) )
            aRangeString = ::rtl::OUString( ((const SfxStringItem*)pItem)->GetValue());

            aPositionRange = pViewSh->GetViewData()->GetCurPos();
        }
        else
        {
            ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
            bool bAutomaticMark = false;
            if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
            {
		        pViewSh->GetViewData()->GetView()->MarkDataArea( sal_True );
                bAutomaticMark = true;
            }

            ScMarkData aMultiMark( rMark );
            aMultiMark.MarkToMulti();

            ScRangeList aRanges;
            aMultiMark.FillRangeListWithMarks( &aRanges, sal_False );
            String aStr;
            ScDocument* pDocument = pViewSh->GetViewData()->GetDocument();
            aRanges.Format( aStr, SCR_ABS_3D, pDocument, pDocument->GetAddressConvention() );
            aRangeString = aStr;

            // get "total" range for positioning
            sal_uLong nCount = aRanges.Count();
            if ( nCount > 0 )
            {
                aPositionRange = *aRanges.GetObject(0);
                for (sal_uLong i=1; i<nCount; i++)
                    aPositionRange.ExtendTo( *aRanges.GetObject(i) );
            }

            if(bAutomaticMark)
                pViewSh->GetViewData()->GetView()->Unmark();
        }

        // ----------------------------------------
        // adapted old code
        pView->UnmarkAll();

        ::rtl::OUString aName;
        const sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;

        uno::Reference < embed::XEmbeddedObject > xObj =
            pViewShell->GetObjectShell()->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID_60 ).GetByteSequence(), aName );

        uno::Reference< ::com::sun::star::chart2::data::XDataReceiver > xReceiver;
        uno::Reference< embed::XComponentSupplier > xCompSupp( xObj, uno::UNO_QUERY );
        if( xCompSupp.is())
            xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY );

        // lock the model to suppress any internal updates
        uno::Reference< frame::XModel > xChartModel( xReceiver, uno::UNO_QUERY );
        if( xChartModel.is() )
            xChartModel->lockControllers();

        ScRangeListRef aDummy;
        Rectangle aMarkDest;
        SCTAB nMarkTab;
        sal_Bool bDrawRect = pViewShell->GetChartArea( aDummy, aMarkDest, nMarkTab );

        //	Objekt-Groesse
        awt::Size aSz = xObj->getVisualAreaSize( nAspect );
        Size aSize( aSz.Width, aSz.Height );

        MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );

        sal_Bool bSizeCh = sal_False;
        if (bDrawRect && !aMarkDest.IsEmpty())
        {
            aSize = aMarkDest.GetSize();
            bSizeCh = sal_True;
        }
        if (aSize.Height() <= 0 || aSize.Width() <= 0)
        {
            aSize.Width() = 5000;
            aSize.Height() = 5000;
            bSizeCh = sal_True;
        }
        if (bSizeCh)
        {
            aSize = Window::LogicToLogic( aSize, MapMode( MAP_100TH_MM ), MapMode( aMapUnit ) );
            aSz.Width = aSize.Width();
            aSz.Height = aSize.Height();
            xObj->setVisualAreaSize( nAspect, aSz );
        }

        ScViewData* pData = pViewSh->GetViewData();
        ScDocShell* pScDocSh = pData->GetDocShell();
        ScDocument* pScDoc	 = pScDocSh->GetDocument();
        sal_Bool bUndo (pScDoc->IsUndoEnabled());

        if( pReqArgs )
        {
            const SfxPoolItem* pItem;
            sal_uInt16 nToTable = 0;

            if( IS_AVAILABLE( FN_PARAM_4, &pItem ) )
            {
                if ( pItem->ISA( SfxUInt16Item ) )
                    nToTable = ((const SfxUInt16Item*)pItem)->GetValue();
                else if ( pItem->ISA( SfxBoolItem ) )
                {
                    //	#46033# in der idl fuer Basic steht FN_PARAM_4 als SfxBoolItem
                    //	-> wenn gesetzt, neue Tabelle, sonst aktuelle Tabelle

                    if ( ((const SfxBoolItem*)pItem)->GetValue() )
                        nToTable = static_cast<sal_uInt16>(pScDoc->GetTableCount());
                    else
                        nToTable = static_cast<sal_uInt16>(pData->GetTabNo());
                }
            }
            else
            {
                if (bDrawRect)
                    nToTable = static_cast<sal_uInt16>(nMarkTab);
                rReq.AppendItem( SfxUInt16Item( FN_PARAM_4, nToTable ) );
            }

            // auf neue Tabelle ausgeben?
            if ( nToTable == pScDoc->GetTableCount() )
            {
                // dann los...
                String		aTabName;
                SCTAB		nNewTab = pScDoc->GetTableCount();

                pScDoc->CreateValidTabName( aTabName );

                if ( pScDoc->InsertTab( nNewTab, aTabName ) )
                {
                    sal_Bool bAppend = sal_True;

                    if (bUndo)
                    {
                        pScDocSh->GetUndoManager()->AddUndoAction(
                            new ScUndoInsertTab( pScDocSh, nNewTab,
                                                 bAppend, aTabName ) );
                    }

                    pScDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nNewTab ) );
                    pViewSh->SetTabNo( nNewTab, sal_True );
                    pScDocSh->PostPaintExtras();			//! erst hinterher ???
                }
                else
                {
                    DBG_ERROR( "Could not create new table :-/" );
                }
            }
            else if ( nToTable != pData->GetTabNo() )
            {
                pViewSh->SetTabNo( nToTable, sal_True );
            }
        }

        lcl_ChartInit( xObj, pData, aRangeString );         // set source range, auto-detect column/row headers

        //	Objekt-Position

        Point aStart;
        if ( bDrawRect )
            aStart = aMarkDest.TopLeft();						// marked by hand
        else
        {
            // get chart position (from window size and data range)
            aStart = pViewSh->GetChartInsertPos( aSize, aPositionRange );
        }

        Rectangle aRect (aStart, aSize);
        SdrOle2Obj* pObj = new SdrOle2Obj( svt::EmbeddedObjectRef( xObj, nAspect ), aName, aRect);
        SdrPageView* pPV = pView->GetSdrPageView();

        // #121334# This call will change the chart's default background fill from white to transparent.
        // Add here again if this is wanted (see task description for details)
        // ChartHelper::AdaptDefaultsForChart( xObj );

//        pView->InsertObjectAtView(pObj, *pPV);//this call leads to an immidiate redraw and asks the chart for a visual representation

        // use the page instead of the view to insert, so no undo action is created yet
        SdrPage* pInsPage = pPV->GetPage();
        pInsPage->InsertObject( pObj );
        pView->UnmarkAllObj();
        pView->MarkObj( pObj, pPV );
        bool bAddUndo = true;               // add undo action later, unless the dialog is canceled

        if (rReq.IsAPI())
        {
            if( xChartModel.is() )
                xChartModel->unlockControllers();
        }
        else
        {
            //the controller will be unlocked by the dialog when the dialog is told to do so

            // only activate object if not called via API (e.g. macro)
            pViewShell->ActivateObject( (SdrOle2Obj*) pObj, SVVERB_SHOW );

            //open wizard
            //@todo get context from calc if that has one
            uno::Reference< uno::XComponentContext > xContext(
                ::cppu::defaultBootstrap_InitialComponentContext() );
            if(xContext.is())
            {
                uno::Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
                if(xMCF.is())
                {
                    uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
                        xMCF->createInstanceWithContext(
                            rtl::OUString::createFromAscii("com.sun.star.comp.chart2.WizardDialog")
                            , xContext), uno::UNO_QUERY);
                    uno::Reference< lang::XInitialization > xInit( xDialog, uno::UNO_QUERY );
                    if( xChartModel.is() && xInit.is() )
                    {
                        uno::Reference< awt::XWindow > xDialogParentWindow(0);
                        //	initialize dialog
                        uno::Sequence<uno::Any> aSeq(2);
                        uno::Any* pArray = aSeq.getArray();
                        beans::PropertyValue aParam1;
                        aParam1.Name = rtl::OUString::createFromAscii("ParentWindow");
                        aParam1.Value <<= uno::makeAny(xDialogParentWindow);
                        beans::PropertyValue aParam2;
                        aParam2.Name = rtl::OUString::createFromAscii("ChartModel");
                        aParam2.Value <<= uno::makeAny(xChartModel);
                        pArray[0] <<= uno::makeAny(aParam1);
                        pArray[1] <<= uno::makeAny(aParam2);
                        xInit->initialize( aSeq );

                        // try to set the dialog's position so it doesn't hide the chart
                        uno::Reference < beans::XPropertySet > xDialogProps( xDialog, uno::UNO_QUERY );
                        if ( xDialogProps.is() )
                        {
                            try
                            {
                                //get dialog size:
                                awt::Size aDialogAWTSize;
                                if( xDialogProps->getPropertyValue( ::rtl::OUString::createFromAscii("Size") )
                                    >>= aDialogAWTSize )
                                {
                                    Size aDialogSize( aDialogAWTSize.Width, aDialogAWTSize.Height );
                                    if ( aDialogSize.Width() > 0 && aDialogSize.Height() > 0 )
                                    {
                                        //calculate and set new position
                                        Point aDialogPos = pViewShell->GetChartDialogPos( aDialogSize, aRect );
                                        xDialogProps->setPropertyValue( ::rtl::OUString::createFromAscii("Position"),
                                            uno::makeAny( awt::Point(aDialogPos.getX(),aDialogPos.getY()) ) );
                                    }
                                }
                                //tell the dialog to unlock controller
                                xDialogProps->setPropertyValue( ::rtl::OUString::createFromAscii("UnlockControllersOnExecute"),
                                            uno::makeAny( sal_True ) );

                            }
                            catch( uno::Exception& )
		                    {
			                    OSL_ASSERT( "Chart wizard couldn't be positioned automatically\n" );
		                    }
                        }

                        sal_Int16 nDialogRet = xDialog->execute();
                        if( nDialogRet == ui::dialogs::ExecutableDialogResults::CANCEL )
                        {
                            // leave OLE inplace mode and unmark
                            OSL_ASSERT( pViewShell );
                            OSL_ASSERT( pView );
                            pViewShell->DeactivateOle();
                            pView->UnmarkAll();

                            // old page view pointer is invalid after switching sheets
                            pPV = pView->GetSdrPageView();

                            // remove the chart
                            OSL_ASSERT( pPV );
                            SdrPage * pPage( pPV->GetPage());
                            OSL_ASSERT( pPage );
                            OSL_ASSERT( pObj );
                            if( pPage )
                                pPage->RemoveObject( pObj->GetOrdNum());

                            bAddUndo = false;       // don't create the undo action for inserting

                            // leave the draw shell
                            pViewShell->SetDrawShell( sal_False );
                        }
                        else
                        {
                            OSL_ASSERT( nDialogRet == ui::dialogs::ExecutableDialogResults::OK );
                            //@todo maybe move chart to different table
                        }
                    }
                    uno::Reference< lang::XComponent > xComponent( xDialog, uno::UNO_QUERY );
                    if( xComponent.is())
                        xComponent->dispose();
                }
            }
        }

        if ( bAddUndo )
        {
            // add undo action the same way as in SdrEditView::InsertObjectAtView
            // (using UndoActionHdl etc.)
            pView->AddUndo(pDoc->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
        }

        // BM/IHA --
    }
}

/*************************************************************************
|*
|* FuInsertChart::Destruktor
|*
\************************************************************************/

FuInsertChart::~FuInsertChart()
{
}

/*************************************************************************
|*
|* FuInsertChart::Function aktivieren
|*
\************************************************************************/

void FuInsertChart::Activate()
{
	FuPoor::Activate();
}

/*************************************************************************
|*
|* FuInsertChart::Function deaktivieren
|*
\************************************************************************/

void FuInsertChart::Deactivate()
{
	FuPoor::Deactivate();
}


