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