Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / dialog / filedlghelper.cxx
blobfe35177e86b274eeb30d90a4a8eab52be4ce181d
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 <sfx2/filedlghelper.hxx>
30 #include <sal/types.h>
31 #include <com/sun/star/lang/XInitialization.hpp>
32 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
33 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
34 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
35 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
36 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
37 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
38 #include <com/sun/star/ui/dialogs/XControlInformation.hpp>
39 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
40 #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
41 #include <com/sun/star/ui/dialogs/XFilePreview.hpp>
42 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
43 #include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
44 #include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
45 #include <com/sun/star/ui/dialogs/XFilePicker2.hpp>
46 #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
47 #include <com/sun/star/lang/XServiceInfo.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 #include <com/sun/star/beans/NamedValue.hpp>
50 #include <com/sun/star/embed/ElementModes.hpp>
51 #include <com/sun/star/container/XEnumeration.hpp>
52 #include <com/sun/star/container/XContainerQuery.hpp>
53 #include <com/sun/star/task/XInteractionRequest.hpp>
54 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
56 #include <comphelper/processfactory.hxx>
57 #include <comphelper/sequenceashashmap.hxx>
58 #include <comphelper/stillreadwriteinteraction.hxx>
59 #include <comphelper/string.hxx>
60 #include <comphelper/types.hxx>
61 #include <tools/urlobj.hxx>
62 #include <vcl/help.hxx>
63 #include <unotools/ucbstreamhelper.hxx>
64 #include <unotools/ucbhelper.hxx>
65 #include <unotools/localfilehelper.hxx>
66 #include <osl/file.hxx>
67 #include <osl/mutex.hxx>
68 #include <osl/security.hxx>
69 #include <osl/thread.hxx>
70 #include <vcl/cvtgrf.hxx>
71 #include <vcl/msgbox.hxx>
72 #include <vcl/mnemonic.hxx>
73 #include <unotools/pathoptions.hxx>
74 #include <unotools/securityoptions.hxx>
75 #include <svl/itemset.hxx>
76 #include <svl/eitem.hxx>
77 #include <svl/intitem.hxx>
78 #include <svl/stritem.hxx>
79 #include <svtools/filter.hxx>
80 #include <unotools/viewoptions.hxx>
81 #include <unotools/moduleoptions.hxx>
82 #include <svtools/helpid.hrc>
83 #include <comphelper/docpasswordrequest.hxx>
84 #include <comphelper/docpasswordhelper.hxx>
85 #include <ucbhelper/content.hxx>
86 #include <ucbhelper/commandenvironment.hxx>
87 #include <comphelper/storagehelper.hxx>
88 #include <toolkit/helper/vclunohelper.hxx>
89 #include <sfx2/app.hxx>
90 #include <sfx2/frame.hxx>
91 #include <sfx2/docfile.hxx>
92 #include <sfx2/docfac.hxx>
93 #include "openflag.hxx"
94 #include <sfx2/passwd.hxx>
95 #include "sfx2/sfxresid.hxx"
96 #include <sfx2/sfxsids.hrc>
97 #include "filedlghelper.hrc"
98 #include "filtergrouping.hxx"
99 #include <sfx2/request.hxx>
100 #include "filedlgimpl.hxx"
101 #include <helpid.hrc>
102 #include <sfxlocal.hrc>
103 #include <rtl/oustringostreaminserter.hxx>
104 #include <rtl/strbuf.hxx>
106 #ifdef UNX
107 #include <errno.h>
108 #include <sys/stat.h>
109 #endif
111 //-----------------------------------------------------------------------------
113 using namespace ::com::sun::star;
114 using namespace ::com::sun::star::container;
115 using namespace ::com::sun::star::lang;
116 using namespace ::com::sun::star::ui::dialogs;
117 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
118 using namespace ::com::sun::star::uno;
119 using namespace ::com::sun::star::beans;
120 using namespace ::rtl;
121 using namespace ::cppu;
123 //-----------------------------------------------------------------------------
125 #define IODLG_CONFIGNAME String(DEFINE_CONST_UNICODE("FilePicker_Save"))
126 #define IMPGRF_CONFIGNAME String(DEFINE_CONST_UNICODE("FilePicker_Graph"))
127 #define USERITEM_NAME ::rtl::OUString("UserItem" )
129 //-----------------------------------------------------------------------------
131 namespace sfx2
134 const OUString* GetLastFilterConfigId( FileDialogHelper::Context _eContext )
136 static const OUString aSD_EXPORT_IDENTIFIER( "SdExportLastFilter" );
137 static const OUString aSI_EXPORT_IDENTIFIER( "SiExportLastFilter" );
138 static const OUString aSW_EXPORT_IDENTIFIER( "SwExportLastFilter" );
140 const OUString* pRet = NULL;
142 switch( _eContext )
144 case FileDialogHelper::SD_EXPORT: pRet = &aSD_EXPORT_IDENTIFIER; break;
145 case FileDialogHelper::SI_EXPORT: pRet = &aSI_EXPORT_IDENTIFIER; break;
146 case FileDialogHelper::SW_EXPORT: pRet = &aSW_EXPORT_IDENTIFIER; break;
147 default: break;
150 return pRet;
153 String EncodeSpaces_Impl( const String& rSource );
154 String DecodeSpaces_Impl( const String& rSource );
156 // ------------------------------------------------------------------------
157 // ----------- FileDialogHelper_Impl ---------------------------
158 // ------------------------------------------------------------------------
160 // ------------------------------------------------------------------------
161 // XFilePickerListener Methods
162 // ------------------------------------------------------------------------
163 void SAL_CALL FileDialogHelper_Impl::fileSelectionChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
165 SolarMutexGuard aGuard;
166 mpAntiImpl->FileSelectionChanged( aEvent );
169 // ------------------------------------------------------------------------
170 void SAL_CALL FileDialogHelper_Impl::directoryChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
172 SolarMutexGuard aGuard;
173 mpAntiImpl->DirectoryChanged( aEvent );
176 // ------------------------------------------------------------------------
177 OUString SAL_CALL FileDialogHelper_Impl::helpRequested( const FilePickerEvent& aEvent ) throw ( RuntimeException )
179 SolarMutexGuard aGuard;
180 return mpAntiImpl->HelpRequested( aEvent );
183 // ------------------------------------------------------------------------
184 void SAL_CALL FileDialogHelper_Impl::controlStateChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
186 SolarMutexGuard aGuard;
187 mpAntiImpl->ControlStateChanged( aEvent );
190 // ------------------------------------------------------------------------
191 void SAL_CALL FileDialogHelper_Impl::dialogSizeChanged() throw ( RuntimeException )
193 SolarMutexGuard aGuard;
194 mpAntiImpl->DialogSizeChanged();
197 // ------------------------------------------------------------------------
198 // XDialogClosedListener Methods
199 // ------------------------------------------------------------------------
200 void SAL_CALL FileDialogHelper_Impl::dialogClosed( const DialogClosedEvent& _rEvent ) throw ( RuntimeException )
202 SolarMutexGuard aGuard;
203 mpAntiImpl->DialogClosed( _rEvent );
204 postExecute( _rEvent.DialogResult );
207 // ------------------------------------------------------------------------
208 // handle XFilePickerListener events
209 // ------------------------------------------------------------------------
210 void FileDialogHelper_Impl::handleFileSelectionChanged( const FilePickerEvent& )
212 if ( mbHasVersions )
213 updateVersions();
215 if ( mbShowPreview )
216 maPreViewTimer.Start();
219 // ------------------------------------------------------------------------
220 void FileDialogHelper_Impl::handleDirectoryChanged( const FilePickerEvent& )
222 if ( mbShowPreview )
223 TimeOutHdl_Impl( NULL );
226 // ------------------------------------------------------------------------
227 OUString FileDialogHelper_Impl::handleHelpRequested( const FilePickerEvent& aEvent )
229 //!!! todo: cache the help strings (here or TRA)
231 rtl::OString sHelpId;
232 // mapping from element id -> help id
233 switch ( aEvent.ElementId )
235 case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
236 sHelpId = HID_FILESAVE_AUTOEXTENSION;
237 break;
239 case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
240 sHelpId = HID_FILESAVE_SAVEWITHPASSWORD;
241 break;
243 case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
244 sHelpId = HID_FILESAVE_CUSTOMIZEFILTER;
245 break;
247 case ExtendedFilePickerElementIds::CHECKBOX_READONLY :
248 sHelpId = HID_FILEOPEN_READONLY;
249 break;
251 case ExtendedFilePickerElementIds::CHECKBOX_LINK :
252 sHelpId = HID_FILEDLG_LINK_CB;
253 break;
255 case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW :
256 sHelpId = HID_FILEDLG_PREVIEW_CB;
257 break;
259 case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
260 sHelpId = HID_FILESAVE_DOPLAY;
261 break;
263 case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL :
264 case ExtendedFilePickerElementIds::LISTBOX_VERSION :
265 sHelpId = HID_FILEOPEN_VERSION;
266 break;
268 case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL :
269 case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
270 sHelpId = HID_FILESAVE_TEMPLATE;
271 break;
273 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL :
274 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
275 sHelpId = HID_FILEOPEN_IMAGE_TEMPLATE;
276 break;
278 case ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
279 sHelpId = HID_FILESAVE_SELECTION;
280 break;
282 default:
283 SAL_WARN( "sfx2.dialog", "invalid element id" );
286 OUString aHelpText;
287 Help* pHelp = Application::GetHelp();
288 if ( pHelp )
289 aHelpText = String( pHelp->GetHelpText( rtl::OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), NULL ) );
290 return aHelpText;
293 // ------------------------------------------------------------------------
294 void FileDialogHelper_Impl::handleControlStateChanged( const FilePickerEvent& aEvent )
296 switch ( aEvent.ElementId )
298 case CommonFilePickerElementIds::LISTBOX_FILTER:
299 updateFilterOptionsBox();
300 enablePasswordBox( sal_False );
301 updateSelectionBox();
302 // only use it for export and with our own dialog
303 if ( mbExport && !mbSystemPicker )
304 updateExportButton();
305 break;
307 case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
308 updatePreviewState();
309 break;
313 // ------------------------------------------------------------------------
314 void FileDialogHelper_Impl::handleDialogSizeChanged()
316 if ( mbShowPreview )
317 TimeOutHdl_Impl( NULL );
320 // ------------------------------------------------------------------------
321 // XEventListener Methods
322 // ------------------------------------------------------------------------
323 void SAL_CALL FileDialogHelper_Impl::disposing( const EventObject& ) throw ( RuntimeException )
325 SolarMutexGuard aGuard;
326 dispose();
329 // ------------------------------------------------------------------------
331 void FileDialogHelper_Impl::dispose()
333 if ( mxFileDlg.is() )
335 // remove the event listener
336 uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
337 if ( xNotifier.is() )
338 xNotifier->removeFilePickerListener( this );
340 ::comphelper::disposeComponent( mxFileDlg );
341 mxFileDlg.clear();
345 // ------------------------------------------------------------------------
346 String FileDialogHelper_Impl::getCurrentFilterUIName() const
348 String aFilterName;
349 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
351 if( xFltMgr.is() )
353 aFilterName = xFltMgr->getCurrentFilter();
355 if ( aFilterName.Len() && isShowFilterExtensionEnabled() )
356 aFilterName = getFilterName( aFilterName );
359 return aFilterName;
362 // ------------------------------------------------------------------------
363 void FileDialogHelper_Impl::LoadLastUsedFilter( const OUString& _rContextIdentifier )
365 SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
367 if( aDlgOpt.Exists() )
369 OUString aLastFilter;
370 if( aDlgOpt.GetUserItem( _rContextIdentifier ) >>= aLastFilter )
371 setFilter( aLastFilter );
375 // ------------------------------------------------------------------------
376 void FileDialogHelper_Impl::SaveLastUsedFilter( const OUString& _rContextIdentifier )
378 SvtViewOptions( E_DIALOG, IODLG_CONFIGNAME ).SetUserItem( _rContextIdentifier,
379 makeAny( getFilterWithExtension( getFilter() ) ) );
382 // ------------------------------------------------------------------------
383 void FileDialogHelper_Impl::SaveLastUsedFilter( void )
385 const OUString* pConfigId = GetLastFilterConfigId( meContext );
386 if( pConfigId )
387 SaveLastUsedFilter( *pConfigId );
390 // ------------------------------------------------------------------------
391 const SfxFilter* FileDialogHelper_Impl::getCurentSfxFilter()
393 String aFilterName = getCurrentFilterUIName();
395 const SfxFilter* pFilter = NULL;
396 if ( mpMatcher && aFilterName.Len() )
397 pFilter = mpMatcher->GetFilter4UIName( aFilterName, m_nMustFlags, m_nDontFlags );
399 return pFilter;
402 // ------------------------------------------------------------------------
403 sal_Bool FileDialogHelper_Impl::updateExtendedControl( sal_Int16 _nExtendedControlId, sal_Bool _bEnable )
405 sal_Bool bIsEnabled = sal_False;
407 uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
408 if ( xCtrlAccess.is() )
412 xCtrlAccess->enableControl( _nExtendedControlId, _bEnable );
413 bIsEnabled = _bEnable;
415 catch( const IllegalArgumentException& )
417 OSL_FAIL( "FileDialogHelper_Impl::updateExtendedControl: caught an exception!" );
420 return bIsEnabled;
423 // ------------------------------------------------------------------------
424 sal_Bool FileDialogHelper_Impl::CheckFilterOptionsCapability( const SfxFilter* _pFilter )
426 sal_Bool bResult = sal_False;
428 if( mxFilterCFG.is() && _pFilter )
430 try {
431 Sequence < PropertyValue > aProps;
432 Any aAny = mxFilterCFG->getByName( _pFilter->GetName() );
433 if ( aAny >>= aProps )
435 ::rtl::OUString aServiceName;
436 sal_Int32 nPropertyCount = aProps.getLength();
437 for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
439 if( aProps[nProperty].Name.equals( DEFINE_CONST_OUSTRING( "UIComponent") ) )
441 aProps[nProperty].Value >>= aServiceName;
442 if( !aServiceName.isEmpty() )
443 bResult = sal_True;
448 catch( const Exception& )
453 return bResult;
456 // ------------------------------------------------------------------------
457 sal_Bool FileDialogHelper_Impl::isInOpenMode() const
459 sal_Bool bRet = sal_False;
461 switch ( m_nDialogType )
463 case FILEOPEN_SIMPLE:
464 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
465 case FILEOPEN_PLAY:
466 case FILEOPEN_READONLY_VERSION:
467 case FILEOPEN_LINK_PREVIEW:
468 bRet = sal_True;
471 return bRet;
474 // ------------------------------------------------------------------------
476 void FileDialogHelper_Impl::updateFilterOptionsBox()
478 if ( !m_bHaveFilterOptions )
479 return;
481 updateExtendedControl(
482 ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS,
483 CheckFilterOptionsCapability( getCurentSfxFilter() )
487 // ------------------------------------------------------------------------
489 void FileDialogHelper_Impl::updateExportButton()
491 uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
492 if ( xCtrlAccess.is() )
494 OUString sEllipses( "..." );
495 OUString sOldLabel( xCtrlAccess->getLabel( CommonFilePickerElementIds::PUSHBUTTON_OK ) );
497 // initialize button label; we need the label with the mnemonic char
498 if ( maButtonLabel.isEmpty() || maButtonLabel.indexOf( MNEMONIC_CHAR ) == -1 )
500 // cut the ellipses, if necessary
501 sal_Int32 nIndex = sOldLabel.indexOf( sEllipses );
502 if ( -1 == nIndex )
503 nIndex = sOldLabel.getLength();
504 maButtonLabel = sOldLabel.copy( 0, nIndex );
507 OUString sLabel = maButtonLabel;
508 // filter with options -> append ellipses on export button label
509 if ( CheckFilterOptionsCapability( getCurentSfxFilter() ) )
510 sLabel += OUString( "..." );
512 if ( sOldLabel != sLabel )
516 xCtrlAccess->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK, sLabel );
518 catch( const IllegalArgumentException& )
520 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::updateExportButton: caught an exception!" );
526 // ------------------------------------------------------------------------
527 void FileDialogHelper_Impl::updateSelectionBox()
529 if ( !mbHasSelectionBox )
530 return;
532 // Does the selection box exist?
533 sal_Bool bSelectionBoxFound = sal_False;
534 uno::Reference< XControlInformation > xCtrlInfo( mxFileDlg, UNO_QUERY );
535 if ( xCtrlInfo.is() )
537 Sequence< ::rtl::OUString > aCtrlList = xCtrlInfo->getSupportedControls();
538 sal_uInt32 nCount = aCtrlList.getLength();
539 for ( sal_uInt32 nCtrl = 0; nCtrl < nCount; ++nCtrl )
540 if ( aCtrlList[ nCtrl ] == "SelectionBox" )
542 bSelectionBoxFound = sal_False;
543 break;
547 if ( bSelectionBoxFound )
549 const SfxFilter* pFilter = getCurentSfxFilter();
550 mbSelectionFltrEnabled = updateExtendedControl(
551 ExtendedFilePickerElementIds::CHECKBOX_SELECTION,
552 ( mbSelectionEnabled && pFilter && ( pFilter->GetFilterFlags() & SFX_FILTER_SUPPORTSSELECTION ) != 0 ) );
553 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
554 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, makeAny( (sal_Bool)mbSelection ) );
558 // ------------------------------------------------------------------------
559 void FileDialogHelper_Impl::enablePasswordBox( sal_Bool bInit )
561 if ( ! mbHasPassword )
562 return;
564 sal_Bool bWasEnabled = mbIsPwdEnabled;
566 const SfxFilter* pCurrentFilter = getCurentSfxFilter();
567 mbIsPwdEnabled = updateExtendedControl(
568 ExtendedFilePickerElementIds::CHECKBOX_PASSWORD,
569 pCurrentFilter && ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_ENCRYPTION )
572 if( bInit )
574 // in case of inintialization previous state is not interesting
575 if( mbIsPwdEnabled )
577 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
578 if( mbPwdCheckBoxState )
579 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
582 else if( !bWasEnabled && mbIsPwdEnabled )
584 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
585 if( mbPwdCheckBoxState )
586 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
588 else if( bWasEnabled && !mbIsPwdEnabled )
590 // remember user settings until checkbox is enabled
591 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
592 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
593 sal_Bool bPassWord = sal_False;
594 mbPwdCheckBoxState = ( aValue >>= bPassWord ) && bPassWord;
595 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_False ) );
599 // ------------------------------------------------------------------------
600 void FileDialogHelper_Impl::updatePreviewState( sal_Bool _bUpdatePreviewWindow )
602 if ( mbHasPreview )
604 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
606 // check, whether or not we have to display a preview
607 if ( xCtrlAccess.is() )
611 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
612 sal_Bool bShowPreview = sal_False;
614 if ( aValue >>= bShowPreview )
616 mbShowPreview = bShowPreview;
618 // setShowState has currently no effect for the
619 // OpenOffice FilePicker (see svtools/source/filepicker/iodlg.cxx)
620 uno::Reference< XFilePreview > xFilePreview( mxFileDlg, UNO_QUERY );
621 if ( xFilePreview.is() )
622 xFilePreview->setShowState( mbShowPreview );
624 if ( _bUpdatePreviewWindow )
625 TimeOutHdl_Impl( NULL );
628 catch( const Exception& )
630 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::updatePreviewState: caught an exception!" );
636 // ------------------------------------------------------------------------
637 void FileDialogHelper_Impl::updateVersions()
639 Sequence < OUString > aEntries;
640 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
642 if ( aPathSeq.getLength() == 1 )
644 INetURLObject aObj( aPathSeq[0] );
646 if ( ( aObj.GetProtocol() == INET_PROT_FILE ) &&
647 ( utl::UCBContentHelper::IsDocument( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) )
651 uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
652 aObj.GetMainURL( INetURLObject::NO_DECODE ),
653 embed::ElementModes::READ );
655 DBG_ASSERT( xStorage.is(), "The method must return the storage or throw an exception!" );
656 if ( !xStorage.is() )
657 throw uno::RuntimeException();
659 uno::Sequence < util::RevisionTag > xVersions = SfxMedium::GetVersionList( xStorage );
661 aEntries.realloc( xVersions.getLength() + 1 );
662 aEntries[0] = OUString( String ( SfxResId( STR_SFX_FILEDLG_ACTUALVERSION ) ) );
664 for ( sal_Int32 i=0; i<xVersions.getLength(); i++ )
665 aEntries[ i + 1 ] = xVersions[i].Identifier;
667 catch( const uno::Exception& )
673 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
674 Any aValue;
678 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
679 ControlActions::DELETE_ITEMS, aValue );
681 catch( const IllegalArgumentException& ){}
683 sal_Int32 nCount = aEntries.getLength();
685 if ( nCount )
689 aValue <<= aEntries;
690 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
691 ControlActions::ADD_ITEMS, aValue );
693 Any aPos;
694 aPos <<= (sal_Int32) 0;
695 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
696 ControlActions::SET_SELECT_ITEM, aPos );
698 catch( const IllegalArgumentException& ){}
702 // -----------------------------------------------------------------------
703 IMPL_LINK_NOARG(FileDialogHelper_Impl, TimeOutHdl_Impl)
705 if ( !mbHasPreview )
706 return 0;
708 maGraphic.Clear();
710 Any aAny;
711 uno::Reference < XFilePreview > xFilePicker( mxFileDlg, UNO_QUERY );
713 if ( ! xFilePicker.is() )
714 return 0;
716 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
718 if ( mbShowPreview && ( aPathSeq.getLength() == 1 ) )
720 OUString aURL = aPathSeq[0];
722 if ( ERRCODE_NONE == getGraphic( aURL, maGraphic ) )
724 // changed the code slightly;
725 // before: the bitmap was scaled and
726 // surrounded a white frame
727 // now: the bitmap will only be scaled
728 // and the filepicker implementation
729 // is responsible for placing it at its
730 // proper position and painting a frame
732 Bitmap aBmp = maGraphic.GetBitmap();
734 // scale the bitmap to the correct size
735 sal_Int32 nOutWidth = xFilePicker->getAvailableWidth();
736 sal_Int32 nOutHeight = xFilePicker->getAvailableHeight();
737 sal_Int32 nBmpWidth = aBmp.GetSizePixel().Width();
738 sal_Int32 nBmpHeight = aBmp.GetSizePixel().Height();
740 double nXRatio = (double) nOutWidth / nBmpWidth;
741 double nYRatio = (double) nOutHeight / nBmpHeight;
743 if ( nXRatio < nYRatio )
744 aBmp.Scale( nXRatio, nXRatio );
745 else
746 aBmp.Scale( nYRatio, nYRatio );
748 // Convert to true color, to allow CopyPixel
749 aBmp.Convert( BMP_CONVERSION_24BIT );
751 // and copy it into the Any
752 SvMemoryStream aData;
754 aData << aBmp;
756 const Sequence < sal_Int8 > aBuffer(
757 static_cast< const sal_Int8* >(aData.GetData()),
758 aData.GetEndOfData() );
760 aAny <<= aBuffer;
766 SolarMutexReleaser aReleaseForCallback;
767 // clear the preview window
768 xFilePicker->setImage( FilePreviewImageFormats::BITMAP, aAny );
770 catch( const IllegalArgumentException& )
774 return 0;
777 // ------------------------------------------------------------------------
778 ErrCode FileDialogHelper_Impl::getGraphic( const OUString& rURL,
779 Graphic& rGraphic ) const
781 if ( utl::UCBContentHelper::IsFolder( rURL ) )
782 return ERRCODE_IO_NOTAFILE;
784 if ( !mpGraphicFilter )
785 return ERRCODE_IO_NOTSUPPORTED;
787 // select graphic filter from dialog filter selection
788 OUString aCurFilter( getFilter() );
790 sal_uInt16 nFilter = !aCurFilter.isEmpty() && mpGraphicFilter->GetImportFormatCount()
791 ? mpGraphicFilter->GetImportFormatNumber( aCurFilter )
792 : GRFILTER_FORMAT_DONTKNOW;
794 INetURLObject aURLObj( rURL );
796 if ( aURLObj.HasError() || INET_PROT_NOT_VALID == aURLObj.GetProtocol() )
798 aURLObj.SetSmartProtocol( INET_PROT_FILE );
799 aURLObj.SetSmartURL( rURL );
802 ErrCode nRet = ERRCODE_NONE;
804 sal_uInt32 nFilterImportFlags = GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
805 // non-local?
806 if ( INET_PROT_FILE != aURLObj.GetProtocol() )
808 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( rURL, STREAM_READ );
810 if( pStream )
811 nRet = mpGraphicFilter->ImportGraphic( rGraphic, rURL, *pStream, nFilter, NULL, nFilterImportFlags );
812 else
813 nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
814 delete pStream;
816 else
818 nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
821 return nRet;
824 // ------------------------------------------------------------------------
825 ErrCode FileDialogHelper_Impl::getGraphic( Graphic& rGraphic ) const
827 ErrCode nRet = ERRCODE_NONE;
829 if ( ! maGraphic )
831 OUString aPath;;
832 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
834 if ( aPathSeq.getLength() == 1 )
836 aPath = aPathSeq[0];
839 if ( !aPath.isEmpty() )
840 nRet = getGraphic( aPath, rGraphic );
841 else
842 nRet = ERRCODE_IO_GENERAL;
844 else
845 rGraphic = maGraphic;
847 return nRet;
850 // ------------------------------------------------------------------------
851 static bool lcl_isSystemFilePicker( const uno::Reference< XFilePicker >& _rxFP )
855 uno::Reference< XServiceInfo > xSI( _rxFP, UNO_QUERY );
856 if ( !xSI.is() )
857 return true;
858 return xSI->supportsService( DEFINE_CONST_OUSTRING( "com.sun.star.ui.dialogs.SystemFilePicker" ) );
860 catch( const Exception& )
863 return false;
866 enum open_or_save_t {OPEN, SAVE, UNDEFINED};
867 static open_or_save_t lcl_OpenOrSave(sal_Int16 const nDialogType)
869 switch (nDialogType)
871 case FILEOPEN_SIMPLE:
872 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
873 case FILEOPEN_PLAY:
874 case FILEOPEN_READONLY_VERSION:
875 case FILEOPEN_LINK_PREVIEW:
876 return OPEN;
877 case FILESAVE_SIMPLE:
878 case FILESAVE_AUTOEXTENSION_PASSWORD:
879 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
880 case FILESAVE_AUTOEXTENSION_SELECTION:
881 case FILESAVE_AUTOEXTENSION_TEMPLATE:
882 case FILESAVE_AUTOEXTENSION:
883 return SAVE;
884 default:
885 assert(false); // invalid dialog type
887 return UNDEFINED;
890 // ------------------------------------------------------------------------
891 // ----------- FileDialogHelper_Impl ---------------------------
892 // ------------------------------------------------------------------------
894 FileDialogHelper_Impl::FileDialogHelper_Impl(
895 FileDialogHelper* _pAntiImpl,
896 sal_Int16 nDialogType,
897 sal_Int64 nFlags,
898 sal_Int16 nDialog,
899 Window* _pPreferredParentWindow,
900 const String& sStandardDir,
901 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList
903 :m_nDialogType ( nDialogType )
904 ,meContext ( FileDialogHelper::UNKNOWN_CONTEXT )
906 const char* pServiceName=0;
907 if ( nDialog == SFX2_IMPL_DIALOG_SYSTEM )
908 pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
909 else if ( nDialog == SFX2_IMPL_DIALOG_OOO )
910 pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
911 else
912 pServiceName = FILE_OPEN_SERVICE_NAME;
913 OUString aService = ::rtl::OUString::createFromAscii( pServiceName );
915 uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
917 // create the file open dialog
918 // the flags can be SFXWB_INSERT or SFXWB_MULTISELECTION
920 mpPreferredParentWindow = _pPreferredParentWindow;
921 mpAntiImpl = _pAntiImpl;
922 mnError = ERRCODE_NONE;
923 mbHasAutoExt = sal_False;
924 mbHasPassword = sal_False;
925 m_bHaveFilterOptions = sal_False;
926 mbIsPwdEnabled = sal_True;
927 mbHasVersions = sal_False;
928 mbHasPreview = sal_False;
929 mbShowPreview = sal_False;
930 mbAddGraphicFilter = SFXWB_GRAPHIC == (nFlags & SFXWB_GRAPHIC);
931 mbDeleteMatcher = sal_False;
932 mbInsert = SFXWB_INSERT == ( nFlags & SFXWB_INSERT );
933 mbExport = SFXWB_EXPORT == ( nFlags & SFXWB_EXPORT );
934 mbIsSaveDlg = sal_False;
935 mbPwdCheckBoxState = sal_False;
936 mbSelection = sal_False;
937 mbSelectionEnabled = sal_True;
938 mbHasSelectionBox = sal_False;
939 mbSelectionFltrEnabled = sal_False;
941 // default settings
942 m_nDontFlags = SFX_FILTER_INTERNAL | SFX_FILTER_NOTINFILEDLG | SFX_FILTER_NOTINSTALLED;
943 if (OPEN == lcl_OpenOrSave(m_nDialogType))
944 m_nMustFlags = SFX_FILTER_IMPORT;
945 else
946 m_nMustFlags = SFX_FILTER_EXPORT;
949 mpMatcher = NULL;
950 mpGraphicFilter = NULL;
951 mnPostUserEventId = 0;
953 // create the picker component
954 mxFileDlg = mxFileDlg.query( xFactory->createInstance( aService ) );
955 mbSystemPicker = lcl_isSystemFilePicker( mxFileDlg );
957 uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
958 uno::Reference< XInitialization > xInit( mxFileDlg, UNO_QUERY );
960 if ( ! mxFileDlg.is() || ! xNotifier.is() )
962 mnError = ERRCODE_ABORT;
963 return;
967 if ( xInit.is() )
969 sal_Int16 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
971 switch ( m_nDialogType )
973 case FILEOPEN_SIMPLE:
974 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
975 break;
977 case FILESAVE_SIMPLE:
978 nTemplateDescription = TemplateDescription::FILESAVE_SIMPLE;
979 mbIsSaveDlg = sal_True;
980 break;
982 case FILESAVE_AUTOEXTENSION_PASSWORD:
983 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD;
984 mbHasPassword = sal_True;
985 mbHasAutoExt = sal_True;
986 mbIsSaveDlg = sal_True;
987 break;
989 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
990 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS;
991 mbHasPassword = sal_True;
993 m_bHaveFilterOptions = sal_True;
994 if( xFactory.is() )
996 mxFilterCFG = uno::Reference< XNameAccess >(
997 xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.document.FilterFactory" ) ),
998 UNO_QUERY );
1001 mbHasAutoExt = sal_True;
1002 mbIsSaveDlg = sal_True;
1003 break;
1005 case FILESAVE_AUTOEXTENSION_SELECTION:
1006 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION;
1007 mbHasAutoExt = sal_True;
1008 mbIsSaveDlg = sal_True;
1009 mbHasSelectionBox = sal_True;
1010 if ( mbExport && !mxFilterCFG.is() && xFactory.is() )
1012 mxFilterCFG = uno::Reference< XNameAccess >(
1013 xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.document.FilterFactory" ) ),
1014 UNO_QUERY );
1016 break;
1018 case FILESAVE_AUTOEXTENSION_TEMPLATE:
1019 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE;
1020 mbHasAutoExt = sal_True;
1021 mbIsSaveDlg = sal_True;
1022 break;
1024 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
1025 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE;
1026 mbHasPreview = sal_True;
1028 // aPreviewTimer
1029 maPreViewTimer.SetTimeout( 500 );
1030 maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1031 break;
1033 case FILEOPEN_PLAY:
1034 nTemplateDescription = TemplateDescription::FILEOPEN_PLAY;
1035 break;
1037 case FILEOPEN_READONLY_VERSION:
1038 nTemplateDescription = TemplateDescription::FILEOPEN_READONLY_VERSION;
1039 mbHasVersions = sal_True;
1040 break;
1042 case FILEOPEN_LINK_PREVIEW:
1043 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW;
1044 mbHasPreview = sal_True;
1045 // aPreviewTimer
1046 maPreViewTimer.SetTimeout( 500 );
1047 maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1048 break;
1050 case FILESAVE_AUTOEXTENSION:
1051 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION;
1052 mbHasAutoExt = sal_True;
1053 mbIsSaveDlg = sal_True;
1054 break;
1056 default:
1057 SAL_WARN( "sfx2.dialog", "FileDialogHelper::ctor with unknown type" );
1058 break;
1061 Sequence < Any > aInitArguments( !mpPreferredParentWindow ? 3 : 4 );
1063 // This is a hack. We currently know that the internal file picker implementation
1064 // supports the extended arguments as specified below.
1065 // TODO:
1066 // a) adjust the service description so that it includes the TemplateDescription and ParentWindow args
1067 // b) adjust the implementation of the system file picker to that it recognizes it
1068 if ( mbSystemPicker )
1070 aInitArguments[0] <<= nTemplateDescription;
1072 else
1074 aInitArguments[0] <<= NamedValue(
1075 ::rtl::OUString( "TemplateDescription" ),
1076 makeAny( nTemplateDescription )
1079 ::rtl::OUString sStandardDirTemp = ::rtl::OUString( sStandardDir );
1081 aInitArguments[1] <<= NamedValue(
1082 ::rtl::OUString( "StandardDir" ),
1083 makeAny( sStandardDirTemp )
1086 aInitArguments[2] <<= NamedValue(
1087 ::rtl::OUString( "BlackList" ),
1088 makeAny( rBlackList )
1092 if ( mpPreferredParentWindow )
1093 aInitArguments[3] <<= NamedValue(
1094 ::rtl::OUString( "ParentWindow" ),
1095 makeAny( VCLUnoHelper::GetInterface( mpPreferredParentWindow ) )
1101 xInit->initialize( aInitArguments );
1103 catch( const Exception& )
1105 OSL_FAIL( "FileDialogHelper_Impl::FileDialogHelper_Impl: could not initialize the picker!" );
1110 // set multiselection mode
1111 if ( nFlags & SFXWB_MULTISELECTION )
1112 mxFileDlg->setMultiSelectionMode( sal_True );
1114 if (mbAddGraphicFilter) // generate graphic filter only on demand
1116 addGraphicFilter();
1119 // Export dialog
1120 if ( mbExport )
1122 mxFileDlg->setTitle( OUString( String( SfxResId( STR_SFX_EXPLORERFILE_EXPORT ) ) ) );
1123 try {
1124 com::sun::star::uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY_THROW );
1125 xCtrlAccess->enableControl( ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR, sal_True );
1127 catch( const Exception & ) { }
1130 // the "insert file" dialog needs another title
1131 if ( mbInsert )
1133 mxFileDlg->setTitle( OUString( String( SfxResId( STR_SFX_EXPLORERFILE_INSERT ) ) ) );
1134 uno::Reference < XFilePickerControlAccess > xExtDlg( mxFileDlg, UNO_QUERY );
1135 if ( xExtDlg.is() )
1139 xExtDlg->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK,
1140 OUString( String( SfxResId( STR_SFX_EXPLORERFILE_BUTTONINSERT ) ) ) );
1142 catch( const IllegalArgumentException& ){}
1146 // add the event listener
1147 xNotifier->addFilePickerListener( this );
1150 // ------------------------------------------------------------------------
1151 FileDialogHelper_Impl::~FileDialogHelper_Impl()
1153 // Remove user event if we haven't received it yet
1154 if ( mnPostUserEventId )
1155 Application::RemoveUserEvent( mnPostUserEventId );
1156 mnPostUserEventId = 0;
1158 delete mpGraphicFilter;
1160 if ( mbDeleteMatcher )
1161 delete mpMatcher;
1163 maPreViewTimer.SetTimeoutHdl( Link() );
1165 ::comphelper::disposeComponent( mxFileDlg );
1168 #define nMagic -1
1170 class PickerThread_Impl : public ::osl::Thread
1172 uno::Reference < XFilePicker > mxPicker;
1173 ::osl::Mutex maMutex;
1174 virtual void SAL_CALL run();
1175 sal_Int16 mnRet;
1176 public:
1177 PickerThread_Impl( const uno::Reference < XFilePicker >& rPicker )
1178 : mxPicker( rPicker ), mnRet(nMagic) {}
1180 sal_Int16 GetReturnValue()
1181 { ::osl::MutexGuard aGuard( maMutex ); return mnRet; }
1183 void SetReturnValue( sal_Int16 aRetValue )
1184 { ::osl::MutexGuard aGuard( maMutex ); mnRet = aRetValue; }
1187 void SAL_CALL PickerThread_Impl::run()
1191 sal_Int16 n = mxPicker->execute();
1192 SetReturnValue( n );
1194 catch( const RuntimeException& )
1196 SetReturnValue( ExecutableDialogResults::CANCEL );
1197 SAL_WARN( "sfx2.dialog", "RuntimeException caught" );
1201 // ------------------------------------------------------------------------
1202 void FileDialogHelper_Impl::setControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
1204 DBG_ASSERT( _pControlId && _pHelpId, "FileDialogHelper_Impl::setControlHelpIds: invalid array pointers!" );
1205 if ( !_pControlId || !_pHelpId )
1206 return;
1208 // forward these ids to the file picker
1211 const ::rtl::OUString sHelpIdPrefix( INET_HID_SCHEME );
1212 // the ids for the single controls
1213 uno::Reference< XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1214 if ( xControlAccess.is() )
1216 while ( *_pControlId )
1218 DBG_ASSERT( INetURLObject( rtl::OStringToOUString( *_pHelpId, RTL_TEXTENCODING_UTF8 ) ).GetProtocol() == INET_PROT_NOT_VALID, "Wrong HelpId!" );
1219 ::rtl::OUString sId( sHelpIdPrefix );
1220 sId += ::rtl::OUString( *_pHelpId, strlen( *_pHelpId ), RTL_TEXTENCODING_UTF8 );
1221 xControlAccess->setValue( *_pControlId, ControlActions::SET_HELP_URL, makeAny( sId ) );
1223 ++_pControlId; ++_pHelpId;
1227 catch( const Exception& )
1229 OSL_FAIL( "FileDialogHelper_Impl::setControlHelpIds: caught an exception while setting the help ids!" );
1233 // ------------------------------------------------------------------------
1234 IMPL_LINK( FileDialogHelper_Impl, InitControls, void*, NOTINTERESTEDIN )
1236 (void)NOTINTERESTEDIN;
1237 mnPostUserEventId = 0;
1238 enablePasswordBox( sal_True );
1239 updateFilterOptionsBox( );
1240 updateSelectionBox( );
1242 return 0L;
1245 // ------------------------------------------------------------------------
1246 void FileDialogHelper_Impl::preExecute()
1248 loadConfig( );
1249 setDefaultValues( );
1250 updatePreviewState( sal_False );
1252 implInitializeFileName( );
1254 #if !(defined(MACOSX) && defined(QUARTZ)) && !defined(WNT)
1255 // allow for dialog implementations which need to be executed before they return valid values for
1256 // current filter and such
1258 // On Vista (at least SP1) it's the same as on MacOSX, the modal dialog won't let message pass
1259 // through before it returns from execution
1260 mnPostUserEventId = Application::PostUserEvent( LINK( this, FileDialogHelper_Impl, InitControls ) );
1261 #else
1262 // However, the Mac OS X implementation's pickers run modally in execute and so the event doesn't
1263 // get through in time... so we call the methods directly
1264 enablePasswordBox( sal_True );
1265 updateFilterOptionsBox( );
1266 updateSelectionBox( );
1267 #endif
1270 // ------------------------------------------------------------------------
1271 void FileDialogHelper_Impl::postExecute( sal_Int16 _nResult )
1273 if ( ExecutableDialogResults::CANCEL != _nResult )
1274 saveConfig();
1277 // ------------------------------------------------------------------------
1278 void FileDialogHelper_Impl::implInitializeFileName( )
1280 if ( !maFileName.isEmpty() )
1282 INetURLObject aObj( maPath );
1283 aObj.Append( maFileName );
1285 // in case we're operating as save dialog, and "auto extension" is checked,
1286 // cut the extension from the name
1287 if ( mbIsSaveDlg && mbHasAutoExt )
1291 sal_Bool bAutoExtChecked = sal_False;
1293 uno::Reference < XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1294 if ( xControlAccess.is()
1295 && ( xControlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 )
1296 >>= bAutoExtChecked
1300 if ( bAutoExtChecked )
1301 { // cut the extension
1302 aObj.removeExtension( );
1303 mxFileDlg->setDefaultName( aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) );
1307 catch( const Exception& )
1309 OSL_FAIL( "FileDialogHelper_Impl::implInitializeFileName: could not ask for the auto-extension current-value!" );
1315 // ------------------------------------------------------------------------
1316 sal_Int16 FileDialogHelper_Impl::implDoExecute()
1318 preExecute();
1320 sal_Int16 nRet = ExecutableDialogResults::CANCEL;
1322 //On MacOSX the native file picker has to run in the primordial thread because of drawing issues
1323 //On Linux the native gtk file picker, when backed by gnome-vfs2, needs to be run in the same
1324 //primordial thread as the ucb gnome-vfs2 provider was initialized in.
1329 #ifdef WNT
1330 if ( mbSystemPicker )
1332 SolarMutexReleaser aSolarMutex;
1333 nRet = mxFileDlg->execute();
1335 else
1336 #endif
1337 nRet = mxFileDlg->execute();
1339 catch( const Exception& )
1341 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1345 postExecute( nRet );
1347 return nRet;
1350 // ------------------------------------------------------------------------
1351 void FileDialogHelper_Impl::implStartExecute()
1353 DBG_ASSERT( mxFileDlg.is(), "invalid file dialog" );
1355 preExecute();
1357 if ( mbSystemPicker )
1360 else
1364 uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( mxFileDlg, UNO_QUERY );
1365 if ( xAsyncDlg.is() )
1366 xAsyncDlg->startExecuteModal( this );
1368 catch( const Exception& )
1370 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1375 // ------------------------------------------------------------------------
1376 void lcl_saveLastURLs(std::vector<rtl::OUString>& rpURLList,
1377 ::comphelper::SequenceAsVector< ::rtl::OUString >& lLastURLs )
1379 lLastURLs.clear();
1380 for(std::vector<rtl::OUString>::iterator i = rpURLList.begin(); i != rpURLList.end(); ++i)
1381 lLastURLs.push_back(*i);
1384 // ------------------------------------------------------------------------
1385 void FileDialogHelper_Impl::implGetAndCacheFiles(const uno::Reference< XInterface >& xPicker, std::vector<rtl::OUString>& rpURLList, const SfxFilter* pFilter)
1387 rpURLList.clear();
1389 rtl::OUString sExtension;
1390 if (pFilter)
1392 sExtension = pFilter->GetDefaultExtension ();
1393 sExtension = comphelper::string::remove(sExtension, '*');
1394 sExtension = comphelper::string::remove(sExtension, '.');
1397 // a) the new way (optional!)
1398 uno::Reference< XFilePicker2 > xPickNew(xPicker, UNO_QUERY);
1399 if (xPickNew.is())
1401 Sequence< OUString > lFiles = xPickNew->getSelectedFiles();
1402 ::sal_Int32 nFiles = lFiles.getLength();
1403 for(sal_Int32 i = 0; i < nFiles; ++i)
1404 rpURLList.push_back(lFiles[i]);
1407 // b) the olde way ... non optional.
1408 else
1410 uno::Reference< XFilePicker > xPickOld(xPicker, UNO_QUERY_THROW);
1411 Sequence< OUString > lFiles = xPickOld->getFiles();
1412 ::sal_Int32 nFiles = lFiles.getLength();
1413 if ( nFiles == 1 )
1415 rpURLList.push_back(lFiles[0]);
1417 else if ( nFiles > 1 )
1419 INetURLObject aPath( lFiles[0] );
1420 aPath.setFinalSlash();
1422 for (::sal_Int32 i = 1; i < nFiles; i++)
1424 if (i == 1)
1425 aPath.Append( lFiles[i] );
1426 else
1427 aPath.setName( lFiles[i] );
1429 rpURLList.push_back(aPath.GetMainURL(INetURLObject::NO_DECODE));
1434 lcl_saveLastURLs(rpURLList, mlLastURLs);
1437 // ------------------------------------------------------------------------
1438 ErrCode FileDialogHelper_Impl::execute( std::vector<rtl::OUString>& rpURLList,
1439 SfxItemSet *& rpSet,
1440 String& rFilter )
1442 // rFilter is a pure output parameter, it shouldn't be used for anything else
1443 // changing this would surely break code
1444 // rpSet is in/out parameter, usually just a media-descriptor that can be changed by dialog
1446 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
1448 // retrieves parameters from rpSet
1449 // for now only Password is used
1450 if ( rpSet )
1452 // check password checkbox if the document had password before
1453 if( mbHasPassword )
1455 SFX_ITEMSET_ARG( rpSet, pPassItem, SfxBoolItem, SID_PASSWORDINTERACTION, sal_False );
1456 mbPwdCheckBoxState = ( pPassItem != NULL && pPassItem->GetValue() );
1458 // in case the document has password to modify, the dialog should be shown
1459 SFX_ITEMSET_ARG( rpSet, pPassToModifyItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, sal_False );
1460 mbPwdCheckBoxState |= ( pPassToModifyItem && pPassToModifyItem->GetValue().hasValue() );
1463 SFX_ITEMSET_ARG( rpSet, pSelectItem, SfxBoolItem, SID_SELECTION, sal_False );
1464 if ( pSelectItem )
1465 mbSelection = pSelectItem->GetValue();
1466 else
1467 mbSelectionEnabled = sal_False;
1469 // the password will be set in case user decide so
1470 rpSet->ClearItem( SID_PASSWORDINTERACTION );
1471 rpSet->ClearItem( SID_PASSWORD );
1472 rpSet->ClearItem( SID_ENCRYPTIONDATA );
1473 rpSet->ClearItem( SID_RECOMMENDREADONLY );
1474 rpSet->ClearItem( SID_MODIFYPASSWORDINFO );
1478 if ( mbHasPassword && !mbPwdCheckBoxState )
1480 SvtSecurityOptions aSecOpt;
1481 mbPwdCheckBoxState = (
1482 aSecOpt.IsOptionSet( SvtSecurityOptions::E_DOCWARN_RECOMMENDPASSWORD ) );
1485 rpURLList.clear();
1487 if ( ! mxFileDlg.is() )
1488 return ERRCODE_ABORT;
1490 if ( ExecutableDialogResults::CANCEL != implDoExecute() )
1492 // create an itemset if there is no
1493 if( !rpSet )
1494 rpSet = new SfxAllItemSet( SFX_APP()->GetPool() );
1496 // the item should remain only if it was set by the dialog
1497 rpSet->ClearItem( SID_SELECTION );
1499 if( mbExport && mbHasSelectionBox )
1503 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
1504 sal_Bool bSelection = sal_False;
1505 if ( aValue >>= bSelection )
1506 rpSet->Put( SfxBoolItem( SID_SELECTION, bSelection ) );
1508 catch( const IllegalArgumentException& )
1510 OSL_FAIL( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1515 // set the read-only flag. When inserting a file, this flag is always set
1516 if ( mbInsert )
1517 rpSet->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
1518 else
1520 if ( ( FILEOPEN_READONLY_VERSION == m_nDialogType ) && xCtrlAccess.is() )
1524 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 );
1525 sal_Bool bReadOnly = sal_False;
1526 if ( ( aValue >>= bReadOnly ) && bReadOnly )
1527 rpSet->Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
1529 catch( const IllegalArgumentException& )
1531 OSL_FAIL( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1535 if ( mbHasVersions && xCtrlAccess.is() )
1539 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
1540 ControlActions::GET_SELECTED_ITEM_INDEX );
1541 sal_Int32 nVersion = 0;
1542 if ( ( aValue >>= nVersion ) && nVersion > 0 )
1543 // open a special version; 0 == current version
1544 rpSet->Put( SfxInt16Item( SID_VERSION, (short)nVersion ) );
1546 catch( const IllegalArgumentException& ){}
1549 // set the filter
1550 getRealFilter( rFilter );
1552 const SfxFilter* pCurrentFilter = getCurentSfxFilter();
1554 // fill the rpURLList
1555 implGetAndCacheFiles( mxFileDlg, rpURLList, pCurrentFilter );
1556 if ( rpURLList.empty() )
1557 return ERRCODE_ABORT;
1559 // check, whether or not we have to display a password box
1560 if ( pCurrentFilter && mbHasPassword && mbIsPwdEnabled && xCtrlAccess.is() )
1564 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
1565 sal_Bool bPassWord = sal_False;
1566 if ( ( aValue >>= bPassWord ) && bPassWord )
1568 // ask for a password
1569 rtl::OUString aDocName(rpURLList[0]);
1570 ErrCode errCode = RequestPassword(pCurrentFilter, aDocName, rpSet);
1571 if (errCode != ERRCODE_NONE)
1572 return errCode;
1575 catch( const IllegalArgumentException& ){}
1578 SaveLastUsedFilter();
1579 return ERRCODE_NONE;
1581 else
1582 return ERRCODE_ABORT;
1585 // ------------------------------------------------------------------------
1586 ErrCode FileDialogHelper_Impl::execute()
1588 if ( ! mxFileDlg.is() )
1589 return ERRCODE_ABORT;
1591 sal_Int16 nRet = implDoExecute();
1593 maPath = mxFileDlg->getDisplayDirectory();
1595 if ( ExecutableDialogResults::CANCEL == nRet )
1596 return ERRCODE_ABORT;
1597 else
1599 return ERRCODE_NONE;
1603 // ------------------------------------------------------------------------
1604 OUString FileDialogHelper_Impl::getPath() const
1606 OUString aPath;
1608 if ( mxFileDlg.is() )
1609 aPath = mxFileDlg->getDisplayDirectory();
1611 if ( aPath.isEmpty() )
1612 aPath = maPath;
1614 return aPath;
1617 // ------------------------------------------------------------------------
1618 OUString FileDialogHelper_Impl::getFilter() const
1620 String aFilter = getCurrentFilterUIName();
1622 if( !aFilter.Len() )
1623 aFilter = maCurFilter;
1625 return aFilter;
1628 // ------------------------------------------------------------------------
1629 void FileDialogHelper_Impl::getRealFilter( String& _rFilter ) const
1631 _rFilter = getCurrentFilterUIName();
1633 if ( !_rFilter.Len() )
1634 _rFilter = maCurFilter;
1636 if ( _rFilter.Len() && mpMatcher )
1638 const SfxFilter* pFilter =
1639 mpMatcher->GetFilter4UIName( _rFilter, m_nMustFlags, m_nDontFlags );
1640 _rFilter = pFilter ? pFilter->GetFilterName() : _rFilter.Erase();
1644 void FileDialogHelper_Impl::verifyPath()
1646 #ifdef UNX
1647 // lp#905355, fdo#43895
1648 // Check that the file has read only permission and is in /tmp -- this is
1649 // the case if we have opened the file from the web with firefox only.
1650 if (maFileName.isEmpty()) {
1651 return;
1653 INetURLObject url(maPath);
1654 if (url.GetProtocol() != INET_PROT_FILE
1655 || url.getName(0, true, INetURLObject::DECODE_WITH_CHARSET) != "tmp")
1657 return;
1659 if (maFileName.indexOf('/') != -1) {
1660 SAL_WARN("sfx2", maFileName << " contains /");
1661 return;
1663 url.insertName(
1664 maFileName, false, INetURLObject::LAST_SEGMENT, true,
1665 INetURLObject::ENCODE_ALL);
1666 rtl::OUString sysPathU;
1667 osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
1668 url.GetMainURL(INetURLObject::NO_DECODE), sysPathU);
1669 if (e != osl::FileBase::E_None) {
1670 SAL_WARN(
1671 "sfx2",
1672 "getSystemPathFromFileURL("
1673 << url.GetMainURL(INetURLObject::NO_DECODE) << ") failed with "
1674 << +e);
1675 return;
1677 rtl::OString sysPathC;
1678 if (!sysPathU.convertToString(
1679 &sysPathC, osl_getThreadTextEncoding(),
1680 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
1681 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1683 SAL_WARN(
1684 "sfx2",
1685 "convertToString(" << sysPathU << ") failed for encoding "
1686 << +osl_getThreadTextEncoding());
1687 return;
1689 struct stat aFileStat;
1690 if (stat(sysPathC.getStr(), &aFileStat) == -1) {
1691 SAL_WARN(
1692 "sfx2",
1693 "stat(" << sysPathC.getStr() << ") failed with errno " << errno);
1694 return;
1696 if ((aFileStat.st_mode & (S_IRWXO | S_IRWXG | S_IRWXU)) == S_IRUSR) {
1697 maPath = SvtPathOptions().GetWorkPath();
1698 mxFileDlg->setDisplayDirectory( maPath );
1700 #endif
1703 // ------------------------------------------------------------------------
1704 void FileDialogHelper_Impl::displayFolder( const ::rtl::OUString& _rPath )
1706 if ( _rPath.isEmpty() )
1707 // nothing to do
1708 return;
1710 maPath = _rPath;
1711 if ( mxFileDlg.is() )
1715 mxFileDlg->setDisplayDirectory( maPath );
1716 verifyPath();
1718 catch( const IllegalArgumentException& )
1720 OSL_FAIL( "FileDialogHelper_Impl::displayFolder: caught an exception!" );
1725 // ------------------------------------------------------------------------
1726 void FileDialogHelper_Impl::setFileName( const ::rtl::OUString& _rFile )
1728 maFileName = _rFile;
1729 if ( mxFileDlg.is() )
1733 mxFileDlg->setDefaultName( maFileName );
1734 verifyPath();
1736 catch( const IllegalArgumentException& )
1738 OSL_FAIL( "FileDialogHelper_Impl::setFileName: caught an exception!" );
1743 // ------------------------------------------------------------------------
1744 void FileDialogHelper_Impl::setFilter( const OUString& rFilter )
1746 DBG_ASSERT( rFilter.indexOf(':') == -1, "Old filter name used!");
1748 maCurFilter = rFilter;
1750 if ( !rFilter.isEmpty() && mpMatcher )
1752 const SfxFilter* pFilter = mpMatcher->GetFilter4FilterName(
1753 rFilter, m_nMustFlags, m_nDontFlags );
1754 if ( pFilter )
1755 maCurFilter = pFilter->GetUIName();
1758 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1760 if ( !maCurFilter.isEmpty() && xFltMgr.is() )
1764 xFltMgr->setCurrentFilter( maCurFilter );
1766 catch( const IllegalArgumentException& ){}
1770 // ------------------------------------------------------------------------
1771 void FileDialogHelper_Impl::createMatcher( const String& rFactory )
1773 mpMatcher = new SfxFilterMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
1774 mbDeleteMatcher = sal_True;
1777 // ------------------------------------------------------------------------
1778 void FileDialogHelper_Impl::addFilters( const String& rFactory,
1779 SfxFilterFlags nMust,
1780 SfxFilterFlags nDont )
1782 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1784 if ( ! xFltMgr.is() )
1785 return;
1787 // we still need a matcher to convert UI names to filter names
1788 if ( !rFactory.Len() )
1790 SfxApplication *pSfxApp = SFX_APP();
1791 mpMatcher = &pSfxApp->GetFilterMatcher();
1792 mbDeleteMatcher = sal_False;
1794 else
1796 mpMatcher = new SfxFilterMatcher( rFactory );
1797 mbDeleteMatcher = sal_True;
1800 uno::Reference< XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1801 uno::Reference< XContainerQuery > xFilterCont(
1802 xSMGR->createInstance(::rtl::OUString("com.sun.star.document.FilterFactory")),
1803 UNO_QUERY);
1804 if ( ! xFilterCont.is() )
1805 return;
1807 m_nMustFlags |= nMust;
1808 m_nDontFlags |= nDont;
1810 // create the list of filters
1811 ::rtl::OUStringBuffer sQuery(256);
1812 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM("getSortedFilterList()"));
1813 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM(":module="));
1814 sQuery.append(rFactory); // use long name here !
1815 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM(":iflags="));
1816 sQuery.append(::rtl::OUString::valueOf((sal_Int32)m_nMustFlags));
1817 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM(":eflags="));
1818 sQuery.append(::rtl::OUString::valueOf((sal_Int32)m_nDontFlags));
1820 uno::Reference< XEnumeration > xResult;
1823 xResult = xFilterCont->createSubSetEnumerationByQuery(sQuery.makeStringAndClear());
1825 catch( const uno::Exception& )
1827 SAL_WARN( "sfx2.dialog", "Could not get filters from the configuration!" );
1830 TSortedFilterList aIter (xResult);
1832 // no matcher any longer used ...
1833 mbDeleteMatcher = sal_False;
1835 // append the filters
1836 ::rtl::OUString sFirstFilter;
1837 if (OPEN == lcl_OpenOrSave(m_nDialogType))
1838 ::sfx2::appendFiltersForOpen( aIter, xFltMgr, sFirstFilter, *this );
1839 else if ( mbExport )
1840 ::sfx2::appendExportFilters( aIter, xFltMgr, sFirstFilter, *this );
1841 else
1842 ::sfx2::appendFiltersForSave( aIter, xFltMgr, sFirstFilter, *this, rFactory );
1844 // set our initial selected filter (if we do not already have one)
1845 if ( maSelectFilter.isEmpty() )
1846 maSelectFilter = sFirstFilter;
1849 // ------------------------------------------------------------------------
1850 void FileDialogHelper_Impl::addFilter( const OUString& rFilterName,
1851 const OUString& rExtension )
1853 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1855 if ( ! xFltMgr.is() )
1856 return;
1860 xFltMgr->appendFilter( rFilterName, rExtension );
1862 if ( maSelectFilter.isEmpty() )
1863 maSelectFilter = rFilterName;
1865 catch( const IllegalArgumentException& )
1867 SAL_WARN( "sfx2.dialog", "Could not append Filter" << rFilterName );
1871 // ------------------------------------------------------------------------
1872 void FileDialogHelper_Impl::addGraphicFilter()
1874 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1876 if ( ! xFltMgr.is() )
1877 return;
1879 // create the list of filters
1880 mpGraphicFilter = new GraphicFilter;
1881 sal_uInt16 i, j, nCount = mpGraphicFilter->GetImportFormatCount();
1883 // compute the extension string for all known import filters
1884 String aExtensions;
1886 for ( i = 0; i < nCount; i++ )
1888 j = 0;
1889 String sWildcard;
1890 while( sal_True )
1892 sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1893 if ( !sWildcard.Len() )
1894 break;
1895 if ( aExtensions.Search( sWildcard ) == STRING_NOTFOUND )
1897 if ( aExtensions.Len() )
1898 aExtensions += sal_Unicode(';');
1899 aExtensions += sWildcard;
1904 #if defined(WNT)
1905 if ( aExtensions.Len() > 240 )
1906 aExtensions = DEFINE_CONST_UNICODE( FILEDIALOG_FILTER_ALL );
1907 #endif
1908 sal_Bool bIsInOpenMode = isInOpenMode();
1912 OUString aAllFilterName = String( SfxResId( STR_SFX_IMPORT_ALL ) );
1913 aAllFilterName = ::sfx2::addExtension( aAllFilterName, aExtensions, bIsInOpenMode, *this );
1915 xFltMgr->appendFilter( aAllFilterName, aExtensions );
1916 maSelectFilter = aAllFilterName;
1918 catch( const IllegalArgumentException& )
1920 SAL_WARN( "sfx2.dialog", "Could not append Filter" );
1923 // Now add the filter
1924 for ( i = 0; i < nCount; i++ )
1926 String aName = mpGraphicFilter->GetImportFormatName( i );
1927 String aExt;
1928 j = 0;
1929 String sWildcard;
1930 while( sal_True )
1932 sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1933 if ( !sWildcard.Len() )
1934 break;
1935 if ( aExt.Search( sWildcard ) == STRING_NOTFOUND )
1937 if ( aExt.Len() )
1938 aExt += sal_Unicode(';');
1939 aExt += sWildcard;
1942 aName = ::sfx2::addExtension( aName, aExt, bIsInOpenMode, *this );
1945 xFltMgr->appendFilter( aName, aExt );
1947 catch( const IllegalArgumentException& )
1949 SAL_WARN( "sfx2.dialog", "Could not append Filter" );
1954 // ------------------------------------------------------------------------
1955 #define GRF_CONFIG_STR " "
1956 #define STD_CONFIG_STR "1 "
1958 void FileDialogHelper_Impl::saveConfig()
1960 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
1961 Any aValue;
1963 if ( ! xDlg.is() )
1964 return;
1966 if ( mbHasPreview )
1968 SvtViewOptions aDlgOpt( E_DIALOG, IMPGRF_CONFIGNAME );
1969 String aUserData = DEFINE_CONST_UNICODE( GRF_CONFIG_STR );
1973 sal_Bool bValue = sal_False;
1974 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
1975 bValue = sal_False;
1976 aValue >>= bValue;
1977 aUserData.SetToken( 1, ' ', String::CreateFromInt32( (sal_Int32) bValue ) );
1979 INetURLObject aObj( getPath() );
1981 if ( aObj.GetProtocol() == INET_PROT_FILE )
1982 aUserData.SetToken( 2, ' ', aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1984 String aFilter = getFilter();
1985 aFilter = EncodeSpaces_Impl( aFilter );
1986 aUserData.SetToken( 3, ' ', aFilter );
1988 aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
1990 catch( const IllegalArgumentException& ){}
1992 else
1994 sal_Bool bWriteConfig = sal_False;
1995 SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
1996 String aUserData = DEFINE_CONST_UNICODE( STD_CONFIG_STR );
1998 if ( aDlgOpt.Exists() )
2000 Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME );
2001 OUString aTemp;
2002 if ( aUserItem >>= aTemp )
2003 aUserData = String( aTemp );
2006 if ( mbHasAutoExt )
2010 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 );
2011 sal_Bool bAutoExt = sal_True;
2012 aValue >>= bAutoExt;
2013 aUserData.SetToken( 0, ' ', String::CreateFromInt32( (sal_Int32) bAutoExt ) );
2014 bWriteConfig = sal_True;
2016 catch( const IllegalArgumentException& ){}
2019 if ( ! mbIsSaveDlg )
2021 OUString aPath = getPath();
2022 if ( !aPath.isEmpty() &&
2023 utl::LocalFileHelper::IsLocalFile( aPath ) )
2025 aUserData.SetToken( 1, ' ', aPath );
2026 bWriteConfig = sal_True;
2030 if( mbHasSelectionBox && mbSelectionFltrEnabled )
2034 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
2035 sal_Bool bSelection = sal_True;
2036 aValue >>= bSelection;
2037 if ( comphelper::string::getTokenCount(aUserData, ' ') < 3 )
2038 aUserData.Append(' ');
2039 aUserData.SetToken( 2, ' ', String::CreateFromInt32( (sal_Int32) bSelection ) );
2040 bWriteConfig = sal_True;
2042 catch( const IllegalArgumentException& ){}
2045 if ( bWriteConfig )
2046 aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
2049 SfxApplication *pSfxApp = SFX_APP();
2050 pSfxApp->SetLastDir_Impl( getPath() );
2053 // ------------------------------------------------------------------------
2054 namespace
2056 static ::rtl::OUString getInitPath( const String& _rFallback, const xub_StrLen _nFallbackToken )
2058 SfxApplication *pSfxApp = SFX_APP();
2059 String sPath = pSfxApp->GetLastDir_Impl();
2061 if ( !sPath.Len() )
2062 sPath = _rFallback.GetToken( _nFallbackToken, ' ' );
2064 // check if the path points to a valid (accessible) directory
2065 sal_Bool bValid = sal_False;
2066 if ( sPath.Len() )
2068 String sPathCheck( sPath );
2069 if ( sPathCheck.GetBuffer()[ sPathCheck.Len() - 1 ] != '/' )
2070 sPathCheck += '/';
2071 sPathCheck += '.';
2074 ::ucbhelper::Content aContent( sPathCheck, uno::Reference< ucb::XCommandEnvironment >() );
2075 bValid = aContent.isFolder();
2077 catch( const Exception& ) {}
2080 if ( !bValid )
2081 sPath.Erase();
2083 return sPath;
2087 // ------------------------------------------------------------------------
2088 void FileDialogHelper_Impl::loadConfig()
2090 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
2091 Any aValue;
2093 if ( ! xDlg.is() )
2094 return;
2096 if ( mbHasPreview )
2098 SvtViewOptions aViewOpt( E_DIALOG, IMPGRF_CONFIGNAME );
2099 String aUserData;
2101 if ( aViewOpt.Exists() )
2103 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2104 OUString aTemp;
2105 if ( aUserItem >>= aTemp )
2106 aUserData = String( aTemp );
2109 if ( aUserData.Len() > 0 )
2113 // respect the last "show preview" state
2114 sal_Bool bShowPreview = (sal_Bool) aUserData.GetToken( 1, ' ' ).ToInt32();
2115 if ( !xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 ).hasValue() )
2117 aValue <<= bShowPreview;
2118 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, aValue );
2121 if ( maPath.isEmpty() )
2122 displayFolder( getInitPath( aUserData, 2 ) );
2124 if ( maCurFilter.isEmpty() )
2126 String aFilter = aUserData.GetToken( 3, ' ' );
2127 aFilter = DecodeSpaces_Impl( aFilter );
2128 setFilter( aFilter );
2131 // set the member so we know that we have to show the preview
2132 mbShowPreview = bShowPreview;
2134 catch( const IllegalArgumentException& ){}
2137 if ( maPath.isEmpty() )
2138 displayFolder( SvtPathOptions().GetGraphicPath() );
2140 else
2142 SvtViewOptions aViewOpt( E_DIALOG, IODLG_CONFIGNAME );
2143 String aUserData;
2145 if ( aViewOpt.Exists() )
2147 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2148 OUString aTemp;
2149 if ( aUserItem >>= aTemp )
2150 aUserData = String( aTemp );
2153 if ( ! aUserData.Len() )
2154 aUserData = DEFINE_CONST_UNICODE( STD_CONFIG_STR );
2156 if ( maPath.isEmpty() )
2157 displayFolder( getInitPath( aUserData, 1 ) );
2159 if ( mbHasAutoExt )
2161 sal_Int32 nFlag = aUserData.GetToken( 0, ' ' ).ToInt32();
2162 aValue <<= (sal_Bool) nFlag;
2165 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue );
2167 catch( const IllegalArgumentException& ){}
2170 if( mbHasSelectionBox )
2172 sal_Int32 nFlag = aUserData.GetToken( 2, ' ' ).ToInt32();
2173 aValue <<= (sal_Bool) nFlag;
2176 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, aValue );
2178 catch( const IllegalArgumentException& ){}
2181 if ( maPath.isEmpty() )
2182 displayFolder( SvtPathOptions().GetWorkPath() );
2186 // ------------------------------------------------------------------------
2187 void FileDialogHelper_Impl::setDefaultValues()
2189 // when no filter is set, we set the curentFilter to <all>
2190 if ( maCurFilter.isEmpty() && !maSelectFilter.isEmpty() )
2192 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
2195 xFltMgr->setCurrentFilter( maSelectFilter );
2197 catch( const IllegalArgumentException& )
2201 // when no path is set, we use the standard 'work' folder
2202 if ( maPath.isEmpty() )
2204 OUString aWorkFolder = SvtPathOptions().GetWorkPath();
2207 mxFileDlg->setDisplayDirectory( aWorkFolder );
2209 catch( const Exception& )
2211 OSL_FAIL( "FileDialogHelper_Impl::setDefaultValues: caught an exception while setting the display directory!" );
2216 sal_Bool FileDialogHelper_Impl::isShowFilterExtensionEnabled() const
2218 return !maFilters.empty();
2221 void FileDialogHelper_Impl::addFilterPair( const OUString& rFilter,
2222 const OUString& rFilterWithExtension )
2224 maFilters.push_back( FilterPair( rFilter, rFilterWithExtension ) );
2228 OUString FileDialogHelper_Impl::getFilterName( const OUString& rFilterWithExtension ) const
2230 OUString sRet;
2231 for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2233 if ( (*pIter).Second == rFilterWithExtension )
2235 sRet = (*pIter).First;
2236 break;
2239 return sRet;
2242 OUString FileDialogHelper_Impl::getFilterWithExtension( const OUString& rFilter ) const
2244 OUString sRet;
2245 for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2247 if ( (*pIter).First == rFilter )
2249 sRet = (*pIter).Second;
2250 break;
2253 return sRet;
2256 void FileDialogHelper_Impl::SetContext( FileDialogHelper::Context _eNewContext )
2258 meContext = _eNewContext;
2260 const OUString* pConfigId = GetLastFilterConfigId( _eNewContext );
2261 if( pConfigId )
2262 LoadLastUsedFilter( *pConfigId );
2265 // ------------------------------------------------------------------------
2266 // ----------- FileDialogHelper ---------------------------
2267 // ------------------------------------------------------------------------
2269 FileDialogHelper::FileDialogHelper(
2270 sal_Int16 nDialogType,
2271 sal_Int64 nFlags,
2272 const String& rFact,
2273 SfxFilterFlags nMust,
2274 SfxFilterFlags nDont )
2276 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags );
2277 mxImp = mpImp;
2279 // create the list of filters
2280 mpImp->addFilters(
2281 SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2284 // ------------------------------------------------------------------------
2285 FileDialogHelper::FileDialogHelper(
2286 sal_Int16 nDialogType,
2287 sal_Int64 nFlags,
2288 const String& rFact,
2289 sal_Int16 nDialog,
2290 SfxFilterFlags nMust,
2291 SfxFilterFlags nDont,
2292 const String& rStandardDir,
2293 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList)
2295 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, nDialog, NULL, rStandardDir, rBlackList );
2296 mxImp = mpImp;
2298 // create the list of filters
2299 mpImp->addFilters(
2300 SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2303 // ------------------------------------------------------------------------
2304 FileDialogHelper::FileDialogHelper(
2305 sal_Int16 nDialogType,
2306 sal_Int64 nFlags,
2307 Window* _pPreferredParent )
2309 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent );
2310 mxImp = mpImp;
2313 // ------------------------------------------------------------------------
2314 FileDialogHelper::FileDialogHelper(
2315 sal_Int16 nDialogType,
2316 sal_Int64 nFlags,
2317 const ::rtl::OUString& aFilterUIName,
2318 const ::rtl::OUString& aExtName,
2319 const ::rtl::OUString& rStandardDir,
2320 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList,
2321 Window* _pPreferredParent )
2323 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent,rStandardDir, rBlackList );
2324 mxImp = mpImp;
2326 // the wildcard here is expected in form "*.extension"
2327 ::rtl::OUString aWildcard;
2328 if ( aExtName.indexOf( (sal_Unicode)'*' ) != 0 )
2330 if ( !aExtName.isEmpty() && aExtName.indexOf( (sal_Unicode)'.' ) != 0 )
2331 aWildcard = ::rtl::OUString( "*." );
2332 else
2333 aWildcard = ::rtl::OUString( "*" );
2336 aWildcard += aExtName;
2338 ::rtl::OUString const aUIString = ::sfx2::addExtension( aFilterUIName,
2339 aWildcard, (OPEN == lcl_OpenOrSave(mpImp->m_nDialogType)), *mpImp);
2340 AddFilter( aUIString, aWildcard );
2343 // ------------------------------------------------------------------------
2344 FileDialogHelper::~FileDialogHelper()
2346 mpImp->dispose();
2347 mxImp.clear();
2350 // ------------------------------------------------------------------------
2351 void FileDialogHelper::CreateMatcher( const String& rFactory )
2353 mpImp->createMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
2356 // ------------------------------------------------------------------------
2357 void FileDialogHelper::SetControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
2359 mpImp->setControlHelpIds( _pControlId, _pHelpId );
2362 void FileDialogHelper::SetContext( Context _eNewContext )
2364 mpImp->SetContext( _eNewContext );
2367 // ------------------------------------------------------------------------
2368 IMPL_LINK_NOARG(FileDialogHelper, ExecuteSystemFilePicker)
2370 m_nError = mpImp->execute();
2371 if ( m_aDialogClosedLink.IsSet() )
2372 m_aDialogClosedLink.Call( this );
2374 return 0L;
2377 // ------------------------------------------------------------------------
2378 // rDirPath has to be a directory
2379 ErrCode FileDialogHelper::Execute( std::vector<rtl::OUString>& rpURLList,
2380 SfxItemSet *& rpSet,
2381 String& rFilter,
2382 const String& rDirPath )
2384 SetDisplayFolder( rDirPath );
2385 return mpImp->execute( rpURLList, rpSet, rFilter );
2389 // ------------------------------------------------------------------------
2390 ErrCode FileDialogHelper::Execute()
2392 return mpImp->execute();
2395 // ------------------------------------------------------------------------
2396 ErrCode FileDialogHelper::Execute( SfxItemSet *& rpSet,
2397 String& rFilter )
2399 ErrCode nRet;
2400 std::vector<rtl::OUString> rURLList;
2401 nRet = mpImp->execute(rURLList, rpSet, rFilter);
2402 return nRet;
2405 void FileDialogHelper::StartExecuteModal( const Link& rEndDialogHdl )
2407 m_aDialogClosedLink = rEndDialogHdl;
2408 m_nError = ERRCODE_NONE;
2409 if ( mpImp->isSystemFilePicker() )
2410 Application::PostUserEvent( LINK( this, FileDialogHelper, ExecuteSystemFilePicker ) );
2411 else
2412 mpImp->implStartExecute();
2415 // ------------------------------------------------------------------------
2417 short FileDialogHelper::GetDialogType() const
2419 return mpImp ? mpImp->m_nDialogType : 0;
2422 // ------------------------------------------------------------------------
2424 sal_Bool FileDialogHelper::IsPasswordEnabled() const
2426 return mpImp ? mpImp->isPasswordEnabled() : sal_False;
2429 // ------------------------------------------------------------------------
2431 String FileDialogHelper::GetRealFilter() const
2433 String sFilter;
2434 if ( mpImp )
2435 mpImp->getRealFilter( sFilter );
2436 return sFilter;
2439 // ------------------------------------------------------------------------
2440 void FileDialogHelper::SetTitle( const String& rNewTitle )
2442 if ( mpImp->mxFileDlg.is() )
2443 mpImp->mxFileDlg->setTitle( rNewTitle );
2446 // ------------------------------------------------------------------------
2447 String FileDialogHelper::GetPath() const
2449 OUString aPath;
2451 if ( mpImp->mlLastURLs.size() > 0)
2452 return mpImp->mlLastURLs[0];
2454 if ( mpImp->mxFileDlg.is() )
2456 Sequence < OUString > aPathSeq = mpImp->mxFileDlg->getFiles();
2458 if ( aPathSeq.getLength() == 1 )
2460 aPath = aPathSeq[0];
2464 return aPath;
2467 // ------------------------------------------------------------------------
2468 Sequence < OUString > FileDialogHelper::GetMPath() const
2470 if ( mpImp->mlLastURLs.size() > 0)
2471 return mpImp->mlLastURLs.getAsConstList();
2473 if ( mpImp->mxFileDlg.is() )
2474 return mpImp->mxFileDlg->getFiles();
2475 else
2477 Sequence < OUString > aEmpty;
2478 return aEmpty;
2482 // ------------------------------------------------------------------------
2483 Sequence< ::rtl::OUString > FileDialogHelper::GetSelectedFiles() const
2485 // a) the new way (optional!)
2486 uno::Sequence< ::rtl::OUString > aResultSeq;
2487 uno::Reference< XFilePicker2 > xPickNew(mpImp->mxFileDlg, UNO_QUERY);
2488 if (xPickNew.is())
2490 aResultSeq = xPickNew->getSelectedFiles();
2492 // b) the olde way ... non optional.
2493 else
2495 uno::Reference< XFilePicker > xPickOld(mpImp->mxFileDlg, UNO_QUERY_THROW);
2496 Sequence< OUString > lFiles = xPickOld->getFiles();
2497 ::sal_Int32 nFiles = lFiles.getLength();
2498 if ( nFiles > 1 )
2500 aResultSeq = Sequence< ::rtl::OUString >( nFiles-1 );
2502 INetURLObject aPath( lFiles[0] );
2503 aPath.setFinalSlash();
2505 for (::sal_Int32 i = 1; i < nFiles; i++)
2507 if (i == 1)
2508 aPath.Append( lFiles[i] );
2509 else
2510 aPath.setName( lFiles[i] );
2512 aResultSeq[i-1] = ::rtl::OUString(aPath.GetMainURL( INetURLObject::NO_DECODE ));
2515 else
2516 aResultSeq = lFiles;
2519 return aResultSeq;
2522 // ------------------------------------------------------------------------
2523 String FileDialogHelper::GetDisplayDirectory() const
2525 return mpImp->getPath();
2528 // ------------------------------------------------------------------------
2529 String FileDialogHelper::GetCurrentFilter() const
2531 return mpImp->getFilter();
2534 // ------------------------------------------------------------------------
2535 ErrCode FileDialogHelper::GetGraphic( Graphic& rGraphic ) const
2537 return mpImp->getGraphic( rGraphic );
2540 // ------------------------------------------------------------------------
2541 static int impl_isFolder( const OUString& rPath )
2545 ::ucbhelper::Content aContent(
2546 rPath, uno::Reference< ucb::XCommandEnvironment > () );
2547 if ( aContent.isFolder() )
2548 return 1;
2550 return 0;
2552 catch ( const Exception & )
2556 return -1;
2559 void FileDialogHelper::SetDisplayDirectory( const String& _rPath )
2561 if ( !_rPath.Len() )
2562 return;
2564 // if the given path isn't a folder, we cut off the last part
2565 // and take it as filename and the rest of the path should be
2566 // the folder
2568 INetURLObject aObj( _rPath );
2570 ::rtl::OUString sFileName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET );
2571 aObj.removeSegment();
2572 ::rtl::OUString sPath = aObj.GetMainURL( INetURLObject::NO_DECODE );
2574 int nIsFolder = impl_isFolder( _rPath );
2575 if ( nIsFolder == 0 ||
2576 ( nIsFolder == -1 && impl_isFolder( sPath ) == 1 ) )
2578 mpImp->setFileName( sFileName );
2579 mpImp->displayFolder( sPath );
2581 else
2583 INetURLObject aObjPathName( _rPath );
2584 ::rtl::OUString sFolder( aObjPathName.GetMainURL( INetURLObject::NO_DECODE ) );
2585 if ( sFolder.isEmpty() )
2587 // _rPath is not a valid path -> fallback to home directory
2588 osl::Security aSecurity;
2589 aSecurity.getHomeDir( sFolder );
2591 mpImp->displayFolder( sFolder );
2595 // ------------------------------------------------------------------------
2596 void FileDialogHelper::SetDisplayFolder( const String& _rURL )
2598 mpImp->displayFolder( _rURL );
2601 // ------------------------------------------------------------------------
2602 void FileDialogHelper::SetFileName( const String& _rFileName )
2604 mpImp->setFileName( _rFileName );
2607 // ------------------------------------------------------------------------
2608 void FileDialogHelper::AddFilter( const String& rFilterName,
2609 const String& rExtension )
2611 mpImp->addFilter( rFilterName, rExtension );
2614 // ------------------------------------------------------------------------
2615 void FileDialogHelper::SetCurrentFilter( const String& rFilter )
2617 String sFilter( rFilter );
2618 if ( mpImp->isShowFilterExtensionEnabled() )
2619 sFilter = mpImp->getFilterWithExtension( rFilter );
2620 mpImp->setFilter( sFilter );
2623 // ------------------------------------------------------------------------
2624 uno::Reference < XFilePicker > FileDialogHelper::GetFilePicker() const
2626 return mpImp->mxFileDlg;
2629 // ------------------------------------------------------------------------
2630 // XFilePickerListener Methods
2631 // ------------------------------------------------------------------------
2632 void SAL_CALL FileDialogHelper::FileSelectionChanged( const FilePickerEvent& aEvent )
2634 mpImp->handleFileSelectionChanged( aEvent );
2637 // ------------------------------------------------------------------------
2638 void SAL_CALL FileDialogHelper::DirectoryChanged( const FilePickerEvent& aEvent )
2640 mpImp->handleDirectoryChanged( aEvent );
2643 // ------------------------------------------------------------------------
2644 OUString SAL_CALL FileDialogHelper::HelpRequested( const FilePickerEvent& aEvent )
2646 return mpImp->handleHelpRequested( aEvent );
2649 // ------------------------------------------------------------------------
2650 void SAL_CALL FileDialogHelper::ControlStateChanged( const FilePickerEvent& aEvent )
2652 mpImp->handleControlStateChanged( aEvent );
2655 // ------------------------------------------------------------------------
2656 void SAL_CALL FileDialogHelper::DialogSizeChanged()
2658 mpImp->handleDialogSizeChanged();
2661 // ------------------------------------------------------------------------
2662 void SAL_CALL FileDialogHelper::DialogClosed( const DialogClosedEvent& _rEvent )
2664 m_nError = ( RET_OK == _rEvent.DialogResult ) ? ERRCODE_NONE : ERRCODE_ABORT;
2665 if ( m_aDialogClosedLink.IsSet() )
2666 m_aDialogClosedLink.Call( this );
2669 // ------------------------------------------------------------------------
2671 ErrCode FileOpenDialog_Impl( sal_Int16 nDialogType,
2672 sal_Int64 nFlags,
2673 const String& rFact,
2674 std::vector<rtl::OUString>& rpURLList,
2675 String& rFilter,
2676 SfxItemSet *& rpSet,
2677 const String* pPath,
2678 sal_Int16 nDialog,
2679 const String& rStandardDir,
2680 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
2682 ErrCode nRet;
2683 FileDialogHelper aDialog( nDialogType, nFlags,
2684 rFact, nDialog, 0, 0, rStandardDir, rBlackList );
2686 String aPath;
2687 if ( pPath )
2688 aPath = *pPath;
2690 nRet = aDialog.Execute( rpURLList, rpSet, rFilter, aPath );
2691 DBG_ASSERT( rFilter.SearchAscii(": ") == STRING_NOTFOUND, "Old filter name used!");
2693 return nRet;
2696 ErrCode RequestPassword(const SfxFilter* pCurrentFilter, rtl::OUString& aURL, SfxItemSet* pSet)
2698 uno::Reference < ::com::sun::star::task::XInteractionHandler > xInteractionHandler( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY );
2699 if( xInteractionHandler.is() )
2701 // TODO: need a save way to distinguish MS filters from other filters
2702 // for now MS-filters are the only alien filters that support encryption
2703 sal_Bool bMSType = !pCurrentFilter->IsOwnFormat();
2704 ::comphelper::DocPasswordRequestType eType = bMSType ?
2705 ::comphelper::DocPasswordRequestType_MS :
2706 ::comphelper::DocPasswordRequestType_STANDARD;
2708 ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, ::com::sun::star::task::PasswordRequestMode_PASSWORD_CREATE, aURL, ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_PASSWORDTOMODIFY ) != 0 ) );
2710 uno::Reference< com::sun::star::task::XInteractionRequest > rRequest( pPasswordRequest.get() );
2711 xInteractionHandler->handle( rRequest );
2712 if ( pPasswordRequest->isPassword() )
2714 if ( pPasswordRequest->getPassword().getLength() )
2716 // TODO/LATER: The filters should show the password dialog themself in future
2717 if ( bMSType )
2719 // all the current MS-filters use MSCodec_Std97 implementation
2720 uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
2721 uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPasswordRequest->getPassword(), aUniqueID );
2723 if ( aEncryptionKey.getLength() )
2725 ::comphelper::SequenceAsHashMap aHashData;
2726 aHashData[ ::rtl::OUString( "STD97EncryptionKey" ) ] <<= aEncryptionKey;
2727 aHashData[ ::rtl::OUString( "STD97UniqueID" ) ] <<= aUniqueID;
2729 pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
2731 else
2732 return ERRCODE_IO_NOTSUPPORTED;
2734 else
2736 pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordRequest->getPassword() ) ) ) );
2740 if ( pPasswordRequest->getRecommendReadOnly() )
2741 pSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, sal_True ) );
2743 if ( bMSType )
2745 // the empty password has 0 as Hash
2746 sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash( pPasswordRequest->getPasswordToModify(), ::rtl::OUString( "com.sun.star.text.TextDocument" ).equals( pCurrentFilter->GetServiceName() ) );
2747 if ( nHash )
2748 pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( nHash ) ) );
2750 else
2752 uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( pPasswordRequest->getPasswordToModify() );
2753 if ( aModifyPasswordInfo.getLength() )
2754 pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( aModifyPasswordInfo ) ) );
2757 else
2758 return ERRCODE_ABORT;
2760 return ERRCODE_NONE;
2763 // ------------------------------------------------------------------------
2764 String EncodeSpaces_Impl( const String& rSource )
2766 String sRet( rSource );
2767 sRet.SearchAndReplaceAll( DEFINE_CONST_UNICODE( " " ), DEFINE_CONST_UNICODE( "%20" ) );
2768 return sRet;
2771 // ------------------------------------------------------------------------
2772 String DecodeSpaces_Impl( const String& rSource )
2774 String sRet( rSource );
2775 sRet.SearchAndReplaceAll( DEFINE_CONST_UNICODE( "%20" ), DEFINE_CONST_UNICODE( " " ) );
2776 return sRet;
2779 // ------------------------------------------------------------------------
2781 } // end of namespace sfx2
2783 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */