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::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
282 {
283  // Look for the NumRules object in the Doc where this NumFormat is set.
284  // The format does not need to exist!
285  const SwCharFormat* pFormat = nullptr;
286  sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
287  switch( nWhich )
288  {
289  case RES_ATTRSET_CHG:
290  case RES_FMT_CHG:
291  pFormat = GetCharFormat();
292  break;
293  }
294 
295  if( pFormat && !pFormat->GetDoc()->IsInDtor() )
296  UpdateNumNodes( const_cast<SwDoc*>(pFormat->GetDoc()) );
297  else
298  CheckRegistration( pOld );
299 }
300 
302 {
303  if(static_cast<const SwCharFormat*>(GetRegisteredIn()))
304  return static_cast<const SwCharFormat*>(GetRegisteredIn())->GetName();
305 
306  return OUString();
307 }
308 
309 void SwNumFormat::SetGraphicBrush( const SvxBrushItem* pBrushItem, const Size* pSize,
310  const sal_Int16* pOrient)
311 {
312  if(pOrient)
313  m_pVertOrient->SetVertOrient( *pOrient );
314  SvxNumberFormat::SetGraphicBrush( pBrushItem, pSize, pOrient);
315 }
316 
318 {
319  bool bDocIsModified = pDoc->getIDocumentState().IsModified();
320  bool bFnd = false;
321  for( SwNumRuleTable::size_type n = pDoc->GetNumRuleTable().size(); !bFnd && n; )
322  {
323  const SwNumRule* pRule = pDoc->GetNumRuleTable()[ --n ];
324  for( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
325  if( pRule->GetNumFormat( i ) == this )
326  {
327  SwNumRule::tTextNodeList aTextNodeList;
328  pRule->GetTextNodeList( aTextNodeList );
329  for ( auto& rpTextNode : aTextNodeList )
330  {
331  lcl_SetRuleChgd( *rpTextNode, i );
332  }
333  bFnd = true;
334  break;
335  }
336  }
337 
338  if( bFnd && !bDocIsModified )
340 }
341 
343 {
344  sal_Int16 eOrient = SvxNumberFormat::GetVertOrient();
345  if(text::VertOrientation::NONE == eOrient)
346  return nullptr;
347  else
348  {
349  m_pVertOrient->SetVertOrient(eOrient);
350  return m_pVertOrient.get();
351  }
352 }
353 
354 SwNumRule::SwNumRule( const OUString& rNm,
355  const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode,
356  SwNumRuleType eType )
357  : maTextNodeList(),
358  maParagraphStyleList(),
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  msDefaultListId()
374 {
375  if( !snRefCount++ ) // for the first time, initialize
376  {
377  SwNumFormat* pFormat;
378  sal_uInt8 n;
379 
380  // numbering:
381  // position-and-space mode LABEL_WIDTH_AND_POSITION:
382  for( n = 0; n < MAXLEVEL; ++n )
383  {
384  pFormat = new SwNumFormat;
385  pFormat->SetIncludeUpperLevels( 1 );
386  pFormat->SetStart( 1 );
389  pFormat->SetSuffix( "." );
391  SwNumRule::saBaseFormats[ NUM_RULE ][ n ] = pFormat;
392  }
393  // position-and-space mode LABEL_ALIGNMENT
394  // first line indent of general numbering in inch: -0,25 inch
395  const long cFirstLineIndent = -1440/4;
396  // indent values of general numbering in inch:
397  // 0,5 0,75 1,0 1,25 1,5
398  // 1,75 2,0 2,25 2,5 2,75
399  const long cIndentAt[ MAXLEVEL ] = {
400  1440/2, 1440*3/4, 1440, 1440*5/4, 1440*3/2,
401  1440*7/4, 1440*2, 1440*9/4, 1440*5/2, 1440*11/4 };
402  for( n = 0; n < MAXLEVEL; ++n )
403  {
404  pFormat = new SwNumFormat;
405  pFormat->SetIncludeUpperLevels( 1 );
406  pFormat->SetStart( 1 );
409  pFormat->SetListtabPos( cIndentAt[ n ] );
410  pFormat->SetFirstLineIndent( cFirstLineIndent );
411  pFormat->SetIndentAt( cIndentAt[ n ] );
412  pFormat->SetSuffix( "." );
414  SwNumRule::saLabelAlignmentBaseFormats[ NUM_RULE ][ n ] = pFormat;
415  }
416 
417  // outline:
418  // position-and-space mode LABEL_WIDTH_AND_POSITION:
419  for( n = 0; n < MAXLEVEL; ++n )
420  {
421  pFormat = new SwNumFormat;
423  pFormat->SetIncludeUpperLevels( MAXLEVEL );
424  pFormat->SetStart( 1 );
427  SwNumRule::saBaseFormats[ OUTLINE_RULE ][ n ] = pFormat;
428  }
429  // position-and-space mode LABEL_ALIGNMENT:
430  for( n = 0; n < MAXLEVEL; ++n )
431  {
432  pFormat = new SwNumFormat;
434  pFormat->SetIncludeUpperLevels( MAXLEVEL );
435  pFormat->SetStart( 1 );
438  SwNumRule::saLabelAlignmentBaseFormats[ OUTLINE_RULE ][ n ] = pFormat;
439  }
440  }
441  OSL_ENSURE( !msName.isEmpty(), "NumRule without a name!" );
442 }
443 
444 SwNumRule::SwNumRule( const SwNumRule& rNumRule )
445  : maTextNodeList(),
446  maParagraphStyleList(),
447  mpNumRuleMap(nullptr),
448  msName( rNumRule.msName ),
449  meRuleType( rNumRule.meRuleType ),
450  mnPoolFormatId( rNumRule.GetPoolFormatId() ),
451  mnPoolHelpId( rNumRule.GetPoolHelpId() ),
452  mnPoolHlpFileId( rNumRule.GetPoolHlpFileId() ),
453  mbAutoRuleFlag( rNumRule.mbAutoRuleFlag ),
454  mbInvalidRuleFlag( true ),
455  mbContinusNum( rNumRule.mbContinusNum ),
456  mbAbsSpaces( rNumRule.mbAbsSpaces ),
457  mbHidden( rNumRule.mbHidden ),
458  mbCountPhantoms( true ),
459  mbUsedByRedline( false ),
460  meDefaultNumberFormatPositionAndSpaceMode( rNumRule.meDefaultNumberFormatPositionAndSpaceMode ),
461  msDefaultListId( rNumRule.msDefaultListId )
462 {
463  ++snRefCount;
464  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
465  if( rNumRule.maFormats[ n ] )
466  Set( n, *rNumRule.maFormats[ n ] );
467 }
468 
470 {
471  for (auto & i : maFormats)
472  i.reset();
473 
474  if (mpNumRuleMap)
475  {
476  mpNumRuleMap->erase(GetName());
477  }
478 
479  if( !--snRefCount ) // the last one closes the door (?)
480  {
481  // Numbering:
482  SwNumFormat** ppFormats = &SwNumRule::saBaseFormats[0][0];
483  int n;
484 
485  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
486  {
487  delete *ppFormats;
488  *ppFormats = nullptr;
489  }
490 
491  // Outline:
492  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
493  {
494  delete *ppFormats;
495  *ppFormats = nullptr;
496  }
497 
498  ppFormats = &SwNumRule::saLabelAlignmentBaseFormats[0][0];
499  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
500  {
501  delete *ppFormats;
502  *ppFormats = nullptr;
503  }
504  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
505  {
506  delete *ppFormats;
507  *ppFormats = nullptr;
508  }
509  }
510 
511  maTextNodeList.clear();
512  maParagraphStyleList.clear();
513 }
514 
516 {
517  for(auto& rpNumFormat : maFormats)
518  {
519  if( rpNumFormat )
520  {
521  SwCharFormat* pFormat = rpNumFormat->GetCharFormat();
522  if( pFormat && pFormat->GetDoc() != pDoc )
523  {
524  // copy
525  SwNumFormat* pNew = new SwNumFormat( *rpNumFormat );
526  pNew->SetCharFormat( pDoc->CopyCharFormat( *pFormat ) );
527  rpNumFormat.reset(pNew);
528  }
529  }
530  }
531 }
532 
534 {
535  if( this != &rNumRule )
536  {
537  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
538  Set( n, rNumRule.maFormats[ n ].get() );
539 
540  meRuleType = rNumRule.meRuleType;
541  msName = rNumRule.msName;
542  mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
543  mbInvalidRuleFlag = true;
544  mbContinusNum = rNumRule.mbContinusNum;
545  mbAbsSpaces = rNumRule.mbAbsSpaces;
546  mbHidden = rNumRule.mbHidden;
547  mnPoolFormatId = rNumRule.GetPoolFormatId();
548  mnPoolHelpId = rNumRule.GetPoolHelpId();
549  mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
550  }
551  return *this;
552 }
553 
554 bool SwNumRule::operator==( const SwNumRule& rRule ) const
555 {
556  bool bRet = meRuleType == rRule.meRuleType &&
557  msName == rRule.msName &&
558  mbAutoRuleFlag == rRule.mbAutoRuleFlag &&
559  mbContinusNum == rRule.mbContinusNum &&
560  mbAbsSpaces == rRule.mbAbsSpaces &&
561  mnPoolFormatId == rRule.GetPoolFormatId() &&
562  mnPoolHelpId == rRule.GetPoolHelpId() &&
564  if( bRet )
565  {
566  for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
567  if( rRule.Get( n ) != Get( n ) )
568  {
569  bRet = false;
570  break;
571  }
572  }
573  return bRet;
574 }
575 
576 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat& rNumFormat )
577 {
578  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
579  if( i < MAXLEVEL )
580  {
581  if( !maFormats[ i ] || (rNumFormat != Get( i )) )
582  {
583  maFormats[ i ].reset(new SwNumFormat( rNumFormat ));
584  mbInvalidRuleFlag = true;
585  }
586  }
587 }
588 
589 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat* pNumFormat )
590 {
591  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
592  if( i >= MAXLEVEL )
593  return;
594  if( !maFormats[ i ] )
595  {
596  if( pNumFormat )
597  {
598  maFormats[ i ].reset(new SwNumFormat( *pNumFormat ));
599  mbInvalidRuleFlag = true;
600  }
601  }
602  else if( !pNumFormat )
603  {
604  maFormats[ i ].reset();
605  mbInvalidRuleFlag = true;
606  }
607  else if( *maFormats[i] != *pNumFormat )
608  {
609  *maFormats[ i ] = *pNumFormat;
610  mbInvalidRuleFlag = true;
611  }
612 }
613 
614 OUString SwNumRule::MakeNumString( const SwNodeNum& rNum, bool bInclStrings ) const
615 {
616  if (rNum.IsCounted())
617  return MakeNumString(rNum.GetNumberVector(), bInclStrings);
618 
619  return OUString();
620 }
621 
623  const bool bInclStrings,
624  const bool bOnlyArabic,
625  const unsigned int _nRestrictToThisLevel,
626  SwNumRule::Extremities* pExtremities,
627  LanguageType nLang ) const
628 {
629  OUStringBuffer aStr;
630 
631  SwNumberTree::tNumberVector::size_type nLevel = rNumVector.size() - 1;
632 
633  if ( pExtremities )
634  pExtremities->nPrefixChars = pExtremities->nSuffixChars = 0;
635 
636  if ( nLevel > _nRestrictToThisLevel )
637  {
638  nLevel = _nRestrictToThisLevel;
639  }
640 
641  if (nLevel < MAXLEVEL)
642  {
643  const SwNumFormat& rMyNFormat = Get( static_cast<sal_uInt16>(nLevel) );
644 
645  {
646  css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang));
647 
648  if (rMyNFormat.HasListFormat())
649  {
650  OUString sLevelFormat = rMyNFormat.GetListFormat();
651  // In this case we are ignoring GetIncludeUpperLevels: we put all
652  // level numbers requested by level format
653  for (SwNumberTree::tNumberVector::size_type i=0; i <= nLevel; ++i)
654  {
655  OUString sReplacement;
656  if (rNumVector[i])
657  {
658  if (bOnlyArabic)
659  sReplacement = OUString::number(rNumVector[i]);
660  else
661  sReplacement = Get(i).GetNumStr(rNumVector[i], aLocale);
662  }
663  else
664  sReplacement = "0"; // all 0 level are a 0
665 
666  OUString sFind("%" + OUString::number(i + 1));
667  sal_Int32 nPosition = sLevelFormat.indexOf(sFind);
668  if (nPosition >= 0)
669  sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
670  }
671 
672  // As a fallback: caller code expects nonempty string as a result.
673  // But if we have empty string (and had no errors before) this is valid result.
674  // So use classical hack with zero-width-space as a string filling.
675  if (sLevelFormat.isEmpty())
676  sLevelFormat = OUStringChar(CHAR_ZWSP);
677 
678  aStr = sLevelFormat;
679  }
680  else
681  {
682  // Fallback case: level format is not defined
683  // So use old way with levels joining by dot "."
684  SwNumberTree::tNumberVector::size_type i = nLevel;
685 
686  if (!IsContinusNum() &&
687  // - do not include upper levels, if level isn't numbered.
688  rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
689  rMyNFormat.GetIncludeUpperLevels()) // Just the own level?
690  {
691  sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels();
692  if (1 < n)
693  {
694  if (i + 1 >= n)
695  i -= n - 1;
696  else
697  i = 0;
698  }
699  }
700 
701  for (; i <= nLevel; ++i)
702  {
703  const SwNumFormat& rNFormat = Get(i);
704  if (SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType())
705  {
706  // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ??
707  // if( i != rNum.nMyLevel )
708  // aStr += ".";
709  continue;
710  }
711 
712  if (rNumVector[i])
713  {
714  if (bOnlyArabic)
715  aStr.append(OUString::number(rNumVector[i]));
716  else
717  aStr.append(rNFormat.GetNumStr(rNumVector[i], aLocale));
718  }
719  else
720  aStr.append("0"); // all 0 level are a 0
721  if (i != nLevel && !aStr.isEmpty())
722  aStr.append(".");
723  }
724 
725  // The type doesn't have any number, so don't append
726  // the post-/prefix string
727  if (bInclStrings && !bOnlyArabic &&
728  SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() &&
729  SVX_NUM_BITMAP != rMyNFormat.GetNumberingType())
730  {
731  const OUString& sPrefix = rMyNFormat.GetPrefix();
732  const OUString& sSuffix = rMyNFormat.GetSuffix();
733 
734  aStr.insert(0, sPrefix);
735  aStr.append(sSuffix);
736  if (pExtremities)
737  {
738  pExtremities->nPrefixChars = sPrefix.getLength();
739  pExtremities->nSuffixChars = sSuffix.getLength();
740  }
741  }
742  }
743  }
744  }
745 
746  return aStr.makeStringAndClear();
747 }
748 
749 OUString SwNumRule::MakeRefNumString( const SwNodeNum& rNodeNum,
750  const bool bInclSuperiorNumLabels,
751  const int nRestrictInclToThisLevel ) const
752 {
753  OUString aRefNumStr;
754 
755  if ( rNodeNum.GetLevelInListTree() >= 0 )
756  {
757  bool bOldHadPrefix = true;
758 
759  const SwNodeNum* pWorkingNodeNum( &rNodeNum );
760  do
761  {
762  bool bMakeNumStringForPhantom( false );
763  if ( pWorkingNodeNum->IsPhantom() )
764  {
765  int nListLevel = pWorkingNodeNum->GetLevelInListTree();
766 
767  if (nListLevel < 0)
768  nListLevel = 0;
769 
770  if (nListLevel >= MAXLEVEL)
771  nListLevel = MAXLEVEL - 1;
772 
773  SwNumFormat aFormat( Get( static_cast<sal_uInt16>(nListLevel) ) );
774  bMakeNumStringForPhantom = aFormat.IsEnumeration() &&
776 
777  }
778  if ( bMakeNumStringForPhantom ||
779  ( !pWorkingNodeNum->IsPhantom() &&
780  pWorkingNodeNum->GetTextNode() &&
781  pWorkingNodeNum->GetTextNode()->HasNumber() ) )
782  {
783  Extremities aExtremities;
784  OUString aPrevStr = MakeNumString( pWorkingNodeNum->GetNumberVector(),
785  true, false, MAXLEVEL,
786  &aExtremities);
787  sal_Int32 nStrip = 0;
788  while ( nStrip < aExtremities.nPrefixChars )
789  {
790  const sal_Unicode c = aPrevStr[nStrip];
791  if ( c!='\t' && c!=' ')
792  break;
793  ++nStrip;
794  }
795 
796  if (nStrip)
797  {
798  aPrevStr = aPrevStr.copy( nStrip );
799  aExtremities.nPrefixChars -= nStrip;
800  }
801 
802  if (bOldHadPrefix &&
803  aExtremities.nSuffixChars &&
804  !aExtremities.nPrefixChars
805  )
806  {
807  aPrevStr = aPrevStr.copy(0,
808  aPrevStr.getLength() - aExtremities.nSuffixChars);
809  }
810 
811  bOldHadPrefix = ( aExtremities.nPrefixChars > 0);
812 
813  aRefNumStr = aPrevStr + aRefNumStr;
814  }
815 
816  if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
817  {
818  sal_uInt8 n = Get( static_cast<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
819  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
820  // skip parents, whose list label is already contained in the actual list label.
821  while ( pWorkingNodeNum && n > 1 )
822  {
823  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
824  --n;
825  }
826  }
827  else
828  {
829  break;
830  }
831  } while ( pWorkingNodeNum &&
832  pWorkingNodeNum->GetLevelInListTree() >= 0 &&
833  pWorkingNodeNum->GetLevelInListTree() >= nRestrictInclToThisLevel );
834  }
835 
836  return aRefNumStr;
837 }
838 
840 {
841  OUString aParagraphStyleListString;
842  for (const auto& rParagraphStyle : maParagraphStyleList)
843  {
844  if (!aParagraphStyleListString.isEmpty())
845  aParagraphStyleListString += ", ";
846  aParagraphStyleListString += rParagraphStyle->GetName();
847  }
848  return aParagraphStyleListString;
849 }
850 
857 {
858  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
859  {
860  Set( n, rNumRule.maFormats[ n ].get() );
861  if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() &&
862  !pDoc->GetCharFormats()->IsAlive(maFormats[n]->GetCharFormat()))
863  {
864  // If we copy across different Documents, then copy the
865  // corresponding CharFormat into the new Document.
866  maFormats[n]->SetCharFormat( pDoc->CopyCharFormat( *maFormats[n]->
867  GetCharFormat() ) );
868  }
869  }
870  meRuleType = rNumRule.meRuleType;
871  msName = rNumRule.msName;
872  mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
873  mnPoolFormatId = rNumRule.GetPoolFormatId();
874  mnPoolHelpId = rNumRule.GetPoolHelpId();
875  mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
876  mbInvalidRuleFlag = true;
877  return *this;
878 }
879 
880 void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
881 {
882  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
883  {
884  const SvxNumberFormat* pSvxFormat = rNumRule.Get(n);
885  maFormats[n].reset( pSvxFormat ? new SwNumFormat(*pSvxFormat, pDoc) : nullptr );
886  }
887 
888  mbInvalidRuleFlag = true;
890 }
891 
893 {
894  SvxNumRule aRule(SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::CHAR_STYLE |
895  SvxNumRuleFlags::ENABLE_LINKED_BMP | SvxNumRuleFlags::ENABLE_EMBEDDED_BMP,
897  meRuleType == NUM_RULE ? SvxNumRuleType::NUMBERING : SvxNumRuleType::OUTLINE_NUMBERING );
898  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
899  {
900  SwNumFormat aNumFormat = Get(n);
901  if(aNumFormat.GetCharFormat())
902  aNumFormat.SetCharFormatName(aNumFormat.GetCharFormat()->GetName());
903  aRule.SetLevel(n, aNumFormat, maFormats[n] != nullptr);
904  }
905  return aRule;
906 }
907 
909 {
910  if (bFlag)
911  {
913  for ( const SwTextNode* pTextNode : maTextNodeList )
914  {
915  // #i111681# - applying patch from cmc
916  SwList* pList = pTextNode->GetDoc()->getIDocumentListsAccess().getListByName( pTextNode->GetListId() );
917  OSL_ENSURE( pList, "<SwNumRule::SetInvalidRule(..)> - list at which the text node is registered at does not exist. This is a serious issue.");
918  if ( pList )
919  {
920  aLists.insert( pList );
921  }
922  }
923  for ( auto aList : aLists )
924  aList->InvalidateListTree();
925  }
926 
927  mbInvalidRuleFlag = bFlag;
928 }
929 
931 void SwNumRule::ChangeIndent( const sal_Int32 nDiff )
932 {
933  for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
934  {
935  SwNumFormat aTmpNumFormat( Get(i) );
936 
937  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
938  aTmpNumFormat.GetPositionAndSpaceMode() );
939  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
940  {
941  auto nNewIndent = nDiff +
942  aTmpNumFormat.GetAbsLSpace();
943  if ( nNewIndent < 0 )
944  {
945  nNewIndent = 0;
946  }
947  aTmpNumFormat.SetAbsLSpace( nNewIndent );
948  }
949  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
950  {
951  // adjust also the list tab position, if a list tab stop is applied
952  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
953  {
954  const long nNewListTab = aTmpNumFormat.GetListtabPos() + nDiff;
955  aTmpNumFormat.SetListtabPos( nNewListTab );
956  }
957 
958  const long nNewIndent = nDiff +
959  aTmpNumFormat.GetIndentAt();
960  aTmpNumFormat.SetIndentAt( nNewIndent );
961  }
962 
963  Set( i, aTmpNumFormat );
964  }
965 
966  SetInvalidRule( true );
967 }
968 
970 void SwNumRule::SetIndent( const short nNewIndent,
971  const sal_uInt16 nListLevel )
972 {
973  SwNumFormat aTmpNumFormat( Get(nListLevel) );
974 
975  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
976  aTmpNumFormat.GetPositionAndSpaceMode() );
977  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
978  {
979  aTmpNumFormat.SetAbsLSpace( nNewIndent );
980  }
981  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
982  {
983  // adjust also the list tab position, if a list tab stop is applied
984  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
985  {
986  const long nNewListTab = aTmpNumFormat.GetListtabPos() +
987  ( nNewIndent - aTmpNumFormat.GetIndentAt() );
988  aTmpNumFormat.SetListtabPos( nNewListTab );
989  }
990 
991  aTmpNumFormat.SetIndentAt( nNewIndent );
992  }
993 
994  SetInvalidRule( true );
995 }
996 
1000 {
1001  SwNumFormat aTmpNumFormat( Get(0) );
1002 
1003  sal_Int32 nDiff( 0 );
1004  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1005  aTmpNumFormat.GetPositionAndSpaceMode() );
1006  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1007  {
1008  nDiff = nNewIndent
1009  - aTmpNumFormat.GetFirstLineOffset()
1010  - aTmpNumFormat.GetAbsLSpace();
1011  }
1012  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1013  {
1014  nDiff = nNewIndent - aTmpNumFormat.GetIndentAt();
1015  }
1016  if ( nDiff != 0 )
1017  {
1018  ChangeIndent( nDiff );
1019  }
1020 }
1021 
1023 {
1025  for ( const SwTextNode* pTextNode : maTextNodeList )
1026  {
1027  aLists.insert( pTextNode->GetDoc()->getIDocumentListsAccess().getListByName( pTextNode->GetListId() ) );
1028  }
1029  for ( auto aList : aLists )
1030  aList->ValidateListTree();
1031 
1032  SetInvalidRule(false);
1033 }
1034 
1035 void SwNumRule::SetCountPhantoms(bool bCountPhantoms)
1036 {
1037  mbCountPhantoms = bCountPhantoms;
1038 }
1039 
1040 SwNumRule::tParagraphStyleList::size_type SwNumRule::GetParagraphStyleListSize() const
1041 {
1042  return maParagraphStyleList.size();
1043 }
1044 
1046 {
1047  tParagraphStyleList::iterator aIter =
1048  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1049 
1050  if ( aIter == maParagraphStyleList.end() )
1051  {
1052  maParagraphStyleList.push_back( &rTextFormatColl );
1053  }
1054 }
1055 
1057 {
1058  tParagraphStyleList::iterator aIter =
1059  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1060 
1061  if ( aIter != maParagraphStyleList.end() )
1062  {
1063  maParagraphStyleList.erase( aIter );
1064  }
1065 }
1066 
1068 {
1069  xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRule"));
1070  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("msName"), BAD_CAST(msName.toUtf8().getStr()));
1071  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mnPoolFormatId"), BAD_CAST(OString::number(mnPoolFormatId).getStr()));
1072  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mbAutoRuleFlag"), BAD_CAST(OString::boolean(mbAutoRuleFlag).getStr()));
1073 
1074  for (const auto& pFormat : maFormats)
1075  {
1076  if (!pFormat)
1077  {
1078  continue;
1079  }
1080 
1081  pFormat->dumpAsXml(pWriter);
1082  }
1083 
1084  xmlTextWriterEndElement(pWriter);
1085 }
1086 
1088 {
1089  if (mpGrabBagItem)
1090  mpGrabBagItem->QueryValue(rVal);
1091  else
1092  rVal <<= uno::Sequence<beans::PropertyValue>();
1093 }
1094 
1096 {
1097  if (!mpGrabBagItem)
1098  mpGrabBagItem = std::make_shared<SfxGrabBagItem>();
1099 
1100  mpGrabBagItem->PutValue(rVal, 0);
1101 }
1102 
1103 namespace numfunc
1104 {
1105  namespace {
1106 
1108  class SwDefBulletConfig : private utl::ConfigItem
1109  {
1110  public:
1111  static SwDefBulletConfig& getInstance();
1112 
1113  const OUString& GetFontname() const
1114  {
1115  return msFontname;
1116  }
1117 
1118  bool IsFontnameUserDefined() const
1119  {
1120  return mbUserDefinedFontname;
1121  }
1122 
1123  const vcl::Font& GetFont() const
1124  {
1125  return *mpFont;
1126  }
1127 
1128  sal_Unicode GetChar( sal_uInt8 p_nListLevel ) const
1129  {
1130  if (p_nListLevel >= MAXLEVEL)
1131  {
1132  p_nListLevel = MAXLEVEL - 1;
1133  }
1134 
1135  return mnLevelChars[p_nListLevel];
1136  }
1137 
1138  SwDefBulletConfig();
1139 
1140  private:
1142  void SetToDefault();
1143 
1145  static uno::Sequence<OUString> GetPropNames();
1146 
1149  void LoadConfig();
1150 
1152  void InitFont();
1153 
1155  virtual void Notify( const uno::Sequence<OUString>& aPropertyNames ) override;
1156  virtual void ImplCommit() override;
1157 
1158  // default bullet list configuration data
1159  OUString msFontname;
1164 
1165  // default bullet list font instance
1166  std::unique_ptr<vcl::Font> mpFont;
1167  };
1168 
1169  class theSwDefBulletConfig
1170  : public rtl::Static<SwDefBulletConfig, theSwDefBulletConfig>{};
1171  }
1172 
1173  SwDefBulletConfig& SwDefBulletConfig::getInstance()
1174  {
1175  return theSwDefBulletConfig::get();
1176  }
1177 
1178  SwDefBulletConfig::SwDefBulletConfig()
1179  : ConfigItem( "Office.Writer/Numbering/DefaultBulletList" ),
1180  // default bullet font is now OpenSymbol
1181  msFontname( OUString("OpenSymbol") ),
1182  mbUserDefinedFontname( false ),
1185  {
1186  SetToDefault();
1187  LoadConfig();
1188  InitFont();
1189 
1190  // enable notification for changes on default bullet configuration change
1191  EnableNotification( GetPropNames() );
1192  }
1193 
1194  void SwDefBulletConfig::SetToDefault()
1195  {
1196  msFontname = "OpenSymbol";
1197  mbUserDefinedFontname = false;
1200 
1201  mnLevelChars[0] = 0x2022;
1202  mnLevelChars[1] = 0x25e6;
1203  mnLevelChars[2] = 0x25aa;
1204  mnLevelChars[3] = 0x2022;
1205  mnLevelChars[4] = 0x25e6;
1206  mnLevelChars[5] = 0x25aa;
1207  mnLevelChars[6] = 0x2022;
1208  mnLevelChars[7] = 0x25e6;
1209  mnLevelChars[8] = 0x25aa;
1210  mnLevelChars[9] = 0x2022;
1211  }
1212 
1213  uno::Sequence<OUString> SwDefBulletConfig::GetPropNames()
1214  {
1215  uno::Sequence<OUString> aPropNames(13);
1216  OUString* pNames = aPropNames.getArray();
1217  pNames[0] = "BulletFont/FontFamilyname";
1218  pNames[1] = "BulletFont/FontWeight";
1219  pNames[2] = "BulletFont/FontItalic";
1220  pNames[3] = "BulletCharLvl1";
1221  pNames[4] = "BulletCharLvl2";
1222  pNames[5] = "BulletCharLvl3";
1223  pNames[6] = "BulletCharLvl4";
1224  pNames[7] = "BulletCharLvl5";
1225  pNames[8] = "BulletCharLvl6";
1226  pNames[9] = "BulletCharLvl7";
1227  pNames[10] = "BulletCharLvl8";
1228  pNames[11] = "BulletCharLvl9";
1229  pNames[12] = "BulletCharLvl10";
1230 
1231  return aPropNames;
1232  }
1233 
1234  void SwDefBulletConfig::LoadConfig()
1235  {
1236  uno::Sequence<OUString> aPropNames = GetPropNames();
1237  uno::Sequence<uno::Any> aValues = GetProperties( aPropNames );
1238  const uno::Any* pValues = aValues.getConstArray();
1239  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1240  "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed");
1241  if ( aValues.getLength() != aPropNames.getLength() )
1242  return;
1243 
1244  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1245  {
1246  if ( pValues[nProp].hasValue() )
1247  {
1248  switch ( nProp )
1249  {
1250  case 0:
1251  {
1252  OUString aStr;
1253  pValues[nProp] >>= aStr;
1254  msFontname = aStr;
1255  mbUserDefinedFontname = true;
1256  }
1257  break;
1258  case 1:
1259  case 2:
1260  {
1261  sal_Int16 nTmp = 0;
1262  pValues[nProp] >>= nTmp;
1263  if ( nProp == 1 )
1264  meFontWeight = static_cast<FontWeight>(nTmp);
1265  else if ( nProp == 2 )
1266  meFontItalic = static_cast<FontItalic>(nTmp);
1267  }
1268  break;
1269  case 3:
1270  case 4:
1271  case 5:
1272  case 6:
1273  case 7:
1274  case 8:
1275  case 9:
1276  case 10:
1277  case 11:
1278  case 12:
1279  {
1280  sal_Unicode cChar = sal_Unicode();
1281  pValues[nProp] >>= cChar;
1282  mnLevelChars[nProp-3] = cChar;
1283  }
1284  break;
1285  }
1286  }
1287  }
1288 
1289  }
1290 
1291  void SwDefBulletConfig::InitFont()
1292  {
1293  mpFont.reset( new vcl::Font( msFontname, OUString(), Size( 0, 14 ) ) );
1294  mpFont->SetWeight( meFontWeight );
1295  mpFont->SetItalic( meFontItalic );
1296  mpFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
1297  }
1298 
1299  void SwDefBulletConfig::Notify( const uno::Sequence<OUString>& )
1300  {
1301  SetToDefault();
1302  LoadConfig();
1303  InitFont();
1304  }
1305 
1306  void SwDefBulletConfig::ImplCommit()
1307  {
1308  }
1309 
1310  OUString const & GetDefBulletFontname()
1311  {
1312  return SwDefBulletConfig::getInstance().GetFontname();
1313  }
1314 
1316  {
1317  return SwDefBulletConfig::getInstance().IsFontnameUserDefined();
1318  }
1319 
1321  {
1322  return SwDefBulletConfig::getInstance().GetFont();
1323  }
1324 
1326  {
1327  return SwDefBulletConfig::getInstance().GetChar( nLevel );
1328  }
1329 
1330  namespace {
1331 
1337  class SwNumberingUIBehaviorConfig : private utl::ConfigItem
1338  {
1339  public:
1340  static SwNumberingUIBehaviorConfig& getInstance();
1341 
1343  {
1345  }
1346 
1347  SwNumberingUIBehaviorConfig();
1348 
1349  private:
1350 
1352  void SetToDefault();
1353 
1355  static css::uno::Sequence<OUString> GetPropNames();
1356 
1358  void LoadConfig();
1359 
1361  virtual void Notify( const css::uno::Sequence<OUString>& aPropertyNames ) override;
1362  virtual void ImplCommit() override;
1363 
1364  // configuration data
1366  };
1367 
1368  class theSwNumberingUIBehaviorConfig : public rtl::Static<SwNumberingUIBehaviorConfig, theSwNumberingUIBehaviorConfig>{};
1369  }
1370 
1371  SwNumberingUIBehaviorConfig& SwNumberingUIBehaviorConfig::getInstance()
1372  {
1374  }
1375 
1376  SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1377  : ConfigItem( "Office.Writer/Numbering/UserInterfaceBehavior" ),
1379  {
1380  SetToDefault();
1381  LoadConfig();
1382 
1383  // enable notification for changes on configuration change
1384  EnableNotification( GetPropNames() );
1385  }
1386 
1387  void SwNumberingUIBehaviorConfig::SetToDefault()
1388  {
1390  }
1391 
1392  css::uno::Sequence<OUString> SwNumberingUIBehaviorConfig::GetPropNames()
1393  {
1394  css::uno::Sequence<OUString> aPropNames { "ChangeIndentOnTabAtFirstPosOfFirstListItem" };
1395 
1396  return aPropNames;
1397  }
1398 
1399  void SwNumberingUIBehaviorConfig::ImplCommit() {}
1400 
1401  void SwNumberingUIBehaviorConfig::LoadConfig()
1402  {
1403  css::uno::Sequence<OUString> aPropNames = GetPropNames();
1404  css::uno::Sequence<css::uno::Any> aValues = GetProperties( aPropNames );
1405  const css::uno::Any* pValues = aValues.getConstArray();
1406  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1407  "<SwNumberingUIBehaviorConfig::LoadConfig()> - GetProperties failed");
1408  if ( aValues.getLength() != aPropNames.getLength() )
1409  return;
1410 
1411  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1412  {
1413  if ( pValues[nProp].hasValue() )
1414  {
1415  switch ( nProp )
1416  {
1417  case 0:
1418  {
1420  }
1421  break;
1422  default:
1423  {
1424  OSL_FAIL( "<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property");
1425  }
1426  }
1427  }
1428  }
1429  }
1430 
1431  void SwNumberingUIBehaviorConfig::Notify( const css::uno::Sequence<OUString>& )
1432  {
1433  SetToDefault();
1434  LoadConfig();
1435  }
1436 
1438  {
1439  return SwNumberingUIBehaviorConfig::getInstance().ChangeIndentOnTabAtFirstPosOfFirstListItem();
1440  }
1441 
1443  {
1444  SwPaM* pCursor = rShell.GetCursor();
1445  if (!pCursor)
1446  {
1447  return true;
1448  }
1449 
1450  SwTextNode* pTextNode = pCursor->GetNode().GetTextNode();
1451  if (!pTextNode)
1452  {
1453  return true;
1454  }
1455 
1456  const SwNumRule* pNumRule = pTextNode->GetNumRule();
1457  if (!pNumRule)
1458  {
1459  return true;
1460  }
1461 
1462  int nOldLevel = pTextNode->GetActualListLevel();
1463  int nNewLevel = nOldLevel + 1;
1464  if (nNewLevel >= MAXLEVEL)
1465  {
1466  return true;
1467  }
1468 
1469  const SwNumFormat& rOldFormat = pNumRule->Get(nOldLevel);
1470  if (rOldFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1471  {
1472  return true;
1473  }
1474 
1475  const SwNumFormat& rNewFormat = pNumRule->Get(nNewLevel);
1476  if (rNewFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1477  {
1478  return true;
1479  }
1480 
1481  // This is the case when the numbering levels don't differ, so changing between them is not
1482  // a better alternative to inserting a tab character.
1483  return rOldFormat.GetIndentAt() != rNewFormat.GetIndentAt();
1484  }
1485 
1487  {
1490 
1492  SvtSaveOptions aSaveOptions;
1493  switch (aSaveOptions.GetODFSaneDefaultVersion())
1494  {
1497  {
1498  ePosAndSpaceMode = SvxNumberFormat::LABEL_WIDTH_AND_POSITION;
1499  }
1500  break;
1501  default: // >= ODFSVER_012
1502  {
1503  ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1504  }
1505  }
1506 
1507  return ePosAndSpaceMode;
1508  }
1509 }
1510 
1512 {
1513  xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRuleTable"));
1514  for (SwNumRule* pNumRule : *this)
1515  pNumRule->dumpAsXml(pWriter);
1516  xmlTextWriterEndElement(pWriter);
1517 }
1518 
1519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
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:1045
bool NumDownChangesIndent(SwWrtShell &rShell)
Decides if increasing ("downing") the numbering level will change the amount of indentation or not...
Definition: number.cxx:1442
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:217
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
SwNumFormat & operator=(const SwNumFormat &)
Definition: number.cxx:257
static sal_uInt16 GetBullIndent(sal_uInt8 nLvl)
Definition: number.cxx:167
static void lcl_SetRuleChgd(SwTextNode &rNd, sal_uInt8 nLevel)
Definition: number.cxx:173
virtual void trackChangeOfListStyleName(const OUString &rListStyleName, const OUString &rNewListStyleName)=0
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:189
OUString MakeRefNumString(const SwNodeNum &rNodeNum, const bool bInclSuperiorNumLabels, const int nRestrictInclToThisLevel) const
Definition: number.cxx:749
OUString MakeNumString(const SwNodeNum &, bool bInclStrings=true) const
Definition: number.cxx:614
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:3127
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
Definition: docfmt.cxx:843
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:89
void SetPositionAndSpaceMode(SvxNumPositionAndSpaceMode ePositionAndSpaceMode)
const SvxBrushItem * GetBrush() const
OUString msFontname
Definition: number.cxx:1159
SVX_NUM_NUMBER_NONE
const short lNumberFirstLineOffset
Definition: swtypes.hxx:106
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:839
sal_uInt16 GetPoolFormatId() const
Query and set PoolFormat IDs.
Definition: numrule.hxx:249
const OUString & GetDefaultListId() const
Definition: numrule.hxx:193
Definition: list.hxx:35
sal_Int64 n
void GetGrabBagItem(css::uno::Any &rVal) const
Definition: number.cxx:1087
FontWeight meFontWeight
Definition: number.cxx:1161
Definition: doc.hxx:184
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
void RemoveParagraphStyle(SwTextFormatColl &rTextFormatColl)
Definition: number.cxx:1056
OUString msName
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
virtual bool IsCounted() const override
Return if this node is counted.
Definition: SwNodeNum.cxx:167
const OUString & GetName() const
Definition: numrule.hxx:223
sal_uInt16 GetPoolHelpId() const
Query and set Help-IDs for document styles.
Definition: numrule.hxx:253
SwNumberTree::tNumberVector GetNumberVector() const
Returns level numbers of this node.
bool operator==(const SwNumRule &) const
Definition: number.cxx:554
void SetIncludeUpperLevels(sal_uInt8 nSet)
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3090
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: number.cxx:1511
bool mbInvalidRuleFlag
Definition: numrule.hxx:132
SwTextNode * GetTextNode() const
Definition: SwNodeNum.hxx:41
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:4111
int GetLevelInListTree() const
Return level of this node.
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:90
void StartListeningToSameModifyAs(const SwClient &)
Definition: calbck.cxx:116
sal_uInt16 sal_Unicode
void SetGrabBagItem(const css::uno::Any &rVal)
Definition: number.cxx:1095
bool operator==(const SvxNumberFormat &) const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
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:1325
const OUString & GetName() const
Definition: format.hxx:111
static bool IsFuzzing()
void SetCharFormatName(const OUString &rSet)
SVX_NUM_ARABIC
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(161)
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(160)
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:1162
sal_Unicode mnLevelChars[MAXLEVEL]
Definition: number.cxx:1163
SvxNumRule MakeSvxNumRule() const
Definition: number.cxx:892
void SetFirstLineIndent(const long nFirstLineIndent)
bool IsAlive(typename std::remove_pointer< Value >::type const *const p) const
check that given format is still alive (i.e. contained here)
Definition: docary.hxx:137
void EndListeningAll()
Definition: calbck.cxx:124
void CheckCharFormats(SwDoc *pDoc)
Tests whether the CharFormats are from the given doc and copies them if appropriate.
Definition: number.cxx:515
bool IsContinusNum() const
Definition: numrule.hxx:234
SVX_NUM_BITMAP
exports com.sun.star. text
bool mbChangeIndentOnTabAtFirstPosOfFirstListItem
Definition: number.cxx:1365
SVX_NUM_CHAR_SPECIAL
WEIGHT_DONTKNOW
SwCharFormat * GetCharFormat() const
Definition: numrule.hxx:74
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:856
SwNumRule(const OUString &rNm, const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode, SwNumRuleType=NUM_RULE)
add parameter
Definition: number.cxx:354
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:342
void SetListtabPos(const long nListtabPos)
std::unique_ptr< SwFormatVertOrient > m_pVertOrient
Definition: numrule.hxx:52
std::unique_ptr< sw::ModifyChangedHint > CheckRegistration(const SfxPoolItem *pOldValue)
Definition: calbck.cxx:78
void SetIndentAt(const long nIndentAt)
int i
LabelFollowedBy GetLabelFollowedBy() const
sal_Int32 GetAbsLSpace() const
std::vector< SwNumRule * >::size_type size_type
Definition: docary.hxx:63
virtual bool IsModified() const =0
Changes of document?
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
Definition: number.cxx:1320
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
void RemoveTextNode(SwTextNode &rTextNode)
Definition: number.cxx:144
size_t size() const
Definition: docary.hxx:84
virtual ~SwNumFormat() override
Definition: number.cxx:224
SwNumRuleType meRuleType
Definition: numrule.hxx:127
void SetBulletChar(sal_Unicode cSet)
static OUString GetOutlineRuleName()
Definition: number.cxx:74
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2808
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:255
#define CHAR_ZWSP
Definition: swtypes.hxx:169
void GetTextNodeList(SwNumRule::tTextNodeList &rTextNodeList) const
Definition: number.cxx:123
static sal_uInt16 GetNumIndent(sal_uInt8 nLvl)
Definition: number.cxx:161
const short lOutlineMinTextDistance
Definition: swtypes.hxx:107
void SetCountPhantoms(bool bCountPhantoms)
Definition: number.cxx:1035
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:119
void SetIndent(const short nNewIndent, const sal_uInt16 nListLevel)
set indent of certain list level to given value
Definition: number.cxx:970
void SetCharTextDistance(short nSet)
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
void dumpAsXml(xmlTextWriterPtr w) const
Definition: number.cxx:1067
SAL_DLLPRIVATE void UpdateNumNodes(SwDoc *pDoc)
Definition: number.cxx:317
SwNumRule::tParagraphStyleList::size_type GetParagraphStyleListSize() const
Definition: number.cxx:1040
ODFSaneDefaultVersion GetODFSaneDefaultVersion() const
std::unique_ptr< vcl::Font > mpFont
Definition: number.cxx:1166
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:931
std::vector< tSwNumTreeNumber > tNumberVector
long GetIndentAt() const
const OUString & GetListFormat() const
bool mbContinusNum
Continuous numbering without levels.
Definition: numrule.hxx:133
const SvxNumberFormat::SvxNumPositionAndSpaceMode meDefaultNumberFormatPositionAndSpaceMode
it needs to export as part of tracked numbering change
Definition: numrule.hxx:139
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:79
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:768
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:80
bool IsContinuousNumbering() const
FontWeight
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:589
SwNumRule::tTextNodeList::size_type GetTextNodeListSize() const
Definition: number.cxx:128
void Validate()
Definition: number.cxx:1022
static SwNumFormat * saBaseFormats[RULE_END][MAXLEVEL]
Definition: numrule.hxx:109
void SetCharFormat(SwCharFormat *)
Definition: number.cxx:273
const Size & GetGraphicSize() const
void SetInvalidRule(bool bFlag)
Definition: number.cxx:908
const SwCharFormats * GetCharFormats() const
Definition: doc.hxx:735
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1486
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
Definition: number.cxx:1315
unsigned char sal_uInt8
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
Definition: number.cxx:1310
static sal_uInt16 snRefCount
Definition: numrule.hxx:113
SwCharFormat * CopyCharFormat(const SwCharFormat &)
copy the char format
Definition: docfmt.cxx:1156
void SetFirstLineOffset(sal_Int32 nSet)
sal_uInt16 nSuffixChars
Definition: numrule.hxx:103
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:254
tTextNodeList maTextNodeList
container for associated text nodes
Definition: numrule.hxx:118
const SwNumRuleTable & GetNumRuleTable() const
Definition: doc.hxx:1063
const sal_uInt16 lNumberIndent
Definition: swtypes.hxx:105
void SetSvxRule(const SvxNumRule &, SwDoc *pDoc)
Definition: number.cxx:880
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:157
~SwNumRule()
Definition: number.cxx:469
SwNumRule & operator=(const SwNumRule &)
Definition: number.cxx:533
static SwNumFormat * saLabelAlignmentBaseFormats[RULE_END][MAXLEVEL]
default list level properties for position-and-space mode LABEL_ALIGNMENT
Definition: numrule.hxx:112
void SetSuffix(const OUString &rSet)
long GetListtabPos() const
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:309
std::shared_ptr< SfxGrabBagItem > mpGrabBagItem
Style InteropGrabBag.
Definition: numrule.hxx:141
bool IsInDtor() const
Definition: doc.hxx:398
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:2848
bool mbUserDefinedFontname
Definition: number.cxx:1160
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 SetIndentOfFirstListLevelAndChangeOthers(const short nNewIndent)
set indent of first list level to given value and change other list level's indents accordingly ...
Definition: number.cxx:999
virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) override
Definition: number.cxx:281
void SetLevel(sal_uInt16 nLevel, const SvxNumberFormat &rFmt, bool bIsValid=true)
aStr
virtual OUString GetCharFormatName() const override
Definition: number.cxx:301
sal_uInt16 mnPoolFormatId
Id-for NumRules created "automatically".
Definition: numrule.hxx:128
sal_Int16 GetVertOrient() const
sal_uInt16 Which() const
bool ChangeIndentOnTabAtFirstPosOfFirstListItem()
configuration, if at first position of the first list item the -key increased the indent of the ...
Definition: number.cxx:1437
OUString msName
Definition: numrule.hxx:126
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:844
FontItalic
bool mbCountPhantoms
Definition: numrule.hxx:136
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
virtual void ResetModified()=0
namespace for static functions and methods for numbering and bullets
Definition: number.cxx:1103