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 <hints.hxx>
22 :
23 : #include <comphelper/string.hxx>
24 : #include <editeng/fontitem.hxx>
25 : #include <editeng/formatbreakitem.hxx>
26 : #include <editeng/escapementitem.hxx>
27 : #include <editeng/lrspitem.hxx>
28 : #include <editeng/rsiditem.hxx>
29 : #include <editeng/tstpitem.hxx>
30 : #include <svl/urihelper.hxx>
31 : #include <svl/ctloptions.hxx>
32 : #include <swmodule.hxx>
33 : #include <txtfld.hxx>
34 : #include <txtinet.hxx>
35 : #include <fmtinfmt.hxx>
36 : #include <fmtpdsc.hxx>
37 : #include <txtatr.hxx>
38 : #include <fmtrfmrk.hxx>
39 : #include <txttxmrk.hxx>
40 : #include <fchrfmt.hxx>
41 : #include <txtftn.hxx>
42 : #include <fmtflcnt.hxx>
43 : #include <fmtfld.hxx>
44 : #include <frmatr.hxx>
45 : #include <charatr.hxx>
46 : #include <ftnidx.hxx>
47 : #include <ftninfo.hxx>
48 : #include <fmtftn.hxx>
49 : #include <fmtmeta.hxx>
50 : #include <charfmt.hxx>
51 : #include <ndtxt.hxx>
52 : #include <doc.hxx>
53 : #include <IDocumentUndoRedo.hxx>
54 : #include <IDocumentSettingAccess.hxx>
55 : #include <IDocumentListsAccess.hxx>
56 : #include <IDocumentRedlineAccess.hxx>
57 : #include <IDocumentLayoutAccess.hxx>
58 : #include <docary.hxx>
59 : #include <pam.hxx>
60 : #include <fldbas.hxx>
61 : #include <paratr.hxx>
62 : #include <txtfrm.hxx>
63 : #include <ftnfrm.hxx>
64 : #include <ftnboss.hxx>
65 : #include <rootfrm.hxx>
66 : #include <pagedesc.hxx>
67 : #include <expfld.hxx>
68 : #include <section.hxx>
69 : #include <mvsave.hxx>
70 : #include <swcache.hxx>
71 : #include <SwGrammarMarkUp.hxx>
72 : #include <dcontact.hxx>
73 : #include <redline.hxx>
74 : #include <doctxm.hxx>
75 : #include <IMark.hxx>
76 : #include <scriptinfo.hxx>
77 : #include <istyleaccess.hxx>
78 : #include <SwStyleNameMapper.hxx>
79 : #include <numrule.hxx>
80 : #include <swtable.hxx>
81 : #include <docsh.hxx>
82 : #include <SwNodeNum.hxx>
83 : #include <svl/intitem.hxx>
84 : #include <list.hxx>
85 : #include <sortedobjs.hxx>
86 : #include <calbck.hxx>
87 : #include <attrhint.hxx>
88 : #include <memory>
89 :
90 : //UUUU
91 : #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
92 : #include <svl/itemiter.hxx>
93 :
94 : using namespace ::com::sun::star;
95 :
96 : typedef std::vector<SwTextAttr*> SwpHts;
97 :
98 318162 : TYPEINIT1( SwTextNode, SwContentNode )
99 :
100 : // unfortunately everyone can change Hints without ensuring order or the linking between them
101 : #ifdef DBG_UTIL
102 : #define CHECK_SWPHINTS(pNd) { if( pNd->GetpSwpHints() && \
103 : !pNd->GetDoc()->IsInReading() ) \
104 : pNd->GetpSwpHints()->Check(true); }
105 : #else
106 : #define CHECK_SWPHINTS(pNd)
107 : #endif
108 :
109 10795 : SwTextNode *SwNodes::MakeTextNode( const SwNodeIndex & rWhere,
110 : SwTextFormatColl *pColl,
111 : SwAttrSet* pAutoAttr )
112 : {
113 : OSL_ENSURE( pColl, "Collection pointer is 0." );
114 :
115 10795 : SwTextNode *pNode = new SwTextNode( rWhere, pColl, pAutoAttr );
116 :
117 10795 : SwNodeIndex aIdx( *pNode );
118 :
119 : // #125329#
120 : // call method <UpdateOutlineNode(..)> only for the document nodes array
121 10795 : if ( IsDocNodes() )
122 10795 : UpdateOutlineNode(*pNode);
123 :
124 : // if there is no layout or it is in a hidden section, MakeFrms is not needed
125 : const SwSectionNode* pSectNd;
126 21602 : if( !GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() ||
127 648 : ( 0 != (pSectNd = pNode->FindSectionNode()) &&
128 30 : pSectNd->GetSection().IsHiddenFlag() ))
129 10189 : return pNode;
130 :
131 1212 : SwNodeIndex aTmp( rWhere );
132 : do {
133 : // max. 2 loops:
134 : // 1. take the successor
135 : // 2. take the predecessor
136 :
137 1056 : SwNode * pNd = & aTmp.GetNode();
138 1056 : switch (pNd->GetNodeType())
139 : {
140 : case ND_TABLENODE:
141 4 : static_cast<SwTableNode*>(pNd)->MakeFrms( aIdx );
142 4 : return pNode;
143 :
144 : case ND_SECTIONNODE:
145 4 : if( static_cast<SwSectionNode*>(pNd)->GetSection().IsHidden() ||
146 2 : static_cast<SwSectionNode*>(pNd)->IsContentHidden() )
147 : {
148 0 : SwNodeIndex aTmpIdx( *pNode );
149 0 : pNd = FindPrvNxtFrmNode( aTmpIdx, pNode );
150 0 : if( !pNd )
151 0 : return pNode;
152 0 : aTmp = *pNd;
153 0 : break;
154 : }
155 2 : static_cast<SwSectionNode*>(pNd)->MakeFrms( aIdx );
156 2 : return pNode;
157 :
158 : case ND_TEXTNODE:
159 : case ND_GRFNODE:
160 : case ND_OLENODE:
161 229 : static_cast<SwContentNode*>(pNd)->MakeFrms( *pNode );
162 229 : return pNode;
163 :
164 : case ND_ENDNODE:
165 475 : if( pNd->StartOfSectionNode()->IsSectionNode() &&
166 0 : aTmp.GetIndex() < rWhere.GetIndex() )
167 : {
168 0 : if( pNd->StartOfSectionNode()->GetSectionNode()->GetSection().IsHiddenFlag())
169 : {
170 0 : if( !GoPrevSection( &aTmp, true, false ) ||
171 0 : aTmp.GetNode().FindTableNode() !=
172 0 : pNode->FindTableNode() )
173 0 : return pNode; // schade, das wars
174 : }
175 : else
176 0 : aTmp = *pNd->StartOfSectionNode();
177 0 : break;
178 : }
179 477 : else if( pNd->StartOfSectionNode()->IsTableNode() &&
180 2 : aTmp.GetIndex() < rWhere.GetIndex() )
181 : {
182 : // after a table node
183 0 : aTmp = *pNd->StartOfSectionNode();
184 0 : break;
185 : }
186 : // no break !!!
187 : default:
188 821 : if( rWhere == aTmp )
189 450 : aTmp -= 2;
190 : else
191 371 : return pNode;
192 450 : break;
193 : }
194 10795 : } while( true );
195 : }
196 :
197 55858 : SwTextNode::SwTextNode( const SwNodeIndex &rWhere, SwTextFormatColl *pTextColl, const SfxItemSet* pAutoAttr )
198 : : SwContentNode( rWhere, ND_TEXTNODE, pTextColl ),
199 : m_pSwpHints( 0 ),
200 : mpNodeNum( 0 ),
201 : m_Text(),
202 : m_pParaIdleData_Impl(0),
203 : m_bContainsHiddenChars(false),
204 : m_bHiddenCharsHidePara(false),
205 : m_bRecalcHiddenCharFlags(false),
206 : m_bLastOutlineState( false ),
207 : m_bNotifiable( false ),
208 : mbEmptyListStyleSetDueToSetOutlineLevelAttr( false ),
209 : mbInSetOrResetAttr( false ),
210 : mpList( 0 ),
211 : m_pNumStringCache(),
212 : m_wXParagraph(),
213 55858 : maFillAttributes()
214 : {
215 55858 : InitSwParaStatistics( true );
216 :
217 55858 : if( pAutoAttr )
218 3055 : SetAttr( *pAutoAttr );
219 :
220 55858 : if (!IsInList() && GetNumRule() && !GetListId().isEmpty())
221 : {
222 : // #i101516#
223 : // apply paragraph style's assigned outline style list level as
224 : // list level of the paragraph, if it has none set already.
225 414 : if ( !HasAttrListLevel() &&
226 207 : pTextColl && pTextColl->IsAssignedToListLevelOfOutlineStyle() )
227 : {
228 0 : SetAttrListLevel( pTextColl->GetAssignedOutlineStyleLevel() );
229 : }
230 207 : AddToList();
231 : }
232 55858 : GetNodes().UpdateOutlineNode(*this);
233 :
234 55858 : m_bNotifiable = true;
235 :
236 55858 : m_bContainsHiddenChars = m_bHiddenCharsHidePara = false;
237 55858 : m_bRecalcHiddenCharFlags = true;
238 55858 : }
239 :
240 165048 : SwTextNode::~SwTextNode()
241 : {
242 : // delete only removes the pointer not the array elements!
243 55016 : if ( m_pSwpHints )
244 : {
245 : // do not delete attributes twice when those delte their content
246 17954 : SwpHints* pTmpHints = m_pSwpHints;
247 17954 : m_pSwpHints = 0;
248 :
249 74969 : for( size_t j = pTmpHints->Count(); j; )
250 : {
251 : // first remove the attribute from the array otherwise
252 : // if would delete itself
253 39061 : DestroyAttr( pTmpHints->GetTextHint( --j ) );
254 : }
255 :
256 17954 : delete pTmpHints;
257 : }
258 :
259 : // must be removed from outline nodes by now
260 : #if OSL_DEBUG_LEVEL > 0
261 : sal_uInt16 foo;
262 : assert(!GetNodes().GetOutLineNds().Seek_Entry(this, &foo));
263 : #endif
264 :
265 55016 : RemoveFromList();
266 :
267 55016 : InitSwParaStatistics( false );
268 :
269 55016 : if (HasWriterListeners())
270 : {
271 3313 : DelFrms_TextNodePart();
272 : }
273 110032 : }
274 :
275 36977 : void SwTextNode::FileLoadedInitHints()
276 : {
277 36977 : if (m_pSwpHints)
278 : {
279 14798 : m_pSwpHints->MergePortions(*this);
280 : }
281 36977 : }
282 :
283 36977 : SwContentFrm *SwTextNode::MakeFrm( SwFrm* pSib )
284 : {
285 : // fdo#52028: ODF file import does not result in MergePortions being called
286 : // for every attribute, since that would be inefficient. So call it here.
287 36977 : FileLoadedInitHints();
288 36977 : SwContentFrm *pFrm = new SwTextFrm( this, pSib );
289 36977 : return pFrm;
290 : }
291 :
292 841636 : sal_Int32 SwTextNode::Len() const
293 : {
294 841636 : return m_Text.getLength();
295 : }
296 :
297 : // After a split node, it's necessary to actualize the ref-pointer of the ftnfrms.
298 1376 : static void lcl_ChangeFootnoteRef( SwTextNode &rNode )
299 : {
300 1376 : SwpHints *pSwpHints = rNode.GetpSwpHints();
301 1376 : if( pSwpHints && rNode.GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() )
302 : {
303 2 : SwContentFrm* pFrm = NULL;
304 : // OD 07.11.2002 #104840# - local variable to remember first footnote
305 : // of node <rNode> in order to invalidate position of its first content.
306 : // Thus, in its <MakeAll()> it will checked its position relative to its reference.
307 2 : SwFootnoteFrm* pFirstFootnoteOfNode = 0;
308 6 : for( size_t j = pSwpHints->Count(); j; )
309 : {
310 2 : SwTextAttr* pHt = pSwpHints->GetTextHint(--j);
311 2 : if (RES_TXTATR_FTN == pHt->Which())
312 : {
313 0 : if( !pFrm )
314 : {
315 0 : pFrm = SwIterator<SwContentFrm,SwTextNode>(rNode).First();
316 0 : if (!pFrm)
317 1376 : return;
318 : }
319 0 : SwTextFootnote *pAttr = static_cast<SwTextFootnote*>(pHt);
320 : OSL_ENSURE( pAttr->GetStartNode(), "FootnoteAtr ohne StartNode." );
321 0 : SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
322 0 : SwContentNode *pNd = aIdx.GetNode().GetContentNode();
323 0 : if ( !pNd )
324 : pNd = pFrm->GetAttrSet()->GetDoc()->
325 0 : GetNodes().GoNextSection( &aIdx, true, false );
326 0 : if ( !pNd )
327 0 : continue;
328 :
329 0 : SwIterator<SwContentFrm,SwContentNode> aIter( *pNd );
330 0 : SwContentFrm* pContent = aIter.First();
331 0 : if( pContent )
332 : {
333 : OSL_ENSURE( pContent->getRootFrm() == pFrm->getRootFrm(),
334 : "lcl_ChangeFootnoteRef: Layout double?" );
335 0 : SwFootnoteFrm *pFootnote = pContent->FindFootnoteFrm();
336 0 : if( pFootnote && pFootnote->GetAttr() == pAttr )
337 : {
338 0 : while( pFootnote->GetMaster() )
339 0 : pFootnote = pFootnote->GetMaster();
340 : // #104840# - remember footnote frame
341 0 : pFirstFootnoteOfNode = pFootnote;
342 0 : while ( pFootnote )
343 : {
344 0 : pFootnote->SetRef( pFrm );
345 0 : pFootnote = pFootnote->GetFollow();
346 0 : static_cast<SwTextFrm*>(pFrm)->SetFootnote( true );
347 : }
348 : }
349 : #if OSL_DEBUG_LEVEL > 0
350 : while( 0 != (pContent = aIter.Next()) )
351 : {
352 : SwFootnoteFrm *pDbgFootnote = pContent->FindFootnoteFrm();
353 : OSL_ENSURE( !pDbgFootnote || pDbgFootnote->GetRef() == pFrm,
354 : "lcl_ChangeFootnoteRef: Who's that guy?" );
355 : }
356 : #endif
357 0 : }
358 : }
359 : } // end of for-loop on <SwpHints>
360 : // #104840# - invalidate
361 2 : if ( pFirstFootnoteOfNode )
362 : {
363 0 : SwContentFrm* pContent = pFirstFootnoteOfNode->ContainsContent();
364 0 : if ( pContent )
365 : {
366 0 : pContent->_InvalidatePos();
367 : }
368 : }
369 : }
370 : }
371 :
372 1376 : SwContentNode *SwTextNode::SplitContentNode( const SwPosition &rPos )
373 : {
374 1376 : bool parentIsOutline = IsOutline();
375 :
376 : // create a node "in front" of me
377 1376 : const sal_Int32 nSplitPos = rPos.nContent.GetIndex();
378 1376 : const sal_Int32 nTextLen = m_Text.getLength();
379 : SwTextNode* const pNode =
380 1376 : _MakeNewTextNode( rPos.nNode, false, nSplitPos==nTextLen );
381 :
382 : // the first paragraph gets the XmlId,
383 : // _except_ if it is empty and the second is not empty
384 1376 : if (nSplitPos != 0) {
385 1121 : pNode->RegisterAsCopyOf(*this, true);
386 1121 : if (nSplitPos == nTextLen)
387 : {
388 1084 : this->RemoveMetadataReference();
389 : // NB: SwUndoSplitNode will call pNode->JoinNext,
390 : // which is sufficient even in this case!
391 : }
392 : }
393 :
394 1376 : ResetAttr( RES_PARATR_LIST_ISRESTART );
395 1376 : ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
396 1376 : ResetAttr( RES_PARATR_LIST_ISCOUNTED );
397 1376 : if ( GetNumRule() == 0 || (parentIsOutline && !IsOutline()) )
398 : {
399 1367 : ResetAttr( RES_PARATR_LIST_ID );
400 1367 : ResetAttr( RES_PARATR_LIST_LEVEL );
401 : }
402 :
403 1376 : if ( HasWriterListeners() && !m_Text.isEmpty() && (nTextLen / 2) < nSplitPos )
404 : {
405 : // optimization for SplitNode: If a split is at the end of a node then
406 : // move the frames from the current to the new one and create new ones
407 : // for the current one. As a result, no need for recreating the layout.
408 :
409 53 : LockModify(); // disable notifications
410 :
411 : // werden FlyFrames mit verschoben, so muessen diese nicht ihre
412 : // Frames zerstoeren. Im SwTextFly::SetAnchor wird es abgefragt!
413 53 : if ( HasHints() )
414 : {
415 3 : pNode->GetOrCreateSwpHints().SetInSplitNode(true);
416 : }
417 :
418 : //Ersten Teil des Inhalts in den neuen Node uebertragen und
419 : //im alten Node loeschen.
420 53 : SwIndex aIdx( this );
421 53 : CutText( pNode, aIdx, nSplitPos );
422 :
423 53 : if( GetWrong() )
424 : {
425 4 : pNode->SetWrong( GetWrong()->SplitList( nSplitPos ) );
426 : }
427 53 : SetWrongDirty( true );
428 :
429 53 : if( GetGrammarCheck() )
430 : {
431 0 : pNode->SetGrammarCheck( GetGrammarCheck()->SplitGrammarList( nSplitPos ) );
432 : }
433 53 : SetGrammarCheckDirty( true );
434 :
435 53 : SetWordCountDirty( true );
436 :
437 53 : if( GetSmartTags() )
438 : {
439 0 : pNode->SetSmartTags( GetSmartTags()->SplitList( nSplitPos ) );
440 : }
441 53 : SetSmartTagDirty( true );
442 :
443 53 : if ( pNode->HasHints() )
444 : {
445 3 : if ( pNode->m_pSwpHints->CanBeDeleted() )
446 : {
447 1 : delete pNode->m_pSwpHints;
448 1 : pNode->m_pSwpHints = 0;
449 : }
450 : else
451 : {
452 2 : pNode->m_pSwpHints->SetInSplitNode(false);
453 : }
454 :
455 : // alle zeichengebundenen Rahmen, die im neuen Absatz laden
456 : // muessen aus den alten Frame entfernt werden:
457 : // JP 01.10.96: alle leeren und nicht zu expandierenden
458 : // Attribute loeschen
459 3 : if ( HasHints() )
460 : {
461 3 : for ( size_t j = m_pSwpHints->Count(); j; )
462 : {
463 1 : SwTextAttr* const pHt = m_pSwpHints->GetTextHint( --j );
464 1 : if ( RES_TXTATR_FLYCNT == pHt ->Which() )
465 : {
466 0 : pHt->GetFlyCnt().GetFrameFormat()->DelFrms();
467 : }
468 1 : else if ( pHt->DontExpand() )
469 : {
470 0 : const sal_Int32* const pEnd = pHt->GetEnd();
471 0 : if (pEnd && pHt->GetStart() == *pEnd )
472 : {
473 : // delete it!
474 0 : m_pSwpHints->DeleteAtPos( j );
475 0 : DestroyAttr( pHt );
476 : }
477 : }
478 : }
479 : }
480 :
481 : }
482 :
483 106 : SwIterator<SwContentFrm,SwTextNode> aIter( *this );
484 107 : for( SwContentFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
485 : {
486 54 : pFrm->RegisterToNode( *pNode );
487 54 : if( pFrm->IsTextFrm() && !pFrm->IsFollow() && static_cast<SwTextFrm*>(pFrm)->GetOfst() )
488 0 : static_cast<SwTextFrm*>(pFrm)->SetOfst( 0 );
489 : }
490 :
491 53 : if ( IsInCache() )
492 : {
493 37 : SwFrm::GetCache().Delete( this );
494 37 : SetInCache( false );
495 : }
496 :
497 53 : UnlockModify(); // Benachrichtigungen wieder freischalten
498 :
499 : // If there is an accessible layout we must call modify even
500 : // with length zero, because we have to notify about the changed
501 : // text node.
502 : const SwRootFrm *pRootFrm;
503 106 : if ( (nTextLen != nSplitPos) ||
504 98 : ( (pRootFrm = pNode->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()) != 0 &&
505 49 : pRootFrm->IsAnyShellAccessible() ) )
506 : {
507 : // dann sage den Frames noch, das am Ende etwas "geloescht" wurde
508 4 : if( 1 == nTextLen - nSplitPos )
509 : {
510 1 : SwDelChr aHint( nSplitPos );
511 1 : pNode->NotifyClients( 0, &aHint );
512 : }
513 : else
514 : {
515 3 : SwDelText aHint( nSplitPos, nTextLen - nSplitPos );
516 3 : pNode->NotifyClients( 0, &aHint );
517 : }
518 : }
519 53 : if ( HasHints() )
520 : {
521 1 : MoveTextAttr_To_AttrSet();
522 : }
523 53 : pNode->MakeFrms( *this ); // neue Frames anlegen.
524 106 : lcl_ChangeFootnoteRef( *this );
525 : }
526 : else
527 : {
528 1323 : SwWrongList *pList = GetWrong();
529 1323 : SetWrong( 0, false );
530 1323 : SetWrongDirty( true );
531 :
532 1323 : SwGrammarMarkUp *pList3 = GetGrammarCheck();
533 1323 : SetGrammarCheck( 0, false );
534 1323 : SetGrammarCheckDirty( true );
535 :
536 1323 : SetWordCountDirty( true );
537 :
538 1323 : SwWrongList *pList2 = GetSmartTags();
539 1323 : SetSmartTags( 0, false );
540 1323 : SetSmartTagDirty( true );
541 :
542 1323 : SwIndex aIdx( this );
543 1323 : CutText( pNode, aIdx, nSplitPos );
544 :
545 : // JP 01.10.96: alle leeren und nicht zu expandierenden
546 : // Attribute loeschen
547 1323 : if ( HasHints() )
548 : {
549 9 : for ( size_t j = m_pSwpHints->Count(); j; )
550 : {
551 3 : SwTextAttr* const pHt = m_pSwpHints->GetTextHint( --j );
552 3 : const sal_Int32* const pEnd = pHt->GetEnd();
553 3 : if ( pHt->DontExpand() && pEnd && (pHt->GetStart() == *pEnd) )
554 : {
555 : // delete it!
556 0 : m_pSwpHints->DeleteAtPos( j );
557 0 : DestroyAttr( pHt );
558 : }
559 : }
560 3 : MoveTextAttr_To_AttrSet();
561 : }
562 :
563 1323 : if( pList )
564 : {
565 6 : pNode->SetWrong( pList->SplitList( nSplitPos ) );
566 6 : SetWrong( pList, false );
567 : }
568 :
569 1323 : if( pList3 )
570 : {
571 0 : pNode->SetGrammarCheck( pList3->SplitGrammarList( nSplitPos ) );
572 0 : SetGrammarCheck( pList3, false );
573 : }
574 :
575 1323 : if( pList2 )
576 : {
577 0 : pNode->SetSmartTags( pList2->SplitList( nSplitPos ) );
578 0 : SetSmartTags( pList2, false );
579 : }
580 :
581 1323 : if ( HasWriterListeners() )
582 : {
583 271 : MakeFrms( *pNode ); // neue Frames anlegen.
584 : }
585 1323 : lcl_ChangeFootnoteRef( *pNode );
586 : }
587 :
588 : {
589 : //Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im
590 : //Paste der Frames selbst erledigen, aber das fuehrt dann wiederum
591 : //zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden
592 : //muesten. #56977# #55001# #56135#
593 : const SfxPoolItem *pItem;
594 1700 : if( HasWriterListeners() && SfxItemState::SET == pNode->GetSwAttrSet().
595 324 : GetItemState( RES_PAGEDESC, true, &pItem ) )
596 : {
597 9 : pNode->ModifyNotification( pItem, pItem );
598 : }
599 : }
600 1376 : return pNode;
601 : }
602 :
603 4 : void SwTextNode::MoveTextAttr_To_AttrSet()
604 : {
605 : OSL_ENSURE( m_pSwpHints, "MoveTextAttr_To_AttrSet without SwpHints?" );
606 8 : for ( size_t i = 0; m_pSwpHints && i < m_pSwpHints->Count(); ++i )
607 : {
608 4 : SwTextAttr *pHt = m_pSwpHints->GetTextHint(i);
609 :
610 4 : if( pHt->GetStart() )
611 0 : break;
612 :
613 4 : const sal_Int32* pHtEndIdx = pHt->GetEnd();
614 :
615 4 : if( !pHtEndIdx )
616 0 : continue;
617 :
618 4 : if (*pHtEndIdx < m_Text.getLength() || pHt->IsCharFormatAttr())
619 0 : break;
620 :
621 8 : if( !pHt->IsDontMoveAttr() &&
622 4 : SetAttr( pHt->GetAttr() ) )
623 : {
624 0 : m_pSwpHints->DeleteAtPos(i);
625 0 : DestroyAttr( pHt );
626 0 : --i;
627 : }
628 : }
629 :
630 4 : }
631 :
632 3066 : SwContentNode *SwTextNode::JoinNext()
633 : {
634 3066 : SwNodes& rNds = GetNodes();
635 3066 : SwNodeIndex aIdx( *this );
636 3066 : if( SwContentNode::CanJoinNext( &aIdx ) )
637 : {
638 3066 : SwDoc* pDoc = rNds.GetDoc();
639 3066 : const std::shared_ptr<sw::mark::ContentIdxStore> pContentStore(sw::mark::ContentIdxStore::Create());
640 3066 : pContentStore->Save(pDoc, aIdx.GetIndex(), SAL_MAX_INT32);
641 3066 : SwTextNode *pTextNode = aIdx.GetNode().GetTextNode();
642 3066 : sal_Int32 nOldLen = m_Text.getLength();
643 :
644 : // METADATA: merge
645 3066 : this->JoinMetadatable(*pTextNode, !this->Len(), !pTextNode->Len());
646 :
647 3066 : SwWrongList *pList = GetWrong();
648 3066 : if( pList )
649 : {
650 9 : pList->JoinList( pTextNode->GetWrong(), nOldLen );
651 9 : SetWrongDirty( true );
652 9 : SetWrong( 0, false );
653 : }
654 : else
655 : {
656 3057 : pList = pTextNode->GetWrong();
657 3057 : if( pList )
658 : {
659 1 : pList->Move( 0, nOldLen );
660 1 : SetWrongDirty( true );
661 1 : pTextNode->SetWrong( 0, false );
662 : }
663 : }
664 :
665 3066 : SwGrammarMarkUp *pList3 = GetGrammarCheck();
666 3066 : if( pList3 )
667 : {
668 0 : pList3->JoinGrammarList( pTextNode->GetGrammarCheck(), nOldLen );
669 0 : SetGrammarCheckDirty( true );
670 0 : SetGrammarCheck( 0, false );
671 : }
672 : else
673 : {
674 3066 : pList3 = pTextNode->GetGrammarCheck();
675 3066 : if( pList3 )
676 : {
677 0 : pList3->MoveGrammar( 0, nOldLen );
678 0 : SetGrammarCheckDirty( true );
679 0 : pTextNode->SetGrammarCheck( 0, false );
680 : }
681 : }
682 :
683 3066 : SwWrongList *pList2 = GetSmartTags();
684 3066 : if( pList2 )
685 : {
686 0 : pList2->JoinList( pTextNode->GetSmartTags(), nOldLen );
687 0 : SetSmartTagDirty( true );
688 0 : SetSmartTags( 0, false );
689 : }
690 : else
691 : {
692 3066 : pList2 = pTextNode->GetSmartTags();
693 3066 : if( pList2 )
694 : {
695 0 : pList2->Move( 0, nOldLen );
696 0 : SetSmartTagDirty( true );
697 0 : pTextNode->SetSmartTags( 0, false );
698 : }
699 : }
700 :
701 : { // wg. SwIndex
702 3066 : pTextNode->CutText( this, SwIndex(pTextNode), pTextNode->Len() );
703 : }
704 : // verschiebe noch alle Bookmarks/TOXMarks
705 3066 : if( !pContentStore->Empty())
706 2 : pContentStore->Restore( pDoc, GetIndex(), nOldLen );
707 :
708 3066 : if( pTextNode->HasAnyIndex() )
709 : {
710 : // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben
711 0 : pDoc->CorrAbs( aIdx, SwPosition( *this ), nOldLen, true );
712 : }
713 3066 : rNds.Delete(aIdx);
714 3066 : SetWrong( pList, false );
715 3066 : SetGrammarCheck( pList3, false );
716 3066 : SetSmartTags( pList2, false );
717 3066 : InvalidateNumRule();
718 : }
719 : else {
720 : OSL_FAIL( "kein TextNode." );
721 : }
722 :
723 3066 : return this;
724 : }
725 :
726 109 : SwContentNode *SwTextNode::JoinPrev()
727 : {
728 109 : SwNodes& rNds = GetNodes();
729 109 : SwNodeIndex aIdx( *this );
730 109 : if( SwContentNode::CanJoinPrev( &aIdx ) )
731 : {
732 109 : SwDoc* pDoc = rNds.GetDoc();
733 109 : const std::shared_ptr<sw::mark::ContentIdxStore> pContentStore(sw::mark::ContentIdxStore::Create());
734 109 : pContentStore->Save( pDoc, aIdx.GetIndex(), SAL_MAX_INT32);
735 109 : SwTextNode *pTextNode = aIdx.GetNode().GetTextNode();
736 109 : const sal_Int32 nLen = pTextNode->Len();
737 :
738 109 : SwWrongList *pList = pTextNode->GetWrong();
739 109 : if( pList )
740 : {
741 1 : pList->JoinList( GetWrong(), Len() );
742 1 : SetWrongDirty( true );
743 1 : pTextNode->SetWrong( 0, false );
744 1 : SetWrong( NULL );
745 : }
746 : else
747 : {
748 108 : pList = GetWrong();
749 108 : if( pList )
750 : {
751 0 : pList->Move( 0, nLen );
752 0 : SetWrongDirty( true );
753 0 : SetWrong( 0, false );
754 : }
755 : }
756 :
757 109 : SwGrammarMarkUp *pList3 = pTextNode->GetGrammarCheck();
758 109 : if( pList3 )
759 : {
760 0 : pList3->JoinGrammarList( GetGrammarCheck(), Len() );
761 0 : SetGrammarCheckDirty( true );
762 0 : pTextNode->SetGrammarCheck( 0, false );
763 0 : SetGrammarCheck( NULL );
764 : }
765 : else
766 : {
767 109 : pList3 = GetGrammarCheck();
768 109 : if( pList3 )
769 : {
770 0 : pList3->MoveGrammar( 0, nLen );
771 0 : SetGrammarCheckDirty( true );
772 0 : SetGrammarCheck( 0, false );
773 : }
774 : }
775 :
776 109 : SwWrongList *pList2 = pTextNode->GetSmartTags();
777 109 : if( pList2 )
778 : {
779 0 : pList2->JoinList( GetSmartTags(), Len() );
780 0 : SetSmartTagDirty( true );
781 0 : pTextNode->SetSmartTags( 0, false );
782 0 : SetSmartTags( NULL );
783 : }
784 : else
785 : {
786 109 : pList2 = GetSmartTags();
787 109 : if( pList2 )
788 : {
789 0 : pList2->Move( 0, nLen );
790 0 : SetSmartTagDirty( true );
791 0 : SetSmartTags( 0, false );
792 : }
793 : }
794 :
795 : { // wg. SwIndex
796 109 : pTextNode->CutText( this, SwIndex(this), SwIndex(pTextNode), nLen );
797 : }
798 : // verschiebe noch alle Bookmarks/TOXMarks
799 109 : if( !pContentStore->Empty() )
800 0 : pContentStore->Restore( pDoc, GetIndex() );
801 :
802 109 : if( pTextNode->HasAnyIndex() )
803 : {
804 : // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben
805 0 : pDoc->CorrAbs( aIdx, SwPosition( *this ), nLen, true );
806 : }
807 109 : rNds.Delete(aIdx);
808 109 : SetWrong( pList, false );
809 109 : SetGrammarCheck( pList3, false );
810 109 : SetSmartTags( pList2, false );
811 109 : InvalidateNumRule();
812 : }
813 : else {
814 : OSL_FAIL( "kein TextNode." );
815 : }
816 :
817 109 : return this;
818 : }
819 :
820 : // erzeugt einen AttrSet mit Bereichen fuer Frame-/Para/Char-Attributen
821 32005 : void SwTextNode::NewAttrSet( SwAttrPool& rPool )
822 : {
823 : OSL_ENSURE( !mpAttrSet.get(), "AttrSet ist doch gesetzt" );
824 32005 : SwAttrSet aNewAttrSet( rPool, aTextNodeSetRange );
825 :
826 : // put names of parent style and conditional style:
827 32005 : const SwFormatColl* pAnyFormatColl = &GetAnyFormatColl();
828 32005 : const SwFormatColl* pFormatColl = GetFormatColl();
829 64010 : OUString sVal;
830 32005 : SwStyleNameMapper::FillProgName( pAnyFormatColl->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
831 64010 : SfxStringItem aAnyFormatColl( RES_FRMATR_STYLE_NAME, sVal );
832 32005 : if ( pFormatColl != pAnyFormatColl )
833 0 : SwStyleNameMapper::FillProgName( pFormatColl->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
834 64010 : SfxStringItem aFormatColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal );
835 32005 : aNewAttrSet.Put( aAnyFormatColl );
836 32005 : aNewAttrSet.Put( aFormatColl );
837 :
838 32005 : aNewAttrSet.SetParent( &pAnyFormatColl->GetAttrSet() );
839 64010 : mpAttrSet = GetDoc()->GetIStyleAccess().getAutomaticStyle( aNewAttrSet, IStyleAccess::AUTO_STYLE_PARA );
840 32005 : }
841 :
842 : // override SwIndexReg::Update => text hints do not need SwIndex for start/end!
843 161106 : void SwTextNode::Update(
844 : SwIndex const & rPos,
845 : const sal_Int32 nChangeLen,
846 : const bool bNegative,
847 : const bool bDelete )
848 : {
849 161106 : SetAutoCompleteWordDirty( true );
850 :
851 161106 : std::unique_ptr<SwpHts> pCollector;
852 161106 : const sal_Int32 nChangePos = rPos.GetIndex();
853 :
854 161106 : if ( HasHints() )
855 : {
856 27590 : if ( bNegative )
857 : {
858 1631 : std::vector<SwTextInputField*> aTextInputFields;
859 :
860 1631 : const sal_Int32 nChangeEnd = nChangePos + nChangeLen;
861 6171 : for ( size_t n = 0; n < m_pSwpHints->Count(); ++n )
862 : {
863 4540 : bool bTextAttrChanged = false;
864 4540 : bool bStartOfTextAttrChanged = false;
865 4540 : SwTextAttr * const pHint = m_pSwpHints->GetTextHint(n);
866 4540 : sal_Int32 & rStart = pHint->GetStart();
867 4540 : if ( rStart > nChangePos )
868 : {
869 1245 : if ( rStart > nChangeEnd )
870 : {
871 702 : rStart = rStart - nChangeLen;
872 : }
873 : else
874 : {
875 543 : rStart = nChangePos;
876 : }
877 1245 : bStartOfTextAttrChanged = true;
878 : }
879 :
880 4540 : sal_Int32 * const pEnd = pHint->GetEnd();
881 4540 : if (pEnd)
882 : {
883 3338 : if ( *pEnd > nChangePos )
884 : {
885 1082 : if( *pEnd > nChangeEnd )
886 : {
887 699 : *pEnd = *pEnd - nChangeLen;
888 : }
889 : else
890 : {
891 383 : *pEnd = nChangePos;
892 : }
893 1082 : bTextAttrChanged = !bStartOfTextAttrChanged;
894 : }
895 : }
896 :
897 4540 : if ( bTextAttrChanged
898 4540 : && pHint->Which() == RES_TXTATR_INPUTFIELD )
899 : {
900 8 : SwTextInputField* pTextInputField = dynamic_cast<SwTextInputField*>(pHint);
901 8 : if ( pTextInputField )
902 8 : aTextInputFields.push_back(pTextInputField);
903 : }
904 : }
905 :
906 : //wait until all the attribute positions are correct
907 : //before updating the field contents
908 1639 : for (SwTextInputField* pTextInputField : aTextInputFields)
909 : {
910 8 : pTextInputField->UpdateFieldContent();
911 : }
912 :
913 1631 : m_pSwpHints->MergePortions( *this );
914 : }
915 : else
916 : {
917 25959 : bool bNoExp = false;
918 25959 : bool bResort = false;
919 25959 : bool bMergePortionsNeeded = false;
920 25959 : const int coArrSz = RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN;
921 25959 : std::vector<SwTextInputField*> aTextInputFields;
922 :
923 : bool aDontExp[ coArrSz ];
924 25959 : memset( &aDontExp, 0, coArrSz * sizeof(bool) );
925 :
926 213482 : for ( size_t n = 0; n < m_pSwpHints->Count(); ++n )
927 : {
928 187523 : bool bTextAttrChanged = false;
929 187523 : SwTextAttr * const pHint = m_pSwpHints->GetTextHint(n);
930 187523 : sal_Int32 & rStart = pHint->GetStart();
931 187523 : sal_Int32 * const pEnd = pHint->GetEnd();
932 187523 : if ( rStart >= nChangePos )
933 : {
934 436 : rStart = rStart + nChangeLen;
935 436 : if ( pEnd )
936 : {
937 253 : *pEnd = *pEnd + nChangeLen;
938 : }
939 : }
940 187087 : else if ( pEnd && (*pEnd >= nChangePos) )
941 : {
942 21358 : if ( (*pEnd > nChangePos) || IsIgnoreDontExpand() )
943 : {
944 134 : *pEnd = *pEnd + nChangeLen;
945 134 : bTextAttrChanged = true;
946 : }
947 : else // *pEnd == nChangePos
948 : {
949 21224 : const sal_uInt16 nWhich = pHint->Which();
950 :
951 : OSL_ENSURE(!isCHRATR(nWhich), "Update: char attr hint?");
952 21224 : if (!(isCHRATR(nWhich) || isTXTATR_WITHEND(nWhich)))
953 0 : continue;
954 :
955 21224 : const sal_uInt16 nWhPos = nWhich - RES_CHRATR_BEGIN;
956 :
957 21224 : if( aDontExp[ nWhPos ] )
958 189 : continue;
959 :
960 21035 : if ( pHint->DontExpand() )
961 : {
962 20811 : pHint->SetDontExpand( false );
963 20811 : bResort = true;
964 : // could have a continuation with IgnoreStart()...
965 20811 : if (pHint->IsFormatIgnoreEnd())
966 : {
967 0 : bMergePortionsNeeded = true;
968 : }
969 20811 : if ( pHint->IsCharFormatAttr() )
970 : {
971 3693 : bNoExp = true;
972 3693 : aDontExp[ RES_TXTATR_CHARFMT - RES_CHRATR_BEGIN ] = true;
973 3693 : aDontExp[ RES_TXTATR_INETFMT - RES_CHRATR_BEGIN ] = true;
974 : }
975 : else
976 17118 : aDontExp[ nWhPos ] = true;
977 : }
978 224 : else if( bNoExp )
979 : {
980 2 : if ( !pCollector.get() )
981 : {
982 2 : pCollector.reset( new SwpHts );
983 : }
984 2 : for(SwpHts::iterator it = pCollector->begin(); it != pCollector->end(); ++it)
985 : {
986 0 : SwTextAttr *pTmp = *it;
987 0 : if( nWhich == pTmp->Which() )
988 : {
989 0 : pCollector->erase( it );
990 : SwTextAttr::Destroy( pTmp,
991 0 : GetDoc()->GetAttrPool() );
992 0 : break;
993 : }
994 : }
995 : SwTextAttr * const pTmp =
996 2 : MakeTextAttr( *GetDoc(),
997 4 : pHint->GetAttr(), nChangePos, nChangePos + nChangeLen);
998 2 : pCollector->push_back( pTmp );
999 : }
1000 : else
1001 : {
1002 222 : *pEnd = *pEnd + nChangeLen;
1003 222 : bTextAttrChanged = true;
1004 : }
1005 : }
1006 : }
1007 :
1008 187334 : if ( bTextAttrChanged
1009 187334 : && pHint->Which() == RES_TXTATR_INPUTFIELD )
1010 : {
1011 8 : SwTextInputField* pTextInputField = dynamic_cast<SwTextInputField*>(pHint);
1012 8 : if ( pTextInputField )
1013 8 : aTextInputFields.push_back(pTextInputField);
1014 : }
1015 : }
1016 :
1017 : //wait until all the attribute positions are correct
1018 : //before updating the field contents
1019 25967 : for (SwTextInputField* pTextInputField : aTextInputFields)
1020 : {
1021 8 : pTextInputField->UpdateFieldContent();
1022 : }
1023 :
1024 25959 : if (bMergePortionsNeeded)
1025 : {
1026 0 : m_pSwpHints->MergePortions(*this); // does Resort too
1027 : }
1028 25959 : else if (bResort)
1029 : {
1030 20063 : m_pSwpHints->Resort();
1031 25959 : }
1032 : }
1033 : }
1034 :
1035 161106 : bool bSortMarks = false;
1036 322212 : SwIndexReg aTmpIdxReg;
1037 161106 : if ( !bNegative && !bDelete )
1038 : {
1039 154134 : const SwRedlineTable& rTable = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
1040 283032 : for ( size_t i = 0; i < rTable.size(); ++i )
1041 : {
1042 128898 : SwRangeRedline *const pRedl = rTable[ i ];
1043 128898 : if ( pRedl->HasMark() )
1044 : {
1045 128313 : SwPosition* const pEnd = pRedl->End();
1046 157503 : if ( this == &pEnd->nNode.GetNode() &&
1047 29190 : *pRedl->GetPoint() != *pRedl->GetMark() )
1048 : {
1049 29190 : SwIndex & rIdx = pEnd->nContent;
1050 29190 : if (nChangePos == rIdx.GetIndex())
1051 : {
1052 1489 : rIdx.Assign( &aTmpIdxReg, rIdx.GetIndex() );
1053 : }
1054 : }
1055 : }
1056 585 : else if ( this == &pRedl->GetPoint()->nNode.GetNode() )
1057 : {
1058 8 : SwIndex & rIdx = pRedl->GetPoint()->nContent;
1059 8 : if (nChangePos == rIdx.GetIndex())
1060 : {
1061 8 : rIdx.Assign( &aTmpIdxReg, rIdx.GetIndex() );
1062 : }
1063 : // the unused position must not be on a SwTextNode
1064 8 : bool const isOneUsed(&pRedl->GetBound(true) == pRedl->GetPoint());
1065 : assert(!pRedl->GetBound(!isOneUsed).nNode.GetNode().IsTextNode());
1066 : assert(!pRedl->GetBound(!isOneUsed).nContent.GetIdxReg()); (void)isOneUsed;
1067 : }
1068 : }
1069 :
1070 : // Bookmarks must never grow to either side, when editing (directly) to the left or right (#i29942#)!
1071 : // And a bookmark with same start and end must remain to the left of the inserted text (used in XML import).
1072 : {
1073 154134 : bool bAtLeastOneBookmarkMoved = false;
1074 154134 : bool bAtLeastOneExpandedBookmarkAtInsertionPosition = false;
1075 : // A text node already knows its marks via its SwIndexes.
1076 154134 : std::set<const sw::mark::IMark*> aSeenMarks;
1077 : const SwIndex* next;
1078 1818690 : for (const SwIndex* pIndex = GetFirstIndex(); pIndex; pIndex = next )
1079 : {
1080 1664556 : next = pIndex->GetNext();
1081 1664556 : const sw::mark::IMark* pMark = pIndex->GetMark();
1082 1664556 : if (!pMark)
1083 2097631 : continue;
1084 : // Only handle bookmarks once, if they start and end at this node as well.
1085 790176 : if (aSeenMarks.find(pMark) != aSeenMarks.end())
1086 348871 : continue;
1087 441305 : aSeenMarks.insert(pMark);
1088 441305 : const SwPosition* pEnd = &pMark->GetMarkEnd();
1089 441305 : SwIndex & rEndIdx = const_cast<SwIndex&>(pEnd->nContent);
1090 882610 : if( this == &pEnd->nNode.GetNode() &&
1091 441305 : rPos.GetIndex() == rEndIdx.GetIndex() )
1092 : {
1093 15994 : rEndIdx.Assign( &aTmpIdxReg, rEndIdx.GetIndex() );
1094 15994 : bAtLeastOneBookmarkMoved = true;
1095 : }
1096 425311 : else if ( !bAtLeastOneExpandedBookmarkAtInsertionPosition )
1097 : {
1098 373228 : if ( pMark->IsExpanded() )
1099 : {
1100 297694 : const SwPosition* pStart = &pMark->GetMarkStart();
1101 595388 : if ( this == &pStart->nNode.GetNode()
1102 297694 : && rPos.GetIndex() == pStart->nContent.GetIndex() )
1103 : {
1104 1034 : bAtLeastOneExpandedBookmarkAtInsertionPosition = true;
1105 : }
1106 : }
1107 : }
1108 : }
1109 :
1110 154134 : bSortMarks = bAtLeastOneBookmarkMoved && bAtLeastOneExpandedBookmarkAtInsertionPosition;
1111 : }
1112 :
1113 : // at-char anchored flys shouldn't be moved, either.
1114 : #if OSL_DEBUG_LEVEL > 0
1115 : std::list<SwFrameFormat*> checkFormats;
1116 : const SwFrameFormats& rFormats = *GetDoc()->GetSpzFrameFormats();
1117 : for (SwFrameFormats::const_iterator pFormat = rFormats.begin(); pFormat != rFormats.end(); ++pFormat)
1118 : {
1119 : const SwFormatAnchor& rAnchor = (*pFormat)->GetAnchor();
1120 : const SwPosition* pContentAnchor = rAnchor.GetContentAnchor();
1121 : if (rAnchor.GetAnchorId() == FLY_AT_CHAR && pContentAnchor)
1122 : {
1123 : // The fly is at-char anchored and has an anchor position.
1124 : SwIndex& rEndIdx = const_cast<SwIndex&>(pContentAnchor->nContent);
1125 : if (&pContentAnchor->nNode.GetNode() == this && rEndIdx.GetIndex() == rPos.GetIndex())
1126 : {
1127 : // The anchor position is exactly our insert position.
1128 : #if 0
1129 : rEndIdx.Assign(&aTmpIdxReg, rEndIdx.GetIndex());
1130 : #endif
1131 : checkFormats.push_back( *pFormat );
1132 : }
1133 : }
1134 : }
1135 : #endif
1136 154134 : std::vector<SwFrameFormat*> const*const pFlys(GetAnchoredFlys());
1137 186682 : for (size_t i = 0; pFlys && i != pFlys->size(); ++i)
1138 : {
1139 32548 : SwFrameFormat const*const pFormat = (*pFlys)[i];
1140 32548 : const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
1141 32548 : const SwPosition* pContentAnchor = rAnchor.GetContentAnchor();
1142 32548 : if (rAnchor.GetAnchorId() == FLY_AT_CHAR && pContentAnchor)
1143 : {
1144 : // The fly is at-char anchored and has an anchor position.
1145 379 : SwIndex& rEndIdx = const_cast<SwIndex&>(pContentAnchor->nContent);
1146 379 : if (&pContentAnchor->nNode.GetNode() == this && rEndIdx.GetIndex() == rPos.GetIndex())
1147 : {
1148 : // The anchor position is exactly our insert position.
1149 161 : rEndIdx.Assign(&aTmpIdxReg, rEndIdx.GetIndex());
1150 : #if OSL_DEBUG_LEVEL > 0
1151 : std::list<SwFrameFormat*>::iterator checkPos = std::find( checkFormats.begin(), checkFormats.end(), pFormat );
1152 : assert( checkPos != checkFormats.end());
1153 : checkFormats.erase( checkPos );
1154 : #endif
1155 : }
1156 : }
1157 : }
1158 : #if OSL_DEBUG_LEVEL > 0
1159 : assert( checkFormats.empty());
1160 : #endif
1161 : }
1162 :
1163 : // base class
1164 161106 : SwIndexReg::Update( rPos, nChangeLen, bNegative, bDelete );
1165 :
1166 161106 : if ( pCollector.get() )
1167 : {
1168 2 : const size_t nCount = pCollector->size();
1169 4 : for ( size_t i = 0; i < nCount; ++i )
1170 : {
1171 2 : m_pSwpHints->TryInsertHint( (*pCollector)[ i ], *this );
1172 : }
1173 : }
1174 :
1175 161106 : aTmpIdxReg.MoveTo( *this );
1176 161106 : if ( bSortMarks )
1177 : {
1178 4 : getIDocumentMarkAccess()->assureSortedMarkContainers();
1179 : }
1180 :
1181 : //Any drawing objects anchored into this text node may be sorted by their
1182 : //anchor position which may have changed here, so resort them
1183 161106 : SwContentFrm* pContentFrm = getLayoutFrm(GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout());
1184 161106 : SwSortedObjs* pSortedObjs = pContentFrm ? pContentFrm->GetDrawObjs() : NULL;
1185 161106 : if (pSortedObjs)
1186 161358 : pSortedObjs->UpdateAll();
1187 161106 : }
1188 :
1189 79810 : void SwTextNode::_ChgTextCollUpdateNum( const SwTextFormatColl *pOldColl,
1190 : const SwTextFormatColl *pNewColl)
1191 : {
1192 79810 : SwDoc* pDoc = GetDoc();
1193 : OSL_ENSURE( pDoc, "Kein Doc?" );
1194 : // erfrage die OutlineLevel und update gegebenenfalls das Nodes-Array,
1195 : // falls sich die Level geaendert haben !
1196 42296 : const int nOldLevel = pOldColl && pOldColl->IsAssignedToListLevelOfOutlineStyle() ?
1197 80289 : pOldColl->GetAssignedOutlineStyleLevel() : MAXLEVEL;
1198 79810 : const int nNewLevel = pNewColl && pNewColl->IsAssignedToListLevelOfOutlineStyle() ?
1199 80628 : pNewColl->GetAssignedOutlineStyleLevel() : MAXLEVEL;
1200 :
1201 79810 : if ( MAXLEVEL != nNewLevel && -1 != nNewLevel )
1202 : {
1203 818 : SetAttrListLevel(nNewLevel);
1204 : }
1205 79810 : if (pDoc)
1206 : {
1207 79810 : pDoc->GetNodes().UpdateOutlineNode(*this);
1208 : }
1209 :
1210 79810 : SwNodes& rNds = GetNodes();
1211 : // Update beim Level 0 noch die Fussnoten !!
1212 159369 : if( ( !nNewLevel || !nOldLevel) && pDoc && !pDoc->GetFootnoteIdxs().empty() &&
1213 79822 : FTNNUM_CHAPTER == pDoc->GetFootnoteInfo().eNum &&
1214 0 : rNds.IsDocNodes() )
1215 : {
1216 0 : SwNodeIndex aTmpIndex( rNds, GetIndex());
1217 :
1218 0 : pDoc->GetFootnoteIdxs().UpdateFootnote( aTmpIndex);
1219 : }
1220 :
1221 79810 : if( pNewColl && RES_CONDTXTFMTCOLL == pNewColl->Which() )
1222 : {
1223 : // Erfrage die akt. Condition des TextNodes:
1224 422 : ChkCondColl();
1225 : }
1226 79810 : }
1227 :
1228 : // Wenn man sich genau am Ende einer Text- bzw. INetvorlage befindet,
1229 : // bekommt diese das DontExpand-Flag verpasst
1230 :
1231 73455 : bool SwTextNode::DontExpandFormat( const SwIndex& rIdx, bool bFlag,
1232 : bool bFormatToTextAttributes )
1233 : {
1234 73455 : const sal_Int32 nIdx = rIdx.GetIndex();
1235 73455 : if (bFormatToTextAttributes && nIdx == m_Text.getLength())
1236 : {
1237 73277 : FormatToTextAttr( this );
1238 : }
1239 :
1240 73455 : bool bRet = false;
1241 73455 : if ( HasHints() )
1242 : {
1243 23065 : const size_t nEndCnt = m_pSwpHints->GetEndCount();
1244 23065 : size_t nPos = nEndCnt;
1245 76998 : while( nPos )
1246 : {
1247 30868 : SwTextAttr *pTmp = m_pSwpHints->GetEnd( --nPos );
1248 30868 : sal_Int32 *pEnd = pTmp->GetEnd();
1249 30868 : if( !pEnd || *pEnd > nIdx )
1250 1341 : continue;
1251 29527 : if( nIdx != *pEnd )
1252 8679 : nPos = 0;
1253 62116 : else if( bFlag != pTmp->DontExpand() && !pTmp->IsLockExpandFlag()
1254 41268 : && *pEnd > pTmp->GetStart())
1255 : {
1256 20420 : bRet = true;
1257 20420 : m_pSwpHints->NoteInHistory( pTmp );
1258 20420 : pTmp->SetDontExpand( bFlag );
1259 : }
1260 : }
1261 : }
1262 73455 : return bRet;
1263 : }
1264 :
1265 434 : static bool lcl_GetTextAttrDefault(sal_Int32 nIndex, sal_Int32 nHintStart, sal_Int32 nHintEnd)
1266 : {
1267 434 : return ((nHintStart <= nIndex) && (nIndex < nHintEnd));
1268 : }
1269 59 : static bool lcl_GetTextAttrExpand(sal_Int32 nIndex, sal_Int32 nHintStart, sal_Int32 nHintEnd)
1270 : {
1271 59 : return ((nHintStart < nIndex) && (nIndex <= nHintEnd));
1272 : }
1273 73 : static bool lcl_GetTextAttrParent(sal_Int32 nIndex, sal_Int32 nHintStart, sal_Int32 nHintEnd)
1274 : {
1275 73 : return ((nHintStart < nIndex) && (nIndex < nHintEnd));
1276 : }
1277 :
1278 : static void
1279 438133 : lcl_GetTextAttrs(
1280 : ::std::vector<SwTextAttr *> *const pVector,
1281 : SwTextAttr **const ppTextAttr,
1282 : SwpHints *const pSwpHints,
1283 : sal_Int32 const nIndex, RES_TXTATR const nWhich,
1284 : enum SwTextNode::GetTextAttrMode const eMode)
1285 : {
1286 438133 : size_t const nSize = (pSwpHints) ? pSwpHints->Count() : 0;
1287 438133 : sal_Int32 nPreviousIndex(0); // index of last hint with nWhich
1288 438133 : bool (*pMatchFunc)(sal_Int32, sal_Int32, sal_Int32)=0;
1289 438133 : switch (eMode)
1290 : {
1291 55057 : case SwTextNode::DEFAULT: pMatchFunc = &lcl_GetTextAttrDefault; break;
1292 32 : case SwTextNode::EXPAND: pMatchFunc = &lcl_GetTextAttrExpand; break;
1293 383044 : case SwTextNode::PARENT: pMatchFunc = &lcl_GetTextAttrParent; break;
1294 : default: assert(false);
1295 : }
1296 :
1297 1209030 : for( size_t i = 0; i < nSize; ++i )
1298 : {
1299 798454 : SwTextAttr *const pHint = pSwpHints->GetTextHint(i);
1300 798454 : sal_Int32 const nHintStart = pHint->GetStart();
1301 798454 : if (nIndex < nHintStart)
1302 : {
1303 465690 : return; // hints are sorted by start, so we are done...
1304 : }
1305 :
1306 770897 : if (pHint->Which() != nWhich)
1307 : {
1308 770321 : continue;
1309 : }
1310 :
1311 576 : sal_Int32 const*const pEndIdx = pHint->GetEnd();
1312 : // cannot have hint with no end and no dummy char
1313 : assert(pEndIdx || pHint->HasDummyChar());
1314 : // Wenn bExpand gesetzt ist, wird das Verhalten bei Eingabe
1315 : // simuliert, d.h. der Start wuede verschoben, das Ende expandiert,
1316 : bool const bContained( (pEndIdx)
1317 566 : ? (*pMatchFunc)(nIndex, nHintStart, *pEndIdx)
1318 1142 : : (nHintStart == nIndex) );
1319 576 : if (bContained)
1320 : {
1321 257 : if (pVector)
1322 : {
1323 70 : if (nPreviousIndex < nHintStart)
1324 : {
1325 8 : pVector->clear(); // clear hints that are outside pHint
1326 8 : nPreviousIndex = nHintStart;
1327 : }
1328 70 : pVector->push_back(pHint);
1329 : }
1330 : else
1331 : {
1332 187 : *ppTextAttr = pHint; // and possibly overwrite outer hint
1333 : }
1334 257 : if (!pEndIdx)
1335 : {
1336 0 : break;
1337 : }
1338 : }
1339 : }
1340 : }
1341 :
1342 : ::std::vector<SwTextAttr *>
1343 56 : SwTextNode::GetTextAttrsAt(sal_Int32 const nIndex, RES_TXTATR const nWhich,
1344 : enum GetTextAttrMode const eMode) const
1345 : {
1346 56 : ::std::vector<SwTextAttr *> ret;
1347 56 : lcl_GetTextAttrs(& ret, 0, m_pSwpHints, nIndex, nWhich, eMode);
1348 56 : return ret;
1349 : }
1350 :
1351 : SwTextAttr *
1352 438077 : SwTextNode::GetTextAttrAt(sal_Int32 const nIndex, RES_TXTATR const nWhich,
1353 : enum GetTextAttrMode const eMode) const
1354 : {
1355 : assert( (nWhich == RES_TXTATR_META)
1356 : || (nWhich == RES_TXTATR_METAFIELD)
1357 : || (nWhich == RES_TXTATR_AUTOFMT)
1358 : || (nWhich == RES_TXTATR_INETFMT)
1359 : || (nWhich == RES_TXTATR_CJK_RUBY)
1360 : || (nWhich == RES_TXTATR_UNKNOWN_CONTAINER)
1361 : || (nWhich == RES_TXTATR_INPUTFIELD ) );
1362 : // "GetTextAttrAt() will give wrong result for this hint!")
1363 :
1364 438077 : SwTextAttr * pRet(0);
1365 438077 : lcl_GetTextAttrs(0, & pRet, m_pSwpHints, nIndex, nWhich, eMode);
1366 438077 : return pRet;
1367 : }
1368 :
1369 82499 : const SwTextInputField* SwTextNode::GetOverlappingInputField( const SwTextAttr& rTextAttr ) const
1370 : {
1371 82499 : const SwTextInputField* pTextInputField = NULL;
1372 :
1373 82499 : pTextInputField = dynamic_cast<const SwTextInputField*>(GetTextAttrAt( rTextAttr.GetStart(), RES_TXTATR_INPUTFIELD, PARENT ));
1374 :
1375 82499 : if ( pTextInputField == NULL && rTextAttr.End() != NULL )
1376 : {
1377 76497 : pTextInputField = dynamic_cast<const SwTextInputField*>(GetTextAttrAt( *(rTextAttr.End()), RES_TXTATR_INPUTFIELD, PARENT ));
1378 : }
1379 :
1380 82499 : return pTextInputField;
1381 : }
1382 :
1383 12207 : void SwTextNode::DelFrms_TextNodePart()
1384 : {
1385 12207 : SetWrong( NULL );
1386 12207 : SetWrongDirty( true );
1387 :
1388 12207 : SetGrammarCheck( NULL );
1389 12207 : SetGrammarCheckDirty( true );
1390 :
1391 12207 : SetSmartTags( NULL );
1392 12207 : SetSmartTagDirty( true );
1393 :
1394 12207 : SetWordCountDirty( true );
1395 12207 : SetAutoCompleteWordDirty( true );
1396 12207 : }
1397 :
1398 115788 : SwTextField* SwTextNode::GetFieldTextAttrAt(
1399 : const sal_Int32 nIndex,
1400 : const bool bIncludeInputFieldAtStart ) const
1401 : {
1402 115788 : SwTextField* pTextField = NULL;
1403 :
1404 115788 : pTextField = dynamic_cast<SwTextField*>(GetTextAttrForCharAt( nIndex, RES_TXTATR_FIELD ));
1405 115788 : if ( pTextField == NULL )
1406 : {
1407 114649 : pTextField = dynamic_cast<SwTextField*>(GetTextAttrForCharAt( nIndex, RES_TXTATR_ANNOTATION ));
1408 : }
1409 115788 : if ( pTextField == NULL )
1410 : {
1411 : pTextField =
1412 : dynamic_cast<SwTextField*>( GetTextAttrAt(
1413 : nIndex,
1414 : RES_TXTATR_INPUTFIELD,
1415 114338 : bIncludeInputFieldAtStart ? DEFAULT : PARENT ));
1416 : }
1417 :
1418 115788 : return pTextField;
1419 : }
1420 :
1421 0 : static SwCharFormat* lcl_FindCharFormat( const SwCharFormats* pCharFormats, const OUString& rName )
1422 : {
1423 0 : if( !rName.isEmpty() )
1424 : {
1425 0 : const size_t nArrLen = pCharFormats->size();
1426 0 : for( size_t i = 1; i < nArrLen; i++ )
1427 : {
1428 0 : SwCharFormat* pFormat = (*pCharFormats)[ i ];
1429 0 : if( pFormat->GetName()==rName )
1430 0 : return pFormat;
1431 : }
1432 : }
1433 0 : return NULL;
1434 : }
1435 :
1436 3063 : void lcl_CopyHint(
1437 : const sal_uInt16 nWhich,
1438 : const SwTextAttr * const pHt,
1439 : SwTextAttr *const pNewHt,
1440 : SwDoc *const pOtherDoc,
1441 : SwTextNode *const pDest )
1442 : {
1443 : assert(nWhich == pHt->Which()); // wrong hint-id
1444 3063 : switch( nWhich )
1445 : {
1446 : // copy nodesarray section with footnote content
1447 : case RES_TXTATR_FTN :
1448 : assert(pDest); // "lcl_CopyHint: no destination text node?"
1449 0 : static_cast<const SwTextFootnote*>(pHt)->CopyFootnote( *static_cast<SwTextFootnote*>(pNewHt), *pDest);
1450 0 : break;
1451 :
1452 : // Beim Kopieren von Feldern in andere Dokumente
1453 : // muessen die Felder bei ihren neuen Feldtypen angemeldet werden.
1454 :
1455 : // TabellenFormel muessen relativ kopiert werden.
1456 : case RES_TXTATR_FIELD :
1457 : {
1458 757 : if( pOtherDoc != NULL )
1459 : {
1460 : static_txtattr_cast<const SwTextField*>(pHt)->CopyTextField(
1461 44 : static_txtattr_cast<SwTextField*>(pNewHt));
1462 : }
1463 :
1464 : // Tabellenformel ??
1465 757 : const SwFormatField& rField = pHt->GetFormatField();
1466 1514 : if( RES_TABLEFLD == rField.GetField()->GetTyp()->Which()
1467 757 : && static_cast<const SwTableField*>(rField.GetField())->IsIntrnlName())
1468 : {
1469 : // wandel die interne in eine externe Formel um
1470 : const SwTableNode* const pDstTableNd =
1471 0 : static_txtattr_cast<const SwTextField*>(pHt)->GetTextNode().FindTableNode();
1472 0 : if( pDstTableNd )
1473 : {
1474 : SwTableField* const pTableField =
1475 : const_cast<SwTableField*>(static_cast<const SwTableField*>(
1476 0 : pNewHt->GetFormatField().GetField()));
1477 0 : pTableField->PtrToBoxNm( &pDstTableNd->GetTable() );
1478 : }
1479 : }
1480 : }
1481 757 : break;
1482 :
1483 : case RES_TXTATR_INPUTFIELD :
1484 : case RES_TXTATR_ANNOTATION :
1485 9 : if( pOtherDoc != NULL )
1486 : {
1487 : static_txtattr_cast<const SwTextField*>(pHt)->CopyTextField(
1488 9 : static_txtattr_cast<SwTextField*>(pNewHt));
1489 : }
1490 9 : break;
1491 :
1492 : case RES_TXTATR_TOXMARK :
1493 0 : if( pOtherDoc && pDest && pDest->GetpSwpHints()
1494 0 : && pDest->GetpSwpHints()->Contains( pNewHt ) )
1495 : {
1496 : // Beim Kopieren von TOXMarks(Client) in andere Dokumente
1497 : // muss der Verzeichnis (Modify) ausgetauscht werden
1498 0 : static_txtattr_cast<SwTextTOXMark*>(pNewHt)->CopyTOXMark(pOtherDoc);
1499 : }
1500 0 : break;
1501 :
1502 : case RES_TXTATR_CHARFMT :
1503 : // Wenn wir es mit einer Zeichenvorlage zu tun haben,
1504 : // muessen wir natuerlich auch die Formate kopieren.
1505 488 : if( pDest && pDest->GetpSwpHints()
1506 488 : && pDest->GetpSwpHints()->Contains( pNewHt ) )
1507 : {
1508 : SwCharFormat* pFormat =
1509 244 : static_cast<SwCharFormat*>(pHt->GetCharFormat().GetCharFormat());
1510 :
1511 244 : if (pOtherDoc)
1512 : {
1513 0 : pFormat = pOtherDoc->CopyCharFormat( *pFormat );
1514 : }
1515 : const_cast<SwFormatCharFormat&>( static_cast<const SwFormatCharFormat&>(
1516 244 : pNewHt->GetCharFormat() ) ).SetCharFormat( pFormat );
1517 : }
1518 244 : break;
1519 : case RES_TXTATR_INETFMT :
1520 : {
1521 : // Wenn wir es mit benutzerdefinierten INet-Zeichenvorlagen
1522 : // zu tun haben, muessen wir natuerlich auch die Formate kopieren.
1523 59 : if( pOtherDoc && pDest && pDest->GetpSwpHints()
1524 59 : && pDest->GetpSwpHints()->Contains( pNewHt ) )
1525 : {
1526 : const SwDoc* const pDoc = static_txtattr_cast<
1527 0 : const SwTextINetFormat*>(pHt)->GetTextNode().GetDoc();
1528 0 : if ( pDoc )
1529 : {
1530 0 : const SwCharFormats* pCharFormats = pDoc->GetCharFormats();
1531 0 : const SwFormatINetFormat& rFormat = pHt->GetINetFormat();
1532 : SwCharFormat* pFormat;
1533 0 : pFormat = lcl_FindCharFormat( pCharFormats, rFormat.GetINetFormat() );
1534 0 : if( pFormat )
1535 0 : pOtherDoc->CopyCharFormat( *pFormat );
1536 0 : pFormat = lcl_FindCharFormat( pCharFormats, rFormat.GetVisitedFormat() );
1537 0 : if( pFormat )
1538 0 : pOtherDoc->CopyCharFormat( *pFormat );
1539 : }
1540 : }
1541 : //JP 24.04.98: Bug 49753 - ein TextNode muss am Attribut
1542 : // gesetzt sein, damit die Vorlagen erzeugt
1543 : // werden koenne
1544 59 : SwTextINetFormat *const pINetHt = static_txtattr_cast<SwTextINetFormat*>(pNewHt);
1545 59 : if ( !pINetHt->GetpTextNode() )
1546 : {
1547 0 : pINetHt->ChgTextNode( pDest );
1548 : }
1549 :
1550 : //JP 22.10.97: Bug 44875 - Verbindung zum Format herstellen
1551 59 : pINetHt->GetCharFormat();
1552 59 : break;
1553 : }
1554 : case RES_TXTATR_META:
1555 : case RES_TXTATR_METAFIELD:
1556 : OSL_ENSURE( pNewHt, "copying Meta should not fail!" );
1557 : OSL_ENSURE( pDest
1558 : && (CH_TXTATR_INWORD == pDest->GetText()[pNewHt->GetStart()]),
1559 : "missing CH_TXTATR?");
1560 0 : break;
1561 : }
1562 3063 : }
1563 :
1564 : // Beschreibung kopiert Attribute an der Position nStart in pDest.
1565 : // BP 7.6.93: Es werden mit Absicht nur die Attribute _mit_ EndIdx
1566 : // kopiert! CopyAttr wird vornehmlich dann gerufen,
1567 : // wenn Attribute fuer einen Node mit leerem String
1568 : // gesetzt werden sollen.
1569 7584 : void SwTextNode::CopyAttr( SwTextNode *pDest, const sal_Int32 nTextStartIdx,
1570 : const sal_Int32 nOldPos )
1571 : {
1572 7584 : if ( HasHints() ) // keine Attribute, keine Kekse
1573 : {
1574 1657 : SwDoc* const pOtherDoc = (pDest->GetDoc() != GetDoc()) ?
1575 1657 : pDest->GetDoc() : 0;
1576 :
1577 1749 : for ( size_t i = 0; i < m_pSwpHints->Count(); ++i )
1578 : {
1579 92 : SwTextAttr *const pHt = m_pSwpHints->GetTextHint(i);
1580 92 : sal_Int32 const nAttrStartIdx = pHt->GetStart();
1581 92 : if ( nTextStartIdx < nAttrStartIdx )
1582 0 : break; // ueber das Textende, da nLen == 0
1583 :
1584 92 : const sal_Int32 *const pEndIdx = pHt->GetEnd();
1585 92 : if ( pEndIdx && !pHt->HasDummyChar() )
1586 : {
1587 92 : sal_uInt16 const nWhich = pHt->Which();
1588 92 : if (RES_TXTATR_INPUTFIELD != nWhich // fdo#74981 skip fields
1589 91 : && ( *pEndIdx > nTextStartIdx
1590 91 : || (*pEndIdx == nTextStartIdx
1591 91 : && nAttrStartIdx == nTextStartIdx)))
1592 : {
1593 91 : if ( RES_TXTATR_REFMARK != nWhich )
1594 : {
1595 : // attribute in the area => copy
1596 : SwTextAttr *const pNewHt =
1597 91 : pDest->InsertItem( pHt->GetAttr(), nOldPos, nOldPos, SetAttrMode::IS_COPY);
1598 91 : if ( pNewHt )
1599 : {
1600 : lcl_CopyHint( nWhich, pHt, pNewHt,
1601 81 : pOtherDoc, pDest );
1602 : }
1603 : }
1604 0 : else if( !pOtherDoc
1605 0 : ? GetDoc()->IsCopyIsMove()
1606 0 : : 0 == pOtherDoc->GetRefMark( pHt->GetRefMark().GetRefName() ) )
1607 : {
1608 : pDest->InsertItem(
1609 0 : pHt->GetAttr(), nOldPos, nOldPos, SetAttrMode::IS_COPY);
1610 : }
1611 : }
1612 : }
1613 : }
1614 : }
1615 :
1616 7584 : if( this != pDest )
1617 : {
1618 : // Frames benachrichtigen, sonst verschwinden die Footnote-Nummern
1619 : SwUpdateAttr aHint(
1620 : nOldPos,
1621 : nOldPos,
1622 7584 : 0);
1623 :
1624 7584 : pDest->ModifyNotification( 0, &aHint );
1625 : }
1626 7584 : }
1627 :
1628 : // kopiert Zeichen und Attibute in pDest, wird angehaengt
1629 : // introduction of new optional parameter to control, if all attributes have to be copied.
1630 6914 : void SwTextNode::CopyText( SwTextNode *const pDest,
1631 : const SwIndex &rStart,
1632 : const sal_Int32 nLen,
1633 : const bool bForceCopyOfAllAttrs )
1634 : {
1635 6914 : SwIndex const aIdx( pDest, pDest->m_Text.getLength() );
1636 6914 : CopyText( pDest, aIdx, rStart, nLen, bForceCopyOfAllAttrs );
1637 6914 : }
1638 :
1639 : // introduction of new optional parameter to control, if all attributes have to be copied.
1640 7214 : void SwTextNode::CopyText( SwTextNode *const pDest,
1641 : const SwIndex &rDestStart,
1642 : const SwIndex &rStart,
1643 : sal_Int32 nLen,
1644 : const bool bForceCopyOfAllAttrs )
1645 : {
1646 7214 : sal_Int32 nTextStartIdx = rStart.GetIndex();
1647 7214 : sal_Int32 nDestStart = rDestStart.GetIndex(); // alte Pos merken
1648 :
1649 7214 : if (pDest->GetDoc()->IsClipBoard() && this->GetNum())
1650 : {
1651 : // #i111677# cache expansion of source (for clipboard)
1652 : pDest->m_pNumStringCache.reset( (nTextStartIdx != 0)
1653 0 : ? new OUString // fdo#49076: numbering only if copy from para start
1654 0 : : new OUString(this->GetNumString()));
1655 : }
1656 :
1657 7214 : if( !nLen )
1658 : {
1659 : // wurde keine Laenge angegeben, dann Kopiere die Attribute
1660 : // an der Position rStart.
1661 4134 : CopyAttr( pDest, nTextStartIdx, nDestStart );
1662 :
1663 : // harte Absatz umspannende Attribute kopieren
1664 4134 : if( HasSwAttrSet() )
1665 : {
1666 : // alle, oder nur die CharAttribute ?
1667 : // #i96213#
1668 1102 : if ( !bForceCopyOfAllAttrs &&
1669 156 : ( nDestStart ||
1670 312 : pDest->HasSwAttrSet() ||
1671 156 : nLen != pDest->GetText().getLength()))
1672 : {
1673 0 : SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
1674 : RES_CHRATR_BEGIN, RES_CHRATR_END-1,
1675 : RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
1676 : RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
1677 : RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
1678 0 : 0 );
1679 0 : aCharSet.Put( *GetpSwAttrSet() );
1680 0 : if( aCharSet.Count() )
1681 : {
1682 0 : pDest->SetAttr( aCharSet, nDestStart, nDestStart );
1683 0 : }
1684 : }
1685 : else
1686 : {
1687 1102 : GetpSwAttrSet()->CopyToModify( *pDest );
1688 : }
1689 : }
1690 8268 : return;
1691 : }
1692 :
1693 : // 1. Text kopieren
1694 3080 : const sal_Int32 oldLen = pDest->m_Text.getLength();
1695 : //JP 15.02.96: Bug 25537 - Attributbehandlung am Ende fehlt! Darum
1696 : // ueber die InsertMethode den Text einfuegen und nicht
1697 : // selbst direkt
1698 : pDest->InsertText( m_Text.copy(nTextStartIdx, nLen), rDestStart,
1699 3080 : SwInsertFlags::EMPTYEXPAND );
1700 :
1701 : // um reale Groesse Updaten !
1702 3080 : nLen = pDest->m_Text.getLength() - oldLen;
1703 3080 : if ( !nLen ) // string not longer?
1704 0 : return;
1705 :
1706 3080 : SwDoc* const pOtherDoc = (pDest->GetDoc() != GetDoc()) ? pDest->GetDoc() : 0;
1707 :
1708 : // harte Absatz umspannende Attribute kopieren
1709 3080 : if( HasSwAttrSet() )
1710 : {
1711 : // alle, oder nur die CharAttribute ?
1712 : // #i96213#
1713 1833 : if ( !bForceCopyOfAllAttrs &&
1714 69 : ( nDestStart ||
1715 137 : pDest->HasSwAttrSet() ||
1716 68 : nLen != pDest->GetText().getLength()))
1717 : {
1718 5 : SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
1719 : RES_CHRATR_BEGIN, RES_CHRATR_END-1,
1720 : RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
1721 : RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
1722 : RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
1723 5 : 0 );
1724 5 : aCharSet.Put( *GetpSwAttrSet() );
1725 5 : if( aCharSet.Count() )
1726 : {
1727 5 : pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen );
1728 5 : }
1729 : }
1730 : else
1731 : {
1732 1823 : GetpSwAttrSet()->CopyToModify( *pDest );
1733 : }
1734 : }
1735 :
1736 : bool const bUndoNodes = !pOtherDoc
1737 3080 : && GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(GetNodes());
1738 :
1739 : // Ende erst jetzt holen, weil beim Kopieren in sich selbst der
1740 : // Start-Index und alle Attribute vorher aktualisiert werden.
1741 3080 : nTextStartIdx = rStart.GetIndex();
1742 3080 : const sal_Int32 nEnd = nTextStartIdx + nLen;
1743 :
1744 : // 2. Attribute kopieren
1745 : // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
1746 : // des Attributs hinter dem zu kopierenden Bereich liegt
1747 3080 : const size_t nSize = m_pSwpHints ? m_pSwpHints->Count() : 0;
1748 :
1749 : // wird in sich selbst kopiert, dann kann beim Einfuegen ein
1750 : // Attribut geloescht werden. Darum erst ins Tmp-Array kopieren und
1751 : // dann erst ins eigene uebertragen.
1752 3080 : SwpHts aArr;
1753 :
1754 : // Del-Array fuer alle RefMarks ohne Ausdehnung
1755 6160 : SwpHts aRefMrkArr;
1756 :
1757 3080 : sal_Int32 nDeletedDummyChars(0);
1758 : //Achtung: kann ungueltig sein!!
1759 6040 : for (size_t n = 0; n < nSize; ++n)
1760 : {
1761 3823 : const sal_Int32 nAttrStartIdx = (*m_pSwpHints)[n]->GetStart();
1762 3823 : if (!( nAttrStartIdx < nEnd))
1763 863 : break;
1764 :
1765 2960 : SwTextAttr * const pHt = m_pSwpHints->GetTextHint(n);
1766 2960 : const sal_Int32 * const pEndIdx = pHt->GetEnd();
1767 2960 : const sal_uInt16 nWhich = pHt->Which();
1768 :
1769 : // JP 26.04.94: REFMARK's werden nie kopiert. Hat das Refmark aber
1770 : // keinen Bereich umspannt, so steht im Text ein 255
1771 : // dieses muss entfernt werden. Trick: erst kopieren,
1772 : // erkennen und sammeln, nach dem kopieren Loeschen.
1773 : // Nimmt sein Zeichen mit ins Grab !!
1774 : // JP 14.08.95: Duerfen RefMarks gemovt werden?
1775 : const bool bCopyRefMark = RES_TXTATR_REFMARK == nWhich
1776 2960 : && ( bUndoNodes
1777 0 : || ( !pOtherDoc
1778 0 : ? GetDoc()->IsCopyIsMove()
1779 2960 : : 0 == pOtherDoc->GetRefMark( pHt->GetRefMark().GetRefName() ) ) );
1780 :
1781 2960 : if ( pEndIdx
1782 2022 : && RES_TXTATR_REFMARK == nWhich
1783 0 : && !bCopyRefMark )
1784 : {
1785 0 : continue;
1786 : }
1787 :
1788 : // Input Fields are only copied, if completely covered by copied text
1789 2960 : if ( nWhich == RES_TXTATR_INPUTFIELD )
1790 : {
1791 : OSL_ENSURE( pEndIdx != NULL,
1792 : "<SwTextNode::CopyText(..)> - RES_TXTATR_INPUTFIELD without EndIndex!" );
1793 4 : if ( nAttrStartIdx < nTextStartIdx
1794 4 : || ( pEndIdx != NULL
1795 4 : && *(pEndIdx) > nEnd ) )
1796 : {
1797 0 : continue;
1798 : }
1799 : }
1800 :
1801 2960 : sal_Int32 nAttrStt = 0;
1802 2960 : sal_Int32 nAttrEnd = 0;
1803 :
1804 2960 : if( nAttrStartIdx < nTextStartIdx )
1805 : {
1806 : // start is before selection
1807 : // copy hints with end and CH_TXTATR only if dummy char is copied
1808 0 : if ( pEndIdx && (*pEndIdx > nTextStartIdx) && !pHt->HasDummyChar() )
1809 : {
1810 : // attribute with extent and the end is in the selection
1811 0 : nAttrStt = nDestStart;
1812 0 : nAttrEnd = (*pEndIdx > nEnd)
1813 : ? rDestStart.GetIndex()
1814 0 : : nDestStart + (*pEndIdx) - nTextStartIdx;
1815 : }
1816 : else
1817 : {
1818 0 : continue;
1819 : }
1820 : }
1821 : else
1822 : {
1823 : // start is in the selection
1824 2960 : nAttrStt = nDestStart + ( nAttrStartIdx - nTextStartIdx );
1825 2960 : if( pEndIdx )
1826 : {
1827 2022 : nAttrEnd = *pEndIdx > nEnd
1828 : ? rDestStart.GetIndex()
1829 2022 : : nDestStart + ( *pEndIdx - nTextStartIdx );
1830 : }
1831 : else
1832 : {
1833 938 : nAttrEnd = nAttrStt;
1834 : }
1835 : }
1836 :
1837 2960 : SwTextAttr * pNewHt = 0;
1838 :
1839 2960 : if( pDest == this )
1840 : {
1841 : // copy the hint here, but insert it later
1842 0 : pNewHt = MakeTextAttr( *GetDoc(), pHt->GetAttr(),
1843 0 : nAttrStt, nAttrEnd, COPY, pDest );
1844 :
1845 0 : lcl_CopyHint(nWhich, pHt, pNewHt, 0, pDest);
1846 0 : aArr.push_back( pNewHt );
1847 : }
1848 : else
1849 : {
1850 : pNewHt = pDest->InsertItem(
1851 2960 : pHt->GetAttr(),
1852 : nAttrStt - nDeletedDummyChars,
1853 : nAttrEnd - nDeletedDummyChars,
1854 5920 : SetAttrMode::NOTXTATRCHR | SetAttrMode::IS_COPY);
1855 2960 : if (pNewHt)
1856 : {
1857 2960 : lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest );
1858 : }
1859 0 : else if (pHt->HasDummyChar())
1860 : {
1861 : // The attribute that has failed to be copied would insert
1862 : // dummy char, so positions of the following attributes have
1863 : // to be shifted by one to compensate for that missing char.
1864 0 : ++nDeletedDummyChars;
1865 : }
1866 : }
1867 :
1868 2960 : if( RES_TXTATR_REFMARK == nWhich && !pEndIdx && !bCopyRefMark )
1869 : {
1870 0 : aRefMrkArr.push_back( pNewHt );
1871 : }
1872 : }
1873 :
1874 : // nur falls im Array Attribute stehen (kann nur beim Kopieren
1875 : // sich selbst passieren!!)
1876 3080 : for ( size_t i = 0; i < aArr.size(); ++i )
1877 : {
1878 0 : InsertHint( aArr[ i ], SetAttrMode::NOTXTATRCHR );
1879 : }
1880 :
1881 3080 : if( pDest->GetpSwpHints() )
1882 : {
1883 1965 : for ( size_t i = 0; i < aRefMrkArr.size(); ++i )
1884 : {
1885 0 : SwTextAttr * const pNewHt = aRefMrkArr[i];
1886 0 : if( pNewHt->GetEnd() )
1887 : {
1888 0 : pDest->GetpSwpHints()->Delete( pNewHt );
1889 0 : pDest->DestroyAttr( pNewHt );
1890 : }
1891 : else
1892 : {
1893 0 : const SwIndex aIdx( pDest, pNewHt->GetStart() );
1894 0 : pDest->EraseText( aIdx, 1 );
1895 : }
1896 : }
1897 : }
1898 :
1899 : CHECK_SWPHINTS(this);
1900 3080 : CHECK_SWPHINTS(pDest);
1901 : }
1902 :
1903 154410 : OUString SwTextNode::InsertText( const OUString & rStr, const SwIndex & rIdx,
1904 : const SwInsertFlags nMode )
1905 : {
1906 : assert(rIdx <= m_Text.getLength()); // invalid index
1907 :
1908 154410 : const sal_Int32 aPos = rIdx.GetIndex();
1909 154410 : sal_Int32 nLen = m_Text.getLength() - aPos;
1910 154410 : sal_Int32 const nOverflow(rStr.getLength() - GetSpaceLeft());
1911 : SAL_WARN_IF(nOverflow > 0, "sw.core",
1912 : "SwTextNode::InsertText: node text with insertion > capacity.");
1913 : OUString const sInserted(
1914 154410 : (nOverflow > 0) ? rStr.copy(0, rStr.getLength() - nOverflow) : rStr);
1915 154410 : if (sInserted.isEmpty())
1916 : {
1917 287 : return sInserted;
1918 : }
1919 154123 : m_Text = m_Text.replaceAt(aPos, 0, sInserted);
1920 : assert(GetSpaceLeft()>=0);
1921 154123 : nLen = m_Text.getLength() - aPos - nLen;
1922 : assert(nLen != 0);
1923 :
1924 154123 : bool bOldExpFlg = IsIgnoreDontExpand();
1925 154123 : if (nMode & SwInsertFlags::FORCEHINTEXPAND)
1926 : {
1927 61 : SetIgnoreDontExpand( true );
1928 : }
1929 :
1930 154123 : Update( rIdx, nLen ); // text content changed!
1931 :
1932 154123 : if (nMode & SwInsertFlags::FORCEHINTEXPAND)
1933 : {
1934 61 : SetIgnoreDontExpand( bOldExpFlg );
1935 : }
1936 :
1937 : // analog zu Insert(char) in txtedt.cxx:
1938 : // 1) bei bHintExp leere Hints an rIdx.GetIndex suchen und aufspannen
1939 : // 2) bei bHintExp == false mitgezogene Feldattribute zuruecksetzen
1940 :
1941 154123 : if ( HasHints() )
1942 : {
1943 25945 : bool bMergePortionsNeeded(false);
1944 400706 : for ( size_t i = 0; i < m_pSwpHints->Count() &&
1945 187457 : rIdx >= (*m_pSwpHints)[i]->GetStart(); ++i )
1946 : {
1947 187304 : SwTextAttr * const pHt = m_pSwpHints->GetTextHint( i );
1948 187304 : sal_Int32 * const pEndIdx = pHt->GetEnd();
1949 187304 : if( !pEndIdx )
1950 116133 : continue;
1951 :
1952 71171 : if( rIdx == *pEndIdx )
1953 : {
1954 1479 : if ( (nMode & SwInsertFlags::NOHINTEXPAND) ||
1955 882 : (!(nMode & SwInsertFlags::FORCEHINTEXPAND)
1956 528 : && pHt->DontExpand()) )
1957 : {
1958 : // bei leeren Attributen auch Start veraendern
1959 9 : if( rIdx == pHt->GetStart() )
1960 9 : pHt->GetStart() = pHt->GetStart() - nLen;
1961 9 : *pEndIdx = *pEndIdx - nLen;
1962 9 : m_pSwpHints->DeleteAtPos(i);
1963 : // could be that pHt has IsFormatIgnoreEnd set, and it's
1964 : // not a RSID-only hint - now we have the inserted text
1965 : // between pHt and its continuation... which we don't know.
1966 : // punt the job to MergePortions below.
1967 9 : if (pHt->IsFormatIgnoreEnd())
1968 : {
1969 0 : bMergePortionsNeeded = true;
1970 : }
1971 9 : InsertHint( pHt, SetAttrMode::NOHINTADJUST );
1972 : }
1973 : // empty hints at insert position?
1974 570 : else if ( (nMode & SwInsertFlags::EMPTYEXPAND)
1975 570 : && (*pEndIdx == pHt->GetStart()) )
1976 : {
1977 1 : pHt->GetStart() = pHt->GetStart() - nLen;
1978 1 : const size_t nAktLen = m_pSwpHints->Count();
1979 1 : m_pSwpHints->DeleteAtPos(i);
1980 1 : InsertHint( pHt/* AUTOSTYLES:, SetAttrMode::NOHINTADJUST*/ );
1981 1 : if ( nAktLen > m_pSwpHints->Count() && i )
1982 : {
1983 0 : --i;
1984 : }
1985 1 : continue;
1986 : }
1987 : else
1988 : {
1989 284 : continue;
1990 : }
1991 : }
1992 283544 : if ( !(nMode & SwInsertFlags::NOHINTEXPAND) &&
1993 212868 : rIdx == nLen && pHt->GetStart() == rIdx.GetIndex() &&
1994 103 : !pHt->IsDontExpandStartAttr() )
1995 : {
1996 : // Kein Feld, am Absatzanfang, HintExpand
1997 102 : m_pSwpHints->DeleteAtPos(i);
1998 102 : pHt->GetStart() = pHt->GetStart() - nLen;
1999 : // no effect on format ignore flags here (para start)
2000 102 : InsertHint( pHt, SetAttrMode::NOHINTADJUST );
2001 : }
2002 : }
2003 25945 : if (bMergePortionsNeeded)
2004 : {
2005 0 : m_pSwpHints->MergePortions(*this);
2006 : }
2007 25945 : TryDeleteSwpHints();
2008 : }
2009 :
2010 154123 : if ( HasWriterListeners() )
2011 : {
2012 10312 : SwInsText aHint( aPos, nLen );
2013 10312 : NotifyClients( 0, &aHint );
2014 : }
2015 :
2016 : // By inserting a character, the hidden flags
2017 : // at the TextNode can become invalid:
2018 154123 : SetCalcHiddenCharFlags();
2019 :
2020 : CHECK_SWPHINTS(this);
2021 154123 : return sInserted;
2022 : }
2023 :
2024 4443 : void SwTextNode::CutText( SwTextNode * const pDest,
2025 : const SwIndex & rStart, const sal_Int32 nLen )
2026 : {
2027 : assert(pDest); // Cut requires a destination
2028 4443 : SwIndex aDestStt(pDest, pDest->GetText().getLength());
2029 4443 : CutImpl( pDest, aDestStt, rStart, nLen, false );
2030 4443 : }
2031 :
2032 4675 : void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart,
2033 : const SwIndex & rStart, sal_Int32 nLen, const bool bUpdate )
2034 : {
2035 : assert(pDest); // Cut requires a destination
2036 :
2037 : assert(GetDoc() == pDest->GetDoc()); // must be same document
2038 :
2039 : assert(pDest != this); // destination must be different node
2040 :
2041 4675 : if( !nLen )
2042 : {
2043 : // wurde keine Laenge angegeben, dann Kopiere die Attribute
2044 : // an der Position rStart.
2045 3448 : CopyAttr( pDest, rStart.GetIndex(), rDestStart.GetIndex() );
2046 6896 : return;
2047 : }
2048 :
2049 1227 : sal_Int32 nTextStartIdx = rStart.GetIndex();
2050 1227 : sal_Int32 nDestStart = rDestStart.GetIndex(); // alte Pos merken
2051 1227 : const sal_Int32 nInitSize = pDest->m_Text.getLength();
2052 :
2053 2454 : pDest->m_Text = pDest->m_Text.replaceAt(nDestStart, 0,
2054 1227 : m_Text.copy(nTextStartIdx, nLen));
2055 1227 : m_Text = m_Text.replaceAt(nTextStartIdx, nLen, "");
2056 1227 : if (GetSpaceLeft() < 0)
2057 : { // FIXME: could only happen when called from SwRangeRedline::Show.
2058 : // unfortunately can't really do anything here to handle that...
2059 0 : abort();
2060 : }
2061 1227 : nLen = pDest->m_Text.getLength() - nInitSize; // update w/ current size!
2062 1227 : if (!nLen) // String nicht gewachsen ??
2063 0 : return;
2064 :
2065 1227 : if (bUpdate)
2066 : {
2067 : // Update aller Indizies
2068 54 : pDest->Update( rDestStart, nLen, false, true);
2069 : }
2070 :
2071 : CHECK_SWPHINTS(pDest);
2072 :
2073 1227 : const sal_Int32 nEnd = rStart.GetIndex() + nLen;
2074 : bool const bUndoNodes =
2075 1227 : GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(GetNodes());
2076 :
2077 : // harte Absatz umspannende Attribute kopieren
2078 1227 : if (HasSwAttrSet())
2079 : {
2080 : // alle, oder nur die CharAttribute ?
2081 1251 : if( nInitSize || pDest->HasSwAttrSet() ||
2082 76 : nLen != pDest->GetText().getLength())
2083 : {
2084 1099 : SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
2085 : RES_CHRATR_BEGIN, RES_CHRATR_END-1,
2086 : RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
2087 : RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
2088 : RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
2089 1099 : 0 );
2090 1099 : aCharSet.Put( *GetpSwAttrSet() );
2091 1099 : if( aCharSet.Count() )
2092 1061 : pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen );
2093 : }
2094 : else
2095 : {
2096 76 : GetpSwAttrSet()->CopyToModify( *pDest );
2097 : }
2098 : }
2099 :
2100 : // 2. Attribute verschieben
2101 : // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
2102 : // des Attributs hinter dem zu verschiebenden Bereich liegt
2103 1227 : bool bMergePortionsNeeded(false);
2104 1227 : size_t nAttrCnt = 0;
2105 2522 : while (m_pSwpHints && (nAttrCnt < m_pSwpHints->Count()))
2106 : {
2107 70 : SwTextAttr * const pHt = m_pSwpHints->GetTextHint(nAttrCnt);
2108 70 : const sal_Int32 nAttrStartIdx = pHt->GetStart();
2109 70 : if (!( nAttrStartIdx < nEnd ))
2110 2 : break;
2111 68 : const sal_Int32 * const pEndIdx = pHt->GetEnd();
2112 68 : const sal_uInt16 nWhich = pHt->Which();
2113 68 : SwTextAttr *pNewHt = 0;
2114 :
2115 : // if the hint has a dummy character, then it must not be split!
2116 68 : if(nAttrStartIdx < nTextStartIdx)
2117 : {
2118 : // Anfang liegt vor dem Bereich
2119 0 : if (!pHt->HasDummyChar() && ( RES_TXTATR_REFMARK != nWhich
2120 0 : || bUndoNodes ) && pEndIdx && *pEndIdx > nTextStartIdx)
2121 : {
2122 : // Attribut mit einem Bereich
2123 : // und das Ende des Attribut liegt im Bereich
2124 0 : pNewHt = MakeTextAttr( *pDest->GetDoc(), pHt->GetAttr(),
2125 : nDestStart,
2126 : nDestStart + (
2127 0 : *pEndIdx > nEnd
2128 : ? nLen
2129 0 : : *pEndIdx - nTextStartIdx ) );
2130 : }
2131 : }
2132 : else
2133 : {
2134 : // der Anfang liegt vollstaendig im Bereich
2135 148 : if (!pEndIdx || *pEndIdx < nEnd ||
2136 44 : (!bUndoNodes && RES_TXTATR_REFMARK == nWhich)
2137 90 : || pHt->HasDummyChar() )
2138 : {
2139 : // do not delete note and later add it -> sidebar flickering
2140 46 : if (GetDoc()->GetDocShell())
2141 : {
2142 46 : GetDoc()->GetDocShell()->Broadcast( SfxSimpleHint(SFX_HINT_USER04));
2143 : }
2144 : // Attribut verschieben
2145 46 : m_pSwpHints->Delete( pHt );
2146 : // die Start/End Indicies neu setzen
2147 46 : if (pHt->IsFormatIgnoreStart() || pHt->IsFormatIgnoreEnd())
2148 : {
2149 0 : bMergePortionsNeeded = true;
2150 : }
2151 46 : pHt->GetStart() =
2152 46 : nDestStart + (nAttrStartIdx - nTextStartIdx);
2153 46 : if (pEndIdx)
2154 : {
2155 108 : *pHt->GetEnd() = nDestStart + (
2156 36 : *pEndIdx > nEnd
2157 : ? nLen
2158 72 : : *pEndIdx - nTextStartIdx );
2159 : }
2160 : pDest->InsertHint( pHt,
2161 : SetAttrMode::NOTXTATRCHR
2162 46 : | SetAttrMode::DONTREPLACE );
2163 46 : if (GetDoc()->GetDocShell())
2164 : {
2165 46 : GetDoc()->GetDocShell()->Broadcast( SfxSimpleHint(SFX_HINT_USER04));
2166 : }
2167 46 : continue; // while-Schleife weiter, ohne ++ !
2168 : }
2169 : // das Ende liegt dahinter
2170 22 : else if (RES_TXTATR_REFMARK != nWhich || bUndoNodes)
2171 : {
2172 22 : pNewHt = MakeTextAttr( *GetDoc(), pHt->GetAttr(),
2173 22 : nDestStart + (nAttrStartIdx - nTextStartIdx),
2174 22 : nDestStart + (*pEndIdx > nEnd
2175 : ? nLen
2176 66 : : *pEndIdx - nTextStartIdx));
2177 : }
2178 : }
2179 22 : if (pNewHt)
2180 : {
2181 : const bool bSuccess( pDest->InsertHint( pNewHt,
2182 : SetAttrMode::NOTXTATRCHR
2183 : | SetAttrMode::DONTREPLACE
2184 22 : | SetAttrMode::IS_COPY) );
2185 22 : if (bSuccess)
2186 : {
2187 22 : lcl_CopyHint( nWhich, pHt, pNewHt, nullptr, pDest );
2188 : }
2189 : }
2190 22 : ++nAttrCnt;
2191 : }
2192 : // sollten jetzt noch leere Attribute rumstehen, dann haben diese
2193 : // eine hoehere Praezedenz. Also herausholen und das Array updaten.
2194 : // Die dabei entstehenden leeren Hints werden von den gesicherten
2195 : // "uebergeplaettet". (Bug: 6977)
2196 1227 : if (m_pSwpHints && nAttrCnt < m_pSwpHints->Count())
2197 : {
2198 2 : SwpHts aArr;
2199 6 : while (nAttrCnt < m_pSwpHints->Count())
2200 : {
2201 2 : SwTextAttr * const pHt = m_pSwpHints->GetTextHint(nAttrCnt);
2202 2 : if (nEnd != pHt->GetStart())
2203 0 : break;
2204 2 : const sal_Int32 * const pEndIdx = pHt->GetEnd();
2205 2 : if (pEndIdx && *pEndIdx == nEnd)
2206 : {
2207 2 : aArr.push_back( pHt );
2208 2 : m_pSwpHints->Delete( pHt );
2209 : }
2210 : else
2211 : {
2212 0 : ++nAttrCnt;
2213 : }
2214 : }
2215 2 : Update( rStart, nLen, true, true );
2216 :
2217 4 : for (size_t n = 0; n < aArr.size(); ++n)
2218 : {
2219 2 : SwTextAttr * const pHt = aArr[ n ];
2220 2 : pHt->GetStart() = *pHt->GetEnd() = rStart.GetIndex();
2221 2 : InsertHint( pHt );
2222 2 : }
2223 : }
2224 : else
2225 : {
2226 1225 : Update( rStart, nLen, true, true );
2227 : }
2228 :
2229 1227 : if (bMergePortionsNeeded)
2230 : {
2231 0 : m_pSwpHints->MergePortions(*this);
2232 : }
2233 :
2234 : CHECK_SWPHINTS(this);
2235 :
2236 1227 : TryDeleteSwpHints();
2237 :
2238 : // Frames benachrichtigen;
2239 1227 : SwInsText aInsHint( nDestStart, nLen );
2240 1227 : pDest->ModifyNotification( 0, &aInsHint );
2241 2454 : SwDelText aDelHint( nTextStartIdx, nLen );
2242 2454 : ModifyNotification( 0, &aDelHint );
2243 : }
2244 :
2245 5680 : void SwTextNode::EraseText(const SwIndex &rIdx, const sal_Int32 nCount,
2246 : const SwInsertFlags nMode )
2247 : {
2248 : assert(rIdx <= m_Text.getLength()); // invalid index
2249 :
2250 5680 : const sal_Int32 nStartIdx = rIdx.GetIndex();
2251 : const sal_Int32 nCnt = (nCount==SAL_MAX_INT32)
2252 5680 : ? m_Text.getLength() - nStartIdx : nCount;
2253 5680 : const sal_Int32 nEndIdx = nStartIdx + nCnt;
2254 5680 : m_Text = m_Text.replaceAt(nStartIdx, nCnt, "");
2255 :
2256 : /* GCAttr(); alle leeren weggwerfen ist zu brutal.
2257 : * Es duerfen nur die wegggeworfen werden,
2258 : * die im Bereich liegen und nicht am Ende des Bereiches liegen
2259 : */
2260 :
2261 13337 : for ( size_t i = 0; m_pSwpHints && i < m_pSwpHints->Count(); ++i )
2262 : {
2263 7956 : SwTextAttr *pHt = m_pSwpHints->GetTextHint(i);
2264 :
2265 7956 : const sal_Int32 nHintStart = pHt->GetStart();
2266 :
2267 7956 : if ( nHintStart < nStartIdx )
2268 3082 : continue;
2269 :
2270 4874 : if ( nHintStart > nEndIdx )
2271 299 : break; // hints are sorted by end, so break here
2272 :
2273 4575 : const sal_Int32* pHtEndIdx = pHt->GetEnd();
2274 4575 : const sal_uInt16 nWhich = pHt->Which();
2275 :
2276 4575 : if( !pHtEndIdx )
2277 : {
2278 : // attribute with neither end nor CH_TXTATR?
2279 : assert(pHt->HasDummyChar());
2280 12156 : if (isTXTATR(nWhich) &&
2281 8104 : (nHintStart >= nStartIdx) && (nHintStart < nEndIdx))
2282 : {
2283 3786 : m_pSwpHints->DeleteAtPos(i);
2284 3786 : DestroyAttr( pHt );
2285 3786 : --i;
2286 : }
2287 4052 : continue;
2288 : }
2289 :
2290 : assert(!( (nHintStart < nEndIdx) && (*pHtEndIdx > nEndIdx)
2291 : && pHt->HasDummyChar() )
2292 : // next line: deleting exactly dummy char: DeleteAttributes
2293 : || ((nHintStart == nStartIdx) && (nHintStart + 1 == nEndIdx)));
2294 : // "ERROR: deleting left-overlapped attribute with CH_TXTATR");
2295 :
2296 : // Delete the hint if:
2297 : // 1. The hint ends before the deletion end position or
2298 : // 2. The hint ends at the deletion end position and
2299 : // we are not in empty expand mode and
2300 : // the hint is a [toxmark|refmark|ruby|inputfield] text attribute
2301 : // 3. deleting exactly the dummy char of an hint with end and dummy
2302 : // char deletes the hint
2303 1823 : if ( (*pHtEndIdx < nEndIdx)
2304 1004 : || ( (*pHtEndIdx == nEndIdx) &&
2305 1599 : !(SwInsertFlags::EMPTYEXPAND & nMode) &&
2306 269 : ( (RES_TXTATR_TOXMARK == nWhich) ||
2307 269 : (RES_TXTATR_REFMARK == nWhich) ||
2308 268 : (RES_TXTATR_CJK_RUBY == nWhich) ||
2309 : (RES_TXTATR_INPUTFIELD == nWhich) ) )
2310 1724 : || ( (nHintStart < nEndIdx) &&
2311 213 : pHt->HasDummyChar() )
2312 : )
2313 : {
2314 63 : m_pSwpHints->DeleteAtPos(i);
2315 63 : DestroyAttr( pHt );
2316 63 : --i;
2317 : }
2318 : }
2319 :
2320 : OSL_ENSURE(rIdx.GetIndex() == nStartIdx, "huh? start index has changed?");
2321 :
2322 5680 : TryDeleteSwpHints();
2323 :
2324 5680 : Update( rIdx, nCnt, true );
2325 :
2326 5680 : if( 1 == nCnt )
2327 : {
2328 5112 : SwDelChr aHint( nStartIdx );
2329 5112 : NotifyClients( 0, &aHint );
2330 : }
2331 : else
2332 : {
2333 568 : SwDelText aHint( nStartIdx, nCnt );
2334 568 : NotifyClients( 0, &aHint );
2335 : }
2336 :
2337 : OSL_ENSURE(rIdx.GetIndex() == nStartIdx, "huh? start index has changed?");
2338 :
2339 : // By deleting a character, the hidden flags
2340 : // at the TextNode can become invalid:
2341 5680 : SetCalcHiddenCharFlags();
2342 :
2343 : CHECK_SWPHINTS(this);
2344 5680 : }
2345 :
2346 1 : void SwTextNode::GCAttr()
2347 : {
2348 1 : if ( !HasHints() )
2349 1 : return;
2350 :
2351 1 : bool bChanged = false;
2352 1 : sal_Int32 nMin = m_Text.getLength();
2353 1 : sal_Int32 nMax = 0;
2354 1 : const bool bAll = nMin != 0; // Bei leeren Absaetzen werden nur die
2355 : // INet-Formate entfernt.
2356 :
2357 2 : for ( size_t i = 0; m_pSwpHints && i < m_pSwpHints->Count(); ++i )
2358 : {
2359 1 : SwTextAttr * const pHt = m_pSwpHints->GetTextHint(i);
2360 :
2361 : // wenn Ende und Start gleich sind --> loeschen
2362 1 : const sal_Int32 * const pEndIdx = pHt->GetEnd();
2363 2 : if (pEndIdx && !pHt->HasDummyChar() && (*pEndIdx == pHt->GetStart())
2364 2 : && ( bAll || pHt->Which() == RES_TXTATR_INETFMT ) )
2365 : {
2366 0 : bChanged = true;
2367 0 : nMin = std::min( nMin, pHt->GetStart() );
2368 0 : nMax = std::max( nMax, *pHt->GetEnd() );
2369 0 : DestroyAttr( m_pSwpHints->Cut(i) );
2370 0 : --i;
2371 : }
2372 : else
2373 : {
2374 1 : pHt->SetDontExpand( false );
2375 : }
2376 : }
2377 1 : TryDeleteSwpHints();
2378 :
2379 1 : if(bChanged)
2380 : {
2381 : //TextFrm's reagieren auf aHint, andere auf aNew
2382 : SwUpdateAttr aHint(
2383 : nMin,
2384 : nMax,
2385 0 : 0);
2386 :
2387 0 : NotifyClients( 0, &aHint );
2388 0 : SwFormatChg aNew( GetTextColl() );
2389 0 : NotifyClients( 0, &aNew );
2390 : }
2391 : }
2392 :
2393 : // #i23726#
2394 833863 : SwNumRule* SwTextNode::_GetNumRule(bool bInParent) const
2395 : {
2396 833863 : SwNumRule* pRet = 0;
2397 :
2398 833863 : const SfxPoolItem* pItem = GetNoCondAttr( RES_PARATR_NUMRULE, bInParent );
2399 833863 : bool bNoNumRule = false;
2400 833863 : if ( pItem )
2401 : {
2402 : OUString sNumRuleName =
2403 104016 : static_cast<const SwNumRuleItem *>(pItem)->GetValue();
2404 104016 : if (!sNumRuleName.isEmpty())
2405 : {
2406 99623 : pRet = GetDoc()->FindNumRulePtr( sNumRuleName );
2407 : }
2408 : else // numbering is turned off
2409 4393 : bNoNumRule = true;
2410 : }
2411 :
2412 833863 : if ( !bNoNumRule )
2413 : {
2414 843827 : if ( pRet && pRet == GetDoc()->GetOutlineNumRule() &&
2415 13642 : ( !HasSwAttrSet() ||
2416 : SfxItemState::SET !=
2417 6319 : GetpSwAttrSet()->GetItemState( RES_PARATR_NUMRULE, false ) ) )
2418 : {
2419 7034 : SwTextFormatColl* pColl = GetTextColl();
2420 7034 : if ( pColl )
2421 : {
2422 7034 : const SwNumRuleItem& rDirectItem = pColl->GetNumRule( false );
2423 7034 : if ( rDirectItem.GetValue().isEmpty() )
2424 : {
2425 0 : pRet = 0L;
2426 : }
2427 : }
2428 : }
2429 : }
2430 :
2431 833863 : return pRet;
2432 : }
2433 :
2434 833863 : SwNumRule* SwTextNode::GetNumRule(bool bInParent) const
2435 : {
2436 833863 : return _GetNumRule(bInParent);
2437 : }
2438 :
2439 5458 : void SwTextNode::NumRuleChgd()
2440 : {
2441 5458 : if ( IsInList() )
2442 : {
2443 5458 : SwNumRule* pNumRule = GetNumRule();
2444 5458 : if ( pNumRule && pNumRule != GetNum()->GetNumRule() )
2445 : {
2446 0 : mpNodeNum->ChangeNumRule( *pNumRule );
2447 : }
2448 : }
2449 :
2450 5458 : if( IsInCache() )
2451 : {
2452 103 : SwFrm::GetCache().Delete( this );
2453 103 : SetInCache( false );
2454 : }
2455 5458 : SetInSwFntCache( false );
2456 :
2457 : // Sending "noop" modify in order to cause invalidations of registered
2458 : // <SwTextFrm> instances to get the list style change respectively the change
2459 : // in the list tree reflected in the layout.
2460 : // Important note:
2461 : {
2462 5458 : SvxLRSpaceItem& rLR = (SvxLRSpaceItem&)GetSwAttrSet().GetLRSpace();
2463 5458 : NotifyClients( &rLR, &rLR );
2464 : }
2465 :
2466 5458 : SetWordCountDirty( true );
2467 5458 : }
2468 :
2469 : // -> #i27615#
2470 95100 : bool SwTextNode::IsNumbered() const
2471 : {
2472 95100 : SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
2473 95100 : return pRule && IsCountedInList();
2474 : }
2475 :
2476 629 : bool SwTextNode::HasMarkedLabel() const
2477 : {
2478 629 : bool bResult = false;
2479 :
2480 629 : if ( IsInList() )
2481 : {
2482 : bResult =
2483 621 : GetDoc()->getIDocumentListsAccess().getListByName( GetListId() )->IsListLevelMarked( GetActualListLevel() );
2484 : }
2485 :
2486 629 : return bResult;
2487 : }
2488 : // <- #i27615#
2489 :
2490 37514 : SwTextNode* SwTextNode::_MakeNewTextNode( const SwNodeIndex& rPos, bool bNext,
2491 : bool bChgFollow )
2492 : {
2493 : /* hartes PageBreak/PageDesc/ColumnBreak aus AUTO-Set ignorieren */
2494 37514 : SwAttrSet* pNewAttrSet = 0;
2495 : // #i75353#
2496 37514 : bool bClearHardSetNumRuleWhenFormatCollChanges( false );
2497 37514 : if( HasSwAttrSet() )
2498 : {
2499 3051 : pNewAttrSet = new SwAttrSet( *GetpSwAttrSet() );
2500 3051 : const SfxItemSet* pTmpSet = GetpSwAttrSet();
2501 :
2502 3051 : if( bNext ) // der naechste erbt keine Breaks!
2503 1920 : pTmpSet = pNewAttrSet;
2504 :
2505 : // PageBreaks/PageDesc/ColBreak rausschmeissen.
2506 3051 : bool bRemoveFromCache = false;
2507 3051 : std::vector<sal_uInt16> aClearWhichIds;
2508 3051 : if ( bNext )
2509 1920 : bRemoveFromCache = ( 0 != pNewAttrSet->ClearItem( RES_PAGEDESC ) );
2510 : else
2511 1131 : aClearWhichIds.push_back( RES_PAGEDESC );
2512 :
2513 3051 : if( SfxItemState::SET == pTmpSet->GetItemState( RES_BREAK, false ) )
2514 : {
2515 532 : if ( bNext )
2516 222 : pNewAttrSet->ClearItem( RES_BREAK );
2517 : else
2518 310 : aClearWhichIds.push_back( RES_BREAK );
2519 532 : bRemoveFromCache = true;
2520 : }
2521 3051 : if( SfxItemState::SET == pTmpSet->GetItemState( RES_KEEP, false ) )
2522 : {
2523 0 : if ( bNext )
2524 0 : pNewAttrSet->ClearItem( RES_KEEP );
2525 : else
2526 0 : aClearWhichIds.push_back( RES_KEEP );
2527 0 : bRemoveFromCache = true;
2528 : }
2529 3051 : if( SfxItemState::SET == pTmpSet->GetItemState( RES_PARATR_SPLIT, false ) )
2530 : {
2531 0 : if ( bNext )
2532 0 : pNewAttrSet->ClearItem( RES_PARATR_SPLIT );
2533 : else
2534 0 : aClearWhichIds.push_back( RES_PARATR_SPLIT );
2535 0 : bRemoveFromCache = true;
2536 : }
2537 3051 : if(SfxItemState::SET == pTmpSet->GetItemState(RES_PARATR_NUMRULE, false))
2538 : {
2539 592 : SwNumRule * pRule = GetNumRule();
2540 :
2541 592 : if (pRule && IsOutline())
2542 : {
2543 15 : if ( bNext )
2544 15 : pNewAttrSet->ClearItem(RES_PARATR_NUMRULE);
2545 : else
2546 : {
2547 : // #i75353#
2548 : // No clear of hard set numbering rule at an outline paragraph at this point.
2549 : // Only if the paragraph style changes - see below.
2550 0 : bClearHardSetNumRuleWhenFormatCollChanges = true;
2551 : }
2552 15 : bRemoveFromCache = true;
2553 : }
2554 : }
2555 :
2556 3051 : if ( !aClearWhichIds.empty() )
2557 1131 : bRemoveFromCache = 0 != ClearItemsFromAttrSet( aClearWhichIds );
2558 :
2559 3051 : if( !bNext && bRemoveFromCache && IsInCache() )
2560 : {
2561 12 : SwFrm::GetCache().Delete( this );
2562 12 : SetInCache( false );
2563 3051 : }
2564 : }
2565 37514 : SwNodes& rNds = GetNodes();
2566 :
2567 37514 : SwTextFormatColl* pColl = GetTextColl();
2568 :
2569 37514 : SwTextNode *pNode = new SwTextNode( rPos, pColl, pNewAttrSet );
2570 :
2571 37514 : delete pNewAttrSet;
2572 :
2573 37514 : const SwNumRule* pRule = GetNumRule();
2574 37514 : if( pRule && pRule == pNode->GetNumRule() && rNds.IsDocNodes() ) // #115901#
2575 : {
2576 : // #i55459#
2577 : // - correction: parameter <bNext> has to be checked, as it was in the
2578 : // previous implementation.
2579 747 : if ( !bNext && !IsCountedInList() )
2580 0 : SetCountedInList(true);
2581 : }
2582 :
2583 : // jetzt kann es sein, das durch die Nummerierung dem neuen Node eine
2584 : // Vorlage aus dem Pool zugewiesen wurde. Dann darf diese nicht
2585 : // nochmal uebergeplaettet werden !!
2586 37514 : if( pColl != pNode->GetTextColl() ||
2587 37461 : ( bChgFollow && pColl != GetTextColl() ))
2588 0 : return pNode; // mehr duerfte nicht gemacht werden oder ????
2589 :
2590 37514 : pNode->_ChgTextCollUpdateNum( 0, pColl ); // fuer Nummerierung/Gliederung
2591 37514 : if( bNext || !bChgFollow )
2592 36191 : return pNode;
2593 :
2594 1323 : SwTextFormatColl *pNextColl = &pColl->GetNextTextFormatColl();
2595 : // #i101870#
2596 : // perform action on different paragraph styles before applying the new paragraph style
2597 1323 : if (pNextColl != pColl)
2598 : {
2599 : // #i75353#
2600 1 : if ( bClearHardSetNumRuleWhenFormatCollChanges )
2601 : {
2602 0 : std::vector<sal_uInt16> aClearWhichIds;
2603 0 : aClearWhichIds.push_back( RES_PARATR_NUMRULE );
2604 0 : if ( ClearItemsFromAttrSet( aClearWhichIds ) != 0 && IsInCache() )
2605 : {
2606 0 : SwFrm::GetCache().Delete( this );
2607 0 : SetInCache( false );
2608 0 : }
2609 : }
2610 : }
2611 1323 : ChgFormatColl( pNextColl );
2612 :
2613 1323 : return pNode;
2614 : }
2615 :
2616 36138 : SwContentNode* SwTextNode::AppendNode( const SwPosition & rPos )
2617 : {
2618 : // Position hinter dem eingefuegt wird
2619 36138 : SwNodeIndex aIdx( rPos.nNode, 1 );
2620 36138 : SwTextNode* pNew = _MakeNewTextNode( aIdx, true );
2621 :
2622 : // reset list attributes at appended text node
2623 36138 : pNew->ResetAttr( RES_PARATR_LIST_ISRESTART );
2624 36138 : pNew->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
2625 36138 : pNew->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
2626 36138 : if ( pNew->GetNumRule() == 0 )
2627 : {
2628 35400 : pNew->ResetAttr( RES_PARATR_LIST_ID );
2629 35400 : pNew->ResetAttr( RES_PARATR_LIST_LEVEL );
2630 : }
2631 :
2632 36138 : if (!IsInList() && GetNumRule() && !GetListId().isEmpty())
2633 : {
2634 0 : AddToList();
2635 : }
2636 :
2637 36138 : if( HasWriterListeners() )
2638 1765 : MakeFrms( *pNew );
2639 36138 : return pNew;
2640 : }
2641 :
2642 250160 : SwTextAttr * SwTextNode::GetTextAttrForCharAt(
2643 : const sal_Int32 nIndex,
2644 : const RES_TXTATR nWhich ) const
2645 : {
2646 250160 : if ( HasHints() )
2647 : {
2648 161686 : for ( size_t i = 0; i < m_pSwpHints->Count(); ++i )
2649 : {
2650 133080 : SwTextAttr * const pHint = m_pSwpHints->GetTextHint(i);
2651 133080 : const sal_Int32 nStartPos = pHint->GetStart();
2652 133080 : if ( nIndex < nStartPos )
2653 : {
2654 20757 : return 0;
2655 : }
2656 112323 : if ( (nIndex == nStartPos) && pHint->HasDummyChar() )
2657 : {
2658 16546 : return ( RES_TXTATR_END == nWhich || nWhich == pHint->Which() )
2659 52248 : ? pHint : 0;
2660 : }
2661 : }
2662 : }
2663 197016 : return 0;
2664 : }
2665 :
2666 : namespace
2667 : {
2668 :
2669 121656 : inline sal_uInt16 lcl_BoundListLevel(const int nActualLevel)
2670 : {
2671 121656 : return static_cast<sal_uInt16>( std::min( std::max(nActualLevel, 0), MAXLEVEL-1 ) );
2672 : }
2673 :
2674 : }
2675 :
2676 : // -> #i29560#
2677 5207 : bool SwTextNode::HasNumber() const
2678 : {
2679 5207 : bool bResult = false;
2680 :
2681 5207 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
2682 5207 : if ( pRule )
2683 : {
2684 3996 : SwNumFormat aFormat(pRule->Get(lcl_BoundListLevel(GetActualListLevel())));
2685 :
2686 : // #i40041#
2687 7718 : bResult = aFormat.IsEnumeration() &&
2688 7718 : SVX_NUM_NUMBER_NONE != aFormat.GetNumberingType();
2689 : }
2690 :
2691 5207 : return bResult;
2692 : }
2693 :
2694 11462342 : bool SwTextNode::HasBullet() const
2695 : {
2696 11462342 : bool bResult = false;
2697 :
2698 11462342 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
2699 11462342 : if ( pRule )
2700 : {
2701 934 : SwNumFormat aFormat(pRule->Get(lcl_BoundListLevel(GetActualListLevel())));
2702 :
2703 934 : bResult = aFormat.IsItemize();
2704 : }
2705 :
2706 11462342 : return bResult;
2707 : }
2708 : // <- #i29560#
2709 :
2710 : // #128041# - introduce parameter <_bInclPrefixAndSuffixStrings>
2711 : //i53420 added max outline parameter
2712 11466434 : OUString SwTextNode::GetNumString( const bool _bInclPrefixAndSuffixStrings,
2713 : const unsigned int _nRestrictToThisLevel ) const
2714 : {
2715 11466434 : if (GetDoc()->IsClipBoard() && m_pNumStringCache.get())
2716 : {
2717 : // #i111677# do not expand number strings in clipboard documents
2718 0 : return *m_pNumStringCache;
2719 : }
2720 11466434 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
2721 11472643 : if ( pRule &&
2722 6209 : IsCountedInList() )
2723 : {
2724 : SvxNumberType const& rNumberType(
2725 6209 : pRule->Get( lcl_BoundListLevel(GetActualListLevel()) ) );
2726 6943 : if (rNumberType.IsTextFormat() ||
2727 :
2728 734 : (style::NumberingType::NUMBER_NONE == rNumberType.GetNumberingType()))
2729 : {
2730 5923 : return pRule->MakeNumString( GetNum()->GetNumberVector(),
2731 : _bInclPrefixAndSuffixStrings,
2732 : false,
2733 11846 : _nRestrictToThisLevel );
2734 : }
2735 : }
2736 :
2737 11460511 : return OUString();
2738 : }
2739 :
2740 637942 : long SwTextNode::GetLeftMarginWithNum( bool bTextLeft ) const
2741 : {
2742 637942 : long nRet = 0;
2743 637942 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
2744 637942 : if( pRule )
2745 : {
2746 57861 : const SwNumFormat& rFormat = pRule->Get(lcl_BoundListLevel(GetActualListLevel()));
2747 :
2748 57861 : if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2749 : {
2750 5298 : nRet = rFormat.GetAbsLSpace();
2751 :
2752 5298 : if( !bTextLeft )
2753 : {
2754 7740 : if( 0 > rFormat.GetFirstLineOffset() &&
2755 3869 : nRet > -rFormat.GetFirstLineOffset() )
2756 2270 : nRet = nRet + rFormat.GetFirstLineOffset();
2757 : else
2758 1601 : nRet = 0;
2759 : }
2760 :
2761 5298 : if( pRule->IsAbsSpaces() )
2762 0 : nRet = nRet - GetSwAttrSet().GetLRSpace().GetLeft();
2763 : }
2764 52563 : else if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2765 : {
2766 52563 : if ( AreListLevelIndentsApplicable() )
2767 : {
2768 32576 : nRet = rFormat.GetIndentAt();
2769 : // #i90401#
2770 : // Only negative first line indents have consider for the left margin
2771 56410 : if ( !bTextLeft &&
2772 23834 : rFormat.GetFirstLineIndent() < 0 )
2773 : {
2774 23271 : nRet = nRet + rFormat.GetFirstLineIndent();
2775 : }
2776 : }
2777 : }
2778 : }
2779 :
2780 637942 : return nRet;
2781 : }
2782 :
2783 187912 : bool SwTextNode::GetFirstLineOfsWithNum( short& rFLOffset ) const
2784 : {
2785 : // #i95907#
2786 187912 : rFLOffset = 0;
2787 :
2788 : // #i51089#
2789 187912 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
2790 187912 : if ( pRule )
2791 : {
2792 14618 : if ( IsCountedInList() )
2793 : {
2794 14484 : const SwNumFormat& rFormat = pRule->Get(lcl_BoundListLevel(GetActualListLevel()));
2795 14484 : if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2796 : {
2797 1375 : rFLOffset = rFormat.GetFirstLineOffset();
2798 :
2799 1375 : if (!getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
2800 : {
2801 1366 : SvxLRSpaceItem aItem = GetSwAttrSet().GetLRSpace();
2802 1366 : rFLOffset = rFLOffset + aItem.GetTextFirstLineOfst();
2803 : }
2804 : }
2805 13109 : else if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2806 : {
2807 13109 : if ( AreListLevelIndentsApplicable() )
2808 : {
2809 8687 : rFLOffset = rFormat.GetFirstLineIndent();
2810 : }
2811 4422 : else if (!getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
2812 : {
2813 4422 : SvxLRSpaceItem aItem = GetSwAttrSet().GetLRSpace();
2814 4422 : rFLOffset = aItem.GetTextFirstLineOfst();
2815 : }
2816 : }
2817 : }
2818 :
2819 14618 : return true;
2820 : }
2821 :
2822 173294 : rFLOffset = GetSwAttrSet().GetLRSpace().GetTextFirstLineOfst();
2823 173294 : return false;
2824 : }
2825 :
2826 0 : SwTwips SwTextNode::GetAdditionalIndentForStartingNewList() const
2827 : {
2828 0 : SwTwips nAdditionalIndent = 0;
2829 :
2830 0 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
2831 0 : if ( pRule )
2832 : {
2833 0 : const SwNumFormat& rFormat = pRule->Get(lcl_BoundListLevel(GetActualListLevel()));
2834 0 : if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2835 : {
2836 0 : nAdditionalIndent = GetSwAttrSet().GetLRSpace().GetLeft();
2837 :
2838 0 : if (getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
2839 : {
2840 0 : nAdditionalIndent = nAdditionalIndent -
2841 0 : GetSwAttrSet().GetLRSpace().GetTextFirstLineOfst();
2842 : }
2843 : }
2844 0 : else if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2845 : {
2846 0 : if ( AreListLevelIndentsApplicable() )
2847 : {
2848 0 : nAdditionalIndent = rFormat.GetIndentAt() + rFormat.GetFirstLineIndent();
2849 : }
2850 : else
2851 : {
2852 0 : nAdditionalIndent = GetSwAttrSet().GetLRSpace().GetLeft();
2853 0 : if (getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
2854 : {
2855 0 : nAdditionalIndent = nAdditionalIndent -
2856 0 : GetSwAttrSet().GetLRSpace().GetTextFirstLineOfst();
2857 : }
2858 : }
2859 : }
2860 : }
2861 : else
2862 : {
2863 0 : nAdditionalIndent = GetSwAttrSet().GetLRSpace().GetLeft();
2864 : }
2865 :
2866 0 : return nAdditionalIndent;
2867 : }
2868 :
2869 : // #i96772#
2870 36498 : void SwTextNode::ClearLRSpaceItemDueToListLevelIndents( SvxLRSpaceItem& o_rLRSpaceItem ) const
2871 : {
2872 36498 : if ( AreListLevelIndentsApplicable() )
2873 : {
2874 1836 : const SwNumRule* pRule = GetNumRule();
2875 1836 : if ( pRule && GetActualListLevel() >= 0 )
2876 : {
2877 1836 : const SwNumFormat& rFormat = pRule->Get(lcl_BoundListLevel(GetActualListLevel()));
2878 1836 : if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2879 : {
2880 1747 : SvxLRSpaceItem aLR( RES_LR_SPACE );
2881 1747 : o_rLRSpaceItem = aLR;
2882 : }
2883 : }
2884 : }
2885 36498 : }
2886 :
2887 : // #i91133#
2888 184321 : long SwTextNode::GetLeftMarginForTabCalculation() const
2889 : {
2890 184321 : long nLeftMarginForTabCalc = 0;
2891 :
2892 184321 : bool bLeftMarginForTabCalcSetToListLevelIndent( false );
2893 184321 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0;
2894 184321 : if( pRule )
2895 : {
2896 14673 : const SwNumFormat& rFormat = pRule->Get(lcl_BoundListLevel(GetActualListLevel()));
2897 14673 : if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2898 : {
2899 13246 : if ( AreListLevelIndentsApplicable() )
2900 : {
2901 8742 : nLeftMarginForTabCalc = rFormat.GetIndentAt();
2902 8742 : bLeftMarginForTabCalcSetToListLevelIndent = true;
2903 : }
2904 : }
2905 : }
2906 184321 : if ( !bLeftMarginForTabCalcSetToListLevelIndent )
2907 : {
2908 175579 : nLeftMarginForTabCalc = GetSwAttrSet().GetLRSpace().GetTextLeft();
2909 : }
2910 :
2911 184321 : return nLeftMarginForTabCalc;
2912 : }
2913 :
2914 0 : static void Replace0xFF(
2915 : SwTextNode const& rNode,
2916 : OUStringBuffer & rText,
2917 : sal_Int32 & rTextStt,
2918 : sal_Int32 nEndPos,
2919 : bool const bExpandFields,
2920 : bool const bExpandFootnote = true )
2921 : {
2922 0 : if (rNode.GetpSwpHints())
2923 : {
2924 0 : sal_Unicode cSrchChr = CH_TXTATR_BREAKWORD;
2925 0 : for( int nSrchIter = 0; 2 > nSrchIter; ++nSrchIter, cSrchChr = CH_TXTATR_INWORD )
2926 : {
2927 0 : sal_Int32 nPos = rText.indexOf(cSrchChr);
2928 0 : while (-1 != nPos && nPos < nEndPos)
2929 : {
2930 : const SwTextAttr* const pAttr =
2931 0 : rNode.GetTextAttrForCharAt(rTextStt + nPos);
2932 0 : if( pAttr )
2933 : {
2934 0 : switch( pAttr->Which() )
2935 : {
2936 : case RES_TXTATR_FIELD:
2937 : case RES_TXTATR_ANNOTATION:
2938 0 : rText.remove(nPos, 1);
2939 0 : if( bExpandFields )
2940 : {
2941 : const OUString aExpand(
2942 0 : static_txtattr_cast<SwTextField const*>(pAttr)->GetFormatField().GetField()->ExpandField(true));
2943 0 : rText.insert(nPos, aExpand);
2944 0 : nPos = nPos + aExpand.getLength();
2945 0 : nEndPos = nEndPos + aExpand.getLength();
2946 0 : rTextStt = rTextStt - aExpand.getLength();
2947 : }
2948 0 : ++rTextStt;
2949 0 : break;
2950 :
2951 : case RES_TXTATR_FTN:
2952 0 : rText.remove(nPos, 1);
2953 0 : if( bExpandFields && bExpandFootnote )
2954 : {
2955 0 : const SwFormatFootnote& rFootnote = pAttr->GetFootnote();
2956 0 : OUString sExpand;
2957 0 : if( !rFootnote.GetNumStr().isEmpty() )
2958 0 : sExpand = rFootnote.GetNumStr();
2959 0 : else if( rFootnote.IsEndNote() )
2960 0 : sExpand = rNode.GetDoc()->GetEndNoteInfo().aFormat.
2961 0 : GetNumStr( rFootnote.GetNumber() );
2962 : else
2963 0 : sExpand = rNode.GetDoc()->GetFootnoteInfo().aFormat.
2964 0 : GetNumStr( rFootnote.GetNumber() );
2965 0 : rText.insert(nPos, sExpand);
2966 0 : nPos = nPos + sExpand.getLength();
2967 0 : nEndPos = nEndPos + sExpand.getLength();
2968 0 : rTextStt = rTextStt - sExpand.getLength();
2969 : }
2970 0 : ++rTextStt;
2971 0 : break;
2972 :
2973 : default:
2974 0 : rText.remove(nPos, 1);
2975 0 : ++rTextStt;
2976 : }
2977 : }
2978 : else
2979 0 : ++nPos, ++nEndPos;
2980 0 : nPos = rText.indexOf(cSrchChr, nPos);
2981 : }
2982 : }
2983 : }
2984 0 : }
2985 :
2986 : // Expand fields
2987 : // #i83479# - handling of new parameters
2988 3683 : OUString SwTextNode::GetExpandText( const sal_Int32 nIdx,
2989 : const sal_Int32 nLen,
2990 : const bool bWithNum,
2991 : const bool bAddSpaceAfterListLabelStr,
2992 : const bool bWithSpacesForLevel,
2993 : const bool bWithFootnote ) const
2994 :
2995 : {
2996 3683 : ExpandMode eMode = ExpandMode::ExpandFields;
2997 3683 : if (bWithFootnote)
2998 3683 : eMode |= ExpandMode::ExpandFootnote;
2999 :
3000 3683 : ModelToViewHelper aConversionMap(*this, eMode);
3001 7366 : OUString aExpandText = aConversionMap.getViewText();
3002 3683 : const sal_Int32 nExpandBegin = aConversionMap.ConvertToViewPosition( nIdx );
3003 3683 : sal_Int32 nEnd = nLen == -1 ? GetText().getLength() : nIdx + nLen;
3004 3683 : const sal_Int32 nExpandEnd = aConversionMap.ConvertToViewPosition( nEnd );
3005 7366 : OUStringBuffer aText(aExpandText.copy(nExpandBegin, nExpandEnd-nExpandBegin));
3006 :
3007 : // remove dummy characters of Input Fields
3008 3683 : comphelper::string::remove(aText, CH_TXT_ATR_INPUTFIELDSTART);
3009 3683 : comphelper::string::remove(aText, CH_TXT_ATR_INPUTFIELDEND);
3010 :
3011 3683 : if( bWithNum )
3012 : {
3013 0 : if ( !GetNumString().isEmpty() )
3014 : {
3015 0 : if ( bAddSpaceAfterListLabelStr )
3016 : {
3017 0 : const sal_Unicode aSpace = ' ';
3018 0 : aText.insert(0, aSpace);
3019 : }
3020 0 : aText.insert(0, GetNumString());
3021 : }
3022 : }
3023 :
3024 3683 : if (bWithSpacesForLevel)
3025 : {
3026 0 : const sal_Unicode aSpace = ' ';
3027 0 : for (int nLevel = GetActualListLevel(); nLevel > 0; --nLevel)
3028 : {
3029 0 : aText.insert(0, aSpace);
3030 0 : aText.insert(0, aSpace);
3031 : }
3032 : }
3033 :
3034 7366 : return aText.makeStringAndClear();
3035 : }
3036 :
3037 0 : bool SwTextNode::GetExpandText( SwTextNode& rDestNd, const SwIndex* pDestIdx,
3038 : sal_Int32 nIdx, sal_Int32 nLen, bool bWithNum,
3039 : bool bWithFootnote, bool bReplaceTabsWithSpaces ) const
3040 : {
3041 0 : if( &rDestNd == this )
3042 0 : return false;
3043 :
3044 0 : SwIndex aDestIdx(&rDestNd, rDestNd.GetText().getLength());
3045 0 : if( pDestIdx )
3046 0 : aDestIdx = *pDestIdx;
3047 0 : const sal_Int32 nDestStt = aDestIdx.GetIndex();
3048 :
3049 : // Text einfuegen
3050 0 : OUStringBuffer buf(GetText());
3051 0 : if( bReplaceTabsWithSpaces )
3052 0 : buf.replace('\t', ' ');
3053 :
3054 : // mask hidden characters
3055 0 : const sal_Unicode cChar = CH_TXTATR_BREAKWORD;
3056 0 : SwScriptInfo::MaskHiddenRanges(*this, buf, 0, buf.getLength(), cChar);
3057 :
3058 0 : buf.remove(0, nIdx);
3059 0 : if (nLen != -1)
3060 : {
3061 0 : buf.truncate(nLen);
3062 : }
3063 : // remove dummy characters of Input Fields
3064 : {
3065 0 : comphelper::string::remove(buf, CH_TXT_ATR_INPUTFIELDSTART);
3066 0 : comphelper::string::remove(buf, CH_TXT_ATR_INPUTFIELDEND);
3067 : }
3068 0 : rDestNd.InsertText(buf.makeStringAndClear(), aDestIdx);
3069 0 : nLen = aDestIdx.GetIndex() - nDestStt;
3070 :
3071 : // alle FontAttribute mit CHARSET Symbol in dem Bereich setzen
3072 0 : if ( HasHints() )
3073 : {
3074 0 : sal_Int32 nInsPos = nDestStt - nIdx;
3075 0 : for ( size_t i = 0; i < m_pSwpHints->Count(); ++i )
3076 : {
3077 0 : const SwTextAttr* pHt = (*m_pSwpHints)[i];
3078 0 : const sal_Int32 nAttrStartIdx = pHt->GetStart();
3079 0 : const sal_uInt16 nWhich = pHt->Which();
3080 0 : if (nIdx + nLen <= nAttrStartIdx)
3081 0 : break; // ueber das Textende
3082 :
3083 0 : const sal_Int32 *pEndIdx = pHt->End();
3084 0 : if( pEndIdx && *pEndIdx > nIdx &&
3085 0 : ( RES_CHRATR_FONT == nWhich ||
3086 0 : RES_TXTATR_CHARFMT == nWhich ||
3087 : RES_TXTATR_AUTOFMT == nWhich ))
3088 : {
3089 : const SvxFontItem* const pFont =
3090 : static_cast<const SvxFontItem*>(
3091 0 : CharFormat::GetItem( *pHt, RES_CHRATR_FONT ));
3092 0 : if ( pFont && RTL_TEXTENCODING_SYMBOL == pFont->GetCharSet() )
3093 : {
3094 : // attribute in area => copy
3095 : rDestNd.InsertItem( *const_cast<SvxFontItem*>(pFont),
3096 0 : nInsPos + nAttrStartIdx, nInsPos + *pEndIdx );
3097 0 : }
3098 : }
3099 0 : else if ( pHt->HasDummyChar() && (nAttrStartIdx >= nIdx) )
3100 : {
3101 0 : aDestIdx = nInsPos + nAttrStartIdx;
3102 0 : switch( nWhich )
3103 : {
3104 : case RES_TXTATR_FIELD:
3105 : case RES_TXTATR_ANNOTATION:
3106 : {
3107 : OUString const aExpand(
3108 0 : static_txtattr_cast<SwTextField const*>(pHt)->GetFormatField().GetField()->ExpandField(true));
3109 0 : if (!aExpand.isEmpty())
3110 : {
3111 0 : ++aDestIdx; // dahinter einfuegen;
3112 : OUString const ins(
3113 0 : rDestNd.InsertText( aExpand, aDestIdx));
3114 : SAL_INFO_IF(ins.getLength() != aExpand.getLength(),
3115 : "sw.core", "GetExpandText lossage");
3116 0 : aDestIdx = nInsPos + nAttrStartIdx;
3117 0 : nInsPos += ins.getLength();
3118 : }
3119 0 : rDestNd.EraseText( aDestIdx, 1 );
3120 0 : --nInsPos;
3121 : }
3122 0 : break;
3123 :
3124 : case RES_TXTATR_FTN:
3125 : {
3126 0 : if ( bWithFootnote )
3127 : {
3128 0 : const SwFormatFootnote& rFootnote = pHt->GetFootnote();
3129 0 : OUString sExpand;
3130 0 : if( !rFootnote.GetNumStr().isEmpty() )
3131 0 : sExpand = rFootnote.GetNumStr();
3132 0 : else if( rFootnote.IsEndNote() )
3133 0 : sExpand = GetDoc()->GetEndNoteInfo().aFormat.
3134 0 : GetNumStr( rFootnote.GetNumber() );
3135 : else
3136 0 : sExpand = GetDoc()->GetFootnoteInfo().aFormat.
3137 0 : GetNumStr( rFootnote.GetNumber() );
3138 0 : if( !sExpand.isEmpty() )
3139 : {
3140 0 : ++aDestIdx; // insert behind
3141 : SvxEscapementItem aItem(
3142 0 : SVX_ESCAPEMENT_SUPERSCRIPT );
3143 : rDestNd.InsertItem(
3144 : aItem,
3145 : aDestIdx.GetIndex(),
3146 0 : aDestIdx.GetIndex() );
3147 0 : OUString const ins( rDestNd.InsertText(sExpand, aDestIdx, SwInsertFlags::EMPTYEXPAND));
3148 : SAL_INFO_IF(ins.getLength() != sExpand.getLength(),
3149 : "sw.core", "GetExpandText lossage");
3150 0 : aDestIdx = nInsPos + nAttrStartIdx;
3151 0 : nInsPos += ins.getLength();
3152 0 : }
3153 : }
3154 0 : rDestNd.EraseText( aDestIdx, 1 );
3155 0 : --nInsPos;
3156 : }
3157 0 : break;
3158 :
3159 : default:
3160 0 : rDestNd.EraseText( aDestIdx, 1 );
3161 0 : --nInsPos;
3162 : }
3163 : }
3164 : }
3165 : }
3166 :
3167 0 : if( bWithNum )
3168 : {
3169 0 : aDestIdx = nDestStt;
3170 0 : rDestNd.InsertText( GetNumString(), aDestIdx );
3171 : }
3172 :
3173 0 : aDestIdx = 0;
3174 0 : sal_Int32 nStartDelete(-1);
3175 0 : while (aDestIdx < rDestNd.GetText().getLength())
3176 : {
3177 0 : sal_Unicode const cur(rDestNd.GetText()[aDestIdx.GetIndex()]);
3178 0 : if ( (cChar == cur) // filter substituted hidden text
3179 0 : || (CH_TXT_ATR_FIELDSTART == cur) // filter all fieldmarks
3180 0 : || (CH_TXT_ATR_FIELDEND == cur)
3181 0 : || (CH_TXT_ATR_FORMELEMENT == cur))
3182 : {
3183 0 : if (-1 == nStartDelete)
3184 : {
3185 0 : nStartDelete = aDestIdx.GetIndex(); // start deletion range
3186 : }
3187 0 : ++aDestIdx;
3188 0 : if (aDestIdx < rDestNd.GetText().getLength())
3189 : {
3190 0 : continue;
3191 : } // else: end of paragraph => delete, see below
3192 : }
3193 : else
3194 : {
3195 0 : if (-1 == nStartDelete)
3196 : {
3197 0 : ++aDestIdx;
3198 0 : continue;
3199 : } // else: delete, see below
3200 : }
3201 : assert(-1 != nStartDelete); // without delete range, would have continued
3202 : rDestNd.EraseText(
3203 : SwIndex(&rDestNd, nStartDelete),
3204 0 : aDestIdx.GetIndex() - nStartDelete);
3205 : assert(aDestIdx.GetIndex() == nStartDelete);
3206 0 : nStartDelete = -1; // reset
3207 : }
3208 :
3209 0 : return true;
3210 : }
3211 :
3212 0 : OUString SwTextNode::GetRedlineText( sal_Int32 nIdx, sal_Int32 nLen,
3213 : bool bExpandFields, bool bWithNum ) const
3214 : {
3215 0 : std::vector<sal_Int32> aRedlArr;
3216 0 : const SwDoc* pDoc = GetDoc();
3217 0 : sal_uInt16 nRedlPos = pDoc->getIDocumentRedlineAccess().GetRedlinePos( *this, nsRedlineType_t::REDLINE_DELETE );
3218 0 : if( USHRT_MAX != nRedlPos )
3219 : {
3220 : // es existiert fuer den Node irgendein Redline-Delete-Object
3221 0 : const sal_uLong nNdIdx = GetIndex();
3222 0 : for( ; nRedlPos < pDoc->getIDocumentRedlineAccess().GetRedlineTable().size() ; ++nRedlPos )
3223 : {
3224 0 : const SwRangeRedline* pTmp = pDoc->getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
3225 0 : if( nsRedlineType_t::REDLINE_DELETE == pTmp->GetType() )
3226 : {
3227 0 : const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
3228 0 : if( pRStt->nNode < nNdIdx )
3229 : {
3230 0 : if( pREnd->nNode > nNdIdx )
3231 : // Absatz ist komplett geloescht
3232 0 : return OUString();
3233 0 : else if( pREnd->nNode == nNdIdx )
3234 : {
3235 : // von 0 bis nContent ist alles geloescht
3236 0 : aRedlArr.push_back( 0 );
3237 0 : aRedlArr.push_back( pREnd->nContent.GetIndex() );
3238 : }
3239 : }
3240 0 : else if( pRStt->nNode == nNdIdx )
3241 : {
3242 : //aRedlArr.Insert( pRStt->nContent.GetIndex(), aRedlArr.Count() );
3243 0 : aRedlArr.push_back( pRStt->nContent.GetIndex() );
3244 0 : if( pREnd->nNode == nNdIdx )
3245 0 : aRedlArr.push_back( pREnd->nContent.GetIndex() );
3246 : else
3247 : {
3248 0 : aRedlArr.push_back(GetText().getLength());
3249 0 : break; // mehr kann nicht kommen
3250 : }
3251 : }
3252 : else
3253 0 : break; // mehr kann nicht kommen
3254 : }
3255 : }
3256 : }
3257 :
3258 0 : OUStringBuffer aText((nLen > GetText().getLength())
3259 0 : ? GetText().copy(nIdx)
3260 0 : : GetText().copy(nIdx, nLen));
3261 :
3262 0 : sal_Int32 nTextStt = nIdx;
3263 0 : sal_Int32 nIdxEnd = nIdx + aText.getLength();
3264 0 : for( size_t n = 0; n < aRedlArr.size(); n += 2 )
3265 : {
3266 0 : sal_Int32 nStt = aRedlArr[ n ];
3267 0 : sal_Int32 nEnd = aRedlArr[ n+1 ];
3268 0 : if( ( nIdx <= nStt && nStt <= nIdxEnd ) ||
3269 0 : ( nIdx <= nEnd && nEnd <= nIdxEnd ))
3270 : {
3271 0 : if( nStt < nIdx ) nStt = nIdx;
3272 0 : if( nIdxEnd < nEnd ) nEnd = nIdxEnd;
3273 0 : const sal_Int32 nDelCnt = nEnd - nStt;
3274 0 : aText.remove(nStt - nTextStt, nDelCnt);
3275 0 : Replace0xFF(*this, aText, nTextStt, nStt - nTextStt, bExpandFields);
3276 0 : nTextStt += nDelCnt;
3277 : }
3278 0 : else if( nStt >= nIdxEnd )
3279 0 : break;
3280 : }
3281 0 : Replace0xFF(*this, aText, nTextStt, aText.getLength(), bExpandFields);
3282 :
3283 0 : if( bWithNum )
3284 0 : aText.insert(0, GetNumString());
3285 0 : return aText.makeStringAndClear();
3286 : }
3287 :
3288 12 : void SwTextNode::ReplaceText( const SwIndex& rStart, const sal_Int32 nDelLen,
3289 : const OUString & rStr)
3290 : {
3291 : assert( rStart.GetIndex() < m_Text.getLength() // index out of bounds
3292 : && rStart.GetIndex() + nDelLen <= m_Text.getLength());
3293 :
3294 12 : sal_Int32 const nOverflow(rStr.getLength() - nDelLen - GetSpaceLeft());
3295 : SAL_WARN_IF(nOverflow > 0, "sw.core",
3296 : "SwTextNode::ReplaceText: node text with insertion > node capacity.");
3297 : OUString const sInserted(
3298 12 : (nOverflow > 0) ? rStr.copy(0, rStr.getLength() - nOverflow) : rStr);
3299 12 : if (sInserted.isEmpty() && 0 == nDelLen)
3300 : {
3301 13 : return; // nothing to do
3302 : }
3303 :
3304 11 : const sal_Int32 nStartPos = rStart.GetIndex();
3305 11 : sal_Int32 nEndPos = nStartPos + nDelLen;
3306 11 : sal_Int32 nLen = nDelLen;
3307 117 : for( sal_Int32 nPos = nStartPos; nPos < nEndPos; ++nPos )
3308 : {
3309 212 : if ((CH_TXTATR_BREAKWORD == m_Text[nPos]) ||
3310 106 : (CH_TXTATR_INWORD == m_Text[nPos]))
3311 : {
3312 0 : SwTextAttr *const pHint = GetTextAttrForCharAt( nPos );
3313 0 : if (pHint)
3314 : {
3315 : assert(!( pHint->GetEnd() && pHint->HasDummyChar()
3316 : && (pHint->GetStart() < nEndPos)
3317 : && (*pHint->GetEnd() > nEndPos) ));
3318 : // "deleting left-overlapped attribute with CH_TXTATR"
3319 0 : DeleteAttribute( pHint );
3320 0 : --nEndPos;
3321 0 : --nLen;
3322 : }
3323 : }
3324 : }
3325 :
3326 11 : bool bOldExpFlg = IsIgnoreDontExpand();
3327 11 : SetIgnoreDontExpand( true );
3328 :
3329 11 : if (nLen && sInserted.getLength())
3330 : {
3331 : // dann das 1. Zeichen ersetzen den Rest loschen und einfuegen
3332 : // Dadurch wird die Attributierung des 1. Zeichen expandiert!
3333 9 : m_Text = m_Text.replaceAt(nStartPos, 1, sInserted.copy(0, 1));
3334 :
3335 9 : ++const_cast<SwIndex&>(rStart);
3336 9 : m_Text = m_Text.replaceAt(rStart.GetIndex(), nLen - 1, "");
3337 9 : Update( rStart, nLen - 1, true );
3338 :
3339 9 : OUString aTmpText( sInserted.copy(1) );
3340 9 : m_Text = m_Text.replaceAt(rStart.GetIndex(), 0, aTmpText);
3341 9 : Update( rStart, aTmpText.getLength(), false );
3342 : }
3343 : else
3344 : {
3345 2 : m_Text = m_Text.replaceAt(nStartPos, nLen, "");
3346 2 : Update( rStart, nLen, true );
3347 :
3348 2 : m_Text = m_Text.replaceAt(nStartPos, 0, sInserted);
3349 2 : Update( rStart, sInserted.getLength(), false );
3350 : }
3351 :
3352 11 : SetIgnoreDontExpand( bOldExpFlg );
3353 22 : SwDelText aDelHint( nStartPos, nDelLen );
3354 11 : NotifyClients( 0, &aDelHint );
3355 :
3356 22 : SwInsText aHint( nStartPos, sInserted.getLength() );
3357 22 : NotifyClients( 0, &aHint );
3358 : }
3359 :
3360 : namespace {
3361 150 : static void lcl_ResetParAttrs( SwTextNode &rTextNode )
3362 : {
3363 150 : std::set<sal_uInt16> aAttrs;
3364 150 : aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_ID );
3365 150 : aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_LEVEL );
3366 150 : aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_ISRESTART );
3367 150 : aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_RESTARTVALUE );
3368 150 : aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_ISCOUNTED );
3369 300 : SwPaM aPam( rTextNode );
3370 : // #i96644#
3371 : // suppress side effect "send data changed events"
3372 300 : rTextNode.GetDoc()->ResetAttrs( aPam, false, aAttrs, false );
3373 150 : }
3374 :
3375 : // Helper method for special handling of modified attributes at text node.
3376 : // The following is handled:
3377 : // (1) on changing the paragraph style - RES_FMT_CHG:
3378 : // Check, if list style of the text node is changed. If yes, add respectively
3379 : // remove the text node to the corresponding list.
3380 : // (2) on changing the attributes - RES_ATTRSET_CHG:
3381 : // Same as (1).
3382 : // (3) on changing the list style - RES_PARATR_NUMRULE:
3383 : // Same as (1).
3384 329773 : void HandleModifyAtTextNode( SwTextNode& rTextNode,
3385 : const SfxPoolItem* pOldValue,
3386 : const SfxPoolItem* pNewValue )
3387 : {
3388 : const sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
3389 329773 : pNewValue ? pNewValue->Which() : 0 ;
3390 329773 : bool bNumRuleSet = false;
3391 329773 : bool bParagraphStyleChanged = false;
3392 329773 : OUString sNumRule;
3393 659546 : OUString sOldNumRule;
3394 329773 : switch ( nWhich )
3395 : {
3396 : case RES_FMT_CHG:
3397 : {
3398 23281 : bParagraphStyleChanged = true;
3399 23281 : if( rTextNode.GetNodes().IsDocNodes() )
3400 : {
3401 : const SwNumRule* pFormerNumRuleAtTextNode =
3402 18486 : rTextNode.GetNum() ? rTextNode.GetNum()->GetNumRule() : 0;
3403 18486 : if ( pFormerNumRuleAtTextNode )
3404 : {
3405 219 : sOldNumRule = pFormerNumRuleAtTextNode->GetName();
3406 : }
3407 18486 : if ( rTextNode.IsEmptyListStyleDueToSetOutlineLevelAttr() )
3408 : {
3409 0 : const SwNumRuleItem& rNumRuleItem = rTextNode.GetTextColl()->GetNumRule();
3410 0 : if ( !rNumRuleItem.GetValue().isEmpty() )
3411 : {
3412 0 : rTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
3413 : }
3414 : }
3415 18486 : const SwNumRule* pNumRuleAtTextNode = rTextNode.GetNumRule();
3416 18486 : if ( pNumRuleAtTextNode )
3417 : {
3418 263 : bNumRuleSet = true;
3419 263 : sNumRule = pNumRuleAtTextNode->GetName();
3420 : }
3421 : }
3422 23281 : break;
3423 : }
3424 : case RES_ATTRSET_CHG:
3425 : {
3426 222664 : const SfxPoolItem* pItem = 0;
3427 : const SwNumRule* pFormerNumRuleAtTextNode =
3428 222664 : rTextNode.GetNum() ? rTextNode.GetNum()->GetNumRule() : 0;
3429 222664 : if ( pFormerNumRuleAtTextNode )
3430 : {
3431 9858 : sOldNumRule = pFormerNumRuleAtTextNode->GetName();
3432 : }
3433 :
3434 222664 : const SwAttrSetChg* pSet = dynamic_cast<const SwAttrSetChg*>(pNewValue);
3435 222664 : if ( pSet && pSet->GetChgSet()->GetItemState( RES_PARATR_NUMRULE, false, &pItem ) ==
3436 : SfxItemState::SET )
3437 : {
3438 : // #i70748#
3439 167 : rTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
3440 167 : bNumRuleSet = true;
3441 : }
3442 : // #i70748#
3443 : // The new list style set at the paragraph.
3444 222664 : const SwNumRule* pNumRuleAtTextNode = rTextNode.GetNumRule();
3445 222664 : if ( pNumRuleAtTextNode )
3446 : {
3447 10007 : sNumRule = pNumRuleAtTextNode->GetName();
3448 : }
3449 222664 : break;
3450 : }
3451 : case RES_PARATR_NUMRULE:
3452 : {
3453 0 : if ( rTextNode.GetNodes().IsDocNodes() )
3454 : {
3455 : const SwNumRule* pFormerNumRuleAtTextNode =
3456 0 : rTextNode.GetNum() ? rTextNode.GetNum()->GetNumRule() : 0;
3457 0 : if ( pFormerNumRuleAtTextNode )
3458 : {
3459 0 : sOldNumRule = pFormerNumRuleAtTextNode->GetName();
3460 : }
3461 :
3462 0 : if ( pNewValue )
3463 : {
3464 : // #i70748#
3465 0 : rTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
3466 0 : bNumRuleSet = true;
3467 : }
3468 : // #i70748#
3469 : // The new list style set at the paragraph.
3470 0 : const SwNumRule* pNumRuleAtTextNode = rTextNode.GetNumRule();
3471 0 : if ( pNumRuleAtTextNode )
3472 : {
3473 0 : sNumRule = pNumRuleAtTextNode->GetName();
3474 : }
3475 : }
3476 0 : break;
3477 : }
3478 : }
3479 329773 : if ( sNumRule != sOldNumRule )
3480 : {
3481 493 : if ( bNumRuleSet )
3482 : {
3483 343 : if (sNumRule.isEmpty())
3484 : {
3485 0 : rTextNode.RemoveFromList();
3486 0 : if ( bParagraphStyleChanged )
3487 : {
3488 0 : lcl_ResetParAttrs(rTextNode);
3489 : }
3490 : }
3491 : else
3492 : {
3493 343 : rTextNode.RemoveFromList();
3494 : // If new list style is the outline style, apply outline
3495 : // level as the list level.
3496 343 : if (sNumRule==SwNumRule::GetOutlineRuleName())
3497 : {
3498 : // #i70748#
3499 : OSL_ENSURE( rTextNode.GetTextColl()->IsAssignedToListLevelOfOutlineStyle(),
3500 : "<HandleModifyAtTextNode()> - text node with outline style, but its paragraph style is not assigned to outline style." );
3501 : const int nNewListLevel =
3502 317 : rTextNode.GetTextColl()->GetAssignedOutlineStyleLevel();
3503 317 : if ( 0 <= nNewListLevel && nNewListLevel < MAXLEVEL )
3504 : {
3505 317 : rTextNode.SetAttrListLevel( nNewListLevel );
3506 : }
3507 : }
3508 343 : rTextNode.AddToList();
3509 : }
3510 : }
3511 : else // <sNumRule.Len() == 0 && sOldNumRule.Len() != 0>
3512 : {
3513 150 : rTextNode.RemoveFromList();
3514 150 : if ( bParagraphStyleChanged )
3515 : {
3516 150 : lcl_ResetParAttrs(rTextNode);
3517 : // #i70748#
3518 150 : if ( dynamic_cast<const SfxUInt16Item &>(rTextNode.GetAttr( RES_PARATR_OUTLINELEVEL, false )).GetValue() > 0 )
3519 : {
3520 0 : rTextNode.SetEmptyListStyleDueToSetOutlineLevelAttr();
3521 : }
3522 : }
3523 : }
3524 : }
3525 329280 : else if (!sNumRule.isEmpty() && !rTextNode.IsInList())
3526 : {
3527 0 : rTextNode.AddToList();
3528 329773 : }
3529 329773 : }
3530 : // End of method <HandleModifyAtTextNode>
3531 : }
3532 :
3533 372280 : void SwTextNode::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
3534 : {
3535 372280 : bool bWasNotifiable = m_bNotifiable;
3536 372280 : m_bNotifiable = false;
3537 :
3538 : // Override Modify so that deleting styles works properly (outline
3539 : // numbering!).
3540 : // Never call _ChgTextCollUpdateNum for Nodes in Undo.
3541 679396 : if( pOldValue && pNewValue && RES_FMT_CHG == pOldValue->Which() &&
3542 382205 : GetRegisteredIn() == static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat &&
3543 112 : GetNodes().IsDocNodes() )
3544 : {
3545 : _ChgTextCollUpdateNum(
3546 : static_cast<const SwTextFormatColl*>(static_cast<const SwFormatChg*>(pOldValue)->pChangedFormat),
3547 112 : static_cast<const SwTextFormatColl*>(static_cast<const SwFormatChg*>(pNewValue)->pChangedFormat) );
3548 : }
3549 :
3550 : //UUUU reset fill information
3551 372280 : if(maFillAttributes.get())
3552 : {
3553 69530 : const sal_uInt16 nWhich = pNewValue ? pNewValue->Which() : 0;
3554 69530 : bool bReset(RES_FMT_CHG == nWhich); // ..on format change (e.g. style changed)
3555 :
3556 69530 : if(!bReset && RES_ATTRSET_CHG == nWhich) // ..on ItemChange from DrawingLayer FillAttributes
3557 : {
3558 61232 : SfxItemIter aIter(*static_cast<const SwAttrSetChg*>(pNewValue)->GetChgSet());
3559 :
3560 122568 : for(const SfxPoolItem* pItem = aIter.FirstItem(); pItem && !bReset; pItem = aIter.NextItem())
3561 : {
3562 61336 : bReset = !IsInvalidItem(pItem) && pItem->Which() >= XATTR_FILL_FIRST && pItem->Which() <= XATTR_FILL_LAST;
3563 61232 : }
3564 : }
3565 :
3566 69530 : if(bReset)
3567 : {
3568 60 : maFillAttributes.reset();
3569 : }
3570 : }
3571 :
3572 372280 : if ( !mbInSetOrResetAttr )
3573 : {
3574 316305 : HandleModifyAtTextNode( *this, pOldValue, pNewValue );
3575 : }
3576 :
3577 372280 : SwContentNode::Modify( pOldValue, pNewValue );
3578 :
3579 372280 : SwDoc * pDoc = GetDoc();
3580 : // #125329# - assure that text node is in document nodes array
3581 372280 : if ( pDoc && !pDoc->IsInDtor() && &pDoc->GetNodes() == &GetNodes() )
3582 : {
3583 308226 : pDoc->GetNodes().UpdateOutlineNode(*this);
3584 : }
3585 :
3586 372280 : m_bNotifiable = bWasNotifiable;
3587 :
3588 372280 : if (pOldValue && (RES_REMOVE_UNO_OBJECT == pOldValue->Which()))
3589 : { // invalidate cached uno object
3590 : SetXParagraph(::com::sun::star::uno::Reference<
3591 0 : ::com::sun::star::text::XTextContent>(0));
3592 : }
3593 372280 : }
3594 :
3595 42184 : SwFormatColl* SwTextNode::ChgFormatColl( SwFormatColl *pNewColl )
3596 : {
3597 : OSL_ENSURE( pNewColl,"ChgFormatColl: Collectionpointer has value 0." );
3598 : OSL_ENSURE( HAS_BASE( SwTextFormatColl, pNewColl ),
3599 : "ChgFormatColl: is not a Text Collection pointer." );
3600 :
3601 42184 : SwTextFormatColl *pOldColl = GetTextColl();
3602 42184 : if( pNewColl != pOldColl )
3603 : {
3604 13468 : SetCalcHiddenCharFlags();
3605 13468 : SwContentNode::ChgFormatColl( pNewColl );
3606 : OSL_ENSURE( !mbInSetOrResetAttr,
3607 : "DEBUG OSL_ENSURE(ON - <SwTextNode::ChgFormatColl(..)> called during <Set/ResetAttr(..)>" );
3608 13468 : if ( !mbInSetOrResetAttr )
3609 : {
3610 13468 : SwFormatChg aTmp1( pOldColl );
3611 26936 : SwFormatChg aTmp2( pNewColl );
3612 26936 : HandleModifyAtTextNode( *this, &aTmp1, &aTmp2 );
3613 : }
3614 :
3615 : //UUUU reset fill information on parent style change
3616 13468 : if(maFillAttributes.get())
3617 : {
3618 23 : maFillAttributes.reset();
3619 : }
3620 : }
3621 :
3622 : // nur wenn im normalen Nodes-Array
3623 42184 : if( GetNodes().IsDocNodes() )
3624 : {
3625 42184 : _ChgTextCollUpdateNum( pOldColl, static_cast<SwTextFormatColl *>(pNewColl) );
3626 : }
3627 :
3628 42184 : GetNodes().UpdateOutlineNode(*this);
3629 :
3630 42184 : return pOldColl;
3631 : }
3632 :
3633 5620 : SwNodeNum* SwTextNode::CreateNum() const
3634 : {
3635 5620 : if ( !mpNodeNum )
3636 : {
3637 5620 : mpNodeNum = new SwNodeNum( const_cast<SwTextNode*>(this) );
3638 : }
3639 5620 : return mpNodeNum;
3640 : }
3641 :
3642 0 : SwNumberTree::tNumberVector SwTextNode::GetNumberVector() const
3643 : {
3644 0 : if ( GetNum() )
3645 : {
3646 0 : return GetNum()->GetNumberVector();
3647 : }
3648 : else
3649 : {
3650 0 : SwNumberTree::tNumberVector aResult;
3651 0 : return aResult;
3652 : }
3653 : }
3654 :
3655 518959 : bool SwTextNode::IsOutline() const
3656 : {
3657 518959 : bool bResult = false;
3658 :
3659 518959 : if ( GetAttrOutlineLevel() > 0 )
3660 : {
3661 16679 : bResult = !IsInRedlines();
3662 : }
3663 : else
3664 : {
3665 502280 : const SwNumRule* pRule( GetNum() ? GetNum()->GetNumRule() : 0L );
3666 502280 : if ( pRule && pRule->IsOutlineRule() )
3667 : {
3668 15 : bResult = !IsInRedlines();
3669 : }
3670 : }
3671 :
3672 518959 : return bResult;
3673 : }
3674 :
3675 498187 : bool SwTextNode::IsOutlineStateChanged() const
3676 : {
3677 498187 : return IsOutline() != m_bLastOutlineState;
3678 : }
3679 :
3680 1924 : void SwTextNode::UpdateOutlineState()
3681 : {
3682 1924 : m_bLastOutlineState = IsOutline();
3683 1924 : }
3684 :
3685 537370 : int SwTextNode::GetAttrOutlineLevel() const
3686 : {
3687 537370 : return static_cast<const SfxUInt16Item &>(GetAttr(RES_PARATR_OUTLINELEVEL)).GetValue();
3688 : }
3689 :
3690 0 : void SwTextNode::SetAttrOutlineLevel(int nLevel)
3691 : {
3692 : assert(0 <= nLevel && nLevel <= MAXLEVEL); // Level Out Of Range
3693 0 : if ( 0 <= nLevel && nLevel <= MAXLEVEL )
3694 : {
3695 : SetAttr( SfxUInt16Item( RES_PARATR_OUTLINELEVEL,
3696 0 : static_cast<sal_uInt16>(nLevel) ) );
3697 : }
3698 0 : }
3699 :
3700 : // #i70748#
3701 :
3702 285 : void SwTextNode::SetEmptyListStyleDueToSetOutlineLevelAttr()
3703 : {
3704 285 : if ( !mbEmptyListStyleSetDueToSetOutlineLevelAttr )
3705 : {
3706 280 : SetAttr( SwNumRuleItem() );
3707 280 : mbEmptyListStyleSetDueToSetOutlineLevelAttr = true;
3708 : }
3709 285 : }
3710 :
3711 12104 : void SwTextNode::ResetEmptyListStyleDueToResetOutlineLevelAttr()
3712 : {
3713 12104 : if ( mbEmptyListStyleSetDueToSetOutlineLevelAttr )
3714 : {
3715 5 : ResetAttr( RES_PARATR_NUMRULE );
3716 5 : mbEmptyListStyleSetDueToSetOutlineLevelAttr = false;
3717 : }
3718 12104 : }
3719 :
3720 5276 : void SwTextNode::SetAttrListLevel( int nLevel )
3721 : {
3722 5276 : if ( nLevel < 0 || nLevel >= MAXLEVEL )
3723 : {
3724 : assert(false); // invalid level
3725 5276 : return;
3726 : }
3727 :
3728 : SfxInt16Item aNewListLevelItem( RES_PARATR_LIST_LEVEL,
3729 5276 : static_cast<sal_Int16>(nLevel) );
3730 5276 : SetAttr( aNewListLevelItem );
3731 : }
3732 :
3733 39436 : bool SwTextNode::HasAttrListLevel() const
3734 : {
3735 43917 : return GetpSwAttrSet() &&
3736 43917 : GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_LEVEL, false ) == SfxItemState::SET;
3737 : }
3738 :
3739 14862 : int SwTextNode::GetAttrListLevel() const
3740 : {
3741 14862 : int nAttrListLevel = 0;
3742 :
3743 : const SfxInt16Item& aListLevelItem =
3744 14862 : dynamic_cast<const SfxInt16Item&>(GetAttr( RES_PARATR_LIST_LEVEL ));
3745 14862 : nAttrListLevel = static_cast<int>(aListLevelItem.GetValue());
3746 :
3747 14862 : return nAttrListLevel;
3748 : }
3749 :
3750 213175 : int SwTextNode::GetActualListLevel() const
3751 : {
3752 213175 : return GetNum() ? GetNum()->GetLevelInListTree() : -1;
3753 : }
3754 :
3755 23 : void SwTextNode::SetListRestart( bool bRestart )
3756 : {
3757 23 : if ( !bRestart )
3758 : {
3759 : // attribute not contained in paragraph style's attribute set. Thus,
3760 : // it can be reset to the attribute pool default by resetting the attribute.
3761 0 : ResetAttr( RES_PARATR_LIST_ISRESTART );
3762 : }
3763 : else
3764 : {
3765 : SfxBoolItem aNewIsRestartItem( RES_PARATR_LIST_ISRESTART,
3766 23 : true );
3767 23 : SetAttr( aNewIsRestartItem );
3768 : }
3769 23 : }
3770 :
3771 42724 : bool SwTextNode::IsListRestart() const
3772 : {
3773 : const SfxBoolItem& aIsRestartItem =
3774 42724 : dynamic_cast<const SfxBoolItem&>(GetAttr( RES_PARATR_LIST_ISRESTART ));
3775 :
3776 42724 : return aIsRestartItem.GetValue();
3777 : }
3778 :
3779 : /** Returns if the paragraph has a visible numbering or bullet.
3780 : This includes all kinds of numbering/bullet/outlines.
3781 : The concrete list label string has to be checked, too.
3782 : */
3783 21809 : bool SwTextNode::HasVisibleNumberingOrBullet() const
3784 : {
3785 21809 : const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
3786 21809 : if ( pRule && IsCountedInList())
3787 : {
3788 : // #i87154#
3789 : // Correction of #newlistlevelattrs#:
3790 : // The numbering type has to be checked for bullet lists.
3791 21663 : const SwNumFormat& rFormat = pRule->Get( lcl_BoundListLevel(GetActualListLevel()) );
3792 24725 : return SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType() ||
3793 24725 : !pRule->MakeNumString( *(GetNum()) ).isEmpty();
3794 : }
3795 :
3796 146 : return false;
3797 : }
3798 :
3799 10 : void SwTextNode::SetAttrListRestartValue( SwNumberTree::tSwNumTreeNumber nNumber )
3800 : {
3801 10 : const bool bChanged( HasAttrListRestartValue()
3802 0 : ? GetAttrListRestartValue() != nNumber
3803 10 : : nNumber != USHRT_MAX );
3804 :
3805 10 : if ( bChanged || !HasAttrListRestartValue() )
3806 : {
3807 10 : if ( nNumber == USHRT_MAX )
3808 : {
3809 0 : ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
3810 : }
3811 : else
3812 : {
3813 : SfxInt16Item aNewListRestartValueItem( RES_PARATR_LIST_RESTARTVALUE,
3814 10 : static_cast<sal_Int16>(nNumber) );
3815 10 : SetAttr( aNewListRestartValueItem );
3816 : }
3817 : }
3818 10 : }
3819 :
3820 37922 : bool SwTextNode::HasAttrListRestartValue() const
3821 : {
3822 41381 : return GetpSwAttrSet() &&
3823 41381 : GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_RESTARTVALUE, false ) == SfxItemState::SET;
3824 : }
3825 16 : SwNumberTree::tSwNumTreeNumber SwTextNode::GetAttrListRestartValue() const
3826 : {
3827 : OSL_ENSURE( HasAttrListRestartValue(),
3828 : "<SwTextNode::GetAttrListRestartValue()> - only ask for list restart value, if attribute is set at text node." );
3829 :
3830 : const SfxInt16Item& aListRestartValueItem =
3831 16 : dynamic_cast<const SfxInt16Item&>(GetAttr( RES_PARATR_LIST_RESTARTVALUE ));
3832 16 : return static_cast<SwNumberTree::tSwNumTreeNumber>(aListRestartValueItem.GetValue());
3833 : }
3834 :
3835 227 : SwNumberTree::tSwNumTreeNumber SwTextNode::GetActualListStartValue() const
3836 : {
3837 227 : SwNumberTree::tSwNumTreeNumber nListRestartValue = 1;
3838 :
3839 227 : if ( IsListRestart() && HasAttrListRestartValue() )
3840 : {
3841 16 : nListRestartValue = GetAttrListRestartValue();
3842 : }
3843 : else
3844 : {
3845 211 : SwNumRule* pRule = GetNumRule();
3846 211 : if ( pRule )
3847 : {
3848 : const SwNumFormat* pFormat =
3849 211 : pRule->GetNumFormat( static_cast<sal_uInt16>(GetAttrListLevel()) );
3850 211 : if ( pFormat )
3851 : {
3852 211 : nListRestartValue = pFormat->GetStart();
3853 : }
3854 : }
3855 : }
3856 :
3857 227 : return nListRestartValue;
3858 : }
3859 :
3860 77268 : bool SwTextNode::IsNotifiable() const
3861 : {
3862 77268 : return m_bNotifiable && IsNotificationEnabled();
3863 : }
3864 :
3865 83445 : bool SwTextNode::IsNotificationEnabled() const
3866 : {
3867 83445 : bool bResult = false;
3868 83445 : const SwDoc * pDoc = GetDoc();
3869 83445 : if( pDoc )
3870 : {
3871 83445 : bResult = !(pDoc->IsInReading() || pDoc->IsInDtor());
3872 : }
3873 83445 : return bResult;
3874 : }
3875 :
3876 874 : void SwTextNode::SetCountedInList( bool bCounted )
3877 : {
3878 874 : if ( bCounted )
3879 : {
3880 : // attribute not contained in paragraph style's attribute set. Thus,
3881 : // it can be reset to the attribute pool default by resetting the attribute.
3882 844 : ResetAttr( RES_PARATR_LIST_ISCOUNTED );
3883 : }
3884 : else
3885 : {
3886 30 : SfxBoolItem aIsCountedInListItem( RES_PARATR_LIST_ISCOUNTED, false );
3887 30 : SetAttr( aIsCountedInListItem );
3888 : }
3889 874 : }
3890 :
3891 124655 : bool SwTextNode::IsCountedInList() const
3892 : {
3893 : const SfxBoolItem& aIsCountedInListItem =
3894 124655 : dynamic_cast<const SfxBoolItem&>(GetAttr( RES_PARATR_LIST_ISCOUNTED ));
3895 :
3896 124655 : return aIsCountedInListItem.GetValue();
3897 : }
3898 :
3899 5914 : void SwTextNode::AddToList()
3900 : {
3901 5914 : if ( IsInList() )
3902 : {
3903 : OSL_FAIL( "<SwTextNode::AddToList()> - the text node is already added to a list. Serious defect -> please inform OD" );
3904 5914 : return;
3905 : }
3906 :
3907 5914 : const OUString sListId = GetListId();
3908 5914 : if (!sListId.isEmpty())
3909 : {
3910 5620 : SwList* pList = GetDoc()->getIDocumentListsAccess().getListByName( sListId );
3911 5620 : if ( pList == 0 )
3912 : {
3913 : // Create corresponding list.
3914 0 : SwNumRule* pNumRule = GetNumRule();
3915 0 : if ( pNumRule )
3916 : {
3917 0 : pList = GetDoc()->getIDocumentListsAccess().createList( sListId, GetNumRule()->GetName() );
3918 : }
3919 : }
3920 : OSL_ENSURE( pList != 0,
3921 : "<SwTextNode::AddToList()> - no list for given list id. Serious defect -> please inform OD" );
3922 5620 : if ( pList )
3923 : {
3924 5620 : pList->InsertListItem( *CreateNum(), GetAttrListLevel() );
3925 5620 : mpList = pList;
3926 : }
3927 5914 : }
3928 : }
3929 :
3930 117902 : void SwTextNode::RemoveFromList()
3931 : {
3932 117902 : if ( IsInList() )
3933 : {
3934 5620 : SwList::RemoveListItem( *mpNodeNum );
3935 5620 : mpList = 0;
3936 5620 : delete mpNodeNum;
3937 5620 : mpNodeNum = 0L;
3938 :
3939 5620 : SetWordCountDirty( true );
3940 : }
3941 117902 : }
3942 :
3943 505237 : bool SwTextNode::IsInList() const
3944 : {
3945 505237 : return GetNum() != 0 && GetNum()->GetParent() != 0;
3946 : }
3947 :
3948 0 : bool SwTextNode::IsFirstOfNumRule() const
3949 : {
3950 0 : bool bResult = false;
3951 :
3952 0 : if ( GetNum() && GetNum()->GetNumRule())
3953 0 : bResult = GetNum()->IsFirst();
3954 :
3955 0 : return bResult;
3956 : }
3957 :
3958 211 : void SwTextNode::SetListId(OUString const& rListId)
3959 : {
3960 : const SfxStringItem& rListIdItem =
3961 211 : dynamic_cast<const SfxStringItem&>(GetAttr( RES_PARATR_LIST_ID ));
3962 211 : if (rListIdItem.GetValue() != rListId)
3963 : {
3964 211 : if (rListId.isEmpty())
3965 : {
3966 0 : ResetAttr( RES_PARATR_LIST_ID );
3967 : }
3968 : else
3969 : {
3970 211 : SfxStringItem aNewListIdItem(RES_PARATR_LIST_ID, rListId);
3971 211 : SetAttr( aNewListIdItem );
3972 : }
3973 : }
3974 211 : }
3975 :
3976 13598 : OUString SwTextNode::GetListId() const
3977 : {
3978 13598 : OUString sListId;
3979 :
3980 : const SfxStringItem& rListIdItem =
3981 13598 : dynamic_cast<const SfxStringItem&>(GetAttr( RES_PARATR_LIST_ID ));
3982 13598 : sListId = rListIdItem.GetValue();
3983 :
3984 : // As long as no explicit list id attribute is set, use the list id of
3985 : // the list, which has been created for the applied list style.
3986 13598 : if (sListId.isEmpty())
3987 : {
3988 11901 : SwNumRule* pRule = GetNumRule();
3989 11901 : if ( pRule )
3990 : {
3991 11554 : sListId = pRule->GetDefaultListId();
3992 : }
3993 : }
3994 :
3995 13598 : return sListId;
3996 : }
3997 :
3998 : /** Determines, if the list level indent attributes can be applied to the
3999 : paragraph.
4000 :
4001 : The list level indents can be applied to the paragraph under the one
4002 : of following conditions:
4003 : - the list style is directly applied to the paragraph and the paragraph
4004 : has no own indent attributes.
4005 : - the list style is applied to the paragraph through one of its paragraph
4006 : styles, the paragraph has no own indent attributes and on the paragraph
4007 : style hierarchy from the paragraph to the paragraph style with the
4008 : list style no indent attributes are found.
4009 :
4010 : @return boolean
4011 : */
4012 147373 : bool SwTextNode::AreListLevelIndentsApplicable() const
4013 : {
4014 147373 : bool bAreListLevelIndentsApplicable( true );
4015 :
4016 147373 : if ( !GetNum() || !GetNum()->GetNumRule() )
4017 : {
4018 : // no list style applied to paragraph
4019 49323 : bAreListLevelIndentsApplicable = false;
4020 : }
4021 196100 : else if ( HasSwAttrSet() &&
4022 98050 : GetpSwAttrSet()->GetItemState( RES_LR_SPACE, false ) == SfxItemState::SET )
4023 : {
4024 : // paragraph has hard-set indent attributes
4025 34831 : bAreListLevelIndentsApplicable = false;
4026 : }
4027 126438 : else if ( HasSwAttrSet() &&
4028 63219 : GetpSwAttrSet()->GetItemState( RES_PARATR_NUMRULE, false ) == SfxItemState::SET )
4029 : {
4030 : // list style is directly applied to paragraph and paragraph has no
4031 : // hard-set indent attributes
4032 59338 : bAreListLevelIndentsApplicable = true;
4033 : }
4034 : else
4035 : {
4036 : // list style is applied through one of the paragraph styles and
4037 : // paragraph has no hard-set indent attributes
4038 :
4039 : // check, paragraph's
4040 3881 : const SwTextFormatColl* pColl = GetTextColl();
4041 7762 : while ( pColl )
4042 : {
4043 3881 : if ( pColl->GetAttrSet().GetItemState( RES_LR_SPACE, false ) == SfxItemState::SET )
4044 : {
4045 : // indent attributes found in the paragraph style hierarchy.
4046 0 : bAreListLevelIndentsApplicable = false;
4047 0 : break;
4048 : }
4049 :
4050 3881 : if ( pColl->GetAttrSet().GetItemState( RES_PARATR_NUMRULE, false ) == SfxItemState::SET )
4051 : {
4052 : // paragraph style with the list style found and until now no
4053 : // indent attributes are found in the paragraph style hierarchy.
4054 3881 : bAreListLevelIndentsApplicable = true;
4055 3881 : break;
4056 : }
4057 :
4058 0 : pColl = dynamic_cast<const SwTextFormatColl*>(pColl->DerivedFrom());
4059 : OSL_ENSURE( pColl,
4060 : "<SwTextNode::AreListLevelIndentsApplicable()> - something wrong in paragraph's style hierarchy. The applied list style is not found." );
4061 : }
4062 : }
4063 :
4064 147373 : return bAreListLevelIndentsApplicable;
4065 : }
4066 :
4067 : /** Retrieves the list tab stop position, if the paragraph's list level defines
4068 : one and this list tab stop has to merged into the tap stops of the paragraph
4069 :
4070 : @param nListTabStopPosition
4071 : output parameter - containing the list tab stop position
4072 :
4073 : @return boolean - indicating, if a list tab stop position is provided
4074 : */
4075 184833 : bool SwTextNode::GetListTabStopPosition( long& nListTabStopPosition ) const
4076 : {
4077 184833 : bool bListTanStopPositionProvided( false );
4078 :
4079 184833 : const SwNumRule* pNumRule = GetNum() ? GetNum()->GetNumRule() : 0;
4080 184833 : if ( pNumRule && HasVisibleNumberingOrBullet() && GetActualListLevel() >= 0 )
4081 : {
4082 14096 : const SwNumFormat& rFormat = pNumRule->Get( static_cast<sal_uInt16>(GetActualListLevel()) );
4083 26790 : if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
4084 12694 : rFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
4085 : {
4086 11899 : bListTanStopPositionProvided = true;
4087 11899 : nListTabStopPosition = rFormat.GetListtabPos();
4088 :
4089 11899 : if ( getIDocumentSettingAccess()->get(DocumentSettingId::TABS_RELATIVE_TO_INDENT) )
4090 : {
4091 : // tab stop position are treated to be relative to the "before text"
4092 : // indent value of the paragraph. Thus, adjust <nListTabStopPos>.
4093 1297 : if ( AreListLevelIndentsApplicable() )
4094 : {
4095 1297 : nListTabStopPosition -= rFormat.GetIndentAt();
4096 : }
4097 0 : else if (!getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
4098 : {
4099 0 : SvxLRSpaceItem aItem = GetSwAttrSet().GetLRSpace();
4100 0 : nListTabStopPosition -= aItem.GetTextLeft();
4101 : }
4102 : }
4103 : }
4104 : }
4105 :
4106 184833 : return bListTanStopPositionProvided;
4107 : }
4108 :
4109 6998 : OUString SwTextNode::GetLabelFollowedBy() const
4110 : {
4111 6998 : const SwNumRule* pNumRule = GetNum() ? GetNum()->GetNumRule() : 0;
4112 6998 : if ( pNumRule && HasVisibleNumberingOrBullet() && GetActualListLevel() >= 0 )
4113 : {
4114 6998 : const SwNumFormat& rFormat = pNumRule->Get( static_cast<sal_uInt16>(GetActualListLevel()) );
4115 6998 : if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
4116 : {
4117 6561 : switch ( rFormat.GetLabelFollowedBy() )
4118 : {
4119 : case SvxNumberFormat::LISTTAB:
4120 : {
4121 6210 : return OUString("\t");
4122 : }
4123 : break;
4124 : case SvxNumberFormat::SPACE:
4125 : {
4126 63 : return OUString(" ");
4127 : }
4128 : break;
4129 : case SvxNumberFormat::NOTHING:
4130 : {
4131 : // intentionally left blank.
4132 : }
4133 288 : break;
4134 : default:
4135 : {
4136 : OSL_FAIL( "<SwTextNode::GetLabelFollowedBy()> - unknown SvxNumberFormat::GetLabelFollowedBy() return value" );
4137 : }
4138 : }
4139 : }
4140 : }
4141 :
4142 725 : return OUString();
4143 : }
4144 :
4145 34175 : void SwTextNode::CalcHiddenCharFlags() const
4146 : {
4147 : sal_Int32 nStartPos;
4148 : sal_Int32 nEndPos;
4149 : // Update of the flags is done inside GetBoundsOfHiddenRange()
4150 34175 : SwScriptInfo::GetBoundsOfHiddenRange( *this, 0, nStartPos, nEndPos );
4151 34175 : }
4152 :
4153 : // #i12836# enhanced pdf export
4154 11461694 : bool SwTextNode::IsHidden() const
4155 : {
4156 11461694 : if ( HasHiddenParaField() || HasHiddenCharAttribute( true ) )
4157 135 : return true;
4158 :
4159 11461559 : const SwSectionNode* pSectNd = FindSectionNode();
4160 11461559 : if ( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
4161 0 : return true;
4162 :
4163 11461559 : return false;
4164 : }
4165 :
4166 : namespace {
4167 : // Helper class for special handling of setting attributes at text node:
4168 : // In constructor an instance of the helper class recognize whose attributes
4169 : // are set and perform corresponding actions before the intrinsic set of
4170 : // attributes has been taken place.
4171 : // In the destructor - after the attributes have been set at the text
4172 : // node - corresponding actions are performed.
4173 : // The following is handled:
4174 : // (1) When the list style attribute - RES_PARATR_NUMRULE - is set,
4175 : // (A) list style attribute is empty -> the text node is removed from
4176 : // its list.
4177 : // (B) list style attribute is not empty
4178 : // (a) text node has no list style -> add text node to its list after
4179 : // the attributes have been set.
4180 : // (b) text node has list style -> change of list style is notified
4181 : // after the attributes have been set.
4182 : // (2) When the list id attribute - RES_PARATR_LIST_ID - is set and changed,
4183 : // the text node is removed from its current list before the attributes
4184 : // are set and added to its new list after the attributes have been set.
4185 : // (3) Notify list tree, if list level - RES_PARATR_LIST_LEVEL - is set
4186 : // and changed after the attributes have been set
4187 : // (4) Notify list tree, if list restart - RES_PARATR_LIST_ISRESTART - is set
4188 : // and changed after the attributes have been set
4189 : // (5) Notify list tree, if list restart value - RES_PARATR_LIST_RESTARTVALUE -
4190 : // is set and changed after the attributes have been set
4191 : // (6) Notify list tree, if count in list - RES_PARATR_LIST_ISCOUNTED - is set
4192 : // and changed after the attributes have been set
4193 : // (7) Set or Reset emtpy list style due to changed outline level - RES_PARATR_OUTLINELEVEL.
4194 : class HandleSetAttrAtTextNode
4195 : {
4196 : public:
4197 : HandleSetAttrAtTextNode( SwTextNode& rTextNode,
4198 : const SfxPoolItem& pItem );
4199 : HandleSetAttrAtTextNode( SwTextNode& rTextNode,
4200 : const SfxItemSet& rItemSet );
4201 : ~HandleSetAttrAtTextNode();
4202 :
4203 : private:
4204 : SwTextNode& mrTextNode;
4205 : bool mbAddTextNodeToList;
4206 : bool mbUpdateListLevel;
4207 : bool mbUpdateListRestart;
4208 : bool mbUpdateListCount;
4209 : // #i70748#
4210 : bool mbOutlineLevelSet;
4211 : };
4212 :
4213 11889 : HandleSetAttrAtTextNode::HandleSetAttrAtTextNode( SwTextNode& rTextNode,
4214 : const SfxPoolItem& pItem )
4215 : : mrTextNode( rTextNode ),
4216 : mbAddTextNodeToList( false ),
4217 : mbUpdateListLevel( false ),
4218 : mbUpdateListRestart( false ),
4219 : mbUpdateListCount( false ),
4220 : // #i70748#
4221 11889 : mbOutlineLevelSet( false )
4222 : {
4223 11889 : switch ( pItem.Which() )
4224 : {
4225 : // handle RES_PARATR_NUMRULE
4226 : case RES_PARATR_NUMRULE:
4227 : {
4228 829 : mrTextNode.RemoveFromList();
4229 :
4230 : const SwNumRuleItem& pNumRuleItem =
4231 829 : dynamic_cast<const SwNumRuleItem&>(pItem);
4232 829 : if ( !pNumRuleItem.GetValue().isEmpty() )
4233 : {
4234 505 : mbAddTextNodeToList = true;
4235 : // #i105562#
4236 :
4237 505 : mrTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
4238 : }
4239 : }
4240 829 : break;
4241 :
4242 : // handle RES_PARATR_LIST_ID
4243 : case RES_PARATR_LIST_ID:
4244 : {
4245 : const SfxStringItem& pListIdItem =
4246 211 : dynamic_cast<const SfxStringItem&>(pItem);
4247 : OSL_ENSURE( pListIdItem.GetValue().getLength() > 0,
4248 : "<HandleSetAttrAtTextNode(..)> - empty list id attribute not excepted. Serious defect -> please inform OD." );
4249 211 : const OUString sListIdOfTextNode = rTextNode.GetListId();
4250 211 : if ( pListIdItem.GetValue() != sListIdOfTextNode )
4251 : {
4252 0 : mbAddTextNodeToList = true;
4253 0 : if ( mrTextNode.IsInList() )
4254 : {
4255 0 : mrTextNode.RemoveFromList();
4256 : }
4257 211 : }
4258 : }
4259 211 : break;
4260 :
4261 : // handle RES_PARATR_LIST_LEVEL
4262 : case RES_PARATR_LIST_LEVEL:
4263 : {
4264 : const SfxInt16Item& aListLevelItem =
4265 5276 : dynamic_cast<const SfxInt16Item&>(pItem);
4266 5276 : if ( aListLevelItem.GetValue() != mrTextNode.GetAttrListLevel() )
4267 : {
4268 968 : mbUpdateListLevel = true;
4269 : }
4270 : }
4271 5276 : break;
4272 :
4273 : // handle RES_PARATR_LIST_ISRESTART
4274 : case RES_PARATR_LIST_ISRESTART:
4275 : {
4276 : const SfxBoolItem& aListIsRestartItem =
4277 23 : dynamic_cast<const SfxBoolItem&>(pItem);
4278 46 : if ( aListIsRestartItem.GetValue() !=
4279 23 : mrTextNode.IsListRestart() )
4280 : {
4281 23 : mbUpdateListRestart = true;
4282 : }
4283 : }
4284 23 : break;
4285 :
4286 : // handle RES_PARATR_LIST_RESTARTVALUE
4287 : case RES_PARATR_LIST_RESTARTVALUE:
4288 : {
4289 : const SfxInt16Item& aListRestartValueItem =
4290 10 : dynamic_cast<const SfxInt16Item&>(pItem);
4291 10 : if ( !mrTextNode.HasAttrListRestartValue() ||
4292 0 : aListRestartValueItem.GetValue() != mrTextNode.GetAttrListRestartValue() )
4293 : {
4294 10 : mbUpdateListRestart = true;
4295 : }
4296 : }
4297 10 : break;
4298 :
4299 : // handle RES_PARATR_LIST_ISCOUNTED
4300 : case RES_PARATR_LIST_ISCOUNTED:
4301 : {
4302 : const SfxBoolItem& aIsCountedInListItem =
4303 30 : dynamic_cast<const SfxBoolItem&>(pItem);
4304 60 : if ( aIsCountedInListItem.GetValue() !=
4305 30 : mrTextNode.IsCountedInList() )
4306 : {
4307 30 : mbUpdateListCount = true;
4308 : }
4309 : }
4310 30 : break;
4311 :
4312 : // #i70748#
4313 : // handle RES_PARATR_OUTLINELEVEL
4314 : case RES_PARATR_OUTLINELEVEL:
4315 : {
4316 : const SfxUInt16Item& aOutlineLevelItem =
4317 0 : dynamic_cast<const SfxUInt16Item&>(pItem);
4318 0 : if ( aOutlineLevelItem.GetValue() != mrTextNode.GetAttrOutlineLevel() )
4319 : {
4320 0 : mbOutlineLevelSet = true;
4321 : }
4322 : }
4323 0 : break;
4324 : }
4325 :
4326 11889 : }
4327 :
4328 81357 : HandleSetAttrAtTextNode::HandleSetAttrAtTextNode( SwTextNode& rTextNode,
4329 : const SfxItemSet& rItemSet )
4330 : : mrTextNode( rTextNode ),
4331 : mbAddTextNodeToList( false ),
4332 : mbUpdateListLevel( false ),
4333 : mbUpdateListRestart( false ),
4334 : mbUpdateListCount( false ),
4335 : // #i70748#
4336 81357 : mbOutlineLevelSet( false )
4337 : {
4338 81357 : const SfxPoolItem* pItem = 0;
4339 : // handle RES_PARATR_NUMRULE
4340 81357 : if ( rItemSet.GetItemState( RES_PARATR_NUMRULE, false, &pItem ) == SfxItemState::SET )
4341 : {
4342 4243 : mrTextNode.RemoveFromList();
4343 :
4344 : const SwNumRuleItem* pNumRuleItem =
4345 4243 : dynamic_cast<const SwNumRuleItem*>(pItem);
4346 4243 : if ( !pNumRuleItem->GetValue().isEmpty() )
4347 : {
4348 3925 : mbAddTextNodeToList = true;
4349 : // #i70748#
4350 3925 : mrTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
4351 : }
4352 : }
4353 :
4354 : // handle RES_PARATR_LIST_ID
4355 81357 : if ( rItemSet.GetItemState( RES_PARATR_LIST_ID, false, &pItem ) == SfxItemState::SET )
4356 : {
4357 : const SfxStringItem* pListIdItem =
4358 113 : dynamic_cast<const SfxStringItem*>(pItem);
4359 113 : const OUString sListIdOfTextNode = mrTextNode.GetListId();
4360 226 : if ( pListIdItem &&
4361 113 : pListIdItem->GetValue() != sListIdOfTextNode )
4362 : {
4363 53 : mbAddTextNodeToList = true;
4364 53 : if ( mrTextNode.IsInList() )
4365 : {
4366 0 : mrTextNode.RemoveFromList();
4367 : }
4368 113 : }
4369 : }
4370 :
4371 : // handle RES_PARATR_LIST_LEVEL
4372 81357 : if ( rItemSet.GetItemState( RES_PARATR_LIST_LEVEL, false, &pItem ) == SfxItemState::SET )
4373 : {
4374 : const SfxInt16Item* pListLevelItem =
4375 2997 : dynamic_cast<const SfxInt16Item*>(pItem);
4376 2997 : if (pListLevelItem && pListLevelItem->GetValue() != mrTextNode.GetAttrListLevel())
4377 : {
4378 1066 : mbUpdateListLevel = true;
4379 : }
4380 : }
4381 :
4382 : // handle RES_PARATR_LIST_ISRESTART
4383 81357 : if ( rItemSet.GetItemState( RES_PARATR_LIST_ISRESTART, false, &pItem ) == SfxItemState::SET )
4384 : {
4385 : const SfxBoolItem* pListIsRestartItem =
4386 10 : dynamic_cast<const SfxBoolItem*>(pItem);
4387 10 : if (pListIsRestartItem && pListIsRestartItem->GetValue() != mrTextNode.IsListRestart())
4388 : {
4389 10 : mbUpdateListRestart = true;
4390 : }
4391 : }
4392 :
4393 : // handle RES_PARATR_LIST_RESTARTVALUE
4394 81357 : if ( rItemSet.GetItemState( RES_PARATR_LIST_RESTARTVALUE, false, &pItem ) == SfxItemState::SET )
4395 : {
4396 : const SfxInt16Item* pListRestartValueItem =
4397 0 : dynamic_cast<const SfxInt16Item*>(pItem);
4398 0 : if ( !mrTextNode.HasAttrListRestartValue() || (pListRestartValueItem &&
4399 0 : pListRestartValueItem->GetValue() != mrTextNode.GetAttrListRestartValue()) )
4400 : {
4401 0 : mbUpdateListRestart = true;
4402 : }
4403 : }
4404 :
4405 : // handle RES_PARATR_LIST_ISCOUNTED
4406 81357 : if ( rItemSet.GetItemState( RES_PARATR_LIST_ISCOUNTED, false, &pItem ) == SfxItemState::SET )
4407 : {
4408 : const SfxBoolItem* pIsCountedInListItem =
4409 0 : dynamic_cast<const SfxBoolItem*>(pItem);
4410 0 : if (pIsCountedInListItem && pIsCountedInListItem->GetValue() !=
4411 0 : mrTextNode.IsCountedInList())
4412 : {
4413 0 : mbUpdateListCount = true;
4414 : }
4415 : }
4416 :
4417 : // #i70748#
4418 : // handle RES_PARATR_OUTLINELEVEL
4419 81357 : if ( rItemSet.GetItemState( RES_PARATR_OUTLINELEVEL, false, &pItem ) == SfxItemState::SET )
4420 : {
4421 : const SfxUInt16Item* pOutlineLevelItem =
4422 881 : dynamic_cast<const SfxUInt16Item*>(pItem);
4423 1762 : if (pOutlineLevelItem && pOutlineLevelItem->GetValue() !=
4424 881 : mrTextNode.GetAttrOutlineLevel())
4425 : {
4426 444 : mbOutlineLevelSet = true;
4427 : }
4428 : }
4429 81357 : }
4430 :
4431 93246 : HandleSetAttrAtTextNode::~HandleSetAttrAtTextNode()
4432 : {
4433 93246 : if ( mbAddTextNodeToList )
4434 : {
4435 4430 : SwNumRule* pNumRuleAtTextNode = mrTextNode.GetNumRule();
4436 4430 : if ( pNumRuleAtTextNode )
4437 : {
4438 4425 : mrTextNode.AddToList();
4439 : }
4440 : }
4441 : else
4442 : {
4443 88816 : if ( mbUpdateListLevel && mrTextNode.IsInList() )
4444 : {
4445 316 : const_cast<SwNodeNum*>(mrTextNode.GetNum())->SetLevelInListTree(
4446 632 : mrTextNode.GetAttrListLevel() );
4447 : }
4448 :
4449 88816 : if ( mbUpdateListRestart && mrTextNode.IsInList() )
4450 : {
4451 33 : SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTextNode.GetNum());
4452 33 : pNodeNum->InvalidateMe();
4453 33 : pNodeNum->NotifyInvalidSiblings();
4454 : }
4455 :
4456 88816 : if ( mbUpdateListCount && mrTextNode.IsInList() )
4457 : {
4458 30 : const_cast<SwNodeNum*>(mrTextNode.GetNum())->InvalidateAndNotifyTree();
4459 : }
4460 : }
4461 :
4462 : // #i70748#
4463 93246 : if (mbOutlineLevelSet)
4464 : {
4465 444 : mrTextNode.GetNodes().UpdateOutlineNode(mrTextNode);
4466 444 : if (mrTextNode.GetAttrOutlineLevel() == 0)
4467 : {
4468 8 : mrTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
4469 : }
4470 : else
4471 : {
4472 436 : const SfxPoolItem* pItem = 0;
4473 872 : if ( mrTextNode.GetSwAttrSet().GetItemState( RES_PARATR_NUMRULE,
4474 436 : true, &pItem )
4475 : != SfxItemState::SET )
4476 : {
4477 280 : mrTextNode.SetEmptyListStyleDueToSetOutlineLevelAttr();
4478 : }
4479 : }
4480 : }
4481 93246 : }
4482 : // End of class <HandleSetAttrAtTextNode>
4483 : }
4484 :
4485 11889 : bool SwTextNode::SetAttr( const SfxPoolItem& pItem )
4486 : {
4487 11889 : const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
4488 11889 : mbInSetOrResetAttr = true;
4489 :
4490 11889 : HandleSetAttrAtTextNode aHandleSetAttr( *this, pItem );
4491 :
4492 11889 : bool bRet = SwContentNode::SetAttr( pItem );
4493 :
4494 11889 : mbInSetOrResetAttr = bOldIsSetOrResetAttr;
4495 :
4496 11889 : return bRet;
4497 : }
4498 :
4499 81357 : bool SwTextNode::SetAttr( const SfxItemSet& rSet )
4500 : {
4501 81357 : const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
4502 81357 : mbInSetOrResetAttr = true;
4503 :
4504 81357 : HandleSetAttrAtTextNode aHandleSetAttr( *this, rSet );
4505 :
4506 81357 : bool bRet = SwContentNode::SetAttr( rSet );
4507 :
4508 81357 : mbInSetOrResetAttr = bOldIsSetOrResetAttr;
4509 :
4510 81357 : return bRet;
4511 : }
4512 :
4513 : namespace {
4514 : // Helper class for special handling of resetting attributes at text node:
4515 : // In constructor an instance of the helper class recognize whose attributes
4516 : // are reset and perform corresponding actions before the intrinsic reset of
4517 : // attributes has been taken place.
4518 : // In the destructor - after the attributes have been reset at the text
4519 : // node - corresponding actions are performed.
4520 : // The following is handled:
4521 : // (1) When the list style attribute - RES_PARATR_NUMRULE - is reset,
4522 : // the text is removed from its list before the attributes have been reset.
4523 : // (2) When the list id attribute - RES_PARATR_LIST_ID - is reset,
4524 : // the text is removed from its list before the attributes have been reset.
4525 : // (3) Notify list tree, if list level - RES_PARATR_LIST_LEVEL - is reset.
4526 : // (4) Notify list tree, if list restart - RES_PARATR_LIST_ISRESTART - is reset.
4527 : // (5) Notify list tree, if list restart value - RES_PARATR_LIST_RESTARTVALUE - is reset.
4528 : // (6) Notify list tree, if count in list - RES_PARATR_LIST_ISCOUNTED - is reset.
4529 : // (7) Reset empty list style, if outline level attribute - RES_PARATR_OUTLINELEVEL - is reset.
4530 : class HandleResetAttrAtTextNode
4531 : {
4532 : public:
4533 : HandleResetAttrAtTextNode( SwTextNode& rTextNode,
4534 : const sal_uInt16 nWhich1,
4535 : const sal_uInt16 nWhich2 );
4536 : HandleResetAttrAtTextNode( SwTextNode& rTextNode,
4537 : const std::vector<sal_uInt16>& rWhichArr );
4538 : explicit HandleResetAttrAtTextNode( SwTextNode& rTextNode );
4539 :
4540 : ~HandleResetAttrAtTextNode();
4541 :
4542 : private:
4543 : SwTextNode& mrTextNode;
4544 : bool mbListStyleOrIdReset;
4545 : bool mbUpdateListLevel;
4546 : bool mbUpdateListRestart;
4547 : bool mbUpdateListCount;
4548 : };
4549 :
4550 194830 : HandleResetAttrAtTextNode::HandleResetAttrAtTextNode( SwTextNode& rTextNode,
4551 : const sal_uInt16 nWhich1,
4552 : const sal_uInt16 nWhich2 )
4553 : : mrTextNode( rTextNode ),
4554 : mbListStyleOrIdReset( false ),
4555 : mbUpdateListLevel( false ),
4556 : mbUpdateListRestart( false ),
4557 194830 : mbUpdateListCount( false )
4558 : {
4559 194830 : bool bRemoveFromList( false );
4560 194830 : if ( nWhich2 != 0 && nWhich2 > nWhich1 )
4561 : {
4562 : // RES_PARATR_NUMRULE and RES_PARATR_LIST_ID
4563 1 : if ( nWhich1 <= RES_PARATR_NUMRULE && RES_PARATR_NUMRULE <= nWhich2 )
4564 : {
4565 0 : bRemoveFromList = mrTextNode.GetNumRule() != 0;
4566 0 : mbListStyleOrIdReset = true;
4567 : }
4568 1 : else if ( nWhich1 <= RES_PARATR_LIST_ID && RES_PARATR_LIST_ID <= nWhich2 )
4569 : {
4570 0 : bRemoveFromList = mrTextNode.GetpSwAttrSet() &&
4571 0 : mrTextNode.GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_ID, false ) == SfxItemState::SET;
4572 : // #i92898#
4573 0 : mbListStyleOrIdReset = true;
4574 : }
4575 :
4576 1 : if ( !bRemoveFromList )
4577 : {
4578 : // RES_PARATR_LIST_LEVEL
4579 0 : mbUpdateListLevel = ( nWhich1 <= RES_PARATR_LIST_LEVEL &&
4580 1 : RES_PARATR_LIST_LEVEL <= nWhich2 &&
4581 1 : mrTextNode.HasAttrListLevel() );
4582 :
4583 : // RES_PARATR_LIST_ISRESTART and RES_PARATR_LIST_RESTARTVALUE
4584 : mbUpdateListRestart =
4585 0 : ( nWhich1 <= RES_PARATR_LIST_ISRESTART && RES_PARATR_LIST_ISRESTART <= nWhich2 &&
4586 2 : mrTextNode.IsListRestart() ) ||
4587 0 : ( nWhich1 <= RES_PARATR_LIST_RESTARTVALUE && RES_PARATR_LIST_RESTARTVALUE <= nWhich2 &&
4588 1 : mrTextNode.HasAttrListRestartValue() );
4589 :
4590 : // RES_PARATR_LIST_ISCOUNTED
4591 : mbUpdateListCount =
4592 1 : ( nWhich1 <= RES_PARATR_LIST_ISCOUNTED && RES_PARATR_LIST_ISCOUNTED <= nWhich2 &&
4593 1 : !mrTextNode.IsCountedInList() );
4594 : }
4595 :
4596 : // #i70748#
4597 : // RES_PARATR_OUTLINELEVEL
4598 2 : if ( nWhich1 <= RES_PARATR_OUTLINELEVEL && RES_PARATR_OUTLINELEVEL <= nWhich2 )
4599 : {
4600 0 : mrTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
4601 : }
4602 : }
4603 : else
4604 : {
4605 : // RES_PARATR_NUMRULE and RES_PARATR_LIST_ID
4606 194829 : if ( nWhich1 == RES_PARATR_NUMRULE )
4607 : {
4608 7151 : bRemoveFromList = mrTextNode.GetNumRule() != 0;
4609 7151 : mbListStyleOrIdReset = true;
4610 : }
4611 187678 : else if ( nWhich1 == RES_PARATR_LIST_ID )
4612 : {
4613 39382 : bRemoveFromList = mrTextNode.GetpSwAttrSet() &&
4614 39382 : mrTextNode.GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_ID, false ) == SfxItemState::SET;
4615 : // #i92898#
4616 36923 : mbListStyleOrIdReset = true;
4617 : }
4618 : // #i70748#
4619 : // RES_PARATR_OUTLINELEVEL
4620 150755 : else if ( nWhich1 == RES_PARATR_OUTLINELEVEL )
4621 : {
4622 0 : mrTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
4623 : }
4624 :
4625 194829 : if ( !bRemoveFromList )
4626 : {
4627 : // RES_PARATR_LIST_LEVEL
4628 231085 : mbUpdateListLevel = nWhich1 == RES_PARATR_LIST_LEVEL &&
4629 231085 : mrTextNode.HasAttrListLevel();
4630 :
4631 : // RES_PARATR_LIST_ISRESTART and RES_PARATR_LIST_RESTARTVALUE
4632 37663 : mbUpdateListRestart = ( nWhich1 == RES_PARATR_LIST_ISRESTART &&
4633 388338 : mrTextNode.IsListRestart() ) ||
4634 37663 : ( nWhich1 == RES_PARATR_LIST_RESTARTVALUE &&
4635 231832 : mrTextNode.HasAttrListRestartValue() );
4636 :
4637 : // RES_PARATR_LIST_ISCOUNTED
4638 232676 : mbUpdateListCount = nWhich1 == RES_PARATR_LIST_ISCOUNTED &&
4639 232676 : !mrTextNode.IsCountedInList();
4640 : }
4641 : }
4642 :
4643 194830 : if ( bRemoveFromList && mrTextNode.IsInList() )
4644 : {
4645 660 : mrTextNode.RemoveFromList();
4646 : }
4647 194830 : }
4648 :
4649 4511 : HandleResetAttrAtTextNode::HandleResetAttrAtTextNode( SwTextNode& rTextNode,
4650 : const std::vector<sal_uInt16>& rWhichArr )
4651 : : mrTextNode( rTextNode ),
4652 : mbListStyleOrIdReset( false ),
4653 : mbUpdateListLevel( false ),
4654 : mbUpdateListRestart( false ),
4655 4511 : mbUpdateListCount( false )
4656 : {
4657 4511 : bool bRemoveFromList( false );
4658 : {
4659 4511 : std::vector<sal_uInt16>::const_iterator it;
4660 61821 : for ( it = rWhichArr.begin(); it != rWhichArr.end(); ++it)
4661 : {
4662 : // RES_PARATR_NUMRULE and RES_PARATR_LIST_ID
4663 57310 : if ( *it == RES_PARATR_NUMRULE )
4664 : {
4665 1200 : bRemoveFromList = bRemoveFromList ||
4666 1200 : mrTextNode.GetNumRule() != 0;
4667 600 : mbListStyleOrIdReset = true;
4668 : }
4669 56710 : else if ( *it == RES_PARATR_LIST_ID )
4670 : {
4671 0 : bRemoveFromList = bRemoveFromList ||
4672 0 : ( mrTextNode.GetpSwAttrSet() &&
4673 0 : mrTextNode.GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_ID, false ) == SfxItemState::SET );
4674 : // #i92898#
4675 0 : mbListStyleOrIdReset = true;
4676 : }
4677 : // #i70748#
4678 : // RES_PARATR_OUTLINELEVEL
4679 56710 : else if ( *it == RES_PARATR_OUTLINELEVEL )
4680 : {
4681 0 : mrTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
4682 : }
4683 :
4684 57310 : if ( !bRemoveFromList )
4685 : {
4686 : // RES_PARATR_LIST_LEVEL
4687 115088 : mbUpdateListLevel = mbUpdateListLevel ||
4688 58377 : ( *it == RES_PARATR_LIST_LEVEL &&
4689 58378 : mrTextNode.HasAttrListLevel() );
4690 :
4691 : // RES_PARATR_LIST_ISRESTART and RES_PARATR_LIST_RESTARTVALUE
4692 56710 : mbUpdateListRestart = mbUpdateListRestart ||
4693 56710 : ( *it == RES_PARATR_LIST_ISRESTART &&
4694 113420 : mrTextNode.IsListRestart() ) ||
4695 56710 : ( *it == RES_PARATR_LIST_RESTARTVALUE &&
4696 56710 : mrTextNode.HasAttrListRestartValue() );
4697 :
4698 : // RES_PARATR_LIST_ISCOUNTED
4699 113420 : mbUpdateListCount = mbUpdateListCount ||
4700 56710 : ( *it == RES_PARATR_LIST_ISCOUNTED &&
4701 56710 : !mrTextNode.IsCountedInList() );
4702 : }
4703 : }
4704 : }
4705 :
4706 4511 : if ( bRemoveFromList && mrTextNode.IsInList() )
4707 : {
4708 600 : mrTextNode.RemoveFromList();
4709 : }
4710 4511 : }
4711 :
4712 7499 : HandleResetAttrAtTextNode::HandleResetAttrAtTextNode( SwTextNode& rTextNode )
4713 : : mrTextNode( rTextNode ),
4714 : mbListStyleOrIdReset( false ),
4715 : mbUpdateListLevel( false ),
4716 : mbUpdateListRestart( false ),
4717 7499 : mbUpdateListCount( false )
4718 : {
4719 7499 : mbListStyleOrIdReset = true;
4720 7499 : if ( rTextNode.IsInList() )
4721 : {
4722 440 : rTextNode.RemoveFromList();
4723 : }
4724 : // #i70748#
4725 7499 : mrTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
4726 7499 : }
4727 :
4728 206840 : HandleResetAttrAtTextNode::~HandleResetAttrAtTextNode()
4729 : {
4730 206840 : if ( mbListStyleOrIdReset && !mrTextNode.IsInList() )
4731 : {
4732 : // check, if in spite of the reset of the list style or the list id
4733 : // the paragraph still has to be added to a list.
4734 52173 : if (mrTextNode.GetNumRule() && !mrTextNode.GetListId().isEmpty())
4735 : {
4736 : // #i96062#
4737 : // If paragraph has no list level attribute set and list style
4738 : // is the outline style, apply outline level as the list level.
4739 3566 : if ( !mrTextNode.HasAttrListLevel() &&
4740 3696 : mrTextNode.GetNumRule()->GetName()==SwNumRule::GetOutlineRuleName() &&
4741 282 : mrTextNode.GetTextColl()->IsAssignedToListLevelOfOutlineStyle() )
4742 : {
4743 282 : int nNewListLevel = mrTextNode.GetTextColl()->GetAssignedOutlineStyleLevel();
4744 282 : if ( 0 <= nNewListLevel && nNewListLevel < MAXLEVEL )
4745 : {
4746 282 : mrTextNode.SetAttrListLevel( nNewListLevel );
4747 : }
4748 : }
4749 645 : mrTextNode.AddToList();
4750 : }
4751 : // #i70748#
4752 : // #i105562#
4753 56183 : else if ( mrTextNode.GetpSwAttrSet() &&
4754 4655 : dynamic_cast<const SfxUInt16Item &>(mrTextNode.GetAttr( RES_PARATR_OUTLINELEVEL, false )).GetValue() > 0 )
4755 : {
4756 5 : mrTextNode.SetEmptyListStyleDueToSetOutlineLevelAttr();
4757 : }
4758 : }
4759 :
4760 206840 : if ( mrTextNode.IsInList() )
4761 : {
4762 4088 : if ( mbUpdateListLevel )
4763 : {
4764 440 : SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTextNode.GetNum());
4765 440 : pNodeNum->SetLevelInListTree( mrTextNode.GetAttrListLevel() );
4766 : }
4767 :
4768 4088 : if ( mbUpdateListRestart )
4769 : {
4770 0 : SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTextNode.GetNum());
4771 0 : pNodeNum->InvalidateMe();
4772 0 : pNodeNum->NotifyInvalidSiblings();
4773 : }
4774 :
4775 4088 : if ( mbUpdateListCount )
4776 : {
4777 0 : SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTextNode.GetNum());
4778 0 : pNodeNum->InvalidateAndNotifyTree();
4779 : }
4780 : }
4781 206840 : }
4782 : // End of class <HandleResetAttrAtTextNode>
4783 : }
4784 :
4785 194830 : bool SwTextNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
4786 : {
4787 194830 : const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
4788 194830 : mbInSetOrResetAttr = true;
4789 :
4790 194830 : HandleResetAttrAtTextNode aHandleResetAttr( *this, nWhich1, nWhich2 );
4791 :
4792 194830 : bool bRet = SwContentNode::ResetAttr( nWhich1, nWhich2 );
4793 :
4794 194830 : mbInSetOrResetAttr = bOldIsSetOrResetAttr;
4795 :
4796 194830 : return bRet;
4797 : }
4798 :
4799 4511 : bool SwTextNode::ResetAttr( const std::vector<sal_uInt16>& rWhichArr )
4800 : {
4801 4511 : const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
4802 4511 : mbInSetOrResetAttr = true;
4803 :
4804 4511 : HandleResetAttrAtTextNode aHandleResetAttr( *this, rWhichArr );
4805 :
4806 4511 : bool bRet = SwContentNode::ResetAttr( rWhichArr );
4807 :
4808 4511 : mbInSetOrResetAttr = bOldIsSetOrResetAttr;
4809 :
4810 4511 : return bRet;
4811 : }
4812 :
4813 7499 : sal_uInt16 SwTextNode::ResetAllAttr()
4814 : {
4815 7499 : const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
4816 7499 : mbInSetOrResetAttr = true;
4817 :
4818 7499 : HandleResetAttrAtTextNode aHandleResetAttr( *this );
4819 :
4820 7499 : const sal_uInt16 nRet = SwContentNode::ResetAllAttr();
4821 :
4822 7499 : mbInSetOrResetAttr = bOldIsSetOrResetAttr;
4823 :
4824 7499 : return nRet;
4825 : }
4826 :
4827 0 : void SwTextNode::dumpAsXml(xmlTextWriterPtr pWriter) const
4828 : {
4829 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("swTextNode"));
4830 0 : xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
4831 0 : xmlTextWriterWriteAttribute(pWriter, BAD_CAST("index"), BAD_CAST(OString::number(GetIndex()).getStr()));
4832 :
4833 0 : OUString sText = GetText();
4834 0 : for (int i = 0; i < 32; ++i)
4835 0 : sText = sText.replace(i, '*');
4836 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("m_Text"));
4837 0 : xmlTextWriterWriteString(pWriter, BAD_CAST(sText.toUtf8().getStr()));
4838 0 : xmlTextWriterEndElement(pWriter);
4839 :
4840 0 : if (GetFormatColl())
4841 : {
4842 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("swTextFormatColl"));
4843 0 : xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(GetFormatColl()->GetName().toUtf8().getStr()));
4844 0 : xmlTextWriterEndElement(pWriter);
4845 : }
4846 :
4847 0 : if (HasSwAttrSet())
4848 : {
4849 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("swAttrSet"));
4850 0 : GetSwAttrSet().dumpAsXml(pWriter);
4851 0 : xmlTextWriterEndElement(pWriter);
4852 : }
4853 :
4854 0 : if (HasHints())
4855 : {
4856 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("swpHints"));
4857 0 : const SwpHints& rHints = GetSwpHints();
4858 0 : for (size_t i = 0; i < rHints.Count(); ++i)
4859 0 : rHints.GetTextHint(i)->dumpAsXml(pWriter);
4860 0 : xmlTextWriterEndElement(pWriter);
4861 : }
4862 :
4863 0 : if (GetNumRule())
4864 0 : GetNumRule()->dumpAsXml(pWriter);
4865 :
4866 0 : xmlTextWriterEndElement(pWriter);
4867 0 : }
4868 :
4869 0 : sal_uInt32 SwTextNode::GetRsid( sal_Int32 nStt, sal_Int32 nEnd ) const
4870 : {
4871 0 : SfxItemSet aSet( (SfxItemPool&) (GetDoc()->GetAttrPool()), RES_CHRATR_RSID, RES_CHRATR_RSID );
4872 0 : if ( GetAttr(aSet, nStt, nEnd) )
4873 : {
4874 0 : const SvxRsidItem* pRsid = static_cast<const SvxRsidItem*>(aSet.GetItem(RES_CHRATR_RSID));
4875 0 : if( pRsid )
4876 0 : return pRsid->GetValue();
4877 : }
4878 :
4879 0 : return 0;
4880 : }
4881 :
4882 316 : sal_uInt32 SwTextNode::GetParRsid() const
4883 : {
4884 316 : return reinterpret_cast<const SvxRsidItem&>(GetAttr( RES_PARATR_RSID )).GetValue();
4885 : }
4886 :
4887 0 : bool SwTextNode::CompareParRsid( const SwTextNode &rTextNode ) const
4888 : {
4889 0 : sal_uInt32 nThisRsid = GetParRsid();
4890 0 : sal_uInt32 nRsid = rTextNode.GetParRsid();
4891 :
4892 0 : return nThisRsid == nRsid;
4893 : }
4894 :
4895 0 : bool SwTextNode::CompareRsid( const SwTextNode &rTextNode, sal_Int32 nStt1, sal_Int32 nStt2,
4896 : sal_Int32 nEnd1, sal_Int32 nEnd2 ) const
4897 :
4898 : {
4899 0 : sal_uInt32 nThisRsid = GetRsid( nStt1, nEnd1 ? nEnd1 : nStt1 );
4900 0 : sal_uInt32 nRsid = rTextNode.GetRsid( nStt2, nEnd2 ? nEnd2 : nStt2 );
4901 :
4902 0 : return nThisRsid == nRsid;
4903 : }
4904 :
4905 : // sw::Metadatable
4906 124 : ::sfx2::IXmlIdRegistry& SwTextNode::GetRegistry()
4907 : {
4908 124 : return GetDoc()->GetXmlIdRegistry();
4909 : }
4910 :
4911 3823 : bool SwTextNode::IsInClipboard() const
4912 : {
4913 3823 : return GetDoc()->IsClipBoard();
4914 : }
4915 :
4916 3833 : bool SwTextNode::IsInUndo() const
4917 : {
4918 3833 : return GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(GetNodes());
4919 : }
4920 :
4921 158 : bool SwTextNode::IsInContent() const
4922 : {
4923 158 : return !GetDoc()->IsInHeaderFooter( SwNodeIndex(*this) );
4924 : }
4925 :
4926 232577 : void SwTextNode::SwClientNotify( const SwModify& rModify, const SfxHint& rHint )
4927 : {
4928 232577 : SwClient::SwClientNotify(rModify, rHint);
4929 232577 : const SwAttrHint* pHint = dynamic_cast<const SwAttrHint*>(&rHint);
4930 232577 : if ( pHint && pHint->GetId() == RES_CONDTXTFMTCOLL && &rModify == GetRegisteredIn() )
4931 126 : ChkCondColl();
4932 232577 : }
4933 :
4934 : #include <unoparagraph.hxx>
4935 :
4936 : uno::Reference< rdf::XMetadatable >
4937 1 : SwTextNode::MakeUnoObject()
4938 : {
4939 : const uno::Reference<rdf::XMetadatable> xMeta(
4940 1 : SwXParagraph::CreateXParagraph(*GetDoc(), this), uno::UNO_QUERY);
4941 1 : return xMeta;
4942 : }
4943 :
4944 : //UUUU
4945 81581 : drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwTextNode::getSdrAllFillAttributesHelper() const
4946 : {
4947 : // create SdrAllFillAttributesHelper on demand
4948 81581 : if(!maFillAttributes.get())
4949 : {
4950 30098 : const_cast< SwTextNode* >(this)->maFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(GetSwAttrSet()));
4951 : }
4952 :
4953 81581 : return maFillAttributes;
4954 177 : }
4955 :
4956 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|