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 <document.hxx>
21 #include <stlsheet.hxx>
22 #include <stlpool.hxx>
24 #include <scitems.hxx>
25 #include <editeng/boxitem.hxx>
26 #include <editeng/frmdiritem.hxx>
27 #include <editeng/lrspitem.hxx>
28 #include <svx/pageitem.hxx>
29 #include <svx/svddef.hxx>
30 #include <svx/svdpool.hxx>
31 #include <svx/xdef.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <editeng/paperinf.hxx>
34 #include <editeng/shaditem.hxx>
35 #include <editeng/sizeitem.hxx>
36 #include <editeng/ulspitem.hxx>
37 #include <editeng/xmlcnitm.hxx>
38 #include <svl/itempool.hxx>
39 #include <svl/itemset.hxx>
40 #include <svl/numformat.hxx>
41 #include <svl/hint.hxx>
42 #include <o3tl/unit_conversion.hxx>
45 #include <globstr.hrc>
46 #include <scresid.hxx>
49 constexpr auto TWO_CM
= o3tl::convert(2, o3tl::Length::cm
, o3tl::Length::twip
); // 1134
50 constexpr auto HFDIST_CM
= o3tl::convert(250, o3tl::Length::mm100
, o3tl::Length::twip
); // 142
52 ScStyleSheet::ScStyleSheet( const OUString
& rName
,
53 const ScStyleSheetPool
& rPoolP
,
54 SfxStyleFamily eFamily
,
55 SfxStyleSearchBits nMaskP
,
56 const OUString
& rParentStyleSheetName
)
58 : SfxStyleSheet ( rName
, rPoolP
, eFamily
, nMaskP
, rParentStyleSheetName
)
59 , eUsage( Usage::UNKNOWN
)
63 ScStyleSheet::ScStyleSheet( const ScStyleSheet
& rStyle
)
64 : SfxStyleSheet ( rStyle
)
65 , eUsage( Usage::UNKNOWN
)
69 ScStyleSheet::~ScStyleSheet()
73 bool ScStyleSheet::HasFollowSupport() const
78 bool ScStyleSheet::HasParentSupport () const
80 bool bHasParentSupport
= false;
82 switch ( GetFamily() )
84 case SfxStyleFamily::Para
: bHasParentSupport
= true; break;
85 case SfxStyleFamily::Frame
: bHasParentSupport
= true; break;
86 case SfxStyleFamily::Page
: bHasParentSupport
= false; break;
89 // added to avoid warnings
93 return bHasParentSupport
;
96 bool ScStyleSheet::SetParent( const OUString
& rParentName
)
99 OUString aEffName
= rParentName
;
100 SfxStyleSheetBase
* pStyle
= m_pPool
->Find( aEffName
, nFamily
);
103 std::unique_ptr
<SfxStyleSheetIterator
> pIter
= m_pPool
->CreateIterator(nFamily
);
104 pStyle
= pIter
->First();
106 aEffName
= pStyle
->GetName();
109 if ( pStyle
&& aEffName
!= GetName() )
111 bResult
= SfxStyleSheet::SetParent( aEffName
);
114 SfxItemSet
& rParentSet
= pStyle
->GetItemSet();
115 GetItemSet().SetParent( &rParentSet
);
117 // #i113491# Drag&Drop in the stylist's hierarchical view doesn't execute a slot,
118 // so the repaint has to come from here (after modifying the ItemSet).
119 // RepaintRange checks the document's IsVisible flag and locked repaints.
120 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(GetPool())->GetDocument();
122 pDoc
->RepaintRange( ScRange( 0,0,0, pDoc
->MaxCol(),pDoc
->MaxRow(),MAXTAB
) );
129 void ScStyleSheet::ResetParent()
131 GetItemSet().SetParent(nullptr);
134 SfxItemSet
& ScStyleSheet::GetItemSet()
138 switch ( GetFamily() )
140 case SfxStyleFamily::Page
:
142 // Page templates should not be derivable,
143 // therefore suitable values are set at this point.
144 // (== Standard page template)
146 SfxItemPool
& rItemPool
= GetPool()->GetPool();
147 pSet
= new SfxItemSetFixed
<
148 ATTR_USERDEF
, ATTR_USERDEF
,
149 ATTR_WRITINGDIR
, ATTR_WRITINGDIR
,
150 ATTR_BACKGROUND
, ATTR_BACKGROUND
,
151 ATTR_BORDER
, ATTR_SHADOW
,
152 ATTR_LRSPACE
, ATTR_PAGE_SCALETO
>(rItemPool
);
154 // If being loaded also the set is then filled in from the file,
155 // so the defaults do not need to be set.
156 // GetPrinter would then also create a new printer,
157 // because the stored Printer is not loaded yet!
159 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(GetPool())->GetDocument();
162 // Setting reasonable default values:
163 SvxPageItem
aPageItem( ATTR_PAGE
);
164 SvxSizeItem
aPaperSizeItem( ATTR_PAGE_SIZE
, SvxPaperInfo::GetDefaultPaperSize() );
166 SvxSetItem
aHFSetItem(
167 rItemPool
.GetUserOrPoolDefaultItem(ATTR_PAGE_HEADERSET
) );
169 SfxItemSet
& rHFSet
= aHFSetItem
.GetItemSet();
170 SvxSizeItem
aHFSizeItem( // 0,5 cm + distance
172 Size( 0, o3tl::convert(500, o3tl::Length::mm100
, o3tl::Length::twip
) + HFDIST_CM
) );
174 SvxULSpaceItem
aHFDistItem ( HFDIST_CM
,// nUp
178 SvxLRSpaceItem
aLRSpaceItem(SvxIndentValue::twips(TWO_CM
), // nLeft
179 SvxIndentValue::twips(TWO_CM
), // nRight
180 SvxIndentValue::zero(), // nFirstLineOffset
182 SvxULSpaceItem
aULSpaceItem( TWO_CM
, // nUp
185 SvxBoxInfoItem
aBoxInfoItem( ATTR_BORDER_INNER
);
187 aBoxInfoItem
.SetTable( false );
188 aBoxInfoItem
.SetDist( true );
189 aBoxInfoItem
.SetValid( SvxBoxInfoItemValidFlags::DISTANCE
);
191 aPageItem
.SetLandscape( false );
193 rHFSet
.Put( aBoxInfoItem
);
194 rHFSet
.Put( aHFSizeItem
);
195 rHFSet
.Put( aHFDistItem
);
196 rHFSet
.Put(SvxLRSpaceItem(SvxIndentValue::zero(), SvxIndentValue::zero(),
197 SvxIndentValue::zero(),
198 ATTR_LRSPACE
)); // Set border to Null
200 aHFSetItem
.SetWhich(ATTR_PAGE_HEADERSET
);
201 pSet
->Put( aHFSetItem
);
202 aHFSetItem
.SetWhich(ATTR_PAGE_FOOTERSET
);
203 pSet
->Put( aHFSetItem
);
204 pSet
->Put( aBoxInfoItem
); // Do not overwrite PoolDefault
205 // due to format templates
208 // Writing direction: not as pool default because the default for cells
209 // must remain SvxFrameDirection::Environment, and each page style's setting is
210 // supposed to be saved in the file format.
211 // The page default depends on the system language.
212 SvxFrameDirection eDirection
= ScGlobal::IsSystemRTL() ?
213 SvxFrameDirection::Horizontal_RL_TB
: SvxFrameDirection::Horizontal_LR_TB
;
214 pSet
->Put( SvxFrameDirectionItem( eDirection
, ATTR_WRITINGDIR
) );
216 rItemPool
.SetUserDefaultItem( aPageItem
);
217 rItemPool
.SetUserDefaultItem( aPaperSizeItem
);
218 rItemPool
.SetUserDefaultItem( aLRSpaceItem
);
219 rItemPool
.SetUserDefaultItem( aULSpaceItem
);
220 rItemPool
.SetUserDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALE
, 100 ) );
221 ScPageScaleToItem aScaleToItem
;
222 rItemPool
.SetUserDefaultItem( aScaleToItem
);
223 rItemPool
.SetUserDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES
, 0 ) );
228 case SfxStyleFamily::Frame
:
230 SfxItemPool
* pItemPool
= &GetPool()->GetPool();
232 if (dynamic_cast<SdrItemPool
*>(pItemPool
) == nullptr)
233 pItemPool
= pItemPool
->GetSecondaryPool();
236 pSet
= new SfxItemSetFixed
<
237 XATTR_LINE_FIRST
, XATTR_LINE_LAST
,
238 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
239 SDRATTR_SHADOW_FIRST
, SDRATTR_SHADOW_LAST
,
240 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_TEXT_WORDWRAP
,
241 SDRATTR_EDGE_FIRST
, SDRATTR_MEASURE_LAST
,
242 SDRATTR_3D_FIRST
, SDRATTR_3D_LAST
,
243 EE_PARA_START
, EE_CHAR_END
>(*pItemPool
);
247 case SfxStyleFamily::Para
:
249 pSet
= new SfxItemSetFixed
<ATTR_PATTERN_START
, ATTR_PATTERN_END
>( GetPool()->GetPool() );
254 if ( nHelpId
== HID_SC_SHEET_CELL_ERG1
)
256 if ( !pSet
->Count() )
258 // Hack to work around that when this code is called from
259 // ~ScStyleSheetPool -> ~SfxStyleSheetPool, GetPool() is no longer
260 // an ScStyleSheetPool:
261 ScStyleSheetPool
* pool
= dynamic_cast<ScStyleSheetPool
*>(
263 if (pool
!= nullptr) {
264 ScDocument
* pDoc
= pool
->GetDocument();
267 sal_uInt32 nNumFmt
= pDoc
->GetFormatTable()->GetStandardFormat( SvNumFormatType::CURRENCY
,ScGlobal::eLnge
);
268 pSet
->Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNumFmt
) );
277 bool ScStyleSheet::IsUsed() const
281 case SfxStyleFamily::Para
:
283 // Always query the document to let it decide if a rescan is necessary,
284 // and store the state.
285 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(m_pPool
)->GetDocument();
286 if ( pDoc
&& pDoc
->IsStyleSheetUsed( *this ) )
287 eUsage
= Usage::USED
;
289 eUsage
= Usage::NOTUSED
;
290 return eUsage
== Usage::USED
;
292 case SfxStyleFamily::Page
:
294 // tdf#108188 - verify that the page style is actually used
295 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(m_pPool
)->GetDocument();
296 if (pDoc
&& pDoc
->IsPageStyleInUse(GetName(), nullptr))
297 eUsage
= Usage::USED
;
299 eUsage
= Usage::NOTUSED
;
300 return eUsage
== Usage::USED
;
302 case SfxStyleFamily::Frame
:
304 ForAllListeners([this] (SfxListener
* pListener
)
306 auto pUser(dynamic_cast<svl::StyleSheetUser
*>(pListener
));
307 if (pUser
&& pUser
->isUsedByModel())
309 eUsage
= Usage::USED
;
310 return true; // break loop
313 eUsage
= Usage::NOTUSED
;
316 return eUsage
== Usage::USED
;
323 void ScStyleSheet::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
325 if ( rHint
.GetId() == SfxHintId::Dying
)
326 GetItemSet().SetParent( nullptr );
327 if (GetFamily() == SfxStyleFamily::Frame
)
328 SfxStyleSheet::Notify(rBC
, rHint
);
331 // Avoid creating a Style "Standard" if this is not the Standard-Name;
332 // otherwise two styles would have the same name when storing.
333 // (on loading the style is created directly per Make with the name; making this query
335 //TODO: If at any time during loading SetName is called, a flag has to be set/checked for loading
336 //TODO: The whole check has to be removed if for a new file version the name transformation is dropped.
338 bool ScStyleSheet::SetName(const OUString
& rNew
, bool bReindexNow
)
340 OUString aFileStdName
= STRING_STANDARD
;
341 if ( rNew
== aFileStdName
&& aFileStdName
!= ScResId(STR_STYLENAME_STANDARD
) )
344 return SfxStyleSheet::SetName(rNew
, bReindexNow
);
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */