1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 28 #include <hintids.hxx> 29 #include <svl/whiter.hxx> 30 #include <editeng/colritem.hxx> 31 #include <editeng/brshitem.hxx> 32 #include <editeng/bolnitem.hxx> 33 #include <editeng/boxitem.hxx> 34 #include <svx/xtable.hxx> 35 #include <fmtpdsc.hxx> 36 #include <pagedesc.hxx> 37 #include <charfmt.hxx> 38 #include <doc.hxx> 39 #include <node.hxx> 40 #include <paratr.hxx> // fuer SetModifyAtAttr 41 #include <cellatr.hxx> // fuer SetModifyAtAttr 42 #ifndef _CMDID_H 43 #include <cmdid.h> 44 #endif 45 #include <istyleaccess.hxx> 46 #include <numrule.hxx> 47 // --> OD 2008-03-19 #refactorlists# 48 #include <list.hxx> 49 // <-- 50 51 52 SwAttrPool::SwAttrPool( SwDoc* pD ) 53 : SfxItemPool( String::CreateFromAscii( 54 RTL_CONSTASCII_STRINGPARAM( "SWG" )), 55 POOLATTR_BEGIN, POOLATTR_END-1, 56 aSlotTab, aAttrTab ), 57 pDoc( pD ) 58 { 59 SetVersionMap( 1, 1, 60, pVersionMap1 ); 60 SetVersionMap( 2, 1, 75, pVersionMap2 ); 61 SetVersionMap( 3, 1, 86, pVersionMap3 ); 62 SetVersionMap( 4, 1,121, pVersionMap4 ); 63 // OD 2004-01-21 #i18732# - apply new version map 64 SetVersionMap( 5, 1,130, pVersionMap5 ); 65 SetVersionMap( 6, 1,136, pVersionMap6 ); 66 } 67 68 SwAttrPool::~SwAttrPool() 69 { 70 } 71 72 SwAttrSet::SwAttrSet( SwAttrPool& rPool, sal_uInt16 nWh1, sal_uInt16 nWh2 ) 73 : SfxItemSet( rPool, nWh1, nWh2 ), pOldSet( 0 ), pNewSet( 0 ) 74 { 75 } 76 77 78 SwAttrSet::SwAttrSet( SwAttrPool& rPool, const sal_uInt16* nWhichPairTable ) 79 : SfxItemSet( rPool, nWhichPairTable ), pOldSet( 0 ), pNewSet( 0 ) 80 { 81 } 82 83 84 SwAttrSet::SwAttrSet( const SwAttrSet& rSet ) 85 : SfxItemSet( rSet ), pOldSet( 0 ), pNewSet( 0 ) 86 { 87 } 88 89 SfxItemSet* SwAttrSet::Clone( sal_Bool bItems, SfxItemPool *pToPool ) const 90 { 91 if ( pToPool && pToPool != GetPool() ) 92 { 93 SwAttrPool* pAttrPool = dynamic_cast< SwAttrPool* >(pToPool); 94 SfxItemSet* pTmpSet = 0; 95 if ( !pAttrPool ) 96 pTmpSet = SfxItemSet::Clone( bItems, pToPool ); 97 else 98 { 99 pTmpSet = new SwAttrSet( *pAttrPool, GetRanges() ); 100 if ( bItems ) 101 { 102 SfxWhichIter aIter(*pTmpSet); 103 sal_uInt16 nWhich = aIter.FirstWhich(); 104 while ( nWhich ) 105 { 106 const SfxPoolItem* pItem; 107 if ( SFX_ITEM_SET == GetItemState( nWhich, sal_False, &pItem ) ) 108 pTmpSet->Put( *pItem, pItem->Which() ); 109 nWhich = aIter.NextWhich(); 110 } 111 } 112 } 113 return pTmpSet; 114 } 115 else 116 return bItems 117 ? new SwAttrSet( *this ) 118 : new SwAttrSet( *GetPool(), GetRanges() ); 119 } 120 121 int SwAttrSet::Put_BC( const SfxPoolItem& rAttr, 122 SwAttrSet* pOld, SwAttrSet* pNew ) 123 { 124 pNewSet = pNew; 125 pOldSet = pOld; 126 int nRet = 0 != SfxItemSet::Put( rAttr ); 127 pOldSet = pNewSet = 0; 128 return nRet; 129 } 130 131 132 int SwAttrSet::Put_BC( const SfxItemSet& rSet, 133 SwAttrSet* pOld, SwAttrSet* pNew ) 134 { 135 pNewSet = pNew; 136 pOldSet = pOld; 137 int nRet = 0 != SfxItemSet::Put( rSet ); 138 pOldSet = pNewSet = 0; 139 return nRet; 140 } 141 142 143 144 sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich, 145 SwAttrSet* pOld, SwAttrSet* pNew ) 146 { 147 pNewSet = pNew; 148 pOldSet = pOld; 149 sal_uInt16 nRet = SfxItemSet::ClearItem( nWhich ); 150 pOldSet = pNewSet = 0; 151 return nRet; 152 } 153 154 155 sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich1, sal_uInt16 nWhich2, 156 SwAttrSet* pOld, SwAttrSet* pNew ) 157 { 158 ASSERT( nWhich1 <= nWhich2, "kein gueltiger Bereich" ); 159 pNewSet = pNew; 160 pOldSet = pOld; 161 sal_uInt16 nRet = 0; 162 for( ; nWhich1 <= nWhich2; ++nWhich1 ) 163 nRet = nRet + SfxItemSet::ClearItem( nWhich1 ); 164 pOldSet = pNewSet = 0; 165 return nRet; 166 } 167 168 169 170 int SwAttrSet::Intersect_BC( const SfxItemSet& rSet, 171 SwAttrSet* pOld, SwAttrSet* pNew ) 172 { 173 pNewSet = pNew; 174 pOldSet = pOld; 175 SfxItemSet::Intersect( rSet ); 176 pOldSet = pNewSet = 0; 177 return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 ); 178 } 179 180 // Notification-Callback 181 void SwAttrSet::Changed( const SfxPoolItem& rOld, 182 const SfxPoolItem& rNew ) 183 { 184 if( pOldSet ) 185 pOldSet->PutChgd( rOld ); 186 187 if( pNewSet ) 188 pNewSet->PutChgd( rNew ); 189 } 190 191 192 // ---------------------------------------------------------------- 193 // Sonderbehandlung fuer einige Attribute 194 // Setze den Modify-Pointer (alten pDefinedIn) bei folgenden Attributen: 195 // - SwFmtDropCaps 196 // - SwFmtPageDesc 197 // (Wird beim Einfuegen in Formate/Nodes gerufen) 198 // ---------------------------------------------------------------- 199 200 bool SwAttrSet::SetModifyAtAttr( const SwModify* pModify ) 201 { 202 bool bSet = false; 203 204 const SfxPoolItem* pItem; 205 if( SFX_ITEM_SET == GetItemState( RES_PAGEDESC, sal_False, &pItem ) && 206 ((SwFmtPageDesc*)pItem)->GetDefinedIn() != pModify ) 207 { 208 ((SwFmtPageDesc*)pItem)->ChgDefinedIn( pModify ); 209 bSet = true; 210 } 211 212 if( SFX_ITEM_SET == GetItemState( RES_PARATR_DROP, sal_False, &pItem ) && 213 ((SwFmtDrop*)pItem)->GetDefinedIn() != pModify ) 214 { 215 // CharFormat gesetzt und dann noch in unterschiedlichen 216 // Attribut Pools, dann muss das CharFormat kopiert werden! 217 SwCharFmt* pCharFmt; 218 if( 0 != ( pCharFmt = ((SwFmtDrop*)pItem)->GetCharFmt() ) 219 && GetPool() != pCharFmt->GetAttrSet().GetPool() ) 220 { 221 pCharFmt = GetDoc()->CopyCharFmt( *pCharFmt ); 222 ((SwFmtDrop*)pItem)->SetCharFmt( pCharFmt ); 223 } 224 ((SwFmtDrop*)pItem)->ChgDefinedIn( pModify ); 225 bSet = true; 226 } 227 228 if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, sal_False, &pItem ) && 229 ((SwTblBoxFormula*)pItem)->GetDefinedIn() != pModify ) 230 { 231 ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pModify ); 232 bSet = true; 233 } 234 235 return bSet; 236 } 237 238 void SwAttrSet::CopyToModify( SwModify& rMod ) const 239 { 240 // kopiere die Attribute ggfs. ueber Dokumentgrenzen 241 SwCntntNode* pCNd = PTR_CAST( SwCntntNode, &rMod ); 242 SwFmt* pFmt = PTR_CAST( SwFmt, &rMod ); 243 244 if( pCNd || pFmt ) 245 { 246 if( Count() ) 247 { 248 // --> OD 2008-08-15 #i92811# 249 SfxStringItem* pNewListIdItem( 0 ); 250 // <-- 251 252 const SfxPoolItem* pItem; 253 const SwDoc *pSrcDoc = GetDoc(); 254 SwDoc *pDstDoc = pCNd ? pCNd->GetDoc() : pFmt->GetDoc(); 255 256 // muss die NumRule kopiert werden? 257 if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState( 258 RES_PARATR_NUMRULE, sal_False, &pItem ) ) 259 { 260 const String& rNm = ((SwNumRuleItem*)pItem)->GetValue(); 261 if( rNm.Len() ) 262 { 263 SwNumRule* pDestRule = pDstDoc->FindNumRulePtr( rNm ); 264 if( pDestRule ) 265 pDestRule->SetInvalidRule( sal_True ); 266 else 267 pDstDoc->MakeNumRule( rNm, 268 pSrcDoc->FindNumRulePtr( rNm ) ); 269 } 270 } 271 272 // --> OD 2008-03-19 #refactorlists# 273 // copy list and if needed also the corresponding list style 274 // for text nodes 275 if ( pSrcDoc != pDstDoc && 276 pCNd && pCNd->IsTxtNode() && 277 GetItemState( RES_PARATR_LIST_ID, sal_False, &pItem ) == SFX_ITEM_SET ) 278 { 279 const String& sListId = 280 dynamic_cast<const SfxStringItem*>(pItem)->GetValue(); 281 if ( sListId.Len() > 0 && 282 !pDstDoc->getListByName( sListId ) ) 283 { 284 const SwList* pList = pSrcDoc->getListByName( sListId ); 285 // copy list style, if needed 286 const String sDefaultListStyleName = 287 pList->GetDefaultListStyleName(); 288 // --> OD 2008-08-15 #i92811# 289 const SwNumRule* pDstDocNumRule = 290 pDstDoc->FindNumRulePtr( sDefaultListStyleName ); 291 if ( !pDstDocNumRule ) 292 { 293 pDstDoc->MakeNumRule( sDefaultListStyleName, 294 pSrcDoc->FindNumRulePtr( sDefaultListStyleName ) ); 295 } 296 else 297 { 298 const SwNumRule* pSrcDocNumRule = 299 pSrcDoc->FindNumRulePtr( sDefaultListStyleName ); 300 // If list id of text node equals the list style's 301 // default list id in the source document, the same 302 // should be hold in the destination document. 303 // Thus, create new list id item. 304 if ( sListId == pSrcDocNumRule->GetDefaultListId() ) 305 { 306 pNewListIdItem = new SfxStringItem ( 307 RES_PARATR_LIST_ID, 308 pDstDocNumRule->GetDefaultListId() ); 309 } 310 } 311 // check again, if list exist, because <SwDoc::MakeNumRule(..)> 312 // could have also created it. 313 if ( pNewListIdItem == 0 && 314 !pDstDoc->getListByName( sListId ) ) 315 { 316 // copy list 317 pDstDoc->createList( sListId, sDefaultListStyleName ); 318 } 319 // <-- 320 } 321 } 322 // <-- 323 324 // JP 04.02.99: Task #61467# Seitenvorlagenwechsel mit kopieren 325 // Gegenueber dem alten Verhalten, sie zu entfernen 326 const SwPageDesc* pPgDesc; 327 if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState( 328 RES_PAGEDESC, sal_False, &pItem ) && 329 0 != ( pPgDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc()) ) 330 { 331 SfxItemSet aTmpSet( *this ); 332 333 SwPageDesc* pDstPgDesc = pDstDoc->FindPageDescByName( 334 pPgDesc->GetName() ); 335 if( !pDstPgDesc ) 336 { 337 // dann kopieren, ansonsten den benutzen 338 pDstPgDesc = &pDstDoc->_GetPageDesc( pDstDoc->MakePageDesc( 339 pPgDesc->GetName() )); 340 pDstDoc->CopyPageDesc( *pPgDesc, *pDstPgDesc ); 341 } 342 SwFmtPageDesc aDesc( pDstPgDesc ); 343 aDesc.SetNumOffset( ((SwFmtPageDesc*)pItem)->GetNumOffset() ); 344 aTmpSet.Put( aDesc ); 345 346 if( pCNd ) 347 { 348 // --> OD 2008-08-15 #i92811# 349 if ( pNewListIdItem != 0 ) 350 { 351 aTmpSet.Put( *pNewListIdItem ); 352 } 353 // <-- 354 pCNd->SetAttr( aTmpSet ); 355 } 356 else 357 pFmt->SetFmtAttr( aTmpSet ); 358 } 359 else if( pCNd ) 360 { 361 // --> OD 2008-08-15 #i92811# 362 if ( pNewListIdItem != 0 ) 363 { 364 SfxItemSet aTmpSet( *this ); 365 aTmpSet.Put( *pNewListIdItem ); 366 pCNd->SetAttr( aTmpSet ); 367 } 368 else 369 { 370 pCNd->SetAttr( *this ); 371 } 372 // <-- 373 } 374 else 375 pFmt->SetFmtAttr( *this ); 376 377 // --> OD 2008-08-15 #i92811# 378 delete pNewListIdItem; 379 pNewListIdItem = 0; 380 // <-- 381 } 382 } 383 #ifdef DBG_UTIL 384 else 385 ASSERT( !this, "weder Format noch ContentNode - keine Attribute kopiert"); 386 #endif 387 } 388 389 // check if ID is InRange of AttrSet-Ids 390 sal_Bool IsInRange( const sal_uInt16* pRange, const sal_uInt16 nId ) 391 { 392 while( *pRange ) 393 { 394 if( *pRange <= nId && nId <= *(pRange+1) ) 395 return sal_True; 396 pRange += 2; 397 } 398 return sal_False; 399 } 400 401