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 OUStringBuffer sBuffer( 7 );
112 do
113 {
114 rName++;
115 sBuffer.append( rPrefix );
116 sBuffer.append( static_cast<sal_Int32>(rName) );
117 sName = sBuffer.makeStringAndClear();
118 }
119 while (rNames.find(sName) != rNames.end());
120}
121
122namespace {
123
124struct XMLTextListAutoStylePoolEntryCmp_Impl
125{
126 bool operator()(
127 std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl> const& r1,
128 std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl> const& r2 ) const
129 {
130 if( r1->IsNamed() )
131 {
132 if( r2->IsNamed() )
133 return r1->GetInternalName().compareTo( r2->GetInternalName() ) < 0;
134 else
135 return true;
136 }
137 else
138 {
139 if( r2->IsNamed() )
140 return false;
141 else
142 return r1->GetNumRules().get() < r2->GetNumRules().get();
143 }
144 }
145};
146
147}
148
149class XMLTextListAutoStylePool_Impl : public o3tl::sorted_vector<std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl>, XMLTextListAutoStylePoolEntryCmp_Impl> {};
150
152 rExport( rExp ),
153 sPrefix( "L" ),
155 nName( 0 )
156{
157 Reference<ucb::XAnyCompareFactory> xCompareFac( rExp.GetModel(), uno::UNO_QUERY );
158 if( xCompareFac.is() )
159 mxNumRuleCompare = xCompareFac->createAnyCompareByName( "NumberingRules" );
160 SvXMLExportFlags nExportFlags = rExport.getExportFlags();
161 bool bStylesOnly = (nExportFlags & SvXMLExportFlags::STYLES) && !(nExportFlags & SvXMLExportFlags::CONTENT);
162 if( bStylesOnly )
163 sPrefix = "ML";
164
165 Reference<XStyleFamiliesSupplier> xFamiliesSupp(rExport.GetModel(), UNO_QUERY);
166 SAL_WARN_IF(!xFamiliesSupp.is(), "xmloff", "getStyleFamilies() from XModel failed for export!");
167 Reference< XNameAccess > xFamilies;
168 if (xFamiliesSupp.is())
169 xFamilies = xFamiliesSupp->getStyleFamilies();
170
171 Reference<XIndexAccess> xStyles;
172 static const OUStringLiteral aNumberStyleName(u"NumberingStyles");
173 if (xFamilies.is() && xFamilies->hasByName(aNumberStyleName))
174 xFamilies->getByName(aNumberStyleName) >>= xStyles;
175
176 const sal_Int32 nStyles = xStyles.is() ? xStyles->getCount() : 0;
177 for (sal_Int32 i = 0; i < nStyles; i++)
178 {
179 Reference<XStyle> xStyle;
180 xStyles->getByIndex(i) >>= xStyle;
181 RegisterName(xStyle->getName());
182 }
183}
184
186{
187}
188
189void XMLTextListAutoStylePool::RegisterName( const OUString& rName )
190{
191 m_aNames.insert(rName);
192}
193
195{
196 if( !pEntry->IsNamed() && mxNumRuleCompare.is() )
197 {
198 const sal_uInt32 nCount = pPool->size();
199
200 uno::Any aAny1, aAny2;
201 aAny1 <<= pEntry->GetNumRules();
202
203 for( sal_uInt32 nPos = 0; nPos < nCount; nPos++ )
204 {
205 aAny2 <<= (*pPool)[nPos]->GetNumRules();
206
207 if( mxNumRuleCompare->compare( aAny1, aAny2 ) == 0 )
208 return nPos;
209 }
210 }
211 else
212 {
214 if( it != pPool->end() )
215 return it - pPool->begin();
216 }
217
218 return sal_uInt32(-1);
219}
220
222 const Reference < XIndexReplace > & rNumRules )
223{
224 OUString sName;
225 XMLTextListAutoStylePoolEntry_Impl aTmp( rNumRules );
226
227 sal_uInt32 nPos = Find( &aTmp );
228 if( nPos != sal_uInt32(-1) )
229 {
230 sName = (*pPool)[ nPos ]->GetName();
231 }
232 else
233 {
234 std::unique_ptr<XMLTextListAutoStylePoolEntry_Impl> pEntry(
236 rNumRules, m_aNames, sPrefix,
237 nName ));
238 sName = pEntry->GetName();
239 pPool->insert( std::move(pEntry) );
240 }
241
242 return sName;
243}
244
246 const Reference < XIndexReplace > & rNumRules ) const
247{
248 OUString sName;
249 XMLTextListAutoStylePoolEntry_Impl aTmp( rNumRules );
250
251 sal_uInt32 nPos = Find( &aTmp );
252 if( nPos != sal_uInt32(-1) )
253 sName = (*pPool)[ nPos ]->GetName();
254
255 return sName;
256}
257
259 const OUString& rInternalName ) const
260{
261 OUString sName;
262 XMLTextListAutoStylePoolEntry_Impl aTmp( rInternalName );
263 sal_uInt32 nPos = Find( &aTmp );
264 if( nPos != sal_uInt32(-1) )
265 sName = (*pPool)[ nPos ]->GetName();
266
267 return sName;
268}
269
271{
272 sal_uInt32 nCount = pPool->size();
273 if( !nCount )
274 return;
275
276 std::vector<XMLTextListAutoStylePoolEntry_Impl*> aExpEntries(nCount);
277
278 sal_uInt32 i;
279 for( i=0; i < nCount; i++ )
280 {
281 XMLTextListAutoStylePoolEntry_Impl *pEntry = (*pPool)[i].get();
282 SAL_WARN_IF( pEntry->GetPos() >= nCount, "xmloff", "Illegal pos" );
283 aExpEntries[pEntry->GetPos()] = pEntry;
284 }
285
286 SvxXMLNumRuleExport aNumRuleExp( rExport );
287
288 for( i=0; i < nCount; i++ )
289 {
290 XMLTextListAutoStylePoolEntry_Impl *pEntry = aExpEntries[i];
291 aNumRuleExp.exportNumberingRule( pEntry->GetName(), false,
292 pEntry->GetNumRules() );
293 }
294}
295
296
297/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::set< OUString > XMLTextListAutoStylePoolNames_Impl
SvXMLExportFlags getExportFlags() const
Definition: xmlexp.hxx:478
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:416
void exportNumberingRule(const OUString &rName, bool bIsHidden, const css::uno::Reference< css::container::XIndexReplace > &xNumRule)
Definition: xmlnume.cxx:644
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)
std::unique_ptr< XMLTextListAutoStylePool_Impl > pPool
XMLTextListAutoStylePoolNames_Impl m_aNames
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 sPrefix
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
const char * sName
int i
SvXMLExportFlags
Definition: xmlexp.hxx:91