1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include <com/sun/star/lang/DisposedException.hpp> 32 #include <com/sun/star/util/DateTime.hpp> 33 #include <com/sun/star/util/Date.hpp> 34 #include <com/sun/star/util/Time.hpp> 35 #include <com/sun/star/beans/PropertyAttribute.hpp> 36 #include <com/sun/star/beans/NamedValue.hpp> 37 #include <com/sun/star/beans/StringPair.hpp> 38 #include <com/sun/star/embed/ElementModes.hpp> 39 #include <com/sun/star/xml/sax/XParser.hpp> 40 #include <com/sun/star/document/XImporter.hpp> 41 #include <com/sun/star/document/XExporter.hpp> 42 #include <com/sun/star/io/XActiveDataSource.hpp> 43 #include <com/sun/star/document/XFilter.hpp> 44 #include <com/sun/star/embed/XTransactedObject.hpp> 45 #include <com/sun/star/lang/Locale.hpp> 46 #include <com/sun/star/util/XModifiable.hpp> 47 #include <com/sun/star/document/XDocumentProperties.hpp> 48 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> 56 #include <vos/mutex.hxx> 57 58 #include <tools/errcode.hxx> 59 #include <svl/cntwids.hrc> 60 #include <comphelper/string.hxx> 61 #include <comphelper/sequenceasvector.hxx> 62 #include <comphelper/storagehelper.hxx> 63 #include <sot/storage.hxx> 64 65 #include <sfx2/objuno.hxx> 66 #include <sfx2/sfx.hrc> 67 68 #include <vector> 69 #include <algorithm> 70 71 #include "sfx2/sfxresid.hxx" 72 #include "doc.hrc" 73 74 using namespace ::com::sun::star; 75 76 // TODO/REFACTOR: provide service for MS formats 77 // TODO/REFACTOR: IsEncrypted is never set nor read 78 // Generator is not saved ATM; which value?! 79 // Generator handling must be implemented 80 // Deprecate "Theme", rework IDL 81 // AutoLoadEnabled is deprecated?! 82 // Reasonable defaults for DateTime 83 // MIMEType readonly?! 84 // Announce changes about Theme, Language, Generator, removed entries etc. 85 // IsEncrypted is necessary for binary formats! 86 // Open: When to call PrepareDocInfoForSave? Currently only called for own formats and HTML/Writer 87 // Open: How to load and save EditingTime to MS formats 88 // PPT-Export should use SavePropertySet 89 90 //============================================================================= 91 92 // The number of user defined fields handled by the evil XDocumentInfo 93 // interface. There are exactly 4. No more, no less. 94 #define FOUR 4 95 96 #define PROPERTY_UNBOUND 0 97 #define PROPERTY_MAYBEVOID ::com::sun::star::beans::PropertyAttribute::MAYBEVOID 98 99 const SfxItemPropertyMapEntry* lcl_GetDocInfoPropertyMap() 100 { 101 static SfxItemPropertyMapEntry aDocInfoPropertyMap_Impl[] = 102 { 103 { "Author" , 6 , WID_FROM, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 104 { "AutoloadEnabled" , 15, MID_DOCINFO_AUTOLOADENABLED, &::getBooleanCppuType(), PROPERTY_UNBOUND, 0 }, 105 { "AutoloadSecs" , 12, MID_DOCINFO_AUTOLOADSECS, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 }, 106 { "AutoloadURL" , 11, MID_DOCINFO_AUTOLOADURL, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 107 { "CreationDate" , 12, WID_DATE_CREATED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, 108 { "DefaultTarget" , 13, MID_DOCINFO_DEFAULTTARGET, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 109 { "Description" , 11, MID_DOCINFO_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 110 { "DocumentStatistic", 17 , MID_DOCINFO_STATISTIC, &::getCppuType((const uno::Sequence< beans::NamedValue >*)0), PROPERTY_UNBOUND, 0 }, 111 { "EditingCycles" , 13, MID_DOCINFO_REVISION, &::getCppuType((const sal_Int16*)0), PROPERTY_UNBOUND, 0 }, 112 { "EditingDuration" , 15, MID_DOCINFO_EDITTIME, &::getCppuType((const sal_Int32*)0), PROPERTY_UNBOUND, 0 }, 113 { "Generator" , 9, SID_APPLICATION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 114 { "Keywords" , 8 , WID_KEYWORDS, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 115 { "Language" , 8, MID_DOCINFO_CHARLOCALE, &::getCppuType((const lang::Locale*)0), PROPERTY_UNBOUND, 0 }, 116 { "MIMEType" , 8 , WID_CONTENT_TYPE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND | ::com::sun::star::beans::PropertyAttribute::READONLY, 0 }, 117 { "ModifiedBy" , 10, MID_DOCINFO_MODIFICATIONAUTHOR, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 118 { "ModifyDate" , 10, WID_DATE_MODIFIED, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, 119 { "PrintDate" , 9 , MID_DOCINFO_PRINTDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, 120 { "PrintedBy" , 9 , MID_DOCINFO_PRINTEDBY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 121 { "Subject" , 7 , MID_DOCINFO_SUBJECT, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 122 { "Template" , 8 , MID_DOCINFO_TEMPLATE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 123 { "TemplateFileName", 16, SID_TEMPLATE_NAME, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 124 { "TemplateDate" , 12, MID_DOCINFO_TEMPLATEDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 }, 125 { "Title" , 5 , WID_TITLE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 }, 126 {0,0,0,0,0,0} 127 }; 128 return aDocInfoPropertyMap_Impl; 129 } 130 131 static sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30, 132 31, 31, 30, 31, 30, 31 }; 133 134 inline sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear ) 135 { 136 if ( nMonth != 2 ) 137 return aDaysInMonth[nMonth-1]; 138 else 139 { 140 if ( (((nYear % 4) == 0) && ((nYear % 100) != 0)) || 141 ((nYear % 400) == 0) ) 142 return aDaysInMonth[nMonth-1] + 1; 143 else 144 return aDaysInMonth[nMonth-1]; 145 } 146 } 147 148 bool IsValidDateTime( const util::DateTime& rDT ) 149 { 150 if ( !rDT.Month || (rDT.Month > 12) ) 151 return false; 152 if ( !rDT.Day || (rDT.Day > DaysInMonth( rDT.Month, rDT.Year )) ) 153 return false; 154 else if ( rDT.Year <= 1582 ) 155 { 156 if ( rDT.Year < 1582 ) 157 return false; 158 else if ( rDT.Month < 10 ) 159 return false; 160 else if ( (rDT.Month == 10) && (rDT.Day < 15) ) 161 return false; 162 } 163 164 return true; 165 } 166 167 struct OUStringHashCode 168 { 169 size_t operator()( const ::rtl::OUString& sString ) const 170 { 171 return sString.hashCode(); 172 } 173 }; 174 175 struct SfxExtendedItemPropertyMap : public SfxItemPropertyMapEntry 176 { 177 ::com::sun::star::uno::Any aValue; 178 }; 179 180 void Copy( const uno::Reference < document::XStandaloneDocumentInfo >& rSource, const uno::Reference < document::XStandaloneDocumentInfo >& rTarget ) 181 { 182 try 183 { 184 uno::Reference< beans::XPropertySet > xSet( rSource, uno::UNO_QUERY ); 185 uno::Reference< beans::XPropertySet > xTarget( rTarget, uno::UNO_QUERY ); 186 uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo(); 187 uno::Reference< beans::XPropertyContainer > xContainer( rTarget, uno::UNO_QUERY ); 188 uno::Sequence< beans::Property > lProps = xSetInfo->getProperties(); 189 const beans::Property* pProps = lProps.getConstArray(); 190 sal_Int32 c = lProps.getLength(); 191 sal_Int32 i = 0; 192 for (i=0; i<c; ++i) 193 { 194 uno::Any aValue = xSet->getPropertyValue( pProps[i].Name ); 195 if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE ) 196 // QUESTION: DefaultValue?! 197 xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue ); 198 try 199 { 200 // it is possible that the propertysets from XML and binary files differ; we shouldn't break then 201 xTarget->setPropertyValue( pProps[i].Name, aValue ); 202 } 203 catch ( uno::Exception& ) {} 204 } 205 206 sal_Int16 nCount = rSource->getUserFieldCount(); 207 sal_Int16 nSupportedCount = rTarget->getUserFieldCount(); 208 for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ ) 209 { 210 ::rtl::OUString aPropName = rSource->getUserFieldName( nInd ); 211 rTarget->setUserFieldName( nInd, aPropName ); 212 ::rtl::OUString aPropVal = rSource->getUserFieldValue( nInd ); 213 rTarget->setUserFieldValue( nInd, aPropVal ); 214 } 215 } 216 catch ( uno::Exception& ) {} 217 } 218 219 class MixedPropertySetInfo : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo > 220 { 221 private: 222 223 SfxItemPropertyMap _aPropertyMap; 224 ::rtl::OUString* _pUserKeys; 225 uno::Reference<beans::XPropertySet> _xUDProps; 226 227 public: 228 229 MixedPropertySetInfo( const SfxItemPropertyMapEntry* pFixProps, 230 ::rtl::OUString* pUserKeys, 231 uno::Reference<beans::XPropertySet> xUDProps); 232 233 virtual ~MixedPropertySetInfo(); 234 235 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties( ) throw (::com::sun::star::uno::RuntimeException); 236 virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); 237 virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException); 238 }; 239 240 //----------------------------------------------------------------------------- 241 242 MixedPropertySetInfo::MixedPropertySetInfo(const SfxItemPropertyMapEntry* pFixProps, 243 ::rtl::OUString* pUserKeys, 244 uno::Reference<beans::XPropertySet> xUDProps) 245 : _aPropertyMap( pFixProps ) 246 , _pUserKeys(pUserKeys) 247 , _xUDProps(xUDProps) 248 { 249 } 250 251 //----------------------------------------------------------------------------- 252 253 MixedPropertySetInfo::~MixedPropertySetInfo() 254 { 255 } 256 257 //----------------------------------------------------------------------------- 258 259 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL MixedPropertySetInfo::getProperties() 260 throw(::com::sun::star::uno::RuntimeException) 261 { 262 ::comphelper::SequenceAsVector< ::com::sun::star::beans::Property > lProps; 263 264 // copy "fix" props 265 //todo: os: this ugly thing should be replaced 266 const SfxItemPropertyMapEntry* pFixProp = lcl_GetDocInfoPropertyMap(); 267 268 while(pFixProp && pFixProp->pName) 269 { 270 ::com::sun::star::beans::Property aProp; 271 272 aProp.Name = ::rtl::OUString::createFromAscii(pFixProp->pName); 273 aProp.Handle = pFixProp->nWID; 274 aProp.Type = *(pFixProp->pType); 275 aProp.Attributes = (sal_Int16)(pFixProp->nFlags); 276 277 lProps.push_back(aProp); 278 ++pFixProp; 279 } 280 281 // copy "dynamic" props 282 283 // NB: this is really ugly: 284 // The returned properties must _not_ include the 4 user-defined fields! 285 // These are _not_ properties of the XDocumentInfo interface. 286 // Some things rely on this, e.g. Copy would break otherwise. 287 // This will have interesting consequences if someone expects to insert 288 // a property with the same name as an user-defined key, but nobody 289 // sane does that. 290 uno::Sequence<beans::Property> udProps = 291 _xUDProps->getPropertySetInfo()->getProperties(); 292 for (sal_Int32 i = 0; i < udProps.getLength(); ++i) { 293 if (std::find(_pUserKeys, _pUserKeys+FOUR, udProps[i].Name) 294 == _pUserKeys+FOUR) { 295 // #i100027#: handles from udProps are not valid here 296 udProps[i].Handle = -1; 297 lProps.push_back(udProps[i]); 298 } 299 } 300 301 return lProps.getAsConstList(); 302 } 303 304 //----------------------------------------------------------------------------- 305 306 ::com::sun::star::beans::Property SAL_CALL MixedPropertySetInfo::getPropertyByName( 307 const ::rtl::OUString& sName ) 308 throw(::com::sun::star::beans::UnknownPropertyException, 309 ::com::sun::star::uno::RuntimeException ) 310 { 311 ::com::sun::star::beans::Property aProp; 312 313 // search it as "fix" prop 314 if( _aPropertyMap.hasPropertyByName( sName ) ) 315 return _aPropertyMap.getPropertyByName( sName ); 316 else 317 // search it as "dynamic" prop 318 return _xUDProps->getPropertySetInfo()->getPropertyByName(sName); 319 } 320 321 //----------------------------------------------------------------------------- 322 323 ::sal_Bool SAL_CALL MixedPropertySetInfo::hasPropertyByName(const ::rtl::OUString& sName) 324 throw(::com::sun::star::uno::RuntimeException) 325 { 326 return _aPropertyMap.hasPropertyByName( sName ) ? // "fix" prop? 327 sal_True : 328 _xUDProps->getPropertySetInfo()->hasPropertyByName(sName); // "dynamic" prop? 329 } 330 331 //----------------------------------------------------------------------------- 332 333 struct SfxDocumentInfoObject_Impl 334 { 335 ::osl::Mutex _aMutex; 336 ::cppu::OInterfaceContainerHelper _aDisposeContainer; 337 338 sal_Bool bDisposed; 339 340 // this contains the names of the 4 user defined properties 341 // which are accessible via the evil XDocumentInfo interface 342 ::rtl::OUString m_UserDefined[FOUR]; 343 344 // the actual contents 345 uno::Reference<document::XDocumentProperties> m_xDocProps; 346 SfxItemPropertyMap m_aPropertyMap; 347 348 SfxDocumentInfoObject_Impl() 349 : _aDisposeContainer( _aMutex ) 350 , bDisposed(sal_False) 351 , m_xDocProps() 352 , m_aPropertyMap( lcl_GetDocInfoPropertyMap() ) 353 { 354 // the number of user fields is not changeable from the outside 355 // we can't set it too high because every name/value pair will be written to the file (even if empty) 356 // currently our dialog has only 4 user keys so 4 is still a reasonable number 357 } 358 359 /// the initialization function 360 void Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined = 0); 361 }; 362 363 void SfxDocumentInfoObject_Impl::Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined) 364 { 365 if (pUserDefined == 0) { 366 // NB: this is an ugly hack; the "Properties" ui dialog displays 367 // exactly 4 user-defined fields and expects these to be available 368 // (should be redesigned), but I do not want to do this in 369 // DocumentProperties; do it here instead 370 uno::Reference<beans::XPropertyAccess> xPropAccess( 371 xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 372 uno::Reference<beans::XPropertyContainer> xPropContainer( 373 xPropAccess, uno::UNO_QUERY_THROW); 374 uno::Sequence< beans::PropertyValue > 375 props = xPropAccess->getPropertyValues(); 376 sal_Int32 oldLength = props.getLength(); 377 if (oldLength < FOUR) { 378 std::vector< ::rtl::OUString > names; 379 for (sal_Int32 i = 0; i < oldLength; ++i) { 380 names.push_back(props[i].Name); 381 } 382 const ::rtl::OUString sInfo( 383 String( SfxResId( STR_DOCINFO_INFOFIELD ) )); 384 for (sal_Int32 i = oldLength; i < FOUR; ++i) { 385 ::rtl::OUString sName(sInfo); 386 sal_Int32 idx = sName.indexOfAsciiL("%1", 2); 387 ::rtl::OUString name = (idx > 0) 388 ? sName.replaceAt(idx, 2, ::rtl::OUString::valueOf(i+1)) 389 : sName + ::rtl::OUString::valueOf(i+1); 390 while (std::find(names.begin(), names.end(), name) 391 != names.end()) { 392 name += ::rtl::OUString::createFromAscii("'"); 393 } 394 // FIXME there is a race condition here 395 try { 396 xPropContainer->addProperty(name, 397 beans::PropertyAttribute::REMOVEABLE, 398 uno::makeAny(::rtl::OUString::createFromAscii(""))); 399 } catch (uno::RuntimeException) { 400 throw; 401 } catch (uno::Exception) { 402 // ignore 403 } 404 } 405 } 406 props = xPropAccess->getPropertyValues(); 407 for (sal_Int32 i = 0; i < FOUR; ++i) { 408 m_UserDefined[i] = props[i].Name; 409 } 410 } else { 411 std::copy(pUserDefined, pUserDefined+FOUR, m_UserDefined); 412 } 413 m_xDocProps = xDocProps; 414 } 415 416 //----------------------------------------------------------------------------- 417 418 SfxDocumentInfoObject::SfxDocumentInfoObject() 419 : _pImp( new SfxDocumentInfoObject_Impl() ) 420 { 421 } 422 423 //----------------------------------------------------------------------------- 424 425 SfxDocumentInfoObject::~SfxDocumentInfoObject() 426 { 427 delete _pImp; 428 } 429 430 //----------------------------------------------------------------------------- 431 432 // ::com::sun::star::lang::XInitialization: 433 void SAL_CALL 434 SfxDocumentInfoObject::initialize(const uno::Sequence< uno::Any > & aArguments) 435 throw (uno::RuntimeException, uno::Exception) 436 { 437 if (aArguments.getLength() >= 1) { 438 uno::Any any = aArguments[0]; 439 uno::Reference<document::XDocumentProperties> xDoc; 440 if (!(any >>= xDoc) || !xDoc.is()) throw lang::IllegalArgumentException( 441 ::rtl::OUString::createFromAscii( 442 "SfxDocumentInfoObject::initialize: no XDocumentProperties given"), 443 *this, 0); 444 _pImp->Reset(xDoc); 445 } else { 446 throw lang::IllegalArgumentException( 447 ::rtl::OUString::createFromAscii( 448 "SfxDocumentInfoObject::initialize: no argument given"), 449 *this, 0); 450 } 451 } 452 453 // ::com::sun::star::util::XCloneable: 454 uno::Reference<util::XCloneable> SAL_CALL 455 SfxDocumentInfoObject::createClone() throw (uno::RuntimeException) 456 { 457 SfxDocumentInfoObject *pNew = new SfxDocumentInfoObject; 458 uno::Reference< util::XCloneable > 459 xCloneable(_pImp->m_xDocProps, uno::UNO_QUERY_THROW); 460 uno::Reference<document::XDocumentProperties> xDocProps( 461 xCloneable->createClone(), uno::UNO_QUERY_THROW); 462 pNew->_pImp->Reset(xDocProps, _pImp->m_UserDefined); 463 return pNew; 464 } 465 466 // ::com::sun::star::document::XDocumentProperties: 467 uno::Reference< document::XDocumentProperties > SAL_CALL 468 SfxDocumentInfoObject::getDocumentProperties() 469 throw(::com::sun::star::uno::RuntimeException) 470 { 471 return _pImp->m_xDocProps; 472 } 473 474 //----------------------------------------------------------------------------- 475 476 const SfxDocumentInfoObject& SfxDocumentInfoObject::operator=( const SfxDocumentInfoObject & rOther) 477 { 478 uno::Reference< util::XCloneable > 479 xCloneable(rOther._pImp->m_xDocProps, uno::UNO_QUERY_THROW); 480 uno::Reference<document::XDocumentProperties> xDocProps( 481 xCloneable->createClone(), uno::UNO_QUERY_THROW); 482 _pImp->Reset(xDocProps, rOther._pImp->m_UserDefined); 483 return *this; 484 } 485 486 //----------------------------------------------------------------------------- 487 488 void SAL_CALL SfxDocumentInfoObject::dispose() throw( ::com::sun::star::uno::RuntimeException ) 489 { 490 ::com::sun::star::lang::EventObject aEvent( (::cppu::OWeakObject *)this ); 491 _pImp->_aDisposeContainer.disposeAndClear( aEvent ); 492 ::osl::MutexGuard aGuard( _pImp->_aMutex ); 493 _pImp->m_xDocProps = 0; 494 // NB: do not call m_xDocProps->dispose(), there could be other refs 495 _pImp->bDisposed = sal_True; 496 } 497 498 //----------------------------------------------------------------------------- 499 500 void SAL_CALL SfxDocumentInfoObject::addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException ) 501 { 502 _pImp->_aDisposeContainer.addInterface( aListener ); 503 } 504 505 //----------------------------------------------------------------------------- 506 507 void SAL_CALL SfxDocumentInfoObject::removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException ) 508 { 509 _pImp->_aDisposeContainer.removeInterface( aListener ); 510 } 511 //----------------------------------------------------------------------------- 512 513 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SfxDocumentInfoObject::getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException ) 514 { 515 ::osl::MutexGuard aGuard( _pImp->_aMutex ); 516 517 uno::Reference<beans::XPropertySet> xPropSet( 518 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 519 MixedPropertySetInfo* pInfo = new MixedPropertySetInfo( lcl_GetDocInfoPropertyMap(), _pImp->m_UserDefined, xPropSet); 520 uno::Reference< beans::XPropertySetInfo > xInfo( 521 static_cast< beans::XPropertySetInfo* >(pInfo), uno::UNO_QUERY_THROW); 522 return xInfo; 523 } 524 525 //----------------------------------------------------------------------------- 526 527 void SAL_CALL SfxDocumentInfoObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aValue) throw ( 528 uno::RuntimeException, beans::UnknownPropertyException, 529 beans::PropertyVetoException, lang::IllegalArgumentException, 530 lang::WrappedTargetException) 531 { 532 const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName ); 533 // fix prop! 534 if ( pEntry ) 535 setFastPropertyValue( pEntry->nWID, aValue ); 536 else 537 // dynamic prop! 538 { 539 uno::Reference<beans::XPropertySet> xPropSet( 540 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 541 return xPropSet->setPropertyValue(aPropertyName, aValue); 542 } 543 } 544 545 //----------------------------------------------------------------------------- 546 547 uno::Any SAL_CALL SfxDocumentInfoObject::getPropertyValue(const ::rtl::OUString& aPropertyName) throw( 548 uno::RuntimeException, beans::UnknownPropertyException, 549 lang::WrappedTargetException) 550 { 551 const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName ); 552 // fix prop! 553 if ( pEntry ) 554 return getFastPropertyValue( pEntry->nWID ); 555 else 556 // dynamic prop! 557 { 558 uno::Reference<beans::XPropertySet> xPropSet( 559 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 560 return xPropSet->getPropertyValue(aPropertyName); 561 } 562 } 563 564 sal_Bool SAL_CALL SfxDocumentInfoObject::isModified() throw(::com::sun::star::uno::RuntimeException) 565 { 566 uno::Reference<util::XModifiable> xModif( 567 _pImp->m_xDocProps, uno::UNO_QUERY_THROW); 568 return xModif->isModified(); 569 } 570 571 void SAL_CALL SfxDocumentInfoObject::setModified( sal_Bool bModified ) 572 throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException) 573 { 574 uno::Reference<util::XModifiable> xModif( 575 _pImp->m_xDocProps, uno::UNO_QUERY_THROW); 576 return xModif->setModified(bModified); 577 } 578 579 void SAL_CALL SfxDocumentInfoObject::addModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException ) 580 { 581 uno::Reference<util::XModifiable> xModif( 582 _pImp->m_xDocProps, uno::UNO_QUERY_THROW); 583 return xModif->addModifyListener(xListener); 584 } 585 586 void SAL_CALL SfxDocumentInfoObject::removeModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException ) 587 { 588 uno::Reference<util::XModifiable> xModif( 589 _pImp->m_xDocProps, uno::UNO_QUERY_THROW); 590 return xModif->removeModifyListener(xListener); 591 } 592 593 //----------------------------------------------------------------------------- 594 595 void SAL_CALL SfxDocumentInfoObject::addPropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw( 596 uno::RuntimeException, beans::UnknownPropertyException, 597 lang::WrappedTargetException) 598 {} 599 600 //----------------------------------------------------------------------------- 601 602 void SAL_CALL SfxDocumentInfoObject::removePropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw( 603 uno::RuntimeException, beans::UnknownPropertyException, 604 lang::WrappedTargetException) 605 {} 606 607 //----------------------------------------------------------------------------- 608 609 void SAL_CALL SfxDocumentInfoObject::addVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw( 610 uno::RuntimeException, beans::UnknownPropertyException, 611 lang::WrappedTargetException) 612 {} 613 614 //----------------------------------------------------------------------------- 615 616 void SAL_CALL SfxDocumentInfoObject::removeVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw( 617 uno::RuntimeException, beans::UnknownPropertyException, 618 lang::WrappedTargetException) 619 {} 620 621 uno::Sequence< beans::PropertyValue > SAL_CALL SfxDocumentInfoObject::getPropertyValues( void ) throw( uno::RuntimeException ) 622 { 623 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = getPropertySetInfo(); 624 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps = xInfo->getProperties(); 625 626 const ::com::sun::star::beans::Property* pProps = aProps.getConstArray(); 627 sal_uInt32 nCount = aProps.getLength(); 628 629 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >aSeq( nCount ); 630 ::com::sun::star::beans::PropertyValue* pValues = aSeq.getArray(); 631 632 for ( sal_uInt32 n = 0; n < nCount; ++n ) 633 { 634 ::com::sun::star::beans::PropertyValue& rCurrValue = pValues[n]; 635 const ::com::sun::star::beans::Property& rCurrProp = pProps[n]; 636 637 rCurrValue.Name = rCurrProp.Name; 638 rCurrValue.Handle = rCurrProp.Handle; 639 rCurrValue.Value = getPropertyValue( rCurrProp.Name ); 640 } 641 642 return aSeq; 643 } 644 645 void SAL_CALL SfxDocumentInfoObject::setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) 646 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 ) 647 { 648 const ::com::sun::star::beans::PropertyValue* pProps = aProps.getConstArray(); 649 sal_uInt32 nCount = aProps.getLength(); 650 651 for ( sal_uInt32 n = 0; n < nCount; ++n ) 652 { 653 const ::com::sun::star::beans::PropertyValue& rProp = pProps[n]; 654 setPropertyValue( rProp.Name, rProp.Value ); 655 } 656 } 657 658 void SAL_CALL SfxDocumentInfoObject::addProperty(const ::rtl::OUString& sName , 659 sal_Int16 nAttributes , 660 const ::com::sun::star::uno::Any& aDefaultValue) 661 throw(::com::sun::star::beans::PropertyExistException , 662 ::com::sun::star::beans::IllegalTypeException , 663 ::com::sun::star::lang::IllegalArgumentException, 664 ::com::sun::star::uno::RuntimeException ) 665 { 666 // clash with "fix" properties ? 667 sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0; 668 if ( bFixProp ) 669 { 670 ::rtl::OUStringBuffer sMsg(256); 671 sMsg.appendAscii("The property \"" ); 672 sMsg.append (sName ); 673 sMsg.appendAscii("\" " ); 674 if ( bFixProp ) 675 sMsg.appendAscii(" already exists as a fix property. Please have a look into the IDL documentation of the DocumentInfo service."); 676 677 throw ::com::sun::star::beans::PropertyExistException( 678 sMsg.makeStringAndClear(), 679 static_cast< ::cppu::OWeakObject* >(this)); 680 } 681 682 uno::Reference<beans::XPropertyContainer> xPropSet( 683 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 684 return xPropSet->addProperty(sName, nAttributes, aDefaultValue); 685 } 686 687 void SAL_CALL SfxDocumentInfoObject::removeProperty(const ::rtl::OUString& sName) 688 throw(::com::sun::star::beans::UnknownPropertyException, 689 ::com::sun::star::beans::NotRemoveableException , 690 ::com::sun::star::uno::RuntimeException ) 691 { 692 // clash with "fix" properties ? 693 sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0; 694 if ( bFixProp ) 695 { 696 ::rtl::OUStringBuffer sMsg(256); 697 sMsg.appendAscii("The property \"" ); 698 sMsg.append (sName ); 699 sMsg.appendAscii("\" cant be removed. Its a fix property of the DocumentInfo service."); 700 701 throw ::com::sun::star::beans::NotRemoveableException( 702 sMsg.makeStringAndClear(), 703 static_cast< ::cppu::OWeakObject* >(this)); 704 } 705 706 uno::Reference<beans::XPropertyContainer> xPropSet( 707 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 708 return xPropSet->removeProperty(sName); 709 } 710 711 sal_Bool equalsDateTime( const util::DateTime& D1, const util::DateTime& D2 ) 712 { 713 return D1.HundredthSeconds == D2.HundredthSeconds && 714 D1.Seconds == D2.Seconds && 715 D1.Minutes == D2.Minutes && 716 D1.Hours == D2.Hours && 717 D1.Day == D2.Day && 718 D1.Month == D2.Month && 719 D1.Year == D2.Year; 720 } 721 722 void SAL_CALL SfxDocumentInfoObject::setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw( 723 uno::RuntimeException, beans::UnknownPropertyException, 724 beans::PropertyVetoException, lang::IllegalArgumentException, 725 lang::WrappedTargetException) 726 { 727 // Attention: Only fix properties should be provided by this method. 728 // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-) 729 730 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); 731 732 if ( aValue.getValueType() == ::getCppuType((const ::rtl::OUString*)0) ) 733 { 734 ::rtl::OUString sTemp ; 735 aValue >>= sTemp ; 736 switch ( nHandle ) 737 { 738 case SID_APPLICATION : 739 _pImp->m_xDocProps->setGenerator(sTemp); 740 break; 741 case WID_FROM : 742 { 743 // QUESTION: do we still need this? 744 /* 745 // String aStrVal( sTemp ); 746 if ( aStrVal.Len() > TIMESTAMP_MAXLENGTH ) 747 { 748 SvAddressParser aParser( aStrVal ); 749 if ( aParser.Count() > 0 ) 750 { 751 String aEmail = aParser.GetEmailAddress(0); 752 String aRealname = aParser.GetRealName(0); 753 754 if ( aRealname.Len() <= TIMESTAMP_MAXLENGTH ) 755 aStrVal = aRealname; 756 else if ( aEmail.Len() <= TIMESTAMP_MAXLENGTH ) 757 aStrVal = aEmail; 758 } 759 } */ 760 761 if ( _pImp->m_xDocProps->getAuthor() != sTemp ) 762 _pImp->m_xDocProps->setAuthor(sTemp); 763 break; 764 } 765 case MID_DOCINFO_PRINTEDBY: 766 if ( _pImp->m_xDocProps->getPrintedBy() != sTemp ) 767 _pImp->m_xDocProps->setPrintedBy(sTemp); 768 break; 769 case MID_DOCINFO_MODIFICATIONAUTHOR: 770 if ( _pImp->m_xDocProps->getModifiedBy() != sTemp ) 771 _pImp->m_xDocProps->setModifiedBy(sTemp); 772 break; 773 case WID_TITLE : 774 { 775 if ( _pImp->m_xDocProps->getTitle() != sTemp ) 776 _pImp->m_xDocProps->setTitle(sTemp); 777 break; 778 } 779 case MID_DOCINFO_SUBJECT : 780 if ( _pImp->m_xDocProps->getSubject() != sTemp ) 781 _pImp->m_xDocProps->setSubject(sTemp); 782 break; 783 case WID_KEYWORDS : 784 { 785 _pImp->m_xDocProps->setKeywords( 786 ::comphelper::string::convertCommaSeparated(sTemp)); 787 } 788 break; 789 case MID_DOCINFO_TEMPLATE: 790 if ( _pImp->m_xDocProps->getTemplateName() != sTemp ) 791 _pImp->m_xDocProps->setTemplateName(sTemp); 792 break; 793 case SID_TEMPLATE_NAME: 794 if ( _pImp->m_xDocProps->getTemplateURL() != sTemp ) 795 _pImp->m_xDocProps->setTemplateURL(sTemp); 796 break; 797 case MID_DOCINFO_DESCRIPTION: 798 if ( _pImp->m_xDocProps->getDescription() != sTemp ) 799 _pImp->m_xDocProps->setDescription(sTemp); 800 break; 801 case MID_DOCINFO_AUTOLOADURL: 802 if ( _pImp->m_xDocProps->getAutoloadURL() != sTemp ) 803 _pImp->m_xDocProps->setAutoloadURL(sTemp); 804 break; 805 case MID_DOCINFO_DEFAULTTARGET: 806 if ( _pImp->m_xDocProps->getDefaultTarget() != sTemp ) 807 _pImp->m_xDocProps->setDefaultTarget(sTemp); 808 break; 809 // case WID_CONTENT_TYPE : // this is readonly! 810 default: 811 break; 812 } 813 } 814 else if ( aValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0) ) 815 { 816 com::sun::star::util::DateTime aTemp; 817 aValue >>= aTemp ; 818 switch ( nHandle ) 819 { 820 case WID_DATE_CREATED : 821 { 822 if ( !equalsDateTime(_pImp->m_xDocProps->getCreationDate(), aTemp ) ) 823 { 824 _pImp->m_xDocProps->setCreationDate(aTemp); 825 } 826 break; 827 } 828 case WID_DATE_MODIFIED : 829 { 830 if ( !equalsDateTime(_pImp->m_xDocProps->getModificationDate(), aTemp ) ) 831 { 832 _pImp->m_xDocProps->setModificationDate(aTemp); 833 } 834 break; 835 } 836 case MID_DOCINFO_PRINTDATE : 837 { 838 if ( !equalsDateTime(_pImp->m_xDocProps->getPrintDate(), aTemp ) ) 839 { 840 _pImp->m_xDocProps->setPrintDate(aTemp); 841 } 842 break; 843 } 844 case MID_DOCINFO_TEMPLATEDATE : 845 { 846 if ( !equalsDateTime(_pImp->m_xDocProps->getTemplateDate(), aTemp ) ) 847 { 848 _pImp->m_xDocProps->setTemplateDate(aTemp); 849 } 850 break; 851 } 852 default: 853 break; 854 } 855 } 856 857 else if ( aValue.getValueType() == ::getBooleanCppuType() ) 858 { 859 sal_Bool bBoolVal = false; 860 aValue >>= bBoolVal ; 861 switch ( nHandle ) 862 { 863 case MID_DOCINFO_AUTOLOADENABLED: 864 // NB: this property does not exist any more 865 // it is emulated as enabled iff delay > 0 866 if ( bBoolVal && (0 == _pImp->m_xDocProps->getAutoloadSecs()) ) { 867 _pImp->m_xDocProps->setAutoloadSecs(60); // default 868 } else if ( !bBoolVal && (0 != _pImp->m_xDocProps->getAutoloadSecs()) ) { 869 _pImp->m_xDocProps->setAutoloadSecs(0); 870 _pImp->m_xDocProps->setAutoloadURL(::rtl::OUString::createFromAscii("")); 871 } 872 break; 873 default: 874 break; 875 } 876 } 877 else if ( aValue.getValueType() == ::getCppuType((const sal_Int32*)0) ) 878 { 879 sal_Int32 nIntVal = 0; 880 aValue >>= nIntVal ; 881 switch ( nHandle ) 882 { 883 case MID_DOCINFO_AUTOLOADSECS: 884 if ( nIntVal != _pImp->m_xDocProps->getAutoloadSecs()) 885 _pImp->m_xDocProps->setAutoloadSecs(nIntVal); 886 break; 887 case MID_DOCINFO_EDITTIME: 888 if ( nIntVal != _pImp->m_xDocProps->getEditingDuration()) 889 _pImp->m_xDocProps->setEditingDuration(nIntVal); 890 break; 891 default: 892 break; 893 } 894 } 895 else if ( aValue.getValueType() == ::getCppuType((const sal_Int16*)0) ) 896 { 897 short nIntVal = 0; 898 aValue >>= nIntVal ; 899 switch ( nHandle ) 900 { 901 case MID_DOCINFO_REVISION: 902 if ( nIntVal != _pImp->m_xDocProps->getEditingCycles()) 903 _pImp->m_xDocProps->setEditingCycles(nIntVal); 904 break; 905 default: 906 break; 907 } 908 } 909 else if ( aValue.getValueType() == ::getCppuType((const uno::Sequence< beans::NamedValue >*)0) ) 910 { 911 if ( nHandle == MID_DOCINFO_STATISTIC ) 912 { 913 uno::Sequence < beans::NamedValue > aData; 914 aValue >>= aData; 915 { 916 _pImp->m_xDocProps->setDocumentStatistics(aData); 917 } 918 } 919 } 920 else if ( aValue.getValueType() == ::getCppuType((const lang::Locale*)0) ) 921 { 922 if ( nHandle == MID_DOCINFO_CHARLOCALE ) 923 { 924 lang::Locale aLocale; 925 aValue >>= aLocale; 926 lang::Locale oldLocale = _pImp->m_xDocProps->getLanguage(); 927 if ( aLocale.Language != oldLocale.Language || 928 aLocale.Country != oldLocale.Country || 929 aLocale.Variant != oldLocale.Variant ) 930 { 931 _pImp->m_xDocProps->setLanguage(aLocale); 932 } 933 } 934 } 935 } 936 937 //----------------------------------------------------------------------------- 938 939 ::com::sun::star::uno::Any SAL_CALL SfxDocumentInfoObject::getFastPropertyValue(sal_Int32 nHandle) throw( 940 uno::RuntimeException, beans::UnknownPropertyException, 941 lang::WrappedTargetException) 942 { 943 // Attention: Only fix properties should be provided by this method. 944 // Dynamic properties has no handle in real ... because it cant be used inside multithreaded environments :-) 945 946 ::osl::MutexGuard aGuard( _pImp->_aMutex ); 947 ::com::sun::star::uno::Any aValue; 948 switch ( nHandle ) 949 { 950 case SID_APPLICATION : 951 aValue <<= _pImp->m_xDocProps->getGenerator(); 952 break; 953 case WID_CONTENT_TYPE : 954 // FIXME this is not available anymore 955 aValue <<= ::rtl::OUString(); 956 break; 957 case MID_DOCINFO_REVISION : 958 aValue <<= _pImp->m_xDocProps->getEditingCycles(); 959 break; 960 case MID_DOCINFO_EDITTIME : 961 aValue <<= _pImp->m_xDocProps->getEditingDuration(); 962 break; 963 case WID_FROM : 964 aValue <<= _pImp->m_xDocProps->getAuthor(); 965 break; 966 case WID_DATE_CREATED : 967 if ( IsValidDateTime( _pImp->m_xDocProps->getCreationDate() ) ) 968 aValue <<= _pImp->m_xDocProps->getCreationDate(); 969 break; 970 case WID_TITLE : 971 aValue <<= _pImp->m_xDocProps->getTitle(); 972 break; 973 case MID_DOCINFO_SUBJECT: 974 aValue <<= _pImp->m_xDocProps->getSubject(); 975 break; 976 case MID_DOCINFO_MODIFICATIONAUTHOR: 977 aValue <<= _pImp->m_xDocProps->getModifiedBy(); 978 break; 979 case WID_DATE_MODIFIED : 980 if ( IsValidDateTime( _pImp->m_xDocProps->getModificationDate() ) ) 981 aValue <<= _pImp->m_xDocProps->getModificationDate(); 982 break; 983 case MID_DOCINFO_PRINTEDBY: 984 aValue <<= _pImp->m_xDocProps->getPrintedBy(); 985 break; 986 case MID_DOCINFO_PRINTDATE: 987 if ( IsValidDateTime( _pImp->m_xDocProps->getPrintDate() ) ) 988 aValue <<= _pImp->m_xDocProps->getPrintDate(); 989 break; 990 case WID_KEYWORDS : 991 aValue <<= ::comphelper::string::convertCommaSeparated( 992 _pImp->m_xDocProps->getKeywords()); 993 break; 994 case MID_DOCINFO_DESCRIPTION: 995 aValue <<= _pImp->m_xDocProps->getDescription(); 996 break; 997 case MID_DOCINFO_TEMPLATE: 998 aValue <<= _pImp->m_xDocProps->getTemplateName(); 999 break; 1000 case SID_TEMPLATE_NAME: 1001 aValue <<= _pImp->m_xDocProps->getTemplateURL(); 1002 break; 1003 case MID_DOCINFO_TEMPLATEDATE: 1004 if ( IsValidDateTime( _pImp->m_xDocProps->getTemplateDate() ) ) 1005 aValue <<= _pImp->m_xDocProps->getTemplateDate(); 1006 break; 1007 case MID_DOCINFO_AUTOLOADENABLED: 1008 aValue <<= static_cast<sal_Bool> 1009 ( (_pImp->m_xDocProps->getAutoloadSecs() != 0) 1010 || !(_pImp->m_xDocProps->getAutoloadURL().equalsAscii(""))); 1011 break; 1012 case MID_DOCINFO_AUTOLOADURL: 1013 aValue <<= _pImp->m_xDocProps->getAutoloadURL(); 1014 break; 1015 case MID_DOCINFO_AUTOLOADSECS: 1016 aValue <<= _pImp->m_xDocProps->getAutoloadSecs(); 1017 break; 1018 case MID_DOCINFO_DEFAULTTARGET: 1019 aValue <<= _pImp->m_xDocProps->getDefaultTarget(); 1020 break; 1021 case MID_DOCINFO_STATISTIC: 1022 aValue <<= _pImp->m_xDocProps->getDocumentStatistics(); 1023 break; 1024 case MID_DOCINFO_CHARLOCALE: 1025 aValue <<= _pImp->m_xDocProps->getLanguage(); 1026 break; 1027 default: 1028 aValue <<= ::rtl::OUString(); 1029 break; 1030 } 1031 1032 return aValue; 1033 } 1034 1035 //----------------------------------------------------------------------------- 1036 1037 sal_Int16 SAL_CALL SfxDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException ) 1038 { 1039 // uno::Reference<beans::XPropertyAccess> xPropSet( 1040 // _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 1041 // return xPropSet->getPropertyValues().getLength(); 1042 return FOUR; 1043 } 1044 1045 //----------------------------------------------------------------------------- 1046 1047 ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) 1048 { 1049 ::osl::MutexGuard aGuard( _pImp->_aMutex ); 1050 if (nIndex < FOUR) 1051 return _pImp->m_UserDefined[nIndex]; 1052 else 1053 return ::rtl::OUString(); 1054 } 1055 1056 //----------------------------------------------------------------------------- 1057 1058 ::rtl::OUString SAL_CALL SfxDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) 1059 { 1060 ::osl::MutexGuard aGuard( _pImp->_aMutex ); 1061 if (nIndex < FOUR) { 1062 ::rtl::OUString name = _pImp->m_UserDefined[nIndex]; 1063 uno::Reference<beans::XPropertySet> xPropSet( 1064 _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); 1065 ::rtl::OUString val; 1066 try { 1067 xPropSet->getPropertyValue(name) >>= val; 1068 return val; 1069 } catch (uno::RuntimeException &) { 1070 throw; 1071 } catch (uno::Exception &) { 1072 return ::rtl::OUString(); // ignore 1073 } 1074 } else 1075 return ::rtl::OUString(); 1076 } 1077 1078 //----------------------------------------------------------------------------- 1079 1080 void SAL_CALL SfxDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException ) 1081 { 1082 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); 1083 if (nIndex < FOUR) // yes, four! 1084 { 1085 // FIXME this is full of race conditions because the PropertyBag 1086 // can be accessed from clients of the DocumentProperties! 1087 ::rtl::OUString name = _pImp->m_UserDefined[nIndex]; 1088 if (name != aName) { 1089 uno::Reference<beans::XPropertySet> xPropSet( 1090 _pImp->m_xDocProps->getUserDefinedProperties(), 1091 uno::UNO_QUERY_THROW); 1092 uno::Reference<beans::XPropertyContainer> xPropContainer( 1093 _pImp->m_xDocProps->getUserDefinedProperties(), 1094 uno::UNO_QUERY_THROW); 1095 uno::Any value; 1096 try { 1097 value = xPropSet->getPropertyValue(name); 1098 xPropContainer->removeProperty(name); 1099 xPropContainer->addProperty(aName, 1100 beans::PropertyAttribute::REMOVEABLE, value); 1101 _pImp->m_UserDefined[nIndex] = aName; 1102 } catch (beans::UnknownPropertyException) { 1103 try { 1104 xPropContainer->addProperty(aName, 1105 beans::PropertyAttribute::REMOVEABLE, 1106 uno::makeAny(::rtl::OUString::createFromAscii(""))); 1107 _pImp->m_UserDefined[nIndex] = aName; 1108 } catch (beans::PropertyExistException) { 1109 _pImp->m_UserDefined[nIndex] = aName; 1110 // ignore 1111 } 1112 } catch (beans::PropertyExistException) { 1113 try { 1114 xPropContainer->addProperty(name, 1115 beans::PropertyAttribute::REMOVEABLE, value); 1116 } catch (beans::PropertyExistException) { 1117 // bugger... 1118 } 1119 } catch (uno::RuntimeException &) { 1120 throw; 1121 } catch (uno::Exception &) { 1122 // ignore everything else; xPropSet _may_ be corrupted 1123 } 1124 } 1125 } 1126 } 1127 1128 //----------------------------------------------------------------------------- 1129 1130 void SAL_CALL SfxDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException ) 1131 { 1132 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); 1133 if (nIndex < FOUR) // yes, four! 1134 { 1135 ::rtl::OUString name = _pImp->m_UserDefined[nIndex]; 1136 uno::Reference<beans::XPropertySet> xPropSet( 1137 _pImp->m_xDocProps->getUserDefinedProperties(), 1138 uno::UNO_QUERY_THROW); 1139 uno::Reference<beans::XPropertyContainer> xPropContainer( 1140 _pImp->m_xDocProps->getUserDefinedProperties(), 1141 uno::UNO_QUERY_THROW); 1142 uno::Any aAny; 1143 aAny <<= aValue; 1144 try { 1145 uno::Any value = xPropSet->getPropertyValue(name); 1146 if (value != aAny) { 1147 xPropSet->setPropertyValue(name, aAny); 1148 } 1149 } catch (beans::UnknownPropertyException) { 1150 try { 1151 // someone removed it, add it back again 1152 xPropContainer->addProperty(name, 1153 beans::PropertyAttribute::REMOVEABLE, aAny); 1154 } catch (uno::RuntimeException &) { 1155 throw; 1156 } catch (uno::Exception &) { 1157 // ignore everything else 1158 } 1159 } catch (uno::RuntimeException &) { 1160 throw; 1161 } catch (uno::Exception &) { 1162 // ignore everything else 1163 } 1164 } 1165 } 1166 1167 //----------------------------------------------------------------------------- 1168 SFX_IMPL_XINTERFACE_2( SfxStandaloneDocumentInfoObject, SfxDocumentInfoObject, ::com::sun::star::lang::XServiceInfo, ::com::sun::star::document::XStandaloneDocumentInfo ) 1169 SFX_IMPL_XTYPEPROVIDER_10( SfxStandaloneDocumentInfoObject, ::com::sun::star::document::XDocumentInfo, ::com::sun::star::lang::XComponent, 1170 ::com::sun::star::beans::XPropertySet, ::com::sun::star::beans::XFastPropertySet, ::com::sun::star::beans::XPropertyAccess, 1171 ::com::sun::star::beans::XPropertyContainer, ::com::sun::star::util::XModifiable, ::com::sun::star::util::XModifyBroadcaster, 1172 ::com::sun::star::document::XStandaloneDocumentInfo, ::com::sun::star::lang::XServiceInfo ) 1173 1174 SFX_IMPL_XSERVICEINFO( SfxStandaloneDocumentInfoObject, "com.sun.star.document.StandaloneDocumentInfo", "com.sun.star.comp.sfx2.StandaloneDocumentInfo" ) 1175 SFX_IMPL_SINGLEFACTORY( SfxStandaloneDocumentInfoObject ) 1176 1177 SfxStandaloneDocumentInfoObject::SfxStandaloneDocumentInfoObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ) 1178 : SfxDocumentInfoObject() 1179 , _xFactory( xFactory ) 1180 { 1181 uno::Reference< lang::XInitialization > xDocProps( 1182 _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1183 "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW); 1184 // xDocProps->initialize(uno::Sequence<uno::Any>()); 1185 uno::Any a; 1186 a <<= xDocProps; 1187 uno::Sequence<uno::Any> args(1); 1188 args[0] = a; 1189 initialize(args); 1190 } 1191 1192 //----------------------------------------------------------------------------- 1193 1194 SfxStandaloneDocumentInfoObject::~SfxStandaloneDocumentInfoObject() 1195 { 1196 } 1197 1198 //----------------------------------------------------------------------------- 1199 1200 uno::Reference< embed::XStorage > GetStorage_Impl( const ::rtl::OUString& rName, sal_Bool bWrite, uno::Reference < lang::XMultiServiceFactory >& xFactory ) 1201 { 1202 // catch unexpected exceptions under solaris 1203 // Client code checks the returned reference but is not interested on error details. 1204 try 1205 { 1206 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1207 return ::comphelper::OStorageHelper::GetStorageFromURL( 1208 rName, 1209 bWrite ? embed::ElementModes::READWRITE : embed::ElementModes::READ, 1210 xFactory ); 1211 } 1212 catch(const uno::Exception&) 1213 {} 1214 1215 return uno::Reference< embed::XStorage >(); 1216 } 1217 1218 //----------------------------------------------------------------------------- 1219 1220 sal_Int16 SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException ) 1221 { 1222 return SfxDocumentInfoObject::getUserFieldCount(); 1223 } 1224 1225 //----------------------------------------------------------------------------- 1226 1227 ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) 1228 { 1229 return SfxDocumentInfoObject::getUserFieldName(nIndex); 1230 } 1231 1232 //----------------------------------------------------------------------------- 1233 1234 ::rtl::OUString SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException ) 1235 { 1236 return SfxDocumentInfoObject::getUserFieldValue(nIndex); 1237 } 1238 1239 //----------------------------------------------------------------------------- 1240 1241 void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException ) 1242 { 1243 SfxDocumentInfoObject::setUserFieldName( nIndex, aName ); 1244 } 1245 1246 //----------------------------------------------------------------------------- 1247 1248 void SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException ) 1249 { 1250 SfxDocumentInfoObject::setUserFieldValue( nIndex, aValue ); 1251 } 1252 1253 //----------------------------------------------------------------------------- 1254 1255 void SAL_CALL SfxStandaloneDocumentInfoObject::loadFromURL(const ::rtl::OUString& aURL) 1256 throw( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException ) 1257 { 1258 sal_Bool bOK = sal_False; 1259 1260 ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex ); 1261 uno::Reference< document::XDocumentProperties > xDocProps( 1262 _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1263 "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW); 1264 // uno::Reference< lang::XInitialization > xInit(xDocProps, uno::UNO_QUERY_THROW); 1265 // xInit->initialize(uno::Sequence<uno::Any>()); 1266 _pImp->Reset(xDocProps); 1267 aGuard.clear(); 1268 1269 uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_False, _xFactory ); 1270 if ( xStorage.is() ) 1271 { 1272 try 1273 { 1274 uno::Sequence<beans::PropertyValue> medium(2); 1275 medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL"); 1276 medium[0].Value <<= aURL; 1277 medium[1].Name = ::rtl::OUString::createFromAscii("URL"); 1278 medium[1].Value <<= aURL; 1279 _pImp->m_xDocProps->loadFromStorage(xStorage, medium); 1280 _pImp->Reset(_pImp->m_xDocProps); 1281 bOK = sal_True; 1282 } 1283 catch( uno::Exception& ) 1284 { 1285 } 1286 } 1287 else 1288 { 1289 uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance( 1290 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY ); 1291 if ( xBinary.is() ) 1292 { 1293 xBinary->loadFromURL( aURL ); 1294 bOK = sal_True; 1295 uno::Reference < document::XStandaloneDocumentInfo > xTarget( static_cast < document::XStandaloneDocumentInfo*> (this), uno::UNO_QUERY ); 1296 Copy( xBinary, xTarget ); 1297 } 1298 } 1299 1300 if ( !bOK ) 1301 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTREAD ); 1302 } 1303 1304 //----------------------------------------------------------------------------- 1305 1306 void SAL_CALL SfxStandaloneDocumentInfoObject::storeIntoURL(const ::rtl::OUString& aURL) throw( ::com::sun::star::io::IOException ) 1307 { 1308 sal_Bool bOK = sal_False; 1309 uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_True, _xFactory ); 1310 if ( xStorage.is() ) 1311 { 1312 try 1313 { 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 1320 _pImp->m_xDocProps->storeToStorage(xStorage, medium); 1321 bOK = sal_True; 1322 } 1323 catch( io::IOException & ) 1324 { 1325 throw; 1326 } 1327 catch( uno::RuntimeException& ) 1328 { 1329 throw; 1330 } 1331 catch( uno::Exception& ) 1332 { 1333 } 1334 } 1335 else 1336 { 1337 uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance( 1338 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY ); 1339 if ( xBinary.is() ) 1340 { 1341 Copy( this, xBinary ); 1342 xBinary->storeIntoURL( aURL ); 1343 bOK = sal_True; 1344 } 1345 } 1346 1347 if ( !bOK ) 1348 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTWRITE ); 1349 } 1350 1351