update dev300-m58
[ooovba.git] / sfx2 / source / doc / guisaveas.cxx
blob81bfa646cf8268c5a29d554a9f5f478138ff5cec
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: guisaveas.cxx,v $
10 * $Revision: 1.37 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
34 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
35 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
36 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
37 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
38 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
39 #include <com/sun/star/view/XSelectionSupplier.hpp>
40 #include <com/sun/star/beans/XPropertyAccess.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/beans/XPropertyContainer.hpp>
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <com/sun/star/document/XExporter.hpp>
45 #include <com/sun/star/document/XDocumentInfoSupplier.hpp>
46 #include <com/sun/star/document/XDocumentInfo.hpp>
47 #include <com/sun/star/task/XInteractionHandler.hpp>
48 #include <com/sun/star/util/DateTime.hpp>
49 #include <com/sun/star/util/XURLTransformer.hpp>
50 #include <com/sun/star/frame/XStorable.hpp>
51 #include <com/sun/star/frame/XStorable2.hpp>
52 #include <com/sun/star/frame/XDispatchProvider.hpp>
53 #include <com/sun/star/frame/XDispatch.hpp>
54 #include <com/sun/star/frame/XTitle.hpp>
55 #include <com/sun/star/util/XModifyListener.hpp>
56 #include <com/sun/star/util/XModifiable.hpp>
57 #include <com/sun/star/util/XModifyBroadcaster.hpp>
59 #include <com/sun/star/util/XCloneable.hpp>
60 #include <com/sun/star/frame/XModuleManager.hpp>
61 #include <com/sun/star/io/IOException.hpp>
63 #include "guisaveas.hxx"
65 #include <svtools/pathoptions.hxx>
66 #include <svtools/pathoptions.hxx>
67 #include <svtools/itemset.hxx>
68 #include <svtools/adrparse.hxx>
69 #include <svtools/useroptions.hxx>
70 #include <svtools/saveopt.hxx>
71 #include <tools/debug.hxx>
72 #include <tools/urlobj.hxx>
73 #include <comphelper/processfactory.hxx>
74 #include <comphelper/configurationhelper.hxx>
75 #include <vcl/msgbox.hxx>
76 #include <vcl/window.hxx>
77 #include <toolkit/awt/vclxwindow.hxx>
79 #include <sfx2/sfxsids.hrc>
80 #include <doc.hrc>
81 #include <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 <sfxtypes.hxx>
88 #include "alienwarn.hxx"
90 #define DOCPROPSNUM 17
92 // flags that specify requested operation
93 #define EXPORT_REQUESTED 1
94 #define PDFEXPORT_REQUESTED 2
95 #define PDFDIRECTEXPORT_REQUESTED 4
96 #define WIDEEXPORT_REQUESTED 8
97 #define SAVE_REQUESTED 16
98 #define SAVEAS_REQUESTED 32
100 // possible statuses of save operation
101 #define STATUS_NO_ACTION 0
102 #define STATUS_SAVE 1
103 #define STATUS_SAVEAS 2
104 #define STATUS_SAVEAS_STANDARDNAME 3
106 const ::rtl::OUString aFilterNameString = ::rtl::OUString::createFromAscii( "FilterName" );
107 const ::rtl::OUString aFilterOptionsString = ::rtl::OUString::createFromAscii( "FilterOptions" );
108 const ::rtl::OUString aFilterDataString = ::rtl::OUString::createFromAscii( "FilterData" );
109 const ::rtl::OUString aFilterFlagsString = ::rtl::OUString::createFromAscii( "FilterFlags" );
111 using namespace ::com::sun::star;
113 //-------------------------------------------------------------------------
114 static sal_uInt16 getSlotIDFromMode( sal_Int8 nStoreMode )
116 // This is a temporary hardcoded solution must be removed when
117 // dialogs do not need parameters in SidSet representation any more
119 sal_uInt16 nResult = 0;
120 if ( nStoreMode == EXPORT_REQUESTED )
121 nResult = SID_EXPORTDOC;
122 else if ( nStoreMode == ( EXPORT_REQUESTED | PDFEXPORT_REQUESTED ) )
123 nResult = SID_EXPORTDOCASPDF;
124 else if ( nStoreMode == ( EXPORT_REQUESTED | PDFEXPORT_REQUESTED | PDFDIRECTEXPORT_REQUESTED ) )
125 nResult = SID_DIRECTEXPORTDOCASPDF;
126 else if ( nStoreMode == SAVEAS_REQUESTED || nStoreMode == ( EXPORT_REQUESTED | WIDEEXPORT_REQUESTED ) )
127 nResult = SID_SAVEASDOC;
128 else {
129 DBG_ASSERT( sal_False, "Unacceptable slot name is provided!\n" );
132 return nResult;
135 //-------------------------------------------------------------------------
136 static sal_uInt8 getStoreModeFromSlotName( const ::rtl::OUString& aSlotName )
138 sal_uInt8 nResult = 0;
139 if ( aSlotName.equalsAscii( "ExportTo" ) )
140 nResult = EXPORT_REQUESTED;
141 else if ( aSlotName.equalsAscii( "ExportToPDF" ) )
142 nResult = EXPORT_REQUESTED | PDFEXPORT_REQUESTED;
143 else if ( aSlotName.equalsAscii( "ExportDirectToPDF" ) )
144 nResult = EXPORT_REQUESTED | PDFEXPORT_REQUESTED | PDFDIRECTEXPORT_REQUESTED;
145 else if ( aSlotName.equalsAscii( "Save" ) )
146 nResult = SAVE_REQUESTED;
147 else if ( aSlotName.equalsAscii( "SaveAs" ) )
148 nResult = SAVEAS_REQUESTED;
149 else
150 throw task::ErrorCodeIOException( ::rtl::OUString(),
151 uno::Reference< uno::XInterface >(),
152 ERRCODE_IO_INVALIDPARAMETER );
154 return nResult;
157 //-------------------------------------------------------------------------
158 static sal_Int32 getMustFlags( sal_Int8 nStoreMode )
160 return ( SFX_FILTER_EXPORT
161 | ( ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) ? 0 : SFX_FILTER_IMPORT ) );
164 //-------------------------------------------------------------------------
165 static sal_Int32 getDontFlags( sal_Int8 nStoreMode )
167 return ( SFX_FILTER_INTERNAL
168 | SFX_FILTER_NOTINFILEDLG
169 | ( ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) ) ? SFX_FILTER_IMPORT : 0 ) );
172 //=========================================================================
173 // class ModelData_Impl
174 //=========================================================================
175 class ModelData_Impl
177 SfxStoringHelper* m_pOwner;
178 uno::Reference< frame::XModel > m_xModel;
179 uno::Reference< frame::XStorable > m_xStorable;
180 uno::Reference< frame::XStorable2 > m_xStorable2;
181 uno::Reference< util::XModifiable > m_xModifiable;
183 ::rtl::OUString m_aModuleName;
184 ::comphelper::SequenceAsHashMap* m_pDocumentPropsHM;
185 ::comphelper::SequenceAsHashMap* m_pModulePropsHM;
187 ::comphelper::SequenceAsHashMap m_aMediaDescrHM;
189 public:
190 ModelData_Impl( SfxStoringHelper& aOwner,
191 const uno::Reference< frame::XModel >& xModel,
192 const uno::Sequence< beans::PropertyValue >& aMediaDescr );
194 ~ModelData_Impl();
196 void FreeDocumentProps();
198 uno::Reference< frame::XModel > GetModel();
199 uno::Reference< frame::XStorable > GetStorable();
200 uno::Reference< frame::XStorable2 > GetStorable2();
201 uno::Reference< util::XModifiable > GetModifiable();
203 ::comphelper::SequenceAsHashMap& GetMediaDescr() { return m_aMediaDescrHM; }
205 const ::comphelper::SequenceAsHashMap& GetDocProps();
207 ::rtl::OUString GetModuleName();
208 const ::comphelper::SequenceAsHashMap& GetModuleProps();
210 void CheckInteractionHandler();
213 ::rtl::OUString GetDocServiceName();
214 uno::Sequence< beans::PropertyValue > GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust, sal_Int32 nDont );
215 uno::Sequence< beans::PropertyValue > GetDocServiceAnyFilter( sal_Int32 nMust, sal_Int32 nDont );
216 uno::Sequence< beans::PropertyValue > GetPreselectedFilter_Impl( sal_Int8 nStoreMode );
217 uno::Sequence< beans::PropertyValue > GetDocServiceDefaultFilter();
219 sal_Bool ExecuteFilterDialog_Impl( const ::rtl::OUString& aFilterName );
221 sal_Int8 CheckSaveAcceptable( sal_Int8 nCurStatus );
222 sal_Int8 CheckStateForSave();
224 sal_Int8 CheckFilter( const ::rtl::OUString& );
226 sal_Bool CheckFilterOptionsDialogExistence();
228 sal_Bool OutputFileDialog( sal_Int8 nStoreMode,
229 const ::comphelper::SequenceAsHashMap& aPreselectedFilterPropsHM,
230 sal_Bool bSetStandardName,
231 ::rtl::OUString& aSuggestedName,
232 sal_Bool bPreselectPassword,
233 const ::rtl::OUString& aSuggestedDir,
234 sal_Int16 nDialog,
235 const ::rtl::OUString& rStandardDir,
236 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList
239 sal_Bool ShowDocumentInfoDialog();
241 ::rtl::OUString GetReccomendedDir( const ::rtl::OUString& aSuggestedDir,
242 const sfx2::FileDialogHelper::Context& aCtxt );
243 ::rtl::OUString GetReccomendedName( const ::rtl::OUString& aSuggestedName,
244 const ::rtl::OUString& aTypeName );
248 //-------------------------------------------------------------------------
249 ModelData_Impl::ModelData_Impl( SfxStoringHelper& aOwner,
250 const uno::Reference< frame::XModel >& xModel,
251 const uno::Sequence< beans::PropertyValue >& aMediaDescr )
252 : m_pOwner( &aOwner )
253 , m_xModel( xModel )
254 , m_pDocumentPropsHM( NULL )
255 , m_pModulePropsHM( NULL )
256 , m_aMediaDescrHM( aMediaDescr )
258 CheckInteractionHandler();
261 //-------------------------------------------------------------------------
262 ModelData_Impl::~ModelData_Impl()
264 FreeDocumentProps();
265 if ( m_pDocumentPropsHM )
266 delete m_pDocumentPropsHM;
268 if ( m_pModulePropsHM )
269 delete m_pModulePropsHM;
272 //-------------------------------------------------------------------------
273 void ModelData_Impl::FreeDocumentProps()
275 if ( m_pDocumentPropsHM )
277 delete m_pDocumentPropsHM;
278 m_pDocumentPropsHM = NULL;
282 //-------------------------------------------------------------------------
283 uno::Reference< frame::XModel > ModelData_Impl::GetModel()
285 if ( !m_xModel.is() )
286 throw uno::RuntimeException();
288 return m_xModel;
291 //-------------------------------------------------------------------------
292 uno::Reference< frame::XStorable > ModelData_Impl::GetStorable()
294 if ( !m_xStorable.is() )
296 m_xStorable = uno::Reference< frame::XStorable >( m_xModel, uno::UNO_QUERY );
297 if ( !m_xStorable.is() )
298 throw uno::RuntimeException();
301 return m_xStorable;
304 //-------------------------------------------------------------------------
305 uno::Reference< frame::XStorable2 > ModelData_Impl::GetStorable2()
307 if ( !m_xStorable2.is() )
309 m_xStorable2 = uno::Reference< frame::XStorable2 >( m_xModel, uno::UNO_QUERY );
310 if ( !m_xStorable2.is() )
311 throw uno::RuntimeException();
314 return m_xStorable2;
317 //-------------------------------------------------------------------------
318 uno::Reference< util::XModifiable > ModelData_Impl::GetModifiable()
320 if ( !m_xModifiable.is() )
322 m_xModifiable = uno::Reference< util::XModifiable >( m_xModel, uno::UNO_QUERY );
323 if ( !m_xModifiable.is() )
324 throw uno::RuntimeException();
327 return m_xModifiable;
330 //-------------------------------------------------------------------------
331 const ::comphelper::SequenceAsHashMap& ModelData_Impl::GetDocProps()
333 if ( !m_pDocumentPropsHM )
334 m_pDocumentPropsHM = new ::comphelper::SequenceAsHashMap( GetModel()->getArgs() );
336 return *m_pDocumentPropsHM;
339 //-------------------------------------------------------------------------
340 ::rtl::OUString ModelData_Impl::GetModuleName()
342 if ( !m_aModuleName.getLength() )
344 m_aModuleName = m_pOwner->GetModuleManager()->identify(
345 uno::Reference< uno::XInterface >( m_xModel, uno::UNO_QUERY ) );
346 if ( !m_aModuleName.getLength() )
347 throw uno::RuntimeException(); // TODO:
349 return m_aModuleName;
352 //-------------------------------------------------------------------------
353 const ::comphelper::SequenceAsHashMap& ModelData_Impl::GetModuleProps()
355 if ( !m_pModulePropsHM )
357 uno::Sequence< beans::PropertyValue > aModuleProps;
358 m_pOwner->GetNamedModuleManager()->getByName( GetModuleName() ) >>= aModuleProps;
359 if ( !aModuleProps.getLength() )
360 throw uno::RuntimeException(); // TODO;
361 m_pModulePropsHM = new ::comphelper::SequenceAsHashMap( aModuleProps );
364 return *m_pModulePropsHM;
367 //-------------------------------------------------------------------------
368 ::rtl::OUString ModelData_Impl::GetDocServiceName()
370 return GetModuleProps().getUnpackedValueOrDefault(::rtl::OUString::createFromAscii( "ooSetupFactoryDocumentService" ), ::rtl::OUString());
373 //-------------------------------------------------------------------------
374 void ModelData_Impl::CheckInteractionHandler()
376 ::comphelper::SequenceAsHashMap::const_iterator aInteractIter =
377 m_aMediaDescrHM.find( ::rtl::OUString::createFromAscii( "InteractionHandler" ) );
379 if ( aInteractIter == m_aMediaDescrHM.end() )
381 try {
382 m_aMediaDescrHM[ ::rtl::OUString::createFromAscii( "InteractionHandler" ) ]
383 <<= uno::Reference< task::XInteractionHandler >(
384 m_pOwner->GetServiceFactory()->createInstance(
385 DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ),
386 uno::UNO_QUERY );
388 catch( uno::Exception& )
392 else
394 uno::Reference< task::XInteractionHandler > xInteract;
395 DBG_ASSERT( ( aInteractIter->second >>= xInteract ) && xInteract.is(), "Broken interaction handler is provided!\n" );
399 //-------------------------------------------------------------------------
400 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceDefaultFilter()
402 uno::Sequence< beans::PropertyValue > aProps;
404 ::rtl::OUString aFilterName = GetModuleProps().getUnpackedValueOrDefault(
405 ::rtl::OUString::createFromAscii( "ooSetupFactoryDefaultFilter" ),
406 ::rtl::OUString() );
408 m_pOwner->GetFilterConfiguration()->getByName( aFilterName ) >>= aProps;
410 return aProps;
413 //-------------------------------------------------------------------------
414 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust,
415 sal_Int32 nDont )
417 uno::Sequence< beans::PropertyValue > aFilterProps;
418 uno::Sequence< beans::PropertyValue > aProps = GetDocServiceDefaultFilter();
419 if ( aProps.getLength() )
421 ::comphelper::SequenceAsHashMap aFiltHM( aProps );
422 sal_Int32 nFlags = aFiltHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ),
423 (sal_Int32)0 );
424 if ( ( ( nFlags & nMust ) == nMust ) && !( nFlags & nDont ) )
425 aFilterProps = aProps;
428 return aFilterProps;
432 //-------------------------------------------------------------------------
433 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetDocServiceAnyFilter( sal_Int32 nMust, sal_Int32 nDont )
435 uno::Sequence< beans::NamedValue > aSearchRequest( 1 );
436 aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "DocumentService" );
437 aSearchRequest[0].Value <<= GetDocServiceName();
439 return SfxStoringHelper::SearchForFilter( m_pOwner->GetFilterQuery(), aSearchRequest, nMust, nDont );
442 //-------------------------------------------------------------------------
443 uno::Sequence< beans::PropertyValue > ModelData_Impl::GetPreselectedFilter_Impl( sal_Int8 nStoreMode )
445 uno::Sequence< beans::PropertyValue > aFilterProps;
447 sal_Int32 nMust = getMustFlags( nStoreMode );
448 sal_Int32 nDont = getDontFlags( nStoreMode );
450 if ( nStoreMode & PDFEXPORT_REQUESTED )
452 // Preselect PDF-Filter for EXPORT
453 uno::Sequence< beans::NamedValue > aSearchRequest( 2 );
454 aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "Type" );
455 aSearchRequest[0].Value <<= ::rtl::OUString::createFromAscii( "pdf_Portable_Document_Format" );
456 aSearchRequest[1].Name = ::rtl::OUString::createFromAscii( "DocumentService" );
457 aSearchRequest[1].Value <<= GetDocServiceName();
459 aFilterProps = SfxStoringHelper::SearchForFilter( m_pOwner->GetFilterQuery(), aSearchRequest, nMust, nDont );
461 else
463 aFilterProps = GetDocServiceDefaultFilterCheckFlags( nMust, nDont );
465 if ( !aFilterProps.getLength() )
467 // the default filter was not faund, use just the first acceptable one
468 aFilterProps = GetDocServiceAnyFilter( nMust, nDont );
472 return aFilterProps;
475 //-------------------------------------------------------------------------
476 sal_Bool ModelData_Impl::ExecuteFilterDialog_Impl( const ::rtl::OUString& aFilterName )
478 sal_Bool bDialogUsed = sal_False;
480 try {
481 uno::Sequence < beans::PropertyValue > aProps;
482 uno::Any aAny = m_pOwner->GetFilterConfiguration()->getByName( aFilterName );
483 if ( aAny >>= aProps )
485 sal_Int32 nPropertyCount = aProps.getLength();
486 for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
487 if( aProps[nProperty].Name.equals( ::rtl::OUString::createFromAscii("UIComponent")) )
489 ::rtl::OUString aServiceName;
490 aProps[nProperty].Value >>= aServiceName;
491 if( aServiceName.getLength() )
493 uno::Reference< ui::dialogs::XExecutableDialog > xFilterDialog(
494 m_pOwner->GetServiceFactory()->createInstance( aServiceName ), uno::UNO_QUERY );
495 uno::Reference< beans::XPropertyAccess > xFilterProperties( xFilterDialog, uno::UNO_QUERY );
497 if( xFilterDialog.is() && xFilterProperties.is() )
499 bDialogUsed = sal_True;
501 uno::Reference< document::XExporter > xExporter( xFilterDialog, uno::UNO_QUERY );
502 if( xExporter.is() )
503 xExporter->setSourceDocument(
504 uno::Reference< lang::XComponent >( GetModel(), uno::UNO_QUERY ) );
506 uno::Sequence< beans::PropertyValue > aPropsForDialog;
507 GetMediaDescr() >> aPropsForDialog;
508 xFilterProperties->setPropertyValues( aPropsForDialog );
510 if( xFilterDialog->execute() )
512 uno::Sequence< beans::PropertyValue > aPropsFromDialog =
513 xFilterProperties->getPropertyValues();
514 for ( sal_Int32 nInd = 0; nInd < aPropsFromDialog.getLength(); nInd++ )
515 GetMediaDescr()[aPropsFromDialog[nInd].Name] = aPropsFromDialog[nInd].Value;
517 else
519 throw task::ErrorCodeIOException( ::rtl::OUString(),
520 uno::Reference< uno::XInterface >(),
521 ERRCODE_IO_ABORT );
526 break;
530 catch( container::NoSuchElementException& )
532 // the filter name is unknown
533 throw task::ErrorCodeIOException( ::rtl::OUString(),
534 uno::Reference< uno::XInterface >(),
535 ERRCODE_IO_INVALIDPARAMETER );
537 catch( task::ErrorCodeIOException& )
539 throw;
541 catch( uno::Exception& )
545 return bDialogUsed;
548 //-------------------------------------------------------------------------
549 sal_Int8 ModelData_Impl::CheckSaveAcceptable( sal_Int8 nCurStatus )
551 sal_Int8 nResult = nCurStatus;
553 if ( nResult != STATUS_NO_ACTION && GetStorable()->hasLocation() )
555 // check whether save is acceptable by the configuration
556 // it is done only for documents that have persistence already
557 uno::Reference< uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig(
558 m_pOwner->GetServiceFactory(),
559 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
560 ::comphelper::ConfigurationHelper::E_STANDARD );
561 if ( !xCommonConfig.is() )
562 throw uno::RuntimeException(); // should the saving proceed as usual instead?
566 sal_Bool bAlwaysSaveAs = sal_False;
568 // the saving is acceptable
569 // in case the configuration entry is not set or set to false
570 // or in case of version creation
571 ::rtl::OUString aVersionCommentString = ::rtl::OUString::createFromAscii( "VersionComment" );
572 if ( ( ::comphelper::ConfigurationHelper::readRelativeKey(
573 xCommonConfig,
574 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Save/Document/" ) ),
575 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AlwaysSaveAs" ) ) ) >>= bAlwaysSaveAs )
576 && bAlwaysSaveAs
577 && GetMediaDescr().find( aVersionCommentString ) == GetMediaDescr().end() )
579 // notify the user that SaveAs is going to be done
580 String aString( SfxResId( STR_NEW_FILENAME_SAVE ) );
581 Window* pWin = SfxStoringHelper::GetModelWindow( m_xModel );
582 QueryBox aMessageBox( pWin, WB_OK_CANCEL | WB_DEF_OK, aString );
583 if ( aMessageBox.Execute() == RET_OK )
584 nResult = STATUS_SAVEAS;
585 else
586 nResult = STATUS_NO_ACTION;
589 catch( uno::Exception& )
591 // impossibility to get the configuration access means normal saving flow for now
595 return nResult;
598 //-------------------------------------------------------------------------
599 sal_Int8 ModelData_Impl::CheckStateForSave()
601 // check acceptable entries for media descriptor
602 sal_Bool bVersInfoNeedsStore = sal_False;
603 ::comphelper::SequenceAsHashMap aAcceptedArgs;
605 ::rtl::OUString aVersionCommentString = ::rtl::OUString::createFromAscii( "VersionComment" );
606 ::rtl::OUString aAuthorString = ::rtl::OUString::createFromAscii( "Author" );
607 ::rtl::OUString aInteractionHandlerString = ::rtl::OUString::createFromAscii( "InteractionHandler" );
608 ::rtl::OUString aStatusIndicatorString = ::rtl::OUString::createFromAscii( "StatusIndicator" );
609 ::rtl::OUString aAlwaysSaveString = ::rtl::OUString::createFromAscii("AlwaysAllowSave");
611 if ( GetMediaDescr().find( aVersionCommentString ) != GetMediaDescr().end() )
613 bVersInfoNeedsStore = sal_True;
614 aAcceptedArgs[ aVersionCommentString ] = GetMediaDescr()[ aVersionCommentString ];
616 if ( GetMediaDescr().find( aAuthorString ) != GetMediaDescr().end() )
617 aAcceptedArgs[ aAuthorString ] = GetMediaDescr()[ aAuthorString ];
618 if ( GetMediaDescr().find( aInteractionHandlerString ) != GetMediaDescr().end() )
619 aAcceptedArgs[ aInteractionHandlerString ] = GetMediaDescr()[ aInteractionHandlerString ];
620 if ( GetMediaDescr().find( aStatusIndicatorString ) != GetMediaDescr().end() )
621 aAcceptedArgs[ aStatusIndicatorString ] = GetMediaDescr()[ aStatusIndicatorString ];
623 // remove unacceptable entry if there is any
624 DBG_ASSERT( GetMediaDescr().size() == aAcceptedArgs.size(),
625 "Unacceptable parameters are provided in Save request!\n" );
626 if ( GetMediaDescr().size() != aAcceptedArgs.size() )
627 GetMediaDescr() = aAcceptedArgs;
629 // the document must be modified unless the always-save flag is set.
630 sal_Bool bAlwaysAllowSave = sal_False;
631 uno::Reference<beans::XPropertySet> xPropSet(m_xModel, uno::UNO_QUERY);
632 if (xPropSet.is())
636 uno::Any any = xPropSet->getPropertyValue( aAlwaysSaveString );
637 any >>= bAlwaysAllowSave;
639 catch (const beans::UnknownPropertyException&)
641 // do nothing...
644 if (!bAlwaysAllowSave)
646 if ( !GetModifiable()->isModified() && !bVersInfoNeedsStore )
647 return STATUS_NO_ACTION;
650 // if the document is readonly or a new one a SaveAs operation must be used
651 if ( !GetStorable()->hasLocation() || GetStorable()->isReadonly() )
652 return STATUS_SAVEAS;
654 // check that the old filter is acceptable
655 ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault(
656 aFilterNameString,
657 ::rtl::OUString() );
658 sal_Int8 nResult = CheckFilter( aOldFilterName );
660 return nResult;
663 sal_Int8 ModelData_Impl::CheckFilter( const ::rtl::OUString& aFilterName )
665 ::comphelper::SequenceAsHashMap aFiltPropsHM;
666 sal_Int32 nFiltFlags = 0;
667 if ( aFilterName.getLength() )
669 // get properties of filter
670 uno::Sequence< beans::PropertyValue > aFilterProps;
671 if ( aFilterName.getLength() )
672 m_pOwner->GetFilterConfiguration()->getByName( aFilterName ) >>= aFilterProps;
674 aFiltPropsHM = ::comphelper::SequenceAsHashMap( aFilterProps );
675 nFiltFlags = aFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 );
678 // only a temporary solution until default filter retrieving feature is implemented
679 // then GetDocServiceDefaultFilter() must be used
680 ::comphelper::SequenceAsHashMap aDefFiltPropsHM = GetDocServiceDefaultFilterCheckFlags( 3, 0 );
681 sal_Int32 nDefFiltFlags = aDefFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 );
683 // if the old filter is not acceptable
684 // and there is no default filter or it is not acceptable for requested parameters then proceed with saveAs
685 if ( ( !aFiltPropsHM.size() || !( nFiltFlags & SFX_FILTER_EXPORT ) )
686 && ( !aDefFiltPropsHM.size() || !( nDefFiltFlags & SFX_FILTER_EXPORT ) || nDefFiltFlags & SFX_FILTER_INTERNAL ) )
687 return STATUS_SAVEAS;
689 // so at this point there is either an acceptable old filter or default one
690 if ( !aFiltPropsHM.size() || !( nFiltFlags & SFX_FILTER_EXPORT ) )
692 // so the default filter must be acceptable
693 return STATUS_SAVEAS_STANDARDNAME;
695 else if ( ( !( nFiltFlags & SFX_FILTER_OWN ) || ( nFiltFlags & SFX_FILTER_ALIEN ) )
696 && !( nFiltFlags & SFX_FILTER_SILENTEXPORT ) && aDefFiltPropsHM.size()
697 && ( nDefFiltFlags & SFX_FILTER_EXPORT ) && !( nDefFiltFlags & SFX_FILTER_INTERNAL ))
699 // the default filter is acceptable and the old filter is alian one
700 // so ask to make a saveAs operation
701 ::rtl::OUString aUIName = aFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "UIName" ),
702 ::rtl::OUString() );
703 ::rtl::OUString aDefUIName = aDefFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "UIName" ),
704 ::rtl::OUString() );
705 ::rtl::OUString aPreusedFilterName = GetDocProps().getUnpackedValueOrDefault(
706 ::rtl::OUString::createFromAscii( "PreusedFilterName" ),
707 ::rtl::OUString() );
708 if ( !aPreusedFilterName.equals( aFilterName ) && !aUIName.equals( aDefUIName ) )
710 if ( !SfxStoringHelper::WarnUnacceptableFormat( GetModel(), aUIName, aDefUIName, sal_True ) )
711 return STATUS_SAVEAS_STANDARDNAME;
715 return STATUS_SAVE;
718 //-------------------------------------------------------------------------
719 sal_Bool ModelData_Impl::CheckFilterOptionsDialogExistence()
721 uno::Sequence< beans::NamedValue > aSearchRequest( 1 );
722 aSearchRequest[0].Name = ::rtl::OUString::createFromAscii( "DocumentService" );
723 aSearchRequest[0].Value <<= GetDocServiceName();
725 uno::Reference< container::XEnumeration > xFilterEnum =
726 m_pOwner->GetFilterQuery()->createSubSetEnumerationByProperties( aSearchRequest );
728 while ( xFilterEnum->hasMoreElements() )
730 uno::Sequence< beans::PropertyValue > pProps;
731 if ( xFilterEnum->nextElement() >>= pProps )
733 ::comphelper::SequenceAsHashMap aPropsHM( pProps );
734 ::rtl::OUString aUIServName = aPropsHM.getUnpackedValueOrDefault(
735 ::rtl::OUString::createFromAscii( "UIComponent" ),
736 ::rtl::OUString() );
737 if ( aUIServName.getLength() )
738 return sal_True;
742 return sal_False;
745 //-------------------------------------------------------------------------
746 sal_Bool ModelData_Impl::OutputFileDialog( sal_Int8 nStoreMode,
747 const ::comphelper::SequenceAsHashMap& aPreselectedFilterPropsHM,
748 sal_Bool bSetStandardName,
749 ::rtl::OUString& aSuggestedName,
750 sal_Bool bPreselectPassword,
751 const ::rtl::OUString& aSuggestedDir,
752 sal_Int16 nDialog,
753 const ::rtl::OUString& rStandardDir,
754 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList)
756 sal_Bool bUseFilterOptions = sal_False;
758 ::comphelper::SequenceAsHashMap::const_iterator aOverwriteIter =
759 GetMediaDescr().find( ::rtl::OUString::createFromAscii( "Overwrite" ) );
761 // the file name must be specified if overwrite option is set
762 if ( aOverwriteIter != GetMediaDescr().end() )
763 throw task::ErrorCodeIOException( ::rtl::OUString(),
764 uno::Reference< uno::XInterface >(),
765 ERRCODE_IO_INVALIDPARAMETER );
767 // no target file name is specified
768 // we need to show the file dialog
770 // check if we have a filter which allows for filter options, so we need a corresponding checkbox in the dialog
771 sal_Bool bAllowOptions = sal_False;
773 // in case of Export, filter options dialog is used if available
774 if( !( nStoreMode & EXPORT_REQUESTED ) || ( nStoreMode & WIDEEXPORT_REQUESTED ) )
775 bAllowOptions = CheckFilterOptionsDialogExistence();
777 // get the filename by dialog ...
778 // create the file dialog
779 sal_Int16 aDialogMode = bAllowOptions
780 ? (com::sun::star::ui::dialogs::TemplateDescription::
781 FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS)
782 : (com::sun::star::ui::dialogs::TemplateDescription::
783 FILESAVE_AUTOEXTENSION_PASSWORD);
784 sal_Int64 aDialogFlags = 0;
786 if( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) )
788 if ( nStoreMode & PDFEXPORT_REQUESTED )
789 aDialogMode = com::sun::star::ui::dialogs::TemplateDescription::
790 FILESAVE_AUTOEXTENSION;
791 else
792 aDialogMode = com::sun::star::ui::dialogs::TemplateDescription::
793 FILESAVE_AUTOEXTENSION_SELECTION;
794 aDialogFlags = SFXWB_EXPORT;
797 sfx2::FileDialogHelper* pFileDlg = NULL;
799 ::rtl::OUString aDocServiceName = GetDocServiceName();
800 DBG_ASSERT( aDocServiceName.getLength(), "No document service for this module set!" );
802 sal_Int32 nMust = getMustFlags( nStoreMode );
803 sal_Int32 nDont = getDontFlags( nStoreMode );
804 sfx2::FileDialogHelper::Context eCtxt = sfx2::FileDialogHelper::UNKNOWN_CONTEXT;
806 if ( ( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED ) )
808 if ( ( nStoreMode & PDFEXPORT_REQUESTED ) && aPreselectedFilterPropsHM.size() )
810 // this is a PDF export
811 // the filter options has been shown already
812 ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
813 ::rtl::OUString::createFromAscii( "UIName" ),
814 ::rtl::OUString() );
816 pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aFilterUIName, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "pdf" ) ), rStandardDir, rBlackList );
817 pFileDlg->SetCurrentFilter( aFilterUIName );
819 else
821 // This is the normal dialog
822 pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aDocServiceName, nDialog, nMust, nDont, rStandardDir, rBlackList );
825 if( aDocServiceName.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) )
826 eCtxt = sfx2::FileDialogHelper::SD_EXPORT;
827 if( aDocServiceName.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) )
828 eCtxt = sfx2::FileDialogHelper::SI_EXPORT;
829 if( aDocServiceName.equalsAscii( "com.sun.star.text.TextDocument" ) )
830 eCtxt = sfx2::FileDialogHelper::SW_EXPORT;
832 if ( eCtxt != sfx2::FileDialogHelper::UNKNOWN_CONTEXT )
833 pFileDlg->SetContext( eCtxt );
835 pFileDlg->CreateMatcher( aDocServiceName );
837 uno::Reference< ui::dialogs::XFilePicker > xFilePicker = pFileDlg->GetFilePicker();
838 uno::Reference< ui::dialogs::XFilePickerControlAccess > xControlAccess =
839 uno::Reference< ui::dialogs::XFilePickerControlAccess >( xFilePicker, uno::UNO_QUERY );
841 if ( xControlAccess.is() )
843 ::rtl::OUString aCtrlText = String( SfxResId( STR_EXPORTBUTTON ) );
844 xControlAccess->setLabel( ui::dialogs::CommonFilePickerElementIds::PUSHBUTTON_OK, aCtrlText );
846 aCtrlText = ::rtl::OUString( String( SfxResId( STR_LABEL_FILEFORMAT ) ) );
847 xControlAccess->setLabel( ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER_LABEL, aCtrlText );
850 else
852 // This is the normal dialog
853 pFileDlg = new sfx2::FileDialogHelper( aDialogMode, aDialogFlags, aDocServiceName, nDialog, nMust, nDont, rStandardDir, rBlackList );
854 pFileDlg->CreateMatcher( aDocServiceName );
857 ::rtl::OUString aAdjustToType;
859 // bSetStandardName == true means that user agreed to store document in the default (default default ;-)) format
860 if ( !(( nStoreMode & EXPORT_REQUESTED ) && !( nStoreMode & WIDEEXPORT_REQUESTED )) &&
861 ( bSetStandardName || GetStorable()->hasLocation() ))
863 uno::Sequence< beans::PropertyValue > aOldFilterProps;
864 ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault(
865 aFilterNameString,
866 ::rtl::OUString() );
868 if ( aOldFilterName.getLength() )
869 m_pOwner->GetFilterConfiguration()->getByName( aOldFilterName ) >>= aOldFilterProps;
871 ::comphelper::SequenceAsHashMap aOldFiltPropsHM( aOldFilterProps );
872 sal_Int32 nOldFiltFlags = aOldFiltPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32)0 );
874 if ( bSetStandardName || ( nOldFiltFlags & nMust ) != nMust || nOldFiltFlags & nDont )
876 // the suggested type will be changed, the extension should be adjusted
877 aAdjustToType = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
878 ::rtl::OUString::createFromAscii( "Type" ),
879 ::rtl::OUString() );
881 ::rtl::OUString aFilterUIName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
882 ::rtl::OUString::createFromAscii( "UIName" ),
883 ::rtl::OUString() );
884 pFileDlg->SetCurrentFilter( aFilterUIName );
886 else
888 pFileDlg->SetCurrentFilter( aOldFiltPropsHM.getUnpackedValueOrDefault(
889 ::rtl::OUString::createFromAscii( "UIName" ),
890 ::rtl::OUString() ) );
894 ::rtl::OUString aReccomendedDir = GetReccomendedDir( aSuggestedDir, eCtxt );
895 if ( aReccomendedDir.getLength() )
896 pFileDlg->SetDisplayDirectory( aReccomendedDir );
897 ::rtl::OUString aReccomendedName = GetReccomendedName( aSuggestedName, aAdjustToType );
898 if ( aReccomendedName.getLength() )
899 pFileDlg->SetFileName( aReccomendedName );
901 uno::Reference < view::XSelectionSupplier > xSel( GetModel()->getCurrentController(), uno::UNO_QUERY );
902 if ( xSel.is() && xSel->getSelection().hasValue() )
903 GetMediaDescr()[::rtl::OUString::createFromAscii( "SelectionOnly" )] <<= sal_True;
905 // This is a temporary hardcoded solution must be removed when
906 // dialogs do not need parameters in SidSet representation any more
907 sal_uInt16 nSlotID = getSlotIDFromMode( nStoreMode );
908 if ( !nSlotID )
909 throw lang::IllegalArgumentException(); // TODO:
911 // generate SidSet from MediaDescriptor and provide it into FileDialog
912 // than merge changed SidSet back
913 SfxAllItemSet aDialogParams( SFX_APP()->GetPool() );
914 SfxItemSet* pDialogParams = &aDialogParams;
915 TransformParameters( nSlotID,
916 GetMediaDescr().getAsConstPropertyValueList(),
917 aDialogParams,
918 NULL );
920 const SfxPoolItem* pItem = NULL;
921 if ( bPreselectPassword && aDialogParams.GetItemState( SID_PASSWORD, sal_True, &pItem ) != SFX_ITEM_SET )
923 // the file dialog preselects the password checkbox if the provided mediadescriptor has password entry
924 // after dialog execution the password entry will be either removed or replaced with the password
925 // entered by the user
926 aDialogParams.Put( SfxStringItem( SID_PASSWORD, String() ) );
929 // aStringTypeFN is a pure output parameter, pDialogParams is an in/out parameter
930 String aStringTypeFN;
931 if ( pFileDlg->Execute( pDialogParams, aStringTypeFN ) != ERRCODE_NONE )
933 delete pFileDlg;
934 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
937 ::rtl::OUString aFilterName = aStringTypeFN;
939 uno::Sequence< beans::PropertyValue > aPropsFromDialog;
940 TransformItems( nSlotID, *pDialogParams, aPropsFromDialog, NULL );
941 GetMediaDescr() << aPropsFromDialog;
943 // get the path from the dialog
944 INetURLObject aURL( pFileDlg->GetPath() );
945 // the path should be provided outside since it might be used for further calls to the dialog
946 aSuggestedName = aURL.GetName( INetURLObject::DECODE_WITH_CHARSET );
948 // old filter options should be cleared in case different filter is used
950 ::rtl::OUString aFilterFromMediaDescr = GetMediaDescr().getUnpackedValueOrDefault(
951 aFilterNameString,
952 ::rtl::OUString() );
953 ::rtl::OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault(
954 aFilterNameString,
955 ::rtl::OUString() );
956 if ( aFilterName.equals( aFilterFromMediaDescr ) )
958 // preserv current settings if any
959 // if there no current settings and the name is the same
960 // as old filter name use old filter settings
962 if ( aFilterFromMediaDescr.equals( aOldFilterName ) )
964 ::comphelper::SequenceAsHashMap::const_iterator aIter =
965 GetDocProps().find( aFilterOptionsString );
966 if ( aIter != GetDocProps().end()
967 && GetMediaDescr().find( aFilterOptionsString ) == GetMediaDescr().end() )
968 GetMediaDescr()[aIter->first] = aIter->second;
970 aIter = GetDocProps().find( aFilterDataString );
971 if ( aIter != GetDocProps().end()
972 && GetMediaDescr().find( aFilterDataString ) == GetMediaDescr().end() )
973 GetMediaDescr()[aIter->first] = aIter->second;
976 else
978 GetMediaDescr().erase( aFilterDataString );
979 GetMediaDescr().erase( aFilterOptionsString );
981 if ( aFilterName.equals( aOldFilterName ) )
983 // merge filter option of the document filter
985 ::comphelper::SequenceAsHashMap::const_iterator aIter =
986 GetDocProps().find( aFilterOptionsString );
987 if ( aIter != GetDocProps().end() )
988 GetMediaDescr()[aIter->first] = aIter->second;
990 aIter = GetDocProps().find( aFilterDataString );
991 if ( aIter != GetDocProps().end() )
992 GetMediaDescr()[aIter->first] = aIter->second;
996 uno::Reference< ui::dialogs::XFilePickerControlAccess > xExtFileDlg( pFileDlg->GetFilePicker(), uno::UNO_QUERY );
997 if ( xExtFileDlg.is() )
999 if ( SfxStoringHelper::CheckFilterOptionsAppearence( m_pOwner->GetFilterConfiguration(), aFilterName ) )
1000 bUseFilterOptions = sal_True;
1002 if ( ( !( nStoreMode & EXPORT_REQUESTED ) || ( nStoreMode & WIDEEXPORT_REQUESTED ) ) && bUseFilterOptions )
1006 // for exporters: always show dialog if format uses options
1007 // for save: show dialog if format uses options and no options given or if forced by user
1008 uno::Any aVal =
1009 xExtFileDlg->getValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, 0 );
1011 aVal >>= bUseFilterOptions;
1012 if ( !bUseFilterOptions )
1013 bUseFilterOptions =
1014 ( GetMediaDescr().find( aFilterDataString ) == GetMediaDescr().end()
1015 && GetMediaDescr().find( aFilterOptionsString ) == GetMediaDescr().end() );
1017 catch( lang::IllegalArgumentException& )
1022 delete pFileDlg;
1024 // merge in results of the dialog execution
1025 GetMediaDescr()[::rtl::OUString::createFromAscii( "URL" )] <<=
1026 ::rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ));
1027 GetMediaDescr()[aFilterNameString] <<= aFilterName;
1029 return bUseFilterOptions;
1032 //-------------------------------------------------------------------------
1033 sal_Bool ModelData_Impl::ShowDocumentInfoDialog()
1035 sal_Bool bDialogUsed = sal_False;
1037 try {
1038 uno::Reference< frame::XController > xController = GetModel()->getCurrentController();
1039 if ( xController.is() )
1041 uno::Reference< frame::XDispatchProvider > xFrameDispatch( xController->getFrame(), uno::UNO_QUERY );
1042 if ( xFrameDispatch.is() )
1044 util::URL aURL;
1045 aURL.Complete = ::rtl::OUString::createFromAscii( ".uno:SetDocumentProperties" );
1047 uno::Reference< util::XURLTransformer > xTransformer(
1048 m_pOwner->GetServiceFactory()->createInstance(
1049 DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer") ),
1050 uno::UNO_QUERY );
1051 if ( xTransformer.is() && xTransformer->parseStrict( aURL ) )
1053 uno::Reference< frame::XDispatch > xDispatch = xFrameDispatch->queryDispatch(
1054 aURL,
1055 ::rtl::OUString::createFromAscii( "_self" ),
1056 0 );
1057 if ( xDispatch.is() )
1059 xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() );
1060 bDialogUsed = sal_True;
1066 catch ( uno::Exception& )
1070 return bDialogUsed;
1073 //-------------------------------------------------------------------------
1074 ::rtl::OUString ModelData_Impl::GetReccomendedDir( const ::rtl::OUString& aSuggestedDir, const sfx2::FileDialogHelper::Context& aCtxt )
1076 ::rtl::OUString aReccomendedDir;
1078 if ( ( aSuggestedDir.getLength() || GetStorable()->hasLocation() )
1079 && !GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "RepairPackage" ),
1080 sal_False ) )
1082 INetURLObject aLocation;
1083 if ( aSuggestedDir.getLength() )
1084 aLocation = INetURLObject( aSuggestedDir );
1085 else
1087 ::rtl::OUString aOldURL = GetStorable()->getLocation();
1088 if ( aOldURL.getLength() )
1090 INetURLObject aTmp( aOldURL );
1091 if ( aTmp.removeSegment() )
1092 aLocation = aTmp;
1095 if ( aLocation.HasError() )
1096 aLocation = INetURLObject( SvtPathOptions().GetWorkPath() );
1099 aLocation.setFinalSlash();
1100 if ( !aLocation.HasError() )
1101 aReccomendedDir = aLocation.GetMainURL( INetURLObject::NO_DECODE );
1103 else
1105 // pb: set graphic path if context == SD_EXPORT or SI_EXPORT else work path
1106 ::rtl::OUString aConfigSuggestion( ( aCtxt != sfx2::FileDialogHelper::UNKNOWN_CONTEXT ) ? SvtPathOptions().GetGraphicPath() : SvtPathOptions().GetWorkPath() );
1107 aReccomendedDir = INetURLObject( aConfigSuggestion ).GetMainURL( INetURLObject::NO_DECODE );
1110 return aReccomendedDir;
1113 //-------------------------------------------------------------------------
1114 ::rtl::OUString ModelData_Impl::GetReccomendedName( const ::rtl::OUString& aSuggestedName, const ::rtl::OUString& aTypeName )
1116 // the last used name might be provided by aSuggestedName from the old selection, or from the MediaDescriptor
1117 ::rtl::OUString aReccomendedName;
1119 if ( aSuggestedName.getLength() )
1120 aReccomendedName = aSuggestedName;
1121 else
1123 aReccomendedName = INetURLObject( GetStorable()->getLocation() ).GetName( INetURLObject::DECODE_WITH_CHARSET );
1124 if ( !aReccomendedName.getLength() )
1126 try {
1127 uno::Reference< frame::XTitle > xTitle( GetModel(), uno::UNO_QUERY_THROW );
1128 aReccomendedName = xTitle->getTitle();
1129 } catch( uno::Exception& ) {}
1132 if ( aReccomendedName.getLength() && aTypeName.getLength() )
1134 // adjust the extension to the type
1135 uno::Reference< container::XNameAccess > xTypeDetection = uno::Reference< container::XNameAccess >(
1136 m_pOwner->GetServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
1137 uno::UNO_QUERY );
1138 if ( xTypeDetection.is() )
1140 INetURLObject aObj( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///c:/" ) ) + aReccomendedName );
1142 uno::Sequence< beans::PropertyValue > aTypeNameProps;
1143 if ( ( xTypeDetection->getByName( aTypeName ) >>= aTypeNameProps ) && aTypeNameProps.getLength() )
1145 ::comphelper::SequenceAsHashMap aTypeNamePropsHM( aTypeNameProps );
1146 uno::Sequence< ::rtl::OUString > aExtensions = aTypeNamePropsHM.getUnpackedValueOrDefault(
1147 ::rtl::OUString::createFromAscii( "Extensions" ),
1148 ::uno::Sequence< ::rtl::OUString >() );
1149 if ( aExtensions.getLength() )
1150 aObj.SetExtension( aExtensions[0] );
1153 aReccomendedName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET );
1158 return aReccomendedName;
1162 //=========================================================================
1163 // class SfxStoringHelper
1164 //=========================================================================
1165 //-------------------------------------------------------------------------
1166 SfxStoringHelper::SfxStoringHelper( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
1167 : m_xFactory( xFactory )
1171 //-------------------------------------------------------------------------
1172 uno::Reference< lang::XMultiServiceFactory > SfxStoringHelper::GetServiceFactory()
1174 if ( !m_xFactory.is() )
1176 m_xFactory = ::comphelper::getProcessServiceFactory();
1177 if( !m_xFactory.is() )
1178 throw uno::RuntimeException(); // TODO:
1181 return m_xFactory;
1184 //-------------------------------------------------------------------------
1185 uno::Reference< container::XNameAccess > SfxStoringHelper::GetFilterConfiguration()
1187 if ( !m_xFilterCFG.is() )
1189 m_xFilterCFG = uno::Reference< container::XNameAccess >(
1190 GetServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
1191 uno::UNO_QUERY );
1193 if ( !m_xFilterCFG.is() )
1194 throw uno::RuntimeException();
1197 return m_xFilterCFG;
1200 //-------------------------------------------------------------------------
1201 uno::Reference< container::XContainerQuery > SfxStoringHelper::GetFilterQuery()
1203 if ( !m_xFilterQuery.is() )
1205 m_xFilterQuery = uno::Reference< container::XContainerQuery >( GetFilterConfiguration(), uno::UNO_QUERY );
1206 if ( !m_xFilterQuery.is() )
1207 throw uno::RuntimeException();
1210 return m_xFilterQuery;
1213 //-------------------------------------------------------------------------
1214 uno::Reference< ::com::sun::star::frame::XModuleManager > SfxStoringHelper::GetModuleManager()
1216 if ( !m_xModuleManager.is() )
1218 m_xModuleManager = uno::Reference< ::com::sun::star::frame::XModuleManager >(
1219 GetServiceFactory()->createInstance(
1220 ::rtl::OUString::createFromAscii( "com.sun.star.frame.ModuleManager" ) ),
1221 uno::UNO_QUERY );
1223 if ( !m_xModuleManager.is() )
1224 throw uno::RuntimeException();
1227 return m_xModuleManager;
1230 //-------------------------------------------------------------------------
1231 uno::Reference< container::XNameAccess > SfxStoringHelper::GetNamedModuleManager()
1233 if ( !m_xNamedModManager.is() )
1235 m_xNamedModManager = uno::Reference< container::XNameAccess >( GetModuleManager(), uno::UNO_QUERY );
1236 if ( !m_xNamedModManager.is() )
1237 throw uno::RuntimeException();
1240 return m_xNamedModManager;
1243 //-------------------------------------------------------------------------
1244 sal_Bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& xModel,
1245 const ::rtl::OUString& aSlotName,
1246 uno::Sequence< beans::PropertyValue >& aArgsSequence,
1247 sal_Bool bPreselectPassword,
1248 ::rtl::OUString aSuggestedName )
1250 ModelData_Impl aModelData( *this, xModel, aArgsSequence );
1252 sal_Bool bDialogUsed = sal_False;
1254 INetURLObject aURL;
1256 sal_Bool bSetStandardName = sal_False; // can be set only for SaveAs
1258 // parse the slot name
1259 sal_Int8 nStoreMode = getStoreModeFromSlotName( aSlotName );
1261 // handle the special cases
1262 if ( nStoreMode & SAVEAS_REQUESTED )
1264 ::comphelper::SequenceAsHashMap::const_iterator aSaveToIter =
1265 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "SaveTo" ) );
1266 if ( aSaveToIter != aModelData.GetMediaDescr().end() )
1268 sal_Bool bWideExport = sal_False;
1269 aSaveToIter->second >>= bWideExport;
1270 if ( bWideExport )
1271 nStoreMode = EXPORT_REQUESTED | WIDEEXPORT_REQUESTED;
1274 // if saving is not acceptable the warning must be shown even in case of SaveAs operation
1275 if ( ( nStoreMode & SAVEAS_REQUESTED ) && aModelData.CheckSaveAcceptable( STATUS_SAVEAS ) == STATUS_NO_ACTION )
1276 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
1278 else if ( nStoreMode & SAVE_REQUESTED )
1280 // if saving is not acceptable by the configuration the warning must be shown
1281 sal_Int8 nStatusSave = aModelData.CheckSaveAcceptable( STATUS_SAVE );
1283 if ( nStatusSave == STATUS_NO_ACTION )
1284 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
1285 else if ( nStatusSave == STATUS_SAVE )
1287 // check whether it is possible to use save operation
1288 nStatusSave = aModelData.CheckStateForSave();
1291 if ( nStatusSave == STATUS_NO_ACTION )
1293 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT );
1295 else if ( nStatusSave == STATUS_SAVE )
1297 // Document properties can contain streams that should be freed before storing
1298 aModelData.FreeDocumentProps();
1300 if ( aModelData.GetStorable2().is() )
1304 aModelData.GetStorable2()->storeSelf( aModelData.GetMediaDescr().getAsConstPropertyValueList() );
1306 catch( lang::IllegalArgumentException& )
1308 OSL_ENSURE( sal_False, "ModelData didn't handle illegal parameters, all the parameters are ignored!\n" );
1309 aModelData.GetStorable()->store();
1312 else
1314 OSL_ENSURE( sal_False, "XStorable2 is not supported by the model!\n" );
1315 aModelData.GetStorable()->store();
1318 return sal_False;
1320 else
1322 // this should be a usual SaveAs operation
1323 nStoreMode = SAVEAS_REQUESTED;
1324 if ( nStatusSave == STATUS_SAVEAS_STANDARDNAME )
1325 bSetStandardName = sal_True;
1329 // preselect a filter for the storing process
1330 uno::Sequence< beans::PropertyValue > aFilterProps = aModelData.GetPreselectedFilter_Impl( nStoreMode );
1332 DBG_ASSERT( aFilterProps.getLength(), "No filter for storing!\n" );
1333 if ( !aFilterProps.getLength() )
1334 throw task::ErrorCodeIOException( ::rtl::OUString(),
1335 uno::Reference< uno::XInterface >(),
1336 ERRCODE_IO_INVALIDPARAMETER );
1338 ::comphelper::SequenceAsHashMap aFilterPropsHM( aFilterProps );
1339 ::rtl::OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault(
1340 ::rtl::OUString::createFromAscii( "Name" ),
1341 ::rtl::OUString() );
1343 ::rtl::OUString aFilterFromMediaDescr = aModelData.GetMediaDescr().getUnpackedValueOrDefault(
1344 aFilterNameString,
1345 ::rtl::OUString() );
1346 ::rtl::OUString aOldFilterName = aModelData.GetDocProps().getUnpackedValueOrDefault(
1347 aFilterNameString,
1348 ::rtl::OUString() );
1350 sal_Bool bUseFilterOptions = sal_False;
1351 ::comphelper::SequenceAsHashMap::const_iterator aFileNameIter = aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "URL" ) );
1353 if ( ( nStoreMode & EXPORT_REQUESTED ) && ( nStoreMode & PDFEXPORT_REQUESTED ) && !( nStoreMode & PDFDIRECTEXPORT_REQUESTED ) )
1355 // this is PDF export, the filter options dialog should be shown before the export
1356 aModelData.GetMediaDescr()[aFilterNameString] <<= aFilterName;
1357 if ( aModelData.GetMediaDescr().find( aFilterFlagsString ) == aModelData.GetMediaDescr().end()
1358 && aModelData.GetMediaDescr().find( aFilterOptionsString ) == aModelData.GetMediaDescr().end()
1359 && aModelData.GetMediaDescr().find( aFilterDataString ) == aModelData.GetMediaDescr().end() )
1361 // execute filter options dialog since no options are set in the media descriptor
1362 if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) )
1363 bDialogUsed = sal_True;
1367 if ( aFileNameIter == aModelData.GetMediaDescr().end() )
1369 sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG;
1370 ::comphelper::SequenceAsHashMap::const_iterator aDlgIter =
1371 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "UseSystemDialog" ) );
1372 if ( aDlgIter != aModelData.GetMediaDescr().end() )
1374 sal_Bool bUseSystemDialog = sal_True;
1375 if ( aDlgIter->second >>= bUseSystemDialog )
1377 if ( bUseSystemDialog )
1378 nDialog = SFX2_IMPL_DIALOG_SYSTEM;
1379 else
1380 nDialog = SFX2_IMPL_DIALOG_OOO;
1384 // The Dispatch supports parameter FolderName that overwrites SuggestedSaveAsDir
1385 ::rtl::OUString aSuggestedDir = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FolderName" ) ), ::rtl::OUString() );
1386 if ( !aSuggestedDir.getLength() )
1388 aSuggestedDir = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() );
1389 if ( !aSuggestedDir.getLength() )
1390 aSuggestedDir = aModelData.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() );
1393 aSuggestedName = aModelData.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() );
1394 if ( !aSuggestedName.getLength() )
1395 aSuggestedName = aModelData.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() );
1397 ::rtl::OUString sStandardDir;
1398 ::comphelper::SequenceAsHashMap::const_iterator aStdDirIter =
1399 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "StandardDir" ) );
1400 if ( aStdDirIter != aModelData.GetMediaDescr().end() )
1401 aStdDirIter->second >>= sStandardDir;
1403 ::com::sun::star::uno::Sequence< ::rtl::OUString > aBlackList;
1405 ::comphelper::SequenceAsHashMap::const_iterator aBlackListIter =
1406 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "BlackList" ) );
1407 if ( aBlackListIter != aModelData.GetMediaDescr().end() )
1408 aBlackListIter->second >>= aBlackList;
1410 sal_Bool bExit = sal_False;
1411 while ( !bExit )
1413 bUseFilterOptions = aModelData.OutputFileDialog( nStoreMode, aFilterProps, bSetStandardName, aSuggestedName, bPreselectPassword, aSuggestedDir, nDialog, sStandardDir, aBlackList );
1415 // in case the dialog is opend a second time the folder should be the same as before, not what was handed over by parameters
1416 aSuggestedDir = ::rtl::OUString();
1417 if ( nStoreMode == SAVEAS_REQUESTED )
1419 // in case of saving check filter for possible alien warning
1420 ::rtl::OUString aSelFilterName = aModelData.GetMediaDescr().getUnpackedValueOrDefault(
1421 aFilterNameString,
1422 ::rtl::OUString() );
1423 sal_Int8 nStatusSave = aModelData.CheckFilter( aSelFilterName );
1424 if ( nStatusSave == STATUS_SAVEAS_STANDARDNAME )
1426 // switch to best filter
1427 bSetStandardName = sal_True;
1429 else if ( nStatusSave == STATUS_SAVE )
1431 // user confirmed alien filter or "good" filter is used
1432 bExit = sal_True;
1435 else
1436 bExit = sal_True;
1439 bDialogUsed = sal_True;
1440 aFileNameIter = aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "URL" ) );
1442 else
1444 // the target file name is provided so check if new filter options
1445 // are provided or old options can be used
1446 if ( aFilterFromMediaDescr.equals( aOldFilterName ) )
1448 ::comphelper::SequenceAsHashMap::const_iterator aIter =
1449 aModelData.GetDocProps().find( aFilterOptionsString );
1450 if ( aIter != aModelData.GetDocProps().end()
1451 && aModelData.GetMediaDescr().find( aFilterOptionsString ) == aModelData.GetMediaDescr().end() )
1452 aModelData.GetMediaDescr()[aIter->first] = aIter->second;
1454 aIter = aModelData.GetDocProps().find( aFilterDataString );
1455 if ( aIter != aModelData.GetDocProps().end()
1456 && aModelData.GetMediaDescr().find( aFilterDataString ) == aModelData.GetMediaDescr().end() )
1457 aModelData.GetMediaDescr()[aIter->first] = aIter->second;
1461 if ( aFileNameIter != aModelData.GetMediaDescr().end() )
1463 ::rtl::OUString aFileName;
1464 aFileNameIter->second >>= aFileName;
1465 aURL.SetURL( aFileName );
1466 DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" );
1468 ::comphelper::SequenceAsHashMap::const_iterator aIter =
1469 aModelData.GetMediaDescr().find( aFilterNameString );
1471 if ( aIter != aModelData.GetMediaDescr().end() )
1472 aIter->second >>= aFilterName;
1473 else
1474 aModelData.GetMediaDescr()[aFilterNameString] <<= aFilterName;
1476 DBG_ASSERT( aFilterName.getLength(), "Illegal filter!" );
1478 else
1480 DBG_ASSERT( sal_False, "This code must be unreachable!\n" );
1481 throw task::ErrorCodeIOException( ::rtl::OUString(),
1482 uno::Reference< uno::XInterface >(),
1483 ERRCODE_IO_INVALIDPARAMETER );
1486 ::comphelper::SequenceAsHashMap::const_iterator aIter =
1487 aModelData.GetMediaDescr().find( ::rtl::OUString::createFromAscii( "FilterFlags" ) );
1488 sal_Bool bFilterFlagsSet = ( aIter != aModelData.GetMediaDescr().end() );
1490 if( !( nStoreMode & PDFEXPORT_REQUESTED ) && !bFilterFlagsSet
1491 && ( ( nStoreMode & EXPORT_REQUESTED ) || bUseFilterOptions ) )
1493 // execute filter options dialog
1494 if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) )
1495 bDialogUsed = sal_True;
1498 // so the arguments will not change any more and can be stored to the main location
1499 aArgsSequence = aModelData.GetMediaDescr().getAsConstPropertyValueList();
1501 // store the document and handle it's docinfo
1502 SvtSaveOptions aOptions;
1504 if ( aOptions.IsDocInfoSave()
1505 && ( !aModelData.GetStorable()->hasLocation()
1506 || INetURLObject( aModelData.GetStorable()->getLocation() ) != aURL ) )
1508 // this is defenitly not a Save operation
1509 // so the document info can be updated
1511 // on export document info must be preserved
1512 uno::Reference<document::XDocumentInfoSupplier> xDIS(
1513 aModelData.GetModel(), uno::UNO_QUERY_THROW);
1514 uno::Reference<util::XCloneable> xCloneable(
1515 xDIS->getDocumentInfo(), uno::UNO_QUERY_THROW);
1516 uno::Reference<document::XDocumentInfo> xOldDocInfo(
1517 xCloneable->createClone(), uno::UNO_QUERY_THROW);
1519 // use dispatch API to show document info dialog
1520 if ( aModelData.ShowDocumentInfoDialog() )
1521 bDialogUsed = sal_True;
1522 else
1524 DBG_ERROR( "Can't execute document info dialog!\n" );
1527 try {
1528 // Document properties can contain streams that should be freed before storing
1529 aModelData.FreeDocumentProps();
1530 if ( ( nStoreMode & EXPORT_REQUESTED ) )
1531 aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
1532 else
1533 aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
1535 catch( uno::Exception& )
1537 if ( ( nStoreMode & EXPORT_REQUESTED ) )
1538 SetDocInfoState( aModelData.GetModel(), xOldDocInfo, sal_True );
1540 throw;
1543 if ( ( nStoreMode & EXPORT_REQUESTED ) )
1544 SetDocInfoState( aModelData.GetModel(), xOldDocInfo, sal_True );
1546 else
1548 // Document properties can contain streams that should be freed before storing
1549 aModelData.FreeDocumentProps();
1551 // this is actually a save operation with different parameters
1552 // so storeTo or storeAs without DocInfo operations are used
1553 if ( ( nStoreMode & EXPORT_REQUESTED ) )
1554 aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
1555 else
1556 aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aArgsSequence );
1559 return bDialogUsed;
1562 //-------------------------------------------------------------------------
1563 // static
1564 uno::Sequence< beans::PropertyValue > SfxStoringHelper::SearchForFilter(
1565 const uno::Reference< container::XContainerQuery >& xFilterQuery,
1566 const uno::Sequence< beans::NamedValue >& aSearchRequest,
1567 sal_Int32 nMustFlags,
1568 sal_Int32 nDontFlags )
1570 uno::Sequence< beans::PropertyValue > aFilterProps;
1571 uno::Reference< container::XEnumeration > xFilterEnum =
1572 xFilterQuery->createSubSetEnumerationByProperties( aSearchRequest );
1574 // use the first filter that is found
1575 if ( xFilterEnum.is() )
1576 while ( xFilterEnum->hasMoreElements() )
1578 uno::Sequence< beans::PropertyValue > aProps;
1579 if ( xFilterEnum->nextElement() >>= aProps )
1581 ::comphelper::SequenceAsHashMap aPropsHM( aProps );
1582 sal_Int32 nFlags = aPropsHM.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ),
1583 (sal_Int32)0 );
1584 if ( ( ( nFlags & nMustFlags ) == nMustFlags ) && !( nFlags & nDontFlags ) )
1586 aFilterProps = aProps;
1587 break;
1592 return aFilterProps;
1595 //-------------------------------------------------------------------------
1596 // static
1597 sal_Bool SfxStoringHelper::CheckFilterOptionsAppearence(
1598 const uno::Reference< container::XNameAccess >& xFilterCFG,
1599 const ::rtl::OUString& aFilterName )
1601 sal_Bool bUseFilterOptions = sal_False;
1603 DBG_ASSERT( xFilterCFG.is(), "No filter configuration!\n" );
1604 if( xFilterCFG.is() )
1606 try {
1607 uno::Sequence < beans::PropertyValue > aProps;
1608 uno::Any aAny = xFilterCFG->getByName( aFilterName );
1609 if ( aAny >>= aProps )
1611 ::comphelper::SequenceAsHashMap aPropsHM( aProps );
1612 ::rtl::OUString aServiceName = aPropsHM.getUnpackedValueOrDefault(
1613 ::rtl::OUString::createFromAscii( "UIComponent" ),
1614 ::rtl::OUString() );
1615 if( aServiceName.getLength() )
1616 bUseFilterOptions = sal_True;
1619 catch( uno::Exception& )
1624 return bUseFilterOptions;
1627 //-------------------------------------------------------------------------
1628 // static
1629 void SfxStoringHelper::SetDocInfoState(
1630 const uno::Reference< frame::XModel >& xModel,
1631 const uno::Reference< document::XDocumentInfo >& i_xOldDocInfo,
1632 sal_Bool bNoModify )
1634 uno::Reference< document::XDocumentInfoSupplier > xModelDocInfoSupplier( xModel, uno::UNO_QUERY );
1635 if ( !xModelDocInfoSupplier.is() )
1636 throw uno::RuntimeException(); // TODO:
1638 uno::Reference< document::XDocumentInfo > xDocInfoToFill = xModelDocInfoSupplier->getDocumentInfo();
1639 uno::Reference< beans::XPropertySet > xPropSet( i_xOldDocInfo,
1640 uno::UNO_QUERY_THROW );
1642 uno::Reference< util::XModifiable > xModifiable( xModel, uno::UNO_QUERY );
1643 if ( bNoModify && !xModifiable.is() )
1644 throw uno::RuntimeException();
1646 sal_Bool bIsModified = bNoModify && xModifiable->isModified();
1650 uno::Reference< beans::XPropertySet > xSet( xDocInfoToFill, uno::UNO_QUERY );
1651 uno::Reference< beans::XPropertyContainer > xContainer( xSet, uno::UNO_QUERY );
1652 uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
1653 uno::Sequence< beans::Property > lProps = xSetInfo->getProperties();
1654 const beans::Property* pProps = lProps.getConstArray();
1655 sal_Int32 c = lProps.getLength();
1656 sal_Int32 i = 0;
1657 for (i=0; i<c; ++i)
1659 uno::Any aValue = xPropSet->getPropertyValue( pProps[i].Name );
1660 if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE )
1661 // QUESTION: DefaultValue?!
1662 xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue );
1665 // it is possible that the propertysets from XML and binary files differ; we shouldn't break then
1666 xSet->setPropertyValue( pProps[i].Name, aValue );
1668 catch ( uno::Exception& ) {}
1671 sal_Int16 nCount = i_xOldDocInfo->getUserFieldCount();
1672 sal_Int16 nSupportedCount = xDocInfoToFill->getUserFieldCount();
1673 for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ )
1675 ::rtl::OUString aPropName = i_xOldDocInfo->getUserFieldName( nInd );
1676 xDocInfoToFill->setUserFieldName( nInd, aPropName );
1677 ::rtl::OUString aPropVal = i_xOldDocInfo->getUserFieldValue( nInd );
1678 xDocInfoToFill->setUserFieldValue( nInd, aPropVal );
1681 catch ( uno::Exception& ) {}
1683 // set the modified flag back if required
1684 if ( bNoModify && bIsModified != xModifiable->isModified() )
1685 xModifiable->setModified( bIsModified );
1688 //-------------------------------------------------------------------------
1689 // static
1690 sal_Bool SfxStoringHelper::WarnUnacceptableFormat( const uno::Reference< frame::XModel >& xModel,
1691 ::rtl::OUString aOldUIName,
1692 ::rtl::OUString /*aDefUIName*/,
1693 sal_Bool /*bCanProceedFurther*/ )
1695 if ( !SvtSaveOptions().IsWarnAlienFormat() )
1696 return sal_True;
1698 Window* pWin = SfxStoringHelper::GetModelWindow( xModel );
1699 SfxAlienWarningDialog aDlg( pWin, aOldUIName );
1701 return aDlg.Execute() == RET_OK;
1704 // static
1705 void SfxStoringHelper::ExecuteFilterDialog( SfxStoringHelper& _rStorageHelper
1706 ,const ::rtl::OUString& _sFilterName
1707 ,const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _xModel
1708 ,/*OUT*/::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArgsSequence)
1710 ModelData_Impl aModelData( _rStorageHelper, _xModel, _rArgsSequence );
1711 if ( aModelData.ExecuteFilterDialog_Impl( _sFilterName ) )
1712 _rArgsSequence = aModelData.GetMediaDescr().getAsConstPropertyValueList();
1715 // static
1716 Window* SfxStoringHelper::GetModelWindow( const uno::Reference< frame::XModel >& xModel )
1718 Window* pWin = 0;
1719 try {
1720 if ( xModel.is() )
1722 uno::Reference< frame::XController > xController = xModel->getCurrentController();
1723 if ( xController.is() )
1725 uno::Reference< frame::XFrame > xFrame = xController->getFrame();
1726 if ( xFrame.is() )
1728 uno::Reference< awt::XWindow > xWindow = xFrame->getContainerWindow();
1729 if ( xWindow.is() )
1731 VCLXWindow* pVCLWindow = VCLXWindow::GetImplementation( xWindow );
1732 if ( pVCLWindow )
1733 pWin = pVCLWindow->GetWindow();
1739 catch ( uno::Exception& )
1743 return pWin;