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