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( negativeFillColor ):
60 {
62 xRule->importNegativeFillColor( rAttribs );
63 break;
64 }
65 case XLS14_TOKEN( axisColor ):
66 {
68 xRule->importAxisColor( rAttribs );
69 break;
70 }
71 case XLS14_TOKEN( cfvo ):
72 {
74 xRule->importCfvo( rAttribs );
75 xRule->getModel().mbIsLower = mbFirstEntry;
76 mbFirstEntry = false;
77 break;
78 }
79 default:
80 break;
81 }
82}
83
84namespace {
85 bool IsSpecificTextCondMode(ScConditionMode eMode)
86 {
87 switch (eMode)
88 {
93 return true;
94 default:
95 break;
96 }
97 return false;
98 }
99}
100
102 : WorksheetContextBase(rFragment)
103 , nFormulaCount(0)
104 , nPriority(-1)
105 , eOperator(ScConditionMode::NONE)
106 , isPreviousElementF(false)
107{
108}
109
111{
112 if (mpCurrentRule)
113 {
114 ScFormatEntry& rFormat = **maEntries.rbegin();
115 assert(rFormat.GetType() == ScFormatEntry::Type::Iconset);
116 ScIconSetFormat& rIconSet = static_cast<ScIconSetFormat&>(rFormat);
117 ScDocument& rDoc = getScDocument();
118 SCTAB nTab = getSheetIndex();
119 ScAddress aPos(0, 0, nTab);
120 mpCurrentRule->SetData(&rIconSet, &rDoc, aPos);
121 mpCurrentRule.reset();
122 }
123 if (nElement == XLS14_TOKEN(cfRule))
124 {
125 OUString aType = rAttribs.getString(XML_type, OUString());
126 OUString aId = rAttribs.getString(XML_id, OUString());
127 nPriority = rAttribs.getInteger( XML_priority, -1 );
128 maPriorities.push_back(nPriority);
130
131 if (aType == "dataBar")
132 {
133 // an ext entry does not need to have an existing corresponding entry
134 ExtLst::const_iterator aExt = getExtLst().find( aId );
135 if(aExt == getExtLst().end())
136 return nullptr;
137
138 ScDataBarFormatData* pInfo = aExt->second;
139 if (!pInfo)
140 {
141 return nullptr;
142 }
143 return new ExtCfRuleContext( *this, pInfo );
144 }
145 else if (aType == "iconSet")
146 {
147 ScDocument& rDoc = getScDocument();
148 mpCurrentRule.reset(new IconSetRule(*this));
149 maEntries.push_back(std::make_unique<ScIconSetFormat>(&rDoc));
150 return new IconSetContext(*this, mpCurrentRule.get());
151 }
152 else if (aType == "cellIs")
153 {
154 sal_Int32 aToken = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID );
157 return this;
158 }
159 else if (aType == "containsText")
160 {
163 return this;
164 }
165 else if (aType == "notContainsText")
166 {
169 return this;
170 }
171 else if (aType == "beginsWith")
172 {
175 return this;
176 }
177 else if (aType == "endsWith")
178 {
181 return this;
182 }
183 else if (aType == "expression")
184 {
187 return this;
188 }
189 else
190 {
191 SAL_WARN("sc", "unhandled XLS14_TOKEN(cfRule) with type: " << aType);
192 }
193 }
194 else if (nElement == XLS14_TOKEN( dxf ))
195 {
196 return new DxfContext( *this, getStyles().createExtDxf() );
197 }
198 else if (nElement == XM_TOKEN( sqref ) || nElement == XM_TOKEN( f ))
199 {
200 if(nElement == XM_TOKEN( f ))
202 return this;
203 }
204
205 return nullptr;
206}
207
209{
210}
211
212void ExtConditionalFormattingContext::onCharacters(const OUString& rCharacters)
213{
214 switch (getCurrentElement())
215 {
216 case XM_TOKEN(f):
217 {
218 aChars = rCharacters;
219 isPreviousElementF = true;
220 }
221 break;
222 case XM_TOKEN(sqref):
223 {
224 aChars = rCharacters;
225 }
226 break;
227 }
228
229}
230
232{
233 switch (getCurrentElement())
234 {
235 case XM_TOKEN(f):
236 {
237 if(!IsSpecificTextCondMode(eOperator) || nFormulaCount == 2)
239 }
240 break;
241 case XLS14_TOKEN( cfRule ):
242 {
245 rStyleIdx++;
246 nFormulaCount = 0;
247 maModels.push_back(maModel);
248 }
249 break;
250 case XM_TOKEN(sqref):
251 {
252 ScRangeList aRange;
253 ScDocument& rDoc = getScDocument();
255 if (!bSuccess || aRange.empty())
256 break;
257
258 SCTAB nTab = getSheetIndex();
259 for (size_t i = 0; i < aRange.size(); ++i)
260 {
261 aRange[i].aStart.SetTab(nTab);
262 aRange[i].aEnd.SetTab(nTab);
263 }
264
265 if (maModels.size() > 1)
266 {
267 std::sort(maModels.begin(), maModels.end(),
268 [](const ExtCondFormatRuleModel& lhs, const ExtCondFormatRuleModel& rhs) {
269 return lhs.nPriority < rhs.nPriority;
270 });
271 }
272
273 if (isPreviousElementF) // sqref can be alone in some cases.
274 {
275 for (size_t i = 0; i < maModels.size(); ++i)
276 {
277 ScAddress rPos = aRange.GetTopLeftCorner();
278 ScCondFormatEntry* pEntry = new ScCondFormatEntry(maModels[i].eOperator, maModels[i].aFormula, "", rDoc,
279 rPos, maModels[i].aStyle, "", "",
283 maEntries.push_back(std::unique_ptr<ScFormatEntry>(pEntry));
284 }
285
286 assert(maPriorities.size() >= maModels.size());
287 maModels.clear();
288 }
289
290 std::vector< std::unique_ptr<ExtCfCondFormat> >& rExtFormats = getCondFormats().importExtCondFormat();
291 rExtFormats.push_back(std::make_unique<ExtCfCondFormat>(aRange, maEntries, &maPriorities));
292
293 maPriorities.clear();
294 isPreviousElementF = false;
295 }
296 break;
297 default:
298 break;
299 }
300}
301
303 WorksheetContextBase(rFragment),
304 mpTarget(pTarget)
305{
306}
307
309{
310 switch( getCurrentElement() )
311 {
312 case XLS_TOKEN( extLst ):
313 if(nElement == XLS_TOKEN( ext ))
314 return this;
315 else
316 return nullptr;
317 case XLS_TOKEN( ext ):
318 if (nElement == XLS14_TOKEN( id ))
319 return this;
320 else
321 return nullptr;
322 }
323 return nullptr;
324}
325
327{
328 switch( getCurrentElement() )
329 {
330 case XLS14_TOKEN( id ):
331 break;
332 }
333}
334
335void ExtLstLocalContext::onCharacters( const OUString& rChars )
336{
337 if (getCurrentElement() == XLS14_TOKEN( id ))
338 {
339 getExtLst().insert( std::pair< OUString, ScDataBarFormatData*>(rChars, mpTarget) );
340 }
341}
342
344 WorksheetContextBase(rFragment)
345{
346}
347
348ContextHandlerRef ExtGlobalContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
349{
350 switch (nElement)
351 {
352 case XLS14_TOKEN(conditionalFormatting): return new ExtConditionalFormattingContext(*this);
353 case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this);
354 case XLS14_TOKEN(sparklineGroups): return new SparklineGroupsContext(*this);
355 }
356 return this;
357}
358
360{
361}
362
364 WorksheetContextBase(rFragment)
365{
366}
367
369{
370 if (nElement == XLS_TOKEN( ext ))
371 return new ExtGlobalContext( *this );
372
373 return this;
374}
375
377 WorkbookContextBase(rFragment)
378{
379}
380
382{
383 if (nElement == LOEXT_TOKEN(extCalcPr))
384 {
385 ScDocument& rDoc = getScDocument();
386 sal_Int32 nToken = rAttribs.getToken( XML_stringRefSyntax, XML_CalcA1 );
387 ScCalcConfig aCalcConfig = rDoc.GetCalcConfig();
388
389 switch( nToken )
390 {
391 case XML_CalcA1:
393 break;
394 case XML_ExcelA1:
396 break;
397 case XML_ExcelR1C1:
399 break;
400 case XML_CalcA1ExcelA1:
402 break;
403 default:
405 break;
406 }
407 rDoc.SetCalcConfig(aCalcConfig);
408 }
409
410 return this;
411}
412
414{
415}
416
418 WorkbookContextBase(rFragment)
419{
420}
421
423{
424 if (nElement == XLS_TOKEN( ext ))
425 return new ExtGlobalWorkbookContext( *this );
426
427 return this;
428}
429
430} //namespace oox::xls
431
432/* 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)
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 onStartElement(const AttributeList &rAttribs) override
ExtCfRuleContext(WorksheetContextBase &rFragment, ScDataBarFormatData *pDataBar)
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
A single ext entry.
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