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