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