/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sfxresid.hxx" #include "doc.hrc" using namespace ::com::sun::star; // TODO/REFACTOR: provide service for MS formats // TODO/REFACTOR: IsEncrypted is never set nor read // Generator is not saved ATM; which value?! // Generator handling must be implemented // Deprecate "Theme", rework IDL // AutoLoadEnabled is deprecated?! // Reasonable defaults for DateTime // MIMEType readonly?! // Announce changes about Theme, Language, Generator, removed entries etc. // IsEncrypted is necessary for binary formats! // Open: When to call PrepareDocInfoForSave? Currently only called for own formats and HTML/Writer // Open: How to load and save EditingTime to MS formats // PPT-Export should use SavePropertySet //============================================================================= // The number of user defined fields handled by the evil XDocumentInfo // interface. There are exactly 4. No more, no less. #define FOUR 4 #define PROPERTY_UNBOUND 0 #define PROPERTY_MAYBEVOID ::com::sun::star::beans::PropertyAttribute::MAYBEVOID const SfxItemPropertyMapEntry* lcl_GetDocInfoPropertyMap() { static SfxItemPropertyMapEntry aDocInfoPropertyMap_Impl[] = { { "Author" , 6 , WID_FROM, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "AutoloadEnabled" , 15, MID_DOCINFO_AUTOLOADENABLED, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 }, { "AutoloadSecs" , 12, MID_DOCINFO_AUTOLOADSECS, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 }, { "AutoloadURL" , 11, MID_DOCINFO_AUTOLOADURL, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "CreationDate" , 12, WID_DATE_CREATED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, { "DefaultTarget" , 13, MID_DOCINFO_DEFAULTTARGET, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "Description" , 11, MID_DOCINFO_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "DocumentStatistic", 17 , MID_DOCINFO_STATISTIC, &::getCppuType((const uno::Sequence< beans::NamedValue >*)0), PROPERTY_UNBOUND, 0 }, { "EditingCycles" , 13, MID_DOCINFO_REVISION, &::getCppuType((const sal_Int16*)0), PROPERTY_UNBOUND, 0 }, { "EditingDuration" , 15, MID_DOCINFO_EDITTIME, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 }, { "Generator" , 9, SID_APPLICATION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "Keywords" , 8 , WID_KEYWORDS, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "Language" , 8, MID_DOCINFO_CHARLOCALE, &::getCppuType((const lang::Locale*)0), PROPERTY_UNBOUND, 0 }, { "MIMEType" , 8 , WID_CONTENT_TYPE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND | ::com::sun::star::beans::PropertyAttribute::READONLY, 0 }, { "ModifiedBy" , 10, MID_DOCINFO_MODIFICATIONAUTHOR, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "ModifyDate" , 10, WID_DATE_MODIFIED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, { "PrintDate" , 9 , MID_DOCINFO_PRINTDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, { "PrintedBy" , 9 , MID_DOCINFO_PRINTEDBY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "Subject" , 7 , MID_DOCINFO_SUBJECT, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "Template" , 8 , MID_DOCINFO_TEMPLATE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "TemplateFileName", 16, SID_TEMPLATE_NAME, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, { "TemplateDate" , 12, MID_DOCINFO_TEMPLATEDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, { "Title" , 5 , WID_TITLE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, {0,0,0,0,0,0} }; return aDocInfoPropertyMap_Impl; } static USHORT aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; inline USHORT DaysInMonth( USHORT nMonth, USHORT nYear ) { if ( nMonth != 2 ) return aDaysInMonth[nMonth-1]; else { if ( (((nYear % 4) == 0) && ((nYear % 100) != 0)) || ((nYear % 400) == 0) ) return aDaysInMonth[nMonth-1] + 1; else return aDaysInMonth[nMonth-1]; } } bool IsValidDateTime( const util::DateTime& rDT ) { if ( !rDT.Month || (rDT.Month > 12) ) return false; if ( !rDT.Day || (rDT.Day > DaysInMonth( rDT.Month, rDT.Year )) ) return false; else if ( rDT.Year <= 1582 ) { if ( rDT.Year < 1582 ) return false; else if ( rDT.Month < 10 ) return false; else if ( (rDT.Month == 10) && (rDT.Day < 15) ) return false; } return true; } struct OUStringHashCode { size_t operator()( const ::rtl::OUString& sString ) const { return sString.hashCode(); } }; struct SfxExtendedItemPropertyMap : public SfxItemPropertyMapEntry { ::com::sun::star::uno::Any aValue; }; void Copy( const uno::Reference < document::XStandaloneDocumentInfo >& rSource, const uno::Reference < document::XStandaloneDocumentInfo >& rTarget ) { try { uno::Reference< beans::XPropertySet > xSet( rSource, uno::UNO_QUERY ); uno::Reference< beans::XPropertySet > xTarget( rTarget, uno::UNO_QUERY ); uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo(); uno::Reference< beans::XPropertyContainer > xContainer( rTarget, uno::UNO_QUERY ); uno::Sequence< beans::Property > lProps = xSetInfo->getProperties(); const beans::Property* pProps = lProps.getConstArray(); sal_Int32 c = lProps.getLength(); sal_Int32 i = 0; for (i=0; igetPropertyValue( pProps[i].Name ); if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE ) // QUESTION: DefaultValue?! xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue ); try { // it is possible that the propertysets from XML and binary files differ; we shouldn't break then xTarget->setPropertyValue( pProps[i].Name, aValue ); } catch ( uno::Exception& ) {} } sal_Int16 nCount = rSource->getUserFieldCount(); sal_Int16 nSupportedCount = rTarget->getUserFieldCount(); for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ ) { ::rtl::OUString aPropName = rSource->getUserFieldName( nInd ); rTarget->setUserFieldName( nInd, aPropName ); ::rtl::OUString aPropVal = rSource->getUserFieldValue( nInd ); rTarget->setUserFieldValue( nInd, aPropVal ); } } catch ( uno::Exception& ) {} } class MixedPropertySetInfo : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo > { private: SfxItemPropertyMap _aPropertyMap; ::rtl::OUString* _pUserKeys; uno::Reference _xUDProps; public: MixedPropertySetInfo( const SfxItemPropertyMapEntry* pFixProps, ::rtl::OUString* pUserKeys, uno::Reference xUDProps); virtual ~MixedPropertySetInfo(); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties( ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException); }; //----------------------------------------------------------------------------- MixedPropertySetInfo::MixedPropertySetInfo(const SfxItemPropertyMapEntry* pFixProps, ::rtl::OUString* pUserKeys, uno::Reference xUDProps) : _aPropertyMap( pFixProps ) , _pUserKeys(pUserKeys) , _xUDProps(xUDProps) { } //----------------------------------------------------------------------------- MixedPropertySetInfo::~MixedPropertySetInfo() { } //----------------------------------------------------------------------------- ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL MixedPropertySetInfo::getProperties() throw(::com::sun::star::uno::RuntimeException) { ::comphelper::SequenceAsVector< ::com::sun::star::beans::Property > lProps; // copy "fix" props //todo: os: this ugly thing should be replaced const SfxItemPropertyMapEntry* pFixProp = lcl_GetDocInfoPropertyMap(); while(pFixProp && pFixProp->pName) { ::com::sun::star::beans::Property aProp; aProp.Name = ::rtl::OUString::createFromAscii(pFixProp->pName); aProp.Handle = pFixProp->nWID; aProp.Type = *(pFixProp->pType); aProp.Attributes = (sal_Int16)(pFixProp->nFlags); lProps.push_back(aProp); ++pFixProp; } // copy "dynamic" props // NB: this is really ugly: // The returned properties must _not_ include the 4 user-defined fields! // These are _not_ properties of the XDocumentInfo interface. // Some things rely on this, e.g. Copy would break otherwise. // This will have interesting consequences if someone expects to insert // a property with the same name as an user-defined key, but nobody // sane does that. uno::Sequence udProps = _xUDProps->getPropertySetInfo()->getProperties(); for (sal_Int32 i = 0; i < udProps.getLength(); ++i) { if (std::find(_pUserKeys, _pUserKeys+FOUR, udProps[i].Name) == _pUserKeys+FOUR) { // #i100027#: handles from udProps are not valid here udProps[i].Handle = -1; lProps.push_back(udProps[i]); } } return lProps.getAsConstList(); } //----------------------------------------------------------------------------- ::com::sun::star::beans::Property SAL_CALL MixedPropertySetInfo::getPropertyByName( const ::rtl::OUString& sName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException ) { ::com::sun::star::beans::Property aProp; // search it as "fix" prop if( _aPropertyMap.hasPropertyByName( sName ) ) return _aPropertyMap.getPropertyByName( sName ); else // search it as "dynamic" prop return _xUDProps->getPropertySetInfo()->getPropertyByName(sName); } //----------------------------------------------------------------------------- ::sal_Bool SAL_CALL MixedPropertySetInfo::hasPropertyByName(const ::rtl::OUString& sName) throw(::com::sun::star::uno::RuntimeException) { return _aPropertyMap.hasPropertyByName( sName ) ? // "fix" prop? sal_True : _xUDProps->getPropertySetInfo()->hasPropertyByName(sName); // "dynamic" prop? } //----------------------------------------------------------------------------- struct SfxDocumentInfoObject_Impl { ::osl::Mutex _aMutex; ::cppu::OInterfaceContainerHelper _aDisposeContainer; sal_Bool bDisposed; // this contains the names of the 4 user defined properties // which are accessible via the evil XDocumentInfo interface ::rtl::OUString m_UserDefined[FOUR]; // the actual contents uno::Reference m_xDocProps; SfxItemPropertyMap m_aPropertyMap; SfxDocumentInfoObject_Impl() : _aDisposeContainer( _aMutex ) , bDisposed(sal_False) , m_xDocProps() , m_aPropertyMap( lcl_GetDocInfoPropertyMap() ) { // the number of user fields is not changeable from the outside // we can't set it too high because every name/value pair will be written to the file (even if empty) // currently our dialog has only 4 user keys so 4 is still a reasonable number } /// the initialization function void Reset(uno::Reference xDocProps, ::rtl::OUString* pUserDefined = 0); }; void SfxDocumentInfoObject_Impl::Reset(uno::Reference xDocProps, ::rtl::OUString* pUserDefined) { if (pUserDefined == 0) { // NB: this is an ugly hack; the "Properties" ui dialog displays // exactly 4 user-defined fields and expects these to be available // (should be redesigned), but I do not want to do this in // DocumentProperties; do it here instead uno::Reference xPropAccess( xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); uno::Reference xPropContainer( xPropAccess, uno::UNO_QUERY_THROW); uno::Sequence< beans::PropertyValue > props = xPropAccess->getPropertyValues(); sal_Int32 oldLength = props.getLength(); if (oldLength < FOUR) { std::vector< ::rtl::OUString > names; for (sal_Int32 i = 0; i < oldLength; ++i) { names.push_back(props[i].Name); } const ::rtl::OUString sInfo( String( SfxResId( STR_DOCINFO_INFOFIELD ) )); for (sal_Int32 i = oldLength; i < FOUR; ++i) { ::rtl::OUString sName(sInfo); sal_Int32 idx = sName.indexOfAsciiL("%1", 2); ::rtl::OUString name = (idx > 0) ? sName.replaceAt(idx, 2, ::rtl::OUString::valueOf(i+1)) : sName + ::rtl::OUString::valueOf(i+1); while (std::find(names.begin(), names.end(), name) != names.end()) { name += ::rtl::OUString::createFromAscii("'"); } // FIXME there is a race condition here try { xPropContainer->addProperty(name, beans::PropertyAttribute::REMOVEABLE, uno::makeAny(::rtl::OUString::createFromAscii(""))); } catch (uno::RuntimeException) { throw; } catch (uno::Exception) { // ignore } } } props = xPropAccess->getPropertyValues(); for (sal_Int32 i = 0; i < FOUR; ++i) { m_UserDefined[i] = props[i].Name; } } else { std::copy(pUserDefined, pUserDefined+FOUR, m_UserDefined); } m_xDocProps = xDocProps; } //----------------------------------------------------------------------------- SfxDocumentInfoObject::SfxDocumentInfoObject() : _pImp( new SfxDocumentInfoObject_Impl() ) { } //----------------------------------------------------------------------------- SfxDocumentInfoObject::~SfxDocumentInfoObject() { delete _pImp; } //----------------------------------------------------------------------------- // ::com::sun::star::lang::XInitialization: void SAL_CALL SfxDocumentInfoObject::initialize(const uno::Sequence< uno::Any > & aArguments) throw (uno::RuntimeException, uno::Exception) { if (aArguments.getLength() >= 1) { uno::Any any = aArguments[0]; uno::Reference xDoc; if (!(any >>= xDoc) || !xDoc.is()) throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "SfxDocumentInfoObject::initialize: no XDocumentProperties given"), *this, 0); _pImp->Reset(xDoc); } else { throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "SfxDocumentInfoObject::initialize: no argument given"), *this, 0); } } // ::com::sun::star::util::XCloneable: uno::Reference SAL_CALL SfxDocumentInfoObject::createClone() throw (uno::RuntimeException) { SfxDocumentInfoObject *pNew = new SfxDocumentInfoObject; uno::Reference< util::XCloneable > xCloneable(_pImp->m_xDocProps, uno::UNO_QUERY_THROW); uno::Reference xDocProps( xCloneable->createClone(), uno::UNO_QUERY_THROW); pNew->_pImp->Reset(xDocProps, _pImp->m_UserDefined); return pNew; } // ::com::sun::star::document::XDocumentProperties: uno::Reference< document::XDocumentProperties > SAL_CALL SfxDocumentInfoObject::getDocumentProperties() throw(::com::sun::star::uno::RuntimeException) { return _pImp->m_xDocProps; } //----------------------------------------------------------------------------- const SfxDocumentInfoObject& SfxDocumentInfoObject::operator=( const SfxDocumentInfoObject & rOther) { uno::Reference< util::XCloneable > xCloneable(rOther._pImp->m_xDocProps, uno::UNO_QUERY_THROW); uno::Reference xDocProps( xCloneable->createClone(), uno::UNO_QUERY_THROW); _pImp->Reset(xDocProps, rOther._pImp->m_UserDefined); return *this; } //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::dispose() throw( ::com::sun::star::uno::RuntimeException ) { ::com::sun::star::lang::EventObject aEvent( (::cppu::OWeakObject *)this ); _pImp->_aDisposeContainer.disposeAndClear( aEvent ); ::osl::MutexGuard aGuard( _pImp->_aMutex ); _pImp->m_xDocProps = 0; // NB: do not call m_xDocProps->dispose(), there could be other refs _pImp->bDisposed = sal_True; } //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException ) { _pImp->_aDisposeContainer.addInterface( aListener ); } //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException ) { _pImp->_aDisposeContainer.removeInterface( aListener ); } //----------------------------------------------------------------------------- ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SfxDocumentInfoObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException ) { ::osl::MutexGuard aGuard( _pImp->_aMutex ); uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); MixedPropertySetInfo* pInfo = new MixedPropertySetInfo( lcl_GetDocInfoPropertyMap(), _pImp->m_UserDefined, xPropSet); uno::Reference< beans::XPropertySetInfo > xInfo( static_cast< beans::XPropertySetInfo* >(pInfo), uno::UNO_QUERY_THROW); return xInfo; } //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aValue) throw ( uno::RuntimeException, beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException) { const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName ); // fix prop! if ( pEntry ) setFastPropertyValue( pEntry->nWID, aValue ); else // dynamic prop! { uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); return xPropSet->setPropertyValue(aPropertyName, aValue); } } //----------------------------------------------------------------------------- uno::Any SAL_CALL SfxDocumentInfoObject::getPropertyValue(const ::rtl::OUString& aPropertyName) throw( uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException) { const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName ); // fix prop! if ( pEntry ) return getFastPropertyValue( pEntry->nWID ); else // dynamic prop! { uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); return xPropSet->getPropertyValue(aPropertyName); } } sal_Bool SAL_CALL SfxDocumentInfoObject::isModified() throw(::com::sun::star::uno::RuntimeException) { uno::Reference xModif( _pImp->m_xDocProps, uno::UNO_QUERY_THROW); return xModif->isModified(); } void SAL_CALL SfxDocumentInfoObject::setModified( sal_Bool bModified ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException) { uno::Reference xModif( _pImp->m_xDocProps, uno::UNO_QUERY_THROW); return xModif->setModified(bModified); } void SAL_CALL SfxDocumentInfoObject::addModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException ) { uno::Reference xModif( _pImp->m_xDocProps, uno::UNO_QUERY_THROW); return xModif->addModifyListener(xListener); } void SAL_CALL SfxDocumentInfoObject::removeModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException ) { uno::Reference xModif( _pImp->m_xDocProps, uno::UNO_QUERY_THROW); return xModif->removeModifyListener(xListener); } //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::addPropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw( uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException) {} //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::removePropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw( uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException) {} //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::addVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw( uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException) {} //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::removeVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw( uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException) {} uno::Sequence< beans::PropertyValue > SAL_CALL SfxDocumentInfoObject::getPropertyValues( void ) throw( uno::RuntimeException ) { ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = getPropertySetInfo(); ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps = xInfo->getProperties(); const ::com::sun::star::beans::Property* pProps = aProps.getConstArray(); sal_uInt32 nCount = aProps.getLength(); ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >aSeq( nCount ); ::com::sun::star::beans::PropertyValue* pValues = aSeq.getArray(); for ( sal_uInt32 n = 0; n < nCount; ++n ) { ::com::sun::star::beans::PropertyValue& rCurrValue = pValues[n]; const ::com::sun::star::beans::Property& rCurrProp = pProps[n]; rCurrValue.Name = rCurrProp.Name; rCurrValue.Handle = rCurrProp.Handle; rCurrValue.Value = getPropertyValue( rCurrProp.Name ); } return aSeq; } void SAL_CALL SfxDocumentInfoObject::setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException ) { const ::com::sun::star::beans::PropertyValue* pProps = aProps.getConstArray(); sal_uInt32 nCount = aProps.getLength(); for ( sal_uInt32 n = 0; n < nCount; ++n ) { const ::com::sun::star::beans::PropertyValue& rProp = pProps[n]; setPropertyValue( rProp.Name, rProp.Value ); } } void SAL_CALL SfxDocumentInfoObject::addProperty(const ::rtl::OUString& sName , sal_Int16 nAttributes , const ::com::sun::star::uno::Any& aDefaultValue) throw(::com::sun::star::beans::PropertyExistException , ::com::sun::star::beans::IllegalTypeException , ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ) { // clash with "fix" properties ? sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0; if ( bFixProp ) { ::rtl::OUStringBuffer sMsg(256); sMsg.appendAscii("The property \"" ); sMsg.append (sName ); sMsg.appendAscii("\" " ); if ( bFixProp ) sMsg.appendAscii(" already exists as a fix property. Please have a look into the IDL documentation of the DocumentInfo service."); throw ::com::sun::star::beans::PropertyExistException( sMsg.makeStringAndClear(), static_cast< ::cppu::OWeakObject* >(this)); } uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); return xPropSet->addProperty(sName, nAttributes, aDefaultValue); } void SAL_CALL SfxDocumentInfoObject::removeProperty(const ::rtl::OUString& sName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::NotRemoveableException , ::com::sun::star::uno::RuntimeException ) { // clash with "fix" properties ? sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0; if ( bFixProp ) { ::rtl::OUStringBuffer sMsg(256); sMsg.appendAscii("The property \"" ); sMsg.append (sName ); sMsg.appendAscii("\" cant be removed. Its a fix property of the DocumentInfo service."); throw ::com::sun::star::beans::NotRemoveableException( sMsg.makeStringAndClear(), static_cast< ::cppu::OWeakObject* >(this)); } uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); return xPropSet->removeProperty(sName); } BOOL equalsDateTime( const util::DateTime& D1, const util::DateTime& D2 ) { return D1.HundredthSeconds == D2.HundredthSeconds && D1.Seconds == D2.Seconds && D1.Minutes == D2.Minutes && D1.Hours == D2.Hours && D1.Day == D2.Day && D1.Month == D2.Month && D1.Year == D2.Year; } void SAL_CALL SfxDocumentInfoObject::setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw( uno::RuntimeException, beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException) { // Attention: Only fix properties should be provided by this method. // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-) ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); if ( aValue.getValueType() == ::getCppuType((const ::rtl::OUString*)0) ) { ::rtl::OUString sTemp ; aValue >>= sTemp ; switch ( nHandle ) { case SID_APPLICATION : _pImp->m_xDocProps->setGenerator(sTemp); break; case WID_FROM : { // QUESTION: do we still need this? /* // String aStrVal( sTemp ); if ( aStrVal.Len() > TIMESTAMP_MAXLENGTH ) { SvAddressParser aParser( aStrVal ); if ( aParser.Count() > 0 ) { String aEmail = aParser.GetEmailAddress(0); String aRealname = aParser.GetRealName(0); if ( aRealname.Len() <= TIMESTAMP_MAXLENGTH ) aStrVal = aRealname; else if ( aEmail.Len() <= TIMESTAMP_MAXLENGTH ) aStrVal = aEmail; } } */ if ( _pImp->m_xDocProps->getAuthor() != sTemp ) _pImp->m_xDocProps->setAuthor(sTemp); break; } case MID_DOCINFO_PRINTEDBY: if ( _pImp->m_xDocProps->getPrintedBy() != sTemp ) _pImp->m_xDocProps->setPrintedBy(sTemp); break; case MID_DOCINFO_MODIFICATIONAUTHOR: if ( _pImp->m_xDocProps->getModifiedBy() != sTemp ) _pImp->m_xDocProps->setModifiedBy(sTemp); break; case WID_TITLE : { if ( _pImp->m_xDocProps->getTitle() != sTemp ) _pImp->m_xDocProps->setTitle(sTemp); break; } case MID_DOCINFO_SUBJECT : if ( _pImp->m_xDocProps->getSubject() != sTemp ) _pImp->m_xDocProps->setSubject(sTemp); break; case WID_KEYWORDS : { _pImp->m_xDocProps->setKeywords( ::comphelper::string::convertCommaSeparated(sTemp)); } break; case MID_DOCINFO_TEMPLATE: if ( _pImp->m_xDocProps->getTemplateName() != sTemp ) _pImp->m_xDocProps->setTemplateName(sTemp); break; case SID_TEMPLATE_NAME: if ( _pImp->m_xDocProps->getTemplateURL() != sTemp ) _pImp->m_xDocProps->setTemplateURL(sTemp); break; case MID_DOCINFO_DESCRIPTION: if ( _pImp->m_xDocProps->getDescription() != sTemp ) _pImp->m_xDocProps->setDescription(sTemp); break; case MID_DOCINFO_AUTOLOADURL: if ( _pImp->m_xDocProps->getAutoloadURL() != sTemp ) _pImp->m_xDocProps->setAutoloadURL(sTemp); break; case MID_DOCINFO_DEFAULTTARGET: if ( _pImp->m_xDocProps->getDefaultTarget() != sTemp ) _pImp->m_xDocProps->setDefaultTarget(sTemp); break; // case WID_CONTENT_TYPE : // this is readonly! default: break; } } else if ( aValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0) ) { com::sun::star::util::DateTime aTemp; aValue >>= aTemp ; switch ( nHandle ) { case WID_DATE_CREATED : { if ( !equalsDateTime(_pImp->m_xDocProps->getCreationDate(), aTemp ) ) { _pImp->m_xDocProps->setCreationDate(aTemp); } break; } case WID_DATE_MODIFIED : { if ( !equalsDateTime(_pImp->m_xDocProps->getModificationDate(), aTemp ) ) { _pImp->m_xDocProps->setModificationDate(aTemp); } break; } case MID_DOCINFO_PRINTDATE : { if ( !equalsDateTime(_pImp->m_xDocProps->getPrintDate(), aTemp ) ) { _pImp->m_xDocProps->setPrintDate(aTemp); } break; } case MID_DOCINFO_TEMPLATEDATE : { if ( !equalsDateTime(_pImp->m_xDocProps->getTemplateDate(), aTemp ) ) { _pImp->m_xDocProps->setTemplateDate(aTemp); } break; } default: break; } } else if ( aValue.getValueType() == ::getBooleanCppuType() ) { sal_Bool bBoolVal = false; aValue >>= bBoolVal ; switch ( nHandle ) { case MID_DOCINFO_AUTOLOADENABLED: // NB: this property does not exist any more // it is emulated as enabled iff delay > 0 if ( bBoolVal && (0 == _pImp->m_xDocProps->getAutoloadSecs()) ) { _pImp->m_xDocProps->setAutoloadSecs(60); // default } else if ( !bBoolVal && (0 != _pImp->m_xDocProps->getAutoloadSecs()) ) { _pImp->m_xDocProps->setAutoloadSecs(0); _pImp->m_xDocProps->setAutoloadURL(::rtl::OUString::createFromAscii("")); } break; default: break; } } else if ( aValue.getValueType() == ::getCppuType((const sal_Int32*)0) ) { sal_Int32 nIntVal = 0; aValue >>= nIntVal ; switch ( nHandle ) { case MID_DOCINFO_AUTOLOADSECS: if ( nIntVal != _pImp->m_xDocProps->getAutoloadSecs()) _pImp->m_xDocProps->setAutoloadSecs(nIntVal); break; case MID_DOCINFO_EDITTIME: if ( nIntVal != _pImp->m_xDocProps->getEditingDuration()) _pImp->m_xDocProps->setEditingDuration(nIntVal); break; default: break; } } else if ( aValue.getValueType() == ::getCppuType((const sal_Int16*)0) ) { short nIntVal = 0; aValue >>= nIntVal ; switch ( nHandle ) { case MID_DOCINFO_REVISION: if ( nIntVal != _pImp->m_xDocProps->getEditingCycles()) _pImp->m_xDocProps->setEditingCycles(nIntVal); break; default: break; } } else if ( aValue.getValueType() == ::getCppuType((const uno::Sequence< beans::NamedValue >*)0) ) { if ( nHandle == MID_DOCINFO_STATISTIC ) { uno::Sequence < beans::NamedValue > aData; aValue >>= aData; { _pImp->m_xDocProps->setDocumentStatistics(aData); } } } else if ( aValue.getValueType() == ::getCppuType((const lang::Locale*)0) ) { if ( nHandle == MID_DOCINFO_CHARLOCALE ) { lang::Locale aLocale; aValue >>= aLocale; lang::Locale oldLocale = _pImp->m_xDocProps->getLanguage(); if ( aLocale.Language != oldLocale.Language || aLocale.Country != oldLocale.Country || aLocale.Variant != oldLocale.Variant ) { _pImp->m_xDocProps->setLanguage(aLocale); } } } } //----------------------------------------------------------------------------- ::com::sun::star::uno::Any SAL_CALL SfxDocumentInfoObject::getFastPropertyValue(sal_Int32 nHandle) throw( uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException) { // Attention: Only fix properties should be provided by this method. // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-) ::osl::MutexGuard aGuard( _pImp->_aMutex ); ::com::sun::star::uno::Any aValue; switch ( nHandle ) { case SID_APPLICATION : aValue <<= _pImp->m_xDocProps->getGenerator(); break; case WID_CONTENT_TYPE : // FIXME this is not available anymore aValue <<= ::rtl::OUString(); break; case MID_DOCINFO_REVISION : aValue <<= _pImp->m_xDocProps->getEditingCycles(); break; case MID_DOCINFO_EDITTIME : aValue <<= _pImp->m_xDocProps->getEditingDuration(); break; case WID_FROM : aValue <<= _pImp->m_xDocProps->getAuthor(); break; case WID_DATE_CREATED : if ( IsValidDateTime( _pImp->m_xDocProps->getCreationDate() ) ) aValue <<= _pImp->m_xDocProps->getCreationDate(); break; case WID_TITLE : aValue <<= _pImp->m_xDocProps->getTitle(); break; case MID_DOCINFO_SUBJECT: aValue <<= _pImp->m_xDocProps->getSubject(); break; case MID_DOCINFO_MODIFICATIONAUTHOR: aValue <<= _pImp->m_xDocProps->getModifiedBy(); break; case WID_DATE_MODIFIED : if ( IsValidDateTime( _pImp->m_xDocProps->getModificationDate() ) ) aValue <<= _pImp->m_xDocProps->getModificationDate(); break; case MID_DOCINFO_PRINTEDBY: aValue <<= _pImp->m_xDocProps->getPrintedBy(); break; case MID_DOCINFO_PRINTDATE: if ( IsValidDateTime( _pImp->m_xDocProps->getPrintDate() ) ) aValue <<= _pImp->m_xDocProps->getPrintDate(); break; case WID_KEYWORDS : aValue <<= ::comphelper::string::convertCommaSeparated( _pImp->m_xDocProps->getKeywords()); break; case MID_DOCINFO_DESCRIPTION: aValue <<= _pImp->m_xDocProps->getDescription(); break; case MID_DOCINFO_TEMPLATE: aValue <<= _pImp->m_xDocProps->getTemplateName(); break; case SID_TEMPLATE_NAME: aValue <<= _pImp->m_xDocProps->getTemplateURL(); break; case MID_DOCINFO_TEMPLATEDATE: if ( IsValidDateTime( _pImp->m_xDocProps->getTemplateDate() ) ) aValue <<= _pImp->m_xDocProps->getTemplateDate(); break; case MID_DOCINFO_AUTOLOADENABLED: aValue <<= static_cast ( (_pImp->m_xDocProps->getAutoloadSecs() != 0) || !(_pImp->m_xDocProps->getAutoloadURL().equalsAscii(""))); break; case MID_DOCINFO_AUTOLOADURL: aValue <<= _pImp->m_xDocProps->getAutoloadURL(); break; case MID_DOCINFO_AUTOLOADSECS: aValue <<= _pImp->m_xDocProps->getAutoloadSecs(); break; case MID_DOCINFO_DEFAULTTARGET: aValue <<= _pImp->m_xDocProps->getDefaultTarget(); break; case MID_DOCINFO_STATISTIC: aValue <<= _pImp->m_xDocProps->getDocumentStatistics(); break; case MID_DOCINFO_CHARLOCALE: aValue <<= _pImp->m_xDocProps->getLanguage(); break; default: aValue <<= ::rtl::OUString(); break; } return aValue; } //----------------------------------------------------------------------------- sal_Int16 SAL_CALL SfxDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException ) { // uno::Reference xPropSet( // _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); // return xPropSet->getPropertyValues().getLength(); return FOUR; } //----------------------------------------------------------------------------- ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) { ::osl::MutexGuard aGuard( _pImp->_aMutex ); if (nIndex < FOUR) return _pImp->m_UserDefined[nIndex]; else return ::rtl::OUString(); } //----------------------------------------------------------------------------- ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) { ::osl::MutexGuard aGuard( _pImp->_aMutex ); if (nIndex < FOUR) { ::rtl::OUString name = _pImp->m_UserDefined[nIndex]; uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); ::rtl::OUString val; try { xPropSet->getPropertyValue(name) >>= val; return val; } catch (uno::RuntimeException &) { throw; } catch (uno::Exception &) { return ::rtl::OUString(); // ignore } } else return ::rtl::OUString(); } //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException ) { ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); if (nIndex < FOUR) // yes, four! { // FIXME this is full of race conditions because the PropertyBag // can be accessed from clients of the DocumentProperties! ::rtl::OUString name = _pImp->m_UserDefined[nIndex]; if (name != aName) { uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); uno::Reference xPropContainer( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); uno::Any value; try { value = xPropSet->getPropertyValue(name); xPropContainer->removeProperty(name); xPropContainer->addProperty(aName, beans::PropertyAttribute::REMOVEABLE, value); _pImp->m_UserDefined[nIndex] = aName; } catch (beans::UnknownPropertyException) { try { xPropContainer->addProperty(aName, beans::PropertyAttribute::REMOVEABLE, uno::makeAny(::rtl::OUString::createFromAscii(""))); _pImp->m_UserDefined[nIndex] = aName; } catch (beans::PropertyExistException) { _pImp->m_UserDefined[nIndex] = aName; // ignore } } catch (beans::PropertyExistException) { try { xPropContainer->addProperty(name, beans::PropertyAttribute::REMOVEABLE, value); } catch (beans::PropertyExistException) { // bugger... } } catch (uno::RuntimeException &) { throw; } catch (uno::Exception &) { // ignore everything else; xPropSet _may_ be corrupted } } } } //----------------------------------------------------------------------------- void SAL_CALL SfxDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException ) { ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); if (nIndex < FOUR) // yes, four! { ::rtl::OUString name = _pImp->m_UserDefined[nIndex]; uno::Reference xPropSet( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); uno::Reference xPropContainer( _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); uno::Any aAny; aAny <<= aValue; try { uno::Any value = xPropSet->getPropertyValue(name); if (value != aAny) { xPropSet->setPropertyValue(name, aAny); } } catch (beans::UnknownPropertyException) { try { // someone removed it, add it back again xPropContainer->addProperty(name, beans::PropertyAttribute::REMOVEABLE, aAny); } catch (uno::RuntimeException &) { throw; } catch (uno::Exception &) { // ignore everything else } } catch (uno::RuntimeException &) { throw; } catch (uno::Exception &) { // ignore everything else } } } //----------------------------------------------------------------------------- SFX_IMPL_XINTERFACE_2( SfxStandaloneDocumentInfoObject, SfxDocumentInfoObject, ::com::sun::star::lang::XServiceInfo, ::com::sun::star::document::XStandaloneDocumentInfo ) SFX_IMPL_XTYPEPROVIDER_10( SfxStandaloneDocumentInfoObject, ::com::sun::star::document::XDocumentInfo, ::com::sun::star::lang::XComponent, ::com::sun::star::beans::XPropertySet, ::com::sun::star::beans::XFastPropertySet, ::com::sun::star::beans::XPropertyAccess, ::com::sun::star::beans::XPropertyContainer, ::com::sun::star::util::XModifiable, ::com::sun::star::util::XModifyBroadcaster, ::com::sun::star::document::XStandaloneDocumentInfo, ::com::sun::star::lang::XServiceInfo ) SFX_IMPL_XSERVICEINFO( SfxStandaloneDocumentInfoObject, "com.sun.star.document.StandaloneDocumentInfo", "com.sun.star.comp.sfx2.StandaloneDocumentInfo" ) SFX_IMPL_SINGLEFACTORY( SfxStandaloneDocumentInfoObject ) SfxStandaloneDocumentInfoObject::SfxStandaloneDocumentInfoObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ) : SfxDocumentInfoObject() , _xFactory( xFactory ) { uno::Reference< lang::XInitialization > xDocProps( _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW); // xDocProps->initialize(uno::Sequence()); uno::Any a; a <<= xDocProps; uno::Sequence args(1); args[0] = a; initialize(args); } //----------------------------------------------------------------------------- SfxStandaloneDocumentInfoObject::~SfxStandaloneDocumentInfoObject() { } //----------------------------------------------------------------------------- uno::Reference< embed::XStorage > GetStorage_Impl( const ::rtl::OUString& rName, sal_Bool bWrite, uno::Reference < lang::XMultiServiceFactory >& xFactory ) { // catch unexpected exceptions under solaris // Client code checks the returned reference but is not interested on error details. try { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); return ::comphelper::OStorageHelper::GetStorageFromURL( rName, bWrite ? embed::ElementModes::READWRITE : embed::ElementModes::READ, xFactory ); } catch(const uno::Exception&) {} return uno::Reference< embed::XStorage >(); } //----------------------------------------------------------------------------- sal_Int16 SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException ) { return SfxDocumentInfoObject::getUserFieldCount(); } //----------------------------------------------------------------------------- ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) { return SfxDocumentInfoObject::getUserFieldName(nIndex); } //----------------------------------------------------------------------------- ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) { return SfxDocumentInfoObject::getUserFieldValue(nIndex); } //----------------------------------------------------------------------------- void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException ) { SfxDocumentInfoObject::setUserFieldName( nIndex, aName ); } //----------------------------------------------------------------------------- void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException ) { SfxDocumentInfoObject::setUserFieldValue( nIndex, aValue ); } //----------------------------------------------------------------------------- void SAL_CALL SfxStandaloneDocumentInfoObject::loadFromURL(const ::rtl::OUString& aURL) throw( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException ) { sal_Bool bOK = sal_False; ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); uno::Reference< document::XDocumentProperties > xDocProps( _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW); // uno::Reference< lang::XInitialization > xInit(xDocProps, uno::UNO_QUERY_THROW); // xInit->initialize(uno::Sequence()); _pImp->Reset(xDocProps); aGuard.clear(); uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_False, _xFactory ); if ( xStorage.is() ) { try { uno::Sequence medium(2); medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL"); medium[0].Value <<= aURL; medium[1].Name = ::rtl::OUString::createFromAscii("URL"); medium[1].Value <<= aURL; _pImp->m_xDocProps->loadFromStorage(xStorage, medium); _pImp->Reset(_pImp->m_xDocProps); bOK = sal_True; } catch( uno::Exception& ) { } } else { uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY ); if ( xBinary.is() ) { xBinary->loadFromURL( aURL ); bOK = sal_True; uno::Reference < document::XStandaloneDocumentInfo > xTarget( static_cast < document::XStandaloneDocumentInfo*> (this), uno::UNO_QUERY ); Copy( xBinary, xTarget ); } } if ( !bOK ) throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTREAD ); } //----------------------------------------------------------------------------- void SAL_CALL SfxStandaloneDocumentInfoObject::storeIntoURL(const ::rtl::OUString& aURL) throw( ::com::sun::star::io::IOException ) { sal_Bool bOK = sal_False; uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_True, _xFactory ); if ( xStorage.is() ) { try { uno::Sequence medium(2); medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL"); medium[0].Value <<= aURL; medium[1].Name = ::rtl::OUString::createFromAscii("URL"); medium[1].Value <<= aURL; _pImp->m_xDocProps->storeToStorage(xStorage, medium); bOK = sal_True; } catch( io::IOException & ) { throw; } catch( uno::RuntimeException& ) { throw; } catch( uno::Exception& ) { } } else { uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY ); if ( xBinary.is() ) { Copy( this, xBinary ); xBinary->storeIntoURL( aURL ); bOK = sal_True; } } if ( !bOK ) throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTWRITE ); }