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  auto pLegacy = dynamic_cast<const sw::LegacyModifyHint*>(&rHint);
284  if(!pLegacy)
285  return;
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->SetSuffix( "." );
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->SetSuffix( "." );
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 bool SwNumRule::operator==( const SwNumRule& rRule ) const
557 {
558  bool bRet = meRuleType == rRule.meRuleType &&
559  msName == rRule.msName &&
560  mbAutoRuleFlag == rRule.mbAutoRuleFlag &&
561  mbContinusNum == rRule.mbContinusNum &&
562  mbAbsSpaces == rRule.mbAbsSpaces &&
563  mnPoolFormatId == rRule.GetPoolFormatId() &&
564  mnPoolHelpId == rRule.GetPoolHelpId() &&
566  if( bRet )
567  {
568  for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
569  if( rRule.Get( n ) != Get( n ) )
570  {
571  bRet = false;
572  break;
573  }
574  }
575  return bRet;
576 }
577 
578 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat& rNumFormat )
579 {
580  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
581  if( i < MAXLEVEL )
582  {
583  if( !maFormats[ i ] || (rNumFormat != Get( i )) )
584  {
585  maFormats[ i ].reset(new SwNumFormat( rNumFormat ));
586  mbInvalidRuleFlag = true;
587  }
588  }
589 }
590 
591 void SwNumRule::Set( sal_uInt16 i, const SwNumFormat* pNumFormat )
592 {
593  OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
594  if( i >= MAXLEVEL )
595  return;
596  if( !maFormats[ i ] )
597  {
598  if( pNumFormat )
599  {
600  maFormats[ i ].reset(new SwNumFormat( *pNumFormat ));
601  mbInvalidRuleFlag = true;
602  }
603  }
604  else if( !pNumFormat )
605  {
606  maFormats[ i ].reset();
607  mbInvalidRuleFlag = true;
608  }
609  else if( *maFormats[i] != *pNumFormat )
610  {
611  *maFormats[ i ] = *pNumFormat;
612  mbInvalidRuleFlag = true;
613  }
614 }
615 
616 OUString SwNumRule::MakeNumString( const SwNodeNum& rNum, bool bInclStrings ) const
617 {
618  if (rNum.IsCounted())
619  return MakeNumString(rNum.GetNumberVector(), bInclStrings);
620 
621  return OUString();
622 }
623 
625  const bool bInclStrings,
626  const bool bOnlyArabic,
627  const unsigned int _nRestrictToThisLevel,
628  SwNumRule::Extremities* pExtremities,
629  LanguageType nLang ) const
630 {
631  OUStringBuffer aStr;
632 
633  SwNumberTree::tNumberVector::size_type nLevel = rNumVector.size() - 1;
634 
635  if ( pExtremities )
636  pExtremities->nPrefixChars = pExtremities->nSuffixChars = 0;
637 
638  if ( nLevel > _nRestrictToThisLevel )
639  {
640  nLevel = _nRestrictToThisLevel;
641  }
642 
643  if (nLevel < MAXLEVEL)
644  {
645  const SwNumFormat& rMyNFormat = Get( static_cast<sal_uInt16>(nLevel) );
646 
647  {
648  css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang));
649 
650  if (rMyNFormat.HasListFormat())
651  {
652  OUString sLevelFormat = rMyNFormat.GetListFormat();
653  // In this case we are ignoring GetIncludeUpperLevels: we put all
654  // level numbers requested by level format
655  for (SwNumberTree::tNumberVector::size_type i=0; i <= nLevel; ++i)
656  {
657  OUString sReplacement;
658  if (rNumVector[i])
659  {
660  if (bOnlyArabic)
661  sReplacement = OUString::number(rNumVector[i]);
662  else
663  sReplacement = Get(i).GetNumStr(rNumVector[i], aLocale);
664  }
665  else
666  sReplacement = "0"; // all 0 level are a 0
667 
668  OUString sFind("%" + OUString::number(i + 1));
669  sal_Int32 nPosition = sLevelFormat.indexOf(sFind);
670  if (nPosition >= 0)
671  sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
672  }
673 
674  // As a fallback: caller code expects nonempty string as a result.
675  // But if we have empty string (and had no errors before) this is valid result.
676  // So use classical hack with zero-width-space as a string filling.
677  if (sLevelFormat.isEmpty())
678  sLevelFormat = OUStringChar(CHAR_ZWSP);
679 
680  aStr = sLevelFormat;
681  }
682  else
683  {
684  // Fallback case: level format is not defined
685  // So use old way with levels joining by dot "."
686  SwNumberTree::tNumberVector::size_type i = nLevel;
687 
688  if (!IsContinusNum() &&
689  // - do not include upper levels, if level isn't numbered.
690  rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
691  rMyNFormat.GetIncludeUpperLevels()) // Just the own level?
692  {
693  sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels();
694  if (1 < n)
695  {
696  if (i + 1 >= n)
697  i -= n - 1;
698  else
699  i = 0;
700  }
701  }
702 
703  for (; i <= nLevel; ++i)
704  {
705  const SwNumFormat& rNFormat = Get(i);
706  if (SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType())
707  {
708  // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ??
709  // if( i != rNum.nMyLevel )
710  // aStr += ".";
711  continue;
712  }
713 
714  if (rNumVector[i])
715  {
716  if (bOnlyArabic)
717  aStr.append(OUString::number(rNumVector[i]));
718  else
719  aStr.append(rNFormat.GetNumStr(rNumVector[i], aLocale));
720  }
721  else
722  aStr.append("0"); // all 0 level are a 0
723  if (i != nLevel && !aStr.isEmpty())
724  aStr.append(".");
725  }
726 
727  // The type doesn't have any number, so don't append
728  // the post-/prefix string
729  if (bInclStrings && !bOnlyArabic &&
730  SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() &&
731  SVX_NUM_BITMAP != rMyNFormat.GetNumberingType())
732  {
733  const OUString& sPrefix = rMyNFormat.GetPrefix();
734  const OUString& sSuffix = rMyNFormat.GetSuffix();
735 
736  aStr.insert(0, sPrefix);
737  aStr.append(sSuffix);
738  if (pExtremities)
739  {
740  pExtremities->nPrefixChars = sPrefix.getLength();
741  pExtremities->nSuffixChars = sSuffix.getLength();
742  }
743  }
744  }
745  }
746  }
747 
748  return aStr.makeStringAndClear();
749 }
750 
751 OUString SwNumRule::MakeRefNumString( const SwNodeNum& rNodeNum,
752  const bool bInclSuperiorNumLabels,
753  const int nRestrictInclToThisLevel ) const
754 {
755  OUString aRefNumStr;
756 
757  if ( rNodeNum.GetLevelInListTree() >= 0 )
758  {
759  bool bOldHadPrefix = true;
760 
761  const SwNodeNum* pWorkingNodeNum( &rNodeNum );
762  do
763  {
764  bool bMakeNumStringForPhantom( false );
765  if ( pWorkingNodeNum->IsPhantom() )
766  {
767  int nListLevel = pWorkingNodeNum->GetLevelInListTree();
768 
769  if (nListLevel < 0)
770  nListLevel = 0;
771 
772  if (nListLevel >= MAXLEVEL)
773  nListLevel = MAXLEVEL - 1;
774 
775  SwNumFormat aFormat( Get( static_cast<sal_uInt16>(nListLevel) ) );
776  bMakeNumStringForPhantom = aFormat.IsEnumeration() &&
778 
779  }
780  if ( bMakeNumStringForPhantom ||
781  ( !pWorkingNodeNum->IsPhantom() &&
782  pWorkingNodeNum->GetTextNode() &&
783  pWorkingNodeNum->GetTextNode()->HasNumber() ) )
784  {
785  Extremities aExtremities;
786  OUString aPrevStr = MakeNumString( pWorkingNodeNum->GetNumberVector(),
787  true, false, MAXLEVEL,
788  &aExtremities);
789  sal_Int32 nStrip = 0;
790  while ( nStrip < aExtremities.nPrefixChars )
791  {
792  const sal_Unicode c = aPrevStr[nStrip];
793  if ( c!='\t' && c!=' ')
794  break;
795  ++nStrip;
796  }
797 
798  if (nStrip)
799  {
800  aPrevStr = aPrevStr.copy( nStrip );
801  aExtremities.nPrefixChars -= nStrip;
802  }
803 
804  if (bOldHadPrefix &&
805  aExtremities.nSuffixChars &&
806  !aExtremities.nPrefixChars
807  )
808  {
809  aPrevStr = aPrevStr.copy(0,
810  aPrevStr.getLength() - aExtremities.nSuffixChars);
811  }
812 
813  bOldHadPrefix = ( aExtremities.nPrefixChars > 0);
814 
815  aRefNumStr = aPrevStr + aRefNumStr;
816  }
817 
818  if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
819  {
820  sal_uInt8 n = Get( static_cast<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
821  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
822  // skip parents, whose list label is already contained in the actual list label.
823  while ( pWorkingNodeNum && n > 1 )
824  {
825  pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
826  --n;
827  }
828  }
829  else
830  {
831  break;
832  }
833  } while ( pWorkingNodeNum &&
834  pWorkingNodeNum->GetLevelInListTree() >= 0 &&
835  pWorkingNodeNum->GetLevelInListTree() >= nRestrictInclToThisLevel );
836  }
837 
838  return aRefNumStr;
839 }
840 
842 {
843  OUString aParagraphStyleListString;
844  for (const auto& rParagraphStyle : maParagraphStyleList)
845  {
846  if (!aParagraphStyleListString.isEmpty())
847  aParagraphStyleListString += ", ";
848  aParagraphStyleListString += rParagraphStyle->GetName();
849  }
850  return aParagraphStyleListString;
851 }
852 
859 {
860  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
861  {
862  Set( n, rNumRule.maFormats[ n ].get() );
863  if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() &&
864  !rDoc.GetCharFormats()->IsAlive(maFormats[n]->GetCharFormat()))
865  {
866  // If we copy across different Documents, then copy the
867  // corresponding CharFormat into the new Document.
868  maFormats[n]->SetCharFormat( rDoc.CopyCharFormat( *maFormats[n]->
869  GetCharFormat() ) );
870  }
871  }
872  meRuleType = rNumRule.meRuleType;
873  msName = rNumRule.msName;
874  mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
875  mnPoolFormatId = rNumRule.GetPoolFormatId();
876  mnPoolHelpId = rNumRule.GetPoolHelpId();
877  mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
878  mbInvalidRuleFlag = true;
879  return *this;
880 }
881 
882 void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
883 {
884  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
885  {
886  const SvxNumberFormat* pSvxFormat = rNumRule.Get(n);
887  maFormats[n].reset( pSvxFormat ? new SwNumFormat(*pSvxFormat, pDoc) : nullptr );
888  }
889 
890  mbInvalidRuleFlag = true;
892 }
893 
895 {
896  SvxNumRule aRule(SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::CHAR_STYLE |
897  SvxNumRuleFlags::ENABLE_LINKED_BMP | SvxNumRuleFlags::ENABLE_EMBEDDED_BMP,
899  meRuleType == NUM_RULE ? SvxNumRuleType::NUMBERING : SvxNumRuleType::OUTLINE_NUMBERING );
900  for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
901  {
902  SwNumFormat aNumFormat = Get(n);
903  if(aNumFormat.GetCharFormat())
904  aNumFormat.SetCharFormatName(aNumFormat.GetCharFormat()->GetName());
905  aRule.SetLevel(n, aNumFormat, maFormats[n] != nullptr);
906  }
907  return aRule;
908 }
909 
911 {
912  if (bFlag)
913  {
915  for ( const SwTextNode* pTextNode : maTextNodeList )
916  {
917  // #i111681# - applying patch from cmc
918  SwList* pList = pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() );
919  OSL_ENSURE( pList, "<SwNumRule::SetInvalidRule(..)> - list at which the text node is registered at does not exist. This is a serious issue.");
920  if ( pList )
921  {
922  aLists.insert( pList );
923  }
924  }
925  for ( auto aList : aLists )
926  aList->InvalidateListTree();
927  }
928 
929  mbInvalidRuleFlag = bFlag;
930 }
931 
933 void SwNumRule::ChangeIndent( const sal_Int32 nDiff )
934 {
935  for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
936  {
937  SwNumFormat aTmpNumFormat( Get(i) );
938 
939  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
940  aTmpNumFormat.GetPositionAndSpaceMode() );
941  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
942  {
943  auto nNewIndent = nDiff +
944  aTmpNumFormat.GetAbsLSpace();
945  if ( nNewIndent < 0 )
946  {
947  nNewIndent = 0;
948  }
949  aTmpNumFormat.SetAbsLSpace( nNewIndent );
950  }
951  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
952  {
953  // adjust also the list tab position, if a list tab stop is applied
954  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
955  {
956  const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() + nDiff;
957  aTmpNumFormat.SetListtabPos( nNewListTab );
958  }
959 
960  const tools::Long nNewIndent = nDiff +
961  aTmpNumFormat.GetIndentAt();
962  aTmpNumFormat.SetIndentAt( nNewIndent );
963  }
964 
965  Set( i, aTmpNumFormat );
966  }
967 
968  SetInvalidRule( true );
969 }
970 
972 void SwNumRule::SetIndent( const short nNewIndent,
973  const sal_uInt16 nListLevel )
974 {
975  SwNumFormat aTmpNumFormat( Get(nListLevel) );
976 
977  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
978  aTmpNumFormat.GetPositionAndSpaceMode() );
979  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
980  {
981  aTmpNumFormat.SetAbsLSpace( nNewIndent );
982  }
983  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
984  {
985  // adjust also the list tab position, if a list tab stop is applied
986  if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
987  {
988  const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() +
989  ( nNewIndent - aTmpNumFormat.GetIndentAt() );
990  aTmpNumFormat.SetListtabPos( nNewListTab );
991  }
992 
993  aTmpNumFormat.SetIndentAt( nNewIndent );
994  }
995 
996  SetInvalidRule( true );
997 }
998 
1002 {
1003  SwNumFormat aTmpNumFormat( Get(0) );
1004 
1005  sal_Int32 nDiff( 0 );
1006  const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1007  aTmpNumFormat.GetPositionAndSpaceMode() );
1008  if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1009  {
1010  nDiff = nNewIndent
1011  - aTmpNumFormat.GetFirstLineOffset()
1012  - aTmpNumFormat.GetAbsLSpace();
1013  }
1014  else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1015  {
1016  nDiff = nNewIndent - aTmpNumFormat.GetIndentAt();
1017  }
1018  if ( nDiff != 0 )
1019  {
1020  ChangeIndent( nDiff );
1021  }
1022 }
1023 
1025 {
1027  for ( const SwTextNode* pTextNode : maTextNodeList )
1028  {
1029  aLists.insert( pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() ) );
1030  }
1031  for ( auto aList : aLists )
1032  aList->ValidateListTree();
1033 
1034  SetInvalidRule(false);
1035 }
1036 
1037 void SwNumRule::SetCountPhantoms(bool bCountPhantoms)
1038 {
1039  mbCountPhantoms = bCountPhantoms;
1040 }
1041 
1042 SwNumRule::tParagraphStyleList::size_type SwNumRule::GetParagraphStyleListSize() const
1043 {
1044  return maParagraphStyleList.size();
1045 }
1046 
1048 {
1049  tParagraphStyleList::iterator aIter =
1050  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1051 
1052  if ( aIter == maParagraphStyleList.end() )
1053  {
1054  maParagraphStyleList.push_back( &rTextFormatColl );
1055  }
1056 }
1057 
1059 {
1060  tParagraphStyleList::iterator aIter =
1061  std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1062 
1063  if ( aIter != maParagraphStyleList.end() )
1064  {
1065  maParagraphStyleList.erase( aIter );
1066  }
1067 }
1068 
1070 {
1071  xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRule"));
1072  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("msName"), BAD_CAST(msName.toUtf8().getStr()));
1073  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mnPoolFormatId"), BAD_CAST(OString::number(mnPoolFormatId).getStr()));
1074  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mbAutoRuleFlag"), BAD_CAST(OString::boolean(mbAutoRuleFlag).getStr()));
1075 
1076  for (const auto& pFormat : maFormats)
1077  {
1078  if (!pFormat)
1079  {
1080  continue;
1081  }
1082 
1083  pFormat->dumpAsXml(pWriter);
1084  }
1085 
1086  xmlTextWriterEndElement(pWriter);
1087 }
1088 
1090 {
1091  if (mpGrabBagItem)
1092  mpGrabBagItem->QueryValue(rVal);
1093  else
1094  rVal <<= uno::Sequence<beans::PropertyValue>();
1095 }
1096 
1098 {
1099  if (!mpGrabBagItem)
1100  mpGrabBagItem = std::make_shared<SfxGrabBagItem>();
1101 
1102  mpGrabBagItem->PutValue(rVal, 0);
1103 }
1104 
1105 namespace numfunc
1106 {
1107  namespace {
1108 
1110  class SwDefBulletConfig : private utl::ConfigItem
1111  {
1112  public:
1113  static SwDefBulletConfig& getInstance();
1114 
1115  const OUString& GetFontname() const
1116  {
1117  return msFontname;
1118  }
1119 
1120  bool IsFontnameUserDefined() const
1121  {
1122  return mbUserDefinedFontname;
1123  }
1124 
1125  const vcl::Font& GetFont() const
1126  {
1127  return *mpFont;
1128  }
1129 
1130  sal_Unicode GetChar( sal_uInt8 p_nListLevel ) const
1131  {
1132  if (p_nListLevel >= MAXLEVEL)
1133  {
1134  p_nListLevel = MAXLEVEL - 1;
1135  }
1136 
1137  return mnLevelChars[p_nListLevel];
1138  }
1139 
1140  SwDefBulletConfig();
1141 
1142  private:
1144  void SetToDefault();
1145 
1147  static uno::Sequence<OUString> GetPropNames();
1148 
1151  void LoadConfig();
1152 
1154  void InitFont();
1155 
1157  virtual void Notify( const uno::Sequence<OUString>& aPropertyNames ) override;
1158  virtual void ImplCommit() override;
1159 
1160  // default bullet list configuration data
1161  OUString msFontname;
1166 
1167  // default bullet list font instance
1168  std::unique_ptr<vcl::Font> mpFont;
1169  };
1170 
1171  class theSwDefBulletConfig
1172  : public rtl::Static<SwDefBulletConfig, theSwDefBulletConfig>{};
1173  }
1174 
1175  SwDefBulletConfig& SwDefBulletConfig::getInstance()
1176  {
1177  return theSwDefBulletConfig::get();
1178  }
1179 
1180  SwDefBulletConfig::SwDefBulletConfig()
1181  : ConfigItem( "Office.Writer/Numbering/DefaultBulletList" ),
1182  // default bullet font is now OpenSymbol
1183  msFontname( OUString("OpenSymbol") ),
1184  mbUserDefinedFontname( false ),
1187  {
1188  SetToDefault();
1189  LoadConfig();
1190  InitFont();
1191 
1192  // enable notification for changes on default bullet configuration change
1193  EnableNotification( GetPropNames() );
1194  }
1195 
1196  void SwDefBulletConfig::SetToDefault()
1197  {
1198  msFontname = "OpenSymbol";
1199  mbUserDefinedFontname = false;
1202 
1203  mnLevelChars[0] = 0x2022;
1204  mnLevelChars[1] = 0x25e6;
1205  mnLevelChars[2] = 0x25aa;
1206  mnLevelChars[3] = 0x2022;
1207  mnLevelChars[4] = 0x25e6;
1208  mnLevelChars[5] = 0x25aa;
1209  mnLevelChars[6] = 0x2022;
1210  mnLevelChars[7] = 0x25e6;
1211  mnLevelChars[8] = 0x25aa;
1212  mnLevelChars[9] = 0x2022;
1213  }
1214 
1215  uno::Sequence<OUString> SwDefBulletConfig::GetPropNames()
1216  {
1217  uno::Sequence<OUString> aPropNames(13);
1218  OUString* pNames = aPropNames.getArray();
1219  pNames[0] = "BulletFont/FontFamilyname";
1220  pNames[1] = "BulletFont/FontWeight";
1221  pNames[2] = "BulletFont/FontItalic";
1222  pNames[3] = "BulletCharLvl1";
1223  pNames[4] = "BulletCharLvl2";
1224  pNames[5] = "BulletCharLvl3";
1225  pNames[6] = "BulletCharLvl4";
1226  pNames[7] = "BulletCharLvl5";
1227  pNames[8] = "BulletCharLvl6";
1228  pNames[9] = "BulletCharLvl7";
1229  pNames[10] = "BulletCharLvl8";
1230  pNames[11] = "BulletCharLvl9";
1231  pNames[12] = "BulletCharLvl10";
1232 
1233  return aPropNames;
1234  }
1235 
1236  void SwDefBulletConfig::LoadConfig()
1237  {
1238  uno::Sequence<OUString> aPropNames = GetPropNames();
1239  uno::Sequence<uno::Any> aValues = GetProperties( aPropNames );
1240  const uno::Any* pValues = aValues.getConstArray();
1241  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1242  "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed");
1243  if ( aValues.getLength() != aPropNames.getLength() )
1244  return;
1245 
1246  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1247  {
1248  if ( pValues[nProp].hasValue() )
1249  {
1250  switch ( nProp )
1251  {
1252  case 0:
1253  {
1254  OUString aStr;
1255  pValues[nProp] >>= aStr;
1256  msFontname = aStr;
1257  mbUserDefinedFontname = true;
1258  }
1259  break;
1260  case 1:
1261  case 2:
1262  {
1263  sal_Int16 nTmp = 0;
1264  pValues[nProp] >>= nTmp;
1265  if ( nProp == 1 )
1266  meFontWeight = static_cast<FontWeight>(nTmp);
1267  else if ( nProp == 2 )
1268  meFontItalic = static_cast<FontItalic>(nTmp);
1269  }
1270  break;
1271  case 3:
1272  case 4:
1273  case 5:
1274  case 6:
1275  case 7:
1276  case 8:
1277  case 9:
1278  case 10:
1279  case 11:
1280  case 12:
1281  {
1282  sal_Unicode cChar = sal_Unicode();
1283  pValues[nProp] >>= cChar;
1284  mnLevelChars[nProp-3] = cChar;
1285  }
1286  break;
1287  }
1288  }
1289  }
1290 
1291  }
1292 
1293  void SwDefBulletConfig::InitFont()
1294  {
1295  mpFont.reset( new vcl::Font( msFontname, OUString(), Size( 0, 14 ) ) );
1296  mpFont->SetWeight( meFontWeight );
1297  mpFont->SetItalic( meFontItalic );
1298  mpFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
1299  }
1300 
1301  void SwDefBulletConfig::Notify( const uno::Sequence<OUString>& )
1302  {
1303  SetToDefault();
1304  LoadConfig();
1305  InitFont();
1306  }
1307 
1308  void SwDefBulletConfig::ImplCommit()
1309  {
1310  }
1311 
1312  OUString const & GetDefBulletFontname()
1313  {
1314  return SwDefBulletConfig::getInstance().GetFontname();
1315  }
1316 
1318  {
1319  return SwDefBulletConfig::getInstance().IsFontnameUserDefined();
1320  }
1321 
1323  {
1324  return SwDefBulletConfig::getInstance().GetFont();
1325  }
1326 
1328  {
1329  return SwDefBulletConfig::getInstance().GetChar( nLevel );
1330  }
1331 
1332  namespace {
1333 
1339  class SwNumberingUIBehaviorConfig : private utl::ConfigItem
1340  {
1341  public:
1342  static SwNumberingUIBehaviorConfig& getInstance();
1343 
1345  {
1347  }
1348 
1349  SwNumberingUIBehaviorConfig();
1350 
1351  private:
1352 
1354  void SetToDefault();
1355 
1357  static css::uno::Sequence<OUString> GetPropNames();
1358 
1360  void LoadConfig();
1361 
1363  virtual void Notify( const css::uno::Sequence<OUString>& aPropertyNames ) override;
1364  virtual void ImplCommit() override;
1365 
1366  // configuration data
1368  };
1369 
1370  class theSwNumberingUIBehaviorConfig : public rtl::Static<SwNumberingUIBehaviorConfig, theSwNumberingUIBehaviorConfig>{};
1371  }
1372 
1373  SwNumberingUIBehaviorConfig& SwNumberingUIBehaviorConfig::getInstance()
1374  {
1376  }
1377 
1378  SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1379  : ConfigItem( "Office.Writer/Numbering/UserInterfaceBehavior" ),
1381  {
1382  SetToDefault();
1383  LoadConfig();
1384 
1385  // enable notification for changes on configuration change
1386  EnableNotification( GetPropNames() );
1387  }
1388 
1389  void SwNumberingUIBehaviorConfig::SetToDefault()
1390  {
1392  }
1393 
1394  css::uno::Sequence<OUString> SwNumberingUIBehaviorConfig::GetPropNames()
1395  {
1396  css::uno::Sequence<OUString> aPropNames { "ChangeIndentOnTabAtFirstPosOfFirstListItem" };
1397 
1398  return aPropNames;
1399  }
1400 
1401  void SwNumberingUIBehaviorConfig::ImplCommit() {}
1402 
1403  void SwNumberingUIBehaviorConfig::LoadConfig()
1404  {
1405  css::uno::Sequence<OUString> aPropNames = GetPropNames();
1406  css::uno::Sequence<css::uno::Any> aValues = GetProperties( aPropNames );
1407  const css::uno::Any* pValues = aValues.getConstArray();
1408  OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1409  "<SwNumberingUIBehaviorConfig::LoadConfig()> - GetProperties failed");
1410  if ( aValues.getLength() != aPropNames.getLength() )
1411  return;
1412 
1413  for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1414  {
1415  if ( pValues[nProp].hasValue() )
1416  {
1417  switch ( nProp )
1418  {
1419  case 0:
1420  {
1422  }
1423  break;
1424  default:
1425  {
1426  OSL_FAIL( "<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property");
1427  }
1428  }
1429  }
1430  }
1431  }
1432 
1433  void SwNumberingUIBehaviorConfig::Notify( const css::uno::Sequence<OUString>& )
1434  {
1435  SetToDefault();
1436  LoadConfig();
1437  }
1438 
1440  {
1441  return SwNumberingUIBehaviorConfig::getInstance().ChangeIndentOnTabAtFirstPosOfFirstListItem();
1442  }
1443 
1444  bool NumDownChangesIndent(const SwWrtShell& rShell)
1445  {
1446  SwPaM* pCursor = rShell.GetCursor();
1447  if (!pCursor)
1448  {
1449  return true;
1450  }
1451 
1452  SwTextNode* pTextNode = pCursor->GetNode().GetTextNode();
1453  if (!pTextNode)
1454  {
1455  return true;
1456  }
1457 
1458  const SwNumRule* pNumRule = pTextNode->GetNumRule();
1459  if (!pNumRule)
1460  {
1461  return true;
1462  }
1463 
1464  int nOldLevel = pTextNode->GetActualListLevel();
1465  int nNewLevel = nOldLevel + 1;
1466  if (nNewLevel >= MAXLEVEL)
1467  {
1468  return true;
1469  }
1470 
1471  const SwNumFormat& rOldFormat = pNumRule->Get(nOldLevel);
1472  if (rOldFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1473  {
1474  return true;
1475  }
1476 
1477  const SwNumFormat& rNewFormat = pNumRule->Get(nNewLevel);
1478  if (rNewFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1479  {
1480  return true;
1481  }
1482 
1483  // This is the case when the numbering levels don't differ, so changing between them is not
1484  // a better alternative to inserting a tab character.
1485  return rOldFormat.GetIndentAt() != rNewFormat.GetIndentAt();
1486  }
1487 
1489  {
1492 
1494  SvtSaveOptions aSaveOptions;
1495  switch (aSaveOptions.GetODFSaneDefaultVersion())
1496  {
1499  {
1500  ePosAndSpaceMode = SvxNumberFormat::LABEL_WIDTH_AND_POSITION;
1501  }
1502  break;
1503  default: // >= ODFSVER_012
1504  {
1505  ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1506  }
1507  }
1508 
1509  return ePosAndSpaceMode;
1510  }
1511 }
1512 
1514 {
1515  xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRuleTable"));
1516  for (SwNumRule* pNumRule : *this)
1517  pNumRule->dumpAsXml(pWriter);
1518  xmlTextWriterEndElement(pWriter);
1519 }
1520 
1521 /* 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:1047
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:199
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
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
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:190
OUString MakeRefNumString(const SwNodeNum &rNodeNum, const bool bInclSuperiorNumLabels, const int nRestrictInclToThisLevel) const
Definition: number.cxx:751
OUString MakeNumString(const SwNodeNum &, bool bInclStrings=true) const
Definition: number.cxx:616
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:3121
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:1161
SVX_NUM_NUMBER_NONE
long Long
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:841
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:1089
FontWeight meFontWeight
Definition: number.cxx:1163
Definition: doc.hxx:186
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
void RemoveParagraphStyle(SwTextFormatColl &rTextFormatColl)
Definition: number.cxx:1058
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
tools::Long GetListtabPos() const
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:556
void SetIncludeUpperLevels(sal_uInt8 nSet)
bool HasNumber() const
Returns if this text node has a number.
Definition: ndtxt.cxx:3058
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: number.cxx:1513
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:4082
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:90
void StartListeningToSameModifyAs(const SwClient &)
Definition: calbck.cxx:119
sal_uInt16 sal_Unicode
void SetGrabBagItem(const css::uno::Any &rVal)
Definition: number.cxx:1097
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:1327
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:1164
sal_Unicode mnLevelChars[MAXLEVEL]
Definition: number.cxx:1165
SvxNumRule MakeSvxNumRule() const
Definition: number.cxx:894
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:127
bool IsContinusNum() const
Definition: numrule.hxx:234
SVX_NUM_BITMAP
exports com.sun.star. text
bool mbChangeIndentOnTabAtFirstPosOfFirstListItem
Definition: number.cxx:1367
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
std::unique_ptr< SwFormatVertOrient > m_pVertOrient
Definition: numrule.hxx:52
std::unique_ptr< sw::ModifyChangedHint > CheckRegistration(const SfxPoolItem *pOldValue)
Definition: calbck.cxx:81
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: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:1322
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
static OUString GetOutlineRuleName()
Definition: number.cxx:74
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2776
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:1037
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:972
void SetCharTextDistance(short nSet)
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
void dumpAsXml(xmlTextWriterPtr w) const
Definition: number.cxx:1069
SwNumRule::tParagraphStyleList::size_type GetParagraphStyleListSize() const
Definition: number.cxx:1042
ODFSaneDefaultVersion GetODFSaneDefaultVersion() const
std::unique_ptr< vcl::Font > mpFont
Definition: number.cxx:1168
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:933
void SetBulletChar(sal_UCS4 cSet)
std::vector< tSwNumTreeNumber > tNumberVector
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:770
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:591
SwNumRule::tTextNodeList::size_type GetTextNodeListSize() const
Definition: number.cxx:128
void Validate()
Definition: number.cxx:1024
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:910
const SwCharFormats * GetCharFormats() const
Definition: doc.hxx:737
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1488
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
Definition: number.cxx:1317
unsigned char sal_uInt8
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
Definition: number.cxx:1312
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:1065
const sal_uInt16 lNumberIndent
Definition: swtypes.hxx:105
void SetSvxRule(const SvxNumRule &, SwDoc *pDoc)
Definition: number.cxx:882
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:163
~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
void SetSuffix(const OUString &rSet)
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:1444
bool IsInDtor() const
Definition: doc.hxx:400
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:2816
bool mbUserDefinedFontname
Definition: number.cxx:1162
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:1001
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
bool ChangeIndentOnTabAtFirstPosOfFirstListItem()
configuration, if at first position of the first list item the -key increased the indent of the ...
Definition: number.cxx:1439
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:845
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:858
namespace for static functions and methods for numbering and bullets
Definition: number.cxx:1105