Line data Source code
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 <cellatr.hxx>
21 : #include <charfmt.hxx>
22 : #include <cmdid.h>
23 : #include <doc.hxx>
24 : #include <IDocumentListsAccess.hxx>
25 : #include <editeng/colritem.hxx>
26 : #include <editeng/brushitem.hxx>
27 : #include <editeng/lineitem.hxx>
28 : #include <editeng/boxitem.hxx>
29 : #include <editeng/editeng.hxx>
30 : #include <fmtpdsc.hxx>
31 : #include <hintids.hxx>
32 : #include <istyleaccess.hxx>
33 : #include <list.hxx>
34 : #include <node.hxx>
35 : #include <numrule.hxx>
36 : #include <pagedesc.hxx>
37 : #include <paratr.hxx>
38 : #include <svl/whiter.hxx>
39 : #include <svx/xtable.hxx>
40 :
41 : #include <svx/svdpool.hxx>
42 : #include <svx/sxenditm.hxx>
43 : #include <svx/sdsxyitm.hxx>
44 :
45 5142 : SwAttrPool::SwAttrPool( SwDoc* pD )
46 : : SfxItemPool( OUString("SWG"),
47 : POOLATTR_BEGIN, POOLATTR_END-1,
48 : aSlotTab, aAttrTab ),
49 5142 : pDoc( pD )
50 : {
51 5142 : SetVersionMap( 1, 1, 60, pVersionMap1 );
52 5142 : SetVersionMap( 2, 1, 75, pVersionMap2 );
53 5142 : SetVersionMap( 3, 1, 86, pVersionMap3 );
54 5142 : SetVersionMap( 4, 1,121, pVersionMap4 );
55 : // #i18732# - apply new version map
56 5142 : SetVersionMap( 5, 1,130, pVersionMap5 );
57 5142 : SetVersionMap( 6, 1,136, pVersionMap6 );
58 5142 : SetVersionMap( 7, 1,144, pVersionMap7 );
59 :
60 : //UUUU create secondary pools immediately
61 5142 : createAndAddSecondaryPools();
62 5142 : }
63 :
64 15405 : SwAttrPool::~SwAttrPool()
65 : {
66 : //UUUU cleanup secondary pools first
67 5135 : removeAndDeleteSecondaryPools();
68 10270 : }
69 :
70 : //UUUU
71 5142 : void SwAttrPool::createAndAddSecondaryPools()
72 : {
73 5142 : const SfxItemPool* pCheckAlreadySet = GetSecondaryPool();
74 :
75 5142 : if(pCheckAlreadySet)
76 : {
77 : OSL_ENSURE(false, "SwAttrPool already has a secondary pool (!)");
78 5142 : return;
79 : }
80 :
81 : // create SfxItemPool and EditEngine pool and add these in a chain. These
82 : // belong us and will be removed/destroyed in removeAndDeleteSecondaryPools() used from
83 : // the destructor
84 5142 : SfxItemPool *pSdrPool = new SdrItemPool(this);
85 :
86 : // #75371# change DefaultItems for the SdrEdgeObj distance items
87 : // to TWIPS.
88 5142 : if(pSdrPool)
89 : {
90 : // 1/100th mm in twips
91 5142 : const long nDefEdgeDist = ((500 * 72) / 127);
92 :
93 5142 : pSdrPool->SetPoolDefaultItem(SdrEdgeNode1HorzDistItem(nDefEdgeDist));
94 5142 : pSdrPool->SetPoolDefaultItem(SdrEdgeNode1VertDistItem(nDefEdgeDist));
95 5142 : pSdrPool->SetPoolDefaultItem(SdrEdgeNode2HorzDistItem(nDefEdgeDist));
96 5142 : pSdrPool->SetPoolDefaultItem(SdrEdgeNode2VertDistItem(nDefEdgeDist));
97 :
98 : // #i33700# // Set shadow distance defaults as PoolDefaultItems
99 5142 : pSdrPool->SetPoolDefaultItem(makeSdrShadowXDistItem((300 * 72) / 127));
100 5142 : pSdrPool->SetPoolDefaultItem(makeSdrShadowYDistItem((300 * 72) / 127));
101 : }
102 :
103 5142 : SfxItemPool *pEEgPool = EditEngine::CreatePool(false);
104 :
105 5142 : pSdrPool->SetSecondaryPool(pEEgPool);
106 :
107 5142 : if(!GetFrozenIdRanges())
108 : {
109 5142 : FreezeIdRanges();
110 : }
111 : else
112 : {
113 0 : pSdrPool->FreezeIdRanges();
114 : }
115 : }
116 :
117 : //UUUU
118 5135 : void SwAttrPool::removeAndDeleteSecondaryPools()
119 : {
120 5135 : SfxItemPool *pSdrPool = GetSecondaryPool();
121 :
122 5135 : if(!pSdrPool)
123 : {
124 : OSL_ENSURE(false, "SwAttrPool has no secondary pool, it's missing (!)");
125 0 : return;
126 : }
127 :
128 5135 : SfxItemPool *pEEgPool = pSdrPool->GetSecondaryPool();
129 :
130 5135 : if(!pEEgPool)
131 : {
132 : OSL_ENSURE(false, "i don't accept additional pools");
133 0 : return;
134 : }
135 :
136 : // first delete the items, then break the linking
137 5135 : pSdrPool->Delete();
138 :
139 5135 : SetSecondaryPool(0);
140 5135 : pSdrPool->SetSecondaryPool(0);
141 :
142 : // final cleanup of secondary pool(s)
143 5135 : SfxItemPool::Free(pSdrPool);
144 5135 : SfxItemPool::Free(pEEgPool);
145 : }
146 :
147 0 : SwAttrSet::SwAttrSet( SwAttrPool& rPool, sal_uInt16 nWh1, sal_uInt16 nWh2 )
148 0 : : SfxItemSet( rPool, nWh1, nWh2 ), pOldSet( 0 ), pNewSet( 0 )
149 : {
150 0 : }
151 :
152 7650228 : SwAttrSet::SwAttrSet( SwAttrPool& rPool, const sal_uInt16* nWhichPairTable )
153 7650228 : : SfxItemSet( rPool, nWhichPairTable ), pOldSet( 0 ), pNewSet( 0 )
154 : {
155 7650228 : }
156 :
157 2179164 : SwAttrSet::SwAttrSet( const SwAttrSet& rSet )
158 2179164 : : SfxItemSet( rSet ), pOldSet( 0 ), pNewSet( 0 )
159 : {
160 2179164 : }
161 :
162 38496 : SfxItemSet* SwAttrSet::Clone( bool bItems, SfxItemPool *pToPool ) const
163 : {
164 38496 : if ( pToPool && pToPool != GetPool() )
165 : {
166 0 : SwAttrPool* pAttrPool = dynamic_cast< SwAttrPool* >(pToPool);
167 0 : SfxItemSet* pTmpSet = 0;
168 0 : if ( !pAttrPool )
169 0 : pTmpSet = SfxItemSet::Clone( bItems, pToPool );
170 : else
171 : {
172 0 : pTmpSet = new SwAttrSet( *pAttrPool, GetRanges() );
173 0 : if ( bItems )
174 : {
175 0 : SfxWhichIter aIter(*pTmpSet);
176 0 : sal_uInt16 nWhich = aIter.FirstWhich();
177 0 : while ( nWhich )
178 : {
179 : const SfxPoolItem* pItem;
180 0 : if ( SfxItemState::SET == GetItemState( nWhich, false, &pItem ) )
181 0 : pTmpSet->Put( *pItem, pItem->Which() );
182 0 : nWhich = aIter.NextWhich();
183 0 : }
184 : }
185 : }
186 0 : return pTmpSet;
187 : }
188 : else
189 : return bItems
190 38496 : ? new SwAttrSet( *this )
191 76992 : : new SwAttrSet( *GetPool(), GetRanges() );
192 : }
193 :
194 820548 : bool SwAttrSet::Put_BC( const SfxPoolItem& rAttr,
195 : SwAttrSet* pOld, SwAttrSet* pNew )
196 : {
197 820548 : pNewSet = pNew;
198 820548 : pOldSet = pOld;
199 820548 : bool nRet = 0 != SfxItemSet::Put( rAttr );
200 820548 : pOldSet = pNewSet = 0;
201 820548 : return nRet;
202 : }
203 :
204 570202 : bool SwAttrSet::Put_BC( const SfxItemSet& rSet,
205 : SwAttrSet* pOld, SwAttrSet* pNew )
206 : {
207 570202 : pNewSet = pNew;
208 570202 : pOldSet = pOld;
209 570202 : bool nRet = SfxItemSet::Put( rSet );
210 570202 : pOldSet = pNewSet = 0;
211 570202 : return nRet;
212 : }
213 :
214 72974 : sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich,
215 : SwAttrSet* pOld, SwAttrSet* pNew )
216 : {
217 72974 : pNewSet = pNew;
218 72974 : pOldSet = pOld;
219 72974 : sal_uInt16 nRet = SfxItemSet::ClearItem( nWhich );
220 72974 : pOldSet = pNewSet = 0;
221 72974 : return nRet;
222 : }
223 :
224 2140546 : sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich1, sal_uInt16 nWhich2,
225 : SwAttrSet* pOld, SwAttrSet* pNew )
226 : {
227 : OSL_ENSURE( nWhich1 <= nWhich2, "no valid range" );
228 2140546 : pNewSet = pNew;
229 2140546 : pOldSet = pOld;
230 2140546 : sal_uInt16 nRet = 0;
231 4297806 : for( ; nWhich1 <= nWhich2; ++nWhich1 )
232 2157260 : nRet = nRet + SfxItemSet::ClearItem( nWhich1 );
233 2140546 : pOldSet = pNewSet = 0;
234 2140546 : return nRet;
235 : }
236 :
237 66052 : int SwAttrSet::Intersect_BC( const SfxItemSet& rSet,
238 : SwAttrSet* pOld, SwAttrSet* pNew )
239 : {
240 66052 : pNewSet = pNew;
241 66052 : pOldSet = pOld;
242 66052 : SfxItemSet::Intersect( rSet );
243 66052 : pOldSet = pNewSet = 0;
244 66052 : return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 );
245 : }
246 :
247 : /// Notification callback
248 2377026 : void SwAttrSet::Changed( const SfxPoolItem& rOld, const SfxPoolItem& rNew )
249 : {
250 2377026 : if( pOldSet )
251 1215318 : pOldSet->PutChgd( rOld );
252 2377026 : if( pNewSet )
253 1215318 : pNewSet->PutChgd( rNew );
254 2377026 : }
255 :
256 : /** special treatment for some attributes
257 :
258 : Set the Modify pointer (old pDefinedIn) for the following attributes:
259 : - SwFmtDropCaps
260 : - SwFmtPageDesc
261 :
262 : (Is called at inserts into formats/nodes)
263 : */
264 1200898 : bool SwAttrSet::SetModifyAtAttr( const SwModify* pModify )
265 : {
266 1200898 : bool bSet = false;
267 :
268 : const SfxPoolItem* pItem;
269 1242490 : if( SfxItemState::SET == GetItemState( RES_PAGEDESC, false, &pItem ) &&
270 41592 : ((SwFmtPageDesc*)pItem)->GetDefinedIn() != pModify )
271 : {
272 41534 : ((SwFmtPageDesc*)pItem)->ChgDefinedIn( pModify );
273 41534 : bSet = true;
274 : }
275 :
276 1200940 : if( SfxItemState::SET == GetItemState( RES_PARATR_DROP, false, &pItem ) &&
277 42 : ((SwFmtDrop*)pItem)->GetDefinedIn() != pModify )
278 : {
279 : // If CharFormat is set and it is set in different attribute pools then
280 : // the CharFormat has to be copied.
281 : SwCharFmt* pCharFmt;
282 68 : if( 0 != ( pCharFmt = ((SwFmtDrop*)pItem)->GetCharFmt() )
283 34 : && GetPool() != pCharFmt->GetAttrSet().GetPool() )
284 : {
285 0 : pCharFmt = GetDoc()->CopyCharFmt( *pCharFmt );
286 0 : ((SwFmtDrop*)pItem)->SetCharFmt( pCharFmt );
287 : }
288 34 : ((SwFmtDrop*)pItem)->ChgDefinedIn( pModify );
289 34 : bSet = true;
290 : }
291 :
292 1200898 : if( SfxItemState::SET == GetItemState( RES_BOXATR_FORMULA, false, &pItem ) &&
293 0 : ((SwTblBoxFormula*)pItem)->GetDefinedIn() != pModify )
294 : {
295 0 : ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pModify );
296 0 : bSet = true;
297 : }
298 :
299 1200898 : return bSet;
300 : }
301 :
302 4880 : void SwAttrSet::CopyToModify( SwModify& rMod ) const
303 : {
304 : // copy attributes across multiple documents if needed
305 4880 : SwCntntNode* pCNd = PTR_CAST( SwCntntNode, &rMod );
306 4880 : SwFmt* pFmt = PTR_CAST( SwFmt, &rMod );
307 :
308 4880 : if( pCNd || pFmt )
309 : {
310 4880 : if( Count() )
311 : {
312 : // #i92811#
313 4878 : SfxStringItem* pNewListIdItem( 0 );
314 :
315 : const SfxPoolItem* pItem;
316 4878 : const SwDoc *pSrcDoc = GetDoc();
317 4878 : SwDoc *pDstDoc = pCNd ? pCNd->GetDoc() : pFmt->GetDoc();
318 :
319 : // Does the NumRule has to be copied?
320 5160 : if( pSrcDoc != pDstDoc &&
321 282 : SfxItemState::SET == GetItemState( RES_PARATR_NUMRULE, false, &pItem ) )
322 : {
323 0 : const OUString& rNm = ((SwNumRuleItem*)pItem)->GetValue();
324 0 : if( !rNm.isEmpty() )
325 : {
326 0 : SwNumRule* pDestRule = pDstDoc->FindNumRulePtr( rNm );
327 0 : if( pDestRule )
328 0 : pDestRule->SetInvalidRule( true );
329 : else
330 0 : pDstDoc->MakeNumRule( rNm, pSrcDoc->FindNumRulePtr( rNm ) );
331 : }
332 : }
333 :
334 : // copy list and if needed also the corresponding list style
335 : // for text nodes
336 5160 : if ( pSrcDoc != pDstDoc &&
337 5122 : pCNd && pCNd->IsTxtNode() &&
338 122 : GetItemState( RES_PARATR_LIST_ID, false, &pItem ) == SfxItemState::SET )
339 : {
340 : const OUString& sListId =
341 0 : dynamic_cast<const SfxStringItem*>(pItem)->GetValue();
342 0 : if ( !sListId.isEmpty() &&
343 0 : !pDstDoc->getIDocumentListsAccess().getListByName( sListId ) )
344 : {
345 0 : const SwList* pList = pSrcDoc->getIDocumentListsAccess().getListByName( sListId );
346 : // copy list style, if needed
347 : const OUString sDefaultListStyleName =
348 0 : pList->GetDefaultListStyleName();
349 : // #i92811#
350 : const SwNumRule* pDstDocNumRule =
351 0 : pDstDoc->FindNumRulePtr( sDefaultListStyleName );
352 0 : if ( !pDstDocNumRule )
353 : {
354 : pDstDoc->MakeNumRule( sDefaultListStyleName,
355 0 : pSrcDoc->FindNumRulePtr( sDefaultListStyleName ) );
356 : }
357 : else
358 : {
359 : const SwNumRule* pSrcDocNumRule =
360 0 : pSrcDoc->FindNumRulePtr( sDefaultListStyleName );
361 : // If list id of text node equals the list style's
362 : // default list id in the source document, the same
363 : // should be hold in the destination document.
364 : // Thus, create new list id item.
365 0 : if (pSrcDocNumRule && sListId == pSrcDocNumRule->GetDefaultListId())
366 : {
367 : pNewListIdItem = new SfxStringItem (
368 : RES_PARATR_LIST_ID,
369 0 : pDstDocNumRule->GetDefaultListId() );
370 : }
371 : }
372 : // check again, if list exist, because <SwDoc::MakeNumRule(..)>
373 : // could have also created it.
374 0 : if ( pNewListIdItem == 0 &&
375 0 : !pDstDoc->getIDocumentListsAccess().getListByName( sListId ) )
376 : {
377 : // copy list
378 0 : pDstDoc->getIDocumentListsAccess().createList( sListId, sDefaultListStyleName );
379 0 : }
380 : }
381 : }
382 :
383 : const SwPageDesc* pPgDesc;
384 5160 : if( pSrcDoc != pDstDoc && SfxItemState::SET == GetItemState(
385 4886 : RES_PAGEDESC, false, &pItem ) &&
386 8 : 0 != ( pPgDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc()) )
387 : {
388 8 : SfxItemSet aTmpSet( *this );
389 :
390 8 : SwPageDesc* pDstPgDesc = pDstDoc->FindPageDesc(pPgDesc->GetName());
391 8 : if( !pDstPgDesc )
392 : {
393 0 : pDstPgDesc = pDstDoc->MakePageDesc(pPgDesc->GetName());
394 0 : pDstDoc->CopyPageDesc( *pPgDesc, *pDstPgDesc );
395 : }
396 16 : SwFmtPageDesc aDesc( pDstPgDesc );
397 8 : aDesc.SetNumOffset( ((SwFmtPageDesc*)pItem)->GetNumOffset() );
398 8 : aTmpSet.Put( aDesc );
399 :
400 8 : if( pCNd )
401 : {
402 : // #i92811#
403 4 : if ( pNewListIdItem != 0 )
404 : {
405 0 : aTmpSet.Put( *pNewListIdItem );
406 : }
407 4 : pCNd->SetAttr( aTmpSet );
408 : }
409 : else
410 : {
411 4 : pFmt->SetFmtAttr( aTmpSet );
412 8 : }
413 : }
414 4870 : else if( pCNd )
415 : {
416 : // #i92811#
417 4714 : if ( pNewListIdItem != 0 )
418 : {
419 0 : SfxItemSet aTmpSet( *this );
420 0 : aTmpSet.Put( *pNewListIdItem );
421 0 : pCNd->SetAttr( aTmpSet );
422 : }
423 : else
424 : {
425 4714 : pCNd->SetAttr( *this );
426 : }
427 : }
428 : else
429 : {
430 156 : pFmt->SetFmtAttr( *this );
431 : }
432 :
433 : // #i92811#
434 4878 : delete pNewListIdItem;
435 4878 : pNewListIdItem = 0;
436 : }
437 : }
438 : #if OSL_DEBUG_LEVEL > 0
439 : else
440 : OSL_FAIL("neither Format nor ContentNode - no Attributes copied");
441 : #endif
442 4880 : }
443 :
444 : /// check if ID is in range of attribute set IDs
445 39362 : bool IsInRange( const sal_uInt16* pRange, const sal_uInt16 nId )
446 : {
447 194554 : while( *pRange )
448 : {
449 116582 : if( *pRange <= nId && nId <= *(pRange+1) )
450 752 : return true;
451 115830 : pRange += 2;
452 : }
453 38610 : return false;
454 270 : }
455 :
456 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|