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