LibreOffice Module xmloff (master) 1
XMLTextListAutoStylePool.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 <utility>
21#include <vector>
22
23#include <tools/solar.h>
25#include <com/sun/star/frame/XModel.hpp>
26#include <com/sun/star/style/XStyle.hpp>
27#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
28#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
29#include <com/sun/star/container/XNamed.hpp>
30#include <com/sun/star/container/XIndexReplace.hpp>
31#include <rtl/ustrbuf.hxx>
32#include <sal/log.hxx>
33#include <xmloff/xmlnume.hxx>
35#include <xmloff/xmlexp.hxx>
36
37
38using namespace ::com::sun::star;
39using namespace ::com::sun::star::uno;
40using namespace ::com::sun::star::beans;
41using namespace ::com::sun::star::container;
42using namespace ::com::sun::star::style;
43
44
46{
47 OUString sName;
48 OUString sInternalName;
49 Reference < XIndexReplace > xNumRules;
50 sal_uInt32 nPos;
52
53
54public:
55
57 sal_uInt32 nPos,
58 const Reference < XIndexReplace > & rNumRules,
60 std::u16string_view rPrefix,
61 sal_uInt32& rName );
62
64 const Reference < XIndexReplace > & rNumRules ) :
65 xNumRules( rNumRules ),
66 nPos( 0 ),
67 bIsNamed( false )
68 {
69 Reference < XNamed > xNamed( xNumRules, UNO_QUERY );
70 if( xNamed.is() )
71 {
72 sInternalName = xNamed->getName();
73 bIsNamed = true;
74 }
75 }
76
78 OUString aInternalName ) :
79 sInternalName(std::move( aInternalName )),
80 nPos( 0 ),
81 bIsNamed( true )
82 {
83 }
84
85 const OUString& GetName() const { return sName; }
86 const OUString& GetInternalName() const { return sInternalName; }
87 const Reference < XIndexReplace > & GetNumRules() const { return xNumRules; }
88 sal_uInt32 GetPos() const { return nPos; }
89 bool IsNamed() const { return bIsNamed; }
90};
91
93 sal_uInt32 nP,
94 const Reference < XIndexReplace > & rNumRules,
96 std::u16string_view rPrefix,
97 sal_uInt32& rName ) :
98 xNumRules( rNumRules ),
99 nPos( nP ),
100 bIsNamed( false )
101{
102 Reference < XNamed > xNamed( xNumRules, UNO_QUERY );
103 if( xNamed.is() )
104 {
105 sInternalName = xNamed->getName();
106 bIsNamed = true;
107 }
108
109 // create a name that hasn't been used before. The created name has not
110 // to be added to the array, because it will never tried again
111 do
112 {
113 rName++;
114 sName = rPrefix + OUString::number( static_cast<sal_Int32>(rName) );
115 }
116 while (rNames.find(sName) != rNames.end());
117}
118
119namespace {
120
121struct XMLTextListAutoStylePoolEntryCmp_Impl
122{
123 bool operator()(
124 std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl> const& r1,
125 std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl> const& r2 ) const
126 {
127 if( r1->IsNamed() )
128 {
129 if( r2->IsNamed() )
130 return r1->GetInternalName().compareTo( r2->GetInternalName() ) < 0;
131 else
132 return true;
133 }
134 else
135 {
136 if( r2->IsNamed() )
137 return false;
138 else
139 return r1->GetNumRules().get() < r2->GetNumRules().get();
140 }
141 }
142};
143
144}
145
146class XMLTextListAutoStylePool_Impl : public o3tl::sorted_vector<std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl>, XMLTextListAutoStylePoolEntryCmp_Impl> {};
147
149 m_rExport( rExp ),
150 m_sPrefix( "L" ),
151 m_pPool( new XMLTextListAutoStylePool_Impl ),
152 m_nName( 0 )
153{
154 Reference<ucb::XAnyCompareFactory> xCompareFac( rExp.GetModel(), uno::UNO_QUERY );
155 if( xCompareFac.is() )
156 mxNumRuleCompare = xCompareFac->createAnyCompareByName( "NumberingRules" );
158 bool bStylesOnly = (nExportFlags & SvXMLExportFlags::STYLES) && !(nExportFlags & SvXMLExportFlags::CONTENT);
159 if( bStylesOnly )
160 m_sPrefix = "ML";
161
162 Reference<XStyleFamiliesSupplier> xFamiliesSupp(m_rExport.GetModel(), UNO_QUERY);
163 SAL_WARN_IF(!xFamiliesSupp.is(), "xmloff", "getStyleFamilies() from XModel failed for export!");
164 Reference< XNameAccess > xFamilies;
165 if (xFamiliesSupp.is())
166 xFamilies = xFamiliesSupp->getStyleFamilies();
167
168 Reference<XIndexAccess> xStyles;
169 static constexpr OUStringLiteral aNumberStyleName(u"NumberingStyles");
170 if (xFamilies.is() && xFamilies->hasByName(aNumberStyleName))
171 xFamilies->getByName(aNumberStyleName) >>= xStyles;
172
173 const sal_Int32 nStyles = xStyles.is() ? xStyles->getCount() : 0;
174 for (sal_Int32 i = 0; i < nStyles; i++)
175 {
176 Reference<XStyle> xStyle;
177 xStyles->getByIndex(i) >>= xStyle;
178 RegisterName(xStyle->getName());
179 }
180}
181
183{
184}
185
186void XMLTextListAutoStylePool::RegisterName( const OUString& rName )
187{
188 m_aNames.insert(rName);
189}
190
192{
193 if( !pEntry->IsNamed() && mxNumRuleCompare.is() )
194 {
195 const sal_uInt32 nCount = m_pPool->size();
196
197 uno::Any aAny1, aAny2;
198 aAny1 <<= pEntry->GetNumRules();
199
200 for( sal_uInt32 nPos = 0; nPos < nCount; nPos++ )
201 {
202 aAny2 <<= (*m_pPool)[nPos]->GetNumRules();
203
204 if( mxNumRuleCompare->compare( aAny1, aAny2 ) == 0 )
205 return nPos;
206 }
207 }
208 else
209 {
211 if( it != m_pPool->end() )
212 return it - m_pPool->begin();
213 }
214
215 return sal_uInt32(-1);
216}
217
219 const Reference < XIndexReplace > & rNumRules )
220{
221 OUString sName;
222 XMLTextListAutoStylePoolEntry_Impl aTmp( rNumRules );
223
224 sal_uInt32 nPos = Find( &aTmp );
225 if( nPos != sal_uInt32(-1) )
226 {
227 sName = (*m_pPool)[ nPos ]->GetName();
228 }
229 else
230 {
231 std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl> pEntry(
233 rNumRules, m_aNames, m_sPrefix,
234 m_nName ));
235 sName = pEntry->GetName();
236 m_pPool->insert( std::move(pEntry) );
237 }
238
239 return sName;
240}
241
243 const Reference < XIndexReplace > & rNumRules ) const
244{
245 OUString sName;
246 XMLTextListAutoStylePoolEntry_Impl aTmp( rNumRules );
247
248 sal_uInt32 nPos = Find( &aTmp );
249 if( nPos != sal_uInt32(-1) )
250 sName = (*m_pPool)[ nPos ]->GetName();
251
252 return sName;
253}
254
256 const OUString& rInternalName ) const
257{
258 OUString sName;
259 XMLTextListAutoStylePoolEntry_Impl aTmp( rInternalName );
260 sal_uInt32 nPos = Find( &aTmp );
261 if( nPos != sal_uInt32(-1) )
262 sName = (*m_pPool)[ nPos ]->GetName();
263
264 return sName;
265}
266
268{
269 sal_uInt32 nCount = m_pPool->size();
270 if( !nCount )
271 return;
272
273 std::vector<XMLTextListAutoStylePoolEntry_Impl*> aExpEntries(nCount);
274
275 sal_uInt32 i;
276 for( i=0; i < nCount; i++ )
277 {
278 XMLTextListAutoStylePoolEntry_Impl *pEntry = (*m_pPool)[i].get();
279 SAL_WARN_IF( pEntry->GetPos() >= nCount, "xmloff", "Illegal pos" );
280 aExpEntries[pEntry->GetPos()] = pEntry;
281 }
282
283 SvxXMLNumRuleExport aNumRuleExp( m_rExport );
284
285 for( i=0; i < nCount; i++ )
286 {
287 XMLTextListAutoStylePoolEntry_Impl *pEntry = aExpEntries[i];
288 aNumRuleExp.exportNumberingRule( pEntry->GetName(), false,
289 pEntry->GetNumRules() );
290 }
291}
292
293
294/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::set< OUString > XMLTextListAutoStylePoolNames_Impl
SvXMLExportFlags getExportFlags() const
Definition: xmlexp.hxx:473
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:411
void exportNumberingRule(const OUString &rName, bool bIsHidden, const css::uno::Reference< css::container::XIndexReplace > &xNumRule)
Definition: xmlnume.cxx:654
XMLTextListAutoStylePoolEntry_Impl(const Reference< XIndexReplace > &rNumRules)
const Reference< XIndexReplace > & GetNumRules() const
XMLTextListAutoStylePoolEntry_Impl(sal_uInt32 nPos, const Reference< XIndexReplace > &rNumRules, XMLTextListAutoStylePoolNames_Impl &rNames, std::u16string_view rPrefix, sal_uInt32 &rName)
XMLTextListAutoStylePoolEntry_Impl(OUString aInternalName)
XMLTextListAutoStylePoolNames_Impl m_aNames
std::unique_ptr< XMLTextListAutoStylePool_Impl > m_pPool
SAL_DLLPRIVATE sal_uInt32 Find(const XMLTextListAutoStylePoolEntry_Impl *pEntry) const
void RegisterName(const OUString &rName)
css::uno::Reference< css::ucb::XAnyCompare > mxNumRuleCompare
this is an optional NumRule compare component for applications where the NumRules don't have names
XMLTextListAutoStylePool(SvXMLExport &rExport)
OUString Add(const css::uno::Reference< css::container::XIndexReplace > &rNumRules)
int nCount
float u
OUString sName
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
int i
SvXMLExportFlags
Definition: xmlexp.hxx:90