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>
65 using ::osl::MutexGuard
;
66 using ::osl::ClearableMutexGuard
;
67 using ::com::sun::star::table::BorderLine
;
68 using namespace ::com::sun::star::uno
;
69 using namespace ::com::sun::star::util
;
70 using namespace ::com::sun::star::lang
;
71 using namespace ::com::sun::star::style
;
72 using namespace ::com::sun::star::beans
;
73 using namespace ::com::sun::star::container
;
74 using namespace ::com::sun::star::drawing
;
76 #define WID_STYLE_HIDDEN 7997
77 #define WID_STYLE_DISPNAME 7998
78 #define WID_STYLE_FAMILY 7999
80 static SvxItemPropertySet
& GetStylePropertySet()
82 static const SfxItemPropertyMapEntry aFullPropertyMap_Impl
[] =
84 { OUString("Family"), WID_STYLE_FAMILY
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::READONLY
, 0},
85 { OUString("UserDefinedAttributes"), SDRATTR_XMLATTRIBUTES
, cppu::UnoType
<XNameContainer
>::get(), 0, 0},
86 { OUString("DisplayName"), WID_STYLE_DISPNAME
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::READONLY
, 0},
87 { OUString("Hidden"), WID_STYLE_HIDDEN
, cppu::UnoType
<bool>::get(), 0, 0},
89 SVX_UNOEDIT_NUMBERING_PROPERTIE
,
92 LINE_PROPERTIES_START_END
95 TEXT_PROPERTIES_DEFAULTS
97 SPECIAL_DIMENSIONING_PROPERTIES_DEFAULTS
98 { OUString("TopBorder"), SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, TOP_BORDER
},
99 { OUString("BottomBorder"), SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, BOTTOM_BORDER
},
100 { OUString("LeftBorder"), SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, LEFT_BORDER
},
101 { OUString("RightBorder"), SDRATTR_TABLE_BORDER
, ::cppu::UnoType
<BorderLine
>::get(), 0, RIGHT_BORDER
},
102 { OUString(), 0, css::uno::Type(), 0, 0 }
105 static SvxItemPropertySet
aPropSet( aFullPropertyMap_Impl
, SdrObject::GetGlobalDrawObjectItemPool() );
109 class ModifyListenerForewarder
: public SfxListener
112 explicit ModifyListenerForewarder( SdStyleSheet
* pStyleSheet
);
114 virtual void Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
117 SdStyleSheet
* mpStyleSheet
;
120 ModifyListenerForewarder::ModifyListenerForewarder( SdStyleSheet
* pStyleSheet
)
121 : mpStyleSheet( pStyleSheet
)
125 SfxBroadcaster
& rBC
= static_cast< SfxBroadcaster
& >( *pStyleSheet
);
126 StartListening( rBC
);
130 void ModifyListenerForewarder::Notify(SfxBroadcaster
& /*rBC*/, const SfxHint
& /*rHint*/)
133 mpStyleSheet
->notifyModifyListener();
136 SdStyleSheet::SdStyleSheet(const OUString
& rDisplayName
, SfxStyleSheetBasePool
& _rPool
, SfxStyleFamily eFamily
, SfxStyleSearchBits _nMask
)
137 : SdStyleSheetBase( rDisplayName
, _rPool
, eFamily
, _nMask
)
138 , ::cppu::BaseMutex()
139 , msApiName( rDisplayName
)
141 , mrBHelper( m_aMutex
)
145 SdStyleSheet::~SdStyleSheet()
148 pSet
= nullptr; // that following destructors also get a change
151 void SdStyleSheet::SetApiName( const OUString
& rApiName
)
153 msApiName
= rApiName
;
156 OUString
const & SdStyleSheet::GetApiName() const
158 if( !msApiName
.isEmpty() )
164 bool SdStyleSheet::SetParent(const OUString
& rParentName
)
166 bool bResult
= false;
168 if (SfxStyleSheet::SetParent(rParentName
))
170 // PseudoStyleSheets do not have their own ItemSets
171 if (nFamily
!= SfxStyleFamily::Pseudo
)
173 if( !rParentName
.isEmpty() )
175 SfxStyleSheetBase
* pStyle
= m_pPool
->Find(rParentName
, nFamily
);
179 SfxItemSet
& rParentSet
= pStyle
->GetItemSet();
180 GetItemSet().SetParent(&rParentSet
);
181 Broadcast( SfxHint( SfxHintId::DataChanged
) );
187 GetItemSet().SetParent(nullptr);
188 Broadcast( SfxHint( SfxHintId::DataChanged
) );
200 * create if necessary and return ItemSets
202 SfxItemSet
& SdStyleSheet::GetItemSet()
204 if (nFamily
== SfxStyleFamily::Para
|| nFamily
== SfxStyleFamily::Page
)
206 // we create the ItemSet 'on demand' if necessary
209 pSet
= new SfxItemSet(
210 GetPool()->GetPool(),
212 XATTR_LINE_FIRST
, XATTR_LINE_LAST
,
213 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
214 SDRATTR_SHADOW_FIRST
, SDRATTR_SHADOW_LAST
,
215 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_TEXT_WORDWRAP
,
216 SDRATTR_EDGE_FIRST
, SDRATTR_MEASURE_LAST
,
217 SDRATTR_3D_FIRST
, SDRATTR_3D_LAST
,
218 EE_PARA_START
, EE_CHAR_END
>{});
225 else if( nFamily
== SfxStyleFamily::Frame
)
229 pSet
= new SfxItemSet(
230 GetPool()->GetPool(),
232 XATTR_LINE_FIRST
, XATTR_LINE_LAST
,
233 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
234 SDRATTR_SHADOW_FIRST
, SDRATTR_SHADOW_LAST
,
235 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_XMLATTRIBUTES
,
236 SDRATTR_TEXT_WORDWRAP
, SDRATTR_TEXT_WORDWRAP
,
237 SDRATTR_TABLE_FIRST
, SDRATTR_TABLE_LAST
,
238 EE_PARA_START
, EE_CHAR_END
>{});
245 // this is a dummy template for the internal template of the
246 // current presentation layout; return the ItemSet of that template
250 SdStyleSheet
* pSdSheet
= GetRealStyleSheet();
254 return pSdSheet
->GetItemSet();
260 pSet
= new SfxItemSet(
261 GetPool()->GetPool(),
263 XATTR_LINE_FIRST
, XATTR_LINE_LAST
,
264 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
265 SDRATTR_SHADOW_FIRST
, SDRATTR_SHADOW_LAST
,
266 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_TEXT_WORDWRAP
,
267 SDRATTR_EDGE_FIRST
, SDRATTR_MEASURE_LAST
,
268 SDRATTR_3D_FIRST
, SDRATTR_3D_LAST
,
269 EE_PARA_START
, EE_CHAR_END
>{});
279 * A template is used when it is referenced by inserted object or by a used
282 bool SdStyleSheet::IsUsed() const
284 bool bResult
= false;
286 const size_t nListenerCount
= GetSizeOfVector();
287 for (size_t n
= 0; n
< nListenerCount
; ++n
)
289 SfxListener
* pListener
= GetListener(n
);
290 if( pListener
== this )
293 const svl::StyleSheetUser
* const pUser(dynamic_cast<svl::StyleSheetUser
*>(pListener
));
295 bResult
= pUser
->isUsedByModel();
302 MutexGuard
aGuard( mrBHelper
.rMutex
);
304 cppu::OInterfaceContainerHelper
* pContainer
= mrBHelper
.getContainer( cppu::UnoType
<XModifyListener
>::get() );
307 Sequence
< Reference
< XInterface
> > aModifyListeners( pContainer
->getElements() );
308 bResult
= std::any_of(aModifyListeners
.begin(), aModifyListeners
.end(),
309 [](const Reference
<XInterface
>& rListener
) {
310 Reference
< XStyle
> xStyle( rListener
, UNO_QUERY
);
311 return xStyle
.is() && xStyle
->isInUse();
319 * Determine the style sheet for which this dummy is for.
321 SdStyleSheet
* SdStyleSheet::GetRealStyleSheet() const
324 OUString
aSep( SD_LT_SEPARATOR
);
325 SdStyleSheet
* pRealStyle
= nullptr;
326 SdDrawDocument
* pDoc
= static_cast<SdStyleSheetPool
*>(m_pPool
)->GetDoc();
328 ::sd::DrawViewShell
* pDrawViewShell
= nullptr;
330 ::sd::ViewShellBase
* pBase
= dynamic_cast< ::sd::ViewShellBase
* >( SfxViewShell::Current() );
332 pDrawViewShell
= dynamic_cast< ::sd::DrawViewShell
* >( pBase
->GetMainViewShell().get() );
334 if (pDrawViewShell
&& pDrawViewShell
->GetDoc() == pDoc
)
336 SdPage
* pPage
= pDrawViewShell
->getCurrentPage();
339 aRealStyle
= pPage
->GetLayoutName();
340 // cut after separator string
342 if( aRealStyle
.indexOf(aSep
) >= 0)
344 aRealStyle
= aRealStyle
.copy(0,(aRealStyle
.indexOf(aSep
) + aSep
.getLength()));
348 if (aRealStyle
.isEmpty())
350 SdPage
* pPage
= pDoc
->GetSdPage(0, PageKind::Standard
);
354 aRealStyle
= pDoc
->GetSdPage(0, PageKind::Standard
)->GetLayoutName();
358 /* no page available yet. This can happen when actualizing the
359 document templates. */
360 SfxStyleSheetIterator
aIter(m_pPool
, SfxStyleFamily::Page
);
361 SfxStyleSheetBase
* pSheet
= aIter
.First();
363 aRealStyle
= pSheet
->GetName();
366 if( aRealStyle
.indexOf(aSep
) >= 0)
368 aRealStyle
= aRealStyle
.copy(0,(aRealStyle
.indexOf(aSep
) + aSep
.getLength()));
372 /* now map from the name (specified for country language) to the internal
373 name (independent of the country language) */
374 OUString aInternalName
;
375 OUString
aStyleName(aName
);
377 if (aStyleName
== SdResId(STR_PSEUDOSHEET_TITLE
))
379 aInternalName
= STR_LAYOUT_TITLE
;
381 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_SUBTITLE
))
383 aInternalName
= STR_LAYOUT_SUBTITLE
;
385 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_BACKGROUND
))
387 aInternalName
= STR_LAYOUT_BACKGROUND
;
389 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS
))
391 aInternalName
= STR_LAYOUT_BACKGROUNDOBJECTS
;
393 else if (aStyleName
== SdResId(STR_PSEUDOSHEET_NOTES
))
395 aInternalName
= STR_LAYOUT_NOTES
;
399 OUString
aOutlineStr(SdResId(STR_PSEUDOSHEET_OUTLINE
));
400 sal_Int32 nPos
= aStyleName
.indexOf(aOutlineStr
);
403 OUString
aNumStr(aStyleName
.copy(aOutlineStr
.getLength()));
404 aInternalName
= STR_LAYOUT_OUTLINE
+ aNumStr
;
408 aRealStyle
+= aInternalName
;
409 pRealStyle
= static_cast< SdStyleSheet
* >( m_pPool
->Find(aRealStyle
, SfxStyleFamily::Page
) );
414 SfxStyleSheetIterator
aIter(m_pPool
, SfxStyleFamily::Page
);
415 if( aIter
.Count() > 0 )
416 // StyleSheet not found, but pool already loaded
417 DBG_ASSERT(pRealStyle
, "Internal StyleSheet not found");
425 * Determine pseudo style sheet which stands for this style sheet.
427 SdStyleSheet
* SdStyleSheet::GetPseudoStyleSheet() const
429 SdStyleSheet
* pPseudoStyle
= nullptr;
430 OUString
aSep( SD_LT_SEPARATOR
);
431 OUString
aStyleName(aName
);
432 // without layout name and separator
434 if( aStyleName
.indexOf(aSep
) >=0 )
436 aStyleName
= aStyleName
.copy (aStyleName
.indexOf(aSep
) + aSep
.getLength());
439 if (aStyleName
== STR_LAYOUT_TITLE
)
441 aStyleName
= SdResId(STR_PSEUDOSHEET_TITLE
);
443 else if (aStyleName
== STR_LAYOUT_SUBTITLE
)
445 aStyleName
= SdResId(STR_PSEUDOSHEET_SUBTITLE
);
447 else if (aStyleName
== STR_LAYOUT_BACKGROUND
)
449 aStyleName
= SdResId(STR_PSEUDOSHEET_BACKGROUND
);
451 else if (aStyleName
== STR_LAYOUT_BACKGROUNDOBJECTS
)
453 aStyleName
= SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS
);
455 else if (aStyleName
== STR_LAYOUT_NOTES
)
457 aStyleName
= SdResId(STR_PSEUDOSHEET_NOTES
);
461 OUString
aOutlineStr(STR_LAYOUT_OUTLINE
);
462 sal_Int32 nPos
= aStyleName
.indexOf(aOutlineStr
);
465 OUString
aNumStr(aStyleName
.copy(aOutlineStr
.getLength()));
466 aStyleName
= SdResId(STR_PSEUDOSHEET_OUTLINE
) + aNumStr
;
470 pPseudoStyle
= static_cast<SdStyleSheet
*>(m_pPool
->Find(aStyleName
, SfxStyleFamily::Pseudo
));
471 DBG_ASSERT(pPseudoStyle
, "PseudoStyleSheet missing");
476 void SdStyleSheet::Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
478 // first, base class functionality
479 SfxStyleSheet::Notify(rBC
, rHint
);
481 if (nFamily
!= SfxStyleFamily::Pseudo
)
484 /* if the dummy gets a notify about a changed attribute, he takes care that
485 the actual meant style sheet sends broadcasts. */
486 if (rHint
.GetId() == SfxHintId::DataChanged
)
488 SdStyleSheet
* pRealStyle
= GetRealStyleSheet();
490 pRealStyle
->Broadcast(rHint
);
495 * Adjust the bullet width and the left text indent of the provided ItemSets to
496 * their font height. The new values are calculated that the ratio to the font
497 * height is as in the style sheet.
499 * @param bOnlyMissingItems If sal_True, only not set items are completed. With
500 * sal_False, are items are overwritten.
502 void SdStyleSheet::AdjustToFontHeight(SfxItemSet
& rSet
, bool bOnlyMissingItems
)
504 /* If not explicit set, adjust bullet width and text indent to new font
506 SfxStyleFamily eFamily
= nFamily
;
507 OUString
aStyleName(aName
);
508 if (eFamily
== SfxStyleFamily::Pseudo
)
510 SfxStyleSheet
* pRealStyle
= GetRealStyleSheet();
511 eFamily
= pRealStyle
->GetFamily();
512 aStyleName
= pRealStyle
->GetName();
515 if (!(eFamily
== SfxStyleFamily::Page
&&
516 aStyleName
.indexOf(STR_LAYOUT_OUTLINE
) != -1 &&
517 rSet
.GetItemState(EE_CHAR_FONTHEIGHT
) == SfxItemState::SET
))
520 const SfxItemSet
* pCurSet
= &GetItemSet();
521 sal_uInt32 nNewHeight
= rSet
.Get(EE_CHAR_FONTHEIGHT
).GetHeight();
522 sal_uInt32 nOldHeight
= pCurSet
->Get(EE_CHAR_FONTHEIGHT
).GetHeight();
524 if (rSet
.GetItemState(EE_PARA_BULLET
) != SfxItemState::SET
|| !bOnlyMissingItems
)
526 const SvxBulletItem
& rBItem
= pCurSet
->Get(EE_PARA_BULLET
);
527 double fBulletFraction
= double(rBItem
.GetWidth()) / nOldHeight
;
528 SvxBulletItem
aNewBItem(rBItem
);
529 aNewBItem
.SetWidth(static_cast<sal_uInt32
>(fBulletFraction
* nNewHeight
));
533 if (rSet
.GetItemState(EE_PARA_LRSPACE
) != SfxItemState::SET
|| !bOnlyMissingItems
)
535 const SvxLRSpaceItem
& rLRItem
= pCurSet
->Get(EE_PARA_LRSPACE
);
536 double fIndentFraction
= double(rLRItem
.GetTextLeft()) / nOldHeight
;
537 SvxLRSpaceItem
aNewLRItem(rLRItem
);
538 aNewLRItem
.SetTextLeft(fIndentFraction
* nNewHeight
);
539 double fFirstIndentFraction
= double(rLRItem
.GetTextFirstLineOfst()) / nOldHeight
;
540 aNewLRItem
.SetTextFirstLineOfst(static_cast<short>(fFirstIndentFraction
* nNewHeight
));
541 rSet
.Put(aNewLRItem
);
544 if (rSet
.GetItemState(EE_PARA_ULSPACE
) != SfxItemState::SET
|| !bOnlyMissingItems
)
546 const SvxULSpaceItem
& rULItem
= pCurSet
->Get(EE_PARA_ULSPACE
);
547 SvxULSpaceItem
aNewULItem(rULItem
);
548 double fLowerFraction
= double(rULItem
.GetLower()) / nOldHeight
;
549 aNewULItem
.SetLower(static_cast<sal_uInt16
>(fLowerFraction
* nNewHeight
));
550 double fUpperFraction
= double(rULItem
.GetUpper()) / nOldHeight
;
551 aNewULItem
.SetUpper(static_cast<sal_uInt16
>(fUpperFraction
* nNewHeight
));
552 rSet
.Put(aNewULItem
);
556 bool SdStyleSheet::HasFollowSupport() const
561 bool SdStyleSheet::HasParentSupport() const
566 bool SdStyleSheet::HasClearParentSupport() const
575 OUStringLiteral
const mpApiName
;
576 sal_uInt32
const mnHelpId
;
577 } const pApiNameMap
[]
578 = { { OUStringLiteral("title"), HID_PSEUDOSHEET_TITLE
},
579 { OUStringLiteral("subtitle"), HID_PSEUDOSHEET_SUBTITLE
},
580 { OUStringLiteral("background"), HID_PSEUDOSHEET_BACKGROUND
},
581 { OUStringLiteral("backgroundobjects"), HID_PSEUDOSHEET_BACKGROUNDOBJECTS
},
582 { OUStringLiteral("notes"), HID_PSEUDOSHEET_NOTES
},
583 { OUStringLiteral("standard"), HID_STANDARD_STYLESHEET_NAME
},
584 { OUStringLiteral("objectwithoutfill"), HID_POOLSHEET_OBJWITHOUTFILL
},
586 { OUStringLiteral("Text"), HID_POOLSHEET_TEXT
},
587 { OUStringLiteral("A4"), HID_POOLSHEET_A4
},
588 { OUStringLiteral("Title A4"), HID_POOLSHEET_A4_TITLE
},
589 { OUStringLiteral("Heading A4"), HID_POOLSHEET_A4_HEADLINE
},
590 { OUStringLiteral("Text A4"), HID_POOLSHEET_A4_TEXT
},
591 { OUStringLiteral("A4"), HID_POOLSHEET_A0
},
592 { OUStringLiteral("Title A0"), HID_POOLSHEET_A0_TITLE
},
593 { OUStringLiteral("Heading A0"), HID_POOLSHEET_A0_HEADLINE
},
594 { OUStringLiteral("Text A0"), HID_POOLSHEET_A0_TEXT
},
596 { OUStringLiteral("Graphic"), HID_POOLSHEET_GRAPHIC
},
597 { OUStringLiteral("Shapes"), HID_POOLSHEET_SHAPES
},
598 { OUStringLiteral("Filled"), HID_POOLSHEET_FILLED
},
599 { OUStringLiteral("Filled Blue"), HID_POOLSHEET_FILLED_BLUE
},
600 { OUStringLiteral("Filled Green"), HID_POOLSHEET_FILLED_GREEN
},
601 { OUStringLiteral("Filled Red"), HID_POOLSHEET_FILLED_RED
},
602 { OUStringLiteral("Filled Yellow"), HID_POOLSHEET_FILLED_YELLOW
},
603 { OUStringLiteral("Outlined"), HID_POOLSHEET_OUTLINE
},
604 { OUStringLiteral("Outlined Blue"), HID_POOLSHEET_OUTLINE_BLUE
},
605 { OUStringLiteral("Outlined Green"), HID_POOLSHEET_OUTLINE_GREEN
},
606 { OUStringLiteral("Outlined Red"), HID_POOLSHEET_OUTLINE_RED
},
607 { OUStringLiteral("Outlined Yellow"), HID_POOLSHEET_OUTLINE_YELLOW
},
608 { OUStringLiteral("Lines"), HID_POOLSHEET_LINES
},
609 { OUStringLiteral("Arrow Line"), HID_POOLSHEET_MEASURE
},
610 { OUStringLiteral("Arrow Dashed"), HID_POOLSHEET_LINES_DASHED
}
613 OUString
GetApiNameForHelpId(sal_uLong nId
)
615 if ((nId
>= HID_PSEUDOSHEET_OUTLINE1
) && (nId
<= HID_PSEUDOSHEET_OUTLINE9
))
616 return "outline" + OUStringChar(sal_Unicode('1' + (nId
- HID_PSEUDOSHEET_OUTLINE1
)));
618 for (const auto& i
: pApiNameMap
)
619 if (nId
== i
.mnHelpId
)
625 sal_uInt32
GetHelpIdForApiName(const OUString
& sName
)
628 if (sName
.startsWith("outline", &sRest
))
630 if (sRest
.getLength() == 1)
632 sal_Unicode ch
= sRest
.toChar();
633 if ('1' <= ch
&& ch
<= '9')
634 return HID_PSEUDOSHEET_OUTLINE1
+ ch
- '1';
636 // No other pre-defined names start with "outline"
640 for (const auto& i
: pApiNameMap
)
641 if (sName
== i
.mpApiName
)
648 void SdStyleSheet::SetHelpId( const OUString
& r
, sal_uLong nId
)
650 SfxStyleSheet::SetHelpId( r
, nId
);
652 const OUString sNewApiName
= GetApiNameForHelpId(nId
);
653 if (!sNewApiName
.isEmpty())
654 msApiName
= sNewApiName
;
657 OUString
SdStyleSheet::GetFamilyString( SfxStyleFamily eFamily
)
661 case SfxStyleFamily::Frame
:
664 OSL_FAIL( "SdStyleSheet::GetFamilyString(), illegal family!" );
666 case SfxStyleFamily::Para
:
671 void SdStyleSheet::throwIfDisposed()
674 throw DisposedException();
677 SdStyleSheet
* SdStyleSheet::CreateEmptyUserStyle( SfxStyleSheetBasePool
& rPool
, SfxStyleFamily eFamily
)
680 sal_Int32 nIndex
= 1;
683 aName
= "user" + OUString::number( nIndex
++ );
685 while( rPool
.Find( aName
, eFamily
) != nullptr );
687 return new SdStyleSheet(aName
, rPool
, eFamily
, SfxStyleSearchBits::UserDefined
);
692 void SAL_CALL
SdStyleSheet::release( ) throw ()
694 if (osl_atomic_decrement( &m_refCount
) != 0)
697 // restore reference count:
698 osl_atomic_increment( &m_refCount
);
699 if (! mrBHelper
.bDisposed
) try
703 catch (RuntimeException
const&)
705 // don't break throw ()
706 TOOLS_WARN_EXCEPTION( "sd", "" );
708 OSL_ASSERT( mrBHelper
.bDisposed
);
709 SdStyleSheetBase::release();
714 void SAL_CALL
SdStyleSheet::dispose( )
717 MutexGuard
aGuard(mrBHelper
.rMutex
);
718 if (mrBHelper
.bDisposed
|| mrBHelper
.bInDispose
)
721 mrBHelper
.bInDispose
= true;
725 // side effect: keeping a reference to this
726 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
729 mrBHelper
.aLC
.disposeAndClear( aEvt
);
734 MutexGuard
aGuard2( mrBHelper
.rMutex
);
735 // bDisposed and bInDispose must be set in this order:
736 mrBHelper
.bDisposed
= true;
737 mrBHelper
.bInDispose
= false;
740 MutexGuard
aGuard2( mrBHelper
.rMutex
);
741 // bDisposed and bInDispose must be set in this order:
742 mrBHelper
.bDisposed
= true;
743 mrBHelper
.bInDispose
= false;
745 catch (RuntimeException
&)
749 catch (const Exception
& exc
)
751 css::uno::Any anyEx
= cppu::getCaughtException();
752 throw css::lang::WrappedTargetRuntimeException(
753 "unexpected UNO exception caught: " + exc
.Message
,
758 void SdStyleSheet::disposing()
760 SolarMutexGuard aGuard
;
770 void SAL_CALL
SdStyleSheet::addEventListener( const Reference
< XEventListener
>& xListener
)
772 ClearableMutexGuard
aGuard( mrBHelper
.rMutex
);
773 if (mrBHelper
.bDisposed
|| mrBHelper
.bInDispose
)
776 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
777 xListener
->disposing( aEvt
);
781 mrBHelper
.addListener( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
785 void SAL_CALL
SdStyleSheet::removeEventListener( const Reference
< XEventListener
>& xListener
)
787 mrBHelper
.removeListener( cppu::UnoType
<decltype(xListener
)>::get(), xListener
);
790 // XModifyBroadcaster
792 void SAL_CALL
SdStyleSheet::addModifyListener( const Reference
< XModifyListener
>& xListener
)
794 ClearableMutexGuard
aGuard( mrBHelper
.rMutex
);
795 if (mrBHelper
.bDisposed
|| mrBHelper
.bInDispose
)
798 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
799 xListener
->disposing( aEvt
);
803 if (!mpModifyListenerForewarder
)
804 mpModifyListenerForewarder
.reset( new ModifyListenerForewarder( this ) );
805 mrBHelper
.addListener( cppu::UnoType
<XModifyListener
>::get(), xListener
);
809 void SAL_CALL
SdStyleSheet::removeModifyListener( const Reference
< XModifyListener
>& xListener
)
811 mrBHelper
.removeListener( cppu::UnoType
<XModifyListener
>::get(), xListener
);
814 void SdStyleSheet::notifyModifyListener()
816 MutexGuard
aGuard( mrBHelper
.rMutex
);
818 cppu::OInterfaceContainerHelper
* pContainer
= mrBHelper
.getContainer( cppu::UnoType
<XModifyListener
>::get() );
821 EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
822 pContainer
->forEach
<XModifyListener
>(
823 [&] (Reference
<XModifyListener
> const& xListener
) {
824 return xListener
->modified(aEvt
);
830 OUString SAL_CALL
SdStyleSheet::getImplementationName()
832 return "SdStyleSheet";
835 sal_Bool SAL_CALL
SdStyleSheet::supportsService( const OUString
& ServiceName
)
837 return cppu::supportsService( this, ServiceName
);
840 Sequence
< OUString
> SAL_CALL
SdStyleSheet::getSupportedServiceNames()
842 return { "com.sun.star.style.Style",
843 "com.sun.star.drawing.FillProperties",
844 "com.sun.star.drawing.LineProperties",
845 "com.sun.star.drawing.ShadowProperties",
846 "com.sun.star.drawing.ConnectorProperties",
847 "com.sun.star.drawing.MeasureProperties",
848 "com.sun.star.style.ParagraphProperties",
849 "com.sun.star.style.CharacterProperties",
850 "com.sun.star.drawing.TextProperties",
851 "com.sun.star.drawing.Text" };
854 bool SdStyleSheet::SetName(const OUString
& rNewName
, bool bReindexNow
)
856 const bool bResult
= SfxUnoStyleSheet::SetName(rNewName
, bReindexNow
);
857 // Don't overwrite predefined API names
858 if (bResult
&& GetHelpIdForApiName(msApiName
) == 0)
860 msApiName
= rNewName
;
861 Broadcast(SfxHint(SfxHintId::DataChanged
));
867 OUString SAL_CALL
SdStyleSheet::getName()
869 SolarMutexGuard aGuard
;
874 void SAL_CALL
SdStyleSheet::setName( const OUString
& rName
)
876 SolarMutexGuard aGuard
;
883 sal_Bool SAL_CALL
SdStyleSheet::isUserDefined()
885 SolarMutexGuard aGuard
;
887 return IsUserDefined();
890 sal_Bool SAL_CALL
SdStyleSheet::isInUse()
892 SolarMutexGuard aGuard
;
897 OUString SAL_CALL
SdStyleSheet::getParentStyle()
899 SolarMutexGuard aGuard
;
902 if( !GetParent().isEmpty() )
904 SdStyleSheet
* pParentStyle
= static_cast< SdStyleSheet
* >( mxPool
->Find( GetParent(), nFamily
) );
906 return pParentStyle
->GetApiName();
911 void SAL_CALL
SdStyleSheet::setParentStyle( const OUString
& rParentName
)
913 SolarMutexGuard aGuard
;
916 if( !rParentName
.isEmpty() )
918 OUString
const name(GetName());
919 sal_Int32
const sep(name
.indexOf(SD_LT_SEPARATOR
));
920 OUString
const master((sep
== -1) ? OUString() : name
.copy(0, sep
));
921 std::shared_ptr
<SfxStyleSheetIterator
> aSSSI
= std::make_shared
<SfxStyleSheetIterator
>(mxPool
.get(), nFamily
);
922 for (SfxStyleSheetBase
*pStyle
= aSSSI
->First(); pStyle
; pStyle
= aSSSI
->Next())
924 // we hope that we have only sd style sheets
925 SdStyleSheet
* pSdStyleSheet
= static_cast<SdStyleSheet
*>(pStyle
);
926 OUString
const curName(pStyle
->GetName());
927 sal_Int32
const curSep(curName
.indexOf(SD_LT_SEPARATOR
));
928 OUString
const curMaster((curSep
== -1)
929 ? OUString() : curName
.copy(0, curSep
));
930 // check that the master matches, as msApiName exists once per
932 if (pSdStyleSheet
->msApiName
== rParentName
&& master
== curMaster
)
941 throw NoSuchElementException();
945 SetParent( rParentName
);
951 Reference
< XPropertySetInfo
> SdStyleSheet::getPropertySetInfo()
954 static Reference
< XPropertySetInfo
> xInfo
= GetStylePropertySet().getPropertySetInfo();
958 void SAL_CALL
SdStyleSheet::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
960 SolarMutexGuard aGuard
;
963 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( aPropertyName
);
964 if( pEntry
== nullptr )
966 throw UnknownPropertyException( aPropertyName
, static_cast<cppu::OWeakObject
*>(this));
969 if( pEntry
->nWID
== WID_STYLE_HIDDEN
)
972 if ( aValue
>>= bValue
)
976 if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
977 return; // not yet implemented for styles
979 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
980 throw PropertyVetoException();
982 if( (pEntry
->nWID
== EE_PARA_NUMBULLET
) && (GetFamily() == SfxStyleFamily::Page
) )
985 const sal_uInt32 nTempHelpId
= GetHelpId( aStr
);
987 if( (nTempHelpId
>= HID_PSEUDOSHEET_OUTLINE2
) && (nTempHelpId
<= HID_PSEUDOSHEET_OUTLINE9
) )
991 SfxItemSet
&rStyleSet
= GetItemSet();
993 if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
996 if( aValue
>>= eMode
)
998 rStyleSet
.Put( XFillBmpStretchItem( eMode
== BitmapMode_STRETCH
) );
999 rStyleSet
.Put( XFillBmpTileItem( eMode
== BitmapMode_REPEAT
) );
1002 throw IllegalArgumentException();
1005 SfxItemSet
aSet( GetPool()->GetPool(), {{pEntry
->nWID
, pEntry
->nWID
}});
1006 aSet
.Put( rStyleSet
);
1010 if( EE_PARA_NUMBULLET
== pEntry
->nWID
)
1012 vcl::Font aBulletFont
;
1013 SdStyleSheetPool::PutNumBulletItem( this, aBulletFont
);
1014 aSet
.Put( rStyleSet
);
1018 aSet
.Put( GetPool()->GetPool().GetDefaultItem( pEntry
->nWID
) );
1022 if( pEntry
->nMemberId
== MID_NAME
&&
1023 ( pEntry
->nWID
== XATTR_FILLBITMAP
|| pEntry
->nWID
== XATTR_FILLGRADIENT
||
1024 pEntry
->nWID
== XATTR_FILLHATCH
|| pEntry
->nWID
== XATTR_FILLFLOATTRANSPARENCE
||
1025 pEntry
->nWID
== XATTR_LINESTART
|| pEntry
->nWID
== XATTR_LINEEND
|| pEntry
->nWID
== XATTR_LINEDASH
) )
1028 if(!(aValue
>>= aTempName
))
1029 throw IllegalArgumentException();
1031 SvxShape::SetFillAttribute( pEntry
->nWID
, aTempName
, aSet
);
1033 else if(!SvxUnoTextRangeBase::SetPropertyValueHelper( pEntry
, aValue
, aSet
))
1035 SvxItemPropertySet_setPropertyValue( pEntry
, aValue
, aSet
);
1038 rStyleSet
.Put( aSet
);
1039 Broadcast(SfxHint(SfxHintId::DataChanged
));
1043 Any SAL_CALL
SdStyleSheet::getPropertyValue( const OUString
& PropertyName
)
1045 SolarMutexGuard aGuard
;
1049 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( PropertyName
);
1050 if( pEntry
== nullptr )
1052 throw UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
1057 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
1059 if( nFamily
== SfxStyleFamily::Page
)
1061 const OUString
aLayoutName( GetName() );
1062 aAny
<<= aLayoutName
.copy( 0, aLayoutName
.indexOf( SD_LT_SEPARATOR
) );
1066 aAny
<<= GetFamilyString(nFamily
);
1069 else if( pEntry
->nWID
== WID_STYLE_DISPNAME
)
1071 OUString aDisplayName
;
1072 if ( nFamily
== SfxStyleFamily::Page
)
1074 const SdStyleSheet
* pStyleSheet
= GetPseudoStyleSheet();
1075 if (pStyleSheet
!= nullptr)
1076 aDisplayName
= pStyleSheet
->GetName();
1079 if (aDisplayName
.isEmpty())
1080 aDisplayName
= GetName();
1082 aAny
<<= aDisplayName
;
1084 else if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
1088 else if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1090 SfxItemSet
&rStyleSet
= GetItemSet();
1092 const XFillBmpStretchItem
* pStretchItem
= rStyleSet
.GetItem
<XFillBmpStretchItem
>(XATTR_FILLBMP_STRETCH
);
1093 const XFillBmpTileItem
* pTileItem
= rStyleSet
.GetItem
<XFillBmpTileItem
>(XATTR_FILLBMP_TILE
);
1095 if( pStretchItem
&& pTileItem
)
1097 if( pTileItem
->GetValue() )
1098 aAny
<<= BitmapMode_REPEAT
;
1099 else if( pStretchItem
->GetValue() )
1100 aAny
<<= BitmapMode_STRETCH
;
1102 aAny
<<= BitmapMode_NO_REPEAT
;
1105 else if( pEntry
->nWID
== WID_STYLE_HIDDEN
)
1107 aAny
<<= IsHidden( );
1111 SfxItemSet
aSet( GetPool()->GetPool(), {{pEntry
->nWID
, pEntry
->nWID
}});
1113 const SfxPoolItem
* pItem
;
1114 SfxItemSet
& rStyleSet
= GetItemSet();
1116 if( rStyleSet
.GetItemState( pEntry
->nWID
, true, &pItem
) == SfxItemState::SET
)
1120 aSet
.Put( GetPool()->GetPool().GetDefaultItem( pEntry
->nWID
) );
1122 if(SvxUnoTextRangeBase::GetPropertyValueHelper( aSet
, pEntry
, aAny
))
1125 // Get value of ItemSet
1126 aAny
= SvxItemPropertySet_getPropertyValue( pEntry
, aSet
);
1129 if( pEntry
->aType
!= aAny
.getValueType() )
1131 // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
1132 if( ( pEntry
->aType
== ::cppu::UnoType
<sal_Int16
>::get()) && aAny
.getValueType() == ::cppu::UnoType
<sal_Int32
>::get() )
1134 sal_Int32 nValue
= 0;
1136 aAny
<<= static_cast<sal_Int16
>(nValue
);
1140 OSL_FAIL("SvxShape::GetAnyForItem() Returnvalue has wrong Type!" );
1148 void SAL_CALL
SdStyleSheet::addPropertyChangeListener( const OUString
& , const Reference
< XPropertyChangeListener
>& ) {}
1149 void SAL_CALL
SdStyleSheet::removePropertyChangeListener( const OUString
& , const Reference
< XPropertyChangeListener
>& ) {}
1150 void SAL_CALL
SdStyleSheet::addVetoableChangeListener( const OUString
& , const Reference
< XVetoableChangeListener
>& ) {}
1151 void SAL_CALL
SdStyleSheet::removeVetoableChangeListener( const OUString
& , const Reference
< XVetoableChangeListener
>& ) {}
1155 PropertyState SAL_CALL
SdStyleSheet::getPropertyState( const OUString
& PropertyName
)
1157 SolarMutexGuard aGuard
;
1161 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( PropertyName
);
1163 if( pEntry
== nullptr )
1164 throw UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
1166 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
1168 return PropertyState_DIRECT_VALUE
;
1170 else if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
1172 return PropertyState_DEFAULT_VALUE
;
1174 else if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1176 const SfxItemSet
& rSet
= GetItemSet();
1178 if( rSet
.GetItemState( XATTR_FILLBMP_STRETCH
, false ) == SfxItemState::SET
||
1179 rSet
.GetItemState( XATTR_FILLBMP_TILE
, false ) == SfxItemState::SET
)
1181 return PropertyState_DIRECT_VALUE
;
1185 return PropertyState_AMBIGUOUS_VALUE
;
1190 SfxItemSet
&rStyleSet
= GetItemSet();
1192 PropertyState eState
;
1194 switch( rStyleSet
.GetItemState( pEntry
->nWID
, false ) )
1196 case SfxItemState::READONLY
:
1197 case SfxItemState::SET
:
1198 eState
= PropertyState_DIRECT_VALUE
;
1200 case SfxItemState::DEFAULT
:
1201 eState
= PropertyState_DEFAULT_VALUE
;
1204 eState
= PropertyState_AMBIGUOUS_VALUE
;
1208 // if an item is set, this doesn't mean we want it :)
1209 if( PropertyState_DIRECT_VALUE
== eState
)
1211 switch( pEntry
->nWID
)
1213 case XATTR_FILLBITMAP
:
1214 case XATTR_FILLGRADIENT
:
1215 case XATTR_FILLHATCH
:
1216 case XATTR_FILLFLOATTRANSPARENCE
:
1218 case XATTR_LINESTART
:
1219 case XATTR_LINEDASH
:
1221 const NameOrIndex
* pItem
= rStyleSet
.GetItem
<NameOrIndex
>(pEntry
->nWID
);
1222 if( ( pItem
== nullptr ) || pItem
->GetName().isEmpty() )
1223 eState
= PropertyState_DEFAULT_VALUE
;
1232 Sequence
< PropertyState
> SAL_CALL
SdStyleSheet::getPropertyStates( const Sequence
< OUString
>& aPropertyName
)
1234 SolarMutexGuard aGuard
;
1238 sal_Int32 nCount
= aPropertyName
.getLength();
1240 Sequence
< PropertyState
> aPropertyStateSequence( nCount
);
1242 std::transform(aPropertyName
.begin(), aPropertyName
.end(), aPropertyStateSequence
.begin(),
1243 [this](const OUString
& rName
) -> PropertyState
{ return getPropertyState(rName
); });
1245 return aPropertyStateSequence
;
1248 void SAL_CALL
SdStyleSheet::setPropertyToDefault( const OUString
& PropertyName
)
1250 SolarMutexGuard aGuard
;
1254 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( PropertyName
);
1255 if( pEntry
== nullptr )
1256 throw UnknownPropertyException( PropertyName
, static_cast<cppu::OWeakObject
*>(this));
1258 SfxItemSet
&rStyleSet
= GetItemSet();
1260 if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1262 rStyleSet
.ClearItem( XATTR_FILLBMP_STRETCH
);
1263 rStyleSet
.ClearItem( XATTR_FILLBMP_TILE
);
1267 rStyleSet
.ClearItem( pEntry
->nWID
);
1269 Broadcast(SfxHint(SfxHintId::DataChanged
));
1272 Any SAL_CALL
SdStyleSheet::getPropertyDefault( const OUString
& aPropertyName
)
1274 SolarMutexGuard aGuard
;
1278 const SfxItemPropertySimpleEntry
* pEntry
= getPropertyMapEntry( aPropertyName
);
1279 if( pEntry
== nullptr )
1280 throw UnknownPropertyException( aPropertyName
, static_cast<cppu::OWeakObject
*>(this));
1282 if( pEntry
->nWID
== WID_STYLE_FAMILY
)
1284 aRet
<<= GetFamilyString(nFamily
);
1286 else if( pEntry
->nWID
== SDRATTR_TEXTDIRECTION
)
1290 else if( pEntry
->nWID
== OWN_ATTR_FILLBMP_MODE
)
1292 aRet
<<= BitmapMode_REPEAT
;
1296 SfxItemPool
& rMyPool
= GetPool()->GetPool();
1297 SfxItemSet
aSet( rMyPool
, {{pEntry
->nWID
, pEntry
->nWID
}});
1298 aSet
.Put( rMyPool
.GetDefaultItem( pEntry
->nWID
) );
1299 aRet
= SvxItemPropertySet_getPropertyValue( pEntry
, aSet
);
1304 /** this is used because our property map is not sorted yet */
1305 const SfxItemPropertySimpleEntry
* SdStyleSheet::getPropertyMapEntry( const OUString
& rPropertyName
)
1307 return GetStylePropertySet().getPropertyMapEntry(rPropertyName
);
1310 //Broadcast that a SdStyleSheet has changed, taking into account outline sublevels
1311 //which need to be explicitly broadcast as changing if their parent style was
1312 //the one that changed
1313 void SdStyleSheet::BroadcastSdStyleSheetChange(SfxStyleSheetBase
const * pStyleSheet
,
1314 PresentationObjects ePO
, SfxStyleSheetBasePool
* pSSPool
)
1316 SdStyleSheet
* pRealSheet
= static_cast<SdStyleSheet
const *>(pStyleSheet
)->GetRealStyleSheet();
1317 pRealSheet
->Broadcast(SfxHint(SfxHintId::DataChanged
));
1319 if( !((ePO
>= PO_OUTLINE_1
) && (ePO
<= PO_OUTLINE_8
)) )
1322 OUString
sStyleName(SdResId(STR_PSEUDOSHEET_OUTLINE
) + " ");
1324 for( sal_uInt16 n
= static_cast<sal_uInt16
>(ePO
- PO_OUTLINE_1
+ 2); n
< 10; n
++ )
1326 OUString
aName( sStyleName
+ OUString::number(n
) );
1328 SfxStyleSheetBase
* pSheet
= pSSPool
->Find( aName
, SfxStyleFamily::Pseudo
);
1332 SdStyleSheet
* pRealStyleSheet
= static_cast<SdStyleSheet
*>(pSheet
)->GetRealStyleSheet();
1333 pRealStyleSheet
->Broadcast(SfxHint(SfxHintId::DataChanged
));
1338 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */