/**************************************************************
 *
 * 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 "scitems.hxx"
#include <svx/fmdpage.hxx>
#include <svx/fmview.hxx>
#include <svx/svditer.hxx>
#include <svx/svdpage.hxx>
#include <svx/svxids.hrc>
#include <svx/unoshape.hxx>

#include <svl/numuno.hxx>
#include <svl/smplhint.hxx>
#include <unotools/undoopt.hxx>
#include <unotools/moduleoptions.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/linkmgr.hxx>
#include <sfx2/printer.hxx>
#include <sfx2/bindings.hxx>
#include <vcl/pdfextoutdevdata.hxx>
#include <vcl/waitobj.hxx>
#include <unotools/charclass.hxx>
#include <tools/multisel.hxx>
#include <tools/resary.hxx>
#include <toolkit/awt/vclxdevice.hxx>

#include <ctype.h>
#include <float.h> // DBL_MAX

#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/sheet/XNamedRanges.hpp>
#include <com/sun/star/sheet/XNamedRanges2.hpp>
#include <com/sun/star/sheet/XLabelRanges.hpp>
#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
#include <com/sun/star/reflection/XIdlClassProvider.hpp>
#include <comphelper/processfactory.hxx>

#include "docuno.hxx"
#include "cellsuno.hxx"
#include "nameuno.hxx"
#include "datauno.hxx"
#include "miscuno.hxx"
#include "notesuno.hxx"
#include "styleuno.hxx"
#include "linkuno.hxx"
#include "servuno.hxx"
#include "targuno.hxx"
#include "convuno.hxx"
#include "optuno.hxx"
#include "forbiuno.hxx"
#include "docsh.hxx"
#include "hints.hxx"
#include "docfunc.hxx"
#include "dociter.hxx"
#include "cell.hxx"
#include "drwlayer.hxx"
#include "rangeutl.hxx"
#include "markdata.hxx"
#include "docoptio.hxx"
#include "scextopt.hxx"
#include "unoguard.hxx"
#include "unonames.hxx"
#include "shapeuno.hxx"
#include "viewuno.hxx"
#include "tabvwsh.hxx"
#include "printfun.hxx"
#include "pfuncache.hxx"
#include "scmod.hxx"
#include "rangeutl.hxx"
#include "ViewSettingsSequenceDefines.hxx"
#include "sheetevents.hxx"
#include "sc.hrc"
#include "scresid.hxx"

using namespace com::sun::star;

// #i111553# provides the name of the VBA constant for this document type (e.g. 'ThisExcelDoc' for Calc)
#define SC_UNO_VBAGLOBNAME "VBAGlobalConstantName"

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

//	alles ohne Which-ID, Map nur für PropertySetInfo

//!	umbenennen, sind nicht mehr nur Options
const SfxItemPropertyMapEntry* lcl_GetDocOptPropertyMap()
{
    static SfxItemPropertyMapEntry aDocOptPropertyMap_Impl[] =
	{
        {MAP_CHAR_LEN(SC_UNO_APPLYFMDES),        0, &getBooleanCppuType(),									  0, 0},
        {MAP_CHAR_LEN(SC_UNO_AREALINKS),         0, &getCppuType((uno::Reference<sheet::XAreaLinks>*)0),      0, 0},
        {MAP_CHAR_LEN(SC_UNO_AUTOCONTFOC),       0, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_BASICLIBRARIES),    0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN(SC_UNO_DIALOGLIBRARIES),   0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN(SC_UNO_VBAGLOBNAME),       0, &getCppuType(static_cast< const rtl::OUString * >(0)),    beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN(SC_UNO_CALCASSHOWN),       PROP_UNO_CALCASSHOWN, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
        {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
        {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),        0, &getCppuType((lang::Locale*)0),                           0, 0},
        {MAP_CHAR_LEN(SC_UNO_COLLABELRNG),       0, &getCppuType((uno::Reference<sheet::XLabelRanges>*)0),    0, 0},
        {MAP_CHAR_LEN(SC_UNO_DDELINKS),          0, &getCppuType((uno::Reference<container::XNameAccess>*)0), 0, 0},
        {MAP_CHAR_LEN(SC_UNO_DEFTABSTOP),        PROP_UNO_DEFTABSTOP, &getCppuType((sal_Int16*)0),                              0, 0},
        {MAP_CHAR_LEN(SC_UNO_EXTERNALDOCLINKS),  0, &getCppuType((uno::Reference<sheet::XExternalDocLinks>*)0), 0, 0},
        {MAP_CHAR_LEN(SC_UNO_FORBIDDEN),         0, &getCppuType((uno::Reference<i18n::XForbiddenCharacters>*)0), beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN(SC_UNO_HASDRAWPAGES),      0, &getBooleanCppuType(),                                    beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN(SC_UNO_IGNORECASE),        PROP_UNO_IGNORECASE, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_ITERENABLED),       PROP_UNO_ITERENABLED, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_ITERCOUNT),         PROP_UNO_ITERCOUNT, &getCppuType((sal_Int32*)0),                              0, 0},
        {MAP_CHAR_LEN(SC_UNO_ITEREPSILON),       PROP_UNO_ITEREPSILON, &getCppuType((double*)0),                                 0, 0},
        {MAP_CHAR_LEN(SC_UNO_LOOKUPLABELS),      PROP_UNO_LOOKUPLABELS, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_MATCHWHOLE),        PROP_UNO_MATCHWHOLE, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_NAMEDRANGES),       0, &getCppuType((uno::Reference<sheet::XNamedRanges>*)0),    0, 0},
        {MAP_CHAR_LEN(SC_UNO_NAMEDRANGES2),       0, &getCppuType((uno::Reference<sheet::XNamedRanges2>*)0),    0, 0},
        {MAP_CHAR_LEN(SC_UNO_DATABASERNG),       0, &getCppuType((uno::Reference<sheet::XDatabaseRanges>*)0), 0, 0},
        {MAP_CHAR_LEN(SC_UNO_NULLDATE),          PROP_UNO_NULLDATE, &getCppuType((util::Date*)0),                             0, 0},
        {MAP_CHAR_LEN(SC_UNO_ROWLABELRNG),       0, &getCppuType((uno::Reference<sheet::XLabelRanges>*)0),    0, 0},
        {MAP_CHAR_LEN(SC_UNO_SHEETLINKS),        0, &getCppuType((uno::Reference<container::XNameAccess>*)0), 0, 0},
        {MAP_CHAR_LEN(SC_UNO_SPELLONLINE),       PROP_UNO_SPELLONLINE, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_STANDARDDEC),       PROP_UNO_STANDARDDEC, &getCppuType((sal_Int16*)0),                              0, 0},
        {MAP_CHAR_LEN(SC_UNO_REGEXENABLED),      PROP_UNO_REGEXENABLED, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_RUNTIMEUID),        0, &getCppuType(static_cast< const rtl::OUString * >(0)),    beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN(SC_UNO_HASVALIDSIGNATURES),0, &getBooleanCppuType(),                                    beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN(SC_UNO_ISLOADED),          0, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_ISUNDOENABLED),     0, &getBooleanCppuType(),                                    0, 0},
        {MAP_CHAR_LEN(SC_UNO_ISADJUSTHEIGHTENABLED), 0, &getBooleanCppuType(),                                0, 0},
        {MAP_CHAR_LEN(SC_UNO_ISEXECUTELINKENABLED), 0, &getBooleanCppuType(),                                 0, 0},
        {MAP_CHAR_LEN(SC_UNO_ISCHANGEREADONLYENABLED), 0, &getBooleanCppuType(),                              0, 0},
        {MAP_CHAR_LEN(SC_UNO_REFERENCEDEVICE),   0, &getCppuType((uno::Reference<awt::XDevice>*)0),           beans::PropertyAttribute::READONLY, 0},
        {MAP_CHAR_LEN("BuildId"),                0, &::getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0},
        {MAP_CHAR_LEN(SC_UNO_CODENAME),        0, &getCppuType(static_cast< const rtl::OUString * >(0)),    0, 0},

        {0,0,0,0,0,0}
	};
	return aDocOptPropertyMap_Impl;
}

//!	StandardDecimals als Property und vom NumberFormatter ????????

const SfxItemPropertyMapEntry* lcl_GetColumnsPropertyMap()
{
    static SfxItemPropertyMapEntry aColumnsPropertyMap_Impl[] =
	{
		{MAP_CHAR_LEN(SC_UNONAME_MANPAGE),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_NEWPAGE),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_CELLVIS),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_OWIDTH),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_CELLWID),	0,	&getCppuType((sal_Int32*)0),	0, 0 },
        {0,0,0,0,0,0}
	};
	return aColumnsPropertyMap_Impl;
}

const SfxItemPropertyMapEntry* lcl_GetRowsPropertyMap()
{
    static SfxItemPropertyMapEntry aRowsPropertyMap_Impl[] =
	{
		{MAP_CHAR_LEN(SC_UNONAME_CELLHGT),	0,	&getCppuType((sal_Int32*)0),	0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_CELLFILT),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_OHEIGHT),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_MANPAGE),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_NEWPAGE),	0,	&getBooleanCppuType(),			0, 0 },
		{MAP_CHAR_LEN(SC_UNONAME_CELLVIS),	0,	&getBooleanCppuType(),			0, 0 },
        {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND, &::getCppuType((const sal_Int32*)0), 0, MID_BACK_COLOR },
        {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND, &::getBooleanCppuType(), 0, MID_GRAPHIC_TRANSPARENT },
        // not sorted, not used with SfxItemPropertyMapEntry::GetByName
        {0,0,0,0,0,0}
	};
	return aRowsPropertyMap_Impl;
}

//!	move these functions to a header file
inline long TwipsToHMM(long nTwips)	{ return (nTwips * 127 + 36) / 72; }
inline long HMMToTwips(long nHMM)	{ return (nHMM * 72 + 63) / 127; }

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

#define SCMODELOBJ_SERVICE			"com.sun.star.sheet.SpreadsheetDocument"
#define SCDOCSETTINGS_SERVICE		"com.sun.star.sheet.SpreadsheetDocumentSettings"
#define SCDOC_SERVICE				"com.sun.star.document.OfficeDocument"

SC_SIMPLE_SERVICE_INFO( ScAnnotationsObj, "ScAnnotationsObj", "com.sun.star.sheet.CellAnnotations" )
SC_SIMPLE_SERVICE_INFO( ScDrawPagesObj, "ScDrawPagesObj", "com.sun.star.drawing.DrawPages" )
SC_SIMPLE_SERVICE_INFO( ScScenariosObj, "ScScenariosObj", "com.sun.star.sheet.Scenarios" )
SC_SIMPLE_SERVICE_INFO( ScSpreadsheetSettingsObj, "ScSpreadsheetSettingsObj", "com.sun.star.sheet.SpreadsheetDocumentSettings" )
SC_SIMPLE_SERVICE_INFO( ScTableColumnsObj, "ScTableColumnsObj", "com.sun.star.table.TableColumns" )
SC_SIMPLE_SERVICE_INFO( ScTableRowsObj, "ScTableRowsObj", "com.sun.star.table.TableRows" )
SC_SIMPLE_SERVICE_INFO( ScTableSheetsObj, "ScTableSheetsObj", "com.sun.star.sheet.Spreadsheets" )

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

class ScPrintUIOptions : public vcl::PrinterOptionsHelper
{
public:
    ScPrintUIOptions();
    void SetDefaults();
};

ScPrintUIOptions::ScPrintUIOptions()
{
    const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
    sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
    sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();

    ResStringArray aStrings( ScResId( SCSTR_PRINT_OPTIONS ) );
    DBG_ASSERT( aStrings.Count() >= 10, "resource incomplete" );
    if( aStrings.Count() < 10 ) // bad resource ?
        return;

    m_aUIProperties.realloc( 8 );

    // create Section for spreadsheet (results in an extra tab page in dialog)
    SvtModuleOptions aOpt;
    String aAppGroupname( aStrings.GetString( 9 ) );
    aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ),
                                    aOpt.GetModuleName( SvtModuleOptions::E_SCALC ) );
    m_aUIProperties[0].Value = getGroupControlOpt( aAppGroupname, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:TabPage:AppPage" ) ) );

    // create subgroup for pages
    m_aUIProperties[1].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 0 ) ), rtl::OUString() );

    // create a bool option for empty pages
    m_aUIProperties[2].Value = getBoolControlOpt( rtl::OUString( aStrings.GetString( 1 ) ),
                                                  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:IsIncludeEmptyPages:CheckBox" ) ),
                                                  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsIncludeEmptyPages" ) ),
                                                  ! bSuppress
                                                  );
    // create Subgroup for print content
    vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
    aPrintRangeOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
    m_aUIProperties[3].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 2 ) ),
                                                      rtl::OUString(),
                                                      aPrintRangeOpt
                                                      );

    // create a choice for the content to create
    uno::Sequence< rtl::OUString > aChoices( 3 ), aHelpIds( 3 );
    aChoices[0] = aStrings.GetString( 3 );
    aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0" ) );
    aChoices[1] = aStrings.GetString( 4 );
    aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1" ) );
    aChoices[2] = aStrings.GetString( 5 );
    aHelpIds[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:2" ) );
    m_aUIProperties[4].Value = getChoiceControlOpt( rtl::OUString(),
                                                    aHelpIds,
                                                    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ),
                                                    aChoices,
                                                    nContent );

    // create Subgroup for print range
    aPrintRangeOpt.mbInternalOnly = sal_True;
    m_aUIProperties[5].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 6 ) ),
                                                      rtl::OUString(),
                                                      aPrintRangeOpt
                                                      );

    // create a choice for the range to print
    rtl::OUString aPrintRangeName( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
    aChoices.realloc( 2 );
    aHelpIds.realloc( 2 );
    aChoices[0] = aStrings.GetString( 7 );
    aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintRange:RadioButton:0" ) );
    aChoices[1] = aStrings.GetString( 8 );
    aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintRange:RadioButton:1" ) );
    m_aUIProperties[6].Value = getChoiceControlOpt( rtl::OUString(),
                                                    aHelpIds,
                                                    aPrintRangeName,
                                                    aChoices,
                                                    0 );

    // create a an Edit dependent on "Pages" selected
    vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, sal_True );
    m_aUIProperties[7].Value = getEditControlOpt( rtl::OUString(),
                                                  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PageRange:Edit" ) ),
                                                  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ),
                                                  rtl::OUString(),
                                                  aPageRangeOpt
                                                  );
}

void ScPrintUIOptions::SetDefaults()
{
    // re-initialize the default values from print options

    const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
    sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
    sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();

    for (sal_Int32 nUIPos=0; nUIPos<m_aUIProperties.getLength(); ++nUIPos)
    {
        uno::Sequence<beans::PropertyValue> aUIProp;
        if ( m_aUIProperties[nUIPos].Value >>= aUIProp )
        {
            for (sal_Int32 nPropPos=0; nPropPos<aUIProp.getLength(); ++nPropPos)
            {
                rtl::OUString aName = aUIProp[nPropPos].Name;
                if ( aName.equalsAscii("Property") )
                {
                    beans::PropertyValue aPropertyValue;
                    if ( aUIProp[nPropPos].Value >>= aPropertyValue )
                    {
                        if ( aPropertyValue.Name.equalsAscii( "PrintContent" ) )
                        {
                            aPropertyValue.Value <<= nContent;
                            aUIProp[nPropPos].Value <<= aPropertyValue;
                        }
                        else if ( aPropertyValue.Name.equalsAscii( "IsIncludeEmptyPages" ) )
                        {
                            ScUnoHelpFunctions::SetBoolInAny( aPropertyValue.Value, ! bSuppress );
                            aUIProp[nPropPos].Value <<= aPropertyValue;
                        }
                    }
                }
            }
            m_aUIProperties[nUIPos].Value <<= aUIProp;
        }
    }
}

// static
void ScModelObj::CreateAndSet(ScDocShell* pDocSh)
{
	if (pDocSh)
		pDocSh->SetBaseModel( new ScModelObj(pDocSh) );
}

ScModelObj::ScModelObj( ScDocShell* pDocSh ) :
	SfxBaseModel( pDocSh ),
	aPropSet( lcl_GetDocOptPropertyMap() ),
	pDocShell( pDocSh ),
    pPrintFuncCache( NULL ),
    pPrinterOptions( NULL ),
    maChangesListeners( m_aMutex )
{
	// pDocShell may be NULL if this is the base of a ScDocOptionsObj
	if ( pDocShell )
	{
		pDocShell->GetDocument()->AddUnoObject(*this); // SfxModel is derived from SfxListener
	}
}

ScModelObj::~ScModelObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);

	if (xNumberAgg.is())
		xNumberAgg->setDelegator(uno::Reference<uno::XInterface>());

	delete pPrintFuncCache;
    delete pPrinterOptions;
}

uno::Reference< uno::XAggregation> ScModelObj::GetFormatter()
{
    // pDocShell may be NULL if this is the base of a ScDocOptionsObj
    if ( !xNumberAgg.is() && pDocShell )
    {
        // setDelegator verändert den RefCount, darum eine Referenz selber halten
		// (direkt am m_refCount, um sich beim release nicht selbst zu löschen)
		comphelper::increment( m_refCount );
        // während des queryInterface braucht man ein Ref auf das
		// SvNumberFormatsSupplierObj, sonst wird es gelöscht.
		uno::Reference<util::XNumberFormatsSupplier> xFormatter(new SvNumberFormatsSupplierObj(pDocShell->GetDocument()->GetFormatTable() ));
		{
			xNumberAgg.set(uno::Reference<uno::XAggregation>( xFormatter, uno::UNO_QUERY ));
			// extra block to force deletion of the temporary before setDelegator
		}

		// beim setDelegator darf die zusätzliche Ref nicht mehr existieren
		xFormatter = NULL;

		if (xNumberAgg.is())
			xNumberAgg->setDelegator( (cppu::OWeakObject*)this );
        comphelper::decrement( m_refCount );
    } // if ( !xNumberAgg.is() )
    return xNumberAgg;
}

ScDocument* ScModelObj::GetDocument() const
{
	if (pDocShell)
		return pDocShell->GetDocument();
	return NULL;
}

SfxObjectShell* ScModelObj::GetEmbeddedObject() const
{
	return pDocShell;
}

void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark, bool bCalcOutputFactor)
{
    if (pDocShell)
    {
        if (bCalcOutputFactor)
            pDocShell->CalcOutputFactor();
        pDocShell->UpdateAllRowHeights(pTabMark);
    }
}

void ScModelObj::BeforeXMLLoading()
{
	if (pDocShell)
		pDocShell->BeforeXMLLoading();
}

void ScModelObj::AfterXMLLoading(sal_Bool bRet)
{
	if (pDocShell)
		pDocShell->AfterXMLLoading(bRet);
}

ScSheetSaveData* ScModelObj::GetSheetSaveData()
{
    if (pDocShell)
        return pDocShell->GetSheetSaveData();
    return NULL;
}

void ScModelObj::RepaintRange( const ScRange& rRange )
{
    if (pDocShell)
        pDocShell->PostPaint( rRange, PAINT_GRID );
}

uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType )
												throw(uno::RuntimeException)
{
	SC_QUERYINTERFACE( sheet::XSpreadsheetDocument )
	SC_QUERYINTERFACE( document::XActionLockable )
	SC_QUERYINTERFACE( sheet::XCalculatable )
	SC_QUERYINTERFACE( util::XProtectable )
	SC_QUERYINTERFACE( drawing::XDrawPagesSupplier )
	SC_QUERYINTERFACE( sheet::XGoalSeek )
	SC_QUERYINTERFACE( sheet::XConsolidatable )
	SC_QUERYINTERFACE( sheet::XDocumentAuditing )
	SC_QUERYINTERFACE( style::XStyleFamiliesSupplier )
	SC_QUERYINTERFACE( view::XRenderable )
	SC_QUERYINTERFACE( document::XLinkAuthorizer )
	SC_QUERYINTERFACE( document::XLinkTargetSupplier )
	SC_QUERYINTERFACE( beans::XPropertySet )
	SC_QUERYINTERFACE( lang::XMultiServiceFactory )
	SC_QUERYINTERFACE( lang::XServiceInfo )
    SC_QUERYINTERFACE( util::XChangesNotifier )

	uno::Any aRet(SfxBaseModel::queryInterface( rType ));
    if ( !aRet.hasValue()
        && rType != ::getCppuType((uno::Reference< com::sun::star::document::XDocumentEventBroadcaster>*)0)
        && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XController>*)0)
        && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XFrame>*)0)
        && rType != ::getCppuType((uno::Reference< com::sun::star::script::XInvocation>*)0)
        && rType != ::getCppuType((uno::Reference< com::sun::star::reflection::XIdlClassProvider>*)0)
        && rType != ::getCppuType((uno::Reference< com::sun::star::beans::XFastPropertySet>*)0)
        && rType != ::getCppuType((uno::Reference< com::sun::star::awt::XWindow>*)0))
    {
        GetFormatter();
	    if ( xNumberAgg.is() )
		    aRet = xNumberAgg->queryAggregation( rType );
    }

	return aRet;
}

void SAL_CALL ScModelObj::acquire() throw()
{
	SfxBaseModel::acquire();
}

void SAL_CALL ScModelObj::release() throw()
{
	SfxBaseModel::release();
}

uno::Sequence<uno::Type> SAL_CALL ScModelObj::getTypes() throw(uno::RuntimeException)
{
	static uno::Sequence<uno::Type> aTypes;
	if ( aTypes.getLength() == 0 )
	{
		uno::Sequence<uno::Type> aParentTypes(SfxBaseModel::getTypes());
		long nParentLen = aParentTypes.getLength();
		const uno::Type* pParentPtr = aParentTypes.getConstArray();

		uno::Sequence<uno::Type> aAggTypes;
		if ( GetFormatter().is() )
		{
			const uno::Type& rProvType = ::getCppuType((uno::Reference<lang::XTypeProvider>*) 0);
			uno::Any aNumProv(xNumberAgg->queryAggregation(rProvType));
			if(aNumProv.getValueType() == rProvType)
			{
				uno::Reference<lang::XTypeProvider> xNumProv(
					*(uno::Reference<lang::XTypeProvider>*)aNumProv.getValue());
				aAggTypes = xNumProv->getTypes();
			}
		}
		long nAggLen = aAggTypes.getLength();
		const uno::Type* pAggPtr = aAggTypes.getConstArray();

		const long nThisLen = 16;
		aTypes.realloc( nParentLen + nAggLen + nThisLen );
		uno::Type* pPtr = aTypes.getArray();
		pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheetDocument>*)0);
		pPtr[nParentLen + 1] = getCppuType((const uno::Reference<document::XActionLockable>*)0);
		pPtr[nParentLen + 2] = getCppuType((const uno::Reference<sheet::XCalculatable>*)0);
		pPtr[nParentLen + 3] = getCppuType((const uno::Reference<util::XProtectable>*)0);
		pPtr[nParentLen + 4] = getCppuType((const uno::Reference<drawing::XDrawPagesSupplier>*)0);
		pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XGoalSeek>*)0);
		pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XConsolidatable>*)0);
		pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XDocumentAuditing>*)0);
		pPtr[nParentLen + 8] = getCppuType((const uno::Reference<style::XStyleFamiliesSupplier>*)0);
		pPtr[nParentLen + 9] = getCppuType((const uno::Reference<view::XRenderable>*)0);
		pPtr[nParentLen +10] = getCppuType((const uno::Reference<document::XLinkAuthorizer>*)0);
		pPtr[nParentLen +11] = getCppuType((const uno::Reference<document::XLinkTargetSupplier>*)0);
		pPtr[nParentLen +12] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
		pPtr[nParentLen +13] = getCppuType((const uno::Reference<lang::XMultiServiceFactory>*)0);
		pPtr[nParentLen +14] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
		pPtr[nParentLen +15] = getCppuType((const uno::Reference<util::XChangesNotifier>*)0);

		long i;
		for (i=0; i<nParentLen; i++)
			pPtr[i] = pParentPtr[i]; // parent types first

		for (i=0; i<nAggLen; i++)
			pPtr[nParentLen+nThisLen+i] = pAggPtr[i]; // aggregated types last
	}
	return aTypes;
}

uno::Sequence<sal_Int8> SAL_CALL ScModelObj::getImplementationId()
													throw(uno::RuntimeException)
{
	static uno::Sequence< sal_Int8 > aId;
	if( aId.getLength() == 0 )
	{
		aId.realloc( 16 );
		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
	}
	return aId;
}

void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
	//	Not interested in reference update hints here

	if ( rHint.ISA( SfxSimpleHint ) )
	{
		sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
		if ( nId == SFX_HINT_DYING )
		{
			pDocShell = NULL; // has become invalid
			if (xNumberAgg.is())
			{
				SvNumberFormatsSupplierObj* pNumFmt =
					SvNumberFormatsSupplierObj::getImplementation(
						uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) );
				if ( pNumFmt )
					pNumFmt->SetNumberFormatter( NULL );
			}

			DELETEZ( pPrintFuncCache ); // must be deleted because it has a pointer to the DocShell
		}
		else if ( nId == SFX_HINT_DATACHANGED )
		{
			//	cached data for rendering become invalid when contents change
			//	(if a broadcast is added to SetDrawModified, is has to be tested here, too)

			DELETEZ( pPrintFuncCache );

            // handle "OnCalculate" sheet events (search also for VBA event handlers)
            if ( pDocShell )
            {
                ScDocument* pDoc = pDocShell->GetDocument();
                if ( pDoc->GetVbaEventProcessor().is() )
                {
                    // If the VBA event processor is set, HasAnyCalcNotification is much faster than HasAnySheetEventScript
                    if ( pDoc->HasAnyCalcNotification() && pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) )
                        HandleCalculateEvents();
                }
                else
                {
                    if ( pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE ) )
                        HandleCalculateEvents();
                }
            }
		}
	}
	else if ( rHint.ISA( ScPointerChangedHint ) )
	{
		sal_uInt16 nFlags = ((const ScPointerChangedHint&)rHint).GetFlags();
		if (nFlags & SC_POINTERCHANGED_NUMFMT)
		{
			//	NumberFormatter-Pointer am Uno-Objekt neu setzen

			if (GetFormatter().is())
			{
				SvNumberFormatsSupplierObj* pNumFmt =
					SvNumberFormatsSupplierObj::getImplementation(
						uno::Reference<util::XNumberFormatsSupplier>(xNumberAgg, uno::UNO_QUERY) );
				if ( pNumFmt && pDocShell )
					pNumFmt->SetNumberFormatter( pDocShell->GetDocument()->GetFormatTable() );
			}
		}
	}

    // always call parent - SfxBaseModel might need to handle the same hints again
    SfxBaseModel::Notify( rBC, rHint );     // SfxBaseModel is derived from SfxListener
}

// XSpreadsheetDocument

uno::Reference<sheet::XSpreadsheets> SAL_CALL ScModelObj::getSheets() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return new ScTableSheetsObj(pDocShell);
	return NULL;
}

// XStyleFamiliesSupplier

uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getStyleFamilies()
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return new ScStyleFamiliesObj(pDocShell);
	return NULL;
}

// XRenderable

OutputDevice* lcl_GetRenderDevice( const uno::Sequence<beans::PropertyValue>& rOptions )
{
	OutputDevice* pRet = NULL;
	const beans::PropertyValue* pPropArray = rOptions.getConstArray();
	long nPropCount = rOptions.getLength();
	for (long i = 0; i < nPropCount; i++)
	{
		const beans::PropertyValue& rProp = pPropArray[i];
		String aPropName(rProp.Name);

		if (aPropName.EqualsAscii( SC_UNONAME_RENDERDEV ))
		{
			uno::Reference<awt::XDevice> xRenderDevice(rProp.Value, uno::UNO_QUERY);
			if ( xRenderDevice.is() )
			{
				VCLXDevice* pDevice = VCLXDevice::GetImplementation( xRenderDevice );
				if ( pDevice )
				{
					pRet = pDevice->GetOutputDevice();
					pRet->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
				}
			}
		}
	}
	return pRet;
}

bool lcl_ParseTarget( const String& rTarget, ScRange& rTargetRange, Rectangle& rTargetRect,
                        bool& rIsSheet, ScDocument* pDoc, SCTAB nSourceTab )
{
    // test in same order as in SID_CURRENTCELL execute

    ScAddress aAddress;
    ScRangeUtil aRangeUtil;
    SCTAB nNameTab;
    sal_Int32 nNumeric = 0;

    bool bRangeValid = false;
    bool bRectValid = false;

    if ( rTargetRange.Parse( rTarget, pDoc ) & SCA_VALID )
    {
        bRangeValid = true;             // range reference
    }
    else if ( aAddress.Parse( rTarget, pDoc ) & SCA_VALID )
    {
        rTargetRange = aAddress;
        bRangeValid = true;             // cell reference
    }
    else if ( aRangeUtil.MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange, RUTL_NAMES ) ||
              aRangeUtil.MakeRangeFromName( rTarget, pDoc, nSourceTab, rTargetRange, RUTL_DBASE ) )
    {
        bRangeValid = true;             // named range or database range
    }
    else if ( ByteString( rTarget, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() &&
              ( nNumeric = rTarget.ToInt32() ) > 0 && nNumeric <= MAXROW+1 )
    {
        // row number is always mapped to cell A(row) on the same sheet
        rTargetRange = ScAddress( 0, (SCROW)(nNumeric-1), nSourceTab ); // target row number is 1-based
        bRangeValid = true;             // row number
    }
    else if ( pDoc->GetTable( rTarget, nNameTab ) )
    {
        rTargetRange = ScAddress(0,0,nNameTab);
        bRangeValid = true;             // sheet name
        rIsSheet = true;                // needs special handling (first page of the sheet)
    }
    else
    {
        // look for named drawing object

        ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
        if ( pDrawLayer )
        {
            SCTAB nTabCount = pDoc->GetTableCount();
            for (SCTAB i=0; i<nTabCount && !bRangeValid; i++)
            {
                SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
                DBG_ASSERT(pPage,"Page ?");
                if (pPage)
                {
                    SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
                    SdrObject* pObject = aIter.Next();
                    while (pObject && !bRangeValid)
                    {
                        if ( ScDrawLayer::GetVisibleName( pObject ) == rTarget )
                        {
                            rTargetRect = pObject->GetLogicRect();              // 1/100th mm
                            rTargetRange = pDoc->GetRange( i, rTargetRect );    // underlying cells
                            bRangeValid = bRectValid = true;                    // rectangle is valid
                        }
                        pObject = aIter.Next();
                    }
                }
            }
        }
    }
    if ( bRangeValid && !bRectValid )
    {
        //  get rectangle for cell range
        rTargetRect = pDoc->GetMMRect( rTargetRange.aStart.Col(), rTargetRange.aStart.Row(),
                                       rTargetRange.aEnd.Col(),   rTargetRange.aEnd.Row(),
                                       rTargetRange.aStart.Tab() );
    }

    return bRangeValid;
}

sal_Bool ScModelObj::FillRenderMarkData( const uno::Any& aSelection,
                                     const uno::Sequence< beans::PropertyValue >& rOptions,
                                     ScMarkData& rMark,
                                     ScPrintSelectionStatus& rStatus, String& rPagesStr ) const
{
	DBG_ASSERT( !rMark.IsMarked() && !rMark.IsMultiMarked(), "FillRenderMarkData: MarkData must be empty" );
	DBG_ASSERT( pDocShell, "FillRenderMarkData: DocShell must be set" );

	sal_Bool bDone = sal_False;

    uno::Reference<frame::XController> xView;

    // defaults when no options are passed: all sheets, include empty pages
    sal_Bool bSelectedSheetsOnly = sal_False;
    sal_Bool bIncludeEmptyPages = sal_True;

    bool bHasPrintContent = false;
    sal_Int32 nPrintContent = 0;        // all sheets / selected sheets / selected cells
    sal_Int32 nPrintRange = 0;          // all pages / pages
    rtl::OUString aPageRange;           // "pages" edit value

    for( sal_Int32 i = 0, nLen = rOptions.getLength(); i < nLen; i++ )
    {
        if( rOptions[i].Name.equalsAscii( "IsOnlySelectedSheets" ) )
        {
            rOptions[i].Value >>= bSelectedSheetsOnly;
        }
        else if( rOptions[i].Name.equalsAscii( "IsIncludeEmptyPages" ) )
        {
            rOptions[i].Value >>= bIncludeEmptyPages;
        }
        else if( rOptions[i].Name.equalsAscii( "PageRange" ) )
        {
            rOptions[i].Value >>= aPageRange;
        }
        else if( rOptions[i].Name.equalsAscii( "PrintRange" ) )
        {
            rOptions[i].Value >>= nPrintRange;
        }
        else if( rOptions[i].Name.equalsAscii( "PrintContent" ) )
        {
            bHasPrintContent = true;
            rOptions[i].Value >>= nPrintContent;
        }
        else if( rOptions[i].Name.equalsAscii( "View" ) )
        {
            rOptions[i].Value >>= xView;
        }
    }

    // "Print Content" selection wins over "Selected Sheets" option
    if ( bHasPrintContent )
        bSelectedSheetsOnly = ( nPrintContent != 0 );

    uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
	if ( xInterface.is() )
	{
		ScCellRangesBase* pSelObj = ScCellRangesBase::getImplementation( xInterface );
        uno::Reference< drawing::XShapes > xShapes( xInterface, uno::UNO_QUERY );
        if ( pSelObj && pSelObj->GetDocShell() == pDocShell )
		{
			sal_Bool bSheet = ( ScTableSheetObj::getImplementation( xInterface ) != NULL );
			sal_Bool bCursor = pSelObj->IsCursorOnly();
			const ScRangeList& rRanges = pSelObj->GetRangeList();

			rMark.MarkFromRangeList( rRanges, sal_False );
			rMark.MarkToSimple();

            if ( rMark.IsMultiMarked() )
            {
                // #i115266# copy behavior of old printing:
                // treat multiple selection like a single selection with the enclosing range
                ScRange aMultiMarkArea;
                rMark.GetMultiMarkArea( aMultiMarkArea );
                rMark.ResetMark();
                rMark.SetMarkArea( aMultiMarkArea );
            }

			if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
			{
				// a sheet object is treated like an empty selection: print the used area of the sheet

				if ( bCursor || bSheet ) // nothing selected -> use whole tables
				{
					rMark.ResetMark(); // doesn't change table selection
					rStatus.SetMode( SC_PRINTSEL_CURSOR );
				}
				else
					rStatus.SetMode( SC_PRINTSEL_RANGE );

				rStatus.SetRanges( rRanges );
				bDone = sal_True;
			}
			// multi selection isn't supported
		}
        else if( xShapes.is() )
        {
            //print a selected ole object
            uno::Reference< container::XIndexAccess > xIndexAccess( xShapes, uno::UNO_QUERY );
            if( xIndexAccess.is() )
            {
                // multi selection isn't supported yet
                uno::Reference< drawing::XShape > xShape( xIndexAccess->getByIndex(0), uno::UNO_QUERY );
                SvxShape* pShape = SvxShape::getImplementation( xShape );
                if( pShape )
                {
                    SdrObject *pSdrObj = pShape->GetSdrObject();
                    if( pDocShell )
                    {
                        ScDocument* pDoc = pDocShell->GetDocument();
                        if( pDoc && pSdrObj )
                        {
                            Rectangle aObjRect = pSdrObj->GetCurrentBoundRect();
                            SCTAB nCurrentTab = ScDocShell::GetCurTab();
                            ScRange aRange = pDoc->GetRange( nCurrentTab, aObjRect );
                            rMark.SetMarkArea( aRange );

                            if( rMark.IsMarked() && !rMark.IsMultiMarked() )
                            {
                                rStatus.SetMode( SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS );
                                bDone = sal_True;
                            }
                        }
                    }
                }
            }
        }
		else if ( ScModelObj::getImplementation( xInterface ) == this )
		{
			//	render the whole document
			//	-> no selection, all sheets

			SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
			for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
				rMark.SelectTable( nTab, sal_True );
			rStatus.SetMode( SC_PRINTSEL_DOCUMENT );
			bDone = sal_True;
		}
		// other selection types aren't supported
	}

    // restrict to selected sheets if a view is available
    if ( bSelectedSheetsOnly && xView.is() )
    {
        ScTabViewObj* pViewObj = ScTabViewObj::getImplementation( xView );
        if (pViewObj)
        {
            ScTabViewShell* pViewSh = pViewObj->GetViewShell();
            if (pViewSh)
            {
                // #i95280# when printing from the shell, the view is never activated,
                // so Excel view settings must also be evaluated here.
                ScExtDocOptions* pExtOpt = pDocShell->GetDocument()->GetExtDocOptions();
                if ( pExtOpt && pExtOpt->IsChanged() )
                {
                    pViewSh->GetViewData()->ReadExtOptions(*pExtOpt); // Excel view settings
                    pViewSh->SetTabNo( pViewSh->GetViewData()->GetTabNo(), sal_True );
                    pExtOpt->SetChanged( false );
                }

                const ScMarkData& rViewMark = pViewSh->GetViewData()->GetMarkData();
                SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
                for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
                    if (!rViewMark.GetTableSelect(nTab))
                        rMark.SelectTable( nTab, sal_False );
            }
        }
    }

    ScPrintOptions aNewOptions;
    aNewOptions.SetSkipEmpty( !bIncludeEmptyPages );
    aNewOptions.SetAllSheets( !bSelectedSheetsOnly );
    rStatus.SetOptions( aNewOptions );

    // "PrintRange" enables (1) or disables (0) the "PageRange" edit
    if ( nPrintRange == 1 )
        rPagesStr = aPageRange;
    else
        rPagesStr.Erase();

	return bDone;
}


sal_Int32 SAL_CALL ScModelObj::getRendererCount( const uno::Any& aSelection,
                                    const uno::Sequence<beans::PropertyValue>& rOptions )
								throw (lang::IllegalArgumentException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (!pDocShell)
		throw uno::RuntimeException();

	ScMarkData aMark;
	ScPrintSelectionStatus aStatus;
	String aPagesStr;
	if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
		return 0;

	//	The same ScPrintFuncCache object in pPrintFuncCache is used as long as
	//	the same selection is used (aStatus) and the document isn't changed
	//	(pPrintFuncCache is cleared in Notify handler)

	if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
	{
		delete pPrintFuncCache;
		pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
	}
	sal_Int32 nPages = pPrintFuncCache->GetPageCount();

    sal_Int32 nSelectCount = nPages;
    if ( aPagesStr.Len() )
    {
        MultiSelection aPageRanges( aPagesStr );
        aPageRanges.SetTotalRange( Range( 1, nPages ) );
        nSelectCount = aPageRanges.GetSelectCount();
    }
    return nSelectCount;
}

sal_Int32 lcl_GetRendererNum( sal_Int32 nSelRenderer, const String& rPagesStr, sal_Int32 nTotalPages )
{
	if ( !rPagesStr.Len() )
		return nSelRenderer;

	MultiSelection aPageRanges( rPagesStr );
	aPageRanges.SetTotalRange( Range( 1, nTotalPages ) );

	sal_Int32 nSelected = aPageRanges.FirstSelected();
	while ( nSelRenderer > 0 )
	{
		nSelected = aPageRanges.NextSelected();
		--nSelRenderer;
	}
	return nSelected - 1; // selection is 1-based
}

uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 nSelRenderer,
                                    const uno::Any& aSelection, const uno::Sequence<beans::PropertyValue>& rOptions )
								throw (lang::IllegalArgumentException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (!pDocShell)
		throw uno::RuntimeException();

	ScMarkData aMark;
	ScPrintSelectionStatus aStatus;
    String aPagesStr;
    // #i115266# if FillRenderMarkData fails, keep nTotalPages at 0, but still handle getRenderer(0) below
    long nTotalPages = 0;
    if ( FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
    {
        if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
        {
            delete pPrintFuncCache;
            pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
        }
        nTotalPages = pPrintFuncCache->GetPageCount();
    }
    sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
	if ( nRenderer >= nTotalPages )
    {
        if ( nSelRenderer == 0 )
        {
            // getRenderer(0) is used to query the settings, so it must always return something

            SCTAB nCurTab = 0; //! use current sheet from view?
            ScPrintFunc aDefaultFunc( pDocShell, pDocShell->GetPrinter(), nCurTab );
            Size aTwips = aDefaultFunc.GetPageSize();
            awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) );

            uno::Sequence<beans::PropertyValue> aSequence(1);
            beans::PropertyValue* pArray = aSequence.getArray();
            pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE );
            pArray[0].Value <<= aPageSize;

            if( ! pPrinterOptions )
                pPrinterOptions = new ScPrintUIOptions;
            else
                pPrinterOptions->SetDefaults();
            pPrinterOptions->appendPrintUIOptions( aSequence );
            return aSequence;
        }
        else
            throw lang::IllegalArgumentException();
	}

	// printer is used as device (just for page layout), draw view is not needed

	SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer );

	ScRange aRange;
	const ScRange* pSelRange = NULL;
	if ( aMark.IsMarked() )
	{
		aMark.GetMarkArea( aRange );
		pSelRange = &aRange;
	}
	ScPrintFunc aFunc( pDocShell, pDocShell->GetPrinter(), nTab,
						pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
	aFunc.SetRenderFlag( sal_True );

	Range aPageRange( nRenderer+1, nRenderer+1 );
	MultiSelection aPage( aPageRange );
	aPage.SetTotalRange( Range(0,RANGE_MAX) );
	aPage.Select( aPageRange );

	long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
	long nTabStart = pPrintFuncCache->GetTabStart( nTab );

	(void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, NULL );

	ScRange aCellRange;
	sal_Bool bWasCellRange = aFunc.GetLastSourceRange( aCellRange );
	Size aTwips = aFunc.GetPageSize();
	awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) );

	long nPropCount = bWasCellRange ? 3 : 2;
	uno::Sequence<beans::PropertyValue> aSequence(nPropCount);
	beans::PropertyValue* pArray = aSequence.getArray();
	pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE );
	pArray[0].Value <<= aPageSize;
	// #i111158# all positions are relative to the whole page, including non-printable area
	pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_INC_NP_AREA );
	pArray[1].Value = uno::makeAny( sal_True );
	if ( bWasCellRange )
	{
		table::CellRangeAddress aRangeAddress( nTab,
						aCellRange.aStart.Col(), aCellRange.aStart.Row(),
						aCellRange.aEnd.Col(), aCellRange.aEnd.Row() );
		pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_SOURCERANGE );
		pArray[2].Value <<= aRangeAddress;
	}

	if( ! pPrinterOptions )
		pPrinterOptions = new ScPrintUIOptions;
	else
		pPrinterOptions->SetDefaults();
	pPrinterOptions->appendPrintUIOptions( aSequence );
	return aSequence;
}

void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelection,
									const uno::Sequence<beans::PropertyValue>& rOptions )
								throw(lang::IllegalArgumentException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (!pDocShell)
		throw uno::RuntimeException();

	ScMarkData aMark;
	ScPrintSelectionStatus aStatus;
	String aPagesStr;
	if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
		throw lang::IllegalArgumentException();

	if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
	{
		delete pPrintFuncCache;
		pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
	}
	long nTotalPages = pPrintFuncCache->GetPageCount();
	sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
	if ( nRenderer >= nTotalPages )
		throw lang::IllegalArgumentException();

	OutputDevice* pDev = lcl_GetRenderDevice( rOptions );
	if ( !pDev )
		throw lang::IllegalArgumentException();

	SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer );
	ScDocument* pDoc = pDocShell->GetDocument();

	FmFormView* pDrawView = NULL;
	Rectangle aFull( 0, 0, LONG_MAX, LONG_MAX );

	// #114135#
	ScDrawLayer* pModel = pDoc->GetDrawLayer();

	if( pModel )
	{
		pDrawView = new FmFormView( pModel, pDev );
		pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
		pDrawView->SetPrintPreview( sal_True );
	}

	ScRange aRange;
	const ScRange* pSelRange = NULL;
	if ( aMark.IsMarked() )
	{
		aMark.GetMarkArea( aRange );
		pSelRange = &aRange;
	}

	//	to increase performance, ScPrintState might be used here for subsequent
	//	pages of the same sheet

	ScPrintFunc aFunc( pDev, pDocShell, nTab, pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
	aFunc.SetDrawView( pDrawView );
	aFunc.SetRenderFlag( sal_True );
	if( aStatus.GetMode() == SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS )
		aFunc.SetExclusivelyDrawOleAndDrawObjects();

	Range aPageRange( nRenderer+1, nRenderer+1 );
	MultiSelection aPage( aPageRange );
	aPage.SetTotalRange( Range(0,RANGE_MAX) );
	aPage.Select( aPageRange );

	long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
	long nTabStart = pPrintFuncCache->GetTabStart( nTab );

	vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
	if ( nRenderer == nTabStart )
	{
		// first page of a sheet: add outline item for the sheet name

		if ( pPDFData && pPDFData->GetIsExportBookmarks() )
		{
            // the sheet starts at the top of the page
            Rectangle aArea( pDev->PixelToLogic( Rectangle( 0,0,0,0 ) ) );
            sal_Int32 nDestID = pPDFData->CreateDest( aArea );
            String aTabName;
            pDoc->GetName( nTab, aTabName );
            sal_Int32 nParent = -1; // top-level
            pPDFData->CreateOutlineItem( nParent, aTabName, nDestID );
        }
        //--->i56629
        // add the named destination stuff
        if( pPDFData && pPDFData->GetIsExportNamedDestinations() )
        {
            Rectangle aArea( pDev->PixelToLogic( Rectangle( 0,0,0,0 ) ) );
            String aTabName;
            pDoc->GetName( nTab, aTabName );
//need the PDF page number here
            pPDFData->CreateNamedDest( aTabName, aArea );
        }
        //<---i56629
    }

    (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_True, NULL );

    //  resolve the hyperlinks for PDF export

    if ( pPDFData )
    {
        // iterate over the hyperlinks that were output for this page

        std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
        std::vector< vcl::PDFExtOutDevBookmarkEntry >::iterator aIter = rBookmarks.begin();
        std::vector< vcl::PDFExtOutDevBookmarkEntry >::iterator aIEnd = rBookmarks.end();
        while ( aIter != aIEnd )
        {
            rtl::OUString aBookmark = aIter->aBookmark;
            if ( aBookmark.toChar() == (sal_Unicode) '#' )
            {
                //  try to resolve internal link

                String aTarget( aBookmark.copy( 1 ) );

                ScRange aTargetRange;
                Rectangle aTargetRect; // 1/100th mm
                bool bIsSheet = false;
                bool bValid = lcl_ParseTarget( aTarget, aTargetRange, aTargetRect, bIsSheet, pDoc, nTab );

                if ( bValid )
                {
                    sal_Int32 nPage = -1;
                    Rectangle aArea;
                    if ( bIsSheet )
                    {
                        //  Get first page for sheet (if nothing from that sheet is printed,
                        //  this page can show a different sheet)
                        nPage = pPrintFuncCache->GetTabStart( aTargetRange.aStart.Tab() );
                        aArea = pDev->PixelToLogic( Rectangle( 0,0,0,0 ) );
                    }
                    else
                    {
                        pPrintFuncCache->InitLocations( aMark, pDev ); // does nothing if already initialized

                        ScPrintPageLocation aLocation;
                        if ( pPrintFuncCache->FindLocation( aTargetRange.aStart, aLocation ) )
                        {
                            nPage = aLocation.nPage;

                            // get the rectangle of the page's cell range in 1/100th mm
                            ScRange aLocRange = aLocation.aCellRange;
                            Rectangle aLocationMM = pDoc->GetMMRect(
                                       aLocRange.aStart.Col(), aLocRange.aStart.Row(),
                                       aLocRange.aEnd.Col(),   aLocRange.aEnd.Row(),
                                       aLocRange.aStart.Tab() );
                            Rectangle aLocationPixel = aLocation.aRectangle;

                            // Scale and move the target rectangle from aLocationMM to aLocationPixel,
                            // to get the target rectangle in pixels.

                            Fraction aScaleX( aLocationPixel.GetWidth(), aLocationMM.GetWidth() );
                            Fraction aScaleY( aLocationPixel.GetHeight(), aLocationMM.GetHeight() );

                            long nX1 = aLocationPixel.Left() + (long)
                                ( Fraction( aTargetRect.Left() - aLocationMM.Left(), 1 ) * aScaleX );
                            long nX2 = aLocationPixel.Left() + (long)
                                ( Fraction( aTargetRect.Right() - aLocationMM.Left(), 1 ) * aScaleX );
                            long nY1 = aLocationPixel.Top() + (long)
                                ( Fraction( aTargetRect.Top() - aLocationMM.Top(), 1 ) * aScaleY );
                            long nY2 = aLocationPixel.Top() + (long)
                                ( Fraction( aTargetRect.Bottom() - aLocationMM.Top(), 1 ) * aScaleY );

                            if ( nX1 > aLocationPixel.Right() ) nX1 = aLocationPixel.Right();
                            if ( nX2 > aLocationPixel.Right() ) nX2 = aLocationPixel.Right();
                            if ( nY1 > aLocationPixel.Bottom() ) nY1 = aLocationPixel.Bottom();
                            if ( nY2 > aLocationPixel.Bottom() ) nY2 = aLocationPixel.Bottom();

                            // The link target area is interpreted using the device's MapMode at
                            // the time of the CreateDest call, so PixelToLogic can be used here,
                            // regardless of the MapMode that is actually selected.

                            aArea = pDev->PixelToLogic( Rectangle( nX1, nY1, nX2, nY2 ) );
                        }
                    }

                    if ( nPage >= 0 )
                    {
                        if ( aIter->nLinkId != -1 )
                            pPDFData->SetLinkDest( aIter->nLinkId, pPDFData->CreateDest( aArea, nPage ) );
                        else
                            pPDFData->DescribeRegisteredDest( aIter->nDestId, aArea, nPage );
                    }
                }
            }
            else
            {
                // external link, use as-is
                pPDFData->SetLinkURL( aIter->nLinkId, aBookmark );
            }
            aIter++;
        }
        rBookmarks.clear();
    }

	if ( pDrawView )
		pDrawView->HideSdrPage();
	delete pDrawView;
}

// XLinkAuthorizer

sal_Bool ScModelObj::authorizeLinks( const ::rtl::OUString& rURL ) throw( uno::RuntimeException )
{
	ScUnoGuard aGuard;
	ScDocument *doc = pDocShell->GetDocument();
	if ( doc ) {
		// The following access to the window is copied from SwDoc::UpdateLinks()
		SfxMedium* pMedium = pDocShell->GetMedium();
		SfxFrame* pFrm = pMedium ? pMedium->GetLoadTargetFrame() : 0;
		sfx2::LinkManager *pLinkMgr = doc->GetLinkManager();
		if ( pLinkMgr->urlIsVendor( rURL ) ) {
			return sal_False;
		} else if ( pLinkMgr->urlIsSafe( rURL ) ) {
			return sal_True;
		}
		Window* pDlgParent = 0;
		if ( pFrm )
			pDlgParent = &pFrm->GetWindow();
		if ( !pDlgParent )
			pDlgParent = pDocShell->GetDialogParent( pMedium );
		if ( pDlgParent )
			return pLinkMgr->GetUserAllowsLinkUpdate( pDlgParent );
	}
	return sal_False;
}

// XLinkTargetSupplier

uno::Reference<container::XNameAccess> SAL_CALL ScModelObj::getLinks() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return new ScLinkTargetTypesObj(pDocShell);
	return NULL;
}

// XActionLockable

sal_Bool SAL_CALL ScModelObj::isActionLocked() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bLocked = sal_False;
	if (pDocShell)
		bLocked = ( pDocShell->GetLockCount() != 0 );
	return bLocked;
}

void SAL_CALL ScModelObj::addActionLock() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		pDocShell->LockDocument();
}

void SAL_CALL ScModelObj::removeActionLock() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		pDocShell->UnlockDocument();
}

void SAL_CALL ScModelObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		pDocShell->SetLockCount(nLock);
}

sal_Int16 SAL_CALL ScModelObj::resetActionLocks() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_uInt16 nRet = 0;
	if (pDocShell)
	{
		nRet = pDocShell->GetLockCount();
		pDocShell->SetLockCount(0);
	}
	return nRet;
}

void SAL_CALL ScModelObj::lockControllers() throw (::com::sun::star::uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SfxBaseModel::lockControllers();
	if (pDocShell)
		pDocShell->LockPaint();
}

void SAL_CALL ScModelObj::unlockControllers() throw (::com::sun::star::uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (hasControllersLocked())
	{
		SfxBaseModel::unlockControllers();
		if (pDocShell)
			pDocShell->UnlockPaint();
	}
}

// XCalculate

void SAL_CALL ScModelObj::calculate() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		pDocShell->DoRecalc(sal_True);
	else
	{
		DBG_ERROR("keine DocShell"); //! Exception oder so?
	}
}

void SAL_CALL ScModelObj::calculateAll() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		pDocShell->DoHardRecalc(sal_True);
	else
	{
		DBG_ERROR("keine DocShell"); //! Exception oder so?
	}
}

sal_Bool SAL_CALL ScModelObj::isAutomaticCalculationEnabled() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return pDocShell->GetDocument()->GetAutoCalc();

	DBG_ERROR("keine DocShell"); //! Exception oder so?
	return sal_False;
}

void SAL_CALL ScModelObj::enableAutomaticCalculation( sal_Bool bEnabled )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		ScDocument* pDoc = pDocShell->GetDocument();
		if ( pDoc->GetAutoCalc() != bEnabled )
		{
			pDoc->SetAutoCalc( bEnabled );
			pDocShell->SetDocumentModified();
		}
	}
	else
	{
		DBG_ERROR("keine DocShell"); //! Exception oder so?
	}
}

// XProtectable

void SAL_CALL ScModelObj::protect( const rtl::OUString& aPassword ) throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	// #i108245# if already protected, don't change anything
	if ( pDocShell && !pDocShell->GetDocument()->IsDocProtected() )
	{
		String aString(aPassword);

		ScDocFunc aFunc(*pDocShell);
		aFunc.Protect( TABLEID_DOC, aString, sal_True );
	}
}

void SAL_CALL ScModelObj::unprotect( const rtl::OUString& aPassword )
						throw(lang::IllegalArgumentException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		String aString(aPassword);

		ScDocFunc aFunc(*pDocShell);
		sal_Bool bDone = aFunc.Unprotect( TABLEID_DOC, aString, sal_True );
		if (!bDone)
			throw lang::IllegalArgumentException();
	}
}

sal_Bool SAL_CALL ScModelObj::isProtected() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return pDocShell->GetDocument()->IsDocProtected();

	DBG_ERROR("keine DocShell"); //! Exception oder so?
	return sal_False;
}

// XDrawPagesSupplier

uno::Reference<drawing::XDrawPages> SAL_CALL ScModelObj::getDrawPages() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return new ScDrawPagesObj(pDocShell);

	DBG_ERROR("keine DocShell"); //! Exception oder so?
	return NULL;
}

#if 0
// XPrintable

rtl::OUString ScModelObj::getPrinterName(void) const
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		SfxPrinter* pPrinter = pDocShell->GetPrinter();
		if (pPrinter)
			return pPrinter->GetName();
	}

	DBG_ERROR("getPrinterName: keine DocShell oder kein Printer");
	return rtl::OUString();
}

void ScModelObj::setPrinterName(const rtl::OUString& PrinterName)
{
	ScUnoGuard aGuard;
	//	Drucker setzen - wie in SfxViewShell::ExecPrint_Impl

	if (pDocShell)
	{
		SfxPrinter* pPrinter = pDocShell->GetPrinter();
		if (pPrinter)
		{
			String aString(PrinterName);
			SfxPrinter* pNewPrinter = new SfxPrinter( pPrinter->GetOptions().Clone(), aString );
			if (pNewPrinter->IsKnown())
				pDocShell->SetPrinter( pNewPrinter, SFX_PRINTER_PRINTER );
			else
				delete pNewPrinter;
		}
	}
}

XPropertySetRef ScModelObj::createPrintOptions(void)
{
	ScUnoGuard aGuard;
	return new ScPrintSettingsObj; //! ScPrintSettingsObj implementieren!
}

void ScModelObj::print(const XPropertySetRef& xOptions)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		//!	xOptions auswerten (wie denn?)

		//!	muss noch
	}
}
#endif

// XGoalSeek

sheet::GoalResult SAL_CALL ScModelObj::seekGoal(
								const table::CellAddress& aFormulaPosition,
								const table::CellAddress& aVariablePosition,
								const ::rtl::OUString& aGoalValue )
									throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sheet::GoalResult aResult;
	aResult.Divergence = DBL_MAX; // nichts gefunden
	if (pDocShell)
	{
		WaitObject aWait( pDocShell->GetActiveDialogParent() );
		String aGoalString(aGoalValue);
		ScDocument* pDoc = pDocShell->GetDocument();
		double fValue = 0.0;
		sal_Bool bFound = pDoc->Solver(
					(SCCOL)aFormulaPosition.Column, (SCROW)aFormulaPosition.Row, aFormulaPosition.Sheet,
					(SCCOL)aVariablePosition.Column, (SCROW)aVariablePosition.Row, aVariablePosition.Sheet,
					aGoalString, fValue );
		aResult.Result = fValue;
		if (bFound)
			aResult.Divergence = 0.0; //! das ist gelogen
	}
	return aResult;
}

// XConsolidatable

uno::Reference<sheet::XConsolidationDescriptor> SAL_CALL ScModelObj::createConsolidationDescriptor(
								sal_Bool bEmpty ) throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	ScConsolidationDescriptor* pNew = new ScConsolidationDescriptor;
	if ( pDocShell && !bEmpty )
	{
		ScDocument* pDoc = pDocShell->GetDocument();
		const ScConsolidateParam* pParam = pDoc->GetConsolidateDlgData();
		if (pParam)
			pNew->SetParam( *pParam );
	}
	return pNew;
}

void SAL_CALL ScModelObj::consolidate(
		const uno::Reference<sheet::XConsolidationDescriptor>& xDescriptor )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	//	das könnte theoretisch ein fremdes Objekt sein, also nur das
	//	öffentliche XConsolidationDescriptor Interface benutzen, um
	//	die Daten in ein ScConsolidationDescriptor Objekt zu kopieren:
	//!	wenn es schon ein ScConsolidationDescriptor ist, direkt per getImplementation?

	ScConsolidationDescriptor aImpl;
	aImpl.setFunction( xDescriptor->getFunction() );
	aImpl.setSources( xDescriptor->getSources() );
	aImpl.setStartOutputPosition( xDescriptor->getStartOutputPosition() );
	aImpl.setUseColumnHeaders( xDescriptor->getUseColumnHeaders() );
	aImpl.setUseRowHeaders( xDescriptor->getUseRowHeaders() );
	aImpl.setInsertLinks( xDescriptor->getInsertLinks() );

	if (pDocShell)
	{
		const ScConsolidateParam& rParam = aImpl.GetParam();
		pDocShell->DoConsolidate( rParam, sal_True );
		pDocShell->GetDocument()->SetConsolidateDlgData( &rParam );
	}
}

// XDocumentAuditing

void SAL_CALL ScModelObj::refreshArrows() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		ScDocFunc aFunc(*pDocShell);
		aFunc.DetectiveRefresh();
	}
}

// XViewDataSupplier
uno::Reference< container::XIndexAccess > SAL_CALL ScModelObj::getViewData(  )
	throw (uno::RuntimeException)
{
	uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );

    if( !xRet.is() )
    {
        ScUnoGuard aGuard;
        if (pDocShell && pDocShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED)
        {
            xRet.set(uno::Reference < container::XIndexAccess >::query(::comphelper::getProcessServiceFactory()->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.IndexedPropertyValues")))));

            uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
            DBG_ASSERT( xCont.is(), "ScModelObj::getViewData() failed for OLE object" );
            if( xCont.is() )
            {
                uno::Sequence< beans::PropertyValue > aSeq;
                aSeq.realloc(1);
                String sName;
                pDocShell->GetDocument()->GetName( pDocShell->GetDocument()->GetVisibleTab(), sName );
                rtl::OUString sOUName(sName);
                aSeq[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVETABLE));
                aSeq[0].Value <<= sOUName;
                xCont->insertByIndex( 0, uno::makeAny( aSeq ) );
            }
        }
    }

	return xRet;
}

//	XPropertySet (Doc-Optionen)
//!	auch an der Applikation anbieten?

uno::Reference<beans::XPropertySetInfo> SAL_CALL ScModelObj::getPropertySetInfo()
														throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	static uno::Reference<beans::XPropertySetInfo> aRef(
		new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
	return aRef;
}

void SAL_CALL ScModelObj::setPropertyValue(
						const rtl::OUString& aPropertyName, const uno::Any& aValue )
				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
						lang::IllegalArgumentException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	ScUnoGuard aGuard;
	String aString(aPropertyName);

	if (pDocShell)
	{
		ScDocument* pDoc = pDocShell->GetDocument();
		const ScDocOptions& rOldOpt = pDoc->GetDocOptions();
		ScDocOptions aNewOpt = rOldOpt;

		sal_Bool bOpt = ScDocOptionsHelper::setPropertyValue( aNewOpt, *aPropSet.getPropertyMap(), aPropertyName, aValue );
		if (bOpt)
		{
			// done...
		}
		else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
		{
			lang::Locale aLocale;
			if ( aValue >>= aLocale )
			{
				LanguageType eLatin, eCjk, eCtl;
				pDoc->GetLanguage( eLatin, eCjk, eCtl );
				eLatin = ScUnoConversion::GetLanguage(aLocale);
				pDoc->SetLanguage( eLatin, eCjk, eCtl );
			}
		}
        else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
        {
            rtl::OUString sCodeName;
            if ( aValue >>= sCodeName )
                pDoc->SetCodeName( sCodeName );
        }
		else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
		{
			lang::Locale aLocale;
			if ( aValue >>= aLocale )
			{
				LanguageType eLatin, eCjk, eCtl;
				pDoc->GetLanguage( eLatin, eCjk, eCtl );
				eCjk = ScUnoConversion::GetLanguage(aLocale);
				pDoc->SetLanguage( eLatin, eCjk, eCtl );
			}
		}
		else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
		{
			lang::Locale aLocale;
			if ( aValue >>= aLocale )
			{
				LanguageType eLatin, eCjk, eCtl;
				pDoc->GetLanguage( eLatin, eCjk, eCtl );
				eCtl = ScUnoConversion::GetLanguage(aLocale);
				pDoc->SetLanguage( eLatin, eCjk, eCtl );
			}
		}
		else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
		{
			//	model is created if not there
			ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
			pModel->SetOpenInDesignMode( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );

			SfxBindings* pBindings = pDocShell->GetViewBindings();
			if (pBindings)
				pBindings->Invalidate( SID_FM_OPEN_READONLY );
		}
		else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
		{
			//	model is created if not there
			ScDrawLayer* pModel = pDocShell->MakeDrawLayer();
			pModel->SetAutoControlFocus( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );

			SfxBindings* pBindings = pDocShell->GetViewBindings();
			if (pBindings)
				pBindings->Invalidate( SID_FM_AUTOCONTROLFOCUS );
		}
        else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
        {
            pDocShell->SetEmpty( !ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
        }
        else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
        {
            sal_Bool bUndoEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
            pDoc->EnableUndo( bUndoEnabled );
            sal_uInt16 nCount = ( bUndoEnabled ?
                static_cast< sal_uInt16 >( SvtUndoOptions().GetUndoCount() ) : 0 );
            pDocShell->GetUndoManager()->SetMaxUndoActionCount( nCount );
        }
        else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
        {
            bool bOldAdjustHeightEnabled = pDoc->IsAdjustHeightEnabled();
            bool bAdjustHeightEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue );
            if( bOldAdjustHeightEnabled != bAdjustHeightEnabled )
            {
                pDoc->EnableAdjustHeight( bAdjustHeightEnabled );
                if( bAdjustHeightEnabled )
                    pDocShell->UpdateAllRowHeights();
            }
        }
        else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
        {
            pDoc->EnableExecuteLink( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
        }
        else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
        {
            pDoc->EnableChangeReadOnly( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
        }
		else if ( aString.EqualsAscii( "BuildId" ) )
		{
			aValue >>= maBuildId;
		}
        else if ( aString.EqualsAscii( "SavedObject" ) ) // set from chart after saving
        {
            rtl::OUString aObjName;
            aValue >>= aObjName;
            if ( aObjName.getLength() )
                pDoc->RestoreChartListener( aObjName );
        }

		if ( aNewOpt != rOldOpt )
		{
			pDoc->SetDocOptions( aNewOpt );
            //  Don't recalculate while loading XML, when the formula text is stored.
            //  Recalculation after loading is handled separately.
            //! Recalc only for options that need it?
            if ( !pDoc->IsImportingXML() )
                pDocShell->DoHardRecalc( sal_True );
			pDocShell->SetDocumentModified();
		}
	}
}

uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyName )
				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	ScUnoGuard aGuard;
	String aString(aPropertyName);
	uno::Any aRet;

	if (pDocShell)
	{
		ScDocument* pDoc = pDocShell->GetDocument();
		const ScDocOptions& rOpt = pDoc->GetDocOptions();
		aRet = ScDocOptionsHelper::getPropertyValue( rOpt, *aPropSet.getPropertyMap(), aPropertyName );
		if ( aRet.hasValue() )
		{
			// done...
		}
		else if ( aString.EqualsAscii( SC_UNONAME_CLOCAL ) )
		{
			LanguageType eLatin, eCjk, eCtl;
			pDoc->GetLanguage( eLatin, eCjk, eCtl );

			lang::Locale aLocale;
			ScUnoConversion::FillLocale( aLocale, eLatin );
			aRet <<= aLocale;
		}
		else if ( aString.EqualsAscii( SC_UNO_CODENAME ) )
		{
			rtl::OUString sCodeName = pDoc->GetCodeName();
			aRet <<= sCodeName;
		}

		else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) )
		{
			LanguageType eLatin, eCjk, eCtl;
			pDoc->GetLanguage( eLatin, eCjk, eCtl );

			lang::Locale aLocale;
			ScUnoConversion::FillLocale( aLocale, eCjk );
			aRet <<= aLocale;
		}
		else if ( aString.EqualsAscii( SC_UNO_CTL_CLOCAL ) )
		{
			LanguageType eLatin, eCjk, eCtl;
			pDoc->GetLanguage( eLatin, eCjk, eCtl );

			lang::Locale aLocale;
			ScUnoConversion::FillLocale( aLocale, eCtl );
			aRet <<= aLocale;
		}
		else if ( aString.EqualsAscii( SC_UNO_NAMEDRANGES2 ) )
		{
			aRet <<= uno::Reference<sheet::XNamedRanges2>(new ScNamedRangesObj( pDocShell ));
		}
		else if ( aString.EqualsAscii( SC_UNO_NAMEDRANGES ) )
		{
			aRet <<= uno::Reference<sheet::XNamedRanges>(new ScNamedRangesObj( pDocShell ));
		}
		else if ( aString.EqualsAscii( SC_UNO_DATABASERNG ) )
		{
			aRet <<= uno::Reference<sheet::XDatabaseRanges>(new ScDatabaseRangesObj( pDocShell ));
		}
		else if ( aString.EqualsAscii( SC_UNO_COLLABELRNG ) )
		{
			aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_True ));
		}
		else if ( aString.EqualsAscii( SC_UNO_ROWLABELRNG ) )
		{
			aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, sal_False ));
		}
		else if ( aString.EqualsAscii( SC_UNO_AREALINKS ) )
		{
			aRet <<= uno::Reference<sheet::XAreaLinks>(new ScAreaLinksObj( pDocShell ));
		}
		else if ( aString.EqualsAscii( SC_UNO_DDELINKS ) )
		{
			aRet <<= uno::Reference<container::XNameAccess>(new ScDDELinksObj( pDocShell ));
		}
		else if ( aString.EqualsAscii( SC_UNO_EXTERNALDOCLINKS ) )
		{
			aRet <<= uno::Reference<sheet::XExternalDocLinks>(new ScExternalDocLinksObj(pDocShell));
		}
		else if ( aString.EqualsAscii( SC_UNO_SHEETLINKS ) )
		{
			aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
		}
		else if ( aString.EqualsAscii( SC_UNO_APPLYFMDES ) )
		{
			// default for no model is TRUE
			ScDrawLayer* pModel = pDoc->GetDrawLayer();
			sal_Bool bOpenInDesign = pModel ? pModel->GetOpenInDesignMode() : sal_True;
			ScUnoHelpFunctions::SetBoolInAny( aRet, bOpenInDesign );
		}
		else if ( aString.EqualsAscii( SC_UNO_AUTOCONTFOC ) )
		{
			// default for no model is FALSE
			ScDrawLayer* pModel = pDoc->GetDrawLayer();
			sal_Bool bAutoControlFocus = pModel ? pModel->GetAutoControlFocus() : sal_False;
			ScUnoHelpFunctions::SetBoolInAny( aRet, bAutoControlFocus );
		}
		else if ( aString.EqualsAscii( SC_UNO_FORBIDDEN ) )
		{
			aRet <<= uno::Reference<i18n::XForbiddenCharacters>(new ScForbiddenCharsObj( pDocShell ));
		}
		else if ( aString.EqualsAscii( SC_UNO_HASDRAWPAGES ) )
		{
			ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetDocument()->GetDrawLayer() != 0) );
		}
		else if ( aString.EqualsAscii( SC_UNO_BASICLIBRARIES ) )
		{
			aRet <<= pDocShell->GetBasicContainer();
		}
        else if ( aString.EqualsAscii( SC_UNO_DIALOGLIBRARIES ) )
        {
            aRet <<= pDocShell->GetDialogContainer();
        }
        else if ( aString.EqualsAscii( SC_UNO_VBAGLOBNAME ) )
        {
            /*  #i111553# This property provides the name of the constant that
                will be used to store this model in the global Basic manager.
                That constant will be equivalent to 'ThisComponent' but for
                each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
                constant can co-exist, as required by VBA. */
            aRet <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ThisExcelDoc" ) );
        }
        else if ( aString.EqualsAscii( SC_UNO_RUNTIMEUID ) )
        {
            aRet <<= getRuntimeUID();
        }
        else if ( aString.EqualsAscii( SC_UNO_HASVALIDSIGNATURES ) )
        {
            aRet <<= hasValidSignatures();
        }
        else if ( aString.EqualsAscii( SC_UNO_ISLOADED ) )
        {
            ScUnoHelpFunctions::SetBoolInAny( aRet, !pDocShell->IsEmpty() );
        }
        else if ( aString.EqualsAscii( SC_UNO_ISUNDOENABLED ) )
        {
            ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsUndoEnabled() );
        }
        else if ( aString.EqualsAscii( SC_UNO_ISADJUSTHEIGHTENABLED ) )
        {
            ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsAdjustHeightEnabled() );
        }
        else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) )
        {
            ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsExecuteLinkEnabled() );
        }
        else if ( aString.EqualsAscii( SC_UNO_ISCHANGEREADONLYENABLED ) )
        {
            ScUnoHelpFunctions::SetBoolInAny( aRet, pDoc->IsChangeReadOnlyEnabled() );
        }
        else if ( aString.EqualsAscii( SC_UNO_REFERENCEDEVICE ) )
        {
            VCLXDevice* pXDev = new VCLXDevice();
            pXDev->SetOutputDevice( pDoc->GetRefDevice() );
            aRet <<= uno::Reference< awt::XDevice >( pXDev );
        }
        else if ( aString.EqualsAscii( "BuildId" ) )
		{
			aRet <<= maBuildId;
		}
		else if ( aString.EqualsAscii( "InternalDocument" ) )
		{
			ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) );
		}
	}

	return aRet;
}

SC_IMPL_DUMMY_PROPERTY_LISTENER( ScModelObj )

// XMultiServiceFactory

uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance(
								const rtl::OUString& aServiceSpecifier )
								throw(uno::Exception, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<uno::XInterface> xRet;
	String aNameStr(aServiceSpecifier);
	sal_uInt16 nType = ScServiceProvider::GetProviderType(aNameStr);
	if ( nType != SC_SERVICE_INVALID )
	{
		//	drawing layer tables must be kept as long as the model is alive
		//	return stored instance if already set
		switch ( nType )
		{
			case SC_SERVICE_GRADTAB:	xRet.set(xDrawGradTab);		break;
			case SC_SERVICE_HATCHTAB:	xRet.set(xDrawHatchTab);	break;
			case SC_SERVICE_BITMAPTAB:	xRet.set(xDrawBitmapTab);	break;
			case SC_SERVICE_TRGRADTAB:	xRet.set(xDrawTrGradTab);	break;
			case SC_SERVICE_MARKERTAB:	xRet.set(xDrawMarkerTab);	break;
			case SC_SERVICE_DASHTAB:	xRet.set(xDrawDashTab); 	break;
			case SC_SERVICE_CHDATAPROV: xRet.set(xChartDataProv);	break;
			case SC_SERVICE_VBAOBJECTPROVIDER: xRet.set(xObjProvider); break;
		}

        // #i64497# If a chart is in a temporary document during clipboard paste,
        // there should be no data provider, so that own data is used
        bool bCreate =
            ! ( nType == SC_SERVICE_CHDATAPROV &&
                ( pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL ));
        // this should never happen, i.e. the temporary document should never be
        // loaded, because this unlinks the data
        OSL_ASSERT( bCreate );

		if ( !xRet.is() && bCreate )
		{
			xRet.set(ScServiceProvider::MakeInstance( nType, pDocShell ));

			//	store created instance
			switch ( nType )
			{
				case SC_SERVICE_GRADTAB:	xDrawGradTab.set(xRet); 	break;
				case SC_SERVICE_HATCHTAB:	xDrawHatchTab.set(xRet);	break;
				case SC_SERVICE_BITMAPTAB:	xDrawBitmapTab.set(xRet);	break;
				case SC_SERVICE_TRGRADTAB:	xDrawTrGradTab.set(xRet);	break;
				case SC_SERVICE_MARKERTAB:	xDrawMarkerTab.set(xRet);	break;
				case SC_SERVICE_DASHTAB:	xDrawDashTab.set(xRet); 	break;
                case SC_SERVICE_CHDATAPROV: xChartDataProv.set(xRet);	break;
                case SC_SERVICE_VBAOBJECTPROVIDER: xObjProvider.set(xRet); break;
			}
		}
	}
	else
	{
		//	alles was ich nicht kenne, werfe ich der SvxFmMSFactory an den Hals,
		//	da wird dann 'ne Exception geworfen, wenn's nicht passt...

		try
		{
			xRet.set(SvxFmMSFactory::createInstance(aServiceSpecifier));
			// extra block to force deletion of the temporary before ScShapeObj ctor (setDelegator)
		}
		catch ( lang::ServiceNotRegisteredException & )
		{
		}

		//	#96117# if the drawing factory created a shape, a ScShapeObj has to be used
		//	to support own properties like ImageMap:

		uno::Reference<drawing::XShape> xShape( xRet, uno::UNO_QUERY );
		if ( xShape.is() )
		{
			xRet.clear(); // for aggregation, xShape must be the object's only ref
			new ScShapeObj( xShape ); // aggregates object and modifies xShape
			xRet.set(xShape);
		}
	}
	return xRet;
}

uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstanceWithArguments(
								const rtl::OUString& ServiceSpecifier,
								const uno::Sequence<uno::Any>& aArgs )
								throw(uno::Exception, uno::RuntimeException)
{
	//!	unterscheiden zwischen eigenen Services und denen vom Drawing-Layer?

	ScUnoGuard aGuard;
	uno::Reference<uno::XInterface> xInt(createInstance(ServiceSpecifier));

	if ( aArgs.getLength() )
	{
		//	used only for cell value binding so far - it can be initialized after creating

		uno::Reference<lang::XInitialization> xInit( xInt, uno::UNO_QUERY );
		if ( xInit.is() )
			xInit->initialize( aArgs );
	}

	return xInt;
}

uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getAvailableServiceNames()
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;

	//!	warum sind die Parameter bei concatServiceNames nicht const ???
	//!	return concatServiceNames( ScServiceProvider::GetAllServiceNames(),
	//!							   SvxFmMSFactory::getAvailableServiceNames() );

	uno::Sequence<rtl::OUString> aMyServices(ScServiceProvider::GetAllServiceNames());
	uno::Sequence<rtl::OUString> aDrawServices(SvxFmMSFactory::getAvailableServiceNames());

	return concatServiceNames( aMyServices, aDrawServices );
}

// XServiceInfo

