LibreOffice Module sw (master)  1
DocumentListsManager.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 #include <DocumentListsManager.hxx>
20 #include <doc.hxx>
21 #include <list.hxx>
22 #include <numrule.hxx>
23 
24 #include <comphelper/random.hxx>
25 #include <osl/diagnose.h>
26 
27 #include <vector>
28 
29 
30 namespace sw
31 {
32 
33 DocumentListsManager::DocumentListsManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ), maLists(), maListStyleLists()
34 {
35 }
36 
37 SwList* DocumentListsManager::createList( const OUString& rListId,
38  const OUString& sDefaultListStyleName )
39 {
40  OUString sListId = rListId;
41  if ( sListId.isEmpty() )
42  {
43  sListId = CreateUniqueListId();
44  }
45 
46  if ( getListByName( sListId ) )
47  {
48  OSL_FAIL( "<DocumentListsManager::createList(..)> - provided list id already used. Serious defect." );
49  return nullptr;
50  }
51 
52  SwNumRule* pDefaultNumRuleForNewList = m_rDoc.FindNumRulePtr( sDefaultListStyleName );
53  if ( !pDefaultNumRuleForNewList )
54  {
55  OSL_FAIL( "<DocumentListsManager::createList(..)> - for provided default list style name no list style is found. Serious defect." );
56  return nullptr;
57  }
58 
59  SwList* pNewList = new SwList( sListId, *pDefaultNumRuleForNewList, m_rDoc.GetNodes() );
60  maLists[sListId].reset(pNewList);
61 
62  return pNewList;
63 }
64 
65 SwList* DocumentListsManager::getListByName( const OUString& sListId ) const
66 {
67  SwList* pList = nullptr;
68 
69  auto aListIter = maLists.find( sListId );
70  if ( aListIter != maLists.end() )
71  {
72  pList = (*aListIter).second.get();
73  }
74 
75  return pList;
76 }
77 
78 void DocumentListsManager::createListForListStyle( const OUString& sListStyleName )
79 {
80  if ( sListStyleName.isEmpty() )
81  {
82  OSL_FAIL( "<DocumentListsManager::createListForListStyle(..)> - no list style name provided. Serious defect." );
83  return;
84  }
85 
86  if ( getListForListStyle( sListStyleName ) )
87  {
88  OSL_FAIL( "<DocumentListsManager::createListForListStyle(..)> - a list for the provided list style name already exists. Serious defect." );
89  return;
90  }
91 
92  SwNumRule* pNumRule = m_rDoc.FindNumRulePtr( sListStyleName );
93  if ( !pNumRule )
94  {
95  OSL_FAIL( "<DocumentListsManager::createListForListStyle(..)> - for provided list style name no list style is found. Serious defect." );
96  return;
97  }
98 
99  OUString sListId( pNumRule->GetDefaultListId() ); // can be empty String
100  if ( getListByName( sListId ) )
101  {
102  sListId.clear();
103  }
104  SwList* pNewList = createList( sListId, sListStyleName );
105  maListStyleLists[sListStyleName] = pNewList;
106  pNumRule->SetDefaultListId( pNewList->GetListId() );
107 }
108 
109 SwList* DocumentListsManager::getListForListStyle( const OUString& sListStyleName ) const
110 {
111  SwList* pList = nullptr;
112 
113  std::unordered_map< OUString, SwList* >::const_iterator
114  aListIter = maListStyleLists.find( sListStyleName );
115  if ( aListIter != maListStyleLists.end() )
116  {
117  pList = (*aListIter).second;
118  }
119 
120  return pList;
121 }
122 
123 void DocumentListsManager::deleteListForListStyle( const OUString& sListStyleName )
124 {
125  OUString sListId;
126  {
127  SwList* pList = getListForListStyle( sListStyleName );
128  OSL_ENSURE( pList,
129  "<DocumentListsManager::deleteListForListStyle(..)> - misusage of method: no list found for given list style name" );
130  if ( pList )
131  {
132  sListId = pList->GetListId();
133  }
134  }
135  if ( !sListId.isEmpty() )
136  {
137  maListStyleLists.erase( sListStyleName );
138  maLists.erase( sListId );
139  }
140 }
141 
142 void DocumentListsManager::deleteListsByDefaultListStyle( const OUString& rListStyleName )
143 {
144  auto aListIter = maLists.begin();
145  while ( aListIter != maLists.end() )
146  {
147  if ( (*aListIter).second->GetDefaultListStyleName() == rListStyleName )
148  {
149  aListIter = maLists.erase(aListIter);
150  }
151  else
152  ++aListIter;
153  }
154 }
155 
156 void DocumentListsManager::trackChangeOfListStyleName( const OUString& sListStyleName,
157  const OUString& sNewListStyleName )
158 {
159  SwList* pList = getListForListStyle( sListStyleName );
160  OSL_ENSURE( pList,
161  "<DocumentListsManager::changeOfListStyleName(..)> - misusage of method: no list found for given list style name" );
162 
163  if ( pList != nullptr )
164  {
165  maListStyleLists.erase( sListStyleName );
166  maListStyleLists[sNewListStyleName] = pList;
167  }
168  for (auto & it : maLists) // tdf#91131 update these references too
169  {
170  if (it.second->GetDefaultListStyleName() == sListStyleName)
171  {
172  it.second->SetDefaultListStyleName(sNewListStyleName);
173  }
174  }
175 }
176 
177 
179 {
180 }
181 
182 
183 const OUString DocumentListsManager::MakeListIdUnique( const OUString& aSuggestedUniqueListId )
184 {
185  long nHitCount = 0;
186  OUString aTmpStr = aSuggestedUniqueListId;
187  while ( getListByName( aTmpStr ) )
188  {
189  ++nHitCount;
190  aTmpStr = aSuggestedUniqueListId + OUString::number( nHitCount );
191  }
192 
193  return aTmpStr;
194 }
195 
197 {
198  static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != nullptr);
199  if (bHack)
200  {
201  static sal_Int64 nIdCounter = SAL_CONST_INT64(7000000000);
202  return MakeListIdUnique( OUString( "list" + OUString::number(nIdCounter++) ) );
203  }
204  else
205  {
206  // #i92478#
207  unsigned int const n(comphelper::rng::uniform_uint_distribution(0,
208  std::numeric_limits<unsigned int>::max()));
209  OUString const aNewListId = "list" + OUString::number(n);
210  return MakeListIdUnique( aNewListId );
211  }
212 }
213 
214 }
215 
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwList * getListByName(const OUString &rListId) const override
const OUString & GetListId() const
Definition: list.cxx:228
const OUString & GetDefaultListId() const
Definition: numrule.hxx:192
Definition: list.hxx:33
Definition: doc.hxx:185
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:40
void SetDefaultListStyleName(OUString const &)
Definition: list.cxx:238
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
std::unordered_map< OUString, std::unique_ptr< SwList > > maLists
DocumentListsManager(SwDoc &i_rSwdoc)
void trackChangeOfListStyleName(const OUString &rListStyleName, const OUString &rNewListStyleName) override
SwNumRule * FindNumRulePtr(const OUString &rName) const
Definition: docnum.cxx:2423
const OUString MakeListIdUnique(const OUString &aSuggestedUniqueListId)
void deleteListsByDefaultListStyle(const OUString &rListStyleName) override
virtual ~DocumentListsManager() override
void createListForListStyle(const OUString &rListStyleName) override
std::unordered_map< OUString, SwList * > maListStyleLists
SwList * createList(const OUString &rListId, const OUString &rDefaultListStyleName) override
void deleteListForListStyle(const OUString &rListStyleName) override
void SetDefaultListId(const OUString &sDefaultListId)
Definition: numrule.hxx:188
SwNodes & GetNodes()
Definition: doc.hxx:403
SwList * getListForListStyle(const OUString &rListStyleName) const override