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 <vcl/svapp.hxx>
27 #include <svl/hint.hxx>
28 #include <svtools/ctrltool.hxx>
29 #include <svl/style.hxx>
30 #include <svl/itemiter.hxx>
31 #include <svl/listener.hxx>
32 #include <svl/numformat.hxx>
33 #include <svl/zforlist.hxx>
34 #include <svl/zformat.hxx>
35 #include <svx/pageitem.hxx>
36 #include <editeng/colritem.hxx>
37 #include <editeng/contouritem.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <editeng/sizeitem.hxx>
41 #include <editeng/udlnitem.hxx>
42 #include <editeng/ulspitem.hxx>
43 #include <editeng/lrspitem.hxx>
44 #include <editeng/boxitem.hxx>
45 #include <editeng/postitem.hxx>
46 #include <editeng/shdditem.hxx>
47 #include <editeng/brushitem.hxx>
48 #include <editeng/flstitem.hxx>
49 #include <editeng/fhgtitem.hxx>
50 #include <editeng/paperinf.hxx>
51 #include <editeng/wghtitem.hxx>
52 #include <pagedesc.hxx>
53 #include <doc.hxx>
54 #include <IDocumentUndoRedo.hxx>
57 #include <docary.hxx>
58 #include <charfmt.hxx>
59 #include <cmdid.h>
60 #include <unomid.h>
61 #include <unomap.hxx>
62 #include <unostyle.hxx>
63 #include <unosett.hxx>
64 #include <docsh.hxx>
65 #include <paratr.hxx>
66 #include <unoprnms.hxx>
67 #include <shellio.hxx>
68 #include <docstyle.hxx>
69 #include <unotextbodyhf.hxx>
70 #include <fmthdft.hxx>
71 #include <fmtpdsc.hxx>
72 #include <strings.hrc>
73 #include <poolfmt.hxx>
74 #include <unoevent.hxx>
75 #include <fmtruby.hxx>
76 #include <SwStyleNameMapper.hxx>
77 #include <sfx2/printer.hxx>
78 #include <com/sun/star/frame/XModel.hpp>
79 #include <com/sun/star/io/IOException.hpp>
80 #include <com/sun/star/style/ParagraphStyleCategory.hpp>
81 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
82 #include <com/sun/star/beans/PropertyAttribute.hpp>
83 #include <com/sun/star/beans/NamedValue.hpp>
84 #include <com/sun/star/drawing/BitmapMode.hpp>
85 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
86 #include <com/sun/star/lang/IllegalArgumentException.hpp>
87 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
88 #include <com/sun/star/document/XEventsSupplier.hpp>
89 #include <com/sun/star/io/XInputStream.hpp>
90 #include <istyleaccess.hxx>
91 #include <fmtfsize.hxx>
92 #include <numrule.hxx>
93 #include <tblafmt.hxx>
94 #include <frameformats.hxx>
95 
97 #include <cppuhelper/exc_hlp.hxx>
100 #include <comphelper/sequence.hxx>
101 #include <sal/log.hxx>
102 
103 #include <svl/stylepool.hxx>
105 #include <editeng/unoipset.hxx>
106 #include <editeng/memberids.h>
107 #include <svx/unomid.hxx>
108 #include <svx/unoshape.hxx>
109 #include <svx/xflbstit.hxx>
110 #include <svx/xflbmtit.hxx>
111 #include <swunohelper.hxx>
112 #include <svx/xbtmpit.hxx>
113 
114 #include <ccoll.hxx>
115 #include <hints.hxx>
116 #include <uiitems.hxx>
117 
118 #include <cassert>
119 #include <memory>
120 #include <set>
121 #include <string_view>
122 #include <limits>
123 
124 using namespace css;
125 using namespace css::io;
126 using namespace css::lang;
127 using namespace css::uno;
128 
129 namespace {
130 
131 class SwXStyle;
132 class SwStyleProperties_Impl;
133 
134  struct StyleFamilyEntry
135  {
136  using GetCountOrName_t = std::function<sal_Int32 (const SwDoc&, OUString*, sal_Int32)>;
137  using CreateStyle_t = std::function<uno::Reference<css::style::XStyle>(SfxStyleSheetBasePool*, SwDocShell*, const OUString&)>;
138  using TranslateIndex_t = std::function<sal_uInt16(const sal_uInt16)>;
139  SfxStyleFamily m_eFamily;
140  sal_uInt16 m_nPropMapType;
141  uno::Reference<beans::XPropertySetInfo> m_xPSInfo;
142  SwGetPoolIdFromName m_aPoolId;
143  OUString m_sName;
144  TranslateId m_pResId;
145  GetCountOrName_t m_fGetCountOrName;
146  CreateStyle_t m_fCreateStyle;
147  TranslateIndex_t m_fTranslateIndex;
148  StyleFamilyEntry(SfxStyleFamily eFamily, sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, OUString const& sName, TranslateId pResId, GetCountOrName_t const & fGetCountOrName, CreateStyle_t const & fCreateStyle, TranslateIndex_t const & fTranslateIndex)
149  : m_eFamily(eFamily)
150  , m_nPropMapType(nPropMapType)
151  , m_xPSInfo(aSwMapProvider.GetPropertySet(nPropMapType)->getPropertySetInfo())
152  , m_aPoolId(aPoolId)
153  , m_sName(sName)
154  , m_pResId(pResId)
155  , m_fGetCountOrName(fGetCountOrName)
156  , m_fCreateStyle(fCreateStyle)
157  , m_fTranslateIndex(fTranslateIndex)
158  { }
159  };
160  const std::vector<StyleFamilyEntry>* our_pStyleFamilyEntries;
161  // these should really be constexprs, but MSVC still is apparently too stupid for them
162  #define nPoolChrNormalRange (RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN)
163  #define nPoolChrHtmlRange (RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN)
164  #define nPoolCollTextRange ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)
165  #define nPoolCollListsRange ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)
166  #define nPoolCollExtraRange ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)
167  #define nPoolCollRegisterRange ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)
168  #define nPoolCollDocRange ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN)
169  #define nPoolCollHtmlRange ( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN)
170  #define nPoolFrameRange ( RES_POOLFRM_END - RES_POOLFRM_BEGIN)
171  #define nPoolPageRange ( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)
172  #define nPoolNumRange ( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN)
173  #define nPoolCollListsStackedStart ( nPoolCollTextRange)
174  #define nPoolCollExtraStackedStart ( nPoolCollListsStackedStart + nPoolCollListsRange)
175  #define nPoolCollRegisterStackedStart ( nPoolCollExtraStackedStart + nPoolCollExtraRange)
176  #define nPoolCollDocStackedStart ( nPoolCollRegisterStackedStart + nPoolCollRegisterRange)
177  #define nPoolCollHtmlStackedStart ( nPoolCollDocStackedStart + nPoolCollDocRange)
178  using paragraphstyle_t = std::remove_const<decltype(style::ParagraphStyleCategory::TEXT)>::type;
179  using collectionbits_t = sal_uInt16;
180  struct ParagraphStyleCategoryEntry
181  {
182  paragraphstyle_t m_eCategory;
183  SfxStyleSearchBits m_nSwStyleBits;
184  collectionbits_t m_nCollectionBits;
185  ParagraphStyleCategoryEntry(paragraphstyle_t eCategory, SfxStyleSearchBits nSwStyleBits, collectionbits_t nCollectionBits)
186  : m_eCategory(eCategory)
187  , m_nSwStyleBits(nSwStyleBits)
188  , m_nCollectionBits(nCollectionBits)
189  { }
190  };
191  const std::vector<ParagraphStyleCategoryEntry>* our_pParagraphStyleCategoryEntries;
192 }
193 static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries();
194 
195 using namespace ::com::sun::star;
196 
197 namespace sw
198 {
199  namespace {
200 
201  class XStyleFamily : public cppu::WeakImplHelper
202  <
203  container::XNameContainer,
204  lang::XServiceInfo,
205  container::XIndexAccess,
206  beans::XPropertySet
207  >
208  , public SfxListener
209  {
210  const StyleFamilyEntry& m_rEntry;
211  SfxStyleSheetBasePool* m_pBasePool;
212  SwDocShell* m_pDocShell;
213 
214  SwXStyle* FindStyle(std::u16string_view rStyleName) const;
215  sal_Int32 GetCountOrName(OUString* pString, sal_Int32 nIndex = SAL_MAX_INT32)
216  { return m_rEntry.m_fGetCountOrName(*m_pDocShell->GetDoc(), pString, nIndex); };
217  static const StyleFamilyEntry& InitEntry(SfxStyleFamily eFamily)
218  {
219  auto pEntries = lcl_GetStyleFamilyEntries();
220  const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
221  [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
222  assert(pEntry != pEntries->end());
223  return *pEntry;
224  }
225  public:
226  XStyleFamily(SwDocShell* pDocShell, const SfxStyleFamily eFamily)
227  : m_rEntry(InitEntry(eFamily))
228  , m_pBasePool(pDocShell->GetStyleSheetPool())
229  , m_pDocShell(pDocShell)
230  {
231  if (m_pBasePool) //tdf#124142 html docs can have no styles
232  StartListening(*m_pBasePool);
233  }
234 
235  //XIndexAccess
236  virtual sal_Int32 SAL_CALL getCount() override
237  {
238  SolarMutexGuard aGuard;
239  return GetCountOrName(nullptr);
240  };
241  virtual uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override;
242 
243  //XElementAccess
244  virtual uno::Type SAL_CALL getElementType( ) override
245  { return cppu::UnoType<style::XStyle>::get(); };
246  virtual sal_Bool SAL_CALL hasElements( ) override
247  {
248  if(!m_pBasePool)
249  throw uno::RuntimeException();
250  return true;
251  }
252 
253  //XNameAccess
254  virtual uno::Any SAL_CALL getByName(const OUString& Name) override;
255  virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
256  virtual sal_Bool SAL_CALL hasByName(const OUString& Name) override;
257 
258  //XNameContainer
259  virtual void SAL_CALL insertByName(const OUString& Name, const uno::Any& Element) override;
260  virtual void SAL_CALL replaceByName(const OUString& Name, const uno::Any& Element) override;
261  virtual void SAL_CALL removeByName(const OUString& Name) override;
262 
263  //XPropertySet
264  virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override
265  { return {}; };
266  virtual void SAL_CALL setPropertyValue( const OUString&, const uno::Any&) override
267  { SAL_WARN("sw.uno", "###unexpected!"); };
268  virtual uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
269  virtual void SAL_CALL addPropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override
270  { SAL_WARN("sw.uno", "###unexpected!"); };
271  virtual void SAL_CALL removePropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override
272  { SAL_WARN("sw.uno", "###unexpected!"); };
273  virtual void SAL_CALL addVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override
274  { SAL_WARN("sw.uno", "###unexpected!"); };
275  virtual void SAL_CALL removeVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override
276  { SAL_WARN("sw.uno", "###unexpected!"); };
277 
278  //SfxListener
279  virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override
280  {
281  if(rHint.GetId() == SfxHintId::Dying)
282  {
283  m_pBasePool = nullptr;
284  m_pDocShell = nullptr;
285  EndListening(rBC);
286  }
287  }
288 
289  //XServiceInfo
290  virtual OUString SAL_CALL getImplementationName() override
291  { return {"XStyleFamily"}; };
292  virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override
293  { return cppu::supportsService(this, rServiceName); };
294  virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
295  { return { "com.sun.star.style.StyleFamily" }; }
296  };
297 
298  }
299 }
300 
301 namespace {
302 
303 class SwStyleBase_Impl;
304 class SwXStyle : public cppu::WeakImplHelper
305  <
306  css::style::XStyle,
307  css::beans::XPropertySet,
308  css::beans::XMultiPropertySet,
309  css::lang::XServiceInfo,
310  css::lang::XUnoTunnel,
311  css::beans::XPropertyState,
312  css::beans::XMultiPropertyStates
313  >
314  , public SfxListener
315  , public SvtListener
316 {
317  SwDoc* m_pDoc;
318  OUString m_sStyleName;
319  const StyleFamilyEntry& m_rEntry;
320  bool m_bIsDescriptor;
321  bool m_bIsConditional;
322  OUString m_sParentStyleName;
323 
324 protected:
325  SfxStyleSheetBasePool* m_pBasePool;
326  std::unique_ptr<SwStyleProperties_Impl> m_pPropertiesImpl;
327  css::uno::Reference<css::container::XNameAccess> m_xStyleFamily;
328  css::uno::Reference<css::beans::XPropertySet> m_xStyleData;
329 
330  template<sal_uInt16>
331  void SetPropertyValue(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&);
332  void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues );
333  SfxStyleSheetBase* GetStyleSheetBase();
334  void PrepareStyleBase(SwStyleBase_Impl& rBase);
335  template<sal_uInt16>
336  uno::Any GetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
337  uno::Any GetStyleProperty_Impl(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
338  uno::Any GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName);
339 
340 public:
341  SwXStyle(SwDoc* pDoc, SfxStyleFamily eFam, bool bConditional = false);
342  SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const OUString& rStyleName);
343  virtual ~SwXStyle() override;
344 
345 
346  static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId();
347 
348  //XUnoTunnel
349  virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override;
350 
351  //XNamed
352  virtual OUString SAL_CALL getName() override;
353  virtual void SAL_CALL setName(const OUString& Name_) override;
354 
355  //XStyle
356  virtual sal_Bool SAL_CALL isUserDefined() override;
357  virtual sal_Bool SAL_CALL isInUse() override;
358  virtual OUString SAL_CALL getParentStyle() override;
359  virtual void SAL_CALL setParentStyle(const OUString& aParentStyle) override;
360 
361  //XPropertySet
362  virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override;
363  virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
364  virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
365  virtual void SAL_CALL addPropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override
366  { OSL_FAIL("not implemented"); };
367  virtual void SAL_CALL removePropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override
368  { OSL_FAIL("not implemented"); };
369  virtual void SAL_CALL addVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override
370  { OSL_FAIL("not implemented"); };
371  virtual void SAL_CALL removeVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override
372  { OSL_FAIL("not implemented"); };
373 
374  //XMultiPropertySet
375  virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override;
376  virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override;
377  virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
378  {};
379  virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
380  {};
381  virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
382  {};
383 
384  //XPropertyState
385  virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override;
386  virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override;
387  virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override;
388  virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override;
389 
390  //XMultiPropertyStates
391  virtual void SAL_CALL setAllPropertiesToDefault( ) override;
392  virtual void SAL_CALL setPropertiesToDefault( const css::uno::Sequence< OUString >& aPropertyNames ) override;
393  virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyDefaults( const css::uno::Sequence< OUString >& aPropertyNames ) override;
394 
395  //XServiceInfo
396  virtual OUString SAL_CALL getImplementationName() override
397  { return {"SwXStyle"}; };
398  virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override
399  { return cppu::supportsService(this, rServiceName); };
400  virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
401 
402  //SfxListener
403  virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
404  //SvtListener
405  virtual void Notify(const SfxHint&) override;
406  const OUString& GetStyleName() const { return m_sStyleName;}
407  SfxStyleFamily GetFamily() const {return m_rEntry.m_eFamily;}
408 
409  bool IsDescriptor() const {return m_bIsDescriptor;}
410  bool IsConditional() const { return m_bIsConditional;}
411  const OUString& GetParentStyleName() const { return m_sParentStyleName;}
412  void SetDoc(SwDoc* pDc, SfxStyleSheetBasePool* pPool)
413  {
414  m_bIsDescriptor = false; m_pDoc = pDc;
415  m_pBasePool = pPool;
416  SfxListener::StartListening(*m_pBasePool);
417  }
418  SwDoc* GetDoc() const { return m_pDoc; }
419  void Invalidate();
420  void ApplyDescriptorProperties();
421  void SetStyleName(const OUString& rSet){ m_sStyleName = rSet;}
426  void SetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase);
427  void PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertyMapEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl);
428 };
429 
430 class SwXFrameStyle
431  : public SwXStyle
432  , public css::document::XEventsSupplier
433  , public sw::ICoreFrameStyle
434 {
435 public:
436  SwXFrameStyle(SfxStyleSheetBasePool& rPool,
437  SwDoc* pDoc,
438  const OUString& rStyleName) :
439  SwXStyle(&rPool, SfxStyleFamily::Frame, pDoc, rStyleName){}
440  explicit SwXFrameStyle(SwDoc *pDoc);
441 
442  virtual void SAL_CALL acquire( ) noexcept override {SwXStyle::acquire();}
443  virtual void SAL_CALL release( ) noexcept override {SwXStyle::release();}
444 
445  virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
446  virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
447  virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents( ) override;
448 
449  //ICoreStyle
450  virtual void SetItem(sal_uInt16 eAtr, const SfxPoolItem& rItem) override;
451  virtual const SfxPoolItem* GetItem(sal_uInt16 eAtr) override;
452  virtual css::document::XEventsSupplier& GetEventsSupplier() override
453  { return *this; };
454 };
455 
456 class SwXPageStyle
457  : public SwXStyle
458 {
459 protected:
460  void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues );
461  css::uno::Sequence< css::uno::Any > GetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames );
462 
463 public:
464  SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName);
465  explicit SwXPageStyle(SwDocShell* pDocSh);
466 
467  virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
468  virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
469 
470  virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override;
471  virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override;
472 };
473 
474 }
475 
476 using sw::XStyleFamily;
477 
479  { return {"SwXStyleFamilies"}; }
480 
481 sal_Bool SwXStyleFamilies::supportsService(const OUString& rServiceName)
482 {
483  return cppu::supportsService(this, rServiceName);
484 }
485 
487  { return { "com.sun.star.style.StyleFamilies" }; }
488 
490  SwUnoCollection(rDocShell.GetDoc()),
491  m_pDocShell(&rDocShell)
492  { }
493 
495  { }
496 
497 uno::Any SAL_CALL SwXStyleFamilies::getByName(const OUString& Name)
498 {
499  SolarMutexGuard aGuard;
500  if(!IsValid())
501  throw uno::RuntimeException();
502  auto pEntries(lcl_GetStyleFamilyEntries());
503  const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
504  [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; });
505  if(pEntry == pEntries->end())
506  throw container::NoSuchElementException();
507  return getByIndex(pEntry-pEntries->begin());
508 }
509 
510 uno::Sequence< OUString > SwXStyleFamilies::getElementNames()
511 {
512  auto pEntries(lcl_GetStyleFamilyEntries());
513  uno::Sequence<OUString> aNames(pEntries->size());
514  std::transform(pEntries->begin(), pEntries->end(),
515  aNames.getArray(), [] (const StyleFamilyEntry& e) { return e.m_sName; });
516  return aNames;
517 }
518 
520 {
521  auto pEntries(lcl_GetStyleFamilyEntries());
522  return std::any_of(pEntries->begin(), pEntries->end(),
523  [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; });
524 }
525 
527 {
528  return lcl_GetStyleFamilyEntries()->size();
529 }
530 
532 {
533  auto pEntries(lcl_GetStyleFamilyEntries());
534  SolarMutexGuard aGuard;
535  if(nIndex < 0 || nIndex >= static_cast<sal_Int32>(pEntries->size()))
536  throw lang::IndexOutOfBoundsException();
537  if(!IsValid())
538  throw uno::RuntimeException();
539  auto eFamily = (*pEntries)[nIndex].m_eFamily;
540  assert(eFamily != SfxStyleFamily::All);
541  auto& rxFamily = m_vFamilies[eFamily];
542  if(!rxFamily.is())
543  rxFamily = new XStyleFamily(m_pDocShell, eFamily);
544  return uno::Any(rxFamily);
545 }
546 
548 {
550 }
551 
553  { return true; }
554 
555 void SwXStyleFamilies::loadStylesFromURL(const OUString& rURL,
556  const uno::Sequence< beans::PropertyValue >& aOptions)
557 {
558  SolarMutexGuard aGuard;
559  if(!IsValid() || rURL.isEmpty())
560  throw uno::RuntimeException();
561  SwgReaderOption aOpt;
562  aOpt.SetFrameFormats(true);
563  aOpt.SetTextFormats(true);
564  aOpt.SetPageDescs(true);
565  aOpt.SetNumRules(true);
566  aOpt.SetMerge(false);
567  for(const auto& rProperty: aOptions)
568  {
569  bool bValue = false;
570  if(rProperty.Value.getValueType() == cppu::UnoType<bool>::get())
571  bValue = rProperty.Value.get<bool>();
572 
573  if(rProperty.Name == UNO_NAME_OVERWRITE_STYLES)
574  aOpt.SetMerge(!bValue);
575  else if(rProperty.Name == UNO_NAME_LOAD_NUMBERING_STYLES)
576  aOpt.SetNumRules(bValue);
577  else if(rProperty.Name == UNO_NAME_LOAD_PAGE_STYLES)
578  aOpt.SetPageDescs(bValue);
579  else if(rProperty.Name == UNO_NAME_LOAD_FRAME_STYLES)
580  aOpt.SetFrameFormats(bValue);
581  else if(rProperty.Name == UNO_NAME_LOAD_TEXT_STYLES)
582  aOpt.SetTextFormats(bValue);
583  else if(rProperty.Name == "InputStream")
584  {
585  Reference<XInputStream> xInputStream;
586  if (!(rProperty.Value >>= xInputStream))
587  throw IllegalArgumentException("Parameter 'InputStream' could not be converted to "
588  "type 'com::sun::star::io::XInputStream'",
589  nullptr, 0);
590 
591  aOpt.SetInputStream(xInputStream);
592 
593  }
594  }
595  const ErrCode nErr = m_pDocShell->LoadStylesFromFile( rURL, aOpt, true );
596  if(nErr)
597  throw io::IOException();
598 }
599 
600 uno::Sequence< beans::PropertyValue > SwXStyleFamilies::getStyleLoaderOptions()
601 {
602  SolarMutexGuard aGuard;
603  const uno::Any aVal(true);
605  { UNO_NAME_LOAD_TEXT_STYLES, aVal },
606  { UNO_NAME_LOAD_FRAME_STYLES, aVal },
607  { UNO_NAME_LOAD_PAGE_STYLES, aVal },
609  { UNO_NAME_OVERWRITE_STYLES, aVal }
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 == u"" 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 
630 template<enum SfxStyleFamily>
631 static sal_Int32 lcl_GetCountOrName(const SwDoc&, OUString*, sal_Int32);
632 
633 template<>
634 sal_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 
659 template<>
660 sal_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 
681 template<>
682 sal_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 
702 template<>
703 sal_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);
711  if(!IsPoolUserFormat(rDesc.GetPoolFormatId()))
712  continue;
713  if(nIndex == nCount)
714  {
715  *pString = rDesc.GetName();
716  break;
717  }
718  ++nCount;
719  }
720  nCount += nPoolPageRange;
721  return nCount;
722 }
723 
724 template<>
725 sal_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 
745 template<>
746 sal_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 
759 template<>
760 sal_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 
782 template<SfxStyleFamily eFamily>
783 static 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 
786 template<>
787 uno::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); };
789 template<>
790 uno::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 
793 template<>
794 uno::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 
797 template<>
798 uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Table>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
799  { return SwXTextTableStyle::CreateXTextTableStyle(pDocShell, sStyleName); };
800 
801 template<>
802 uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Cell>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
803  { return SwXTextCellStyle::CreateXTextCellStyle(pDocShell, sStyleName); };
804 
805 uno::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.
814 uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyleCondParagraph(SwDoc& rDoc)
815  { return new SwXStyle(&rDoc, SfxStyleFamily::Para, true); };
816 
817 template<enum SfxStyleFamily>
818 static sal_uInt16 lcl_TranslateIndex(const sal_uInt16 nIndex);
819 
820 template<>
821 sal_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 
831 template<>
832 sal_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 
850 template<>
851 sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Table>(const sal_uInt16 nIndex)
852 {
853  return nIndex;
854 }
855 
856 template<>
857 sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Cell>(const sal_uInt16 nIndex)
858 {
859  return nIndex;
860 }
861 
862 template<sal_uInt16 nRangeBegin, sal_uInt16 nRangeSize>
863 static sal_uInt16 lcl_TranslateIndexRange(const sal_uInt16 nIndex)
864 {
865  if(nIndex < nRangeSize)
866  return nIndex + nRangeBegin;
867  throw lang::IndexOutOfBoundsException();
868 }
869 
870 uno::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 
889 uno::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 
905 uno::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  }
918  return comphelper::containerToSequence(vRet);
919 }
920 
921 sal_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 
932 void 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 
995 void 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 
1056 void 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 
1080 uno::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 
1089 SwXStyle* 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 
1102 static 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 
1119 static 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 
1135 namespace {
1136 
1137 class SwStyleProperties_Impl
1138 {
1139  const SfxItemPropertyMap& mrMap;
1140  std::map<OUString, uno::Any> m_vPropertyValues;
1141 public:
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 
1203 namespace
1204 {
1205 }
1206 
1207 const uno::Sequence<sal_Int8>& SwXStyle::getUnoTunnelId()
1208 {
1209  static const comphelper::UnoIdInit theSwXStyleUnoTunnelId;
1210  return theSwXStyleUnoTunnelId.getSeq();
1211 }
1212 
1213 sal_Int64 SAL_CALL SwXStyle::getSomething(const uno::Sequence<sal_Int8>& rId)
1214 {
1215  return comphelper::getSomethingImpl(rId, this);
1216 }
1217 
1218 
1219 uno::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 
1262 static 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 
1273 static 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 
1289 static 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 
1303 static 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 
1312 SwXStyle::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 
1328 SwXStyle::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 
1337 SwXStyle::~SwXStyle()
1338 {
1339  SolarMutexGuard aGuard;
1340  if(m_pBasePool)
1341  SfxListener::EndListening(*m_pBasePool);
1342  m_pPropertiesImpl.reset();
1344 }
1345 
1346 void 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 
1356 OUString 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 
1370 void 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 
1388 sal_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 
1398 sal_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 
1407 OUString 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 
1424 void 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 
1456 uno::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;
1462  xCondParaRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CONDITIONAL_PARA_STYLE)->getPropertySetInfo();
1463  return xCondParaRef;
1464  }
1465  return m_rEntry.m_xPSInfo;
1466 }
1467 
1468 void SwXStyle::ApplyDescriptorProperties()
1469 {
1470  m_bIsDescriptor = false;
1471  m_xStyleData.clear();
1472  m_xStyleFamily.clear();
1473  m_pPropertiesImpl->Apply(*this);
1474 }
1475 
1476 namespace {
1477 
1478 class SwStyleBase_Impl
1479 {
1480 private:
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;
1488 public:
1489  SwStyleBase_Impl(SwDoc& rSwDoc, const OUString& rName, const SwAttrSet* pParentStyle)
1490  : m_rDoc(rSwDoc)
1491  , m_pOldPageDesc(nullptr)
1492  , m_pItemSet(nullptr)
1493  , m_rStyleName(rName)
1494  , m_pParentStyle(pParentStyle)
1495  { }
1496 
1497  rtl::Reference<SwDocStyleSheet>& getNewBase()
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 
1543  const TranslateId STR_POOLPAGE_ARY[] =
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 
1559 const 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 
1584 static sal_uInt8 lcl_TranslateMetric(const SfxItemPropertyMapEntry& rEntry, SwDoc* pDoc, uno::Any& o_aValue)
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 }
1604 template<>
1605 void 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 }
1614 template<>
1615 void 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 }
1626 template<>
1627 void 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 }
1633 template<>
1634 void 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  const Graphic aNullGraphic;
1651  SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
1652  XFillBitmapItem aXFillBitmapItem(aNullGraphic);
1653  aXFillBitmapItem.PutValue(aValue, nMemberId);
1654  rStyleSet.Put(aXFillBitmapItem);
1655  }
1656  }
1657  else
1658  SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase);
1659 }
1660 template<>
1661 void 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 }
1679 template<>
1680 void 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 }
1693 template<>
1694 void 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 }
1723 template<>
1724 void 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()
1741  && !SwXNumberingRules::isInvalidStyle(rCharName)
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 }
1774 template<>
1775 void 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 }
1783 template<>
1784 void 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 
1794 template <>
1795 void 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 
1808 template<>
1809 void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1810 {
1811  if(MID_PAGEDESC_PAGEDESCNAME != rEntry.nMemberId)
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(*pNewDesc);
1842  }
1843 }
1844 template<>
1845 void 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 }
1858 template<>
1859 void 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 }
1869 template<>
1870 void 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 }
1905 template<>
1906 void 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 }
1923 template<>
1924 void 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 }
1935 template<>
1936 void 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(*pRuby);
1959  SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
1960 }
1961 template<>
1962 void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
1963 {
1964  if(MID_DROPCAP_CHAR_STYLE_NAME != rEntry.nMemberId)
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(*pDrop);
1988 }
1989 template<>
1990 void 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 
2008 void 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>) },
2036  { RES_TXTATR_CJK_RUBY, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>) },
2037  { RES_PARATR_DROP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>) },
2038  { RES_PARATR_NUMRULE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>) }
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 
2054 void 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 
2095 void 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 
2113 SfxStyleSheetBase* 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 }
2120 void 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 
2129 template<>
2130 uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
2131 template<>
2132 uno::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 }
2145 template<>
2146 uno::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 }
2154 template<>
2155 uno::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 }
2165 template<>
2166 uno::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 }
2180 template<>
2181 uno::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 }
2189 template<>
2190 uno::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 }
2196 template<>
2197 uno::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 
2205 template <>
2206 uno::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 
2217 template<>
2218 uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
2219 {
2220  PrepareStyleBase(rBase);
2221  if(MID_PAGEDESC_PAGEDESCNAME != rEntry.nMemberId)
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 }
2235 template<>
2236 uno::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 }
2246 template<>
2247 uno::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 }
2252 template<>
2253 uno::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 }
2282 template<>
2283 uno::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 }
2300 template<>
2301 uno::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 }
2314 template<>
2315 uno::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 }
2325 template<>
2326 uno::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 }
2336 template<>
2337 uno::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 
2363 uno::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 
2396 uno::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 
2439 uno::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 
2452 uno::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 
2485 void 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 
2493 beans::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)
2503 static 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 != u"" 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 }
2515 uno::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  {
2561  case OWN_ATTR_FILLBMP_MODE:
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 
2611 void SwXStyle::setPropertyToDefault(const OUString& rPropertyName)
2612 {
2613  const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
2614  setPropertiesToDefault(aSequence);
2615 }
2616 
2617 static 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 
2638 void 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 
2685 void 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 
2758 uno::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 
2799 uno::Any SwXStyle::getPropertyDefault(const OUString& rPropertyName)
2800 {
2801  const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
2802  return getPropertyDefaults(aSequence)[0];
2803 }
2804 
2805 void 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 
2824 void 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 
2833 SwXPageStyle::SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName)
2834  : SwXStyle(&rPool, SfxStyleFamily::Page, pDocSh->GetDoc(), rStyleName)
2835 { }
2836 
2837 SwXPageStyle::SwXPageStyle(SwDocShell* pDocSh)
2838  : SwXStyle(pDocSh->GetDoc(), SfxStyleFamily::Page)
2839 { }
2840 
2841 void 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  const 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(*pNewSetItem);
2862 }
2863 
2864 void 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 
2872  const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PAGE_STYLE);
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;
2967  case XATTR_FILLBMP_SIZELOG:
2972  case XATTR_FILLBMP_POS:
2973  case XATTR_FILLBMP_SIZEX:
2974  case XATTR_FILLBMP_SIZEY:
2975  case XATTR_FILLBMP_STRETCH:
2976  case XATTR_FILLBMP_TILE:
2977  case OWN_ATTR_FILLBMP_MODE:
2978  case XATTR_FILLCOLOR:
2979  case XATTR_FILLBACKGROUND:
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(*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:
3032  case FN_UNO_HEADER_RIGHT:
3033  case FN_UNO_HEADER_FIRST:
3034  case FN_UNO_FOOTER:
3035  case FN_UNO_FOOTER_LEFT:
3036  case FN_UNO_FOOTER_RIGHT:
3037  case FN_UNO_FOOTER_FIRST:
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 
3070 void 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 
3089 static 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 
3105 uno::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  }
3128  const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PAGE_STYLE);
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;
3181  case XATTR_FILLBMP_SIZELOG:
3186  case XATTR_FILLBMP_POS:
3187  case XATTR_FILLBMP_SIZEX:
3188  case XATTR_FILLBMP_SIZEY:
3189  case XATTR_FILLBMP_STRETCH:
3190  case XATTR_FILLBMP_TILE:
3191  case OWN_ATTR_FILLBMP_MODE:
3192  case XATTR_FILLCOLOR:
3193  case XATTR_FILLBACKGROUND:
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:
3234  case FN_UNO_HEADER_FIRST:
3235  case FN_UNO_HEADER_RIGHT:
3236  case FN_UNO_FOOTER:
3237  case FN_UNO_FOOTER_LEFT:
3238  case FN_UNO_FOOTER_FIRST:
3239  case FN_UNO_FOOTER_RIGHT:
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 
3296 uno::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 
3322 uno::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 
3329 void 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 
3369 SwXFrameStyle::SwXFrameStyle(SwDoc *pDoc)
3370  : SwXStyle(pDoc, SfxStyleFamily::Frame, false)
3371 { }
3372 
3373 void 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 
3386 const 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 
3396 uno::Sequence<uno::Type> SwXFrameStyle::getTypes()
3397 {
3398  return cppu::OTypeCollection(
3400  SwXStyle::getTypes()
3401  ).getTypes();
3402 }
3403 
3404 uno::Any SwXFrameStyle::queryInterface(const uno::Type& rType)
3405 {
3407  return uno::Any(uno::Reference<XEventsSupplier>(this));
3408  return SwXStyle::queryInterface(rType);
3409 }
3410 
3411 uno::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;
3431 public:
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 {
3450  return AUTOSTYLE_FAMILY_COUNT;
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;
3463  IStyleAccess::SwAutoStyleFamily nType = aAutoStyleByIndex[nIndex];
3464  switch( nType )
3465  {
3467  {
3468  if(!m_xAutoCharStyles.is())
3469  m_xAutoCharStyles = new SwXAutoStyleFamily(m_pDocShell, nType);
3470  aRef = m_xAutoCharStyles;
3471  }
3472  break;
3474  {
3475  if(!m_xAutoRubyStyles.is())
3476  m_xAutoRubyStyles = new SwXAutoStyleFamily(m_pDocShell, nType );
3477  aRef = m_xAutoRubyStyles;
3478  }
3479  break;
3481  {
3482  if(!m_xAutoParaStyles.is())
3483  m_xAutoParaStyles = new SwXAutoStyleFamily(m_pDocShell, nType );
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 
3506 uno::Any SwXAutoStyles::getByName(const OUString& Name)
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 
3520 uno::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 
3530 sal_Bool SwXAutoStyles::hasByName(const OUString& Name)
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 
3557 uno::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
3619  aSet.SetParent(&m_pDocShell->GetDoc()->GetDfltTextFormatColl()->GetAttrSet());
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  const Graphic aNullGraphic;
3699  XFillBitmapItem aXFillBitmapItem(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  }
3724  case OWN_ATTR_FILLBMP_MODE:
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
3774  m_pDocShell->GetDoc()->CheckForUniqueItemForLineFillNameOrIndex(aSet);
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 
3783 uno::Reference< container::XEnumeration > SwXAutoStyleFamily::createEnumeration( )
3784 {
3785  if( !m_pDocShell )
3786  throw uno::RuntimeException();
3787  return uno::Reference< container::XEnumeration >
3788  (new SwXAutoStylesEnumerator( *m_pDocShell->GetDoc(), m_eFamily ));
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> const & pInitSet,
3887 : mpSet(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 
3899 void SwXAutoStyle::Notify(const SfxHint& rHint)
3900 {
3901  if(rHint.GetId() == SfxHintId::Dying)
3902  mpSet.reset();
3903 }
3904 
3905 uno::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 
3950 void SwXAutoStyle::setPropertyValue( const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
3951 {
3952 }
3953 
3954 uno::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 
3961 void SwXAutoStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/,
3962  const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
3963 {
3964 }
3965 
3966 void SwXAutoStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/,
3967  const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
3968 {
3969 }
3970 
3971 void SwXAutoStyle::addVetoableChangeListener( const OUString& /*PropertyName*/,
3972  const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
3973 {
3974 }
3975 
3976 void 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 
3987 uno::Sequence< uno::Any > SwXAutoStyle::GetPropertyValues_Impl(
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  }
4049  case OWN_ATTR_FILLBMP_MODE:
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 
4124 uno::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 
4166 beans::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 
4175 void SwXAutoStyle::setPropertyToDefault( const OUString& /*PropertyName*/ )
4176 {
4177 }
4178 
4179 uno::Any SwXAutoStyle::getPropertyDefault( const OUString& rPropertyName )
4180 {
4181  const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
4182  return getPropertyDefaults ( aSequence ).getConstArray()[0];
4183 }
4184 
4185 uno::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  {
4227  case OWN_ATTR_FILLBMP_MODE:
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 
4278 uno::Sequence< uno::Any > SwXAutoStyle::getPropertyDefaults(
4279  const uno::Sequence< OUString >& /*aPropertyNames*/ )
4280 {
4281  return { };
4282 }
4283 
4284 uno::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 
4342 SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName) :
4343  m_pDocShell(pDocShell), m_pTableAutoFormat_Impl(new SwTableAutoFormat(rTableAutoFormatName)), m_bPhysical(false)
4344 {
4347 }
4348 
4349 uno::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
4441  SwTableAutoFormat* pTableAutoFormat = GetTableAutoFormat(m_pDocShell, m_pTableAutoFormat->GetName());
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 
4486  SwAutoFormatGetDocNode aGetHt( &m_pDocShell->GetDoc()->GetNodes() );
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 
4506 void SAL_CALL SwXTextTableStyle::setParentStyle(const OUString& /*aParentStyle*/)
4507 { }
4508 
4509 //XNamed
4510 OUString SAL_CALL SwXTextTableStyle::getName()
4511 {
4512  SolarMutexGuard aGuard;
4513  OUString sProgName;
4515  return sProgName;
4516 }
4517 
4518 void SAL_CALL SwXTextTableStyle::setName(const OUString& rName)
4519 {
4520  SolarMutexGuard aGuard;
4521  m_pTableAutoFormat->SetName(rName);
4522 }
4523 
4524 //XPropertySet
4525 css::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 
4531 void SAL_CALL SwXTextTableStyle::setPropertyValue(const OUString& /*rPropertyName*/, const css::uno::Any& /*aValue*/)
4532 {
4533  SAL_WARN("sw.uno", "not implemented");
4534 }
4535 
4536 css::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)
4550  return uno::Any(m_pTableAutoFormat->GetName());
4551  else
4552  throw css::beans::UnknownPropertyException(rPropertyName);
4553 
4554  return uno::Any(bIsRow ? OUString("row") : OUString("column"));
4555 }
4556 
4557 void 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 
4562 void 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 
4567 void 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 
4572 void 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
4578 uno::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 
4589 css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getElementNames()
4590 {
4591  SolarMutexGuard aGuard;
4593 }
4594 
4595 sal_Bool SAL_CALL SwXTextTableStyle::hasByName(const OUString& rName)
4596 {
4597  SolarMutexGuard aGuard;
4598  const CellStyleNameMap& rMap = GetCellStyleNameMap();
4599  CellStyleNameMap::const_iterator iter = rMap.find(rName);
4600  return iter != rMap.end();
4601 }
4602 
4603 //XNameContainer
4604 void SAL_CALL SwXTextTableStyle::insertByName(const OUString& /*Name*/, const uno::Any& /*Element*/)
4605 {
4606  SAL_WARN("sw.uno", "not implemented");
4607 }
4608 
4609 void SAL_CALL SwXTextTableStyle::replaceByName(const OUString& rName, const uno::Any& rElement)
4610 {
4611  SolarMutexGuard aGuard;
4612  const CellStyleNameMap& rMap = GetCellStyleNameMap();
4613  CellStyleNameMap::const_iterator iter = rMap.find(rName);
4614  if(iter == rMap.end())
4615  throw container::NoSuchElementException();
4616  const sal_Int32 nCellStyle = iter->second;
4617 
4618  uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
4619  if (!xStyle.is())
4620  throw lang::IllegalArgumentException();
4621 
4622  SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
4623  if (!pStyleToReplaceWith)
4624  throw lang::IllegalArgumentException();
4625 
4626  // replace only with physical ...
4627  if (!pStyleToReplaceWith->IsPhysical())
4628  throw lang::IllegalArgumentException();
4629 
4630  const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
4631  const sal_Int32 nBoxFormat = rTableTemplateMap[nCellStyle];
4632 
4633  // move SwBoxAutoFormat to dest. SwTableAutoFormat
4634  m_pTableAutoFormat->SetBoxFormat(*pStyleToReplaceWith->GetBoxFormat(), nBoxFormat);
4635  // remove unassigned SwBoxAutoFormat, which is not anymore in use anyways
4636  m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(xStyle->getName());
4637  // make SwXTextCellStyle use new, moved SwBoxAutoFormat
4638  pStyleToReplaceWith->SetBoxFormat(&m_pTableAutoFormat->GetBoxFormat(nBoxFormat));
4639  m_pTableAutoFormat->GetBoxFormat(nBoxFormat).SetXObject(xStyle);
4640  // make this SwXTextTableStyle use new SwXTextCellStyle
4641  m_aCellStyles[nCellStyle] = xStyle;
4642 }
4643 
4644 void SAL_CALL SwXTextTableStyle::removeByName(const OUString& /*Name*/)
4645 {
4646  SAL_WARN("sw.uno", "not implemented");
4647 }
4648 
4649 //XElementAccess
4651 {
4653 }
4654 
4656 {
4657  return true;
4658 }
4659 
4660 //XServiceInfo
4662 {
4663  return {"SwXTextTableStyle"};
4664 }
4665 
4666 sal_Bool SAL_CALL SwXTextTableStyle::supportsService(const OUString& rServiceName)
4667 {
4668  return cppu::supportsService(this, rServiceName);
4669 }
4670 
4671 css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getSupportedServiceNames()
4672 {
4673  return {"com.sun.star.style.Style"};
4674 }
4675 
4676 // SwXTextCellStyle
4677 SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, const OUString& sParentStyle) :
4678  m_pDocShell(pDocShell),
4679  m_pBoxAutoFormat(pBoxAutoFormat),
4680  m_sParentStyle(sParentStyle),
4681  m_bPhysical(true)
4682 { }
4683 
4684 SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, const OUString& sName) :
4685  m_pDocShell(pDocShell),
4686  m_pBoxAutoFormat_Impl(std::make_shared<SwBoxAutoFormat>()),
4687  m_sName(sName),
4688  m_bPhysical(false)
4689 {
4691 }
4692 
4694 {
4695  return m_pBoxAutoFormat;
4696 }
4697 
4699 {
4700  if (m_bPhysical)
4701  m_pBoxAutoFormat = pBoxFormat;
4702  else
4703  SAL_INFO("sw.uno", "trying to call SwXTextCellStyle::SetBoxFormat on non physical style");
4704 }
4705 
4707 {
4708  if (!m_bPhysical)
4709  {
4710  SwBoxAutoFormat* pBoxAutoFormat = GetBoxAutoFormat(m_pDocShell, m_sName, &m_sParentStyle);
4711  if (pBoxAutoFormat)
4712  {
4713  m_bPhysical = true;
4714  m_pBoxAutoFormat_Impl = nullptr;
4715  m_pBoxAutoFormat = pBoxAutoFormat;
4716  m_pBoxAutoFormat->SetXObject(uno::Reference<style::XStyle>(this));
4717  }
4718  else
4719  SAL_WARN("sw.uno", "setting style physical, but SwBoxAutoFormat in document not found");
4720  }
4721  else
4722  SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextCellStyle");
4723 }
4724 
4726 {
4727  return m_bPhysical;
4728 }
4729 
4730 SwBoxAutoFormat* SwXTextCellStyle::GetBoxAutoFormat(SwDocShell* pDocShell, std::u16string_view sName, OUString* pParentName)
4731 {
4732  if (sName.empty())
4733  return nullptr;
4734 
4735  SwBoxAutoFormat* pBoxAutoFormat = pDocShell->GetDoc()->GetCellStyles().GetBoxFormat(sName);
4736  if (!pBoxAutoFormat)
4737  {
4738  sal_Int32 nTemplateIndex;
4739  OUString sParentName;
4740  std::u16string_view sCellSubName;
4741 
4742  size_t nSeparatorIndex = sName.rfind('.');
4743  if (nSeparatorIndex == std::u16string_view::npos)
4744  return nullptr;
4745 
4746  sParentName = sName.substr(0, nSeparatorIndex);
4747  sCellSubName = sName.substr(nSeparatorIndex+1);
4748  nTemplateIndex = o3tl::toInt32(sCellSubName)-1; // -1 because cell styles names start from 1, but internally are indexed from 0
4749  if (0 > nTemplateIndex)
4750  return nullptr;
4751 
4752  const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
4753  if (rTableTemplateMap.size() <= o3tl::make_unsigned(nTemplateIndex))
4754  return nullptr;
4755 
4757  SwTableAutoFormat* pTableAutoFormat = pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentName);
4758  if (!pTableAutoFormat)
4759  return nullptr;
4760 
4761  if (pParentName)
4762  *pParentName = sParentName;
4763  sal_uInt32 nBoxIndex = rTableTemplateMap[nTemplateIndex];
4764  pBoxAutoFormat = &pTableAutoFormat->GetBoxFormat(nBoxIndex);
4765  }
4766 
4767  return pBoxAutoFormat;
4768 }
4769 
4770 css::uno::Reference<css::style::XStyle> SwXTextCellStyle::CreateXTextCellStyle(SwDocShell* pDocShell, const OUString& sName)
4771 {
4772  uno::Reference<style::XStyle> xTextCellStyle;
4773 
4774  if (!sName.isEmpty()) // create a cell style for a physical box
4775  {
4776  OUString sParentName;
4777  SwBoxAutoFormat* pBoxFormat = GetBoxAutoFormat(pDocShell, sName, &sParentName);
4778 
4779  // something went wrong but we don't want a crash
4780  if (!pBoxFormat)
4781  {
4782  // return a default-dummy style to prevent crash
4783  static SwBoxAutoFormat aDefaultBoxFormat;
4784  pBoxFormat = &aDefaultBoxFormat;
4785  }
4786 
4787  xTextCellStyle.set(pBoxFormat->GetXObject(), uno::UNO_QUERY);
4788  if (!xTextCellStyle.is())
4789  {
4790  xTextCellStyle.set(new SwXTextCellStyle(pDocShell, pBoxFormat, sParentName));
4791  pBoxFormat->SetXObject(xTextCellStyle);
4792  }
4793  }
4794  else // create a non physical style
4795  xTextCellStyle.set(new SwXTextCellStyle(pDocShell, sName));
4796 
4797  return xTextCellStyle;
4798 }
4799 
4800 // XStyle
4802 {
4803  SolarMutexGuard aGuard;
4804  // if this cell belong to first table style then its default style
4805  if (&m_pDocShell->GetDoc()->GetTableStyles()[0] == m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(m_sParentStyle))
4806  return false;
4807 
4808  return true;
4809 }
4810 
4812 {
4813  SolarMutexGuard aGuard;
4814  uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY);
4815  if (!xFamiliesSupplier.is())
4816  return false;
4817 
4818  uno::Reference<container::XNameAccess> xFamilies = xFamiliesSupplier->getStyleFamilies();
4819  if (!xFamilies.is())
4820  return false;
4821 
4822  uno::Reference<container::XNameAccess> xTableStyles;
4823  xFamilies->getByName("TableStyles") >>= xTableStyles;
4824  if (!xTableStyles.is())
4825  return false;
4826 
4827  uno::Reference<style::XStyle> xStyle;
4828  xTableStyles->getByName(m_sParentStyle) >>= xStyle;
4829  if (!xStyle.is())
4830  return false;
4831 
4832  return xStyle->isInUse();
4833 }
4834 
4836 {
4837  // Do not return name of the parent (which is a table style) because the parent should be a cell style.
4838  return OUString();
4839 }
4840 
4841 void SAL_CALL SwXTextCellStyle::setParentStyle(const OUString& /*sParentStyle*/)
4842 {
4843  SolarMutexGuard aGuard;
4844  // Changing parent to one which is unaware of it will lead to a something unexpected. getName() rely on a parent.
4845  SAL_INFO("sw.uno", "Changing SwXTextCellStyle parent");
4846 }
4847 
4848 //XNamed
4849 OUString SAL_CALL SwXTextCellStyle::getName()
4850 {
4851  SolarMutexGuard aGuard;
4852  OUString sName;
4853 
4854  // if style is physical then we request a name from doc
4855  if (m_bPhysical)
4856  {
4857  SwTableAutoFormat* pTableFormat = m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(m_sParentStyle);
4858  if (!pTableFormat)
4859  {
4860  // if auto format is not found as a child of table formats, look in SwDoc cellstyles
4861  sName = m_pDocShell->GetDoc()->GetCellStyles().GetBoxFormatName(*m_pBoxAutoFormat);
4862  }
4863  else
4864  {
4865  OUString sParentStyle;
4867  sName = sParentStyle + pTableFormat->GetTableTemplateCellSubName(*m_pBoxAutoFormat);
4868  }
4869  }
4870  else
4871  sName = m_sName;
4872 
4873  return sName;
4874 }
4875 
4876 void SAL_CALL SwXTextCellStyle::setName(const OUString& sName)
4877 {
4878  SolarMutexGuard aGuard;
4879  // if style is physical then we can not rename it.
4880  if (!m_bPhysical)
4881  m_sName = sName;
4882  // change name if style is unassigned (name is not generated automatically)
4883  m_pDocShell->GetDoc()->GetCellStyles().ChangeBoxFormatName(getName(), sName);
4884 }
4885 
4886 //XPropertySet
4887 css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextCellStyle::getPropertySetInfo()
4888 {
4889  static uno::Reference<beans::XPropertySetInfo> xRef(aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertySetInfo());
4890  return xRef;
4891 }
4892 
4893 void SAL_CALL SwXTextCellStyle::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& aValue)
4894 {
4895  SolarMutexGuard aGuard;
4896  const SfxItemPropertyMapEntry *const pEntry = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertyMap().getByName(rPropertyName);
4897  if(pEntry)
4898  {
4899  switch(pEntry->nWID)
4900  {
4901  case RES_BACKGROUND:
4902  {
4904  rBrush.PutValue(aValue, 0);
4906  return;
4907  }
4908  case RES_BOX:
4909  {
4911  rBox.PutValue(aValue, pEntry->nMemberId);
4912  m_pBoxAutoFormat->SetBox(rBox);
4913  return;
4914  }
4915  case RES_VERT_ORIENT:
4916  {
4918  rVertOrient.PutValue(aValue, pEntry->nMemberId);
4919  m_pBoxAutoFormat->SetVerticalAlignment(rVertOrient);
4920  return;
4921  }
4922  case RES_FRAMEDIR:
4923  {
4925  rDirItem.PutValue(aValue, pEntry->nMemberId);
4927  return;
4928  }
4929  case RES_BOXATR_FORMAT:
4930  {
4931  sal_uInt32 nKey;
4932  if (aValue >>= nKey)
4933  {
4934  // FIXME: It's not working for old "automatic" currency formats, which are still in use by autotbl.fmt.
4935  // Scenario:
4936  // 1) Mark all styles present by default in autotbl.fmt as default.
4937  // 2) convert all currencies present in autotbl.fmt before calling this code
4938  const SvNumberformat* pNumFormat = m_pDocShell->GetDoc()->GetNumberFormatter()->GetEntry(nKey);
4939  if (pNumFormat)
4940  m_pBoxAutoFormat->SetValueFormat(pNumFormat->GetFormatstring(), pNumFormat->GetLanguage(), GetAppLanguage());
4941  }
4942  return;
4943  }
4944  // Paragraph attributes
4945  case RES_PARATR_ADJUST:
4946  {
4947  SvxAdjustItem rAdjustItem = m_pBoxAutoFormat->GetAdjust();
4948  rAdjustItem.PutValue(aValue, pEntry->nMemberId);
4949  m_pBoxAutoFormat->SetAdjust(rAdjustItem);
4950  return;
4951  }
4952  case RES_CHRATR_COLOR:
4953  {
4954  SvxColorItem rColorItem = m_pBoxAutoFormat->GetColor();
4955  rColorItem.PutValue(aValue, pEntry->nMemberId);
4956  m_pBoxAutoFormat->SetColor(rColorItem);
4957  return;
4958  }
4959  case RES_CHRATR_SHADOWED:
4960  {
4961  SvxShadowedItem rShadowedItem = m_pBoxAutoFormat->GetShadowed();
4962  bool bValue = false; aValue >>= bValue;
4963  rShadowedItem.SetValue(bValue);
4964  m_pBoxAutoFormat->SetShadowed(rShadowedItem);
4965  return;
4966  }
4967  case RES_CHRATR_CONTOUR:
4968  {
4969  SvxContourItem rContourItem = m_pBoxAutoFormat->GetContour();
4970  bool bValue = false; aValue >>= bValue;
4971  rContourItem.SetValue(bValue);
4972  m_pBoxAutoFormat->SetContour(rContourItem);
4973  return;
4974  }
4975  case RES_CHRATR_CROSSEDOUT:
4976  {
4977  SvxCrossedOutItem rCrossedOutItem = m_pBoxAutoFormat->GetCrossedOut();
4978  rCrossedOutItem.PutValue(aValue, pEntry->nMemberId);
4979  m_pBoxAutoFormat->SetCrossedOut(rCrossedOutItem);
4980  return;
4981  }
4982  case RES_CHRATR_UNDERLINE:
4983  {
4984  SvxUnderlineItem rUnderlineItem = m_pBoxAutoFormat->GetUnderline();
4985  rUnderlineItem.PutValue(aValue, pEntry->nMemberId);
4986  m_pBoxAutoFormat->SetUnderline(rUnderlineItem);
4987  return;
4988  }
4989  case RES_CHRATR_FONTSIZE:
4990  {
4991  SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetHeight();
4992  rFontHeightItem.PutValue(aValue, pEntry->