| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sfx2.hxx" |
| |
| #include <sfx2/filedlghelper.hxx> |
| #include <sal/types.h> |
| #include <com/sun/star/lang/XInitialization.hpp> |
| #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> |
| #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> |
| #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> |
| #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp> |
| #include <com/sun/star/ui/dialogs/ControlActions.hpp> |
| #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> |
| #include <com/sun/star/ui/dialogs/XControlInformation.hpp> |
| #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> |
| #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> |
| #include <com/sun/star/ui/dialogs/XFilePreview.hpp> |
| #include <com/sun/star/ui/dialogs/XFilterManager.hpp> |
| #include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp> |
| #include <com/sun/star/ui/dialogs/XFolderPicker.hpp> |
| #include <com/sun/star/ui/dialogs/XFilePicker2.hpp> |
| #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/beans/NamedValue.hpp> |
| #include <com/sun/star/embed/ElementModes.hpp> |
| #include <com/sun/star/container/XEnumeration.hpp> |
| #include <com/sun/star/container/XContainerQuery.hpp> |
| #include <com/sun/star/task/XInteractionRequest.hpp> |
| #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> |
| |
| #include <comphelper/processfactory.hxx> |
| #include <comphelper/types.hxx> |
| #include <comphelper/sequenceashashmap.hxx> |
| #include <comphelper/stillreadwriteinteraction.hxx> |
| #include <tools/urlobj.hxx> |
| #include <vcl/help.hxx> |
| #include <unotools/ucbstreamhelper.hxx> |
| #include <unotools/ucbhelper.hxx> |
| #include <unotools/localfilehelper.hxx> |
| #include <vos/thread.hxx> |
| #include <vos/mutex.hxx> |
| #include <vos/security.hxx> |
| #include <vcl/cvtgrf.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <vcl/mnemonic.hxx> |
| #include <unotools/pathoptions.hxx> |
| #include <unotools/securityoptions.hxx> |
| #include <svl/itemset.hxx> |
| #include <svl/eitem.hxx> |
| #include <svl/intitem.hxx> |
| #include <svl/stritem.hxx> |
| #include <svtools/filter.hxx> |
| #include <unotools/viewoptions.hxx> |
| #include <unotools/moduleoptions.hxx> |
| #include <svtools/helpid.hrc> |
| #include <comphelper/docpasswordrequest.hxx> |
| #include <comphelper/docpasswordhelper.hxx> |
| #include <ucbhelper/content.hxx> |
| #include <ucbhelper/commandenvironment.hxx> |
| #include <comphelper/storagehelper.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| #include <sfx2/app.hxx> |
| #include <sfx2/frame.hxx> |
| #include <sfx2/docfile.hxx> |
| #include <sfx2/docfac.hxx> |
| #include "openflag.hxx" |
| #include <sfx2/passwd.hxx> |
| #include "sfx2/sfxresid.hxx" |
| #include <sfx2/sfxsids.hrc> |
| #include "filedlghelper.hrc" |
| #include "filtergrouping.hxx" |
| #include <sfx2/request.hxx> |
| #include "filedlgimpl.hxx" |
| #include <helpid.hrc> |
| #include <sfxlocal.hrc> |
| #include <vcl/dibtools.hxx> |
| |
| //----------------------------------------------------------------------------- |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::ui::dialogs; |
| using namespace ::com::sun::star::ui::dialogs::TemplateDescription; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::beans; |
| using namespace ::rtl; |
| using namespace ::cppu; |
| |
| //----------------------------------------------------------------------------- |
| |
| #define IODLG_CONFIGNAME String(DEFINE_CONST_UNICODE("FilePicker_Save")) |
| #define IMPGRF_CONFIGNAME String(DEFINE_CONST_UNICODE("FilePicker_Graph")) |
| #define USERITEM_NAME ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "UserItem" )) |
| |
| //----------------------------------------------------------------------------- |
| |
| namespace sfx2 |
| { |
| |
| const OUString* GetLastFilterConfigId( FileDialogHelper::Context _eContext ) |
| { |
| static const OUString aSD_EXPORT_IDENTIFIER( RTL_CONSTASCII_USTRINGPARAM( "SdExportLastFilter" ) ); |
| static const OUString aSI_EXPORT_IDENTIFIER( RTL_CONSTASCII_USTRINGPARAM( "SiExportLastFilter" ) ); |
| static const OUString aSW_EXPORT_IDENTIFIER( RTL_CONSTASCII_USTRINGPARAM( "SwExportLastFilter" ) ); |
| |
| const OUString* pRet = NULL; |
| |
| switch( _eContext ) |
| { |
| case FileDialogHelper::SD_EXPORT: pRet = &aSD_EXPORT_IDENTIFIER; break; |
| case FileDialogHelper::SI_EXPORT: pRet = &aSI_EXPORT_IDENTIFIER; break; |
| case FileDialogHelper::SW_EXPORT: pRet = &aSW_EXPORT_IDENTIFIER; break; |
| default: break; |
| } |
| |
| return pRet; |
| } |
| |
| String EncodeSpaces_Impl( const String& rSource ); |
| String DecodeSpaces_Impl( const String& rSource ); |
| |
| // ------------------------------------------------------------------------ |
| // ----------- FileDialogHelper_Impl --------------------------- |
| // ------------------------------------------------------------------------ |
| |
| // ------------------------------------------------------------------------ |
| // XFilePickerListener Methods |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper_Impl::fileSelectionChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| mpAntiImpl->FileSelectionChanged( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper_Impl::directoryChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| mpAntiImpl->DirectoryChanged( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| OUString SAL_CALL FileDialogHelper_Impl::helpRequested( const FilePickerEvent& aEvent ) throw ( RuntimeException ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| return mpAntiImpl->HelpRequested( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper_Impl::controlStateChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| mpAntiImpl->ControlStateChanged( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper_Impl::dialogSizeChanged() throw ( RuntimeException ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| mpAntiImpl->DialogSizeChanged(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // XDialogClosedListener Methods |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper_Impl::dialogClosed( const DialogClosedEvent& _rEvent ) throw ( RuntimeException ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| mpAntiImpl->DialogClosed( _rEvent ); |
| postExecute( _rEvent.DialogResult ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // handle XFilePickerListener events |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::handleFileSelectionChanged( const FilePickerEvent& ) |
| { |
| if ( mbHasVersions ) |
| updateVersions(); |
| |
| if ( mbShowPreview ) |
| maPreViewTimer.Start(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::handleDirectoryChanged( const FilePickerEvent& ) |
| { |
| if ( mbShowPreview ) |
| TimeOutHdl_Impl( NULL ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| OUString FileDialogHelper_Impl::handleHelpRequested( const FilePickerEvent& aEvent ) |
| { |
| //!!! todo: cache the help strings (here or TRA) |
| |
| rtl::OString sHelpId; |
| // mapping from element id -> help id |
| switch ( aEvent.ElementId ) |
| { |
| case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION : |
| sHelpId = HID_FILESAVE_AUTOEXTENSION; |
| break; |
| |
| case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD : |
| sHelpId = HID_FILESAVE_SAVEWITHPASSWORD; |
| break; |
| |
| case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS : |
| sHelpId = HID_FILESAVE_CUSTOMIZEFILTER; |
| break; |
| |
| case ExtendedFilePickerElementIds::CHECKBOX_READONLY : |
| sHelpId = HID_FILEOPEN_READONLY; |
| break; |
| |
| case ExtendedFilePickerElementIds::CHECKBOX_LINK : |
| sHelpId = HID_FILEDLG_LINK_CB; |
| break; |
| |
| case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : |
| sHelpId = HID_FILEDLG_PREVIEW_CB; |
| break; |
| |
| case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY : |
| sHelpId = HID_FILESAVE_DOPLAY; |
| break; |
| |
| case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL : |
| case ExtendedFilePickerElementIds::LISTBOX_VERSION : |
| sHelpId = HID_FILEOPEN_VERSION; |
| break; |
| |
| case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL : |
| case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE : |
| sHelpId = HID_FILESAVE_TEMPLATE; |
| break; |
| |
| case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL : |
| case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE : |
| sHelpId = HID_FILEOPEN_IMAGE_TEMPLATE; |
| break; |
| |
| case ExtendedFilePickerElementIds::CHECKBOX_SELECTION : |
| sHelpId = HID_FILESAVE_SELECTION; |
| break; |
| |
| default: |
| DBG_ERRORFILE( "invalid element id" ); |
| } |
| |
| OUString aHelpText; |
| Help* pHelp = Application::GetHelp(); |
| if ( pHelp ) |
| aHelpText = String( pHelp->GetHelpText( String( ByteString(sHelpId), RTL_TEXTENCODING_UTF8), NULL ) ); |
| return aHelpText; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::handleControlStateChanged( const FilePickerEvent& aEvent ) |
| { |
| switch ( aEvent.ElementId ) |
| { |
| case CommonFilePickerElementIds::LISTBOX_FILTER: |
| updateFilterOptionsBox(); |
| enablePasswordBox( sal_False ); |
| updateSelectionBox(); |
| // only use it for export and with our own dialog |
| if ( mbExport && !mbSystemPicker ) |
| updateExportButton(); |
| break; |
| |
| case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW: |
| updatePreviewState(); |
| break; |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::handleDialogSizeChanged() |
| { |
| if ( mbShowPreview ) |
| TimeOutHdl_Impl( NULL ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // XEventListener Methods |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper_Impl::disposing( const EventObject& ) throw ( RuntimeException ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| dispose(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // ------------------------------------------------------------------------ |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::dispose() |
| { |
| if ( mxFileDlg.is() ) |
| { |
| // remove the event listener |
| uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY ); |
| if ( xNotifier.is() ) |
| xNotifier->removeFilePickerListener( this ); |
| |
| ::comphelper::disposeComponent( mxFileDlg ); |
| mxFileDlg.clear(); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| String FileDialogHelper_Impl::getCurrentFilterUIName() const |
| { |
| String aFilterName; |
| uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY ); |
| |
| if( xFltMgr.is() ) |
| { |
| aFilterName = xFltMgr->getCurrentFilter(); |
| |
| if ( aFilterName.Len() && isShowFilterExtensionEnabled() ) |
| aFilterName = getFilterName( aFilterName ); |
| } |
| |
| return aFilterName; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::LoadLastUsedFilter( const OUString& _rContextIdentifier ) |
| { |
| SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME ); |
| |
| if( aDlgOpt.Exists() ) |
| { |
| OUString aLastFilter; |
| if( aDlgOpt.GetUserItem( _rContextIdentifier ) >>= aLastFilter ) |
| setFilter( aLastFilter ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::SaveLastUsedFilter( const OUString& _rContextIdentifier ) |
| { |
| SvtViewOptions( E_DIALOG, IODLG_CONFIGNAME ).SetUserItem( _rContextIdentifier, |
| makeAny( getFilterWithExtension( getFilter() ) ) ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::SaveLastUsedFilter( void ) |
| { |
| const OUString* pConfigId = GetLastFilterConfigId( meContext ); |
| if( pConfigId ) |
| SaveLastUsedFilter( *pConfigId ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| const SfxFilter* FileDialogHelper_Impl::getCurentSfxFilter() |
| { |
| String aFilterName = getCurrentFilterUIName(); |
| |
| const SfxFilter* pFilter = NULL; |
| if ( mpMatcher && aFilterName.Len() ) |
| pFilter = mpMatcher->GetFilter4UIName( aFilterName, m_nMustFlags, m_nDontFlags ); |
| |
| return pFilter; |
| } |
| |
| // ------------------------------------------------------------------------ |
| sal_Bool FileDialogHelper_Impl::updateExtendedControl( sal_Int16 _nExtendedControlId, sal_Bool _bEnable ) |
| { |
| sal_Bool bIsEnabled = sal_False; |
| |
| uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| if ( xCtrlAccess.is() ) |
| { |
| try |
| { |
| xCtrlAccess->enableControl( _nExtendedControlId, _bEnable ); |
| bIsEnabled = _bEnable; |
| } |
| catch( const IllegalArgumentException& ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::updateExtendedControl: caught an exception!" ); |
| } |
| } |
| return bIsEnabled; |
| } |
| |
| // ------------------------------------------------------------------------ |
| sal_Bool FileDialogHelper_Impl::CheckFilterOptionsCapability( const SfxFilter* _pFilter ) |
| { |
| sal_Bool bResult = sal_False; |
| |
| if( mxFilterCFG.is() && _pFilter ) |
| { |
| try { |
| Sequence < PropertyValue > aProps; |
| Any aAny = mxFilterCFG->getByName( _pFilter->GetName() ); |
| if ( aAny >>= aProps ) |
| { |
| ::rtl::OUString aServiceName; |
| sal_Int32 nPropertyCount = aProps.getLength(); |
| for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty ) |
| { |
| if( aProps[nProperty].Name.equals( DEFINE_CONST_OUSTRING( "UIComponent") ) ) |
| { |
| aProps[nProperty].Value >>= aServiceName; |
| if( aServiceName.getLength() ) |
| bResult = sal_True; |
| } |
| } |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| return bResult; |
| } |
| |
| // ------------------------------------------------------------------------ |
| sal_Bool FileDialogHelper_Impl::isInOpenMode() const |
| { |
| sal_Bool bRet = sal_False; |
| |
| switch ( m_nDialogType ) |
| { |
| case FILEOPEN_SIMPLE: |
| case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE: |
| case FILEOPEN_PLAY: |
| case FILEOPEN_READONLY_VERSION: |
| case FILEOPEN_LINK_PREVIEW: |
| bRet = sal_True; |
| } |
| |
| return bRet; |
| } |
| |
| // ------------------------------------------------------------------------ |
| |
| void FileDialogHelper_Impl::updateFilterOptionsBox() |
| { |
| if ( !m_bHaveFilterOptions ) |
| return; |
| |
| updateExtendedControl( |
| ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS, |
| CheckFilterOptionsCapability( getCurentSfxFilter() ) |
| ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| |
| void FileDialogHelper_Impl::updateExportButton() |
| { |
| uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| if ( xCtrlAccess.is() ) |
| { |
| OUString sEllipses( RTL_CONSTASCII_USTRINGPARAM( "..." ) ); |
| OUString sOldLabel( xCtrlAccess->getLabel( CommonFilePickerElementIds::PUSHBUTTON_OK ) ); |
| |
| // initialize button label; we need the label with the mnemonic char |
| if ( !maButtonLabel.getLength() || maButtonLabel.indexOf( MNEMONIC_CHAR ) == -1 ) |
| { |
| // cut the ellipses, if necessary |
| sal_Int32 nIndex = sOldLabel.indexOf( sEllipses ); |
| if ( -1 == nIndex ) |
| nIndex = sOldLabel.getLength(); |
| maButtonLabel = sOldLabel.copy( 0, nIndex ); |
| } |
| |
| OUString sLabel = maButtonLabel; |
| // filter with options -> append ellipses on export button label |
| if ( CheckFilterOptionsCapability( getCurentSfxFilter() ) ) |
| sLabel += OUString( RTL_CONSTASCII_USTRINGPARAM( "..." ) ); |
| |
| if ( sOldLabel != sLabel ) |
| { |
| try |
| { |
| xCtrlAccess->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK, sLabel ); |
| } |
| catch( const IllegalArgumentException& ) |
| { |
| DBG_ERRORFILE( "FileDialogHelper_Impl::updateExportButton: caught an exception!" ); |
| } |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::updateSelectionBox() |
| { |
| if ( !mbHasSelectionBox ) |
| return; |
| |
| // Does the selection box exist? |
| sal_Bool bSelectionBoxFound = sal_False; |
| uno::Reference< XControlInformation > xCtrlInfo( mxFileDlg, UNO_QUERY ); |
| if ( xCtrlInfo.is() ) |
| { |
| Sequence< ::rtl::OUString > aCtrlList = xCtrlInfo->getSupportedControls(); |
| sal_uInt32 nCount = aCtrlList.getLength(); |
| for ( sal_uInt32 nCtrl = 0; nCtrl < nCount; ++nCtrl ) |
| if ( aCtrlList[ nCtrl ].equalsAscii("SelectionBox") ) |
| { |
| bSelectionBoxFound = sal_False; |
| break; |
| } |
| } |
| |
| if ( bSelectionBoxFound ) |
| { |
| const SfxFilter* pFilter = getCurentSfxFilter(); |
| mbSelectionFltrEnabled = updateExtendedControl( |
| ExtendedFilePickerElementIds::CHECKBOX_SELECTION, |
| ( mbSelectionEnabled && pFilter && ( pFilter->GetFilterFlags() & SFX_FILTER_SUPPORTSSELECTION ) != 0 ) ); |
| uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, makeAny( (sal_Bool)mbSelection ) ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::enablePasswordBox( sal_Bool bInit ) |
| { |
| if ( ! mbHasPassword ) |
| return; |
| |
| sal_Bool bWasEnabled = mbIsPwdEnabled; |
| |
| const SfxFilter* pCurrentFilter = getCurentSfxFilter(); |
| mbIsPwdEnabled = updateExtendedControl( |
| ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, |
| pCurrentFilter && ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_ENCRYPTION ) |
| ); |
| |
| if( bInit ) |
| { |
| // in case of inintialization previous state is not interesting |
| if( mbIsPwdEnabled ) |
| { |
| uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| if( mbPwdCheckBoxState ) |
| xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) ); |
| } |
| } |
| else if( !bWasEnabled && mbIsPwdEnabled ) |
| { |
| uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| if( mbPwdCheckBoxState ) |
| xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) ); |
| } |
| else if( bWasEnabled && !mbIsPwdEnabled ) |
| { |
| // remember user settings until checkbox is enabled |
| uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 ); |
| sal_Bool bPassWord = sal_False; |
| mbPwdCheckBoxState = ( aValue >>= bPassWord ) && bPassWord; |
| xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_False ) ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::updatePreviewState( sal_Bool _bUpdatePreviewWindow ) |
| { |
| if ( mbHasPreview ) |
| { |
| uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| |
| // check, wether or not we have to display a preview |
| if ( xCtrlAccess.is() ) |
| { |
| try |
| { |
| Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 ); |
| sal_Bool bShowPreview = sal_False; |
| |
| if ( aValue >>= bShowPreview ) |
| { |
| mbShowPreview = bShowPreview; |
| |
| // #97633 |
| // setShowState has currently no effect for the |
| // OpenOffice FilePicker (see svtools/source/filepicker/iodlg.cxx) |
| uno::Reference< XFilePreview > xFilePreview( mxFileDlg, UNO_QUERY ); |
| if ( xFilePreview.is() ) |
| xFilePreview->setShowState( mbShowPreview ); |
| |
| if ( _bUpdatePreviewWindow ) |
| TimeOutHdl_Impl( NULL ); |
| } |
| } |
| catch( Exception ) |
| { |
| DBG_ERRORFILE( "FileDialogHelper_Impl::updatePreviewState: caught an exception!" ); |
| } |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::updateVersions() |
| { |
| Sequence < OUString > aEntries; |
| Sequence < OUString > aPathSeq = mxFileDlg->getFiles(); |
| |
| if ( aPathSeq.getLength() == 1 ) |
| { |
| INetURLObject aObj( aPathSeq[0] ); |
| |
| if ( ( aObj.GetProtocol() == INET_PROT_FILE ) && |
| ( utl::UCBContentHelper::IsDocument( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) ) |
| { |
| try |
| { |
| uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( |
| aObj.GetMainURL( INetURLObject::NO_DECODE ), |
| embed::ElementModes::READ ); |
| |
| DBG_ASSERT( xStorage.is(), "The method must return the storage or throw an exception!" ); |
| if ( !xStorage.is() ) |
| throw uno::RuntimeException(); |
| |
| uno::Sequence < util::RevisionTag > xVersions = SfxMedium::GetVersionList( xStorage ); |
| |
| aEntries.realloc( xVersions.getLength() + 1 ); |
| aEntries[0] = OUString( String ( SfxResId( STR_SFX_FILEDLG_ACTUALVERSION ) ) ); |
| |
| for ( sal_Int32 i=0; i<xVersions.getLength(); i++ ) |
| aEntries[ i + 1 ] = xVersions[i].Identifier; |
| |
| // TODO/LATER: not sure that this information must be shown in future ( binfilter? ) |
| //REMOVE else |
| //REMOVE { |
| //REMOVE SfxFilterFlags nMust = SFX_FILTER_IMPORT | SFX_FILTER_OWN; |
| //REMOVE SfxFilterFlags nDont = SFX_FILTER_NOTINSTALLED | SFX_FILTER_STARONEFILTER; |
| //REMOVE if ( SFX_APP()->GetFilterMatcher().GetFilter4ClipBoardId( pStor->GetFormat(), nMust, nDont ) ) |
| //REMOVE { |
| //REMOVE aEntries.realloc( 1 ); |
| //REMOVE aEntries[0] = OUString( String ( SfxResId( STR_SFX_FILEDLG_ACTUALVERSION ) ) ); |
| //REMOVE } |
| //REMOVE } |
| } |
| catch( uno::Exception& ) |
| { |
| } |
| } |
| } |
| |
| uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY ); |
| Any aValue; |
| |
| try |
| { |
| xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, |
| ControlActions::DELETE_ITEMS, aValue ); |
| } |
| catch( IllegalArgumentException ){} |
| |
| sal_Int32 nCount = aEntries.getLength(); |
| |
| if ( nCount ) |
| { |
| try |
| { |
| aValue <<= aEntries; |
| xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, |
| ControlActions::ADD_ITEMS, aValue ); |
| |
| Any aPos; |
| aPos <<= (sal_Int32) 0; |
| xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, |
| ControlActions::SET_SELECT_ITEM, aPos ); |
| } |
| catch( IllegalArgumentException ){} |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| class OReleaseSolarMutex |
| { |
| private: |
| const sal_Int32 m_nAquireCount; |
| public: |
| OReleaseSolarMutex( ) |
| :m_nAquireCount( Application::ReleaseSolarMutex() ) |
| { |
| } |
| ~OReleaseSolarMutex( ) |
| { |
| Application::AcquireSolarMutex( m_nAquireCount ); |
| } |
| }; |
| |
| // ----------------------------------------------------------------------- |
| IMPL_LINK( FileDialogHelper_Impl, TimeOutHdl_Impl, Timer*, EMPTYARG ) |
| { |
| if ( !mbHasPreview ) |
| return 0; |
| |
| maGraphic.Clear(); |
| |
| Any aAny; |
| uno::Reference < XFilePreview > xFilePicker( mxFileDlg, UNO_QUERY ); |
| |
| if ( ! xFilePicker.is() ) |
| return 0; |
| |
| Sequence < OUString > aPathSeq = mxFileDlg->getFiles(); |
| |
| if ( mbShowPreview && ( aPathSeq.getLength() == 1 ) ) |
| { |
| OUString aURL = aPathSeq[0]; |
| |
| if ( ERRCODE_NONE == getGraphic( aURL, maGraphic ) ) |
| { |
| // #89491 |
| // changed the code slightly; |
| // before: the bitmap was scaled and |
| // surrounded a white frame |
| // now: the bitmap will only be scaled |
| // and the filepicker implementation |
| // is responsible for placing it at its |
| // proper position and painting a frame |
| |
| Bitmap aBmp = maGraphic.GetBitmap(); |
| if ( !aBmp.IsEmpty() ) |
| { |
| // scale the bitmap to the correct size |
| sal_Int32 nOutWidth = xFilePicker->getAvailableWidth(); |
| sal_Int32 nOutHeight = xFilePicker->getAvailableHeight(); |
| sal_Int32 nBmpWidth = aBmp.GetSizePixel().Width(); |
| sal_Int32 nBmpHeight = aBmp.GetSizePixel().Height(); |
| |
| double nXRatio = (double) nOutWidth / nBmpWidth; |
| double nYRatio = (double) nOutHeight / nBmpHeight; |
| |
| if ( nXRatio < nYRatio ) |
| aBmp.Scale( nXRatio, nXRatio ); |
| else |
| aBmp.Scale( nYRatio, nYRatio ); |
| |
| // #94505# Convert to true color, to allow CopyPixel |
| aBmp.Convert( BMP_CONVERSION_24BIT ); |
| |
| // and copy it into the Any |
| SvMemoryStream aData; |
| |
| WriteDIB(aBmp, aData, false, true); |
| |
| const Sequence < sal_Int8 > aBuffer( |
| static_cast< const sal_Int8* >(aData.GetData()), |
| aData.GetEndOfData() ); |
| |
| aAny <<= aBuffer; |
| } |
| } |
| } |
| |
| try |
| { |
| OReleaseSolarMutex aReleaseForCallback; |
| // clear the preview window |
| xFilePicker->setImage( FilePreviewImageFormats::BITMAP, aAny ); |
| } |
| catch( IllegalArgumentException ) |
| { |
| } |
| |
| return 0; |
| } |
| |
| // ------------------------------------------------------------------------ |
| ErrCode FileDialogHelper_Impl::getGraphic( const OUString& rURL, |
| Graphic& rGraphic ) const |
| { |
| if ( utl::UCBContentHelper::IsFolder( rURL ) ) |
| return ERRCODE_IO_NOTAFILE; |
| |
| if ( !mpGraphicFilter ) |
| return ERRCODE_IO_NOTSUPPORTED; |
| |
| // select graphic filter from dialog filter selection |
| OUString aCurFilter( getFilter() ); |
| |
| sal_uInt16 nFilter = aCurFilter.getLength() && mpGraphicFilter->GetImportFormatCount() |
| ? mpGraphicFilter->GetImportFormatNumber( aCurFilter ) |
| : GRFILTER_FORMAT_DONTKNOW; |
| |
| INetURLObject aURLObj( rURL ); |
| |
| if ( aURLObj.HasError() || INET_PROT_NOT_VALID == aURLObj.GetProtocol() ) |
| { |
| aURLObj.SetSmartProtocol( INET_PROT_FILE ); |
| aURLObj.SetSmartURL( rURL ); |
| } |
| |
| ErrCode nRet = ERRCODE_NONE; |
| |
| sal_uInt32 nFilterImportFlags = GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG; |
| // non-local? |
| if ( INET_PROT_FILE != aURLObj.GetProtocol() ) |
| { |
| SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( rURL, STREAM_READ ); |
| |
| if( pStream ) |
| nRet = mpGraphicFilter->ImportGraphic( rGraphic, rURL, *pStream, nFilter, NULL, nFilterImportFlags ); |
| else |
| nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags ); |
| delete pStream; |
| } |
| else |
| { |
| nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags ); |
| } |
| |
| return nRet; |
| } |
| |
| // ------------------------------------------------------------------------ |
| ErrCode FileDialogHelper_Impl::getGraphic( Graphic& rGraphic ) const |
| { |
| ErrCode nRet = ERRCODE_NONE; |
| |
| if ( ! maGraphic ) |
| { |
| OUString aPath;; |
| Sequence < OUString > aPathSeq = mxFileDlg->getFiles(); |
| |
| if ( aPathSeq.getLength() == 1 ) |
| { |
| aPath = aPathSeq[0]; |
| } |
| |
| if ( aPath.getLength() ) |
| nRet = getGraphic( aPath, rGraphic ); |
| else |
| nRet = ERRCODE_IO_GENERAL; |
| } |
| else |
| rGraphic = maGraphic; |
| |
| return nRet; |
| } |
| |
| // ------------------------------------------------------------------------ |
| sal_Bool lcl_isSystemFilePicker( const uno::Reference< XFilePicker >& _rxFP ) |
| { |
| try |
| { |
| uno::Reference< XServiceInfo > xSI( _rxFP, UNO_QUERY ); |
| if ( xSI.is() && xSI->supportsService( DEFINE_CONST_OUSTRING( "com.sun.star.ui.dialogs.SystemFilePicker" ) ) ) |
| return sal_True; |
| } |
| catch( const Exception& ) |
| { |
| } |
| return sal_False; |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| // ----------- FileDialogHelper_Impl --------------------------- |
| // ------------------------------------------------------------------------ |
| |
| FileDialogHelper_Impl::FileDialogHelper_Impl( |
| FileDialogHelper* _pAntiImpl, |
| sal_Int16 nDialogType, |
| sal_Int64 nFlags, |
| sal_Int16 nDialog, |
| Window* _pPreferredParentWindow, |
| const String& sStandardDir, |
| const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList |
| ) |
| :m_nDialogType ( nDialogType ) |
| ,meContext ( FileDialogHelper::UNKNOWN_CONTEXT ) |
| { |
| const char* pServiceName=0; |
| if ( nDialog == SFX2_IMPL_DIALOG_SYSTEM ) |
| pServiceName = FILE_OPEN_SERVICE_NAME_OOO; |
| else if ( nDialog == SFX2_IMPL_DIALOG_OOO ) |
| pServiceName = FILE_OPEN_SERVICE_NAME_OOO; |
| else |
| pServiceName = FILE_OPEN_SERVICE_NAME; |
| OUString aService = ::rtl::OUString::createFromAscii( pServiceName ); |
| |
| uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); |
| |
| // create the file open dialog |
| // the flags can be SFXWB_INSERT or SFXWB_MULTISELECTION |
| |
| mpPreferredParentWindow = _pPreferredParentWindow; |
| mpAntiImpl = _pAntiImpl; |
| mnError = ERRCODE_NONE; |
| mbHasAutoExt = sal_False; |
| mbHasPassword = sal_False; |
| m_bHaveFilterOptions = sal_False; |
| mbIsPwdEnabled = sal_True; |
| mbHasVersions = sal_False; |
| mbHasPreview = sal_False; |
| mbShowPreview = sal_False; |
| mbHasLink = sal_False; |
| mbDeleteMatcher = sal_False; |
| mbInsert = SFXWB_INSERT == ( nFlags & SFXWB_INSERT ); |
| mbExport = SFXWB_EXPORT == ( nFlags & SFXWB_EXPORT ); |
| mbIsSaveDlg = sal_False; |
| mbPwdCheckBoxState = sal_False; |
| mbSelection = sal_False; |
| mbSelectionEnabled = sal_True; |
| mbHasSelectionBox = sal_False; |
| mbSelectionFltrEnabled = sal_False; |
| |
| // default settings |
| m_nDontFlags = SFX_FILTER_INTERNAL | SFX_FILTER_NOTINFILEDLG | SFX_FILTER_NOTINSTALLED; |
| if( WB_OPEN == ( nFlags & WB_OPEN ) ) |
| m_nMustFlags = SFX_FILTER_IMPORT; |
| else |
| m_nMustFlags = SFX_FILTER_EXPORT; |
| |
| |
| mpMatcher = NULL; |
| mpGraphicFilter = NULL; |
| mnPostUserEventId = 0; |
| |
| // create the picker component |
| mxFileDlg = mxFileDlg.query( xFactory->createInstance( aService ) ); |
| mbSystemPicker = lcl_isSystemFilePicker( mxFileDlg ); |
| |
| uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY ); |
| uno::Reference< XInitialization > xInit( mxFileDlg, UNO_QUERY ); |
| |
| if ( ! mxFileDlg.is() || ! xNotifier.is() ) |
| { |
| mnError = ERRCODE_ABORT; |
| return; |
| } |
| |
| |
| if ( xInit.is() ) |
| { |
| sal_Int16 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE; |
| |
| switch ( m_nDialogType ) |
| { |
| case FILEOPEN_SIMPLE: |
| nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE; |
| break; |
| |
| case FILESAVE_SIMPLE: |
| nTemplateDescription = TemplateDescription::FILESAVE_SIMPLE; |
| mbIsSaveDlg = sal_True; |
| break; |
| |
| case FILESAVE_AUTOEXTENSION_PASSWORD: |
| nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD; |
| mbHasPassword = sal_True; |
| mbHasAutoExt = sal_True; |
| mbIsSaveDlg = sal_True; |
| break; |
| |
| case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS: |
| nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS; |
| mbHasPassword = sal_True; |
| |
| m_bHaveFilterOptions = sal_True; |
| if( xFactory.is() ) |
| { |
| mxFilterCFG = uno::Reference< XNameAccess >( |
| xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.document.FilterFactory" ) ), |
| UNO_QUERY ); |
| } |
| |
| mbHasAutoExt = sal_True; |
| mbIsSaveDlg = sal_True; |
| break; |
| |
| case FILESAVE_AUTOEXTENSION_SELECTION: |
| nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION; |
| mbHasAutoExt = sal_True; |
| mbIsSaveDlg = sal_True; |
| mbHasSelectionBox = sal_True; |
| if ( mbExport && !mxFilterCFG.is() && xFactory.is() ) |
| { |
| mxFilterCFG = uno::Reference< XNameAccess >( |
| xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.document.FilterFactory" ) ), |
| UNO_QUERY ); |
| } |
| break; |
| |
| case FILESAVE_AUTOEXTENSION_TEMPLATE: |
| nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE; |
| mbHasAutoExt = sal_True; |
| mbIsSaveDlg = sal_True; |
| break; |
| |
| case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE: |
| nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE; |
| mbHasPreview = sal_True; |
| mbHasLink = sal_True; |
| |
| // aPreviewTimer |
| maPreViewTimer.SetTimeout( 500 ); |
| maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) ); |
| break; |
| |
| case FILEOPEN_PLAY: |
| nTemplateDescription = TemplateDescription::FILEOPEN_PLAY; |
| break; |
| |
| case FILEOPEN_READONLY_VERSION: |
| nTemplateDescription = TemplateDescription::FILEOPEN_READONLY_VERSION; |
| mbHasVersions = sal_True; |
| break; |
| |
| case FILEOPEN_LINK_PREVIEW: |
| nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW; |
| mbHasPreview = sal_True; |
| mbHasLink = sal_True; |
| // aPreviewTimer |
| maPreViewTimer.SetTimeout( 500 ); |
| maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) ); |
| break; |
| |
| case FILESAVE_AUTOEXTENSION: |
| nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION; |
| mbHasAutoExt = sal_True; |
| mbIsSaveDlg = sal_True; |
| break; |
| |
| default: |
| DBG_ERRORFILE( "FileDialogHelper::ctor with unknown type" ); |
| break; |
| } |
| |
| |
| |
| //Sequence < Any > aInitArguments( mbSystemPicker || !mpPreferredParentWindow ? 1 : 3 ); |
| Sequence < Any > aInitArguments( !mpPreferredParentWindow ? 3 : 4 ); |
| |
| // This is a hack. We currently know that the internal file picker implementation |
| // supports the extended arguments as specified below. |
| // TODO: |
| // a) adjust the service description so that it includes the TemplateDescription and ParentWindow args |
| // b) adjust the implementation of the system file picker to that it recognizes it |
| if ( mbSystemPicker ) |
| { |
| aInitArguments[0] <<= nTemplateDescription; |
| } |
| else |
| { |
| aInitArguments[0] <<= NamedValue( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TemplateDescription" ) ), |
| makeAny( nTemplateDescription ) |
| ); |
| |
| ::rtl::OUString sStandardDirTemp = ::rtl::OUString( sStandardDir ); |
| |
| aInitArguments[1] <<= NamedValue( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StandardDir" ) ), |
| makeAny( sStandardDirTemp ) |
| ); |
| |
| aInitArguments[2] <<= NamedValue( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BlackList" ) ), |
| makeAny( rBlackList ) |
| ); |
| |
| |
| if ( mpPreferredParentWindow ) |
| aInitArguments[3] <<= NamedValue( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ), |
| makeAny( VCLUnoHelper::GetInterface( mpPreferredParentWindow ) ) |
| ); |
| |
| |
| } |
| |
| try |
| { |
| xInit->initialize( aInitArguments ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::FileDialogHelper_Impl: could not initialize the picker!" ); |
| } |
| } |
| |
| |
| // set multiselection mode |
| if ( nFlags & SFXWB_MULTISELECTION ) |
| mxFileDlg->setMultiSelectionMode( sal_True ); |
| |
| if ( mbHasLink ) // generate graphic filter only on demand |
| addGraphicFilter(); |
| |
| // Export dialog |
| if ( mbExport ) |
| { |
| mxFileDlg->setTitle( OUString( String( SfxResId( STR_SFX_EXPLORERFILE_EXPORT ) ) ) ); |
| try { |
| com::sun::star::uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY_THROW ); |
| xCtrlAccess->enableControl( ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR, sal_True ); |
| } |
| catch( const Exception & ) { } |
| } |
| |
| // the "insert file" dialog needs another title |
| if ( mbInsert ) |
| { |
| mxFileDlg->setTitle( OUString( String( SfxResId( STR_SFX_EXPLORERFILE_INSERT ) ) ) ); |
| uno::Reference < XFilePickerControlAccess > xExtDlg( mxFileDlg, UNO_QUERY ); |
| if ( xExtDlg.is() ) |
| { |
| try |
| { |
| xExtDlg->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK, |
| OUString( String( SfxResId( STR_SFX_EXPLORERFILE_BUTTONINSERT ) ) ) ); |
| } |
| catch( IllegalArgumentException ){} |
| } |
| } |
| |
| // add the event listener |
| xNotifier->addFilePickerListener( this ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| FileDialogHelper_Impl::~FileDialogHelper_Impl() |
| { |
| // Remove user event if we haven't received it yet |
| if ( mnPostUserEventId ) |
| Application::RemoveUserEvent( mnPostUserEventId ); |
| mnPostUserEventId = 0; |
| |
| delete mpGraphicFilter; |
| |
| if ( mbDeleteMatcher ) |
| delete mpMatcher; |
| |
| maPreViewTimer.SetTimeoutHdl( Link() ); |
| |
| ::comphelper::disposeComponent( mxFileDlg ); |
| } |
| |
| #define nMagic -1 |
| |
| class PickerThread_Impl : public ::vos::OThread |
| { |
| uno::Reference < XFilePicker > mxPicker; |
| ::vos::OMutex maMutex; |
| virtual void SAL_CALL run(); |
| sal_Int16 mnRet; |
| public: |
| PickerThread_Impl( const uno::Reference < XFilePicker >& rPicker ) |
| : mxPicker( rPicker ), mnRet(nMagic) {} |
| |
| sal_Int16 GetReturnValue() |
| { ::vos::OGuard aGuard( maMutex ); return mnRet; } |
| |
| void SetReturnValue( sal_Int16 aRetValue ) |
| { ::vos::OGuard aGuard( maMutex ); mnRet = aRetValue; } |
| }; |
| |
| void SAL_CALL PickerThread_Impl::run() |
| { |
| try |
| { |
| sal_Int16 n = mxPicker->execute(); |
| SetReturnValue( n ); |
| } |
| catch( RuntimeException& ) |
| { |
| SetReturnValue( ExecutableDialogResults::CANCEL ); |
| DBG_ERRORFILE( "RuntimeException caught" ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::setControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId ) |
| { |
| DBG_ASSERT( _pControlId && _pHelpId, "FileDialogHelper_Impl::setControlHelpIds: invalid array pointers!" ); |
| if ( !_pControlId || !_pHelpId ) |
| return; |
| |
| // forward these ids to the file picker |
| try |
| { |
| const ::rtl::OUString sHelpIdPrefix( RTL_CONSTASCII_USTRINGPARAM( INET_HID_SCHEME ) ); |
| // the ids for the single controls |
| uno::Reference< XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY ); |
| if ( xControlAccess.is() ) |
| { |
| while ( *_pControlId ) |
| { |
| DBG_ASSERT( INetURLObject( rtl::OStringToOUString( *_pHelpId, RTL_TEXTENCODING_UTF8 ) ).GetProtocol() == INET_PROT_NOT_VALID, "Wrong HelpId!" ); |
| ::rtl::OUString sId( sHelpIdPrefix ); |
| sId += ::rtl::OUString( *_pHelpId, strlen( *_pHelpId ), RTL_TEXTENCODING_UTF8 ); |
| xControlAccess->setValue( *_pControlId, ControlActions::SET_HELP_URL, makeAny( sId ) ); |
| |
| ++_pControlId; ++_pHelpId; |
| } |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::setControlHelpIds: caught an exception while setting the help ids!" ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| IMPL_LINK( FileDialogHelper_Impl, InitControls, void*, NOTINTERESTEDIN ) |
| { |
| (void)NOTINTERESTEDIN; |
| mnPostUserEventId = 0; |
| enablePasswordBox( sal_True ); |
| updateFilterOptionsBox( ); |
| updateSelectionBox( ); |
| |
| return 0L; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::preExecute() |
| { |
| loadConfig( ); |
| setDefaultValues( ); |
| updatePreviewState( sal_False ); |
| |
| implInitializeFileName( ); |
| // #106079# / 2002-12-09 / fs@openoffice.org |
| |
| #if !(defined(MACOSX) && defined(QUARTZ)) && !defined(WNT) |
| // allow for dialog implementations which need to be executed before they return valid values for |
| // current filter and such |
| |
| // On Vista (at least SP1) it's the same as on MacOSX, the modal dialog won't let message pass |
| // through before it returns from execution |
| mnPostUserEventId = Application::PostUserEvent( LINK( this, FileDialogHelper_Impl, InitControls ) ); |
| #else |
| // However, the Mac OS X implementation's pickers run modally in execute and so the event doesn't |
| // get through in time... so we call the methods directly |
| enablePasswordBox( sal_True ); |
| updateFilterOptionsBox( ); |
| updateSelectionBox( ); |
| #endif |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::postExecute( sal_Int16 _nResult ) |
| { |
| if ( ExecutableDialogResults::CANCEL != _nResult ) |
| saveConfig(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::implInitializeFileName( ) |
| { |
| if ( maFileName.getLength() ) |
| { |
| INetURLObject aObj( maPath ); |
| aObj.Append( maFileName ); |
| |
| // in case we're operating as save dialog, and "auto extension" is checked, |
| // cut the extension from the name |
| // #106079# / 2002-12-09 / fs@openoffice.org |
| if ( mbIsSaveDlg && mbHasAutoExt ) |
| { |
| try |
| { |
| sal_Bool bAutoExtChecked = sal_False; |
| |
| uno::Reference < XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY ); |
| if ( xControlAccess.is() |
| && ( xControlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 ) |
| >>= bAutoExtChecked |
| ) |
| ) |
| { |
| if ( bAutoExtChecked ) |
| { // cut the extension |
| aObj.removeExtension( ); |
| mxFileDlg->setDefaultName( aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) ); |
| } |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::implInitializeFileName: could not ask for the auto-extension current-value!" ); |
| } |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| sal_Int16 FileDialogHelper_Impl::implDoExecute() |
| { |
| preExecute(); |
| |
| sal_Int16 nRet = ExecutableDialogResults::CANCEL; |
| |
| //On MacOSX the native file picker has to run in the primordial thread because of drawing issues |
| //On Linux the native gtk file picker, when backed by gnome-vfs2, needs to be run in the same |
| //primordial thread as the ucb gnome-vfs2 provider was initialized in. |
| /* |
| #ifdef WNT |
| if ( mbSystemPicker ) |
| { |
| PickerThread_Impl* pThread = new PickerThread_Impl( mxFileDlg ); |
| pThread->create(); |
| while ( pThread->GetReturnValue() == nMagic ) |
| Application::Yield(); |
| pThread->join(); |
| nRet = pThread->GetReturnValue(); |
| delete pThread; |
| } |
| else |
| #endif |
| */ |
| { |
| try |
| { |
| #ifdef WNT |
| if ( mbSystemPicker ) |
| { |
| OReleaseSolarMutex aSolarMutex; |
| nRet = mxFileDlg->execute(); |
| } |
| else |
| #endif |
| nRet = mxFileDlg->execute(); |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERRORFILE( "FileDialogHelper_Impl::implDoExecute: caught an exception!" ); |
| } |
| } |
| |
| postExecute( nRet ); |
| |
| return nRet; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::implStartExecute() |
| { |
| DBG_ASSERT( mxFileDlg.is(), "invalid file dialog" ); |
| |
| preExecute(); |
| |
| if ( mbSystemPicker ) |
| { |
| } |
| else |
| { |
| try |
| { |
| uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( mxFileDlg, UNO_QUERY ); |
| if ( xAsyncDlg.is() ) |
| xAsyncDlg->startExecuteModal( this ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERRORFILE( "FileDialogHelper_Impl::implDoExecute: caught an exception!" ); |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| String FileDialogHelper_Impl::implEnsureURLExtension(const String& sURL, |
| const String& /*sExtension*/) |
| { |
| return sURL; |
| /* |
| // This feature must be active for file save/export only ! |
| if ( |
| (! mbIsSaveDlg) && |
| (! mbExport ) |
| ) |
| return sURL; |
| |
| // no extension available (because "ALL *.*" was selected) ? |
| // Nod idea what else should happen here .-) |
| if (sExtension.Len() < 1) |
| return sURL; |
| |
| // Some FilePicker implementations already add the right extension ... |
| // or might be the user used the right one already ... |
| // Dont create duplicate extension. |
| INetURLObject aURL(sURL); |
| if (aURL.getExtension().equals(sExtension)) |
| return sURL; |
| |
| // Ignore any other extension set by the user. |
| // Make sure suitable extension is used always. |
| // e.g. "test.bla.odt" for "ODT" |
| ::rtl::OUStringBuffer sNewURL(256); |
| sNewURL.append (sURL ); |
| sNewURL.appendAscii("." ); |
| sNewURL.append (sExtension); |
| return sNewURL.makeStringAndClear(); |
| */ |
| } |
| |
| // ------------------------------------------------------------------------ |
| void lcl_saveLastURLs(SvStringsDtor*& rpURLList , |
| ::comphelper::SequenceAsVector< ::rtl::OUString >& lLastURLs ) |
| { |
| lLastURLs.clear(); |
| sal_uInt16 c = rpURLList->Count(); |
| sal_uInt16 i = 0; |
| for (i=0; i<c; ++i) |
| lLastURLs.push_back(*(rpURLList->GetObject(i))); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::implGetAndCacheFiles(const uno::Reference< XInterface >& xPicker , |
| SvStringsDtor*& rpURLList, |
| const SfxFilter* pFilter ) |
| { |
| rpURLList = NULL; |
| |
| String sExtension; |
| if (pFilter) |
| { |
| sExtension = pFilter->GetDefaultExtension (); |
| sExtension.EraseAllChars( '*' ); |
| sExtension.EraseAllChars( '.' ); |
| } |
| |
| // a) the new way (optional!) |
| uno::Reference< XFilePicker2 > xPickNew(xPicker, UNO_QUERY); |
| if (xPickNew.is()) |
| { |
| rpURLList = new SvStringsDtor; |
| Sequence< OUString > lFiles = xPickNew->getSelectedFiles(); |
| ::sal_Int32 nFiles = lFiles.getLength(); |
| for (::sal_Int32 i = 0; i < nFiles; i++) |
| { |
| String* pURL = new String(implEnsureURLExtension(lFiles[i], sExtension)); |
| rpURLList->Insert( pURL, rpURLList->Count() ); |
| } |
| } |
| |
| // b) the olde way ... non optional. |
| else |
| { |
| uno::Reference< XFilePicker > xPickOld(xPicker, UNO_QUERY_THROW); |
| Sequence< OUString > lFiles = xPickOld->getFiles(); |
| ::sal_Int32 nFiles = lFiles.getLength(); |
| if ( nFiles == 1 ) |
| { |
| rpURLList = new SvStringsDtor; |
| String* pURL = new String(implEnsureURLExtension(lFiles[0], sExtension)); |
| rpURLList->Insert( pURL, 0 ); |
| } |
| else |
| if ( nFiles > 1 ) |
| { |
| rpURLList = new SvStringsDtor; |
| |
| INetURLObject aPath( lFiles[0] ); |
| aPath.setFinalSlash(); |
| |
| for (::sal_Int32 i = 1; i < nFiles; i++) |
| { |
| if (i == 1) |
| aPath.Append( lFiles[i] ); |
| else |
| aPath.setName( lFiles[i] ); |
| |
| String* pURL = new String(implEnsureURLExtension(aPath.GetMainURL( INetURLObject::NO_DECODE ), sExtension) ); |
| rpURLList->Insert( pURL, rpURLList->Count() ); |
| } |
| } |
| } |
| |
| lcl_saveLastURLs(rpURLList, mlLastURLs); |
| } |
| |
| // ------------------------------------------------------------------------ |
| ErrCode FileDialogHelper_Impl::execute( SvStringsDtor*& rpURLList, |
| SfxItemSet *& rpSet, |
| String& rFilter ) |
| { |
| // rFilter is a pure output parameter, it shouldn't be used for anything else |
| // changing this would surely break code |
| // rpSet is in/out parameter, usually just a media-descriptor that can be changed by dialog |
| |
| uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY ); |
| |
| // retrieves parameters from rpSet |
| // for now only Password is used |
| if ( rpSet ) |
| { |
| // check password checkbox if the document had password before |
| if( mbHasPassword ) |
| { |
| SFX_ITEMSET_ARG( rpSet, pPassItem, SfxBoolItem, SID_PASSWORDINTERACTION, sal_False ); |
| mbPwdCheckBoxState = ( pPassItem != NULL && pPassItem->GetValue() ); |
| |
| // in case the document has password to modify, the dialog should be shown |
| SFX_ITEMSET_ARG( rpSet, pPassToModifyItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, sal_False ); |
| mbPwdCheckBoxState |= ( pPassToModifyItem && pPassToModifyItem->GetValue().hasValue() ); |
| } |
| |
| SFX_ITEMSET_ARG( rpSet, pSelectItem, SfxBoolItem, SID_SELECTION, sal_False ); |
| if ( pSelectItem ) |
| mbSelection = pSelectItem->GetValue(); |
| else |
| mbSelectionEnabled = sal_False; |
| |
| // the password will be set in case user decide so |
| rpSet->ClearItem( SID_PASSWORDINTERACTION ); |
| rpSet->ClearItem( SID_PASSWORD ); |
| rpSet->ClearItem( SID_ENCRYPTIONDATA ); |
| rpSet->ClearItem( SID_RECOMMENDREADONLY ); |
| rpSet->ClearItem( SID_MODIFYPASSWORDINFO ); |
| |
| } |
| |
| if ( mbHasPassword && !mbPwdCheckBoxState ) |
| { |
| SvtSecurityOptions aSecOpt; |
| mbPwdCheckBoxState = ( |
| aSecOpt.IsOptionSet( SvtSecurityOptions::E_DOCWARN_RECOMMENDPASSWORD ) ); |
| } |
| |
| rpURLList = NULL; |
| |
| if ( ! mxFileDlg.is() ) |
| return ERRCODE_ABORT; |
| |
| if ( ExecutableDialogResults::CANCEL != implDoExecute() ) |
| { |
| // create an itemset if there is no |
| if( !rpSet ) |
| rpSet = new SfxAllItemSet( SFX_APP()->GetPool() ); |
| |
| // the item should remain only if it was set by the dialog |
| rpSet->ClearItem( SID_SELECTION ); |
| |
| if( mbExport && mbHasSelectionBox ) |
| { |
| try |
| { |
| Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 ); |
| sal_Bool bSelection = sal_False; |
| if ( aValue >>= bSelection ) |
| rpSet->Put( SfxBoolItem( SID_SELECTION, bSelection ) ); |
| } |
| catch( IllegalArgumentException ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" ); |
| } |
| } |
| |
| |
| // set the read-only flag. When inserting a file, this flag is always set |
| if ( mbInsert ) |
| rpSet->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) ); |
| else |
| { |
| if ( ( FILEOPEN_READONLY_VERSION == m_nDialogType ) && xCtrlAccess.is() ) |
| { |
| try |
| { |
| Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ); |
| sal_Bool bReadOnly = sal_False; |
| if ( ( aValue >>= bReadOnly ) && bReadOnly ) |
| rpSet->Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) ); |
| } |
| catch( IllegalArgumentException ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" ); |
| } |
| } |
| } |
| if ( mbHasVersions && xCtrlAccess.is() ) |
| { |
| try |
| { |
| Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, |
| ControlActions::GET_SELECTED_ITEM_INDEX ); |
| sal_Int32 nVersion = 0; |
| if ( ( aValue >>= nVersion ) && nVersion > 0 ) |
| // open a special version; 0 == current version |
| rpSet->Put( SfxInt16Item( SID_VERSION, (short)nVersion ) ); |
| } |
| catch( IllegalArgumentException ){} |
| } |
| |
| // set the filter |
| getRealFilter( rFilter ); |
| |
| const SfxFilter* pCurrentFilter = getCurentSfxFilter(); |
| |
| // fill the rpURLList |
| implGetAndCacheFiles( mxFileDlg, rpURLList, pCurrentFilter ); |
| if ( rpURLList == NULL || rpURLList->GetObject(0) == NULL ) |
| return ERRCODE_ABORT; |
| |
| // check, wether or not we have to display a password box |
| if ( pCurrentFilter && mbHasPassword && mbIsPwdEnabled && xCtrlAccess.is() ) |
| { |
| try |
| { |
| Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 ); |
| sal_Bool bPassWord = sal_False; |
| if ( ( aValue >>= bPassWord ) && bPassWord ) |
| { |
| // ask for a password |
| uno::Reference < ::com::sun::star::task::XInteractionHandler > xInteractionHandler( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY ); |
| |
| if( xInteractionHandler.is() ) |
| { |
| // TODO: need a save way to distinguish MS filters from other filters |
| // for now MS-filters are the only alien filters that support encryption |
| sal_Bool bMSType = !pCurrentFilter->IsOwnFormat(); |
| ::comphelper::DocPasswordRequestType eType = bMSType ? |
| ::comphelper::DocPasswordRequestType_MS : |
| ::comphelper::DocPasswordRequestType_STANDARD; |
| |
| ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, ::com::sun::star::task::PasswordRequestMode_PASSWORD_CREATE, *(rpURLList->GetObject(0)), ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_PASSWORDTOMODIFY ) != 0 ) ); |
| |
| uno::Reference< com::sun::star::task::XInteractionRequest > rRequest( pPasswordRequest.get() ); |
| xInteractionHandler->handle( rRequest ); |
| if ( pPasswordRequest->isPassword() ) |
| { |
| if ( pPasswordRequest->getPassword().getLength() ) |
| { |
| // TODO/LATER: The filters should show the password dialog themself in future |
| if ( bMSType ) |
| { |
| // all the current MS-filters use MSCodec_Std97 implementation |
| uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 ); |
| uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPasswordRequest->getPassword(), aUniqueID ); |
| |
| if ( aEncryptionKey.getLength() ) |
| { |
| ::comphelper::SequenceAsHashMap aHashData; |
| aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= aEncryptionKey; |
| aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= aUniqueID; |
| |
| rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) ); |
| } |
| else |
| return ERRCODE_IO_NOTSUPPORTED; |
| } |
| else |
| { |
| rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordRequest->getPassword() ) ) ) ); |
| } |
| } |
| |
| if ( pPasswordRequest->getRecommendReadOnly() ) |
| rpSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, sal_True ) ); |
| |
| if ( bMSType ) |
| { |
| // the empty password has 0 as Hash |
| sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash( pPasswordRequest->getPasswordToModify(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) ).equals( pCurrentFilter->GetServiceName() ) ); |
| if ( nHash ) |
| rpSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( nHash ) ) ); |
| } |
| else |
| { |
| uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( pPasswordRequest->getPasswordToModify() ); |
| if ( aModifyPasswordInfo.getLength() ) |
| rpSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( aModifyPasswordInfo ) ) ); |
| } |
| } |
| else |
| return ERRCODE_ABORT; |
| } |
| } |
| } |
| catch( IllegalArgumentException ){} |
| } |
| |
| SaveLastUsedFilter(); |
| return ERRCODE_NONE; |
| } |
| else |
| return ERRCODE_ABORT; |
| } |
| |
| // ------------------------------------------------------------------------ |
| ErrCode FileDialogHelper_Impl::execute() |
| { |
| if ( ! mxFileDlg.is() ) |
| return ERRCODE_ABORT; |
| |
| sal_Int16 nRet = implDoExecute(); |
| |
| maPath = mxFileDlg->getDisplayDirectory(); |
| |
| if ( ExecutableDialogResults::CANCEL == nRet ) |
| return ERRCODE_ABORT; |
| else |
| { |
| return ERRCODE_NONE; |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| OUString FileDialogHelper_Impl::getPath() const |
| { |
| OUString aPath; |
| |
| if ( mxFileDlg.is() ) |
| aPath = mxFileDlg->getDisplayDirectory(); |
| |
| if ( !aPath.getLength() ) |
| aPath = maPath; |
| |
| return aPath; |
| } |
| |
| // ------------------------------------------------------------------------ |
| OUString FileDialogHelper_Impl::getFilter() const |
| { |
| String aFilter = getCurrentFilterUIName(); |
| |
| if( !aFilter.Len() ) |
| aFilter = maCurFilter; |
| |
| return aFilter; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::getRealFilter( String& _rFilter ) const |
| { |
| _rFilter = getCurrentFilterUIName(); |
| |
| if ( !_rFilter.Len() ) |
| _rFilter = maCurFilter; |
| |
| if ( _rFilter.Len() && mpMatcher ) |
| { |
| const SfxFilter* pFilter = |
| mpMatcher->GetFilter4UIName( _rFilter, m_nMustFlags, m_nDontFlags ); |
| _rFilter = pFilter ? pFilter->GetFilterName() : _rFilter.Erase(); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::displayFolder( const ::rtl::OUString& _rPath ) |
| { |
| if ( ! _rPath.getLength() ) |
| // nothing to do |
| return; |
| |
| /* |
| if ( !::utl::UCBContentHelper::IsFolder( _rPath ) ) |
| // only valid folders accepted here |
| return; |
| */ |
| |
| maPath = _rPath; |
| if ( mxFileDlg.is() ) |
| { |
| try |
| { |
| mxFileDlg->setDisplayDirectory( maPath ); |
| } |
| catch( const IllegalArgumentException& ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::displayFolder: caught an exception!" ); |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::setFileName( const ::rtl::OUString& _rFile ) |
| { |
| maFileName = _rFile; |
| if ( mxFileDlg.is() ) |
| { |
| try |
| { |
| mxFileDlg->setDefaultName( maFileName ); |
| } |
| catch( const IllegalArgumentException& ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::setFileName: caught an exception!" ); |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::setFilter( const OUString& rFilter ) |
| { |
| DBG_ASSERT( rFilter.indexOf(':') == -1, "Old filter name used!"); |
| |
| maCurFilter = rFilter; |
| |
| if ( rFilter.getLength() && mpMatcher ) |
| { |
| const SfxFilter* pFilter = mpMatcher->GetFilter4FilterName( |
| rFilter, m_nMustFlags, m_nDontFlags ); |
| if ( pFilter ) |
| maCurFilter = pFilter->GetUIName(); |
| } |
| |
| uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY ); |
| |
| if ( maCurFilter.getLength() && xFltMgr.is() ) |
| { |
| try |
| { |
| xFltMgr->setCurrentFilter( maCurFilter ); |
| } |
| catch( IllegalArgumentException ){} |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::createMatcher( const String& rFactory ) |
| { |
| mpMatcher = new SfxFilterMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) ); |
| mbDeleteMatcher = sal_True; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::addFilters( sal_Int64 nFlags, |
| const String& rFactory, |
| SfxFilterFlags nMust, |
| SfxFilterFlags nDont ) |
| { |
| uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY ); |
| |
| if ( ! xFltMgr.is() ) |
| return; |
| |
| // we still need a matcher to convert UI names to filter names |
| if ( !rFactory.Len() ) |
| { |
| SfxApplication *pSfxApp = SFX_APP(); |
| mpMatcher = &pSfxApp->GetFilterMatcher(); |
| mbDeleteMatcher = sal_False; |
| } |
| else |
| { |
| mpMatcher = new SfxFilterMatcher( rFactory ); |
| mbDeleteMatcher = sal_True; |
| } |
| |
| uno::Reference< XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); |
| uno::Reference< XContainerQuery > xFilterCont( |
| xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.FilterFactory")), |
| UNO_QUERY); |
| if ( ! xFilterCont.is() ) |
| return; |
| |
| m_nMustFlags |= nMust; |
| m_nDontFlags |= nDont; |
| |
| // create the list of filters |
| ::rtl::OUStringBuffer sQuery(256); |
| sQuery.appendAscii("getSortedFilterList()"); |
| sQuery.appendAscii(":module=" ); |
| sQuery.append (rFactory ); // use long name here ! |
| sQuery.appendAscii(":iflags=" ); |
| sQuery.append (::rtl::OUString::valueOf((sal_Int32)m_nMustFlags)); |
| sQuery.appendAscii(":eflags=" ); |
| sQuery.append (::rtl::OUString::valueOf((sal_Int32)m_nDontFlags)); |
| |
| uno::Reference< XEnumeration > xResult; |
| try |
| { |
| xResult = xFilterCont->createSubSetEnumerationByQuery(sQuery.makeStringAndClear()); |
| } |
| catch( uno::Exception& ) |
| { |
| DBG_ERRORFILE( "Could not get filters from the configuration!" ); |
| } |
| |
| TSortedFilterList aIter (xResult); |
| |
| // no matcher any longer used ... |
| mbDeleteMatcher = sal_False; |
| |
| // append the filters |
| ::rtl::OUString sFirstFilter; |
| if ( WB_OPEN == ( nFlags & WB_OPEN ) ) |
| ::sfx2::appendFiltersForOpen( aIter, xFltMgr, sFirstFilter, *this ); |
| else if ( mbExport ) |
| ::sfx2::appendExportFilters( aIter, xFltMgr, sFirstFilter, *this ); |
| else |
| ::sfx2::appendFiltersForSave( aIter, xFltMgr, sFirstFilter, *this, rFactory ); |
| |
| // set our initial selected filter (if we do not already have one) |
| if ( !maSelectFilter.getLength() ) |
| maSelectFilter = sFirstFilter; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::addFilter( const OUString& rFilterName, |
| const OUString& rExtension ) |
| { |
| uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY ); |
| |
| if ( ! xFltMgr.is() ) |
| return; |
| |
| try |
| { |
| xFltMgr->appendFilter( rFilterName, rExtension ); |
| |
| if ( !maSelectFilter.getLength() ) |
| maSelectFilter = rFilterName; |
| } |
| catch( IllegalArgumentException ) |
| { |
| #ifdef DBG_UTIL |
| ByteString aMsg( "Could not append Filter" ); |
| aMsg += ByteString( String( rFilterName ), RTL_TEXTENCODING_UTF8 ); |
| DBG_ERRORFILE( aMsg.GetBuffer() ); |
| #endif |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::addGraphicFilter() |
| { |
| uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY ); |
| |
| if ( ! xFltMgr.is() ) |
| return; |
| |
| // create the list of filters |
| mpGraphicFilter = new GraphicFilter; |
| sal_uInt16 i, j, nCount = mpGraphicFilter->GetImportFormatCount(); |
| |
| // compute the extension string for all known import filters |
| String aExtensions; |
| |
| for ( i = 0; i < nCount; i++ ) |
| { |
| j = 0; |
| String sWildcard; |
| while( sal_True ) |
| { |
| sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ ); |
| if ( !sWildcard.Len() ) |
| break; |
| if ( aExtensions.Search( sWildcard ) == STRING_NOTFOUND ) |
| { |
| if ( aExtensions.Len() ) |
| aExtensions += sal_Unicode(';'); |
| aExtensions += sWildcard; |
| } |
| } |
| } |
| |
| #if defined(WNT) |
| if ( aExtensions.Len() > 240 ) |
| aExtensions = DEFINE_CONST_UNICODE( FILEDIALOG_FILTER_ALL ); |
| #endif |
| sal_Bool bIsInOpenMode = isInOpenMode(); |
| |
| try |
| { |
| OUString aAllFilterName = String( SfxResId( STR_SFX_IMPORT_ALL ) ); |
| aAllFilterName = ::sfx2::addExtension( aAllFilterName, aExtensions, bIsInOpenMode, *this ); |
| |
| xFltMgr->appendFilter( aAllFilterName, aExtensions ); |
| maSelectFilter = aAllFilterName; |
| } |
| catch( IllegalArgumentException ) |
| { |
| DBG_ERRORFILE( "Could not append Filter" ); |
| } |
| |
| // Now add the filter |
| for ( i = 0; i < nCount; i++ ) |
| { |
| String aName = mpGraphicFilter->GetImportFormatName( i ); |
| String aExt; |
| j = 0; |
| String sWildcard; |
| while( sal_True ) |
| { |
| sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ ); |
| if ( !sWildcard.Len() ) |
| break; |
| if ( aExt.Search( sWildcard ) == STRING_NOTFOUND ) |
| { |
| if ( aExt.Len() ) |
| aExt += sal_Unicode(';'); |
| aExt += sWildcard; |
| } |
| } |
| aName = ::sfx2::addExtension( aName, aExt, bIsInOpenMode, *this ); |
| try |
| { |
| xFltMgr->appendFilter( aName, aExt ); |
| } |
| catch( IllegalArgumentException ) |
| { |
| DBG_ERRORFILE( "Could not append Filter" ); |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| #define GRF_CONFIG_STR " " |
| #define STD_CONFIG_STR "1 " |
| |
| void FileDialogHelper_Impl::saveConfig() |
| { |
| uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY ); |
| Any aValue; |
| |
| if ( ! xDlg.is() ) |
| return; |
| |
| if ( mbHasPreview ) |
| { |
| SvtViewOptions aDlgOpt( E_DIALOG, IMPGRF_CONFIGNAME ); |
| String aUserData = DEFINE_CONST_UNICODE( GRF_CONFIG_STR ); |
| |
| try |
| { |
| aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0 ); |
| sal_Bool bValue = sal_False; |
| aValue >>= bValue; |
| aUserData.SetToken( 0, ' ', String::CreateFromInt32( (sal_Int32) bValue ) ); |
| |
| aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 ); |
| bValue = sal_False; |
| aValue >>= bValue; |
| aUserData.SetToken( 1, ' ', String::CreateFromInt32( (sal_Int32) bValue ) ); |
| |
| INetURLObject aObj( getPath() ); |
| |
| if ( aObj.GetProtocol() == INET_PROT_FILE ) |
| aUserData.SetToken( 2, ' ', aObj.GetMainURL( INetURLObject::NO_DECODE ) ); |
| |
| String aFilter = getFilter(); |
| aFilter = EncodeSpaces_Impl( aFilter ); |
| aUserData.SetToken( 3, ' ', aFilter ); |
| |
| aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) ); |
| } |
| catch( IllegalArgumentException ){} |
| } |
| else |
| { |
| sal_Bool bWriteConfig = sal_False; |
| SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME ); |
| String aUserData = DEFINE_CONST_UNICODE( STD_CONFIG_STR ); |
| |
| if ( aDlgOpt.Exists() ) |
| { |
| Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME ); |
| OUString aTemp; |
| if ( aUserItem >>= aTemp ) |
| aUserData = String( aTemp ); |
| } |
| |
| if ( mbHasAutoExt ) |
| { |
| try |
| { |
| aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 ); |
| sal_Bool bAutoExt = sal_True; |
| aValue >>= bAutoExt; |
| aUserData.SetToken( 0, ' ', String::CreateFromInt32( (sal_Int32) bAutoExt ) ); |
| bWriteConfig = sal_True; |
| } |
| catch( IllegalArgumentException ){} |
| } |
| |
| if ( ! mbIsSaveDlg ) |
| { |
| OUString aPath = getPath(); |
| if ( aPath.getLength() && |
| utl::LocalFileHelper::IsLocalFile( aPath ) ) |
| { |
| aUserData.SetToken( 1, ' ', aPath ); |
| bWriteConfig = sal_True; |
| } |
| } |
| |
| if( mbHasSelectionBox && mbSelectionFltrEnabled ) |
| { |
| try |
| { |
| aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 ); |
| sal_Bool bSelection = sal_True; |
| aValue >>= bSelection; |
| if ( aUserData.GetTokenCount(' ') < 3 ) |
| aUserData.Append(' '); |
| aUserData.SetToken( 2, ' ', String::CreateFromInt32( (sal_Int32) bSelection ) ); |
| bWriteConfig = sal_True; |
| } |
| catch( IllegalArgumentException ){} |
| } |
| |
| if ( bWriteConfig ) |
| aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) ); |
| } |
| |
| SfxApplication *pSfxApp = SFX_APP(); |
| pSfxApp->SetLastDir_Impl( getPath() ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| namespace |
| { |
| static ::rtl::OUString getInitPath( const String& _rFallback, const xub_StrLen _nFallbackToken ) |
| { |
| SfxApplication *pSfxApp = SFX_APP(); |
| String sPath = pSfxApp->GetLastDir_Impl(); |
| |
| if ( !sPath.Len() ) |
| sPath = _rFallback.GetToken( _nFallbackToken, ' ' ); |
| |
| // check if the path points to a valid (accessible) directory |
| sal_Bool bValid = sal_False; |
| if ( sPath.Len() ) |
| { |
| String sPathCheck( sPath ); |
| if ( sPathCheck.GetBuffer()[ sPathCheck.Len() - 1 ] != '/' ) |
| sPathCheck += '/'; |
| sPathCheck += '.'; |
| try |
| { |
| ::ucbhelper::Content aContent( sPathCheck, uno::Reference< ucb::XCommandEnvironment >() ); |
| bValid = aContent.isFolder(); |
| } |
| catch( Exception& ) {} |
| } |
| |
| if ( !bValid ) |
| sPath.Erase(); |
| |
| return sPath; |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::loadConfig() |
| { |
| uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY ); |
| Any aValue; |
| |
| if ( ! xDlg.is() ) |
| return; |
| |
| if ( mbHasPreview ) |
| { |
| SvtViewOptions aViewOpt( E_DIALOG, IMPGRF_CONFIGNAME ); |
| String aUserData; |
| |
| if ( aViewOpt.Exists() ) |
| { |
| Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME ); |
| OUString aTemp; |
| if ( aUserItem >>= aTemp ) |
| aUserData = String( aTemp ); |
| } |
| |
| if ( aUserData.Len() > 0 ) |
| { |
| try |
| { |
| // respect the last "insert as link" state |
| sal_Bool bLink = (sal_Bool) aUserData.GetToken( 0, ' ' ).ToInt32(); |
| aValue <<= bLink; |
| xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, aValue ); |
| |
| // respect the last "show preview" state |
| sal_Bool bShowPreview = (sal_Bool) aUserData.GetToken( 1, ' ' ).ToInt32(); |
| aValue <<= bShowPreview; |
| xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, aValue ); |
| |
| if ( !maPath.getLength() ) |
| displayFolder( getInitPath( aUserData, 2 ) ); |
| |
| if ( ! maCurFilter.getLength() ) |
| { |
| String aFilter = aUserData.GetToken( 3, ' ' ); |
| aFilter = DecodeSpaces_Impl( aFilter ); |
| setFilter( aFilter ); |
| } |
| |
| // set the member so we know that we have to show the preview |
| mbShowPreview = bShowPreview; |
| } |
| catch( IllegalArgumentException ){} |
| } |
| |
| if ( !maPath.getLength() ) |
| displayFolder( SvtPathOptions().GetGraphicPath() ); |
| } |
| else |
| { |
| SvtViewOptions aViewOpt( E_DIALOG, IODLG_CONFIGNAME ); |
| String aUserData; |
| |
| if ( aViewOpt.Exists() ) |
| { |
| Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME ); |
| OUString aTemp; |
| if ( aUserItem >>= aTemp ) |
| aUserData = String( aTemp ); |
| } |
| |
| if ( ! aUserData.Len() ) |
| aUserData = DEFINE_CONST_UNICODE( STD_CONFIG_STR ); |
| |
| if ( ! maPath.getLength() ) |
| displayFolder( getInitPath( aUserData, 1 ) ); |
| |
| if ( mbHasAutoExt ) |
| { |
| sal_Int32 nFlag = aUserData.GetToken( 0, ' ' ).ToInt32(); |
| aValue <<= (sal_Bool) nFlag; |
| try |
| { |
| xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue ); |
| } |
| catch( IllegalArgumentException ){} |
| } |
| |
| if( mbHasSelectionBox ) |
| { |
| sal_Int32 nFlag = aUserData.GetToken( 2, ' ' ).ToInt32(); |
| aValue <<= (sal_Bool) nFlag; |
| try |
| { |
| xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, aValue ); |
| } |
| catch( IllegalArgumentException ){} |
| } |
| |
| if ( !maPath.getLength() ) |
| displayFolder( SvtPathOptions().GetWorkPath() ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper_Impl::setDefaultValues() |
| { |
| // when no filter is set, we set the curentFilter to <all> |
| if ( !maCurFilter.getLength() && maSelectFilter.getLength() ) |
| { |
| uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY ); |
| try |
| { |
| xFltMgr->setCurrentFilter( maSelectFilter ); |
| } |
| catch( IllegalArgumentException ) |
| {} |
| } |
| |
| // when no path is set, we use the standard 'work' folder |
| if ( ! maPath.getLength() ) |
| { |
| OUString aWorkFolder = SvtPathOptions().GetWorkPath(); |
| try |
| { |
| mxFileDlg->setDisplayDirectory( aWorkFolder ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "FileDialogHelper_Impl::setDefaultValues: caught an exception while setting the display directory!" ); |
| } |
| |
| // INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() ); |
| //SetStandardDir( aStdDirObj.GetMainURL( INetURLObject::NO_DECODE ) ); |
| } |
| } |
| |
| sal_Bool FileDialogHelper_Impl::isShowFilterExtensionEnabled() const |
| { |
| return !maFilters.empty(); |
| } |
| |
| void FileDialogHelper_Impl::addFilterPair( const OUString& rFilter, |
| const OUString& rFilterWithExtension ) |
| { |
| maFilters.push_back( FilterPair( rFilter, rFilterWithExtension ) ); |
| |
| } |
| |
| OUString FileDialogHelper_Impl::getFilterName( const OUString& rFilterWithExtension ) const |
| { |
| OUString sRet; |
| for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter ) |
| { |
| if ( (*pIter).Second == rFilterWithExtension ) |
| { |
| sRet = (*pIter).First; |
| break; |
| } |
| } |
| return sRet; |
| } |
| |
| OUString FileDialogHelper_Impl::getFilterWithExtension( const OUString& rFilter ) const |
| { |
| OUString sRet; |
| for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter ) |
| { |
| if ( (*pIter).First == rFilter ) |
| { |
| sRet = (*pIter).Second; |
| break; |
| } |
| } |
| return sRet; |
| } |
| |
| void FileDialogHelper_Impl::SetContext( FileDialogHelper::Context _eNewContext ) |
| { |
| meContext = _eNewContext; |
| |
| sal_Int32 nNewHelpId = 0; |
| OUString aConfigId; |
| |
| switch( _eNewContext ) |
| { |
| // #104952# dependency to SVX not allowed! When used again, another solution has to be found |
| // case FileDialogHelper::SW_INSERT_GRAPHIC: |
| // case FileDialogHelper::SC_INSERT_GRAPHIC: |
| // case FileDialogHelper::SD_INSERT_GRAPHIC: nNewHelpId = SID_INSERT_GRAPHIC; break; |
| case FileDialogHelper::SW_INSERT_SOUND: |
| case FileDialogHelper::SC_INSERT_SOUND: |
| case FileDialogHelper::SD_INSERT_SOUND: nNewHelpId = SID_INSERT_SOUND; break; |
| case FileDialogHelper::SW_INSERT_VIDEO: |
| case FileDialogHelper::SC_INSERT_VIDEO: |
| case FileDialogHelper::SD_INSERT_VIDEO: nNewHelpId = SID_INSERT_VIDEO; break; |
| default: break; |
| } |
| |
| const OUString* pConfigId = GetLastFilterConfigId( _eNewContext ); |
| if( pConfigId ) |
| LoadLastUsedFilter( *pConfigId ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // ----------- FileDialogHelper --------------------------- |
| // ------------------------------------------------------------------------ |
| |
| FileDialogHelper::FileDialogHelper( |
| sal_Int64 nFlags, |
| const String& rFact, |
| SfxFilterFlags nMust, |
| SfxFilterFlags nDont ) |
| { |
| mpImp = new FileDialogHelper_Impl( this, getDialogType( nFlags ), nFlags ); |
| mxImp = mpImp; |
| |
| // create the list of filters |
| mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont ); |
| } |
| |
| FileDialogHelper::FileDialogHelper( |
| sal_Int64 nFlags, |
| const String& rFact, |
| sal_Int16 nDialog, |
| SfxFilterFlags nMust, |
| SfxFilterFlags nDont, |
| const String& rStandardDir, |
| const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList) |
| { |
| mpImp = new FileDialogHelper_Impl( this, getDialogType( nFlags ), nFlags, nDialog, NULL , rStandardDir, rBlackList ); |
| mxImp = mpImp; |
| |
| // create the list of filters |
| mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont ); |
| } |
| |
| FileDialogHelper::FileDialogHelper( |
| sal_Int64 nFlags, |
| const String& rFact, |
| sal_Int16 nDialog, |
| SfxFilterFlags nMust, |
| SfxFilterFlags nDont ) |
| { |
| mpImp = new FileDialogHelper_Impl( this, getDialogType( nFlags ), nFlags, nDialog ); |
| mxImp = mpImp; |
| |
| // create the list of filters |
| mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| FileDialogHelper::FileDialogHelper( sal_Int64 nFlags ) |
| { |
| sal_Int16 nDialogType = getDialogType( nFlags ); |
| |
| mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags ); |
| mxImp = mpImp; |
| } |
| |
| // ------------------------------------------------------------------------ |
| FileDialogHelper::FileDialogHelper( |
| sal_Int16 nDialogType, |
| sal_Int64 nFlags, |
| const String& rFact, |
| SfxFilterFlags nMust, |
| SfxFilterFlags nDont ) |
| { |
| mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags ); |
| mxImp = mpImp; |
| |
| // create the list of filters |
| mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| FileDialogHelper::FileDialogHelper( |
| sal_Int16 nDialogType, |
| sal_Int64 nFlags, |
| const String& rFact, |
| sal_Int16 nDialog, |
| SfxFilterFlags nMust, |
| SfxFilterFlags nDont, |
| const String& rStandardDir, |
| const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList) |
| { |
| mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, nDialog, NULL, rStandardDir, rBlackList ); |
| mxImp = mpImp; |
| |
| // create the list of filters |
| mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| FileDialogHelper::FileDialogHelper( |
| sal_Int16 nDialogType, |
| sal_Int64 nFlags, |
| Window* _pPreferredParent ) |
| { |
| mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent ); |
| mxImp = mpImp; |
| } |
| |
| // ------------------------------------------------------------------------ |
| FileDialogHelper::FileDialogHelper( |
| sal_Int16 nDialogType, |
| sal_Int64 nFlags, |
| const ::rtl::OUString& aFilterUIName, |
| const ::rtl::OUString& aExtName, |
| const ::rtl::OUString& rStandardDir, |
| const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList, |
| Window* _pPreferredParent ) |
| { |
| mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent,rStandardDir, rBlackList ); |
| mxImp = mpImp; |
| |
| // the wildcard here is expected in form "*.extension" |
| ::rtl::OUString aWildcard; |
| if ( aExtName.indexOf( (sal_Unicode)'*' ) != 0 ) |
| { |
| if ( aExtName.getLength() && aExtName.indexOf( (sal_Unicode)'.' ) != 0 ) |
| aWildcard = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*." ) ); |
| else |
| aWildcard = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*" ) ); |
| } |
| |
| aWildcard += aExtName; |
| |
| ::rtl::OUString aUIString = |
| ::sfx2::addExtension( aFilterUIName, aWildcard, ( WB_OPEN == ( nFlags & WB_OPEN ) ), *mpImp ); |
| AddFilter( aUIString, aWildcard ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| FileDialogHelper::~FileDialogHelper() |
| { |
| mpImp->dispose(); |
| mxImp.clear(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper::CreateMatcher( const String& rFactory ) |
| { |
| mpImp->createMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper::SetControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId ) |
| { |
| mpImp->setControlHelpIds( _pControlId, _pHelpId ); |
| } |
| |
| void FileDialogHelper::SetContext( Context _eNewContext ) |
| { |
| mpImp->SetContext( _eNewContext ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| IMPL_LINK( FileDialogHelper, ExecuteSystemFilePicker, void*, EMPTYARG ) |
| { |
| m_nError = mpImp->execute(); |
| if ( m_aDialogClosedLink.IsSet() ) |
| m_aDialogClosedLink.Call( this ); |
| |
| return 0L; |
| } |
| |
| // ------------------------------------------------------------------------ |
| // rDirPath has to be a directory |
| ErrCode FileDialogHelper::Execute( SvStringsDtor*& rpURLList, |
| SfxItemSet *& rpSet, |
| String& rFilter, |
| const String& rDirPath ) |
| { |
| SetDisplayFolder( rDirPath ); |
| return mpImp->execute( rpURLList, rpSet, rFilter ); |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| ErrCode FileDialogHelper::Execute() |
| { |
| return mpImp->execute(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| ErrCode FileDialogHelper::Execute( SfxItemSet *& rpSet, |
| String& rFilter ) |
| { |
| ErrCode nRet; |
| SvStringsDtor* pURLList; |
| |
| nRet = mpImp->execute( pURLList, rpSet, rFilter ); |
| |
| delete pURLList; |
| |
| return nRet; |
| } |
| |
| void FileDialogHelper::StartExecuteModal( const Link& rEndDialogHdl ) |
| { |
| m_aDialogClosedLink = rEndDialogHdl; |
| m_nError = ERRCODE_NONE; |
| if ( mpImp->isSystemFilePicker() ) |
| Application::PostUserEvent( LINK( this, FileDialogHelper, ExecuteSystemFilePicker ) ); |
| else |
| mpImp->implStartExecute(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| |
| short FileDialogHelper::GetDialogType() const |
| { |
| return mpImp ? mpImp->m_nDialogType : 0; |
| } |
| |
| // ------------------------------------------------------------------------ |
| |
| sal_Bool FileDialogHelper::IsPasswordEnabled() const |
| { |
| return mpImp ? mpImp->isPasswordEnabled() : sal_False; |
| } |
| |
| // ------------------------------------------------------------------------ |
| |
| String FileDialogHelper::GetRealFilter() const |
| { |
| String sFilter; |
| if ( mpImp ) |
| mpImp->getRealFilter( sFilter ); |
| return sFilter; |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper::SetTitle( const String& rNewTitle ) |
| { |
| if ( mpImp->mxFileDlg.is() ) |
| mpImp->mxFileDlg->setTitle( rNewTitle ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| String FileDialogHelper::GetPath() const |
| { |
| OUString aPath; |
| |
| if ( mpImp->mlLastURLs.size() > 0) |
| return mpImp->mlLastURLs[0]; |
| |
| if ( mpImp->mxFileDlg.is() ) |
| { |
| Sequence < OUString > aPathSeq = mpImp->mxFileDlg->getFiles(); |
| |
| if ( aPathSeq.getLength() == 1 ) |
| { |
| aPath = aPathSeq[0]; |
| } |
| } |
| |
| return aPath; |
| } |
| |
| // ------------------------------------------------------------------------ |
| Sequence < OUString > FileDialogHelper::GetMPath() const |
| { |
| if ( mpImp->mlLastURLs.size() > 0) |
| return mpImp->mlLastURLs.getAsConstList(); |
| |
| if ( mpImp->mxFileDlg.is() ) |
| return mpImp->mxFileDlg->getFiles(); |
| else |
| { |
| Sequence < OUString > aEmpty; |
| return aEmpty; |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| Sequence< ::rtl::OUString > FileDialogHelper::GetSelectedFiles() const |
| { |
| // a) the new way (optional!) |
| uno::Sequence< ::rtl::OUString > aResultSeq; |
| uno::Reference< XFilePicker2 > xPickNew(mpImp->mxFileDlg, UNO_QUERY); |
| if (xPickNew.is()) |
| { |
| aResultSeq = xPickNew->getSelectedFiles(); |
| } |
| // b) the olde way ... non optional. |
| else |
| { |
| uno::Reference< XFilePicker > xPickOld(mpImp->mxFileDlg, UNO_QUERY_THROW); |
| Sequence< OUString > lFiles = xPickOld->getFiles(); |
| ::sal_Int32 nFiles = lFiles.getLength(); |
| if ( nFiles > 1 ) |
| { |
| aResultSeq = Sequence< ::rtl::OUString >( nFiles-1 ); |
| |
| INetURLObject aPath( lFiles[0] ); |
| aPath.setFinalSlash(); |
| |
| for (::sal_Int32 i = 1; i < nFiles; i++) |
| { |
| if (i == 1) |
| aPath.Append( lFiles[i] ); |
| else |
| aPath.setName( lFiles[i] ); |
| |
| aResultSeq[i-1] = ::rtl::OUString(aPath.GetMainURL( INetURLObject::NO_DECODE )); |
| } |
| } |
| else |
| aResultSeq = lFiles; |
| } |
| |
| return aResultSeq; |
| } |
| |
| // ------------------------------------------------------------------------ |
| String FileDialogHelper::GetDisplayDirectory() const |
| { |
| return mpImp->getPath(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| String FileDialogHelper::GetCurrentFilter() const |
| { |
| return mpImp->getFilter(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| ErrCode FileDialogHelper::GetGraphic( Graphic& rGraphic ) const |
| { |
| return mpImp->getGraphic( rGraphic ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| static int impl_isFolder( const OUString& rPath ) |
| { |
| uno::Reference< task::XInteractionHandler > xHandler; |
| try |
| { |
| uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW ); |
| xHandler.set( xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.task.InteractionHandler" ) ), |
| uno::UNO_QUERY_THROW ); |
| } |
| catch ( Exception const & ) |
| { |
| } |
| |
| ::rtl::Reference< ::comphelper::StillReadWriteInteraction > aHandler = new ::comphelper::StillReadWriteInteraction( xHandler , uno::Reference< task::XInteractionHandler >()); |
| |
| try |
| { |
| ::ucbhelper::Content aContent( |
| rPath, new ::ucbhelper::CommandEnvironment( static_cast< task::XInteractionHandler* > ( aHandler.get() ), uno::Reference< ucb::XProgressHandler >() ) ); |
| if ( aContent.isFolder() ) |
| return 1; |
| |
| return 0; |
| } |
| catch ( Exception const & ) |
| { |
| } |
| |
| return -1; |
| } |
| |
| void FileDialogHelper::SetDisplayDirectory( const String& _rPath ) |
| { |
| if ( !_rPath.Len() ) |
| return; |
| |
| // if the given path isn't a folder, we cut off the last part |
| // and take it as filename and the rest of the path should be |
| // the folder |
| |
| INetURLObject aObj( _rPath ); |
| |
| ::rtl::OUString sFileName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ); |
| aObj.removeSegment(); |
| ::rtl::OUString sPath = aObj.GetMainURL( INetURLObject::NO_DECODE ); |
| |
| int nIsFolder = impl_isFolder( _rPath ); |
| if ( nIsFolder == 0 || |
| ( nIsFolder == -1 && impl_isFolder( sPath ) == 1 ) ) |
| { |
| mpImp->setFileName( sFileName ); |
| mpImp->displayFolder( sPath ); |
| } |
| else |
| { |
| INetURLObject aObjPathName( _rPath ); |
| ::rtl::OUString sFolder( aObjPathName.GetMainURL( INetURLObject::NO_DECODE ) ); |
| if ( sFolder.getLength() == 0 ) |
| { |
| // _rPath is not a valid path -> fallback to home directory |
| vos:: OSecurity aSecurity; |
| aSecurity.getHomeDir( sFolder ); |
| } |
| mpImp->displayFolder( sFolder ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper::SetDisplayFolder( const String& _rURL ) |
| { |
| mpImp->displayFolder( _rURL ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper::SetFileName( const String& _rFileName ) |
| { |
| mpImp->setFileName( _rFileName ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper::AddFilter( const String& rFilterName, |
| const String& rExtension ) |
| { |
| mpImp->addFilter( rFilterName, rExtension ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void FileDialogHelper::SetCurrentFilter( const String& rFilter ) |
| { |
| String sFilter( rFilter ); |
| if ( mpImp->isShowFilterExtensionEnabled() ) |
| sFilter = mpImp->getFilterWithExtension( rFilter ); |
| mpImp->setFilter( sFilter ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| uno::Reference < XFilePicker > FileDialogHelper::GetFilePicker() const |
| { |
| return mpImp->mxFileDlg; |
| } |
| |
| // ------------------------------------------------------------------------ |
| sal_Int16 FileDialogHelper::getDialogType( sal_Int64 nFlags ) const |
| { |
| sal_Int16 nDialogType = FILEOPEN_SIMPLE; |
| |
| if ( nFlags & WB_SAVEAS ) |
| { |
| if ( nFlags & SFXWB_PASSWORD ) |
| nDialogType = FILESAVE_AUTOEXTENSION_PASSWORD; |
| else |
| nDialogType = FILESAVE_SIMPLE; |
| } |
| else if ( nFlags & SFXWB_GRAPHIC ) |
| { |
| if ( nFlags & SFXWB_SHOWSTYLES ) |
| nDialogType = FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE; |
| else |
| nDialogType = FILEOPEN_LINK_PREVIEW; |
| } |
| else if ( SFXWB_INSERT != ( nFlags & SFXWB_INSERT ) ) |
| nDialogType = FILEOPEN_READONLY_VERSION; |
| |
| return nDialogType; |
| } |
| |
| // ------------------------------------------------------------------------ |
| // XFilePickerListener Methods |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper::FileSelectionChanged( const FilePickerEvent& aEvent ) |
| { |
| mpImp->handleFileSelectionChanged( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper::DirectoryChanged( const FilePickerEvent& aEvent ) |
| { |
| mpImp->handleDirectoryChanged( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| OUString SAL_CALL FileDialogHelper::HelpRequested( const FilePickerEvent& aEvent ) |
| { |
| return mpImp->handleHelpRequested( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper::ControlStateChanged( const FilePickerEvent& aEvent ) |
| { |
| mpImp->handleControlStateChanged( aEvent ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper::DialogSizeChanged() |
| { |
| mpImp->handleDialogSizeChanged(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| void SAL_CALL FileDialogHelper::DialogClosed( const DialogClosedEvent& _rEvent ) |
| { |
| m_nError = ( RET_OK == _rEvent.DialogResult ) ? ERRCODE_NONE : ERRCODE_ABORT; |
| if ( m_aDialogClosedLink.IsSet() ) |
| m_aDialogClosedLink.Call( this ); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // ------------------------------------------------------------------------ |
| // ------------------------------------------------------------------------ |
| |
| ErrCode FileOpenDialog_Impl( sal_Int64 nFlags, |
| const String& rFact, |
| SvStringsDtor *& rpURLList, |
| String& rFilter, |
| SfxItemSet *& rpSet, |
| const String* pPath, |
| sal_Int16 nDialog, |
| const String& rStandardDir, |
| const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) |
| { |
| ErrCode nRet; |
| FileDialogHelper aDialog( nFlags, rFact, nDialog, 0, 0, rStandardDir, rBlackList ); |
| |
| String aPath; |
| if ( pPath ) |
| aPath = *pPath; |
| |
| nRet = aDialog.Execute( rpURLList, rpSet, rFilter, aPath ); |
| DBG_ASSERT( rFilter.SearchAscii(": ") == STRING_NOTFOUND, "Old filter name used!"); |
| |
| return nRet; |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| String EncodeSpaces_Impl( const String& rSource ) |
| { |
| String sRet( rSource ); |
| sRet.SearchAndReplaceAll( DEFINE_CONST_UNICODE( " " ), DEFINE_CONST_UNICODE( "%20" ) ); |
| return sRet; |
| } |
| |
| // ------------------------------------------------------------------------ |
| String DecodeSpaces_Impl( const String& rSource ) |
| { |
| String sRet( rSource ); |
| sRet.SearchAndReplaceAll( DEFINE_CONST_UNICODE( "%20" ), DEFINE_CONST_UNICODE( " " ) ); |
| return sRet; |
| } |
| |
| // ------------------------------------------------------------------------ |
| |
| } // end of namespace sfx2 |
| |