rtl::OUString SAL_CALL ScModelObj::getImplementationName() throw(uno::RuntimeException)
{
	return rtl::OUString::createFromAscii( "ScModelObj" );
}

sal_Bool SAL_CALL ScModelObj::supportsService( const rtl::OUString& rServiceName )
													throw(uno::RuntimeException)
{
	String aServiceStr(rServiceName);
	return aServiceStr.EqualsAscii( SCMODELOBJ_SERVICE ) ||
		   aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE ) ||
		   aServiceStr.EqualsAscii( SCDOC_SERVICE );
}

uno::Sequence<rtl::OUString> SAL_CALL ScModelObj::getSupportedServiceNames()
													throw(uno::RuntimeException)
{
	uno::Sequence<rtl::OUString> aRet(2);
	rtl::OUString* pArray = aRet.getArray();
	pArray[0] = rtl::OUString::createFromAscii( SCMODELOBJ_SERVICE );
	pArray[1] = rtl::OUString::createFromAscii( SCDOCSETTINGS_SERVICE );
	return aRet;
}

// XUnoTunnel

sal_Int64 SAL_CALL ScModelObj::getSomething(
				const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
{
	if ( rId.getLength() == 16 &&
          0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
									rId.getConstArray(), 16 ) )
	{
		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
	}

	if ( rId.getLength() == 16 &&
		0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(),
                                    rId.getConstArray(), 16 ) )
	{
		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell ));
	}

	//	aggregated number formats supplier has XUnoTunnel, too
	//	interface from aggregated object must be obtained via queryAggregation

	sal_Int64 nRet = SfxBaseModel::getSomething( rId );
	if ( nRet )
		return nRet;

	if ( GetFormatter().is() )
	{
		const uno::Type& rTunnelType = ::getCppuType((uno::Reference<lang::XUnoTunnel>*) 0);
		uno::Any aNumTunnel(xNumberAgg->queryAggregation(rTunnelType));
		if(aNumTunnel.getValueType() == rTunnelType)
		{
			uno::Reference<lang::XUnoTunnel> xTunnelAgg(
				*(uno::Reference<lang::XUnoTunnel>*)aNumTunnel.getValue());
			return xTunnelAgg->getSomething( rId );
		}
	}

	return 0;
}

