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
)
57 : SfxStyleSheet ( rName
, rPoolP
, eFamily
, nMaskP
)
58 , eUsage( Usage::UNKNOWN
)
62 ScStyleSheet::ScStyleSheet( const ScStyleSheet
& rStyle
)
63 : SfxStyleSheet ( rStyle
)
64 , eUsage( Usage::UNKNOWN
)
68 ScStyleSheet::~ScStyleSheet()
72 bool ScStyleSheet::HasFollowSupport() const
77 bool ScStyleSheet::HasParentSupport () const
79 bool bHasParentSupport
= false;
81 switch ( GetFamily() )
83 case SfxStyleFamily::Para
: bHasParentSupport
= true; break;
84 case SfxStyleFamily::Frame
: bHasParentSupport
= true; break;
85 case SfxStyleFamily::Page
: bHasParentSupport
= false; break;
88 // added to avoid warnings
92 return bHasParentSupport
;
95 bool ScStyleSheet::SetParent( const OUString
& rParentName
)
98 OUString aEffName
= rParentName
;
99 SfxStyleSheetBase
* pStyle
= m_pPool
->Find( aEffName
, nFamily
);
102 std::unique_ptr
<SfxStyleSheetIterator
> pIter
= m_pPool
->CreateIterator(nFamily
);
103 pStyle
= pIter
->First();
105 aEffName
= pStyle
->GetName();
108 if ( pStyle
&& aEffName
!= GetName() )
110 bResult
= SfxStyleSheet::SetParent( aEffName
);
113 SfxItemSet
& rParentSet
= pStyle
->GetItemSet();
114 GetItemSet().SetParent( &rParentSet
);
116 // #i113491# Drag&Drop in the stylist's hierarchical view doesn't execute a slot,
117 // so the repaint has to come from here (after modifying the ItemSet).
118 // RepaintRange checks the document's IsVisible flag and locked repaints.
119 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(GetPool())->GetDocument();
121 pDoc
->RepaintRange( ScRange( 0,0,0, pDoc
->MaxCol(),pDoc
->MaxRow(),MAXTAB
) );
128 void ScStyleSheet::ResetParent()
130 GetItemSet().SetParent(nullptr);
133 SfxItemSet
& ScStyleSheet::GetItemSet()
137 switch ( GetFamily() )
139 case SfxStyleFamily::Page
:
141 // Page templates should not be derivable,
142 // therefore suitable values are set at this point.
143 // (== Standard page template)
145 SfxItemPool
& rItemPool
= GetPool()->GetPool();
146 pSet
= new SfxItemSetFixed
<
147 ATTR_USERDEF
, ATTR_USERDEF
,
148 ATTR_WRITINGDIR
, ATTR_WRITINGDIR
,
149 ATTR_BACKGROUND
, ATTR_BACKGROUND
,
150 ATTR_BORDER
, ATTR_SHADOW
,
151 ATTR_LRSPACE
, ATTR_PAGE_SCALETO
>(rItemPool
);
153 // If being loaded also the set is then filled in from the file,
154 // so the defaults do not need to be set.
155 // GetPrinter would then also create a new printer,
156 // because the stored Printer is not loaded yet!
158 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(GetPool())->GetDocument();
161 // Setting reasonable default values:
162 SvxPageItem
aPageItem( ATTR_PAGE
);
163 SvxSizeItem
aPaperSizeItem( ATTR_PAGE_SIZE
, SvxPaperInfo::GetDefaultPaperSize() );
165 SvxSetItem
aHFSetItem(
166 rItemPool
.GetDefaultItem(ATTR_PAGE_HEADERSET
) );
168 SfxItemSet
& rHFSet
= aHFSetItem
.GetItemSet();
169 SvxSizeItem
aHFSizeItem( // 0,5 cm + distance
171 Size( 0, o3tl::convert(500, o3tl::Length::mm100
, o3tl::Length::twip
) + HFDIST_CM
) );
173 SvxULSpaceItem
aHFDistItem ( HFDIST_CM
,// nUp
177 SvxLRSpaceItem
aLRSpaceItem( TWO_CM
, // nLeft
179 0, // nFirstLineOffset
181 SvxULSpaceItem
aULSpaceItem( TWO_CM
, // nUp
184 SvxBoxInfoItem
aBoxInfoItem( ATTR_BORDER_INNER
);
186 aBoxInfoItem
.SetTable( false );
187 aBoxInfoItem
.SetDist( true );
188 aBoxInfoItem
.SetValid( SvxBoxInfoItemValidFlags::DISTANCE
);
190 aPageItem
.SetLandscape( false );
192 rHFSet
.Put( aBoxInfoItem
);
193 rHFSet
.Put( aHFSizeItem
);
194 rHFSet
.Put( aHFDistItem
);
195 rHFSet
.Put( SvxLRSpaceItem(0, 0, 0, ATTR_LRSPACE
) ); // Set border to Null
197 aHFSetItem
.SetWhich(ATTR_PAGE_HEADERSET
);
198 pSet
->Put( aHFSetItem
);
199 aHFSetItem
.SetWhich(ATTR_PAGE_FOOTERSET
);
200 pSet
->Put( aHFSetItem
);
201 pSet
->Put( aBoxInfoItem
); // Do not overwrite PoolDefault
202 // due to format templates
205 // Writing direction: not as pool default because the default for cells
206 // must remain SvxFrameDirection::Environment, and each page style's setting is
207 // supposed to be saved in the file format.
208 // The page default depends on the system language.
209 SvxFrameDirection eDirection
= ScGlobal::IsSystemRTL() ?
210 SvxFrameDirection::Horizontal_RL_TB
: SvxFrameDirection::Horizontal_LR_TB
;
211 pSet
->Put( SvxFrameDirectionItem( eDirection
, ATTR_WRITINGDIR
) );
213 rItemPool
.SetPoolDefaultItem( aPageItem
);
214 rItemPool
.SetPoolDefaultItem( aPaperSizeItem
);
215 rItemPool
.SetPoolDefaultItem( aLRSpaceItem
);
216 rItemPool
.SetPoolDefaultItem( aULSpaceItem
);
217 rItemPool
.SetPoolDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALE
, 100 ) );
218 ScPageScaleToItem aScaleToItem
;
219 rItemPool
.SetPoolDefaultItem( aScaleToItem
);
220 rItemPool
.SetPoolDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES
, 0 ) );
225 case SfxStyleFamily::Frame
:
227 SfxItemPool
* pItemPool
= &GetPool()->GetPool();
228 if (dynamic_cast<SdrItemPool
*>(pItemPool
) == nullptr)
229 pItemPool
= pItemPool
->GetSecondaryPool();
232 pSet
= new SfxItemSetFixed
<
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_TEXT_WORDWRAP
,
237 SDRATTR_EDGE_FIRST
, SDRATTR_MEASURE_LAST
,
238 SDRATTR_3D_FIRST
, SDRATTR_3D_LAST
,
239 EE_PARA_START
, EE_CHAR_END
>(*pItemPool
);
243 case SfxStyleFamily::Para
:
245 pSet
= new SfxItemSetFixed
<ATTR_PATTERN_START
, ATTR_PATTERN_END
>( GetPool()->GetPool() );
250 if ( nHelpId
== HID_SC_SHEET_CELL_ERG1
)
252 if ( !pSet
->Count() )
254 // Hack to work around that when this code is called from
255 // ~ScStyleSheetPool -> ~SfxStyleSheetPool, GetPool() is no longer
256 // an ScStyleSheetPool:
257 ScStyleSheetPool
* pool
= dynamic_cast<ScStyleSheetPool
*>(
259 if (pool
!= nullptr) {
260 ScDocument
* pDoc
= pool
->GetDocument();
263 sal_uInt32 nNumFmt
= pDoc
->GetFormatTable()->GetStandardFormat( SvNumFormatType::CURRENCY
,ScGlobal::eLnge
);
264 pSet
->Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNumFmt
) );
273 bool ScStyleSheet::IsUsed() const
277 case SfxStyleFamily::Para
:
279 // Always query the document to let it decide if a rescan is necessary,
280 // and store the state.
281 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(m_pPool
)->GetDocument();
282 if ( pDoc
&& pDoc
->IsStyleSheetUsed( *this ) )
283 eUsage
= Usage::USED
;
285 eUsage
= Usage::NOTUSED
;
286 return eUsage
== Usage::USED
;
288 case SfxStyleFamily::Page
:
290 // tdf#108188 - verify that the page style is actually used
291 ScDocument
* pDoc
= static_cast<ScStyleSheetPool
*>(m_pPool
)->GetDocument();
292 if (pDoc
&& pDoc
->IsPageStyleInUse(GetName(), nullptr))
293 eUsage
= Usage::USED
;
295 eUsage
= Usage::NOTUSED
;
296 return eUsage
== Usage::USED
;
298 case SfxStyleFamily::Frame
:
300 ForAllListeners([this] (SfxListener
* pListener
)
302 auto pUser(dynamic_cast<svl::StyleSheetUser
*>(pListener
));
303 if (pUser
&& pUser
->isUsedByModel())
305 eUsage
= Usage::USED
;
306 return true; // break loop
309 eUsage
= Usage::NOTUSED
;
312 return eUsage
== Usage::USED
;
319 void ScStyleSheet::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
321 if ( rHint
.GetId() == SfxHintId::Dying
)
322 GetItemSet().SetParent( nullptr );
323 if (GetFamily() == SfxStyleFamily::Frame
)
324 SfxStyleSheet::Notify(rBC
, rHint
);
327 // Avoid creating a Style "Standard" if this is not the Standard-Name;
328 // otherwise two styles would have the same name when storing.
329 // (on loading the style is created directly per Make with the name; making this query
331 //TODO: If at any time during loading SetName is called, a flag has to be set/checked for loading
332 //TODO: The whole check has to be removed if for a new file version the name transformation is dropped.
334 bool ScStyleSheet::SetName(const OUString
& rNew
, bool bReindexNow
)
336 OUString aFileStdName
= STRING_STANDARD
;
337 if ( rNew
== aFileStdName
&& aFileStdName
!= ScResId(STR_STYLENAME_STANDARD
) )
340 return SfxStyleSheet::SetName(rNew
, bReindexNow
);
343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */