/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// Take all properties of the XPropertySet which are also found in the // XMLPropertyMapEntry-array and which are not set to their default-value, // if a state is available. // After that I call the method 'ContextFilter'.
const uno::Sequence<OUString>& FilterPropertiesInfo_Impl::GetApiNames()
{ if( !mxApiNames )
{ // we have to do three things: // 1) sort API names, // 2) merge duplicates, // 3) construct sequence
while ( aCurrent != aEnd )
{ // equal to next element? if ( aOld->GetApiName() == aCurrent->GetApiName() )
{ // if equal: merge index lists
std::vector<sal_uInt32> aMerged;
std::merge(aOld->GetIndexes().begin(), aOld->GetIndexes().end(),
aCurrent->GetIndexes().begin(), aCurrent->GetIndexes().end(),
std::back_inserter(aMerged));
aOld->GetIndexes() = std::move(aMerged);
aCurrent->GetIndexes().clear(); // erase element, and continue with next
aCurrent = aPropInfos.erase( aCurrent );
} else
{ // remember old element and continue with next
aOld = aCurrent;
++aCurrent;
}
}
}
bool bDelInfo = false; if( !pFilterInfo )
{
assert(GetODFDefaultVersion() != SvtSaveOptions::ODFVER_UNKNOWN); const SvtSaveOptions::ODFSaneDefaultVersion nCurrentVersion(rExport.getSaneDefaultVersion());
pFilterInfo = new FilterPropertiesInfo_Impl; for( sal_Int32 i=0; i < nProps; i++ )
{ // Are we allowed to ask for the property? (MID_FLAG_NO_PROP..) // Does the PropertySet contain name of mpEntries-array ? const OUString& rAPIName = mpImpl->mxPropMapper->GetEntryAPIName( i ); const sal_Int32 nFlags = mpImpl->mxPropMapper->GetEntryFlags( i ); if( (0 == (nFlags & MID_FLAG_NO_PROPERTY_EXPORT)) &&
( (0 != (nFlags & MID_FLAG_MUST_EXIST)) ||
xInfo->hasPropertyByName( rAPIName ) ) )
{ const SvtSaveOptions::ODFSaneDefaultVersion nEarliestODFVersionForExport(
mpImpl->mxPropMapper->GetEarliestODFVersionForExport(i)); // note: only standard ODF versions are allowed here, // only exception is the unknown future
assert((nEarliestODFVersionForExport & SvtSaveOptions::ODFSVER_EXTENDED) == 0
|| nEarliestODFVersionForExport == SvtSaveOptions::ODFSVER_FUTURE_EXTENDED);
static_assert(SvtSaveOptions::ODFSVER_LATEST_EXTENDED < SvtSaveOptions::ODFSVER_FUTURE_EXTENDED); /// standard ODF namespaces for elements and attributes static sal_uInt16 s_OdfNs[] = {
XML_NAMESPACE_OFFICE,
XML_NAMESPACE_STYLE,
XML_NAMESPACE_TEXT,
XML_NAMESPACE_TABLE,
XML_NAMESPACE_DRAW,
XML_NAMESPACE_FO,
XML_NAMESPACE_XLINK,
XML_NAMESPACE_DC,
XML_NAMESPACE_META,
XML_NAMESPACE_NUMBER,
XML_NAMESPACE_PRESENTATION,
XML_NAMESPACE_SVG,
XML_NAMESPACE_CHART,
XML_NAMESPACE_DR3D,
XML_NAMESPACE_MATH,
XML_NAMESPACE_FORM,
XML_NAMESPACE_SCRIPT,
XML_NAMESPACE_CONFIG,
XML_NAMESPACE_DB,
XML_NAMESPACE_XFORMS,
XML_NAMESPACE_SMIL,
XML_NAMESPACE_ANIMATION,
XML_NAMESPACE_XML,
XML_NAMESPACE_XHTML,
XML_NAMESPACE_GRDDL,
}; staticbool s_Assert(false); if (!s_Assert)
{
assert(std::is_sorted(std::begin(s_OdfNs), std::end(s_OdfNs)));
s_Assert = true;
} //static_assert(std::is_sorted(std::begin(s_OdfNs), std::end(s_OdfNs))); autoconst ns(mpImpl->mxPropMapper->GetEntryNameSpace(i)); autoconst iter(std::lower_bound(std::begin(s_OdfNs), std::end(s_OdfNs),
ns)); boolconst isExtension(iter == std::end(s_OdfNs) || *iter != ns // FIXME: very special hack to suppress style:hyperlink
|| (ns == XML_NAMESPACE_STYLE
&& mpImpl->mxPropMapper->GetEntryXMLName(i) == GetXMLToken(XML_HYPERLINK))); if (isExtension
? ((nCurrentVersion & SvtSaveOptions::ODFSVER_EXTENDED) // if it's in standard ODF, don't export extension
&& (nCurrentVersion < nEarliestODFVersionForExport))
: (nEarliestODFVersionForExport <= nCurrentVersion))
{
pFilterInfo->AddProperty(rAPIName, i);
}
}
}
// Check whether the property set info is destroyed if it is assigned to // a weak reference only; If it is destroyed, then every instance of // getPropertySetInfo returns a new object; such property set infos must // not be cached:
WeakReference < XPropertySetInfo > xWeakInfo( xInfo );
xInfo.clear();
xInfo = xWeakInfo; if( xInfo.is() )
{
mpImpl->maCache.emplace(xInfo, std::unique_ptr<FilterPropertiesInfo_Impl>(pFilterInfo));
} else
bDelInfo = true;
}
if( pFilterInfo->GetPropertyCount() )
{ try
{
pFilterInfo->FillPropertyStateArray(
aPropStateArray, xPropSet, mpImpl->mxPropMapper, bDefault);
} catch( UnknownPropertyException& )
{ // might be a problem of getImplementationId
TOOLS_WARN_EXCEPTION("xmloff.style", "unknown property in getPropertyStates" );
}
}
// Have to do if we change from a vector to a list or something like that
if( bDelInfo ) delete pFilterInfo;
return aPropStateArray;
}
void SvXMLExportPropertyMapper::ContextFilter( bool bEnableFoFontFamily,
std::vector< XMLPropertyState >& rProperties, const Reference< XPropertySet >& rPropSet ) const
{ // Derived class could implement this. if (mpImpl->mxNextMapper.is())
mpImpl->mxNextMapper->ContextFilter(bEnableFoFontFamily, rProperties, rPropSet);
}
// Compares two Sequences of XMLPropertyState: // 1.Number of elements equal ? // 2.Index of each element equal ? (So I know whether the propertynames are the same) // 3.Value of each element equal ? bool SvXMLExportPropertyMapper::Equals( const std::vector< XMLPropertyState >& aProperties1, const std::vector< XMLPropertyState >& aProperties2 ) const
{ if (aProperties1.size() < aProperties2.size()) returntrue; if (aProperties1.size() > aProperties2.size()) returnfalse;
// Compare index. If equal, compare value if( rProp1.mnIndex < rProp2.mnIndex ) returntrue; if( rProp1.mnIndex > rProp2.mnIndex ) returnfalse;
if( rProp1.mnIndex != -1 )
{ // Now compare values if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
XML_TYPE_BUILDIN_CMP ) != 0 )
{ // simple type ( binary compare ) if ( rProp1.maValue != rProp2.maValue) returnfalse;
} else
{ // complex type ( ask for compare-function ) if (!mpImpl->mxPropMapper->GetPropertyHandler(
rProp1.mnIndex )->equals( rProp1.maValue,
rProp2.maValue )) returnfalse;
}
}
}
returntrue;
}
// Compares two Sequences of XMLPropertyState: // 1.Number of elements equal ? // 2.Index of each element equal ? (So I know whether the propertynames are the same) // 3.Value of each element equal ? bool SvXMLExportPropertyMapper::LessPartial( const std::vector< XMLPropertyState >& aProperties1, const std::vector< XMLPropertyState >& aProperties2 ) const
{ if (aProperties1.size() < aProperties2.size()) returntrue; if (aProperties1.size() > aProperties2.size()) returnfalse;
// Compare index. If equal, compare value if( rProp1.mnIndex < rProp2.mnIndex ) returntrue; if( rProp1.mnIndex > rProp2.mnIndex ) returnfalse;
if( rProp1.mnIndex != -1 )
{ // Now compare values if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
XML_TYPE_BUILDIN_CMP ) != 0 )
{ // simple type ( binary compare ) if ( comphelper::anyLess(rProp1.maValue, rProp2.maValue) ) returntrue; if ( comphelper::anyLess(rProp2.maValue, rProp1.maValue ) ) returnfalse;
}
}
}
returnfalse;
}
/** fills the given attribute list with the items in the given set void SvXMLExportPropertyMapper::exportXML( SvXMLAttributeList& rAttrList, const ::std::vector< XMLPropertyState >& rProperties, const SvXMLUnitConverter& rUnitConverter, const SvXMLNamespaceMap& rNamespaceMap, sal_uInt16 nFlags ) const { _exportXML( rAttrList, rProperties, rUnitConverter, rNamespaceMap, nFlags, 0, -1, -1 ); }
/** this method is called for every item that has the
MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ void SvXMLExportPropertyMapper::handleSpecialItem(
comphelper::AttributeList& rAttrList, const XMLPropertyState& rProperty, const SvXMLUnitConverter& rUnitConverter, const SvXMLNamespaceMap& rNamespaceMap, const ::std::vector< XMLPropertyState > *pProperties,
sal_uInt32 nIdx ) const
{
OSL_ENSURE(mpImpl->mxNextMapper.is(), "special item not handled in xml export"); if (mpImpl->mxNextMapper.is())
mpImpl->mxNextMapper->handleSpecialItem(
rAttrList, rProperty, rUnitConverter, rNamespaceMap, pProperties, nIdx);
}
/** this method is called for every item that has the
MID_FLAG_ELEMENT_EXPORT flag set */ void SvXMLExportPropertyMapper::handleElementItem(
SvXMLExport& rExport, const XMLPropertyState& rProperty,
SvXmlExportFlags nFlags, const ::std::vector< XMLPropertyState > *pProperties,
sal_uInt32 nIdx ) const
{
OSL_ENSURE(mpImpl->mxNextMapper.is(), "element item not handled in xml export"); if (mpImpl->mxNextMapper.is())
mpImpl->mxNextMapper->handleElementItem(rExport, rProperty, nFlags, pProperties, nIdx);
}
// protected methods
/** fills the given attribute list with the items in the given set */ void SvXMLExportPropertyMapper::_exportXML(
sal_uInt16 nPropType, sal_uInt16& rPropTypeFlags,
comphelper::AttributeList& rAttrList, const ::std::vector< XMLPropertyState >& rProperties, const SvXMLUnitConverter& rUnitConverter, const SvXMLNamespaceMap& rNamespaceMap,
std::vector<sal_uInt16>* pIndexArray,
sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx ) const
{ const sal_uInt32 nCount = rProperties.size();
sal_uInt32 nIndex = 0;
// if the prefix isn't defined yet or has another meaning, // we have to redefine it now.
sal_uInt16 nKey = pNamespaceMap->GetKeyByPrefix( sPrefix ); if( USHRT_MAX == nKey || pNamespaceMap->GetNameByKey( nKey ) != sNamespace )
{ bool bAddNamespace = false; if( USHRT_MAX == nKey )
{ // The prefix is unused, so it is sufficient // to add it to the namespace map.
bAddNamespace = true;
} else
{ // check if there is a prefix registered for the // namespace URI
nKey = pNamespaceMap->GetKeyByName( sNamespace ); if( XML_NAMESPACE_UNKNOWN == nKey )
{ // There is no prefix for the namespace, so // we have to generate one and have to add it.
sal_Int32 n=0;
OUString sOrigPrefix( sPrefix ); do
{
sPrefix = sOrigPrefix + OUString::number( ++n );
nKey = pNamespaceMap->GetKeyByPrefix( sPrefix );
} while( nKey != USHRT_MAX );
bAddNamespace = true;
} else
{ // If there is a prefix for the namespace, // we reuse that.
sPrefix = pNamespaceMap->GetPrefixByKey( nKey );
} // In any case, the attribute name has to be adapted.
sAttribName = sPrefix + ":" + rAttribName.subView(nColonPos+1);
}
// We don't seem to have a generic mechanism to write an attribute in the extension // namespace in case of certain attribute values only, so do this manually.
sal_Int8 nExtendedStatus
= CheckExtendedNamespace(mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex),
aValue, rUnitConverter.getSaneDefaultVersion()); if (nExtendedStatus == -1) return; if (nExtendedStatus == 1)
sName = rNamespaceMap.GetQNameByKey(
XML_NAMESPACE_LO_EXT, mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex));
rAttrList.AddAttribute( sName, aValue );
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.