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