// static
const uno::Sequence<sal_Int8>& ScModelObj::getUnoTunnelId()
{
	static uno::Sequence<sal_Int8> * pSeq = 0;
	if( !pSeq )
	{
		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
		if( !pSeq )
		{
			static uno::Sequence< sal_Int8 > aSeq( 16 );
			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
			pSeq = &aSeq;
		}
	}
	return *pSeq;
}

// static
ScModelObj* ScModelObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
{
	ScModelObj* pRet = NULL;
	uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
	if (xUT.is())
		pRet = reinterpret_cast<ScModelObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
	return pRet;
}

// XChangesNotifier

void ScModelObj::addChangesListener( const uno::Reference< util::XChangesListener >& aListener )
	throw (uno::RuntimeException)
{
	ScUnoGuard aGuard;
	maChangesListeners.addInterface( aListener );
}

void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesListener >& aListener )
	throw (uno::RuntimeException)
{
	ScUnoGuard aGuard;
	maChangesListeners.removeInterface( aListener );
}

bool ScModelObj::HasChangesListeners() const
{
	if ( maChangesListeners.getLength() > 0 )
		return true;

	// "change" event set in any sheet?
	return pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript(SC_SHEETEVENT_CHANGE);
}

void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges,
	const uno::Sequence< beans::PropertyValue >& rProperties )
{
	if ( pDocShell && HasChangesListeners() )
	{
        util::ChangesEvent aEvent;
        aEvent.Source.set( static_cast< cppu::OWeakObject* >( this ) );
        aEvent.Base <<= aEvent.Source;

        sal_uLong nRangeCount = rRanges.Count();
        aEvent.Changes.realloc( static_cast< sal_Int32 >( nRangeCount ) );
        for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
        {
            uno::Reference< table::XCellRange > xRangeObj;

            ScRange aRange( *rRanges.GetObject( nIndex ) );
            if ( aRange.aStart == aRange.aEnd )
            {
                xRangeObj.set( new ScCellObj( pDocShell, aRange.aStart ) );
            }
            else
            {
                xRangeObj.set( new ScCellRangeObj( pDocShell, aRange ) );
            }

            util::ElementChange& rChange = aEvent.Changes[ static_cast< sal_Int32 >( nIndex ) ];
            rChange.Accessor <<= rOperation;
            rChange.Element <<= rProperties;
            rChange.ReplacedElement <<= xRangeObj;
        }

        ::cppu::OInterfaceIteratorHelper aIter( maChangesListeners );
        while ( aIter.hasMoreElements() )
        {
            try
            {
        		static_cast< util::XChangesListener* >( aIter.next() )->changesOccurred( aEvent );
            }
            catch( uno::Exception& )
            {
            }
        }
    }

    // handle sheet events
    //! separate method with ScMarkData? Then change HasChangesListeners back.
    if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell )
    {
        ScMarkData aMarkData;
        aMarkData.MarkFromRangeList( rRanges, sal_False );
        ScDocument* pDoc = pDocShell->GetDocument();
        SCTAB nTabCount = pDoc->GetTableCount();
        for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
            if (aMarkData.GetTableSelect(nTab))
            {
                const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab);
                if (pEvents)
                {
                    const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE);
                    if (pScript)
                    {
                        ScRangeList aTabRanges; // collect ranges on this sheet
                        sal_uLong nRangeCount = rRanges.Count();
                        for ( sal_uLong nIndex = 0; nIndex < nRangeCount; ++nIndex )
                        {
                            ScRange aRange( *rRanges.GetObject( nIndex ) );
                            if ( aRange.aStart.Tab() == nTab )
                                aTabRanges.Append( aRange );
                        }
                        sal_uLong nTabRangeCount = aTabRanges.Count();
                        if ( nTabRangeCount > 0 )
                        {
                            uno::Reference<uno::XInterface> xTarget;
                            if ( nTabRangeCount == 1 )
                            {
                                ScRange aRange( *aTabRanges.GetObject( 0 ) );
                                if ( aRange.aStart == aRange.aEnd )
                                    xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) );
                                else
                                    xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) );
                            }
                            else
                                xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) );

                            uno::Sequence<uno::Any> aParams(1);
                            aParams[0] <<= xTarget;

                            uno::Any aRet;
                            uno::Sequence<sal_Int16> aOutArgsIndex;
                            uno::Sequence<uno::Any> aOutArgs;

                            /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
                        }
                    }
                }
            }
    }
}

