Update ooo320-m1
[ooovba.git] / oox / source / xls / worksheetfragment.cxx
blob3fe45b06a6b2ba201f12d0c66e0293b4887d5217
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: worksheetfragment.cxx,v $
10 * $Revision: 1.5.4.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/xls/worksheetfragment.hxx"
32 #include "oox/helper/attributelist.hxx"
33 #include "oox/helper/recordinputstream.hxx"
34 #include "oox/core/filterbase.hxx"
35 #include "oox/core/relations.hxx"
36 #include "oox/xls/addressconverter.hxx"
37 #include "oox/xls/autofiltercontext.hxx"
38 #include "oox/xls/biffinputstream.hxx"
39 #include "oox/xls/commentsfragment.hxx"
40 #include "oox/xls/condformatcontext.hxx"
41 #include "oox/xls/drawingfragment.hxx"
42 #include "oox/xls/externallinkbuffer.hxx"
43 #include "oox/xls/pagesettings.hxx"
44 #include "oox/xls/pivottablebuffer.hxx"
45 #include "oox/xls/pivottablefragment.hxx"
46 #include "oox/xls/querytablefragment.hxx"
47 #include "oox/xls/scenariobuffer.hxx"
48 #include "oox/xls/scenariocontext.hxx"
49 #include "oox/xls/sheetdatacontext.hxx"
50 #include "oox/xls/tablefragment.hxx"
51 #include "oox/xls/viewsettings.hxx"
52 #include "oox/xls/workbooksettings.hxx"
53 #include "oox/xls/worksheetsettings.hxx"
55 using ::rtl::OUString;
56 using ::rtl::OUStringBuffer;
57 using ::com::sun::star::uno::Any;
58 using ::com::sun::star::uno::Reference;
59 using ::com::sun::star::uno::Exception;
60 using ::com::sun::star::table::CellAddress;
61 using ::com::sun::star::table::CellRangeAddress;
62 using ::oox::core::ContextHandlerRef;
63 using ::oox::core::RecordInfo;
64 using ::oox::core::Relations;
65 using ::oox::core::RelationsRef;
67 namespace oox {
68 namespace xls {
70 // ============================================================================
72 namespace {
74 const sal_uInt16 BIFF_COLINFO_HIDDEN = 0x0001;
75 const sal_uInt16 BIFF_COLINFO_SHOWPHONETIC = 0x0008;
76 const sal_uInt16 BIFF_COLINFO_COLLAPSED = 0x1000;
78 const sal_uInt16 BIFF_DEFROW_CUSTOMHEIGHT = 0x0001;
79 const sal_uInt16 BIFF_DEFROW_HIDDEN = 0x0002;
80 const sal_uInt16 BIFF_DEFROW_THICKTOP = 0x0004;
81 const sal_uInt16 BIFF_DEFROW_THICKBOTTOM = 0x0008;
82 const sal_uInt16 BIFF2_DEFROW_DEFHEIGHT = 0x8000;
83 const sal_uInt16 BIFF2_DEFROW_MASK = 0x7FFF;
85 const sal_uInt32 BIFF_DATAVAL_STRINGLIST = 0x00000080;
86 const sal_uInt32 BIFF_DATAVAL_ALLOWBLANK = 0x00000100;
87 const sal_uInt32 BIFF_DATAVAL_NODROPDOWN = 0x00000200;
88 const sal_uInt32 BIFF_DATAVAL_SHOWINPUT = 0x00040000;
89 const sal_uInt32 BIFF_DATAVAL_SHOWERROR = 0x00080000;
91 const sal_Int32 OOBIN_OLEOBJECT_CONTENT = 1;
92 const sal_Int32 OOBIN_OLEOBJECT_ICON = 4;
93 const sal_Int32 OOBIN_OLEOBJECT_ALWAYS = 1;
94 const sal_Int32 OOBIN_OLEOBJECT_ONCALL = 3;
95 const sal_uInt16 OOBIN_OLEOBJECT_LINKED = 0x0001;
96 const sal_uInt16 OOBIN_OLEOBJECT_AUTOLOAD = 0x0002;
98 } // namespace
100 // ============================================================================
102 OoxDataValidationsContext::OoxDataValidationsContext( OoxWorksheetFragmentBase& rFragment ) :
103 OoxWorksheetContextBase( rFragment )
107 ContextHandlerRef OoxDataValidationsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
109 switch( getCurrentElement() )
111 case XLS_TOKEN( dataValidations ):
112 if( nElement == XLS_TOKEN( dataValidation ) )
114 importDataValidation( rAttribs );
115 return this;
117 break;
118 case XLS_TOKEN( dataValidation ):
119 switch( nElement )
121 case XLS_TOKEN( formula1 ):
122 case XLS_TOKEN( formula2 ):
123 return this; // collect formulas in onEndElement()
125 break;
127 return 0;
130 namespace {
132 ApiTokenSequence lclImportDataValFormula( FormulaParser& rParser, const OUString& rFormula, const CellAddress& rBaseAddress )
134 TokensFormulaContext aContext( true, false );
135 aContext.setBaseAddress( rBaseAddress );
136 rParser.importFormula( aContext, rFormula );
137 return aContext.getTokens();
140 } // namespace
142 void OoxDataValidationsContext::onEndElement( const OUString& rChars )
144 if( mxValModel.get() ) switch( getCurrentElement() )
146 case XLS_TOKEN( formula1 ):
147 mxValModel->maTokens1 = lclImportDataValFormula(
148 getFormulaParser(), rChars, mxValModel->maRanges.getBaseAddress() );
149 // process string list of a list validation (convert to list of string tokens)
150 if( mxValModel->mnType == XML_list )
151 getFormulaParser().convertStringToStringList( mxValModel->maTokens1, ',', true );
152 break;
153 case XLS_TOKEN( formula2 ):
154 mxValModel->maTokens2 = lclImportDataValFormula(
155 getFormulaParser(), rChars, mxValModel->maRanges.getBaseAddress() );
156 break;
157 case XLS_TOKEN( dataValidation ):
158 setValidation( *mxValModel );
159 mxValModel.reset();
160 break;
165 ContextHandlerRef OoxDataValidationsContext::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm )
167 if( nRecId == OOBIN_ID_DATAVALIDATION )
168 importDataValidation( rStrm );
169 return 0;
172 void OoxDataValidationsContext::importDataValidation( const AttributeList& rAttribs )
174 mxValModel.reset( new ValidationModel );
175 getAddressConverter().convertToCellRangeList( mxValModel->maRanges, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), true );
176 mxValModel->maInputTitle = rAttribs.getXString( XML_promptTitle, OUString() );
177 mxValModel->maInputMessage = rAttribs.getXString( XML_prompt, OUString() );
178 mxValModel->maErrorTitle = rAttribs.getXString( XML_errorTitle, OUString() );
179 mxValModel->maErrorMessage = rAttribs.getXString( XML_error, OUString() );
180 mxValModel->mnType = rAttribs.getToken( XML_type, XML_none );
181 mxValModel->mnOperator = rAttribs.getToken( XML_operator, XML_between );
182 mxValModel->mnErrorStyle = rAttribs.getToken( XML_errorStyle, XML_stop );
183 mxValModel->mbShowInputMsg = rAttribs.getBool( XML_showInputMessage, false );
184 mxValModel->mbShowErrorMsg = rAttribs.getBool( XML_showErrorMessage, false );
185 /* The attribute showDropDown@dataValidation is in fact a "suppress
186 dropdown" flag, as it was in the BIFF format! ECMA specification
187 and attribute name are plain wrong! */
188 mxValModel->mbNoDropDown = rAttribs.getBool( XML_showDropDown, false );
189 mxValModel->mbAllowBlank = rAttribs.getBool( XML_allowBlank, false );
192 void OoxDataValidationsContext::importDataValidation( RecordInputStream& rStrm )
194 ValidationModel aModel;
196 sal_uInt32 nFlags;
197 BinRangeList aRanges;
198 rStrm >> nFlags >> aRanges >> aModel.maErrorTitle >> aModel.maErrorMessage >> aModel.maInputTitle >> aModel.maInputMessage;
200 // equal flags in BIFF and OOBIN
201 aModel.setBinType( extractValue< sal_uInt8 >( nFlags, 0, 4 ) );
202 aModel.setBinOperator( extractValue< sal_uInt8 >( nFlags, 20, 4 ) );
203 aModel.setBinErrorStyle( extractValue< sal_uInt8 >( nFlags, 4, 3 ) );
204 aModel.mbAllowBlank = getFlag( nFlags, BIFF_DATAVAL_ALLOWBLANK );
205 aModel.mbNoDropDown = getFlag( nFlags, BIFF_DATAVAL_NODROPDOWN );
206 aModel.mbShowInputMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWINPUT );
207 aModel.mbShowErrorMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWERROR );
209 // cell range list
210 getAddressConverter().convertToCellRangeList( aModel.maRanges, aRanges, getSheetIndex(), true );
212 // condition formula(s)
213 FormulaParser& rParser = getFormulaParser();
214 TokensFormulaContext aContext( true, false );
215 aContext.setBaseAddress( aModel.maRanges.getBaseAddress() );
216 rParser.importFormula( aContext, rStrm );
217 aModel.maTokens1 = aContext.getTokens();
218 rParser.importFormula( aContext, rStrm );
219 aModel.maTokens2 = aContext.getTokens();
220 // process string list of a list validation (convert to list of string tokens)
221 if( (aModel.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) )
222 rParser.convertStringToStringList( aModel.maTokens1, ',', true );
224 // set validation data
225 setValidation( aModel );
228 // ============================================================================
230 OoxWorksheetFragment::OoxWorksheetFragment( const WorkbookHelper& rHelper,
231 const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
232 OoxWorksheetFragmentBase( rHelper, rFragmentPath, xProgressBar, eSheetType, nSheet )
234 // import data tables related to this worksheet
235 RelationsRef xTableRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "table" ) );
236 for( Relations::const_iterator aIt = xTableRels->begin(), aEnd = xTableRels->end(); aIt != aEnd; ++aIt )
237 importOoxFragment( new OoxTableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) );
239 // import comments related to this worksheet
240 OUString aCommentsFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "comments" ) );
241 if( aCommentsFragmentPath.getLength() > 0 )
242 importOoxFragment( new OoxCommentsFragment( *this, aCommentsFragmentPath ) );
245 // oox.core.ContextHandler2Helper interface -----------------------------------
247 ContextHandlerRef OoxWorksheetFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
249 switch( getCurrentElement() )
251 case XML_ROOT_CONTEXT: switch( getSheetType() )
253 case SHEETTYPE_WORKSHEET: return (nElement == XLS_TOKEN( worksheet )) ? this : 0;
254 case SHEETTYPE_CHARTSHEET: return 0;
255 case SHEETTYPE_MACROSHEET: return (nElement == XM_TOKEN( macrosheet )) ? this : 0;
256 case SHEETTYPE_DIALOGSHEET: return (nElement == XM_TOKEN( dialogsheet )) ? this : 0;
257 case SHEETTYPE_MODULESHEET: return 0;
258 case SHEETTYPE_EMPTYSHEET: return 0;
260 break;
262 case XLS_TOKEN( worksheet ):
263 case XM_TOKEN( macrosheet ):
264 switch( nElement )
266 case XLS_TOKEN( sheetData ): return new OoxSheetDataContext( *this );
267 case XLS_TOKEN( autoFilter ): return new OoxAutoFilterContext( *this );
268 case XLS_TOKEN( conditionalFormatting ): return new OoxCondFormatContext( *this );
269 case XLS_TOKEN( dataValidations ): return new OoxDataValidationsContext( *this );
271 case XLS_TOKEN( sheetViews ):
272 case XLS_TOKEN( cols ):
273 case XLS_TOKEN( mergeCells ):
274 case XLS_TOKEN( hyperlinks ):
275 case XLS_TOKEN( rowBreaks ):
276 case XLS_TOKEN( colBreaks ):
277 case XLS_TOKEN( oleObjects ):
278 case XLS_TOKEN( controls ): return this;
280 case XLS_TOKEN( sheetPr ): getWorksheetSettings().importSheetPr( rAttribs ); return this;
281 case XLS_TOKEN( dimension ): importDimension( rAttribs ); break;
282 case XLS_TOKEN( sheetFormatPr ): importSheetFormatPr( rAttribs ); break;
283 case XLS_TOKEN( sheetProtection ): getWorksheetSettings().importSheetProtection( rAttribs ); break;
284 case XLS_TOKEN( phoneticPr ): getWorksheetSettings().importPhoneticPr( rAttribs ); break;
285 case XLS_TOKEN( printOptions ): getPageSettings().importPrintOptions( rAttribs ); break;
286 case XLS_TOKEN( pageMargins ): getPageSettings().importPageMargins( rAttribs ); break;
287 case XLS_TOKEN( pageSetup ): getPageSettings().importPageSetup( getRelations(), rAttribs ); break;
288 case XLS_TOKEN( headerFooter ): getPageSettings().importHeaderFooter( rAttribs ); return this;
289 case XLS_TOKEN( picture ): getPageSettings().importPicture( getRelations(), rAttribs ); break;
290 case XLS_TOKEN( drawing ): importDrawing( rAttribs ); break;
291 case XLS_TOKEN( legacyDrawing ): importLegacyDrawing( rAttribs ); break;
292 case XLS_TOKEN( scenarios ):
293 return new OoxScenariosContext( *this );
295 break;
297 case XLS_TOKEN( sheetPr ):
298 switch( nElement )
300 // TODO: Treat tab color as a sheet setting later.
301 // case XLS_TOKEN( tabColor ): getWorksheetSettings().importTabColor( rAttribs ); break;
302 case XLS_TOKEN( tabColor ): getSheetViewSettings().importTabColor( rAttribs ); break;
303 case XLS_TOKEN( outlinePr ): getWorksheetSettings().importOutlinePr( rAttribs ); break;
304 case XLS_TOKEN( pageSetUpPr ): importPageSetUpPr( rAttribs ); break;
306 break;
308 case XLS_TOKEN( sheetViews ):
309 switch( nElement )
311 case XLS_TOKEN( sheetView ): getSheetViewSettings().importSheetView( rAttribs ); return this;
313 break;
314 case XLS_TOKEN( sheetView ):
315 switch( nElement )
317 case XLS_TOKEN( pane ): getSheetViewSettings().importPane( rAttribs ); break;
318 case XLS_TOKEN( selection ): getSheetViewSettings().importSelection( rAttribs ); break;
320 break;
322 case XLS_TOKEN( cols ):
323 if( nElement == XLS_TOKEN( col ) ) importCol( rAttribs );
324 break;
325 case XLS_TOKEN( mergeCells ):
326 if( nElement == XLS_TOKEN( mergeCell ) ) importMergeCell( rAttribs );
327 break;
328 case XLS_TOKEN( hyperlinks ):
329 if( nElement == XLS_TOKEN( hyperlink ) ) importHyperlink( rAttribs );
330 break;
331 case XLS_TOKEN( rowBreaks ):
332 if( nElement == XLS_TOKEN( brk ) ) importBrk( rAttribs, true );
333 break;
334 case XLS_TOKEN( colBreaks ):
335 if( nElement == XLS_TOKEN( brk ) ) importBrk( rAttribs, false );
336 break;
338 case XLS_TOKEN( headerFooter ):
339 switch( nElement )
341 case XLS_TOKEN( firstHeader ):
342 case XLS_TOKEN( firstFooter ):
343 case XLS_TOKEN( oddHeader ):
344 case XLS_TOKEN( oddFooter ):
345 case XLS_TOKEN( evenHeader ):
346 case XLS_TOKEN( evenFooter ): return this; // collect h/f contents in onEndElement()
348 break;
350 case XLS_TOKEN( oleObjects ):
351 if( nElement == XLS_TOKEN( oleObject ) ) importOleObject( rAttribs );
352 break;
353 case XLS_TOKEN( controls ):
354 if( nElement == XLS_TOKEN( control ) ) importControl( rAttribs );
355 break;
357 return 0;
360 void OoxWorksheetFragment::onEndElement( const OUString& rChars )
362 switch( getCurrentElement() )
364 case XLS_TOKEN( firstHeader ):
365 case XLS_TOKEN( firstFooter ):
366 case XLS_TOKEN( oddHeader ):
367 case XLS_TOKEN( oddFooter ):
368 case XLS_TOKEN( evenHeader ):
369 case XLS_TOKEN( evenFooter ):
370 getPageSettings().importHeaderFooterCharacters( rChars, getCurrentElement() );
371 break;
375 ContextHandlerRef OoxWorksheetFragment::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm )
377 switch( getCurrentElement() )
379 case XML_ROOT_CONTEXT:
380 if( nRecId == OOBIN_ID_WORKSHEET ) return this;
381 break;
383 case OOBIN_ID_WORKSHEET:
384 switch( nRecId )
386 case OOBIN_ID_SHEETDATA: return new OoxSheetDataContext( *this );
387 case OOBIN_ID_CONDFORMATTING: return new OoxCondFormatContext( *this );
388 case OOBIN_ID_DATAVALIDATIONS: return new OoxDataValidationsContext( *this );
390 case OOBIN_ID_SHEETVIEWS:
391 case OOBIN_ID_COLS:
392 case OOBIN_ID_MERGECELLS:
393 case OOBIN_ID_ROWBREAKS:
394 case OOBIN_ID_COLBREAKS:
395 case OOBIN_ID_OLEOBJECTS:
396 case OOBIN_ID_CONTROLS: return this;
398 case OOBIN_ID_SHEETPR: getWorksheetSettings().importSheetPr( rStrm ); break;
399 case OOBIN_ID_DIMENSION: importDimension( rStrm ); break;
400 case OOBIN_ID_SHEETFORMATPR: importSheetFormatPr( rStrm ); break;
401 case OOBIN_ID_HYPERLINK: importHyperlink( rStrm ); break;
402 case OOBIN_ID_PAGEMARGINS: getPageSettings().importPageMargins( rStrm ); break;
403 case OOBIN_ID_PAGESETUP: getPageSettings().importPageSetup( getRelations(), rStrm ); break;
404 case OOBIN_ID_PRINTOPTIONS: getPageSettings().importPrintOptions( rStrm ); break;
405 case OOBIN_ID_HEADERFOOTER: getPageSettings().importHeaderFooter( rStrm ); break;
406 case OOBIN_ID_PICTURE: getPageSettings().importPicture( getRelations(), rStrm ); break;
407 case OOBIN_ID_SHEETPROTECTION: getWorksheetSettings().importSheetProtection( rStrm ); break;
408 case OOBIN_ID_PHONETICPR: getWorksheetSettings().importPhoneticPr( rStrm ); break;
409 case OOBIN_ID_DRAWING: importDrawing( rStrm ); break;
410 case OOBIN_ID_LEGACYDRAWING: importLegacyDrawing( rStrm ); break;
411 case OOBIN_ID_SCENARIOS:
412 return new OoxScenariosContext( *this );
414 break;
416 case OOBIN_ID_SHEETVIEWS:
417 switch( nRecId )
419 case OOBIN_ID_SHEETVIEW: getSheetViewSettings().importSheetView( rStrm ); return this;
421 break;
422 case OOBIN_ID_SHEETVIEW:
423 switch( nRecId )
425 case OOBIN_ID_PANE: getSheetViewSettings().importPane( rStrm ); break;
426 case OOBIN_ID_SELECTION: getSheetViewSettings().importSelection( rStrm ); break;
428 break;
430 case OOBIN_ID_COLS:
431 if( nRecId == OOBIN_ID_COL ) importCol( rStrm );
432 break;
433 case OOBIN_ID_MERGECELLS:
434 if( nRecId == OOBIN_ID_MERGECELL ) importMergeCell( rStrm );
435 break;
436 case OOBIN_ID_ROWBREAKS:
437 if( nRecId == OOBIN_ID_BRK ) importBrk( rStrm, true );
438 break;
439 case OOBIN_ID_COLBREAKS:
440 if( nRecId == OOBIN_ID_BRK ) importBrk( rStrm, false );
441 break;
442 case OOBIN_ID_OLEOBJECTS:
443 if( nRecId == OOBIN_ID_OLEOBJECT ) importOleObject( rStrm );
444 break;
445 case OOBIN_ID_CONTROLS:
446 if( nRecId == OOBIN_ID_CONTROL ) importControl( rStrm );
447 break;
449 return 0;
452 // oox.core.FragmentHandler2 interface ----------------------------------------
454 const RecordInfo* OoxWorksheetFragment::getRecordInfos() const
456 static const RecordInfo spRecInfos[] =
458 { OOBIN_ID_CFRULE, OOBIN_ID_CFRULE + 1 },
459 { OOBIN_ID_COLBREAKS, OOBIN_ID_COLBREAKS + 1 },
460 { OOBIN_ID_COLORSCALE, OOBIN_ID_COLORSCALE + 1 },
461 { OOBIN_ID_COLS, OOBIN_ID_COLS + 1 },
462 { OOBIN_ID_CONDFORMATTING, OOBIN_ID_CONDFORMATTING + 1 },
463 { OOBIN_ID_CONTROLS, OOBIN_ID_CONTROLS + 2 },
464 { OOBIN_ID_CUSTOMSHEETVIEW, OOBIN_ID_CUSTOMSHEETVIEW + 1 },
465 { OOBIN_ID_CUSTOMSHEETVIEWS, OOBIN_ID_CUSTOMSHEETVIEWS + 3 },
466 { OOBIN_ID_DATABAR, OOBIN_ID_DATABAR + 1 },
467 { OOBIN_ID_DATAVALIDATIONS, OOBIN_ID_DATAVALIDATIONS + 1 },
468 { OOBIN_ID_HEADERFOOTER, OOBIN_ID_HEADERFOOTER + 1 },
469 { OOBIN_ID_ICONSET, OOBIN_ID_ICONSET + 1 },
470 { OOBIN_ID_MERGECELLS, OOBIN_ID_MERGECELLS + 1 },
471 { OOBIN_ID_OLEOBJECTS, OOBIN_ID_OLEOBJECTS + 2 },
472 { OOBIN_ID_ROW, -1 },
473 { OOBIN_ID_ROWBREAKS, OOBIN_ID_ROWBREAKS + 1 },
474 { OOBIN_ID_SCENARIO, OOBIN_ID_SCENARIO + 1 },
475 { OOBIN_ID_SCENARIOS, OOBIN_ID_SCENARIOS + 1 },
476 { OOBIN_ID_SHEETDATA, OOBIN_ID_SHEETDATA + 1 },
477 { OOBIN_ID_SHEETVIEW, OOBIN_ID_SHEETVIEW + 1 },
478 { OOBIN_ID_SHEETVIEWS, OOBIN_ID_SHEETVIEWS + 1 },
479 { OOBIN_ID_TABLEPARTS, OOBIN_ID_TABLEPARTS + 2 },
480 { OOBIN_ID_WORKSHEET, OOBIN_ID_WORKSHEET + 1 },
481 { -1, -1 }
483 return spRecInfos;
486 void OoxWorksheetFragment::initializeImport()
488 // initial processing in base class WorksheetHelper
489 initializeWorksheetImport();
491 // import query table fragments related to this worksheet
492 RelationsRef xQueryRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "queryTable" ) );
493 for( Relations::const_iterator aIt = xQueryRels->begin(), aEnd = xQueryRels->end(); aIt != aEnd; ++aIt )
494 importOoxFragment( new OoxQueryTableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) );
496 // import pivot table fragments related to this worksheet
497 RelationsRef xPivotRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "pivotTable" ) );
498 for( Relations::const_iterator aIt = xPivotRels->begin(), aEnd = xPivotRels->end(); aIt != aEnd; ++aIt )
499 importOoxFragment( new OoxPivotTableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) );
502 void OoxWorksheetFragment::finalizeImport()
504 // final processing in base class WorksheetHelper
505 finalizeWorksheetImport();
508 // private --------------------------------------------------------------------
510 void OoxWorksheetFragment::importPageSetUpPr( const AttributeList& rAttribs )
512 // for whatever reason, this flag is still stored separated from the page settings
513 getPageSettings().setFitToPagesMode( rAttribs.getBool( XML_fitToPage, false ) );
516 void OoxWorksheetFragment::importDimension( const AttributeList& rAttribs )
518 CellRangeAddress aRange;
519 getAddressConverter().convertToCellRangeUnchecked( aRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex() );
520 setDimension( aRange );
523 void OoxWorksheetFragment::importSheetFormatPr( const AttributeList& rAttribs )
525 // default column settings
526 setBaseColumnWidth( rAttribs.getInteger( XML_baseColWidth, 8 ) );
527 setDefaultColumnWidth( rAttribs.getDouble( XML_defaultColWidth, 0.0 ) );
528 // default row settings
529 setDefaultRowSettings(
530 rAttribs.getDouble( XML_defaultRowHeight, 0.0 ),
531 rAttribs.getBool( XML_customHeight, false ),
532 rAttribs.getBool( XML_zeroHeight, false ),
533 rAttribs.getBool( XML_thickTop, false ),
534 rAttribs.getBool( XML_thickBottom, false ) );
537 void OoxWorksheetFragment::importCol( const AttributeList& rAttribs )
539 ColumnModel aModel;
540 aModel.mnFirstCol = rAttribs.getInteger( XML_min, -1 );
541 aModel.mnLastCol = rAttribs.getInteger( XML_max, -1 );
542 aModel.mfWidth = rAttribs.getDouble( XML_width, 0.0 );
543 aModel.mnXfId = rAttribs.getInteger( XML_style, -1 );
544 aModel.mnLevel = rAttribs.getInteger( XML_outlineLevel, 0 );
545 aModel.mbShowPhonetic = rAttribs.getBool( XML_phonetic, false );
546 aModel.mbHidden = rAttribs.getBool( XML_hidden, false );
547 aModel.mbCollapsed = rAttribs.getBool( XML_collapsed, false );
548 // set column properties in the current sheet
549 setColumnModel( aModel );
552 void OoxWorksheetFragment::importMergeCell( const AttributeList& rAttribs )
554 CellRangeAddress aRange;
555 if( getAddressConverter().convertToCellRange( aRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex(), true, true ) )
556 setMergedRange( aRange );
559 void OoxWorksheetFragment::importHyperlink( const AttributeList& rAttribs )
561 HyperlinkModel aModel;
562 if( getAddressConverter().convertToCellRange( aModel.maRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex(), true, true ) )
564 aModel.maTarget = getRelations().getExternalTargetFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
565 aModel.maLocation = rAttribs.getXString( XML_location, OUString() );
566 aModel.maDisplay = rAttribs.getXString( XML_display, OUString() );
567 aModel.maTooltip = rAttribs.getXString( XML_tooltip, OUString() );
568 setHyperlink( aModel );
572 void OoxWorksheetFragment::importBrk( const AttributeList& rAttribs, bool bRowBreak )
574 PageBreakModel aModel;
575 aModel.mnColRow = rAttribs.getInteger( XML_id, 0 );
576 aModel.mnMin = rAttribs.getInteger( XML_id, 0 );
577 aModel.mnMax = rAttribs.getInteger( XML_id, 0 );
578 aModel.mbManual = rAttribs.getBool( XML_man, false );
579 setPageBreak( aModel, bRowBreak );
582 void OoxWorksheetFragment::importDrawing( const AttributeList& rAttribs )
584 setDrawingPath( getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) ) );
587 void OoxWorksheetFragment::importLegacyDrawing( const AttributeList& rAttribs )
589 setVmlDrawingPath( getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) ) );
592 void OoxWorksheetFragment::importOleObject( const AttributeList& rAttribs )
594 ::oox::vml::OleObjectInfo aInfo;
595 aInfo.setShapeId( rAttribs.getInteger( XML_shapeId, 0 ) );
596 OSL_ENSURE( rAttribs.hasAttribute( XML_link ) != rAttribs.hasAttribute( R_TOKEN( id ) ),
597 "OoxWorksheetFragment::importOleObject - OLE object must be either linked or embedded" );
598 aInfo.mbLinked = rAttribs.hasAttribute( XML_link );
599 if( aInfo.mbLinked )
600 aInfo.maTargetLink = getFormulaParser().importOleTargetLink( rAttribs.getString( XML_link, OUString() ) );
601 else if( rAttribs.hasAttribute( R_TOKEN( id ) ) )
602 importEmbeddedOleData( aInfo.maEmbeddedData, rAttribs.getString( R_TOKEN( id ), OUString() ) );
603 aInfo.maProgId = rAttribs.getString( XML_progId, OUString() );
604 aInfo.mbShowAsIcon = rAttribs.getToken( XML_dvAspect, XML_DVASPECT_CONTENT ) == XML_DVASPECT_ICON;
605 aInfo.mbAutoUpdate = rAttribs.getToken( XML_oleUpdate, XML_OLEUPDATE_ONCALL ) == XML_OLEUPDATE_ALWAYS;
606 aInfo.mbAutoLoad = rAttribs.getBool( XML_autoLoad, false );
607 getVmlDrawing().registerOleObject( aInfo );
610 void OoxWorksheetFragment::importControl( const AttributeList& rAttribs )
612 ::oox::vml::ControlInfo aInfo;
613 aInfo.setShapeId( rAttribs.getInteger( XML_shapeId, 0 ) );
614 aInfo.maFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
615 aInfo.maName = rAttribs.getString( XML_name, OUString() );
616 getVmlDrawing().registerControl( aInfo );
619 void OoxWorksheetFragment::importDimension( RecordInputStream& rStrm )
621 BinRange aBinRange;
622 aBinRange.read( rStrm );
623 CellRangeAddress aRange;
624 getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() );
625 setDimension( aRange );
628 void OoxWorksheetFragment::importSheetFormatPr( RecordInputStream& rStrm )
630 sal_Int32 nDefaultWidth;
631 sal_uInt16 nBaseWidth, nDefaultHeight, nFlags;
632 rStrm >> nDefaultWidth >> nBaseWidth >> nDefaultHeight >> nFlags;
634 // base column with
635 setBaseColumnWidth( nBaseWidth );
636 // default width is stored as 1/256th of a character in OOBIN, convert to entire character
637 setDefaultColumnWidth( static_cast< double >( nDefaultWidth ) / 256.0 );
638 // row height is in twips in OOBIN, convert to points; equal flags in BIFF and OOBIN
639 setDefaultRowSettings(
640 nDefaultHeight / 20.0,
641 getFlag( nFlags, BIFF_DEFROW_CUSTOMHEIGHT ),
642 getFlag( nFlags, BIFF_DEFROW_HIDDEN ),
643 getFlag( nFlags, BIFF_DEFROW_THICKTOP ),
644 getFlag( nFlags, BIFF_DEFROW_THICKBOTTOM ) );
647 void OoxWorksheetFragment::importCol( RecordInputStream& rStrm )
649 ColumnModel aModel;
651 sal_Int32 nWidth;
652 sal_uInt16 nFlags;
653 rStrm >> aModel.mnFirstCol >> aModel.mnLastCol >> nWidth >> aModel.mnXfId >> nFlags;
655 // column indexes are 0-based in OOBIN, but ColumnModel expects 1-based
656 ++aModel.mnFirstCol;
657 ++aModel.mnLastCol;
658 // width is stored as 1/256th of a character in OOBIN, convert to entire character
659 aModel.mfWidth = static_cast< double >( nWidth ) / 256.0;
660 // equal flags in BIFF and OOBIN
661 aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 );
662 aModel.mbShowPhonetic = getFlag( nFlags, BIFF_COLINFO_SHOWPHONETIC );
663 aModel.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN );
664 aModel.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED );
665 // set column properties in the current sheet
666 setColumnModel( aModel );
669 void OoxWorksheetFragment::importMergeCell( RecordInputStream& rStrm )
671 BinRange aBinRange;
672 rStrm >> aBinRange;
673 CellRangeAddress aRange;
674 if( getAddressConverter().convertToCellRange( aRange, aBinRange, getSheetIndex(), true, true ) )
675 setMergedRange( aRange );
678 void OoxWorksheetFragment::importHyperlink( RecordInputStream& rStrm )
680 BinRange aBinRange;
681 rStrm >> aBinRange;
682 HyperlinkModel aModel;
683 if( getAddressConverter().convertToCellRange( aModel.maRange, aBinRange, getSheetIndex(), true, true ) )
685 aModel.maTarget = getRelations().getExternalTargetFromRelId( rStrm.readString() );
686 rStrm >> aModel.maLocation >> aModel.maTooltip >> aModel.maDisplay;
687 setHyperlink( aModel );
691 void OoxWorksheetFragment::importBrk( RecordInputStream& rStrm, bool bRowBreak )
693 PageBreakModel aModel;
694 sal_Int32 nManual;
695 rStrm >> aModel.mnColRow >> aModel.mnMin >> aModel.mnMax >> nManual;
696 aModel.mbManual = nManual != 0;
697 setPageBreak( aModel, bRowBreak );
700 void OoxWorksheetFragment::importDrawing( RecordInputStream& rStrm )
702 setDrawingPath( getFragmentPathFromRelId( rStrm.readString() ) );
705 void OoxWorksheetFragment::importLegacyDrawing( RecordInputStream& rStrm )
707 setVmlDrawingPath( getFragmentPathFromRelId( rStrm.readString() ) );
710 void OoxWorksheetFragment::importOleObject( RecordInputStream& rStrm )
712 ::oox::vml::OleObjectInfo aInfo;
713 sal_Int32 nAspect, nUpdateMode, nShapeId;
714 sal_uInt16 nFlags;
715 rStrm >> nAspect >> nUpdateMode >> nShapeId >> nFlags >> aInfo.maProgId;
716 aInfo.mbLinked = getFlag( nFlags, OOBIN_OLEOBJECT_LINKED );
717 if( aInfo.mbLinked )
718 aInfo.maTargetLink = getFormulaParser().importOleTargetLink( rStrm );
719 else
720 importEmbeddedOleData( aInfo.maEmbeddedData, rStrm.readString() );
721 aInfo.setShapeId( nShapeId );
722 aInfo.mbShowAsIcon = nAspect == OOBIN_OLEOBJECT_ICON;
723 aInfo.mbAutoUpdate = nUpdateMode == OOBIN_OLEOBJECT_ALWAYS;
724 aInfo.mbAutoLoad = getFlag( nFlags, OOBIN_OLEOBJECT_AUTOLOAD );
725 getVmlDrawing().registerOleObject( aInfo );
728 void OoxWorksheetFragment::importControl( RecordInputStream& rStrm )
730 ::oox::vml::ControlInfo aInfo;
731 aInfo.setShapeId( rStrm.readInt32() );
732 aInfo.maFragmentPath = getFragmentPathFromRelId( rStrm.readString() );
733 rStrm >> aInfo.maName;
734 getVmlDrawing().registerControl( aInfo );
737 void OoxWorksheetFragment::importEmbeddedOleData( StreamDataSequence& orEmbeddedData, const OUString& rRelId )
739 OUString aFragmentPath = getFragmentPathFromRelId( rRelId );
740 if( aFragmentPath.getLength() > 0 )
741 getBaseFilter().importBinaryData( orEmbeddedData, aFragmentPath );
744 // ============================================================================
746 BiffWorksheetFragment::BiffWorksheetFragment( const BiffWorkbookFragmentBase& rParent, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
747 BiffWorksheetFragmentBase( rParent, xProgressBar, eSheetType, nSheet )
751 BiffWorksheetFragment::~BiffWorksheetFragment()
755 bool BiffWorksheetFragment::importFragment()
757 // initial processing in base class WorksheetHelper
758 initializeWorksheetImport();
760 // create a SheetDataContext object that implements cell import
761 BiffSheetDataContext aSheetData( *this );
763 WorkbookSettings& rWorkbookSett = getWorkbookSettings();
764 WorksheetSettings& rWorksheetSett = getWorksheetSettings();
765 SheetViewSettings& rSheetViewSett = getSheetViewSettings();
766 CondFormatBuffer& rCondFormats = getCondFormats();
767 PageSettings& rPageSett = getPageSettings();
769 // process all record in this sheet fragment
770 while( mrStrm.startNextRecord() && (mrStrm.getRecId() != BIFF_ID_EOF) )
772 if( isBofRecord() )
774 // skip unknown embedded fragments (BOF/EOF blocks)
775 skipFragment();
777 else
779 // cache base stream position to detect if record is already processed
780 sal_Int64 nStrmPos = mrStrm.tellBase();
781 sal_uInt16 nRecId = mrStrm.getRecId();
783 switch( nRecId )
785 // records in all BIFF versions
786 case BIFF_ID_BOTTOMMARGIN: rPageSett.importBottomMargin( mrStrm ); break;
787 case BIFF_ID_CALCCOUNT: rWorkbookSett.importCalcCount( mrStrm ); break;
788 case BIFF_ID_CALCMODE: rWorkbookSett.importCalcMode( mrStrm ); break;
789 case BIFF_ID_DEFCOLWIDTH: importDefColWidth(); break;
790 case BIFF_ID_DELTA: rWorkbookSett.importDelta( mrStrm ); break;
791 case BIFF2_ID_DIMENSION: importDimension(); break;
792 case BIFF3_ID_DIMENSION: importDimension(); break;
793 case BIFF_ID_FOOTER: rPageSett.importFooter( mrStrm ); break;
794 case BIFF_ID_HEADER: rPageSett.importHeader( mrStrm ); break;
795 case BIFF_ID_HORPAGEBREAKS: importPageBreaks( true ); break;
796 case BIFF_ID_ITERATION: rWorkbookSett.importIteration( mrStrm ); break;
797 case BIFF_ID_LEFTMARGIN: rPageSett.importLeftMargin( mrStrm ); break;
798 case BIFF_ID_PANE: rSheetViewSett.importPane( mrStrm ); break;
799 case BIFF_ID_PASSWORD: rWorksheetSett.importPassword( mrStrm ); break;
800 case BIFF_ID_PRINTGRIDLINES: rPageSett.importPrintGridLines( mrStrm ); break;
801 case BIFF_ID_PRINTHEADERS: rPageSett.importPrintHeaders( mrStrm ); break;
802 case BIFF_ID_PROTECT: rWorksheetSett.importProtect( mrStrm ); break;
803 case BIFF_ID_REFMODE: rWorkbookSett.importRefMode( mrStrm ); break;
804 case BIFF_ID_RIGHTMARGIN: rPageSett.importRightMargin( mrStrm ); break;
805 case BIFF_ID_SELECTION: rSheetViewSett.importSelection( mrStrm ); break;
806 case BIFF_ID_TOPMARGIN: rPageSett.importTopMargin( mrStrm ); break;
807 case BIFF_ID_VERPAGEBREAKS: importPageBreaks( false ); break;
809 // BIFF specific records
810 default: switch( getBiff() )
812 case BIFF2: switch( nRecId )
814 case BIFF_ID_COLUMNDEFAULT: importColumnDefault(); break;
815 case BIFF_ID_COLWIDTH: importColWidth(); break;
816 case BIFF2_ID_DEFROWHEIGHT: importDefRowHeight(); break;
817 case BIFF2_ID_WINDOW2: rSheetViewSett.importWindow2( mrStrm ); break;
819 break;
821 case BIFF3: switch( nRecId )
823 case BIFF_ID_COLINFO: importColInfo(); break;
824 case BIFF_ID_DEFCOLWIDTH: importDefColWidth(); break;
825 case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break;
826 case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break;
827 case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break;
828 case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break;
829 case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( mrStrm ); break;
830 case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( mrStrm ); break;
831 case BIFF_ID_VCENTER: rPageSett.importVerCenter( mrStrm ); break;
832 case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( mrStrm ); break;
835 break;
837 case BIFF4: switch( nRecId )
839 case BIFF_ID_COLINFO: importColInfo(); break;
840 case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break;
841 case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break;
842 case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break;
843 case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break;
844 case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break;
845 case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( mrStrm ); break;
846 case BIFF_ID_STANDARDWIDTH: importStandardWidth(); break;
847 case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( mrStrm ); break;
848 case BIFF_ID_VCENTER: rPageSett.importVerCenter( mrStrm ); break;
849 case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( mrStrm ); break;
851 break;
853 case BIFF5: switch( nRecId )
855 case BIFF_ID_COLINFO: importColInfo(); break;
856 case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break;
857 case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break;
858 case BIFF_ID_MERGEDCELLS: importMergedCells(); break; // #i62300# also in BIFF5
859 case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break;
860 case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break;
861 case BIFF_ID_PTDEFINITION: importPTDefinition(); break;
862 case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break;
863 case BIFF_ID_SCENPROTECT: rWorksheetSett.importScenProtect( mrStrm ); break;
864 case BIFF_ID_SCL: rSheetViewSett.importScl( mrStrm ); break;
865 case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( mrStrm ); break;
866 case BIFF_ID_STANDARDWIDTH: importStandardWidth(); break;
867 case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( mrStrm ); break;
868 case BIFF_ID_VCENTER: rPageSett.importVerCenter( mrStrm ); break;
869 case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( mrStrm ); break;
871 break;
873 case BIFF8: switch( nRecId )
875 case BIFF_ID_CFHEADER: rCondFormats.importCfHeader( mrStrm ); break;
876 case BIFF_ID_COLINFO: importColInfo(); break;
877 case BIFF_ID_DATAVALIDATION: importDataValidation(); break;
878 case BIFF_ID_DATAVALIDATIONS: importDataValidations(); break;
879 case BIFF3_ID_DEFROWHEIGHT: importDefRowHeight(); break;
880 case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break;
881 case BIFF_ID_HYPERLINK: importHyperlink(); break;
882 case BIFF_ID_LABELRANGES: importLabelRanges(); break;
883 case BIFF_ID_MERGEDCELLS: importMergedCells(); break;
884 case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break;
885 case BIFF_ID_PAGESETUP: rPageSett.importPageSetup( mrStrm ); break;
886 case BIFF_ID_PHONETICPR: rWorksheetSett.importPhoneticPr( mrStrm ); break;
887 case BIFF_ID_PICTURE: rPageSett.importPicture( mrStrm ); break;
888 case BIFF_ID_PTDEFINITION: importPTDefinition(); break;
889 case BIFF_ID_SAVERECALC: rWorkbookSett.importSaveRecalc( mrStrm ); break;
890 case BIFF_ID_SCENARIOS: importScenarios(); break;
891 case BIFF_ID_SCENPROTECT: rWorksheetSett.importScenProtect( mrStrm ); break;
892 case BIFF_ID_SCL: rSheetViewSett.importScl( mrStrm ); break;
893 case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( mrStrm ); break;
894 case BIFF_ID_SHEETPROTECTION: rWorksheetSett.importSheetProtection( mrStrm ); break;
895 case BIFF_ID_STANDARDWIDTH: importStandardWidth(); break;
896 case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( mrStrm ); break;
897 case BIFF_ID_VCENTER: rPageSett.importVerCenter( mrStrm ); break;
898 case BIFF3_ID_WINDOW2: rSheetViewSett.importWindow2( mrStrm ); break;
900 break;
902 case BIFF_UNKNOWN: break;
906 // record not processed, try cell records
907 if( mrStrm.tellBase() == nStrmPos )
908 aSheetData.importRecord();
909 // record still not processed, try pivot table records
910 if( mxPTContext.get() && (mrStrm.tellBase() == nStrmPos) )
911 mxPTContext->importRecord();
915 // final processing in base class WorksheetHelper
916 finalizeWorksheetImport();
917 return mrStrm.getRecId() == BIFF_ID_EOF;
920 // private --------------------------------------------------------------------
922 void BiffWorksheetFragment::importColInfo()
924 sal_uInt16 nFirstCol, nLastCol, nWidth, nXfId, nFlags;
925 mrStrm >> nFirstCol >> nLastCol >> nWidth >> nXfId >> nFlags;
927 ColumnModel aModel;
928 // column indexes are 0-based in BIFF, but ColumnModel expects 1-based
929 aModel.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1;
930 aModel.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1;
931 // width is stored as 1/256th of a character in BIFF, convert to entire character
932 aModel.mfWidth = static_cast< double >( nWidth ) / 256.0;
933 aModel.mnXfId = nXfId;
934 aModel.mnLevel = extractValue< sal_Int32 >( nFlags, 8, 3 );
935 aModel.mbShowPhonetic = getFlag( nFlags, BIFF_COLINFO_SHOWPHONETIC );
936 aModel.mbHidden = getFlag( nFlags, BIFF_COLINFO_HIDDEN );
937 aModel.mbCollapsed = getFlag( nFlags, BIFF_COLINFO_COLLAPSED );
938 // set column properties in the current sheet
939 setColumnModel( aModel );
942 void BiffWorksheetFragment::importColumnDefault()
944 sal_uInt16 nFirstCol, nLastCol, nXfId;
945 mrStrm >> nFirstCol >> nLastCol >> nXfId;
946 setDefaultColumnFormat( nFirstCol, nLastCol, nXfId );
949 void BiffWorksheetFragment::importColWidth()
951 sal_uInt8 nFirstCol, nLastCol;
952 sal_uInt16 nWidth;
953 mrStrm >> nFirstCol >> nLastCol >> nWidth;
955 ColumnModel aModel;
956 // column indexes are 0-based in BIFF, but ColumnModel expects 1-based
957 aModel.mnFirstCol = static_cast< sal_Int32 >( nFirstCol ) + 1;
958 aModel.mnLastCol = static_cast< sal_Int32 >( nLastCol ) + 1;
959 // width is stored as 1/256th of a character in BIFF, convert to entire character
960 aModel.mfWidth = static_cast< double >( nWidth ) / 256.0;
961 // set column properties in the current sheet
962 setColumnModel( aModel );
965 void BiffWorksheetFragment::importDefColWidth()
967 /* Stored as entire number of characters without padding pixels, which
968 will be added in setBaseColumnWidth(). Call has no effect, if a
969 width has already been set from the STANDARDWIDTH record. */
970 setBaseColumnWidth( mrStrm.readuInt16() );
973 void BiffWorksheetFragment::importDefRowHeight()
975 sal_uInt16 nFlags = BIFF_DEFROW_CUSTOMHEIGHT, nHeight;
976 if( getBiff() != BIFF2 )
977 mrStrm >> nFlags;
978 mrStrm >> nHeight;
979 if( getBiff() == BIFF2 )
980 nHeight &= BIFF2_DEFROW_MASK;
981 // row height is in twips in BIFF, convert to points
982 setDefaultRowSettings(
983 nHeight / 20.0,
984 getFlag( nFlags, BIFF_DEFROW_CUSTOMHEIGHT ),
985 getFlag( nFlags, BIFF_DEFROW_HIDDEN ),
986 getFlag( nFlags, BIFF_DEFROW_THICKTOP ),
987 getFlag( nFlags, BIFF_DEFROW_THICKBOTTOM ) );
990 void BiffWorksheetFragment::importDataValidations()
992 sal_Int32 nObjId;
993 mrStrm.skip( 10 );
994 mrStrm >> nObjId;
995 //! TODO: invalidate object id in drawing object manager
998 namespace {
1000 OUString lclReadDataValMessage( BiffInputStream& rStrm )
1002 // empty strings are single NUL characters (string length is 1)
1003 OUString aMessage = rStrm.readUniString( true );
1004 if( (aMessage.getLength() == 1) && (aMessage[ 0 ] == 0) )
1005 aMessage = OUString();
1006 return aMessage;
1009 ApiTokenSequence lclReadDataValFormula( BiffInputStream& rStrm, FormulaParser& rParser )
1011 sal_uInt16 nFmlaSize = rStrm.readuInt16();
1012 rStrm.skip( 2 );
1013 // enable NUL characters, string list is single tStr token with NUL separators
1014 TokensFormulaContext aContext( true, false, true );
1015 rParser.importFormula( aContext, rStrm, &nFmlaSize );
1016 return aContext.getTokens();
1019 } // namespace
1021 void BiffWorksheetFragment::importDataValidation()
1023 ValidationModel aModel;
1025 // flags
1026 sal_uInt32 nFlags;
1027 mrStrm >> nFlags;
1028 aModel.setBinType( extractValue< sal_uInt8 >( nFlags, 0, 4 ) );
1029 aModel.setBinOperator( extractValue< sal_uInt8 >( nFlags, 20, 4 ) );
1030 aModel.setBinErrorStyle( extractValue< sal_uInt8 >( nFlags, 4, 3 ) );
1031 aModel.mbAllowBlank = getFlag( nFlags, BIFF_DATAVAL_ALLOWBLANK );
1032 aModel.mbNoDropDown = getFlag( nFlags, BIFF_DATAVAL_NODROPDOWN );
1033 aModel.mbShowInputMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWINPUT );
1034 aModel.mbShowErrorMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWERROR );
1036 // message strings
1037 aModel.maInputTitle = lclReadDataValMessage( mrStrm );
1038 aModel.maErrorTitle = lclReadDataValMessage( mrStrm );
1039 aModel.maInputMessage = lclReadDataValMessage( mrStrm );
1040 aModel.maErrorMessage = lclReadDataValMessage( mrStrm );
1042 // condition formula(s)
1043 FormulaParser& rParser = getFormulaParser();
1044 aModel.maTokens1 = lclReadDataValFormula( mrStrm, rParser );
1045 aModel.maTokens2 = lclReadDataValFormula( mrStrm, rParser );
1046 // process string list of a list validation (convert to list of string tokens)
1047 if( (aModel.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) )
1048 rParser.convertStringToStringList( aModel.maTokens1, '\0', true );
1050 // cell range list
1051 BinRangeList aRanges;
1052 mrStrm >> aRanges;
1053 getAddressConverter().convertToCellRangeList( aModel.maRanges, aRanges, getSheetIndex(), true );
1055 // set validation data
1056 setValidation( aModel );
1059 void BiffWorksheetFragment::importDimension()
1061 BinRange aBinRange;
1062 aBinRange.read( mrStrm, true, (mrStrm.getRecId() == BIFF3_ID_DIMENSION) && (getBiff() == BIFF8) );
1063 // first unused row/column index in BIFF, not last used
1064 if( aBinRange.maFirst.mnCol < aBinRange.maLast.mnCol ) --aBinRange.maLast.mnCol;
1065 if( aBinRange.maFirst.mnRow < aBinRange.maLast.mnRow ) --aBinRange.maLast.mnRow;
1066 // set dimension
1067 CellRangeAddress aRange;
1068 getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() );
1069 setDimension( aRange );
1072 void BiffWorksheetFragment::importHyperlink()
1074 HyperlinkModel aModel;
1076 // read cell range for the hyperlink
1077 BinRange aBiffRange;
1078 mrStrm >> aBiffRange;
1079 // #i80006# Excel silently ignores invalid hi-byte of column index (TODO: everywhere?)
1080 aBiffRange.maFirst.mnCol &= 0xFF;
1081 aBiffRange.maLast.mnCol &= 0xFF;
1082 if( !getAddressConverter().convertToCellRange( aModel.maRange, aBiffRange, getSheetIndex(), true, true ) )
1083 return;
1085 // try to read the StdHlink data
1086 if( !::oox::ole::OleHelper::importStdHlink( aModel, mrStrm, getTextEncoding(), true ) )
1087 return;
1089 // try to read the optional following SCREENTIP record
1090 if( (mrStrm.getNextRecId() == BIFF_ID_SCREENTIP) && mrStrm.startNextRecord() )
1092 mrStrm.skip( 2 ); // repeated record id
1093 // the cell range, again
1094 mrStrm >> aBiffRange;
1095 CellRangeAddress aRange;
1096 if( getAddressConverter().convertToCellRange( aRange, aBiffRange, getSheetIndex(), true, true ) &&
1097 (aRange.StartColumn == aModel.maRange.StartColumn) &&
1098 (aRange.StartRow == aModel.maRange.StartRow) &&
1099 (aRange.EndColumn == aModel.maRange.EndColumn) &&
1100 (aRange.EndRow == aModel.maRange.EndRow) )
1102 /* This time, we have no string length, no flag field, and a
1103 null-terminated 16-bit character array. */
1104 aModel.maTooltip = mrStrm.readNulUnicodeArray();
1108 // store the hyperlink settings
1109 setHyperlink( aModel );
1112 void BiffWorksheetFragment::importLabelRanges()
1114 BinRangeList aBiffRowRanges, aBiffColRanges;
1115 mrStrm >> aBiffRowRanges >> aBiffColRanges;
1116 ApiCellRangeList aColRanges, aRowRanges;
1117 getAddressConverter().convertToCellRangeList( aColRanges, aBiffColRanges, getSheetIndex(), true );
1118 getAddressConverter().convertToCellRangeList( aRowRanges, aBiffRowRanges, getSheetIndex(), true );
1119 setLabelRanges( aColRanges, aRowRanges );
1122 void BiffWorksheetFragment::importMergedCells()
1124 BinRangeList aBiffRanges;
1125 mrStrm >> aBiffRanges;
1126 ApiCellRangeList aRanges;
1127 getAddressConverter().convertToCellRangeList( aRanges, aBiffRanges, getSheetIndex(), true );
1128 for( ApiCellRangeList::const_iterator aIt = aRanges.begin(), aEnd = aRanges.end(); aIt != aEnd; ++aIt )
1129 setMergedRange( *aIt );
1132 void BiffWorksheetFragment::importPageBreaks( bool bRowBreak )
1134 PageBreakModel aModel;
1135 aModel.mbManual = true; // only manual breaks stored in BIFF
1136 bool bBiff8 = getBiff() == BIFF8; // skip start/end columns or rows in BIFF8
1138 sal_uInt16 nCount;
1139 mrStrm >> nCount;
1140 for( sal_uInt16 nIndex = 0; !mrStrm.isEof() && (nIndex < nCount); ++nIndex )
1142 aModel.mnColRow = mrStrm.readuInt16();
1143 setPageBreak( aModel, bRowBreak );
1144 if( bBiff8 )
1145 mrStrm.skip( 4 );
1149 void BiffWorksheetFragment::importPTDefinition()
1151 mxPTContext.reset( new BiffPivotTableContext( *this, getPivotTables().createPivotTable() ) );
1152 mxPTContext->importRecord();
1155 void BiffWorksheetFragment::importScenarios()
1157 getScenarios().createSheetScenarios( getSheetIndex() ).importScenarios( mrStrm );
1160 void BiffWorksheetFragment::importStandardWidth()
1162 sal_uInt16 nWidth;
1163 mrStrm >> nWidth;
1164 // width is stored as 1/256th of a character in BIFF, convert to entire character
1165 double fWidth = static_cast< double >( nWidth ) / 256.0;
1166 // set as default width, will override the width from DEFCOLWIDTH record
1167 setDefaultColumnWidth( fWidth );
1170 // ============================================================================
1172 } // namespace xls
1173 } // namespace oox