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