1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/beans/PropertyAttribute.hpp>
21 #include <com/sun/star/lang/DisposedException.hpp>
22 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
23 #include <com/sun/star/style/XStyle.hpp>
24 #include <com/sun/star/table/BorderLine.hpp>
26 #include <osl/mutex.hxx>
27 #include <vcl/svapp.hxx>
28 #include <cppuhelper/exc_hlp.hxx>
29 #include <cppuhelper/supportsservice.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <editeng/fhgtitem.hxx>
33 #include <editeng/ulspitem.hxx>
34 #include <svl/hint.hxx>
35 #include <svl/itemset.hxx>
37 #include <svx/xflbmtit.hxx>
38 #include <svx/xflbstit.hxx>
39 #include <editeng/bulletitem.hxx>
40 #include <editeng/lrspitem.hxx>
41 #include <svx/unoshprp.hxx>
42 #include <svx/unoshape.hxx>
43 #include <svx/svdpool.hxx>
44 #include <svx/sdtaaitm.hxx>
45 #include <svx/sdtacitm.hxx>
46 #include <svx/sdtayitm.hxx>
47 #include <svx/sdtaiitm.hxx>
48 #include <svx/xit.hxx>
49 #include <tools/diagnose_ex.h>
50 #include <stlsheet.hxx>
51 #include <sdresid.hxx>
53 #include <drawdoc.hxx>
54 #include <stlpool.hxx>
55 #include <strings.hrc>
57 #include <strings.hxx>
59 #include <DrawViewShell.hxx>
60 #include <ViewShellBase.hxx>
64 #include <string_view>
66 using ::osl::MutexGuard
;
67 using ::osl::ClearableMutexGuard
;
68 using ::com::sun::star::table::BorderLine
;
69 using namespace ::com::sun::star::uno
;
70 using namespace ::com::sun::star::util
;
71 using namespace ::com::sun::star::lang
;
72 using namespace ::com::sun::star::style
;
73 using namespace ::com::sun::star::beans
;
74 using namespace ::com::sun::star::container
;
75 using namespace ::com::sun::star::drawing
;
77 #define WID_STYLE_HIDDEN 7997
78 #define WID_STYLE_DISPNAME 7998
79 #define WID_STYLE_FAMILY 7999
81 static SvxItemPropertySet
& GetStylePropertySet()
83 static const SfxItemPropertyMapEntry aFullPropertyMap_Impl
[] =
85 { u
"Family", WID_STYLE_FAMILY
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::READONLY
, 0},
86 { u
"UserDefinedAttributes", SDRATTR_XMLATTRIBUTES
, cppu::UnoType
<XNameContainer
>::get(), 0, 0},
87 { u
"DisplayName", WID_STYLE_DISPNAME
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::READONLY
, 0},
88 { u
"Hidden", WID_STYLE_HIDDEN
, cppu::UnoType
<bool>::get(), 0, 0},
90 SVX_UNOEDIT_NUMBERING_PROPERTIE
,
93 LINE_PROPERTIES_START_END
96 TEXT_PROPERTIES_DEFAULTS
98 SPECIAL_DIMENSIONING_PROPERTIES_DEFAULTS
99 { u
"TopBorder", SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, TOP_BORDER
},
100 { u
"BottomBorder", SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, BOTTOM_BORDER
},
101 { u
"LeftBorder", SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, LEFT_BORDER
},
102 { u
"RightBorder", SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, RIGHT_BORDER
},
103 { u
"", 0, css::uno::Type(), 0, 0 }
106 static SvxItemPropertySet
aPropSet( aFullPropertyMap_Impl
, SdrObject::GetGlobalDrawObjectItemPool() );
110 class ModifyListenerForwarder
: public SfxListener
113 explicit ModifyListenerForwarder( SdStyleSheet
* pStyleSheet
);
115 virtual void Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
118 SdStyleSheet
* mpStyleSheet
;
121 ModifyListenerForwarder::ModifyListenerForwarder( SdStyleSheet
* pStyleSheet
)
122 : mpStyleSheet( pStyleSheet
)
126 SfxBroadcaster
& rBC
= static_cast< SfxBroadcaster
& >( *pStyleSheet
);
127 StartListening( rBC
);
131 void ModifyListenerForwarder::Notify(SfxBroadcaster
& /*rBC*/, const SfxHint
& /*rHint*/)
134 mpStyleSheet
->notifyModifyListener();
137 SdStyleSheet::SdStyleSheet(const OUString
& rDisplayName
, SfxStyleSheetBasePool
& _rPool
, SfxStyleFamily eFamily
, SfxStyleSearchBits _nMask
)
138 : SdStyleSheetBase( rDisplayName
, _rPool
, eFamily
, _nMask
)
139 , ::cppu::BaseMutex()
140 , msApiName( rDisplayName
)
142 , mrBHelper( m_aMutex
)
146 SdStyleSheet::~SdStyleSheet()
149 pSet
= nullptr; // that following destructors also get a change
152 void SdStyleSheet::SetApiName( const OUString
& rApiName
)
154 msApiName
= rApiName
;
157 OUString
const & SdStyleSheet::GetApiName() const
159 if( !msApiName
.isEmpty() )
165 bool SdStyleSheet::SetParent(const OUString
& rParentName
)
167 bool bResult
= false;
169 if (SfxStyleSheet::SetParent(rParentName
))
171 // PseudoStyleSheets do not have their own ItemSets
172 if (nFamily
!= SfxStyleFamily::Pseudo
)
174 if( !rParentName
.isEmpty() )
176 SfxStyleSheetBase
* pStyle
= m_pPool
->Find(rParentName
, nFamily
);
180 SfxItemSet
& rParentSet
= pStyle
->GetItemSet();
181 GetItemSet().SetParent(&rParentSet
);
182 Broadcast( SfxHint( SfxHintId::DataChanged
) );
188 GetItemSet().SetParent(nullptr);
189 Broadcast( SfxHint( SfxHintId::DataChanged
) );
201 * create if necessary and return ItemSets
203 SfxItemSet
& SdStyleSheet::GetItemSet()
205 if (nFamily
== SfxStyleFamily::Para
|| nFamily
== SfxStyleFamily::Page
)
207 // we create the ItemSet 'on demand' if necessary
210 pSet
= new SfxItemSet(
211 GetPool()->GetPool(),
213 XATTR_LINE_FIRST
, XATTR_LINE_LAST
,
214 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
215 SDRATTR_SHADOW_FIRST
, SDRATTR_SHADOW_LAST
,
216 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_TEXT_WORDWRAP
,
217 SDRATTR_EDGE_FIRST
, SDRATTR_MEASURE_LAST
,
218 SDRATTR_3D_FIRST
, SDRATTR_3D_LAST
,
219 EE_PARA_START
, EE_CHAR_END
>{});
226 else if( nFamily
== SfxStyleFamily::Frame
)
230 pSet
= new SfxItemSet(
231 GetPool()->GetPool(),
233 XATTR_LINE_FIRST
, XATTR_LINE_LAST
,
234 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
235 SDRATTR_SHADOW_FIRST
, SDRATTR_SHADOW_LAST
,
236 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_XMLATTRIBUTES
,
237 SDRATTR_TEXT_WORDWRAP
, SDRATTR_TEXT_WORDWRAP
,
238 SDRATTR_TABLE_FIRST
, SDRATTR_TABLE_LAST
,
239 EE_PARA_START
, EE_CHAR_END
>{});
246 // this is a dummy template for the internal template of the
247 // current presentation layout; return the ItemSet of that template
251 SdStyleSheet
* pSdSheet
= GetRealStyleSheet();
255 return pSdSheet
->GetItemSet();
261 pSet
= new SfxItemSet(
262 GetPool()->GetPool(),
264 XATTR_LINE_FIRST
, XATTR_LINE_LAST
,
265 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
266 SDRATTR_SHADOW_FIRST
, SDRATTR_SHADOW_LAST
,
267 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_TEXT_WORDWRAP
,
268 SDRATTR_EDGE_FIRST
, SDRATTR_MEASURE_LAST
,
269 SDRATTR_3D_FIRST
, SDRATTR_3D_LAST
,
270 EE_PARA_START
, EE_CHAR_END
>{});
280 * A template is used when it is referenced by inserted object or by a used
283 bool SdStyleSheet::IsUsed() const
285 bool bResult
= false;
287 const size_t nListenerCount
= GetSizeOfVector();
288 for (size_t n
= 0; n
< nListenerCount
; ++n
)
290 SfxListener
* pListener
= GetListener(n
);
291 if( pListener
== this )
294 const svl::StyleSheetUser
* const pUser(dynamic_cast<svl::StyleSheetUser
*>(pListener
));
296 bResult
= pUser
->isUsedByModel();
303 MutexGuard
aGuard( mrBHelper
.rMutex
);
305 cppu::OInterfaceContainerHelper
* pContainer
= mrBHelper
.getContainer( cppu::UnoType
<XModifyListener
>::get() );
308 Sequence
< Reference
< XInterface
> > aModifyListeners( pContainer
->getElements() );
309 bResult
= std::any_of(aModifyListeners
.begin(), aModifyListeners
.end(),
310 [](const Reference
<XInterface
>& rListener
) {
311 Reference
< XStyle
> xStyle( rListener
, UNO_QUERY
);
312 return xStyle
.is() && xStyle
->isInUse();
320 * Determine the style sheet for which this dummy is for.
322 SdStyleSheet
* SdStyleSheet::GetRealStyleSheet() const
325 OUString
aSep( SD_LT_SEPARATOR
);
326 SdStyleSheet
* pRealStyle
= nullptr;
327 SdDrawDocument
* pDoc
= static_cast<SdStyleSheetPool
*>(m_pPool
)->GetDoc();
329 ::sd::DrawViewShell
* pDrawViewShell
= nullptr;
331 ::sd::ViewShellBase
* pBase
= dynamic_cast< ::sd::ViewShellBase
* >( SfxViewShell::Current() );
333 pDrawViewShell
= dynamic_cast< ::sd::DrawViewShell
* >( pBase
->GetMainViewShell().get() );
335 if (pDrawViewShell
&& pDrawViewShell
->GetDoc() == pDoc
)
337 SdPage
* pPage
= pDrawViewShell
->getCurrentPage();
340 aRealStyle
= pPage
->GetLayoutName();
341 // cut after separator string
343 if( aRealStyle
.indexOf(aSep
) >= 0)
345 aRealStyle
= aRealStyle
.copy(0,(aRealStyle
.indexOf(aSep
) + aSep
.getLength()));
349 if (aRealStyle
.isEmpty())
351 SdPage
* pPage
= pDoc
->GetSdPage(0, PageKind::Standard
);
355 aRealStyle
= pDoc
->GetSdPage(0, PageKind::Standard
)->GetLayoutName();
359 /* no page available yet. This can happen when actualizing the
360 document templates. */
361 SfxStyleSheetIterator
aIter(m_pPool
, SfxStyleFamily::Page
);
362 SfxStyleSheetBase
* pSheet
= aIter
.First();
364 aRealStyle
= pSheet
->GetName();
367 if( aRealStyle
.indexOf(aSep
) >= 0)
369 aRealStyle
= aRealStyle
.copy(0,(aRealStyle
.indexOf(aSep
) + aSep
.getLength()));
373 /* now map from the name (specified for country language) to the internal
374 name (independent of the country language) */
375 OUString aInternalName
;
376 OUString
aStyleName(aName
);
378 if (aStyleName
== SdResId(STR_PSEUDOSHEET_TITLE
))
380 aInternalName
= STR_LAYOUT_TITLE
;
382 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_SUBTITLE
))
384 aInternalName
= STR_LAYOUT_SUBTITLE
;
386 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_BACKGROUND
))
388 aInternalName
= STR_LAYOUT_BACKGROUND
;
390 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS
))
392 aInternalName
= STR_LAYOUT_BACKGROUNDOBJECTS
;
394 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_NOTES
))
396 aInternalName
= STR_LAYOUT_NOTES
;
400 OUString
aOutlineStr(SdResId(STR_PSEUDOSHEET_OUTLINE
));
401 sal_Int32 nPos
= aStyleName
.indexOf(aOutlineStr
);
404 OUString
aNumStr(aStyleName
.copy(aOutlineStr
.getLength()));
405 aInternalName
= STR_LAYOUT_OUTLINE
+ aNumStr
;
409 aRealStyle
+= aInternalName
;
410 pRealStyle
= static_cast< SdStyleSheet
* >( m_pPool
->Find(aRealStyle
, SfxStyleFamily::Page
) );
415 SfxStyleSheetIterator
aIter(m_pPool
, SfxStyleFamily::Page
);
416 if( aIter
.Count() > 0 )
417 // StyleSheet not found, but pool already loaded
418 DBG_ASSERT(pRealStyle
, "Internal StyleSheet not found");
426 * Determine pseudo style sheet which stands for this style sheet.
428 SdStyleSheet
* SdStyleSheet::GetPseudoStyleSheet() const
430 SdStyleSheet
* pPseudoStyle
= nullptr;
431 OUString
aSep( SD_LT_SEPARATOR
);
432 OUString
aStyleName(aName
);
433 // without layout name and separator
435 if( aStyleName
.indexOf(aSep
) >=0 )
437 aStyleName
= aStyleName
.copy (aStyleName
.indexOf(aSep
) + aSep
.getLength());
440 if (aStyleName
== STR_LAYOUT_TITLE
)
442 aStyleName
= SdResId(STR_PSEUDOSHEET_TITLE
);
444 else if (aStyleName
== STR_LAYOUT_SUBTITLE
)
446 aStyleName
= SdResId(STR_PSEUDOSHEET_SUBTITLE
);
448 else if (aStyleName
== STR_LAYOUT_BACKGROUND
)
450 aStyleName
= SdResId(STR_PSEUDOSHEET_BACKGROUND
);
452 else if (aStyleName
== STR_LAYOUT_BACKGROUNDOBJECTS
)
454 aStyleName
= SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS
);
456 else if (aStyleName
== STR_LAYOUT_NOTES
)
458 aStyleName
= SdResId(STR_PSEUDOSHEET_NOTES
);
462 OUString
aOutlineStr(STR_LAYOUT_OUTLINE
);
463 sal_Int32 nPos
= aStyleName
.indexOf(aOutlineStr
);
466 OUString
aNumStr(aStyleName
.copy(aOutlineStr
.getLength()));
467 aStyleName
= SdResId(STR_PSEUDOSHEET_OUTLINE
) + aNumStr
;
471 pPseudoStyle
= static_cast<SdStyleSheet
*>(m_pPool
->Find(aStyleName
, SfxStyleFamily::Pseudo
));
472 DBG_ASSERT(pPseudoStyle
, "PseudoStyleSheet missing");
477 void SdStyleSheet::Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
479 // first, base class functionality
480 SfxStyleSheet::Notify(rBC
, rHint
);
482 if (nFamily
!= SfxStyleFamily::Pseudo
)
485 /* if the dummy gets a notify about a changed attribute, he takes care that
486 the actual meant style sheet sends broadcasts. */
487 if (rHint
.GetId() == SfxHintId::DataChanged
)
489 SdStyleSheet
* pRealStyle
= GetRealStyleSheet();
491 pRealStyle
->Broadcast(rHint
);
496 * Adjust the bullet width and the left text indent of the provided ItemSets to
497 * their font height. The new values are calculated that the ratio to the font
498 * height is as in the style sheet.
500 * @param bOnlyMissingItems If sal_True, only not set items are completed. With
501 * sal_False, are items are overwritten.
503 void SdStyleSheet::AdjustToFontHeight(SfxItemSet
& rSet
, bool bOnlyMissingItems
)
505 /* If not explicit set, adjust bullet width and text indent to new font
507 SfxStyleFamily eFamily
= nFamily
;
508 OUString
aStyleName(aName
);
509 if (eFamily
== SfxStyleFamily::Pseudo
)
511 SfxStyleSheet
* pRealStyle
= GetRealStyleSheet();
512 eFamily
= pRealStyle
->GetFamily();
513 aStyleName
= pRealStyle
->GetName();
516 if (!(eFamily
== SfxStyleFamily::Page
&&
517 aStyleName
.indexOf(STR_LAYOUT_OUTLINE
) != -1 &&
518 rSet
.GetItemState(EE_CHAR_FONTHEIGHT
) == SfxItemState::SET
))
521 const SfxItemSet
* pCurSet
= &GetItemSet();
522 sal_uInt32 nNewHeight
= rSet
.Get(EE_CHAR_FONTHEIGHT
).GetHeight();
523 sal_uInt32 nOldHeight
= pCurSet
->Get(EE_CHAR_FONTHEIGHT
).GetHeight();
525 if (rSet
.GetItemState(EE_PARA_BULLET
) != SfxItemState::SET
|| !bOnlyMissingItems
)
527 const SvxBulletItem
& rBItem
= pCurSet
->Get(EE_PARA_BULLET
);
528 double fBulletFraction
= double(rBItem
.GetWidth()) / nOldHeight
;
529 SvxBulletItem
aNewBItem(rBItem
);
530 aNewBItem
.SetWidth(static_cast<sal_uInt32
>(fBulletFraction
* nNewHeight
));
534 if (rSet
.GetItemState(EE_PARA_LRSPACE
) != SfxItemState::SET
|| !bOnlyMissingItems
)
536 const SvxLRSpaceItem
& rLRItem
= pCurSet
->Get(EE_PARA_LRSPACE
);
537 double fIndentFraction
= double(rLRItem
.GetTextLeft()) / nOldHeight
;
538 SvxLRSpaceItem
aNewLRItem(rLRItem
);
539 aNewLRItem
.SetTextLeft(fIndentFraction
* nNewHeight
);
540 double fFirstIndentFraction
= double(rLRItem
.GetTextFirstLineOffset()) / nOldHeight
;
541 aNewLRItem
.SetTextFirstLineOffset(static_cast<short>(fFirstIndentFraction
* nNewHeight
));
542 rSet
.Put(aNewLRItem
);
545 if (rSet
.GetItemState(EE_PARA_ULSPACE
) != SfxItemState::SET
|| !bOnlyMissingItems
)
547 const SvxULSpaceItem
& rULItem
= pCurSet
->Get(EE_PARA_ULSPACE
);
548 SvxULSpaceItem
aNewULItem(rULItem
);
549 double fLowerFraction
= double(rULItem
.GetLower()) / nOldHeight
;
550 aNewULItem
.SetLower(static_cast<sal_uInt16
>(fLowerFraction
* nNewHeight
));
551 double fUpperFraction
= double(rULItem
.GetUpper()) / nOldHeight
;
552 aNewULItem
.SetUpper(static_cast<sal_uInt16
>(fUpperFraction
* nNewHeight
));
553 rSet
.Put(aNewULItem
);
557 bool SdStyleSheet::HasFollowSupport() const
562 bool SdStyleSheet::HasParentSupport() const
567 bool SdStyleSheet::HasClearParentSupport() const
576 std::u16string_view mpApiName
;
578 } const pApiNameMap
[]
579 = { { std::u16string_view(u
"title"), HID_PSEUDOSHEET_TITLE
},
580 { std::u16string_view(u
"subtitle"), HID_PSEUDOSHEET_SUBTITLE
},
581 { std::u16string_view(u
"background"), HID_PSEUDOSHEET_BACKGROUND
},
582 { std::u16string_view(u
"backgroundobjects"), HID_PSEUDOSHEET_BACKGROUNDOBJECTS
},
583 { std::u16string_view(u
"notes"), HID_PSEUDOSHEET_NOTES
},
584 { std::u16string_view(u
"standard"), HID_STANDARD_STYLESHEET_NAME
},
585 { std::u16string_view(u
"objectwithoutfill"), HID_POOLSHEET_OBJWITHOUTFILL
},
587 { std::u16string_view(u
"Text"), HID_POOLSHEET_TEXT
},
588 { std::u16string_view(u
"A4"), HID_POOLSHEET_A4
},
589 { std::u16string_view(u
"Title A4"), HID_POOLSHEET_A4_TITLE
},
590 { std::u16string_view(u
"Heading A4"), HID_POOLSHEET_A4_HEADLINE
},
591 { std::u16string_view(u
"Text A4"), HID_POOLSHEET_A4_TEXT
},
592 { std::u16string_view(u
"A4"), HID_POOLSHEET_A0
},
593 { std::u16string_view(u
"Title A0"), HID_POOLSHEET_A0_TITLE
},
594 { std::u16string_view(u
"Heading A0"), HID_POOLSHEET_A0_HEADLINE
},
595 { std::u16string_view(u
"Text A0"), HID_POOLSHEET_A0_TEXT
},
597 { std::u16string_view(u
"Graphic"), HID_POOLSHEET_GRAPHIC
},
598 { std::u16string_view(u
"Shapes"), HID_POOLSHEET_SHAPES
},
599 { std::u16string_view(u
"Filled"), HID_POOLSHEET_FILLED
},
600 { std::u16string_view(u
"Filled Blue"), HID_POOLSHEET_FILLED_BLUE
},
601 { std::u16string_view(u
"Filled Green"), HID_POOLSHEET_FILLED_GREEN
},
602 { std::u16string_view(u
"Filled Red"), HID_POOLSHEET_FILLED_RED
},
603 { std::u16string_view(u
"Filled Yellow"), HID_POOLSHEET_FILLED_YELLOW
},
604 { std::u16string_view(u
"Outlined"), HID_POOLSHEET_OUTLINE
},
605 { std::u16string_view(u
"Outlined Blue"), HID_POOLSHEET_OUTLINE_BLUE
},
606 { std::u16string_view(u
"Outlined Green"), HID_POOLSHEET_OUTLINE_GREEN
},
607 { std::u16string_view(u
"Outlined Red"), HID_POOLSHEET_OUTLINE_RED
},
608 { std::u16string_view(u
"Outlined Yellow"), HID_POOLSHEET_OUTLINE_YELLOW
},
609 { std::u16string_view(u
"Lines"), HID_POOLSHEET_LINES
},
610 { std::u16string_view(u
"Arrow Line"), HID_POOLSHEET_MEASURE
},
611 { std::u16string_view(u
"Arrow Dashed"), HID_POOLSHEET_LINES_DASHED
}
614 OUString
GetApiNameForHelpId(sal_uLong nId
)
616 if ((nId
>= HID_PSEUDOSHEET_OUTLINE1
) && (nId
<= HID_PSEUDOSHEET_OUTLINE9
))
617 return "outline" + OUStringChar(sal_Unicode('1' + (nId
- HID_PSEUDOSHEET_OUTLINE1
)));
619 for (const auto& i
: pApiNameMap
)
620 if (nId
== i
.mnHelpId
)
626 sal_uInt32
GetHelpIdForApiName(const OUString
& sName
)
629 if (sName
.startsWith("outline", &sRest
))
631 if (sRest
.getLength() == 1)
633 sal_Unicode ch
= sRest
.toChar();
634 if ('1' <= ch
&& ch
<= '9')
635 return HID_PSEUDOSHEET_OUTLINE1
+ ch
- '1';
637 // No other pre-defined names start with "outline"
641 for (const auto& i
: pApiNameMap
)
642 if (sName
== i
.mpApiName
)
649 void SdStyleSheet::SetHelpId( const OUString
& r
, sal_uLong nId
)
651 SfxStyleSheet::SetHelpId( r
, nId
);
653 const OUString sNewApiName
= GetApiNameForHelpId(nId
);
654 if (!sNewApiName
.isEmpty())
655 msApiName
= sNewApiName
;
658 OUString
SdStyleSheet::GetFamilyString( SfxStyleFamily eFamily
)
662 case SfxStyleFamily::Frame
:
665 OSL_FAIL( "SdStyleSheet::GetFamilyString(), illegal family!" );
667 case SfxStyleFamily::Para
:
672 void SdStyleSheet::throwIfDisposed()
675 throw DisposedException();
678 SdStyleSheet
* SdStyleSheet::CreateEmptyUserStyle( SfxStyleSheetBasePool
& rPool
, SfxStyleFamily eFamily
)
681 sal_Int32 nIndex
= 1;
684 aName
= "user" + OUString::number( nIndex
++ );
686 while( rPool
.Find( aName
, eFamily
) != nullptr );
688 return new SdStyleSheet(aName
, rPool
, eFamily
, SfxStyleSearchBits::UserDefined
);
693 void SAL_CALL
SdStyleSheet::release( ) throw ()
695 if (osl_atomic_decrement( &m_refCount
) != 0)
698 // restore reference count:
699 osl_atomic_increment( &m_refCount
);
700 if (! mrBHelper
.bDisposed
) try
704 catch (RuntimeException
const&)
706 // don't break throw ()
707 TOOLS_WARN_EXCEPTION( "sd", "" );
709 OSL_ASSERT( mrBHelper
.bDisposed
);
710 SdStyleSheetBase::release();
715 void SAL_CALL
SdStyleSheet::dispose( )
718 MutexGuard
aGuard(mrBHelper
.rMutex
);
719 if (mrBHelper
.bDisposed
|| mrBHelper
.bInDispose
)
722 mrBHelper
.bInDispose
= true;
726 // side effect: keeping a reference to this
727 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
730 mrBHelper
.aLC
.disposeAndClear( aEvt
);
735 MutexGuard
aGuard2( mrBHelper
.rMutex
);
736 // bDisposed and bInDispose must be set in this order:
737 mrBHelper
.bDisposed
= true;
738 mrBHelper
.bInDispose
= false;
741 MutexGuard
aGuard2( mrBHelper
.rMutex
);
742 // bDisposed and bInDispose must be set in this order:
743 mrBHelper
.bDisposed
= true;
744 mrBHelper
.bInDispose
= false;
746 catch (RuntimeException
&)
750 catch (const Exception
& exc
)
752 css::uno::Any anyEx
= cppu::getCaughtException();
753 throw css::lang::WrappedTargetRuntimeException(
754 "unexpected UNO exception caught: " + exc
.Message
,
759 void SdStyleSheet::disposing()
761 SolarMutexGuard aGuard
;
771 void SAL_CALL
SdStyleSheet::addEventListener( const Reference
< XEventListener
>& xListener
)
773 ClearableMutexGuard
aGuard( mrBHelper
.rMutex
);
774 if (mrBHelper
.bDisposed
|| mrBHelper
.bInDispose
)
777 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
778 xListener
->disposing( aEvt
);
782 mrBHelper
.addListener( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
786 void SAL_CALL
SdStyleSheet::removeEventListener( const Reference
< XEventListener
>& xListener
)
788 mrBHelper
.removeListener( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
791 // XModifyBroadcaster
793 void SAL_CALL
SdStyleSheet::addModifyListener( const Reference
< XModifyListener
>& xListener
)
795 ClearableMutexGuard
aGuard( mrBHelper
.rMutex
);
796 if (mrBHelper
.bDisposed
|| mrBHelper
.bInDispose
)
799 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
800 xListener
->disposing( aEvt
);
804 if (!mpModifyListenerForwarder
)
805 mpModifyListenerForwarder
.reset( new ModifyListenerForwarder( this ) );
806 mrBHelper
.addListener( cppu::UnoType
<XModifyListener
>::get(), xListener
);
810 void SAL_CALL
SdStyleSheet::removeModifyListener( const Reference
< XModifyListener
>& xListener
)
812 mrBHelper
.removeListener( cppu::UnoType
<XModifyListener
>::get(), xListener
);
815 void SdStyleSheet::notifyModifyListener()
817 MutexGuard
aGuard( mrBHelper
.rMutex
);
819 cppu::OInterfaceContainerHelper
* pContainer
= mrBHelper
.getContainer( cppu::UnoType
<XModifyListener
>::get() );
822 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
823 pContainer
->forEach
<XModifyListener
>(
824 [&] (Reference
<XModifyListener
> const& xListener
) {
825 return xListener
->modified(aEvt
);
831 OUString SAL_CALL
SdStyleSheet::getImplementationName()
833 return "SdStyleSheet";
836 sal_Bool SAL_CALL
SdStyleSheet::supportsService( const OUString
& ServiceName
)
838 return cppu::supportsService( this, ServiceName
);
841 Sequence
< OUString
> SAL_CALL
SdStyleSheet::getSupportedServiceNames()
843 return { "com.sun.star.style.Style",
844 "com.sun.star.drawing.FillProperties",
845 "com.sun.star.drawing.LineProperties",
846 "com.sun.star.drawing.ShadowProperties",
847 "com.sun.star.drawing.ConnectorProperties",
848 "com.sun.star.drawing.MeasureProperties",
849 "com.sun.star.style.ParagraphProperties",
850 "com.sun.star.style.CharacterProperties",
851 "com.sun.star.drawing.TextProperties",
852 "com.sun.star.drawing.Text" };
855 bool SdStyleSheet::SetName(const OUString
& rNewName
, bool bReindexNow
)
857 const bool bResult
= SfxUnoStyleSheet::SetName(rNewName
, bReindexNow
);
858 // Don't overwrite predefined API names
859 if (bResult
&& GetHelpIdForApiName(msApiName
) == 0)
861 msApiName
= rNewName
;
862 Broadcast(SfxHint(SfxHintId::DataChanged
));
868 OUString SAL_CALL
SdStyleSheet::getName()
870 SolarMutexGuard aGuard
;
875 void SAL_CALL
SdStyleSheet::setName( const OUString
& rName
)
877 SolarMutexGuard aGuard
;
884 sal_Bool SAL_CALL
SdStyleSheet::isUserDefined()
886 SolarMutexGuard aGuard
;
888 return IsUserDefined();
891 sal_Bool SAL_CALL
SdStyleSheet::isInUse()
893 SolarMutexGuard aGuard
;
898 OUString SAL_CALL
SdStyleSheet::getParentStyle()
900 SolarMutexGuard aGuard
;
903 if( !GetParent().isEmpty() )
905 SdStyleSheet
* pParentStyle
= static_cast< SdStyleSheet
* >( mxPool
->Find( GetParent(), nFamily
) );
907 return pParentStyle
->GetApiName();
912 void SAL_CALL
SdStyleSheet::setParentStyle( const OUString
& rParentName
)
914 SolarMutexGuard aGuard
;
917 if( !rParentName
.isEmpty() )
919 OUString
const name(GetName());
920 sal_Int32
const sep(name
.indexOf(SD_LT_SEPARATOR
));
921 OUString
const master((sep
== -1) ? OUString() : name
.copy(0, sep
));
922 std::shared_ptr
<SfxStyleSheetIterator
> aSSSI
= std::make_shared
<SfxStyleSheetIterator
>(mxPool
.get(), nFamily
);
923 for (SfxStyleSheetBase
*pStyle
= aSSSI
->First(); pStyle
; pStyle
= aSSSI
->Next())
925 // we hope that we have only sd style sheets
926 SdStyleSheet
* pSdStyleSheet
= static_cast<SdStyleSheet
*>(pStyle
);
927 OUString
const curName(pStyle
->GetName());
928 sal_Int32
const curSep(curName
.indexOf(SD_LT_SEPARATOR
));
929 OUString
const curMaster((curSep
== -1)
930 ? OUString() : curName
.copy(0, curSep
));
931 // check that the master matches, as msApiName exists once per
933 if (pSdStyleSheet
->msApiName
== rParentName
&& master
== curMaster
)
942 throw NoSuchElementException();
946 SetParent( rParentName
);
952 Reference
< XPropertySetInfo
> SdStyleSheet::getPropertySetInfo()
955 static Reference
< XPropertySetInfo
> xInfo
= GetStylePropertySet().getPropertySetInfo();
959 void SAL_CALL
SdStyleSheet::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
961 SolarMutexGuard aGuard
;
964 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( aPropertyName
);
965 if( pEntry
== nullptr )
967 throw UnknownPropertyException( aPropertyName
, static_cast<cppu::OWeakObject
*>(this));
970 if( pEntry
->nWID
== WID_STYLE_HIDDEN
)
973 if ( aValue
>>= bValue
)
977 if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
978 return; // not yet implemented for styles
980 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
981 throw PropertyVetoException();
983 if( (pEntry
->nWID
== EE_PARA_NUMBULLET
) && (GetFamily() == SfxStyleFamily::Page
) )
986 const sal_uInt32 nTempHelpId
= GetHelpId( aStr
);
988 if( (nTempHelpId
>= HID_PSEUDOSHEET_OUTLINE2
) && (nTempHelpId
<= HID_PSEUDOSHEET_OUTLINE9
) )
992 SfxItemSet
&rStyleSet
= GetItemSet();
994 if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
997 if( aValue
>>= eMode
)
999 rStyleSet
.Put( XFillBmpStretchItem( eMode
== BitmapMode_STRETCH
) );
1000 rStyleSet
.Put( XFillBmpTileItem( eMode
== BitmapMode_REPEAT
) );
1003 throw IllegalArgumentException();
1006 SfxItemSet
aSet( GetPool()->GetPool(), {{pEntry
->nWID
, pEntry
->nWID
}});
1007 aSet
.Put( rStyleSet
);
1011 if( EE_PARA_NUMBULLET
== pEntry
->nWID
)
1013 vcl::Font aBulletFont
;
1014 SdStyleSheetPool::PutNumBulletItem( this, aBulletFont
);
1015 aSet
.Put( rStyleSet
);
1019 aSet
.Put( GetPool()->GetPool().GetDefaultItem( pEntry
->nWID
) );
1023 if( pEntry
->nMemberId
== MID_NAME
&&
1024 ( pEntry
->nWID
== XATTR_FILLBITMAP
|| pEntry
->nWID
== XATTR_FILLGRADIENT
||
1025 pEntry
->nWID
== XATTR_FILLHATCH
|| pEntry
->nWID
== XATTR_FILLFLOATTRANSPARENCE
||
1026 pEntry
->nWID
== XATTR_LINESTART
|| pEntry
->nWID
== XATTR_LINEEND
|| pEntry
->nWID
== XATTR_LINEDASH
) )
1029 if(!(aValue
>>= aTempName
))
1030 throw IllegalArgumentException();
1032 SvxShape::SetFillAttribute( pEntry
->nWID
, aTempName
, aSet
);
1034 else if(!SvxUnoTextRangeBase::SetPropertyValueHelper( pEntry
, aValue
, aSet
))
1036 SvxItemPropertySet_setPropertyValue( pEntry
, aValue
, aSet
);
1039 rStyleSet
.Put( aSet
);
1040 Broadcast(SfxHint(SfxHintId::DataChanged
));
1044 Any SAL_CALL
SdStyleSheet::getPropertyValue( const OUString
& PropertyName
)
1046 SolarMutexGuard aGuard
;
1050 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( PropertyName
);
1051 if( pEntry
== nullptr )
1053 throw UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
1058 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
1060 if( nFamily
== SfxStyleFamily::Page
)
1062 const OUString
aLayoutName( GetName() );
1063 aAny
<<= aLayoutName
.copy( 0, aLayoutName
.indexOf( SD_LT_SEPARATOR
) );
1067 aAny
<<= GetFamilyString(nFamily
);
1070 else if( pEntry
->nWID
== WID_STYLE_DISPNAME
)
1072 OUString aDisplayName
;
1073 if ( nFamily
== SfxStyleFamily::Page
)
1075 const SdStyleSheet
* pStyleSheet
= GetPseudoStyleSheet();
1076 if (pStyleSheet
!= nullptr)
1077 aDisplayName
= pStyleSheet
->GetName();
1080 if (aDisplayName
.isEmpty())
1081 aDisplayName
= GetName();
1083 aAny
<<= aDisplayName
;
1085 else if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
1089 else if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1091 SfxItemSet
&rStyleSet
= GetItemSet();
1093 const XFillBmpStretchItem
* pStretchItem
= rStyleSet
.GetItem
<XFillBmpStretchItem
>(XATTR_FILLBMP_STRETCH
);
1094 const XFillBmpTileItem
* pTileItem
= rStyleSet
.GetItem
<XFillBmpTileItem
>(XATTR_FILLBMP_TILE
);
1096 if( pStretchItem
&& pTileItem
)
1098 if( pTileItem
->GetValue() )
1099 aAny
<<= BitmapMode_REPEAT
;
1100 else if( pStretchItem
->GetValue() )
1101 aAny
<<= BitmapMode_STRETCH
;
1103 aAny
<<= BitmapMode_NO_REPEAT
;
1106 else if( pEntry
->nWID
== WID_STYLE_HIDDEN
)
1108 aAny
<<= IsHidden( );
1112 SfxItemSet
aSet( GetPool()->GetPool(), {{pEntry
->nWID
, pEntry
->nWID
}});
1114 const SfxPoolItem
* pItem
;
1115 SfxItemSet
& rStyleSet
= GetItemSet();
1117 if( rStyleSet
.GetItemState( pEntry
->nWID
, true, &pItem
) == SfxItemState::SET
)
1121 aSet
.Put( GetPool()->GetPool().GetDefaultItem( pEntry
->nWID
) );
1123 if(SvxUnoTextRangeBase::GetPropertyValueHelper( aSet
, pEntry
, aAny
))
1126 // Get value of ItemSet
1127 aAny
= SvxItemPropertySet_getPropertyValue( pEntry
, aSet
);
1130 if( pEntry
->aType
!= aAny
.getValueType() )
1132 // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
1133 if( ( pEntry
->aType
== ::cppu::UnoType
<sal_Int16
>::get()) && aAny
.getValueType() == ::cppu::UnoType
<sal_Int32
>::get() )
1135 sal_Int32 nValue
= 0;
1137 aAny
<<= static_cast<sal_Int16
>(nValue
);
1141 OSL_FAIL("SvxShape::GetAnyForItem() Returnvalue has wrong Type!" );
1149 void SAL_CALL
SdStyleSheet::addPropertyChangeListener( const OUString
& , const Reference
< XPropertyChangeListener
>& ) {}
1150 void SAL_CALL
SdStyleSheet::removePropertyChangeListener( const OUString
& , const Reference
< XPropertyChangeListener
>& ) {}
1151 void SAL_CALL
SdStyleSheet::addVetoableChangeListener( const OUString
& , const Reference
< XVetoableChangeListener
>& ) {}
1152 void SAL_CALL
SdStyleSheet::removeVetoableChangeListener( const OUString
& , const Reference
< XVetoableChangeListener
>& ) {}
1156 PropertyState SAL_CALL
SdStyleSheet::getPropertyState( const OUString
& PropertyName
)
1158 SolarMutexGuard aGuard
;
1162 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( PropertyName
);
1164 if( pEntry
== nullptr )
1165 throw UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
1167 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
1169 return PropertyState_DIRECT_VALUE
;
1171 else if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
1173 return PropertyState_DEFAULT_VALUE
;
1175 else if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1177 const SfxItemSet
& rSet
= GetItemSet();
1179 if( rSet
.GetItemState( XATTR_FILLBMP_STRETCH
, false ) == SfxItemState::SET
||
1180 rSet
.GetItemState( XATTR_FILLBMP_TILE
, false ) == SfxItemState::SET
)
1182 return PropertyState_DIRECT_VALUE
;
1186 return PropertyState_AMBIGUOUS_VALUE
;
1191 SfxItemSet
&rStyleSet
= GetItemSet();
1193 PropertyState eState
;
1195 switch( rStyleSet
.GetItemState( pEntry
->nWID
, false ) )
1197 case SfxItemState::READONLY
:
1198 case SfxItemState::SET
:
1199 eState
= PropertyState_DIRECT_VALUE
;
1201 case SfxItemState::DEFAULT
:
1202 eState
= PropertyState_DEFAULT_VALUE
;
1205 eState
= PropertyState_AMBIGUOUS_VALUE
;
1209 // if an item is set, this doesn't mean we want it :)
1210 if( PropertyState_DIRECT_VALUE
== eState
)
1212 switch( pEntry
->nWID
)
1214 case XATTR_FILLBITMAP
:
1215 case XATTR_FILLGRADIENT
:
1216 case XATTR_FILLHATCH
:
1217 case XATTR_FILLFLOATTRANSPARENCE
:
1219 case XATTR_LINESTART
:
1220 case XATTR_LINEDASH
:
1222 const NameOrIndex
* pItem
= rStyleSet
.GetItem
<NameOrIndex
>(pEntry
->nWID
);
1223 if( ( pItem
== nullptr ) || pItem
->GetName().isEmpty() )
1224 eState
= PropertyState_DEFAULT_VALUE
;
1233 Sequence
< PropertyState
> SAL_CALL
SdStyleSheet::getPropertyStates( const Sequence
< OUString
>& aPropertyName
)
1235 SolarMutexGuard aGuard
;
1239 sal_Int32 nCount
= aPropertyName
.getLength();
1241 Sequence
< PropertyState
> aPropertyStateSequence( nCount
);
1243 std::transform(aPropertyName
.begin(), aPropertyName
.end(), aPropertyStateSequence
.begin(),
1244 [this](const OUString
& rName
) -> PropertyState
{ return getPropertyState(rName
); });
1246 return aPropertyStateSequence
;
1249 void SAL_CALL
SdStyleSheet::setPropertyToDefault( const OUString
& PropertyName
)
1251 SolarMutexGuard aGuard
;
1255 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( PropertyName
);
1256 if( pEntry
== nullptr )
1257 throw UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
1259 SfxItemSet
&rStyleSet
= GetItemSet();
1261 if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1263 rStyleSet
.ClearItem( XATTR_FILLBMP_STRETCH
);
1264 rStyleSet
.ClearItem( XATTR_FILLBMP_TILE
);
1268 rStyleSet
.ClearItem( pEntry
->nWID
);
1270 Broadcast(SfxHint(SfxHintId::DataChanged
));
1273 Any SAL_CALL
SdStyleSheet::getPropertyDefault( const OUString
& aPropertyName
)
1275 SolarMutexGuard aGuard
;
1279 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( aPropertyName
);
1280 if( pEntry
== nullptr )
1281 throw UnknownPropertyException( aPropertyName
, static_cast<cppu::OWeakObject
*>(this));
1283 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
1285 aRet
<<= GetFamilyString(nFamily
);
1287 else if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
1291 else if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1293 aRet
<<= BitmapMode_REPEAT
;
1297 SfxItemPool
& rMyPool
= GetPool()->GetPool();
1298 SfxItemSet
aSet( rMyPool
, {{pEntry
->nWID
, pEntry
->nWID
}});
1299 aSet
.Put( rMyPool
.GetDefaultItem( pEntry
->nWID
) );
1300 aRet
= SvxItemPropertySet_getPropertyValue( pEntry
, aSet
);
1305 /** this is used because our property map is not sorted yet */
1306 const SfxItemPropertySimpleEntry
* SdStyleSheet::getPropertyMapEntry( const OUString
& rPropertyName
)
1308 return GetStylePropertySet().getPropertyMapEntry(rPropertyName
);
1311 //Broadcast that a SdStyleSheet has changed, taking into account outline sublevels
1312 //which need to be explicitly broadcast as changing if their parent style was
1313 //the one that changed
1314 void SdStyleSheet::BroadcastSdStyleSheetChange(SfxStyleSheetBase
const * pStyleSheet
,
1315 PresentationObjects ePO
, SfxStyleSheetBasePool
* pSSPool
)
1317 SdStyleSheet
* pRealSheet
= static_cast<SdStyleSheet
const *>(pStyleSheet
)->GetRealStyleSheet();
1318 pRealSheet
->Broadcast(SfxHint(SfxHintId::DataChanged
));
1320 if( (ePO
< PresentationObjects::Outline_1
) || (ePO
> PresentationObjects::Outline_8
) )
1323 OUString
sStyleName(SdResId(STR_PSEUDOSHEET_OUTLINE
) + " ");
1325 for( sal_uInt16 n
= static_cast<sal_uInt16
>(ePO
) - static_cast<sal_uInt16
>(PresentationObjects::Outline_1
) + 2; n
< 10; n
++ )
1327 OUString
aName( sStyleName
+ OUString::number(n
) );
1329 SfxStyleSheetBase
* pSheet
= pSSPool
->Find( aName
, SfxStyleFamily::Pseudo
);
1333 SdStyleSheet
* pRealStyleSheet
= static_cast<SdStyleSheet
*>(pSheet
)->GetRealStyleSheet();
1334 pRealStyleSheet
->Broadcast(SfxHint(SfxHintId::DataChanged
));
1339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */