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 #ifndef _MSGBOX_HXX //autogen 28 #include <vcl/msgbox.hxx> 29 #endif 30 #include <svl/eitem.hxx> 31 #include <svl/stritem.hxx> 32 #include <svl/intitem.hxx> 33 #include <tools/zcodec.hxx> 34 #include <com/sun/star/frame/XStorable.hpp> 35 #include <com/sun/star/frame/XModel.hpp> 36 #include <com/sun/star/frame/XFrame.hpp> 37 #include <com/sun/star/document/XFilter.hpp> 38 #include <com/sun/star/document/XImporter.hpp> 39 #include <com/sun/star/document/XExporter.hpp> 40 #include <com/sun/star/document/FilterOptionsRequest.hpp> 41 #include <com/sun/star/document/XInteractionFilterOptions.hpp> 42 #include <com/sun/star/task/XInteractionHandler.hpp> 43 #include <com/sun/star/task/XInteractionAskLater.hpp> 44 #include <com/sun/star/task/FutureDocumentVersionProductUpdateRequest.hpp> 45 #include <com/sun/star/task/InteractionClassification.hpp> 46 #include <com/sun/star/lang/XInitialization.hpp> 47 #include <com/sun/star/document/MacroExecMode.hpp> 48 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> 49 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> 50 #include <com/sun/star/ui/dialogs/XFilePicker.hpp> 51 #include <com/sun/star/beans/XPropertySetInfo.hpp> 52 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 53 #include <com/sun/star/beans/XPropertyAccess.hpp> 54 #include <com/sun/star/beans/PropertyValue.hpp> 55 #include <com/sun/star/beans/XPropertySet.hpp> 56 #include <com/sun/star/container/XNameAccess.hpp> 57 #include <com/sun/star/container/XSet.hpp> 58 #include <com/sun/star/embed/ElementModes.hpp> 59 #include <com/sun/star/embed/EmbedStates.hpp> 60 #include <com/sun/star/embed/Aspects.hpp> 61 #include <com/sun/star/embed/XTransactedObject.hpp> 62 #include <com/sun/star/embed/XEmbedPersist.hpp> 63 #include <com/sun/star/embed/XLinkageSupport.hpp> 64 #include <com/sun/star/embed/EntryInitModes.hpp> 65 #include <com/sun/star/embed/XOptimizedStorage.hpp> 66 #include <com/sun/star/embed/XEncryptionProtectedStorage.hpp> 67 #include <com/sun/star/io/XTruncate.hpp> 68 #include <com/sun/star/util/XModifiable.hpp> 69 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp> 70 #include <com/sun/star/xml/crypto/CipherID.hpp> 71 #include <com/sun/star/xml/crypto/DigestID.hpp> 72 73 #include <com/sun/star/document/XDocumentProperties.hpp> 74 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> 75 #include <comphelper/processfactory.hxx> 76 #include <comphelper/configurationhelper.hxx> 77 #include <comphelper/interaction.hxx> 78 #include <svtools/sfxecode.hxx> 79 #include <unotools/securityoptions.hxx> 80 #include <cppuhelper/weak.hxx> 81 #include <comphelper/processfactory.hxx> 82 #include <tools/cachestr.hxx> 83 #include <unotools/streamwrap.hxx> 84 85 #include <unotools/saveopt.hxx> 86 #include <unotools/useroptions.hxx> 87 #include <unotools/pathoptions.hxx> 88 #include <tools/urlobj.hxx> 89 #include <tools/diagnose_ex.h> 90 #include <unotools/localfilehelper.hxx> 91 #include <unotools/ucbhelper.hxx> 92 #include <unotools/tempfile.hxx> 93 #include <unotools/docinfohelper.hxx> 94 #include <ucbhelper/content.hxx> 95 #include <sot/storinfo.hxx> 96 #include <sot/exchange.hxx> 97 #include <sot/formats.hxx> 98 #include <comphelper/storagehelper.hxx> 99 #include <comphelper/seqstream.hxx> 100 #include <comphelper/documentconstants.hxx> 101 #include <comphelper/string.hxx> 102 #include <vcl/bitmapex.hxx> 103 #include <svtools/embedhlp.hxx> 104 #include <rtl/logfile.hxx> 105 #include <basic/modsizeexceeded.hxx> 106 #include <osl/file.hxx> 107 108 #include <sfx2/signaturestate.hxx> 109 #include <sfx2/app.hxx> 110 #include <sfx2/objsh.hxx> 111 #include <sfx2/childwin.hxx> 112 #include <sfx2/request.hxx> 113 #include "sfx2/sfxresid.hxx" 114 #include <sfx2/docfile.hxx> 115 #include "fltfnc.hxx" 116 #include <sfx2/docfilt.hxx> 117 #include <sfx2/docfac.hxx> 118 #include "objshimp.hxx" 119 #include "sfxtypes.hxx" 120 #include "doc.hrc" 121 #include <sfx2/sfxsids.hrc> 122 #include <sfx2/module.hxx> 123 #include <sfx2/dispatch.hxx> 124 #include "openflag.hxx" 125 #include "helper.hxx" 126 #include <sfx2/filedlghelper.hxx> 127 #include <sfx2/event.hxx> 128 #include "fltoptint.hxx" 129 #include <sfx2/viewfrm.hxx> 130 #include "graphhelp.hxx" 131 #include "appbaslib.hxx" 132 #include "appdata.hxx" 133 134 #ifdef OS2 135 #include <osl/file.hxx> 136 #include <stdio.h> 137 #include <sys/ea.h> 138 #endif 139 140 #include "../appl/app.hrc" 141 142 extern sal_uInt32 CheckPasswd_Impl( SfxObjectShell*, SfxItemPool&, SfxMedium* ); 143 144 using namespace ::com::sun::star; 145 using namespace ::com::sun::star::container; 146 using namespace ::com::sun::star::lang; 147 using namespace ::com::sun::star::ui::dialogs; 148 using namespace ::com::sun::star::uno; 149 using namespace ::com::sun::star::beans; 150 using namespace ::com::sun::star::ucb; 151 using namespace ::com::sun::star::task; 152 using namespace ::com::sun::star::document; 153 using namespace ::rtl; 154 using namespace ::cppu; 155 156 namespace css = ::com::sun::star; 157 158 //========================================================================= 159 void impl_addToModelCollection(const css::uno::Reference< css::frame::XModel >& xModel) 160 { 161 if (!xModel.is()) 162 return; 163 164 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); 165 css::uno::Reference< css::container::XSet > xModelCollection( 166 xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.GlobalEventBroadcaster")), 167 css::uno::UNO_QUERY); 168 if (xModelCollection.is()) 169 { 170 try 171 { 172 xModelCollection->insert(css::uno::makeAny(xModel)); 173 } 174 catch ( uno::Exception& ) 175 { 176 OSL_ENSURE( sal_False, "The document seems to be in the collection already!\n" ); 177 } 178 } 179 } 180 181 //========================================================================= 182 183 sal_Bool SfxObjectShell::Save() 184 { 185 return SaveChildren(); 186 } 187 188 //-------------------------------------------------------------------------- 189 190 sal_Bool SfxObjectShell::SaveAs( SfxMedium& rMedium ) 191 { 192 return SaveAsChildren( rMedium ); 193 } 194 195 //------------------------------------------------------------------------- 196 197 sal_Bool SfxObjectShell::QuerySlotExecutable( sal_uInt16 /*nSlotId*/ ) 198 { 199 return sal_True; 200 } 201 202 //------------------------------------------------------------------------- 203 204 bool GetEncryptionData_Impl( const SfxItemSet* pSet, uno::Sequence< beans::NamedValue >& o_rEncryptionData ) 205 { 206 bool bResult = false; 207 if ( pSet ) 208 { 209 SFX_ITEMSET_ARG( pSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False); 210 if ( pEncryptionDataItem ) 211 { 212 pEncryptionDataItem->GetValue() >>= o_rEncryptionData; 213 bResult = true; 214 } 215 else 216 { 217 SFX_ITEMSET_ARG( pSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False); 218 if ( pPasswordItem ) 219 { 220 ::rtl::OUString aPassword = pPasswordItem->GetValue(); 221 o_rEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPassword ); 222 bResult = true; 223 } 224 } 225 } 226 227 return bResult; 228 } 229 230 //------------------------------------------------------------------------- 231 sal_Bool SfxObjectShell::PutURLContentsToVersionStream_Impl( 232 ::rtl::OUString aURL, 233 const uno::Reference< embed::XStorage >& xDocStorage, 234 ::rtl::OUString aStreamName ) 235 { 236 sal_Bool bResult = sal_False; 237 try 238 { 239 uno::Reference< embed::XStorage > xVersion = xDocStorage->openStorageElement( 240 ::rtl::OUString::createFromAscii( "Versions" ), 241 embed::ElementModes::READWRITE ); 242 243 DBG_ASSERT( xVersion.is(), 244 "The method must throw an exception if the storage can not be opened!\n" ); 245 if ( !xVersion.is() ) 246 throw uno::RuntimeException(); 247 248 uno::Reference< io::XStream > xVerStream = xVersion->openStreamElement( 249 aStreamName, 250 embed::ElementModes::READWRITE ); 251 DBG_ASSERT( xVerStream.is(), "The method must throw an exception if the storage can not be opened!\n" ); 252 if ( !xVerStream.is() ) 253 throw uno::RuntimeException(); 254 255 uno::Reference< io::XOutputStream > xOutStream = xVerStream->getOutputStream(); 256 uno::Reference< io::XTruncate > xTrunc( xOutStream, uno::UNO_QUERY ); 257 258 DBG_ASSERT( xTrunc.is(), "The output stream must exist and implement XTruncate interface!\n" ); 259 if ( !xTrunc.is() ) 260 throw RuntimeException(); 261 262 uno::Reference< io::XInputStream > xTmpInStream = 263 ::comphelper::OStorageHelper::GetInputStreamFromURL( aURL ); 264 DBG_ASSERT( xTmpInStream.is(), "The method must create the stream or throw an exception!\n" ); 265 if ( !xTmpInStream.is() ) 266 throw uno::RuntimeException(); 267 268 xTrunc->truncate(); 269 ::comphelper::OStorageHelper::CopyInputToOutput( xTmpInStream, xOutStream ); 270 xOutStream->closeOutput(); 271 272 uno::Reference< embed::XTransactedObject > xTransact( xVersion, uno::UNO_QUERY ); 273 DBG_ASSERT( xTransact.is(), "The storage must implement XTransacted interface!\n" ); 274 if ( xTransact.is() ) 275 xTransact->commit(); 276 277 bResult = sal_True; 278 } 279 catch( uno::Exception& ) 280 { 281 // TODO/LATER: handle the error depending on exception 282 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 283 } 284 285 return bResult; 286 } 287 288 //------------------------------------------------------------------------- 289 ::rtl::OUString SfxObjectShell::CreateTempCopyOfStorage_Impl( const uno::Reference< embed::XStorage >& xStorage ) 290 { 291 ::rtl::OUString aTempURL = ::utl::TempFile().GetURL(); 292 293 DBG_ASSERT( aTempURL.getLength(), "Can't create a temporary file!\n" ); 294 if ( aTempURL.getLength() ) 295 { 296 try 297 { 298 uno::Reference< embed::XStorage > xTempStorage = 299 ::comphelper::OStorageHelper::GetStorageFromURL( aTempURL, embed::ElementModes::READWRITE ); 300 301 // the password will be transfered from the xStorage to xTempStorage by storage implemetation 302 xStorage->copyToStorage( xTempStorage ); 303 304 // the temporary storage was commited by the previous method and it will die by refcount 305 } 306 catch ( uno::Exception& ) 307 { 308 DBG_ERROR( "Creation of a storage copy is failed!" ); 309 ::utl::UCBContentHelper::Kill( aTempURL ); 310 311 aTempURL = ::rtl::OUString(); 312 313 // TODO/LATER: may need error code setting based on exception 314 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 315 } 316 } 317 318 return aTempURL; 319 } 320 321 //------------------------------------------------------------------------- 322 SvGlobalName SfxObjectShell::GetClassName() const 323 { 324 return GetFactory().GetClassId(); 325 } 326 327 //------------------------------------------------------------------------- 328 void SfxObjectShell::SetupStorage( const uno::Reference< embed::XStorage >& xStorage, 329 sal_Int32 nVersion, 330 sal_Bool bTemplate ) const 331 { 332 uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY ); 333 334 if ( xProps.is() ) 335 { 336 SvGlobalName aName; 337 String aFullTypeName, aShortTypeName, aAppName; 338 sal_uInt32 nClipFormat=0; 339 340 FillClass( &aName, &nClipFormat, &aAppName, &aFullTypeName, &aShortTypeName, nVersion, bTemplate ); 341 if ( nClipFormat ) 342 { 343 // basic doesn't have a ClipFormat 344 // without MediaType the storage is not really usable, but currently the BasicIDE still 345 // is an SfxObjectShell and so we can't take this as an error 346 datatransfer::DataFlavor aDataFlavor; 347 SotExchange::GetFormatDataFlavor( nClipFormat, aDataFlavor ); 348 if ( aDataFlavor.MimeType.getLength() ) 349 { 350 try 351 { 352 xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ), uno::makeAny( aDataFlavor.MimeType ) ); 353 } 354 catch( uno::Exception& ) 355 { 356 const_cast<SfxObjectShell*>( this )->SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 357 } 358 359 SvtSaveOptions aSaveOpt; 360 SvtSaveOptions::ODFDefaultVersion nDefVersion = aSaveOpt.GetODFDefaultVersion(); 361 362 uno::Sequence< beans::NamedValue > aEncryptionAlgs( 3 ); 363 aEncryptionAlgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StartKeyGenerationAlgorithm" ) ); 364 aEncryptionAlgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionAlgorithm" ) ); 365 aEncryptionAlgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChecksumAlgorithm" ) ); 366 // the default values, that should be used for ODF1.1 and older formats 367 aEncryptionAlgs[0].Value <<= xml::crypto::DigestID::SHA1; 368 aEncryptionAlgs[1].Value <<= xml::crypto::CipherID::BLOWFISH_CFB_8; 369 aEncryptionAlgs[2].Value <<= xml::crypto::DigestID::SHA1_1K; 370 371 if ( nDefVersion >= SvtSaveOptions::ODFVER_012 ) 372 { 373 try 374 { 375 // older versions can not have this property set, it exists only starting from ODF1.2 376 xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "Version" ), uno::makeAny( ODFVER_012_TEXT ) ); 377 } 378 catch( uno::Exception& ) 379 { 380 } 381 382 if ( !aSaveOpt.IsUseSHA1InODF12() ) 383 { 384 aEncryptionAlgs[0].Value <<= xml::crypto::DigestID::SHA256; 385 aEncryptionAlgs[2].Value <<= xml::crypto::DigestID::SHA256_1K; 386 } 387 if ( !aSaveOpt.IsUseBlowfishInODF12() ) 388 aEncryptionAlgs[1].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; 389 } 390 391 try 392 { 393 // set the encryption algorithms accordingly; 394 // the setting does not trigger encryption, 395 // it just provides the format for the case that contents should be encrypted 396 uno::Reference< embed::XEncryptionProtectedStorage > xEncr( xStorage, uno::UNO_QUERY_THROW ); 397 xEncr->setEncryptionAlgorithms( aEncryptionAlgs ); 398 } 399 catch( uno::Exception& ) 400 { 401 const_cast<SfxObjectShell*>( this )->SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 402 } 403 404 } 405 } 406 } 407 } 408 409 //------------------------------------------------------------------------- 410 void SfxObjectShell::PrepareSecondTryLoad_Impl() 411 { 412 // only for internal use 413 pImp->m_xDocStorage = uno::Reference< embed::XStorage >(); 414 pImp->m_bIsInit = sal_False; 415 ResetError(); 416 } 417 418 //------------------------------------------------------------------------- 419 sal_Bool SfxObjectShell::GeneralInit_Impl( const uno::Reference< embed::XStorage >& xStorage, 420 sal_Bool bTypeMustBeSetAlready ) 421 { 422 if ( pImp->m_bIsInit ) 423 return sal_False; 424 425 pImp->m_bIsInit = sal_True; 426 if ( xStorage.is() ) 427 { 428 // no notification is required the storage is set the first time 429 pImp->m_xDocStorage = xStorage; 430 431 try { 432 uno::Reference < beans::XPropertySet > xPropSet( xStorage, uno::UNO_QUERY_THROW ); 433 Any a = xPropSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ); 434 ::rtl::OUString aMediaType; 435 if ( !(a>>=aMediaType) || !aMediaType.getLength() ) 436 { 437 if ( bTypeMustBeSetAlready ) 438 { 439 SetError( ERRCODE_IO_BROKENPACKAGE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 440 return sal_False; 441 } 442 443 SetupStorage( xStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False ); 444 } 445 } 446 catch ( uno::Exception& ) 447 { 448 OSL_ENSURE( sal_False, "Can't check storage's mediatype!\n" ); 449 } 450 } 451 else 452 pImp->m_bCreateTempStor = sal_True; 453 454 return sal_True; 455 } 456 457 //------------------------------------------------------------------------- 458 sal_Bool SfxObjectShell::InitNew( const uno::Reference< embed::XStorage >& xStorage ) 459 { 460 return GeneralInit_Impl( xStorage, sal_False ); 461 } 462 463 //------------------------------------------------------------------------- 464 sal_Bool SfxObjectShell::Load( SfxMedium& rMedium ) 465 { 466 return GeneralInit_Impl( rMedium.GetStorage(), sal_True ); 467 } 468 469 sal_Bool SfxObjectShell::DoInitNew( SfxMedium* pMed ) 470 /* [Beschreibung] 471 472 Diese von SvPersist geerbte virtuelle Methode wird gerufen, um 473 die SfxObjectShell-Instanz aus einem Storage (pStor != 0) bzw. 474 (pStor == 0) ganz neu zu initialisieren. 475 476 Wie alle Do...-Methoden liegt hier eine Steuerung vor, die eigentliche 477 Implementierung erfolgt, indem die ebenfalls virtuellen Methode 478 InitNew(SvStorate*) von der SfxObjectShell-Subclass implementiert wird. 479 480 F"ur pStor == 0 wird ein die SfxObjectShell-Instanz mit einem leeren 481 SfxMedium verbunden, sonst mit einem SfxMedium, welches auf den 482 als Parameter "ubergeben SvStorage verweist. 483 484 Erst nach InitNew() oder Load() ist das Objekt korrekt initialisiert. 485 486 [R"uckgabewert] 487 sal_True Das Objekt wurde initialisiert. 488 sal_False Das Objekt konnte nicht initialisiert werden 489 */ 490 491 { 492 ModifyBlocker_Impl aBlock( this ); 493 pMedium = pMed; 494 if ( !pMedium ) 495 { 496 bIsTmp = sal_True; 497 pMedium = new SfxMedium; 498 } 499 500 pMedium->CanDisposeStorage_Impl( sal_True ); 501 502 if ( InitNew( pMed ? pMed->GetStorage() : uno::Reference < embed::XStorage >() ) ) 503 { 504 // empty documents always get their macros from the user, so there is no reason to restrict access 505 pImp->aMacroMode.allowMacroExecution(); 506 if ( SFX_CREATE_MODE_EMBEDDED == eCreateMode ) 507 SetTitle( String( SfxResId( STR_NONAME ) )); 508 509 uno::Reference< frame::XModel > xModel ( GetModel(), uno::UNO_QUERY ); 510 if ( xModel.is() ) 511 { 512 SfxItemSet *pSet = GetMedium()->GetItemSet(); 513 uno::Sequence< beans::PropertyValue > aArgs; 514 TransformItems( SID_OPENDOC, *pSet, aArgs ); 515 sal_Int32 nLength = aArgs.getLength(); 516 aArgs.realloc( nLength + 1 ); 517 aArgs[nLength].Name = DEFINE_CONST_UNICODE("Title"); 518 aArgs[nLength].Value <<= ::rtl::OUString( GetTitle( SFX_TITLE_DETECT ) ); 519 xModel->attachResource( ::rtl::OUString(), aArgs ); 520 impl_addToModelCollection(xModel); 521 } 522 523 SetInitialized_Impl( true ); 524 return sal_True; 525 } 526 527 return sal_False; 528 } 529 530 //------------------------------------------------------------------------- 531 532 sal_Bool SfxObjectShell::ImportFromGeneratedStream_Impl( 533 const uno::Reference< io::XStream >& xStream, 534 const uno::Sequence< beans::PropertyValue >& aMediaDescr ) 535 { 536 if ( !xStream.is() ) 537 return sal_False; 538 539 if ( pMedium && pMedium->HasStorage_Impl() ) 540 pMedium->CloseStorage(); 541 542 sal_Bool bResult = sal_False; 543 544 try 545 { 546 uno::Reference< embed::XStorage > xStorage = 547 ::comphelper::OStorageHelper::GetStorageFromStream( xStream, embed::ElementModes::READWRITE ); 548 549 if ( !xStorage.is() ) 550 throw uno::RuntimeException(); 551 552 if ( !pMedium ) 553 pMedium = new SfxMedium( xStorage, String() ); 554 else 555 pMedium->SetStorage_Impl( xStorage ); 556 557 SfxAllItemSet aSet( SFX_APP()->GetPool() ); 558 TransformParameters( SID_OPENDOC, aMediaDescr, aSet ); 559 pMedium->GetItemSet()->Put( aSet ); 560 pMedium->CanDisposeStorage_Impl( sal_False ); 561 562 // allow the subfilter to reinit the model 563 if ( pImp->m_bIsInit ) 564 pImp->m_bIsInit = sal_False; 565 566 if ( LoadOwnFormat( *pMedium ) ) 567 { 568 bHasName = sal_True; 569 if ( !IsReadOnly() && IsLoadReadonly() ) 570 SetReadOnlyUI(); 571 572 bResult = sal_True; 573 OSL_ENSURE( pImp->m_xDocStorage == xStorage, "Wrong storage is used!\n" ); 574 } 575 576 // now the medium can be disconnected from the storage 577 // the medium is not allowed to dispose the storage so CloseStorage() can be used 578 pMedium->CloseStorage(); 579 } 580 catch( uno::Exception& ) 581 { 582 } 583 584 return bResult; 585 } 586 587 //------------------------------------------------------------------------- 588 589 sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed ) 590 { 591 ModifyBlocker_Impl aBlock( this ); 592 593 if ( SFX_CREATE_MODE_EMBEDDED != eCreateMode ) 594 GetpApp()->ShowStatusText( SfxResId(STR_DOC_LOADING) ); 595 596 pMedium = pMed; 597 pMedium->CanDisposeStorage_Impl( sal_True ); 598 599 sal_Bool bOk = sal_False; 600 const SfxFilter* pFilter = pMed->GetFilter(); 601 SfxItemSet* pSet = pMedium->GetItemSet(); 602 if( !pImp->nEventId ) 603 { 604 SFX_ITEMSET_ARG( 605 pSet, pTemplateItem, SfxBoolItem, 606 SID_TEMPLATE, sal_False); 607 SetActivateEvent_Impl( 608 ( pTemplateItem && pTemplateItem->GetValue() ) 609 ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC ); 610 } 611 612 613 SFX_ITEMSET_ARG( pSet, pBaseItem, SfxStringItem, 614 SID_BASEURL, sal_False); 615 String aBaseURL; 616 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False); 617 if( pBaseItem ) 618 aBaseURL = pBaseItem->GetValue(); 619 else 620 { 621 if ( pSalvageItem ) 622 { 623 String aName( pMed->GetPhysicalName() ); 624 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aBaseURL ); 625 } 626 else 627 aBaseURL = pMed->GetBaseURL(); 628 } 629 pMed->GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, aBaseURL ) ); 630 631 pImp->nLoadedFlags = 0; 632 pImp->bModelInitialized = sal_False; 633 634 //TODO/LATER: make a clear strategy how to handle "UsesStorage" etc. 635 sal_Bool bOwnStorageFormat = IsOwnStorageFormat_Impl( *pMedium ); 636 sal_Bool bHasStorage = IsPackageStorageFormat_Impl( *pMedium ); 637 if ( pMedium->GetFilter() ) 638 { 639 sal_uInt32 nError = HandleFilter( pMedium, this ); 640 if ( nError != ERRCODE_NONE ) 641 SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 642 } 643 644 EnableSetModified( sal_False ); 645 646 pMedium->LockOrigFileOnDemand( sal_True, sal_False ); 647 if ( GetError() == ERRCODE_NONE && bOwnStorageFormat && ( !pFilter || !( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) ) ) 648 { 649 uno::Reference< embed::XStorage > xStorage; 650 if ( pMedium->GetError() == ERRCODE_NONE ) 651 xStorage = pMedium->GetStorage(); 652 653 if( xStorage.is() && pMedium->GetLastStorageCreationState() == ERRCODE_NONE ) 654 { 655 DBG_ASSERT( pFilter, "No filter for storage found!" ); 656 657 try 658 { 659 sal_Bool bWarnMediaTypeFallback = sal_False; 660 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairPackageItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False); 661 662 // treat the package as broken if the mediatype was retrieved as a fallback 663 uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW ); 664 xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaTypeFallbackUsed" ) ) ) 665 >>= bWarnMediaTypeFallback; 666 667 if ( pRepairPackageItem && pRepairPackageItem->GetValue() ) 668 { 669 // the macros in repaired documents should be disabled 670 pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, document::MacroExecMode::NEVER_EXECUTE ) ); 671 672 // the mediatype was retrieved by using fallback solution but this is a repairing mode 673 // so it is acceptable to open the document if there is no contents that required manifest.xml 674 bWarnMediaTypeFallback = sal_False; 675 } 676 677 if ( bWarnMediaTypeFallback || !xStorage->getElementNames().getLength() ) 678 SetError( ERRCODE_IO_BROKENPACKAGE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 679 } 680 catch( uno::Exception& ) 681 { 682 // TODO/LATER: may need error code setting based on exception 683 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 684 } 685 686 // Load 687 if ( !GetError() ) 688 { 689 pImp->nLoadedFlags = 0; 690 pImp->bModelInitialized = sal_False; 691 bOk = xStorage.is() && LoadOwnFormat( *pMed ); 692 if ( bOk ) 693 { 694 // the document loaded from template has no name 695 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False); 696 if ( !pTemplateItem || !pTemplateItem->GetValue() ) 697 bHasName = sal_True; 698 699 if ( !IsReadOnly() && IsLoadReadonly() ) 700 SetReadOnlyUI(); 701 } 702 else 703 SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 704 } 705 } 706 else 707 SetError( pMed->GetLastStorageCreationState(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 708 } 709 else if ( GetError() == ERRCODE_NONE && InitNew(0) ) 710 { 711 // Name vor ConvertFrom setzen, damit GetSbxObject() schon funktioniert 712 bHasName = sal_True; 713 SetName( SfxResId( STR_NONAME ) ); 714 715 if( !bHasStorage ) 716 pMedium->GetInStream(); 717 else 718 pMedium->GetStorage(); 719 720 if ( GetError() == ERRCODE_NONE ) 721 { 722 pImp->nLoadedFlags = 0; 723 pImp->bModelInitialized = sal_False; 724 if ( pMedium->GetFilter() && ( pMedium->GetFilter()->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) ) 725 { 726 uno::Reference < beans::XPropertySet > xSet( GetModel(), uno::UNO_QUERY ); 727 ::rtl::OUString sLockUpdates(::rtl::OUString::createFromAscii("LockUpdates")); 728 bool bSetProperty = true; 729 try 730 { 731 xSet->setPropertyValue( sLockUpdates, makeAny( (sal_Bool) sal_True ) ); 732 } 733 catch(const beans::UnknownPropertyException& ) 734 { 735 bSetProperty = false; 736 } 737 bOk = ImportFrom(*pMedium); 738 if(bSetProperty) 739 { 740 try 741 { 742 xSet->setPropertyValue( sLockUpdates, makeAny( (sal_Bool) sal_False ) ); 743 } 744 catch(const beans::UnknownPropertyException& ) 745 {} 746 } 747 UpdateLinks(); 748 FinishedLoading( SFX_LOADED_ALL ); 749 } 750 else 751 { 752 bOk = ConvertFrom(*pMedium); 753 InitOwnModel_Impl(); 754 } 755 } 756 } 757 758 if ( bOk ) 759 { 760 try 761 { 762 ::ucbhelper::Content aContent( pMedium->GetName(), com::sun::star::uno::Reference < XCommandEnvironment >() ); 763 com::sun::star::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties(); 764 if ( xProps.is() ) 765 { 766 ::rtl::OUString aAuthor( RTL_CONSTASCII_USTRINGPARAM("Author") ); 767 ::rtl::OUString aKeywords( RTL_CONSTASCII_USTRINGPARAM("Keywords") ); 768 ::rtl::OUString aSubject( RTL_CONSTASCII_USTRINGPARAM("Subject") ); 769 Any aAny; 770 ::rtl::OUString aValue; 771 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( 772 GetModel(), uno::UNO_QUERY_THROW); 773 uno::Reference<document::XDocumentProperties> xDocProps 774 = xDPS->getDocumentProperties(); 775 if ( xProps->hasPropertyByName( aAuthor ) ) 776 { 777 aAny = aContent.getPropertyValue( aAuthor ); 778 if ( ( aAny >>= aValue ) ) 779 xDocProps->setAuthor(aValue); 780 } 781 if ( xProps->hasPropertyByName( aKeywords ) ) 782 { 783 aAny = aContent.getPropertyValue( aKeywords ); 784 if ( ( aAny >>= aValue ) ) 785 xDocProps->setKeywords( 786 ::comphelper::string::convertCommaSeparated(aValue)); 787 ; 788 } 789 if ( xProps->hasPropertyByName( aSubject ) ) 790 { 791 aAny = aContent.getPropertyValue( aSubject ); 792 if ( ( aAny >>= aValue ) ) { 793 xDocProps->setSubject(aValue); 794 } 795 } 796 } 797 } 798 catch( Exception& ) 799 { 800 } 801 802 // Falls nicht asynchron geladen wird selbst FinishedLoading aufrufen 803 if ( !( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) && 804 ( !pMedium->GetFilter() || pMedium->GetFilter()->UsesStorage() ) 805 ) 806 FinishedLoading( SFX_LOADED_MAINDOCUMENT ); 807 808 if( IsOwnStorageFormat_Impl(*pMed) && pMed->GetFilter() ) 809 { 810 //???? dv DirEntry aDirEntry( pMed->GetPhysicalName() ); 811 //???? dv SetFileName( aDirEntry.GetFull() ); 812 } 813 Broadcast( SfxSimpleHint(SFX_HINT_NAMECHANGED) ); 814 815 if ( SFX_CREATE_MODE_EMBEDDED != eCreateMode ) 816 { 817 GetpApp()->HideStatusText(); 818 819 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pAsTempItem, SfxBoolItem, SID_TEMPLATE, sal_False); 820 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False); 821 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False); 822 if( bOk && pMedium->GetOrigURL().Len() 823 && !( pAsTempItem && pAsTempItem->GetValue() ) 824 && !( pPreviewItem && pPreviewItem->GetValue() ) 825 && !( pHiddenItem && pHiddenItem->GetValue() ) ) 826 { 827 INetURLObject aUrl( pMedium->GetOrigURL() ); 828 829 if ( aUrl.GetProtocol() == INET_PROT_FILE ) 830 { 831 const SfxFilter* pOrgFilter = pMedium->GetOrigFilter(); 832 Application::AddToRecentDocumentList( 833 aUrl.GetURLNoPass( INetURLObject::NO_DECODE ), 834 (pOrgFilter) ? pOrgFilter->GetMimeType() : String() ); 835 } 836 } 837 } 838 839 if ( pMedium->HasStorage_Impl() ) 840 { 841 uno::Reference< XInteractionHandler > xHandler( pMedium->GetInteractionHandler() ); 842 if ( xHandler.is() && !SFX_APP()->Get_Impl()->bODFVersionWarningLater ) 843 { 844 uno::Reference<beans::XPropertySet> xStorageProps( pMedium->GetStorage(), uno::UNO_QUERY_THROW ); 845 ::rtl::OUString sVersion; 846 try 847 { 848 xStorageProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= sVersion; 849 } 850 catch( const uno::Exception& ) 851 { 852 // Custom Property "ODFVersion" does not exist 853 } 854 855 if ( sVersion.getLength() ) 856 { 857 double nVersion = sVersion.toDouble(); 858 if ( nVersion > 1.20001 && SfxObjectShell_Impl::NeedsOfficeUpdateDialog() ) 859 // ODF version greater than 1.2 - added some decimal places to be safe against floating point conversion errors (hack) 860 { 861 ::rtl::OUString sDocumentURL( pMedium->GetOrigURL() ); 862 ::rtl::OUString aSystemFileURL; 863 if ( osl::FileBase::getSystemPathFromFileURL( sDocumentURL, aSystemFileURL ) == osl::FileBase::E_None ) 864 sDocumentURL = aSystemFileURL; 865 866 FutureDocumentVersionProductUpdateRequest aUpdateRequest; 867 aUpdateRequest.Classification = InteractionClassification_QUERY; 868 aUpdateRequest.DocumentURL = sDocumentURL; 869 870 ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest = new ::comphelper::OInteractionRequest( makeAny( aUpdateRequest ) ); 871 pRequest->addContinuation( new ::comphelper::OInteractionApprove ); 872 pRequest->addContinuation( new ::comphelper::OInteractionAbort ); 873 874 typedef ::comphelper::OInteraction< XInteractionAskLater > OInteractionAskLater; 875 OInteractionAskLater* pLater = new OInteractionAskLater; 876 pRequest->addContinuation( pLater ); 877 878 try 879 { 880 xHandler->handle( pRequest.get() ); 881 } 882 catch( const Exception& ) 883 { 884 DBG_UNHANDLED_EXCEPTION(); 885 } 886 if ( pLater->wasSelected() ) 887 SFX_APP()->Get_Impl()->bODFVersionWarningLater = true; 888 } 889 } 890 } 891 } 892 } 893 else 894 GetpApp()->HideStatusText(); 895 896 return bOk; 897 } 898 899 sal_uInt32 SfxObjectShell::HandleFilter( SfxMedium* pMedium, SfxObjectShell* pDoc ) 900 { 901 sal_uInt32 nError = ERRCODE_NONE; 902 SfxItemSet* pSet = pMedium->GetItemSet(); 903 SFX_ITEMSET_ARG( pSet, pOptions, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False ); 904 SFX_ITEMSET_ARG( pSet, pData, SfxUnoAnyItem, SID_FILTER_DATA, sal_False ); 905 if ( !pData && !pOptions ) 906 { 907 com::sun::star::uno::Reference< XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); 908 com::sun::star::uno::Reference< XNameAccess > xFilterCFG; 909 if( xServiceManager.is() ) 910 { 911 xFilterCFG = com::sun::star::uno::Reference< XNameAccess >( 912 xServiceManager->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ), 913 UNO_QUERY ); 914 } 915 916 if( xFilterCFG.is() ) 917 { 918 sal_Bool bAbort = sal_False; 919 try { 920 const SfxFilter* pFilter = pMedium->GetFilter(); 921 Sequence < PropertyValue > aProps; 922 Any aAny = xFilterCFG->getByName( pFilter->GetName() ); 923 if ( aAny >>= aProps ) 924 { 925 sal_Int32 nPropertyCount = aProps.getLength(); 926 for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty ) 927 if( aProps[nProperty].Name.equals( ::rtl::OUString::createFromAscii("UIComponent")) ) 928 { 929 ::rtl::OUString aServiceName; 930 aProps[nProperty].Value >>= aServiceName; 931 if( aServiceName.getLength() ) 932 { 933 com::sun::star::uno::Reference< XInteractionHandler > rHandler = pMedium->GetInteractionHandler(); 934 if( rHandler.is() ) 935 { 936 // we need some properties in the media descriptor, so we have to make sure that they are in 937 Any aStreamAny; 938 aStreamAny <<= pMedium->GetInputStream(); 939 if ( pSet->GetItemState( SID_INPUTSTREAM ) < SFX_ITEM_SET ) 940 pSet->Put( SfxUnoAnyItem( SID_INPUTSTREAM, aStreamAny ) ); 941 if ( pSet->GetItemState( SID_FILE_NAME ) < SFX_ITEM_SET ) 942 pSet->Put( SfxStringItem( SID_FILE_NAME, pMedium->GetName() ) ); 943 if ( pSet->GetItemState( SID_FILTER_NAME ) < SFX_ITEM_SET ) 944 pSet->Put( SfxStringItem( SID_FILTER_NAME, pFilter->GetName() ) ); 945 946 Sequence< PropertyValue > rProperties; 947 TransformItems( SID_OPENDOC, *pSet, rProperties, NULL ); 948 RequestFilterOptions* pFORequest = new RequestFilterOptions( pDoc->GetModel(), rProperties ); 949 950 com::sun::star::uno::Reference< XInteractionRequest > rRequest( pFORequest ); 951 rHandler->handle( rRequest ); 952 953 if ( !pFORequest->isAbort() ) 954 { 955 SfxAllItemSet aNewParams( pDoc->GetPool() ); 956 TransformParameters( SID_OPENDOC, 957 pFORequest->getFilterOptions(), 958 aNewParams, 959 NULL ); 960 961 SFX_ITEMSET_ARG( &aNewParams, 962 pFilterOptions, 963 SfxStringItem, 964 SID_FILE_FILTEROPTIONS, 965 sal_False ); 966 if ( pFilterOptions ) 967 pSet->Put( *pFilterOptions ); 968 969 SFX_ITEMSET_ARG( &aNewParams, 970 pFilterData, 971 SfxUnoAnyItem, 972 SID_FILTER_DATA, 973 sal_False ); 974 if ( pFilterData ) 975 pSet->Put( *pFilterData ); 976 } 977 else 978 bAbort = sal_True; 979 } 980 } 981 982 break; 983 } 984 } 985 986 if( bAbort ) 987 { 988 // filter options were not entered 989 nError = ERRCODE_ABORT; 990 } 991 } 992 catch( NoSuchElementException& ) 993 { 994 // the filter name is unknown 995 nError = ERRCODE_IO_INVALIDPARAMETER; 996 } 997 catch( Exception& ) 998 { 999 nError = ERRCODE_ABORT; 1000 } 1001 } 1002 } 1003 1004 return nError; 1005 } 1006 1007 //------------------------------------------------------------------------- 1008 1009 sal_Bool SfxObjectShell::IsOwnStorageFormat_Impl(const SfxMedium &rMedium) const 1010 { 1011 return !rMedium.GetFilter() || // Embedded 1012 ( rMedium.GetFilter()->IsOwnFormat() && 1013 rMedium.GetFilter()->UsesStorage() && 1014 rMedium.GetFilter()->GetVersion() >= SOFFICE_FILEFORMAT_60 ); 1015 } 1016 1017 //------------------------------------------------------------------------- 1018 1019 sal_Bool SfxObjectShell::IsPackageStorageFormat_Impl(const SfxMedium &rMedium) const 1020 { 1021 return !rMedium.GetFilter() || // Embedded 1022 ( rMedium.GetFilter()->UsesStorage() && 1023 rMedium.GetFilter()->GetVersion() >= SOFFICE_FILEFORMAT_60 ); 1024 } 1025 1026 //------------------------------------------------------------------------- 1027 1028 sal_Bool SfxObjectShell::DoSave() 1029 // DoSave wird nur noch ueber OLE aufgerufen. Sichern eigener Dokumente im SFX 1030 // laeuft uber DoSave_Impl, um das Anlegen von Backups zu ermoeglichen. 1031 // Save in eigenes Format jetzt auch wieder Hierueber 1032 { 1033 sal_Bool bOk = sal_False ; 1034 { 1035 ModifyBlocker_Impl aBlock( this ); 1036 1037 pImp->bIsSaving = sal_True; 1038 1039 uno::Sequence< beans::NamedValue > aEncryptionData; 1040 if ( IsPackageStorageFormat_Impl( *GetMedium() ) ) 1041 { 1042 if ( GetEncryptionData_Impl( GetMedium()->GetItemSet(), aEncryptionData ) ) 1043 { 1044 try 1045 { 1046 //TODO/MBA: GetOutputStorage?! Special mode, because it's "Save"?! 1047 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( GetMedium()->GetStorage(), aEncryptionData ); 1048 bOk = sal_True; 1049 } 1050 catch( uno::Exception& ) 1051 { 1052 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1053 } 1054 1055 DBG_ASSERT( bOk, "The root storage must allow to set common password!\n" ); 1056 } 1057 else 1058 bOk = sal_True; 1059 1060 if ( HasBasic() ) 1061 { 1062 try 1063 { 1064 // The basic and dialogs related contents are still not able to proceed with save operation ( saveTo only ) 1065 // so since the document storage is locked a workaround has to be used 1066 1067 uno::Reference< embed::XStorage > xTmpStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 1068 DBG_ASSERT( xTmpStorage.is(), "If a storage can not be created an exception must be thrown!\n" ); 1069 if ( !xTmpStorage.is() ) 1070 throw uno::RuntimeException(); 1071 1072 ::rtl::OUString aBasicStorageName( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ); 1073 ::rtl::OUString aDialogsStorageName( RTL_CONSTASCII_USTRINGPARAM( "Dialogs" ) ); 1074 if ( GetMedium()->GetStorage()->hasByName( aBasicStorageName ) ) 1075 GetMedium()->GetStorage()->copyElementTo( aBasicStorageName, xTmpStorage, aBasicStorageName ); 1076 if ( GetMedium()->GetStorage()->hasByName( aDialogsStorageName ) ) 1077 GetMedium()->GetStorage()->copyElementTo( aDialogsStorageName, xTmpStorage, aDialogsStorageName ); 1078 1079 GetBasicManager(); 1080 1081 // disconnect from the current storage 1082 pImp->pBasicManager->setStorage( xTmpStorage ); 1083 1084 // store to the current storage 1085 pImp->pBasicManager->storeLibrariesToStorage( GetMedium()->GetStorage() ); 1086 1087 // connect to the current storage back 1088 pImp->pBasicManager->setStorage( GetMedium()->GetStorage() ); 1089 } 1090 catch( uno::Exception& ) 1091 { 1092 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1093 bOk = sal_False; 1094 } 1095 } 1096 } 1097 1098 if ( bOk ) 1099 bOk = Save(); 1100 1101 bOk = pMedium->Commit(); 1102 } 1103 1104 //#88046 1105 // if ( bOk ) 1106 // SetModified( sal_False ); 1107 return bOk; 1108 } 1109 1110 void Lock_Impl( SfxObjectShell* pDoc, sal_Bool bLock ) 1111 { 1112 SfxViewFrame *pFrame= SfxViewFrame::GetFirst( pDoc ); 1113 while ( pFrame ) 1114 { 1115 pFrame->GetDispatcher()->Lock( bLock ); 1116 pFrame->Enable( !bLock ); 1117 pFrame = SfxViewFrame::GetNext( *pFrame, pDoc ); 1118 } 1119 1120 } 1121 1122 //------------------------------------------------------------------------- 1123 1124 sal_Bool SfxObjectShell::SaveTo_Impl 1125 ( 1126 SfxMedium &rMedium, // Medium, in das gespeichert werden soll 1127 const SfxItemSet* pSet 1128 ) 1129 1130 /* [Beschreibung] 1131 1132 Schreibt den aktuellen Inhalt in das Medium rMedium. 1133 Ist das Zielmedium kein Storage, so wird ueber ein temporaeres 1134 Medium gespeichert, sonst direkt, da das Medium transacted 1135 geschaltet ist, wenn wir es selbst geoeffnet haben und falls wir 1136 Server sind entweder der Container einen transacted Storage zur 1137 Verfuegung stellt oder selbst einen temporaeren Storage erzeugt hat. 1138 */ 1139 1140 { 1141 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE SfxObjectShell::SaveTo_Impl" ); 1142 if( RTL_LOGFILE_HASLOGFILE() ) 1143 { 1144 ByteString aString( rMedium.GetName(), RTL_TEXTENCODING_ASCII_US ); 1145 RTL_LOGFILE_PRODUCT_CONTEXT_TRACE1( aLog, "saving \"%s\"", aString.GetBuffer() ); 1146 } 1147 1148 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Begin" ) ) ); 1149 1150 ModifyBlocker_Impl aMod(this); 1151 1152 const SfxFilter *pFilter = rMedium.GetFilter(); 1153 if ( !pFilter ) 1154 { 1155 // if no filter was set, use the default filter 1156 // this should be changed in the feature, it should be an error! 1157 DBG_ERROR("No filter set!"); 1158 pFilter = GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_IMPORT | SFX_FILTER_EXPORT ); 1159 rMedium.SetFilter(pFilter); 1160 } 1161 1162 sal_Bool bStorageBasedSource = IsPackageStorageFormat_Impl( *pMedium ); 1163 sal_Bool bStorageBasedTarget = IsPackageStorageFormat_Impl( rMedium ); 1164 sal_Bool bOwnSource = IsOwnStorageFormat_Impl( *pMedium ); 1165 sal_Bool bOwnTarget = IsOwnStorageFormat_Impl( rMedium ); 1166 1167 // Examine target format to determine whether to query if any password 1168 // protected libraries exceed the size we can handler 1169 if ( bOwnTarget && !QuerySaveSizeExceededModules_Impl( rMedium.GetInteractionHandler() ) ) 1170 { 1171 SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1172 return sal_False; 1173 } 1174 1175 sal_Bool bNeedsDisconnectionOnFail = sal_False; 1176 1177 sal_Bool bStoreToSameLocation = sal_False; 1178 1179 // the detection whether the script is changed should be done before saving 1180 sal_Bool bTryToPreserveScriptSignature = sal_False; 1181 // no way to detect whether a filter is oasis format, have to wait for saving process 1182 sal_Bool bNoPreserveForOasis = sal_False; 1183 if ( bOwnSource && bOwnTarget 1184 && ( pImp->nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK 1185 || pImp->nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED 1186 || pImp->nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_INVALID ) ) 1187 { 1188 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MacroSignaturePreserving" ) ) ); 1189 1190 // the checking of the library modified state iterates over the libraries, should be done only when required 1191 // currently the check is commented out since it is broken, we have to check the signature every time we save 1192 // TODO/LATER: let isAnyContainerModified() work! 1193 bTryToPreserveScriptSignature = sal_True; // !pImp->pBasicManager->isAnyContainerModified(); 1194 if ( bTryToPreserveScriptSignature ) 1195 { 1196 // check that the storage format stays the same 1197 SvtSaveOptions aSaveOpt; 1198 SvtSaveOptions::ODFDefaultVersion nVersion = aSaveOpt.GetODFDefaultVersion(); 1199 1200 ::rtl::OUString aODFVersion; 1201 try 1202 { 1203 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); 1204 xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aODFVersion; 1205 } 1206 catch( uno::Exception& ) 1207 {} 1208 1209 // preserve only if the same filter has been used 1210 bTryToPreserveScriptSignature = pMedium->GetFilter() && pFilter && pMedium->GetFilter()->GetFilterName() == pFilter->GetFilterName(); 1211 1212 bNoPreserveForOasis = ( 1213 (aODFVersion.equals( ODFVER_012_TEXT ) && nVersion == SvtSaveOptions::ODFVER_011) || 1214 (!aODFVersion.getLength() && nVersion >= SvtSaveOptions::ODFVER_012) 1215 ); 1216 } 1217 } 1218 1219 sal_Bool bCopyTo = sal_False; 1220 SfxItemSet *pMedSet = rMedium.GetItemSet(); 1221 if( pMedSet ) 1222 { 1223 SFX_ITEMSET_ARG( pMedSet, pSaveToItem, SfxBoolItem, SID_SAVETO, sal_False ); 1224 bCopyTo = GetCreateMode() == SFX_CREATE_MODE_EMBEDDED || 1225 (pSaveToItem && pSaveToItem->GetValue()); 1226 } 1227 1228 // use UCB for case sensitive/insensitive file name comparison 1229 if ( pMedium 1230 && pMedium->GetName().CompareIgnoreCaseToAscii( "private:stream", 14 ) != COMPARE_EQUAL 1231 && rMedium.GetName().CompareIgnoreCaseToAscii( "private:stream", 14 ) != COMPARE_EQUAL 1232 && ::utl::UCBContentHelper::EqualURLs( pMedium->GetName(), rMedium.GetName() ) ) 1233 { 1234 bStoreToSameLocation = sal_True; 1235 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save" ) ) ); 1236 1237 if ( pMedium->DocNeedsFileDateCheck() ) 1238 rMedium.CheckFileDate( pMedium->GetInitFileDate( sal_False ) ); 1239 1240 if ( bCopyTo && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) 1241 { 1242 // export to the same location is vorbidden 1243 SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1244 } 1245 else 1246 { 1247 // before we overwrite the original file, we will make a backup if there is a demand for that 1248 // if the backup is not created here it will be created internally and will be removed in case of successful saving 1249 const sal_Bool bDoBackup = SvtSaveOptions().IsBackup(); 1250 if ( bDoBackup ) 1251 { 1252 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "DoBackup" ) ) ); 1253 rMedium.DoBackup_Impl(); 1254 if ( rMedium.GetError() ) 1255 { 1256 SetError( rMedium.GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1257 rMedium.ResetError(); 1258 } 1259 } 1260 1261 if ( bStorageBasedSource && bStorageBasedTarget ) 1262 { 1263 // The active storage must be switched. The simple saving is not enough. 1264 // The problem is that the target medium contains target MediaDescriptor. 1265 1266 // In future the switch of the persistance could be done on stream level: 1267 // a new wrapper service will be implemented that allows to exchange 1268 // persistance on the fly. So the real persistance will be set 1269 // to that stream only after successful commit of the storage. 1270 // TODO/LATER: 1271 // create wrapper stream based on the URL 1272 // create a new storage based on this stream 1273 // store to this new storage 1274 // commit the new storage 1275 // call saveCompleted based with this new storage ( get rid of old storage and "frees" URL ) 1276 // commit the wrapper stream ( the stream will connect the URL only on commit, after that it will hold it ) 1277 // if the last step is failed the stream should stay to be transacted and should be commited on any flush 1278 // so we can forget the stream in any way and the next storage commit will flush it 1279 1280 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Own to Own" ) ) ); 1281 1282 bNeedsDisconnectionOnFail = DisconnectStorage_Impl( 1283 *pMedium, rMedium ); 1284 if ( bNeedsDisconnectionOnFail 1285 || ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) ) 1286 { 1287 pMedium->CloseAndRelease(); 1288 1289 // TODO/LATER: for now the medium must be closed since it can already contain streams from old medium 1290 // in future those streams should not be copied in case a valid target url is provided, 1291 // if the url is not provided ( means the document is based on a stream ) this code is not 1292 // reachable. 1293 rMedium.CloseAndRelease(); 1294 rMedium.GetOutputStorage(); 1295 } 1296 } 1297 else if ( !bStorageBasedSource && !bStorageBasedTarget ) 1298 { 1299 // the source and the target formats are alien 1300 // just disconnect the stream from the source format 1301 // so that the target medium can use it 1302 1303 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Alien to Alien" ) ) ); 1304 1305 pMedium->CloseAndRelease(); 1306 rMedium.CloseAndRelease(); 1307 rMedium.CreateTempFileNoCopy(); 1308 rMedium.GetOutStream(); 1309 } 1310 else if ( !bStorageBasedSource && bStorageBasedTarget ) 1311 { 1312 // the source format is an alien one but the target 1313 // format is an own one so just disconnect the source 1314 // medium 1315 1316 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Alien to Own" ) ) ); 1317 1318 pMedium->CloseAndRelease(); 1319 rMedium.CloseAndRelease(); 1320 rMedium.GetOutputStorage(); 1321 } 1322 else // means if ( bStorageBasedSource && !bStorageBasedTarget ) 1323 { 1324 // the source format is an own one but the target is 1325 // an alien format, just connect the source to temporary 1326 // storage 1327 1328 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save: Own to Alien" ) ) ); 1329 1330 bNeedsDisconnectionOnFail = DisconnectStorage_Impl( 1331 *pMedium, rMedium ); 1332 if ( bNeedsDisconnectionOnFail 1333 || ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) ) 1334 { 1335 pMedium->CloseAndRelease(); 1336 rMedium.CloseAndRelease(); 1337 rMedium.CreateTempFileNoCopy(); 1338 rMedium.GetOutStream(); 1339 } 1340 } 1341 } 1342 } 1343 else 1344 { 1345 // This is SaveAs or export action, prepare the target medium 1346 // the alien filters still might write directly to the file, that is of course a bug, 1347 // but for now the framework has to be ready for it 1348 // TODO/LATER: let the medium be prepared for alien formats as well 1349 1350 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "SaveAs/Export" ) ) ); 1351 1352 rMedium.CloseAndRelease(); 1353 if ( bStorageBasedTarget ) 1354 { 1355 rMedium.GetOutputStorage(); 1356 } 1357 } 1358 1359 // TODO/LATER: error handling 1360 if( rMedium.GetErrorCode() || pMedium->GetErrorCode() || GetErrorCode() ) 1361 return sal_False; 1362 1363 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Locking" ) ) ); 1364 1365 rMedium.LockOrigFileOnDemand( sal_False, sal_False ); 1366 1367 if ( bStorageBasedTarget ) 1368 { 1369 if ( rMedium.GetErrorCode() ) 1370 return sal_False; 1371 1372 // If the filter is a "cross export" filter ( f.e. a filter for exporting an impress document from 1373 // a draw document ), the ClassId of the destination storage is different from the ClassId of this 1374 // document. It can be retrieved from the default filter for the desired target format 1375 long nFormat = rMedium.GetFilter()->GetFormat(); 1376 SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher(); 1377 const SfxFilter *pFilt = rMatcher.GetFilter4ClipBoardId( nFormat ); 1378 if ( pFilt ) 1379 { 1380 if ( pFilt->GetServiceName() != rMedium.GetFilter()->GetServiceName() ) 1381 { 1382 datatransfer::DataFlavor aDataFlavor; 1383 SotExchange::GetFormatDataFlavor( nFormat, aDataFlavor ); 1384 1385 try 1386 { 1387 uno::Reference< beans::XPropertySet > xProps( rMedium.GetStorage(), uno::UNO_QUERY ); 1388 DBG_ASSERT( xProps.is(), "The storage implementation must implement XPropertySet!" ); 1389 if ( !xProps.is() ) 1390 throw uno::RuntimeException(); 1391 1392 xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ), 1393 uno::makeAny( aDataFlavor.MimeType ) ); 1394 } 1395 catch( uno::Exception& ) 1396 { 1397 } 1398 } 1399 } 1400 } 1401 1402 // TODO/LATER: error handling 1403 if( rMedium.GetErrorCode() || pMedium->GetErrorCode() || GetErrorCode() ) 1404 return sal_False; 1405 1406 sal_Bool bOldStat = pImp->bForbidReload; 1407 pImp->bForbidReload = sal_True; 1408 1409 // lock user interface while saving the document 1410 Lock_Impl( this, sal_True ); 1411 1412 sal_Bool bOk = sal_False; 1413 // TODO/LATER: get rid of bOk 1414 1415 if( bOwnTarget && !( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) ) 1416 { 1417 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing in own format." ) ) ); 1418 uno::Reference< embed::XStorage > xMedStorage = rMedium.GetStorage(); 1419 if ( !xMedStorage.is() ) 1420 { 1421 // no saving without storage, unlock UI and return 1422 Lock_Impl( this, sal_False ); 1423 pImp->bForbidReload = bOldStat; 1424 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed, still no error set." ) ) ); 1425 return sal_False; 1426 } 1427 1428 // transfer password from the parameters to the storage 1429 uno::Sequence< beans::NamedValue > aEncryptionData; 1430 sal_Bool bPasswdProvided = sal_False; 1431 if ( GetEncryptionData_Impl( rMedium.GetItemSet(), aEncryptionData ) ) 1432 { 1433 bPasswdProvided = sal_True; 1434 try { 1435 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( xMedStorage, aEncryptionData ); 1436 bOk = sal_True; 1437 } 1438 catch( uno::Exception& ) 1439 { 1440 DBG_ERROR( "Setting of common encryption key failed!" ); 1441 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1442 } 1443 } 1444 else 1445 bOk = sal_True; 1446 1447 pFilter = rMedium.GetFilter(); 1448 1449 const SfxStringItem *pVersionItem = pSet ? (const SfxStringItem*) 1450 SfxRequest::GetItem( pSet, SID_DOCINFO_COMMENTS, sal_False, TYPE(SfxStringItem) ) : NULL; 1451 ::rtl::OUString aTmpVersionURL; 1452 1453 if ( bOk ) 1454 { 1455 bOk = sal_False; 1456 // currently the case that the storage is the same should be impossible 1457 if ( xMedStorage == GetStorage() ) 1458 { 1459 OSL_ENSURE( !pVersionItem, "This scenario is impossible currently!\n" ); 1460 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Should be impossible." ) ) ); 1461 // usual save procedure 1462 bOk = Save(); 1463 } 1464 else 1465 { 1466 // save to target 1467 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Save as own format." ) ) ); 1468 bOk = SaveAsOwnFormat( rMedium ); 1469 if ( bOk && pVersionItem ) 1470 { 1471 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "pVersionItem != NULL" ) ) ); 1472 aTmpVersionURL = CreateTempCopyOfStorage_Impl( xMedStorage ); 1473 bOk = ( aTmpVersionURL.getLength() > 0 ); 1474 } 1475 } 1476 } 1477 1478 1479 if ( bOk && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED && !bPasswdProvided ) 1480 { 1481 // store the thumbnail representation image 1482 // the thumbnail is not stored in case of encrypted document 1483 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Thumbnail creation." ) ) ); 1484 if ( !GenerateAndStoreThumbnail( bPasswdProvided, 1485 sal_False, 1486 pFilter->IsOwnTemplateFormat(), 1487 xMedStorage ) ) 1488 { 1489 // TODO: error handling 1490 OSL_ENSURE( sal_False, "Couldn't store thumbnail representation!" ); 1491 } 1492 } 1493 1494 if ( bOk ) 1495 { 1496 if ( pImp->bIsSaving || pImp->bPreserveVersions ) 1497 { 1498 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Preserve versions." ) ) ); 1499 try 1500 { 1501 Sequence < util::RevisionTag > aVersions = rMedium.GetVersionList(); 1502 if ( aVersions.getLength() ) 1503 { 1504 // copy the version streams 1505 ::rtl::OUString aVersionsName( RTL_CONSTASCII_USTRINGPARAM( "Versions" ) ); 1506 uno::Reference< embed::XStorage > xNewVerStor = xMedStorage->openStorageElement( 1507 aVersionsName, 1508 embed::ElementModes::READWRITE ); 1509 uno::Reference< embed::XStorage > xOldVerStor = GetStorage()->openStorageElement( 1510 aVersionsName, 1511 embed::ElementModes::READ ); 1512 if ( !xNewVerStor.is() || !xOldVerStor.is() ) 1513 throw uno::RuntimeException(); 1514 1515 for ( sal_Int32 n=0; n<aVersions.getLength(); n++ ) 1516 { 1517 if ( xOldVerStor->hasByName( aVersions[n].Identifier ) ) 1518 xOldVerStor->copyElementTo( aVersions[n].Identifier, xNewVerStor, aVersions[n].Identifier ); 1519 } 1520 1521 uno::Reference< embed::XTransactedObject > xTransact( xNewVerStor, uno::UNO_QUERY ); 1522 if ( xTransact.is() ) 1523 xTransact->commit(); 1524 } 1525 } 1526 catch( uno::Exception& ) 1527 { 1528 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Preserve versions has failed." ) ) ); 1529 DBG_ERROR( "Couldn't copy versions!\n" ); 1530 bOk = sal_False; 1531 // TODO/LATER: a specific error could be set 1532 } 1533 } 1534 1535 if ( bOk && pVersionItem ) 1536 { 1537 // store a version also 1538 const SfxStringItem *pAuthorItem = pSet ? (const SfxStringItem*) 1539 SfxRequest::GetItem( pSet, SID_DOCINFO_AUTHOR, sal_False, TYPE(SfxStringItem) ) : NULL; 1540 1541 // version comment 1542 util::RevisionTag aInfo; 1543 aInfo.Comment = pVersionItem->GetValue(); 1544 1545 // version author 1546 String aAuthor; 1547 if ( pAuthorItem ) 1548 aInfo.Author = pAuthorItem->GetValue(); 1549 else 1550 // if not transferred as a parameter, get it from user settings 1551 aInfo.Author = SvtUserOptions().GetFullName(); 1552 1553 DateTime aTime; 1554 aInfo.TimeStamp.Day = aTime.GetDay(); 1555 aInfo.TimeStamp.Month = aTime.GetMonth(); 1556 aInfo.TimeStamp.Year = aTime.GetYear(); 1557 aInfo.TimeStamp.Hours = aTime.GetHour(); 1558 aInfo.TimeStamp.Minutes = aTime.GetMin(); 1559 aInfo.TimeStamp.Seconds = aTime.GetSec(); 1560 1561 if ( bOk ) 1562 { 1563 // add new version information into the versionlist and save the versionlist 1564 // the version list must have been transferred from the "old" medium before 1565 rMedium.AddVersion_Impl( aInfo ); 1566 rMedium.SaveVersionList_Impl( sal_True ); 1567 bOk = PutURLContentsToVersionStream_Impl( aTmpVersionURL, xMedStorage, aInfo.Identifier ); 1568 } 1569 } 1570 else if ( bOk && ( pImp->bIsSaving || pImp->bPreserveVersions ) ) 1571 { 1572 rMedium.SaveVersionList_Impl( sal_True ); 1573 } 1574 } 1575 1576 if ( aTmpVersionURL.getLength() ) 1577 ::utl::UCBContentHelper::Kill( aTmpVersionURL ); 1578 } 1579 else 1580 { 1581 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing in alien format." ) ) ); 1582 // it's a "SaveAs" in an alien format 1583 if ( rMedium.GetFilter() && ( rMedium.GetFilter()->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) ) 1584 bOk = ExportTo( rMedium ); 1585 else 1586 bOk = ConvertTo( rMedium ); 1587 1588 // after saving the document, the temporary object storage must be updated 1589 // if the old object storage was not a temporary one, it will be updated also, because it will be used 1590 // as a source for copying the objects into the new temporary storage that will be created below 1591 // updating means: all child objects must be stored into it 1592 // ( same as on loading, where these objects are copied to the temporary storage ) 1593 // but don't commit these changes, because in the case when the old object storage is not a temporary one, 1594 // all changes will be written into the original file ! 1595 1596 if( bOk && !bCopyTo ) 1597 // we also don't touch any graphical replacements here 1598 bOk = SaveChildren( sal_True ); 1599 } 1600 1601 if ( bOk ) 1602 { 1603 // if ODF version of oasis format changes on saving the signature should not be preserved 1604 if ( bOk && bTryToPreserveScriptSignature && bNoPreserveForOasis ) 1605 bTryToPreserveScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_60 ); 1606 1607 uno::Reference< security::XDocumentDigitalSignatures > xDDSigns; 1608 if ( bOk && bTryToPreserveScriptSignature ) 1609 { 1610 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Copying scripting signature." ) ) ); 1611 1612 // if the scripting code was not changed and it is signed the signature should be preserved 1613 // unfortunately at this point we have only information whether the basic code has changed or not 1614 // so the only way is to check the signature if the basic was not changed 1615 try 1616 { 1617 // get the ODF version of the new medium 1618 uno::Sequence< uno::Any > aArgs( 1 ); 1619 aArgs[0] <<= ::rtl::OUString(); 1620 try 1621 { 1622 uno::Reference < beans::XPropertySet > xPropSet( rMedium.GetStorage(), uno::UNO_QUERY_THROW ); 1623 aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ); 1624 } 1625 catch( uno::Exception& ) 1626 { 1627 } 1628 1629 xDDSigns = uno::Reference< security::XDocumentDigitalSignatures >( 1630 comphelper::getProcessServiceFactory()->createInstanceWithArguments( 1631 rtl::OUString( 1632 RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), 1633 aArgs ), 1634 uno::UNO_QUERY_THROW ); 1635 1636 ::rtl::OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName(); 1637 1638 if ( aScriptSignName.getLength() ) 1639 { 1640 pMedium->Close(); 1641 1642 // target medium is still not commited, it should not be closed 1643 // commit the package storage and close it, but leave the streams open 1644 rMedium.StorageCommit_Impl(); 1645 rMedium.CloseStorage(); 1646 1647 uno::Reference< embed::XStorage > xReadOrig = pMedium->GetZipStorageToSign_Impl(); 1648 if ( !xReadOrig.is() ) 1649 throw uno::RuntimeException(); 1650 uno::Reference< embed::XStorage > xMetaInf = xReadOrig->openStorageElement( 1651 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), 1652 embed::ElementModes::READ ); 1653 1654 uno::Reference< embed::XStorage > xTarget = rMedium.GetZipStorageToSign_Impl( sal_False ); 1655 if ( !xTarget.is() ) 1656 throw uno::RuntimeException(); 1657 uno::Reference< embed::XStorage > xTargetMetaInf = xTarget->openStorageElement( 1658 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), 1659 embed::ElementModes::READWRITE ); 1660 1661 if ( xMetaInf.is() && xTargetMetaInf.is() ) 1662 { 1663 xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName ); 1664 1665 uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY ); 1666 if ( xTransact.is() ) 1667 xTransact->commit(); 1668 1669 xTargetMetaInf->dispose(); 1670 1671 // now check the copied signature 1672 uno::Sequence< security::DocumentSignatureInformation > aInfos = 1673 xDDSigns->verifyScriptingContentSignatures( xTarget, 1674 uno::Reference< io::XInputStream >() ); 1675 sal_uInt16 nState = ImplCheckSignaturesInformation( aInfos ); 1676 if ( nState == SIGNATURESTATE_SIGNATURES_OK || nState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED 1677 || nState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK) 1678 { 1679 rMedium.SetCachedSignatureState_Impl( nState ); 1680 1681 // commit the ZipStorage from target medium 1682 xTransact.set( xTarget, uno::UNO_QUERY ); 1683 if ( xTransact.is() ) 1684 xTransact->commit(); 1685 } 1686 else 1687 { 1688 // it should not happen, the copies signature is invalid! 1689 // throw the changes away 1690 OSL_ASSERT( "An invalid signature was copied!" ); 1691 } 1692 } 1693 } 1694 } 1695 catch( uno::Exception& ) 1696 { 1697 } 1698 1699 pMedium->Close(); 1700 rMedium.CloseZipStorage_Impl(); 1701 } 1702 1703 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Medium commit." ) ) ); 1704 1705 // transfer data to its destinated location 1706 // the medium commits the storage or the stream it is based on 1707 RegisterTransfer( rMedium ); 1708 bOk = rMedium.Commit(); 1709 1710 if ( bOk ) 1711 { 1712 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing is successful." ) ) ); 1713 1714 // if the target medium is an alien format and the "old" medium was an own format and the "old" medium 1715 // has a name, the object storage must be exchanged, because now we need a new temporary storage 1716 // as object storage 1717 if ( !bCopyTo && bStorageBasedSource && !bStorageBasedTarget ) 1718 { 1719 if ( bStoreToSameLocation ) 1720 { 1721 // if the old medium already disconnected from document storage, the storage still must 1722 // be switched if backup file is used 1723 if ( bNeedsDisconnectionOnFail ) 1724 ConnectTmpStorage_Impl( pImp->m_xDocStorage, NULL ); 1725 } 1726 else if ( pMedium->GetName().Len() 1727 || ( pMedium->HasStorage_Impl() && pMedium->WillDisposeStorageOnClose_Impl() ) ) 1728 { 1729 OSL_ENSURE( pMedium->GetName().Len(), "Fallback is used, the medium without name should not dispose the storage!\n" ); 1730 // copy storage of old medium to new temporary storage and take this over 1731 if( !ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) ) 1732 { 1733 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Process after storing has failed." ) ) ); 1734 bOk = sal_False; 1735 } 1736 } 1737 } 1738 } 1739 else 1740 { 1741 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing has failed." ) ) ); 1742 1743 // in case the document storage was connected to backup temporarely it must be disconnected now 1744 if ( bNeedsDisconnectionOnFail ) 1745 ConnectTmpStorage_Impl( pImp->m_xDocStorage, NULL ); 1746 } 1747 } 1748 1749 // unlock user interface 1750 Lock_Impl( this, sal_False ); 1751 pImp->bForbidReload = bOldStat; 1752 1753 if ( bOk ) 1754 { 1755 try 1756 { 1757 ::ucbhelper::Content aContent( rMedium.GetName(), com::sun::star::uno::Reference < XCommandEnvironment >() ); 1758 com::sun::star::uno::Reference < XPropertySetInfo > xProps = aContent.getProperties(); 1759 if ( xProps.is() ) 1760 { 1761 ::rtl::OUString aAuthor( RTL_CONSTASCII_USTRINGPARAM("Author") ); 1762 ::rtl::OUString aKeywords( RTL_CONSTASCII_USTRINGPARAM("Keywords") ); 1763 ::rtl::OUString aSubject( RTL_CONSTASCII_USTRINGPARAM("Subject") ); 1764 Any aAny; 1765 1766 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( 1767 GetModel(), uno::UNO_QUERY_THROW); 1768 uno::Reference<document::XDocumentProperties> xDocProps 1769 = xDPS->getDocumentProperties(); 1770 1771 if ( xProps->hasPropertyByName( aAuthor ) ) 1772 { 1773 aAny <<= xDocProps->getAuthor(); 1774 aContent.setPropertyValue( aAuthor, aAny ); 1775 } 1776 if ( xProps->hasPropertyByName( aKeywords ) ) 1777 { 1778 aAny <<= ::comphelper::string::convertCommaSeparated( 1779 xDocProps->getKeywords()); 1780 aContent.setPropertyValue( aKeywords, aAny ); 1781 } 1782 if ( xProps->hasPropertyByName( aSubject ) ) 1783 { 1784 aAny <<= xDocProps->getSubject(); 1785 aContent.setPropertyValue( aSubject, aAny ); 1786 } 1787 } 1788 } 1789 catch( Exception& ) 1790 { 1791 } 1792 1793 #ifdef OS2 1794 { 1795 #define CHAR_POINTER(THE_OUSTRING) ::rtl::OUStringToOString (THE_OUSTRING, RTL_TEXTENCODING_UTF8).pData->buffer 1796 // Header for a single-valued ASCII EA data item 1797 typedef struct _EA_ASCII_header { 1798 sal_uInt16 usAttr; /* value: EAT_ASCII */ 1799 sal_uInt16 usLen; /* length of data */ 1800 CHAR szType[_MAX_PATH]; /* ASCII data fits in here ... */ 1801 } EA_ASCII_HEADER; 1802 char filePath[_MAX_PATH]; 1803 char fileExt[_MAX_PATH]; 1804 char docType[_MAX_PATH]; 1805 int rc; 1806 oslFileError eRet; 1807 ::rtl::OUString aSystemFileURL; 1808 const ::rtl::OUString aFileURL = rMedium.GetName(); 1809 // close medium 1810 rMedium.Close(); 1811 1812 // convert file URL to system path 1813 if (osl::FileBase::getSystemPathFromFileURL( aFileURL, aSystemFileURL) == osl::FileBase::E_None) { 1814 EA_ASCII_HEADER eaAscii; 1815 struct _ea eaType; 1816 strcpy( filePath, CHAR_POINTER( aSystemFileURL)); 1817 strcpy( docType, CHAR_POINTER( rMedium.GetFilter()->GetServiceName())); 1818 #if OSL_DEBUG_LEVEL>1 1819 printf( "file name: %s\n", filePath); 1820 printf( "filter name: %s\n", CHAR_POINTER(rMedium.GetFilter()->GetFilterName())); 1821 printf( "service name: %s\n", docType); 1822 #endif 1823 // initialize OS/2 EA data structure 1824 eaAscii.usAttr = EAT_ASCII; 1825 _splitpath ( filePath, NULL, NULL, NULL, fileExt); 1826 if (!stricmp( fileExt, ".pdf")) 1827 strcpy( eaAscii.szType, "Acrobat Document"); 1828 else if (!strcmp( docType, "com.sun.star.text.TextDocument")) 1829 strcpy( eaAscii.szType, "OpenOfficeOrg Writer Document"); 1830 else if (!strcmp( docType, "com.sun.star.sheet.SpreadsheetDocument")) 1831 strcpy( eaAscii.szType, "OpenOfficeOrg Calc Document"); 1832 else if (!strcmp( docType, "com.sun.star.presentation.PresentationDocument")) 1833 strcpy( eaAscii.szType, "OpenOfficeOrg Impress Document"); 1834 else if (!strcmp( docType, "com.sun.star.drawing.DrawingDocument")) 1835 strcpy( eaAscii.szType, "OpenOfficeOrg Draw Document"); 1836 else 1837 strcpy( eaAscii.szType, "OpenOfficeOrg Document"); 1838 eaAscii.usLen = strlen( eaAscii.szType); 1839 // fill libc EA data structure 1840 eaType.flags = 0; 1841 eaType.size = sizeof(sal_uInt16)*2 + eaAscii.usLen; 1842 eaType.value = &eaAscii; 1843 // put EA to file 1844 rc = _ea_put( &eaType, filePath, 0, ".TYPE"); 1845 #if OSL_DEBUG_LEVEL>1 1846 printf( "ea name: %s, rc %d, errno %d\n", eaAscii.szType, rc, errno); 1847 #endif 1848 } 1849 } 1850 #endif 1851 1852 } 1853 1854 return bOk; 1855 } 1856 1857 //------------------------------------------------------------------------ 1858 sal_Bool SfxObjectShell::DisconnectStorage_Impl( SfxMedium& rSrcMedium, SfxMedium& rTargetMedium ) 1859 { 1860 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::DisconnectStorage_Impl" ); 1861 1862 // this method disconnects the storage from source medium, and attaches it to the backup created by the target medium 1863 1864 uno::Reference< embed::XStorage > xStorage = rSrcMedium.GetStorage(); 1865 1866 sal_Bool bResult = sal_False; 1867 if ( xStorage == pImp->m_xDocStorage ) 1868 { 1869 try 1870 { 1871 uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW ); 1872 ::rtl::OUString aBackupURL = rTargetMedium.GetBackup_Impl(); 1873 if ( !aBackupURL.getLength() ) 1874 { 1875 // the backup could not be created, try to disconnect the storage and close the source SfxMedium 1876 // in this case the optimization is not possible, connect storage to a temporary file 1877 rTargetMedium.ResetError(); 1878 xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() ); 1879 rSrcMedium.CanDisposeStorage_Impl( sal_False ); 1880 rSrcMedium.Close(); 1881 1882 // now try to create the backup 1883 rTargetMedium.GetBackup_Impl(); 1884 } 1885 else 1886 { 1887 // the following call will only compare stream sizes 1888 // TODO/LATER: this is a very risky part, since if the URL contents are different from the storage 1889 // contents, the storag will be broken 1890 xOptStorage->attachToURL( aBackupURL, sal_True ); 1891 1892 // the storage is successfuly attached to backup, thus it it owned by the document not by the medium 1893 rSrcMedium.CanDisposeStorage_Impl( sal_False ); 1894 bResult = sal_True; 1895 } 1896 } 1897 catch ( uno::Exception& ) 1898 {} 1899 } 1900 1901 OSL_ENSURE( bResult, "Storage disconnecting has failed - affects performance!" ); 1902 1903 return bResult; 1904 } 1905 1906 //------------------------------------------------------------------------ 1907 1908 sal_Bool SfxObjectShell::ConnectTmpStorage_Impl( 1909 const uno::Reference< embed::XStorage >& xStorage, 1910 SfxMedium* pMediumArg ) 1911 1912 /* [Beschreibung] 1913 1914 Arbeitet die Applikation auf einem temporaeren Storage, 1915 so darf der temporaere Storage nicht aus dem SaveCompleted 1916 genommen werden. Daher wird in diesem Fall schon hier an 1917 den neuen Storage connected. SaveCompleted tut dann nichts. 1918 1919 */ 1920 1921 { 1922 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::ConnectTmpStorage_Impl" ); 1923 1924 sal_Bool bResult = sal_False; 1925 1926 if ( xStorage.is() ) 1927 { 1928 try 1929 { 1930 // the empty argument means that the storage will create temporary stream itself 1931 uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY_THROW ); 1932 xOptStorage->writeAndAttachToStream( uno::Reference< io::XStream >() ); 1933 1934 // the storage is successfuly disconnected from the original sources, thus the medium must not dispose it 1935 if ( pMediumArg ) 1936 pMediumArg->CanDisposeStorage_Impl( sal_False ); 1937 1938 bResult = sal_True; 1939 } 1940 catch( uno::Exception& ) 1941 { 1942 } 1943 1944 // if switching of the storage does not work for any reason ( nonroot storage for example ) use the old method 1945 if ( !bResult ) try 1946 { 1947 uno::Reference< embed::XStorage > xTmpStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 1948 1949 DBG_ASSERT( xTmpStorage.is(), "If a storage can not be created an exception must be thrown!\n" ); 1950 if ( !xTmpStorage.is() ) 1951 throw uno::RuntimeException(); 1952 1953 // TODO/LATER: may be it should be done in SwitchPersistence also 1954 // TODO/LATER: find faster way to copy storage; perhaps sharing with backup?! 1955 xStorage->copyToStorage( xTmpStorage ); 1956 //CopyStoragesOfUnknownMediaType( xStorage, xTmpStorage ); 1957 bResult = SaveCompleted( xTmpStorage ); 1958 1959 if ( bResult ) 1960 { 1961 pImp->pBasicManager->setStorage( xTmpStorage ); 1962 1963 // Get rid of this workaround after issue i113914 is fixed 1964 try 1965 { 1966 uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries( pImp->xBasicLibraries, uno::UNO_QUERY_THROW ); 1967 xBasicLibraries->setRootStorage( xTmpStorage ); 1968 } 1969 catch( uno::Exception& ) 1970 {} 1971 try 1972 { 1973 uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries( pImp->xDialogLibraries, uno::UNO_QUERY_THROW ); 1974 xDialogLibraries->setRootStorage( xTmpStorage ); 1975 } 1976 catch( uno::Exception& ) 1977 {} 1978 } 1979 } 1980 catch( uno::Exception& ) 1981 {} 1982 1983 if ( !bResult ) 1984 { 1985 // TODO/LATER: may need error code setting based on exception 1986 SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 1987 } 1988 } 1989 1990 return bResult; 1991 } 1992 1993 //------------------------------------------------------------------------- 1994 1995 sal_Bool SfxObjectShell::DoSaveObjectAs( SfxMedium& rMedium, sal_Bool bCommit ) 1996 { 1997 sal_Bool bOk = sal_False; 1998 { 1999 ModifyBlocker_Impl aBlock( this ); 2000 2001 uno::Reference < embed::XStorage > xNewStor = rMedium.GetStorage(); 2002 if ( !xNewStor.is() ) 2003 return sal_False; 2004 2005 uno::Reference < beans::XPropertySet > xPropSet( xNewStor, uno::UNO_QUERY ); 2006 if ( xPropSet.is() ) 2007 { 2008 Any a = xPropSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ); 2009 ::rtl::OUString aMediaType; 2010 if ( !(a>>=aMediaType) || !aMediaType.getLength() ) 2011 { 2012 OSL_ENSURE( sal_False, "The mediatype must be set already!\n" ); 2013 SetupStorage( xNewStor, SOFFICE_FILEFORMAT_CURRENT, sal_False ); 2014 } 2015 2016 pImp->bIsSaving = sal_False; 2017 bOk = SaveAsOwnFormat( rMedium ); 2018 2019 if ( bCommit ) 2020 { 2021 try { 2022 uno::Reference< embed::XTransactedObject > xTransact( xNewStor, uno::UNO_QUERY_THROW ); 2023 xTransact->commit(); 2024 } 2025 catch( uno::Exception& ) 2026 { 2027 DBG_ERROR( "The strotage was not commited on DoSaveAs!\n" ); 2028 } 2029 } 2030 } 2031 } 2032 2033 return bOk; 2034 } 2035 2036 //------------------------------------------------------------------------- 2037 // TODO/LATER: may be the call must be removed completelly 2038 sal_Bool SfxObjectShell::DoSaveAs( SfxMedium& rMedium ) 2039 { 2040 // hier kommen nur Root-Storages rein, die via Temp-File gespeichert werden 2041 rMedium.CreateTempFileNoCopy(); 2042 SetError(rMedium.GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2043 if ( GetError() ) 2044 return sal_False; 2045 2046 // copy version list from "old" medium to target medium, so it can be used on saving 2047 if ( pImp->bPreserveVersions ) 2048 rMedium.TransferVersionList_Impl( *pMedium ); 2049 2050 sal_Bool bRet = SaveTo_Impl( rMedium, NULL ); 2051 if ( !bRet ) 2052 SetError(rMedium.GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2053 return bRet; 2054 } 2055 2056 //------------------------------------------------------------------------- 2057 2058 sal_Bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed ) 2059 { 2060 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::DoSaveCompleted" ); 2061 2062 sal_Bool bOk = sal_True; 2063 sal_Bool bMedChanged = pNewMed && pNewMed!=pMedium; 2064 /* sal_Bool bCreatedTempStor = pNewMed && pMedium && 2065 IsPackageStorageFormat_Impl(*pMedium) && 2066 !IsPackageStorageFormat_Impl(*pNewMed) && 2067 pMedium->GetName().Len(); 2068 */ 2069 DBG_ASSERT( !pNewMed || pNewMed->GetError() == ERRCODE_NONE, "DoSaveCompleted: Medium has error!" ); 2070 2071 // delete Medium (and Storage!) after all notifications 2072 SfxMedium* pOld = pMedium; 2073 if ( bMedChanged ) 2074 { 2075 pMedium = pNewMed; 2076 pMedium->CanDisposeStorage_Impl( sal_True ); 2077 } 2078 2079 const SfxFilter *pFilter = pMedium ? pMedium->GetFilter() : 0; 2080 if ( pNewMed ) 2081 { 2082 if( bMedChanged ) 2083 { 2084 if( pNewMed->GetName().Len() ) 2085 bHasName = sal_True; 2086 Broadcast( SfxSimpleHint(SFX_HINT_NAMECHANGED) ); 2087 getDocProperties()->setGenerator( 2088 ::utl::DocInfoHelper::GetGeneratorString() ); 2089 } 2090 2091 uno::Reference< embed::XStorage > xStorage; 2092 if ( !pFilter || IsPackageStorageFormat_Impl( *pMedium ) ) 2093 { 2094 uno::Reference < embed::XStorage > xOld = GetStorage(); 2095 2096 // when the package based medium is broken and has no storage or if the storage 2097 // is the same as the document storage the current document storage should be preserved 2098 xStorage = pMedium->GetStorage(); 2099 bOk = SaveCompleted( xStorage ); 2100 if ( bOk && xStorage.is() && xOld != xStorage 2101 && (!pOld || !pOld->HasStorage_Impl() || xOld != pOld->GetStorage() ) ) 2102 { 2103 // old own storage was not controlled by old Medium -> dispose it 2104 try { 2105 xOld->dispose(); 2106 } catch( uno::Exception& ) 2107 { 2108 // the storage is disposed already 2109 // can happen during reload scenario when the medium has disposed it during the closing 2110 // will be fixed in one of the next milestones 2111 } 2112 } 2113 } 2114 else 2115 { 2116 if( pMedium->GetOpenMode() & STREAM_WRITE ) 2117 pMedium->GetInStream(); 2118 xStorage = GetStorage(); 2119 } 2120 2121 // TODO/LATER: may be this code will be replaced, but not sure 2122 // Set storage in document library containers 2123 pImp->pBasicManager->setStorage( xStorage ); 2124 2125 // Get rid of this workaround after issue i113914 is fixed 2126 try 2127 { 2128 uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries( pImp->xBasicLibraries, uno::UNO_QUERY_THROW ); 2129 xBasicLibraries->setRootStorage( xStorage ); 2130 } 2131 catch( uno::Exception& ) 2132 {} 2133 try 2134 { 2135 uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries( pImp->xDialogLibraries, uno::UNO_QUERY_THROW ); 2136 xDialogLibraries->setRootStorage( xStorage ); 2137 } 2138 catch( uno::Exception& ) 2139 {} 2140 } 2141 else 2142 { 2143 if( pMedium ) 2144 { 2145 if( pFilter && !IsPackageStorageFormat_Impl( *pMedium ) && (pMedium->GetOpenMode() & STREAM_WRITE )) 2146 { 2147 pMedium->ReOpen(); 2148 bOk = SaveCompletedChildren( sal_False ); 2149 } 2150 else 2151 bOk = SaveCompleted( NULL ); 2152 } 2153 // entweder Save oder ConvertTo 2154 else 2155 bOk = SaveCompleted( NULL ); 2156 } 2157 2158 if ( bOk && pNewMed ) 2159 { 2160 if( bMedChanged ) 2161 { 2162 delete pOld; 2163 2164 uno::Reference< frame::XModel > xModel = GetModel(); 2165 if ( xModel.is() ) 2166 { 2167 ::rtl::OUString aURL = pNewMed->GetOrigURL(); 2168 uno::Sequence< beans::PropertyValue > aMediaDescr; 2169 TransformItems( SID_OPENDOC, *pNewMed->GetItemSet(), aMediaDescr ); 2170 try 2171 { 2172 xModel->attachResource( aURL, aMediaDescr ); 2173 } 2174 catch( uno::Exception& ) 2175 {} 2176 } 2177 2178 // before the title regenerated the document must loose the signatures 2179 pImp->nDocumentSignatureState = SIGNATURESTATE_NOSIGNATURES; 2180 pImp->nScriptingSignatureState = pNewMed->GetCachedSignatureState_Impl(); 2181 OSL_ENSURE( pImp->nScriptingSignatureState != SIGNATURESTATE_SIGNATURES_BROKEN, "The signature must not be broken at this place" ); 2182 pImp->bSignatureErrorIsShown = sal_False; 2183 2184 // TODO/LATER: in future the medium must control own signature state, not the document 2185 pNewMed->SetCachedSignatureState_Impl( SIGNATURESTATE_NOSIGNATURES ); // set the default value back 2186 2187 // Titel neu setzen 2188 if ( pNewMed->GetName().Len() && SFX_CREATE_MODE_EMBEDDED != eCreateMode ) 2189 InvalidateName(); 2190 SetModified(sal_False); // nur bei gesetztem Medium zur"ucksetzen 2191 Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) ); 2192 2193 // this is the end of the saving process, it is possible that the file was changed 2194 // between medium commit and this step ( attributes change and so on ) 2195 // so get the file date again 2196 if ( pNewMed->DocNeedsFileDateCheck() ) 2197 pNewMed->GetInitFileDate( sal_True ); 2198 } 2199 } 2200 2201 pMedium->ClearBackup_Impl(); 2202 pMedium->LockOrigFileOnDemand( sal_True, sal_False ); 2203 2204 return bOk; 2205 } 2206 2207 //------------------------------------------------------------------------- 2208 2209 sal_Bool SfxObjectShell::ConvertFrom 2210 ( 2211 SfxMedium& /*rMedium*/ /* <SfxMedium>, welches die Quell-Datei beschreibt 2212 (z.B. Dateiname, <SfxFilter>, Open-Modi etc.) */ 2213 ) 2214 2215 /* [Beschreibung] 2216 2217 Diese Methode wird zum Laden von Dokumenten "uber alle Filter gerufen, 2218 die nicht SFX_FILTER_OWN sind oder f"ur die kein Clipboard-Format 2219 registriert wurde (also kein Storage-Format benutzen). Mit anderen Worten: 2220 mit dieser Methode wird importiert. 2221 2222 Das hier zu "offende File sollte "uber 'rMedium' ge"offnet werden, 2223 um die richtigen Open-Modi zu gew"ahrleisten. Insbesondere wenn das 2224 Format beibehalten wird (nur m"oglich bei SFX_FILTER_SIMULATE oder 2225 SFX_FILTER_ONW) mu\s die Datei STREAM_SHARE_DENYWRITE ge"offnet werden. 2226 2227 2228 [R"uckgabewert] 2229 2230 sal_Bool sal_True 2231 Das Dokument konnte geladen werden. 2232 2233 sal_False 2234 Das Dokument konnte nicht geladen werden, ein 2235 Fehlercode ist mit <SvMedium::GetError()const> zu 2236 erhalten. 2237 2238 2239 [Beispiel] 2240 2241 sal_Bool DocSh::ConvertFrom( SfxMedium &rMedium ) 2242 { 2243 SvStreamRef xStream = rMedium.GetInStream(); 2244 if( xStream.is() ) 2245 { 2246 xStream->SetBufferSize(4096); 2247 *xStream >> ...; 2248 2249 // NICHT 'rMedium.CloseInStream()' rufen! File gelockt halten! 2250 return SVSTREAM_OK == rMedium.GetError(); 2251 } 2252 2253 return sal_False; 2254 } 2255 2256 2257 [Querverweise] 2258 2259 <SfxObjectShell::ConvertTo(SfxMedium&)> 2260 <SFX_FILTER_REGISTRATION> 2261 */ 2262 { 2263 return sal_False; 2264 } 2265 2266 sal_Bool SfxObjectShell::InsertFrom( SfxMedium& rMedium ) 2267 { 2268 ::rtl::OUString aTypeName( rMedium.GetFilter()->GetTypeName() ); 2269 ::rtl::OUString aFilterName( rMedium.GetFilter()->GetFilterName() ); 2270 2271 uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory(); 2272 uno::Reference < lang::XMultiServiceFactory > xFilterFact ( 2273 xMan->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), uno::UNO_QUERY ); 2274 2275 uno::Sequence < beans::PropertyValue > aProps; 2276 uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY ); 2277 if ( xFilters->hasByName( aFilterName ) ) 2278 { 2279 xFilters->getByName( aFilterName ) >>= aProps; 2280 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILTER_NAME, aFilterName ) ); 2281 } 2282 2283 ::rtl::OUString aFilterImplName; 2284 sal_Int32 nFilterProps = aProps.getLength(); 2285 for ( sal_Int32 nFilterProp = 0; nFilterProp<nFilterProps; nFilterProp++ ) 2286 { 2287 const beans::PropertyValue& rFilterProp = aProps[nFilterProp]; 2288 if ( rFilterProp.Name.compareToAscii("FilterService") == COMPARE_EQUAL ) 2289 { 2290 rFilterProp.Value >>= aFilterImplName; 2291 break; 2292 } 2293 } 2294 2295 uno::Reference< document::XFilter > xLoader; 2296 if ( aFilterImplName.getLength() ) 2297 { 2298 try{ 2299 xLoader = uno::Reference< document::XFilter > 2300 ( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY ); 2301 }catch(const uno::Exception&) 2302 { xLoader.clear(); } 2303 } 2304 if ( xLoader.is() ) 2305 { 2306 // #131744#: it happens that xLoader does not support xImporter! 2307 try{ 2308 uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW ); 2309 uno::Reference< document::XImporter > xImporter( xLoader, uno::UNO_QUERY_THROW ); 2310 xImporter->setTargetDocument( xComp ); 2311 2312 uno::Sequence < beans::PropertyValue > lDescriptor; 2313 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, rMedium.GetName() ) ); 2314 TransformItems( SID_OPENDOC, *rMedium.GetItemSet(), lDescriptor ); 2315 2316 com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aArgs ( lDescriptor.getLength() ); 2317 com::sun::star::beans::PropertyValue * pNewValue = aArgs.getArray(); 2318 const com::sun::star::beans::PropertyValue * pOldValue = lDescriptor.getConstArray(); 2319 const OUString sInputStream ( RTL_CONSTASCII_USTRINGPARAM ( "InputStream" ) ); 2320 2321 sal_Bool bHasInputStream = sal_False; 2322 sal_Bool bHasBaseURL = sal_False; 2323 sal_Int32 i; 2324 sal_Int32 nEnd = lDescriptor.getLength(); 2325 2326 for ( i = 0; i < nEnd; i++ ) 2327 { 2328 pNewValue[i] = pOldValue[i]; 2329 if ( pOldValue [i].Name == sInputStream ) 2330 bHasInputStream = sal_True; 2331 else if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "DocumentBaseURL" ) ) ) 2332 bHasBaseURL = sal_True; 2333 } 2334 2335 if ( !bHasInputStream ) 2336 { 2337 aArgs.realloc ( ++nEnd ); 2338 aArgs[nEnd-1].Name = sInputStream; 2339 aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XInputStream > ( new utl::OSeekableInputStreamWrapper ( *rMedium.GetInStream() ) ); 2340 } 2341 2342 if ( !bHasBaseURL ) 2343 { 2344 aArgs.realloc ( ++nEnd ); 2345 aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DocumentBaseURL" ) ); 2346 aArgs[nEnd-1].Value <<= rMedium.GetBaseURL(); 2347 } 2348 2349 aArgs.realloc( ++nEnd ); 2350 aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "InsertMode" ) ); 2351 aArgs[nEnd-1].Value <<= (sal_Bool) sal_True; 2352 2353 return xLoader->filter( aArgs ); 2354 }catch(const uno::Exception&) 2355 {} 2356 } 2357 2358 return sal_False; 2359 } 2360 2361 sal_Bool SfxObjectShell::ImportFrom( SfxMedium& rMedium ) 2362 { 2363 ::rtl::OUString aTypeName( rMedium.GetFilter()->GetTypeName() ); 2364 ::rtl::OUString aFilterName( rMedium.GetFilter()->GetFilterName() ); 2365 2366 uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory(); 2367 uno::Reference < lang::XMultiServiceFactory > xFilterFact ( 2368 xMan->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), uno::UNO_QUERY ); 2369 2370 uno::Sequence < beans::PropertyValue > aProps; 2371 uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY ); 2372 if ( xFilters->hasByName( aFilterName ) ) 2373 { 2374 xFilters->getByName( aFilterName ) >>= aProps; 2375 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILTER_NAME, aFilterName ) ); 2376 } 2377 2378 ::rtl::OUString aFilterImplName; 2379 sal_Int32 nFilterProps = aProps.getLength(); 2380 for ( sal_Int32 nFilterProp = 0; nFilterProp<nFilterProps; nFilterProp++ ) 2381 { 2382 const beans::PropertyValue& rFilterProp = aProps[nFilterProp]; 2383 if ( rFilterProp.Name.compareToAscii("FilterService") == COMPARE_EQUAL ) 2384 { 2385 rFilterProp.Value >>= aFilterImplName; 2386 break; 2387 } 2388 } 2389 2390 uno::Reference< document::XFilter > xLoader; 2391 if ( aFilterImplName.getLength() ) 2392 { 2393 try{ 2394 xLoader = uno::Reference< document::XFilter > 2395 ( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY ); 2396 }catch(const uno::Exception&) 2397 { xLoader.clear(); } 2398 } 2399 if ( xLoader.is() ) 2400 { 2401 // #131744#: it happens that xLoader does not support xImporter! 2402 try{ 2403 uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW ); 2404 uno::Reference< document::XImporter > xImporter( xLoader, uno::UNO_QUERY_THROW ); 2405 xImporter->setTargetDocument( xComp ); 2406 2407 uno::Sequence < beans::PropertyValue > lDescriptor; 2408 rMedium.GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, rMedium.GetName() ) ); 2409 TransformItems( SID_OPENDOC, *rMedium.GetItemSet(), lDescriptor ); 2410 2411 com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aArgs ( lDescriptor.getLength() ); 2412 com::sun::star::beans::PropertyValue * pNewValue = aArgs.getArray(); 2413 const com::sun::star::beans::PropertyValue * pOldValue = lDescriptor.getConstArray(); 2414 const OUString sInputStream ( RTL_CONSTASCII_USTRINGPARAM ( "InputStream" ) ); 2415 2416 sal_Bool bHasInputStream = sal_False; 2417 sal_Bool bHasBaseURL = sal_False; 2418 sal_Int32 i; 2419 sal_Int32 nEnd = lDescriptor.getLength(); 2420 2421 for ( i = 0; i < nEnd; i++ ) 2422 { 2423 pNewValue[i] = pOldValue[i]; 2424 if ( pOldValue [i].Name == sInputStream ) 2425 bHasInputStream = sal_True; 2426 else if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "DocumentBaseURL" ) ) ) 2427 bHasBaseURL = sal_True; 2428 } 2429 2430 if ( !bHasInputStream ) 2431 { 2432 aArgs.realloc ( ++nEnd ); 2433 aArgs[nEnd-1].Name = sInputStream; 2434 aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XInputStream > ( new utl::OSeekableInputStreamWrapper ( *rMedium.GetInStream() ) ); 2435 } 2436 2437 if ( !bHasBaseURL ) 2438 { 2439 aArgs.realloc ( ++nEnd ); 2440 aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DocumentBaseURL" ) ); 2441 aArgs[nEnd-1].Value <<= rMedium.GetBaseURL(); 2442 } 2443 2444 return xLoader->filter( aArgs ); 2445 }catch(const uno::Exception&) 2446 {} 2447 } 2448 2449 return sal_False; 2450 } 2451 2452 sal_Bool SfxObjectShell::ExportTo( SfxMedium& rMedium ) 2453 { 2454 ::rtl::OUString aTypeName( rMedium.GetFilter()->GetTypeName() ); 2455 ::rtl::OUString aFilterName( rMedium.GetFilter()->GetFilterName() ); 2456 uno::Reference< document::XExporter > xExporter; 2457 2458 { 2459 uno::Reference< lang::XMultiServiceFactory > xMan = ::comphelper::getProcessServiceFactory(); 2460 uno::Reference < lang::XMultiServiceFactory > xFilterFact ( 2461 xMan->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), uno::UNO_QUERY ); 2462 2463 uno::Sequence < beans::PropertyValue > aProps; 2464 uno::Reference < container::XNameAccess > xFilters ( xFilterFact, uno::UNO_QUERY ); 2465 if ( xFilters->hasByName( aFilterName ) ) 2466 xFilters->getByName( aFilterName ) >>= aProps; 2467 2468 ::rtl::OUString aFilterImplName; 2469 sal_Int32 nFilterProps = aProps.getLength(); 2470 for ( sal_Int32 nFilterProp = 0; nFilterProp<nFilterProps; nFilterProp++ ) 2471 { 2472 const beans::PropertyValue& rFilterProp = aProps[nFilterProp]; 2473 if ( rFilterProp.Name.compareToAscii("FilterService") == COMPARE_EQUAL ) 2474 { 2475 rFilterProp.Value >>= aFilterImplName; 2476 break; 2477 } 2478 } 2479 2480 if ( aFilterImplName.getLength() ) 2481 { 2482 try{ 2483 xExporter = uno::Reference< document::XExporter > 2484 ( xFilterFact->createInstanceWithArguments( aFilterName, uno::Sequence < uno::Any >() ), uno::UNO_QUERY ); 2485 }catch(const uno::Exception&) 2486 { xExporter.clear(); } 2487 } 2488 } 2489 2490 if ( xExporter.is() ) 2491 { 2492 try{ 2493 uno::Reference< lang::XComponent > xComp( GetModel(), uno::UNO_QUERY_THROW ); 2494 uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY_THROW ); 2495 xExporter->setSourceDocument( xComp ); 2496 2497 com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aOldArgs; 2498 SfxItemSet* pItems = rMedium.GetItemSet(); 2499 TransformItems( SID_SAVEASDOC, *pItems, aOldArgs ); 2500 2501 const com::sun::star::beans::PropertyValue * pOldValue = aOldArgs.getConstArray(); 2502 com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > aArgs ( aOldArgs.getLength() ); 2503 com::sun::star::beans::PropertyValue * pNewValue = aArgs.getArray(); 2504 2505 // put in the REAL file name, and copy all PropertyValues 2506 const OUString sOutputStream ( RTL_CONSTASCII_USTRINGPARAM ( "OutputStream" ) ); 2507 const OUString sStream ( RTL_CONSTASCII_USTRINGPARAM ( "StreamForOutput" ) ); 2508 sal_Bool bHasOutputStream = sal_False; 2509 sal_Bool bHasStream = sal_False; 2510 sal_Bool bHasBaseURL = sal_False; 2511 sal_Int32 i; 2512 sal_Int32 nEnd = aOldArgs.getLength(); 2513 2514 for ( i = 0; i < nEnd; i++ ) 2515 { 2516 pNewValue[i] = pOldValue[i]; 2517 if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "FileName" ) ) ) 2518 pNewValue[i].Value <<= OUString ( rMedium.GetName() ); 2519 else if ( pOldValue[i].Name == sOutputStream ) 2520 bHasOutputStream = sal_True; 2521 else if ( pOldValue[i].Name == sStream ) 2522 bHasStream = sal_True; 2523 else if ( pOldValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "DocumentBaseURL" ) ) ) 2524 bHasBaseURL = sal_True; 2525 } 2526 2527 if ( !bHasOutputStream ) 2528 { 2529 aArgs.realloc ( ++nEnd ); 2530 aArgs[nEnd-1].Name = sOutputStream; 2531 aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > ( new utl::OOutputStreamWrapper ( *rMedium.GetOutStream() ) ); 2532 } 2533 2534 // add stream as well, for OOX export and maybe others 2535 if ( !bHasStream ) 2536 { 2537 aArgs.realloc ( ++nEnd ); 2538 aArgs[nEnd-1].Name = sStream; 2539 aArgs[nEnd-1].Value <<= com::sun::star::uno::Reference < com::sun::star::io::XStream > ( new utl::OStreamWrapper ( *rMedium.GetOutStream() ) ); 2540 } 2541 2542 if ( !bHasBaseURL ) 2543 { 2544 aArgs.realloc ( ++nEnd ); 2545 aArgs[nEnd-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DocumentBaseURL" ) ); 2546 aArgs[nEnd-1].Value <<= rMedium.GetBaseURL( sal_True ); 2547 } 2548 2549 return xFilter->filter( aArgs ); 2550 }catch(const uno::Exception&) 2551 {} 2552 } 2553 2554 return sal_False; 2555 } 2556 2557 //------------------------------------------------------------------------- 2558 2559 sal_Bool SfxObjectShell::ConvertTo 2560 ( 2561 SfxMedium& /*rMedium*/ /* <SfxMedium>, welches die Ziel-Datei beschreibt 2562 (z.B. Dateiname, <SfxFilter>, Open-Modi etc.) */ 2563 ) 2564 2565 /* [Beschreibung] 2566 2567 Diese Methode wird zum Speichern von Dokumenten "uber alle Filter gerufen, 2568 die nicht SFX_FILTER_OWN sind oder f"ur die kein Clipboard-Format 2569 registriert wurde (also kein Storage-Format benutzen). Mit anderen Worten: 2570 mit dieser Methode wird exportiert. 2571 2572 Das hier zu "offende File sollte "uber 'rMedium' ge"offnet werden, 2573 um die richtigen Open-Modi zu gew"ahrleisten. Insbesondere wenn das 2574 Format beibehalten wird (nur m"oglich bei SFX_FILTER_SIMULATE oder 2575 SFX_FILTER_ONW) mu\s die Datei auch nach dem Speichern im Modus 2576 STREAM_SHARE_DENYWRITE ge"offnet bleiben. 2577 2578 2579 [R"uckgabewert] 2580 2581 sal_Bool sal_True 2582 Das Dokument konnte gespeichert werden. 2583 2584 sal_False 2585 Das Dokument konnte nicht gespeichert werden, ein 2586 Fehlercode ist mit <SvMedium::GetError()const> zu 2587 erhalten. 2588 2589 2590 [Beispiel] 2591 2592 sal_Bool DocSh::ConvertTo( SfxMedium &rMedium ) 2593 { 2594 SvStreamRef xStream = rMedium.GetOutStream(); 2595 if ( xStream.is() ) 2596 { 2597 xStream->SetBufferSize(4096); 2598 *xStream << ...; 2599 2600 rMedium.CloseOutStream(); // "offnet automatisch wieder den InStream 2601 return SVSTREAM_OK == rMedium.GetError(); 2602 } 2603 return sal_False ; 2604 } 2605 2606 2607 [Querverweise] 2608 2609 <SfxObjectShell::ConvertFrom(SfxMedium&)> 2610 <SFX_FILTER_REGISTRATION> 2611 */ 2612 2613 { 2614 return sal_False; 2615 } 2616 2617 //------------------------------------------------------------------------- 2618 2619 sal_Bool SfxObjectShell::DoSave_Impl( const SfxItemSet* pArgs ) 2620 { 2621 SfxMedium* pRetrMedium = GetMedium(); 2622 const SfxFilter* pFilter = pRetrMedium->GetFilter(); 2623 2624 // copy the original itemset, but remove the "version" item, because pMediumTmp 2625 // is a new medium "from scratch", so no version should be stored into it 2626 SfxItemSet* pSet = new SfxAllItemSet(*pRetrMedium->GetItemSet()); 2627 pSet->ClearItem( SID_VERSION ); 2628 pSet->ClearItem( SID_DOC_BASEURL ); 2629 2630 // create a medium as a copy; this medium is only for writingm, because it uses the same name as the original one 2631 // writing is done through a copy, that will be transferred to the target ( of course after calling HandsOff ) 2632 SfxMedium* pMediumTmp = new SfxMedium( pRetrMedium->GetName(), pRetrMedium->GetOpenMode(), pRetrMedium->IsDirect(), pFilter, pSet ); 2633 pMediumTmp->SetLongName( pRetrMedium->GetLongName() ); 2634 // pMediumTmp->CreateTempFileNoCopy(); 2635 if ( pMediumTmp->GetErrorCode() != ERRCODE_NONE ) 2636 { 2637 SetError( pMediumTmp->GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2638 delete pMediumTmp; 2639 return sal_False; 2640 } 2641 2642 // copy version list from "old" medium to target medium, so it can be used on saving 2643 pMediumTmp->TransferVersionList_Impl( *pRetrMedium ); 2644 /* 2645 if ( pFilter && ( pFilter->GetFilterFlags() & SFX_FILTER_PACKED ) ) 2646 SetError( GetMedium()->Unpack_Impl( pRetrMedium->GetPhysicalName() ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2647 */ 2648 2649 // an interaction handler here can aquire only in case of GUI Saving 2650 // and should be removed after the saving is done 2651 com::sun::star::uno::Reference< XInteractionHandler > xInteract; 2652 SFX_ITEMSET_ARG( pArgs, pxInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False ); 2653 if ( pxInteractionItem && ( pxInteractionItem->GetValue() >>= xInteract ) && xInteract.is() ) 2654 pMediumTmp->GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER, makeAny( xInteract ) ) ); 2655 2656 sal_Bool bSaved = sal_False; 2657 if( !GetError() && SaveTo_Impl( *pMediumTmp, pArgs ) ) 2658 { 2659 bSaved = sal_True; 2660 2661 if( pMediumTmp->GetItemSet() ) 2662 { 2663 pMediumTmp->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER ); 2664 pMediumTmp->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL ); 2665 } 2666 2667 SetError(pMediumTmp->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2668 2669 sal_Bool bOpen( sal_False ); 2670 bOpen = DoSaveCompleted( pMediumTmp ); 2671 DBG_ASSERT(bOpen,"Fehlerbehandlung fuer DoSaveCompleted nicht implementiert"); 2672 } 2673 else 2674 { 2675 // transfer error code from medium to objectshell 2676 SetError( pMediumTmp->GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2677 2678 // reconnect to object storage 2679 DoSaveCompleted( 0 ); 2680 2681 if( pRetrMedium->GetItemSet() ) 2682 { 2683 pRetrMedium->GetItemSet()->ClearItem( SID_INTERACTIONHANDLER ); 2684 pRetrMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL ); 2685 } 2686 2687 delete pMediumTmp; 2688 } 2689 2690 SetModified( !bSaved ); 2691 return bSaved; 2692 } 2693 2694 //------------------------------------------------------------------------- 2695 2696 sal_Bool SfxObjectShell::Save_Impl( const SfxItemSet* pSet ) 2697 { 2698 if ( IsReadOnly() ) 2699 { 2700 SetError( ERRCODE_SFX_DOCUMENTREADONLY, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2701 return sal_False; 2702 } 2703 2704 DBG_CHKTHIS(SfxObjectShell, 0); 2705 2706 pImp->bIsSaving = sal_True; 2707 sal_Bool bSaved = sal_False; 2708 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False); 2709 if ( pSalvageItem ) 2710 { 2711 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False); 2712 String aFilterName; 2713 const SfxFilter *pFilter = NULL; 2714 if ( pFilterItem ) 2715 pFilter = SfxFilterMatcher( String::CreateFromAscii( GetFactory().GetShortName()) ).GetFilter4FilterName( aFilterName ); 2716 2717 SfxMedium *pMed = new SfxMedium( 2718 pSalvageItem->GetValue(), STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC, sal_False, pFilter ); 2719 2720 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False ); 2721 if ( pPasswordItem ) 2722 pMed->GetItemSet()->Put( *pPasswordItem ); 2723 2724 bSaved = DoSaveAs( *pMed ); 2725 if ( bSaved ) 2726 bSaved = DoSaveCompleted( pMed ); 2727 else 2728 delete pMed; 2729 } 2730 else 2731 bSaved = DoSave_Impl( pSet ); 2732 return bSaved; 2733 } 2734 2735 //------------------------------------------------------------------------- 2736 2737 sal_Bool SfxObjectShell::CommonSaveAs_Impl 2738 ( 2739 const INetURLObject& aURL, 2740 const String& aFilterName, 2741 SfxItemSet* aParams 2742 ) 2743 { 2744 if( aURL.HasError() ) 2745 { 2746 SetError( ERRCODE_IO_INVALIDPARAMETER, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2747 return sal_False; 2748 } 2749 2750 if ( aURL != INetURLObject( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ) ) ) 2751 { 2752 // gibt es schon ein Doc mit dem Namen? 2753 SfxObjectShell* pDoc = 0; 2754 for ( SfxObjectShell* pTmp = SfxObjectShell::GetFirst(); 2755 pTmp && !pDoc; 2756 pTmp = SfxObjectShell::GetNext(*pTmp) ) 2757 { 2758 if( ( pTmp != this ) && pTmp->GetMedium() ) 2759 { 2760 INetURLObject aCompare( pTmp->GetMedium()->GetName() ); 2761 if ( aCompare == aURL ) 2762 pDoc = pTmp; 2763 } 2764 } 2765 if ( pDoc ) 2766 { 2767 // dann Fehlermeldeung: "schon offen" 2768 SetError(ERRCODE_SFX_ALREADYOPEN, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 2769 return sal_False; 2770 } 2771 } 2772 2773 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" ); 2774 DBG_ASSERT( aParams->Count() != 0, "fehlerhafte Parameter"); 2775 2776 SFX_ITEMSET_ARG( aParams, pSaveToItem, SfxBoolItem, SID_SAVETO, sal_False ); 2777 sal_Bool bSaveTo = pSaveToItem ? pSaveToItem->GetValue() : sal_False; 2778 2779 const SfxFilter* pFilter = GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ); 2780 if ( !pFilter 2781 || !pFilter->CanExport() 2782 || (!bSaveTo && !pFilter->CanImport()) ) 2783 { 2784 SetError( ERRCODE_IO_INVALIDPARAMETER, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2785 return sal_False; 2786 } 2787 2788 SFX_ITEMSET_ARG( aParams, pCopyStreamItem, SfxBoolItem, SID_COPY_STREAM_IF_POSSIBLE, sal_False ); 2789 if ( bSaveTo && pCopyStreamItem && pCopyStreamItem->GetValue() && !IsModified() ) 2790 { 2791 if ( pMedium->TryDirectTransfer( aURL.GetMainURL( INetURLObject::NO_DECODE ), *aParams ) ) 2792 return sal_True; 2793 } 2794 aParams->ClearItem( SID_COPY_STREAM_IF_POSSIBLE ); 2795 2796 pImp->bPasswd = aParams && SFX_ITEM_SET == aParams->GetItemState(SID_PASSWORD); 2797 2798 SfxMedium *pActMed = GetMedium(); 2799 const INetURLObject aActName(pActMed->GetName()); 2800 2801 sal_Bool bWasReadonly = IsReadOnly(); 2802 2803 if ( aURL == aActName && aURL != INetURLObject( OUString::createFromAscii( "private:stream" ) ) 2804 && IsReadOnly() ) 2805 { 2806 SetError(ERRCODE_SFX_DOCUMENTREADONLY, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )); 2807 return sal_False; 2808 } 2809 2810 // this notification should be already sent by caller in sfxbasemodel 2811 // SFX_APP()->NotifyEvent(SfxEventHint( bSaveTo? SFX_EVENT_SAVETODOC : SFX_EVENT_SAVEASDOC,this)); 2812 2813 if( SFX_ITEM_SET != aParams->GetItemState(SID_UNPACK) && SvtSaveOptions().IsSaveUnpacked() ) 2814 aParams->Put( SfxBoolItem( SID_UNPACK, sal_False ) ); 2815 2816 ::rtl::OUString aTempFileURL; 2817 if ( IsDocShared() ) 2818 aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ); 2819 2820 if ( PreDoSaveAs_Impl(aURL.GetMainURL( INetURLObject::NO_DECODE ),aFilterName,aParams)) 2821 { 2822 pImp->bWaitingForPicklist = sal_True; 2823 2824 // Daten am Medium updaten 2825 SfxItemSet *pSet = GetMedium()->GetItemSet(); 2826 pSet->ClearItem( SID_INTERACTIONHANDLER ); 2827 pSet->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL ); 2828 pSet->ClearItem( SID_STANDARD_DIR ); 2829 pSet->ClearItem( SID_PATH ); 2830 2831 if ( !bSaveTo ) 2832 { 2833 pSet->ClearItem( SID_REFERER ); 2834 pSet->ClearItem( SID_POSTDATA ); 2835 pSet->ClearItem( SID_TEMPLATE ); 2836 pSet->ClearItem( SID_DOC_READONLY ); 2837 pSet->ClearItem( SID_CONTENTTYPE ); 2838 pSet->ClearItem( SID_CHARSET ); 2839 pSet->ClearItem( SID_FILTER_NAME ); 2840 pSet->ClearItem( SID_OPTIONS ); 2841 //pSet->ClearItem( SID_FILE_FILTEROPTIONS ); 2842 pSet->ClearItem( SID_VERSION ); 2843 pSet->ClearItem( SID_EDITDOC ); 2844 pSet->ClearItem( SID_OVERWRITE ); 2845 pSet->ClearItem( SID_DEFAULTFILEPATH ); 2846 pSet->ClearItem( SID_DEFAULTFILENAME ); 2847 2848 SFX_ITEMSET_GET( (*aParams), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False ); 2849 if ( pFilterItem ) 2850 pSet->Put( *pFilterItem ); 2851 2852 SFX_ITEMSET_GET( (*aParams), pOptionsItem, SfxStringItem, SID_OPTIONS, sal_False ); 2853 if ( pOptionsItem ) 2854 pSet->Put( *pOptionsItem ); 2855 2856 SFX_ITEMSET_GET( (*aParams), pFilterOptItem, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False ); 2857 if ( pFilterOptItem ) 2858 pSet->Put( *pFilterOptItem ); 2859 2860 if ( IsDocShared() && aTempFileURL.getLength() ) 2861 { 2862 // this is a shared document that has to be disconnected from the old location 2863 FreeSharedFile( aTempFileURL ); 2864 2865 if ( pFilter->IsOwnFormat() 2866 && pFilter->UsesStorage() 2867 && pFilter->GetVersion() >= SOFFICE_FILEFORMAT_60 ) 2868 { 2869 // the target format is the own format 2870 // the target document must be shared 2871 SwitchToShared( sal_True, sal_False ); 2872 } 2873 } 2874 } 2875 2876 if ( bWasReadonly && !bSaveTo ) 2877 Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) ); 2878 2879 return sal_True; 2880 } 2881 else 2882 return sal_False; 2883 } 2884 2885 //------------------------------------------------------------------------- 2886 2887 sal_Bool SfxObjectShell::PreDoSaveAs_Impl 2888 ( 2889 const String& rFileName, 2890 const String& aFilterName, 2891 SfxItemSet* pParams 2892 ) 2893 { 2894 // copy all items stored in the itemset of the current medium 2895 SfxAllItemSet* pMergedParams = new SfxAllItemSet( *pMedium->GetItemSet() ); 2896 2897 // in "SaveAs" title and password will be cleared ( maybe the new itemset contains new values, otherwise they will be empty ) 2898 pMergedParams->ClearItem( SID_PASSWORD ); 2899 pMergedParams->ClearItem( SID_DOCINFO_TITLE ); 2900 2901 pMergedParams->ClearItem( SID_INPUTSTREAM ); 2902 pMergedParams->ClearItem( SID_STREAM ); 2903 pMergedParams->ClearItem( SID_CONTENT ); 2904 pMergedParams->ClearItem( SID_DOC_READONLY ); 2905 pMergedParams->ClearItem( SID_DOC_BASEURL ); 2906 2907 pMergedParams->ClearItem( SID_REPAIRPACKAGE ); 2908 2909 // "SaveAs" will never store any version information - it's a complete new file ! 2910 pMergedParams->ClearItem( SID_VERSION ); 2911 2912 // merge the new parameters into the copy 2913 // all values present in both itemsets will be overwritten by the new parameters 2914 if( pParams ) 2915 pMergedParams->Put( *pParams ); 2916 //DELETEZ( pParams ); 2917 2918 #ifdef DBG_UTIL 2919 if ( pMergedParams->GetItemState( SID_DOC_SALVAGE) >= SFX_ITEM_SET ) 2920 DBG_ERROR("Salvage item present in Itemset, check the parameters!"); 2921 #endif 2922 2923 // should be unneccessary - too hot to handle! 2924 pMergedParams->ClearItem( SID_DOC_SALVAGE ); 2925 2926 // take over the new merged itemset 2927 pParams = pMergedParams; 2928 2929 // create a medium for the target URL 2930 SfxMedium *pNewFile = new SfxMedium( rFileName, STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC, sal_False, 0, pParams ); 2931 2932 // set filter; if no filter is given, take the default filter of the factory 2933 if ( aFilterName.Len() ) 2934 pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) ); 2935 else 2936 pNewFile->SetFilter( GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_IMPORT | SFX_FILTER_EXPORT ) ); 2937 2938 if ( pNewFile->GetErrorCode() != ERRCODE_NONE ) 2939 { 2940 // creating temporary file failed ( f.e. floppy disk not inserted! ) 2941 SetError( pNewFile->GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2942 delete pNewFile; 2943 return sal_False; 2944 } 2945 2946 // check if a "SaveTo" is wanted, no "SaveAs" 2947 SFX_ITEMSET_ARG( pParams, pSaveToItem, SfxBoolItem, SID_SAVETO, sal_False ); 2948 sal_Bool bCopyTo = GetCreateMode() == SFX_CREATE_MODE_EMBEDDED || (pSaveToItem && pSaveToItem->GetValue()); 2949 2950 // distinguish between "Save" and "SaveAs" 2951 pImp->bIsSaving = sal_False; 2952 2953 // copy version list from "old" medium to target medium, so it can be used on saving 2954 if ( pImp->bPreserveVersions ) 2955 pNewFile->TransferVersionList_Impl( *pMedium ); 2956 2957 /* 2958 if ( GetMedium()->GetFilter() && ( GetMedium()->GetFilter()->GetFilterFlags() & SFX_FILTER_PACKED ) ) 2959 { 2960 SfxMedium *pMed = bCopyTo ? pMedium : pNewFile; 2961 pNewFile->SetError( GetMedium()->Unpack_Impl( pMed->GetPhysicalName() ) , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2962 } 2963 */ 2964 // Save the document ( first as temporary file, then transfer to the target URL by committing the medium ) 2965 sal_Bool bOk = sal_False; 2966 if ( !pNewFile->GetErrorCode() && SaveTo_Impl( *pNewFile, NULL ) ) 2967 { 2968 bOk = sal_True; 2969 2970 // transfer a possible error from the medium to the document 2971 SetError( pNewFile->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2972 2973 // notify the document that saving was done successfully 2974 if ( !bCopyTo ) 2975 { 2976 bOk = DoSaveCompleted( pNewFile ); 2977 } 2978 else 2979 bOk = DoSaveCompleted(0); 2980 2981 if( bOk ) 2982 { 2983 if( !bCopyTo ) 2984 SetModified( sal_False ); 2985 } 2986 else 2987 { 2988 // TODO/LATER: the code below must be dead since the storage commit makes all the stuff 2989 // and the DoSaveCompleted call should not be able to fail in general 2990 2991 DBG_ASSERT( !bCopyTo, "Error while reconnecting to medium, can't be handled!"); 2992 SetError( pNewFile->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 2993 2994 if ( !bCopyTo ) 2995 { 2996 // reconnect to the old medium 2997 sal_Bool bRet( sal_False ); 2998 bRet = DoSaveCompleted( pMedium ); 2999 DBG_ASSERT( bRet, "Error in DoSaveCompleted, can't be handled!"); 3000 } 3001 3002 // TODO/LATER: disconnect the new file from the storage for the case when pure saving is done 3003 // if storing has corrupted the file, probably it must be restored either here or 3004 // by the storage 3005 DELETEZ( pNewFile ); 3006 } 3007 } 3008 else 3009 { 3010 SetError( pNewFile->GetErrorCode(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 3011 3012 // reconnect to the old storage 3013 DoSaveCompleted( 0 ); 3014 3015 DELETEZ( pNewFile ); 3016 } 3017 3018 if ( bCopyTo ) 3019 DELETEZ( pNewFile ); 3020 else if( !bOk ) 3021 SetModified( sal_True ); 3022 3023 return bOk; 3024 } 3025 3026 //------------------------------------------------------------------------ 3027 3028 sal_Bool SfxObjectShell::LoadFrom( SfxMedium& /*rMedium*/ ) 3029 { 3030 DBG_ERROR( "Base implementation, must not be called in general!" ); 3031 return sal_True; 3032 } 3033 3034 //------------------------------------------------------------------------- 3035 sal_Bool SfxObjectShell::IsInformationLost() 3036 { 3037 Sequence< PropertyValue > aProps = GetModel()->getArgs(); 3038 ::rtl::OUString aFilterName; 3039 ::rtl::OUString aPreusedFilterName; 3040 for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ ) 3041 { 3042 if ( aProps[nInd].Name.equalsAscii( "FilterName" ) ) 3043 aProps[nInd].Value >>= aFilterName; 3044 else if ( aProps[nInd].Name.equalsAscii( "PreusedFilterName" ) ) 3045 aProps[nInd].Value >>= aPreusedFilterName; 3046 } 3047 3048 // if current filter can lead to information loss and it was used 3049 // for the latest store then the user should be asked to store in own format 3050 if ( aFilterName.getLength() && aFilterName.equals( aPreusedFilterName ) ) 3051 { 3052 const SfxFilter *pFilt = GetMedium()->GetFilter(); 3053 DBG_ASSERT( pFilt && aFilterName.equals( pFilt->GetName() ), "MediaDescriptor contains wrong filter!\n" ); 3054 return ( pFilt && pFilt->IsAlienFormat() ); 3055 } 3056 3057 return sal_False; 3058 } 3059 3060 //------------------------------------------------------------------------- 3061 sal_Bool SfxObjectShell::CanReload_Impl() 3062 3063 /* [Beschreibung] 3064 3065 Interne Methode zum Feststellen, ob eine erneutes Laden des 3066 Dokuments (auch als RevertToSaved oder LastVersion bekannt) 3067 m"oglich ist. 3068 */ 3069 3070 { 3071 return pMedium && HasName() && !IsInModalMode() && !pImp->bForbidReload; 3072 } 3073 3074 //------------------------------------------------------------------------- 3075 3076 sal_uInt16 SfxObjectShell::GetHiddenInformationState( sal_uInt16 nStates ) 3077 { 3078 sal_uInt16 nState = 0; 3079 if ( nStates & HIDDENINFORMATION_DOCUMENTVERSIONS ) 3080 { 3081 if ( GetMedium()->GetVersionList().getLength() ) 3082 nState |= HIDDENINFORMATION_DOCUMENTVERSIONS; 3083 } 3084 3085 return nState; 3086 } 3087 3088 sal_Int16 SfxObjectShell::QueryHiddenInformation( HiddenWarningFact eFact, Window* pParent ) 3089 { 3090 sal_Int16 nRet = RET_YES; 3091 sal_uInt16 nResId = 0; 3092 SvtSecurityOptions::EOption eOption = static_cast< SvtSecurityOptions::EOption >( -1 ); 3093 3094 switch ( eFact ) 3095 { 3096 case WhenSaving : 3097 { 3098 nResId = STR_HIDDENINFO_CONTINUE_SAVING; 3099 eOption = SvtSecurityOptions::E_DOCWARN_SAVEORSEND; 3100 break; 3101 } 3102 case WhenPrinting : 3103 { 3104 nResId = STR_HIDDENINFO_CONTINUE_PRINTING; 3105 eOption = SvtSecurityOptions::E_DOCWARN_PRINT; 3106 break; 3107 } 3108 case WhenSigning : 3109 { 3110 nResId = STR_HIDDENINFO_CONTINUE_SIGNING; 3111 eOption = SvtSecurityOptions::E_DOCWARN_SIGNING; 3112 break; 3113 } 3114 case WhenCreatingPDF : 3115 { 3116 nResId = STR_HIDDENINFO_CONTINUE_CREATEPDF; 3117 eOption = SvtSecurityOptions::E_DOCWARN_CREATEPDF; 3118 break; 3119 } 3120 default: 3121 { 3122 DBG_ERRORFILE( "SfxObjectShell::DetectHiddenInformation(): what fact?" ); 3123 } 3124 } 3125 3126 if ( eOption != -1 && SvtSecurityOptions().IsOptionSet( eOption ) ) 3127 { 3128 String sMessage( SfxResId( STR_HIDDENINFO_CONTAINS ) ); 3129 sal_uInt16 nWantedStates = HIDDENINFORMATION_RECORDEDCHANGES | HIDDENINFORMATION_NOTES; 3130 if ( eFact != WhenPrinting ) 3131 nWantedStates |= HIDDENINFORMATION_DOCUMENTVERSIONS; 3132 sal_uInt16 nStates = GetHiddenInformationState( nWantedStates ); 3133 bool bWarning = false; 3134 3135 if ( ( nStates & HIDDENINFORMATION_RECORDEDCHANGES ) == HIDDENINFORMATION_RECORDEDCHANGES ) 3136 { 3137 sMessage += String( SfxResId( STR_HIDDENINFO_RECORDCHANGES ) ); 3138 sMessage += '\n'; 3139 bWarning = true; 3140 } 3141 if ( ( nStates & HIDDENINFORMATION_NOTES ) == HIDDENINFORMATION_NOTES ) 3142 { 3143 sMessage += String( SfxResId( STR_HIDDENINFO_NOTES ) ); 3144 sMessage += '\n'; 3145 bWarning = true; 3146 } 3147 if ( ( nStates & HIDDENINFORMATION_DOCUMENTVERSIONS ) == HIDDENINFORMATION_DOCUMENTVERSIONS ) 3148 { 3149 sMessage += String( SfxResId( STR_HIDDENINFO_DOCVERSIONS ) ); 3150 sMessage += '\n'; 3151 bWarning = true; 3152 } 3153 3154 if ( bWarning ) 3155 { 3156 sMessage += '\n'; 3157 sMessage += String( SfxResId( nResId ) ); 3158 WarningBox aWBox( pParent, WB_YES_NO | WB_DEF_NO, sMessage ); 3159 nRet = aWBox.Execute(); 3160 } 3161 } 3162 3163 return nRet; 3164 } 3165 3166 sal_Bool SfxObjectShell::HasSecurityOptOpenReadOnly() const 3167 { 3168 return sal_True; 3169 } 3170 3171 sal_Bool SfxObjectShell::IsSecurityOptOpenReadOnly() const 3172 { 3173 return IsLoadReadonly(); 3174 } 3175 3176 void SfxObjectShell::SetSecurityOptOpenReadOnly( sal_Bool _b ) 3177 { 3178 SetLoadReadonly( _b ); 3179 } 3180 3181 sal_Bool SfxObjectShell::LoadOwnFormat( SfxMedium& rMedium ) 3182 { 3183 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE SfxObjectShell::LoadOwnFormat" ); 3184 if( RTL_LOGFILE_HASLOGFILE() ) 3185 { 3186 ByteString aString( rMedium.GetName(), RTL_TEXTENCODING_ASCII_US ); 3187 RTL_LOGFILE_PRODUCT_CONTEXT_TRACE1( aLog, "loading \"%s\"", aString.GetBuffer() ); 3188 } 3189 3190 uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage(); 3191 if ( xStorage.is() ) 3192 { 3193 // Password 3194 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswdItem, SfxStringItem, SID_PASSWORD, sal_False ); 3195 if ( pPasswdItem || ERRCODE_IO_ABORT != CheckPasswd_Impl( this, SFX_APP()->GetPool(), pMedium ) ) 3196 { 3197 uno::Sequence< beans::NamedValue > aEncryptionData; 3198 if ( GetEncryptionData_Impl(pMedium->GetItemSet(), aEncryptionData) ) 3199 { 3200 try 3201 { 3202 // the following code must throw an exception in case of failure 3203 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( xStorage, aEncryptionData ); 3204 } 3205 catch( uno::Exception& ) 3206 { 3207 // TODO/LATER: handle the error code 3208 } 3209 } 3210 3211 // load document 3212 return Load( rMedium ); 3213 } 3214 return sal_False; 3215 } 3216 else 3217 return sal_False; 3218 } 3219 3220 sal_Bool SfxObjectShell::SaveAsOwnFormat( SfxMedium& rMedium ) 3221 { 3222 uno::Reference< embed::XStorage > xStorage = rMedium.GetStorage(); 3223 if( xStorage.is() ) 3224 { 3225 sal_Int32 nVersion = rMedium.GetFilter()->GetVersion(); 3226 3227 // OASIS templates have own mediatypes ( SO7 also actually, but it is to late to use them here ) 3228 sal_Bool bTemplate = ( rMedium.GetFilter()->IsOwnTemplateFormat() && nVersion > SOFFICE_FILEFORMAT_60 ); 3229 3230 SetupStorage( xStorage, nVersion, bTemplate ); 3231 3232 if ( HasBasic() ) 3233 { 3234 // Initialize Basic 3235 GetBasicManager(); 3236 3237 // Save dialog/script container 3238 pImp->pBasicManager->storeLibrariesToStorage( xStorage ); 3239 } 3240 3241 return SaveAs( rMedium ); 3242 } 3243 else return sal_False; 3244 } 3245 3246 uno::Reference< embed::XStorage > SfxObjectShell::GetStorage() 3247 { 3248 if ( !pImp->m_xDocStorage.is() ) 3249 { 3250 OSL_ENSURE( pImp->m_bCreateTempStor, "The storage must exist already!\n" ); 3251 try { 3252 // no notification is required the storage is set the first time 3253 pImp->m_xDocStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 3254 OSL_ENSURE( pImp->m_xDocStorage.is(), "The method must either return storage or throw an exception!" ); 3255 3256 SetupStorage( pImp->m_xDocStorage, SOFFICE_FILEFORMAT_CURRENT, sal_False ); 3257 pImp->m_bCreateTempStor = sal_False; 3258 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_STORAGECHANGED, GlobalEventConfig::GetEventName(STR_EVENT_STORAGECHANGED), this ) ); 3259 } 3260 catch( uno::Exception& ) 3261 { 3262 // TODO/LATER: error handling? 3263 } 3264 } 3265 3266 OSL_ENSURE( pImp->m_xDocStorage.is(), "The document storage must be created!" ); 3267 return pImp->m_xDocStorage; 3268 } 3269 3270 3271 sal_Bool SfxObjectShell::SaveChildren( sal_Bool bObjectsOnly ) 3272 { 3273 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveChildren" ); 3274 3275 sal_Bool bResult = sal_True; 3276 if ( pImp->mpObjectContainer ) 3277 { 3278 sal_Bool bOasis = ( SotStorage::GetVersion( GetStorage() ) > SOFFICE_FILEFORMAT_60 ); 3279 GetEmbeddedObjectContainer().StoreChildren(bOasis,bObjectsOnly); 3280 } 3281 3282 return bResult; 3283 } 3284 3285 sal_Bool SfxObjectShell::SaveAsChildren( SfxMedium& rMedium ) 3286 { 3287 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveAsChildren" ); 3288 3289 sal_Bool bResult = sal_True; 3290 3291 uno::Reference < embed::XStorage > xStorage = rMedium.GetStorage(); 3292 if ( !xStorage.is() ) 3293 return sal_False; 3294 3295 if ( xStorage == GetStorage() ) 3296 return SaveChildren(); 3297 3298 sal_Bool bOasis = sal_True; 3299 if ( pImp->mpObjectContainer ) 3300 { 3301 bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 ); 3302 GetEmbeddedObjectContainer().StoreAsChildren(bOasis,SFX_CREATE_MODE_EMBEDDED == eCreateMode,xStorage); 3303 } 3304 3305 if ( bResult ) 3306 bResult = CopyStoragesOfUnknownMediaType( GetStorage(), xStorage ); 3307 3308 return bResult; 3309 } 3310 3311 sal_Bool SfxObjectShell::SaveCompletedChildren( sal_Bool bSuccess ) 3312 { 3313 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveCompletedChildren" ); 3314 3315 sal_Bool bResult = sal_True; 3316 3317 if ( pImp->mpObjectContainer ) 3318 { 3319 uno::Sequence < ::rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames(); 3320 for ( sal_Int32 n=0; n<aNames.getLength(); n++ ) 3321 { 3322 uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( aNames[n] ); 3323 OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" ); 3324 if ( xObj.is() ) 3325 { 3326 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); 3327 if ( xPersist.is() ) 3328 { 3329 try 3330 { 3331 xPersist->saveCompleted( bSuccess ); 3332 } 3333 catch( uno::Exception& ) 3334 { 3335 // TODO/LATER: error handling 3336 bResult = sal_False; 3337 break; 3338 } 3339 } 3340 } 3341 } 3342 } 3343 3344 return bResult; 3345 } 3346 3347 sal_Bool SfxObjectShell::SwitchChildrenPersistance( const uno::Reference< embed::XStorage >& xStorage, 3348 sal_Bool bForceNonModified ) 3349 { 3350 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SwitchChildrenPersistence" ); 3351 3352 if ( !xStorage.is() ) 3353 { 3354 // TODO/LATER: error handling 3355 return sal_False; 3356 } 3357 3358 sal_Bool bResult = sal_True; 3359 3360 if ( pImp->mpObjectContainer ) 3361 pImp->mpObjectContainer->SetPersistentEntries(xStorage,bForceNonModified); 3362 3363 return bResult; 3364 } 3365 3366 // Never call this method directly, always use the DoSaveCompleted call 3367 sal_Bool SfxObjectShell::SaveCompleted( const uno::Reference< embed::XStorage >& xStorage ) 3368 { 3369 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SaveCompleted" ); 3370 3371 sal_Bool bResult = sal_False; 3372 sal_Bool bSendNotification = sal_False; 3373 uno::Reference< embed::XStorage > xOldStorageHolder; 3374 3375 #ifdef DBG_UTIL 3376 // check for wrong creation of object container 3377 sal_Bool bHasContainer = ( pImp->mpObjectContainer != 0 ); 3378 #endif 3379 3380 if ( !xStorage.is() || xStorage == GetStorage() ) 3381 { 3382 // no persistence change 3383 bResult = SaveCompletedChildren( sal_False ); 3384 } 3385 else 3386 { 3387 if ( pImp->mpObjectContainer ) 3388 GetEmbeddedObjectContainer().SwitchPersistence( xStorage ); 3389 3390 bResult = SwitchChildrenPersistance( xStorage, sal_True ); 3391 } 3392 3393 if ( bResult ) 3394 { 3395 if ( xStorage.is() && pImp->m_xDocStorage != xStorage ) 3396 { 3397 // make sure that until the storage is assigned the object container is not created by accident! 3398 DBG_ASSERT( bHasContainer == (pImp->mpObjectContainer != 0), "Wrong storage in object container!" ); 3399 xOldStorageHolder = pImp->m_xDocStorage; 3400 pImp->m_xDocStorage = xStorage; 3401 bSendNotification = sal_True; 3402 3403 if ( IsEnableSetModified() ) 3404 SetModified( sal_False ); 3405 } 3406 } 3407 else 3408 { 3409 if ( pImp->mpObjectContainer ) 3410 GetEmbeddedObjectContainer().SwitchPersistence( pImp->m_xDocStorage ); 3411 3412 // let already successfully connected objects be switched back 3413 SwitchChildrenPersistance( pImp->m_xDocStorage, sal_True ); 3414 } 3415 3416 if ( bSendNotification ) 3417 { 3418 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_STORAGECHANGED, GlobalEventConfig::GetEventName(STR_EVENT_STORAGECHANGED), this ) ); 3419 } 3420 3421 return bResult; 3422 } 3423 3424 3425 sal_Bool StoragesOfUnknownMediaTypeAreCopied_Impl( const uno::Reference< embed::XStorage >& xSource, 3426 const uno::Reference< embed::XStorage >& xTarget ) 3427 { 3428 OSL_ENSURE( xSource.is() && xTarget.is(), "Source and/or target storages are not available!\n" ); 3429 if ( !xSource.is() || !xTarget.is() || xSource == xTarget ) 3430 return sal_True; 3431 3432 try 3433 { 3434 uno::Sequence< ::rtl::OUString > aSubElements = xSource->getElementNames(); 3435 for ( sal_Int32 nInd = 0; nInd < aSubElements.getLength(); nInd++ ) 3436 { 3437 if ( xSource->isStorageElement( aSubElements[nInd] ) ) 3438 { 3439 ::rtl::OUString aMediaType; 3440 ::rtl::OUString aMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); 3441 sal_Bool bGotMediaType = sal_False; 3442 3443 try 3444 { 3445 uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW ); 3446 bGotMediaType = 3447 ( xOptStorage->getElementPropertyValue( aSubElements[nInd], aMediaTypePropName ) >>= aMediaType ); 3448 } 3449 catch( uno::Exception& ) 3450 {} 3451 3452 if ( !bGotMediaType ) 3453 { 3454 uno::Reference< embed::XStorage > xSubStorage; 3455 try { 3456 xSubStorage = xSource->openStorageElement( aSubElements[nInd], embed::ElementModes::READ ); 3457 } catch( uno::Exception& ) 3458 {} 3459 3460 if ( !xSubStorage.is() ) 3461 { 3462 xSubStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 3463 xSource->copyStorageElementLastCommitTo( aSubElements[nInd], xSubStorage ); 3464 } 3465 3466 uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW ); 3467 bGotMediaType = ( xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType ); 3468 } 3469 3470 // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist 3471 // probably it should be placed in the MimeType-ClassID table or in standalone table 3472 if ( aMediaType.getLength() 3473 && aMediaType.compareToAscii( "application/vnd.sun.star.oleobject" ) != COMPARE_EQUAL ) 3474 { 3475 ::com::sun::star::datatransfer::DataFlavor aDataFlavor; 3476 aDataFlavor.MimeType = aMediaType; 3477 sal_uInt32 nFormat = SotExchange::GetFormat( aDataFlavor ); 3478 3479 switch ( nFormat ) 3480 { 3481 case SOT_FORMATSTR_ID_STARWRITER_60 : 3482 case SOT_FORMATSTR_ID_STARWRITERWEB_60 : 3483 case SOT_FORMATSTR_ID_STARWRITERGLOB_60 : 3484 case SOT_FORMATSTR_ID_STARDRAW_60 : 3485 case SOT_FORMATSTR_ID_STARIMPRESS_60 : 3486 case SOT_FORMATSTR_ID_STARCALC_60 : 3487 case SOT_FORMATSTR_ID_STARCHART_60 : 3488 case SOT_FORMATSTR_ID_STARMATH_60 : 3489 case SOT_FORMATSTR_ID_STARWRITER_8: 3490 case SOT_FORMATSTR_ID_STARWRITERWEB_8: 3491 case SOT_FORMATSTR_ID_STARWRITERGLOB_8: 3492 case SOT_FORMATSTR_ID_STARDRAW_8: 3493 case SOT_FORMATSTR_ID_STARIMPRESS_8: 3494 case SOT_FORMATSTR_ID_STARCALC_8: 3495 case SOT_FORMATSTR_ID_STARCHART_8: 3496 case SOT_FORMATSTR_ID_STARMATH_8: 3497 break; 3498 3499 default: 3500 { 3501 if ( !xTarget->hasByName( aSubElements[nInd] ) ) 3502 return sal_False; 3503 } 3504 } 3505 } 3506 } 3507 } 3508 } 3509 catch( uno::Exception& ) 3510 { 3511 OSL_ENSURE( sal_False, "Cant check storage consistency!\n" ); 3512 } 3513 3514 return sal_True; 3515 } 3516 3517 3518 sal_Bool SfxObjectShell::SwitchPersistance( const uno::Reference< embed::XStorage >& xStorage ) 3519 { 3520 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::SwitchPersistance" ); 3521 3522 sal_Bool bResult = sal_False; 3523 #ifdef DBG_UTIL 3524 // check for wrong creation of object container 3525 sal_Bool bHasContainer = ( pImp->mpObjectContainer != 0 ); 3526 #endif 3527 if ( xStorage.is() ) 3528 { 3529 if ( pImp->mpObjectContainer ) 3530 GetEmbeddedObjectContainer().SwitchPersistence( xStorage ); 3531 bResult = SwitchChildrenPersistance( xStorage ); 3532 3533 // TODO/LATER: substorages that have unknown mimetypes probably should be copied to the target storage here 3534 OSL_ENSURE( StoragesOfUnknownMediaTypeAreCopied_Impl( pImp->m_xDocStorage, xStorage ), 3535 "Some of substorages with unknown mimetypes is lost!" ); 3536 } 3537 3538 if ( bResult ) 3539 { 3540 // make sure that until the storage is assigned the object container is not created by accident! 3541 DBG_ASSERT( bHasContainer == (pImp->mpObjectContainer != 0), "Wrong storage in object container!" ); 3542 if ( pImp->m_xDocStorage != xStorage ) 3543 DoSaveCompleted( new SfxMedium( xStorage, GetMedium()->GetBaseURL() ) ); 3544 3545 if ( IsEnableSetModified() ) 3546 SetModified( sal_True ); // ??? 3547 } 3548 3549 return bResult; 3550 } 3551 3552 sal_Bool SfxObjectShell::CopyStoragesOfUnknownMediaType( const uno::Reference< embed::XStorage >& xSource, 3553 const uno::Reference< embed::XStorage >& xTarget ) 3554 { 3555 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::CopyStoragesOfUnknownMediaType" ); 3556 3557 // This method does not commit the target storage and should not do it 3558 sal_Bool bResult = sal_True; 3559 3560 try 3561 { 3562 uno::Sequence< ::rtl::OUString > aSubElements = xSource->getElementNames(); 3563 for ( sal_Int32 nInd = 0; nInd < aSubElements.getLength(); nInd++ ) 3564 { 3565 if ( aSubElements[nInd].equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Configurations" ) ) ) ) 3566 { 3567 // The workaround for compatibility with SO7, "Configurations" substorage must be preserved 3568 if ( xSource->isStorageElement( aSubElements[nInd] ) ) 3569 { 3570 OSL_ENSURE( !xTarget->hasByName( aSubElements[nInd] ), 3571 "The target storage is an output storage, the element should not exist in the target!\n" ); 3572 3573 xSource->copyElementTo( aSubElements[nInd], xTarget, aSubElements[nInd] ); 3574 } 3575 } 3576 else if ( xSource->isStorageElement( aSubElements[nInd] ) ) 3577 { 3578 ::rtl::OUString aMediaType; 3579 ::rtl::OUString aMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); 3580 sal_Bool bGotMediaType = sal_False; 3581 3582 try 3583 { 3584 uno::Reference< embed::XOptimizedStorage > xOptStorage( xSource, uno::UNO_QUERY_THROW ); 3585 bGotMediaType = 3586 ( xOptStorage->getElementPropertyValue( aSubElements[nInd], aMediaTypePropName ) >>= aMediaType ); 3587 } 3588 catch( uno::Exception& ) 3589 {} 3590 3591 if ( !bGotMediaType ) 3592 { 3593 uno::Reference< embed::XStorage > xSubStorage; 3594 try { 3595 xSubStorage = xSource->openStorageElement( aSubElements[nInd], embed::ElementModes::READ ); 3596 } catch( uno::Exception& ) 3597 {} 3598 3599 if ( !xSubStorage.is() ) 3600 { 3601 // TODO/LATER: as optimization in future a substorage of target storage could be used 3602 // instead of the temporary storage; this substorage should be removed later 3603 // if the MimeType is wrong 3604 xSubStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); 3605 xSource->copyStorageElementLastCommitTo( aSubElements[nInd], xSubStorage ); 3606 } 3607 3608 uno::Reference< beans::XPropertySet > xProps( xSubStorage, uno::UNO_QUERY_THROW ); 3609 bGotMediaType = ( xProps->getPropertyValue( aMediaTypePropName ) >>= aMediaType ); 3610 } 3611 3612 // TODO/LATER: there should be a way to detect whether an object with such a MediaType can exist 3613 // probably it should be placed in the MimeType-ClassID table or in standalone table 3614 if ( aMediaType.getLength() 3615 && aMediaType.compareToAscii( "application/vnd.sun.star.oleobject" ) != COMPARE_EQUAL ) 3616 { 3617 ::com::sun::star::datatransfer::DataFlavor aDataFlavor; 3618 aDataFlavor.MimeType = aMediaType; 3619 sal_uInt32 nFormat = SotExchange::GetFormat( aDataFlavor ); 3620 3621 switch ( nFormat ) 3622 { 3623 case SOT_FORMATSTR_ID_STARWRITER_60 : 3624 case SOT_FORMATSTR_ID_STARWRITERWEB_60 : 3625 case SOT_FORMATSTR_ID_STARWRITERGLOB_60 : 3626 case SOT_FORMATSTR_ID_STARDRAW_60 : 3627 case SOT_FORMATSTR_ID_STARIMPRESS_60 : 3628 case SOT_FORMATSTR_ID_STARCALC_60 : 3629 case SOT_FORMATSTR_ID_STARCHART_60 : 3630 case SOT_FORMATSTR_ID_STARMATH_60 : 3631 case SOT_FORMATSTR_ID_STARWRITER_8: 3632 case SOT_FORMATSTR_ID_STARWRITERWEB_8: 3633 case SOT_FORMATSTR_ID_STARWRITERGLOB_8: 3634 case SOT_FORMATSTR_ID_STARDRAW_8: 3635 case SOT_FORMATSTR_ID_STARIMPRESS_8: 3636 case SOT_FORMATSTR_ID_STARCALC_8: 3637 case SOT_FORMATSTR_ID_STARCHART_8: 3638 case SOT_FORMATSTR_ID_STARMATH_8: 3639 break; 3640 3641 default: 3642 { 3643 OSL_ENSURE( 3644 aSubElements[nInd].equalsAscii( "Configurations2" ) || !xTarget->hasByName( aSubElements[nInd] ), 3645 "The target storage is an output storage, the element should not exist in the target!\n" ); 3646 3647 if ( !xTarget->hasByName( aSubElements[nInd] ) ) 3648 { 3649 xSource->copyElementTo( aSubElements[nInd], xTarget, aSubElements[nInd] ); 3650 } 3651 } 3652 } 3653 } 3654 } 3655 } 3656 } 3657 catch( uno::Exception& ) 3658 { 3659 bResult = sal_False; 3660 // TODO/LATER: a specific error could be provided 3661 } 3662 3663 return bResult; 3664 } 3665 3666 sal_Bool SfxObjectShell::GenerateAndStoreThumbnail( sal_Bool bEncrypted, 3667 sal_Bool bSigned, 3668 sal_Bool bIsTemplate, 3669 const uno::Reference< embed::XStorage >& xStor ) 3670 { 3671 RTL_LOGFILE_CONTEXT( aLog, "sfx2 (mv76033) SfxObjectShell::GenerateAndStoreThumbnail" ); 3672 3673 sal_Bool bResult = sal_False; 3674 3675 try { 3676 uno::Reference< embed::XStorage > xThumbnailStor = 3677 xStor->openStorageElement( ::rtl::OUString::createFromAscii( "Thumbnails" ), 3678 embed::ElementModes::READWRITE ); 3679 if ( xThumbnailStor.is() ) 3680 { 3681 uno::Reference< io::XStream > xStream = xThumbnailStor->openStreamElement( 3682 ::rtl::OUString::createFromAscii( "thumbnail.png" ), 3683 embed::ElementModes::READWRITE ); 3684 3685 if ( xStream.is() && WriteThumbnail( bEncrypted, bSigned, bIsTemplate, xStream ) ) 3686 { 3687 uno::Reference< embed::XTransactedObject > xTransact( xThumbnailStor, uno::UNO_QUERY_THROW ); 3688 xTransact->commit(); 3689 bResult = sal_True; 3690 } 3691 } 3692 } 3693 catch( uno::Exception& ) 3694 { 3695 } 3696 3697 return bResult; 3698 } 3699 3700 sal_Bool SfxObjectShell::WriteThumbnail( sal_Bool bEncrypted, 3701 sal_Bool bSigned, 3702 sal_Bool bIsTemplate, 3703 const uno::Reference< io::XStream >& xStream ) 3704 { 3705 sal_Bool bResult = sal_False; 3706 3707 if ( xStream.is() ) 3708 { 3709 try { 3710 uno::Reference< io::XTruncate > xTruncate( xStream->getOutputStream(), uno::UNO_QUERY_THROW ); 3711 xTruncate->truncate(); 3712 3713 if ( bEncrypted ) 3714 { 3715 sal_uInt16 nResID = GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl( 3716 ::rtl::OUString::createFromAscii( GetFactory().GetShortName() ), 3717 bIsTemplate ); 3718 if ( nResID ) 3719 { 3720 if ( !bSigned ) 3721 { 3722 bResult = GraphicHelper::getThumbnailReplacement_Impl( nResID, xStream ); 3723 } 3724 else 3725 { 3726 // retrieve the bitmap and write a signature bitmap over it 3727 SfxResId aResId( nResID ); 3728 BitmapEx aThumbBitmap( aResId ); 3729 bResult = GraphicHelper::getSignedThumbnailFormatFromBitmap_Impl( aThumbBitmap, xStream ); 3730 } 3731 } 3732 } 3733 else 3734 { 3735 ::boost::shared_ptr<GDIMetaFile> pMetaFile = 3736 GetPreviewMetaFile( sal_False ); 3737 if ( pMetaFile ) 3738 { 3739 bResult = GraphicHelper::getThumbnailFormatFromGDI_Impl( 3740 pMetaFile.get(), bSigned, xStream ); 3741 } 3742 } 3743 } 3744 catch( uno::Exception& ) 3745 {} 3746 } 3747 3748 return bResult; 3749 } 3750 3751 void SfxObjectShell::UpdateLinks() 3752 { 3753 } 3754 3755 sal_Bool SfxObjectShell::QuerySaveSizeExceededModules_Impl( const uno::Reference< task::XInteractionHandler >& xHandler ) 3756 { 3757 if ( !HasBasic() ) 3758 return sal_True; 3759 3760 if ( !pImp->pBasicManager->isValid() ) 3761 GetBasicManager(); 3762 uno::Sequence< rtl::OUString > sModules; 3763 if ( xHandler.is() ) 3764 { 3765 if( pImp->pBasicManager->LegacyPsswdBinaryLimitExceeded( sModules ) ) 3766 { 3767 ModuleSizeExceeded* pReq = new ModuleSizeExceeded( sModules ); 3768 uno::Reference< task::XInteractionRequest > xReq( pReq ); 3769 xHandler->handle( xReq ); 3770 return pReq->isApprove(); 3771 } 3772 } 3773 // No interaction handler, default is to continue to save 3774 return sal_True; 3775 } 3776 // ----------------------------------------------------------------------------- 3777 uno::Reference< task::XInteractionHandler > SfxObjectShell::getInteractionHandler() const 3778 { 3779 uno::Reference< task::XInteractionHandler > xRet; 3780 if ( GetMedium() ) 3781 xRet = GetMedium()->GetInteractionHandler(); 3782 return xRet; 3783 } 3784