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