1ca5ec200SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file
5ca5ec200SAndrew Rist * distributed with this work for additional information
6ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the
8ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance
9ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at
10ca5ec200SAndrew Rist *
11ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12ca5ec200SAndrew Rist *
13ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing,
14ca5ec200SAndrew Rist * software distributed under the License is distributed on an
15ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the
17ca5ec200SAndrew Rist * specific language governing permissions and limitations
18ca5ec200SAndrew Rist * under the License.
19ca5ec200SAndrew Rist *
20ca5ec200SAndrew Rist *************************************************************/
21ca5ec200SAndrew Rist
22ca5ec200SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "oox/xls/sheetdatacontext.hxx"
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include <com/sun/star/table/CellContentType.hpp>
27cdf0e10cSrcweir #include <com/sun/star/table/XCell.hpp>
28cdf0e10cSrcweir #include <com/sun/star/table/XCellRange.hpp>
29cdf0e10cSrcweir #include <com/sun/star/text/XText.hpp>
30*1f71f1d8SDamjan Jovanovic #include <com/sun/star/util/DateTime.hpp>
31cdf0e10cSrcweir #include "oox/helper/attributelist.hxx"
32*1f71f1d8SDamjan Jovanovic #include "oox/helper/datetimehelper.hxx"
33cdf0e10cSrcweir #include "oox/helper/propertyset.hxx"
34cdf0e10cSrcweir #include "oox/xls/addressconverter.hxx"
35cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx"
36cdf0e10cSrcweir #include "oox/xls/formulaparser.hxx"
37cdf0e10cSrcweir #include "oox/xls/richstringcontext.hxx"
38cdf0e10cSrcweir #include "oox/xls/unitconverter.hxx"
39cdf0e10cSrcweir
40cdf0e10cSrcweir namespace oox {
41cdf0e10cSrcweir namespace xls {
42cdf0e10cSrcweir
43cdf0e10cSrcweir // ============================================================================
44cdf0e10cSrcweir
45cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
46cdf0e10cSrcweir using namespace ::com::sun::star::table;
47cdf0e10cSrcweir using namespace ::com::sun::star::text;
48cdf0e10cSrcweir using namespace ::com::sun::star::uno;
49*1f71f1d8SDamjan Jovanovic using namespace ::com::sun::star::util;
50cdf0e10cSrcweir
51cdf0e10cSrcweir using ::oox::core::ContextHandlerRef;
52cdf0e10cSrcweir using ::rtl::OUString;
53cdf0e10cSrcweir
54cdf0e10cSrcweir // ============================================================================
55cdf0e10cSrcweir
56cdf0e10cSrcweir namespace {
57cdf0e10cSrcweir
58cdf0e10cSrcweir // record constants -----------------------------------------------------------
59cdf0e10cSrcweir
60cdf0e10cSrcweir const sal_uInt32 BIFF12_CELL_SHOWPHONETIC = 0x01000000;
61cdf0e10cSrcweir
62cdf0e10cSrcweir const sal_uInt8 BIFF12_DATATABLE_ROW = 0x01;
63cdf0e10cSrcweir const sal_uInt8 BIFF12_DATATABLE_2D = 0x02;
64cdf0e10cSrcweir const sal_uInt8 BIFF12_DATATABLE_REF1DEL = 0x04;
65cdf0e10cSrcweir const sal_uInt8 BIFF12_DATATABLE_REF2DEL = 0x08;
66cdf0e10cSrcweir
67cdf0e10cSrcweir const sal_uInt16 BIFF12_ROW_THICKTOP = 0x0001;
68cdf0e10cSrcweir const sal_uInt16 BIFF12_ROW_THICKBOTTOM = 0x0002;
69cdf0e10cSrcweir const sal_uInt16 BIFF12_ROW_COLLAPSED = 0x0800;
70cdf0e10cSrcweir const sal_uInt16 BIFF12_ROW_HIDDEN = 0x1000;
71cdf0e10cSrcweir const sal_uInt16 BIFF12_ROW_CUSTOMHEIGHT = 0x2000;
72cdf0e10cSrcweir const sal_uInt16 BIFF12_ROW_CUSTOMFORMAT = 0x4000;
73cdf0e10cSrcweir const sal_uInt8 BIFF12_ROW_SHOWPHONETIC = 0x01;
74cdf0e10cSrcweir
75cdf0e10cSrcweir const sal_uInt16 BIFF_DATATABLE_ROW = 0x0004;
76cdf0e10cSrcweir const sal_uInt16 BIFF_DATATABLE_2D = 0x0008;
77cdf0e10cSrcweir const sal_uInt16 BIFF_DATATABLE_REF1DEL = 0x0010;
78cdf0e10cSrcweir const sal_uInt16 BIFF_DATATABLE_REF2DEL = 0x0020;
79cdf0e10cSrcweir
80cdf0e10cSrcweir const sal_uInt8 BIFF_FORMULA_RES_STRING = 0; /// Result is a string.
81cdf0e10cSrcweir const sal_uInt8 BIFF_FORMULA_RES_BOOL = 1; /// Result is Boolean value.
82cdf0e10cSrcweir const sal_uInt8 BIFF_FORMULA_RES_ERROR = 2; /// Result is error code.
83cdf0e10cSrcweir const sal_uInt8 BIFF_FORMULA_RES_EMPTY = 3; /// Result is empty cell (BIFF8 only).
84cdf0e10cSrcweir const sal_uInt16 BIFF_FORMULA_SHARED = 0x0008; /// Shared formula cell.
85cdf0e10cSrcweir
86cdf0e10cSrcweir const sal_uInt8 BIFF2_ROW_CUSTOMFORMAT = 0x01;
87cdf0e10cSrcweir const sal_uInt16 BIFF_ROW_DEFAULTHEIGHT = 0x8000;
88cdf0e10cSrcweir const sal_uInt16 BIFF_ROW_HEIGHTMASK = 0x7FFF;
89cdf0e10cSrcweir const sal_uInt32 BIFF_ROW_COLLAPSED = 0x00000010;
90cdf0e10cSrcweir const sal_uInt32 BIFF_ROW_HIDDEN = 0x00000020;
91cdf0e10cSrcweir const sal_uInt32 BIFF_ROW_CUSTOMHEIGHT = 0x00000040;
92cdf0e10cSrcweir const sal_uInt32 BIFF_ROW_CUSTOMFORMAT = 0x00000080;
93cdf0e10cSrcweir const sal_uInt32 BIFF_ROW_THICKTOP = 0x10000000;
94cdf0e10cSrcweir const sal_uInt32 BIFF_ROW_THICKBOTTOM = 0x20000000;
95cdf0e10cSrcweir const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000;
96cdf0e10cSrcweir
97cdf0e10cSrcweir const sal_Int32 BIFF2_CELL_USEIXFE = 63;
98cdf0e10cSrcweir
99cdf0e10cSrcweir } // namespace
100cdf0e10cSrcweir
101cdf0e10cSrcweir // ============================================================================
102cdf0e10cSrcweir
SheetDataContextBase(const WorksheetHelper & rHelper)103cdf0e10cSrcweir SheetDataContextBase::SheetDataContextBase( const WorksheetHelper& rHelper ) :
104cdf0e10cSrcweir mrAddressConv( rHelper.getAddressConverter() ),
105cdf0e10cSrcweir mrFormulaParser( rHelper.getFormulaParser() ),
106cdf0e10cSrcweir mrSheetData( rHelper.getSheetData() ),
107cdf0e10cSrcweir mnSheet( rHelper.getSheetIndex() )
108cdf0e10cSrcweir {
109f4ffe9aeSDamjan Jovanovic maLastCellAddress.Sheet = rHelper.getSheetIndex();
110f4ffe9aeSDamjan Jovanovic maLastCellAddress.Row = SAL_MAX_UINT32; // wraps around to 0 when incremented
111cdf0e10cSrcweir }
112cdf0e10cSrcweir
~SheetDataContextBase()113cdf0e10cSrcweir SheetDataContextBase::~SheetDataContextBase()
114cdf0e10cSrcweir {
115cdf0e10cSrcweir }
116cdf0e10cSrcweir
117cdf0e10cSrcweir // ============================================================================
118cdf0e10cSrcweir
SheetDataContext(WorksheetFragmentBase & rFragment)119cdf0e10cSrcweir SheetDataContext::SheetDataContext( WorksheetFragmentBase& rFragment ) :
120cdf0e10cSrcweir WorksheetContextBase( rFragment ),
121cdf0e10cSrcweir SheetDataContextBase( rFragment ),
122cdf0e10cSrcweir mbHasFormula( false ),
123cdf0e10cSrcweir mbValidRange( false )
124cdf0e10cSrcweir {
125cdf0e10cSrcweir }
126cdf0e10cSrcweir
onCreateContext(sal_Int32 nElement,const AttributeList & rAttribs)127cdf0e10cSrcweir ContextHandlerRef SheetDataContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir switch( getCurrentElement() )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir case XLS_TOKEN( sheetData ):
132cdf0e10cSrcweir if( nElement == XLS_TOKEN( row ) ) { importRow( rAttribs ); return this; }
133cdf0e10cSrcweir break;
134cdf0e10cSrcweir
135cdf0e10cSrcweir case XLS_TOKEN( row ):
136cdf0e10cSrcweir // do not process cell elements with invalid (out-of-range) address
137cdf0e10cSrcweir if( nElement == XLS_TOKEN( c ) && importCell( rAttribs ) )
138cdf0e10cSrcweir return this;
139cdf0e10cSrcweir break;
140cdf0e10cSrcweir
141cdf0e10cSrcweir case XLS_TOKEN( c ):
142cdf0e10cSrcweir switch( nElement )
143cdf0e10cSrcweir {
144cdf0e10cSrcweir case XLS_TOKEN( is ):
145cdf0e10cSrcweir mxInlineStr.reset( new RichString( *this ) );
146cdf0e10cSrcweir return new RichStringContext( *this, mxInlineStr );
147cdf0e10cSrcweir case XLS_TOKEN( v ):
148cdf0e10cSrcweir return this; // characters contain cell value
149cdf0e10cSrcweir case XLS_TOKEN( f ):
150cdf0e10cSrcweir importFormula( rAttribs );
151cdf0e10cSrcweir return this; // characters contain formula string
152cdf0e10cSrcweir }
153cdf0e10cSrcweir break;
154cdf0e10cSrcweir }
155cdf0e10cSrcweir return 0;
156cdf0e10cSrcweir }
157cdf0e10cSrcweir
onCharacters(const OUString & rChars)158cdf0e10cSrcweir void SheetDataContext::onCharacters( const OUString& rChars )
159cdf0e10cSrcweir {
160cdf0e10cSrcweir switch( getCurrentElement() )
161cdf0e10cSrcweir {
162cdf0e10cSrcweir case XLS_TOKEN( v ):
163cdf0e10cSrcweir maCellValue = rChars;
164cdf0e10cSrcweir break;
165cdf0e10cSrcweir case XLS_TOKEN( f ):
166cdf0e10cSrcweir if( maFmlaData.mnFormulaType != XML_TOKEN_INVALID )
167cdf0e10cSrcweir maTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, rChars );
168cdf0e10cSrcweir break;
169cdf0e10cSrcweir }
170cdf0e10cSrcweir }
171cdf0e10cSrcweir
onEndElement()172cdf0e10cSrcweir void SheetDataContext::onEndElement()
173cdf0e10cSrcweir {
174cdf0e10cSrcweir if( getCurrentElement() == XLS_TOKEN( c ) )
175cdf0e10cSrcweir {
176cdf0e10cSrcweir // try to create a formula cell
177cdf0e10cSrcweir if( mbHasFormula ) switch( maFmlaData.mnFormulaType )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir case XML_normal:
180cdf0e10cSrcweir mrSheetData.setFormulaCell( maCellData, maTokens );
181cdf0e10cSrcweir break;
182cdf0e10cSrcweir case XML_shared:
183cdf0e10cSrcweir if( maFmlaData.mnSharedId >= 0 )
184cdf0e10cSrcweir {
185cdf0e10cSrcweir if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
186cdf0e10cSrcweir mrSheetData.createSharedFormula( maFmlaData.mnSharedId, maTokens );
187cdf0e10cSrcweir mrSheetData.setFormulaCell( maCellData, maFmlaData.mnSharedId );
188cdf0e10cSrcweir }
189cdf0e10cSrcweir else
190cdf0e10cSrcweir // no success, set plain cell value and formatting below
191cdf0e10cSrcweir mbHasFormula = false;
192cdf0e10cSrcweir break;
193cdf0e10cSrcweir case XML_array:
194cdf0e10cSrcweir if( mbValidRange && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
195cdf0e10cSrcweir mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, maTokens );
196cdf0e10cSrcweir // set cell formatting, but do not set result as cell value
197cdf0e10cSrcweir mrSheetData.setBlankCell( maCellData );
198cdf0e10cSrcweir break;
199cdf0e10cSrcweir case XML_dataTable:
200cdf0e10cSrcweir if( mbValidRange )
201cdf0e10cSrcweir mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData );
202cdf0e10cSrcweir // set cell formatting, but do not set result as cell value
203cdf0e10cSrcweir mrSheetData.setBlankCell( maCellData );
204cdf0e10cSrcweir break;
205cdf0e10cSrcweir default:
206cdf0e10cSrcweir OSL_ENSURE( maFmlaData.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onEndElement - unknown formula type" );
207cdf0e10cSrcweir mbHasFormula = false;
208cdf0e10cSrcweir }
209cdf0e10cSrcweir
210cdf0e10cSrcweir if( !mbHasFormula )
211cdf0e10cSrcweir {
212cdf0e10cSrcweir // no formula created: try to set the cell value
213cdf0e10cSrcweir if( maCellValue.getLength() > 0 ) switch( maCellData.mnCellType )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir case XML_n:
216cdf0e10cSrcweir mrSheetData.setValueCell( maCellData, maCellValue.toDouble() );
217cdf0e10cSrcweir break;
218*1f71f1d8SDamjan Jovanovic case XML_d:
219*1f71f1d8SDamjan Jovanovic {
220*1f71f1d8SDamjan Jovanovic DateTime dateTime;
221*1f71f1d8SDamjan Jovanovic if ( parseISO8601DateTime( maCellValue, dateTime ) )
222*1f71f1d8SDamjan Jovanovic mrSheetData.setDateTimeCell( maCellData, dateTime );
223*1f71f1d8SDamjan Jovanovic else
224*1f71f1d8SDamjan Jovanovic mrSheetData.setErrorCell( maCellData, maCellValue );
225*1f71f1d8SDamjan Jovanovic }
226*1f71f1d8SDamjan Jovanovic break;
227cdf0e10cSrcweir case XML_b:
228cdf0e10cSrcweir mrSheetData.setBooleanCell( maCellData, maCellValue.toDouble() != 0.0 );
229cdf0e10cSrcweir break;
230cdf0e10cSrcweir case XML_e:
231cdf0e10cSrcweir mrSheetData.setErrorCell( maCellData, maCellValue );
232cdf0e10cSrcweir break;
233cdf0e10cSrcweir case XML_str:
234cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, maCellValue );
235cdf0e10cSrcweir break;
236cdf0e10cSrcweir case XML_s:
237cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, maCellValue.toInt32() );
238cdf0e10cSrcweir break;
239cdf0e10cSrcweir }
240cdf0e10cSrcweir else if( (maCellData.mnCellType == XML_inlineStr) && mxInlineStr.get() )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir mxInlineStr->finalizeImport();
243cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, mxInlineStr );
244cdf0e10cSrcweir }
245cdf0e10cSrcweir else
246cdf0e10cSrcweir {
247cdf0e10cSrcweir // empty cell, update cell type
248cdf0e10cSrcweir maCellData.mnCellType = XML_TOKEN_INVALID;
249cdf0e10cSrcweir mrSheetData.setBlankCell( maCellData );
250cdf0e10cSrcweir }
251cdf0e10cSrcweir }
252cdf0e10cSrcweir }
253cdf0e10cSrcweir }
254cdf0e10cSrcweir
onCreateRecordContext(sal_Int32 nRecId,SequenceInputStream & rStrm)255cdf0e10cSrcweir ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir switch( getCurrentElement() )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir case BIFF12_ID_SHEETDATA:
260cdf0e10cSrcweir if( nRecId == BIFF12_ID_ROW ) { importRow( rStrm ); return this; }
261cdf0e10cSrcweir break;
262cdf0e10cSrcweir
263cdf0e10cSrcweir case BIFF12_ID_ROW:
264cdf0e10cSrcweir switch( nRecId )
265cdf0e10cSrcweir {
266cdf0e10cSrcweir case BIFF12_ID_ARRAY: importArray( rStrm ); break;
267cdf0e10cSrcweir case BIFF12_ID_CELL_BOOL: importCellBool( rStrm, CELLTYPE_VALUE ); break;
268cdf0e10cSrcweir case BIFF12_ID_CELL_BLANK: importCellBlank( rStrm, CELLTYPE_VALUE ); break;
269cdf0e10cSrcweir case BIFF12_ID_CELL_DOUBLE: importCellDouble( rStrm, CELLTYPE_VALUE ); break;
270cdf0e10cSrcweir case BIFF12_ID_CELL_ERROR: importCellError( rStrm, CELLTYPE_VALUE ); break;
271cdf0e10cSrcweir case BIFF12_ID_CELL_RK: importCellRk( rStrm, CELLTYPE_VALUE ); break;
272cdf0e10cSrcweir case BIFF12_ID_CELL_RSTRING: importCellRString( rStrm, CELLTYPE_VALUE ); break;
273cdf0e10cSrcweir case BIFF12_ID_CELL_SI: importCellSi( rStrm, CELLTYPE_VALUE ); break;
274cdf0e10cSrcweir case BIFF12_ID_CELL_STRING: importCellString( rStrm, CELLTYPE_VALUE ); break;
275cdf0e10cSrcweir case BIFF12_ID_DATATABLE: importDataTable( rStrm ); break;
276cdf0e10cSrcweir case BIFF12_ID_FORMULA_BOOL: importCellBool( rStrm, CELLTYPE_FORMULA ); break;
277cdf0e10cSrcweir case BIFF12_ID_FORMULA_DOUBLE: importCellDouble( rStrm, CELLTYPE_FORMULA ); break;
278cdf0e10cSrcweir case BIFF12_ID_FORMULA_ERROR: importCellError( rStrm, CELLTYPE_FORMULA ); break;
279cdf0e10cSrcweir case BIFF12_ID_FORMULA_STRING: importCellString( rStrm, CELLTYPE_FORMULA ); break;
280cdf0e10cSrcweir case BIFF12_ID_MULTCELL_BOOL: importCellBool( rStrm, CELLTYPE_MULTI ); break;
281cdf0e10cSrcweir case BIFF12_ID_MULTCELL_BLANK: importCellBlank( rStrm, CELLTYPE_MULTI ); break;
282cdf0e10cSrcweir case BIFF12_ID_MULTCELL_DOUBLE: importCellDouble( rStrm, CELLTYPE_MULTI ); break;
283cdf0e10cSrcweir case BIFF12_ID_MULTCELL_ERROR: importCellError( rStrm, CELLTYPE_MULTI ); break;
284cdf0e10cSrcweir case BIFF12_ID_MULTCELL_RK: importCellRk( rStrm, CELLTYPE_MULTI ); break;
285cdf0e10cSrcweir case BIFF12_ID_MULTCELL_RSTRING:importCellRString( rStrm, CELLTYPE_MULTI ); break;
286cdf0e10cSrcweir case BIFF12_ID_MULTCELL_SI: importCellSi( rStrm, CELLTYPE_MULTI ); break;
287cdf0e10cSrcweir case BIFF12_ID_MULTCELL_STRING: importCellString( rStrm, CELLTYPE_MULTI ); break;
288cdf0e10cSrcweir case BIFF12_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir break;
291cdf0e10cSrcweir }
292cdf0e10cSrcweir return 0;
293cdf0e10cSrcweir }
294cdf0e10cSrcweir
295cdf0e10cSrcweir // private --------------------------------------------------------------------
296cdf0e10cSrcweir
importRow(const AttributeList & rAttribs)297cdf0e10cSrcweir void SheetDataContext::importRow( const AttributeList& rAttribs )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir RowModel aModel;
300cdf0e10cSrcweir aModel.mnRow = rAttribs.getInteger( XML_r, -1 );
301f4ffe9aeSDamjan Jovanovic if ( aModel.mnRow == -1 )
302f4ffe9aeSDamjan Jovanovic aModel.mnRow = ++maLastCellAddress.Row;
303f4ffe9aeSDamjan Jovanovic else
304f4ffe9aeSDamjan Jovanovic maLastCellAddress.Row = aModel.mnRow - 1;
305f4ffe9aeSDamjan Jovanovic maLastCellAddress.Column = SAL_MAX_UINT32; // wraps around to 0 when incremented
306cdf0e10cSrcweir aModel.mfHeight = rAttribs.getDouble( XML_ht, -1.0 );
307cdf0e10cSrcweir aModel.mnXfId = rAttribs.getInteger( XML_s, -1 );
308cdf0e10cSrcweir aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
309cdf0e10cSrcweir aModel.mbCustomHeight = rAttribs.getBool( XML_customHeight, false );
310cdf0e10cSrcweir aModel.mbCustomFormat = rAttribs.getBool( XML_customFormat, false );
311cdf0e10cSrcweir aModel.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
312cdf0e10cSrcweir aModel.mbHidden = rAttribs.getBool( XML_hidden, false );
313cdf0e10cSrcweir aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
314cdf0e10cSrcweir aModel.mbThickTop = rAttribs.getBool( XML_thickTop, false );
315cdf0e10cSrcweir aModel.mbThickBottom = rAttribs.getBool( XML_thickBot, false );
316cdf0e10cSrcweir
317cdf0e10cSrcweir // decode the column spans (space-separated list of colon-separated integer pairs)
318cdf0e10cSrcweir OUString aColSpansText = rAttribs.getString( XML_spans, OUString() );
319cdf0e10cSrcweir sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
320cdf0e10cSrcweir sal_Int32 nIndex = 0;
321cdf0e10cSrcweir while( nIndex >= 0 )
322cdf0e10cSrcweir {
323cdf0e10cSrcweir OUString aColSpanToken = aColSpansText.getToken( 0, ' ', nIndex );
324cdf0e10cSrcweir sal_Int32 nSepPos = aColSpanToken.indexOf( ':' );
325cdf0e10cSrcweir if( (0 < nSepPos) && (nSepPos + 1 < aColSpanToken.getLength()) )
326cdf0e10cSrcweir {
327cdf0e10cSrcweir // OOXML uses 1-based integer column indexes, row model expects 0-based colspans
328cdf0e10cSrcweir sal_Int32 nLastCol = ::std::min( aColSpanToken.copy( nSepPos + 1 ).toInt32() - 1, nMaxCol );
329cdf0e10cSrcweir aModel.insertColSpan( ValueRange( aColSpanToken.copy( 0, nSepPos ).toInt32() - 1, nLastCol ) );
330cdf0e10cSrcweir }
331cdf0e10cSrcweir }
332cdf0e10cSrcweir
333cdf0e10cSrcweir // set row properties in the current sheet
334cdf0e10cSrcweir setRowModel( aModel );
335cdf0e10cSrcweir }
336cdf0e10cSrcweir
importCell(const AttributeList & rAttribs)337cdf0e10cSrcweir bool SheetDataContext::importCell( const AttributeList& rAttribs )
338cdf0e10cSrcweir {
339f4ffe9aeSDamjan Jovanovic OUString r = rAttribs.getString( XML_r, OUString() );
340f4ffe9aeSDamjan Jovanovic bool bValidAddr;
341f4ffe9aeSDamjan Jovanovic if ( r.getLength() > 0 )
342f4ffe9aeSDamjan Jovanovic bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, rAttribs.getString( XML_r, OUString() ), mnSheet, true );
343f4ffe9aeSDamjan Jovanovic else
344f4ffe9aeSDamjan Jovanovic {
345f4ffe9aeSDamjan Jovanovic maCellData.maCellAddr.Column = ++maLastCellAddress.Column;
346f4ffe9aeSDamjan Jovanovic maCellData.maCellAddr.Row = maLastCellAddress.Row;
347f4ffe9aeSDamjan Jovanovic maCellData.maCellAddr.Sheet = maLastCellAddress.Sheet;
348f4ffe9aeSDamjan Jovanovic bValidAddr = true;
349f4ffe9aeSDamjan Jovanovic }
350cdf0e10cSrcweir if( bValidAddr )
351cdf0e10cSrcweir {
352f4ffe9aeSDamjan Jovanovic maLastCellAddress.Column = maCellData.maCellAddr.Column;
353f4ffe9aeSDamjan Jovanovic maLastCellAddress.Row = maCellData.maCellAddr.Row;
354f4ffe9aeSDamjan Jovanovic maLastCellAddress.Sheet = maCellData.maCellAddr.Sheet;
355cdf0e10cSrcweir maCellData.mnCellType = rAttribs.getToken( XML_t, XML_n );
356cdf0e10cSrcweir maCellData.mnXfId = rAttribs.getInteger( XML_s, -1 );
357cdf0e10cSrcweir maCellData.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
358cdf0e10cSrcweir
359cdf0e10cSrcweir // reset cell value, formula settings, and inline string
360cdf0e10cSrcweir maCellValue = OUString();
361cdf0e10cSrcweir mxInlineStr.reset();
362cdf0e10cSrcweir mbHasFormula = false;
363cdf0e10cSrcweir
364cdf0e10cSrcweir // update used area of the sheet
365cdf0e10cSrcweir extendUsedArea( maCellData.maCellAddr );
366cdf0e10cSrcweir }
367cdf0e10cSrcweir return bValidAddr;
368cdf0e10cSrcweir }
369cdf0e10cSrcweir
importFormula(const AttributeList & rAttribs)370cdf0e10cSrcweir void SheetDataContext::importFormula( const AttributeList& rAttribs )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir mbHasFormula = true;
373cdf0e10cSrcweir mbValidRange = mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, rAttribs.getString( XML_ref, OUString() ), mnSheet, true, true );
374cdf0e10cSrcweir
375cdf0e10cSrcweir maFmlaData.mnFormulaType = rAttribs.getToken( XML_t, XML_normal );
376cdf0e10cSrcweir maFmlaData.mnSharedId = rAttribs.getInteger( XML_si, -1 );
377cdf0e10cSrcweir
378cdf0e10cSrcweir if( maFmlaData.mnFormulaType == XML_dataTable )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir maTableData.maRef1 = rAttribs.getString( XML_r1, OUString() );
381cdf0e10cSrcweir maTableData.maRef2 = rAttribs.getString( XML_r2, OUString() );
382cdf0e10cSrcweir maTableData.mb2dTable = rAttribs.getBool( XML_dt2D, false );
383cdf0e10cSrcweir maTableData.mbRowTable = rAttribs.getBool( XML_dtr, false );
384cdf0e10cSrcweir maTableData.mbRef1Deleted = rAttribs.getBool( XML_del1, false );
385cdf0e10cSrcweir maTableData.mbRef2Deleted = rAttribs.getBool( XML_del2, false );
386cdf0e10cSrcweir }
387cdf0e10cSrcweir
388cdf0e10cSrcweir // clear token array, will be regenerated from element text
389cdf0e10cSrcweir maTokens = ApiTokenSequence();
390cdf0e10cSrcweir }
391cdf0e10cSrcweir
importRow(SequenceInputStream & rStrm)392cdf0e10cSrcweir void SheetDataContext::importRow( SequenceInputStream& rStrm )
393cdf0e10cSrcweir {
394cdf0e10cSrcweir RowModel aModel;
395cdf0e10cSrcweir sal_Int32 nSpanCount;
396cdf0e10cSrcweir sal_uInt16 nHeight, nFlags1;
397cdf0e10cSrcweir sal_uInt8 nFlags2;
398cdf0e10cSrcweir rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2 >> nSpanCount;
399cdf0e10cSrcweir maCurrPos.mnCol = 0;
400cdf0e10cSrcweir
401cdf0e10cSrcweir // row index is 0-based in BIFF12, but RowModel expects 1-based
402cdf0e10cSrcweir aModel.mnRow = maCurrPos.mnRow + 1;
403cdf0e10cSrcweir // row height is in twips in BIFF12, convert to points
404cdf0e10cSrcweir aModel.mfHeight = nHeight / 20.0;
405cdf0e10cSrcweir aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 );
406cdf0e10cSrcweir aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT );
407cdf0e10cSrcweir aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT );
408cdf0e10cSrcweir aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC );
409cdf0e10cSrcweir aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN );
410cdf0e10cSrcweir aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED );
411cdf0e10cSrcweir aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP );
412cdf0e10cSrcweir aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM );
413cdf0e10cSrcweir
414cdf0e10cSrcweir // read the column spans
415cdf0e10cSrcweir sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
416cdf0e10cSrcweir for( sal_Int32 nSpanIdx = 0; (nSpanIdx < nSpanCount) && !rStrm.isEof(); ++nSpanIdx )
417cdf0e10cSrcweir {
418cdf0e10cSrcweir sal_Int32 nFirstCol, nLastCol;
419cdf0e10cSrcweir rStrm >> nFirstCol >> nLastCol;
420cdf0e10cSrcweir aModel.insertColSpan( ValueRange( nFirstCol, ::std::min( nLastCol, nMaxCol ) ) );
421cdf0e10cSrcweir }
422cdf0e10cSrcweir
423cdf0e10cSrcweir // set row properties in the current sheet
424cdf0e10cSrcweir setRowModel( aModel );
425cdf0e10cSrcweir }
426cdf0e10cSrcweir
readCellHeader(SequenceInputStream & rStrm,CellType eCellType)427cdf0e10cSrcweir bool SheetDataContext::readCellHeader( SequenceInputStream& rStrm, CellType eCellType )
428cdf0e10cSrcweir {
429cdf0e10cSrcweir switch( eCellType )
430cdf0e10cSrcweir {
431cdf0e10cSrcweir case CELLTYPE_VALUE:
432cdf0e10cSrcweir case CELLTYPE_FORMULA: rStrm >> maCurrPos.mnCol; break;
433cdf0e10cSrcweir case CELLTYPE_MULTI: ++maCurrPos.mnCol; break;
434cdf0e10cSrcweir }
435cdf0e10cSrcweir
436cdf0e10cSrcweir sal_uInt32 nXfId;
437cdf0e10cSrcweir rStrm >> nXfId;
438cdf0e10cSrcweir
439cdf0e10cSrcweir bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, maCurrPos, mnSheet, true );
440cdf0e10cSrcweir maCellData.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 );
441cdf0e10cSrcweir maCellData.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC );
442cdf0e10cSrcweir
443cdf0e10cSrcweir // update used area of the sheet
444cdf0e10cSrcweir if( bValidAddr )
445cdf0e10cSrcweir extendUsedArea( maCellData.maCellAddr );
446cdf0e10cSrcweir return bValidAddr;
447cdf0e10cSrcweir }
448cdf0e10cSrcweir
readCellFormula(SequenceInputStream & rStrm)449cdf0e10cSrcweir ApiTokenSequence SheetDataContext::readCellFormula( SequenceInputStream& rStrm )
450cdf0e10cSrcweir {
451cdf0e10cSrcweir rStrm.skip( 2 );
452cdf0e10cSrcweir return mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm );
453cdf0e10cSrcweir }
454cdf0e10cSrcweir
readFormulaRef(SequenceInputStream & rStrm)455cdf0e10cSrcweir bool SheetDataContext::readFormulaRef( SequenceInputStream& rStrm )
456cdf0e10cSrcweir {
457cdf0e10cSrcweir BinRange aRange;
458cdf0e10cSrcweir rStrm >> aRange;
459cdf0e10cSrcweir return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true );
460cdf0e10cSrcweir }
461cdf0e10cSrcweir
importCellBool(SequenceInputStream & rStrm,CellType eCellType)462cdf0e10cSrcweir void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCellType )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
465cdf0e10cSrcweir {
466cdf0e10cSrcweir maCellData.mnCellType = XML_b;
467cdf0e10cSrcweir bool bValue = rStrm.readuInt8() != 0;
468cdf0e10cSrcweir if( eCellType == CELLTYPE_FORMULA )
469cdf0e10cSrcweir mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
470cdf0e10cSrcweir else
471cdf0e10cSrcweir mrSheetData.setBooleanCell( maCellData, bValue );
472cdf0e10cSrcweir }
473cdf0e10cSrcweir }
474cdf0e10cSrcweir
importCellBlank(SequenceInputStream & rStrm,CellType eCellType)475cdf0e10cSrcweir void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCellType )
476cdf0e10cSrcweir {
477cdf0e10cSrcweir OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" );
478cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
479cdf0e10cSrcweir mrSheetData.setBlankCell( maCellData );
480cdf0e10cSrcweir }
481cdf0e10cSrcweir
importCellDouble(SequenceInputStream & rStrm,CellType eCellType)482cdf0e10cSrcweir void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType )
483cdf0e10cSrcweir {
484cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir maCellData.mnCellType = XML_n;
487cdf0e10cSrcweir double fValue = rStrm.readDouble();
488cdf0e10cSrcweir if( eCellType == CELLTYPE_FORMULA )
489cdf0e10cSrcweir mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
490cdf0e10cSrcweir else
491cdf0e10cSrcweir mrSheetData.setValueCell( maCellData, fValue );
492cdf0e10cSrcweir }
493cdf0e10cSrcweir }
494cdf0e10cSrcweir
importCellError(SequenceInputStream & rStrm,CellType eCellType)495cdf0e10cSrcweir void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCellType )
496cdf0e10cSrcweir {
497cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
498cdf0e10cSrcweir {
499cdf0e10cSrcweir maCellData.mnCellType = XML_e;
500cdf0e10cSrcweir sal_uInt8 nErrorCode = rStrm.readuInt8();
501cdf0e10cSrcweir if( eCellType == CELLTYPE_FORMULA )
502cdf0e10cSrcweir mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
503cdf0e10cSrcweir else
504cdf0e10cSrcweir mrSheetData.setErrorCell( maCellData, nErrorCode );
505cdf0e10cSrcweir }
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
importCellRk(SequenceInputStream & rStrm,CellType eCellType)508cdf0e10cSrcweir void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellType )
509cdf0e10cSrcweir {
510cdf0e10cSrcweir OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRk - no formula cells supported" );
511cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
512cdf0e10cSrcweir {
513cdf0e10cSrcweir maCellData.mnCellType = XML_n;
514cdf0e10cSrcweir mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
515cdf0e10cSrcweir }
516cdf0e10cSrcweir }
517cdf0e10cSrcweir
importCellRString(SequenceInputStream & rStrm,CellType eCellType)518cdf0e10cSrcweir void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType eCellType )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRString - no formula cells supported" );
521cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
522cdf0e10cSrcweir {
523cdf0e10cSrcweir maCellData.mnCellType = XML_inlineStr;
524cdf0e10cSrcweir RichStringRef xString( new RichString( *this ) );
525cdf0e10cSrcweir xString->importString( rStrm, true );
526cdf0e10cSrcweir xString->finalizeImport();
527cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, xString );
528cdf0e10cSrcweir }
529cdf0e10cSrcweir }
530cdf0e10cSrcweir
importCellSi(SequenceInputStream & rStrm,CellType eCellType)531cdf0e10cSrcweir void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellType )
532cdf0e10cSrcweir {
533cdf0e10cSrcweir OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellSi - no formula cells supported" );
534cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
535cdf0e10cSrcweir {
536cdf0e10cSrcweir maCellData.mnCellType = XML_s;
537cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, rStrm.readInt32() );
538cdf0e10cSrcweir }
539cdf0e10cSrcweir }
540cdf0e10cSrcweir
importCellString(SequenceInputStream & rStrm,CellType eCellType)541cdf0e10cSrcweir void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eCellType )
542cdf0e10cSrcweir {
543cdf0e10cSrcweir if( readCellHeader( rStrm, eCellType ) )
544cdf0e10cSrcweir {
545cdf0e10cSrcweir maCellData.mnCellType = XML_inlineStr;
546cdf0e10cSrcweir // always import the string, stream will point to formula afterwards, if existing
547cdf0e10cSrcweir RichStringRef xString( new RichString( *this ) );
548cdf0e10cSrcweir xString->importString( rStrm, false );
549cdf0e10cSrcweir xString->finalizeImport();
550cdf0e10cSrcweir if( eCellType == CELLTYPE_FORMULA )
551cdf0e10cSrcweir mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
552cdf0e10cSrcweir else
553cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, xString );
554cdf0e10cSrcweir }
555cdf0e10cSrcweir }
556cdf0e10cSrcweir
importArray(SequenceInputStream & rStrm)557cdf0e10cSrcweir void SheetDataContext::importArray( SequenceInputStream& rStrm )
558cdf0e10cSrcweir {
559cdf0e10cSrcweir if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
560cdf0e10cSrcweir {
561cdf0e10cSrcweir rStrm.skip( 1 );
562cdf0e10cSrcweir ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm );
563cdf0e10cSrcweir mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens );
564cdf0e10cSrcweir }
565cdf0e10cSrcweir }
566cdf0e10cSrcweir
importDataTable(SequenceInputStream & rStrm)567cdf0e10cSrcweir void SheetDataContext::importDataTable( SequenceInputStream& rStrm )
568cdf0e10cSrcweir {
569cdf0e10cSrcweir if( readFormulaRef( rStrm ) )
570cdf0e10cSrcweir {
571cdf0e10cSrcweir BinAddress aRef1, aRef2;
572cdf0e10cSrcweir sal_uInt8 nFlags;
573cdf0e10cSrcweir rStrm >> aRef1 >> aRef2 >> nFlags;
574cdf0e10cSrcweir maTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
575cdf0e10cSrcweir maTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
576cdf0e10cSrcweir maTableData.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW );
577cdf0e10cSrcweir maTableData.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D );
578cdf0e10cSrcweir maTableData.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL );
579cdf0e10cSrcweir maTableData.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL );
580cdf0e10cSrcweir mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData );
581cdf0e10cSrcweir }
582cdf0e10cSrcweir }
583cdf0e10cSrcweir
importSharedFmla(SequenceInputStream & rStrm)584cdf0e10cSrcweir void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm )
585cdf0e10cSrcweir {
586cdf0e10cSrcweir if( readFormulaRef( rStrm ) && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_SHAREDFORMULA, rStrm );
589cdf0e10cSrcweir mrSheetData.createSharedFormula( maCellData.maCellAddr, aTokens );
590cdf0e10cSrcweir }
591cdf0e10cSrcweir }
592cdf0e10cSrcweir
593cdf0e10cSrcweir // ============================================================================
594cdf0e10cSrcweir
BiffSheetDataContext(const WorksheetHelper & rHelper)595cdf0e10cSrcweir BiffSheetDataContext::BiffSheetDataContext( const WorksheetHelper& rHelper ) :
596cdf0e10cSrcweir BiffWorksheetContextBase( rHelper ),
597cdf0e10cSrcweir SheetDataContextBase( rHelper ),
598cdf0e10cSrcweir mnBiff2XfId( 0 )
599cdf0e10cSrcweir {
600cdf0e10cSrcweir switch( getBiff() )
601cdf0e10cSrcweir {
602cdf0e10cSrcweir case BIFF2:
603cdf0e10cSrcweir mnFormulaSkipSize = 9; // double formula result, 1 byte flags
604cdf0e10cSrcweir mnArraySkipSize = 1; // recalc-always flag
605cdf0e10cSrcweir break;
606cdf0e10cSrcweir case BIFF3:
607cdf0e10cSrcweir case BIFF4:
608cdf0e10cSrcweir mnFormulaSkipSize = 10; // double formula result, 2 byte flags
609cdf0e10cSrcweir mnArraySkipSize = 2; // 2 byte flags
610cdf0e10cSrcweir break;
611cdf0e10cSrcweir case BIFF5:
612cdf0e10cSrcweir case BIFF8:
613cdf0e10cSrcweir mnFormulaSkipSize = 14; // double formula result, 2 byte flags, 4 bytes nothing
614cdf0e10cSrcweir mnArraySkipSize = 6; // 2 byte flags, 4 bytes nothing
615cdf0e10cSrcweir break;
616cdf0e10cSrcweir case BIFF_UNKNOWN:
617cdf0e10cSrcweir break;
618cdf0e10cSrcweir }
619cdf0e10cSrcweir }
620cdf0e10cSrcweir
importRecord(BiffInputStream & rStrm)621cdf0e10cSrcweir void BiffSheetDataContext::importRecord( BiffInputStream& rStrm )
622cdf0e10cSrcweir {
623cdf0e10cSrcweir sal_uInt16 nRecId = rStrm.getRecId();
624cdf0e10cSrcweir switch( nRecId )
625cdf0e10cSrcweir {
626cdf0e10cSrcweir // records in all BIFF versions
627cdf0e10cSrcweir case BIFF2_ID_ARRAY: // #i72713#
628cdf0e10cSrcweir case BIFF3_ID_ARRAY: importArray( rStrm ); break;
629cdf0e10cSrcweir case BIFF2_ID_BLANK:
630cdf0e10cSrcweir case BIFF3_ID_BLANK: importBlank( rStrm ); break;
631cdf0e10cSrcweir case BIFF2_ID_BOOLERR:
632cdf0e10cSrcweir case BIFF3_ID_BOOLERR: importBoolErr( rStrm ); break;
633cdf0e10cSrcweir case BIFF2_ID_INTEGER: importInteger( rStrm ); break;
634cdf0e10cSrcweir case BIFF_ID_IXFE: rStrm >> mnBiff2XfId; break;
635cdf0e10cSrcweir case BIFF2_ID_LABEL:
636cdf0e10cSrcweir case BIFF3_ID_LABEL: importLabel( rStrm ); break;
637cdf0e10cSrcweir case BIFF2_ID_NUMBER:
638cdf0e10cSrcweir case BIFF3_ID_NUMBER: importNumber( rStrm ); break;
639cdf0e10cSrcweir case BIFF_ID_RK: importRk( rStrm ); break;
640cdf0e10cSrcweir
641cdf0e10cSrcweir // BIFF specific records
642cdf0e10cSrcweir default: switch( getBiff() )
643cdf0e10cSrcweir {
644cdf0e10cSrcweir case BIFF2: switch( nRecId )
645cdf0e10cSrcweir {
646cdf0e10cSrcweir case BIFF2_ID_DATATABLE: importDataTable( rStrm ); break;
647cdf0e10cSrcweir case BIFF2_ID_DATATABLE2: importDataTable( rStrm ); break;
648cdf0e10cSrcweir case BIFF2_ID_FORMULA: importFormula( rStrm ); break;
649cdf0e10cSrcweir case BIFF2_ID_ROW: importRow( rStrm ); break;
650cdf0e10cSrcweir }
651cdf0e10cSrcweir break;
652cdf0e10cSrcweir
653cdf0e10cSrcweir case BIFF3: switch( nRecId )
654cdf0e10cSrcweir {
655cdf0e10cSrcweir case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
656cdf0e10cSrcweir case BIFF3_ID_FORMULA: importFormula( rStrm ); break;
657cdf0e10cSrcweir case BIFF3_ID_ROW: importRow( rStrm ); break;
658cdf0e10cSrcweir }
659cdf0e10cSrcweir break;
660cdf0e10cSrcweir
661cdf0e10cSrcweir case BIFF4: switch( nRecId )
662cdf0e10cSrcweir {
663cdf0e10cSrcweir case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
664cdf0e10cSrcweir case BIFF4_ID_FORMULA: importFormula( rStrm ); break;
665cdf0e10cSrcweir case BIFF3_ID_ROW: importRow( rStrm ); break;
666cdf0e10cSrcweir }
667cdf0e10cSrcweir break;
668cdf0e10cSrcweir
669cdf0e10cSrcweir case BIFF5: switch( nRecId )
670cdf0e10cSrcweir {
671cdf0e10cSrcweir case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
672cdf0e10cSrcweir case BIFF3_ID_FORMULA:
673cdf0e10cSrcweir case BIFF4_ID_FORMULA:
674cdf0e10cSrcweir case BIFF5_ID_FORMULA: importFormula( rStrm ); break;
675cdf0e10cSrcweir case BIFF_ID_MULTBLANK: importMultBlank( rStrm ); break;
676cdf0e10cSrcweir case BIFF_ID_MULTRK: importMultRk( rStrm ); break;
677cdf0e10cSrcweir case BIFF3_ID_ROW: importRow( rStrm ); break;
678cdf0e10cSrcweir case BIFF_ID_RSTRING: importLabel( rStrm ); break;
679cdf0e10cSrcweir case BIFF_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
680cdf0e10cSrcweir }
681cdf0e10cSrcweir break;
682cdf0e10cSrcweir
683cdf0e10cSrcweir case BIFF8: switch( nRecId )
684cdf0e10cSrcweir {
685cdf0e10cSrcweir case BIFF3_ID_DATATABLE: importDataTable( rStrm ); break;
686cdf0e10cSrcweir case BIFF3_ID_FORMULA:
687cdf0e10cSrcweir case BIFF4_ID_FORMULA:
688cdf0e10cSrcweir case BIFF5_ID_FORMULA: importFormula( rStrm ); break;
689cdf0e10cSrcweir case BIFF_ID_LABELSST: importLabelSst( rStrm ); break;
690cdf0e10cSrcweir case BIFF_ID_MULTBLANK: importMultBlank( rStrm ); break;
691cdf0e10cSrcweir case BIFF_ID_MULTRK: importMultRk( rStrm ); break;
692cdf0e10cSrcweir case BIFF3_ID_ROW: importRow( rStrm ); break;
693cdf0e10cSrcweir case BIFF_ID_RSTRING: importLabel( rStrm ); break;
694cdf0e10cSrcweir case BIFF_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
695cdf0e10cSrcweir }
696cdf0e10cSrcweir break;
697cdf0e10cSrcweir
698cdf0e10cSrcweir case BIFF_UNKNOWN:
699cdf0e10cSrcweir break;
700cdf0e10cSrcweir }
701cdf0e10cSrcweir }
702cdf0e10cSrcweir }
703cdf0e10cSrcweir
704cdf0e10cSrcweir // private --------------------------------------------------------------------
705cdf0e10cSrcweir
importRow(BiffInputStream & rStrm)706cdf0e10cSrcweir void BiffSheetDataContext::importRow( BiffInputStream& rStrm )
707cdf0e10cSrcweir {
708cdf0e10cSrcweir RowModel aModel;
709cdf0e10cSrcweir sal_uInt16 nRow, nFirstUsedCol, nFirstFreeCol, nHeight;
710cdf0e10cSrcweir rStrm >> nRow >> nFirstUsedCol >> nFirstFreeCol >> nHeight;
711cdf0e10cSrcweir if( getBiff() == BIFF2 )
712cdf0e10cSrcweir {
713cdf0e10cSrcweir rStrm.skip( 2 );
714cdf0e10cSrcweir aModel.mbCustomFormat = rStrm.readuInt8() == BIFF2_ROW_CUSTOMFORMAT;
715cdf0e10cSrcweir if( aModel.mbCustomFormat )
716cdf0e10cSrcweir {
717cdf0e10cSrcweir rStrm.skip( 5 );
718cdf0e10cSrcweir aModel.mnXfId = rStrm.readuInt16();
719cdf0e10cSrcweir }
720cdf0e10cSrcweir }
721cdf0e10cSrcweir else
722cdf0e10cSrcweir {
723cdf0e10cSrcweir rStrm.skip( 4 );
724cdf0e10cSrcweir sal_uInt32 nFlags = rStrm.readuInt32();
725cdf0e10cSrcweir aModel.mnXfId = extractValue< sal_Int32 >( nFlags, 16, 12 );
726cdf0e10cSrcweir aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 0, 3 );
727cdf0e10cSrcweir aModel.mbCustomFormat = getFlag( nFlags, BIFF_ROW_CUSTOMFORMAT );
728cdf0e10cSrcweir aModel.mbCustomHeight = getFlag( nFlags, BIFF_ROW_CUSTOMHEIGHT );
729cdf0e10cSrcweir aModel.mbShowPhonetic = getFlag( nFlags, BIFF_ROW_SHOWPHONETIC );
730cdf0e10cSrcweir aModel.mbHidden = getFlag( nFlags, BIFF_ROW_HIDDEN );
731cdf0e10cSrcweir aModel.mbCollapsed = getFlag( nFlags, BIFF_ROW_COLLAPSED );
732cdf0e10cSrcweir aModel.mbThickTop = getFlag( nFlags, BIFF_ROW_THICKTOP );
733cdf0e10cSrcweir aModel.mbThickBottom = getFlag( nFlags, BIFF_ROW_THICKBOTTOM );
734cdf0e10cSrcweir }
735cdf0e10cSrcweir
736cdf0e10cSrcweir // row index is 0-based in BIFF, but RowModel expects 1-based
737cdf0e10cSrcweir aModel.mnRow = static_cast< sal_Int32 >( nRow ) + 1;
738cdf0e10cSrcweir // row height is in twips in BIFF, convert to points
739cdf0e10cSrcweir aModel.mfHeight = (nHeight & BIFF_ROW_HEIGHTMASK) / 20.0;
740cdf0e10cSrcweir // set column spans
741cdf0e10cSrcweir if( nFirstUsedCol < nFirstFreeCol )
742cdf0e10cSrcweir {
743cdf0e10cSrcweir sal_Int32 nLastCol = ::std::min< sal_Int32 >( nFirstFreeCol - 1, mrAddressConv.getMaxApiAddress().Column );
744cdf0e10cSrcweir aModel.insertColSpan( ValueRange( nFirstUsedCol, nLastCol ) );
745cdf0e10cSrcweir }
746cdf0e10cSrcweir
747cdf0e10cSrcweir // set row properties in the current sheet
748cdf0e10cSrcweir setRowModel( aModel );
749cdf0e10cSrcweir }
750cdf0e10cSrcweir
readCellXfId(BiffInputStream & rStrm,const BinAddress & rAddr,bool bBiff2)751cdf0e10cSrcweir bool BiffSheetDataContext::readCellXfId( BiffInputStream& rStrm, const BinAddress& rAddr, bool bBiff2 )
752cdf0e10cSrcweir {
753cdf0e10cSrcweir bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, rAddr, mnSheet, true );
754cdf0e10cSrcweir if( bValidAddr )
755cdf0e10cSrcweir {
756cdf0e10cSrcweir // update used area of the sheet
757cdf0e10cSrcweir extendUsedArea( maCellData.maCellAddr );
758cdf0e10cSrcweir
759cdf0e10cSrcweir // load the XF identifier according to current BIFF version
760cdf0e10cSrcweir if( bBiff2 )
761cdf0e10cSrcweir {
762cdf0e10cSrcweir /* #i71453# On first call, check if the file contains XF records
763cdf0e10cSrcweir (by trying to access the first XF with index 0). If there are
764cdf0e10cSrcweir no XFs, the explicit formatting information contained in each
765cdf0e10cSrcweir cell record will be used instead. */
766cdf0e10cSrcweir if( !mobBiff2HasXfs )
767cdf0e10cSrcweir mobBiff2HasXfs = getStyles().getCellXf( 0 ).get() != 0;
768cdf0e10cSrcweir // read formatting information (includes the XF identifier)
769cdf0e10cSrcweir sal_uInt8 nFlags1, nFlags2, nFlags3;
770cdf0e10cSrcweir rStrm >> nFlags1 >> nFlags2 >> nFlags3;
771cdf0e10cSrcweir /* If the file contains XFs, extract and set the XF identifier,
772cdf0e10cSrcweir otherwise get the explicit formatting. */
773cdf0e10cSrcweir if( mobBiff2HasXfs.get() )
774cdf0e10cSrcweir {
775cdf0e10cSrcweir maCellData.mnXfId = extractValue< sal_Int32 >( nFlags1, 0, 6 );
776cdf0e10cSrcweir /* If the identifier is equal to 63, then the real identifier
777cdf0e10cSrcweir is contained in the preceding IXFE record (stored in the
778cdf0e10cSrcweir class member mnBiff2XfId). */
779cdf0e10cSrcweir if( maCellData.mnXfId == BIFF2_CELL_USEIXFE )
780cdf0e10cSrcweir maCellData.mnXfId = mnBiff2XfId;
781cdf0e10cSrcweir }
782cdf0e10cSrcweir else
783cdf0e10cSrcweir {
784cdf0e10cSrcweir /* Let the Xf class do the API conversion. Keeping the member
785cdf0e10cSrcweir maCellData.mnXfId untouched will prevent to trigger the
786cdf0e10cSrcweir usual XF formatting conversion later on. */
787cdf0e10cSrcweir PropertySet aPropSet( getCell( maCellData.maCellAddr ) );
788cdf0e10cSrcweir Xf::writeBiff2CellFormatToPropertySet( *this, aPropSet, nFlags1, nFlags2, nFlags3 );
789cdf0e10cSrcweir }
790cdf0e10cSrcweir }
791cdf0e10cSrcweir else
792cdf0e10cSrcweir {
793cdf0e10cSrcweir // BIFF3-BIFF8: 16-bit XF identifier
794cdf0e10cSrcweir maCellData.mnXfId = rStrm.readuInt16();
795cdf0e10cSrcweir }
796cdf0e10cSrcweir }
797cdf0e10cSrcweir return bValidAddr;
798cdf0e10cSrcweir }
799cdf0e10cSrcweir
readCellHeader(BiffInputStream & rStrm,bool bBiff2)800cdf0e10cSrcweir bool BiffSheetDataContext::readCellHeader( BiffInputStream& rStrm, bool bBiff2 )
801cdf0e10cSrcweir {
802cdf0e10cSrcweir BinAddress aAddr;
803cdf0e10cSrcweir rStrm >> aAddr;
804cdf0e10cSrcweir return readCellXfId( rStrm, aAddr, bBiff2 );
805cdf0e10cSrcweir }
806cdf0e10cSrcweir
readFormulaRef(BiffInputStream & rStrm)807cdf0e10cSrcweir bool BiffSheetDataContext::readFormulaRef( BiffInputStream& rStrm )
808cdf0e10cSrcweir {
809cdf0e10cSrcweir BinRange aRange;
810cdf0e10cSrcweir aRange.read( rStrm, false ); // columns always 8-bit
811cdf0e10cSrcweir return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true );
812cdf0e10cSrcweir }
813cdf0e10cSrcweir
importBlank(BiffInputStream & rStrm)814cdf0e10cSrcweir void BiffSheetDataContext::importBlank( BiffInputStream& rStrm )
815cdf0e10cSrcweir {
816cdf0e10cSrcweir if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BLANK ) )
817cdf0e10cSrcweir mrSheetData.setBlankCell( maCellData );
818cdf0e10cSrcweir }
819cdf0e10cSrcweir
importBoolErr(BiffInputStream & rStrm)820cdf0e10cSrcweir void BiffSheetDataContext::importBoolErr( BiffInputStream& rStrm )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_BOOLERR ) )
823cdf0e10cSrcweir {
824cdf0e10cSrcweir sal_uInt8 nValue, nType;
825cdf0e10cSrcweir rStrm >> nValue >> nType;
826cdf0e10cSrcweir switch( nType )
827cdf0e10cSrcweir {
828cdf0e10cSrcweir case BIFF_BOOLERR_BOOL:
829cdf0e10cSrcweir maCellData.mnCellType = XML_b;
830cdf0e10cSrcweir mrSheetData.setBooleanCell( maCellData, nValue != 0 );
831cdf0e10cSrcweir break;
832cdf0e10cSrcweir case BIFF_BOOLERR_ERROR:
833cdf0e10cSrcweir maCellData.mnCellType = XML_e;
834cdf0e10cSrcweir mrSheetData.setErrorCell( maCellData, nValue );
835cdf0e10cSrcweir break;
836cdf0e10cSrcweir default:
837cdf0e10cSrcweir OSL_ENSURE( false, "BiffSheetDataContext::importBoolErr - unknown cell type" );
838cdf0e10cSrcweir maCellData.mnCellType = XML_TOKEN_INVALID;
839cdf0e10cSrcweir mrSheetData.setBlankCell( maCellData );
840cdf0e10cSrcweir }
841cdf0e10cSrcweir }
842cdf0e10cSrcweir }
843cdf0e10cSrcweir
importFormula(BiffInputStream & rStrm)844cdf0e10cSrcweir void BiffSheetDataContext::importFormula( BiffInputStream& rStrm )
845cdf0e10cSrcweir {
846cdf0e10cSrcweir if( readCellHeader( rStrm, getBiff() == BIFF2 ) )
847cdf0e10cSrcweir {
848cdf0e10cSrcweir maCellData.mnCellType = XML_n;
849cdf0e10cSrcweir rStrm.skip( mnFormulaSkipSize );
850cdf0e10cSrcweir ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm );
851cdf0e10cSrcweir mrSheetData.setFormulaCell( maCellData, aTokens );
852cdf0e10cSrcweir }
853cdf0e10cSrcweir }
854cdf0e10cSrcweir
importInteger(BiffInputStream & rStrm)855cdf0e10cSrcweir void BiffSheetDataContext::importInteger( BiffInputStream& rStrm )
856cdf0e10cSrcweir {
857cdf0e10cSrcweir if( readCellHeader( rStrm, true ) )
858cdf0e10cSrcweir {
859cdf0e10cSrcweir maCellData.mnCellType = XML_n;
860cdf0e10cSrcweir mrSheetData.setValueCell( maCellData, rStrm.readuInt16() );
861cdf0e10cSrcweir }
862cdf0e10cSrcweir }
863cdf0e10cSrcweir
importLabel(BiffInputStream & rStrm)864cdf0e10cSrcweir void BiffSheetDataContext::importLabel( BiffInputStream& rStrm )
865cdf0e10cSrcweir {
866cdf0e10cSrcweir /* the deep secrets of BIFF type and record identifier...
867cdf0e10cSrcweir record id BIFF -> XF type String type
868cdf0e10cSrcweir 0x0004 2-7 -> 3 byte 8-bit length, byte string
869cdf0e10cSrcweir 0x0004 8 -> 3 byte 16-bit length, unicode string
870cdf0e10cSrcweir 0x0204 2-7 -> 2 byte 16-bit length, byte string
871cdf0e10cSrcweir 0x0204 8 -> 2 byte 16-bit length, unicode string
872cdf0e10cSrcweir */
873cdf0e10cSrcweir bool bBiff2Xf = rStrm.getRecId() == BIFF2_ID_LABEL;
874cdf0e10cSrcweir if( readCellHeader( rStrm, bBiff2Xf ) )
875cdf0e10cSrcweir {
876cdf0e10cSrcweir maCellData.mnCellType = XML_inlineStr;
877cdf0e10cSrcweir if( getBiff() == BIFF8 )
878cdf0e10cSrcweir {
879cdf0e10cSrcweir // string may contain rich-text formatting
880cdf0e10cSrcweir RichStringRef xString( new RichString( *this ) );
881cdf0e10cSrcweir xString->importUniString( rStrm );
882cdf0e10cSrcweir xString->finalizeImport();
883cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, xString );
884cdf0e10cSrcweir }
885cdf0e10cSrcweir else
886cdf0e10cSrcweir {
887cdf0e10cSrcweir // #i63105# use text encoding from FONT record
888cdf0e10cSrcweir rtl_TextEncoding eTextEnc = getTextEncoding();
889cdf0e10cSrcweir if( const Font* pFont = getStyles().getFontFromCellXf( maCellData.mnXfId ).get() )
890cdf0e10cSrcweir eTextEnc = pFont->getFontEncoding();
891cdf0e10cSrcweir // RSTRING record contains rich-text formatting
892cdf0e10cSrcweir if( rStrm.getRecId() == BIFF_ID_RSTRING )
893cdf0e10cSrcweir {
894cdf0e10cSrcweir BiffStringFlags nFlags = BIFF_STR_EXTRAFONTS;
895cdf0e10cSrcweir // BIFF2 record identifier: 8-bit string length (see above)
896cdf0e10cSrcweir setFlag( nFlags, BIFF_STR_8BITLENGTH, bBiff2Xf );
897cdf0e10cSrcweir RichStringRef xString( new RichString( *this ) );
898cdf0e10cSrcweir xString->importByteString( rStrm, eTextEnc, nFlags );
899cdf0e10cSrcweir xString->finalizeImport();
900cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, xString );
901cdf0e10cSrcweir }
902cdf0e10cSrcweir else
903cdf0e10cSrcweir {
904cdf0e10cSrcweir // BIFF2 record identifier: 8-bit string length (see above)
905cdf0e10cSrcweir OUString aText = rStrm.readByteStringUC( !bBiff2Xf, eTextEnc );
906cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, aText );
907cdf0e10cSrcweir }
908cdf0e10cSrcweir }
909cdf0e10cSrcweir }
910cdf0e10cSrcweir }
911cdf0e10cSrcweir
importLabelSst(BiffInputStream & rStrm)912cdf0e10cSrcweir void BiffSheetDataContext::importLabelSst( BiffInputStream& rStrm )
913cdf0e10cSrcweir {
914cdf0e10cSrcweir if( readCellHeader( rStrm, false ) )
915cdf0e10cSrcweir {
916cdf0e10cSrcweir maCellData.mnCellType = XML_s;
917cdf0e10cSrcweir mrSheetData.setStringCell( maCellData, rStrm.readInt32() );
918cdf0e10cSrcweir }
919cdf0e10cSrcweir }
920cdf0e10cSrcweir
importMultBlank(BiffInputStream & rStrm)921cdf0e10cSrcweir void BiffSheetDataContext::importMultBlank( BiffInputStream& rStrm )
922cdf0e10cSrcweir {
923cdf0e10cSrcweir BinAddress aAddr;
924cdf0e10cSrcweir bool bValidAddr = true;
925cdf0e10cSrcweir for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol )
926cdf0e10cSrcweir if( (bValidAddr = readCellXfId( rStrm, aAddr, false )) == true )
927cdf0e10cSrcweir mrSheetData.setBlankCell( maCellData );
928cdf0e10cSrcweir }
929cdf0e10cSrcweir
importMultRk(BiffInputStream & rStrm)930cdf0e10cSrcweir void BiffSheetDataContext::importMultRk( BiffInputStream& rStrm )
931cdf0e10cSrcweir {
932cdf0e10cSrcweir BinAddress aAddr;
933cdf0e10cSrcweir bool bValidAddr = true;
934cdf0e10cSrcweir for( rStrm >> aAddr; bValidAddr && (rStrm.getRemaining() > 2); ++aAddr.mnCol )
935cdf0e10cSrcweir {
936cdf0e10cSrcweir if( (bValidAddr = readCellXfId( rStrm, aAddr, false )) == true )
937cdf0e10cSrcweir {
938cdf0e10cSrcweir maCellData.mnCellType = XML_n;
939cdf0e10cSrcweir sal_Int32 nRkValue = rStrm.readInt32();
940cdf0e10cSrcweir mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( nRkValue ) );
941cdf0e10cSrcweir }
942cdf0e10cSrcweir }
943cdf0e10cSrcweir }
944cdf0e10cSrcweir
importNumber(BiffInputStream & rStrm)945cdf0e10cSrcweir void BiffSheetDataContext::importNumber( BiffInputStream& rStrm )
946cdf0e10cSrcweir {
947cdf0e10cSrcweir if( readCellHeader( rStrm, rStrm.getRecId() == BIFF2_ID_NUMBER ) )
948cdf0e10cSrcweir {
949cdf0e10cSrcweir maCellData.mnCellType = XML_n;
950cdf0e10cSrcweir mrSheetData.setValueCell( maCellData, rStrm.readDouble() );
951cdf0e10cSrcweir }
952cdf0e10cSrcweir }
953cdf0e10cSrcweir
importRk(BiffInputStream & rStrm)954cdf0e10cSrcweir void BiffSheetDataContext::importRk( BiffInputStream& rStrm )
955cdf0e10cSrcweir {
956cdf0e10cSrcweir if( readCellHeader( rStrm, false ) )
957cdf0e10cSrcweir {
958cdf0e10cSrcweir maCellData.mnCellType = XML_n;
959cdf0e10cSrcweir mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
960cdf0e10cSrcweir }
961cdf0e10cSrcweir }
962cdf0e10cSrcweir
importArray(BiffInputStream & rStrm)963cdf0e10cSrcweir void BiffSheetDataContext::importArray( BiffInputStream& rStrm )
964cdf0e10cSrcweir {
965cdf0e10cSrcweir if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
966cdf0e10cSrcweir {
967cdf0e10cSrcweir rStrm.skip( mnArraySkipSize );
968cdf0e10cSrcweir ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm );
969cdf0e10cSrcweir mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens );
970cdf0e10cSrcweir }
971cdf0e10cSrcweir }
972cdf0e10cSrcweir
importDataTable(BiffInputStream & rStrm)973cdf0e10cSrcweir void BiffSheetDataContext::importDataTable( BiffInputStream& rStrm )
974cdf0e10cSrcweir {
975cdf0e10cSrcweir if( readFormulaRef( rStrm ) )
976cdf0e10cSrcweir {
977cdf0e10cSrcweir DataTableModel aModel;
978cdf0e10cSrcweir BinAddress aRef1, aRef2;
979cdf0e10cSrcweir switch( rStrm.getRecId() )
980cdf0e10cSrcweir {
981cdf0e10cSrcweir case BIFF2_ID_DATATABLE:
982cdf0e10cSrcweir rStrm.skip( 1 );
983cdf0e10cSrcweir aModel.mbRowTable = rStrm.readuInt8() != 0;
984cdf0e10cSrcweir aModel.mb2dTable = false;
985cdf0e10cSrcweir rStrm >> aRef1;
986cdf0e10cSrcweir break;
987cdf0e10cSrcweir case BIFF2_ID_DATATABLE2:
988cdf0e10cSrcweir rStrm.skip( 2 );
989cdf0e10cSrcweir aModel.mb2dTable = true;
990cdf0e10cSrcweir rStrm >> aRef1 >> aRef2;
991cdf0e10cSrcweir break;
992cdf0e10cSrcweir case BIFF3_ID_DATATABLE:
993cdf0e10cSrcweir {
994cdf0e10cSrcweir sal_uInt16 nFlags;
995cdf0e10cSrcweir rStrm >> nFlags >> aRef1 >> aRef2;
996cdf0e10cSrcweir aModel.mbRowTable = getFlag( nFlags, BIFF_DATATABLE_ROW );
997cdf0e10cSrcweir aModel.mb2dTable = getFlag( nFlags, BIFF_DATATABLE_2D );
998cdf0e10cSrcweir aModel.mbRef1Deleted = getFlag( nFlags, BIFF_DATATABLE_REF1DEL );
999cdf0e10cSrcweir aModel.mbRef2Deleted = getFlag( nFlags, BIFF_DATATABLE_REF2DEL );
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir break;
1002cdf0e10cSrcweir default:
1003cdf0e10cSrcweir OSL_ENSURE( false, "BiffSheetDataContext::importDataTable - unknown record id" );
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir aModel.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
1006cdf0e10cSrcweir aModel.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
1007cdf0e10cSrcweir mrSheetData.createTableOperation( maFmlaData.maFormulaRef, aModel );
1008cdf0e10cSrcweir }
1009cdf0e10cSrcweir }
1010cdf0e10cSrcweir
importSharedFmla(BiffInputStream & rStrm)1011cdf0e10cSrcweir void BiffSheetDataContext::importSharedFmla( BiffInputStream& rStrm )
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir if( readFormulaRef( rStrm ) && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
1014cdf0e10cSrcweir {
1015cdf0e10cSrcweir rStrm.skip( 2 ); // flags
1016cdf0e10cSrcweir ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_SHAREDFORMULA, rStrm );
1017cdf0e10cSrcweir mrSheetData.createSharedFormula( maCellData.maCellAddr, aTokens );
1018cdf0e10cSrcweir }
1019cdf0e10cSrcweir }
1020cdf0e10cSrcweir
1021cdf0e10cSrcweir // ============================================================================
1022cdf0e10cSrcweir
1023cdf0e10cSrcweir } // namespace xls
1024cdf0e10cSrcweir } // namespace oox
1025