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 
427  SwFormatAutoFormat const& rListAutoFormat(static_cast<SwFormatAutoFormat const&>(rInf.GetTextFrame()->GetTextNodeForParaProps()->GetAttr(RES_PARATR_LIST_AUTOFMT)));
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 {
540  const SwDoc& rDoc = rTextNode.GetDoc();
541  SwRedlineTable::size_type nRedlPos = rDoc.getIDocumentRedlineAccess().GetRedlinePos( rTextNode, RedlineType::Any );
542 
543  if( SwRedlineTable::npos != nRedlPos )
544  {
545  const sal_uLong nNdIdx = rTextNode.GetIndex();
546  for( ; nRedlPos < rDoc.getIDocumentRedlineAccess().GetRedlineTable().size() ; ++nRedlPos )
547  {
548  const SwRangeRedline* pTmp = rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
549  if( RedlineType::Delete == pTmp->GetType() ||
550  RedlineType::Insert == pTmp->GetType() )
551  {
552  const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
553  if( pRStt->nNode < nNdIdx && pREnd->nNode >= nNdIdx )
554  return pTmp;
555  }
556  }
557  }
558  return nullptr;
559 }
560 
561 static void lcl_setRedlineAttr( SwTextFormatInfo &rInf, const SwTextNode& rTextNode, const std::unique_ptr<SwFont>& pNumFnt )
562 {
563  if ( rInf.GetVsh()->GetLayout()->IsHideRedlines() )
564  return;
565 
566  const SwRangeRedline* pRedlineNum = lcl_GetRedlineAtNodeInsertionOrDeletion( rTextNode );
567  if (!pRedlineNum)
568  return;
569 
570  SwAttrPool& rPool = rInf.GetVsh()->GetDoc()->GetAttrPool();
571  SfxItemSet aSet(rPool, svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1>);
572 
573  std::size_t aAuthor = (1 < pRedlineNum->GetStackCount())
574  ? pRedlineNum->GetAuthor( 1 )
575  : pRedlineNum->GetAuthor();
576 
577  if ( RedlineType::Delete == pRedlineNum->GetType() )
578  SW_MOD()->GetDeletedAuthorAttr(aAuthor, aSet);
579  else
580  SW_MOD()->GetInsertAuthorAttr(aAuthor, aSet);
581 
582  const SfxPoolItem* pItem = nullptr;
583  if (SfxItemState::SET == aSet.GetItemState(RES_CHRATR_COLOR, true, &pItem))
584  pNumFnt->SetColor(static_cast<const SvxColorItem*>(pItem)->GetValue());
585  if (SfxItemState::SET == aSet.GetItemState(RES_CHRATR_UNDERLINE, true, &pItem))
586  pNumFnt->SetUnderline(static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle());
587  if (SfxItemState::SET == aSet.GetItemState(RES_CHRATR_CROSSEDOUT, true, &pItem))
588  pNumFnt->SetStrikeout( static_cast<const SvxCrossedOutItem*>(pItem)->GetStrikeout() );
589 }
590 
592 {
593  if( rInf.IsNumDone() || rInf.GetTextStart() != m_nStart
594  || rInf.GetTextStart() != rInf.GetIdx() )
595  return nullptr;
596 
597  SwNumberPortion *pRet = nullptr;
598  // sw_redlinehide: at this point it's certain that pTextNd is the node with
599  // the numbering of the frame; only the actual number-vector (GetNumString)
600  // depends on the hide-mode in the layout so other calls don't need to care
601  const SwTextNode *const pTextNd = GetTextFrame()->GetTextNodeForParaProps();
602  const SwNumRule* pNumRule = pTextNd->GetNumRule();
603 
604  // Has a "valid" number?
605  // sw_redlinehide: check that pParaPropsNode is the correct one
606  assert(pTextNd->IsNumbered(m_pFrame->getRootFrame()) == pTextNd->IsNumbered(nullptr));
607  if (pTextNd->IsNumbered(m_pFrame->getRootFrame()) && pTextNd->IsCountedInList())
608  {
609  int nLevel = pTextNd->GetActualListLevel();
610 
611  if (nLevel < 0)
612  nLevel = 0;
613 
614  if (nLevel >= MAXLEVEL)
615  nLevel = MAXLEVEL - 1;
616 
617  const SwNumFormat &rNumFormat = pNumRule->Get( nLevel );
618  const bool bLeft = SvxAdjust::Left == rNumFormat.GetNumAdjust();
619  const bool bCenter = SvxAdjust::Center == rNumFormat.GetNumAdjust();
620  const bool bLabelAlignmentPosAndSpaceModeActive(
622  const sal_uInt16 nMinDist = bLabelAlignmentPosAndSpaceModeActive
623  ? 0 : rNumFormat.GetCharTextDistance();
624 
625  if( SVX_NUM_BITMAP == rNumFormat.GetNumberingType() )
626  {
627  OUString referer;
628  if (auto const sh1 = rInf.GetVsh()) {
629  if (auto const doc = sh1->GetDoc()) {
630  auto const sh2 = doc->GetPersist();
631  if (sh2 != nullptr && sh2->HasName()) {
632  referer = sh2->GetMedium()->GetName();
633  }
634  }
635  }
636  pRet = new SwGrfNumPortion( pTextNd->GetLabelFollowedBy(),
637  rNumFormat.GetBrush(), referer,
638  rNumFormat.GetGraphicOrientation(),
639  rNumFormat.GetGraphicSize(),
640  bLeft, bCenter, nMinDist,
641  bLabelAlignmentPosAndSpaceModeActive );
642  tools::Long nTmpA = rInf.GetLast()->GetAscent();
643  tools::Long nTmpD = rInf.GetLast()->Height() - nTmpA;
644  if( !rInf.IsTest() )
645  static_cast<SwGrfNumPortion*>(pRet)->SetBase( nTmpA, nTmpD, nTmpA, nTmpD );
646  }
647  else
648  {
649  // The SwFont is created dynamically and passed in the ctor,
650  // as the CharFormat only returns an SV-Font.
651  // In the dtor of SwNumberPortion, the SwFont is deleted.
652  const SwAttrSet* pFormat = rNumFormat.GetCharFormat() ?
653  &rNumFormat.GetCharFormat()->GetAttrSet() :
654  nullptr;
655  const IDocumentSettingAccess* pIDSA = pTextNd->getIDocumentSettingAccess();
656 
657  if( SVX_NUM_CHAR_SPECIAL == rNumFormat.GetNumberingType() )
658  {
659  const std::optional<vcl::Font> pFormatFnt = rNumFormat.GetBulletFont();
660 
661  // Build a new bullet font basing on the current paragraph font:
662  std::unique_ptr<SwFont> pNumFnt(new SwFont( &rInf.GetCharAttr(), pIDSA ));
663 
664  // #i53199#
666  {
667  // i18463:
668  // Underline style of paragraph font should not be considered
669  // Overline style of paragraph font should not be considered
670  // Weight style of paragraph font should not be considered
671  // Posture style of paragraph font should not be considered
672  pNumFnt->SetUnderline( LINESTYLE_NONE );
673  pNumFnt->SetOverline( LINESTYLE_NONE );
674  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::Latin );
675  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CJK );
676  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CTL );
677  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::Latin );
678  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CJK );
679  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CTL );
680  }
681 
682  // Apply the explicit attributes from the character style
683  // associated with the numbering to the new bullet font.
684  if( pFormat )
685  pNumFnt->SetDiffFnt( pFormat, pIDSA );
686 
687  checkApplyParagraphMarkFormatToNumbering(pNumFnt.get(), rInf, pIDSA, pFormat);
688 
689  if ( pFormatFnt )
690  {
691  const SwFontScript nAct = pNumFnt->GetActual();
692  pNumFnt->SetFamily( pFormatFnt->GetFamilyType(), nAct );
693  pNumFnt->SetName( pFormatFnt->GetFamilyName(), nAct );
694  pNumFnt->SetStyleName( pFormatFnt->GetStyleName(), nAct );
695  pNumFnt->SetCharSet( pFormatFnt->GetCharSet(), nAct );
696  pNumFnt->SetPitch( pFormatFnt->GetPitch(), nAct );
697  }
698 
699  // we do not allow a vertical font
700  pNumFnt->SetVertical( pNumFnt->GetOrientation(),
701  m_pFrame->IsVertical() );
702 
703  lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt );
704 
705  // --> OD 2008-01-23 #newlistelevelattrs#
706  if (rNumFormat.GetBulletChar())
707  {
708  pRet = new SwBulletPortion(rNumFormat.GetBulletChar(),
709  pTextNd->GetLabelFollowedBy(),
710  std::move(pNumFnt),
711  bLeft, bCenter, nMinDist,
712  bLabelAlignmentPosAndSpaceModeActive);
713  }
714  }
715  else
716  {
717  OUString aText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame()) );
718  if ( !aText.isEmpty() )
719  {
720  aText += pTextNd->GetLabelFollowedBy();
721  }
722 
723  // Not just an optimization ...
724  // A number portion without text will be assigned a width of 0.
725  // The succeeding text portion will flow into the BreakCut in the BreakLine,
726  // although we have rInf.GetLast()->GetFlyPortion()!
727  if( !aText.isEmpty() )
728  {
729 
730  // Build a new numbering font basing on the current paragraph font:
731  std::unique_ptr<SwFont> pNumFnt(new SwFont( &rInf.GetCharAttr(), pIDSA ));
732 
733  // #i53199#
735  {
736  // i18463:
737  // Underline style of paragraph font should not be considered
738  pNumFnt->SetUnderline( LINESTYLE_NONE );
739  // Overline style of paragraph font should not be considered
740  pNumFnt->SetOverline( LINESTYLE_NONE );
741  }
742 
743  // Apply the explicit attributes from the character style
744  // associated with the numbering to the new bullet font.
745  if( pFormat )
746  pNumFnt->SetDiffFnt( pFormat, pIDSA );
747 
748  checkApplyParagraphMarkFormatToNumbering(pNumFnt.get(), rInf, pIDSA, pFormat);
749 
750  lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt );
751 
752  // we do not allow a vertical font
753  pNumFnt->SetVertical( pNumFnt->GetOrientation(), m_pFrame->IsVertical() );
754 
755  pRet = new SwNumberPortion( aText, std::move(pNumFnt),
756  bLeft, bCenter, nMinDist,
757  bLabelAlignmentPosAndSpaceModeActive );
758  }
759  }
760  }
761  }
762  return pRet;
763 }
764 
765 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxNumType GetNumberingType() const
Base class of the Writer layout elements.
Definition: frame.hxx:315
constexpr TypedWhichId< SvxCrossedOutItem > RES_CHRATR_CROSSEDOUT(5)
sal_uLong GetIndex() const
Definition: node.hxx:291
SwViewShell * GetVsh()
Definition: inftxt.hxx:221
Marks a position in the document model.
Definition: pam.hxx:35
const SwField * GetField() const
Definition: fmtfld.hxx:110
bool IsInDocBody() const
Definition: frame.hxx:944
sal_UCS4 GetBulletChar() const
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:402
OUString GetLabelFollowedBy() const
Retrieves the character following the list label, if the paragraph's list level defines one...
Definition: ndtxt.cxx:4502
SwFlyCntPortion * NewFlyCntPortion(SwTextFormatInfo &rInf, SwTextAttr *pHt) const
Sets a new portion for an object anchored as character.
Definition: itrform2.cxx:2622
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:397
SwNodeIndex nNode
Definition: pam.hxx:37
const SvxBrushItem * GetBrush() const
sal_uIntPtr sal_uLong
long Long
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
Base class of all fields.
Definition: fldbas.hxx:289
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:390
Definition: doc.hxx:188
bool IsNumDone() const
Definition: inftxt.hxx:628
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:93
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(57)
sal_uInt16 FirstWhich()
void SetLen(TextFrameIndex const nLen)
Definition: porlin.hxx:76
Distinguish only for painting/hide.
Definition: porfld.hxx:115
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
SwFont * m_pFont
Definition: itratr.hxx:39
bool SeekAndChg(SwTextSizeInfo &rInf)
Definition: itrtxt.hxx:310
const std::shared_ptr< SfxItemSet > & GetStyleHandle() const
Definition: fmtautofmt.hxx:49
sal_uInt16 Which() const
Definition: txatbase.hxx:114
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1295
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:157
constexpr TypedWhichId< SfxGrabBagItem > RES_CHRATR_GRABBAG(43)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_ANNOTATION(59)
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
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:4095
sal_uInt16 NextWhich()
SvxNumType
size_type size() const
Definition: docary.hxx:265
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
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:41
short GetCharTextDistance() const
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
SwDoc * GetDoc() const
Definition: viewsh.hxx:281
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:195
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1112
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
const std::optional< Color > & GetBackColor() const
Definition: swfont.hxx:190
sal_uInt16 GetStackCount() const
Definition: docredln.cxx:1817
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(58)
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:561
static SwFieldPortion * lcl_NewMetaPortion(SwTextAttr &rHint, const bool bPrefix)
Definition: txtfld.cxx:298
const SwFormatVertOrient * GetGraphicOrientation() const
Definition: number.cxx:344
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:207
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1305
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
#define SW_MOD()
Definition: swmodule.hxx:256
SwFootnotePortion * NewFootnotePortion(SwTextFormatInfo &rInf, SwTextAttr *pHt)
The portion for the Footnote Reference in the Text.
Definition: txtftn.cxx:785
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
SwDoc & GetDoc()
Definition: node.hxx:212
void ChgBodyTextFlag(bool bIsInBody)
Set by UpdateExpFields where node position is known.
Definition: expfld.hxx:139
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:143
SwNumberPortion * NewNumberPortion(SwTextFormatInfo &rInf) const
Definition: txtfld.cxx:591
vector_type::size_type size_type
Definition: docary.hxx:223
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:135
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2807
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:2097
SvxAdjust GetNumAdjust() const
bool IsUpdateExpFields()
Definition: viewimp.cxx:151
ITALIC_NONE
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:284
const SwPosition * Start() const
Definition: pam.hxx:212
const SwAttrSet & GetCharAttr() const
Definition: inftxt.hxx:768
void SetNoLength()
Definition: porfld.hxx:58
SwFieldType * GetTyp() const
Definition: fldbas.hxx:392
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
sal_uInt32 Height() const
Definition: possiz.hxx:49
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:79
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:465
LanguageType GetLanguage() const
Definition: swfont.hxx:279
TextFrameIndex m_nStart
Definition: itrtxt.hxx:41
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
const Size & GetGraphicSize() const
void SetLen(const TextFrameIndex nNew)
Definition: inftxt.hxx:274
virtual void SetLanguage(LanguageType nLng)
Definition: fldbas.cxx:423
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
std::size_t GetAuthor(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1825
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:1813
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2875
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1254
bool IsCountedInList() const
Definition: ndtxt.cxx:4233
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
const SwPosition * End() const
Definition: pam.hxx:217
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:165
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1840
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
static const SwRangeRedline * lcl_GetRedlineAtNodeInsertionOrDeletion(const SwTextNode &rTextNode)
Definition: txtfld.cxx:538
virtual OUString GetFieldName() const
get name or content
Definition: fldbas.cxx:300
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:422
const Color & GetHighlightColor() const
Definition: swfont.hxx:192
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
OUString GetNumString(const bool _bInclPrefixAndSuffixStrings=true, const unsigned int _nRestrictToThisLevel=MAXLEVEL, SwRootFrame const *pLayout=nullptr) const
Returns outline of numbering string.
Definition: ndtxt.cxx:3115
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:163
bool IsVertical() const
Definition: frame.hxx:974
constexpr TypedWhichId< SwFormatAutoFormat > RES_PARATR_LIST_AUTOFMT(87)
SwDoc & GetDoc()
Definition: txtfrm.hxx:460
void SetDiffFnt(const SfxItemSet *pSet, const IDocumentSettingAccess *pIDocumentSettingAccess)
Definition: swfont.cxx:473
bool IsTest() const
Definition: inftxt.hxx:587
sal_uInt32 & GetAscent()
Definition: porlin.hxx:78
SwTextFrame * GetTextFrame()
Definition: itrtxt.hxx:134
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:120
virtual const SwRedlineTable & GetRedlineTable() const =0
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:722
void ChgBodyTextFlag(bool bIsInBody)
set from UpdateExpFields (the Node-Position is known there)
Definition: dbfld.hxx:117
void SetHighlightColor(const Color &aNewColor)
Definition: swfont.hxx:941
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2074
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:224
SwFieldIds Which() const
Definition: fldbas.hxx:272
aStr
sal_uInt16 GetPageNum() const
Definition: rootfrm.hxx:313
TextFrameIndex GetTextStart() const
Definition: inftxt.hxx:123
sal_uInt16 Which() const
SwRootFrame * getRootFrame()
Definition: frame.hxx:680
const SfxPoolItem * GetCurItem() const
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1319
bool IsVirtPageNum() const
Definition: rootfrm.hxx:316
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