Update ooo320-m1
[ooovba.git] / sfx2 / source / doc / objuno.cxx
blob712498b97d5062fd6c2a6a7c19c25e0c38e1c168
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: objuno.cxx,v $
10 * $Revision: 1.41 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include <com/sun/star/lang/DisposedException.hpp>
35 #include <com/sun/star/util/DateTime.hpp>
36 #include <com/sun/star/util/Date.hpp>
37 #include <com/sun/star/util/Time.hpp>
38 #include <com/sun/star/beans/PropertyAttribute.hpp>
39 #include <com/sun/star/beans/NamedValue.hpp>
40 #include <com/sun/star/beans/StringPair.hpp>
41 #include <com/sun/star/embed/ElementModes.hpp>
42 #include <com/sun/star/xml/sax/XParser.hpp>
43 #include <com/sun/star/document/XImporter.hpp>
44 #include <com/sun/star/document/XExporter.hpp>
45 #include <com/sun/star/io/XActiveDataSource.hpp>
46 #include <com/sun/star/document/XFilter.hpp>
47 #include <com/sun/star/embed/XTransactedObject.hpp>
48 #include <com/sun/star/lang/Locale.hpp>
49 #include <com/sun/star/util/XModifiable.hpp>
50 #include <com/sun/star/document/XDocumentProperties.hpp>
51 #include <com/sun/star/document/XCompatWriterDocProperties.hpp>
53 #include <unotools/configmgr.hxx>
54 #include <tools/inetdef.hxx>
55 #include <unotools/bootstrap.hxx>
56 #include <cppuhelper/interfacecontainer.hxx>
57 #include <osl/mutex.hxx>
58 #include <rtl/ustrbuf.hxx>
59 #include <vcl/svapp.hxx>
60 #include <vos/mutex.hxx>
62 #include <tools/errcode.hxx>
63 #include <svtools/cntwids.hrc>
64 #include <comphelper/string.hxx>
65 #include <comphelper/sequenceasvector.hxx>
66 #include <comphelper/storagehelper.hxx>
67 #include <sot/storage.hxx>
69 #include <sfx2/objuno.hxx>
70 #include <sfx2/sfx.hrc>
72 #include <vector>
73 #include <algorithm>
75 #include "sfxresid.hxx"
76 #include "doc.hrc"
78 using namespace ::com::sun::star;
80 // TODO/REFACTOR: provide service for MS formats
81 // TODO/REFACTOR: IsEncrypted is never set nor read
82 // Generator is not saved ATM; which value?!
83 // Generator handling must be implemented
84 // Deprecate "Theme", rework IDL
85 // AutoLoadEnabled is deprecated?!
86 // Reasonable defaults for DateTime
87 // MIMEType readonly?!
88 // Announce changes about Theme, Language, Generator, removed entries etc.
89 // IsEncrypted is necessary for binary formats!
90 // Open: When to call PrepareDocInfoForSave? Currently only called for own formats and HTML/Writer
91 // Open: How to load and save EditingTime to MS formats
92 // PPT-Export should use SavePropertySet
94 //=============================================================================
96 // The number of user defined fields handled by the evil XDocumentInfo
97 // interface. There are exactly 4. No more, no less.
98 #define FOUR 4
100 #define PROPERTY_UNBOUND 0
101 #define PROPERTY_MAYBEVOID ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
103 const SfxItemPropertyMapEntry* lcl_GetDocInfoPropertyMap()
105 static SfxItemPropertyMapEntry aDocInfoPropertyMap_Impl[] =
107 { "Author" , 6 , WID_FROM, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
108 { "AutoloadEnabled" , 15, MID_DOCINFO_AUTOLOADENABLED, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 },
109 { "AutoloadSecs" , 12, MID_DOCINFO_AUTOLOADSECS, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 },
110 { "AutoloadURL" , 11, MID_DOCINFO_AUTOLOADURL, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
111 { "Category" , 8 , MID_CATEGORY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
112 { "Company" , 7 , MID_COMPANY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
113 { "Manager" , 7 , MID_MANAGER, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
114 { "CreationDate" , 12, WID_DATE_CREATED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
115 { "DefaultTarget" , 13, MID_DOCINFO_DEFAULTTARGET, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
116 { "Description" , 11, MID_DOCINFO_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
117 { "DocumentStatistic", 17 , MID_DOCINFO_STATISTIC, &::getCppuType((const uno::Sequence< beans::NamedValue >*)0), PROPERTY_UNBOUND, 0 },
118 { "EditingCycles" , 13, MID_DOCINFO_REVISION, &::getCppuType((const sal_Int16*)0), PROPERTY_UNBOUND, 0 },
119 { "EditingDuration" , 15, MID_DOCINFO_EDITTIME, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 },
120 { "Generator" , 9, SID_APPLICATION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
121 { "Keywords" , 8 , WID_KEYWORDS, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
122 { "Language" , 8, MID_DOCINFO_CHARLOCALE, &::getCppuType((const lang::Locale*)0), PROPERTY_UNBOUND, 0 },
123 { "MIMEType" , 8 , WID_CONTENT_TYPE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND | ::com::sun::star::beans::PropertyAttribute::READONLY, 0 },
124 { "ModifiedBy" , 10, MID_DOCINFO_MODIFICATIONAUTHOR, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
125 { "ModifyDate" , 10, WID_DATE_MODIFIED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
126 { "PrintDate" , 9 , MID_DOCINFO_PRINTDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
127 { "PrintedBy" , 9 , MID_DOCINFO_PRINTEDBY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
128 { "Subject" , 7 , MID_DOCINFO_SUBJECT, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
129 { "Template" , 8 , MID_DOCINFO_TEMPLATE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
130 { "TemplateFileName", 16, SID_TEMPLATE_NAME, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
131 { "TemplateDate" , 12, MID_DOCINFO_TEMPLATEDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
132 { "Title" , 5 , WID_TITLE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
133 {0,0,0,0,0,0}
135 return aDocInfoPropertyMap_Impl;
138 static USHORT aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
139 31, 31, 30, 31, 30, 31 };
141 inline USHORT DaysInMonth( USHORT nMonth, USHORT nYear )
143 if ( nMonth != 2 )
144 return aDaysInMonth[nMonth-1];
145 else
147 if ( (((nYear % 4) == 0) && ((nYear % 100) != 0)) ||
148 ((nYear % 400) == 0) )
149 return aDaysInMonth[nMonth-1] + 1;
150 else
151 return aDaysInMonth[nMonth-1];
155 bool IsValidDateTime( const util::DateTime& rDT )
157 if ( !rDT.Month || (rDT.Month > 12) )
158 return false;
159 if ( !rDT.Day || (rDT.Day > DaysInMonth( rDT.Month, rDT.Year )) )
160 return false;
161 else if ( rDT.Year <= 1582 )
163 if ( rDT.Year < 1582 )
164 return false;
165 else if ( rDT.Month < 10 )
166 return false;
167 else if ( (rDT.Month == 10) && (rDT.Day < 15) )
168 return false;
171 return true;
174 struct OUStringHashCode
176 size_t operator()( const ::rtl::OUString& sString ) const
178 return sString.hashCode();
182 struct SfxExtendedItemPropertyMap : public SfxItemPropertyMapEntry
184 ::com::sun::star::uno::Any aValue;
187 void Copy( const uno::Reference < document::XStandaloneDocumentInfo >& rSource, const uno::Reference < document::XStandaloneDocumentInfo >& rTarget )
191 uno::Reference< beans::XPropertySet > xSet( rSource, uno::UNO_QUERY );
192 uno::Reference< beans::XPropertySet > xTarget( rTarget, uno::UNO_QUERY );
193 uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
194 uno::Reference< beans::XPropertyContainer > xContainer( rTarget, uno::UNO_QUERY );
195 uno::Sequence< beans::Property > lProps = xSetInfo->getProperties();
196 const beans::Property* pProps = lProps.getConstArray();
197 sal_Int32 c = lProps.getLength();
198 sal_Int32 i = 0;
199 for (i=0; i<c; ++i)
201 uno::Any aValue = xSet->getPropertyValue( pProps[i].Name );
202 if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE )
203 // QUESTION: DefaultValue?!
204 xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue );
207 // it is possible that the propertysets from XML and binary files differ; we shouldn't break then
208 xTarget->setPropertyValue( pProps[i].Name, aValue );
210 catch ( uno::Exception& ) {}
213 sal_Int16 nCount = rSource->getUserFieldCount();
214 sal_Int16 nSupportedCount = rTarget->getUserFieldCount();
215 for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ )
217 ::rtl::OUString aPropName = rSource->getUserFieldName( nInd );
218 rTarget->setUserFieldName( nInd, aPropName );
219 ::rtl::OUString aPropVal = rSource->getUserFieldValue( nInd );
220 rTarget->setUserFieldValue( nInd, aPropVal );
223 catch ( uno::Exception& ) {}
226 class MixedPropertySetInfo : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
228 private:
230 SfxItemPropertyMap _aPropertyMap;
231 ::rtl::OUString* _pUserKeys;
232 uno::Reference<beans::XPropertySet> _xUDProps;
234 public:
236 MixedPropertySetInfo( const SfxItemPropertyMapEntry* pFixProps,
237 ::rtl::OUString* pUserKeys,
238 uno::Reference<beans::XPropertySet> xUDProps);
240 virtual ~MixedPropertySetInfo();
242 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties( ) throw (::com::sun::star::uno::RuntimeException);
243 virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
244 virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException);
247 //-----------------------------------------------------------------------------
249 MixedPropertySetInfo::MixedPropertySetInfo(const SfxItemPropertyMapEntry* pFixProps,
250 ::rtl::OUString* pUserKeys,
251 uno::Reference<beans::XPropertySet> xUDProps)
252 : _aPropertyMap( pFixProps )
253 , _pUserKeys(pUserKeys)
254 , _xUDProps(xUDProps)
258 //-----------------------------------------------------------------------------
260 MixedPropertySetInfo::~MixedPropertySetInfo()
264 //-----------------------------------------------------------------------------
266 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL MixedPropertySetInfo::getProperties()
267 throw(::com::sun::star::uno::RuntimeException)
269 ::comphelper::SequenceAsVector< ::com::sun::star::beans::Property > lProps;
271 // copy "fix" props
272 //todo: os: this ugly thing should be replaced
273 const SfxItemPropertyMapEntry* pFixProp = lcl_GetDocInfoPropertyMap();
275 while(pFixProp && pFixProp->pName)
277 ::com::sun::star::beans::Property aProp;
279 aProp.Name = ::rtl::OUString::createFromAscii(pFixProp->pName);
280 aProp.Handle = pFixProp->nWID;
281 aProp.Type = *(pFixProp->pType);
282 aProp.Attributes = (sal_Int16)(pFixProp->nFlags);
284 lProps.push_back(aProp);
285 ++pFixProp;
288 // copy "dynamic" props
290 // NB: this is really ugly:
291 // The returned properties must _not_ include the 4 user-defined fields!
292 // These are _not_ properties of the XDocumentInfo interface.
293 // Some things rely on this, e.g. Copy would break otherwise.
294 // This will have interesting consequences if someone expects to insert
295 // a property with the same name as an user-defined key, but nobody
296 // sane does that.
297 uno::Sequence<beans::Property> udProps =
298 _xUDProps->getPropertySetInfo()->getProperties();
299 for (sal_Int32 i = 0; i < udProps.getLength(); ++i) {
300 if (std::find(_pUserKeys, _pUserKeys+FOUR, udProps[i].Name)
301 == _pUserKeys+FOUR) {
302 // #i100027#: handles from udProps are not valid here
303 udProps[i].Handle = -1;
304 lProps.push_back(udProps[i]);
308 return lProps.getAsConstList();
311 //-----------------------------------------------------------------------------
313 ::com::sun::star::beans::Property SAL_CALL MixedPropertySetInfo::getPropertyByName(
314 const ::rtl::OUString& sName )
315 throw(::com::sun::star::beans::UnknownPropertyException,
316 ::com::sun::star::uno::RuntimeException )
318 ::com::sun::star::beans::Property aProp;
320 // search it as "fix" prop
321 if( _aPropertyMap.hasPropertyByName( sName ) )
322 return _aPropertyMap.getPropertyByName( sName );
323 else
324 // search it as "dynamic" prop
325 return _xUDProps->getPropertySetInfo()->getPropertyByName(sName);
328 //-----------------------------------------------------------------------------
330 ::sal_Bool SAL_CALL MixedPropertySetInfo::hasPropertyByName(const ::rtl::OUString& sName)
331 throw(::com::sun::star::uno::RuntimeException)
333 return _aPropertyMap.hasPropertyByName( sName ) ? // "fix" prop?
334 sal_True :
335 _xUDProps->getPropertySetInfo()->hasPropertyByName(sName); // "dynamic" prop?
338 //-----------------------------------------------------------------------------
340 struct SfxDocumentInfoObject_Impl
342 ::osl::Mutex _aMutex;
343 ::cppu::OInterfaceContainerHelper _aDisposeContainer;
345 sal_Bool bDisposed;
347 // this contains the names of the 4 user defined properties
348 // which are accessible via the evil XDocumentInfo interface
349 ::rtl::OUString m_UserDefined[FOUR];
351 // the actual contents
352 uno::Reference<document::XDocumentProperties> m_xDocProps;
353 SfxItemPropertyMap m_aPropertyMap;
355 SfxDocumentInfoObject_Impl()
356 : _aDisposeContainer( _aMutex )
357 , bDisposed(sal_False)
358 , m_xDocProps()
359 , m_aPropertyMap( lcl_GetDocInfoPropertyMap() )
361 // the number of user fields is not changeable from the outside
362 // we can't set it too high because every name/value pair will be written to the file (even if empty)
363 // currently our dialog has only 4 user keys so 4 is still a reasonable number
366 /// the initialization function
367 void Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined = 0);
370 void SfxDocumentInfoObject_Impl::Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined)
372 if (pUserDefined == 0) {
373 // NB: this is an ugly hack; the "Properties" ui dialog displays
374 // exactly 4 user-defined fields and expects these to be available
375 // (should be redesigned), but I do not want to do this in
376 // DocumentProperties; do it here instead
377 uno::Reference<beans::XPropertyAccess> xPropAccess(
378 xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
379 uno::Reference<beans::XPropertyContainer> xPropContainer(
380 xPropAccess, uno::UNO_QUERY_THROW);
381 uno::Sequence< beans::PropertyValue >
382 props = xPropAccess->getPropertyValues();
383 sal_Int32 oldLength = props.getLength();
384 if (oldLength < FOUR) {
385 std::vector< ::rtl::OUString > names;
386 for (sal_Int32 i = 0; i < oldLength; ++i) {
387 names.push_back(props[i].Name);
389 const ::rtl::OUString sInfo(
390 String( SfxResId( STR_DOCINFO_INFOFIELD ) ));
391 for (sal_Int32 i = oldLength; i < FOUR; ++i) {
392 ::rtl::OUString sName(sInfo);
393 sal_Int32 idx = sName.indexOfAsciiL("%1", 2);
394 ::rtl::OUString name = (idx > 0)
395 ? sName.replaceAt(idx, 2, ::rtl::OUString::valueOf(i+1))
396 : sName + ::rtl::OUString::valueOf(i+1);
397 while (std::find(names.begin(), names.end(), name)
398 != names.end()) {
399 name += ::rtl::OUString::createFromAscii("'");
401 // FIXME there is a race condition here
402 try {
403 xPropContainer->addProperty(name,
404 beans::PropertyAttribute::REMOVEABLE,
405 uno::makeAny(::rtl::OUString::createFromAscii("")));
406 } catch (uno::RuntimeException) {
407 throw;
408 } catch (uno::Exception) {
409 // ignore
413 props = xPropAccess->getPropertyValues();
414 for (sal_Int32 i = 0; i < FOUR; ++i) {
415 m_UserDefined[i] = props[i].Name;
417 } else {
418 std::copy(pUserDefined, pUserDefined+FOUR, m_UserDefined);
420 m_xDocProps = xDocProps;
423 //-----------------------------------------------------------------------------
425 SfxDocumentInfoObject::SfxDocumentInfoObject()
426 : _pImp( new SfxDocumentInfoObject_Impl() )
430 //-----------------------------------------------------------------------------
432 SfxDocumentInfoObject::~SfxDocumentInfoObject()
434 delete _pImp;
437 //-----------------------------------------------------------------------------
439 // ::com::sun::star::lang::XInitialization:
440 void SAL_CALL
441 SfxDocumentInfoObject::initialize(const uno::Sequence< uno::Any > & aArguments)
442 throw (uno::RuntimeException, uno::Exception)
444 if (aArguments.getLength() >= 1) {
445 uno::Any any = aArguments[0];
446 uno::Reference<document::XDocumentProperties> xDoc;
447 if (!(any >>= xDoc) || !xDoc.is()) throw lang::IllegalArgumentException(
448 ::rtl::OUString::createFromAscii(
449 "SfxDocumentInfoObject::initialize: no XDocumentProperties given"),
450 *this, 0);
451 _pImp->Reset(xDoc);
452 } else {
453 throw lang::IllegalArgumentException(
454 ::rtl::OUString::createFromAscii(
455 "SfxDocumentInfoObject::initialize: no argument given"),
456 *this, 0);
460 // ::com::sun::star::util::XCloneable:
461 uno::Reference<util::XCloneable> SAL_CALL
462 SfxDocumentInfoObject::createClone() throw (uno::RuntimeException)
464 SfxDocumentInfoObject *pNew = new SfxDocumentInfoObject;
465 uno::Reference< util::XCloneable >
466 xCloneable(_pImp->m_xDocProps, uno::UNO_QUERY_THROW);
467 uno::Reference<document::XDocumentProperties> xDocProps(
468 xCloneable->createClone(), uno::UNO_QUERY_THROW);
469 pNew->_pImp->Reset(xDocProps, _pImp->m_UserDefined);
470 return pNew;
473 // ::com::sun::star::document::XDocumentProperties:
474 uno::Reference< document::XDocumentProperties > SAL_CALL
475 SfxDocumentInfoObject::getDocumentProperties()
476 throw(::com::sun::star::uno::RuntimeException)
478 return _pImp->m_xDocProps;
481 //-----------------------------------------------------------------------------
483 const SfxDocumentInfoObject& SfxDocumentInfoObject::operator=( const SfxDocumentInfoObject & rOther)
485 uno::Reference< util::XCloneable >
486 xCloneable(rOther._pImp->m_xDocProps, uno::UNO_QUERY_THROW);
487 uno::Reference<document::XDocumentProperties> xDocProps(
488 xCloneable->createClone(), uno::UNO_QUERY_THROW);
489 _pImp->Reset(xDocProps, rOther._pImp->m_UserDefined);
490 return *this;
493 //-----------------------------------------------------------------------------
495 void SAL_CALL SfxDocumentInfoObject::dispose() throw( ::com::sun::star::uno::RuntimeException )
497 ::com::sun::star::lang::EventObject aEvent( (::cppu::OWeakObject *)this );
498 _pImp->_aDisposeContainer.disposeAndClear( aEvent );
499 ::osl::MutexGuard aGuard( _pImp->_aMutex );
500 _pImp->m_xDocProps = 0;
501 // NB: do not call m_xDocProps->dispose(), there could be other refs
502 _pImp->bDisposed = sal_True;
505 //-----------------------------------------------------------------------------
507 void SAL_CALL SfxDocumentInfoObject::addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
509 _pImp->_aDisposeContainer.addInterface( aListener );
512 //-----------------------------------------------------------------------------
514 void SAL_CALL SfxDocumentInfoObject::removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
516 _pImp->_aDisposeContainer.removeInterface( aListener );
518 //-----------------------------------------------------------------------------
520 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SfxDocumentInfoObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException )
522 ::osl::MutexGuard aGuard( _pImp->_aMutex );
524 uno::Reference<beans::XPropertySet> xPropSet(
525 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
526 MixedPropertySetInfo* pInfo = new MixedPropertySetInfo( lcl_GetDocInfoPropertyMap(), _pImp->m_UserDefined, xPropSet);
527 uno::Reference< beans::XPropertySetInfo > xInfo(
528 static_cast< beans::XPropertySetInfo* >(pInfo), uno::UNO_QUERY_THROW);
529 return xInfo;
532 //-----------------------------------------------------------------------------
534 void SAL_CALL SfxDocumentInfoObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aValue) throw (
535 uno::RuntimeException, beans::UnknownPropertyException,
536 beans::PropertyVetoException, lang::IllegalArgumentException,
537 lang::WrappedTargetException)
539 const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
540 // fix prop!
541 if ( pEntry )
542 setFastPropertyValue( pEntry->nWID, aValue );
543 else
544 // dynamic prop!
546 uno::Reference<beans::XPropertySet> xPropSet(
547 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
548 return xPropSet->setPropertyValue(aPropertyName, aValue);
552 //-----------------------------------------------------------------------------
554 uno::Any SAL_CALL SfxDocumentInfoObject::getPropertyValue(const ::rtl::OUString& aPropertyName) throw(
555 uno::RuntimeException, beans::UnknownPropertyException,
556 lang::WrappedTargetException)
558 const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
559 // fix prop!
560 if ( pEntry )
561 return getFastPropertyValue( pEntry->nWID );
562 else
563 // dynamic prop!
565 uno::Reference<beans::XPropertySet> xPropSet(
566 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
567 return xPropSet->getPropertyValue(aPropertyName);
571 sal_Bool SAL_CALL SfxDocumentInfoObject::isModified() throw(::com::sun::star::uno::RuntimeException)
573 uno::Reference<util::XModifiable> xModif(
574 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
575 return xModif->isModified();
578 void SAL_CALL SfxDocumentInfoObject::setModified( sal_Bool bModified )
579 throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)
581 uno::Reference<util::XModifiable> xModif(
582 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
583 return xModif->setModified(bModified);
586 void SAL_CALL SfxDocumentInfoObject::addModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
588 uno::Reference<util::XModifiable> xModif(
589 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
590 return xModif->addModifyListener(xListener);
593 void SAL_CALL SfxDocumentInfoObject::removeModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
595 uno::Reference<util::XModifiable> xModif(
596 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
597 return xModif->removeModifyListener(xListener);
600 //-----------------------------------------------------------------------------
602 void SAL_CALL SfxDocumentInfoObject::addPropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
603 uno::RuntimeException, beans::UnknownPropertyException,
604 lang::WrappedTargetException)
607 //-----------------------------------------------------------------------------
609 void SAL_CALL SfxDocumentInfoObject::removePropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
610 uno::RuntimeException, beans::UnknownPropertyException,
611 lang::WrappedTargetException)
614 //-----------------------------------------------------------------------------
616 void SAL_CALL SfxDocumentInfoObject::addVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
617 uno::RuntimeException, beans::UnknownPropertyException,
618 lang::WrappedTargetException)
621 //-----------------------------------------------------------------------------
623 void SAL_CALL SfxDocumentInfoObject::removeVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
624 uno::RuntimeException, beans::UnknownPropertyException,
625 lang::WrappedTargetException)
628 uno::Sequence< beans::PropertyValue > SAL_CALL SfxDocumentInfoObject::getPropertyValues( void ) throw( uno::RuntimeException )
630 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = getPropertySetInfo();
631 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps = xInfo->getProperties();
633 const ::com::sun::star::beans::Property* pProps = aProps.getConstArray();
634 sal_uInt32 nCount = aProps.getLength();
636 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >aSeq( nCount );
637 ::com::sun::star::beans::PropertyValue* pValues = aSeq.getArray();
639 for ( sal_uInt32 n = 0; n < nCount; ++n )
641 ::com::sun::star::beans::PropertyValue& rCurrValue = pValues[n];
642 const ::com::sun::star::beans::Property& rCurrProp = pProps[n];
644 rCurrValue.Name = rCurrProp.Name;
645 rCurrValue.Handle = rCurrProp.Handle;
646 rCurrValue.Value = getPropertyValue( rCurrProp.Name );
649 return aSeq;
652 void SAL_CALL SfxDocumentInfoObject::setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps )
653 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 )
655 const ::com::sun::star::beans::PropertyValue* pProps = aProps.getConstArray();
656 sal_uInt32 nCount = aProps.getLength();
658 for ( sal_uInt32 n = 0; n < nCount; ++n )
660 const ::com::sun::star::beans::PropertyValue& rProp = pProps[n];
661 setPropertyValue( rProp.Name, rProp.Value );
665 void SAL_CALL SfxDocumentInfoObject::addProperty(const ::rtl::OUString& sName ,
666 sal_Int16 nAttributes ,
667 const ::com::sun::star::uno::Any& aDefaultValue)
668 throw(::com::sun::star::beans::PropertyExistException ,
669 ::com::sun::star::beans::IllegalTypeException ,
670 ::com::sun::star::lang::IllegalArgumentException,
671 ::com::sun::star::uno::RuntimeException )
673 // clash with "fix" properties ?
674 sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
675 if ( bFixProp )
677 ::rtl::OUStringBuffer sMsg(256);
678 sMsg.appendAscii("The property \"" );
679 sMsg.append (sName );
680 sMsg.appendAscii("\" " );
681 if ( bFixProp )
682 sMsg.appendAscii(" already exists as a fix property. Please have a look into the IDL documentation of the DocumentInfo service.");
684 throw ::com::sun::star::beans::PropertyExistException(
685 sMsg.makeStringAndClear(),
686 static_cast< ::cppu::OWeakObject* >(this));
689 uno::Reference<beans::XPropertyContainer> xPropSet(
690 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
691 return xPropSet->addProperty(sName, nAttributes, aDefaultValue);
694 void SAL_CALL SfxDocumentInfoObject::removeProperty(const ::rtl::OUString& sName)
695 throw(::com::sun::star::beans::UnknownPropertyException,
696 ::com::sun::star::beans::NotRemoveableException ,
697 ::com::sun::star::uno::RuntimeException )
699 // clash with "fix" properties ?
700 sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
701 if ( bFixProp )
703 ::rtl::OUStringBuffer sMsg(256);
704 sMsg.appendAscii("The property \"" );
705 sMsg.append (sName );
706 sMsg.appendAscii("\" cant be removed. Its a fix property of the DocumentInfo service.");
708 throw ::com::sun::star::beans::NotRemoveableException(
709 sMsg.makeStringAndClear(),
710 static_cast< ::cppu::OWeakObject* >(this));
713 uno::Reference<beans::XPropertyContainer> xPropSet(
714 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
715 return xPropSet->removeProperty(sName);
718 BOOL equalsDateTime( const util::DateTime& D1, const util::DateTime& D2 )
720 return D1.HundredthSeconds == D2.HundredthSeconds &&
721 D1.Seconds == D2.Seconds &&
722 D1.Minutes == D2.Minutes &&
723 D1.Hours == D2.Hours &&
724 D1.Day == D2.Day &&
725 D1.Month == D2.Month &&
726 D1.Year == D2.Year;
729 void SAL_CALL SfxDocumentInfoObject::setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw(
730 uno::RuntimeException, beans::UnknownPropertyException,
731 beans::PropertyVetoException, lang::IllegalArgumentException,
732 lang::WrappedTargetException)
734 // Attention: Only fix properties should be provided by this method.
735 // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-)
737 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
739 if ( aValue.getValueType() == ::getCppuType((const ::rtl::OUString*)0) )
741 ::rtl::OUString sTemp ;
742 aValue >>= sTemp ;
743 switch ( nHandle )
745 case SID_APPLICATION :
746 _pImp->m_xDocProps->setGenerator(sTemp);
747 break;
748 case WID_FROM :
750 // QUESTION: do we still need this?
752 // String aStrVal( sTemp );
753 if ( aStrVal.Len() > TIMESTAMP_MAXLENGTH )
755 SvAddressParser aParser( aStrVal );
756 if ( aParser.Count() > 0 )
758 String aEmail = aParser.GetEmailAddress(0);
759 String aRealname = aParser.GetRealName(0);
761 if ( aRealname.Len() <= TIMESTAMP_MAXLENGTH )
762 aStrVal = aRealname;
763 else if ( aEmail.Len() <= TIMESTAMP_MAXLENGTH )
764 aStrVal = aEmail;
766 } */
768 if ( _pImp->m_xDocProps->getAuthor() != sTemp )
769 _pImp->m_xDocProps->setAuthor(sTemp);
770 break;
772 case MID_DOCINFO_PRINTEDBY:
773 if ( _pImp->m_xDocProps->getPrintedBy() != sTemp )
774 _pImp->m_xDocProps->setPrintedBy(sTemp);
775 break;
776 case MID_DOCINFO_MODIFICATIONAUTHOR:
777 if ( _pImp->m_xDocProps->getModifiedBy() != sTemp )
778 _pImp->m_xDocProps->setModifiedBy(sTemp);
779 break;
780 case WID_TITLE :
782 if ( _pImp->m_xDocProps->getTitle() != sTemp )
783 _pImp->m_xDocProps->setTitle(sTemp);
784 break;
786 case MID_DOCINFO_SUBJECT :
787 if ( _pImp->m_xDocProps->getSubject() != sTemp )
788 _pImp->m_xDocProps->setSubject(sTemp);
789 break;
790 case WID_KEYWORDS :
792 _pImp->m_xDocProps->setKeywords(
793 ::comphelper::string::convertCommaSeparated(sTemp));
795 break;
796 case MID_DOCINFO_TEMPLATE:
797 if ( _pImp->m_xDocProps->getTemplateName() != sTemp )
798 _pImp->m_xDocProps->setTemplateName(sTemp);
799 break;
800 case SID_TEMPLATE_NAME:
801 if ( _pImp->m_xDocProps->getTemplateURL() != sTemp )
802 _pImp->m_xDocProps->setTemplateURL(sTemp);
803 break;
804 case MID_DOCINFO_DESCRIPTION:
805 if ( _pImp->m_xDocProps->getDescription() != sTemp )
806 _pImp->m_xDocProps->setDescription(sTemp);
807 break;
808 case MID_DOCINFO_AUTOLOADURL:
809 if ( _pImp->m_xDocProps->getAutoloadURL() != sTemp )
810 _pImp->m_xDocProps->setAutoloadURL(sTemp);
811 break;
812 case MID_DOCINFO_DEFAULTTARGET:
813 if ( _pImp->m_xDocProps->getDefaultTarget() != sTemp )
814 _pImp->m_xDocProps->setDefaultTarget(sTemp);
815 break;
816 // case WID_CONTENT_TYPE : // this is readonly!
817 case MID_CATEGORY:
818 case MID_MANAGER:
819 case MID_COMPANY:
821 uno::Reference< document::XCompatWriterDocProperties > xWriterProps( _pImp->m_xDocProps, uno::UNO_QUERY );
822 if ( xWriterProps.is() )
824 if ( nHandle == MID_CATEGORY )
825 xWriterProps->setCategory( sTemp );
826 else if ( nHandle == MID_MANAGER )
827 xWriterProps->setManager( sTemp );
828 else
829 xWriterProps->setCompany( sTemp );
830 break;
833 default:
834 break;
837 else if ( aValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0) )
839 com::sun::star::util::DateTime aTemp;
840 aValue >>= aTemp ;
841 switch ( nHandle )
843 case WID_DATE_CREATED :
845 if ( !equalsDateTime(_pImp->m_xDocProps->getCreationDate(), aTemp ) )
847 _pImp->m_xDocProps->setCreationDate(aTemp);
849 break;
851 case WID_DATE_MODIFIED :
853 if ( !equalsDateTime(_pImp->m_xDocProps->getModificationDate(), aTemp ) )
855 _pImp->m_xDocProps->setModificationDate(aTemp);
857 break;
859 case MID_DOCINFO_PRINTDATE :
861 if ( !equalsDateTime(_pImp->m_xDocProps->getPrintDate(), aTemp ) )
863 _pImp->m_xDocProps->setPrintDate(aTemp);
865 break;
867 case MID_DOCINFO_TEMPLATEDATE :
869 if ( !equalsDateTime(_pImp->m_xDocProps->getTemplateDate(), aTemp ) )
871 _pImp->m_xDocProps->setTemplateDate(aTemp);
873 break;
875 default:
876 break;
880 else if ( aValue.getValueType() == ::getBooleanCppuType() )
882 sal_Bool bBoolVal = false;
883 aValue >>= bBoolVal ;
884 switch ( nHandle )
886 case MID_DOCINFO_AUTOLOADENABLED:
887 // NB: this property does not exist any more
888 // it is emulated as enabled iff delay > 0
889 if ( bBoolVal && (0 == _pImp->m_xDocProps->getAutoloadSecs()) ) {
890 _pImp->m_xDocProps->setAutoloadSecs(60); // default
891 } else if ( !bBoolVal && (0 != _pImp->m_xDocProps->getAutoloadSecs()) ) {
892 _pImp->m_xDocProps->setAutoloadSecs(0);
893 _pImp->m_xDocProps->setAutoloadURL(::rtl::OUString::createFromAscii(""));
895 break;
896 default:
897 break;
900 else if ( aValue.getValueType() == ::getCppuType((const sal_Int32*)0) )
902 sal_Int32 nIntVal = 0;
903 aValue >>= nIntVal ;
904 switch ( nHandle )
906 case MID_DOCINFO_AUTOLOADSECS:
907 if ( nIntVal != _pImp->m_xDocProps->getAutoloadSecs())
908 _pImp->m_xDocProps->setAutoloadSecs(nIntVal);
909 break;
910 case MID_DOCINFO_EDITTIME:
911 if ( nIntVal != _pImp->m_xDocProps->getEditingDuration())
912 _pImp->m_xDocProps->setEditingDuration(nIntVal);
913 break;
914 default:
915 break;
918 else if ( aValue.getValueType() == ::getCppuType((const sal_Int16*)0) )
920 short nIntVal = 0;
921 aValue >>= nIntVal ;
922 switch ( nHandle )
924 case MID_DOCINFO_REVISION:
925 if ( nIntVal != _pImp->m_xDocProps->getEditingCycles())
926 _pImp->m_xDocProps->setEditingCycles(nIntVal);
927 break;
928 default:
929 break;
932 else if ( aValue.getValueType() == ::getCppuType((const uno::Sequence< beans::NamedValue >*)0) )
934 if ( nHandle == MID_DOCINFO_STATISTIC )
936 uno::Sequence < beans::NamedValue > aData;
937 aValue >>= aData;
939 _pImp->m_xDocProps->setDocumentStatistics(aData);
943 else if ( aValue.getValueType() == ::getCppuType((const lang::Locale*)0) )
945 if ( nHandle == MID_DOCINFO_CHARLOCALE )
947 lang::Locale aLocale;
948 aValue >>= aLocale;
949 lang::Locale oldLocale = _pImp->m_xDocProps->getLanguage();
950 if ( aLocale.Language != oldLocale.Language ||
951 aLocale.Country != oldLocale.Country ||
952 aLocale.Variant != oldLocale.Variant )
954 _pImp->m_xDocProps->setLanguage(aLocale);
960 //-----------------------------------------------------------------------------
962 ::com::sun::star::uno::Any SAL_CALL SfxDocumentInfoObject::getFastPropertyValue(sal_Int32 nHandle) throw(
963 uno::RuntimeException, beans::UnknownPropertyException,
964 lang::WrappedTargetException)
966 // Attention: Only fix properties should be provided by this method.
967 // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-)
969 ::osl::MutexGuard aGuard( _pImp->_aMutex );
970 ::com::sun::star::uno::Any aValue;
971 switch ( nHandle )
973 case SID_APPLICATION :
974 aValue <<= _pImp->m_xDocProps->getGenerator();
975 break;
976 case WID_CONTENT_TYPE :
977 // FIXME this is not available anymore
978 aValue <<= ::rtl::OUString();
979 break;
980 case MID_DOCINFO_REVISION :
981 aValue <<= _pImp->m_xDocProps->getEditingCycles();
982 break;
983 case MID_DOCINFO_EDITTIME :
984 aValue <<= _pImp->m_xDocProps->getEditingDuration();
985 break;
986 case WID_FROM :
987 aValue <<= _pImp->m_xDocProps->getAuthor();
988 break;
989 case WID_DATE_CREATED :
990 if ( IsValidDateTime( _pImp->m_xDocProps->getCreationDate() ) )
991 aValue <<= _pImp->m_xDocProps->getCreationDate();
992 break;
993 case WID_TITLE :
994 aValue <<= _pImp->m_xDocProps->getTitle();
995 break;
996 case MID_DOCINFO_SUBJECT:
997 aValue <<= _pImp->m_xDocProps->getSubject();
998 break;
999 case MID_DOCINFO_MODIFICATIONAUTHOR:
1000 aValue <<= _pImp->m_xDocProps->getModifiedBy();
1001 break;
1002 case WID_DATE_MODIFIED :
1003 if ( IsValidDateTime( _pImp->m_xDocProps->getModificationDate() ) )
1004 aValue <<= _pImp->m_xDocProps->getModificationDate();
1005 break;
1006 case MID_DOCINFO_PRINTEDBY:
1007 aValue <<= _pImp->m_xDocProps->getPrintedBy();
1008 break;
1009 case MID_DOCINFO_PRINTDATE:
1010 if ( IsValidDateTime( _pImp->m_xDocProps->getPrintDate() ) )
1011 aValue <<= _pImp->m_xDocProps->getPrintDate();
1012 break;
1013 case WID_KEYWORDS :
1014 aValue <<= ::comphelper::string::convertCommaSeparated(
1015 _pImp->m_xDocProps->getKeywords());
1016 break;
1017 case MID_DOCINFO_DESCRIPTION:
1018 aValue <<= _pImp->m_xDocProps->getDescription();
1019 break;
1020 case MID_DOCINFO_TEMPLATE:
1021 aValue <<= _pImp->m_xDocProps->getTemplateName();
1022 break;
1023 case SID_TEMPLATE_NAME:
1024 aValue <<= _pImp->m_xDocProps->getTemplateURL();
1025 break;
1026 case MID_DOCINFO_TEMPLATEDATE:
1027 if ( IsValidDateTime( _pImp->m_xDocProps->getTemplateDate() ) )
1028 aValue <<= _pImp->m_xDocProps->getTemplateDate();
1029 break;
1030 case MID_DOCINFO_AUTOLOADENABLED:
1031 aValue <<= static_cast<sal_Bool>
1032 ( (_pImp->m_xDocProps->getAutoloadSecs() != 0)
1033 || !(_pImp->m_xDocProps->getAutoloadURL().equalsAscii("")));
1034 break;
1035 case MID_DOCINFO_AUTOLOADURL:
1036 aValue <<= _pImp->m_xDocProps->getAutoloadURL();
1037 break;
1038 case MID_DOCINFO_AUTOLOADSECS:
1039 aValue <<= _pImp->m_xDocProps->getAutoloadSecs();
1040 break;
1041 case MID_DOCINFO_DEFAULTTARGET:
1042 aValue <<= _pImp->m_xDocProps->getDefaultTarget();
1043 break;
1044 case MID_DOCINFO_STATISTIC:
1045 aValue <<= _pImp->m_xDocProps->getDocumentStatistics();
1046 break;
1047 case MID_DOCINFO_CHARLOCALE:
1048 aValue <<= _pImp->m_xDocProps->getLanguage();
1049 break;
1050 case MID_CATEGORY:
1051 case MID_MANAGER:
1052 case MID_COMPANY:
1054 uno::Reference< document::XCompatWriterDocProperties > xWriterProps( _pImp->m_xDocProps, uno::UNO_QUERY );
1055 if ( xWriterProps.is() )
1057 if ( nHandle == MID_CATEGORY )
1058 aValue <<= xWriterProps->getCategory();
1059 else if ( nHandle == MID_MANAGER )
1060 aValue <<= xWriterProps->getManager();
1061 else
1062 aValue <<= xWriterProps->getCompany();
1063 break;
1067 default:
1068 aValue <<= ::rtl::OUString();
1069 break;
1072 return aValue;
1075 //-----------------------------------------------------------------------------
1077 sal_Int16 SAL_CALL SfxDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
1079 // uno::Reference<beans::XPropertyAccess> xPropSet(
1080 // _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
1081 // return xPropSet->getPropertyValues().getLength();
1082 return FOUR;
1085 //-----------------------------------------------------------------------------
1087 ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1089 ::osl::MutexGuard aGuard( _pImp->_aMutex );
1090 if (nIndex < FOUR)
1091 return _pImp->m_UserDefined[nIndex];
1092 else
1093 return ::rtl::OUString();
1096 //-----------------------------------------------------------------------------
1098 ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1100 ::osl::MutexGuard aGuard( _pImp->_aMutex );
1101 if (nIndex < FOUR) {
1102 ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
1103 uno::Reference<beans::XPropertySet> xPropSet(
1104 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
1105 ::rtl::OUString val;
1106 try {
1107 xPropSet->getPropertyValue(name) >>= val;
1108 return val;
1109 } catch (uno::RuntimeException &) {
1110 throw;
1111 } catch (uno::Exception &) {
1112 return ::rtl::OUString(); // ignore
1114 } else
1115 return ::rtl::OUString();
1118 //-----------------------------------------------------------------------------
1120 void SAL_CALL SfxDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
1122 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
1123 if (nIndex < FOUR) // yes, four!
1125 // FIXME this is full of race conditions because the PropertyBag
1126 // can be accessed from clients of the DocumentProperties!
1127 ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
1128 if (name != aName) {
1129 uno::Reference<beans::XPropertySet> xPropSet(
1130 _pImp->m_xDocProps->getUserDefinedProperties(),
1131 uno::UNO_QUERY_THROW);
1132 uno::Reference<beans::XPropertyContainer> xPropContainer(
1133 _pImp->m_xDocProps->getUserDefinedProperties(),
1134 uno::UNO_QUERY_THROW);
1135 uno::Any value;
1136 try {
1137 value = xPropSet->getPropertyValue(name);
1138 xPropContainer->removeProperty(name);
1139 xPropContainer->addProperty(aName,
1140 beans::PropertyAttribute::REMOVEABLE, value);
1141 _pImp->m_UserDefined[nIndex] = aName;
1142 } catch (beans::UnknownPropertyException) {
1143 try {
1144 xPropContainer->addProperty(aName,
1145 beans::PropertyAttribute::REMOVEABLE,
1146 uno::makeAny(::rtl::OUString::createFromAscii("")));
1147 _pImp->m_UserDefined[nIndex] = aName;
1148 } catch (beans::PropertyExistException) {
1149 _pImp->m_UserDefined[nIndex] = aName;
1150 // ignore
1152 } catch (beans::PropertyExistException) {
1153 try {
1154 xPropContainer->addProperty(name,
1155 beans::PropertyAttribute::REMOVEABLE, value);
1156 } catch (beans::PropertyExistException) {
1157 // bugger...
1159 } catch (uno::RuntimeException &) {
1160 throw;
1161 } catch (uno::Exception &) {
1162 // ignore everything else; xPropSet _may_ be corrupted
1168 //-----------------------------------------------------------------------------
1170 void SAL_CALL SfxDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
1172 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
1173 if (nIndex < FOUR) // yes, four!
1175 ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
1176 uno::Reference<beans::XPropertySet> xPropSet(
1177 _pImp->m_xDocProps->getUserDefinedProperties(),
1178 uno::UNO_QUERY_THROW);
1179 uno::Reference<beans::XPropertyContainer> xPropContainer(
1180 _pImp->m_xDocProps->getUserDefinedProperties(),
1181 uno::UNO_QUERY_THROW);
1182 uno::Any aAny;
1183 aAny <<= aValue;
1184 try {
1185 uno::Any value = xPropSet->getPropertyValue(name);
1186 if (value != aAny) {
1187 xPropSet->setPropertyValue(name, aAny);
1189 } catch (beans::UnknownPropertyException) {
1190 try {
1191 // someone removed it, add it back again
1192 xPropContainer->addProperty(name,
1193 beans::PropertyAttribute::REMOVEABLE, aAny);
1194 } catch (uno::RuntimeException &) {
1195 throw;
1196 } catch (uno::Exception &) {
1197 // ignore everything else
1199 } catch (uno::RuntimeException &) {
1200 throw;
1201 } catch (uno::Exception &) {
1202 // ignore everything else
1207 //-----------------------------------------------------------------------------
1208 SFX_IMPL_XINTERFACE_2( SfxStandaloneDocumentInfoObject, SfxDocumentInfoObject, ::com::sun::star::lang::XServiceInfo, ::com::sun::star::document::XStandaloneDocumentInfo )
1209 SFX_IMPL_XTYPEPROVIDER_10( SfxStandaloneDocumentInfoObject, ::com::sun::star::document::XDocumentInfo, ::com::sun::star::lang::XComponent,
1210 ::com::sun::star::beans::XPropertySet, ::com::sun::star::beans::XFastPropertySet, ::com::sun::star::beans::XPropertyAccess,
1211 ::com::sun::star::beans::XPropertyContainer, ::com::sun::star::util::XModifiable, ::com::sun::star::util::XModifyBroadcaster,
1212 ::com::sun::star::document::XStandaloneDocumentInfo, ::com::sun::star::lang::XServiceInfo )
1214 SFX_IMPL_XSERVICEINFO( SfxStandaloneDocumentInfoObject, "com.sun.star.document.StandaloneDocumentInfo", "com.sun.star.comp.sfx2.StandaloneDocumentInfo" )
1215 SFX_IMPL_SINGLEFACTORY( SfxStandaloneDocumentInfoObject )
1217 SfxStandaloneDocumentInfoObject::SfxStandaloneDocumentInfoObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
1218 : SfxDocumentInfoObject()
1219 , _xFactory( xFactory )
1221 uno::Reference< lang::XInitialization > xDocProps(
1222 _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1223 "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW);
1224 // xDocProps->initialize(uno::Sequence<uno::Any>());
1225 uno::Any a;
1226 a <<= xDocProps;
1227 uno::Sequence<uno::Any> args(1);
1228 args[0] = a;
1229 initialize(args);
1232 //-----------------------------------------------------------------------------
1234 SfxStandaloneDocumentInfoObject::~SfxStandaloneDocumentInfoObject()
1238 //-----------------------------------------------------------------------------
1240 uno::Reference< embed::XStorage > GetStorage_Impl( const ::rtl::OUString& rName, sal_Bool bWrite, uno::Reference < lang::XMultiServiceFactory >& xFactory )
1242 // catch unexpected exceptions under solaris
1243 // Client code checks the returned reference but is not interested on error details.
1246 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1247 return ::comphelper::OStorageHelper::GetStorageFromURL(
1248 rName,
1249 bWrite ? embed::ElementModes::READWRITE : embed::ElementModes::READ,
1250 xFactory );
1252 catch(const uno::Exception&)
1255 return uno::Reference< embed::XStorage >();
1258 //-----------------------------------------------------------------------------
1260 sal_Int16 SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
1262 return SfxDocumentInfoObject::getUserFieldCount();
1265 //-----------------------------------------------------------------------------
1267 ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1269 return SfxDocumentInfoObject::getUserFieldName(nIndex);
1272 //-----------------------------------------------------------------------------
1274 ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1276 return SfxDocumentInfoObject::getUserFieldValue(nIndex);
1279 //-----------------------------------------------------------------------------
1281 void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
1283 SfxDocumentInfoObject::setUserFieldName( nIndex, aName );
1286 //-----------------------------------------------------------------------------
1288 void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
1290 SfxDocumentInfoObject::setUserFieldValue( nIndex, aValue );
1293 //-----------------------------------------------------------------------------
1295 void SAL_CALL SfxStandaloneDocumentInfoObject::loadFromURL(const ::rtl::OUString& aURL)
1296 throw( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException )
1298 sal_Bool bOK = sal_False;
1300 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
1301 uno::Reference< document::XDocumentProperties > xDocProps(
1302 _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1303 "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW);
1304 // uno::Reference< lang::XInitialization > xInit(xDocProps, uno::UNO_QUERY_THROW);
1305 // xInit->initialize(uno::Sequence<uno::Any>());
1306 _pImp->Reset(xDocProps);
1307 aGuard.clear();
1309 uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_False, _xFactory );
1310 if ( xStorage.is() )
1314 uno::Sequence<beans::PropertyValue> medium(2);
1315 medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL");
1316 medium[0].Value <<= aURL;
1317 medium[1].Name = ::rtl::OUString::createFromAscii("URL");
1318 medium[1].Value <<= aURL;
1319 _pImp->m_xDocProps->loadFromStorage(xStorage, medium);
1320 _pImp->Reset(_pImp->m_xDocProps);
1321 bOK = sal_True;
1323 catch( uno::Exception& )
1327 else
1329 uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
1330 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY );
1331 if ( xBinary.is() )
1333 xBinary->loadFromURL( aURL );
1334 bOK = sal_True;
1335 uno::Reference < document::XStandaloneDocumentInfo > xTarget( static_cast < document::XStandaloneDocumentInfo*> (this), uno::UNO_QUERY );
1336 Copy( xBinary, xTarget );
1340 if ( !bOK )
1341 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTREAD );
1344 //-----------------------------------------------------------------------------
1346 void SAL_CALL SfxStandaloneDocumentInfoObject::storeIntoURL(const ::rtl::OUString& aURL) throw( ::com::sun::star::io::IOException )
1348 sal_Bool bOK = sal_False;
1349 uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_True, _xFactory );
1350 if ( xStorage.is() )
1354 uno::Sequence<beans::PropertyValue> medium(2);
1355 medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL");
1356 medium[0].Value <<= aURL;
1357 medium[1].Name = ::rtl::OUString::createFromAscii("URL");
1358 medium[1].Value <<= aURL;
1360 _pImp->m_xDocProps->storeToStorage(xStorage, medium);
1361 bOK = sal_True;
1363 catch( io::IOException & )
1365 throw;
1367 catch( uno::RuntimeException& )
1369 throw;
1371 catch( uno::Exception& )
1375 else
1377 uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
1378 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY );
1379 if ( xBinary.is() )
1381 Copy( this, xBinary );
1382 xBinary->storeIntoURL( aURL );
1383 bOK = sal_True;
1387 if ( !bOK )
1388 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTWRITE );