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