/* -*- 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 .
*/
usingnamespace ::xmloff::token; using ::com::sun::star::lang::IllegalArgumentException; using ::com::sun::star::lang::WrappedTargetException; using ::com::sun::star::beans::UnknownPropertyException; using ::com::sun::star::beans::PropertyVetoException;
void SvXMLImportPropertyMapper::ChainImportMapper(
std::unique_ptr< SvXMLImportPropertyMapper> rMapper )
{ // add map entries from rMapper to current map
maPropMapper->AddMapperEntry( rMapper->getPropertySetMapper() ); // rMapper uses the same map as 'this'
rMapper->maPropMapper = maPropMapper;
auto pNewMapper = rMapper.get(); // set rMapper as last mapper in current chain
SvXMLImportPropertyMapper* pNext = mxNextMapper.get(); if( pNext )
{ while( pNext->mxNextMapper)
pNext = pNext->mxNextMapper.get();
pNext->mxNextMapper = std::move(rMapper);
} else
mxNextMapper = std::move(rMapper);
// if rMapper was already chained, correct // map pointer of successors
pNext = pNewMapper;
const css::uno::Sequence< css::xml::Attribute > unknownAttribs = xAttrList->getUnknownAttributes(); for (const css::xml::Attribute& rAttribute : unknownAttribs)
{ int nSepIndex = rAttribute.Name.indexOf(SvXMLImport::aNamespaceSeparator); if (nSepIndex != -1)
{ // If it's an unknown attribute in a known namespace, ignore it.
OUString aPrefix = rAttribute.Name.copy(0, nSepIndex); auto nKey = rNamespaceMap.GetKeyByPrefix(aPrefix); if (nKey != USHRT_MAX && !(nKey & XML_NAMESPACE_UNKNOWN_FLAG)) continue;
}
// index of actual property map entry // This looks very strange, but it works well: // If the start index is 0, the new value will become -1, and // GetEntryIndex will start searching with position 0. // Otherwise GetEntryIndex will start with the next position specified.
sal_Int32 nIndex = nStartIdx - 1;
sal_uInt32 nFlags = 0; // flags of actual property map entry bool bFound = false;
// for better error reporting: this should be set true if no // warning is needed bool bNoWarning = false;
do
{ // find an entry for this attribute
nIndex = maPropMapper->GetEntryIndex( nPrefix, aLocalName,
nPropType, nIndex );
if( nIndex > -1 && nIndex < nEndIdx )
{ // create a XMLPropertyState with an empty value
// no warning if handleSpecialItem added properties
bNoWarning |= ( nOldSize != rProperties.size() );
}
// no warning if we found could set the item. This // 'remembers' bSet across multi properties.
bNoWarning |= bSet;
// store the property in the given vector if( bSet )
{ if( nReference == -1 )
rProperties.push_back( aNewProperty ); else
rProperties[nReference] = std::move(aNewProperty);
} else
{ // warn about unknown value. Unless it's a // multi property: Then we get another chance // to set the value. if( !bNoWarning &&
((nFlags & MID_FLAG_MULTI_PROPERTY) == 0) )
{
m_rImport.SetError( XMLERROR_FLAG_WARNING |
XMLERROR_STYLE_ATTR_VALUE,
{ rAttrName, sValue } );
}
}
}
bFound = true; continue;
}
// find map entry and create new property state if( -1 == nIndex )
{ switch( nPropType )
{ case XML_TYPE_PROP_CHART:
nIndex = maPropMapper->FindEntryIndex( "ChartUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) ); break; case XML_TYPE_PROP_PARAGRAPH:
nIndex = maPropMapper->FindEntryIndex( "ParaUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) ); break; case XML_TYPE_PROP_TEXT:
nIndex = maPropMapper->FindEntryIndex( "TextUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) ); break; default: break;
} // other property type or property not found if( -1 == nIndex )
nIndex = maPropMapper->FindEntryIndex( "UserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
}
// #106963#; use userdefined attribute only if it is in the specified property range if( nIndex != -1 && nIndex >= nStartIdx && nIndex < nEndIdx)
{
XMLPropertyState aNewProperty( nIndex, Any(xAttrContainer) );
// push it on our stack so we export it later
rProperties.push_back( aNewProperty );
}
}
/** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */ bool SvXMLImportPropertyMapper::handleSpecialItem(
XMLPropertyState& rProperty,
std::vector< XMLPropertyState >& rProperties, const OUString& rValue, const SvXMLUnitConverter& rUnitConverter, const SvXMLNamespaceMap& rNamespaceMap ) const
{
OSL_ENSURE( mxNextMapper, "unsupported special item in xml import" ); if( mxNextMapper ) return mxNextMapper->handleSpecialItem( rProperty, rProperties, rValue,
rUnitConverter, rNamespaceMap ); else returnfalse;
}
// handle no-property and special items if( ( pSpecialContextIds != nullptr ) &&
( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
{ // maybe it's one of our special context ids?
sal_Int16 nContextId = maPropMapper->GetEntryContextId(nIdx);
for ( sal_Int32 n = 0;
pSpecialContextIds[n].nContextID != -1;
n++ )
{ // found: set index in pSpecialContextIds array if ( pSpecialContextIds[n].nContextID == nContextId )
{
pSpecialContextIds[n].nIndex = i; break; // early out
}
}
}
}
// iterate over property states that we want to set for( sal_Int32 i=0; i < nCount; i++ )
{ const XMLPropertyState& rProp = rProperties[i];
sal_Int32 nIdx = rProp.mnIndex;
// disregard property state if it has an invalid index if( -1 == nIdx ) continue;
// handle no-property and special items if( ( pSpecialContextIds != nullptr ) &&
( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
{ // maybe it's one of our special context ids?
sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
for ( sal_Int32 n = 0;
pSpecialContextIds[n].nContextID != -1;
n++ )
{ // found: set index in pSpecialContextIds array if ( pSpecialContextIds[n].nContextID == nContextId )
{
pSpecialContextIds[n].nIndex = i; break; // early out
}
}
}
}
// property pairs structure stores names + values of properties to be set.
std::vector<PropertyPair> aPropertyPairs;
aPropertyPairs.reserve( nCount );
// iterate over property states that we want to set
sal_Int32 i; for( i = 0; i < nCount; i++ )
{ const XMLPropertyState& rProp = rProperties[i];
sal_Int32 nIdx = rProp.mnIndex;
// disregard property state if it has an invalid index if( -1 == nIdx ) continue;
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.