LibreOffice Module sw (master)  1
ww8par5.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 <config_features.h>
21 
22 #include <sal/types.h>
23 #include <tools/solar.h>
25 #include <comphelper/string.hxx>
27 #include <sot/storinfo.hxx>
28 #include <com/sun/star/embed/XStorage.hpp>
29 #include <com/sun/star/embed/ElementModes.hpp>
30 #include <com/sun/star/embed/XTransactedObject.hpp>
31 #include <com/sun/star/task/InteractionHandler.hpp>
32 
33 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
34 #include <svl/urihelper.hxx>
35 #include <svl/zforlist.hxx>
36 #include <svl/zformat.hxx>
37 #include <sfx2/linkmgr.hxx>
38 #include <rtl/character.hxx>
39 #include <unotools/charclass.hxx>
40 
41 #include <ucbhelper/content.hxx>
43 
44 #include <com/sun/star/i18n/ScriptType.hpp>
45 #include <com/sun/star/i18n/XBreakIterator.hpp>
46 #include <hintids.hxx>
47 #include <editeng/fontitem.hxx>
48 #include <editeng/fhgtitem.hxx>
49 #include <editeng/langitem.hxx>
50 #include <fmtfld.hxx>
51 #include <fmtanchr.hxx>
52 #include <pam.hxx>
53 #include <doc.hxx>
55 #include <IDocumentMarkAccess.hxx>
56 #include <IDocumentState.hxx>
57 #include <charatr.hxx>
58 #include <flddat.hxx>
59 #include <docufld.hxx>
60 #include <reffld.hxx>
61 #include <IMark.hxx>
62 #include <expfld.hxx>
63 #include <dbfld.hxx>
64 #include <usrfld.hxx>
65 #include <tox.hxx>
66 #include <section.hxx>
67 #include <ndtxt.hxx>
68 #include <fmtinfmt.hxx>
69 #include <chpfld.hxx>
70 #include <ftnidx.hxx>
71 #include <txtftn.hxx>
72 #include <viewsh.hxx>
73 #include <shellres.hxx>
74 #include <fmtruby.hxx>
75 #include <charfmt.hxx>
76 #include <txtatr.hxx>
77 #include <breakit.hxx>
78 #include <fmtclds.hxx>
79 #include <pagedesc.hxx>
80 #include <poolfmt.hxx>
81 #include <SwStyleNameMapper.hxx>
82 
83 #include "ww8scan.hxx"
84 #include "ww8par.hxx"
85 #include "ww8par2.hxx"
86 #include "writerhelper.hxx"
87 #include "fields.hxx"
88 #include <o3tl/safeint.hxx>
89 #include <unotools/fltrcfg.hxx>
90 #include <xmloff/odffields.hxx>
91 
92 #include <algorithm>
93 
94 #define MAX_FIELDLEN 64000
95 
96 #define WW8_TOX_LEVEL_DELIM ':'
97 
98 using namespace ::com::sun::star;
99 using namespace msfilter::util;
100 using namespace sw::util;
101 using namespace sw::mark;
102 using namespace std; // #i24377#
103 using namespace nsSwDocInfoSubType;
104 
105 // Bookmarks
106 namespace
107 {
108  // #120879# - helper method to identify a bookmark name to match the internal TOC bookmark naming convention
109  bool IsTOCBookmarkName(const OUString& rName)
110  {
111  return rName.startsWith("_Toc") || rName.startsWith(IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()+"_Toc");
112  }
113 
114  OUString EnsureTOCBookmarkName(const OUString& rName)
115  {
116  OUString sTmp = rName;
117  if ( IsTOCBookmarkName ( rName ) )
118  {
121  }
122  return sTmp;
123  }
124 }
125 
127 {
128  // should also work via pRes.nCo2OrIdx
129  WW8PLCFx_Book* pB = m_xPlcxMan->GetBook();
130  if( !pB )
131  {
132  OSL_ENSURE( pB, "WW8PLCFx_Book - Pointer does not exist" );
133  return 0;
134  }
135 
136  eBookStatus eB = pB->GetStatus();
137  if (eB & BOOK_IGNORE)
138  return 0; // ignore bookmark
139 
140  if (pB->GetIsEnd())
141  {
142  m_xReffedStck->SetAttr(*m_pPaM->GetPoint(), RES_FLTR_BOOKMARK, true,
143  pB->GetHandle(), (eB & BOOK_FIELD)!=0);
144  return 0;
145  }
146 
147  // "_Hlt*" are unnecessary
148  const OUString* pName = pB->GetName();
149  // Now, as we read the TOC field completely, we also need the hyperlinks inside keep available.
150  // So the hidden bookmarks inside for hyperlink jumping also should be kept.
151  if ( !pName ||
152  pName->startsWithIgnoreAsciiCase( "_Hlt" ) )
153  {
154  return 0;
155  }
156 
157  // do NOT call ToUpper as the bookmark name can also be a hyperlink target!
158 
159  OUString aVal;
160  if( SwFltGetFlag( m_nFieldFlags, SwFltControlStack::BOOK_TO_VAR_REF ) )
161  {
162  // set variable for translation bookmark
163  long nLen = pB->GetLen();
164  if( nLen > MAX_FIELDLEN )
165  nLen = MAX_FIELDLEN;
166 
167  long nOldPos = m_pStrm->Tell();
168  m_xSBase->WW8ReadString( *m_pStrm, aVal, pB->GetStartPos(), nLen,
169  m_eStructCharSet );
170  m_pStrm->Seek( nOldPos );
171 
172  // now here the implementation of the old "QuoteString" and
173  // I hope with a better performance as before. It's also only
174  // needed if the filterflags say we will convert bookmarks
175  // to SetExpFields! And this the exception!
176 
177  bool bSetAsHex;
178  bool bAllowCr = SwFltGetFlag(m_nFieldFlags,
180 
181  for( sal_Int32 nI = 0;
182  nI < aVal.getLength() && aVal.getLength() < (MAX_FIELDLEN - 4);
183  ++nI )
184  {
185  const sal_Unicode cChar = aVal[nI];
186  switch( cChar )
187  {
188  case 0x0b:
189  case 0x0c:
190  case 0x0d:
191  if( bAllowCr )
192  {
193  aVal = aVal.replaceAt( nI, 1, "\n" );
194  bSetAsHex = false;
195  }
196  else
197  bSetAsHex = true;
198  break;
199 
200  case 0xFE:
201  case 0xFF:
202  bSetAsHex = true;
203  break;
204 
205  default:
206  bSetAsHex = 0x20 > cChar;
207  break;
208  }
209 
210  if( bSetAsHex )
211  {
212  //all Hex-Numbers with \x before
213  OUString sTmp( "\\x" );
214  if( cChar < 0x10 )
215  sTmp += "0";
216  sTmp += OUString::number( cChar, 16 );
217  aVal = aVal.replaceAt( nI, 1 , sTmp );
218  nI += sTmp.getLength() - 1;
219  }
220  }
221 
222  if ( aVal.getLength() > (MAX_FIELDLEN - 4))
223  aVal = aVal.copy( 0, MAX_FIELDLEN - 4 );
224  }
225 
226  //e.g. inserting bookmark around field result, so we need to put
227  //it around the entire writer field, as we don't have the separation
228  //of field and field result of word, see #i16941#
229  SwPosition aStart(*m_pPaM->GetPoint());
230  if (!m_aFieldStack.empty())
231  {
232  const WW8FieldEntry &rTest = m_aFieldStack.back();
233  aStart = rTest.maStartPos;
234  }
235 
236  const OUString sOrigName = BookmarkToWriter(*pName);
237  m_xReffedStck->NewAttr( aStart,
238  SwFltBookmark( EnsureTOCBookmarkName( sOrigName ), aVal, pB->GetHandle(), IsTOCBookmarkName( sOrigName ) ));
239  return 0;
240 }
241 
243 {
244  if (WW8PLCFx_AtnBook* pAtnBook = m_xPlcxMan->GetAtnBook())
245  {
246  if (pAtnBook->getIsEnd())
247  m_xReffedStck->SetAttr(*m_pPaM->GetPoint(), RES_FLTR_ANNOTATIONMARK, true, pAtnBook->getHandle());
248  else
249  m_xReffedStck->NewAttr(*m_pPaM->GetPoint(), CntUInt16Item(RES_FLTR_ANNOTATIONMARK, pAtnBook->getHandle()));
250  }
251  return 0;
252 }
253 
255 {
256  if (WW8PLCFx_FactoidBook* pFactoidBook = m_xPlcxMan->GetFactoidBook())
257  {
258  if (pFactoidBook->getIsEnd())
259  m_xReffedStck->SetAttr(*m_pPaM->GetPoint(), RES_FLTR_RDFMARK, true, pFactoidBook->getHandle());
260  else
261  {
262  SwFltRDFMark aMark;
263  aMark.SetHandle(pFactoidBook->getHandle());
264  GetSmartTagInfo(aMark);
265  m_xReffedStck->NewAttr(*m_pPaM->GetPoint(), aMark);
266  }
267  }
268  return 0;
269 }
270 
271 // general help methods to separate parameters
272 
275 OUString SwWW8ImplReader::ConvertFFileName(const OUString& rOrg)
276 {
277  OUString aName = rOrg.replaceAll("\\\\", "\\");
278  aName = aName.replaceAll("%20", " ");
279 
280  // remove attached quotation marks
281  if (aName.endsWith("\""))
282  aName = aName.copy(0, aName.getLength()-1);
283 
284  // Need the more sophisticated url converter.
285  if (!aName.isEmpty())
286  aName = URIHelper::SmartRel2Abs(
287  INetURLObject(m_sBaseURL), aName, Link<OUString *, bool>(), false);
288 
289  return aName;
290 }
291 
292 namespace
293 {
296  void ConvertUFName( OUString& rName )
297  {
298  rName = GetAppCharClass().uppercase( rName );
299  }
300 }
301 
302 static void lcl_ConvertSequenceName(OUString& rSequenceName)
303 {
304  ConvertUFName(rSequenceName);
305  if ('0' <= rSequenceName[0] && '9' >= rSequenceName[0])
306  rSequenceName = "_" + rSequenceName;
307 }
308 
309 // FindParaStart() finds 1st Parameter that follows '\' and cToken
310 // and returns start of this parameter or -1
311 static sal_Int32 FindParaStart( const OUString& rStr, sal_Unicode cToken, sal_Unicode cToken2 )
312 {
313  bool bStr = false; // ignore inside a string
314 
315  for( sal_Int32 nBuf = 0; nBuf+1 < rStr.getLength(); nBuf++ )
316  {
317  if( rStr[ nBuf ] == '"' )
318  bStr = !bStr;
319 
320  if( !bStr
321  && rStr[ nBuf ] == '\\'
322  && ( rStr[ nBuf + 1 ] == cToken
323  || rStr[ nBuf + 1 ] == cToken2 ) )
324  {
325  nBuf += 2;
326  // skip spaces between cToken and its parameters
327  while( nBuf < rStr.getLength()
328  && rStr[ nBuf ] == ' ' )
329  nBuf++;
330  // return start of parameters
331  return nBuf < rStr.getLength() ? nBuf : -1;
332  }
333  }
334  return -1;
335 }
336 
337 // FindPara() finds the first parameter including '\' and cToken.
338 // A new String will be allocated (has to be deallocated by the caller)
339 // and everything that is part of the parameter will be returned.
340 static OUString FindPara( const OUString& rStr, sal_Unicode cToken, sal_Unicode cToken2 )
341 {
342  sal_Int32 n2; // end
343  sal_Int32 n = FindParaStart( rStr, cToken, cToken2 ); // start
344  if( n == -1)
345  return OUString();
346 
347  if( rStr[ n ] == '"'
348  || rStr[ n ] == 132 )
349  { // Quotationmark in front of parameter
350  n++; // Skip quotationmark
351  n2 = n; // search for the end starting from here
352  while( n2 < rStr.getLength()
353  && rStr[ n2 ] != 147
354  && rStr[ n2 ] != '"' )
355  n2++; // search end of parameter
356  }
357  else
358  { // no quotationmarks
359  n2 = n; // search for the end starting from here
360  while( n2 < rStr.getLength()
361  && rStr[ n2 ] != ' ' )
362  n2++; // search end of parameter
363  }
364  return rStr.copy( n, n2-n );
365 }
366 
367 static SvxNumType GetNumTypeFromName(const OUString& rStr,
368  bool bAllowPageDesc = false)
369 {
370  SvxNumType eTyp = bAllowPageDesc ? SVX_NUM_PAGEDESC : SVX_NUM_ARABIC;
371  if( rStr.startsWithIgnoreAsciiCase( "Arabi" ) ) // Arabisch, Arabic
372  eTyp = SVX_NUM_ARABIC;
373  else if( rStr.startsWith( "misch" ) ) // r"omisch
374  eTyp = SVX_NUM_ROMAN_LOWER;
375  else if( rStr.startsWith( "MISCH" ) ) // R"OMISCH
376  eTyp = SVX_NUM_ROMAN_UPPER;
377  else if( rStr.startsWithIgnoreAsciiCase( "alphabeti" ) )// alphabetisch, alphabetic
378  eTyp = ( rStr[0] == 'A' )
381  else if( rStr.startsWithIgnoreAsciiCase( "roman" ) ) // us
382  eTyp = ( rStr[0] == 'R' )
385  return eTyp;
386 }
387 
388 static SvxNumType GetNumberPara(const OUString& rStr, bool bAllowPageDesc = false)
389 {
390  OUString s( FindPara( rStr, '*', '*' ) ); // Type of number
391  SvxNumType aType = GetNumTypeFromName( s, bAllowPageDesc );
392  return aType;
393 }
394 
396 {
397  bool bRet(false);
398 
399  const SvxLanguageItem *pLang =
400  static_cast<const SvxLanguageItem*>(GetFormatAttr(RES_CHRATR_LANGUAGE));
401  OSL_ENSURE(pLang, "impossible");
402  LanguageType nDefault = pLang ? pLang->GetValue() : LANGUAGE_ENGLISH_US;
403 
404  if (nLang != nDefault)
405  {
406  rField.SetAutomaticLanguage(false);
407  rField.SetLanguage(nLang);
408  bRet = true;
409  }
410 
411  return bRet;
412 }
413 
415 {
416  //Get the system date in the correct final language layout, convert to
417  //a known language and modify the 2 digit year part to be 4 digit, and
418  //convert back to the correct language layout.
419  const sal_uInt32 nIndex = pFormatter->GetFormatIndex(NF_DATE_SYSTEM_SHORT, nLang);
420 
421  SvNumberformat aFormat = *(pFormatter->GetEntry(nIndex));
422  aFormat.ConvertLanguage(*pFormatter, nLang, LANGUAGE_ENGLISH_US);
423 
424  OUString sParams(aFormat.GetFormatstring());
425  // #i36594#
426  // Fix provided by mloiseleur@openoffice.org.
427  // A default date can have already 4 year digits, in some case
428  const sal_Int32 pos = sParams.indexOf("YYYY");
429  if ( pos == -1 )
430  {
431  sParams = sParams.replaceFirst("YY", "YYYY");
432  }
433  return sParams;
434 }
435 
436 SvNumFormatType SwWW8ImplReader::GetTimeDatePara(OUString const & rStr, sal_uInt32& rFormat,
437  LanguageType &rLang, int nWhichDefault, bool bHijri)
438 {
439  bool bRTL = false;
440  if (m_xPlcxMan && !m_bVer67)
441  {
442  SprmResult aResult = m_xPlcxMan->HasCharSprm(0x85A);
443  if (aResult.pSprm && aResult.nRemainingData >= 1 && *aResult.pSprm)
444  bRTL = true;
445  }
446  sal_uInt16 eLang = bRTL ? RES_CHRATR_CTL_LANGUAGE : RES_CHRATR_LANGUAGE;
447  const SvxLanguageItem *pLang = static_cast<const SvxLanguageItem*>(GetFormatAttr(eLang));
448  OSL_ENSURE(pLang, "impossible");
449  rLang = pLang ? pLang->GetValue() : LANGUAGE_ENGLISH_US;
450 
451  SvNumberFormatter* pFormatter = m_rDoc.GetNumberFormatter();
452  OUString sParams( FindPara( rStr, '@', '@' ) );// Date/Time
453  if (sParams.isEmpty())
454  {
455  bool bHasTime = false;
456  switch (nWhichDefault)
457  {
458  case ww::ePRINTDATE:
459  case ww::eSAVEDATE:
460  sParams = GetWordDefaultDateStringAsUS(pFormatter, rLang);
461  sParams += " HH:MM:SS AM/PM";
462  bHasTime = true;
463  break;
464  case ww::eCREATEDATE:
465  sParams += "DD/MM/YYYY HH:MM:SS";
466  bHasTime = true;
467  break;
468  default:
469  case ww::eDATE:
470  sParams = GetWordDefaultDateStringAsUS(pFormatter, rLang);
471  break;
472  }
473 
474  if (bHijri)
475  sParams = "[~hijri]" + sParams;
476 
477  sal_Int32 nCheckPos = 0;
478  SvNumFormatType nType = SvNumFormatType::DEFINED;
479  rFormat = 0;
480 
481  OUString sTemp(sParams);
482  pFormatter->PutandConvertEntry(sTemp, nCheckPos, nType, rFormat,
483  LANGUAGE_ENGLISH_US, rLang, false);
484  sParams = sTemp;
485 
486  return bHasTime ? SvNumFormatType::DATETIME : SvNumFormatType::DATE;
487  }
488 
489  sal_uLong nFormatIdx =
490  sw::ms::MSDateTimeFormatToSwFormat(sParams, pFormatter, rLang, bHijri,
491  GetFib().m_lid);
492  SvNumFormatType nNumFormatType = SvNumFormatType::UNDEFINED;
493  if (nFormatIdx)
494  nNumFormatType = pFormatter->GetType(nFormatIdx);
495  rFormat = nFormatIdx;
496 
497  return nNumFormatType;
498 }
499 
500 // Fields
501 
502 // Update respective fields after loading (currently references)
504 {
505  m_rDoc.getIDocumentState().SetUpdateExpFieldStat(true);
506  m_rDoc.SetInitDBFields(true); // Also update fields in the database
507 }
508 
510 {
511  sal_uInt16 nRet = 0;
512  WW8PLCFx_FLD* pF = m_xPlcxMan->GetField();
513  OSL_ENSURE(pF, "WW8PLCFx_FLD - Pointer not available");
514  WW8_CP nCP = 0;
515  if (!pF || !pF->EndPosIsFieldEnd(nCP))
516  return nRet;
517 
518  const SvtFilterOptions &rOpt = SvtFilterOptions::Get();
519  bool bUseEnhFields = rOpt.IsUseEnhancedFields();
520 
521  OSL_ENSURE(!m_aFieldStack.empty(), "Empty field stack");
522  if (!m_aFieldStack.empty())
523  {
524  /*
525  only hyperlinks currently need to be handled like this, for the other
526  cases we have inserted a field not an attribute with an unknown end
527  point
528  */
529  nRet = m_aFieldStack.back().mnFieldId;
530  switch (nRet)
531  {
532  case 70:
533  if (bUseEnhFields && m_pPaM!=nullptr && m_pPaM->GetPoint()!=nullptr) {
534  SwPosition aEndPos = *m_pPaM->GetPoint();
535  SwPaM aFieldPam( m_aFieldStack.back().GetPtNode(), m_aFieldStack.back().GetPtContent(), aEndPos.nNode, aEndPos.nContent.GetIndex());
536  IDocumentMarkAccess* pMarksAccess = m_rDoc.getIDocumentMarkAccess( );
537  IFieldmark *pFieldmark = pMarksAccess->makeFieldBookmark(
538  aFieldPam, m_aFieldStack.back().GetBookmarkName(), ODF_FORMTEXT );
539  OSL_ENSURE(pFieldmark!=nullptr, "hmmm; why was the bookmark not created?");
540  if (pFieldmark!=nullptr) {
541  const IFieldmark::parameter_map_t& rParametersToAdd = m_aFieldStack.back().getParameters();
542  pFieldmark->GetParameters()->insert(rParametersToAdd.begin(), rParametersToAdd.end());
543  }
544  }
545  break;
546  // Doing corresponding status management for TOX field, index field, hyperlink field and page reference field
547  case 13://TOX
548  case 8://index
549  if (m_bLoadingTOXCache)
550  {
551  if (m_nEmbeddedTOXLevel > 0)
552  {
553  JoinNode(*m_pPaM);
554  --m_nEmbeddedTOXLevel;
555  }
556  else
557  {
558  m_aTOXEndCps.insert(nCP);
559  m_bLoadingTOXCache = false;
560  if ( m_pPaM->End() &&
561  m_pPaM->End()->nNode.GetNode().GetTextNode() &&
562  m_pPaM->End()->nNode.GetNode().GetTextNode()->Len() == 0 )
563  {
564  JoinNode(*m_pPaM);
565  }
566  else
567  {
568  m_bCareLastParaEndInToc = true;
569  }
570 
571  if (m_pPosAfterTOC)
572  {
573  *m_pPaM = *m_pPosAfterTOC;
574  m_pPosAfterTOC.reset();
575  }
576  }
577  }
578  break;
579  case 37: //REF
580  if (m_bLoadingTOXCache && !m_bLoadingTOXHyperlink)
581  {
582  m_xCtrlStck->SetAttr(*m_pPaM->GetPoint(),RES_TXTATR_INETFMT);
583  }
584  break;
585  case 88:
586  if (m_bLoadingTOXHyperlink)
587  m_bLoadingTOXHyperlink = false;
588  m_xCtrlStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_INETFMT);
589  break;
590  case 36:
591  case 68:
592  //Move outside the section associated with this type of field
593  *m_pPaM->GetPoint() = m_aFieldStack.back().maStartPos;
594  break;
595  case 7: // IF-field
596  {
597  // conditional field parameters
598  const OUString& fieldDefinition = m_aFieldStack.back().GetBookmarkCode();
599 
600  OUString paramCondition;
601  OUString paramTrue;
602  OUString paramFalse;
603 
604  SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse);
605 
606  // create new field
607  SwFieldType* pFieldType = m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::HiddenText);
608  SwHiddenTextField aHTField(
609  static_cast<SwHiddenTextFieldType*>(pFieldType),
610  paramCondition,
611  paramTrue,
612  paramFalse,
613  static_cast<sal_uInt16>(TYP_CONDTXTFLD));
614 
615  // insert new field into document
616  m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aHTField));
617  break;
618  }
619  default:
620  OUString aCode = m_aFieldStack.back().GetBookmarkCode();
621  if ( !aCode.isEmpty() )
622  {
623  // Unhandled field with stored code
624  SwPosition aEndPos = *m_pPaM->GetPoint();
625  SwPaM aFieldPam(
626  m_aFieldStack.back().GetPtNode(), m_aFieldStack.back().GetPtContent(),
627  aEndPos.nNode, aEndPos.nContent.GetIndex());
628 
629  IDocumentMarkAccess* pMarksAccess = m_rDoc.getIDocumentMarkAccess( );
630 
631  IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(
632  aFieldPam,
633  m_aFieldStack.back().GetBookmarkName(),
634  ODF_UNHANDLED );
635  if ( pFieldmark )
636  {
637  // adapt redline positions to inserted field mark start
638  // dummy char (assume not necessary for end dummy char)
639  m_xRedlineStack->MoveAttrs(*aFieldPam.Start());
640  const IFieldmark::parameter_map_t& rParametersToAdd = m_aFieldStack.back().getParameters();
641  pFieldmark->GetParameters()->insert(rParametersToAdd.begin(), rParametersToAdd.end());
642  OUString sFieldId = OUString::number( m_aFieldStack.back().mnFieldId );
643  pFieldmark->GetParameters()->insert(
644  std::pair< OUString, uno::Any > (
645  ODF_ID_PARAM,
646  uno::makeAny( sFieldId ) ) );
647  pFieldmark->GetParameters()->insert(
648  std::pair< OUString, uno::Any > (
650  uno::makeAny( aCode ) ) );
651 
652  if ( m_aFieldStack.back().mnObjLocFc > 0 )
653  {
654  // Store the OLE object as an internal link
655  OUString sOleId('_');
656  sOleId += OUString::number( m_aFieldStack.back().mnObjLocFc );
657 
659  tools::SvRef<SotStorage> xSrc1 = xSrc0->OpenSotStorage( sOleId, StreamMode::READ );
660 
661  // Store it now!
662  uno::Reference< embed::XStorage > xDocStg = GetDoc().GetDocStorage();
663  if (xDocStg.is())
664  {
665  uno::Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement(
666  "OLELinks", embed::ElementModes::WRITE );
667  tools::SvRef<SotStorage> xObjDst = SotStorage::OpenOLEStorage( xOleStg, sOleId );
668 
669  if ( xObjDst.is() )
670  {
671  xSrc1->CopyTo( xObjDst.get() );
672 
673  if ( !xObjDst->GetError() )
674  xObjDst->Commit();
675  }
676 
677  uno::Reference< embed::XTransactedObject > xTransact( xOleStg, uno::UNO_QUERY );
678  if ( xTransact.is() )
679  xTransact->commit();
680  }
681 
682  // Store the OLE Id as a parameter
683  pFieldmark->GetParameters()->insert(
684  std::pair< OUString, uno::Any >(
685  ODF_OLE_PARAM, uno::makeAny( sOleId ) ) );
686  }
687  }
688  }
689 
690  break;
691  }
692  m_aFieldStack.pop_back();
693  }
694  return nRet;
695 }
696 
697 static bool AcceptableNestedField(sal_uInt16 nFieldCode)
698 {
699  switch (nFieldCode)
700  {
701  case 8: // allow recursive field in TOC...
702  case 13: // allow recursive field in TOC...
703  case 36:
704  case 68:
705  case 79:
706  case 88:
707  // Accept AutoTextList field as nested field.
708  // Thus, the field result is imported as plain text.
709  case 89:
710  return true;
711  default:
712  return false;
713  }
714 }
715 
716 WW8FieldEntry::WW8FieldEntry(SwPosition const &rPos, sal_uInt16 nFieldId) throw()
717  : maStartPos(rPos), mnFieldId(nFieldId), mnObjLocFc(0)
718 {
719 }
720 
722  : maStartPos(rOther.maStartPos), mnFieldId(rOther.mnFieldId), mnObjLocFc(rOther.mnObjLocFc)
723 {
724 }
725 
726 void WW8FieldEntry::Swap(WW8FieldEntry &rOther) throw()
727 {
728  std::swap(maStartPos, rOther.maStartPos);
729  std::swap(mnFieldId, rOther.mnFieldId);
730 }
731 
733 {
734  WW8FieldEntry aTemp(rOther);
735  Swap(aTemp);
736  return *this;
737 }
738 
739 
740 void WW8FieldEntry::SetBookmarkName(const OUString& bookmarkName)
741 {
742  msBookmarkName=bookmarkName;
743 }
744 
745 void WW8FieldEntry::SetBookmarkType(const OUString& bookmarkType)
746 {
747  msMarkType=bookmarkType;
748 }
749 
750 void WW8FieldEntry::SetBookmarkCode(const OUString& bookmarkCode)
751 {
752  msMarkCode = bookmarkCode;
753 }
754 
755 
756 // Read_Field reads a field or returns 0 if the field cannot be read,
757 // so that the calling function reads the field in text format.
758 // Returnvalue: Total length of field
760 {
761  typedef eF_ResT (SwWW8ImplReader:: *FNReadField)( WW8FieldDesc*, OUString& );
762  enum Limits {eMax = 96};
763  static const FNReadField aWW8FieldTab[eMax+1] =
764  {
765  nullptr,
767  nullptr,
769  nullptr,
770  nullptr,
772  nullptr,
774  nullptr,
776  nullptr,
799  nullptr,
800  nullptr,
805  nullptr,
807  nullptr,
808  nullptr,
810  nullptr,
811  nullptr,
812  nullptr,
813  nullptr,
815  nullptr,
820  nullptr,
821 
822  nullptr, // 56
823 
827  nullptr,
828  nullptr,
829  nullptr,
830  nullptr,
831  &SwWW8ImplReader::Read_F_DocInfo, // 64 - DOCVARIABLE
832  nullptr,
833  nullptr,
836  nullptr,
840  nullptr, /*&SwWW8ImplReader::Read_F_Tox*/
841  nullptr,
842  nullptr,
843  nullptr,
844  nullptr,
845  nullptr,
846  nullptr,
847  nullptr,
848  nullptr,
849  nullptr,
851  nullptr, // 84
853  nullptr, // 86
856  nullptr, // 89
857  nullptr, // 90
859  nullptr, // 92
860  nullptr, // 93
861  nullptr, // 94
863  nullptr // eMax - Dummy empty method
864  };
865  OSL_ENSURE( SAL_N_ELEMENTS( aWW8FieldTab ) == eMax+1, "FieldFunc table not right" );
866 
867  WW8PLCFx_FLD* pF = m_xPlcxMan->GetField();
868  OSL_ENSURE(pF, "WW8PLCFx_FLD - Pointer not available");
869 
870  if (!pF || !pF->StartPosIsFieldStart())
871  return 0;
872 
873  bool bNested = false;
874  if (!m_aFieldStack.empty())
875  {
876  bNested = std::any_of(m_aFieldStack.cbegin(), m_aFieldStack.cend(),
877  [](const WW8FieldEntry& aField) { return !AcceptableNestedField(aField.mnFieldId); });
878  }
879 
880  WW8FieldDesc aF;
881  bool bOk = pF->GetPara(pRes->nCp2OrIdx, aF);
882 
883  OSL_ENSURE(bOk, "WW8: Bad Field!");
884  if (aF.nId == 33) aF.bCodeNest=false; // do not recurse into nested page fields
885  bool bCodeNest = aF.bCodeNest;
886  if ( aF.nId == 6 ) bCodeNest = false; // We can handle them and lose the inner data
887 
888  m_aFieldStack.emplace_back(*m_pPaM->GetPoint(), aF.nId);
889 
890  if (bNested)
891  return 0;
892 
893  sal_uInt16 n = (aF.nId <= eMax) ? aF.nId : static_cast<sal_uInt16>(eMax);
894  sal_uInt16 nI = n / 32; // # of sal_uInt32
895  sal_uInt32 nMask = 1 << ( n % 32 ); // Mask for bits
896 
897  if (SAL_N_ELEMENTS(m_nFieldTagAlways) <= nI)
898  { // if indexes larger than 95 are needed, then a new configuration
899  // item has to be added, and nFieldTagAlways/nFieldTagBad expanded!
900  return aF.nLen;
901  }
902 
903  if( m_nFieldTagAlways[nI] & nMask ) // Flag: Tag it
904  return Read_F_Tag( &aF ); // Result not as text
905 
906  if( !bOk || !aF.nId ) // Field corrupted
907  return aF.nLen; // -> ignore
908 
909  if( aF.nId > eMax - 1) // WW: Nested Field
910  {
911  if( m_nFieldTagBad[nI] & nMask ) // Flag: Tag it when bad
912  return Read_F_Tag( &aF ); // Result not as text
913  else
914  return aF.nLen;
915  }
916 
917  //Only one type of field (hyperlink) in drawing textboxes exists
918  if (aF.nId != 88 && m_xPlcxMan->GetDoingDrawTextBox())
919  return aF.nLen;
920 
921  bool bHasHandler = aWW8FieldTab[aF.nId] != nullptr;
922  if (aF.nId == 10) // STYLEREF
923  {
924  // STYLEREF, by default these are not handled.
925  bHasHandler = false;
926  sal_uInt64 nOldPos = m_pStrm->Tell();
927  OUString aStr;
928  aF.nLCode = m_xSBase->WW8ReadString(*m_pStrm, aStr, m_xPlcxMan->GetCpOfs() + aF.nSCode, aF.nLCode, m_eTextCharSet);
929  m_pStrm->Seek(nOldPos);
930 
931  WW8ReadFieldParams aReadParam(aStr);
932  sal_Int32 nRet = aReadParam.SkipToNextToken();
933  if (nRet == -2 && !aReadParam.GetResult().isEmpty())
934  // Single numeric argument: this can be handled by SwChapterField.
935  bHasHandler = rtl::isAsciiDigit(aReadParam.GetResult()[0]);
936 
937  if (bHasHandler)
938  {
939  nRet = aReadParam.SkipToNextToken();
940  // Handle using SwChapterField only in case there is no \[a-z]
941  // switch after the field argument.
942  bHasHandler = nRet < 0 || nRet == '*';
943  }
944  }
945 
946  // no routine available
947  if (!bHasHandler || bCodeNest)
948  {
949  if( m_nFieldTagBad[nI] & nMask ) // Flag: Tag it when bad
950  return Read_F_Tag( &aF ); // Result not as text
951  // only read result
952  if (aF.bResNest && !AcceptableNestedField(aF.nId))
953  return aF.nLen; // Result nested -> unusable
954 
955  long nOldPos = m_pStrm->Tell();
956  OUString aStr;
957  aF.nLCode = m_xSBase->WW8ReadString( *m_pStrm, aStr, m_xPlcxMan->GetCpOfs()+
958  aF.nSCode, aF.nLCode, m_eTextCharSet );
959  m_pStrm->Seek( nOldPos );
960 
961  // field codes which contain '/' or '.' are not displayed in WinWord
962  // skip if it is formula field or found space before. see #i119446, #i119585.
963  const sal_Int32 nDotPos = aStr.indexOf('.');
964  const sal_Int32 nSlashPos = aStr.indexOf('/');
965  sal_Int32 nSpacePos = aStr.indexOf( ' ', 1 );
966  if ( nSpacePos<0 )
967  nSpacePos = aStr.getLength();
968 
969  if ( !( aStr.getLength()>1 && aStr[1]=='=') &&
970  (( nDotPos>=0 && nDotPos < nSpacePos ) ||
971  ( nSlashPos>=0 && nSlashPos < nSpacePos )))
972  return aF.nLen;
973  else
974  {
975  // Link fields aren't supported, but they are bound to an OLE object
976  // that needs to be roundtripped
977  if ( aF.nId == 56 )
978  m_bEmbeddObj = true;
979  // Field not supported: store the field code for later use
980  m_aFieldStack.back().SetBookmarkCode( aStr );
981  return aF.nLen - aF.nLRes - 1; // skipped too many, the resulted field will be read like main text
982  }
983  }
984  else
985  { // read field
986  auto nOldPos = m_pStrm->Tell();
987  OUString aStr;
988  if ( aF.nId == 6 && aF.bCodeNest )
989  {
990  // TODO Extract the whole code string using the nested codes
991  aF.nLCode = m_xSBase->WW8ReadString( *m_pStrm, aStr, m_xPlcxMan->GetCpOfs() +
992  aF.nSCode, aF.nSRes - aF.nSCode - 1, m_eTextCharSet );
993  }
994  else
995  {
996  aF.nLCode = m_xSBase->WW8ReadString( *m_pStrm, aStr, m_xPlcxMan->GetCpOfs()+
997  aF.nSCode, aF.nLCode, m_eTextCharSet );
998  }
999 
1000  // #i51312# - graphics inside field code not supported by Writer.
1001  // Thus, delete character 0x01, which stands for such a graphic.
1002  if (aF.nId==51) //#i56768# only do it for the MACROBUTTON field, since DropListFields need the 0x01.
1003  {
1004  aStr = aStr.replaceAll("\x01", "");
1005  }
1006 
1007  eF_ResT eRes = (this->*aWW8FieldTab[aF.nId])( &aF, aStr );
1008  m_pStrm->Seek(nOldPos);
1009 
1010  switch ( eRes )
1011  {
1012  case eF_ResT::OK:
1013  return aF.nLen;
1014  case eF_ResT::TEXT:
1015  // skipped too many, the resulted field will be read like main text
1016  // attributes can start at char 0x14 so skip one
1017  // char more back == "-2"
1018  if (aF.nLRes)
1019  return aF.nLen - aF.nLRes - 2;
1020  else
1021  return aF.nLen;
1022  case eF_ResT::TAGIGN:
1023  if ( m_nFieldTagBad[nI] & nMask ) // Flag: Tag bad
1024  return Read_F_Tag( &aF ); // Tag it
1025  return aF.nLen; // or ignore
1026  case eF_ResT::READ_FSPA:
1027  return aF.nLen - aF.nLRes - 2; // position on char 1
1028  default:
1029  return aF.nLen; // ignore
1030  }
1031  }
1032 }
1033 
1034 // Tag fields
1035 
1036 // MakeTagString() returns the position of the first CR / end of line / page break
1037 // in pText and converts only up to this point.
1038 // If none of these special characters is found, the function returns 0.
1039 void SwWW8ImplReader::MakeTagString( OUString& rStr, const OUString& rOrg )
1040 {
1041  bool bAllowCr = SwFltGetFlag( m_nFieldFlags, SwFltControlStack::TAGS_IN_TEXT )
1042  || SwFltGetFlag( m_nFieldFlags, SwFltControlStack::ALLOW_FLD_CR );
1043  sal_Unicode cChar;
1044  rStr = rOrg;
1045 
1046  for( sal_Int32 nI = 0;
1047  nI < rStr.getLength() && rStr.getLength() < (MAX_FIELDLEN - 4); ++nI )
1048  {
1049  bool bSetAsHex = false;
1050  cChar = rStr[ nI ];
1051  switch( cChar )
1052  {
1053  case 132: // Exchange typographical quotation marks for normal ones
1054  case 148:
1055  case 147:
1056  rStr = rStr.replaceAt( nI, 1, "\"" );
1057  break;
1058  case 19:
1059  rStr = rStr.replaceAt( nI, 1, "{" );
1060  break; // 19..21 to {|}
1061  case 20:
1062  rStr = rStr.replaceAt( nI, 1, "|" );
1063  break;
1064  case 21:
1065  rStr = rStr.replaceAt( nI, 1, "}" );
1066  break;
1067  case '\\': // Tag \{|} with \ ...
1068  case '{':
1069  case '|':
1070  case '}':
1071  rStr = rStr.replaceAt( nI, 0, "\\" );
1072  ++nI;
1073  break;
1074  case 0x0b:
1075  case 0x0c:
1076  case 0x0d:
1077  if( bAllowCr )
1078  rStr = rStr.replaceAt( nI, 1, "\n" );
1079  else
1080  bSetAsHex = true;
1081  break;
1082  case 0xFE:
1083  case 0xFF:
1084  bSetAsHex = true;
1085  break;
1086  default:
1087  bSetAsHex = 0x20 > cChar;
1088  break;
1089  }
1090 
1091  if( bSetAsHex )
1092  {
1093  //all Hex-Numbers with \x before
1094  OUString sTmp( "\\x" );
1095  if( cChar < 0x10 )
1096  sTmp += "0";
1097  sTmp += OUString::number( cChar, 16 );
1098  rStr = rStr.replaceAt( nI, 1 , sTmp );
1099  nI += sTmp.getLength() - 1;
1100  }
1101  }
1102 
1103  if( rStr.getLength() > (MAX_FIELDLEN - 4))
1104  rStr = rStr.copy( 0, MAX_FIELDLEN - 4 );
1105 }
1106 
1107 void SwWW8ImplReader::InsertTagField( const sal_uInt16 nId, const OUString& rTagText )
1108 {
1109  OUString aName("WwFieldTag");
1110  if( SwFltGetFlag( m_nFieldFlags, SwFltControlStack::TAGS_DO_ID ) ) // Number?
1111  aName += OUString::number( nId ); // return it?
1112 
1113  if( SwFltGetFlag(m_nFieldFlags, SwFltControlStack::TAGS_IN_TEXT))
1114  {
1115  aName += rTagText; // tag as text
1116  m_rDoc.getIDocumentContentOperations().InsertString(*m_pPaM, aName,
1118  }
1119  else
1120  { // tag normally
1121 
1122  SwFieldType* pFT = m_rDoc.getIDocumentFieldsAccess().InsertFieldType(
1123  SwSetExpFieldType( &m_rDoc, aName, nsSwGetSetExpType::GSE_STRING ) );
1124  SwSetExpField aField( static_cast<SwSetExpFieldType*>(pFT), rTagText ); // SUB_INVISIBLE
1125  sal_uInt16 nSubType = ( SwFltGetFlag( m_nFieldFlags, SwFltControlStack::TAGS_VISIBLE ) ) ? 0 : nsSwExtendedSubType::SUB_INVISIBLE;
1126  aField.SetSubType(nSubType | nsSwGetSetExpType::GSE_STRING);
1127 
1128  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1129  }
1130 }
1131 
1133 {
1134  long nOldPos = m_pStrm->Tell();
1135 
1136  WW8_CP nStart = pF->nSCode - 1; // starting with 0x19
1137  WW8_CP nL = pF->nLen; // Total length with result and nest
1138  if( nL > MAX_FIELDLEN )
1139  nL = MAX_FIELDLEN; // MaxLength, by quoting
1140  // max. 4 times as big
1141  OUString sFText;
1142  m_xSBase->WW8ReadString( *m_pStrm, sFText,
1143  m_xPlcxMan->GetCpOfs() + nStart, nL, m_eStructCharSet);
1144 
1145  OUString aTagText;
1146  MakeTagString( aTagText, sFText );
1147  InsertTagField( pF->nId, aTagText );
1148 
1149  m_pStrm->Seek( nOldPos );
1150  return pF->nLen;
1151 }
1152 
1153 // normal fields
1154 
1156 {
1157  OUString aDef;
1158  OUString aQ;
1159  WW8ReadFieldParams aReadParam( rStr );
1160  for (;;)
1161  {
1162  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1163  if ( nRet==-1 )
1164  break;
1165  switch( nRet )
1166  {
1167  case -2:
1168  if( aQ.isEmpty() )
1169  aQ = aReadParam.GetResult();
1170  break;
1171  case 'd':
1172  case 'D':
1173  if ( aReadParam.GoToTokenParam() )
1174  aDef = aReadParam.GetResult();
1175  break;
1176  }
1177  }
1178  if( aDef.isEmpty() )
1179  aDef = GetFieldResult( pF );
1180 
1181  if ( pF->nId != 0x01 ) // 0x01 fields have no result
1182  {
1183  SwInputField aField( static_cast<SwInputFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Input )),
1184  aDef, aQ, INP_TXT, 0, false );
1185  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1186  }
1187 
1188  return eF_ResT::OK;
1189 }
1190 
1191 // GetFieldResult allocates a string and reads the resulted field
1193 {
1194  long nOldPos = m_pStrm->Tell();
1195 
1196  WW8_CP nStart = pF->nSRes; // result start
1197  WW8_CP nL = pF->nLRes; // result length
1198  if( !nL )
1199  return OUString(); // no result
1200 
1201  if( nL > MAX_FIELDLEN )
1202  nL = MAX_FIELDLEN; // MaxLength, by quoting
1203  // max. 4 times as big
1204 
1205  OUString sRes;
1206  m_xSBase->WW8ReadString( *m_pStrm, sRes, m_xPlcxMan->GetCpOfs() + nStart,
1207  nL, m_eStructCharSet );
1208 
1209  m_pStrm->Seek( nOldPos );
1210 
1211  //replace both CR 0x0D and VT 0x0B with LF 0x0A
1212  return sRes.replace(0x0D, 0x0A).replace(0x0B, 0x0A);
1213 }
1214 
1215 /*
1216 Bookmarks can be set with fields SET and ASK, and they can be referenced with
1217 REF. When set, they behave like variables in writer, otherwise they behave
1218 like normal bookmarks. We can check whether we should use a show variable
1219 instead of a normal bookmark ref by converting to "show variable" at the end
1220 of the document those refs which look for the content of a bookmark but whose
1221 bookmarks were set with SET or ASK. (See SwWW8FltRefStack)
1222 
1223 The other piece of the puzzle is that refs that point to the "location" of the
1224 bookmark will in word actually point to the last location where the bookmark
1225 was set with SET or ASK, not the actual bookmark. This is only noticeable when
1226 a document sets the bookmark more than once. This is because word places the
1227 true bookmark at the location of the last set, but the refs will display the
1228 position of the first set before the ref.
1229 
1230 So what we will do is
1231 
1232 1) keep a list of all bookmarks that were set, any bookmark names mentioned
1233 here that are referred by content will be converted to show variables.
1234 
1235 2) create pseudo bookmarks for every position that a bookmark is set with SET
1236 or ASK but has no existing bookmark. We can then keep a map from the original
1237 bookmark name to the new one. As we parse the document new pseudo names will
1238 replace the older ones, so the map always contains the bookmark of the
1239 location that msword itself would use.
1240 
1241 3) word's bookmarks are case insensitive, writers are not. So we need to
1242 map case different versions together, regardless of whether they are
1243 variables or not.
1244 
1245 4) when a reference is (first) SET or ASK, the bookmark associated with it
1246 is placed around the 0x14 0x15 result part of the field. We will fiddle
1247 the placement to be the writer equivalent of directly before and after
1248 the field, which gives the same effect and meaning, to do so we must
1249 get any bookmarks in the field range, and begin them immediately before
1250 the set/ask field, and end them directly afterwards. MapBookmarkVariables
1251 returns an identifier of the bookmark attribute to close after inserting
1252 the appropriate set/ask field.
1253 */
1255  OUString &rOrigName, const OUString &rData)
1256 {
1257  OSL_ENSURE(m_xPlcxMan.get(), "No pPlcxMan");
1258  long nNo;
1259  /*
1260  If there was no bookmark associated with this set field, then we create a
1261  pseudo one and insert it in the document.
1262  */
1263  sal_uInt16 nIndex;
1264  m_xPlcxMan->GetBook()->MapName(rOrigName);
1265  OUString sName = m_xPlcxMan->GetBook()->GetBookmark(
1266  pF->nSCode, pF->nSCode + pF->nLen, nIndex);
1267  if (!sName.isEmpty())
1268  {
1269  m_xPlcxMan->GetBook()->SetStatus(nIndex, BOOK_IGNORE);
1270  nNo = nIndex;
1271  }
1272  else
1273  {
1274  nNo = m_xReffingStck->aFieldVarNames.size()+1;
1275  sName = "WWSetBkmk" + OUString::number(nNo);
1276  nNo += m_xPlcxMan->GetBook()->GetIMax();
1277  }
1278  m_xReffedStck->NewAttr(*m_pPaM->GetPoint(),
1279  SwFltBookmark( BookmarkToWriter(sName), rData, nNo ));
1280  m_xReffingStck->aFieldVarNames[rOrigName] = sName;
1281  return nNo;
1282 }
1283 
1284 /*
1285 Word can set a bookmark with set or with ask, such a bookmark is equivalent to
1286 our variables, but until the end of a document we cannot be sure if a bookmark
1287 is a variable or not, at the end we will have a list of reference names which
1288 were set or asked, all bookmarks using the content of those bookmarks are
1289 converted to show variables, those that reference the position of the field
1290 can be left as references, because a bookmark is also inserted at the position
1291 of a set or ask field, either by word, or in some special cases by the import
1292 filter itself.
1293 */
1295  SwFltStackEntry &rEntry)
1296 {
1297  SwFltStackEntry *pRet=nullptr;
1298  if (pField && SwFieldIds::GetRef == pField->Which())
1299  {
1300  //Get the name of the ref field, and see if actually a variable
1301  const OUString sName = pField->GetPar1();
1302  std::map<OUString, OUString, SwWW8::ltstr>::const_iterator
1303  aResult = aFieldVarNames.find(sName);
1304 
1305  if (aResult != aFieldVarNames.end())
1306  {
1307  SwGetExpField aField( static_cast<SwGetExpFieldType*>(
1308  pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetExp)), sName, nsSwGetSetExpType::GSE_STRING, 0);
1309  SwFormatField aTmp(aField);
1310  rEntry.pAttr.reset( aTmp.Clone() );
1311  pRet = &rEntry;
1312  }
1313  }
1314  return pRet;
1315 }
1316 
1317 OUString SwWW8ImplReader::GetMappedBookmark(const OUString &rOrigName)
1318 {
1319  OUString sName(BookmarkToWriter(rOrigName));
1320  OSL_ENSURE(m_xPlcxMan.get(), "no pPlcxMan");
1321  m_xPlcxMan->GetBook()->MapName(sName);
1322 
1323  //See if there has been a variable set with this name, if so get
1324  //the pseudo bookmark name that was set with it.
1325  std::map<OUString, OUString, SwWW8::ltstr>::const_iterator aResult =
1326  m_xReffingStck->aFieldVarNames.find(sName);
1327 
1328  return (aResult == m_xReffingStck->aFieldVarNames.end())
1329  ? sName : (*aResult).second;
1330 }
1331 
1332 // "ASK"
1334 {
1335  OUString sOrigName, aQ;
1336  OUString aDef;
1337  WW8ReadFieldParams aReadParam( rStr );
1338  for (;;)
1339  {
1340  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1341  if ( nRet==-1 )
1342  break;
1343  switch( nRet )
1344  {
1345  case -2:
1346  if (sOrigName.isEmpty())
1347  sOrigName = aReadParam.GetResult();
1348  else if (aQ.isEmpty())
1349  aQ = aReadParam.GetResult();
1350  break;
1351  case 'd':
1352  case 'D':
1353  if ( aReadParam.GoToTokenParam() )
1354  aDef = aReadParam.GetResult();
1355  break;
1356  }
1357  }
1358 
1359  if (sOrigName.isEmpty())
1360  return eF_ResT::TAGIGN; // does not make sense without textmark
1361 
1362  const OUString aResult(GetFieldResult(pF));
1363 
1364  //#i24377#, munge Default Text into title as we have only one slot
1365  //available for aResult and aDef otherwise
1366  if (!aDef.isEmpty())
1367  {
1368  if (!aQ.isEmpty())
1369  aQ += " - ";
1370  aQ += aDef;
1371  }
1372 
1373  const long nNo = MapBookmarkVariables(pF, sOrigName, aResult);
1374 
1375  SwSetExpFieldType* pFT = static_cast<SwSetExpFieldType*>(m_rDoc.getIDocumentFieldsAccess().InsertFieldType(
1376  SwSetExpFieldType(&m_rDoc, sOrigName, nsSwGetSetExpType::GSE_STRING)));
1377  SwSetExpField aField(pFT, aResult);
1379  aField.SetInputFlag(true);
1380  aField.SetPromptText( aQ );
1381 
1382  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1383 
1384  m_xReffedStck->SetAttr(*m_pPaM->GetPoint(), RES_FLTR_BOOKMARK, true, nNo);
1385  return eF_ResT::OK;
1386 }
1387 
1388 // "AUTONR"
1390 {
1391  if( !m_pNumFieldType ){ // 1st time
1392  SwSetExpFieldType aT( &m_rDoc, "AutoNr", nsSwGetSetExpType::GSE_SEQ );
1393  m_pNumFieldType = m_rDoc.getIDocumentFieldsAccess().InsertFieldType( aT );
1394  }
1395  SwSetExpField aField( static_cast<SwSetExpFieldType*>(m_pNumFieldType), OUString(),
1396  GetNumberPara( rStr ) );
1397  aField.SetValue( ++m_nFieldNum, nullptr );
1398  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1399  return eF_ResT::OK;
1400 }
1401 
1402 // "SEQ"
1404 {
1405  OUString aSequenceName;
1406  OUString aBook;
1407  bool bHidden = false;
1408  bool bFormat = false;
1409  bool bCountOn = true;
1410  OUString sStart;
1411  SvxNumType eNumFormat = SVX_NUM_ARABIC;
1412  WW8ReadFieldParams aReadParam( rStr );
1413  for (;;)
1414  {
1415  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1416  if ( nRet==-1 )
1417  break;
1418  switch( nRet )
1419  {
1420  case -2:
1421  if( aSequenceName.isEmpty() )
1422  aSequenceName = aReadParam.GetResult();
1423  else if( aBook.isEmpty() )
1424  aBook = aReadParam.GetResult();
1425  break;
1426 
1427  case 'h':
1428  if( !bFormat )
1429  bHidden = true; // activate hidden flag
1430  break;
1431 
1432  case '*':
1433  bFormat = true; // activate format flag
1434  if ( aReadParam.SkipToNextToken()!=-2 )
1435  break;
1436  if ( aReadParam.GetResult()!="MERGEFORMAT" && aReadParam.GetResult()!="CHARFORMAT" )
1437  eNumFormat = GetNumTypeFromName( aReadParam.GetResult() );
1438  break;
1439 
1440  case 'r':
1441  bCountOn = false;
1442  if ( aReadParam.SkipToNextToken()==-2 )
1443  sStart = aReadParam.GetResult();
1444  break;
1445 
1446  case 'c':
1447  bCountOn = false;
1448  break;
1449 
1450  case 'n':
1451  bCountOn = true; // Increase value by one (default)
1452  break;
1453 
1454  case 's': // Outline Level
1455  //#i19682, what am I to do with this value
1456  break;
1457  }
1458  }
1459  if (aSequenceName.isEmpty() && aBook.isEmpty())
1460  return eF_ResT::TAGIGN;
1461 
1462  SwSetExpFieldType* pFT = static_cast<SwSetExpFieldType*>(m_rDoc.getIDocumentFieldsAccess().InsertFieldType(
1463  SwSetExpFieldType( &m_rDoc, aSequenceName, nsSwGetSetExpType::GSE_SEQ ) ) );
1464  SwSetExpField aField( pFT, OUString(), eNumFormat );
1465 
1466  //#i120654# Add bHidden for /h flag (/h: Hide the field result.)
1467  if (bHidden)
1469 
1470  if (!sStart.isEmpty())
1471  aField.SetFormula( aSequenceName + "=" + sStart );
1472  else if (!bCountOn)
1473  aField.SetFormula(aSequenceName);
1474 
1475  m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
1476  return eF_ResT::OK;
1477 }
1478 
1480 {
1481  WW8ReadFieldParams aReadParam(rString);
1482  sal_Int32 nRet = aReadParam.SkipToNextToken();
1483  if (nRet != -2)
1484  // \param was found, not normal text.
1485  return eF_ResT::TAGIGN;
1486 
1487  OUString aResult = aReadParam.GetResult();
1488  sal_Int32 nResult = aResult.toInt32();
1489  if (nResult < 1)
1490  return eF_ResT::TAGIGN;
1491 
1492  SwFieldType* pFieldType = m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Chapter);
1493  SwChapterField aField(static_cast<SwChapterFieldType*>(pFieldType), CF_TITLE);
1494  aField.SetLevel(nResult - 1);
1495  m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
1496 
1497  return eF_ResT::OK;
1498 }
1499 
1501 {
1502  sal_uInt16 nSub=0;
1503  // RegInfoFormat, DefaultFormat for DocInfoFields
1504  sal_uInt16 nReg = DI_SUB_AUTHOR;
1505  bool bDateTime = false;
1506 
1507  if( 85 == pF->nId )
1508  {
1509  OUString aDocProperty;
1510  WW8ReadFieldParams aReadParam( rStr );
1511  for (;;)
1512  {
1513  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1514  if ( nRet==-1 )
1515  break;
1516  switch( nRet )
1517  {
1518  case -2:
1519  if( aDocProperty.isEmpty() )
1520  aDocProperty = aReadParam.GetResult();
1521  break;
1522  case '*':
1523  //Skip over MERGEFORMAT
1524  (void)aReadParam.SkipToNextToken();
1525  break;
1526  }
1527  }
1528 
1529  aDocProperty = aDocProperty.replaceAll("\"", "");
1530 
1531  /*
1532  There are up to 26 fields that may be meant by 'DocumentProperty'.
1533  Which of them is to be inserted here ?
1534  This Problem can only be solved by implementing a name matching
1535  method that compares the given Parameter String with the four
1536  possible name sets (english, german, french, spanish)
1537  */
1538 
1539  static const sal_Char* aName10 = "\x0F"; // SW field code
1540  static const sal_Char* aName11 // German
1541  = "TITEL";
1542  static const sal_Char* aName12 // French
1543  = "TITRE";
1544  static const sal_Char* aName13 // English
1545  = "TITLE";
1546  static const sal_Char* aName14 // Spanish
1547  = "TITRO";
1548  static const sal_Char* aName20 = "\x15"; // SW field code
1549  static const sal_Char* aName21 // German
1550  = "ERSTELLDATUM";
1551  static const sal_Char* aName22 // French
1552  = "CR\xC9\xC9";
1553  static const sal_Char* aName23 // English
1554  = "CREATED";
1555  static const sal_Char* aName24 // Spanish
1556  = "CREADO";
1557  static const sal_Char* aName30 = "\x16"; // SW field code
1558  static const sal_Char* aName31 // German
1559  = "ZULETZTGESPEICHERTZEIT";
1560  static const sal_Char* aName32 // French
1561  = "DERNIERENREGISTREMENT";
1562  static const sal_Char* aName33 // English
1563  = "SAVED";
1564  static const sal_Char* aName34 // Spanish
1565  = "MODIFICADO";
1566  static const sal_Char* aName40 = "\x17"; // SW field code
1567  static const sal_Char* aName41 // German
1568  = "ZULETZTGEDRUCKT";
1569  static const sal_Char* aName42 // French
1570  = "DERNI\xC8" "REIMPRESSION";
1571  static const sal_Char* aName43 // English
1572  = "LASTPRINTED";
1573  static const sal_Char* aName44 // Spanish
1574  = "HUPS PUPS";
1575  static const sal_Char* aName50 = "\x18"; // SW field code
1576  static const sal_Char* aName51 // German
1577  = "\xDC" "BERARBEITUNGSNUMMER";
1578  static const sal_Char* aName52 // French
1579  = "NUM\xC9" "RODEREVISION";
1580  static const sal_Char* aName53 // English
1581  = "REVISIONNUMBER";
1582  static const sal_Char* aName54 // Spanish
1583  = "SNUBBEL BUBBEL";
1584  static const sal_uInt16 nFieldCnt = 5;
1585 
1586  // additional fields are to be coded soon!
1587 
1588  static const sal_uInt16 nLangCnt = 4;
1589  static const sal_Char *aNameSet_26[nFieldCnt][nLangCnt+1] =
1590  {
1591  {aName10, aName11, aName12, aName13, aName14},
1592  {aName20, aName21, aName22, aName23, aName24},
1593  {aName30, aName31, aName32, aName33, aName34},
1594  {aName40, aName41, aName42, aName43, aName44},
1595  {aName50, aName51, aName52, aName53, aName54}
1596  };
1597 
1598  bool bFieldFound= false;
1599  sal_uInt16 nFIdx;
1600  for(sal_uInt16 nLIdx=1; !bFieldFound && (nLangCnt > nLIdx); ++nLIdx)
1601  {
1602  for(nFIdx = 0; !bFieldFound && (nFieldCnt > nFIdx); ++nFIdx)
1603  {
1604  if( aDocProperty == OUString( aNameSet_26[nFIdx][nLIdx], strlen(aNameSet_26[nFIdx][nLIdx]),
1605  RTL_TEXTENCODING_MS_1252 ) )
1606  {
1607  bFieldFound = true;
1608  pF->nId = aNameSet_26[nFIdx][0][0];
1609  }
1610  }
1611  }
1612 
1613  if( !bFieldFound )
1614  {
1615  SwDocInfoField aField( static_cast<SwDocInfoFieldType*>(
1616  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocInfo )), DI_CUSTOM|nReg, aDocProperty, GetFieldResult( pF ) );
1617  m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
1618 
1619  return eF_ResT::OK;
1620  }
1621  }
1622 
1623  switch( pF->nId )
1624  {
1625  case 14:
1626  /* supports all INFO variables! */
1627  nSub = DI_KEYS;
1628  break;
1629  case 15:
1630  nSub = DI_TITLE;
1631  break;
1632  case 16:
1633  nSub = DI_THEMA;
1634  break;
1635  case 18:
1636  nSub = DI_KEYS;
1637  break;
1638  case 19:
1639  nSub = DI_COMMENT;
1640  break;
1641  case 20:
1642  nSub = DI_CHANGE;
1643  nReg = DI_SUB_AUTHOR;
1644  break;
1645  case 21:
1646  nSub = DI_CREATE;
1647  nReg = DI_SUB_DATE;
1648  bDateTime = true;
1649  break;
1650  case 23:
1651  nSub = DI_PRINT;
1652  nReg = DI_SUB_DATE;
1653  bDateTime = true;
1654  break;
1655  case 24:
1656  nSub = DI_DOCNO;
1657  break;
1658  case 22:
1659  nSub = DI_CHANGE;
1660  nReg = DI_SUB_DATE;
1661  bDateTime = true;
1662  break;
1663  case 25:
1664  nSub = DI_CHANGE;
1665  nReg = DI_SUB_TIME;
1666  bDateTime = true;
1667  break;
1668  case 64: // DOCVARIABLE
1669  nSub = DI_CUSTOM;
1670  break;
1671  }
1672 
1673  sal_uInt32 nFormat = 0;
1674 
1676  if (bDateTime)
1677  {
1678  SvNumFormatType nDT = GetTimeDatePara(rStr, nFormat, nLang, pF->nId);
1679  switch (nDT)
1680  {
1681  case SvNumFormatType::DATE:
1682  nReg = DI_SUB_DATE;
1683  break;
1684  case SvNumFormatType::TIME:
1685  nReg = DI_SUB_TIME;
1686  break;
1687  case SvNumFormatType::DATETIME:
1688  nReg = DI_SUB_DATE;
1689  break;
1690  default:
1691  nReg = DI_SUB_DATE;
1692  break;
1693  }
1694  }
1695 
1696  OUString aData;
1697  // Extract DOCVARIABLE varname
1698  if ( 64 == pF->nId )
1699  {
1700  WW8ReadFieldParams aReadParam( rStr );
1701  for (;;)
1702  {
1703  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1704  if ( nRet==-1)
1705  break;
1706  switch( nRet )
1707  {
1708  case -2:
1709  if( aData.isEmpty() )
1710  aData = aReadParam.GetResult();
1711  break;
1712  case '*':
1713  //Skip over MERGEFORMAT
1714  (void)aReadParam.SkipToNextToken();
1715  break;
1716  }
1717  }
1718 
1719  aData = aData.replaceAll("\"", "");
1720  }
1721 
1722  SwDocInfoField aField( static_cast<SwDocInfoFieldType*>(
1723  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocInfo )), nSub|nReg, aData, nFormat );
1724  if (bDateTime)
1725  ForceFieldLanguage(aField, nLang);
1726  m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
1727 
1728  return eF_ResT::OK;
1729 }
1730 
1732 {
1733  // SH: The SwAuthorField refers not to the original author but to the current user, better use DocInfo
1734  SwDocInfoField aField( static_cast<SwDocInfoFieldType*>(
1735  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocInfo )),
1736  DI_CREATE|DI_SUB_AUTHOR, OUString() );
1737  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1738  return eF_ResT::OK;
1739 }
1740 
1742 {
1743  SwTemplNameField aField( static_cast<SwTemplNameFieldType*>(
1744  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::TemplateName )), FF_NAME );
1745  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1746  return eF_ResT::OK;
1747 }
1748 
1749 // Both the date and the time fields can be used for showing a date a time or both.
1751 {
1752  bool bHijri = false;
1753  WW8ReadFieldParams aReadParam(rStr);
1754  for (;;)
1755  {
1756  const sal_Int32 nTok = aReadParam.SkipToNextToken();
1757  if ( nTok==-1 )
1758  break;
1759  switch (nTok)
1760  {
1761  default:
1762  case 'l':
1763  case -2:
1764  break;
1765  case 'h':
1766  bHijri = true;
1767  break;
1768  case 's':
1769  //Saka Calendar, should we do something with this ?
1770  break;
1771  }
1772  }
1773 
1774  sal_uInt32 nFormat = 0;
1775 
1777  SvNumFormatType nDT = GetTimeDatePara(rStr, nFormat, nLang, ww::eDATE, bHijri);
1778 
1779  if( SvNumFormatType::UNDEFINED == nDT ) // no D/T-Formatstring
1780  {
1781  if (32 == pF->nId)
1782  {
1783  nDT = SvNumFormatType::TIME;
1784  nFormat = m_rDoc.GetNumberFormatter()->GetFormatIndex(
1786  }
1787  else
1788  {
1789  nDT = SvNumFormatType::DATE;
1790  nFormat = m_rDoc.GetNumberFormatter()->GetFormatIndex(
1792  }
1793  }
1794 
1795  if (nDT & SvNumFormatType::DATE)
1796  {
1797  SwDateTimeField aField(static_cast<SwDateTimeFieldType*>(
1798  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DateTime )), DATEFLD, nFormat);
1799  ForceFieldLanguage(aField, nLang);
1800  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1801  }
1802  else if (nDT == SvNumFormatType::TIME)
1803  {
1804  SwDateTimeField aField(static_cast<SwDateTimeFieldType*>(
1805  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DateTime)), TIMEFLD, nFormat);
1806  ForceFieldLanguage(aField, nLang);
1807  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1808  }
1809 
1810  return eF_ResT::OK;
1811 }
1812 
1814 {
1816  WW8ReadFieldParams aReadParam(rStr);
1817  for (;;)
1818  {
1819  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1820  if ( nRet==-1 )
1821  break;
1822  switch (nRet)
1823  {
1824  case 'p':
1825  eType = FF_PATHNAME;
1826  break;
1827  case '*':
1828  //Skip over MERGEFORMAT
1829  (void)aReadParam.SkipToNextToken();
1830  break;
1831  default:
1832  OSL_ENSURE(false, "unknown option in FileName field");
1833  break;
1834  }
1835  }
1836 
1837  SwFileNameField aField(
1838  static_cast<SwFileNameFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Filename)), eType);
1839  m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
1840  return eF_ResT::OK;
1841 }
1842 
1844 {
1845  sal_uInt16 nSub = DS_PAGE; // page number
1846  switch ( pF->nId ){
1847  case 27: nSub = DS_WORD; break; // number of words
1848  case 28: nSub = DS_CHAR; break; // number of characters
1849  }
1850  SwDocStatField aField( static_cast<SwDocStatFieldType*>(
1851  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocStat )), nSub,
1852  GetNumberPara( rStr ) );
1853  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1854  return eF_ResT::OK;
1855 }
1856 
1858 {
1859  // page number
1860  SwPageNumberField aField( static_cast<SwPageNumberFieldType*>(
1861  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::PageNumber )), PG_RANDOM,
1862  GetNumberPara(rStr, true));
1863 
1864  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1865  return eF_ResT::OK;
1866 }
1867 
1869 {
1870  //e.g. #i20118#
1871  OUString aQ;
1872  OUString aName;
1873  sal_Int32 nSize = 0;
1874  WW8ReadFieldParams aReadParam( rStr );
1875  for (;;)
1876  {
1877  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1878  if ( nRet==-1 )
1879  break;
1880  switch( nRet )
1881  {
1882  case -2:
1883  if( aQ.isEmpty() )
1884  aQ = aReadParam.GetResult();
1885  break;
1886  case 'f':
1887  case 'F':
1888  if ( aReadParam.GoToTokenParam() )
1889  aName = aReadParam.GetResult();
1890  break;
1891  case 's':
1892  case 'S':
1893  if ( aReadParam.GoToTokenParam() )
1894  {
1895  const OUString aSiz = aReadParam.GetResult();
1896  if (!aSiz.isEmpty())
1897  {
1898  bool bFail = o3tl::checked_multiply<sal_Int32>(aSiz.toInt32(), 20, nSize); // pT -> twip
1899  if (bFail)
1900  nSize = -1;
1901  }
1902  }
1903  break;
1904  }
1905  }
1906  if( aQ.isEmpty() )
1907  return eF_ResT::TAGIGN; // -> no 0-char in text
1908 
1909  if (sal_Unicode cChar = static_cast<sal_Unicode>(aQ.toInt32()))
1910  {
1911  if (!aName.isEmpty()) // Font Name set ?
1912  {
1913  SvxFontItem aFont(FAMILY_DONTKNOW, aName, OUString(),
1914  PITCH_DONTKNOW, RTL_TEXTENCODING_SYMBOL, RES_CHRATR_FONT);
1915  NewAttr(aFont); // new Font
1916  }
1917 
1918  if (nSize > 0) //#i20118#
1919  {
1920  SvxFontHeightItem aSz(nSize, 100, RES_CHRATR_FONTSIZE);
1921  NewAttr(aSz);
1922  }
1923 
1924  m_rDoc.getIDocumentContentOperations().InsertString(*m_pPaM, OUString(cChar));
1925 
1926  if (nSize > 0)
1927  m_xCtrlStck->SetAttr(*m_pPaM->GetPoint(), RES_CHRATR_FONTSIZE);
1928  if (!aName.isEmpty())
1929  m_xCtrlStck->SetAttr(*m_pPaM->GetPoint(), RES_CHRATR_FONT);
1930  }
1931  else
1932  {
1933  m_rDoc.getIDocumentContentOperations().InsertString(*m_pPaM, "###");
1934  }
1935 
1936  return eF_ResT::OK;
1937 }
1938 
1939 // "EMBED"
1941 {
1942  WW8ReadFieldParams aReadParam( rStr );
1943  for (;;)
1944  {
1945  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1946  if ( nRet==-1 )
1947  break;
1948  switch( nRet )
1949  {
1950  case -2:
1951  // sHost
1952  break;
1953 
1954  case 's':
1955  // use ObjectSize
1956  break;
1957  }
1958  }
1959 
1960  if( m_bObj && m_nPicLocFc )
1961  m_nObjLocFc = m_nPicLocFc;
1962  m_bEmbeddObj = true;
1963  return eF_ResT::TEXT;
1964 }
1965 
1966 // "SET"
1968 {
1969  OUString sOrigName;
1970  OUString sVal;
1971  WW8ReadFieldParams aReadParam( rStr );
1972  for (;;)
1973  {
1974  const sal_Int32 nRet = aReadParam.SkipToNextToken();
1975  if ( nRet==-1 )
1976  break;
1977  switch( nRet )
1978  {
1979  case -2:
1980  if (sOrigName.isEmpty())
1981  sOrigName = aReadParam.GetResult();
1982  else if (sVal.isEmpty())
1983  sVal = aReadParam.GetResult();
1984  break;
1985  }
1986  }
1987 
1988  const long nNo = MapBookmarkVariables(pF, sOrigName, sVal);
1989 
1990  SwFieldType* pFT = m_rDoc.getIDocumentFieldsAccess().InsertFieldType( SwSetExpFieldType( &m_rDoc, sOrigName,
1992  SwSetExpField aField( static_cast<SwSetExpFieldType*>(pFT), sVal, ULONG_MAX );
1994 
1995  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
1996 
1997  m_xReffedStck->SetAttr(*m_pPaM->GetPoint(), RES_FLTR_BOOKMARK, true, nNo);
1998 
1999  return eF_ResT::OK;
2000 }
2001 
2002 // "REF"
2004 { // Reference - Field
2005  OUString sOrigBkmName;
2006  REFERENCEMARK eFormat = REF_CONTENT;
2007 
2008  WW8ReadFieldParams aReadParam( rStr );
2009  for (;;)
2010  {
2011  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2012  if ( nRet==-1 )
2013  break;
2014  switch( nRet )
2015  {
2016  case -2:
2017  if( sOrigBkmName.isEmpty() ) // get name of bookmark
2018  sOrigBkmName = aReadParam.GetResult();
2019  break;
2020 
2021  /* References to numbers in Word could be either to a numbered
2022  paragraph or to a chapter number. However Word does not seem to
2023  have the capability we do, of referring to the chapter number some
2024  other bookmark is in. As a result, cross-references to chapter
2025  numbers in a word document will be cross-references to a numbered
2026  paragraph, being the chapter heading paragraph. As it happens, our
2027  cross-references to numbered paragraphs will do the right thing
2028  when the target is a numbered chapter heading, so there is no need
2029  for us to use the REF_CHAPTER bookmark format on import.
2030  */
2031  case 'n':
2032  eFormat = REF_NUMBER_NO_CONTEXT;
2033  break;
2034  case 'r':
2035  eFormat = REF_NUMBER;
2036  break;
2037  case 'w':
2038  eFormat = REF_NUMBER_FULL_CONTEXT;
2039  break;
2040 
2041  case 'p':
2042  eFormat = REF_UPDOWN;
2043  break;
2044  case 'h':
2045  break;
2046  default:
2047  // unimplemented switch: just do 'nix nought nothing' :-)
2048  break;
2049  }
2050  }
2051 
2052  OUString sBkmName(GetMappedBookmark(sOrigBkmName));
2053 
2054  // #i120879# add cross reference bookmark name prefix, if it
2055  // matches internal TOC bookmark naming convention
2056  if ( IsTOCBookmarkName( sBkmName ) )
2057  {
2058  sBkmName = EnsureTOCBookmarkName(sBkmName);
2059  // track <sBookmarkName> as referenced TOC bookmark.
2060  m_xReffedStck->aReferencedTOCBookmarks.insert( sBkmName );
2061  }
2062 
2063  SwGetRefField aField(
2064  static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),
2065  sBkmName,"",REF_BOOKMARK,0,eFormat);
2066 
2067  if (eFormat == REF_CONTENT)
2068  {
2069  /*
2070  If we are just inserting the contents of the bookmark, then it
2071  is possible that the bookmark is actually a variable, so we
2072  must store it until the end of the document to see if it was,
2073  in which case we'll turn it into a show variable
2074  */
2075  m_xReffingStck->NewAttr( *m_pPaM->GetPoint(), SwFormatField(aField) );
2076  m_xReffingStck->SetAttr( *m_pPaM->GetPoint(), RES_TXTATR_FIELD);
2077  }
2078  else
2079  {
2080  m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField));
2081  }
2082  return eF_ResT::OK;
2083 }
2084 
2085 // Note Reference - Field
2087 {
2088  OUString aBkmName;
2089  bool bAboveBelow = false;
2090 
2091  WW8ReadFieldParams aReadParam( rStr );
2092  for (;;)
2093  {
2094  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2095  if ( nRet==-1 )
2096  break;
2097  switch( nRet )
2098  {
2099  case -2:
2100  if( aBkmName.isEmpty() ) // get name of foot/endnote
2101  aBkmName = aReadParam.GetResult();
2102  break;
2103  case 'r':
2104  // activate flag 'Chapter Number'
2105  break;
2106  case 'p':
2107  bAboveBelow = true;
2108  break;
2109  case 'h':
2110  break;
2111  default:
2112  // unimplemented switch: just do 'nix nought nothing' :-)
2113  break;
2114  }
2115  }
2116 
2117  // set Sequence No of corresponding Foot-/Endnote to Zero
2118  // (will be corrected in
2119  SwGetRefField aField( static_cast<SwGetRefFieldType*>(
2120  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), aBkmName, "", REF_FOOTNOTE, 0,
2121  REF_ONLYNUMBER );
2122  m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField));
2123  m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD);
2124  if (bAboveBelow)
2125  {
2126  SwGetRefField aField2( static_cast<SwGetRefFieldType*>(
2127  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),aBkmName, "", REF_FOOTNOTE, 0,
2128  REF_UPDOWN );
2129  m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField2));
2130  m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD);
2131  }
2132  return eF_ResT::OK;
2133 }
2134 
2135 // "PAGEREF"
2137 {
2138  OUString sOrigName;
2139  WW8ReadFieldParams aReadParam( rStr );
2140  for (;;)
2141  {
2142  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2143  if ( nRet==-1 )
2144  break;
2145  else if ( nRet == -2 && sOrigName.isEmpty() )
2146  {
2147  sOrigName = aReadParam.GetResult();
2148  }
2149  }
2150 
2151  const OUString sName(GetMappedBookmark(sOrigName));
2152 
2153  // loading page reference field in TOX
2154  if (m_bLoadingTOXCache)
2155  {
2156  // insert page ref representation as plain text --> return FLD_TEXT
2157  // if there is no hyperlink settings for current toc and referenced bookmark is available,
2158  // assign link to current ref area
2159  if (!m_bLoadingTOXHyperlink && !sName.isEmpty())
2160  {
2161  // #i120879# add cross reference bookmark name prefix, if it
2162  // matches internal TOC bookmark naming convention
2163  OUString sBookmarkName;
2164  if ( IsTOCBookmarkName( sName ) )
2165  {
2166  sBookmarkName = EnsureTOCBookmarkName(sName);
2167  // track <sBookmarkName> as referenced TOC bookmark.
2168  m_xReffedStck->aReferencedTOCBookmarks.insert( sBookmarkName );
2169  }
2170  else
2171  {
2172  sBookmarkName = sName;
2173  }
2174  OUString sURL = "#" + sBookmarkName;
2175  const OUString sTarget;
2176  SwFormatINetFormat aURL( sURL, sTarget );
2177  const OUString sLinkStyle("Index Link");
2178  const sal_uInt16 nPoolId =
2180  aURL.SetVisitedFormatAndId( sLinkStyle, nPoolId);
2181  aURL.SetINetFormatAndId( sLinkStyle, nPoolId );
2182  m_xCtrlStck->NewAttr( *m_pPaM->GetPoint(), aURL );
2183  }
2184  return eF_ResT::TEXT;
2185  }
2186 
2187  // #i120879# add cross reference bookmark name prefix, if it matches
2188  // internal TOC bookmark naming convention
2189  OUString sPageRefBookmarkName;
2190  if ( IsTOCBookmarkName( sName ) )
2191  {
2192  sPageRefBookmarkName = EnsureTOCBookmarkName(sName);
2193  // track <sPageRefBookmarkName> as referenced TOC bookmark.
2194  m_xReffedStck->aReferencedTOCBookmarks.insert( sPageRefBookmarkName );
2195  }
2196  else
2197  {
2198  sPageRefBookmarkName = sName;
2199  }
2200  SwGetRefField aField( static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),
2201  sPageRefBookmarkName, "", REF_BOOKMARK, 0, REF_PAGE );
2202  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
2203 
2204  return eF_ResT::OK;
2205 }
2206 
2207 //helper function
2208 //For MS MacroButton field, the symbol in plain text is always "(" (0x28),
2209 //which should be mapped according to the macro type
2210 static bool ConvertMacroSymbol( const OUString& rName, OUString& rReference )
2211 {
2212  bool bConverted = false;
2213  if( rReference == "(" )
2214  {
2215  bConverted = true;
2216  sal_Unicode cSymbol = sal_Unicode(); // silence false warning
2217  if (rName == "CheckIt")
2218  cSymbol = 0xF06F;
2219  else if (rName == "UncheckIt")
2220  cSymbol = 0xF0FE;
2221  else if (rName == "ShowExample")
2222  cSymbol = 0xF02A;
2223  //else if... : todo
2224  else
2225  bConverted = false;
2226 
2227  if( bConverted )
2228  rReference = OUString(cSymbol);
2229  }
2230  return bConverted;
2231 }
2232 
2233 // "MACROBUTTON"
2235 {
2236  OUString aName;
2237  OUString aVText;
2238  bool bNewVText = true;
2239  bool bBracket = false;
2240  WW8ReadFieldParams aReadParam( rStr );
2241 
2242  sal_Int32 nOffset = 0;
2243 
2244  for (;;)
2245  {
2246  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2247  if ( nRet==-1 )
2248  break;
2249  switch( nRet )
2250  {
2251  case -2:
2252  if( aName.isEmpty() )
2253  aName = aReadParam.GetResult();
2254  else if( aVText.isEmpty() || bBracket )
2255  {
2256  nOffset = aReadParam.GetTokenSttPtr() + 1;
2257 
2258  if( bBracket )
2259  aVText += " ";
2260  aVText += aReadParam.GetResult();
2261  if (bNewVText)
2262  {
2263  bBracket = (aVText[0] == '[');
2264  bNewVText = false;
2265  }
2266  else if( aVText.endsWith("]") )
2267  bBracket = false;
2268  }
2269  break;
2270  }
2271  }
2272  if( aName.isEmpty() )
2273  return eF_ResT::TAGIGN; // makes no sense without Macro-Name
2274 
2275  //try converting macro symbol according to macro name
2276  bool bApplyWingdings = ConvertMacroSymbol( aName, aVText );
2277  aName = "StarOffice.Standard.Modul1." + aName;
2278 
2279  SwMacroField aField( static_cast<SwMacroFieldType*>(
2280  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Macro )), aName, aVText );
2281 
2282  if( !bApplyWingdings )
2283  {
2284 
2285  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
2286  WW8_CP nOldCp = m_xPlcxMan->Where();
2287  WW8_CP nCp = nOldCp + nOffset;
2288 
2289  SwPaM aPaM(*m_pPaM, m_pPaM);
2290  aPaM.SetMark();
2291  aPaM.Move(fnMoveBackward);
2292  aPaM.Exchange();
2293 
2294  m_pPostProcessAttrsInfo.reset(new WW8PostProcessAttrsInfo(nCp, nCp, aPaM));
2295  }
2296  else
2297  {
2298  //set Wingdings font
2299  sal_uInt16 i = 0;
2300  for ( ; i < m_xFonts->GetMax(); i++ )
2301  {
2302  FontFamily eFamily;
2303  OUString aFontName;
2304  FontPitch ePitch;
2305  rtl_TextEncoding eSrcCharSet;
2306  if( GetFontParams( i, eFamily, aFontName, ePitch, eSrcCharSet )
2307  && aFontName=="Wingdings" )
2308  {
2309  break;
2310  }
2311  }
2312 
2313  if ( i < m_xFonts->GetMax() )
2314  {
2315 
2316  SetNewFontAttr( i, true, RES_CHRATR_FONT );
2317  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
2318  m_xCtrlStck->SetAttr( *m_pPaM->GetPoint(), RES_CHRATR_FONT );
2319  ResetCharSetVars();
2320  }
2321  }
2322 
2323  return eF_ResT::OK;
2324 }
2325 
2327  SwPaM & rPaM)
2328  : mbCopy(false)
2329  , mnCpStart(nCpStart)
2330  , mnCpEnd(nCpEnd)
2331  , mPaM(*rPaM.GetMark(), *rPaM.GetPoint())
2332  , mItemSet(rPaM.GetDoc()->GetAttrPool(), svl::Items<RES_CHRATR_BEGIN, RES_PARATR_END - 1>{})
2333 {
2334 }
2335 
2336 bool CanUseRemoteLink(const OUString &rGrfName)
2337 {
2338  bool bUseRemote = false;
2339  try
2340  {
2341  // Related: tdf#102499, add a default css::ucb::XCommandEnvironment
2342  // in order to have https protocol manage certificates correctly
2343  uno::Reference< task::XInteractionHandler > xIH(
2344  task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr));
2345 
2346  uno::Reference< ucb::XProgressHandler > xProgress;
2347  ::ucbhelper::CommandEnvironment* pCommandEnv =
2348  new ::ucbhelper::CommandEnvironment(new comphelper::SimpleFileAccessInteraction( xIH ), xProgress);
2349 
2350  ::ucbhelper::Content aCnt(rGrfName,
2351  static_cast< ucb::XCommandEnvironment* >(pCommandEnv),
2353 
2354  if ( !INetURLObject( rGrfName ).isAnyKnownWebDAVScheme() )
2355  {
2356  OUString aTitle;
2357  aCnt.getPropertyValue("Title") >>= aTitle;
2358  bUseRemote = !aTitle.isEmpty();
2359  }
2360  else
2361  {
2362  // is a link to a WebDAV resource
2363  // need to use MediaType to check for link usability
2364  OUString aMediaType;
2365  aCnt.getPropertyValue("MediaType") >>= aMediaType;
2366  bUseRemote = !aMediaType.isEmpty();
2367  }
2368  }
2369  catch ( ... )
2370  {
2371  // this file did not exist, so we will not set this as graphiclink
2372  bUseRemote = false;
2373  }
2374  return bUseRemote;
2375 }
2376 
2377 // "INCLUDEPICTURE"
2379 {
2380  OUString aGrfName;
2381  bool bEmbedded = true;
2382 
2383  WW8ReadFieldParams aReadParam( rStr );
2384  for (;;)
2385  {
2386  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2387  if ( nRet==-1 )
2388  break;
2389  switch( nRet )
2390  {
2391  case -2:
2392  if (aGrfName.isEmpty())
2393  aGrfName = ConvertFFileName(aReadParam.GetResult());
2394  break;
2395 
2396  case 'd':
2397  bEmbedded = false;
2398  break;
2399 
2400  case 'c':// skip the converter name
2401  aReadParam.FindNextStringPiece();
2402  break;
2403  }
2404  }
2405 
2406  if (!bEmbedded)
2407  bEmbedded = !CanUseRemoteLink(aGrfName);
2408 
2409  if (!bEmbedded)
2410  {
2411  /*
2412  Special case:
2413 
2414  Now we write the Link into the Doc and remember the SwFlyFrameFormat.
2415  Since we end on return FLD_READ_FSPA below, the skip value will be set
2416  so that Char-1 will still be read.
2417  When we then call SwWW8ImplReader::ImportGraf() it will then recognize
2418  that we have inserted a graphic link and the suiting SwAttrSet will be
2419  inserted into the frame format.
2420  */
2422  RES_FRMATR_END-1>{} );
2423  aFlySet.Put( SwFormatAnchor( RndStdIds::FLY_AS_CHAR ) );
2424  aFlySet.Put( SwFormatVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ));
2427  aGrfName,
2428  OUString(),
2429  nullptr, // Graphic*
2430  &aFlySet,
2431  nullptr, nullptr); // SwFrameFormat*
2433  INetURLObject(aGrfName).GetBase());
2434  }
2435  return eF_ResT::READ_FSPA;
2436 }
2437 
2439 {
2440  const OUString aName(msFileLinkSeed + OUString::number(++mnFileSectionNo));
2441  return mrDoc.GetUniqueSectionName(&aName);
2442 }
2443 
2444 // "INCLUDETEXT"
2446 {
2447  OUString aPara;
2448  OUString aBook;
2449  WW8ReadFieldParams aReadParam( rStr );
2450  for (;;)
2451  {
2452  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2453  if ( nRet==-1 )
2454  break;
2455  switch( nRet )
2456  {
2457  case -2:
2458  if( aPara.isEmpty() )
2459  aPara = aReadParam.GetResult();
2460  else if( aBook.isEmpty() )
2461  aBook = aReadParam.GetResult();
2462  break;
2463  case '*':
2464  //Skip over MERGEFORMAT
2465  (void)aReadParam.SkipToNextToken();
2466  break;
2467  }
2468  }
2469  aPara = ConvertFFileName(aPara);
2470 
2471  if (!aBook.isEmpty() && aBook[ 0 ] != '\\')
2472  {
2473  // Section from Source (no switch)?
2474  ConvertUFName(aBook);
2475  aPara += OUStringLiteral1(sfx2::cTokenSeparator)
2476  + OUStringLiteral1(sfx2::cTokenSeparator) + aBook;
2477  }
2478 
2479  /*
2480  ##509##
2481  What we will do is insert a section to be linked to a file, but just in
2482  case the file is not available we will fill in the section with the stored
2483  content of this winword field as a fallback.
2484  */
2485  SwPosition aTmpPos(*m_pPaM->GetPoint());
2486 
2489  aSection.SetLinkFileName( aPara );
2490  aSection.SetProtectFlag(true);
2491 
2492  SwSection *const pSection =
2493  m_rDoc.InsertSwSection(*m_pPaM, aSection, nullptr, nullptr, false);
2494  OSL_ENSURE(pSection, "no section inserted");
2495  if (!pSection)
2496  return eF_ResT::TEXT;
2497  const SwSectionNode* pSectionNode = pSection->GetFormat()->GetSectionNode();
2498  OSL_ENSURE(pSectionNode, "no section node!");
2499  if (!pSectionNode)
2500  return eF_ResT::TEXT;
2501 
2502  m_pPaM->GetPoint()->nNode = pSectionNode->GetIndex()+1;
2504 
2505  //we have inserted a section before this point, so adjust pos
2506  //for future page/section segment insertion
2508 
2509  return eF_ResT::TEXT;
2510 }
2511 
2512 // "SERIALPRINT"
2514 {
2515 #if !HAVE_FEATURE_DBCONNECTIVITY
2516  (void) pF;
2517  (void) rStr;
2518 #else
2519  OUString aName;
2520  WW8ReadFieldParams aReadParam( rStr );
2521  for (;;)
2522  {
2523  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2524  if ( nRet==-1 )
2525  break;
2526  switch( nRet )
2527  {
2528  case -2:
2529  if( aName.isEmpty() )
2530  aName = aReadParam.GetResult();
2531  break;
2532  }
2533  }
2534  SwDBFieldType aD( &m_rDoc, aName, SwDBData() ); // Database: nothing
2535 
2537  SwDBField aField( static_cast<SwDBFieldType*>(pFT) );
2538  aField.SetFieldCode( rStr );
2539 
2540  OUString aResult;
2541  m_xSBase->WW8ReadString( *m_pStrm, aResult, m_xPlcxMan->GetCpOfs()+
2542  pF->nSRes, pF->nLRes, m_eTextCharSet );
2543 
2544  aResult = aResult.replace( '\xb', '\n' );
2545 
2546  aField.InitContent(aResult);
2547 
2549 #endif
2550  return eF_ResT::OK;
2551 }
2552 
2553 // "NEXT"
2555 {
2556 #if HAVE_FEATURE_DBCONNECTIVITY
2559  SwDBNextSetField aField( static_cast<SwDBNextSetFieldType*>(pFT), OUString(),
2560  SwDBData() ); // Database: nothing
2562 #endif
2563  return eF_ResT::OK;
2564 }
2565 
2566 // "DATASET"
2568 {
2569 #if HAVE_FEATURE_DBCONNECTIVITY
2572  SwDBSetNumberField aField( static_cast<SwDBSetNumberFieldType*>(pFT),
2573  SwDBData() ); // Datenbase: nothing
2575 #endif
2576  return eF_ResT::OK;
2577 }
2578 
2579 /*
2580  EQ , only the usage for
2581  a. Combined Characters supported, must be exactly in the form that word
2582  only accepts as combined characters, i.e.
2583  eq \o(\s\up Y(XXX),\s\do Y(XXX))
2584  b. Ruby Text supported, must be in the form that word recognizes as being
2585  ruby text
2586  ...
2587 */
2589 {
2590  WW8ReadFieldParams aReadParam( rStr );
2591  const sal_Int32 cChar = aReadParam.SkipToNextToken();
2592  if ('o' == cChar || 'O' == cChar)
2593  {
2594  EquationResult aResult(ParseCombinedChars(rStr));
2595 
2596  if (aResult.sType == "Input")
2597  {
2598  SwInputField aField( static_cast<SwInputFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Input )),
2599  aResult.sResult, aResult.sResult, INP_TXT, 0 );
2600  m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); // insert input field
2601  }
2602  else if (aResult.sType == "CombinedCharacters")
2603  {
2604  SwCombinedCharField aField(static_cast<SwCombinedCharFieldType*>(
2607  }
2608  }
2609  else if ('*' == cChar)
2610  Read_SubF_Ruby(aReadParam);
2611 
2612  return eF_ResT::OK;
2613 }
2614 
2616 {
2617  sal_uInt16 nJustificationCode=0;
2618  OUString sFontName;
2619  sal_uInt32 nFontSize=0;
2620  OUString sRuby;
2621  OUString sText;
2622  for (;;)
2623  {
2624  const sal_Int32 nRet = rReadParam.SkipToNextToken();
2625  if ( nRet==-1 )
2626  break;
2627  switch( nRet )
2628  {
2629  case -2:
2630  {
2631  OUString sTemp = rReadParam.GetResult();
2632  if( sTemp.startsWithIgnoreAsciiCase( "jc" ) )
2633  {
2634  sTemp = sTemp.copy(2);
2635  nJustificationCode = static_cast<sal_uInt16>(sTemp.toInt32());
2636  }
2637  else if( sTemp.startsWithIgnoreAsciiCase( "hps" ) )
2638  {
2639  sTemp = sTemp.copy(3);
2640  nFontSize= static_cast<sal_uInt32>(sTemp.toInt32());
2641  }
2642  else if( sTemp.startsWithIgnoreAsciiCase( "Font:" ) )
2643  {
2644  sTemp = sTemp.copy(5);
2645  sFontName = sTemp;
2646  }
2647  }
2648  break;
2649  case '*':
2650  break;
2651  case 'o':
2652  for (;;)
2653  {
2654  const sal_Int32 nRes = rReadParam.SkipToNextToken();
2655  if ( nRes==-1 )
2656  break;
2657  if ('u' == nRes)
2658  {
2659  if (-2 == rReadParam.SkipToNextToken() &&
2660  rReadParam.GetResult().startsWithIgnoreAsciiCase("p"))
2661  {
2662  if (-2 == rReadParam.SkipToNextToken())
2663  {
2664  OUString sPart = rReadParam.GetResult();
2665  sal_Int32 nBegin = sPart.indexOf('(');
2666 
2667  //Word disallows brackets in this field,
2668  sal_Int32 nEnd = sPart.indexOf(')');
2669 
2670  if ((nBegin != -1) &&
2671  (nEnd != -1) && (nBegin < nEnd))
2672  {
2673  sRuby = sPart.copy(nBegin+1,nEnd-nBegin-1);
2674  }
2675  if (-1 != nEnd)
2676  {
2677  if (-1 ==
2678  (nBegin = sPart.indexOf(',',nEnd)))
2679  {
2680  nBegin = sPart.indexOf(';',nEnd);
2681  }
2682  nEnd = sPart.lastIndexOf(')');
2683  }
2684  if ((nBegin != -1) && (nEnd != -1) && (nBegin < nEnd))
2685  {
2686  sText = sPart.copy(nBegin+1,nEnd-nBegin-1);
2687  }
2688  }
2689  }
2690  }
2691 
2692  }
2693  break;
2694  }
2695  }
2696 
2697  //Translate and apply
2698  if (sRuby.isEmpty() || sText.isEmpty() || sFontName.isEmpty() || !nFontSize)
2699  return;
2700 
2701  css::text::RubyAdjust eRubyAdjust;
2702  switch (nJustificationCode)
2703  {
2704  case 0:
2705  eRubyAdjust = css::text::RubyAdjust_CENTER;
2706  break;
2707  case 1:
2708  eRubyAdjust = css::text::RubyAdjust_BLOCK;
2709  break;
2710  case 2:
2711  eRubyAdjust = css::text::RubyAdjust_INDENT_BLOCK;
2712  break;
2713  default:
2714  case 3:
2715  eRubyAdjust = css::text::RubyAdjust_LEFT;
2716  break;
2717  case 4:
2718  eRubyAdjust = css::text::RubyAdjust_RIGHT;
2719  break;
2720  }
2721 
2722  SwFormatRuby aRuby(sRuby);
2723  const SwCharFormat *pCharFormat=nullptr;
2724  //Make a guess at which of asian of western we should be setting
2725  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
2726  sal_uInt16 nScript = g_pBreakIt->GetBreakIter()->getScriptType(sRuby, 0);
2727 
2728  //Check to see if we already have a ruby charstyle that this fits
2729  for(const auto& rpCharFormat : m_aRubyCharFormats)
2730  {
2731  const SvxFontHeightItem &rFH =
2732  ItemGet<SvxFontHeightItem>(*rpCharFormat,
2734  if (rFH.GetHeight() == nFontSize*10)
2735  {
2736  const SvxFontItem &rF = ItemGet<SvxFontItem>(*rpCharFormat,
2738  if (rF.GetFamilyName() == sFontName)
2739  {
2740  pCharFormat = rpCharFormat;
2741  break;
2742  }
2743  }
2744  }
2745 
2746  //Create a new char style if necessary
2747  if (!pCharFormat)
2748  {
2749  OUString aNm;
2750  //Take this as the base name
2752  aNm+=OUString::number(m_aRubyCharFormats.size()+1);
2754  SvxFontHeightItem aHeightItem(nFontSize*10, 100, RES_CHRATR_FONTSIZE);
2755  SvxFontItem aFontItem(FAMILY_DONTKNOW,sFontName,
2756  OUString(), PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, RES_CHRATR_FONT);
2757  aHeightItem.SetWhich(GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript));
2758  aFontItem.SetWhich(GetWhichOfScript(RES_CHRATR_FONT,nScript));
2759  pFormat->SetFormatAttr(aHeightItem);
2760  pFormat->SetFormatAttr(aFontItem);
2761  m_aRubyCharFormats.push_back(pFormat);
2762  pCharFormat = pFormat;
2763  }
2764 
2765  //Set the charstyle and justification
2766  aRuby.SetCharFormatName(pCharFormat->GetName());
2767  aRuby.SetCharFormatId(pCharFormat->GetPoolFormatId());
2768  aRuby.SetAdjustment(eRubyAdjust);
2769 
2770  NewAttr(aRuby);
2773 
2774 }
2775 
2776 // "table of ..." fields
2777 
2778 static void lcl_toxMatchACSwitch(SwDoc const & rDoc,
2779  SwTOXBase& rBase,
2780  WW8ReadFieldParams& rParam,
2781  SwCaptionDisplay eCaptionType)
2782 {
2783  if ( rParam.GoToTokenParam() )
2784  {
2785  SwTOXType* pType = const_cast<SwTOXType*>(rDoc.GetTOXType( TOX_ILLUSTRATIONS, 0));
2786  rBase.RegisterToTOXType( *pType );
2787  rBase.SetCaptionDisplay( eCaptionType );
2788  // Read Sequence Name and store in TOXBase
2789  OUString sSeqName( rParam.GetResult() );
2790  lcl_ConvertSequenceName( sSeqName );
2791  rBase.SetSequenceName( sSeqName );
2792  }
2793 }
2794 
2796 {
2797  //If the TOC contains Template entries at levels > the evaluation level
2798  //that was initially taken from the max normal outline level of the word TOC
2799  //then we cannot use that for the evaluation level because writer cuts off
2800  //all styles above that level, while word just cuts off the "standard"
2801  //outline styles, we have no option but to expand to the highest level
2802  //Word included.
2803  if ((rBase.GetLevel() != MAXLEVEL) && (SwTOXElement::Template & rBase.GetCreateType()))
2804  {
2805  for (sal_uInt16 nI = MAXLEVEL; nI > 0; --nI)
2806  {
2807  if (!rBase.GetStyleNames(nI-1).isEmpty())
2808  {
2809  rBase.SetLevel(nI);
2810  break;
2811  }
2812  }
2813  }
2814 }
2815 
2816 static void lcl_toxMatchTSwitch(SwWW8ImplReader const & rReader, SwTOXBase& rBase,
2817  WW8ReadFieldParams& rParam)
2818 {
2819  if ( rParam.GoToTokenParam() )
2820  {
2821  OUString sParams( rParam.GetResult() );
2822  if( !sParams.isEmpty() )
2823  {
2824  sal_Int32 nIndex = 0;
2825 
2826  // Delimiters between styles and style levels appears to allow both ; and ,
2827 
2828  OUString sTemplate( sParams.getToken(0, ';', nIndex) );
2829  if( -1 == nIndex )
2830  {
2831  nIndex=0;
2832  sTemplate = sParams.getToken(0, ',', nIndex);
2833  }
2834  if( -1 == nIndex )
2835  {
2836  const SwFormat* pStyle = rReader.GetStyleWithOrgWWName(sTemplate);
2837  if( pStyle )
2838  sTemplate = pStyle->GetName();
2839  // Store Style for Level 0 into TOXBase
2840  rBase.SetStyleNames( sTemplate, 0 );
2841  }
2842  else while( -1 != nIndex )
2843  {
2844  sal_Int32 nOldIndex=nIndex;
2845  sal_uInt16 nLevel = static_cast<sal_uInt16>(
2846  sParams.getToken(0, ';', nIndex).toInt32());
2847  if( -1 == nIndex )
2848  {
2849  nIndex = nOldIndex;
2850  nLevel = static_cast<sal_uInt16>(
2851  sParams.getToken(0, ',', nIndex).toInt32());
2852  }
2853 
2854  if( (0 < nLevel) && (MAXLEVEL >= nLevel) )
2855  {
2856  nLevel--;
2857  // Store Style and Level into TOXBase
2858  const SwFormat* pStyle
2859  = rReader.GetStyleWithOrgWWName( sTemplate );
2860 
2861  if( pStyle )
2862  sTemplate = pStyle->GetName();
2863 
2864  OUString sStyles( rBase.GetStyleNames( nLevel ) );
2865  if( !sStyles.isEmpty() )
2866  sStyles += OUStringLiteral1(TOX_STYLE_DELIMITER);
2867  sStyles += sTemplate;
2868  rBase.SetStyleNames( sStyles, nLevel );
2869  }
2870  // read next style name...
2871  nOldIndex = nIndex;
2872  sTemplate = sParams.getToken(0, ';', nIndex);
2873  if( -1 == nIndex )
2874  {
2875  nIndex=nOldIndex;
2876  sTemplate = sParams.getToken(0, ',', nIndex);
2877  }
2878  }
2879  }
2880  }
2881 }
2882 
2884 {
2885  sal_uInt16 nIndexCols = 1;
2886  if (!maSegments.empty())
2887  nIndexCols = maSegments.back().maSep.ccolM1 + 1;
2888  return nIndexCols;
2889 }
2890 
2891 //Will there be a new pagebreak at this position (don't know what type
2892 //until later)
2894 {
2895  bool bRet = false;
2896  if (!maSegments.empty())
2897  {
2898  if (!maSegments.back().IsContinuous() &&
2899  maSegments.back().maStart == rIdx)
2900  {
2901  bRet = true;
2902  }
2903  }
2904  return bRet;
2905 }
2906 
2907 static sal_uInt16 lcl_GetMaxValidWordTOCLevel(const SwForm &rForm)
2908 {
2909  // GetFormMax() returns level + 1, hence the -1
2910  sal_uInt16 nRet = rForm.GetFormMax()-1;
2911 
2912  // If the max of this type of TOC is greater than the max of a word
2913  // possible toc, then clip to the word max
2914  if (nRet > WW8ListManager::nMaxLevel)
2916 
2917  return nRet;
2918 }
2919 
2921 {
2922  if (!m_bLoadingTOXCache)
2923  {
2924  m_bLoadingTOXCache = true;
2925  }
2926  else
2927  {
2928  // Embedded TOX --> continue reading its content, but no further TOX
2929  // field
2931  return eF_ResT::TEXT;
2932  }
2933 
2934  if (pF->nLRes < 3)
2935  return eF_ResT::TEXT; // ignore (#i25440#)
2936 
2937  TOXTypes eTox; // create a ToxBase
2938  switch( pF->nId )
2939  {
2940  case 8:
2941  eTox = TOX_INDEX;
2942  break;
2943  case 13:
2944  eTox = TOX_CONTENT;
2945  break;
2946  default:
2947  eTox = TOX_USER;
2948  break;
2949  }
2950 
2952 
2953  sal_uInt16 nIndexCols = 1;
2954 
2955  const SwTOXType* pType = m_rDoc.GetTOXType( eTox, 0 );
2956  SwForm aOrigForm(eTox);
2957  SwTOXBase* pBase = new SwTOXBase( pType, aOrigForm, nCreateOf, OUString() );
2959  switch( eTox ){
2960  case TOX_INDEX:
2961  {
2963 
2964  // We set SwTOXElement::OutlineLevel only if
2965  // the parameter \o is within 1 to 9
2966  // or the parameter \f exists
2967  // or NO switch parameter are given at all.
2968  WW8ReadFieldParams aReadParam( rStr );
2969  for (;;)
2970  {
2971  const sal_Int32 nRet = aReadParam.SkipToNextToken();
2972  if ( nRet==-1 )
2973  break;
2974  switch( nRet )
2975  {
2976  case 'c':
2977  if ( aReadParam.GoToTokenParam() )
2978  {
2979  const OUString sParams( aReadParam.GetResult() );
2980  // if NO OUString just ignore the \c
2981  if( !sParams.isEmpty() )
2982  {
2983  nIndexCols = static_cast<sal_uInt16>(sParams.toInt32());
2984  }
2985  }
2986  break;
2987  case 'e':
2988  {
2989  if ( aReadParam.GoToTokenParam() ) // if NO String just ignore the \e
2990  {
2991  OUString sDelimiter( aReadParam.GetResult() );
2992  SwForm aForm( pBase->GetTOXForm() );
2993 
2994  // Attention: if TOX_CONTENT brave
2995  // GetFormMax() returns MAXLEVEL + 1 !!
2996  sal_uInt16 nEnd = aForm.GetFormMax()-1;
2997 
2998  for(sal_uInt16 nLevel = 1;
2999  nLevel <= nEnd;
3000  ++nLevel)
3001  {
3002  // Levels count from 1
3003  // Level 0 is reserved for CAPTION
3004 
3005  // Insert delimiter instead of tab in front of the page number if there is one:
3006  FormTokenType ePrevType = TOKEN_END;
3008  // -> #i21237#
3009  SwFormTokens aPattern =
3010  aForm.GetPattern(nLevel);
3011  SwFormTokens::iterator aIt = aPattern.begin();
3012  do
3013  {
3014  eType = ++aIt == aPattern.end() ? TOKEN_END : aIt->eTokenType;
3015 
3016  if (eType == TOKEN_PAGE_NUMS)
3017  {
3018  if (TOKEN_TAB_STOP == ePrevType)
3019  {
3020  --aIt;
3021 
3022  if(0x09 == sDelimiter[0])
3023  aIt->eTabAlign = SvxTabAdjust::End;
3024  else
3025  {
3026  SwFormToken aToken(TOKEN_TEXT);
3027  aToken.sText = sDelimiter;
3028  *aIt = aToken;
3029  }
3030  aForm.SetPattern(nLevel, aPattern);
3031  }
3032 
3033  eType = TOKEN_END;
3034  }
3035 
3036  ePrevType = eType;
3037  }
3038  while (TOKEN_END != eType);
3039  // <- #i21237#
3040  }
3041  pBase->SetTOXForm( aForm );
3042  }
3043  }
3044  break;
3045  case 'h':
3046  {
3047  eOptions |= SwTOIOptions::AlphaDelimiter;
3048  }
3049  break;
3050  }
3051  }
3052  pBase->SetOptions( eOptions );
3053  }
3054  break;
3055 
3056  case TOX_CONTENT:
3057  {
3058  bool bIsHyperlink = false;
3059  // We set SwTOXElement::OutlineLevel only if
3060  // the parameter \o is within 1 to 9
3061  // or the parameter \f exists
3062  // or NO switch parameter are given at all.
3063  SwTOXElement eCreateFrom = SwTOXElement::NONE;
3064  sal_Int32 nMaxLevel = 0;
3065  WW8ReadFieldParams aReadParam( rStr );
3066  for (;;)
3067  {
3068  const sal_Int32 nRet = aReadParam.SkipToNextToken();
3069  if ( nRet==-1 )
3070  break;
3071  switch( nRet )
3072  {
3073  case 'h':
3074  bIsHyperlink = true;
3075  break;
3076  case 'a':
3077  case 'c':
3078  lcl_toxMatchACSwitch(m_rDoc, *pBase, aReadParam,
3079  ('c' == nRet)
3081  : CAPTION_TEXT );
3082  break;
3083  case 'o':
3084  {
3085  sal_Int32 nVal;
3086  if( !aReadParam.GetTokenSttFromTo(nullptr, &nVal, WW8ListManager::nMaxLevel) )
3087  nVal = lcl_GetMaxValidWordTOCLevel(aOrigForm);
3088  if( nMaxLevel < nVal )
3089  nMaxLevel = nVal;
3090  eCreateFrom |= SwTOXElement::OutlineLevel;
3091  }
3092  break;
3093  case 'f':
3094  eCreateFrom |= SwTOXElement::Mark;
3095  break;
3096  case 'l':
3097  {
3098  sal_Int32 nVal;
3099  if( aReadParam.GetTokenSttFromTo(nullptr, &nVal, WW8ListManager::nMaxLevel) )
3100  {
3101  if( nMaxLevel < nVal )
3102  nMaxLevel = nVal;
3103  eCreateFrom |= SwTOXElement::Mark;
3104  }
3105  }
3106  break;
3107  case 't': // paragraphs using special styles shall
3108  // provide the TOX's content
3109  lcl_toxMatchTSwitch(*this, *pBase, aReadParam);
3110  eCreateFrom |= SwTOXElement::Template;
3111  break;
3112  case 'p':
3113  {
3114  if ( aReadParam.GoToTokenParam() ) // if NO String just ignore the \p
3115  {
3116  OUString sDelimiter( aReadParam.GetResult() );
3117  SwForm aForm( pBase->GetTOXForm() );
3118 
3119  // Attention: if TOX_CONTENT brave
3120  // GetFormMax() returns MAXLEVEL + 1 !!
3121  sal_uInt16 nEnd = aForm.GetFormMax()-1;
3122 
3123  for(sal_uInt16 nLevel = 1;
3124  nLevel <= nEnd;
3125  ++nLevel)
3126  {
3127  // Levels count from 1
3128  // Level 0 is reserved for CAPTION
3129 
3130  // Insert delimiter instead of tab in front of the pagenumber if there is one:
3131  FormTokenType ePrevType = TOKEN_END;
3133 
3134  // -> #i21237#
3135  SwFormTokens aPattern = aForm.GetPattern(nLevel);
3136  SwFormTokens::iterator aIt = aPattern.begin();
3137  do
3138  {
3139  eType = ++aIt == aPattern.end() ? TOKEN_END : aIt->eTokenType;
3140 
3141  if (eType == TOKEN_PAGE_NUMS)
3142  {
3143  if (TOKEN_TAB_STOP == ePrevType)
3144  {
3145  --aIt;
3146 
3147  SwFormToken aToken(TOKEN_TEXT);
3148  aToken.sText = sDelimiter;
3149 
3150  *aIt = aToken;
3151  aForm.SetPattern(nLevel,
3152  aPattern);
3153  }
3154  eType = TOKEN_END;
3155  }
3156  ePrevType = eType;
3157  }
3158  while( TOKEN_END != eType );
3159  // <- #i21237#
3160  }
3161  pBase->SetTOXForm( aForm );
3162  }
3163  }
3164  break;
3165  case 'n': // don't print page numbers
3166  {
3167  // read START and END param
3168  sal_Int32 nStart(0);
3169  sal_Int32 nEnd(0);
3170  if( !aReadParam.GetTokenSttFromTo( &nStart, &nEnd,
3172  {
3173  nStart = 1;
3174  nEnd = aOrigForm.GetFormMax()-1;
3175  }
3176  // remove page numbers from this levels
3177  SwForm aForm( pBase->GetTOXForm() );
3178  if (aForm.GetFormMax() <= nEnd)
3179  nEnd = aForm.GetFormMax()-1;
3180  for ( sal_Int32 nLevel = nStart; nLevel<=nEnd; ++nLevel )
3181  {
3182  // Levels count from 1
3183  // Level 0 is reserved for CAPTION
3184 
3185  // Remove pagenumber and if necessary the tab in front of it:
3187  // -> #i21237#
3188  SwFormTokens aPattern = aForm.GetPattern(nLevel);
3189  SwFormTokens::iterator aIt = aPattern.begin();
3190  do
3191  {
3192  eType = ++aIt == aPattern.end() ? TOKEN_END : aIt->eTokenType;
3193 
3194  if (eType == TOKEN_PAGE_NUMS)
3195  {
3196  aIt = aPattern.erase(aIt);
3197  --aIt;
3198  if (
3199  TOKEN_TAB_STOP ==
3200  aIt->eTokenType
3201  )
3202  {
3203  aPattern.erase(aIt);
3204  aForm.SetPattern(nLevel, aPattern);
3205  }
3206  eType = TOKEN_END;
3207  }
3208  }
3209  while (TOKEN_END != eType);
3210  // <- #i21237#
3211  }
3212  pBase->SetTOXForm( aForm );
3213  }
3214  break;
3215 
3216  /*
3217  // the following switches are not (yet) supported
3218  // by good old StarWriter:
3219  case 'b':
3220  case 's':
3221  case 'd':
3222  break;
3223  */
3224  }
3225  }
3226 
3227  // For loading the expression of TOC field, we need to mapping its parameters to TOX entries tokens
3228  // also include the hyperlinks and page references
3229  SwFormToken aLinkStart(TOKEN_LINK_START);
3230  SwFormToken aLinkEnd(TOKEN_LINK_END);
3231  aLinkStart.sCharStyleName = "Index Link";
3232  aLinkEnd.sCharStyleName = "Index Link";
3233  SwForm aForm(pBase->GetTOXForm());
3234  sal_uInt16 nEnd = aForm.GetFormMax()-1;
3235 
3236  for(sal_uInt16 nLevel = 1; nLevel <= nEnd; ++nLevel)
3237  {
3238  SwFormTokens aPattern = aForm.GetPattern(nLevel);
3239  if ( bIsHyperlink )
3240  {
3241  aPattern.insert(aPattern.begin(), aLinkStart);
3242  }
3243  else
3244  {
3245  auto aItr = std::find_if(aPattern.begin(), aPattern.end(),
3246  [](const SwFormToken& rToken) { return rToken.eTokenType == TOKEN_PAGE_NUMS; });
3247  if (aItr != aPattern.end())
3248  aPattern.insert(aItr, aLinkStart);
3249  }
3250  aPattern.push_back(aLinkEnd);
3251  aForm.SetPattern(nLevel, aPattern);
3252  }
3253  pBase->SetTOXForm(aForm);
3254 
3255  if (!nMaxLevel)
3256  nMaxLevel = WW8ListManager::nMaxLevel;
3257  pBase->SetLevel(nMaxLevel);
3258 
3259  const TOXTypes eType = pBase->GetTOXType()->GetType();
3260  switch( eType )
3261  {
3262  case TOX_CONTENT:
3263  {
3264  //If we would be created from outlines, either explicitly or by default
3265  //then see if we need extra styles added to the outlines
3266  SwTOXElement eEffectivelyFrom = eCreateFrom != SwTOXElement::NONE ? eCreateFrom : SwTOXElement::OutlineLevel;
3267  if (eEffectivelyFrom & SwTOXElement::OutlineLevel)
3268  {
3269  // #i19683# Insert a text token " " between the number and entry token.
3270  // In an ideal world we could handle the tab stop between the number and
3271  // the entry correctly, but I currently have no clue how to obtain
3272  // the tab stop position. It is _not_ set at the paragraph style.
3273  std::unique_ptr<SwForm> pForm;
3274  for (SwWW8StyInf & rSI : m_vColl)
3275  {
3276  if (rSI.IsOutlineNumbered())
3277  {
3278  sal_uInt16 nStyleLevel = rSI.mnWW8OutlineLevel;
3279  const SwNumFormat& rFormat = rSI.GetOutlineNumrule()->Get( nStyleLevel );
3280  if ( SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType() )
3281  {
3282  ++nStyleLevel;
3283 
3284  if ( !pForm )
3285  pForm.reset(new SwForm( pBase->GetTOXForm() ));
3286 
3287  SwFormTokens aPattern = pForm->GetPattern(nStyleLevel);
3288  SwFormTokens::iterator aIt =
3289  find_if(aPattern.begin(), aPattern.end(),
3291 
3292  if ( aIt != aPattern.end() )
3293  {
3294  SwFormToken aNumberEntrySeparator( TOKEN_TEXT );
3295  aNumberEntrySeparator.sText = " ";
3296  aPattern.insert( ++aIt, aNumberEntrySeparator );
3297  pForm->SetPattern( nStyleLevel, aPattern );
3298  }
3299  }
3300  }
3301  }
3302  if ( pForm )
3303  {
3304  pBase->SetTOXForm( *pForm );
3305  }
3306  }
3307 
3308  if (eCreateFrom != SwTOXElement::NONE)
3309  pBase->SetCreate(eCreateFrom);
3311  }
3312  break;
3313  case TOX_ILLUSTRATIONS:
3314  {
3315  if( eCreateFrom == SwTOXElement::NONE )
3316  eCreateFrom = SwTOXElement::Sequence;
3317  pBase->SetCreate( eCreateFrom );
3318 
3319  /*
3320  We don't know until here if we are an illustration
3321  or not, and so have being used a TOX_CONTENT so far
3322  which has 10 levels, while TOX has only two, this
3323  level is set only in the constructor of SwForm, so
3324  create a new one and copy over anything that could
3325  be set in the old one, and remove entries from the
3326  pattern which do not apply to illustration indices
3327  */
3328  SwForm aOldForm( pBase->GetTOXForm() );
3329  SwForm aNewForm( eType );
3330  sal_uInt16 nNewEnd = aNewForm.GetFormMax()-1;
3331 
3332  // #i21237#
3333  for(sal_uInt16 nLevel = 1; nLevel <= nNewEnd; ++nLevel)
3334  {
3335  SwFormTokens aPattern = aOldForm.GetPattern(nLevel);
3336  SwFormTokens::iterator new_end =
3337  remove_if(aPattern.begin(), aPattern.end(), SwFormTokenEqualToFormTokenType(TOKEN_ENTRY_NO));
3338  aPattern.erase(new_end, aPattern.end() ); // table index imported with wrong page number format
3339  aForm.SetPattern( nLevel, aPattern );
3340  aForm.SetTemplate( nLevel, aOldForm.GetTemplate(nLevel) );
3341  }
3342 
3343  pBase->SetTOXForm( aNewForm );
3344  }
3345  break;
3346  default:
3347  OSL_ENSURE(false, "Unhandled toc options!");
3348  break;
3349  }
3350  }
3351  break;
3352  case TOX_USER:
3353  break;
3354  default:
3355  OSL_ENSURE(false, "Unhandled toc options!");
3356  break;
3357  } // ToxBase fertig
3358 
3359  // #i21237# - propagate tab stops from paragraph styles used in TOX to patterns of the TOX
3360  pBase->AdjustTabStops( m_rDoc );
3361 
3362  //#i10028# inserting a toc implicitly acts like a parabreak in word and writer
3363  if ( m_pPaM->End() &&
3364  m_pPaM->End()->nNode.GetNode().GetTextNode() &&
3365  m_pPaM->End()->nNode.GetNode().GetTextNode()->Len() != 0 )
3366  {
3367  m_bCareFirstParaEndInToc = true;
3368  }
3369 
3370  if (m_pPaM->GetPoint()->nContent.GetIndex())
3372 
3373  const SwPosition* pPos = m_pPaM->GetPoint();
3374 
3375  SwFltTOX aFltTOX( pBase );
3376 
3377  // test if there is already a break item on this node
3378  if(SwContentNode* pNd = pPos->nNode.GetNode().GetContentNode())
3379  {
3380  const SfxItemSet* pSet = pNd->GetpSwAttrSet();
3381  if( pSet )
3382  {
3383  if (SfxItemState::SET == pSet->GetItemState(RES_BREAK, false))
3384  aFltTOX.SetHadBreakItem(true);
3385  if (SfxItemState::SET == pSet->GetItemState(RES_PAGEDESC, false))
3386  aFltTOX.SetHadPageDescItem(true);
3387  }
3388  }
3389 
3390  //Will there be a new pagebreak at this position (don't know what type
3391  //until later)
3393  aFltTOX.SetHadPageDescItem(true);
3394 
3395  // Set start in stack
3396  m_xReffedStck->NewAttr( *pPos, aFltTOX );
3397 
3398  m_rDoc.InsertTableOf(*m_pPaM->GetPoint(), aFltTOX.GetBase());
3399 
3400  //The TOC field representation contents should be inserted into TOC section, but not after TOC section.
3401  //So we need update the document position when loading TOC representation and after loading TOC;
3402  m_pPosAfterTOC.reset(new SwPaM(*m_pPaM, m_pPaM));
3403  (*m_pPaM).Move(fnMoveBackward);
3404  SwPaM aRegion(*m_pPaM, m_pPaM);
3405 
3406  OSL_ENSURE(SwDoc::GetCurTOX(*aRegion.GetPoint()), "Misunderstood how toc works");
3407  if (SwTOXBase* pBase2 = SwDoc::GetCurTOX(*aRegion.GetPoint()))
3408  {
3409  pBase2->SetMSTOCExpression(rStr);
3410 
3411  if ( nIndexCols > 1 )
3412  {
3413  // Set the column number for index
3415  SwFormatCol aCol;
3416  aCol.Init( nIndexCols, 708, USHRT_MAX );
3417  aSet.Put( aCol );
3418  pBase2->SetAttrSet( aSet );
3419  }
3420 
3421  // inserting a toc inserts a section before this point, so adjust pos
3422  // for future page/section segment insertion
3423  m_aSectionManager.PrependedInlineNode( *m_pPosAfterTOC->GetPoint(), aRegion.GetNode() );
3424  }
3425 
3426  // Set end in stack
3427  m_xReffedStck->SetAttr( *pPos, RES_FLTR_TOX );
3428 
3429  if (!m_aApos.back()) //a para end in apo doesn't count
3430  m_bWasParaEnd = true;
3431 
3432  //Return FLD_TEXT, instead of FLD_OK
3433  //FLD_TEXT means the following content, commonly indicate the field representation content should be parsed
3434  //FLD_OK means the current field loading is finished. The rest part should be ignored.
3435  return eF_ResT::TEXT;
3436 }
3437 
3439 {
3440  /*
3441  #i3958# 0x8 followed by 0x1 where the shape is the 0x8 and its anchoring
3442  to be ignored followed by a 0x1 with an empty drawing. Detect in inserting
3443  the drawing that we are in the Shape field and respond accordingly
3444  */
3445  return eF_ResT::TEXT;
3446  }
3447 
3449 {
3450  OUString sURL, sTarget, sMark;
3451 
3452  //HYPERLINK "filename" [switches]
3453  rStr = comphelper::string::stripEnd(rStr, 1);
3454 
3455  bool bOptions = false;
3456  WW8ReadFieldParams aReadParam( rStr );
3457  for (;;)
3458  {
3459  const sal_Int32 nRet = aReadParam.SkipToNextToken();
3460  if ( nRet==-1 )
3461  break;
3462  switch( nRet )
3463  {
3464  case -2:
3465  if (sURL.isEmpty() && !bOptions)
3466  sURL = ConvertFFileName(aReadParam.GetResult());
3467  break;
3468 
3469  case 'n':
3470  sTarget = "_blank";
3471  bOptions = true;
3472  break;
3473 
3474  case 'l':
3475  bOptions = true;
3476  if ( aReadParam.SkipToNextToken()==-2 )
3477  {
3478  sMark = aReadParam.GetResult();
3479  if( sMark.endsWith("\""))
3480  {
3481  sMark = sMark.copy( 0, sMark.getLength() - 1 );
3482  }
3483  // #120879# add cross reference bookmark name prefix, if it matches internal TOC bookmark naming convention
3484  if ( IsTOCBookmarkName( sMark ) )
3485  {
3486  sMark = EnsureTOCBookmarkName(sMark);
3487  // track <sMark> as referenced TOC bookmark.
3488  m_xReffedStck->aReferencedTOCBookmarks.insert( sMark );
3489  }
3490 
3491  if (m_bLoadingTOXCache)
3492  {
3493  m_bLoadingTOXHyperlink = true; //on loading a TOC field nested hyperlink field
3494  }
3495  }
3496  break;
3497  case 't':
3498  bOptions = true;
3499  if ( aReadParam.SkipToNextToken()==-2 )
3500  sTarget = aReadParam.GetResult();
3501  break;
3502  case 'h':
3503  case 'm':
3504  OSL_ENSURE( false, "Analysis still missing - unknown data" );
3505  [[fallthrough]];
3506  case 's': //worthless fake anchor option
3507  bOptions = true;
3508  break;
3509  }
3510  }
3511 
3512  // use the result
3513  OSL_ENSURE(!sURL.isEmpty() || !sMark.isEmpty(), "WW8: Empty URL");
3514 
3515  if( !sMark.isEmpty() )
3516  sURL = sURL + "#" + sMark;
3517 
3518  SwFormatINetFormat aURL(sURL, sTarget);
3519  // If on loading TOC field, change the default style into the "index link"
3520  if (m_bLoadingTOXCache)
3521  {
3522  OUString sLinkStyle("Index Link");
3523  sal_uInt16 nPoolId =
3525  aURL.SetVisitedFormatAndId( sLinkStyle, nPoolId );
3526  aURL.SetINetFormatAndId( sLinkStyle, nPoolId );
3527  }
3528 
3529  //As an attribute this needs to be closed, and that'll happen from
3530  //EndExtSprm in conjunction with the maFieldStack. If there are flyfrms
3531  //between the start and begin, their hyperlinks will be set at that time
3532  //as well.
3533  m_xCtrlStck->NewAttr( *m_pPaM->GetPoint(), aURL );
3534  return eF_ResT::TEXT;
3535 }
3536 
3537 static void lcl_ImportTox(SwDoc &rDoc, SwPaM const &rPaM, const OUString &rStr, bool bIdx)
3538 {
3539  TOXTypes eTox = ( !bIdx ) ? TOX_CONTENT : TOX_INDEX; // Default
3540 
3541  sal_uInt16 nLevel = 1;
3542 
3543  OUString sFieldText;
3544  WW8ReadFieldParams aReadParam(rStr);
3545  for (;;)
3546  {
3547  const sal_Int32 nRet = aReadParam.SkipToNextToken();
3548  if ( nRet==-1 )
3549  break;
3550  switch( nRet )
3551  {
3552  case -2:
3553  if( sFieldText.isEmpty() )
3554  {
3555  // PrimaryKey without ":", 2nd after
3556  sFieldText = aReadParam.GetResult();
3557  }
3558  break;
3559 
3560  case 'f':
3561  if ( aReadParam.GoToTokenParam() )
3562  {
3563  const OUString sParams( aReadParam.GetResult() );
3564  if( sParams[0]!='C' && sParams[0]!='c' )
3565  eTox = TOX_USER;
3566  }
3567  break;
3568 
3569  case 'l':
3570  if ( aReadParam.GoToTokenParam() )
3571  {
3572  const OUString sParams( aReadParam.GetResult() );
3573  // if NO String just ignore the \l
3574  if( !sParams.isEmpty() && sParams[0]>'0' && sParams[0]<='9' )
3575  {
3576  nLevel = static_cast<sal_uInt16>(sParams.toInt32());
3577  }
3578  }
3579  break;
3580  }
3581  }
3582 
3583  OSL_ENSURE( rDoc.GetTOXTypeCount( eTox ), "Doc.GetTOXTypeCount() == 0 :-(" );
3584 
3585  const SwTOXType* pT = rDoc.GetTOXType( eTox, 0 );
3586  SwTOXMark aM( pT );
3587 
3588  if( eTox != TOX_INDEX )
3589  aM.SetLevel( nLevel );
3590  else
3591  {
3592  sal_Int32 nFnd = sFieldText.indexOf( WW8_TOX_LEVEL_DELIM );
3593  if( -1 != nFnd ) // it exist levels
3594  {
3595  aM.SetPrimaryKey( sFieldText.copy( 0, nFnd ) );
3596  sal_Int32 nScndFnd = sFieldText.indexOf( WW8_TOX_LEVEL_DELIM, nFnd+1 );
3597  if( -1 != nScndFnd )
3598  {
3599  aM.SetSecondaryKey( sFieldText.copy( nFnd+1, nScndFnd - nFnd - 1 ));
3600  nFnd = nScndFnd;
3601  }
3602  sFieldText = sFieldText.copy( nFnd+1 );
3603  }
3604  }
3605 
3606  if (!sFieldText.isEmpty())
3607  {
3608  aM.SetAlternativeText( sFieldText );
3609  rDoc.getIDocumentContentOperations().InsertPoolItem( rPaM, aM );
3610  }
3611 }
3612 
3613 void SwWW8ImplReader::ImportTox( int nFieldId, const OUString& aStr )
3614 {
3615  bool bIdx = (nFieldId != 9);
3616  lcl_ImportTox(m_rDoc, *m_pPaM, aStr, bIdx);
3617 }
3618 
3619 void SwWW8ImplReader::Read_FieldVanish( sal_uInt16, const sal_uInt8*, short nLen )
3620 {
3621  //Meaningless in a style
3622  if (m_pCurrentColl || !m_xPlcxMan)
3623  return;
3624 
3625  const int nChunk = 64; //number of characters to read at one time
3626 
3627  // Careful: MEMICMP doesn't work with fieldnames including umlauts!
3628  const static sal_Char *aFieldNames[] = { "\x06""INHALT", "\x02""XE", // dt.
3629  "\x02""TC" }; // us
3630  const static sal_uInt8 aFieldId[] = { 9, 4, 9 };
3631 
3632  if( nLen < 0 )
3633  {
3634  m_bIgnoreText = false;
3635  return;
3636  }
3637 
3638  // our method was called from
3639  // ''Skip attributes of field contents'' loop within ReadTextAttr()
3640  if( m_bIgnoreText )
3641  return;
3642 
3643  m_bIgnoreText = true;
3644  long nOldPos = m_pStrm->Tell();
3645 
3646  WW8_CP nStartCp = m_xPlcxMan->Where() + m_xPlcxMan->GetCpOfs();
3647 
3648  OUString sFieldName;
3649  sal_Int32 nFieldLen = m_xSBase->WW8ReadString( *m_pStrm, sFieldName, nStartCp,
3650  nChunk, m_eStructCharSet );
3651  nStartCp+=nFieldLen;
3652 
3653  sal_Int32 nC = 0;
3654  //If the first chunk did not start with a field start then
3655  //reset the stream position and give up
3656  if( !nFieldLen || sFieldName[nC]!=0x13 ) // Field Start Mark
3657  {
3658  // If Field End Mark found
3659  if( nFieldLen && sFieldName[nC]==0x15 )
3660  m_bIgnoreText = false;
3661  m_pStrm->Seek( nOldPos );
3662  return; // no field found
3663  }
3664 
3665  sal_Int32 nFnd;
3666  //If this chunk does not contain a field end, keep reading chunks
3667  //until we find one, or we run out of text,
3668  for (;;)
3669  {
3670  nFnd = sFieldName.indexOf(0x15);
3671  //found field end, we can stop now
3672  if (nFnd != -1)
3673  break;
3674  OUString sTemp;
3675  nFieldLen = m_xSBase->WW8ReadString( *m_pStrm, sTemp,
3676  nStartCp, nChunk, m_eStructCharSet );
3677  sFieldName+=sTemp;
3678  nStartCp+=nFieldLen;
3679  if (!nFieldLen)
3680  break;
3681  }
3682 
3683  m_pStrm->Seek( nOldPos );
3684 
3685  //if we have no 0x15 give up, otherwise erase everything from the 0x15
3686  //onwards
3687  if (nFnd<0)
3688  return;
3689 
3690  sFieldName = sFieldName.copy(0, nFnd);
3691 
3692  nC++;
3693  while ( sFieldName[nC]==' ' )
3694  nC++;
3695 
3696  for( int i = 0; i < 3; i++ )
3697  {
3698  const sal_Char* pName = aFieldNames[i];
3699  const sal_Int32 nNameLen = static_cast<sal_Int32>(*pName++);
3700  if( sFieldName.matchIgnoreAsciiCaseAsciiL( pName, nNameLen, nC ) )
3701  {
3702  ImportTox( aFieldId[i], sFieldName.copy( nC + nNameLen ) );
3703  break; // no duplicates allowed
3704  }
3705  }
3706  m_bIgnoreText = true;
3707  m_pStrm->Seek( nOldPos );
3708 }
3709 
3710 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
eF_ResT Read_F_Set(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1967
virtual void SetSubType(sal_uInt16 nType) override
Definition: expfld.cxx:894
SvxNumType GetNumberingType() const
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:233
void InsertTagField(const sal_uInt16 nId, const OUString &rTagText)
Definition: ww8par5.cxx:1107
bool is() const
const SwDocInfoSubType DI_SUB_TIME
Definition: docufld.hxx:79
std::vector< SwFormToken > SwFormTokens
Vector of tokens.
Definition: tox.hxx:249
TOXTypes
Definition: toxe.hxx:39
Iterator for Booknotes.
Definition: ww8scan.hxx:743
std::unique_ptr< SwWW8FltControlStack > m_xCtrlStck
Definition: ww8par.hxx:1097
SVX_NUM_CHARS_UPPER_LETTER_N
bool bCodeNest
instruction used recursively
Definition: ww8scan.hxx:197
sal_uLong GetIndex() const
Definition: node.hxx:282
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
SwTOIOptions
Definition: tox.hxx:350
OString stripEnd(const OString &rIn, sal_Char c)
Handles the import of PlcfAtnBkf and PlcfAtnBkl: start / end position of annotation marks...
Definition: ww8scan.hxx:782
std::map< OUString, css::uno::Any > parameter_map_t
Definition: IMark.hxx:94
Marks a position in the document model.
Definition: pam.hxx:35
rtl_TextEncoding m_eStructCharSet
Definition: ww8par.hxx:1284
void Read_FieldVanish(sal_uInt16 nId, const sal_uInt8 *pData, short nLen)
Definition: ww8par5.cxx:3619
bool m_bLoadingTOXCache
Definition: ww8par.hxx:1361
SwTOXElement GetCreateType() const
Definition: tox.hxx:671
Size & Swap(Size &rSize)
eF_ResT Read_F_DateTime(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1750
static bool AcceptableNestedField(sal_uInt16 nFieldCode)
Definition: ww8par5.cxx:697
SwFlyFrameFormat * m_pFlyFormatOfJustInsertedGraphic
Definition: ww8par.hxx:1198
#define ODF_OLE_PARAM
long Read_Book(WW8PLCFManResult *)
Definition: ww8par5.cxx:126
#define RES_CHRATR_FONTSIZE
Definition: hintids.hxx:76
"Page"
Definition: reffld.hxx:48
eF_ResT Read_F_Num(WW8FieldDesc *pF, OUString &)
Definition: ww8par5.cxx:1843
sal_uInt16 End_Field()
Definition: ww8par5.cxx:509
void SetLinkFileName(OUString const &rNew)
Definition: section.hxx:118
#define RES_CHRATR_LANGUAGE
Definition: hintids.hxx:78
#define RES_TXTATR_CJK_RUBY
Definition: hintids.hxx:143
#define LANGUAGE_ENGLISH_US
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
Definition: docfmt.cxx:867
WW8_CP nSCode
start of instructions code
Definition: ww8scan.hxx:191
virtual SwFlyFrameFormat * InsertGraphic(const SwPaM &rRg, const OUString &rGrfName, const OUString &rFltName, const Graphic *pGraphic, const SfxItemSet *pFlyAttrSet, const SfxItemSet *pGrfAttrSet, SwFrameFormat *)=0
Insert graphic or formula.
const SwExtendedSubType SUB_INVISIBLE
Invisible.
Definition: fldbas.hxx:205
sal_uLong MSDateTimeFormatToSwFormat(OUString &rParams, SvNumberFormatter *pFormatter, LanguageType &rLang, bool bHijri, LanguageType nDocLang)
Convert from Word Date/Time field str to Writer's Date Time str.
void SetBookmarkType(const OUString &bookmarkType)
Definition: ww8par5.cxx:745
static void FillUIName(const OUString &rName, OUString &rFillName, SwGetPoolIdFromName)
void SetLevel(sal_uInt16 nLevel)
Definition: tox.hxx:562
sal_uInt32 GetFormatIndex(NfIndexTableOffset, LanguageType eLnge=LANGUAGE_DONTKNOW)
static SwTOXBase * GetCurTOX(const SwPosition &rPos)
Get current table of contents.
Definition: doctxm.cxx:449
Definition: tox.hxx:276
SwNodeIndex nNode
Definition: pam.hxx:37
bool EndPosIsFieldEnd(WW8_CP &)
Definition: ww8scan.cxx:4031
void SetPromptText(const OUString &rStr)
Definition: expfld.hxx:256
eF_ResT Read_F_InputVar(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1333
eF_ResT Read_F_Author(WW8FieldDesc *, OUString &)
Definition: ww8par5.cxx:1731
#define WW8_TOX_LEVEL_DELIM
Definition: ww8par5.cxx:96
SVX_NUM_NUMBER_NONE
ErrCode GetError() const
void SetAdjustment(css::text::RubyAdjust nNew)
Definition: fmtruby.hxx:74
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:284
sal_uIntPtr sal_uLong
FAMILY_DONTKNOW
css::uno::Any getPropertyValue(const OUString &rPropertyName)
wwFrameNamer m_aGrfNameGenerator
Definition: ww8par.hxx:1177
const sal_Unicode cTokenSeparator
Base class of all fields.
Definition: fldbas.hxx:279
void MakeTagString(OUString &rStr, const OUString &rOrg)
Definition: ww8par5.cxx:1039
#define TOX_STYLE_DELIMITER
Definition: tox.hxx:386
#define RES_FRMATR_END
Definition: hintids.hxx:236
#define RES_FLTR_BOOKMARK
Definition: hintids.hxx:321
long MapBookmarkVariables(const WW8FieldDesc *pF, OUString &rOrigName, const OUString &rData)
Definition: ww8par5.cxx:1254
Provides access to the marks of a document.
Definition: doc.hxx:185
eBookStatus
Definition: ww8scan.hxx:740
OUString GetUniqueSectionName(const OUString *pChkStr=nullptr) const
Definition: ndsect.cxx:1356
SvNumFormatType GetType(sal_uInt32 nFIndex) const
static SotStorage * OpenOLEStorage(css::uno::Reference< css::embed::XStorage > const &xStorage, OUString const &rEleName, StreamMode=StreamMode::STD_READWRITE)
#define ODF_CODE_PARAM
sal_uInt64 Seek(sal_uInt64 nPos)
#define RES_CHRATR_FONT
Definition: hintids.hxx:75
void ConvertLanguage(SvNumberFormatter &rConverter, LanguageType eConvertFrom, LanguageType eConvertTo)
const SwDocInfoSubType DI_COMMENT
Definition: docufld.hxx:69
SwNode & GetNode() const
Definition: ndindex.hxx:118
std::unique_ptr< SwPaM > m_pPosAfterTOC
Definition: ww8par.hxx:1366
long Read_AtnBook(WW8PLCFManResult *)
Definition: ww8par5.cxx:242
WW8_CP nLen
total length (to skip over text)
Definition: ww8scan.hxx:190
static void EnsureMaxLevelForTemplates(SwTOXBase &rBase)
Definition: ww8par5.cxx:2795
static OUString FindPara(const OUString &rStr, sal_Unicode cToken, sal_Unicode cToken2)
Definition: ww8par5.cxx:340
SwSectionFormat * GetFormat()
Definition: section.hxx:337
REFERENCEMARK
Definition: reffld.hxx:45
long GetLen() const
Definition: ww8scan.cxx:4375
sal_uInt16 GetFormMax() const
Definition: tox.hxx:653
void SetLevel(sal_uInt8)
Definition: chpfld.cxx:80
bool StartPosIsFieldStart()
Definition: ww8scan.cxx:4024
virtual sal_uInt16 GetSubType() const override
Definition: expfld.cxx:902
eF_ResT Read_F_Macro(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:2234
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:347
void SetOptions(SwTOIOptions nOpt)
Definition: tox.hxx:716
const OUString & GetFormatstring() const
eF_ResT Read_F_Shape(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par5.cxx:3438
bool Commit()
static void ParseIfFieldDefinition(const OUString &aFieldDefinition, OUString &rCondition, OUString &rTrue, OUString &rFalse)
Definition: docufld.cxx:1539
eF_ResT Read_F_Seq(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1403
#define MAX_FIELDLEN
Definition: ww8par5.cxx:94
SvxNumType
static LanguageType nLang
Definition: srtdlg.cxx:58
#define RES_FLTR_ANNOTATIONMARK
Definition: hintids.hxx:326
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
void SetCharFormatName(const OUString &rNm)
Definition: fmtruby.hxx:65
virtual OUString GetPar1() const
Definition: fldbas.cxx:271
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:389
void SetCreate(SwTOXElement)
Definition: tox.hxx:689
sal_uInt16 sal_Unicode
Stores RDF statements on a paragraph (key-value pairs where the subject is the paragraph).
Definition: fltshell.hxx:264
static SW_DLLPUBLIC OUString GetCrossRefHeadingBookmarkNamePrefix()
Definition: docbm.cxx:517
const SwTOXType * GetTOXType() const
Definition: tox.hxx:668
const SwCharFormat * GetDfltCharFormat() const
Definition: doc.hxx:747
SwTOXBaseSection * InsertTableOf(const SwPosition &rPos, const SwTOXBase &rTOX, const SfxItemSet *pSet=nullptr, bool bExpand=false, SwRootFrame const *pLayout=nullptr)
Definition: doctxm.cxx:348
void AdjustTabStops(SwDoc const &rDoc)
Definition: tox.hxx:522
SotStorage * OpenSotStorage(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE, bool transacted=true)
FUNC_TYPE const nType
SwIndex nContent
Definition: pam.hxx:38
void RegisterToTOXType(SwTOXType &rMark)
Definition: tox.cxx:539
Handles the import of PlcfBkfFactoid and PlcfBklFactoid: start / end position of factoids.
Definition: ww8scan.hxx:812
std::unique_ptr< SwWW8ReferencedFltEndStack > m_xReffedStck
Definition: ww8par.hxx:1111
std::vector< SwWW8StyInf > m_vColl
Definition: ww8par.hxx:1234
SwSectionNode * GetSectionNode()
Definition: section.cxx:1007
"Number (full context)"
Definition: reffld.hxx:60
char sal_Char
void SetFieldCode(const OUString &rStr)
access to the command string
Definition: dbfld.hxx:102
OUString sText
Definition: tox.hxx:208
const OUString & GetName() const
Definition: format.hxx:111
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:34
eF_ResT Read_F_DBNum(WW8FieldDesc *, OUString &)
Definition: ww8par5.cxx:2567
SvStream * m_pStrm
Definition: ww8par.hxx:1088
SVX_NUM_ARABIC
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
bool CopyTo(SotStorage *pDestStg)
SVX_NUM_ROMAN_UPPER
virtual void SetValue(const double &rVal) override
Definition: expfld.cxx:907
SwSection * InsertSwSection(SwPaM const &rRange, SwSectionData &, std::pair< SwTOXBase const *, sw::RedlineMode > const *pTOXBase, SfxItemSet const *const pAttr, bool const bUpdate=true)
Definition: ndsect.cxx:154
sal_uInt16 GetTOXTypeCount(TOXTypes eTyp) const
Manage table of content types.
Definition: doctxm.cxx:612
SVX_NUM_ROMAN_LOWER
virtual parameter_map_t * GetParameters()=0
"Category and Number"
Definition: reffld.hxx:53
void SetAutomaticLanguage(bool const bSet)
Definition: fldbas.hxx:372
void SetBookmarkCode(const OUString &bookmarkCode)
Definition: ww8par5.cxx:750
eF_ResT Read_F_IncludeText(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:2445
const SwDoc & mrDoc
Definition: ww8par.hxx:948
Iterator for fields.
Definition: ww8scan.hxx:718
eF_ResT
Definition: ww8par.hxx:622
void SetUniqueGraphName(SwFrameFormat *pFrameFormat, const OUString &rFixedPart)
Definition: ww8graf.cxx:181
void SetAlternativeText(const OUString &rAlt)
Definition: tox.hxx:548
bool m_bLoadingTOXHyperlink
Definition: ww8par.hxx:1364
#define RES_FLTR_TOX
Definition: hintids.hxx:324
void SetHadPageDescItem(bool bVal)
Definition: fltshell.hxx:293
if(nullptr==pCandidateA||nullptr==pCandidateB)
SwFltStackEntry * RefToVar(const SwField *pField, SwFltStackEntry &rEntry)
Definition: ww8par5.cxx:1294
eF_ResT Read_F_PgRef(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:2136
sal_uInt16 GetPoolFormatId() const
Get and set Pool style IDs.
Definition: format.hxx:143
void Swap(WW8FieldEntry &rOther)
Definition: ww8par5.cxx:726
Base class for various Writer styles.
Definition: format.hxx:43
#define SAL_N_ELEMENTS(arr)
const SwDocInfoSubType DI_CUSTOM
Definition: docufld.hxx:75
WW8_CP nLCode
length
Definition: ww8scan.hxx:192
void SetHadBreakItem(bool bVal)
Definition: fltshell.hxx:292
WW8_CP Read_F_Tag(WW8FieldDesc *pF)
Definition: ww8par5.cxx:1132
void SetVisitedFormatAndId(const OUString &rNm, const sal_uInt16 nId)
Definition: fmtinfmt.hxx:112
void SetFormula(const OUString &rStr)
Definition: fldbas.cxx:701
void Read_SubF_Ruby(msfilter::util::WW8ReadFieldParams &rReadParam)
Definition: ww8par5.cxx:2615
long Read_FactoidBook(WW8PLCFManResult *)
Definition: ww8par5.cxx:254
eF_ResT Read_F_FormCheckBox(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:182
eF_ResT Read_F_DBField(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:2513
const char aObjectPool[]
Definition: ww8scan.hxx:44
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void PrependedInlineNode(const SwPosition &rPos, const SwNode &rNode)
Definition: ww8par2.cxx:2382
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:483
const SwDocInfoSubType DI_PRINT
Definition: docufld.hxx:72
eF_ResT Read_F_TemplName(WW8FieldDesc *, OUString &)
Definition: ww8par5.cxx:1741
bool CurrentSectionIsProtected() const
Definition: ww8par2.cxx:140
T * get() const
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
bool bResNest
instruction inserted into result
Definition: ww8scan.hxx:198
eF_ResT Read_F_Symbol(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1868
static SvtFilterOptions & Get()
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
wwSectionManager m_aSectionManager
Definition: ww8par.hxx:1149
SwFileNameFormat
Definition: fldbas.hxx:145
SwDoc & m_rDoc
Definition: ww8par.hxx:1093
NF_TIME_START
void SetPrimaryKey(const OUString &rStr)
Definition: tox.hxx:568
bool PutandConvertEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge, LanguageType eNewLnge, bool bConvertDateOrder)
SwTOXElement
Definition: tox.hxx:328
const SwPosition * GetPoint() const
Definition: pam.hxx:207
std::unique_ptr< WW8ScannerBase > m_xSBase
Definition: ww8par.hxx:1222
EquationResult ParseCombinedChars(const OUString &rStr)
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
eF_ResT Read_F_FileName(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1813
OUString sCharStyleName
Definition: tox.hxx:209
#define LANGUAGE_SYSTEM
const SwDocInfoSubType DI_KEYS
Definition: docufld.hxx:68
OUString sName
bool SwFltGetFlag(sal_uLong nFieldFlags, int no)
Definition: fltshell.hxx:42
void Exchange()
Definition: pam.cxx:471
int i
SwContentNode * GetContentNode()
Definition: node.hxx:615
const SwDocInfoSubType DI_CREATE
Definition: docufld.hxx:70
void SetSequenceName(const OUString &rSet)
Definition: tox.hxx:506
FlyAnchors.
Definition: fmtanchr.hxx:34
rtl_TextEncoding m_eTextCharSet
Definition: ww8par.hxx:1283
void SetCaptionDisplay(SwCaptionDisplay eSet)
Definition: tox.hxx:509
void NewAttr(const SfxPoolItem &rAttr, const bool bFirstLineOfStSet=false, const bool bLeftIndentSet=false)
Definition: ww8par6.cxx:2741
void AppendTextNode(SwPosition &rPos)
Definition: ww8par.cxx:2401
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
bool ForceFieldLanguage(SwField &rField, LanguageType nLang)
Definition: ww8par5.cxx:395
#define RES_CHRATR_BEGIN
Definition: hintids.hxx:68
WW8_CP GetStartPos() const
Definition: ww8scan.hxx:769
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:195
new reference format types for referencing bookmarks and set references
Definition: reffld.hxx:58
eF_ResT Read_F_Embedd(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1940
eF_ResT Read_F_Ref(WW8FieldDesc *pF, OUString &)
Definition: ww8par5.cxx:2003
static sal_Int32 FindParaStart(const OUString &rStr, sal_Unicode cToken, sal_Unicode cToken2)
Definition: ww8par5.cxx:311
#define RES_FLTR_RDFMARK
Definition: hintids.hxx:327
eF_ResT Read_F_FormTextBox(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:90
PITCH_DONTKNOW
void ImportTox(int nFieldId, const OUString &aStr)
Definition: ww8par5.cxx:3613
SvNumFormatType
const sal_uInt8 * pSprm
Definition: ww8scan.hxx:95
eF_ResT Read_F_Tox(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par5.cxx:2920
const SwDocInfoSubType DI_SUB_DATE
Definition: docufld.hxx:80
void UpdateFields()
Definition: ww8par5.cxx:503
Marks a node in the document model.
Definition: ndindex.hxx:31
sal_uInt16 sal_Char * pName
GUIDCNamePair const aData
void SetBookmarkName(const OUString &bookmarkName)
Definition: ww8par5.cxx:740
FontPitch
DocumentType const eType
sal_uInt16 GetLevel() const
Definition: tox.hxx:704
eF_ResT Read_F_FormListBox(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:241
void InitContent()
Evaluation for header and footer.
Definition: dbfld.cxx:190
#define RES_TXTATR_INETFMT
Definition: hintids.hxx:141
SVX_NUM_CHARS_LOWER_LETTER_N
std::deque< bool > m_aApos
Definition: ww8par.hxx:1204
const OUString * GetName() const
Definition: ww8scan.cxx:4499
WW8PostProcessAttrsInfo(WW8_CP nCpStart, WW8_CP nCpEnd, SwPaM &rPaM)
Definition: ww8par5.cxx:2326
sal_Int32 WW8_CP
Definition: ww8struc.hxx:153
const SwTOXBase & GetBase()
Definition: fltshell.hxx:291
eBookStatus GetStatus() const
Definition: ww8scan.cxx:4403
int m_nEmbeddedTOXLevel
Definition: ww8par.hxx:1362
void SetTOXForm(const SwForm &rForm)
Definition: tox.hxx:692
WW8_CP nLRes
length ( == 0, if no result )
Definition: ww8scan.hxx:194
static bool ConvertMacroSymbol(const OUString &rName, OUString &rReference)
Definition: ww8par5.cxx:2210
const SwDocInfoSubType DI_SUB_AUTHOR
Definition: docufld.hxx:78
std::vector< const SwCharFormat * > m_aRubyCharFormats
Definition: ww8par.hxx:1209
bool m_bCareFirstParaEndInToc
Definition: ww8par.hxx:1372
OUString ConvertFFileName(const OUString &rRaw)
translate FieldParameter names into the system character set and at the same time, double backslashes are converted into single ones
Definition: ww8par5.cxx:275
NF_DATE_START
FontFamily
const OUString & GetFamilyName() const
#define ODF_UNHANDLED
std::unique_ptr< SfxPoolItem > pAttr
Definition: fltshell.hxx:88
OUString GetFieldResult(WW8FieldDesc const *pF)
Definition: ww8par5.cxx:1192
const SwFormat * GetStyleWithOrgWWName(OUString const &rName) const
Definition: ww8par2.cxx:3581
long GetHandle() const
Definition: ww8scan.cxx:4411
SVX_NUM_PAGEDESC
"Reference"
Definition: reffld.hxx:50
#define RES_TXTATR_FIELD
Definition: hintids.hxx:150
const SwGetSetExpType GSE_SEQ
Sequence.
Definition: fldbas.hxx:197
OUString UniqueName()
Definition: ww8par5.cxx:2438
sal_uInt32 GetHeight() const
static OUString GetWordDefaultDateStringAsUS(SvNumberFormatter *pFormatter, LanguageType nLang)
Definition: ww8par5.cxx:414
OUString BookmarkToWriter(const OUString &rBookmark)
Definition: wrtw8nds.cxx:1184
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:202
SvNumFormatType GetTimeDatePara(OUString const &rStr, sal_uInt32 &rFormat, LanguageType &rLang, int nWhichDefault, bool bHijri=false)
Definition: ww8par5.cxx:436
sal_Int32 FindNextStringPiece(sal_Int32 _nStart=-1)
virtual void SetLanguage(LanguageType nLng)
Definition: fldbas.cxx:370
void SetHandle(long nHandle)
Definition: fltshell.cxx:1063
eF_ResT Read_F_DBNext(WW8FieldDesc *, OUString &)
Definition: ww8par5.cxx:2554
#define RES_CHRATR_CTL_LANGUAGE
Definition: hintids.hxx:97
unsigned char sal_uInt8
sal_uInt16 nId
WW-id for fields.
Definition: ww8scan.hxx:195
const SwDocInfoSubType DI_DOCNO
Definition: docufld.hxx:73
const SvNumberformat * GetEntry(sal_uInt32 nKey) const
virtual SwFieldType * InsertFieldType(const SwFieldType &)=0
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:261
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, bool bExpandCharToPara=false, SwTextAttr **ppNewTextAttr=nullptr)=0
Insert an attribute.
"Above/Below"
Definition: reffld.hxx:51
OUString const & GetStyleNames(sal_uInt16 nLevel) const
Definition: tox.hxx:483
bool GetIsEnd() const
Definition: ww8scan.hxx:772
bool GetPara(long nIdx, WW8FieldDesc &rF)
Definition: ww8scan.cxx:4102
static SvxNumType GetNumberPara(const OUString &rStr, bool bAllowPageDesc=false)
Definition: ww8par5.cxx:388
sal_uInt16 CurrentSectionColCount() const
Definition: ww8par5.cxx:2883
bool CanUseRemoteLink(const OUString &rGrfName)
Definition: ww8par5.cxx:2336
static void lcl_toxMatchACSwitch(SwDoc const &rDoc, SwTOXBase &rBase, WW8ReadFieldParams &rParam, SwCaptionDisplay eCaptionType)
Definition: ww8par5.cxx:2778
sal_Int32 GetIndex() const
Definition: index.hxx:95
void SetStyleNames(const OUString &rSet, sal_uInt16 nLevel)
Definition: tox.hxx:488
eF_ResT Read_F_OCX(WW8FieldDesc *, OUString &)
Definition: ww8par3.cxx:82
#define ODF_FORMTEXT
eF_ResT Read_F_Input(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:1155
eF_ResT Read_F_ANumber(WW8FieldDesc *, OUString &)
Definition: ww8par5.cxx:1389
NF_DATE_SYSTEM_SHORT
sal_Int32 nRemainingData
Definition: ww8scan.hxx:96
long Read_Field(WW8PLCFManResult *pRes)
Definition: ww8par5.cxx:759
void SetInputFlag(bool bInp)
Definition: expfld.hxx:262
const SwPosition * End() const
Definition: pam.hxx:217
bool m_bIgnoreText
Definition: ww8par.hxx:1313
WW8_CP nSRes
start of result
Definition: ww8scan.hxx:193
"Number (no context)"
Definition: reffld.hxx:59
sal_uInt64 Tell() const
Reference< XComponentContext > getProcessComponentContext()
eF_ResT Read_F_DocInfo(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par5.cxx:1500
static void lcl_ImportTox(SwDoc &rDoc, SwPaM const &rPaM, const OUString &rStr, bool bIdx)
Definition: ww8par5.cxx:3537
eF_ResT Read_F_Styleref(WW8FieldDesc *, OUString &rStr)
Reads a STYLEREF field.
Definition: ww8par5.cxx:1479
void SetSecondaryKey(const OUString &rStr)
Definition: tox.hxx:574
TOXTypes GetType() const
Definition: tox.hxx:663
OUString const msFileLinkSeed
Definition: ww8par.hxx:949
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
eF_ResT Read_F_Hyperlink(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:3448
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter()
Definition: breakit.hxx:62
WW8FieldEntry(SwPosition const &rPos, sal_uInt16 nFieldId)
Definition: ww8par5.cxx:716
void SetProtected(bool bSet)
Definition: tox.hxx:503
OString const aName
static sal_uInt16 lcl_GetMaxValidWordTOCLevel(const SwForm &rForm)
Definition: ww8par5.cxx:2907
std::shared_ptr< WW8PLCFMan > m_xPlcxMan
Definition: ww8par.hxx:1223
static void lcl_ConvertSequenceName(OUString &rSequenceName)
Definition: ww8par5.cxx:302
bool WillHavePageDescHere(const SwNodeIndex &rIdx) const
Definition: ww8par5.cxx:2893
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const override
Definition: atrfld.cxx:211
OUString GetMappedBookmark(const OUString &rOrigName)
Definition: ww8par5.cxx:1317
int mnFileSectionNo
Definition: ww8par.hxx:950
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:195
wwSectionNamer m_aSectionNameGenerator
Definition: ww8par.hxx:1167
virtual SwFieldType * GetSysFieldType(const SwFieldIds eWhich) const =0
static void lcl_toxMatchTSwitch(SwWW8ImplReader const &rReader, SwTOXBase &rBase, WW8ReadFieldParams &rParam)
Definition: ww8par5.cxx:2816
const SwDocInfoSubType DI_CHANGE
Definition: docufld.hxx:71
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:457
bool m_bWasParaEnd
Definition: ww8par.hxx:1335
const SwTOXType * GetTOXType(TOXTypes eTyp, sal_uInt16 nId) const
Definition: doctxm.cxx:621
sw::hack::Position maStartPos
Definition: ww8par.hxx:566
void SetLevel(sal_uInt16)
Definition: tox.hxx:698
const char *const aFieldNames[]
Definition: authfld.cxx:562
const SwDocInfoSubType DI_THEMA
Definition: docufld.hxx:67
const SwForm & GetTOXForm() const
Definition: tox.hxx:686
SwFormat * m_pCurrentColl
Definition: ww8par.hxx:1230
void Init(sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct)
This function allows to (repeatedly) initialize the columns.
Definition: atrfrm.cxx:947
#define RES_PAGEDESC
Definition: hintids.hxx:198
const SwDocInfoSubType DI_TITLE
Definition: docufld.hxx:66
#define RES_BREAK
Definition: hintids.hxx:199
SwCaptionDisplay
Definition: tox.hxx:366
bool IsUseEnhancedFields() const
static SvxNumType GetNumTypeFromName(const OUString &rStr, bool bAllowPageDesc=false)
Definition: ww8par5.cxx:367
eF_ResT Read_F_CurPage(WW8FieldDesc *, OUString &)
Definition: ww8par5.cxx:1857
eF_ResT Read_F_IncludePicture(WW8FieldDesc *, OUString &rStr)
Definition: ww8par5.cxx:2378
CharClass & GetAppCharClass()
Definition: init.cxx:751
#define RES_FRMATR_BEGIN
Definition: hintids.hxx:192
std::deque< wwSection > maSegments
Definition: ww8par.hxx:826
eF_ResT Read_F_NoteReference(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par5.cxx:2086
aStr
FormTokenType
Definition: tox.hxx:191
SwPaM * m_pPaM
Definition: ww8par.hxx:1095
void SetINetFormatAndId(const OUString &rNm, const sal_uInt16 nId)
Definition: fmtinfmt.hxx:94
void SetCharFormatId(sal_uInt16 nNew)
Definition: fmtruby.hxx:68
#define ODF_ID_PARAM
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1307
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
bool GetTokenSttFromTo(sal_Int32 *_pFrom, sal_Int32 *_pTo, sal_Int32 _nMax)
eF_ResT Read_F_Equation(WW8FieldDesc *, OUString &)
Definition: ww8par5.cxx:2588
#define RES_PARATR_END
Definition: hintids.hxx:180
only the title
Definition: chpfld.hxx:33
WW8FieldEntry & operator=(const WW8FieldEntry &rOther)
Definition: ww8par5.cxx:732
SVL_DLLPUBLIC OUString SmartRel2Abs(INetURLObject const &rTheBaseURIRef, OUString const &rTheRelURIRef, Link< OUString *, bool > const &rMaybeFileHdl=Link< OUString *, bool >(), bool bCheckFileExists=true, bool bIgnoreFragment=false, INetURLObject::EncodeMechanism eEncodeMechanism=INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism eDecodeMechanism=INetURLObject::DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
eF_ResT Read_F_HTMLControl(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:314
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo