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