LibreOffice Module sw (master)  1
tox.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 <calbck.hxx>
21 #include <doc.hxx>
22 #include <docary.hxx>
23 #include <editeng/tstpitem.hxx>
24 #include <hintids.hxx>
25 #include <hints.hxx>
26 #include <ndtxt.hxx>
27 #include <paratr.hxx>
28 #include <rootfrm.hxx>
29 #include <scriptinfo.hxx>
30 #include <strings.hrc>
31 #include <swtypes.hxx>
32 #include <tox.hxx>
33 #include <txtfrm.hxx>
34 #include <txttxmrk.hxx>
35 
36 #include <optional>
37 #include <sal/log.hxx>
38 #include <osl/diagnose.h>
39 
40 #include <algorithm>
41 
42 
43 using namespace std;
44 
45 
46 const sal_Unicode C_NUM_REPL = '@';
48 
49 namespace
50 {
51 void lcl_FillAuthPattern(SwFormTokens &rAuthTokens, sal_uInt16 nTypeId)
52 {
53  rAuthTokens.reserve(9); // Worst case: Start+Sep1+Auth+3*(Sep2+Auth)
54 
55  SwFormToken aStartToken( TOKEN_AUTHORITY );
57  rAuthTokens.push_back( aStartToken );
58  SwFormToken aSeparatorToken( TOKEN_TEXT );
59  aSeparatorToken.sText = ": ";
60  rAuthTokens.push_back( aSeparatorToken );
61 
62  --nTypeId; // compensate +1 offset introduced by caller
63 
64  SwFormToken aTextToken( TOKEN_TEXT );
65  aTextToken.sText = ", ";
66 
67  const ToxAuthorityField nVals[4] = {
72  };
73 
74  for(size_t i = 0; i < SAL_N_ELEMENTS(nVals); ++i)
75  {
76  if(nVals[i] == AUTH_FIELD_END)
77  break;
78  if( i > 0 )
79  rAuthTokens.push_back( aTextToken );
80 
81  // -> #i21237#
83 
84  aToken.nAuthorityField = nVals[i];
85  rAuthTokens.push_back(aToken);
86  // <- #i21237#
87  }
88 }
89 }
90 
94  , m_pType(nullptr)
95  , m_pTextAttr(nullptr)
96  , m_nLevel(0)
97  , m_bAutoGenerated(false)
98  , m_bMainEntry(false)
99 {
100 }
101 
104  , m_pType(pType)
105  , m_pTextAttr(nullptr)
106  , m_nLevel(0)
107  , m_bAutoGenerated(false)
108  , m_bMainEntry(false)
109 {
110  StartListening(const_cast<SwTOXType*>(m_pType)->GetNotifier());
111 }
112 
115  , SvtListener()
116  , m_pType(rCopy.m_pType)
117  , m_aPrimaryKey(rCopy.m_aPrimaryKey)
118  , m_aSecondaryKey(rCopy.m_aSecondaryKey)
119  , m_aTextReading(rCopy.m_aTextReading)
120  , m_aPrimaryKeyReading(rCopy.m_aPrimaryKeyReading)
121  , m_aSecondaryKeyReading(rCopy.m_aSecondaryKeyReading)
122  , m_pTextAttr(nullptr)
123  , m_nLevel(rCopy.m_nLevel)
124  , m_bAutoGenerated(rCopy.m_bAutoGenerated)
125  , m_bMainEntry(rCopy.m_bMainEntry)
126 {
127  if(m_pType)
128  StartListening(const_cast<SwTOXType*>(m_pType)->GetNotifier());
129  // Copy AlternativString
130  m_aAltText = rCopy.m_aAltText;
131 }
132 
134 {
135 }
136 
138 {
140  m_pType = &rType;
141  StartListening(rType.GetNotifier());
142 }
143 
144 bool SwTOXMark::operator==( const SfxPoolItem& rAttr ) const
145 {
146  assert(SfxPoolItem::operator==(rAttr));
147  return m_pType == static_cast<const SwTOXMark&>(rAttr).m_pType;
148 }
149 
151 {
152  return new SwTOXMark( *this );
153 }
154 
155 void SwTOXMark::Notify(const SfxHint& rHint)
156 {
157  if (rHint.GetId() == SfxHintId::SwLegacyModify)
158  {
159  auto pLegacyHint = static_cast<const sw::LegacyModifyHint*>(&rHint);
160  CallSwClientNotify(rHint);
161  if (pLegacyHint->m_pOld && (RES_REMOVE_UNO_OBJECT == pLegacyHint->m_pOld->Which()))
162  SetXTOXMark(css::uno::Reference<css::text::XDocumentIndexMark>(nullptr));
163  } else if (auto pCollectHint = dynamic_cast<const sw::CollectTextMarksHint*>(&rHint))
164  {
165  if(GetTextTOXMark())
166  pCollectHint->m_rMarks.push_back(this);
167  } else if (auto pCollectLayoutHint = dynamic_cast<const sw::CollectTextTOXMarksForLayoutHint*>(&rHint))
168  {
169  if(!GetTextTOXMark())
170  return;
171  auto& rTextMark = *GetTextTOXMark();
172  auto& rNode = rTextMark.GetTextNode();
173  auto pLayout = pCollectLayoutHint->m_pLayout;
174  // Check basic sanity and that it is part of our layout and not in undo
175  if(!rNode.GetNodes().IsDocNodes() || !rNode.GetText().getLength() || !rNode.HasWriterListeners() || !rNode.getLayoutFrame(pLayout))
176  return;
177  // Check for being hidden
178  if(rNode.IsHiddenByParaField() || SwScriptInfo::IsInHiddenRange(rNode, rTextMark.GetStart()))
179  return;
180  // Check for being hidden by hidden redlines
181  if (pLayout && pLayout->HasMergedParas() && sw::IsMarkHintHidden(*pLayout, rNode, rTextMark))
182  return;
183  pCollectLayoutHint->m_rMarks.push_back(rTextMark);
184  }
185 }
186 
188 {
189  const SwPtrMsgPoolItem aMsgHint(RES_REMOVE_UNO_OBJECT, &static_cast<sw::BroadcastingModify&>(*this));
190  CallSwClientNotify(sw::LegacyModifyHint(&aMsgHint, &aMsgHint));
191 }
192 
193 OUString SwTOXMark::GetText(SwRootFrame const*const pLayout) const
194 {
195  if( !m_aAltText.isEmpty() )
196  return m_aAltText;
197 
199  {
200  const sal_Int32* pEndIdx = m_pTextAttr->GetEnd();
201  OSL_ENSURE( pEndIdx, "TOXMark without mark!");
202  if( pEndIdx )
203  {
204  const sal_Int32 nStt = m_pTextAttr->GetStart();
205  return m_pTextAttr->GetpTextNd()->GetExpandText(pLayout, nStt, *pEndIdx-nStt);
206  }
207  }
208 
209  return OUString();
210 }
211 
212 // Manage types of TOX
213 SwTOXType::SwTOXType(SwDoc& rDoc, TOXTypes eTyp, const OUString& rName)
214  : m_rDoc(rDoc)
215  , m_aName(rName)
216  , m_eType(eTyp)
217 {
218 }
219 
221  : m_rDoc(rCopy.m_rDoc)
222  , m_aName(rCopy.m_aName)
223  , m_eType(rCopy.m_eType)
224 {
225  if (auto pRegisteredIn = const_cast<SwTOXType&>(rCopy).GetRegisteredIn())
226  pRegisteredIn->Add(this);
227 }
228 
229 static const char* STR_POOLCOLL_TOX_ARY[] =
230 {
231  // Subcategory Index-Directories
232  STR_POOLCOLL_TOX_IDXH,
233  STR_POOLCOLL_TOX_IDX1,
234  STR_POOLCOLL_TOX_IDX2,
235  STR_POOLCOLL_TOX_IDX3,
236  STR_POOLCOLL_TOX_IDXBREAK
237 };
238 
239 static const char* STR_POOLCOLL_TOX_CNTNT_ARY[] =
240 {
241  // Subcategory Tables of Contents
242  STR_POOLCOLL_TOX_CNTNTH,
243  STR_POOLCOLL_TOX_CNTNT1,
244  STR_POOLCOLL_TOX_CNTNT2,
245  STR_POOLCOLL_TOX_CNTNT3,
246  STR_POOLCOLL_TOX_CNTNT4,
247  STR_POOLCOLL_TOX_CNTNT5
248 };
249 
250 static const char* STR_POOLCOLL_TOX_CNTNT_EXTRA_ARY[] =
251 {
252  // Subcategory Table of Contents more Levels 5 - 10
253  STR_POOLCOLL_TOX_CNTNT6,
254  STR_POOLCOLL_TOX_CNTNT7,
255  STR_POOLCOLL_TOX_CNTNT8,
256  STR_POOLCOLL_TOX_CNTNT9,
257  STR_POOLCOLL_TOX_CNTNT10
258 };
259 
260 static const char* STR_POOLCOLL_TOX_USER_ARY[] =
261 {
262  // Subcategory User-Directories:
263  STR_POOLCOLL_TOX_USERH,
264  STR_POOLCOLL_TOX_USER1,
265  STR_POOLCOLL_TOX_USER2,
266  STR_POOLCOLL_TOX_USER3,
267  STR_POOLCOLL_TOX_USER4,
268  STR_POOLCOLL_TOX_USER5
269 };
270 
271 static const char* STR_POOLCOLL_TOX_USER_EXTRA_ARY[] =
272 {
273  // Subcategory User-Directories more Levels 5 - 10
274  STR_POOLCOLL_TOX_USER6,
275  STR_POOLCOLL_TOX_USER7,
276  STR_POOLCOLL_TOX_USER8,
277  STR_POOLCOLL_TOX_USER9,
278  STR_POOLCOLL_TOX_USER10
279 };
280 
281 static const char* STR_POOLCOLL_TOX_ILLUS_ARY[] =
282 {
283  // Illustrations Index
284  STR_POOLCOLL_TOX_ILLUSH,
285  STR_POOLCOLL_TOX_ILLUS1
286 };
287 
288 static const char* STR_POOLCOLL_TOX_OBJECT_ARY[] =
289 {
290  // Object Index
291  STR_POOLCOLL_TOX_OBJECTH,
292  STR_POOLCOLL_TOX_OBJECT1
293 };
294 
295 static const char* STR_POOLCOLL_TOX_TABLES_ARY[] =
296 {
297  // Tables Index
298  STR_POOLCOLL_TOX_TABLESH,
299  STR_POOLCOLL_TOX_TABLES1
300 };
301 
302 static const char* STR_POOLCOLL_TOX_AUTHORITIES_ARY[] =
303 {
304  // Index of Authorities
305  STR_POOLCOLL_TOX_AUTHORITIESH,
306  STR_POOLCOLL_TOX_AUTHORITIES1
307 };
308 
309 static const char* STR_POOLCOLL_TOX_CITATION_ARY[] =
310 {
311  STR_POOLCOLL_TOX_CITATION
312 };
313 
314 // Edit forms
315 SwForm::SwForm( TOXTypes eTyp ) // #i21237#
316  : m_eType( eTyp ), m_nFormMaxLevel( SwForm::GetFormMaxLevel( eTyp )),
317 // nFirstTabPos( lNumberIndent ),
318  m_bCommaSeparated(false)
319 {
320  //bHasFirstTabPos =
321  m_bIsRelTabPos = true;
322 
323  // The table of contents has a certain number of headlines + headings
324  // The user has 10 levels + headings
325  // Keyword has 3 levels + headings+ separator
326  // Indexes of tables, object illustrations and authorities consist of a heading and one level
327 
328  const char** pPoolId;
329  switch( m_eType )
330  {
331  case TOX_INDEX: pPoolId = STR_POOLCOLL_TOX_ARY; break;
332  case TOX_USER: pPoolId = STR_POOLCOLL_TOX_USER_ARY; break;
333  case TOX_CONTENT: pPoolId = STR_POOLCOLL_TOX_CNTNT_ARY; break;
334  case TOX_ILLUSTRATIONS: pPoolId = STR_POOLCOLL_TOX_ILLUS_ARY; break;
335  case TOX_OBJECTS : pPoolId = STR_POOLCOLL_TOX_OBJECT_ARY; break;
336  case TOX_TABLES : pPoolId = STR_POOLCOLL_TOX_TABLES_ARY; break;
337  case TOX_AUTHORITIES : pPoolId = STR_POOLCOLL_TOX_AUTHORITIES_ARY; break;
338  case TOX_CITATION : pPoolId = STR_POOLCOLL_TOX_CITATION_ARY; break;
339  default:
340  OSL_ENSURE( false, "invalid TOXTyp");
341  return ;
342  }
343 
344  SwFormTokens aTokens;
346  {
347  SwFormToken aLinkStt (TOKEN_LINK_START);
348  aLinkStt.sCharStyleName = SwResId(STR_POOLCHR_TOXJUMP);
349  aTokens.push_back(aLinkStt);
350  }
351 
352  if (TOX_CONTENT == m_eType)
353  {
354  aTokens.emplace_back(TOKEN_ENTRY_NO);
355  aTokens.emplace_back(TOKEN_ENTRY_TEXT);
356  }
357  else
358  aTokens.emplace_back(TOKEN_ENTRY);
359 
360  if (TOX_AUTHORITIES != m_eType)
361  {
362  SwFormToken aToken(TOKEN_TAB_STOP);
363  aToken.nTabStopPosition = 0;
364 
365  // #i36870# right aligned tab for all
366  aToken.cTabFillChar = '.';
367  aToken.eTabAlign = SvxTabAdjust::End;
368 
369  aTokens.push_back(aToken);
370  aTokens.emplace_back(TOKEN_PAGE_NUMS);
371  }
372 
374  aTokens.emplace_back(TOKEN_LINK_END);
375 
376  SetTemplate(0, SwResId(*pPoolId++));
377 
378  if(TOX_INDEX == m_eType)
379  {
380  for( sal_uInt16 i = 1; i < 5; ++i )
381  {
382  if(1 == i)
383  {
384  SwFormTokens aTmpTokens;
385  SwFormToken aTmpToken(TOKEN_ENTRY);
386  aTmpTokens.push_back(aTmpToken);
387 
388  SetPattern( i, aTmpTokens );
389  SetTemplate(i, SwResId(STR_POOLCOLL_TOX_IDXBREAK));
390  }
391  else
392  {
393  SetPattern( i, aTokens );
395  }
396  }
397  }
398  else
399  {
400  for (sal_uInt16 i = 1; i < GetFormMax(); ++i, ++pPoolId) // Number 0 is the title
401  {
402  if (TOX_AUTHORITIES == m_eType)
403  {
404  SwFormTokens aAuthTokens;
405  lcl_FillAuthPattern(aAuthTokens, i);
406  SetPattern(i, aAuthTokens);
407  }
408  else
409  SetPattern( i, aTokens );
410 
411  if( TOX_CONTENT == m_eType && 6 == i )
413  else if( TOX_USER == m_eType && 6 == i )
415  else if( TOX_AUTHORITIES == m_eType ) //reuse the same STR_POOLCOLL_TOX_AUTHORITIES1 id each time
416  pPoolId = STR_POOLCOLL_TOX_AUTHORITIES_ARY + 1;
417  SetTemplate(i, SwResId(*pPoolId));
418  }
419  }
420 }
421 
422 SwForm::SwForm(const SwForm& rForm)
423  : m_eType( rForm.m_eType )
424 {
425  *this = rForm;
426 }
427 
429 {
430  m_eType = rForm.m_eType;
432 // nFirstTabPos = rForm.nFirstTabPos;
433 // bHasFirstTabPos = rForm.bHasFirstTabPos;
436  for(sal_uInt16 i=0; i < m_nFormMaxLevel; ++i)
437  {
438  m_aPattern[i] = rForm.m_aPattern[i];
439  m_aTemplate[i] = rForm.m_aTemplate[i];
440  }
441  return *this;
442 }
443 
444 sal_uInt16 SwForm::GetFormMaxLevel( TOXTypes eTOXType )
445 {
446  switch( eTOXType )
447  {
448  case TOX_INDEX:
449  return 5;
450  case TOX_USER:
451  case TOX_CONTENT:
452  return MAXLEVEL + 1;
453  case TOX_ILLUSTRATIONS:
454  case TOX_OBJECTS:
455  case TOX_TABLES:
456  return 2;
457  case TOX_BIBLIOGRAPHY:
458  case TOX_CITATION:
459  case TOX_AUTHORITIES:
460  return AUTH_TYPE_END + 1;
461  }
462  return 0;
463 }
464 
465 void SwForm::AdjustTabStops( SwDoc const & rDoc ) // #i21237#
466 {
467  const sal_uInt16 nFormMax = GetFormMax();
468  for ( sal_uInt16 nLevel = 1; nLevel < nFormMax; ++nLevel )
469  {
470  SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName( GetTemplate(nLevel) );
471  if( pColl == nullptr )
472  {
473  // Paragraph Style for this level has not been created.
474  // --> No need to propagate default values
475  continue;
476  }
477 
478  const SvxTabStopItem& rTabStops = pColl->GetTabStops(false);
479  const sal_uInt16 nTabCount = rTabStops.Count();
480  if (nTabCount != 0)
481  {
482  SwFormTokens aCurrentPattern = GetPattern(nLevel);
483  SwFormTokens::iterator aIt = aCurrentPattern.begin();
484 
485  bool bChanged = false;
486  for(sal_uInt16 nTab = 0; nTab < nTabCount; ++nTab)
487  {
488  const SvxTabStop& rTab = rTabStops[nTab];
489 
490  if ( rTab.GetAdjustment() == SvxTabAdjust::Default )
491  continue; // ignore the default tab stop
492 
493  aIt = find_if( aIt, aCurrentPattern.end(), SwFormTokenEqualToFormTokenType(TOKEN_TAB_STOP) );
494  if ( aIt != aCurrentPattern.end() )
495  {
496  bChanged = true;
497  aIt->nTabStopPosition = rTab.GetTabPos();
498  aIt->eTabAlign =
499  ( nTab == nTabCount - 1
500  && rTab.GetAdjustment() == SvxTabAdjust::Right )
501  ? SvxTabAdjust::End
502  : rTab.GetAdjustment();
503  aIt->cTabFillChar = rTab.GetFill();
504  ++aIt;
505  }
506  else
507  break; // no more tokens to replace
508  }
509 
510  if ( bChanged )
511  SetPattern( nLevel, aCurrentPattern );
512  }
513  }
514 }
515 
516 OUString SwForm::GetFormEntry() {return "<E>";}
517 OUString SwForm::GetFormTab() {return "<T>";}
518 OUString SwForm::GetFormPageNums() {return "<#>";}
519 OUString SwForm::GetFormLinkStt() {return "<LS>";}
520 OUString SwForm::GetFormLinkEnd() {return "<LE>";}
521 OUString SwForm::GetFormEntryNum() {return "<E#>";}
522 OUString SwForm::GetFormEntryText() {return "<ET>";}
523 OUString SwForm::GetFormChapterMark() {return "<C>";}
524 OUString SwForm::GetFormText() {return "<X>";}
525 OUString SwForm::GetFormAuth() {return "<A>";}
526 
527 SwTOXBase::SwTOXBase(const SwTOXType* pTyp, const SwForm& rForm,
528  SwTOXElement nCreaType, const OUString& rTitle )
529  : SwClient(const_cast<sw::BroadcastingModify*>(static_cast<sw::BroadcastingModify const *>(pTyp)))
530  , m_aForm(rForm)
531  , m_aTitle(rTitle)
532  , m_eLanguage(::GetAppLanguage())
533  , m_nCreateType(nCreaType)
534  , m_nOLEOptions(SwTOOElements::NONE)
535  , m_eCaptionDisplay(CAPTION_COMPLETE)
536  , m_bProtected( true )
537  , m_bFromChapter(false)
538  , m_bFromObjectNames(false)
539  , m_bLevelFromChapter(false)
540  , maMSTOCExpression()
541  , mbKeepExpression(true)
542 {
543  m_aData.nOptions = SwTOIOptions::NONE;
544 }
545 
546 SwTOXBase::SwTOXBase( const SwTOXBase& rSource, SwDoc* pDoc )
547  : SwClient( rSource.GetRegisteredInNonConst() )
548  , mbKeepExpression(true)
549 {
550  CopyTOXBase( pDoc, rSource );
551 }
552 
554 {
555  rType.Add( this );
556 }
557 
558 void SwTOXBase::CopyTOXBase( SwDoc* pDoc, const SwTOXBase& rSource )
559 {
561  SwTOXType* pType = const_cast<SwTOXType*>(rSource.GetTOXType());
562  if( pDoc &&
563  std::find_if(pDoc->GetTOXTypes().begin(), pDoc->GetTOXTypes().end(),
564  [=](const std::unique_ptr<SwTOXType> & p) { return p.get() == pType; })
565  == pDoc->GetTOXTypes().end())
566  {
567  // type not in pDoc, so create it now
568  const SwTOXTypes& rTypes = pDoc->GetTOXTypes();
569  bool bFound = false;
570  for( size_t n = rTypes.size(); n; )
571  {
572  const SwTOXType* pCmp = rTypes[ --n ].get();
573  if( pCmp->GetType() == pType->GetType() &&
574  pCmp->GetTypeName() == pType->GetTypeName() )
575  {
576  pType = const_cast<SwTOXType*>(pCmp);
577  bFound = true;
578  break;
579  }
580  }
581 
582  if( !bFound )
583  pType = const_cast<SwTOXType*>(pDoc->InsertTOXType( *pType ));
584  }
585  pType->Add( this );
586 
587  m_nCreateType = rSource.m_nCreateType;
588  m_aTitle = rSource.m_aTitle;
589  m_aForm = rSource.m_aForm;
592  m_bProtected = rSource.m_bProtected;
593  m_bFromChapter = rSource.m_bFromChapter;
598  m_nOLEOptions = rSource.m_nOLEOptions;
599  m_eLanguage = rSource.m_eLanguage;
602 
603  for( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
604  m_aStyleNames[i] = rSource.m_aStyleNames[i];
605 
606  // it's the same data type!
607  m_aData.nOptions = rSource.m_aData.nOptions;
608 
609  if( !pDoc || pDoc->IsCopyIsMove() )
610  m_aName = rSource.GetTOXName();
611  else
612  m_aName = pDoc->GetUniqueTOXBaseName( *pType, rSource.GetTOXName() );
613 }
614 
615 // TOX specific functions
617 {
618 // if( GetTOXType()->GetType() == TOX_USER )
619 // delete aData.pTemplateName;
620 }
621 
622 void SwTOXBase::SetTitle(const OUString& rTitle)
623  { m_aTitle = rTitle; }
624 
625 void SwTOXBase::SetBookmarkName(const OUString& bName)
626 {
627  m_aBookmarkName = bName;
628 }
629 
630 void SwTOXBase::SetEntryTypeName(const OUString& sName)
631 {
632  m_aEntryTypeName = sName ;
633 }
634 
636 {
637  m_aForm = rSource.m_aForm;
638  m_aName = rSource.m_aName;
639  m_aTitle = rSource.m_aTitle;
643  for(sal_uInt16 nLevel = 0; nLevel < MAXLEVEL; nLevel++)
646  m_eLanguage = rSource.m_eLanguage;
648  m_aData = rSource.m_aData;
649  m_nCreateType = rSource.m_nCreateType;
650  m_nOLEOptions = rSource.m_nOLEOptions;
652  m_bProtected = rSource.m_bProtected;
653  m_bFromChapter = rSource.m_bFromChapter;
656 
657  if (rSource.GetAttrSet())
658  SetAttrSet(*rSource.GetAttrSet());
659 
660  return *this;
661 }
662 
663 OUString SwFormToken::GetString() const
664 {
665  OUString sToken;
666 
667  switch( eTokenType )
668  {
669  case TOKEN_ENTRY_NO:
670  sToken = SwForm::GetFormEntryNum();
671  break;
672  case TOKEN_ENTRY_TEXT:
673  sToken = SwForm::GetFormEntryText();
674  break;
675  case TOKEN_ENTRY:
676  sToken = SwForm::GetFormEntry();
677  break;
678  case TOKEN_TAB_STOP:
679  sToken = SwForm::GetFormTab();
680  break;
681  case TOKEN_TEXT:
682  // Return a Token only if Text is not empty!
683  if( sText.isEmpty() )
684  {
685  return OUString();
686  }
687  sToken = SwForm::GetFormText();
688  break;
689  case TOKEN_PAGE_NUMS:
690  sToken = SwForm::GetFormPageNums();
691  break;
692  case TOKEN_CHAPTER_INFO:
693  sToken = SwForm::GetFormChapterMark();
694  break;
695  case TOKEN_LINK_START:
696  sToken = SwForm::GetFormLinkStt();
697  break;
698  case TOKEN_LINK_END:
699  sToken = SwForm::GetFormLinkEnd();
700  break;
701  case TOKEN_AUTHORITY:
702  {
703  sToken = SwForm::GetFormAuth();
704  }
705  break;
706  case TOKEN_END:
707  break;
708  }
709 
710  OUString sData = " " + sCharStyleName + "," + OUString::number( nPoolId ) + ",";
711 
712  // TabStopPosition and TabAlign or ChapterInfoFormat
713  switch (eTokenType)
714  {
715  case TOKEN_TAB_STOP:
716  sData += OUString::number( nTabStopPosition ) + ","
717  + OUString::number( static_cast< sal_Int32 >(eTabAlign) ) + ","
718  + OUStringChar(cTabFillChar) + ","
719  + OUString::number( bWithTab ? 1 : 0 );
720  break;
721  case TOKEN_CHAPTER_INFO:
722  case TOKEN_ENTRY_NO:
723  // add also maximum permitted level
724  sData += OUString::number( nChapterFormat ) + ","
725  + OUString::number( nOutlineLevel );
726  break;
727  case TOKEN_TEXT:
728  sData += OUStringChar(TOX_STYLE_DELIMITER)
729  + sText.replaceAll(OUStringChar(TOX_STYLE_DELIMITER), "")
730  + OUStringChar(TOX_STYLE_DELIMITER);
731  break;
732  case TOKEN_AUTHORITY:
733  if (nAuthorityField<10)
734  {
735  sData = "0" + OUString::number( nAuthorityField ) + sData;
736  }
737  else
738  {
739  sData = OUString::number( nAuthorityField ) + sData;
740  }
741  break;
742  default:
743  break;
744  }
745 
746  return sToken.subView(0, sToken.getLength()-1) + sData + sToken.subView(sToken.getLength()-1);
747 }
748 
749 // -> #i21237#
750 
759 static FormTokenType lcl_GetTokenType(const OUString & sToken,
760  sal_Int32 & rTokenLen)
761 {
762  static struct
763  {
764  OUString sTokenStart;
765  sal_Int16 nTokenLength;
766  FormTokenType eTokenType;
767  } const aTokenArr[] = {
768  { SwForm::GetFormTab().copy(0, 2), 3, TOKEN_TAB_STOP },
769  { SwForm::GetFormPageNums().copy(0, 2), 3, TOKEN_PAGE_NUMS },
770  { SwForm::GetFormLinkStt().copy(0, 3), 4, TOKEN_LINK_START },
771  { SwForm::GetFormLinkEnd().copy(0, 3), 4, TOKEN_LINK_END },
772  { SwForm::GetFormEntryNum().copy(0, 3), 4, TOKEN_ENTRY_NO },
773  { SwForm::GetFormEntryText().copy(0, 3), 4, TOKEN_ENTRY_TEXT },
774  { SwForm::GetFormChapterMark().copy(0, 2), 3, TOKEN_CHAPTER_INFO },
775  { SwForm::GetFormText().copy(0, 2), 3, TOKEN_TEXT },
776  { SwForm::GetFormEntry().copy(0, 2), 3, TOKEN_ENTRY },
777  { SwForm::GetFormAuth().copy(0, 2), 5, TOKEN_AUTHORITY }
778  };
779 
780  for(const auto & i : aTokenArr)
781  {
782  if( sToken.startsWith( i.sTokenStart ) )
783  {
784  rTokenLen = i.nTokenLength;
785  return i.eTokenType;
786  }
787  }
788 
789  SAL_WARN("sw.core", "SwFormTokensHelper: invalid token");
790  return TOKEN_END;
791 }
792 
801 static OUString
802 lcl_SearchNextToken(const OUString & sPattern, sal_Int32 const nStt)
803 {
804  sal_Int32 nEnd = sPattern.indexOf( '>', nStt );
805  if (nEnd >= 0)
806  {
807  // apparently the TOX_STYLE_DELIMITER act as a bracketing for
808  // TOKEN_TEXT tokens so that the user can have '>' inside the text...
809  const sal_Int32 nTextSeparatorFirst = sPattern.indexOf( TOX_STYLE_DELIMITER, nStt );
810  if ( nTextSeparatorFirst >= 0
811  && nTextSeparatorFirst + 1 < sPattern.getLength()
812  && nTextSeparatorFirst < nEnd)
813  {
814  const sal_Int32 nTextSeparatorSecond = sPattern.indexOf( TOX_STYLE_DELIMITER,
815  nTextSeparatorFirst + 1 );
816  // Since nEnd>=0 we don't need to check if nTextSeparatorSecond<0!
817  if( nEnd < nTextSeparatorSecond )
818  nEnd = sPattern.indexOf( '>', nTextSeparatorSecond );
819  // FIXME: No check to verify that nEnd is still >=0?
820  assert(nEnd >= 0);
821  }
822 
823  ++nEnd;
824 
825  return sPattern.copy( nStt, nEnd - nStt );
826  }
827 
828  return OUString();
829 }
830 
839 static std::optional<SwFormToken>
840 lcl_BuildToken(const OUString & sPattern, sal_Int32 & nCurPatternPos)
841 {
842  OUString sToken( lcl_SearchNextToken(sPattern, nCurPatternPos) );
843  nCurPatternPos += sToken.getLength();
844  sal_Int32 nTokenLen = 0;
845  FormTokenType const eTokenType = lcl_GetTokenType(sToken, nTokenLen);
846  if (TOKEN_END == eTokenType) // invalid input? skip it
847  {
848  nCurPatternPos = sPattern.getLength();
849  return std::optional<SwFormToken>();
850  }
851 
852  // at this point sPattern contains the
853  // character style name, the PoolId, tab stop position, tab stop alignment, chapter info format
854  // the form is: CharStyleName, PoolId[, TabStopPosition|ChapterInfoFormat[, TabStopAlignment[, TabFillChar]]]
855  // in text tokens the form differs from the others: CharStyleName, PoolId[,\0xffinserted text\0xff]
856  SwFormToken eRet( eTokenType );
857  const OUString sAuthFieldEnum = sToken.copy( 2, 2 );
858  sToken = sToken.copy( nTokenLen, sToken.getLength() - nTokenLen - 1);
859 
860  sal_Int32 nIdx{ 0 };
861  eRet.sCharStyleName = sToken.getToken( 0, ',', nIdx );
862  OUString sTmp( sToken.getToken( 0, ',', nIdx ));
863  if( !sTmp.isEmpty() )
864  eRet.nPoolId = o3tl::narrowing<sal_uInt16>(sTmp.toInt32());
865 
866  switch( eTokenType )
867  {
868 //i53420
869  case TOKEN_CHAPTER_INFO:
870 //i53420
871  case TOKEN_ENTRY_NO:
872  sTmp = sToken.getToken( 0, ',', nIdx ); // token 2
873  if( !sTmp.isEmpty() )
874  eRet.nChapterFormat = o3tl::narrowing<sal_uInt16>(sTmp.toInt32());
875  sTmp = sToken.getToken( 0, ',', nIdx ); // token 3
876  if( !sTmp.isEmpty() )
877  eRet.nOutlineLevel = o3tl::narrowing<sal_uInt16>(sTmp.toInt32()); //the maximum outline level to examine
878  break;
879 
880  case TOKEN_TEXT:
881  {
882  const sal_Int32 nStartText = sToken.indexOf( TOX_STYLE_DELIMITER );
883  if( nStartText>=0 && nStartText+1<sToken.getLength())
884  {
885  const sal_Int32 nEndText = sToken.indexOf( TOX_STYLE_DELIMITER,
886  nStartText + 1);
887  if( nEndText>=0 )
888  {
889  eRet.sText = sToken.copy( nStartText + 1,
890  nEndText - nStartText - 1);
891  }
892  }
893  }
894  break;
895 
896  case TOKEN_TAB_STOP:
897  sTmp = sToken.getToken( 0, ',', nIdx ); // token 2
898  if( !sTmp.isEmpty() )
899  eRet.nTabStopPosition = sTmp.toInt32();
900 
901  sTmp = sToken.getToken( 0, ',', nIdx ); // token 3
902  if( !sTmp.isEmpty() )
903  eRet.eTabAlign = static_cast<SvxTabAdjust>(sTmp.toInt32());
904 
905  sTmp = sToken.getToken( 0, ',', nIdx ); // token 4
906  if( !sTmp.isEmpty() )
907  eRet.cTabFillChar = sTmp[0];
908 
909  sTmp = sToken.getToken( 0, ',', nIdx ); // token 5
910  if( !sTmp.isEmpty() )
911  eRet.bWithTab = 0 != sTmp.toInt32();
912  break;
913 
914  case TOKEN_AUTHORITY:
915  eRet.nAuthorityField = o3tl::narrowing<sal_uInt16>(sAuthFieldEnum.toInt32());
916  break;
917  default: break;
918  }
919  return eRet;
920 }
921 
922 SwFormTokensHelper::SwFormTokensHelper(const OUString & rPattern)
923 {
924  sal_Int32 nCurPatternPos = 0;
925 
926  while (nCurPatternPos < rPattern.getLength())
927  {
928  std::optional<SwFormToken> const oToken(
929  lcl_BuildToken(rPattern, nCurPatternPos));
930  if (oToken)
931  m_Tokens.push_back(*oToken);
932  }
933 }
934 
935 // <- #i21237#
936 
937 void SwForm::SetPattern(sal_uInt16 nLevel, const SwFormTokens& rTokens)
938 {
939  OSL_ENSURE(nLevel < GetFormMax(), "Index >= FORM_MAX");
940  m_aPattern[nLevel] = rTokens;
941 }
942 
943 void SwForm::SetPattern(sal_uInt16 nLevel, const OUString & rStr)
944 {
945  OSL_ENSURE(nLevel < GetFormMax(), "Index >= FORM_MAX");
946 
948  m_aPattern[nLevel] = aHelper.GetTokens();
949 }
950 
951 const SwFormTokens& SwForm::GetPattern(sal_uInt16 nLevel) const
952 {
953  OSL_ENSURE(nLevel < GetFormMax(), "Index >= FORM_MAX");
954  return m_aPattern[nLevel];
955 }
956 
957 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SwFormTokens & GetTokens() const
Returns vector of tokens.
Definition: tox.hxx:313
std::vector< SwFormToken > SwFormTokens
Vector of tokens.
Definition: tox.hxx:289
SwCaptionDisplay m_eCaptionDisplay
Definition: tox.hxx:452
OUString m_aStyleNames[MAXLEVEL]
Definition: tox.hxx:439
const sal_Unicode C_NUM_REPL
Definition: tox.cxx:46
const SfxItemSet * GetAttrSet() const
Definition: doctxm.cxx:2038
TOXTypes
Definition: toxe.hxx:39
bool IsMarkHintHidden(SwRootFrame const &rLayout, SwTextNode const &rNode, SwTextAttrEnd const &rHint)
Definition: reffld.cxx:1113
void SetAttrSet(const SfxItemSet &)
Definition: doctxm.cxx:2046
void Add(SwClient *pDepend)
Definition: calbck.cxx:173
const SvxTabStopItem & GetTabStops(bool=true) const
Definition: paratr.hxx:228
SwTOXMark()
pool default constructor
Definition: tox.cxx:92
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
sal_uInt16 Count() const
OUString m_sSequenceName
Definition: tox.hxx:440
static OUString lcl_SearchNextToken(const OUString &sPattern, sal_Int32 const nStt)
Returns the string of a token.
Definition: tox.cxx:802
SwTextTOXMark * m_pTextAttr
Definition: tox.hxx:98
OUString m_aName
SwTOXType(SwDoc &rDoc, TOXTypes eTyp, const OUString &rName)
Definition: tox.cxx:213
void SetPattern(sal_uInt16 nLevel, const SwFormTokens &rName)
Definition: tox.cxx:937
sal_uInt16 nOutlineLevel
Definition: tox.hxx:255
constexpr TypedWhichId< SwPtrMsgPoolItem > RES_REMOVE_UNO_OBJECT(181)
static const char * STR_POOLCOLL_TOX_CNTNT_EXTRA_ARY[]
Definition: tox.cxx:250
static const char * STR_POOLCOLL_TOX_ARY[]
Definition: tox.cxx:229
SwTOOElements
Definition: tox.hxx:413
Definition: tox.hxx:316
OUString m_aTitle
Definition: tox.hxx:433
const SwTOXType * InsertTOXType(const SwTOXType &rTyp)
Definition: doctxm.cxx:628
SwTextFormatColl * FindTextFormatCollByName(const OUString &rName) const
Definition: doc.hxx:799
OUString m_aBookmarkName
Definition: tox.hxx:434
SAL_DLLPRIVATE void SetXTOXMark(css::uno::Reference< css::text::XDocumentIndexMark > const &xMark)
Definition: tox.hxx:168
static OUString GetFormLinkStt()
Definition: tox.cxx:519
OUString const & GetTemplate(sal_uInt16 nLevel) const
Definition: tox.hxx:688
void SetTitle(const OUString &rTitle)
Definition: tox.cxx:622
#define TOX_STYLE_DELIMITER
Definition: tox.hxx:426
sal_Int64 n
Definition: doc.hxx:188
SwForm(TOXTypes eTOXType=TOX_CONTENT)
Definition: tox.cxx:315
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:90
static const char * STR_POOLCOLL_TOX_ILLUS_ARY[]
Definition: tox.cxx:281
static const char * STR_POOLCOLL_TOX_CNTNT_ARY[]
Definition: tox.cxx:239
union SwTOXBase::@30 m_aData
sal_uInt16 m_nFormMaxLevel
Definition: tox.hxx:322
sal_uInt16 GetFormMax() const
Definition: tox.hxx:699
Dialog to specify the properties of date form field.
static OUString GetFormTab()
Definition: tox.cxx:517
SwFormTokens m_Tokens
the tokens
Definition: tox.hxx:298
static const char * STR_POOLCOLL_TOX_OBJECT_ARY[]
Definition: tox.cxx:288
sal_uInt16 nLevel
Definition: tox.hxx:446
static std::optional< SwFormToken > lcl_BuildToken(const OUString &sPattern, sal_Int32 &nCurPatternPos)
Builds a token from its string representation.
Definition: tox.cxx:840
bool m_bFromChapter
Definition: tox.hxx:454
sal_uInt16 nPoolId
Definition: tox.hxx:252
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
bool bWithTab
Definition: tox.hxx:258
virtual ~SwTOXMark() override
Definition: tox.cxx:133
SfxHintId GetId() const
void InvalidateTOXMark()
Definition: tox.cxx:187
bool m_bLevelFromChapter
Definition: tox.hxx:457
sal_Unicode cTabFillChar
Definition: tox.hxx:257
SwTOIOptions nOptions
Definition: tox.hxx:447
static const char * STR_POOLCOLL_TOX_AUTHORITIES_ARY[]
Definition: tox.cxx:302
SwDoc & m_rDoc
Definition: docbm.cxx:1208
sal_uInt16 sal_Unicode
const SwTOXType * GetTOXType() const
Definition: tox.hxx:714
SwTOXElement m_nCreateType
Definition: tox.hxx:450
void RegisterToTOXType(SwTOXType &rMark)
Definition: tox.cxx:553
void SetTemplate(sal_uInt16 nLevel, const OUString &rName)
Definition: tox.hxx:682
OUString sText
Definition: tox.hxx:248
sal_Int32 & GetTabPos()
sal_Int32 GetStart() const
Definition: txatbase.hxx:86
static OUString GetFormEntry()
Definition: tox.cxx:516
static const char * STR_POOLCOLL_TOX_USER_EXTRA_ARY[]
Definition: tox.cxx:271
bool m_bProtected
Definition: tox.hxx:453
LanguageType m_eLanguage
Definition: tox.hxx:442
OUString maMSTOCExpression
Definition: tox.hxx:462
SvxTabAdjust & GetAdjustment()
static OUString GetFormEntryNum()
Definition: tox.cxx:521
#define SAL_N_ELEMENTS(arr)
virtual const sal_Int32 * GetEnd() const override
end position
Definition: atrtox.cxx:49
sal_Int32 m_nLevel
void EndListeningAll()
OUString GetString() const
Definition: tox.cxx:663
int i
SwTOXElement
Definition: tox.hxx:368
virtual void Notify(const SfxHint &rHint) override
Definition: tox.cxx:155
FormTokenType eTokenType
Definition: tox.hxx:251
const SwFormTokens & GetPattern(sal_uInt16 nLevel) const
Definition: tox.cxx:951
OUString sCharStyleName
Definition: tox.hxx:249
bool m_bIsRelTabPos
Definition: tox.hxx:324
void SetBookmarkName(const OUString &bName)
Definition: tox.cxx:625
Any aHelper
void RegisterToTOXType(SwTOXType &rMark)
Definition: tox.cxx:137
OUString GetText(SwRootFrame const *pLayout) const
Definition: tox.cxx:193
SwTOXBase(const SwTOXType *pTyp, const SwForm &rForm, SwTOXElement nCreaType, const OUString &rTitle)
Definition: tox.cxx:527
const OUString & GetTypeName() const
Definition: tox.hxx:706
const SwTextNode * GetpTextNd() const
Definition: txttxmrk.hxx:44
static OUString GetFormChapterMark()
Definition: tox.cxx:523
SwTOOElements m_nOLEOptions
Definition: tox.hxx:451
SwForm & operator=(const SwForm &rForm)
Definition: tox.cxx:428
sal_uInt16 nChapterFormat
Definition: tox.hxx:254
sal_uInt16 nAuthorityField
Definition: tox.hxx:256
bool StartListening(SvtBroadcaster &rBroadcaster)
static sal_uInt16 GetFormMaxLevel(TOXTypes eType)
Definition: tox.cxx:444
virtual ~SwTOXBase() override
Definition: tox.cxx:616
SwForm m_aForm
Definition: tox.hxx:431
void SetEntryTypeName(const OUString &sName)
Definition: tox.cxx:630
OUString m_sSortAlgorithm
Definition: tox.hxx:443
const sal_Unicode C_END_PAGE_NUM
Definition: tox.cxx:47
void CopyTOXBase(SwDoc *, const SwTOXBase &)
Definition: tox.cxx:558
const SwTOXTypes & GetTOXTypes() const
Definition: doc.hxx:979
ToxAuthorityField
Definition: toxe.hxx:82
SwTOXBase & operator=(const SwTOXBase &rSource)
Definition: tox.cxx:635
OUString m_aAltText
Definition: tox.hxx:89
SvtBroadcaster & GetNotifier()
Definition: calbck.hxx:99
bool m_bFromObjectNames
Definition: tox.hxx:455
OUString GetExpandText(SwRootFrame const *pLayout, const sal_Int32 nIdx=0, const sal_Int32 nLen=-1, const bool bWithNum=false, const bool bAddSpaceAfterListLabelStr=false, const bool bWithSpacesForLevel=false, const ExpandMode eAdditionalMode=ExpandMode::ExpandFootnote) const
add 4th optional parameter indicating, when that a spa...
Definition: ndtxt.cxx:3359
SwTwips nTabStopPosition
Definition: tox.hxx:250
OUString GetUniqueTOXBaseName(const SwTOXType &rType, const OUString &sChkStr) const
Definition: doctxm.cxx:635
sal_Unicode & GetFill()
static const char * STR_POOLCOLL_TOX_TABLES_ARY[]
Definition: tox.cxx:295
OUString m_aEntryTypeName
Definition: tox.hxx:435
bool IsCopyIsMove() const
Definition: doc.hxx:1372
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
LanguageType GetAppLanguage()
Definition: init.cxx:722
TOXTypes m_eType
Definition: tox.hxx:321
const SwTOXType * m_pType
Definition: tox.hxx:88
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:159
OUString m_sMainEntryCharStyle
Definition: tox.hxx:437
static const char * STR_POOLCOLL_TOX_USER_ARY[]
Definition: tox.cxx:260
OUString m_aTemplate[AUTH_TYPE_END+1]
Definition: tox.hxx:319
static OUString GetFormLinkEnd()
Definition: tox.cxx:520
void * p
static FormTokenType lcl_GetTokenType(const OUString &sToken, sal_Int32 &rTokenLen)
Returns the type of a token.
Definition: tox.cxx:759
static OUString GetFormText()
Definition: tox.cxx:524
static OUString GetFormEntryText()
Definition: tox.cxx:522
constexpr TypedWhichId< SwTOXMark > RES_TXTATR_TOXMARK(47)
virtual bool operator==(const SfxPoolItem &) const override
Definition: tox.cxx:144
TOXTypes GetType() const
Definition: tox.hxx:709
virtual void CallSwClientNotify(const SfxHint &rHint) const override
Definition: calbck.cxx:326
static bool IsInHiddenRange(const SwTextNode &rNode, sal_Int32 nPos)
Definition: porlay.cxx:1978
SvxTabAdjust eTabAlign
Definition: tox.hxx:253
#define SAL_WARN(area, stream)
static const char * STR_POOLCOLL_TOX_CITATION_ARY[]
Definition: tox.cxx:309
const SwTextTOXMark * GetTextTOXMark() const
Definition: tox.hxx:163
const EnumerationType m_eType
SwFormTokens m_aPattern[AUTH_TYPE_END+1]
Definition: tox.hxx:318
Helper class that converts vectors of tokens to strings and vice versa.
Definition: tox.hxx:295
OUString SwResId(std::string_view aId)
Definition: swmodule.cxx:165
static OUString GetFormAuth()
Definition: tox.cxx:525
virtual SwTOXMark * Clone(SfxItemPool *pPool=nullptr) const override
Definition: tox.cxx:150
void AdjustTabStops(SwDoc const &rDoc)
Definition: tox.cxx:465
FormTokenType
Definition: tox.hxx:231
bool m_bCommaSeparated
Definition: tox.hxx:325
const OUString & GetTOXName() const
Definition: tox.hxx:486
SwFormTokensHelper(const OUString &rStr)
constructor
Definition: tox.cxx:922
OUString m_aName
Definition: tox.hxx:432
static OUString GetFormPageNums()
Definition: tox.cxx:518