diff options
Diffstat (limited to 'sc/source/filter/excel/xlroot.cxx')
-rw-r--r-- | sc/source/filter/excel/xlroot.cxx | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx new file mode 100644 index 000000000000..3dc0fda96dc0 --- /dev/null +++ b/sc/source/filter/excel/xlroot.cxx @@ -0,0 +1,440 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 "xlroot.hxx" +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <comphelper/processfactory.hxx> +#include <vcl/svapp.hxx> +#include <svl/stritem.hxx> +#include <svl/languageoptions.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/printer.hxx> +#include <sfx2/docfile.hxx> +#include <vcl/font.hxx> +#include <editeng/editstat.hxx> +#include "scitems.hxx" +#include <editeng/eeitem.hxx> +#include "document.hxx" +#include "docpool.hxx" +#include "docuno.hxx" +#include "editutil.hxx" +#include "drwlayer.hxx" +#include "scextopt.hxx" +#include "patattr.hxx" +#include "fapihelper.hxx" +#include "xlconst.hxx" +#include "xlstyle.hxx" +#include "xlchart.hxx" +#include "xltracer.hxx" +#include <unotools/useroptions.hxx> +#include "root.hxx" + +namespace ApiScriptType = ::com::sun::star::i18n::ScriptType; + +using ::rtl::OUString; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::awt::XDevice; +using ::com::sun::star::awt::DeviceInfo; +using ::com::sun::star::frame::XFrame; +using ::com::sun::star::frame::XFramesSupplier; +using ::com::sun::star::lang::XMultiServiceFactory; + +using namespace ::com::sun::star; + +// Global data ================================================================ + +#ifdef DBG_UTIL +XclDebugObjCounter::~XclDebugObjCounter() +{ + DBG_ASSERT( mnObjCnt == 0, "XclDebugObjCounter::~XclDebugObjCounter - wrong root object count" ); +} +#endif + +// ---------------------------------------------------------------------------- + +XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium, + SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc, bool bExport ) : + meBiff( eBiff ), + meOutput( EXC_OUTPUT_BINARY ), + mrMedium( rMedium ), + mxRootStrg( xRootStrg ), + mrDoc( rDoc ), + maDefPassword( CREATE_STRING( "VelvetSweatshop" ) ), + meTextEnc( eTextEnc ), + meSysLang( Application::GetSettings().GetLanguage() ), + meDocLang( Application::GetSettings().GetLanguage() ), + meUILang( Application::GetSettings().GetUILanguage() ), + mnDefApiScript( ApiScriptType::LATIN ), + maScMaxPos( MAXCOL, MAXROW, MAXTAB ), + maXclMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ), + maMaxPos( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ), + mxFontPropSetHlp( new XclFontPropSetHelper ), + mxChPropSetHlp( new XclChPropSetHelper ), + mxRD( new RootData ),//! + mfScreenPixelX( 50.0 ), + mfScreenPixelY( 50.0 ), + mnCharWidth( 110 ), + mnScTab( 0 ), + mbExport( bExport ) +{ + maUserName = SvtUserOptions().GetLastName(); + if( maUserName.Len() == 0 ) + maUserName = CREATE_STRING( "Calc" ); + + switch( ScGlobal::GetDefaultScriptType() ) + { + case SCRIPTTYPE_LATIN: mnDefApiScript = ApiScriptType::LATIN; break; + case SCRIPTTYPE_ASIAN: mnDefApiScript = ApiScriptType::ASIAN; break; + case SCRIPTTYPE_COMPLEX: mnDefApiScript = ApiScriptType::COMPLEX; break; + default: DBG_ERRORFILE( "XclRootData::XclRootData - unknown script type" ); + } + + // maximum cell position + switch( meBiff ) + { + case EXC_BIFF2: maXclMaxPos.Set( EXC_MAXCOL2, EXC_MAXROW2, EXC_MAXTAB2 ); break; + case EXC_BIFF3: maXclMaxPos.Set( EXC_MAXCOL3, EXC_MAXROW3, EXC_MAXTAB3 ); break; + case EXC_BIFF4: maXclMaxPos.Set( EXC_MAXCOL4, EXC_MAXROW4, EXC_MAXTAB4 ); break; + case EXC_BIFF5: maXclMaxPos.Set( EXC_MAXCOL5, EXC_MAXROW5, EXC_MAXTAB5 ); break; + case EXC_BIFF8: maXclMaxPos.Set( EXC_MAXCOL8, EXC_MAXROW8, EXC_MAXTAB8 ); break; + default: DBG_ERROR_BIFF(); + } + maMaxPos.SetCol( ::std::min( maScMaxPos.Col(), maXclMaxPos.Col() ) ); + maMaxPos.SetRow( ::std::min( maScMaxPos.Row(), maXclMaxPos.Row() ) ); + maMaxPos.SetTab( ::std::min( maScMaxPos.Tab(), maXclMaxPos.Tab() ) ); + + // document URL and path + if( const SfxItemSet* pItemSet = mrMedium.GetItemSet() ) + if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) ) + maDocUrl = pItem->GetValue(); + maBasePath = maDocUrl.Copy( 0, maDocUrl.SearchBackward( '/' ) + 1 ); + + // extended document options - always own object, try to copy existing data from document + if( const ScExtDocOptions* pOldDocOpt = mrDoc.GetExtDocOptions() ) + mxExtDocOpt.reset( new ScExtDocOptions( *pOldDocOpt ) ); + else + mxExtDocOpt.reset( new ScExtDocOptions ); + + // screen pixel size + try + { + Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW ); + Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW ); + Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW ); + Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW ); + DeviceInfo aDeviceInfo = xDevice->getInfo(); + mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0; + mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0; + } + catch( Exception& ) + { + OSL_FAIL( "XclRootData::XclRootData - cannot get output device info" ); + } +} + +XclRootData::~XclRootData() +{ +} + +// ---------------------------------------------------------------------------- + +XclRoot::XclRoot( XclRootData& rRootData ) : + mrData( rRootData ) +{ +#ifdef DBG_UTIL + ++mrData.mnObjCnt; +#endif + + // filter tracer + // do not use CREATE_OUSTRING for conditional expression + mrData.mxTracer.reset( new XclTracer( GetDocUrl(), IsExport() ? + OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Tracing/Export/Excel")) + : OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Tracing/Import/Excel" )) ) ); +} + +XclRoot::XclRoot( const XclRoot& rRoot ) : + mrData( rRoot.mrData ) +{ +#ifdef DBG_UTIL + ++mrData.mnObjCnt; +#endif +} + +XclRoot::~XclRoot() +{ +#ifdef DBG_UTIL + --mrData.mnObjCnt; +#endif +} + +XclRoot& XclRoot::operator=( const XclRoot& rRoot ) +{ + (void)rRoot; // avoid compiler warning + // allowed for assignment in derived classes - but test if the same root data is used + DBG_ASSERT( &mrData == &rRoot.mrData, "XclRoot::operator= - incompatible root data" ); + return *this; +} + +void XclRoot::SetTextEncoding( rtl_TextEncoding eTextEnc ) +{ + if( eTextEnc != RTL_TEXTENCODING_DONTKNOW ) + mrData.meTextEnc = eTextEnc; +} + +void XclRoot::SetCharWidth( const XclFontData& rFontData ) +{ + mrData.mnCharWidth = 0; + if( OutputDevice* pPrinter = GetPrinter() ) + { + Font aFont( rFontData.maName, Size( 0, rFontData.mnHeight ) ); + aFont.SetFamily( rFontData.GetScFamily( GetTextEncoding() ) ); + aFont.SetCharSet( rFontData.GetFontEncoding() ); + aFont.SetWeight( rFontData.GetScWeight() ); + pPrinter->SetFont( aFont ); + mrData.mnCharWidth = pPrinter->GetTextWidth( String( '0' ) ); + } + if( mrData.mnCharWidth <= 0 ) + { + // #i48717# Win98 with HP LaserJet returns 0 + DBG_ERRORFILE( "XclRoot::SetCharWidth - invalid character width (no printer?)" ); + mrData.mnCharWidth = 11 * rFontData.mnHeight / 20; + } +} + +sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const +{ + return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 ); +} + +sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const +{ + return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 ); +} + +double XclRoot::GetPixelXFromHmm( sal_Int32 nX ) const +{ + return static_cast< double >( (nX - 0.5) / mrData.mfScreenPixelX ); +} + +double XclRoot::GetPixelYFromHmm( sal_Int32 nY ) const +{ + return static_cast< double >( (nY - 0.5) / mrData.mfScreenPixelY ); +} + +uno::Sequence< beans::NamedValue > XclRoot::RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const +{ + ::std::vector< OUString > aDefaultPasswords; + aDefaultPasswords.push_back( mrData.maDefPassword ); + return ScfApiHelper::QueryEncryptionDataForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords ); +} + +bool XclRoot::HasVbaStorage() const +{ + SotStorageRef xRootStrg = GetRootStorage(); + return xRootStrg.Is() && xRootStrg->IsContained( EXC_STORAGE_VBA_PROJECT ); +} + +SotStorageRef XclRoot::OpenStorage( SotStorageRef xStrg, const String& rStrgName ) const +{ + return mrData.mbExport ? + ScfTools::OpenStorageWrite( xStrg, rStrgName ) : + ScfTools::OpenStorageRead( xStrg, rStrgName ); +} + +SotStorageRef XclRoot::OpenStorage( const String& rStrgName ) const +{ + return OpenStorage( GetRootStorage(), rStrgName ); +} + +SotStorageStreamRef XclRoot::OpenStream( SotStorageRef xStrg, const String& rStrmName ) const +{ + return mrData.mbExport ? + ScfTools::OpenStorageStreamWrite( xStrg, rStrmName ) : + ScfTools::OpenStorageStreamRead( xStrg, rStrmName ); +} + +SotStorageStreamRef XclRoot::OpenStream( const String& rStrmName ) const +{ + return OpenStream( GetRootStorage(), rStrmName ); +} + +SfxObjectShell* XclRoot::GetDocShell() const +{ + return GetDoc().GetDocumentShell(); +} + +ScModelObj* XclRoot::GetDocModelObj() const +{ + SfxObjectShell* pDocShell = GetDocShell(); + return pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : 0; +} + +OutputDevice* XclRoot::GetPrinter() const +{ + return GetDoc().GetRefDevice(); +} + +ScStyleSheetPool& XclRoot::GetStyleSheetPool() const +{ + return *GetDoc().GetStyleSheetPool(); +} + +ScRangeName& XclRoot::GetNamedRanges() const +{ + return *GetDoc().GetRangeName(); +} + +ScDBCollection& XclRoot::GetDatabaseRanges() const +{ + return *GetDoc().GetDBCollection(); +} + +SdrPage* XclRoot::GetSdrPage( SCTAB nScTab ) const +{ + return ((nScTab >= 0) && GetDoc().GetDrawLayer()) ? + GetDoc().GetDrawLayer()->GetPage( static_cast< sal_uInt16 >( nScTab ) ) : 0; +} + +SvNumberFormatter& XclRoot::GetFormatter() const +{ + return *GetDoc().GetFormatTable(); +} + +DateTime XclRoot::GetNullDate() const +{ + return *GetFormatter().GetNullDate(); +} + +sal_uInt16 XclRoot::GetBaseYear() const +{ + // return 1904 for 1904-01-01, and 1900 for 1899-12-30 + return (GetNullDate().GetYear() == 1904) ? 1904 : 1900; +} + +double XclRoot::GetDoubleFromDateTime( const DateTime& rDateTime ) const +{ + double fValue = rDateTime - GetNullDate(); + // adjust dates before 1900-03-01 to get correct time values in the range [0.0,1.0) + if( rDateTime < DateTime( Date( 1, 3, 1900 ) ) ) + fValue -= 1.0; + return fValue; +} + +DateTime XclRoot::GetDateTimeFromDouble( double fValue ) const +{ + DateTime aDateTime = GetNullDate() + fValue; + // adjust dates before 1900-03-01 to get correct time values + if( aDateTime < DateTime( Date( 1, 3, 1900 ) ) ) + aDateTime += 1L; + return aDateTime; +} + +ScEditEngineDefaulter& XclRoot::GetEditEngine() const +{ + if( !mrData.mxEditEngine.get() ) + { + mrData.mxEditEngine.reset( new ScEditEngineDefaulter( GetDoc().GetEnginePool() ) ); + ScEditEngineDefaulter& rEE = *mrData.mxEditEngine; + rEE.SetRefMapMode( MAP_100TH_MM ); + rEE.SetEditTextObjectPool( GetDoc().GetEditPool() ); + rEE.SetUpdateMode( false ); + rEE.EnableUndo( false ); + rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS ); + } + return *mrData.mxEditEngine; +} + +ScHeaderEditEngine& XclRoot::GetHFEditEngine() const +{ + if( !mrData.mxHFEditEngine.get() ) + { + mrData.mxHFEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True ) ); + ScHeaderEditEngine& rEE = *mrData.mxHFEditEngine; + rEE.SetRefMapMode( MAP_TWIP ); // headers/footers use twips as default metric + rEE.SetUpdateMode( false ); + rEE.EnableUndo( false ); + rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS ); + + // set Calc header/footer defaults + SfxItemSet* pEditSet = new SfxItemSet( rEE.GetEmptyItemSet() ); + SfxItemSet aItemSet( *GetDoc().GetPool(), ATTR_PATTERN_START, ATTR_PATTERN_END ); + ScPatternAttr::FillToEditItemSet( *pEditSet, aItemSet ); + // FillToEditItemSet() adjusts font height to 1/100th mm, we need twips + pEditSet->Put( aItemSet.Get( ATTR_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT ); + pEditSet->Put( aItemSet.Get( ATTR_CJK_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CJK ); + pEditSet->Put( aItemSet.Get( ATTR_CTL_FONT_HEIGHT ), EE_CHAR_FONTHEIGHT_CTL ); + rEE.SetDefaults( pEditSet ); // takes ownership + } + return *mrData.mxHFEditEngine; +} + +EditEngine& XclRoot::GetDrawEditEngine() const +{ + if( !mrData.mxDrawEditEng.get() ) + { + mrData.mxDrawEditEng.reset( new EditEngine( &GetDoc().GetDrawLayer()->GetItemPool() ) ); + EditEngine& rEE = *mrData.mxDrawEditEng; + rEE.SetRefMapMode( MAP_100TH_MM ); + rEE.SetUpdateMode( false ); + rEE.EnableUndo( false ); + rEE.SetControlWord( rEE.GetControlWord() & ~EE_CNTRL_ALLOWBIGOBJS ); + } + return *mrData.mxDrawEditEng; +} + +XclFontPropSetHelper& XclRoot::GetFontPropSetHelper() const +{ + return *mrData.mxFontPropSetHlp; +} + +XclChPropSetHelper& XclRoot::GetChartPropSetHelper() const +{ + return *mrData.mxChPropSetHlp; +} + +ScExtDocOptions& XclRoot::GetExtDocOptions() const +{ + return *mrData.mxExtDocOpt; +} + +XclTracer& XclRoot::GetTracer() const +{ + return *mrData.mxTracer; +} + +// ============================================================================ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |