LibreOffice Module sw (master)  1
doctxm.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <limits.h>
21 #include <hintids.hxx>
23 #include <comphelper/classids.hxx>
24 #include <o3tl/string_view.hxx>
25 #include <docsh.hxx>
26 #include <ndole.hxx>
27 #include <txttxmrk.hxx>
28 #include <fmtpdsc.hxx>
29 #include <frmatr.hxx>
30 #include <pagedesc.hxx>
31 #include <doc.hxx>
32 #include <IDocumentUndoRedo.hxx>
36 #include <IDocumentState.hxx>
39 #include <pagefrm.hxx>
40 #include <ndtxt.hxx>
41 #include <swtable.hxx>
42 #include <doctxm.hxx>
43 #include <txmsrt.hxx>
44 #include <rolbck.hxx>
45 #include <poolfmt.hxx>
46 #include <txtfrm.hxx>
47 #include <rootfrm.hxx>
48 #include <UndoAttribute.hxx>
49 #include <UndoSection.hxx>
50 #include <swundo.hxx>
51 #include <mdiexp.hxx>
52 #include <docary.hxx>
53 #include <charfmt.hxx>
54 #include <fchrfmt.hxx>
55 #include <fldbas.hxx>
56 #include <fmtfld.hxx>
57 #include <txtfld.hxx>
58 #include <expfld.hxx>
59 #include <mvsave.hxx>
60 #include <node2lay.hxx>
61 #include <SwStyleNameMapper.hxx>
62 #include <breakit.hxx>
63 #include <calbck.hxx>
64 #include <ToxTextGenerator.hxx>
66 #include <frameformats.hxx>
67 #include <tools/datetimeutils.hxx>
68 #include <tools/globname.hxx>
69 #include <com/sun/star/embed/XEmbeddedObject.hpp>
70 #include <o3tl/safeint.hxx>
71 #include <osl/diagnose.h>
72 
73 #include <memory>
74 
75 using namespace ::com::sun::star;
76 
77 template<typename T, typename... Args> static
78 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
79 MakeSwTOXSortTabBase(SwRootFrame const*const pLayout, Args&& ... args)
80 {
81  std::unique_ptr<T> pRet(new T(std::forward<Args>(args)...));
82  pRet->InitText(pLayout); // ensure it's expanded with the layout
83  return pRet;
84 }
85 
86 void SwDoc::GetTOIKeys(SwTOIKeyType eTyp, std::vector<OUString>& rArr,
87  SwRootFrame const& rLayout) const
88 {
89  rArr.clear();
90 
91  // Look up all Primary and Secondary via the Pool
92  for (const SfxPoolItem* pPoolItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK))
93  {
94  const SwTOXMark* pItem = dynamic_cast<const SwTOXMark*>(pPoolItem);
95  if( !pItem )
96  continue;
97  const SwTOXType* pTOXType = pItem->GetTOXType();
98  if ( !pTOXType || pTOXType->GetType()!=TOX_INDEX )
99  continue;
100  const SwTextTOXMark* pMark = pItem->GetTextTOXMark();
101  if ( pMark && pMark->GetpTextNd() &&
102  pMark->GetpTextNd()->GetNodes().IsDocNodes() &&
103  (!rLayout.IsHideRedlines()
104  || !sw::IsMarkHintHidden(rLayout, *pMark->GetpTextNd(), *pMark)))
105  {
106  const OUString sStr = TOI_PRIMARY == eTyp
107  ? pItem->GetPrimaryKey()
108  : pItem->GetSecondaryKey();
109 
110  if( !sStr.isEmpty() )
111  rArr.push_back( sStr );
112  }
113  }
114 }
115 
117 sal_uInt16 SwDoc::GetCurTOXMark( const SwPosition& rPos,
118  SwTOXMarks& rArr )
119 {
120  // search on Position rPos for all SwTOXMarks
121  SwTextNode *const pTextNd = rPos.nNode.GetNode().GetTextNode();
122  if( !pTextNd || !pTextNd->GetpSwpHints() )
123  return 0;
124 
125  const SwpHints & rHts = *pTextNd->GetpSwpHints();
126  sal_Int32 nSttIdx;
127  const sal_Int32 *pEndIdx;
128 
129  const sal_Int32 nCurrentPos = rPos.nContent.GetIndex();
130 
131  for( size_t n = 0; n < rHts.Count(); ++n )
132  {
133  const SwTextAttr* pHt = rHts.Get(n);
134  if( RES_TXTATR_TOXMARK != pHt->Which() )
135  continue;
136  if( ( nSttIdx = pHt->GetStart() ) < nCurrentPos )
137  {
138  // also check the end
139  pEndIdx = pHt->End();
140  if( nullptr == pEndIdx || *pEndIdx <= nCurrentPos )
141  continue; // keep searching
142  }
143  else if( nSttIdx > nCurrentPos )
144  // If Hint's Start is greater than rPos, break, because
145  // the attributes are sorted by Start!
146  break;
147 
148  SwTOXMark* pTMark = const_cast<SwTOXMark*>(&pHt->GetTOXMark());
149  rArr.push_back( pTMark );
150  }
151  return rArr.size();
152 }
153 
155 void SwDoc::DeleteTOXMark( const SwTOXMark* pTOXMark )
156 {
157  const SwTextTOXMark* pTextTOXMark = pTOXMark->GetTextTOXMark();
158  assert(pTextTOXMark);
159 
160  SwTextNode& rTextNd = const_cast<SwTextNode&>(pTextTOXMark->GetTextNode());
161  assert(rTextNd.GetpSwpHints());
162 
163  if (pTextTOXMark->HasDummyChar())
164  {
165  // tdf#106377 don't use SwUndoResetAttr, it uses NOTXTATRCHR
166  SwPaM tmp(rTextNd, pTextTOXMark->GetStart(),
167  rTextNd, pTextTOXMark->GetStart()+1);
168  assert(rTextNd.GetText()[pTextTOXMark->GetStart()] == CH_TXTATR_INWORD);
170  }
171  else
172  {
173  std::unique_ptr<SwRegHistory> aRHst;
174  if (GetIDocumentUndoRedo().DoesUndo())
175  {
176  // save attributes for Undo
177  SwUndoResetAttr* pUndo = new SwUndoResetAttr(
178  SwPosition( rTextNd, SwIndex( &rTextNd, pTextTOXMark->GetStart() ) ),
180  GetIDocumentUndoRedo().AppendUndo( std::unique_ptr<SwUndo>(pUndo) );
181 
182  aRHst.reset(new SwRegHistory(rTextNd, &pUndo->GetHistory()));
183  rTextNd.GetpSwpHints()->Register(aRHst.get());
184  }
185 
186  rTextNd.DeleteAttribute( const_cast<SwTextTOXMark*>(pTextTOXMark) );
187 
188  if (GetIDocumentUndoRedo().DoesUndo())
189  {
190  if( rTextNd.GetpSwpHints() )
191  rTextNd.GetpSwpHints()->DeRegister();
192  }
193  }
194 
196 }
197 
198 namespace {
199 
201 class CompareNodeContent
202 {
203  SwNodeOffset m_nNode;
204  sal_Int32 m_nContent;
205 public:
206  CompareNodeContent( SwNodeOffset nNd, sal_Int32 nCnt )
207  : m_nNode( nNd ), m_nContent( nCnt ) {}
208 
209  bool operator==( const CompareNodeContent& rCmp ) const
210  { return m_nNode == rCmp.m_nNode && m_nContent == rCmp.m_nContent; }
211  bool operator!=( const CompareNodeContent& rCmp ) const
212  { return m_nNode != rCmp.m_nNode || m_nContent != rCmp.m_nContent; }
213  bool operator< ( const CompareNodeContent& rCmp ) const
214  { return m_nNode < rCmp.m_nNode ||
215  ( m_nNode == rCmp.m_nNode && m_nContent < rCmp.m_nContent); }
216  bool operator<=( const CompareNodeContent& rCmp ) const
217  { return m_nNode < rCmp.m_nNode ||
218  ( m_nNode == rCmp.m_nNode && m_nContent <= rCmp.m_nContent); }
219  bool operator> ( const CompareNodeContent& rCmp ) const
220  { return m_nNode > rCmp.m_nNode ||
221  ( m_nNode == rCmp.m_nNode && m_nContent > rCmp.m_nContent); }
222  bool operator>=( const CompareNodeContent& rCmp ) const
223  { return m_nNode > rCmp.m_nNode ||
224  ( m_nNode == rCmp.m_nNode && m_nContent >= rCmp.m_nContent); }
225 };
226 
227 }
228 
229 const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark,
230  SwTOXSearch eDir, bool bInReadOnly )
231 {
232  const SwTextTOXMark* pMark = rCurTOXMark.GetTextTOXMark();
233 
234  CompareNodeContent aAbsIdx(pMark ? pMark->GetpTextNd()->GetIndex() : SwNodeOffset(0), pMark ? pMark->GetStart() : 0);
235  CompareNodeContent aPrevPos( SwNodeOffset(0), 0 );
236  CompareNodeContent aNextPos( NODE_OFFSET_MAX, SAL_MAX_INT32 );
237  CompareNodeContent aMax( SwNodeOffset(0), 0 );
238  CompareNodeContent aMin( NODE_OFFSET_MAX, SAL_MAX_INT32 );
239 
240  const SwTOXMark* pNew = nullptr;
241  const SwTOXMark* pMax = &rCurTOXMark;
242  const SwTOXMark* pMin = &rCurTOXMark;
243 
244  const SwTOXType* pType = rCurTOXMark.GetTOXType();
245  SwTOXMarks aMarks;
246  pType->CollectTextMarks(aMarks);
247 
248  for(SwTOXMark* pTOXMark : aMarks)
249  {
250  if ( pTOXMark == &rCurTOXMark )
251  continue;
252 
253  pMark = pTOXMark->GetTextTOXMark();
254  if (!pMark)
255  continue;
256 
257  SwTextNode const*const pTOXSrc = pMark->GetpTextNd();
258  if (!pTOXSrc)
259  continue;
260 
261  Point aPt;
262  std::pair<Point, bool> const tmp(aPt, false);
263  const SwContentFrame* pCFrame = pTOXSrc->getLayoutFrame(
264  getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp);
265  if (!pCFrame)
266  continue;
267 
268  if ( bInReadOnly || !pCFrame->IsProtected() )
269  {
270  CompareNodeContent aAbsNew( pTOXSrc->GetIndex(), pMark->GetStart() );
271  switch( eDir )
272  {
273  // The following (a bit more complicated) statements make it
274  // possible to also travel across Entries on the same (!)
275  // position. If someone has time, please feel free to optimize.
276  case TOX_SAME_PRV:
277  if (pTOXMark->GetText(nullptr) != rCurTOXMark.GetText(nullptr))
278  break;
279  [[fallthrough]];
280  case TOX_PRV:
281  if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos) ||
282  (aAbsIdx == aAbsNew &&
283  (reinterpret_cast<sal_uLong>(&rCurTOXMark) > reinterpret_cast<sal_uLong>(pTOXMark) &&
284  (!pNew || aPrevPos < aAbsIdx || reinterpret_cast<sal_uLong>(pNew) < reinterpret_cast<sal_uLong>(pTOXMark) ) )) ||
285  (aPrevPos == aAbsNew && aAbsIdx != aAbsNew &&
286  reinterpret_cast<sal_uLong>(pTOXMark) > reinterpret_cast<sal_uLong>(pNew)) )
287  {
288  pNew = pTOXMark;
289  aPrevPos = aAbsNew;
290  if ( aAbsNew >= aMax )
291  {
292  aMax = aAbsNew;
293  pMax = pTOXMark;
294  }
295  }
296  break;
297 
298  case TOX_SAME_NXT:
299  if (pTOXMark->GetText(nullptr) != rCurTOXMark.GetText(nullptr))
300  break;
301  [[fallthrough]];
302  case TOX_NXT:
303  if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos) ||
304  (aAbsIdx == aAbsNew &&
305  (reinterpret_cast<sal_uLong>(&rCurTOXMark) < reinterpret_cast<sal_uLong>(pTOXMark) &&
306  (!pNew || aNextPos > aAbsIdx || reinterpret_cast<sal_uLong>(pNew) > reinterpret_cast<sal_uLong>(pTOXMark)) )) ||
307  (aNextPos == aAbsNew && aAbsIdx != aAbsNew &&
308  reinterpret_cast<sal_uLong>(pTOXMark) < reinterpret_cast<sal_uLong>(pNew)) )
309  {
310  pNew = pTOXMark;
311  aNextPos = aAbsNew;
312  if ( aAbsNew <= aMin )
313  {
314  aMin = aAbsNew;
315  pMin = pTOXMark;
316  }
317  }
318  break;
319  }
320  }
321  }
322 
323  // We couldn't find a successor
324  // Use minimum or maximum
325  if(!pNew)
326  {
327  switch(eDir)
328  {
329  case TOX_PRV:
330  case TOX_SAME_PRV:
331  pNew = pMax;
332  break;
333  case TOX_NXT:
334  case TOX_SAME_NXT:
335  pNew = pMin;
336  break;
337  default:
338  pNew = &rCurTOXMark;
339  }
340  }
341  return *pNew;
342 }
343 
345  const SwTOXBase& rTOX,
346  const SfxItemSet* pSet,
347  bool bExpand,
348  SwRootFrame const*const pLayout)
349 {
350  SwPaM aPam( rPos );
351  return InsertTableOf( aPam, rTOX, pSet, bExpand, pLayout );
352 }
353 
355  const SwTOXBase& rTOX,
356  const SfxItemSet* pSet,
357  bool bExpand,
358  SwRootFrame const*const pLayout )
359 {
360  assert(!bExpand || pLayout != nullptr);
362 
363  OUString sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), rTOX.GetTOXName() );
364  SwSectionData aSectionData( SectionType::ToxContent, sSectNm );
365 
366  std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode> const tmp(
367  &rTOX,
368  pLayout && pLayout->IsHideRedlines()
371  pLayout ? pLayout->GetFieldmarkMode() : sw::FieldmarkMode::ShowBoth);
372  SwTOXBaseSection *const pNewSection = dynamic_cast<SwTOXBaseSection *>(
373  InsertSwSection(aPam, aSectionData, & tmp, pSet, false));
374  if (pNewSection)
375  {
376  SwSectionNode *const pSectNd = pNewSection->GetFormat()->GetSectionNode();
377  pNewSection->SetTOXName(sSectNm); // rTOX may have had no name...
378 
379  if( bExpand )
380  {
381  // add value for 2nd parameter = true to
382  // indicate, that a creation of a new table of content has to be performed.
383  // Value of 1st parameter = default value.
384  pNewSection->Update( nullptr, pLayout, true );
385  }
386  else if( rTOX.GetTitle().getLength()==1 && IsInReading() )
387  // insert title of TOX
388  {
389  // then insert the headline section
390  SwNodeIndex aIdx( *pSectNd, +1 );
391 
392  SwTextNode* pHeadNd = GetNodes().MakeTextNode( aIdx,
393  getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ) );
394 
395  SwSectionData headerData( SectionType::ToxHeader, pNewSection->GetTOXName()+"_Head" );
396 
397  SwNodeIndex aStt( *pHeadNd ); --aIdx;
398  SwSectionFormat* pSectFormat = MakeSectionFormat();
400  aStt, *pSectFormat, headerData, nullptr, &aIdx, true, false);
401  }
402  }
403 
405 
406  return pNewSection;
407 }
408 
410  const SwTOXBase& rTOX,
411  const SfxItemSet* pSet )
412 {
413  // check for recursive TOX
414  SwNode* pNd = GetNodes()[ nSttNd ];
415  SwSectionNode* pSectNd = pNd->FindSectionNode();
416  while( pSectNd )
417  {
418  SectionType eT = pSectNd->GetSection().GetType();
420  return;
421  pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
422  }
423 
424  const OUString sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), rTOX.GetTOXName());
425 
426  SwSectionData aSectionData( SectionType::ToxContent, sSectNm );
427 
428  SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd );
429  SwSectionFormat* pFormat = MakeSectionFormat();
430  if(pSet)
431  pFormat->SetFormatAttr(*pSet);
432 
433  SwSectionNode *const pNewSectionNode =
434  GetNodes().InsertTextSection(aStt, *pFormat, aSectionData, &rTOX, &aEnd);
435  if (!pNewSectionNode)
436  {
437  DelSectionFormat( pFormat );
438  return;
439  }
440 
441  SwTOXBaseSection *const pNewSection(
442  dynamic_cast<SwTOXBaseSection*>(& pNewSectionNode->GetSection()));
443  if (pNewSection)
444  pNewSection->SetTOXName(sSectNm); // rTOX may have had no name...
445 }
446 
449 {
450  SwNode& rNd = rPos.nNode.GetNode();
451  SwSectionNode* pSectNd = rNd.FindSectionNode();
452  while( pSectNd )
453  {
454  SectionType eT = pSectNd->GetSection().GetType();
455  if( SectionType::ToxContent == eT )
456  {
457  assert( dynamic_cast< const SwTOXBaseSection *>( &pSectNd->GetSection()) &&
458  "no TOXBaseSection!" );
459  SwTOXBaseSection& rTOXSect = static_cast<SwTOXBaseSection&>(
460  pSectNd->GetSection());
461  return &rTOXSect;
462  }
463  pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
464  }
465  return nullptr;
466 }
467 
469 {
470  assert( dynamic_cast<const SwTOXBaseSection*>( &rTOXBase) && "no TOXBaseSection!" );
471  const SwTOXBaseSection& rTOXSect = static_cast<const SwTOXBaseSection&>(rTOXBase);
472  SwSectionFormat const * pFormat = rTOXSect.GetFormat();
473  OSL_ENSURE( pFormat, "invalid TOXBaseSection!" );
474  return pFormat->GetAttrSet();
475 }
476 
477 const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, bool bCreate )
478 {
479  std::unique_ptr<SwTOXBase>* prBase = nullptr;
480  switch(eTyp)
481  {
482  case TOX_CONTENT: prBase = &mpDefTOXBases->pContBase; break;
483  case TOX_INDEX: prBase = &mpDefTOXBases->pIdxBase; break;
484  case TOX_USER: prBase = &mpDefTOXBases->pUserBase; break;
485  case TOX_TABLES: prBase = &mpDefTOXBases->pTableBase; break;
486  case TOX_OBJECTS: prBase = &mpDefTOXBases->pObjBase; break;
487  case TOX_ILLUSTRATIONS: prBase = &mpDefTOXBases->pIllBase; break;
488  case TOX_AUTHORITIES: prBase = &mpDefTOXBases->pAuthBase; break;
489  case TOX_BIBLIOGRAPHY: prBase = &mpDefTOXBases->pBiblioBase; break;
490  case TOX_CITATION: break;
491  }
492  if (!prBase)
493  return nullptr;
494  if(!(*prBase) && bCreate)
495  {
496  SwForm aForm(eTyp);
497  const SwTOXType* pType = GetTOXType(eTyp, 0);
498  prBase->reset(new SwTOXBase(pType, aForm, SwTOXElement::NONE, pType->GetTypeName()));
499  }
500  return prBase->get();
501 }
502 
504 {
505  std::unique_ptr<SwTOXBase>* prBase = nullptr;
506  switch(rBase.GetType())
507  {
508  case TOX_CONTENT: prBase = &mpDefTOXBases->pContBase; break;
509  case TOX_INDEX: prBase = &mpDefTOXBases->pIdxBase; break;
510  case TOX_USER: prBase = &mpDefTOXBases->pUserBase; break;
511  case TOX_TABLES: prBase = &mpDefTOXBases->pTableBase; break;
512  case TOX_OBJECTS: prBase = &mpDefTOXBases->pObjBase; break;
513  case TOX_ILLUSTRATIONS: prBase = &mpDefTOXBases->pIllBase; break;
514  case TOX_AUTHORITIES: prBase = &mpDefTOXBases->pAuthBase; break;
515  case TOX_BIBLIOGRAPHY: prBase = &mpDefTOXBases->pBiblioBase; break;
516  case TOX_CITATION: break;
517  }
518  if (!prBase)
519  return;
520  prBase->reset(new SwTOXBase(rBase));
521 }
522 
524 bool SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, bool bDelNodes )
525 {
526  // We only delete the TOX, not the Nodes
527  bool bRet = false;
528  assert( dynamic_cast<const SwTOXBaseSection*>( &rTOXBase) && "no TOXBaseSection!" );
529 
530  const SwTOXBaseSection& rTOXSect = static_cast<const SwTOXBaseSection&>(rTOXBase);
531  SwSectionFormat const * pFormat = rTOXSect.GetFormat();
532  /* Save the start node of the TOX' section. */
533  SwSectionNode const * pMyNode = pFormat ? pFormat->GetSectionNode() : nullptr;
534  if (pMyNode)
535  {
537 
538  /* Save start node of section's surrounding. */
539  SwNode const * pStartNd = pMyNode->StartOfSectionNode();
540 
541  /* Look for the point where to move the cursors in the area to
542  delete to. This is done by first searching forward from the
543  end of the TOX' section. If no content node is found behind
544  the TOX one is searched before it. If this is not
545  successful, too, insert new text node behind the end of
546  the TOX' section. The cursors from the TOX' section will be
547  moved to the content node found or the new text node. */
548 
549  /* Set PaM to end of TOX' section and search following content node.
550  aSearchPam will contain the point where to move the cursors
551  to. */
552  SwPaM aSearchPam(*pMyNode->EndOfSectionNode());
553  SwPosition aEndPos(*pStartNd->EndOfSectionNode());
554  if (! aSearchPam.Move() /* no content node found */
555  || *aSearchPam.GetPoint() >= aEndPos /* content node found
556  outside surrounding */
557  )
558  {
559  /* Set PaM to beginning of TOX' section and search previous
560  content node */
561  SwPaM aTmpPam(*pMyNode);
562  aSearchPam = aTmpPam;
563  SwPosition aStartPos(*pStartNd);
564 
565  if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */
566  || *aSearchPam.GetPoint() <= aStartPos /* content node
567  found outside
568  surrounding */
569  )
570  {
571  /* There is no content node in the surrounding of
572  TOX'. Append text node behind TOX' section. */
573 
574  SwPosition aInsPos(*pMyNode->EndOfSectionNode());
576 
577  SwPaM aTmpPam1(aInsPos);
578  aSearchPam = aTmpPam1;
579  }
580  }
581 
582  /* PaM containing the TOX. */
583  SwPaM aPam(*pMyNode->EndOfSectionNode(), *pMyNode);
584 
585  /* Move cursors contained in TOX to the above calculated point. */
586  PaMCorrAbs(aPam, *aSearchPam.GetPoint());
587 
588  if( !bDelNodes )
589  {
590  SwSections aArr( 0 );
591  pFormat->GetChildSections( aArr, SectionSort::Not, false );
592  for( const auto pSect : aArr )
593  {
594  if( SectionType::ToxHeader == pSect->GetType() )
595  {
596  DelSectionFormat( pSect->GetFormat(), bDelNodes );
597  }
598  }
599  }
600 
601  DelSectionFormat( const_cast<SwSectionFormat *>(pFormat), bDelNodes );
602 
604  bRet = true;
605  }
606 
607  return bRet;
608 }
609 
611 sal_uInt16 SwDoc::GetTOXTypeCount(TOXTypes eTyp) const
612 {
613  sal_uInt16 nCnt = 0;
614  for( auto const & pTOXType : *mpTOXTypes )
615  if( eTyp == pTOXType->GetType() )
616  ++nCnt;
617  return nCnt;
618 }
619 
620 const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, sal_uInt16 nId ) const
621 {
622  sal_uInt16 nCnt = 0;
623  for( auto const & pTOXType : *mpTOXTypes )
624  if( eTyp == pTOXType->GetType() && nCnt++ == nId )
625  return pTOXType.get();
626  return nullptr;
627 }
628 
630 {
631  SwTOXType * pNew = new SwTOXType(rTyp);
632  mpTOXTypes->emplace_back( pNew );
633  return pNew;
634 }
635 
636 OUString SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType,
637  const OUString& sChkStr ) const
638 {
639  if( IsInMailMerge())
640  {
641  OUString newName = "MailMergeTOX"
642  + OStringToOUString( DateTimeToOString( DateTime( DateTime::SYSTEM )), RTL_TEXTENCODING_ASCII_US )
643  + OUString::number( mpSectionFormatTable->size() + 1 );
644  if( !sChkStr.isEmpty())
645  newName += sChkStr;
646  return newName;
647  }
648 
649  bool bUseChkStr = !sChkStr.isEmpty();
650  const OUString& aName( rType.GetTypeName() );
651  const sal_Int32 nNmLen = aName.getLength();
652 
654  const SwSectionFormats::size_type nFlagSize = ( mpSectionFormatTable->size() / 8 ) +2;
655  std::unique_ptr<sal_uInt8[]> pSetFlags(new sal_uInt8[ nFlagSize ]);
656  memset( pSetFlags.get(), 0, nFlagSize );
657 
658  for( auto pSectionFormat : *mpSectionFormatTable )
659  {
660  const SwSectionNode *pSectNd = pSectionFormat->GetSectionNode();
661  if ( !pSectNd )
662  continue;
663 
664  const SwSection& rSect = pSectNd->GetSection();
665  if (rSect.GetType()==SectionType::ToxContent)
666  {
667  const OUString& rNm = rSect.GetSectionName();
668  if ( rNm.startsWith(aName) )
669  {
670  // Calculate number and set the Flag
671  nNum = o3tl::toInt32(rNm.subView( nNmLen ));
672  if( nNum-- && nNum < mpSectionFormatTable->size() )
673  pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
674  }
675  if ( bUseChkStr && sChkStr==rNm )
676  bUseChkStr = false;
677  }
678  }
679 
680  if( !bUseChkStr )
681  {
682  // All Numbers have been flagged accordingly, so get the right Number
683  nNum = mpSectionFormatTable->size();
684  for( SwSectionFormats::size_type n = 0; n < nFlagSize; ++n )
685  {
686  sal_uInt8 nTmp = pSetFlags[ n ];
687  if( nTmp != 0xff )
688  {
689  // so get the Number
690  nNum = n * 8;
691  while( nTmp & 1 )
692  {
693  ++nNum;
694  nTmp >>= 1;
695  }
696  break;
697  }
698  }
699  }
700  if ( bUseChkStr )
701  return sChkStr;
702  return aName + OUString::number( ++nNum );
703 }
704 
705 bool SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const OUString& rName)
706 {
707  assert( dynamic_cast<const SwTOXBaseSection*>( &rTOXBase) && "no TOXBaseSection!" );
708  SwTOXBaseSection* pTOX = const_cast<SwTOXBaseSection*>(static_cast<const SwTOXBaseSection*>(&rTOXBase));
709 
710  if (GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), rName) == rName)
711  {
712  pTOX->SetTOXName(rName);
713  pTOX->SetSectionName(rName);
715  return true;
716  }
717  return false;
718 }
719 
720 static const SwTextNode* lcl_FindChapterNode( const SwNode& rNd,
721  SwRootFrame const*const pLayout, sal_uInt8 const nLvl = 0 )
722 {
723  const SwNode* pNd = &rNd;
724  if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() )
725  {
726  // then find the "Anchor" (Body) position
727  Point aPt;
728  SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() );
729  const SwFrame* pFrame = aNode2Layout.GetFrame( &aPt );
730 
731  if( pFrame )
732  {
733  SwPosition aPos( *pNd );
734  pNd = GetBodyTextNode( pNd->GetDoc(), aPos, *pFrame );
735  OSL_ENSURE( pNd, "Where's the paragraph?" );
736  }
737  }
738  return pNd ? pNd->FindOutlineNodeOfLevel(nLvl, pLayout) : nullptr;
739 }
740 
741 static bool IsHeadingContained(const SwTextNode* pChptrNd, const SwNode& rNd)
742 {
743  const SwNode* pNd = &rNd;
744  const SwOutlineNodes& rONds = pNd->GetNodes().GetOutLineNds();
745  bool bIsHeadingContained = false;
746  if (!rONds.empty())
747  {
748  bool bCheckFirst = false;
750 
751  if (!rONds.Seek_Entry(const_cast<SwNode*>(pNd), &nPos))
752  {
753  if (nPos == 0)
754  bCheckFirst = true;
755  else
756  nPos--;
757  }
758 
759  if (bCheckFirst)
760  {
761  const SwContentNode* pCNd = pNd->GetContentNode();
762 
763  Point aPt(0, 0);
764  std::pair<Point, bool> const tmp(aPt, false);
765 
766  const SwFrame* pChptrFrame = pChptrNd ? pChptrNd->getLayoutFrame(
767  pChptrNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp) : nullptr;
768  const SwPageFrame* pChptrPgFrame = pChptrFrame ? pChptrFrame->FindPageFrame() : nullptr;
769  const SwFrame* pNdFrame
770  = pCNd ? pCNd->getLayoutFrame(
771  pCNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp)
772  : nullptr;
773 
774  // Check if the one asking doesn't precede the page of the specified chapter note
775  bIsHeadingContained
776  = pNdFrame && pChptrPgFrame
777  && pChptrPgFrame->getFrameArea().Top() <= pNdFrame->getFrameArea().Top();
778  // Check if the one asking doesn't succeed the specified chapter note
779  if (bIsHeadingContained)
780  {
781  const SwNode* aChptrNd = pChptrNd;
782  if (!rONds.Seek_Entry(const_cast<SwNode*>(aChptrNd), &nPos) && nPos)
783  nPos--;
784  // Search for the next outline node with a larger level than the specified chapter node
785  while (nPos < rONds.size() - 1
786  && pChptrNd->GetAttrOutlineLevel()
787  < rONds[nPos + 1]->GetTextNode()->GetAttrOutlineLevel())
788  nPos++;
789  // If there exists such an outline node, check if the one asking doesn't succeed
790  // the specified chapter node
791  if (nPos < rONds.size() - 1) {
792  nPos++;
793  const auto aONdsTxtNd = rONds[nPos]->GetTextNode();
794  pChptrFrame = aONdsTxtNd->getLayoutFrame(
795  aONdsTxtNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr,
796  &tmp);
797  pChptrPgFrame = pChptrFrame ? pChptrFrame->FindPageFrame() : nullptr;
798  bIsHeadingContained
799  = pNdFrame && pChptrPgFrame
800  && pChptrPgFrame->getFrameArea().Top() >= pNdFrame->getFrameArea().Top();
801  }
802  }
803  }
804  else
805  {
806  // Search for the next outline node which lies not within the current chapter node
807  while (pChptrNd->GetAttrOutlineLevel()
808  < rONds[nPos]->GetTextNode()->GetAttrOutlineLevel())
809  nPos--;
810  bIsHeadingContained = pChptrNd == rONds[nPos]->GetTextNode();
811  }
812  }
813  else
814  {
815  // If there are no outline nodes, consider the heading contained,
816  // otherwise the _XDocumentIndex._update() test fails
817  bIsHeadingContained = true;
818  }
819  return bIsHeadingContained;
820 }
821 
822 // Table of contents class
824  : SwTOXBase( rBase )
825  , SwSection( SectionType::ToxContent, OUString(), rFormat )
826 {
827  SetProtect( rBase.IsProtected() );
829 }
830 
832 {
833 }
834 
836 {
837  bool bRet = false;
838  const SwSectionNode* pSectNd = GetFormat()->GetSectionNode();
839  if( pSectNd )
840  {
841  rPos.nNode = *pSectNd;
842  SwContentNode* pCNd = pSectNd->GetDoc().GetNodes().GoNext( &rPos.nNode );
843  rPos.nContent.Assign( pCNd, 0 );
844  bRet = true;
845  }
846  return bRet;
847 }
848 
851  SwRootFrame const*const pLayout,
852  const bool _bNewTOX)
853 {
854  if (!GetFormat())
855  return;
856  SwSectionNode const*const pSectNd(GetFormat()->GetSectionNode());
857  if (nullptr == pSectNd ||
858  !pSectNd->GetNodes().IsDocNodes() ||
859  IsHiddenFlag() ||
860  (pLayout->HasMergedParas() && pSectNd->GetRedlineMergeFlag() == SwNode::Merge::Hidden))
861  {
862  return;
863  }
864 
865  if ( !mbKeepExpression )
866  {
867  maMSTOCExpression.clear();
868  }
869 
870  SwDoc& rDoc = const_cast<SwDoc&>(pSectNd->GetDoc());
871 
872  if (pAttr && GetFormat())
873  rDoc.ChgFormat(*GetFormat(), *pAttr);
874 
875  // determine default page description, which will be used by the content nodes,
876  // if no appropriate one is found.
877  const SwPageDesc* pDefaultPageDesc;
878  {
879  pDefaultPageDesc =
880  pSectNd->GetSection().GetFormat()->GetPageDesc().GetPageDesc();
881  if ( !_bNewTOX && !pDefaultPageDesc )
882  {
883  // determine page description of table-of-content
884  SwNodeOffset nPgDescNdIdx = pSectNd->GetIndex() + 1;
885  SwNodeOffset* pPgDescNdIdx = &nPgDescNdIdx;
886  pDefaultPageDesc = pSectNd->FindPageDesc( pPgDescNdIdx );
887  if ( nPgDescNdIdx < pSectNd->GetIndex() )
888  {
889  pDefaultPageDesc = nullptr;
890  }
891  }
892  // consider end node of content section in the node array.
893  if ( !pDefaultPageDesc &&
894  ( pSectNd->EndOfSectionNode()->GetIndex() <
895  (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) )
896  )
897  {
898  // determine page description of content after table-of-content
899  SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) );
900  const SwContentNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx );
901  const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet();
902  const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak();
903  if ( eBreak != SvxBreak::PageBefore && eBreak != SvxBreak::PageBoth )
904  {
905  pDefaultPageDesc = pNdAfterTOX->FindPageDesc();
906  }
907  }
908  // consider start node of content section in the node array.
909  if ( !pDefaultPageDesc &&
910  ( pSectNd->GetIndex() >
911  (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) )
912  )
913  {
914  // determine page description of content before table-of-content
915  SwNodeIndex aIdx( *pSectNd );
916  pDefaultPageDesc =
917  SwNodes::GoPrevious( &aIdx )->FindPageDesc();
918 
919  }
920  if ( !pDefaultPageDesc )
921  {
922  // determine default page description
923  pDefaultPageDesc = &rDoc.GetPageDesc( 0 );
924  }
925  }
926 
928 
929  // get current Language
931  TOX_INDEX == GetTOXType()->GetType() ?
933  GetSortAlgorithm() );
934 
935  m_aSortArr.clear();
936 
937  // find the first layout node for this TOX, if it only find the content
938  // in his own chapter
939  const SwSectionNode* pChapterSectNd = IsFromChapter() ? pSectNd->FindSectionNode() : nullptr;
940  const SwTextNode* pOwnChapterNode = pChapterSectNd
941  ? ::lcl_FindChapterNode( *pSectNd, pLayout, pChapterSectNd->GetSectionLevel() + 1 )
942  : nullptr;
943 
944  SwNode2LayoutSaveUpperFrames aN2L(*pSectNd);
945  const_cast<SwSectionNode*>(pSectNd)->DelFrames();
946 
947  // This would be a good time to update the Numbering
948  rDoc.UpdateNumRule();
949 
951  UpdateMarks( aIntl, pOwnChapterNode, pLayout );
952 
954  UpdateOutline( pOwnChapterNode, pLayout );
955 
957  UpdateTemplate( pOwnChapterNode, pLayout );
958 
961  UpdateContent( SwTOXElement::Ole, pOwnChapterNode, pLayout );
962 
965  UpdateTable( pOwnChapterNode, pLayout );
966 
969  UpdateContent( SwTOXElement::Graphic, pOwnChapterNode, pLayout );
970 
971  if( !GetSequenceName().isEmpty() && !IsFromObjectNames() &&
974  UpdateSequence( pOwnChapterNode, pLayout );
975 
977  UpdateContent( SwTOXElement::Frame, pOwnChapterNode, pLayout );
978 
980  UpdateAuthorities( aIntl, pLayout );
981 
982  // Insert AlphaDelimiters if needed (just for keywords)
983  if( TOX_INDEX == SwTOXBase::GetType() &&
985  InsertAlphaDelimiter( aIntl );
986 
987  // remove old content an insert one empty textnode (to hold the layout!)
988  SwTextNode* pFirstEmptyNd;
989 
990  SwUndoUpdateIndex * pUndo(nullptr);
991  {
992  rDoc.getIDocumentRedlineAccess().DeleteRedline( *pSectNd, true, RedlineType::Any );
993 
994  SwNodeIndex aSttIdx( *pSectNd, +1 );
995  SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
996  pFirstEmptyNd = rDoc.GetNodes().MakeTextNode( aEndIdx,
998 
999  {
1000  // Task 70995 - save and restore PageDesc and Break Attributes
1001  SwNodeIndex aNxtIdx( aSttIdx );
1002  const SwContentNode* pCNd = aNxtIdx.GetNode().GetContentNode();
1003  if( !pCNd )
1004  pCNd = rDoc.GetNodes().GoNext( &aNxtIdx );
1005  assert(pCNd != pFirstEmptyNd);
1006  assert(pCNd->GetIndex() < pFirstEmptyNd->GetIndex());
1007  if( pCNd->HasSwAttrSet() )
1008  {
1009  SfxItemSet aBrkSet( rDoc.GetAttrPool(), aBreakSetRange );
1010  aBrkSet.Put( *pCNd->GetpSwAttrSet() );
1011  if( aBrkSet.Count() )
1012  pFirstEmptyNd->SetAttr( aBrkSet );
1013  }
1014  }
1015 
1016  if (rDoc.GetIDocumentUndoRedo().DoesUndo())
1017  {
1018  // note: this will first append a SwUndoDelSection from the ctor...
1019  pUndo = new SwUndoUpdateIndex(*this);
1020  // tdf#123313 insert Undo *after* all CrossRefBookmark Undos have
1021  // been inserted by the Update*() functions
1022  rDoc.GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndoUpdateIndex>(pUndo));
1023  }
1024  else
1025  {
1026  --aEndIdx;
1027  SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 ));
1028  SwDoc::CorrAbs( aSttIdx, aEndIdx, aPos, true );
1029 
1030  // delete flys in whole range including start node which requires
1031  // giving the node before start node as Mark parameter, hence -1.
1032  // (flys must be deleted because the anchor nodes are removed)
1033  DelFlyInRange( SwNodeIndex(aSttIdx, -1), aEndIdx );
1034 
1035  rDoc.GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() );
1036  }
1037  }
1038 
1039  // insert title of TOX
1040  if ( !GetTitle().isEmpty() )
1041  {
1042  // then insert the headline section
1043  SwNodeIndex aIdx( *pSectNd, +1 );
1044 
1045  SwTextNode* pHeadNd = rDoc.GetNodes().MakeTextNode( aIdx,
1047  pHeadNd->InsertText( GetTitle(), SwIndex( pHeadNd ) );
1048 
1049  SwSectionData headerData( SectionType::ToxHeader, GetTOXName()+"_Head" );
1050 
1051  SwNodeIndex aStt( *pHeadNd ); --aIdx;
1052  SwSectionFormat* pSectFormat = rDoc.MakeSectionFormat();
1053  rDoc.GetNodes().InsertTextSection(
1054  aStt, *pSectFormat, headerData, nullptr, &aIdx, true, false);
1055 
1056  if (pUndo)
1057  {
1058  pUndo->TitleSectionInserted(*pSectFormat);
1059  }
1060  }
1061 
1062  // Sort the List of all TOC Marks and TOC Sections
1063  std::vector<SwTextFormatColl*> aCollArr( GetTOXForm().GetFormMax(), nullptr );
1064  std::unordered_map<OUString, int> markURLs;
1065  SwNodeIndex aInsPos( *pFirstEmptyNd, 1 );
1066  for( size_t nCnt = 0; nCnt < m_aSortArr.size(); ++nCnt )
1067  {
1068  ::SetProgressState( 0, rDoc.GetDocShell() );
1069 
1070  // Put the Text into the TOC
1071  sal_uInt16 nLvl = m_aSortArr[ nCnt ]->GetLevel();
1072  SwTextFormatColl* pColl = aCollArr[ nLvl ];
1073  if( !pColl )
1074  {
1075  pColl = GetTextFormatColl( nLvl );
1076  aCollArr[ nLvl ] = pColl;
1077  }
1078 
1079  // Generate: Set dynamic TabStops
1080  SwTextNode* pTOXNd = rDoc.GetNodes().MakeTextNode( aInsPos , pColl );
1081  m_aSortArr[ nCnt ]->pTOXNd = pTOXNd;
1082 
1083  // Generate: Evaluate Form and insert the place holder for the
1084  // page number. If it is a TOX_INDEX and the SwForm IsCommaSeparated()
1085  // then a range of entries must be generated into one paragraph
1086  size_t nRange = 1;
1087  if(TOX_INDEX == SwTOXBase::GetType() &&
1088  GetTOXForm().IsCommaSeparated() &&
1089  m_aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
1090  {
1091  const SwTOXMark& rMark = m_aSortArr[nCnt]->pTextMark->GetTOXMark();
1092  const OUString& sPrimKey = rMark.GetPrimaryKey();
1093  const OUString& sSecKey = rMark.GetSecondaryKey();
1094  const SwTOXMark* pNextMark = nullptr;
1095  while(m_aSortArr.size() > (nCnt + nRange) &&
1096  m_aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX )
1097  {
1098  pNextMark = &(m_aSortArr[nCnt + nRange]->pTextMark->GetTOXMark());
1099  if( !pNextMark ||
1100  pNextMark->GetPrimaryKey() != sPrimKey ||
1101  pNextMark->GetSecondaryKey() != sSecKey)
1102  break;
1103  nRange++;
1104  }
1105  }
1106  // pass node index of table-of-content section and default page description
1107  // to method <GenerateText(..)>.
1108  ::SetProgressState( 0, rDoc.GetDocShell() );
1109 
1110  std::shared_ptr<sw::ToxTabStopTokenHandler> tabStopTokenHandler =
1111  std::make_shared<sw::DefaultToxTabStopTokenHandler>(
1112  pSectNd->GetIndex(), *pDefaultPageDesc, GetTOXForm().IsRelTabPos(),
1116  sw::ToxTextGenerator ttgn(GetTOXForm(), tabStopTokenHandler);
1117  ttgn.GenerateText(GetFormat()->GetDoc(), markURLs, m_aSortArr, nCnt, nRange, pLayout);
1118  nCnt += nRange - 1;
1119  }
1120 
1121  // delete the first dummy node and remove all Cursor into the previous node
1122  aInsPos = *pFirstEmptyNd;
1123  {
1124  SwPaM aCorPam( *pFirstEmptyNd );
1125  aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 );
1126  if( !aCorPam.Move( fnMoveForward ) )
1127  aCorPam.Move( fnMoveBackward );
1128  SwNodeIndex aEndIdx( aInsPos, 1 );
1129  SwDoc::CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), true );
1130 
1131  // Task 70995 - save and restore PageDesc and Break Attributes
1132  if( pFirstEmptyNd->HasSwAttrSet() )
1133  {
1134  if( !GetTitle().isEmpty() )
1135  aEndIdx = *pSectNd;
1136  else
1137  aEndIdx = *pFirstEmptyNd;
1138  SwContentNode* pCNd = rDoc.GetNodes().GoNext( &aEndIdx );
1139  if( pCNd ) // Robust against defect documents, e.g. i60336
1140  pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() );
1141  }
1142  }
1143 
1144  // now create the new Frames
1145  SwNodeOffset nIdx = pSectNd->GetIndex();
1146  // don't delete if index is empty
1147  if(nIdx + SwNodeOffset(2) < pSectNd->EndOfSectionIndex())
1148  rDoc.GetNodes().Delete( aInsPos );
1149 
1150  aN2L.RestoreUpperFrames( rDoc.GetNodes(), nIdx, nIdx + 1 );
1151  o3tl::sorted_vector<SwRootFrame*> aAllLayouts = rDoc.GetAllLayouts();
1152  for ( const auto& rpLayout : aAllLayouts )
1153  {
1154  SwFrame::CheckPageDescs( static_cast<SwPageFrame*>(rpLayout->Lower()) );
1155  }
1156 
1158 }
1159 
1161 {
1162  SwDoc* pDoc = GetFormat()->GetDoc();
1163  OUString sLastDeli;
1164  size_t i = 0;
1165  while( i < m_aSortArr.size() )
1166  {
1167  ::SetProgressState( 0, pDoc->GetDocShell() );
1168 
1169  sal_uInt16 nLevel = m_aSortArr[i]->GetLevel();
1170 
1171  // Skip AlphaDelimiter
1172  if( nLevel == FORM_ALPHA_DELIMITER )
1173  continue;
1174 
1175  const OUString sDeli = rIntl.GetIndexKey( m_aSortArr[i]->GetText(),
1176  m_aSortArr[i]->GetLocale() );
1177 
1178  // Do we already have a Delimiter?
1179  if( !sDeli.isEmpty() && sLastDeli != sDeli )
1180  {
1181  // We skip all that are less than a small Blank (these are special characters)
1182  if( ' ' <= sDeli[0] )
1183  {
1184  std::unique_ptr<SwTOXCustom> pCst(
1185  MakeSwTOXSortTabBase<SwTOXCustom>(nullptr,
1186  TextAndReading(sDeli, OUString()),
1188  rIntl, m_aSortArr[i]->GetLocale() ));
1189  m_aSortArr.insert( m_aSortArr.begin() + i, std::move(pCst));
1190  i++;
1191  }
1192  sLastDeli = sDeli;
1193  }
1194 
1195  // Skip until we get to the same or a lower Level
1196  do {
1197  i++;
1198  } while (i < m_aSortArr.size() && m_aSortArr[i]->GetLevel() > nLevel);
1199  }
1200 }
1201 
1204 {
1205  SwDoc* pDoc = GetFormat()->GetDoc();
1206  const OUString& rName = GetTOXForm().GetTemplate( nLevel );
1207  SwTextFormatColl* pColl = !rName.isEmpty() ? pDoc->FindTextFormatCollByName(rName) :nullptr;
1208  if( !pColl )
1209  {
1210  sal_uInt16 nPoolFormat = 0;
1211  const TOXTypes eMyType = SwTOXBase::GetType();
1212  switch( eMyType )
1213  {
1214  case TOX_INDEX: nPoolFormat = RES_POOLCOLL_TOX_IDXH; break;
1215  case TOX_USER:
1216  if( nLevel < 6 )
1217  nPoolFormat = RES_POOLCOLL_TOX_USERH;
1218  else
1219  nPoolFormat = RES_POOLCOLL_TOX_USER6 - 6;
1220  break;
1221  case TOX_ILLUSTRATIONS: nPoolFormat = RES_POOLCOLL_TOX_ILLUSH; break;
1222  case TOX_OBJECTS: nPoolFormat = RES_POOLCOLL_TOX_OBJECTH; break;
1223  case TOX_TABLES: nPoolFormat = RES_POOLCOLL_TOX_TABLESH; break;
1224  case TOX_AUTHORITIES:
1225  case TOX_BIBLIOGRAPHY:
1226  nPoolFormat = RES_POOLCOLL_TOX_AUTHORITIESH; break;
1227  case TOX_CITATION: break;
1228  case TOX_CONTENT:
1229  // There's a jump in the ContentArea!
1230  if( nLevel < 6 )
1231  nPoolFormat = RES_POOLCOLL_TOX_CNTNTH;
1232  else
1233  nPoolFormat = RES_POOLCOLL_TOX_CNTNT6 - 6;
1234  break;
1235  }
1236 
1237  if(eMyType == TOX_AUTHORITIES && nLevel)
1238  nPoolFormat = nPoolFormat + 1;
1239  else if(eMyType == TOX_INDEX && nLevel)
1240  {
1241  // pool: Level 1,2,3, Delimiter
1242  // SwForm: Delimiter, Level 1,2,3
1243  nPoolFormat += 1 == nLevel ? nLevel + 3 : nLevel - 1;
1244  }
1245  else
1246  nPoolFormat = nPoolFormat + nLevel;
1247  pColl = pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool( nPoolFormat );
1248  }
1249  return pColl;
1250 }
1251 
1252 void SwTOXBaseSection::SwClientNotify(const SwModify& rModify, const SfxHint& rHint)
1253 {
1254  if (auto pFindHint = dynamic_cast<const sw::FindContentFrameHint*>(&rHint))
1255  {
1256  if(pFindHint->m_rpContentFrame)
1257  return;
1258  auto pSectFormat = GetFormat();
1259  if(!pSectFormat)
1260  return;
1261  const SwSectionNode* pSectNd = pSectFormat->GetSectionNode();
1262  if(!pSectNd)
1263  return;
1264  SwNodeIndex aIdx(*pSectNd, 1);
1265  SwContentNode* pCNd = aIdx.GetNode().GetContentNode();
1266  if(!pCNd)
1267  pCNd = pFindHint->m_rDoc.GetNodes().GoNext(&aIdx);
1268  if(!pCNd)
1269  return;
1270  if(pCNd->EndOfSectionIndex() >= pSectNd->EndOfSectionIndex())
1271  return;
1272  pFindHint->m_rpContentFrame = pCNd->getLayoutFrame(&pFindHint->m_rLayout);
1273  } else
1274  SwTOXBase::SwClientNotify(rModify, rHint);
1275 }
1276 
1279  const SwTextNode* pOwnChapterNode,
1280  SwRootFrame const*const pLayout)
1281 {
1282  const auto pType = static_cast<SwTOXType*>(SwTOXBase::GetRegisteredIn());
1283  auto pShell = GetFormat()->GetDoc()->GetDocShell();
1284  const TOXTypes eTOXTyp = GetTOXType()->GetType();
1285  std::vector<std::reference_wrapper<SwTextTOXMark>> vMarks;
1286  pType->CollectTextTOXMarksForLayout(vMarks, pLayout);
1287  for(auto& rMark: vMarks)
1288  {
1289  ::SetProgressState(0, pShell);
1290  auto& rNode = rMark.get().GetTextNode();
1291  if(IsFromChapter() && !IsHeadingContained(pOwnChapterNode, rNode))
1292  continue;
1293  auto rTOXMark = rMark.get().GetTOXMark();
1294  if(TOX_INDEX == eTOXTyp)
1295  {
1296  // index entry mark
1297  assert(g_pBreakIt);
1298  lang::Locale aLocale = g_pBreakIt->GetLocale(rNode.GetLang(rMark.get().GetStart()));
1299  InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, rNode, &rMark.get(), GetOptions(), FORM_ENTRY, rIntl, aLocale));
1300  if(GetOptions() & SwTOIOptions::KeyAsEntry && !rTOXMark.GetPrimaryKey().isEmpty())
1301  {
1302  InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, rNode, &rMark.get(), GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale));
1303  if (!rTOXMark.GetSecondaryKey().isEmpty())
1304  {
1305  InsertSorted(MakeSwTOXSortTabBase<SwTOXIndex>(pLayout, rNode, &rMark.get(), GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale));
1306  }
1307  }
1308  }
1309  else if(TOX_USER == eTOXTyp || rTOXMark.GetLevel() <= GetLevel())
1310  { // table of content mark, also used for user marks
1311  InsertSorted(MakeSwTOXSortTabBase<SwTOXContent>(pLayout, rNode, &rMark.get(), rIntl));
1312  }
1313  }
1314 }
1315 
1317 void SwTOXBaseSection::UpdateOutline( const SwTextNode* pOwnChapterNode,
1318  SwRootFrame const*const pLayout)
1319 {
1320  SwDoc* pDoc = GetFormat()->GetDoc();
1321  SwNodes& rNds = pDoc->GetNodes();
1322 
1323  const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1324  for( auto pOutlineNode : rOutlNds )
1325  {
1326  ::SetProgressState( 0, pDoc->GetDocShell() );
1327  SwTextNode* pTextNd = pOutlineNode->GetTextNode();
1328  if( pTextNd && pTextNd->Len() && pTextNd->HasWriterListeners() &&
1329  o3tl::make_unsigned( pTextNd->GetAttrOutlineLevel()) <= GetLevel() &&
1330  pTextNd->getLayoutFrame(pLayout) &&
1331  !pTextNd->IsHiddenByParaField() &&
1332  !pTextNd->HasHiddenCharAttribute( true ) &&
1333  (!pLayout || !pLayout->HasMergedParas()
1334  || static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps() == pTextNd) &&
1335  ( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pTextNd) ))
1336  {
1337  InsertSorted(MakeSwTOXSortTabBase<SwTOXPara>(pLayout, *pTextNd, SwTOXElement::OutlineLevel));
1338  }
1339  }
1340 }
1341 
1343 void SwTOXBaseSection::UpdateTemplate(const SwTextNode* pOwnChapterNode,
1344  SwRootFrame const*const pLayout)
1345 {
1346  SwDoc* pDoc = GetFormat()->GetDoc();
1347  for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
1348  {
1349  const OUString sTmpStyleNames = GetStyleNames(i);
1350  if (sTmpStyleNames.isEmpty())
1351  continue;
1352 
1353  sal_Int32 nIndex = 0;
1354  while (nIndex >= 0)
1355  {
1357  sTmpStyleNames.getToken( 0, TOX_STYLE_DELIMITER, nIndex ));
1358  //TODO: no outline Collections in content indexes if OutlineLevels are already included
1359  if( !pColl ||
1363  continue;
1364 
1365  SwIterator<SwTextNode,SwFormatColl> aIter( *pColl );
1366  for( SwTextNode* pTextNd = aIter.First(); pTextNd; pTextNd = aIter.Next() )
1367  {
1368  ::SetProgressState( 0, pDoc->GetDocShell() );
1369 
1370  if (pTextNd->GetText().getLength() &&
1371  pTextNd->getLayoutFrame(pLayout) &&
1372  pTextNd->GetNodes().IsDocNodes() &&
1373  (!pLayout || !pLayout->HasMergedParas()
1374  || static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps() == pTextNd) &&
1375  (!IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pTextNd)))
1376  {
1377  InsertSorted(MakeSwTOXSortTabBase<SwTOXPara>(pLayout, *pTextNd, SwTOXElement::Template, i + 1));
1378  }
1379  }
1380  }
1381  }
1382 }
1383 
1385 void SwTOXBaseSection::UpdateSequence(const SwTextNode* pOwnChapterNode,
1386  SwRootFrame const*const pLayout)
1387 {
1388  SwDoc* pDoc = GetFormat()->GetDoc();
1390  if(!pSeqField)
1391  return;
1392 
1393  std::vector<SwFormatField*> vFields;
1394  pSeqField->GatherFields(vFields);
1395  for(auto pFormatField: vFields)
1396  {
1397  const SwTextField* pTextField = pFormatField->GetTextField();
1398  SwTextNode& rTextNode = pTextField->GetTextNode();
1399  ::SetProgressState( 0, pDoc->GetDocShell() );
1400 
1401  if (rTextNode.GetText().getLength() &&
1402  rTextNode.getLayoutFrame(pLayout) &&
1403  ( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, rTextNode))
1404  && (!pLayout || !pLayout->IsHideRedlines()
1405  || !sw::IsFieldDeletedInModel(pDoc->getIDocumentRedlineAccess(), *pTextField)))
1406  {
1407  const SwSetExpField& rSeqField = dynamic_cast<const SwSetExpField&>(*(pFormatField->GetField()));
1408  const OUString sName = GetSequenceName()
1409  + OUStringChar(cSequenceMarkSeparator)
1410  + OUString::number( rSeqField.GetSeqNumber() );
1411  std::unique_ptr<SwTOXPara> pNew(new SwTOXPara( rTextNode, SwTOXElement::Sequence, 1, sName ));
1412  // set indexes if the number or the reference text are to be displayed
1413  if( GetCaptionDisplay() == CAPTION_TEXT )
1414  {
1415  pNew->SetStartIndex(
1416  SwGetExpField::GetReferenceTextPos( *pFormatField, *pDoc ));
1417  }
1418  else if(GetCaptionDisplay() == CAPTION_NUMBER)
1419  {
1420  pNew->SetEndIndex(pTextField->GetStart() + 1);
1421  }
1422  pNew->InitText(pLayout);
1423  InsertSorted(std::move(pNew));
1424  }
1425  }
1426 }
1427 
1429  SwRootFrame const*const pLayout)
1430 {
1431  SwDoc* pDoc = GetFormat()->GetDoc();
1432  SwFieldType* pAuthField = pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::TableOfAuthorities, OUString(), false);
1433  if(!pAuthField)
1434  return;
1435 
1436  std::vector<SwFormatField*> vFields;
1437  pAuthField->GatherFields(vFields);
1438  for(auto pFormatField: vFields)
1439  {
1440  const auto pTextField = pFormatField->GetTextField();
1441  const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
1442  ::SetProgressState( 0, pDoc->GetDocShell() );
1443 
1444  if (rTextNode.GetText().getLength() &&
1445  rTextNode.getLayoutFrame(pLayout) &&
1446  (!pLayout || !pLayout->IsHideRedlines()
1447  || !sw::IsFieldDeletedInModel(pDoc->getIDocumentRedlineAccess(), *pTextField)))
1448  {
1449  //#106485# the body node has to be used!
1450  SwContentFrame *const pFrame = rTextNode.getLayoutFrame(pLayout);
1451  SwPosition aFieldPos(rTextNode);
1452  const SwTextNode* pTextNode = nullptr;
1453  if(pFrame && !pFrame->IsInDocBody())
1454  pTextNode = GetBodyTextNode( *pDoc, aFieldPos, *pFrame );
1455  if(!pTextNode)
1456  pTextNode = &rTextNode;
1457 
1458  InsertSorted(MakeSwTOXSortTabBase<SwTOXAuthority>(pLayout, *pTextNode, *pFormatField, rIntl));
1459  }
1460  }
1461 }
1462 
1463 static SwTOOElements lcl_IsSOObject( const SvGlobalName& rFactoryNm )
1464 {
1465  static const struct SoObjType {
1466  SwTOOElements nFlag;
1467  // GlobalNameId
1468  struct {
1469  sal_uInt32 n1;
1470  sal_uInt16 n2, n3;
1471  sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
1472  } aGlNmIds[4];
1473  } aArr[] = {
1488  };
1489 
1490  for( SoObjType const & rArr : aArr )
1491  for (auto & rId : rArr.aGlNmIds)
1492  {
1493  if( !rId.n1 )
1494  break;
1495  SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
1496  rId.b8, rId.b9, rId.b10, rId.b11,
1497  rId.b12, rId.b13, rId.b14, rId.b15 );
1498  if( rFactoryNm == aGlbNm )
1499  {
1500  return rArr.nFlag;
1501  }
1502  }
1503 
1504  return SwTOOElements::NONE;
1505 }
1506 
1508  const SwTextNode* pOwnChapterNode,
1509  SwRootFrame const*const pLayout)
1510 {
1511  SwDoc* pDoc = GetFormat()->GetDoc();
1512  SwNodes& rNds = pDoc->GetNodes();
1513  // on the 1st Node of the 1st Section
1515  nEndIdx = rNds.GetEndOfAutotext().GetIndex();
1516 
1517  while( nIdx < nEndIdx )
1518  {
1519  ::SetProgressState( 0, pDoc->GetDocShell() );
1520 
1521  SwNode* pNd = rNds[ nIdx ];
1522  SwContentNode* pCNd = nullptr;
1523  switch( eMyType )
1524  {
1525  case SwTOXElement::Frame:
1526  if( !pNd->IsNoTextNode() )
1527  {
1528  pCNd = pNd->GetContentNode();
1529  if( !pCNd )
1530  {
1531  SwNodeIndex aTmp( *pNd );
1532  pCNd = rNds.GoNext( &aTmp );
1533  }
1534  }
1535  break;
1536  case SwTOXElement::Graphic:
1537  if( pNd->IsGrfNode() )
1538  pCNd = static_cast<SwContentNode*>(pNd);
1539  break;
1540  case SwTOXElement::Ole:
1541  if( pNd->IsOLENode() )
1542  {
1543  bool bInclude = true;
1545  {
1546  SwOLENode* pOLENode = pNd->GetOLENode();
1547  SwTOOElements nMyOLEOptions = GetOLEOptions();
1548  SwOLEObj& rOLEObj = pOLENode->GetOLEObj();
1549 
1550  if( rOLEObj.IsOleRef() ) // Not yet loaded
1551  {
1552  SvGlobalName aTmpName( rOLEObj.GetOleRef()->getClassID() );
1553  SwTOOElements nObj = ::lcl_IsSOObject( aTmpName );
1554  bInclude = ( (nMyOLEOptions & SwTOOElements::Other) && SwTOOElements::NONE == nObj )
1555  || (nMyOLEOptions & nObj);
1556  }
1557  else
1558  {
1559  OSL_FAIL("OLE Object no loaded?");
1560  bInclude = false;
1561  }
1562  }
1563 
1564  if(bInclude)
1565  pCNd = static_cast<SwContentNode*>(pNd);
1566  }
1567  break;
1568  default: break;
1569  }
1570 
1571  if( pCNd )
1572  {
1573  // find node in body text
1574  int nSetLevel = USHRT_MAX;
1575 
1576  //#111105# tables of tables|illustrations|objects don't support hierarchies
1577  if( IsLevelFromChapter() &&
1581  {
1582  const SwTextNode* pOutlNd = ::lcl_FindChapterNode( *pCNd,
1583  pLayout, MAXLEVEL - 1);
1584  if( pOutlNd )
1585  {
1587  {
1588  nSetLevel = pOutlNd->GetTextColl()->GetAttrOutlineLevel();
1589  }
1590  }
1591  }
1592 
1593  if (pCNd->getLayoutFrame(pLayout)
1594  && (!pLayout || !pLayout->HasMergedParas()
1596  && ( !IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pCNd)))
1597  {
1598  std::unique_ptr<SwTOXPara> pNew( MakeSwTOXSortTabBase<SwTOXPara>(
1599  pLayout, *pCNd, eMyType,
1600  ( USHRT_MAX != nSetLevel )
1601  ? o3tl::narrowing<sal_uInt16>(nSetLevel)
1602  : FORM_ALPHA_DELIMITER ) );
1603  InsertSorted( std::move(pNew) );
1604  }
1605  }
1606 
1607  nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + SwNodeOffset(2); // 2 == End/Start Node
1608  }
1609 }
1610 
1612 void SwTOXBaseSection::UpdateTable(const SwTextNode* pOwnChapterNode,
1613  SwRootFrame const*const pLayout)
1614 {
1615  SwDoc* pDoc = GetFormat()->GetDoc();
1616  SwNodes& rNds = pDoc->GetNodes();
1617  const SwFrameFormats& rArr = *pDoc->GetTableFrameFormats();
1618 
1619  for( auto pFrameFormat : rArr )
1620  {
1621  ::SetProgressState( 0, pDoc->GetDocShell() );
1622 
1623  SwTable* pTmpTable = SwTable::FindTable( pFrameFormat );
1624  SwTableBox* pFBox;
1625  if( pTmpTable && nullptr != (pFBox = pTmpTable->GetTabSortBoxes()[0] ) &&
1626  pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() )
1627  {
1628  const SwTableNode* pTableNd = pFBox->GetSttNd()->FindTableNode();
1629  SwNodeIndex aContentIdx( *pTableNd, 1 );
1630 
1631  SwContentNode* pCNd;
1632  while( nullptr != ( pCNd = rNds.GoNext( &aContentIdx ) ) &&
1633  aContentIdx.GetIndex() < pTableNd->EndOfSectionIndex() )
1634  {
1635  if (pCNd->getLayoutFrame(pLayout)
1636  && (!pLayout || !pLayout->HasMergedParas()
1638  && (!IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pCNd)))
1639  {
1640  std::unique_ptr<SwTOXTable> pNew(new SwTOXTable( *pCNd ));
1642  {
1643  const SwTextNode* pOutlNd =
1644  ::lcl_FindChapterNode(*pCNd, pLayout, MAXLEVEL - 1);
1645  if( pOutlNd )
1646  {
1648  {
1649  const int nTmp = pOutlNd->GetTextColl()->GetAttrOutlineLevel();
1650  pNew->SetLevel(o3tl::narrowing<sal_uInt16>(nTmp));
1651  }
1652  }
1653  }
1654  pNew->InitText(pLayout);
1655  InsertSorted(std::move(pNew));
1656  break;
1657  }
1658  }
1659  }
1660  }
1661 }
1662 
1665 {
1666  if( m_aSortArr.empty() )
1667  return ;
1668 
1669  // Insert the current PageNumber into the TOC
1670  SwPageFrame* pCurrentPage = nullptr;
1671  sal_uInt16 nPage = 0;
1672  SwDoc* pDoc = GetFormat()->GetDoc();
1673 
1675  TOX_INDEX == GetTOXType()->GetType() ?
1677  GetSortAlgorithm() );
1678 
1679  for( size_t nCnt = 0; nCnt < m_aSortArr.size(); ++nCnt )
1680  {
1681  // Loop over all SourceNodes
1682 
1683  // process run in lines
1684  size_t nRange = 0;
1685  if(GetTOXForm().IsCommaSeparated() &&
1686  m_aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
1687  {
1688  const SwTOXMark& rMark = m_aSortArr[nCnt]->pTextMark->GetTOXMark();
1689  const OUString& sPrimKey = rMark.GetPrimaryKey();
1690  const OUString& sSecKey = rMark.GetSecondaryKey();
1691  const SwTOXMark* pNextMark = nullptr;
1692  while(m_aSortArr.size() > (nCnt + nRange)&&
1693  m_aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
1694  nullptr != (pNextMark = &(m_aSortArr[nCnt + nRange]->pTextMark->GetTOXMark())) &&
1695  pNextMark->GetPrimaryKey() == sPrimKey &&
1696  pNextMark->GetSecondaryKey() == sSecKey)
1697  nRange++;
1698  }
1699  else
1700  nRange = 1;
1701 
1702  for(size_t nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; ++nRunInEntry)
1703  {
1704  std::vector<sal_uInt16> aNums; // the PageNumber
1705  std::vector<SwPageDesc*> aDescs; // The PageDescriptors matching the PageNumbers
1706  std::vector<sal_uInt16> aMainNums; // contains page numbers of main entries
1707  SwTOXSortTabBase* pSortBase = m_aSortArr[nRunInEntry].get();
1708  size_t nSize = pSortBase->aTOXSources.size();
1709  for (size_t j = 0; j < nSize; ++j)
1710  {
1711  ::SetProgressState( 0, pDoc->GetDocShell() );
1712 
1713  SwTOXSource& rTOXSource = pSortBase->aTOXSources[j];
1714  if( rTOXSource.pNd )
1715  {
1716  SwContentFrame* pFrame = rTOXSource.pNd->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() );
1717  OSL_ENSURE( pFrame || pDoc->IsUpdateTOX(), "TOX, no Frame found");
1718  if( !pFrame )
1719  continue;
1720  if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->HasFollow() )
1721  {
1722  // find the right one
1723  SwTextFrame* pNext;
1724  TextFrameIndex const nPos(static_cast<SwTextFrame*>(pFrame)
1725  ->MapModelToView(static_cast<SwTextNode const*>(rTOXSource.pNd),
1726  rTOXSource.nPos));
1727  for (;;)
1728  {
1729  pNext = static_cast<SwTextFrame*>(pFrame->GetFollow());
1730  if (!pNext || nPos < pNext->GetOffset())
1731  break;
1732  pFrame = pNext;
1733  }
1734  }
1735 
1736  SwPageFrame* pTmpPage = pFrame->FindPageFrame();
1737  if( pTmpPage != pCurrentPage )
1738  {
1739  nPage = pTmpPage->GetVirtPageNum();
1740  pCurrentPage = pTmpPage;
1741  }
1742 
1743  // Insert as sorted
1744  std::vector<sal_uInt16>::size_type i;
1745  for( i = 0; i < aNums.size() && aNums[i] < nPage; ++i )
1746  ;
1747 
1748  if( i >= aNums.size() || aNums[ i ] != nPage )
1749  {
1750  aNums.insert(aNums.begin() + i, nPage);
1751  aDescs.insert(aDescs.begin() + i, pCurrentPage->GetPageDesc() );
1752  }
1753  // is it a main entry?
1754  if(TOX_SORT_INDEX == pSortBase->GetType() &&
1755  rTOXSource.bMainEntry)
1756  {
1757  aMainNums.push_back(nPage);
1758  }
1759  }
1760  }
1761  // Insert the PageNumber into the TOC TextNode
1762  const SwTOXSortTabBase* pBase = m_aSortArr[ nCnt ].get();
1763  if(pBase->pTOXNd)
1764  {
1765  const SwTextNode* pTextNd = pBase->pTOXNd->GetTextNode();
1766  OSL_ENSURE( pTextNd, "no TextNode, wrong TOC" );
1767 
1768  UpdatePageNum_( const_cast<SwTextNode*>(pTextNd), aNums, aDescs, &aMainNums,
1769  aIntl );
1770  }
1771  }
1772  }
1773  // Delete the mapping array after setting the right PageNumber
1774  m_aSortArr.clear();
1775 }
1776 
1779 static bool lcl_HasMainEntry( const std::vector<sal_uInt16>* pMainEntryNums, sal_uInt16 nToFind )
1780 {
1781  if (!pMainEntryNums)
1782  return false;
1783 
1784  for( auto nMainEntry : *pMainEntryNums )
1785  if (nToFind == nMainEntry)
1786  return true;
1787  return false;
1788 }
1789 
1791  const std::vector<sal_uInt16>& rNums,
1792  const std::vector<SwPageDesc*>& rDescs,
1793  const std::vector<sal_uInt16>* pMainEntryNums,
1794  const SwTOXInternational& rIntl )
1795 {
1796  // collect starts end ends of main entry character style
1797  std::optional< std::vector<sal_uInt16> > xCharStyleIdx;
1798  if (pMainEntryNums)
1799  xCharStyleIdx.emplace();
1800 
1801  OUString sSrchStr
1802  = OUStringChar(C_NUM_REPL) + SwTOXMark::S_PAGE_DELI + OUStringChar(C_NUM_REPL);
1803  sal_Int32 nStartPos = pNd->GetText().indexOf(sSrchStr);
1804  sSrchStr = OUStringChar(C_NUM_REPL) + OUStringChar(C_END_PAGE_NUM);
1805  sal_Int32 nEndPos = pNd->GetText().indexOf(sSrchStr);
1806 
1807  if (-1 == nEndPos || rNums.empty())
1808  return;
1809 
1810  if (-1 == nStartPos || nStartPos > nEndPos)
1811  nStartPos = nEndPos;
1812 
1813  sal_uInt16 nOld = rNums[0],
1814  nBeg = nOld,
1815  nCount = 0;
1816  OUString aNumStr( rDescs[0]->GetNumType().GetNumStr( nBeg ) );
1817  if( xCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg ))
1818  {
1819  xCharStyleIdx->push_back( 0 );
1820  }
1821 
1822  // Delete place holder
1823  SwIndex aPos(pNd, nStartPos);
1824  SwCharFormat* pPageNoCharFormat = nullptr;
1825  SwpHints* pHints = pNd->GetpSwpHints();
1826  if(pHints)
1827  for(size_t nHintIdx = 0; nHintIdx < pHints->Count(); ++nHintIdx)
1828  {
1829  const SwTextAttr* pAttr = pHints->Get(nHintIdx);
1830  const sal_Int32 nTmpEnd = pAttr->End() ? *pAttr->End() : 0;
1831  if( nStartPos >= pAttr->GetStart() &&
1832  (nStartPos + 2) <= nTmpEnd &&
1833  pAttr->Which() == RES_TXTATR_CHARFMT)
1834  {
1835  pPageNoCharFormat = pAttr->GetCharFormat().GetCharFormat();
1836  break;
1837  }
1838  }
1839  pNd->EraseText(aPos, nEndPos - nStartPos + 2);
1840 
1841  std::vector<sal_uInt16>::size_type i;
1842  for( i = 1; i < rNums.size(); ++i)
1843  {
1844  SvxNumberType aType( rDescs[i]->GetNumType() );
1845  if( TOX_INDEX == SwTOXBase::GetType() )
1846  { // Summarize for the following
1847  // Add up all following
1848  // break up if main entry starts or ends and
1849  // insert a char style index
1850  bool bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld)
1851  != lcl_HasMainEntry(pMainEntryNums, rNums[i]);
1852 
1853  if(nOld == rNums[i]-1 && !bMainEntryChanges &&
1855  nCount++;
1856  else
1857  {
1858  // Flush for the following old values
1860  {
1861  if ( nCount >= 1 )
1862  aNumStr += rIntl.GetFollowingText( nCount > 1 );
1863  }
1864  else if (nCount) //#58127# If nCount == 0, then the only PageNumber is already in aNumStr!
1865  {
1866  if (nCount == 1 )
1867  aNumStr += SwTOXMark::S_PAGE_DELI;
1868  else
1869  aNumStr += "-";
1870 
1871  aNumStr += aType.GetNumStr( nBeg + nCount );
1872  }
1873 
1874  // Create new String
1875  nBeg = rNums[i];
1876  aNumStr += SwTOXMark::S_PAGE_DELI;
1877  //the change of the character style must apply after sPageDeli is appended
1878  if (xCharStyleIdx && bMainEntryChanges)
1879  {
1880  xCharStyleIdx->push_back(aNumStr.getLength());
1881  }
1882  aNumStr += aType.GetNumStr( nBeg );
1883  nCount = 0;
1884  }
1885  nOld = rNums[i];
1886  }
1887  else
1888  { // Insert all Numbers
1889  aNumStr += aType.GetNumStr( rNums[i] );
1890  if (i+1 != rNums.size())
1891  aNumStr += SwTOXMark::S_PAGE_DELI;
1892  }
1893  }
1894  // Flush when ending and the following old values
1895  if( TOX_INDEX == SwTOXBase::GetType() )
1896  {
1898  {
1899  if( nCount >= 1 )
1900  aNumStr += rIntl.GetFollowingText( nCount > 1 );
1901  }
1902  else
1903  {
1904  if(nCount >= 2)
1905  aNumStr += "-";
1906  else if(nCount == 1)
1907  aNumStr += SwTOXMark::S_PAGE_DELI;
1908  //#58127# If nCount == 0, then the only PageNumber is already in aNumStr!
1909  if(nCount)
1910  aNumStr += rDescs[i-1]->GetNumType().GetNumStr( nBeg+nCount );
1911  }
1912  }
1914  if(pPageNoCharFormat)
1915  {
1916  SwFormatCharFormat aCharFormat( pPageNoCharFormat );
1917  pNd->InsertItem(aCharFormat, nStartPos, nStartPos + aNumStr.getLength(), SetAttrMode::DONTEXPAND);
1918  }
1919 
1920  // The main entries should get their character style
1921  if (!xCharStyleIdx || xCharStyleIdx->empty() || GetMainEntryCharStyle().isEmpty())
1922  return;
1923 
1924  // eventually the last index must me appended
1925  if (xCharStyleIdx->size()&0x01)
1926  xCharStyleIdx->push_back(aNumStr.getLength());
1927 
1928  // search by name
1929  SwDoc& rDoc = pNd->GetDoc();
1931  SwCharFormat* pCharFormat = nullptr;
1932  if(USHRT_MAX != nPoolId)
1933  pCharFormat = rDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool(nPoolId);
1934  else
1935  pCharFormat = rDoc.FindCharFormatByName( GetMainEntryCharStyle() );
1936  if(!pCharFormat)
1937  pCharFormat = rDoc.MakeCharFormat(GetMainEntryCharStyle(), nullptr);
1938 
1939  // find the page numbers in aNumStr and set the character style
1940  sal_Int32 nOffset = pNd->GetText().getLength() - aNumStr.getLength();
1941  SwFormatCharFormat aCharFormat(pCharFormat);
1942  for (size_t j = 0; j < xCharStyleIdx->size(); j += 2)
1943  {
1944  sal_Int32 nStartIdx = (*xCharStyleIdx)[j] + nOffset;
1945  sal_Int32 nEndIdx = (*xCharStyleIdx)[j + 1] + nOffset;
1946  pNd->InsertItem(aCharFormat, nStartIdx, nEndIdx, SetAttrMode::DONTEXPAND);
1947  }
1948 }
1949 
1950 void SwTOXBaseSection::InsertSorted(std::unique_ptr<SwTOXSortTabBase> pNew)
1951 {
1952  Range aRange(0, m_aSortArr.size());
1953  if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTextMark )
1954  {
1955  const SwTOXMark& rMark = pNew->pTextMark->GetTOXMark();
1956  // Evaluate Key
1957  // Calculate the range where to insert
1958  if( !(GetOptions() & SwTOIOptions::KeyAsEntry) &&
1959  !rMark.GetPrimaryKey().isEmpty() )
1960  {
1961  aRange = GetKeyRange( rMark.GetPrimaryKey(),
1962  rMark.GetPrimaryKeyReading(),
1963  *pNew, FORM_PRIMARY_KEY, aRange );
1964 
1965  if( !rMark.GetSecondaryKey().isEmpty() )
1966  aRange = GetKeyRange( rMark.GetSecondaryKey(),
1967  rMark.GetSecondaryKeyReading(),
1968  *pNew, FORM_SECONDARY_KEY, aRange );
1969  }
1970  }
1971  // Search for identical entries and remove the trailing one
1973  {
1974  for(short i = static_cast<short>(aRange.Min()); i < static_cast<short>(aRange.Max()); ++i)
1975  {
1976  SwTOXSortTabBase* pOld = m_aSortArr[i].get();
1977  if (pOld->equivalent(*pNew))
1978  {
1979  if (pOld->sort_lt(*pNew))
1980  {
1981  return;
1982  }
1983  else
1984  {
1985  // remove the old content
1986  m_aSortArr.erase( m_aSortArr.begin() + i );
1987  aRange.Max()--;
1988  break;
1989  }
1990  }
1991  }
1992  }
1993 
1994  // find position and insert
1995  tools::Long i;
1996 
1997  for( i = aRange.Min(); i < aRange.Max(); ++i)
1998  { // Only check for same level
1999  SwTOXSortTabBase* pOld = m_aSortArr[i].get();
2000  if (pOld->equivalent(*pNew))
2001  {
2003  {
2004  // Own entry for double entries or keywords
2005  if( pOld->GetType() == TOX_SORT_CUSTOM &&
2007  continue;
2008 
2010  { // Own entry
2011  m_aSortArr.insert(m_aSortArr.begin() + i, std::move(pNew));
2012  return;
2013  }
2014  // If the own entry is already present, add it to the references list
2015  pOld->aTOXSources.push_back(pNew->aTOXSources[0]);
2016 
2017  return;
2018  }
2019 #if OSL_DEBUG_LEVEL > 0
2020  else
2021  OSL_FAIL("Bibliography entries cannot be found here");
2022 #endif
2023  }
2024  if (pNew->sort_lt(*pOld))
2025  break;
2026  }
2027  // Skip SubLevel
2028  while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() &&
2029  m_aSortArr[i]->GetLevel() > pNew->GetLevel() )
2030  i++;
2031 
2032  // Insert at position i
2033  m_aSortArr.insert(m_aSortArr.begin()+i, std::move(pNew));
2034 }
2035 
2037 Range SwTOXBaseSection::GetKeyRange(const OUString& rStr, const OUString& rStrReading,
2038  const SwTOXSortTabBase& rNew,
2039  sal_uInt16 nLevel, const Range& rRange )
2040 {
2041  const SwTOXInternational& rIntl = *rNew.pTOXIntl;
2042  TextAndReading aToCompare(rStr, rStrReading);
2043 
2045  {
2046  aToCompare.sText = rIntl.ToUpper( aToCompare.sText, 0 )
2047  + aToCompare.sText.subView(1);
2048  }
2049 
2050  OSL_ENSURE(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0");
2051 
2052  const tools::Long nMin = rRange.Min();
2053  const tools::Long nMax = rRange.Max();
2054 
2055  tools::Long i;
2056 
2057  for( i = nMin; i < nMax; ++i)
2058  {
2059  SwTOXSortTabBase* pBase = m_aSortArr[i].get();
2060 
2061  if( rIntl.IsEqual( pBase->GetText(), pBase->GetLocale(),
2062  aToCompare, rNew.GetLocale() ) &&
2063  pBase->GetLevel() == nLevel )
2064  break;
2065  }
2066  if(i == nMax)
2067  { // If not already present, create and insert
2068  std::unique_ptr<SwTOXCustom> pKey(MakeSwTOXSortTabBase<SwTOXCustom>(
2069  nullptr, aToCompare, nLevel, rIntl, rNew.GetLocale() ));
2070  for(i = nMin; i < nMax; ++i)
2071  {
2072  if (nLevel == m_aSortArr[i]->GetLevel() && pKey->sort_lt(*m_aSortArr[i]))
2073  break;
2074  }
2075  m_aSortArr.insert(m_aSortArr.begin() + i, std::move(pKey));
2076  }
2077  const tools::Long nStart = i+1;
2078  const tools::Long nEnd = m_aSortArr.size();
2079 
2080  // Find end of range
2081  for(i = nStart; i < nEnd; ++i)
2082  {
2083  if(m_aSortArr[i]->GetLevel() <= nLevel)
2084  {
2085  return Range(nStart, i);
2086  }
2087  }
2088  return Range(nStart, nEnd);
2089 }
2090 
2092 {
2093  const SwTOXBaseSection *pSect = dynamic_cast<const SwTOXBaseSection*>(this);
2094  if (!pSect || !pSect->GetFormat())
2095  return false;
2096 
2097  const SwSectionNode* pSectNode = pSect->GetFormat()->GetSectionNode();
2098  if (!pSectNode)
2099  return false;
2100 
2101  const SwDocShell* pDocSh = pSectNode->GetDoc().GetDocShell();
2102  if (!pDocSh)
2103  return false;
2104 
2105  if (pDocSh->IsReadOnly())
2106  return true;
2107 
2108  pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode();
2109  if (!pSectNode)
2110  return false;
2111 
2112  return pSectNode->GetSection().IsProtectFlag();
2113 }
2114 
2116 {
2117  const SwTOXBaseSection *pSect = dynamic_cast<const SwTOXBaseSection*>(this);
2118  if(pSect && pSect->GetFormat())
2119  return &pSect->GetFormat()->GetAttrSet();
2120  return nullptr;
2121 }
2122 
2124 {
2125  SwTOXBaseSection *pSect = dynamic_cast<SwTOXBaseSection*>(this);
2126  if( pSect && pSect->GetFormat() )
2127  pSect->GetFormat()->SetFormatAttr( rSet );
2128 }
2129 
2130 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual SwCharFormat * GetCharFormatFromPool(sal_uInt16 nId)=0
OUString GetNumStr(sal_Int32 nNo) const
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:985
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:241
#define SO3_SM_CLASSID_60
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:694
SvxBreak
virtual void SwClientNotify(const SwModify &rMod, const SfxHint &rHint) override
Definition: tox.hxx:464
const css::lang::Locale & GetLocale() const
Definition: txmsrt.hxx:183
OUString GetIndexKey(const TextAndReading &rTaR, const css::lang::Locale &rLcl) const
Definition: txmsrt.cxx:122
Base class of the Writer layout elements.
Definition: frame.hxx:314
const sal_Unicode C_NUM_REPL
Definition: tox.cxx:45
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:162
const SfxItemSet * GetAttrSet() const
Definition: doctxm.cxx:2115
TOXTypes
Definition: toxe.hxx:39
bool IsMarkHintHidden(SwRootFrame const &rLayout, SwTextNode const &rNode, SwTextAttrEnd const &rHint)
Definition: reffld.cxx:1140
void SetAttrSet(const SfxItemSet &)
Definition: doctxm.cxx:2123
std::vector< SwSection * > SwSections
Definition: section.hxx:40
bool IsInMailMerge() const
Definition: doc.hxx:959
bool operator>=(const BigInt &rVal1, const BigInt &rVal2)
OUString const & GetSecondaryKeyReading() const
Definition: tox.hxx:656
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
Definition: ndarr.hxx:155
sal_Int32 nIndex
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:689
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
std::unique_ptr< SwDefTOXBase_Impl > mpDefTOXBases
Definition: doc.hxx:248
Marks a position in the document model.
Definition: pam.hxx:36
SwTOXElement GetCreateType() const
Definition: tox.hxx:699
bool IsInDocBody() const
Definition: frame.hxx:943
SwTOIOptions GetOptions() const
Definition: tox.hxx:735
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:164
SwPageDesc * GetPageDesc()
Definition: fmtpdsc.hxx:61
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:115
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
Definition: docfmt.cxx:854
const OUString & GetText() const
Definition: ndtxt.hxx:218
virtual const SwRootFrame * GetCurrentLayout() const =0
static void CheckPageDescs(SwPageFrame *pStart, bool bNotifyFields=true, SwPageFrame **ppPrev=nullptr)
Check all pages (starting from the given one) if they use the appropriate frame format.
Definition: pagechg.cxx:1066
virtual bool get(DocumentSettingId id) const override
Return the specified document setting.
OUString const & GetPrimaryKey() const
Definition: tox.hxx:632
constexpr SwNodeOffset NODE_OFFSET_MAX(SAL_MAX_INT32)
SwDocShell * GetDocShell()
Definition: doc.hxx:1351
bool IsProtected() const
Definition: tox.hxx:536
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:226
Definition: toxe.hxx:25
const SwFrameFormats * GetTableFrameFormats() const
Definition: doc.hxx:810
void DelSectionFormat(SwSectionFormat *pFormat, bool bDelNodes=false)
Definition: ndsect.cxx:521
virtual SwFieldType * GetFieldType(SwFieldIds nResId, const OUString &rName, bool bDbFieldMatching) const =0
SwNodeOffset StartOfSectionIndex() const
Definition: node.hxx:685
static SwTOXBase * GetCurTOX(const SwPosition &rPos)
Get current table of contents.
Definition: doctxm.cxx:448
SwTOOElements
Definition: tox.hxx:407
Definition: tox.hxx:311
SwNodeIndex nNode
Definition: pam.hxx:38
const SwTOXType * InsertTOXType(const SwTOXType &rTyp)
Definition: doctxm.cxx:629
int n1
void InsertAlphaDelimiter(const SwTOXInternational &rIntl)
Definition: doctxm.cxx:1160
SvxBreak GetBreak() const
SwTextFormatColl * FindTextFormatCollByName(const OUString &rName) const
Definition: doc.hxx:798
void SetSectionName(OUString const &rName)
Definition: section.hxx:168
const SwTextNode * GetBodyTextNode(const SwDoc &rDoc, SwPosition &rPos, const SwFrame &rFrame)
Forward declaration: get "BodyTextNode" for exp.fld in Fly's headers/footers/footnotes.
Definition: expfld.cxx:163
static bool lcl_HasMainEntry(const std::vector< sal_uInt16 > *pMainEntryNums, sal_uInt16 nToFind)
Replace the PageNumber place holders.
Definition: doctxm.cxx:1779
SwHistory & GetHistory()
virtual void SetModified()=0
Must be called manually at changes of format.
sal_uInt16 GetType() const
Definition: txmsrt.hxx:143
sal_uIntPtr sal_uLong
std::vector< SwTOXMark * > SwTOXMarks
Definition: tox.hxx:44
long Long
Subgroup user indices.
Definition: poolfmt.hxx:382
OUString const & GetTemplate(sal_uInt16 nLevel) const
Definition: tox.hxx:670
#define SO3_SIMPRESS_CLASSID_30
#define SO3_SIMPRESS_CLASSID_60
virtual sal_uInt16 GetLevel() const =0
void CollectTextMarks(SwTOXMarks &rMarks) const
Definition: tox.hxx:182
#define SO3_SCH_CLASSID_30
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:939
#define TOX_STYLE_DELIMITER
Definition: tox.hxx:420
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1204
sal_Int64 n
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
Definition: doc.hxx:187
void TitleSectionInserted(SwSectionFormat &rSectionFormat)
Definition: unsect.cxx:555
TElementType * Next()
Definition: calbck.hxx:364
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
This class generates text for the entries of a table of x.
tuple args
WW8LvlType GetNumType(sal_uInt8 nWwLevelNo)
Definition: ww8par2.cxx:887
#define SO3_SDRAW_CLASSID_50
bool IsUpdateTOX() const
Definition: doc.hxx:948
virtual void DeleteRange(SwPaM &)=0
Delete a range SwFlyFrameFormat.
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1317
bool HasDummyChar() const
Definition: txatbase.hxx:107
SwNode & GetNode() const
Definition: ndindex.hxx:128
OUString newName(std::u16string_view aNewPrefix, const OUString &aOldPrefix, std::u16string_view old_Name)
void UpdateTemplate(const SwTextNode *pOwnChapterNode, SwRootFrame const *pLayout)
Generate table of contents from template areas.
Definition: doctxm.cxx:1343
SwSectionFormat * GetFormat()
Definition: section.hxx:336
bool operator<=(const BigInt &rVal1, const BigInt &rVal2)
bool IsTOXBaseInReadonly() const
Definition: doctxm.cxx:2091
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
#define SO3_SC_CLASSID_40
const SwTOXType * GetTOXType() const
Definition: tox.hxx:574
sal_uInt16 Which() const
Definition: txatbase.hxx:116
static const SwAttrSet & GetTOXBaseAttrSet(const SwTOXBase &rTOX)
Definition: doctxm.cxx:468
sal_uInt16 nLevel
Definition: tox.hxx:439
#define FORM_SECONDARY_KEY
Definition: tox.hxx:207
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
The root element of a Writer document layout.
Definition: rootfrm.hxx:81
OUString GetFollowingText(bool bMorePages) const
Definition: txmsrt.cxx:128
bool SetTOXBaseName(const SwTOXBase &rTOXBase, const OUString &rName)
Definition: doctxm.cxx:705
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4060
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Definition: fldbas.cxx:203
const SwSection & GetSection() const
Definition: node.hxx:551
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
#define SO3_SCH_CLASSID_40
OUString const & GetPrimaryKeyReading() const
Definition: tox.hxx:650
bool IsAssignedToListLevelOfOutlineStyle() const
Definition: fmtcol.hxx:120
static SwTOOElements lcl_IsSOObject(const SvGlobalName &rFactoryNm)
Definition: doctxm.cxx:1463
const SwTOXType * GetTOXType() const
Definition: tox.hxx:696
const SvxFormatBreakItem & GetBreak(bool=true) const
Definition: frmatr.hxx:62
#define CH_TXTATR_INWORD
Definition: hintids.hxx:174
SwTOXBaseSection * InsertTableOf(const SwPosition &rPos, const SwTOXBase &rTOX, const SfxItemSet *pSet=nullptr, bool bExpand=false, SwRootFrame const *pLayout=nullptr)
Definition: doctxm.cxx:344
int n2
const SwTOXMark & GetTOXMark() const
Definition: txatbase.hxx:232
SwIndex nContent
Definition: pam.hxx:39
const SwRect & getFrameArea() const
Definition: frame.hxx:179
#define SO3_SC_CLASSID_30
SwSectionNode * GetSectionNode()
Definition: section.cxx:922
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:426
SwTOXSearch
Definition: toxe.hxx:22
virtual bool equivalent(const SwTOXSortTabBase &)
Definition: txmsrt.cxx:226
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
SwTOIKeyType
Definition: toxe.hxx:30
int nCount
bool IsEqual(const TextAndReading &rTaR1, const css::lang::Locale &rLocale1, const TextAndReading &rTaR2, const css::lang::Locale &rLocale2) const
Definition: txmsrt.hxx:93
Content 6th level.
Definition: poolfmt.hxx:389
bool IsTextFrame() const
Definition: frame.hxx:1234
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
const SwTextNode * pTOXNd
Definition: txmsrt.hxx:128
SwTextAttr * InsertItem(SfxPoolItem &rAttr, const sal_Int32 nStart, const sal_Int32 nEnd, const SetAttrMode nMode=SetAttrMode::DEFAULT)
create new text attribute from rAttr and insert it
Definition: thints.cxx:1305
bool DeleteTOX(const SwTOXBase &rTOXBase, bool bDelNodes)
Delete table of contents.
Definition: doctxm.cxx:524
sal_uInt16 GetTOXTypeCount(TOXTypes eTyp) const
Manage table of content types.
Definition: doctxm.cxx:611
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
bool IsProtectFlag() const
Definition: section.hxx:187
o3tl::sorted_vector< SwRootFrame * > GetAllLayouts()
Definition: doclay.cxx:1668
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:161
const OUString & GetSequenceName() const
Definition: tox.hxx:539
#define SO3_SC_CLASSID_60
SwSectionFormat * MakeSectionFormat()
Definition: ndsect.cxx:514
OUString ToUpper(const OUString &rStr, sal_Int32 nPos) const
Definition: txmsrt.cxx:103
#define SO3_SCH_CLASSID_60
SwTOOElements GetOLEOptions() const
Definition: tox.hxx:512
size_type size() const
virtual bool DoesUndo() const =0
Is Undo enabled?
const char * sName
OUString maMSTOCExpression
Definition: tox.hxx:455
Specific frame formats (frames, DrawObjects).
sal_uInt16 GetSeqNumber() const
Definition: expfld.hxx:247
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:162
#define SO3_SC_CLASSID_50
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1806
object index.
Definition: poolfmt.hxx:400
void UpdatePageNum()
Calculate PageNumber and insert after formatting.
Definition: doctxm.cxx:1664
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
Range GetKeyRange(const OUString &rStr, const OUString &rStrReading, const SwTOXSortTabBase &rNew, sal_uInt16 nLevel, const Range &rRange)
Find Key Range and insert if possible.
Definition: doctxm.cxx:2037
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:457
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:503
static sal_Int32 GetReferenceTextPos(const SwFormatField &rFormat, SwDoc &rDoc, sal_Int32 nHint=0)
Find the index of the reference text following the current field.
Definition: expfld.cxx:973
#define SO3_SM_CLASSID_50
#define SO3_SCH_CLASSID_50
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:2106
virtual void AppendUndo(std::unique_ptr< SwUndo > pUndo)=0
Add new Undo action.
std::vector< std::unique_ptr< SwTOXSortTabBase > > m_aSortArr
Definition: doctxm.hxx:37
size_t Count() const
Definition: ndhints.hxx:142
void DeRegister()
deregister the currently registered History
Definition: ndhints.hxx:197
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
#define SAL_MAX_INT32
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:135
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
SwTOXBaseSection(SwTOXBase const &rBase, SwSectionFormat &rFormat)
Definition: doctxm.cxx:823
std::unique_ptr< SwTOXTypes > mpTOXTypes
Definition: doc.hxx:247
int i
SwTOXElement
Definition: tox.hxx:363
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:133
const OUString & GetSectionName() const
Definition: section.hxx:167
SwDoc & GetDoc()
Definition: node.hxx:213
const SwPosition * GetPoint() const
Definition: pam.hxx:208
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:66
void UpdateOutline(const SwTextNode *pOwnChapterNode, SwRootFrame const *pLayout)
Generate table of contents from outline.
Definition: doctxm.cxx:1317
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:880
sw::FieldmarkMode GetFieldmarkMode() const
Definition: rootfrm.hxx:423
void SetProtect(bool const bFlag=true)
Definition: section.cxx:353
virtual void SwClientNotify(const SwModify &rModify, const SfxHint &rHint) override
Definition: doctxm.cxx:1252
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
Text body.
Definition: poolfmt.hxx:251
TextFrameIndex MapModelToView(MergedPara const &, SwTextNode const *pNode, sal_Int32 nIndex)
Definition: txtfrm.cxx:1186
TElementType * First()
Definition: calbck.hxx:356
bool IsFromObjectNames() const
Definition: tox.hxx:530
bool IsHiddenFlag() const
Definition: section.hxx:186
virtual bool DeleteRedline(const SwPaM &rPam, bool bSaveInUndo, RedlineType nDelType)=0
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:143
bool SetPosAtStartEnd(SwPosition &rPos) const
Definition: doctxm.cxx:835
SwContentNode * GetContentNode()
Definition: node.hxx:627
SwNodeOffset GetIndex() const
Definition: node.hxx:292
const SvxPageUsage aArr[]
#define SO3_SIMPRESS_CLASSID_40
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
void UpdateNumRule()
Definition: docnum.cxx:2647
OUString GetText(SwRootFrame const *pLayout) const
Definition: tox.cxx:192
Marks a character position inside a document model node.
Definition: index.hxx:33
void UpdateTable(const SwTextNode *pOwnChapterNode, SwRootFrame const *pLayout)
Collect table entries.
Definition: doctxm.cxx:1612
WhichRangesContainer const aBreakSetRange(svl::Items< RES_PAGEDESC, RES_BREAK >)
const OUString & GetTypeName() const
Definition: tox.hxx:688
const SwTextNode * GetpTextNd() const
Definition: txttxmrk.hxx:44
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
static bool IsHeadingContained(const SwTextNode *pChptrNd, const SwNode &rNd)
Definition: doctxm.cxx:741
bool operator<(const wwFont &r1, const wwFont &r2)
Definition: wrtw8sty.cxx:849
Definition: toxe.hxx:24
size
void GetTOIKeys(SwTOIKeyType eTyp, std::vector< OUString > &rArr, SwRootFrame const &rLayout) const
Definition: doctxm.cxx:86
const SwTOXInternational * pTOXIntl
Definition: txmsrt.hxx:130
Marks a node in the document model.
Definition: ndindex.hxx:30
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:230
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:705
SwTextFormatColl * GetTextFormatColl(sal_uInt16 nLevel)
Evaluate Template.
Definition: doctxm.cxx:1203
static std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type MakeSwTOXSortTabBase(SwRootFrame const *const pLayout, Args &&...args)
Definition: doctxm.cxx:79
bool HasSwAttrSet() const
Definition: node.hxx:458
void Register(SwRegHistory *pHist)
register a History, which receives all attribute changes (for Undo)
Definition: ndhints.hxx:195
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
SectionType
Definition: section.hxx:44
bool empty() const
void UpdateAuthorities(const SwTOXInternational &rIntl, SwRootFrame const *pLayout)
Definition: doctxm.cxx:1428
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
bool IsFromChapter() const
Definition: tox.hxx:527
sal_uInt16 GetLevel() const
Definition: tox.hxx:729
Represents the style of a text portion.
Definition: charfmt.hxx:26
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:57
A page of the document layout.
Definition: pagefrm.hxx:57
SwSectionNode * InsertTextSection(SwNodeIndex const &rNdIdx, SwSectionFormat &rSectionFormat, SwSectionData const &, SwTOXBase const *const pTOXBase, SwNodeIndex const *const pEnd, bool const bInsAtStart=true, bool const bCreateFrames=true)
Insert a new SwSection.
Definition: ndsect.cxx:786
const SwTOXMark & GotoTOXMark(const SwTOXMark &rCurTOXMark, SwTOXSearch eDir, bool bInReadOnly)
Definition: doctxm.cxx:229
const OUString & GetTitle() const
Definition: tox.hxx:702
virtual ~SwTOXBaseSection() override
Definition: doctxm.cxx:831
bool IsInReading() const
Definition: doc.hxx:953
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
SwCaptionDisplay GetCaptionDisplay() const
Definition: tox.hxx:542
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:112
bool IsReadOnly() const
const sal_Unicode C_END_PAGE_NUM
Definition: tox.cxx:46
bool operator!=(const ScCsvLayoutData &rData1, const ScCsvLayoutData &rData2)
void UpdateSequence(const SwTextNode *pOwnChapterNode, SwRootFrame const *pLayout)
Generate content from sequence fields.
Definition: doctxm.cxx:1385
const OUString & GetSortAlgorithm() const
Definition: tox.hxx:553
void DeleteAttribute(SwTextAttr *const pTextAttr)
delete the attribute pTextAttr
Definition: thints.cxx:1739
tools::Long Min() const
user index 6..10.
Definition: poolfmt.hxx:412
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:448
std::unique_ptr< SwSectionFormats > mpSectionFormatTable
Definition: doc.hxx:242
bool IsOleRef() const
To avoid unnecessary loading of object.
Definition: ndole.cxx:904
const SwTextNode & GetTextNode() const
Definition: txttxmrk.hxx:49
illustrations index.
Definition: poolfmt.hxx:396
void EraseText(const SwIndex &rIdx, const sal_Int32 nCount=SAL_MAX_INT32, const SwInsertFlags nMode=SwInsertFlags::DEFAULT)
delete text content ATTENTION: must not be called with a range that overlaps the start of an attribut...
Definition: ndtxt.cxx:2689
const SwPageDesc * FindPageDesc(SwNodeOffset *pPgDescNdIdx=nullptr) const
Search PageDesc with which this node is formatted.
Definition: node.cxx:475
OUString InsertText(const OUString &rStr, const SwIndex &rIdx, const SwInsertFlags nMode=SwInsertFlags::DEFAULT)
insert text content
Definition: ndtxt.cxx:2297
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:770
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void DeleteTOXMark(const SwTOXMark *pTOXMark)
Delete table of contents Mark.
Definition: doctxm.cxx:155
static constexpr OUStringLiteral S_PAGE_DELI
Definition: tox.hxx:167
OUString sText
Definition: txmsrt.hxx:61
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
bool IsRelTabPos() const
Definition: tox.hxx:342
#define SO3_SIMPRESS_CLASSID_50
void SetTOXName(const OUString &rSet)
Definition: tox.hxx:480
SwCharFormat * GetCharFormat() const
Definition: fchrfmt.hxx:70
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:471
const SwTextNode * FindOutlineNodeOfLevel(sal_uInt8 nLvl, SwRootFrame const *pLayout=nullptr) const
Definition: node.cxx:773
virtual bool SetAttr(const SfxPoolItem &)
made virtual
Definition: node.cxx:1566
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:67
void InsertSorted(std::unique_ptr< SwTOXSortTabBase > pBase)
Definition: doctxm.cxx:1950
void Update(const SfxItemSet *pAttr=nullptr, SwRootFrame const *pLayout=nullptr, const bool _bNewTOX=false)
Collect table of contents content.
Definition: doctxm.cxx:850
OUString GetUniqueTOXBaseName(const SwTOXType &rType, const OUString &sChkStr) const
Definition: doctxm.cxx:636
void CorrAbs(const SwNodeIndex &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
Definition: doccorr.cxx:168
bool IsFieldDeletedInModel(IDocumentRedlineAccess const &rIDRA, SwTextField const &rTextField)
OUString const & GetSecondaryKey() const
Definition: tox.hxx:638
static const SwTextNode * lcl_FindChapterNode(const SwNode &rNd, SwRootFrame const *const pLayout, sal_uInt8 const nLvl=0)
Definition: doctxm.cxx:720
unsigned char sal_uInt8
static sal_uInt16 GetCurTOXMark(const SwPosition &rPos, SwTOXMarks &)
Get current table of contents Mark.
Definition: doctxm.cxx:117
TOXTypes GetType() const
Definition: tox.hxx:720
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
OUString const & GetStyleNames(sal_uInt16 nLevel) const
Definition: tox.hxx:517
#define SO3_SM_CLASSID_40
bool mbKeepExpression
Definition: tox.hxx:456
OUString aName
sal_Int32 GetIndex() const
Definition: index.hxx:91
OString DateTimeToOString(const DateTime &rDateTime)
void SetProgressState(tools::Long nPosition, SwDocShell const *pDocShell)
Definition: mainwn.cxx:82
LanguageType GetLanguage() const
Definition: tox.hxx:550
bool IsCommaSeparated() const
Definition: tox.hxx:345
SwNodes & GetNodes()
Definition: doc.hxx:408
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:186
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:164
const sal_Int32 * End() const
Definition: txatbase.hxx:156
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:418
#define FORM_ALPHA_DELIMITER
Definition: tox.hxx:205
void PaMCorrAbs(const SwPaM &rRange, const SwPosition &rNewPos)
Function declarations so that everything below the CursorShell can move the Cursor once in a while...
Definition: doccorr.cxx:86
void Delete(const SwNodeIndex &rPos, SwNodeOffset nNodes=SwNodeOffset(1))
delete nodes
Definition: nodes.cxx:1085
constexpr TypedWhichId< SwTOXMark > RES_TXTATR_TOXMARK(47)
#define FORM_ENTRY
Definition: tox.hxx:208
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
tables index.
Definition: poolfmt.hxx:404
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:421
virtual bool AppendTextNode(SwPosition &rPos)=0
const OUString & GetMainEntryCharStyle() const
Definition: tox.hxx:500
TOXTypes GetType() const
Definition: tox.hxx:691
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:726
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
const char cSequenceMarkSeparator
Definition: swtypes.hxx:126
void UpdatePageNum_(SwTextNode *pNd, const std::vector< sal_uInt16 > &rNums, const std::vector< SwPageDesc * > &rDescs, const std::vector< sal_uInt16 > *pMainEntryNums, const SwTOXInternational &rIntl)
Definition: doctxm.cxx:1790
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:358
void ChgFormat(SwFormat &rFormat, const SfxItemSet &rSet)
Definition: docfmt.cxx:1871
void UpdateMarks(const SwTOXInternational &rIntl, const SwTextNode *pOwnChapterNode, SwRootFrame const *pLayout)
Create from Marks.
Definition: doctxm.cxx:1278
static SwTOIOptions GetOptions()
Definition: txmsrt.hxx:144
#define FORM_PRIMARY_KEY
Definition: tox.hxx:206
void DelFlyInRange(const SwNodeIndex &rMkNdIdx, const SwNodeIndex &rPtNdIdx, SwIndex const *const pMkIdx, SwIndex const *const pPtIdx)
Delete and move all Flys at the paragraph, that are within the selection.
Definition: docedt.cxx:208
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc...
Definition: nodes.cxx:2380
Subgroup index tables.
Definition: poolfmt.hxx:367
bool HasMergedParas() const
Definition: rootfrm.hxx:425
Subgroup table of contents.
Definition: poolfmt.hxx:374
SwSectionNode * GetSectionNode()
Definition: node.hxx:619
const SwTextTOXMark * GetTextTOXMark() const
Definition: tox.hxx:158
SectionType GetType() const
Definition: section.hxx:169
bool Seek_Entry(SwNode *rP, size_type *pnPos) const
Definition: ndnum.cxx:32
const SwTOXType * GetTOXType(TOXTypes eTyp, sal_uInt16 nId) const
Definition: doctxm.cxx:620
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
sal_uInt16 GetSectionLevel() const
Returns the section level at the position given by aIndex.
Definition: node.cxx:271
const SwFormatPageDesc & GetPageDesc(bool=true) const
Definition: fmtpdsc.hxx:78
const SwForm & GetTOXForm() const
Definition: tox.hxx:711
SwTextNode & GetTextNode() const
Definition: txtfld.hxx:53
const SwFormatCharFormat & GetCharFormat() const
Definition: txatbase.hxx:187
#define SO3_SDRAW_CLASSID_60
int GetAttrOutlineLevel() const
Definition: fmtcol.cxx:599
std::vector< SwNode * >::size_type size_type
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:160
void SetDefaultTOXBase(const SwTOXBase &rBase)
Definition: doctxm.cxx:503
tools::Long Max() const
TextAndReading const & GetText() const
Definition: txmsrt.hxx:177
#define FORM_TITLE
Definition: tox.hxx:204
index of authorities.
Definition: poolfmt.hxx:408
SwSection * InsertSwSection(SwPaM const &rRange, SwSectionData &, std::tuple< SwTOXBase const *, sw::RedlineMode, sw::FieldmarkMode > const *pTOXBase, SfxItemSet const *const pAttr, bool const bUpdate=true)
Definition: ndsect.cxx:156
void GetChildSections(SwSections &rArr, SectionSort eSort=SectionSort::Not, bool bAllSections=true) const
Definition: section.cxx:850
#define SO3_SM_CLASSID_30
virtual bool sort_lt(const SwTOXSortTabBase &)
Definition: txmsrt.cxx:252
Class for sorting directories.
Definition: txmsrt.hxx:121
bool operator==(const ScCsvLayoutData &rData1, const ScCsvLayoutData &rData2)
Merge GetRedlineMergeFlag() const
Definition: node.hxx:99
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1300
void UpdateContent(SwTOXElement eType, const SwTextNode *pOwnChapterNode, SwRootFrame const *pLayout)
Definition: doctxm.cxx:1507
std::vector< SwTOXSource > aTOXSources
Definition: txmsrt.hxx:126
const SwTOXBase * GetDefaultTOXBase(TOXTypes eTyp, bool bCreate)
Definition: doctxm.cxx:477
sal_uInt16 nPos
bool IsLevelFromChapter() const
Definition: tox.hxx:533
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1318
const OUString & GetTOXName() const
Definition: tox.hxx:479
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
SwTextNode * MakeTextNode(const SwNodeIndex &rWhere, SwTextFormatColl *pColl, bool bNewFrames=true)
Implementations of "Make...Node" are in the given .cxx-files.
Definition: ndtxt.cxx:104
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1628
Base class of the Writer document model elements.
Definition: node.hxx:81
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:858