| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sfx2.hxx" |
| |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/util/DateTime.hpp> |
| #include <com/sun/star/util/Date.hpp> |
| #include <com/sun/star/util/Time.hpp> |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <com/sun/star/beans/NamedValue.hpp> |
| #include <com/sun/star/beans/StringPair.hpp> |
| #include <com/sun/star/embed/ElementModes.hpp> |
| #include <com/sun/star/xml/sax/XParser.hpp> |
| #include <com/sun/star/document/XImporter.hpp> |
| #include <com/sun/star/document/XExporter.hpp> |
| #include <com/sun/star/io/XActiveDataSource.hpp> |
| #include <com/sun/star/document/XFilter.hpp> |
| #include <com/sun/star/embed/XTransactedObject.hpp> |
| #include <com/sun/star/lang/Locale.hpp> |
| #include <com/sun/star/util/XModifiable.hpp> |
| #include <com/sun/star/document/XDocumentProperties.hpp> |
| |
| #include <unotools/configmgr.hxx> |
| #include <tools/inetdef.hxx> |
| #include <unotools/bootstrap.hxx> |
| #include <cppuhelper/interfacecontainer.hxx> |
| #include <osl/mutex.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vos/mutex.hxx> |
| |
| #include <tools/errcode.hxx> |
| #include <svl/cntwids.hrc> |
| #include <comphelper/string.hxx> |
| #include <comphelper/sequenceasvector.hxx> |
| #include <comphelper/storagehelper.hxx> |
| #include <sot/storage.hxx> |
| |
| #include <sfx2/objuno.hxx> |
| #include <sfx2/sfx.hrc> |
| |
| #include <vector> |
| #include <algorithm> |
| |
| #include "sfx2/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 sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30, |
| 31, 31, 30, 31, 30, 31 }; |
| |
| inline sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 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; i<c; ++i) |
| { |
| uno::Any aValue = xSet->getPropertyValue( 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<beans::XPropertySet> _xUDProps; |
| |
| public: |
| |
| MixedPropertySetInfo( const SfxItemPropertyMapEntry* pFixProps, |
| ::rtl::OUString* pUserKeys, |
| uno::Reference<beans::XPropertySet> 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<beans::XPropertySet> 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<beans::Property> 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<document::XDocumentProperties> 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<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined = 0); |
| }; |
| |
| void SfxDocumentInfoObject_Impl::Reset(uno::Reference<document::XDocumentProperties> 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<beans::XPropertyAccess> xPropAccess( |
| xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); |
| uno::Reference<beans::XPropertyContainer> 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<document::XDocumentProperties> 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<util::XCloneable> 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<document::XDocumentProperties> 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<document::XDocumentProperties> 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<beans::XPropertySet> 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<beans::XPropertySet> 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<beans::XPropertySet> 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<util::XModifiable> 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<util::XModifiable> 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<util::XModifiable> 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<util::XModifiable> 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<beans::XPropertyContainer> 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<beans::XPropertyContainer> xPropSet( |
| _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); |
| return xPropSet->removeProperty(sName); |
| } |
| |
| sal_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<sal_Bool> |
| ( (_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<beans::XPropertyAccess> 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<beans::XPropertySet> 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<beans::XPropertySet> xPropSet( |
| _pImp->m_xDocProps->getUserDefinedProperties(), |
| uno::UNO_QUERY_THROW); |
| uno::Reference<beans::XPropertyContainer> 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<beans::XPropertySet> xPropSet( |
| _pImp->m_xDocProps->getUserDefinedProperties(), |
| uno::UNO_QUERY_THROW); |
| uno::Reference<beans::XPropertyContainer> 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>()); |
| uno::Any a; |
| a <<= xDocProps; |
| uno::Sequence<uno::Any> 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<uno::Any>()); |
| _pImp->Reset(xDocProps); |
| aGuard.clear(); |
| |
| uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_False, _xFactory ); |
| if ( xStorage.is() ) |
| { |
| try |
| { |
| uno::Sequence<beans::PropertyValue> 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<beans::PropertyValue> 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 ); |
| } |
| |