1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 27 #include <sot/storage.hxx> 28 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> 29 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> 30 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> 31 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> 32 #include <com/sun/star/ui/dialogs/XControlAccess.hpp> 33 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 34 #include <com/sun/star/beans/XPropertyAccess.hpp> 35 #include <com/sun/star/beans/XPropertySet.hpp> 36 #include <com/sun/star/beans/PropertyValue.hpp> 37 #include <com/sun/star/container/XNameAccess.hpp> 38 #include <com/sun/star/document/XExporter.hpp> 39 #include <com/sun/star/task/XInteractionHandler.hpp> 40 #include <com/sun/star/task/XStatusIndicator.hpp> 41 #include <com/sun/star/task/XStatusIndicatorFactory.hpp> 42 #include <com/sun/star/frame/XDocumentTemplates.hpp> 43 #include <com/sun/star/frame/XStorable.hpp> 44 #include <comphelper/processfactory.hxx> 45 #include <com/sun/star/security/CertificateValidity.hpp> 46 47 #include <com/sun/star/security/DocumentSignatureInformation.hpp> 48 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp> 49 #include <tools/urlobj.hxx> 50 #include <svl/whiter.hxx> 51 #include <vcl/msgbox.hxx> 52 #include <svl/intitem.hxx> 53 #include <svl/eitem.hxx> 54 #include <vcl/wrkwin.hxx> 55 #include <svtools/sfxecode.hxx> 56 #include <svtools/ehdl.hxx> 57 58 #include <comphelper/string.hxx> 59 #include <basic/sbx.hxx> 60 #include <unotools/pathoptions.hxx> 61 #include <unotools/useroptions.hxx> 62 #include <svtools/asynclink.hxx> 63 #include <unotools/saveopt.hxx> 64 #include <comphelper/documentconstants.hxx> 65 66 #include <sfx2/app.hxx> 67 #include <sfx2/signaturestate.hxx> 68 #include "sfx2/sfxresid.hxx" 69 #include <sfx2/event.hxx> 70 #include <sfx2/request.hxx> 71 #include <sfx2/printer.hxx> 72 #include <sfx2/viewsh.hxx> 73 #include <sfx2/doctdlg.hxx> 74 #include <sfx2/docfilt.hxx> 75 #include <sfx2/docfile.hxx> 76 #include <sfx2/dispatch.hxx> 77 #include <sfx2/dinfdlg.hxx> 78 #include <sfx2/objitem.hxx> 79 #include <sfx2/objsh.hxx> 80 #include "objshimp.hxx" 81 #include "sfxtypes.hxx" 82 //#include "interno.hxx" 83 #include <sfx2/module.hxx> 84 #include <sfx2/viewfrm.hxx> 85 #include "versdlg.hxx" 86 #include "doc.hrc" 87 #include <sfx2/docfac.hxx> 88 #include <sfx2/fcontnr.hxx> 89 #include <sfx2/filedlghelper.hxx> 90 #include "sfx2/sfxhelp.hxx" 91 #include <sfx2/msgpool.hxx> 92 #include <sfx2/objface.hxx> 93 94 #include "../appl/app.hrc" 95 #include <com/sun/star/document/XDocumentSubStorageSupplier.hpp> 96 #include <com/sun/star/embed/XTransactedObject.hpp> 97 #include <com/sun/star/util/XCloneable.hpp> 98 #include <com/sun/star/document/XDocumentProperties.hpp> 99 100 #include "helpid.hrc" 101 102 #include "guisaveas.hxx" 103 104 using namespace ::com::sun::star; 105 using namespace ::com::sun::star::lang; 106 using namespace ::com::sun::star::uno; 107 using namespace ::com::sun::star::ui::dialogs; 108 using namespace ::com::sun::star::awt; 109 using namespace ::com::sun::star::container; 110 using namespace ::com::sun::star::beans; 111 using namespace ::com::sun::star::document; 112 using namespace ::com::sun::star::task; 113 114 //==================================================================== 115 116 class SfxSaveAsContext_Impl 117 { 118 String& _rNewNameVar; 119 String _aNewName; 120 121 public: 122 SfxSaveAsContext_Impl( String &rNewNameVar, 123 const String &rNewName ) 124 : _rNewNameVar( rNewNameVar ), 125 _aNewName( rNewName ) 126 { rNewNameVar = rNewName; } 127 ~SfxSaveAsContext_Impl() 128 { _rNewNameVar.Erase(); } 129 }; 130 131 //==================================================================== 132 133 #define SfxObjectShell 134 #include "sfxslots.hxx" 135 136 //========================================================================= 137 138 139 140 SFX_IMPL_INTERFACE(SfxObjectShell,SfxShell,SfxResId(0)) 141 { 142 } 143 144 //========================================================================= 145 146 class SfxClosePreventer_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener > 147 { 148 sal_Bool m_bGotOwnership; 149 sal_Bool m_bPreventClose; 150 151 public: 152 SfxClosePreventer_Impl(); 153 154 sal_Bool HasOwnership() { return m_bGotOwnership; } 155 156 void SetPreventClose( sal_Bool bPrevent ) { m_bPreventClose = bPrevent; } 157 158 virtual void SAL_CALL queryClosing( const lang::EventObject& aEvent, sal_Bool bDeliverOwnership ); 159 160 virtual void SAL_CALL notifyClosing( const lang::EventObject& aEvent ) ; 161 162 virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) ; 163 164 } ; 165 166 SfxClosePreventer_Impl::SfxClosePreventer_Impl() 167 : m_bGotOwnership( sal_False ) 168 , m_bPreventClose( sal_True ) 169 { 170 } 171 172 void SAL_CALL SfxClosePreventer_Impl::queryClosing( const lang::EventObject&, sal_Bool bDeliverOwnership ) 173 { 174 if ( m_bPreventClose ) 175 { 176 if ( !m_bGotOwnership ) 177 m_bGotOwnership = bDeliverOwnership; 178 179 throw util::CloseVetoException(); 180 } 181 } 182 183 void SAL_CALL SfxClosePreventer_Impl::notifyClosing( const lang::EventObject& ) 184 {} 185 186 void SAL_CALL SfxClosePreventer_Impl::disposing( const lang::EventObject& ) 187 {} 188 189 //========================================================================= 190 class SfxInstanceCloseGuard_Impl 191 { 192 SfxClosePreventer_Impl* m_pPreventer; 193 uno::Reference< util::XCloseListener > m_xPreventer; 194 uno::Reference< util::XCloseable > m_xCloseable; 195 196 public: 197 SfxInstanceCloseGuard_Impl() 198 : m_pPreventer( NULL ) 199 {} 200 201 ~SfxInstanceCloseGuard_Impl(); 202 203 sal_Bool Init_Impl( const uno::Reference< util::XCloseable >& xCloseable ); 204 }; 205 206 sal_Bool SfxInstanceCloseGuard_Impl::Init_Impl( const uno::Reference< util::XCloseable >& xCloseable ) 207 { 208 sal_Bool bResult = sal_False; 209 210 // do not allow reinit after the successful init 211 if ( xCloseable.is() && !m_xCloseable.is() ) 212 { 213 try 214 { 215 m_pPreventer = new SfxClosePreventer_Impl(); 216 m_xPreventer = uno::Reference< util::XCloseListener >( m_pPreventer ); 217 xCloseable->addCloseListener( m_xPreventer ); 218 m_xCloseable = xCloseable; 219 bResult = sal_True; 220 } 221 catch( uno::Exception& ) 222 { 223 OSL_ENSURE( sal_False, "Could not register close listener!\n" ); 224 } 225 } 226 227 return bResult; 228 } 229 230 SfxInstanceCloseGuard_Impl::~SfxInstanceCloseGuard_Impl() 231 { 232 if ( m_xCloseable.is() && m_xPreventer.is() ) 233 { 234 try 235 { 236 m_xCloseable->removeCloseListener( m_xPreventer ); 237 } 238 catch( uno::Exception& ) 239 { 240 } 241 242 try 243 { 244 if ( m_pPreventer ) 245 { 246 m_pPreventer->SetPreventClose( sal_False ); 247 248 if ( m_pPreventer->HasOwnership() ) 249 m_xCloseable->close( sal_True ); // TODO: do it asynchronously 250 } 251 } 252 catch( uno::Exception& ) 253 { 254 } 255 } 256 } 257 258 //========================================================================= 259 260 void SfxObjectShell::PrintExec_Impl(SfxRequest &rReq) 261 { 262 SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this); 263 if ( pFrame ) 264 { 265 rReq.SetSlot( SID_PRINTDOC ); 266 pFrame->GetViewShell()->ExecuteSlot(rReq); 267 } 268 } 269 270 //-------------------------------------------------------------------- 271 272 void SfxObjectShell::PrintState_Impl(SfxItemSet &rSet) 273 { 274 bool bPrinting = false; 275 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); 276 if ( pFrame ) 277 { 278 SfxPrinter *pPrinter = pFrame->GetViewShell()->GetPrinter(); 279 bPrinting = pPrinter && pPrinter->IsPrinting(); 280 } 281 rSet.Put( SfxBoolItem( SID_PRINTOUT, bPrinting ) ); 282 } 283 284 //-------------------------------------------------------------------- 285 286 sal_Bool SfxObjectShell::APISaveAs_Impl 287 ( 288 const String& aFileName, 289 SfxItemSet* aParams 290 ) 291 { 292 sal_Bool bOk = sal_False; 293 294 {DBG_CHKTHIS(SfxObjectShell, 0);} 295 296 if ( GetMedium() ) 297 { 298 String aFilterName; 299 SFX_ITEMSET_ARG( aParams, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False ); 300 if( pFilterNameItem ) 301 { 302 aFilterName = pFilterNameItem->GetValue(); 303 } 304 else 305 { 306 SFX_ITEMSET_ARG( aParams, pContentTypeItem, SfxStringItem, SID_CONTENTTYPE, sal_False ); 307 if ( pContentTypeItem ) 308 { 309 const SfxFilter* pFilter = SfxFilterMatcher( String::CreateFromAscii(GetFactory().GetShortName()) ).GetFilter4Mime( pContentTypeItem->GetValue(), SFX_FILTER_EXPORT ); 310 if ( pFilter ) 311 aFilterName = pFilter->GetName(); 312 } 313 } 314 315 // in case no filter defined use default one 316 if( !aFilterName.Len() ) 317 { 318 const SfxFilter* pFilt = SfxFilter::GetDefaultFilterFromFactory(GetFactory().GetFactoryName()); 319 320 DBG_ASSERT( pFilt, "No default filter!\n" ); 321 if( pFilt ) 322 aFilterName = pFilt->GetFilterName(); 323 324 aParams->Put(SfxStringItem( SID_FILTER_NAME, aFilterName)); 325 } 326 327 328 { 329 SfxObjectShellRef xLock( this ); // ??? 330 331 // use the title that is provided in the media descriptor 332 SFX_ITEMSET_ARG( aParams, pDocTitleItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False ); 333 if ( pDocTitleItem ) 334 getDocProperties()->setTitle( pDocTitleItem->GetValue() ); 335 336 bOk = CommonSaveAs_Impl( INetURLObject(aFileName), aFilterName, 337 aParams ); 338 339 } 340 341 // prevent picklist-entry 342 GetMedium()->SetUpdatePickList( sal_False ); 343 } 344 345 return bOk; 346 } 347 348 //-------------------------------------------------------------------- 349 350 void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) 351 { 352 {DBG_CHKTHIS(SfxObjectShell, 0);} 353 354 sal_uInt16 nId = rReq.GetSlot(); 355 356 if( SID_SIGNATURE == nId || SID_MACRO_SIGNATURE == nId ) 357 { 358 if ( QueryHiddenInformation( WhenSigning, NULL ) == RET_YES ) 359 ( SID_SIGNATURE == nId ) ? SignDocumentContent() : SignScriptingContent(); 360 return; 361 } 362 363 if ( !GetMedium() && nId != SID_CLOSEDOC ) 364 { 365 rReq.Ignore(); 366 return; 367 } 368 369 // this guard is created here to have it destruction at the end of the method 370 SfxInstanceCloseGuard_Impl aModelGuard; 371 372 sal_Bool bIsPDFExport = sal_False; 373 switch(nId) 374 { 375 case SID_VERSION: 376 { 377 SfxViewFrame* pFrame = GetFrame(); 378 if ( !pFrame ) 379 pFrame = SfxViewFrame::GetFirst( this ); 380 if ( !pFrame ) 381 return; 382 383 if ( pFrame->GetFrame().GetParentFrame() ) 384 { 385 pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq ); 386 return; 387 } 388 389 if ( !IsOwnStorageFormat_Impl( *GetMedium() ) ) 390 return; 391 392 SfxVersionDialog *pDlg = new SfxVersionDialog( pFrame, IsSaveVersionOnClose() ); 393 pDlg->Execute(); 394 SetSaveVersionOnClose( pDlg->IsSaveVersionOnClose() ); 395 delete pDlg; 396 rReq.Done(); 397 return; 398 } 399 400 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 401 case SID_DOCINFO: 402 { 403 SFX_REQUEST_ARG(rReq, pDocInfItem, SfxDocumentInfoItem, SID_DOCINFO, sal_False); 404 if ( pDocInfItem ) 405 { 406 // parameter, e.g. from replayed macro 407 pDocInfItem->UpdateDocumentInfo(getDocProperties(), true); 408 SetUseUserData( pDocInfItem->IsUseUserData() ); 409 } 410 else 411 { 412 // no argument containing DocInfo; check optional arguments 413 sal_Bool bReadOnly = IsReadOnly(); 414 SFX_REQUEST_ARG(rReq, pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False); 415 if ( pROItem ) 416 // override readonly attribute of document 417 // e.g. if a readonly document is saved elsewhere and user asks for editing DocInfo before 418 bReadOnly = pROItem->GetValue(); 419 420 // collect data for dialog 421 String aURL, aTitle; 422 if ( HasName() ) 423 { 424 aURL = GetMedium()->GetName(); 425 aTitle = GetTitle(); 426 } 427 else 428 { 429 aURL = DEFINE_CONST_UNICODE( "private:factory/" ); 430 aURL += String::CreateFromAscii( GetFactory().GetShortName() ); 431 432 aTitle = GetTitle(); 433 } 434 435 SfxDocumentInfoItem aDocInfoItem( aURL, getDocProperties(), 436 IsUseUserData() ); 437 if ( !GetSlotState( SID_DOCTEMPLATE ) ) 438 // templates not supported 439 aDocInfoItem.SetTemplate(sal_False); 440 441 SfxItemSet aSet(GetPool(), SID_DOCINFO, SID_DOCINFO, SID_DOC_READONLY, SID_DOC_READONLY, 442 SID_EXPLORER_PROPS_START, SID_EXPLORER_PROPS_START, SID_BASEURL, SID_BASEURL, 443 0L ); 444 aSet.Put( aDocInfoItem ); 445 aSet.Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) ); 446 aSet.Put( SfxStringItem( SID_EXPLORER_PROPS_START, aTitle ) ); 447 aSet.Put( SfxStringItem( SID_BASEURL, GetMedium()->GetBaseURL() ) ); 448 449 // creating dialog is done via virtual method; application will add its own statistics page 450 SfxDocumentInfoDialog *pDlg = CreateDocumentInfoDialog(0, aSet); 451 if ( RET_OK == pDlg->Execute() ) 452 { 453 SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pDocInfoItem, SfxDocumentInfoItem, SID_DOCINFO, sal_False); 454 if ( pDocInfoItem ) 455 { 456 // user has done some changes to DocumentInfo 457 pDocInfoItem->UpdateDocumentInfo(getDocProperties()); 458 SetUseUserData( ((const SfxDocumentInfoItem *)pDocInfoItem)->IsUseUserData() ); 459 460 // add data from dialog for possible recording purposes 461 rReq.AppendItem( SfxDocumentInfoItem( GetTitle(), 462 getDocProperties(), IsUseUserData() ) ); 463 } 464 465 rReq.Done(); 466 } 467 else 468 // nothing done; no recording 469 rReq.Ignore(); 470 471 delete pDlg; 472 } 473 474 return; 475 } 476 477 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 478 479 case SID_EXPORTDOCASPDF: 480 case SID_DIRECTEXPORTDOCASPDF: 481 bIsPDFExport = sal_True; 482 case SID_EXPORTDOC: 483 case SID_SAVEASDOC: 484 case SID_SAVEDOC: 485 { 486 // derived class may decide to abort this 487 if( !QuerySlotExecutable( nId ) ) 488 { 489 rReq.SetReturnValue( SfxBoolItem( 0, sal_False ) ); 490 return; 491 } 492 493 //!! detaillierte Auswertung eines Fehlercodes 494 SfxObjectShellRef xLock( this ); 495 496 // the model can not be closed till the end of this method 497 // if somebody tries to close it during this time the model will be closed 498 // at the end of the method 499 aModelGuard.Init_Impl( uno::Reference< util::XCloseable >( GetModel(), uno::UNO_QUERY ) ); 500 501 sal_Bool bDialogUsed = sal_False; 502 sal_uInt32 nErrorCode = ERRCODE_NONE; 503 504 // by default versions should be preserved always except in case of an explicit 505 // SaveAs via GUI, so the flag must be set accordingly 506 pImp->bPreserveVersions = (nId == SID_SAVEDOC); 507 try 508 { 509 SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, GetTitle() ); // ??? 510 511 if ( nId == SID_SAVEASDOC ) 512 { 513 // in case of plugin mode the SaveAs operation means SaveTo 514 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, sal_False ); 515 if ( pViewOnlyItem && pViewOnlyItem->GetValue() ) 516 rReq.AppendItem( SfxBoolItem( SID_SAVETO, sal_True ) ); 517 } 518 519 // TODO/LATER: do the following GUI related actions in standalone method 520 // ======================================================================================================== 521 // Introduce a status indicator for GUI operation 522 SFX_REQUEST_ARG( rReq, pStatusIndicatorItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False ); 523 if ( !pStatusIndicatorItem ) 524 { 525 // get statusindicator 526 uno::Reference< task::XStatusIndicator > xStatusIndicator; 527 uno::Reference < frame::XController > xCtrl( GetModel()->getCurrentController() ); 528 if ( xCtrl.is() ) 529 { 530 uno::Reference< task::XStatusIndicatorFactory > xStatFactory( xCtrl->getFrame(), uno::UNO_QUERY ); 531 if( xStatFactory.is() ) 532 xStatusIndicator = xStatFactory->createStatusIndicator(); 533 } 534 535 OSL_ENSURE( xStatusIndicator.is(), "Can not retrieve default status indicator!\n" ); 536 537 if ( xStatusIndicator.is() ) 538 { 539 SfxUnoAnyItem aStatIndItem( SID_PROGRESS_STATUSBAR_CONTROL, uno::makeAny( xStatusIndicator ) ); 540 541 if ( nId == SID_SAVEDOC ) 542 { 543 // in case of saving it is not possible to transport the parameters from here 544 // but it is not clear here whether the saving will be done or saveAs operation 545 GetMedium()->GetItemSet()->Put( aStatIndItem ); 546 } 547 548 rReq.AppendItem( aStatIndItem ); 549 } 550 } 551 else if ( nId == SID_SAVEDOC ) 552 { 553 // in case of saving it is not possible to transport the parameters from here 554 // but it is not clear here whether the saving will be done or saveAs operation 555 GetMedium()->GetItemSet()->Put( *pStatusIndicatorItem ); 556 } 557 558 // Introduce an interaction handler for GUI operation 559 SFX_REQUEST_ARG( rReq, pInteractionHandlerItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False ); 560 if ( !pInteractionHandlerItem ) 561 { 562 uno::Reference< task::XInteractionHandler > xInteract; 563 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); 564 if( xServiceManager.is() ) 565 { 566 xInteract = Reference< XInteractionHandler >( 567 xServiceManager->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), 568 UNO_QUERY ); 569 } 570 571 OSL_ENSURE( xInteract.is(), "Can not retrieve default status indicator!\n" ); 572 if ( xInteract.is() ) 573 { 574 SfxUnoAnyItem aInteractionItem( SID_INTERACTIONHANDLER, uno::makeAny( xInteract ) ); 575 if ( nId == SID_SAVEDOC ) 576 { 577 // in case of saving it is not possible to transport the parameters from here 578 // but it is not clear here whether the saving will be done or saveAs operation 579 GetMedium()->GetItemSet()->Put( aInteractionItem ); 580 } 581 582 rReq.AppendItem( aInteractionItem ); 583 } 584 } 585 else if ( nId == SID_SAVEDOC ) 586 { 587 // in case of saving it is not possible to transport the parameters from here 588 // but it is not clear here whether the saving will be done or saveAs operation 589 GetMedium()->GetItemSet()->Put( *pInteractionHandlerItem ); 590 } 591 // ======================================================================================================== 592 593 sal_Bool bPreselectPassword = sal_False; 594 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); 595 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldPasswordItem, SfxStringItem, SID_PASSWORD, sal_False ); 596 if ( pOldEncryptionDataItem || pOldPasswordItem ) 597 bPreselectPassword = sal_True; 598 599 uno::Sequence< beans::PropertyValue > aDispatchArgs; 600 if ( rReq.GetArgs() ) 601 TransformItems( nId, 602 *rReq.GetArgs(), 603 aDispatchArgs, 604 NULL ); 605 606 const SfxSlot* pSlot = GetModule()->GetSlotPool()->GetSlot( nId ); 607 if ( !pSlot ) 608 throw uno::Exception(); 609 610 uno::Reference< lang::XMultiServiceFactory > xEmptyFactory; 611 SfxStoringHelper aHelper( xEmptyFactory ); 612 613 if ( QueryHiddenInformation( bIsPDFExport ? WhenCreatingPDF : WhenSaving, NULL ) == RET_YES ) 614 { 615 bDialogUsed = aHelper.GUIStoreModel( GetModel(), 616 ::rtl::OUString::createFromAscii( pSlot->GetUnoName() ), 617 aDispatchArgs, 618 bPreselectPassword, 619 GetSharedFileURL(), 620 GetDocumentSignatureState() ); 621 } 622 else 623 { 624 // the user has decided not to store the document 625 throw task::ErrorCodeIOException( ::rtl::OUString(), 626 uno::Reference< uno::XInterface >(), 627 ERRCODE_IO_ABORT ); 628 } 629 630 // merge aDispatchArgs to the request 631 SfxAllItemSet aResultParams( GetPool() ); 632 TransformParameters( nId, 633 aDispatchArgs, 634 aResultParams, 635 NULL ); 636 rReq.SetArgs( aResultParams ); 637 638 SFX_REQUEST_ARG( rReq, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False ); 639 ::rtl::OUString aFilterName = pFilterNameItem ? ::rtl::OUString( pFilterNameItem->GetValue() ) 640 : ::rtl::OUString(); 641 const SfxFilter* pFilt = GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ); 642 643 OSL_ENSURE( nId == SID_SAVEDOC || pFilt, "The filter can not be zero since it was used for storing!\n" ); 644 if ( bDialogUsed && pFilt 645 && pFilt->IsOwnFormat() 646 && pFilt->UsesStorage() 647 && pFilt->GetVersion() >= SOFFICE_FILEFORMAT_60 ) 648 { 649 SfxViewFrame* pDocViewFrame = SfxViewFrame::GetFirst( this ); 650 if ( pDocViewFrame ) 651 SfxHelp::OpenHelpAgent( &pDocViewFrame->GetFrame(), HID_DID_SAVE_PACKED_XML ); 652 } 653 654 // the StoreAsURL/StoreToURL method have called this method with false 655 // so it has to be restored to true here since it is a call from GUI 656 GetMedium()->SetUpdatePickList( sal_True ); 657 658 // TODO: in future it must be done in followind way 659 // if document is opened from GUI it is immediately appeares in the picklist 660 // if the document is a new one then it appeares in the picklist immediately 661 // after SaveAs operation triggered from GUI 662 } 663 catch( task::ErrorCodeIOException& aErrorEx ) 664 { 665 nErrorCode = (sal_uInt32)aErrorEx.ErrCode; 666 } 667 catch( Exception& ) 668 { 669 nErrorCode = ERRCODE_IO_GENERAL; 670 } 671 672 // by default versions should be preserved always except in case of an explicit 673 // SaveAs via GUI, so the flag must be reset to guarantee this 674 pImp->bPreserveVersions = sal_True; 675 sal_uIntPtr lErr=GetErrorCode(); 676 677 if ( !lErr && nErrorCode ) 678 lErr = nErrorCode; 679 680 if ( lErr && nErrorCode == ERRCODE_NONE ) 681 { 682 SFX_REQUEST_ARG( rReq, pWarnItem, SfxBoolItem, SID_FAIL_ON_WARNING, sal_False ); 683 if ( pWarnItem && pWarnItem->GetValue() ) 684 nErrorCode = lErr; 685 } 686 687 // may be nErrorCode should be shown in future 688 if ( lErr != ERRCODE_IO_ABORT ) 689 { 690 SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC,GetTitle()); 691 ErrorHandler::HandleError( lErr ); 692 } 693 694 if ( nId == SID_EXPORTDOCASPDF ) 695 { 696 // This function is used by the SendMail function that needs information if a export 697 // file was written or not. This could be due to cancellation of the export 698 // or due to an error. So IO abort must be handled like an error! 699 nErrorCode = ( lErr != ERRCODE_IO_ABORT ) && ( nErrorCode == ERRCODE_NONE ) ? nErrorCode : lErr; 700 } 701 702 rReq.SetReturnValue( SfxBoolItem(0, nErrorCode == ERRCODE_NONE ) ); 703 704 ResetError(); 705 706 Invalidate(); 707 break; 708 } 709 710 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 711 712 case SID_CLOSEDOC: 713 { 714 SfxViewFrame *pFrame = GetFrame(); 715 if ( pFrame && pFrame->GetFrame().GetParentFrame() ) 716 { 717 // Wenn SID_CLOSEDOC "uber Menue etc. ausgef"uhrt wird, das 718 // aktuelle Dokument aber in einem Frame liegt, soll eigentlich 719 // das FrameSetDocument geclosed werden 720 pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq ); 721 rReq.Done(); 722 return; 723 } 724 725 sal_Bool bInFrameSet = sal_False; 726 sal_uInt16 nFrames=0; 727 pFrame = SfxViewFrame::GetFirst( this ); 728 while ( pFrame ) 729 { 730 if ( pFrame->GetFrame().GetParentFrame() ) 731 { 732 // Auf dieses Dokument existiert noch eine Sicht, die 733 // in einem FrameSet liegt; diese darf nat"urlich nicht 734 // geclosed werden 735 bInFrameSet = sal_True; 736 } 737 else 738 nFrames++; 739 740 pFrame = SfxViewFrame::GetNext( *pFrame, this ); 741 } 742 743 if ( bInFrameSet ) 744 { 745 // Alle Sichten, die nicht in einem FrameSet liegen, closen 746 pFrame = SfxViewFrame::GetFirst( this ); 747 while ( pFrame ) 748 { 749 if ( !pFrame->GetFrame().GetParentFrame() ) 750 pFrame->GetFrame().DoClose(); 751 pFrame = SfxViewFrame::GetNext( *pFrame, this ); 752 } 753 } 754 755 // Parameter auswerten 756 SFX_REQUEST_ARG(rReq, pSaveItem, SfxBoolItem, SID_CLOSEDOC_SAVE, sal_False); 757 SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_CLOSEDOC_FILENAME, sal_False); 758 if ( pSaveItem ) 759 { 760 if ( pSaveItem->GetValue() ) 761 { 762 if ( !pNameItem ) 763 { 764 SbxBase::SetError( SbxERR_WRONG_ARGS ); 765 rReq.Ignore(); 766 return; 767 } 768 SfxAllItemSet aArgs( GetPool() ); 769 SfxStringItem aTmpItem( SID_FILE_NAME, pNameItem->GetValue() ); 770 aArgs.Put( aTmpItem, aTmpItem.Which() ); 771 SfxRequest aSaveAsReq( SID_SAVEASDOC, SFX_CALLMODE_API, aArgs ); 772 ExecFile_Impl( aSaveAsReq ); 773 if ( !aSaveAsReq.IsDone() ) 774 { 775 rReq.Ignore(); 776 return; 777 } 778 } 779 else 780 SetModified(sal_False); 781 } 782 783 // Benutzer bricht ab? 784 if ( !PrepareClose( 2 ) ) 785 { 786 rReq.SetReturnValue( SfxBoolItem(0, sal_False) ); 787 rReq.Done(); 788 return; 789 } 790 791 SetModified( sal_False ); 792 sal_uIntPtr lErr = GetErrorCode(); 793 ErrorHandler::HandleError(lErr); 794 795 rReq.SetReturnValue( SfxBoolItem(0, sal_True) ); 796 rReq.Done(); 797 rReq.ReleaseArgs(); // da der Pool in Close zerst"ort wird 798 DoClose(); 799 return; 800 } 801 802 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 803 case SID_DOCTEMPLATE: 804 { 805 // speichern als Dokumentvorlagen 806 SfxDocumentTemplateDlg *pDlg = 0; 807 SfxErrorContext aEc(ERRCTX_SFX_DOCTEMPLATE,GetTitle()); 808 SfxDocumentTemplates *pTemplates = new SfxDocumentTemplates; 809 810 if ( !rReq.GetArgs() ) 811 { 812 pDlg = new SfxDocumentTemplateDlg(0, pTemplates); 813 if ( RET_OK == pDlg->Execute() && pDlg->GetTemplateName().Len()) 814 { 815 rReq.AppendItem(SfxStringItem( 816 SID_TEMPLATE_NAME, pDlg->GetTemplateName())); 817 rReq.AppendItem(SfxStringItem( 818 SID_TEMPLATE_REGIONNAME, pDlg->GetRegionName())); 819 } 820 else 821 { 822 delete pDlg; 823 rReq.Ignore(); 824 return; 825 } 826 } 827 828 SFX_REQUEST_ARG(rReq, pRegionItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, sal_False); 829 SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False); 830 SFX_REQUEST_ARG(rReq, pRegionNrItem, SfxUInt16Item, SID_TEMPLATE_REGION, sal_False); 831 if ( (!pRegionItem && !pRegionNrItem ) || !pNameItem ) 832 { 833 DBG_ASSERT( rReq.IsAPI(), "non-API call without Arguments" ); 834 SbxBase::SetError( SbxERR_WRONG_ARGS ); 835 rReq.Ignore(); 836 return; 837 } 838 839 ::rtl::OUString aTemplateName = pNameItem->GetValue(); 840 ::rtl::OUString aTemplateGroup; 841 if ( pRegionItem ) 842 aTemplateGroup = pRegionItem->GetValue(); 843 else 844 // pRegionNrItem must not be NULL, it was just checked 845 aTemplateGroup = pTemplates->GetFullRegionName( pRegionNrItem->GetValue() ); 846 // check Group and Name 847 delete pTemplates; 848 849 sal_Bool bOk = sal_False; 850 try 851 { 852 uno::Reference< frame::XStorable > xStorable( GetModel(), uno::UNO_QUERY_THROW ); 853 ::rtl::OUString aService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.DocumentTemplates" ) ); 854 uno::Reference< frame::XDocumentTemplates > xTemplates( 855 comphelper::getProcessServiceFactory()->createInstance( aService ), 856 uno::UNO_QUERY_THROW ); 857 858 bOk = xTemplates->storeTemplate( aTemplateGroup, aTemplateName, xStorable ); 859 } 860 catch( uno::Exception& ) 861 { 862 } 863 864 DELETEX(pDlg); 865 866 rReq.SetReturnValue( SfxBoolItem( 0, bOk ) ); 867 if ( bOk ) 868 { 869 // update the Organizer runtime cache from the template component if the cache has already been created 870 // TODO/LATER: get rid of this cache duplication 871 SfxDocumentTemplates aTemplates; 872 aTemplates.ReInitFromComponent(); 873 } 874 else 875 { 876 ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); 877 return; 878 } 879 880 break; 881 } 882 } 883 884 // Picklisten-Eintrag verhindern 885 if ( rReq.IsAPI() ) 886 GetMedium()->SetUpdatePickList( sal_False ); 887 else if ( rReq.GetArgs() ) 888 { 889 SFX_ITEMSET_GET( *rReq.GetArgs(), pPicklistItem, SfxBoolItem, SID_PICKLIST, sal_False ); 890 if ( pPicklistItem ) 891 GetMedium()->SetUpdatePickList( pPicklistItem->GetValue() ); 892 } 893 894 // Ignore()-Zweige haben schon returnt 895 rReq.Done(); 896 } 897 898 //------------------------------------------------------------------------- 899 900 void SfxObjectShell::GetState_Impl(SfxItemSet &rSet) 901 { 902 DBG_CHKTHIS(SfxObjectShell, 0); 903 SfxWhichIter aIter( rSet ); 904 905 for ( sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich() ) 906 { 907 switch ( nWhich ) 908 { 909 case SID_DOCTEMPLATE : 910 { 911 if ( !GetFactory().GetTemplateFilter() ) 912 rSet.DisableItem( nWhich ); 913 break; 914 } 915 916 case SID_VERSION: 917 { 918 SfxObjectShell *pDoc = this; 919 SfxViewFrame* pFrame = GetFrame(); 920 if ( !pFrame ) 921 pFrame = SfxViewFrame::GetFirst( this ); 922 if ( pFrame ) 923 { 924 if ( pFrame->GetFrame().GetParentFrame() ) 925 { 926 pFrame = pFrame->GetTopViewFrame(); 927 pDoc = pFrame->GetObjectShell(); 928 } 929 } 930 931 if ( !pFrame || !pDoc->HasName() || 932 !IsOwnStorageFormat_Impl( *pDoc->GetMedium() ) ) 933 //REMOVE || pDoc->GetMedium()->GetStorage()->GetVersion() < SOFFICE_FILEFORMAT_50 ) 934 rSet.DisableItem( nWhich ); 935 break; 936 } 937 case SID_SAVEDOC: 938 { 939 sal_Bool bMediumRO = IsReadOnlyMedium(); 940 if ( !bMediumRO && GetMedium() && IsModified() ) 941 rSet.Put(SfxStringItem( 942 nWhich, String(SfxResId(STR_SAVEDOC)))); 943 else 944 rSet.DisableItem(nWhich); 945 } 946 break; 947 948 case SID_DOCINFO: 949 if ( 0 != ( pImp->eFlags & SFXOBJECTSHELL_NODOCINFO ) ) 950 rSet.DisableItem( nWhich ); 951 break; 952 953 case SID_CLOSEDOC: 954 { 955 SfxObjectShell *pDoc = this; 956 SfxViewFrame *pFrame = GetFrame(); 957 if ( pFrame && pFrame->GetFrame().GetParentFrame() ) 958 { 959 // Wenn SID_CLOSEDOC "uber Menue etc. ausgef"uhrt wird, das 960 // aktuelle Dokument aber in einem Frame liegt, soll eigentlich 961 // das FrameSetDocument geclosed werden 962 pDoc = pFrame->GetTopViewFrame()->GetObjectShell(); 963 } 964 965 if ( pDoc->GetFlags() & SFXOBJECTSHELL_DONTCLOSE ) 966 rSet.DisableItem(nWhich); 967 else 968 rSet.Put(SfxStringItem(nWhich, String(SfxResId(STR_CLOSEDOC)))); 969 break; 970 } 971 972 case SID_SAVEASDOC: 973 { 974 if( ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) != SFX_LOADED_MAINDOCUMENT ) 975 { 976 rSet.DisableItem( nWhich ); 977 break; 978 } 979 /* 980 const SfxFilter* pCombinedFilters = NULL; 981 SfxFilterContainer* pFilterContainer = GetFactory().GetFilterContainer(); 982 983 if ( pFilterContainer ) 984 { 985 SfxFilterFlags nMust = SFX_FILTER_IMPORT | SFX_FILTER_EXPORT; 986 SfxFilterFlags nDont = SFX_FILTER_NOTINSTALLED | SFX_FILTER_INTERNAL; 987 988 pCombinedFilters = pFilterContainer->GetAnyFilter( nMust, nDont ); 989 } 990 */ 991 if ( /*!pCombinedFilters ||*/ !GetMedium() ) 992 rSet.DisableItem( nWhich ); 993 else 994 rSet.Put( SfxStringItem( nWhich, String( SfxResId( STR_SAVEASDOC ) ) ) ); 995 break; 996 } 997 998 case SID_EXPORTDOCASPDF: 999 case SID_DIRECTEXPORTDOCASPDF: 1000 { 1001 /* 1002 1003 search for filter can't work correctly ... 1004 Because it's not clear, which export filter for which office module 1005 must be searched. On the other side it can be very expensive doing so. 1006 The best solution would be: on installation time we should know if pdf feature 1007 was installed or not!!! (e.g. by writing a bool inside cfg) 1008 1009 SfxFilterContainer* pFilterContainer = GetFactory().GetFilterContainer(); 1010 if ( pFilterContainer ) 1011 { 1012 String aPDFExtension = String::CreateFromAscii( "pdf" ); 1013 const SfxFilter* pFilter = pFilterContainer->GetFilter4Extension( aPDFExtension, SFX_FILTER_EXPORT ); 1014 if ( pFilter != NULL ) 1015 break; 1016 } 1017 1018 rSet.DisableItem( nWhich ); 1019 */ 1020 break; 1021 } 1022 1023 case SID_DOC_MODIFIED: 1024 { 1025 rSet.Put( SfxStringItem( SID_DOC_MODIFIED, IsModified() ? '*' : ' ' ) ); 1026 break; 1027 } 1028 1029 case SID_MODIFIED: 1030 { 1031 rSet.Put( SfxBoolItem( SID_MODIFIED, IsModified() ) ); 1032 break; 1033 } 1034 1035 case SID_DOCINFO_TITLE: 1036 { 1037 rSet.Put( SfxStringItem( 1038 SID_DOCINFO_TITLE, getDocProperties()->getTitle() ) ); 1039 break; 1040 } 1041 case SID_FILE_NAME: 1042 { 1043 if( GetMedium() && HasName() ) 1044 rSet.Put( SfxStringItem( 1045 SID_FILE_NAME, GetMedium()->GetName() ) ); 1046 break; 1047 } 1048 case SID_SIGNATURE: 1049 { 1050 rSet.Put( SfxUInt16Item( SID_SIGNATURE, GetDocumentSignatureState() ) ); 1051 break; 1052 } 1053 case SID_MACRO_SIGNATURE: 1054 { 1055 // the slot makes sense only if there is a macro in the document 1056 if ( pImp->documentStorageHasMacros() || pImp->aMacroMode.hasMacroLibrary() ) 1057 rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) ); 1058 else 1059 rSet.DisableItem( nWhich ); 1060 break; 1061 } 1062 } 1063 } 1064 } 1065 1066 //-------------------------------------------------------------------- 1067 1068 void SfxObjectShell::ExecProps_Impl(SfxRequest &rReq) 1069 { 1070 switch ( rReq.GetSlot() ) 1071 { 1072 case SID_MODIFIED: 1073 { 1074 SetModified( ( (SfxBoolItem&) rReq.GetArgs()->Get(SID_MODIFIED)).GetValue() ); 1075 rReq.Done(); 1076 break; 1077 } 1078 1079 case SID_DOCTITLE: 1080 SetTitle( ( (SfxStringItem&) rReq.GetArgs()->Get(SID_DOCTITLE)).GetValue() ); 1081 rReq.Done(); 1082 break; 1083 1084 case SID_DOCINFO_AUTHOR : 1085 { 1086 ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue(); 1087 getDocProperties()->setAuthor( aStr ); 1088 break; 1089 } 1090 1091 case SID_DOCINFO_COMMENTS : 1092 { 1093 ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue(); 1094 getDocProperties()->setDescription( aStr ); 1095 break; 1096 } 1097 1098 case SID_DOCINFO_KEYWORDS : 1099 { 1100 ::rtl::OUString aStr = ( (SfxStringItem&)rReq.GetArgs()->Get(rReq.GetSlot())).GetValue(); 1101 getDocProperties()->setKeywords( 1102 ::comphelper::string::convertCommaSeparated(aStr) ); 1103 break; 1104 } 1105 } 1106 } 1107 1108 //-------------------------------------------------------------------- 1109 1110 void SfxObjectShell::StateProps_Impl(SfxItemSet &rSet) 1111 { 1112 SfxWhichIter aIter(rSet); 1113 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() ) 1114 { 1115 switch ( nSID ) 1116 { 1117 case SID_DOCINFO_AUTHOR : 1118 { 1119 rSet.Put( SfxStringItem( nSID, 1120 getDocProperties()->getAuthor() ) ); 1121 break; 1122 } 1123 1124 case SID_DOCINFO_COMMENTS : 1125 { 1126 rSet.Put( SfxStringItem( nSID, 1127 getDocProperties()->getDescription()) ); 1128 break; 1129 } 1130 1131 case SID_DOCINFO_KEYWORDS : 1132 { 1133 rSet.Put( SfxStringItem( nSID, ::comphelper::string:: 1134 convertCommaSeparated(getDocProperties()->getKeywords())) ); 1135 break; 1136 } 1137 1138 case SID_DOCPATH: 1139 { 1140 DBG_ERROR( "Not supported anymore!" ); 1141 break; 1142 } 1143 1144 case SID_DOCFULLNAME: 1145 { 1146 rSet.Put( SfxStringItem( SID_DOCFULLNAME, GetTitle(SFX_TITLE_FULLNAME) ) ); 1147 break; 1148 } 1149 1150 case SID_DOCTITLE: 1151 { 1152 rSet.Put( SfxStringItem( SID_DOCTITLE, GetTitle() ) ); 1153 break; 1154 } 1155 1156 case SID_DOC_READONLY: 1157 { 1158 rSet.Put( SfxBoolItem( SID_DOC_READONLY, IsReadOnly() ) ); 1159 break; 1160 } 1161 1162 case SID_DOC_SAVED: 1163 { 1164 rSet.Put( SfxBoolItem( SID_DOC_SAVED, !IsModified() ) ); 1165 break; 1166 } 1167 1168 case SID_CLOSING: 1169 { 1170 rSet.Put( SfxBoolItem( SID_CLOSING, false ) ); 1171 break; 1172 } 1173 1174 case SID_DOC_LOADING: 1175 rSet.Put( SfxBoolItem( nSID, SFX_LOADED_MAINDOCUMENT != 1176 ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) ) ); 1177 break; 1178 1179 case SID_IMG_LOADING: 1180 rSet.Put( SfxBoolItem( nSID, SFX_LOADED_IMAGES != 1181 ( pImp->nLoadedFlags & SFX_LOADED_IMAGES ) ) ); 1182 break; 1183 } 1184 } 1185 } 1186 1187 //-------------------------------------------------------------------- 1188 1189 void SfxObjectShell::ExecView_Impl(SfxRequest &rReq) 1190 { 1191 switch ( rReq.GetSlot() ) 1192 { 1193 case SID_ACTIVATE: 1194 { 1195 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this, sal_True ); 1196 if ( pFrame ) 1197 pFrame->GetFrame().Appear(); 1198 rReq.SetReturnValue( SfxObjectItem( 0, pFrame ) ); 1199 rReq.Done(); 1200 break; 1201 } 1202 case SID_NEWWINDOWFOREDIT: 1203 { 1204 SfxViewFrame* pFrame = SfxViewFrame::Current(); 1205 if( pFrame->GetObjectShell() == this && 1206 ( pFrame->GetFrameType() & SFXFRAME_HASTITLE ) ) 1207 pFrame->ExecuteSlot( rReq ); 1208 else 1209 { 1210 String aFileName( GetObjectShell()->GetMedium()->GetName() ); 1211 if ( aFileName.Len() ) 1212 { 1213 SfxStringItem aName( SID_FILE_NAME, aFileName ); 1214 SfxBoolItem aCreateView( SID_OPEN_NEW_VIEW, sal_True ); 1215 SFX_APP()->GetAppDispatcher_Impl()->Execute( 1216 SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aName, 1217 &aCreateView, 0L); 1218 } 1219 } 1220 } 1221 } 1222 } 1223 1224 //-------------------------------------------------------------------- 1225 1226 void SfxObjectShell::StateView_Impl(SfxItemSet& /*rSet*/) 1227 { 1228 } 1229 1230 sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< security::DocumentSignatureInformation >& aInfos ) 1231 { 1232 sal_Bool bCertValid = sal_True; 1233 sal_uInt16 nResult = SIGNATURESTATE_NOSIGNATURES; 1234 int nInfos = aInfos.getLength(); 1235 bool bCompleteSignature = true; 1236 if( nInfos ) 1237 { 1238 nResult = SIGNATURESTATE_SIGNATURES_OK; 1239 for ( int n = 0; n < nInfos; n++ ) 1240 { 1241 if ( bCertValid ) 1242 { 1243 sal_Int32 nCertStat = aInfos[n].CertificateStatus; 1244 bCertValid = nCertStat == security::CertificateValidity::VALID ? sal_True : sal_False; 1245 } 1246 1247 if ( !aInfos[n].SignatureIsValid ) 1248 { 1249 nResult = SIGNATURESTATE_SIGNATURES_BROKEN; 1250 break; // we know enough 1251 } 1252 bCompleteSignature &= !aInfos[n].PartialDocumentSignature; 1253 } 1254 } 1255 1256 if ( nResult == SIGNATURESTATE_SIGNATURES_OK && !bCertValid ) 1257 nResult = SIGNATURESTATE_SIGNATURES_NOTVALIDATED; 1258 else if ( nResult == SIGNATURESTATE_SIGNATURES_OK && bCertValid && !bCompleteSignature) 1259 nResult = SIGNATURESTATE_SIGNATURES_PARTIAL_OK; 1260 1261 // this code must not check whether the document is modified 1262 // it should only check the provided info 1263 1264 return nResult; 1265 } 1266 1267 uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( sal_Bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner ) 1268 { 1269 uno::Sequence< security::DocumentSignatureInformation > aResult; 1270 uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner; 1271 1272 if ( GetMedium() && GetMedium()->GetName().Len() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() ) 1273 { 1274 try 1275 { 1276 if ( !xLocSigner.is() ) 1277 { 1278 uno::Sequence< uno::Any > aArgs( 1 ); 1279 aArgs[0] <<= ::rtl::OUString(); 1280 try 1281 { 1282 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); 1283 aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ); 1284 } 1285 catch( uno::Exception& ) 1286 { 1287 } 1288 1289 xLocSigner.set( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW ); 1290 1291 } 1292 1293 if ( bScriptingContent ) 1294 aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), 1295 uno::Reference< io::XInputStream >() ); 1296 else 1297 aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), 1298 uno::Reference< io::XInputStream >() ); 1299 } 1300 catch( com::sun::star::uno::Exception& ) 1301 { 1302 } 1303 } 1304 1305 return aResult; 1306 } 1307 1308 sal_uInt16 SfxObjectShell::ImplGetSignatureState( sal_Bool bScriptingContent ) 1309 { 1310 sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState; 1311 1312 if ( *pState == SIGNATURESTATE_UNKNOWN ) 1313 { 1314 *pState = SIGNATURESTATE_NOSIGNATURES; 1315 1316 uno::Sequence< security::DocumentSignatureInformation > aInfos = ImplAnalyzeSignature( bScriptingContent ); 1317 *pState = ImplCheckSignaturesInformation( aInfos ); 1318 } 1319 1320 if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED 1321 || *pState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK) 1322 { 1323 if ( IsModified() ) 1324 *pState = SIGNATURESTATE_SIGNATURES_INVALID; 1325 } 1326 1327 return (sal_uInt16)*pState; 1328 } 1329 1330 void SfxObjectShell::ImplSign( sal_Bool bScriptingContent ) 1331 { 1332 // Check if it is stored in OASIS format... 1333 if ( GetMedium() 1334 && GetMedium()->GetFilter() 1335 && GetMedium()->GetName().Len() 1336 && ( !GetMedium()->GetFilter()->IsOwnFormat() 1337 || !GetMedium()->HasStorage_Impl() 1338 ) 1339 ) 1340 { 1341 // Only OASIS and OOo6.x formats will be handled further 1342 InfoBox( NULL, SfxResId( RID_XMLSEC_INFO_WRONGDOCFORMAT ) ).Execute(); 1343 return; 1344 } 1345 1346 // check whether the document is signed 1347 ImplGetSignatureState( sal_False ); // document signature 1348 ImplGetSignatureState( sal_True ); // script signature 1349 sal_Bool bHasSign = ( pImp->nScriptingSignatureState != SIGNATURESTATE_NOSIGNATURES || pImp->nDocumentSignatureState != SIGNATURESTATE_NOSIGNATURES ); 1350 1351 // the target ODF version on saving 1352 SvtSaveOptions aSaveOpt; 1353 SvtSaveOptions::ODFDefaultVersion nVersion = aSaveOpt.GetODFDefaultVersion(); 1354 1355 // the document is not new and is not modified 1356 ::rtl::OUString aODFVersion; 1357 try 1358 { 1359 // check the version of the document 1360 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); 1361 xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aODFVersion; 1362 } 1363 catch( uno::Exception& ) 1364 {} 1365 1366 bool bNoSig = false; 1367 1368 if ( IsModified() || !GetMedium() || !GetMedium()->GetName().Len() 1369 || (!aODFVersion.equals( ODFVER_012_TEXT ) && !bHasSign) ) 1370 { 1371 // the document might need saving ( new, modified or in ODF1.1 format without signature ) 1372 1373 if ( nVersion >= SvtSaveOptions::ODFVER_012 ) 1374 { 1375 1376 if ( (bHasSign && QueryBox( NULL, SfxResId( MSG_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN ) ).Execute() == RET_YES) 1377 || (!bHasSign && QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_SAVEBEFORESIGN ) ).Execute() == RET_YES) ) 1378 { 1379 sal_uInt16 nId = SID_SAVEDOC; 1380 if ( !GetMedium() || !GetMedium()->GetName().Len() ) 1381 nId = SID_SAVEASDOC; 1382 SfxRequest aSaveRequest( nId, 0, GetPool() ); 1383 //ToDo: Review. We needed to call SetModified, otherwise the document would not be saved. 1384 SetModified(sal_True); 1385 ExecFile_Impl( aSaveRequest ); 1386 1387 // Check if it is stored in OASIS format... 1388 if ( GetMedium() && GetMedium()->GetFilter() 1389 && ( !GetMedium()->GetFilter()->IsOwnFormat() || !GetMedium()->HasStorage_Impl() 1390 || SotStorage::GetVersion( GetMedium()->GetStorage() ) <= SOFFICE_FILEFORMAT_60 ) ) 1391 { 1392 // Only OASIS format will be handled further 1393 InfoBox( NULL, SfxResId( RID_XMLSEC_INFO_WRONGDOCFORMAT ) ).Execute(); 1394 return; 1395 } 1396 } 1397 else 1398 { 1399 //When the document is modified then we must not show the digital signatures dialog 1400 //If we have come here then the user denied to save. 1401 if (!bHasSign) 1402 bNoSig = true; 1403 } 1404 } 1405 else 1406 { 1407 ErrorBox( NULL, WB_OK, SfxResId( STR_XMLSEC_ODF12_EXPECTED ) ).Execute(); 1408 return; 1409 } 1410 1411 if ( IsModified() || !GetMedium() || !GetMedium()->GetName().Len() ) 1412 return; 1413 } 1414 1415 // the document is not modified currently, so it can not become modified after signing 1416 sal_Bool bAllowModifiedBack = sal_False; 1417 if ( IsEnableSetModified() ) 1418 { 1419 EnableSetModified( sal_False ); 1420 bAllowModifiedBack = sal_True; 1421 } 1422 1423 // we have to store to the original document, the original medium should be closed for this time 1424 if ( !bNoSig 1425 && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) ) 1426 { 1427 GetMedium()->CloseAndRelease(); 1428 1429 // We sign only ODF1.2, that means that if this point has been reached, 1430 // the ODF1.2 signing process should be used. 1431 // This code still might be called to show the signature of ODF1.1 document. 1432 sal_Bool bSigned = GetMedium()->SignContents_Impl( 1433 bScriptingContent, 1434 aODFVersion, 1435 pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_OK 1436 || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED 1437 || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK); 1438 1439 DoSaveCompleted( GetMedium() ); 1440 1441 if ( bSigned ) 1442 { 1443 if ( bScriptingContent ) 1444 { 1445 pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check 1446 1447 // adding of scripting signature removes existing document signature 1448 pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check 1449 } 1450 else 1451 pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check 1452 1453 pImp->bSignatureErrorIsShown = sal_False; 1454 1455 Invalidate( SID_SIGNATURE ); 1456 Invalidate( SID_MACRO_SIGNATURE ); 1457 Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) ); 1458 } 1459 } 1460 1461 if ( bAllowModifiedBack ) 1462 EnableSetModified( sal_True ); 1463 } 1464 1465 sal_uInt16 SfxObjectShell::GetDocumentSignatureState() 1466 { 1467 return ImplGetSignatureState( sal_False ); 1468 } 1469 1470 void SfxObjectShell::SignDocumentContent() 1471 { 1472 ImplSign( sal_False ); 1473 } 1474 1475 sal_uInt16 SfxObjectShell::GetScriptingSignatureState() 1476 { 1477 return ImplGetSignatureState( sal_True ); 1478 } 1479 1480 void SfxObjectShell::SignScriptingContent() 1481 { 1482 ImplSign( sal_True ); 1483 } 1484 1485 // static 1486 const uno::Sequence<sal_Int8>& SfxObjectShell::getUnoTunnelId() 1487 { 1488 static uno::Sequence<sal_Int8> * pSeq = 0; 1489 if( !pSeq ) 1490 { 1491 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 1492 if( !pSeq ) 1493 { 1494 static uno::Sequence< sal_Int8 > aSeq( 16 ); 1495 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 1496 pSeq = &aSeq; 1497 } 1498 } 1499 return *pSeq; 1500 } 1501