LibreOffice Module sc (master) 1
extlstcontext.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 */
9
10#include <memory>
11#include <extlstcontext.hxx>
12#include <worksheethelper.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>
25#include <SparklineFragment.hxx>
26
27#include <rangeutl.hxx>
28#include <sal/log.hxx>
29
30using ::oox::core::ContextHandlerRef;
31using ::oox::xls::CondFormatBuffer;
32
33sal_Int32 rStyleIdx = 0;
34
35namespace oox::xls {
36
38 WorksheetContextBase( rFragment ),
39 mpTarget( pTarget ),
40 mbFirstEntry(true)
41{
42}
43
45{
46 return this;
47}
48
50{
51 switch( getCurrentElement() )
52 {
53 case XLS14_TOKEN( dataBar ):
54 {
56 xRule->importDataBar( rAttribs );
57 break;
58 }
59 case XLS14_TOKEN( fillColor ):
60 {
62 xRule->importPositiveFillColor( rAttribs );
63 break;
64 }
65 case XLS14_TOKEN( negativeFillColor ):
66 {
68 xRule->importNegativeFillColor( rAttribs );
69 break;
70 }
71 case XLS14_TOKEN( axisColor ):
72 {
74 xRule->importAxisColor( rAttribs );
75 break;
76 }
77 case XLS14_TOKEN( cfvo ):
78 {
80 xRule->importCfvo( rAttribs );
81 xRule->getModel().mbIsLower = mbFirstEntry;
82 mbFirstEntry = false;
83 mpRule = xRule;
84 break;
85 }
86 default:
87 break;
88 }
89}
90
91void ExtCfRuleContext::onCharacters( const OUString& rChars )
92{
93 switch( getCurrentElement() )
94 {
95 case XM_TOKEN( f ):
96 {
97 if (mpRule)
98 {
99 mpRule->getModel().msScaleTypeValue = rChars;
100 }
101 }
102 break;
103 }
104}
105
107{
108 switch( getCurrentElement() )
109 {
110 case XLS14_TOKEN( cfvo ):
111 {
112 mpRule.reset();
113 break;
114 }
115 }
116}
117
118namespace {
119 bool IsSpecificTextCondMode(ScConditionMode eMode)
120 {
121 switch (eMode)
122 {
127 return true;
128 default:
129 break;
130 }
131 return false;
132 }
133}
134
136 : WorksheetContextBase(rFragment)
137 , nFormulaCount(0)
138 , nPriority(-1)
139 , eOperator(ScConditionMode::NONE)
140 , isPreviousElementF(false)
141{
142}
143
145{
146 if (mpCurrentRule)
147 {
148 ScFormatEntry& rFormat = **maEntries.rbegin();
149 assert(rFormat.GetType() == ScFormatEntry::Type::Iconset);
150 ScIconSetFormat& rIconSet = static_cast<ScIconSetFormat&>(rFormat);
151 ScDocument& rDoc = getScDocument();
152 SCTAB nTab = getSheetIndex();
153 ScAddress aPos(0, 0, nTab);
154 mpCurrentRule->SetData(&rIconSet, &rDoc, aPos);
155 mpCurrentRule.reset();
156 }
157 if (nElement == XLS14_TOKEN(cfRule))
158 {
159 OUString aType = rAttribs.getString(XML_type, OUString());
160 OUString aId = rAttribs.getString(XML_id, OUString());
161 nPriority = rAttribs.getInteger( XML_priority, -1 );
162 maPriorities.push_back(nPriority);
164
165 if (aType == "dataBar")
166 {
167 // an ext entry does not need to have an existing corresponding entry
168 ScDataBarFormatData* pInfo;
169 ExtLst::const_iterator aExt = getExtLst().find( aId );
170 if (aExt == getExtLst().end())
171 {
172 pInfo = new ScDataBarFormatData();
173 if (pInfo)
174 {
175 auto pFormat = std::make_unique<ScDataBarFormat>(&getScDocument());
176 pFormat->SetDataBarData(pInfo);
177 getCondFormats().importExtFormatEntries().push_back(std::move(pFormat));
178 }
179 }
180 else
181 {
182 pInfo = aExt->second;
183 }
184
185 if (!pInfo)
186 {
187 return nullptr;
188 }
189 return new ExtCfRuleContext( *this, pInfo );
190 }
191 else if (aType == "iconSet")
192 {
193 ScDocument& rDoc = getScDocument();
194 mpCurrentRule.reset(new IconSetRule(*this));
195 maEntries.push_back(std::make_unique<ScIconSetFormat>(&rDoc));
196 return new IconSetContext(*this, mpCurrentRule.get());
197 }
198 else if (aType == "cellIs")
199 {
200 sal_Int32 aToken = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID );
203 return this;
204 }
205 else if (aType == "containsText")
206 {
209 return this;
210 }
211 else if (aType == "notContainsText")
212 {
215 return this;
216 }
217 else if (aType == "beginsWith")
218 {
221 return this;
222 }
223 else if (aType == "endsWith")
224 {
227 return this;
228 }
229 else if (aType == "expression")
230 {
233 return this;
234 }
235 else
236 {
237 SAL_WARN("sc", "unhandled XLS14_TOKEN(cfRule) with type: " << aType);
238 }
239 }
240 else if (nElement == XLS14_TOKEN( dxf ))
241 {
242 return new DxfContext( *this, getStyles().createExtDxf() );
243 }
244 else if (nElement == XM_TOKEN( sqref ) || nElement == XM_TOKEN( f ))
245 {
246 if(nElement == XM_TOKEN( f ))
248 return this;
249 }
250
251 return nullptr;
252}
253
255{
256}
257
258void ExtConditionalFormattingContext::onCharacters(const OUString& rCharacters)
259{
260 switch (getCurrentElement())
261 {
262 case XM_TOKEN(f):
263 {
264 aChars = rCharacters;
265 isPreviousElementF = true;
266 }
267 break;
268 case XM_TOKEN(sqref):
269 {
270 aChars = rCharacters;
271 }
272 break;
273 }
274
275}
276
278{
279 switch (getCurrentElement())
280 {
281 case XM_TOKEN(f):
282 {
283 if(!IsSpecificTextCondMode(eOperator) || nFormulaCount == 2)
285 }
286 break;
287 case XLS14_TOKEN( cfRule ):
288 {
289 if (IsSpecificTextCondMode(maModel.eOperator) && nFormulaCount == 1)
290 {
293 }
294
297 rStyleIdx++;
298 nFormulaCount = 0;
299 maModels.push_back(maModel);
300 }
301 break;
302 case XM_TOKEN(sqref):
303 {
304 ScRangeList aRange;
305 ScDocument& rDoc = getScDocument();
307 if (!bSuccess || aRange.empty())
308 break;
309
310 SCTAB nTab = getSheetIndex();
311 for (size_t i = 0; i < aRange.size(); ++i)
312 {
313 aRange[i].aStart.SetTab(nTab);
314 aRange[i].aEnd.SetTab(nTab);
315 }
316
317 if (maModels.size() > 1)
318 {
319 std::sort(maModels.begin(), maModels.end(),
320 [](const ExtCondFormatRuleModel& lhs, const ExtCondFormatRuleModel& rhs) {
321 return lhs.nPriority < rhs.nPriority;
322 });
323 }
324
325 if (isPreviousElementF) // sqref can be alone in some cases.
326 {
327 for (size_t i = 0; i < maModels.size(); ++i)
328 {
329 ScAddress rPos = aRange.GetTopLeftCorner();
330 ScCondFormatEntry* pEntry = new ScCondFormatEntry(maModels[i].eOperator, maModels[i].aFormula, "", rDoc,
331 rPos, maModels[i].aStyle, "", "",
335 maEntries.push_back(std::unique_ptr<ScFormatEntry>(pEntry));
336 }
337
338 assert(maPriorities.size() >= maModels.size());
339 maModels.clear();
340 }
341
342 std::vector< std::unique_ptr<ExtCfCondFormat> >& rExtFormats = getCondFormats().importExtCondFormat();
343 rExtFormats.push_back(std::make_unique<ExtCfCondFormat>(aRange, maEntries, &maPriorities));
344
345 maPriorities.clear();
346 isPreviousElementF = false;
347 }
348 break;
349 default:
350 break;
351 }
352}
353
355 WorksheetContextBase(rFragment),
356 mpTarget(pTarget)
357{
358}
359
361{
362 switch( getCurrentElement() )
363 {
364 case XLS_TOKEN( extLst ):
365 if(nElement == XLS_TOKEN( ext ))
366 return this;
367 else
368 return nullptr;
369 case XLS_TOKEN( ext ):
370 if (nElement == XLS14_TOKEN( id ))
371 return this;
372 else
373 return nullptr;
374 }
375 return nullptr;
376}
377
379{
380 switch( getCurrentElement() )
381 {
382 case XLS14_TOKEN( id ):
383 break;
384 }
385}
386
387void ExtLstLocalContext::onCharacters( const OUString& rChars )
388{
389 if (getCurrentElement() == XLS14_TOKEN( id ))
390 {
391 getExtLst().insert( std::pair< OUString, ScDataBarFormatData*>(rChars, mpTarget) );
392 }
393}
394
396 WorksheetContextBase(rFragment)
397{
398}
399
400ContextHandlerRef ExtGlobalContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
401{
402 switch (nElement)
403 {
404 case XLS14_TOKEN(conditionalFormatting): return new ExtConditionalFormattingContext(*this);
405 case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this);
406 case XLS14_TOKEN(sparklineGroups): return new SparklineGroupsContext(*this);
407 }
408 return this;
409}
410
412{
413}
414
416 WorksheetContextBase(rFragment)
417{
418}
419
421{
422 if (nElement == XLS_TOKEN( ext ))
423 return new ExtGlobalContext( *this );
424
425 return this;
426}
427
429 WorkbookContextBase(rFragment)
430{
431}
432
434{
435 if (nElement == LOEXT_TOKEN(extCalcPr))
436 {
437 ScDocument& rDoc = getScDocument();
438 sal_Int32 nToken = rAttribs.getToken( XML_stringRefSyntax, XML_CalcA1 );
439 ScCalcConfig aCalcConfig = rDoc.GetCalcConfig();
440
441 switch( nToken )
442 {
443 case XML_CalcA1:
445 break;
446 case XML_ExcelA1:
448 break;
449 case XML_ExcelR1C1:
451 break;
452 case XML_CalcA1ExcelA1:
454 break;
455 default:
457 break;
458 }
459 rDoc.SetCalcConfig(aCalcConfig);
460 }
461
462 return this;
463}
464
466{
467}
468
470 WorkbookContextBase(rFragment)
471{
472}
473
475{
476 if (nElement == XLS_TOKEN( ext ))
477 return new ExtGlobalWorkbookContext( *this );
478
479 return this;
480}
481
482} //namespace oox::xls
483
484/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const ScCalcConfig & GetCalcConfig() const
Definition: document.hxx:2619
SC_DLLPUBLIC void SetCalcConfig(const ScCalcConfig &rConfig)
Definition: document10.cxx:205
virtual Type GetType() const =0
ScAddress GetTopLeftCorner() const
Definition: rangelst.cxx:1150
bool empty() const
Definition: rangelst.hxx:88
size_t size() const
Definition: rangelst.hxx:89
static bool GetRangeListFromString(ScRangeList &rRangeList, std::u16string_view rRangeListStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator=' ', sal_Unicode cQuote='\'')
Definition: rangeutl.cxx:552
std::optional< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
std::optional< OUString > getString(sal_Int32 nAttrToken) const
std::optional< sal_Int32 > getToken(sal_Int32 nAttrToken) const
void forEachMem(FuncType pFunc) const
std::vector< std::unique_ptr< ExtCfCondFormat > > & importExtCondFormat()
ExtCfDataBarRuleRef createExtCfDataBarRule(ScDataBarFormatData *pTarget)
std::vector< std::unique_ptr< ScFormatEntry > > & importExtFormatEntries()
static ScConditionMode convertToInternalOperator(sal_Int32 nToken)
void finalizeImport()
Final processing after import of all style settings.
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
ScDataBarFormatData * mpTarget
virtual void onEndElement() override
virtual void onStartElement(const AttributeList &rAttribs) override
ExtCfDataBarRuleRef mpRule
ExtCfRuleContext(WorksheetContextBase &rFragment, ScDataBarFormatData *pDataBar)
virtual void onCharacters(const OUString &rChars) override
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
virtual void onStartElement(const AttributeList &rAttribs) override
std::vector< std::unique_ptr< ScFormatEntry > > maEntries
std::unique_ptr< IconSetRule > mpCurrentRule
virtual void onCharacters(const OUString &rCharacters) override
ExtConditionalFormattingContext(WorksheetContextBase &rFragment)
std::vector< ExtCondFormatRuleModel > maModels
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
virtual void onStartElement(const AttributeList &rAttribs) override
ExtGlobalContext(WorksheetContextBase &rFragment)
virtual void onStartElement(const AttributeList &rAttribs) override
ExtGlobalWorkbookContext(WorkbookContextBase &rFragment)
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
ExtLstGlobalContext(WorksheetFragment &rFragment)
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
ExtLstGlobalWorkbookContext(WorkbookFragment &rFragment)
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
virtual void onStartElement(const AttributeList &rAttribs) override
ExtLstLocalContext(WorksheetContextBase &rFragment, ScDataBarFormatData *pTarget)
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
ScDataBarFormatData * mpTarget
virtual void onCharacters(const OUString &rChars) override
Handle import of the sparkline, sparkline group and attributes.
OUString createExtDxfStyle(sal_Int32 nDxfId) const
const RefVector< Dxf > & getExtDxfs() const
Context handler derived from the WorkbookHelper helper class.
StylesBuffer & getStyles() const
Returns all cell formatting objects read from the styles substream.
Context handler derived from the WorksheetHelper helper class.
CondFormatBuffer & getCondFormats() const
Returns the conditional formatting in this sheet.
SCTAB getSheetIndex() const
Returns the index of the current sheet.
ScConditionMode
Definition: conditio.hxx:60
sal_Int32 rStyleIdx
#define SAL_WARN(area, stream)
NONE
int i
std::shared_ptr< ExtCfDataBarRule > ExtCfDataBarRuleRef
end
XML_type
XML_TOKEN_INVALID
DefTokenId nToken
Definition: qproform.cxx:397
T * mpTarget
Configuration options for formula interpreter.
Definition: calcconfig.hxx:44
void SetStringRefSyntax(formula::FormulaGrammar::AddressConvention eConv)
Definition: calcconfig.cxx:163
sal_Int16 SCTAB
Definition: types.hxx:22