void ScModelObj::HandleCalculateEvents()
{
    if (pDocShell)
    {
        ScDocument* pDoc = pDocShell->GetDocument();
        // don't call events before the document is visible
        // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading)
        if ( pDoc->IsDocVisible() )
        {
            SCTAB nTabCount = pDoc->GetTableCount();
            for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
            {
                if (pDoc->HasCalcNotification(nTab))
                {
                    if (const ScSheetEvents* pEvents = pDoc->GetSheetEvents( nTab ))
                    {
                        if (const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE))
                        {
                            uno::Any aRet;
                            uno::Sequence<uno::Any> aParams;
                            uno::Sequence<sal_Int16> aOutArgsIndex;
                            uno::Sequence<uno::Any> aOutArgs;
                            pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
                        }
                    }

                    try
                    {
                        uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW );
                        uno::Sequence< uno::Any > aArgs( 1 );
                        aArgs[ 0 ] <<= nTab;
                        xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_CALCULATE ), aArgs );
                    }
                    catch( uno::Exception& )
                    {
                    }
                }
            }
        }
        pDoc->ResetCalcNotifications();
	}
}

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

ScDrawPagesObj::ScDrawPagesObj(ScDocShell* pDocSh) :
	pDocShell( pDocSh )
{
	pDocShell->GetDocument()->AddUnoObject(*this);
}

ScDrawPagesObj::~ScDrawPagesObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScDrawPagesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	//	Referenz-Update interessiert hier nicht

	if ( rHint.ISA( SfxSimpleHint ) &&
			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
	{
		pDocShell = NULL; // ungültig geworden
	}
}

uno::Reference<drawing::XDrawPage> ScDrawPagesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
{
	if (pDocShell)
	{
		ScDrawLayer* pDrawLayer = pDocShell->MakeDrawLayer();
		DBG_ASSERT(pDrawLayer,"kann Draw-Layer nicht anlegen");
		if ( pDrawLayer && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
		{
			SdrPage* pPage = pDrawLayer->GetPage((sal_uInt16)nIndex);
			DBG_ASSERT(pPage,"Draw-Page not found");
			if (pPage)
			{
				return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
			}
		}
	}
	return NULL;
}

// XDrawPages

uno::Reference<drawing::XDrawPage> SAL_CALL ScDrawPagesObj::insertNewByIndex( sal_Int32 nPos )
											throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<drawing::XDrawPage> xRet;
	if (pDocShell)
	{
		String aNewName;
		pDocShell->GetDocument()->CreateValidTabName(aNewName);
		ScDocFunc aFunc(*pDocShell);
		if ( aFunc.InsertTable( (SCTAB)nPos, aNewName, sal_True, sal_True ) )
			xRet.set(GetObjectByIndex_Impl( nPos ));
	}
	return xRet;
}

void SAL_CALL ScDrawPagesObj::remove( const uno::Reference<drawing::XDrawPage>& xPage )
											throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SvxDrawPage* pImp = SvxDrawPage::getImplementation( xPage );
	if ( pDocShell && pImp )
	{
		SdrPage* pPage = pImp->GetSdrPage();
		if (pPage)
		{
			SCTAB nPageNum = static_cast<SCTAB>(pPage->GetPageNum());
			ScDocFunc aFunc(*pDocShell);
			aFunc.DeleteTable( nPageNum, sal_True, sal_True );
		}
	}
}

// XIndexAccess

sal_Int32 SAL_CALL ScDrawPagesObj::getCount() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return pDocShell->GetDocument()->GetTableCount();
	return 0;
}

uno::Any SAL_CALL ScDrawPagesObj::getByIndex( sal_Int32 nIndex )
							throw(lang::IndexOutOfBoundsException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<drawing::XDrawPage> xPage(GetObjectByIndex_Impl(nIndex));
	if (xPage.is())
		return uno::makeAny(xPage);
	else
		throw lang::IndexOutOfBoundsException();
//	return uno::Any();
}

uno::Type SAL_CALL ScDrawPagesObj::getElementType() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return getCppuType((uno::Reference<drawing::XDrawPage>*)0);
}

sal_Bool SAL_CALL ScDrawPagesObj::hasElements() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return ( getCount() != 0 );
}

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

ScTableSheetsObj::ScTableSheetsObj(ScDocShell* pDocSh) :
	pDocShell( pDocSh )
{
	pDocShell->GetDocument()->AddUnoObject(*this);
}

ScTableSheetsObj::~ScTableSheetsObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScTableSheetsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	//	Referenz-Update interessiert hier nicht

	if ( rHint.ISA( SfxSimpleHint ) &&
			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
	{
		pDocShell = NULL; // ungültig geworden
	}
}

// XSpreadsheets

ScTableSheetObj* ScTableSheetsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
{
	if ( pDocShell && nIndex >= 0 && nIndex < pDocShell->GetDocument()->GetTableCount() )
		return new ScTableSheetObj( pDocShell, static_cast<SCTAB>(nIndex) );

	return NULL;
}

ScTableSheetObj* ScTableSheetsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
{
	if (pDocShell)
	{
		SCTAB nIndex;
		String aString(aName);
		if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
			return new ScTableSheetObj( pDocShell, nIndex );
	}
	return NULL;
}

void SAL_CALL ScTableSheetsObj::insertNewByName( const rtl::OUString& aName, sal_Int16 nPosition )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	if (pDocShell)
	{
		String aNamStr(aName);
		ScDocFunc aFunc(*pDocShell);
		bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
	}
	if (!bDone)
		throw uno::RuntimeException(); // no other exceptions specified
}

void SAL_CALL ScTableSheetsObj::moveByName( const rtl::OUString& aName, sal_Int16 nDestination )
											throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	if (pDocShell)
	{
		String aNamStr(aName);
		SCTAB nSource;
		if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
			bDone = pDocShell->MoveTable( nSource, nDestination, sal_False, sal_True );
	}
	if (!bDone)
		throw uno::RuntimeException(); // no other exceptions specified
}

void SAL_CALL ScTableSheetsObj::copyByName( const rtl::OUString& aName,
								const rtl::OUString& aCopy, sal_Int16 nDestination )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	if (pDocShell)
	{
		String aNamStr(aName);
		String aNewStr(aCopy);
		SCTAB nSource;
		if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) )
		{
			bDone = pDocShell->MoveTable( nSource, nDestination, sal_True, sal_True );
			if (bDone)
			{
                // #i92477# any index past the last sheet means "append" in MoveTable
                SCTAB nResultTab = static_cast<SCTAB>(nDestination);
                SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount(); // count after copying
                if (nResultTab >= nTabCount)
                    nResultTab = nTabCount - 1;

                ScDocFunc aFunc(*pDocShell);
                bDone = aFunc.RenameTable( nResultTab, aNewStr, sal_True, sal_True );
			}
		}
	}
	if (!bDone)
		throw uno::RuntimeException(); // no other exceptions specified
}

void SAL_CALL ScTableSheetsObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
							throw(lang::IllegalArgumentException, container::ElementExistException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	sal_Bool bIllArg = sal_False;

	//!	Type of aElement can be some specific interface instead of XInterface

	if ( pDocShell )
	{
		uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
		if ( xInterface.is() )
		{
			ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
			if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
			{
				ScDocument* pDoc = pDocShell->GetDocument();
				String aNamStr(aName);
				SCTAB nDummy;
				if ( pDoc->GetTable( aNamStr, nDummy ) )
				{
					// name already exists
					throw container::ElementExistException();
				}
				else
				{
					SCTAB nPosition = pDoc->GetTableCount();
					ScDocFunc aFunc(*pDocShell);
					bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
					if (bDone)
						pSheetObj->InitInsertSheet( pDocShell, nPosition );
					//	Dokument und neuen Range am Objekt setzen
				}
			}
			else
				bIllArg = sal_True;
		}
		else
			bIllArg = sal_True;
	}

	if (!bDone)
	{
		if (bIllArg)
			throw lang::IllegalArgumentException();
		else
			throw uno::RuntimeException(); // ElementExistException is handled above
	}
}

void SAL_CALL ScTableSheetsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
							throw(lang::IllegalArgumentException, container::NoSuchElementException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	sal_Bool bIllArg = sal_False;

	//!	Type of aElement can be some specific interface instead of XInterface

	if ( pDocShell )
	{
		uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
		if ( xInterface.is() )
		{
			ScTableSheetObj* pSheetObj = ScTableSheetObj::getImplementation( xInterface );
			if ( pSheetObj && !pSheetObj->GetDocShell() ) // noch nicht eingefuegt?
			{
				String aNamStr(aName);
				SCTAB nPosition;
				if ( pDocShell->GetDocument()->GetTable( aNamStr, nPosition ) )
				{
					ScDocFunc aFunc(*pDocShell);
					if ( aFunc.DeleteTable( nPosition, sal_True, sal_True ) )
					{
						//	InsertTable kann jetzt eigentlich nicht schiefgehen...
						bDone = aFunc.InsertTable( nPosition, aNamStr, sal_True, sal_True );
						if (bDone)
							pSheetObj->InitInsertSheet( pDocShell, nPosition );
					}
				}
				else
				{
					// not found
					throw container::NoSuchElementException();
				}
			}
			else
				bIllArg = sal_True;
		}
		else
			bIllArg = sal_True;
	}

	if (!bDone)
	{
		if (bIllArg)
			throw lang::IllegalArgumentException();
		else
			throw uno::RuntimeException(); // NoSuchElementException is handled above
	}
}

