/* -*- 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 .
*/
// retrieve the service name if ( !sControlImplementation.isEmpty() )
{
OUString sOOoImplementationName; const sal_uInt16 nImplPrefix = GetImport().GetNamespaceMap().GetKeyByAttrValueQName( sControlImplementation, &sOOoImplementationName );
m_sServiceName = ( nImplPrefix == XML_NAMESPACE_OOO ) ? sOOoImplementationName : sControlImplementation;
}
if ( m_sServiceName.isEmpty() )
m_sServiceName = determineDefaultServiceName();
// create the object *now*. This allows setting properties in the various handleAttribute methods. // (Though currently not all code is migrated to this pattern, most attributes are still handled // by remembering the value (via implPushBackPropertyValue), and setting the correct property value // later (in OControlImport::StartElement).)
m_xElement = createElement(); if ( m_xElement.is() )
m_xInfo = m_xElement->getPropertySetInfo();
// call the base class
OPropertyImport::startFastElement( nElement, _rxAttrList );
}
void OElementImport::endFastElement(sal_Int32 )
{
OSL_ENSURE(m_xElement.is(), "OElementImport::EndElement: invalid element created!"); if (!m_xElement.is()) return;
// apply the non-generic properties
implApplySpecificProperties();
// set the generic properties
implApplyGenericProperties();
// set the style properties if ( m_pStyleElement && m_xElement.is() )
{
Reference< XPropertySet > xPropTranslation = new OGridColumnPropertyTranslator( Reference< XMultiPropertySet >( m_xElement, UNO_QUERY ) ); const_cast< XMLTextStyleContext* >( m_pStyleElement )->FillPropertySet( xPropTranslation );
const OUString sNumberStyleName = m_pStyleElement->GetDataStyleName( ); if ( !sNumberStyleName.isEmpty() ) // the style also has a number (sub) style
m_rContext.applyControlNumberStyle( m_xElement, sNumberStyleName );
}
// insert the element into the parent container if (m_sName.isEmpty())
{
OSL_FAIL("OElementImport::EndElement: did not find a name attribute!");
m_sName = implGetDefaultName();
}
if (m_xParentContainer.is())
m_xParentContainer->insertByName(m_sName, Any(m_xElement));
LEAVE_LOG_CONTEXT( );
}
void OElementImport::implApplySpecificProperties()
{ if ( m_aValues.empty() ) return;
// set all the properties we collected #if OSL_DEBUG_LEVEL > 0 // check if the object has all the properties // (We do this in the non-pro version only. Doing it all the time would be too much expensive) if ( m_xInfo.is() )
{ for ( constauto& rCheck : m_aValues )
{
OSL_ENSURE(m_xInfo->hasPropertyByName(rCheck.Name),
OStringBuffer("OElementImport::implApplySpecificProperties: read a property (" +
OUStringToOString(rCheck.Name, RTL_TEXTENCODING_ASCII_US) + ") which does not exist on the element!").getStr());
}
} #endif
// set the properties const Reference< XMultiPropertySet > xMultiProps(m_xElement, UNO_QUERY); bool bSuccess = false; if (xMultiProps.is())
{ // translate our properties so that the XMultiPropertySet can handle them
// sort our property value array so that we can use it in a setPropertyValues
::std::sort( m_aValues.begin(), m_aValues.end(), PropertyValueLess());
// the names
Sequence< OUString > aNames(m_aValues.size());
OUString* pNames = aNames.getArray(); // the values
Sequence< Any > aValues(m_aValues.size());
Any* pValues = aValues.getArray(); // copy
try
{
xMultiProps->setPropertyValues(aNames, aValues);
bSuccess = true;
} catch(const Exception&)
{
DBG_UNHANDLED_EXCEPTION("xmloff.forms");
OSL_FAIL("OElementImport::implApplySpecificProperties: could not set the properties (using the XMultiPropertySet)!");
}
}
if (bSuccess) return;
// no XMultiPropertySet or setting all properties at once failed for ( constauto& rPropValues : m_aValues )
{ // this try/catch here is expensive, but because this is just a fallback which should normally not be // used it's acceptable this way ... try
{
m_xElement->setPropertyValue(rPropValues.Name, rPropValues.Value);
} catch(const Exception&)
{
DBG_UNHANDLED_EXCEPTION("xmloff.forms");
OSL_FAIL(OStringBuffer("OElementImport::implApplySpecificProperties: could not set the property \"" +
OUStringToOString(rPropValues.Name, RTL_TEXTENCODING_ASCII_US) + "\"!").getStr());
}
}
}
void OElementImport::implApplyGenericProperties()
{ if ( m_aGenericValues.empty() ) return;
// PropertyValueArray::iterator aEnd = m_aGenericValues.end(); for ( auto& rPropValues : m_aGenericValues )
{ // check property type for numeric types before setting // the property try
{ // if such a property does not yet exist at the element, create it if necessary constbool bExistentProperty = m_xInfo->hasPropertyByName( rPropValues.Name ); if ( !bExistentProperty )
{ if ( !xDynamicProperties.is() )
{
SAL_WARN( "xmloff", "OElementImport::implApplyGenericProperties: encountered an unknown property ("
<< rPropValues.Name << "), but component is no PropertyBag!"); continue;
}
// re-fetch the PropertySetInfo
m_xInfo = m_xElement->getPropertySetInfo();
}
// determine the type of the value (source for the following conversion)
TypeClass eValueTypeClass = rPropValues.Value.getValueTypeClass(); constbool bValueIsSequence = TypeClass_SEQUENCE == eValueTypeClass; if ( bValueIsSequence )
{
uno::Type aSimpleType( getSequenceElementType( rPropValues.Value.getValueType() ) );
eValueTypeClass = aSimpleType.getTypeClass();
}
// determine the type of the property (target for the following conversion) const Property aProperty( m_xInfo->getPropertyByName( rPropValues.Name ) );
TypeClass ePropTypeClass = aProperty.Type.getTypeClass(); constbool bPropIsSequence = TypeClass_SEQUENCE == ePropTypeClass; if( bPropIsSequence )
{
uno::Type aSimpleType( ::comphelper::getSequenceElementType( aProperty.Type ) );
ePropTypeClass = aSimpleType.getTypeClass();
}
if ( bPropIsSequence != bValueIsSequence )
{
OSL_FAIL( "OElementImport::implImportGenericProperties: either both value and property should be a sequence, or none of them!" ); continue;
}
if ( bValueIsSequence )
{
Sequence< Any > aXMLValueList;
rPropValues.Value >>= aXMLValueList; // just skip this part if empty sequence if (!aXMLValueList.getLength()) continue;
SAL_WARN_IF( eValueTypeClass != TypeClass_ANY, "xmloff", "OElementImport::implApplyGenericProperties: only ANYs should have been imported as generic list property!" ); // (OPropertyImport should produce only Sequencer< Any >, since it cannot know the real type
SAL_WARN_IF( ePropTypeClass != TypeClass_SHORT, "xmloff", "OElementImport::implApplyGenericProperties: conversion to sequences other than 'sequence< short >' not implemented, yet!" );
std::transform(std::cbegin(aXMLValueList), std::cend(aXMLValueList), aPropertyValueList.getArray(),
[](const Any& rXMLValue) -> sal_Int16 { // only value sequences of numeric types implemented so far. double nVal( 0 );
OSL_VERIFY( rXMLValue >>= nVal ); returnstatic_cast< sal_Int16 >( nVal );
});
m_xElement->setPropertyValue( rPropValues.Name, rPropValues.Value );
} catch(const Exception&)
{
DBG_UNHANDLED_EXCEPTION("xmloff.forms");
OSL_FAIL(OStringBuffer("OElementImport::EndElement: could not set the property \"" +
OUStringToOString(rPropValues.Name, RTL_TEXTENCODING_ASCII_US) + "\"!").getStr());
}
}
}
OUString OElementImport::implGetDefaultName() const
{ // no optimization here. If this method gets called, the XML stream did not contain a name for the // element, which is a heavy error. So in this case we don't care for performance static constexpr OUString sUnnamedName = u"unnamed"_ustr;
OSL_ENSURE(m_xParentContainer.is(), "OElementImport::implGetDefaultName: no parent container!"); if (!m_xParentContainer.is()) return sUnnamedName;
Sequence< OUString > aNames = m_xParentContainer->getElementNames();
for (sal_Int32 i=0; i<32768; ++i) // the limit is nearly arbitrary...
{ // assemble the new name (suggestion)
OUString sReturn = sUnnamedName + OUString::number(i); // check the existence (this is the bad performance part...) if (comphelper::findValue(aNames, sReturn) == -1) // not found the name return sReturn;
}
OSL_FAIL("OElementImport::implGetDefaultName: did not find a free name!"); return sUnnamedName;
}
PropertyGroups::const_iterator OElementImport::impl_matchPropertyGroup( const PropertyGroups& i_propertyGroups ) const
{
ENSURE_OR_RETURN( m_xInfo.is(), "OElementImport::impl_matchPropertyGroup: no property set info!", i_propertyGroups.end() );
bool OElementImport::handleAttribute(sal_Int32 nElement, const OUString& _rValue)
{ auto nLocal = nElement & TOKEN_MASK; if ( nLocal == XML_CONTROL_IMPLEMENTATION ) // ignore this, it has already been handled in OElementImport::StartElement returntrue;
if ( nLocal == XML_NAME )
{ if ( m_sName.isEmpty() ) // remember the name for later use in EndElement
m_sName = _rValue; returntrue;
}
// maybe it's the style attribute? if ( nLocal == XML_TEXT_STYLE_NAME )
{ const SvXMLStyleContext* pStyleContext = m_rContext.getStyleElement( _rValue );
OSL_ENSURE( pStyleContext, "OElementImport::handleAttribute: do not know the style!" ); // remember the element for later usage.
m_pStyleElement = dynamic_cast<const XMLTextStyleContext*>( pStyleContext ); returntrue;
}
if ( m_bImplicitGenericAttributeHandling ) if ( tryGenericAttribute( nElement, _rValue ) ) returntrue;
// let the base class handle it return OPropertyImport::handleAttribute( nElement, _rValue);
}
Reference< XPropertySet > OElementImport::createElement()
{
Reference< XPropertySet > xReturn; if (!m_sServiceName.isEmpty())
{
Reference< XComponentContext > xContext = m_rFormImport.getGlobalContext().GetComponentContext();
Reference< XInterface > xPure = xContext->getServiceManager()->createInstanceWithContext(m_sServiceName, xContext);
OSL_ENSURE(xPure.is(),
OStringBuffer("OElementImport::createElement: service factory gave me no object (service name: " +
OUStringToOString(m_sServiceName, RTL_TEXTENCODING_ASCII_US) + ")!").getStr());
xReturn.set(xPure, UNO_QUERY); if (autoconst props = Reference<css::beans::XPropertySet>(xPure, css::uno::UNO_QUERY))
{ try {
props->setPropertyValue(
u"Referer"_ustr, css::uno::Any(m_rFormImport.getGlobalContext().GetBaseURL()));
} catch (css::uno::Exception &) {
TOOLS_INFO_EXCEPTION("xmloff.forms", "setPropertyValue Referer failed");
}
}
} else
OSL_FAIL("OElementImport::createElement: no service name to create an element!");
return xReturn;
}
void OElementImport::registerEvents(const Sequence< ScriptEventDescriptor >& _rEvents)
{
OSL_ENSURE(m_xElement.is(), "OElementImport::registerEvents: no element to register events for!");
m_rEventManager.registerEvents(m_xElement, _rEvents);
}
void OElementImport::simulateDefaultedAttribute(sal_Int32 nElement, const OUString& _rPropertyName, const OUString& _pAttributeDefault)
{
OSL_ENSURE( m_xInfo.is(), "OPropertyImport::simulateDefaultedAttribute: the component should be more gossipy about it's properties!" );
// get the class id of our element
sal_Int16 nClassId = FormComponentType::CONTROL;
m_xElement->getPropertyValue(PROPERTY_CLASSID) >>= nClassId;
// translate the value properties we collected in handleAttributes for ( auto& rValueProps : m_aValueProperties )
{ bool bSuccess = false; switch (rValueProps.Handle)
{ case PROPID_VALUE: case PROPID_CURRENT_VALUE:
{ // get the property names if (!bRetrievedValues)
{
getValuePropertyNames(m_eElementType, nClassId, pCurrentValueProperty, pValueProperty); if ( pCurrentValueProperty.isEmpty() && pValueProperty.isEmpty() )
{
SAL_WARN( "xmloff.forms", "OControlImport::StartElement: illegal value property names!" ); break;
}
bRetrievedValues = true;
} if ( PROPID_VALUE == rValueProps.Handle && pValueProperty.isEmpty() )
{
SAL_WARN( "xmloff.forms", "OControlImport::StartElement: the control does not have a value property!"); break;
}
if ( PROPID_CURRENT_VALUE == rValueProps.Handle && pCurrentValueProperty.isEmpty() )
{
SAL_WARN( "xmloff.forms", "OControlImport::StartElement: the control does not have a current-value property!"); break;
}
// transfer the name if (PROPID_VALUE == rValueProps.Handle)
rValueProps.Name = pValueProperty; else
rValueProps.Name = pCurrentValueProperty;
bSuccess = true;
} break; case PROPID_MIN_VALUE: case PROPID_MAX_VALUE:
{ // get the property names if (!bRetrievedValueLimits)
{
getValueLimitPropertyNames(nClassId, pMinValueProperty, pMaxValueProperty); if ( pMinValueProperty.isEmpty() || pMaxValueProperty.isEmpty() )
{
SAL_WARN( "xmloff.forms", "OControlImport::StartElement: illegal value limit property names!" ); break;
}
bRetrievedValueLimits = true;
}
OSL_ENSURE((PROPID_MIN_VALUE != rValueProps.Handle) || !pMinValueProperty.isEmpty(), "OControlImport::StartElement: the control does not have a value property!");
OSL_ENSURE((PROPID_MAX_VALUE != rValueProps.Handle) || !pMaxValueProperty.isEmpty(), "OControlImport::StartElement: the control does not have a current-value property!");
// transfer the name if (PROPID_MIN_VALUE == rValueProps.Handle)
rValueProps.Name = pMinValueProperty; else
rValueProps.Name = pMaxValueProperty;
bSuccess = true;
} break;
}
if ( !bSuccess ) continue;
// translate the value
implTranslateValueProperty(m_xInfo, rValueProps); // add the property to the base class' array
implPushBackPropertyValue(rValueProps);
}
// retrieve the type of the property
Property aProp = _rxPropInfo->getPropertyByName(_rPropValue.Name); // the untranslated string value as read in handleAttribute
OUString sValue; bool bSuccess = _rPropValue.Value >>= sValue;
OSL_ENSURE(bSuccess, "OControlImport::implTranslateValueProperty: supposed to be called with non-translated string values!");
if (TypeClass_ANY == aProp.Type.getTypeClass())
{ // we have exactly 2 properties where this type class is allowed:
SAL_WARN_IF(
_rPropValue.Name != PROPERTY_EFFECTIVE_VALUE
&& _rPropValue.Name != PROPERTY_EFFECTIVE_DEFAULT, "xmloff", "OControlImport::implTranslateValueProperty: invalid property type/name combination, Any and " << _rPropValue.Name);
// Both properties are allowed to have a double or a string value, // so first try to convert the string into a number double nValue; if (::sax::Converter::convertDouble(nValue, sValue))
_rPropValue.Value <<= nValue; else
_rPropValue.Value <<= sValue;
} else
_rPropValue.Value = PropertyConversion::convertString(aProp.Type, sValue);
}
// register our control with its id if (!m_sControlId.isEmpty())
m_rFormImport.registerControlId(m_xElement, m_sControlId); // it's allowed to have no control id. In this case we're importing a column
// one more pre-work to do: // when we set default values, then by definition the respective value is set // to this default value, too. This means if the sequence contains for example // a DefaultText value, then the Text will be affected by this, too. // In case the Text is not part of the property sequence (or occurs _before_ // the DefaultText, which can happen for other value/default-value property names), // this means that the Text (the value property) is incorrectly imported.
bool bRestoreValuePropertyValue = false;
Any aValuePropertyValue;
sal_Int16 nClassId = FormComponentType::CONTROL; try
{ // get the class id of our element
m_xElement->getPropertyValue(PROPERTY_CLASSID) >>= nClassId;
} catch( const Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.forms", "caught an exception while retrieving the class id!");
}
OUString pValueProperty;
OUString pDefaultValueProperty;
getRuntimeValuePropertyNames(m_eElementType, nClassId, pValueProperty, pDefaultValueProperty); if ( !pDefaultValueProperty.isEmpty() && !pValueProperty.isEmpty() )
{ bool bNonDefaultValuePropertyValue = false; // is the "value property" part of the sequence?
// look up this property in our sequence for ( constauto& rCheck : m_aValues )
{ if ( rCheck.Name == pDefaultValueProperty )
bRestoreValuePropertyValue = true; elseif ( rCheck.Name == pValueProperty )
{
bNonDefaultValuePropertyValue = true; // we need to restore the value property we found here, nothing else
aValuePropertyValue = rCheck.Value;
}
}
if ( bRestoreValuePropertyValue && !bNonDefaultValuePropertyValue )
{ // found it -> need to remember (and restore) the "value property value", which is not set explicitly try
{
aValuePropertyValue = m_xElement->getPropertyValue( pValueProperty );
} catch( const Exception& )
{
TOOLS_WARN_EXCEPTION( "xmloff.forms", "caught an exception while retrieving the current value property!");
}
}
}
// let the base class set all the values
OElementImport::endFastElement(nElement);
// restore the "value property value", if necessary if ( bRestoreValuePropertyValue && !pValueProperty.isEmpty() )
{ try
{
m_xElement->setPropertyValue( pValueProperty, aValuePropertyValue );
} catch( const Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.forms", "caught an exception while restoring the value property!");
}
}
// the external cell binding, if applicable if ( m_xElement.is() && !m_sBoundCellAddress.isEmpty() )
doRegisterCellValueBinding( m_sBoundCellAddress );
// XForms binding, if applicable if ( m_xElement.is() && !m_sBindingID.isEmpty() )
doRegisterXFormsValueBinding( m_sBindingID );
// XForms list binding, if applicable if ( m_xElement.is() && !m_sListBindingID.isEmpty() )
doRegisterXFormsListBinding( m_sListBindingID );
// XForms submission, if applicable if ( m_xElement.is() && !m_sSubmissionID.isEmpty() )
doRegisterXFormsSubmission( m_sSubmissionID );
}
// the base class should have created the control, so we can register it if ( !m_sReferringControls.isEmpty() )
m_rFormImport.registerControlReferences(m_xElement, m_sReferringControls);
}
bool OPasswordImport::handleAttribute(sal_Int32 nElement, const OUString& _rValue)
{ staticconst sal_Int32 s_nEchoCharAttributeName = OAttributeMetaData::getSpecialAttributeToken(SCAFlags::EchoChar); if ((nElement & TOKEN_MASK) == s_nEchoCharAttributeName)
{ // need a special handling for the EchoChar property
PropertyValue aEchoChar;
aEchoChar.Name = PROPERTY_ECHOCHAR;
OSL_ENSURE(_rValue.getLength() == 1, "OPasswordImport::handleAttribute: invalid echo char attribute!"); // we ourself should not have written values other than of length 1 if (_rValue.getLength() >= 1)
aEchoChar.Value <<= static_cast<sal_Int16>(_rValue[0]); else
aEchoChar.Value <<= sal_Int16(0);
implPushBackPropertyValue(aEchoChar); returntrue;
} return OControlImport::handleAttribute(nElement, _rValue);
}
bool ORadioImport::handleAttribute(sal_Int32 nElement, const OUString& _rValue)
{ // need special handling for the State & CurrentState properties: // they're stored as booleans, but expected to be int16 properties staticconst sal_Int32 nCurrentSelectedAttributeName = OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::CurrentSelected); staticconst sal_Int32 nSelectedAttributeName = OAttributeMetaData::getCommonControlAttributeToken(CCAFlags::Selected); if ( (nElement & TOKEN_MASK) == nCurrentSelectedAttributeName
|| (nElement & TOKEN_MASK) == nSelectedAttributeName
)
{ const OAttribute2Property::AttributeAssignment* pProperty = m_rContext.getAttributeMap().getAttributeTranslation(nElement & TOKEN_MASK);
assert(pProperty && "ORadioImport::handleAttribute: invalid property map!"); if (pProperty)
{ const Any aBooleanValue( PropertyConversion::convertString(pProperty->aPropertyType, _rValue, pProperty->pEnumMap) );
// create and store a new PropertyValue
PropertyValue aNewValue;
aNewValue.Name = pProperty->sPropertyName;
aNewValue.Value <<= static_cast<sal_Int16>(::cppu::any2bool(aBooleanValue));
// need to make the URL absolute if // * it's the image-data attribute // * it's the target-location attribute, and we're dealing with an object which has the respective property bool bMakeAbsolute =
(nElement & TOKEN_MASK) == s_nImageDataAttributeName
|| ( (nElement & TOKEN_MASK) == s_nTargetLocationAttributeName
&& ( ( OControlElement::BUTTON == m_eElementType )
|| ( OControlElement::IMAGE == m_eElementType )
)
);
if ( m_xCursor.is() )
xTextImportHelper->SetCursor( m_xCursor );
} if ( m_xCursor.is() )
{
m_bEncounteredTextPara = true; return xTextImportHelper->CreateTextChildContext( m_rContext.getGlobalContext(), nElement, xAttrList );
}
} else
{ // in theory, we could accumulate all the text portions (without formatting), // and set it as Text property at the model ...
}
}
}
// handle the convert-empty-to-null attribute, whose default is different from the property default // unfortunately, different classes are imported by this class ('cause they're represented by the // same XML element), though not all of them know this property. // So we have to do a check ... if (m_xElement.is() && m_xInfo.is() && m_xInfo->hasPropertyByName(PROPERTY_EMPTY_IS_NULL) )
simulateDefaultedAttribute(OAttributeMetaData::getDatabaseAttributeToken(DAFlags::ConvertEmpty), PROPERTY_EMPTY_IS_NULL, u"false"_ustr);
}
void OTextLikeImport::removeRedundantCurrentValue()
{ if ( !m_bEncounteredTextPara ) return;
// In case the text is written in the text:p elements, we need to ignore what we read as // current-value attribute, since it's redundant. // fortunately, OElementImport tagged the value property with the PROPID_CURRENT_VALUE // handle, so we do not need to determine the name of our value property here // (normally, it should be "Text", since no other controls than the edit field should // have the text:p elements)
PropertyValueArray::iterator aValuePropertyPos = ::std::find_if(
m_aValues.begin(),
m_aValues.end(),
EqualHandle( PROPID_CURRENT_VALUE )
); if ( aValuePropertyPos != m_aValues.end() )
{
OSL_ENSURE( aValuePropertyPos->Name == PROPERTY_TEXT, "OTextLikeImport::EndElement: text:p was present, but our value property is *not* 'Text'!" ); if ( aValuePropertyPos->Name == PROPERTY_TEXT )
{
m_aValues.erase(aValuePropertyPos);
}
}
// additionally, we need to set the "RichText" property of our element to sal_True // (the presence of the text:p is used as indicator for the value of the RichText property) bool bHasRichTextProperty = false; if ( m_xInfo.is() )
bHasRichTextProperty = m_xInfo->hasPropertyByName( PROPERTY_RICH_TEXT );
OSL_ENSURE( bHasRichTextProperty, "OTextLikeImport::EndElement: text:p, but no rich text control?" ); if ( bHasRichTextProperty )
m_xElement->setPropertyValue( PROPERTY_RICH_TEXT, Any( true ) ); // Note that we do *not* set the RichText property (in case our element has one) to sal_False here // since this is the default of this property, anyway.
}
void OTextLikeImport::adjustDefaultControlProperty()
{ // In OpenOffice.org 2.0, we changed the implementation of the css.form.component.TextField (the model of a text field control), // so that it now uses another default control. So if we encounter a text field where the *old* default // control property is writing, we are not allowed to use it
PropertyValueArray::iterator aDefaultControlPropertyPos = ::std::find_if(
m_aValues.begin(),
m_aValues.end(),
EqualName( u"DefaultControl"_ustr )
); if ( aDefaultControlPropertyPos != m_aValues.end() )
{
OUString sDefaultControl;
OSL_VERIFY( aDefaultControlPropertyPos->Value >>= sDefaultControl ); if ( sDefaultControl == "stardiv.one.form.control.Edit" )
{ // complete remove this property value from the array. Today's "default value" of the "DefaultControl" // property is sufficient
m_aValues.erase(aDefaultControlPropertyPos);
}
}
}
// let the base class do the stuff
OControlImport::endFastElement(nElement);
// some cleanups
rtl::Reference < XMLTextImportHelper > xTextImportHelper( m_rContext.getGlobalContext().GetTextImport() ); if ( m_xCursor.is() )
{ // delete the newline which has been imported erroneously // TODO (fs): stole this code somewhere - why don't we fix the text import??
m_xCursor->gotoEnd( false );
m_xCursor->goLeft( 1, true );
m_xCursor->setString( OUString() );
css::uno::Reference< css::xml::sax::XFastContextHandler > OListAndComboImport::createFastChildContext(
sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& _rxAttrList )
{ // is it the "option" sub tag of a listbox ? if ((nElement & TOKEN_MASK) == XML_OPTION) returnnew OListOptionImport(GetImport(), this);
// is it the "item" sub tag of a combobox ? if ((nElement & TOKEN_MASK) == XML_ITEM) returnnew OComboItemImport(GetImport(), this);
if (OControlElement::COMBOBOX == m_eElementType)
{ // for the auto-completion // the attribute default does not equal the property default, so in case we did not read this attribute, // we have to simulate it
simulateDefaultedAttribute( OAttributeMetaData::getSpecialAttributeToken( SCAFlags::AutoCompletion ), PROPERTY_AUTOCOMPLETE, u"false"_ustr);
// same for the convert-empty-to-null attribute, which's default is different from the property default
--> --------------------
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.