summaryrefslogtreecommitdiff
path: root/oox/source/xls
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2010-04-12 17:59:48 +0200
committerJens-Heiner Rechtien <hr@openoffice.org>2010-04-12 17:59:48 +0200
commitb8e6f863db2f8a5ef34409e5080491fe7b198045 (patch)
tree4c19509816c3dc464af752e80b1d3ef507b03676 /oox/source/xls
parentb831dc7de1114c1568b6f14f89180fafc7cf11df (diff)
parent6b37bdc42e3aa173df608e8d85b3000d0e7e7fe3 (diff)
CWS-TOOLING: integrate CWS dr74
Diffstat (limited to 'oox/source/xls')
-rw-r--r--oox/source/xls/biffhelper.cxx58
-rw-r--r--oox/source/xls/formulabase.cxx123
-rw-r--r--oox/source/xls/stylesbuffer.cxx224
3 files changed, 281 insertions, 124 deletions
diff --git a/oox/source/xls/biffhelper.cxx b/oox/source/xls/biffhelper.cxx
index f69cac731ee7..8ecea303183e 100644
--- a/oox/source/xls/biffhelper.cxx
+++ b/oox/source/xls/biffhelper.cxx
@@ -119,19 +119,27 @@ struct CodePageEntry_TEPred
// ----------------------------------------------------------------------------
-bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue )
+union DecodedDouble
+{
+ double mfValue;
+ sal_math_Double maStruct;
+
+ inline explicit DecodedDouble() {}
+ inline explicit DecodedDouble( double fValue ) : mfValue( fValue ) {}
+};
+
+bool lclCalcRkFromDouble( sal_Int32& ornRkValue, const DecodedDouble& rDecDbl )
{
// double
- const sal_math_Double* pValue = reinterpret_cast< const sal_math_Double* >( &fValue );
- if( (pValue->w32_parts.lsw == 0) && ((pValue->w32_parts.msw & 0x3) == 0) )
+ if( (rDecDbl.maStruct.w32_parts.lsw == 0) && ((rDecDbl.maStruct.w32_parts.msw & 0x3) == 0) )
{
- ornRkValue = static_cast< sal_Int32 >( pValue->w32_parts.msw );
+ ornRkValue = static_cast< sal_Int32 >( rDecDbl.maStruct.w32_parts.msw );
return true;
}
// integer
double fInt = 0.0;
- double fFrac = modf( fValue, &fInt );
+ double fFrac = modf( rDecDbl.mfValue, &fInt );
if( (fFrac == 0.0) && (-536870912.0 <= fInt) && (fInt <= 536870911.0) ) // 2^29
{
ornRkValue = static_cast< sal_Int32 >( fInt );
@@ -143,6 +151,22 @@ bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue )
return false;
}
+bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue )
+{
+ DecodedDouble aDecDbl( fValue );
+ if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) )
+ return true;
+
+ aDecDbl.mfValue *= 100.0;
+ if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) )
+ {
+ ornRkValue |= BIFF_RK_100FLAG;
+ return true;
+ }
+
+ return false;
+}
+
// ----------------------------------------------------------------------------
void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, sal_Int32 nBytes, BiffType eBiff )
@@ -229,23 +253,22 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm,
/*static*/ double BiffHelper::calcDoubleFromRk( sal_Int32 nRkValue )
{
- double fValue = 0.0;
+ DecodedDouble aDecDbl( 0.0 );
if( getFlag( nRkValue, BIFF_RK_INTFLAG ) )
{
sal_Int32 nTemp = nRkValue >> 2;
setFlag< sal_Int32 >( nTemp, 0xE0000000, nRkValue < 0 );
- fValue = nTemp;
+ aDecDbl.mfValue = nTemp;
}
else
{
- sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &fValue );
- pDouble->w32_parts.msw = static_cast< sal_uInt32 >( nRkValue & BIFF_RK_VALUEMASK );
+ aDecDbl.maStruct.w32_parts.msw = static_cast< sal_uInt32 >( nRkValue & BIFF_RK_VALUEMASK );
}
if( getFlag( nRkValue, BIFF_RK_100FLAG ) )
- fValue /= 100.0;
+ aDecDbl.mfValue /= 100.0;
- return fValue;
+ return aDecDbl.mfValue;
}
/*static*/ bool BiffHelper::calcRkFromDouble( sal_Int32& ornRkValue, double fValue )
@@ -276,10 +299,10 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm,
case BIFF_ERR_NA: nApiError = 0x7FFF; break;
default: OSL_ENSURE( false, "BiffHelper::calcDoubleFromError - unknown error code" );
}
- double fValue;
- ::rtl::math::setNan( &fValue );
- reinterpret_cast< sal_math_Double* >( &fValue )->nan_parts.fraction_lo = nApiError;
- return fValue;
+ DecodedDouble aDecDbl;
+ ::rtl::math::setNan( &aDecDbl.mfValue );
+ aDecDbl.maStruct.nan_parts.fraction_lo = nApiError;
+ return aDecDbl.mfValue;
}
/*static*/ rtl_TextEncoding BiffHelper::calcTextEncodingFromCodePage( sal_uInt16 nCodePage )
@@ -309,15 +332,14 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm,
sal_uInt16 nFormat, nEnv;
sal_Int32 nBytes;
rStrm >> nFormat >> nEnv >> nBytes;
- OSL_ENSURE( (nFormat == BIFF_IMGDATA_WMF) || (nFormat == BIFF_IMGDATA_DIB) || (nFormat == BIFF_IMGDATA_NATIVE), "BiffHelper::importImgData - unknown format" );
OSL_ENSURE( nBytes > 0, "BiffHelper::importImgData - invalid data size" );
if( (0 < nBytes) && (nBytes <= rStrm.getRemaining()) )
{
switch( nFormat )
{
- case BIFF_IMGDATA_WMF: /* TODO */ break;
+// case BIFF_IMGDATA_WMF: /* TODO */ break;
case BIFF_IMGDATA_DIB: lclImportImgDataDib( orDataSeq, rStrm, nBytes, eBiff ); break;
- case BIFF_IMGDATA_NATIVE: /* TODO */ break;
+// case BIFF_IMGDATA_NATIVE: /* TODO */ break;
default: OSL_ENSURE( false, "BiffHelper::importImgData - unknown image format" );
}
}
diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx
index b9b9c3d57dcc..b2e5ba0ee931 100644
--- a/oox/source/xls/formulabase.cxx
+++ b/oox/source/xls/formulabase.cxx
@@ -229,12 +229,13 @@ const size_t FUNCINFO_PARAMINFOCOUNT = 5; /// Number of parameter
const sal_uInt16 FUNCFLAG_VOLATILE = 0x0001; /// Result is volatile (e.g. NOW() function).
const sal_uInt16 FUNCFLAG_IMPORTONLY = 0x0002; /// Only used in import filter.
const sal_uInt16 FUNCFLAG_EXPORTONLY = 0x0004; /// Only used in export filter.
-const sal_uInt16 FUNCFLAG_MACROCALL = 0x0008; /// Function is simulated by macro call in Excel.
-const sal_uInt16 FUNCFLAG_EXTERNAL = 0x0010; /// Function is external in Calc.
-const sal_uInt16 FUNCFLAG_MACROFUNC = 0x0020; /// Function is a macro-sheet function.
-const sal_uInt16 FUNCFLAG_MACROCMD = 0x0040; /// Function is a macro-sheet command.
-const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0080; /// Function is always represented by a tFuncVar token.
-const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0100; /// Optional parameters are expected to appear in pairs.
+const sal_uInt16 FUNCFLAG_MACROCALL = 0x0008; /// Function is stored as macro call in Excel (_xlfn. prefix). OOXML name MUST exist.
+const sal_uInt16 FUNCFLAG_MACROCALLODF = 0x0010; /// ODF-only function stored as macro call in Excel (_xlfnodf. prefix). ODF name MUST exist.
+const sal_uInt16 FUNCFLAG_EXTERNAL = 0x0020; /// Function is external in Calc.
+const sal_uInt16 FUNCFLAG_MACROFUNC = 0x0040; /// Function is a macro-sheet function.
+const sal_uInt16 FUNCFLAG_MACROCMD = 0x0080; /// Function is a macro-sheet command.
+const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0100; /// Function is always represented by a tFuncVar token.
+const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0200; /// Optional parameters are expected to appear in pairs.
const sal_uInt16 FUNCFLAG_FUNCLIBMASK = 0xF000; /// Mask for function library bits.
const sal_uInt16 FUNCFLAG_EUROTOOL = 0x1000; /// Function is part of the EuroTool add-in.
@@ -346,7 +347,6 @@ static const FunctionData saFuncTableBiff2[] =
{ "TREND", "TREND", 50, 50, 1, 3, A, { RA, RA, RA, C }, 0 },
{ "LOGEST", "LOGEST", 51, 51, 1, 2, A, { RA, RA, C, C }, 0 },
{ "GROWTH", "GROWTH", 52, 52, 1, 3, A, { RA, RA, RA, C }, 0 },
- { 0, "RETURN", 55, 55, 0, 1, R, { RO }, FUNCFLAG_MACROFUNC },
{ "PV", "PV", 56, 56, 3, 5, V, { VR }, 0 },
{ "FV", "FV", 57, 57, 3, 5, V, { VR }, 0 },
{ "NPER", "NPER", 58, 58, 3, 5, V, { VR }, 0 },
@@ -370,11 +370,9 @@ static const FunctionData saFuncTableBiff2[] =
{ "ROWS", "ROWS", 76, 76, 1, 1, V, { RO }, 0 },
{ "COLUMNS", "COLUMNS", 77, 77, 1, 1, V, { RO }, 0 },
{ "OFFSET", "OFFSET", 78, 78, 3, 5, R, { RO, VR }, FUNCFLAG_VOLATILE },
- { 0, "ABSREF", 79, 79, 2, 2, R, { VR, RO }, FUNCFLAG_MACROFUNC },
{ "SEARCH", "SEARCH", 82, 82, 2, 3, V, { VR }, 0 },
{ "TRANSPOSE", "TRANSPOSE", 83, 83, 1, 1, A, { VO }, 0 },
{ "TYPE", "TYPE", 86, 86, 1, 1, V, { VX }, 0 },
- { 0, "ACTIVE.CELL", 94, 94, 0, 0, R, {}, FUNCFLAG_MACROFUNC },
{ "ATAN2", "ATAN2", 97, 97, 2, 2, V, { VR }, 0 },
{ "ASIN", "ASIN", 98, 98, 1, 1, V, { VR }, 0 },
{ "ACOS", "ACOS", 99, 99, 1, 1, V, { VR }, 0 },
@@ -408,9 +406,6 @@ static const FunctionData saFuncTableBiff2[] =
{ "SYD", "SYD", 143, 143, 4, 4, V, { VR }, 0 },
{ "DDB", "DDB", 144, 144, 4, 5, V, { VR }, 0 },
{ "INDIRECT", "INDIRECT", 148, 148, 1, 2, R, { VR }, FUNCFLAG_VOLATILE },
- { 0, "ADD.BAR", 151, 151, 0, 0, V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
- { 0, "ADD.MENU", 152, 152, 2, 2, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
- { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
{ "CLEAN", "CLEAN", 162, 162, 1, 1, V, { VR }, 0 },
{ "MDETERM", "MDETERM", 163, 163, 1, 1, V, { VA }, 0 },
{ "MINVERSE", "MINVERSE", 164, 164, 1, 1, A, { VA }, 0 },
@@ -434,10 +429,16 @@ static const FunctionData saFuncTableBiff2[] =
// *** macro sheet commands ***
{ 0, "A1.R1C1", 30, 30, 0, 1, V, { VR }, FUNCFLAG_MACROCMD },
+ { 0, "RETURN", 55, 55, 0, 1, R, { RO }, FUNCFLAG_MACROFUNC },
+ { 0, "ABSREF", 79, 79, 2, 2, R, { VR, RO }, FUNCFLAG_MACROFUNC },
{ 0, "ADD.ARROW", 81, 81, 0, 0, V, {}, FUNCFLAG_MACROCMD },
+ { 0, "ACTIVE.CELL", 94, 94, 0, 0, R, {}, FUNCFLAG_MACROFUNC },
{ 0, "ACTIVATE", 103, 103, 0, 2, V, { VR }, FUNCFLAG_MACROCMD },
{ 0, "ACTIVATE.NEXT", 104, 104, 0, 0, V, {}, FUNCFLAG_MACROCMD },
- { 0, "ACTIVATE.PREV", 105, 105, 0, 0, V, {}, FUNCFLAG_MACROCMD }
+ { 0, "ACTIVATE.PREV", 105, 105, 0, 0, V, {}, FUNCFLAG_MACROCMD },
+ { 0, "ADD.BAR", 151, 151, 0, 0, V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
+ { 0, "ADD.MENU", 152, 152, 2, 2, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
+ { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }
};
/** Functions new in BIFF3. */
@@ -447,9 +448,6 @@ static const FunctionData saFuncTableBiff3[] =
{ "TREND", "TREND", 50, 50, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4
{ "LOGEST", "LOGEST", 51, 51, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4
{ "GROWTH", "GROWTH", 52, 52, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4
- { 0, "ADD.BAR", 151, 151, 0, 1, V, { VR }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1
- { 0, "ADD.MENU", 152, 152, 2, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3
- { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 3, BIFF3: 3-4
{ "TRUNC", "TRUNC", 197, 197, 1, 2, V, { VR }, 0 }, // BIFF2: 1, BIFF3: 1-2
{ "DOLLAR", "USDOLLAR", 204, 204, 1, 2, V, { VR }, FUNCFLAG_IMPORTONLY },
{ 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { VR }, 0 },
@@ -478,7 +476,13 @@ static const FunctionData saFuncTableBiff3[] =
{ "ATANH", "ATANH", 234, 234, 1, 1, V, { VR }, 0 },
{ "ACOTH", "ATANH", 234, 234, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY },
{ "DGET", "DGET", 235, 235, 3, 3, V, { RO, RR }, 0 },
- { "INFO", "INFO", 244, 244, 1, 1, V, { VR }, FUNCFLAG_VOLATILE }
+ { "INFO", "INFO", 244, 244, 1, 1, V, { VR }, FUNCFLAG_VOLATILE },
+
+ // *** macro sheet commands ***
+
+ { 0, "ADD.BAR", 151, 151, 0, 1, V, { VR }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1
+ { 0, "ADD.MENU", 152, 152, 2, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3
+ { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { VR, RO }, FUNCFLAG_MACROFUNC } // BIFF2: 3, BIFF3: 3-4
};
/** Functions new in BIFF4. */
@@ -662,8 +666,6 @@ static const FunctionData saFuncTableBiff5[] =
{ "WEEKDAY", "WEEKDAY", 70, 70, 1, 2, V, { VR }, 0 }, // BIFF2-4: 1, BIFF5: 1-2
{ "HLOOKUP", "HLOOKUP", 101, 101, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4
{ "VLOOKUP", "VLOOKUP", 102, 102, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4
- { 0, "ADD.MENU", 152, 152, 2, 4, V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4
- { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5
{ "DAYS360", "DAYS360", 220, 220, 2, 3, V, { VR }, 0 }, // BIFF3-4: 2, BIFF5: 2-3
{ 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_EXPORTONLY }, // MACRO or EXTERNAL
{ "CONCATENATE", "CONCATENATE", 336, 336, 0, MX, V, { VR }, 0 },
@@ -686,6 +688,8 @@ static const FunctionData saFuncTableBiff5[] =
// *** macro sheet commands ***
+ { 0, "ADD.MENU", 152, 152, 2, 4, V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4
+ { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5
{ 0, "ADD.CHART.AUTOFORMAT", 390, 390, 0, 2, V, { VR }, FUNCFLAG_MACROCMD },
{ 0, "ADD.LIST.ITEM", 451, 451, 0, 2, V, { VR }, FUNCFLAG_MACROCMD },
{ 0, "ACTIVE.CELL.FONT", 476, 476, 0, 14, V, { VR }, FUNCFLAG_MACROCMD }
@@ -738,41 +742,39 @@ static const FunctionData saFuncTableOox[] =
/** Functions defined by OpenFormula, but not supported by Calc or by Excel. */
static const FunctionData saFuncTableOdf[] =
{
- { "ARABIC", 0, NOID, NOID, 1, 1, V, { VR }, 0 },
- { "B", 0, NOID, NOID, 3, 4, V, { VR }, 0 },
- { "BASE", 0, NOID, NOID, 2, 3, V, { VR }, 0 },
- { "BITAND", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "BITOR", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, 0 },
- { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "DDE", 0, NOID, NOID, 3, 4, V, { VR }, 0 },
- { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, 0 },
- { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, 0 },
- { "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, 0 },
- { "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, 0 },
- { "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, 0 },
- { "IFNA", 0, NOID, NOID, 2, 2, V, { VR, RO }, 0 },
- { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { RO }, 0 },
- { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { VR }, 0 },
- { "MULTIPLE.OPERATIONS", 0, NOID, NOID, 3, 5, V, { RO }, 0 },
- { "MUNIT", 0, NOID, NOID, 1, 1, A, { VR }, 0 },
- { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "PDURATION", 0, NOID, NOID, 3, 3, V, { VR }, 0 },
- { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { VR }, 0 },
- { "PHI", 0, NOID, NOID, 1, 1, V, { VR }, 0 },
- { "RRI", 0, NOID, NOID, 3, 3, V, { VR }, 0 },
- { "SHEET", 0, NOID, NOID, 1, 1, V, { RO }, 0 },
- { "SHEETS", 0, NOID, NOID, 0, 1, V, { RO }, 0 },
- { "SKEWP", 0, NOID, NOID, 1, MX, V, { RX }, 0 },
- { "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR }, 0 },
- { "UNICODE", 0, NOID, NOID, 1, 1, V, { VR }, 0 },
- { "XOR", 0, NOID, NOID, 1, MX, V, { RX }, 0 }
+ { "ARABIC", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "B", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BASE", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITAND", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "IFNA", 0, NOID, NOID, 2, 2, V, { VR, RO }, FUNCFLAG_MACROCALLODF },
+ { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "MUNIT", 0, NOID, NOID, 1, 1, A, { VR }, FUNCFLAG_MACROCALLODF },
+ { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "PDURATION", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "PHI", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "RRI", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "SHEET", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "SHEETS", 0, NOID, NOID, 0, 1, V, { RO }, FUNCFLAG_MACROCALLODF },
+ { "SKEWP", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF },
+ { "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "UNICODE", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF },
+ { "XOR", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF }
};
// ----------------------------------------------------------------------------
@@ -895,6 +897,7 @@ FunctionProviderImpl::FunctionProviderImpl( FilterType eFilter, BiffType eBiff,
initFuncs( saFuncTableBiff8, STATIC_ARRAY_END( saFuncTableBiff8 ), nMaxParam, bImportFilter );
if( eFilter == FILTER_OOX )
initFuncs( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ), nMaxParam, bImportFilter );
+ initFuncs( saFuncTableOdf, STATIC_ARRAY_END( saFuncTableOdf ), nMaxParam, bImportFilter );
}
void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam )
@@ -905,13 +908,25 @@ void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nM
xFuncInfo->maOdfFuncName = OUString::createFromAscii( rFuncData.mpcOdfFuncName );
if( rFuncData.mpcOoxFuncName )
xFuncInfo->maOoxFuncName = OUString::createFromAscii( rFuncData.mpcOoxFuncName );
+
if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALL ) )
+ {
+ OSL_ENSURE( xFuncInfo->maOoxFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing OOXML function name" );
+ OSL_ENSURE( !getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ), "FunctionProviderImpl::initFunc - unexpected flag FUNCFLAG_MACROCALLODF" );
xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfn." ) + xFuncInfo->maOoxFuncName;
+ }
+ else if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ) )
+ {
+ OSL_ENSURE( xFuncInfo->maOdfFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing ODF function name" );
+ xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfnodf." ) + xFuncInfo->maOdfFuncName;
+ }
+
switch( rFuncData.mnFlags & FUNCFLAG_FUNCLIBMASK )
{
case FUNCFLAG_EUROTOOL: xFuncInfo->meFuncLibType = FUNCLIB_EUROTOOL; break;
default: xFuncInfo->meFuncLibType = FUNCLIB_UNKNOWN;
}
+
xFuncInfo->mnApiOpCode = -1;
xFuncInfo->mnOobFuncId = rFuncData.mnOobFuncId;
xFuncInfo->mnBiffFuncId = rFuncData.mnBiffFuncId;
diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx
index 3eac90040667..cd914ceae196 100644
--- a/oox/source/xls/stylesbuffer.cxx
+++ b/oox/source/xls/stylesbuffer.cxx
@@ -69,6 +69,7 @@ using ::com::sun::star::awt::FontDescriptor;
using ::com::sun::star::awt::XDevice;
using ::com::sun::star::awt::XFont2;
using ::com::sun::star::table::BorderLine;
+using ::com::sun::star::table::TableBorder;
using ::com::sun::star::text::XText;
using ::com::sun::star::style::XStyle;
using ::oox::core::FilterBase;
@@ -1398,7 +1399,6 @@ void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const
rPropMap[ PROP_VertJustify ] <<= maApiData.meVerJustify;
rPropMap[ PROP_WritingMode ] <<= maApiData.mnWritingMode;
rPropMap[ PROP_RotateAngle ] <<= maApiData.mnRotation;
- rPropMap[ PROP_RotateReference ] <<= ::com::sun::star::table::CellVertJustify_STANDARD; // rotation reference
rPropMap[ PROP_Orientation ] <<= maApiData.meOrientation;
rPropMap[ PROP_ParaIndent ] <<= maApiData.mnIndent;
rPropMap[ PROP_IsTextWrapped ] <<= maApiData.mbWrapText;
@@ -1517,6 +1517,57 @@ ApiBorderData::ApiBorderData() :
{
}
+bool ApiBorderData::hasAnyOuterBorder() const
+{
+ return
+ (maBorder.IsTopLineValid && (maBorder.TopLine.OuterLineWidth > 0)) ||
+ (maBorder.IsBottomLineValid && (maBorder.BottomLine.OuterLineWidth > 0)) ||
+ (maBorder.IsLeftLineValid && (maBorder.LeftLine.OuterLineWidth > 0)) ||
+ (maBorder.IsRightLineValid && (maBorder.RightLine.OuterLineWidth > 0));
+}
+
+namespace {
+
+bool operator==( const BorderLine& rLeft, const BorderLine& rRight )
+{
+ return
+ (rLeft.Color == rRight.Color) &&
+ (rLeft.InnerLineWidth == rRight.InnerLineWidth) &&
+ (rLeft.OuterLineWidth == rRight.OuterLineWidth) &&
+ (rLeft.LineDistance == rRight.LineDistance);
+}
+
+bool operator==( const TableBorder& rLeft, const TableBorder& rRight )
+{
+ return
+ (rLeft.TopLine == rRight.TopLine) &&
+ (rLeft.IsTopLineValid == rRight.IsTopLineValid) &&
+ (rLeft.BottomLine == rRight.BottomLine) &&
+ (rLeft.IsBottomLineValid == rRight.IsBottomLineValid) &&
+ (rLeft.LeftLine == rRight.LeftLine) &&
+ (rLeft.IsLeftLineValid == rRight.IsLeftLineValid) &&
+ (rLeft.RightLine == rRight.RightLine) &&
+ (rLeft.IsRightLineValid == rRight.IsRightLineValid) &&
+ (rLeft.HorizontalLine == rRight.HorizontalLine) &&
+ (rLeft.IsHorizontalLineValid == rRight.IsHorizontalLineValid) &&
+ (rLeft.VerticalLine == rRight.VerticalLine) &&
+ (rLeft.IsVerticalLineValid == rRight.IsVerticalLineValid) &&
+ (rLeft.Distance == rRight.Distance) &&
+ (rLeft.IsDistanceValid == rRight.IsDistanceValid);
+}
+
+} // namespace
+
+bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight )
+{
+ return
+ (rLeft.maBorder == rRight.maBorder) &&
+ (rLeft.maTLtoBR == rRight.maTLtoBR) &&
+ (rLeft.maBLtoTR == rRight.maBLtoTR) &&
+ (rLeft.mbBorderUsed == rRight.mbBorderUsed) &&
+ (rLeft.mbDiagUsed == rRight.mbDiagUsed);
+}
+
// ============================================================================
namespace {
@@ -1820,6 +1871,14 @@ ApiSolidFillData::ApiSolidFillData() :
{
}
+bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight )
+{
+ return
+ (rLeft.mnColor == rRight.mnColor) &&
+ (rLeft.mbTransparent == rRight.mbTransparent) &&
+ (rLeft.mbUsed == rRight.mbUsed);
+}
+
// ============================================================================
namespace {
@@ -2132,7 +2191,8 @@ XfModel::XfModel() :
Xf::Xf( const WorkbookHelper& rHelper ) :
WorkbookHelper( rHelper ),
maAlignment( rHelper ),
- maProtection( rHelper )
+ maProtection( rHelper ),
+ meRotationRef( ::com::sun::star::table::CellVertJustify_STANDARD )
{
}
@@ -2315,13 +2375,46 @@ void Xf::importXf( BiffInputStream& rStrm )
void Xf::finalizeImport()
{
+ StylesBuffer& rStyles = getStyles();
+
// alignment and protection
maAlignment.finalizeImport();
maProtection.finalizeImport();
- // update used flags from cell style
- if( maModel.mbCellXf )
- if( const Xf* pStyleXf = getStyles().getStyleXf( maModel.mnStyleXfId ).get() )
- updateUsedFlags( *pStyleXf );
+
+ /* Enables the used flags, if the formatting attributes differ from the
+ style XF. In cell XFs Excel uses the cell attributes, if they differ
+ from the parent style XF (even if the used flag is switched off).
+ #109899# ...or if the respective flag is not set in parent style XF.
+ */
+ const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0;
+ if( pStyleXf )
+ {
+ const XfModel& rStyleData = pStyleXf->maModel;
+ if( !maModel.mbFontUsed )
+ maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
+ if( !maModel.mbNumFmtUsed )
+ maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
+ if( !maModel.mbAlignUsed )
+ maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData());
+ if( !maModel.mbProtUsed )
+ maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData());
+ if( !maModel.mbBorderUsed )
+ maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId );
+ if( !maModel.mbAreaUsed )
+ maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId );
+ }
+
+ /* #i38709# Decide which rotation reference mode to use. If any outer
+ border line of the cell is set (either explicitly or via cell style),
+ and the cell contents are rotated, set rotation reference to bottom of
+ cell. This causes the borders to be painted rotated with the text. */
+ if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) )
+ {
+ sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1);
+ if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() )
+ if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() )
+ meRotationRef = ::com::sun::star::table::CellVertJustify_BOTTOM;
+ }
}
FontRef Xf::getFont() const
@@ -2341,7 +2434,7 @@ void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const
StylesBuffer& rStyles = getStyles();
// create and set cell style
- if( maModel.mbCellXf )
+ if( isCellXf() )
rPropMap[ PROP_CellStyle ] <<= rStyles.createCellStyle( maModel.mnStyleXfId );
if( maModel.mbFontUsed )
@@ -2356,6 +2449,8 @@ void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const
rStyles.writeBorderToPropertyMap( rPropMap, maModel.mnBorderId );
if( maModel.mbAreaUsed )
rStyles.writeFillToPropertyMap( rPropMap, maModel.mnFillId );
+ if( maModel.mbAlignUsed || maModel.mbBorderUsed )
+ rPropMap[ PROP_RotateReference ] <<= meRotationRef;
}
void Xf::writeToPropertySet( PropertySet& rPropSet ) const
@@ -2371,37 +2466,15 @@ void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags )
- In cell XFs a *set* bit means a used attribute.
- In style XFs a *cleared* bit means a used attribute.
The boolean flags always store true, if the attribute is used.
- The "maModel.mbCellXf == getFlag(...)" construct evaluates to true in
- both mentioned cases: cell XF and set bit; or style XF and cleared bit.
- */
- maModel.mbFontUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_FONT_USED );
- maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED );
- maModel.mbAlignUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED );
- maModel.mbProtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_PROT_USED );
- maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_BORDER_USED );
- maModel.mbAreaUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_AREA_USED );
-}
-
-void Xf::updateUsedFlags( const Xf& rStyleXf )
-{
- /* Enables the used flags, if the formatting attributes differ from the
- passed style XF. In cell XFs Excel uses the cell attributes, if they
- differ from the parent style XF.
- #109899# ...or if the respective flag is not set in parent style XF.
+ The "isCellXf() == getFlag(...)" construct evaluates to true in both
+ mentioned cases: cell XF and set bit; or style XF and cleared bit.
*/
- const XfModel& rStyleData = rStyleXf.maModel;
- if( !maModel.mbFontUsed )
- maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
- if( !maModel.mbNumFmtUsed )
- maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
- if( !maModel.mbAlignUsed )
- maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == rStyleXf.maAlignment.getApiData());
- if( !maModel.mbProtUsed )
- maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == rStyleXf.maProtection.getApiData());
- if( !maModel.mbBorderUsed )
- maModel.mbBorderUsed = !rStyleData.mbBorderUsed || (maModel.mnBorderId != rStyleData.mnBorderId);
- if( !maModel.mbAreaUsed )
- maModel.mbAreaUsed = !rStyleData.mbAreaUsed || (maModel.mnFillId != rStyleData.mnFillId);
+ maModel.mbFontUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_FONT_USED );
+ maModel.mbNumFmtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED );
+ maModel.mbAlignUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED );
+ maModel.mbProtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_PROT_USED );
+ maModel.mbBorderUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_BORDER_USED );
+ maModel.mbAreaUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_AREA_USED );
}
// ============================================================================
@@ -3133,11 +3206,12 @@ void StylesBuffer::importFormat( BiffInputStream& rStrm )
void StylesBuffer::importXf( BiffInputStream& rStrm )
{
XfRef xXf( new Xf( *this ) );
- // store XF in both lists (except BIFF2 which does not support cell styles)
- maCellXfs.push_back( xXf );
- if( getBiff() != BIFF2 )
- maStyleXfs.push_back( xXf );
xXf->importXf( rStrm );
+
+ XfRef xCellXf, xStyleXf;
+ (xXf->isCellXf() ? xCellXf : xStyleXf) = xXf;
+ maCellXfs.push_back( xCellXf );
+ maStyleXfs.push_back( xStyleXf );
}
void StylesBuffer::importStyle( BiffInputStream& rStrm )
@@ -3156,20 +3230,11 @@ void StylesBuffer::finalizeImport()
// borders and fills
maBorders.forEachMem( &Border::finalizeImport );
maFills.forEachMem( &Fill::finalizeImport );
-
- /* Style XFs and cell XFs. The BIFF format stores cell XFs and style XFs
- mixed in a single list. The import filter has stored the XFs in both
- lists to make the getStyleXf() function working correctly (e.g. for
- retrieving the default font, see getDefaultFont() function), except for
- BIFF2 which does not support cell styles at all. Therefore, if in BIFF
- filter mode, we do not need to finalize the cell styles list. */
- if( getFilterType() == FILTER_OOX )
- maStyleXfs.forEachMem( &Xf::finalizeImport );
+ // style XFs and cell XFs
+ maStyleXfs.forEachMem( &Xf::finalizeImport );
maCellXfs.forEachMem( &Xf::finalizeImport );
-
// built-in and user defined cell styles
maCellStyles.finalizeImport();
-
// differential formatting (for conditional formatting)
maDxfs.forEachMem( &Dxf::finalizeImport );
}
@@ -3184,6 +3249,11 @@ FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const
return maFonts.get( nFontId );
}
+BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const
+{
+ return maBorders.get( nBorderId );
+}
+
XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const
{
return maCellXfs.get( nXfId );
@@ -3225,6 +3295,56 @@ const FontModel& StylesBuffer::getDefaultFontModel() const
return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel();
}
+bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const
+{
+ if( nBorderId1 == nBorderId2 )
+ return true;
+
+ switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ // in OOXML, borders are assumed to be unique
+ return false;
+
+ case FILTER_BIFF:
+ {
+ // in BIFF, a new border entry has been created for every XF
+ const Border* pBorder1 = maBorders.get( nBorderId1 ).get();
+ const Border* pBorder2 = maBorders.get( nBorderId2 ).get();
+ return pBorder1 && pBorder2 && (pBorder1->getApiData() == pBorder2->getApiData());
+ }
+
+ case FILTER_UNKNOWN:
+ break;
+ }
+ return false;
+}
+
+bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const
+{
+ if( nFillId1 == nFillId2 )
+ return true;
+
+ switch( getFilterType() )
+ {
+ case FILTER_OOX:
+ // in OOXML, fills are assumed to be unique
+ return false;
+
+ case FILTER_BIFF:
+ {
+ // in BIFF, a new fill entry has been created for every XF
+ const Fill* pFill1 = maFills.get( nFillId1 ).get();
+ const Fill* pFill2 = maFills.get( nFillId2 ).get();
+ return pFill1 && pFill2 && (pFill1->getApiData() == pFill2->getApiData());
+ }
+
+ case FILTER_UNKNOWN:
+ break;
+ }
+ return false;
+}
+
OUString StylesBuffer::getDefaultStyleName() const
{
return maCellStyles.getDefaultStyleName();