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