summaryrefslogtreecommitdiff
path: root/sc/source/filter/oox
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.com>2019-04-19 23:15:53 +0530
committerAndras Timar <andras.timar@collabora.com>2019-05-04 10:22:02 +0200
commitc2f1c68ffb6dfa1ce7de09dcc428d6c53549e88d (patch)
tree15d5df7332e6249922645e58d30c2706df17c659 /sc/source/filter/oox
parent8c637b47d9de4b3a64c33a9c2ffe7ed220be2467 (diff)
tdf#122590: follow-up : import x14:cfRule priorities
If there are x:cfRule's and x14:cfRule's with matching range-list, then insert the conditional-fmt entries into the document in the order of the priorities. That is don't just append the x14:cfRule entries to the document after the x:cfRule entries are inserted. There was also a off-by-one bug in the priority export of x14:cfRule entries. This caused the priority numbers to be duplicated. This is also fixed. Change-Id: I5b0d11c4456b2966b808f6ee589075a870f43768 Reviewed-on: https://gerrit.libreoffice.org/71311 Tested-by: Jenkins Reviewed-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'sc/source/filter/oox')
-rw-r--r--sc/source/filter/oox/condformatbuffer.cxx87
-rw-r--r--sc/source/filter/oox/extlstcontext.cxx15
2 files changed, 96 insertions, 6 deletions
diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx
index 5750cce50592..0d75b4399200 100644
--- a/sc/source/filter/oox/condformatbuffer.cxx
+++ b/sc/source/filter/oox/condformatbuffer.cxx
@@ -18,6 +18,8 @@
*/
#include <memory>
+#include <unordered_set>
+#include <unordered_map>
#include <condformatbuffer.hxx>
#include <formulaparser.hxx>
@@ -424,7 +426,8 @@ void CondFormatRuleModel::setBiff12TextType( sal_Int32 nOperator )
CondFormatRule::CondFormatRule( const CondFormat& rCondFormat, ScConditionalFormat* pFormat ) :
WorksheetHelper( rCondFormat ),
mrCondFormat( rCondFormat ),
- mpFormat(pFormat)
+ mpFormat(pFormat),
+ mpFormatEntry(nullptr)
{
}
@@ -698,8 +701,20 @@ void CondFormatRule::importCfRule( SequenceInputStream& rStrm )
}
}
+void CondFormatRule::setFormatEntry(sal_Int32 nPriority, ScFormatEntry* pEntry)
+{
+ maModel.mnPriority = nPriority;
+ mpFormatEntry = pEntry;
+}
+
void CondFormatRule::finalizeImport()
{
+ if (mpFormatEntry)
+ {
+ mpFormat->AddEntry(mpFormatEntry);
+ return;
+ }
+
ScConditionMode eOperator = ScConditionMode::NONE;
/* Replacement formula for unsupported rule types (text comparison rules,
@@ -1091,10 +1106,63 @@ ScConditionalFormat* findFormatByRange(const ScRangeList& rRange, const ScDocume
return nullptr;
}
+class ScRangeListHasher
+{
+public:
+ size_t operator() (ScRangeList const& rRanges) const
+ {
+ size_t nHash = 0;
+ for (size_t nIdx = 0; nIdx < rRanges.size(); ++nIdx)
+ nHash += rRanges[nIdx].hashArea();
+ return nHash;
+ }
+};
+
}
void CondFormatBuffer::finalizeImport()
{
+ std::unordered_set<size_t> aDoneExtCFs;
+ typedef std::unordered_map<ScRangeList, CondFormat*, ScRangeListHasher> RangeMap;
+ typedef std::vector<std::unique_ptr<ScFormatEntry>> FormatEntries;
+ RangeMap aRangeMap;
+ for (auto& rxCondFormat : maCondFormats)
+ {
+ if (aRangeMap.find(rxCondFormat->getRanges()) != aRangeMap.end())
+ continue;
+ aRangeMap[rxCondFormat->getRanges()] = rxCondFormat.get();
+ }
+
+ size_t nExtCFIndex = 0;
+ for (const auto& rxExtCondFormat : maExtCondFormats)
+ {
+ ScDocument* pDoc = &getScDocument();
+ const ScRangeList& rRange = rxExtCondFormat->getRange();
+ RangeMap::iterator it = aRangeMap.find(rRange);
+ if (it != aRangeMap.end())
+ {
+ CondFormat& rCondFormat = *it->second;
+ const FormatEntries& rEntries = rxExtCondFormat->getEntries();
+ const std::vector<sal_Int32>& rPriorities = rxExtCondFormat->getPriorities();
+ size_t nEntryIdx = 0;
+ for (const auto& rxEntry : rEntries)
+ {
+ CondFormatRuleRef xRule = rCondFormat.createRule();
+ ScFormatEntry* pNewEntry = rxEntry->Clone(pDoc);
+ sal_Int32 nPriority = rPriorities[nEntryIdx];
+ if (nPriority == -1)
+ nPriority = mnNonPrioritizedRuleNextPriority++;
+ xRule->setFormatEntry(nPriority, pNewEntry);
+ rCondFormat.insertRule(xRule);
+ ++nEntryIdx;
+ }
+
+ aDoneExtCFs.insert(nExtCFIndex);
+ }
+
+ ++nExtCFIndex;
+ }
+
for( const auto& rxCondFormat : maCondFormats )
{
if ( rxCondFormat.get())
@@ -1106,10 +1174,16 @@ void CondFormatBuffer::finalizeImport()
rxCfRule.get()->finalizeImport();
}
+ nExtCFIndex = 0;
for (const auto& rxExtCondFormat : maExtCondFormats)
{
- ScDocument* pDoc = &getScDocument();
+ if (aDoneExtCFs.count(nExtCFIndex))
+ {
+ ++nExtCFIndex;
+ continue;
+ }
+ ScDocument* pDoc = &getScDocument();
const ScRangeList& rRange = rxExtCondFormat->getRange();
SCTAB nTab = rRange.front().aStart.Tab();
ScConditionalFormat* pFormat = findFormatByRange(rRange, pDoc, nTab);
@@ -1128,6 +1202,8 @@ void CondFormatBuffer::finalizeImport()
{
pFormat->AddEntry(rxEntry->Clone(pDoc));
}
+
+ ++nExtCFIndex;
}
rStyleIdx = 0; // Resets <extlst> <cfRule> style index.
@@ -1294,10 +1370,15 @@ void ExtCfDataBarRule::importCfvo( const AttributeList& rAttribs )
maModel.maColorScaleType = rAttribs.getString( XML_type, OUString() );
}
-ExtCfCondFormat::ExtCfCondFormat(const ScRangeList& rRange, std::vector< std::unique_ptr<ScFormatEntry> >& rEntries):
+ExtCfCondFormat::ExtCfCondFormat(const ScRangeList& rRange, std::vector< std::unique_ptr<ScFormatEntry> >& rEntries,
+ std::vector<sal_Int32>* pPriorities):
maRange(rRange)
{
maEntries.swap(rEntries);
+ if (pPriorities)
+ maPriorities = *pPriorities;
+ else
+ maPriorities.resize(maEntries.size(), -1);
}
ExtCfCondFormat::~ExtCfCondFormat()
diff --git a/sc/source/filter/oox/extlstcontext.cxx b/sc/source/filter/oox/extlstcontext.cxx
index 1d1bc8341fd5..46d268f32ca7 100644
--- a/sc/source/filter/oox/extlstcontext.cxx
+++ b/sc/source/filter/oox/extlstcontext.cxx
@@ -84,6 +84,7 @@ void ExtCfRuleContext::onStartElement( const AttributeList& rAttribs )
ExtConditionalFormattingContext::ExtConditionalFormattingContext(WorksheetContextBase& rFragment):
WorksheetContextBase(rFragment)
{
+ nPriority = -1;
isPreviousElementF = false;
}
@@ -104,6 +105,7 @@ ContextHandlerRef ExtConditionalFormattingContext::onCreateContext(sal_Int32 nEl
{
OUString aType = rAttribs.getString(XML_type, OUString());
OUString aId = rAttribs.getString(XML_id, OUString());
+ nPriority = rAttribs.getInteger( XML_priority, -1 );
if (aType == "dataBar")
{
@@ -179,6 +181,7 @@ void ExtConditionalFormattingContext::onEndElement()
case XM_TOKEN(f):
{
rFormulas.push_back(aChars);
+ maPriorities.push_back(nPriority);
}
break;
case XLS14_TOKEN( cfRule ):
@@ -201,9 +204,9 @@ void ExtConditionalFormattingContext::onEndElement()
aRange[i].aEnd.SetTab(nTab);
}
- if(isPreviousElementF) // sqref can be alone in some cases.
+ if (isPreviousElementF) // sqref can be alone in some cases.
{
- for(const OUString& rFormula : rFormulas)
+ for (const OUString& rFormula : rFormulas)
{
ScAddress rPos = aRange.GetTopLeftCorner();
rStyle = getStyles().createExtDxfStyle(rStyleIdx);
@@ -215,11 +218,17 @@ void ExtConditionalFormattingContext::onEndElement()
maEntries.push_back(std::unique_ptr<ScFormatEntry>(pEntry));
rStyleIdx++;
}
+
+ assert(rFormulas.size() == maPriorities.size());
rFormulas.clear();
}
std::vector< std::unique_ptr<ExtCfCondFormat> >& rExtFormats = getCondFormats().importExtCondFormat();
- rExtFormats.push_back(std::make_unique<ExtCfCondFormat>(aRange, maEntries));
+ rExtFormats.push_back(std::make_unique<ExtCfCondFormat>(aRange, maEntries, &maPriorities));
+
+ if (isPreviousElementF)
+ maPriorities.clear();
+
isPreviousElementF = false;
}
break;