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