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 85 : SheetDataContextBase::SheetDataContextBase( const WorksheetHelper& rHelper ) :
66 85 : mrAddressConv( rHelper.getAddressConverter() ),
67 85 : mrFormulaParser( rHelper.getFormulaParser() ),
68 85 : mrSheetData( rHelper.getSheetData() ),
69 340 : mnSheet( rHelper.getSheetIndex() )
70 : {
71 85 : }
72 :
73 85 : SheetDataContextBase::~SheetDataContextBase()
74 : {
75 85 : }
76 :
77 85 : SheetDataContext::SheetDataContext( WorksheetFragmentBase& rFragment ) :
78 : WorksheetContextBase( rFragment ),
79 : SheetDataContextBase( rFragment ),
80 : mbHasFormula( false ),
81 : mbValidRange( false ),
82 : mnRow( -1 ),
83 85 : mnCol( -1 )
84 : {
85 : SAL_INFO( "sc.filter", "start safe sheet data context - unlock\n" );
86 85 : }
87 :
88 170 : SheetDataContext::~SheetDataContext()
89 : {
90 : SAL_INFO( "sc.filter", "end safe sheet data context - relock\n" );
91 170 : }
92 :
93 4500 : ContextHandlerRef SheetDataContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
94 : {
95 4500 : switch( getCurrentElement() )
96 : {
97 : case XLS_TOKEN( sheetData ):
98 540 : 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 1977 : if( nElement == XLS_TOKEN( c ) && importCell( rAttribs ) )
104 1977 : return this;
105 0 : break;
106 :
107 : case XLS_TOKEN( c ):
108 1983 : 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 1706 : return this; // characters contain cell value
115 : case XLS_TOKEN( f ):
116 277 : importFormula( rAttribs );
117 277 : return this; // characters contain formula string
118 : }
119 0 : break;
120 : }
121 0 : return 0;
122 : }
123 :
124 1879 : void SheetDataContext::onCharacters( const OUString& rChars )
125 : {
126 1879 : switch( getCurrentElement() )
127 : {
128 : case XLS_TOKEN( v ):
129 1706 : maCellValue = rChars;
130 1706 : break;
131 : case XLS_TOKEN( f ):
132 173 : if( maFmlaData.mnFormulaType != XML_TOKEN_INVALID )
133 : {
134 173 : maFormulaStr = rChars;
135 : }
136 173 : break;
137 : }
138 1879 : }
139 :
140 4585 : void SheetDataContext::onEndElement()
141 : {
142 4585 : if( getCurrentElement() == XLS_TOKEN( c ) )
143 : {
144 : // try to create a formula cell
145 1977 : 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 167 : setCellFormula( maCellData.maCellAddr, maFormulaStr );
152 167 : 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 167 : if (!maCellValue.isEmpty())
157 167 : setCellFormulaValue(maCellData.maCellAddr, maCellValue, maCellData.mnCellType);
158 167 : break;
159 :
160 : case XML_shared:
161 107 : if( maFmlaData.mnSharedId >= 0 )
162 : {
163 107 : if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) )
164 6 : createSharedFormulaMapEntry(maCellData.maCellAddr, maFmlaData.maFormulaRef, maFmlaData.mnSharedId, maFormulaStr);
165 :
166 107 : setCellFormula(maCellData.maCellAddr, maFmlaData.mnSharedId, maCellValue, maCellData.mnCellType);
167 107 : mrSheetData.setCellFormat( maCellData );
168 : }
169 : else
170 : // no success, set plain cell value and formatting below
171 0 : mbHasFormula = false;
172 107 : 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 1977 : if( !mbHasFormula )
191 : {
192 : // no formula created: try to set the cell value
193 1700 : if( !maCellValue.isEmpty() ) switch( maCellData.mnCellType )
194 : {
195 : case XML_n:
196 1154 : mrSheetData.setValueCell( maCellData, maCellValue.toDouble() );
197 1154 : break;
198 : case XML_b:
199 0 : mrSheetData.setBooleanCell( maCellData, maCellValue.toDouble() != 0.0 );
200 0 : 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 275 : mrSheetData.setStringCell( maCellData, maCellValue.toInt32() );
209 275 : break;
210 : case XML_d:
211 0 : mrSheetData.setDateCell( maCellData, maCellValue );
212 0 : break;
213 : }
214 271 : 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 271 : maCellData.mnCellType = XML_TOKEN_INVALID;
223 271 : mrSheetData.setBlankCell( maCellData );
224 : }
225 : }
226 : }
227 4585 : }
228 :
229 0 : ContextHandlerRef SheetDataContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
230 : {
231 0 : switch( getCurrentElement() )
232 : {
233 : case BIFF12_ID_SHEETDATA:
234 0 : if( nRecId == BIFF12_ID_ROW ) { importRow( rStrm ); return this; }
235 0 : break;
236 :
237 : case BIFF12_ID_ROW:
238 0 : 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 0 : 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 0 : case BIFF12_ID_CELL_RK: importCellRk( rStrm, CELLTYPE_VALUE ); break;
246 0 : case BIFF12_ID_CELL_RSTRING: importCellRString( rStrm, CELLTYPE_VALUE ); break;
247 0 : 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 0 : 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 0 : case BIFF12_ID_SHAREDFMLA: importSharedFmla( rStrm ); break;
263 : }
264 0 : break;
265 : }
266 0 : return 0;
267 : }
268 :
269 : // private --------------------------------------------------------------------
270 :
271 540 : void SheetDataContext::importRow( const AttributeList& rAttribs )
272 : {
273 540 : RowModel aModel;
274 540 : sal_Int32 nRow = rAttribs.getInteger( XML_r, -1 ); // 1-based row index
275 540 : if(nRow != -1)
276 : {
277 540 : aModel.mnRow = nRow;
278 540 : mnRow = nRow-1; // to 0-based row index.
279 : }
280 : else
281 0 : aModel.mnRow = ++mnRow;
282 540 : mnCol = -1;
283 :
284 540 : aModel.mfHeight = rAttribs.getDouble( XML_ht, -1.0 );
285 540 : aModel.mnXfId = rAttribs.getInteger( XML_s, -1 );
286 540 : aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
287 540 : aModel.mbCustomHeight = rAttribs.getBool( XML_customHeight, false );
288 540 : aModel.mbCustomFormat = rAttribs.getBool( XML_customFormat, false );
289 540 : aModel.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
290 540 : aModel.mbHidden = rAttribs.getBool( XML_hidden, false );
291 540 : aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
292 540 : aModel.mbThickTop = rAttribs.getBool( XML_thickTop, false );
293 540 : aModel.mbThickBottom = rAttribs.getBool( XML_thickBot, false );
294 :
295 : // decode the column spans (space-separated list of colon-separated integer pairs)
296 1080 : OUString aColSpansText = rAttribs.getString( XML_spans, OUString() );
297 540 : sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
298 540 : sal_Int32 nIndex = 0;
299 1620 : while( nIndex >= 0 )
300 : {
301 540 : OUString aColSpanToken = aColSpansText.getToken( 0, ' ', nIndex );
302 540 : sal_Int32 nSepPos = aColSpanToken.indexOf( ':' );
303 540 : if( (0 < nSepPos) && (nSepPos + 1 < aColSpanToken.getLength()) )
304 : {
305 : // OOXML uses 1-based integer column indexes, row model expects 0-based colspans
306 274 : sal_Int32 nLastCol = ::std::min( aColSpanToken.copy( nSepPos + 1 ).toInt32() - 1, nMaxCol );
307 274 : aModel.insertColSpan( ValueRange( aColSpanToken.copy( 0, nSepPos ).toInt32() - 1, nLastCol ) );
308 : }
309 540 : }
310 :
311 : // set row properties in the current sheet
312 1080 : setRowModel( aModel );
313 540 : }
314 :
315 1977 : bool SheetDataContext::importCell( const AttributeList& rAttribs )
316 : {
317 1977 : bool bValid = true;
318 1977 : const char* p = rAttribs.getChar(XML_r);
319 :
320 1977 : if (!p)
321 : {
322 3 : ++mnCol;
323 3 : maCellData.maCellAddr = CellAddress( mnSheet, mnCol, mnRow );
324 : }
325 : else
326 : {
327 1974 : bValid = mrAddressConv.convertToCellAddress(maCellData.maCellAddr, p, mnSheet, true);
328 1974 : mnCol = maCellData.maCellAddr.Column;
329 : }
330 :
331 1977 : if( bValid )
332 : {
333 1977 : maCellData.mnCellType = rAttribs.getToken( XML_t, XML_n );
334 1977 : maCellData.mnXfId = rAttribs.getInteger( XML_s, -1 );
335 1977 : maCellData.mbShowPhonetic = rAttribs.getBool( XML_ph, false );
336 :
337 : // reset cell value, formula settings, and inline string
338 1977 : maCellValue = OUString();
339 1977 : mxInlineStr.reset();
340 1977 : mbHasFormula = false;
341 :
342 : // update used area of the sheet
343 1977 : extendUsedArea( maCellData.maCellAddr );
344 : }
345 1977 : return bValid;
346 : }
347 :
348 277 : void SheetDataContext::importFormula( const AttributeList& rAttribs )
349 : {
350 277 : mbHasFormula = true;
351 277 : mbValidRange = mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, rAttribs.getString( XML_ref, OUString() ), mnSheet, true, true );
352 :
353 277 : maFmlaData.mnFormulaType = rAttribs.getToken( XML_t, XML_normal );
354 277 : maFmlaData.mnSharedId = rAttribs.getInteger( XML_si, -1 );
355 :
356 277 : 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 277 : maFormulaStr = OUString();
367 277 : }
368 :
369 0 : void SheetDataContext::importRow( SequenceInputStream& rStrm )
370 : {
371 0 : RowModel aModel;
372 : sal_Int32 nSpanCount;
373 : sal_uInt16 nHeight, nFlags1;
374 : sal_uInt8 nFlags2;
375 0 : rStrm >> maCurrPos.mnRow >> aModel.mnXfId >> nHeight >> nFlags1 >> nFlags2 >> nSpanCount;
376 0 : maCurrPos.mnCol = 0;
377 :
378 : // row index is 0-based in BIFF12, but RowModel expects 1-based
379 0 : aModel.mnRow = maCurrPos.mnRow + 1;
380 : // row height is in twips in BIFF12, convert to points
381 0 : aModel.mfHeight = nHeight / 20.0;
382 0 : aModel.mnLevel = extractValue< sal_Int32 >( nFlags1, 8, 3 );
383 0 : aModel.mbCustomHeight = getFlag( nFlags1, BIFF12_ROW_CUSTOMHEIGHT );
384 0 : aModel.mbCustomFormat = getFlag( nFlags1, BIFF12_ROW_CUSTOMFORMAT );
385 0 : aModel.mbShowPhonetic = getFlag( nFlags2, BIFF12_ROW_SHOWPHONETIC );
386 0 : aModel.mbHidden = getFlag( nFlags1, BIFF12_ROW_HIDDEN );
387 0 : aModel.mbCollapsed = getFlag( nFlags1, BIFF12_ROW_COLLAPSED );
388 0 : aModel.mbThickTop = getFlag( nFlags1, BIFF12_ROW_THICKTOP );
389 0 : aModel.mbThickBottom = getFlag( nFlags1, BIFF12_ROW_THICKBOTTOM );
390 :
391 : // read the column spans
392 0 : sal_Int32 nMaxCol = mrAddressConv.getMaxApiAddress().Column;
393 0 : for( sal_Int32 nSpanIdx = 0; (nSpanIdx < nSpanCount) && !rStrm.isEof(); ++nSpanIdx )
394 : {
395 : sal_Int32 nFirstCol, nLastCol;
396 0 : rStrm >> nFirstCol >> nLastCol;
397 0 : aModel.insertColSpan( ValueRange( nFirstCol, ::std::min( nLastCol, nMaxCol ) ) );
398 : }
399 :
400 : // set row properties in the current sheet
401 0 : setRowModel( aModel );
402 0 : }
403 :
404 0 : bool SheetDataContext::readCellHeader( SequenceInputStream& rStrm, CellType eCellType )
405 : {
406 0 : switch( eCellType )
407 : {
408 : case CELLTYPE_VALUE:
409 0 : case CELLTYPE_FORMULA: rStrm >> maCurrPos.mnCol; break;
410 0 : case CELLTYPE_MULTI: ++maCurrPos.mnCol; break;
411 : }
412 :
413 : sal_uInt32 nXfId;
414 0 : rStrm >> nXfId;
415 :
416 0 : bool bValidAddr = mrAddressConv.convertToCellAddress( maCellData.maCellAddr, maCurrPos, mnSheet, true );
417 0 : maCellData.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 );
418 0 : maCellData.mbShowPhonetic = getFlag( nXfId, BIFF12_CELL_SHOWPHONETIC );
419 :
420 : // update used area of the sheet
421 0 : if( bValidAddr )
422 0 : extendUsedArea( maCellData.maCellAddr );
423 0 : return bValidAddr;
424 : }
425 :
426 0 : ApiTokenSequence SheetDataContext::readCellFormula( SequenceInputStream& rStrm )
427 : {
428 0 : rStrm.skip( 2 );
429 0 : return mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_CELL, rStrm );
430 : }
431 :
432 0 : bool SheetDataContext::readFormulaRef( SequenceInputStream& rStrm )
433 : {
434 0 : BinRange aRange;
435 0 : rStrm >> aRange;
436 0 : return mrAddressConv.convertToCellRange( maFmlaData.maFormulaRef, aRange, mnSheet, true, true );
437 : }
438 :
439 0 : void SheetDataContext::importCellBool( SequenceInputStream& rStrm, CellType eCellType )
440 : {
441 0 : if( readCellHeader( rStrm, eCellType ) )
442 : {
443 0 : maCellData.mnCellType = XML_b;
444 0 : bool bValue = rStrm.readuInt8() != 0;
445 0 : if( eCellType == CELLTYPE_FORMULA )
446 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
447 : else
448 0 : mrSheetData.setBooleanCell( maCellData, bValue );
449 : }
450 0 : }
451 :
452 0 : void SheetDataContext::importCellBlank( SequenceInputStream& rStrm, CellType eCellType )
453 : {
454 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellBlank - no formula cells supported" );
455 0 : if( readCellHeader( rStrm, eCellType ) )
456 0 : mrSheetData.setBlankCell( maCellData );
457 0 : }
458 :
459 0 : void SheetDataContext::importCellDouble( SequenceInputStream& rStrm, CellType eCellType )
460 : {
461 0 : if( readCellHeader( rStrm, eCellType ) )
462 : {
463 0 : maCellData.mnCellType = XML_n;
464 0 : double fValue = rStrm.readDouble();
465 0 : if( eCellType == CELLTYPE_FORMULA )
466 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
467 : else
468 0 : mrSheetData.setValueCell( maCellData, fValue );
469 : }
470 0 : }
471 :
472 0 : void SheetDataContext::importCellError( SequenceInputStream& rStrm, CellType eCellType )
473 : {
474 0 : if( readCellHeader( rStrm, eCellType ) )
475 : {
476 0 : maCellData.mnCellType = XML_e;
477 0 : sal_uInt8 nErrorCode = rStrm.readuInt8();
478 0 : if( eCellType == CELLTYPE_FORMULA )
479 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
480 : else
481 0 : mrSheetData.setErrorCell( maCellData, nErrorCode );
482 : }
483 0 : }
484 :
485 0 : void SheetDataContext::importCellRk( SequenceInputStream& rStrm, CellType eCellType )
486 : {
487 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRk - no formula cells supported" );
488 0 : if( readCellHeader( rStrm, eCellType ) )
489 : {
490 0 : maCellData.mnCellType = XML_n;
491 0 : mrSheetData.setValueCell( maCellData, BiffHelper::calcDoubleFromRk( rStrm.readInt32() ) );
492 : }
493 0 : }
494 :
495 0 : void SheetDataContext::importCellRString( SequenceInputStream& rStrm, CellType eCellType )
496 : {
497 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellRString - no formula cells supported" );
498 0 : if( readCellHeader( rStrm, eCellType ) )
499 : {
500 0 : maCellData.mnCellType = XML_inlineStr;
501 0 : RichStringRef xString( new RichString( *this ) );
502 0 : xString->importString( rStrm, true );
503 0 : xString->finalizeImport();
504 0 : mrSheetData.setStringCell( maCellData, xString );
505 : }
506 0 : }
507 :
508 0 : void SheetDataContext::importCellSi( SequenceInputStream& rStrm, CellType eCellType )
509 : {
510 : OSL_ENSURE( eCellType != CELLTYPE_FORMULA, "SheetDataContext::importCellSi - no formula cells supported" );
511 0 : if( readCellHeader( rStrm, eCellType ) )
512 : {
513 0 : maCellData.mnCellType = XML_s;
514 0 : mrSheetData.setStringCell( maCellData, rStrm.readInt32() );
515 : }
516 0 : }
517 :
518 0 : void SheetDataContext::importCellString( SequenceInputStream& rStrm, CellType eCellType )
519 : {
520 0 : if( readCellHeader( rStrm, eCellType ) )
521 : {
522 0 : maCellData.mnCellType = XML_inlineStr;
523 : // always import the string, stream will point to formula afterwards, if existing
524 0 : RichStringRef xString( new RichString( *this ) );
525 0 : xString->importString( rStrm, false );
526 0 : xString->finalizeImport();
527 0 : if( eCellType == CELLTYPE_FORMULA )
528 0 : mrSheetData.setFormulaCell( maCellData, readCellFormula( rStrm ) );
529 : else
530 0 : mrSheetData.setStringCell( maCellData, xString );
531 : }
532 0 : }
533 :
534 0 : void SheetDataContext::importArray( SequenceInputStream& rStrm )
535 : {
536 0 : if( readFormulaRef( rStrm ) && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) )
537 : {
538 0 : rStrm.skip( 1 );
539 0 : ApiTokenSequence aTokens = mrFormulaParser.importFormula( maCellData.maCellAddr, FORMULATYPE_ARRAY, rStrm );
540 0 : mrSheetData.createArrayFormula( maFmlaData.maFormulaRef, aTokens );
541 : }
542 0 : }
543 :
544 0 : void SheetDataContext::importDataTable( SequenceInputStream& rStrm )
545 : {
546 0 : if( readFormulaRef( rStrm ) )
547 : {
548 0 : BinAddress aRef1, aRef2;
549 : sal_uInt8 nFlags;
550 0 : rStrm >> aRef1 >> aRef2 >> nFlags;
551 0 : maTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false );
552 0 : maTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false );
553 0 : maTableData.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW );
554 0 : maTableData.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D );
555 0 : maTableData.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL );
556 0 : maTableData.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL );
557 0 : mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData );
558 : }
559 0 : }
560 :
561 0 : void SheetDataContext::importSharedFmla( SequenceInputStream& /*rStrm*/ )
562 : {
563 0 : }
564 :
565 : } // namespace xls
566 18 : } // namespace oox
567 :
568 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|