summaryrefslogtreecommitdiff
path: root/sfx2/source/doc/objuno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/doc/objuno.cxx')
-rw-r--r--sfx2/source/doc/objuno.cxx1389
1 files changed, 1389 insertions, 0 deletions
diff --git a/sfx2/source/doc/objuno.cxx b/sfx2/source/doc/objuno.cxx
new file mode 100644
index 000000000000..80f8c320a516
--- /dev/null
+++ b/sfx2/source/doc/objuno.cxx
@@ -0,0 +1,1389 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// 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 <com/sun/star/document/XCompatWriterDocProperties.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 <osl/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 "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 },
+ { "Category" , 8 , MID_CATEGORY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "Company" , 7 , MID_COMPANY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
+ { "Manager" , 7 , MID_MANAGER, &::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; 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(RTL_CONSTASCII_USTRINGPARAM("'"));
+ }
+ // FIXME there is a race condition here
+ try {
+ xPropContainer->addProperty(name,
+ beans::PropertyAttribute::REMOVEABLE,
+ uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(""))));
+ } 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(RTL_CONSTASCII_USTRINGPARAM(
+ "SfxDocumentInfoObject::initialize: no XDocumentProperties given")),
+ *this, 0);
+ _pImp->Reset(xDoc);
+ } else {
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "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);
+}
+
+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!
+ case MID_CATEGORY:
+ case MID_MANAGER:
+ case MID_COMPANY:
+ {
+ uno::Reference< document::XCompatWriterDocProperties > xWriterProps( _pImp->m_xDocProps, uno::UNO_QUERY );
+ if ( xWriterProps.is() )
+ {
+ if ( nHandle == MID_CATEGORY )
+ xWriterProps->setCategory( sTemp );
+ else if ( nHandle == MID_MANAGER )
+ xWriterProps->setManager( sTemp );
+ else
+ xWriterProps->setCompany( sTemp );
+ break;
+ }
+ }
+ 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(RTL_CONSTASCII_USTRINGPARAM("")));
+ }
+ 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;
+ case MID_CATEGORY:
+ case MID_MANAGER:
+ case MID_COMPANY:
+ {
+ uno::Reference< document::XCompatWriterDocProperties > xWriterProps( _pImp->m_xDocProps, uno::UNO_QUERY );
+ if ( xWriterProps.is() )
+ {
+ if ( nHandle == MID_CATEGORY )
+ aValue <<= xWriterProps->getCategory();
+ else if ( nHandle == MID_MANAGER )
+ aValue <<= xWriterProps->getManager();
+ else
+ aValue <<= xWriterProps->getCompany();
+ 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(RTL_CONSTASCII_USTRINGPARAM(""))));
+ _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
+ {
+ SolarMutexGuard aSolarGuard;
+ 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(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL"));
+ medium[0].Value <<= aURL;
+ medium[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("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(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL"));
+ medium[0].Value <<= aURL;
+ medium[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("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 );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */