LibreOffice Module sw (master)  1
ww8par3.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 <memory>
21 #include <svl/itemiter.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/outdev.hxx>
24 #include <sal/log.hxx>
25 
26 #include <vcl/unohelp.hxx>
27 #include <com/sun/star/form/XFormComponent.hpp>
28 #include <com/sun/star/drawing/XShape.hpp>
29 #include <com/sun/star/drawing/XShapes.hpp>
30 #include <com/sun/star/drawing/XControlShape.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/container/XIndexContainer.hpp>
33 #include <com/sun/star/text/VertOrientation.hpp>
34 #include <com/sun/star/text/TextContentAnchorType.hpp>
35 #include <com/sun/star/beans/XPropertyContainer.hpp>
36 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 
38 #include <algorithm>
39 #include <hintids.hxx>
40 #include <editeng/fontitem.hxx>
41 #include <editeng/lrspitem.hxx>
42 #include <editeng/fhgtitem.hxx>
43 #include <editeng/colritem.hxx>
44 #include <editeng/wghtitem.hxx>
46 #include <editeng/udlnitem.hxx>
47 #include <editeng/postitem.hxx>
48 #include <o3tl/safeint.hxx>
49 #include <o3tl/temporary.hxx>
50 #include <unotextrange.hxx>
51 #include <doc.hxx>
52 #include <docary.hxx>
54 #include <IDocumentMarkAccess.hxx>
55 #include <docsh.hxx>
56 #include <numrule.hxx>
57 #include <paratr.hxx>
58 #include <charatr.hxx>
59 #include <charfmt.hxx>
60 #include <ndtxt.hxx>
61 #include <expfld.hxx>
62 #include <fmtfld.hxx>
63 #include <flddropdown.hxx>
64 #include "sprmids.hxx"
65 #include "writerhelper.hxx"
66 #include "writerwordglue.hxx"
67 #include "ww8par.hxx"
68 #include "ww8par2.hxx"
69 
70 #include <IMark.hxx>
71 #include <unotools/fltrcfg.hxx>
72 #include <rtl/character.hxx>
73 #include <xmloff/odffields.hxx>
74 #include <comphelper/string.hxx>
75 
76 using namespace com::sun::star;
77 using namespace sw::util;
78 using namespace sw::types;
79 using namespace sw::mark;
80 
81 // UNO-Controls
82 
83 // OCX i.e. word 97 form controls
85 {
86  if( m_bObj && m_nPicLocFc )
87  m_nObjLocFc = m_nPicLocFc;
88  m_bEmbeddObj = true;
89  return eF_ResT::TEXT;
90 }
91 
93 {
94  WW8FormulaEditBox aFormula(*this);
95 
96  sal_Int32 const nPos(rStr.indexOf(0x01));
97  if (pF->nLCode && nPos != -1 && nPos < pF->nLCode) {
98  ImportFormulaControl(aFormula, pF->nSCode + nPos, WW8_CT_EDIT);
99  }
100 
101  /*
102  Here we have a small complication. This formula control contains
103  the default text that is displayed if you edit the form field in
104  the "default text" area. But MSOffice does not display that
105  information, instead it display the result of the field,
106  MSOffice just uses the default text of the control as its
107  initial value for the displayed default text. So we will swap in
108  the field result into the formula here in place of the default
109  text.
110  */
111 
112  const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
113  const bool bUseEnhFields = rOpt.IsUseEnhancedFields();
114 
115  if (!bUseEnhFields)
116  {
117  aFormula.msDefault = GetFieldResult(pF);
118 
119  SwInputField aField(
120  static_cast<SwInputFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Input )),
121  aFormula.msDefault,
122  aFormula.msTitle,
123  INP_TXT,
124  0 );
125  aField.SetHelp(aFormula.msHelp);
126  aField.SetToolTip(aFormula.msToolTip);
127 
129  return eF_ResT::OK;
130  }
131  else
132  {
133  WW8PLCFx_Book* pB = m_xPlcxMan->GetBook();
134  OUString aBookmarkName;
135  if (pB!=nullptr) {
136  WW8_CP currentCP=pF->nSCode;
137  WW8_CP currentLen=pF->nLen;
138 
139  WW8_CP nEnd;
140  if (o3tl::checked_add(currentCP, currentLen-1, nEnd)) {
141  SAL_WARN("sw.ww8", "broken offset, ignoring");
142  }
143  else
144  {
145  sal_uInt16 bkmFindIdx;
146  OUString aBookmarkFind=pB->GetBookmark(currentCP-1, nEnd, bkmFindIdx);
147 
148  if (!aBookmarkFind.isEmpty()) {
149  pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark bookmark as consumed, such that it'll not get inserted as a "normal" bookmark again
150  if (!aBookmarkFind.isEmpty()) {
151  aBookmarkName=aBookmarkFind;
152  }
153  }
154  }
155  }
156 
157  if (pB!=nullptr && aBookmarkName.isEmpty()) {
158  aBookmarkName=pB->GetUniqueBookmarkName(aFormula.msTitle);
159  }
160 
161  if (!aBookmarkName.isEmpty()) {
162  m_aFieldStack.back().SetBookmarkName(aBookmarkName);
163  m_aFieldStack.back().SetBookmarkType(ODF_FORMTEXT);
164  if ( aFormula.msToolTip.getLength() < 139 )
165  m_aFieldStack.back().getParameters()["Description"] <<= aFormula.msToolTip;
166  m_aFieldStack.back().getParameters()["Name"] <<= aFormula.msTitle;
167  if (aFormula.mnMaxLen && aFormula.mnMaxLen < 32768 )
168  m_aFieldStack.back().getParameters()["MaxLength"] <<= aFormula.mnMaxLen;
169 
170  if ( aFormula.mfType == 1 )
171  m_aFieldStack.back().getParameters()["Type"] <<= OUString("number");
172  else if ( aFormula.mfType == 2 )
173  m_aFieldStack.back().getParameters()["Type"] <<= OUString("date");
174  else if ( aFormula.mfType == 3 )
175  m_aFieldStack.back().getParameters()["Type"] <<= OUString("currentTime");
176  else if ( aFormula.mfType == 4 )
177  m_aFieldStack.back().getParameters()["Type"] <<= OUString("currentDate");
178  else if ( aFormula.mfType == 5 )
179  m_aFieldStack.back().getParameters()["Type"] <<= OUString("calculated");
180  }
181  return eF_ResT::TEXT;
182  }
183 }
184 
186 {
187  WW8FormulaCheckBox aFormula(*this);
188 
189  if (!m_xFormImpl)
190  m_xFormImpl.reset(new SwMSConvertControls(m_pDocShell, m_pPaM));
191 
192  if (rStr[pF->nLCode-1]==0x01)
193  ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_CHECKBOX);
194  const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
195  const bool bUseEnhFields = rOpt.IsUseEnhancedFields();
196 
197  if (!bUseEnhFields)
198  {
199  m_xFormImpl->InsertFormula(aFormula);
200  return eF_ResT::OK;
201  }
202 
203  OUString aBookmarkName;
204  WW8PLCFx_Book* pB = m_xPlcxMan->GetBook();
205  if (pB!=nullptr) {
206  WW8_CP currentCP=pF->nSCode;
207  WW8_CP currentLen=pF->nLen;
208 
209  sal_uInt16 bkmFindIdx;
210  OUString aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);
211 
212  if (!aBookmarkFind.isEmpty()) {
213  pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark as consumed by field
214  if (!aBookmarkFind.isEmpty()) {
215  aBookmarkName=aBookmarkFind;
216  }
217  }
218  }
219 
220  if (pB!=nullptr && aBookmarkName.isEmpty()) {
221  aBookmarkName=pB->GetUniqueBookmarkName(aFormula.msTitle);
222  }
223 
224  if (!aBookmarkName.isEmpty())
225  {
227  IFieldmark* pFieldmark = pMarksAccess->makeNoTextFieldBookmark(
228  *m_pPaM, aBookmarkName, ODF_FORMCHECKBOX );
229  OSL_ENSURE(pFieldmark!=nullptr, "hmmm; why was the bookmark not created?");
230  if (pFieldmark!=nullptr) {
231  IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters();
232  ICheckboxFieldmark* pCheckboxFm = dynamic_cast<ICheckboxFieldmark*>(pFieldmark);
233  (*pParameters)[ODF_FORMCHECKBOX_NAME] <<= aFormula.msTitle;
234  (*pParameters)[ODF_FORMCHECKBOX_HELPTEXT] <<= aFormula.msToolTip;
235 
236  if(pCheckboxFm)
237  pCheckboxFm->SetChecked(aFormula.mnChecked != 0);
238  // set field data here...
239  }
240  }
241  return eF_ResT::OK;
242 }
243 
245 {
246  WW8FormulaListBox aFormula(*this);
247 
248  if (pF->nLCode > 0 && rStr.getLength() >= pF->nLCode && rStr[pF->nLCode-1] == 0x01)
249  ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_DROPDOWN);
250 
251  const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
252  bool bUseEnhFields = rOpt.IsUseEnhancedFields();
253 
254  if (!bUseEnhFields)
255  {
256  SwDropDownField aField(static_cast<SwDropDownFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Dropdown)));
257 
258  aField.SetName(aFormula.msTitle);
259  aField.SetHelp(aFormula.msHelp);
260  aField.SetToolTip(aFormula.msToolTip);
261 
262  if (!aFormula.maListEntries.empty())
263  {
264  aField.SetItems(aFormula.maListEntries);
265  int nIndex = aFormula.mfDropdownIndex < aFormula.maListEntries.size() ? aFormula.mfDropdownIndex : 0;
266  aField.SetSelectedItem(aFormula.maListEntries[nIndex]);
267  }
268 
270  return eF_ResT::OK;
271  }
272  else
273  {
274  // TODO: review me
275  OUString aBookmarkName;
276  WW8PLCFx_Book* pB = m_xPlcxMan->GetBook();
277  if (pB!=nullptr)
278  {
279  WW8_CP currentCP=pF->nSCode;
280  WW8_CP currentLen=pF->nLen;
281 
282  sal_uInt16 bkmFindIdx;
283  OUString aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);
284 
285  if (!aBookmarkFind.isEmpty())
286  {
287  pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark as consumed by field
288  if (!aBookmarkFind.isEmpty())
289  aBookmarkName=aBookmarkFind;
290  }
291  }
292 
293  if (pB!=nullptr && aBookmarkName.isEmpty())
294  aBookmarkName=pB->GetUniqueBookmarkName(aFormula.msTitle);
295 
296  if (!aBookmarkName.isEmpty())
297  {
299  IFieldmark *pFieldmark =
300  pMarksAccess->makeNoTextFieldBookmark( *m_pPaM, aBookmarkName, ODF_FORMDROPDOWN );
301  OSL_ENSURE(pFieldmark!=nullptr, "hmmm; why was the bookmark not created?");
302  if ( pFieldmark != nullptr )
303  {
304  uno::Sequence< OUString > vListEntries(aFormula.maListEntries.size());
305  std::copy(aFormula.maListEntries.begin(), aFormula.maListEntries.end(), vListEntries.begin());
306  (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] <<= vListEntries;
307  sal_Int32 nIndex = aFormula.mfDropdownIndex < aFormula.maListEntries.size() ? aFormula.mfDropdownIndex : 0;
308  (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_RESULT] <<= nIndex;
309  // set field data here...
310  }
311  }
312 
313  return eF_ResT::OK;
314  }
315 }
316 
318 {
319  if( m_bObj && m_nPicLocFc )
320  m_nObjLocFc = m_nPicLocFc;
321  m_bEmbeddObj = true;
322  return eF_ResT::TEXT;
323 }
324 
325 // Helper declarations
326 
327 // Style Id's for each level
329 // Character Style Pointer
331 
332 namespace {
333 
334 struct WW8LST // only THOSE entries, WE need!
335 {
336  WW8aIdSty aIdSty; // Style Id's for each level,
337  // nIStDNil if no style linked
338  sal_uInt32 nIdLst; // Unique List ID
339  sal_uInt32 nTplC; // Unique template code - What is this?
340  bool bSimpleList:1; // Flag: List only has ONE level
341  bool bRestartHdn:1; // WW6-Compatibility-Flag:
342  // true if the list should start numbering over
343 }; // at the beginning of each section
344 
345 }
346 
347 const sal_uInt32 cbLSTF=28;
348 
349 namespace {
350 
351 struct WW8LFO // only THOSE entries, WE need!
352 {
353  SwNumRule* pNumRule; // Parent NumRule
354  sal_uInt32 nIdLst; // Unique List ID
355  sal_uInt8 nLfoLvl; // count of levels whose format is overridden
356  bool bSimpleList;
357 };
358 
359 struct WW8LVL // only THE entries, WE need!
360 {
361  sal_Int32 nStartAt; // start at value for this value
362  sal_Int32 nV6DxaSpace;// Ver6-Compatible: min Space between Num and text::Paragraph
363  sal_Int32 nV6Indent; // Ver6-Compatible: Width of prefix text;
364  // Use definition of first line indent if appropriate!
365  // Paragraph attributes from GrpprlPapx
366  sal_uInt16 nDxaLeft; // left indent
367  short nDxaLeft1; // first line indent
368 
369  sal_uInt8 nNFC; // number format code
370  // Offset of fieldcodes in Num-X-String
372  sal_uInt8 nLenGrpprlChpx; // length, in bytes, of the LVL's grpprlChpx
373  sal_uInt8 nLenGrpprlPapx; // length, in bytes, of the LVL's grpprlPapx
374  sal_uInt8 nAlign; // alignment (left, right, centered) of the number
375  bool bV6Prev; // Ver6-Compatible: number will include previous levels
376  bool bV6PrSp; // Ver6-Compatible: doesn't matter
377  bool bV6; // if true, pay attention to the V6-Compatible Entries!
378 
379 };
380 
381 struct WW8LFOLVL
382 {
383  sal_Int32 nStartAt; // start-at value if bFormat==false and bStartAt == true
384  // (if bFormat==true, the start-at is stored in the LVL)
385  sal_uInt8 nLevel; // the level to be overridden
386  // this byte has not been packed into the following byte on _purpose_ !!
387  // (see comment of struct WW8LFOInfo)
388 
389  bool bStartAt :1; // true if the start-at value is overridden
390  bool bFormat :1; // true if the formatting is overridden
391 
392  WW8LFOLVL() :
393  nStartAt(1), nLevel(0), bStartAt(true), bFormat(false) {}
394 };
395 
396 }
397 
398 // Data to be saved in ListInfo
399 
400 struct WW8LSTInfo // sorted by nIdLst (in WW8 used list-Id)
401 {
402  std::vector<ww::bytes> maParaSprms;
403  WW8aIdSty aIdSty; // Style Id's for each level
404  WW8aCFormat aCharFormat = {}; // Character Style Pointer
405 
406  SwNumRule* pNumRule; // Pointer to list-template in Writer
407  sal_uInt32 nIdLst; // WW8Id of this list
408  bool bSimpleList:1;// Flag, if this NumRule only uses one Level
409  bool bUsedInDoc :1;// Flag, if this NumRule is used in the Doc,
410  // or is supposed to be deleted on Reader-End
411 
412  WW8LSTInfo(SwNumRule* pNumRule_, const WW8LST& aLST)
413  : pNumRule(pNumRule_), nIdLst(aLST.nIdLst),
414  bSimpleList(aLST.bSimpleList), bUsedInDoc(false)
415  {
416  memcpy( aIdSty, aLST.aIdSty, sizeof( aIdSty ));
417  }
418 
419 };
420 
421 // Data to be saved in ListenFormatOverrideInfos
422 
423 struct WW8LFOInfo // unordered, means ordered like in WW8 Stream
424 {
425  std::vector<ww::bytes> maParaSprms;
426  std::vector<WW8LFOLVL> maOverrides;
427  SwNumRule* pNumRule; // Pointer to list template in Writer
428  // either List in LSTInfos or own List
429  // (in Ctor use the list from LSTInfos first)
430 
431  sal_uInt32 nIdLst; // WW8-Id of the relevant list
432  sal_uInt8 nLfoLvl; // count of levels whose format is overridden
433  // yes we could include nLfoLvl (via :4) into the following byte,
434  // but it probably would be a source of error once MS increases their Listformat
435  // to more than 15 levels
436 
437  bool bOverride :1;// Flag if NumRule is not included in maLSTInfos,
438  // but was created for m_LFOInfos
439  bool bUsedInDoc :1;// Flag if NumRule is used in Doc,
440  // or should be deleted on Reader-End
441  bool bLSTbUIDSet :1;// Flag, if bUsedInDoc is set in maLSTInfos
442 
443  explicit WW8LFOInfo(const WW8LFO& rLFO);
444 };
445 
446 WW8LFOInfo::WW8LFOInfo(const WW8LFO& rLFO)
447  : maParaSprms(WW8ListManager::nMaxLevel)
448  , maOverrides(WW8ListManager::nMaxLevel)
449  , pNumRule(rLFO.pNumRule)
450  , nIdLst(rLFO.nIdLst)
451  , nLfoLvl(rLFO.nLfoLvl)
452  , bOverride(rLFO.nLfoLvl != 0)
453  , bUsedInDoc(false)
454  , bLSTbUIDSet(false)
455 {
456 }
457 
458 // Helper methods
459 
460 // find Sprm-Parameter-Data, if Sprm is included in Grpprl
462  sal_uInt8 nLen)
463 {
464  return maSprmParser.findSprmData(nId, &rSprms, nLen);
465 }
466 
467 namespace {
468 
469 class ListWithId
470 {
471 private:
472  sal_uInt32 mnIdLst;
473 public:
474  explicit ListWithId(sal_uInt32 nIdLst) : mnIdLst(nIdLst) {}
475  bool operator() (const std::unique_ptr<WW8LSTInfo>& pEntry) const
476  { return (pEntry->nIdLst == mnIdLst); }
477 };
478 
479 }
480 
481 // Access via List-Id of LST Entry
482 WW8LSTInfo* WW8ListManager::GetLSTByListId( sal_uInt32 nIdLst ) const
483 {
484  auto aResult =
485  std::find_if(maLSTInfos.begin(),maLSTInfos.end(),ListWithId(nIdLst));
486  if (aResult == maLSTInfos.end())
487  return nullptr;
488  return aResult->get();
489 }
490 
491 static OUString sanitizeString(const OUString& rString)
492 {
493  sal_Int32 i=0;
494  while (i < rString.getLength())
495  {
496  sal_Unicode c = rString[i];
497  if (rtl::isHighSurrogate(c))
498  {
499  if (i+1 == rString.getLength()
500  || !rtl::isLowSurrogate(rString[i+1]))
501  {
502  SAL_WARN("sw.ww8", "Surrogate error: high without low");
503  return rString.copy(0, i);
504  }
505  ++i; //skip correct low
506  }
507  if (rtl::isLowSurrogate(c)) //bare low without preceding high
508  {
509  SAL_WARN("sw.ww8", "Surrogate error: low without high");
510  return rString.copy(0, i);
511  }
512  ++i;
513  }
514  return rString;
515 }
516 
518 {
520 
521  switch (nNFC)
522  {
523  case 0:
524  nType = SVX_NUM_ARABIC;
525  break;
526  case 1:
527  nType = SVX_NUM_ROMAN_UPPER;
528  break;
529  case 2:
530  nType = SVX_NUM_ROMAN_LOWER;
531  break;
532  case 3:
534  break;
535  case 4:
537  break;
538  case 5: // ordinal
539  nType = SVX_NUM_TEXT_NUMBER;
540  break;
541  case 6: // cardinalText
542  nType = SVX_NUM_TEXT_CARDINAL;
543  break;
544  case 7: // ordinalText
545  nType = SVX_NUM_TEXT_ORDINAL;
546  break;
547  //case 8: // hex
548 
549  case 9:
550  // 0x09, msonfcChiManSty
551  nType = SVX_NUM_SYMBOL_CHICAGO;
552  break;
553  //case 15: // decimalHalfWidth
554  //case 17: // japaneseDigitalTenThousand
555 
556  case 18: // decimalEnclosedCircle
557  case 28: // decimalEnclosedCircleChinese
558  case 29: // ideographEnclosedCircle
559  nType = SVX_NUM_CIRCLE_NUMBER;
560  break;
561  case 22:
562  // 0x16, msonfcArabicLZ
563  nType = SVX_NUM_ARABIC_ZERO;
564  break;
565  case 23:
566  nType = SVX_NUM_CHAR_SPECIAL;
567 
568  break;
569  case 255:
570  nType = SVX_NUM_NUMBER_NONE;
571  break;
572  case 14:
573  case 19:
575  break;
576  case 30:
577  nType = SVX_NUM_TIAN_GAN_ZH;
578  break;
579  case 31: // ideographZodiac
580  case 32: // ideographZodiacTraditional
581  nType = SVX_NUM_DI_ZI_ZH;
582  break;
583  case 33: // taiwaneseCounting
584  case 35:
585  case 36:
586  case 37:
587  case 11:
588  case 39:
589  nType = SVX_NUM_NUMBER_LOWER_ZH;
590  break;
591  case 34:
593  break;
594  case 38:
595  nType = SVX_NUM_NUMBER_UPPER_ZH;
596  break;
597  case 10:
598  case 16: // japaneseLegal
600  break;
601  case 20:
602  nType = SVX_NUM_AIU_FULLWIDTH_JA;
603  break;
604  case 12:
605  nType = SVX_NUM_AIU_HALFWIDTH_JA;
606  break;
607  case 21:
609  break;
610  case 13:
612  break;
613  case 24:
615  break;
616  case 25:
617  nType = SVX_NUM_HANGUL_JAMO_KO;
618  break;
619  //case 26: // decimalEnclosedFullstop
620  //case 27: // decimalEnclosedParen
621  //case 40: // decimal (Chinese)
622 
623  case 41: // koreanDigital
624  case 42: // koreanCounting
625  case 43: // koreanLegal
626  nType = SVX_NUM_NUMBER_HANGUL_KO;
627  break;
628  case 44: // koreanDigital2
629  nType = SVX_NUM_NUMBER_UPPER_KO;
630  break;
631  case 45: // hebrew1
632  nType = SVX_NUM_NUMBER_HEBREW;
633  break;
634  case 46: // arabicAlpha
635  nType = SVX_NUM_CHARS_ARABIC;
636  break;
637  case 47: // hebrew2
638  nType = SVX_NUM_CHARS_HEBREW;
639  break;
640  case 48: // arabicAbjad
642  break;
643  case 49: // hindiVowels
644  nType = SVX_NUM_CHARS_NEPALI;
645  break;
646  //case 50: // hindiConsonants
647  //case 51: // hindiNumbers
648  //case 52: // hindiCounting
649 
650  case 53: // thaiLetters
651  nType = SVX_NUM_CHARS_THAI;
652  break;
653  //case 54: // thaiNumbers
654  //case 55: // thaiCounting
655  //case 56: // vietnameseCounting
656  //case 57: // numberInDash
657 
658  case 58: // russianLower
660  break;
661  case 59: // russianUpper
663  break;
664  default:
665  nType = SVX_NUM_ARABIC;
666  break;
667  }
668 
669  return nType;
670 }
671 
672 bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet>& rpItemSet,
673  sal_uInt16 nLevelStyle, bool bSetStartNo, sal_uInt16 /*nLevel*/, ww::bytes &rParaSprms)
674 {
675  sal_uInt8 aBits1(0);
677  SvxAdjust eAdj; // Alignment (Left/right/centered)
678  sal_UCS4 cBullet(0x2190); // default safe bullet
679 
680  sal_Unicode cGrfBulletCP(USHRT_MAX);
681 
682  WW8LVL aLVL = {};
683 
684  // 1. read LVLF
685 
686  rSt.ReadInt32( aLVL.nStartAt );
687  rSt.ReadUChar( aLVL.nNFC );
688  rSt.ReadUChar( aBits1 );
689  if( ERRCODE_NONE != rSt.GetError() ) return false;
690  aLVL.nAlign = (aBits1 & 0x03);
691  if( aBits1 & 0x10 ) aLVL.bV6Prev = true;
692  if( aBits1 & 0x20 ) aLVL.bV6PrSp = true;
693  if( aBits1 & 0x40 ) aLVL.bV6 = true;
694  bool bLVLOkB = true;
695  for(sal_uInt8 nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
696  {
697  rSt.ReadUChar( aLVL.aOfsNumsXCH[ nLevelB ] );
698  if( ERRCODE_NONE != rSt.GetError() )
699  {
700  bLVLOkB = false;
701  break;
702  }
703  }
704 
705  if( !bLVLOkB )
706  return false;
707 
708  sal_uInt8 ixchFollow(0);
709  rSt.ReadUChar( ixchFollow );
710  rSt.ReadInt32( aLVL.nV6DxaSpace );
711  rSt.ReadInt32( aLVL.nV6Indent );
712  rSt.ReadUChar( aLVL.nLenGrpprlChpx );
713  rSt.ReadUChar( aLVL.nLenGrpprlPapx );
714  rSt.SeekRel( 2 );
715  if( ERRCODE_NONE != rSt.GetError()) return false;
716 
717  // 2. read PAPx if needed and search for indent values
718 
719  short nTabPos = 0; // #i86652# - read tab setting
720  if( aLVL.nLenGrpprlPapx )
721  {
722  sal_uInt8 aGrpprlPapx[ 255 ];
723  if (aLVL.nLenGrpprlPapx != rSt.ReadBytes(&aGrpprlPapx, aLVL.nLenGrpprlPapx))
724  return false;
725  // "sprmPDxaLeft" pap.dxaLeft;dxa;word;
726  SprmResult aSprm = GrpprlHasSprm(0x840F,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
727  if (!aSprm.pSprm)
728  aSprm = GrpprlHasSprm(0x845E,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
729 
730  if (aSprm.pSprm && aSprm.nRemainingData >= 2)
731  {
732  const sal_uInt8 *pBegin = aSprm.pSprm - 2;
733  for(int i=0;i<4;++i)
734  rParaSprms.push_back(*pBegin++);
735  short nDxaLeft = SVBT16ToUInt16(aSprm.pSprm);
736  aLVL.nDxaLeft = (0 < nDxaLeft) ? o3tl::narrowing<sal_uInt16>(nDxaLeft)
737  : o3tl::narrowing<sal_uInt16>(-nDxaLeft);
738  }
739 
740  // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
741  aSprm = GrpprlHasSprm(0x8411,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
742  if (!aSprm.pSprm)
743  aSprm = GrpprlHasSprm(0x8460,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
744 
745  if (aSprm.pSprm && aSprm.nRemainingData >= 2)
746  {
747  const sal_uInt8 *pBegin = aSprm.pSprm - 2;
748  for(int i=0;i<4;++i)
749  rParaSprms.push_back(*pBegin++);
750  aLVL.nDxaLeft1 = SVBT16ToUInt16(aSprm.pSprm);
751  }
752 
753  // #i86652# - read tab setting
754  aSprm = GrpprlHasSprm(0xC615,aGrpprlPapx[0],aLVL.nLenGrpprlPapx);
755  const sal_uInt8* pSprm = aSprm.pSprm;
756  if (pSprm && aSprm.nRemainingData >= 5)
757  {
758  bool bDone = false;
759  if (*(pSprm-1) == 5)
760  {
761  if (*pSprm++ == 0) //nDel
762  {
763  if (*pSprm++ == 1) //nIns
764  {
765  nTabPos = SVBT16ToUInt16(pSprm);
766  pSprm+=2;
767  if (*pSprm == 6) //type
768  {
769  bDone = true;
770  }
771  }
772  }
773  }
774  OSL_ENSURE(bDone, "tab setting in numbering is "
775  "of unexpected configuration");
776  }
777  if ( rNumFormat.GetPositionAndSpaceMode() ==
779  {
780  // If there is a tab setting with a larger value, then use that.
781  // Ideally we would allow tabs to be used in numbering fields and set
782  // this on the containing paragraph which would make it actually work
783  // most of the time.
784  if ( nTabPos != 0 )
785  {
786  const sal_uInt16 nDesired = aLVL.nDxaLeft + aLVL.nDxaLeft1;
787 
788  bool bDoAdjust = false;
789  if ( nDesired < aLVL.nDxaLeft )
790  {
791  if ( nDesired < nTabPos && nTabPos < aLVL.nDxaLeft )
792  {
793  bDoAdjust = true;
794  }
795  }
796  else
797  {
798  if ( aLVL.nDxaLeft < nTabPos && nTabPos < nDesired )
799  {
800  bDoAdjust = true;
801  }
802  }
803 
804  if (bDoAdjust)
805  {
806  aLVL.nDxaLeft = (0 < nTabPos)
807  ? o3tl::narrowing<sal_uInt16>(nTabPos)
808  : o3tl::narrowing<sal_uInt16>(-nTabPos);
809 
810  aLVL.nDxaLeft1 = nDesired - aLVL.nDxaLeft;
811  }
812  }
813  }
814  }
815 
816  // 3. read CHPx if needed
817 
818  sal_uInt16 nWitchPicIsBullet = USHRT_MAX;
819  bool bIsPicBullet = false;
820 
821  if( aLVL.nLenGrpprlChpx )
822  {
823  sal_uInt8 aGrpprlChpx[ 255 ] = {};
824  if (aLVL.nLenGrpprlChpx != rSt.ReadBytes(&aGrpprlChpx, aLVL.nLenGrpprlChpx))
825  return false;
826 
827  //For i120928,parse the graphic info of bullets
828  SprmResult aSprmWhichPis = GrpprlHasSprm(NS_sprm::CPbiIBullet::val, aGrpprlChpx[0],aLVL.nLenGrpprlChpx);
829  SprmResult aSprmIsPicBullet = GrpprlHasSprm(NS_sprm::CPbiGrf::val, aGrpprlChpx[0],aLVL.nLenGrpprlChpx);
830  if (aSprmWhichPis.pSprm && aSprmWhichPis.nRemainingData >= 1)
831  {
832  nWitchPicIsBullet = *aSprmWhichPis.pSprm;
833  }
834  if (aSprmIsPicBullet.pSprm && aSprmIsPicBullet.nRemainingData >= 1)
835  {
836  bIsPicBullet = (*aSprmIsPicBullet.pSprm) & 0x0001;
837  }
838 
839  // create new Itemset for character attributes
840  rpItemSet.reset(new SfxItemSet( rDoc.GetAttrPool(), svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END - 1>));
841 
842  // Set Reader-ItemSet-Pointer to the newly created set
843  rReader.SetCurrentItemSet(std::move(rpItemSet));
844  // Set Reader-Style to Style of this Level
845  sal_uInt16 nOldColl = rReader.GetCurrentColl();
846  sal_uInt16 nNewColl = nLevelStyle;
847  if (ww::stiNil == nNewColl)
848  nNewColl = 0;
849  rReader.SetNCurrentColl( nNewColl );
850 
851  // The Read_xy() methods in WW8PAR6.cxx are calling their respective
852  // NewAttr() or GetFormatAttr() which can determine, by using the assigned
853  // Reader-ItemSet-Pointer, whether this specific ItemSet is relevant
854  // and not a Stack or Style!
855  sal_uInt16 nOldFlags1 = rReader.GetToggleAttrFlags();
856  sal_uInt16 nOldFlags2 = rReader.GetToggleBiDiAttrFlags();
857 
858  WW8SprmIter aSprmIter(&aGrpprlChpx[0], aLVL.nLenGrpprlChpx,
859  maSprmParser);
860  while (const sal_uInt8* pSprm = aSprmIter.GetSprms())
861  {
862  rReader.ImportSprm(pSprm, aSprmIter.GetRemLen(), aSprmIter.GetCurrentId());
863  aSprmIter.advance();
864  }
865 
866  // Reset Reader-ItemSet-Pointer and Reader-Style
867  rpItemSet = rReader.SetCurrentItemSet(nullptr);
868  rReader.SetNCurrentColl( nOldColl );
869  rReader.SetToggleAttrFlags(nOldFlags1);
870  rReader.SetToggleBiDiAttrFlags(nOldFlags2);
871  }
872 
873  // 4. Read numbering String. Results in prefix and postfix
874 
875  OUString sNumString(sanitizeString(read_uInt16_PascalString(rSt)));
876 
877  // 5. convert read values into Writer syntax
878 
879  nType = GetSvxNumTypeFromMSONFC(aLVL.nNFC);
880  //For i120928,type info
881  if (bIsPicBullet)
882  {
883  nType = SVX_NUM_BITMAP;
884  }
885 
886  if (style::NumberingType::CHAR_SPECIAL == nType)
887  {
888  cBullet = !sNumString.isEmpty()
889  ? sNumString.iterateCodePoints(&o3tl::temporary(sal_Int32(0))) : 0x2190;
890 
891  if (!cBullet) // unsave control code?
892  cBullet = 0x2190;
893  }
894  else if (style::NumberingType::BITMAP == nType) //For i120928,position index info of graphic
895  {
896  cGrfBulletCP = nWitchPicIsBullet; // This is a bullet picture ID
897  }
898 
899  switch( aLVL.nAlign )
900  {
901  case 0:
902  eAdj = SvxAdjust::Left;
903  break;
904  case 1:
905  eAdj = SvxAdjust::Center;
906  break;
907  case 2:
908  eAdj = SvxAdjust::Right;
909  break;
910  case 3:
911  // Writer here cannot do block justification
912  eAdj = SvxAdjust::Left;
913  break;
914  default:
915  // undefined value
916  OSL_ENSURE( false, "Value of aLVL.nAlign is not supported" );
917  // take default
918  eAdj = SvxAdjust::Left;
919  break;
920  }
921 
922  // 6. Configure NumFormat
923  if( bSetStartNo && 0 <= aLVL.nStartAt)
924  rNumFormat.SetStart(o3tl::narrowing<sal_uInt16>(aLVL.nStartAt));
925  rNumFormat.SetNumberingType( nType );
926  rNumFormat.SetNumAdjust( eAdj );
927 
928  if( style::NumberingType::CHAR_SPECIAL == nType )
929  {
930  // first character of the Prefix-Text is the Bullet
931  rNumFormat.SetBulletChar(cBullet);
932  // Don't forget: further below, after building styles
933  // Call SetBulletFont() !!!
934  }
935  //For i120928,position index info
936  else if (style::NumberingType::BITMAP == nType)
937  {
938  rNumFormat.SetGrfBulletCP(cGrfBulletCP);
939  }
940  else
941  {
942  // Replace symbols at aOfsNumsXCH offsets to %1%, %2% as supported by LO
943  OUString sListFormat = sNumString;
944  if (sListFormat.getLength())
945  {
946  sal_uInt32 nExtraOffset = 0;
947  sal_uInt8 nLevelB = 0;
948  while (nLevelB < nMaxLevel && aLVL.aOfsNumsXCH[nLevelB])
949  {
950  // Replacement symbol is read from source string from position taken from aOfsNumsXCH array
951  sal_uInt8 nOffset = aLVL.aOfsNumsXCH[nLevelB] + nExtraOffset - 1;
952  if (nOffset >= sListFormat.getLength())
953  {
954  SAL_WARN("sw.ww8", "List level reference is beyond the border. Ignored.");
955  nLevelB++;
956  continue;
957  }
958  sal_uInt8 nReplacement = sListFormat[nOffset] + 1;
959 
960  OUString sReplacement("%" + OUString::number(nReplacement) + "%");
961  sListFormat = sListFormat.replaceAt(nOffset, 1, sReplacement);
962 
963  // We need also update an offset, since we are replacing one symbol by at least two
964  nExtraOffset += sReplacement.getLength() - 1;
965  nLevelB++;
966  }
967  }
968 
969  rNumFormat.SetListFormat(sListFormat);
970 
971  // Total count of replacement holders is determining amount of required parent numbering to include
972  // TODO: not sure how "%" symbol is escaped. This is not supported yet
973  sal_Int16 nParentNum = comphelper::string::getTokenCount(sListFormat, '%');
974  rNumFormat.SetIncludeUpperLevels(nParentNum);
975  }
976 
977  // #i89181#
978  if ( rNumFormat.GetPositionAndSpaceMode() ==
980  {
981  if (eAdj == SvxAdjust::Right)
982  {
983  rNumFormat.SetAbsLSpace(aLVL.nDxaLeft);
984  rNumFormat.SetFirstLineOffset(-aLVL.nDxaLeft);
985  rNumFormat.SetCharTextDistance(-aLVL.nDxaLeft1);
986  }
987  else
988  {
989  rNumFormat.SetAbsLSpace( aLVL.nDxaLeft );
990  rNumFormat.SetFirstLineOffset(aLVL.nDxaLeft1);
991  }
992  }
993  else
994  {
995  rNumFormat.SetIndentAt( aLVL.nDxaLeft );
996  rNumFormat.SetFirstLineIndent(aLVL.nDxaLeft1);
997  if ( !aLVL.bV6 )
998  rNumFormat.SetListtabPos( nTabPos );
999  else
1000  rNumFormat.SetListtabPos( aLVL.nV6Indent );
1002  switch ( ixchFollow )
1003  {
1004  case 0:
1005  {
1006  eNumLabelFollowedBy = SvxNumberFormat::LISTTAB;
1007  }
1008  break;
1009  case 1:
1010  {
1011  eNumLabelFollowedBy = SvxNumberFormat::SPACE;
1012  }
1013  break;
1014  case 2:
1015  {
1016  eNumLabelFollowedBy = SvxNumberFormat::NOTHING;
1017  }
1018  break;
1019  }
1020  rNumFormat.SetLabelFollowedBy( eNumLabelFollowedBy );
1021  }
1022 
1023  return true;
1024 }
1025 
1027  WW8aISet const & rListItemSet, WW8aCFormat& rCharFormat, bool& bNewCharFormatCreated,
1028  const OUString& sPrefix )
1029 {
1030  bNewCharFormatCreated = false;
1031  sal_uInt8 nIdenticalItemSetLevel;
1032  const SfxPoolItem* pItem;
1033 
1034  SwNumFormat aNumFormat = rNumRule.Get( nLevel );
1035 
1036  SfxItemSet* pThisLevelItemSet = rListItemSet[nLevel].get();
1037 
1038  if( pThisLevelItemSet && pThisLevelItemSet->Count())
1039  {
1040  nIdenticalItemSetLevel = nMaxLevel;
1041  SfxItemIter aIter( *pThisLevelItemSet );
1042  for (sal_uInt8 nLowerLevel = 0; nLowerLevel < nLevel; ++nLowerLevel)
1043  {
1044  SfxItemSet* pLowerLevelItemSet = rListItemSet[nLowerLevel].get();
1045  if( pLowerLevelItemSet
1046  && (pLowerLevelItemSet->Count() == pThisLevelItemSet->Count()) )
1047  {
1048  nIdenticalItemSetLevel = nLowerLevel;
1049  const SfxPoolItem* pItemIter = aIter.GetCurItem();
1050  do
1051  {
1052  if( // search for appropriate pItem in pLowerLevelItemSet
1053  (SfxItemState::SET != pLowerLevelItemSet->GetItemState(
1054  pItemIter->Which(), false, &pItem ) )
1055  || // use virtual "!=" Operator
1056  (*pItem != *pItemIter) )
1057  // if no Item with equal nWhich was found or Item value was not equal
1058  // store inequality and break!
1059  {
1060  nIdenticalItemSetLevel = nMaxLevel;
1061  break;
1062  }
1063  pItemIter = aIter.NextItem();
1064  } while (pItemIter);
1065 
1066  if( nIdenticalItemSetLevel != nMaxLevel )
1067  break;
1068  }
1069  }
1070 
1071  SwCharFormat* pFormat;
1072  if (nMaxLevel == nIdenticalItemSetLevel)
1073  {
1074  // Define Style
1075  const OUString aName( (!sPrefix.isEmpty() ? sPrefix : rNumRule.GetName())
1076  + "z" + OUString::number( nLevel ) );
1077 
1078  // remove const by casting
1080  bNewCharFormatCreated = true;
1081  // Set Attributes
1082  pFormat->SetFormatAttr( *pThisLevelItemSet );
1083  }
1084  else
1085  {
1086  // append Style
1087  pFormat = rCharFormat[ nIdenticalItemSetLevel ];
1088  }
1089 
1090  // store
1091  rCharFormat[ nLevel ] = pFormat;
1092 
1093  // Append Style to NumFormat
1094 
1095  aNumFormat.SetCharFormat( pFormat );
1096  }
1097 
1098  // if necessary: Append Bullet Font to NumFormat
1099 
1100  if( SVX_NUM_CHAR_SPECIAL == aNumFormat.GetNumberingType() )
1101  {
1102  SwCharFormat* pFormat = aNumFormat.GetCharFormat();
1103  vcl::Font aFont;
1104  if( !pFormat )
1105  {
1106  aFont = numfunc::GetDefBulletFont();
1107  }
1108  else
1109  {
1110  const SvxFontItem& rFontItem = pFormat->GetFont();
1111  aFont.SetFamily( rFontItem.GetFamily() );
1112  aFont.SetFamilyName( rFontItem.GetFamilyName() );
1113  aFont.SetStyleName( rFontItem.GetStyleName() );
1114  aFont.SetPitch( rFontItem.GetPitch() );
1115  aFont.SetCharSet( rFontItem.GetCharSet() );
1116  }
1117  aNumFormat.SetBulletFont( &aFont );
1118  }
1119 
1120  // Set NumFormat in NumRule
1121 
1122  rNumRule.Set(nLevel, aNumFormat);
1123 }
1124 
1126 {
1127  // Used to build the Style Name
1128  const OUString sPrefix("WW8Num" + OUString::number(nUniqueList++));
1129  // #i86652#
1130  sal_uInt16 nRul =
1131  rDoc.MakeNumRule( rDoc.GetUniqueNumRuleName(&sPrefix), nullptr, false,
1133  SwNumRule* pMyNumRule = rDoc.GetNumRuleTable()[nRul];
1134  pMyNumRule->SetAutoRule(false);
1135  pMyNumRule->SetContinusNum(bSimple);
1136  return pMyNumRule;
1137 }
1138 
1140 {
1141  if (i < maLSTInfos.size())
1142  return maLSTInfos[i]->pNumRule;
1143  else
1144  return nullptr;
1145 }
1146 
1147 // public methods
1148 
1150  : maSprmParser(rReader_.GetFib()), rReader(rReader_)
1151  , rDoc(rReader.GetDoc())
1152  , rFib(rReader.GetFib()), rSt(rSt_)
1153  , nUniqueList(1)
1154  , nLastLFOPosition(USHRT_MAX)
1155 {
1156 
1157  // LST and LFO only since WW8
1158  if( ( 8 > rFib.m_nVersion )
1159  || ( rFib.m_fcPlcfLst == rFib.m_fcPlfLfo )
1160  || ( rFib.m_lcbPlcfLst < 2 )
1161  || ( rFib.m_lcbPlfLfo < 2) ) return; // no public lists
1162 
1163  // create Arrays
1164  bool bLVLOk = true;
1165 
1166  tools::Long nOriginalPos = rSt.Tell();
1167 
1168  // 1. read PLCF LST and create list templates in Writer
1169 
1170  bool bOk = checkSeek(rSt, rFib.m_fcPlcfLst);
1171 
1172  if (!bOk)
1173  return;
1174 
1175  sal_uInt32 nRemainingPlcfLst = rFib.m_lcbPlcfLst;
1176 
1177  sal_uInt16 nListCount(0);
1178  rSt.ReadUInt16( nListCount );
1179  nRemainingPlcfLst -= 2;
1180  bOk = nListCount > 0;
1181 
1182  if (!bOk)
1183  return;
1184 
1185  // 1.1 read all LST
1186  const size_t nMinRecordSize = 10 + 2*nMaxLevel;
1187  const size_t nMaxRecords = rSt.remainingSize() / nMinRecordSize;
1188  if (nListCount > nMaxRecords)
1189  {
1190  SAL_WARN("sw.ww8", "Parsing error: " << nMaxRecords <<
1191  " max possible entries, but " << nListCount << " claimed, truncating");
1192  nListCount = nMaxRecords;
1193  }
1194  for (sal_uInt16 nList=0; nList < nListCount; ++nList)
1195  {
1196  if (nRemainingPlcfLst < cbLSTF)
1197  break;
1198 
1199  WW8LST aLST = {};
1200 
1201  // 1.1.1 read Data
1202 
1203  rSt.ReadUInt32( aLST.nIdLst );
1204  rSt.ReadUInt32( aLST.nTplC );
1205  for (sal_uInt16 & nLevel : aLST.aIdSty)
1206  rSt.ReadUInt16( nLevel );
1207 
1208  sal_uInt8 aBits1(0);
1209  rSt.ReadUChar( aBits1 );
1210 
1211  rSt.SeekRel( 1 );
1212 
1213  if( aBits1 & 0x01 )
1214  aLST.bSimpleList = true;
1215  if( aBits1 & 0x02 )
1216  aLST.bRestartHdn = true;
1217 
1218  // 1.1.2 new NumRule inserted in Doc and WW8LSTInfo marked
1219 
1220  /*
1221  #i1869#
1222  In word 2000 microsoft got rid of creating new "simple lists" with
1223  only 1 level, all new lists are created with 9 levels. To hack it
1224  so that the list types formerly known as simple lists still have
1225  their own tab page to themselves one of the reserved bits is used
1226  to show that a given list is to be in the simple list tabpage.
1227  This has now nothing to do with the actual number of list level a
1228  list has, only how many will be shown in the user interface.
1229 
1230  i.e. create a simple list in 2000 and open it in 97 and 97 will
1231  claim (correctly) that it is an outline list. We can set our
1232  continuous flag in these lists to store this information.
1233  */
1234  SwNumRule* pMyNumRule = CreateNextRule(
1235  aLST.bSimpleList || (aBits1 & 0x10));
1236 
1237  WW8LSTInfo* pLSTInfo = new WW8LSTInfo(pMyNumRule, aLST);
1238  maLSTInfos.emplace_back(pLSTInfo);
1239 
1240  nRemainingPlcfLst -= cbLSTF;
1241  }
1242 
1243  // 1.2 read all LVL of all aLST
1244 
1245  sal_uInt16 nLSTInfos = static_cast< sal_uInt16 >(maLSTInfos.size());
1246  for (sal_uInt16 nList = 0; nList < nLSTInfos; ++nList)
1247  {
1248  WW8aISet aItemSet; // Character attributes from GrpprlChpx
1249 
1250  WW8LSTInfo* pListInfo = maLSTInfos[nList].get();
1251  if( !pListInfo || !pListInfo->pNumRule ) break;
1252  SwNumRule& rMyNumRule = *pListInfo->pNumRule;
1253 
1254  // 1.2.1 read specific LVL(s) for this aLST
1255 
1256  sal_uInt16 nLvlCount = static_cast< sal_uInt16 >(pListInfo->bSimpleList ? nMinLevel : nMaxLevel);
1257  pListInfo->maParaSprms.resize(nMaxLevel);
1258  for (sal_uInt16 nLevel = 0; nLevel < nLvlCount; ++nLevel)
1259  {
1260  SwNumFormat aNumFormat( rMyNumRule.Get( nLevel ) );
1261  // read LVLF
1262  bLVLOk = ReadLVL( aNumFormat, aItemSet[nLevel],
1263  pListInfo->aIdSty[nLevel], true, nLevel,
1264  pListInfo->maParaSprms[nLevel]);
1265  if( !bLVLOk )
1266  break;
1267  // and set in rMyNumRule
1268  rMyNumRule.Set( nLevel, aNumFormat );
1269  }
1270  if( !bLVLOk )
1271  break;
1272 
1273  // 1.2.2 compare ItemPools and CHPx Settings of different Levels
1274  // and create Style(s) if necessary
1275 
1276  for (sal_uInt16 nLevel = 0; nLevel < nLvlCount; ++nLevel)
1277  {
1278  bool bDummy;
1279  AdjustLVL( nLevel, rMyNumRule, aItemSet,
1280  pListInfo->aCharFormat, bDummy );
1281  }
1282  }
1283 
1284  // 2. read and save PLF LFO
1285 
1286  bOk = checkSeek(rSt, rFib.m_fcPlfLfo);
1287 
1288  if (!bOk)
1289  return;
1290 
1291  sal_Int32 nLfoCount(0);
1292  rSt.ReadInt32( nLfoCount );
1293  bOk = nLfoCount > 0;
1294 
1295  if (!bOk)
1296  return;
1297 
1298  // 2.1 read all LFO
1299 
1300  for (sal_Int32 nLfo = 0; nLfo < nLfoCount; ++nLfo)
1301  {
1302  bOk = false;
1303 
1304  WW8LFO aLFO = {};
1305 
1306  rSt.ReadUInt32( aLFO.nIdLst );
1307  rSt.SeekRel( 8 );
1308  rSt.ReadUChar( aLFO.nLfoLvl );
1309  if (!rSt.good())
1310  break;
1311  rSt.SeekRel( 3 );
1312  // as many Overrides as there are
1313  if ((nMaxLevel < aLFO.nLfoLvl) || rSt.GetError())
1314  break;
1315 
1316  // get the Parent NumRule of the current List
1317  WW8LSTInfo* pParentListInfo = GetLSTByListId(aLFO.nIdLst);
1318  if (pParentListInfo)
1319  {
1320  // Save the NumRule in this first step
1321  aLFO.pNumRule = pParentListInfo->pNumRule;
1322 
1323  // are there multiple Levels in the List?
1324  aLFO.bSimpleList = pParentListInfo->bSimpleList;
1325  }
1326  // store in Array
1327  std::unique_ptr<WW8LFOInfo> pLFOInfo(new WW8LFOInfo(aLFO));
1328  if (pParentListInfo)
1329  {
1330  //Copy the basic paragraph properties for each level from the
1331  //original list into the list format override levels.
1332  int nMaxSize = pParentListInfo->maParaSprms.size();
1333  pLFOInfo->maParaSprms.resize(nMaxSize);
1334  for (int i = 0; i < nMaxSize; ++i)
1335  pLFOInfo->maParaSprms[i] = pParentListInfo->maParaSprms[i];
1336  }
1337  m_LFOInfos.push_back(std::move(pLFOInfo));
1338  bOk = true;
1339  }
1340 
1341  if( bOk )
1342  {
1343 
1344  // 2.2 read specific LFOLVL for all LFO
1345 
1346  size_t nLFOInfos = m_LFOInfos.size();
1347  for (size_t nLfo = 0; nLfo < nLFOInfos; ++nLfo)
1348  {
1349  WW8LFOInfo& rLFOInfo = *m_LFOInfos[nLfo];
1350  // Do LFOLVL exist?
1351  if( rLFOInfo.bOverride )
1352  {
1353  WW8LSTInfo* pParentListInfo = GetLSTByListId(rLFOInfo.nIdLst);
1354  if (!pParentListInfo)
1355  break;
1356 
1357  // 2.2.1 create new NumRule for this List
1358 
1359  SwNumRule* pParentNumRule = rLFOInfo.pNumRule;
1360  OSL_ENSURE(pParentNumRule, "ww: Impossible lists, please report");
1361  if( !pParentNumRule )
1362  break;
1363  // create name-prefix for NumRule-Name
1364  // and (if necessary) for Style-Name
1365  const OUString sPrefix("WW8NumSt" + OUString::number( nLfo + 1 ));
1366  // Now assign pNumRule its actual value!!!
1367  // (it contained the parent NumRule up to this point)
1368 
1369  // check if a Style is referencing this LFO
1370  if( USHRT_MAX > rReader.StyleUsingLFO( nLfo ) )
1371  {
1372  sal_uInt16 nRul = rDoc.MakeNumRule(
1373  rDoc.GetUniqueNumRuleName( &sPrefix ), pParentNumRule);
1374  rLFOInfo.pNumRule = rDoc.GetNumRuleTable()[ nRul ];
1375  rLFOInfo.pNumRule->SetAutoRule(false);
1376  }
1377  else
1378  {
1379  sal_uInt16 nRul = rDoc.MakeNumRule(
1380  rDoc.GetUniqueNumRuleName(), pParentNumRule);
1381  rLFOInfo.pNumRule = rDoc.GetNumRuleTable()[ nRul ];
1382  rLFOInfo.pNumRule->SetAutoRule(true); // = default
1383  }
1384 
1385  // 2.2.2 read all LFOLVL (and LVL) for the new NumRule
1386 
1387  WW8aISet aItemSet; // Character attributes from GrpprlChpx
1388  WW8aCFormat aCharFormat = {}; // Character Style Pointer
1389 
1390  //2.2.2.0 skip inter-group of override header ?
1391  //See #i25438# for why I moved this here, compare
1392  //that original bugdoc's binary to what it looks like
1393  //when resaved with word, i.e. there is always a
1394  //4 byte header, there might be more than one if
1395  //that header was 0xFFFFFFFF, e.g. #114412# ?
1396  sal_uInt32 nTest;
1397  rSt.ReadUInt32( nTest );
1398  do
1399  {
1400  nTest = 0;
1401  rSt.ReadUInt32( nTest );
1402  }
1403  while (nTest == 0xFFFFFFFF);
1404  rSt.SeekRel(-4);
1405 
1406  for (sal_uInt8 nLevel = 0; nLevel < rLFOInfo.nLfoLvl; ++nLevel)
1407  {
1408  WW8LFOLVL aLFOLVL;
1409  bLVLOk = false;
1410 
1411  // 2.2.2.1 read LFOLVL
1412 
1413  rSt.ReadInt32( aLFOLVL.nStartAt );
1414  sal_uInt8 aBits1(0);
1415  rSt.ReadUChar( aBits1 );
1416  rSt.SeekRel( 3 );
1417  if (rSt.GetError())
1418  break;
1419 
1420  // Note: MS writes the Override-Level-Number into 4 bit.
1421  // We do not! (See comment at "struct WW8LFOInfo")
1422  aLFOLVL.nLevel = aBits1 & 0x0F;
1423  if( (0xFF > aBits1) &&
1424  (nMaxLevel > aLFOLVL.nLevel) )
1425  {
1426  if (aBits1 & 0x10)
1427  aLFOLVL.bStartAt = true;
1428  else
1429  aLFOLVL.bStartAt = false;
1430 
1431  // 2.2.2.2 load dedicated LVL if necessary
1432 
1433  SwNumFormat aNumFormat(
1434  rLFOInfo.pNumRule->Get(aLFOLVL.nLevel));
1435  if (aBits1 & 0x20)
1436  {
1437  aLFOLVL.bFormat = true;
1438  // if bStartup is true, replace Startup-Level
1439  // with the LVLF that is saved in the LVL
1440  bLVLOk = nLevel < rLFOInfo.maParaSprms.size() &&
1441  ReadLVL(aNumFormat, aItemSet[nLevel],
1442  pParentListInfo->aIdSty[nLevel],
1443  aLFOLVL.bStartAt, nLevel,
1444  rLFOInfo.maParaSprms[nLevel]);
1445 
1446  if (!bLVLOk)
1447  break;
1448  }
1449  else if (aLFOLVL.bStartAt)
1450  {
1451  aNumFormat.SetStart(
1452  writer_cast<sal_uInt16>(aLFOLVL.nStartAt));
1453  }
1454 
1455  // 2.2.2.3 Set NumFormat in NumRule
1456 
1457  rLFOInfo.pNumRule->Set(aLFOLVL.nLevel, aNumFormat);
1458  }
1459  bLVLOk = true;
1460 
1461  if (nMaxLevel > aLFOLVL.nLevel)
1462  rLFOInfo.maOverrides[aLFOLVL.nLevel] = aLFOLVL;
1463  }
1464  if( !bLVLOk )
1465  break;
1466 
1467  // 2.2.3 adjust LVL of the new NumRule
1468 
1469  bool bNewCharFormatCreated = false;
1470  for (sal_uInt8 nLevel = 0; nLevel < rLFOInfo.nLfoLvl; ++nLevel)
1471  {
1472  AdjustLVL( nLevel, *rLFOInfo.pNumRule, aItemSet, aCharFormat,
1473  bNewCharFormatCreated, sPrefix );
1474  }
1475  }
1476  }
1477  }
1478  // and we're done!
1479  rSt.Seek( nOriginalPos );
1480 }
1481 
1482 WW8ListManager::~WW8ListManager() COVERITY_NOEXCEPT_FALSE
1483 {
1484  /*
1485  named lists remain in document
1486  unused automatic lists are removed from document (DelNumRule)
1487  */
1488  for(auto & rpInfo : maLSTInfos)
1489  {
1490  if (rpInfo->pNumRule && !rpInfo->bUsedInDoc &&
1491  rpInfo->pNumRule->IsAutoRule())
1492  {
1493  rDoc.DelNumRule(rpInfo->pNumRule->GetName());
1494  }
1495  rpInfo.reset();
1496  }
1497  for (auto aIter = m_LFOInfos.rbegin(); aIter != m_LFOInfos.rend(); ++aIter)
1498  {
1499  if ((*aIter)->bOverride
1500  && (*aIter)->pNumRule
1501  && !(*aIter)->bUsedInDoc
1502  && (*aIter)->pNumRule->IsAutoRule())
1503  {
1504  rDoc.DelNumRule( (*aIter)->pNumRule->GetName() );
1505  }
1506  }
1507 }
1508 
1509 static bool IsEqualFormatting(const SwNumRule &rOne, const SwNumRule &rTwo)
1510 {
1511  bool bRet =
1512  (
1513  rOne.GetRuleType() == rTwo.GetRuleType() &&
1514  rOne.IsContinusNum() == rTwo.IsContinusNum() &&
1515  rOne.IsAbsSpaces() == rTwo.IsAbsSpaces() &&
1516  rOne.GetPoolFormatId() == rTwo.GetPoolFormatId() &&
1517  rOne.GetPoolHelpId() == rTwo.GetPoolHelpId() &&
1518  rOne.GetPoolHlpFileId() == rTwo.GetPoolHlpFileId()
1519  );
1520 
1521  if (bRet)
1522  {
1523  for (sal_uInt8 n = 0; n < MAXLEVEL; ++n )
1524  {
1525  //The SvxNumberFormat compare, not the SwNumFormat compare
1526  const SvxNumberFormat &rO = rOne.Get(n);
1527  const SvxNumberFormat &rT = rTwo.Get(n);
1528  if (rO != rT)
1529  {
1530  bRet = false;
1531  break;
1532  }
1533  }
1534  }
1535  return bRet;
1536 }
1537 
1539  const sal_uInt8 nLevel, std::vector<sal_uInt8> &rParaSprms, SwTextNode *pNode)
1540 {
1541  if (m_LFOInfos.size() <= nLFOPosition)
1542  return nullptr;
1543 
1544  WW8LFOInfo& rLFOInfo = *m_LFOInfos[nLFOPosition];
1545 
1546  bool bFirstUse = !rLFOInfo.bUsedInDoc;
1547  rLFOInfo.bUsedInDoc = true;
1548 
1549  if( !rLFOInfo.pNumRule )
1550  return nullptr;
1551 
1552  // #i25545#
1553  // #i100132# - a number format does not have to exist on given list level
1554  SwNumFormat aFormat(rLFOInfo.pNumRule->Get(nLevel));
1555 
1556  if (rReader.IsRightToLeft() && nLastLFOPosition != nLFOPosition) {
1557  if ( aFormat.GetNumAdjust() == SvxAdjust::Right)
1558  aFormat.SetNumAdjust(SvxAdjust::Left);
1559  else if ( aFormat.GetNumAdjust() == SvxAdjust::Left)
1560  aFormat.SetNumAdjust(SvxAdjust::Right);
1561  rLFOInfo.pNumRule->Set(nLevel, aFormat);
1562  }
1563  nLastLFOPosition = nLFOPosition;
1564  /*
1565  #i1869#
1566  If this list has had its bits set in word 2000 to pretend that it is a
1567  simple list from the point of view of the user, then it is almost
1568  certainly a simple continuous list, and we will try to keep it like that.
1569  Otherwise when we save again it will be shown as the true outline list
1570  that it is, confusing the user that just wanted what they thought was a
1571  simple list. On the other hand it is possible that some of the other levels
1572  were used by the user, in which case we will not pretend anymore that it
1573  is a simple list. Something that word 2000 does anyway, that 97 didn't, to
1574  my bewilderment.
1575  */
1576  if (nLevel && rLFOInfo.pNumRule->IsContinusNum())
1577  rLFOInfo.pNumRule->SetContinusNum(false);
1578 
1579  if( (!rLFOInfo.bOverride) && (!rLFOInfo.bLSTbUIDSet) )
1580  {
1581  WW8LSTInfo* pParentListInfo = GetLSTByListId( rLFOInfo.nIdLst );
1582  if( pParentListInfo )
1583  pParentListInfo->bUsedInDoc = true;
1584  rLFOInfo.bLSTbUIDSet = true;
1585  }
1586 
1587  if (rLFOInfo.maParaSprms.size() > nLevel)
1588  rParaSprms = rLFOInfo.maParaSprms[nLevel];
1589 
1590  SwNumRule *pRet = rLFOInfo.pNumRule;
1591 
1592  bool bRestart(false);
1593  sal_uInt16 nStart(0);
1594  bool bNewstart(false);
1595  /*
1596  Note: If you fiddle with this then you have to make sure that #i18322#
1597  #i13833#, #i20095# and #112466# continue to work
1598 
1599  Check if there were overrides for this level
1600  */
1601  if (rLFOInfo.bOverride && nLevel < rLFOInfo.nLfoLvl)
1602  {
1603  WW8LSTInfo* pParentListInfo = GetLSTByListId(rLFOInfo.nIdLst);
1604  OSL_ENSURE(pParentListInfo, "ww: Impossible lists, please report");
1605  if (pParentListInfo && pParentListInfo->pNumRule)
1606  {
1607  const WW8LFOLVL &rOverride = rLFOInfo.maOverrides[nLevel];
1608  bool bNoChangeFromParent =
1609  IsEqualFormatting(*pRet, *(pParentListInfo->pNumRule));
1610 
1611  //If so then I think word still uses the parent (maybe)
1612  if (bNoChangeFromParent)
1613  {
1614  pRet = pParentListInfo->pNumRule;
1615 
1616  //did it not affect start at value ?
1617  if (bFirstUse && rOverride.bStartAt)
1618  {
1619  const SwNumFormat &rFormat =
1620  pParentListInfo->pNumRule->Get(nLevel);
1621  if (
1622  rFormat.GetStart() ==
1623  rLFOInfo.maOverrides[nLevel].nStartAt
1624  )
1625  {
1626  bRestart = true;
1627  }
1628  else
1629  {
1630  bNewstart = true;
1631  nStart = writer_cast<sal_uInt16>
1632  (rLFOInfo.maOverrides[nLevel].nStartAt);
1633  }
1634  }
1635 
1636  pParentListInfo->bUsedInDoc = true;
1637  }
1638  }
1639  }
1640 
1641  if (pNode)
1642  {
1643  pNode->SetAttrListLevel(nLevel);
1644 
1645  if (bRestart || bNewstart)
1646  pNode->SetListRestart(true);
1647  if (bNewstart)
1648  pNode->SetAttrListRestartValue(nStart);
1649  }
1650  return pRet;
1651 }
1652 
1653 // SwWW8ImplReader: append a List to a Style or Paragraph
1654 
1656  SwWW8StyInf& rStyleInfo)
1657 {
1658  bool bRes = true;
1659  if( rStyleInfo.m_pFormat && rStyleInfo.m_bColl )
1660  {
1661  bRes = m_rDoc.SetTextFormatColl(rRg, static_cast<SwTextFormatColl*>(rStyleInfo.m_pFormat));
1662  SwTextNode* pTextNode = m_pPaM->GetNode().GetTextNode();
1663  OSL_ENSURE( pTextNode, "No Text-Node at PaM-Position" );
1664  if ( !pTextNode )
1665  {
1666  // make code robust
1667  return bRes;
1668  }
1669 
1670  const SwNumRule * pNumRule = pTextNode->GetNumRule(); // #i27610#
1671 
1673  ! (pNumRule && pNumRule->IsOutlineRule()) ) // #i27610#
1674  {
1675  pTextNode->ResetAttr( RES_PARATR_NUMRULE );
1676  }
1677 
1678  if (USHRT_MAX > rStyleInfo.m_nLFOIndex && WW8ListManager::nMaxLevel
1679  > rStyleInfo.m_nListLevel)
1680  {
1681  const bool bApplyListStyle = false;
1682  RegisterNumFormatOnTextNode(rStyleInfo.m_nLFOIndex, rStyleInfo.m_nListLevel,
1683  bApplyListStyle);
1684  }
1685  }
1686  return bRes;
1687 }
1688 
1689 void UseListIndent(SwWW8StyInf &rStyle, const SwNumFormat &rFormat)
1690 {
1691  // #i86652#
1693  {
1694  const auto nAbsLSpace = rFormat.GetAbsLSpace();
1695  const tools::Long nListFirstLineIndent = GetListFirstLineIndent(rFormat);
1696  SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*rStyle.m_pFormat, RES_LR_SPACE));
1697  aLR.SetTextLeft(nAbsLSpace);
1698  aLR.SetTextFirstLineOffset(writer_cast<short>(nListFirstLineIndent));
1699  rStyle.m_pFormat->SetFormatAttr(aLR);
1700  rStyle.m_bListRelevantIndentSet = true;
1701  }
1702 }
1703 
1704 void SetStyleIndent(SwWW8StyInf &rStyle, const SwNumFormat &rFormat)
1705 {
1707  return;
1708 
1709  SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*rStyle.m_pFormat, RES_LR_SPACE));
1710  if (rStyle.m_bListRelevantIndentSet)
1711  {
1712 
1713  SyncIndentWithList( aLR, rFormat, false, false ); // #i103711#, #i105414#
1714  }
1715  else
1716  {
1717  aLR.SetTextLeft(0);
1718  aLR.SetTextFirstLineOffset(0);
1719  }
1720  rStyle.m_pFormat->SetFormatAttr(aLR);
1721 }
1722 
1723 void SwWW8ImplReader::SetStylesList(sal_uInt16 nStyle, sal_uInt16 nCurrentLFO,
1724  sal_uInt8 nCurrentLevel)
1725 {
1726  if (nStyle >= m_vColl.size())
1727  return;
1728 
1729  SwWW8StyInf &rStyleInf = m_vColl[nStyle];
1730  if (!rStyleInf.m_bValid)
1731  return;
1732 
1733  OSL_ENSURE(m_pCurrentColl, "Cannot be called outside of style import");
1734  // Phase 1: Numbering attributes when reading a StyleDef
1735  if( !m_pCurrentColl )
1736  return;
1737 
1738  if (nCurrentLFO < USHRT_MAX)
1739  rStyleInf.m_nLFOIndex = nCurrentLFO;
1740  if (nCurrentLevel < MAXLEVEL)
1741  rStyleInf.m_nListLevel = nCurrentLevel;
1742 
1743  // only save the Parameters for now. The actual List will be appended
1744  // at a later point, when the Listdefinitions is read...
1745  if (rStyleInf.m_nLFOIndex < USHRT_MAX && rStyleInf.m_nListLevel < WW8ListManager::nMaxLevel)
1746  {
1747  std::vector<sal_uInt8> aParaSprms;
1748  SwNumRule* pNmRule = m_xLstManager->GetNumRuleForActivation(
1749  rStyleInf.m_nLFOIndex, rStyleInf.m_nListLevel, aParaSprms);
1750  if (pNmRule)
1751  UseListIndent(rStyleInf, pNmRule->Get(rStyleInf.m_nListLevel));
1752  }
1753 }
1754 
1756 {
1757 
1758  if (nStyle >= m_vColl.size())
1759  return;
1760 
1761  SwWW8StyInf &rStyleInf = m_vColl[nStyle];
1762  if (!(rStyleInf.m_bValid && rStyleInf.m_pFormat))
1763  return;
1764 
1765  //Save old pre-list modified indent, which are the word indent values
1766  rStyleInf.maWordLR.reset(ItemGet<SvxLRSpaceItem>(*rStyleInf.m_pFormat, RES_LR_SPACE).Clone());
1767 
1768  // Phase 2: refresh StyleDef after reading all Lists
1769  if (rStyleInf.m_nLFOIndex < USHRT_MAX && rStyleInf.m_nListLevel < WW8ListManager::nMaxLevel)
1770  {
1771  std::vector<sal_uInt8> aParaSprms;
1772  SwNumRule* pNmRule = m_xLstManager->GetNumRuleForActivation(
1773  rStyleInf.m_nLFOIndex, rStyleInf.m_nListLevel, aParaSprms);
1774 
1775  if (pNmRule != nullptr)
1776  {
1777  if (rStyleInf.IsWW8BuiltInHeadingStyle()
1778  && rStyleInf.HasWW8OutlineLevel())
1779  {
1780  rStyleInf.m_pOutlineNumrule = pNmRule;
1781  }
1782  else
1783  {
1784  rStyleInf.m_pFormat->SetFormatAttr(
1785  SwNumRuleItem(pNmRule->GetName()));
1786  rStyleInf.m_bHasStyNumRule = true;
1787  }
1788 
1789  SetStyleIndent(rStyleInf, pNmRule->Get(rStyleInf.m_nListLevel));
1790  }
1791  }
1792 }
1793 
1795  sal_uInt8 nCurrentLevel,
1796  const bool bSetAttr)
1797 {
1798  // Note: the method appends NumRule to the Text Node if
1799  // bSetAttr (of course the lists have to be read before)
1800  // and only sets the Level. It does not check if there is a NumRule
1801  // attached to the STYLE !!!
1802 
1803  if (!m_xLstManager) // are all list declarations read?
1804  return;
1805 
1806  SwTextNode* pTextNd = m_pPaM->GetNode().GetTextNode();
1807  OSL_ENSURE(pTextNd, "No Text-Node at PaM-Position");
1808  if (!pTextNd)
1809  return;
1810 
1811  // WW8ListManager::nMaxLevel indicates body text, cancelling an inherited numbering.
1812  if (nCurrentLFO < USHRT_MAX && nCurrentLevel == WW8ListManager::nMaxLevel)
1813  {
1814  pTextNd->SetAttr(SwNumRuleItem(OUString()));
1815  return;
1816  }
1817 
1818  // Undefined listLevel is treated as the first level with valid numbering rule.
1819  // TODO:This doesn't allow for inheriting from a style(HOW?), but it matches previous behaviour.
1820  if (nCurrentLFO < USHRT_MAX && nCurrentLevel == MAXLEVEL)
1821  nCurrentLevel = 0;
1822 
1823  std::vector<sal_uInt8> aParaSprms;
1824  const SwNumRule* pRule = bSetAttr ?
1825  m_xLstManager->GetNumRuleForActivation( nCurrentLFO, nCurrentLevel,
1826  aParaSprms, pTextNd) : nullptr;
1827 
1828  if (pRule == nullptr && bSetAttr)
1829  return;
1830 
1831  if (bSetAttr && pTextNd->GetNumRule() != pRule
1832  && (pTextNd->GetNumRule() != m_rDoc.GetOutlineNumRule()
1833  || pRule != m_pChosenWW8OutlineStyle))
1834  {
1835  // Now this is either not a part of Chapter Numbering,
1836  // or else it is using a different numRule than the one copied to Chapter Numbering.
1838  : pRule->GetName();
1839  pTextNd->SetAttr(SwNumRuleItem(sName));
1840  }
1841  pTextNd->SetAttrListLevel(nCurrentLevel);
1842 
1843  // <IsCounted()> state of text node has to be adjusted accordingly.
1844  if ( /*nCurrentLevel >= 0 &&*/ nCurrentLevel < MAXLEVEL )
1845  {
1846  pTextNd->SetCountedInList( true );
1847  }
1848 
1849  // #i99822#
1850  // Direct application of the list level formatting no longer
1851  // needed for list levels of mode LABEL_ALIGNMENT
1852  bool bApplyListLevelIndentDirectlyAtPara(true);
1853  {
1854  if (pTextNd->GetNumRule() && nCurrentLevel < MAXLEVEL)
1855  {
1856  const SwNumFormat& rFormat = pTextNd->GetNumRule()->Get(nCurrentLevel);
1857  if (rFormat.GetPositionAndSpaceMode()
1859  {
1860  bApplyListLevelIndentDirectlyAtPara = false;
1861  }
1862  }
1863  }
1864 
1865  if (!bApplyListLevelIndentDirectlyAtPara)
1866  return;
1867 
1868  std::unique_ptr<SfxItemSet> xListIndent(new SfxItemSet(m_rDoc.GetAttrPool(), svl::Items<RES_LR_SPACE,
1869  RES_LR_SPACE>));
1870  const SvxLRSpaceItem *pItem = static_cast<const SvxLRSpaceItem*>(
1871  GetFormatAttr(RES_LR_SPACE));
1872  OSL_ENSURE(pItem, "impossible");
1873  if (pItem)
1874  xListIndent->Put(*pItem);
1875 
1876  /*
1877  Take the original paragraph sprms attached to this list level
1878  formatting and apply them to the paragraph. I'm convinced that
1879  this is exactly what word does.
1880  */
1881  if (short nLen = static_cast< short >(aParaSprms.size()))
1882  {
1883  std::unique_ptr<SfxItemSet> xOldCurrentItemSet(SetCurrentItemSet(std::move(xListIndent)));
1884 
1885  sal_uInt8* pSprms1 = aParaSprms.data();
1886  while (0 < nLen)
1887  {
1888  sal_uInt16 nL1 = ImportSprm(pSprms1, nLen);
1889  nLen = nLen - nL1;
1890  pSprms1 += nL1;
1891  }
1892 
1893  xListIndent = SetCurrentItemSet(std::move(xOldCurrentItemSet));
1894  }
1895 
1896  if (const SvxLRSpaceItem *pLR = xListIndent->GetItem<SvxLRSpaceItem>(RES_LR_SPACE))
1897  {
1898  m_xCtrlStck->NewAttr(*m_pPaM->GetPoint(), *pLR);
1899  m_xCtrlStck->SetAttr(*m_pPaM->GetPoint(), RES_LR_SPACE);
1900  }
1901 }
1902 
1903 void SwWW8ImplReader::RegisterNumFormat(sal_uInt16 nCurrentLFO, sal_uInt8 nCurrentLevel)
1904 {
1905  // Are we reading the StyleDef ?
1906  if (m_pCurrentColl)
1907  SetStylesList( m_nCurrentColl , nCurrentLFO, nCurrentLevel);
1908  else
1909  RegisterNumFormatOnTextNode(nCurrentLFO, nCurrentLevel);
1910 }
1911 
1912 void SwWW8ImplReader::Read_ListLevel(sal_uInt16, const sal_uInt8* pData,
1913  short nLen)
1914 {
1915  if (m_xPlcxMan && m_xPlcxMan->GetDoingDrawTextBox())
1916  return;
1917 
1918  if( nLen < 0 )
1919  {
1920  // the current level is finished, what should we do ?
1922  if (m_xStyles && !m_bVer67)
1923  m_xStyles->mnWwNumLevel = 0;
1924  }
1925  else
1926  {
1927  // security check
1928  if( !pData )
1929  return;
1930 
1931  // the Streamdata is zero based
1932  m_nListLevel = *pData;
1933 
1934  if (m_xStyles && !m_bVer67)
1935  {
1936  /*
1937  if this is the case, then if the numbering is actually stored in
1938  winword 6 format, and its likely that sprmPIlvl has been abused
1939  to set the ww6 list level information which we will need when we
1940  reach the true ww6 list def. So set it now
1941  */
1942  m_xStyles->mnWwNumLevel = m_nListLevel;
1943  }
1944 
1945  // Treat an invalid level as body-level
1948 
1950  if (USHRT_MAX > m_nLFOPosition)
1951  {
1952  assert(false && "m_nLFOPosition is usually reset immediately, so we rarely ever get here.");
1953  m_nLFOPosition = USHRT_MAX;
1955  }
1956  }
1957 }
1958 
1959 void SwWW8ImplReader::Read_LFOPosition(sal_uInt16, const sal_uInt8* pData,
1960  short nLen)
1961 {
1962  if (m_xPlcxMan && m_xPlcxMan->GetDoingDrawTextBox())
1963  return;
1964 
1965  if( nLen < 0 )
1966  {
1967  // the current level is finished, what should we do ?
1968  m_nLFOPosition = USHRT_MAX;
1970  }
1971  else
1972  {
1973  // security check
1974  if( !pData )
1975  return;
1976 
1977  short nData = SVBT16ToUInt16( pData );
1978  if( 0 >= nData )
1979  {
1980  // disable the numbering/list style apply to the paragraph or the style
1981 
1982  /*
1983  If you have a paragraph in word with left and/or hanging indent
1984  and remove its numbering, then the indentation appears to get
1985  reset, but not back to the base style, instead it goes to a blank
1986  setting.
1987  Unless it's a broken ww6 list in 97 in which case more hackery is
1988  required, some more details about broken ww6 list in
1989  ww8par6.cxx#SwWW8ImplReader::Read_LR
1990  */
1991 
1992  if (m_pCurrentColl)
1993  {
1994  // here a "named" style is being configured
1995 
1996  // disable the numbering/list in the style currently configured
1998 
1999  // reset/blank the indent
2001 
2002  // These sprmPIlfos are supposed to indicate "cancel" numbering.
2003  // Since m_nLFOPosition is "data - 1", then zero becomes USHRT_MAX
2004  // which is no good since that indicates "unspecified, available for inheritance".
2005  // So instead use USHRT_MAX-1 for indicating an explicit "cancel numbering".
2006  RegisterNumFormat(USHRT_MAX-1, MAXLEVEL);
2007  }
2008  else if (SwTextNode* pTextNode = m_pPaM->GetNode().GetTextNode())
2009  {
2010  // here a paragraph is being directly formatted
2011 
2012  // empty the numbering/list style applied to the current paragraph
2013  SwNumRuleItem aEmptyRule;
2014  pTextNode->SetAttr( aEmptyRule );
2015 
2016  // create an empty SvxLRSpaceItem
2017  std::shared_ptr<SvxLRSpaceItem> aLR(std::make_shared<SvxLRSpaceItem>(RES_LR_SPACE));
2018 
2019  // replace it with the one of the current node if it exist
2020  const SfxPoolItem* pLR = GetFormatAttr(RES_LR_SPACE);
2021  if( pLR )
2022  aLR.reset(static_cast<SvxLRSpaceItem*>(pLR->Clone()));
2023 
2024  // reset/blank the left indent (and only the left)
2025  aLR->SetTextLeft(0);
2026  aLR->SetTextFirstLineOffset(0);
2027 
2028  // apply the modified SvxLRSpaceItem to the current paragraph
2029  pTextNode->SetAttr( *aLR );
2030  }
2031 
2032  m_nLFOPosition = USHRT_MAX;
2033  }
2034  else // nData in (0..0x7FFF]
2035  {
2036  m_nLFOPosition = o3tl::narrowing<sal_uInt16>(nData)-1; // m_nLFOPosition in [0..0x7FFF)
2037  /*
2038  If we are a ww8+ style with ww7- style lists then there is a
2039  bizarre broken word bug where when the list is removed from a para
2040  the ww6 list first line indent still affects the first line
2041  indentation. Setting this flag will allow us to recover from this
2042  braindeadness
2043  */
2044  if (m_pCurrentColl && (m_nLFOPosition == 2047-1) && m_nCurrentColl < m_vColl.size())
2045  m_vColl[m_nCurrentColl].m_bHasBrokenWW6List = true;
2046 
2047  // here the stream data is 1-based, we subtract ONE
2048  if (m_nLFOPosition != 2047-1) //Normal ww8+ list behaviour
2049  {
2051  m_nLFOPosition = USHRT_MAX;
2053  }
2054  else if (m_xPlcxMan && m_xPlcxMan->HasParaSprm(NS_sprm::LN_PAnld).pSprm)
2055  {
2056  /*
2057  #i8114# Horrific backwards compatible ww7- lists in ww8+
2058  docs
2059  */
2060  m_nListLevel = std::min<sal_uInt8>(WW8ListManager::nMaxLevel, m_nListLevel);
2061  Read_ANLevelNo(13 /*equiv ww7- sprm no*/, &m_nListLevel, 1);
2062  }
2063  }
2064  }
2065 }
2066 
2067 // Reading Controls
2068 
2070  WW8_CP nStart, SwWw8ControlType nWhich )
2071 {
2072  bool bRet=false;
2073  /*
2074  * Save the reader state and process the sprms for this anchor cp.
2075  * Doing so will set the nPicLocFc to the offset to find the hypertext
2076  * data in the data stream.
2077  */
2078  WW8_CP nEndCp = nStart+1; //Only interested in the single 0x01 character
2079 
2080  WW8ReaderSave aSave(this,nStart);
2081 
2082  WW8PLCFManResult aRes;
2083  nStart = m_xPlcxMan->Where();
2084  while(nStart <= nEndCp)
2085  {
2086  if ( m_xPlcxMan->Get(&aRes)
2087  && aRes.pMemPos && aRes.nSprmId )
2088  {
2089  //only interested in sprms which would set nPicLocFc
2090  if ( (68 == aRes.nSprmId) || (0x6A03 == aRes.nSprmId) )
2091  {
2092  Read_PicLoc( aRes.nSprmId, aRes.pMemPos +
2093  m_xSprmParser->DistanceToData(aRes.nSprmId), 4);
2094  break;
2095  }
2096  }
2097  m_xPlcxMan->advance();
2098  nStart = m_xPlcxMan->Where();
2099  }
2100  sal_uLong nOffset = m_nPicLocFc;
2101  aSave.Restore(this);
2102 
2103  sal_uLong nOldPos = m_pDataStream->Tell();
2104  WW8_PIC aPic;
2105  m_pDataStream->Seek( nOffset);
2106  PicRead( m_pDataStream, &aPic, m_bVer67);
2107 
2108  if((aPic.lcb > 0x3A) && !m_pDataStream->GetError() )
2109  {
2110  aFormula.FormulaRead(nWhich,m_pDataStream);
2111  bRet = true;
2112  }
2113 
2114  /*
2115  There is a problem with aPic, the WW8_PIC is always used even though it
2116  is too big for the WW95 files, it needs to be modified to check the
2117  version C.
2118  */
2119  m_pDataStream->Seek( nOldPos );
2120  return bRet;
2121 }
2122 
2124 {
2125  const uno::Reference< lang::XMultiServiceFactory > & rServiceFactory =
2126  GetServiceFactory();
2127 
2128  if(!rServiceFactory.is())
2129  return;
2130 
2131  awt::Size aSz;
2132  uno::Reference< form::XFormComponent> xFComp;
2133 
2134  if (rFormula.Import(rServiceFactory, xFComp, aSz))
2135  {
2136  uno::Reference <drawing::XShape> xShapeRef;
2137  if (InsertControl(xFComp, aSz, &xShapeRef, false))
2138  GetShapes()->add(xShapeRef);
2139  }
2140 }
2141 
2143  SvStream *pDataStream)
2144 {
2145  sal_uInt8 nField;
2146 
2147  // The following is a FFData structure as described in
2148  // Microsoft's DOC specification (chapter 2.9.78)
2149  sal_uInt32 nVersion = 0;
2150  pDataStream->ReadUInt32(nVersion);
2151  // An unsigned integer that MUST be 0xFFFFFFFF
2152  if (nVersion != 0xFFFFFFFF)
2153  {
2154  SAL_WARN("sw.ww8", "Parsing error: invalid header for FFData");
2155  return; // bail out
2156  }
2157 
2158  // might be better to read the bits as a 16 bit word
2159  // ( like it is in the spec. )
2160  sal_uInt8 bits1 = 0;
2161  pDataStream->ReadUChar( bits1 );
2162  sal_uInt8 bits2 = 0;
2163  pDataStream->ReadUChar( bits2 );
2164 
2165  sal_uInt8 iType = ( bits1 & 0x3 );
2166 
2167  // we should verify that bits.iType & nWhich concur
2168  OSL_ENSURE( iType == nWhich, "something wrong, expect control type read from stream doesn't match nWhich passed in");
2169  if ( iType != nWhich )
2170  return; // bail out
2171 
2172  sal_uInt8 iRes = (bits1 & 0x7C) >> 2;
2173 
2174  pDataStream->ReadUInt16( mnMaxLen );
2175 
2176  sal_uInt16 hps = 0;
2177  pDataStream->ReadUInt16( hps );
2178 
2179  // xstzName
2180  msTitle = read_uInt16_BeltAndBracesString(*pDataStream);
2181 
2182  if (nWhich == WW8_CT_EDIT)
2183  { // Field is a textbox
2184  // Default text
2185  // xstzTextDef
2187  }
2188  else
2189  {
2190  // CheckBox or ComboBox
2191  sal_uInt16 wDef = 0;
2192  pDataStream->ReadUInt16( wDef );
2193  mnChecked = wDef; // default
2194  if (nWhich == WW8_CT_CHECKBOX)
2195  {
2196  if ( iRes != 25 )
2197  mnChecked = iRes;
2198  msDefault = ( wDef == 0 ) ? OUStringLiteral( u"0" ) : OUStringLiteral( u"1" );
2199  }
2200  }
2201  // xstzTextFormat
2203  // xstzHelpText
2204  msHelp = read_uInt16_BeltAndBracesString(*pDataStream);
2205  // xstzStatText
2207 
2208  // xstzEntryMcr
2210  //xstzExitMcr
2212 
2213  if (nWhich == WW8_CT_DROPDOWN)
2214  {
2215  bool bAllOk = true;
2216  // SSTB (see Spec. 2.2.4)
2217  sal_uInt16 fExtend = 0;
2218  pDataStream->ReadUInt16( fExtend );
2219  sal_uInt16 nStringsCnt = 0;
2220 
2221  // Isn't it that if fExtend isn't 0xFFFF then fExtend actually
2222  // doesn't exist and we really have just read nStringsCnt ( or cData )?
2223  if (fExtend != 0xFFFF)
2224  bAllOk = false;
2225  pDataStream->ReadUInt16( nStringsCnt );
2226 
2227  // I guess this should be zero ( and we should ensure that )
2228  sal_uInt16 cbExtra = 0;
2229  pDataStream->ReadUInt16( cbExtra );
2230 
2231  OSL_ENSURE(bAllOk, "Unknown formfield dropdown list structure");
2232  if (!bAllOk) //Not as expected, don't risk it at all.
2233  nStringsCnt = 0;
2234  const size_t nMinRecordSize = sizeof(sal_uInt16);
2235  const size_t nMaxRecords = pDataStream->remainingSize() / nMinRecordSize;
2236  if (nStringsCnt > nMaxRecords)
2237  {
2238  SAL_WARN("sw.ww8", "Parsing error: " << nMaxRecords <<
2239  " max possible entries, but " << nStringsCnt << " claimed, truncating");
2240  nStringsCnt = nMaxRecords;
2241  }
2242  maListEntries.reserve(nStringsCnt);
2243  for (sal_uInt32 nI = 0; nI < nStringsCnt; ++nI)
2244  {
2245  OUString sEntry = read_uInt16_PascalString(*pDataStream);
2246  maListEntries.push_back(sEntry);
2247  }
2248  }
2249  mfDropdownIndex = iRes;
2250 
2251  mbHelp = bits1 & 0x80;
2252 
2253  nField = bits2;
2254  mfToolTip = nField & 0x01;
2255  mfNoMark = (nField & 0x02)>>1;
2256  mfType = (nField & 0x38)>>3;
2257  mfUnused = (nField & 0xE0)>>5;
2258 }
2259 
2261  : WW8FormulaControl(SL::aListBox, rR)
2262 {
2263 }
2264 
2265 //Miserable hack to get a hardcoded guesstimate of the size of a list dropdown
2266 //box's first entry to set as the lists default size
2267 awt::Size SwWW8ImplReader::MiserableDropDownFormHack(const OUString &rString,
2268  uno::Reference<beans::XPropertySet> const & rPropSet)
2269 {
2270  awt::Size aRet;
2271  struct CtrlFontMapEntry
2272  {
2273  sal_uInt16 nWhichId;
2274  const char* pPropNm;
2275  };
2276  const CtrlFontMapEntry aMapTable[] =
2277  {
2278  { RES_CHRATR_COLOR, "TextColor" },
2279  { RES_CHRATR_FONT, "FontName" },
2280  { RES_CHRATR_FONTSIZE, "FontHeight" },
2281  { RES_CHRATR_WEIGHT, "FontWeight" },
2282  { RES_CHRATR_UNDERLINE, "FontUnderline" },
2283  { RES_CHRATR_CROSSEDOUT, "FontStrikeout" },
2284  { RES_CHRATR_POSTURE, "FontSlant" },
2285  { 0, nullptr }
2286  };
2287 
2288  vcl::Font aFont;
2289  uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
2290  rPropSet->getPropertySetInfo();
2291 
2292  uno::Any aTmp;
2293  for (const CtrlFontMapEntry* pMap = aMapTable; pMap->nWhichId; ++pMap)
2294  {
2295  bool bSet = true;
2296  const SfxPoolItem* pItem = GetFormatAttr( pMap->nWhichId );
2297  OSL_ENSURE(pItem, "Impossible");
2298  if (!pItem)
2299  continue;
2300 
2301  switch ( pMap->nWhichId )
2302  {
2303  case RES_CHRATR_COLOR:
2304  {
2305  OUString aNm;
2306  if (xPropSetInfo->hasPropertyByName(aNm = "TextColor"))
2307  {
2308  aTmp <<= static_cast<sal_Int32>(static_cast<const SvxColorItem*>(pItem)->GetValue());
2309  rPropSet->setPropertyValue(aNm, aTmp);
2310  }
2311  }
2312  aFont.SetColor(static_cast<const SvxColorItem*>(pItem)->GetValue());
2313  break;
2314  case RES_CHRATR_FONT:
2315  {
2316  const SvxFontItem *pFontItem = static_cast<const SvxFontItem *>(pItem);
2317  OUString aNm;
2318  if (xPropSetInfo->hasPropertyByName(aNm = "FontStyleName"))
2319  {
2320  aTmp <<= pFontItem->GetStyleName();
2321  rPropSet->setPropertyValue( aNm, aTmp );
2322  }
2323  if (xPropSetInfo->hasPropertyByName(aNm = "FontFamily"))
2324  {
2325  aTmp <<= static_cast<sal_Int16>(pFontItem->GetFamily());
2326  rPropSet->setPropertyValue( aNm, aTmp );
2327  }
2328  if (xPropSetInfo->hasPropertyByName(aNm = "FontCharset"))
2329  {
2330  aTmp <<= static_cast<sal_Int16>(pFontItem->GetCharSet());
2331  rPropSet->setPropertyValue( aNm, aTmp );
2332  }
2333  if (xPropSetInfo->hasPropertyByName(aNm = "FontPitch"))
2334  {
2335  aTmp <<= static_cast<sal_Int16>(pFontItem->GetPitch());
2336  rPropSet->setPropertyValue( aNm, aTmp );
2337  }
2338 
2339  aTmp <<= pFontItem->GetFamilyName();
2340  aFont.SetFamilyName( pFontItem->GetFamilyName() );
2341  aFont.SetStyleName( pFontItem->GetStyleName() );
2342  aFont.SetFamily( pFontItem->GetFamily() );
2343  aFont.SetCharSet( pFontItem->GetCharSet() );
2344  aFont.SetPitch( pFontItem->GetPitch() );
2345  }
2346  break;
2347 
2348  case RES_CHRATR_FONTSIZE:
2349  {
2350  Size aSize( aFont.GetFontSize().Width(),
2351  static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() );
2352  aTmp <<= static_cast<float>(aSize.Height()) / 20.0;
2353 
2355  MapMode(MapUnit::MapTwip), MapMode(MapUnit::Map100thMM)));
2356  }
2357  break;
2358 
2359  case RES_CHRATR_WEIGHT:
2361  static_cast<const SvxWeightItem*>(pItem)->GetWeight() );
2362  aFont.SetWeight( static_cast<const SvxWeightItem*>(pItem)->GetWeight() );
2363  break;
2364 
2365  case RES_CHRATR_UNDERLINE:
2366  aTmp <<= static_cast<sal_Int16>(static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle());
2367  aFont.SetUnderline(static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle());
2368  break;
2369 
2370  case RES_CHRATR_CROSSEDOUT:
2371  aTmp <<= static_cast<sal_Int16>( static_cast<const SvxCrossedOutItem*>(pItem)->GetStrikeout() );
2372  aFont.SetStrikeout( static_cast<const SvxCrossedOutItem*>(pItem)->GetStrikeout() );
2373  break;
2374 
2375  case RES_CHRATR_POSTURE:
2376  aTmp <<= static_cast<sal_Int16>( static_cast<const SvxPostureItem*>(pItem)->GetPosture() );
2377  aFont.SetItalic( static_cast<const SvxPostureItem*>(pItem)->GetPosture() );
2378  break;
2379 
2380  default:
2381  bSet = false;
2382  break;
2383  }
2384 
2385  if (bSet && xPropSetInfo->hasPropertyByName(OUString::createFromAscii(pMap->pPropNm)))
2386  rPropSet->setPropertyValue(OUString::createFromAscii(pMap->pPropNm), aTmp);
2387  }
2388  // now calculate the size of the control
2390  OSL_ENSURE(pOut, "Impossible");
2391  if (pOut)
2392  {
2393  pOut->Push( PushFlags::FONT | PushFlags::MAPMODE );
2394  pOut->SetMapMode( MapMode( MapUnit::Map100thMM ));
2395  pOut->SetFont( aFont );
2396  aRet.Width = pOut->GetTextWidth(rString);
2397  aRet.Width += 500; //plus size of button, total hack territory
2398  aRet.Height = pOut->GetTextHeight();
2399  pOut->Pop();
2400  }
2401  return aRet;
2402 }
2403 
2404 bool WW8FormulaListBox::Import(const uno::Reference <
2405  lang::XMultiServiceFactory> &rServiceFactory,
2406  uno::Reference <form::XFormComponent> &rFComp,awt::Size &rSz )
2407 {
2408  uno::Reference<uno::XInterface> xCreate = rServiceFactory->createInstance("com.sun.star.form.component.ComboBox");
2409  if( !xCreate.is() )
2410  return false;
2411 
2412  rFComp.set(xCreate, uno::UNO_QUERY);
2413  if( !rFComp.is() )
2414  return false;
2415 
2416  uno::Reference<beans::XPropertySet> xPropSet(xCreate, uno::UNO_QUERY);
2417 
2418  uno::Any aTmp;
2419  if (!msTitle.isEmpty())
2420  aTmp <<= msTitle;
2421  else
2422  aTmp <<= msName;
2423  xPropSet->setPropertyValue("Name", aTmp );
2424 
2425  if (!msToolTip.isEmpty())
2426  {
2427  aTmp <<= msToolTip;
2428  xPropSet->setPropertyValue("HelpText", aTmp );
2429  }
2430 
2431  xPropSet->setPropertyValue("Dropdown", css::uno::makeAny(true));
2432 
2433  if (!maListEntries.empty())
2434  {
2435  sal_uInt32 nLen = maListEntries.size();
2436  uno::Sequence< OUString > aListSource(nLen);
2437  for (sal_uInt32 nI = 0; nI < nLen; ++nI)
2438  aListSource[nI] = maListEntries[nI];
2439  aTmp <<= aListSource;
2440  xPropSet->setPropertyValue("StringItemList", aTmp );
2441 
2442  if (mfDropdownIndex < nLen)
2443  {
2444  aTmp <<= aListSource[mfDropdownIndex];
2445  }
2446  else
2447  {
2448  aTmp <<= aListSource[0];
2449  }
2450 
2451  xPropSet->setPropertyValue("DefaultText", aTmp );
2452 
2453  rSz = mrRdr.MiserableDropDownFormHack(maListEntries[0], xPropSet);
2454  }
2455  else
2456  {
2457  static constexpr OUStringLiteral aBlank =
2458  u"\u2002\u2002\u2002\u2002\u2002";
2459  rSz = mrRdr.MiserableDropDownFormHack(aBlank, xPropSet);
2460  }
2461 
2462  return true;
2463 }
2464 
2467 {
2468 }
2469 
2470 static void lcl_AddToPropertyContainer
2471 (uno::Reference<beans::XPropertySet> const & xPropSet,
2472  const OUString & rPropertyName, const OUString & rValue)
2473 {
2474  uno::Reference<beans::XPropertySetInfo> xPropSetInfo =
2475  xPropSet->getPropertySetInfo();
2476  if (xPropSetInfo.is() &&
2477  ! xPropSetInfo->hasPropertyByName(rPropertyName))
2478  {
2479  uno::Reference<beans::XPropertyContainer>
2480  xPropContainer(xPropSet, uno::UNO_QUERY);
2481  uno::Any aAny((OUString()));
2482  xPropContainer->addProperty
2483  (rPropertyName,
2484  static_cast<sal_Int16>(beans::PropertyAttribute::BOUND |
2485  beans::PropertyAttribute::REMOVABLE),
2486  aAny);
2487  }
2488 
2489  uno::Any aAnyValue(rValue);
2490  xPropSet->setPropertyValue(rPropertyName, aAnyValue );
2491 }
2492 
2493 bool WW8FormulaCheckBox::Import(const uno::Reference <
2494  lang::XMultiServiceFactory> &rServiceFactory,
2495  uno::Reference <form::XFormComponent> &rFComp,awt::Size &rSz )
2496 {
2497  uno::Reference< uno::XInterface > xCreate = rServiceFactory->createInstance("com.sun.star.form.component.CheckBox");
2498  if( !xCreate.is() )
2499  return false;
2500 
2501  rFComp.set( xCreate, uno::UNO_QUERY );
2502  if( !rFComp.is() )
2503  return false;
2504 
2505  uno::Reference< beans::XPropertySet > xPropSet( xCreate, uno::UNO_QUERY );
2506 
2507  rSz.Width = 16 * mhpsCheckBox;
2508  rSz.Height = 16 * mhpsCheckBox;
2509 
2510  uno::Any aTmp;
2511  if (!msTitle.isEmpty())
2512  aTmp <<= msTitle;
2513  else
2514  aTmp <<= msName;
2515  xPropSet->setPropertyValue("Name", aTmp );
2516 
2517  aTmp <<= static_cast<sal_Int16>(mnChecked);
2518  xPropSet->setPropertyValue("DefaultState", aTmp);
2519 
2520  if (!msToolTip.isEmpty())
2521  lcl_AddToPropertyContainer(xPropSet, "HelpText", msToolTip);
2522 
2523  if (!msHelp.isEmpty())
2524  lcl_AddToPropertyContainer(xPropSet, "HelpF1Text", msHelp);
2525 
2526  return true;
2527 
2528 }
2529 
2532 {
2533 }
2534 
2536  const uno::Reference< form::XFormComponent > & rFComp,
2537  const awt::Size& rSize, uno::Reference< drawing::XShape > *pShape,
2538  bool bFloatingCtrl)
2539 {
2540  const uno::Reference< container::XIndexContainer > &rComps = GetFormComps();
2542  rComps->insertByIndex( rComps->getCount(), aTmp );
2543 
2544  const uno::Reference< lang::XMultiServiceFactory > &rServiceFactory =
2545  GetServiceFactory();
2546  if( !rServiceFactory.is() )
2547  return false;
2548 
2549  uno::Reference< uno::XInterface > xCreate = rServiceFactory->createInstance(
2550  "com.sun.star.drawing.ControlShape");
2551  if( !xCreate.is() )
2552  return false;
2553 
2554  uno::Reference< drawing::XShape > xShape(xCreate, uno::UNO_QUERY);
2555 
2556  OSL_ENSURE(xShape.is(), "Did not get XShape");
2557  xShape->setSize(rSize);
2558 
2559  uno::Reference< beans::XPropertySet > xShapePropSet(
2560  xCreate, uno::UNO_QUERY );
2561 
2562  //I lay a small bet that this will change to
2563  //sal_Int16 nTemp=TextContentAnchorType::AS_CHARACTER;
2564  text::TextContentAnchorType nTemp;
2565  if (bFloatingCtrl)
2566  nTemp = text::TextContentAnchorType_AT_PARAGRAPH;
2567  else
2568  nTemp = text::TextContentAnchorType_AS_CHARACTER;
2569 
2570  xShapePropSet->setPropertyValue("AnchorType", uno::Any(static_cast<sal_Int16>(nTemp)) );
2571 
2572  xShapePropSet->setPropertyValue("VertOrient", uno::Any(sal_Int16(text::VertOrientation::TOP)) );
2573 
2574  uno::Reference< text::XText > xDummyTextRef;
2575  uno::Reference< text::XTextRange > xTextRg =
2576  new SwXTextRange( *pPaM, xDummyTextRef );
2577 
2578  aTmp <<= xTextRg;
2579  xShapePropSet->setPropertyValue("TextRange", aTmp );
2580 
2581  // Set the Control-Model for the Control-Shape
2582  uno::Reference< drawing::XControlShape > xControlShape( xShape,
2583  uno::UNO_QUERY );
2584  uno::Reference< awt::XControlModel > xControlModel( rFComp,
2585  uno::UNO_QUERY );
2586  xControlShape->setControl( xControlModel );
2587 
2588  if (pShape)
2589  *pShape = xShape;
2590 
2591  return true;
2592 }
2593 
2594 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetToolTip(const OUString &rToolTip)
Sets the tool tip of the field.
void SetFamily(FontFamily)
void Read_ListLevel(sal_uInt16 nId, const sal_uInt8 *pData, short nLen)
Definition: ww8par3.cxx:1912
SvxNumType GetNumberingType() const
void AdjustLVL(sal_uInt8 nLevel, SwNumRule &rNumRule, WW8aISet const &rListItemSet, WW8aCFormat &aCharFormat, bool &bNewCharFormatCreated, const OUString &aPrefix=OUString())
Definition: ww8par3.cxx:1026
simple Iterator for SPRMs
Definition: ww8scan.hxx:262
SVX_NUM_CHARS_HEBREW
WW8aCFormat aCharFormat
Definition: ww8par3.cxx:404
void SetStrikeout(FontStrikeout)
constexpr TypedWhichId< SvxCrossedOutItem > RES_CHRATR_CROSSEDOUT(5)
void SetListRestart(bool bRestart)
Definition: ndtxt.cxx:4094
void SetStyleIndent(SwWW8StyInf &rStyle, const SwNumFormat &rFormat)
Definition: ww8par3.cxx:1704
Iterator for Booknotes.
Definition: ww8scan.hxx:750
std::unique_ptr< SwWW8FltControlStack > m_xCtrlStck
Definition: ww8par.hxx:1106
SVX_NUM_CHARS_UPPER_LETTER_N
OUString GetUniqueBookmarkName(const OUString &rSuggestedName)
Definition: ww8scan.cxx:4490
void SetLabelFollowedBy(const LabelFollowedBy eLabelFollowedBy)
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
SVX_NUM_NUMBER_HEBREW
sal_Int32 nIndex
std::map< OUString, css::uno::Any > parameter_map_t
Definition: IMark.hxx:94
void SetFontSize(const Size &)
WW8_FC m_fcPlcfLst
Definition: ww8scan.hxx:1461
sal_uInt8 mfNoMark
Definition: ww8par.hxx:666
virtual bool Import(const css::uno::Reference< css::lang::XMultiServiceFactory > &rServiceFactory, css::uno::Reference< css::form::XFormComponent > &rFComp, css::awt::Size &rSz)=0
SwWw8ControlType
Definition: ww8par.hxx:640
sal_Int32 m_lcbPlfLfo
Definition: ww8scan.hxx:1464
std::unique_ptr< WW8RStyle > m_xStyles
Definition: ww8par.hxx:1238
OUString msName
Definition: ww8par.hxx:689
SVX_NUM_CHARS_NEPALI
static bool IsEqualFormatting(const SwNumRule &rOne, const SwNumRule &rTwo)
Definition: ww8par3.cxx:1509
sal_uInt32 sal_UCS4
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
Definition: docfmt.cxx:843
WW8_CP nSCode
start of instructions code
Definition: ww8scan.hxx:193
const sal_uInt32 cbLSTF
Definition: ww8par3.cxx:347
static constexpr auto Items
SwNumRule * m_pOutlineNumrule
Definition: ww8par.hxx:231
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
bool bOverride
Definition: ww8par3.cxx:437
void SetAutoRule(bool bFlag)
Definition: numrule.hxx:231
virtual bool SetAttr(const SfxPoolItem &) override
overriding to handle change of certain paragraph attributes
Definition: ndtxt.cxx:4856
SVX_NUM_FULL_WIDTH_ARABIC
std::string GetValue
void UseListIndent(SwWW8StyInf &rStyle, const SwNumFormat &rFormat)
Definition: ww8par3.cxx:1689
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
static void lcl_AddToPropertyContainer(uno::Reference< beans::XPropertySet > const &xPropSet, const OUString &rPropertyName, const OUString &rValue)
Definition: ww8par3.cxx:2471
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
SprmResult findSprmData(sal_uInt16 nId, sal_uInt8 *pSprms, sal_Int32 nLen) const
Returns the offset to data of the first sprm of id nId, 0.
Definition: ww8scan.cxx:8493
SVX_NUM_NUMBER_NONE
std::vector< sal_uInt8 > bytes
Definition: types.hxx:29
sal_uIntPtr sal_uLong
long Long
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
WW8aIdSty aIdSty
Definition: ww8par3.cxx:403
void SetNCurrentColl(sal_uInt16 nColl)
Definition: ww8par.hxx:1895
bool m_bHasStyNumRule
Definition: ww8par.hxx:253
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
sal_uInt8 mfType
Definition: ww8par.hxx:667
sal_uInt16 GetCurrentId() const
Definition: ww8scan.hxx:285
void SetGrfBulletCP(sal_Unicode cP)
Definition: numrule.hxx:81
sal_uInt16 GetPoolFormatId() const
Query and set PoolFormat IDs.
Definition: numrule.hxx:251
const sal_uInt8 * pMemPos
Definition: ww8scan.hxx:857
const SvxFontItem & GetFont(bool=true) const
Definition: charatr.hxx:122
sal_Int64 n
Provides access to the marks of a document.
#define ODF_FORMCHECKBOX
SVX_NUM_CIRCLE_NUMBER
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:90
void SetContinusNum(bool bFlag)
Definition: numrule.hxx:237
void SetWeight(FontWeight)
OUString msEntryMcr
Definition: ww8par.hxx:681
SwCharFormat * WW8aCFormat[nMaxLevel]
Definition: ww8par.hxx:185
sal_uInt64 Seek(sal_uInt64 nPos)
sal_Int32 m_lcbPlcfLst
Definition: ww8scan.hxx:1462
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
void InsertFormula(WW8FormulaControl &rFormula)
Definition: ww8par3.cxx:2123
std::unique_ptr< WW8ListManager, o3tl::default_delete< WW8ListManager > > m_xLstManager
Definition: ww8par.hxx:1230
OUString msDefault
Definition: ww8par.hxx:676
WW8_CP nLen
total length (to skip over text)
Definition: ww8scan.hxx:192
const OUString & GetName() const
Definition: numrule.hxx:225
sal_uInt16 GetPoolHelpId() const
Query and set Help-IDs for document styles.
Definition: numrule.hxx:255
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2479
sal_Int32 lcb
Definition: ww8struc.hxx:446
const SfxPoolItem * GetFormatAttr(sal_uInt16 nWhich)
Definition: ww8par6.cxx:2814
void SetCharSet(rtl_TextEncoding)
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1794
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, SwTextAttr **ppNewTextAttr=nullptr)=0
Insert an attribute.
#define ODF_FORMCHECKBOX_HELPTEXT
static constexpr sal_uInt16 val
Definition: sprmids.hxx:277
void SetIncludeUpperLevels(sal_uInt8 nSet)
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
FontPitch GetPitch() const
SwNumRule * GetNumRule(size_t i)
Definition: ww8par3.cxx:1139
WW8FormulaCheckBox(const WW8FormulaCheckBox &)=delete
void SetMapMode()
bool bUsedInDoc
Definition: ww8par3.cxx:409
bool m_bListRelevantIndentSet
Definition: ww8par.hxx:255
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
#define ODF_FORMDROPDOWN_RESULT
sal_uInt16 mhpsCheckBox
Definition: ww8par.hxx:670
bool IsRightToLeft()
Definition: ww8par6.cxx:4571
SVX_NUM_CHARS_ARABIC
SVX_NUM_ARABIC_ZERO
FontFamily GetFamily() const
sal_uInt64 SeekRel(sal_Int64 nPos)
bool ImportFormulaControl(WW8FormulaControl &rBox, WW8_CP nStart, SwWw8ControlType nWhich)
Definition: ww8par3.cxx:2069
void SetIndentAt(const tools::Long nIndentAt)
SvxNumType
void RegisterNumFormat(sal_uInt16 nCurrentLFO, sal_uInt8 nCurrentLevel)
Definition: ww8par3.cxx:1903
static SvxNumType GetSvxNumTypeFromMSONFC(sal_uInt16 nMSONFC)
Definition: ww8par3.cxx:517
static OutputDevice * GetDefaultDevice()
WW8LSTInfo * GetLSTByListId(sal_uInt32 nIdLst) const
Definition: ww8par3.cxx:482
constexpr tools::Long Width() const
sal_uInt8 mfDropdownIndex
Definition: ww8par.hxx:664
constexpr OUStringLiteral aListBox
Definition: ww8scan.hxx:50
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
SwDoc & m_rDoc
Definition: docbm.cxx:1208
void Read_LFOPosition(sal_uInt16 nId, const sal_uInt8 *pData, short nLen)
read and interpret the sprmPIlfo used to determine which list contains the paragraph.
Definition: ww8par3.cxx:1959
wwSprmParser maSprmParser
Definition: ww8par.hxx:167
SwNumRule * pNumRule
Definition: ww8par3.cxx:427
sal_uInt16 sal_Unicode
const SfxPoolItem * NextItem()
OUString msExitMcr
Definition: ww8par.hxx:682
void SetTextLeft(const tools::Long nL, const sal_uInt16 nProp=100)
const SwCharFormat * GetDfltCharFormat() const
Definition: doc.hxx:753
ErrCode GetError() const
std::vector< WW8LFOLVL > maOverrides
Definition: ww8par3.cxx:426
sal_uInt16 mnChecked
Definition: ww8par.hxx:671
std::vector< SwWW8StyInf > m_vColl
Definition: ww8par.hxx:1243
bool SetTextFormatColl(const SwPaM &rRg, SwTextFormatColl *pFormat, const bool bReset=true, const bool bResetListAttrs=false, SwRootFrame const *pLayout=nullptr)
Add 4th optional parameter .
Definition: docfmt.cxx:1072
rtl_TextEncoding GetCharSet() const
SVX_NUM_CHARS_CYRILLIC_LOWER_LETTER_RU
std::unique_ptr< SfxItemSet > WW8aISet[nMaxLevel]
Definition: ww8par.hxx:183
Ret writer_cast(Param in)
A static_cast style cast for conversion of word types to writer's.
SVX_NUM_ARABIC
WW8LSTInfo(SwNumRule *pNumRule_, const WW8LST &aLST)
Definition: ww8par3.cxx:412
oslFileHandle & pOut
WW8FormulaListBox(const WW8FormulaListBox &)=delete
tools::Long GetListFirstLineIndent(const SwNumFormat &rFormat)
Definition: ww8par.cxx:1218
SVX_NUM_ROMAN_UPPER
void SetToolTip(const OUString &rStr)
Definition: expfld.cxx:1414
bool IsWW8BuiltInHeadingStyle() const
Definition: ww8par.hxx:333
SVX_NUM_ROMAN_LOWER
virtual parameter_map_t * GetParameters()=0
void SetHelp(const OUString &rStr)
Definition: expfld.cxx:1404
SVX_NUM_IROHA_FULLWIDTH_JA
const SfxPoolItem * GetDfltAttr(sal_uInt16 nWhich)
Get the default attribute from corresponding default attribute table.
Definition: hints.cxx:153
void SetUnderline(FontLineStyle)
void SetCountedInList(bool bCounted)
Definition: ndtxt.cxx:4210
void SetSelectedItem(const OUString &rItem)
Sets the selected item.
OUString msFormatting
Definition: ww8par.hxx:677
sal_uInt64 remainingSize()
eF_ResT
Definition: ww8par.hxx:623
sal_uInt8 mfUnused
Definition: ww8par.hxx:668
const char * sName
SVX_NUM_DI_ZI_ZH
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
SvStream & rSt
Definition: ww8par.hxx:171
void SetPitch(FontPitch ePitch)
const OUString & GetStyleName() const
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_WEIGHT(15)
Definition: ww8scan.hxx:43
sal_uInt16 GetCurrentColl() const
Definition: ww8par.hxx:1894
WW8_CP nLCode
length
Definition: ww8scan.hxx:194
bool IsContinusNum() const
Definition: numrule.hxx:236
void SetStylesList(sal_uInt16 nStyle, sal_uInt16 nCurrentLFO, sal_uInt8 nCurrentLevel)
Definition: ww8par3.cxx:1723
sal_uInt8 m_nVersion
Program-Version asked for by us: in Ctor we check if it matches the value of nFib.
Definition: ww8scan.hxx:1118
SwNumRule * pNumRule
Definition: ww8par3.cxx:406
virtual bool Import(const css::uno::Reference< css::lang::XMultiServiceFactory > &rServiceFactory, css::uno::Reference< css::form::XFormComponent > &rFComp, css::awt::Size &rSz) override
Definition: ww8par3.cxx:2493
SVX_NUM_BITMAP
void SetNumAdjust(SvxAdjust eSet)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
SVX_NUM_CHAR_SPECIAL
SwCharFormat * GetCharFormat() const
Definition: numrule.hxx:74
eF_ResT Read_F_FormCheckBox(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:185
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
std::vector< ww::bytes > maParaSprms
Definition: ww8par3.cxx:402
short ImportSprm(const sal_uInt8 *pPos, sal_Int32 nMemLen, sal_uInt16 nId=0)
Definition: ww8par6.cxx:6123
OUString msHelp
Definition: ww8par.hxx:679
SVX_NUM_IROHA_HALFWIDTH_JA
SVX_NUM_TIAN_GAN_ZH
bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
SVX_NUM_NUMBER_UPPER_KO
static SvtFilterOptions & Get()
void SetFamilyName(const OUString &rFamilyName)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
sal_uInt16 m_nCurrentColl
Definition: ww8par.hxx:1297
SvxAdjust
bool HasWW8OutlineLevel() const
Definition: ww8par.hxx:311
int i
SwDoc & m_rDoc
Definition: ww8par.hxx:1102
void SetBulletFont(const vcl::Font *pFont)
sal_Int32 GetAbsLSpace() const
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwNumRuleType GetRuleType() const
Definition: numrule.hxx:212
void SetToggleAttrFlags(sal_uInt16 nFlags)
Definition: ww8par.cxx:590
std::unique_ptr< SfxItemSet > SetCurrentItemSet(std::unique_ptr< SfxItemSet > pItemSet)
Definition: ww8par.cxx:6681
SVX_NUM_CHARS_ARABIC_ABJAD
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
Definition: number.cxx:1338
SVX_NUM_TEXT_NUMBER
sal_uInt8 mfToolTip
Definition: ww8par.hxx:665
SwFormat * m_pFormat
Definition: ww8par.hxx:229
OUString msTitle
Definition: ww8par.hxx:675
sal_uInt16 WW8aIdSty[WW8ListManager::nMaxLevel]
Definition: ww8par3.cxx:328
sal_uInt16 Count() const
void Read_ANLevelNo(sal_uInt16, const sal_uInt8 *pData, short nLen)
Definition: ww8par2.cxx:743
std::shared_ptr< SvxLRSpaceItem > maWordLR
Definition: ww8par.hxx:248
sal_uInt16 m_nLFOIndex
Definition: ww8par.hxx:235
void SetTextFirstLineOffset(const short nF, const sal_uInt16 nProp=100)
void RegisterNumFormatOnStyle(sal_uInt16 nStyle)
Definition: ww8par3.cxx:1755
std::enable_if< std::is_signed< T >::value, bool >::type checked_add(T a, T b, T &result)
virtual bool InsertControl(const css::uno::Reference< css::form::XFormComponent > &rFComp, const css::awt::Size &rSize, css::uno::Reference< css::drawing::XShape > *pShape, bool bFloatingCtrl) override
Definition: ww8par3.cxx:2535
float u
virtual bool Import(const css::uno::Reference< css::lang::XMultiServiceFactory > &rServiceFactory, css::uno::Reference< css::form::XFormComponent > &rFComp, css::awt::Size &rSz) override
Definition: ww8par3.cxx:2404
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2798
sal_uInt32 nIdLst
Definition: ww8par3.cxx:431
eF_ResT Read_F_FormTextBox(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:92
void FormulaRead(SwWw8ControlType nWhich, SvStream *pD)
Definition: ww8par3.cxx:2142
const Size & GetFontSize() const
void Restore(SwWW8ImplReader *pRdr)
Definition: ww8par.cxx:2043
const sal_uInt8 * pSprm
Definition: ww8scan.hxx:95
sal_uInt16 nLastLFOPosition
Definition: ww8par.hxx:193
const sal_uInt16 LN_PAnld
Definition: sprmids.hxx:39
sal_uInt8 GetPoolHlpFileId() const
Definition: numrule.hxx:257
sal_uInt8 nLfoLvl
Definition: ww8par3.cxx:432
sal_uInt16 GetToggleAttrFlags() const
Definition: ww8par.cxx:580
SvStream & ReadUChar(unsigned char &rChar)
std::vector< std::unique_ptr< WW8LSTInfo > > maLSTInfos
Definition: ww8par.hxx:172
sal_uInt16 GetStart() const
OUString sPrefix
sal_Int16 nVersion
SVX_NUM_TEXT_CARDINAL
SVX_NUM_CHARS_THAI
sal_uInt32 nIdLst
Definition: ww8par3.cxx:407
void SetCharTextDistance(short nSet)
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
eF_ResT Read_F_FormListBox(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:244
sal_uInt16 StyleUsingLFO(sal_uInt16 nLFOIndex) const
Definition: ww8par2.cxx:3561
virtual sw::mark::IFieldmark * makeNoTextFieldBookmark(const SwPaM &rPaM, const OUString &rName, const OUString &rType)=0
SVX_NUM_CHARS_LOWER_LETTER_N
sal_uInt16 mnMaxLen
FFData.cch in the spec: maximum length, in characters, of the value of the textbox.
Definition: ww8par.hxx:674
std::vector< std::unique_ptr< WW8LFOInfo > > m_LFOInfos
Definition: ww8par.hxx:173
SVX_NUM_NUMBER_HANGUL_KO
std::vector< OUString > maListEntries
Definition: ww8par.hxx:683
void RegisterNumFormatOnTextNode(sal_uInt16 nCurrentLFO, sal_uInt8 nCurrentLevel, const bool bSetAttr=true)
Definition: ww8par3.cxx:1794
Dropdown field.
Definition: flddropdown.hxx:58
void SetColor(const Color &)
sal_Int32 WW8_CP
Definition: ww8struc.hxx:153
constexpr T & temporary(T &&x)
SvStream & ReadInt32(sal_Int32 &rInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
void SetBulletChar(sal_UCS4 cSet)
void SetName(const OUString &rName)
Sets the name of the field.
WW8LFOInfo(const WW8LFO &rLFO)
Definition: ww8par3.cxx:446
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:450
sal_Int32 GetRemLen() const
Definition: ww8scan.hxx:286
sal_uInt8 m_nListLevel
Definition: ww8par.hxx:236
constexpr TypedWhichId< SvxColorItem > RES_CHRATR_COLOR(3)
SVX_NUM_NUMBER_UPPER_ZH_TW
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:79
void SetToggleBiDiAttrFlags(sal_uInt16 nFlags)
Definition: ww8par.cxx:596
void SetStatus(sal_uInt16 nIndex, eBookStatus eStat)
Definition: ww8scan.cxx:4424
const OUString & GetFamilyName() const
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
WW8ListManager(SvStream &rSt_, SwWW8ImplReader &rReader_)
Definition: ww8par3.cxx:1149
void SetAttrListLevel(int nLevel)
Sets the list level of this text node.
Definition: ndtxt.cxx:4057
#define ODF_FORMCHECKBOX_NAME
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:608
void SetStyleName(const OUString &rStyleName)
void SetCharFormat(SwCharFormat *)
Definition: number.cxx:273
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
const WW8Fib & rFib
Definition: ww8par.hxx:170
void SyncIndentWithList(SvxLRSpaceItem &rLR, const SwNumFormat &rFormat, const bool bFirstLineOfstSet, const bool bLeftIndentSet)
Definition: ww8par.cxx:1253
#define ERRCODE_NONE
void advance()
Definition: ww8scan.cxx:889
unsigned char sal_uInt8
SVX_NUM_NUMBER_TRADITIONAL_JA
SVX_NUM_HANGUL_JAMO_KO
constexpr OUStringLiteral aCheckBox
Definition: ww8scan.hxx:49
void SetFont(const vcl::Font &rNewFont)
void SetFirstLineOffset(sal_Int32 nSet)
static void PicRead(SvStream *pDataStream, WW8_PIC *pPic, bool bVer67)
Definition: ww8graf2.cxx:443
VCL_DLLPUBLIC float ConvertFontWeight(FontWeight eWeight)
const SwNumRuleTable & GetNumRuleTable() const
Definition: doc.hxx:1066
SVX_NUM_NUMBER_LOWER_ZH
tools::Long GetTextHeight() const
sal_uInt16 nSprmId
Definition: ww8scan.hxx:858
OUString aName
#define ODF_FORMDROPDOWN_LISTENTRY
SVX_NUM_NUMBER_UPPER_ZH
eF_ResT Read_F_OCX(WW8FieldDesc *, OUString &)
Definition: ww8par3.cxx:84
#define ODF_FORMTEXT
sal_Int32 nRemainingData
Definition: ww8scan.hxx:96
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
bool ReadLVL(SwNumFormat &rNumFormat, std::unique_ptr< SfxItemSet > &rpItemSet, sal_uInt16 nLevelStyle, bool bSetStartNo, sal_uInt16 nLevel, ww::bytes &rParaSprms)
Definition: ww8par3.cxx:672
bool IsInvalidOrToBeMergedTabCell() const
Definition: ww8par2.cxx:3542
sal_uInt64 Tell() const
QPRO_FUNC_TYPE nType
sal_uInt16 MakeNumRule(const OUString &rName, const SwNumRule *pCpy=nullptr, bool bBroadcast=false, const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode=SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
Definition: docnum.cxx:2435
~WW8ListManager() COVERITY_NOEXCEPT_FALSE
Definition: ww8par3.cxx:1482
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
SVX_NUM_HANGUL_SYLLABLE_KO
SVX_NUM_CHARS_CYRILLIC_UPPER_LETTER_RU
WW8FormulaEditBox(const WW8FormulaEditBox &)=delete
constexpr sal_uInt16 RES_CHRATR_END(46)
void SetStart(sal_uInt16 nSet)
SwNumRule * CreateNextRule(bool bSimple)
Definition: ww8par3.cxx:1125
bool good() const
void SetItalic(FontItalic)
std::unique_ptr< wwSprmParser > m_xSprmParser
Definition: ww8par.hxx:1181
void Read_PicLoc(sal_uInt16, const sal_uInt8 *pData, short nLen)
Definition: ww8par6.cxx:2884
std::shared_ptr< WW8PLCFMan > m_xPlcxMan
Definition: ww8par.hxx:1232
sal_uInt16 GetToggleBiDiAttrFlags() const
Definition: ww8par.cxx:585
bool IsAbsSpaces() const
Definition: numrule.hxx:239
WW8_FC m_fcPlfLfo
Definition: ww8scan.hxx:1463
bool bSimpleList
Definition: ww8par3.cxx:408
SVX_NUM_SYMBOL_CHICAGO
#define SAL_WARN(area, stream)
void SetHelp(const OUString &rHelp)
Sets the help text of the field.
void SetAbsLSpace(sal_Int32 nSet)
SVX_NUM_TEXT_ORDINAL
std::vector< ww::bytes > maParaSprms
Definition: ww8par3.cxx:425
virtual SwFieldType * GetSysFieldType(const SwFieldIds eWhich) const =0
bool m_bValid
Definition: ww8par.hxx:249
SvStream * m_pDataStream
Definition: ww8par.hxx:1099
sal_uInt16 nUniqueList
Definition: ww8par.hxx:174
bool DelNumRule(const OUString &rName, bool bBroadCast=false)
Definition: docnum.cxx:1045
SVX_NUM_AIU_HALFWIDTH_JA
static OUString sanitizeString(const OUString &rString)
Definition: ww8par3.cxx:491
bool m_bColl
Definition: ww8par.hxx:251
OUString msToolTip
Definition: ww8par.hxx:680
constexpr OUStringLiteral aTextField
Definition: ww8scan.hxx:51
sal_uInt8 m_nListLevel
Definition: ww8par.hxx:1313
bool bUsedInDoc
Definition: ww8par3.cxx:439
OUString read_uInt16_BeltAndBracesString(SvStream &rStrm)
Definition: ww8scan.cxx:2082
void SetNumberingType(SvxNumType nSet)
sal_uLong m_nPicLocFc
Definition: ww8par.hxx:1287
virtual void SetChecked(bool checked)=0
virtual bool ResetAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0) override
Definition: ndtxt.cxx:5089
SwFormat * m_pCurrentColl
Definition: ww8par.hxx:1239
OUString read_uInt16_PascalString(SvStream &rStrm)
Definition: ww8scan.hxx:162
OUString GetBookmark(tools::Long nStart, tools::Long nEnd, sal_uInt16 &nIndex)
Definition: ww8scan.cxx:4456
SwCharFormat * WW8aCFormat[WW8ListManager::nMaxLevel]
Definition: ww8par3.cxx:330
void SetFirstLineIndent(const tools::Long nFirstLineIndent)
void Push(PushFlags nFlags=PushFlags::ALL)
bool IsUseEnhancedFields() const
SwPaM * m_pPaM
Definition: ww8par.hxx:1104
SwDoc & rDoc
Definition: ww8par.hxx:169
constexpr TypedWhichId< SvxPostureItem > RES_CHRATR_POSTURE(11)
bool SetTextFormatCollAndListLevel(const SwPaM &rRg, SwWW8StyInf &rStyleInfo)
Definition: ww8par3.cxx:1655
void SetAttrListRestartValue(SwNumberTree::tSwNumTreeNumber nNum)
Definition: ndtxt.cxx:4138
sal_uInt16 Which() const
void SetListFormat(const OUString &rPrefix, const OUString &rSuffix, int nLevel)
bool IsOutlineRule() const
Definition: numrule.hxx:242
SVX_NUM_AIU_FULLWIDTH_JA
const SwNumRule * m_pChosenWW8OutlineStyle
Definition: ww8par.hxx:1312
SwWW8ImplReader & mrRdr
Definition: ww8par.hxx:650
sal_uInt16 nPos
const sal_uInt8 * GetSprms() const
Definition: ww8scan.hxx:282
const SfxPoolItem * GetCurItem() const
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1319
void SetListtabPos(const tools::Long nListtabPos)
sal_uInt16 m_nLFOPosition
Definition: ww8par.hxx:1299
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:850
#define ODF_FORMDROPDOWN
void SetItems(const std::vector< OUString > &rItems)
Sets the items of the dropdown box.
SwWW8ImplReader & rReader
Definition: ww8par.hxx:168
SwNumRule * GetNumRuleForActivation(sal_uInt16 nLFOPosition, const sal_uInt8 nLevel, std::vector< sal_uInt8 > &rParaSprms, SwTextNode *pNode=nullptr)
Definition: ww8par3.cxx:1538
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1024
SprmResult GrpprlHasSprm(sal_uInt16 nId, sal_uInt8 &rSprms, sal_uInt8 nLen)
Definition: ww8par3.cxx:461
css::awt::Size MiserableDropDownFormHack(const OUString &rString, css::uno::Reference< css::beans::XPropertySet > const &rPropSet)
Definition: ww8par3.cxx:2267
eF_ResT Read_F_HTMLControl(WW8FieldDesc *pF, OUString &rStr)
Definition: ww8par3.cxx:317
bool bLSTbUIDSet
Definition: ww8par3.cxx:441