Version 7.5.1.1, tag libreoffice-7.5.1.1
[LibreOffice.git] / xmloff / source / style / xmlprmap.cxx
blobf7145161e3b8b2b3344a2b0234186b08031583bd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <o3tl/safeint.hxx>
21 #include <rtl/ref.hxx>
23 #include <xmloff/xmlprmap.hxx>
24 #include <xmloff/xmlprhdl.hxx>
25 #include <xmloff/xmltypes.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/maptype.hxx>
28 #include <xmloff/prhdlfac.hxx>
29 #include <xmloff/xmlimp.hxx>
31 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <vector>
35 using namespace ::std;
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::beans;
39 using ::xmloff::token::GetXMLToken;
41 namespace {
43 /** Helper-class for XML-im/export:
44 - Holds a pointer to a given array of XMLPropertyMapEntry
45 - Provides several methods to access data from this array
46 - Holds a Sequence of XML-names (for properties)
47 - The filter takes all properties of the XPropertySet which are also
48 in the XMLPropertyMapEntry and which are have not a default value
49 and put them into a vector of XMLPropertyStae
50 - this class knows how to compare, im/export properties
52 Attention: At all methods, which get an index as parameter, there is no
53 range validation to save runtime !!
55 struct XMLPropertySetMapperEntry_Impl
57 OUString sXMLAttributeName;
58 OUString sAPIPropertyName;
59 sal_Int32 nType;
60 sal_uInt16 nXMLNameSpace;
61 sal_Int16 nContextId;
62 SvtSaveOptions::ODFSaneDefaultVersion nEarliestODFVersionForExport;
63 bool bImportOnly;
64 const XMLPropertyHandler *pHdl;
66 XMLPropertySetMapperEntry_Impl(
67 const XMLPropertyMapEntry& rMapEntry,
68 const rtl::Reference< XMLPropertyHandlerFactory >& rFactory );
70 sal_uInt32 GetPropType() const { return nType & XML_TYPE_PROP_MASK; }
75 XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
76 const XMLPropertyMapEntry& rMapEntry,
77 const rtl::Reference< XMLPropertyHandlerFactory >& rFactory ) :
78 sXMLAttributeName( GetXMLToken(rMapEntry.meXMLName) ),
79 sAPIPropertyName( rMapEntry.getApiName() ),
80 nType( rMapEntry.mnType ),
81 nXMLNameSpace( rMapEntry.mnNameSpace ),
82 nContextId( rMapEntry.mnContextId ),
83 nEarliestODFVersionForExport( rMapEntry.mnEarliestODFVersionForExport ),
84 bImportOnly( rMapEntry.mbImportOnly),
85 pHdl( rFactory->GetPropertyHandler( rMapEntry.mnType & MID_FLAG_MASK ) )
87 assert(pHdl);
90 struct XMLPropertySetMapper::Impl
92 std::vector<XMLPropertySetMapperEntry_Impl> maMapEntries;
93 std::vector<rtl::Reference <XMLPropertyHandlerFactory> > maHdlFactories;
95 bool mbOnlyExportMappings;
97 explicit Impl( bool bForExport ) : mbOnlyExportMappings(bForExport) {}
100 // Ctor
101 XMLPropertySetMapper::XMLPropertySetMapper(
102 const XMLPropertyMapEntry* pEntries, const rtl::Reference<XMLPropertyHandlerFactory>& rFactory,
103 bool bForExport ) :
104 mpImpl(new Impl(bForExport))
106 mpImpl->maHdlFactories.push_back(rFactory);
107 if( !pEntries )
108 return;
110 const XMLPropertyMapEntry* pIter = pEntries;
112 if (mpImpl->mbOnlyExportMappings)
114 while( !pIter->IsEnd() )
116 if (!pIter->mbImportOnly)
118 XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
119 mpImpl->maMapEntries.push_back( aEntry );
121 ++pIter;
124 else
126 while( !pIter->IsEnd() )
128 XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
129 mpImpl->maMapEntries.push_back( aEntry );
130 ++pIter;
135 XMLPropertySetMapper::~XMLPropertySetMapper()
139 void XMLPropertySetMapper::AddMapperEntry(
140 const rtl::Reference < XMLPropertySetMapper >& rMapper )
142 for( const auto& rHdlFactory : rMapper->mpImpl->maHdlFactories )
144 mpImpl->maHdlFactories.push_back(rHdlFactory);
147 for( const auto& rMapEntry : rMapper->mpImpl->maMapEntries )
149 if (!mpImpl->mbOnlyExportMappings || !rMapEntry.bImportOnly)
150 mpImpl->maMapEntries.push_back( rMapEntry );
154 sal_Int32 XMLPropertySetMapper::GetEntryCount() const
156 return mpImpl->maMapEntries.size();
159 sal_uInt32 XMLPropertySetMapper::GetEntryFlags( sal_Int32 nIndex ) const
161 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
162 return mpImpl->maMapEntries[nIndex].nType & ~MID_FLAG_MASK;
165 sal_uInt32 XMLPropertySetMapper::GetEntryType( sal_Int32 nIndex ) const
167 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
168 sal_uInt32 nType = mpImpl->maMapEntries[nIndex].nType;
169 return nType;
172 sal_uInt16 XMLPropertySetMapper::GetEntryNameSpace( sal_Int32 nIndex ) const
174 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
175 return mpImpl->maMapEntries[nIndex].nXMLNameSpace;
178 const OUString& XMLPropertySetMapper::GetEntryXMLName( sal_Int32 nIndex ) const
180 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
181 return mpImpl->maMapEntries[nIndex].sXMLAttributeName;
184 const OUString& XMLPropertySetMapper::GetEntryAPIName( sal_Int32 nIndex ) const
186 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
187 return mpImpl->maMapEntries[nIndex].sAPIPropertyName;
190 sal_Int16 XMLPropertySetMapper::GetEntryContextId( sal_Int32 nIndex ) const
192 assert((-1 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
193 return nIndex == -1 ? 0 : mpImpl->maMapEntries[nIndex].nContextId;
196 SvtSaveOptions::ODFSaneDefaultVersion
197 XMLPropertySetMapper::GetEarliestODFVersionForExport(sal_Int32 const nIndex) const
199 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
200 return mpImpl->maMapEntries[nIndex].nEarliestODFVersionForExport;
203 const XMLPropertyHandler* XMLPropertySetMapper::GetPropertyHandler( sal_Int32 nIndex ) const
205 assert((0 <= nIndex) && (o3tl::make_unsigned(nIndex) < mpImpl->maMapEntries.size()));
206 return mpImpl->maMapEntries[nIndex].pHdl;
209 // Export a Property
210 bool XMLPropertySetMapper::exportXML(
211 OUString& rStrExpValue,
212 const XMLPropertyState& rProperty,
213 const SvXMLUnitConverter& rUnitConverter ) const
215 bool bRet = false;
217 const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
219 assert(pHdl);
220 if( pHdl )
221 bRet = pHdl->exportXML( rStrExpValue, rProperty.maValue,
222 rUnitConverter );
224 return bRet;
227 // Import a Property
228 bool XMLPropertySetMapper::importXML(
229 const OUString& rStrImpValue,
230 XMLPropertyState& rProperty,
231 const SvXMLUnitConverter& rUnitConverter ) const
233 bool bRet = false;
235 const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
237 if( pHdl )
238 bRet = pHdl->importXML( rStrImpValue, rProperty.maValue,
239 rUnitConverter );
241 return bRet;
244 // Search for the given name and the namespace in the list and return
245 // the index of the entry
246 // If there is no matching entry the method returns -1
247 sal_Int32 XMLPropertySetMapper::GetEntryIndex(
248 sal_uInt16 nNamespace,
249 std::u16string_view rStrName,
250 sal_uInt32 nPropType,
251 sal_Int32 nStartAt /* = -1 */ ) const
253 sal_Int32 nEntries = GetEntryCount();
254 sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;
256 if ( nEntries && nIndex < nEntries )
260 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
261 if( (!nPropType || nPropType == rEntry.GetPropType()) &&
262 rEntry.nXMLNameSpace == nNamespace &&
263 rStrName == rEntry.sXMLAttributeName )
264 return nIndex;
265 else
266 nIndex++;
268 } while( nIndex<nEntries );
271 return -1;
274 // Search for the given name and the namespace in the list and return
275 // the index of the entry
276 // If there is no matching entry the method returns -1
277 sal_Int32 XMLPropertySetMapper::GetEntryIndex(
278 sal_Int32 nElement,
279 sal_uInt32 nPropType,
280 sal_Int32 nStartAt /* = -1 */ ) const
282 sal_Int32 nEntries = GetEntryCount();
283 sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;
285 if ( nEntries && nIndex < nEntries )
287 sal_uInt16 nNamespace = (nElement >> NMSP_SHIFT) - 1;
288 const OUString& rStrName = SvXMLImport::getNameFromToken(nElement);
291 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
292 if( (!nPropType || nPropType == rEntry.GetPropType()) &&
293 rEntry.nXMLNameSpace == nNamespace &&
294 rStrName == rEntry.sXMLAttributeName )
295 return nIndex;
296 else
297 nIndex++;
299 } while( nIndex<nEntries );
302 return -1;
305 /** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
306 sal_Int32 XMLPropertySetMapper::FindEntryIndex(
307 const char* sApiName,
308 sal_uInt16 nNameSpace,
309 std::u16string_view sXMLName ) const
311 sal_Int32 nIndex = 0;
312 sal_Int32 nEntries = GetEntryCount();
316 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
317 if( rEntry.nXMLNameSpace == nNameSpace &&
318 rEntry.sXMLAttributeName == sXMLName &&
319 rEntry.sAPIPropertyName.equalsAscii( sApiName ) )
320 return nIndex;
321 else
322 nIndex++;
324 } while( nIndex < nEntries );
326 return -1;
329 sal_Int32 XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId ) const
331 const sal_Int32 nEntries = GetEntryCount();
333 if ( nEntries )
335 sal_Int32 nIndex = 0;
338 const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
339 if( rEntry.nContextId == nContextId )
340 return nIndex;
341 else
342 nIndex++;
344 } while( nIndex < nEntries );
347 return -1;
350 void XMLPropertySetMapper::RemoveEntry( sal_Int32 nIndex )
352 const sal_Int32 nEntries = GetEntryCount();
353 if( nIndex>=nEntries || nIndex<0 )
354 return;
355 vector < XMLPropertySetMapperEntry_Impl >::iterator aEIter = mpImpl->maMapEntries.begin();
356 std::advance(aEIter, nIndex);
357 mpImpl->maMapEntries.erase( aEIter );
360 void XMLPropertySetMapper::GetEntryAPINames( o3tl::sorted_vector<OUString>& rNames) const
362 for (const XMLPropertySetMapperEntry_Impl& rMapEntry : mpImpl->maMapEntries)
363 rNames.insert(rMapEntry.sAPIPropertyName);
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */