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/.
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"
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
);
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;
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
;
149 pBorderWidths
[i
]->mnIndex
= -1;
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
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
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
)
194 rProperties
.push_back(*pNewPadding
[i
]);
195 delete pNewPadding
[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
);
230 case CTF_SC_ROWHEIGHT
: pHeight
= property
; break;
231 case CTF_SC_ROWOPTIMALHEIGHT
: pOptimalHeight
= property
; break;
232 case CTF_SC_ROWBREAKBEFORE
: pPageBreak
= property
; break;
238 if(!(::cppu::any2bool(pPageBreak
->maValue
)))
239 pPageBreak
->mnIndex
= -1;
243 if (::cppu::any2bool(pOptimalHeight
->maValue
))
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;
253 pOptimalHeight
->mnIndex
= -1;
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
;
267 XMLTableCellPropsContext(
268 SvXMLImport
& rImport
, sal_uInt16 nPrfx
,
269 const OUString
& rLName
,
270 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
,
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
,
287 ::std::vector
< XMLPropertyState
> &rProps
,
288 const rtl::Reference
< SvXMLImportPropertyMapper
> &rMap
)
289 : SvXMLPropertySetContext( rImport
, nPrfx
, rLName
, xAttrList
, nFamily
,
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
) )
307 for ( int i
=0; i
<xAttrList
->getLength(); ++i
)
310 OUString sName
= xAttrList
->getNameByIndex(i
);
311 sal_uInt16 nPrfx
= GetImport().GetNamespaceMap().GetKeyByAttrName( sName
,
313 if ( nPrfx
== XML_NAMESPACE_XLINK
)
315 if ( IsXMLToken( aLocalName
, XML_HREF
) )
317 sURL
= xAttrList
->getValueByIndex(i
);
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
;
338 ScXMLImport
& GetScImport() { return static_cast<ScXMLImport
&>(GetImport()); }
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
));
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
) )
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 );
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
);
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
) )
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
),
428 mpCondFormat(nullptr),
429 mbDeleteCondFormat(true)
433 XMLTableStyleContext::~XMLTableStyleContext()
435 if(mbDeleteCondFormat
)
439 SvXMLImportContextRef
XMLTableStyleContext::CreateChildContext(
441 const OUString
& rLocalName
,
442 const uno::Reference
< XAttributeList
> & xAttrList
)
444 SvXMLImportContextRef xContext
;
446 if( (XML_NAMESPACE_STYLE
== nPrefix
) &&
447 IsXMLToken(rLocalName
, XML_MAP
) )
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(
462 xContext
= new XMLTableCellPropsContext( GetImport(), nPrefix
,
463 rLocalName
, xAttrList
,
464 XML_TYPE_PROP_TABLE_CELL
,
470 xContext
= XMLPropStyleContext::CreateChildContext( nPrefix
, rLocalName
,
475 void XMLTableStyleContext::ApplyCondFormat( const uno::Sequence
<table::CellRangeAddress
>& xCellRanges
)
477 if(!mpCondFormat
|| GetScImport().HasNewCondFormatData())
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
);
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
)
528 AddProperty(CTF_SC_CELLSTYLE
, uno::makeAny(GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL
, GetParentName() )));
531 sal_Int32 nNumFmt
= GetNumberFormat();
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
);
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" );
577 xPrMap
= xImpPrMap
->getPropertySetMapper();
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())
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));
599 XMLTableStylesContext
* pMyStyles
= static_cast<XMLTableStylesContext
*>(GetScImport().GetStyles());
601 pStyle
= static_cast<const SvXMLNumFormatContext
*>(
602 pMyStyles
->FindStyleChildContext(XML_STYLE_FAMILY_DATA_STYLE
, sDataStyleName
, true));
605 OSL_FAIL("not possible to get style");
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
);
624 pStyle
= SvXMLStylesContext::CreateStyleStyleChildContext(
625 nFamily
, nPrefix
, rLocalName
, xAttrList
);
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
);
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
,
655 case XML_STYLE_FAMILY_TABLE_CELL
:
656 pStyle
= new XMLTableStyleContext( GetScImport(), nPrefix
, rLocalName
,
657 xAttrList
, *this, nFamily
, true);
659 case XML_STYLE_FAMILY_SD_GRAPHICS_ID
:
660 pStyle
= new XMLGraphicsDefaultStyle( GetScImport(), nPrefix
, rLocalName
,
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
,
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();
696 GetImport().GetTextImport()->SetAutoStyles( this );
698 GetScImport().InsertStyles();
701 rtl::Reference
< SvXMLImportPropertyMapper
>
702 XMLTableStylesContext::GetImportPropertyMapper(
703 sal_uInt16 nFamily
) const
705 rtl::Reference
< SvXMLImportPropertyMapper
> xMapper(SvXMLStylesContext::GetImportPropertyMapper(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
;
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
;
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
;
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
;
752 uno::Reference
< XNameContainer
>
753 XMLTableStylesContext::GetStylesContainer( sal_uInt16 nFamily
) const
755 uno::Reference
< XNameContainer
> xStyles(SvXMLStylesContext::GetStylesContainer(nFamily
));
761 case XML_STYLE_FAMILY_TABLE_TABLE
:
763 if( xTableStyles
.is() )
764 xStyles
.set(xTableStyles
);
766 sName
= "TableStyles";
769 case XML_STYLE_FAMILY_TABLE_CELL
:
771 if( xCellStyles
.is() )
772 xStyles
.set(xCellStyles
);
774 sName
= "CellStyles";
777 case XML_STYLE_FAMILY_TABLE_COLUMN
:
779 if( xColumnStyles
.is() )
780 xStyles
.set(xColumnStyles
);
782 sName
= "ColumnStyles";
785 case XML_STYLE_FAMILY_TABLE_ROW
:
787 if( xRowStyles
.is() )
788 xStyles
.set(xRowStyles
);
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).
814 case XML_STYLE_FAMILY_TABLE_TABLE
:
815 const_cast<XMLTableStylesContext
*>(this)->xTableStyles
.set(xStyles
);
817 case XML_STYLE_FAMILY_TABLE_CELL
:
818 const_cast<XMLTableStylesContext
*>(this)->xCellStyles
.set(xStyles
);
820 case XML_STYLE_FAMILY_TABLE_COLUMN
:
821 const_cast<XMLTableStylesContext
*>(this)->xColumnStyles
.set(xStyles
);
823 case XML_STYLE_FAMILY_TABLE_ROW
:
824 const_cast<XMLTableStylesContext
*>(this)->xRowStyles
.set(xStyles
);
834 OUString
XMLTableStylesContext::GetServiceName( sal_uInt16 nFamily
) const
836 OUString
sServiceName(SvXMLStylesContext::GetServiceName(nFamily
));
837 if (sServiceName
.isEmpty())
841 case XML_STYLE_FAMILY_TABLE_COLUMN
:
842 sServiceName
= gsColumnStyleServiceName
;
844 case XML_STYLE_FAMILY_TABLE_ROW
:
845 sServiceName
= gsRowStyleServiceName
;
847 case XML_STYLE_FAMILY_TABLE_CELL
:
848 sServiceName
= gsCellStyleServiceName
;
850 case XML_STYLE_FAMILY_TABLE_TABLE
:
851 sServiceName
= gsTableStyleServiceName
;
858 sal_Int32
XMLTableStylesContext::GetIndex(const sal_Int16 nContextID
)
860 if (nContextID
== CTF_SC_CELLSTYLE
)
862 if (nCellStyleIndex
== -1)
864 GetImportPropertyMapper(XML_STYLE_FAMILY_TABLE_CELL
)->getPropertySetMapper()->FindEntryIndex(nContextID
);
865 return nCellStyleIndex
;
867 else if (nContextID
== CTF_SC_NUMBERFORMAT
)
869 if (nNumberFormatIndex
== -1)
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
;
893 bool ScXMLMasterStylesContext::InsertStyleFamily( sal_uInt16
) const
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(
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!
929 SvXMLStyleContext
*ScXMLMasterStylesContext::CreateStyleStyleChildContext(
930 sal_uInt16
/* nFamily */,
931 sal_uInt16
/* nPrefix */,
932 const OUString
& /* rLocalName */,
933 const uno::Reference
< XAttributeList
> & /* xAttrList */ )
938 void ScXMLMasterStylesContext::EndElement()
944 ScMasterPageContext::ScMasterPageContext( SvXMLImport
& rImport
,
945 sal_uInt16 nPrfx
, const OUString
& rLName
,
946 const uno::Reference
< XAttributeList
> & xAttrList
,
948 XMLTextMasterPageContext( rImport
, nPrfx
, rLName
, xAttrList
, bOverwrite
),
949 bContainsRightHeader(false),
950 bContainsRightFooter(false)
954 ScMasterPageContext::~ScMasterPageContext()
958 SvXMLImportContext
*ScMasterPageContext::CreateHeaderFooterContext(
960 const OUString
& rLocalName
,
961 const css::uno::Reference
< css::xml::sax::XAttributeList
> & xAttrList
,
964 const bool /*bFirst*/ )
969 bContainsRightFooter
= true;
971 bContainsRightHeader
= true;
974 xPropSet
.set(GetStyle(), UNO_QUERY
);
975 return new XMLTableHeaderFooterContext( GetImport(),
982 void ScMasterPageContext::ClearContent(const OUString
& rContent
)
985 xPropSet
.set(GetStyle(), UNO_QUERY
);
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*/ ),
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
);
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
);
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: */