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