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 <fmtpdsc.hxx>
29 : #include <hintids.hxx>
30 : #include <istyleaccess.hxx>
31 : #include <list.hxx>
32 : #include <node.hxx>
33 : #include <numrule.hxx>
34 : #include <pagedesc.hxx>
35 : #include <paratr.hxx>
36 : #include <svl/whiter.hxx>
37 : #include <svx/xtable.hxx>
38 :
39 : // ----------
40 : // SwAttrPool
41 : // ----------
42 :
43 931 : SwAttrPool::SwAttrPool( SwDoc* pD )
44 : : SfxItemPool( OUString("SWG"),
45 : POOLATTR_BEGIN, POOLATTR_END-1,
46 : aSlotTab, aAttrTab ),
47 931 : pDoc( pD )
48 : {
49 931 : SetVersionMap( 1, 1, 60, pVersionMap1 );
50 931 : SetVersionMap( 2, 1, 75, pVersionMap2 );
51 931 : SetVersionMap( 3, 1, 86, pVersionMap3 );
52 931 : SetVersionMap( 4, 1,121, pVersionMap4 );
53 : // #i18732# - apply new version map
54 931 : SetVersionMap( 5, 1,130, pVersionMap5 );
55 931 : SetVersionMap( 6, 1,136, pVersionMap6 );
56 931 : }
57 :
58 1856 : SwAttrPool::~SwAttrPool()
59 : {
60 1856 : }
61 :
62 : // ---------
63 : // SwAttrSet
64 : // ---------
65 :
66 0 : SwAttrSet::SwAttrSet( SwAttrPool& rPool, sal_uInt16 nWh1, sal_uInt16 nWh2 )
67 0 : : SfxItemSet( rPool, nWh1, nWh2 ), pOldSet( 0 ), pNewSet( 0 )
68 : {
69 0 : }
70 :
71 309266 : SwAttrSet::SwAttrSet( SwAttrPool& rPool, const sal_uInt16* nWhichPairTable )
72 309266 : : SfxItemSet( rPool, nWhichPairTable ), pOldSet( 0 ), pNewSet( 0 )
73 : {
74 309266 : }
75 :
76 212012 : SwAttrSet::SwAttrSet( const SwAttrSet& rSet )
77 212012 : : SfxItemSet( rSet ), pOldSet( 0 ), pNewSet( 0 )
78 : {
79 212012 : }
80 :
81 4032 : SfxItemSet* SwAttrSet::Clone( sal_Bool bItems, SfxItemPool *pToPool ) const
82 : {
83 4032 : if ( pToPool && pToPool != GetPool() )
84 : {
85 0 : SwAttrPool* pAttrPool = dynamic_cast< SwAttrPool* >(pToPool);
86 0 : SfxItemSet* pTmpSet = 0;
87 0 : if ( !pAttrPool )
88 0 : pTmpSet = SfxItemSet::Clone( bItems, pToPool );
89 : else
90 : {
91 0 : pTmpSet = new SwAttrSet( *pAttrPool, GetRanges() );
92 0 : if ( bItems )
93 : {
94 0 : SfxWhichIter aIter(*pTmpSet);
95 0 : sal_uInt16 nWhich = aIter.FirstWhich();
96 0 : while ( nWhich )
97 : {
98 : const SfxPoolItem* pItem;
99 0 : if ( SFX_ITEM_SET == GetItemState( nWhich, sal_False, &pItem ) )
100 0 : pTmpSet->Put( *pItem, pItem->Which() );
101 0 : nWhich = aIter.NextWhich();
102 0 : }
103 : }
104 : }
105 0 : return pTmpSet;
106 : }
107 : else
108 : return bItems
109 4032 : ? new SwAttrSet( *this )
110 8064 : : new SwAttrSet( *GetPool(), GetRanges() );
111 : }
112 :
113 59681 : int SwAttrSet::Put_BC( const SfxPoolItem& rAttr,
114 : SwAttrSet* pOld, SwAttrSet* pNew )
115 : {
116 59681 : pNewSet = pNew;
117 59681 : pOldSet = pOld;
118 59681 : int nRet = 0 != SfxItemSet::Put( rAttr );
119 59681 : pOldSet = pNewSet = 0;
120 59681 : return nRet;
121 : }
122 :
123 :
124 25289 : int SwAttrSet::Put_BC( const SfxItemSet& rSet,
125 : SwAttrSet* pOld, SwAttrSet* pNew )
126 : {
127 25289 : pNewSet = pNew;
128 25289 : pOldSet = pOld;
129 25289 : int nRet = 0 != SfxItemSet::Put( rSet );
130 25289 : pOldSet = pNewSet = 0;
131 25289 : return nRet;
132 : }
133 :
134 5848 : sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich,
135 : SwAttrSet* pOld, SwAttrSet* pNew )
136 : {
137 5848 : pNewSet = pNew;
138 5848 : pOldSet = pOld;
139 5848 : sal_uInt16 nRet = SfxItemSet::ClearItem( nWhich );
140 5848 : pOldSet = pNewSet = 0;
141 5848 : return nRet;
142 : }
143 :
144 36840 : sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich1, sal_uInt16 nWhich2,
145 : SwAttrSet* pOld, SwAttrSet* pNew )
146 : {
147 : OSL_ENSURE( nWhich1 <= nWhich2, "no valid range" );
148 36840 : pNewSet = pNew;
149 36840 : pOldSet = pOld;
150 36840 : sal_uInt16 nRet = 0;
151 75196 : for( ; nWhich1 <= nWhich2; ++nWhich1 )
152 38356 : nRet = nRet + SfxItemSet::ClearItem( nWhich1 );
153 36840 : pOldSet = pNewSet = 0;
154 36840 : return nRet;
155 : }
156 :
157 3153 : int SwAttrSet::Intersect_BC( const SfxItemSet& rSet,
158 : SwAttrSet* pOld, SwAttrSet* pNew )
159 : {
160 3153 : pNewSet = pNew;
161 3153 : pOldSet = pOld;
162 3153 : SfxItemSet::Intersect( rSet );
163 3153 : pOldSet = pNewSet = 0;
164 3153 : return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 );
165 : }
166 :
167 : /// Notification callback
168 212043 : void SwAttrSet::Changed( const SfxPoolItem& rOld, const SfxPoolItem& rNew )
169 : {
170 212043 : if( pOldSet )
171 80825 : pOldSet->PutChgd( rOld );
172 212043 : if( pNewSet )
173 80825 : pNewSet->PutChgd( rNew );
174 212043 : }
175 :
176 : /** special treatment for some attributes
177 :
178 : Set the Modify pointer (old pDefinedIn) for the following attributes:
179 : - SwFmtDropCaps
180 : - SwFmtPageDesc
181 :
182 : (Is called at inserts into formats/nodes)
183 : */
184 95902 : bool SwAttrSet::SetModifyAtAttr( const SwModify* pModify )
185 : {
186 95902 : bool bSet = false;
187 :
188 : const SfxPoolItem* pItem;
189 98623 : if( SFX_ITEM_SET == GetItemState( RES_PAGEDESC, sal_False, &pItem ) &&
190 2721 : ((SwFmtPageDesc*)pItem)->GetDefinedIn() != pModify )
191 : {
192 2717 : ((SwFmtPageDesc*)pItem)->ChgDefinedIn( pModify );
193 2717 : bSet = true;
194 : }
195 :
196 95902 : if( SFX_ITEM_SET == GetItemState( RES_PARATR_DROP, sal_False, &pItem ) &&
197 0 : ((SwFmtDrop*)pItem)->GetDefinedIn() != pModify )
198 : {
199 : // If CharFormat is set and it is set in different attribute pools then
200 : // the CharFormat has to be copied.
201 : SwCharFmt* pCharFmt;
202 0 : if( 0 != ( pCharFmt = ((SwFmtDrop*)pItem)->GetCharFmt() )
203 0 : && GetPool() != pCharFmt->GetAttrSet().GetPool() )
204 : {
205 0 : pCharFmt = GetDoc()->CopyCharFmt( *pCharFmt );
206 0 : ((SwFmtDrop*)pItem)->SetCharFmt( pCharFmt );
207 : }
208 0 : ((SwFmtDrop*)pItem)->ChgDefinedIn( pModify );
209 0 : bSet = true;
210 : }
211 :
212 95902 : if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, sal_False, &pItem ) &&
213 0 : ((SwTblBoxFormula*)pItem)->GetDefinedIn() != pModify )
214 : {
215 0 : ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pModify );
216 0 : bSet = true;
217 : }
218 :
219 95902 : return bSet;
220 : }
221 :
222 94 : void SwAttrSet::CopyToModify( SwModify& rMod ) const
223 : {
224 : // copy attributes across multiple documents if needed
225 94 : SwCntntNode* pCNd = PTR_CAST( SwCntntNode, &rMod );
226 94 : SwFmt* pFmt = PTR_CAST( SwFmt, &rMod );
227 :
228 94 : if( pCNd || pFmt )
229 : {
230 94 : if( Count() )
231 : {
232 : // #i92811#
233 94 : SfxStringItem* pNewListIdItem( 0 );
234 :
235 : const SfxPoolItem* pItem;
236 94 : const SwDoc *pSrcDoc = GetDoc();
237 94 : SwDoc *pDstDoc = pCNd ? pCNd->GetDoc() : pFmt->GetDoc();
238 :
239 : // Does the NumRule has to be copied?
240 96 : if( pSrcDoc != pDstDoc &&
241 2 : SFX_ITEM_SET == GetItemState( RES_PARATR_NUMRULE, sal_False, &pItem ) )
242 : {
243 0 : const String& rNm = ((SwNumRuleItem*)pItem)->GetValue();
244 0 : if( rNm.Len() )
245 : {
246 0 : SwNumRule* pDestRule = pDstDoc->FindNumRulePtr( rNm );
247 0 : if( pDestRule )
248 0 : pDestRule->SetInvalidRule( sal_True );
249 : else
250 0 : pDstDoc->MakeNumRule( rNm, pSrcDoc->FindNumRulePtr( rNm ) );
251 0 : }
252 : }
253 :
254 : // copy list and if needed also the corresponding list style
255 : // for text nodes
256 96 : if ( pSrcDoc != pDstDoc &&
257 98 : pCNd && pCNd->IsTxtNode() &&
258 2 : GetItemState( RES_PARATR_LIST_ID, sal_False, &pItem ) == SFX_ITEM_SET )
259 : {
260 : const String& sListId =
261 0 : dynamic_cast<const SfxStringItem*>(pItem)->GetValue();
262 0 : if ( sListId.Len() > 0 &&
263 0 : !pDstDoc->getListByName( sListId ) )
264 : {
265 0 : const SwList* pList = pSrcDoc->getListByName( sListId );
266 : // copy list style, if needed
267 : const String sDefaultListStyleName =
268 0 : pList->GetDefaultListStyleName();
269 : // #i92811#
270 : const SwNumRule* pDstDocNumRule =
271 0 : pDstDoc->FindNumRulePtr( sDefaultListStyleName );
272 0 : if ( !pDstDocNumRule )
273 : {
274 : pDstDoc->MakeNumRule( sDefaultListStyleName,
275 0 : pSrcDoc->FindNumRulePtr( sDefaultListStyleName ) );
276 : }
277 : else
278 : {
279 : const SwNumRule* pSrcDocNumRule =
280 0 : pSrcDoc->FindNumRulePtr( sDefaultListStyleName );
281 : // If list id of text node equals the list style's
282 : // default list id in the source document, the same
283 : // should be hold in the destination document.
284 : // Thus, create new list id item.
285 0 : if ( sListId == pSrcDocNumRule->GetDefaultListId() )
286 : {
287 : pNewListIdItem = new SfxStringItem (
288 : RES_PARATR_LIST_ID,
289 0 : pDstDocNumRule->GetDefaultListId() );
290 : }
291 : }
292 : // check again, if list exist, because <SwDoc::MakeNumRule(..)>
293 : // could have also created it.
294 0 : if ( pNewListIdItem == 0 &&
295 0 : !pDstDoc->getListByName( sListId ) )
296 : {
297 : // copy list
298 0 : pDstDoc->createList( sListId, sDefaultListStyleName );
299 0 : }
300 0 : }
301 : }
302 :
303 : const SwPageDesc* pPgDesc;
304 96 : if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState(
305 94 : RES_PAGEDESC, sal_False, &pItem ) &&
306 0 : 0 != ( pPgDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc()) )
307 : {
308 0 : SfxItemSet aTmpSet( *this );
309 :
310 : SwPageDesc* pDstPgDesc = pDstDoc->FindPageDescByName(
311 0 : pPgDesc->GetName() );
312 0 : if( !pDstPgDesc )
313 : {
314 : pDstPgDesc = &pDstDoc->GetPageDesc(
315 0 : pDstDoc->MakePageDesc( pPgDesc->GetName() ));
316 0 : pDstDoc->CopyPageDesc( *pPgDesc, *pDstPgDesc );
317 : }
318 0 : SwFmtPageDesc aDesc( pDstPgDesc );
319 0 : aDesc.SetNumOffset( ((SwFmtPageDesc*)pItem)->GetNumOffset() );
320 0 : aTmpSet.Put( aDesc );
321 :
322 0 : if( pCNd )
323 : {
324 : // #i92811#
325 0 : if ( pNewListIdItem != 0 )
326 : {
327 0 : aTmpSet.Put( *pNewListIdItem );
328 : }
329 0 : pCNd->SetAttr( aTmpSet );
330 : }
331 : else
332 : {
333 0 : pFmt->SetFmtAttr( aTmpSet );
334 0 : }
335 : }
336 94 : else if( pCNd )
337 : {
338 : // #i92811#
339 94 : if ( pNewListIdItem != 0 )
340 : {
341 0 : SfxItemSet aTmpSet( *this );
342 0 : aTmpSet.Put( *pNewListIdItem );
343 0 : pCNd->SetAttr( aTmpSet );
344 : }
345 : else
346 : {
347 94 : pCNd->SetAttr( *this );
348 : }
349 : }
350 : else
351 : {
352 0 : pFmt->SetFmtAttr( *this );
353 : }
354 :
355 : // #i92811#
356 94 : delete pNewListIdItem;
357 94 : pNewListIdItem = 0;
358 : }
359 : }
360 : #if OSL_DEBUG_LEVEL > 0
361 : else
362 : OSL_FAIL("neither Format nor ContentNode - no Attributes copied");
363 : #endif
364 94 : }
365 :
366 : /// check if ID is in range of attribute set IDs
367 8268 : bool IsInRange( const sal_uInt16* pRange, const sal_uInt16 nId )
368 : {
369 32988 : while( *pRange )
370 : {
371 16494 : if( *pRange <= nId && nId <= *(pRange+1) )
372 42 : return true;
373 16452 : pRange += 2;
374 : }
375 8226 : return false;
376 99 : }
377 :
378 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|