1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 31 #include <com/sun/star/ui/dialogs/XFilePicker.hpp> 32 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> 33 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> 34 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> 35 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp" 36 #include <com/sun/star/view/XSelectionSupplier.hpp> 37 #include <com/sun/star/beans/XPropertyAccess.hpp> 38 #include <com/sun/star/beans/XPropertySet.hpp> 39 #include <com/sun/star/beans/XPropertyContainer.hpp> 40 #include <com/sun/star/beans/PropertyAttribute.hpp> 41 #include <com/sun/star/document/XExporter.hpp> 42 #include <com/sun/star/document/XDocumentInfoSupplier.hpp> 43 #include <com/sun/star/document/XDocumentInfo.hpp> 44 #include <com/sun/star/task/XInteractionHandler.hpp> 45 #include <com/sun/star/util/DateTime.hpp> 46 #include <com/sun/star/util/XURLTransformer.hpp> 47 #include <com/sun/star/frame/XStorable.hpp> 48 #include <com/sun/star/frame/XStorable2.hpp> 49 #include <com/sun/star/frame/XDispatchProvider.hpp> 50 #include <com/sun/star/frame/XDispatch.hpp> 51 #include <com/sun/star/frame/XTitle.hpp> 52 #include <com/sun/star/util/XModifyListener.hpp> 53 #include <com/sun/star/util/XModifiable.hpp> 54 #include <com/sun/star/util/XModifyBroadcaster.hpp> 55 56 #include <com/sun/star/util/XCloneable.hpp> 57 #include <com/sun/star/frame/XModuleManager.hpp> 58 #include <com/sun/star/io/IOException.hpp> 59 60 #include "guisaveas.hxx" 61 62 #include <unotools/pathoptions.hxx> 63 #include <unotools/pathoptions.hxx> 64 #include <svl/itemset.hxx> 65 #include <svl/eitem.hxx> 66 #include <svl/stritem.hxx> 67 #include <svl/intitem.hxx> 68 #include <unotools/useroptions.hxx> 69 #include <unotools/saveopt.hxx> 70 #include <tools/debug.hxx> 71 #include <tools/urlobj.hxx> 72 #include <comphelper/processfactory.hxx> 73 #include <comphelper/configurationhelper.hxx> 74 #include <comphelper/mimeconfighelper.hxx> 75 #include <vcl/msgbox.hxx> 76 #include <vcl/window.hxx> 77 #include <toolkit/awt/vclxwindow.hxx> 78 79 #include <sfx2/sfxsids.hrc> 80 #include <doc.hrc> 81 #include <sfx2/sfxresid.hxx> 82 #include <sfx2/docfilt.hxx> 83 #include <sfx2/filedlghelper.hxx> 84 #include <sfx2/app.hxx> 85 #include <sfx2/objsh.hxx> 86 #include <sfx2/dinfdlg.hxx> 87 #include <sfx2/request.hxx> 88 #include <sfxtypes.hxx> 89 #include "alienwarn.hxx" 90 91 #include "../appl/app.hrc" 92 93 #define DOCPROPSNUM 17 94 95 // flags that specify requested operation 96 #define EXPORT_REQUESTED 1 97 #define PDFEXPORT_REQUESTED 2 98 #define PDFDIRECTEXPORT_REQUESTED 4 99 #define WIDEEXPORT_REQUESTED 8 100 #define SAVE_REQUESTED 16 101 #define SAVEAS_REQUESTED 32 102 103 // possible statuses of save operation 104 #define STATUS_NO_ACTION 0 105 #define STATUS_SAVE 1 106 #define STATUS_SAVEAS 2 107 #define STATUS_SAVEAS_STANDARDNAME 3 108 109 const ::rtl::OUString aFilterNameString = ::rtl::OUString::createFromAscii( "FilterName" ); 110 const ::rtl::OUString aFilterOptionsString = ::rtl::OUString::createFromAscii( "FilterOptions" ); 111 const ::rtl::OUString aFilterDataString = ::rtl::OUString::createFromAscii( "FilterData" ); 112 const ::rtl::OUString aFilterFlagsString = ::rtl::OUString::createFromAscii( "FilterFlags" ); 113 114 using namespace ::com::sun::star; 115 116 namespace { 117 //------------------------------------------------------------------------- 118 static sal_uInt16 getSlotIDFromMode( sal_Int8 nStoreMode ) 119 { 120 // This is a temporary hardcoded solution must be removed when 121 // dialogs do not need parameters in SidSet representation any more 122 123 sal_uInt16 nResult = 0; 124 if ( nStoreMode == EXPORT_REQUESTED ) 125 nResult = SID_EXPORTDOC; 126 else if ( nStoreMode == ( EXPORT_REQUESTED | PDFEXPORT_REQUESTED ) ) 127 nResult = SID_EXPORTDOCASPDF; 128 else if ( nStoreMode == ( EXPORT_REQUESTED | PDFEXPORT_REQUESTED | PDFDIRECTEXPORT_REQUESTED ) ) 129 nResult = SID_DIRECTEXPORTDOCASPDF; 130 else if ( nStoreMode == SAVEAS_REQUESTED || nStoreMode == ( EXPORT_REQUESTED | WIDEEXPORT_REQUESTED ) ) 131 nResult = SID_SAVEASDOC; 132 else { 133 DBG_ASSERT( sal_False, "Unacceptable slot name is provided!\n" ); 134 } 135 136 return nResult; 137 } 138 139 //------------------------------------------------------------------------- 140 static sal_uInt8 getStoreModeFromSlotName( const ::rtl::OUString& aSlotName ) 141 { 142 sal_uInt8 nResult = 0; 143 if ( aSlotName.equalsAscii( "ExportTo" ) ) 144 nResult = EXPORT_REQUESTED; 145 else if ( aSlotName.equalsAscii( "ExportToPDF" ) ) 146 nResult = EXPORT_REQUESTED | PDFEXPORT_REQUESTED; 147 else if ( aSlotName.equalsAscii( "ExportDirectToPDF" ) ) 148 nResult = EXPORT_REQUESTED | PDFEXPORT_REQUESTED | PDFDIRECTEXPORT_REQUESTED; 149 else if ( aSlotName.equalsAscii( "Save" ) ) 150 nResult = SAVE_REQUESTED; 151 else if ( aSlotName.equalsAscii( "SaveAs" ) ) 152 nResult = SAVEAS_REQUESTED; 153 else 154 throw task::ErrorCodeIOException( ::rtl::OUString(), 155 uno::Reference< uno::XInterface >(), 156 ERRCODE_IO_INVALIDPARAMETER ); 157 158 return nResult; 159 } 160 161 //------------------------------------------------------------------------- 162 static sal_Int32 getMustFlags( sal_Int8 nStoreMode ) 163 { 164 return ( SFX_FILTER_EXPORT 165 | ( ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) ? 0 : SFX_FILTER_IMPORT ) ); 166 } 167 168 //------------------------------------------------------------------------- 169 static sal_Int32 getDontFlags( sal_Int8 nStoreMode ) 170 { 171 return ( SFX_FILTER_INTERNAL 172 | SFX_FILTER_NOTINFILEDLG 173 | ( ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) ? SFX_FILTER_IMPORT : 0 ) ); 174 } 175 176 //========================================================================= 177 // class DocumentSettingsGuard 178 //========================================================================= 179 180 class DocumentSettingsGuard 181 { 182 uno::Reference< beans::XPropertySet > m_xDocumentSettings; 183 sal_Bool m_bPreserveReadOnly; 184 sal_Bool m_bReadOnlySupported; 185 186 sal_Bool m_bRestoreSettings; 187 public: 188 DocumentSettingsGuard( const uno::Reference< frame::XModel >& xModel, sal_Bool bReadOnly, sal_Bool bRestore ) 189 : m_bPreserveReadOnly( sal_False ) 190 , m_bReadOnlySupported( sal_False ) 191 , m_bRestoreSettings( bRestore ) 192 { 193 try 194 { 195 uno::Reference< lang::XMultiServiceFactory > xDocSettingsSupplier( xModel, uno::UNO_QUERY_THROW ); 196 m_xDocumentSettings.set( 197 xDocSettingsSupplier->createInstance( 198 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.Settings" ) ) ), 199 uno::UNO_QUERY_THROW ); 200 201 ::rtl::OUString aLoadReadonlyString( RTL_CONSTASCII_USTRINGPARAM( "LoadReadonly" ) ); 202 203 try 204 { 205 m_xDocumentSettings->getPropertyValue( aLoadReadonlyString ) >>= m_bPreserveReadOnly; 206 m_xDocumentSettings->setPropertyValue( aLoadReadonlyString, uno::makeAny( bReadOnly ) ); 207 m_bReadOnlySupported = sal_True; 208 } 209 catch( uno::Exception& ) 210 {} 211 } 212 catch( uno::Exception& ) 213 {} 214 215 if ( ( bReadOnly && !m_bReadOnlySupported ) ) 216 throw uno::RuntimeException(); // the user could provide the data, so it must be stored 217 } 218 219 ~DocumentSettingsGuard() 220 { 221 if ( m_bRestoreSettings ) 222 { 223 ::rtl::OUString aLoadReadonlyString( RTL_CONSTASCII_USTRINGPARAM( "LoadReadonly" ) ); 224 225 try 226 { 227 if ( m_bReadOnlySupported ) 228 m_xDocumentSettings->setPropertyValue( aLoadReadonlyString, uno::makeAny( m_bPreserveReadOnly ) ); 229 } 230 catch( uno::Exception& ) 231 { 232 OSL_ASSERT( "Unexpected exception!" ); 233 } 234 } 235 } 236 }; 237 } // anonymous namespace 238 239 //========================================================================= 240 // class ModelData_Impl 241 //========================================================================= 242 class ModelData_Impl 243 { 244 SfxStoringHelper* m_pOwner; 245 uno::Reference< frame::XModel > m_xModel; 246 uno::Reference< frame::XStorable > m_xStorable; 247 uno::Reference< frame::XStorable2 > m_xStorable2; 248 uno::Reference< util::XModifiable > m_xModifiable; 249 250 ::rtl::OUString m_aModuleName; 251 ::comphelper::SequenceAsHashMap* m_pDocumentPropsHM; 252 ::comphelper::SequenceAsHashMap* m_pModulePropsHM; 253 254 ::comphelper::SequenceAsHashMap m_aMediaDescrHM; 255 256 sal_Bool m_bRecommendReadOnly; 257 258 public: 259 ModelData_Impl( SfxStoringHelper& aOwner, 260 const uno::Reference< frame::XModel >& xModel, 261 const uno::Sequence< beans::PropertyValue >& aMediaDescr ); 262 263 ~ModelData_Impl(); 264 265 void FreeDocumentProps(); 266 267 uno::Reference< frame::XModel > GetModel(); 268 uno::Reference< frame::XStorable > GetStorable(); 269 uno::Reference< frame::XStorable2 > GetStorable2(); 270 uno::Reference< util::XModifiable > GetModifiable(); 271 272 ::comphelper::SequenceAsHashMap& GetMediaDescr() { return m_aMediaDescrHM; } 273 274 sal_Bool IsRecommendReadOnly() { return m_bRecommendReadOnly; } 275 276 const ::comphelper::SequenceAsHashMap& GetDocProps(); 277 278 ::rtl::OUString GetModuleName(); 279 const ::comphelper::SequenceAsHashMap& GetModuleProps(); 280 281 void CheckInteractionHandler(); 282 283 284 ::rtl::OUString GetDocServiceName(); 285 uno::Sequence< beans::PropertyValue > GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust, sal_Int32 nDont ); 286 uno::Sequence< beans::PropertyValue > GetDocServiceAnyFilter( sal_Int32 nMust, sal_Int32 nDont ); 287 uno::Sequence< beans::PropertyValue > GetPreselectedFilter_Impl( sal_Int8 nStoreMode ); 288 uno::Sequence< beans::PropertyValue > GetDocServiceDefaultFilter(); 289 290 sal_Bool ExecuteFilterDialog_Impl( const ::rtl::OUString& aFilterName ); 291 292 sal_Int8 CheckSaveAcceptable( sal_Int8 nCurStatus ); 293 sal_Int8 CheckStateForSave(); 294 295 sal_Int8 CheckFilter( const ::rtl::OUString& ); 296 297 sal_Bool CheckFilterOptionsDialogExistence(); 298 299 sal_Bool OutputFileDialog( sal_Int8 nStoreMode, 300 const ::comphelper::SequenceAsHashMap& aPreselectedFilterPropsHM, 301 sal_Bool bSetStandardName, 302 ::rtl::OUString& aSuggestedName, 303 sal_Bool bPreselectPassword, 304 const ::rtl::OUString& aSuggestedDir, 305 sal_Int16 nDialog, 306 const ::rtl::OUString& rStandardDir, 307 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList 308 ); 309 310 sal_Bool ShowDocumentInfoDialog(); 311 312 ::rtl::OUString GetReccomendedDir( const ::rtl::OUString& aSuggestedDir, 313 const sfx2::FileDialogHelper::Context& aCtxt ); 314 ::rtl::OUString GetReccomendedName( const ::rtl::OUString& aSuggestedName, 315 const ::rtl::OUString& aTypeName ); 316 317 }; 318 319 //------------------------------------------------------------------------- 320 ModelData_Impl::ModelData_Impl( SfxStoringHelper& aOwner, 321 const uno::Reference< frame::XModel >& xModel, 322 const uno::Sequence< beans::PropertyValue >& aMediaDescr ) 323 : m_pOwner( &aOwner ) 324 , m_xModel( xModel ) 325 , m_pDocumentPropsHM( NULL ) 326 , m_pModulePropsHM( NULL ) 327 , m_aMediaDescrHM( aMediaDescr ) 328 , m_bRecommendReadOnly( sal_False ) 329 { 330 CheckInteractionHandler(); 331 } 332 333 //------------------------------------------------------------------------- 334 ModelData_Impl::~ModelData_Impl() 335 { 336 FreeDocumentProps(); 337 if ( m_pDocumentPropsHM ) 338 delete m_pDocumentPropsHM; 339 340 if ( m_pModulePropsHM ) 341 delete m_pModulePropsHM; 342 } 343 344 //------------------------------------------------------------------------- 345 void ModelData_Impl::FreeDocumentProps() 346 { 347 if ( m_pDocumentPropsHM ) 348 { 349 delete m_pDocumentPropsHM; 350 m_pDocumentPropsHM = NULL; 351 } 352 } 353 354 //------------------------------------------------------------------------- 355 uno::Reference< frame::XModel > ModelData_Impl::GetModel() 356 { 357 if ( !m_xModel.is() ) 358 throw uno::RuntimeException(); 359 360 return m_xModel; 361 } 362 363 //------------------------------------------------------------------------- 364 uno::Reference< frame::XStorable > ModelData_Impl::GetStorable() 365 { 366 if ( !m_xStorable.is() ) 367 { 368 m_xStorable = uno::Reference< frame::XStorable >( m_xModel, uno::UNO_QUERY ); 369 if ( !m_xStorable.is() ) 370 throw uno::RuntimeException(); 371 } 372 373 return m_xStorable; 374 } 375 376 //------------------------------------------------------------------------- 377 uno::Reference< frame::XStorable2 > ModelData_Impl::GetStorable2() 378 { 379 if ( !m_xStorable2.is() ) 380 { 381 m_xStorable2 = uno::Reference< frame::XStorable2 >( m_xModel, uno::UNO_QUERY ); 382 if ( !m_xStorable2.is() ) 383 throw uno::RuntimeException(); 384 } 385 386 return m_xStorable2; 387 } 388 389 //------------------------------------------------------------------------- 390 uno::Reference< util::XModifiable > ModelData_Impl::GetModifiable() 391 { 392 if ( !m_xModifiable.is() ) 393 { 394 m_xModifiable = uno::Reference< util::XModifiable >( m_xModel, uno::UNO_QUERY ); 395 if ( !m_xModifiable.is() ) 396 throw uno::RuntimeException(); 397 } 398 399 return m_xModifiable; 400 } 401 402 //------------------------------------------------------------------------- 403 const ::comphelper::SequenceAsHashMap& ModelData_Impl::GetDocProps() 404 { 405 if ( !m_pDocumentPropsHM ) 406 m_pDocumentPropsHM = new ::comphelper::SequenceAsHashMap( GetModel()->getArgs() ); 407 408 return *m_pDocumentPropsHM; 409 } 410 411 //------------------------------------------------------------------------- 412 ::rtl::OUString ModelData_Impl::GetModuleName() 413 { 414 if ( !m_aModuleName.getLength() ) 415 { 416 m_aModuleName = m_pOwner->GetModuleManager()->identify( 417 uno::Reference< uno::XInterface >( m_xModel, uno::UNO_QUERY ) ); 418 if ( !m_aModuleName.getLength() ) 419 throw uno::RuntimeException(); // TODO: 420 } 421 return m_aModuleName; 422 } 423 424 //------------------------------------------------------------------------- 425 const ::comphelper::SequenceAsHashMap& ModelData_Impl::GetModuleProps() 426 { 427 if ( !m_pModulePropsHM ) 428 { 429 uno::Sequence< beans::PropertyValue > aModuleProps; 430 m_pOwner->GetNamedModuleManager()->getByName( GetModuleName() ) >>= aModuleProps; 431 if ( !aModuleProps.getLength() ) 432 throw uno::RuntimeException(); // TODO; 433 m_pModulePropsHM = new ::comphelper::SequenceAsHashMap( aModuleProps ); 434 } 435 436 return *m_pModulePropsHM; 437 } 438 439 //------------------------------------------------------------------------- 440 ::rtl::OUString ModelData_Impl::GetDocServiceName() 441 { 442 return GetModuleProps().getUnpackedValueOrDefault(::rtl::OUString::createFromAscii( "ooSetupFactoryDocumentService" ), ::rtl::OUString()); 443 } 444 445 //------------------------------------------------------------------------- 446 void ModelData_Impl::CheckInteractionHandler() 447 { 448 ::comphelper::SequenceAsHashMap::const_iterator aInteractIter = 449 m_aMediaDescrHM.find( ::rtl::OUString::createFromAscii( "InteractionHandler" ) ); 450 451 if ( aInteractIter == m_aMediaDescrHM.end() ) 452 { 453 try { 454 m_aMediaDescrHM[ ::rtl::OUString::createFromAscii( "InteractionHandler" ) ] 455 <<= uno::Reference< task::XInteractionHandler >( 456 m_pOwner->GetServiceFactory()->createInstance( 457 DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), 458 uno::UNO_QUERY ); 459 } 460 catch( uno::Exception& ) 461 { 462 } 463 } 464 else 465 { 466 uno::Reference< task::XInteractionHandler > xInteract; 467 DBG_ASSERT( ( aInteractIter->second >>= xInteract ) && xInteract.is(), "Broken interaction handler is provided!\n" ); 468 } 469 } 470 471 //------------------------------------------------------------------------- 472 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceDefaultFilter() 473 { 474 uno::Sequence< beans::PropertyValue > aProps; 475 476 ::rtl::OUString aFilterName = GetModuleProps().getUnpackedValueOrDefault( 477 ::rtl::OUString::createFromAscii( "ooSetupFactoryDefaultFilter" ), 478 ::rtl::OUString() ); 479 480 m_pOwner->GetFilterConfiguration()->getByName( aFilterName ) >>= aProps; 481 482 return aProps; 483 } 484 485 //------------------------------------------------------------------------- 486 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust, 487 sal_Int32 nDont ) 488 { 489 uno::Sequence< beans::PropertyValue > aFilterProps; 490 uno::Sequence< beans::PropertyValue > aProps = GetDocServiceDefaultFilter(); 491 if ( aProps.getLength() ) 492 { 493 ::comphelper::SequenceAsHashMap aFiltHM( aProps ); 494 sal_Int32 nFlags = aFiltHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), 495 (sal_Int32)0 ); 496 if ( ( ( nFlags & nMust ) == nMust ) && !( nFlags & nDont ) ) 497 aFilterProps = aProps; 498 } 499 500 return aFilterProps; 501 } 502 503 504 //------------------------------------------------------------------------- 505 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceAnyFilter( sal_Int32 nMust, sal_Int32 nDont ) 506 { 507 uno::Sequence< beans::NamedValue > aSearchRequest( 1 ); 508 aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "DocumentService" ); 509 aSearchRequest[0].Value <<= GetDocServiceName(); 510 511 return ::comphelper::MimeConfigurationHelper::SearchForFilter( m_pOwner->GetFilterQuery(), aSearchRequest, nMust, nDont ); 512 } 513 514 //------------------------------------------------------------------------- 515 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetPreselectedFilter_Impl( sal_Int8 nStoreMode ) 516 { 517 uno::Sequence< beans::PropertyValue > aFilterProps; 518 519 sal_Int32 nMust = getMustFlags( nStoreMode ); 520 sal_Int32 nDont = getDontFlags( nStoreMode ); 521 522 if ( nStoreMode & PDFEXPORT_REQUESTED ) 523 { 524 // Preselect PDF-Filter for EXPORT 525 uno::Sequence< beans::NamedValue > aSearchRequest( 2 ); 526 aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "Type" ); 527 aSearchRequest[0].Value <<= ::rtl::OUString::createFromAscii( "pdf_Portable_Document_Format" ); 528 aSearchRequest[1].Name = ::rtl::OUString::createFromAscii( "DocumentService" ); 529 aSearchRequest[1].Value <<= GetDocServiceName(); 530 531 aFilterProps = ::comphelper::MimeConfigurationHelper::SearchForFilter( m_pOwner->GetFilterQuery(), aSearchRequest, nMust, nDont ); 532 } 533 else 534 { 535 aFilterProps = GetDocServiceDefaultFilterCheckFlags( nMust, nDont ); 536 537 if ( !aFilterProps.getLength() ) 538 { 539 // the default filter was not faund, use just the first acceptable one 540 aFilterProps = GetDocServiceAnyFilter( nMust, nDont ); 541 } 542 } 543 544 return aFilterProps; 545 } 546 547 //------------------------------------------------------------------------- 548 sal_Bool ModelData_Impl::ExecuteFilterDialog_Impl( const ::rtl::OUString& aFilterName ) 549 { 550 sal_Bool bDialogUsed = sal_False; 551 552 try { 553 uno::Sequence < beans::PropertyValue > aProps; 554 uno::Any aAny = m_pOwner->GetFilterConfiguration()->getByName( aFilterName ); 555 if ( aAny >>= aProps ) 556 { 557 sal_Int32 nPropertyCount = aProps.getLength(); 558 for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty ) 559 if( aProps[nProperty].Name.equals( ::rtl::OUString::createFromAscii("UIComponent")) ) 560 { 561 ::rtl::OUString aServiceName; 562 aProps[nProperty].Value >>= aServiceName; 563 if( aServiceName.getLength() ) 564 { 565 uno::Reference< ui::dialogs::XExecutableDialog > xFilterDialog( 566 m_pOwner->GetServiceFactory()->createInstance( aServiceName ), uno::UNO_QUERY ); 567 uno::Reference< beans::XPropertyAccess > xFilterProperties( xFilterDialog, uno::UNO_QUERY ); 568 569 if( xFilterDialog.is() && xFilterProperties.is() ) 570 { 571 bDialogUsed = sal_True; 572 573 uno::Reference< document::XExporter > xExporter( xFilterDialog, uno::UNO_QUERY ); 574 if( xExporter.is() ) 575 xExporter->setSourceDocument( 576 uno::Reference< lang::XComponent >( GetModel(), uno::UNO_QUERY ) ); 577 578 uno::Sequence< beans::PropertyValue > aPropsForDialog; 579 GetMediaDescr() >> aPropsForDialog; 580 xFilterProperties->setPropertyValues( aPropsForDialog ); 581 582 if( xFilterDialog->execute() ) 583 { 584 uno::Sequence< beans::PropertyValue > aPropsFromDialog = 585 xFilterProperties->getPropertyValues(); 586 for ( sal_Int32 nInd = 0; nInd < aPropsFromDialog.getLength(); nInd++ ) 587 GetMediaDescr()[aPropsFromDialog[nInd].Name] = aPropsFromDialog[nInd].Value; 588 } 589 else 590 { 591 throw task::ErrorCodeIOException( ::rtl::OUString(), 592 uno::Reference< uno::XInterface >(), 593 ERRCODE_IO_ABORT ); 594 } 595 } 596 } 597 598 break; 599 } 600 } 601 } 602 catch( container::NoSuchElementException& ) 603 { 604 // the filter name is unknown 605 throw task::ErrorCodeIOException( ::rtl::OUString(), 606 uno::Reference< uno::XInterface >(), 607 ERRCODE_IO_INVALIDPARAMETER ); 608 } 609 catch( task::ErrorCodeIOException& ) 610 { 611 throw; 612 } 613 catch( uno::Exception& ) 614 { 615 } 616 617 return bDialogUsed; 618 } 619 620 //------------------------------------------------------------------------- 621 sal_Int8 ModelData_Impl::CheckSaveAcceptable( sal_Int8 nCurStatus ) 622 { 623 sal_Int8 nResult = nCurStatus; 624 625 if ( nResult != STATUS_NO_ACTION && GetStorable()->hasLocation() ) 626 { 627 // check whether save is acceptable by the configuration 628 // it is done only for documents that have persistence already 629 uno::Reference< uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig( 630 m_pOwner->GetServiceFactory(), 631 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ), 632 ::comphelper::ConfigurationHelper::E_STANDARD ); 633 if ( !xCommonConfig.is() ) 634 throw uno::RuntimeException(); // should the saving proceed as usual instead? 635 636 try 637 { 638 sal_Bool bAlwaysSaveAs = sal_False; 639 640 // the saving is acceptable 641 // in case the configuration entry is not set or set to false 642 // or in case of version creation 643 ::rtl::OUString aVersionCommentString = ::rtl::OUString::createFromAscii( "VersionComment" ); 644 if ( ( ::comphelper::ConfigurationHelper::readRelativeKey( 645 xCommonConfig, 646 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Save/Document/" ) ), 647 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AlwaysSaveAs" ) ) ) >>= bAlwaysSaveAs ) 648 && bAlwaysSaveAs 649 && GetMediaDescr().find( aVersionCommentString ) == GetMediaDescr().end() ) 650 { 651 // notify the user that SaveAs is going to be done 652 String aString( SfxResId( STR_NEW_FILENAME_SAVE ) ); 653 Window* pWin = SfxStoringHelper::GetModelWindow( m_xModel ); 654 QueryBox aMessageBox( pWin, WB_OK_CANCEL | WB_DEF_OK, aString ); 655 if ( aMessageBox.Execute() == RET_OK ) 656 nResult = STATUS_SAVEAS; 657 else 658 nResult = STATUS_NO_ACTION; 659 } 660 } 661 catch( uno::Exception& ) 662 { 663 // impossibility to get the configuration access means normal saving flow for now 664 } 665 } 666 667 return nResult; 668 } 669 670 //------------------------------------------------------------------------- 671 sal_Int8 ModelData_Impl::CheckStateForSave() 672 { 673 // if the document is readonly or a new one a SaveAs operation must be used 674 if ( !GetStorable()->hasLocation() || GetStorable()->isReadonly() ) 675 return STATUS_SAVEAS; 676 677 // check acceptable entries for media descriptor 678 sal_Bool bVersInfoNeedsStore = sal_False; 679 ::comphelper::SequenceAsHashMap aAcceptedArgs; 680 681 ::rtl::OUString aVersionCommentString = ::rtl::OUString::createFromAscii( "VersionComment" ); 682 ::rtl::OUString aAuthorString = ::rtl::OUString::createFromAscii( "Author" ); 683 ::rtl::OUString aInteractionHandlerString = ::rtl::OUString::createFromAscii( "InteractionHandler" ); 684 ::rtl::OUString aStatusIndicatorString = ::rtl::OUString::createFromAscii( "StatusIndicator" ); 685 ::rtl::OUString aFailOnWarningString = ::rtl::OUString::createFromAscii( "FailOnWarning" ); 686 687 if ( GetMediaDescr().find( aVersionCommentString ) != GetMediaDescr().end() ) 688 { 689 bVersInfoNeedsStore = sal_True; 690 aAcceptedArgs[ aVersionCommentString ] = GetMediaDescr()[ aVersionCommentString ]; 691 } 692 if ( GetMediaDescr().find( aAuthorString ) != GetMediaDescr().end() ) 693 aAcceptedArgs[ aAuthorString ] = GetMediaDescr()[ aAuthorString ]; 694 if ( GetMediaDescr().find( aInteractionHandlerString ) != GetMediaDescr().end() ) 695 aAcceptedArgs[ aInteractionHandlerString ] = GetMediaDescr()[ aInteractionHandlerString ]; 696 if ( GetMediaDescr().find( aStatusIndicatorString ) != GetMediaDescr().end() ) 697 aAcceptedArgs[ aStatusIndicatorString ] = GetMediaDescr()[ aStatusIndicatorString ]; 698 if ( GetMediaDescr().find( aFailOnWarningString ) != GetMediaDescr().end() ) 699 aAcceptedArgs[ aFailOnWarningString ] = GetMediaDescr()[ aFailOnWarningString ]; 700 701 // remove unacceptable entry if there is any 702 DBG_ASSERT( GetMediaDescr().size() == aAcceptedArgs.size(), 703 "Unacceptable parameters are provided in Save request!\n" ); 704 if ( GetMediaDescr().size() != aAcceptedArgs.size() ) 705 GetMediaDescr() = aAcceptedArgs; 706 707 // the document must be modified 708 if ( !GetModifiable()->isModified() && !bVersInfoNeedsStore ) 709 return STATUS_NO_ACTION; 710 711 // check that the old filter is acceptable 712 ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault( 713 aFilterNameString, 714 ::rtl::OUString() ); 715 sal_Int8 nResult = CheckFilter( aOldFilterName ); 716 717 return nResult; 718 } 719 720 sal_Int8 ModelData_Impl::CheckFilter( const ::rtl::OUString& aFilterName ) 721 { 722 ::comphelper::SequenceAsHashMap aFiltPropsHM; 723 sal_Int32 nFiltFlags = 0; 724 if ( aFilterName.getLength() ) 725 { 726 // get properties of filter 727 uno::Sequence< beans::PropertyValue > aFilterProps; 728 if ( aFilterName.getLength() ) 729 m_pOwner->GetFilterConfiguration()->getByName( aFilterName ) >>= aFilterProps; 730 731 aFiltPropsHM = ::comphelper::SequenceAsHashMap( aFilterProps ); 732 nFiltFlags = aFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 ); 733 } 734 735 // only a temporary solution until default filter retrieving feature is implemented 736 // then GetDocServiceDefaultFilter() must be used 737 ::comphelper::SequenceAsHashMap aDefFiltPropsHM = GetDocServiceDefaultFilterCheckFlags( 3, 0 ); 738 sal_Int32 nDefFiltFlags = aDefFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 ); 739 740 // if the old filter is not acceptable 741 // and there is no default filter or it is not acceptable for requested parameters then proceed with saveAs 742 if ( ( !aFiltPropsHM.size() || !( nFiltFlags & SFX_FILTER_EXPORT ) ) 743 && ( !aDefFiltPropsHM.size() || !( nDefFiltFlags & SFX_FILTER_EXPORT ) || nDefFiltFlags & SFX_FILTER_INTERNAL ) ) 744 return STATUS_SAVEAS; 745 746 // so at this point there is either an acceptable old filter or default one 747 if ( !aFiltPropsHM.size() || !( nFiltFlags & SFX_FILTER_EXPORT ) ) 748 { 749 // so the default filter must be acceptable 750 return STATUS_SAVEAS_STANDARDNAME; 751 } 752 else if ( ( !( nFiltFlags & SFX_FILTER_OWN ) || ( nFiltFlags & SFX_FILTER_ALIEN ) ) 753 && aDefFiltPropsHM.size() 754 && ( nDefFiltFlags & SFX_FILTER_EXPORT ) && !( nDefFiltFlags & SFX_FILTER_INTERNAL )) 755 { 756 // the default filter is acceptable and the old filter is alian one 757 // so ask to make a saveAs operation 758 ::rtl::OUString aUIName = aFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "UIName" ), 759 ::rtl::OUString() ); 760 ::rtl::OUString aDefUIName = aDefFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "UIName" ), 761 ::rtl::OUString() ); 762 ::rtl::OUString aPreusedFilterName = GetDocProps().getUnpackedValueOrDefault( 763 ::rtl::OUString::createFromAscii( "PreusedFilterName" ), 764 ::rtl::OUString() ); 765 if ( !aPreusedFilterName.equals( aFilterName ) && !aUIName.equals( aDefUIName ) ) 766 { 767 if ( !SfxStoringHelper::WarnUnacceptableFormat( GetModel(), aUIName, aDefUIName, sal_True ) ) 768 return STATUS_SAVEAS_STANDARDNAME; 769 } 770 } 771 772 return STATUS_SAVE; 773 } 774 775 //------------------------------------------------------------------------- 776 sal_Bool ModelData_Impl::CheckFilterOptionsDialogExistence() 777 { 778 uno::Sequence< beans::NamedValue > aSearchRequest( 1 ); 779 aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "DocumentService" ); 780 aSearchRequest[0].Value <<= GetDocServiceName(); 781 782 uno::Reference< container::XEnumeration > xFilterEnum = 783 m_pOwner->GetFilterQuery()->createSubSetEnumerationByProperties( aSearchRequest ); 784 785 while ( xFilterEnum->hasMoreElements() ) 786 { 787 uno::Sequence< beans::PropertyValue > pProps; 788 if ( xFilterEnum->nextElement() >>= pProps ) 789 { 790 ::comphelper::SequenceAsHashMap aPropsHM( pProps ); 791 ::rtl::OUString aUIServName = aPropsHM.getUnpackedValueOrDefault( 792 ::rtl::OUString::createFromAscii( "UIComponent" ), 793 ::rtl::OUString() ); 794 if ( aUIServName.getLength() ) 795 return sal_True; 796 } 797 } 798 799 return sal_False; 800 } 801 802 //------------------------------------------------------------------------- 803 sal_Bool ModelData_Impl::OutputFileDialog( sal_Int8 nStoreMode, 804 const ::comphelper::SequenceAsHashMap& aPreselectedFilterPropsHM, 805 sal_Bool bSetStandardName, 806 ::rtl::OUString& aSuggestedName, 807 sal_Bool bPreselectPassword, 808 const ::rtl::OUString& aSuggestedDir, 809 sal_Int16 nDialog, 810 const ::rtl::OUString& rStandardDir, 811 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList) 812 { 813 sal_Bool bUseFilterOptions = sal_False; 814 815 ::comphelper::SequenceAsHashMap::const_iterator aOverwriteIter = 816 GetMediaDescr().find( ::rtl::OUString::createFromAscii( "Overwrite" ) ); 817 818 // the file name must be specified if overwrite option is set 819 if ( aOverwriteIter != GetMediaDescr().end() ) 820 throw task::ErrorCodeIOException( ::rtl::OUString(), 821 uno::Reference< uno::XInterface >(), 822 ERRCODE_IO_INVALIDPARAMETER ); 823 824 // no target file name is specified 825 // we need to show the file dialog 826 827 // check if we have a filter which allows for filter options, so we need a corresponding checkbox in the dialog 828 sal_Bool bAllowOptions = sal_False; 829 830 // in case of Export, filter options dialog is used if available 831 if( !( nStoreMode & EXPORT_REQUESTED ) || ( nStoreMode & WIDEEXPORT_REQUESTED ) ) 832 bAllowOptions = CheckFilterOptionsDialogExistence(); 833 834 // get the filename by dialog ... 835 // create the file dialog 836 sal_Int16 aDialogMode = bAllowOptions 837 ? (com::sun::star::ui::dialogs::TemplateDescription:: 838 FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS) 839 : (com::sun::star::ui::dialogs::TemplateDescription:: 840 FILESAVE_AUTOEXTENSION_PASSWORD); 841 sal_Int64 aDialogFlags = 0; 842 843 if( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) 844 { 845 if ( nStoreMode & PDFEXPORT_REQUESTED ) 846 aDialogMode = com::sun::star::ui::dialogs::TemplateDescription:: 847 FILESAVE_AUTOEXTENSION; 848 else 849 aDialogMode = com::sun::star::ui::dialogs::TemplateDescription:: 850 FILESAVE_AUTOEXTENSION_SELECTION; 851 aDialogFlags = SFXWB_EXPORT; 852 } 853 854 sfx2::FileDialogHelper* pFileDlg = NULL; 855 856 ::rtl::OUString aDocServiceName = GetDocServiceName(); 857 DBG_ASSERT( aDocServiceName.getLength(), "No document service for this module set!" ); 858 859 sal_Int32 nMust = getMustFlags( nStoreMode ); 860 sal_Int32 nDont = getDontFlags( nStoreMode ); 861 sfx2::FileDialogHelper::Context eCtxt = sfx2::FileDialogHelper::UNKNOWN_CONTEXT; 862 863 if ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) 864 { 865 if ( ( nStoreMode & PDFEXPORT_REQUESTED ) && aPreselectedFilterPropsHM.size() ) 866 { 867 // this is a PDF export 868 // the filter options has been shown already 869 ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault( 870 ::rtl::OUString::createFromAscii( "UIName" ), 871 ::rtl::OUString() ); 872 873 pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aFilterUIName, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "pdf" ) ), rStandardDir, rBlackList ); 874 pFileDlg->SetCurrentFilter( aFilterUIName ); 875 } 876 else 877 { 878 // This is the normal dialog 879 pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aDocServiceName, nDialog, nMust, nDont, rStandardDir, rBlackList ); 880 } 881 882 if( aDocServiceName.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) ) 883 eCtxt = sfx2::FileDialogHelper::SD_EXPORT; 884 if( aDocServiceName.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) ) 885 eCtxt = sfx2::FileDialogHelper::SI_EXPORT; 886 if( aDocServiceName.equalsAscii( "com.sun.star.text.TextDocument" ) ) 887 eCtxt = sfx2::FileDialogHelper::SW_EXPORT; 888 889 if ( eCtxt != sfx2::FileDialogHelper::UNKNOWN_CONTEXT ) 890 pFileDlg->SetContext( eCtxt ); 891 892 pFileDlg->CreateMatcher( aDocServiceName ); 893 894 uno::Reference< ui::dialogs::XFilePicker > xFilePicker = pFileDlg->GetFilePicker(); 895 uno::Reference< ui::dialogs::XFilePickerControlAccess > xControlAccess = 896 uno::Reference< ui::dialogs::XFilePickerControlAccess >( xFilePicker, uno::UNO_QUERY ); 897 898 if ( xControlAccess.is() ) 899 { 900 ::rtl::OUString aCtrlText = String( SfxResId( STR_EXPORTBUTTON ) ); 901 xControlAccess->setLabel( ui::dialogs::CommonFilePickerElementIds::PUSHBUTTON_OK, aCtrlText ); 902 903 aCtrlText = ::rtl::OUString( String( SfxResId( STR_LABEL_FILEFORMAT ) ) ); 904 xControlAccess->setLabel( ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER_LABEL, aCtrlText ); 905 } 906 } 907 else 908 { 909 // This is the normal dialog 910 pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aDocServiceName, nDialog, nMust, nDont, rStandardDir, rBlackList ); 911 pFileDlg->CreateMatcher( aDocServiceName ); 912 } 913 914 ::rtl::OUString aAdjustToType; 915 916 if ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) 917 { 918 // it is export, set the preselected filter 919 ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault( 920 ::rtl::OUString::createFromAscii( "UIName" ), 921 ::rtl::OUString() ); 922 pFileDlg->SetCurrentFilter( aFilterUIName ); 923 } 924 // it is no export, bSetStandardName == true means that user agreed to store document in the default (default default ;-)) format 925 else if ( bSetStandardName || GetStorable()->hasLocation() ) 926 { 927 uno::Sequence< beans::PropertyValue > aOldFilterProps; 928 ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault( 929 aFilterNameString, 930 ::rtl::OUString() ); 931 932 if ( aOldFilterName.getLength() ) 933 m_pOwner->GetFilterConfiguration()->getByName( aOldFilterName ) >>= aOldFilterProps; 934 935 ::comphelper::SequenceAsHashMap aOldFiltPropsHM( aOldFilterProps ); 936 sal_Int32 nOldFiltFlags = aOldFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 ); 937 938 if ( bSetStandardName || ( nOldFiltFlags & nMust ) != nMust || nOldFiltFlags & nDont ) 939 { 940 // the suggested type will be changed, the extension should be adjusted 941 aAdjustToType = aPreselectedFilterPropsHM.getUnpackedValueOrDefault( 942 ::rtl::OUString::createFromAscii( "Type" ), 943 ::rtl::OUString() ); 944 945 ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault( 946 ::rtl::OUString::createFromAscii( "UIName" ), 947 ::rtl::OUString() ); 948 pFileDlg->SetCurrentFilter( aFilterUIName ); 949 } 950 else 951 { 952 pFileDlg->SetCurrentFilter( aOldFiltPropsHM.getUnpackedValueOrDefault( 953 ::rtl::OUString::createFromAscii( "UIName" ), 954 ::rtl::OUString() ) ); 955 } 956 } 957 958 ::rtl::OUString aReccomendedDir = GetReccomendedDir( aSuggestedDir, eCtxt ); 959 if ( aReccomendedDir.getLength() ) 960 pFileDlg->SetDisplayDirectory( aReccomendedDir ); 961 ::rtl::OUString aReccomendedName = GetReccomendedName( aSuggestedName, aAdjustToType ); 962 if ( aReccomendedName.getLength() ) 963 pFileDlg->SetFileName( aReccomendedName ); 964 965 uno::Reference < view::XSelectionSupplier > xSel( GetModel()->getCurrentController(), uno::UNO_QUERY ); 966 if ( xSel.is() && xSel->getSelection().hasValue() ) 967 GetMediaDescr()[::rtl::OUString::createFromAscii( "SelectionOnly" )] <<= sal_True; 968 969 // This is a temporary hardcoded solution must be removed when 970 // dialogs do not need parameters in SidSet representation any more 971 sal_uInt16 nSlotID = getSlotIDFromMode( nStoreMode ); 972 if ( !nSlotID ) 973 throw lang::IllegalArgumentException(); // TODO: 974 975 // generate SidSet from MediaDescriptor and provide it into FileDialog 976 // than merge changed SidSet back 977 SfxAllItemSet aDialogParams( SFX_APP()->GetPool() ); 978 SfxItemSet* pDialogParams = &aDialogParams; 979 TransformParameters( nSlotID, 980 GetMediaDescr().getAsConstPropertyValueList(), 981 aDialogParams, 982 NULL ); 983 984 const SfxPoolItem* pItem = NULL; 985 if ( bPreselectPassword && aDialogParams.GetItemState( SID_ENCRYPTIONDATA, sal_True, &pItem ) != SFX_ITEM_SET ) 986 { 987 // the file dialog preselects the password checkbox if the provided mediadescriptor has encryption data entry 988 // after dialog execution the password interaction flag will be either removed or not 989 aDialogParams.Put( SfxBoolItem( SID_PASSWORDINTERACTION, sal_True ) ); 990 } 991 992 // aStringTypeFN is a pure output parameter, pDialogParams is an in/out parameter 993 String aStringTypeFN; 994 if ( pFileDlg->Execute( pDialogParams, aStringTypeFN ) != ERRCODE_NONE ) 995 { 996 delete pFileDlg; 997 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT ); 998 } 999 1000 ::rtl::OUString aFilterName = aStringTypeFN; 1001 1002 // the following two arguments can not be converted in MediaDescriptor, 1003 // so they should be removed from the ItemSet after retrieving 1004 SFX_ITEMSET_ARG( pDialogParams, pRecommendReadOnly, SfxBoolItem, SID_RECOMMENDREADONLY, sal_False ); 1005 m_bRecommendReadOnly = ( pRecommendReadOnly && pRecommendReadOnly->GetValue() ); 1006 pDialogParams->ClearItem( SID_RECOMMENDREADONLY ); 1007 1008 uno::Sequence< beans::PropertyValue > aPropsFromDialog; 1009 TransformItems( nSlotID, *pDialogParams, aPropsFromDialog, NULL ); 1010 GetMediaDescr() << aPropsFromDialog; 1011 1012 // get the path from the dialog 1013 INetURLObject aURL( pFileDlg->GetPath() ); 1014 // the path should be provided outside since it might be used for further calls to the dialog 1015 aSuggestedName = aURL.GetName( INetURLObject::DECODE_WITH_CHARSET ); 1016 1017 // old filter options should be cleared in case different filter is used 1018 1019 ::rtl::OUString aFilterFromMediaDescr = GetMediaDescr().getUnpackedValueOrDefault( 1020 aFilterNameString, 1021 ::rtl::OUString() ); 1022 ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault( 1023 aFilterNameString, 1024 ::rtl::OUString() ); 1025 if ( aFilterName.equals( aFilterFromMediaDescr ) ) 1026 { 1027 // preserv current settings if any 1028 // if there no current settings and the name is the same 1029 // as old filter name use old filter settings 1030 1031 if ( aFilterFromMediaDescr.equals( aOldFilterName ) ) 1032 { 1033 ::comphelper::SequenceAsHashMap::const_iterator aIter = 1034 GetDocProps().find( aFilterOptionsString ); 1035 if ( aIter != GetDocProps().end() 1036 && GetMediaDescr().find( aFilterOptionsString ) == GetMediaDescr().end() ) 1037 GetMediaDescr()[aIter->first] = aIter->second; 1038 1039 aIter = GetDocProps().find( aFilterDataString ); 1040 if ( aIter != GetDocProps().end() 1041 && GetMediaDescr().find( aFilterDataString ) == GetMediaDescr().end() ) 1042 GetMediaDescr()[aIter->first] = aIter->second; 1043 } 1044 } 1045 else 1046 { 1047 GetMediaDescr().erase( aFilterDataString ); 1048 GetMediaDescr().erase( aFilterOptionsString ); 1049 1050 if ( aFilterName.equals( aOldFilterName ) ) 1051 { 1052 // merge filter option of the document filter 1053 1054 ::comphelper::SequenceAsHashMap::const_iterator aIter = 1055 GetDocProps().find( aFilterOptionsString ); 1056 if ( aIter != GetDocProps().end() ) 1057 GetMediaDescr()[aIter->first] = aIter->second; 1058 1059 aIter = GetDocProps().find( aFilterDataString ); 1060 if ( aIter != GetDocProps().end() ) 1061 GetMediaDescr()[aIter->first] = aIter->second; 1062 } 1063 } 1064 1065 uno::Reference< ui::dialogs::XFilePickerControlAccess > xExtFileDlg( pFileDlg->GetFilePicker(), uno::UNO_QUERY ); 1066 if ( xExtFileDlg.is() ) 1067 { 1068 if ( SfxStoringHelper::CheckFilterOptionsAppearence( m_pOwner->GetFilterConfiguration(), aFilterName ) ) 1069 bUseFilterOptions = sal_True; 1070 1071 if ( ( !( nStoreMode & EXPORT_REQUESTED ) || ( nStoreMode & WIDEEXPORT_REQUESTED ) ) && bUseFilterOptions ) 1072 { 1073 try 1074 { 1075 // for exporters: always show dialog if format uses options 1076 // for save: show dialog if format uses options and no options given or if forced by user 1077 uno::Any aVal = 1078 xExtFileDlg->getValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, 0 ); 1079 1080 aVal >>= bUseFilterOptions; 1081 if ( !bUseFilterOptions ) 1082 bUseFilterOptions = 1083 ( GetMediaDescr().find( aFilterDataString ) == GetMediaDescr().end() 1084 && GetMediaDescr().find( aFilterOptionsString ) == GetMediaDescr().end() ); 1085 } 1086 catch( lang::IllegalArgumentException& ) 1087 {} 1088 } 1089 } 1090 1091 delete pFileDlg; 1092 1093 // merge in results of the dialog execution 1094 GetMediaDescr()[::rtl::OUString::createFromAscii( "URL" )] <<= 1095 ::rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE )); 1096 GetMediaDescr()[aFilterNameString] <<= aFilterName; 1097 1098 return bUseFilterOptions; 1099 } 1100 1101 //------------------------------------------------------------------------- 1102 sal_Bool ModelData_Impl::ShowDocumentInfoDialog() 1103 { 1104 sal_Bool bDialogUsed = sal_False; 1105 1106 try { 1107 uno::Reference< frame::XController > xController = GetModel()->getCurrentController(); 1108 if ( xController.is() ) 1109 { 1110 uno::Reference< frame::XDispatchProvider > xFrameDispatch( xController->getFrame(), uno::UNO_QUERY ); 1111 if ( xFrameDispatch.is() ) 1112 { 1113 util::URL aURL; 1114 aURL.Complete = ::rtl::OUString::createFromAscii( ".uno:SetDocumentProperties" ); 1115 1116 uno::Reference< util::XURLTransformer > xTransformer( 1117 m_pOwner->GetServiceFactory()->createInstance( 1118 DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer") ), 1119 uno::UNO_QUERY ); 1120 if ( xTransformer.is() && xTransformer->parseStrict( aURL ) ) 1121 { 1122 uno::Reference< frame::XDispatch > xDispatch = xFrameDispatch->queryDispatch( 1123 aURL, 1124 ::rtl::OUString::createFromAscii( "_self" ), 1125 0 ); 1126 if ( xDispatch.is() ) 1127 { 1128 xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() ); 1129 bDialogUsed = sal_True; 1130 } 1131 } 1132 } 1133 } 1134 } 1135 catch ( uno::Exception& ) 1136 { 1137 } 1138 1139 return bDialogUsed; 1140 } 1141 1142 //------------------------------------------------------------------------- 1143 ::rtl::OUString ModelData_Impl::GetReccomendedDir( const ::rtl::OUString& aSuggestedDir, const sfx2::FileDialogHelper::Context& aCtxt ) 1144 { 1145 ::rtl::OUString aReccomendedDir; 1146 1147 if ( ( aSuggestedDir.getLength() || GetStorable()->hasLocation() ) 1148 && !GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "RepairPackage" ), 1149 sal_False ) ) 1150 { 1151 INetURLObject aLocation; 1152 if ( aSuggestedDir.getLength() ) 1153 aLocation = INetURLObject( aSuggestedDir ); 1154 else 1155 { 1156 ::rtl::OUString aOldURL = GetStorable()->getLocation(); 1157 if ( aOldURL.getLength() ) 1158 { 1159 INetURLObject aTmp( aOldURL ); 1160 if ( aTmp.removeSegment() ) 1161 aLocation = aTmp; 1162 } 1163 1164 if ( aLocation.HasError() ) 1165 aLocation = INetURLObject( SvtPathOptions().GetWorkPath() ); 1166 } 1167 1168 aLocation.setFinalSlash(); 1169 if ( !aLocation.HasError() ) 1170 aReccomendedDir = aLocation.GetMainURL( INetURLObject::NO_DECODE ); 1171 } 1172 else 1173 { 1174 // pb: set graphic path if context == SD_EXPORT or SI_EXPORT else work path 1175 ::rtl::OUString aConfigSuggestion( ( aCtxt != sfx2::FileDialogHelper::UNKNOWN_CONTEXT ) ? SvtPathOptions().GetGraphicPath() : SvtPathOptions().GetWorkPath() ); 1176 aReccomendedDir = INetURLObject( aConfigSuggestion ).GetMainURL( INetURLObject::NO_DECODE ); 1177 } 1178 1179 return aReccomendedDir; 1180 } 1181 1182 //------------------------------------------------------------------------- 1183 ::rtl::OUString ModelData_Impl::GetReccomendedName( const ::rtl::OUString& aSuggestedName, const ::rtl::OUString& aTypeName ) 1184 { 1185 // the last used name might be provided by aSuggestedName from the old selection, or from the MediaDescriptor 1186 ::rtl::OUString aReccomendedName; 1187 1188 if ( aSuggestedName.getLength() ) 1189 aReccomendedName = aSuggestedName; 1190 else 1191 { 1192 aReccomendedName = INetURLObject( GetStorable()->getLocation() ).GetName( INetURLObject::DECODE_WITH_CHARSET ); 1193 if ( !aReccomendedName.getLength() ) 1194 { 1195 try { 1196 uno::Reference< frame::XTitle > xTitle( GetModel(), uno::UNO_QUERY_THROW ); 1197 aReccomendedName = xTitle->getTitle(); 1198 } catch( uno::Exception& ) {} 1199 } 1200 1201 if ( aReccomendedName.getLength() && aTypeName.getLength() ) 1202 { 1203 // adjust the extension to the type 1204 uno::Reference< container::XNameAccess > xTypeDetection = uno::Reference< container::XNameAccess >( 1205 m_pOwner->GetServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ), 1206 uno::UNO_QUERY ); 1207 if ( xTypeDetection.is() ) 1208 { 1209 INetURLObject aObj( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///c:/" ) ) + aReccomendedName ); 1210 1211 uno::Sequence< beans::PropertyValue > aTypeNameProps; 1212 if ( ( xTypeDetection->getByName( aTypeName ) >>= aTypeNameProps ) && aTypeNameProps.getLength() ) 1213 { 1214 ::comphelper::SequenceAsHashMap aTypeNamePropsHM( aTypeNameProps ); 1215 uno::Sequence< ::rtl::OUString > aExtensions = aTypeNamePropsHM.getUnpackedValueOrDefault( 1216 ::rtl::OUString::createFromAscii( "Extensions" ), 1217 ::uno::Sequence< ::rtl::OUString >() ); 1218 if ( aExtensions.getLength() ) 1219 aObj.SetExtension( aExtensions[0] ); 1220 } 1221 1222 aReccomendedName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ); 1223 } 1224 } 1225 } 1226 1227 return aReccomendedName; 1228 } 1229 1230 1231 //========================================================================= 1232 // class SfxStoringHelper 1233 //========================================================================= 1234 //------------------------------------------------------------------------- 1235 SfxStoringHelper::SfxStoringHelper( const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 1236 : m_xFactory( xFactory ) 1237 { 1238 } 1239 1240 //------------------------------------------------------------------------- 1241 uno::Reference< lang::XMultiServiceFactory > SfxStoringHelper::GetServiceFactory() 1242 { 1243 if ( !m_xFactory.is() ) 1244 { 1245 m_xFactory = ::comphelper::getProcessServiceFactory(); 1246 if( !m_xFactory.is() ) 1247 throw uno::RuntimeException(); // TODO: 1248 } 1249 1250 return m_xFactory; 1251 } 1252 1253 //------------------------------------------------------------------------- 1254 uno::Reference< container::XNameAccess > SfxStoringHelper::GetFilterConfiguration() 1255 { 1256 if ( !m_xFilterCFG.is() ) 1257 { 1258 m_xFilterCFG = uno::Reference< container::XNameAccess >( 1259 GetServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ), 1260 uno::UNO_QUERY ); 1261 1262 if ( !m_xFilterCFG.is() ) 1263 throw uno::RuntimeException(); 1264 } 1265 1266 return m_xFilterCFG; 1267 } 1268 1269 //------------------------------------------------------------------------- 1270 uno::Reference< container::XContainerQuery > SfxStoringHelper::GetFilterQuery() 1271 { 1272 if ( !m_xFilterQuery.is() ) 1273 { 1274 m_xFilterQuery = uno::Reference< container::XContainerQuery >( GetFilterConfiguration(), uno::UNO_QUERY ); 1275 if ( !m_xFilterQuery.is() ) 1276 throw uno::RuntimeException(); 1277 } 1278 1279 return m_xFilterQuery; 1280 } 1281 1282 //------------------------------------------------------------------------- 1283 uno::Reference< ::com::sun::star::frame::XModuleManager > SfxStoringHelper::GetModuleManager() 1284 { 1285 if ( !m_xModuleManager.is() ) 1286 { 1287 m_xModuleManager = uno::Reference< ::com::sun::star::frame::XModuleManager >( 1288 GetServiceFactory()->createInstance( 1289 ::rtl::OUString::createFromAscii( "com.sun.star.frame.ModuleManager" ) ), 1290 uno::UNO_QUERY ); 1291 1292 if ( !m_xModuleManager.is() ) 1293 throw uno::RuntimeException(); 1294 } 1295 1296 return m_xModuleManager; 1297 } 1298 1299 //------------------------------------------------------------------------- 1300 uno::Reference< container::XNameAccess > SfxStoringHelper::GetNamedModuleManager() 1301 { 1302 if ( !m_xNamedModManager.is() ) 1303 { 1304 m_xNamedModManager = uno::Reference< container::XNameAccess >( GetModuleManager(), uno::UNO_QUERY ); 1305 if ( !m_xNamedModManager.is() ) 1306 throw uno::RuntimeException(); 1307 } 1308 1309 return m_xNamedModManager; 1310 } 1311 1312 //------------------------------------------------------------------------- 1313 sal_Bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& xModel, 1314 const ::rtl::OUString& aSlotName, 1315 uno::Sequence< beans::PropertyValue >& aArgsSequence, 1316 sal_Bool bPreselectPassword, 1317 ::rtl::OUString aSuggestedName, 1318 sal_uInt16 nDocumentSignatureState ) 1319 { 1320 ModelData_Impl aModelData( *this, xModel, aArgsSequence ); 1321 1322 sal_Bool bDialogUsed = sal_False; 1323 1324 INetURLObject aURL; 1325 1326 sal_Bool bSetStandardName = sal_False; // can be set only for SaveAs 1327 1328 // parse the slot name 1329 sal_Int8 nStoreMode = getStoreModeFromSlotName( aSlotName ); 1330 sal_Int8 nStatusSave = STATUS_NO_ACTION; 1331 1332 // handle the special cases 1333 if ( nStoreMode & SAVEAS_REQUESTED ) 1334 { 1335 ::comphelper::SequenceAsHashMap::const_iterator aSaveToIter = 1336 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "SaveTo" ) ); 1337 if ( aSaveToIter != aModelData.GetMediaDescr().end() ) 1338 { 1339 sal_Bool bWideExport = sal_False; 1340 aSaveToIter->second >>= bWideExport; 1341 if ( bWideExport ) 1342 nStoreMode = EXPORT_REQUESTED | WIDEEXPORT_REQUESTED; 1343 } 1344 1345 // if saving is not acceptable the warning must be shown even in case of SaveAs operation 1346 if ( ( nStoreMode & SAVEAS_REQUESTED ) && aModelData.CheckSaveAcceptable( STATUS_SAVEAS ) == STATUS_NO_ACTION ) 1347 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT ); 1348 } 1349 else if ( nStoreMode & SAVE_REQUESTED ) 1350 { 1351 // if saving is not acceptable by the configuration the warning must be shown 1352 nStatusSave = aModelData.CheckSaveAcceptable( STATUS_SAVE ); 1353 1354 if ( nStatusSave == STATUS_NO_ACTION ) 1355 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT ); 1356 else if ( nStatusSave == STATUS_SAVE ) 1357 { 1358 // check whether it is possible to use save operation 1359 nStatusSave = aModelData.CheckStateForSave(); 1360 } 1361 1362 if ( nStatusSave == STATUS_NO_ACTION ) 1363 { 1364 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT ); 1365 } 1366 else if ( nStatusSave != STATUS_SAVE ) 1367 { 1368 // this should be a usual SaveAs operation 1369 nStoreMode = SAVEAS_REQUESTED; 1370 if ( nStatusSave == STATUS_SAVEAS_STANDARDNAME ) 1371 bSetStandardName = sal_True; 1372 } 1373 } 1374 1375 if ( !( nStoreMode & EXPORT_REQUESTED ) ) 1376 { 1377 // if it is no export, warn user that the signature will be removed 1378 if ( SIGNATURESTATE_SIGNATURES_OK == nDocumentSignatureState 1379 || SIGNATURESTATE_SIGNATURES_INVALID == nDocumentSignatureState 1380 || SIGNATURESTATE_SIGNATURES_NOTVALIDATED == nDocumentSignatureState 1381 || SIGNATURESTATE_SIGNATURES_PARTIAL_OK == nDocumentSignatureState) 1382 { 1383 if ( QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_LOSINGSIGNATURE ) ).Execute() != RET_YES ) 1384 { 1385 // the user has decided not to store the document 1386 throw task::ErrorCodeIOException( ::rtl::OUString(), 1387 uno::Reference< uno::XInterface >(), 1388 ERRCODE_IO_ABORT ); 1389 } 1390 } 1391 } 1392 1393 if ( nStoreMode & SAVE_REQUESTED && nStatusSave == STATUS_SAVE ) 1394 { 1395 // Document properties can contain streams that should be freed before storing 1396 aModelData.FreeDocumentProps(); 1397 1398 if ( aModelData.GetStorable2().is() ) 1399 { 1400 try 1401 { 1402 aModelData.GetStorable2()->storeSelf( aModelData.GetMediaDescr().getAsConstPropertyValueList() ); 1403 } 1404 catch( lang::IllegalArgumentException& ) 1405 { 1406 OSL_ENSURE( sal_False, "ModelData didn't handle illegal parameters, all the parameters are ignored!\n" ); 1407 aModelData.GetStorable()->store(); 1408 } 1409 } 1410 else 1411 { 1412 OSL_ENSURE( sal_False, "XStorable2 is not supported by the model!\n" ); 1413 aModelData.GetStorable()->store(); 1414 } 1415 1416 return sal_False; 1417 } 1418 1419 // preselect a filter for the storing process 1420 uno::Sequence< beans::PropertyValue > aFilterProps = aModelData.GetPreselectedFilter_Impl( nStoreMode ); 1421 1422 DBG_ASSERT( aFilterProps.getLength(), "No filter for storing!\n" ); 1423 if ( !aFilterProps.getLength() ) 1424 throw task::ErrorCodeIOException( ::rtl::OUString(), 1425 uno::Reference< uno::XInterface >(), 1426 ERRCODE_IO_INVALIDPARAMETER ); 1427 1428 ::comphelper::SequenceAsHashMap aFilterPropsHM( aFilterProps ); 1429 ::rtl::OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault( 1430 ::rtl::OUString::createFromAscii( "Name" ), 1431 ::rtl::OUString() ); 1432 1433 ::rtl::OUString aFilterFromMediaDescr = aModelData.GetMediaDescr().getUnpackedValueOrDefault( 1434 aFilterNameString, 1435 ::rtl::OUString() ); 1436 ::rtl::OUString aOldFilterName = aModelData.GetDocProps().getUnpackedValueOrDefault( 1437 aFilterNameString, 1438 ::rtl::OUString() ); 1439 1440 sal_Bool bUseFilterOptions = sal_False; 1441 ::comphelper::SequenceAsHashMap::const_iterator aFileNameIter = aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "URL" ) ); 1442 1443 if ( ( nStoreMode & EXPORT_REQUESTED ) && ( nStoreMode & PDFEXPORT_REQUESTED ) && !( nStoreMode & PDFDIRECTEXPORT_REQUESTED ) ) 1444 { 1445 // this is PDF export, the filter options dialog should be shown before the export 1446 aModelData.GetMediaDescr()[aFilterNameString] <<= aFilterName; 1447 if ( aModelData.GetMediaDescr().find( aFilterFlagsString ) == aModelData.GetMediaDescr().end() 1448 && aModelData.GetMediaDescr().find( aFilterOptionsString ) == aModelData.GetMediaDescr().end() 1449 && aModelData.GetMediaDescr().find( aFilterDataString ) == aModelData.GetMediaDescr().end() ) 1450 { 1451 // execute filter options dialog since no options are set in the media descriptor 1452 if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) ) 1453 bDialogUsed = sal_True; 1454 } 1455 } 1456 1457 if ( aFileNameIter == aModelData.GetMediaDescr().end() ) 1458 { 1459 sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG; 1460 ::comphelper::SequenceAsHashMap::const_iterator aDlgIter = 1461 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "UseSystemDialog" ) ); 1462 if ( aDlgIter != aModelData.GetMediaDescr().end() ) 1463 { 1464 sal_Bool bUseSystemDialog = sal_True; 1465 if ( aDlgIter->second >>= bUseSystemDialog ) 1466 { 1467 if ( bUseSystemDialog ) 1468 nDialog = SFX2_IMPL_DIALOG_SYSTEM; 1469 else 1470 nDialog = SFX2_IMPL_DIALOG_OOO; 1471 } 1472 } 1473 1474 // The Dispatch supports parameter FolderName that overwrites SuggestedSaveAsDir 1475 ::rtl::OUString aSuggestedDir = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FolderName" ) ), ::rtl::OUString() ); 1476 if ( !aSuggestedDir.getLength() ) 1477 { 1478 aSuggestedDir = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() ); 1479 if ( !aSuggestedDir.getLength() ) 1480 aSuggestedDir = aModelData.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() ); 1481 } 1482 1483 aSuggestedName = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() ); 1484 if ( !aSuggestedName.getLength() ) 1485 aSuggestedName = aModelData.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() ); 1486 1487 ::rtl::OUString sStandardDir; 1488 ::comphelper::SequenceAsHashMap::const_iterator aStdDirIter = 1489 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "StandardDir" ) ); 1490 if ( aStdDirIter != aModelData.GetMediaDescr().end() ) 1491 aStdDirIter->second >>= sStandardDir; 1492 1493 ::com::sun::star::uno::Sequence< ::rtl::OUString > aBlackList; 1494 1495 ::comphelper::SequenceAsHashMap::const_iterator aBlackListIter = 1496 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "BlackList" ) ); 1497 if ( aBlackListIter != aModelData.GetMediaDescr().end() ) 1498 aBlackListIter->second >>= aBlackList; 1499 1500 sal_Bool bExit = sal_False; 1501 while ( !bExit ) 1502 { 1503 bUseFilterOptions = aModelData.OutputFileDialog( nStoreMode, aFilterProps, bSetStandardName, aSuggestedName, bPreselectPassword, aSuggestedDir, nDialog, sStandardDir, aBlackList ); 1504 1505 // in case the dialog is opend a second time the folder should be the same as before, not what was handed over by parameters 1506 aSuggestedDir = ::rtl::OUString(); 1507 if ( nStoreMode == SAVEAS_REQUESTED ) 1508 { 1509 // in case of saving check filter for possible alien warning 1510 ::rtl::OUString aSelFilterName = aModelData.GetMediaDescr().getUnpackedValueOrDefault( 1511 aFilterNameString, 1512 ::rtl::OUString() ); 1513 sal_Int8 nStatusFilterSave = aModelData.CheckFilter( aSelFilterName ); 1514 if ( nStatusFilterSave == STATUS_SAVEAS_STANDARDNAME ) 1515 { 1516 // switch to best filter 1517 bSetStandardName = sal_True; 1518 } 1519 else if ( nStatusFilterSave == STATUS_SAVE ) 1520 { 1521 // user confirmed alien filter or "good" filter is used 1522 bExit = sal_True; 1523 } 1524 } 1525 else 1526 bExit = sal_True; 1527 } 1528 1529 bDialogUsed = sal_True; 1530 aFileNameIter = aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "URL" ) ); 1531 } 1532 else 1533 { 1534 // the target file name is provided so check if new filter options 1535 // are provided or old options can be used 1536 if ( aFilterFromMediaDescr.equals( aOldFilterName ) ) 1537 { 1538 ::comphelper::SequenceAsHashMap::const_iterator aIter = 1539 aModelData.GetDocProps().find( aFilterOptionsString ); 1540 if ( aIter != aModelData.GetDocProps().end() 1541 && aModelData.GetMediaDescr().find( aFilterOptionsString ) == aModelData.GetMediaDescr().end() ) 1542 aModelData.GetMediaDescr()[aIter->first] = aIter->second; 1543 1544 aIter = aModelData.GetDocProps().find( aFilterDataString ); 1545 if ( aIter != aModelData.GetDocProps().end() 1546 && aModelData.GetMediaDescr().find( aFilterDataString ) == aModelData.GetMediaDescr().end() ) 1547 aModelData.GetMediaDescr()[aIter->first] = aIter->second; 1548 } 1549 } 1550 1551 if ( aFileNameIter != aModelData.GetMediaDescr().end() ) 1552 { 1553 ::rtl::OUString aFileName; 1554 aFileNameIter->second >>= aFileName; 1555 aURL.SetURL( aFileName ); 1556 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" ); 1557 1558 ::comphelper::SequenceAsHashMap::const_iterator aIter = 1559 aModelData.GetMediaDescr().find( aFilterNameString ); 1560 1561 if ( aIter != aModelData.GetMediaDescr().end() ) 1562 aIter->second >>= aFilterName; 1563 else 1564 aModelData.GetMediaDescr()[aFilterNameString] <<= aFilterName; 1565 1566 DBG_ASSERT( aFilterName.getLength(), "Illegal filter!" ); 1567 } 1568 else 1569 { 1570 DBG_ASSERT( sal_False, "This code must be unreachable!\n" ); 1571 throw task::ErrorCodeIOException( ::rtl::OUString(), 1572 uno::Reference< uno::XInterface >(), 1573 ERRCODE_IO_INVALIDPARAMETER ); 1574 } 1575 1576 ::comphelper::SequenceAsHashMap::const_iterator aIter = 1577 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "FilterFlags" ) ); 1578 sal_Bool bFilterFlagsSet = ( aIter != aModelData.GetMediaDescr().end() ); 1579 1580 if( !( nStoreMode & PDFEXPORT_REQUESTED ) && !bFilterFlagsSet 1581 && ( ( nStoreMode & EXPORT_REQUESTED ) || bUseFilterOptions ) ) 1582 { 1583 // execute filter options dialog 1584 if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) ) 1585 bDialogUsed = sal_True; 1586 } 1587 1588 // so the arguments will not change any more and can be stored to the main location 1589 aArgsSequence = aModelData.GetMediaDescr().getAsConstPropertyValueList(); 1590 1591 // store the document and handle it's docinfo 1592 SvtSaveOptions aOptions; 1593 1594 DocumentSettingsGuard aSettingsGuard( aModelData.GetModel(), aModelData.IsRecommendReadOnly(), nStoreMode & EXPORT_REQUESTED ); 1595 1596 OSL_ENSURE( aModelData.GetMediaDescr().find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ) ) == aModelData.GetMediaDescr().end(), "The Password property of MediaDescriptor should not be used here!" ); 1597 if ( aOptions.IsDocInfoSave() 1598 && ( !aModelData.GetStorable()->hasLocation() 1599 || INetURLObject( aModelData.GetStorable()->getLocation() ) != aURL ) ) 1600 { 1601 // this is defenitly not a Save operation 1602 // so the document info can be updated 1603 1604 // on export document info must be preserved 1605 uno::Reference<document::XDocumentInfoSupplier> xDIS( 1606 aModelData.GetModel(), uno::UNO_QUERY_THROW); 1607 uno::Reference<util::XCloneable> xCloneable( 1608 xDIS->getDocumentInfo(), uno::UNO_QUERY_THROW); 1609 uno::Reference<document::XDocumentInfo> xOldDocInfo( 1610 xCloneable->createClone(), uno::UNO_QUERY_THROW); 1611 1612 // use dispatch API to show document info dialog 1613 if ( aModelData.ShowDocumentInfoDialog() ) 1614 bDialogUsed = sal_True; 1615 else 1616 { 1617 DBG_ERROR( "Can't execute document info dialog!\n" ); 1618 } 1619 1620 try { 1621 // Document properties can contain streams that should be freed before storing 1622 aModelData.FreeDocumentProps(); 1623 if ( ( nStoreMode & EXPORT_REQUESTED ) ) 1624 aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence ); 1625 else 1626 aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence ); 1627 } 1628 catch( uno::Exception& ) 1629 { 1630 if ( ( nStoreMode & EXPORT_REQUESTED ) ) 1631 SetDocInfoState( aModelData.GetModel(), xOldDocInfo, sal_True ); 1632 1633 throw; 1634 } 1635 1636 if ( ( nStoreMode & EXPORT_REQUESTED ) ) 1637 SetDocInfoState( aModelData.GetModel(), xOldDocInfo, sal_True ); 1638 } 1639 else 1640 { 1641 // Document properties can contain streams that should be freed before storing 1642 aModelData.FreeDocumentProps(); 1643 1644 // this is actually a save operation with different parameters 1645 // so storeTo or storeAs without DocInfo operations are used 1646 if ( ( nStoreMode & EXPORT_REQUESTED ) ) 1647 aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence ); 1648 else 1649 aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence ); 1650 } 1651 1652 return bDialogUsed; 1653 } 1654 1655 //------------------------------------------------------------------------- 1656 // static 1657 sal_Bool SfxStoringHelper::CheckFilterOptionsAppearence( 1658 const uno::Reference< container::XNameAccess >& xFilterCFG, 1659 const ::rtl::OUString& aFilterName ) 1660 { 1661 sal_Bool bUseFilterOptions = sal_False; 1662 1663 DBG_ASSERT( xFilterCFG.is(), "No filter configuration!\n" ); 1664 if( xFilterCFG.is() ) 1665 { 1666 try { 1667 uno::Sequence < beans::PropertyValue > aProps; 1668 uno::Any aAny = xFilterCFG->getByName( aFilterName ); 1669 if ( aAny >>= aProps ) 1670 { 1671 ::comphelper::SequenceAsHashMap aPropsHM( aProps ); 1672 ::rtl::OUString aServiceName = aPropsHM.getUnpackedValueOrDefault( 1673 ::rtl::OUString::createFromAscii( "UIComponent" ), 1674 ::rtl::OUString() ); 1675 if( aServiceName.getLength() ) 1676 bUseFilterOptions = sal_True; 1677 } 1678 } 1679 catch( uno::Exception& ) 1680 { 1681 } 1682 } 1683 1684 return bUseFilterOptions; 1685 } 1686 1687 //------------------------------------------------------------------------- 1688 // static 1689 void SfxStoringHelper::SetDocInfoState( 1690 const uno::Reference< frame::XModel >& xModel, 1691 const uno::Reference< document::XDocumentInfo >& i_xOldDocInfo, 1692 sal_Bool bNoModify ) 1693 { 1694 uno::Reference< document::XDocumentInfoSupplier > xModelDocInfoSupplier( xModel, uno::UNO_QUERY ); 1695 if ( !xModelDocInfoSupplier.is() ) 1696 throw uno::RuntimeException(); // TODO: 1697 1698 uno::Reference< document::XDocumentInfo > xDocInfoToFill = xModelDocInfoSupplier->getDocumentInfo(); 1699 uno::Reference< beans::XPropertySet > xPropSet( i_xOldDocInfo, 1700 uno::UNO_QUERY_THROW ); 1701 1702 uno::Reference< util::XModifiable > xModifiable( xModel, uno::UNO_QUERY ); 1703 if ( bNoModify && !xModifiable.is() ) 1704 throw uno::RuntimeException(); 1705 1706 sal_Bool bIsModified = bNoModify && xModifiable->isModified(); 1707 1708 try 1709 { 1710 uno::Reference< beans::XPropertySet > xSet( xDocInfoToFill, uno::UNO_QUERY ); 1711 uno::Reference< beans::XPropertyContainer > xContainer( xSet, uno::UNO_QUERY ); 1712 uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo(); 1713 uno::Sequence< beans::Property > lProps = xSetInfo->getProperties(); 1714 const beans::Property* pProps = lProps.getConstArray(); 1715 sal_Int32 c = lProps.getLength(); 1716 sal_Int32 i = 0; 1717 for (i=0; i<c; ++i) 1718 { 1719 uno::Any aValue = xPropSet->getPropertyValue( pProps[i].Name ); 1720 if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE ) 1721 // QUESTION: DefaultValue?! 1722 xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue ); 1723 try 1724 { 1725 // it is possible that the propertysets from XML and binary files differ; we shouldn't break then 1726 xSet->setPropertyValue( pProps[i].Name, aValue ); 1727 } 1728 catch ( uno::Exception& ) {} 1729 } 1730 1731 sal_Int16 nCount = i_xOldDocInfo->getUserFieldCount(); 1732 sal_Int16 nSupportedCount = xDocInfoToFill->getUserFieldCount(); 1733 for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ ) 1734 { 1735 ::rtl::OUString aPropName = i_xOldDocInfo->getUserFieldName( nInd ); 1736 xDocInfoToFill->setUserFieldName( nInd, aPropName ); 1737 ::rtl::OUString aPropVal = i_xOldDocInfo->getUserFieldValue( nInd ); 1738 xDocInfoToFill->setUserFieldValue( nInd, aPropVal ); 1739 } 1740 } 1741 catch ( uno::Exception& ) {} 1742 1743 // set the modified flag back if required 1744 if ( bNoModify && bIsModified != xModifiable->isModified() ) 1745 xModifiable->setModified( bIsModified ); 1746 } 1747 1748 //------------------------------------------------------------------------- 1749 // static 1750 sal_Bool SfxStoringHelper::WarnUnacceptableFormat( const uno::Reference< frame::XModel >& xModel, 1751 ::rtl::OUString aOldUIName, 1752 ::rtl::OUString /*aDefUIName*/, 1753 sal_Bool /*bCanProceedFurther*/ ) 1754 { 1755 if ( !SvtSaveOptions().IsWarnAlienFormat() ) 1756 return sal_True; 1757 1758 Window* pWin = SfxStoringHelper::GetModelWindow( xModel ); 1759 SfxAlienWarningDialog aDlg( pWin, aOldUIName ); 1760 1761 return aDlg.Execute() == RET_OK; 1762 } 1763 1764 // static 1765 void SfxStoringHelper::ExecuteFilterDialog( SfxStoringHelper& _rStorageHelper 1766 ,const ::rtl::OUString& _sFilterName 1767 ,const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _xModel 1768 ,/*OUT*/::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArgsSequence) 1769 { 1770 ModelData_Impl aModelData( _rStorageHelper, _xModel, _rArgsSequence ); 1771 if ( aModelData.ExecuteFilterDialog_Impl( _sFilterName ) ) 1772 _rArgsSequence = aModelData.GetMediaDescr().getAsConstPropertyValueList(); 1773 } 1774 1775 // static 1776 Window* SfxStoringHelper::GetModelWindow( const uno::Reference< frame::XModel >& xModel ) 1777 { 1778 Window* pWin = 0; 1779 try { 1780 if ( xModel.is() ) 1781 { 1782 uno::Reference< frame::XController > xController = xModel->getCurrentController(); 1783 if ( xController.is() ) 1784 { 1785 uno::Reference< frame::XFrame > xFrame = xController->getFrame(); 1786 if ( xFrame.is() ) 1787 { 1788 uno::Reference< awt::XWindow > xWindow = xFrame->getContainerWindow(); 1789 if ( xWindow.is() ) 1790 { 1791 VCLXWindow* pVCLWindow = VCLXWindow::GetImplementation( xWindow ); 1792 if ( pVCLWindow ) 1793 pWin = pVCLWindow->GetWindow(); 1794 } 1795 } 1796 } 1797 } 1798 } 1799 catch ( uno::Exception& ) 1800 { 1801 } 1802 1803 return pWin; 1804 } 1805 1806