LibreOffice Module sw (master)  1
txtfld.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <hintids.hxx>
21 #include <fmtfld.hxx>
22 #include <txtfld.hxx>
23 #include <charfmt.hxx>
24 #include <fmtautofmt.hxx>
25 
26 #include <viewsh.hxx>
27 #include <doc.hxx>
28 #include <rootfrm.hxx>
29 #include <pagefrm.hxx>
30 #include <ndtxt.hxx>
31 #include <fldbas.hxx>
32 #include <viewopt.hxx>
33 #include <flyfrm.hxx>
34 #include <viewimp.hxx>
35 #include <swfont.hxx>
36 #include <swmodule.hxx>
37 #include "porfld.hxx"
38 #include "porftn.hxx"
39 #include "porref.hxx"
40 #include "portox.hxx"
41 #include "porfly.hxx"
42 #include "itrform2.hxx"
43 #include <chpfld.hxx>
44 #include <dbfld.hxx>
45 #include <expfld.hxx>
46 #include <docufld.hxx>
47 #include <pagedesc.hxx>
48 #include <fmtmeta.hxx>
49 #include <reffld.hxx>
50 #include <flddat.hxx>
53 #include <redline.hxx>
54 #include <sfx2/docfile.hxx>
55 #include <svl/grabbagitem.hxx>
56 #include <svl/itemiter.hxx>
57 #include <svl/whiter.hxx>
58 #include <editeng/colritem.hxx>
59 #include <editeng/udlnitem.hxx>
61 
62 static bool lcl_IsInBody( SwFrame const *pFrame )
63 {
64  if ( pFrame->IsInDocBody() )
65  return true;
66  else
67  {
68  const SwFrame *pTmp = pFrame;
69  const SwFlyFrame *pFly;
70  while ( nullptr != (pFly = pTmp->FindFlyFrame()) )
71  pTmp = pFly->GetAnchorFrame();
72  return pTmp->IsInDocBody();
73  }
74 }
75 
77  const SwTextAttr *pHint ) const
78 {
79  SwExpandPortion *pRet = nullptr;
80  SwFrame *pFrame = m_pFrame;
81  SwField *pField = const_cast<SwField*>(pHint->GetFormatField().GetField());
82  const bool bName = rInf.GetOpt().IsFieldName();
83 
84  SwCharFormat* pChFormat = nullptr;
85  bool bNewFlyPor = false;
86  sal_uInt16 subType = 0;
87 
88  // set language
89  const_cast<SwTextFormatter*>(this)->SeekAndChg( rInf );
90  if (pField->GetLanguage() != GetFnt()->GetLanguage())
91  {
92  pField->SetLanguage( GetFnt()->GetLanguage() );
93  // let the visual note know about its new language
94  if (pField->GetTyp()->Which()==SwFieldIds::Postit)
95  const_cast<SwFormatField*> (&pHint->GetFormatField())->Broadcast( SwFormatFieldHint( &pHint->GetFormatField(), SwFormatFieldHintWhich::LANGUAGE ) );
96  }
97 
98  SwViewShell *pSh = rInf.GetVsh();
99  SwDoc *const pDoc( pSh ? pSh->GetDoc() : nullptr );
100  bool const bInClipboard( pDoc == nullptr || pDoc->IsClipBoard() );
101  bool bPlaceHolder = false;
102 
103  switch( pField->GetTyp()->Which() )
104  {
105  case SwFieldIds::Script:
106  case SwFieldIds::Postit:
107  pRet = new SwPostItsPortion( SwFieldIds::Script == pField->GetTyp()->Which() );
108  break;
109 
111  {
112  if( bName )
113  pRet = new SwFieldPortion( pField->GetFieldName() );
114  else
115  pRet = new SwCombinedPortion( pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
116  }
117  break;
118 
120  {
121  OUString const aStr( bName
122  ? pField->GetFieldName()
123  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
124  pRet = new SwHiddenPortion(aStr);
125  }
126  break;
127 
128  case SwFieldIds::Chapter:
129  if( !bName && pSh && !pSh->Imp()->IsUpdateExpFields() )
130  {
131  static_cast<SwChapterField*>(pField)->ChangeExpansion(*pFrame,
132  &static_txtattr_cast<SwTextField const*>(pHint)->GetTextNode());
133  }
134  {
135  OUString const aStr( bName
136  ? pField->GetFieldName()
137  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
138  pRet = new SwFieldPortion( aStr );
139  }
140  break;
141 
142  case SwFieldIds::DocStat:
143  if( !bName && pSh && !pSh->Imp()->IsUpdateExpFields() )
144  {
145  static_cast<SwDocStatField*>(pField)->ChangeExpansion( pFrame );
146  }
147  {
148  OUString const aStr( bName
149  ? pField->GetFieldName()
150  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
151  pRet = new SwFieldPortion( aStr );
152  }
153  static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType= ATTR_PAGECOUNTFLD;
154  break;
155 
157  {
158  if( !bName && pSh && pSh->GetLayout() && !pSh->Imp()->IsUpdateExpFields() )
159  {
160  SwPageNumberFieldType *pPageNr = static_cast<SwPageNumberFieldType *>(pField->GetTyp());
161 
162  const SwRootFrame* pTmpRootFrame = pSh->GetLayout();
163  const bool bVirt = pTmpRootFrame->IsVirtPageNum();
164 
165  sal_uInt16 nVirtNum = pFrame->GetVirtPageNum();
166  sal_uInt16 nNumPages = pTmpRootFrame->GetPageNum();
167  SvxNumType nNumFormat = SvxNumType(-1);
168  if(SVX_NUM_PAGEDESC == pField->GetFormat())
169  nNumFormat = pFrame->FindPageFrame()->GetPageDesc()->GetNumType().GetNumberingType();
170  static_cast<SwPageNumberField*>(pField)
171  ->ChangeExpansion(nVirtNum, nNumPages);
172  pPageNr->ChangeExpansion(pDoc,
173  bVirt, nNumFormat != SvxNumType(-1) ? &nNumFormat : nullptr);
174  }
175  {
176  OUString const aStr( bName
177  ? pField->GetFieldName()
178  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
179  pRet = new SwFieldPortion( aStr );
180  }
181  static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType= ATTR_PAGENUMBERFLD;
182  break;
183  }
184  case SwFieldIds::GetExp:
185  {
186  if( !bName && pSh && !pSh->Imp()->IsUpdateExpFields() )
187  {
188  SwGetExpField* pExpField = static_cast<SwGetExpField*>(pField);
189  if( !::lcl_IsInBody( pFrame ) )
190  {
191  pExpField->ChgBodyTextFlag( false );
192  pExpField->ChangeExpansion(*pFrame,
193  *static_txtattr_cast<SwTextField const*>(pHint));
194  }
195  else if( !pExpField->IsInBodyText() )
196  {
197  // Was something else previously, thus: expand first, then convert it!
198  pExpField->ChangeExpansion(*pFrame,
199  *static_txtattr_cast<SwTextField const*>(pHint));
200  pExpField->ChgBodyTextFlag( true );
201  }
202  }
203  {
204  OUString const aStr( bName
205  ? pField->GetFieldName()
206  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
207  pRet = new SwFieldPortion( aStr );
208  }
209  break;
210  }
212  {
213  if( !bName )
214  {
215  SwDBField* pDBField = static_cast<SwDBField*>(pField);
216  pDBField->ChgBodyTextFlag( ::lcl_IsInBody( pFrame ) );
217  }
218  {
219  OUString const aStr( bName
220  ? pField->GetFieldName()
221  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
222  pRet = new SwFieldPortion(aStr);
223  }
224  break;
225  }
227  if( !bName && pSh && !pSh->Imp()->IsUpdateExpFields() )
228  {
229  static_cast<SwRefPageGetField*>(pField)->ChangeExpansion(*pFrame,
230  static_txtattr_cast<SwTextField const*>(pHint));
231  }
232  {
233  OUString const aStr( bName
234  ? pField->GetFieldName()
235  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
236  pRet = new SwFieldPortion(aStr);
237  }
238  break;
239 
241  if( !bName )
242  pChFormat = static_cast<SwJumpEditField*>(pField)->GetCharFormat();
243  bNewFlyPor = true;
244  bPlaceHolder = true;
245  break;
246  case SwFieldIds::GetRef:
247  subType = static_cast<SwGetRefField*>(pField)->GetSubType();
248  {
249  OUString const str( bName
250  ? pField->GetFieldName()
251  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
252  pRet = new SwFieldPortion(str);
253  }
254  if( subType == REF_BOOKMARK )
255  static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType = ATTR_BOOKMARKFLD;
256  else if( subType == REF_SETREFATTR )
257  static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType = ATTR_SETREFATTRFLD;
258  break;
260  subType = static_cast<SwDateTimeField*>(pField)->GetSubType();
261  {
262  OUString const str( bName
263  ? pField->GetFieldName()
264  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
265  pRet = new SwFieldPortion(str);
266  }
267  if( subType & DATEFLD )
268  static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType= ATTR_DATEFLD;
269  else if( subType & TIMEFLD )
270  static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType = ATTR_TIMEFLD;
271  break;
272  default:
273  {
274  OUString const aStr( bName
275  ? pField->GetFieldName()
276  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
277  pRet = new SwFieldPortion(aStr);
278  }
279  }
280 
281  if( bNewFlyPor )
282  {
283  std::unique_ptr<SwFont> pTmpFnt;
284  if( !bName )
285  {
286  pTmpFnt.reset(new SwFont( *m_pFont ));
287  pTmpFnt->SetDiffFnt(&pChFormat->GetAttrSet(), &m_pFrame->GetDoc().getIDocumentSettingAccess());
288  }
289  OUString const aStr( bName
290  ? pField->GetFieldName()
291  : pField->ExpandField(bInClipboard, pFrame->getRootFrame()) );
292  pRet = new SwFieldPortion(aStr, std::move(pTmpFnt), bPlaceHolder);
293  }
294 
295  return pRet;
296 }
297 
298 static SwFieldPortion * lcl_NewMetaPortion(SwTextAttr & rHint, const bool bPrefix)
299 {
300  ::sw::Meta *const pMeta(
301  static_cast<SwFormatMeta &>(rHint.GetAttr()).GetMeta() );
302  OUString fix;
303  ::sw::MetaField *const pField( dynamic_cast< ::sw::MetaField * >(pMeta) );
304  OSL_ENSURE(pField, "lcl_NewMetaPortion: no meta field?");
305  if (pField)
306  {
307  OUString color;
308  pField->GetPrefixAndSuffix(bPrefix ? &fix : nullptr, bPrefix ? nullptr : &fix, &color);
309  }
310  return new SwFieldPortion( fix );
311 }
312 
322 {
323  const TextFrameIndex nIdx(rInfo.GetIdx());
324 
325  // sw_redlinehide: because there is a dummy character at the start of these
326  // hints, it's impossible to have ends of hints from different nodes at the
327  // same view position, so it's sufficient to check the hints of the current
328  // node. However, m_pByEndIter exists for the whole text frame, so
329  // it's necessary to iterate all hints for that purpose...
330  if (!m_pByEndIter)
331  {
333  }
334  SwTextNode const* pNode(nullptr);
335  for (SwTextAttr const* pHint = m_pByEndIter->NextAttr(pNode); pHint;
336  pHint = m_pByEndIter->NextAttr(pNode))
337  {
338  SwTextAttr & rHint(const_cast<SwTextAttr&>(*pHint));
339  TextFrameIndex const nEnd(
340  rInfo.GetTextFrame()->MapModelToView(pNode, rHint.GetAnyEnd()));
341  if (nEnd > nIdx)
342  {
343  m_pByEndIter->PrevAttr();
344  break;
345  }
346  if (nEnd == nIdx)
347  {
348  if (RES_TXTATR_METAFIELD == rHint.Which())
349  {
350  SwFieldPortion *const pPortion(
351  lcl_NewMetaPortion(rHint, false));
352  pPortion->SetNoLength(); // no CH_TXTATR at hint end!
353  return pPortion;
354  }
355  }
356  }
357  return nullptr;
358 }
359 
361 {
362  SwTextAttr *pHint = GetAttr( rInf.GetIdx() );
363  SwLinePortion *pRet = nullptr;
364  if( !pHint )
365  {
366  pRet = new SwTextPortion;
367  pRet->SetLen(TextFrameIndex(1));
368  rInf.SetLen(TextFrameIndex(1));
369  return pRet;
370  }
371 
372  switch( pHint->Which() )
373  {
374  case RES_TXTATR_FLYCNT :
375  {
376  pRet = NewFlyCntPortion( rInf, pHint );
377  break;
378  }
379  case RES_TXTATR_FTN :
380  {
381  pRet = NewFootnotePortion( rInf, pHint );
382  break;
383  }
384  case RES_TXTATR_FIELD :
385  case RES_TXTATR_ANNOTATION :
386  {
387  pRet = NewFieldPortion( rInf, pHint );
388  break;
389  }
390  case RES_TXTATR_REFMARK :
391  {
392  pRet = new SwIsoRefPortion;
393  break;
394  }
395  case RES_TXTATR_TOXMARK :
396  {
397  pRet = new SwIsoToxPortion;
398  break;
399  }
401  {
402  pRet = lcl_NewMetaPortion( *pHint, true );
403  break;
404  }
405  default: ;
406  }
407  if( !pRet )
408  {
409  pRet = new SwFieldPortion( "" );
410  rInf.SetLen(TextFrameIndex(1));
411  }
412  return pRet;
413 }
414 
421  const IDocumentSettingAccess* pIDSA,
422  const SwAttrSet* pFormat)
423 {
425  return;
426 
428  std::shared_ptr<SfxItemSet> pSet(rListAutoFormat.GetStyleHandle());
429 
430  // TODO remove this fallback (for WW8/RTF)
431  bool isDOCX = pIDSA->get(DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS);
432  if (!isDOCX && !pSet)
433  {
434  TextFrameIndex const nTextLen(rInf.GetTextFrame()->GetText().getLength());
435  SwTextNode const* pNode(nullptr);
437  for (SwTextAttr const* pHint = iter.PrevAttr(&pNode); pHint;
438  pHint = iter.PrevAttr(&pNode))
439  {
440  TextFrameIndex const nHintEnd(
441  rInf.GetTextFrame()->MapModelToView(pNode, pHint->GetAnyEnd()));
442  if (nHintEnd < nTextLen)
443  {
444  break; // only those at para end are interesting
445  }
446  // Formatting for the paragraph mark is usually set to apply only to the
447  // (non-existent) extra character at end of the text node, but there can be
448  // other hints too (ending at nTextLen), so look for all matching hints.
449  // Still the (non-existent) extra character at the end is preferred if it exists.
450  if (pHint->Which() == RES_TXTATR_AUTOFMT)
451  {
452  pSet = pHint->GetAutoFormat().GetStyleHandle();
453  // When we find an empty hint (start == end) we got what we are looking for.
454  if (pHint->GetStart() == *pHint->End())
455  break;
456  }
457  }
458  }
459 
460  // Check each item and in case it should be ignored, then clear it.
461  if (!pSet)
462  return;
463 
464  std::unique_ptr<SfxItemSet> const pCleanedSet = pSet->Clone();
465 
466  if (pCleanedSet->HasItem(RES_TXTATR_CHARFMT))
467  {
468  // Insert attributes of referenced char format into current set
469  const SwFormatCharFormat& rCharFormat = pCleanedSet->Get(RES_TXTATR_CHARFMT);
470  const SwAttrSet& rStyleAttrs = static_cast<const SwCharFormat *>(rCharFormat.GetRegisteredIn())->GetAttrSet();
471  SfxWhichIter aIter(rStyleAttrs);
472  sal_uInt16 nWhich = aIter.FirstWhich();
473  while (nWhich)
474  {
475  if (!SwTextNode::IsIgnoredCharFormatForNumbering(nWhich, /*bIsCharStyle=*/true)
476  && !pCleanedSet->HasItem(nWhich)
477  && !(pFormat && pFormat->HasItem(nWhich)) )
478  {
479  // Copy from parent sets only allowed items which will not overwrite
480  // values explicitly defined in current set (pCleanedSet) or in pFormat
481  if (const SfxPoolItem* pItem = rStyleAttrs.GetItem(nWhich, true))
482  pCleanedSet->Put(*pItem);
483  }
484  nWhich = aIter.NextWhich();
485  }
486 
487  // It is not required here anymore, all referenced items are inserted
488  pCleanedSet->ClearItem(RES_TXTATR_CHARFMT);
489  };
490 
491  SfxItemIter aIter(*pSet);
492  const SfxPoolItem* pItem = aIter.GetCurItem();
493  while (pItem)
494  {
496  pCleanedSet->ClearItem(pItem->Which());
497  else if (pFormat && pFormat->HasItem(pItem->Which()))
498  pCleanedSet->ClearItem(pItem->Which());
499  else if (pItem->Which() == RES_CHRATR_BACKGROUND)
500  {
501  bool bShadingWasImported = false;
502  // If Shading was imported, it should not be converted to a Highlight,
503  // but remain as Shading which is ignored for numbering.
504  if (pCleanedSet->HasItem(RES_CHRATR_GRABBAG))
505  {
506  SfxGrabBagItem aGrabBag = pCleanedSet->Get(RES_CHRATR_GRABBAG, /*bSrchInParent=*/false);
507  std::map<OUString, css::uno::Any>& rMap = aGrabBag.GetGrabBag();
508  auto aIterator = rMap.find("CharShadingMarker");
509  if (aIterator != rMap.end())
510  aIterator->second >>= bShadingWasImported;
511  }
512 
513  // If used, BACKGROUND is converted to HIGHLIGHT. So also ignore if a highlight already exists.
514  if (bShadingWasImported
515  || pCleanedSet->HasItem(RES_CHRATR_HIGHLIGHT)
516  || (pFormat && pFormat->HasItem(RES_CHRATR_HIGHLIGHT)))
517  {
518  pCleanedSet->ClearItem(pItem->Which());
519  }
520  }
521  pItem = aIter.NextItem();
522  };
523 
524  // SetDiffFnt resets the background color (why?), so capture it and re-apply if it had a value,
525  // because an existing value should override anything inherited from the paragraph marker.
526  const std::optional<Color> oFontBackColor = pNumFnt->GetBackColor();
527  // The same is true for the highlight color.
528  const Color aHighlight = pNumFnt->GetHighlightColor();
529 
530  pNumFnt->SetDiffFnt(pCleanedSet.get(), pIDSA);
531 
532  if (oFontBackColor)
533  pNumFnt->SetBackColor(oFontBackColor);
534  if (aHighlight != COL_TRANSPARENT)
535  pNumFnt->SetHighlightColor(aHighlight);
536 }
537 
539  bool& bIsMoved )
540 {
541  const SwDoc& rDoc = rTextNode.GetDoc();
542  SwRedlineTable::size_type nRedlPos = rDoc.getIDocumentRedlineAccess().GetRedlinePos( rTextNode, RedlineType::Any );
543 
544  if( SwRedlineTable::npos != nRedlPos )
545  {
546  const SwNodeOffset nNdIdx = rTextNode.GetIndex();
548  for( ; nRedlPos < rTable.size() ; ++nRedlPos )
549  {
550  const SwRangeRedline* pTmp = rTable[ nRedlPos ];
551  if( RedlineType::Delete == pTmp->GetType() ||
552  RedlineType::Insert == pTmp->GetType() )
553  {
554  const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
555  if( pRStt->nNode <= nNdIdx && pREnd->nNode > nNdIdx )
556  {
557  bIsMoved = pTmp->IsMoved();
558  return pTmp;
559  }
560  }
561  }
562  }
563  return nullptr;
564 }
565 
566 static void lcl_setRedlineAttr( SwTextFormatInfo &rInf, const SwTextNode& rTextNode, const std::unique_ptr<SwFont>& pNumFnt )
567 {
568  if ( rInf.GetVsh()->GetLayout()->IsHideRedlines() )
569  return;
570 
571  bool bIsMoved;
572  const SwRangeRedline* pRedlineNum = lcl_GetRedlineAtNodeInsertionOrDeletion( rTextNode, bIsMoved );
573  if (!pRedlineNum)
574  return;
575 
576  // moved text: dark green with double underline or strikethrough
577  if ( bIsMoved )
578  {
579  pNumFnt->SetColor(COL_GREEN);
580  if ( RedlineType::Delete == pRedlineNum->GetType() )
581  pNumFnt->SetStrikeout(STRIKEOUT_DOUBLE);
582  else
583  pNumFnt->SetUnderline(LINESTYLE_DOUBLE);
584  return;
585  }
586 
587  SwAttrPool& rPool = rInf.GetVsh()->GetDoc()->GetAttrPool();
589 
590  std::size_t aAuthor = (1 < pRedlineNum->GetStackCount())
591  ? pRedlineNum->GetAuthor( 1 )
592  : pRedlineNum->GetAuthor();
593 
594  if ( RedlineType::Delete == pRedlineNum->GetType() )
595  SW_MOD()->GetDeletedAuthorAttr(aAuthor, aSet);
596  else
597  SW_MOD()->GetInsertAuthorAttr(aAuthor, aSet);
598 
599  if (const SvxColorItem* pItem = aSet.GetItemIfSet(RES_CHRATR_COLOR))
600  pNumFnt->SetColor(pItem->GetValue());
601  if (const SvxUnderlineItem* pItem = aSet.GetItemIfSet(RES_CHRATR_UNDERLINE))
602  pNumFnt->SetUnderline(pItem->GetLineStyle());
603  if (const SvxCrossedOutItem* pItem = aSet.GetItemIfSet(RES_CHRATR_CROSSEDOUT))
604  pNumFnt->SetStrikeout( pItem->GetStrikeout() );
605 }
606 
608 {
609  if( rInf.IsNumDone() || rInf.GetTextStart() != m_nStart
610  || rInf.GetTextStart() != rInf.GetIdx() )
611  return nullptr;
612 
613  SwNumberPortion *pRet = nullptr;
614  // sw_redlinehide: at this point it's certain that pTextNd is the node with
615  // the numbering of the frame; only the actual number-vector (GetNumString)
616  // depends on the hide-mode in the layout so other calls don't need to care
617  const SwTextNode *const pTextNd = GetTextFrame()->GetTextNodeForParaProps();
618  const SwNumRule* pNumRule = pTextNd->GetNumRule();
619 
620  // Has a "valid" number?
621  // sw_redlinehide: check that pParaPropsNode is the correct one
622  assert(pTextNd->IsNumbered(m_pFrame->getRootFrame()) == pTextNd->IsNumbered(nullptr));
623  if (pTextNd->IsNumbered(m_pFrame->getRootFrame()) && pTextNd->IsCountedInList())
624  {
625  int nLevel = pTextNd->GetActualListLevel();
626 
627  if (nLevel < 0)
628  nLevel = 0;
629 
630  if (nLevel >= MAXLEVEL)
631  nLevel = MAXLEVEL - 1;
632 
633  const SwNumFormat &rNumFormat = pNumRule->Get( nLevel );
634  const bool bLeft = SvxAdjust::Left == rNumFormat.GetNumAdjust();
635  const bool bCenter = SvxAdjust::Center == rNumFormat.GetNumAdjust();
636  const bool bLabelAlignmentPosAndSpaceModeActive(
638  const sal_uInt16 nMinDist = bLabelAlignmentPosAndSpaceModeActive
639  ? 0 : rNumFormat.GetCharTextDistance();
640 
641  if( SVX_NUM_BITMAP == rNumFormat.GetNumberingType() )
642  {
643  OUString referer;
644  if (auto const sh1 = rInf.GetVsh()) {
645  if (auto const doc = sh1->GetDoc()) {
646  auto const sh2 = doc->GetPersist();
647  if (sh2 != nullptr && sh2->HasName()) {
648  referer = sh2->GetMedium()->GetName();
649  }
650  }
651  }
652  pRet = new SwGrfNumPortion( pTextNd->GetLabelFollowedBy(),
653  rNumFormat.GetBrush(), referer,
654  rNumFormat.GetGraphicOrientation(),
655  rNumFormat.GetGraphicSize(),
656  bLeft, bCenter, nMinDist,
657  bLabelAlignmentPosAndSpaceModeActive );
658  tools::Long nTmpA = rInf.GetLast()->GetAscent();
659  tools::Long nTmpD = rInf.GetLast()->Height() - nTmpA;
660  if( !rInf.IsTest() )
661  static_cast<SwGrfNumPortion*>(pRet)->SetBase( nTmpA, nTmpD, nTmpA, nTmpD );
662  }
663  else
664  {
665  // The SwFont is created dynamically and passed in the ctor,
666  // as the CharFormat only returns an SV-Font.
667  // In the dtor of SwNumberPortion, the SwFont is deleted.
668  const SwAttrSet* pFormat = rNumFormat.GetCharFormat() ?
669  &rNumFormat.GetCharFormat()->GetAttrSet() :
670  nullptr;
671  const IDocumentSettingAccess* pIDSA = pTextNd->getIDocumentSettingAccess();
672 
673  if( SVX_NUM_CHAR_SPECIAL == rNumFormat.GetNumberingType() )
674  {
675  const std::optional<vcl::Font> pFormatFnt = rNumFormat.GetBulletFont();
676 
677  // Build a new bullet font basing on the current paragraph font:
678  std::unique_ptr<SwFont> pNumFnt(new SwFont( &rInf.GetCharAttr(), pIDSA ));
679 
680  // #i53199#
682  {
683  // i18463:
684  // Underline style of paragraph font should not be considered
685  // Overline style of paragraph font should not be considered
686  // Weight style of paragraph font should not be considered
687  // Posture style of paragraph font should not be considered
688  pNumFnt->SetUnderline( LINESTYLE_NONE );
689  pNumFnt->SetOverline( LINESTYLE_NONE );
690  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::Latin );
691  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CJK );
692  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CTL );
693  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::Latin );
694  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CJK );
695  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CTL );
696  }
697 
698  // Apply the explicit attributes from the character style
699  // associated with the numbering to the new bullet font.
700  if( pFormat )
701  pNumFnt->SetDiffFnt( pFormat, pIDSA );
702 
703  checkApplyParagraphMarkFormatToNumbering(pNumFnt.get(), rInf, pIDSA, pFormat);
704 
705  if ( pFormatFnt )
706  {
707  const SwFontScript nAct = pNumFnt->GetActual();
708  pNumFnt->SetFamily( pFormatFnt->GetFamilyType(), nAct );
709  pNumFnt->SetName( pFormatFnt->GetFamilyName(), nAct );
710  pNumFnt->SetStyleName( pFormatFnt->GetStyleName(), nAct );
711  pNumFnt->SetCharSet( pFormatFnt->GetCharSet(), nAct );
712  pNumFnt->SetPitch( pFormatFnt->GetPitch(), nAct );
713  }
714 
715  // we do not allow a vertical font
716  pNumFnt->SetVertical( pNumFnt->GetOrientation(),
717  m_pFrame->IsVertical() );
718 
719  lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt );
720 
721  // --> OD 2008-01-23 #newlistelevelattrs#
722  if (rNumFormat.GetBulletChar())
723  {
724  pRet = new SwBulletPortion(rNumFormat.GetBulletChar(),
725  pTextNd->GetLabelFollowedBy(),
726  std::move(pNumFnt),
727  bLeft, bCenter, nMinDist,
728  bLabelAlignmentPosAndSpaceModeActive);
729  }
730  }
731  else
732  {
733  OUString aText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame()) );
734  if ( !aText.isEmpty() )
735  {
736  aText += pTextNd->GetLabelFollowedBy();
737  }
738 
739  // Not just an optimization ...
740  // A number portion without text will be assigned a width of 0.
741  // The succeeding text portion will flow into the BreakCut in the BreakLine,
742  // although we have rInf.GetLast()->GetFlyPortion()!
743  if( !aText.isEmpty() )
744  {
745 
746  // Build a new numbering font basing on the current paragraph font:
747  std::unique_ptr<SwFont> pNumFnt(new SwFont( &rInf.GetCharAttr(), pIDSA ));
748 
749  // #i53199#
751  {
752  // i18463:
753  // Underline style of paragraph font should not be considered
754  pNumFnt->SetUnderline( LINESTYLE_NONE );
755  // Overline style of paragraph font should not be considered
756  pNumFnt->SetOverline( LINESTYLE_NONE );
757  }
758 
759  // Apply the explicit attributes from the character style
760  // associated with the numbering to the new bullet font.
761  if( pFormat )
762  pNumFnt->SetDiffFnt( pFormat, pIDSA );
763 
764  checkApplyParagraphMarkFormatToNumbering(pNumFnt.get(), rInf, pIDSA, pFormat);
765 
766  lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt );
767 
768  // we do not allow a vertical font
769  pNumFnt->SetVertical( pNumFnt->GetOrientation(), m_pFrame->IsVertical() );
770 
771  pRet = new SwNumberPortion( aText, std::move(pNumFnt),
772  bLeft, bCenter, nMinDist,
773  bLabelAlignmentPosAndSpaceModeActive );
774  }
775  }
776  }
777  }
778  return pRet;
779 }
780 
781 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxNumType GetNumberingType() const
Base class of the Writer layout elements.
Definition: frame.hxx:314
constexpr TypedWhichId< SvxCrossedOutItem > RES_CHRATR_CROSSEDOUT(5)
SwViewShell * GetVsh()
Definition: inftxt.hxx:221
Marks a position in the document model.
Definition: pam.hxx:36
const SwField * GetField() const
Definition: fmtfld.hxx:116
bool IsInDocBody() const
Definition: frame.hxx:943
sal_UCS4 GetBulletChar() const
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:408
OUString GetLabelFollowedBy() const
Retrieves the character following the list label, if the paragraph's list level defines one...
Definition: ndtxt.cxx:4521
SwFlyCntPortion * NewFlyCntPortion(SwTextFormatInfo &rInf, SwTextAttr *pHt) const
Sets a new portion for an object anchored as character.
Definition: itrform2.cxx:2661
SwExpandPortion * NewFieldPortion(SwTextFormatInfo &rInf, const SwTextAttr *pHt) const
Definition: txtfld.cxx:76
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_METAFIELD(49)
SwViewShellImp * Imp()
Definition: viewsh.hxx:182
SwTextAttr * GetAttr(TextFrameIndex nPos) const
Returns the attribute for a position.
Definition: itratr.cxx:143
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:403
SwNodeIndex nNode
Definition: pam.hxx:38
const SvxBrushItem * GetBrush() const
long Long
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
Base class of all fields.
Definition: fldbas.hxx:291
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:390
Definition: doc.hxx:187
bool IsNumDone() const
Definition: inftxt.hxx:628
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
sal_uInt16 FirstWhich()
void SetLen(TextFrameIndex const nLen)
Definition: porlin.hxx:76
Distinguish only for painting/hide.
Definition: porfld.hxx:118
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
SwFont * m_pFont
Definition: itratr.hxx:39
bool SeekAndChg(SwTextSizeInfo &rInf)
Definition: itrtxt.hxx:310
sal_uInt16 Which() const
Definition: txatbase.hxx:116
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:161
constexpr TypedWhichId< SfxGrabBagItem > RES_CHRATR_GRABBAG(43)
The root element of a Writer document layout.
Definition: rootfrm.hxx:81
For old documents the Field-Which IDs must be preserved !!!
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4116
sal_uInt16 NextWhich()
SvxNumType
size_type size() const
Definition: docary.hxx:267
bool IsFieldName() const
Definition: viewopt.hxx:269
const SfxPoolItem * NextItem()
SwExpandPortion * TryNewNoLengthPortion(SwTextFormatInfo const &rInfo)
Try to create a new portion with zero length, for an end of a hint (where there is no CH_TXTATR)...
Definition: txtfld.cxx:321
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
LINESTYLE_NONE
void ChangeExpansion(SwDoc *pDoc, bool bVirtPageNum, const SvxNumType *pNumFormat)
Definition: docufld.cxx:129
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
static const SwRangeRedline * lcl_GetRedlineAtNodeInsertionOrDeletion(const SwTextNode &rTextNode, bool &bIsMoved)
Definition: txtfld.cxx:538
short GetCharTextDistance() const
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1111
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
const std::optional< Color > & GetBackColor() const
Definition: swfont.hxx:191
sal_uInt16 GetStackCount() const
Definition: docredln.cxx:1906
This portion represents a part of the paragraph string.
Definition: portxt.hxx:26
SVX_NUM_BITMAP
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1806
SVX_NUM_CHAR_SPECIAL
SwCharFormat * GetCharFormat() const
Definition: numrule.hxx:74
static void lcl_setRedlineAttr(SwTextFormatInfo &rInf, const SwTextNode &rTextNode, const std::unique_ptr< SwFont > &pNumFnt)
Definition: txtfld.cxx:566
static SwFieldPortion * lcl_NewMetaPortion(SwTextAttr &rHint, const bool bPrefix)
Definition: txtfld.cxx:298
const SwFormatVertOrient * GetGraphicOrientation() const
Definition: number.cxx:351
const SwViewOption & GetOpt() const
Definition: inftxt.hxx:238
Used in for asian layout specialities to display up to six characters in 2 rows and 2-3 columns...
Definition: porfld.hxx:210
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1306
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
#define SW_MOD()
Definition: swmodule.hxx:255
SwFootnotePortion * NewFootnotePortion(SwTextFormatInfo &rInf, SwTextAttr *pHt)
The portion for the Footnote Reference in the Text.
Definition: txtftn.cxx:792
SwDoc & GetDoc()
Definition: node.hxx:213
void ChgBodyTextFlag(bool bIsInBody)
Set by UpdateExpFields where node position is known.
Definition: expfld.hxx:142
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(58)
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:143
SwNumberPortion * NewNumberPortion(SwTextFormatInfo &rInf) const
Definition: txtfld.cxx:607
SwNodeOffset GetIndex() const
Definition: node.hxx:292
vector_type::size_type size_type
Definition: docary.hxx:222
SwLinePortion * NewExtraPortion(SwTextFormatInfo &rInf)
Definition: txtfld.cxx:360
std::unique_ptr< sw::MergedAttrIterByEnd > m_pByEndIter
Definition: itrform2.hxx:45
WEIGHT_NORMAL
bool IsInBodyText() const
Called by formatting.
Definition: expfld.hxx:138
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2833
const std::map< OUString, css::uno::Any > & GetGrabBag() const
Provides access to settings of a document.
SwFont * GetFnt()
Definition: itratr.hxx:103
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:271
const IDocumentSettingAccess * getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: node.cxx:2094
SvxAdjust GetNumAdjust() const
bool IsUpdateExpFields()
Definition: viewimp.cxx:190
ITALIC_NONE
SwTwips Height() const
Definition: possiz.hxx:49
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
Represents the style of a text portion.
Definition: charfmt.hxx:26
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:284
const SwPosition * Start() const
Definition: pam.hxx:213
const SwAttrSet & GetCharAttr() const
Definition: inftxt.hxx:768
void SetNoLength()
Definition: porfld.hxx:58
SwFieldType * GetTyp() const
Definition: fldbas.hxx:398
static void checkApplyParagraphMarkFormatToNumbering(SwFont *pNumFnt, SwTextFormatInfo &rInf, const IDocumentSettingAccess *pIDSA, const SwAttrSet *pFormat)
OOXML spec says that w:rPr inside w:pPr specifies formatting for the paragraph mark symbol (i...
Definition: txtfld.cxx:420
SwTwips & GetAscent()
Definition: porlin.hxx:78
constexpr TypedWhichId< SwFormatField > RES_TXTATR_ANNOTATION(60)
constexpr TypedWhichId< SvxColorItem > RES_CHRATR_COLOR(3)
SwTextFrame * m_pFrame
Definition: itrtxt.hxx:34
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:51
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:86
constexpr TypedWhichId< SvxBrushItem > RES_CHRATR_BACKGROUND(21)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
SVX_NUM_PAGEDESC
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:484
LanguageType GetLanguage() const
Definition: swfont.hxx:282
TextFrameIndex m_nStart
Definition: itrtxt.hxx:41
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
bool IsMoved() const
Definition: redline.hxx:273
const Size & GetGraphicSize() const
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
void SetLen(const TextFrameIndex nNew)
Definition: inftxt.hxx:274
virtual void SetLanguage(LanguageType nLng)
Definition: fldbas.cxx:442
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
STRIKEOUT_DOUBLE
std::size_t GetAuthor(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1914
void SetBackColor(std::optional< Color > xNewColor)
Definition: swfont.cxx:64
static bool IsIgnoredCharFormatForNumbering(const sal_uInt16 nWhich, bool bIsCharStyle=false)
In MS Word, the font underline setting of the paragraph end position won't affect the formatting of n...
Definition: thints.cxx:1845
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2901
constexpr::Color COL_GREEN(0x00, 0x80, 0x00)
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1255
bool IsCountedInList() const
Definition: ndtxt.cxx:4253
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
const SwPosition * End() const
Definition: pam.hxx:218
void GetPrefixAndSuffix(OUString *const o_pPrefix, OUString *const o_pSuffix, OUString *const o_pShadingColor)
get prefix/suffix from the RDF repository.
Definition: fmtatr2.cxx:734
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:164
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1929
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
virtual OUString GetFieldName() const
get name or content
Definition: fldbas.cxx:305
constexpr TypedWhichId< SwTOXMark > RES_TXTATR_TOXMARK(47)
SwFontScript
Definition: swfont.hxx:122
SwLinePortion * GetLast()
Definition: inftxt.hxx:560
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:421
const Color & GetHighlightColor() const
Definition: swfont.hxx:193
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
constexpr sal_uInt16 RES_CHRATR_END(46)
OUString GetNumString(const bool _bInclPrefixAndSuffixStrings=true, const unsigned int _nRestrictToThisLevel=MAXLEVEL, SwRootFrame const *pLayout=nullptr) const
Returns outline of numbering string.
Definition: ndtxt.cxx:3138
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:167
bool IsVertical() const
Definition: frame.hxx:973
constexpr TypedWhichId< SwFormatAutoFormat > RES_PARATR_LIST_AUTOFMT(87)
SwDoc & GetDoc()
Definition: txtfrm.hxx:461
void SetDiffFnt(const SfxItemSet *pSet, const IDocumentSettingAccess *pIDocumentSettingAccess)
Definition: swfont.cxx:473
bool IsTest() const
Definition: inftxt.hxx:587
SwTextFrame * GetTextFrame()
Definition: itrtxt.hxx:134
LINESTYLE_DOUBLE
const SwFrame * GetAnchorFrame() const
constexpr TypedWhichId< SwFormatRefMark > RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN)
void ChangeExpansion(const SwFrame &, const SwTextField &)
For fields in header/footer/footnotes/flys: Only called by formatting!!
Definition: expfld.cxx:344
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
virtual const SwRedlineTable & GetRedlineTable() const =0
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:731
void ChgBodyTextFlag(bool bIsInBody)
set from UpdateExpFields (the Node-Position is known there)
Definition: dbfld.hxx:118
void SetHighlightColor(const Color &aNewColor)
Definition: swfont.hxx:944
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
constexpr TypedWhichId< SvxBrushItem > RES_CHRATR_HIGHLIGHT(42)
static constexpr size_type npos
Definition: docary.hxx:223
SwFieldIds Which() const
Definition: fldbas.hxx:273
aStr
sal_uInt16 GetPageNum() const
Definition: rootfrm.hxx:312
TextFrameIndex GetTextStart() const
Definition: inftxt.hxx:123
sal_uInt16 Which() const
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
const SfxPoolItem * GetCurItem() const
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1318
bool IsVirtPageNum() const
Definition: rootfrm.hxx:315
const std::optional< vcl::Font > & GetBulletFont() const
static bool lcl_IsInBody(SwFrame const *pFrame)
Definition: txtfld.cxx:62
const SvxNumberType & GetNumType() const
Definition: pagedesc.hxx:202