diff options
author | Andre Fischer <andre.f.fischer <Andre Fischer<andre.f.fischer@oracle.com> | 2011-01-26 11:11:11 +0100 |
---|---|---|
committer | Andre Fischer <andre.f.fischer <Andre Fischer<andre.f.fischer@oracle.com> | 2011-01-26 11:11:11 +0100 |
commit | cf054f6ef9d88233703678889bc3eb3efe516ec3 (patch) | |
tree | 1d2e2e6166cab18b3cec15dafa144557c63c5a8d /xmloff/source/forms | |
parent | 312cafc472e4ac74a045baf123476a2457c15185 (diff) | |
parent | d646413d464dc5d6518f87daa8538cd0c600797f (diff) |
impress195: rebase to DEV300 m98
Diffstat (limited to 'xmloff/source/forms')
31 files changed, 1667 insertions, 316 deletions
diff --git a/xmloff/source/forms/controlelement.cxx b/xmloff/source/forms/controlelement.cxx index 84a74fe44a8b..748cf68c23ed 100644 --- a/xmloff/source/forms/controlelement.cxx +++ b/xmloff/source/forms/controlelement.cxx @@ -59,6 +59,8 @@ namespace xmloff case HIDDEN: return "hidden"; case GRID: return "grid"; case VALUERANGE: return "value-range"; + case TIME: return "time"; + case DATE: return "date"; default: return "generic-control"; } diff --git a/xmloff/source/forms/controlelement.hxx b/xmloff/source/forms/controlelement.hxx index 1816710fb4dc..d226f218f426 100644 --- a/xmloff/source/forms/controlelement.hxx +++ b/xmloff/source/forms/controlelement.hxx @@ -63,6 +63,8 @@ namespace xmloff GRID, VALUERANGE, GENERIC_CONTROL, + TIME, + DATE, UNKNOWN // must be the last element }; diff --git a/xmloff/source/forms/controlpropertymap.cxx b/xmloff/source/forms/controlpropertymap.cxx index 8e81c2a7e19c..aed0b8c4e190 100644 --- a/xmloff/source/forms/controlpropertymap.cxx +++ b/xmloff/source/forms/controlpropertymap.cxx @@ -27,7 +27,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/xmltoken.hxx> #include <xmloff/maptype.hxx> #include <xmloff/xmltypes.hxx> diff --git a/xmloff/source/forms/elementexport.cxx b/xmloff/source/forms/elementexport.cxx index 115b06c4c2ad..1126583f9a45 100644 --- a/xmloff/source/forms/elementexport.cxx +++ b/xmloff/source/forms/elementexport.cxx @@ -30,12 +30,13 @@ #include "elementexport.hxx" #include "strings.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include "eventexport.hxx" #include "formenums.hxx" #include "formcellbinding.hxx" #include "formcellbinding.hxx" -#include "xformsexport.hxx" +#include "xmloff/xformsexport.hxx" +#include "property_meta_data.hxx" /** === begin UNO includes === **/ #include <com/sun/star/text/XText.hpp> @@ -321,6 +322,9 @@ namespace xmloff #endif } + // "new-style" properties ... + exportGenericHandlerAttributes(); + // common control attributes exportCommonControlAttributes(); @@ -474,6 +478,84 @@ namespace xmloff } //--------------------------------------------------------------------- + void OControlExport::exportGenericHandlerAttributes() + { + const Sequence< Property > aProperties = m_xPropertyInfo->getProperties(); + for ( const Property* prop = aProperties.getConstArray(); + prop != aProperties.getConstArray() + aProperties.getLength(); + ++prop + ) + { + try + { + // see if this property can already be handled with an IPropertyHandler (which, on the long + // term, should be the case for most, if not all, properties) + const PropertyDescription* propDescription = metadata::getPropertyDescription( prop->Name ); + if ( propDescription == NULL ) + continue; + + // let the factory provide the concrete handler. Note that caching, if desired, is the task + // of the factory + PPropertyHandler handler = (*propDescription->factory)( propDescription->propertyId ); + ENSURE_OR_CONTINUE( handler.get() != NULL, + "OControlExport::exportGenericHandlerAttributes: invalid property handler provided by the factory!" ); + + ::rtl::OUString attributeValue; + if ( propDescription->propertyGroup == NO_GROUP ) + { + // that's a property which has a direct mapping to an attribute + if ( !shouldExportProperty( prop->Name ) ) + // TODO: in the future, we surely need a more sophisticated approach to this, involving the property + // handler, or the property description + { + exportedProperty( prop->Name ); + continue; + } + + const Any propValue = m_xProps->getPropertyValue( prop->Name ); + attributeValue = handler->getAttributeValue( propValue ); + } + else + { + // that's a property which is part of a group of properties, whose values, in their entity, comprise + // a single attribute value + + // retrieve the descriptions of all other properties which add to the attribute value + PropertyDescriptionList descriptions; + metadata::getPropertyGroup( propDescription->propertyGroup, descriptions ); + + // retrieve the values for all those properties + PropertyValues aValues; + for ( PropertyDescriptionList::iterator desc = descriptions.begin(); + desc != descriptions.end(); + ++desc + ) + { + // TODO: XMultiPropertySet? + const Any propValue = m_xProps->getPropertyValue( (*desc)->propertyName ); + aValues[ (*desc)->propertyId ] = propValue; + } + + // let the handler translate into an XML attribute value + attributeValue = handler->getAttributeValue( aValues ); + } + + AddAttribute( + propDescription->attribute.namespacePrefix, + token::GetXMLToken( propDescription->attribute.attributeToken ), + attributeValue + ); + + exportedProperty( prop->Name ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + + //--------------------------------------------------------------------- void OControlExport::exportCommonControlAttributes() { size_t i=0; @@ -1380,21 +1462,35 @@ namespace xmloff m_nClassId = FormComponentType::CONTROL; DBG_CHECK_PROPERTY( PROPERTY_CLASSID, sal_Int16 ); m_xProps->getPropertyValue(PROPERTY_CLASSID) >>= m_nClassId; + bool knownType = false; switch (m_nClassId) { case FormComponentType::DATEFIELD: + m_eType = DATE; + knownType = true; + // NO BREAK case FormComponentType::TIMEFIELD: + if ( !knownType ) + { + m_eType = TIME; + knownType = true; + } + m_nIncludeSpecial |= SCA_VALIDATION; + // NO BREAK case FormComponentType::NUMERICFIELD: case FormComponentType::CURRENCYFIELD: case FormComponentType::PATTERNFIELD: - m_eType = FORMATTED_TEXT; + if ( !knownType ) + { + m_eType = FORMATTED_TEXT; + knownType = true; + } // NO BREAK case FormComponentType::TEXTFIELD: { // it's some kind of edit. To know which type we need further investigation - if (FORMATTED_TEXT != m_eType) - { // not coming from the previous cases which had a class id .ne. TEXTFIELD - + if ( !knownType ) + { // check if it's a formatted field if (m_xPropertyInfo->hasPropertyByName(PROPERTY_FORMATKEY)) { @@ -1430,14 +1526,21 @@ namespace xmloff m_eType = TEXT; } } + knownType = true; } - // attributes which are common to all the four types: + // attributes which are common to all the types: // common attributes m_nIncludeCommon = - CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_VALUE | + CCA_NAME | CCA_SERVICE_NAME | CCA_DISABLED | CCA_PRINTABLE | CCA_TAB_INDEX | CCA_TAB_STOP | CCA_TITLE; + if ( ( m_nClassId != FormComponentType::DATEFIELD ) + && ( m_nClassId != FormComponentType::TIMEFIELD ) + ) + // date and time field values are handled differently nowadays + m_nIncludeCommon |= CCA_VALUE; + // database attributes m_nIncludeDatabase = DA_DATA_FIELD | DA_INPUT_REQUIRED; @@ -1461,8 +1564,7 @@ namespace xmloff // max and min values and validation: if (FORMATTED_TEXT == m_eType) { // in general all controls represented as formatted-text have these props - if (FormComponentType::PATTERNFIELD != m_nClassId) - // but the PatternField does not have value limits + if ( FormComponentType::PATTERNFIELD != m_nClassId ) // except the PatternField m_nIncludeSpecial |= SCA_MAX_VALUE | SCA_MIN_VALUE; if (FormComponentType::TEXTFIELD != m_nClassId) @@ -1471,8 +1573,13 @@ namespace xmloff } // if it's not a password field or rich text control, the CurrentValue needs to be stored, too - if ( PASSWORD != m_eType ) + if ( ( PASSWORD != m_eType ) + && ( DATE != m_eType ) + && ( TIME != m_eType ) + ) + { m_nIncludeCommon |= CCA_CURRENT_VALUE; + } } break; diff --git a/xmloff/source/forms/elementexport.hxx b/xmloff/source/forms/elementexport.hxx index d9504271ac04..a8981f0a1fea 100644 --- a/xmloff/source/forms/elementexport.hxx +++ b/xmloff/source/forms/elementexport.hxx @@ -161,6 +161,13 @@ namespace xmloff */ void exportSubTags() throw (::com::sun::star::uno::Exception); + /** adds the attributes which are handled via generic IPropertyHandlers + + <p>In the future, this really should be *all* attribiutes, instead of this shitload of + hand-crafted code we have currently ...</p> + */ + void exportGenericHandlerAttributes(); + /** adds common control attributes to the XMLExport context given <p>The attribute list of the context is not cleared initially, this is the responsibility of the caller.</p> diff --git a/xmloff/source/forms/elementimport.cxx b/xmloff/source/forms/elementimport.cxx index b946c4a20941..c010b666e552 100644 --- a/xmloff/source/forms/elementimport.cxx +++ b/xmloff/source/forms/elementimport.cxx @@ -28,22 +28,21 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" -#include <algorithm> #include "elementimport.hxx" -#include <xmloff/xmlimp.hxx> -#include <xmloff/nmspmap.hxx> -#include <xmloff/xmluconv.hxx> +#include "xmloff/xmlimp.hxx" +#include "xmloff/nmspmap.hxx" +#include "xmloff/xmluconv.hxx" #include "strings.hxx" #include "callbacks.hxx" #include "attriblistmerge.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include "eventimport.hxx" -#include <xmloff/txtstyli.hxx> +#include "xmloff/txtstyli.hxx" #include "formenums.hxx" -#include <xmloff/xmltoken.hxx> +#include "xmloff/xmltoken.hxx" #include "gridcolumnproptranslator.hxx" -#include <comphelper/extract.hxx> -#include <comphelper/types.hxx> +#include "property_description.hxx" +#include "property_meta_data.hxx" /** === begin UNO includes === **/ #include <com/sun/star/text/XText.hpp> @@ -54,9 +53,13 @@ #include <com/sun/star/beans/XPropertyContainer.hpp> #include <com/sun/star/beans/PropertyAttribute.hpp> /** === end UNO includes === **/ + #include <tools/urlobj.hxx> +#include <tools/diagnose_ex.h> #include <tools/time.hxx> #include <rtl/logfile.hxx> +#include <comphelper/extract.hxx> +#include <comphelper/types.hxx> #include <algorithm> #include <functional> @@ -157,6 +160,7 @@ namespace xmloff ,m_rEventManager(_rEventManager) ,m_pStyleElement( NULL ) ,m_xParentContainer(_rxParentContainer) + ,m_bImplicitGenericAttributeHandling( true ) { OSL_ENSURE(m_xParentContainer.is(), "OElementImport::OElementImport: invalid parent container!"); } @@ -167,17 +171,41 @@ namespace xmloff } //--------------------------------------------------------------------- + ::rtl::OUString OElementImport::determineDefaultServiceName() const + { + return ::rtl::OUString(); + } + + //--------------------------------------------------------------------- void OElementImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList) { ENTER_LOG_CONTEXT( "xmloff::OElementImport - importing one element" ); - // call the base class. This should give us enough information (especially the service name) - // to create our UNO element - OPropertyImport::StartElement(_rxAttrList); - // create the element + const SvXMLNamespaceMap& rMap = m_rContext.getGlobalContext().GetNamespaceMap(); + const ::rtl::OUString sImplNameAttribute = rMap.GetQNameByKey( XML_NAMESPACE_FORM, GetXMLToken( XML_CONTROL_IMPLEMENTATION ) ); + const ::rtl::OUString sControlImplementation = _rxAttrList->getValueByName( sImplNameAttribute ); + + // retrieve the service name + if ( sControlImplementation.getLength() > 0 ) + { + ::rtl::OUString sOOoImplementationName; + const sal_uInt16 nImplPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sControlImplementation, &sOOoImplementationName ); + m_sServiceName = ( nImplPrefix == XML_NAMESPACE_OOO ) ? sOOoImplementationName : sControlImplementation; + } + + if ( !m_sServiceName.getLength() ) + 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_xInfo.is() && m_xElement.is() ) + if ( m_xElement.is() ) m_xInfo = m_xElement->getPropertySetInfo(); + + // call the base class + OPropertyImport::StartElement( _rxAttrList ); } //--------------------------------------------------------------------- @@ -197,26 +225,61 @@ namespace xmloff 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 ::rtl::OUString sNumberStyleName = const_cast< XMLTextStyleContext* >( m_pStyleElement )->GetDataStyleName( ); + if ( sNumberStyleName.getLength() ) + // the style also has a number (sub) style + m_rContext.applyControlNumberStyle( m_xElement, sNumberStyleName ); + } + + // insert the element into the parent container + if (!m_sName.getLength()) + { + OSL_ENSURE(sal_False, "OElementImport::EndElement: did not find a name attribute!"); + m_sName = implGetDefaultName(); + } + + m_xParentContainer->insertByName(m_sName, makeAny(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 much to expensive) if ( m_xInfo.is() ) { - PropertyValueArray::iterator aEnd = m_aValues.end(); + PropertyValueArray::const_iterator aEnd = m_aValues.end(); for ( PropertyValueArray::iterator aCheck = m_aValues.begin(); aCheck != aEnd; ++aCheck ) { OSL_ENSURE(m_xInfo->hasPropertyByName(aCheck->Name), - ::rtl::OString("OElementImport::EndElement: read a property (") + ::rtl::OString("OElementImport::implApplySpecificProperties: read a property (") += ::rtl::OString(aCheck->Name.getStr(), aCheck->Name.getLength(), RTL_TEXTENCODING_ASCII_US) += ::rtl::OString(") which does not exist on the element!")); } } #endif - OSL_ENSURE(!m_aValues.empty(), "OElementImport::EndElement: no properties read!"); // set the properties const Reference< XMultiPropertySet > xMultiProps(m_xElement, UNO_QUERY); @@ -253,7 +316,7 @@ namespace xmloff } catch(Exception&) { - OSL_ENSURE(sal_False, "OElementImport::EndElement: could not set the properties (using the XMultiPropertySet)!"); + OSL_ENSURE(sal_False, "OElementImport::implApplySpecificProperties: could not set the properties (using the XMultiPropertySet)!"); } } @@ -274,42 +337,16 @@ namespace xmloff catch(Exception&) { OSL_ENSURE(sal_False, - ::rtl::OString("OElementImport::EndElement: could not set the property \"") + ::rtl::OString("OElementImport::implApplySpecificProperties: could not set the property \"") += ::rtl::OString(aPropValues->Name.getStr(), aPropValues->Name.getLength(), RTL_TEXTENCODING_ASCII_US) += ::rtl::OString("\"!")); } } } - - // set the generic properties - implImportGenericProperties(); - - // 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 ::rtl::OUString sNumberStyleName = const_cast< XMLTextStyleContext* >( m_pStyleElement )->GetDataStyleName( ); - if ( sNumberStyleName.getLength() ) - // the style also has a number (sub) style - m_rContext.applyControlNumberStyle( m_xElement, sNumberStyleName ); - } - - // insert the element into the parent container - if (!m_sName.getLength()) - { - OSL_ENSURE(sal_False, "OElementImport::EndElement: did not find a name attribute!"); - m_sName = implGetDefaultName(); - } - - m_xParentContainer->insertByName(m_sName, makeAny(m_xElement)); - LEAVE_LOG_CONTEXT( ); } //--------------------------------------------------------------------- - void OElementImport::implImportGenericProperties() + void OElementImport::implApplyGenericProperties() { if ( m_aGenericValues.empty() ) return; @@ -334,7 +371,7 @@ namespace xmloff if ( !xDynamicProperties.is() ) { #if OSL_DEBUG_LEVEL > 0 - ::rtl::OString aMessage( "OElementImport::implImportGenericProperties: encountered an unknown property (" ); + ::rtl::OString aMessage( "OElementImport::implApplyGenericProperties: encountered an unknown property (" ); aMessage += ::rtl::OUStringToOString( aPropValues->Name, RTL_TEXTENCODING_ASCII_US ); aMessage += "), but component is no PropertyBag!"; OSL_ENSURE( false, aMessage.getStr() ); @@ -352,7 +389,7 @@ namespace xmloff m_xInfo = m_xElement->getPropertySetInfo(); } - // determine the type of the value (source forthe following conversion) + // determine the type of the value (source for the following conversion) TypeClass eValueTypeClass = aPropValues->Value.getValueTypeClass(); const sal_Bool bValueIsSequence = TypeClass_SEQUENCE == eValueTypeClass; if ( bValueIsSequence ) @@ -361,7 +398,7 @@ namespace xmloff eValueTypeClass = aSimpleType.getTypeClass(); } - // determine the type of the property (target forthe following conversion) + // determine the type of the property (target for the following conversion) const Property aProperty( m_xInfo->getPropertyByName( aPropValues->Name ) ); TypeClass ePropTypeClass = aProperty.Type.getTypeClass(); const sal_Bool bPropIsSequence = TypeClass_SEQUENCE == ePropTypeClass; @@ -373,18 +410,18 @@ namespace xmloff if ( bPropIsSequence != bValueIsSequence ) { - OSL_ENSURE( false, "OElementImport::implImportGenericProperties: either both value and property should be a sequence, or none of them!" ); + OSL_ENSURE( false, "OElementImport::implApplyGenericProperties: either both value and property should be a sequence, or none of them!" ); continue; } if ( bValueIsSequence ) { OSL_ENSURE( eValueTypeClass == TypeClass_ANY, - "OElementImport::implImportGenericProperties: only ANYs should have been imported as generic list property!" ); + "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 OSL_ENSURE( ePropTypeClass == TypeClass_SHORT, - "OElementImport::implImportGenericProperties: conversion to sequences other than 'sequence< short >' not implemented, yet!" ); + "OElementImport::implApplyGenericProperties: conversion to sequences other than 'sequence< short >' not implemented, yet!" ); Sequence< Any > aXMLValueList; aPropValues->Value >>= aXMLValueList; @@ -427,13 +464,13 @@ namespace xmloff aPropValues->Value <<= static_cast< sal_Int64 >( nVal ); break; default: - OSL_ENSURE( false, "OElementImport::implImportGenericProperties: unsupported value type!" ); + OSL_ENSURE( false, "OElementImport::implApplyGenericProperties: unsupported value type!" ); break; } } break; default: - OSL_ENSURE( false, "OElementImport::implImportGenericProperties: non-double values not supported!" ); + OSL_ENSURE( false, "OElementImport::implApplyGenericProperties: non-double values not supported!" ); break; } } @@ -484,38 +521,117 @@ namespace xmloff } //--------------------------------------------------------------------- - void OElementImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + PropertyGroups::const_iterator OElementImport::impl_matchPropertyGroup( const PropertyGroups& i_propertyGroups ) const { - if (!m_sServiceName.getLength() && - token::IsXMLToken( _rLocalName, token::XML_CONTROL_IMPLEMENTATION)) - { // it's the service name + ENSURE_OR_RETURN( m_xInfo.is(), "OElementImport::impl_matchPropertyGroup: no property set info!", i_propertyGroups.end() ); - ::rtl::OUString sImplName; - const sal_uInt16 nImplPrefix = - GetImport().GetNamespaceMap().GetKeyByAttrName( _rValue, - &sImplName ); - m_sServiceName = XML_NAMESPACE_OOO==nImplPrefix ? sImplName - :_rValue; + for ( PropertyGroups::const_iterator group = i_propertyGroups.begin(); + group != i_propertyGroups.end(); + ++group + ) + { + bool missingProp = false; + for ( PropertyDescriptionList::const_iterator prop = group->begin(); + prop != group->end(); + ++prop + ) + { + if ( !m_xInfo->hasPropertyByName( (*prop)->propertyName ) ) + { + missingProp = true; + break; + } + } + + if ( missingProp ) + // try next group + continue; + + return group; } - else + + return i_propertyGroups.end(); + } + + //--------------------------------------------------------------------- + bool OElementImport::tryGenericAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ) + { + // the generic approach (which I hope all props will be migrated to, on the medium term): property handlers + const AttributeDescription attribute( metadata::getAttributeDescription( _nNamespaceKey, _rLocalName ) ); + if ( attribute.attributeToken != XML_TOKEN_INVALID ) { - if (!m_sName.getLength() && - token::IsXMLToken( _rLocalName, token::XML_NAME)) - // remember the name for later use in EndElement - m_sName = _rValue; + PropertyGroups propertyGroups; + metadata::getPropertyGroupList( attribute, propertyGroups ); + const PropertyGroups::const_iterator pos = impl_matchPropertyGroup( propertyGroups ); + if ( pos == propertyGroups.end() ) + return false; - // maybe it's the style attribute? - if ( token::IsXMLToken( _rLocalName, token::XML_TEXT_STYLE_NAME ) ) + do { - const SvXMLStyleContext* pStyleContext = m_rContext.getStyleElement( _rValue ); - OSL_ENSURE( pStyleContext, "OPropertyImport::handleAttribute: do not know the style!" ); - // remember the element for later usage. - m_pStyleElement = PTR_CAST( XMLTextStyleContext, pStyleContext ); + const PropertyDescriptionList& rProperties( *pos ); + const PropertyDescription* first = *rProperties.begin(); + ENSURE_OR_BREAK( first != NULL, "OElementImport::handleAttribute: invalid property description!" ); + const PPropertyHandler handler = (*first->factory)( first->propertyId ); + ENSURE_OR_BREAK( handler.get() != NULL, "OElementImport::handleAttribute: invalid property handler!" ); + + PropertyValues aValues; + for ( PropertyDescriptionList::const_iterator propDesc = rProperties.begin(); + propDesc != rProperties.end(); + ++propDesc + ) + { + aValues[ (*propDesc)->propertyId ] = Any(); + } + if ( handler->getPropertyValues( _rValue, aValues ) ) + { + for ( PropertyDescriptionList::const_iterator propDesc = rProperties.begin(); + propDesc != rProperties.end(); + ++propDesc + ) + { + implPushBackPropertyValue( (*propDesc)->propertyName, aValues[ (*propDesc)->propertyId ] ); + } + } } - else - // let the base class handle it - OPropertyImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); + while ( false ); + + // handled + return true; } + return false; + } + + //--------------------------------------------------------------------- + bool OElementImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + { + if ( token::IsXMLToken( _rLocalName, token::XML_CONTROL_IMPLEMENTATION ) ) + // ignore this, it has already been handled in OElementImport::StartElement + return true; + + if ( token::IsXMLToken( _rLocalName, token::XML_NAME ) ) + { + if ( !m_sName.getLength() ) + // remember the name for later use in EndElement + m_sName = _rValue; + return true; + } + + // maybe it's the style attribute? + if ( token::IsXMLToken( _rLocalName, token::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 = PTR_CAST( XMLTextStyleContext, pStyleContext ); + return true; + } + + if ( m_bImplicitGenericAttributeHandling ) + if ( tryGenericAttribute( _nNamespaceKey, _rLocalName, _rValue ) ) + return true; + + // let the base class handle it + return OPropertyImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); } //--------------------------------------------------------------------- @@ -553,7 +669,7 @@ namespace xmloff { ::rtl::OUString sLocalAttrName = ::rtl::OUString::createFromAscii(_pAttributeName); if ( !encounteredAttribute( sLocalAttrName ) ) - handleAttribute( XML_NAMESPACE_FORM, sLocalAttrName, ::rtl::OUString::createFromAscii( _pAttributeDefault ) ); + OSL_VERIFY( handleAttribute( XML_NAMESPACE_FORM, sLocalAttrName, ::rtl::OUString::createFromAscii( _pAttributeDefault ) ) ); } } @@ -566,6 +682,7 @@ namespace xmloff :OElementImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer) ,m_eElementType(OControlElement::UNKNOWN) { + disableImplicitGenericAttributeHandling(); } //--------------------------------------------------------------------- @@ -574,6 +691,38 @@ namespace xmloff :OElementImport(_rImport, _rEventManager, _nPrefix, _rName, _rxParentContainer) ,m_eElementType(_eType) { + disableImplicitGenericAttributeHandling(); + } + + //--------------------------------------------------------------------- + ::rtl::OUString OControlImport::determineDefaultServiceName() const + { + const sal_Char* pServiceName = NULL; + switch ( m_eElementType ) + { + case OControlElement::TEXT: + case OControlElement::TEXT_AREA: + case OControlElement::PASSWORD: pServiceName = "com.sun.star.form.component.TextField"; break; + case OControlElement::FILE: pServiceName = "com.sun.star.form.component.FileControl"; break; + case OControlElement::FORMATTED_TEXT: pServiceName = "com.sun.star.form.component.FormattedField"; break; + case OControlElement::FIXED_TEXT: pServiceName = "com.sun.star.form.component.FixedText"; break; + case OControlElement::COMBOBOX: pServiceName = "com.sun.star.form.component.ComboBox"; break; + case OControlElement::LISTBOX: pServiceName = "com.sun.star.form.component.ListBox"; break; + case OControlElement::BUTTON: pServiceName = "com.sun.star.form.component.CommandButton"; break; + case OControlElement::IMAGE: pServiceName = "com.sun.star.form.component.ImageButton"; break; + case OControlElement::CHECKBOX: pServiceName = "com.sun.star.form.component.CheckBox"; break; + case OControlElement::RADIO: pServiceName = "com.sun.star.form.component.RadioButton"; break; + case OControlElement::FRAME: pServiceName = "com.sun.star.form.component.GroupBox"; break; + case OControlElement::IMAGE_FRAME: pServiceName = "com.sun.star.form.component.DatabaseImageControl"; break; + case OControlElement::HIDDEN: pServiceName = "com.sun.star.form.component.HiddenControl"; break; + case OControlElement::GRID: pServiceName = "com.sun.star.form.component.GridControl"; break; + case OControlElement::TIME: pServiceName = "com.sun.star.form.component.DateField"; break; + case OControlElement::DATE: pServiceName = "com.sun.star.form.component.TimeField"; break; + default: break; + } + if ( pServiceName != NULL ) + return ::rtl::OUString::createFromAscii( pServiceName ); + return ::rtl::OUString(); } //--------------------------------------------------------------------- @@ -584,7 +733,7 @@ namespace xmloff } //--------------------------------------------------------------------- - void OControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + bool OControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { static const sal_Char* pLinkedCellAttributeName = OAttributeMetaData::getBindingAttributeName(BA_LINKED_CELL); @@ -601,66 +750,84 @@ namespace xmloff m_sControlId = _rValue; } } + return true; } - else if ( _rLocalName.equalsAscii( pLinkedCellAttributeName ) ) + + if ( _rLocalName.equalsAscii( pLinkedCellAttributeName ) ) { // it's the address of a spreadsheet cell m_sBoundCellAddress = _rValue; + return true; } - else if ( _nNamespaceKey == XML_NAMESPACE_XFORMS && IsXMLToken( _rLocalName, XML_BIND ) ) + + if ( _nNamespaceKey == XML_NAMESPACE_XFORMS && IsXMLToken( _rLocalName, XML_BIND ) ) { m_sBindingID = _rValue; + return true; } - else if ( _nNamespaceKey == XML_NAMESPACE_FORM && IsXMLToken( _rLocalName, XML_XFORMS_LIST_SOURCE ) ) + + if ( _nNamespaceKey == XML_NAMESPACE_FORM && IsXMLToken( _rLocalName, XML_XFORMS_LIST_SOURCE ) ) { m_sListBindingID = _rValue; + return true; } - else if ( (_nNamespaceKey == XML_NAMESPACE_FORM && IsXMLToken( _rLocalName, XML_XFORMS_SUBMISSION ) ) || - ( _nNamespaceKey == XML_NAMESPACE_XFORMS && IsXMLToken( _rLocalName, XML_SUBMISSION ) ) ) + + if ( ( ( _nNamespaceKey == XML_NAMESPACE_FORM ) + && IsXMLToken( _rLocalName, XML_XFORMS_SUBMISSION ) + ) + || ( ( _nNamespaceKey == XML_NAMESPACE_XFORMS ) + && IsXMLToken( _rLocalName, XML_SUBMISSION ) + ) + ) { m_sSubmissionID = _rValue; + return true; } - else + + if ( OElementImport::tryGenericAttribute( _nNamespaceKey, _rLocalName, _rValue ) ) + return true; + + static const sal_Char* pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE); + static const sal_Char* pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_VALUE); + static const sal_Char* pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MIN_VALUE); + static const sal_Char* pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MAX_VALUE); + static const sal_Char* pRepeatDelayAttributeName = OAttributeMetaData::getSpecialAttributeName( SCA_REPEAT_DELAY ); + + sal_Int32 nHandle = -1; + if ( _rLocalName.equalsAscii( pValueAttributeName ) ) + nHandle = PROPID_VALUE; + else if ( _rLocalName.equalsAscii( pCurrentValueAttributeName ) ) + nHandle = PROPID_CURRENT_VALUE; + else if ( _rLocalName.equalsAscii( pMinValueAttributeName ) ) + nHandle = PROPID_MIN_VALUE; + else if ( _rLocalName.equalsAscii( pMaxValueAttributeName ) ) + nHandle = PROPID_MAX_VALUE; + if ( nHandle != -1 ) { - static const sal_Char* pValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_VALUE); - static const sal_Char* pCurrentValueAttributeName = OAttributeMetaData::getCommonControlAttributeName(CCA_CURRENT_VALUE); - static const sal_Char* pMinValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MIN_VALUE); - static const sal_Char* pMaxValueAttributeName = OAttributeMetaData::getSpecialAttributeName(SCA_MAX_VALUE); - static const sal_Char* pRepeatDelayAttributeName = OAttributeMetaData::getSpecialAttributeName( SCA_REPEAT_DELAY ); - - sal_Int32 nHandle = -1; - if ( _rLocalName.equalsAscii( pValueAttributeName ) ) - nHandle = PROPID_VALUE; - else if ( _rLocalName.equalsAscii( pCurrentValueAttributeName ) ) - nHandle = PROPID_CURRENT_VALUE; - else if ( _rLocalName.equalsAscii( pMinValueAttributeName ) ) - nHandle = PROPID_MIN_VALUE; - else if ( _rLocalName.equalsAscii( pMaxValueAttributeName ) ) - nHandle = PROPID_MAX_VALUE; - if ( nHandle != -1 ) + // for the moment, simply remember the name and the value + PropertyValue aProp; + aProp.Name = _rLocalName; + aProp.Handle = nHandle; + aProp.Value <<= _rValue; + m_aValueProperties.push_back(aProp); + return true; + } + + if ( _rLocalName.equalsAscii( pRepeatDelayAttributeName ) ) + { + ::Time aTime; + sal_Int32 nFractions = 0; + if ( SvXMLUnitConverter::convertTimeDuration( _rValue, aTime, &nFractions ) ) { - // for the moment, simply remember the name and the value PropertyValue aProp; - aProp.Name = _rLocalName; - aProp.Handle = nHandle; - aProp.Value <<= _rValue; - m_aValueProperties.push_back(aProp); - } - else if ( _rLocalName.equalsAscii( pRepeatDelayAttributeName ) ) - { - ::Time aTime; - sal_Int32 nFractions = 0; - if ( SvXMLUnitConverter::convertTimeDuration( _rValue, aTime, &nFractions ) ) - { - PropertyValue aProp; - aProp.Name = PROPERTY_REPEAT_DELAY; - aProp.Value <<= (sal_Int32)( ( ( aTime.GetMSFromTime() / 1000 ) * 1000 ) + nFractions ); + aProp.Name = PROPERTY_REPEAT_DELAY; + aProp.Value <<= (sal_Int32)( ( ( aTime.GetMSFromTime() / 1000 ) * 1000 ) + nFractions ); - implPushBackPropertyValue(aProp); - } + implPushBackPropertyValue(aProp); } - else - OElementImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); + return true; } + + return OElementImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); } //--------------------------------------------------------------------- @@ -713,6 +880,7 @@ namespace xmloff ++aValueProps ) { + bool bSuccess = false; switch (aValueProps->Handle) { case PROPID_VALUE: @@ -722,6 +890,7 @@ namespace xmloff if (!bRetrievedValues) { getValuePropertyNames(m_eElementType, nClassId, pCurrentValueProperty, pValueProperty); + ENSURE_OR_BREAK( pCurrentValueProperty && pValueProperty, "OControlImport::StartElement: illegal value property names!" ); bRetrievedValues = sal_True; } OSL_ENSURE((PROPID_VALUE != aValueProps->Handle) || pValueProperty, @@ -734,6 +903,7 @@ namespace xmloff aValueProps->Name = ::rtl::OUString::createFromAscii(pValueProperty); else aValueProps->Name = ::rtl::OUString::createFromAscii(pCurrentValueProperty); + bSuccess = true; } break; case PROPID_MIN_VALUE: @@ -743,6 +913,7 @@ namespace xmloff if (!bRetrievedValueLimits) { getValueLimitPropertyNames(nClassId, pMinValueProperty, pMaxValueProperty); + ENSURE_OR_BREAK( pMinValueProperty && pMaxValueProperty, "OControlImport::StartElement: illegal value limit property names!" ); bRetrievedValueLimits = sal_True; } OSL_ENSURE((PROPID_MIN_VALUE != aValueProps->Handle) || pMinValueProperty, @@ -755,10 +926,14 @@ namespace xmloff aValueProps->Name = ::rtl::OUString::createFromAscii(pMinValueProperty); else aValueProps->Name = ::rtl::OUString::createFromAscii(pMaxValueProperty); + bSuccess = true; } break; } + if ( !bSuccess ) + continue; + // translate the value implTranslateValueProperty(m_xInfo, *aValueProps); // add the property to the base class' array @@ -980,7 +1155,7 @@ namespace xmloff } //--------------------------------------------------------------------- - void OImagePositionImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, + bool OImagePositionImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ) { if ( _rLocalName == GetXMLToken( XML_IMAGE_POSITION ) ) @@ -990,16 +1165,19 @@ namespace xmloff _rValue, OEnumMapper::getEnumMap( OEnumMapper::epImagePosition ) ) >>= m_nImagePosition ); m_bHaveImagePosition = sal_True; + return true; } - else if ( _rLocalName == GetXMLToken( XML_IMAGE_ALIGN ) ) + + if ( _rLocalName == GetXMLToken( XML_IMAGE_ALIGN ) ) { OSL_VERIFY( PropertyConversion::convertString( m_rContext.getGlobalContext(), ::getCppuType( &m_nImageAlign ), _rValue, OEnumMapper::getEnumMap( OEnumMapper::epImageAlign ) ) >>= m_nImageAlign ); + return true; } - else - OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); + + return OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); } //--------------------------------------------------------------------- @@ -1047,14 +1225,16 @@ namespace xmloff } //--------------------------------------------------------------------- - void OReferredControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, + bool OReferredControlImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { static const ::rtl::OUString s_sReferenceAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getCommonControlAttributeName(CCA_FOR)); if (_rLocalName == s_sReferenceAttributeName) + { m_sReferringControls = _rValue; - else - OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); + return true; + } + return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); } //===================================================================== @@ -1068,7 +1248,7 @@ namespace xmloff } //--------------------------------------------------------------------- - void OPasswordImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + bool OPasswordImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { static const ::rtl::OUString s_sEchoCharAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getSpecialAttributeName(SCA_ECHO_CHAR)); if (_rLocalName == s_sEchoCharAttributeName) @@ -1083,9 +1263,9 @@ namespace xmloff else aEchoChar.Value <<= (sal_Int16)0; implPushBackPropertyValue(aEchoChar); + return true; } - else - OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); + return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); } //===================================================================== @@ -1099,7 +1279,7 @@ namespace xmloff } //--------------------------------------------------------------------- - void ORadioImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + bool ORadioImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { // need special handling for the State & CurrentState properties: // they're stored as booleans, but expected to be int16 properties @@ -1122,9 +1302,9 @@ namespace xmloff implPushBackPropertyValue(aNewValue); } + return true; } - else - OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); + return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); } //===================================================================== @@ -1138,7 +1318,7 @@ namespace xmloff } //--------------------------------------------------------------------- - void OURLReferenceImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + bool OURLReferenceImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { static const sal_Char* s_pTargetLocationAttributeName = OAttributeMetaData::getCommonControlAttributeName( CCA_TARGET_LOCATION ); static const sal_Char* s_pImageDataAttributeName = OAttributeMetaData::getCommonControlAttributeName( CCA_IMAGE_DATA ); @@ -1157,18 +1337,18 @@ namespace xmloff if ( bMakeAbsolute && ( _rValue.getLength() > 0 ) ) { // make a global URL out of the local one - ::rtl::OUString sAdjustedValue; - // only resolve image related url - // we don't want say form url targets to be resolved - // using ResolveGraphicObjectURL - if ( 0 == _rLocalName.compareToAscii( s_pImageDataAttributeName ) ) - sAdjustedValue = m_rContext.getGlobalContext().ResolveGraphicObjectURL( _rValue, FALSE ); - else - sAdjustedValue = m_rContext.getGlobalContext().GetAbsoluteReference( _rValue ); - OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, sAdjustedValue ); + ::rtl::OUString sAdjustedValue; + // only resolve image related url + // we don't want say form url targets to be resolved + // using ResolveGraphicObjectURL + if ( 0 == _rLocalName.compareToAscii( s_pImageDataAttributeName ) ) + sAdjustedValue = m_rContext.getGlobalContext().ResolveGraphicObjectURL( _rValue, FALSE ); + else + sAdjustedValue = m_rContext.getGlobalContext().GetAbsoluteReference( _rValue ); + return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, sAdjustedValue ); } - else - OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); + + return OImagePositionImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); } //===================================================================== @@ -1205,14 +1385,14 @@ namespace xmloff } //--------------------------------------------------------------------- - void OValueRangeImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ) + bool OValueRangeImport::handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ) { if ( _rLocalName.equalsAscii( OAttributeMetaData::getSpecialAttributeName( SCA_STEP_SIZE ) ) ) { GetImport().GetMM100UnitConverter().convertNumber( m_nStepSizeValue, _rValue ); + return true; } - else - OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); + return OControlImport::handleAttribute( _nNamespaceKey, _rLocalName, _rValue ); } //--------------------------------------------------------------------- @@ -1535,7 +1715,7 @@ namespace xmloff } //--------------------------------------------------------------------- - void OListAndComboImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + bool OListAndComboImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { static const sal_Char* pListSourceAttributeName = OAttributeMetaData::getDatabaseAttributeName(DA_LIST_SOURCE); if ( _rLocalName.equalsAscii(pListSourceAttributeName) ) @@ -1560,12 +1740,16 @@ namespace xmloff } implPushBackPropertyValue( aListSource ); + return true; } - else if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_CELL_RANGE ) ) ) + + if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_CELL_RANGE ) ) ) { m_sCellListSource = _rValue; + return true; } - else if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_LINKING_TYPE ) ) ) + + if ( _rLocalName.equalsAscii( OAttributeMetaData::getBindingAttributeName( BA_LIST_LINKING_TYPE ) ) ) { sal_Int16 nLinkageType = 0; PropertyConversion::convertString( @@ -1576,9 +1760,10 @@ namespace xmloff ) >>= nLinkageType; m_bLinkWithIndexes = ( nLinkageType != 0 ); + return true; } - else - OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); + + return OControlImport::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); } //--------------------------------------------------------------------- @@ -1776,7 +1961,9 @@ namespace xmloff || (OControlElement::FORMATTED_TEXT == _eType) || (OControlElement::CHECKBOX == _eType) || (OControlElement::LISTBOX == _eType) - || (OControlElement::COMBOBOX == _eType), + || (OControlElement::COMBOBOX == _eType) + || (OControlElement::TIME == _eType) + || (OControlElement::DATE == _eType), "OColumnWrapperImport::implCreateChildContext: invalid or unrecognized sub element!"); switch (_eType) @@ -1871,19 +2058,25 @@ namespace xmloff } //--------------------------------------------------------------------- - void OFormImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) + bool OFormImport::handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { // handle the master/details field attributes (they're way too special to let the OPropertyImport handle them) static const ::rtl::OUString s_sMasterFieldsAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getFormAttributeName(faMasterFields)); static const ::rtl::OUString s_sDetailFieldsAttributeName = ::rtl::OUString::createFromAscii(OAttributeMetaData::getFormAttributeName(faDetailFiels)); - if (s_sMasterFieldsAttributeName == _rLocalName) + if ( s_sMasterFieldsAttributeName == _rLocalName ) + { implTranslateStringListProperty(PROPERTY_MASTERFIELDS, _rValue); - else if (s_sDetailFieldsAttributeName == _rLocalName) + return true; + } + + if ( s_sDetailFieldsAttributeName == _rLocalName ) + { implTranslateStringListProperty(PROPERTY_DETAILFIELDS, _rValue); + return true; + } - else - OFormImport_Base::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); + return OFormImport_Base::handleAttribute(_nNamespaceKey, _rLocalName, _rValue); } //--------------------------------------------------------------------- diff --git a/xmloff/source/forms/elementimport.hxx b/xmloff/source/forms/elementimport.hxx index 97eb2ec950d3..3b604c752595 100644 --- a/xmloff/source/forms/elementimport.hxx +++ b/xmloff/source/forms/elementimport.hxx @@ -31,6 +31,9 @@ #include "propertyimport.hxx" #include "controlelement.hxx" #include "valueproperties.hxx" +#include "eventimport.hxx" +#include "logging.hxx" +#include "property_description.hxx" /** === begin UNO includes === **/ #include <com/sun/star/text/XTextCursor.hpp> @@ -39,9 +42,8 @@ #include <com/sun/star/form/XGridColumnFactory.hpp> #include <com/sun/star/script/XEventAttacherManager.hpp> /** === end UNO includes === **/ + #include <comphelper/stl_types.hxx> -#include "eventimport.hxx" -#include "logging.hxx" class XMLTextStyleContext; //......................................................................... @@ -83,22 +85,25 @@ namespace xmloff ,public OStackedLogging { protected: - ::rtl::OUString m_sServiceName; // the service name as extracted from the service-name attribute - ::rtl::OUString m_sName; // the name of the object (redundant, already contained in the base class' array) + ::rtl::OUString m_sServiceName; // the service name as extracted from the service-name attribute + ::rtl::OUString m_sName; // the name of the object (redundant, already contained in the base class' array) OFormLayerXMLImport_Impl& m_rFormImport; // the form import context - IEventAttacherManager& m_rEventManager; // the event attacher manager + IEventAttacherManager& m_rEventManager; // the event attacher manager const XMLTextStyleContext* m_pStyleElement; // the XML element which describes the style we encountered // while reading our element + /// the parent container to insert the new element into ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > - m_xParentContainer; - // the parent container to insert the new element into + m_xParentContainer; - ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > - m_xInfo; + /// the element we're creating. Valid after StartElement ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > - m_xElement; // the element we're creating. Valid after StartElement + m_xElement; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > + m_xInfo; + + bool m_bImplicitGenericAttributeHandling; public: /** ctor @@ -132,7 +137,7 @@ namespace xmloff virtual void EndElement(); // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); @@ -158,13 +163,28 @@ namespace xmloff */ void simulateDefaultedAttribute(const sal_Char* _pAttributeName, const ::rtl::OUString& _rPropertyName, const sal_Char* _pAttributeDefault); + /** to be called from within handleAttribute, checks whether the given attribute is covered by our generic + attribute handler mechanisms + */ + bool tryGenericAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ); + + /** controls whether |handleAttribute| implicitly calls |tryGenericAttribute|, or whether the derived class + must do this explicitly at a suitable place in its own |handleAttribute| + */ + void disableImplicitGenericAttributeHandling() { m_bImplicitGenericAttributeHandling = false; } + private: ::rtl::OUString implGetDefaultName() const; - void implImportGenericProperties(); + void implApplyGenericProperties(); + void implApplySpecificProperties(); /** sets the style properties which have been read for the element (if any) */ void implSetStyleProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxObject ); + + PropertyGroups::const_iterator impl_matchPropertyGroup( const PropertyGroups& i_propertyGroups ) const; + + virtual ::rtl::OUString determineDefaultServiceName() const; }; //===================================================================== @@ -225,7 +245,7 @@ namespace xmloff virtual void EndElement(); // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); @@ -239,6 +259,8 @@ namespace xmloff const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >& _rxPropInfo, ::com::sun::star::beans::PropertyValue& /* [in/out] */ _rPropValue); + virtual ::rtl::OUString determineDefaultServiceName() const; + /** registers the given cell address as value binding address for our element <p>The default implementation simply calls registerCellValueBinding at our import @@ -265,7 +287,6 @@ namespace xmloff // OElementImport overridables virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > createElement(); - }; // TODO: @@ -295,7 +316,7 @@ namespace xmloff const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& _rxAttrList); // OPropertyImport overridables - virtual void handleAttribute( sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ); @@ -321,7 +342,7 @@ namespace xmloff const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& _rxAttrList); // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); }; @@ -339,7 +360,7 @@ namespace xmloff ); // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); }; @@ -358,7 +379,7 @@ namespace xmloff protected: // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); }; @@ -380,7 +401,7 @@ namespace xmloff protected: // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); }; @@ -430,7 +451,7 @@ namespace xmloff const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& _rxAttrList ); // OPropertyImport overridables - virtual void handleAttribute( sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute( sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue ); }; @@ -516,7 +537,7 @@ namespace xmloff virtual void EndElement(); // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); @@ -715,7 +736,7 @@ namespace xmloff sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName); // OPropertyImport overridables - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); diff --git a/xmloff/source/forms/formattributes.cxx b/xmloff/source/forms/formattributes.cxx index 0e2ef69ab9f8..e27f03f01de9 100644 --- a/xmloff/source/forms/formattributes.cxx +++ b/xmloff/source/forms/formattributes.cxx @@ -28,7 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #include "formattributes.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/xmluconv.hxx> #include <rtl/ustrbuf.hxx> #include <rtl/logfile.hxx> diff --git a/xmloff/source/forms/formevents.cxx b/xmloff/source/forms/formevents.cxx index fcccef5065a8..5e46fbaab8d8 100644 --- a/xmloff/source/forms/formevents.cxx +++ b/xmloff/source/forms/formevents.cxx @@ -28,7 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #include "formevents.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/xmlevent.hxx> //......................................................................... diff --git a/xmloff/source/forms/formlayerexport.cxx b/xmloff/source/forms/formlayerexport.cxx index ad5ff7eb4dae..50245fad1d2a 100644 --- a/xmloff/source/forms/formlayerexport.cxx +++ b/xmloff/source/forms/formlayerexport.cxx @@ -32,7 +32,7 @@ #include <xmloff/formlayerexport.hxx> #include "strings.hxx" #include "elementexport.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/xmlexp.hxx> #include "layerexport.hxx" #include "propertyexport.hxx" diff --git a/xmloff/source/forms/formsimp.cxx b/xmloff/source/forms/formsimp.cxx index 00a745660710..bc0baaba551e 100644 --- a/xmloff/source/forms/formsimp.cxx +++ b/xmloff/source/forms/formsimp.cxx @@ -29,7 +29,7 @@ #include "precompiled_xmloff.hxx" #include <com/sun/star/xml/sax/XAttributeList.hpp> #include <xmloff/xmlimp.hxx> -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/nmspmap.hxx> #ifndef _XMLOFF_ANIMIMP_HXX diff --git a/xmloff/source/forms/handler/form_handler_factory.cxx b/xmloff/source/forms/handler/form_handler_factory.cxx new file mode 100644 index 000000000000..72a9edf38f42 --- /dev/null +++ b/xmloff/source/forms/handler/form_handler_factory.cxx @@ -0,0 +1,90 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_xmloff.hxx" + +#include "forms/form_handler_factory.hxx" +#include "vcl_date_handler.hxx" +#include "vcl_time_handler.hxx" + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + namespace + { + static PPropertyHandler s_pVCLDateHandler = NULL; + static PPropertyHandler s_pVCLTimeHandler = NULL; + } + + //================================================================================================================== + //= FormHandlerFactory + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + PPropertyHandler FormHandlerFactory::getFormPropertyHandler( const PropertyId i_propertyId ) + { + PPropertyHandler pHandler( NULL ); + + switch ( i_propertyId ) + { + case PID_DATE_MIN: + case PID_DATE_MAX: + case PID_DEFAULT_DATE: + case PID_DATE: + if ( s_pVCLDateHandler.get() == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( s_pVCLDateHandler == NULL ) + s_pVCLDateHandler = new VCLDateHandler(); + } + pHandler = s_pVCLDateHandler; + break; + + case PID_TIME_MIN: + case PID_TIME_MAX: + case PID_DEFAULT_TIME: + case PID_TIME: + if ( s_pVCLTimeHandler.get() == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( s_pVCLTimeHandler == NULL ) + s_pVCLTimeHandler = new VCLTimeHandler(); + } + pHandler = s_pVCLTimeHandler; + break; + + default: + OSL_ENSURE( false, "FormHandlerFactory::getFormPropertyHandler: unknown property ID!" ); + break; + } + + return pHandler; + } + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... diff --git a/xmloff/source/forms/handler/property_handler_base.cxx b/xmloff/source/forms/handler/property_handler_base.cxx new file mode 100644 index 000000000000..d599e0e259fe --- /dev/null +++ b/xmloff/source/forms/handler/property_handler_base.cxx @@ -0,0 +1,61 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_xmloff.hxx" + +#include "property_handler_base.hxx" + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + //================================================================================================================== + //= PropertyHandlerBase + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + PropertyHandlerBase::~PropertyHandlerBase() + { + } + + //------------------------------------------------------------------------------------------------------------------ + oslInterlockedCount SAL_CALL PropertyHandlerBase::acquire() + { + return osl_incrementInterlockedCount( &m_refCount ); + } + + //------------------------------------------------------------------------------------------------------------------ + oslInterlockedCount SAL_CALL PropertyHandlerBase::release() + { + oslInterlockedCount decremented = osl_decrementInterlockedCount( &m_refCount ); + if ( 0 == decremented ) + delete this; + return decremented; + } + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... diff --git a/xmloff/source/forms/handler/property_handler_base.hxx b/xmloff/source/forms/handler/property_handler_base.hxx new file mode 100644 index 000000000000..01f2a9e843f6 --- /dev/null +++ b/xmloff/source/forms/handler/property_handler_base.hxx @@ -0,0 +1,64 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef XMLOFF_PROPERTY_HANDLER_BASE_HXX +#define XMLOFF_PROPERTY_HANDLER_BASE_HXX + +#include "forms/property_handler.hxx" + +#include <osl/interlck.h> + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + //================================================================================================================== + //= PropertyHandlerBase + //================================================================================================================== + class PropertyHandlerBase : public IPropertyHandler + { + protected: + PropertyHandlerBase() + :m_refCount( 0 ) + { + } + + virtual ~PropertyHandlerBase(); + + // IReference + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + + private: + oslInterlockedCount m_refCount; + }; + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... + +#endif // XMLOFF_PROPERTY_HANDLER_BASE_HXX diff --git a/xmloff/source/forms/handler/vcl_date_handler.cxx b/xmloff/source/forms/handler/vcl_date_handler.cxx new file mode 100644 index 000000000000..a8404ed04e05 --- /dev/null +++ b/xmloff/source/forms/handler/vcl_date_handler.cxx @@ -0,0 +1,114 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_xmloff.hxx" + +#include "vcl_date_handler.hxx" +#include "xmloff/xmluconv.hxx" + +#include <com/sun/star/util/DateTime.hpp> + +#include <tools/diagnose_ex.h> +#include <tools/date.hxx> + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::util::DateTime; + + //================================================================================================================== + //= VCLDateHandler + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + VCLDateHandler::VCLDateHandler() + { + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString VCLDateHandler::getAttributeValue( const PropertyValues& /*i_propertyValues*/ ) const + { + OSL_ENSURE( false, "VCLDateHandler::getAttributeValue: unexpected call!" ); + return ::rtl::OUString(); + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString VCLDateHandler::getAttributeValue( const Any& i_propertyValue ) const + { + sal_Int32 nVCLDate(0); + OSL_VERIFY( i_propertyValue >>= nVCLDate ); + ::Date aVCLDate( nVCLDate ); + + DateTime aDateTime; // default-inited to 0 + aDateTime.Day = aVCLDate.GetDay(); + aDateTime.Month = aVCLDate.GetMonth(); + aDateTime.Year = aVCLDate.GetYear(); + + ::rtl::OUStringBuffer aBuffer; + SvXMLUnitConverter::convertDateTime( aBuffer, aDateTime, sal_False ); + return aBuffer.makeStringAndClear(); + } + + //------------------------------------------------------------------------------------------------------------------ + bool VCLDateHandler::getPropertyValues( const ::rtl::OUString i_attributeValue, PropertyValues& o_propertyValues ) const + { + sal_Int32 nVCLDate(0); + + DateTime aDateTime; + if ( SvXMLUnitConverter::convertDateTime( aDateTime, i_attributeValue ) ) + { + ::Date aVCLDate( aDateTime.Day, aDateTime.Month, aDateTime.Year ); + nVCLDate = aVCLDate.GetDate(); + } + else + { + // compatibility format, before we wrote those values in XML-schema compatible form + if ( !SvXMLUnitConverter::convertNumber( nVCLDate, i_attributeValue ) ) + { + OSL_ENSURE( false, "VCLDateHandler::getPropertyValues: unknown date format (no XML-schema date, no legacy integer)!" ); + return false; + } + } + + const Any aPropertyValue( makeAny( nVCLDate ) ); + + OSL_ENSURE( o_propertyValues.size() == 1, "VCLDateHandler::getPropertyValues: date strings represent exactly one property - not more, not less!" ); + for ( PropertyValues::iterator prop = o_propertyValues.begin(); + prop != o_propertyValues.end(); + ++prop + ) + { + prop->second = aPropertyValue; + } + return true; + } + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... diff --git a/xmloff/source/forms/handler/vcl_date_handler.hxx b/xmloff/source/forms/handler/vcl_date_handler.hxx new file mode 100644 index 000000000000..44a7f7395ceb --- /dev/null +++ b/xmloff/source/forms/handler/vcl_date_handler.hxx @@ -0,0 +1,55 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef XMLOFF_VCL_DATE_HANDLER_HXX +#define XMLOFF_VCL_DATE_HANDLER_HXX + +#include "property_handler_base.hxx" + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + //================================================================================================================== + //= VCLDateHandler + //================================================================================================================== + class VCLDateHandler : public PropertyHandlerBase + { + public: + VCLDateHandler(); + + // IPropertyHandler + virtual ::rtl::OUString getAttributeValue( const PropertyValues& i_propertyValues ) const; + virtual ::rtl::OUString getAttributeValue( const ::com::sun::star::uno::Any& i_propertyValue ) const; + virtual bool getPropertyValues( const ::rtl::OUString i_attributeValue, PropertyValues& o_propertyValues ) const; + }; + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... + +#endif // XMLOFF_VCL_DATE_HANDLER_HXX diff --git a/xmloff/source/forms/handler/vcl_time_handler.cxx b/xmloff/source/forms/handler/vcl_time_handler.cxx new file mode 100644 index 000000000000..98ea739d04a4 --- /dev/null +++ b/xmloff/source/forms/handler/vcl_time_handler.cxx @@ -0,0 +1,115 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_xmloff.hxx" + +#include "vcl_time_handler.hxx" +#include "xmloff/xmluconv.hxx" + +#include <com/sun/star/util/DateTime.hpp> + +#include <tools/diagnose_ex.h> +#include <tools/time.hxx> + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::util::DateTime; + + //================================================================================================================== + //= VCLTimeHandler + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + VCLTimeHandler::VCLTimeHandler() + { + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString VCLTimeHandler::getAttributeValue( const PropertyValues& /*i_propertyValues*/ ) const + { + OSL_ENSURE( false, "VCLTimeHandler::getAttributeValue: unexpected call!" ); + return ::rtl::OUString(); + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString VCLTimeHandler::getAttributeValue( const Any& i_propertyValue ) const + { + sal_Int32 nVCLTime(0); + OSL_VERIFY( i_propertyValue >>= nVCLTime ); + ::Time aVCLTime( nVCLTime ); + + DateTime aDateTime; // default-inited to 0 + aDateTime.Hours = aVCLTime.GetHour(); + aDateTime.Minutes = aVCLTime.GetMin(); + aDateTime.Seconds = aVCLTime.GetSec(); + aDateTime.HundredthSeconds = aVCLTime.Get100Sec(); + + ::rtl::OUStringBuffer aBuffer; + SvXMLUnitConverter::convertTime( aBuffer, aDateTime ); + return aBuffer.makeStringAndClear(); + } + + //------------------------------------------------------------------------------------------------------------------ + bool VCLTimeHandler::getPropertyValues( const ::rtl::OUString i_attributeValue, PropertyValues& o_propertyValues ) const + { + sal_Int32 nVCLTime(0); + + DateTime aDateTime; + if ( SvXMLUnitConverter::convertTime( aDateTime, i_attributeValue ) ) + { + ::Time aVCLTime( aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.HundredthSeconds ); + nVCLTime = aVCLTime.GetTime(); + } + else + { + // compatibility format, before we wrote those values in XML-schema compatible form + if ( !SvXMLUnitConverter::convertNumber( nVCLTime, i_attributeValue ) ) + { + OSL_ENSURE( false, "VCLTimeHandler::getPropertyValues: unknown time format (no XML-schema time, no legacy integer)!" ); + return false; + } + } + + const Any aPropertyValue( makeAny( nVCLTime ) ); + + OSL_ENSURE( o_propertyValues.size() == 1, "VCLTimeHandler::getPropertyValues: time strings represent exactly one property - not more, not less!" ); + for ( PropertyValues::iterator prop = o_propertyValues.begin(); + prop != o_propertyValues.end(); + ++prop + ) + { + prop->second = aPropertyValue; + } + return true; + } + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... diff --git a/xmloff/source/forms/handler/vcl_time_handler.hxx b/xmloff/source/forms/handler/vcl_time_handler.hxx new file mode 100644 index 000000000000..7ed6f0aa5730 --- /dev/null +++ b/xmloff/source/forms/handler/vcl_time_handler.hxx @@ -0,0 +1,55 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef XMLOFF_VCL_TIME_HANDLER_HXX +#define XMLOFF_VCL_TIME_HANDLER_HXX + +#include "property_handler_base.hxx" + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + //================================================================================================================== + //= VCLTimeHandler + //================================================================================================================== + class VCLTimeHandler : public PropertyHandlerBase + { + public: + VCLTimeHandler(); + + // IPropertyHandler + virtual ::rtl::OUString getAttributeValue( const PropertyValues& i_propertyValues ) const; + virtual ::rtl::OUString getAttributeValue( const ::com::sun::star::uno::Any& i_propertyValue ) const; + virtual bool getPropertyValues( const ::rtl::OUString i_attributeValue, PropertyValues& o_propertyValues ) const; + }; + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... + +#endif // XMLOFF_VCL_TIME_HANDLER_HXX diff --git a/xmloff/source/forms/layerexport.cxx b/xmloff/source/forms/layerexport.cxx index 9d024a3e2c2e..d4f0e86534ab 100644 --- a/xmloff/source/forms/layerexport.cxx +++ b/xmloff/source/forms/layerexport.cxx @@ -33,7 +33,7 @@ #include "strings.hxx" #include <xmloff/xmlexp.hxx> #include <xmloff/nmspmap.hxx> -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/xmluconv.hxx> #include <xmloff/xmlprmap.hxx> #include <xmloff/prhdlfac.hxx> @@ -54,7 +54,7 @@ #include <xmloff/XMLEventExport.hxx> #include "formevents.hxx" #include <xmloff/xmlnumfe.hxx> -#include "xformsexport.hxx" +#include "xmloff/xformsexport.hxx" /** === begin UNO includes === **/ #include <com/sun/star/text/XText.hpp> diff --git a/xmloff/source/forms/layerimport.cxx b/xmloff/source/forms/layerimport.cxx index 77d60f83ee49..cf5155f6a9a1 100644 --- a/xmloff/source/forms/layerimport.cxx +++ b/xmloff/source/forms/layerimport.cxx @@ -58,9 +58,9 @@ #include "controlpropertymap.hxx" #include "formevents.hxx" #include "formcellbinding.hxx" -#include "xformsimport.hxx" +#include "xmloff/xformsimport.hxx" #include <xmloff/xmltoken.hxx> -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <rtl/logfile.hxx> #include <algorithm> diff --git a/xmloff/source/forms/makefile.mk b/xmloff/source/forms/makefile.mk deleted file mode 100644 index 8c46a4fbf3c9..000000000000 --- a/xmloff/source/forms/makefile.mk +++ /dev/null @@ -1,70 +0,0 @@ -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2010 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# <http://www.openoffice.org/license.html> -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -PRJ=..$/.. - -PRJNAME=xmloff -TARGET=forms - -ENABLE_EXCEPTIONS=TRUE - -# --- Settings ----------------------------------------------------- - -.INCLUDE : settings.mk -.INCLUDE: $(PRJ)$/util$/makefile.pmk - -# --- Files -------------------------------------------------------- - -SLOFILES = \ - $(SLO)$/officeforms.obj \ - $(SLO)$/formevents.obj \ - $(SLO)$/eventimport.obj \ - $(SLO)$/eventexport.obj \ - $(SLO)$/controlpropertyhdl.obj \ - $(SLO)$/controlpropertymap.obj \ - $(SLO)$/valueproperties.obj \ - $(SLO)$/attriblistmerge.obj \ - $(SLO)$/controlelement.obj \ - $(SLO)$/formlayerexport.obj \ - $(SLO)$/layerexport.obj \ - $(SLO)$/elementexport.obj \ - $(SLO)$/propertyexport.obj \ - $(SLO)$/elementimport.obj \ - $(SLO)$/layerimport.obj \ - $(SLO)$/propertyimport.obj \ - $(SLO)$/formlayerimport.obj \ - $(SLO)$/formattributes.obj \ - $(SLO)$/formenums.obj \ - $(SLO)$/formsimp.obj \ - $(SLO)$/strings.obj \ - $(SLO)$/logging.obj \ - $(SLO)$/formcellbinding.obj \ - $(SLO)$/gridcolumnproptranslator.obj \ - -# --- Tagets ------------------------------------------------------- - -.INCLUDE : target.mk diff --git a/xmloff/source/forms/officeforms.cxx b/xmloff/source/forms/officeforms.cxx index d434d7a9addf..0de7b04b70d3 100644 --- a/xmloff/source/forms/officeforms.cxx +++ b/xmloff/source/forms/officeforms.cxx @@ -30,7 +30,7 @@ #include "officeforms.hxx" #include <xmloff/xmluconv.hxx> #include <xmloff/xmltoken.hxx> -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/xmlexp.hxx> #include <xmloff/xmlimp.hxx> #include <xmloff/nmspmap.hxx> diff --git a/xmloff/source/forms/property_description.hxx b/xmloff/source/forms/property_description.hxx new file mode 100644 index 000000000000..4edab2e649f7 --- /dev/null +++ b/xmloff/source/forms/property_description.hxx @@ -0,0 +1,140 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef XMLOFF_PROPERTY_DESCRIPTION_HXX +#define XMLOFF_PROPERTY_DESCRIPTION_HXX + +#include "forms/property_handler.hxx" +#include "property_group.hxx" + +#include "xmloff/xmltoken.hxx" + +#include <vector> +#include <list> + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + //================================================================================================================== + //= PropertyDescription + //================================================================================================================== + struct AttributeDescription + { + sal_uInt16 namespacePrefix; // usually XML_NAMESPACE_FORM + ::xmloff::token::XMLTokenEnum attributeToken; + + AttributeDescription() + :namespacePrefix( 0 ) + ,attributeToken( ::xmloff::token::XML_TOKEN_INVALID ) + { + } + + AttributeDescription( + const sal_uInt16 i_namespacePrefix, + const ::xmloff::token::XMLTokenEnum i_attributeToken + ) + :namespacePrefix( i_namespacePrefix ) + ,attributeToken( i_attributeToken ) + { + } + }; + + //.................................................................................................................. + inline bool operator==( const AttributeDescription& i_lhs, const AttributeDescription& i_rhs ) + { + return ( i_lhs.namespacePrefix == i_rhs.namespacePrefix ) + && ( i_lhs.attributeToken == i_rhs.attributeToken ); + } + + //================================================================================================================== + //= PropertyDescription + //================================================================================================================== + struct PropertyDescription + { + /// is the name of the property + const ::rtl::OUString propertyName; + /** denotes the attribute which represents the property. Note that multiple properties might comprise a single + attribute value. + */ + const AttributeDescription attribute; + /// is the factory for creating a handler for reading and writing the property + const PropertyHandlerFactory factory; + /// the unique ID of the property. The property meta data table must not contain two entries with the same property ID + const PropertyId propertyId; + /** the group which the property belongs to. Multiple properties belonging to the same group will, all together, + define the attribute value to be written into the ODF file. + + Consequently, properties which have the same |propertyGroup| value must also have the same |attribute| + and the same |factory| value, with the only exception being NO_GROUP properties. + + Note that the other direction is not given: It is perfectly legitimate to map the same attribute to different + (disjunct) property groups. + */ + const PropertyGroup propertyGroup; + + PropertyDescription() + :propertyName() + ,attribute() + ,factory( NULL ) + ,propertyId( PID_INVALID ) + ,propertyGroup( NO_GROUP ) + { + } + + PropertyDescription( + const ::rtl::OUString& i_propertyName, + const sal_uInt16 i_namespacePrefix, + const ::xmloff::token::XMLTokenEnum i_attributeToken, + const PropertyHandlerFactory i_factory, + const PropertyId i_propertyId, + const PropertyGroup i_propertyGroup + ) + :propertyName( i_propertyName ) + ,attribute( i_namespacePrefix, i_attributeToken ) + ,factory( i_factory ) + ,propertyId( i_propertyId ) + ,propertyGroup( i_propertyGroup ) + { + } + }; + + //================================================================================================================== + //= PropertyDescriptionList + //================================================================================================================== + typedef ::std::vector< const PropertyDescription* > PropertyDescriptionList; + + //================================================================================================================== + //= PropertyGroups + //================================================================================================================== + typedef ::std::list< PropertyDescriptionList > PropertyGroups; + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... + +#endif // XMLOFF_PROPERTY_DESCRIPTION_HXX diff --git a/xmloff/source/forms/property_group.hxx b/xmloff/source/forms/property_group.hxx new file mode 100644 index 000000000000..bca354f14e92 --- /dev/null +++ b/xmloff/source/forms/property_group.hxx @@ -0,0 +1,47 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef XMLOFF_PROPERTY_GROUP_HXX +#define XMLOFF_PROPERTY_GROUP_HXX + +//...................................................................................................................... +namespace xmloff +{ +//...................................................................................................................... + + //================================================================================================================== + //= PropertyGroup + //================================================================================================================== + enum PropertyGroup + { + NO_GROUP + }; + +//...................................................................................................................... +} // namespace xmloff +//...................................................................................................................... + +#endif // XMLOFF_PROPERTY_GROUP_HXX diff --git a/xmloff/source/forms/property_meta_data.cxx b/xmloff/source/forms/property_meta_data.cxx new file mode 100644 index 000000000000..5930d123578c --- /dev/null +++ b/xmloff/source/forms/property_meta_data.cxx @@ -0,0 +1,270 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_xmloff.hxx" + +#include "property_description.hxx" +#include "forms/form_handler_factory.hxx" +#include "strings.hxx" +#include "xmloff/xmltoken.hxx" +#include "xmloff/xmlnmspe.hxx" + +#include <tools/diagnose_ex.h> +#include <tools/debug.hxx> + +#include <hash_map> + +//...................................................................................................................... +namespace xmloff { namespace metadata +{ +//...................................................................................................................... + + using namespace ::xmloff::token; + +#define FORM_SINGLE_PROPERTY( id, att ) \ + PropertyDescription( PROPERTY_##id, XML_NAMESPACE_FORM, att, &FormHandlerFactory::getFormPropertyHandler, PID_##id, NO_GROUP ) + + //================================================================================================================== + //= property meta data + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + namespace + { + const PropertyDescription* lcl_getPropertyMetaData() + { + static const PropertyDescription s_propertyMetaData[] = + { + FORM_SINGLE_PROPERTY( DATE_MIN, XML_MIN_VALUE ), + FORM_SINGLE_PROPERTY( DATE_MAX, XML_MAX_VALUE ), + FORM_SINGLE_PROPERTY( DEFAULT_DATE, XML_VALUE ), + FORM_SINGLE_PROPERTY( DATE, XML_CURRENT_VALUE ), + FORM_SINGLE_PROPERTY( TIME_MIN, XML_MIN_VALUE ), + FORM_SINGLE_PROPERTY( TIME_MAX, XML_MAX_VALUE ), + FORM_SINGLE_PROPERTY( DEFAULT_TIME, XML_VALUE ), + FORM_SINGLE_PROPERTY( TIME, XML_CURRENT_VALUE ), + + PropertyDescription() + }; + return s_propertyMetaData; + } + } + + //------------------------------------------------------------------------------------------------------------------ + namespace + { + // TODO: instead of having all of the below static, it should be some per-instance data. This way, the + // approach used here would scale much better. + // That is, if you have multiple "meta data instances", which manage a small, but closed set of properties, + // then looking looking through those multiple instances would probably be faster than searching within + // one big instance, since in this case, every instance can quickly decide whether it is responsible + // for some attribute or property, and otherwise delegate to the next instance. + + //.............................................................................................................. + typedef ::std::hash_map< ::rtl::OUString, const PropertyDescription*, ::rtl::OUStringHash > DescriptionsByName; + + //.............................................................................................................. + const DescriptionsByName& lcl_getPropertyDescriptions() + { + DBG_TESTSOLARMUTEX(); + static DescriptionsByName s_propertyDescriptionsByName; + if ( s_propertyDescriptionsByName.empty() ) + { + const PropertyDescription* desc = lcl_getPropertyMetaData(); + while ( desc->propertyName.getLength() != 0 ) + { + s_propertyDescriptionsByName[ desc->propertyName ] = desc; + ++desc; + } + } + return s_propertyDescriptionsByName; + } + + //.............................................................................................................. + typedef ::std::map< PropertyGroup, PropertyDescriptionList > IndexedPropertyGroups; + + //.............................................................................................................. + const IndexedPropertyGroups& lcl_getIndexedPropertyGroups() + { + DBG_TESTSOLARMUTEX(); + static IndexedPropertyGroups s_indexedPropertyGroups; + if ( s_indexedPropertyGroups.empty() ) + { + const PropertyDescription* desc = lcl_getPropertyMetaData(); + while ( desc->propertyName.getLength() != 0 ) + { + if ( desc->propertyGroup != NO_GROUP ) + s_indexedPropertyGroups[ desc->propertyGroup ].push_back( desc ); + ++desc; + } + } + return s_indexedPropertyGroups; + } + + //.............................................................................................................. + typedef ::std::hash_map< ::rtl::OUString, XMLTokenEnum, ::rtl::OUStringHash > ReverseTokenLookup; + + //.............................................................................................................. + const ReverseTokenLookup& getReverseTokenLookup() + { + DBG_TESTSOLARMUTEX(); + static ReverseTokenLookup s_reverseTokenLookup; + if ( s_reverseTokenLookup.empty() ) + { + const PropertyDescription* desc = lcl_getPropertyMetaData(); + while ( desc->propertyName.getLength() != 0 ) + { + s_reverseTokenLookup[ token::GetXMLToken( desc->attribute.attributeToken ) ] = desc->attribute.attributeToken; + ++desc; + } + } + return s_reverseTokenLookup; + } + + //.............................................................................................................. + struct AttributeHash : public ::std::unary_function< AttributeDescription, size_t > + { + size_t operator()( const AttributeDescription& i_attribute ) const + { + return size_t( i_attribute.attributeToken * 100 ) + size_t( i_attribute.namespacePrefix ); + } + }; + + //.............................................................................................................. + typedef ::std::hash_multimap< AttributeDescription, PropertyGroup, AttributeHash > AttributeGroups; + + //.............................................................................................................. + const AttributeGroups& lcl_getAttributeGroups() + { + DBG_TESTSOLARMUTEX(); + static AttributeGroups s_attributeGroups; + if ( s_attributeGroups.empty() ) + { + const PropertyDescription* desc = lcl_getPropertyMetaData(); + while ( desc->propertyName.getLength() != 0 ) + { + if ( desc->propertyGroup != NO_GROUP ) + s_attributeGroups.insert( AttributeGroups::value_type( desc->attribute, desc->propertyGroup ) ); + ++desc; + } + } + return s_attributeGroups; + } + + //.............................................................................................................. + typedef ::std::hash_map< AttributeDescription, PropertyGroups, AttributeHash > AttributesWithoutGroup; + + //.............................................................................................................. + const AttributesWithoutGroup& lcl_getAttributesWithoutGroups() + { + DBG_TESTSOLARMUTEX(); + static AttributesWithoutGroup s_attributesWithoutGroup; + if ( s_attributesWithoutGroup.empty() ) + { + const PropertyDescription* desc = lcl_getPropertyMetaData(); + while ( desc->propertyName.getLength() != 0 ) + { + if ( desc->propertyGroup == NO_GROUP ) + { + PropertyDescriptionList singleElementList; + singleElementList.push_back( desc ); + + s_attributesWithoutGroup[ desc->attribute ].push_back( singleElementList ); + } + ++desc; + } + } + return s_attributesWithoutGroup; + } + } + + //------------------------------------------------------------------------------------------------------------------ + const PropertyDescription* getPropertyDescription( const ::rtl::OUString& i_propertyName ) + { + const DescriptionsByName& rAllDescriptions( lcl_getPropertyDescriptions() ); + DescriptionsByName::const_iterator pos = rAllDescriptions.find( i_propertyName ); + if ( pos != rAllDescriptions.end() ) + return pos->second; + return NULL; + } + + //------------------------------------------------------------------------------------------------------------------ + void getPropertyGroup( const PropertyGroup i_propertyGroup, PropertyDescriptionList& o_propertyDescriptions ) + { + OSL_ENSURE( i_propertyGroup != NO_GROUP, "xmloff::metadata::getPropertyGroup: illegal group!" ); + + const IndexedPropertyGroups& rPropertyGroups( lcl_getIndexedPropertyGroups() ); + const IndexedPropertyGroups::const_iterator pos = rPropertyGroups.find( i_propertyGroup ); + if ( pos != rPropertyGroups.end() ) + o_propertyDescriptions = pos->second; + } + + //------------------------------------------------------------------------------------------------------------------ + void getPropertyGroupList( const AttributeDescription& i_attribute, PropertyGroups& o_propertyGroups ) + { + const AttributeGroups& rAttributeGroups = lcl_getAttributeGroups(); + + ::std::pair< AttributeGroups::const_iterator, AttributeGroups::const_iterator > + range = rAttributeGroups.equal_range( i_attribute ); + + if ( range.first == range.second ) + { + // the attribute is not used for any non-trivial group, which means it is mapped directly to + // a single property + const AttributesWithoutGroup& attributesWithoutGroups( lcl_getAttributesWithoutGroups() ); + const AttributesWithoutGroup::const_iterator pos = attributesWithoutGroups.find( i_attribute ); + if ( pos != attributesWithoutGroups.end() ) + o_propertyGroups = pos->second; + } + else + { + const IndexedPropertyGroups& rPropertyGroups = lcl_getIndexedPropertyGroups(); + for ( AttributeGroups::const_iterator group = range.first; group != range.second; ++group ) + { + const PropertyGroup propGroup = group->second; + const IndexedPropertyGroups::const_iterator groupPos = rPropertyGroups.find( propGroup ); + ENSURE_OR_CONTINUE( groupPos != rPropertyGroups.end(), "getPropertyGroupList: inconsistency!" ); + o_propertyGroups.push_back( groupPos->second ); + } + } + } + + //------------------------------------------------------------------------------------------------------------------ + AttributeDescription getAttributeDescription( const sal_uInt16 i_namespacePrefix, const ::rtl::OUString& i_attributeName ) + { + AttributeDescription attribute; + const ReverseTokenLookup& rTokenLookup( getReverseTokenLookup() ); + const ReverseTokenLookup::const_iterator pos = rTokenLookup.find( i_attributeName ); + if ( pos != rTokenLookup.end() ) + { + attribute.namespacePrefix = i_namespacePrefix; + attribute.attributeToken = pos->second; + } + return attribute; + } + +//...................................................................................................................... +} } // namespace xmloff::metadata +//...................................................................................................................... diff --git a/xmloff/source/forms/property_meta_data.hxx b/xmloff/source/forms/property_meta_data.hxx new file mode 100644 index 000000000000..f246a7bfd745 --- /dev/null +++ b/xmloff/source/forms/property_meta_data.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef XMLOFF_PROPERTY_META_DATA_HXX +#define XMLOFF_PROPERTY_META_DATA_HXX + +#include "property_description.hxx" + +//...................................................................................................................... +namespace xmloff { namespace metadata +{ +//...................................................................................................................... + + const PropertyDescription* getPropertyDescription( const ::rtl::OUString& i_propertyName ); + + /** retries the descriptions of all properties which add to the given XML attribute + + <p>Effectively, the complete property map is search for all entries which have the given + namespace/attribute values.</p> + */ + void getPropertyGroup( + const PropertyGroup i_propertyGroup, + PropertyDescriptionList& o_propertyDescriptions + ); + + /** retrieves all known property groups which are mapped to the given attribute + */ + void getPropertyGroupList( + const AttributeDescription& i_attribute, + PropertyGroups& o_propertyGroups + ); + + /** retrieves the attribute descriptor for the attribute given by namespace prefix and attribute name + */ + AttributeDescription + getAttributeDescription( const sal_uInt16 i_namespacePrefix, const ::rtl::OUString& i_attributeName ); + +//...................................................................................................................... +} } // namespace xmloff::metadata +//...................................................................................................................... + +#endif // XMLOFF_PROPERTY_META_DATA_HXX diff --git a/xmloff/source/forms/propertyexport.cxx b/xmloff/source/forms/propertyexport.cxx index 2a485566cf9d..bab88b47a82f 100644 --- a/xmloff/source/forms/propertyexport.cxx +++ b/xmloff/source/forms/propertyexport.cxx @@ -32,12 +32,11 @@ #include "propertyexport.hxx" #include <xmloff/xmlexp.hxx> #include "strings.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <xmloff/xmluconv.hxx> #include <xmloff/families.hxx> #include <osl/diagnose.h> #include <com/sun/star/beans/PropertyAttribute.hpp> -#include <com/sun/star/beans/XPropertyState.hpp> #include <com/sun/star/util/Date.hpp> #include <com/sun/star/util/Time.hpp> #include <com/sun/star/util/DateTime.hpp> @@ -72,6 +71,8 @@ namespace xmloff OPropertyExport::OPropertyExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps) :m_rContext(_rContext) ,m_xProps(_rxProps) + ,m_xPropertyInfo( m_xProps->getPropertySetInfo() ) + ,m_xPropertyState( _rxProps, UNO_QUERY ) { // caching ::rtl::OUStringBuffer aBuffer; @@ -80,7 +81,6 @@ namespace xmloff m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(aBuffer, sal_False); m_sValueFalse = aBuffer.makeStringAndClear(); - m_xPropertyInfo = m_xProps->getPropertySetInfo(); OSL_ENSURE(m_xPropertyInfo.is(), "OPropertyExport::OPropertyExport: need an XPropertySetInfo!"); // collect the properties which need to be exported @@ -88,6 +88,18 @@ namespace xmloff } //--------------------------------------------------------------------- + bool OPropertyExport::shouldExportProperty( const ::rtl::OUString& i_propertyName ) const + { + // if the property state is DEFAULT, it does not need to be written - at least + // if it's a built-in property, and not a dynamically-added one. + bool bIsDefaultValue = m_xPropertyState.is() + && ( PropertyState_DEFAULT_VALUE == m_xPropertyState->getPropertyState( i_propertyName ) ); + bool bIsDynamicProperty = m_xPropertyInfo.is() + && ( ( m_xPropertyInfo->getPropertyByName( i_propertyName ).Attributes & PropertyAttribute::REMOVEABLE ) != 0 ); + return ( !bIsDefaultValue || bIsDynamicProperty ); + } + + //--------------------------------------------------------------------- void OPropertyExport::exportRemainingProperties() { // the properties tag (will be created if we have at least one no-default property) @@ -95,9 +107,6 @@ namespace xmloff try { - Reference< XPropertyState > xPropertyState( m_xProps, UNO_QUERY ); - Reference< XPropertySetInfo > xPSI( m_xProps->getPropertySetInfo() ); - Any aValue; ::rtl::OUString sValue; @@ -112,13 +121,7 @@ namespace xmloff #if OSL_DEBUG_LEVEL > 0 const ::rtl::OUString sPropertyName = *aProperty; (void)sPropertyName; #endif - // if the property state is DEFAULT, it does not need to be written - at least - // if it's a built-in property, and not a dynamically-added one. - bool bIsDefaultValue = xPropertyState.is() - && ( PropertyState_DEFAULT_VALUE == xPropertyState->getPropertyState( *aProperty ) ); - bool bIsDynamicProperty = xPSI.is() - && ( ( xPSI->getPropertyByName( *aProperty ).Attributes & PropertyAttribute::REMOVEABLE ) != 0 ); - if ( bIsDefaultValue && !bIsDynamicProperty ) + if ( !shouldExportProperty( *aProperty ) ) continue; // now that we have the first sub-tag we need the form:properties element diff --git a/xmloff/source/forms/propertyexport.hxx b/xmloff/source/forms/propertyexport.hxx index ab17912e4df4..3ddfd8d4cabd 100644 --- a/xmloff/source/forms/propertyexport.hxx +++ b/xmloff/source/forms/propertyexport.hxx @@ -31,6 +31,7 @@ #include "formattributes.hxx" #include <comphelper/stl_types.hxx> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> #include <callbacks.hxx> #include <xmloff/xmlexp.hxx> #include "callbacks.hxx" @@ -74,10 +75,12 @@ namespace xmloff protected: IFormsExportContext& m_rContext; - ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > - m_xProps; - ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > - m_xPropertyInfo; + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + m_xProps; + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > + m_xPropertyInfo; + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > + m_xPropertyState; // caching ::rtl::OUString m_sValueTrue; @@ -308,6 +311,14 @@ namespace xmloff const sal_Unicode _aQuoteCharacter = '"', const sal_Unicode _aListSeparator = ','); + /** determines whether the given property is to be exported + + <p>Currently, the method simply checks whether the property's state is <em>not</em> PropertyState.DEFAULT, + or whether the property is a dynamic property (i.e. added via an <code>XPropertyContainer</code>). + So, take care when using the method - the heuristics is not applicable for all properties.</p> + */ + bool shouldExportProperty( const ::rtl::OUString& i_propertyName ) const; + /** tries to convert an arbitrary <type scope="com.sun:star.uno">Any</type> into an string <p>If the type contained in the Any is not supported, the returned string will be empty. In the diff --git a/xmloff/source/forms/propertyimport.cxx b/xmloff/source/forms/propertyimport.cxx index 45fa2f5b4744..1fdb85067f3d 100644 --- a/xmloff/source/forms/propertyimport.cxx +++ b/xmloff/source/forms/propertyimport.cxx @@ -34,7 +34,7 @@ #include <osl/diagnose.h> #include <comphelper/extract.hxx> #include "callbacks.hxx" -#include "xmlnmspe.hxx" +#include "xmloff/xmlnmspe.hxx" #include <tools/date.hxx> #include <tools/time.hxx> #include <tools/datetime.hxx> @@ -349,7 +349,7 @@ _rChars } //--------------------------------------------------------------------- -void OPropertyImport::handleAttribute(sal_uInt16 /*_nNamespaceKey*/, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) +bool OPropertyImport::handleAttribute(sal_uInt16 /*_nNamespaceKey*/, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue) { const OAttribute2Property::AttributeAssignment* pProperty = m_rContext.getAttributeMap().getAttributeTranslation(_rLocalName); if (pProperty) @@ -361,18 +361,21 @@ void OPropertyImport::handleAttribute(sal_uInt16 /*_nNamespaceKey*/, const ::rtl // convert the value string into the target type aNewValue.Value = PropertyConversion::convertString(m_rContext.getGlobalContext(), pProperty->aPropertyType, _rValue, pProperty->pEnumMap, pProperty->bInverseSemantics); implPushBackPropertyValue( aNewValue ); + return true; } -#if OSL_DEBUG_LEVEL > 0 - else if (!token::IsXMLToken(_rLocalName, token::XML_TYPE)) // xlink:type is valid but ignored for <form:form> + if (!token::IsXMLToken(_rLocalName, token::XML_TYPE)) // xlink:type is valid but ignored for <form:form> { +#if OSL_DEBUG_LEVEL > 0 ::rtl::OString sMessage( "OPropertyImport::handleAttribute: Can't handle the following:\n" ); sMessage += ::rtl::OString( " Attribute name: " ); sMessage += ::rtl::OString( _rLocalName.getStr(), _rLocalName.getLength(), osl_getThreadTextEncoding() ); sMessage += ::rtl::OString( "\n value: " ); sMessage += ::rtl::OString( _rValue.getStr(), _rValue.getLength(), osl_getThreadTextEncoding() ); OSL_ENSURE( sal_False, sMessage.getStr() ); - } #endif + return false; + } + return true; } //===================================================================== diff --git a/xmloff/source/forms/propertyimport.hxx b/xmloff/source/forms/propertyimport.hxx index 30bc8bb1d617..d46c0068f090 100644 --- a/xmloff/source/forms/propertyimport.hxx +++ b/xmloff/source/forms/propertyimport.hxx @@ -119,7 +119,7 @@ namespace xmloff @param _rValue attribute value */ - virtual void handleAttribute(sal_uInt16 _nNamespaceKey, + virtual bool handleAttribute(sal_uInt16 _nNamespaceKey, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue); diff --git a/xmloff/source/forms/valueproperties.cxx b/xmloff/source/forms/valueproperties.cxx index 1c44db963944..8bf9ae7bcd57 100644 --- a/xmloff/source/forms/valueproperties.cxx +++ b/xmloff/source/forms/valueproperties.cxx @@ -65,16 +65,6 @@ namespace xmloff } break; - case FormComponentType::DATEFIELD: - _rpCurrentValuePropertyName = PROPERTY_DATE; - _rpValuePropertyName = PROPERTY_DEFAULT_DATE; - break; - - case FormComponentType::TIMEFIELD: - _rpCurrentValuePropertyName = PROPERTY_TIME; - _rpValuePropertyName = PROPERTY_DEFAULT_TIME; - break; - case FormComponentType::NUMERICFIELD: case FormComponentType::CURRENCYFIELD: _rpCurrentValuePropertyName = PROPERTY_VALUE; @@ -108,6 +98,10 @@ namespace xmloff _rpCurrentValuePropertyName = PROPERTY_SPINVALUE; _rpValuePropertyName = PROPERTY_DEFAULT_SPINVALUE; break; + + default: + OSL_ENSURE( false, "OValuePropertiesMetaData::getValuePropertyNames: unsupported component type!" ); + break; } } @@ -119,16 +113,6 @@ namespace xmloff _rpMinValuePropertyName = _rpMaxValuePropertyName = NULL; switch (_nFormComponentType) { - case FormComponentType::DATEFIELD: - _rpMinValuePropertyName = PROPERTY_DATE_MIN; - _rpMaxValuePropertyName = PROPERTY_DATE_MAX; - break; - - case FormComponentType::TIMEFIELD: - _rpMinValuePropertyName = PROPERTY_TIME_MIN; - _rpMaxValuePropertyName = PROPERTY_TIME_MAX; - break; - case FormComponentType::NUMERICFIELD: case FormComponentType::CURRENCYFIELD: _rpMinValuePropertyName = PROPERTY_VALUE_MIN; @@ -149,6 +133,10 @@ namespace xmloff _rpMinValuePropertyName = PROPERTY_SPINVALUE_MIN; _rpMaxValuePropertyName = PROPERTY_SPINVALUE_MAX; break; + + default: + OSL_ENSURE( false, "OValuePropertiesMetaData::getValueLimitPropertyNames: unsupported component type!" ); + break; } } @@ -175,7 +163,15 @@ namespace xmloff break; case FormComponentType::DATEFIELD: + _rpValuePropertyName = PROPERTY_DATE; + _rpDefaultValuePropertyName = PROPERTY_DEFAULT_DATE; + break; + case FormComponentType::TIMEFIELD: + _rpValuePropertyName = PROPERTY_TIME; + _rpDefaultValuePropertyName = PROPERTY_DEFAULT_TIME; + break; + case FormComponentType::NUMERICFIELD: case FormComponentType::CURRENCYFIELD: case FormComponentType::PATTERNFIELD: |