Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / sc / source / core / data / stlsheet.cxx
blob47b861756337a00bb7e1016e23961844a99ff22e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
43 #include <attrib.hxx>
45 #include <globstr.hrc>
46 #include <scresid.hxx>
47 #include <sc.hrc>
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
75 return false;
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;
87 default:
89 // added to avoid warnings
93 return bHasParentSupport;
96 bool ScStyleSheet::SetParent( const OUString& rParentName )
98 bool bResult = false;
99 OUString aEffName = rParentName;
100 SfxStyleSheetBase* pStyle = m_pPool->Find( aEffName, nFamily );
101 if (!pStyle)
103 std::unique_ptr<SfxStyleSheetIterator> pIter = m_pPool->CreateIterator(nFamily);
104 pStyle = pIter->First();
105 if (pStyle)
106 aEffName = pStyle->GetName();
109 if ( pStyle && aEffName != GetName() )
111 bResult = SfxStyleSheet::SetParent( aEffName );
112 if (bResult)
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();
121 if (pDoc)
122 pDoc->RepaintRange( ScRange( 0,0,0, pDoc->MaxCol(),pDoc->MaxRow(),MAXTAB ) );
126 return bResult;
129 void ScStyleSheet::ResetParent()
131 GetItemSet().SetParent(nullptr);
134 SfxItemSet& ScStyleSheet::GetItemSet()
136 if ( !pSet )
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();
160 if ( pDoc )
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
171 ATTR_PAGE_SIZE,
172 Size( 0, o3tl::convert(500, o3tl::Length::mm100, o3tl::Length::twip) + HFDIST_CM ) );
174 SvxULSpaceItem aHFDistItem ( HFDIST_CM,// nUp
175 HFDIST_CM,// nLow
176 ATTR_ULSPACE );
178 SvxLRSpaceItem aLRSpaceItem(SvxIndentValue::twips(TWO_CM), // nLeft
179 SvxIndentValue::twips(TWO_CM), // nRight
180 SvxIndentValue::zero(), // nFirstLineOffset
181 ATTR_LRSPACE);
182 SvxULSpaceItem aULSpaceItem( TWO_CM, // nUp
183 TWO_CM, // nLow
184 ATTR_ULSPACE );
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 ) );
226 break;
228 case SfxStyleFamily::Frame:
230 SfxItemPool* pItemPool = &GetPool()->GetPool();
231 assert(pItemPool);
232 if (dynamic_cast<SdrItemPool*>(pItemPool) == nullptr)
233 pItemPool = pItemPool->GetSecondaryPool();
234 assert(pItemPool);
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);
245 break;
247 case SfxStyleFamily::Para:
248 default:
249 pSet = new SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END>( GetPool()->GetPool() );
250 break;
252 bMySet = true;
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 *>(
262 GetPool());
263 if (pool != nullptr) {
264 ScDocument* pDoc = pool->GetDocument();
265 if ( pDoc )
267 sal_uInt32 nNumFmt = pDoc->GetFormatTable()->GetStandardFormat( SvNumFormatType::CURRENCY,ScGlobal::eLnge );
268 pSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumFmt ) );
274 return *pSet;
277 bool ScStyleSheet::IsUsed() const
279 switch (GetFamily())
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;
288 else
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;
298 else
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
312 else
313 eUsage = Usage::NOTUSED;
314 return false;
316 return eUsage == Usage::USED;
318 default:
319 return true;
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
334 // not applicable)
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) )
342 return false;
343 else
344 return SfxStyleSheet::SetName(rNew, bReindexNow);
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */