summaryrefslogtreecommitdiff
path: root/oox/source/xls/sheetdatacontext.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source/xls/sheetdatacontext.cxx')
-rw-r--r--oox/source/xls/sheetdatacontext.cxx870
1 files changed, 442 insertions, 428 deletions
diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx
index c515ec02bfbe..00c4e21d82e7 100644
--- a/oox/source/xls/sheetdatacontext.cxx
+++ b/oox/source/xls/sheetdatacontext.cxx
@@ -27,8 +27,6 @@
#include "oox/xls/sheetdatacontext.hxx"
-#include <com/sun/star/sheet/XArrayFormulaTokens.hpp>
-#include <com/sun/star/sheet/XFormulaTokens.hpp>
#include <com/sun/star/table/CellContentType.hpp>
#include <com/sun/star/table/XCell.hpp>
#include <com/sun/star/table/XCellRange.hpp>
@@ -39,7 +37,6 @@
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/formulaparser.hxx"
#include "oox/xls/richstringcontext.hxx"
-#include "oox/xls/sharedformulabuffer.hxx"
#include "oox/xls/unitconverter.hxx"
namespace oox {
@@ -98,64 +95,31 @@ const sal_uInt32 BIFF_ROW_THICKTOP = 0x10000000;
const sal_uInt32 BIFF_ROW_THICKBOTTOM = 0x20000000;
const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000;
-const sal_Int32 BIFF2_XF_EXTENDED_IDS = 63;
-const sal_uInt8 BIFF2_XF_MASK = 0x3F;
+const sal_Int32 BIFF2_CELL_USEIXFE = 63;
-// ----------------------------------------------------------------------------
-
-/** Formula context for cell formulas. */
-class CellFormulaContext : public SimpleFormulaContext
-{
-public:
- explicit CellFormulaContext(
- const Reference< XFormulaTokens >& rxTokens,
- const CellAddress& rCellPos );
-};
-
-CellFormulaContext::CellFormulaContext( const Reference< XFormulaTokens >& rxTokens, const CellAddress& rCellPos ) :
- SimpleFormulaContext( rxTokens, false, false )
-{
- setBaseAddress( rCellPos );
-}
-
-// ----------------------------------------------------------------------------
-
-/** Uses the XArrayFormulaTokens interface to set a token sequence. */
-class ArrayFormulaContext : public FormulaContext
-{
-public:
- explicit ArrayFormulaContext(
- const Reference< XArrayFormulaTokens >& rxTokens,
- const CellRangeAddress& rArrayRange );
-
- virtual void setTokens( const ApiTokenSequence& rTokens );
+} // namespace
-private:
- Reference< XArrayFormulaTokens > mxTokens;
-};
+// ============================================================================
-ArrayFormulaContext::ArrayFormulaContext(
- const Reference< XArrayFormulaTokens >& rxTokens, const CellRangeAddress& rArrayRange ) :
- FormulaContext( false, false ),
- mxTokens( rxTokens )
+SheetDataContextBase::SheetDataContextBase( const WorksheetHelper& rHelper ) :
+ mrAddressConv( rHelper.getAddressConverter() ),
+ mrFormulaParser( rHelper.getFormulaParser() ),
+ mrSheetData( rHelper.getSheetData() ),
+ mnSheet( rHelper.getSheetIndex() )
{
- OSL_ENSURE( mxTokens.is(), "ArrayFormulaContext::ArrayFormulaContext - missing XArrayFormulaTokens interface" );
- setBaseAddress( CellAddress( rArrayRange.Sheet, rArrayRange.StartColumn, rArrayRange.StartRow ) );
}
-void ArrayFormulaContext::setTokens( const ApiTokenSequence& rTokens )
+SheetDataContextBase::~SheetDataContextBase()
{
- mxTokens->setArrayTokens( rTokens );
}
-// ----------------------------------------------------------------------------
-
-} // namespace
-
// ============================================================================
SheetDataContext::SheetDataContext( WorksheetFragmentBase& rFragment ) :
- WorksheetContextBase( rFragment )
+ WorksheetContextBase( rFragment ),
+ SheetDataContextBase( rFragment ),
+ mbHasFormula( false ),
+ mbValidRange( false )
{
}
@@ -168,20 +132,22 @@ ContextHandlerRef SheetDataContext::onCreateContext( sal_Int32 nElement, const A
break;
case XLS_TOKEN( row ):
- if( nElement == XLS_TOKEN( c ) ) { importCell( rAttribs ); return this; }
+ // do not process cell elements with invalid (out-of-range) address
+ if( nElement == XLS_TOKEN( c ) && importCell( rAttribs ) )
+ return this;
break;
case XLS_TOKEN( c ):
- if( maCurrCell.mxCell.is() ) switch( nElement )
+ switch( nElement )
{
case XLS_TOKEN( is ):
mxInlineStr.reset( new RichString( *this ) );
return new RichStringContext( *this, mxInlineStr );
case XLS_TOKEN( v ):
- return this;
+ return this; // characters contain cell value
case XLS_TOKEN( f ):
importFormula( rAttribs );
- return this;
+ return this; // characters contain formula string
}
break;
}
@@ -193,94 +159,86 @@ void SheetDataContext::onCharacters( const OUString& rChars )
switch( getCurrentElement() )
{
case XLS_TOKEN( v ):
- maCurrCell.maValueStr = rChars;
- maCurrCell.mbHasValueStr = true;
+ maCellValue = rChars;
break;
-
case XLS_TOKEN( f ):
- if( maCurrCell.mxCell.is() ) try
- {
- switch( maCurrCell.mnFormulaType )
- {
- case XML_normal:
- if( rChars.getLength() > 0 )
- {
- Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW );
- CellFormulaContext aContext( xTokens, maCurrCell.maAddress );
- getFormulaParser().importFormula( aContext, rChars );
- }
- break;
-
- case XML_array:
- if( (maCurrCell.maFormulaRef.getLength() > 0) && (rChars.getLength() > 0) )
- {
- CellRangeAddress aArrayRange;
- Reference< XArrayFormulaTokens > xTokens( getCellRange( maCurrCell.maFormulaRef, &aArrayRange ), UNO_QUERY_THROW );
- ArrayFormulaContext aContext( xTokens, aArrayRange );
- getFormulaParser().importFormula( aContext, rChars );
- }
- break;
-
- case XML_shared:
- if( maCurrCell.mnSharedId >= 0 )
- {
- if( rChars.getLength() > 0 )
- getSharedFormulas().importSharedFmla( rChars, maCurrCell.maFormulaRef, maCurrCell.mnSharedId, maCurrCell.maAddress );
- Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY_THROW );
- ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress );
- getSharedFormulas().setSharedFormulaCell( aContext, maCurrCell.mnSharedId );
- }
- break;
-
- case XML_dataTable:
- if( maCurrCell.maFormulaRef.getLength() > 0 )
- {
- CellRangeAddress aTableRange;
- if( getAddressConverter().convertToCellRange( aTableRange, maCurrCell.maFormulaRef, getSheetIndex(), true, true ) )
- setTableOperation( aTableRange, maTableData );
- }
- break;
-
- default:
- OSL_ENSURE( false, "SheetDataContext::onCharacters - unknown formula type" );
- }
- }
- catch( Exception& )
- {
- }
+ if( maFmlaData.mnFormulaType != XML_TOKEN_INVALID )
+ maTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, rChars );
break;
}
}
void SheetDataContext::onEndElement()
{
- if( isCurrentElement( XLS_TOKEN( c ) ) && maCurrCell.mxCell.is() )
+ if( getCurrentElement() == XLS_TOKEN( c ) )
{
- if( maCurrCell.mxCell->getType() == CellContentType_EMPTY )
+ // try to create a formula cell
+ if( mbHasFormula ) switch( maFmlaData.mnFormulaType )
+ {
+ case XML_normal:
+ mrSheetData.setFormulaCell( maCellData, maTokens );
+ break;
+ case XML_shared:
+ if( maFmlaData.mnSharedId >= 0 )
+ {
+ if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
+ mrSheetData.createSharedFormula( maFmlaData.mnSharedId, maTokens );
+ mrSheetData.setFormulaCell( maCellData, maFmlaData.mnSharedId );
+ }
+ else
+ // no success, set plain cell value and formatting below
+ mbHasFormula = false;
+ break;
+ case XML_array:
+ if( mbValidRange && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
+ mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, maTokens );
+ // set cell formatting, but do not set result as cell value
+ mrSheetData.setBlankCell( maCellData );
+ break;
+ case XML_dataTable:
+ if( mbValidRange )
+ mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData );
+ // set cell formatting, but do not set result as cell value
+ mrSheetData.setBlankCell( maCellData );
+ break;
+ default:
+ OSL_ENSURE( maFmlaData.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onEndElement - unknown formula type" );
+ mbHasFormula = false;
+ }
+
+ if( !mbHasFormula )
{
- if( maCurrCell.mbHasValueStr )
+ // no formula created: try to set the cell value
+ if( maCellValue.getLength() > 0 ) switch( maCellData.mnCellType )
{
- // implemented in WorksheetHelper class
- setCell( maCurrCell );
+ case XML_n:
+ mrSheetData.setValueCell( maCellData, maCellValue.toDouble() );
+ break;
+ case XML_b:
+ mrSheetData.setBooleanCell( maCellData, maCellValue.toDouble() != 0.0 );
+ break;
+ case XML_e:
+ mrSheetData.setErrorCell( maCellData, maCellValue );
+ break;
+ case XML_str:
+ mrSheetData.setStringCell( maCellData, maCellValue );
+ break;
+ case XML_s:
+ mrSheetData.setStringCell( maCellData, maCellValue.toInt32() );
+ break;
}
- else if( (maCurrCell.mnCellType == XML_inlineStr) && mxInlineStr.get() )
+ else if( (maCellData.mnCellType == XML_inlineStr) && mxInlineStr.get() )
{
- // convert font settings
mxInlineStr->finalizeImport();
- // write string to cell
- Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
- if( xText.is() )
- mxInlineStr->convert( xText, maCurrCell.mnXfId );
+ mrSheetData.setStringCell( maCellData, mxInlineStr );
}
else
{
// empty cell, update cell type
- maCurrCell.mnCellType = XML_TOKEN_INVALID;
+ maCellData.mnCellType = XML_TOKEN_INVALID;
+ mrSheetData.setBlankCell( maCellData );
}
}
-
- // store the cell formatting data
- setCellFormat( maCurrCell );
}
}
@@ -289,10 +247,7 @@ ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, Seq
switch( getCurrentElement() )
{
case BIFF12_ID_SHEETDATA:
- switch( nRecId )
- {
- case BIFF12_ID_ROW: importRow( rStrm ); return this;
- }
+ if( nRecId == BIFF12_ID_ROW ) { importRow( rStrm ); return this; }
break;
case BIFF12_ID_ROW:
@@ -332,7 +287,7 @@ ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, Seq
void SheetDataContext::importRow( const AttributeList& rAttribs )
{
RowModel aModel;
- aModel.mnFirstRow = aModel.mnLastRow = rAttribs.getInteger( XML_r, -1 );
+ aModel.mnRow = rAttribs.getInteger( XML_r, -1 );
aModel.mfHeight = rAttribs.getDouble( XML_ht, -1.0 );
aModel.mnXfId = rAttribs.getInteger( XML_s, -1 );
aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
@@ -343,41 +298,106 @@ void SheetDataContext::importRow( const AttributeList& rAttribs )
aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
aModel.mbThickTop = rAttribs.getBool( XML_thickTop, false );
aModel.mbThickBottom = rAttribs.getBool( XML_thickBot, false );
+
+ // decode the column spans (space-separated list of colon-separated integer pairs)
+ OUString aColSpansText = rAttribs.getString( XML_spans, OUString() );
+ sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ {
+ OUString aColSpanToken = aColSpansText.getToken( 0, ' ', nIndex );
+ sal_Int32 nSepPos = aColSpanToken.indexOf( ':' );
+ if( (0 < nSepPos) && (nSepPos + 1 < aColSpanToken.getLength()) )
+ {
+ // OOXML uses 1-based integer column indexes, row model expects 0-based colspans
+ sal_Int32 nLastCol = ::std::min( aColSpanToken.copy( nSepPos + 1 ).toInt32() - 1, nMaxCol );
+ aModel.insertColSpan( ValueRange( aColSpanToken.copy( 0, nSepPos ).toInt32() - 1, nLastCol ) );
+ }
+ }
+
// set row properties in the current sheet
setRowModel( aModel );
}
-void SheetDataContext::importCell( const AttributeList& rAttribs )
+bool SheetDataContext::importCell( const AttributeList& rAttribs )
{
- maCurrCell.reset();
- maCurrCell.mxCell = getCell( rAttribs.getString( XML_r, OUString() ), &maCurrCell.maAddress );
- maCurrCell.mnCellType = rAttribs.getToken( XML_t, XML_n );
- maCurrCell.mnXfId = rAttribs.getInteger( XML_s, -1 );
- maCurrCell.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
- mxInlineStr.reset();
+ bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, rAttribs.getString( XML_r, OUString() ), mnSheet, true );
+ if( bValidAddr )
+ {
+ maCellData.mnCellType = rAttribs.getToken( XML_t, XML_n );
+ maCellData.mnXfId = rAttribs.getInteger( XML_s, -1 );
+ maCellData.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
- // update used area of the sheet
- if( maCurrCell.mxCell.is() )
- extendUsedArea( maCurrCell.maAddress );
+ // reset cell value, formula settings, and inline string
+ maCellValue = OUString();
+ mxInlineStr.reset();
+ mbHasFormula = false;
+
+ // update used area of the sheet
+ extendUsedArea( maCellData.maCellAddr );
+ }
+ return bValidAddr;
}
void SheetDataContext::importFormula( const AttributeList& rAttribs )
{
- maCurrCell.maFormulaRef = rAttribs.getString( XML_ref, OUString() );
- maCurrCell.mnFormulaType = rAttribs.getToken( XML_t, XML_normal );
- maCurrCell.mnSharedId = rAttribs.getInteger( XML_si, -1 );
- maTableData.maRef1 = rAttribs.getString( XML_r1, OUString() );
- maTableData.maRef2 = rAttribs.getString( XML_r2, OUString() );
- maTableData.mb2dTable = rAttribs.getBool( XML_dt2D, false );
- maTableData.mbRowTable = rAttribs.getBool( XML_dtr, false );
- maTableData.mbRef1Deleted = rAttribs.getBool( XML_del1, false );
- maTableData.mbRef2Deleted = rAttribs.getBool( XML_del2, false );
+ mbHasFormula = true;
+ mbValidRange = mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, rAttribs.getString( XML_ref, OUString() ), mnSheet, true, true );
+
+ maFmlaData.mnFormulaType = rAttribs.getToken( XML_t, XML_normal );
+ maFmlaData.mnSharedId = rAttribs.getInteger( XML_si, -1 );
+
+ if( maFmlaData.mnFormulaType == XML_dataTable )
+ {
+ maTableData.maRef1 = rAttribs.getString( XML_r1, OUString() );
+ maTableData.maRef2 = rAttribs.getString( XML_r2, OUString() );
+ maTableData.mb2dTable = rAttribs.getBool( XML_dt2D, false );
+ maTableData.mbRowTable = rAttribs.getBool( XML_dtr, false );
+ maTableData.mbRef1Deleted = rAttribs.getBool( XML_del1, false );
+ maTableData.mbRef2Deleted = rAttribs.getBool( XML_del2, false );
+ }
+
+ // clear token array, will be regenerated from element text
+ maTokens = ApiTokenSequence();
}
-void SheetDataContext::importCellHeader( SequenceInputStream& rStrm, CellType eCellType )
+void SheetDataContext::importRow( SequenceInputStream& rStrm )
{
- maCurrCell.reset();
+ RowModel aModel;
+ sal_Int32 nSpanCount;
+ sal_uInt16 nHeight, nFlags1;
+ sal_uInt8 nFlags2;
+ rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2 >> nSpanCount;
+ maCurrPos.mnCol = 0;
+ // row index is 0-based in BIFF12, but RowModel expects 1-based
+ aModel.mnRow = maCurrPos.mnRow + 1;
+ // row height is in twips in BIFF12, convert to points
+ aModel.mfHeight = nHeight / 20.0;
+ aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 );
+ aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT );
+ aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT );
+ aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC );
+ aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN );
+ aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED );
+ aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP );
+ aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM );
+
+ // read the column spans
+ sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
+ for( sal_Int32 nSpanIdx = 0; (nSpanIdx < nSpanCount) && !rStrm.isEof(); ++nSpanIdx )
+ {
+ sal_Int32 nFirstCol, nLastCol;
+ rStrm >> nFirstCol >> nLastCol;
+ aModel.insertColSpan( ValueRange( nFirstCol, ::std::min( nLastCol, nMaxCol ) ) );
+ }
+
+ // set row properties in the current sheet
+ setRowModel( aModel );
+}
+
+bool SheetDataContext::readCellHeader( SequenceInputStream& rStrm, CellType eCellType )
+{
switch( eCellType )
{
case CELLTYPE_VALUE:
@@ -388,200 +408,157 @@ void SheetDataContext::importCellHeader( SequenceInputStream& rStrm, CellType eC
sal_uInt32 nXfId;
rStrm >> nXfId;
- maCurrCell.mxCell = getCell( maCurrPos, &maCurrCell.maAddress );
- maCurrCell.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 );
- maCurrCell.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC );
+ bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, maCurrPos, mnSheet, true );
+ maCellData.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 );
+ maCellData.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC );
// update used area of the sheet
- if( maCurrCell.mxCell.is() )
- extendUsedArea( maCurrCell.maAddress );
+ if( bValidAddr )
+ extendUsedArea( maCellData.maCellAddr );
+ return bValidAddr;
+}
+
+ApiTokenSequence SheetDataContext::readCellFormula( SequenceInputStream& rStrm )
+{
+ rStrm.skip( 2 );
+ return mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm );
+}
+
+bool SheetDataContext::readFormulaRef( SequenceInputStream& rStrm )
+{
+ BinRange aRange;
+ rStrm >> aRange;
+ return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true );
}
void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCellType )
{
- importCellHeader( rStrm, eCellType );
- maCurrCell.mnCellType = XML_b;
- if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ if( readCellHeader( rStrm, eCellType ) )
{
+ maCellData.mnCellType = XML_b;
bool bValue = rStrm.readuInt8() != 0;
if( eCellType == CELLTYPE_FORMULA )
- {
- importCellFormula( rStrm );
- }
+ mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
else
- {
- setBooleanCell( maCurrCell.mxCell, bValue );
- // #108770# set 'Standard' number format for all Boolean cells
- maCurrCell.mnNumFmtId = 0;
- }
+ mrSheetData.setBooleanCell( maCellData, bValue );
}
- setCellFormat( maCurrCell );
}
void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCellType )
{
OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" );
- importCellHeader( rStrm, eCellType );
- setCellFormat( maCurrCell );
+ if( readCellHeader( rStrm, eCellType ) )
+ mrSheetData.setBlankCell( maCellData );
}
void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType )
{
- importCellHeader( rStrm, eCellType );
- maCurrCell.mnCellType = XML_n;
- if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ if( readCellHeader( rStrm, eCellType ) )
{
+ maCellData.mnCellType = XML_n;
double fValue = rStrm.readDouble();
if( eCellType == CELLTYPE_FORMULA )
- importCellFormula( rStrm );
+ mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
else
- maCurrCell.mxCell->setValue( fValue );
+ mrSheetData.setValueCell( maCellData, fValue );
}
- setCellFormat( maCurrCell );
}
void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCellType )
{
- importCellHeader( rStrm, eCellType );
- maCurrCell.mnCellType = XML_e;
- if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ if( readCellHeader( rStrm, eCellType ) )
{
+ maCellData.mnCellType = XML_e;
sal_uInt8 nErrorCode = rStrm.readuInt8();
if( eCellType == CELLTYPE_FORMULA )
- importCellFormula( rStrm );
+ mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
else
- setErrorCell( maCurrCell.mxCell, nErrorCode );
+ mrSheetData.setErrorCell( maCellData, nErrorCode );
}
- setCellFormat( maCurrCell );
}
void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellType )
{
OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRk - no formula cells supported" );
- importCellHeader( rStrm, eCellType );
- maCurrCell.mnCellType = XML_n;
- if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
- maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
- setCellFormat( maCurrCell );
+ if( readCellHeader( rStrm, eCellType ) )
+ {
+ maCellData.mnCellType = XML_n;
+ mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
+ }
}
void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType eCellType )
{
OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRString - no formula cells supported" );
- importCellHeader( rStrm, eCellType );
- maCurrCell.mnCellType = XML_inlineStr;
- Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
- if( xText.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ if( readCellHeader( rStrm, eCellType ) )
{
- RichString aString( *this );
- aString.importString( rStrm, true );
- aString.finalizeImport();
- aString.convert( xText, maCurrCell.mnXfId );
+ maCellData.mnCellType = XML_inlineStr;
+ RichStringRef xString( new RichString( *this ) );
+ xString->importString( rStrm, true );
+ xString->finalizeImport();
+ mrSheetData.setStringCell( maCellData, xString );
}
- setCellFormat( maCurrCell );
}
void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellType )
{
OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellSi - no formula cells supported" );
- importCellHeader( rStrm, eCellType );
- maCurrCell.mnCellType = XML_s;
- if( maCurrCell.mxCell.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
- setSharedStringCell( maCurrCell.mxCell, rStrm.readInt32(), maCurrCell.mnXfId );
- setCellFormat( maCurrCell );
+ if( readCellHeader( rStrm, eCellType ) )
+ {
+ maCellData.mnCellType = XML_s;
+ mrSheetData.setStringCell( maCellData, rStrm.readInt32() );
+ }
}
void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eCellType )
{
- importCellHeader( rStrm, eCellType );
- maCurrCell.mnCellType = XML_inlineStr;
- Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
- if( xText.is() && (maCurrCell.mxCell->getType() == CellContentType_EMPTY) )
+ if( readCellHeader( rStrm, eCellType ) )
{
- RichString aString( *this );
- aString.importString( rStrm, false );
- aString.finalizeImport();
+ maCellData.mnCellType = XML_inlineStr;
+ // always import the string, stream will point to formula afterwards, if existing
+ RichStringRef xString( new RichString( *this ) );
+ xString->importString( rStrm, false );
+ xString->finalizeImport();
if( eCellType == CELLTYPE_FORMULA )
- importCellFormula( rStrm );
+ mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
else
- aString.convert( xText, maCurrCell.mnXfId );
+ mrSheetData.setStringCell( maCellData, xString );
}
- setCellFormat( maCurrCell );
-}
-
-void SheetDataContext::importCellFormula( SequenceInputStream& rStrm )
-{
- rStrm.skip( 2 );
- Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY );
- if( xTokens.is() )
- {
- ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress );
- getFormulaParser().importFormula( aContext, rStrm );
- }
-}
-
-void SheetDataContext::importRow( SequenceInputStream& rStrm )
-{
- RowModel aModel;
-
- sal_uInt16 nHeight, nFlags1;
- sal_uInt8 nFlags2;
- rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2;
-
- // row index is 0-based in BIFF12, but RowModel expects 1-based
- aModel.mnFirstRow = aModel.mnLastRow = maCurrPos.mnRow + 1;
- // row height is in twips in BIFF12, convert to points
- aModel.mfHeight = nHeight / 20.0;
- aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 );
- aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT );
- aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT );
- aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC );
- aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN );
- aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED );
- aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP );
- aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM );
- // set row properties in the current sheet
- setRowModel( aModel );
}
void SheetDataContext::importArray( SequenceInputStream& rStrm )
{
- BinRange aRange;
- rStrm >> aRange;
- CellRangeAddress aArrayRange;
- Reference< XCellRange > xRange = getCellRange( aRange, &aArrayRange );
- Reference< XArrayFormulaTokens > xTokens( xRange, UNO_QUERY );
- if( xRange.is() && xTokens.is() )
+ if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
{
rStrm.skip( 1 );
- ArrayFormulaContext aContext( xTokens, aArrayRange );
- getFormulaParser().importFormula( aContext, rStrm );
+ ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm );
+ mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens );
}
}
-void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm )
-{
- getSharedFormulas().importSharedFmla( rStrm, maCurrCell.maAddress );
-}
-
void SheetDataContext::importDataTable( SequenceInputStream& rStrm )
{
- BinRange aRange;
- rStrm >> aRange;
- CellRangeAddress aTableRange;
- if( getAddressConverter().convertToCellRange( aTableRange, aRange, getSheetIndex(), true, true ) )
+ if( readFormulaRef( rStrm ) )
{
- DataTableModel aModel;
BinAddress aRef1, aRef2;
sal_uInt8 nFlags;
rStrm >> aRef1 >> aRef2 >> nFlags;
- aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
- aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
- aModel.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW );
- aModel.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D );
- aModel.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL );
- aModel.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL );
- setTableOperation( aTableRange, aModel );
+ maTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
+ maTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
+ maTableData.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW );
+ maTableData.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D );
+ maTableData.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL );
+ maTableData.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL );
+ mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData );
+ }
+}
+
+void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm )
+{
+ if( readFormulaRef( rStrm ) && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
+ {
+ ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_SHAREDFORMULA, rStrm );
+ mrSheetData.createSharedFormula( maCellData.maCellAddr, aTokens );
}
}
@@ -589,26 +566,27 @@ void SheetDataContext::importDataTable( SequenceInputStream& rStrm )
BiffSheetDataContext::BiffSheetDataContext( const WorksheetHelper& rHelper ) :
BiffWorksheetContextBase( rHelper ),
+ SheetDataContextBase( rHelper ),
mnBiff2XfId( 0 )
{
- mnArrayIgnoreSize = (getBiff() == BIFF2) ? 1 : ((getBiff() <= BIFF4) ? 2 : 6);
switch( getBiff() )
{
case BIFF2:
- mnFormulaIgnoreSize = 9; // double formula result, 1 byte flags
- mnArrayIgnoreSize = 1; // recalc-always flag
+ mnFormulaSkipSize = 9; // double formula result, 1 byte flags
+ mnArraySkipSize = 1; // recalc-always flag
break;
case BIFF3:
case BIFF4:
- mnFormulaIgnoreSize = 10; // double formula result, 2 byte flags
- mnArrayIgnoreSize = 2; // 2 byte flags
+ mnFormulaSkipSize = 10; // double formula result, 2 byte flags
+ mnArraySkipSize = 2; // 2 byte flags
break;
case BIFF5:
case BIFF8:
- mnFormulaIgnoreSize = 14; // double formula result, 2 byte flags, 4 bytes nothing
- mnArrayIgnoreSize = 6; // 2 byte flags, 4 bytes nothing
+ mnFormulaSkipSize = 14; // double formula result, 2 byte flags, 4 bytes nothing
+ mnArraySkipSize = 6; // 2 byte flags, 4 bytes nothing
+ break;
+ case BIFF_UNKNOWN:
break;
- case BIFF_UNKNOWN: break;
}
}
@@ -689,258 +667,284 @@ void BiffSheetDataContext::importRecord( BiffInputStream& rStrm )
}
break;
- case BIFF_UNKNOWN: break;
+ case BIFF_UNKNOWN:
+ break;
}
}
}
// private --------------------------------------------------------------------
-void BiffSheetDataContext::setCurrCell( const BinAddress& rAddr )
-{
- maCurrCell.reset();
- maCurrCell.mxCell = getCell( rAddr, &maCurrCell.maAddress );
- // update used area of the sheet
- if( maCurrCell.mxCell.is() )
- extendUsedArea( maCurrCell.maAddress );
-}
-
-void BiffSheetDataContext::importXfId( BiffInputStream& rStrm, bool bBiff2 )
+void BiffSheetDataContext::importRow( BiffInputStream& rStrm )
{
- if( bBiff2 )
+ RowModel aModel;
+ sal_uInt16 nRow, nFirstUsedCol, nFirstFreeCol, nHeight;
+ rStrm >> nRow >> nFirstUsedCol >> nFirstFreeCol >> nHeight;
+ if( getBiff() == BIFF2 )
{
- sal_uInt8 nBiff2XfId;
- rStrm >> nBiff2XfId;
rStrm.skip( 2 );
- maCurrCell.mnXfId = nBiff2XfId & BIFF2_XF_MASK;
- if( maCurrCell.mnXfId == BIFF2_XF_EXTENDED_IDS )
- maCurrCell.mnXfId = mnBiff2XfId;
+ aModel.mbCustomFormat = rStrm.readuInt8() == BIFF2_ROW_CUSTOMFORMAT;
+ if( aModel.mbCustomFormat )
+ {
+ rStrm.skip( 5 );
+ aModel.mnXfId = rStrm.readuInt16();
+ }
}
else
{
- maCurrCell.mnXfId = rStrm.readuInt16();
+ rStrm.skip( 4 );
+ sal_uInt32 nFlags = rStrm.readuInt32();
+ aModel.mnXfId = extractValue< sal_Int32 >( nFlags, 16, 12 );
+ aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 0, 3 );
+ aModel.mbCustomFormat = getFlag( nFlags, BIFF_ROW_CUSTOMFORMAT );
+ aModel.mbCustomHeight = getFlag( nFlags, BIFF_ROW_CUSTOMHEIGHT );
+ aModel.mbShowPhonetic = getFlag( nFlags, BIFF_ROW_SHOWPHONETIC );
+ aModel.mbHidden = getFlag( nFlags, BIFF_ROW_HIDDEN );
+ aModel.mbCollapsed = getFlag( nFlags, BIFF_ROW_COLLAPSED );
+ aModel.mbThickTop = getFlag( nFlags, BIFF_ROW_THICKTOP );
+ aModel.mbThickBottom = getFlag( nFlags, BIFF_ROW_THICKBOTTOM );
+ }
+
+ // row index is 0-based in BIFF, but RowModel expects 1-based
+ aModel.mnRow = static_cast< sal_Int32 >( nRow ) + 1;
+ // row height is in twips in BIFF, convert to points
+ aModel.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0;
+ // set column spans
+ if( nFirstUsedCol < nFirstFreeCol )
+ {
+ sal_Int32 nLastCol = ::std::min< sal_Int32 >( nFirstFreeCol - 1, mrAddressConv.getMaxApiAddress().Column );
+ aModel.insertColSpan( ValueRange( nFirstUsedCol, nLastCol ) );
+ }
+
+ // set row properties in the current sheet
+ setRowModel( aModel );
+}
+
+bool BiffSheetDataContext::readCellXfId( BiffInputStream& rStrm, const BinAddress& rAddr, bool bBiff2 )
+{
+ bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, rAddr, mnSheet, true );
+ if( bValidAddr )
+ {
+ // update used area of the sheet
+ extendUsedArea( maCellData.maCellAddr );
+
+ // load the XF identifier according to current BIFF version
+ if( bBiff2 )
+ {
+ /* #i71453# On first call, check if the file contains XF records
+ (by trying to access the first XF with index 0). If there are
+ no XFs, the explicit formatting information contained in each
+ cell record will be used instead. */
+ if( !mobBiff2HasXfs )
+ mobBiff2HasXfs = getStyles().getCellXf( 0 ).get() != 0;
+ // read formatting information (includes the XF identifier)
+ sal_uInt8 nFlags1, nFlags2, nFlags3;
+ rStrm >> nFlags1 >> nFlags2 >> nFlags3;
+ /* If the file contains XFs, extract and set the XF identifier,
+ otherwise get the explicit formatting. */
+ if( mobBiff2HasXfs.get() )
+ {
+ maCellData.mnXfId = extractValue< sal_Int32 >( nFlags1, 0, 6 );
+ /* If the identifier is equal to 63, then the real identifier
+ is contained in the preceding IXFE record (stored in the
+ class member mnBiff2XfId). */
+ if( maCellData.mnXfId == BIFF2_CELL_USEIXFE )
+ maCellData.mnXfId = mnBiff2XfId;
+ }
+ else
+ {
+ /* Let the Xf class do the API conversion. Keeping the member
+ maCellData.mnXfId untouched will prevent to trigger the
+ usual XF formatting conversion later on. */
+ PropertySet aPropSet( getCell( maCellData.maCellAddr ) );
+ Xf::writeBiff2CellFormatToPropertySet( *this, aPropSet, nFlags1, nFlags2, nFlags3 );
+ }
+ }
+ else
+ {
+ // BIFF3-BIFF8: 16-bit XF identifier
+ maCellData.mnXfId = rStrm.readuInt16();
+ }
}
+ return bValidAddr;
}
-void BiffSheetDataContext::importCellHeader( BiffInputStream& rStrm, bool bBiff2 )
+bool BiffSheetDataContext::readCellHeader( BiffInputStream& rStrm, bool bBiff2 )
{
BinAddress aAddr;
rStrm >> aAddr;
- setCurrCell( aAddr );
- importXfId( rStrm, bBiff2 );
+ return readCellXfId( rStrm, aAddr, bBiff2 );
+}
+
+bool BiffSheetDataContext::readFormulaRef( BiffInputStream& rStrm )
+{
+ BinRange aRange;
+ aRange.read( rStrm, false ); // columns always 8-bit
+ return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true );
}
void BiffSheetDataContext::importBlank( BiffInputStream& rStrm )
{
- importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK );
- setCellFormat( maCurrCell );
+ if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK ) )
+ mrSheetData.setBlankCell( maCellData );
}
void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm )
{
- importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BOOLERR );
- if( maCurrCell.mxCell.is() )
+ if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BOOLERR ) )
{
sal_uInt8 nValue, nType;
rStrm >> nValue >> nType;
switch( nType )
{
case BIFF_BOOLERR_BOOL:
- maCurrCell.mnCellType = XML_b;
- setBooleanCell( maCurrCell.mxCell, nValue != 0 );
- // #108770# set 'Standard' number format for all Boolean cells
- maCurrCell.mnNumFmtId = 0;
+ maCellData.mnCellType = XML_b;
+ mrSheetData.setBooleanCell( maCellData, nValue != 0 );
break;
case BIFF_BOOLERR_ERROR:
- maCurrCell.mnCellType = XML_e;
- setErrorCell( maCurrCell.mxCell, nValue );
+ maCellData.mnCellType = XML_e;
+ mrSheetData.setErrorCell( maCellData, nValue );
break;
default:
OSL_ENSURE( false, "BiffSheetDataContext::importBoolErr - unknown cell type" );
+ maCellData.mnCellType = XML_TOKEN_INVALID;
+ mrSheetData.setBlankCell( maCellData );
}
}
- setCellFormat( maCurrCell );
}
void BiffSheetDataContext::importFormula( BiffInputStream& rStrm )
{
- importCellHeader( rStrm, getBiff() == BIFF2 );
- maCurrCell.mnCellType = XML_n;
- Reference< XFormulaTokens > xTokens( maCurrCell.mxCell, UNO_QUERY );
- if( xTokens.is() )
+ if( readCellHeader( rStrm, getBiff() == BIFF2 ) )
{
- rStrm.skip( mnFormulaIgnoreSize );
- ExtCellFormulaContext aContext( *this, xTokens, maCurrCell.maAddress );
- getFormulaParser().importFormula( aContext, rStrm );
+ maCellData.mnCellType = XML_n;
+ rStrm.skip( mnFormulaSkipSize );
+ ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm );
+ mrSheetData.setFormulaCell( maCellData, aTokens );
}
- setCellFormat( maCurrCell );
}
void BiffSheetDataContext::importInteger( BiffInputStream& rStrm )
{
- importCellHeader( rStrm, true );
- maCurrCell.mnCellType = XML_n;
- if( maCurrCell.mxCell.is() )
- maCurrCell.mxCell->setValue( rStrm.readuInt16() );
- setCellFormat( maCurrCell );
+ if( readCellHeader( rStrm, true ) )
+ {
+ maCellData.mnCellType = XML_n;
+ mrSheetData.setValueCell( maCellData, rStrm.readuInt16() );
+ }
}
void BiffSheetDataContext::importLabel( BiffInputStream& rStrm )
{
+ /* the deep secrets of BIFF type and record identifier...
+ record id BIFF -> XF type String type
+ 0x0004 2-7 -> 3 byte 8-bit length, byte string
+ 0x0004 8 -> 3 byte 16-bit length, unicode string
+ 0x0204 2-7 -> 2 byte 16-bit length, byte string
+ 0x0204 8 -> 2 byte 16-bit length, unicode string
+ */
bool bBiff2Xf = rStrm.getRecId() == BIFF2_ID_LABEL;
- importCellHeader( rStrm, bBiff2Xf );
- maCurrCell.mnCellType = XML_inlineStr;
- Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY );
- if( xText.is() )
- {
- /* the deep secrets of BIFF type and record identifier...
- record id BIFF -> XF type String type
- 0x0004 2-7 -> 3 byte 8-bit length, byte string
- 0x0004 8 -> 3 byte 16-bit length, unicode string
- 0x0204 2-7 -> 2 byte 16-bit length, byte string
- 0x0204 8 -> 2 byte 16-bit length, unicode string */
-
- RichString aString( *this );
+ if( readCellHeader( rStrm, bBiff2Xf ) )
+ {
+ maCellData.mnCellType = XML_inlineStr;
if( getBiff() == BIFF8 )
{
- aString.importUniString( rStrm );
+ // string may contain rich-text formatting
+ RichStringRef xString( new RichString( *this ) );
+ xString->importUniString( rStrm );
+ xString->finalizeImport();
+ mrSheetData.setStringCell( maCellData, xString );
}
else
{
// #i63105# use text encoding from FONT record
rtl_TextEncoding eTextEnc = getTextEncoding();
- if( const Font* pFont = getStyles().getFontFromCellXf( maCurrCell.mnXfId ).get() )
+ if( const Font* pFont = getStyles().getFontFromCellXf( maCellData.mnXfId ).get() )
eTextEnc = pFont->getFontEncoding();
- BiffStringFlags nFlags = bBiff2Xf ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT;
- setFlag( nFlags, BIFF_STR_EXTRAFONTS, rStrm.getRecId() == BIFF_ID_RSTRING );
- aString.importByteString( rStrm, eTextEnc, nFlags );
+ // RSTRING record contains rich-text formatting
+ if( rStrm.getRecId() == BIFF_ID_RSTRING )
+ {
+ BiffStringFlags nFlags = BIFF_STR_EXTRAFONTS;
+ // BIFF2 record identifier: 8-bit string length (see above)
+ setFlag( nFlags, BIFF_STR_8BITLENGTH, bBiff2Xf );
+ RichStringRef xString( new RichString( *this ) );
+ xString->importByteString( rStrm, eTextEnc, nFlags );
+ xString->finalizeImport();
+ mrSheetData.setStringCell( maCellData, xString );
+ }
+ else
+ {
+ // BIFF2 record identifier: 8-bit string length (see above)
+ OUString aText = rStrm.readByteStringUC( !bBiff2Xf, eTextEnc );
+ mrSheetData.setStringCell( maCellData, aText );
+ }
}
- aString.finalizeImport();
- aString.convert( xText, maCurrCell.mnXfId );
}
- setCellFormat( maCurrCell );
}
void BiffSheetDataContext::importLabelSst( BiffInputStream& rStrm )
{
- importCellHeader( rStrm, false );
- maCurrCell.mnCellType = XML_s;
- if( maCurrCell.mxCell.is() )
- setSharedStringCell( maCurrCell.mxCell, rStrm.readInt32(), maCurrCell.mnXfId );
- setCellFormat( maCurrCell );
+ if( readCellHeader( rStrm, false ) )
+ {
+ maCellData.mnCellType = XML_s;
+ mrSheetData.setStringCell( maCellData, rStrm.readInt32() );
+ }
}
void BiffSheetDataContext::importMultBlank( BiffInputStream& rStrm )
{
BinAddress aAddr;
- for( rStrm >> aAddr; rStrm.getRemaining() > 2; ++aAddr.mnCol )
- {
- setCurrCell( aAddr );
- importXfId( rStrm, false );
- setCellFormat( maCurrCell );
- }
+ bool bValidAddr = true;
+ for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol )
+ if( (bValidAddr = readCellXfId( rStrm, aAddr, false )) == true )
+ mrSheetData.setBlankCell( maCellData );
}
void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm )
{
BinAddress aAddr;
- for( rStrm >> aAddr; rStrm.getRemaining() > 2; ++aAddr.mnCol )
+ bool bValidAddr = true;
+ for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol )
{
- setCurrCell( aAddr );
- maCurrCell.mnCellType = XML_n;
- importXfId( rStrm, false );
- sal_Int32 nRkValue = rStrm.readInt32();
- if( maCurrCell.mxCell.is() )
- maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( nRkValue ) );
- setCellFormat( maCurrCell );
+ if( (bValidAddr = readCellXfId( rStrm, aAddr, false )) == true )
+ {
+ maCellData.mnCellType = XML_n;
+ sal_Int32 nRkValue = rStrm.readInt32();
+ mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( nRkValue ) );
+ }
}
}
void BiffSheetDataContext::importNumber( BiffInputStream& rStrm )
{
- importCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER );
- maCurrCell.mnCellType = XML_n;
- if( maCurrCell.mxCell.is() )
- maCurrCell.mxCell->setValue( rStrm.readDouble() );
- setCellFormat( maCurrCell );
+ if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER ) )
+ {
+ maCellData.mnCellType = XML_n;
+ mrSheetData.setValueCell( maCellData, rStrm.readDouble() );
+ }
}
void BiffSheetDataContext::importRk( BiffInputStream& rStrm )
{
- importCellHeader( rStrm, false );
- maCurrCell.mnCellType = XML_n;
- if( maCurrCell.mxCell.is() )
- maCurrCell.mxCell->setValue( BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
- setCellFormat( maCurrCell );
-}
-
-void BiffSheetDataContext::importRow( BiffInputStream& rStrm )
-{
- RowModel aModel;
-
- sal_uInt16 nRow, nHeight;
- rStrm >> nRow;
- rStrm.skip( 4 );
- rStrm >> nHeight;
- if( getBiff() == BIFF2 )
+ if( readCellHeader( rStrm, false ) )
{
- rStrm.skip( 2 );
- aModel.mbCustomFormat = rStrm.readuInt8() == BIFF2_ROW_CUSTOMFORMAT;
- if( aModel.mbCustomFormat )
- {
- rStrm.skip( 5 );
- aModel.mnXfId = rStrm.readuInt16();
- }
+ maCellData.mnCellType = XML_n;
+ mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
}
- else
- {
- rStrm.skip( 4 );
- sal_uInt32 nFlags = rStrm.readuInt32();
- aModel.mnXfId = extractValue< sal_Int32 >( nFlags, 16, 12 );
- aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 0, 3 );
- aModel.mbCustomFormat = getFlag( nFlags, BIFF_ROW_CUSTOMFORMAT );
- aModel.mbCustomHeight = getFlag( nFlags, BIFF_ROW_CUSTOMHEIGHT );
- aModel.mbShowPhonetic = getFlag( nFlags, BIFF_ROW_SHOWPHONETIC );
- aModel.mbHidden = getFlag( nFlags, BIFF_ROW_HIDDEN );
- aModel.mbCollapsed = getFlag( nFlags, BIFF_ROW_COLLAPSED );
- aModel.mbThickTop = getFlag( nFlags, BIFF_ROW_THICKTOP );
- aModel.mbThickBottom = getFlag( nFlags, BIFF_ROW_THICKBOTTOM );
- }
-
- // row index is 0-based in BIFF, but RowModel expects 1-based
- aModel.mnFirstRow = aModel.mnLastRow = nRow + 1;
- // row height is in twips in BIFF, convert to points
- aModel.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0;
- // set row properties in the current sheet
- setRowModel( aModel );
}
void BiffSheetDataContext::importArray( BiffInputStream& rStrm )
{
- BinRange aRange;
- aRange.read( rStrm, false ); // columns always 8-bit
- CellRangeAddress aArrayRange;
- Reference< XCellRange > xRange = getCellRange( aRange, &aArrayRange );
- Reference< XArrayFormulaTokens > xTokens( xRange, UNO_QUERY );
- if( xRange.is() && xTokens.is() )
+ if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
{
- rStrm.skip( mnArrayIgnoreSize );
- ArrayFormulaContext aContext( xTokens, aArrayRange );
- getFormulaParser().importFormula( aContext, rStrm );
+ rStrm.skip( mnArraySkipSize );
+ ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm );
+ mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens );
}
}
-void BiffSheetDataContext::importSharedFmla( BiffInputStream& rStrm )
-{
- getSharedFormulas().importSharedFmla( rStrm, maCurrCell.maAddress );
-}
-
void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm )
{
- BinRange aRange;
- aRange.read( rStrm, false ); // columns always 8-bit
- CellRangeAddress aTableRange;
- if( getAddressConverter().convertToCellRange( aTableRange, aRange, getSheetIndex(), true, true ) )
+ if( readFormulaRef( rStrm ) )
{
DataTableModel aModel;
BinAddress aRef1, aRef2;
@@ -972,7 +976,17 @@ void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm )
}
aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
- setTableOperation( aTableRange, aModel );
+ mrSheetData.createTableOperation( maFmlaData.maFormulaRef, aModel );
+ }
+}
+
+void BiffSheetDataContext::importSharedFmla( BiffInputStream& rStrm )
+{
+ if( readFormulaRef( rStrm ) && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
+ {
+ rStrm.skip( 2 ); // flags
+ ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_SHAREDFORMULA, rStrm );
+ mrSheetData.createSharedFormula( maCellData.maCellAddr, aTokens );
}
}