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