Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / xml / xmlstyli.cxx
blob792e59594bc7dc3ad0a9306db5bed0833878812c
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "xmlstyli.hxx"
21 #include <xmloff/nmspmap.hxx>
22 #include <xmloff/xmlnmspe.hxx>
23 #include <xmloff/xmlimppr.hxx>
24 #include <xmloff/families.hxx>
25 #include <xmloff/xmlnumfi.hxx>
26 #include <xmloff/XMLGraphicsDefaultStyle.hxx>
27 #include <xmloff/xmltoken.hxx>
28 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
29 #include <com/sun/star/table/BorderLine2.hpp>
30 #include <comphelper/extract.hxx>
31 #include <xmloff/xmlprcon.hxx>
32 #include "XMLTableHeaderFooterContext.hxx"
33 #include "XMLConverter.hxx"
34 #include "XMLTableShapeImportHelper.hxx"
35 #include <sheetdata.hxx>
36 #include "xmlannoi.hxx"
37 #include <textuno.hxx>
38 #include <cellsuno.hxx>
39 #include "xmlstyle.hxx"
41 #include <docuno.hxx>
42 #include <unonames.hxx>
43 #include <document.hxx>
44 #include <conditio.hxx>
45 #include <rangelst.hxx>
47 #define XML_LINE_LEFT 0
48 #define XML_LINE_RIGHT 1
49 #define XML_LINE_TOP 2
50 #define XML_LINE_BOTTOM 3
52 #define XML_LINE_TLBR 0
53 #define XML_LINE_BLTR 1
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::xml::sax;
57 using namespace ::com::sun::star::style;
58 using namespace ::com::sun::star::beans;
59 using namespace ::com::sun::star::container;
60 using namespace xmloff::token;
61 using namespace ::formula;
63 using com::sun::star::uno::UNO_QUERY;
64 ScXMLCellImportPropertyMapper::ScXMLCellImportPropertyMapper(
65 const rtl::Reference< XMLPropertySetMapper >& rMapper,
66 SvXMLImport& rImportP) :
67 SvXMLImportPropertyMapper( rMapper, rImportP )
71 ScXMLCellImportPropertyMapper::~ScXMLCellImportPropertyMapper()
75 void ScXMLCellImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
77 static const sal_Int16 aPaddingCTF[4] = { CTF_SC_LEFTPADDING, CTF_SC_RIGHTPADDING,
78 CTF_SC_TOPPADDING, CTF_SC_BOTTOMPADDING };
79 static const sal_Int16 aBorderCTF[4] = { CTF_SC_LEFTBORDER, CTF_SC_RIGHTBORDER,
80 CTF_SC_TOPBORDER, CTF_SC_BOTTOMBORDER };
82 SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex);
83 XMLPropertyState* pAllPaddingProperty(nullptr);
84 XMLPropertyState* pPadding[4] = { nullptr, nullptr, nullptr, nullptr };
85 XMLPropertyState* pNewPadding[4] = { nullptr, nullptr, nullptr, nullptr };
86 XMLPropertyState* pAllBorderProperty = nullptr;
87 XMLPropertyState* pBorders[4] = { nullptr, nullptr, nullptr, nullptr };
88 XMLPropertyState* pNewBorders[4] = { nullptr, nullptr, nullptr, nullptr };
89 XMLPropertyState* pAllBorderWidthProperty = nullptr;
90 XMLPropertyState* pBorderWidths[4] = { nullptr, nullptr, nullptr, nullptr };
91 XMLPropertyState* pDiagBorders[2] = { nullptr };
92 XMLPropertyState* pOldDiagBorderWidths[2] = { nullptr }; // old attribute names without "s"
93 XMLPropertyState* pDiagBorderWidths[2] = { nullptr };
95 for (auto& rProperty : rProperties)
97 XMLPropertyState*property = &rProperty;
98 if (property->mnIndex != -1)
100 sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex);
101 switch (nContextID)
103 case CTF_SC_ALLPADDING : pAllPaddingProperty = property; break;
104 case CTF_SC_LEFTPADDING : pPadding[XML_LINE_LEFT] = property; break;
105 case CTF_SC_RIGHTPADDING : pPadding[XML_LINE_RIGHT] = property; break;
106 case CTF_SC_TOPPADDING : pPadding[XML_LINE_TOP] = property; break;
107 case CTF_SC_BOTTOMPADDING : pPadding[XML_LINE_BOTTOM] = property; break;
108 case CTF_SC_ALLBORDER : pAllBorderProperty = property; break;
109 case CTF_SC_LEFTBORDER : pBorders[XML_LINE_LEFT] = property; break;
110 case CTF_SC_RIGHTBORDER : pBorders[XML_LINE_RIGHT] = property; break;
111 case CTF_SC_TOPBORDER : pBorders[XML_LINE_TOP] = property; break;
112 case CTF_SC_BOTTOMBORDER : pBorders[XML_LINE_BOTTOM] = property; break;
113 case CTF_SC_ALLBORDERWIDTH : pAllBorderWidthProperty = property; break;
114 case CTF_SC_LEFTBORDERWIDTH : pBorderWidths[XML_LINE_LEFT] = property; break;
115 case CTF_SC_RIGHTBORDERWIDTH : pBorderWidths[XML_LINE_RIGHT] = property; break;
116 case CTF_SC_TOPBORDERWIDTH : pBorderWidths[XML_LINE_TOP] = property; break;
117 case CTF_SC_BOTTOMBORDERWIDTH : pBorderWidths[XML_LINE_BOTTOM] = property; break;
118 case CTF_SC_DIAGONALTLBR : pDiagBorders[XML_LINE_TLBR] = property; break;
119 case CTF_SC_DIAGONALBLTR : pDiagBorders[XML_LINE_BLTR] = property; break;
120 case CTF_SC_DIAGONALTLBRWIDTH : pOldDiagBorderWidths[XML_LINE_TLBR] = property; break;
121 case CTF_SC_DIAGONALTLBRWIDTHS : pDiagBorderWidths[XML_LINE_TLBR] = property; break;
122 case CTF_SC_DIAGONALBLTRWIDTH : pOldDiagBorderWidths[XML_LINE_BLTR] = property; break;
123 case CTF_SC_DIAGONALBLTRWIDTHS : pDiagBorderWidths[XML_LINE_BLTR] = property; break;
127 sal_uInt16 i;
129 // #i27594#; copy Value, but don't insert
130 if (pAllBorderWidthProperty)
131 pAllBorderWidthProperty->mnIndex = -1;
132 if (pAllBorderProperty)
133 pAllBorderProperty->mnIndex = -1;
134 if (pAllPaddingProperty)
135 pAllPaddingProperty->mnIndex = -1;
137 for (i = 0; i < 4; ++i)
139 if (pAllPaddingProperty && !pPadding[i])
140 pNewPadding[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aPaddingCTF[i]), pAllPaddingProperty->maValue);
141 if (pAllBorderProperty && !pBorders[i])
143 pNewBorders[i] = new XMLPropertyState(maPropMapper->FindEntryIndex(aBorderCTF[i]), pAllBorderProperty->maValue);
144 pBorders[i] = pNewBorders[i];
146 if( !pBorderWidths[i] )
147 pBorderWidths[i] = pAllBorderWidthProperty;
148 else
149 pBorderWidths[i]->mnIndex = -1;
150 if( pBorders[i] )
152 table::BorderLine2 aBorderLine;
153 pBorders[i]->maValue >>= aBorderLine;
154 if( pBorderWidths[i] )
156 // Merge style:border-line-width values to fo:border values. Do
157 // not override fo:border line width or line style with an
158 // empty value!
159 table::BorderLine2 aBorderLineWidth;
160 pBorderWidths[i]->maValue >>= aBorderLineWidth;
161 aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
162 aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
163 aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
164 pBorders[i]->maValue <<= aBorderLine;
168 for( i = 0; i < 2; ++i )
170 if( pDiagBorders[i] && ( pDiagBorderWidths[i] || pOldDiagBorderWidths[i] ) )
172 table::BorderLine2 aBorderLine;
173 pDiagBorders[i]->maValue >>= aBorderLine;
174 table::BorderLine2 aBorderLineWidth;
175 if (pDiagBorderWidths[i])
176 pDiagBorderWidths[i]->maValue >>= aBorderLineWidth; // prefer new attribute
177 else
178 pOldDiagBorderWidths[i]->maValue >>= aBorderLineWidth;
179 aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
180 aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
181 aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
182 pDiagBorders[i]->maValue <<= aBorderLine;
183 if (pDiagBorderWidths[i])
184 pDiagBorderWidths[i]->mnIndex = -1;
185 if (pOldDiagBorderWidths[i])
186 pOldDiagBorderWidths[i]->mnIndex = -1; // reset mnIndex for old and new attribute if both are present
190 for (i = 0; i < 4; ++i)
192 if (pNewPadding[i])
194 rProperties.push_back(*pNewPadding[i]);
195 delete pNewPadding[i];
197 if (pNewBorders[i])
199 rProperties.push_back(*pNewBorders[i]);
200 delete pNewBorders[i];
205 ScXMLRowImportPropertyMapper::ScXMLRowImportPropertyMapper(
206 const rtl::Reference< XMLPropertySetMapper >& rMapper,
207 SvXMLImport& rImportP) :
208 SvXMLImportPropertyMapper( rMapper, rImportP )
212 ScXMLRowImportPropertyMapper::~ScXMLRowImportPropertyMapper()
216 void ScXMLRowImportPropertyMapper::finished(::std::vector< XMLPropertyState >& rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
218 SvXMLImportPropertyMapper::finished(rProperties, nStartIndex, nEndIndex);
219 XMLPropertyState* pHeight(nullptr);
220 XMLPropertyState* pOptimalHeight(nullptr);
221 XMLPropertyState* pPageBreak(nullptr);
222 for (auto& rProperty : rProperties)
224 XMLPropertyState* property = &rProperty;
225 if (property->mnIndex != -1)
227 sal_Int16 nContextID = getPropertySetMapper()->GetEntryContextId(property->mnIndex);
228 switch (nContextID)
230 case CTF_SC_ROWHEIGHT : pHeight = property; break;
231 case CTF_SC_ROWOPTIMALHEIGHT : pOptimalHeight = property; break;
232 case CTF_SC_ROWBREAKBEFORE : pPageBreak = property; break;
236 if (pPageBreak)
238 if(!(::cppu::any2bool(pPageBreak->maValue)))
239 pPageBreak->mnIndex = -1;
241 if (pOptimalHeight)
243 if (::cppu::any2bool(pOptimalHeight->maValue))
245 if (pHeight)
247 // set the stored height, but keep "optimal" flag:
248 // pass the height value as OptimalHeight property (only allowed while loading!)
249 pOptimalHeight->maValue = pHeight->maValue;
250 pHeight->mnIndex = -1;
252 else
253 pOptimalHeight->mnIndex = -1;
256 else if (pHeight)
258 rProperties.emplace_back(maPropMapper->FindEntryIndex(CTF_SC_ROWOPTIMALHEIGHT), css::uno::Any(false));
260 // don't access pointers to rProperties elements after push_back!
263 class XMLTableCellPropsContext : public SvXMLPropertySetContext
265 using SvXMLPropertySetContext::CreateChildContext;
266 public:
267 XMLTableCellPropsContext(
268 SvXMLImport& rImport, sal_uInt16 nPrfx,
269 const OUString& rLName,
270 const uno::Reference< xml::sax::XAttributeList >& xAttrList,
271 sal_uInt32 nFamily,
272 ::std::vector< XMLPropertyState > &rProps,
273 const rtl::Reference < SvXMLImportPropertyMapper > &rMap);
275 virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix,
276 const OUString& rLocalName,
277 const uno::Reference< xml::sax::XAttributeList >& xAttrList,
278 ::std::vector< XMLPropertyState > &rProperties,
279 const XMLPropertyState& rProp ) override;
282 XMLTableCellPropsContext::XMLTableCellPropsContext(
283 SvXMLImport& rImport, sal_uInt16 nPrfx,
284 const OUString& rLName,
285 const uno::Reference< xml::sax::XAttributeList >& xAttrList,
286 sal_uInt32 nFamily,
287 ::std::vector< XMLPropertyState > &rProps,
288 const rtl::Reference < SvXMLImportPropertyMapper > &rMap)
289 : SvXMLPropertySetContext( rImport, nPrfx, rLName, xAttrList, nFamily,
290 rProps, rMap )
294 SvXMLImportContextRef XMLTableCellPropsContext::CreateChildContext( sal_uInt16 nPrefix,
295 const OUString& rLocalName,
296 const uno::Reference< xml::sax::XAttributeList >& xAttrList,
297 ::std::vector< XMLPropertyState > &rProperties,
298 const XMLPropertyState& rProp )
300 // no need for a custom context or indeed a SvXMLTokenMap to grab just the
301 // single attribute ( href ) that we are interested in.
302 // still though, we will check namespaces etc.
303 if ( ( XML_NAMESPACE_STYLE == nPrefix) &&
304 IsXMLToken(rLocalName, XML_HYPERLINK ) )
306 OUString sURL;
307 for ( int i=0; i<xAttrList->getLength(); ++i )
309 OUString aLocalName;
310 OUString sName = xAttrList->getNameByIndex(i);
311 sal_uInt16 nPrfx = GetImport().GetNamespaceMap().GetKeyByAttrName( sName,
312 &aLocalName );
313 if ( nPrfx == XML_NAMESPACE_XLINK )
315 if ( IsXMLToken( aLocalName, XML_HREF ) )
317 sURL = xAttrList->getValueByIndex(i);
318 break;
322 if ( !sURL.isEmpty() )
324 XMLPropertyState aProp( rProp );
325 aProp.maValue <<= sURL;
326 rProperties.push_back( aProp );
329 return SvXMLPropertySetContext::CreateChildContext( nPrefix, rLocalName, xAttrList, rProperties, rProp );
332 class ScXMLMapContext : public SvXMLImportContext
334 OUString msApplyStyle;
335 OUString msCondition;
336 OUString msBaseCell;
338 ScXMLImport& GetScImport() { return static_cast<ScXMLImport&>(GetImport()); }
339 public:
341 ScXMLMapContext(
342 SvXMLImport& rImport, sal_uInt16 nPrfx,
343 const OUString& rLName,
344 const uno::Reference< xml::sax::XAttributeList > & xAttrList );
346 ScCondFormatEntry* CreateConditionEntry();
349 ScXMLMapContext::ScXMLMapContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
350 const OUString& rLName, const uno::Reference< xml::sax::XAttributeList > & xAttrList )
351 : SvXMLImportContext( rImport, nPrfx, rLName )
353 sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
354 for( sal_Int16 i=0; i < nAttrCount; ++i )
356 const OUString& rAttrName(xAttrList->getNameByIndex( i ));
357 OUString aLocalName;
358 sal_uInt16 nPrefix(GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
359 const OUString& rValue(xAttrList->getValueByIndex( i ));
361 // TODO: use a map here
362 if( XML_NAMESPACE_STYLE == nPrefix )
364 if( IsXMLToken(aLocalName, XML_CONDITION ) )
365 msCondition = rValue;
366 else if( IsXMLToken(aLocalName, XML_APPLY_STYLE_NAME ) )
367 msApplyStyle = GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, rValue);
368 else if ( IsXMLToken(aLocalName, XML_BASE_CELL_ADDRESS ) )
369 msBaseCell = rValue;
374 ScCondFormatEntry* ScXMLMapContext::CreateConditionEntry()
376 OUString aCondition, aConditionNmsp;
377 FormulaGrammar::Grammar eGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
378 GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eGrammar, msCondition );
379 bool bHasNmsp = aCondition.getLength() < msCondition.getLength();
381 // parse a condition from the attribute string
382 ScXMLConditionParseResult aParseResult;
383 ScXMLConditionHelper::parseCondition( aParseResult, aCondition, 0 );
385 if( !bHasNmsp )
387 // the attribute does not contain a namespace: try to find a namespace of an external grammar
388 FormulaGrammar::Grammar eNewGrammar = FormulaGrammar::GRAM_UNSPECIFIED;
389 GetScImport().ExtractFormulaNamespaceGrammar( aCondition, aConditionNmsp, eNewGrammar, aCondition, true );
390 if( eNewGrammar != FormulaGrammar::GRAM_EXTERNAL )
391 eGrammar = eNewGrammar;
394 ScConditionMode eMode = ScConditionEntry::GetModeFromApi(aParseResult.meOperator);
395 ScDocument* pDoc = GetScImport().GetDocument();
397 ScCondFormatEntry* pEntry = new ScCondFormatEntry(eMode, aParseResult.maOperand1, aParseResult.maOperand2, pDoc, ScAddress(), msApplyStyle,
398 OUString(), OUString(), eGrammar, eGrammar);
400 pEntry->SetSrcString(msBaseCell);
401 return pEntry;
404 void XMLTableStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
405 const OUString& rLocalName,
406 const OUString& rValue )
408 // TODO: use a map here
409 if( IsXMLToken(rLocalName, XML_DATA_STYLE_NAME ) )
410 sDataStyleName = rValue;
411 else if ( IsXMLToken(rLocalName, XML_MASTER_PAGE_NAME ) )
412 sPageStyle = rValue;
413 else
414 XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
418 XMLTableStyleContext::XMLTableStyleContext( ScXMLImport& rImport,
419 sal_uInt16 nPrfx, const OUString& rLName,
420 const uno::Reference< XAttributeList > & xAttrList,
421 SvXMLStylesContext& rStyles, sal_uInt16 nFamily, bool bDefaultStyle ) :
422 XMLPropStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ),
423 sDataStyleName(),
424 pStyles(&rStyles),
425 nNumberFormat(-1),
426 nLastSheet(-1),
427 bParentSet(false),
428 mpCondFormat(nullptr),
429 mbDeleteCondFormat(true)
433 XMLTableStyleContext::~XMLTableStyleContext()
435 if(mbDeleteCondFormat)
436 delete mpCondFormat;
439 SvXMLImportContextRef XMLTableStyleContext::CreateChildContext(
440 sal_uInt16 nPrefix,
441 const OUString& rLocalName,
442 const uno::Reference< XAttributeList > & xAttrList )
444 SvXMLImportContextRef xContext;
446 if( (XML_NAMESPACE_STYLE == nPrefix) &&
447 IsXMLToken(rLocalName, XML_MAP ) )
449 if(!mpCondFormat)
450 mpCondFormat = new ScConditionalFormat( 0, GetScImport().GetDocument() );
451 ScXMLMapContext* pMapContext = new ScXMLMapContext(GetImport(), nPrefix, rLocalName, xAttrList);
452 xContext = pMapContext;
453 mpCondFormat->AddEntry(pMapContext->CreateConditionEntry());
455 else if ( ( XML_NAMESPACE_STYLE == nPrefix) &&
456 IsXMLToken(rLocalName, XML_TABLE_CELL_PROPERTIES ) )
458 rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
459 GetStyles()->GetImportPropertyMapper(
460 GetFamily() );
461 if( xImpPrMap.is() )
462 xContext = new XMLTableCellPropsContext( GetImport(), nPrefix,
463 rLocalName, xAttrList,
464 XML_TYPE_PROP_TABLE_CELL,
465 GetProperties(),
466 xImpPrMap );
469 if (!xContext)
470 xContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName,
471 xAttrList );
472 return xContext;
475 void XMLTableStyleContext::ApplyCondFormat( const uno::Sequence<table::CellRangeAddress>& xCellRanges )
477 if(!mpCondFormat || GetScImport().HasNewCondFormatData())
478 return;
480 ScRangeList aRangeList;
481 for(const table::CellRangeAddress& aAddress : xCellRanges)
483 ScRange aRange( aAddress.StartColumn, aAddress.StartRow, aAddress.Sheet, aAddress.EndColumn, aAddress.EndRow, aAddress.Sheet );
484 aRangeList.Join( aRange );
487 ScDocument* pDoc = GetScImport().GetDocument();
488 SCTAB nTab = GetScImport().GetTables().GetCurrentSheet();
489 ScConditionalFormatList* pFormatList = pDoc->GetCondFormList(nTab);
490 auto itr = std::find_if(pFormatList->begin(), pFormatList->end(),
491 [this](const std::unique_ptr<ScConditionalFormat>& rxFormat) { return rxFormat->EqualEntries(*mpCondFormat); });
492 if (itr != pFormatList->end())
494 ScRangeList& rRangeList = (*itr)->GetRangeList();
495 sal_uInt32 nCondId = (*itr)->GetKey();
496 size_t n = aRangeList.size();
497 for(size_t i = 0; i < n; ++i)
499 const ScRange & rRange = aRangeList[i];
500 rRangeList.Join(rRange);
503 pDoc->AddCondFormatData( aRangeList, nTab, nCondId );
504 return;
507 if(mpCondFormat && mbDeleteCondFormat)
509 sal_uLong nIndex = pDoc->AddCondFormat(std::unique_ptr<ScConditionalFormat>(mpCondFormat), nTab );
510 mpCondFormat->SetKey(nIndex);
511 mpCondFormat->SetRange(aRangeList);
513 pDoc->AddCondFormatData( aRangeList, nTab, nIndex );
514 mbDeleteCondFormat = false;
519 void XMLTableStyleContext::FillPropertySet(
520 const uno::Reference< XPropertySet > & rPropSet )
522 if (!IsDefaultStyle())
524 if (GetFamily() == XML_STYLE_FAMILY_TABLE_CELL)
526 if (!bParentSet)
528 AddProperty(CTF_SC_CELLSTYLE, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, GetParentName() )));
529 bParentSet = true;
531 sal_Int32 nNumFmt = GetNumberFormat();
532 if (nNumFmt >= 0)
533 AddProperty(CTF_SC_NUMBERFORMAT, uno::makeAny(nNumFmt));
535 else if (GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE)
537 if (!sPageStyle.isEmpty())
538 AddProperty(CTF_SC_MASTERPAGENAME, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_MASTER_PAGE, sPageStyle )));
541 XMLPropStyleContext::FillPropertySet(rPropSet);
544 void XMLTableStyleContext::SetDefaults()
546 if ((GetFamily() == XML_STYLE_FAMILY_TABLE_CELL) && GetImport().GetModel().is())
548 uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetImport().GetModel(), uno::UNO_QUERY);
549 if (xMultiServiceFactory.is())
551 uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance("com.sun.star.sheet.Defaults"), uno::UNO_QUERY);
552 if (xProperties.is())
553 FillPropertySet(xProperties);
558 void XMLTableStyleContext::AddProperty(const sal_Int16 nContextID, const uno::Any& rValue)
560 XMLPropertyState* property = FindProperty(nContextID);
561 if (property)
562 property->mnIndex = -1; // #i46996# remove old property, so it isn't double
563 sal_Int32 nIndex(static_cast<XMLTableStylesContext *>(pStyles)->GetIndex(nContextID));
564 OSL_ENSURE(nIndex != -1, "Property not found in Map");
565 XMLPropertyState aPropState(nIndex, rValue);
566 GetProperties().push_back(aPropState); // has to be inserted in a sort order later
569 XMLPropertyState* XMLTableStyleContext::FindProperty(const sal_Int16 nContextID)
571 XMLPropertyState* pRet = nullptr;
572 rtl::Reference < XMLPropertySetMapper > xPrMap;
573 rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
574 pStyles->GetImportPropertyMapper( GetFamily() );
575 OSL_ENSURE( xImpPrMap.is(), "There is the import prop mapper" );
576 if( xImpPrMap.is() )
577 xPrMap = xImpPrMap->getPropertySetMapper();
578 if( xPrMap.is() )
580 auto aIter = std::find_if(GetProperties().begin(), GetProperties().end(),
581 [&xPrMap, &nContextID](const XMLPropertyState& rProp) {
582 return rProp.mnIndex != -1 && xPrMap->GetEntryContextId(rProp.mnIndex) == nContextID;
584 if (aIter != GetProperties().end())
585 pRet = &(*aIter);
587 return pRet;
590 sal_Int32 XMLTableStyleContext::GetNumberFormat()
592 if (nNumberFormat < 0 && !sDataStyleName.isEmpty())
594 const SvXMLNumFormatContext* pStyle = static_cast<const SvXMLNumFormatContext*>(
595 pStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, true));
597 if (!pStyle)
599 XMLTableStylesContext* pMyStyles = static_cast<XMLTableStylesContext*>(GetScImport().GetStyles());
600 if (pMyStyles)
601 pStyle = static_cast<const SvXMLNumFormatContext*>(
602 pMyStyles->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE, sDataStyleName, true));
603 else
605 OSL_FAIL("not possible to get style");
608 if (pStyle)
609 nNumberFormat = const_cast<SvXMLNumFormatContext*>(pStyle)->GetKey();
611 return nNumberFormat;
614 SvXMLStyleContext *XMLTableStylesContext::CreateStyleStyleChildContext(
615 sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName,
616 const uno::Reference< xml::sax::XAttributeList > & xAttrList )
618 SvXMLStyleContext *pStyle;
619 // use own wrapper for text and paragraph, to record style usage
620 if (nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH || nFamily == XML_STYLE_FAMILY_TEXT_TEXT)
621 pStyle = new ScCellTextStyleContext( GetImport(), nPrefix, rLocalName,
622 xAttrList, *this, nFamily );
623 else
624 pStyle = SvXMLStylesContext::CreateStyleStyleChildContext(
625 nFamily, nPrefix, rLocalName, xAttrList );
627 if (!pStyle)
629 switch( nFamily )
631 case XML_STYLE_FAMILY_TABLE_CELL:
632 case XML_STYLE_FAMILY_TABLE_COLUMN:
633 case XML_STYLE_FAMILY_TABLE_ROW:
634 case XML_STYLE_FAMILY_TABLE_TABLE:
635 pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName,
636 xAttrList, *this, nFamily );
637 break;
641 return pStyle;
644 SvXMLStyleContext *XMLTableStylesContext::CreateDefaultStyleStyleChildContext(
645 sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName,
646 const uno::Reference< xml::sax::XAttributeList > & xAttrList )
648 SvXMLStyleContext *pStyle(SvXMLStylesContext::CreateDefaultStyleStyleChildContext( nFamily, nPrefix,
649 rLocalName,
650 xAttrList ));
651 if (!pStyle)
653 switch( nFamily )
655 case XML_STYLE_FAMILY_TABLE_CELL:
656 pStyle = new XMLTableStyleContext( GetScImport(), nPrefix, rLocalName,
657 xAttrList, *this, nFamily, true);
658 break;
659 case XML_STYLE_FAMILY_SD_GRAPHICS_ID:
660 pStyle = new XMLGraphicsDefaultStyle( GetScImport(), nPrefix, rLocalName,
661 xAttrList, *this);
662 break;
666 return pStyle;
669 static const OUStringLiteral gsCellStyleServiceName("com.sun.star.style.CellStyle");
670 static const OUStringLiteral gsColumnStyleServiceName(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME);
671 static const OUStringLiteral gsRowStyleServiceName(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME);
672 static const OUStringLiteral gsTableStyleServiceName(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME);
674 XMLTableStylesContext::XMLTableStylesContext( SvXMLImport& rImport,
675 sal_uInt16 nPrfx ,
676 const OUString& rLName ,
677 const uno::Reference< XAttributeList > & xAttrList,
678 const bool bTempAutoStyles )
679 : SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList )
680 , nNumberFormatIndex(-1)
681 , nConditionalFormatIndex(-1)
682 , nCellStyleIndex(-1)
683 , nMasterPageNameIndex(-1)
684 , bAutoStyles(bTempAutoStyles)
688 XMLTableStylesContext::~XMLTableStylesContext()
692 void XMLTableStylesContext::EndElement()
694 SvXMLStylesContext::EndElement();
695 if (bAutoStyles)
696 GetImport().GetTextImport()->SetAutoStyles( this );
697 else
698 GetScImport().InsertStyles();
701 rtl::Reference < SvXMLImportPropertyMapper >
702 XMLTableStylesContext::GetImportPropertyMapper(
703 sal_uInt16 nFamily ) const
705 rtl::Reference < SvXMLImportPropertyMapper > xMapper(SvXMLStylesContext::GetImportPropertyMapper(nFamily));
707 if (!xMapper.is())
709 switch( nFamily )
711 case XML_STYLE_FAMILY_TABLE_CELL:
713 if( !xCellImpPropMapper.is() )
715 const_cast<XMLTableStylesContext *>(this)->xCellImpPropMapper =
716 new ScXMLCellImportPropertyMapper( GetScImport().GetCellStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
717 xCellImpPropMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(const_cast<SvXMLImport&>(GetImport())));
719 xMapper = xCellImpPropMapper;
721 break;
722 case XML_STYLE_FAMILY_TABLE_COLUMN:
724 if( !xColumnImpPropMapper.is() )
725 const_cast<XMLTableStylesContext *>(this)->xColumnImpPropMapper =
726 new SvXMLImportPropertyMapper( GetScImport().GetColumnStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
727 xMapper = xColumnImpPropMapper;
729 break;
730 case XML_STYLE_FAMILY_TABLE_ROW:
732 if( !xRowImpPropMapper.is() )
733 const_cast<XMLTableStylesContext *>(this)->xRowImpPropMapper =
734 new ScXMLRowImportPropertyMapper( GetScImport().GetRowStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
735 xMapper = xRowImpPropMapper;
737 break;
738 case XML_STYLE_FAMILY_TABLE_TABLE:
740 if( !xTableImpPropMapper.is() )
741 const_cast<XMLTableStylesContext *>(this)->xTableImpPropMapper =
742 new SvXMLImportPropertyMapper( GetScImport().GetTableStylesPropertySetMapper(), const_cast<SvXMLImport&>(GetImport()) );
743 xMapper = xTableImpPropMapper;
745 break;
749 return xMapper;
752 uno::Reference < XNameContainer >
753 XMLTableStylesContext::GetStylesContainer( sal_uInt16 nFamily ) const
755 uno::Reference < XNameContainer > xStyles(SvXMLStylesContext::GetStylesContainer(nFamily));
756 if (!xStyles.is())
758 OUString sName;
759 switch( nFamily )
761 case XML_STYLE_FAMILY_TABLE_TABLE:
763 if( xTableStyles.is() )
764 xStyles.set(xTableStyles);
765 else
766 sName = "TableStyles";
768 break;
769 case XML_STYLE_FAMILY_TABLE_CELL:
771 if( xCellStyles.is() )
772 xStyles.set(xCellStyles);
773 else
774 sName = "CellStyles";
776 break;
777 case XML_STYLE_FAMILY_TABLE_COLUMN:
779 if( xColumnStyles.is() )
780 xStyles.set(xColumnStyles);
781 else
782 sName = "ColumnStyles";
784 break;
785 case XML_STYLE_FAMILY_TABLE_ROW:
787 if( xRowStyles.is() )
788 xStyles.set(xRowStyles);
789 else
790 sName = "RowStyles";
792 break;
794 if( !xStyles.is() && !sName.isEmpty() && GetScImport().GetModel().is() )
796 uno::Reference< XStyleFamiliesSupplier > xFamiliesSupp(
797 GetScImport().GetModel(), UNO_QUERY );
798 if (xFamiliesSupp.is())
800 uno::Reference< XNameAccess > xFamilies(xFamiliesSupp->getStyleFamilies());
804 xStyles.set(xFamilies->getByName( sName ), uno::UNO_QUERY);
806 catch ( uno::Exception& )
808 // #i97680# Named table/column/row styles aren't supported, getByName will throw an exception.
809 // For better interoperability, these styles should then be handled as automatic styles.
810 // For now, NULL is returned (and the style is ignored).
812 switch( nFamily )
814 case XML_STYLE_FAMILY_TABLE_TABLE:
815 const_cast<XMLTableStylesContext *>(this)->xTableStyles.set(xStyles);
816 break;
817 case XML_STYLE_FAMILY_TABLE_CELL:
818 const_cast<XMLTableStylesContext *>(this)->xCellStyles.set(xStyles);
819 break;
820 case XML_STYLE_FAMILY_TABLE_COLUMN:
821 const_cast<XMLTableStylesContext *>(this)->xColumnStyles.set(xStyles);
822 break;
823 case XML_STYLE_FAMILY_TABLE_ROW:
824 const_cast<XMLTableStylesContext *>(this)->xRowStyles.set(xStyles);
825 break;
831 return xStyles;
834 OUString XMLTableStylesContext::GetServiceName( sal_uInt16 nFamily ) const
836 OUString sServiceName(SvXMLStylesContext::GetServiceName(nFamily));
837 if (sServiceName.isEmpty())
839 switch( nFamily )
841 case XML_STYLE_FAMILY_TABLE_COLUMN:
842 sServiceName = gsColumnStyleServiceName;
843 break;
844 case XML_STYLE_FAMILY_TABLE_ROW:
845 sServiceName = gsRowStyleServiceName;
846 break;
847 case XML_STYLE_FAMILY_TABLE_CELL:
848 sServiceName = gsCellStyleServiceName;
849 break;
850 case XML_STYLE_FAMILY_TABLE_TABLE:
851 sServiceName = gsTableStyleServiceName;
852 break;
855 return sServiceName;
858 sal_Int32 XMLTableStylesContext::GetIndex(const sal_Int16 nContextID)
860 if (nContextID == CTF_SC_CELLSTYLE)
862 if (nCellStyleIndex == -1)
863 nCellStyleIndex =
864 GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
865 return nCellStyleIndex;
867 else if (nContextID == CTF_SC_NUMBERFORMAT)
869 if (nNumberFormatIndex == -1)
870 nNumberFormatIndex =
871 GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
872 return nNumberFormatIndex;
874 else if (nContextID == CTF_SC_IMPORT_MAP)
876 if (nConditionalFormatIndex == -1)
877 nConditionalFormatIndex =
878 GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID);
879 return nConditionalFormatIndex;
881 else if (nContextID == CTF_SC_MASTERPAGENAME)
883 if (nMasterPageNameIndex == -1)
884 nMasterPageNameIndex =
885 GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_TABLE)->getPropertySetMapper()->FindEntryIndex(nContextID);
886 return nMasterPageNameIndex;
888 else
889 return -1;
893 bool ScXMLMasterStylesContext::InsertStyleFamily( sal_uInt16 ) const
895 return true;
898 ScXMLMasterStylesContext::ScXMLMasterStylesContext(
899 SvXMLImport& rImport,
900 sal_uInt16 nPrfx, const OUString& rLName,
901 const uno::Reference< XAttributeList > & xAttrList ) :
902 SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList )
906 ScXMLMasterStylesContext::~ScXMLMasterStylesContext()
910 SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleChildContext(
911 sal_uInt16 nPrefix,
912 const OUString& rLocalName,
913 const uno::Reference< XAttributeList > & xAttrList )
915 SvXMLStyleContext *pContext(nullptr);
917 if( (XML_NAMESPACE_STYLE == nPrefix) &&
918 IsXMLToken(rLocalName, XML_MASTER_PAGE) &&
919 InsertStyleFamily( XML_STYLE_FAMILY_MASTER_PAGE ) )
920 pContext = new ScMasterPageContext(
921 GetImport(), nPrefix, rLocalName, xAttrList,
922 !GetImport().GetTextImport()->IsInsertMode() );
924 // any other style will be ignored here!
926 return pContext;
929 SvXMLStyleContext *ScXMLMasterStylesContext::CreateStyleStyleChildContext(
930 sal_uInt16 /* nFamily */,
931 sal_uInt16 /* nPrefix */,
932 const OUString& /* rLocalName */,
933 const uno::Reference< XAttributeList > & /* xAttrList */ )
935 return nullptr;
938 void ScXMLMasterStylesContext::EndElement()
940 FinishStyles(true);
944 ScMasterPageContext::ScMasterPageContext( SvXMLImport& rImport,
945 sal_uInt16 nPrfx, const OUString& rLName,
946 const uno::Reference< XAttributeList > & xAttrList,
947 bool bOverwrite ) :
948 XMLTextMasterPageContext( rImport, nPrfx, rLName, xAttrList, bOverwrite ),
949 bContainsRightHeader(false),
950 bContainsRightFooter(false)
954 ScMasterPageContext::~ScMasterPageContext()
958 SvXMLImportContext *ScMasterPageContext::CreateHeaderFooterContext(
959 sal_uInt16 nPrefix,
960 const OUString& rLocalName,
961 const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList,
962 const bool bFooter,
963 const bool bLeft,
964 const bool /*bFirst*/ )
966 if (!bLeft)
968 if (bFooter)
969 bContainsRightFooter = true;
970 else
971 bContainsRightHeader = true;
973 if (!xPropSet.is())
974 xPropSet.set(GetStyle(), UNO_QUERY );
975 return new XMLTableHeaderFooterContext( GetImport(),
976 nPrefix, rLocalName,
977 xAttrList,
978 xPropSet,
979 bFooter, bLeft );
982 void ScMasterPageContext::ClearContent(const OUString& rContent)
984 if (!xPropSet.is())
985 xPropSet.set(GetStyle(), UNO_QUERY );
987 if (xPropSet.is())
989 uno::Reference < sheet::XHeaderFooterContent > xHeaderFooterContent(xPropSet->getPropertyValue( rContent ), uno::UNO_QUERY);
990 if (xHeaderFooterContent.is())
992 xHeaderFooterContent->getLeftText()->setString("");
993 xHeaderFooterContent->getCenterText()->setString("");
994 xHeaderFooterContent->getRightText()->setString("");
995 xPropSet->setPropertyValue( rContent, uno::makeAny(xHeaderFooterContent) );
1000 void ScMasterPageContext::Finish( bool bOverwrite )
1002 XMLTextMasterPageContext::Finish(bOverwrite);
1003 if (!bContainsRightFooter)
1004 ClearContent(SC_UNO_PAGE_RIGHTFTRCON);
1005 if (!bContainsRightHeader)
1006 ClearContent(SC_UNO_PAGE_RIGHTHDRCON);
1009 ScCellTextStyleContext::ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
1010 const OUString& rLName, const uno::Reference<xml::sax::XAttributeList> & xAttrList,
1011 SvXMLStylesContext& rStyles, sal_uInt16 nFamily ) :
1012 XMLTextStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, false/*bDefaultStyle*/ ),
1013 nLastSheet(-1)
1017 ScCellTextStyleContext::~ScCellTextStyleContext()
1021 void ScCellTextStyleContext::FillPropertySet( const uno::Reference<beans::XPropertySet>& xPropSet )
1023 XMLTextStyleContext::FillPropertySet( xPropSet );
1025 ScXMLImport& rXMLImport = GetScImport();
1027 ScCellTextCursor* pCellImp = comphelper::getUnoTunnelImplementation<ScCellTextCursor>( xPropSet );
1028 if (pCellImp)
1030 ScAddress aPos = pCellImp->GetCellObj().GetPosition();
1031 if ( aPos.Tab() != nLastSheet )
1033 ESelection aSel = pCellImp->GetSelection();
1035 ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(GetImport().GetModel())->GetSheetSaveData();
1036 pSheetData->AddTextStyle( GetName(), aPos, aSel );
1038 nLastSheet = aPos.Tab();
1041 else if ( rXMLImport.GetTables().GetCurrentSheet() != nLastSheet )
1043 ScDrawTextCursor* pDrawImp = comphelper::getUnoTunnelImplementation<ScDrawTextCursor>( xPropSet );
1044 if (pDrawImp)
1046 XMLTableShapeImportHelper* pTableShapeImport = static_cast<XMLTableShapeImportHelper*>(GetScImport().GetShapeImport().get());
1047 ScXMLAnnotationContext* pAnnotationContext = pTableShapeImport->GetAnnotationContext();
1048 if (pAnnotationContext)
1050 pAnnotationContext->AddContentStyle( GetFamily(), GetName(), pDrawImp->GetSelection() );
1051 nLastSheet = rXMLImport.GetTables().GetCurrentSheet();
1055 // if it's a different shape, BlockSheet is called from XMLTableShapeImportHelper::finishShape
1056 // formatted text in page headers/footers can be ignored
1060 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */