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