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