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