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