void SAL_CALL ScTableSheetsObj::removeByName( const rtl::OUString& aName )
								throw(container::NoSuchElementException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	if (pDocShell)
	{
		SCTAB nIndex;
		String aString(aName);
		if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) )
		{
			ScDocFunc aFunc(*pDocShell);
			bDone = aFunc.DeleteTable( nIndex, sal_True, sal_True );
		}
		else
		{
			// not found
			throw container::NoSuchElementException();
		}
	}

	if (!bDone)
		throw uno::RuntimeException(); // NoSuchElementException is handled above
}

// XCellRangesAccess

uno::Reference< table::XCell > SAL_CALL ScTableSheetsObj::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow, sal_Int32 nSheet )
	throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
	if (! xSheet.is())
		throw lang::IndexOutOfBoundsException();

	return xSheet->getCellByPosition(nColumn, nRow);
}

uno::Reference< table::XCellRange > SAL_CALL ScTableSheetsObj::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom, sal_Int32 nSheet )
	throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<table::XCellRange> xSheet(static_cast<ScCellRangeObj*>(GetObjectByIndex_Impl((sal_uInt16)nSheet)));
	if (! xSheet.is())
		throw lang::IndexOutOfBoundsException();

	return xSheet->getCellRangeByPosition(nLeft, nTop, nRight, nBottom);
}

uno::Sequence < uno::Reference< table::XCellRange > > SAL_CALL ScTableSheetsObj::getCellRangesByName( const rtl::OUString& aRange )
	throw (lang::IllegalArgumentException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
    uno::Sequence < uno::Reference < table::XCellRange > > xRet;

	ScRangeList aRangeList;
	ScDocument* pDoc = pDocShell->GetDocument();
	if (ScRangeStringConverter::GetRangeListFromString( aRangeList, aRange, pDoc, ::formula::FormulaGrammar::CONV_OOO, ';' ))
    {
	    sal_Int32 nCount = aRangeList.Count();
        if (nCount)
        {
            xRet.realloc(nCount);
	        for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
	        {
		        const ScRange* pRange = aRangeList.GetObject( nIndex );
		        if( pRange )
                    xRet[nIndex] = new ScCellRangeObj(pDocShell, *pRange);
            }
        }
        else
            throw lang::IllegalArgumentException();
    }
    else
        throw lang::IllegalArgumentException();
    return xRet;
}

// XEnumerationAccess

uno::Reference<container::XEnumeration> SAL_CALL ScTableSheetsObj::createEnumeration()
													throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
    return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetsEnumeration")));
}

// XIndexAccess

sal_Int32 SAL_CALL ScTableSheetsObj::getCount() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
		return pDocShell->GetDocument()->GetTableCount();
	return 0;
}

uno::Any SAL_CALL ScTableSheetsObj::getByIndex( sal_Int32 nIndex )
							throw(lang::IndexOutOfBoundsException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByIndex_Impl(nIndex));
	if (xSheet.is())
        return uno::makeAny(xSheet);
	else
		throw lang::IndexOutOfBoundsException();
//    return uno::Any();
}

uno::Type SAL_CALL ScTableSheetsObj::getElementType() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return getCppuType((uno::Reference<sheet::XSpreadsheet>*)0);
}

sal_Bool SAL_CALL ScTableSheetsObj::hasElements() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return ( getCount() != 0 );
}

// XNameAccess

uno::Any SAL_CALL ScTableSheetsObj::getByName( const rtl::OUString& aName )
			throw(container::NoSuchElementException,
					lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<sheet::XSpreadsheet> xSheet(GetObjectByName_Impl(aName));
	if (xSheet.is())
        return uno::makeAny(xSheet);
	else
		throw container::NoSuchElementException();
//    return uno::Any();
}

uno::Sequence<rtl::OUString> SAL_CALL ScTableSheetsObj::getElementNames()
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		ScDocument* pDoc = pDocShell->GetDocument();
		SCTAB nCount = pDoc->GetTableCount();
		String aName;
		uno::Sequence<rtl::OUString> aSeq(nCount);
		rtl::OUString* pAry = aSeq.getArray();
		for (SCTAB i=0; i<nCount; i++)
		{
			pDoc->GetName( i, aName );
			pAry[i] = aName;
		}
		return aSeq;
	}
	return uno::Sequence<rtl::OUString>();
}

sal_Bool SAL_CALL ScTableSheetsObj::hasByName( const rtl::OUString& aName )
										throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		SCTAB nIndex;
		if ( pDocShell->GetDocument()->GetTable( String(aName), nIndex ) )
			return sal_True;
	}
	return sal_False;
}

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

ScTableColumnsObj::ScTableColumnsObj(ScDocShell* pDocSh, SCTAB nT, SCCOL nSC, SCCOL nEC) :
	pDocShell( pDocSh ),
	nTab	 ( nT ),
	nStartCol( nSC ),
	nEndCol	 ( nEC )
{
	pDocShell->GetDocument()->AddUnoObject(*this);
}

ScTableColumnsObj::~ScTableColumnsObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScTableColumnsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	if ( rHint.ISA( ScUpdateRefHint ) )
	{
//        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;

		//!	Referenz-Update für Tab und Start/Ende
	}
	else if ( rHint.ISA( SfxSimpleHint ) &&
			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
	{
		pDocShell = NULL; // ungültig geworden
	}
}

// XTableColumns

ScTableColumnObj* ScTableColumnsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
{
	SCCOL nCol = static_cast<SCCOL>(nIndex) + nStartCol;
	if ( pDocShell && nCol <= nEndCol )
		return new ScTableColumnObj( pDocShell, nCol, nTab );

	return NULL; // falscher Index
}

ScTableColumnObj* ScTableColumnsObj::GetObjectByName_Impl(const rtl::OUString& aName) const
{
	SCCOL nCol = 0;
	String aString(aName);
	if ( ::AlphaToCol( nCol, aString) )
		if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
			return new ScTableColumnObj( pDocShell, nCol, nTab );

	return NULL;
}

void SAL_CALL ScTableColumnsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartCol+nPosition <= nEndCol &&
			nStartCol+nPosition+nCount-1 <= MAXCOL )
	{
		ScDocFunc aFunc(*pDocShell);
		ScRange aRange( (SCCOL)(nStartCol+nPosition), 0, nTab,
						(SCCOL)(nStartCol+nPosition+nCount-1), MAXROW, nTab );
		bDone = aFunc.InsertCells( aRange, NULL, INS_INSCOLS, sal_True, sal_True );
	}
	if (!bDone)
		throw uno::RuntimeException(); // no other exceptions specified
}

void SAL_CALL ScTableColumnsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	//	Der zu löschende Bereich muss innerhalb des Objekts liegen
	if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartCol+nIndex+nCount-1 <= nEndCol )
	{
		ScDocFunc aFunc(*pDocShell);
		ScRange aRange( (SCCOL)(nStartCol+nIndex), 0, nTab,
						(SCCOL)(nStartCol+nIndex+nCount-1), MAXROW, nTab );
		bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELCOLS, sal_True, sal_True );
	}
	if (!bDone)
		throw uno::RuntimeException(); // no other exceptions specified
}

// XEnumerationAccess

uno::Reference<container::XEnumeration> SAL_CALL ScTableColumnsObj::createEnumeration()
													throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
    return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableColumnsEnumeration")));
}

// XIndexAccess

sal_Int32 SAL_CALL ScTableColumnsObj::getCount() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return nEndCol - nStartCol + 1;
}

uno::Any SAL_CALL ScTableColumnsObj::getByIndex( sal_Int32 nIndex )
							throw(lang::IndexOutOfBoundsException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<table::XCellRange> xColumn(GetObjectByIndex_Impl(nIndex));
	if (xColumn.is())
        return uno::makeAny(xColumn);
	else
		throw lang::IndexOutOfBoundsException();
//    return uno::Any();
}

uno::Type SAL_CALL ScTableColumnsObj::getElementType() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return getCppuType((uno::Reference<table::XCellRange>*)0);
}

sal_Bool SAL_CALL ScTableColumnsObj::hasElements() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return ( getCount() != 0 );
}

uno::Any SAL_CALL ScTableColumnsObj::getByName( const rtl::OUString& aName )
			throw(container::NoSuchElementException,
					lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<table::XCellRange> xColumn(GetObjectByName_Impl(aName));
	if (xColumn.is())
        return uno::makeAny(xColumn);
	else
		throw container::NoSuchElementException();
//    return uno::Any();
}

uno::Sequence<rtl::OUString> SAL_CALL ScTableColumnsObj::getElementNames()
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SCCOL nCount = nEndCol - nStartCol + 1;
	uno::Sequence<rtl::OUString> aSeq(nCount);
	rtl::OUString* pAry = aSeq.getArray();
	for (SCCOL i=0; i<nCount; i++)
		pAry[i] = ::ScColToAlpha( nStartCol + i );

	return aSeq;
}

sal_Bool SAL_CALL ScTableColumnsObj::hasByName( const rtl::OUString& aName )
										throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SCCOL nCol = 0;
	String aString(aName);
	if ( ::AlphaToCol( nCol, aString) )
		if ( pDocShell && nCol >= nStartCol && nCol <= nEndCol )
			return sal_True;

	return sal_False; // not found
}

// XPropertySet

uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnsObj::getPropertySetInfo()
														throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	static uno::Reference<beans::XPropertySetInfo> aRef(
		new SfxItemPropertySetInfo( lcl_GetColumnsPropertyMap() ));
	return aRef;
}

void SAL_CALL ScTableColumnsObj::setPropertyValue(
						const rtl::OUString& aPropertyName, const uno::Any& aValue )
				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
						lang::IllegalArgumentException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (!pDocShell)
		throw uno::RuntimeException();

	ScDocFunc aFunc(*pDocShell);
	SCCOLROW nColArr[2];
	nColArr[0] = nStartCol;
	nColArr[1] = nEndCol;
	String aNameString(aPropertyName);

	if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
	{
		sal_Int32 nNewWidth = 0;
		if ( aValue >>= nNewWidth )
			aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, SC_SIZE_ORIGINAL,
									(sal_uInt16)HMMToTwips(nNewWidth), sal_True, sal_True );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
	{
		sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
		ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
		aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, eMode, 0, sal_True, sal_True );
		//	SC_SIZE_DIRECT with size 0: hide
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
	{
		sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
		if (bOpt)
			aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab,
									SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, sal_True, sal_True );
		// sal_False for columns currently has no effect
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
	{
		//!	single function to set/remove all breaks?
		sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
		for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++)
			if (bSet)
				aFunc.InsertPageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
			else
				aFunc.RemovePageBreak( sal_True, ScAddress(nCol,0,nTab), sal_True, sal_True, sal_True );
	}
}

uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPropertyName )
				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (!pDocShell)
		throw uno::RuntimeException();

	ScDocument* pDoc = pDocShell->GetDocument();
	String aNameString(aPropertyName);
	uno::Any aAny;

	//!	loop over all columns for current state?

	if ( aNameString.EqualsAscii( SC_UNONAME_CELLWID ) )
	{
		// for hidden column, return original height
		sal_uInt16 nWidth = pDoc->GetOriginalWidth( nStartCol, nTab );
		aAny <<= (sal_Int32)TwipsToHMM(nWidth);
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
	{
        SCCOL nLastCol;
        bool bVis = !pDoc->ColHidden(nStartCol, nTab, nLastCol);
		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
	{
		sal_Bool bOpt = !(pDoc->GetColFlags( nStartCol, nTab ) & CR_MANUALSIZE);
		ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
	{
        ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
        ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
	{
        ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
        ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
	}

	return aAny;
}

SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableColumnsObj )

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

ScTableRowsObj::ScTableRowsObj(ScDocShell* pDocSh, SCTAB nT, SCROW nSR, SCROW nER) :
	pDocShell( pDocSh ),
	nTab	 ( nT ),
	nStartRow( nSR ),
	nEndRow	 ( nER )
{
	pDocShell->GetDocument()->AddUnoObject(*this);
}

ScTableRowsObj::~ScTableRowsObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScTableRowsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	if ( rHint.ISA( ScUpdateRefHint ) )
	{
//        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;

		//!	Referenz-Update fuer Tab und Start/Ende
	}
	else if ( rHint.ISA( SfxSimpleHint ) &&
			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
	{
		pDocShell = NULL; // ungültig geworden
	}
}

// XTableRows

ScTableRowObj* ScTableRowsObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
{
	SCROW nRow = static_cast<SCROW>(nIndex) + nStartRow;
	if ( pDocShell && nRow <= nEndRow )
		return new ScTableRowObj( pDocShell, nRow, nTab );

	return NULL; // falscher Index
}

void SAL_CALL ScTableRowsObj::insertByIndex( sal_Int32 nPosition, sal_Int32 nCount )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	if ( pDocShell && nCount > 0 && nPosition >= 0 && nStartRow+nPosition <= nEndRow &&
			nStartRow+nPosition+nCount-1 <= MAXROW )
	{
		ScDocFunc aFunc(*pDocShell);
		ScRange aRange( 0, (SCROW)(nStartRow+nPosition), nTab,
						MAXCOL, (SCROW)(nStartRow+nPosition+nCount-1), nTab );
		bDone = aFunc.InsertCells( aRange, NULL, INS_INSROWS, sal_True, sal_True );
	}
	if (!bDone)
		throw uno::RuntimeException(); // no other exceptions specified
}

void SAL_CALL ScTableRowsObj::removeByIndex( sal_Int32 nIndex, sal_Int32 nCount )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_Bool bDone = sal_False;
	//	Der zu löschende Bereich muss innerhalb des Objekts liegen
	if ( pDocShell && nCount > 0 && nIndex >= 0 && nStartRow+nIndex+nCount-1 <= nEndRow )
	{
		ScDocFunc aFunc(*pDocShell);
		ScRange aRange( 0, (SCROW)(nStartRow+nIndex), nTab,
						MAXCOL, (SCROW)(nStartRow+nIndex+nCount-1), nTab );
		bDone = aFunc.DeleteCells( aRange, NULL, DEL_DELROWS, sal_True, sal_True );
	}
	if (!bDone)
		throw uno::RuntimeException(); // no other exceptions specified
}

// XEnumerationAccess

uno::Reference<container::XEnumeration> SAL_CALL ScTableRowsObj::createEnumeration()
													throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
    return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.table.TableRowsEnumeration")));
}

// XIndexAccess

sal_Int32 SAL_CALL ScTableRowsObj::getCount() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return nEndRow - nStartRow + 1;
}

uno::Any SAL_CALL ScTableRowsObj::getByIndex( sal_Int32 nIndex )
							throw(lang::IndexOutOfBoundsException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<table::XCellRange> xRow(GetObjectByIndex_Impl(nIndex));
	if (xRow.is())
        return uno::makeAny(xRow);
	else
		throw lang::IndexOutOfBoundsException();
//    return uno::Any();
}

uno::Type SAL_CALL ScTableRowsObj::getElementType() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return getCppuType((uno::Reference<table::XCellRange>*)0);
}

sal_Bool SAL_CALL ScTableRowsObj::hasElements() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return ( getCount() != 0 );
}

// XPropertySet

uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowsObj::getPropertySetInfo()
														throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	static uno::Reference<beans::XPropertySetInfo> aRef(
		new SfxItemPropertySetInfo( lcl_GetRowsPropertyMap() ));
	return aRef;
}

