summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-12-17 12:09:17 +0100
committerDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-12-17 12:09:17 +0100
commita25f4715687671a2cdeb1c7e07df02e21bd46758 (patch)
tree54f618019256d07bed67be8565f153b081fe6a6a
parent70ec19ae3cbf881388c0011e0c4aa132bece311c (diff)
dr78: #i71453# BIFF2: use formatting information from cell records if XF records are missing
-rw-r--r--oox/inc/oox/xls/sheetdatacontext.hxx1
-rw-r--r--oox/inc/oox/xls/stylesbuffer.hxx5
-rw-r--r--oox/source/dump/biffdumper.ini2
-rw-r--r--oox/source/xls/sheetdatacontext.cxx39
-rw-r--r--oox/source/xls/stylesbuffer.cxx35
5 files changed, 72 insertions, 10 deletions
diff --git a/oox/inc/oox/xls/sheetdatacontext.hxx b/oox/inc/oox/xls/sheetdatacontext.hxx
index a77f4b285fa4..fec8b7db89cb 100644
--- a/oox/inc/oox/xls/sheetdatacontext.hxx
+++ b/oox/inc/oox/xls/sheetdatacontext.hxx
@@ -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.
};
// ============================================================================
diff --git a/oox/inc/oox/xls/stylesbuffer.hxx b/oox/inc/oox/xls/stylesbuffer.hxx
index 4fa9c964108e..b597546f8484 100644
--- a/oox/inc/oox/xls/stylesbuffer.hxx
+++ b/oox/inc/oox/xls/stylesbuffer.hxx
@@ -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 );
diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini
index 8e1626f82659..18e8cd87e551 100644
--- a/oox/source/dump/biffdumper.ini
+++ b/oox/source/dump/biffdumper.ini
@@ -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=
diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx
index 05e4c5bfe767..8ce601b0aa8c 100644
--- a/oox/source/xls/sheetdatacontext.cxx
+++ b/oox/source/xls/sheetdatacontext.cxx
@@ -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
{
diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx
index 5a149961c0e2..b95ca8984ded 100644
--- a/oox/source/xls/stylesbuffer.cxx
+++ b/oox/source/xls/stylesbuffer.cxx
@@ -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: