dr78: #i71453# BIFF2: use formatting information from cell records if XF records are missing

This commit is contained in:
Daniel Rentz [dr] 2010-12-17 12:09:17 +01:00
parent 70ec19ae3c
commit a25f471568
5 changed files with 72 additions and 10 deletions

View file

@ -163,6 +163,7 @@ private:
sal_uInt32 mnFormulaIgnoreSize; /// Number of bytes to be ignored in FORMULA record.
sal_uInt32 mnArrayIgnoreSize; /// Number of bytes to be ignored in ARRAY record.
sal_uInt16 mnBiff2XfId; /// Current XF identifier from IXFE record.
OptValue< bool > mobBiff2HasXfs; /// Select XF formatting or direct formatting in BIFF2.
};
// ============================================================================

View file

@ -787,6 +787,11 @@ public:
/** Writes all formatting attributes to the passed property set. */
void writeToPropertySet( PropertySet& rPropSet ) const;
/** Converts formatting information from BIFF2 cell record data directly. */
static void writeBiff2CellFormatToPropertySet(
const WorkbookHelper& rHelper, PropertySet& rPropSet,
sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 );
private:
/** Sets 'attribute used' flags from the passed BIFF bit field. */
void setBiffUsedFlags( sal_uInt8 nUsedFlags );

View file

@ -2193,7 +2193,7 @@ combilist=XF-FILLCOLOR-BIFF8
0x3F80=uint8,dec,bg-color-idx,COLORS
end
# BIFF2 XF index field -------------------------------------------------------
# BIFF2 cell records ----------------------------------------------------------
constlist=XFINDEX-BIFF2
default=

View file

@ -106,8 +106,9 @@ const sal_uInt32 BIFF_ROW_THICKTOP = 0x10000000;
const sal_uInt32 BIFF_ROW_THICKBOTTOM = 0x20000000;
const sal_uInt32 BIFF_ROW_SHOWPHONETIC = 0x40000000;
const sal_Int32 BIFF2_XF_EXTENDED_IDS = 63;
const sal_uInt8 BIFF2_XF_MASK = 0x3F;
const sal_uInt8 BIFF2_CELL_LOCKED = 0x40;
const sal_uInt8 BIFF2_CELL_HIDDEN = 0x80;
const sal_Int32 BIFF2_CELL_USEIXFE = 63;
// ----------------------------------------------------------------------------
@ -600,7 +601,6 @@ BiffSheetDataContext::BiffSheetDataContext( const BiffWorksheetFragmentBase& rPa
BiffWorksheetContextBase( rParent ),
mnBiff2XfId( 0 )
{
mnArrayIgnoreSize = (getBiff() == BIFF2) ? 1 : ((getBiff() <= BIFF4) ? 2 : 6);
switch( getBiff() )
{
case BIFF2:
@ -718,12 +718,33 @@ void BiffSheetDataContext::importXfId( bool bBiff2 )
{
if( bBiff2 )
{
sal_uInt8 nBiff2XfId;
mrStrm >> nBiff2XfId;
mrStrm.skip( 2 );
maCurrCell.mnXfId = nBiff2XfId & BIFF2_XF_MASK;
if( maCurrCell.mnXfId == BIFF2_XF_EXTENDED_IDS )
maCurrCell.mnXfId = mnBiff2XfId;
/* #i71453# On first call, check if the file contains XF records (by
trying to access the first XF with index 0). If there are no XFs,
the explicit formatting information contained in each cell record
will be used instead. */
if( !mobBiff2HasXfs )
mobBiff2HasXfs = getStyles().getCellXf( 0 ).get() != 0;
// read formatting information (includes the XF identifier)
sal_uInt8 nFlags1, nFlags2, nFlags3;
mrStrm >> nFlags1 >> nFlags2 >> nFlags3;
/* If the file contains XFs, extract and set the XF identifier,
otherwise get the explicit formatting. */
if( mobBiff2HasXfs.get() )
{
maCurrCell.mnXfId = extractValue< sal_Int32 >( nFlags1, 0, 6 );
/* If the identifier is equal to 63, then the real identifier is
contained in the preceding IXFE record (stored in mnBiff2XfId). */
if( maCurrCell.mnXfId == BIFF2_CELL_USEIXFE )
maCurrCell.mnXfId = mnBiff2XfId;
}
else
{
/* Let the Xf class do the API conversion. Keeping the member
maCurrCell.mnXfId untouched will prevent to trigger the usual
XF formatting conversion later on. */
PropertySet aPropSet( maCurrCell.mxCell );
Xf::writeBiff2CellFormatToPropertySet( *this, aPropSet, nFlags1, nFlags2, nFlags3 );
}
}
else
{

View file

@ -2477,6 +2477,41 @@ void Xf::writeToPropertySet( PropertySet& rPropSet ) const
rPropSet.setProperties( aPropMap );
}
/*static*/ void Xf::writeBiff2CellFormatToPropertySet( const WorkbookHelper& rHelper,
PropertySet& rPropSet, sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 )
{
/* Create an XF object and let it do the work. We will have access to its
private members here. Also, create temporary border and fill objects,
this prevents polluting the border and fill buffers with new temporary
objects per imported cell. */
Xf aXf( rHelper );
Border aBorder( rHelper, false );
Fill aFill( rHelper, false );
// no used flags available in BIFF2 (always true)
aXf.setAllUsedFlags( true );
// set the attributes
aXf.maModel.mnFontId = extractValue< sal_Int32 >( nFlags2, 6, 2 );
aXf.maModel.mnNumFmtId = extractValue< sal_Int32 >( nFlags2, 0, 6 );
aXf.maAlignment.setBiff2Data( nFlags3 );
aXf.maProtection.setBiff2Data( nFlags1 );
aBorder.setBiff2Data( nFlags3 );
aFill.setBiff2Data( nFlags3 );
// finalize the objects (convert model to API attributes)
aXf.finalizeImport();
aBorder.finalizeImport();
aFill.finalizeImport();
// write the properties to the property set
PropertyMap aPropMap;
aXf.writeToPropertyMap( aPropMap );
aBorder.writeToPropertyMap( aPropMap );
aFill.writeToPropertyMap( aPropMap );
rPropSet.setProperties( aPropMap );
}
void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags )
{
/* Notes about finding the used flags: