diff options
author | Rüdiger Timm <rt@openoffice.org> | 2008-01-17 07:06:10 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2008-01-17 07:06:10 +0000 |
commit | 3381981e76873304b171f7df900561dac681d2af (patch) | |
tree | f496d5a2006e8719b5783d5a8966a05858ed3014 /oox/source/xls/sharedformulabuffer.cxx | |
parent | 90e7bde2a1f3dd8c81e947578f14f40059961740 (diff) |
#i10000# Bring module to HEAD.
Diffstat (limited to 'oox/source/xls/sharedformulabuffer.cxx')
-rw-r--r-- | oox/source/xls/sharedformulabuffer.cxx | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/oox/source/xls/sharedformulabuffer.cxx b/oox/source/xls/sharedformulabuffer.cxx new file mode 100644 index 000000000000..5a09ec22c407 --- /dev/null +++ b/oox/source/xls/sharedformulabuffer.cxx @@ -0,0 +1,220 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sharedformulabuffer.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "oox/xls/sharedformulabuffer.hxx" +#include <rtl/ustrbuf.hxx> +#include <com/sun/star/sheet/XFormulaTokens.hpp> +#include "oox/helper/recordinputstream.hxx" +#include "oox/xls/addressconverter.hxx" +#include "oox/xls/biffinputstream.hxx" +#include "oox/xls/defnamesbuffer.hxx" +#include "oox/xls/formulaparser.hxx" + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::table::CellAddress; +using ::com::sun::star::table::CellRangeAddress; +using ::com::sun::star::sheet::XFormulaTokens; +using ::com::sun::star::sheet::XNamedRange; + +namespace oox { +namespace xls { + +// ============================================================================ + +namespace { + +bool operator==( const CellAddress& rAddr1, const CellAddress& rAddr2 ) +{ + return + (rAddr1.Sheet == rAddr2.Sheet) && + (rAddr1.Column == rAddr2.Column) && + (rAddr1.Row == rAddr2.Row); +} + +bool lclContains( const CellRangeAddress& rRange, const CellAddress& rAddr ) +{ + return + (rRange.Sheet == rAddr.Sheet) && + (rRange.StartColumn <= rAddr.Column) && (rAddr.Column <= rRange.EndColumn) && + (rRange.StartRow <= rAddr.Row) && (rAddr.Row <= rRange.EndRow); +} + +} // namespace + +// ============================================================================ + +ExtCellFormulaContext::ExtCellFormulaContext( const WorksheetHelper& rHelper, + const Reference< XFormulaTokens >& rxTokens, const CellAddress& rCellPos ) : + SimpleFormulaContext( rxTokens, false, false ), + WorksheetHelper( rHelper ) +{ + setBaseAddress( rCellPos ); +} + +void ExtCellFormulaContext::setSharedFormula( const CellAddress& rBaseAddr ) +{ + getSharedFormulas().setSharedFormulaCell( *this, rBaseAddr ); +} + +// ============================================================================ + +SharedFormulaBuffer::SharedFormulaBuffer( const WorksheetHelper& rHelper ) : + WorksheetHelper( rHelper ) +{ +} + +void SharedFormulaBuffer::importSharedFmla( const OUString& rFormula, const OUString& rSharedRange, sal_Int32 nSharedId, const CellAddress& rBaseAddr ) +{ + CellRangeAddress aFmlaRange; + if( getAddressConverter().convertToCellRange( aFmlaRange, rSharedRange, getSheetIndex(), true ) ) + { + // create the defined name representing the shared formula + OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" ); + BinAddress aMapKey( nSharedId, 0 ); + Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey ); + // convert the formula definition + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY ); + if( xTokens.is() ) + { + SimpleFormulaContext aContext( xTokens, true, false ); + aContext.setBaseAddress( rBaseAddr ); + getFormulaParser().importFormula( aContext, rFormula ); + updateCachedCell( rBaseAddr, aMapKey ); + } + } +} + +void SharedFormulaBuffer::importSharedFmla( RecordInputStream& rStrm, const CellAddress& rBaseAddr ) +{ + BinRange aRange; + rStrm >> aRange; + CellRangeAddress aFmlaRange; + if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true ) ) + { + // create the defined name representing the shared formula + OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" ); + BinAddress aMapKey( rBaseAddr ); + Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey ); + // load the formula definition + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY ); + if( xTokens.is() ) + { + SimpleFormulaContext aContext( xTokens, true, false ); + aContext.setBaseAddress( rBaseAddr ); + getFormulaParser().importFormula( aContext, rStrm ); + updateCachedCell( rBaseAddr, aMapKey ); + } + } +} + +void SharedFormulaBuffer::importSharedFmla( BiffInputStream& rStrm, const CellAddress& rBaseAddr ) +{ + BinRange aRange; + aRange.read( rStrm, false ); // always 8bit column indexes + CellRangeAddress aFmlaRange; + if( getAddressConverter().convertToCellRange( aFmlaRange, aRange, getSheetIndex(), true ) ) + { + // create the defined name representing the shared formula + OSL_ENSURE( lclContains( aFmlaRange, rBaseAddr ), "SharedFormulaBuffer::importSharedFmla - invalid range for shared formula" ); + BinAddress aMapKey( rBaseAddr ); + Reference< XNamedRange > xNamedRange = createDefinedName( aMapKey ); + // load the formula definition + Reference< XFormulaTokens > xTokens( xNamedRange, UNO_QUERY ); + if( xTokens.is() ) + { + rStrm.skip( 2 ); // flags + SimpleFormulaContext aContext( xTokens, true, false ); + aContext.setBaseAddress( rBaseAddr ); + getFormulaParser().importFormula( aContext, rStrm ); + updateCachedCell( rBaseAddr, aMapKey ); + } + } +} + +void SharedFormulaBuffer::setSharedFormulaCell( ExtCellFormulaContext& rContext, const CellAddress& rBaseAddr ) +{ + if( !implSetSharedFormulaCell( rContext, BinAddress( rBaseAddr ) ) ) + if( rContext.getBaseAddress() == rBaseAddr ) + mxLastContext.reset( new ExtCellFormulaContext( rContext ) ); +} + +void SharedFormulaBuffer::setSharedFormulaCell( ExtCellFormulaContext& rContext, sal_Int32 nSharedId ) +{ + implSetSharedFormulaCell( rContext, BinAddress( nSharedId, 0 ) ); +} + +Reference< XNamedRange > SharedFormulaBuffer::createDefinedName( const BinAddress& rMapKey ) +{ + OSL_ENSURE( maIndexMap.count( rMapKey ) == 0, "SharedFormulaBuffer::createDefinedName - shared formula exists already" ); + // create the defined name representing the shared formula + OUString aName = OUStringBuffer().appendAscii( "__shared_" ). + append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) ). + append( sal_Unicode( '_' ) ).append( rMapKey.mnRow ). + append( sal_Unicode( '_' ) ).append( rMapKey.mnCol ).makeStringAndClear(); + Reference< XNamedRange > xNamedRange = getDefinedNames().createDefinedName( aName ); + sal_Int32 nTokenIndex = getDefinedNames().getTokenIndex( xNamedRange ); + if( nTokenIndex >= 0 ) + maIndexMap[ rMapKey ] = nTokenIndex; + return xNamedRange; +} + +bool SharedFormulaBuffer::implSetSharedFormulaCell( ExtCellFormulaContext& rContext, const BinAddress& rMapKey ) +{ + TokenIndexMap::const_iterator aIt = maIndexMap.find( rMapKey ); + sal_Int32 nTokenIndex = (aIt == maIndexMap.end()) ? -1 : aIt->second; + if( nTokenIndex >= 0 ) + { + getFormulaParser().convertNameToFormula( rContext, nTokenIndex ); + return true; + } + return false; +} + +void SharedFormulaBuffer::updateCachedCell( const CellAddress& rBaseAddr, const BinAddress& rMapKey ) +{ + if( mxLastContext.get() && (mxLastContext->getBaseAddress() == rBaseAddr) ) + implSetSharedFormulaCell( *mxLastContext, rMapKey ); + mxLastContext.reset(); +} + +// ============================================================================ + +} // namespace xls +} // namespace oox + |