1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include <o3tl/sorted_vector.hxx>
24 #include <com/sun/star/frame/XModel.hpp>
25 #include <com/sun/star/style/XStyle.hpp>
26 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
27 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
28 #include <com/sun/star/container/XNamed.hpp>
29 #include <com/sun/star/container/XIndexReplace.hpp>
30 #include <sal/log.hxx>
31 #include <xmloff/xmlnume.hxx>
32 #include <xmloff/XMLTextListAutoStylePool.hxx>
33 #include <xmloff/xmlexp.hxx>
36 using namespace ::com::sun::star
;
37 using namespace ::com::sun::star::uno
;
38 using namespace ::com::sun::star::container
;
39 using namespace ::com::sun::star::style
;
42 class XMLTextListAutoStylePoolEntry_Impl
45 OUString sInternalName
;
46 Reference
< XIndexReplace
> xNumRules
;
53 XMLTextListAutoStylePoolEntry_Impl(
55 const Reference
< XIndexReplace
> & rNumRules
,
56 XMLTextListAutoStylePoolNames_Impl
& rNames
,
57 std::u16string_view rPrefix
,
60 explicit XMLTextListAutoStylePoolEntry_Impl(
61 const Reference
< XIndexReplace
> & rNumRules
) :
62 xNumRules( rNumRules
),
66 Reference
< XNamed
> xNamed( xNumRules
, UNO_QUERY
);
69 sInternalName
= xNamed
->getName();
74 explicit XMLTextListAutoStylePoolEntry_Impl(
75 OUString aInternalName
) :
76 sInternalName(std::move( aInternalName
)),
82 const OUString
& GetName() const { return sName
; }
83 const OUString
& GetInternalName() const { return sInternalName
; }
84 const Reference
< XIndexReplace
> & GetNumRules() const { return xNumRules
; }
85 sal_uInt32
GetPos() const { return nPos
; }
86 bool IsNamed() const { return bIsNamed
; }
89 XMLTextListAutoStylePoolEntry_Impl::XMLTextListAutoStylePoolEntry_Impl(
91 const Reference
< XIndexReplace
> & rNumRules
,
92 XMLTextListAutoStylePoolNames_Impl
& rNames
,
93 std::u16string_view rPrefix
,
95 xNumRules( rNumRules
),
99 Reference
< XNamed
> xNamed( xNumRules
, UNO_QUERY
);
102 sInternalName
= xNamed
->getName();
106 // create a name that hasn't been used before. The created name has not
107 // to be added to the array, because it will never tried again
111 sName
= rPrefix
+ OUString::number( static_cast<sal_Int32
>(rName
) );
113 while (rNames
.find(sName
) != rNames
.end());
118 struct XMLTextListAutoStylePoolEntryCmp_Impl
120 template <typename T1
, typename T2
>
121 requires
o3tl::is_reference_to
<T1
, XMLTextListAutoStylePoolEntry_Impl
>
122 && o3tl::is_reference_to
<T2
, XMLTextListAutoStylePoolEntry_Impl
>
123 bool operator()(T1
const& r1
, T2
const& r2
) const
128 return r1
->GetInternalName().compareTo( r2
->GetInternalName() ) < 0;
137 return r1
->GetNumRules().get() < r2
->GetNumRules().get();
144 class XMLTextListAutoStylePool_Impl
: public o3tl::sorted_vector
<std::unique_ptr
<XMLTextListAutoStylePoolEntry_Impl
>, XMLTextListAutoStylePoolEntryCmp_Impl
> {};
146 XMLTextListAutoStylePool::XMLTextListAutoStylePool( SvXMLExport
& rExp
) :
148 m_sPrefix( u
"L"_ustr
),
149 m_pPool( new XMLTextListAutoStylePool_Impl
),
152 Reference
<ucb::XAnyCompareFactory
> xCompareFac( rExp
.GetModel(), uno::UNO_QUERY
);
153 if( xCompareFac
.is() )
154 mxNumRuleCompare
= xCompareFac
->createAnyCompareByName( u
"NumberingRules"_ustr
);
155 SvXMLExportFlags nExportFlags
= m_rExport
.getExportFlags();
156 bool bStylesOnly
= (nExportFlags
& SvXMLExportFlags::STYLES
) && !(nExportFlags
& SvXMLExportFlags::CONTENT
);
160 Reference
<XStyleFamiliesSupplier
> xFamiliesSupp(m_rExport
.GetModel(), UNO_QUERY
);
161 SAL_WARN_IF(!xFamiliesSupp
.is(), "xmloff", "getStyleFamilies() from XModel failed for export!");
162 Reference
< XNameAccess
> xFamilies
;
163 if (xFamiliesSupp
.is())
164 xFamilies
= xFamiliesSupp
->getStyleFamilies();
166 Reference
<XIndexAccess
> xStyles
;
167 static constexpr OUString
aNumberStyleName(u
"NumberingStyles"_ustr
);
168 if (xFamilies
.is() && xFamilies
->hasByName(aNumberStyleName
))
169 xFamilies
->getByName(aNumberStyleName
) >>= xStyles
;
171 const sal_Int32 nStyles
= xStyles
.is() ? xStyles
->getCount() : 0;
172 for (sal_Int32 i
= 0; i
< nStyles
; i
++)
174 Reference
<XStyle
> xStyle
;
175 xStyles
->getByIndex(i
) >>= xStyle
;
176 RegisterName(xStyle
->getName());
180 XMLTextListAutoStylePool::~XMLTextListAutoStylePool()
184 void XMLTextListAutoStylePool::RegisterName( const OUString
& rName
)
186 m_aNames
.insert(rName
);
189 sal_uInt32
XMLTextListAutoStylePool::Find( const XMLTextListAutoStylePoolEntry_Impl
* pEntry
) const
191 if( !pEntry
->IsNamed() && mxNumRuleCompare
.is() )
193 const sal_uInt32 nCount
= m_pPool
->size();
195 uno::Any aAny1
, aAny2
;
196 aAny1
<<= pEntry
->GetNumRules();
198 for( sal_uInt32 nPos
= 0; nPos
< nCount
; nPos
++ )
200 aAny2
<<= (*m_pPool
)[nPos
]->GetNumRules();
202 if( mxNumRuleCompare
->compare( aAny1
, aAny2
) == 0 )
208 XMLTextListAutoStylePool_Impl::const_iterator it
= m_pPool
->find( pEntry
);
209 if( it
!= m_pPool
->end() )
210 return it
- m_pPool
->begin();
213 return sal_uInt32(-1);
216 OUString
XMLTextListAutoStylePool::Add(
217 const Reference
< XIndexReplace
> & rNumRules
)
220 XMLTextListAutoStylePoolEntry_Impl
aTmp( rNumRules
);
222 sal_uInt32 nPos
= Find( &aTmp
);
223 if( nPos
!= sal_uInt32(-1) )
225 sName
= (*m_pPool
)[ nPos
]->GetName();
229 std::unique_ptr
<XMLTextListAutoStylePoolEntry_Impl
> pEntry(
230 new XMLTextListAutoStylePoolEntry_Impl( m_pPool
->size(),
231 rNumRules
, m_aNames
, m_sPrefix
,
233 sName
= pEntry
->GetName();
234 m_pPool
->insert( std::move(pEntry
) );
240 OUString
XMLTextListAutoStylePool::Find(
241 const Reference
< XIndexReplace
> & rNumRules
) const
244 XMLTextListAutoStylePoolEntry_Impl
aTmp( rNumRules
);
246 sal_uInt32 nPos
= Find( &aTmp
);
247 if( nPos
!= sal_uInt32(-1) )
248 sName
= (*m_pPool
)[ nPos
]->GetName();
253 OUString
XMLTextListAutoStylePool::Find(
254 const OUString
& rInternalName
) const
257 XMLTextListAutoStylePoolEntry_Impl
aTmp( rInternalName
);
258 sal_uInt32 nPos
= Find( &aTmp
);
259 if( nPos
!= sal_uInt32(-1) )
260 sName
= (*m_pPool
)[ nPos
]->GetName();
265 void XMLTextListAutoStylePool::exportXML() const
267 sal_uInt32 nCount
= m_pPool
->size();
271 std::vector
<XMLTextListAutoStylePoolEntry_Impl
*> aExpEntries(nCount
);
274 for( i
=0; i
< nCount
; i
++ )
276 XMLTextListAutoStylePoolEntry_Impl
*pEntry
= (*m_pPool
)[i
].get();
277 SAL_WARN_IF( pEntry
->GetPos() >= nCount
, "xmloff", "Illegal pos" );
278 aExpEntries
[pEntry
->GetPos()] = pEntry
;
281 SvxXMLNumRuleExport
aNumRuleExp( m_rExport
);
283 for( i
=0; i
< nCount
; i
++ )
285 XMLTextListAutoStylePoolEntry_Impl
*pEntry
= aExpEntries
[i
];
286 aNumRuleExp
.exportNumberingRule( pEntry
->GetName(), false,
287 pEntry
->GetNumRules() );
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */