Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <cellatr.hxx>
30 : : #include <charfmt.hxx>
31 : : #include <cmdid.h>
32 : : #include <doc.hxx>
33 : : #include <editeng/colritem.hxx>
34 : : #include <editeng/brshitem.hxx>
35 : : #include <editeng/bolnitem.hxx>
36 : : #include <editeng/boxitem.hxx>
37 : : #include <fmtpdsc.hxx>
38 : : #include <hintids.hxx>
39 : : #include <istyleaccess.hxx>
40 : : #include <list.hxx>
41 : : #include <node.hxx>
42 : : #include <numrule.hxx>
43 : : #include <pagedesc.hxx>
44 : : #include <paratr.hxx>
45 : : #include <svl/whiter.hxx>
46 : : #include <svx/xtable.hxx>
47 : :
48 : : // ----------
49 : : // SwAttrPool
50 : : // ----------
51 : :
52 : 1622 : SwAttrPool::SwAttrPool( SwDoc* pD )
53 : : : SfxItemPool( rtl::OUString("SWG"),
54 : : POOLATTR_BEGIN, POOLATTR_END-1,
55 : : aSlotTab, aAttrTab ),
56 [ + - ]: 1622 : pDoc( pD )
57 : : {
58 [ + - ]: 1622 : SetVersionMap( 1, 1, 60, pVersionMap1 );
59 [ + - ]: 1622 : SetVersionMap( 2, 1, 75, pVersionMap2 );
60 [ + - ]: 1622 : SetVersionMap( 3, 1, 86, pVersionMap3 );
61 [ + - ]: 1622 : SetVersionMap( 4, 1,121, pVersionMap4 );
62 : : // #i18732# - apply new version map
63 [ + - ]: 1622 : SetVersionMap( 5, 1,130, pVersionMap5 );
64 [ + - ]: 1622 : SetVersionMap( 6, 1,136, pVersionMap6 );
65 : 1622 : }
66 : :
67 : 1531 : SwAttrPool::~SwAttrPool()
68 : : {
69 [ - + ]: 3062 : }
70 : :
71 : : // ---------
72 : : // SwAttrSet
73 : : // ---------
74 : :
75 : 0 : SwAttrSet::SwAttrSet( SwAttrPool& rPool, sal_uInt16 nWh1, sal_uInt16 nWh2 )
76 : 0 : : SfxItemSet( rPool, nWh1, nWh2 ), pOldSet( 0 ), pNewSet( 0 )
77 : : {
78 : 0 : }
79 : :
80 : 455590 : SwAttrSet::SwAttrSet( SwAttrPool& rPool, const sal_uInt16* nWhichPairTable )
81 : 455590 : : SfxItemSet( rPool, nWhichPairTable ), pOldSet( 0 ), pNewSet( 0 )
82 : : {
83 : 455590 : }
84 : :
85 : 355957 : SwAttrSet::SwAttrSet( const SwAttrSet& rSet )
86 : 355957 : : SfxItemSet( rSet ), pOldSet( 0 ), pNewSet( 0 )
87 : : {
88 : 355957 : }
89 : :
90 : 6159 : SfxItemSet* SwAttrSet::Clone( sal_Bool bItems, SfxItemPool *pToPool ) const
91 : : {
92 [ - + ][ # # ]: 6159 : if ( pToPool && pToPool != GetPool() )
[ - + ]
93 : : {
94 [ # # ]: 0 : SwAttrPool* pAttrPool = dynamic_cast< SwAttrPool* >(pToPool);
95 : 0 : SfxItemSet* pTmpSet = 0;
96 [ # # ]: 0 : if ( !pAttrPool )
97 : 0 : pTmpSet = SfxItemSet::Clone( bItems, pToPool );
98 : : else
99 : : {
100 [ # # ]: 0 : pTmpSet = new SwAttrSet( *pAttrPool, GetRanges() );
101 [ # # ]: 0 : if ( bItems )
102 : : {
103 [ # # ]: 0 : SfxWhichIter aIter(*pTmpSet);
104 [ # # ]: 0 : sal_uInt16 nWhich = aIter.FirstWhich();
105 [ # # ]: 0 : while ( nWhich )
106 : : {
107 : : const SfxPoolItem* pItem;
108 [ # # ][ # # ]: 0 : if ( SFX_ITEM_SET == GetItemState( nWhich, sal_False, &pItem ) )
109 [ # # ]: 0 : pTmpSet->Put( *pItem, pItem->Which() );
110 [ # # ]: 0 : nWhich = aIter.NextWhich();
111 [ # # ]: 0 : }
112 : : }
113 : : }
114 : 0 : return pTmpSet;
115 : : }
116 : : else
117 : : return bItems
118 [ + - ]: 6159 : ? new SwAttrSet( *this )
119 [ + - ][ # # ]: 12318 : : new SwAttrSet( *GetPool(), GetRanges() );
120 : : }
121 : :
122 : 84807 : int SwAttrSet::Put_BC( const SfxPoolItem& rAttr,
123 : : SwAttrSet* pOld, SwAttrSet* pNew )
124 : : {
125 : 84807 : pNewSet = pNew;
126 : 84807 : pOldSet = pOld;
127 : 84807 : int nRet = 0 != SfxItemSet::Put( rAttr );
128 : 84807 : pOldSet = pNewSet = 0;
129 : 84807 : return nRet;
130 : : }
131 : :
132 : :
133 : 25897 : int SwAttrSet::Put_BC( const SfxItemSet& rSet,
134 : : SwAttrSet* pOld, SwAttrSet* pNew )
135 : : {
136 : 25897 : pNewSet = pNew;
137 : 25897 : pOldSet = pOld;
138 : 25897 : int nRet = 0 != SfxItemSet::Put( rSet );
139 : 25897 : pOldSet = pNewSet = 0;
140 : 25897 : return nRet;
141 : : }
142 : :
143 : 7780 : sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich,
144 : : SwAttrSet* pOld, SwAttrSet* pNew )
145 : : {
146 : 7780 : pNewSet = pNew;
147 : 7780 : pOldSet = pOld;
148 : 7780 : sal_uInt16 nRet = SfxItemSet::ClearItem( nWhich );
149 : 7780 : pOldSet = pNewSet = 0;
150 : 7780 : return nRet;
151 : : }
152 : :
153 : 61701 : sal_uInt16 SwAttrSet::ClearItem_BC( sal_uInt16 nWhich1, sal_uInt16 nWhich2,
154 : : SwAttrSet* pOld, SwAttrSet* pNew )
155 : : {
156 : : OSL_ENSURE( nWhich1 <= nWhich2, "no valid range" );
157 : 61701 : pNewSet = pNew;
158 : 61701 : pOldSet = pOld;
159 : 61701 : sal_uInt16 nRet = 0;
160 [ + + ]: 124618 : for( ; nWhich1 <= nWhich2; ++nWhich1 )
161 : 62917 : nRet = nRet + SfxItemSet::ClearItem( nWhich1 );
162 : 61701 : pOldSet = pNewSet = 0;
163 : 61701 : return nRet;
164 : : }
165 : :
166 : 3111 : int SwAttrSet::Intersect_BC( const SfxItemSet& rSet,
167 : : SwAttrSet* pOld, SwAttrSet* pNew )
168 : : {
169 : 3111 : pNewSet = pNew;
170 : 3111 : pOldSet = pOld;
171 : 3111 : SfxItemSet::Intersect( rSet );
172 : 3111 : pOldSet = pNewSet = 0;
173 [ # # ][ + - ]: 3111 : return pNew ? pNew->Count() : ( pOld ? pOld->Count() : 0 );
174 : : }
175 : :
176 : : /// Notification callback
177 : 331000 : void SwAttrSet::Changed( const SfxPoolItem& rOld, const SfxPoolItem& rNew )
178 : : {
179 [ + + ]: 331000 : if( pOldSet )
180 : 113471 : pOldSet->PutChgd( rOld );
181 [ + + ]: 331000 : if( pNewSet )
182 : 113471 : pNewSet->PutChgd( rNew );
183 : 331000 : }
184 : :
185 : : /** special treatment for some attributes
186 : :
187 : : Set the Modify pointer (old pDefinedIn) for the following attributes:
188 : : - SwFmtDropCaps
189 : : - SwFmtPageDesc
190 : :
191 : : (Is called at inserts into formats/nodes)
192 : : */
193 : 137950 : bool SwAttrSet::SetModifyAtAttr( const SwModify* pModify )
194 : : {
195 : 137950 : bool bSet = false;
196 : :
197 : : const SfxPoolItem* pItem;
198 [ + - ]: 140978 : if( SFX_ITEM_SET == GetItemState( RES_PAGEDESC, sal_False, &pItem ) &&
[ + + + + ]
[ + + ]
199 : 3028 : ((SwFmtPageDesc*)pItem)->GetDefinedIn() != pModify )
200 : : {
201 : 3022 : ((SwFmtPageDesc*)pItem)->ChgDefinedIn( pModify );
202 : 3022 : bSet = true;
203 : : }
204 : :
205 [ + - ]: 137950 : if( SFX_ITEM_SET == GetItemState( RES_PARATR_DROP, sal_False, &pItem ) &&
[ - + # # ]
[ - + ]
206 : 0 : ((SwFmtDrop*)pItem)->GetDefinedIn() != pModify )
207 : : {
208 : : // If CharFormat is set and it is set in different attribute pools then
209 : : // the CharFormat has to be copied.
210 : : SwCharFmt* pCharFmt;
211 [ # # # # ]: 0 : if( 0 != ( pCharFmt = ((SwFmtDrop*)pItem)->GetCharFmt() )
[ # # ]
212 : 0 : && GetPool() != pCharFmt->GetAttrSet().GetPool() )
213 : : {
214 [ # # ]: 0 : pCharFmt = GetDoc()->CopyCharFmt( *pCharFmt );
215 [ # # ]: 0 : ((SwFmtDrop*)pItem)->SetCharFmt( pCharFmt );
216 : : }
217 : 0 : ((SwFmtDrop*)pItem)->ChgDefinedIn( pModify );
218 : 0 : bSet = true;
219 : : }
220 : :
221 [ + - ]: 137950 : if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, sal_False, &pItem ) &&
[ - + # # ]
[ - + ]
222 : 0 : ((SwTblBoxFormula*)pItem)->GetDefinedIn() != pModify )
223 : : {
224 : 0 : ((SwTblBoxFormula*)pItem)->ChgDefinedIn( pModify );
225 : 0 : bSet = true;
226 : : }
227 : :
228 : 137950 : return bSet;
229 : : }
230 : :
231 : 76 : void SwAttrSet::CopyToModify( SwModify& rMod ) const
232 : : {
233 : : // copy attributes across multiple documents if needed
234 [ + - ][ + - ]: 76 : SwCntntNode* pCNd = PTR_CAST( SwCntntNode, &rMod );
235 [ + - ][ - + ]: 76 : SwFmt* pFmt = PTR_CAST( SwFmt, &rMod );
236 : :
237 [ - + ][ # # ]: 76 : if( pCNd || pFmt )
238 : : {
239 [ + - ]: 76 : if( Count() )
240 : : {
241 : : // #i92811#
242 : 76 : SfxStringItem* pNewListIdItem( 0 );
243 : :
244 : : const SfxPoolItem* pItem;
245 : 76 : const SwDoc *pSrcDoc = GetDoc();
246 [ + - ]: 76 : SwDoc *pDstDoc = pCNd ? pCNd->GetDoc() : pFmt->GetDoc();
247 : :
248 : : // Does the NumRule has to be copied?
249 [ + + ][ - + ]: 80 : if( pSrcDoc != pDstDoc &&
[ - + ]
250 [ + - ]: 4 : SFX_ITEM_SET == GetItemState( RES_PARATR_NUMRULE, sal_False, &pItem ) )
251 : : {
252 : 0 : const String& rNm = ((SwNumRuleItem*)pItem)->GetValue();
253 [ # # ]: 0 : if( rNm.Len() )
254 : : {
255 [ # # ]: 0 : SwNumRule* pDestRule = pDstDoc->FindNumRulePtr( rNm );
256 [ # # ]: 0 : if( pDestRule )
257 [ # # ]: 0 : pDestRule->SetInvalidRule( sal_True );
258 : : else
259 [ # # ][ # # ]: 0 : pDstDoc->MakeNumRule( rNm, pSrcDoc->FindNumRulePtr( rNm ) );
260 : : }
261 : : }
262 : :
263 : : // copy list and if needed also the corresponding list style
264 : : // for text nodes
265 [ + + ]: 84 : if ( pSrcDoc != pDstDoc &&
[ + - + - ]
[ - + ][ - + ]
266 : 4 : pCNd && pCNd->IsTxtNode() &&
267 [ + - ]: 4 : GetItemState( RES_PARATR_LIST_ID, sal_False, &pItem ) == SFX_ITEM_SET )
268 : : {
269 : : const String& sListId =
270 [ # # ]: 0 : dynamic_cast<const SfxStringItem*>(pItem)->GetValue();
271 [ # # ][ # # ]: 0 : if ( sListId.Len() > 0 &&
[ # # ]
272 [ # # ][ # # ]: 0 : !pDstDoc->getListByName( sListId ) )
[ # # ][ # # ]
[ # # ]
273 : : {
274 [ # # ][ # # ]: 0 : const SwList* pList = pSrcDoc->getListByName( sListId );
[ # # ]
275 : : // copy list style, if needed
276 : : const String sDefaultListStyleName =
277 [ # # ]: 0 : pList->GetDefaultListStyleName();
278 : : // #i92811#
279 : : const SwNumRule* pDstDocNumRule =
280 [ # # ]: 0 : pDstDoc->FindNumRulePtr( sDefaultListStyleName );
281 [ # # ]: 0 : if ( !pDstDocNumRule )
282 : : {
283 : : pDstDoc->MakeNumRule( sDefaultListStyleName,
284 [ # # ][ # # ]: 0 : pSrcDoc->FindNumRulePtr( sDefaultListStyleName ) );
285 : : }
286 : : else
287 : : {
288 : : const SwNumRule* pSrcDocNumRule =
289 [ # # ]: 0 : pSrcDoc->FindNumRulePtr( sDefaultListStyleName );
290 : : // If list id of text node equals the list style's
291 : : // default list id in the source document, the same
292 : : // should be hold in the destination document.
293 : : // Thus, create new list id item.
294 [ # # ][ # # ]: 0 : if ( sListId == pSrcDocNumRule->GetDefaultListId() )
[ # # ][ # # ]
295 : : {
296 : : pNewListIdItem = new SfxStringItem (
297 : : RES_PARATR_LIST_ID,
298 [ # # ][ # # ]: 0 : pDstDocNumRule->GetDefaultListId() );
[ # # ][ # # ]
299 : : }
300 : : }
301 : : // check again, if list exist, because <SwDoc::MakeNumRule(..)>
302 : : // could have also created it.
303 [ # # ][ # # ]: 0 : if ( pNewListIdItem == 0 &&
[ # # ]
304 [ # # ][ # # ]: 0 : !pDstDoc->getListByName( sListId ) )
[ # # ][ # # ]
[ # # ]
305 : : {
306 : : // copy list
307 [ # # ][ # # ]: 0 : pDstDoc->createList( sListId, sDefaultListStyleName );
[ # # ][ # # ]
[ # # ]
308 [ # # ]: 0 : }
309 : : }
310 : : }
311 : :
312 : : const SwPageDesc* pPgDesc;
313 [ + + ][ - + ]: 80 : if( pSrcDoc != pDstDoc && SFX_ITEM_SET == GetItemState(
[ # # ][ - + ]
314 [ + - ]: 4 : RES_PAGEDESC, sal_False, &pItem ) &&
315 : 0 : 0 != ( pPgDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc()) )
316 : : {
317 [ # # ]: 0 : SfxItemSet aTmpSet( *this );
318 : :
319 : : SwPageDesc* pDstPgDesc = pDstDoc->FindPageDescByName(
320 [ # # ]: 0 : pPgDesc->GetName() );
321 [ # # ]: 0 : if( !pDstPgDesc )
322 : : {
323 : : pDstPgDesc = &pDstDoc->GetPageDesc(
324 [ # # ][ # # ]: 0 : pDstDoc->MakePageDesc( pPgDesc->GetName() ));
325 [ # # ]: 0 : pDstDoc->CopyPageDesc( *pPgDesc, *pDstPgDesc );
326 : : }
327 [ # # ]: 0 : SwFmtPageDesc aDesc( pDstPgDesc );
328 : 0 : aDesc.SetNumOffset( ((SwFmtPageDesc*)pItem)->GetNumOffset() );
329 [ # # ]: 0 : aTmpSet.Put( aDesc );
330 : :
331 [ # # ]: 0 : if( pCNd )
332 : : {
333 : : // #i92811#
334 [ # # ]: 0 : if ( pNewListIdItem != 0 )
335 : : {
336 [ # # ]: 0 : aTmpSet.Put( *pNewListIdItem );
337 : : }
338 [ # # ]: 0 : pCNd->SetAttr( aTmpSet );
339 : : }
340 : : else
341 : : {
342 [ # # ]: 0 : pFmt->SetFmtAttr( aTmpSet );
343 [ # # ][ # # ]: 0 : }
344 : : }
345 [ + - ]: 76 : else if( pCNd )
346 : : {
347 : : // #i92811#
348 [ - + ]: 76 : if ( pNewListIdItem != 0 )
349 : : {
350 [ # # ]: 0 : SfxItemSet aTmpSet( *this );
351 [ # # ]: 0 : aTmpSet.Put( *pNewListIdItem );
352 [ # # ][ # # ]: 0 : pCNd->SetAttr( aTmpSet );
353 : : }
354 : : else
355 : : {
356 [ + - ]: 76 : pCNd->SetAttr( *this );
357 : : }
358 : : }
359 : : else
360 : : {
361 [ # # ]: 0 : pFmt->SetFmtAttr( *this );
362 : : }
363 : :
364 : : // #i92811#
365 [ - + ][ # # ]: 76 : delete pNewListIdItem;
366 : 76 : pNewListIdItem = 0;
367 : : }
368 : : }
369 : : #if OSL_DEBUG_LEVEL > 0
370 : : else
371 : : OSL_FAIL("neither Format nor ContentNode - no Attributes copied");
372 : : #endif
373 : 76 : }
374 : :
375 : : /// check if ID is in range of attribute set IDs
376 : 16165 : sal_Bool IsInRange( const sal_uInt16* pRange, const sal_uInt16 nId )
377 : : {
378 [ + + ]: 48389 : while( *pRange )
379 : : {
380 [ + + ][ + + ]: 32277 : if( *pRange <= nId && nId <= *(pRange+1) )
381 : 53 : return sal_True;
382 : 32224 : pRange += 2;
383 : : }
384 : 16165 : return sal_False;
385 : : }
386 : :
387 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|