diff options
Diffstat (limited to 'sc/source/ui/unoobj/docuno.cxx')
-rw-r--r-- | sc/source/ui/unoobj/docuno.cxx | 3776 |
1 files changed, 3776 insertions, 0 deletions
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx new file mode 100644 index 000000000000..3d3f0f479601 --- /dev/null +++ b/sc/source/ui/unoobj/docuno.cxx @@ -0,0 +1,3776 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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/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/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 "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; + +//------------------------------------------------------------------------ + +// alles ohne Which-ID, Map nur fuer 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_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_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() >= 19, "resource incomplete" ); + if( aStrings.Count() < 19 ) // 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( 18 ) ); + aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ), + aOpt.GetModuleName( SvtModuleOptions::E_SCALC ) ); + m_aUIProperties[0].Value = getGroupControlOpt( aAppGroupname, rtl::OUString() ); + + // 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( aStrings.GetString( 2 ) ), + 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( 6 ) ), + rtl::OUString(), + aPrintRangeOpt + ); + + // create a choice for the content to create + uno::Sequence< rtl::OUString > aChoices( 3 ), aHelpTexts( 3 ); + aChoices[0] = aStrings.GetString( 7 ); + aHelpTexts[0] = aStrings.GetString( 8 ); + aChoices[1] = aStrings.GetString( 9 ); + aHelpTexts[1] = aStrings.GetString( 10 ); + aChoices[2] = aStrings.GetString( 11 ); + aHelpTexts[2] = aStrings.GetString( 12 ); + m_aUIProperties[4].Value = getChoiceControlOpt( rtl::OUString(), + aHelpTexts, + 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( 13 ) ), + rtl::OUString(), + aPrintRangeOpt + ); + + // create a choice for the range to print + rtl::OUString aPrintRangeName( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) ); + aChoices.realloc( 2 ); + aHelpTexts.realloc( 2 ); + aChoices[0] = aStrings.GetString( 14 ); + aHelpTexts[0] = aStrings.GetString( 15 ); + aChoices[1] = aStrings.GetString( 16 ); + aHelpTexts[1] = aStrings.GetString( 17 ); + m_aUIProperties[6].Value = getChoiceControlOpt( rtl::OUString(), + aHelpTexts, + 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::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ), + rtl::OUString(), + aPageRangeOpt + ); + + // "Print only selected sheets" isn't needed because of the "Selected Sheets" choice in "Print content" +#if 0 + // create subgroup for sheets + m_aUIProperties[8].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 3 ) ), rtl::OUString() ); + + // create a bool option for selected pages only + m_aUIProperties[9].Value = getBoolControlOpt( rtl::OUString( aStrings.GetString( 4 ) ), + rtl::OUString( aStrings.GetString( 5 ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsOnlySelectedSheets" ) ), + i_bSelectedOnly + ); +#endif +} + +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 veraendert den RefCount, darum eine Referenz selber halten + // (direkt am m_refCount, um sich beim release nicht selbst zu loeschen) + comphelper::increment( m_refCount ); + // waehrend des queryInterface braucht man ein Ref auf das + // SvNumberFormatsSupplierObj, sonst wird es geloescht. + 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 zusaetzliche 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) +{ + if (pDocShell) + 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; +} + +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::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 = 15; + 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::XLinkTargetSupplier>*)0); + pPtr[nParentLen +11] = getCppuType((const uno::Reference<beans::XPropertySet>*)0); + pPtr[nParentLen +12] = getCppuType((const uno::Reference<lang::XMultiServiceFactory>*)0); + pPtr[nParentLen +13] = getCppuType((const uno::Reference<lang::XServiceInfo>*)0); + pPtr[nParentLen +14] = 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 ) ) + { + 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 && pDocShell->GetDocument()->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) ) + HandleCalculateEvents(); + } + } + else if ( rHint.ISA( ScPointerChangedHint ) ) + { + USHORT 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; +} + +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" ); + + BOOL bDone = 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 ) + { + BOOL bSheet = ( ScTableSheetObj::getImplementation( xInterface ) != NULL ); + BOOL bCursor = pSelObj->IsCursorOnly(); + const ScRangeList& rRanges = pSelObj->GetRangeList(); + + rMark.MarkFromRangeList( rRanges, FALSE ); + rMark.MarkToSimple(); + + 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 = 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 = 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, TRUE ); + rStatus.SetMode( SC_PRINTSEL_DOCUMENT ); + bDone = 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) + { + 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, 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; + 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 ) + { + 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( 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, FALSE, NULL, NULL ); + + ScRange aCellRange; + 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 0 + const ScPrintOptions& rPrintOpt = + #endif + // FIXME: is this for side effects ? + SC_MOD()->GetPrintOptions(); + 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( 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( 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, TRUE, NULL, 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 ) + pPDFData->SetLinkDest( aIter->nLinkId, pPDFData->CreateDest( aArea, nPage ) ); + } + } + else + { + // external link, use as-is + pPDFData->SetLinkURL( aIter->nLinkId, aBookmark ); + } + aIter++; + } + rBookmarks.clear(); + } + + delete pDrawView; +} + +// 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; + BOOL bLocked = 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; + USHORT 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(TRUE); + else + { + DBG_ERROR("keine DocShell"); //! Exception oder so? + } +} + +void SAL_CALL ScModelObj::calculateAll() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (pDocShell) + pDocShell->DoHardRecalc(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 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, 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); + BOOL bDone = aFunc.Unprotect( TABLEID_DOC, aString, 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 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; + 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 koennte theoretisch ein fremdes Objekt sein, also nur das + // oeffentliche 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, 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; + + 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 ) ) + { + BOOL bUndoEnabled = ScUnoHelpFunctions::GetBoolFromAny( aValue ); + pDoc->EnableUndo( bUndoEnabled ); + USHORT nCount = ( bUndoEnabled ? + static_cast< USHORT >( 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( 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_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, TRUE )); + } + else if ( aString.EqualsAscii( SC_UNO_ROWLABELRNG ) ) + { + aRet <<= uno::Reference<sheet::XLabelRanges>(new ScLabelRangesObj( pDocShell, 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_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); + USHORT 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; + } + + // #i64497# If a chart is in a temporary document during clipoard 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, becuase 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; + } + } + } + else + { + // alles was ich nicht kenn, werf 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; + + ULONG nRangeCount = rRanges.Count(); + aEvent.Changes.realloc( static_cast< sal_Int32 >( nRangeCount ) ); + for ( 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, 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 + ULONG nRangeCount = rRanges.Count(); + for ( ULONG nIndex = 0; nIndex < nRangeCount; ++nIndex ) + { + ScRange aRange( *rRanges.GetObject( nIndex ) ); + if ( aRange.aStart.Tab() == nTab ) + aTabRanges.Append( aRange ); + } + 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; // ungueltig geworden + } +} + +uno::Reference<drawing::XDrawPage> ScDrawPagesObj::GetObjectByIndex_Impl(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((USHORT)nIndex); + DBG_ASSERT(pPage,"Draw-Page nicht gefunden"); + 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, TRUE, 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, TRUE, 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; // ungueltig 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; + BOOL bDone = FALSE; + if (pDocShell) + { + String aNamStr(aName); + ScDocFunc aFunc(*pDocShell); + bDone = aFunc.InsertTable( nPosition, aNamStr, TRUE, 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; + BOOL bDone = FALSE; + if (pDocShell) + { + String aNamStr(aName); + SCTAB nSource; + if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) ) + bDone = pDocShell->MoveTable( nSource, nDestination, FALSE, 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; + BOOL bDone = FALSE; + if (pDocShell) + { + String aNamStr(aName); + String aNewStr(aCopy); + SCTAB nSource; + if ( pDocShell->GetDocument()->GetTable( aNamStr, nSource ) ) + { + bDone = pDocShell->MoveTable( nSource, nDestination, TRUE, 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, TRUE, 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; + BOOL bDone = FALSE; + BOOL bIllArg = 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, TRUE, TRUE ); + if (bDone) + pSheetObj->InitInsertSheet( pDocShell, nPosition ); + // Dokument und neuen Range am Objekt setzen + } + } + else + bIllArg = TRUE; + } + else + bIllArg = 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; + BOOL bDone = FALSE; + BOOL bIllArg = 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, TRUE, TRUE ) ) + { + // InsertTable kann jetzt eigentlich nicht schiefgehen... + bDone = aFunc.InsertTable( nPosition, aNamStr, TRUE, TRUE ); + if (bDone) + pSheetObj->InitInsertSheet( pDocShell, nPosition ); + } + } + else + { + // not found + throw container::NoSuchElementException(); + } + } + else + bIllArg = TRUE; + } + else + bIllArg = 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; + BOOL bDone = FALSE; + if (pDocShell) + { + SCTAB nIndex; + String aString(aName); + if ( pDocShell->GetDocument()->GetTable( aString, nIndex ) ) + { + ScDocFunc aFunc(*pDocShell); + bDone = aFunc.DeleteTable( nIndex, TRUE, 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((USHORT)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((USHORT)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 TRUE; + } + return 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 fuer Tab und Start/Ende + } + else if ( rHint.ISA( SfxSimpleHint ) && + ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + { + pDocShell = NULL; // ungueltig 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; + BOOL bDone = 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, TRUE, 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; + BOOL bDone = FALSE; + // Der zu loeschende 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, TRUE, 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 TRUE; + + return FALSE; // nicht gefunden +} + +// 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( TRUE, 1, nColArr, nTab, SC_SIZE_ORIGINAL, + (USHORT)HMMToTwips(nNewWidth), TRUE, TRUE ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) ) + { + BOOL bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue ); + ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT; + aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab, eMode, 0, TRUE, TRUE ); + // SC_SIZE_DIRECT with size 0: hide + } + else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) ) + { + BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue ); + if (bOpt) + aFunc.SetWidthOrHeight( TRUE, 1, nColArr, nTab, + SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, TRUE, TRUE ); + // 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? + BOOL bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue ); + for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++) + if (bSet) + aFunc.InsertPageBreak( TRUE, ScAddress(nCol,0,nTab), TRUE, TRUE, TRUE ); + else + aFunc.RemovePageBreak( TRUE, ScAddress(nCol,0,nTab), TRUE, TRUE, 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 + USHORT 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 ) ) + { + 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; // ungueltig 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; + BOOL bDone = 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, TRUE, 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; + BOOL bDone = FALSE; + // Der zu loeschende 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, TRUE, 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, (USHORT)HMMToTwips(nNewHeight) ); + } + else + { + BOOL bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue ); + if (bOpt) + aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, TRUE, TRUE ); + else + { + //! manually set old heights again? + } + } + } + else if ( aNameString.EqualsAscii( SC_UNONAME_CELLHGT ) ) + { + sal_Int32 nNewHeight = 0; + if ( aValue >>= nNewHeight ) + aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, SC_SIZE_ORIGINAL, + (USHORT)HMMToTwips(nNewHeight), TRUE, TRUE ); + } + else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) ) + { + BOOL bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue ); + ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT; + aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, eMode, 0, TRUE, TRUE ); + // SC_SIZE_DIRECT with size 0: hide + } + 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? + BOOL bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue ); + for (SCROW nRow=nStartRow; nRow<=nEndRow; nRow++) + if (bSet) + aFunc.InsertPageBreak( FALSE, ScAddress(0,nRow,nTab), TRUE, TRUE, TRUE ); + else + aFunc.RemovePageBreak( FALSE, ScAddress(0,nRow,nTab), TRUE, TRUE, 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 + USHORT 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 ) ) + { + 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; // ungueltig 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; // ungueltig 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, 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(), TRUE ); + aMarkData.SetMultiMarkArea( ScRange(aPos) ); + + ScDocFunc aFunc(*pDocShell); + aFunc.DeleteContents( aMarkData, IDF_NOTE, TRUE, 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; + 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; // ungueltig geworden + } +} + +// XScenarios + +BOOL ScScenariosObj::GetScenarioIndex_Impl( const rtl::OUString& rName, SCTAB& rIndex ) +{ + //! Case-insensitiv ???? + + 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 TRUE; + } + } + + return FALSE; +} + +ScTableSheetObj* ScScenariosObj::GetObjectByIndex_Impl(sal_Int32 nIndex) +{ + USHORT nCount = (USHORT)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; // nicht gefunden +} + +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, TRUE ); + + USHORT nRangeCount = (USHORT)aRanges.getLength(); + if (nRangeCount) + { + const table::CellRangeAddress* pAry = aRanges.getConstArray(); + for (USHORT 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 + USHORT 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, TRUE, 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 ); +} + + + + + |