Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "sheetdatacontext.hxx"
21 :
22 : #include <com/sun/star/table/CellContentType.hpp>
23 : #include <com/sun/star/table/XCell.hpp>
24 : #include <com/sun/star/table/XCellRange.hpp>
25 : #include <com/sun/star/text/XText.hpp>
26 : #include "oox/helper/attributelist.hxx"
27 : #include "oox/helper/propertyset.hxx"
28 : #include "addressconverter.hxx"
29 : #include "biffinputstream.hxx"
30 : #include "formulaparser.hxx"
31 : #include "richstringcontext.hxx"
32 : #include "unitconverter.hxx"
33 :
34 : namespace oox {
35 : namespace xls {
36 :
37 : // ============================================================================
38 :
39 : using namespace ::com::sun::star::sheet;
40 : using namespace ::com::sun::star::table;
41 : using namespace ::com::sun::star::text;
42 : using namespace ::com::sun::star::uno;
43 :
44 : using ::oox::core::ContextHandlerRef;
45 :
46 : // ============================================================================
47 :
48 : namespace {
49 :
50 : // record constants -----------------------------------------------------------
51 :
52 : const sal_uInt32 BIFF12_CELL_SHOWPHONETIC = 0x01000000;
53 :
54 : const sal_uInt8 BIFF12_DATATABLE_ROW = 0x01;
55 : const sal_uInt8 BIFF12_DATATABLE_2D = 0x02;
56 : const sal_uInt8 BIFF12_DATATABLE_REF1DEL = 0x04;
57 : const sal_uInt8 BIFF12_DATATABLE_REF2DEL = 0x08;
58 :
59 : const sal_uInt16 BIFF12_ROW_THICKTOP = 0x0001;
60 : const sal_uInt16 BIFF12_ROW_THICKBOTTOM = 0x0002;
61 : const sal_uInt16 BIFF12_ROW_COLLAPSED = 0x0800;
62 : const sal_uInt16 BIFF12_ROW_HIDDEN = 0x1000;
63 : const sal_uInt16 BIFF12_ROW_CUSTOMHEIGHT = 0x2000;
64 : const sal_uInt16 BIFF12_ROW_CUSTOMFORMAT = 0x4000;
65 : const sal_uInt8 BIFF12_ROW_SHOWPHONETIC = 0x01;
66 :
67 : const sal_uInt16 BIFF_DATATABLE_ROW = 0x0004;
68 : const sal_uInt16 BIFF_DATATABLE_2D = 0x0008;
69 : const sal_uInt16 BIFF_DATATABLE_REF1DEL = 0x0010;
70 : const sal_uInt16 BIFF_DATATABLE_REF2DEL = 0x0020;
71 :
72 : const sal_uInt8 BIFF_FORMULA_RES_STRING = 0; /// Result is a string.
73 : const sal_uInt8 BIFF_FORMULA_RES_BOOL = 1; /// Result is Boolean value.
74 : const sal_uInt8 BIFF_FORMULA_RES_ERROR = 2; /// Result is error code.
75 : const sal_uInt8 BIFF_FORMULA_RES_EMPTY = 3; /// Result is empty cell (BIFF8 only).
76 : const sal_uInt16 BIFF_FORMULA_SHARED = 0x0008; /// Shared formula cell.
77 :
78 : const sal_uInt8 BIFF2_ROW_CUSTOMFORMAT = 0x01;
79 : const sal_uInt16 BIFF_ROW_DEFAULTHEIGHT = 0x8000;
80 : const sal_uInt16 BIFF_ROW_HEIGHTMASK = 0x7FFF;
81 : const sal_uInt32 BIFF_ROW_COLLAPSED = 0x00000010;
82 : const sal_uInt32 BIFF_ROW_HIDDEN = 0x00000020;
83 : const sal_uInt32 BIFF_ROW_CUSTOMHEIGHT = 0x00000040;
84 : const sal_uInt32 BIFF_ROW_CUSTOMFORMAT = 0x00000080;
85 : const sal_uInt32 BIFF_ROW_THICKTOP = 0x10000000;
86 : const sal_uInt32 BIFF_ROW_THICKBOTTOM = 0x20000000;
87 : const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000;
88 :
89 : const sal_Int32 BIFF2_CELL_USEIXFE = 63;
90 :
91 : } // namespace
92 :
93 : // ============================================================================
94 :
95 43 : SheetDataContextBase::SheetDataContextBase( const WorksheetHelper& rHelper ) :
96 43 : mrAddressConv( rHelper.getAddressConverter() ),
97 43 : mrFormulaParser( rHelper.getFormulaParser() ),
98 43 : mrSheetData( rHelper.getSheetData() ),
99 172 : mnSheet( rHelper.getSheetIndex() )
100 : {
101 43 : }
102 :
103 43 : SheetDataContextBase::~SheetDataContextBase()
104 : {
105 43 : }
106 :
107 : // ============================================================================
108 :
109 43 : SheetDataContext::SheetDataContext( WorksheetFragmentBase& rFragment ) :
110 : WorksheetContextBase( rFragment ),
111 : SheetDataContextBase( rFragment ),
112 : mbHasFormula( false ),
113 : mbValidRange( false ),
114 : mnRow( -1 ),
115 43 : mnCol( -1 )
116 : {
117 43 : }
118 :
119 1998 : ContextHandlerRef SheetDataContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
120 : {
121 1998 : switch( getCurrentElement() )
122 : {
123 : case XLS_TOKEN( sheetData ):
124 260 : if( nElement == XLS_TOKEN( row ) ) { importRow( rAttribs ); return this; }
125 0 : break;
126 :
127 : case XLS_TOKEN( row ):
128 : // do not process cell elements with invalid (out-of-range) address
129 851 : if( nElement == XLS_TOKEN( c ) && importCell( rAttribs ) )
130 851 : return this;
131 0 : break;
132 :
133 : case XLS_TOKEN( c ):
134 887 : switch( nElement )
135 : {
136 : case XLS_TOKEN( is ):
137 0 : mxInlineStr.reset( new RichString( *this ) );
138 0 : return new RichStringContext( *this, mxInlineStr );
139 : case XLS_TOKEN( v ):
140 845 : return this; // characters contain cell value
141 : case XLS_TOKEN( f ):
142 42 : importFormula( rAttribs );
143 42 : return this; // characters contain formula string
144 : }
145 0 : break;
146 : }
147 0 : return 0;
148 : }
149 :
150 871 : void SheetDataContext::onCharacters( const OUString& rChars )
151 : {
152 871 : switch( getCurrentElement() )
153 : {
154 : case XLS_TOKEN( v ):
155 845 : maCellValue = rChars;
156 845 : break;
157 : case XLS_TOKEN( f ):
158 26 : if( maFmlaData.mnFormulaType != XML_TOKEN_INVALID )
159 : {
160 26 : maFormulaStr = rChars;
161 : }
162 26 : break;
163 : }
164 871 : }
165 :
166 2041 : void SheetDataContext::onEndElement()
167 : {
168 2041 : if( getCurrentElement() == XLS_TOKEN( c ) )
169 : {
170 : // try to create a formula cell
171 851 : if( mbHasFormula ) switch( maFmlaData.mnFormulaType )
172 : {
173 : // will buffer formulas but need to
174 : // a) need to set format first
175 : // :/
176 : case XML_normal:
177 25 : setCellFormula( maCellData.maCellAddr, maFormulaStr );
178 25 : mrSheetData.setCellFormat( maCellData );
179 :
180 : // If a number cell has some preloaded value, stick it into the buffer
181 : // but do this only for real cell formulas (not array, shared etc.)
182 25 : if( !( maCellValue.isEmpty() ) && ( maCellData.mnCellType == XML_n ) )
183 23 : setCellFormulaValue( maCellData.maCellAddr, maCellValue.toDouble() );
184 25 : break;
185 :
186 : case XML_shared:
187 17 : if( maFmlaData.mnSharedId >= 0 )
188 : {
189 17 : if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
190 : {
191 1 : createSharedFormulaMapEntry( maCellData.maCellAddr, maFmlaData.mnSharedId, maFormulaStr );
192 : }
193 17 : setCellFormula( maCellData.maCellAddr, maFmlaData.mnSharedId );
194 17 : mrSheetData.setCellFormat( maCellData );
195 : }
196 : else
197 : // no success, set plain cell value and formatting below
198 0 : mbHasFormula = false;
199 17 : break;
200 : case XML_array:
201 0 : if( mbValidRange && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
202 0 : setCellArrayFormula( maFmlaData.maFormulaRef, maCellData.maCellAddr, maFormulaStr );
203 : // set cell formatting, but do not set result as cell value
204 0 : mrSheetData.setBlankCell( maCellData );
205 0 : break;
206 : case XML_dataTable:
207 0 : if( mbValidRange )
208 0 : mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData );
209 : // set cell formatting, but do not set result as cell value
210 0 : mrSheetData.setBlankCell( maCellData );
211 0 : break;
212 : default:
213 : OSL_ENSURE( maFmlaData.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onEndElement - unknown formula type" );
214 0 : mbHasFormula = false;
215 : }
216 :
217 851 : if( !mbHasFormula )
218 : {
219 : // no formula created: try to set the cell value
220 809 : if( !maCellValue.isEmpty() ) switch( maCellData.mnCellType )
221 : {
222 : case XML_n:
223 737 : mrSheetData.setValueCell( maCellData, maCellValue.toDouble() );
224 737 : break;
225 : case XML_b:
226 0 : mrSheetData.setBooleanCell( maCellData, maCellValue.toDouble() != 0.0 );
227 0 : break;
228 : case XML_e:
229 0 : mrSheetData.setErrorCell( maCellData, maCellValue );
230 0 : break;
231 : case XML_str:
232 0 : mrSheetData.setStringCell( maCellData, maCellValue );
233 0 : break;
234 : case XML_s:
235 66 : mrSheetData.setStringCell( maCellData, maCellValue.toInt32() );
236 66 : break;
237 : }
238 6 : else if( (maCellData.mnCellType == XML_inlineStr) && mxInlineStr.get() )
239 : {
240 0 : mxInlineStr->finalizeImport();
241 0 : mrSheetData.setStringCell( maCellData, mxInlineStr );
242 : }
243 : else
244 : {
245 : // empty cell, update cell type
246 6 : maCellData.mnCellType = XML_TOKEN_INVALID;
247 6 : mrSheetData.setBlankCell( maCellData );
248 : }
249 : }
250 : }
251 2041 : }
252 :
253 0 : ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
254 : {
255 0 : switch( getCurrentElement() )
256 : {
257 : case BIFF12_ID_SHEETDATA:
258 0 : if( nRecId == BIFF12_ID_ROW ) { importRow( rStrm ); return this; }
259 0 : break;
260 :
261 : case BIFF12_ID_ROW:
262 0 : switch( nRecId )
263 : {
264 0 : case BIFF12_ID_ARRAY: importArray( rStrm ); break;
265 0 : case BIFF12_ID_CELL_BOOL: importCellBool( rStrm, CELLTYPE_VALUE ); break;
266 0 : case BIFF12_ID_CELL_BLANK: importCellBlank( rStrm, CELLTYPE_VALUE ); break;
267 0 : case BIFF12_ID_CELL_DOUBLE: importCellDouble( rStrm, CELLTYPE_VALUE ); break;
268 0 : case BIFF12_ID_CELL_ERROR: importCellError( rStrm, CELLTYPE_VALUE ); break;
269 0 : case BIFF12_ID_CELL_RK: importCellRk( rStrm, CELLTYPE_VALUE ); break;
270 0 : case BIFF12_ID_CELL_RSTRING: importCellRString( rStrm, CELLTYPE_VALUE ); break;
271 0 : case BIFF12_ID_CELL_SI: importCellSi( rStrm, CELLTYPE_VALUE ); break;
272 0 : case BIFF12_ID_CELL_STRING: importCellString( rStrm, CELLTYPE_VALUE ); break;
273 0 : case BIFF12_ID_DATATABLE: importDataTable( rStrm ); break;
274 0 : case BIFF12_ID_FORMULA_BOOL: importCellBool( rStrm, CELLTYPE_FORMULA ); break;
275 0 : case BIFF12_ID_FORMULA_DOUBLE: importCellDouble( rStrm, CELLTYPE_FORMULA ); break;
276 0 : case BIFF12_ID_FORMULA_ERROR: importCellError( rStrm, CELLTYPE_FORMULA ); break;
277 0 : case BIFF12_ID_FORMULA_STRING: importCellString( rStrm, CELLTYPE_FORMULA ); break;
278 0 : case BIFF12_ID_MULTCELL_BOOL: importCellBool( rStrm, CELLTYPE_MULTI ); break;
279 0 : case BIFF12_ID_MULTCELL_BLANK: importCellBlank( rStrm, CELLTYPE_MULTI ); break;
280 0 : case BIFF12_ID_MULTCELL_DOUBLE: importCellDouble( rStrm, CELLTYPE_MULTI ); break;
281 0 : case BIFF12_ID_MULTCELL_ERROR: importCellError( rStrm, CELLTYPE_MULTI ); break;
282 0 : case BIFF12_ID_MULTCELL_RK: importCellRk( rStrm, CELLTYPE_MULTI ); break;
283 0 : case BIFF12_ID_MULTCELL_RSTRING:importCellRString( rStrm, CELLTYPE_MULTI ); break;
284 0 : case BIFF12_ID_MULTCELL_SI: importCellSi( rStrm, CELLTYPE_MULTI ); break;
285 0 : case BIFF12_ID_MULTCELL_STRING: importCellString( rStrm, CELLTYPE_MULTI ); break;
286 0 : case BIFF12_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
287 : }
288 0 : break;
289 : }
290 0 : return 0;
291 : }
292 :
293 : // private --------------------------------------------------------------------
294 :
295 260 : void SheetDataContext::importRow( const AttributeList& rAttribs )
296 : {
297 260 : RowModel aModel;
298 260 : sal_Int32 nRow = rAttribs.getInteger( XML_r, -1 );
299 260 : if(nRow != -1)
300 260 : aModel.mnRow = nRow;
301 : else
302 0 : aModel.mnRow = ++mnRow;
303 260 : mnCol = -1;
304 :
305 260 : aModel.mfHeight = rAttribs.getDouble( XML_ht, -1.0 );
306 260 : aModel.mnXfId = rAttribs.getInteger( XML_s, -1 );
307 260 : aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
308 260 : aModel.mbCustomHeight = rAttribs.getBool( XML_customHeight, false );
309 260 : aModel.mbCustomFormat = rAttribs.getBool( XML_customFormat, false );
310 260 : aModel.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
311 260 : aModel.mbHidden = rAttribs.getBool( XML_hidden, false );
312 260 : aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
313 260 : aModel.mbThickTop = rAttribs.getBool( XML_thickTop, false );
314 260 : aModel.mbThickBottom = rAttribs.getBool( XML_thickBot, false );
315 :
316 : // decode the column spans (space-separated list of colon-separated integer pairs)
317 520 : OUString aColSpansText = rAttribs.getString( XML_spans, OUString() );
318 260 : sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
319 260 : sal_Int32 nIndex = 0;
320 780 : while( nIndex >= 0 )
321 : {
322 260 : OUString aColSpanToken = aColSpansText.getToken( 0, ' ', nIndex );
323 260 : sal_Int32 nSepPos = aColSpanToken.indexOf( ':' );
324 260 : if( (0 < nSepPos) && (nSepPos + 1 < aColSpanToken.getLength()) )
325 : {
326 : // OOXML uses 1-based integer column indexes, row model expects 0-based colspans
327 92 : sal_Int32 nLastCol = ::std::min( aColSpanToken.copy( nSepPos + 1 ).toInt32() - 1, nMaxCol );
328 92 : aModel.insertColSpan( ValueRange( aColSpanToken.copy( 0, nSepPos ).toInt32() - 1, nLastCol ) );
329 : }
330 260 : }
331 :
332 : // set row properties in the current sheet
333 520 : setRowModel( aModel );
334 260 : }
335 :
336 851 : bool SheetDataContext::importCell( const AttributeList& rAttribs )
337 : {
338 851 : OUString aCellAddrStr = rAttribs.getString( XML_r, OUString() );
339 851 : bool bValid = true;
340 851 : if(aCellAddrStr.isEmpty())
341 : {
342 0 : ++mnCol;
343 0 : maCellData.maCellAddr = CellAddress( mnSheet, mnCol, mnRow );
344 : }
345 : else
346 : {
347 851 : bValid = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, aCellAddrStr, mnSheet, true );
348 :
349 851 : mnCol = maCellData.maCellAddr.Column;
350 : }
351 :
352 851 : if( bValid )
353 : {
354 851 : maCellData.mnCellType = rAttribs.getToken( XML_t, XML_n );
355 851 : maCellData.mnXfId = rAttribs.getInteger( XML_s, -1 );
356 851 : maCellData.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
357 :
358 : // reset cell value, formula settings, and inline string
359 851 : maCellValue = OUString();
360 851 : mxInlineStr.reset();
361 851 : mbHasFormula = false;
362 :
363 : // update used area of the sheet
364 851 : extendUsedArea( maCellData.maCellAddr );
365 : }
366 851 : return bValid;
367 : }
368 :
369 42 : void SheetDataContext::importFormula( const AttributeList& rAttribs )
370 : {
371 42 : mbHasFormula = true;
372 42 : mbValidRange = mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, rAttribs.getString( XML_ref, OUString() ), mnSheet, true, true );
373 :
374 42 : maFmlaData.mnFormulaType = rAttribs.getToken( XML_t, XML_normal );
375 42 : maFmlaData.mnSharedId = rAttribs.getInteger( XML_si, -1 );
376 :
377 42 : if( maFmlaData.mnFormulaType == XML_dataTable )
378 : {
379 0 : maTableData.maRef1 = rAttribs.getString( XML_r1, OUString() );
380 0 : maTableData.maRef2 = rAttribs.getString( XML_r2, OUString() );
381 0 : maTableData.mb2dTable = rAttribs.getBool( XML_dt2D, false );
382 0 : maTableData.mbRowTable = rAttribs.getBool( XML_dtr, false );
383 0 : maTableData.mbRef1Deleted = rAttribs.getBool( XML_del1, false );
384 0 : maTableData.mbRef2Deleted = rAttribs.getBool( XML_del2, false );
385 : }
386 :
387 42 : maFormulaStr = OUString();
388 42 : }
389 :
390 0 : void SheetDataContext::importRow( SequenceInputStream& rStrm )
391 : {
392 0 : RowModel aModel;
393 : sal_Int32 nSpanCount;
394 : sal_uInt16 nHeight, nFlags1;
395 : sal_uInt8 nFlags2;
396 0 : rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2 >> nSpanCount;
397 0 : maCurrPos.mnCol = 0;
398 :
399 : // row index is 0-based in BIFF12, but RowModel expects 1-based
400 0 : aModel.mnRow = maCurrPos.mnRow + 1;
401 : // row height is in twips in BIFF12, convert to points
402 0 : aModel.mfHeight = nHeight / 20.0;
403 0 : aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 );
404 0 : aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT );
405 0 : aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT );
406 0 : aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC );
407 0 : aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN );
408 0 : aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED );
409 0 : aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP );
410 0 : aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM );
411 :
412 : // read the column spans
413 0 : sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
414 0 : for( sal_Int32 nSpanIdx = 0; (nSpanIdx < nSpanCount) && !rStrm.isEof(); ++nSpanIdx )
415 : {
416 : sal_Int32 nFirstCol, nLastCol;
417 0 : rStrm >> nFirstCol >> nLastCol;
418 0 : aModel.insertColSpan( ValueRange( nFirstCol, ::std::min( nLastCol, nMaxCol ) ) );
419 : }
420 :
421 : // set row properties in the current sheet
422 0 : setRowModel( aModel );
423 0 : }
424 :
425 0 : bool SheetDataContext::readCellHeader( SequenceInputStream& rStrm, CellType eCellType )
426 : {
427 0 : switch( eCellType )
428 : {
429 : case CELLTYPE_VALUE:
430 0 : case CELLTYPE_FORMULA: rStrm >> maCurrPos.mnCol; break;
431 0 : case CELLTYPE_MULTI: ++maCurrPos.mnCol; break;
432 : }
433 :
434 : sal_uInt32 nXfId;
435 0 : rStrm >> nXfId;
436 :
437 0 : bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, maCurrPos, mnSheet, true );
438 0 : maCellData.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 );
439 0 : maCellData.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC );
440 :
441 : // update used area of the sheet
442 0 : if( bValidAddr )
443 0 : extendUsedArea( maCellData.maCellAddr );
444 0 : return bValidAddr;
445 : }
446 :
447 0 : ApiTokenSequence SheetDataContext::readCellFormula( SequenceInputStream& rStrm )
448 : {
449 0 : rStrm.skip( 2 );
450 0 : return mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm );
451 : }
452 :
453 0 : bool SheetDataContext::readFormulaRef( SequenceInputStream& rStrm )
454 : {
455 0 : BinRange aRange;
456 0 : rStrm >> aRange;
457 0 : return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true );
458 : }
459 :
460 0 : void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCellType )
461 : {
462 0 : if( readCellHeader( rStrm, eCellType ) )
463 : {
464 0 : maCellData.mnCellType = XML_b;
465 0 : bool bValue = rStrm.readuInt8() != 0;
466 0 : if( eCellType == CELLTYPE_FORMULA )
467 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
468 : else
469 0 : mrSheetData.setBooleanCell( maCellData, bValue );
470 : }
471 0 : }
472 :
473 0 : void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCellType )
474 : {
475 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" );
476 0 : if( readCellHeader( rStrm, eCellType ) )
477 0 : mrSheetData.setBlankCell( maCellData );
478 0 : }
479 :
480 0 : void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType )
481 : {
482 0 : if( readCellHeader( rStrm, eCellType ) )
483 : {
484 0 : maCellData.mnCellType = XML_n;
485 0 : double fValue = rStrm.readDouble();
486 0 : if( eCellType == CELLTYPE_FORMULA )
487 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
488 : else
489 0 : mrSheetData.setValueCell( maCellData, fValue );
490 : }
491 0 : }
492 :
493 0 : void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCellType )
494 : {
495 0 : if( readCellHeader( rStrm, eCellType ) )
496 : {
497 0 : maCellData.mnCellType = XML_e;
498 0 : sal_uInt8 nErrorCode = rStrm.readuInt8();
499 0 : if( eCellType == CELLTYPE_FORMULA )
500 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
501 : else
502 0 : mrSheetData.setErrorCell( maCellData, nErrorCode );
503 : }
504 0 : }
505 :
506 0 : void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellType )
507 : {
508 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRk - no formula cells supported" );
509 0 : if( readCellHeader( rStrm, eCellType ) )
510 : {
511 0 : maCellData.mnCellType = XML_n;
512 0 : mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
513 : }
514 0 : }
515 :
516 0 : void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType eCellType )
517 : {
518 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRString - no formula cells supported" );
519 0 : if( readCellHeader( rStrm, eCellType ) )
520 : {
521 0 : maCellData.mnCellType = XML_inlineStr;
522 0 : RichStringRef xString( new RichString( *this ) );
523 0 : xString->importString( rStrm, true );
524 0 : xString->finalizeImport();
525 0 : mrSheetData.setStringCell( maCellData, xString );
526 : }
527 0 : }
528 :
529 0 : void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellType )
530 : {
531 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellSi - no formula cells supported" );
532 0 : if( readCellHeader( rStrm, eCellType ) )
533 : {
534 0 : maCellData.mnCellType = XML_s;
535 0 : mrSheetData.setStringCell( maCellData, rStrm.readInt32() );
536 : }
537 0 : }
538 :
539 0 : void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eCellType )
540 : {
541 0 : if( readCellHeader( rStrm, eCellType ) )
542 : {
543 0 : maCellData.mnCellType = XML_inlineStr;
544 : // always import the string, stream will point to formula afterwards, if existing
545 0 : RichStringRef xString( new RichString( *this ) );
546 0 : xString->importString( rStrm, false );
547 0 : xString->finalizeImport();
548 0 : if( eCellType == CELLTYPE_FORMULA )
549 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
550 : else
551 0 : mrSheetData.setStringCell( maCellData, xString );
552 : }
553 0 : }
554 :
555 0 : void SheetDataContext::importArray( SequenceInputStream& rStrm )
556 : {
557 0 : if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
558 : {
559 0 : rStrm.skip( 1 );
560 0 : ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm );
561 0 : mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens );
562 : }
563 0 : }
564 :
565 0 : void SheetDataContext::importDataTable( SequenceInputStream& rStrm )
566 : {
567 0 : if( readFormulaRef( rStrm ) )
568 : {
569 0 : BinAddress aRef1, aRef2;
570 : sal_uInt8 nFlags;
571 0 : rStrm >> aRef1 >> aRef2 >> nFlags;
572 0 : maTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
573 0 : maTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
574 0 : maTableData.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW );
575 0 : maTableData.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D );
576 0 : maTableData.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL );
577 0 : maTableData.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL );
578 0 : mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData );
579 : }
580 0 : }
581 :
582 0 : void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm )
583 : {
584 0 : if( readFormulaRef( rStrm ) && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
585 : {
586 0 : ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_SHAREDFORMULA, rStrm );
587 0 : mrSheetData.createSharedFormula( maCellData.maCellAddr, aTokens );
588 : }
589 0 : }
590 :
591 : // ============================================================================
592 :
593 : } // namespace xls
594 15 : } // namespace oox
595 :
596 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|