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