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