1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
30 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
31 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
32 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
33 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
34 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
35 #include <com/sun/star/view/XSelectionSupplier.hpp>
36 #include <com/sun/star/beans/XPropertyAccess.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/beans/XPropertyContainer.hpp>
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <com/sun/star/document/XExporter.hpp>
41 #include <com/sun/star/document/XDocumentInfoSupplier.hpp>
42 #include <com/sun/star/document/XDocumentInfo.hpp>
43 #include <com/sun/star/task/XInteractionHandler.hpp>
44 #include <com/sun/star/util/DateTime.hpp>
45 #include <com/sun/star/util/XURLTransformer.hpp>
46 #include <com/sun/star/frame/XStorable.hpp>
47 #include <com/sun/star/frame/XStorable2.hpp>
48 #include <com/sun/star/frame/XDispatchProvider.hpp>
49 #include <com/sun/star/frame/XDispatch.hpp>
50 #include <com/sun/star/frame/XTitle.hpp>
51 #include <com/sun/star/util/XModifyListener.hpp>
52 #include <com/sun/star/util/XModifiable.hpp>
53 #include <com/sun/star/util/XModifyBroadcaster.hpp>
55 #include <com/sun/star/util/XCloneable.hpp>
56 #include <com/sun/star/frame/XModuleManager.hpp>
57 #include <com/sun/star/io/IOException.hpp>
59 #include "guisaveas.hxx"
61 #include <unotools/pathoptions.hxx>
62 #include <svl/itemset.hxx>
63 #include <svl/eitem.hxx>
64 #include <svl/stritem.hxx>
65 #include <svl/intitem.hxx>
66 #include <unotools/useroptions.hxx>
67 #include <unotools/saveopt.hxx>
68 #include <svtools/miscopt.hxx>
69 #include <tools/debug.hxx>
70 #include <tools/urlobj.hxx>
71 #include <comphelper/processfactory.hxx>
72 #include <comphelper/configurationhelper.hxx>
73 #include <comphelper/mimeconfighelper.hxx>
74 #include <vcl/msgbox.hxx>
75 #include <vcl/window.hxx>
76 #include <toolkit/awt/vclxwindow.hxx>
78 #include <sfx2/sfxsids.hrc>
80 #include <sfx2/sfxresid.hxx>
81 #include <sfx2/docfilt.hxx>
82 #include <sfx2/filedlghelper.hxx>
83 #include <sfx2/app.hxx>
84 #include <sfx2/objsh.hxx>
85 #include <sfx2/dinfdlg.hxx>
86 #include <sfx2/request.hxx>
87 #include <sfxtypes.hxx>
88 #include "alienwarn.hxx"
90 #include "../appl/app.hrc"
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 char aFilterNameString
[] = "FilterName";
107 const char aFilterOptionsString
[] = "FilterOptions";
108 const char aFilterDataString
[] = "FilterData";
109 const char aFilterFlagsString
[] = "FilterFlags";
111 using namespace ::com::sun::star
;
114 //-------------------------------------------------------------------------
115 static sal_uInt16
getSlotIDFromMode( sal_Int8 nStoreMode
)
117 // This is a temporary hardcoded solution must be removed when
118 // dialogs do not need parameters in SidSet representation any more
120 sal_uInt16 nResult
= 0;
121 if ( nStoreMode
== EXPORT_REQUESTED
)
122 nResult
= SID_EXPORTDOC
;
123 else if ( nStoreMode
== ( EXPORT_REQUESTED
| PDFEXPORT_REQUESTED
) )
124 nResult
= SID_EXPORTDOCASPDF
;
125 else if ( nStoreMode
== ( EXPORT_REQUESTED
| PDFEXPORT_REQUESTED
| PDFDIRECTEXPORT_REQUESTED
) )
126 nResult
= SID_DIRECTEXPORTDOCASPDF
;
127 else if ( nStoreMode
== SAVEAS_REQUESTED
|| nStoreMode
== ( EXPORT_REQUESTED
| WIDEEXPORT_REQUESTED
) )
128 nResult
= SID_SAVEASDOC
;
130 DBG_ASSERT( sal_False
, "Unacceptable slot name is provided!\n" );
136 //-------------------------------------------------------------------------
137 static sal_uInt8
getStoreModeFromSlotName( const ::rtl::OUString
& aSlotName
)
139 sal_uInt8 nResult
= 0;
140 if ( aSlotName
== "ExportTo" )
141 nResult
= EXPORT_REQUESTED
;
142 else if ( aSlotName
== "ExportToPDF" )
143 nResult
= EXPORT_REQUESTED
| PDFEXPORT_REQUESTED
;
144 else if ( aSlotName
== "ExportDirectToPDF" )
145 nResult
= EXPORT_REQUESTED
| PDFEXPORT_REQUESTED
| PDFDIRECTEXPORT_REQUESTED
;
146 else if ( aSlotName
== "Save" )
147 nResult
= SAVE_REQUESTED
;
148 else if ( aSlotName
== "SaveAs" )
149 nResult
= SAVEAS_REQUESTED
;
151 throw task::ErrorCodeIOException( ::rtl::OUString(),
152 uno::Reference
< uno::XInterface
>(),
153 ERRCODE_IO_INVALIDPARAMETER
);
158 //-------------------------------------------------------------------------
159 static sal_Int32
getMustFlags( sal_Int8 nStoreMode
)
161 return ( SFX_FILTER_EXPORT
162 | ( ( ( nStoreMode
& EXPORT_REQUESTED
) && !( nStoreMode
& WIDEEXPORT_REQUESTED
) ) ? 0 : SFX_FILTER_IMPORT
) );
165 //-------------------------------------------------------------------------
166 static sal_Int32
getDontFlags( sal_Int8 nStoreMode
)
168 return ( SFX_FILTER_INTERNAL
169 | SFX_FILTER_NOTINFILEDLG
170 | ( ( ( nStoreMode
& EXPORT_REQUESTED
) && !( nStoreMode
& WIDEEXPORT_REQUESTED
) ) ? SFX_FILTER_IMPORT
: 0 ) );
173 //=========================================================================
174 // class DocumentSettingsGuard
175 //=========================================================================
177 class DocumentSettingsGuard
179 uno::Reference
< beans::XPropertySet
> m_xDocumentSettings
;
180 sal_Bool m_bPreserveReadOnly
;
181 sal_Bool m_bReadOnlySupported
;
183 sal_Bool m_bRestoreSettings
;
185 DocumentSettingsGuard( const uno::Reference
< frame::XModel
>& xModel
, sal_Bool bReadOnly
, sal_Bool bRestore
)
186 : m_bPreserveReadOnly( sal_False
)
187 , m_bReadOnlySupported( sal_False
)
188 , m_bRestoreSettings( bRestore
)
192 uno::Reference
< lang::XMultiServiceFactory
> xDocSettingsSupplier( xModel
, uno::UNO_QUERY_THROW
);
193 m_xDocumentSettings
.set(
194 xDocSettingsSupplier
->createInstance(
195 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.Settings" ) ) ),
196 uno::UNO_QUERY_THROW
);
198 ::rtl::OUString
aLoadReadonlyString( RTL_CONSTASCII_USTRINGPARAM( "LoadReadonly" ) );
202 m_xDocumentSettings
->getPropertyValue( aLoadReadonlyString
) >>= m_bPreserveReadOnly
;
203 m_xDocumentSettings
->setPropertyValue( aLoadReadonlyString
, uno::makeAny( bReadOnly
) );
204 m_bReadOnlySupported
= sal_True
;
206 catch( const uno::Exception
& )
209 catch( const uno::Exception
& )
212 if ( ( bReadOnly
&& !m_bReadOnlySupported
) )
213 throw uno::RuntimeException(); // the user could provide the data, so it must be stored
216 ~DocumentSettingsGuard()
218 if ( m_bRestoreSettings
)
220 ::rtl::OUString
aLoadReadonlyString( RTL_CONSTASCII_USTRINGPARAM( "LoadReadonly" ) );
224 if ( m_bReadOnlySupported
)
225 m_xDocumentSettings
->setPropertyValue( aLoadReadonlyString
, uno::makeAny( m_bPreserveReadOnly
) );
227 catch( const uno::Exception
& )
229 OSL_FAIL( "Unexpected exception!" );
234 } // anonymous namespace
236 //=========================================================================
237 // class ModelData_Impl
238 //=========================================================================
241 SfxStoringHelper
* m_pOwner
;
242 uno::Reference
< frame::XModel
> m_xModel
;
243 uno::Reference
< frame::XStorable
> m_xStorable
;
244 uno::Reference
< frame::XStorable2
> m_xStorable2
;
245 uno::Reference
< util::XModifiable
> m_xModifiable
;
247 ::rtl::OUString m_aModuleName
;
248 ::comphelper::SequenceAsHashMap
* m_pDocumentPropsHM
;
249 ::comphelper::SequenceAsHashMap
* m_pModulePropsHM
;
251 ::comphelper::SequenceAsHashMap m_aMediaDescrHM
;
253 sal_Bool m_bRecommendReadOnly
;
256 ModelData_Impl( SfxStoringHelper
& aOwner
,
257 const uno::Reference
< frame::XModel
>& xModel
,
258 const uno::Sequence
< beans::PropertyValue
>& aMediaDescr
);
262 void FreeDocumentProps();
264 uno::Reference
< frame::XModel
> GetModel();
265 uno::Reference
< frame::XStorable
> GetStorable();
266 uno::Reference
< frame::XStorable2
> GetStorable2();
267 uno::Reference
< util::XModifiable
> GetModifiable();
269 ::comphelper::SequenceAsHashMap
& GetMediaDescr() { return m_aMediaDescrHM
; }
271 sal_Bool
IsRecommendReadOnly() const { return m_bRecommendReadOnly
; }
273 const ::comphelper::SequenceAsHashMap
& GetDocProps();
275 ::rtl::OUString
GetModuleName();
276 const ::comphelper::SequenceAsHashMap
& GetModuleProps();
278 void CheckInteractionHandler();
281 ::rtl::OUString
GetDocServiceName();
282 uno::Sequence
< beans::PropertyValue
> GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust
, sal_Int32 nDont
);
283 uno::Sequence
< beans::PropertyValue
> GetDocServiceAnyFilter( sal_Int32 nMust
, sal_Int32 nDont
);
284 uno::Sequence
< beans::PropertyValue
> GetPreselectedFilter_Impl( sal_Int8 nStoreMode
);
285 uno::Sequence
< beans::PropertyValue
> GetDocServiceDefaultFilter();
287 sal_Bool
ExecuteFilterDialog_Impl( const ::rtl::OUString
& aFilterName
);
289 sal_Int8
CheckSaveAcceptable( sal_Int8 nCurStatus
);
290 sal_Int8
CheckStateForSave();
292 sal_Int8
CheckFilter( const ::rtl::OUString
& );
294 sal_Bool
CheckFilterOptionsDialogExistence();
296 sal_Bool
OutputFileDialog( sal_Int8 nStoreMode
,
297 const ::comphelper::SequenceAsHashMap
& aPreselectedFilterPropsHM
,
298 sal_Bool bSetStandardName
,
299 ::rtl::OUString
& aSuggestedName
,
300 sal_Bool bPreselectPassword
,
301 ::rtl::OUString
& aSuggestedDir
,
303 const ::rtl::OUString
& rStandardDir
,
304 const ::com::sun::star::uno::Sequence
< ::rtl::OUString
>& rBlackList
307 sal_Bool
ShowDocumentInfoDialog();
309 ::rtl::OUString
GetReccomendedDir( const ::rtl::OUString
& aSuggestedDir
);
310 ::rtl::OUString
GetReccomendedName( const ::rtl::OUString
& aSuggestedName
,
311 const ::rtl::OUString
& aTypeName
);
315 //-------------------------------------------------------------------------
316 ModelData_Impl::ModelData_Impl( SfxStoringHelper
& aOwner
,
317 const uno::Reference
< frame::XModel
>& xModel
,
318 const uno::Sequence
< beans::PropertyValue
>& aMediaDescr
)
319 : m_pOwner( &aOwner
)
321 , m_pDocumentPropsHM( NULL
)
322 , m_pModulePropsHM( NULL
)
323 , m_aMediaDescrHM( aMediaDescr
)
324 , m_bRecommendReadOnly( sal_False
)
326 CheckInteractionHandler();
329 //-------------------------------------------------------------------------
330 ModelData_Impl::~ModelData_Impl()
333 if ( m_pDocumentPropsHM
)
334 delete m_pDocumentPropsHM
;
336 if ( m_pModulePropsHM
)
337 delete m_pModulePropsHM
;
340 //-------------------------------------------------------------------------
341 void ModelData_Impl::FreeDocumentProps()
343 if ( m_pDocumentPropsHM
)
345 delete m_pDocumentPropsHM
;
346 m_pDocumentPropsHM
= NULL
;
350 //-------------------------------------------------------------------------
351 uno::Reference
< frame::XModel
> ModelData_Impl::GetModel()
353 if ( !m_xModel
.is() )
354 throw uno::RuntimeException();
359 //-------------------------------------------------------------------------
360 uno::Reference
< frame::XStorable
> ModelData_Impl::GetStorable()
362 if ( !m_xStorable
.is() )
364 m_xStorable
= uno::Reference
< frame::XStorable
>( m_xModel
, uno::UNO_QUERY
);
365 if ( !m_xStorable
.is() )
366 throw uno::RuntimeException();
372 //-------------------------------------------------------------------------
373 uno::Reference
< frame::XStorable2
> ModelData_Impl::GetStorable2()
375 if ( !m_xStorable2
.is() )
377 m_xStorable2
= uno::Reference
< frame::XStorable2
>( m_xModel
, uno::UNO_QUERY
);
378 if ( !m_xStorable2
.is() )
379 throw uno::RuntimeException();
385 //-------------------------------------------------------------------------
386 uno::Reference
< util::XModifiable
> ModelData_Impl::GetModifiable()
388 if ( !m_xModifiable
.is() )
390 m_xModifiable
= uno::Reference
< util::XModifiable
>( m_xModel
, uno::UNO_QUERY
);
391 if ( !m_xModifiable
.is() )
392 throw uno::RuntimeException();
395 return m_xModifiable
;
398 //-------------------------------------------------------------------------
399 const ::comphelper::SequenceAsHashMap
& ModelData_Impl::GetDocProps()
401 if ( !m_pDocumentPropsHM
)
402 m_pDocumentPropsHM
= new ::comphelper::SequenceAsHashMap( GetModel()->getArgs() );
404 return *m_pDocumentPropsHM
;
407 //-------------------------------------------------------------------------
408 ::rtl::OUString
ModelData_Impl::GetModuleName()
410 if ( m_aModuleName
.isEmpty() )
412 m_aModuleName
= m_pOwner
->GetModuleManager()->identify(
413 uno::Reference
< uno::XInterface
>( m_xModel
, uno::UNO_QUERY
) );
414 if ( m_aModuleName
.isEmpty() )
415 throw uno::RuntimeException(); // TODO:
417 return m_aModuleName
;
420 //-------------------------------------------------------------------------
421 const ::comphelper::SequenceAsHashMap
& ModelData_Impl::GetModuleProps()
423 if ( !m_pModulePropsHM
)
425 uno::Sequence
< beans::PropertyValue
> aModuleProps
;
426 m_pOwner
->GetNamedModuleManager()->getByName( GetModuleName() ) >>= aModuleProps
;
427 if ( !aModuleProps
.getLength() )
428 throw uno::RuntimeException(); // TODO;
429 m_pModulePropsHM
= new ::comphelper::SequenceAsHashMap( aModuleProps
);
432 return *m_pModulePropsHM
;
435 //-------------------------------------------------------------------------
436 ::rtl::OUString
ModelData_Impl::GetDocServiceName()
438 return GetModuleProps().getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryDocumentService")), ::rtl::OUString());
441 //-------------------------------------------------------------------------
442 void ModelData_Impl::CheckInteractionHandler()
444 ::comphelper::SequenceAsHashMap::const_iterator aInteractIter
=
445 m_aMediaDescrHM
.find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) );
447 if ( aInteractIter
== m_aMediaDescrHM
.end() )
450 m_aMediaDescrHM
[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) ]
451 <<= uno::Reference
< task::XInteractionHandler
>(
452 m_pOwner
->GetServiceFactory()->createInstance(
453 DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ),
456 catch( const uno::Exception
& )
462 uno::Reference
< task::XInteractionHandler
> xInteract
;
463 DBG_ASSERT( ( aInteractIter
->second
>>= xInteract
) && xInteract
.is(), "Broken interaction handler is provided!\n" );
467 //-------------------------------------------------------------------------
468 uno::Sequence
< beans::PropertyValue
> ModelData_Impl::GetDocServiceDefaultFilter()
470 uno::Sequence
< beans::PropertyValue
> aProps
;
472 ::rtl::OUString aFilterName
= GetModuleProps().getUnpackedValueOrDefault(
473 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryDefaultFilter")),
476 m_pOwner
->GetFilterConfiguration()->getByName( aFilterName
) >>= aProps
;
481 //-------------------------------------------------------------------------
482 uno::Sequence
< beans::PropertyValue
> ModelData_Impl::GetDocServiceDefaultFilterCheckFlags( sal_Int32 nMust
,
485 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
486 uno::Sequence
< beans::PropertyValue
> aProps
= GetDocServiceDefaultFilter();
487 if ( aProps
.getLength() )
489 ::comphelper::SequenceAsHashMap
aFiltHM( aProps
);
490 sal_Int32 nFlags
= aFiltHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")),
492 if ( ( ( nFlags
& nMust
) == nMust
) && !( nFlags
& nDont
) )
493 aFilterProps
= aProps
;
500 //-------------------------------------------------------------------------
501 uno::Sequence
< beans::PropertyValue
> ModelData_Impl::GetDocServiceAnyFilter( sal_Int32 nMust
, sal_Int32 nDont
)
503 uno::Sequence
< beans::NamedValue
> aSearchRequest( 1 );
504 aSearchRequest
[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentService"));
505 aSearchRequest
[0].Value
<<= GetDocServiceName();
507 return ::comphelper::MimeConfigurationHelper::SearchForFilter( m_pOwner
->GetFilterQuery(), aSearchRequest
, nMust
, nDont
);
510 //-------------------------------------------------------------------------
511 uno::Sequence
< beans::PropertyValue
> ModelData_Impl::GetPreselectedFilter_Impl( sal_Int8 nStoreMode
)
513 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
515 sal_Int32 nMust
= getMustFlags( nStoreMode
);
516 sal_Int32 nDont
= getDontFlags( nStoreMode
);
518 if ( nStoreMode
& PDFEXPORT_REQUESTED
)
520 // Preselect PDF-Filter for EXPORT
521 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
522 aSearchRequest
[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Type"));
523 aSearchRequest
[0].Value
<<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("pdf_Portable_Document_Format"));
524 aSearchRequest
[1].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentService"));
525 aSearchRequest
[1].Value
<<= GetDocServiceName();
527 aFilterProps
= ::comphelper::MimeConfigurationHelper::SearchForFilter( m_pOwner
->GetFilterQuery(), aSearchRequest
, nMust
, nDont
);
531 aFilterProps
= GetDocServiceDefaultFilterCheckFlags( nMust
, nDont
);
533 if ( !aFilterProps
.getLength() )
535 // the default filter was not faund, use just the first acceptable one
536 aFilterProps
= GetDocServiceAnyFilter( nMust
, nDont
);
543 //-------------------------------------------------------------------------
544 sal_Bool
ModelData_Impl::ExecuteFilterDialog_Impl( const ::rtl::OUString
& aFilterName
)
546 sal_Bool bDialogUsed
= sal_False
;
549 uno::Sequence
< beans::PropertyValue
> aProps
;
550 uno::Any aAny
= m_pOwner
->GetFilterConfiguration()->getByName( aFilterName
);
551 if ( aAny
>>= aProps
)
553 sal_Int32 nPropertyCount
= aProps
.getLength();
554 for( sal_Int32 nProperty
=0; nProperty
< nPropertyCount
; ++nProperty
)
555 if( aProps
[nProperty
].Name
== "UIComponent" )
557 ::rtl::OUString aServiceName
;
558 aProps
[nProperty
].Value
>>= aServiceName
;
559 if( !aServiceName
.isEmpty() )
561 uno::Reference
< ui::dialogs::XExecutableDialog
> xFilterDialog(
562 m_pOwner
->GetServiceFactory()->createInstance( aServiceName
), uno::UNO_QUERY
);
563 uno::Reference
< beans::XPropertyAccess
> xFilterProperties( xFilterDialog
, uno::UNO_QUERY
);
565 if( xFilterDialog
.is() && xFilterProperties
.is() )
567 bDialogUsed
= sal_True
;
569 uno::Reference
< document::XExporter
> xExporter( xFilterDialog
, uno::UNO_QUERY
);
571 xExporter
->setSourceDocument(
572 uno::Reference
< lang::XComponent
>( GetModel(), uno::UNO_QUERY
) );
574 uno::Sequence
< beans::PropertyValue
> aPropsForDialog
;
575 GetMediaDescr() >> aPropsForDialog
;
576 xFilterProperties
->setPropertyValues( aPropsForDialog
);
578 if( xFilterDialog
->execute() )
580 uno::Sequence
< beans::PropertyValue
> aPropsFromDialog
=
581 xFilterProperties
->getPropertyValues();
582 for ( sal_Int32 nInd
= 0; nInd
< aPropsFromDialog
.getLength(); nInd
++ )
583 GetMediaDescr()[aPropsFromDialog
[nInd
].Name
] = aPropsFromDialog
[nInd
].Value
;
587 throw task::ErrorCodeIOException( ::rtl::OUString(),
588 uno::Reference
< uno::XInterface
>(),
598 catch( const container::NoSuchElementException
& )
600 // the filter name is unknown
601 throw task::ErrorCodeIOException( ::rtl::OUString(),
602 uno::Reference
< uno::XInterface
>(),
603 ERRCODE_IO_INVALIDPARAMETER
);
605 catch( const task::ErrorCodeIOException
& )
609 catch( const uno::Exception
& )
616 //-------------------------------------------------------------------------
617 sal_Int8
ModelData_Impl::CheckSaveAcceptable( sal_Int8 nCurStatus
)
619 sal_Int8 nResult
= nCurStatus
;
621 if ( nResult
!= STATUS_NO_ACTION
&& GetStorable()->hasLocation() )
623 // check whether save is acceptable by the configuration
624 // it is done only for documents that have persistence already
625 uno::Reference
< uno::XInterface
> xCommonConfig
= ::comphelper::ConfigurationHelper::openConfig(
626 m_pOwner
->GetServiceFactory(),
627 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
628 ::comphelper::ConfigurationHelper::E_STANDARD
);
629 if ( !xCommonConfig
.is() )
630 throw uno::RuntimeException(); // should the saving proceed as usual instead?
634 sal_Bool bAlwaysSaveAs
= sal_False
;
636 // the saving is acceptable
637 // in case the configuration entry is not set or set to false
638 // or in case of version creation
639 ::rtl::OUString aVersionCommentString
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VersionComment"));
640 if ( ( ::comphelper::ConfigurationHelper::readRelativeKey(
642 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Save/Document/" ) ),
643 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AlwaysSaveAs" ) ) ) >>= bAlwaysSaveAs
)
645 && GetMediaDescr().find( aVersionCommentString
) == GetMediaDescr().end() )
647 // notify the user that SaveAs is going to be done
648 String
aString( SfxResId( STR_NEW_FILENAME_SAVE
) );
649 Window
* pWin
= SfxStoringHelper::GetModelWindow( m_xModel
);
650 QueryBox
aMessageBox( pWin
, WB_OK_CANCEL
| WB_DEF_OK
, aString
);
651 if ( aMessageBox
.Execute() == RET_OK
)
652 nResult
= STATUS_SAVEAS
;
654 nResult
= STATUS_NO_ACTION
;
657 catch( const uno::Exception
& )
659 // impossibility to get the configuration access means normal saving flow for now
666 //-------------------------------------------------------------------------
667 sal_Int8
ModelData_Impl::CheckStateForSave()
669 // if the document is readonly or a new one a SaveAs operation must be used
670 if ( !GetStorable()->hasLocation() || GetStorable()->isReadonly() )
671 return STATUS_SAVEAS
;
673 // check acceptable entries for media descriptor
674 sal_Bool bVersInfoNeedsStore
= sal_False
;
675 ::comphelper::SequenceAsHashMap aAcceptedArgs
;
677 ::rtl::OUString
aVersionCommentString(RTL_CONSTASCII_USTRINGPARAM("VersionComment"));
678 ::rtl::OUString
aAuthorString(RTL_CONSTASCII_USTRINGPARAM("Author"));
679 ::rtl::OUString
aInteractionHandlerString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler"));
680 ::rtl::OUString
aStatusIndicatorString(RTL_CONSTASCII_USTRINGPARAM("StatusIndicator"));
682 if ( GetMediaDescr().find( aVersionCommentString
) != GetMediaDescr().end() )
684 bVersInfoNeedsStore
= sal_True
;
685 aAcceptedArgs
[ aVersionCommentString
] = GetMediaDescr()[ aVersionCommentString
];
687 if ( GetMediaDescr().find( aAuthorString
) != GetMediaDescr().end() )
688 aAcceptedArgs
[ aAuthorString
] = GetMediaDescr()[ aAuthorString
];
689 if ( GetMediaDescr().find( aInteractionHandlerString
) != GetMediaDescr().end() )
690 aAcceptedArgs
[ aInteractionHandlerString
] = GetMediaDescr()[ aInteractionHandlerString
];
691 if ( GetMediaDescr().find( aStatusIndicatorString
) != GetMediaDescr().end() )
692 aAcceptedArgs
[ aStatusIndicatorString
] = GetMediaDescr()[ aStatusIndicatorString
];
694 // remove unacceptable entry if there is any
695 DBG_ASSERT( GetMediaDescr().size() == aAcceptedArgs
.size(),
696 "Unacceptable parameters are provided in Save request!\n" );
697 if ( GetMediaDescr().size() != aAcceptedArgs
.size() )
698 GetMediaDescr() = aAcceptedArgs
;
700 // the document must be modified unless the always-save flag is set.
701 SvtMiscOptions aMiscOptions
;
702 sal_Bool bAlwaysAllowSave
= aMiscOptions
.IsSaveAlwaysAllowed();
703 if (!bAlwaysAllowSave
)
705 if ( !GetModifiable()->isModified() && !bVersInfoNeedsStore
)
706 return STATUS_NO_ACTION
;
709 // check that the old filter is acceptable
710 ::rtl::OUString aOldFilterName
= GetDocProps().getUnpackedValueOrDefault(
711 rtl::OUString(aFilterNameString
),
713 sal_Int8 nResult
= CheckFilter( aOldFilterName
);
718 sal_Int8
ModelData_Impl::CheckFilter( const ::rtl::OUString
& aFilterName
)
720 ::comphelper::SequenceAsHashMap aFiltPropsHM
;
721 sal_Int32 nFiltFlags
= 0;
722 if ( !aFilterName
.isEmpty() )
724 // get properties of filter
725 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
726 if ( !aFilterName
.isEmpty() )
727 m_pOwner
->GetFilterConfiguration()->getByName( aFilterName
) >>= aFilterProps
;
729 aFiltPropsHM
= ::comphelper::SequenceAsHashMap( aFilterProps
);
730 nFiltFlags
= aFiltPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")), (sal_Int32
)0 );
733 // only a temporary solution until default filter retrieving feature is implemented
734 // then GetDocServiceDefaultFilter() must be used
735 ::comphelper::SequenceAsHashMap aDefFiltPropsHM
= GetDocServiceDefaultFilterCheckFlags( 3, 0 );
736 sal_Int32 nDefFiltFlags
= aDefFiltPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")), (sal_Int32
)0 );
738 // if the old filter is not acceptable
739 // and there is no default filter or it is not acceptable for requested parameters then proceed with saveAs
740 if ( ( !aFiltPropsHM
.size() || !( nFiltFlags
& SFX_FILTER_EXPORT
) )
741 && ( !aDefFiltPropsHM
.size() || !( nDefFiltFlags
& SFX_FILTER_EXPORT
) || nDefFiltFlags
& SFX_FILTER_INTERNAL
) )
742 return STATUS_SAVEAS
;
744 // so at this point there is either an acceptable old filter or default one
745 if ( !aFiltPropsHM
.size() || !( nFiltFlags
& SFX_FILTER_EXPORT
) )
747 // so the default filter must be acceptable
748 return STATUS_SAVEAS_STANDARDNAME
;
750 else if ( ( !( nFiltFlags
& SFX_FILTER_OWN
) || ( nFiltFlags
& SFX_FILTER_ALIEN
) )
751 && aDefFiltPropsHM
.size()
752 && ( nDefFiltFlags
& SFX_FILTER_EXPORT
) && !( nDefFiltFlags
& SFX_FILTER_INTERNAL
))
754 // the default filter is acceptable and the old filter is alian one
755 // so ask to make a saveAs operation
756 ::rtl::OUString aUIName
= aFiltPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIName")),
758 ::rtl::OUString aDefUIName
= aDefFiltPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIName")),
760 ::rtl::OUString aPreusedFilterName
= GetDocProps().getUnpackedValueOrDefault(
761 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PreusedFilterName")),
763 if ( !aPreusedFilterName
.equals( aFilterName
) && !aUIName
.equals( aDefUIName
) )
765 if ( !SfxStoringHelper::WarnUnacceptableFormat( GetModel(), aUIName
, aDefUIName
, sal_True
) )
766 return STATUS_SAVEAS_STANDARDNAME
;
773 //-------------------------------------------------------------------------
774 sal_Bool
ModelData_Impl::CheckFilterOptionsDialogExistence()
776 uno::Sequence
< beans::NamedValue
> aSearchRequest( 1 );
777 aSearchRequest
[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentService"));
778 aSearchRequest
[0].Value
<<= GetDocServiceName();
780 uno::Reference
< container::XEnumeration
> xFilterEnum
=
781 m_pOwner
->GetFilterQuery()->createSubSetEnumerationByProperties( aSearchRequest
);
783 while ( xFilterEnum
->hasMoreElements() )
785 uno::Sequence
< beans::PropertyValue
> pProps
;
786 if ( xFilterEnum
->nextElement() >>= pProps
)
788 ::comphelper::SequenceAsHashMap
aPropsHM( pProps
);
789 ::rtl::OUString aUIServName
= aPropsHM
.getUnpackedValueOrDefault(
790 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIComponent")),
792 if ( !aUIServName
.isEmpty() )
800 //-------------------------------------------------------------------------
801 sal_Bool
ModelData_Impl::OutputFileDialog( sal_Int8 nStoreMode
,
802 const ::comphelper::SequenceAsHashMap
& aPreselectedFilterPropsHM
,
803 sal_Bool bSetStandardName
,
804 ::rtl::OUString
& aSuggestedName
,
805 sal_Bool bPreselectPassword
,
806 ::rtl::OUString
& aSuggestedDir
,
808 const ::rtl::OUString
& rStandardDir
,
809 const ::com::sun::star::uno::Sequence
< ::rtl::OUString
>& rBlackList
)
811 sal_Bool bUseFilterOptions
= sal_False
;
813 ::comphelper::SequenceAsHashMap::const_iterator aOverwriteIter
=
814 GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Overwrite")) );
816 // the file name must be specified if overwrite option is set
817 if ( aOverwriteIter
!= GetMediaDescr().end() )
818 throw task::ErrorCodeIOException( ::rtl::OUString(),
819 uno::Reference
< uno::XInterface
>(),
820 ERRCODE_IO_INVALIDPARAMETER
);
822 // no target file name is specified
823 // we need to show the file dialog
825 // check if we have a filter which allows for filter options, so we need a corresponding checkbox in the dialog
826 sal_Bool bAllowOptions
= sal_False
;
828 // in case of Export, filter options dialog is used if available
829 if( !( nStoreMode
& EXPORT_REQUESTED
) || ( nStoreMode
& WIDEEXPORT_REQUESTED
) )
830 bAllowOptions
= CheckFilterOptionsDialogExistence();
832 // get the filename by dialog ...
833 // create the file dialog
834 sal_Int16 aDialogMode
= bAllowOptions
835 ? (com::sun::star::ui::dialogs::TemplateDescription::
836 FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS
)
837 : (com::sun::star::ui::dialogs::TemplateDescription::
838 FILESAVE_AUTOEXTENSION_PASSWORD
);
839 sal_Int64 aDialogFlags
= 0;
841 if( ( nStoreMode
& EXPORT_REQUESTED
) && !( nStoreMode
& WIDEEXPORT_REQUESTED
) )
843 if ( nStoreMode
& PDFEXPORT_REQUESTED
)
844 aDialogMode
= com::sun::star::ui::dialogs::TemplateDescription::
845 FILESAVE_AUTOEXTENSION
;
847 aDialogMode
= com::sun::star::ui::dialogs::TemplateDescription::
848 FILESAVE_AUTOEXTENSION_SELECTION
;
849 aDialogFlags
= SFXWB_EXPORT
;
852 sfx2::FileDialogHelper
* pFileDlg
= NULL
;
854 ::rtl::OUString aDocServiceName
= GetDocServiceName();
855 DBG_ASSERT( !aDocServiceName
.isEmpty(), "No document service for this module set!" );
857 sal_Int32 nMust
= getMustFlags( nStoreMode
);
858 sal_Int32 nDont
= getDontFlags( nStoreMode
);
859 sfx2::FileDialogHelper::Context eCtxt
= sfx2::FileDialogHelper::UNKNOWN_CONTEXT
;
861 if ( ( nStoreMode
& EXPORT_REQUESTED
) && !( nStoreMode
& WIDEEXPORT_REQUESTED
) )
863 if ( ( nStoreMode
& PDFEXPORT_REQUESTED
) && aPreselectedFilterPropsHM
.size() )
865 // this is a PDF export
866 // the filter options has been shown already
867 ::rtl::OUString aFilterUIName
= aPreselectedFilterPropsHM
.getUnpackedValueOrDefault(
868 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIName")),
871 pFileDlg
= new sfx2::FileDialogHelper( aDialogMode
, aDialogFlags
, aFilterUIName
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "pdf" ) ), rStandardDir
, rBlackList
);
872 pFileDlg
->SetCurrentFilter( aFilterUIName
);
876 // This is the normal dialog
877 pFileDlg
= new sfx2::FileDialogHelper( aDialogMode
, aDialogFlags
, aDocServiceName
, nDialog
, nMust
, nDont
, rStandardDir
, rBlackList
);
880 if ( aDocServiceName
== "com.sun.star.drawing.DrawingDocument" )
881 eCtxt
= sfx2::FileDialogHelper::SD_EXPORT
;
882 else if ( aDocServiceName
== "com.sun.star.presentation.PresentationDocument" )
883 eCtxt
= sfx2::FileDialogHelper::SI_EXPORT
;
884 else if ( aDocServiceName
== "com.sun.star.text.TextDocument" )
885 eCtxt
= sfx2::FileDialogHelper::SW_EXPORT
;
887 if ( eCtxt
!= sfx2::FileDialogHelper::UNKNOWN_CONTEXT
)
888 pFileDlg
->SetContext( eCtxt
);
890 pFileDlg
->CreateMatcher( aDocServiceName
);
892 uno::Reference
< ui::dialogs::XFilePicker
> xFilePicker
= pFileDlg
->GetFilePicker();
893 uno::Reference
< ui::dialogs::XFilePickerControlAccess
> xControlAccess
=
894 uno::Reference
< ui::dialogs::XFilePickerControlAccess
>( xFilePicker
, uno::UNO_QUERY
);
896 if ( xControlAccess
.is() )
898 ::rtl::OUString aCtrlText
= String( SfxResId( STR_EXPORTBUTTON
) );
899 xControlAccess
->setLabel( ui::dialogs::CommonFilePickerElementIds::PUSHBUTTON_OK
, aCtrlText
);
901 aCtrlText
= ::rtl::OUString( String( SfxResId( STR_LABEL_FILEFORMAT
) ) );
902 xControlAccess
->setLabel( ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER_LABEL
, aCtrlText
);
907 // This is the normal dialog
908 pFileDlg
= new sfx2::FileDialogHelper( aDialogMode
, aDialogFlags
, aDocServiceName
, nDialog
, nMust
, nDont
, rStandardDir
, rBlackList
);
909 pFileDlg
->CreateMatcher( aDocServiceName
);
912 ::rtl::OUString aAdjustToType
;
914 const ::rtl::OUString
sFilterNameString(aFilterNameString
);
916 if ( ( nStoreMode
& EXPORT_REQUESTED
) && !( nStoreMode
& WIDEEXPORT_REQUESTED
) )
918 // it is export, set the preselected filter
919 ::rtl::OUString aFilterUIName
= aPreselectedFilterPropsHM
.getUnpackedValueOrDefault(
920 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIName")),
922 pFileDlg
->SetCurrentFilter( aFilterUIName
);
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() )
927 uno::Sequence
< beans::PropertyValue
> aOldFilterProps
;
928 ::rtl::OUString aOldFilterName
= GetDocProps().getUnpackedValueOrDefault(
932 if ( !aOldFilterName
.isEmpty() )
933 m_pOwner
->GetFilterConfiguration()->getByName( aOldFilterName
) >>= aOldFilterProps
;
935 ::comphelper::SequenceAsHashMap
aOldFiltPropsHM( aOldFilterProps
);
936 sal_Int32 nOldFiltFlags
= aOldFiltPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")), (sal_Int32
)0 );
938 if ( bSetStandardName
|| ( nOldFiltFlags
& nMust
) != nMust
|| nOldFiltFlags
& nDont
)
940 // the suggested type will be changed, the extension should be adjusted
941 aAdjustToType
= aPreselectedFilterPropsHM
.getUnpackedValueOrDefault(
942 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Type")),
945 ::rtl::OUString aFilterUIName
= aPreselectedFilterPropsHM
.getUnpackedValueOrDefault(
946 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIName")),
948 pFileDlg
->SetCurrentFilter( aFilterUIName
);
952 pFileDlg
->SetCurrentFilter( aOldFiltPropsHM
.getUnpackedValueOrDefault(
953 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIName")),
954 ::rtl::OUString() ) );
958 ::rtl::OUString aReccomendedDir
= GetReccomendedDir( aSuggestedDir
);
959 if ( !aReccomendedDir
.isEmpty() )
960 pFileDlg
->SetDisplayFolder( aReccomendedDir
);
961 ::rtl::OUString aReccomendedName
= GetReccomendedName( aSuggestedName
, aAdjustToType
);
962 if ( !aReccomendedName
.isEmpty() )
963 pFileDlg
->SetFileName( aReccomendedName
);
965 uno::Reference
< view::XSelectionSupplier
> xSel( GetModel()->getCurrentController(), uno::UNO_QUERY
);
966 if ( xSel
.is() && xSel
->getSelection().hasValue() )
967 GetMediaDescr()[::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SelectionOnly"))] <<= sal_True
;
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
);
973 throw lang::IllegalArgumentException(); // TODO:
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(),
984 const SfxPoolItem
* pItem
= NULL
;
985 if ( bPreselectPassword
&& aDialogParams
.GetItemState( SID_ENCRYPTIONDATA
, sal_True
, &pItem
) != SFX_ITEM_SET
)
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
) );
992 // aStringTypeFN is a pure output parameter, pDialogParams is an in/out parameter
993 String aStringTypeFN
;
994 if ( pFileDlg
->Execute( pDialogParams
, aStringTypeFN
) != ERRCODE_NONE
)
997 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference
< uno::XInterface
>(), ERRCODE_IO_ABORT
);
1000 ::rtl::OUString aFilterName
= aStringTypeFN
;
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
);
1008 uno::Sequence
< beans::PropertyValue
> aPropsFromDialog
;
1009 TransformItems( nSlotID
, *pDialogParams
, aPropsFromDialog
, NULL
);
1010 GetMediaDescr() << aPropsFromDialog
;
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 aSuggestedDir
= pFileDlg
->GetDisplayDirectory();
1018 // old filter options should be cleared in case different filter is used
1020 ::rtl::OUString aFilterFromMediaDescr
= GetMediaDescr().getUnpackedValueOrDefault(
1022 ::rtl::OUString() );
1023 ::rtl::OUString aOldFilterName
= GetDocProps().getUnpackedValueOrDefault(
1025 ::rtl::OUString() );
1027 const ::rtl::OUString
sFilterOptionsString(aFilterOptionsString
);
1028 const ::rtl::OUString
sFilterDataString(aFilterDataString
);
1030 if ( aFilterName
.equals( aFilterFromMediaDescr
) )
1032 // preserv current settings if any
1033 // if there no current settings and the name is the same
1034 // as old filter name use old filter settings
1036 if ( aFilterFromMediaDescr
.equals( aOldFilterName
) )
1038 ::comphelper::SequenceAsHashMap::const_iterator aIter
=
1039 GetDocProps().find( sFilterOptionsString
);
1040 if ( aIter
!= GetDocProps().end()
1041 && GetMediaDescr().find( sFilterOptionsString
) == GetMediaDescr().end() )
1042 GetMediaDescr()[aIter
->first
] = aIter
->second
;
1044 aIter
= GetDocProps().find( sFilterDataString
);
1045 if ( aIter
!= GetDocProps().end()
1046 && GetMediaDescr().find( sFilterDataString
) == GetMediaDescr().end() )
1047 GetMediaDescr()[aIter
->first
] = aIter
->second
;
1052 GetMediaDescr().erase( sFilterDataString
);
1053 GetMediaDescr().erase( sFilterOptionsString
);
1055 if ( aFilterName
.equals( aOldFilterName
) )
1057 // merge filter option of the document filter
1059 ::comphelper::SequenceAsHashMap::const_iterator aIter
=
1060 GetDocProps().find( sFilterOptionsString
);
1061 if ( aIter
!= GetDocProps().end() )
1062 GetMediaDescr()[aIter
->first
] = aIter
->second
;
1064 aIter
= GetDocProps().find( sFilterDataString
);
1065 if ( aIter
!= GetDocProps().end() )
1066 GetMediaDescr()[aIter
->first
] = aIter
->second
;
1070 uno::Reference
< ui::dialogs::XFilePickerControlAccess
> xExtFileDlg( pFileDlg
->GetFilePicker(), uno::UNO_QUERY
);
1071 if ( xExtFileDlg
.is() )
1073 if ( SfxStoringHelper::CheckFilterOptionsAppearence( m_pOwner
->GetFilterConfiguration(), aFilterName
) )
1074 bUseFilterOptions
= sal_True
;
1076 if ( ( !( nStoreMode
& EXPORT_REQUESTED
) || ( nStoreMode
& WIDEEXPORT_REQUESTED
) ) && bUseFilterOptions
)
1080 // for exporters: always show dialog if format uses options
1081 // for save: show dialog if format uses options and no options given or if forced by user
1083 xExtFileDlg
->getValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS
, 0 );
1085 aVal
>>= bUseFilterOptions
;
1086 if ( !bUseFilterOptions
)
1088 ( GetMediaDescr().find( sFilterDataString
) == GetMediaDescr().end()
1089 && GetMediaDescr().find( sFilterOptionsString
) == GetMediaDescr().end() );
1091 catch( const lang::IllegalArgumentException
& )
1098 // merge in results of the dialog execution
1099 GetMediaDescr()[::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"))] <<=
1100 ::rtl::OUString( aURL
.GetMainURL( INetURLObject::NO_DECODE
));
1101 GetMediaDescr()[sFilterNameString
] <<= aFilterName
;
1103 return bUseFilterOptions
;
1106 //-------------------------------------------------------------------------
1107 sal_Bool
ModelData_Impl::ShowDocumentInfoDialog()
1109 sal_Bool bDialogUsed
= sal_False
;
1112 uno::Reference
< frame::XController
> xController
= GetModel()->getCurrentController();
1113 if ( xController
.is() )
1115 uno::Reference
< frame::XDispatchProvider
> xFrameDispatch( xController
->getFrame(), uno::UNO_QUERY
);
1116 if ( xFrameDispatch
.is() )
1119 aURL
.Complete
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:SetDocumentProperties"));
1121 uno::Reference
< util::XURLTransformer
> xTransformer(
1122 m_pOwner
->GetServiceFactory()->createInstance(
1123 DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer") ),
1125 if ( xTransformer
.is() && xTransformer
->parseStrict( aURL
) )
1127 uno::Reference
< frame::XDispatch
> xDispatch
= xFrameDispatch
->queryDispatch(
1129 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")),
1131 if ( xDispatch
.is() )
1133 xDispatch
->dispatch( aURL
, uno::Sequence
< beans::PropertyValue
>() );
1134 bDialogUsed
= sal_True
;
1140 catch ( const uno::Exception
& )
1147 //-------------------------------------------------------------------------
1148 ::rtl::OUString
ModelData_Impl::GetReccomendedDir( const ::rtl::OUString
& aSuggestedDir
)
1150 ::rtl::OUString aReccomendedDir
;
1152 if ( ( !aSuggestedDir
.isEmpty() || GetStorable()->hasLocation() )
1153 && !GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")),
1156 INetURLObject aLocation
;
1157 if ( !aSuggestedDir
.isEmpty() )
1158 aLocation
= INetURLObject( aSuggestedDir
);
1161 ::rtl::OUString aOldURL
= GetStorable()->getLocation();
1162 if ( !aOldURL
.isEmpty() )
1164 INetURLObject
aTmp( aOldURL
);
1165 if ( aTmp
.removeSegment() )
1169 if ( aLocation
.HasError() )
1170 aLocation
= INetURLObject( SvtPathOptions().GetWorkPath() );
1173 aLocation
.setFinalSlash();
1174 if ( !aLocation
.HasError() )
1175 aReccomendedDir
= aLocation
.GetMainURL( INetURLObject::NO_DECODE
);
1179 aReccomendedDir
= INetURLObject( SvtPathOptions().GetWorkPath() ).GetMainURL( INetURLObject::NO_DECODE
);
1182 return aReccomendedDir
;
1185 //-------------------------------------------------------------------------
1186 ::rtl::OUString
ModelData_Impl::GetReccomendedName( const ::rtl::OUString
& aSuggestedName
, const ::rtl::OUString
& aTypeName
)
1188 // the last used name might be provided by aSuggestedName from the old selection, or from the MediaDescriptor
1189 ::rtl::OUString aReccomendedName
;
1191 if ( !aSuggestedName
.isEmpty() )
1192 aReccomendedName
= aSuggestedName
;
1195 aReccomendedName
= INetURLObject( GetStorable()->getLocation() ).GetName( INetURLObject::DECODE_WITH_CHARSET
);
1196 if ( aReccomendedName
.isEmpty() )
1199 uno::Reference
< frame::XTitle
> xTitle( GetModel(), uno::UNO_QUERY_THROW
);
1200 aReccomendedName
= xTitle
->getTitle();
1201 } catch( const uno::Exception
& ) {}
1204 if ( !aReccomendedName
.isEmpty() && !aTypeName
.isEmpty() )
1206 // adjust the extension to the type
1207 uno::Reference
< container::XNameAccess
> xTypeDetection
= uno::Reference
< container::XNameAccess
>(
1208 m_pOwner
->GetServiceFactory()->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.TypeDetection")) ),
1210 if ( xTypeDetection
.is() )
1212 INetURLObject
aObj( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///c:/" ) ) + aReccomendedName
);
1214 uno::Sequence
< beans::PropertyValue
> aTypeNameProps
;
1215 if ( ( xTypeDetection
->getByName( aTypeName
) >>= aTypeNameProps
) && aTypeNameProps
.getLength() )
1217 ::comphelper::SequenceAsHashMap
aTypeNamePropsHM( aTypeNameProps
);
1218 uno::Sequence
< ::rtl::OUString
> aExtensions
= aTypeNamePropsHM
.getUnpackedValueOrDefault(
1219 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Extensions")),
1220 ::uno::Sequence
< ::rtl::OUString
>() );
1221 if ( aExtensions
.getLength() )
1222 aObj
.SetExtension( aExtensions
[0] );
1225 aReccomendedName
= aObj
.GetName( INetURLObject::DECODE_WITH_CHARSET
);
1230 return aReccomendedName
;
1234 //=========================================================================
1235 // class SfxStoringHelper
1236 //=========================================================================
1237 //-------------------------------------------------------------------------
1238 SfxStoringHelper::SfxStoringHelper( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
1239 : m_xFactory( xFactory
)
1243 //-------------------------------------------------------------------------
1244 uno::Reference
< lang::XMultiServiceFactory
> SfxStoringHelper::GetServiceFactory()
1246 if ( !m_xFactory
.is() )
1248 m_xFactory
= ::comphelper::getProcessServiceFactory();
1249 if( !m_xFactory
.is() )
1250 throw uno::RuntimeException(); // TODO:
1256 //-------------------------------------------------------------------------
1257 uno::Reference
< container::XNameAccess
> SfxStoringHelper::GetFilterConfiguration()
1259 if ( !m_xFilterCFG
.is() )
1261 m_xFilterCFG
= uno::Reference
< container::XNameAccess
>(
1262 GetServiceFactory()->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.FilterFactory")) ),
1265 if ( !m_xFilterCFG
.is() )
1266 throw uno::RuntimeException();
1269 return m_xFilterCFG
;
1272 //-------------------------------------------------------------------------
1273 uno::Reference
< container::XContainerQuery
> SfxStoringHelper::GetFilterQuery()
1275 if ( !m_xFilterQuery
.is() )
1277 m_xFilterQuery
= uno::Reference
< container::XContainerQuery
>( GetFilterConfiguration(), uno::UNO_QUERY
);
1278 if ( !m_xFilterQuery
.is() )
1279 throw uno::RuntimeException();
1282 return m_xFilterQuery
;
1285 //-------------------------------------------------------------------------
1286 uno::Reference
< ::com::sun::star::frame::XModuleManager
> SfxStoringHelper::GetModuleManager()
1288 if ( !m_xModuleManager
.is() )
1290 m_xModuleManager
= uno::Reference
< ::com::sun::star::frame::XModuleManager
>(
1291 GetServiceFactory()->createInstance(
1292 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.ModuleManager")) ),
1295 if ( !m_xModuleManager
.is() )
1296 throw uno::RuntimeException();
1299 return m_xModuleManager
;
1302 //-------------------------------------------------------------------------
1303 uno::Reference
< container::XNameAccess
> SfxStoringHelper::GetNamedModuleManager()
1305 if ( !m_xNamedModManager
.is() )
1307 m_xNamedModManager
= uno::Reference
< container::XNameAccess
>( GetModuleManager(), uno::UNO_QUERY
);
1308 if ( !m_xNamedModManager
.is() )
1309 throw uno::RuntimeException();
1312 return m_xNamedModManager
;
1315 //-------------------------------------------------------------------------
1316 sal_Bool
SfxStoringHelper::GUIStoreModel( const uno::Reference
< frame::XModel
>& xModel
,
1317 const ::rtl::OUString
& aSlotName
,
1318 uno::Sequence
< beans::PropertyValue
>& aArgsSequence
,
1319 sal_Bool bPreselectPassword
,
1320 ::rtl::OUString aSuggestedName
,
1321 sal_uInt16 nDocumentSignatureState
)
1323 ModelData_Impl
aModelData( *this, xModel
, aArgsSequence
);
1325 sal_Bool bDialogUsed
= sal_False
;
1329 sal_Bool bSetStandardName
= sal_False
; // can be set only for SaveAs
1331 // parse the slot name
1332 sal_Int8 nStoreMode
= getStoreModeFromSlotName( aSlotName
);
1333 sal_Int8 nStatusSave
= STATUS_NO_ACTION
;
1335 // handle the special cases
1336 if ( nStoreMode
& SAVEAS_REQUESTED
)
1338 ::comphelper::SequenceAsHashMap::const_iterator aSaveToIter
=
1339 aModelData
.GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SaveTo")) );
1340 if ( aSaveToIter
!= aModelData
.GetMediaDescr().end() )
1342 sal_Bool bWideExport
= sal_False
;
1343 aSaveToIter
->second
>>= bWideExport
;
1345 nStoreMode
= EXPORT_REQUESTED
| WIDEEXPORT_REQUESTED
;
1348 // if saving is not acceptable the warning must be shown even in case of SaveAs operation
1349 if ( ( nStoreMode
& SAVEAS_REQUESTED
) && aModelData
.CheckSaveAcceptable( STATUS_SAVEAS
) == STATUS_NO_ACTION
)
1350 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference
< uno::XInterface
>(), ERRCODE_IO_ABORT
);
1352 else if ( nStoreMode
& SAVE_REQUESTED
)
1354 // if saving is not acceptable by the configuration the warning must be shown
1355 nStatusSave
= aModelData
.CheckSaveAcceptable( STATUS_SAVE
);
1357 if ( nStatusSave
== STATUS_NO_ACTION
)
1358 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference
< uno::XInterface
>(), ERRCODE_IO_ABORT
);
1359 else if ( nStatusSave
== STATUS_SAVE
)
1361 // check whether it is possible to use save operation
1362 nStatusSave
= aModelData
.CheckStateForSave();
1365 if ( nStatusSave
== STATUS_NO_ACTION
)
1367 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference
< uno::XInterface
>(), ERRCODE_IO_ABORT
);
1369 else if ( nStatusSave
!= STATUS_SAVE
)
1371 // this should be a usual SaveAs operation
1372 nStoreMode
= SAVEAS_REQUESTED
;
1373 if ( nStatusSave
== STATUS_SAVEAS_STANDARDNAME
)
1374 bSetStandardName
= sal_True
;
1378 if ( !( nStoreMode
& EXPORT_REQUESTED
) )
1380 // if it is no export, warn user that the signature will be removed
1381 if ( SIGNATURESTATE_SIGNATURES_OK
== nDocumentSignatureState
1382 || SIGNATURESTATE_SIGNATURES_INVALID
== nDocumentSignatureState
1383 || SIGNATURESTATE_SIGNATURES_NOTVALIDATED
== nDocumentSignatureState
1384 || SIGNATURESTATE_SIGNATURES_PARTIAL_OK
== nDocumentSignatureState
)
1386 if ( QueryBox( NULL
, SfxResId( RID_XMLSEC_QUERY_LOSINGSIGNATURE
) ).Execute() != RET_YES
)
1388 // the user has decided not to store the document
1389 throw task::ErrorCodeIOException( ::rtl::OUString(),
1390 uno::Reference
< uno::XInterface
>(),
1396 if ( nStoreMode
& SAVE_REQUESTED
&& nStatusSave
== STATUS_SAVE
)
1398 // Document properties can contain streams that should be freed before storing
1399 aModelData
.FreeDocumentProps();
1401 if ( aModelData
.GetStorable2().is() )
1405 aModelData
.GetStorable2()->storeSelf( aModelData
.GetMediaDescr().getAsConstPropertyValueList() );
1407 catch( const lang::IllegalArgumentException
& )
1409 OSL_FAIL( "ModelData didn't handle illegal parameters, all the parameters are ignored!\n" );
1410 aModelData
.GetStorable()->store();
1415 OSL_FAIL( "XStorable2 is not supported by the model!\n" );
1416 aModelData
.GetStorable()->store();
1422 // preselect a filter for the storing process
1423 uno::Sequence
< beans::PropertyValue
> aFilterProps
= aModelData
.GetPreselectedFilter_Impl( nStoreMode
);
1425 DBG_ASSERT( aFilterProps
.getLength(), "No filter for storing!\n" );
1426 if ( !aFilterProps
.getLength() )
1427 throw task::ErrorCodeIOException( ::rtl::OUString(),
1428 uno::Reference
< uno::XInterface
>(),
1429 ERRCODE_IO_INVALIDPARAMETER
);
1431 ::comphelper::SequenceAsHashMap
aFilterPropsHM( aFilterProps
);
1432 ::rtl::OUString aFilterName
= aFilterPropsHM
.getUnpackedValueOrDefault(
1433 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")),
1434 ::rtl::OUString() );
1436 const ::rtl::OUString
sFilterNameString(aFilterNameString
);
1438 ::rtl::OUString aFilterFromMediaDescr
= aModelData
.GetMediaDescr().getUnpackedValueOrDefault(
1440 ::rtl::OUString() );
1441 ::rtl::OUString aOldFilterName
= aModelData
.GetDocProps().getUnpackedValueOrDefault(
1443 ::rtl::OUString() );
1445 sal_Bool bUseFilterOptions
= sal_False
;
1446 ::comphelper::SequenceAsHashMap::const_iterator aFileNameIter
= aModelData
.GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) );
1448 const ::rtl::OUString
sFilterOptionsString(aFilterOptionsString
);
1449 const ::rtl::OUString
sFilterDataString(aFilterDataString
);
1450 const ::rtl::OUString
sFilterFlagsString(aFilterFlagsString
);
1452 if ( ( nStoreMode
& EXPORT_REQUESTED
) && ( nStoreMode
& PDFEXPORT_REQUESTED
) && !( nStoreMode
& PDFDIRECTEXPORT_REQUESTED
) )
1454 // this is PDF export, the filter options dialog should be shown before the export
1455 aModelData
.GetMediaDescr()[sFilterNameString
] <<= aFilterName
;
1456 if ( aModelData
.GetMediaDescr().find( sFilterFlagsString
) == aModelData
.GetMediaDescr().end()
1457 && aModelData
.GetMediaDescr().find( sFilterOptionsString
) == aModelData
.GetMediaDescr().end()
1458 && aModelData
.GetMediaDescr().find( sFilterDataString
) == aModelData
.GetMediaDescr().end() )
1460 // execute filter options dialog since no options are set in the media descriptor
1461 if ( aModelData
.ExecuteFilterDialog_Impl( aFilterName
) )
1462 bDialogUsed
= sal_True
;
1466 if ( aFileNameIter
== aModelData
.GetMediaDescr().end() )
1468 sal_Int16 nDialog
= SFX2_IMPL_DIALOG_CONFIG
;
1469 ::comphelper::SequenceAsHashMap::const_iterator aDlgIter
=
1470 aModelData
.GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UseSystemDialog")) );
1471 if ( aDlgIter
!= aModelData
.GetMediaDescr().end() )
1473 sal_Bool bUseSystemDialog
= sal_True
;
1474 if ( aDlgIter
->second
>>= bUseSystemDialog
)
1476 if ( bUseSystemDialog
)
1477 nDialog
= SFX2_IMPL_DIALOG_SYSTEM
;
1479 nDialog
= SFX2_IMPL_DIALOG_OOO
;
1483 // The Dispatch supports parameter FolderName that overwrites SuggestedSaveAsDir
1484 ::rtl::OUString aSuggestedDir
= aModelData
.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FolderName" ) ), ::rtl::OUString() );
1485 if ( aSuggestedDir
.isEmpty() )
1487 aSuggestedDir
= aModelData
.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() );
1488 if ( aSuggestedDir
.isEmpty() )
1489 aSuggestedDir
= aModelData
.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsDir" ) ), ::rtl::OUString() );
1492 aSuggestedName
= aModelData
.GetMediaDescr().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() );
1493 if ( aSuggestedName
.isEmpty() )
1494 aSuggestedName
= aModelData
.GetDocProps().getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SuggestedSaveAsName" ) ), ::rtl::OUString() );
1496 ::rtl::OUString sStandardDir
;
1497 ::comphelper::SequenceAsHashMap::const_iterator aStdDirIter
=
1498 aModelData
.GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StandardDir")) );
1499 if ( aStdDirIter
!= aModelData
.GetMediaDescr().end() )
1500 aStdDirIter
->second
>>= sStandardDir
;
1502 ::com::sun::star::uno::Sequence
< ::rtl::OUString
> aBlackList
;
1504 ::comphelper::SequenceAsHashMap::const_iterator aBlackListIter
=
1505 aModelData
.GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BlackList")) );
1506 if ( aBlackListIter
!= aModelData
.GetMediaDescr().end() )
1507 aBlackListIter
->second
>>= aBlackList
;
1509 sal_Bool bExit
= sal_False
;
1512 // in case the dialog is opened a second time the folder should be the same as previously navigated to by the user, not what was handed over by initial parameters
1513 bUseFilterOptions
= aModelData
.OutputFileDialog( nStoreMode
, aFilterProps
, bSetStandardName
, aSuggestedName
, bPreselectPassword
, aSuggestedDir
, nDialog
, sStandardDir
, aBlackList
);
1514 if ( nStoreMode
== SAVEAS_REQUESTED
)
1516 // in case of saving check filter for possible alien warning
1517 ::rtl::OUString aSelFilterName
= aModelData
.GetMediaDescr().getUnpackedValueOrDefault(
1519 ::rtl::OUString() );
1520 sal_Int8 nStatusFilterSave
= aModelData
.CheckFilter( aSelFilterName
);
1521 if ( nStatusFilterSave
== STATUS_SAVEAS_STANDARDNAME
)
1523 // switch to best filter
1524 bSetStandardName
= sal_True
;
1526 else if ( nStatusFilterSave
== STATUS_SAVE
)
1528 // user confirmed alien filter or "good" filter is used
1536 bDialogUsed
= sal_True
;
1537 aFileNameIter
= aModelData
.GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) );
1541 // the target file name is provided so check if new filter options
1542 // are provided or old options can be used
1543 if ( aFilterFromMediaDescr
.equals( aOldFilterName
) )
1545 ::comphelper::SequenceAsHashMap::const_iterator aIter
=
1546 aModelData
.GetDocProps().find( sFilterOptionsString
);
1547 if ( aIter
!= aModelData
.GetDocProps().end()
1548 && aModelData
.GetMediaDescr().find( sFilterOptionsString
) == aModelData
.GetMediaDescr().end() )
1549 aModelData
.GetMediaDescr()[aIter
->first
] = aIter
->second
;
1551 aIter
= aModelData
.GetDocProps().find( sFilterDataString
);
1552 if ( aIter
!= aModelData
.GetDocProps().end()
1553 && aModelData
.GetMediaDescr().find( sFilterDataString
) == aModelData
.GetMediaDescr().end() )
1554 aModelData
.GetMediaDescr()[aIter
->first
] = aIter
->second
;
1558 if ( aFileNameIter
!= aModelData
.GetMediaDescr().end() )
1560 ::rtl::OUString aFileName
;
1561 aFileNameIter
->second
>>= aFileName
;
1562 aURL
.SetURL( aFileName
);
1563 DBG_ASSERT( aURL
.GetProtocol() != INET_PROT_NOT_VALID
, "Illegal URL!" );
1565 ::comphelper::SequenceAsHashMap::const_iterator aIter
=
1566 aModelData
.GetMediaDescr().find( sFilterNameString
);
1568 if ( aIter
!= aModelData
.GetMediaDescr().end() )
1569 aIter
->second
>>= aFilterName
;
1571 aModelData
.GetMediaDescr()[sFilterNameString
] <<= aFilterName
;
1573 DBG_ASSERT( !aFilterName
.isEmpty(), "Illegal filter!" );
1577 DBG_ASSERT( sal_False
, "This code must be unreachable!\n" );
1578 throw task::ErrorCodeIOException( ::rtl::OUString(),
1579 uno::Reference
< uno::XInterface
>(),
1580 ERRCODE_IO_INVALIDPARAMETER
);
1583 ::comphelper::SequenceAsHashMap::const_iterator aIter
=
1584 aModelData
.GetMediaDescr().find( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FilterFlags")) );
1585 sal_Bool bFilterFlagsSet
= ( aIter
!= aModelData
.GetMediaDescr().end() );
1587 if( !( nStoreMode
& PDFEXPORT_REQUESTED
) && !bFilterFlagsSet
1588 && ( ( nStoreMode
& EXPORT_REQUESTED
) || bUseFilterOptions
) )
1590 // execute filter options dialog
1591 if ( aModelData
.ExecuteFilterDialog_Impl( aFilterName
) )
1592 bDialogUsed
= sal_True
;
1595 // so the arguments will not change any more and can be stored to the main location
1596 aArgsSequence
= aModelData
.GetMediaDescr().getAsConstPropertyValueList();
1598 // store the document and handle it's docinfo
1599 SvtSaveOptions aOptions
;
1601 DocumentSettingsGuard
aSettingsGuard( aModelData
.GetModel(), aModelData
.IsRecommendReadOnly(), nStoreMode
& EXPORT_REQUESTED
);
1603 OSL_ENSURE( aModelData
.GetMediaDescr().find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ) ) == aModelData
.GetMediaDescr().end(), "The Password property of MediaDescriptor should not be used here!" );
1604 if ( aOptions
.IsDocInfoSave()
1605 && ( !aModelData
.GetStorable()->hasLocation()
1606 || INetURLObject( aModelData
.GetStorable()->getLocation() ) != aURL
) )
1608 // this is defenitly not a Save operation
1609 // so the document info can be updated
1611 // on export document info must be preserved
1612 uno::Reference
<document::XDocumentInfoSupplier
> xDIS(
1613 aModelData
.GetModel(), uno::UNO_QUERY_THROW
);
1614 uno::Reference
<util::XCloneable
> xCloneable(
1615 xDIS
->getDocumentInfo(), uno::UNO_QUERY_THROW
);
1616 uno::Reference
<document::XDocumentInfo
> xOldDocInfo(
1617 xCloneable
->createClone(), uno::UNO_QUERY_THROW
);
1619 // use dispatch API to show document info dialog
1620 if ( aModelData
.ShowDocumentInfoDialog() )
1621 bDialogUsed
= sal_True
;
1624 OSL_FAIL( "Can't execute document info dialog!\n" );
1628 // Document properties can contain streams that should be freed before storing
1629 aModelData
.FreeDocumentProps();
1630 if ( ( nStoreMode
& EXPORT_REQUESTED
) )
1631 aModelData
.GetStorable()->storeToURL( aURL
.GetMainURL( INetURLObject::NO_DECODE
), aArgsSequence
);
1633 aModelData
.GetStorable()->storeAsURL( aURL
.GetMainURL( INetURLObject::NO_DECODE
), aArgsSequence
);
1635 catch( const uno::Exception
& )
1637 if ( ( nStoreMode
& EXPORT_REQUESTED
) )
1638 SetDocInfoState( aModelData
.GetModel(), xOldDocInfo
, sal_True
);
1643 if ( ( nStoreMode
& EXPORT_REQUESTED
) )
1644 SetDocInfoState( aModelData
.GetModel(), xOldDocInfo
, sal_True
);
1648 // Document properties can contain streams that should be freed before storing
1649 aModelData
.FreeDocumentProps();
1651 // this is actually a save operation with different parameters
1652 // so storeTo or storeAs without DocInfo operations are used
1653 if ( ( nStoreMode
& EXPORT_REQUESTED
) )
1654 aModelData
.GetStorable()->storeToURL( aURL
.GetMainURL( INetURLObject::NO_DECODE
), aArgsSequence
);
1656 aModelData
.GetStorable()->storeAsURL( aURL
.GetMainURL( INetURLObject::NO_DECODE
), aArgsSequence
);
1662 //-------------------------------------------------------------------------
1664 sal_Bool
SfxStoringHelper::CheckFilterOptionsAppearence(
1665 const uno::Reference
< container::XNameAccess
>& xFilterCFG
,
1666 const ::rtl::OUString
& aFilterName
)
1668 sal_Bool bUseFilterOptions
= sal_False
;
1670 DBG_ASSERT( xFilterCFG
.is(), "No filter configuration!\n" );
1671 if( xFilterCFG
.is() )
1674 uno::Sequence
< beans::PropertyValue
> aProps
;
1675 uno::Any aAny
= xFilterCFG
->getByName( aFilterName
);
1676 if ( aAny
>>= aProps
)
1678 ::comphelper::SequenceAsHashMap
aPropsHM( aProps
);
1679 ::rtl::OUString aServiceName
= aPropsHM
.getUnpackedValueOrDefault(
1680 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UIComponent")),
1681 ::rtl::OUString() );
1682 if( !aServiceName
.isEmpty() )
1683 bUseFilterOptions
= sal_True
;
1686 catch( const uno::Exception
& )
1691 return bUseFilterOptions
;
1694 //-------------------------------------------------------------------------
1696 void SfxStoringHelper::SetDocInfoState(
1697 const uno::Reference
< frame::XModel
>& xModel
,
1698 const uno::Reference
< document::XDocumentInfo
>& i_xOldDocInfo
,
1699 sal_Bool bNoModify
)
1701 uno::Reference
< document::XDocumentInfoSupplier
> xModelDocInfoSupplier( xModel
, uno::UNO_QUERY
);
1702 if ( !xModelDocInfoSupplier
.is() )
1703 throw uno::RuntimeException(); // TODO:
1705 uno::Reference
< document::XDocumentInfo
> xDocInfoToFill
= xModelDocInfoSupplier
->getDocumentInfo();
1706 uno::Reference
< beans::XPropertySet
> xPropSet( i_xOldDocInfo
,
1707 uno::UNO_QUERY_THROW
);
1709 uno::Reference
< util::XModifiable
> xModifiable( xModel
, uno::UNO_QUERY
);
1710 if ( bNoModify
&& !xModifiable
.is() )
1711 throw uno::RuntimeException();
1713 sal_Bool bIsModified
= bNoModify
&& xModifiable
->isModified();
1717 uno::Reference
< beans::XPropertySet
> xSet( xDocInfoToFill
, uno::UNO_QUERY
);
1718 uno::Reference
< beans::XPropertyContainer
> xContainer( xSet
, uno::UNO_QUERY
);
1719 uno::Reference
< beans::XPropertySetInfo
> xSetInfo
= xSet
->getPropertySetInfo();
1720 uno::Sequence
< beans::Property
> lProps
= xSetInfo
->getProperties();
1721 const beans::Property
* pProps
= lProps
.getConstArray();
1722 sal_Int32 c
= lProps
.getLength();
1726 uno::Any aValue
= xPropSet
->getPropertyValue( pProps
[i
].Name
);
1727 if ( pProps
[i
].Attributes
& ::com::sun::star::beans::PropertyAttribute::REMOVABLE
)
1728 // QUESTION: DefaultValue?!
1729 xContainer
->addProperty( pProps
[i
].Name
, pProps
[i
].Attributes
, aValue
);
1732 // it is possible that the propertysets from XML and binary files differ; we shouldn't break then
1733 xSet
->setPropertyValue( pProps
[i
].Name
, aValue
);
1735 catch ( const uno::Exception
& ) {}
1738 sal_Int16 nCount
= i_xOldDocInfo
->getUserFieldCount();
1739 sal_Int16 nSupportedCount
= xDocInfoToFill
->getUserFieldCount();
1740 for ( sal_Int16 nInd
= 0; nInd
< nCount
&& nInd
< nSupportedCount
; nInd
++ )
1742 ::rtl::OUString aPropName
= i_xOldDocInfo
->getUserFieldName( nInd
);
1743 xDocInfoToFill
->setUserFieldName( nInd
, aPropName
);
1744 ::rtl::OUString aPropVal
= i_xOldDocInfo
->getUserFieldValue( nInd
);
1745 xDocInfoToFill
->setUserFieldValue( nInd
, aPropVal
);
1748 catch ( const uno::Exception
& ) {}
1750 // set the modified flag back if required
1751 if ( bNoModify
&& bIsModified
!= xModifiable
->isModified() )
1752 xModifiable
->setModified( bIsModified
);
1755 //-------------------------------------------------------------------------
1757 sal_Bool
SfxStoringHelper::WarnUnacceptableFormat( const uno::Reference
< frame::XModel
>& xModel
,
1758 ::rtl::OUString aOldUIName
,
1759 ::rtl::OUString
/*aDefUIName*/,
1760 sal_Bool
/*bCanProceedFurther*/ )
1762 if ( !SvtSaveOptions().IsWarnAlienFormat() )
1765 Window
* pWin
= SfxStoringHelper::GetModelWindow( xModel
);
1766 SfxAlienWarningDialog
aDlg( pWin
, aOldUIName
);
1768 return aDlg
.Execute() == RET_OK
;
1771 Window
* SfxStoringHelper::GetModelWindow( const uno::Reference
< frame::XModel
>& xModel
)
1777 uno::Reference
< frame::XController
> xController
= xModel
->getCurrentController();
1778 if ( xController
.is() )
1780 uno::Reference
< frame::XFrame
> xFrame
= xController
->getFrame();
1783 uno::Reference
< awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
1786 VCLXWindow
* pVCLWindow
= VCLXWindow::GetImplementation( xWindow
);
1788 pWin
= pVCLWindow
->GetWindow();
1794 catch ( const uno::Exception
& )
1801 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */