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
