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>
14 #include <xeextlst.hxx>
16 #include <xestyle.hxx>
17 #include <stlpool.hxx>
18 #include <scitems.hxx>
19 #include <svl/itemset.hxx>
20 #include <svl/intitem.hxx>
22 #include <oox/export/utils.hxx>
23 #include <oox/token/namespaces.hxx>
25 using namespace ::oox
;
27 XclExpExt::XclExpExt( const XclExpRoot
& rRoot
):
32 XclExtLst::XclExtLst( const XclExpRoot
& rRoot
):
37 XclExpExtNegativeColor::XclExpExtNegativeColor( const Color
& rColor
):
42 void XclExpExtNegativeColor::SaveXml( XclExpXmlStream
& rStrm
)
44 rStrm
.GetCurrentStream()->singleElementNS( XML_x14
, XML_negativeFillColor
,
45 XML_rgb
, XclXmlUtils::ToOString(maColor
) );
48 XclExpExtAxisColor::XclExpExtAxisColor( const Color
& rColor
):
53 void XclExpExtAxisColor::SaveXml( XclExpXmlStream
& rStrm
)
55 rStrm
.GetCurrentStream()->singleElementNS( XML_x14
, XML_axisColor
,
56 XML_rgb
, XclXmlUtils::ToOString(maAxisColor
) );
59 XclExpExtIcon::XclExpExtIcon(const XclExpRoot
& rRoot
, const std::pair
<ScIconSetType
, sal_Int32
>& rCustomEntry
):
61 nIndex(rCustomEntry
.second
)
63 pIconSetName
= ScIconSetFormat::getIconSetName(rCustomEntry
.first
);
66 void XclExpExtIcon::SaveXml(XclExpXmlStream
& rStrm
)
68 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
73 pIconSetName
= "NoIcons";
76 rWorksheet
->singleElementNS(XML_x14
, XML_cfIcon
,
77 XML_iconSet
, pIconSetName
,
78 XML_iconId
, OString::number(nIndex
));
81 XclExpExtCfvo::XclExpExtCfvo( const XclExpRoot
& rRoot
, const ScColorScaleEntry
& rEntry
, const ScAddress
& rSrcPos
, bool bFirst
):
83 meType(rEntry
.GetType()),
86 if( rEntry
.GetType() == COLORSCALE_FORMULA
)
88 const ScTokenArray
* pArr
= rEntry
.GetFormula();
92 aFormula
= XclXmlUtils::ToOUString( GetCompileFormulaContext(), rSrcPos
, pArr
);
94 maValue
= OUStringToOString(aFormula
, RTL_TEXTENCODING_UTF8
);
97 maValue
= OString::number(rEntry
.GetValue());
102 const char* getColorScaleType( ScColorScaleEntryType eType
, bool bFirst
)
110 case COLORSCALE_PERCENT
:
112 case COLORSCALE_FORMULA
:
114 case COLORSCALE_AUTO
:
119 case COLORSCALE_PERCENTILE
:
129 void XclExpExtCfvo::SaveXml( XclExpXmlStream
& rStrm
)
131 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
132 rWorksheet
->startElementNS(XML_x14
, XML_cfvo
, XML_type
, getColorScaleType(meType
, mbFirst
));
134 if (meType
== COLORSCALE_FORMULA
||
135 meType
== COLORSCALE_PERCENT
||
136 meType
== COLORSCALE_PERCENTILE
||
137 meType
== COLORSCALE_VALUE
)
139 rWorksheet
->startElementNS(XML_xm
, XML_f
);
140 rWorksheet
->writeEscaped(maValue
.getStr());
141 rWorksheet
->endElementNS(XML_xm
, XML_f
);
144 rWorksheet
->endElementNS(XML_x14
, XML_cfvo
);
147 XclExpExtCF::XclExpExtCF( const XclExpRoot
& rRoot
, const ScCondFormatEntry
& rFormat
):
155 bool RequiresFixedFormula(ScConditionMode eMode
)
159 case ScConditionMode::BeginsWith
:
160 case ScConditionMode::EndsWith
:
161 case ScConditionMode::ContainsText
:
162 case ScConditionMode::NotContainsText
:
171 OString
GetFixedFormula(ScConditionMode eMode
, const ScAddress
& rAddress
, std::string_view rText
)
173 OStringBuffer aBuffer
;
174 XclXmlUtils::ToOString(aBuffer
, rAddress
);
175 OString aPos
= aBuffer
.makeStringAndClear();
178 case ScConditionMode::BeginsWith
:
179 return OString("LEFT(" + aPos
+ ",LEN(" + rText
+ "))=" + rText
);
180 case ScConditionMode::EndsWith
:
181 return OString("RIGHT(" + aPos
+ ",LEN(" + rText
+ "))=" + rText
);
182 case ScConditionMode::ContainsText
:
183 return OString(OString::Concat("NOT(ISERROR(SEARCH(") + rText
+ "," + aPos
+ ")))");
184 case ScConditionMode::NotContainsText
:
185 return OString(OString::Concat("ISERROR(SEARCH(") + rText
+ "," + aPos
+ "))");
195 void XclExpExtCF::SaveXml( XclExpXmlStream
& rStrm
)
197 OUString aStyleName
= mrFormat
.GetStyle();
198 SfxStyleSheetBasePool
* pPool
= GetDoc().GetStyleSheetPool();
199 SfxStyleSheetBase
* pStyle
= pPool
->Find(aStyleName
, SfxStyleFamily::Para
);
200 SfxItemSet
& rSet
= pStyle
->GetItemSet();
202 std::unique_ptr
<ScTokenArray
> pTokenArray(mrFormat
.CreateFlatCopiedTokenArray(0));
203 aFormula
= XclXmlUtils::ToOUString( GetCompileFormulaContext(), mrFormat
.GetValidSrcPos(), pTokenArray
.get());
205 std::unique_ptr
<XclExpColor
> pColor(new XclExpColor
);
206 if(!pColor
->FillFromItemSet( rSet
))
209 std::unique_ptr
<XclExpCellBorder
> pBorder(new XclExpCellBorder
);
210 if (!pBorder
->FillFromItemSet( rSet
, GetPalette(), GetBiff()) )
213 std::unique_ptr
<XclExpCellAlign
> pAlign(new XclExpCellAlign
);
214 if (!pAlign
->FillFromItemSet(*this, rSet
, false, GetBiff()))
217 std::unique_ptr
<XclExpCellProt
> pCellProt(new XclExpCellProt
);
218 if (!pCellProt
->FillFromItemSet( rSet
))
221 std::unique_ptr
<XclExpDxfFont
> pFont(new XclExpDxfFont(GetRoot(), rSet
));
223 std::unique_ptr
<XclExpNumFmt
> pNumFormat
;
224 const SfxPoolItem
*pPoolItem
= nullptr;
225 if( rSet
.GetItemState( ATTR_VALUE_FORMAT
, true, &pPoolItem
) == SfxItemState::SET
)
227 sal_uInt32 nScNumFmt
= static_cast< const SfxUInt32Item
* >(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
:
333 case ScConditionMode::NotDuplicate
:
336 case ScConditionMode::BeginsWith
:
339 case ScConditionMode::EndsWith
:
342 case ScConditionMode::ContainsText
:
343 pRet
= "containsText";
345 case ScConditionMode::NotContainsText
:
346 pRet
= "notContains";
348 case ScConditionMode::Direct
:
350 case ScConditionMode::NONE
:
357 const char* GetTypeString(ScConditionMode eMode
)
361 case ScConditionMode::Direct
:
363 case ScConditionMode::BeginsWith
:
365 case ScConditionMode::EndsWith
:
367 case ScConditionMode::ContainsText
:
368 return "containsText";
369 case ScConditionMode::NotContainsText
:
370 return "notContainsText";
378 void XclExpExtDataBar::SaveXml( XclExpXmlStream
& rStrm
)
380 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
381 rWorksheet
->startElementNS( XML_x14
, XML_dataBar
,
382 XML_minLength
, OString::number(mnMinLength
),
383 XML_maxLength
, OString::number(mnMaxLength
),
384 XML_axisPosition
, getAxisPosition(meAxisPosition
),
385 XML_gradient
, ToPsz(mbGradient
) );
387 mpLowerLimit
->SaveXml( rStrm
);
388 mpUpperLimit
->SaveXml( rStrm
);
389 mpNegativeColor
->SaveXml( rStrm
);
390 mpAxisColor
->SaveXml( rStrm
);
392 rWorksheet
->endElementNS( XML_x14
, XML_dataBar
);
395 XclExpExtIconSet::XclExpExtIconSet(const XclExpRoot
& rRoot
, const ScIconSetFormat
& rFormat
, const ScAddress
& rPos
):
398 const ScIconSetFormatData
& rData
= *rFormat
.GetIconSetData();
399 for (auto const& itr
: rData
.m_Entries
)
401 maCfvos
.AppendNewRecord(new XclExpExtCfvo(*this, *itr
, rPos
, false));
403 mbCustom
= rData
.mbCustom
;
404 mbReverse
= rData
.mbReverse
;
405 mbShowValue
= rData
.mbShowValue
;
406 mpIconSetName
= ScIconSetFormat::getIconSetName(rData
.eIconSetType
);
410 for (const auto& rItem
: rData
.maCustomVector
)
412 maCustom
.AppendNewRecord(new XclExpExtIcon(*this, rItem
));
417 void XclExpExtIconSet::SaveXml(XclExpXmlStream
& rStrm
)
419 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
421 rWorksheet
->startElementNS(XML_x14
, XML_iconSet
,
422 XML_iconSet
, mpIconSetName
,
423 XML_custom
, sax_fastparser::UseIf(ToPsz10(mbCustom
), mbCustom
),
424 XML_reverse
, ToPsz10(mbReverse
),
425 XML_showValue
, ToPsz10(mbShowValue
));
427 maCfvos
.SaveXml(rStrm
);
431 maCustom
.SaveXml(rStrm
);
434 rWorksheet
->endElementNS(XML_x14
, XML_iconSet
);
437 XclExpExtCfRule::XclExpExtCfRule( const XclExpRoot
& rRoot
, const ScFormatEntry
& rFormat
, const ScAddress
& rPos
, const OString
& rId
, sal_Int32 nPriority
):
441 mnPriority(nPriority
),
444 switch (rFormat
.GetType())
446 case ScFormatEntry::Type::Databar
:
448 const ScDataBarFormat
& rDataBar
= static_cast<const ScDataBarFormat
&>(rFormat
);
449 mxEntry
= new XclExpExtDataBar( *this, rDataBar
, rPos
);
453 case ScFormatEntry::Type::Iconset
:
455 const ScIconSetFormat
& rIconSet
= static_cast<const ScIconSetFormat
&>(rFormat
);
456 mxEntry
= new XclExpExtIconSet(*this, rIconSet
, rPos
);
460 case ScFormatEntry::Type::ExtCondition
:
462 const ScCondFormatEntry
& rCondFormat
= static_cast<const ScCondFormatEntry
&>(rFormat
);
463 mxEntry
= new XclExpExtCF(*this, rCondFormat
);
464 pType
= GetTypeString(rCondFormat
.GetOperation());
465 mOperator
= GetOperatorString( rCondFormat
.GetOperation() );
473 void XclExpExtCfRule::SaveXml( XclExpXmlStream
& rStrm
)
478 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
479 rWorksheet
->startElementNS( XML_x14
, XML_cfRule
,
481 XML_priority
, sax_fastparser::UseIf(OString::number(mnPriority
+ 1), mnPriority
!= -1),
482 XML_operator
, mOperator
,
485 mxEntry
->SaveXml( rStrm
);
487 rWorksheet
->endElementNS( XML_x14
, XML_cfRule
);
491 XclExpExtConditionalFormatting::XclExpExtConditionalFormatting( const XclExpRoot
& rRoot
,
492 std::vector
<XclExpExtCondFormatData
>& rData
, const ScRangeList
& rRange
):
496 ScAddress aAddr
= maRange
.front().aStart
;
497 for (const auto& rItem
: rData
)
499 const ScFormatEntry
* pEntry
= rItem
.pEntry
;
500 switch (pEntry
->GetType())
502 case ScFormatEntry::Type::Iconset
:
504 const ScIconSetFormat
& rIconSet
= static_cast<const ScIconSetFormat
&>(*pEntry
);
505 bool bNeedsExt
= false;
506 switch (rIconSet
.GetIconSetData()->eIconSetType
)
508 case IconSet_3Triangles
:
509 case IconSet_3Smilies
:
510 case IconSet_3ColorSmilies
:
519 if (rIconSet
.GetIconSetData()->mbCustom
)
524 maCfRules
.AppendNewRecord(new XclExpExtCfRule(*this, *pEntry
, aAddr
, rItem
.aGUID
, rItem
.nPriority
));
528 case ScFormatEntry::Type::Databar
:
529 maCfRules
.AppendNewRecord(new XclExpExtCfRule( *this, *pEntry
, aAddr
, rItem
.aGUID
, rItem
.nPriority
));
531 case ScFormatEntry::Type::ExtCondition
:
532 maCfRules
.AppendNewRecord(new XclExpExtCfRule( *this, *pEntry
, aAddr
, rItem
.aGUID
, rItem
.nPriority
));
540 void XclExpExtConditionalFormatting::SaveXml( XclExpXmlStream
& rStrm
)
542 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
543 rWorksheet
->startElementNS( XML_x14
, XML_conditionalFormatting
,
544 FSNS( XML_xmlns
, XML_xm
), rStrm
.getNamespaceURL(OOX_NS(xm
)) );
546 maCfRules
.SaveXml( rStrm
);
547 rWorksheet
->startElementNS(XML_xm
, XML_sqref
);
548 rWorksheet
->write(XclXmlUtils::ToOString(rStrm
.GetRoot().GetDoc(), maRange
));
550 rWorksheet
->endElementNS( XML_xm
, XML_sqref
);
552 rWorksheet
->endElementNS( XML_x14
, XML_conditionalFormatting
);
555 XclExpExtCalcPr::XclExpExtCalcPr( const XclExpRoot
& rRoot
, formula::FormulaGrammar::AddressConvention eConv
):
558 maURI
= OString("{7626C862-2A13-11E5-B345-FEFF819CDC9F}");
562 case formula::FormulaGrammar::CONV_OOO
:
563 maSyntax
= OString("CalcA1");
565 case formula::FormulaGrammar::CONV_XL_A1
:
566 maSyntax
= OString("ExcelA1");
568 case formula::FormulaGrammar::CONV_XL_R1C1
:
569 maSyntax
= OString("ExcelR1C1");
571 case formula::FormulaGrammar::CONV_A1_XL_A1
:
572 maSyntax
= OString("CalcA1ExcelA1");
574 case formula::FormulaGrammar::CONV_UNSPECIFIED
:
575 case formula::FormulaGrammar::CONV_ODF
:
576 case formula::FormulaGrammar::CONV_XL_OOX
:
577 case formula::FormulaGrammar::CONV_LOTUS_A1
:
578 case formula::FormulaGrammar::CONV_LAST
:
579 maSyntax
= OString("Unspecified");
584 void XclExpExtCalcPr::SaveXml( XclExpXmlStream
& rStrm
)
586 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
587 rWorksheet
->startElement( XML_ext
,
588 FSNS(XML_xmlns
, XML_loext
), rStrm
.getNamespaceURL(OOX_NS(loext
)),
591 rWorksheet
->singleElementNS(XML_loext
, XML_extCalcPr
, XML_stringRefSyntax
, maSyntax
);
593 rWorksheet
->endElement( XML_ext
);
596 XclExpExtCondFormat::XclExpExtCondFormat( const XclExpRoot
& rRoot
):
599 maURI
= OString("{78C0D931-6437-407d-A8EE-F0AAD7539E65}");
602 void XclExpExtCondFormat::SaveXml( XclExpXmlStream
& rStrm
)
604 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
605 rWorksheet
->startElement( XML_ext
,
606 FSNS(XML_xmlns
, XML_x14
), rStrm
.getNamespaceURL(OOX_NS(xls14Lst
)),
609 rWorksheet
->startElementNS(XML_x14
, XML_conditionalFormattings
);
611 maCF
.SaveXml( rStrm
);
613 rWorksheet
->endElementNS( XML_x14
, XML_conditionalFormattings
);
614 rWorksheet
->endElement( XML_ext
);
617 void XclExpExtCondFormat::AddRecord( XclExpExtConditionalFormatting
* pEntry
)
619 maCF
.AppendRecord( pEntry
);
622 void XclExtLst::SaveXml( XclExpXmlStream
& rStrm
)
624 if(maExtEntries
.IsEmpty())
627 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
628 rWorksheet
->startElement(XML_extLst
);
630 maExtEntries
.SaveXml(rStrm
);
632 rWorksheet
->endElement( XML_extLst
);
635 void XclExtLst::AddRecord( XclExpExt
* pEntry
)
637 maExtEntries
.AppendRecord( pEntry
);
640 XclExpExt
* XclExtLst::GetItem( XclExpExtType eType
)
642 size_t n
= maExtEntries
.GetSize();
643 for( size_t i
= 0; i
< n
; ++i
)
645 if (maExtEntries
.GetRecord( i
)->GetType() == eType
)
646 return maExtEntries
.GetRecord( i
);
653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */