LibreOffice Module sw (master) 1
unostyle.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <o3tl/safeint.hxx>
23#include <o3tl/string_view.hxx>
25#include <hintids.hxx>
26#include <utility>
27#include <vcl/svapp.hxx>
28#include <svl/hint.hxx>
29#include <svtools/ctrltool.hxx>
30#include <svl/style.hxx>
31#include <svl/itemiter.hxx>
32#include <svl/listener.hxx>
33#include <svl/numformat.hxx>
34#include <svl/zforlist.hxx>
35#include <svl/zformat.hxx>
36#include <svx/pageitem.hxx>
37#include <editeng/colritem.hxx>
40#include <editeng/fontitem.hxx>
41#include <editeng/sizeitem.hxx>
42#include <editeng/udlnitem.hxx>
43#include <editeng/ulspitem.hxx>
44#include <editeng/lrspitem.hxx>
45#include <editeng/boxitem.hxx>
46#include <editeng/postitem.hxx>
47#include <editeng/shdditem.hxx>
48#include <editeng/brushitem.hxx>
49#include <editeng/flstitem.hxx>
50#include <editeng/fhgtitem.hxx>
51#include <editeng/paperinf.hxx>
52#include <editeng/wghtitem.hxx>
53#include <pagedesc.hxx>
54#include <doc.hxx>
55#include <IDocumentUndoRedo.hxx>
58#include <docary.hxx>
59#include <charfmt.hxx>
60#include <cmdid.h>
61#include <unomid.h>
62#include <unomap.hxx>
63#include <unostyle.hxx>
64#include <unosett.hxx>
65#include <docsh.hxx>
66#include <paratr.hxx>
67#include <unoprnms.hxx>
68#include <shellio.hxx>
69#include <docstyle.hxx>
70#include <unotextbodyhf.hxx>
71#include <fmthdft.hxx>
72#include <fmtpdsc.hxx>
73#include <strings.hrc>
74#include <poolfmt.hxx>
75#include <unoevent.hxx>
76#include <fmtruby.hxx>
77#include <SwStyleNameMapper.hxx>
78#include <sfx2/printer.hxx>
79#include <com/sun/star/frame/XModel.hpp>
80#include <com/sun/star/io/IOException.hpp>
81#include <com/sun/star/style/ParagraphStyleCategory.hpp>
82#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
83#include <com/sun/star/beans/PropertyAttribute.hpp>
84#include <com/sun/star/beans/NamedValue.hpp>
85#include <com/sun/star/drawing/BitmapMode.hpp>
86#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
87#include <com/sun/star/lang/IllegalArgumentException.hpp>
88#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
89#include <com/sun/star/document/XEventsSupplier.hpp>
90#include <com/sun/star/io/XInputStream.hpp>
91#include <istyleaccess.hxx>
92#include <fmtfsize.hxx>
93#include <numrule.hxx>
94#include <tblafmt.hxx>
95#include <frameformats.hxx>
96
102#include <sal/log.hxx>
103
104#include <svl/stylepool.hxx>
106#include <editeng/unoipset.hxx>
107#include <editeng/memberids.h>
108#include <svx/unomid.hxx>
109#include <svx/unoshape.hxx>
110#include <svx/xflbstit.hxx>
111#include <svx/xflbmtit.hxx>
112#include <swunohelper.hxx>
113#include <svx/xbtmpit.hxx>
114
115#include <ccoll.hxx>
116#include <hints.hxx>
117#include <uiitems.hxx>
118
119#include <cassert>
120#include <memory>
121#include <set>
122#include <string_view>
123#include <limits>
124
125using namespace css;
126using namespace css::io;
127using namespace css::lang;
128using namespace css::uno;
129
130namespace {
131
132class SwXStyle;
133class SwStyleProperties_Impl;
134
135 struct StyleFamilyEntry
136 {
137 using GetCountOrName_t = std::function<sal_Int32 (const SwDoc&, OUString*, sal_Int32)>;
138 using CreateStyle_t = std::function<uno::Reference<css::style::XStyle>(SfxStyleSheetBasePool*, SwDocShell*, const OUString&)>;
139 using TranslateIndex_t = std::function<sal_uInt16(const sal_uInt16)>;
140 SfxStyleFamily m_eFamily;
141 sal_uInt16 m_nPropMapType;
142 uno::Reference<beans::XPropertySetInfo> m_xPSInfo;
143 SwGetPoolIdFromName m_aPoolId;
144 OUString m_sName;
145 TranslateId m_pResId;
146 GetCountOrName_t m_fGetCountOrName;
147 CreateStyle_t m_fCreateStyle;
148 TranslateIndex_t m_fTranslateIndex;
149 StyleFamilyEntry(SfxStyleFamily eFamily, sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, OUString sName, TranslateId pResId, GetCountOrName_t fGetCountOrName, CreateStyle_t fCreateStyle, TranslateIndex_t fTranslateIndex)
150 : m_eFamily(eFamily)
151 , m_nPropMapType(nPropMapType)
152 , m_xPSInfo(aSwMapProvider.GetPropertySet(nPropMapType)->getPropertySetInfo())
153 , m_aPoolId(aPoolId)
154 , m_sName(std::move(sName))
155 , m_pResId(pResId)
156 , m_fGetCountOrName(std::move(fGetCountOrName))
157 , m_fCreateStyle(std::move(fCreateStyle))
158 , m_fTranslateIndex(std::move(fTranslateIndex))
159 { }
160 };
161 const std::vector<StyleFamilyEntry>* our_pStyleFamilyEntries;
162 // these should really be constexprs, but MSVC still is apparently too stupid for them
163 #define nPoolChrNormalRange (RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN)
164 #define nPoolChrHtmlRange (RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN)
165 #define nPoolCollTextRange ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)
166 #define nPoolCollListsRange ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)
167 #define nPoolCollExtraRange ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)
168 #define nPoolCollRegisterRange ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)
169 #define nPoolCollDocRange ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN)
170 #define nPoolCollHtmlRange ( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN)
171 #define nPoolFrameRange ( RES_POOLFRM_END - RES_POOLFRM_BEGIN)
172 #define nPoolPageRange ( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)
173 #define nPoolNumRange ( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN)
174 #define nPoolCollListsStackedStart ( nPoolCollTextRange)
175 #define nPoolCollExtraStackedStart ( nPoolCollListsStackedStart + nPoolCollListsRange)
176 #define nPoolCollRegisterStackedStart ( nPoolCollExtraStackedStart + nPoolCollExtraRange)
177 #define nPoolCollDocStackedStart ( nPoolCollRegisterStackedStart + nPoolCollRegisterRange)
178 #define nPoolCollHtmlStackedStart ( nPoolCollDocStackedStart + nPoolCollDocRange)
179 using paragraphstyle_t = std::remove_const<decltype(style::ParagraphStyleCategory::TEXT)>::type;
180 using collectionbits_t = sal_uInt16;
181 struct ParagraphStyleCategoryEntry
182 {
183 paragraphstyle_t m_eCategory;
184 SfxStyleSearchBits m_nSwStyleBits;
185 collectionbits_t m_nCollectionBits;
186 ParagraphStyleCategoryEntry(paragraphstyle_t eCategory, SfxStyleSearchBits nSwStyleBits, collectionbits_t nCollectionBits)
187 : m_eCategory(eCategory)
188 , m_nSwStyleBits(nSwStyleBits)
189 , m_nCollectionBits(nCollectionBits)
190 { }
191 };
192 const std::vector<ParagraphStyleCategoryEntry>* our_pParagraphStyleCategoryEntries;
193}
194static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries();
195
196using namespace ::com::sun::star;
197
198namespace sw
199{
200 namespace {
201
202 class XStyleFamily : public cppu::WeakImplHelper
203 <
204 container::XNameContainer,
205 lang::XServiceInfo,
206 container::XIndexAccess,
207 beans::XPropertySet
208 >
209 , public SfxListener
210 {
211 const StyleFamilyEntry& m_rEntry;
212 SfxStyleSheetBasePool* m_pBasePool;
213 SwDocShell* m_pDocShell;
214
215 SwXStyle* FindStyle(std::u16string_view rStyleName) const;
216 sal_Int32 GetCountOrName(OUString* pString, sal_Int32 nIndex = SAL_MAX_INT32)
217 { return m_rEntry.m_fGetCountOrName(*m_pDocShell->GetDoc(), pString, nIndex); };
218 static const StyleFamilyEntry& InitEntry(SfxStyleFamily eFamily)
219 {
220 auto pEntries = lcl_GetStyleFamilyEntries();
221 const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
222 [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
223 assert(pEntry != pEntries->end());
224 return *pEntry;
225 }
226 public:
227 XStyleFamily(SwDocShell* pDocShell, const SfxStyleFamily eFamily)
228 : m_rEntry(InitEntry(eFamily))
229 , m_pBasePool(pDocShell->GetStyleSheetPool())
230 , m_pDocShell(pDocShell)
231 {
232 if (m_pBasePool) //tdf#124142 html docs can have no styles
233 StartListening(*m_pBasePool);
234 }
235
236 //XIndexAccess
237 virtual sal_Int32 SAL_CALL getCount() override
238 {
239 SolarMutexGuard aGuard;
240 return GetCountOrName(nullptr);
241 };
242 virtual uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override;
243
244 //XElementAccess
245 virtual uno::Type SAL_CALL getElementType( ) override
247 virtual sal_Bool SAL_CALL hasElements( ) override
248 {
249 if(!m_pBasePool)
250 throw uno::RuntimeException();
251 return true;
252 }
253
254 //XNameAccess
255 virtual uno::Any SAL_CALL getByName(const OUString& Name) override;
256 virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
257 virtual sal_Bool SAL_CALL hasByName(const OUString& Name) override;
258
259 //XNameContainer
260 virtual void SAL_CALL insertByName(const OUString& Name, const uno::Any& Element) override;
261 virtual void SAL_CALL replaceByName(const OUString& Name, const uno::Any& Element) override;
262 virtual void SAL_CALL removeByName(const OUString& Name) override;
263
264 //XPropertySet
265 virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override
266 { return {}; };
267 virtual void SAL_CALL setPropertyValue( const OUString&, const uno::Any&) override
268 { SAL_WARN("sw.uno", "###unexpected!"); };
269 virtual uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
270 virtual void SAL_CALL addPropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override
271 { SAL_WARN("sw.uno", "###unexpected!"); };
272 virtual void SAL_CALL removePropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override
273 { SAL_WARN("sw.uno", "###unexpected!"); };
274 virtual void SAL_CALL addVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override
275 { SAL_WARN("sw.uno", "###unexpected!"); };
276 virtual void SAL_CALL removeVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override
277 { SAL_WARN("sw.uno", "###unexpected!"); };
278
279 //SfxListener
280 virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override
281 {
282 if(rHint.GetId() == SfxHintId::Dying)
283 {
284 m_pBasePool = nullptr;
285 m_pDocShell = nullptr;
286 EndListening(rBC);
287 }
288 }
289
290 //XServiceInfo
291 virtual OUString SAL_CALL getImplementationName() override
292 { return {"XStyleFamily"}; };
293 virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override
294 { return cppu::supportsService(this, rServiceName); };
295 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
296 { return { "com.sun.star.style.StyleFamily" }; }
297 };
298
299 }
300}
301
302namespace {
303
304class SwStyleBase_Impl;
305class SwXStyle : public cppu::WeakImplHelper
306 <
307 css::style::XStyle,
308 css::beans::XPropertySet,
309 css::beans::XMultiPropertySet,
310 css::lang::XServiceInfo,
311 css::lang::XUnoTunnel,
312 css::beans::XPropertyState,
313 css::beans::XMultiPropertyStates
314 >
315 , public SfxListener
316 , public SvtListener
317{
318 SwDoc* m_pDoc;
319 OUString m_sStyleName;
320 const StyleFamilyEntry& m_rEntry;
321 bool m_bIsDescriptor;
322 bool m_bIsConditional;
323 OUString m_sParentStyleName;
324
325protected:
326 SfxStyleSheetBasePool* m_pBasePool;
327 std::unique_ptr<SwStyleProperties_Impl> m_pPropertiesImpl;
328 css::uno::Reference<css::container::XNameAccess> m_xStyleFamily;
329 css::uno::Reference<css::beans::XPropertySet> m_xStyleData;
330
331 template<sal_uInt16>
332 void SetPropertyValue(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&);
333 void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues );
334 SfxStyleSheetBase* GetStyleSheetBase();
335 void PrepareStyleBase(SwStyleBase_Impl& rBase);
336 template<sal_uInt16>
337 uno::Any GetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
338 uno::Any GetStyleProperty_Impl(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
339 uno::Any GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName);
340
341public:
342 SwXStyle(SwDoc* pDoc, SfxStyleFamily eFam, bool bConditional = false);
343 SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const OUString& rStyleName);
344 virtual ~SwXStyle() override;
345
346
347 static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId();
348
349 //XUnoTunnel
350 virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override;
351
352 //XNamed
353 virtual OUString SAL_CALL getName() override;
354 virtual void SAL_CALL setName(const OUString& Name_) override;
355
356 //XStyle
357 virtual sal_Bool SAL_CALL isUserDefined() override;
358 virtual sal_Bool SAL_CALL isInUse() override;
359 virtual OUString SAL_CALL getParentStyle() override;
360 virtual void SAL_CALL setParentStyle(const OUString& aParentStyle) override;
361
362 //XPropertySet
363 virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override;
364 virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
365 virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
366 virtual void SAL_CALL addPropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override
367 { OSL_FAIL("not implemented"); };
368 virtual void SAL_CALL removePropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override
369 { OSL_FAIL("not implemented"); };
370 virtual void SAL_CALL addVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override
371 { OSL_FAIL("not implemented"); };
372 virtual void SAL_CALL removeVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override
373 { OSL_FAIL("not implemented"); };
374
375 //XMultiPropertySet
376 virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override;
377 virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override;
378 virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
379 {};
380 virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
381 {};
382 virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
383 {};
384
385 //XPropertyState
386 virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override;
387 virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override;
388 virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override;
389 virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override;
390
391 //XMultiPropertyStates
392 virtual void SAL_CALL setAllPropertiesToDefault( ) override;
393 virtual void SAL_CALL setPropertiesToDefault( const css::uno::Sequence< OUString >& aPropertyNames ) override;
394 virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyDefaults( const css::uno::Sequence< OUString >& aPropertyNames ) override;
395
396 //XServiceInfo
397 virtual OUString SAL_CALL getImplementationName() override
398 { return {"SwXStyle"}; };
399 virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override
400 { return cppu::supportsService(this, rServiceName); };
401 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
402
403 //SfxListener
404 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
405 //SvtListener
406 virtual void Notify(const SfxHint&) override;
407 const OUString& GetStyleName() const { return m_sStyleName;}
408 SfxStyleFamily GetFamily() const {return m_rEntry.m_eFamily;}
409
410 bool IsDescriptor() const {return m_bIsDescriptor;}
411 bool IsConditional() const { return m_bIsConditional;}
412 const OUString& GetParentStyleName() const { return m_sParentStyleName;}
413 void SetDoc(SwDoc* pDc, SfxStyleSheetBasePool* pPool)
414 {
415 m_bIsDescriptor = false; m_pDoc = pDc;
416 m_pBasePool = pPool;
417 SfxListener::StartListening(*m_pBasePool);
418 }
419 SwDoc* GetDoc() const { return m_pDoc; }
420 void Invalidate();
421 void ApplyDescriptorProperties();
422 void SetStyleName(const OUString& rSet){ m_sStyleName = rSet;}
427 void SetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase);
428 void PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertyMapEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl);
429};
430
431class SwXFrameStyle
432 : public SwXStyle
433 , public css::document::XEventsSupplier
434 , public sw::ICoreFrameStyle
435{
436public:
437 SwXFrameStyle(SfxStyleSheetBasePool& rPool,
438 SwDoc* pDoc,
439 const OUString& rStyleName) :
440 SwXStyle(&rPool, SfxStyleFamily::Frame, pDoc, rStyleName){}
441 explicit SwXFrameStyle(SwDoc *pDoc);
442
443 virtual void SAL_CALL acquire( ) noexcept override {SwXStyle::acquire();}
444 virtual void SAL_CALL release( ) noexcept override {SwXStyle::release();}
445
446 virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
447 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
448 virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents( ) override;
449
450 //ICoreStyle
451 virtual void SetItem(sal_uInt16 eAtr, const SfxPoolItem& rItem) override;
452 virtual const SfxPoolItem* GetItem(sal_uInt16 eAtr) override;
453 virtual css::document::XEventsSupplier& GetEventsSupplier() override
454 { return *this; };
455};
456
457class SwXPageStyle
458 : public SwXStyle
459{
460protected:
461 void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues );
462 css::uno::Sequence< css::uno::Any > GetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames );
463
464public:
465 SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName);
466 explicit SwXPageStyle(SwDocShell* pDocSh);
467
468 virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
469 virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
470
471 virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override;
472 virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override;
473};
474
475}
476
477using sw::XStyleFamily;
478
480 { return {"SwXStyleFamilies"}; }
481
482sal_Bool SwXStyleFamilies::supportsService(const OUString& rServiceName)
483{
484 return cppu::supportsService(this, rServiceName);
485}
486
488 { return { "com.sun.star.style.StyleFamilies" }; }
489
491 SwUnoCollection(rDocShell.GetDoc()),
492 m_pDocShell(&rDocShell)
493 { }
494
496 { }
497
498uno::Any SAL_CALL SwXStyleFamilies::getByName(const OUString& Name)
499{
500 SolarMutexGuard aGuard;
501 if(!IsValid())
502 throw uno::RuntimeException();
503 auto pEntries(lcl_GetStyleFamilyEntries());
504 const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
505 [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; });
506 if(pEntry == pEntries->end())
507 throw container::NoSuchElementException();
508 return getByIndex(pEntry-pEntries->begin());
509}
510
511uno::Sequence< OUString > SwXStyleFamilies::getElementNames()
512{
513 auto pEntries(lcl_GetStyleFamilyEntries());
514 uno::Sequence<OUString> aNames(pEntries->size());
515 std::transform(pEntries->begin(), pEntries->end(),
516 aNames.getArray(), [] (const StyleFamilyEntry& e) { return e.m_sName; });
517 return aNames;
518}
519
521{
522 auto pEntries(lcl_GetStyleFamilyEntries());
523 return std::any_of(pEntries->begin(), pEntries->end(),
524 [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; });
525}
526
528{
529 return lcl_GetStyleFamilyEntries()->size();
530}
531
533{
534 auto pEntries(lcl_GetStyleFamilyEntries());
535 SolarMutexGuard aGuard;
536 if(nIndex < 0 || o3tl::make_unsigned(nIndex) >= pEntries->size())
537 throw lang::IndexOutOfBoundsException();
538 if(!IsValid())
539 throw uno::RuntimeException();
540 auto eFamily = (*pEntries)[nIndex].m_eFamily;
541 assert(eFamily != SfxStyleFamily::All);
542 auto& rxFamily = m_vFamilies[eFamily];
543 if(!rxFamily.is())
544 rxFamily = new XStyleFamily(m_pDocShell, eFamily);
545 return uno::Any(rxFamily);
546}
547
549{
551}
552
554 { return true; }
555
556void SwXStyleFamilies::loadStylesFromURL(const OUString& rURL,
557 const uno::Sequence< beans::PropertyValue >& aOptions)
558{
559 SolarMutexGuard aGuard;
560 if(!IsValid() || rURL.isEmpty())
561 throw uno::RuntimeException();
562 SwgReaderOption aOpt;
563 aOpt.SetFrameFormats(true);
564 aOpt.SetTextFormats(true);
565 aOpt.SetPageDescs(true);
566 aOpt.SetNumRules(true);
567 aOpt.SetMerge(false);
568 for(const auto& rProperty: aOptions)
569 {
570 bool bValue = false;
571 if(rProperty.Value.getValueType() == cppu::UnoType<bool>::get())
572 bValue = rProperty.Value.get<bool>();
573
574 if(rProperty.Name == UNO_NAME_OVERWRITE_STYLES)
575 aOpt.SetMerge(!bValue);
576 else if(rProperty.Name == UNO_NAME_LOAD_NUMBERING_STYLES)
577 aOpt.SetNumRules(bValue);
578 else if(rProperty.Name == UNO_NAME_LOAD_PAGE_STYLES)
579 aOpt.SetPageDescs(bValue);
580 else if(rProperty.Name == UNO_NAME_LOAD_FRAME_STYLES)
581 aOpt.SetFrameFormats(bValue);
582 else if(rProperty.Name == UNO_NAME_LOAD_TEXT_STYLES)
583 aOpt.SetTextFormats(bValue);
584 else if(rProperty.Name == "InputStream")
585 {
586 Reference<XInputStream> xInputStream;
587 if (!(rProperty.Value >>= xInputStream))
588 throw IllegalArgumentException("Parameter 'InputStream' could not be converted to "
589 "type 'com::sun::star::io::XInputStream'",
590 nullptr, 0);
591
592 aOpt.SetInputStream(xInputStream);
593
594 }
595 }
596 const ErrCode nErr = m_pDocShell->LoadStylesFromFile( rURL, aOpt, true );
597 if(nErr)
598 throw io::IOException();
599}
600
601uno::Sequence< beans::PropertyValue > SwXStyleFamilies::getStyleLoaderOptions()
602{
603 const uno::Any aVal(true);
610 });
611}
612
614 SfxItemSet const& rSet, std::u16string_view rPropName, bool const bFooter,
615 SvxSetItem const*& o_rpItem)
616{
617 o_rpItem = rSet.GetItemIfSet(
618 bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
619 false);
620 if (!o_rpItem &&
621 rPropName == UNO_NAME_FIRST_IS_SHARED)
622 { // fdo#79269 header may not exist, check footer then
623 o_rpItem = rSet.GetItemIfSet(
624 (!bFooter) ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
625 false);
626 }
627 return o_rpItem;
628}
629
630template<enum SfxStyleFamily>
631static sal_Int32 lcl_GetCountOrName(const SwDoc&, OUString*, sal_Int32);
632
633template<>
634sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Char>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
635{
636 const sal_uInt16 nBaseCount = nPoolChrHtmlRange + nPoolChrNormalRange;
637 nIndex -= nBaseCount;
638 sal_Int32 nCount = 0;
639 for(auto pFormat : *rDoc.GetCharFormats())
640 {
641 if(pFormat->IsDefault() && pFormat != rDoc.GetDfltCharFormat())
642 continue;
643 if(!IsPoolUserFormat(pFormat->GetPoolFormatId()))
644 continue;
645 if(nIndex == nCount)
646 {
647 // the default character format needs to be set to "Default!"
648 if(rDoc.GetDfltCharFormat() == pFormat)
649 *pString = SwResId(STR_POOLCHR_STANDARD);
650 else
651 *pString = pFormat->GetName();
652 break;
653 }
654 ++nCount;
655 }
656 return nCount + nBaseCount;
657}
658
659template<>
660sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Para>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
661{
662 const sal_uInt16 nBaseCount = nPoolCollHtmlStackedStart + nPoolCollHtmlRange;
663 nIndex -= nBaseCount;
664 sal_Int32 nCount = 0;
665 for(auto pColl : *rDoc.GetTextFormatColls())
666 {
667 if(pColl->IsDefault())
668 continue;
669 if(!IsPoolUserFormat(pColl->GetPoolFormatId()))
670 continue;
671 if(nIndex == nCount)
672 {
673 *pString = pColl->GetName();
674 break;
675 }
676 ++nCount;
677 }
678 return nCount + nBaseCount;
679}
680
681template<>
682sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Frame>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
683{
685 sal_Int32 nCount = 0;
686 for(const auto pFormat : *rDoc.GetFrameFormats())
687 {
688 if(pFormat->IsDefault() || pFormat->IsAuto())
689 continue;
690 if(!IsPoolUserFormat(pFormat->GetPoolFormatId()))
691 continue;
692 if(nIndex == nCount)
693 {
694 *pString = pFormat->GetName();
695 break;
696 }
697 ++nCount;
698 }
699 return nCount + nPoolFrameRange;
700}
701
702template<>
703sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Page>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
704{
706 sal_Int32 nCount = 0;
707 const size_t nArrLen = rDoc.GetPageDescCnt();
708 for(size_t i = 0; i < nArrLen; ++i)
709 {
710 const SwPageDesc& rDesc = rDoc.GetPageDesc(i);
712 continue;
713 if(nIndex == nCount)
714 {
715 *pString = rDesc.GetName();
716 break;
717 }
718 ++nCount;
719 }
721 return nCount;
722}
723
724template<>
725sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Pseudo>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
726{
728 sal_Int32 nCount = 0;
729 for(const auto pRule : rDoc.GetNumRuleTable())
730 {
731 if(pRule->IsAutoRule())
732 continue;
733 if(!IsPoolUserFormat(pRule->GetPoolFormatId()))
734 continue;
735 if(nIndex == nCount)
736 {
737 *pString = pRule->GetName();
738 break;
739 }
740 ++nCount;
741 }
742 return nCount + nPoolNumRange;
743}
744
745template<>
746sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Table>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
747{
748 if (!rDoc.HasTableStyles())
749 return 0;
750
751 const auto pAutoFormats = &rDoc.GetTableStyles();
752 const sal_Int32 nCount = pAutoFormats->size();
753 if (0 <= nIndex && nIndex < nCount)
754 *pString = pAutoFormats->operator[](nIndex).GetName();
755
756 return nCount;
757}
758
759template<>
760sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Cell>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
761{
762 const auto& rAutoFormats = rDoc.GetTableStyles();
763 const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
764 const sal_Int32 nUsedCellStylesCount = rAutoFormats.size() * rTableTemplateMap.size();
765 const sal_Int32 nCount = nUsedCellStylesCount + rDoc.GetCellStyles().size();
766 if (0 <= nIndex && nIndex < nCount)
767 {
768 if (nUsedCellStylesCount > nIndex)
769 {
770 const sal_Int32 nAutoFormat = nIndex / rTableTemplateMap.size();
771 const sal_Int32 nBoxFormat = rTableTemplateMap[nIndex % rTableTemplateMap.size()];
772 const SwTableAutoFormat& rTableFormat = rAutoFormats[nAutoFormat];
774 *pString += rTableFormat.GetTableTemplateCellSubName(rTableFormat.GetBoxFormat(nBoxFormat));
775 }
776 else
777 *pString = rDoc.GetCellStyles()[nIndex-nUsedCellStylesCount].GetName();
778 }
779 return nCount;
780}
781
782template<SfxStyleFamily eFamily>
783static uno::Reference< css::style::XStyle> lcl_CreateStyle(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
784 { return pBasePool ? new SwXStyle(pBasePool, eFamily, pDocShell->GetDoc(), sStyleName) : new SwXStyle(pDocShell->GetDoc(), eFamily, false); };
785
786template<>
787uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Para>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
788 { return pBasePool ? new SwXStyle(pBasePool, SfxStyleFamily::Para, pDocShell->GetDoc(), sStyleName) : new SwXStyle(pDocShell->GetDoc(), SfxStyleFamily::Para, false); };
789template<>
790uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Frame>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
791 { return pBasePool ? new SwXFrameStyle(*pBasePool, pDocShell->GetDoc(), sStyleName) : new SwXFrameStyle(pDocShell->GetDoc()); };
792
793template<>
794uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Page>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
795 { return pBasePool ? new SwXPageStyle(*pBasePool, pDocShell, sStyleName) : new SwXPageStyle(pDocShell); };
796
797template<>
798uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Table>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
799 { return SwXTextTableStyle::CreateXTextTableStyle(pDocShell, sStyleName); };
800
801template<>
802uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Cell>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
803 { return SwXTextCellStyle::CreateXTextCellStyle(pDocShell, sStyleName); };
804
805uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyle(SfxStyleFamily eFamily, SwDoc& rDoc)
806{
807 auto pEntries(lcl_GetStyleFamilyEntries());
808 const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
809 [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
810 return pEntry == pEntries->end() ? nullptr : pEntry->m_fCreateStyle(nullptr, rDoc.GetDocShell(), "");
811}
812
813// FIXME: Ugly special casing that should die.
814uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyleCondParagraph(SwDoc& rDoc)
815 { return new SwXStyle(&rDoc, SfxStyleFamily::Para, true); };
816
817template<enum SfxStyleFamily>
818static sal_uInt16 lcl_TranslateIndex(const sal_uInt16 nIndex);
819
820template<>
821sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Char>(const sal_uInt16 nIndex)
822{
823 static_assert(nPoolChrNormalRange > 0 && nPoolChrHtmlRange > 0, "invalid pool range");
828 throw lang::IndexOutOfBoundsException();
829}
830
831template<>
832sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Para>(const sal_uInt16 nIndex)
833{
834 static_assert(nPoolCollTextRange > 0 && nPoolCollListsRange > 0 && nPoolCollExtraRange > 0 && nPoolCollRegisterRange > 0 && nPoolCollDocRange > 0 && nPoolCollHtmlRange > 0, "weird pool range");
847 throw lang::IndexOutOfBoundsException();
848}
849
850template<>
851sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Table>(const sal_uInt16 nIndex)
852{
853 return nIndex;
854}
855
856template<>
857sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Cell>(const sal_uInt16 nIndex)
858{
859 return nIndex;
860}
861
862template<sal_uInt16 nRangeBegin, sal_uInt16 nRangeSize>
863static sal_uInt16 lcl_TranslateIndexRange(const sal_uInt16 nIndex)
864{
865 if(nIndex < nRangeSize)
866 return nIndex + nRangeBegin;
867 throw lang::IndexOutOfBoundsException();
868}
869
870uno::Any XStyleFamily::getByIndex(sal_Int32 nIndex)
871{
872 SolarMutexGuard aGuard;
873 if(nIndex < 0)
874 throw lang::IndexOutOfBoundsException();
875 if(!m_pBasePool)
876 throw uno::RuntimeException();
877 OUString sStyleName;
878 try
879 {
880 SwStyleNameMapper::FillUIName(m_rEntry.m_fTranslateIndex(nIndex), sStyleName);
881 } catch(...) {}
882 if (sStyleName.isEmpty())
883 GetCountOrName(&sStyleName, nIndex);
884 if(sStyleName.isEmpty())
885 throw lang::IndexOutOfBoundsException();
886 return getByName(sStyleName);
887}
888
889uno::Any XStyleFamily::getByName(const OUString& rName)
890{
891 SolarMutexGuard aGuard;
892 OUString sStyleName;
893 SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId);
894 if(!m_pBasePool)
895 throw uno::RuntimeException();
896 SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
897 if(!pBase)
898 throw container::NoSuchElementException(rName);
899 uno::Reference<style::XStyle> xStyle = FindStyle(sStyleName);
900 if(!xStyle.is())
901 xStyle = m_rEntry.m_fCreateStyle(m_pBasePool, m_pDocShell, m_rEntry.m_eFamily == SfxStyleFamily::Frame ? pBase->GetName() : sStyleName);
902 return uno::Any(xStyle);
903}
904
905uno::Sequence<OUString> XStyleFamily::getElementNames()
906{
907 SolarMutexGuard aGuard;
908 if(!m_pBasePool)
909 throw uno::RuntimeException();
910 std::vector<OUString> vRet;
911 std::unique_ptr<SfxStyleSheetIterator> pIt = m_pBasePool->CreateIterator(m_rEntry.m_eFamily);
912 for (SfxStyleSheetBase* pStyle = pIt->First(); pStyle; pStyle = pIt->Next())
913 {
914 OUString sName;
915 SwStyleNameMapper::FillProgName(pStyle->GetName(), sName, m_rEntry.m_aPoolId);
916 vRet.push_back(sName);
917 }
919}
920
921sal_Bool XStyleFamily::hasByName(const OUString& rName)
922{
923 SolarMutexGuard aGuard;
924 if(!m_pBasePool)
925 throw uno::RuntimeException();
926 OUString sStyleName;
927 SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId);
928 SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
929 return nullptr != pBase;
930}
931
932void XStyleFamily::insertByName(const OUString& rName, const uno::Any& rElement)
933{
934 SolarMutexGuard aGuard;
935 if(!m_pBasePool)
936 throw uno::RuntimeException();
937 OUString sStyleName;
938 SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId);
939 SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
940 SfxStyleSheetBase* pUINameBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
941 if(pBase || pUINameBase)
942 throw container::ElementExistException();
943 if(rElement.getValueType().getTypeClass() != uno::TypeClass_INTERFACE)
944 throw lang::IllegalArgumentException();
945 if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId)
946 {
947 // handle cell style
948 uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
949 SwXTextCellStyle* pNewStyle = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
950 if (!pNewStyle)
951 throw lang::IllegalArgumentException();
952
953 pNewStyle->setName(sStyleName); // insertByName sets the element name
954 m_pDocShell->GetDoc()->GetCellStyles().AddBoxFormat(*pNewStyle->GetBoxFormat(), sStyleName);
955 pNewStyle->SetPhysical();
956 }
957 else if (SwGetPoolIdFromName::TabStyle == m_rEntry.m_aPoolId)
958 {
959 // handle table style
960 uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
961 SwXTextTableStyle* pNewStyle = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
962 if (!pNewStyle)
963 throw lang::IllegalArgumentException();
964
965 pNewStyle->setName(sStyleName); // insertByName sets the element name
966 m_pDocShell->GetDoc()->GetTableStyles().AddAutoFormat(*pNewStyle->GetTableFormat());
967 pNewStyle->SetPhysical();
968 }
969 else
970 {
971 uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>();
972 SwXStyle* pNewStyle = comphelper::getFromUnoTunnel<SwXStyle>(xStyleTunnel);
973 if (!pNewStyle || !pNewStyle->IsDescriptor() || pNewStyle->GetFamily() != m_rEntry.m_eFamily)
974 throw lang::IllegalArgumentException();
975
976 SfxStyleSearchBits nMask = SfxStyleSearchBits::All;
977 if(m_rEntry.m_eFamily == SfxStyleFamily::Para && !pNewStyle->IsConditional())
978 nMask &= ~SfxStyleSearchBits::SwCondColl;
979 m_pBasePool->Make(sStyleName, m_rEntry.m_eFamily, nMask);
980 pNewStyle->SetDoc(m_pDocShell->GetDoc(), m_pBasePool);
981 pNewStyle->SetStyleName(sStyleName);
982 const OUString sParentStyleName(pNewStyle->GetParentStyleName());
983 if (!sParentStyleName.isEmpty())
984 {
985 SfxStyleSheetBase* pParentBase = m_pBasePool->Find(sParentStyleName, m_rEntry.m_eFamily);
986 if(pParentBase && pParentBase->GetFamily() == m_rEntry.m_eFamily &&
987 pParentBase->GetPool() == m_pBasePool)
988 m_pBasePool->SetParent(m_rEntry.m_eFamily, sStyleName, sParentStyleName);
989 }
990 // after all, we still need to apply the properties of the descriptor
991 pNewStyle->ApplyDescriptorProperties();
992 }
993}
994
995void XStyleFamily::replaceByName(const OUString& rName, const uno::Any& rElement)
996{
997 SolarMutexGuard aGuard;
998 if(!m_pBasePool)
999 throw uno::RuntimeException();
1000 OUString sStyleName;
1001 SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.m_aPoolId);
1002 SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
1003 // replacements only for userdefined styles
1004 if(!pBase)
1005 throw container::NoSuchElementException();
1006 if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId)
1007 {
1008 // handle cell styles, don't call on assigned cell styles (TableStyle child)
1009 OUString sParent;
1010 SwBoxAutoFormat* pBoxAutoFormat = SwXTextCellStyle::GetBoxAutoFormat(m_pDocShell, sStyleName, &sParent);
1011 if (pBoxAutoFormat && sParent.isEmpty())// if parent exists then this style is assigned to a table style. Don't replace.
1012 {
1013 uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
1014 SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
1015 if (!pStyleToReplaceWith)
1016 throw lang::IllegalArgumentException();
1017
1018 pStyleToReplaceWith->setName(sStyleName);
1019 *pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat();
1020 pStyleToReplaceWith->SetPhysical();
1021 }
1022 }
1023 else if (SwGetPoolIdFromName::TabStyle == m_rEntry.m_aPoolId)
1024 {
1025 // handle table styles
1026 SwTableAutoFormat* pTableAutoFormat = SwXTextTableStyle::GetTableAutoFormat(m_pDocShell, sStyleName);
1027 if (pTableAutoFormat)
1028 {
1029 uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
1030 SwXTextTableStyle* pStyleToReplaceWith = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
1031 if (!pStyleToReplaceWith)
1032 throw lang::IllegalArgumentException();
1033
1034 pStyleToReplaceWith->setName(sStyleName);
1035 *pTableAutoFormat = *pStyleToReplaceWith->GetTableFormat();
1036 pStyleToReplaceWith->SetPhysical();
1037 }
1038 }
1039 else
1040 {
1041 if(!pBase->IsUserDefined())
1042 throw lang::IllegalArgumentException();
1043 //if there's an object available to this style then it must be invalidated
1044 uno::Reference<style::XStyle> xStyle = FindStyle(pBase->GetName());
1045 if(xStyle.is())
1046 {
1047 SwXStyle* pStyle = comphelper::getFromUnoTunnel<SwXStyle>(xStyle);
1048 if(pStyle)
1049 pStyle->Invalidate();
1050 }
1051 m_pBasePool->Remove(pBase);
1052 insertByName(rName, rElement);
1053 }
1054}
1055
1056void XStyleFamily::removeByName(const OUString& rName)
1057{
1058 SolarMutexGuard aGuard;
1059 if(!m_pBasePool)
1060 throw uno::RuntimeException();
1061 OUString sName;
1062 SwStyleNameMapper::FillUIName(rName, sName, m_rEntry.m_aPoolId);
1063 SfxStyleSheetBase* pBase = m_pBasePool->Find(sName, m_rEntry.m_eFamily);
1064 if(!pBase)
1065 throw container::NoSuchElementException();
1066 if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId)
1067 {
1068 // handle cell style
1069 m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(rName);
1070 }
1071 else if (SwGetPoolIdFromName::TabStyle == m_rEntry.m_aPoolId)
1072 {
1073 // handle table style
1074 m_pDocShell->GetDoc()->GetTableStyles().EraseAutoFormat(rName);
1075 }
1076 else
1077 m_pBasePool->Remove(pBase);
1078}
1079
1080uno::Any SAL_CALL XStyleFamily::getPropertyValue( const OUString& sPropertyName )
1081{
1082 if(sPropertyName != "DisplayName")
1083 throw beans::UnknownPropertyException( "unknown property: " + sPropertyName, static_cast<OWeakObject *>(this) );
1084 SolarMutexGuard aGuard;
1085 return uno::Any(SwResId(m_rEntry.m_pResId));
1086}
1087
1088
1089SwXStyle* XStyleFamily::FindStyle(std::u16string_view rStyleName) const
1090{
1091 const size_t nLCount = m_pBasePool->GetSizeOfVector();
1092 for(size_t i = 0; i < nLCount; ++i)
1093 {
1094 SfxListener* pListener = m_pBasePool->GetListener(i);
1095 SwXStyle* pTempStyle = dynamic_cast<SwXStyle*>(pListener);
1096 if(pTempStyle && pTempStyle->GetFamily() == m_rEntry.m_eFamily && pTempStyle->GetStyleName() == rStyleName)
1097 return pTempStyle;
1098 }
1099 return nullptr;
1100}
1101
1102static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries()
1103{
1104 if(!our_pStyleFamilyEntries)
1105 {
1106 our_pStyleFamilyEntries = new std::vector<StyleFamilyEntry>{
1107 { SfxStyleFamily::Char, PROPERTY_MAP_CHAR_STYLE, SwGetPoolIdFromName::ChrFmt, "CharacterStyles", STR_STYLE_FAMILY_CHARACTER, &lcl_GetCountOrName<SfxStyleFamily::Char>, &lcl_CreateStyle<SfxStyleFamily::Char>, &lcl_TranslateIndex<SfxStyleFamily::Char> },
1108 { SfxStyleFamily::Para, PROPERTY_MAP_PARA_STYLE, SwGetPoolIdFromName::TxtColl, "ParagraphStyles", STR_STYLE_FAMILY_PARAGRAPH, &lcl_GetCountOrName<SfxStyleFamily::Para>, &lcl_CreateStyle<SfxStyleFamily::Para>, &lcl_TranslateIndex<SfxStyleFamily::Para> },
1109 { SfxStyleFamily::Page, PROPERTY_MAP_PAGE_STYLE, SwGetPoolIdFromName::PageDesc, "PageStyles", STR_STYLE_FAMILY_PAGE, &lcl_GetCountOrName<SfxStyleFamily::Page>, &lcl_CreateStyle<SfxStyleFamily::Page>, &lcl_TranslateIndexRange<RES_POOLPAGE_BEGIN, nPoolPageRange> },
1110 { SfxStyleFamily::Frame, PROPERTY_MAP_FRAME_STYLE, SwGetPoolIdFromName::FrmFmt, "FrameStyles", STR_STYLE_FAMILY_FRAME, &lcl_GetCountOrName<SfxStyleFamily::Frame>, &lcl_CreateStyle<SfxStyleFamily::Frame>, &lcl_TranslateIndexRange<RES_POOLFRM_BEGIN, nPoolFrameRange> },
1111 { SfxStyleFamily::Pseudo, PROPERTY_MAP_NUM_STYLE, SwGetPoolIdFromName::NumRule, "NumberingStyles", STR_STYLE_FAMILY_NUMBERING, &lcl_GetCountOrName<SfxStyleFamily::Pseudo>, &lcl_CreateStyle<SfxStyleFamily::Pseudo>, &lcl_TranslateIndexRange<RES_POOLNUMRULE_BEGIN, nPoolNumRange> },
1112 { SfxStyleFamily::Table, PROPERTY_MAP_TABLE_STYLE, SwGetPoolIdFromName::TabStyle, "TableStyles", STR_STYLE_FAMILY_TABLE, &lcl_GetCountOrName<SfxStyleFamily::Table>, &lcl_CreateStyle<SfxStyleFamily::Table>, &lcl_TranslateIndex<SfxStyleFamily::Table> },
1113 { SfxStyleFamily::Cell, PROPERTY_MAP_CELL_STYLE, SwGetPoolIdFromName::CellStyle,"CellStyles", STR_STYLE_FAMILY_CELL, &lcl_GetCountOrName<SfxStyleFamily::Cell>, &lcl_CreateStyle<SfxStyleFamily::Cell>, &lcl_TranslateIndex<SfxStyleFamily::Cell> }
1114 };
1115 }
1116 return our_pStyleFamilyEntries;
1117}
1118
1119static const std::vector<ParagraphStyleCategoryEntry>* lcl_GetParagraphStyleCategoryEntries()
1120{
1121 if(!our_pParagraphStyleCategoryEntries)
1122 {
1123 our_pParagraphStyleCategoryEntries = new std::vector<ParagraphStyleCategoryEntry>{
1124 { style::ParagraphStyleCategory::TEXT, SfxStyleSearchBits::SwText, COLL_TEXT_BITS },
1125 { style::ParagraphStyleCategory::CHAPTER, SfxStyleSearchBits::SwChapter, COLL_DOC_BITS },
1126 { style::ParagraphStyleCategory::LIST, SfxStyleSearchBits::SwList, COLL_LISTS_BITS },
1127 { style::ParagraphStyleCategory::INDEX, SfxStyleSearchBits::SwIndex, COLL_REGISTER_BITS },
1128 { style::ParagraphStyleCategory::EXTRA, SfxStyleSearchBits::SwExtra, COLL_EXTRA_BITS },
1129 { style::ParagraphStyleCategory::HTML, SfxStyleSearchBits::SwHtml, COLL_HTML_BITS }
1130 };
1131 }
1132 return our_pParagraphStyleCategoryEntries;
1133}
1134
1135namespace {
1136
1137class SwStyleProperties_Impl
1138{
1139 const SfxItemPropertyMap& mrMap;
1140 std::map<OUString, uno::Any> m_vPropertyValues;
1141public:
1142 explicit SwStyleProperties_Impl(const SfxItemPropertyMap& rMap)
1143 : mrMap(rMap)
1144 { }
1145
1146 bool AllowsKey(std::u16string_view rName)
1147 {
1148 return mrMap.hasPropertyByName(rName);
1149 }
1150 bool SetProperty(const OUString& rName, const uno::Any& rValue)
1151 {
1152 if(!AllowsKey(rName))
1153 return false;
1154 m_vPropertyValues[rName] = rValue;
1155 return true;
1156 }
1157 void GetProperty(const OUString& rName, const uno::Any*& pAny)
1158 {
1159 if(!AllowsKey(rName))
1160 {
1161 pAny = nullptr;
1162 return;
1163 }
1164 pAny = &m_vPropertyValues[rName];
1165 return;
1166 }
1167 bool ClearProperty( const OUString& rName )
1168 {
1169 if(!AllowsKey(rName))
1170 return false;
1171 m_vPropertyValues[rName] = uno::Any();
1172 return true;
1173 }
1174 void ClearAllProperties( )
1175 { m_vPropertyValues.clear(); }
1176 void Apply(SwXStyle& rStyle)
1177 {
1178 for(const auto& rPropertyPair : m_vPropertyValues)
1179 {
1180 if(rPropertyPair.second.hasValue())
1181 rStyle.setPropertyValue(rPropertyPair.first, rPropertyPair.second);
1182 }
1183 }
1184 static void GetProperty(const OUString &rPropertyName, const uno::Reference < beans::XPropertySet > &rxPropertySet, uno::Any& rAny )
1185 {
1186 rAny = rxPropertySet->getPropertyValue( rPropertyName );
1187 }
1188};
1189
1190}
1191
1193{
1194 auto pEntries(lcl_GetStyleFamilyEntries());
1195 const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
1196 [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
1197 if(pEntry != pEntries->end())
1198 return pEntry->m_aPoolId;
1199 SAL_WARN("sw.uno", "someone asking for all styles in unostyle.cxx!" );
1201}
1202
1203namespace
1204{
1205}
1206
1207const uno::Sequence<sal_Int8>& SwXStyle::getUnoTunnelId()
1208{
1209 static const comphelper::UnoIdInit theSwXStyleUnoTunnelId;
1210 return theSwXStyleUnoTunnelId.getSeq();
1211}
1212
1213sal_Int64 SAL_CALL SwXStyle::getSomething(const uno::Sequence<sal_Int8>& rId)
1214{
1215 return comphelper::getSomethingImpl(rId, this);
1216}
1217
1218
1219uno::Sequence< OUString > SwXStyle::getSupportedServiceNames()
1220{
1221 tools::Long nCount = 1;
1222 if(SfxStyleFamily::Para == m_rEntry.m_eFamily)
1223 {
1224 nCount = 5;
1225 if(m_bIsConditional)
1226 nCount++;
1227 }
1228 else if(SfxStyleFamily::Char == m_rEntry.m_eFamily)
1229 nCount = 5;
1230 else if(SfxStyleFamily::Page == m_rEntry.m_eFamily)
1231 nCount = 3;
1232 uno::Sequence< OUString > aRet(nCount);
1233 OUString* pArray = aRet.getArray();
1234 pArray[0] = "com.sun.star.style.Style";
1235 switch(m_rEntry.m_eFamily)
1236 {
1237 case SfxStyleFamily::Char:
1238 pArray[1] = "com.sun.star.style.CharacterStyle";
1239 pArray[2] = "com.sun.star.style.CharacterProperties";
1240 pArray[3] = "com.sun.star.style.CharacterPropertiesAsian";
1241 pArray[4] = "com.sun.star.style.CharacterPropertiesComplex";
1242 break;
1243 case SfxStyleFamily::Page:
1244 pArray[1] = "com.sun.star.style.PageStyle";
1245 pArray[2] = "com.sun.star.style.PageProperties";
1246 break;
1247 case SfxStyleFamily::Para:
1248 pArray[1] = "com.sun.star.style.ParagraphStyle";
1249 pArray[2] = "com.sun.star.style.ParagraphProperties";
1250 pArray[3] = "com.sun.star.style.ParagraphPropertiesAsian";
1251 pArray[4] = "com.sun.star.style.ParagraphPropertiesComplex";
1252 if(m_bIsConditional)
1253 pArray[5] = "com.sun.star.style.ConditionalParagraphStyle";
1254 break;
1255
1256 default:
1257 ;
1258 }
1259 return aRet;
1260}
1261
1262static uno::Reference<beans::XPropertySet> lcl_InitStandardStyle(const SfxStyleFamily eFamily, uno::Reference<container::XNameAccess> const & rxStyleFamily)
1263{
1264 using return_t = decltype(lcl_InitStandardStyle(eFamily, rxStyleFamily));
1265 if(eFamily != SfxStyleFamily::Para && eFamily != SfxStyleFamily::Page)
1266 return {};
1267 auto aResult(rxStyleFamily->getByName("Standard"));
1268 if(!aResult.has<return_t>())
1269 return {};
1270 return aResult.get<return_t>();
1271}
1272
1273static uno::Reference<container::XNameAccess> lcl_InitStyleFamily(SwDoc* pDoc, const StyleFamilyEntry& rEntry)
1274{
1275 using return_t = decltype(lcl_InitStyleFamily(pDoc, rEntry));
1276 if(rEntry.m_eFamily != SfxStyleFamily::Char
1277 && rEntry.m_eFamily != SfxStyleFamily::Para
1278 && rEntry.m_eFamily != SfxStyleFamily::Page)
1279 return {};
1280 auto xModel(pDoc->GetDocShell()->GetBaseModel());
1281 uno::Reference<style::XStyleFamiliesSupplier> xFamilySupplier(xModel, uno::UNO_QUERY);
1282 auto xFamilies = xFamilySupplier->getStyleFamilies();
1283 auto aResult(xFamilies->getByName(rEntry.m_sName));
1284 if(!aResult.has<return_t>())
1285 return {};
1286 return aResult.get<return_t>();
1287}
1288
1289static bool lcl_InitConditional(SfxStyleSheetBasePool* pBasePool, const SfxStyleFamily eFamily, const OUString& rStyleName)
1290{
1291 if(!pBasePool || eFamily != SfxStyleFamily::Para)
1292 return false;
1293 SfxStyleSheetBase* pBase = pBasePool->Find(rStyleName, eFamily);
1294 SAL_WARN_IF(!pBase, "sw.uno", "where is the style?" );
1295 if(!pBase)
1296 return false;
1298 if(nId != USHRT_MAX)
1300 return RES_CONDTXTFMTCOLL == static_cast<SwDocStyleSheet*>(pBase)->GetCollection()->Which();
1301}
1302
1303static const StyleFamilyEntry& lcl_GetStyleEntry(const SfxStyleFamily eFamily)
1304{
1305 auto pEntries = lcl_GetStyleFamilyEntries();
1306 const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
1307 [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
1308 assert(pEntry != pEntries->end());
1309 return *pEntry;
1310}
1311
1312SwXStyle::SwXStyle(SwDoc* pDoc, SfxStyleFamily eFamily, bool bConditional)
1313 : m_pDoc(pDoc)
1314 , m_rEntry(lcl_GetStyleEntry(eFamily))
1315 , m_bIsDescriptor(true)
1316 , m_bIsConditional(bConditional)
1317 , m_pBasePool(nullptr)
1318 , m_xStyleFamily(lcl_InitStyleFamily(pDoc, m_rEntry))
1319 , m_xStyleData(lcl_InitStandardStyle(eFamily, m_xStyleFamily))
1320{
1321 assert(!m_bIsConditional || m_rEntry.m_eFamily == SfxStyleFamily::Para); // only paragraph styles are conditional
1322 // Register ourselves as a listener to the document (via the page descriptor)
1324 m_pPropertiesImpl = std::make_unique<SwStyleProperties_Impl>(
1325 aSwMapProvider.GetPropertySet(m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType)->getPropertyMap());
1326}
1327
1328SwXStyle::SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const OUString& rStyleName)
1329 : m_pDoc(pDoc)
1330 , m_sStyleName(rStyleName)
1331 , m_rEntry(lcl_GetStyleEntry(eFamily))
1332 , m_bIsDescriptor(false)
1333 , m_bIsConditional(lcl_InitConditional(pPool, eFamily, rStyleName))
1334 , m_pBasePool(pPool)
1335{ }
1336
1337SwXStyle::~SwXStyle()
1338{
1339 SolarMutexGuard aGuard;
1340 if(m_pBasePool)
1341 SfxListener::EndListening(*m_pBasePool);
1342 m_pPropertiesImpl.reset();
1344}
1345
1346void SwXStyle::Notify(const SfxHint& rHint)
1347{
1348 if(rHint.GetId() == SfxHintId::Dying)
1349 {
1350 m_pDoc = nullptr;
1351 m_xStyleData.clear();
1352 m_xStyleFamily.clear();
1353 }
1354}
1355
1356OUString SwXStyle::getName()
1357{
1358 SolarMutexGuard aGuard;
1359 if(!m_pBasePool)
1360 return m_sStyleName;
1361 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
1362 SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
1363 if(!pBase)
1364 throw uno::RuntimeException();
1365 OUString aString;
1366 SwStyleNameMapper::FillProgName(pBase->GetName(), aString, lcl_GetSwEnumFromSfxEnum ( m_rEntry.m_eFamily ));
1367 return aString;
1368}
1369
1370void SwXStyle::setName(const OUString& rName)
1371{
1372 SolarMutexGuard aGuard;
1373 if(!m_pBasePool)
1374 {
1375 m_sStyleName = rName;
1376 return;
1377 }
1378 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
1379 SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
1380 if(!pBase || !pBase->IsUserDefined())
1381 throw uno::RuntimeException();
1382 rtl::Reference<SwDocStyleSheet> xTmp(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
1383 if(!xTmp->SetName(rName))
1384 throw uno::RuntimeException();
1385 m_sStyleName = rName;
1386}
1387
1388sal_Bool SwXStyle::isUserDefined()
1389{
1390 SolarMutexGuard aGuard;
1391 if(!m_pBasePool)
1392 throw uno::RuntimeException();
1393 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
1394 //if it is not found it must be non user defined
1395 return pBase && pBase->IsUserDefined();
1396}
1397
1398sal_Bool SwXStyle::isInUse()
1399{
1400 SolarMutexGuard aGuard;
1401 if(!m_pBasePool)
1402 throw uno::RuntimeException();
1403 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily, SfxStyleSearchBits::Used);
1404 return pBase && pBase->IsUsed();
1405}
1406
1407OUString SwXStyle::getParentStyle()
1408{
1409 SolarMutexGuard aGuard;
1410 if(!m_pBasePool)
1411 {
1412 if(!m_bIsDescriptor)
1413 throw uno::RuntimeException();
1414 return m_sParentStyleName;
1415 }
1416 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
1417 OUString aString;
1418 if(pBase)
1419 aString = pBase->GetParent();
1420 SwStyleNameMapper::FillProgName(aString, aString, lcl_GetSwEnumFromSfxEnum(m_rEntry.m_eFamily));
1421 return aString;
1422}
1423
1424void SwXStyle::setParentStyle(const OUString& rParentStyle)
1425{
1426 SolarMutexGuard aGuard;
1427 OUString sParentStyle;
1428 SwStyleNameMapper::FillUIName(rParentStyle, sParentStyle, lcl_GetSwEnumFromSfxEnum ( m_rEntry.m_eFamily ) );
1429 if(!m_pBasePool)
1430 {
1431 if(!m_bIsDescriptor)
1432 throw uno::RuntimeException();
1433 m_sParentStyleName = sParentStyle;
1434 try
1435 {
1436 const auto aAny = m_xStyleFamily->getByName(sParentStyle);
1437 m_xStyleData = aAny.get<decltype(m_xStyleData)>();
1438 }
1439 catch(...)
1440 { }
1441 return;
1442 }
1443 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
1444 if(!pBase)
1445 throw uno::RuntimeException();
1446 rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
1447 //make it a 'real' style - necessary for pooled styles
1448 xBase->GetItemSet();
1449 if(xBase->GetParent() != sParentStyle)
1450 {
1451 if(!xBase->SetParent(sParentStyle))
1452 throw uno::RuntimeException();
1453 }
1454}
1455
1456uno::Reference<beans::XPropertySetInfo> SwXStyle::getPropertySetInfo()
1457{
1458 if(m_bIsConditional)
1459 {
1460 assert(m_rEntry.m_eFamily == SfxStyleFamily::Para);
1461 static uno::Reference<beans::XPropertySetInfo> xCondParaRef;
1463 return xCondParaRef;
1464 }
1465 return m_rEntry.m_xPSInfo;
1466}
1467
1468void SwXStyle::ApplyDescriptorProperties()
1469{
1470 m_bIsDescriptor = false;
1471 m_xStyleData.clear();
1472 m_xStyleFamily.clear();
1473 m_pPropertiesImpl->Apply(*this);
1474}
1475
1476namespace {
1477
1478class SwStyleBase_Impl
1479{
1480private:
1481 SwDoc& m_rDoc;
1482 const SwPageDesc* m_pOldPageDesc;
1484 SfxItemSet* m_pItemSet;
1485 std::unique_ptr<SfxItemSet> m_pMyItemSet;
1486 OUString m_rStyleName;
1487 const SwAttrSet* m_pParentStyle;
1488public:
1489 SwStyleBase_Impl(SwDoc& rSwDoc, OUString aName, const SwAttrSet* pParentStyle)
1490 : m_rDoc(rSwDoc)
1491 , m_pOldPageDesc(nullptr)
1492 , m_pItemSet(nullptr)
1493 , m_rStyleName(std::move(aName))
1494 , m_pParentStyle(pParentStyle)
1495 { }
1496
1498 {
1499 return m_xNewBase;
1500 }
1501
1502 void setNewBase(SwDocStyleSheet* pNew)
1503 {
1504 m_xNewBase = pNew;
1505 }
1506
1507 bool HasItemSet() const
1508 {
1509 return m_xNewBase.is();
1510 }
1511
1513 {
1514 assert(m_xNewBase.is());
1515 if(!m_pItemSet)
1516 {
1517 m_pMyItemSet.reset(new SfxItemSet(m_xNewBase->GetItemSet()));
1518 m_pItemSet = m_pMyItemSet.get();
1519
1520 // set parent style to have the correct XFillStyle setting as XFILL_NONE
1521 if(!m_pItemSet->GetParent() && m_pParentStyle)
1522 m_pItemSet->SetParent(m_pParentStyle);
1523 }
1524 return *m_pItemSet;
1525 }
1526
1527 const SwPageDesc* GetOldPageDesc();
1528
1529 // still a hack, but a bit more explicit and with a proper scope
1530 struct ItemSetOverrider
1531 {
1532 SwStyleBase_Impl& m_rStyleBase;
1533 SfxItemSet* m_pOldSet;
1534 ItemSetOverrider(SwStyleBase_Impl& rStyleBase, SfxItemSet* pTemp)
1535 : m_rStyleBase(rStyleBase)
1536 , m_pOldSet(m_rStyleBase.m_pItemSet)
1537 { m_rStyleBase.m_pItemSet = pTemp; }
1538 ~ItemSetOverrider()
1539 { m_rStyleBase.m_pItemSet = m_pOldSet; };
1540 };
1541};
1542
1544 {
1545 // Page styles
1546 STR_POOLPAGE_STANDARD,
1547 STR_POOLPAGE_FIRST,
1548 STR_POOLPAGE_LEFT,
1549 STR_POOLPAGE_RIGHT,
1550 STR_POOLPAGE_ENVELOPE,
1551 STR_POOLPAGE_REGISTER,
1552 STR_POOLPAGE_HTML,
1553 STR_POOLPAGE_FOOTNOTE,
1554 STR_POOLPAGE_ENDNOTE,
1555 STR_POOLPAGE_LANDSCAPE
1556 };
1557}
1558
1559const SwPageDesc* SwStyleBase_Impl::GetOldPageDesc()
1560{
1561 if(!m_pOldPageDesc)
1562 {
1563 SwPageDesc *pd = m_rDoc.FindPageDesc(m_rStyleName);
1564 if(pd)
1565 m_pOldPageDesc = pd;
1566
1567 if(!m_pOldPageDesc)
1568 {
1569 for (size_t i = 0; i < SAL_N_ELEMENTS(STR_POOLPAGE_ARY); ++i)
1570 {
1571 if (SwResId(STR_POOLPAGE_ARY[i]) == m_rStyleName)
1572 {
1574 break;
1575 }
1576 }
1577 }
1578 }
1579 return m_pOldPageDesc;
1580}
1581
1582
1583
1585{
1586 // check for needed metric translation
1587 if(!(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM))
1588 return rEntry.nMemberId;
1589 // exception: If these ItemTypes are used, do not convert when these are negative
1590 // since this means they are intended as percent values
1591 if((XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID)
1592 && o_aValue.has<sal_Int32>()
1593 && o_aValue.get<sal_Int32>() < 0)
1594 return rEntry.nMemberId;
1595 if(!pDoc)
1596 return rEntry.nMemberId;
1597
1598 const SfxItemPool& rPool = pDoc->GetAttrPool();
1599 const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID));
1600 if(eMapUnit != MapUnit::Map100thMM)
1601 SvxUnoConvertFromMM(eMapUnit, o_aValue);
1602 return rEntry.nMemberId;
1603}
1604template<>
1605void SwXStyle::SetPropertyValue<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1606{
1607 // default ItemSet handling
1608 SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1609 SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID);
1610 aSet.SetParent(&rStyleSet);
1611 rPropSet.setPropertyValue(rEntry, rValue, aSet);
1612 rStyleSet.Put(aSet);
1613}
1614template<>
1615void SwXStyle::SetPropertyValue<FN_UNO_HIDDEN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1616{
1617 bool bHidden = false;
1618 if(rValue >>= bHidden)
1619 {
1620 //make it a 'real' style - necessary for pooled styles
1621 o_rStyleBase.getNewBase()->GetItemSet();
1622 o_rStyleBase.getNewBase()->SetHidden(bHidden);
1623 }
1624 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
1625}
1626template<>
1627void SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1628{
1629 o_rStyleBase.getNewBase()->GetItemSet();
1630 o_rStyleBase.getNewBase()->SetGrabBagItem(rValue);
1631 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
1632}
1633template<>
1634void SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1635{
1636 uno::Any aValue(rValue);
1637 const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue));
1638 if(MID_NAME == nMemberId)
1639 {
1640 // add set commands for FillName items
1641 SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1642 if(!aValue.has<OUString>())
1643 throw lang::IllegalArgumentException();
1644 SvxShape::SetFillAttribute(rEntry.nWID, aValue.get<OUString>(), rStyleSet);
1645 }
1646 else if(MID_BITMAP == nMemberId)
1647 {
1648 if(sal_uInt16(XATTR_FILLBITMAP) == rEntry.nWID)
1649 {
1650 Graphic aNullGraphic;
1651 SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1652 XFillBitmapItem aXFillBitmapItem(std::move(aNullGraphic));
1653 aXFillBitmapItem.PutValue(aValue, nMemberId);
1654 rStyleSet.Put(aXFillBitmapItem);
1655 }
1656 }
1657 else
1658 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase);
1659}
1660template<>
1661void SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1662{
1663 SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1664 const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rStyleSet, RES_BACKGROUND, true, m_pDoc->IsInXMLImport()));
1665 std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone());
1666
1667 uno::Any aValue(rValue);
1668 const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue));
1669 aChangedBrushItem->PutValue(aValue, nMemberId);
1670
1671 // 0xff is already the default - but if BackTransparent is set
1672 // to true, it must be applied in the item set on ODF import
1673 // to potentially override parent style, which is unknown yet
1674 if(*aChangedBrushItem == *aOriginalBrushItem && (MID_GRAPHIC_TRANSPARENT != nMemberId || !aValue.has<bool>() || !aValue.get<bool>()))
1675 return;
1676
1677 setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, rStyleSet);
1678}
1679template<>
1680void SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1681{
1682 drawing::BitmapMode eMode;
1683 if(!(rValue >>= eMode))
1684 {
1685 if(!rValue.has<sal_Int32>())
1686 throw lang::IllegalArgumentException();
1687 eMode = static_cast<drawing::BitmapMode>(rValue.get<sal_Int32>());
1688 }
1689 SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1690 rStyleSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode));
1691 rStyleSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode));
1692}
1693template<>
1694void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1695{
1696 if(!rValue.has<OUString>())
1697 throw lang::IllegalArgumentException();
1698 SfxPrinter* pPrinter = m_pDoc->getIDocumentDeviceAccess().getPrinter(true);
1699 OUString sValue(rValue.get<OUString>());
1700 using printeridx_t = decltype(pPrinter->GetPaperBinCount());
1701 printeridx_t nBin = std::numeric_limits<printeridx_t>::max();
1702 if(sValue == "[From printer settings]")
1703 nBin = std::numeric_limits<printeridx_t>::max()-1;
1704 else if(pPrinter)
1705 {
1706 for(sal_uInt16 i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i)
1707 {
1708 if (sValue == pPrinter->GetPaperBinName(i))
1709 {
1710 nBin = i;
1711 break;
1712 }
1713 }
1714 }
1715 if(nBin == std::numeric_limits<printeridx_t>::max())
1716 throw lang::IllegalArgumentException();
1717 SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1718 SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID);
1719 aSet.SetParent(&rStyleSet);
1720 rPropSet.setPropertyValue(rEntry, uno::Any(static_cast<sal_Int8>(nBin == std::numeric_limits<printeridx_t>::max()-1 ? -1 : nBin)), aSet);
1721 rStyleSet.Put(aSet);
1722}
1723template<>
1724void SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1725{
1726 if(!rValue.has<uno::Reference<container::XIndexReplace>>() || !rValue.has<uno::Reference<lang::XUnoTunnel>>())
1727 throw lang::IllegalArgumentException();
1728 auto xNumberTunnel(rValue.get<uno::Reference<lang::XUnoTunnel>>());
1729 SwXNumberingRules* pSwXRules = comphelper::getFromUnoTunnel<SwXNumberingRules>(xNumberTunnel);
1730 if(!pSwXRules)
1731 return;
1732 SwNumRule aSetRule(*pSwXRules->GetNumRule());
1733 for(sal_uInt16 i = 0; i < MAXLEVEL; ++i)
1734 {
1735 const SwNumFormat* pFormat = aSetRule.GetNumFormat(i);
1736 if(!pFormat)
1737 continue;
1738 SwNumFormat aFormat(*pFormat);
1739 const auto& rCharName(pSwXRules->GetNewCharStyleNames()[i]);
1740 if(!rCharName.isEmpty()
1742 && (!pFormat->GetCharFormat() || pFormat->GetCharFormat()->GetName() != rCharName))
1743 {
1744 auto pCharFormatIt(std::find_if(m_pDoc->GetCharFormats()->begin(), m_pDoc->GetCharFormats()->end(),
1745 [&rCharName] (SwCharFormat* pF) { return pF->GetName() == rCharName; }));
1746 if(pCharFormatIt != m_pDoc->GetCharFormats()->end())
1747 aFormat.SetCharFormat(*pCharFormatIt);
1748 else if(m_pBasePool)
1749 {
1750 auto pBase(m_pBasePool->Find(rCharName, SfxStyleFamily::Char));
1751 if(!pBase)
1752 pBase = &m_pBasePool->Make(rCharName, SfxStyleFamily::Char);
1753 aFormat.SetCharFormat(static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat());
1754 }
1755 else
1756 aFormat.SetCharFormat(nullptr);
1757 }
1758 // same for fonts:
1759 const auto& rBulletName(pSwXRules->GetBulletFontNames()[i]);
1760 if(!rBulletName.isEmpty()
1761 && !SwXNumberingRules::isInvalidStyle(rBulletName)
1762 && (!pFormat->GetBulletFont() || pFormat->GetBulletFont()->GetFamilyName() != rBulletName))
1763 {
1764 const auto pFontListItem(static_cast<const SvxFontListItem*>(m_pDoc->GetDocShell()->GetItem(SID_ATTR_CHAR_FONTLIST)));
1765 const auto pList(pFontListItem->GetFontList());
1766 FontMetric aFontInfo(pList->Get(rBulletName, WEIGHT_NORMAL, ITALIC_NONE));
1767 vcl::Font aFont(aFontInfo);
1768 aFormat.SetBulletFont(&aFont);
1769 }
1770 aSetRule.Set(i, &aFormat);
1771 }
1772 o_rStyleBase.getNewBase()->SetNumRule(aSetRule);
1773}
1774template<>
1775void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1776{
1777 if(!rValue.has<sal_Int16>())
1778 return;
1779 const auto nLevel(rValue.get<sal_Int16>());
1780 if(0 <= nLevel && nLevel <= MAXLEVEL)
1781 o_rStyleBase.getNewBase()->GetCollection()->SetAttrOutlineLevel(nLevel);
1782}
1783template<>
1784void SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1785{
1786 if(!rValue.has<OUString>())
1787 return;
1788 const auto sValue(rValue.get<OUString>());
1789 OUString aString;
1790 SwStyleNameMapper::FillUIName(sValue, aString, m_rEntry.m_aPoolId);
1791 o_rStyleBase.getNewBase()->SetFollow(aString);
1792}
1793
1794template <>
1795void SwXStyle::SetPropertyValue<FN_UNO_LINK_STYLE>(const SfxItemPropertyMapEntry&,
1796 const SfxItemPropertySet&,
1797 const uno::Any& rValue,
1798 SwStyleBase_Impl& o_rStyleBase)
1799{
1800 if (!rValue.has<OUString>())
1801 return;
1802 const auto sValue(rValue.get<OUString>());
1803 OUString aString;
1804 SwStyleNameMapper::FillUIName(sValue, aString, m_rEntry.m_aPoolId);
1805 o_rStyleBase.getNewBase()->SetLink(aString);
1806}
1807
1808template<>
1809void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1810{
1812 {
1813 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
1814 return;
1815 }
1816 if(!rValue.has<OUString>())
1817 throw lang::IllegalArgumentException();
1818 // special handling for RES_PAGEDESC
1819 SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1820 std::unique_ptr<SwFormatPageDesc> pNewDesc;
1821 if(const SwFormatPageDesc* pItem = rStyleSet.GetItemIfSet(RES_PAGEDESC))
1822 pNewDesc.reset(new SwFormatPageDesc(*pItem));
1823 else
1824 pNewDesc.reset(new SwFormatPageDesc);
1825 const auto sValue(rValue.get<OUString>());
1826 OUString sDescName;
1828 if(pNewDesc->GetPageDesc() && pNewDesc->GetPageDesc()->GetName() == sDescName)
1829 return;
1830 if(sDescName.isEmpty())
1831 {
1832 rStyleSet.ClearItem(RES_BREAK);
1833 rStyleSet.Put(SwFormatPageDesc());
1834 }
1835 else
1836 {
1837 SwPageDesc* pPageDesc(SwPageDesc::GetByName(*m_pDoc, sDescName));
1838 if(!pPageDesc)
1839 throw lang::IllegalArgumentException();
1840 pNewDesc->RegisterToPageDesc(*pPageDesc);
1841 rStyleSet.Put(std::move(pNewDesc));
1842 }
1843}
1844template<>
1845void SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1846{
1847 if(m_rEntry.m_eFamily != SfxStyleFamily::Page)
1848 {
1849 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
1850 return;
1851 }
1852 if(!m_pDoc || !rValue.has<drawing::TextVerticalAdjust>() || !o_rStyleBase.GetOldPageDesc())
1853 return;
1854 SwPageDesc* pPageDesc = m_pDoc->FindPageDesc(o_rStyleBase.GetOldPageDesc()->GetName());
1855 if(pPageDesc)
1856 pPageDesc->SetVerticalAdjustment(rValue.get<drawing::TextVerticalAdjust>());
1857}
1858template<>
1859void SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1860{
1861 if(!rValue.has<bool>())
1862 throw lang::IllegalArgumentException();
1863 const bool bAuto(rValue.get<bool>());
1864 if(SfxStyleFamily::Para == m_rEntry.m_eFamily)
1865 o_rStyleBase.getNewBase()->GetCollection()->SetAutoUpdateFormat(bAuto);
1866 else if(SfxStyleFamily::Frame == m_rEntry.m_eFamily)
1867 o_rStyleBase.getNewBase()->GetFrameFormat()->SetAutoUpdateFormat(bAuto);
1868}
1869template<>
1870void SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1871{
1872 static_assert(COND_COMMAND_COUNT == 28, "invalid size of command count?");
1873 using expectedarg_t = uno::Sequence<beans::NamedValue>;
1874 if(!rValue.has<expectedarg_t>() || !m_pBasePool)
1875 throw lang::IllegalArgumentException();
1876 SwCondCollItem aCondItem;
1877 const auto aNamedValues = rValue.get<expectedarg_t>();
1878 for(const auto& rNamedValue : aNamedValues)
1879 {
1880 if(!rNamedValue.Value.has<OUString>())
1881 throw lang::IllegalArgumentException();
1882
1883 const OUString sValue(rNamedValue.Value.get<OUString>());
1884 // get UI style name from programmatic style name
1885 OUString aStyleName;
1886 SwStyleNameMapper::FillUIName(sValue, aStyleName, lcl_GetSwEnumFromSfxEnum(m_rEntry.m_eFamily));
1887
1888 // check for correct context and style name
1889 const auto nIdx(GetCommandContextIndex(rNamedValue.Name));
1890 if (nIdx == -1)
1891 throw lang::IllegalArgumentException();
1892 bool bStyleFound = false;
1893 for(auto pBase = m_pBasePool->First(SfxStyleFamily::Para); pBase; pBase = m_pBasePool->Next())
1894 {
1895 bStyleFound = pBase->GetName() == aStyleName;
1896 if (bStyleFound)
1897 break;
1898 }
1899 if (!bStyleFound)
1900 throw lang::IllegalArgumentException();
1901 aCondItem.SetStyle(&aStyleName, nIdx);
1902 }
1903 o_rStyleBase.GetItemSet().Put(aCondItem);
1904}
1905template<>
1906void SwXStyle::SetPropertyValue<FN_UNO_CATEGORY>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1907{
1908 if(!o_rStyleBase.getNewBase()->IsUserDefined() || !rValue.has<paragraphstyle_t>())
1909 throw lang::IllegalArgumentException();
1910 static std::optional<std::map<paragraphstyle_t, SfxStyleSearchBits>> pUnoToCore;
1911 if(!pUnoToCore)
1912 {
1913 pUnoToCore.emplace();
1914 auto pEntries = lcl_GetParagraphStyleCategoryEntries();
1915 std::transform(pEntries->begin(), pEntries->end(), std::inserter(*pUnoToCore, pUnoToCore->end()),
1916 [] (const ParagraphStyleCategoryEntry& rEntry) { return std::pair<paragraphstyle_t, SfxStyleSearchBits>(rEntry.m_eCategory, rEntry.m_nSwStyleBits); });
1917 }
1918 const auto pUnoToCoreIt(pUnoToCore->find(rValue.get<paragraphstyle_t>()));
1919 if(pUnoToCoreIt == pUnoToCore->end())
1920 throw lang::IllegalArgumentException();
1921 o_rStyleBase.getNewBase()->SetMask( pUnoToCoreIt->second|SfxStyleSearchBits::UserDefined );
1922}
1923template<>
1924void SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1925{
1926 OUString sName;
1927 rValue >>= sName;
1928 SwRegisterItem aReg(!sName.isEmpty());
1929 aReg.SetWhich(SID_SWREGISTER_MODE);
1930 o_rStyleBase.GetItemSet().Put(aReg);
1931 OUString aString;
1933 o_rStyleBase.GetItemSet().Put(SfxStringItem(SID_SWREGISTER_COLLECTION, aString ) );
1934}
1935template<>
1936void SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1937{
1938 if(MID_RUBY_CHARSTYLE != rEntry.nMemberId)
1939 return;
1940 if(!rValue.has<OUString>())
1941 throw lang::IllegalArgumentException();
1942 const auto sValue(rValue.get<OUString>());
1943 SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet());
1944 std::unique_ptr<SwFormatRuby> pRuby;
1945 if(const SwFormatRuby* pRubyItem = rStyleSet.GetItemIfSet(RES_TXTATR_CJK_RUBY))
1946 pRuby.reset(new SwFormatRuby(*pRubyItem));
1947 else
1948 pRuby.reset(new SwFormatRuby(OUString()));
1949 OUString sStyle;
1951 pRuby->SetCharFormatName(sValue);
1952 pRuby->SetCharFormatId(0);
1953 if(!sValue.isEmpty())
1954 {
1956 pRuby->SetCharFormatId(nId);
1957 }
1958 rStyleSet.Put(std::move(pRuby));
1959 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
1960}
1961template<>
1962void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1963{
1965 {
1966 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
1967 return;
1968 }
1969 if(!rValue.has<OUString>())
1970 throw lang::IllegalArgumentException();
1971 SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet());
1972 std::unique_ptr<SwFormatDrop> pDrop;
1973 if(const SwFormatDrop* pDropItem = rStyleSet.GetItemIfSet(RES_PARATR_DROP))
1974 pDrop.reset(new SwFormatDrop(*pDropItem));
1975 else
1976 pDrop.reset(new SwFormatDrop);
1977 const auto sValue(rValue.get<OUString>());
1978 OUString sStyle;
1980 auto pStyle(static_cast<SwDocStyleSheet*>(m_pDoc->GetDocShell()->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Char)));
1981 //default character style must not be set as default format
1982 if(!pStyle || pStyle->GetCharFormat() == m_pDoc->GetDfltCharFormat() )
1983 {
1984 throw lang::IllegalArgumentException();
1985 }
1986 pDrop->SetCharFormat(pStyle->GetCharFormat());
1987 rStyleSet.Put(std::move(pDrop));
1988}
1989template<>
1990void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1991{
1992 uno::Any aValue(rValue);
1993 lcl_TranslateMetric(rEntry, m_pDoc, aValue);
1994 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase);
1995 // --> OD 2006-10-18 #i70223#
1996 if(SfxStyleFamily::Para == m_rEntry.m_eFamily &&
1997 o_rStyleBase.getNewBase().is() && o_rStyleBase.getNewBase()->GetCollection() &&
1998 //rBase.getNewBase()->GetCollection()->GetOutlineLevel() < MAXLEVEL /* assigned to list level of outline style */) //#outline level,removed by zhaojianwei
1999 o_rStyleBase.getNewBase()->GetCollection()->IsAssignedToListLevelOfOutlineStyle())
2000 {
2001 OUString sNewNumberingRuleName;
2002 aValue >>= sNewNumberingRuleName;
2003 if(sNewNumberingRuleName.isEmpty() || sNewNumberingRuleName != m_pDoc->GetOutlineNumRule()->GetName())
2004 o_rStyleBase.getNewBase()->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle();
2005 }
2006}
2007
2008void SwXStyle::SetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase)
2009{
2010 using propertytype_t = decltype(rEntry.nWID);
2011 using coresetter_t = std::function<void(SwXStyle&, const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&)>;
2012 static std::optional<std::map<propertytype_t, coresetter_t>> pUnoToCore;
2013 if(!pUnoToCore)
2014 {
2015 pUnoToCore = std::map<propertytype_t, coresetter_t> {
2016 // these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again
2017 { FN_UNO_HIDDEN, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_HIDDEN>) },
2018 { FN_UNO_STYLE_INTEROP_GRAB_BAG, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG>) },
2019 { XATTR_FILLGRADIENT, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
2020 { XATTR_FILLHATCH, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
2021 { XATTR_FILLBITMAP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
2022 { XATTR_FILLFLOATTRANSPARENCE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
2023 { RES_BACKGROUND, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>) },
2024 { OWN_ATTR_FILLBMP_MODE, std::mem_fn(&SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>) },
2025 { RES_PAPER_BIN, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>) },
2026 { FN_UNO_NUM_RULES, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES>) },
2028 { FN_UNO_FOLLOW_STYLE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE>) },
2029 { FN_UNO_LINK_STYLE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_LINK_STYLE>) },
2030 { RES_PAGEDESC, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>) },
2032 { FN_UNO_IS_AUTO_UPDATE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE>) },
2033 { FN_UNO_PARA_STYLE_CONDITIONS, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS>) },
2034 { FN_UNO_CATEGORY, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_CATEGORY>) },
2035 { SID_SWREGISTER_COLLECTION, std::mem_fn(&SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION>) },
2037 { RES_PARATR_DROP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>) },
2039 };
2040 }
2041 const auto pUnoToCoreIt(pUnoToCore->find(rEntry.nWID));
2042 if(pUnoToCoreIt != pUnoToCore->end())
2043 pUnoToCoreIt->second(*this, rEntry, rPropSet, rValue, rBase);
2044 else
2045 {
2046 // adapted switch logic to a more readable state; removed goto's and made
2047 // execution of standard setting of property in ItemSet dependent of this variable
2048 uno::Any aValue(rValue);
2049 lcl_TranslateMetric(rEntry, m_pDoc, aValue);
2050 SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, rBase);
2051 }
2052}
2053
2054void SwXStyle::SetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
2055{
2056 if(!m_pDoc)
2057 throw uno::RuntimeException();
2058 sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
2059 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
2060 const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
2061 if(rPropertyNames.getLength() != rValues.getLength())
2062 throw lang::IllegalArgumentException();
2063
2064 SwStyleBase_Impl aBaseImpl(*m_pDoc, m_sStyleName, &GetDoc()->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
2065 if(m_pBasePool)
2066 {
2067 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
2068 SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
2069 if(!pBase)
2070 throw uno::RuntimeException();
2071 aBaseImpl.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
2072 }
2073 if(!aBaseImpl.getNewBase().is() && !m_bIsDescriptor)
2074 throw uno::RuntimeException();
2075
2076 const OUString* pNames = rPropertyNames.getConstArray();
2077 const uno::Any* pValues = rValues.getConstArray();
2078 for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
2079 {
2080 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(pNames[nProp]);
2081 if(!pEntry || (!m_bIsConditional && pNames[nProp] == UNO_NAME_PARA_STYLE_CONDITIONS))
2082 throw beans::UnknownPropertyException("Unknown property: " + pNames[nProp], static_cast<cppu::OWeakObject*>(this));
2083 if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
2084 throw beans::PropertyVetoException ("Property is read-only: " + pNames[nProp], static_cast<cppu::OWeakObject*>(this));
2085 if(aBaseImpl.getNewBase().is())
2086 SetStyleProperty(*pEntry, *pPropSet, pValues[nProp], aBaseImpl);
2087 else if(!m_pPropertiesImpl->SetProperty(pNames[nProp], pValues[nProp]))
2088 throw lang::IllegalArgumentException();
2089 }
2090
2091 if(aBaseImpl.HasItemSet())
2092 aBaseImpl.getNewBase()->SetItemSet(aBaseImpl.GetItemSet());
2093}
2094
2095void SwXStyle::setPropertyValues(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
2096{
2097 SolarMutexGuard aGuard;
2098 // workaround for bad designed API
2099 try
2100 {
2101 SetPropertyValues_Impl( rPropertyNames, rValues );
2102 }
2103 catch (const beans::UnknownPropertyException &rException)
2104 {
2105 // wrap the original (here not allowed) exception in
2106 // a lang::WrappedTargetException that gets thrown instead.
2107 lang::WrappedTargetException aWExc;
2108 aWExc.TargetException <<= rException;
2109 throw aWExc;
2110 }
2111}
2112
2113SfxStyleSheetBase* SwXStyle::GetStyleSheetBase()
2114{
2115 if(!m_pBasePool)
2116 return nullptr;
2117 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
2118 return pBase;
2119}
2120void SwXStyle::PrepareStyleBase(SwStyleBase_Impl& rBase)
2121{
2122 SfxStyleSheetBase* pBase(GetStyleSheetBase());
2123 if(!pBase)
2124 throw uno::RuntimeException();
2125 if(!rBase.getNewBase().is())
2126 rBase.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
2127}
2128
2129template<>
2130uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
2131template<>
2132uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
2133{
2134 SfxStyleSheetBase* pBase(GetStyleSheetBase());
2135 if(!pBase)
2136 return uno::Any(false);
2137 bool bPhys = static_cast<SwDocStyleSheet*>(pBase)->IsPhysical();
2138 // The standard character format is not existing physically
2139 if( bPhys && SfxStyleFamily::Char == GetFamily() &&
2140 static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat() &&
2141 static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat()->IsDefault() )
2142 bPhys = false;
2143 return uno::Any(bool(bPhys));
2144}
2145template<>
2146uno::Any SwXStyle::GetStyleProperty<FN_UNO_HIDDEN>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
2147{
2148 SfxStyleSheetBase* pBase(GetStyleSheetBase());
2149 if(!pBase)
2150 return uno::Any(false);
2151 rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
2152 return uno::Any(xBase->IsHidden());
2153}
2154template<>
2155uno::Any SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
2156{
2157 SfxStyleSheetBase* pBase(GetStyleSheetBase());
2158 if(!pBase)
2159 return uno::Any();
2160 uno::Any aRet;
2161 rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
2162 xBase->GetGrabBagItem(aRet);
2163 return aRet;
2164}
2165template<>
2166uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
2167{
2168 PrepareStyleBase(rBase);
2169 SfxItemSet& rSet = rBase.GetItemSet();
2170 uno::Any aValue;
2171 rPropSet.getPropertyValue(rEntry, rSet, aValue);
2172 sal_Int8 nBin(aValue.get<sal_Int8>());
2173 if(nBin == -1)
2174 return uno::Any(OUString("[From printer settings]"));
2175 SfxPrinter* pPrinter = GetDoc()->getIDocumentDeviceAccess().getPrinter(false);
2176 if(!pPrinter)
2177 return uno::Any();
2178 return uno::Any(pPrinter->GetPaperBinName(nBin));
2179}
2180template<>
2181uno::Any SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2182{
2183 PrepareStyleBase(rBase);
2184 const SwNumRule* pRule = rBase.getNewBase()->GetNumRule();
2185 assert(pRule && "Where is the NumRule?");
2186 uno::Reference<container::XIndexReplace> xRules(new SwXNumberingRules(*pRule, GetDoc()));
2187 return uno::Any(xRules);
2188}
2189template<>
2190uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2191{
2192 PrepareStyleBase(rBase);
2193 SAL_WARN_IF(SfxStyleFamily::Para != GetFamily(), "sw.uno", "only paras");
2194 return uno::Any(sal_Int16(rBase.getNewBase()->GetCollection()->GetAttrOutlineLevel()));
2195}
2196template<>
2197uno::Any SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2198{
2199 PrepareStyleBase(rBase);
2200 OUString aString;
2201 SwStyleNameMapper::FillProgName(rBase.getNewBase()->GetFollow(), aString, lcl_GetSwEnumFromSfxEnum(GetFamily()));
2202 return uno::Any(aString);
2203}
2204
2205template <>
2206uno::Any SwXStyle::GetStyleProperty<FN_UNO_LINK_STYLE>(const SfxItemPropertyMapEntry&,
2207 const SfxItemPropertySet&,
2208 SwStyleBase_Impl& rBase)
2209{
2210 PrepareStyleBase(rBase);
2211 OUString aString;
2212 SwStyleNameMapper::FillProgName(rBase.getNewBase()->GetLink(), aString,
2213 lcl_GetSwEnumFromSfxEnum(GetFamily()));
2214 return uno::Any(aString);
2215}
2216
2217template<>
2218uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
2219{
2220 PrepareStyleBase(rBase);
2222 return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase);
2223 // special handling for RES_PAGEDESC
2224 const SwFormatPageDesc* pItem =
2225 rBase.GetItemSet().GetItemIfSet(RES_PAGEDESC);
2226 if(!pItem)
2227 return uno::Any();
2228 const SwPageDesc* pDesc = pItem->GetPageDesc();
2229 if(!pDesc)
2230 return uno::Any();
2231 OUString aString;
2233 return uno::Any(aString);
2234}
2235template<>
2236uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2237{
2238 PrepareStyleBase(rBase);
2239 switch(GetFamily())
2240 {
2241 case SfxStyleFamily::Para : return uno::Any(rBase.getNewBase()->GetCollection()->IsAutoUpdateFormat());
2242 case SfxStyleFamily::Frame: return uno::Any(rBase.getNewBase()->GetFrameFormat()->IsAutoUpdateFormat());
2243 default: return uno::Any();
2244 }
2245}
2246template<>
2247uno::Any SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2248{
2249 PrepareStyleBase(rBase);
2250 return uno::Any(rBase.getNewBase()->GetName());
2251}
2252template<>
2253uno::Any SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2254{
2255 PrepareStyleBase(rBase);
2256 static_assert(COND_COMMAND_COUNT == 28, "invalid size of command count?");
2257 uno::Sequence<beans::NamedValue> aSeq(COND_COMMAND_COUNT);
2258 sal_uInt16 nIndex = 0;
2259 for(auto& rNV : asNonConstRange(aSeq))
2260 {
2261 rNV.Name = GetCommandContextByIndex(nIndex++);
2262 rNV.Value <<= OUString();
2263 }
2264 SwFormat* pFormat = static_cast<SwDocStyleSheet*>(GetStyleSheetBase())->GetCollection();
2265 if(pFormat && RES_CONDTXTFMTCOLL == pFormat->Which())
2266 {
2267 const CommandStruct* pCmds = SwCondCollItem::GetCmds();
2268 beans::NamedValue* pSeq = aSeq.getArray();
2269 for(sal_uInt16 n = 0; n < COND_COMMAND_COUNT; ++n)
2270 {
2271 const SwCollCondition* pCond = static_cast<SwConditionTextFormatColl*>(pFormat)->HasCondition(SwCollCondition(nullptr, pCmds[n].nCnd, pCmds[n].nSubCond));
2272 if(!pCond || !pCond->GetTextFormatColl())
2273 continue;
2274 // get programmatic style name from UI style name
2275 OUString aStyleName = pCond->GetTextFormatColl()->GetName();
2276 SwStyleNameMapper::FillProgName(aStyleName, aStyleName, lcl_GetSwEnumFromSfxEnum(GetFamily()));
2277 pSeq[n].Value <<= aStyleName;
2278 }
2279 }
2280 return uno::Any(aSeq);
2281}
2282template<>
2283uno::Any SwXStyle::GetStyleProperty<FN_UNO_CATEGORY>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2284{
2285 PrepareStyleBase(rBase);
2286 static std::optional<std::map<collectionbits_t, paragraphstyle_t>> pUnoToCore;
2287 if(!pUnoToCore)
2288 {
2289 pUnoToCore.emplace();
2290 auto pEntries = lcl_GetParagraphStyleCategoryEntries();
2291 std::transform(pEntries->begin(), pEntries->end(), std::inserter(*pUnoToCore, pUnoToCore->end()),
2292 [] (const ParagraphStyleCategoryEntry& rEntry) { return std::pair<collectionbits_t, paragraphstyle_t>(rEntry.m_nCollectionBits, rEntry.m_eCategory); });
2293 }
2294 const sal_uInt16 nPoolId = rBase.getNewBase()->GetCollection()->GetPoolFormatId();
2295 const auto pUnoToCoreIt(pUnoToCore->find(COLL_GET_RANGE_BITS & nPoolId));
2296 if(pUnoToCoreIt == pUnoToCore->end())
2297 return uno::Any(sal_Int16(-1));
2298 return uno::Any(pUnoToCoreIt->second);
2299}
2300template<>
2301uno::Any SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2302{
2303 PrepareStyleBase(rBase);
2304 const SwPageDesc *pPageDesc = rBase.getNewBase()->GetPageDesc();
2305 if(!pPageDesc)
2306 return uno::Any(OUString());
2307 const SwTextFormatColl* pCol = pPageDesc->GetRegisterFormatColl();
2308 if(!pCol)
2309 return uno::Any(OUString());
2310 OUString aName;
2312 return uno::Any(aName);
2313}
2314template<>
2315uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2316{
2317 PrepareStyleBase(rBase);
2318 const SfxItemSet& rSet = rBase.GetItemSet();
2319 const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND));
2320 uno::Any aResult;
2321 if(!aOriginalBrushItem->QueryValue(aResult, rEntry.nMemberId))
2322 SAL_WARN("sw.uno", "error getting attribute from RES_BACKGROUND.");
2323 return aResult;
2324}
2325template<>
2326uno::Any SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
2327{
2328 PrepareStyleBase(rBase);
2329 const SfxItemSet& rSet = rBase.GetItemSet();
2330 if (rSet.Get(XATTR_FILLBMP_TILE).GetValue())
2331 return uno::Any(drawing::BitmapMode_REPEAT);
2332 if (rSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
2333 return uno::Any(drawing::BitmapMode_STRETCH);
2334 return uno::Any(drawing::BitmapMode_NO_REPEAT);
2335}
2336template<>
2337uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
2338{
2339 PrepareStyleBase(rBase);
2340 SfxItemSet& rSet = rBase.GetItemSet();
2341 uno::Any aResult;
2342 rPropSet.getPropertyValue(rEntry, rSet, aResult);
2343 //
2344 // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
2345 if(rEntry.aType == cppu::UnoType<sal_Int16>::get() && aResult.getValueType() == cppu::UnoType<sal_Int32>::get())
2346 aResult <<= static_cast<sal_Int16>(aResult.get<sal_Int32>());
2347 // check for needed metric translation
2348 if(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM && GetDoc())
2349 {
2350 const SfxItemPool& rPool = GetDoc()->GetAttrPool();
2351 const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID));
2352 bool bAllowedConvert(true);
2353 // exception: If these ItemTypes are used, do not convert when these are negative
2354 // since this means they are intended as percent values
2355 if(XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID)
2356 bAllowedConvert = !aResult.has<sal_Int32>() || aResult.get<sal_Int32>() > 0;
2357 if(eMapUnit != MapUnit::Map100thMM && bAllowedConvert)
2358 SvxUnoConvertToMM(eMapUnit, aResult);
2359 }
2360 return aResult;
2361}
2362
2363uno::Any SwXStyle::GetStyleProperty_Impl(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
2364{
2365 using propertytype_t = decltype(rEntry.nWID);
2366 using coresetter_t = std::function<uno::Any(SwXStyle&, const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)>;
2367 static std::optional<std::map<propertytype_t, coresetter_t>> pUnoToCore;
2368 if(!pUnoToCore)
2369 {
2370 pUnoToCore = std::map<propertytype_t, coresetter_t> {
2371 // these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again
2372 { FN_UNO_IS_PHYSICAL, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL>) },
2373 { FN_UNO_HIDDEN, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_HIDDEN>) },
2374 { FN_UNO_STYLE_INTEROP_GRAB_BAG, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG>) },
2375 { RES_PAPER_BIN, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>) },
2376 { FN_UNO_NUM_RULES, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES>) },
2377 { RES_PARATR_OUTLINELEVEL, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>) },
2378 { FN_UNO_FOLLOW_STYLE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE>) },
2379 { FN_UNO_LINK_STYLE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_LINK_STYLE>) },
2380 { RES_PAGEDESC, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>) },
2381 { FN_UNO_IS_AUTO_UPDATE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE>) },
2382 { FN_UNO_DISPLAY_NAME, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME>) },
2383 { FN_UNO_PARA_STYLE_CONDITIONS, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS>) },
2384 { FN_UNO_CATEGORY, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_CATEGORY>) },
2385 { SID_SWREGISTER_COLLECTION, std::mem_fn(&SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION>) },
2386 { RES_BACKGROUND, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>) },
2387 { OWN_ATTR_FILLBMP_MODE, std::mem_fn(&SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE>) }
2388 };
2389 }
2390 const auto pUnoToCoreIt(pUnoToCore->find(rEntry.nWID));
2391 if(pUnoToCoreIt != pUnoToCore->end())
2392 return pUnoToCoreIt->second(*this, rEntry, rPropSet, rBase);
2393 return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase);
2394}
2395
2396uno::Any SwXStyle::GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName)
2397{
2398 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
2399 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropertyName);
2400 if(!pEntry || (!m_bIsConditional && rPropertyName == UNO_NAME_PARA_STYLE_CONDITIONS))
2401 throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject*>(this));
2402 if(m_pBasePool)
2403 return GetStyleProperty_Impl(*pEntry, *pPropSet, rBase);
2404 const uno::Any* pAny = nullptr;
2405 m_pPropertiesImpl->GetProperty(rPropertyName, pAny);
2406 if(pAny->hasValue())
2407 return *pAny;
2408 uno::Any aValue;
2409 switch(m_rEntry.m_eFamily)
2410 {
2411 case SfxStyleFamily::Pseudo:
2412 throw uno::RuntimeException("No default value for: " + rPropertyName);
2413 break;
2414 case SfxStyleFamily::Para:
2415 case SfxStyleFamily::Page:
2416 SwStyleProperties_Impl::GetProperty(rPropertyName, m_xStyleData, aValue);
2417 break;
2418 case SfxStyleFamily::Char:
2419 case SfxStyleFamily::Frame:
2420 {
2421 if(pEntry->nWID < POOLATTR_BEGIN || pEntry->nWID >= RES_UNKNOWNATR_END)
2422 throw uno::RuntimeException("No default value for: " + rPropertyName);
2423 SwFormat* pFormat;
2424 if(m_rEntry.m_eFamily == SfxStyleFamily::Char)
2425 pFormat = m_pDoc->GetDfltCharFormat();
2426 else
2427 pFormat = m_pDoc->GetDfltFrameFormat();
2428 const SwAttrPool* pPool = pFormat->GetAttrSet().GetPool();
2429 const SfxPoolItem& rItem = pPool->GetDefaultItem(pEntry->nWID);
2430 rItem.QueryValue(aValue, pEntry->nMemberId);
2431 }
2432 break;
2433 default:
2434 ;
2435 }
2436 return aValue;
2437}
2438
2439uno::Any SwXStyle::getPropertyValue(const OUString& rPropertyName)
2440{
2441 SolarMutexGuard aGuard;
2442 if(!m_pDoc)
2443 throw uno::RuntimeException();
2444 if(!m_pBasePool && !m_bIsDescriptor)
2445 throw uno::RuntimeException();
2446 sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
2447 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
2448 SwStyleBase_Impl aBase(*m_pDoc, m_sStyleName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
2449 return GetPropertyValue_Impl(pPropSet, aBase, rPropertyName);
2450}
2451
2452uno::Sequence<uno::Any> SwXStyle::getPropertyValues(const uno::Sequence<OUString>& rPropertyNames)
2453{
2454 SolarMutexGuard aGuard;
2455 if(!m_pDoc)
2456 throw uno::RuntimeException();
2457 if(!m_pBasePool && !m_bIsDescriptor)
2458 throw uno::RuntimeException();
2459 sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
2460 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
2461 SwStyleBase_Impl aBase(*m_pDoc, m_sStyleName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
2462 uno::Sequence<uno::Any> aValues(rPropertyNames.getLength());
2463 auto aValuesRange = asNonConstRange(aValues);
2464 // workaround for bad designed API
2465 try
2466 {
2467 for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
2468 aValuesRange[nProp] = GetPropertyValue_Impl(pPropSet, aBase, rPropertyNames[nProp]);
2469 }
2470 catch(beans::UnknownPropertyException&)
2471 {
2472 css::uno::Any anyEx = cppu::getCaughtException();
2473 throw css::lang::WrappedTargetRuntimeException("Unknown property exception caught",
2474 static_cast < cppu::OWeakObject * > ( this ), anyEx );
2475 }
2476 catch(lang::WrappedTargetException&)
2477 {
2478 css::uno::Any anyEx = cppu::getCaughtException();
2479 throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
2480 static_cast < cppu::OWeakObject * > ( this ), anyEx );
2481 }
2482 return aValues;
2483}
2484
2485void SwXStyle::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
2486{
2487 SolarMutexGuard aGuard;
2488 const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
2489 const uno::Sequence<uno::Any> aValues(&rValue, 1);
2490 SetPropertyValues_Impl(aProperties, aValues);
2491}
2492
2493beans::PropertyState SwXStyle::getPropertyState(const OUString& rPropertyName)
2494{
2495 SolarMutexGuard aGuard;
2496 uno::Sequence<OUString> aNames{rPropertyName};
2497 uno::Sequence<beans::PropertyState> aStates = getPropertyStates(aNames);
2498 return aStates.getConstArray()[0];
2499}
2500
2501// allow to retarget the SfxItemSet working on, default correctly. Only
2502// use pSourceSet below this point (except in header/footer processing)
2503static const SfxItemSet* lcl_GetItemsetForProperty(const SfxItemSet& rSet, SfxStyleFamily eFamily, std::u16string_view rPropertyName)
2504{
2505 if(eFamily != SfxStyleFamily::Page)
2506 return &rSet;
2507 const bool isFooter = o3tl::starts_with(rPropertyName, u"Footer");
2508 if(!isFooter && !o3tl::starts_with(rPropertyName, u"Header") && rPropertyName != UNO_NAME_FIRST_IS_SHARED)
2509 return &rSet;
2510 const SvxSetItem* pSetItem;
2511 if(!lcl_GetHeaderFooterItem(rSet, rPropertyName, isFooter, pSetItem))
2512 return nullptr;
2513 return &pSetItem->GetItemSet();
2514}
2515uno::Sequence<beans::PropertyState> SwXStyle::getPropertyStates(const uno::Sequence<OUString>& rPropertyNames)
2516{
2517 SolarMutexGuard aGuard;
2518 uno::Sequence<beans::PropertyState> aRet(rPropertyNames.getLength());
2519 beans::PropertyState* pStates = aRet.getArray();
2520
2521 if(!m_pBasePool)
2522 throw uno::RuntimeException();
2523 SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.m_eFamily);
2524
2525 SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
2526 if(!pBase)
2527 throw uno::RuntimeException();
2528
2529 const OUString* pNames = rPropertyNames.getConstArray();
2530 rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
2531 sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
2532
2533 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
2534 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
2535 const SfxItemSet& rSet = xStyle->GetItemSet();
2536
2537 for(sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i)
2538 {
2539 const OUString sPropName = pNames[i];
2540 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
2541
2542 if(!pEntry)
2543 throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast<cppu::OWeakObject*>(this));
2544
2545 if (FN_UNO_NUM_RULES == pEntry->nWID || FN_UNO_FOLLOW_STYLE == pEntry->nWID
2546 || pEntry->nWID == FN_UNO_LINK_STYLE)
2547 {
2548 // handle NumRules first, done
2549 pStates[i] = beans::PropertyState_DIRECT_VALUE;
2550 continue;
2551 }
2552 const SfxItemSet* pSourceSet = lcl_GetItemsetForProperty(rSet, m_rEntry.m_eFamily, sPropName);
2553 if(!pSourceSet)
2554 {
2555 // if no SetItem, value is ambiguous and we are done
2556 pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
2557 continue;
2558 }
2559 switch(pEntry->nWID)
2560 {
2562 {
2563 if(SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_STRETCH, false)
2564 || SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_TILE, false))
2565 {
2566 pStates[i] = beans::PropertyState_DIRECT_VALUE;
2567 }
2568 else
2569 {
2570 pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
2571 }
2572 }
2573 break;
2574 case RES_BACKGROUND:
2575 {
2576 // for FlyFrames we need to mark the used properties from type RES_BACKGROUND
2577 // as beans::PropertyState_DIRECT_VALUE to let users of this property call
2578 // getPropertyValue where the member properties will be mapped from the
2579 // fill attributes to the according SvxBrushItem entries
2581 {
2582 pStates[i] = beans::PropertyState_DIRECT_VALUE;
2583 }
2584 else
2585 {
2586 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
2587 }
2588 }
2589 break;
2590 default:
2591 {
2592 pStates[i] = pPropSet->getPropertyState(*pEntry, *pSourceSet);
2593
2594 if(SfxStyleFamily::Page == m_rEntry.m_eFamily && SID_ATTR_PAGE_SIZE == pEntry->nWID && beans::PropertyState_DIRECT_VALUE == pStates[i])
2595 {
2596 const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
2597 sal_uInt8 nMemberId = pEntry->nMemberId & 0x7f;
2598
2599 if((LONG_MAX == rSize.GetSize().Width() && (MID_SIZE_WIDTH == nMemberId || MID_SIZE_SIZE == nMemberId)) ||
2600 (LONG_MAX == rSize.GetSize().Height() && MID_SIZE_HEIGHT == nMemberId))
2601 {
2602 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
2603 }
2604 }
2605 }
2606 }
2607 }
2608 return aRet;
2609}
2610
2611void SwXStyle::setPropertyToDefault(const OUString& rPropertyName)
2612{
2613 const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
2614 setPropertiesToDefault(aSequence);
2615}
2616
2617static SwFormat* lcl_GetFormatForStyle(SwDoc const * pDoc, const rtl::Reference<SwDocStyleSheet>& xStyle, const SfxStyleFamily eFamily)
2618{
2619 if(!xStyle.is())
2620 return nullptr;
2621 switch(eFamily)
2622 {
2623 case SfxStyleFamily::Char: return xStyle->GetCharFormat();
2624 case SfxStyleFamily::Para: return xStyle->GetCollection();
2625 case SfxStyleFamily::Frame: return xStyle->GetFrameFormat();
2626 case SfxStyleFamily::Page:
2627 {
2628 SwPageDesc* pDesc(pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName()));
2629 if(pDesc)
2630 return &pDesc->GetMaster();
2631 }
2632 break;
2633 default: ;
2634 }
2635 return nullptr;
2636}
2637
2638void SAL_CALL SwXStyle::setPropertiesToDefault(const uno::Sequence<OUString>& aPropertyNames)
2639{
2640 SolarMutexGuard aGuard;
2641 const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase())));
2642 SwFormat* pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.m_eFamily);
2643 if(!pTargetFormat)
2644 {
2645 if(!m_bIsDescriptor)
2646 return;
2647 for(const auto& rName : aPropertyNames)
2648 m_pPropertiesImpl->ClearProperty(rName);
2649 return;
2650 }
2651 const sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
2652 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
2653 const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
2654 for(const auto& rName : aPropertyNames)
2655 {
2656 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rName);
2657 if(!pEntry)
2658 throw beans::UnknownPropertyException("Unknown property: " + rName, static_cast<cppu::OWeakObject*>(this));
2659 if (pEntry->nWID == FN_UNO_FOLLOW_STYLE || pEntry->nWID == FN_UNO_LINK_STYLE
2660 || pEntry->nWID == FN_UNO_NUM_RULES)
2661 throw uno::RuntimeException("Cannot reset: " + rName, static_cast<cppu::OWeakObject*>(this));
2662 if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
2663 throw uno::RuntimeException("setPropertiesToDefault: property is read-only: " + rName, static_cast<cppu::OWeakObject*>(this));
2664 if(pEntry->nWID == RES_PARATR_OUTLINELEVEL)
2665 {
2666 static_cast<SwTextFormatColl*>(pTargetFormat)->DeleteAssignmentToListLevelOfOutlineStyle();
2667 continue;
2668 }
2669 pTargetFormat->ResetFormatAttr(pEntry->nWID);
2670 if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
2671 {
2672 //
2673 SwDoc* pDoc = pTargetFormat->GetDoc();
2675 aSet.SetParent(&pTargetFormat->GetAttrSet());
2676
2677 aSet.ClearItem(XATTR_FILLBMP_STRETCH);
2678 aSet.ClearItem(XATTR_FILLBMP_TILE);
2679
2680 pTargetFormat->SetFormatAttr(aSet);
2681 }
2682 }
2683}
2684
2685void SAL_CALL SwXStyle::setAllPropertiesToDefault()
2686{
2687 SolarMutexGuard aGuard;
2688 if(!m_pBasePool)
2689 {
2690 if(!m_bIsDescriptor)
2691 throw uno::RuntimeException();
2692 m_pPropertiesImpl->ClearAllProperties();
2693 return;
2694 }
2695 const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase())));
2696 if(!xStyle.is())
2697 throw uno::RuntimeException();
2698 if(SfxStyleFamily::Page == m_rEntry.m_eFamily)
2699 {
2700 size_t nPgDscPos(0);
2701 SwPageDesc* pDesc = m_pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName(), &nPgDscPos);
2702 SwFormat* pPageFormat(nullptr);
2703 if(pDesc)
2704 {
2705 pPageFormat = &pDesc->GetMaster();
2706 pDesc->SetUseOn(UseOnPage::All);
2707 }
2708 else
2709 pPageFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.m_eFamily);
2710 SwPageDesc& rPageDesc = m_pDoc->GetPageDesc(nPgDscPos);
2711 rPageDesc.ResetAllMasterAttr();
2712
2713 pPageFormat->SetPageFormatToDefault();
2714 SwPageDesc* pStdPgDsc = m_pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD);
2715 std::shared_ptr<SwFormatFrameSize> aFrameSz(std::make_shared<SwFormatFrameSize>(SwFrameSize::Fixed));
2716
2717 if(RES_POOLPAGE_STANDARD == rPageDesc.GetPoolFormatId())
2718 {
2719 if(m_pDoc->getIDocumentDeviceAccess().getPrinter(false))
2720 {
2721 const Size aPhysSize( SvxPaperInfo::GetPaperSize(
2722 static_cast<Printer*>(m_pDoc->getIDocumentDeviceAccess().getPrinter(false))));
2723 aFrameSz->SetSize(aPhysSize);
2724 }
2725 else
2726 {
2727 aFrameSz->SetSize(SvxPaperInfo::GetDefaultPaperSize());
2728 }
2729
2730 }
2731 else
2732 {
2733 aFrameSz.reset(pStdPgDsc->GetMaster().GetFrameSize().Clone());
2734 }
2735
2736 if(pStdPgDsc->GetLandscape())
2737 {
2738 SwTwips nTmp = aFrameSz->GetHeight();
2739 aFrameSz->SetHeight(aFrameSz->GetWidth());
2740 aFrameSz->SetWidth(nTmp);
2741 }
2742
2743 pPageFormat->SetFormatAttr(*aFrameSz);
2744 m_pDoc->ChgPageDesc(nPgDscPos, m_pDoc->GetPageDesc(nPgDscPos));
2745 return;
2746 }
2747 if(SfxStyleFamily::Para == m_rEntry.m_eFamily)
2748 {
2749 if(xStyle->GetCollection())
2750 xStyle->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle();
2751 }
2752 SwFormat* const pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.m_eFamily);
2753 if(!pTargetFormat)
2754 return;
2755 pTargetFormat->ResetAllFormatAttr();
2756}
2757
2758uno::Sequence<uno::Any> SAL_CALL SwXStyle::getPropertyDefaults(const uno::Sequence<OUString>& aPropertyNames)
2759{
2760 SolarMutexGuard aGuard;
2761 sal_Int32 nCount = aPropertyNames.getLength();
2762 uno::Sequence<uno::Any> aRet(nCount);
2763 if(!nCount)
2764 return aRet;
2765 auto pRet = aRet.getArray();
2766 SfxStyleSheetBase* pBase = GetStyleSheetBase();
2767 if(!pBase)
2768 throw uno::RuntimeException();
2769 rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
2770 const sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
2771 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
2772 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
2773
2774 const SfxItemSet &rSet = xStyle->GetItemSet(), *pParentSet = rSet.GetParent();
2775 for(sal_Int32 i = 0; i < nCount; ++i)
2776 {
2777 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(aPropertyNames[i]);
2778
2779 if(!pEntry)
2780 throw beans::UnknownPropertyException("Unknown property: " + aPropertyNames[i], static_cast < cppu::OWeakObject * >(this));
2781 // these cannot be in an item set, especially not the
2782 // parent set, so the default value is void
2783 if (pEntry->nWID >= RES_UNKNOWNATR_END)
2784 continue;
2785
2786 if(pParentSet)
2787 {
2788 aSwMapProvider.GetPropertySet(nPropSetId)->getPropertyValue(aPropertyNames[i], *pParentSet, pRet[i]);
2789 }
2790 else if(pEntry->nWID != rSet.GetPool()->GetSlotId(pEntry->nWID))
2791 {
2792 const SfxPoolItem& rItem = rSet.GetPool()->GetDefaultItem(pEntry->nWID);
2793 rItem.QueryValue(pRet[i], pEntry->nMemberId);
2794 }
2795 }
2796 return aRet;
2797}
2798
2799uno::Any SwXStyle::getPropertyDefault(const OUString& rPropertyName)
2800{
2801 const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
2802 return getPropertyDefaults(aSequence)[0];
2803}
2804
2805void SwXStyle::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
2806{
2807 if((rHint.GetId() == SfxHintId::Dying) || (rHint.GetId() == SfxHintId::StyleSheetErased))
2808 {
2809 m_pBasePool = nullptr;
2811 }
2812 else if(rHint.GetId() == SfxHintId::StyleSheetChanged)
2813 {
2814 SfxStyleSheetBasePool& rBP = static_cast<SfxStyleSheetBasePool&>(rBC);
2815 SfxStyleSheetBase* pOwnBase = rBP.Find(m_sStyleName, m_rEntry.m_eFamily);
2816 if(!pOwnBase)
2817 {
2819 Invalidate();
2820 }
2821 }
2822}
2823
2824void SwXStyle::Invalidate()
2825{
2826 m_sStyleName.clear();
2827 m_pBasePool = nullptr;
2828 m_pDoc = nullptr;
2829 m_xStyleData.clear();
2830 m_xStyleFamily.clear();
2831}
2832
2833SwXPageStyle::SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName)
2834 : SwXStyle(&rPool, SfxStyleFamily::Page, pDocSh->GetDoc(), rStyleName)
2835{ }
2836
2837SwXPageStyle::SwXPageStyle(SwDocShell* pDocSh)
2838 : SwXStyle(pDocSh->GetDoc(), SfxStyleFamily::Page)
2839{ }
2840
2841void SwXStyle::PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertyMapEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl)
2842{
2843 // create a new SvxSetItem and get it's ItemSet as new target
2844 std::unique_ptr<SvxSetItem> pNewSetItem(pSetItem->Clone());
2845 SfxItemSet& rSetSet = pNewSetItem->GetItemSet();
2846
2847 // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem
2848 rSetSet.SetParent(&m_pDoc->GetDfltFrameFormat()->GetAttrSet());
2849
2850 // replace the used SfxItemSet at the SwStyleBase_Impl temporarily and use the
2851 // default method to set the property
2852 {
2853 SwStyleBase_Impl::ItemSetOverrider o(rBaseImpl, &rSetSet);
2854 SetStyleProperty(rEntry, rPropSet, rVal, rBaseImpl);
2855 }
2856
2857 // reset parent at ItemSet from SetItem
2858 rSetSet.SetParent(nullptr);
2859
2860 // set the new SvxSetItem at the real target and delete it
2861 rBaseImpl.GetItemSet().Put(std::move(pNewSetItem));
2862}
2863
2864void SwXPageStyle::SetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
2865{
2866 if(!GetDoc())
2867 throw uno::RuntimeException();
2868
2869 if(rPropertyNames.getLength() != rValues.getLength())
2870 throw lang::IllegalArgumentException();
2871
2873 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
2874 SwStyleBase_Impl aBaseImpl(*GetDoc(), GetStyleName(), &GetDoc()->GetDfltFrameFormat()->GetAttrSet()); // add pDfltFrameFormat as parent
2875 if(!m_pBasePool)
2876 {
2877 if(!IsDescriptor())
2878 throw uno::RuntimeException();
2879 for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
2880 if(!m_pPropertiesImpl->SetProperty(rPropertyNames[nProp], rValues[nProp]))
2881 throw lang::IllegalArgumentException();
2882 return;
2883 }
2884 SfxStyleSheetBase* pBase = GetStyleSheetBase();
2885 if(!pBase)
2886 throw uno::RuntimeException();
2887 aBaseImpl.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
2888 for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
2889 {
2890 const OUString& rPropName = rPropertyNames[nProp];
2891 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropName);
2892
2893 if(!pEntry)
2894 throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast<cppu::OWeakObject*>(this));
2895 if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
2896 throw beans::PropertyVetoException("Property is read-only: " + rPropName, static_cast<cppu::OWeakObject*>(this));
2897
2898 const bool bHeader(rPropName.startsWith("Header"));
2899 const bool bFooter(rPropName.startsWith("Footer"));
2900 const bool bFirstIsShared(rPropName == UNO_NAME_FIRST_IS_SHARED);
2901 if(bHeader || bFooter || bFirstIsShared)
2902 {
2903 switch(pEntry->nWID)
2904 {
2905 case SID_ATTR_PAGE_ON:
2906 case RES_BACKGROUND:
2907 case RES_BOX:
2908 case RES_LR_SPACE:
2909 case RES_SHADOW:
2910 case RES_UL_SPACE:
2911 case SID_ATTR_PAGE_DYNAMIC:
2912 case SID_ATTR_PAGE_SHARED:
2913 case SID_ATTR_PAGE_SHARED_FIRST:
2914 case SID_ATTR_PAGE_SIZE:
2916 {
2917 // it is a Header/Footer entry, access the SvxSetItem containing it's information
2918 const SvxSetItem* pSetItem = nullptr;
2919 if (lcl_GetHeaderFooterItem(aBaseImpl.GetItemSet(), rPropName, bFooter, pSetItem))
2920 {
2921 PutItemToSet(pSetItem, *pPropSet, *pEntry, rValues[nProp], aBaseImpl);
2922
2923 if (pEntry->nWID == SID_ATTR_PAGE_SHARED_FIRST)
2924 {
2925 // Need to add this to the other as well
2926 pSetItem = aBaseImpl.GetItemSet().GetItemIfSet(
2927 bFooter ? SID_ATTR_PAGE_HEADERSET : SID_ATTR_PAGE_FOOTERSET,
2928 false);
2929 if (pSetItem)
2930 {
2931 PutItemToSet(pSetItem, *pPropSet, *pEntry, rValues[nProp], aBaseImpl);
2932 }
2933 }
2934 }
2935 else if(pEntry->nWID == SID_ATTR_PAGE_ON && rValues[nProp].get<bool>())
2936 {
2937 // Header/footer gets switched on, create defaults and the needed SfxSetItem
2939 <RES_FRMATR_BEGIN,RES_FRMATR_END - 1, // [82
2940
2941 // FillAttribute support
2943
2944 SID_ATTR_BORDER_INNER,SID_ATTR_BORDER_INNER, // [10023
2945 SID_ATTR_PAGE_SIZE,SID_ATTR_PAGE_SIZE, // [10051
2946 SID_ATTR_PAGE_ON,SID_ATTR_PAGE_SHARED, // [10060
2947 SID_ATTR_PAGE_SHARED_FIRST,SID_ATTR_PAGE_SHARED_FIRST>
2948 aTempSet(*aBaseImpl.GetItemSet().GetPool());
2949
2950 // set correct parent to get the XFILL_NONE FillStyle as needed
2951 aTempSet.SetParent(&GetDoc()->GetDfltFrameFormat()->GetAttrSet());
2952
2953 aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_ON, true));
2955 aTempSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(constTwips_5mm, constTwips_5mm)));
2956 aTempSet.Put(SvxLRSpaceItem(RES_LR_SPACE));
2957 aTempSet.Put(SvxULSpaceItem(RES_UL_SPACE));
2958 aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_SHARED, true));
2959 aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_SHARED_FIRST, true));
2960 aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_DYNAMIC, true));
2961
2962 SvxSetItem aNewSetItem(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, aTempSet);
2963 aBaseImpl.GetItemSet().Put(aNewSetItem);
2964 }
2965 }
2966 continue;
2972 case XATTR_FILLBMP_POS:
2976 case XATTR_FILLBMP_TILE:
2978 case XATTR_FILLCOLOR:
2980 case XATTR_FILLBITMAP:
2982 case XATTR_FILLGRADIENT:
2983 case XATTR_FILLHATCH:
2984 case XATTR_FILLSTYLE:
2988 if(bFirstIsShared) // only special handling for headers/footers here
2989 break;
2990 {
2991 const SvxSetItem* pSetItem =
2992 aBaseImpl.GetItemSet().GetItemIfSet(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, false);
2993
2994 if(pSetItem)
2995 {
2996 // create a new SvxSetItem and get it's ItemSet as new target
2997 std::unique_ptr<SvxSetItem> pNewSetItem(pSetItem->Clone());
2998 SfxItemSet& rSetSet = pNewSetItem->GetItemSet();
2999
3000 // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem
3001 rSetSet.SetParent(&GetDoc()->GetDfltFrameFormat()->GetAttrSet());
3002
3003 // replace the used SfxItemSet at the SwStyleBase_Impl temporarily and use the
3004 // default method to set the property
3005 {
3006 SwStyleBase_Impl::ItemSetOverrider o(aBaseImpl, &rSetSet);
3007 SetStyleProperty(*pEntry, *pPropSet, rValues[nProp], aBaseImpl);
3008 }
3009
3010 // reset parent at ItemSet from SetItem
3011 rSetSet.SetParent(nullptr);
3012
3013 // set the new SvxSetItem at the real target and delete it
3014 aBaseImpl.GetItemSet().Put(std::move(pNewSetItem));
3015 }
3016 }
3017 continue;
3018 default: ;
3019 }
3020 }
3021 switch(pEntry->nWID)
3022 {
3023 case SID_ATTR_PAGE_DYNAMIC:
3024 case SID_ATTR_PAGE_SHARED:
3025 case SID_ATTR_PAGE_SHARED_FIRST:
3026 case SID_ATTR_PAGE_ON:
3028 // these slots are exclusive to Header/Footer, thus this is an error
3029 throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast<cppu::OWeakObject*>(this));
3030 case FN_UNO_HEADER:
3031 case FN_UNO_HEADER_LEFT:
3034 case FN_UNO_FOOTER:
3035 case FN_UNO_FOOTER_LEFT:
3038 throw lang::IllegalArgumentException();
3039 case FN_PARAM_FTN_INFO:
3040 {
3041 const SwPageFootnoteInfoItem& rItem = aBaseImpl.GetItemSet().Get(FN_PARAM_FTN_INFO);
3042 std::unique_ptr<SfxPoolItem> pNewFootnoteItem(rItem.Clone());
3043 if(!pNewFootnoteItem->PutValue(rValues[nProp], pEntry->nMemberId))
3044 throw lang::IllegalArgumentException();
3045 aBaseImpl.GetItemSet().Put(std::move(pNewFootnoteItem));
3046 break;
3047 }
3048 default:
3049 {
3050 SetStyleProperty(*pEntry, *pPropSet, rValues[nProp], aBaseImpl);
3051 break;
3052 }
3053 }
3054 }
3055
3056 if(aBaseImpl.HasItemSet())
3057 {
3058 ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
3059
3060 if (undoGuard.UndoWasEnabled())
3061 {
3062 // Fix i64460: as long as Undo of page styles with header/footer causes trouble...
3063 GetDoc()->GetIDocumentUndoRedo().DelAllUndoObj();
3064 }
3065
3066 aBaseImpl.getNewBase()->SetItemSet(aBaseImpl.GetItemSet());
3067 }
3068}
3069
3070void SwXPageStyle::setPropertyValues(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
3071{
3072 SolarMutexGuard aGuard;
3073
3074 // workaround for bad designed API
3075 try
3076 {
3077 SetPropertyValues_Impl(rPropertyNames, rValues);
3078 }
3079 catch (const beans::UnknownPropertyException &rException)
3080 {
3081 // wrap the original (here not allowed) exception in
3082 // a lang::WrappedTargetException that gets thrown instead.
3083 lang::WrappedTargetException aWExc;
3084 aWExc.TargetException <<= rException;
3085 throw aWExc;
3086 }
3087}
3088
3089static uno::Reference<text::XText> lcl_makeHeaderFooter(const sal_uInt16 nRes, const bool bHeader, SwFrameFormat const*const pFrameFormat)
3090{
3091 if (!pFrameFormat)
3092 return nullptr;
3093 const SfxItemSet& rSet = pFrameFormat->GetAttrSet();
3094 const SfxPoolItem* pItem;
3095 if(SfxItemState::SET != rSet.GetItemState(nRes, true, &pItem))
3096 return nullptr;
3097 SwFrameFormat* const pHeadFootFormat = bHeader
3098 ? static_cast<SwFormatHeader*>(const_cast<SfxPoolItem*>(pItem))->GetHeaderFormat()
3099 : static_cast<SwFormatFooter*>(const_cast<SfxPoolItem*>(pItem))->GetFooterFormat();
3100 if(!pHeadFootFormat)
3101 return nullptr;
3102 return SwXHeadFootText::CreateXHeadFootText(*pHeadFootFormat, bHeader);
3103}
3104
3105uno::Sequence<uno::Any> SwXPageStyle::GetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames)
3106{
3107 if(!GetDoc())
3108 throw uno::RuntimeException();
3109
3110 sal_Int32 nLength = rPropertyNames.getLength();
3111 uno::Sequence<uno::Any> aRet (nLength);
3112 auto aRetRange = asNonConstRange(aRet);
3113 if(!m_pBasePool)
3114 {
3115 if(!IsDescriptor())
3116 throw uno::RuntimeException();
3117 for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
3118 {
3119 const uno::Any* pAny = nullptr;
3120 m_pPropertiesImpl->GetProperty(rPropertyNames[nProp], pAny);
3121 if (!pAny->hasValue())
3122 SwStyleProperties_Impl::GetProperty(rPropertyNames[nProp], m_xStyleData, aRetRange[nProp]);
3123 else
3124 aRetRange[nProp] = *pAny;
3125 }
3126 return aRet;
3127 }
3129 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
3130 SwStyleBase_Impl aBase(*GetDoc(), GetStyleName(), &GetDoc()->GetDfltFrameFormat()->GetAttrSet()); // add pDfltFrameFormat as parent
3131 SfxStyleSheetBase* pBase = GetStyleSheetBase();
3132 if(!pBase)
3133 throw uno::RuntimeException();
3134 for(sal_Int32 nProp = 0; nProp < nLength; ++nProp)
3135 {
3136 const OUString& rPropName = rPropertyNames[nProp];
3137 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropName);
3138
3139 if (!pEntry)
3140 throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast < cppu::OWeakObject * > ( this ) );
3141 const bool bHeader(rPropName.startsWith("Header"));
3142 const bool bFooter(rPropName.startsWith("Footer"));
3143 const bool bFirstIsShared(rPropName == UNO_NAME_FIRST_IS_SHARED);
3144 if(bHeader || bFooter || bFirstIsShared)
3145 {
3146 switch(pEntry->nWID)
3147 {
3148 case SID_ATTR_PAGE_ON:
3149 case RES_BACKGROUND:
3150 case RES_BOX:
3151 case RES_LR_SPACE:
3152 case RES_SHADOW:
3153 case RES_UL_SPACE:
3154 case SID_ATTR_PAGE_DYNAMIC:
3155 case SID_ATTR_PAGE_SHARED:
3156 case SID_ATTR_PAGE_SHARED_FIRST:
3157 case SID_ATTR_PAGE_SIZE:
3159 {
3160 // slot is a Header/Footer slot
3161 rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pBase) ) );
3162 const SfxItemSet& rSet = xStyle->GetItemSet();
3163 const SvxSetItem* pSetItem;
3164
3165 if (lcl_GetHeaderFooterItem(rSet, rPropName, bFooter, pSetItem))
3166 {
3167 // get from SfxItemSet of the corresponding SfxSetItem
3168 const SfxItemSet& rSetSet = pSetItem->GetItemSet();
3169 {
3170 SwStyleBase_Impl::ItemSetOverrider o(aBase, &const_cast< SfxItemSet& >(rSetSet));
3171 aRetRange[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase);
3172 }
3173 }
3174 else if(pEntry->nWID == SID_ATTR_PAGE_ON)
3175 {
3176 // header/footer is not available, thus off. Default is <false>, though
3177 aRetRange[nProp] <<= false;
3178 }
3179 }
3180 continue;
3186 case XATTR_FILLBMP_POS:
3190 case XATTR_FILLBMP_TILE:
3192 case XATTR_FILLCOLOR:
3194 case XATTR_FILLBITMAP:
3196 case XATTR_FILLGRADIENT:
3197 case XATTR_FILLHATCH:
3198 case XATTR_FILLSTYLE:
3202 if(bFirstIsShared) // only special handling for headers/footers here
3203 break;
3204 {
3205 rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pBase) ) );
3206 const SfxItemSet& rSet = xStyle->GetItemSet();
3207 const SvxSetItem* pSetItem =
3208 rSet.GetItemIfSet(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, false);
3209 if(pSetItem)
3210 {
3211 // set at SfxItemSet of the corresponding SfxSetItem
3212 const SfxItemSet& rSetSet = pSetItem->GetItemSet();
3213 {
3214 SwStyleBase_Impl::ItemSetOverrider o(aBase, &const_cast<SfxItemSet&>(rSetSet));
3215 aRetRange[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase);
3216 }
3217 }
3218 }
3219 continue;
3220 default: ;
3221 }
3222 }
3223 switch(pEntry->nWID)
3224 {
3225 // these slots are exclusive to Header/Footer, thus this is an error
3226 case SID_ATTR_PAGE_DYNAMIC:
3227 case SID_ATTR_PAGE_SHARED:
3228 case SID_ATTR_PAGE_SHARED_FIRST:
3229 case SID_ATTR_PAGE_ON:
3231 throw beans::UnknownPropertyException( "Unknown property: " + rPropName, static_cast < cppu::OWeakObject * > ( this ) );
3232 case FN_UNO_HEADER:
3233 case FN_UNO_HEADER_LEFT:
3236 case FN_UNO_FOOTER:
3237 case FN_UNO_FOOTER_LEFT:
3240 {
3241 bool bLeft(false);
3242 bool bFirst(false);
3243 sal_uInt16 nRes = 0;
3244 switch(pEntry->nWID)
3245 {
3246 case FN_UNO_HEADER: nRes = RES_HEADER; break;
3247 case FN_UNO_HEADER_LEFT: nRes = RES_HEADER; bLeft = true; break;
3248 case FN_UNO_HEADER_FIRST: nRes = RES_HEADER; bFirst = true; break;
3249 case FN_UNO_HEADER_RIGHT: nRes = RES_HEADER; break;
3250 case FN_UNO_FOOTER: nRes = RES_FOOTER; break;
3251 case FN_UNO_FOOTER_LEFT: nRes = RES_FOOTER; bLeft = true; break;
3252 case FN_UNO_FOOTER_FIRST: nRes = RES_FOOTER; bFirst = true; break;
3253 case FN_UNO_FOOTER_RIGHT: nRes = RES_FOOTER; break;
3254 default: ;
3255 }
3256
3257 const SwPageDesc* pDesc = aBase.GetOldPageDesc();
3258 assert(pDesc);
3259 const SwFrameFormat* pFrameFormat = nullptr;
3260 bool bShare = (nRes == RES_HEADER && pDesc->IsHeaderShared()) || (nRes == RES_FOOTER && pDesc->IsFooterShared());
3261 bool bShareFirst = pDesc->IsFirstShared();
3262 // TextLeft returns the left content if there is one,
3263 // Text and TextRight return the master content.
3264 // TextRight does the same as Text and is for
3265 // compatibility only.
3266 if(bLeft && !bShare)
3267 pFrameFormat = &pDesc->GetLeft();
3268 else if(bFirst && !bShareFirst)
3269 {
3270 pFrameFormat = &pDesc->GetFirstMaster();
3271 // no need to make GetFirstLeft() accessible
3272 // since it is always shared
3273 }
3274 else
3275 pFrameFormat = &pDesc->GetMaster();
3276 const uno::Reference<text::XText> xRet = lcl_makeHeaderFooter(nRes, nRes == RES_HEADER, pFrameFormat);
3277 if (xRet.is())
3278 aRetRange[nProp] <<= xRet;
3279 }
3280 break;
3281 case FN_PARAM_FTN_INFO:
3282 {
3283 rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
3284 const SfxItemSet& rSet = xStyle->GetItemSet();
3285 const SfxPoolItem& rItem = rSet.Get(FN_PARAM_FTN_INFO);
3286 rItem.QueryValue(aRetRange[nProp], pEntry->nMemberId);
3287 }
3288 break;
3289 default:
3290 aRetRange[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase);
3291 }
3292 }
3293 return aRet;
3294}
3295
3296uno::Sequence<uno::Any> SwXPageStyle::getPropertyValues(const uno::Sequence<OUString>& rPropertyNames)
3297{
3298 SolarMutexGuard aGuard;
3299 uno::Sequence<uno::Any> aValues;
3300
3301 // workaround for bad designed API
3302 try
3303 {
3304 aValues = GetPropertyValues_Impl(rPropertyNames);
3305 }
3306 catch(beans::UnknownPropertyException &)
3307 {
3308 css::uno::Any anyEx = cppu::getCaughtException();
3309 throw lang::WrappedTargetRuntimeException("Unknown property exception caught",
3310 static_cast < cppu::OWeakObject * > ( this ), anyEx );
3311 }
3312 catch(lang::WrappedTargetException &)
3313 {
3314 css::uno::Any anyEx = cppu::getCaughtException();
3315 throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
3316 static_cast < cppu::OWeakObject * > ( this ), anyEx );
3317 }
3318
3319 return aValues;
3320}
3321
3322uno::Any SwXPageStyle::getPropertyValue(const OUString& rPropertyName)
3323{
3324 SolarMutexGuard aGuard;
3325 const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
3326 return GetPropertyValues_Impl(aProperties)[0];
3327}
3328
3329void SwXPageStyle::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
3330{
3331 SolarMutexGuard aGuard;
3332 const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
3333 const uno::Sequence<uno::Any> aValues(&rValue, 1);
3334
3335 // Trick: if the Domain Mapper changes the props of shared header/footer,
3336 // store the old ones in time for later use.
3337 const bool bIsHeader = rPropertyName == UNO_NAME_HEADER_IS_SHARED;
3338 const bool bIsFooter = rPropertyName == UNO_NAME_FOOTER_IS_SHARED;
3339 if ((bIsFooter || bIsHeader) && rValue == uno::Any(true))
3340 {
3341 // Find the matching page descriptor
3342 for (size_t i = 0; i < GetDoc()->GetPageDescCnt(); i++)
3343 {
3344 auto pPageDesc = &GetDoc()->GetPageDesc(i);
3345 // If we have the right page descriptor stash the necessary formats in import time.
3346 if (pPageDesc->GetName() == GetStyleName())
3347 {
3348 auto pLeftHeader = pPageDesc->GetLeft().GetHeader().GetHeaderFormat();
3349 if (bIsHeader && pLeftHeader)
3350 {
3351 pPageDesc->StashFrameFormat(pPageDesc->GetLeft(), true, true, false);
3352 pPageDesc->StashFrameFormat(pPageDesc->GetFirstMaster(), true, false, true);
3353 pPageDesc->StashFrameFormat(pPageDesc->GetFirstLeft(), true, true, true);
3354 }
3355 auto pLeftFooter = pPageDesc->GetLeft().GetFooter().GetFooterFormat();
3356 if (bIsFooter && pLeftFooter)
3357 {
3358 pPageDesc->StashFrameFormat(pPageDesc->GetLeft(), false, true, false);
3359 pPageDesc->StashFrameFormat(pPageDesc->GetFirstMaster(), false, false, true);
3360 pPageDesc->StashFrameFormat(pPageDesc->GetFirstLeft(), false, true, true);
3361 }
3362 }
3363 }
3364 }
3365 // And set the props... as we did it before.
3366 SetPropertyValues_Impl(aProperties, aValues);
3367}
3368
3369SwXFrameStyle::SwXFrameStyle(SwDoc *pDoc)
3370 : SwXStyle(pDoc, SfxStyleFamily::Frame, false)
3371{ }
3372
3373void SwXFrameStyle::SetItem(sal_uInt16 eAtr, const SfxPoolItem& rItem)
3374{
3375 assert(eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END);
3376 SfxStyleSheetBase* pBase = GetStyleSheetBase();
3377 if(!pBase)
3378 return;
3379 rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
3380 SfxItemSet& rStyleSet = xStyle->GetItemSet();
3381 SfxItemSet aSet(*rStyleSet.GetPool(), sal_uInt16(eAtr), sal_uInt16(eAtr));
3382 aSet.Put(rItem);
3383 xStyle->SetItemSet(aSet);
3384}
3385
3386const SfxPoolItem* SwXFrameStyle::GetItem(sal_uInt16 eAtr)
3387{
3388 assert(eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END);
3389 SfxStyleSheetBase* pBase = GetStyleSheetBase();
3390 if(!pBase)
3391 return nullptr;
3392 rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
3393 return &xStyle->GetItemSet().Get(eAtr);
3394}
3395
3396uno::Sequence<uno::Type> SwXFrameStyle::getTypes()
3397{
3398 return cppu::OTypeCollection(
3400 SwXStyle::getTypes()
3401 ).getTypes();
3402}
3403
3404uno::Any SwXFrameStyle::queryInterface(const uno::Type& rType)
3405{
3407 return uno::Any(uno::Reference<XEventsSupplier>(this));
3408 return SwXStyle::queryInterface(rType);
3409}
3410
3411uno::Reference<container::XNameReplace> SwXFrameStyle::getEvents()
3412{
3413 return new SwFrameStyleEventDescriptor(*this);
3414}
3415
3416// Already implemented autostyle families: 3
3417#define AUTOSTYLE_FAMILY_COUNT 3
3419{
3423};
3424
3426{
3427 std::vector<std::shared_ptr<SfxItemSet>> mAutoStyles;
3428 std::vector<std::shared_ptr<SfxItemSet>>::iterator m_aIter;
3431public:
3433 bool hasMoreElements() { return m_aIter != mAutoStyles.end(); }
3434 std::shared_ptr<SfxItemSet> const & nextElement() { return *(m_aIter++); }
3436 SwDoc& getDoc() const { return m_rDoc; }
3437};
3438
3440 SwUnoCollection(rDocShell.GetDoc()), m_pDocShell( &rDocShell )
3441{
3442}
3443
3445{
3446}
3447
3449{
3451}
3452
3454{
3455 SolarMutexGuard aGuard;
3456 uno::Any aRet;
3457 if(nIndex < 0 || nIndex >= AUTOSTYLE_FAMILY_COUNT)
3458 throw lang::IndexOutOfBoundsException();
3459 if(!IsValid())
3460 throw uno::RuntimeException();
3461
3462 uno::Reference< style::XAutoStyleFamily > aRef;
3464 switch( nType )
3465 {
3467 {
3468 if(!m_xAutoCharStyles.is())
3470 aRef = m_xAutoCharStyles;
3471 }
3472 break;
3474 {
3475 if(!m_xAutoRubyStyles.is())
3477 aRef = m_xAutoRubyStyles;
3478 }
3479 break;
3481 {
3482 if(!m_xAutoParaStyles.is())
3484 aRef = m_xAutoParaStyles;
3485 }
3486 break;
3487
3488 default:
3489 ;
3490 }
3491 aRet <<= aRef;
3492
3493 return aRet;
3494}
3495
3497{
3499}
3500
3502{
3503 return true;
3504}
3505
3507{
3508 uno::Any aRet;
3509 if(Name == "CharacterStyles")
3510 aRet = getByIndex(0);
3511 else if(Name == "RubyStyles")
3512 aRet = getByIndex(1);
3513 else if(Name == "ParagraphStyles")
3514 aRet = getByIndex(2);
3515 else
3516 throw container::NoSuchElementException();
3517 return aRet;
3518}
3519
3520uno::Sequence< OUString > SwXAutoStyles::getElementNames()
3521{
3522 uno::Sequence< OUString > aNames(AUTOSTYLE_FAMILY_COUNT);
3523 OUString* pNames = aNames.getArray();
3524 pNames[0] = "CharacterStyles";
3525 pNames[1] = "RubyStyles";
3526 pNames[2] = "ParagraphStyles";
3527 return aNames;
3528}
3529
3531{
3532 if( Name == "CharacterStyles" ||
3533 Name == "RubyStyles" ||
3534 Name == "ParagraphStyles" )
3535 return true;
3536 else
3537 return false;
3538}
3539
3541 m_pDocShell( pDocSh ), m_eFamily(nFamily)
3542{
3543 // Register ourselves as a listener to the document (via the page descriptor)
3545}
3546
3548{
3549}
3550
3552{
3553 if(rHint.GetId() == SfxHintId::Dying)
3554 m_pDocShell = nullptr;
3555}
3556
3557uno::Reference< style::XAutoStyle > SwXAutoStyleFamily::insertStyle(
3558 const uno::Sequence< beans::PropertyValue >& Values )
3559{
3560 if (!m_pDocShell)
3561 {
3562 throw uno::RuntimeException();
3563 }
3564
3565 WhichRangesContainer pRange;
3566 const SfxItemPropertySet* pPropSet = nullptr;
3567 switch( m_eFamily )
3568 {
3570 {
3571 pRange = aCharAutoFormatSetRange;
3573 break;
3574 }
3576 {
3579 break;
3580 }
3582 {
3583 pRange = aTextNodeSetRange; // checked, already added support for [XATTR_FILL_FIRST, XATTR_FILL_LAST]
3585 break;
3586 }
3587 default: ;
3588 }
3589
3590 if( !pPropSet)
3591 throw uno::RuntimeException();
3592
3593 SwAttrSet aSet( m_pDocShell->GetDoc()->GetAttrPool(), pRange );
3594 const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == m_eFamily);
3595
3596 if(!bTakeCareOfDrawingLayerFillStyle)
3597 {
3598 for( const beans::PropertyValue& rValue : Values )
3599 {
3600 try
3601 {
3602 pPropSet->setPropertyValue( rValue.Name, rValue.Value, aSet );
3603 }
3604 catch (const beans::UnknownPropertyException &)
3605 {
3606 OSL_FAIL( "Unknown property" );
3607 }
3608 catch (const lang::IllegalArgumentException &)
3609 {
3610 OSL_FAIL( "Illegal argument" );
3611 }
3612 }
3613 }
3614 else
3615 {
3616 // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem
3617 // to make cases in RES_BACKGROUND work correct; target *is* a style
3618 // where this is the case
3620
3621 // here the used DrawingLayer FillStyles are imported when family is
3622 // equal to IStyleAccess::AUTO_STYLE_PARA, thus we will need to serve the
3623 // used slots functionality here to do this correctly
3624 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
3625
3626 for( const beans::PropertyValue& rValue : Values )
3627 {
3628 const OUString& rPropName = rValue.Name;
3629 uno::Any aValue(rValue.Value);
3630 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropName);
3631
3632 if (!pEntry)
3633 {
3634 SAL_WARN("sw.core", "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName);
3635 continue;
3636 }
3637
3638 const sal_uInt8 nMemberId(pEntry->nMemberId);
3639 bool bDone(false);
3640
3641 // check for needed metric translation
3642 if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM)
3643 {
3644 bool bDoIt(true);
3645
3646 if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID)
3647 {
3648 // exception: If these ItemTypes are used, do not convert when these are negative
3649 // since this means they are intended as percent values
3650 sal_Int32 nValue = 0;
3651
3652 if(aValue >>= nValue)
3653 {
3654 bDoIt = nValue > 0;
3655 }
3656 }
3657
3658 if(bDoIt)
3659 {
3660 const SfxItemPool& rPool = m_pDocShell->GetDoc()->GetAttrPool();
3661 const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID));
3662
3663 if(eMapUnit != MapUnit::Map100thMM)
3664 {
3665 SvxUnoConvertFromMM(eMapUnit, aValue);
3666 }
3667 }
3668 }
3669
3670 switch(pEntry->nWID)
3671 {
3672 case XATTR_FILLGRADIENT:
3673 case XATTR_FILLHATCH:
3674 case XATTR_FILLBITMAP:
3676 // not yet needed; activate when LineStyle support may be added
3677 // case XATTR_LINESTART:
3678 // case XATTR_LINEEND:
3679 // case XATTR_LINEDASH:
3680 {
3681 if(MID_NAME == nMemberId)
3682 {
3683 // add set commands for FillName items
3684 OUString aTempName;
3685
3686 if(!(aValue >>= aTempName))
3687 {
3688 throw lang::IllegalArgumentException();
3689 }
3690
3691 SvxShape::SetFillAttribute(pEntry->nWID, aTempName, aSet);
3692 bDone = true;
3693 }
3694 else if (MID_BITMAP == nMemberId)
3695 {
3696 if(XATTR_FILLBITMAP == pEntry->nWID)
3697 {
3698 Graphic aNullGraphic;
3699 XFillBitmapItem aXFillBitmapItem(std::move(aNullGraphic));
3700
3701 aXFillBitmapItem.PutValue(aValue, nMemberId);
3702 aSet.Put(aXFillBitmapItem);
3703 bDone = true;
3704 }
3705 }
3706
3707 break;
3708 }
3709 case RES_BACKGROUND:
3710 {
3711 const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(aSet, RES_BACKGROUND, true, m_pDocShell->GetDoc()->IsInXMLImport()));
3712 std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone());
3713
3714 aChangedBrushItem->PutValue(aValue, nMemberId);
3715
3716 if(*aChangedBrushItem != *aOriginalBrushItem)
3717 {
3718 setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, aSet);
3719 }
3720
3721 bDone = true;
3722 break;
3723 }
3725 {
3726 drawing::BitmapMode eMode;
3727
3728 if(!(aValue >>= eMode))
3729 {
3730 sal_Int32 nMode = 0;
3731
3732 if(!(aValue >>= nMode))
3733 {
3734 throw lang::IllegalArgumentException();
3735 }
3736
3737 eMode = static_cast<drawing::BitmapMode>(nMode);
3738 }
3739
3740 aSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode));
3741 aSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode));
3742
3743 bDone = true;
3744 break;
3745 }
3746 default: break;
3747 }
3748
3749 if(!bDone)
3750 {
3751 try
3752 {
3753 pPropSet->setPropertyValue( rPropName, aValue, aSet );
3754 }
3755 catch (const beans::UnknownPropertyException &)
3756 {
3757 OSL_FAIL( "Unknown property" );
3758 }
3759 catch (const lang::IllegalArgumentException &)
3760 {
3761 OSL_FAIL( "Illegal argument" );
3762 }
3763 }
3764 }
3765
3766 // clear parent again
3767 aSet.SetParent(nullptr);
3768 }
3769
3770 // need to ensure uniqueness of evtl. added NameOrIndex items
3771 // currently in principle only needed when bTakeCareOfDrawingLayerFillStyle,
3772 // but does not hurt and is easily forgotten later eventually, so keep it
3773 // as common case
3775
3776 // AutomaticStyle creation
3777 std::shared_ptr<SfxItemSet> pSet = m_pDocShell->GetDoc()->GetIStyleAccess().cacheAutomaticStyle( aSet, m_eFamily );
3778 uno::Reference<style::XAutoStyle> xRet = new SwXAutoStyle(m_pDocShell->GetDoc(), pSet, m_eFamily);
3779
3780 return xRet;
3781}
3782
3783uno::Reference< container::XEnumeration > SwXAutoStyleFamily::createEnumeration( )
3784{
3785 if( !m_pDocShell )
3786 throw uno::RuntimeException();
3787 return uno::Reference< container::XEnumeration >
3789}
3790
3792{
3794}
3795
3797{
3798 return false;
3799}
3800
3802: m_rDoc( rInitDoc ), m_eFamily( eFam )
3803{
3804 // special case for ruby auto styles:
3805 if ( IStyleAccess::AUTO_STYLE_RUBY == eFam )
3806 {
3807 std::set< std::pair< sal_uInt16, text::RubyAdjust > > aRubyMap;
3808 SwAttrPool& rAttrPool = m_rDoc.GetAttrPool();
3809
3810 // do this in two phases otherwise we invalidate the iterators when we insert into the pool
3811 std::vector<const SwFormatRuby*> vRubyItems;
3812 for (const SfxPoolItem* pItem : rAttrPool.GetItemSurrogates(RES_TXTATR_CJK_RUBY))
3813 {
3814 auto pRubyItem = dynamic_cast<const SwFormatRuby*>(pItem);
3815 if ( pRubyItem && pRubyItem->GetTextRuby() )
3816 vRubyItems.push_back(pRubyItem);
3817 }
3818 for (const SwFormatRuby* pRubyItem : vRubyItems)
3819 {
3820 std::pair< sal_uInt16, text::RubyAdjust > aPair( pRubyItem->GetPosition(), pRubyItem->GetAdjustment() );
3821 if ( aRubyMap.insert( aPair ).second )
3822 {
3823 auto pItemSet = std::make_shared<SfxItemSetFixed<RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY>>( rAttrPool );
3824 pItemSet->Put( *pRubyItem );
3825 mAutoStyles.push_back( pItemSet );
3826 }
3827 }
3828 }
3829 else
3830 {
3832 }
3833
3834 m_aIter = mAutoStyles.begin();
3835}
3836
3838: m_pImpl( new SwAutoStylesEnumImpl( rDoc, eFam ) )
3839{
3840 // Register ourselves as a listener to the document (via the page descriptor)
3842}
3843
3845{
3846}
3847
3849{
3850 if(rHint.GetId() == SfxHintId::Dying)
3851 m_pImpl.reset();
3852}
3853
3855{
3856 if( !m_pImpl )
3857 throw uno::RuntimeException();
3858 return m_pImpl->hasMoreElements();
3859}
3860
3862{
3863 if( !m_pImpl )
3864 throw uno::RuntimeException();
3865 uno::Any aRet;
3866 if( m_pImpl->hasMoreElements() )
3867 {
3868 std::shared_ptr<SfxItemSet> pNextSet = m_pImpl->nextElement();
3869 uno::Reference< style::XAutoStyle > xAutoStyle = new SwXAutoStyle(&m_pImpl->getDoc(),
3870 pNextSet, m_pImpl->getFamily());
3871 aRet <<= xAutoStyle;
3872 }
3873 return aRet;
3874}
3875
3876// SwXAutoStyle with the family IStyleAccess::AUTO_STYLE_PARA (or
3877// PROPERTY_MAP_PARA_AUTO_STYLE) now uses DrawingLayer FillStyles to allow
3878// unified paragraph background fill, thus the UNO API implementation has to
3879// support the needed slots for these. This seems to be used only for reading
3880// (no setPropertyValue implementation here), so maybe specialized for saving
3881// the Writer Doc to ODF
3882
3884 SwDoc* pDoc,
3885 std::shared_ptr<SfxItemSet> pInitSet,
3887: mpSet(std::move(pInitSet)),
3888 meFamily(eFam),
3889 mrDoc(*pDoc)
3890{
3891 // Register ourselves as a listener to the document (via the page descriptor)
3892 //StartListening(mrDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
3893}
3894
3896{
3897}
3898
3900{
3901 if(rHint.GetId() == SfxHintId::Dying)
3902 mpSet.reset();
3903}
3904
3905uno::Reference< beans::XPropertySetInfo > SwXAutoStyle::getPropertySetInfo( )
3906{
3907 uno::Reference< beans::XPropertySetInfo > xRet;
3908 switch( meFamily )
3909 {
3911 {
3912 static uno::Reference< beans::XPropertySetInfo > xCharRef;
3913 if(!xCharRef.is())
3914 {
3916 }
3917 xRet = xCharRef;
3918 }
3919 break;
3921 {
3922 static uno::Reference< beans::XPropertySetInfo > xRubyRef;
3923 if(!xRubyRef.is())
3924 {
3925 const sal_uInt16 nMapId = PROPERTY_MAP_RUBY_AUTO_STYLE;
3926 xRubyRef = aSwMapProvider.GetPropertySet(nMapId)->getPropertySetInfo();
3927 }
3928 xRet = xRubyRef;
3929 }
3930 break;
3932 {
3933 static uno::Reference< beans::XPropertySetInfo > xParaRef;
3934 if(!xParaRef.is())
3935 {
3936 const sal_uInt16 nMapId = PROPERTY_MAP_PARA_AUTO_STYLE;
3937 xParaRef = aSwMapProvider.GetPropertySet(nMapId)->getPropertySetInfo();
3938 }
3939 xRet = xParaRef;
3940 }
3941 break;
3942
3943 default:
3944 ;
3945 }
3946
3947 return xRet;
3948}
3949
3950void SwXAutoStyle::setPropertyValue( const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
3951{
3952}
3953
3954uno::Any SwXAutoStyle::getPropertyValue( const OUString& rPropertyName )
3955{
3956 SolarMutexGuard aGuard;
3957 const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
3958 return GetPropertyValues_Impl(aProperties).getConstArray()[0];
3959}
3960
3961void SwXAutoStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/,
3962 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
3963{
3964}
3965
3966void SwXAutoStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/,
3967 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
3968{
3969}
3970
3971void SwXAutoStyle::addVetoableChangeListener( const OUString& /*PropertyName*/,
3972 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
3973{
3974}
3975
3976void SwXAutoStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/,
3977 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
3978{
3979}
3980
3982 const uno::Sequence< OUString >& /*aPropertyNames*/,
3983 const uno::Sequence< uno::Any >& /*aValues*/ )
3984{
3985}
3986
3988 const uno::Sequence< OUString > & rPropertyNames )
3989{
3990 if( !mpSet )
3991 {
3992 throw uno::RuntimeException();
3993 }
3994
3995 // query_item
3997 switch(meFamily)
3998 {
4002 default: ;
4003 }
4004
4005 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
4006 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
4007 const OUString* pNames = rPropertyNames.getConstArray();
4008
4009 const sal_Int32 nLen(rPropertyNames.getLength());
4010 uno::Sequence< uno::Any > aRet( nLen );
4011 uno::Any* pValues = aRet.getArray();
4012 const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == meFamily);
4013
4014 for( sal_Int32 i = 0; i < nLen; ++i )
4015 {
4016 const OUString sPropName = pNames[i];
4017 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
4018 if(!pEntry)
4019 {
4020 throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast < cppu::OWeakObject * > ( this ) );
4021 }
4022
4023 uno::Any aTarget;
4024 bool bDone(false);
4025
4026 if ( RES_TXTATR_AUTOFMT == pEntry->nWID || RES_AUTO_STYLE == pEntry->nWID )
4027 {
4028 OUString sName(StylePool::nameOf( mpSet ));
4029 aTarget <<= sName;
4030 bDone = true;
4031 }
4032 else if(bTakeCareOfDrawingLayerFillStyle)
4033 {
4034 // add support for DrawingLayer FillStyle slots
4035 switch(pEntry->nWID)
4036 {
4037 case RES_BACKGROUND:
4038 {
4039 const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(*mpSet, RES_BACKGROUND));
4040
4041 if(!aOriginalBrushItem->QueryValue(aTarget, pEntry->nMemberId))
4042 {
4043 OSL_ENSURE(false, "Error getting attribute from RES_BACKGROUND (!)");
4044 }
4045
4046 bDone = true;
4047 break;
4048 }
4050 {
4051 if (mpSet->Get(XATTR_FILLBMP_TILE).GetValue())
4052 {
4053 aTarget <<= drawing::BitmapMode_REPEAT;
4054 }
4055 else if (mpSet->Get(XATTR_FILLBMP_STRETCH).GetValue())
4056 {
4057 aTarget <<= drawing::BitmapMode_STRETCH;
4058 }
4059 else
4060 {
4061 aTarget <<= drawing::BitmapMode_NO_REPEAT;
4062 }
4063
4064 bDone = true;
4065 break;
4066 }
4067 }
4068 }
4069
4070 if(!bDone)
4071 {
4072 pPropSet->getPropertyValue( *pEntry, *mpSet, aTarget );
4073 }
4074
4075 if(bTakeCareOfDrawingLayerFillStyle)
4076 {
4077 if(pEntry->aType == cppu::UnoType<sal_Int16>::get() && pEntry->aType != aTarget.getValueType())
4078 {
4079 // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
4080 sal_Int32 nValue = 0;
4081 if (aTarget >>= nValue)
4082 {
4083 aTarget <<= static_cast<sal_Int16>(nValue);
4084 }
4085 }
4086
4087 // check for needed metric translation
4088 if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM)
4089 {
4090 bool bDoIt(true);
4091
4092 if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID)
4093 {
4094 // exception: If these ItemTypes are used, do not convert when these are negative
4095 // since this means they are intended as percent values
4096 sal_Int32 nValue = 0;
4097
4098 if(aTarget >>= nValue)
4099 {
4100 bDoIt = nValue > 0;
4101 }
4102 }
4103
4104 if(bDoIt)
4105 {
4106 const SfxItemPool& rPool = mrDoc.GetAttrPool();
4107 const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID));
4108
4109 if(eMapUnit != MapUnit::Map100thMM)
4110 {
4111 SvxUnoConvertToMM(eMapUnit, aTarget);
4112 }
4113 }
4114 }
4115 }
4116
4117 // add value
4118 pValues[i] = aTarget;
4119 }
4120
4121 return aRet;
4122}
4123
4124uno::Sequence< uno::Any > SwXAutoStyle::getPropertyValues (
4125 const uno::Sequence< OUString >& rPropertyNames )
4126{
4127 SolarMutexGuard aGuard;
4128 uno::Sequence< uno::Any > aValues;
4129
4130 // workaround for bad designed API
4131 try
4132 {
4133 aValues = GetPropertyValues_Impl( rPropertyNames );
4134 }
4135 catch (beans::UnknownPropertyException &)
4136 {
4137 css::uno::Any exc = cppu::getCaughtException();
4138 throw lang::WrappedTargetRuntimeException("Unknown property exception caught", static_cast < cppu::OWeakObject * > ( this ), exc );
4139 }
4140 catch (lang::WrappedTargetException &)
4141 {
4142 css::uno::Any exc = cppu::getCaughtException();
4143 throw lang::WrappedTargetRuntimeException("WrappedTargetException caught", static_cast < cppu::OWeakObject * > ( this ), exc );
4144 }
4145
4146 return aValues;
4147}
4148
4150 const uno::Sequence< OUString >& /*aPropertyNames*/,
4151 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
4152{
4153}
4154
4156 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
4157{
4158}
4159
4161 const uno::Sequence< OUString >& /*aPropertyNames*/,
4162 const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
4163{
4164}
4165
4166beans::PropertyState SwXAutoStyle::getPropertyState( const OUString& rPropertyName )
4167{
4168 SolarMutexGuard aGuard;
4169
4170 uno::Sequence< OUString > aNames { rPropertyName };
4171 uno::Sequence< beans::PropertyState > aStates = getPropertyStates(aNames);
4172 return aStates.getConstArray()[0];
4173}
4174
4175void SwXAutoStyle::setPropertyToDefault( const OUString& /*PropertyName*/ )
4176{
4177}
4178
4179uno::Any SwXAutoStyle::getPropertyDefault( const OUString& rPropertyName )
4180{
4181 const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
4182 return getPropertyDefaults ( aSequence ).getConstArray()[0];
4183}
4184
4185uno::Sequence< beans::PropertyState > SwXAutoStyle::getPropertyStates(
4186 const uno::Sequence< OUString >& rPropertyNames )
4187{
4188 if (!mpSet)
4189 {
4190 throw uno::RuntimeException();
4191 }
4192
4193 SolarMutexGuard aGuard;
4194 uno::Sequence< beans::PropertyState > aRet(rPropertyNames.getLength());
4195 beans::PropertyState* pStates = aRet.getArray();
4196 const OUString* pNames = rPropertyNames.getConstArray();
4197
4199 switch(meFamily)
4200 {
4204 default: ;
4205 }
4206
4207 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
4208 const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
4209 const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == meFamily);
4210
4211 for(sal_Int32 i = 0; i < rPropertyNames.getLength(); i++)
4212 {
4213 const OUString sPropName = pNames[i];
4214 const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
4215 if(!pEntry)
4216 {
4217 throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast < cppu::OWeakObject * > ( this ) );
4218 }
4219
4220 bool bDone(false);
4221
4222 if(bTakeCareOfDrawingLayerFillStyle)
4223 {
4224 // DrawingLayer PropertyStyle support
4225 switch(pEntry->nWID)
4226 {
4228 {
4229 if(SfxItemState::SET == mpSet->GetItemState(XATTR_FILLBMP_STRETCH, false)
4230 || SfxItemState::SET == mpSet->GetItemState(XATTR_FILLBMP_TILE, false))
4231 {
4232 pStates[i] = beans::PropertyState_DIRECT_VALUE;
4233 }
4234 else
4235 {
4236 pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
4237 }
4238
4239 bDone = true;
4240 break;
4241 }
4242 case RES_BACKGROUND:
4243 {
4245 pEntry->nMemberId))
4246 {
4247 pStates[i] = beans::PropertyState_DIRECT_VALUE;
4248 }
4249 else
4250 {
4251 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
4252 }
4253 bDone = true;
4254
4255 break;
4256 }
4257 }
4258 }
4259
4260 if(!bDone)
4261 {
4262 pStates[i] = pPropSet->getPropertyState(*pEntry, *mpSet );
4263 }
4264 }
4265
4266 return aRet;
4267}
4268
4270{
4271}
4272
4274 const uno::Sequence< OUString >& /*rPropertyNames*/ )
4275{
4276}
4277
4278uno::Sequence< uno::Any > SwXAutoStyle::getPropertyDefaults(
4279 const uno::Sequence< OUString >& /*aPropertyNames*/ )
4280{
4281 return { };
4282}
4283
4284uno::Sequence< beans::PropertyValue > SwXAutoStyle::getProperties()
4285{
4286 if( !mpSet )
4287 throw uno::RuntimeException();
4288 SolarMutexGuard aGuard;
4289 std::vector< beans::PropertyValue > aPropertyVector;
4290
4291 sal_Int8 nPropSetId = 0;
4292 switch(meFamily)
4293 {
4297 default: ;
4298 }
4299
4300 const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
4301 const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
4302
4303 SfxItemSet& rSet = *mpSet;
4304 SfxItemIter aIter(rSet);
4305
4306 for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
4307 {
4308 const sal_uInt16 nWID = pItem->Which();
4309
4310 // TODO: Optimize - and fix! the old iteration filled each WhichId
4311 // only once but there are more properties than WhichIds
4312 for( const auto pEntry : rMap.getPropertyEntries() )
4313 {
4314 if ( pEntry->nWID == nWID )
4315 {
4316 beans::PropertyValue aPropertyValue;
4317 aPropertyValue.Name = pEntry->aName;
4318 pItem->QueryValue( aPropertyValue.Value, pEntry->nMemberId );
4319 aPropertyVector.push_back( aPropertyValue );
4320 }
4321 }
4322 }
4323
4324 const sal_Int32 nCount = aPropertyVector.size();
4325 uno::Sequence< beans::PropertyValue > aRet( nCount );
4326 beans::PropertyValue* pProps = aRet.getArray();
4327
4328 for ( int i = 0; i < nCount; ++i, pProps++ )
4329 {
4330 *pProps = aPropertyVector[i];
4331 }
4332
4333 return aRet;
4334}
4335
4337 m_pDocShell(pDocShell), m_pTableAutoFormat(pTableAutoFormat), m_bPhysical(true)
4338{
4340}
4341
4342SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName) :
4343 m_pDocShell(pDocShell), m_pTableAutoFormat_Impl(new SwTableAutoFormat(rTableAutoFormatName)), m_bPhysical(false)
4344{
4347}
4348
4349uno::Reference<style::XStyle> SwXTextTableStyle::CreateXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName)
4350{
4351 SolarMutexGuard aGuard;
4352 uno::Reference<style::XStyle> xTextTableStyle;
4353 SwTableAutoFormat* pAutoFormat = GetTableAutoFormat(pDocShell, rTableAutoFormatName);
4354 if (pAutoFormat && pAutoFormat->GetName() == rTableAutoFormatName)
4355 {
4356 xTextTableStyle.set(pAutoFormat->GetXObject(), uno::UNO_QUERY);
4357 if (!xTextTableStyle.is())
4358 {
4359 xTextTableStyle.set(new SwXTextTableStyle(pDocShell, pAutoFormat));
4360 pAutoFormat->SetXObject(xTextTableStyle);
4361 }
4362 }
4363
4364 // If corresponding AutoFormat doesn't exist create a non physical style.
4365 if (!xTextTableStyle.is())
4366 {
4367 xTextTableStyle.set(new SwXTextTableStyle(pDocShell, rTableAutoFormatName));
4368 SAL_INFO("sw.uno", "creating SwXTextTableStyle for non existing SwTableAutoFormat");
4369 }
4370
4371 return xTextTableStyle;
4372}
4373
4375{
4376 const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
4377 assert(aTableTemplateMap.size() == STYLE_COUNT && "can not map SwTableAutoFormat to a SwXTextTableStyle");
4378 for (sal_Int32 i=0; i<STYLE_COUNT; ++i)
4379 {
4380 SwBoxAutoFormat* pBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
4381 uno::Reference<style::XStyle> xCellStyle(pBoxFormat->GetXObject(), uno::UNO_QUERY);
4382 if (!xCellStyle.is())
4383 {
4384 xCellStyle.set(new SwXTextCellStyle(m_pDocShell, pBoxFormat, m_pTableAutoFormat->GetName()));
4385 pBoxFormat->SetXObject(xCellStyle);
4386 }
4387 m_aCellStyles[i] = xCellStyle;
4388 }
4389}
4390
4392{
4393 static CellStyleNameMap const aMap
4394 {
4395 { "first-row" , FIRST_ROW_STYLE },
4396 { "last-row" , LAST_ROW_STYLE },
4397 { "first-column" , FIRST_COLUMN_STYLE },
4398 { "last-column" , LAST_COLUMN_STYLE },
4399 { "body" , BODY_STYLE },
4400 { "even-rows" , EVEN_ROWS_STYLE },
4401 { "odd-rows" , ODD_ROWS_STYLE },
4402 { "even-columns" , EVEN_COLUMNS_STYLE },
4403 { "odd-columns" , ODD_COLUMNS_STYLE },
4404 { "background" , BACKGROUND_STYLE },
4405 // loext namespace
4406 { "first-row-start-column" , FIRST_ROW_START_COLUMN_STYLE },
4407 { "first-row-end-column" , FIRST_ROW_END_COLUMN_STYLE },
4408 { "last-row-start-column" , LAST_ROW_START_COLUMN_STYLE },
4409 { "last-row-end-column" , LAST_ROW_END_COLUMN_STYLE },
4410 { "first-row-even-column" , FIRST_ROW_EVEN_COLUMN_STYLE },
4411 { "last-row-even-column" , LAST_ROW_EVEN_COLUMN_STYLE },
4412 };
4413 return aMap;
4414}
4415
4417{
4418 return m_pTableAutoFormat;
4419}
4420
4422{
4423 const size_t nStyles = pDocShell->GetDoc()->GetTableStyles().size();
4424 for(size_t i=0; i < nStyles; ++i)
4425 {
4426 SwTableAutoFormat* pAutoFormat = &pDocShell->GetDoc()->GetTableStyles()[i];
4427 if (pAutoFormat->GetName() == sName)
4428 {
4429 return pAutoFormat;
4430 }
4431 }
4432 // not found
4433 return nullptr;
4434}
4435
4437{
4438 if (!m_bPhysical)
4439 {
4440 // find table format in doc
4442 if (pTableAutoFormat)
4443 {
4444 m_bPhysical = true;
4446 const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
4447 for (size_t i=0; i<aTableTemplateMap.size(); ++i)
4448 {
4449 SwBoxAutoFormat* pOldBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
4450 uno::Reference<style::XStyle> xCellStyle(pOldBoxFormat->GetXObject(), uno::UNO_QUERY);
4451 if (!xCellStyle.is())
4452 continue;
4453 SwXTextCellStyle& rStyle = dynamic_cast<SwXTextCellStyle&>(*xCellStyle);
4454 SwBoxAutoFormat& rNewBoxFormat = pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
4455 rStyle.SetBoxFormat(&rNewBoxFormat);
4456 rNewBoxFormat.SetXObject(xCellStyle);
4457 }
4458 m_pTableAutoFormat_Impl = nullptr;
4459 m_pTableAutoFormat = pTableAutoFormat;
4460 m_pTableAutoFormat->SetXObject(uno::Reference<style::XStyle>(this));
4461 }
4462 else
4463 SAL_WARN("sw.uno", "setting style physical, but SwTableAutoFormat in document not found");
4464 }
4465 else
4466 SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextTableStyle");
4467}
4468
4469// XStyle
4471{
4472 SolarMutexGuard aGuard;
4473 // only first style is not user defined
4474 if (m_pDocShell->GetDoc()->GetTableStyles()[0].GetName() == m_pTableAutoFormat->GetName())
4475 return false;
4476
4477 return true;
4478}
4479
4481{
4482 SolarMutexGuard aGuard;
4483 if (!m_bPhysical)
4484 return false;
4485
4487
4488 for (SwFrameFormat* const & pFormat : *m_pDocShell->GetDoc()->GetTableFrameFormats())
4489 {
4490 if (!pFormat->GetInfo(aGetHt))
4491 {
4492 SwTable* pTable = SwTable::FindTable(pFormat);
4493 if (pTable->GetTableStyleName() == m_pTableAutoFormat->GetName())
4494 return true;
4495 }
4496 }
4497
4498 return false;
4499}
4500
4502{
4503 return OUString();
4504}
4505
4506void SAL_CALL SwXTextTableStyle::setParentStyle(const OUString& /*aParentStyle*/)
4507{ }
4508
4509//XNamed
4511{
4512 SolarMutexGuard aGuard;
4513 OUString sProgName;
4515 return sProgName;
4516}
4517
4518void SAL_CALL SwXTextTableStyle::setName(const OUString& rName)
4519{
4520 SolarMutexGuard aGuard;
4522}
4523
4524//XPropertySet
4525css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextTableStyle::getPropertySetInfo()
4526{
4527 static uno::Reference<beans::XPropertySetInfo> xRef(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_STYLE)->getPropertySetInfo());
4528 return xRef;
4529}
4530
4531void SAL_CALL SwXTextTableStyle::setPropertyValue(const OUString& /*rPropertyName*/, const css::uno::Any& /*aValue*/)
4532{
4533 SAL_WARN("sw.uno", "not implemented");
4534}
4535
4536css::uno::Any SAL_CALL SwXTextTableStyle::getPropertyValue(const OUString& rPropertyName)
4537{
4538 SolarMutexGuard aGuard;
4539 bool bIsRow = false;
4540
4541 if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_END_COLUMN)
4543 else if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_START_COLUMN)
4545 else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_END_COLUMN)
4547 else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_START_COLUMN)
4549 else if (rPropertyName == UNO_NAME_DISPLAY_NAME)
4551 else
4552 throw css::beans::UnknownPropertyException(rPropertyName);
4553
4554 return uno::Any(bIsRow ? OUString("row") : OUString("column"));
4555}
4556
4557void SAL_CALL SwXTextTableStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*xListener*/ )
4558{
4559 SAL_WARN("sw.uno", "not implemented");
4560}
4561
4562void SAL_CALL SwXTextTableStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*aListener*/ )
4563{
4564 SAL_WARN("sw.uno", "not implemented");
4565}
4566
4567void SAL_CALL SwXTextTableStyle::addVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ )
4568{
4569 SAL_WARN("sw.uno", "not implemented");
4570}
4571
4572void SAL_CALL SwXTextTableStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ )
4573{
4574 SAL_WARN("sw.uno", "not implemented");
4575}
4576
4577//XNameAccess
4578uno::Any SAL_CALL SwXTextTableStyle::getByName(const OUString& rName)
4579{
4580 SolarMutexGuard aGuard;
4581 const CellStyleNameMap& rMap = GetCellStyleNameMap();
4582 CellStyleNameMap::const_iterator iter = rMap.find(rName);
4583 if(iter == rMap.end())
4584 throw css::container::NoSuchElementException();
4585
4586 return css::uno::Any(m_aCellStyles[(*iter).second]);
4587}
4588
4589css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getElementNames()
4590{
4592}
4593
4594sal_Bool SAL_CALL SwXTextTableStyle::hasByName(const OUString& rName)
4595{
4596 const CellStyleNameMap& rMap = GetCellStyleNameMap();
4597 CellStyleNameMap::const_iterator iter = rMap.find(rName);
4598 return iter != rMap.end();
4599}
4600
4601//XNameContainer
4602void SAL_CALL SwXTextTableStyle::insertByName(const OUString& /*Name*/, const uno::Any& /*Element*/)
4603{
4604 SAL_WARN("sw.uno", "not implemented");
4605}
4606
4607void SAL_CALL SwXTextTableStyle::replaceByName(const OUString& rName, const uno::Any& rElement)
4608{
4609 SolarMutexGuard aGuard;
4610 const CellStyleNameMap& rMap = GetCellStyleNameMap();
4611 CellStyleNameMap::const_iterator iter = rMap.find(rName);
4612 if(iter == rMap.end())
4613 throw container::NoSuchElementException();
4614 const sal_Int32 nCellStyle = iter->second;
4615
4616 uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
4617 if (!xStyle.is())
4618 throw lang::IllegalArgumentException();
4619
4620 SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
4621 if (!pStyleToReplaceWith)
4622 throw lang::IllegalArgumentException();
4623
4624 // replace only with physical ...
4625 if (!pStyleToReplaceWith->IsPhysical())
4626 throw lang::IllegalArgumentException();
4627
4628 const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
4629 const sal_Int32 nBoxFormat = rTableTemplateMap[nCellStyle];
4630
4631 // move SwBoxAutoFormat to dest. SwTableAutoFormat
4632 m_pTableAutoFormat->SetBoxFormat(*pStyleToReplaceWith->GetBoxFormat(), nBoxFormat);
4633 // remove unassigned SwBoxAutoFormat, which is not anymore in use anyways
4634 m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(xStyle->getName());
4635 // make SwXTextCellStyle use new, moved SwBoxAutoFormat
4636 pStyleToReplaceWith->SetBoxFormat(&m_pTableAutoFormat->GetBoxFormat(nBoxFormat));
4637 m_pTableAutoFormat->GetBoxFormat(nBoxFormat).SetXObject(xStyle);
4638 // make this SwXTextTableStyle use new SwXTextCellStyle
4639 m_aCellStyles[nCellStyle] = xStyle;
4640}
4641
4642void SAL_CALL SwXTextTableStyle::removeByName(const OUString& /*Name*/)
4643{
4644 SAL_WARN("sw.uno", "not implemented");
4645}
4646
4647//XElementAccess
4649{
4651}
4652
4654{
4655 return true;
4656}
4657
4658//XServiceInfo
4660{
4661 return {"SwXTextTableStyle"};
4662}
4663
4664sal_Bool SAL_CALL SwXTextTableStyle::supportsService(const OUString& rServiceName)
4665{
4666 return cppu::supportsService(this, rServiceName);
4667}
4668
4669css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getSupportedServiceNames()
4670{
4671 return {"com.sun.star.style.Style"};
4672}
4673
4674// SwXTextCellStyle
4675SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, OUString sParentStyle) :
4676 m_pDocShell(pDocShell),
4677 m_pBoxAutoFormat(pBoxAutoFormat),
4678 m_sParentStyle(std::move(sParentStyle)),
4679 m_bPhysical(true)
4680{ }
4681
4683 m_pDocShell(pDocShell),
4684 m_pBoxAutoFormat_Impl(std::make_shared<SwBoxAutoFormat>()),
4685 m_sName(std::move(sName)),
4686 m_bPhysical(false)
4687{
4689}
4690
4692{
4693 return m_pBoxAutoFormat;
4694}
4695
4697{
4698 if (m_bPhysical)
4699 m_pBoxAutoFormat = pBoxFormat;
4700 else
4701 SAL_INFO("sw.uno", "trying to call SwXTextCellStyle::SetBoxFormat on non physical style");
4702}
4703
4705{
4706 if (!m_bPhysical)
4707 {
4709 if (pBoxAutoFormat)
4710 {
4711 m_bPhysical = true;
4712 m_pBoxAutoFormat_Impl = nullptr;
4713 m_pBoxAutoFormat = pBoxAutoFormat;
4714 m_pBoxAutoFormat->SetXObject(uno::Reference<style::XStyle>(this));
4715 }
4716 else
4717 SAL_WARN("sw.uno", "setting style physical, but SwBoxAutoFormat in document not found");
4718 }
4719 else
4720 SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextCellStyle");
4721}
4722
4724{
4725 return m_bPhysical;
4726}
4727
4728SwBoxAutoFormat* SwXTextCellStyle::GetBoxAutoFormat(SwDocShell* pDocShell, std::u16string_view sName, OUString* pParentName)
4729{
4730 if (sName.empty())
4731 return nullptr;
4732
4733 SwBoxAutoFormat* pBoxAutoFormat = pDocShell->GetDoc()->GetCellStyles().GetBoxFormat(sName);
4734 if (!pBoxAutoFormat)
4735 {
4736 sal_Int32 nTemplateIndex;
4737 OUString sParentName;
4738 std::u16string_view sCellSubName;
4739
4740 size_t nSeparatorIndex = sName.rfind('.');
4741 if (nSeparatorIndex == std::u16string_view::npos)
4742 return nullptr;
4743
4744 sParentName = sName.substr(0, nSeparatorIndex);
4745 sCellSubName = sName.substr(nSeparatorIndex+1);
4746 nTemplateIndex = o3tl::toInt32(sCellSubName)-1; // -1 because cell styles names start from 1, but internally are indexed from 0
4747 if (0 > nTemplateIndex)
4748 return nullptr;
4749
4750 const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
4751 if (rTableTemplateMap.size() <= o3tl::make_unsigned(nTemplateIndex))
4752 return nullptr;
4753
4755 SwTableAutoFormat* pTableAutoFormat = pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentName);
4756 if (!pTableAutoFormat)
4757 return nullptr;
4758
4759 if (pParentName)
4760 *pParentName = sParentName;
4761 sal_uInt32 nBoxIndex = rTableTemplateMap[nTemplateIndex];
4762 pBoxAutoFormat = &pTableAutoFormat->GetBoxFormat(nBoxIndex);
4763 }
4764
4765 return pBoxAutoFormat;
4766}
4767
4768css::uno::Reference<css::style::XStyle> SwXTextCellStyle::CreateXTextCellStyle(SwDocShell* pDocShell, const OUString& sName)
4769{
4770 uno::Reference<style::XStyle> xTextCellStyle;
4771
4772 if (!sName.isEmpty()) // create a cell style for a physical box
4773 {
4774 OUString sParentName;
4775 SwBoxAutoFormat* pBoxFormat = GetBoxAutoFormat(pDocShell, sName, &sParentName);
4776
4777 // something went wrong but we don't want a crash
4778 if (!pBoxFormat)
4779 {
4780 // return a default-dummy style to prevent crash
4781 static SwBoxAutoFormat aDefaultBoxFormat;
4782 pBoxFormat = &aDefaultBoxFormat;
4783 }
4784
4785 xTextCellStyle.set(pBoxFormat->GetXObject(), uno::UNO_QUERY);
4786 if (!xTextCellStyle.is())
4787 {
4788 xTextCellStyle.set(new SwXTextCellStyle(pDocShell, pBoxFormat, sParentName));
4789 pBoxFormat->SetXObject(xTextCellStyle);
4790 }
4791 }
4792 else // create a non physical style
4793 xTextCellStyle.set(new SwXTextCellStyle(pDocShell, sName));
4794
4795 return xTextCellStyle;
4796}
4797
4798// XStyle
4800{
4801 SolarMutexGuard aGuard;
4802 // if this cell belong to first table style then its default style
4804 return false;
4805
4806 return true;
4807}
4808
4810{
4811 SolarMutexGuard aGuard;
4812 uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY);
4813 if (!xFamiliesSupplier.is())
4814 return false;
4815
4816 uno::Reference<container::XNameAccess> xFamilies = xFamiliesSupplier->getStyleFamilies();
4817 if (!xFamilies.is())
4818 return false;
4819
4820 uno::Reference<container::XNameAccess> xTableStyles;
4821 xFamilies->getByName("TableStyles") >>= xTableStyles;
4822 if (!xTableStyles.is())
4823 return false;
4824
4825 uno::Reference<style::XStyle> xStyle;
4826 xTableStyles->getByName(m_sParentStyle) >>= xStyle;
4827 if (!xStyle.is())
4828 return false;
4829
4830 return xStyle->isInUse();
4831}
4832
4834{
4835 // Do not return name of the parent (which is a table style) because the parent should be a cell style.
4836 return OUString();
4837}
4838
4839void SAL_CALL SwXTextCellStyle::setParentStyle(const OUString& /*sParentStyle*/)
4840{
4841 // Changing parent to one which is unaware of it will lead to a something unexpected. getName() rely on a parent.
4842 SAL_INFO("sw.uno", "Changing SwXTextCellStyle parent");
4843}
4844
4845//XNamed
4846OUString SAL_CALL SwXTextCellStyle::getName()
4847{
4848 SolarMutexGuard aGuard;
4849 OUString sName;
4850
4851 // if style is physical then we request a name from doc
4852 if (m_bPhysical)
4853 {
4855 if (!pTableFormat)
4856 {
4857 // if auto format is not found as a child of table formats, look in SwDoc cellstyles
4859 }
4860 else
4861 {
4862 OUString sParentStyle;
4864 sName = sParentStyle + pTableFormat->GetTableTemplateCellSubName(*m_pBoxAutoFormat);
4865 }
4866 }
4867 else
4868 sName = m_sName;
4869
4870 return sName;
4871}
4872
4873void SAL_CALL SwXTextCellStyle::setName(const OUString& sName)
4874{
4875 SolarMutexGuard aGuard;
4876 // if style is physical then we can not rename it.
4877 if (!m_bPhysical)
4878 m_sName = sName;
4879 // change name if style is unassigned (name is not generated automatically)
4881}
4882
4883//XPropertySet
4884css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextCellStyle::getPropertySetInfo()
4885{
4886 static uno::Reference<beans::XPropertySetInfo> xRef(aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertySetInfo());
4887 return xRef;
4888}
4889
4890void SAL_CALL SwXTextCellStyle::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& aValue)
4891{
4892 SolarMutexGuard aGuard;
4894 if(pEntry)
4895 {
4896 switch(pEntry->nWID)
4897 {
4898 case RES_BACKGROUND:
4899 {
4901 rBrush.PutValue(aValue, 0);
4903 return;
4904 }
4905 case RES_BOX:
4906 {
4908 rBox.PutValue(aValue, pEntry->nMemberId);
4909 m_pBoxAutoFormat->SetBox(rBox);
4910 return;
4911 }
4912 case RES_VERT_ORIENT:
4913 {
4915 rVertOrient.PutValue(aValue, pEntry->nMemberId);
4917 return;
4918 }
4919 case RES_FRAMEDIR:
4920 {
4922 rDirItem.PutValue(aValue, pEntry->nMemberId);
4924 return;
4925 }
4926 case RES_BOXATR_FORMAT:
4927 {
4928 sal_uInt32 nKey;
4929 if (aValue >>= nKey)
4930 {
4931 // FIXME: It's not working for old "automatic" currency formats, which are still in use by autotbl.fmt.
4932 // Scenario:
4933 // 1) Mark all styles present by default in autotbl.fmt as default.
4934 // 2) convert all currencies present in autotbl.fmt before calling this code
4935 const SvNumberformat* pNumFormat = m_pDocShell->GetDoc()->GetNumberFormatter()->GetEntry(nKey);
4936 if (pNumFormat)
4938 }
4939 return;
4940 }
4941 // Paragraph attributes
4942 case RES_PARATR_ADJUST:
4943 {
4944 SvxAdjustItem rAdjustItem = m_pBoxAutoFormat->GetAdjust();
4945 rAdjustItem.PutValue(aValue, pEntry->nMemberId);
4946 m_pBoxAutoFormat->SetAdjust(rAdjustItem);
4947 return;
4948 }
4949 case RES_CHRATR_COLOR:
4950 {
4951 SvxColorItem rColorItem = m_pBoxAutoFormat->GetColor();
4952 rColorItem.PutValue(aValue, pEntry->nMemberId);
4953 m_pBoxAutoFormat->SetColor(rColorItem);
4954 return;
4955 }
4957 {
4958 SvxShadowedItem rShadowedItem = m_pBoxAutoFormat->GetShadowed();
4959 bool bValue = false; aValue >>= bValue;
4960 rShadowedItem.SetValue(bValue);
4961 m_pBoxAutoFormat->SetShadowed(rShadowedItem);
4962 return;
4963 }
4964 case RES_CHRATR_CONTOUR:
4965 {
4966 SvxContourItem rContourItem = m_pBoxAutoFormat->GetContour();
4967 bool bValue = false; aValue >>= bValue;
4968 rContourItem.SetValue(bValue);
4969 m_pBoxAutoFormat->SetContour(rContourItem);
4970 return;
4971 }
4973 {
4975 rCrossedOutItem.PutValue(aValue, pEntry->nMemberId);
4976 m_pBoxAutoFormat->SetCrossedOut(rCrossedOutItem);
4977 return;
4978 }
4980 {
4982 rUnderlineItem.PutValue(aValue, pEntry->nMemberId);
4983 m_pBoxAutoFormat->SetUnderline(rUnderlineItem);
4984 return;
4985 }
4987 {
4988 SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetHeight();
4989 rFontHeightItem.PutValue(aValue, pEntry->nMemberId);
4990 m_pBoxAutoFormat->SetHeight(rFontHeightItem);
4991 return;
4992 }
4993 case RES_CHRATR_WEIGHT:
4994 {
4995 SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetWeight();
4996 rWeightItem.PutValue(aValue, pEntry->nMemberId);
4997 m_pBoxAutoFormat->SetWeight(rWeightItem);
4998 return;
4999 }
5000 case RES_CHRATR_POSTURE:
5001 {
5002 SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetPosture();
5003 rPostureItem.PutValue(aValue, pEntry->nMemberId);
5004 m_pBoxAutoFormat->SetPosture(rPostureItem);
5005 return;
5006 }
5007 case RES_CHRATR_FONT:
5008 {
5009 SvxFontItem rFontItem = m_pBoxAutoFormat->GetFont();
5010 rFontItem.PutValue(aValue, pEntry->nMemberId);
5011 m_pBoxAutoFormat->SetFont(rFontItem);
5012 return;
5013 }
5015 {
5016 SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCJKHeight();
5017 rFontHeightItem.PutValue(aValue, pEntry->nMemberId);
5018 m_pBoxAutoFormat->SetCJKHeight(rFontHeightItem);
5019 return;
5020 }
5022 {
5024 rWeightItem.PutValue(aValue, pEntry->nMemberId);
5025 m_pBoxAutoFormat->SetCJKWeight(rWeightItem);
5026 return;
5027 }
5029 {
5031 rPostureItem.PutValue(aValue, pEntry->nMemberId);
5032 m_pBoxAutoFormat->SetCJKPosture(rPostureItem);
5033 return;
5034 }
5036 {
5038 rFontItem.PutValue(aValue, pEntry->nMemberId);
5039 m_pBoxAutoFormat->SetCJKFont(rFontItem);
5040 return;
5041 }
5042