LibreOffice Module sw (master)  1
number.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <hintids.hxx>
22 
23 #include <vcl/font.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <editeng/numitem.hxx>
26 #include <svl/grabbagitem.hxx>
27 #include <fmtornt.hxx>
28 #include <doc.hxx>
29 #include <charfmt.hxx>
30 #include <ndtxt.hxx>
31 #include <docary.hxx>
32 #include <SwStyleNameMapper.hxx>
33 
34 // Needed to load default bullet list configuration
35 #include <unotools/configmgr.hxx>
36 #include <unotools/configitem.hxx>
37 
38 #include <numrule.hxx>
39 #include <SwNodeNum.hxx>
40 
41 #include <list.hxx>
42 
43 #include <algorithm>
44 #include <unordered_map>
45 #include <libxml/xmlwriter.h>
46 
47 #include <rtl/ustrbuf.hxx>
49 #include <unotools/saveopt.hxx>
50 #include <osl/diagnose.h>
51 
52 #include <IDocumentListsAccess.hxx>
54 #include <IDocumentState.hxx>
55 
56 #include <com/sun/star/beans/PropertyValue.hpp>
57 #include <wrtsh.hxx>
58 
59 using namespace ::com::sun::star;
60 
61 sal_uInt16 SwNumRule::snRefCount = 0;
63  {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } };
64 
66  {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } };
67 
68 const sal_uInt16 SwNumRule::saDefNumIndents[ MAXLEVEL ] = {
79 };
80 
82 {
83  return "Outline";
84 }
85 
86 const SwNumFormat& SwNumRule::Get( sal_uInt16 i ) const
87 {
88  assert( i < MAXLEVEL && meRuleType < RULE_END );
89  return maFormats[ i ]
90  ? *maFormats[ i ]
92  ? *saBaseFormats[ meRuleType ][ i ]
94 }
95 
96 const SwNumFormat* SwNumRule::GetNumFormat( sal_uInt16 i ) const
97 {
98  const SwNumFormat * pResult = nullptr;
99 
100  assert( i < MAXLEVEL && meRuleType < RULE_END );
101  if ( i < MAXLEVEL && meRuleType < RULE_END)
102  {
103  pResult = maFormats[ i ].get();
104  }
105 
106  return pResult;
107 }
108 
109 // #i91400#
110 void SwNumRule::SetName( const OUString & rName,
111  IDocumentListsAccess& rDocListAccess)
112 {
113  if ( msName == rName )
114  return;
115 
116  if (mpNumRuleMap)
117  {
118  mpNumRuleMap->erase(msName);
119  (*mpNumRuleMap)[rName] = this;
120 
121  if ( !GetDefaultListId().isEmpty() )
122  {
123  rDocListAccess.trackChangeOfListStyleName( msName, rName );
124  }
125  }
126 
127  msName = rName;
128 }
129 
131 {
132  rTextNodeList = maTextNodeList;
133 }
134 
135 SwNumRule::tTextNodeList::size_type SwNumRule::GetTextNodeListSize() const
136 {
137  return maTextNodeList.size();
138 }
139 
141 {
142  tTextNodeList::iterator aIter =
143  std::find( maTextNodeList.begin(), maTextNodeList.end(), &rTextNode );
144 
145  if ( aIter == maTextNodeList.end() )
146  {
147  maTextNodeList.push_back( &rTextNode );
148  }
149 }
150 
152 {
153  tTextNodeList::iterator aIter =
154  std::find( maTextNodeList.begin(), maTextNodeList.end(), &rTextNode );
155 
156  if ( aIter != maTextNodeList.end() )
157  {
158  maTextNodeList.erase( aIter );
159  }
160 }
161 
162 void SwNumRule::SetNumRuleMap(std::unordered_map<OUString, SwNumRule *> *
163  pNumRuleMap)
164 {
165  mpNumRuleMap = pNumRuleMap;
166 }
167 
169 {
170  OSL_ENSURE( MAXLEVEL > nLvl, "NumLevel is out of range" );
171  return saDefNumIndents[ nLvl ];
172 }
173 
175 {
176  OSL_ENSURE( MAXLEVEL > nLvl, "NumLevel is out of range" );
177  return saDefNumIndents[ nLvl ];
178 }
179 
180 static void lcl_SetRuleChgd( SwTextNode& rNd, sal_uInt8 nLevel )
181 {
182  if( rNd.GetActualListLevel() == nLevel )
183  rNd.NumRuleChgd();
184 }
185 
188  SwClient( nullptr ),
189  m_pVertOrient(new SwFormatVertOrient( 0, text::VertOrientation::NONE))
190  ,m_cGrfBulletCP(USHRT_MAX)//For i120928,record the cp info of graphic within bullet
191 {
192 }
193 
195  SvxNumberFormat(rFormat),
196  SwClient( rFormat.GetRegisteredInNonConst() ),
197  m_pVertOrient(new SwFormatVertOrient( 0, rFormat.GetVertOrient()))
198  ,m_cGrfBulletCP(rFormat.m_cGrfBulletCP)//For i120928,record the cp info of graphic within bullet
199 {
200  sal_Int16 eMyVertOrient = rFormat.GetVertOrient();
201  SetGraphicBrush( rFormat.GetBrush(), &rFormat.GetGraphicSize(),
202  &eMyVertOrient);
203 }
204 
206  : SvxNumberFormat(rNumFormat)
207  , m_pVertOrient(new SwFormatVertOrient( 0, rNumFormat.GetVertOrient()))
208  , m_cGrfBulletCP(USHRT_MAX)
209 {
210  sal_Int16 eMyVertOrient = rNumFormat.GetVertOrient();
211  SetGraphicBrush( rNumFormat.GetBrush(), &rNumFormat.GetGraphicSize(),
212  &eMyVertOrient);
213  const OUString rCharStyleName = rNumFormat.SvxNumberFormat::GetCharFormatName();
214  if( !rCharStyleName.isEmpty() )
215  {
216  SwCharFormat* pCFormat = pDoc->FindCharFormatByName( rCharStyleName );
217  if( !pCFormat )
218  {
219  sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rCharStyleName,
221  pCFormat = nId != USHRT_MAX
223  : pDoc->MakeCharFormat( rCharStyleName, nullptr );
224  }
225  pCFormat->Add( this );
226  }
227  else
228  EndListeningAll();
229 }
230 
232 {
233 }
234 
235 // #i22362#
237 {
238  // #i30655# native numbering did not work any longer
239  // using this code. Therefore HBRINKM and I agreed upon defining
240  // IsEnumeration() as !IsItemize()
241  return !IsItemize();
242 }
243 
245 {
246  bool bResult;
247 
248  switch(GetNumberingType())
249  {
251  case SVX_NUM_BITMAP:
252  bResult = true;
253 
254  break;
255 
256  default:
257  bResult = false;
258  }
259 
260  return bResult;
261 
262 }
263 
265 {
266  SvxNumberFormat::operator=(rNumFormat);
267  StartListeningToSameModifyAs(rNumFormat);
268  //For i120928,record the cp info of graphic within bullet
269  m_cGrfBulletCP = rNumFormat.m_cGrfBulletCP;
270  return *this;
271 }
272 
273 bool SwNumFormat::operator==( const SwNumFormat& rNumFormat) const
274 {
275  bool bRet = SvxNumberFormat::operator==(rNumFormat) &&
276  GetRegisteredIn() == rNumFormat.GetRegisteredIn();
277  return bRet;
278 }
279 
281 {
282  if( pChFormat )
283  pChFormat->Add( this );
284  else
285  EndListeningAll();
286 }
287 
288 void SwNumFormat::SwClientNotify(const SwModify&, const SfxHint& rHint)
289 {
290  if (rHint.GetId() != SfxHintId::SwLegacyModify)
291  return;
292  auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
293  // Look for the NumRules object in the Doc where this NumFormat is set.
294  // The format does not need to exist!
295  const SwCharFormat* pFormat = nullptr;
296  switch(pLegacy->GetWhich())
297  {
298  case RES_ATTRSET_CHG:
299  case RES_FMT_CHG:
300  pFormat = GetCharFormat();
301  break;
302  }
303 
304  if(pFormat && !pFormat->GetDoc()->IsInDtor())
305  UpdateNumNodes(*const_cast<SwDoc*>(pFormat->GetDoc()));
306  else
307  CheckRegistration(pLegacy->m_pOld);
308 }
309 
311 {
312  if(static_cast<const SwCharFormat*>(GetRegisteredIn()))
313  return static_cast<const SwCharFormat*>(GetRegisteredIn())->GetName();
314 
315  return OUString();
316 }
317 
318 void SwNumFormat::SetGraphicBrush( const SvxBrushItem* pBrushItem, const Size* pSize,
319  const sal_Int16* pOrient)
320 {
321  if(pOrient)
322  m_pVertOrient->SetVertOrient( *pOrient );
323  SvxNumberFormat::SetGraphicBrush( pBrushItem, pSize, pOrient);
324 }
325 
327 {
328  bool bDocIsModified = rDoc.getIDocumentState().IsModified();
329  bool bFnd = false;
330  for( SwNumRuleTable::size_type n = rDoc.GetNumRuleTable().size(); !bFnd && n; )
331  {
332  const SwNumRule* pRule = rDoc.GetNumRuleTable()[ --n ];
333  for( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
334  if( pRule->GetNumFormat( i ) == this )
335  {
336  SwNumRule::tTextNodeList aTextNodeList;
337  pRule->GetTextNodeList( aTextNodeList );
338  for ( auto& rpTextNode : aTextNodeList )
339  {
340  lcl_SetRuleChgd( *rpTextNode, i );
341  }
342  bFnd = true;
343  break;
344  }
345  }
346 
347  if( bFnd && !bDocIsModified )
349 }
350 
352 {
353  sal_Int16 eOrient = SvxNumberFormat::GetVertOrient();
354  if(text::VertOrientation::NONE == eOrient)
355  return nullptr;
356  else
357  {
358  m_pVertOrient->SetVertOrient(eOrient);
359  return m_pVertOrient.get();
360  }
361 }
362 
363 SwNumRule::SwNumRule( const OUString& rNm,
364  const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode,
365  SwNumRuleType eType )
366  : mpNumRuleMap(nullptr),
367  msName( rNm ),
368  meRuleType( eType ),
369  mnPoolFormatId( USHRT_MAX ),
370  mnPoolHelpId( USHRT_MAX ),
371  mnPoolHlpFileId( UCHAR_MAX ),
372  mbAutoRuleFlag( true ),
373  mbInvalidRuleFlag( true ),
374  mbContinusNum( false ),
375  mbAbsSpaces( false ),
376  mbHidden( false ),
377  mbCountPhantoms( true ),
378  mbUsedByRedline( false ),
379  meDefaultNumberFormatPositionAndSpaceMode( eDefaultNumberFormatPositionAndSpaceMode )
380 {
381  if( !snRefCount++ ) // for the first time, initialize
382  {
383  SwNumFormat* pFormat;
384  sal_uInt8 n;
385 
386  // numbering:
387  // position-and-space mode LABEL_WIDTH_AND_POSITION:
388  for( n = 0; n < MAXLEVEL; ++n )
389  {
390  pFormat = new SwNumFormat;
391  pFormat->SetIncludeUpperLevels( 1 );
392  pFormat->SetStart( 1 );
395  pFormat->SetListFormat("%" + OUString::number(n + 1) + "%.");
397  SwNumRule::saBaseFormats[ NUM_RULE ][ n ] = pFormat;
398  }
399  // position-and-space mode LABEL_ALIGNMENT
400  // first line indent of general numbering in inch: -0,25 inch
401  const tools::Long cFirstLineIndent = o3tl::toTwips(-0.25, o3tl::Length::in);
402  // indent values of general numbering in inch:
403  const tools::Long cIndentAt[ MAXLEVEL ] = {
414  };
415  for( n = 0; n < MAXLEVEL; ++n )
416  {
417  pFormat = new SwNumFormat;
418  pFormat->SetIncludeUpperLevels( 1 );
419  pFormat->SetStart( 1 );
422  pFormat->SetListtabPos( cIndentAt[ n ] );
423  pFormat->SetFirstLineIndent( cFirstLineIndent );
424  pFormat->SetIndentAt( cIndentAt[ n ] );
425  pFormat->SetListFormat( "%" + OUString::number(n + 1) + "%.");
427  SwNumRule::saLabelAlignmentBaseFormats[ NUM_RULE ][ n ] = pFormat;
428  }
429 
430  // outline:
431  // position-and-space mode LABEL_WIDTH_AND_POSITION:
432  for( n = 0; n < MAXLEVEL; ++n )
433  {
434  pFormat = new SwNumFormat;
436  pFormat->SetIncludeUpperLevels( MAXLEVEL );
437  pFormat->SetStart( 1 );
440  SwNumRule::saBaseFormats[ OUTLINE_RULE ][ n ] = pFormat;
441  }
442  // position-and-space mode LABEL_ALIGNMENT:
443  for( n = 0; n < MAXLEVEL; ++n )
444  {
445  pFormat = new SwNumFormat;
447  pFormat->SetIncludeUpperLevels( MAXLEVEL );
448  pFormat->SetStart( 1 );
451  SwNumRule::saLabelAlignmentBaseFormats[ OUTLINE_RULE ][ n ] = pFormat;
452  }
453  }
454  OSL_ENSURE( !msName.isEmpty(), "NumRule without a name!" );
455 }
456 
457 SwNumRule::SwNumRule( const SwNumRule& rNumRule )
458  : mpNumRuleMap(nullptr),
459  msName( rNumRule.msName ),
460  meRuleType( rNumRule.meRuleType ),
461  mnPoolFormatId( rNumRule.GetPoolFormatId() ),
462  mnPoolHelpId( rNumRule.GetPoolHelpId() ),
463  mnPoolHlpFileId( rNumRule.GetPoolHlpFileId() ),
464  mbAutoRuleFlag( rNumRule.mbAutoRuleFlag ),
465  mbInvalidRuleFlag( true ),
466  mbContinusNum( rNumRule.mbContinusNum ),
467  mbAbsSpaces( rNumRule.mbAbsSpaces ),
468  mbHidden( rNumRule.mbHidden ),
469  mbCountPhantoms( true ),
470  mbUsedByRedline( false ),
471  meDefaultNumberFormatPositionAndSpaceMode( rNumRule.meDefaultNumberFormatPositionAndSpaceMode ),
472  msDefaultListId( rNumRule.msDefaultListId )
473 {
474  ++snRefCount;
475  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
476  if( rNumRule.maFormats[ n ] )
477  Set( n, *rNumRule.maFormats[ n ] );
478 }
479 
481 {
482  for (auto & i : maFormats)
483  i.reset();
484 
485  if (mpNumRuleMap)
486  {
487  mpNumRuleMap->erase(GetName());
488  }
489 
490  if( !--snRefCount ) // the last one closes the door (?)
491  {
492  // Numbering:
493  SwNumFormat** ppFormats = &SwNumRule::saBaseFormats[0][0];
494  int n;
495 
496  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
497  {
498  delete *ppFormats;
499  *ppFormats = nullptr;
500  }
501 
502  // Outline:
503  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
504  {
505  delete *ppFormats;
506  *ppFormats = nullptr;
507  }
508 
509  ppFormats = &SwNumRule::saLabelAlignmentBaseFormats[0][0];
510  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
511  {
512  delete *ppFormats;
513  *ppFormats = nullptr;
514  }
515  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
516  {
517  delete *ppFormats;
518  *ppFormats = nullptr;
519  }
520  }
521 
522  maTextNodeList.clear();
523  maParagraphStyleList.clear();
524 }
525 
527 {
528  for(auto& rpNumFormat : maFormats)
529  {
530  if( rpNumFormat )
531  {
532  SwCharFormat* pFormat = rpNumFormat->GetCharFormat();
533  if( pFormat && pFormat->GetDoc() != &rDoc )
534  {
535  // copy
536  SwNumFormat* pNew = new SwNumFormat( *rpNumFormat );
537  pNew->SetCharFormat( rDoc.CopyCharFormat( *pFormat ) );
538  rpNumFormat.reset(pNew);
539  }
540  }
541  }
542 }
543 
545 {
546  if( this != &rNumRule )
547  {
548  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
549  Set( n, rNumRule.maFormats[ n ].get() );
550 
551  meRuleType = rNumRule.meRuleType;
552  msName = rNumRule.msName;
553  mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
554  mbInvalidRuleFlag = true;
555  mbContinusNum = rNumRule.mbContinusNum;
556  mbAbsSpaces = rNumRule.mbAbsSpaces;
557  mbHidden = rNumRule.mbHidden;
558  mnPoolFormatId = rNumRule.GetPoolFormatId();
559  mnPoolHelpId = rNumRule.GetPoolHelpId();
560  mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
561  }
562  return *this;
563 }
564 
565 void SwNumRule::Reset( const OUString& rName )
566 {
567  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
568  Set( n, nullptr);
569 
571  msName = rName;
572  mbAutoRuleFlag = true;
573  mbInvalidRuleFlag = true;
574  mbContinusNum = false;
575  mbAbsSpaces = false;
576  mbHidden = false;
577  mnPoolFormatId = USHRT_MAX;
578  mnPoolHelpId = USHRT_MAX;
579  mnPoolHlpFileId = UCHAR_MAX;
580 }
581 
582 bool SwNumRule::operator==( const SwNumRule& rRule ) const
583 {
584  bool bRet = meRuleType == rRule.meRuleType &&
585  msName == rRule.msName &&
586  mbAutoRuleFlag == rRule.mbAutoRuleFlag &&
587  mbContinusNum == rRule.mbContinusNum &&
588  mbAbsSpaces == rRule.mbAbsSpaces &&
589  mnPoolFormatId == rRule.GetPoolFormatId() &&
590  mnPoolHelpId == rRule.GetPoolHelpId() &&
592  if( bRet )
593  {
594  for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
595  if( rRule.Get( n ) != Get( n ) )
596  {
597  bRet = false;
598  break;
599  }
600  }
601  return bRet;
602 }
603 
604 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat& rNumFormat )
605 {
606  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
607  if( i < MAXLEVEL )
608  {
609  if( !maFormats[ i ] || (rNumFormat != Get( i )) )
610  {
611  maFormats[ i ].reset(new SwNumFormat( rNumFormat ));
612  mbInvalidRuleFlag = true;
613  }
614  }
615 }
616 
617 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat* pNumFormat )
618 {
619  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
620  if( i >= MAXLEVEL )
621  return;
622  if( !maFormats[ i ] )
623  {
624  if( pNumFormat )
625  {
626  maFormats[ i ].reset(new SwNumFormat( *pNumFormat ));
627  mbInvalidRuleFlag = true;
628  }
629  }
630  else if( !pNumFormat )
631  {
632  maFormats[ i ].reset();
633  mbInvalidRuleFlag = true;
634  }
635  else if( *maFormats[i] != *pNumFormat )
636  {
637  *maFormats[ i ] = *pNumFormat;
638  mbInvalidRuleFlag = true;
639  }
640 }
641 
642 OUString SwNumRule::MakeNumString( const SwNodeNum& rNum, bool bInclStrings ) const
643 {
644  if (rNum.IsCounted())
645  return MakeNumString(rNum.GetNumberVector(), bInclStrings);
646 
647  return OUString();
648 }
649 
651  const bool bInclStrings,
652  const bool bOnlyArabic,
653  const unsigned int _nRestrictToThisLevel,
654  SwNumRule::Extremities* pExtremities,
655  LanguageType nLang ) const
656 {
657  OUStringBuffer aStr;
658 
659  SwNumberTree::tNumberVector::size_type nLevel = rNumVector.size() - 1;
660 
661  if ( pExtremities )
662  pExtremities->nPrefixChars = pExtremities->nSuffixChars = 0;
663 
664  if ( nLevel > _nRestrictToThisLevel )
665  {
666  nLevel = _nRestrictToThisLevel;
667  }
668 
669  assert(nLevel < MAXLEVEL);
670 
671  const SwNumFormat& rMyNFormat = Get( o3tl::narrowing<sal_uInt16>(nLevel) );
672 
673  if (rMyNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
674  {
675  if (!rMyNFormat.HasListFormat())
676  return OUString();
677 
678  // If numbering is disabled for this level we should emit just prefix/suffix
679  // Remove everything between first %1% and last %n% (including markers)
680  OUString sLevelFormat = rMyNFormat.GetListFormat(bInclStrings);
681  sal_Int32 nFirstPosition = sLevelFormat.indexOf("%");
682  sal_Int32 nLastPosition = sLevelFormat.lastIndexOf("%");
683  if (nFirstPosition >= 0 && nLastPosition >= nFirstPosition)
684  sLevelFormat = sLevelFormat.replaceAt(nFirstPosition, nLastPosition - nFirstPosition + 1, u"");
685  return sLevelFormat;
686  }
687 
688  css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang));
689 
690  if (rMyNFormat.HasListFormat())
691  {
692  OUString sLevelFormat = rMyNFormat.GetListFormat(bInclStrings);
693 
694  // In this case we are ignoring GetIncludeUpperLevels: we put all
695  // level numbers requested by level format
696  for (SwNumberTree::tNumberVector::size_type i=0; i <= nLevel; ++i)
697  {
698  OUString sReplacement;
699  const SwNumFormat& rNFormat = Get(i);
700  if (rNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
701  {
702  // Numbering disabled - replacement is empty
703  // And we should skip all level string content until next level marker:
704  // so %1%.%2%.%3% with second level as NONE will result 1.1, not 1..1
705  OUString sFind("%" + OUString::number(i + 1) + "%");
706  sal_Int32 nPositionToken = sLevelFormat.indexOf(sFind);
707  sal_Int32 nPositionNextToken = sLevelFormat.indexOf('%', nPositionToken + sFind.getLength());
708  if (nPositionToken > 0 && nPositionNextToken >= nPositionToken)
709  {
710  sLevelFormat = sLevelFormat.replaceAt(nPositionToken, nPositionNextToken - nPositionToken, u"");
711  }
712  }
713  else if (rNumVector[i])
714  {
715  if (bOnlyArabic)
716  sReplacement = OUString::number(rNumVector[i]);
717  else
718  sReplacement = Get(i).GetNumStr(rNumVector[i], aLocale);
719  }
720  else
721  sReplacement = "0"; // all 0 level are a 0
722 
723  OUString sFind("%" + OUString::number(i + 1) + "%");
724  sal_Int32 nPosition = sLevelFormat.indexOf(sFind);
725  if (nPosition >= 0)
726  sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
727  }
728 
729  aStr = sLevelFormat;
730  }
731  else
732  {
733  // Fallback case: level format is not defined
734  // So use old way with levels joining by dot "."
735  SwNumberTree::tNumberVector::size_type i = nLevel;
736 
737  if (!IsContinusNum() &&
738  // - do not include upper levels, if level isn't numbered.
739  rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
740  rMyNFormat.GetIncludeUpperLevels()) // Just the own level?
741  {
742  sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels();
743  if (1 < n)
744  {
745  if (i + 1 >= n)
746  i -= n - 1;
747  else
748  i = 0;
749  }
750  }
751 
752  for (; i <= nLevel; ++i)
753  {
754  const SwNumFormat& rNFormat = Get(i);
755  if (SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType())
756  {
757  // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ??
758  // if( i != rNum.nMyLevel )
759  // aStr += ".";
760  continue;
761  }
762 
763  if (rNumVector[i])
764  {
765  if (bOnlyArabic)
766  aStr.append(rNumVector[i]);
767  else
768  aStr.append(rNFormat.GetNumStr(rNumVector[i], aLocale));
769  }
770  else
771  aStr.append("0"); // all 0 level are a 0
772  if (i != nLevel && !aStr.isEmpty())
773  aStr.append(".");
774  }
775 
776  // The type doesn't have any number, so don't append
777  // the post-/prefix string
778  if (bInclStrings && !bOnlyArabic &&
779  SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() &&
780  SVX_NUM_BITMAP != rMyNFormat.GetNumberingType())
781  {
782  const OUString& sPrefix = rMyNFormat.GetPrefix();
783  const OUString& sSuffix = rMyNFormat.GetSuffix();
784 
785  aStr.insert(0, sPrefix);
786  aStr.append(sSuffix);
787  if (pExtremities)
788  {
789  pExtremities->nPrefixChars = sPrefix.getLength();
790  pExtremities->nSuffixChars = sSuffix.getLength();
791  }
792  }
793  }
794 
795  return aStr.makeStringAndClear();
796 }
797 
798 OUString SwNumRule::MakeRefNumString( const SwNodeNum& rNodeNum,
799  const bool bInclSuperiorNumLabels,
800  const int nRestrictInclToThisLevel ) const
801 {
802  OUString aRefNumStr;
803 
804  if ( rNodeNum.GetLevelInListTree() >= 0 )
805  {
806  bool bOldHadPrefix = true;
807 
808  const SwNodeNum* pWorkingNodeNum( &rNodeNum );
809  do
810  {
811  bool bMakeNumStringForPhantom( false );
812  if ( pWorkingNodeNum->IsPhantom() )
813  {
814  int nListLevel = pWorkingNodeNum->GetLevelInListTree();
815 
816  if (nListLevel < 0)
817  nListLevel = 0;
818 
819  if (nListLevel >= MAXLEVEL)
820  nListLevel = MAXLEVEL - 1;
821 
822  SwNumFormat aFormat( Get( o3tl::narrowing<sal_uInt16>(nListLevel) ) );
823  bMakeNumStringForPhantom = aFormat.IsEnumeration() &&
825 
826  }
827  if ( bMakeNumStringForPhantom ||
828  ( !pWorkingNodeNum->IsPhantom() &&
829  pWorkingNodeNum->GetTextNode() &&
830  pWorkingNodeNum->GetTextNode()->HasNumber() ) )
831  {
832  Extremities aExtremities;
833  OUString aPrevStr = MakeNumString( pWorkingNodeNum->GetNumberVector(),
834  true, false, MAXLEVEL,
835  &aExtremities);
836  sal_Int32 nStrip = 0;
837  while ( nStrip < aExtremities.nPrefixChars )
838  {
839  const sal_Unicode c = aPrevStr[nStrip];
840  if ( c!='\t' && c!=' ')
841  break;
842  ++nStrip;
843  }
844 
845  if (nStrip)
846  {
847  aPrevStr = aPrevStr.copy( nStrip );
848  aExtremities.nPrefixChars -= nStrip;
849  }
850 
851  if (bOldHadPrefix &&
852  aExtremities.nSuffixChars &&
853  !aExtremities.nPrefixChars
854  )
855  {
856  aPrevStr = aPrevStr.copy(0,
857  aPrevStr.getLength() - aExtremities.nSuffixChars);
858  }
859 
860  bOldHadPrefix = ( aExtremities.nPrefixChars > 0);
861 
862  aRefNumStr = aPrevStr + aRefNumStr;
863  }
864 
865  if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
866  {
867  sal_uInt8 n = Get( o3tl::narrowing<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
868  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
869  // skip parents, whose list label is already contained in the actual list label.
870  while ( pWorkingNodeNum && n > 1 )
871  {
872  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
873  --n;
874  }
875  }
876  else
877  {
878  break;
879  }
880  } while ( pWorkingNodeNum &&
881  pWorkingNodeNum->GetLevelInListTree() >= 0 &&
882  pWorkingNodeNum->GetLevelInListTree() >= nRestrictInclToThisLevel );
883  }
884 
885  return aRefNumStr;
886 }
887 
889 {
890  OUString aParagraphStyleListString;
891  for (const auto& rParagraphStyle : maParagraphStyleList)
892  {
893  if (!aParagraphStyleListString.isEmpty())
894  aParagraphStyleListString += ", ";
895  aParagraphStyleListString += rParagraphStyle->GetName();
896  }
897  return aParagraphStyleListString;
898 }
899 
906 {
907  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
908  {
909  Set( n, rNumRule.maFormats[ n ].get() );
910  if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() &&
911  !rDoc.GetCharFormats()->ContainsFormat(maFormats[n]->GetCharFormat()))
912  {
913  // If we copy across different Documents, then copy the
914  // corresponding CharFormat into the new Document.
915  maFormats[n]->SetCharFormat( rDoc.CopyCharFormat( *maFormats[n]->
916  GetCharFormat() ) );
917  }
918  }
919  meRuleType = rNumRule.meRuleType;
920  msName = rNumRule.msName;
921  mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
922  mnPoolFormatId = rNumRule.GetPoolFormatId();
923  mnPoolHelpId = rNumRule.GetPoolHelpId();
924  mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
925  mbInvalidRuleFlag = true;
926  return *this;
927 }
928 
929 void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
930 {
931  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
932  {
933  const SvxNumberFormat* pSvxFormat = rNumRule.Get(n);
934  maFormats[n].reset( pSvxFormat ? new SwNumFormat(*pSvxFormat, pDoc) : nullptr );
935  }
936 
937  mbInvalidRuleFlag = true;
939 }
940 
942 {
943  SvxNumRule aRule(SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::CHAR_STYLE |
944  SvxNumRuleFlags::ENABLE_LINKED_BMP | SvxNumRuleFlags::ENABLE_EMBEDDED_BMP,
946  meRuleType == NUM_RULE ? SvxNumRuleType::NUMBERING : SvxNumRuleType::OUTLINE_NUMBERING );
947  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
948  {
949  const SwNumFormat & rNumFormat = Get(n);
950  if(rNumFormat.GetCharFormat())
951  {
952  SwNumFormat aNewFormat = rNumFormat;
953  aNewFormat.SetCharFormatName(rNumFormat.GetCharFormat()->GetName());
954  aRule.SetLevel(n, aNewFormat, maFormats[n] != nullptr);
955  }
956  else
957  aRule.SetLevel(n, rNumFormat, maFormats[n] != nullptr);
958  }
959  return aRule;
960 }
961 
963 {
964  if (bFlag)
965  {
967  for ( const SwTextNode* pTextNode : maTextNodeList )
968  {
969  // #i111681# - applying patch from cmc
970  SwList* pList = pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() );
971  OSL_ENSURE( pList, "<SwNumRule::SetInvalidRule(..)> - list at which the text node is registered at does not exist. This is a serious issue.");
972  if ( pList )
973  {
974  aLists.insert( pList );
975  }
976  }
977  for ( auto aList : aLists )
978  aList->InvalidateListTree();
979  }
980 
981  mbInvalidRuleFlag = bFlag;
982 }
983 
985 void SwNumRule::ChangeIndent( const sal_Int32 nDiff )
986 {
987  for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
988  {
989  SwNumFormat aTmpNumFormat( Get(i) );
990 
991  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
992  aTmpNumFormat.GetPositionAndSpaceMode() );
993  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
994  {
995  auto nNewIndent = nDiff +
996  aTmpNumFormat.GetAbsLSpace();
997  if ( nNewIndent < 0 )
998  {
999  nNewIndent = 0;
1000  }
1001  aTmpNumFormat.SetAbsLSpace( nNewIndent );
1002  }
1003  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1004  {
1005  // adjust also the list tab position, if a list tab stop is applied
1006  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
1007  {
1008  const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() + nDiff;
1009  aTmpNumFormat.SetListtabPos( nNewListTab );
1010  }
1011 
1012  const tools::Long nNewIndent = nDiff +
1013  aTmpNumFormat.GetIndentAt();
1014  aTmpNumFormat.SetIndentAt( nNewIndent );
1015  }
1016 
1017  Set( i, aTmpNumFormat );
1018  }
1019 
1020  SetInvalidRule( true );
1021 }
1022 
1024 void SwNumRule::SetIndent( const short nNewIndent,
1025  const sal_uInt16 nListLevel )
1026 {
1027  SwNumFormat aTmpNumFormat( Get(nListLevel) );
1028 
1029  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1030  aTmpNumFormat.GetPositionAndSpaceMode() );
1031  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1032  {
1033  aTmpNumFormat.SetAbsLSpace( nNewIndent );
1034  }
1035  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1036  {
1037  // adjust also the list tab position, if a list tab stop is applied
1038  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
1039  {
1040  const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() +
1041  ( nNewIndent - aTmpNumFormat.GetIndentAt() );
1042  aTmpNumFormat.SetListtabPos( nNewListTab );
1043  }
1044 
1045  aTmpNumFormat.SetIndentAt( nNewIndent );
1046  }
1047 
1048  SetInvalidRule( true );
1049 }
1050 
1054 {
1055  SwNumFormat aTmpNumFormat( Get(0) );
1056 
1057  sal_Int32 nDiff( 0 );
1058  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1059  aTmpNumFormat.GetPositionAndSpaceMode() );
1060  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1061  {
1062  nDiff = nNewIndent
1063  - aTmpNumFormat.GetFirstLineOffset()
1064  - aTmpNumFormat.GetAbsLSpace();
1065  }
1066  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1067  {
1068  nDiff = nNewIndent - aTmpNumFormat.GetIndentAt();
1069  }
1070  if ( nDiff != 0 )
1071  {
1072  ChangeIndent( nDiff );
1073  }
1074 }
1075 
1076 void SwNumRule::Validate(const SwDoc& rDoc)
1077 {
1079  for ( const SwTextNode* pTextNode : maTextNodeList )
1080  {
1081  aLists.insert( pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() ) );
1082  }
1083  for ( auto aList : aLists )
1084  aList->ValidateListTree(rDoc);
1085 
1086  SetInvalidRule(false);
1087 }
1088 
1089 void SwNumRule::SetCountPhantoms(bool bCountPhantoms)
1090 {
1091  mbCountPhantoms = bCountPhantoms;
1092 }
1093 
1094 SwNumRule::tParagraphStyleList::size_type SwNumRule::GetParagraphStyleListSize() const
1095 {
1096  return maParagraphStyleList.size();
1097 }
1098 
1100 {
1101  tParagraphStyleList::iterator aIter =
1102  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1103 
1104  if ( aIter == maParagraphStyleList.end() )
1105  {
1106  maParagraphStyleList.push_back( &rTextFormatColl );
1107  }
1108 }
1109 
1111 {
1112  tParagraphStyleList::iterator aIter =
1113  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1114 
1115  if ( aIter != maParagraphStyleList.end() )
1116  {
1117  maParagraphStyleList.erase( aIter );
1118  }
1119 }
1120 
1122 {
1123  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRule"));
1124  (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("msName"), BAD_CAST(msName.toUtf8().getStr()));
1125  (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mnPoolFormatId"), BAD_CAST(OString::number(mnPoolFormatId).getStr()));
1126  (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mbAutoRuleFlag"), BAD_CAST(OString::boolean(mbAutoRuleFlag).getStr()));
1127 
1128  for (const auto& pFormat : maFormats)
1129  {
1130  if (!pFormat)
1131  {
1132  continue;
1133  }
1134 
1135  pFormat->dumpAsXml(pWriter);
1136  }
1137 
1138  (void)xmlTextWriterEndElement(pWriter);
1139 }
1140 
1142 {
1143  if (mpGrabBagItem)
1144  mpGrabBagItem->QueryValue(rVal);
1145  else
1146  rVal <<= uno::Sequence<beans::PropertyValue>();
1147 }
1148 
1150 {
1151  if (!mpGrabBagItem)
1152  mpGrabBagItem = std::make_shared<SfxGrabBagItem>();
1153 
1154  mpGrabBagItem->PutValue(rVal, 0);
1155 }
1156 
1157 namespace numfunc
1158 {
1159  namespace {
1160 
1162  class SwDefBulletConfig : private utl::ConfigItem
1163  {
1164  public:
1165  static SwDefBulletConfig& getInstance();
1166 
1167  const OUString& GetFontname() const
1168  {
1169  return msFontname;
1170  }
1171 
1172  bool IsFontnameUserDefined() const
1173  {
1174  return mbUserDefinedFontname;
1175  }
1176 
1177  const vcl::Font& GetFont() const
1178  {
1179  return *mpFont;
1180  }
1181 
1182  sal_Unicode GetChar( sal_uInt8 p_nListLevel ) const
1183  {
1184  if (p_nListLevel >= MAXLEVEL)
1185  {
1186  p_nListLevel = MAXLEVEL - 1;
1187  }
1188 
1189  return mnLevelChars[p_nListLevel];
1190  }
1191 
1192  SwDefBulletConfig();
1193 
1194  private:
1196  void SetToDefault();
1197 
1199  static uno::Sequence<OUString> GetPropNames();
1200 
1203  void LoadConfig();
1204 
1206  void InitFont();
1207 
1209  virtual void Notify( const uno::Sequence<OUString>& aPropertyNames ) override;
1210  virtual void ImplCommit() override;
1211 
1212  // default bullet list configuration data
1213  OUString msFontname;
1218 
1219  // default bullet list font instance
1220  std::optional<vcl::Font> mpFont;
1221  };
1222 
1223  }
1224 
1225  SwDefBulletConfig& SwDefBulletConfig::getInstance()
1226  {
1227  static SwDefBulletConfig theSwDefBulletConfig;
1228  return theSwDefBulletConfig;
1229  }
1230 
1231  SwDefBulletConfig::SwDefBulletConfig()
1232  : ConfigItem( "Office.Writer/Numbering/DefaultBulletList" ),
1233  // default bullet font is now OpenSymbol
1234  msFontname( OUString("OpenSymbol") ),
1235  mbUserDefinedFontname( false ),
1238  {
1239  SetToDefault();
1240  LoadConfig();
1241  InitFont();
1242 
1243  // enable notification for changes on default bullet configuration change
1244  EnableNotification( GetPropNames() );
1245  }
1246 
1247  void SwDefBulletConfig::SetToDefault()
1248  {
1249  msFontname = "OpenSymbol";
1250  mbUserDefinedFontname = false;
1253 
1254  mnLevelChars[0] = 0x2022;
1255  mnLevelChars[1] = 0x25e6;
1256  mnLevelChars[2] = 0x25aa;
1257  mnLevelChars[3] = 0x2022;
1258  mnLevelChars[4] = 0x25e6;
1259  mnLevelChars[5] = 0x25aa;
1260  mnLevelChars[6] = 0x2022;
1261  mnLevelChars[7] = 0x25e6;
1262  mnLevelChars[8] = 0x25aa;
1263  mnLevelChars[9] = 0x2022;
1264  }
1265 
1266  uno::Sequence<OUString> SwDefBulletConfig::GetPropNames()
1267  {
1268  uno::Sequence<OUString> aPropNames(13);
1269  OUString* pNames = aPropNames.getArray();
1270  pNames[0] = "BulletFont/FontFamilyname";
1271  pNames[1] = "BulletFont/FontWeight";
1272  pNames[2] = "BulletFont/FontItalic";
1273  pNames[3] = "BulletCharLvl1";
1274  pNames[4] = "BulletCharLvl2";
1275  pNames[5] = "BulletCharLvl3";
1276  pNames[6] = "BulletCharLvl4";
1277  pNames[7] = "BulletCharLvl5";
1278  pNames[8] = "BulletCharLvl6";
1279  pNames[9] = "BulletCharLvl7";
1280  pNames[10] = "BulletCharLvl8";
1281  pNames[11] = "BulletCharLvl9";
1282  pNames[12] = "BulletCharLvl10";
1283 
1284  return aPropNames;
1285  }
1286 
1287  void SwDefBulletConfig::LoadConfig()
1288  {
1289  uno::Sequence<OUString> aPropNames = GetPropNames();
1290  uno::Sequence<uno::Any> aValues = GetProperties( aPropNames );
1291  const uno::Any* pValues = aValues.getConstArray();
1292  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1293  "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed");
1294  if ( aValues.getLength() != aPropNames.getLength() )
1295  return;
1296 
1297  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1298  {
1299  if ( pValues[nProp].hasValue() )
1300  {
1301  switch ( nProp )
1302  {
1303  case 0:
1304  {
1305  OUString aStr;
1306  pValues[nProp] >>= aStr;
1307  msFontname = aStr;
1308  mbUserDefinedFontname = true;
1309  }
1310  break;
1311  case 1:
1312  case 2:
1313  {
1314  sal_Int16 nTmp = 0;
1315  pValues[nProp] >>= nTmp;
1316  if ( nProp == 1 )
1317  meFontWeight = static_cast<FontWeight>(nTmp);
1318  else if ( nProp == 2 )
1319  meFontItalic = static_cast<FontItalic>(nTmp);
1320  }
1321  break;
1322  case 3:
1323  case 4:
1324  case 5:
1325  case 6:
1326  case 7:
1327  case 8:
1328  case 9:
1329  case 10:
1330  case 11:
1331  case 12:
1332  {
1333  sal_Unicode cChar = sal_Unicode();
1334  pValues[nProp] >>= cChar;
1335  mnLevelChars[nProp-3] = cChar;
1336  }
1337  break;
1338  }
1339  }
1340  }
1341 
1342  }
1343 
1344  void SwDefBulletConfig::InitFont()
1345  {
1346  mpFont.emplace( msFontname, OUString(), Size( 0, 14 ) );
1347  mpFont->SetWeight( meFontWeight );
1348  mpFont->SetItalic( meFontItalic );
1349  mpFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
1350  }
1351 
1352  void SwDefBulletConfig::Notify( const uno::Sequence<OUString>& )
1353  {
1354  SetToDefault();
1355  LoadConfig();
1356  InitFont();
1357  }
1358 
1359  void SwDefBulletConfig::ImplCommit()
1360  {
1361  }
1362 
1363  OUString const & GetDefBulletFontname()
1364  {
1365  return SwDefBulletConfig::getInstance().GetFontname();
1366  }
1367 
1369  {
1370  return SwDefBulletConfig::getInstance().IsFontnameUserDefined();
1371  }
1372 
1374  {
1375  return SwDefBulletConfig::getInstance().GetFont();
1376  }
1377 
1379  {
1380  return SwDefBulletConfig::getInstance().GetChar( nLevel );
1381  }
1382 
1383  namespace {
1384 
1390  class SwNumberingUIBehaviorConfig : private utl::ConfigItem
1391  {
1392  public:
1393  static SwNumberingUIBehaviorConfig& getInstance();
1394 
1396  {
1398  }
1399 
1400  SwNumberingUIBehaviorConfig();
1401 
1402  private:
1403 
1405  void SetToDefault();
1406 
1408  static css::uno::Sequence<OUString> GetPropNames();
1409 
1411  void LoadConfig();
1412 
1414  virtual void Notify( const css::uno::Sequence<OUString>& aPropertyNames ) override;
1415  virtual void ImplCommit() override;
1416 
1417  // configuration data
1419  };
1420 
1421  }
1422 
1423  SwNumberingUIBehaviorConfig& SwNumberingUIBehaviorConfig::getInstance()
1424  {
1425  static SwNumberingUIBehaviorConfig theSwNumberingUIBehaviorConfig;
1426  return theSwNumberingUIBehaviorConfig;
1427  }
1428 
1429  SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1430  : ConfigItem( "Office.Writer/Numbering/UserInterfaceBehavior" ),
1432  {
1433  SetToDefault();
1434  LoadConfig();
1435 
1436  // enable notification for changes on configuration change
1437  EnableNotification( GetPropNames() );
1438  }
1439 
1440  void SwNumberingUIBehaviorConfig::SetToDefault()
1441  {
1443  }
1444 
1445  css::uno::Sequence<OUString> SwNumberingUIBehaviorConfig::GetPropNames()
1446  {
1447  css::uno::Sequence<OUString> aPropNames { "ChangeIndentOnTabAtFirstPosOfFirstListItem" };
1448 
1449  return aPropNames;
1450  }
1451 
1452  void SwNumberingUIBehaviorConfig::ImplCommit() {}
1453 
1454  void SwNumberingUIBehaviorConfig::LoadConfig()
1455  {
1456  css::uno::Sequence<OUString> aPropNames = GetPropNames();
1457  css::uno::Sequence<css::uno::Any> aValues = GetProperties( aPropNames );
1458  const css::uno::Any* pValues = aValues.getConstArray();
1459  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1460  "<SwNumberingUIBehaviorConfig::LoadConfig()> - GetProperties failed");
1461  if ( aValues.getLength() != aPropNames.getLength() )
1462  return;
1463 
1464  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1465  {
1466  if ( pValues[nProp].hasValue() )
1467  {
1468  switch ( nProp )
1469  {
1470  case 0:
1471  {
1473  }
1474  break;
1475  default:
1476  {
1477  OSL_FAIL( "<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property");
1478  }
1479  }
1480  }
1481  }
1482  }
1483 
1484  void SwNumberingUIBehaviorConfig::Notify( const css::uno::Sequence<OUString>& )
1485  {
1486  SetToDefault();
1487  LoadConfig();
1488  }
1489 
1491  {
1492  return SwNumberingUIBehaviorConfig::getInstance().ChangeIndentOnTabAtFirstPosOfFirstListItem();
1493  }
1494 
1495  bool NumDownChangesIndent(const SwWrtShell& rShell)
1496  {
1497  SwPaM* pCursor = rShell.GetCursor();
1498  if (!pCursor)
1499  {
1500  return true;
1501  }
1502 
1503  SwTextNode* pTextNode = pCursor->GetNode().GetTextNode();
1504  if (!pTextNode)
1505  {
1506  return true;
1507  }
1508 
1509  const SwNumRule* pNumRule = pTextNode->GetNumRule();
1510  if (!pNumRule)
1511  {
1512  return true;
1513  }
1514 
1515  int nOldLevel = pTextNode->GetActualListLevel();
1516  int nNewLevel = nOldLevel + 1;
1517  if (nNewLevel >= MAXLEVEL)
1518  {
1519  return true;
1520  }
1521 
1522  const SwNumFormat& rOldFormat = pNumRule->Get(nOldLevel);
1523  if (rOldFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1524  {
1525  return true;
1526  }
1527 
1528  const SwNumFormat& rNewFormat = pNumRule->Get(nNewLevel);
1529  if (rNewFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1530  {
1531  return true;
1532  }
1533 
1534  // This is the case when the numbering levels don't differ, so changing between them is not
1535  // a better alternative to inserting a tab character.
1536  return rOldFormat.GetIndentAt() != rNewFormat.GetIndentAt();
1537  }
1538 
1540  {
1543 
1545  switch (GetODFSaneDefaultVersion())
1546  {
1549  {
1550  ePosAndSpaceMode = SvxNumberFormat::LABEL_WIDTH_AND_POSITION;
1551  }
1552  break;
1553  default: // >= ODFSVER_012
1554  {
1555  ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1556  }
1557  }
1558 
1559  return ePosAndSpaceMode;
1560  }
1561 }
1562 
1564 {
1565  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRuleTable"));
1566  for (SwNumRule* pNumRule : *this)
1567  pNumRule->dumpAsXml(pWriter);
1568  (void)xmlTextWriterEndElement(pWriter);
1569 }
1570 
1571 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual SwCharFormat * GetCharFormatFromPool(sal_uInt16 nId)=0
SvxNumberFormat & operator=(const SvxNumberFormat &)
OUString GetNumStr(sal_Int32 nNo) const
SvxNumType GetNumberingType() const
void AddParagraphStyle(SwTextFormatColl &rTextFormatColl)
Definition: number.cxx:1099
sal_uInt16 mnPoolHelpId
HelpId for this Pool-style.
Definition: numrule.hxx:129
void SetLabelFollowedBy(const LabelFollowedBy eLabelFollowedBy)
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
bool mbHidden
Is the numbering rule to be hidden in the UI?
Definition: numrule.hxx:135
void Add(SwClient *pDepend)
Definition: calbck.cxx:173
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: number.cxx:288
SwNumFormat & operator=(const SwNumFormat &)
Definition: number.cxx:264
static sal_uInt16 GetBullIndent(sal_uInt8 nLvl)
Definition: number.cxx:174
constexpr short lOutlineMinTextDistance
Definition: swtypes.hxx:103
static void lcl_SetRuleChgd(SwTextNode &rNd, sal_uInt8 nLevel)
Definition: number.cxx:180
virtual void trackChangeOfListStyleName(const OUString &rListStyleName, const OUString &rNewListStyleName)=0
OUString MakeRefNumString(const SwNodeNum &rNodeNum, const bool bInclSuperiorNumLabels, const int nRestrictInclToThisLevel) const
Definition: number.cxx:798
constexpr auto toTwips(N number, Length from)
constexpr short lNumberFirstLineOffset
Definition: swtypes.hxx:102
OUString MakeNumString(const SwNodeNum &, bool bInclStrings=true) const
Definition: number.cxx:642
void Notify(SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld, const SwRect *pOldRect=nullptr)
Notify the background based on the difference between old and new rectangle.
Definition: frmtool.cxx:3242
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
Definition: docfmt.cxx:856
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(162)
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:96
void SetPositionAndSpaceMode(SvxNumPositionAndSpaceMode ePositionAndSpaceMode)
const SvxBrushItem * GetBrush() const
OUString msFontname
Definition: number.cxx:1213
SVX_NUM_NUMBER_NONE
long Long
void AddTextNode(SwTextNode &rTextNode)
Definition: number.cxx:140
SwNumberTreeNode * GetParent() const
Returns the parent of this node.
virtual void Notify(const css::uno::Sequence< OUString > &aPropertyNames)=0
OUString MakeParagraphStyleListString() const
Definition: number.cxx:888
sal_uInt16 GetPoolFormatId() const
Query and set PoolFormat IDs.
Definition: numrule.hxx:251
const OUString & GetDefaultListId() const
Definition: numrule.hxx:195
Definition: list.hxx:35
sal_Int64 n
void GetGrabBagItem(css::uno::Any &rVal) const
Definition: number.cxx:1141
FontWeight meFontWeight
Definition: number.cxx:1215
Definition: doc.hxx:188
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
void RemoveParagraphStyle(SwTextFormatColl &rTextFormatColl)
Definition: number.cxx:1110
OUString msName
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:93
sal_uInt8 mnPoolHlpFileId
FilePos at Doc on style helps.
Definition: numrule.hxx:130
sal_Int16 nId
sal_uInt8 GetIncludeUpperLevels() const
SwNumRuleType
Definition: numrule.hxx:92
tools::Long GetListtabPos() const
virtual bool IsCounted() const override
Return if this node is counted.
Definition: SwNodeNum.cxx:170
const OUString & GetName() const
Definition: numrule.hxx:225
sal_uInt16 GetPoolHelpId() const
Query and set Help-IDs for document styles.
Definition: numrule.hxx:255
SwNumberTree::tNumberVector GetNumberVector() const
Returns level numbers of this node.
bool operator==(const SwNumRule &) const
Definition: number.cxx:582
bool ContainsFormat(const SwCharFormat *pFormat) const
fast check if given format is contained here pFormat must not have been deleted
Definition: chrfmt.cxx:109
void Validate(const SwDoc &rDoc)
Definition: number.cxx:1076
void SetIncludeUpperLevels(sal_uInt8 nSet)
bool HasNumber(SwRootFrame const *pLayout=nullptr) const
Returns if this text node has a number.
Definition: ndtxt.cxx:3066
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: number.cxx:1563
bool mbInvalidRuleFlag
Definition: numrule.hxx:132
SwTextNode * GetTextNode() const
Definition: SwNodeNum.hxx:40
bool operator==(const SwNumFormat &) const
Definition: number.cxx:273
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4081
SfxHintId GetId() const
int GetLevelInListTree() const
Return level of this node.
void SetIndentAt(const tools::Long nIndentAt)
bool HasListFormat() const
static LanguageType nLang
Definition: srtdlg.cxx:51
static const sal_uInt16 saDefNumIndents[MAXLEVEL]
Definition: numrule.hxx:110
Used by the UI to modify the document model.
Definition: wrtsh.hxx:93
void StartListeningToSameModifyAs(const SwClient &)
Definition: calbck.cxx:129
sal_uInt16 sal_Unicode
void SetGrabBagItem(const css::uno::Any &rVal)
Definition: number.cxx:1149
bool operator==(const SvxNumberFormat &) const
OUString sSuffix
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:426
sal_Unicode GetBulletChar(sal_uInt8 nLevel)
retrieve unicode of character used for the default bullet list for the given list level ...
Definition: number.cxx:1378
const OUString & GetName() const
Definition: format.hxx:115
static bool IsFuzzing()
void SetCharFormatName(const OUString &rSet)
SVX_NUM_ARABIC
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
virtual OUString GetName() const override
SvxNumberFormat::SvxNumPositionAndSpaceMode meDefaultNumberFormatPositionAndSpaceMode
it needs to export as part of tracked numbering change
Definition: numrule.hxx:139
bool mbAutoRuleFlag
Definition: numrule.hxx:131
const OUString & GetPrefix() const
void SetNumRuleMap(std::unordered_map< OUString, SwNumRule * > *pNumRuleMap)
Register this rule in a "name->numrule" map.
Definition: number.cxx:162
const OUString & GetSuffix() const
FontItalic meFontItalic
Definition: number.cxx:1216
sal_Unicode mnLevelChars[MAXLEVEL]
Definition: number.cxx:1217
SvxNumRule MakeSvxNumRule() const
Definition: number.cxx:941
void EndListeningAll()
Definition: calbck.cxx:137
std::optional< sw::ModifyChangedHint > CheckRegistration(const SfxPoolItem *pOldValue)
Definition: calbck.cxx:78
bool IsContinusNum() const
Definition: numrule.hxx:236
SVX_NUM_BITMAP
exports com.sun.star. text
bool mbChangeIndentOnTabAtFirstPosOfFirstListItem
Definition: number.cxx:1418
SvtSaveOptions::ODFSaneDefaultVersion GetODFSaneDefaultVersion()
SVX_NUM_CHAR_SPECIAL
WEIGHT_DONTKNOW
SwCharFormat * GetCharFormat() const
Definition: numrule.hxx:74
SwNumRule(const OUString &rNm, const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode, SwNumRuleType=NUM_RULE)
add parameter
Definition: number.cxx:363
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
const SwFormatVertOrient * GetGraphicOrientation() const
Definition: number.cxx:351
OUString GetListFormat(bool bIncludePrefixSuffix=true) const
std::unique_ptr< SwFormatVertOrient > m_pVertOrient
Definition: numrule.hxx:52
constexpr sal_uInt16 lNumberIndent
Definition: swtypes.hxx:101
void Reset(const OUString &rName)
Definition: number.cxx:565
void CheckCharFormats(SwDoc &rDoc)
Tests whether the CharFormats are from the given doc and copies them if appropriate.
Definition: number.cxx:526
int i
LabelFollowedBy GetLabelFollowedBy() const
sal_Int32 GetAbsLSpace() const
std::vector< SwNumRule * >::size_type size_type
Definition: docary.hxx:67
virtual bool IsModified() const =0
Changes of document?
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
Definition: number.cxx:1373
bool IsPhantom() const
Return if this node is a phantom.
bool mbAbsSpaces
Levels represent absolute indents.
Definition: numrule.hxx:134
bool IsEnumeration() const
Definition: number.cxx:236
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(163)
void RemoveTextNode(SwTextNode &rTextNode)
Definition: number.cxx:151
float u
size_t size() const
Definition: docary.hxx:88
virtual ~SwNumFormat() override
Definition: number.cxx:231
SwNumRuleType meRuleType
Definition: numrule.hxx:127
static OUString GetOutlineRuleName()
Definition: number.cxx:81
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2795
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
const PropertyStruct aPropNames[]
sal_Unicode m_cGrfBulletCP
Definition: numrule.hxx:54
bool IsItemize() const
Definition: number.cxx:244
sal_uInt8 GetPoolHlpFileId() const
Definition: numrule.hxx:257
void GetTextNodeList(SwNumRule::tTextNodeList &rTextNodeList) const
Definition: number.cxx:130
static sal_uInt16 GetNumIndent(sal_uInt8 nLvl)
Definition: number.cxx:168
void SetCountPhantoms(bool bCountPhantoms)
Definition: number.cxx:1089
std::unordered_map< OUString, SwNumRule * > * mpNumRuleMap
unordered_map containing "name->rule" relation
Definition: numrule.hxx:124
OUString sPrefix
ITALIC_NONE
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:123
void SetIndent(const short nNewIndent, const sal_uInt16 nListLevel)
set indent of certain list level to given value
Definition: number.cxx:1024
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
void SetCharTextDistance(short nSet)
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
void dumpAsXml(xmlTextWriterPtr w) const
Definition: number.cxx:1121
Represents the style of a text portion.
Definition: charfmt.hxx:26
SwNumRule::tParagraphStyleList::size_type GetParagraphStyleListSize() const
Definition: number.cxx:1094
Provides access to the lists of a document.
void ChangeIndent(const sal_Int32 nDiff)
change indent of all list levels by given difference
Definition: number.cxx:985
void SetBulletChar(sal_UCS4 cSet)
std::vector< tSwNumTreeNumber > tNumberVector
bool mbContinusNum
Continuous numbering without levels.
Definition: numrule.hxx:133
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:86
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:771
sal_uInt16 nPrefixChars
Definition: numrule.hxx:102
std::unique_ptr< SwNumFormat > maFormats[MAXLEVEL]
Definition: numrule.hxx:115
const PropertyValue * pValues
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
bool IsContinuousNumbering() const
FontWeight
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:617
SwNumRule::tTextNodeList::size_type GetTextNodeListSize() const
Definition: number.cxx:135
static SwNumFormat * saBaseFormats[RULE_END][MAXLEVEL]
Definition: numrule.hxx:109
void SetCharFormat(SwCharFormat *)
Definition: number.cxx:280
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:196
const Size & GetGraphicSize() const
void SetInvalidRule(bool bFlag)
Definition: number.cxx:962
const SwCharFormats * GetCharFormats() const
Definition: doc.hxx:740
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1539
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
Definition: number.cxx:1368
unsigned char sal_uInt8
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
Definition: number.cxx:1363
static sal_uInt16 snRefCount
Definition: numrule.hxx:113
SwCharFormat * CopyCharFormat(const SwCharFormat &)
copy the char format
Definition: docfmt.cxx:1169
void SetFirstLineOffset(sal_Int32 nSet)
sal_uInt16 nSuffixChars
Definition: numrule.hxx:103
tTextNodeList maTextNodeList
container for associated text nodes
Definition: numrule.hxx:118
const SwNumRuleTable & GetNumRuleTable() const
Definition: doc.hxx:1066
void SetSvxRule(const SvxNumRule &, SwDoc *pDoc)
Definition: number.cxx:929
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:165
~SwNumRule()
Definition: number.cxx:480
SwNumRule & operator=(const SwNumRule &)
Definition: number.cxx:544
static SwNumFormat * saLabelAlignmentBaseFormats[RULE_END][MAXLEVEL]
default list level properties for position-and-space mode LABEL_ALIGNMENT
Definition: numrule.hxx:112
sal_Int32 GetFirstLineOffset() const
std::vector< SwTextNode * > tTextNodeList
Definition: numrule.hxx:97
void SetStart(sal_uInt16 nSet)
virtual void SetGraphicBrush(const SvxBrushItem *pBrushItem, const Size *pSize=nullptr, const sal_Int16 *pOrient=nullptr)
virtual void SetGraphicBrush(const SvxBrushItem *pBrushItem, const Size *pSize=nullptr, const sal_Int16 *pOrient=nullptr) override
Definition: number.cxx:318
std::shared_ptr< SfxGrabBagItem > mpGrabBagItem
Style InteropGrabBag.
Definition: numrule.hxx:141
bool NumDownChangesIndent(const SwWrtShell &rShell)
Decides if increasing ("downing") the numbering level will change the amount of indentation or not...
Definition: number.cxx:1495
bool IsInDtor() const
Definition: doc.hxx:404
tParagraphStyleList maParagraphStyleList
container for associated paragraph styles
Definition: numrule.hxx:121
void NumRuleChgd()
Notify this textnode that its numbering rule has changed.
Definition: ndtxt.cxx:2835
bool mbUserDefinedFontname
Definition: number.cxx:1214
void SetAbsLSpace(sal_Int32 nSet)
struct _xmlTextWriter * xmlTextWriterPtr
virtual void ImplCommit()=0
void SetNumberingType(SvxNumType nSet)
void SetName(const OUString &rNm, IDocumentListsAccess &rDocListAccess)
Definition: number.cxx:110
std::pair< const_iterator, bool > insert(Value &&x)
void SetFirstLineIndent(const tools::Long nFirstLineIndent)
void SetIndentOfFirstListLevelAndChangeOthers(const short nNewIndent)
set indent of first list level to given value and change other list level's indents accordingly ...
Definition: number.cxx:1053
tools::Long GetIndentAt() const
void SetLevel(sal_uInt16 nLevel, const SvxNumberFormat &rFmt, bool bIsValid=true)
aStr
virtual OUString GetCharFormatName() const override
Definition: number.cxx:310
sal_uInt16 mnPoolFormatId
Id-for NumRules created "automatically".
Definition: numrule.hxx:128
sal_Int16 GetVertOrient() const
std::optional< vcl::Font > mpFont
Definition: number.cxx:1220
void SetListFormat(const OUString &rPrefix, const OUString &rSuffix, int nLevel)
bool ChangeIndentOnTabAtFirstPosOfFirstListItem()
configuration, if at first position of the first list item the -key increased the indent of the ...
Definition: number.cxx:1490
void SetListtabPos(const tools::Long nListtabPos)
SAL_DLLPRIVATE void UpdateNumNodes(SwDoc &rDoc)
Definition: number.cxx:326
OUString msName
Definition: numrule.hxx:126
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:856
FontItalic
bool mbCountPhantoms
Definition: numrule.hxx:136
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
virtual void ResetModified()=0
SwNumRule & CopyNumRule(SwDoc &, const SwNumRule &)
A kind of copy-constructor to make sure the num formats are attached to the correctCharFormats of a d...
Definition: number.cxx:905
namespace for static functions and methods for numbering and bullets
Definition: number.cxx:1157
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo