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