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 <document.hxx>
21 #include <stlsheet.hxx>
22 #include <stlpool.hxx>
23
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 <editeng/paperinf.hxx>
30 #include <editeng/shaditem.hxx>
31 #include <editeng/sizeitem.hxx>
32 #include <editeng/ulspitem.hxx>
33 #include <editeng/xmlcnitm.hxx>
34 #include <svl/itempool.hxx>
35 #include <svl/itemset.hxx>
36 #include <svl/hint.hxx>
37 #include <o3tl/unit_conversion.hxx>
38 #include <attrib.hxx>
39
40 #include <globstr.hrc>
41 #include <scresid.hxx>
42 #include <sc.hrc>
43
44 constexpr auto TWO_CM = o3tl::convert(2, o3tl::Length::cm, o3tl::Length::twip); // 1134
45 constexpr auto HFDIST_CM = o3tl::convert(250, o3tl::Length::mm100, o3tl::Length::twip); // 142
46
ScStyleSheet(const OUString & rName,const ScStyleSheetPool & rPoolP,SfxStyleFamily eFamily,SfxStyleSearchBits nMaskP)47 ScStyleSheet::ScStyleSheet( const OUString& rName,
48 const ScStyleSheetPool& rPoolP,
49 SfxStyleFamily eFamily,
50 SfxStyleSearchBits nMaskP )
51
52 : SfxStyleSheet ( rName, rPoolP, eFamily, nMaskP )
53 , eUsage( Usage::UNKNOWN )
54 {
55 }
56
ScStyleSheet(const ScStyleSheet & rStyle)57 ScStyleSheet::ScStyleSheet( const ScStyleSheet& rStyle )
58 : SfxStyleSheet ( rStyle )
59 , eUsage( Usage::UNKNOWN )
60 {
61 }
62
~ScStyleSheet()63 ScStyleSheet::~ScStyleSheet()
64 {
65 }
66
HasFollowSupport() const67 bool ScStyleSheet::HasFollowSupport() const
68 {
69 return false;
70 }
71
HasParentSupport() const72 bool ScStyleSheet::HasParentSupport () const
73 {
74 bool bHasParentSupport = false;
75
76 switch ( GetFamily() )
77 {
78 case SfxStyleFamily::Para: bHasParentSupport = true; break;
79 case SfxStyleFamily::Page: bHasParentSupport = false; break;
80 default:
81 {
82 // added to avoid warnings
83 }
84 }
85
86 return bHasParentSupport;
87 }
88
SetParent(const OUString & rParentName)89 bool ScStyleSheet::SetParent( const OUString& rParentName )
90 {
91 bool bResult = false;
92 OUString aEffName = rParentName;
93 SfxStyleSheetBase* pStyle = m_pPool->Find( aEffName, nFamily );
94 if (!pStyle)
95 {
96 std::unique_ptr<SfxStyleSheetIterator> pIter = m_pPool->CreateIterator(nFamily);
97 pStyle = pIter->First();
98 if (pStyle)
99 aEffName = pStyle->GetName();
100 }
101
102 if ( pStyle && aEffName != GetName() )
103 {
104 bResult = SfxStyleSheet::SetParent( aEffName );
105 if (bResult)
106 {
107 SfxItemSet& rParentSet = pStyle->GetItemSet();
108 GetItemSet().SetParent( &rParentSet );
109
110 // #i113491# Drag&Drop in the stylist's hierarchical view doesn't execute a slot,
111 // so the repaint has to come from here (after modifying the ItemSet).
112 // RepaintRange checks the document's IsVisible flag and locked repaints.
113 ScDocument* pDoc = static_cast<ScStyleSheetPool*>(GetPool())->GetDocument();
114 if (pDoc)
115 pDoc->RepaintRange( ScRange( 0,0,0, MAXCOL,MAXROW,MAXTAB ) );
116 }
117 }
118
119 return bResult;
120 }
121
ResetParent()122 void ScStyleSheet::ResetParent()
123 {
124 GetItemSet().SetParent(nullptr);
125 }
126
GetItemSet()127 SfxItemSet& ScStyleSheet::GetItemSet()
128 {
129 if ( !pSet )
130 {
131 switch ( GetFamily() )
132 {
133 case SfxStyleFamily::Page:
134 {
135 // Page templates should not be derivable,
136 // therefore suitable values are set at this point.
137 // (== Standard page template)
138
139 SfxItemPool& rItemPool = GetPool()->GetPool();
140 pSet = new SfxItemSet(
141 rItemPool,
142 svl::Items<
143 ATTR_USERDEF, ATTR_USERDEF,
144 ATTR_WRITINGDIR, ATTR_WRITINGDIR,
145 ATTR_BACKGROUND, ATTR_BACKGROUND,
146 ATTR_BORDER, ATTR_SHADOW,
147 ATTR_LRSPACE, ATTR_PAGE_SCALETO>{} );
148
149 // If being loaded also the set is then filled in from the file,
150 // so the defaults do not need to be set.
151 // GetPrinter would then also create a new printer,
152 // because the stored Printer is not loaded yet!
153
154 ScDocument* pDoc = static_cast<ScStyleSheetPool*>(GetPool())->GetDocument();
155 if ( pDoc )
156 {
157 // Setting reasonable default values:
158 SvxPageItem aPageItem( ATTR_PAGE );
159 SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetDefaultPaperSize() );
160
161 SvxSetItem aHFSetItem(
162 rItemPool.GetDefaultItem(ATTR_PAGE_HEADERSET) );
163
164 SfxItemSet& rHFSet = aHFSetItem.GetItemSet();
165 SvxSizeItem aHFSizeItem( // 0,5 cm + distance
166 ATTR_PAGE_SIZE,
167 Size( 0, o3tl::convert(500, o3tl::Length::mm100, o3tl::Length::twip) + HFDIST_CM ) );
168
169 SvxULSpaceItem aHFDistItem ( HFDIST_CM,// nUp
170 HFDIST_CM,// nLow
171 ATTR_ULSPACE );
172
173 SvxLRSpaceItem aLRSpaceItem( TWO_CM, // nLeft
174 TWO_CM, // nRight
175 TWO_CM, // nTLeft
176 0, // nFirstLineOffset
177 ATTR_LRSPACE );
178 SvxULSpaceItem aULSpaceItem( TWO_CM, // nUp
179 TWO_CM, // nLow
180 ATTR_ULSPACE );
181 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
182
183 aBoxInfoItem.SetTable( false );
184 aBoxInfoItem.SetDist( true );
185 aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
186
187 aPageItem.SetLandscape( false );
188
189 rHFSet.Put( aBoxInfoItem );
190 rHFSet.Put( aHFSizeItem );
191 rHFSet.Put( aHFDistItem );
192 rHFSet.Put( SvxLRSpaceItem( 0,0,0,0, ATTR_LRSPACE ) ); // Set border to Null
193
194 aHFSetItem.SetWhich(ATTR_PAGE_HEADERSET);
195 pSet->Put( aHFSetItem );
196 aHFSetItem.SetWhich(ATTR_PAGE_FOOTERSET);
197 pSet->Put( aHFSetItem );
198 pSet->Put( aBoxInfoItem ); // Do not overwrite PoolDefault
199 // due to format templates
200
201
202 // Writing direction: not as pool default because the default for cells
203 // must remain SvxFrameDirection::Environment, and each page style's setting is
204 // supposed to be saved in the file format.
205 // The page default depends on the system language.
206 SvxFrameDirection eDirection = ScGlobal::IsSystemRTL() ?
207 SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB;
208 pSet->Put( SvxFrameDirectionItem( eDirection, ATTR_WRITINGDIR ) );
209
210 rItemPool.SetPoolDefaultItem( aPageItem );
211 rItemPool.SetPoolDefaultItem( aPaperSizeItem );
212 rItemPool.SetPoolDefaultItem( aLRSpaceItem );
213 rItemPool.SetPoolDefaultItem( aULSpaceItem );
214 rItemPool.SetPoolDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALE, 100 ) );
215 ScPageScaleToItem aScaleToItem;
216 rItemPool.SetPoolDefaultItem( aScaleToItem );
217 rItemPool.SetPoolDefaultItem( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, 0 ) );
218 }
219 }
220 break;
221
222 case SfxStyleFamily::Para:
223 default:
224 pSet = new SfxItemSet( GetPool()->GetPool(), svl::Items<ATTR_PATTERN_START, ATTR_PATTERN_END>{} );
225 break;
226 }
227 bMySet = true;
228 }
229 if ( nHelpId == HID_SC_SHEET_CELL_ERG1 )
230 {
231 if ( !pSet->Count() )
232 {
233 // Hack to work around that when this code is called from
234 // ~ScStyleSheetPool -> ~SfxStyleSheetPool, GetPool() is no longer
235 // an ScStyleSheetPool:
236 ScStyleSheetPool * pool = dynamic_cast<ScStyleSheetPool *>(
237 GetPool());
238 if (pool != nullptr) {
239 ScDocument* pDoc = pool->GetDocument();
240 if ( pDoc )
241 {
242 sal_uInt32 nNumFmt = pDoc->GetFormatTable()->GetStandardFormat( SvNumFormatType::CURRENCY,ScGlobal::eLnge );
243 pSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumFmt ) );
244 }
245 }
246 }
247 }
248
249 return *pSet;
250 }
251
IsUsed() const252 bool ScStyleSheet::IsUsed() const
253 {
254 if ( GetFamily() == SfxStyleFamily::Para )
255 {
256 // Always query the document to let it decide if a rescan is necessary,
257 // and store the state.
258 ScDocument* pDoc = static_cast<ScStyleSheetPool*>(m_pPool)->GetDocument();
259 if ( pDoc && pDoc->IsStyleSheetUsed( *this ) )
260 eUsage = Usage::USED;
261 else
262 eUsage = Usage::NOTUSED;
263 return eUsage == Usage::USED;
264 }
265 else
266 return true;
267 }
268
Notify(SfxBroadcaster &,const SfxHint & rHint)269 void ScStyleSheet::Notify( SfxBroadcaster&, const SfxHint& rHint )
270 {
271 if ( rHint.GetId() == SfxHintId::Dying )
272 GetItemSet().SetParent( nullptr );
273 }
274
275 // Avoid creating a Style "Standard" if this is not the Standard-Name;
276 // otherwise two styles would have the same name when storing.
277 // (on loading the style is created directly per Make with the name; making this query
278 // not applicable)
279 //TODO: If at any time during loading SetName is called, a flag has to be set/checked for loading
280 //TODO: The whole check has to be removed if for a new file version the name transformation is dropped.
281
SetName(const OUString & rNew,bool bReindexNow)282 bool ScStyleSheet::SetName(const OUString& rNew, bool bReindexNow)
283 {
284 OUString aFileStdName = STRING_STANDARD;
285 if ( rNew == aFileStdName && aFileStdName != ScResId(STR_STYLENAME_STANDARD) )
286 return false;
287 else
288 return SfxStyleSheet::SetName(rNew, bReindexNow);
289 }
290
291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
292