summaryrefslogtreecommitdiff
path: root/oox/source/xls/sharedformulabuffer.cxx
diff options
context:
space:
mode:
authorRüdiger Timm <rt@openoffice.org>2008-01-17 07:06:10 +0000
committerRüdiger Timm <rt@openoffice.org>2008-01-17 07:06:10 +0000
commit3381981e76873304b171f7df900561dac681d2af (patch)
treef496d5a2006e8719b5783d5a8966a05858ed3014 /oox/source/xls/sharedformulabuffer.cxx
parent90e7bde2a1f3dd8c81e947578f14f40059961740 (diff)
#i10000# Bring module to HEAD.
Diffstat (limited to 'oox/source/xls/sharedformulabuffer.cxx')
-rw-r--r--oox/source/xls/sharedformulabuffer.cxx220
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
+