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  pField->GetPrefixAndSuffix(bPrefix ? &fix : nullptr, bPrefix ? nullptr : &fix);
308  }
309  return new SwFieldPortion( fix );
310 }
311 
321 {
322  const TextFrameIndex nIdx(rInfo.GetIdx());
323 
324  // sw_redlinehide: because there is a dummy character at the start of these
325  // hints, it's impossible to have ends of hints from different nodes at the
326  // same view position, so it's sufficient to check the hints of the current
327  // node. However, m_pByEndIter exists for the whole text frame, so
328  // it's necessary to iterate all hints for that purpose...
329  if (!m_pByEndIter)
330  {
332  }
333  SwTextNode const* pNode(nullptr);
334  for (SwTextAttr const* pHint = m_pByEndIter->NextAttr(pNode); pHint;
335  pHint = m_pByEndIter->NextAttr(pNode))
336  {
337  SwTextAttr & rHint(const_cast<SwTextAttr&>(*pHint));
338  TextFrameIndex const nEnd(
339  rInfo.GetTextFrame()->MapModelToView(pNode, rHint.GetAnyEnd()));
340  if (nEnd > nIdx)
341  {
342  m_pByEndIter->PrevAttr();
343  break;
344  }
345  if (nEnd == nIdx)
346  {
347  if (RES_TXTATR_METAFIELD == rHint.Which())
348  {
349  SwFieldPortion *const pPortion(
350  lcl_NewMetaPortion(rHint, false));
351  pPortion->SetNoLength(); // no CH_TXTATR at hint end!
352  return pPortion;
353  }
354  }
355  }
356  return nullptr;
357 }
358 
360 {
361  SwTextAttr *pHint = GetAttr( rInf.GetIdx() );
362  SwLinePortion *pRet = nullptr;
363  if( !pHint )
364  {
365  pRet = new SwTextPortion;
366  pRet->SetLen(TextFrameIndex(1));
367  rInf.SetLen(TextFrameIndex(1));
368  return pRet;
369  }
370 
371  switch( pHint->Which() )
372  {
373  case RES_TXTATR_FLYCNT :
374  {
375  pRet = NewFlyCntPortion( rInf, pHint );
376  break;
377  }
378  case RES_TXTATR_FTN :
379  {
380  pRet = NewFootnotePortion( rInf, pHint );
381  break;
382  }
383  case RES_TXTATR_FIELD :
384  case RES_TXTATR_ANNOTATION :
385  {
386  pRet = NewFieldPortion( rInf, pHint );
387  break;
388  }
389  case RES_TXTATR_REFMARK :
390  {
391  pRet = new SwIsoRefPortion;
392  break;
393  }
394  case RES_TXTATR_TOXMARK :
395  {
396  pRet = new SwIsoToxPortion;
397  break;
398  }
400  {
401  pRet = lcl_NewMetaPortion( *pHint, true );
402  break;
403  }
404  default: ;
405  }
406  if( !pRet )
407  {
408  pRet = new SwFieldPortion( "" );
409  rInf.SetLen(TextFrameIndex(1));
410  }
411  return pRet;
412 }
413 
420  const IDocumentSettingAccess* pIDSA,
421  const SwAttrSet* pFormat)
422 {
424  return;
425 
426  SwFormatAutoFormat const& rListAutoFormat(static_cast<SwFormatAutoFormat const&>(rInf.GetTextFrame()->GetTextNodeForParaProps()->GetAttr(RES_PARATR_LIST_AUTOFMT)));
427  std::shared_ptr<SfxItemSet> pSet(rListAutoFormat.GetStyleHandle());
428 
429  // TODO remove this fallback (for WW8/RTF)
430  bool isDOCX = pIDSA->get(DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS);
431  if (!isDOCX && !pSet)
432  {
433  TextFrameIndex const nTextLen(rInf.GetTextFrame()->GetText().getLength());
434  SwTextNode const* pNode(nullptr);
436  for (SwTextAttr const* pHint = iter.PrevAttr(&pNode); pHint;
437  pHint = iter.PrevAttr(&pNode))
438  {
439  TextFrameIndex const nHintEnd(
440  rInf.GetTextFrame()->MapModelToView(pNode, pHint->GetAnyEnd()));
441  if (nHintEnd < nTextLen)
442  {
443  break; // only those at para end are interesting
444  }
445  // Formatting for the paragraph mark is usually set to apply only to the
446  // (non-existent) extra character at end of the text node, but there can be
447  // other hints too (ending at nTextLen), so look for all matching hints.
448  // Still the (non-existent) extra character at the end is preferred if it exists.
449  if (pHint->Which() == RES_TXTATR_AUTOFMT)
450  {
451  pSet = pHint->GetAutoFormat().GetStyleHandle();
452  // When we find an empty hint (start == end) we got what we are looking for.
453  if (pHint->GetStart() == *pHint->End())
454  break;
455  }
456  }
457  }
458 
459  // Check each item and in case it should be ignored, then clear it.
460  if (!pSet)
461  return;
462 
463  std::unique_ptr<SfxItemSet> const pCleanedSet = pSet->Clone();
464 
465  if (pCleanedSet->HasItem(RES_TXTATR_CHARFMT))
466  {
467  // Insert attributes of referenced char format into current set
468  const SwFormatCharFormat& rCharFormat = pCleanedSet->Get(RES_TXTATR_CHARFMT);
469  const SwAttrSet& rStyleAttrs = static_cast<const SwCharFormat *>(rCharFormat.GetRegisteredIn())->GetAttrSet();
470  SfxWhichIter aIter(rStyleAttrs);
471  sal_uInt16 nWhich = aIter.FirstWhich();
472  while (nWhich)
473  {
474  if (!SwTextNode::IsIgnoredCharFormatForNumbering(nWhich, /*bIsCharStyle=*/true)
475  && !pCleanedSet->HasItem(nWhich)
476  && !(pFormat && pFormat->HasItem(nWhich)) )
477  {
478  // Copy from parent sets only allowed items which will not overwrite
479  // values explicitly defined in current set (pCleanedSet) or in pFormat
480  if (const SfxPoolItem* pItem = rStyleAttrs.GetItem(nWhich, true))
481  pCleanedSet->Put(*pItem);
482  }
483  nWhich = aIter.NextWhich();
484  }
485 
486  // It is not required here anymore, all referenced items are inserted
487  pCleanedSet->ClearItem(RES_TXTATR_CHARFMT);
488  };
489 
490  SfxItemIter aIter(*pSet);
491  const SfxPoolItem* pItem = aIter.GetCurItem();
492  while (pItem)
493  {
495  pCleanedSet->ClearItem(pItem->Which());
496  else if (pFormat && pFormat->HasItem(pItem->Which()))
497  pCleanedSet->ClearItem(pItem->Which());
498  else if (pItem->Which() == RES_CHRATR_BACKGROUND)
499  {
500  bool bShadingWasImported = false;
501  // If Shading was imported, it should not be converted to a Highlight,
502  // but remain as Shading which is ignored for numbering.
503  if (pCleanedSet->HasItem(RES_CHRATR_GRABBAG))
504  {
505  SfxGrabBagItem aGrabBag = pCleanedSet->Get(RES_CHRATR_GRABBAG, /*bSrchInParent=*/false);
506  std::map<OUString, css::uno::Any>& rMap = aGrabBag.GetGrabBag();
507  auto aIterator = rMap.find("CharShadingMarker");
508  if (aIterator != rMap.end())
509  aIterator->second >>= bShadingWasImported;
510  }
511 
512  // If used, BACKGROUND is converted to HIGHLIGHT. So also ignore if a highlight already exists.
513  if (bShadingWasImported
514  || pCleanedSet->HasItem(RES_CHRATR_HIGHLIGHT)
515  || (pFormat && pFormat->HasItem(RES_CHRATR_HIGHLIGHT)))
516  {
517  pCleanedSet->ClearItem(pItem->Which());
518  }
519  }
520  pItem = aIter.NextItem();
521  };
522 
523  // SetDiffFnt resets the background color (why?), so capture it and re-apply if it had a value,
524  // because an existing value should override anything inherited from the paragraph marker.
525  const std::optional<Color> oFontBackColor = pNumFnt->GetBackColor();
526  // The same is true for the highlight color.
527  const Color aHighlight = pNumFnt->GetHighlightColor();
528 
529  pNumFnt->SetDiffFnt(pCleanedSet.get(), pIDSA);
530 
531  if (oFontBackColor)
532  pNumFnt->SetBackColor(oFontBackColor);
533  if (aHighlight != COL_TRANSPARENT)
534  pNumFnt->SetHighlightColor(aHighlight);
535 }
536 
538 {
539  const SwDoc& rDoc = rTextNode.GetDoc();
540  SwRedlineTable::size_type nRedlPos = rDoc.getIDocumentRedlineAccess().GetRedlinePos( rTextNode, RedlineType::Any );
541 
542  if( SwRedlineTable::npos != nRedlPos )
543  {
544  const sal_uLong nNdIdx = rTextNode.GetIndex();
545  for( ; nRedlPos < rDoc.getIDocumentRedlineAccess().GetRedlineTable().size() ; ++nRedlPos )
546  {
547  const SwRangeRedline* pTmp = rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
548  if( RedlineType::Delete == pTmp->GetType() ||
549  RedlineType::Insert == pTmp->GetType() )
550  {
551  const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
552  if( pRStt->nNode < nNdIdx && pREnd->nNode >= nNdIdx )
553  return pTmp;
554  }
555  }
556  }
557  return nullptr;
558 }
559 
560 static void lcl_setRedlineAttr( SwTextFormatInfo &rInf, const SwTextNode& rTextNode, const std::unique_ptr<SwFont>& pNumFnt )
561 {
562  if ( rInf.GetVsh()->GetLayout()->IsHideRedlines() )
563  return;
564 
565  const SwRangeRedline* pRedlineNum = lcl_GetRedlineAtNodeInsertionOrDeletion( rTextNode );
566  if (!pRedlineNum)
567  return;
568 
569  std::unique_ptr<SfxItemSet> pSet;
570 
571  SwAttrPool& rPool = rInf.GetVsh()->GetDoc()->GetAttrPool();
572  pSet = std::make_unique<SfxItemSet>(rPool, svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1>{});
573 
574  std::size_t aAuthor = (1 < pRedlineNum->GetStackCount())
575  ? pRedlineNum->GetAuthor( 1 )
576  : pRedlineNum->GetAuthor();
577 
578  if ( RedlineType::Delete == pRedlineNum->GetType() )
579  SW_MOD()->GetDeletedAuthorAttr(aAuthor, *pSet);
580  else
581  SW_MOD()->GetInsertAuthorAttr(aAuthor, *pSet);
582 
583  const SfxPoolItem* pItem = nullptr;
584  if (SfxItemState::SET == pSet->GetItemState(RES_CHRATR_COLOR, true, &pItem))
585  pNumFnt->SetColor(static_cast<const SvxColorItem*>(pItem)->GetValue());
586  if (SfxItemState::SET == pSet->GetItemState(RES_CHRATR_UNDERLINE, true, &pItem))
587  pNumFnt->SetUnderline(static_cast<const SvxUnderlineItem*>(pItem)->GetLineStyle());
588  if (SfxItemState::SET == pSet->GetItemState(RES_CHRATR_CROSSEDOUT, true, &pItem))
589  pNumFnt->SetStrikeout( static_cast<const SvxCrossedOutItem*>(pItem)->GetStrikeout() );
590 }
591 
593 {
594  if( rInf.IsNumDone() || rInf.GetTextStart() != m_nStart
595  || rInf.GetTextStart() != rInf.GetIdx() )
596  return nullptr;
597 
598  SwNumberPortion *pRet = nullptr;
599  // sw_redlinehide: at this point it's certain that pTextNd is the node with
600  // the numbering of the frame; only the actual number-vector (GetNumString)
601  // depends on the hide-mode in the layout so other calls don't need to care
602  const SwTextNode *const pTextNd = GetTextFrame()->GetTextNodeForParaProps();
603  const SwNumRule* pNumRule = pTextNd->GetNumRule();
604 
605  // Has a "valid" number?
606  // sw_redlinehide: check that pParaPropsNode is the correct one
607  assert(pTextNd->IsNumbered(m_pFrame->getRootFrame()) == pTextNd->IsNumbered(nullptr));
608  if (pTextNd->IsNumbered(m_pFrame->getRootFrame()) && pTextNd->IsCountedInList())
609  {
610  int nLevel = pTextNd->GetActualListLevel();
611 
612  if (nLevel < 0)
613  nLevel = 0;
614 
615  if (nLevel >= MAXLEVEL)
616  nLevel = MAXLEVEL - 1;
617 
618  const SwNumFormat &rNumFormat = pNumRule->Get( nLevel );
619  const bool bLeft = SvxAdjust::Left == rNumFormat.GetNumAdjust();
620  const bool bCenter = SvxAdjust::Center == rNumFormat.GetNumAdjust();
621  const bool bLabelAlignmentPosAndSpaceModeActive(
623  const sal_uInt16 nMinDist = bLabelAlignmentPosAndSpaceModeActive
624  ? 0 : rNumFormat.GetCharTextDistance();
625 
626  if( SVX_NUM_BITMAP == rNumFormat.GetNumberingType() )
627  {
628  OUString referer;
629  if (auto const sh1 = rInf.GetVsh()) {
630  if (auto const doc = sh1->GetDoc()) {
631  auto const sh2 = doc->GetPersist();
632  if (sh2 != nullptr && sh2->HasName()) {
633  referer = sh2->GetMedium()->GetName();
634  }
635  }
636  }
637  pRet = new SwGrfNumPortion( pTextNd->GetLabelFollowedBy(),
638  rNumFormat.GetBrush(), referer,
639  rNumFormat.GetGraphicOrientation(),
640  rNumFormat.GetGraphicSize(),
641  bLeft, bCenter, nMinDist,
642  bLabelAlignmentPosAndSpaceModeActive );
643  tools::Long nTmpA = rInf.GetLast()->GetAscent();
644  tools::Long nTmpD = rInf.GetLast()->Height() - nTmpA;
645  if( !rInf.IsTest() )
646  static_cast<SwGrfNumPortion*>(pRet)->SetBase( nTmpA, nTmpD, nTmpA, nTmpD );
647  }
648  else
649  {
650  // The SwFont is created dynamically and passed in the ctor,
651  // as the CharFormat only returns an SV-Font.
652  // In the dtor of SwNumberPortion, the SwFont is deleted.
653  const SwAttrSet* pFormat = rNumFormat.GetCharFormat() ?
654  &rNumFormat.GetCharFormat()->GetAttrSet() :
655  nullptr;
656  const IDocumentSettingAccess* pIDSA = pTextNd->getIDocumentSettingAccess();
657 
658  if( SVX_NUM_CHAR_SPECIAL == rNumFormat.GetNumberingType() )
659  {
660  const vcl::Font *pFormatFnt = rNumFormat.GetBulletFont();
661 
662  // Build a new bullet font basing on the current paragraph font:
663  std::unique_ptr<SwFont> pNumFnt(new SwFont( &rInf.GetCharAttr(), pIDSA ));
664 
665  // #i53199#
667  {
668  // i18463:
669  // Underline style of paragraph font should not be considered
670  // Overline style of paragraph font should not be considered
671  // Weight style of paragraph font should not be considered
672  // Posture style of paragraph font should not be considered
673  pNumFnt->SetUnderline( LINESTYLE_NONE );
674  pNumFnt->SetOverline( LINESTYLE_NONE );
675  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::Latin );
676  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CJK );
677  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CTL );
678  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::Latin );
679  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CJK );
680  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CTL );
681  }
682 
683  // Apply the explicit attributes from the character style
684  // associated with the numbering to the new bullet font.
685  if( pFormat )
686  pNumFnt->SetDiffFnt( pFormat, pIDSA );
687 
688  checkApplyParagraphMarkFormatToNumbering(pNumFnt.get(), rInf, pIDSA, pFormat);
689 
690  if ( pFormatFnt )
691  {
692  const SwFontScript nAct = pNumFnt->GetActual();
693  pNumFnt->SetFamily( pFormatFnt->GetFamilyType(), nAct );
694  pNumFnt->SetName( pFormatFnt->GetFamilyName(), nAct );
695  pNumFnt->SetStyleName( pFormatFnt->GetStyleName(), nAct );
696  pNumFnt->SetCharSet( pFormatFnt->GetCharSet(), nAct );
697  pNumFnt->SetPitch( pFormatFnt->GetPitch(), nAct );
698  }
699 
700  // we do not allow a vertical font
701  pNumFnt->SetVertical( pNumFnt->GetOrientation(),
702  m_pFrame->IsVertical() );
703 
704  lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt );
705 
706  // --> OD 2008-01-23 #newlistelevelattrs#
707  if (rNumFormat.GetBulletChar())
708  {
709  pRet = new SwBulletPortion(rNumFormat.GetBulletChar(),
710  pTextNd->GetLabelFollowedBy(),
711  std::move(pNumFnt),
712  bLeft, bCenter, nMinDist,
713  bLabelAlignmentPosAndSpaceModeActive);
714  }
715  }
716  else
717  {
718  OUString aText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame()) );
719  if ( !aText.isEmpty() )
720  {
721  aText += pTextNd->GetLabelFollowedBy();
722  }
723 
724  // Not just an optimization ...
725  // A number portion without text will be assigned a width of 0.
726  // The succeeding text portion will flow into the BreakCut in the BreakLine,
727  // although we have rInf.GetLast()->GetFlyPortion()!
728  if( !aText.isEmpty() )
729  {
730 
731  // Build a new numbering font basing on the current paragraph font:
732  std::unique_ptr<SwFont> pNumFnt(new SwFont( &rInf.GetCharAttr(), pIDSA ));
733 
734  // #i53199#
736  {
737  // i18463:
738  // Underline style of paragraph font should not be considered
739  pNumFnt->SetUnderline( LINESTYLE_NONE );
740  // Overline style of paragraph font should not be considered
741  pNumFnt->SetOverline( LINESTYLE_NONE );
742  }
743 
744  // Apply the explicit attributes from the character style
745  // associated with the numbering to the new bullet font.
746  if( pFormat )
747  pNumFnt->SetDiffFnt( pFormat, pIDSA );
748 
749  checkApplyParagraphMarkFormatToNumbering(pNumFnt.get(), rInf, pIDSA, pFormat);
750 
751  lcl_setRedlineAttr( rInf, *pTextNd, pNumFnt );
752 
753  // we do not allow a vertical font
754  pNumFnt->SetVertical( pNumFnt->GetOrientation(), m_pFrame->IsVertical() );
755 
756  pRet = new SwNumberPortion( aText, std::move(pNumFnt),
757  bLeft, bCenter, nMinDist,
758  bLabelAlignmentPosAndSpaceModeActive );
759  }
760  }
761  }
762  }
763  return pRet;
764 }
765 
766 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxNumType GetNumberingType() const
Base class of the Writer layout elements.
Definition: frame.hxx:313
constexpr TypedWhichId< SvxCrossedOutItem > RES_CHRATR_CROSSEDOUT(5)
sal_uLong GetIndex() const
Definition: node.hxx:291
SwViewShell * GetVsh()
Definition: inftxt.hxx:221
void GetPrefixAndSuffix(OUString *const o_pPrefix, OUString *const o_pSuffix)
get prefix/suffix from the RDF repository.
Definition: fmtatr2.cxx:732
Marks a position in the document model.
Definition: pam.hxx:35
const OUString & GetFamilyName() const
const SwField * GetField() const
Definition: fmtfld.hxx:110
bool IsInDocBody() const
Definition: frame.hxx:939
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:4513
SwFlyCntPortion * NewFlyCntPortion(SwTextFormatInfo &rInf, SwTextAttr *pHt) const
Sets a new portion for an object anchored as character.
Definition: itrform2.cxx:2565
SwExpandPortion * NewFieldPortion(SwTextFormatInfo &rInf, const SwTextAttr *pHt) const
Definition: txtfld.cxx:76
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_METAFIELD(49)
sal_uInt16 Height() const
Definition: possiz.hxx: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
const OUString & GetStyleName() const
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:187
bool IsNumDone() const
Definition: inftxt.hxx:628
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(57)
sal_uInt16 FirstWhich()
void SetLen(TextFrameIndex const nLen)
Definition: porlin.hxx:74
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:1285
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:4106
FontFamily GetFamilyType()
sal_uInt16 NextWhich()
SvxNumType
size_type size() const
Definition: docary.hxx:266
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:320
LINESTYLE_NONE
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
void ChangeExpansion(SwDoc *pDoc, bool bVirtPageNum, const SvxNumType *pNumFormat)
Definition: docufld.cxx:128
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:41
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
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:1107
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
const std::optional< Color > & GetBackColor() const
Definition: swfont.hxx:190
sal_uInt16 GetStackCount() const
Definition: docredln.cxx:1787
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:560
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:1295
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:785
FontPitch GetPitch()
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:678
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:127
SwNumberPortion * NewNumberPortion(SwTextFormatInfo &rInf) const
Definition: txtfld.cxx:592
vector_type::size_type size_type
Definition: docary.hxx:228
SwLinePortion * NewExtraPortion(SwTextFormatInfo &rInf)
Definition: txtfld.cxx:359
const vcl::Font * GetBulletFont() const
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:2813
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:2092
SvxAdjust GetNumAdjust() const
bool IsUpdateExpFields()
Definition: viewimp.cxx:150
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:419
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:49
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
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: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:1795
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:2881
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1244
bool IsCountedInList() const
Definition: ndtxt.cxx:4244
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
const SwPosition * End() const
Definition: pam.hxx:217
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:159
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1810
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
static const SwRangeRedline * lcl_GetRedlineAtNodeInsertionOrDeletion(const SwTextNode &rTextNode)
Definition: txtfld.cxx:537
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:420
const Color & GetHighlightColor() const
Definition: swfont.hxx:192
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:3121
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:163
bool IsVertical() const
Definition: frame.hxx:969
constexpr TypedWhichId< SwFormatAutoFormat > RES_PARATR_LIST_AUTOFMT(87)
SwDoc & GetDoc()
Definition: txtfrm.hxx:457
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
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:342
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:725
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:2067
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:229
SwFieldIds Which() const
Definition: fldbas.hxx:272
aStr
sal_uInt16 GetPageNum() const
Definition: rootfrm.hxx:311
sal_uInt16 & GetAscent()
Definition: porlin.hxx:76
TextFrameIndex GetTextStart() const
Definition: inftxt.hxx:123
sal_uInt16 Which() const
SwRootFrame * getRootFrame()
Definition: frame.hxx:677
rtl_TextEncoding GetCharSet() const
const SfxPoolItem * GetCurItem() const
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1320
bool IsVirtPageNum() const
Definition: rootfrm.hxx:314
static bool lcl_IsInBody(SwFrame const *pFrame)
Definition: txtfld.cxx:62
const SvxNumberType & GetNumType() const
Definition: pagedesc.hxx:203