Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / doc / objuno.cxx
blob64574a117202343c151c894ba0e7b52f635e208b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <com/sun/star/lang/DisposedException.hpp>
31 #include <com/sun/star/util/DateTime.hpp>
32 #include <com/sun/star/util/Date.hpp>
33 #include <com/sun/star/util/Time.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/beans/NamedValue.hpp>
36 #include <com/sun/star/beans/StringPair.hpp>
37 #include <com/sun/star/embed/ElementModes.hpp>
38 #include <com/sun/star/xml/sax/XParser.hpp>
39 #include <com/sun/star/document/XImporter.hpp>
40 #include <com/sun/star/document/XExporter.hpp>
41 #include <com/sun/star/io/XActiveDataSource.hpp>
42 #include <com/sun/star/document/XFilter.hpp>
43 #include <com/sun/star/embed/XTransactedObject.hpp>
44 #include <com/sun/star/lang/Locale.hpp>
45 #include <com/sun/star/util/XModifiable.hpp>
46 #include <com/sun/star/document/XDocumentProperties.hpp>
47 #include <com/sun/star/document/XCompatWriterDocProperties.hpp>
49 #include <unotools/configmgr.hxx>
50 #include <tools/inetdef.hxx>
51 #include <unotools/bootstrap.hxx>
52 #include <cppuhelper/interfacecontainer.hxx>
53 #include <osl/mutex.hxx>
54 #include <rtl/ustrbuf.hxx>
55 #include <vcl/svapp.hxx>
57 #include <tools/errcode.hxx>
58 #include <svl/cntwids.hrc>
59 #include <comphelper/string.hxx>
60 #include <comphelper/sequenceasvector.hxx>
61 #include <comphelper/storagehelper.hxx>
62 #include <sot/storage.hxx>
64 #include <sfx2/objuno.hxx>
65 #include <sfx2/sfx.hrc>
67 #include <vector>
68 #include <algorithm>
70 #include "sfx2/sfxresid.hxx"
71 #include "doc.hrc"
73 using namespace ::com::sun::star;
75 // TODO/REFACTOR: provide service for MS formats
76 // TODO/REFACTOR: IsEncrypted is never set nor read
77 // Generator is not saved ATM; which value?!
78 // Generator handling must be implemented
79 // Deprecate "Theme", rework IDL
80 // AutoLoadEnabled is deprecated?!
81 // Reasonable defaults for DateTime
82 // MIMEType readonly?!
83 // Announce changes about Theme, Language, Generator, removed entries etc.
84 // IsEncrypted is necessary for binary formats!
85 // Open: When to call PrepareDocInfoForSave? Currently only called for own formats and HTML/Writer
86 // Open: How to load and save EditingTime to MS formats
87 // PPT-Export should use SavePropertySet
89 //=============================================================================
91 // The number of user defined fields handled by the evil XDocumentInfo
92 // interface. There are exactly 4. No more, no less.
93 #define FOUR 4
95 #define PROPERTY_UNBOUND 0
96 #define PROPERTY_MAYBEVOID ::com::sun::star::beans::PropertyAttribute::MAYBEVOID
98 const SfxItemPropertyMapEntry* lcl_GetDocInfoPropertyMap()
100 static SfxItemPropertyMapEntry aDocInfoPropertyMap_Impl[] =
102 { "Author" , 6 , WID_FROM, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
103 { "AutoloadEnabled" , 15, MID_DOCINFO_AUTOLOADENABLED, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 },
104 { "AutoloadSecs" , 12, MID_DOCINFO_AUTOLOADSECS, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 },
105 { "AutoloadURL" , 11, MID_DOCINFO_AUTOLOADURL, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
106 { "Category" , 8 , MID_CATEGORY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
107 { "Company" , 7 , MID_COMPANY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
108 { "Manager" , 7 , MID_MANAGER, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
109 { "CreationDate" , 12, WID_DATE_CREATED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
110 { "DefaultTarget" , 13, MID_DOCINFO_DEFAULTTARGET, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
111 { "Description" , 11, MID_DOCINFO_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
112 { "DocumentStatistic", 17 , MID_DOCINFO_STATISTIC, &::getCppuType((const uno::Sequence< beans::NamedValue >*)0), PROPERTY_UNBOUND, 0 },
113 { "EditingCycles" , 13, MID_DOCINFO_REVISION, &::getCppuType((const sal_Int16*)0), PROPERTY_UNBOUND, 0 },
114 { "EditingDuration" , 15, MID_DOCINFO_EDITTIME, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 },
115 { "Generator" , 9, SID_APPLICATION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
116 { "Keywords" , 8 , WID_KEYWORDS, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
117 { "Language" , 8, MID_DOCINFO_CHARLOCALE, &::getCppuType((const lang::Locale*)0), PROPERTY_UNBOUND, 0 },
118 { "MIMEType" , 8 , WID_CONTENT_TYPE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND | ::com::sun::star::beans::PropertyAttribute::READONLY, 0 },
119 { "ModifiedBy" , 10, MID_DOCINFO_MODIFICATIONAUTHOR, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
120 { "ModifyDate" , 10, WID_DATE_MODIFIED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
121 { "PrintDate" , 9 , MID_DOCINFO_PRINTDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
122 { "PrintedBy" , 9 , MID_DOCINFO_PRINTEDBY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
123 { "Subject" , 7 , MID_DOCINFO_SUBJECT, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
124 { "Template" , 8 , MID_DOCINFO_TEMPLATE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
125 { "TemplateFileName", 16, SID_TEMPLATE_NAME, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
126 { "TemplateDate" , 12, MID_DOCINFO_TEMPLATEDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
127 { "Title" , 5 , WID_TITLE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
128 {0,0,0,0,0,0}
130 return aDocInfoPropertyMap_Impl;
133 static sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
134 31, 31, 30, 31, 30, 31 };
136 inline sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
138 if ( nMonth != 2 )
139 return aDaysInMonth[nMonth-1];
140 else
142 if ( (((nYear % 4) == 0) && ((nYear % 100) != 0)) ||
143 ((nYear % 400) == 0) )
144 return aDaysInMonth[nMonth-1] + 1;
145 else
146 return aDaysInMonth[nMonth-1];
150 bool IsValidDateTime( const util::DateTime& rDT )
152 if ( !rDT.Month || (rDT.Month > 12) )
153 return false;
154 if ( !rDT.Day || (rDT.Day > DaysInMonth( rDT.Month, rDT.Year )) )
155 return false;
156 else if ( rDT.Year <= 1582 )
158 if ( rDT.Year < 1582 )
159 return false;
160 else if ( rDT.Month < 10 )
161 return false;
162 else if ( (rDT.Month == 10) && (rDT.Day < 15) )
163 return false;
166 return true;
169 struct OUStringHashCode
171 size_t operator()( const ::rtl::OUString& sString ) const
173 return sString.hashCode();
177 struct SfxExtendedItemPropertyMap : public SfxItemPropertyMapEntry
179 ::com::sun::star::uno::Any aValue;
182 void Copy( const uno::Reference < document::XStandaloneDocumentInfo >& rSource, const uno::Reference < document::XStandaloneDocumentInfo >& rTarget )
186 uno::Reference< beans::XPropertySet > xSet( rSource, uno::UNO_QUERY );
187 uno::Reference< beans::XPropertySet > xTarget( rTarget, uno::UNO_QUERY );
188 uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
189 uno::Reference< beans::XPropertyContainer > xContainer( rTarget, uno::UNO_QUERY );
190 uno::Sequence< beans::Property > lProps = xSetInfo->getProperties();
191 const beans::Property* pProps = lProps.getConstArray();
192 sal_Int32 c = lProps.getLength();
193 sal_Int32 i = 0;
194 for (i=0; i<c; ++i)
196 uno::Any aValue = xSet->getPropertyValue( pProps[i].Name );
197 if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE )
198 // QUESTION: DefaultValue?!
199 xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue );
202 // it is possible that the propertysets from XML and binary files differ; we shouldn't break then
203 xTarget->setPropertyValue( pProps[i].Name, aValue );
205 catch ( const uno::Exception& ) {}
208 sal_Int16 nCount = rSource->getUserFieldCount();
209 sal_Int16 nSupportedCount = rTarget->getUserFieldCount();
210 for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ )
212 ::rtl::OUString aPropName = rSource->getUserFieldName( nInd );
213 rTarget->setUserFieldName( nInd, aPropName );
214 ::rtl::OUString aPropVal = rSource->getUserFieldValue( nInd );
215 rTarget->setUserFieldValue( nInd, aPropVal );
218 catch ( const uno::Exception& ) {}
221 class MixedPropertySetInfo : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
223 private:
225 SfxItemPropertyMap _aPropertyMap;
226 ::rtl::OUString* _pUserKeys;
227 uno::Reference<beans::XPropertySet> _xUDProps;
229 public:
231 MixedPropertySetInfo( const SfxItemPropertyMapEntry* pFixProps,
232 ::rtl::OUString* pUserKeys,
233 uno::Reference<beans::XPropertySet> xUDProps);
235 virtual ~MixedPropertySetInfo();
237 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties( ) throw (::com::sun::star::uno::RuntimeException);
238 virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
239 virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException);
242 //-----------------------------------------------------------------------------
244 MixedPropertySetInfo::MixedPropertySetInfo(const SfxItemPropertyMapEntry* pFixProps,
245 ::rtl::OUString* pUserKeys,
246 uno::Reference<beans::XPropertySet> xUDProps)
247 : _aPropertyMap( pFixProps )
248 , _pUserKeys(pUserKeys)
249 , _xUDProps(xUDProps)
253 //-----------------------------------------------------------------------------
255 MixedPropertySetInfo::~MixedPropertySetInfo()
259 //-----------------------------------------------------------------------------
261 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL MixedPropertySetInfo::getProperties()
262 throw(::com::sun::star::uno::RuntimeException)
264 ::comphelper::SequenceAsVector< ::com::sun::star::beans::Property > lProps;
266 // copy "fix" props
267 //todo: os: this ugly thing should be replaced
268 const SfxItemPropertyMapEntry* pFixProp = lcl_GetDocInfoPropertyMap();
270 while(pFixProp && pFixProp->pName)
272 ::com::sun::star::beans::Property aProp;
274 aProp.Name = ::rtl::OUString::createFromAscii(pFixProp->pName);
275 aProp.Handle = pFixProp->nWID;
276 aProp.Type = *(pFixProp->pType);
277 aProp.Attributes = (sal_Int16)(pFixProp->nFlags);
279 lProps.push_back(aProp);
280 ++pFixProp;
283 // copy "dynamic" props
285 // NB: this is really ugly:
286 // The returned properties must _not_ include the 4 user-defined fields!
287 // These are _not_ properties of the XDocumentInfo interface.
288 // Some things rely on this, e.g. Copy would break otherwise.
289 // This will have interesting consequences if someone expects to insert
290 // a property with the same name as an user-defined key, but nobody
291 // sane does that.
292 uno::Sequence<beans::Property> udProps =
293 _xUDProps->getPropertySetInfo()->getProperties();
294 for (sal_Int32 i = 0; i < udProps.getLength(); ++i) {
295 if (std::find(_pUserKeys, _pUserKeys+FOUR, udProps[i].Name)
296 == _pUserKeys+FOUR) {
297 // #i100027#: handles from udProps are not valid here
298 udProps[i].Handle = -1;
299 lProps.push_back(udProps[i]);
303 return lProps.getAsConstList();
306 //-----------------------------------------------------------------------------
308 ::com::sun::star::beans::Property SAL_CALL MixedPropertySetInfo::getPropertyByName(
309 const ::rtl::OUString& sName )
310 throw(::com::sun::star::beans::UnknownPropertyException,
311 ::com::sun::star::uno::RuntimeException )
313 ::com::sun::star::beans::Property aProp;
315 // search it as "fix" prop
316 if( _aPropertyMap.hasPropertyByName( sName ) )
317 return _aPropertyMap.getPropertyByName( sName );
318 else
319 // search it as "dynamic" prop
320 return _xUDProps->getPropertySetInfo()->getPropertyByName(sName);
323 //-----------------------------------------------------------------------------
325 ::sal_Bool SAL_CALL MixedPropertySetInfo::hasPropertyByName(const ::rtl::OUString& sName)
326 throw(::com::sun::star::uno::RuntimeException)
328 return _aPropertyMap.hasPropertyByName( sName ) ? // "fix" prop?
329 sal_True :
330 _xUDProps->getPropertySetInfo()->hasPropertyByName(sName); // "dynamic" prop?
333 //-----------------------------------------------------------------------------
335 struct SfxDocumentInfoObject_Impl
337 ::osl::Mutex _aMutex;
338 ::cppu::OInterfaceContainerHelper _aDisposeContainer;
340 sal_Bool bDisposed;
342 // this contains the names of the 4 user defined properties
343 // which are accessible via the evil XDocumentInfo interface
344 ::rtl::OUString m_UserDefined[FOUR];
346 // the actual contents
347 uno::Reference<document::XDocumentProperties> m_xDocProps;
348 SfxItemPropertyMap m_aPropertyMap;
350 SfxDocumentInfoObject_Impl()
351 : _aDisposeContainer( _aMutex )
352 , bDisposed(sal_False)
353 , m_xDocProps()
354 , m_aPropertyMap( lcl_GetDocInfoPropertyMap() )
356 // the number of user fields is not changeable from the outside
357 // we can't set it too high because every name/value pair will be written to the file (even if empty)
358 // currently our dialog has only 4 user keys so 4 is still a reasonable number
361 /// the initialization function
362 void Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined = 0);
365 void SfxDocumentInfoObject_Impl::Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined)
367 if (pUserDefined == 0) {
368 // NB: this is an ugly hack; the "Properties" ui dialog displays
369 // exactly 4 user-defined fields and expects these to be available
370 // (should be redesigned), but I do not want to do this in
371 // DocumentProperties; do it here instead
372 uno::Reference<beans::XPropertyAccess> xPropAccess(
373 xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
374 uno::Reference<beans::XPropertyContainer> xPropContainer(
375 xPropAccess, uno::UNO_QUERY_THROW);
376 uno::Sequence< beans::PropertyValue >
377 props = xPropAccess->getPropertyValues();
378 sal_Int32 oldLength = props.getLength();
379 if (oldLength < FOUR) {
380 std::vector< ::rtl::OUString > names;
381 for (sal_Int32 i = 0; i < oldLength; ++i) {
382 names.push_back(props[i].Name);
384 const ::rtl::OUString sInfo(
385 String( SfxResId( STR_DOCINFO_INFOFIELD ) ));
386 for (sal_Int32 i = oldLength; i < FOUR; ++i) {
387 ::rtl::OUString sName(sInfo);
388 sal_Int32 idx = sName.indexOfAsciiL("%1", 2);
389 ::rtl::OUString name = (idx > 0)
390 ? sName.replaceAt(idx, 2, ::rtl::OUString::valueOf(i+1))
391 : sName + ::rtl::OUString::valueOf(i+1);
392 while (std::find(names.begin(), names.end(), name)
393 != names.end()) {
394 name += ::rtl::OUString("'");
396 // FIXME there is a race condition here
397 try {
398 xPropContainer->addProperty(name,
399 beans::PropertyAttribute::REMOVEABLE,
400 uno::makeAny(::rtl::OUString("")));
401 } catch (const uno::RuntimeException&) {
402 throw;
403 } catch (const uno::Exception&) {
404 // ignore
408 props = xPropAccess->getPropertyValues();
409 for (sal_Int32 i = 0; i < FOUR; ++i) {
410 m_UserDefined[i] = props[i].Name;
412 } else {
413 std::copy(pUserDefined, pUserDefined+FOUR, m_UserDefined);
415 m_xDocProps = xDocProps;
418 //-----------------------------------------------------------------------------
420 SfxDocumentInfoObject::SfxDocumentInfoObject()
421 : _pImp( new SfxDocumentInfoObject_Impl() )
425 //-----------------------------------------------------------------------------
427 SfxDocumentInfoObject::~SfxDocumentInfoObject()
429 delete _pImp;
432 //-----------------------------------------------------------------------------
434 // ::com::sun::star::lang::XInitialization:
435 void SAL_CALL
436 SfxDocumentInfoObject::initialize(const uno::Sequence< uno::Any > & aArguments)
437 throw (uno::RuntimeException, uno::Exception)
439 if (aArguments.getLength() >= 1) {
440 uno::Any any = aArguments[0];
441 uno::Reference<document::XDocumentProperties> xDoc;
442 if (!(any >>= xDoc) || !xDoc.is()) throw lang::IllegalArgumentException(
443 ::rtl::OUString(
444 "SfxDocumentInfoObject::initialize: no XDocumentProperties given"),
445 *this, 0);
446 _pImp->Reset(xDoc);
447 } else {
448 throw lang::IllegalArgumentException(
449 ::rtl::OUString(
450 "SfxDocumentInfoObject::initialize: no argument given"),
451 *this, 0);
455 // ::com::sun::star::util::XCloneable:
456 uno::Reference<util::XCloneable> SAL_CALL
457 SfxDocumentInfoObject::createClone() throw (uno::RuntimeException)
459 SfxDocumentInfoObject *pNew = new SfxDocumentInfoObject;
460 uno::Reference< util::XCloneable >
461 xCloneable(_pImp->m_xDocProps, uno::UNO_QUERY_THROW);
462 uno::Reference<document::XDocumentProperties> xDocProps(
463 xCloneable->createClone(), uno::UNO_QUERY_THROW);
464 pNew->_pImp->Reset(xDocProps, _pImp->m_UserDefined);
465 return pNew;
468 // ::com::sun::star::document::XDocumentProperties:
469 uno::Reference< document::XDocumentProperties > SAL_CALL
470 SfxDocumentInfoObject::getDocumentProperties()
471 throw(::com::sun::star::uno::RuntimeException)
473 return _pImp->m_xDocProps;
476 //-----------------------------------------------------------------------------
478 const SfxDocumentInfoObject& SfxDocumentInfoObject::operator=( const SfxDocumentInfoObject & rOther)
480 uno::Reference< util::XCloneable >
481 xCloneable(rOther._pImp->m_xDocProps, uno::UNO_QUERY_THROW);
482 uno::Reference<document::XDocumentProperties> xDocProps(
483 xCloneable->createClone(), uno::UNO_QUERY_THROW);
484 _pImp->Reset(xDocProps, rOther._pImp->m_UserDefined);
485 return *this;
488 //-----------------------------------------------------------------------------
490 void SAL_CALL SfxDocumentInfoObject::dispose() throw( ::com::sun::star::uno::RuntimeException )
492 ::com::sun::star::lang::EventObject aEvent( (::cppu::OWeakObject *)this );
493 _pImp->_aDisposeContainer.disposeAndClear( aEvent );
494 ::osl::MutexGuard aGuard( _pImp->_aMutex );
495 _pImp->m_xDocProps = 0;
496 // NB: do not call m_xDocProps->dispose(), there could be other refs
497 _pImp->bDisposed = sal_True;
500 //-----------------------------------------------------------------------------
502 void SAL_CALL SfxDocumentInfoObject::addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
504 _pImp->_aDisposeContainer.addInterface( aListener );
507 //-----------------------------------------------------------------------------
509 void SAL_CALL SfxDocumentInfoObject::removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
511 _pImp->_aDisposeContainer.removeInterface( aListener );
513 //-----------------------------------------------------------------------------
515 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SfxDocumentInfoObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException )
517 ::osl::MutexGuard aGuard( _pImp->_aMutex );
519 uno::Reference<beans::XPropertySet> xPropSet(
520 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
521 MixedPropertySetInfo* pInfo = new MixedPropertySetInfo( lcl_GetDocInfoPropertyMap(), _pImp->m_UserDefined, xPropSet);
522 uno::Reference< beans::XPropertySetInfo > xInfo(
523 static_cast< beans::XPropertySetInfo* >(pInfo), uno::UNO_QUERY_THROW);
524 return xInfo;
527 //-----------------------------------------------------------------------------
529 void SAL_CALL SfxDocumentInfoObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aValue) throw (
530 uno::RuntimeException, beans::UnknownPropertyException,
531 beans::PropertyVetoException, lang::IllegalArgumentException,
532 lang::WrappedTargetException)
534 const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
535 // fix prop!
536 if ( pEntry )
537 setFastPropertyValue( pEntry->nWID, aValue );
538 else
539 // dynamic prop!
541 uno::Reference<beans::XPropertySet> xPropSet(
542 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
543 return xPropSet->setPropertyValue(aPropertyName, aValue);
547 //-----------------------------------------------------------------------------
549 uno::Any SAL_CALL SfxDocumentInfoObject::getPropertyValue(const ::rtl::OUString& aPropertyName) throw(
550 uno::RuntimeException, beans::UnknownPropertyException,
551 lang::WrappedTargetException)
553 const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
554 // fix prop!
555 if ( pEntry )
556 return getFastPropertyValue( pEntry->nWID );
557 else
558 // dynamic prop!
560 uno::Reference<beans::XPropertySet> xPropSet(
561 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
562 return xPropSet->getPropertyValue(aPropertyName);
566 sal_Bool SAL_CALL SfxDocumentInfoObject::isModified() throw(::com::sun::star::uno::RuntimeException)
568 uno::Reference<util::XModifiable> xModif(
569 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
570 return xModif->isModified();
573 void SAL_CALL SfxDocumentInfoObject::setModified( sal_Bool bModified )
574 throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)
576 uno::Reference<util::XModifiable> xModif(
577 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
578 return xModif->setModified(bModified);
581 void SAL_CALL SfxDocumentInfoObject::addModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
583 uno::Reference<util::XModifiable> xModif(
584 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
585 return xModif->addModifyListener(xListener);
588 void SAL_CALL SfxDocumentInfoObject::removeModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
590 uno::Reference<util::XModifiable> xModif(
591 _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
592 return xModif->removeModifyListener(xListener);
595 //-----------------------------------------------------------------------------
597 void SAL_CALL SfxDocumentInfoObject::addPropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
598 uno::RuntimeException, beans::UnknownPropertyException,
599 lang::WrappedTargetException)
602 //-----------------------------------------------------------------------------
604 void SAL_CALL SfxDocumentInfoObject::removePropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
605 uno::RuntimeException, beans::UnknownPropertyException,
606 lang::WrappedTargetException)
609 //-----------------------------------------------------------------------------
611 void SAL_CALL SfxDocumentInfoObject::addVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
612 uno::RuntimeException, beans::UnknownPropertyException,
613 lang::WrappedTargetException)
616 //-----------------------------------------------------------------------------
618 void SAL_CALL SfxDocumentInfoObject::removeVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
619 uno::RuntimeException, beans::UnknownPropertyException,
620 lang::WrappedTargetException)
623 uno::Sequence< beans::PropertyValue > SAL_CALL SfxDocumentInfoObject::getPropertyValues( void ) throw( uno::RuntimeException )
625 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = getPropertySetInfo();
626 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps = xInfo->getProperties();
628 const ::com::sun::star::beans::Property* pProps = aProps.getConstArray();
629 sal_uInt32 nCount = aProps.getLength();
631 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >aSeq( nCount );
632 ::com::sun::star::beans::PropertyValue* pValues = aSeq.getArray();
634 for ( sal_uInt32 n = 0; n < nCount; ++n )
636 ::com::sun::star::beans::PropertyValue& rCurrValue = pValues[n];
637 const ::com::sun::star::beans::Property& rCurrProp = pProps[n];
639 rCurrValue.Name = rCurrProp.Name;
640 rCurrValue.Handle = rCurrProp.Handle;
641 rCurrValue.Value = getPropertyValue( rCurrProp.Name );
644 return aSeq;
647 void SAL_CALL SfxDocumentInfoObject::setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps )
648 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 )
650 const ::com::sun::star::beans::PropertyValue* pProps = aProps.getConstArray();
651 sal_uInt32 nCount = aProps.getLength();
653 for ( sal_uInt32 n = 0; n < nCount; ++n )
655 const ::com::sun::star::beans::PropertyValue& rProp = pProps[n];
656 setPropertyValue( rProp.Name, rProp.Value );
660 void SAL_CALL SfxDocumentInfoObject::addProperty(const ::rtl::OUString& sName ,
661 sal_Int16 nAttributes ,
662 const ::com::sun::star::uno::Any& aDefaultValue)
663 throw(::com::sun::star::beans::PropertyExistException ,
664 ::com::sun::star::beans::IllegalTypeException ,
665 ::com::sun::star::lang::IllegalArgumentException,
666 ::com::sun::star::uno::RuntimeException )
668 // clash with "fix" properties ?
669 sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
670 if ( bFixProp )
672 ::rtl::OUStringBuffer sMsg(256);
673 sMsg.appendAscii(RTL_CONSTASCII_STRINGPARAM("The property \""));
674 sMsg.append(sName);
675 sMsg.appendAscii(RTL_CONSTASCII_STRINGPARAM("\" "));
676 if ( bFixProp )
677 sMsg.appendAscii(RTL_CONSTASCII_STRINGPARAM(" already exists as a fix property. Please have a look into the IDL documentation of the DocumentInfo service."));
679 throw ::com::sun::star::beans::PropertyExistException(
680 sMsg.makeStringAndClear(),
681 static_cast< ::cppu::OWeakObject* >(this));
684 uno::Reference<beans::XPropertyContainer> xPropSet(
685 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
686 return xPropSet->addProperty(sName, nAttributes, aDefaultValue);
689 void SAL_CALL SfxDocumentInfoObject::removeProperty(const ::rtl::OUString& sName)
690 throw(::com::sun::star::beans::UnknownPropertyException,
691 ::com::sun::star::beans::NotRemoveableException ,
692 ::com::sun::star::uno::RuntimeException )
694 // clash with "fix" properties ?
695 sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
696 if ( bFixProp )
698 ::rtl::OUStringBuffer sMsg(256);
699 sMsg.appendAscii(RTL_CONSTASCII_STRINGPARAM("The property \""));
700 sMsg.append(sName);
701 sMsg.appendAscii(RTL_CONSTASCII_STRINGPARAM("\" cant be removed. Its a fix property of the DocumentInfo service."));
703 throw ::com::sun::star::beans::NotRemoveableException(
704 sMsg.makeStringAndClear(),
705 static_cast< ::cppu::OWeakObject* >(this));
708 uno::Reference<beans::XPropertyContainer> xPropSet(
709 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
710 return xPropSet->removeProperty(sName);
713 sal_Bool equalsDateTime( const util::DateTime& D1, const util::DateTime& D2 )
715 return D1.HundredthSeconds == D2.HundredthSeconds &&
716 D1.Seconds == D2.Seconds &&
717 D1.Minutes == D2.Minutes &&
718 D1.Hours == D2.Hours &&
719 D1.Day == D2.Day &&
720 D1.Month == D2.Month &&
721 D1.Year == D2.Year;
724 void SAL_CALL SfxDocumentInfoObject::setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw(
725 uno::RuntimeException, beans::UnknownPropertyException,
726 beans::PropertyVetoException, lang::IllegalArgumentException,
727 lang::WrappedTargetException)
729 // Attention: Only fix properties should be provided by this method.
730 // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-)
732 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
734 if ( aValue.getValueType() == ::getCppuType((const ::rtl::OUString*)0) )
736 ::rtl::OUString sTemp ;
737 aValue >>= sTemp ;
738 switch ( nHandle )
740 case SID_APPLICATION :
741 _pImp->m_xDocProps->setGenerator(sTemp);
742 break;
743 case WID_FROM :
745 if ( _pImp->m_xDocProps->getAuthor() != sTemp )
746 _pImp->m_xDocProps->setAuthor(sTemp);
747 break;
749 case MID_DOCINFO_PRINTEDBY:
750 if ( _pImp->m_xDocProps->getPrintedBy() != sTemp )
751 _pImp->m_xDocProps->setPrintedBy(sTemp);
752 break;
753 case MID_DOCINFO_MODIFICATIONAUTHOR:
754 if ( _pImp->m_xDocProps->getModifiedBy() != sTemp )
755 _pImp->m_xDocProps->setModifiedBy(sTemp);
756 break;
757 case WID_TITLE :
759 if ( _pImp->m_xDocProps->getTitle() != sTemp )
760 _pImp->m_xDocProps->setTitle(sTemp);
761 break;
763 case MID_DOCINFO_SUBJECT :
764 if ( _pImp->m_xDocProps->getSubject() != sTemp )
765 _pImp->m_xDocProps->setSubject(sTemp);
766 break;
767 case WID_KEYWORDS :
769 _pImp->m_xDocProps->setKeywords(
770 ::comphelper::string::convertCommaSeparated(sTemp));
772 break;
773 case MID_DOCINFO_TEMPLATE:
774 if ( _pImp->m_xDocProps->getTemplateName() != sTemp )
775 _pImp->m_xDocProps->setTemplateName(sTemp);
776 break;
777 case SID_TEMPLATE_NAME:
778 if ( _pImp->m_xDocProps->getTemplateURL() != sTemp )
779 _pImp->m_xDocProps->setTemplateURL(sTemp);
780 break;
781 case MID_DOCINFO_DESCRIPTION:
782 if ( _pImp->m_xDocProps->getDescription() != sTemp )
783 _pImp->m_xDocProps->setDescription(sTemp);
784 break;
785 case MID_DOCINFO_AUTOLOADURL:
786 if ( _pImp->m_xDocProps->getAutoloadURL() != sTemp )
787 _pImp->m_xDocProps->setAutoloadURL(sTemp);
788 break;
789 case MID_DOCINFO_DEFAULTTARGET:
790 if ( _pImp->m_xDocProps->getDefaultTarget() != sTemp )
791 _pImp->m_xDocProps->setDefaultTarget(sTemp);
792 break;
793 case MID_CATEGORY:
794 case MID_MANAGER:
795 case MID_COMPANY:
797 uno::Reference< document::XCompatWriterDocProperties > xWriterProps( _pImp->m_xDocProps, uno::UNO_QUERY );
798 if ( xWriterProps.is() )
800 if ( nHandle == MID_CATEGORY )
801 xWriterProps->setCategory( sTemp );
802 else if ( nHandle == MID_MANAGER )
803 xWriterProps->setManager( sTemp );
804 else
805 xWriterProps->setCompany( sTemp );
806 break;
809 default:
810 break;
813 else if ( aValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0) )
815 com::sun::star::util::DateTime aTemp;
816 aValue >>= aTemp ;
817 switch ( nHandle )
819 case WID_DATE_CREATED :
821 if ( !equalsDateTime(_pImp->m_xDocProps->getCreationDate(), aTemp ) )
823 _pImp->m_xDocProps->setCreationDate(aTemp);
825 break;
827 case WID_DATE_MODIFIED :
829 if ( !equalsDateTime(_pImp->m_xDocProps->getModificationDate(), aTemp ) )
831 _pImp->m_xDocProps->setModificationDate(aTemp);
833 break;
835 case MID_DOCINFO_PRINTDATE :
837 if ( !equalsDateTime(_pImp->m_xDocProps->getPrintDate(), aTemp ) )
839 _pImp->m_xDocProps->setPrintDate(aTemp);
841 break;
843 case MID_DOCINFO_TEMPLATEDATE :
845 if ( !equalsDateTime(_pImp->m_xDocProps->getTemplateDate(), aTemp ) )
847 _pImp->m_xDocProps->setTemplateDate(aTemp);
849 break;
851 default:
852 break;
856 else if ( aValue.getValueType() == ::getBooleanCppuType() )
858 sal_Bool bBoolVal = false;
859 aValue >>= bBoolVal ;
860 switch ( nHandle )
862 case MID_DOCINFO_AUTOLOADENABLED:
863 // NB: this property does not exist any more
864 // it is emulated as enabled iff delay > 0
865 if ( bBoolVal && (0 == _pImp->m_xDocProps->getAutoloadSecs()) ) {
866 _pImp->m_xDocProps->setAutoloadSecs(60); // default
867 } else if ( !bBoolVal && (0 != _pImp->m_xDocProps->getAutoloadSecs()) ) {
868 _pImp->m_xDocProps->setAutoloadSecs(0);
869 _pImp->m_xDocProps->setAutoloadURL(::rtl::OUString(""));
871 break;
872 default:
873 break;
876 else if ( aValue.getValueType() == ::getCppuType((const sal_Int32*)0) )
878 sal_Int32 nIntVal = 0;
879 aValue >>= nIntVal ;
880 switch ( nHandle )
882 case MID_DOCINFO_AUTOLOADSECS:
883 if ( nIntVal != _pImp->m_xDocProps->getAutoloadSecs())
884 _pImp->m_xDocProps->setAutoloadSecs(nIntVal);
885 break;
886 case MID_DOCINFO_EDITTIME:
887 if ( nIntVal != _pImp->m_xDocProps->getEditingDuration())
888 _pImp->m_xDocProps->setEditingDuration(nIntVal);
889 break;
890 default:
891 break;
894 else if ( aValue.getValueType() == ::getCppuType((const sal_Int16*)0) )
896 short nIntVal = 0;
897 aValue >>= nIntVal ;
898 switch ( nHandle )
900 case MID_DOCINFO_REVISION:
901 if ( nIntVal != _pImp->m_xDocProps->getEditingCycles())
902 _pImp->m_xDocProps->setEditingCycles(nIntVal);
903 break;
904 default:
905 break;
908 else if ( aValue.getValueType() == ::getCppuType((const uno::Sequence< beans::NamedValue >*)0) )
910 if ( nHandle == MID_DOCINFO_STATISTIC )
912 uno::Sequence < beans::NamedValue > aData;
913 aValue >>= aData;
915 _pImp->m_xDocProps->setDocumentStatistics(aData);
919 else if ( aValue.getValueType() == ::getCppuType((const lang::Locale*)0) )
921 if ( nHandle == MID_DOCINFO_CHARLOCALE )
923 lang::Locale aLocale;
924 aValue >>= aLocale;
925 lang::Locale oldLocale = _pImp->m_xDocProps->getLanguage();
926 if ( aLocale.Language != oldLocale.Language ||
927 aLocale.Country != oldLocale.Country ||
928 aLocale.Variant != oldLocale.Variant )
930 _pImp->m_xDocProps->setLanguage(aLocale);
936 //-----------------------------------------------------------------------------
938 ::com::sun::star::uno::Any SAL_CALL SfxDocumentInfoObject::getFastPropertyValue(sal_Int32 nHandle) throw(
939 uno::RuntimeException, beans::UnknownPropertyException,
940 lang::WrappedTargetException)
942 // Attention: Only fix properties should be provided by this method.
943 // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-)
945 ::osl::MutexGuard aGuard( _pImp->_aMutex );
946 ::com::sun::star::uno::Any aValue;
947 switch ( nHandle )
949 case SID_APPLICATION :
950 aValue <<= _pImp->m_xDocProps->getGenerator();
951 break;
952 case WID_CONTENT_TYPE :
953 // FIXME this is not available anymore
954 aValue <<= ::rtl::OUString();
955 break;
956 case MID_DOCINFO_REVISION :
957 aValue <<= _pImp->m_xDocProps->getEditingCycles();
958 break;
959 case MID_DOCINFO_EDITTIME :
960 aValue <<= _pImp->m_xDocProps->getEditingDuration();
961 break;
962 case WID_FROM :
963 aValue <<= _pImp->m_xDocProps->getAuthor();
964 break;
965 case WID_DATE_CREATED :
966 if ( IsValidDateTime( _pImp->m_xDocProps->getCreationDate() ) )
967 aValue <<= _pImp->m_xDocProps->getCreationDate();
968 break;
969 case WID_TITLE :
970 aValue <<= _pImp->m_xDocProps->getTitle();
971 break;
972 case MID_DOCINFO_SUBJECT:
973 aValue <<= _pImp->m_xDocProps->getSubject();
974 break;
975 case MID_DOCINFO_MODIFICATIONAUTHOR:
976 aValue <<= _pImp->m_xDocProps->getModifiedBy();
977 break;
978 case WID_DATE_MODIFIED :
979 if ( IsValidDateTime( _pImp->m_xDocProps->getModificationDate() ) )
980 aValue <<= _pImp->m_xDocProps->getModificationDate();
981 break;
982 case MID_DOCINFO_PRINTEDBY:
983 aValue <<= _pImp->m_xDocProps->getPrintedBy();
984 break;
985 case MID_DOCINFO_PRINTDATE:
986 if ( IsValidDateTime( _pImp->m_xDocProps->getPrintDate() ) )
987 aValue <<= _pImp->m_xDocProps->getPrintDate();
988 break;
989 case WID_KEYWORDS :
990 aValue <<= ::comphelper::string::convertCommaSeparated(
991 _pImp->m_xDocProps->getKeywords());
992 break;
993 case MID_DOCINFO_DESCRIPTION:
994 aValue <<= _pImp->m_xDocProps->getDescription();
995 break;
996 case MID_DOCINFO_TEMPLATE:
997 aValue <<= _pImp->m_xDocProps->getTemplateName();
998 break;
999 case SID_TEMPLATE_NAME:
1000 aValue <<= _pImp->m_xDocProps->getTemplateURL();
1001 break;
1002 case MID_DOCINFO_TEMPLATEDATE:
1003 if ( IsValidDateTime( _pImp->m_xDocProps->getTemplateDate() ) )
1004 aValue <<= _pImp->m_xDocProps->getTemplateDate();
1005 break;
1006 case MID_DOCINFO_AUTOLOADENABLED:
1007 aValue <<= static_cast<sal_Bool>
1008 ( (_pImp->m_xDocProps->getAutoloadSecs() != 0)
1009 || !_pImp->m_xDocProps->getAutoloadURL().isEmpty());
1010 break;
1011 case MID_DOCINFO_AUTOLOADURL:
1012 aValue <<= _pImp->m_xDocProps->getAutoloadURL();
1013 break;
1014 case MID_DOCINFO_AUTOLOADSECS:
1015 aValue <<= _pImp->m_xDocProps->getAutoloadSecs();
1016 break;
1017 case MID_DOCINFO_DEFAULTTARGET:
1018 aValue <<= _pImp->m_xDocProps->getDefaultTarget();
1019 break;
1020 case MID_DOCINFO_STATISTIC:
1021 aValue <<= _pImp->m_xDocProps->getDocumentStatistics();
1022 break;
1023 case MID_DOCINFO_CHARLOCALE:
1024 aValue <<= _pImp->m_xDocProps->getLanguage();
1025 break;
1026 case MID_CATEGORY:
1027 case MID_MANAGER:
1028 case MID_COMPANY:
1030 uno::Reference< document::XCompatWriterDocProperties > xWriterProps( _pImp->m_xDocProps, uno::UNO_QUERY );
1031 if ( xWriterProps.is() )
1033 if ( nHandle == MID_CATEGORY )
1034 aValue <<= xWriterProps->getCategory();
1035 else if ( nHandle == MID_MANAGER )
1036 aValue <<= xWriterProps->getManager();
1037 else
1038 aValue <<= xWriterProps->getCompany();
1039 break;
1043 default:
1044 aValue <<= ::rtl::OUString();
1045 break;
1048 return aValue;
1051 //-----------------------------------------------------------------------------
1053 sal_Int16 SAL_CALL SfxDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
1055 return FOUR;
1058 //-----------------------------------------------------------------------------
1060 ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1062 ::osl::MutexGuard aGuard( _pImp->_aMutex );
1063 if (nIndex < FOUR)
1064 return _pImp->m_UserDefined[nIndex];
1065 else
1066 return ::rtl::OUString();
1069 //-----------------------------------------------------------------------------
1071 ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1073 ::osl::MutexGuard aGuard( _pImp->_aMutex );
1074 if (nIndex < FOUR) {
1075 ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
1076 uno::Reference<beans::XPropertySet> xPropSet(
1077 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
1078 ::rtl::OUString val;
1079 try {
1080 xPropSet->getPropertyValue(name) >>= val;
1081 return val;
1082 } catch (const uno::RuntimeException &) {
1083 throw;
1084 } catch (const uno::Exception &) {
1085 return ::rtl::OUString(); // ignore
1087 } else
1088 return ::rtl::OUString();
1091 //-----------------------------------------------------------------------------
1093 void SAL_CALL SfxDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
1095 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
1096 if (nIndex < FOUR) // yes, four!
1098 // FIXME this is full of race conditions because the PropertyBag
1099 // can be accessed from clients of the DocumentProperties!
1100 ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
1101 if (name != aName) {
1102 uno::Reference<beans::XPropertySet> xPropSet(
1103 _pImp->m_xDocProps->getUserDefinedProperties(),
1104 uno::UNO_QUERY_THROW);
1105 uno::Reference<beans::XPropertyContainer> xPropContainer(
1106 _pImp->m_xDocProps->getUserDefinedProperties(),
1107 uno::UNO_QUERY_THROW);
1108 uno::Any value;
1109 try {
1110 value = xPropSet->getPropertyValue(name);
1111 xPropContainer->removeProperty(name);
1112 xPropContainer->addProperty(aName,
1113 beans::PropertyAttribute::REMOVEABLE, value);
1114 _pImp->m_UserDefined[nIndex] = aName;
1115 } catch (const beans::UnknownPropertyException&) {
1116 try {
1117 xPropContainer->addProperty(aName,
1118 beans::PropertyAttribute::REMOVEABLE,
1119 uno::makeAny(::rtl::OUString("")));
1120 _pImp->m_UserDefined[nIndex] = aName;
1121 } catch (const beans::PropertyExistException&) {
1122 _pImp->m_UserDefined[nIndex] = aName;
1123 // ignore
1125 } catch (const beans::PropertyExistException&) {
1126 try {
1127 xPropContainer->addProperty(name,
1128 beans::PropertyAttribute::REMOVEABLE, value);
1129 } catch (const beans::PropertyExistException&) {
1130 // bugger...
1132 } catch (const uno::RuntimeException &) {
1133 throw;
1134 } catch (const uno::Exception &) {
1135 // ignore everything else; xPropSet _may_ be corrupted
1141 //-----------------------------------------------------------------------------
1143 void SAL_CALL SfxDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
1145 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
1146 if (nIndex < FOUR) // yes, four!
1148 ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
1149 uno::Reference<beans::XPropertySet> xPropSet(
1150 _pImp->m_xDocProps->getUserDefinedProperties(),
1151 uno::UNO_QUERY_THROW);
1152 uno::Reference<beans::XPropertyContainer> xPropContainer(
1153 _pImp->m_xDocProps->getUserDefinedProperties(),
1154 uno::UNO_QUERY_THROW);
1155 uno::Any aAny;
1156 aAny <<= aValue;
1157 try {
1158 uno::Any value = xPropSet->getPropertyValue(name);
1159 if (value != aAny) {
1160 xPropSet->setPropertyValue(name, aAny);
1162 } catch (const beans::UnknownPropertyException&) {
1163 try {
1164 // someone removed it, add it back again
1165 xPropContainer->addProperty(name,
1166 beans::PropertyAttribute::REMOVEABLE, aAny);
1167 } catch (const uno::RuntimeException &) {
1168 throw;
1169 } catch (const uno::Exception &) {
1170 // ignore everything else
1172 } catch (const uno::RuntimeException &) {
1173 throw;
1174 } catch (const uno::Exception &) {
1175 // ignore everything else
1180 //-----------------------------------------------------------------------------
1181 SFX_IMPL_XINTERFACE_2( SfxStandaloneDocumentInfoObject, SfxDocumentInfoObject, ::com::sun::star::lang::XServiceInfo, ::com::sun::star::document::XStandaloneDocumentInfo )
1182 SFX_IMPL_XTYPEPROVIDER_10( SfxStandaloneDocumentInfoObject, ::com::sun::star::document::XDocumentInfo, ::com::sun::star::lang::XComponent,
1183 ::com::sun::star::beans::XPropertySet, ::com::sun::star::beans::XFastPropertySet, ::com::sun::star::beans::XPropertyAccess,
1184 ::com::sun::star::beans::XPropertyContainer, ::com::sun::star::util::XModifiable, ::com::sun::star::util::XModifyBroadcaster,
1185 ::com::sun::star::document::XStandaloneDocumentInfo, ::com::sun::star::lang::XServiceInfo )
1187 SFX_IMPL_XSERVICEINFO( SfxStandaloneDocumentInfoObject, "com.sun.star.document.StandaloneDocumentInfo", "com.sun.star.comp.sfx2.StandaloneDocumentInfo" )
1188 SFX_IMPL_SINGLEFACTORY( SfxStandaloneDocumentInfoObject )
1190 SfxStandaloneDocumentInfoObject::SfxStandaloneDocumentInfoObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
1191 : SfxDocumentInfoObject()
1192 , _xFactory( xFactory )
1194 uno::Reference< lang::XInitialization > xDocProps(
1195 _xFactory->createInstance( ::rtl::OUString(
1196 "com.sun.star.document.DocumentProperties")), uno::UNO_QUERY_THROW);
1197 uno::Any a;
1198 a <<= xDocProps;
1199 uno::Sequence<uno::Any> args(1);
1200 args[0] = a;
1201 initialize(args);
1204 //-----------------------------------------------------------------------------
1206 SfxStandaloneDocumentInfoObject::~SfxStandaloneDocumentInfoObject()
1210 //-----------------------------------------------------------------------------
1212 uno::Reference< embed::XStorage > GetStorage_Impl( const ::rtl::OUString& rName, sal_Bool bWrite, uno::Reference < lang::XMultiServiceFactory >& xFactory )
1214 // catch unexpected exceptions under solaris
1215 // Client code checks the returned reference but is not interested on error details.
1218 SolarMutexGuard aSolarGuard;
1219 return ::comphelper::OStorageHelper::GetStorageFromURL(
1220 rName,
1221 bWrite ? embed::ElementModes::READWRITE : embed::ElementModes::READ,
1222 xFactory );
1224 catch(const uno::Exception&)
1227 return uno::Reference< embed::XStorage >();
1230 //-----------------------------------------------------------------------------
1232 sal_Int16 SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
1234 return SfxDocumentInfoObject::getUserFieldCount();
1237 //-----------------------------------------------------------------------------
1239 ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1241 return SfxDocumentInfoObject::getUserFieldName(nIndex);
1244 //-----------------------------------------------------------------------------
1246 ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
1248 return SfxDocumentInfoObject::getUserFieldValue(nIndex);
1251 //-----------------------------------------------------------------------------
1253 void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
1255 SfxDocumentInfoObject::setUserFieldName( nIndex, aName );
1258 //-----------------------------------------------------------------------------
1260 void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
1262 SfxDocumentInfoObject::setUserFieldValue( nIndex, aValue );
1265 //-----------------------------------------------------------------------------
1267 void SAL_CALL SfxStandaloneDocumentInfoObject::loadFromURL(const ::rtl::OUString& aURL)
1268 throw( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException )
1270 sal_Bool bOK = sal_False;
1272 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
1273 uno::Reference< document::XDocumentProperties > xDocProps(
1274 _xFactory->createInstance( ::rtl::OUString(
1275 "com.sun.star.document.DocumentProperties")), uno::UNO_QUERY_THROW);
1276 _pImp->Reset(xDocProps);
1277 aGuard.clear();
1279 uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_False, _xFactory );
1280 if ( xStorage.is() )
1284 uno::Sequence<beans::PropertyValue> medium(2);
1285 medium[0].Name = ::rtl::OUString("DocumentBaseURL");
1286 medium[0].Value <<= aURL;
1287 medium[1].Name = ::rtl::OUString("URL");
1288 medium[1].Value <<= aURL;
1289 _pImp->m_xDocProps->loadFromStorage(xStorage, medium);
1290 _pImp->Reset(_pImp->m_xDocProps);
1291 bOK = sal_True;
1293 catch( const uno::Exception& )
1297 else
1299 uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
1300 ::rtl::OUString("com.sun.star.document.BinaryStandaloneDocumentInfo" ) ), uno::UNO_QUERY );
1301 if ( xBinary.is() )
1303 xBinary->loadFromURL( aURL );
1304 bOK = sal_True;
1305 uno::Reference < document::XStandaloneDocumentInfo > xTarget( static_cast < document::XStandaloneDocumentInfo*> (this), uno::UNO_QUERY );
1306 Copy( xBinary, xTarget );
1310 if ( !bOK )
1311 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTREAD );
1314 //-----------------------------------------------------------------------------
1316 void SAL_CALL SfxStandaloneDocumentInfoObject::storeIntoURL(const ::rtl::OUString& aURL) throw( ::com::sun::star::io::IOException )
1318 sal_Bool bOK = sal_False;
1319 uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_True, _xFactory );
1320 if ( xStorage.is() )
1324 uno::Sequence<beans::PropertyValue> medium(2);
1325 medium[0].Name = ::rtl::OUString("DocumentBaseURL");
1326 medium[0].Value <<= aURL;
1327 medium[1].Name = ::rtl::OUString("URL");
1328 medium[1].Value <<= aURL;
1330 _pImp->m_xDocProps->storeToStorage(xStorage, medium);
1331 bOK = sal_True;
1333 catch( const io::IOException & )
1335 throw;
1337 catch( const uno::RuntimeException& )
1339 throw;
1341 catch( const uno::Exception& )
1345 else
1347 uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
1348 ::rtl::OUString("com.sun.star.document.BinaryStandaloneDocumentInfo" ) ), uno::UNO_QUERY );
1349 if ( xBinary.is() )
1351 Copy( this, xBinary );
1352 xBinary->storeIntoURL( aURL );
1353 bOK = sal_True;
1357 if ( !bOK )
1358 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTWRITE );
1361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */