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