void SAL_CALL ScTableRowsObj::setPropertyValue(
						const rtl::OUString& aPropertyName, const uno::Any& aValue )
				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
						lang::IllegalArgumentException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (!pDocShell)
		throw uno::RuntimeException();

	ScDocFunc aFunc(*pDocShell);
	ScDocument* pDoc = pDocShell->GetDocument();
	SCCOLROW nRowArr[2];
	nRowArr[0] = nStartRow;
	nRowArr[1] = nEndRow;
	String aNameString(aPropertyName);

    if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
    {
        sal_Int32 nNewHeight = 0;
        if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) )
        {
            // used to set the stored row height for rows with optimal height when loading.

            // TODO: It's probably cleaner to use a different property name
            // for this.
            pDoc->SetRowHeightOnly( nStartRow, nEndRow, nTab, (sal_uInt16)HMMToTwips(nNewHeight) );
        }
        else
        {
            sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
            if (bOpt)
                aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, sal_True, sal_True );
            else
            {
                //! manually set old heights again?
            }
        }
    }
    else if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
	{
		sal_Int32 nNewHeight = 0;
		if ( aValue >>= nNewHeight )
			aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_ORIGINAL,
									(sal_uInt16)HMMToTwips(nNewHeight), sal_True, sal_True );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
	{
		sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
		ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
		aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, eMode, 0, sal_True, sal_True );
		// SC_SIZE_DIRECT with size 0: hide
	}
    else if ( aNameString.EqualsAscii( SC_UNONAME_VISFLAG ) )
    {
        // #i116460# Shortcut to only set the flag, without drawing layer update etc.
        // Should only be used from import filters.
        pDoc->SetRowHidden(nStartRow, nEndRow, nTab, !ScUnoHelpFunctions::GetBoolFromAny( aValue ));
    }
	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
	{
		//! undo etc.
		if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
            pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true);
        else
            pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false);
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) )
	{
		//!	single function to set/remove all breaks?
		sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
		for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++)
			if (bSet)
				aFunc.InsertPageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
			else
				aFunc.RemovePageBreak( sal_False, ScAddress(0,nRow,nTab), sal_True, sal_True, sal_True );
	}
    else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
    {
        // #i57867# Background color is specified for row styles in the file format,
        // so it has to be supported along with the row properties (import only).

        // Use ScCellRangeObj to set the property for all cells in the rows
        // (this means, the "row attribute" must be set before individual cell attributes).

        ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
        uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
        xRangeObj->setPropertyValue( aPropertyName, aValue );
    }
}

uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aPropertyName )
				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (!pDocShell)
		throw uno::RuntimeException();

	ScDocument* pDoc = pDocShell->GetDocument();
	String aNameString(aPropertyName);
	uno::Any aAny;

	//! loop over all rows for current state?

	if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) )
	{
		// for hidden row, return original height
		sal_uInt16 nHeight = pDoc->GetOriginalHeight( nStartRow, nTab );
		aAny <<= (sal_Int32)TwipsToHMM(nHeight);
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
	{
        SCROW nLastRow;
        bool bVis = !pDoc->RowHidden(nStartRow, nTab, nLastRow);
		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
	{
        bool bVis = pDoc->RowFiltered(nStartRow, nTab);
		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
	{
		sal_Bool bOpt = !(pDoc->GetRowFlags( nStartRow, nTab ) & CR_MANUALSIZE);
		ScUnoHelpFunctions::SetBoolInAny( aAny, bOpt );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
	{
        ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
        ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
	}
	else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
	{
        ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
        ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
	}
    else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
    {
        // Use ScCellRangeObj to get the property from the cell range
        // (for completeness only, this is not used by the XML filter).

        ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab );
        uno::Reference<beans::XPropertySet> xRangeObj = new ScCellRangeObj( pDocShell, aRange );
        aAny = xRangeObj->getPropertyValue( aPropertyName );
    }

	return aAny;
}

SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableRowsObj )

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

//UNUSED2008-05  ScSpreadsheetSettingsObj::ScSpreadsheetSettingsObj(ScDocShell* pDocSh) :
//UNUSED2008-05  pDocShell( pDocSh )
//UNUSED2008-05  {
//UNUSED2008-05      pDocShell->GetDocument()->AddUnoObject(*this);
//UNUSED2008-05  }

ScSpreadsheetSettingsObj::~ScSpreadsheetSettingsObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScSpreadsheetSettingsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	// Referenz-Update interessiert hier nicht

	if ( rHint.ISA( SfxSimpleHint ) &&
			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
	{
		pDocShell = NULL; // ungültig geworden
	}
}

// XPropertySet

uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSpreadsheetSettingsObj::getPropertySetInfo()
														throw(uno::RuntimeException)
{
	//! muss noch
	return NULL;
}

void SAL_CALL ScSpreadsheetSettingsObj::setPropertyValue(
                        const rtl::OUString& /* aPropertyName */, const uno::Any& /* aValue */ )
				throw(beans::UnknownPropertyException, beans::PropertyVetoException,
						lang::IllegalArgumentException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	//! muss noch
}

uno::Any SAL_CALL ScSpreadsheetSettingsObj::getPropertyValue( const rtl::OUString& /* aPropertyName */ )
				throw(beans::UnknownPropertyException, lang::WrappedTargetException,
						uno::RuntimeException)
{
	//! muss noch
	return uno::Any();
}

SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSpreadsheetSettingsObj )

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

ScAnnotationsObj::ScAnnotationsObj(ScDocShell* pDocSh, SCTAB nT) :
	pDocShell( pDocSh ),
	nTab( nT )
{
	pDocShell->GetDocument()->AddUnoObject(*this);
}

ScAnnotationsObj::~ScAnnotationsObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScAnnotationsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	//!	nTab bei Referenz-Update anpassen!!!

	if ( rHint.ISA( SfxSimpleHint ) &&
			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
	{
		pDocShell = NULL; // ungültig geworden
	}
}

bool ScAnnotationsObj::GetAddressByIndex_Impl( sal_Int32 nIndex, ScAddress& rPos ) const
{
	if (pDocShell)
	{
		sal_Int32 nFound = 0;
		ScDocument* pDoc = pDocShell->GetDocument();
		ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
		for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
		{
            if (pCell->HasNote())
			{
				if (nFound == nIndex)
				{
					rPos = ScAddress( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() );
					return true;
				}
				++nFound;
			}
		}
	}
	return false;
}

ScAnnotationObj* ScAnnotationsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
{
	if (pDocShell)
	{
		ScAddress aPos;
		if ( GetAddressByIndex_Impl( nIndex, aPos ) )
			return new ScAnnotationObj( pDocShell, aPos );
	}
	return NULL;
}

// XSheetAnnotations

void SAL_CALL ScAnnotationsObj::insertNew(
        const table::CellAddress& aPosition, const ::rtl::OUString& rText )
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		DBG_ASSERT( aPosition.Sheet == nTab, "addAnnotation mit falschem Sheet" );
		ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );

        ScDocFunc aFunc( *pDocShell );
        aFunc.ReplaceNote( aPos, rText, 0, 0, sal_True );
	}
}

void SAL_CALL ScAnnotationsObj::removeByIndex( sal_Int32 nIndex ) throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if (pDocShell)
	{
		ScAddress aPos;
		if ( GetAddressByIndex_Impl( nIndex, aPos ) )
		{
			ScMarkData aMarkData;
			aMarkData.SelectTable( aPos.Tab(), sal_True );
			aMarkData.SetMultiMarkArea( ScRange(aPos) );

			ScDocFunc aFunc(*pDocShell);
			aFunc.DeleteContents( aMarkData, IDF_NOTE, sal_True, sal_True );
		}
	}
}

// XEnumerationAccess

uno::Reference<container::XEnumeration> SAL_CALL ScAnnotationsObj::createEnumeration()
													throw(uno::RuntimeException)
{
	//!	iterate directly (more efficiently)?

	ScUnoGuard aGuard;
    return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.CellAnnotationsEnumeration")));
}

// XIndexAccess

sal_Int32 SAL_CALL ScAnnotationsObj::getCount() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	sal_uLong nCount = 0;
	if (pDocShell)
	{
        ScCellIterator aCellIter( pDocShell->GetDocument(), 0,0, nTab, MAXCOL,MAXROW, nTab );
        for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext() )
            if (pCell->HasNote())
				++nCount;
	}
	return nCount;
}

uno::Any SAL_CALL ScAnnotationsObj::getByIndex( sal_Int32 nIndex )
							throw(lang::IndexOutOfBoundsException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<sheet::XSheetAnnotation> xAnnotation(GetObjectByIndex_Impl(nIndex));
	if (xAnnotation.is())
        return uno::makeAny(xAnnotation);
	else
		throw lang::IndexOutOfBoundsException();
//    return uno::Any();
}

uno::Type SAL_CALL ScAnnotationsObj::getElementType() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return getCppuType((uno::Reference<sheet::XSheetAnnotation>*)0);
}

sal_Bool SAL_CALL ScAnnotationsObj::hasElements() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return ( getCount() != 0 );
}

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

ScScenariosObj::ScScenariosObj(ScDocShell* pDocSh, SCTAB nT) :
	pDocShell( pDocSh ),
	nTab	 ( nT )
{
	pDocShell->GetDocument()->AddUnoObject(*this);
}

ScScenariosObj::~ScScenariosObj()
{
	if (pDocShell)
		pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScScenariosObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
	if ( rHint.ISA( ScUpdateRefHint ) )
	{
//        const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;

		//!	Referenz-Update fuer Tab und Start/Ende
	}
	else if ( rHint.ISA( SfxSimpleHint ) &&
			((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
	{
		pDocShell = NULL; // ungültig geworden
	}
}

// XScenarios

sal_Bool ScScenariosObj::GetScenarioIndex_Impl( const rtl::OUString& rName, SCTAB& rIndex )
{
	//!	Case-insensitive ????

	if ( pDocShell )
	{
		String aString(rName);

		String aTabName;
		ScDocument* pDoc = pDocShell->GetDocument();
		SCTAB nCount = (SCTAB)getCount();
		for (SCTAB i=0; i<nCount; i++)
			if (pDoc->GetName( nTab+i+1, aTabName ))
				if ( aTabName == aString )
				{
					rIndex = i;
					return sal_True;
				}
	}

	return sal_False;
}

ScTableSheetObj* ScScenariosObj::GetObjectByIndex_Impl(sal_Int32 nIndex)
{
	sal_uInt16 nCount = (sal_uInt16)getCount();
	if ( pDocShell && nIndex >= 0 && nIndex < nCount )
		return new ScTableSheetObj( pDocShell, nTab+static_cast<SCTAB>(nIndex)+1 );

	return NULL; // kein Dokument oder falscher Index
}

ScTableSheetObj* ScScenariosObj::GetObjectByName_Impl(const rtl::OUString& aName)
{
	SCTAB nIndex;
	if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
		return new ScTableSheetObj( pDocShell, nTab+nIndex+1 );

	return NULL; // not found
}

void SAL_CALL ScScenariosObj::addNewByName( const rtl::OUString& aName,
								const uno::Sequence<table::CellRangeAddress>& aRanges,
								const rtl::OUString& aComment )
									throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	if ( pDocShell )
	{
		ScMarkData aMarkData;
		aMarkData.SelectTable( nTab, sal_True );

		sal_uInt16 nRangeCount = (sal_uInt16)aRanges.getLength();
		if (nRangeCount)
		{
			const table::CellRangeAddress* pAry = aRanges.getConstArray();
			for (sal_uInt16 i=0; i<nRangeCount; i++)
			{
				DBG_ASSERT( pAry[i].Sheet == nTab, "addScenario mit falscher Tab" );
				ScRange aRange( (SCCOL)pAry[i].StartColumn, (SCROW)pAry[i].StartRow, nTab,
								(SCCOL)pAry[i].EndColumn,   (SCROW)pAry[i].EndRow,   nTab );

				aMarkData.SetMultiMarkArea( aRange );
			}
		}

		String aNameStr(aName);
		String aCommStr(aComment);

		Color aColor( COL_LIGHTGRAY ); // Default
		sal_uInt16 nFlags = SC_SCENARIO_SHOWFRAME | SC_SCENARIO_PRINTFRAME | SC_SCENARIO_TWOWAY | SC_SCENARIO_PROTECT;

		pDocShell->MakeScenario( nTab, aNameStr, aCommStr, aColor, nFlags, aMarkData );
	}
}

void SAL_CALL ScScenariosObj::removeByName( const rtl::OUString& aName )
											throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SCTAB nIndex;
	if ( pDocShell && GetScenarioIndex_Impl( aName, nIndex ) )
	{
		ScDocFunc aFunc(*pDocShell);
		aFunc.DeleteTable( nTab+nIndex+1, sal_True, sal_True );
	}
}

// XEnumerationAccess

uno::Reference<container::XEnumeration> SAL_CALL ScScenariosObj::createEnumeration()
													throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
    return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.ScenariosEnumeration")));
}

// XIndexAccess

sal_Int32 SAL_CALL ScScenariosObj::getCount() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SCTAB nCount = 0;
	if ( pDocShell )
	{
		ScDocument* pDoc = pDocShell->GetDocument();
		if (!pDoc->IsScenario(nTab))
		{
			SCTAB nTabCount = pDoc->GetTableCount();
			SCTAB nNext = nTab + 1;
			while (nNext < nTabCount && pDoc->IsScenario(nNext))
			{
				++nCount;
				++nNext;
			}
		}
	}
	return nCount;
}

uno::Any SAL_CALL ScScenariosObj::getByIndex( sal_Int32 nIndex )
							throw(lang::IndexOutOfBoundsException,
									lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<sheet::XScenario> xScen(GetObjectByIndex_Impl(nIndex));
	if (xScen.is())
        return uno::makeAny(xScen);
	else
		throw lang::IndexOutOfBoundsException();
//    return uno::Any();
}

uno::Type SAL_CALL ScScenariosObj::getElementType() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return getCppuType((uno::Reference<sheet::XScenario>*)0);
}

sal_Bool SAL_CALL ScScenariosObj::hasElements() throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	return ( getCount() != 0 );
}

uno::Any SAL_CALL ScScenariosObj::getByName( const rtl::OUString& aName )
			throw(container::NoSuchElementException,
					lang::WrappedTargetException, uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<sheet::XScenario> xScen(GetObjectByName_Impl(aName));
	if (xScen.is())
        return uno::makeAny(xScen);
	else
		throw container::NoSuchElementException();
//    return uno::Any();
}

uno::Sequence<rtl::OUString> SAL_CALL ScScenariosObj::getElementNames()
												throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SCTAB nCount = (SCTAB)getCount();
	uno::Sequence<rtl::OUString> aSeq(nCount);

	if ( pDocShell ) // sonst ist auch Count = 0
	{
		String aTabName;
		ScDocument* pDoc = pDocShell->GetDocument();
		rtl::OUString* pAry = aSeq.getArray();
		for (SCTAB i=0; i<nCount; i++)
			if (pDoc->GetName( nTab+i+1, aTabName ))
				pAry[i] = aTabName;
	}

	return aSeq;
}

sal_Bool SAL_CALL ScScenariosObj::hasByName( const rtl::OUString& aName )
										throw(uno::RuntimeException)
{
	ScUnoGuard aGuard;
	SCTAB nIndex;
	return GetScenarioIndex_Impl( aName, nIndex );
}

/* vim: set noet sw=4 ts=4: */
