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