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