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