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 :
21 : #include <hintids.hxx>
22 : #include <editeng/frmdiritem.hxx>
23 : #include <editeng/protitem.hxx>
24 : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
25 : #include <fmtcntnt.hxx>
26 : #include <fmtanchr.hxx>
27 : #include <frmfmt.hxx>
28 : #include <txtftn.hxx>
29 : #include <ftnfrm.hxx>
30 : #include <doc.hxx>
31 : #include <docary.hxx>
32 : #include <node.hxx>
33 : #include <ndindex.hxx>
34 : #include <numrule.hxx>
35 : #include <swtable.hxx>
36 : #include <ndtxt.hxx>
37 : #include <pam.hxx>
38 : #include <swcache.hxx>
39 : #include <section.hxx>
40 : #include <cntfrm.hxx>
41 : #include <flyfrm.hxx>
42 : #include <txtfrm.hxx>
43 : #include <tabfrm.hxx> // SwTabFrm
44 : #include <viewsh.hxx>
45 : #include <paratr.hxx>
46 : #include <ftnidx.hxx>
47 : #include <fmtftn.hxx>
48 : #include <fmthdft.hxx>
49 : #include <frmatr.hxx>
50 : #include <fmtautofmt.hxx>
51 : #include <frmtool.hxx>
52 : #include <pagefrm.hxx>
53 : #include <node2lay.hxx>
54 : #include <pagedesc.hxx>
55 : #include <fmtpdsc.hxx>
56 : #include <breakit.hxx>
57 : #include <crsskip.hxx>
58 : #include <SwStyleNameMapper.hxx>
59 : #include <scriptinfo.hxx>
60 : #include <rootfrm.hxx>
61 : #include <istyleaccess.hxx>
62 : #include <IDocumentListItems.hxx>
63 : #include <switerator.hxx>
64 : #include "ndole.hxx"
65 :
66 : using namespace ::com::sun::star::i18n;
67 :
68 79745 : TYPEINIT2( SwCntntNode, SwModify, SwIndexReg )
69 :
70 : /*
71 : * Some local helper functions for the attribute set handle of a content node.
72 : * Since the attribute set of a content node may not be modified directly,
73 : * we always have to create a new SwAttrSet, do the modifications, and get
74 : * a new handle from the style access
75 : */
76 :
77 : namespace AttrSetHandleHelper
78 : {
79 :
80 22445 : void GetNewAutoStyle( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
81 : const SwCntntNode& rNode,
82 : SwAttrSet& rNewAttrSet )
83 : {
84 22445 : const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get());
85 22445 : if( rNode.GetModifyAtAttr() )
86 36 : const_cast<SwAttrSet*>(pAttrSet)->SetModifyAtAttr( 0 );
87 22445 : IStyleAccess& rSA = pAttrSet->GetPool()->GetDoc()->GetIStyleAccess();
88 22445 : mrpAttrSet = rSA.getAutomaticStyle( rNewAttrSet, rNode.IsTxtNode() ?
89 : IStyleAccess::AUTO_STYLE_PARA :
90 44890 : IStyleAccess::AUTO_STYLE_NOTXT );
91 22445 : const bool bSetModifyAtAttr = ((SwAttrSet*)mrpAttrSet.get())->SetModifyAtAttr( &rNode );
92 22445 : rNode.SetModifyAtAttr( bSetModifyAtAttr );
93 22445 : }
94 :
95 :
96 240 : void SetParent( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
97 : const SwCntntNode& rNode,
98 : const SwFmt* pParentFmt,
99 : const SwFmt* pConditionalFmt )
100 : {
101 240 : const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get());
102 : OSL_ENSURE( pAttrSet, "no SwAttrSet" );
103 : OSL_ENSURE( pParentFmt || !pConditionalFmt, "ConditionalFmt without ParentFmt?" );
104 :
105 240 : const SwAttrSet* pParentSet = pParentFmt ? &pParentFmt->GetAttrSet() : 0;
106 :
107 240 : if ( pParentSet != pAttrSet->GetParent() )
108 : {
109 120 : SwAttrSet aNewSet( *pAttrSet );
110 120 : aNewSet.SetParent( pParentSet );
111 120 : aNewSet.ClearItem( RES_FRMATR_STYLE_NAME );
112 120 : aNewSet.ClearItem( RES_FRMATR_CONDITIONAL_STYLE_NAME );
113 120 : String sVal;
114 :
115 120 : if ( pParentFmt )
116 : {
117 120 : SwStyleNameMapper::FillProgName( pParentFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
118 120 : const SfxStringItem aAnyFmtColl( RES_FRMATR_STYLE_NAME, sVal );
119 120 : aNewSet.Put( aAnyFmtColl );
120 :
121 120 : if ( pConditionalFmt != pParentFmt )
122 0 : SwStyleNameMapper::FillProgName( pConditionalFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
123 :
124 120 : const SfxStringItem aFmtColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal );
125 120 : aNewSet.Put( aFmtColl );
126 : }
127 :
128 120 : GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
129 : }
130 240 : }
131 :
132 4930 : const SfxPoolItem* Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
133 : const SwCntntNode& rNode,
134 : const SfxPoolItem& rAttr )
135 : {
136 4930 : SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
137 4930 : const SfxPoolItem* pRet = aNewSet.Put( rAttr );
138 4930 : if ( pRet )
139 2090 : GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
140 4930 : return pRet;
141 : }
142 :
143 12248 : int Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, const SwCntntNode& rNode,
144 : const SfxItemSet& rSet )
145 : {
146 12248 : SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
147 :
148 : // #i76273# Robust
149 12248 : SfxItemSet* pStyleNames = 0;
150 12248 : if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) )
151 : {
152 1750 : pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME );
153 1750 : pStyleNames->Put( aNewSet );
154 : }
155 :
156 12248 : const int nRet = aNewSet.Put( rSet );
157 :
158 : // #i76273# Robust
159 12248 : if ( pStyleNames )
160 : {
161 1750 : aNewSet.Put( *pStyleNames );
162 1750 : delete pStyleNames;
163 : }
164 :
165 12248 : if ( nRet )
166 11842 : GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
167 :
168 12248 : return nRet;
169 : }
170 :
171 990 : int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
172 : const SwCntntNode& rNode, const SfxPoolItem& rAttr,
173 : SwAttrSet* pOld, SwAttrSet* pNew )
174 : {
175 990 : SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
176 :
177 : // for a correct broadcast, we need to do a SetModifyAtAttr with the items
178 : // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle
179 990 : if( rNode.GetModifyAtAttr() )
180 2 : aNewSet.SetModifyAtAttr( &rNode );
181 :
182 990 : const int nRet = aNewSet.Put_BC( rAttr, pOld, pNew );
183 :
184 990 : if ( nRet )
185 990 : GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
186 :
187 990 : return nRet;
188 : }
189 :
190 2763 : int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
191 : const SwCntntNode& rNode, const SfxItemSet& rSet,
192 : SwAttrSet* pOld, SwAttrSet* pNew )
193 : {
194 2763 : SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
195 :
196 : // #i76273# Robust
197 2763 : SfxItemSet* pStyleNames = 0;
198 2763 : if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) )
199 : {
200 418 : pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME );
201 418 : pStyleNames->Put( aNewSet );
202 : }
203 :
204 : // for a correct broadcast, we need to do a SetModifyAtAttr with the items
205 : // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle
206 2763 : if( rNode.GetModifyAtAttr() )
207 0 : aNewSet.SetModifyAtAttr( &rNode );
208 :
209 2763 : const int nRet = aNewSet.Put_BC( rSet, pOld, pNew );
210 :
211 : // #i76273# Robust
212 2763 : if ( pStyleNames )
213 : {
214 418 : aNewSet.Put( *pStyleNames );
215 418 : delete pStyleNames;
216 : }
217 :
218 2763 : if ( nRet )
219 2053 : GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
220 :
221 2763 : return nRet;
222 : }
223 :
224 5956 : sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
225 : const SwCntntNode& rNode, sal_uInt16 nWhich,
226 : SwAttrSet* pOld, SwAttrSet* pNew )
227 : {
228 5956 : SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
229 5956 : if( rNode.GetModifyAtAttr() )
230 1716 : aNewSet.SetModifyAtAttr( &rNode );
231 5956 : const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich, pOld, pNew );
232 5956 : if ( nRet )
233 2492 : GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
234 5956 : return nRet;
235 : }
236 :
237 12096 : sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet,
238 : const SwCntntNode& rNode,
239 : sal_uInt16 nWhich1, sal_uInt16 nWhich2,
240 : SwAttrSet* pOld, SwAttrSet* pNew )
241 : {
242 12096 : SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet );
243 12096 : if( rNode.GetModifyAtAttr() )
244 0 : aNewSet.SetModifyAtAttr( &rNode );
245 12096 : const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich1, nWhich2, pOld, pNew );
246 12096 : if ( nRet )
247 1378 : GetNewAutoStyle( mrpAttrSet, rNode, aNewSet );
248 12096 : return nRet;
249 : }
250 :
251 : }
252 :
253 : /*******************************************************************
254 : |* Returns the section level at the position given by aIndex.
255 : |*
256 : |* We use the following logic:
257 : |* S = Start, E = End, C = CntntNode
258 : |* Level 0 = E
259 : |* 1 = S E
260 : |* 2 = SC
261 : |*
262 : |* All EndNodes of the BaseSection have level 0
263 : |* All StartNodes of the BaseSection have level 1
264 : *******************************************************************/
265 :
266 0 : sal_uInt16 SwNode::GetSectionLevel() const
267 : {
268 : // EndNode of a BaseSection? They are always 0!
269 0 : if( IsEndNode() && 0 == pStartOfSection->StartOfSectionIndex() )
270 0 : return 0;
271 :
272 : sal_uInt16 nLevel;
273 0 : const SwNode* pNode = IsStartNode() ? this : pStartOfSection;
274 0 : for( nLevel = 1; 0 != pNode->StartOfSectionIndex(); ++nLevel )
275 0 : pNode = pNode->pStartOfSection;
276 0 : return IsEndNode() ? nLevel-1 : nLevel;
277 : }
278 :
279 : /*******************************************************************
280 : |* Inserts a node into the rNodes array at the rWhere position
281 : |* For the theEndOfSection it is passed the EndOfSection index of
282 : |* the preceding node. If it is at position 0 of the variable array
283 : |* theEndOfSection becomes 0 (itsef the new one).
284 : |*
285 : |* Parameters
286 : |* IN
287 : |* rNodes is the variable array in which the node will be
288 : |* inserted
289 : |* IN
290 : |* rWhere is the position within the array where the node will
291 : |* be inserted
292 : *******************************************************************/
293 :
294 : #ifdef DBG_UTIL
295 : long SwNode::s_nSerial = 0;
296 : #endif
297 :
298 16157 : SwNode::SwNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType )
299 : : nNodeType( nNdType )
300 : , nAFmtNumLvl( 0 )
301 : , bSetNumLSpace( false )
302 : , bIgnoreDontExpand( false)
303 : #ifdef DBG_UTIL
304 : , m_nSerial( s_nSerial++)
305 : #endif
306 16157 : , pStartOfSection( 0 )
307 : {
308 16157 : SwNodes& rNodes = const_cast<SwNodes&> (rWhere.GetNodes());
309 16157 : if( rWhere.GetIndex() )
310 : {
311 16157 : SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ];
312 16157 : rNodes.InsertNode( this, rWhere );
313 16157 : if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
314 : {
315 11345 : pStartOfSection = pNd->pStartOfSection;
316 11345 : if( pNd->GetEndNode() ) // Skip EndNode ? Section
317 : {
318 2666 : pNd = pStartOfSection;
319 2666 : pStartOfSection = pNd->pStartOfSection;
320 : }
321 : }
322 : }
323 : else
324 : {
325 0 : rNodes.InsertNode( this, rWhere );
326 0 : pStartOfSection = (SwStartNode*)this;
327 : }
328 16157 : }
329 :
330 11160 : SwNode::SwNode( SwNodes& rNodes, sal_uLong nPos, const sal_uInt8 nNdType )
331 : : nNodeType( nNdType )
332 : , nAFmtNumLvl( 0 )
333 : , bSetNumLSpace( false )
334 : , bIgnoreDontExpand( false)
335 : #ifdef DBG_UTIL
336 : , m_nSerial( s_nSerial++)
337 : #endif
338 11160 : , pStartOfSection( 0 )
339 : {
340 11160 : if( nPos )
341 : {
342 10044 : SwNode* pNd = rNodes[ nPos - 1 ];
343 10044 : rNodes.InsertNode( this, nPos );
344 10044 : if( 0 == ( pStartOfSection = pNd->GetStartNode()) )
345 : {
346 4464 : pStartOfSection = pNd->pStartOfSection;
347 4464 : if( pNd->GetEndNode() ) // Skip EndNode ? Section!
348 : {
349 4464 : pNd = pStartOfSection;
350 4464 : pStartOfSection = pNd->pStartOfSection;
351 : }
352 : }
353 : }
354 : else
355 : {
356 1116 : rNodes.InsertNode( this, nPos );
357 1116 : pStartOfSection = (SwStartNode*)this;
358 : }
359 11160 : }
360 :
361 14905 : SwNode::~SwNode()
362 : {
363 14905 : }
364 :
365 : // Find the TableNode in which it is located.
366 : // If we're not in a table: return 0
367 :
368 34390 : SwTableNode* SwNode::FindTableNode()
369 : {
370 34390 : if( IsTableNode() )
371 0 : return GetTableNode();
372 34390 : SwStartNode* pTmp = pStartOfSection;
373 102362 : while( !pTmp->IsTableNode() && pTmp->GetIndex() )
374 33582 : pTmp = pTmp->pStartOfSection;
375 34390 : return pTmp->GetTableNode();
376 : }
377 :
378 :
379 : // Is the node located in the visible area of the Shell?
380 0 : sal_Bool SwNode::IsInVisibleArea( ViewShell* pSh ) const
381 : {
382 0 : sal_Bool bRet = sal_False;
383 : const SwCntntNode* pNd;
384 :
385 0 : if( ND_STARTNODE & nNodeType )
386 : {
387 0 : SwNodeIndex aIdx( *this );
388 0 : pNd = GetNodes().GoNext( &aIdx );
389 : }
390 0 : else if( ND_ENDNODE & nNodeType )
391 : {
392 0 : SwNodeIndex aIdx( *EndOfSectionNode() );
393 0 : pNd = GetNodes().GoPrevious( &aIdx );
394 : }
395 : else
396 0 : pNd = GetCntntNode();
397 :
398 0 : if( !pSh )
399 : // Get the Shell from the Doc
400 0 : GetDoc()->GetEditShell( &pSh );
401 :
402 0 : if( pSh )
403 : {
404 : const SwFrm* pFrm;
405 0 : if( pNd && 0 != ( pFrm = pNd->getLayoutFrm( pSh->GetLayout(), 0, 0, sal_False ) ) )
406 : {
407 :
408 0 : if ( pFrm->IsInTab() )
409 0 : pFrm = pFrm->FindTabFrm();
410 :
411 0 : if( !pFrm->IsValid() )
412 0 : do
413 0 : { pFrm = pFrm->FindPrev();
414 0 : } while ( pFrm && !pFrm->IsValid() );
415 :
416 0 : if( !pFrm || pSh->VisArea().IsOver( pFrm->Frm() ) )
417 0 : bRet = sal_True;
418 : }
419 : }
420 :
421 0 : return bRet;
422 : }
423 :
424 1203 : bool SwNode::IsInProtectSect() const
425 : {
426 1203 : const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
427 1203 : const SwSectionNode* pSectNd = pNd->FindSectionNode();
428 1203 : return pSectNd && pSectNd->GetSection().IsProtectFlag();
429 : }
430 :
431 : // Does the node contain anything protected?
432 : // I.e.: Area/Frame/Table rows/... including the Anchor for
433 : // Frames/Footnotes/...
434 62 : sal_Bool SwNode::IsProtect() const
435 : {
436 62 : const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this;
437 62 : const SwStartNode* pSttNd = pNd->FindSectionNode();
438 62 : if( pSttNd && ((SwSectionNode*)pSttNd)->GetSection().IsProtectFlag() )
439 0 : return sal_True;
440 :
441 62 : if( 0 != ( pSttNd = FindTableBoxStartNode() ) )
442 : {
443 : SwCntntFrm* pCFrm;
444 62 : if( IsCntntNode() && 0 != (pCFrm = ((SwCntntNode*)this)->getLayoutFrm( GetDoc()->GetCurrentLayout() ) ))
445 48 : return pCFrm->IsProtected();
446 :
447 14 : const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().
448 28 : GetTblBox( pSttNd->GetIndex() );
449 : //Robust #149568
450 14 : if( pBox && pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
451 0 : return sal_True;
452 : }
453 :
454 14 : SwFrmFmt* pFlyFmt = GetFlyFmt();
455 14 : if( pFlyFmt )
456 : {
457 0 : if( pFlyFmt->GetProtect().IsCntntProtected() )
458 0 : return sal_True;
459 0 : const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
460 0 : return rAnchor.GetCntntAnchor()
461 0 : ? rAnchor.GetCntntAnchor()->nNode.GetNode().IsProtect()
462 0 : : sal_False;
463 : }
464 :
465 14 : if( 0 != ( pSttNd = FindFootnoteStartNode() ) )
466 : {
467 0 : const SwTxtFtn* pTFtn = GetDoc()->GetFtnIdxs().SeekEntry(
468 0 : SwNodeIndex( *pSttNd ) );
469 0 : if( pTFtn )
470 0 : return pTFtn->GetTxtNode().IsProtect();
471 : }
472 :
473 14 : return sal_False;
474 : }
475 :
476 : // Find the PageDesc that is used to format this node. If the Layout is available,
477 : // we search through that. Else we can only do it the hard way by searching onwards through the nodes.
478 68 : const SwPageDesc* SwNode::FindPageDesc( sal_Bool bCalcLay,
479 : sal_uInt32* pPgDescNdIdx ) const
480 : {
481 68 : if ( !GetNodes().IsDocNodes() )
482 : {
483 0 : return 0;
484 : }
485 :
486 68 : const SwPageDesc* pPgDesc = 0;
487 :
488 : const SwCntntNode* pNode;
489 68 : if( ND_STARTNODE & nNodeType )
490 : {
491 0 : SwNodeIndex aIdx( *this );
492 0 : pNode = GetNodes().GoNext( &aIdx );
493 : }
494 68 : else if( ND_ENDNODE & nNodeType )
495 : {
496 0 : SwNodeIndex aIdx( *EndOfSectionNode() );
497 0 : pNode = GetNodes().GoPrevious( &aIdx );
498 : }
499 : else
500 : {
501 68 : pNode = GetCntntNode();
502 68 : if( pNode )
503 68 : pPgDesc = ((SwFmtPageDesc&)pNode->GetAttr( RES_PAGEDESC )).GetPageDesc();
504 : }
505 :
506 : // Are we going through the Layout?
507 68 : if( !pPgDesc )
508 : {
509 : const SwFrm* pFrm;
510 : const SwPageFrm* pPage;
511 66 : if( pNode && 0 != ( pFrm = pNode->getLayoutFrm( pNode->GetDoc()->GetCurrentLayout(), 0, 0, bCalcLay ) ) &&
512 : 0 != ( pPage = pFrm->FindPageFrm() ) )
513 : {
514 66 : pPgDesc = pPage->GetPageDesc();
515 66 : if ( pPgDescNdIdx )
516 : {
517 0 : *pPgDescNdIdx = pNode->GetIndex();
518 : }
519 : }
520 : }
521 :
522 68 : if( !pPgDesc )
523 : {
524 : // Thus via the nodes array
525 0 : const SwDoc* pDoc = GetDoc();
526 0 : const SwNode* pNd = this;
527 : const SwStartNode* pSttNd;
528 0 : if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() &&
529 : 0 != ( pSttNd = pNd->FindFlyStartNode() ) )
530 : {
531 : // Find the right Anchor first
532 0 : const SwFrmFmt* pFmt = 0;
533 0 : const SwFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
534 : sal_uInt16 n;
535 :
536 0 : for( n = 0; n < rFmts.size(); ++n )
537 : {
538 0 : SwFrmFmt* pFrmFmt = rFmts[ n ];
539 0 : const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
540 0 : if( rCntnt.GetCntntIdx() &&
541 0 : &rCntnt.GetCntntIdx()->GetNode() == (SwNode*)pSttNd )
542 : {
543 0 : pFmt = pFrmFmt;
544 0 : break;
545 : }
546 : }
547 :
548 0 : if( pFmt )
549 : {
550 0 : const SwFmtAnchor* pAnchor = &pFmt->GetAnchor();
551 0 : if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
552 0 : pAnchor->GetCntntAnchor() )
553 : {
554 0 : pNd = &pAnchor->GetCntntAnchor()->nNode.GetNode();
555 0 : const SwNode* pFlyNd = pNd->FindFlyStartNode();
556 0 : while( pFlyNd )
557 : {
558 : // Get up through the Anchor
559 0 : for( n = 0; n < rFmts.size(); ++n )
560 : {
561 0 : const SwFrmFmt* pFrmFmt = rFmts[ n ];
562 0 : const SwNodeIndex* pIdx = pFrmFmt->GetCntnt().
563 0 : GetCntntIdx();
564 0 : if( pIdx && pFlyNd == &pIdx->GetNode() )
565 : {
566 0 : if( pFmt == pFrmFmt )
567 : {
568 0 : pNd = pFlyNd;
569 0 : pFlyNd = 0;
570 0 : break;
571 : }
572 0 : pAnchor = &pFrmFmt->GetAnchor();
573 0 : if ((FLY_AT_PAGE == pAnchor->GetAnchorId()) ||
574 0 : !pAnchor->GetCntntAnchor() )
575 : {
576 0 : pFlyNd = 0;
577 0 : break;
578 : }
579 :
580 0 : pFlyNd = pAnchor->GetCntntAnchor()->nNode.
581 0 : GetNode().FindFlyStartNode();
582 0 : break;
583 : }
584 : }
585 0 : if( n >= rFmts.size() )
586 : {
587 : OSL_ENSURE( !this, "FlySection, but no Format found" );
588 0 : return 0;
589 : }
590 : }
591 : }
592 : }
593 : // pNd should now contain the correct Anchor or it's still this
594 : }
595 :
596 0 : if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() )
597 : {
598 0 : if( pNd->GetIndex() > GetNodes().GetEndOfAutotext().GetIndex() )
599 : {
600 0 : pPgDesc = &pDoc->GetPageDesc( 0 );
601 0 : pNd = 0;
602 : }
603 : else
604 : {
605 : // Find the Body Textnode
606 0 : if( 0 != ( pSttNd = pNd->FindHeaderStartNode() ) ||
607 : 0 != ( pSttNd = pNd->FindFooterStartNode() ))
608 : {
609 : // Then find this StartNode in the PageDescs
610 : sal_uInt16 nId;
611 : UseOnPage eAskUse;
612 0 : if( SwHeaderStartNode == pSttNd->GetStartNodeType())
613 : {
614 0 : nId = RES_HEADER;
615 0 : eAskUse = nsUseOnPage::PD_HEADERSHARE;
616 : }
617 : else
618 : {
619 0 : nId = RES_FOOTER;
620 0 : eAskUse = nsUseOnPage::PD_FOOTERSHARE;
621 : }
622 :
623 0 : for( sal_uInt16 n = pDoc->GetPageDescCnt(); n && !pPgDesc; )
624 : {
625 0 : const SwPageDesc& rPgDsc = pDoc->GetPageDesc( --n );
626 0 : const SwFrmFmt* pFmt = &rPgDsc.GetMaster();
627 0 : int nStt = 0, nLast = 1;
628 0 : if( !( eAskUse & rPgDsc.ReadUseOn() )) ++nLast;
629 :
630 0 : for( ; nStt < nLast; ++nStt, pFmt = &rPgDsc.GetLeft() )
631 : {
632 : const SwFmtHeader& rHdFt = (SwFmtHeader&)
633 0 : pFmt->GetFmtAttr( nId );
634 0 : if( rHdFt.GetHeaderFmt() )
635 : {
636 : const SwFmtCntnt& rCntnt =
637 0 : rHdFt.GetHeaderFmt()->GetCntnt();
638 0 : if( rCntnt.GetCntntIdx() &&
639 0 : &rCntnt.GetCntntIdx()->GetNode() ==
640 : (SwNode*)pSttNd )
641 : {
642 0 : pPgDesc = &rPgDsc;
643 0 : break;
644 : }
645 : }
646 : }
647 : }
648 :
649 0 : if( !pPgDesc )
650 0 : pPgDesc = &pDoc->GetPageDesc( 0 );
651 0 : pNd = 0;
652 : }
653 0 : else if( 0 != ( pSttNd = pNd->FindFootnoteStartNode() ))
654 : {
655 : // iThe Anchor can only be in the Bodytext
656 : const SwTxtFtn* pTxtFtn;
657 0 : const SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs();
658 0 : for( sal_uInt16 n = 0; n < rFtnArr.size(); ++n )
659 0 : if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
660 : (SwNode*)pSttNd ==
661 0 : &pTxtFtn->GetStartNode()->GetNode() )
662 : {
663 0 : pNd = &pTxtFtn->GetTxtNode();
664 0 : break;
665 : }
666 : }
667 : else
668 : {
669 : // Can only be a page-bound Fly (or something newer).
670 : // WE can only return the standard here
671 : OSL_ENSURE( pNd->FindFlyStartNode(),
672 : "Where is this Node?" );
673 :
674 0 : pPgDesc = &pDoc->GetPageDesc( 0 );
675 0 : pNd = 0;
676 : }
677 : }
678 : }
679 :
680 0 : if( pNd )
681 : {
682 0 : SwFindNearestNode aInfo( *pNd );
683 : // Over all Nodes of all PageDescs
684 : const SfxPoolItem* pItem;
685 0 : sal_uInt32 i, nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_PAGEDESC );
686 0 : for( i = 0; i < nMaxItems; ++i )
687 0 : if( 0 != (pItem = pDoc->GetAttrPool().GetItem2( RES_PAGEDESC, i ) ) &&
688 0 : ((SwFmtPageDesc*)pItem)->GetDefinedIn() )
689 : {
690 0 : const SwModify* pMod = ((SwFmtPageDesc*)pItem)->GetDefinedIn();
691 0 : if( pMod->ISA( SwCntntNode ) )
692 0 : aInfo.CheckNode( *(SwCntntNode*)pMod );
693 0 : else if( pMod->ISA( SwFmt ))
694 0 : ((SwFmt*)pMod)->GetInfo( aInfo );
695 : }
696 :
697 0 : if( 0 != ( pNd = aInfo.GetFoundNode() ))
698 : {
699 0 : if( pNd->IsCntntNode() )
700 : pPgDesc = ((SwFmtPageDesc&)pNd->GetCntntNode()->
701 0 : GetAttr( RES_PAGEDESC )).GetPageDesc();
702 0 : else if( pNd->IsTableNode() )
703 0 : pPgDesc = pNd->GetTableNode()->GetTable().
704 0 : GetFrmFmt()->GetPageDesc().GetPageDesc();
705 0 : else if( pNd->IsSectionNode() )
706 0 : pPgDesc = pNd->GetSectionNode()->GetSection().
707 0 : GetFmt()->GetPageDesc().GetPageDesc();
708 0 : if ( pPgDescNdIdx )
709 : {
710 0 : *pPgDescNdIdx = pNd->GetIndex();
711 : }
712 : }
713 0 : if( !pPgDesc )
714 0 : pPgDesc = &pDoc->GetPageDesc( 0 );
715 : }
716 : }
717 68 : return pPgDesc;
718 : }
719 :
720 :
721 : // If the node is located in a Fly, we return it formatted accordingly
722 26 : SwFrmFmt* SwNode::GetFlyFmt() const
723 : {
724 26 : SwFrmFmt* pRet = 0;
725 26 : const SwNode* pSttNd = FindFlyStartNode();
726 26 : if( pSttNd )
727 : {
728 8 : if( IsCntntNode() )
729 : {
730 8 : SwCntntFrm* pFrm = SwIterator<SwCntntFrm,SwCntntNode>::FirstElement( *(SwCntntNode*)this );
731 8 : if( pFrm )
732 0 : pRet = pFrm->FindFlyFrm()->GetFmt();
733 : }
734 8 : if( !pRet )
735 : {
736 : // The hard way through the Doc is our last way out
737 8 : const SwFrmFmts& rFrmFmtTbl = *GetDoc()->GetSpzFrmFmts();
738 12 : for( sal_uInt16 n = 0; n < rFrmFmtTbl.size(); ++n )
739 : {
740 12 : SwFrmFmt* pFmt = rFrmFmtTbl[n];
741 12 : const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
742 24 : if( rCntnt.GetCntntIdx() &&
743 12 : &rCntnt.GetCntntIdx()->GetNode() == pSttNd )
744 : {
745 8 : pRet = pFmt;
746 8 : break;
747 : }
748 : }
749 : }
750 : }
751 26 : return pRet;
752 : }
753 :
754 234 : SwTableBox* SwNode::GetTblBox() const
755 : {
756 234 : SwTableBox* pBox = 0;
757 234 : const SwNode* pSttNd = FindTableBoxStartNode();
758 234 : if( pSttNd )
759 234 : pBox = (SwTableBox*)pSttNd->FindTableNode()->GetTable().GetTblBox(
760 468 : pSttNd->GetIndex() );
761 234 : return pBox;
762 : }
763 :
764 9648 : SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp )
765 : {
766 9648 : SwStartNode* pTmp = IsStartNode() ? (SwStartNode*)this : pStartOfSection;
767 :
768 23612 : while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() )
769 4316 : pTmp = pTmp->pStartOfSection;
770 9648 : return eTyp == pTmp->GetStartNodeType() ? pTmp : 0;
771 : }
772 :
773 0 : const SwTxtNode* SwNode::FindOutlineNodeOfLevel( sal_uInt8 nLvl ) const
774 : {
775 0 : const SwTxtNode* pRet = 0;
776 0 : const SwOutlineNodes& rONds = GetNodes().GetOutLineNds();
777 0 : if( MAXLEVEL > nLvl && !rONds.empty() )
778 : {
779 : sal_uInt16 nPos;
780 0 : SwNode* pNd = (SwNode*)this;
781 0 : bool bCheckFirst = false;
782 0 : if( !rONds.Seek_Entry( pNd, &nPos ))
783 : {
784 0 : if( nPos )
785 0 : nPos = nPos-1;
786 : else
787 0 : bCheckFirst = true;
788 : }
789 :
790 0 : if( bCheckFirst )
791 : {
792 : // The first OutlineNode comes after the one asking. Test if it points to the same node.
793 : // If not it's invalid.
794 0 : pRet = rONds[0]->GetTxtNode();
795 :
796 0 : const SwCntntNode* pCNd = GetCntntNode();
797 :
798 0 : Point aPt( 0, 0 );
799 0 : const SwFrm* pFrm = pRet->getLayoutFrm( pRet->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ),
800 0 : * pMyFrm = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ) : 0;
801 0 : const SwPageFrm* pPgFrm = pFrm ? pFrm->FindPageFrm() : 0;
802 0 : if( pPgFrm && pMyFrm &&
803 0 : pPgFrm->Frm().Top() > pMyFrm->Frm().Top() )
804 : {
805 : // The one asking precedes the Page, thus its invalid
806 0 : pRet = 0;
807 : }
808 : }
809 : else
810 : {
811 : // Or at the Field and get it from there!
812 0 : while( nPos &&
813 0 : nLvl < ( pRet = rONds[nPos]->GetTxtNode() )
814 0 : ->GetAttrOutlineLevel() - 1 )
815 0 : --nPos;
816 :
817 0 : if( !nPos ) // Get seperately when 0
818 0 : pRet = rONds[0]->GetTxtNode();
819 : }
820 : }
821 0 : return pRet;
822 : }
823 :
824 1170 : inline bool IsValidNextPrevNd( const SwNode& rNd )
825 : {
826 1170 : return ND_TABLENODE == rNd.GetNodeType() ||
827 1160 : ( ND_CONTENTNODE & rNd.GetNodeType() ) ||
828 698 : ( ND_ENDNODE == rNd.GetNodeType() && rNd.StartOfSectionNode() &&
829 3028 : ND_TABLENODE == rNd.StartOfSectionNode()->GetNodeType() );
830 : }
831 :
832 390 : sal_uInt8 SwNode::HasPrevNextLayNode() const
833 : {
834 : // assumption: <this> node is a node inside the document nodes array section.
835 :
836 390 : sal_uInt8 nRet = 0;
837 390 : if( IsValidNextPrevNd( *this ))
838 : {
839 390 : SwNodeIndex aIdx( *this, -1 );
840 : // #i77805# - skip section start and end nodes
841 1180 : while ( aIdx.GetNode().IsSectionNode() ||
842 390 : ( aIdx.GetNode().IsEndNode() &&
843 10 : aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) )
844 : {
845 0 : --aIdx;
846 : }
847 390 : if( IsValidNextPrevNd( aIdx.GetNode() ))
848 164 : nRet |= ND_HAS_PREV_LAYNODE;
849 : // #i77805# - skip section start and end nodes
850 390 : aIdx = SwNodeIndex( *this, +1 );
851 1396 : while ( aIdx.GetNode().IsSectionNode() ||
852 390 : ( aIdx.GetNode().IsEndNode() &&
853 226 : aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) )
854 : {
855 0 : ++aIdx;
856 : }
857 390 : if( IsValidNextPrevNd( aIdx.GetNode() ))
858 164 : nRet |= ND_HAS_NEXT_LAYNODE;
859 : }
860 390 : return nRet;
861 : }
862 :
863 : /*******************************************************************
864 : |* Retruns the node's StartOfSection
865 : |*
866 : |* Parameters
867 : |* IN
868 : |* rNodes is the variable array in which the node is contained
869 : *******************************************************************/
870 :
871 3092 : SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType,
872 : SwStartNodeType eSttNd )
873 3092 : : SwNode( rWhere, nNdType ), eSttNdTyp( eSttNd )
874 : {
875 : // Just do this temporarily until the EndNode is inserted
876 3092 : pEndOfSection = (SwEndNode*)this;
877 3092 : }
878 :
879 5580 : SwStartNode::SwStartNode( SwNodes& rNodes, sal_uLong nPos )
880 5580 : : SwNode( rNodes, nPos, ND_STARTNODE ), eSttNdTyp( SwNormalStartNode )
881 : {
882 : // Just do this temporarily until the EndNode is inserted
883 5580 : pEndOfSection = (SwEndNode*)this;
884 5580 : }
885 :
886 :
887 84 : void SwStartNode::CheckSectionCondColl() const
888 : {
889 : //FEATURE::CONDCOLL
890 84 : SwNodeIndex aIdx( *this );
891 84 : sal_uLong nEndIdx = EndOfSectionIndex();
892 84 : const SwNodes& rNds = GetNodes();
893 : SwCntntNode* pCNd;
894 320 : while( 0 != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx )
895 236 : pCNd->ChkCondColl();
896 : //FEATURE::CONDCOLL
897 84 : }
898 :
899 : /*******************************************************************
900 : |* Inserts a node into the array rNodes at the position aWhere.
901 : |* The theStartOfSection pointer is set accordingly.
902 : |* The EndOfSection pointer of the corresponding StartNodes (identified
903 : |* by rStartOfSection) is set to this node.
904 : |*
905 : |* Parameters
906 : |* IN
907 : |* rNodes is the variable array in which the node is contained
908 : |* IN
909 : |* aWhere is the position where the node is inserted
910 : |* We pass a copy!
911 : *******************************************************************/
912 :
913 3092 : SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd )
914 3092 : : SwNode( rWhere, ND_ENDNODE )
915 : {
916 3092 : pStartOfSection = &rSttNd;
917 3092 : pStartOfSection->pEndOfSection = this;
918 3092 : }
919 :
920 5580 : SwEndNode::SwEndNode( SwNodes& rNds, sal_uLong nPos, SwStartNode& rSttNd )
921 5580 : : SwNode( rNds, nPos, ND_ENDNODE )
922 : {
923 5580 : pStartOfSection = &rSttNd;
924 5580 : pStartOfSection->pEndOfSection = this;
925 5580 : }
926 :
927 :
928 :
929 : // --------------------
930 : // SwCntntNode
931 : // --------------------
932 :
933 :
934 9973 : SwCntntNode::SwCntntNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType,
935 : SwFmtColl *pColl )
936 : : SwModify( pColl ), // CrsrsShell, FrameFmt,
937 : SwNode( rWhere, nNdType ),
938 : pCondColl( 0 ),
939 9973 : mbSetModifyAtAttr( false )
940 : {
941 9973 : }
942 :
943 :
944 15538 : SwCntntNode::~SwCntntNode()
945 : {
946 : // The base class SwClient of SwFrm excludes itself from the dependency list!
947 : // Thus, we need to delete all Frames in the the dependency list.
948 7769 : if( GetDepends() )
949 336 : DelFrms();
950 :
951 7769 : delete pCondColl;
952 :
953 7769 : if ( mpAttrSet.get() && mbSetModifyAtAttr )
954 96 : ((SwAttrSet*)mpAttrSet.get())->SetModifyAtAttr( 0 );
955 7769 : }
956 :
957 67884 : void SwCntntNode::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
958 : {
959 : sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
960 67884 : pNewValue ? pNewValue->Which() : 0 ;
961 :
962 67884 : switch( nWhich )
963 : {
964 : case RES_OBJECTDYING :
965 : {
966 0 : SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject;
967 :
968 : // Do not mangle pointers if it is the upper-most format!
969 0 : if( GetRegisteredIn() == pFmt )
970 : {
971 0 : if( pFmt->GetRegisteredIn() )
972 : {
973 : // If Parent, register anew in the new Parent
974 0 : ((SwModify*)pFmt->GetRegisteredIn())->Add( this );
975 0 : if ( GetpSwAttrSet() )
976 0 : AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
977 : }
978 : else
979 : {
980 : // Else register anyways when dying
981 0 : ((SwModify*)GetRegisteredIn())->Remove( this );
982 0 : if ( GetpSwAttrSet() )
983 0 : AttrSetHandleHelper::SetParent( mpAttrSet, *this, 0, 0 );
984 : }
985 : }
986 : }
987 0 : break;
988 :
989 :
990 : case RES_FMT_CHG:
991 : // If the Format parent was switched, register the Attrset at the new one
992 : // Skip own Modify!
993 4418 : if( GetpSwAttrSet() &&
994 120 : ((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() )
995 : {
996 : // Attach Set to the new parent
997 120 : AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() );
998 : }
999 4298 : break;
1000 : //FEATURE::CONDCOLL
1001 : case RES_CONDCOLL_CONDCHG:
1002 0 : if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() &&
1003 0 : &GetNodes() == &GetDoc()->GetNodes() )
1004 : {
1005 0 : ChkCondColl();
1006 : }
1007 67884 : return ; // Do not pass through to the base class/Frames
1008 : //FEATURE::CONDCOLL
1009 :
1010 : case RES_ATTRSET_CHG:
1011 43004 : if( GetNodes().IsDocNodes() && IsTxtNode() )
1012 : {
1013 70374 : if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState(
1014 35187 : RES_CHRATR_HIDDEN, sal_False ) )
1015 : {
1016 4 : ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1017 : }
1018 : }
1019 43004 : break;
1020 :
1021 : case RES_UPDATE_ATTR:
1022 19492 : if( GetNodes().IsDocNodes() && IsTxtNode() )
1023 : {
1024 19492 : const sal_uInt16 nTmp = ((SwUpdateAttr*)pNewValue)->nWhichAttr;
1025 19492 : if ( RES_ATTRSET_CHG == nTmp )
1026 : {
1027 : // TODO: anybody wants to do some optimization here?
1028 30 : ((SwTxtNode*)this)->SetCalcHiddenCharFlags();
1029 : }
1030 : }
1031 19492 : break;
1032 : }
1033 :
1034 67884 : NotifyClients( pOldValue, pNewValue );
1035 : }
1036 :
1037 2155 : sal_Bool SwCntntNode::InvalidateNumRule()
1038 : {
1039 2155 : SwNumRule* pRule = 0;
1040 : const SfxPoolItem* pItem;
1041 2185 : if( GetNodes().IsDocNodes() &&
1042 : 0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, sal_True )) &&
1043 16 : ((SwNumRuleItem*)pItem)->GetValue().Len() &&
1044 : 0 != (pRule = GetDoc()->FindNumRulePtr(
1045 14 : ((SwNumRuleItem*)pItem)->GetValue() ) ) )
1046 : {
1047 14 : pRule->SetInvalidRule( sal_True );
1048 : }
1049 2155 : return 0 != pRule;
1050 : }
1051 :
1052 38170 : SwCntntFrm *SwCntntNode::getLayoutFrm( const SwRootFrm* _pRoot,
1053 : const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm ) const
1054 : {
1055 : return (SwCntntFrm*) ::GetFrmOfModify( _pRoot, *(SwModify*)this, FRM_CNTNT,
1056 38170 : pPoint, pPos, bCalcFrm );
1057 : }
1058 :
1059 156 : SwRect SwCntntNode::FindLayoutRect( const sal_Bool bPrtArea, const Point* pPoint,
1060 : const sal_Bool bCalcFrm ) const
1061 : {
1062 156 : SwRect aRet;
1063 : SwCntntFrm* pFrm = (SwCntntFrm*)::GetFrmOfModify( 0, *(SwModify*)this,
1064 156 : FRM_CNTNT, pPoint, 0, bCalcFrm );
1065 156 : if( pFrm )
1066 156 : aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1067 156 : return aRet;
1068 : }
1069 :
1070 16 : SwRect SwCntntNode::FindPageFrmRect( const sal_Bool bPrtArea, const Point* pPoint,
1071 : const sal_Bool bCalcFrm ) const
1072 : {
1073 16 : SwRect aRet;
1074 : SwFrm* pFrm = ::GetFrmOfModify( 0, *(SwModify*)this,
1075 16 : FRM_CNTNT, pPoint, 0, bCalcFrm );
1076 16 : if( pFrm && 0 != ( pFrm = pFrm->FindPageFrm() ))
1077 16 : aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm();
1078 16 : return aRet;
1079 : }
1080 :
1081 0 : xub_StrLen SwCntntNode::Len() const { return 0; }
1082 :
1083 :
1084 :
1085 2398 : SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl )
1086 : {
1087 : OSL_ENSURE( pNewColl, "Collectionpointer is 0." );
1088 2398 : SwFmtColl *pOldColl = GetFmtColl();
1089 :
1090 2398 : if( pNewColl != pOldColl )
1091 : {
1092 2398 : pNewColl->Add( this );
1093 :
1094 : // Set the Parent of out AutoAttributes to the new Collection
1095 2398 : if( GetpSwAttrSet() )
1096 120 : AttrSetHandleHelper::SetParent( mpAttrSet, *this, pNewColl, pNewColl );
1097 :
1098 : //FEATURE::CONDCOLL
1099 : // TODO: HACK: We need to recheck this condition according to the new template!
1100 : if( true /*pNewColl */ )
1101 : {
1102 2398 : SetCondFmtColl( 0 );
1103 : }
1104 : //FEATURE::CONDCOLL
1105 :
1106 2398 : if( !IsModifyLocked() )
1107 : {
1108 2398 : SwFmtChg aTmp1( pOldColl );
1109 2398 : SwFmtChg aTmp2( pNewColl );
1110 2398 : SwCntntNode::Modify( &aTmp1, &aTmp2 );
1111 : }
1112 : }
1113 2398 : if ( IsInCache() )
1114 : {
1115 0 : SwFrm::GetCache().Delete( this );
1116 0 : SetInCache( sal_False );
1117 : }
1118 2398 : return pOldColl;
1119 : }
1120 :
1121 :
1122 808 : sal_Bool SwCntntNode::GoNext(SwIndex * pIdx, sal_uInt16 nMode ) const
1123 : {
1124 808 : sal_Bool bRet = sal_True;
1125 808 : if( pIdx->GetIndex() < Len() )
1126 : {
1127 772 : if( !IsTxtNode() )
1128 0 : ++(*pIdx);
1129 : else
1130 : {
1131 772 : const SwTxtNode& rTNd = *GetTxtNode();
1132 772 : xub_StrLen nPos = pIdx->GetIndex();
1133 772 : if( pBreakIt->GetBreakIter().is() )
1134 : {
1135 772 : sal_Int32 nDone = 0;
1136 : sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1137 : CharacterIteratorMode::SKIPCELL :
1138 772 : CharacterIteratorMode::SKIPCONTROLCHARACTER;
1139 2316 : nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharacters( rTNd.GetTxt(), nPos,
1140 772 : pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1141 2316 : nItrMode, 1, nDone );
1142 :
1143 : // Check if nPos is inside hidden text range:
1144 772 : if ( CRSR_SKIP_HIDDEN & nMode )
1145 : {
1146 : xub_StrLen nHiddenStart;
1147 : xub_StrLen nHiddenEnd;
1148 0 : SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1149 0 : if ( nHiddenStart != STRING_LEN && nHiddenStart != nPos )
1150 0 : nPos = nHiddenEnd;
1151 : }
1152 :
1153 772 : if( 1 == nDone )
1154 772 : *pIdx = nPos;
1155 : else
1156 0 : bRet = sal_False;
1157 : }
1158 0 : else if( nPos < rTNd.GetTxt().Len() )
1159 0 : ++(*pIdx);
1160 : else
1161 0 : bRet = sal_False;
1162 : }
1163 : }
1164 : else
1165 36 : bRet = sal_False;
1166 808 : return bRet;
1167 : }
1168 :
1169 :
1170 2200 : sal_Bool SwCntntNode::GoPrevious(SwIndex * pIdx, sal_uInt16 nMode ) const
1171 : {
1172 2200 : sal_Bool bRet = sal_True;
1173 2200 : if( pIdx->GetIndex() > 0 )
1174 : {
1175 62 : if( !IsTxtNode() )
1176 0 : (*pIdx)--;
1177 : else
1178 : {
1179 62 : const SwTxtNode& rTNd = *GetTxtNode();
1180 62 : xub_StrLen nPos = pIdx->GetIndex();
1181 62 : if( pBreakIt->GetBreakIter().is() )
1182 : {
1183 62 : sal_Int32 nDone = 0;
1184 : sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ?
1185 : CharacterIteratorMode::SKIPCELL :
1186 62 : CharacterIteratorMode::SKIPCONTROLCHARACTER;
1187 186 : nPos = (xub_StrLen)pBreakIt->GetBreakIter()->previousCharacters( rTNd.GetTxt(), nPos,
1188 62 : pBreakIt->GetLocale( rTNd.GetLang( nPos ) ),
1189 186 : nItrMode, 1, nDone );
1190 :
1191 : // Check if nPos is inside hidden text range:
1192 62 : if ( CRSR_SKIP_HIDDEN & nMode )
1193 : {
1194 : xub_StrLen nHiddenStart;
1195 : xub_StrLen nHiddenEnd;
1196 0 : SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd );
1197 0 : if ( nHiddenStart != STRING_LEN )
1198 0 : nPos = nHiddenStart;
1199 : }
1200 :
1201 62 : if( 1 == nDone )
1202 62 : *pIdx = nPos;
1203 : else
1204 0 : bRet = sal_False;
1205 : }
1206 0 : else if( nPos )
1207 0 : (*pIdx)--;
1208 : else
1209 0 : bRet = sal_False;
1210 : }
1211 : }
1212 : else
1213 2138 : bRet = sal_False;
1214 2200 : return bRet;
1215 : }
1216 :
1217 :
1218 : /*
1219 : * Creates all Views for the Doc for this Node.
1220 : * The created ContentFrames are attached to the corresponding Layout.
1221 : */
1222 :
1223 16 : void SwCntntNode::MakeFrms( SwCntntNode& rNode )
1224 : {
1225 : OSL_ENSURE( &rNode != this,
1226 : "No ContentNode or CopyNode and new Node identical." );
1227 :
1228 16 : if( !GetDepends() || &rNode == this ) // Do we actually have Frames?
1229 16 : return;
1230 :
1231 : SwFrm *pFrm, *pNew;
1232 : SwLayoutFrm *pUpper;
1233 : // Create Frames for Nodes which come after the Table?
1234 : OSL_ENSURE( FindTableNode() == rNode.FindTableNode(), "Table confusion" );
1235 :
1236 16 : SwNode2Layout aNode2Layout( *this, rNode.GetIndex() );
1237 :
1238 32 : while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) )
1239 : {
1240 0 : pNew = rNode.MakeFrm( pUpper );
1241 0 : pNew->Paste( pUpper, pFrm );
1242 : // #i27138#
1243 : // notify accessibility paragraphs objects about changed
1244 : // CONTENT_FLOWS_FROM/_TO relation.
1245 : // Relation CONTENT_FLOWS_FROM for next paragraph will change
1246 : // and relation CONTENT_FLOWS_TO for previous paragraph will change.
1247 0 : if ( pNew->IsTxtFrm() )
1248 : {
1249 0 : ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
1250 0 : if ( pViewShell && pViewShell->GetLayout() &&
1251 0 : pViewShell->GetLayout()->IsAnyShellAccessible() )
1252 : {
1253 : pViewShell->InvalidateAccessibleParaFlowRelation(
1254 0 : dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
1255 0 : dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) );
1256 : }
1257 : }
1258 16 : }
1259 : }
1260 :
1261 : /*
1262 : * Deletes all Views from the Doc for this Node.
1263 : * The ContentFrames are removed from the corresponding Layout.
1264 : */
1265 :
1266 1438 : void SwCntntNode::DelFrms()
1267 : {
1268 1438 : if( !GetDepends() )
1269 1932 : return;
1270 :
1271 944 : SwCntntFrm::DelFrms(*this);
1272 944 : if( IsTxtNode() )
1273 : {
1274 944 : ((SwTxtNode*)this)->SetWrong( NULL );
1275 944 : ((SwTxtNode*)this)->SetWrongDirty( true );
1276 :
1277 944 : ((SwTxtNode*)this)->SetGrammarCheck( NULL );
1278 944 : ((SwTxtNode*)this)->SetGrammarCheckDirty( true );
1279 : // SMARTTAGS
1280 944 : ((SwTxtNode*)this)->SetSmartTags( NULL );
1281 944 : ((SwTxtNode*)this)->SetSmartTagDirty( true );
1282 :
1283 944 : ((SwTxtNode*)this)->SetWordCountDirty( true );
1284 944 : ((SwTxtNode*)this)->SetAutoCompleteWordDirty( true );
1285 : }
1286 : }
1287 :
1288 :
1289 0 : SwCntntNode *SwCntntNode::JoinNext()
1290 : {
1291 0 : return this;
1292 : }
1293 :
1294 :
1295 0 : SwCntntNode *SwCntntNode::JoinPrev()
1296 : {
1297 0 : return this;
1298 : }
1299 :
1300 :
1301 :
1302 : // Get info from Modify
1303 1832 : bool SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const
1304 : {
1305 1832 : switch( rInfo.Which() )
1306 : {
1307 : case RES_AUTOFMT_DOCNODE:
1308 1832 : if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes )
1309 : {
1310 1416 : ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this;
1311 1416 : return false;
1312 : }
1313 416 : break;
1314 :
1315 : case RES_FINDNEARESTNODE:
1316 0 : if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() )
1317 0 : ((SwFindNearestNode&)rInfo).CheckNode( *this );
1318 0 : return true;
1319 :
1320 : case RES_CONTENT_VISIBLE:
1321 : {
1322 : ((SwPtrMsgPoolItem&)rInfo).pObject =
1323 0 : SwIterator<SwFrm,SwCntntNode>::FirstElement(*this);
1324 : }
1325 0 : return false;
1326 : }
1327 :
1328 416 : return SwModify::GetInfo( rInfo );
1329 : }
1330 :
1331 :
1332 : // Set an Attribute
1333 5920 : sal_Bool SwCntntNode::SetAttr(const SfxPoolItem& rAttr )
1334 : {
1335 5920 : if( !GetpSwAttrSet() ) // Have the Nodes created by the corresponding AttrSets
1336 1638 : NewAttrSet( GetDoc()->GetAttrPool() );
1337 :
1338 : OSL_ENSURE( GetpSwAttrSet(), "Why did't we create an AttrSet?");
1339 :
1340 5920 : if ( IsInCache() )
1341 : {
1342 0 : SwFrm::GetCache().Delete( this );
1343 0 : SetInCache( sal_False );
1344 : }
1345 :
1346 5920 : sal_Bool bRet = sal_False;
1347 : // If Modify is locked, we do not send any Modifys
1348 17190 : if( IsModifyLocked() ||
1349 11270 : ( !GetDepends() && RES_PARATR_NUMRULE != rAttr.Which() ))
1350 : {
1351 4930 : bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rAttr );
1352 : }
1353 : else
1354 : {
1355 990 : SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1356 990 : aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1357 990 : if( 0 != ( bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rAttr, &aOld, &aNew ) ))
1358 : {
1359 990 : SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1360 990 : SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1361 990 : ModifyNotification( &aChgOld, &aChgNew ); // Send all changed ones
1362 990 : }
1363 : }
1364 5920 : return bRet;
1365 : }
1366 : #include <svl/itemiter.hxx>
1367 :
1368 15089 : sal_Bool SwCntntNode::SetAttr( const SfxItemSet& rSet )
1369 : {
1370 15089 : if ( IsInCache() )
1371 : {
1372 0 : SwFrm::GetCache().Delete( this );
1373 0 : SetInCache( sal_False );
1374 : }
1375 :
1376 15089 : const SfxPoolItem* pFnd = 0;
1377 15089 : if( SFX_ITEM_SET == rSet.GetItemState( RES_AUTO_STYLE, sal_False, &pFnd ) )
1378 : {
1379 : OSL_ENSURE( rSet.Count() == 1, "SetAutoStyle mixed with other attributes?!" );
1380 80 : const SwFmtAutoFmt* pTmp = static_cast<const SwFmtAutoFmt*>(pFnd);
1381 :
1382 : // If there already is an attribute set (usually containing a numbering
1383 : // item), we have to merge the attribute of the new set into the old set:
1384 80 : bool bSetParent = true;
1385 80 : if ( GetpSwAttrSet() )
1386 : {
1387 2 : bSetParent = false;
1388 2 : AttrSetHandleHelper::Put( mpAttrSet, *this, *pTmp->GetStyleHandle() );
1389 : }
1390 : else
1391 : {
1392 78 : mpAttrSet = pTmp->GetStyleHandle();
1393 : }
1394 :
1395 80 : if ( bSetParent )
1396 : {
1397 : // If the content node has a conditional style, we have to set the
1398 : // string item containing the correct conditional style name (the
1399 : // style name property has already been set during the import!)
1400 : // In case we do not have a conditional style, we make use of the
1401 : // fact that nobody else uses the attribute set behind the handle.
1402 : // FME 2007-07-10 #i78124# If autostyle does not have a parent,
1403 : // the string is empty.
1404 78 : const SfxPoolItem* pNameItem = 0;
1405 234 : if ( 0 != GetCondFmtColl() ||
1406 78 : SFX_ITEM_SET != mpAttrSet->GetItemState( RES_FRMATR_STYLE_NAME, sal_False, &pNameItem ) ||
1407 78 : 0 == static_cast<const SfxStringItem*>(pNameItem)->GetValue().Len() )
1408 0 : AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1409 : else
1410 78 : const_cast<SfxItemSet*>(mpAttrSet.get())->SetParent( &GetFmtColl()->GetAttrSet() );
1411 : }
1412 :
1413 80 : return sal_True;
1414 : }
1415 :
1416 15009 : if( !GetpSwAttrSet() ) // Have the AttrsSets created by the corresponding Nodes
1417 6451 : NewAttrSet( GetDoc()->GetAttrPool() );
1418 :
1419 15009 : sal_Bool bRet = sal_False;
1420 : // If Modify is locked, do not send any Modifys
1421 39757 : if ( IsModifyLocked() ||
1422 13529 : ( !GetDepends() &&
1423 11219 : SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_NUMRULE, sal_False ) ) )
1424 : {
1425 : // Some special treatment for Attributes
1426 12246 : bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rSet );
1427 : }
1428 : else
1429 : {
1430 2763 : SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1431 2763 : aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1432 2763 : if( 0 != (bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rSet, &aOld, &aNew )) )
1433 : {
1434 : // Some special treatment for Attributes
1435 2053 : SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1436 2053 : SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1437 2053 : ModifyNotification( &aChgOld, &aChgNew ); // Send out all changed ones
1438 2763 : }
1439 : }
1440 15009 : return bRet;
1441 : }
1442 :
1443 : // With nWhich it takes the Hint from the Delta array
1444 40857 : sal_Bool SwCntntNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
1445 : {
1446 40857 : if( !GetpSwAttrSet() )
1447 28761 : return sal_False;
1448 :
1449 12096 : if ( IsInCache() )
1450 : {
1451 0 : SwFrm::GetCache().Delete( this );
1452 0 : SetInCache( sal_False );
1453 : }
1454 :
1455 : // If Modify is locked, do not send out any Modifys
1456 12096 : if( IsModifyLocked() )
1457 : {
1458 0 : sal_uInt16 nDel = 0;
1459 0 : if ( !nWhich2 || nWhich2 < nWhich1 )
1460 : {
1461 0 : std::vector<sal_uInt16> aClearWhichIds;
1462 0 : aClearWhichIds.push_back( nWhich1 );
1463 0 : nDel = ClearItemsFromAttrSet( aClearWhichIds );
1464 : }
1465 : else
1466 0 : nDel = AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, 0, 0 );
1467 :
1468 0 : if( !GetpSwAttrSet()->Count() ) // Empt? Delete
1469 0 : mpAttrSet.reset();
1470 0 : return 0 != nDel;
1471 : }
1472 :
1473 : // No valid area defined?
1474 12096 : if( !nWhich2 || nWhich2 < nWhich1 )
1475 12096 : nWhich2 = nWhich1; // Then set only this Item to 1st Id
1476 :
1477 12096 : SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1478 12096 : aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1479 12096 : sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, &aOld, &aNew );
1480 :
1481 12096 : if( bRet )
1482 : {
1483 1378 : SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1484 1378 : SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1485 1378 : ModifyNotification( &aChgOld, &aChgNew ); // All changed ones are sent
1486 :
1487 1378 : if( !GetpSwAttrSet()->Count() ) // Empty?, delete it
1488 0 : mpAttrSet.reset();
1489 : }
1490 12096 : return bRet;
1491 : }
1492 2616 : sal_Bool SwCntntNode::ResetAttr( const std::vector<sal_uInt16>& rWhichArr )
1493 : {
1494 2616 : if( !GetpSwAttrSet() )
1495 80 : return sal_False;
1496 :
1497 2536 : if ( IsInCache() )
1498 : {
1499 0 : SwFrm::GetCache().Delete( this );
1500 0 : SetInCache( sal_False );
1501 : }
1502 :
1503 : // If Modify is locked, do not send out any Modifys
1504 2536 : sal_uInt16 nDel = 0;
1505 2536 : if( IsModifyLocked() )
1506 : {
1507 2446 : std::vector<sal_uInt16> aClearWhichIds(rWhichArr);
1508 2446 : nDel = ClearItemsFromAttrSet( aClearWhichIds );
1509 : }
1510 : else
1511 : {
1512 90 : SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1513 90 : aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1514 :
1515 90 : std::vector<sal_uInt16>::const_iterator it;
1516 3600 : for ( it = rWhichArr.begin(); it != rWhichArr.end(); ++it )
1517 3510 : if( AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, *it, &aOld, &aNew ))
1518 46 : ++nDel;
1519 :
1520 90 : if( nDel )
1521 : {
1522 16 : SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1523 16 : SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1524 16 : ModifyNotification( &aChgOld, &aChgNew ); // All changed ones are sent
1525 90 : }
1526 : }
1527 2536 : if( !GetpSwAttrSet()->Count() ) // Empty?, delete it
1528 0 : mpAttrSet.reset();
1529 2536 : return 0 != nDel ;
1530 : }
1531 :
1532 :
1533 2840 : sal_uInt16 SwCntntNode::ResetAllAttr()
1534 : {
1535 2840 : if( !GetpSwAttrSet() )
1536 394 : return 0;
1537 :
1538 2446 : if ( IsInCache() )
1539 : {
1540 0 : SwFrm::GetCache().Delete( this );
1541 0 : SetInCache( sal_False );
1542 : }
1543 :
1544 : // If Modify is locked, do not send out any Modifys
1545 2446 : if( IsModifyLocked() )
1546 : {
1547 0 : std::vector<sal_uInt16> aClearWhichIds;
1548 0 : aClearWhichIds.push_back(0);
1549 0 : sal_uInt16 nDel = ClearItemsFromAttrSet( aClearWhichIds );
1550 0 : if( !GetpSwAttrSet()->Count() ) // Empty? Delete
1551 0 : mpAttrSet.reset();
1552 0 : return nDel;
1553 : }
1554 :
1555 2446 : SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ),
1556 2446 : aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() );
1557 2446 : sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, 0, &aOld, &aNew );
1558 :
1559 2446 : if( bRet )
1560 : {
1561 2446 : SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld );
1562 2446 : SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew );
1563 2446 : ModifyNotification( &aChgOld, &aChgNew ); // All changed ones are sent
1564 :
1565 2446 : if( !GetpSwAttrSet()->Count() ) // Empty? Delete
1566 2446 : mpAttrSet.reset();
1567 : }
1568 2446 : return aNew.Count();
1569 : }
1570 :
1571 :
1572 29739 : sal_Bool SwCntntNode::GetAttr( SfxItemSet& rSet, sal_Bool bInParent ) const
1573 : {
1574 29739 : if( rSet.Count() )
1575 0 : rSet.ClearItem();
1576 :
1577 29739 : const SwAttrSet& rAttrSet = GetSwAttrSet();
1578 29739 : if( bInParent )
1579 29739 : return rSet.Set( rAttrSet, sal_True ) ? sal_True : sal_False;
1580 :
1581 0 : rSet.Put( rAttrSet );
1582 0 : return rSet.Count() ? sal_True : sal_False;
1583 : }
1584 :
1585 2986 : sal_uInt16 SwCntntNode::ClearItemsFromAttrSet( const std::vector<sal_uInt16>& rWhichIds )
1586 : {
1587 2986 : sal_uInt16 nRet = 0;
1588 2986 : if ( 0 == rWhichIds.size() )
1589 966 : return nRet;
1590 :
1591 : OSL_ENSURE( GetpSwAttrSet(), "no item set" );
1592 2020 : SwAttrSet aNewAttrSet( *GetpSwAttrSet() );
1593 13374 : for ( std::vector<sal_uInt16>::const_iterator aIter = rWhichIds.begin();
1594 8916 : aIter != rWhichIds.end();
1595 : ++aIter )
1596 : {
1597 2438 : nRet = nRet + aNewAttrSet.ClearItem( *aIter );
1598 : }
1599 2020 : if ( nRet )
1600 1480 : AttrSetHandleHelper::GetNewAutoStyle( mpAttrSet, *this, aNewAttrSet );
1601 :
1602 2020 : return nRet;
1603 : }
1604 :
1605 125844 : const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich,
1606 : sal_Bool bInParents ) const
1607 : {
1608 125844 : const SfxPoolItem* pFnd = 0;
1609 125844 : if( pCondColl && pCondColl->GetRegisteredIn() )
1610 : {
1611 0 : if( !GetpSwAttrSet() || ( SFX_ITEM_SET != GetpSwAttrSet()->GetItemState(
1612 0 : nWhich, sal_False, &pFnd ) && bInParents ))
1613 0 : ((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd );
1614 : }
1615 : // undo change of issue #i51029#
1616 : // Note: <GetSwAttrSet()> returns <mpAttrSet>, if set, otherwise it returns
1617 : // the attribute set of the paragraph style, which is valid for the
1618 : // content node - see file <node.hxx>
1619 : else
1620 : {
1621 125844 : GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd );
1622 : }
1623 125844 : return pFnd;
1624 : }
1625 :
1626 : // Can we join two Nodes?
1627 : // We can return the 2nd position in pIdx.
1628 1208 : int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
1629 : {
1630 1208 : const SwNodes& rNds = GetNodes();
1631 1208 : sal_uInt8 nNdType = GetNodeType();
1632 1208 : SwNodeIndex aIdx( *this, 1 );
1633 :
1634 1208 : const SwNode* pNd = this;
1635 5352 : while( aIdx < rNds.Count()-1 &&
1636 1338 : (( pNd = &aIdx.GetNode())->IsSectionNode() ||
1637 1468 : ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1638 130 : ++aIdx;
1639 :
1640 1208 : if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() )
1641 0 : return sal_False;
1642 1208 : if( IsTxtNode() )
1643 : { // Do not merge strings if the result exceeds the allowed string length
1644 1208 : const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this);
1645 1208 : sal_uInt64 nSum = pTxtNd->GetTxt().Len();
1646 1208 : pTxtNd = static_cast<const SwTxtNode*>(pNd);
1647 1208 : nSum += pTxtNd->GetTxt().Len();
1648 1208 : if( nSum > STRING_LEN )
1649 0 : return sal_False;
1650 : }
1651 1208 : if( pIdx )
1652 1208 : *pIdx = aIdx;
1653 1208 : return sal_True;
1654 : }
1655 :
1656 : // Can we join two Nodes?
1657 : // We can return the 2nd position in pIdx.
1658 0 : int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
1659 : {
1660 0 : sal_uInt8 nNdType = GetNodeType();
1661 0 : SwNodeIndex aIdx( *this, -1 );
1662 :
1663 0 : const SwNode* pNd = this;
1664 0 : while( aIdx.GetIndex() &&
1665 0 : (( pNd = &aIdx.GetNode())->IsSectionNode() ||
1666 0 : ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
1667 0 : aIdx--;
1668 :
1669 0 : if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() )
1670 0 : return sal_False;
1671 0 : if( pIdx )
1672 0 : *pIdx = aIdx;
1673 0 : return sal_True;
1674 : }
1675 :
1676 :
1677 : //FEATURE::CONDCOLL
1678 :
1679 :
1680 2398 : void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl )
1681 : {
1682 2398 : if( (!pColl && pCondColl) || ( pColl && !pCondColl ) ||
1683 0 : ( pColl && pColl != pCondColl->GetRegisteredIn() ) )
1684 : {
1685 0 : SwFmtColl* pOldColl = GetCondFmtColl();
1686 0 : delete pCondColl;
1687 0 : if( pColl )
1688 0 : pCondColl = new SwDepend( this, pColl );
1689 : else
1690 0 : pCondColl = 0;
1691 :
1692 0 : if( GetpSwAttrSet() )
1693 : {
1694 0 : AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() );
1695 : }
1696 :
1697 0 : if( !IsModifyLocked() )
1698 : {
1699 0 : SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() );
1700 0 : SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() );
1701 0 : NotifyClients( &aTmp1, &aTmp2 );
1702 : }
1703 0 : if( IsInCache() )
1704 : {
1705 0 : SwFrm::GetCache().Delete( this );
1706 0 : SetInCache( sal_False );
1707 : }
1708 : }
1709 2398 : }
1710 :
1711 :
1712 2 : sal_Bool SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const
1713 : {
1714 2 : const SwNodes& rNds = GetNodes();
1715 : {
1716 2 : int nCond = 0;
1717 2 : const SwStartNode* pSttNd = StartOfSectionNode();
1718 8 : while( pSttNd )
1719 : {
1720 4 : switch( pSttNd->GetNodeType() )
1721 : {
1722 0 : case ND_TABLENODE: nCond = PARA_IN_TABLEBODY; break;
1723 0 : case ND_SECTIONNODE: nCond = PARA_IN_SECTION; break;
1724 :
1725 : default:
1726 4 : switch( pSttNd->GetStartNodeType() )
1727 : {
1728 : case SwTableBoxStartNode:
1729 : {
1730 0 : nCond = PARA_IN_TABLEBODY;
1731 0 : const SwTableNode* pTblNd = pSttNd->FindTableNode();
1732 : const SwTableBox* pBox;
1733 0 : if( pTblNd && 0 != ( pBox = pTblNd->GetTable().
1734 0 : GetTblBox( pSttNd->GetIndex() ) ) && pBox &&
1735 0 : pBox->IsInHeadline( &pTblNd->GetTable() ) )
1736 0 : nCond = PARA_IN_TABLEHEAD;
1737 : }
1738 0 : break;
1739 0 : case SwFlyStartNode: nCond = PARA_IN_FRAME; break;
1740 : case SwFootnoteStartNode:
1741 : {
1742 0 : nCond = PARA_IN_FOOTENOTE;
1743 0 : const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs();
1744 : const SwTxtFtn* pTxtFtn;
1745 0 : const SwNode* pSrchNd = pSttNd;
1746 :
1747 0 : for( sal_uInt16 n = 0; n < rFtnArr.size(); ++n )
1748 0 : if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() &&
1749 0 : pSrchNd == &pTxtFtn->GetStartNode()->GetNode() )
1750 : {
1751 0 : if( pTxtFtn->GetFtn().IsEndNote() )
1752 0 : nCond = PARA_IN_ENDNOTE;
1753 0 : break;
1754 : }
1755 : }
1756 0 : break;
1757 0 : case SwHeaderStartNode: nCond = PARA_IN_HEADER; break;
1758 0 : case SwFooterStartNode: nCond = PARA_IN_FOOTER; break;
1759 4 : case SwNormalStartNode: break;
1760 : }
1761 : }
1762 :
1763 4 : if( nCond )
1764 : {
1765 0 : rTmp.SetCondition( (Master_CollConditions)nCond, 0 );
1766 0 : return sal_True;
1767 : }
1768 4 : pSttNd = pSttNd->GetIndex()
1769 2 : ? pSttNd->StartOfSectionNode()
1770 6 : : 0;
1771 : }
1772 : }
1773 :
1774 : {
1775 : sal_uInt16 nPos;
1776 2 : const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1777 2 : if( !rOutlNds.empty() )
1778 : {
1779 0 : if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos )
1780 0 : --nPos;
1781 0 : if( nPos < rOutlNds.size() &&
1782 0 : rOutlNds[ nPos ]->GetIndex() < GetIndex() )
1783 : {
1784 0 : SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode();
1785 :
1786 0 : if( pOutlNd->IsOutline())
1787 : {
1788 0 : rTmp.SetCondition( PARA_IN_OUTLINE, pOutlNd->GetAttrOutlineLevel() - 1 );
1789 0 : return sal_True;
1790 : }
1791 : }
1792 : }
1793 : }
1794 :
1795 2 : return sal_False;
1796 : }
1797 :
1798 :
1799 154 : void SwCntntNode::ChkCondColl()
1800 : {
1801 : // Check, just to be sure
1802 154 : if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() )
1803 : {
1804 2 : SwCollCondition aTmp( 0, 0, 0 );
1805 : const SwCollCondition* pCColl;
1806 :
1807 2 : bool bDone = false;
1808 :
1809 2 : if( IsAnyCondition( aTmp ))
1810 : {
1811 0 : pCColl = static_cast<SwConditionTxtFmtColl*>(GetFmtColl())
1812 0 : ->HasCondition( aTmp );
1813 :
1814 0 : if (pCColl)
1815 : {
1816 0 : SetCondFmtColl( pCColl->GetTxtFmtColl() );
1817 0 : bDone = true;
1818 : }
1819 : }
1820 :
1821 2 : if (!bDone)
1822 : {
1823 2 : if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule())
1824 : {
1825 : // Is at which Level in a list?
1826 : aTmp.SetCondition( PARA_IN_LIST,
1827 0 : ((SwTxtNode*)this)->GetActualListLevel() );
1828 0 : pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())->
1829 0 : HasCondition( aTmp );
1830 : }
1831 : else
1832 2 : pCColl = 0;
1833 :
1834 2 : if( pCColl )
1835 0 : SetCondFmtColl( pCColl->GetTxtFmtColl() );
1836 2 : else if( pCondColl )
1837 0 : SetCondFmtColl( 0 );
1838 2 : }
1839 : }
1840 154 : }
1841 :
1842 : // #i42921#
1843 1351 : short SwCntntNode::GetTextDirection( const SwPosition& rPos,
1844 : const Point* pPt ) const
1845 : {
1846 1351 : short nRet = -1;
1847 :
1848 1351 : Point aPt;
1849 1351 : if( pPt )
1850 567 : aPt = *pPt;
1851 :
1852 : // #i72024# - No format of the frame, because this can cause recursive layout actions
1853 1351 : SwFrm* pFrm = getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, &rPos, sal_False );
1854 :
1855 1351 : if ( pFrm )
1856 : {
1857 1351 : if ( pFrm->IsVertical() )
1858 : {
1859 0 : if ( pFrm->IsRightToLeft() )
1860 0 : nRet = FRMDIR_VERT_TOP_LEFT;
1861 : else
1862 0 : nRet = FRMDIR_VERT_TOP_RIGHT;
1863 : }
1864 : else
1865 : {
1866 1351 : if ( pFrm->IsRightToLeft() )
1867 0 : nRet = FRMDIR_HORI_RIGHT_TOP;
1868 : else
1869 1351 : nRet = FRMDIR_HORI_LEFT_TOP;
1870 : }
1871 : }
1872 :
1873 :
1874 1351 : return nRet;
1875 : }
1876 :
1877 2 : SwOLENodes* SwCntntNode::CreateOLENodesArray( const SwFmtColl& rColl, bool bOnlyWithInvalidSize )
1878 : {
1879 2 : SwOLENodes *pNodes = 0;
1880 2 : SwIterator<SwCntntNode,SwFmtColl> aIter( rColl );
1881 2 : for( SwCntntNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
1882 : {
1883 0 : SwOLENode *pONd = pNd->GetOLENode();
1884 0 : if ( pONd && (!bOnlyWithInvalidSize || pONd->IsOLESizeInvalid()) )
1885 : {
1886 0 : if ( !pNodes )
1887 0 : pNodes = new SwOLENodes;
1888 0 : pNodes->push_back( pONd );
1889 : }
1890 : }
1891 :
1892 2 : return pNodes;
1893 : }
1894 :
1895 : /*
1896 : * Document Interface Access
1897 : */
1898 59149 : const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return GetDoc(); }
1899 6181 : const IDocumentDeviceAccess* SwNode::getIDocumentDeviceAccess() const { return GetDoc(); }
1900 96176 : const IDocumentMarkAccess* SwNode::getIDocumentMarkAccess() const { return GetDoc()->getIDocumentMarkAccess(); }
1901 16177 : const IDocumentRedlineAccess* SwNode::getIDocumentRedlineAccess() const { return GetDoc(); }
1902 0 : const IDocumentStylePoolAccess* SwNode::getIDocumentStylePoolAccess() const { return GetDoc(); }
1903 3605 : const IDocumentLineNumberAccess* SwNode::getIDocumentLineNumberAccess() const { return GetDoc(); }
1904 767 : const IDocumentDrawModelAccess* SwNode::getIDocumentDrawModelAccess() const { return GetDoc(); }
1905 0 : const IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() const { return GetDoc(); }
1906 9357 : IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() { return GetDoc(); }
1907 2 : const IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() const { return GetDoc(); }
1908 2 : IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() { return GetDoc(); }
1909 0 : const IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() const { return GetDoc(); }
1910 16 : IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() { return GetDoc(); }
1911 0 : IDocumentContentOperations* SwNode::getIDocumentContentOperations() { return GetDoc(); }
1912 3746 : IStyleAccess& SwNode::getIDocumentStyleAccess() { return GetDoc()->GetIStyleAccess(); }
1913 : // #i83479#
1914 5450 : IDocumentListItems& SwNode::getIDocumentListItems()
1915 : {
1916 5450 : return *GetDoc();
1917 : }
1918 :
1919 9455 : sal_Bool SwNode::IsInRedlines() const
1920 : {
1921 9455 : const SwDoc * pDoc = GetDoc();
1922 9455 : sal_Bool bResult = sal_False;
1923 :
1924 9455 : if (pDoc != NULL)
1925 9455 : bResult = pDoc->IsInRedlines(*this);
1926 :
1927 9455 : return bResult;
1928 : }
1929 :
1930 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|