Kaydet (Commit) 8a27eeb1 authored tarafından Dennis Francis's avatar Dennis Francis Kaydeden (comit) Andras Timar

tdf#124953: Use rangelist's combined range top-left address...

as origin address in the conditional format formula on xlsx export.
Excel seems to get confused if anything else is supplied as the
origin in the formula.

For example, before this patch, for a condfmt range over the
range-list [A3:C5 E1:F2], the origin address used in the formula
(for text search type entries) is A3.

<conditionalFormatting sqref="A3:C5 E1:F2">
   <cfRule type="containsText" dxfId="0" priority="1" operator="containsText" text="ABC">
       <formula>NOT(ISERROR(SEARCH("ABC",A3)))</formula>
   </cfRule>
</conditionalFormatting>

In this patch we use the top-left cell address(A1) of the combined range "A1:F5" as
the origin address.

       <formula>NOT(ISERROR(SEARCH("ABC",A1)))</formula>

Reviewed-on: https://gerrit.libreoffice.org/71312
Tested-by: Jenkins
Reviewed-by: 's avatarAndras Timar <andras.timar@collabora.com>
(cherry picked from commit ca40d4ce)

Change-Id: If08a859bc361f925148ff463758d03ebbc41c0ac
Reviewed-on: https://gerrit.libreoffice.org/72009Reviewed-by: 's avatarAndras Timar <andras.timar@collabora.com>
Tested-by: 's avatarAndras Timar <andras.timar@collabora.com>
üst baf7d49f
...@@ -112,6 +112,7 @@ public: ...@@ -112,6 +112,7 @@ public:
void testConditionalFormatRangeListXLSX(); void testConditionalFormatRangeListXLSX();
void testConditionalFormatContainsTextXLSX(); void testConditionalFormatContainsTextXLSX();
void testConditionalFormatPriorityCheckXLSX(); void testConditionalFormatPriorityCheckXLSX();
void testConditionalFormatOriginXLSX();
void testMiscRowHeightExport(); void testMiscRowHeightExport();
void testNamedRangeBugfdo62729(); void testNamedRangeBugfdo62729();
void testBuiltinRangesXLSX(); void testBuiltinRangesXLSX();
...@@ -240,6 +241,7 @@ public: ...@@ -240,6 +241,7 @@ public:
CPPUNIT_TEST(testConditionalFormatRangeListXLSX); CPPUNIT_TEST(testConditionalFormatRangeListXLSX);
CPPUNIT_TEST(testConditionalFormatContainsTextXLSX); CPPUNIT_TEST(testConditionalFormatContainsTextXLSX);
CPPUNIT_TEST(testConditionalFormatPriorityCheckXLSX); CPPUNIT_TEST(testConditionalFormatPriorityCheckXLSX);
CPPUNIT_TEST(testConditionalFormatOriginXLSX);
CPPUNIT_TEST(testMiscRowHeightExport); CPPUNIT_TEST(testMiscRowHeightExport);
CPPUNIT_TEST(testNamedRangeBugfdo62729); CPPUNIT_TEST(testNamedRangeBugfdo62729);
CPPUNIT_TEST(testBuiltinRangesXLSX); CPPUNIT_TEST(testBuiltinRangesXLSX);
...@@ -3979,6 +3981,19 @@ void ScExportTest::testConditionalFormatPriorityCheckXLSX() ...@@ -3979,6 +3981,19 @@ void ScExportTest::testConditionalFormatPriorityCheckXLSX()
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A3", bHighPriorityExtensionA3, nA3ExtPriority < nA3NormalPriority); CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A3", bHighPriorityExtensionA3, nA3ExtPriority < nA3NormalPriority);
} }
void ScExportTest::testConditionalFormatOriginXLSX()
{
ScDocShellRef xDocSh = loadDoc("conditional_fmt_origin.", FORMAT_XLSX);
CPPUNIT_ASSERT(xDocSh.is());
xmlDocPtr pDoc = XPathHelper::parseExport(*xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
CPPUNIT_ASSERT(pDoc);
// tdf#124953 : The range-list is B3:C6 F1:G2, origin address in the formula should be B1, not B3.
OUString aFormula = getXPathContent(pDoc, "//x:conditionalFormatting/x:cfRule/x:formula");
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong origin address in formula", OUString("NOT(ISERROR(SEARCH(\"BAC\",B1)))"), aFormula);
}
void ScExportTest::testEscapeCharInNumberFormatXLSX() void ScExportTest::testEscapeCharInNumberFormatXLSX()
{ {
ScDocShellRef xDocSh = loadDoc("tdf81939.", FORMAT_XLSX); ScDocShellRef xDocSh = loadDoc("tdf81939.", FORMAT_XLSX);
......
...@@ -581,7 +581,7 @@ void XclExpLabelranges::Save( XclExpStream& rStrm ) ...@@ -581,7 +581,7 @@ void XclExpLabelranges::Save( XclExpStream& rStrm )
class XclExpCFImpl : protected XclExpRoot class XclExpCFImpl : protected XclExpRoot
{ {
public: public:
explicit XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority ); explicit XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority, ScAddress aOrigin );
/** Writes the body of the CF record. */ /** Writes the body of the CF record. */
void WriteBody( XclExpStream& rStrm ); void WriteBody( XclExpStream& rStrm );
...@@ -589,6 +589,7 @@ public: ...@@ -589,6 +589,7 @@ public:
private: private:
const ScCondFormatEntry& mrFormatEntry; /// Calc conditional format entry. const ScCondFormatEntry& mrFormatEntry; /// Calc conditional format entry.
ScAddress maOrigin; /// Top left cell of the combined range
XclFontData maFontData; /// Font formatting attributes. XclFontData maFontData; /// Font formatting attributes.
XclExpCellBorder maBorder; /// Border formatting attributes. XclExpCellBorder maBorder; /// Border formatting attributes.
XclExpCellArea maArea; /// Pattern formatting attributes. XclExpCellArea maArea; /// Pattern formatting attributes.
...@@ -610,9 +611,10 @@ private: ...@@ -610,9 +611,10 @@ private:
bool mbFormula2; bool mbFormula2;
}; };
XclExpCFImpl::XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority ) : XclExpCFImpl::XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority, ScAddress aOrigin ) :
XclExpRoot( rRoot ), XclExpRoot( rRoot ),
mrFormatEntry( rFormatEntry ), mrFormatEntry( rFormatEntry ),
maOrigin( aOrigin ),
mnFontColorId( 0 ), mnFontColorId( 0 ),
mnType( EXC_CF_TYPE_CELL ), mnType( EXC_CF_TYPE_CELL ),
mnOperator( EXC_CF_CMP_NONE ), mnOperator( EXC_CF_CMP_NONE ),
...@@ -628,6 +630,10 @@ XclExpCFImpl::XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rF ...@@ -628,6 +630,10 @@ XclExpCFImpl::XclExpCFImpl( const XclExpRoot& rRoot, const ScCondFormatEntry& rF
mbPattUsed( false ), mbPattUsed( false ),
mbFormula2(false) mbFormula2(false)
{ {
// Set correct tab for maOrigin from GetValidSrcPos() of the format-entry.
ScAddress aValidSrcPos = mrFormatEntry.GetValidSrcPos();
maOrigin.SetTab(aValidSrcPos.Tab());
/* Get formatting attributes here, and not in WriteBody(). This is needed to /* Get formatting attributes here, and not in WriteBody(). This is needed to
correctly insert all colors into the palette. */ correctly insert all colors into the palette. */
...@@ -1053,7 +1059,7 @@ void XclExpCFImpl::SaveXml( XclExpXmlStream& rStrm ) ...@@ -1053,7 +1059,7 @@ void XclExpCFImpl::SaveXml( XclExpXmlStream& rStrm )
if (RequiresFixedFormula(eOperation)) if (RequiresFixedFormula(eOperation))
{ {
rWorksheet->startElement( XML_formula, FSEND ); rWorksheet->startElement( XML_formula, FSEND );
OString aFormula = GetFixedFormula(eOperation, mrFormatEntry.GetValidSrcPos(), aText); OString aFormula = GetFixedFormula(eOperation, maOrigin, aText);
rWorksheet->writeEscaped(aFormula.getStr()); rWorksheet->writeEscaped(aFormula.getStr());
rWorksheet->endElement( XML_formula ); rWorksheet->endElement( XML_formula );
} }
...@@ -1077,10 +1083,10 @@ void XclExpCFImpl::SaveXml( XclExpXmlStream& rStrm ) ...@@ -1077,10 +1083,10 @@ void XclExpCFImpl::SaveXml( XclExpXmlStream& rStrm )
rWorksheet->endElement( XML_cfRule ); rWorksheet->endElement( XML_cfRule );
} }
XclExpCF::XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority = 0 ) : XclExpCF::XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority, ScAddress aOrigin ) :
XclExpRecord( EXC_ID_CF ), XclExpRecord( EXC_ID_CF ),
XclExpRoot( rRoot ), XclExpRoot( rRoot ),
mxImpl( new XclExpCFImpl( rRoot, rFormatEntry, nPriority ) ) mxImpl( new XclExpCFImpl( rRoot, rFormatEntry, nPriority, aOrigin ) )
{ {
} }
...@@ -1289,11 +1295,12 @@ XclExpCondfmt::XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat ...@@ -1289,11 +1295,12 @@ XclExpCondfmt::XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat
if( !maXclRanges.empty() ) if( !maXclRanges.empty() )
{ {
std::vector<XclExpExtCondFormatData> aExtEntries; std::vector<XclExpExtCondFormatData> aExtEntries;
ScAddress aOrigin = aScRanges.Combine().aStart;
for( size_t nIndex = 0, nCount = rCondFormat.size(); nIndex < nCount; ++nIndex ) for( size_t nIndex = 0, nCount = rCondFormat.size(); nIndex < nCount; ++nIndex )
if( const ScFormatEntry* pFormatEntry = rCondFormat.GetEntry( nIndex ) ) if( const ScFormatEntry* pFormatEntry = rCondFormat.GetEntry( nIndex ) )
{ {
if(pFormatEntry->GetType() == ScFormatEntry::Type::Condition) if(pFormatEntry->GetType() == ScFormatEntry::Type::Condition)
maCFList.AppendNewRecord( new XclExpCF( GetRoot(), static_cast<const ScCondFormatEntry&>(*pFormatEntry), ++rIndex ) ); maCFList.AppendNewRecord( new XclExpCF( GetRoot(), static_cast<const ScCondFormatEntry&>(*pFormatEntry), ++rIndex, aOrigin ) );
else if(pFormatEntry->GetType() == ScFormatEntry::Type::ExtCondition) else if(pFormatEntry->GetType() == ScFormatEntry::Type::ExtCondition)
{ {
const ScCondFormatEntry& rFormat = static_cast<const ScCondFormatEntry&>(*pFormatEntry); const ScCondFormatEntry& rFormat = static_cast<const ScCondFormatEntry&>(*pFormatEntry);
......
...@@ -170,7 +170,7 @@ class XclExpCFImpl; ...@@ -170,7 +170,7 @@ class XclExpCFImpl;
class XclExpCF : public XclExpRecord, protected XclExpRoot class XclExpCF : public XclExpRecord, protected XclExpRoot
{ {
public: public:
explicit XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority ); explicit XclExpCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormatEntry, sal_Int32 nPriority, ScAddress aOrigin );
virtual ~XclExpCF() override; virtual ~XclExpCF() override;
virtual void SaveXml( XclExpXmlStream& rStrm ) override; virtual void SaveXml( XclExpXmlStream& rStrm ) override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment