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