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  : maTextNodeList(),
360  maParagraphStyleList(),
361  mpNumRuleMap(nullptr),
362  msName( rNm ),
363  meRuleType( eType ),
364  mnPoolFormatId( USHRT_MAX ),
365  mnPoolHelpId( USHRT_MAX ),
366  mnPoolHlpFileId( UCHAR_MAX ),
367  mbAutoRuleFlag( true ),
368  mbInvalidRuleFlag( true ),
369  mbContinusNum( false ),
370  mbAbsSpaces( false ),
371  mbHidden( false ),
372  mbCountPhantoms( true ),
373  mbUsedByRedline( false ),
374  meDefaultNumberFormatPositionAndSpaceMode( eDefaultNumberFormatPositionAndSpaceMode ),
375  msDefaultListId()
376 {
377  if( !snRefCount++ ) // for the first time, initialize
378  {
379  SwNumFormat* pFormat;
380  sal_uInt8 n;
381 
382  // numbering:
383  // position-and-space mode LABEL_WIDTH_AND_POSITION:
384  for( n = 0; n < MAXLEVEL; ++n )
385  {
386  pFormat = new SwNumFormat;
387  pFormat->SetIncludeUpperLevels( 1 );
388  pFormat->SetStart( 1 );
391  pFormat->SetListFormat("%" + OUString::number(n + 1) + "%.");
393  SwNumRule::saBaseFormats[ NUM_RULE ][ n ] = pFormat;
394  }
395  // position-and-space mode LABEL_ALIGNMENT
396  // first line indent of general numbering in inch: -0,25 inch
397  const tools::Long cFirstLineIndent = -1440/4;
398  // indent values of general numbering in inch:
399  // 0,5 0,75 1,0 1,25 1,5
400  // 1,75 2,0 2,25 2,5 2,75
401  const tools::Long cIndentAt[ MAXLEVEL ] = {
402  1440/2, 1440*3/4, 1440, 1440*5/4, 1440*3/2,
403  1440*7/4, 1440*2, 1440*9/4, 1440*5/2, 1440*11/4 };
404  for( n = 0; n < MAXLEVEL; ++n )
405  {
406  pFormat = new SwNumFormat;
407  pFormat->SetIncludeUpperLevels( 1 );
408  pFormat->SetStart( 1 );
411  pFormat->SetListtabPos( cIndentAt[ n ] );
412  pFormat->SetFirstLineIndent( cFirstLineIndent );
413  pFormat->SetIndentAt( cIndentAt[ n ] );
414  pFormat->SetListFormat( "%" + OUString::number(n + 1) + "%.");
416  SwNumRule::saLabelAlignmentBaseFormats[ NUM_RULE ][ n ] = pFormat;
417  }
418 
419  // outline:
420  // position-and-space mode LABEL_WIDTH_AND_POSITION:
421  for( n = 0; n < MAXLEVEL; ++n )
422  {
423  pFormat = new SwNumFormat;
425  pFormat->SetIncludeUpperLevels( MAXLEVEL );
426  pFormat->SetStart( 1 );
429  SwNumRule::saBaseFormats[ OUTLINE_RULE ][ n ] = pFormat;
430  }
431  // position-and-space mode LABEL_ALIGNMENT:
432  for( n = 0; n < MAXLEVEL; ++n )
433  {
434  pFormat = new SwNumFormat;
436  pFormat->SetIncludeUpperLevels( MAXLEVEL );
437  pFormat->SetStart( 1 );
440  SwNumRule::saLabelAlignmentBaseFormats[ OUTLINE_RULE ][ n ] = pFormat;
441  }
442  }
443  OSL_ENSURE( !msName.isEmpty(), "NumRule without a name!" );
444 }
445 
446 SwNumRule::SwNumRule( const SwNumRule& rNumRule )
447  : maTextNodeList(),
448  maParagraphStyleList(),
449  mpNumRuleMap(nullptr),
450  msName( rNumRule.msName ),
451  meRuleType( rNumRule.meRuleType ),
452  mnPoolFormatId( rNumRule.GetPoolFormatId() ),
453  mnPoolHelpId( rNumRule.GetPoolHelpId() ),
454  mnPoolHlpFileId( rNumRule.GetPoolHlpFileId() ),
455  mbAutoRuleFlag( rNumRule.mbAutoRuleFlag ),
456  mbInvalidRuleFlag( true ),
457  mbContinusNum( rNumRule.mbContinusNum ),
458  mbAbsSpaces( rNumRule.mbAbsSpaces ),
459  mbHidden( rNumRule.mbHidden ),
460  mbCountPhantoms( true ),
461  mbUsedByRedline( false ),
462  meDefaultNumberFormatPositionAndSpaceMode( rNumRule.meDefaultNumberFormatPositionAndSpaceMode ),
463  msDefaultListId( rNumRule.msDefaultListId )
464 {
465  ++snRefCount;
466  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
467  if( rNumRule.maFormats[ n ] )
468  Set( n, *rNumRule.maFormats[ n ] );
469 }
470 
472 {
473  for (auto & i : maFormats)
474  i.reset();
475 
476  if (mpNumRuleMap)
477  {
478  mpNumRuleMap->erase(GetName());
479  }
480 
481  if( !--snRefCount ) // the last one closes the door (?)
482  {
483  // Numbering:
484  SwNumFormat** ppFormats = &SwNumRule::saBaseFormats[0][0];
485  int n;
486 
487  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
488  {
489  delete *ppFormats;
490  *ppFormats = nullptr;
491  }
492 
493  // Outline:
494  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
495  {
496  delete *ppFormats;
497  *ppFormats = nullptr;
498  }
499 
500  ppFormats = &SwNumRule::saLabelAlignmentBaseFormats[0][0];
501  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
502  {
503  delete *ppFormats;
504  *ppFormats = nullptr;
505  }
506  for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
507  {
508  delete *ppFormats;
509  *ppFormats = nullptr;
510  }
511  }
512 
513  maTextNodeList.clear();
514  maParagraphStyleList.clear();
515 }
516 
518 {
519  for(auto& rpNumFormat : maFormats)
520  {
521  if( rpNumFormat )
522  {
523  SwCharFormat* pFormat = rpNumFormat->GetCharFormat();
524  if( pFormat && pFormat->GetDoc() != &rDoc )
525  {
526  // copy
527  SwNumFormat* pNew = new SwNumFormat( *rpNumFormat );
528  pNew->SetCharFormat( rDoc.CopyCharFormat( *pFormat ) );
529  rpNumFormat.reset(pNew);
530  }
531  }
532  }
533 }
534 
536 {
537  if( this != &rNumRule )
538  {
539  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
540  Set( n, rNumRule.maFormats[ n ].get() );
541 
542  meRuleType = rNumRule.meRuleType;
543  msName = rNumRule.msName;
544  mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
545  mbInvalidRuleFlag = true;
546  mbContinusNum = rNumRule.mbContinusNum;
547  mbAbsSpaces = rNumRule.mbAbsSpaces;
548  mbHidden = rNumRule.mbHidden;
549  mnPoolFormatId = rNumRule.GetPoolFormatId();
550  mnPoolHelpId = rNumRule.GetPoolHelpId();
551  mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
552  }
553  return *this;
554 }
555 
556 void SwNumRule::Reset( const OUString& rName )
557 {
558  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
559  Set( n, nullptr);
560 
562  msName = rName;
563  mbAutoRuleFlag = true;
564  mbInvalidRuleFlag = true;
565  mbContinusNum = false;
566  mbAbsSpaces = false;
567  mbHidden = false;
568  mnPoolFormatId = USHRT_MAX;
569  mnPoolHelpId = USHRT_MAX;
570  mnPoolHlpFileId = UCHAR_MAX;
571 }
572 
573 bool SwNumRule::operator==( const SwNumRule& rRule ) const
574 {
575  bool bRet = meRuleType == rRule.meRuleType &&
576  msName == rRule.msName &&
577  mbAutoRuleFlag == rRule.mbAutoRuleFlag &&
578  mbContinusNum == rRule.mbContinusNum &&
579  mbAbsSpaces == rRule.mbAbsSpaces &&
580  mnPoolFormatId == rRule.GetPoolFormatId() &&
581  mnPoolHelpId == rRule.GetPoolHelpId() &&
583  if( bRet )
584  {
585  for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
586  if( rRule.Get( n ) != Get( n ) )
587  {
588  bRet = false;
589  break;
590  }
591  }
592  return bRet;
593 }
594 
595 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat& rNumFormat )
596 {
597  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
598  if( i < MAXLEVEL )
599  {
600  if( !maFormats[ i ] || (rNumFormat != Get( i )) )
601  {
602  maFormats[ i ].reset(new SwNumFormat( rNumFormat ));
603  mbInvalidRuleFlag = true;
604  }
605  }
606 }
607 
608 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat* pNumFormat )
609 {
610  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
611  if( i >= MAXLEVEL )
612  return;
613  if( !maFormats[ i ] )
614  {
615  if( pNumFormat )
616  {
617  maFormats[ i ].reset(new SwNumFormat( *pNumFormat ));
618  mbInvalidRuleFlag = true;
619  }
620  }
621  else if( !pNumFormat )
622  {
623  maFormats[ i ].reset();
624  mbInvalidRuleFlag = true;
625  }
626  else if( *maFormats[i] != *pNumFormat )
627  {
628  *maFormats[ i ] = *pNumFormat;
629  mbInvalidRuleFlag = true;
630  }
631 }
632 
633 OUString SwNumRule::MakeNumString( const SwNodeNum& rNum, bool bInclStrings ) const
634 {
635  if (rNum.IsCounted())
636  return MakeNumString(rNum.GetNumberVector(), bInclStrings);
637 
638  return OUString();
639 }
640 
642  const bool bInclStrings,
643  const bool bOnlyArabic,
644  const unsigned int _nRestrictToThisLevel,
645  SwNumRule::Extremities* pExtremities,
646  LanguageType nLang ) const
647 {
648  OUStringBuffer aStr;
649 
650  SwNumberTree::tNumberVector::size_type nLevel = rNumVector.size() - 1;
651 
652  if ( pExtremities )
653  pExtremities->nPrefixChars = pExtremities->nSuffixChars = 0;
654 
655  if ( nLevel > _nRestrictToThisLevel )
656  {
657  nLevel = _nRestrictToThisLevel;
658  }
659 
660  if (nLevel < MAXLEVEL)
661  {
662  const SwNumFormat& rMyNFormat = Get( o3tl::narrowing<sal_uInt16>(nLevel) );
663 
664  {
665  css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang));
666 
667  if (rMyNFormat.HasListFormat())
668  {
669  OUString sLevelFormat = rMyNFormat.GetListFormat(bInclStrings);
670 
671  // In this case we are ignoring GetIncludeUpperLevels: we put all
672  // level numbers requested by level format
673  for (SwNumberTree::tNumberVector::size_type i=0; i <= nLevel; ++i)
674  {
675  OUString sReplacement;
676  if (rNumVector[i])
677  {
678  if (bOnlyArabic)
679  sReplacement = OUString::number(rNumVector[i]);
680  else
681  sReplacement = Get(i).GetNumStr(rNumVector[i], aLocale);
682  }
683  else
684  sReplacement = "0"; // all 0 level are a 0
685 
686  OUString sFind("%" + OUString::number(i + 1) + "%");
687  sal_Int32 nPosition = sLevelFormat.indexOf(sFind);
688  if (nPosition >= 0)
689  sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
690  }
691 
692  aStr = sLevelFormat;
693  }
694  else
695  {
696  // Fallback case: level format is not defined
697  // So use old way with levels joining by dot "."
698  SwNumberTree::tNumberVector::size_type i = nLevel;
699 
700  if (!IsContinusNum() &&
701  // - do not include upper levels, if level isn't numbered.
702  rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
703  rMyNFormat.GetIncludeUpperLevels()) // Just the own level?
704  {
705  sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels();
706  if (1 < n)
707  {
708  if (i + 1 >= n)
709  i -= n - 1;
710  else
711  i = 0;
712  }
713  }
714 
715  for (; i <= nLevel; ++i)
716  {
717  const SwNumFormat& rNFormat = Get(i);
718  if (SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType())
719  {
720  // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ??
721  // if( i != rNum.nMyLevel )
722  // aStr += ".";
723  continue;
724  }
725 
726  if (rNumVector[i])
727  {
728  if (bOnlyArabic)
729  aStr.append(rNumVector[i]);
730  else
731  aStr.append(rNFormat.GetNumStr(rNumVector[i], aLocale));
732  }
733  else
734  aStr.append("0"); // all 0 level are a 0
735  if (i != nLevel && !aStr.isEmpty())
736  aStr.append(".");
737  }
738 
739  // The type doesn't have any number, so don't append
740  // the post-/prefix string
741  if (bInclStrings && !bOnlyArabic &&
742  SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() &&
743  SVX_NUM_BITMAP != rMyNFormat.GetNumberingType())
744  {
745  const OUString& sPrefix = rMyNFormat.GetPrefix();
746  const OUString& sSuffix = rMyNFormat.GetSuffix();
747 
748  aStr.insert(0, sPrefix);
749  aStr.append(sSuffix);
750  if (pExtremities)
751  {
752  pExtremities->nPrefixChars = sPrefix.getLength();
753  pExtremities->nSuffixChars = sSuffix.getLength();
754  }
755  }
756  }
757  }
758  }
759 
760  return aStr.makeStringAndClear();
761 }
762 
763 OUString SwNumRule::MakeRefNumString( const SwNodeNum& rNodeNum,
764  const bool bInclSuperiorNumLabels,
765  const int nRestrictInclToThisLevel ) const
766 {
767  OUString aRefNumStr;
768 
769  if ( rNodeNum.GetLevelInListTree() >= 0 )
770  {
771  bool bOldHadPrefix = true;
772 
773  const SwNodeNum* pWorkingNodeNum( &rNodeNum );
774  do
775  {
776  bool bMakeNumStringForPhantom( false );
777  if ( pWorkingNodeNum->IsPhantom() )
778  {
779  int nListLevel = pWorkingNodeNum->GetLevelInListTree();
780 
781  if (nListLevel < 0)
782  nListLevel = 0;
783 
784  if (nListLevel >= MAXLEVEL)
785  nListLevel = MAXLEVEL - 1;
786 
787  SwNumFormat aFormat( Get( o3tl::narrowing<sal_uInt16>(nListLevel) ) );
788  bMakeNumStringForPhantom = aFormat.IsEnumeration() &&
790 
791  }
792  if ( bMakeNumStringForPhantom ||
793  ( !pWorkingNodeNum->IsPhantom() &&
794  pWorkingNodeNum->GetTextNode() &&
795  pWorkingNodeNum->GetTextNode()->HasNumber() ) )
796  {
797  Extremities aExtremities;
798  OUString aPrevStr = MakeNumString( pWorkingNodeNum->GetNumberVector(),
799  true, false, MAXLEVEL,
800  &aExtremities);
801  sal_Int32 nStrip = 0;
802  while ( nStrip < aExtremities.nPrefixChars )
803  {
804  const sal_Unicode c = aPrevStr[nStrip];
805  if ( c!='\t' && c!=' ')
806  break;
807  ++nStrip;
808  }
809 
810  if (nStrip)
811  {
812  aPrevStr = aPrevStr.copy( nStrip );
813  aExtremities.nPrefixChars -= nStrip;
814  }
815 
816  if (bOldHadPrefix &&
817  aExtremities.nSuffixChars &&
818  !aExtremities.nPrefixChars
819  )
820  {
821  aPrevStr = aPrevStr.copy(0,
822  aPrevStr.getLength() - aExtremities.nSuffixChars);
823  }
824 
825  bOldHadPrefix = ( aExtremities.nPrefixChars > 0);
826 
827  aRefNumStr = aPrevStr + aRefNumStr;
828  }
829 
830  if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
831  {
832  sal_uInt8 n = Get( o3tl::narrowing<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
833  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
834  // skip parents, whose list label is already contained in the actual list label.
835  while ( pWorkingNodeNum && n > 1 )
836  {
837  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
838  --n;
839  }
840  }
841  else
842  {
843  break;
844  }
845  } while ( pWorkingNodeNum &&
846  pWorkingNodeNum->GetLevelInListTree() >= 0 &&
847  pWorkingNodeNum->GetLevelInListTree() >= nRestrictInclToThisLevel );
848  }
849 
850  return aRefNumStr;
851 }
852 
854 {
855  OUString aParagraphStyleListString;
856  for (const auto& rParagraphStyle : maParagraphStyleList)
857  {
858  if (!aParagraphStyleListString.isEmpty())
859  aParagraphStyleListString += ", ";
860  aParagraphStyleListString += rParagraphStyle->GetName();
861  }
862  return aParagraphStyleListString;
863 }
864 
871 {
872  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
873  {
874  Set( n, rNumRule.maFormats[ n ].get() );
875  if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() &&
876  !rDoc.GetCharFormats()->ContainsFormat(maFormats[n]->GetCharFormat()))
877  {
878  // If we copy across different Documents, then copy the
879  // corresponding CharFormat into the new Document.
880  maFormats[n]->SetCharFormat( rDoc.CopyCharFormat( *maFormats[n]->
881  GetCharFormat() ) );
882  }
883  }
884  meRuleType = rNumRule.meRuleType;
885  msName = rNumRule.msName;
886  mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
887  mnPoolFormatId = rNumRule.GetPoolFormatId();
888  mnPoolHelpId = rNumRule.GetPoolHelpId();
889  mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
890  mbInvalidRuleFlag = true;
891  return *this;
892 }
893 
894 void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
895 {
896  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
897  {
898  const SvxNumberFormat* pSvxFormat = rNumRule.Get(n);
899  maFormats[n].reset( pSvxFormat ? new SwNumFormat(*pSvxFormat, pDoc) : nullptr );
900  }
901 
902  mbInvalidRuleFlag = true;
904 }
905 
907 {
908  SvxNumRule aRule(SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::CHAR_STYLE |
909  SvxNumRuleFlags::ENABLE_LINKED_BMP | SvxNumRuleFlags::ENABLE_EMBEDDED_BMP,
911  meRuleType == NUM_RULE ? SvxNumRuleType::NUMBERING : SvxNumRuleType::OUTLINE_NUMBERING );
912  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
913  {
914  const SwNumFormat & rNumFormat = Get(n);
915  if(rNumFormat.GetCharFormat())
916  {
917  SwNumFormat aNewFormat = rNumFormat;
918  aNewFormat.SetCharFormatName(rNumFormat.GetCharFormat()->GetName());
919  aRule.SetLevel(n, aNewFormat, maFormats[n] != nullptr);
920  }
921  else
922  aRule.SetLevel(n, rNumFormat, maFormats[n] != nullptr);
923  }
924  return aRule;
925 }
926 
928 {
929  if (bFlag)
930  {
932  for ( const SwTextNode* pTextNode : maTextNodeList )
933  {
934  // #i111681# - applying patch from cmc
935  SwList* pList = pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() );
936  OSL_ENSURE( pList, "<SwNumRule::SetInvalidRule(..)> - list at which the text node is registered at does not exist. This is a serious issue.");
937  if ( pList )
938  {
939  aLists.insert( pList );
940  }
941  }
942  for ( auto aList : aLists )
943  aList->InvalidateListTree();
944  }
945 
946  mbInvalidRuleFlag = bFlag;
947 }
948 
950 void SwNumRule::ChangeIndent( const sal_Int32 nDiff )
951 {
952  for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
953  {
954  SwNumFormat aTmpNumFormat( Get(i) );
955 
956  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
957  aTmpNumFormat.GetPositionAndSpaceMode() );
958  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
959  {
960  auto nNewIndent = nDiff +
961  aTmpNumFormat.GetAbsLSpace();
962  if ( nNewIndent < 0 )
963  {
964  nNewIndent = 0;
965  }
966  aTmpNumFormat.SetAbsLSpace( nNewIndent );
967  }
968  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
969  {
970  // adjust also the list tab position, if a list tab stop is applied
971  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
972  {
973  const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() + nDiff;
974  aTmpNumFormat.SetListtabPos( nNewListTab );
975  }
976 
977  const tools::Long nNewIndent = nDiff +
978  aTmpNumFormat.GetIndentAt();
979  aTmpNumFormat.SetIndentAt( nNewIndent );
980  }
981 
982  Set( i, aTmpNumFormat );
983  }
984 
985  SetInvalidRule( true );
986 }
987 
989 void SwNumRule::SetIndent( const short nNewIndent,
990  const sal_uInt16 nListLevel )
991 {
992  SwNumFormat aTmpNumFormat( Get(nListLevel) );
993 
994  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
995  aTmpNumFormat.GetPositionAndSpaceMode() );
996  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
997  {
998  aTmpNumFormat.SetAbsLSpace( nNewIndent );
999  }
1000  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1001  {
1002  // adjust also the list tab position, if a list tab stop is applied
1003  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
1004  {
1005  const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() +
1006  ( nNewIndent - aTmpNumFormat.GetIndentAt() );
1007  aTmpNumFormat.SetListtabPos( nNewListTab );
1008  }
1009 
1010  aTmpNumFormat.SetIndentAt( nNewIndent );
1011  }
1012 
1013  SetInvalidRule( true );
1014 }
1015 
1019 {
1020  SwNumFormat aTmpNumFormat( Get(0) );
1021 
1022  sal_Int32 nDiff( 0 );
1023  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1024  aTmpNumFormat.GetPositionAndSpaceMode() );
1025  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1026  {
1027  nDiff = nNewIndent
1028  - aTmpNumFormat.GetFirstLineOffset()
1029  - aTmpNumFormat.GetAbsLSpace();
1030  }
1031  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1032  {
1033  nDiff = nNewIndent - aTmpNumFormat.GetIndentAt();
1034  }
1035  if ( nDiff != 0 )
1036  {
1037  ChangeIndent( nDiff );
1038  }
1039 }
1040 
1041 void SwNumRule::Validate(const SwDoc& rDoc)
1042 {
1044  for ( const SwTextNode* pTextNode : maTextNodeList )
1045  {
1046  aLists.insert( pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() ) );
1047  }
1048  for ( auto aList : aLists )
1049  aList->ValidateListTree(rDoc);
1050 
1051  SetInvalidRule(false);
1052 }
1053 
1054 void SwNumRule::SetCountPhantoms(bool bCountPhantoms)
1055 {
1056  mbCountPhantoms = bCountPhantoms;
1057 }
1058 
1059 SwNumRule::tParagraphStyleList::size_type SwNumRule::GetParagraphStyleListSize() const
1060 {
1061  return maParagraphStyleList.size();
1062 }
1063 
1065 {
1066  tParagraphStyleList::iterator aIter =
1067  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1068 
1069  if ( aIter == maParagraphStyleList.end() )
1070  {
1071  maParagraphStyleList.push_back( &rTextFormatColl );
1072  }
1073 }
1074 
1076 {
1077  tParagraphStyleList::iterator aIter =
1078  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1079 
1080  if ( aIter != maParagraphStyleList.end() )
1081  {
1082  maParagraphStyleList.erase( aIter );
1083  }
1084 }
1085 
1087 {
1088  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRule"));
1089  (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("msName"), BAD_CAST(msName.toUtf8().getStr()));
1090  (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mnPoolFormatId"), BAD_CAST(OString::number(mnPoolFormatId).getStr()));
1091  (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mbAutoRuleFlag"), BAD_CAST(OString::boolean(mbAutoRuleFlag).getStr()));
1092 
1093  for (const auto& pFormat : maFormats)
1094  {
1095  if (!pFormat)
1096  {
1097  continue;
1098  }
1099 
1100  pFormat->dumpAsXml(pWriter);
1101  }
1102 
1103  (void)xmlTextWriterEndElement(pWriter);
1104 }
1105 
1107 {
1108  if (mpGrabBagItem)
1109  mpGrabBagItem->QueryValue(rVal);
1110  else
1111  rVal <<= uno::Sequence<beans::PropertyValue>();
1112 }
1113 
1115 {
1116  if (!mpGrabBagItem)
1117  mpGrabBagItem = std::make_shared<SfxGrabBagItem>();
1118 
1119  mpGrabBagItem->PutValue(rVal, 0);
1120 }
1121 
1122 namespace numfunc
1123 {
1124  namespace {
1125 
1127  class SwDefBulletConfig : private utl::ConfigItem
1128  {
1129  public:
1130  static SwDefBulletConfig& getInstance();
1131 
1132  const OUString& GetFontname() const
1133  {
1134  return msFontname;
1135  }
1136 
1137  bool IsFontnameUserDefined() const
1138  {
1139  return mbUserDefinedFontname;
1140  }
1141 
1142  const vcl::Font& GetFont() const
1143  {
1144  return *mpFont;
1145  }
1146 
1147  sal_Unicode GetChar( sal_uInt8 p_nListLevel ) const
1148  {
1149  if (p_nListLevel >= MAXLEVEL)
1150  {
1151  p_nListLevel = MAXLEVEL - 1;
1152  }
1153 
1154  return mnLevelChars[p_nListLevel];
1155  }
1156 
1157  SwDefBulletConfig();
1158 
1159  private:
1161  void SetToDefault();
1162 
1164  static uno::Sequence<OUString> GetPropNames();
1165 
1168  void LoadConfig();
1169 
1171  void InitFont();
1172 
1174  virtual void Notify( const uno::Sequence<OUString>& aPropertyNames ) override;
1175  virtual void ImplCommit() override;
1176 
1177  // default bullet list configuration data
1178  OUString msFontname;
1183 
1184  // default bullet list font instance
1185  std::unique_ptr<vcl::Font> mpFont;
1186  };
1187 
1188  }
1189 
1190  SwDefBulletConfig& SwDefBulletConfig::getInstance()
1191  {
1192  static SwDefBulletConfig theSwDefBulletConfig;
1193  return theSwDefBulletConfig;
1194  }
1195 
1196  SwDefBulletConfig::SwDefBulletConfig()
1197  : ConfigItem( "Office.Writer/Numbering/DefaultBulletList" ),
1198  // default bullet font is now OpenSymbol
1199  msFontname( OUString("OpenSymbol") ),
1200  mbUserDefinedFontname( false ),
1203  {
1204  SetToDefault();
1205  LoadConfig();
1206  InitFont();
1207 
1208  // enable notification for changes on default bullet configuration change
1209  EnableNotification( GetPropNames() );
1210  }
1211 
1212  void SwDefBulletConfig::SetToDefault()
1213  {
1214  msFontname = "OpenSymbol";
1215  mbUserDefinedFontname = false;
1218 
1219  mnLevelChars[0] = 0x2022;
1220  mnLevelChars[1] = 0x25e6;
1221  mnLevelChars[2] = 0x25aa;
1222  mnLevelChars[3] = 0x2022;
1223  mnLevelChars[4] = 0x25e6;
1224  mnLevelChars[5] = 0x25aa;
1225  mnLevelChars[6] = 0x2022;
1226  mnLevelChars[7] = 0x25e6;
1227  mnLevelChars[8] = 0x25aa;
1228  mnLevelChars[9] = 0x2022;
1229  }
1230 
1231  uno::Sequence<OUString> SwDefBulletConfig::GetPropNames()
1232  {
1233  uno::Sequence<OUString> aPropNames(13);
1234  OUString* pNames = aPropNames.getArray();
1235  pNames[0] = "BulletFont/FontFamilyname";
1236  pNames[1] = "BulletFont/FontWeight";
1237  pNames[2] = "BulletFont/FontItalic";
1238  pNames[3] = "BulletCharLvl1";
1239  pNames[4] = "BulletCharLvl2";
1240  pNames[5] = "BulletCharLvl3";
1241  pNames[6] = "BulletCharLvl4";
1242  pNames[7] = "BulletCharLvl5";
1243  pNames[8] = "BulletCharLvl6";
1244  pNames[9] = "BulletCharLvl7";
1245  pNames[10] = "BulletCharLvl8";
1246  pNames[11] = "BulletCharLvl9";
1247  pNames[12] = "BulletCharLvl10";
1248 
1249  return aPropNames;
1250  }
1251 
1252  void SwDefBulletConfig::LoadConfig()
1253  {
1254  uno::Sequence<OUString> aPropNames = GetPropNames();
1255  uno::Sequence<uno::Any> aValues = GetProperties( aPropNames );
1256  const uno::Any* pValues = aValues.getConstArray();
1257  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1258  "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed");
1259  if ( aValues.getLength() != aPropNames.getLength() )
1260  return;
1261 
1262  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1263  {
1264  if ( pValues[nProp].hasValue() )
1265  {
1266  switch ( nProp )
1267  {
1268  case 0:
1269  {
1270  OUString aStr;
1271  pValues[nProp] >>= aStr;
1272  msFontname = aStr;
1273  mbUserDefinedFontname = true;
1274  }
1275  break;
1276  case 1:
1277  case 2:
1278  {
1279  sal_Int16 nTmp = 0;
1280  pValues[nProp] >>= nTmp;
1281  if ( nProp == 1 )
1282  meFontWeight = static_cast<FontWeight>(nTmp);
1283  else if ( nProp == 2 )
1284  meFontItalic = static_cast<FontItalic>(nTmp);
1285  }
1286  break;
1287  case 3:
1288  case 4:
1289  case 5:
1290  case 6:
1291  case 7:
1292  case 8:
1293  case 9:
1294  case 10:
1295  case 11:
1296  case 12:
1297  {
1298  sal_Unicode cChar = sal_Unicode();
1299  pValues[nProp] >>= cChar;
1300  mnLevelChars[nProp-3] = cChar;
1301  }
1302  break;
1303  }
1304  }
1305  }
1306 
1307  }
1308 
1309  void SwDefBulletConfig::InitFont()
1310  {
1311  mpFont.reset( new vcl::Font( msFontname, OUString(), Size( 0, 14 ) ) );
1312  mpFont->SetWeight( meFontWeight );
1313  mpFont->SetItalic( meFontItalic );
1314  mpFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
1315  }
1316 
1317  void SwDefBulletConfig::Notify( const uno::Sequence<OUString>& )
1318  {
1319  SetToDefault();
1320  LoadConfig();
1321  InitFont();
1322  }
1323 
1324  void SwDefBulletConfig::ImplCommit()
1325  {
1326  }
1327 
1328  OUString const & GetDefBulletFontname()
1329  {
1330  return SwDefBulletConfig::getInstance().GetFontname();
1331  }
1332 
1334  {
1335  return SwDefBulletConfig::getInstance().IsFontnameUserDefined();
1336  }
1337 
1339  {
1340  return SwDefBulletConfig::getInstance().GetFont();
1341  }
1342 
1344  {
1345  return SwDefBulletConfig::getInstance().GetChar( nLevel );
1346  }
1347 
1348  namespace {
1349 
1355  class SwNumberingUIBehaviorConfig : private utl::ConfigItem
1356  {
1357  public:
1358  static SwNumberingUIBehaviorConfig& getInstance();
1359 
1361  {
1363  }
1364 
1365  SwNumberingUIBehaviorConfig();
1366 
1367  private:
1368 
1370  void SetToDefault();
1371 
1373  static css::uno::Sequence<OUString> GetPropNames();
1374 
1376  void LoadConfig();
1377 
1379  virtual void Notify( const css::uno::Sequence<OUString>& aPropertyNames ) override;
1380  virtual void ImplCommit() override;
1381 
1382  // configuration data
1384  };
1385 
1386  }
1387 
1388  SwNumberingUIBehaviorConfig& SwNumberingUIBehaviorConfig::getInstance()
1389  {
1390  static SwNumberingUIBehaviorConfig theSwNumberingUIBehaviorConfig;
1391  return theSwNumberingUIBehaviorConfig;
1392  }
1393 
1394  SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1395  : ConfigItem( "Office.Writer/Numbering/UserInterfaceBehavior" ),
1397  {
1398  SetToDefault();
1399  LoadConfig();
1400 
1401  // enable notification for changes on configuration change
1402  EnableNotification( GetPropNames() );
1403  }
1404 
1405  void SwNumberingUIBehaviorConfig::SetToDefault()
1406  {
1408  }
1409 
1410  css::uno::Sequence<OUString> SwNumberingUIBehaviorConfig::GetPropNames()
1411  {
1412  css::uno::Sequence<OUString> aPropNames { "ChangeIndentOnTabAtFirstPosOfFirstListItem" };
1413 
1414  return aPropNames;
1415  }
1416 
1417  void SwNumberingUIBehaviorConfig::ImplCommit() {}
1418 
1419  void SwNumberingUIBehaviorConfig::LoadConfig()
1420  {
1421  css::uno::Sequence<OUString> aPropNames = GetPropNames();
1422  css::uno::Sequence<css::uno::Any> aValues = GetProperties( aPropNames );
1423  const css::uno::Any* pValues = aValues.getConstArray();
1424  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1425  "<SwNumberingUIBehaviorConfig::LoadConfig()> - GetProperties failed");
1426  if ( aValues.getLength() != aPropNames.getLength() )
1427  return;
1428 
1429  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1430  {
1431  if ( pValues[nProp].hasValue() )
1432  {
1433  switch ( nProp )
1434  {
1435  case 0:
1436  {
1438  }
1439  break;
1440  default:
1441  {
1442  OSL_FAIL( "<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property");
1443  }
1444  }
1445  }
1446  }
1447  }
1448 
1449  void SwNumberingUIBehaviorConfig::Notify( const css::uno::Sequence<OUString>& )
1450  {
1451  SetToDefault();
1452  LoadConfig();
1453  }
1454 
1456  {
1457  return SwNumberingUIBehaviorConfig::getInstance().ChangeIndentOnTabAtFirstPosOfFirstListItem();
1458  }
1459 
1460  bool NumDownChangesIndent(const SwWrtShell& rShell)
1461  {
1462  SwPaM* pCursor = rShell.GetCursor();
1463  if (!pCursor)
1464  {
1465  return true;
1466  }
1467 
1468  SwTextNode* pTextNode = pCursor->GetNode().GetTextNode();
1469  if (!pTextNode)
1470  {
1471  return true;
1472  }
1473 
1474  const SwNumRule* pNumRule = pTextNode->GetNumRule();
1475  if (!pNumRule)
1476  {
1477  return true;
1478  }
1479 
1480  int nOldLevel = pTextNode->GetActualListLevel();
1481  int nNewLevel = nOldLevel + 1;
1482  if (nNewLevel >= MAXLEVEL)
1483  {
1484  return true;
1485  }
1486 
1487  const SwNumFormat& rOldFormat = pNumRule->Get(nOldLevel);
1488  if (rOldFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1489  {
1490  return true;
1491  }
1492 
1493  const SwNumFormat& rNewFormat = pNumRule->Get(nNewLevel);
1494  if (rNewFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1495  {
1496  return true;
1497  }
1498 
1499  // This is the case when the numbering levels don't differ, so changing between them is not
1500  // a better alternative to inserting a tab character.
1501  return rOldFormat.GetIndentAt() != rNewFormat.GetIndentAt();
1502  }
1503 
1505  {
1508 
1510  switch (GetODFSaneDefaultVersion())
1511  {
1514  {
1515  ePosAndSpaceMode = SvxNumberFormat::LABEL_WIDTH_AND_POSITION;
1516  }
1517  break;
1518  default: // >= ODFSVER_012
1519  {
1520  ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1521  }
1522  }
1523 
1524  return ePosAndSpaceMode;
1525  }
1526 }
1527 
1529 {
1530  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRuleTable"));
1531  for (SwNumRule* pNumRule : *this)
1532  pNumRule->dumpAsXml(pWriter);
1533  (void)xmlTextWriterEndElement(pWriter);
1534 }
1535 
1536 /* 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:1064
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:102
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:195
OUString MakeRefNumString(const SwNodeNum &rNodeNum, const bool bInclSuperiorNumLabels, const int nRestrictInclToThisLevel) const
Definition: number.cxx:763
constexpr short lNumberFirstLineOffset
Definition: swtypes.hxx:101
OUString MakeNumString(const SwNodeNum &, bool bInclStrings=true) const
Definition: number.cxx:633
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:3191
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
Definition: docfmt.cxx:843
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:1178
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:853
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:1106
FontWeight meFontWeight
Definition: number.cxx:1180
Definition: doc.hxx:188
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
void RemoveParagraphStyle(SwTextFormatColl &rTextFormatColl)
Definition: number.cxx:1075
OUString msName
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:90
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:573
void Validate(const SwDoc &rDoc)
Definition: number.cxx:1041
void SetIncludeUpperLevels(sal_uInt8 nSet)
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3071
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: number.cxx:1528
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:4087
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:1114
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:1343
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:1181
sal_Unicode mnLevelChars[MAXLEVEL]
Definition: number.cxx:1182
SvxNumRule MakeSvxNumRule() const
Definition: number.cxx:906
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:1383
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:100
void Reset(const OUString &rName)
Definition: number.cxx:556
void CheckCharFormats(SwDoc &rDoc)
Tests whether the CharFormats are from the given doc and copies them if appropriate.
Definition: number.cxx:517
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:1338
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:2798
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:1054
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:989
void SetCharTextDistance(short nSet)
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
void dumpAsXml(xmlTextWriterPtr w) const
Definition: number.cxx:1086
SwNumRule::tParagraphStyleList::size_type GetParagraphStyleListSize() const
Definition: number.cxx:1059
std::unique_ptr< vcl::Font > mpFont
Definition: number.cxx:1185
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:950
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:608
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
const Size & GetGraphicSize() const
void SetInvalidRule(bool bFlag)
Definition: number.cxx:927
const SwCharFormats * GetCharFormats() const
Definition: doc.hxx:740
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1504
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
Definition: number.cxx:1333
unsigned char sal_uInt8
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
Definition: number.cxx:1328
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
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:894
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:159
~SwNumRule()
Definition: number.cxx:471
SwNumRule & operator=(const SwNumRule &)
Definition: number.cxx:535
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:1460
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:2838
bool mbUserDefinedFontname
Definition: number.cxx:1179
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:1018
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
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:1455
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:850
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:870
namespace for static functions and methods for numbering and bullets
Definition: number.cxx:1122
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo
bool ContainsFormat(SwCharFormat *pFormat) const
fast check if given format is contained here pFormat must not have been deleted
Definition: chrfmt.cxx:98