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