nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / filter / oox / extlstcontext.cxx
blob14cc8c161a1b3e06e440dd3b5c6660ef123d8fb7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <memory>
11 #include <extlstcontext.hxx>
12 #include <worksheethelper.hxx>
13 #include <oox/core/contexthandler.hxx>
14 #include <oox/helper/attributelist.hxx>
15 #include <oox/token/namespaces.hxx>
16 #include <oox/token/tokens.hxx>
17 #include <colorscale.hxx>
18 #include <condformatbuffer.hxx>
19 #include <condformatcontext.hxx>
20 #include <document.hxx>
21 #include <worksheetfragment.hxx>
22 #include <workbookfragment.hxx>
23 #include <stylesbuffer.hxx>
24 #include <stylesfragment.hxx>
26 #include <rangeutl.hxx>
27 #include <sal/log.hxx>
29 using ::oox::core::ContextHandlerRef;
30 using ::oox::xls::CondFormatBuffer;
32 sal_Int32 rStyleIdx = 0;
34 namespace oox::xls {
36 ExtCfRuleContext::ExtCfRuleContext( WorksheetContextBase& rFragment, ScDataBarFormatData* pTarget ):
37 WorksheetContextBase( rFragment ),
38 mpTarget( pTarget ),
39 mbFirstEntry(true)
43 ContextHandlerRef ExtCfRuleContext::onCreateContext( sal_Int32 , const AttributeList& )
45 return this;
48 void ExtCfRuleContext::onStartElement( const AttributeList& rAttribs )
50 switch( getCurrentElement() )
52 case XLS14_TOKEN( dataBar ):
54 ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget);
55 xRule->importDataBar( rAttribs );
56 break;
58 case XLS14_TOKEN( negativeFillColor ):
60 ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget);
61 xRule->importNegativeFillColor( rAttribs );
62 break;
64 case XLS14_TOKEN( axisColor ):
66 ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget);
67 xRule->importAxisColor( rAttribs );
68 break;
70 case XLS14_TOKEN( cfvo ):
72 ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget);
73 xRule->importCfvo( rAttribs );
74 xRule->getModel().mbIsLower = mbFirstEntry;
75 mbFirstEntry = false;
76 break;
78 default:
79 break;
83 namespace {
84 bool IsSpecificTextCondMode(ScConditionMode eMode)
86 switch (eMode)
88 case ScConditionMode::BeginsWith:
89 case ScConditionMode::EndsWith:
90 case ScConditionMode::ContainsText:
91 case ScConditionMode::NotContainsText:
92 return true;
93 default:
94 break;
96 return false;
100 ExtConditionalFormattingContext::ExtConditionalFormattingContext(WorksheetContextBase& rFragment)
101 : WorksheetContextBase(rFragment)
102 , nFormulaCount(0)
103 , nPriority(-1)
104 , eOperator(ScConditionMode::NONE)
105 , isPreviousElementF(false)
109 ContextHandlerRef ExtConditionalFormattingContext::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs)
111 if (mpCurrentRule)
113 ScFormatEntry& rFormat = **maEntries.rbegin();
114 assert(rFormat.GetType() == ScFormatEntry::Type::Iconset);
115 ScIconSetFormat& rIconSet = static_cast<ScIconSetFormat&>(rFormat);
116 ScDocument& rDoc = getScDocument();
117 SCTAB nTab = getSheetIndex();
118 ScAddress aPos(0, 0, nTab);
119 mpCurrentRule->SetData(&rIconSet, &rDoc, aPos);
120 mpCurrentRule.reset();
122 if (nElement == XLS14_TOKEN(cfRule))
124 OUString aType = rAttribs.getString(XML_type, OUString());
125 OUString aId = rAttribs.getString(XML_id, OUString());
126 nPriority = rAttribs.getInteger( XML_priority, -1 );
127 maPriorities.push_back(nPriority);
128 maModel.nPriority = nPriority;
130 if (aType == "dataBar")
132 // an ext entry does not need to have an existing corresponding entry
133 ExtLst::const_iterator aExt = getExtLst().find( aId );
134 if(aExt == getExtLst().end())
135 return nullptr;
137 ScDataBarFormatData* pInfo = aExt->second;
138 if (!pInfo)
140 return nullptr;
142 return new ExtCfRuleContext( *this, pInfo );
144 else if (aType == "iconSet")
146 ScDocument& rDoc = getScDocument();
147 mpCurrentRule.reset(new IconSetRule(*this));
148 maEntries.push_back(std::make_unique<ScIconSetFormat>(&rDoc));
149 return new IconSetContext(*this, mpCurrentRule.get());
151 else if (aType == "cellIs")
153 sal_Int32 aToken = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID );
154 eOperator = CondFormatBuffer::convertToInternalOperator(aToken);
155 maModel.eOperator = eOperator;
156 return this;
158 else if (aType == "containsText")
160 eOperator = ScConditionMode::ContainsText;
161 maModel.eOperator = eOperator;
162 return this;
164 else if (aType == "notContainsText")
166 eOperator = ScConditionMode::NotContainsText;
167 maModel.eOperator = eOperator;
168 return this;
170 else if (aType == "beginsWith")
172 eOperator = ScConditionMode::BeginsWith;
173 maModel.eOperator = eOperator;
174 return this;
176 else if (aType == "endsWith")
178 eOperator = ScConditionMode::EndsWith;
179 maModel.eOperator = eOperator;
180 return this;
182 else if (aType == "expression")
184 eOperator = ScConditionMode::Direct;
185 maModel.eOperator = eOperator;
186 return this;
188 else
190 SAL_WARN("sc", "unhandled XLS14_TOKEN(cfRule) with type: " << aType);
193 else if (nElement == XLS14_TOKEN( dxf ))
195 return new DxfContext( *this, getStyles().createExtDxf() );
197 else if (nElement == XM_TOKEN( sqref ) || nElement == XM_TOKEN( f ))
199 if(nElement == XM_TOKEN( f ))
200 nFormulaCount++;
201 return this;
204 return nullptr;
207 void ExtConditionalFormattingContext::onStartElement(const AttributeList& /*Attribs*/)
211 void ExtConditionalFormattingContext::onCharacters(const OUString& rCharacters)
213 switch (getCurrentElement())
215 case XM_TOKEN(f):
217 aChars = rCharacters;
218 isPreviousElementF = true;
220 break;
221 case XM_TOKEN(sqref):
223 aChars = rCharacters;
225 break;
230 void ExtConditionalFormattingContext::onEndElement()
232 switch (getCurrentElement())
234 case XM_TOKEN(f):
236 if(!IsSpecificTextCondMode(eOperator) || nFormulaCount == 2)
237 maModel.aFormula = aChars;
239 break;
240 case XLS14_TOKEN( cfRule ):
242 getStyles().getExtDxfs().forEachMem( &Dxf::finalizeImport );
243 maModel.aStyle = getStyles().createExtDxfStyle(rStyleIdx);
244 rStyleIdx++;
245 nFormulaCount = 0;
246 maModels.push_back(maModel);
248 break;
249 case XM_TOKEN(sqref):
251 ScRangeList aRange;
252 ScDocument& rDoc = getScDocument();
253 bool bSuccess = ScRangeStringConverter::GetRangeListFromString(aRange, aChars, rDoc, formula::FormulaGrammar::CONV_XL_OOX);
254 if (!bSuccess || aRange.empty())
255 break;
257 SCTAB nTab = getSheetIndex();
258 for (size_t i = 0; i < aRange.size(); ++i)
260 aRange[i].aStart.SetTab(nTab);
261 aRange[i].aEnd.SetTab(nTab);
264 if (maModels.size() > 1)
266 std::sort(maModels.begin(), maModels.end(),
267 [](const ExtCondFormatRuleModel& lhs, const ExtCondFormatRuleModel& rhs) {
268 return lhs.nPriority < rhs.nPriority;
272 if (isPreviousElementF) // sqref can be alone in some cases.
274 for (size_t i = 0; i < maModels.size(); ++i)
276 ScAddress rPos = aRange.GetTopLeftCorner();
277 ScCondFormatEntry* pEntry = new ScCondFormatEntry(maModels[i].eOperator, maModels[i].aFormula, "", rDoc,
278 rPos, maModels[i].aStyle, "", "",
279 formula::FormulaGrammar::GRAM_OOXML ,
280 formula::FormulaGrammar::GRAM_OOXML,
281 ScFormatEntry::Type::ExtCondition );
282 maEntries.push_back(std::unique_ptr<ScFormatEntry>(pEntry));
285 assert(maModels.size() == maPriorities.size());
286 maModels.clear();
289 std::vector< std::unique_ptr<ExtCfCondFormat> >& rExtFormats = getCondFormats().importExtCondFormat();
290 rExtFormats.push_back(std::make_unique<ExtCfCondFormat>(aRange, maEntries, &maPriorities));
292 maPriorities.clear();
293 isPreviousElementF = false;
295 break;
296 default:
297 break;
301 ExtLstLocalContext::ExtLstLocalContext( WorksheetContextBase& rFragment, ScDataBarFormatData* pTarget ):
302 WorksheetContextBase(rFragment),
303 mpTarget(pTarget)
307 ContextHandlerRef ExtLstLocalContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
309 switch( getCurrentElement() )
311 case XLS_TOKEN( extLst ):
312 if(nElement == XLS_TOKEN( ext ))
313 return this;
314 else
315 return nullptr;
316 break;
317 case XLS_TOKEN( ext ):
318 if (nElement == XLS14_TOKEN( id ))
319 return this;
320 else
321 return nullptr;
323 return nullptr;
326 void ExtLstLocalContext::onStartElement( const AttributeList& )
328 switch( getCurrentElement() )
330 case XLS14_TOKEN( id ):
331 break;
335 void ExtLstLocalContext::onCharacters( const OUString& rChars )
337 if (getCurrentElement() == XLS14_TOKEN( id ))
339 getExtLst().insert( std::pair< OUString, ScDataBarFormatData*>(rChars, mpTarget) );
343 ExtGlobalContext::ExtGlobalContext( WorksheetContextBase& rFragment ):
344 WorksheetContextBase(rFragment)
348 ContextHandlerRef ExtGlobalContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
350 switch (nElement)
352 case XLS14_TOKEN(conditionalFormatting): return new ExtConditionalFormattingContext(*this);
353 case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this);
355 return this;
358 void ExtGlobalContext::onStartElement( const AttributeList& /*rAttribs*/ )
362 ExtLstGlobalContext::ExtLstGlobalContext( WorksheetFragment& rFragment ):
363 WorksheetContextBase(rFragment)
367 ContextHandlerRef ExtLstGlobalContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
369 if (nElement == XLS_TOKEN( ext ))
370 return new ExtGlobalContext( *this );
372 return this;
375 ExtGlobalWorkbookContext::ExtGlobalWorkbookContext( WorkbookContextBase& rFragment ):
376 WorkbookContextBase(rFragment)
380 ContextHandlerRef ExtGlobalWorkbookContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
382 if (nElement == LOEXT_TOKEN(extCalcPr))
384 ScDocument& rDoc = getScDocument();
385 sal_Int32 nToken = rAttribs.getToken( XML_stringRefSyntax, XML_CalcA1 );
386 ScCalcConfig aCalcConfig = rDoc.GetCalcConfig();
388 switch( nToken )
390 case XML_CalcA1:
391 aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_OOO );
392 break;
393 case XML_ExcelA1:
394 aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_XL_A1 );
395 break;
396 case XML_ExcelR1C1:
397 aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_XL_R1C1 );
398 break;
399 case XML_CalcA1ExcelA1:
400 aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_A1_XL_A1 );
401 break;
402 default:
403 aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_UNSPECIFIED );
404 break;
406 rDoc.SetCalcConfig(aCalcConfig);
409 return this;
412 void ExtGlobalWorkbookContext::onStartElement( const AttributeList& /*rAttribs*/ )
416 ExtLstGlobalWorkbookContext::ExtLstGlobalWorkbookContext( WorkbookFragment& rFragment ):
417 WorkbookContextBase(rFragment)
421 ContextHandlerRef ExtLstGlobalWorkbookContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
423 if (nElement == XLS_TOKEN( ext ))
424 return new ExtGlobalWorkbookContext( *this );
426 return this;
429 } //namespace oox::xls
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */