1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <sal/config.h>
12 #include <string_view>
15 #include <xeextlst.hxx>
17 #include <xestyle.hxx>
18 #include <stlpool.hxx>
19 #include <scitems.hxx>
20 #include <svl/itemset.hxx>
21 #include <svl/intitem.hxx>
23 #include <oox/export/utils.hxx>
24 #include <oox/token/namespaces.hxx>
26 using namespace ::oox
;
28 XclExpExt::XclExpExt( const XclExpRoot
& rRoot
):
33 XclExtLst::XclExtLst( const XclExpRoot
& rRoot
):
38 XclExpExtNegativeColor::XclExpExtNegativeColor( const Color
& rColor
):
43 void XclExpExtNegativeColor::SaveXml( XclExpXmlStream
& rStrm
)
45 rStrm
.GetCurrentStream()->singleElementNS( XML_x14
, XML_negativeFillColor
,
46 XML_rgb
, XclXmlUtils::ToOString(maColor
) );
49 XclExpExtAxisColor::XclExpExtAxisColor( const Color
& rColor
):
54 void XclExpExtAxisColor::SaveXml( XclExpXmlStream
& rStrm
)
56 rStrm
.GetCurrentStream()->singleElementNS( XML_x14
, XML_axisColor
,
57 XML_rgb
, XclXmlUtils::ToOString(maAxisColor
) );
60 XclExpExtIcon::XclExpExtIcon(const XclExpRoot
& rRoot
, const std::pair
<ScIconSetType
, sal_Int32
>& rCustomEntry
):
62 nIndex(rCustomEntry
.second
)
64 maIconSetName
= ScIconSetFormat::getIconSetName(rCustomEntry
.first
);
67 void XclExpExtIcon::SaveXml(XclExpXmlStream
& rStrm
)
69 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
74 maIconSetName
= u
"NoIcons"_ustr
;
77 rWorksheet
->singleElementNS(XML_x14
, XML_cfIcon
,
78 XML_iconSet
, maIconSetName
,
79 XML_iconId
, OString::number(nIndex
));
82 XclExpExtCfvo::XclExpExtCfvo( const XclExpRoot
& rRoot
, const ScColorScaleEntry
& rEntry
, const ScAddress
& rSrcPos
, bool bFirst
):
84 meType(rEntry
.GetType()),
87 if( rEntry
.GetType() == COLORSCALE_FORMULA
)
89 const ScTokenArray
* pArr
= rEntry
.GetFormula();
93 aFormula
= XclXmlUtils::ToOUString( GetCompileFormulaContext(), rSrcPos
, pArr
);
95 maValue
= OUStringToOString(aFormula
, RTL_TEXTENCODING_UTF8
);
98 maValue
= OString::number(rEntry
.GetValue());
103 const char* getColorScaleType( ScColorScaleEntryType eType
, bool bFirst
)
111 case COLORSCALE_PERCENT
:
113 case COLORSCALE_FORMULA
:
115 case COLORSCALE_AUTO
:
120 case COLORSCALE_PERCENTILE
:
130 void XclExpExtCfvo::SaveXml( XclExpXmlStream
& rStrm
)
132 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
133 rWorksheet
->startElementNS(XML_x14
, XML_cfvo
, XML_type
, getColorScaleType(meType
, mbFirst
));
135 if (meType
== COLORSCALE_FORMULA
||
136 meType
== COLORSCALE_PERCENT
||
137 meType
== COLORSCALE_PERCENTILE
||
138 meType
== COLORSCALE_VALUE
)
140 rWorksheet
->startElementNS(XML_xm
, XML_f
);
141 rWorksheet
->writeEscaped(maValue
.getStr());
142 rWorksheet
->endElementNS(XML_xm
, XML_f
);
145 rWorksheet
->endElementNS(XML_x14
, XML_cfvo
);
148 XclExpExtCF::XclExpExtCF( const XclExpRoot
& rRoot
, const ScCondFormatEntry
& rFormat
):
156 bool RequiresFixedFormula(ScConditionMode eMode
)
160 case ScConditionMode::BeginsWith
:
161 case ScConditionMode::EndsWith
:
162 case ScConditionMode::ContainsText
:
163 case ScConditionMode::NotContainsText
:
172 OString
GetFixedFormula(ScConditionMode eMode
, const ScAddress
& rAddress
, std::string_view rText
)
174 OStringBuffer aBuffer
;
175 XclXmlUtils::ToOString(aBuffer
, rAddress
);
176 OString aPos
= aBuffer
.makeStringAndClear();
179 case ScConditionMode::BeginsWith
:
180 return OString("LEFT(" + aPos
+ ",LEN(" + rText
+ "))=" + rText
);
181 case ScConditionMode::EndsWith
:
182 return OString("RIGHT(" + aPos
+ ",LEN(" + rText
+ "))=" + rText
);
183 case ScConditionMode::ContainsText
:
184 return OString(OString::Concat("NOT(ISERROR(SEARCH(") + rText
+ "," + aPos
+ ")))");
185 case ScConditionMode::NotContainsText
:
186 return OString(OString::Concat("ISERROR(SEARCH(") + rText
+ "," + aPos
+ "))");
196 void XclExpExtCF::SaveXml( XclExpXmlStream
& rStrm
)
198 OUString aStyleName
= mrFormat
.GetStyle();
199 SfxStyleSheetBasePool
* pPool
= GetDoc().GetStyleSheetPool();
200 SfxStyleSheetBase
* pStyle
= pPool
->Find(aStyleName
, SfxStyleFamily::Para
);
201 SfxItemSet
& rSet
= pStyle
->GetItemSet();
203 std::unique_ptr
<ScTokenArray
> pTokenArray(mrFormat
.CreateFlatCopiedTokenArray(0));
204 aFormula
= XclXmlUtils::ToOUString( GetCompileFormulaContext(), mrFormat
.GetValidSrcPos(), pTokenArray
.get());
206 std::unique_ptr
<XclExpColor
> pColor(new XclExpColor
);
207 if(!pColor
->FillFromItemSet( rSet
))
210 std::unique_ptr
<XclExpCellBorder
> pBorder(new XclExpCellBorder
);
211 if (!pBorder
->FillFromItemSet( rSet
, GetPalette(), GetBiff()) )
214 std::unique_ptr
<XclExpCellAlign
> pAlign(new XclExpCellAlign
);
215 if (!pAlign
->FillFromItemSet(*this, rSet
, false, GetBiff()))
218 std::unique_ptr
<XclExpCellProt
> pCellProt(new XclExpCellProt
);
219 if (!pCellProt
->FillFromItemSet( rSet
))
222 std::unique_ptr
<XclExpDxfFont
> pFont(new XclExpDxfFont(GetRoot(), rSet
));
224 std::unique_ptr
<XclExpNumFmt
> pNumFormat
;
225 if( const SfxUInt32Item
* pPoolItem
= rSet
.GetItemIfSet( ATTR_VALUE_FORMAT
) )
227 sal_uInt32 nScNumFmt
= pPoolItem
->GetValue();
228 XclExpNumFmtBuffer
& rNumFmtBuffer
= GetRoot().GetNumFmtBuffer();
229 sal_uInt32 nXclNumFmt
= rNumFmtBuffer
.Insert(nScNumFmt
);
230 pNumFormat
.reset(new XclExpNumFmt(nScNumFmt
, nXclNumFmt
, rNumFmtBuffer
.GetFormatCode(nScNumFmt
)));
233 XclExpDxf
rDxf( GetRoot(),
237 std::move(pNumFormat
),
238 std::move(pCellProt
),
241 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
243 ScConditionMode eOperation
= mrFormat
.GetOperation();
244 if (RequiresFixedFormula(eOperation
))
246 ScAddress aFixedFormulaPos
= mrFormat
.GetValidSrcPos();
247 OString aFixedFormulaText
= aFormula
.toUtf8();
248 OString aFixedFormula
= GetFixedFormula(eOperation
, aFixedFormulaPos
, aFixedFormulaText
);
249 rWorksheet
->startElementNS( XML_xm
, XML_f
);
250 rWorksheet
->writeEscaped(aFixedFormula
.getStr());
251 rWorksheet
->endElementNS( XML_xm
, XML_f
);
253 rWorksheet
->startElementNS( XML_xm
, XML_f
);
254 rWorksheet
->writeEscaped( aFormula
);
255 rWorksheet
->endElementNS( XML_xm
, XML_f
);
256 rDxf
.SaveXmlExt(rStrm
);
260 rWorksheet
->startElementNS(XML_xm
, XML_f
);
261 rWorksheet
->writeEscaped(aFormula
);
262 rWorksheet
->endElementNS(XML_xm
, XML_f
);
263 rDxf
.SaveXmlExt(rStrm
);
267 XclExpExtDataBar::XclExpExtDataBar( const XclExpRoot
& rRoot
, const ScDataBarFormat
& rFormat
, const ScAddress
& rPos
):
270 const ScDataBarFormatData
& rFormatData
= *rFormat
.GetDataBarData();
271 mpLowerLimit
.reset(new XclExpExtCfvo(*this, *rFormatData
.mpLowerLimit
, rPos
, true));
272 mpUpperLimit
.reset(new XclExpExtCfvo(*this, *rFormatData
.mpUpperLimit
, rPos
, false));
273 if (rFormatData
.mxNegativeColor
)
274 mpNegativeColor
.reset(new XclExpExtNegativeColor(*rFormatData
.mxNegativeColor
));
276 mpNegativeColor
.reset( new XclExpExtNegativeColor( rFormatData
.maPositiveColor
) );
277 mpAxisColor
.reset( new XclExpExtAxisColor( rFormatData
.maAxisColor
) );
279 meAxisPosition
= rFormatData
.meAxisPosition
;
280 mbGradient
= rFormatData
.mbGradient
;
281 mnMinLength
= rFormatData
.mnMinLength
;
282 mnMaxLength
= rFormatData
.mnMaxLength
;
287 const char* getAxisPosition(databar::ScAxisPosition eAxisPosition
)
289 switch(eAxisPosition
)
293 case databar::AUTOMATIC
:
295 case databar::MIDDLE
:
301 const char* GetOperatorString(ScConditionMode eMode
)
303 const char* pRet
= nullptr;
306 case ScConditionMode::Equal
:
309 case ScConditionMode::Less
:
312 case ScConditionMode::Greater
:
313 pRet
= "greaterThan";
315 case ScConditionMode::EqLess
:
316 pRet
= "lessThanOrEqual";
318 case ScConditionMode::EqGreater
:
319 pRet
= "greaterThanOrEqual";
321 case ScConditionMode::NotEqual
:
324 case ScConditionMode::Between
:
327 case ScConditionMode::NotBetween
:
330 case ScConditionMode::Duplicate
:
331 case ScConditionMode::NotDuplicate
:
334 case ScConditionMode::BeginsWith
:
337 case ScConditionMode::EndsWith
:
340 case ScConditionMode::ContainsText
:
341 pRet
= "containsText";
343 case ScConditionMode::NotContainsText
:
344 pRet
= "notContains";
346 case ScConditionMode::Direct
:
348 case ScConditionMode::NONE
:
355 const char* GetTypeString(ScConditionMode eMode
)
359 case ScConditionMode::Direct
:
361 case ScConditionMode::BeginsWith
:
363 case ScConditionMode::EndsWith
:
365 case ScConditionMode::ContainsText
:
366 return "containsText";
367 case ScConditionMode::NotContainsText
:
368 return "notContainsText";
376 void XclExpExtDataBar::SaveXml( XclExpXmlStream
& rStrm
)
378 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
379 rWorksheet
->startElementNS( XML_x14
, XML_dataBar
,
380 XML_minLength
, OString::number(mnMinLength
),
381 XML_maxLength
, OString::number(mnMaxLength
),
382 XML_axisPosition
, getAxisPosition(meAxisPosition
),
383 XML_gradient
, ToPsz(mbGradient
) );
385 mpLowerLimit
->SaveXml( rStrm
);
386 mpUpperLimit
->SaveXml( rStrm
);
387 mpNegativeColor
->SaveXml( rStrm
);
388 mpAxisColor
->SaveXml( rStrm
);
390 rWorksheet
->endElementNS( XML_x14
, XML_dataBar
);
393 XclExpExtIconSet::XclExpExtIconSet(const XclExpRoot
& rRoot
, const ScIconSetFormat
& rFormat
, const ScAddress
& rPos
):
396 const ScIconSetFormatData
& rData
= *rFormat
.GetIconSetData();
397 for (auto const& itr
: rData
.m_Entries
)
399 maCfvos
.AppendNewRecord(new XclExpExtCfvo(*this, *itr
, rPos
, false));
401 mbCustom
= rData
.mbCustom
;
402 mbReverse
= rData
.mbReverse
;
403 mbShowValue
= rData
.mbShowValue
;
404 maIconSetName
= ScIconSetFormat::getIconSetName(rData
.eIconSetType
);
408 for (const auto& rItem
: rData
.maCustomVector
)
410 maCustom
.AppendNewRecord(new XclExpExtIcon(*this, rItem
));
415 void XclExpExtIconSet::SaveXml(XclExpXmlStream
& rStrm
)
417 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
419 rWorksheet
->startElementNS(XML_x14
, XML_iconSet
,
420 XML_iconSet
, maIconSetName
,
421 XML_custom
, sax_fastparser::UseIf(ToPsz10(mbCustom
), mbCustom
),
422 XML_reverse
, ToPsz10(mbReverse
),
423 XML_showValue
, ToPsz10(mbShowValue
));
425 maCfvos
.SaveXml(rStrm
);
429 maCustom
.SaveXml(rStrm
);
432 rWorksheet
->endElementNS(XML_x14
, XML_iconSet
);
435 XclExpExtCfRule::XclExpExtCfRule( const XclExpRoot
& rRoot
, const ScFormatEntry
& rFormat
, const ScAddress
& rPos
, OString aId
, sal_Int32 nPriority
):
437 maId(std::move(aId
)),
439 mnPriority(nPriority
),
442 switch (rFormat
.GetType())
444 case ScFormatEntry::Type::Databar
:
446 const ScDataBarFormat
& rDataBar
= static_cast<const ScDataBarFormat
&>(rFormat
);
447 mxEntry
= new XclExpExtDataBar( *this, rDataBar
, rPos
);
451 case ScFormatEntry::Type::Iconset
:
453 const ScIconSetFormat
& rIconSet
= static_cast<const ScIconSetFormat
&>(rFormat
);
454 mxEntry
= new XclExpExtIconSet(*this, rIconSet
, rPos
);
458 case ScFormatEntry::Type::ExtCondition
:
460 const ScCondFormatEntry
& rCondFormat
= static_cast<const ScCondFormatEntry
&>(rFormat
);
461 mxEntry
= new XclExpExtCF(*this, rCondFormat
);
462 pType
= GetTypeString(rCondFormat
.GetOperation());
463 mOperator
= GetOperatorString( rCondFormat
.GetOperation() );
471 void XclExpExtCfRule::SaveXml( XclExpXmlStream
& rStrm
)
476 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
477 rWorksheet
->startElementNS( XML_x14
, XML_cfRule
,
479 XML_priority
, sax_fastparser::UseIf(OString::number(mnPriority
+ 1), mnPriority
!= -1),
480 XML_operator
, mOperator
,
483 mxEntry
->SaveXml( rStrm
);
485 rWorksheet
->endElementNS( XML_x14
, XML_cfRule
);
489 XclExpExtConditionalFormatting::XclExpExtConditionalFormatting( const XclExpRoot
& rRoot
,
490 std::vector
<XclExpExtCondFormatData
>& rData
, ScRangeList aRange
):
492 maRange(std::move(aRange
))
494 ScAddress aAddr
= maRange
.front().aStart
;
495 for (const auto& rItem
: rData
)
497 const ScFormatEntry
* pEntry
= rItem
.pEntry
;
498 switch (pEntry
->GetType())
500 case ScFormatEntry::Type::Iconset
:
502 const ScIconSetFormat
& rIconSet
= static_cast<const ScIconSetFormat
&>(*pEntry
);
503 bool bNeedsExt
= false;
504 switch (rIconSet
.GetIconSetData()->eIconSetType
)
506 case IconSet_3Triangles
:
507 case IconSet_3Smilies
:
508 case IconSet_3ColorSmilies
:
517 if (rIconSet
.GetIconSetData()->mbCustom
)
522 maCfRules
.AppendNewRecord(new XclExpExtCfRule(*this, *pEntry
, aAddr
, rItem
.aGUID
, rItem
.nPriority
));
526 case ScFormatEntry::Type::Databar
:
527 case ScFormatEntry::Type::ExtCondition
:
528 maCfRules
.AppendNewRecord(new XclExpExtCfRule( *this, *pEntry
, aAddr
, rItem
.aGUID
, rItem
.nPriority
));
536 void XclExpExtConditionalFormatting::SaveXml( XclExpXmlStream
& rStrm
)
538 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
539 rWorksheet
->startElementNS( XML_x14
, XML_conditionalFormatting
,
540 FSNS( XML_xmlns
, XML_xm
), rStrm
.getNamespaceURL(OOX_NS(xm
)) );
542 maCfRules
.SaveXml( rStrm
);
543 rWorksheet
->startElementNS(XML_xm
, XML_sqref
);
544 rWorksheet
->write(XclXmlUtils::ToOString(rStrm
.GetRoot().GetDoc(), maRange
));
546 rWorksheet
->endElementNS( XML_xm
, XML_sqref
);
548 rWorksheet
->endElementNS( XML_x14
, XML_conditionalFormatting
);
551 XclExpExtCalcPr::XclExpExtCalcPr( const XclExpRoot
& rRoot
, formula::FormulaGrammar::AddressConvention eConv
):
554 maURI
= "{7626C862-2A13-11E5-B345-FEFF819CDC9F}"_ostr
;
558 case formula::FormulaGrammar::CONV_OOO
:
559 maSyntax
= "CalcA1"_ostr
;
561 case formula::FormulaGrammar::CONV_XL_A1
:
562 maSyntax
= "ExcelA1"_ostr
;
564 case formula::FormulaGrammar::CONV_XL_R1C1
:
565 maSyntax
= "ExcelR1C1"_ostr
;
567 case formula::FormulaGrammar::CONV_A1_XL_A1
:
568 maSyntax
= "CalcA1ExcelA1"_ostr
;
570 case formula::FormulaGrammar::CONV_UNSPECIFIED
:
571 case formula::FormulaGrammar::CONV_ODF
:
572 case formula::FormulaGrammar::CONV_XL_OOX
:
573 case formula::FormulaGrammar::CONV_LOTUS_A1
:
574 case formula::FormulaGrammar::CONV_LAST
:
575 maSyntax
= "Unspecified"_ostr
;
580 void XclExpExtCalcPr::SaveXml( XclExpXmlStream
& rStrm
)
582 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
583 rWorksheet
->startElement( XML_ext
,
584 FSNS(XML_xmlns
, XML_loext
), rStrm
.getNamespaceURL(OOX_NS(loext
)),
587 rWorksheet
->singleElementNS(XML_loext
, XML_extCalcPr
, XML_stringRefSyntax
, maSyntax
);
589 rWorksheet
->endElement( XML_ext
);
592 XclExpExtCondFormat::XclExpExtCondFormat( const XclExpRoot
& rRoot
):
595 maURI
= "{78C0D931-6437-407d-A8EE-F0AAD7539E65}"_ostr
;
598 void XclExpExtCondFormat::SaveXml( XclExpXmlStream
& rStrm
)
600 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
601 rWorksheet
->startElement( XML_ext
,
602 FSNS(XML_xmlns
, XML_x14
), rStrm
.getNamespaceURL(OOX_NS(xls14Lst
)),
605 rWorksheet
->startElementNS(XML_x14
, XML_conditionalFormattings
);
607 maCF
.SaveXml( rStrm
);
609 rWorksheet
->endElementNS( XML_x14
, XML_conditionalFormattings
);
610 rWorksheet
->endElement( XML_ext
);
613 void XclExpExtCondFormat::AddRecord( XclExpExtConditionalFormatting
* pEntry
)
615 maCF
.AppendRecord( pEntry
);
618 void XclExtLst::SaveXml( XclExpXmlStream
& rStrm
)
620 if(maExtEntries
.IsEmpty())
623 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
624 rWorksheet
->startElement(XML_extLst
);
626 maExtEntries
.SaveXml(rStrm
);
628 rWorksheet
->endElement( XML_extLst
);
631 void XclExtLst::AddRecord( XclExpExt
* pEntry
)
633 maExtEntries
.AppendRecord( pEntry
);
636 XclExpExt
* XclExtLst::GetItem( XclExpExtType eType
)
638 size_t n
= maExtEntries
.GetSize();
639 for( size_t i
= 0; i
< n
; ++i
)
641 if (maExtEntries
.GetRecord( i
)->GetType() == eType
)
642 return maExtEntries
.GetRecord( i
);
649 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */