Bump version to 4.1-6
[LibreOffice.git] / sfx2 / source / dialog / filedlghelper.cxx
blob88fd6aa5f4f94dccbc60d8646f6f920402766dce
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sfx2/filedlghelper.hxx>
21 #include <sal/types.h>
22 #include <com/sun/star/lang/XInitialization.hpp>
23 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
24 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
25 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
26 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
27 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
28 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
29 #include <com/sun/star/ui/dialogs/XControlInformation.hpp>
30 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
31 #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
32 #include <com/sun/star/ui/dialogs/XFilePreview.hpp>
33 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
34 #include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
35 #include <com/sun/star/ui/dialogs/XFilePicker2.hpp>
36 #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/NamedValue.hpp>
40 #include <com/sun/star/embed/ElementModes.hpp>
41 #include <com/sun/star/container/XEnumeration.hpp>
42 #include <com/sun/star/container/XContainerQuery.hpp>
43 #include <com/sun/star/task/InteractionHandler.hpp>
44 #include <com/sun/star/task/XInteractionRequest.hpp>
45 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/sequenceashashmap.hxx>
49 #include <comphelper/stillreadwriteinteraction.hxx>
50 #include <comphelper/string.hxx>
51 #include <comphelper/types.hxx>
52 #include <tools/urlobj.hxx>
53 #include <vcl/help.hxx>
54 #include <unotools/ucbstreamhelper.hxx>
55 #include <unotools/ucbhelper.hxx>
56 #include <unotools/localfilehelper.hxx>
57 #include <osl/file.hxx>
58 #include <osl/mutex.hxx>
59 #include <osl/security.hxx>
60 #include <osl/thread.hxx>
61 #include <vcl/cvtgrf.hxx>
62 #include <vcl/msgbox.hxx>
63 #include <vcl/mnemonic.hxx>
64 #include <unotools/pathoptions.hxx>
65 #include <unotools/securityoptions.hxx>
66 #include <svl/itemset.hxx>
67 #include <svl/eitem.hxx>
68 #include <svl/intitem.hxx>
69 #include <svl/stritem.hxx>
70 #include <vcl/graphicfilter.hxx>
71 #include <unotools/viewoptions.hxx>
72 #include <unotools/moduleoptions.hxx>
73 #include <svtools/helpid.hrc>
74 #include <comphelper/docpasswordrequest.hxx>
75 #include <comphelper/docpasswordhelper.hxx>
76 #include <ucbhelper/content.hxx>
77 #include <ucbhelper/commandenvironment.hxx>
78 #include <comphelper/storagehelper.hxx>
79 #include <toolkit/helper/vclunohelper.hxx>
80 #include <sfx2/app.hxx>
81 #include <sfx2/frame.hxx>
82 #include <sfx2/docfile.hxx>
83 #include <sfx2/docfac.hxx>
84 #include "openflag.hxx"
85 #include <sfx2/passwd.hxx>
86 #include "sfx2/sfxresid.hxx"
87 #include <sfx2/sfxsids.hrc>
88 #include "filedlghelper.hrc"
89 #include "filtergrouping.hxx"
90 #include <sfx2/request.hxx>
91 #include "filedlgimpl.hxx"
92 #include <helpid.hrc>
93 #include <sfxlocal.hrc>
94 #include <rtl/strbuf.hxx>
96 #ifdef UNX
97 #include <errno.h>
98 #include <sys/stat.h>
99 #endif
101 //-----------------------------------------------------------------------------
103 using namespace ::com::sun::star;
104 using namespace ::com::sun::star::container;
105 using namespace ::com::sun::star::lang;
106 using namespace ::com::sun::star::ui::dialogs;
107 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
108 using namespace ::com::sun::star::uno;
109 using namespace ::com::sun::star::beans;
110 using namespace ::rtl;
111 using namespace ::cppu;
113 //-----------------------------------------------------------------------------
115 #define IODLG_CONFIGNAME OUString("FilePicker_Save")
116 #define IMPGRF_CONFIGNAME OUString("FilePicker_Graph")
117 #define USERITEM_NAME OUString("UserItem")
119 //-----------------------------------------------------------------------------
121 namespace sfx2
124 const OUString* GetLastFilterConfigId( FileDialogHelper::Context _eContext )
126 static const OUString aSD_EXPORT_IDENTIFIER( "SdExportLastFilter" );
127 static const OUString aSI_EXPORT_IDENTIFIER( "SiExportLastFilter" );
128 static const OUString aSW_EXPORT_IDENTIFIER( "SwExportLastFilter" );
130 const OUString* pRet = NULL;
132 switch( _eContext )
134 case FileDialogHelper::SD_EXPORT: pRet = &aSD_EXPORT_IDENTIFIER; break;
135 case FileDialogHelper::SI_EXPORT: pRet = &aSI_EXPORT_IDENTIFIER; break;
136 case FileDialogHelper::SW_EXPORT: pRet = &aSW_EXPORT_IDENTIFIER; break;
137 default: break;
140 return pRet;
143 String EncodeSpaces_Impl( const String& rSource );
144 String DecodeSpaces_Impl( const String& rSource );
146 // ------------------------------------------------------------------------
147 // ----------- FileDialogHelper_Impl ---------------------------
148 // ------------------------------------------------------------------------
150 // ------------------------------------------------------------------------
151 // XFilePickerListener Methods
152 // ------------------------------------------------------------------------
153 void SAL_CALL FileDialogHelper_Impl::fileSelectionChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
155 SolarMutexGuard aGuard;
156 mpAntiImpl->FileSelectionChanged( aEvent );
159 // ------------------------------------------------------------------------
160 void SAL_CALL FileDialogHelper_Impl::directoryChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
162 SolarMutexGuard aGuard;
163 mpAntiImpl->DirectoryChanged( aEvent );
166 // ------------------------------------------------------------------------
167 OUString SAL_CALL FileDialogHelper_Impl::helpRequested( const FilePickerEvent& aEvent ) throw ( RuntimeException )
169 SolarMutexGuard aGuard;
170 return mpAntiImpl->HelpRequested( aEvent );
173 // ------------------------------------------------------------------------
174 void SAL_CALL FileDialogHelper_Impl::controlStateChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
176 SolarMutexGuard aGuard;
177 mpAntiImpl->ControlStateChanged( aEvent );
180 // ------------------------------------------------------------------------
181 void SAL_CALL FileDialogHelper_Impl::dialogSizeChanged() throw ( RuntimeException )
183 SolarMutexGuard aGuard;
184 mpAntiImpl->DialogSizeChanged();
187 // ------------------------------------------------------------------------
188 // XDialogClosedListener Methods
189 // ------------------------------------------------------------------------
190 void SAL_CALL FileDialogHelper_Impl::dialogClosed( const DialogClosedEvent& _rEvent ) throw ( RuntimeException )
192 SolarMutexGuard aGuard;
193 mpAntiImpl->DialogClosed( _rEvent );
194 postExecute( _rEvent.DialogResult );
197 // ------------------------------------------------------------------------
198 // handle XFilePickerListener events
199 // ------------------------------------------------------------------------
200 void FileDialogHelper_Impl::handleFileSelectionChanged( const FilePickerEvent& )
202 if ( mbHasVersions )
203 updateVersions();
205 if ( mbShowPreview )
206 maPreViewTimer.Start();
209 // ------------------------------------------------------------------------
210 void FileDialogHelper_Impl::handleDirectoryChanged( const FilePickerEvent& )
212 if ( mbShowPreview )
213 TimeOutHdl_Impl( NULL );
216 // ------------------------------------------------------------------------
217 OUString FileDialogHelper_Impl::handleHelpRequested( const FilePickerEvent& aEvent )
219 //!!! todo: cache the help strings (here or TRA)
221 OString sHelpId;
222 // mapping from element id -> help id
223 switch ( aEvent.ElementId )
225 case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
226 sHelpId = HID_FILESAVE_AUTOEXTENSION;
227 break;
229 case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
230 sHelpId = HID_FILESAVE_SAVEWITHPASSWORD;
231 break;
233 case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
234 sHelpId = HID_FILESAVE_CUSTOMIZEFILTER;
235 break;
237 case ExtendedFilePickerElementIds::CHECKBOX_READONLY :
238 sHelpId = HID_FILEOPEN_READONLY;
239 break;
241 case ExtendedFilePickerElementIds::CHECKBOX_LINK :
242 sHelpId = HID_FILEDLG_LINK_CB;
243 break;
245 case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW :
246 sHelpId = HID_FILEDLG_PREVIEW_CB;
247 break;
249 case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
250 sHelpId = HID_FILESAVE_DOPLAY;
251 break;
253 case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL :
254 case ExtendedFilePickerElementIds::LISTBOX_VERSION :
255 sHelpId = HID_FILEOPEN_VERSION;
256 break;
258 case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL :
259 case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
260 sHelpId = HID_FILESAVE_TEMPLATE;
261 break;
263 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL :
264 case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
265 sHelpId = HID_FILEOPEN_IMAGE_TEMPLATE;
266 break;
268 case ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
269 sHelpId = HID_FILESAVE_SELECTION;
270 break;
272 default:
273 SAL_WARN( "sfx2.dialog", "invalid element id" );
276 OUString aHelpText;
277 Help* pHelp = Application::GetHelp();
278 if ( pHelp )
279 aHelpText = String( pHelp->GetHelpText( OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), NULL ) );
280 return aHelpText;
283 // ------------------------------------------------------------------------
284 void FileDialogHelper_Impl::handleControlStateChanged( const FilePickerEvent& aEvent )
286 switch ( aEvent.ElementId )
288 case CommonFilePickerElementIds::LISTBOX_FILTER:
289 updateFilterOptionsBox();
290 enablePasswordBox( sal_False );
291 updateSelectionBox();
292 // only use it for export and with our own dialog
293 if ( mbExport && !mbSystemPicker )
294 updateExportButton();
295 break;
297 case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
298 updatePreviewState();
299 break;
303 // ------------------------------------------------------------------------
304 void FileDialogHelper_Impl::handleDialogSizeChanged()
306 if ( mbShowPreview )
307 TimeOutHdl_Impl( NULL );
310 // ------------------------------------------------------------------------
311 // XEventListener Methods
312 // ------------------------------------------------------------------------
313 void SAL_CALL FileDialogHelper_Impl::disposing( const EventObject& ) throw ( RuntimeException )
315 SolarMutexGuard aGuard;
316 dispose();
319 // ------------------------------------------------------------------------
321 void FileDialogHelper_Impl::dispose()
323 if ( mxFileDlg.is() )
325 // remove the event listener
326 uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
327 if ( xNotifier.is() )
328 xNotifier->removeFilePickerListener( this );
330 ::comphelper::disposeComponent( mxFileDlg );
331 mxFileDlg.clear();
335 // ------------------------------------------------------------------------
336 String FileDialogHelper_Impl::getCurrentFilterUIName() const
338 String aFilterName;
339 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
341 if( xFltMgr.is() )
343 aFilterName = xFltMgr->getCurrentFilter();
345 if ( aFilterName.Len() && isShowFilterExtensionEnabled() )
346 aFilterName = getFilterName( aFilterName );
349 return aFilterName;
352 // ------------------------------------------------------------------------
353 void FileDialogHelper_Impl::LoadLastUsedFilter( const OUString& _rContextIdentifier )
355 SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
357 if( aDlgOpt.Exists() )
359 OUString aLastFilter;
360 if( aDlgOpt.GetUserItem( _rContextIdentifier ) >>= aLastFilter )
361 setFilter( aLastFilter );
365 // ------------------------------------------------------------------------
366 void FileDialogHelper_Impl::SaveLastUsedFilter( const OUString& _rContextIdentifier )
368 SvtViewOptions( E_DIALOG, IODLG_CONFIGNAME ).SetUserItem( _rContextIdentifier,
369 makeAny( getFilterWithExtension( getFilter() ) ) );
372 // ------------------------------------------------------------------------
373 void FileDialogHelper_Impl::SaveLastUsedFilter( void )
375 const OUString* pConfigId = GetLastFilterConfigId( meContext );
376 if( pConfigId )
377 SaveLastUsedFilter( *pConfigId );
380 // ------------------------------------------------------------------------
381 const SfxFilter* FileDialogHelper_Impl::getCurentSfxFilter()
383 String aFilterName = getCurrentFilterUIName();
385 const SfxFilter* pFilter = NULL;
386 if ( mpMatcher && aFilterName.Len() )
387 pFilter = mpMatcher->GetFilter4UIName( aFilterName, m_nMustFlags, m_nDontFlags );
389 return pFilter;
392 // ------------------------------------------------------------------------
393 sal_Bool FileDialogHelper_Impl::updateExtendedControl( sal_Int16 _nExtendedControlId, sal_Bool _bEnable )
395 sal_Bool bIsEnabled = sal_False;
397 uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
398 if ( xCtrlAccess.is() )
402 xCtrlAccess->enableControl( _nExtendedControlId, _bEnable );
403 bIsEnabled = _bEnable;
405 catch( const IllegalArgumentException& )
407 OSL_FAIL( "FileDialogHelper_Impl::updateExtendedControl: caught an exception!" );
410 return bIsEnabled;
413 // ------------------------------------------------------------------------
414 sal_Bool FileDialogHelper_Impl::CheckFilterOptionsCapability( const SfxFilter* _pFilter )
416 sal_Bool bResult = sal_False;
418 if( mxFilterCFG.is() && _pFilter )
420 try {
421 Sequence < PropertyValue > aProps;
422 Any aAny = mxFilterCFG->getByName( _pFilter->GetName() );
423 if ( aAny >>= aProps )
425 OUString aServiceName;
426 sal_Int32 nPropertyCount = aProps.getLength();
427 for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
429 if( aProps[nProperty].Name == "UIComponent" )
431 aProps[nProperty].Value >>= aServiceName;
432 if( !aServiceName.isEmpty() )
433 bResult = sal_True;
438 catch( const Exception& )
443 return bResult;
446 // ------------------------------------------------------------------------
447 sal_Bool FileDialogHelper_Impl::isInOpenMode() const
449 sal_Bool bRet = sal_False;
451 switch ( m_nDialogType )
453 case FILEOPEN_SIMPLE:
454 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
455 case FILEOPEN_PLAY:
456 case FILEOPEN_READONLY_VERSION:
457 case FILEOPEN_LINK_PREVIEW:
458 bRet = sal_True;
461 return bRet;
464 // ------------------------------------------------------------------------
466 void FileDialogHelper_Impl::updateFilterOptionsBox()
468 if ( !m_bHaveFilterOptions )
469 return;
471 updateExtendedControl(
472 ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS,
473 CheckFilterOptionsCapability( getCurentSfxFilter() )
477 // ------------------------------------------------------------------------
479 void FileDialogHelper_Impl::updateExportButton()
481 uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
482 if ( xCtrlAccess.is() )
484 OUString sEllipses( "..." );
485 OUString sOldLabel( xCtrlAccess->getLabel( CommonFilePickerElementIds::PUSHBUTTON_OK ) );
487 // initialize button label; we need the label with the mnemonic char
488 if ( maButtonLabel.isEmpty() || maButtonLabel.indexOf( MNEMONIC_CHAR ) == -1 )
490 // cut the ellipses, if necessary
491 sal_Int32 nIndex = sOldLabel.indexOf( sEllipses );
492 if ( -1 == nIndex )
493 nIndex = sOldLabel.getLength();
494 maButtonLabel = sOldLabel.copy( 0, nIndex );
497 OUString sLabel = maButtonLabel;
498 // filter with options -> append ellipses on export button label
499 if ( CheckFilterOptionsCapability( getCurentSfxFilter() ) )
500 sLabel += "...";
502 if ( sOldLabel != sLabel )
506 xCtrlAccess->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK, sLabel );
508 catch( const IllegalArgumentException& )
510 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::updateExportButton: caught an exception!" );
516 // ------------------------------------------------------------------------
517 void FileDialogHelper_Impl::updateSelectionBox()
519 if ( !mbHasSelectionBox )
520 return;
522 // Does the selection box exist?
523 sal_Bool bSelectionBoxFound = sal_False;
524 uno::Reference< XControlInformation > xCtrlInfo( mxFileDlg, UNO_QUERY );
525 if ( xCtrlInfo.is() )
527 Sequence< OUString > aCtrlList = xCtrlInfo->getSupportedControls();
528 sal_uInt32 nCount = aCtrlList.getLength();
529 for ( sal_uInt32 nCtrl = 0; nCtrl < nCount; ++nCtrl )
530 if ( aCtrlList[ nCtrl ] == "SelectionBox" )
532 bSelectionBoxFound = sal_True;
533 break;
537 if ( bSelectionBoxFound )
539 const SfxFilter* pFilter = getCurentSfxFilter();
540 mbSelectionFltrEnabled = updateExtendedControl(
541 ExtendedFilePickerElementIds::CHECKBOX_SELECTION,
542 ( mbSelectionEnabled && pFilter && ( pFilter->GetFilterFlags() & SFX_FILTER_SUPPORTSSELECTION ) != 0 ) );
543 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
544 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, makeAny( (sal_Bool)mbSelection ) );
548 // ------------------------------------------------------------------------
549 void FileDialogHelper_Impl::enablePasswordBox( sal_Bool bInit )
551 if ( ! mbHasPassword )
552 return;
554 sal_Bool bWasEnabled = mbIsPwdEnabled;
556 const SfxFilter* pCurrentFilter = getCurentSfxFilter();
557 mbIsPwdEnabled = updateExtendedControl(
558 ExtendedFilePickerElementIds::CHECKBOX_PASSWORD,
559 pCurrentFilter && ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_ENCRYPTION )
562 if( bInit )
564 // in case of inintialization previous state is not interesting
565 if( mbIsPwdEnabled )
567 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
568 if( mbPwdCheckBoxState )
569 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
572 else if( !bWasEnabled && mbIsPwdEnabled )
574 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
575 if( mbPwdCheckBoxState )
576 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
578 else if( bWasEnabled && !mbIsPwdEnabled )
580 // remember user settings until checkbox is enabled
581 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
582 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
583 sal_Bool bPassWord = sal_False;
584 mbPwdCheckBoxState = ( aValue >>= bPassWord ) && bPassWord;
585 xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_False ) );
589 // ------------------------------------------------------------------------
590 void FileDialogHelper_Impl::updatePreviewState( sal_Bool _bUpdatePreviewWindow )
592 if ( mbHasPreview )
594 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
596 // check, whether or not we have to display a preview
597 if ( xCtrlAccess.is() )
601 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
602 sal_Bool bShowPreview = sal_False;
604 if ( aValue >>= bShowPreview )
606 mbShowPreview = bShowPreview;
608 // setShowState has currently no effect for the
609 // OpenOffice FilePicker (see svtools/source/filepicker/iodlg.cxx)
610 uno::Reference< XFilePreview > xFilePreview( mxFileDlg, UNO_QUERY );
611 if ( xFilePreview.is() )
612 xFilePreview->setShowState( mbShowPreview );
614 if ( _bUpdatePreviewWindow )
615 TimeOutHdl_Impl( NULL );
618 catch( const Exception& )
620 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::updatePreviewState: caught an exception!" );
626 // ------------------------------------------------------------------------
627 void FileDialogHelper_Impl::updateVersions()
629 Sequence < OUString > aEntries;
630 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
632 if ( aPathSeq.getLength() == 1 )
634 INetURLObject aObj( aPathSeq[0] );
636 if ( ( aObj.GetProtocol() == INET_PROT_FILE ) &&
637 ( utl::UCBContentHelper::IsDocument( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) )
641 uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
642 aObj.GetMainURL( INetURLObject::NO_DECODE ),
643 embed::ElementModes::READ );
645 DBG_ASSERT( xStorage.is(), "The method must return the storage or throw an exception!" );
646 if ( !xStorage.is() )
647 throw uno::RuntimeException();
649 uno::Sequence < util::RevisionTag > xVersions = SfxMedium::GetVersionList( xStorage );
651 aEntries.realloc( xVersions.getLength() + 1 );
652 aEntries[0] = SfxResId( STR_SFX_FILEDLG_ACTUALVERSION ).toString();
654 for ( sal_Int32 i=0; i<xVersions.getLength(); i++ )
655 aEntries[ i + 1 ] = xVersions[i].Identifier;
657 catch( const uno::Exception& )
663 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
664 Any aValue;
668 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
669 ControlActions::DELETE_ITEMS, aValue );
671 catch( const IllegalArgumentException& ){}
673 sal_Int32 nCount = aEntries.getLength();
675 if ( nCount )
679 aValue <<= aEntries;
680 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
681 ControlActions::ADD_ITEMS, aValue );
683 Any aPos;
684 aPos <<= (sal_Int32) 0;
685 xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
686 ControlActions::SET_SELECT_ITEM, aPos );
688 catch( const IllegalArgumentException& ){}
692 // -----------------------------------------------------------------------
693 IMPL_LINK_NOARG(FileDialogHelper_Impl, TimeOutHdl_Impl)
695 if ( !mbHasPreview )
696 return 0;
698 maGraphic.Clear();
700 Any aAny;
701 uno::Reference < XFilePreview > xFilePicker( mxFileDlg, UNO_QUERY );
703 if ( ! xFilePicker.is() )
704 return 0;
706 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
708 if ( mbShowPreview && ( aPathSeq.getLength() == 1 ) )
710 OUString aURL = aPathSeq[0];
712 if ( ERRCODE_NONE == getGraphic( aURL, maGraphic ) )
714 // changed the code slightly;
715 // before: the bitmap was scaled and
716 // surrounded a white frame
717 // now: the bitmap will only be scaled
718 // and the filepicker implementation
719 // is responsible for placing it at its
720 // proper position and painting a frame
722 Bitmap aBmp = maGraphic.GetBitmap();
723 if ( !aBmp.IsEmpty() )
725 // scale the bitmap to the correct size
726 sal_Int32 nOutWidth = xFilePicker->getAvailableWidth();
727 sal_Int32 nOutHeight = xFilePicker->getAvailableHeight();
728 sal_Int32 nBmpWidth = aBmp.GetSizePixel().Width();
729 sal_Int32 nBmpHeight = aBmp.GetSizePixel().Height();
731 double nXRatio = (double) nOutWidth / nBmpWidth;
732 double nYRatio = (double) nOutHeight / nBmpHeight;
734 if ( nXRatio < nYRatio )
735 aBmp.Scale( nXRatio, nXRatio );
736 else
737 aBmp.Scale( nYRatio, nYRatio );
739 // Convert to true color, to allow CopyPixel
740 aBmp.Convert( BMP_CONVERSION_24BIT );
742 // and copy it into the Any
743 SvMemoryStream aData;
745 aData << aBmp;
747 const Sequence < sal_Int8 > aBuffer(
748 static_cast< const sal_Int8* >(aData.GetData()),
749 aData.GetEndOfData() );
751 aAny <<= aBuffer;
758 SolarMutexReleaser aReleaseForCallback;
759 // clear the preview window
760 xFilePicker->setImage( FilePreviewImageFormats::BITMAP, aAny );
762 catch( const IllegalArgumentException& )
766 return 0;
769 // ------------------------------------------------------------------------
770 ErrCode FileDialogHelper_Impl::getGraphic( const OUString& rURL,
771 Graphic& rGraphic ) const
773 if ( utl::UCBContentHelper::IsFolder( rURL ) )
774 return ERRCODE_IO_NOTAFILE;
776 if ( !mpGraphicFilter )
777 return ERRCODE_IO_NOTSUPPORTED;
779 // select graphic filter from dialog filter selection
780 OUString aCurFilter( getFilter() );
782 sal_uInt16 nFilter = !aCurFilter.isEmpty() && mpGraphicFilter->GetImportFormatCount()
783 ? mpGraphicFilter->GetImportFormatNumber( aCurFilter )
784 : GRFILTER_FORMAT_DONTKNOW;
786 INetURLObject aURLObj( rURL );
788 if ( aURLObj.HasError() || INET_PROT_NOT_VALID == aURLObj.GetProtocol() )
790 aURLObj.SetSmartProtocol( INET_PROT_FILE );
791 aURLObj.SetSmartURL( rURL );
794 ErrCode nRet = ERRCODE_NONE;
796 sal_uInt32 nFilterImportFlags = GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
797 // non-local?
798 if ( INET_PROT_FILE != aURLObj.GetProtocol() )
800 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( rURL, STREAM_READ );
802 if( pStream )
803 nRet = mpGraphicFilter->ImportGraphic( rGraphic, rURL, *pStream, nFilter, NULL, nFilterImportFlags );
804 else
805 nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
806 delete pStream;
808 else
810 nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
813 return nRet;
816 // ------------------------------------------------------------------------
817 ErrCode FileDialogHelper_Impl::getGraphic( Graphic& rGraphic ) const
819 ErrCode nRet = ERRCODE_NONE;
821 if ( ! maGraphic )
823 OUString aPath;;
824 Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
826 if ( aPathSeq.getLength() == 1 )
828 aPath = aPathSeq[0];
831 if ( !aPath.isEmpty() )
832 nRet = getGraphic( aPath, rGraphic );
833 else
834 nRet = ERRCODE_IO_GENERAL;
836 else
837 rGraphic = maGraphic;
839 return nRet;
842 // ------------------------------------------------------------------------
843 static bool lcl_isSystemFilePicker( const uno::Reference< XFilePicker >& _rxFP )
847 uno::Reference< XServiceInfo > xSI( _rxFP, UNO_QUERY );
848 if ( !xSI.is() )
849 return true;
850 return xSI->supportsService( "com.sun.star.ui.dialogs.SystemFilePicker" );
852 catch( const Exception& )
855 return false;
858 enum open_or_save_t {OPEN, SAVE, UNDEFINED};
859 static open_or_save_t lcl_OpenOrSave(sal_Int16 const nDialogType)
861 switch (nDialogType)
863 case FILEOPEN_SIMPLE:
864 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
865 case FILEOPEN_PLAY:
866 case FILEOPEN_READONLY_VERSION:
867 case FILEOPEN_LINK_PREVIEW:
868 return OPEN;
869 case FILESAVE_SIMPLE:
870 case FILESAVE_AUTOEXTENSION_PASSWORD:
871 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
872 case FILESAVE_AUTOEXTENSION_SELECTION:
873 case FILESAVE_AUTOEXTENSION_TEMPLATE:
874 case FILESAVE_AUTOEXTENSION:
875 return SAVE;
876 default:
877 assert(false); // invalid dialog type
879 return UNDEFINED;
882 // ------------------------------------------------------------------------
883 // ----------- FileDialogHelper_Impl ---------------------------
884 // ------------------------------------------------------------------------
886 FileDialogHelper_Impl::FileDialogHelper_Impl(
887 FileDialogHelper* _pAntiImpl,
888 sal_Int16 nDialogType,
889 sal_Int64 nFlags,
890 sal_Int16 nDialog,
891 Window* _pPreferredParentWindow,
892 const String& sStandardDir,
893 const ::com::sun::star::uno::Sequence< OUString >& rBlackList
895 :m_nDialogType ( nDialogType )
896 ,meContext ( FileDialogHelper::UNKNOWN_CONTEXT )
898 const char* pServiceName=0;
899 if ( nDialog == SFX2_IMPL_DIALOG_SYSTEM )
900 pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
901 else if ( nDialog == SFX2_IMPL_DIALOG_OOO )
902 pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
903 else
904 pServiceName = "com.sun.star.ui.dialogs.FilePicker";
905 OUString aService = OUString::createFromAscii( pServiceName );
907 uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
909 // create the file open dialog
910 // the flags can be SFXWB_INSERT or SFXWB_MULTISELECTION
912 mpPreferredParentWindow = _pPreferredParentWindow;
913 mpAntiImpl = _pAntiImpl;
914 mnError = ERRCODE_NONE;
915 mbHasAutoExt = sal_False;
916 mbHasPassword = sal_False;
917 m_bHaveFilterOptions = sal_False;
918 mbIsPwdEnabled = sal_True;
919 mbHasVersions = sal_False;
920 mbHasPreview = sal_False;
921 mbShowPreview = sal_False;
922 mbAddGraphicFilter = SFXWB_GRAPHIC == (nFlags & SFXWB_GRAPHIC);
923 mbDeleteMatcher = sal_False;
924 mbInsert = SFXWB_INSERT == ( nFlags & SFXWB_INSERT );
925 mbExport = SFXWB_EXPORT == ( nFlags & SFXWB_EXPORT );
926 mbIsSaveDlg = sal_False;
927 mbIsSaveACopyDlg = SFXWB_SAVEACOPY == ( nFlags & SFXWB_SAVEACOPY );
928 mbPwdCheckBoxState = sal_False;
929 mbSelection = sal_False;
930 mbSelectionEnabled = sal_True;
931 mbHasSelectionBox = sal_False;
932 mbSelectionFltrEnabled = sal_False;
934 // default settings
935 m_nDontFlags = SFX_FILTER_INTERNAL | SFX_FILTER_NOTINFILEDLG | SFX_FILTER_NOTINSTALLED;
936 if (OPEN == lcl_OpenOrSave(m_nDialogType))
937 m_nMustFlags = SFX_FILTER_IMPORT;
938 else
939 m_nMustFlags = SFX_FILTER_EXPORT;
942 mpMatcher = NULL;
943 mpGraphicFilter = NULL;
944 mnPostUserEventId = 0;
946 // create the picker component
947 mxFileDlg = mxFileDlg.query( xFactory->createInstance( aService ) );
948 mbSystemPicker = lcl_isSystemFilePicker( mxFileDlg );
950 uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
951 uno::Reference< XInitialization > xInit( mxFileDlg, UNO_QUERY );
953 if ( ! mxFileDlg.is() || ! xNotifier.is() )
955 mnError = ERRCODE_ABORT;
956 return;
960 if ( xInit.is() )
962 sal_Int16 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
964 switch ( m_nDialogType )
966 case FILEOPEN_SIMPLE:
967 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
968 break;
970 case FILESAVE_SIMPLE:
971 nTemplateDescription = TemplateDescription::FILESAVE_SIMPLE;
972 mbIsSaveDlg = sal_True;
973 break;
975 case FILESAVE_AUTOEXTENSION_PASSWORD:
976 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD;
977 mbHasPassword = sal_True;
978 mbHasAutoExt = sal_True;
979 mbIsSaveDlg = sal_True;
980 break;
982 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
983 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS;
984 mbHasPassword = sal_True;
986 m_bHaveFilterOptions = sal_True;
987 if( xFactory.is() )
989 mxFilterCFG = uno::Reference< XNameAccess >(
990 xFactory->createInstance( "com.sun.star.document.FilterFactory" ),
991 UNO_QUERY );
994 mbHasAutoExt = sal_True;
995 mbIsSaveDlg = sal_True;
996 break;
998 case FILESAVE_AUTOEXTENSION_SELECTION:
999 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION;
1000 mbHasAutoExt = sal_True;
1001 mbIsSaveDlg = sal_True;
1002 mbHasSelectionBox = sal_True;
1003 if ( mbExport && !mxFilterCFG.is() && xFactory.is() )
1005 mxFilterCFG = uno::Reference< XNameAccess >(
1006 xFactory->createInstance( "com.sun.star.document.FilterFactory" ),
1007 UNO_QUERY );
1009 break;
1011 case FILESAVE_AUTOEXTENSION_TEMPLATE:
1012 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE;
1013 mbHasAutoExt = sal_True;
1014 mbIsSaveDlg = sal_True;
1015 break;
1017 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
1018 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE;
1019 mbHasPreview = sal_True;
1021 // aPreviewTimer
1022 maPreViewTimer.SetTimeout( 500 );
1023 maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1024 break;
1026 case FILEOPEN_PLAY:
1027 nTemplateDescription = TemplateDescription::FILEOPEN_PLAY;
1028 break;
1030 case FILEOPEN_READONLY_VERSION:
1031 nTemplateDescription = TemplateDescription::FILEOPEN_READONLY_VERSION;
1032 mbHasVersions = sal_True;
1033 break;
1035 case FILEOPEN_LINK_PREVIEW:
1036 nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW;
1037 mbHasPreview = sal_True;
1038 // aPreviewTimer
1039 maPreViewTimer.SetTimeout( 500 );
1040 maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1041 break;
1043 case FILESAVE_AUTOEXTENSION:
1044 nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION;
1045 mbHasAutoExt = sal_True;
1046 mbIsSaveDlg = sal_True;
1047 break;
1049 default:
1050 SAL_WARN( "sfx2.dialog", "FileDialogHelper::ctor with unknown type" );
1051 break;
1054 Sequence < Any > aInitArguments( !mpPreferredParentWindow ? 3 : 4 );
1056 // This is a hack. We currently know that the internal file picker implementation
1057 // supports the extended arguments as specified below.
1058 // TODO:
1059 // a) adjust the service description so that it includes the TemplateDescription and ParentWindow args
1060 // b) adjust the implementation of the system file picker to that it recognizes it
1061 if ( mbSystemPicker )
1063 aInitArguments[0] <<= nTemplateDescription;
1065 else
1067 aInitArguments[0] <<= NamedValue(
1068 OUString( "TemplateDescription" ),
1069 makeAny( nTemplateDescription )
1072 OUString sStandardDirTemp = OUString( sStandardDir );
1074 aInitArguments[1] <<= NamedValue(
1075 OUString( "StandardDir" ),
1076 makeAny( sStandardDirTemp )
1079 aInitArguments[2] <<= NamedValue(
1080 OUString( "BlackList" ),
1081 makeAny( rBlackList )
1085 if ( mpPreferredParentWindow )
1086 aInitArguments[3] <<= NamedValue(
1087 OUString( "ParentWindow" ),
1088 makeAny( VCLUnoHelper::GetInterface( mpPreferredParentWindow ) )
1094 xInit->initialize( aInitArguments );
1096 catch( const Exception& )
1098 OSL_FAIL( "FileDialogHelper_Impl::FileDialogHelper_Impl: could not initialize the picker!" );
1103 // set multiselection mode
1104 if ( nFlags & SFXWB_MULTISELECTION )
1105 mxFileDlg->setMultiSelectionMode( sal_True );
1107 if (mbAddGraphicFilter) // generate graphic filter only on demand
1109 addGraphicFilter();
1112 // Export dialog
1113 if ( mbExport )
1115 mxFileDlg->setTitle( SfxResId( STR_SFX_EXPLORERFILE_EXPORT ).toString() );
1116 try {
1117 com::sun::star::uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY_THROW );
1118 xCtrlAccess->enableControl( ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR, sal_True );
1120 catch( const Exception & ) { }
1123 // Save a copy dialog
1124 if ( mbIsSaveACopyDlg )
1126 mxFileDlg->setTitle( SfxResId( STR_PB_SAVEACOPY ).toString() );
1129 // the "insert file" dialog needs another title
1130 if ( mbInsert )
1132 mxFileDlg->setTitle( SfxResId( STR_SFX_EXPLORERFILE_INSERT ).toString() );
1133 uno::Reference < XFilePickerControlAccess > xExtDlg( mxFileDlg, UNO_QUERY );
1134 if ( xExtDlg.is() )
1138 xExtDlg->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK,
1139 SfxResId( STR_SFX_EXPLORERFILE_BUTTONINSERT ).toString() );
1141 catch( const IllegalArgumentException& ){}
1145 // add the event listener
1146 xNotifier->addFilePickerListener( this );
1149 // ------------------------------------------------------------------------
1150 FileDialogHelper_Impl::~FileDialogHelper_Impl()
1152 // Remove user event if we haven't received it yet
1153 if ( mnPostUserEventId )
1154 Application::RemoveUserEvent( mnPostUserEventId );
1155 mnPostUserEventId = 0;
1157 delete mpGraphicFilter;
1159 if ( mbDeleteMatcher )
1160 delete mpMatcher;
1162 maPreViewTimer.SetTimeoutHdl( Link() );
1164 ::comphelper::disposeComponent( mxFileDlg );
1167 #define nMagic -1
1169 class PickerThread_Impl : public ::osl::Thread
1171 uno::Reference < XFilePicker > mxPicker;
1172 ::osl::Mutex maMutex;
1173 virtual void SAL_CALL run();
1174 sal_Int16 mnRet;
1175 public:
1176 PickerThread_Impl( const uno::Reference < XFilePicker >& rPicker )
1177 : mxPicker( rPicker ), mnRet(nMagic) {}
1179 sal_Int16 GetReturnValue()
1180 { ::osl::MutexGuard aGuard( maMutex ); return mnRet; }
1182 void SetReturnValue( sal_Int16 aRetValue )
1183 { ::osl::MutexGuard aGuard( maMutex ); mnRet = aRetValue; }
1186 void SAL_CALL PickerThread_Impl::run()
1190 sal_Int16 n = mxPicker->execute();
1191 SetReturnValue( n );
1193 catch( const RuntimeException& )
1195 SetReturnValue( ExecutableDialogResults::CANCEL );
1196 SAL_WARN( "sfx2.dialog", "RuntimeException caught" );
1200 // ------------------------------------------------------------------------
1201 void FileDialogHelper_Impl::setControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
1203 DBG_ASSERT( _pControlId && _pHelpId, "FileDialogHelper_Impl::setControlHelpIds: invalid array pointers!" );
1204 if ( !_pControlId || !_pHelpId )
1205 return;
1207 // forward these ids to the file picker
1210 const OUString sHelpIdPrefix( INET_HID_SCHEME );
1211 // the ids for the single controls
1212 uno::Reference< XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1213 if ( xControlAccess.is() )
1215 while ( *_pControlId )
1217 DBG_ASSERT( INetURLObject( OStringToOUString( *_pHelpId, RTL_TEXTENCODING_UTF8 ) ).GetProtocol() == INET_PROT_NOT_VALID, "Wrong HelpId!" );
1218 OUString sId( sHelpIdPrefix );
1219 sId += OUString( *_pHelpId, strlen( *_pHelpId ), RTL_TEXTENCODING_UTF8 );
1220 xControlAccess->setValue( *_pControlId, ControlActions::SET_HELP_URL, makeAny( sId ) );
1222 ++_pControlId; ++_pHelpId;
1226 catch( const Exception& )
1228 OSL_FAIL( "FileDialogHelper_Impl::setControlHelpIds: caught an exception while setting the help ids!" );
1232 // ------------------------------------------------------------------------
1233 IMPL_LINK( FileDialogHelper_Impl, InitControls, void*, NOTINTERESTEDIN )
1235 (void)NOTINTERESTEDIN;
1236 mnPostUserEventId = 0;
1237 enablePasswordBox( sal_True );
1238 updateFilterOptionsBox( );
1239 updateSelectionBox( );
1241 return 0L;
1244 // ------------------------------------------------------------------------
1245 void FileDialogHelper_Impl::preExecute()
1247 loadConfig( );
1248 setDefaultValues( );
1249 updatePreviewState( sal_False );
1251 implInitializeFileName( );
1253 #if !(defined(MACOSX) && defined(MACOSX)) && !defined(WNT)
1254 // allow for dialog implementations which need to be executed before they return valid values for
1255 // current filter and such
1257 // On Vista (at least SP1) it's the same as on MacOSX, the modal dialog won't let message pass
1258 // through before it returns from execution
1259 mnPostUserEventId = Application::PostUserEvent( LINK( this, FileDialogHelper_Impl, InitControls ) );
1260 #else
1261 // However, the Mac OS X implementation's pickers run modally in execute and so the event doesn't
1262 // get through in time... so we call the methods directly
1263 enablePasswordBox( sal_True );
1264 updateFilterOptionsBox( );
1265 updateSelectionBox( );
1266 #endif
1269 // ------------------------------------------------------------------------
1270 void FileDialogHelper_Impl::postExecute( sal_Int16 _nResult )
1272 if ( ExecutableDialogResults::CANCEL != _nResult )
1273 saveConfig();
1276 // ------------------------------------------------------------------------
1277 void FileDialogHelper_Impl::implInitializeFileName( )
1279 if ( !maFileName.isEmpty() )
1281 INetURLObject aObj( maPath );
1282 aObj.Append( maFileName );
1284 // in case we're operating as save dialog, and "auto extension" is checked,
1285 // cut the extension from the name
1286 if ( mbIsSaveDlg && mbHasAutoExt )
1290 sal_Bool bAutoExtChecked = sal_False;
1292 uno::Reference < XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1293 if ( xControlAccess.is()
1294 && ( xControlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 )
1295 >>= bAutoExtChecked
1299 if ( bAutoExtChecked )
1300 { // cut the extension
1301 aObj.removeExtension( );
1302 mxFileDlg->setDefaultName( aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) );
1306 catch( const Exception& )
1308 OSL_FAIL( "FileDialogHelper_Impl::implInitializeFileName: could not ask for the auto-extension current-value!" );
1314 // ------------------------------------------------------------------------
1315 sal_Int16 FileDialogHelper_Impl::implDoExecute()
1317 preExecute();
1319 sal_Int16 nRet = ExecutableDialogResults::CANCEL;
1321 //On MacOSX the native file picker has to run in the primordial thread because of drawing issues
1322 //On Linux the native gtk file picker, when backed by gnome-vfs2, needs to be run in the same
1323 //primordial thread as the ucb gnome-vfs2 provider was initialized in.
1328 #ifdef WNT
1329 if ( mbSystemPicker )
1331 SolarMutexReleaser aSolarMutex;
1332 nRet = mxFileDlg->execute();
1334 else
1335 #endif
1336 nRet = mxFileDlg->execute();
1338 catch( const Exception& )
1340 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1344 postExecute( nRet );
1346 return nRet;
1349 // ------------------------------------------------------------------------
1350 void FileDialogHelper_Impl::implStartExecute()
1352 DBG_ASSERT( mxFileDlg.is(), "invalid file dialog" );
1354 preExecute();
1356 if ( mbSystemPicker )
1359 else
1363 uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( mxFileDlg, UNO_QUERY );
1364 if ( xAsyncDlg.is() )
1365 xAsyncDlg->startExecuteModal( this );
1367 catch( const Exception& )
1369 SAL_WARN( "sfx2.dialog", "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1374 // ------------------------------------------------------------------------
1375 void lcl_saveLastURLs(std::vector<OUString>& rpURLList,
1376 ::comphelper::SequenceAsVector< OUString >& lLastURLs )
1378 lLastURLs.clear();
1379 for(std::vector<OUString>::iterator i = rpURLList.begin(); i != rpURLList.end(); ++i)
1380 lLastURLs.push_back(*i);
1383 // ------------------------------------------------------------------------
1384 void FileDialogHelper_Impl::implGetAndCacheFiles(const uno::Reference< XInterface >& xPicker, std::vector<OUString>& rpURLList, const SfxFilter* pFilter)
1386 rpURLList.clear();
1388 OUString sExtension;
1389 if (pFilter)
1391 sExtension = pFilter->GetDefaultExtension ();
1392 sExtension = comphelper::string::remove(sExtension, '*');
1393 sExtension = comphelper::string::remove(sExtension, '.');
1396 // a) the new way (optional!)
1397 uno::Reference< XFilePicker2 > xPickNew(xPicker, UNO_QUERY);
1398 if (xPickNew.is())
1400 Sequence< OUString > lFiles = xPickNew->getSelectedFiles();
1401 ::sal_Int32 nFiles = lFiles.getLength();
1402 for(sal_Int32 i = 0; i < nFiles; ++i)
1403 rpURLList.push_back(lFiles[i]);
1406 // b) the olde way ... non optional.
1407 else
1409 uno::Reference< XFilePicker > xPickOld(xPicker, UNO_QUERY_THROW);
1410 Sequence< OUString > lFiles = xPickOld->getFiles();
1411 ::sal_Int32 nFiles = lFiles.getLength();
1412 if ( nFiles == 1 )
1414 rpURLList.push_back(lFiles[0]);
1416 else if ( nFiles > 1 )
1418 INetURLObject aPath( lFiles[0] );
1419 aPath.setFinalSlash();
1421 for (::sal_Int32 i = 1; i < nFiles; i++)
1423 if (i == 1)
1424 aPath.Append( lFiles[i] );
1425 else
1426 aPath.setName( lFiles[i] );
1428 rpURLList.push_back(aPath.GetMainURL(INetURLObject::NO_DECODE));
1433 lcl_saveLastURLs(rpURLList, mlLastURLs);
1436 // ------------------------------------------------------------------------
1437 ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList,
1438 SfxItemSet *& rpSet,
1439 String& rFilter )
1441 // rFilter is a pure output parameter, it shouldn't be used for anything else
1442 // changing this would surely break code
1443 // rpSet is in/out parameter, usually just a media-descriptor that can be changed by dialog
1445 uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
1447 // retrieves parameters from rpSet
1448 // for now only Password is used
1449 if ( rpSet )
1451 // check password checkbox if the document had password before
1452 if( mbHasPassword )
1454 SFX_ITEMSET_ARG( rpSet, pPassItem, SfxBoolItem, SID_PASSWORDINTERACTION, sal_False );
1455 mbPwdCheckBoxState = ( pPassItem != NULL && pPassItem->GetValue() );
1457 // in case the document has password to modify, the dialog should be shown
1458 SFX_ITEMSET_ARG( rpSet, pPassToModifyItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, sal_False );
1459 mbPwdCheckBoxState |= ( pPassToModifyItem && pPassToModifyItem->GetValue().hasValue() );
1462 SFX_ITEMSET_ARG( rpSet, pSelectItem, SfxBoolItem, SID_SELECTION, sal_False );
1463 if ( pSelectItem )
1464 mbSelection = pSelectItem->GetValue();
1465 else
1466 mbSelectionEnabled = sal_False;
1468 // the password will be set in case user decide so
1469 rpSet->ClearItem( SID_PASSWORDINTERACTION );
1470 rpSet->ClearItem( SID_PASSWORD );
1471 rpSet->ClearItem( SID_ENCRYPTIONDATA );
1472 rpSet->ClearItem( SID_RECOMMENDREADONLY );
1473 rpSet->ClearItem( SID_MODIFYPASSWORDINFO );
1477 if ( mbHasPassword && !mbPwdCheckBoxState )
1479 SvtSecurityOptions aSecOpt;
1480 mbPwdCheckBoxState = (
1481 aSecOpt.IsOptionSet( SvtSecurityOptions::E_DOCWARN_RECOMMENDPASSWORD ) );
1484 rpURLList.clear();
1486 if ( ! mxFileDlg.is() )
1487 return ERRCODE_ABORT;
1489 if ( ExecutableDialogResults::CANCEL != implDoExecute() )
1491 // create an itemset if there is no
1492 if( !rpSet )
1493 rpSet = new SfxAllItemSet( SFX_APP()->GetPool() );
1495 // the item should remain only if it was set by the dialog
1496 rpSet->ClearItem( SID_SELECTION );
1498 if( mbExport && mbHasSelectionBox )
1502 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
1503 sal_Bool bSelection = sal_False;
1504 if ( aValue >>= bSelection )
1505 rpSet->Put( SfxBoolItem( SID_SELECTION, bSelection ) );
1507 catch( const IllegalArgumentException& )
1509 OSL_FAIL( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1514 // set the read-only flag. When inserting a file, this flag is always set
1515 if ( mbInsert )
1516 rpSet->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
1517 else
1519 if ( ( FILEOPEN_READONLY_VERSION == m_nDialogType ) && xCtrlAccess.is() )
1523 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 );
1524 sal_Bool bReadOnly = sal_False;
1525 if ( ( aValue >>= bReadOnly ) && bReadOnly )
1526 rpSet->Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
1528 catch( const IllegalArgumentException& )
1530 OSL_FAIL( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1534 if ( mbHasVersions && xCtrlAccess.is() )
1538 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
1539 ControlActions::GET_SELECTED_ITEM_INDEX );
1540 sal_Int32 nVersion = 0;
1541 if ( ( aValue >>= nVersion ) && nVersion > 0 )
1542 // open a special version; 0 == current version
1543 rpSet->Put( SfxInt16Item( SID_VERSION, (short)nVersion ) );
1545 catch( const IllegalArgumentException& ){}
1548 // set the filter
1549 getRealFilter( rFilter );
1551 const SfxFilter* pCurrentFilter = getCurentSfxFilter();
1553 // fill the rpURLList
1554 implGetAndCacheFiles( mxFileDlg, rpURLList, pCurrentFilter );
1555 if ( rpURLList.empty() )
1556 return ERRCODE_ABORT;
1558 // check, whether or not we have to display a password box
1559 if ( pCurrentFilter && mbHasPassword && mbIsPwdEnabled && xCtrlAccess.is() )
1563 Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
1564 sal_Bool bPassWord = sal_False;
1565 if ( ( aValue >>= bPassWord ) && bPassWord )
1567 // ask for a password
1568 OUString aDocName(rpURLList[0]);
1569 ErrCode errCode = RequestPassword(pCurrentFilter, aDocName, rpSet);
1570 if (errCode != ERRCODE_NONE)
1571 return errCode;
1574 catch( const IllegalArgumentException& ){}
1577 SaveLastUsedFilter();
1578 return ERRCODE_NONE;
1580 else
1581 return ERRCODE_ABORT;
1584 // ------------------------------------------------------------------------
1585 ErrCode FileDialogHelper_Impl::execute()
1587 if ( ! mxFileDlg.is() )
1588 return ERRCODE_ABORT;
1590 sal_Int16 nRet = implDoExecute();
1592 maPath = mxFileDlg->getDisplayDirectory();
1594 if ( ExecutableDialogResults::CANCEL == nRet )
1595 return ERRCODE_ABORT;
1596 else
1598 return ERRCODE_NONE;
1602 // ------------------------------------------------------------------------
1603 OUString FileDialogHelper_Impl::getPath() const
1605 OUString aPath;
1607 if ( mxFileDlg.is() )
1608 aPath = mxFileDlg->getDisplayDirectory();
1610 if ( aPath.isEmpty() )
1611 aPath = maPath;
1613 return aPath;
1616 // ------------------------------------------------------------------------
1617 OUString FileDialogHelper_Impl::getFilter() const
1619 String aFilter = getCurrentFilterUIName();
1621 if( !aFilter.Len() )
1622 aFilter = maCurFilter;
1624 return aFilter;
1627 // ------------------------------------------------------------------------
1628 void FileDialogHelper_Impl::getRealFilter( String& _rFilter ) const
1630 _rFilter = getCurrentFilterUIName();
1632 if ( !_rFilter.Len() )
1633 _rFilter = maCurFilter;
1635 if ( _rFilter.Len() && mpMatcher )
1637 const SfxFilter* pFilter =
1638 mpMatcher->GetFilter4UIName( _rFilter, m_nMustFlags, m_nDontFlags );
1639 _rFilter = pFilter ? String(pFilter->GetFilterName()) : _rFilter.Erase();
1643 void FileDialogHelper_Impl::verifyPath()
1645 #ifdef UNX
1646 // lp#905355, fdo#43895
1647 // Check that the file has read only permission and is in /tmp -- this is
1648 // the case if we have opened the file from the web with firefox only.
1649 if (maFileName.isEmpty()) {
1650 return;
1652 INetURLObject url(maPath);
1653 if (url.GetProtocol() != INET_PROT_FILE
1654 || url.getName(0, true, INetURLObject::DECODE_WITH_CHARSET) != "tmp")
1656 return;
1658 if (maFileName.indexOf('/') != -1) {
1659 SAL_WARN("sfx2.dialog", maFileName << " contains /");
1660 return;
1662 url.insertName(
1663 maFileName, false, INetURLObject::LAST_SEGMENT, true,
1664 INetURLObject::ENCODE_ALL);
1665 OUString sysPathU;
1666 osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL(
1667 url.GetMainURL(INetURLObject::NO_DECODE), sysPathU);
1668 if (e != osl::FileBase::E_None) {
1669 SAL_WARN(
1670 "sfx2.dialog",
1671 "getSystemPathFromFileURL("
1672 << url.GetMainURL(INetURLObject::NO_DECODE) << ") failed with "
1673 << +e);
1674 return;
1676 OString sysPathC;
1677 if (!sysPathU.convertToString(
1678 &sysPathC, osl_getThreadTextEncoding(),
1679 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
1680 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1682 SAL_WARN(
1683 "sfx2.dialog",
1684 "convertToString(" << sysPathU << ") failed for encoding "
1685 << +osl_getThreadTextEncoding());
1686 return;
1688 struct stat aFileStat;
1689 if (stat(sysPathC.getStr(), &aFileStat) == -1) {
1690 SAL_WARN(
1691 "sfx2.dialog",
1692 "stat(" << sysPathC.getStr() << ") failed with errno " << errno);
1693 return;
1695 if ((aFileStat.st_mode & (S_IRWXO | S_IRWXG | S_IRWXU)) == S_IRUSR) {
1696 maPath = SvtPathOptions().GetWorkPath();
1697 mxFileDlg->setDisplayDirectory( maPath );
1699 #endif
1702 // ------------------------------------------------------------------------
1703 void FileDialogHelper_Impl::displayFolder( const OUString& _rPath )
1705 if ( _rPath.isEmpty() )
1706 // nothing to do
1707 return;
1709 maPath = _rPath;
1710 if ( mxFileDlg.is() )
1714 mxFileDlg->setDisplayDirectory( maPath );
1715 verifyPath();
1717 catch( const IllegalArgumentException& )
1719 OSL_FAIL( "FileDialogHelper_Impl::displayFolder: caught an exception!" );
1724 // ------------------------------------------------------------------------
1725 void FileDialogHelper_Impl::setFileName( const OUString& _rFile )
1727 maFileName = _rFile;
1728 if ( mxFileDlg.is() )
1732 mxFileDlg->setDefaultName( maFileName );
1733 verifyPath();
1735 catch( const IllegalArgumentException& )
1737 OSL_FAIL( "FileDialogHelper_Impl::setFileName: caught an exception!" );
1742 // ------------------------------------------------------------------------
1743 void FileDialogHelper_Impl::setFilter( const OUString& rFilter )
1745 DBG_ASSERT( rFilter.indexOf(':') == -1, "Old filter name used!");
1747 maCurFilter = rFilter;
1749 if ( !rFilter.isEmpty() && mpMatcher )
1751 const SfxFilter* pFilter = mpMatcher->GetFilter4FilterName(
1752 rFilter, m_nMustFlags, m_nDontFlags );
1753 if ( pFilter )
1754 maCurFilter = pFilter->GetUIName();
1757 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1759 if ( !maCurFilter.isEmpty() && xFltMgr.is() )
1763 xFltMgr->setCurrentFilter( maCurFilter );
1765 catch( const IllegalArgumentException& ){}
1769 // ------------------------------------------------------------------------
1770 void FileDialogHelper_Impl::createMatcher( const String& rFactory )
1772 mpMatcher = new SfxFilterMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
1773 mbDeleteMatcher = sal_True;
1776 // ------------------------------------------------------------------------
1777 void FileDialogHelper_Impl::addFilters( const String& rFactory,
1778 SfxFilterFlags nMust,
1779 SfxFilterFlags nDont )
1781 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1783 if ( ! xFltMgr.is() )
1784 return;
1786 // we still need a matcher to convert UI names to filter names
1787 if ( !rFactory.Len() )
1789 SfxApplication *pSfxApp = SFX_APP();
1790 mpMatcher = &pSfxApp->GetFilterMatcher();
1791 mbDeleteMatcher = sal_False;
1793 else
1795 mpMatcher = new SfxFilterMatcher( rFactory );
1796 mbDeleteMatcher = sal_True;
1799 uno::Reference< XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1800 uno::Reference< XContainerQuery > xFilterCont(
1801 xSMGR->createInstance(OUString("com.sun.star.document.FilterFactory")),
1802 UNO_QUERY);
1803 if ( ! xFilterCont.is() )
1804 return;
1806 m_nMustFlags |= nMust;
1807 m_nDontFlags |= nDont;
1809 // create the list of filters
1810 OUStringBuffer sQuery(256);
1811 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM("getSortedFilterList()"));
1812 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM(":module="));
1813 sQuery.append(rFactory); // use long name here !
1814 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM(":iflags="));
1815 sQuery.append(OUString::valueOf((sal_Int32)m_nMustFlags));
1816 sQuery.appendAscii(RTL_CONSTASCII_STRINGPARAM(":eflags="));
1817 sQuery.append(OUString::valueOf((sal_Int32)m_nDontFlags));
1819 uno::Reference< XEnumeration > xResult;
1822 xResult = xFilterCont->createSubSetEnumerationByQuery(sQuery.makeStringAndClear());
1824 catch( const uno::Exception& )
1826 SAL_WARN( "sfx2.dialog", "Could not get filters from the configuration!" );
1829 TSortedFilterList aIter (xResult);
1831 // no matcher any longer used ...
1832 mbDeleteMatcher = sal_False;
1834 // append the filters
1835 OUString sFirstFilter;
1836 if (OPEN == lcl_OpenOrSave(m_nDialogType))
1837 ::sfx2::appendFiltersForOpen( aIter, xFltMgr, sFirstFilter, *this );
1838 else if ( mbExport )
1839 ::sfx2::appendExportFilters( aIter, xFltMgr, sFirstFilter, *this );
1840 else
1841 ::sfx2::appendFiltersForSave( aIter, xFltMgr, sFirstFilter, *this, rFactory );
1843 // set our initial selected filter (if we do not already have one)
1844 if ( maSelectFilter.isEmpty() )
1845 maSelectFilter = sFirstFilter;
1848 // ------------------------------------------------------------------------
1849 void FileDialogHelper_Impl::addFilter( const OUString& rFilterName,
1850 const OUString& rExtension )
1852 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1854 if ( ! xFltMgr.is() )
1855 return;
1859 xFltMgr->appendFilter( rFilterName, rExtension );
1861 if ( maSelectFilter.isEmpty() )
1862 maSelectFilter = rFilterName;
1864 catch( const IllegalArgumentException& )
1866 SAL_WARN( "sfx2.dialog", "Could not append Filter" << rFilterName );
1870 // ------------------------------------------------------------------------
1871 void FileDialogHelper_Impl::addGraphicFilter()
1873 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1875 if ( ! xFltMgr.is() )
1876 return;
1878 // create the list of filters
1879 mpGraphicFilter = new GraphicFilter;
1880 sal_uInt16 i, j, nCount = mpGraphicFilter->GetImportFormatCount();
1882 // compute the extension string for all known import filters
1883 String aExtensions;
1885 for ( i = 0; i < nCount; i++ )
1887 j = 0;
1888 String sWildcard;
1889 while( true )
1891 sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1892 if ( !sWildcard.Len() )
1893 break;
1894 if ( aExtensions.Search( sWildcard ) == STRING_NOTFOUND )
1896 if ( aExtensions.Len() )
1897 aExtensions += sal_Unicode(';');
1898 aExtensions += sWildcard;
1903 #if defined(WNT)
1904 if ( aExtensions.Len() > 240 )
1905 aExtensions = FILEDIALOG_FILTER_ALL;
1906 #endif
1907 sal_Bool bIsInOpenMode = isInOpenMode();
1911 OUString aAllFilterName = SfxResId( STR_SFX_IMPORT_ALL ).toString();
1912 aAllFilterName = ::sfx2::addExtension( aAllFilterName, aExtensions, bIsInOpenMode, *this );
1914 xFltMgr->appendFilter( aAllFilterName, aExtensions );
1915 maSelectFilter = aAllFilterName;
1917 catch( const IllegalArgumentException& )
1919 SAL_WARN( "sfx2.dialog", "Could not append Filter" );
1922 // Now add the filter
1923 for ( i = 0; i < nCount; i++ )
1925 String aName = mpGraphicFilter->GetImportFormatName( i );
1926 String aExt;
1927 j = 0;
1928 String sWildcard;
1929 while( true )
1931 sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1932 if ( !sWildcard.Len() )
1933 break;
1934 if ( aExt.Search( sWildcard ) == STRING_NOTFOUND )
1936 if ( aExt.Len() )
1937 aExt += sal_Unicode(';');
1938 aExt += sWildcard;
1941 aName = ::sfx2::addExtension( aName, aExt, bIsInOpenMode, *this );
1944 xFltMgr->appendFilter( aName, aExt );
1946 catch( const IllegalArgumentException& )
1948 SAL_WARN( "sfx2.dialog", "Could not append Filter" );
1953 // ------------------------------------------------------------------------
1954 #define GRF_CONFIG_STR " "
1955 #define STD_CONFIG_STR "1 "
1957 void FileDialogHelper_Impl::saveConfig()
1959 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
1960 Any aValue;
1962 if ( ! xDlg.is() )
1963 return;
1965 if ( mbHasPreview )
1967 SvtViewOptions aDlgOpt( E_DIALOG, IMPGRF_CONFIGNAME );
1968 String aUserData = OUString(GRF_CONFIG_STR);
1972 sal_Bool bValue = sal_False;
1973 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
1974 bValue = sal_False;
1975 aValue >>= bValue;
1976 aUserData.SetToken( 1, ' ', OUString::number( (sal_Int32) bValue ) );
1978 INetURLObject aObj( getPath() );
1980 if ( aObj.GetProtocol() == INET_PROT_FILE )
1981 aUserData.SetToken( 2, ' ', aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1983 String aFilter = getFilter();
1984 aFilter = EncodeSpaces_Impl( aFilter );
1985 aUserData.SetToken( 3, ' ', aFilter );
1987 aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
1989 catch( const IllegalArgumentException& ){}
1991 else
1993 sal_Bool bWriteConfig = sal_False;
1994 SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
1995 String aUserData = OUString(STD_CONFIG_STR);
1997 if ( aDlgOpt.Exists() )
1999 Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME );
2000 OUString aTemp;
2001 if ( aUserItem >>= aTemp )
2002 aUserData = String( aTemp );
2005 if ( mbHasAutoExt )
2009 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 );
2010 sal_Bool bAutoExt = sal_True;
2011 aValue >>= bAutoExt;
2012 aUserData.SetToken( 0, ' ', OUString::number( (sal_Int32) bAutoExt ) );
2013 bWriteConfig = sal_True;
2015 catch( const IllegalArgumentException& ){}
2018 if ( ! mbIsSaveDlg )
2020 OUString aPath = getPath();
2021 if ( !aPath.isEmpty() &&
2022 utl::LocalFileHelper::IsLocalFile( aPath ) )
2024 aUserData.SetToken( 1, ' ', aPath );
2025 bWriteConfig = sal_True;
2029 if( mbHasSelectionBox && mbSelectionFltrEnabled )
2033 aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
2034 sal_Bool bSelection = sal_True;
2035 aValue >>= bSelection;
2036 if ( comphelper::string::getTokenCount(aUserData, ' ') < 3 )
2037 aUserData.Append(' ');
2038 aUserData.SetToken( 2, ' ', OUString::number( (sal_Int32) bSelection ) );
2039 bWriteConfig = sal_True;
2041 catch( const IllegalArgumentException& ){}
2044 if ( bWriteConfig )
2045 aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
2048 SfxApplication *pSfxApp = SFX_APP();
2049 pSfxApp->SetLastDir_Impl( getPath() );
2052 // ------------------------------------------------------------------------
2053 namespace
2055 static OUString getInitPath( const String& _rFallback, const xub_StrLen _nFallbackToken )
2057 SfxApplication *pSfxApp = SFX_APP();
2058 String sPath = pSfxApp->GetLastDir_Impl();
2060 if ( !sPath.Len() )
2061 sPath = _rFallback.GetToken( _nFallbackToken, ' ' );
2063 // check if the path points to a valid (accessible) directory
2064 sal_Bool bValid = sal_False;
2065 if ( sPath.Len() )
2067 String sPathCheck( sPath );
2068 if ( sPathCheck.GetBuffer()[ sPathCheck.Len() - 1 ] != '/' )
2069 sPathCheck += '/';
2070 sPathCheck += '.';
2073 ::ucbhelper::Content aContent( sPathCheck, uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
2074 bValid = aContent.isFolder();
2076 catch( const Exception& ) {}
2079 if ( !bValid )
2080 sPath.Erase();
2082 return sPath;
2086 // ------------------------------------------------------------------------
2087 void FileDialogHelper_Impl::loadConfig()
2089 uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
2090 Any aValue;
2092 if ( ! xDlg.is() )
2093 return;
2095 if ( mbHasPreview )
2097 SvtViewOptions aViewOpt( E_DIALOG, IMPGRF_CONFIGNAME );
2098 String aUserData;
2100 if ( aViewOpt.Exists() )
2102 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2103 OUString aTemp;
2104 if ( aUserItem >>= aTemp )
2105 aUserData = String( aTemp );
2108 if ( aUserData.Len() > 0 )
2112 // respect the last "insert as link" state
2113 sal_Bool bLink = (sal_Bool) aUserData.GetToken( 0, ' ' ).ToInt32();
2114 aValue <<= bLink;
2115 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, aValue );
2117 // respect the last "show preview" state
2118 sal_Bool bShowPreview = (sal_Bool) aUserData.GetToken( 1, ' ' ).ToInt32();
2119 aValue <<= bShowPreview;
2120 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, aValue );
2122 if ( maPath.isEmpty() )
2123 displayFolder( getInitPath( aUserData, 2 ) );
2125 if ( maCurFilter.isEmpty() )
2127 String aFilter = aUserData.GetToken( 3, ' ' );
2128 aFilter = DecodeSpaces_Impl( aFilter );
2129 setFilter( aFilter );
2132 // set the member so we know that we have to show the preview
2133 mbShowPreview = bShowPreview;
2135 catch( const IllegalArgumentException& ){}
2138 if ( maPath.isEmpty() )
2139 displayFolder( SvtPathOptions().GetGraphicPath() );
2141 else
2143 SvtViewOptions aViewOpt( E_DIALOG, IODLG_CONFIGNAME );
2144 String aUserData;
2146 if ( aViewOpt.Exists() )
2148 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2149 OUString aTemp;
2150 if ( aUserItem >>= aTemp )
2151 aUserData = String( aTemp );
2154 if ( ! aUserData.Len() )
2155 aUserData = STD_CONFIG_STR;
2157 if ( maPath.isEmpty() )
2158 displayFolder( getInitPath( aUserData, 1 ) );
2160 if ( mbHasAutoExt )
2162 sal_Int32 nFlag = aUserData.GetToken( 0, ' ' ).ToInt32();
2163 aValue <<= (sal_Bool) nFlag;
2166 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue );
2168 catch( const IllegalArgumentException& ){}
2171 if( mbHasSelectionBox )
2173 sal_Int32 nFlag = aUserData.GetToken( 2, ' ' ).ToInt32();
2174 aValue <<= (sal_Bool) nFlag;
2177 xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, aValue );
2179 catch( const IllegalArgumentException& ){}
2182 if ( maPath.isEmpty() )
2183 displayFolder( SvtPathOptions().GetWorkPath() );
2187 // ------------------------------------------------------------------------
2188 void FileDialogHelper_Impl::setDefaultValues()
2190 // when no filter is set, we set the curentFilter to <all>
2191 if ( maCurFilter.isEmpty() && !maSelectFilter.isEmpty() )
2193 uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
2196 xFltMgr->setCurrentFilter( maSelectFilter );
2198 catch( const IllegalArgumentException& )
2202 // when no path is set, we use the standard 'work' folder
2203 if ( maPath.isEmpty() )
2205 OUString aWorkFolder = SvtPathOptions().GetWorkPath();
2208 mxFileDlg->setDisplayDirectory( aWorkFolder );
2210 catch( const Exception& )
2212 OSL_FAIL( "FileDialogHelper_Impl::setDefaultValues: caught an exception while setting the display directory!" );
2217 sal_Bool FileDialogHelper_Impl::isShowFilterExtensionEnabled() const
2219 return !maFilters.empty();
2222 void FileDialogHelper_Impl::addFilterPair( const OUString& rFilter,
2223 const OUString& rFilterWithExtension )
2225 maFilters.push_back( FilterPair( rFilter, rFilterWithExtension ) );
2229 OUString FileDialogHelper_Impl::getFilterName( const OUString& rFilterWithExtension ) const
2231 OUString sRet;
2232 for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2234 if ( (*pIter).Second == rFilterWithExtension )
2236 sRet = (*pIter).First;
2237 break;
2240 return sRet;
2243 OUString FileDialogHelper_Impl::getFilterWithExtension( const OUString& rFilter ) const
2245 OUString sRet;
2246 for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2248 if ( (*pIter).First == rFilter )
2250 sRet = (*pIter).Second;
2251 break;
2254 return sRet;
2257 void FileDialogHelper_Impl::SetContext( FileDialogHelper::Context _eNewContext )
2259 meContext = _eNewContext;
2261 const OUString* pConfigId = GetLastFilterConfigId( _eNewContext );
2262 if( pConfigId )
2263 LoadLastUsedFilter( *pConfigId );
2266 // ------------------------------------------------------------------------
2267 // ----------- FileDialogHelper ---------------------------
2268 // ------------------------------------------------------------------------
2270 FileDialogHelper::FileDialogHelper(
2271 sal_Int16 nDialogType,
2272 sal_Int64 nFlags,
2273 const String& rFact,
2274 SfxFilterFlags nMust,
2275 SfxFilterFlags nDont )
2277 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags );
2278 mxImp = mpImp;
2280 // create the list of filters
2281 mpImp->addFilters(
2282 SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2285 // ------------------------------------------------------------------------
2286 FileDialogHelper::FileDialogHelper(
2287 sal_Int16 nDialogType,
2288 sal_Int64 nFlags,
2289 const String& rFact,
2290 sal_Int16 nDialog,
2291 SfxFilterFlags nMust,
2292 SfxFilterFlags nDont,
2293 const String& rStandardDir,
2294 const ::com::sun::star::uno::Sequence< OUString >& rBlackList)
2296 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, nDialog, NULL, rStandardDir, rBlackList );
2297 mxImp = mpImp;
2299 // create the list of filters
2300 mpImp->addFilters(
2301 SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2304 // ------------------------------------------------------------------------
2305 FileDialogHelper::FileDialogHelper(
2306 sal_Int16 nDialogType,
2307 sal_Int64 nFlags,
2308 Window* _pPreferredParent )
2310 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent );
2311 mxImp = mpImp;
2314 // ------------------------------------------------------------------------
2315 FileDialogHelper::FileDialogHelper(
2316 sal_Int16 nDialogType,
2317 sal_Int64 nFlags,
2318 const OUString& aFilterUIName,
2319 const OUString& aExtName,
2320 const OUString& rStandardDir,
2321 const ::com::sun::star::uno::Sequence< OUString >& rBlackList,
2322 Window* _pPreferredParent )
2324 mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent,rStandardDir, rBlackList );
2325 mxImp = mpImp;
2327 // the wildcard here is expected in form "*.extension"
2328 OUString aWildcard;
2329 if ( aExtName.indexOf( (sal_Unicode)'*' ) != 0 )
2331 if ( !aExtName.isEmpty() && aExtName.indexOf( (sal_Unicode)'.' ) != 0 )
2332 aWildcard = OUString( "*." );
2333 else
2334 aWildcard = OUString( "*" );
2337 aWildcard += aExtName;
2339 OUString const aUIString = ::sfx2::addExtension( aFilterUIName,
2340 aWildcard, (OPEN == lcl_OpenOrSave(mpImp->m_nDialogType)), *mpImp);
2341 AddFilter( aUIString, aWildcard );
2344 // ------------------------------------------------------------------------
2345 FileDialogHelper::~FileDialogHelper()
2347 mpImp->dispose();
2348 mxImp.clear();
2351 // ------------------------------------------------------------------------
2352 void FileDialogHelper::CreateMatcher( const String& rFactory )
2354 mpImp->createMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
2357 // ------------------------------------------------------------------------
2358 void FileDialogHelper::SetControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
2360 mpImp->setControlHelpIds( _pControlId, _pHelpId );
2363 void FileDialogHelper::SetContext( Context _eNewContext )
2365 mpImp->SetContext( _eNewContext );
2368 // ------------------------------------------------------------------------
2369 IMPL_LINK_NOARG(FileDialogHelper, ExecuteSystemFilePicker)
2371 m_nError = mpImp->execute();
2372 if ( m_aDialogClosedLink.IsSet() )
2373 m_aDialogClosedLink.Call( this );
2375 return 0L;
2378 // ------------------------------------------------------------------------
2379 // rDirPath has to be a directory
2380 ErrCode FileDialogHelper::Execute( std::vector<OUString>& rpURLList,
2381 SfxItemSet *& rpSet,
2382 String& rFilter,
2383 const String& rDirPath )
2385 SetDisplayFolder( rDirPath );
2386 return mpImp->execute( rpURLList, rpSet, rFilter );
2390 // ------------------------------------------------------------------------
2391 ErrCode FileDialogHelper::Execute()
2393 return mpImp->execute();
2396 // ------------------------------------------------------------------------
2397 ErrCode FileDialogHelper::Execute( SfxItemSet *& rpSet,
2398 String& rFilter )
2400 ErrCode nRet;
2401 std::vector<OUString> rURLList;
2402 nRet = mpImp->execute(rURLList, rpSet, rFilter);
2403 return nRet;
2406 void FileDialogHelper::StartExecuteModal( const Link& rEndDialogHdl )
2408 m_aDialogClosedLink = rEndDialogHdl;
2409 m_nError = ERRCODE_NONE;
2410 if ( mpImp->isSystemFilePicker() )
2411 Application::PostUserEvent( LINK( this, FileDialogHelper, ExecuteSystemFilePicker ) );
2412 else
2413 mpImp->implStartExecute();
2416 // ------------------------------------------------------------------------
2418 short FileDialogHelper::GetDialogType() const
2420 return mpImp ? mpImp->m_nDialogType : 0;
2423 // ------------------------------------------------------------------------
2425 sal_Bool FileDialogHelper::IsPasswordEnabled() const
2427 return mpImp ? mpImp->isPasswordEnabled() : sal_False;
2430 // ------------------------------------------------------------------------
2432 String FileDialogHelper::GetRealFilter() const
2434 String sFilter;
2435 if ( mpImp )
2436 mpImp->getRealFilter( sFilter );
2437 return sFilter;
2440 // ------------------------------------------------------------------------
2441 void FileDialogHelper::SetTitle( const String& rNewTitle )
2443 if ( mpImp->mxFileDlg.is() )
2444 mpImp->mxFileDlg->setTitle( rNewTitle );
2447 // ------------------------------------------------------------------------
2448 String FileDialogHelper::GetPath() const
2450 OUString aPath;
2452 if ( mpImp->mlLastURLs.size() > 0)
2453 return mpImp->mlLastURLs[0];
2455 if ( mpImp->mxFileDlg.is() )
2457 Sequence < OUString > aPathSeq = mpImp->mxFileDlg->getFiles();
2459 if ( aPathSeq.getLength() == 1 )
2461 aPath = aPathSeq[0];
2465 return aPath;
2468 // ------------------------------------------------------------------------
2469 Sequence < OUString > FileDialogHelper::GetMPath() const
2471 if ( mpImp->mlLastURLs.size() > 0)
2472 return mpImp->mlLastURLs.getAsConstList();
2474 if ( mpImp->mxFileDlg.is() )
2475 return mpImp->mxFileDlg->getFiles();
2476 else
2478 Sequence < OUString > aEmpty;
2479 return aEmpty;
2483 // ------------------------------------------------------------------------
2484 Sequence< OUString > FileDialogHelper::GetSelectedFiles() const
2486 // a) the new way (optional!)
2487 uno::Sequence< OUString > aResultSeq;
2488 uno::Reference< XFilePicker2 > xPickNew(mpImp->mxFileDlg, UNO_QUERY);
2489 if (xPickNew.is())
2491 aResultSeq = xPickNew->getSelectedFiles();
2493 // b) the olde way ... non optional.
2494 else
2496 uno::Reference< XFilePicker > xPickOld(mpImp->mxFileDlg, UNO_QUERY_THROW);
2497 Sequence< OUString > lFiles = xPickOld->getFiles();
2498 ::sal_Int32 nFiles = lFiles.getLength();
2499 if ( nFiles > 1 )
2501 aResultSeq = Sequence< OUString >( nFiles-1 );
2503 INetURLObject aPath( lFiles[0] );
2504 aPath.setFinalSlash();
2506 for (::sal_Int32 i = 1; i < nFiles; i++)
2508 if (i == 1)
2509 aPath.Append( lFiles[i] );
2510 else
2511 aPath.setName( lFiles[i] );
2513 aResultSeq[i-1] = OUString(aPath.GetMainURL( INetURLObject::NO_DECODE ));
2516 else
2517 aResultSeq = lFiles;
2520 return aResultSeq;
2523 // ------------------------------------------------------------------------
2524 String FileDialogHelper::GetDisplayDirectory() const
2526 return mpImp->getPath();
2529 // ------------------------------------------------------------------------
2530 String FileDialogHelper::GetCurrentFilter() const
2532 return mpImp->getFilter();
2535 // ------------------------------------------------------------------------
2536 ErrCode FileDialogHelper::GetGraphic( Graphic& rGraphic ) const
2538 return mpImp->getGraphic( rGraphic );
2541 // ------------------------------------------------------------------------
2542 static int impl_isFolder( const OUString& rPath )
2546 ::ucbhelper::Content aContent(
2547 rPath, uno::Reference< ucb::XCommandEnvironment > (),
2548 comphelper::getProcessComponentContext() );
2549 if ( aContent.isFolder() )
2550 return 1;
2552 return 0;
2554 catch ( const Exception & )
2558 return -1;
2561 void FileDialogHelper::SetDisplayDirectory( const String& _rPath )
2563 if ( !_rPath.Len() )
2564 return;
2566 // if the given path isn't a folder, we cut off the last part
2567 // and take it as filename and the rest of the path should be
2568 // the folder
2570 INetURLObject aObj( _rPath );
2572 OUString sFileName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET );
2573 aObj.removeSegment();
2574 OUString sPath = aObj.GetMainURL( INetURLObject::NO_DECODE );
2576 int nIsFolder = impl_isFolder( _rPath );
2577 if ( nIsFolder == 0 ||
2578 ( nIsFolder == -1 && impl_isFolder( sPath ) == 1 ) )
2580 mpImp->setFileName( sFileName );
2581 mpImp->displayFolder( sPath );
2583 else
2585 INetURLObject aObjPathName( _rPath );
2586 OUString sFolder( aObjPathName.GetMainURL( INetURLObject::NO_DECODE ) );
2587 if ( sFolder.isEmpty() )
2589 // _rPath is not a valid path -> fallback to home directory
2590 osl::Security aSecurity;
2591 aSecurity.getHomeDir( sFolder );
2593 mpImp->displayFolder( sFolder );
2597 // ------------------------------------------------------------------------
2598 void FileDialogHelper::SetDisplayFolder( const String& _rURL )
2600 mpImp->displayFolder( _rURL );
2603 // ------------------------------------------------------------------------
2604 void FileDialogHelper::SetFileName( const String& _rFileName )
2606 mpImp->setFileName( _rFileName );
2609 // ------------------------------------------------------------------------
2610 void FileDialogHelper::AddFilter( const String& rFilterName,
2611 const String& rExtension )
2613 mpImp->addFilter( rFilterName, rExtension );
2616 // ------------------------------------------------------------------------
2617 void FileDialogHelper::SetCurrentFilter( const String& rFilter )
2619 String sFilter( rFilter );
2620 if ( mpImp->isShowFilterExtensionEnabled() )
2621 sFilter = mpImp->getFilterWithExtension( rFilter );
2622 mpImp->setFilter( sFilter );
2625 // ------------------------------------------------------------------------
2626 uno::Reference < XFilePicker > FileDialogHelper::GetFilePicker() const
2628 return mpImp->mxFileDlg;
2631 // ------------------------------------------------------------------------
2632 // XFilePickerListener Methods
2633 // ------------------------------------------------------------------------
2634 void SAL_CALL FileDialogHelper::FileSelectionChanged( const FilePickerEvent& aEvent )
2636 mpImp->handleFileSelectionChanged( aEvent );
2639 // ------------------------------------------------------------------------
2640 void SAL_CALL FileDialogHelper::DirectoryChanged( const FilePickerEvent& aEvent )
2642 mpImp->handleDirectoryChanged( aEvent );
2645 // ------------------------------------------------------------------------
2646 OUString SAL_CALL FileDialogHelper::HelpRequested( const FilePickerEvent& aEvent )
2648 return mpImp->handleHelpRequested( aEvent );
2651 // ------------------------------------------------------------------------
2652 void SAL_CALL FileDialogHelper::ControlStateChanged( const FilePickerEvent& aEvent )
2654 mpImp->handleControlStateChanged( aEvent );
2657 // ------------------------------------------------------------------------
2658 void SAL_CALL FileDialogHelper::DialogSizeChanged()
2660 mpImp->handleDialogSizeChanged();
2663 // ------------------------------------------------------------------------
2664 void SAL_CALL FileDialogHelper::DialogClosed( const DialogClosedEvent& _rEvent )
2666 m_nError = ( RET_OK == _rEvent.DialogResult ) ? ERRCODE_NONE : ERRCODE_ABORT;
2667 if ( m_aDialogClosedLink.IsSet() )
2668 m_aDialogClosedLink.Call( this );
2671 // ------------------------------------------------------------------------
2673 ErrCode FileOpenDialog_Impl( sal_Int16 nDialogType,
2674 sal_Int64 nFlags,
2675 const String& rFact,
2676 std::vector<OUString>& rpURLList,
2677 String& rFilter,
2678 SfxItemSet *& rpSet,
2679 const String* pPath,
2680 sal_Int16 nDialog,
2681 const String& rStandardDir,
2682 const ::com::sun::star::uno::Sequence< OUString >& rBlackList )
2684 ErrCode nRet;
2685 FileDialogHelper aDialog( nDialogType, nFlags,
2686 rFact, nDialog, 0, 0, rStandardDir, rBlackList );
2688 String aPath;
2689 if ( pPath )
2690 aPath = *pPath;
2692 nRet = aDialog.Execute( rpURLList, rpSet, rFilter, aPath );
2693 DBG_ASSERT( rFilter.SearchAscii(": ") == STRING_NOTFOUND, "Old filter name used!");
2695 return nRet;
2698 ErrCode RequestPassword(const SfxFilter* pCurrentFilter, OUString& aURL, SfxItemSet* pSet)
2700 uno::Reference < task::XInteractionHandler2 > xInteractionHandler = task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), 0 );
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[ OUString( "STD97EncryptionKey" ) ] <<= aEncryptionKey;
2727 aHashData[ 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(), 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;
2759 return ERRCODE_NONE;
2762 // ------------------------------------------------------------------------
2763 String EncodeSpaces_Impl( const String& rSource )
2765 OUString sRet( rSource );
2766 sRet = sRet.replaceAll( " ", "%20" );
2767 return sRet;
2770 // ------------------------------------------------------------------------
2771 String DecodeSpaces_Impl( const String& rSource )
2773 OUString sRet( rSource );
2774 sRet = sRet.replaceAll( "%20", " " );
2775 return sRet;
2778 // ------------------------------------------------------------------------
2780 } // end of namespace sfx2
2782 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */