diff options
Diffstat (limited to 'fpicker/source/win32/filepicker')
-rw-r--r-- | fpicker/source/win32/filepicker/FPServiceInfo.hxx | 6 | ||||
-rw-r--r-- | fpicker/source/win32/filepicker/FPentry.cxx | 17 | ||||
-rw-r--r-- | fpicker/source/win32/filepicker/VistaFilePicker.cxx | 46 | ||||
-rw-r--r-- | fpicker/source/win32/filepicker/VistaFilePicker.hxx | 21 | ||||
-rw-r--r-- | fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx | 177 | ||||
-rw-r--r-- | fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx | 17 | ||||
-rw-r--r-- | fpicker/source/win32/filepicker/vistatypes.h | 1 |
7 files changed, 197 insertions, 88 deletions
diff --git a/fpicker/source/win32/filepicker/FPServiceInfo.hxx b/fpicker/source/win32/filepicker/FPServiceInfo.hxx index 36aadf4b1c97..edc350c1a9cc 100644 --- a/fpicker/source/win32/filepicker/FPServiceInfo.hxx +++ b/fpicker/source/win32/filepicker/FPServiceInfo.hxx @@ -26,6 +26,12 @@ // the implementation names #define FILE_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.Win32FilePicker" +// the service names +#define FOLDER_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.SystemFolderPicker" + +// the implementation names +#define FOLDER_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.Win32FolderPicker" + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/fpicker/source/win32/filepicker/FPentry.cxx b/fpicker/source/win32/filepicker/FPentry.cxx index 2166ba82e6d4..d62dda491128 100644 --- a/fpicker/source/win32/filepicker/FPentry.cxx +++ b/fpicker/source/win32/filepicker/FPentry.cxx @@ -25,32 +25,27 @@ #include "../misc/WinImplHelper.hxx" #include <stdio.h> -#include "../folderpicker/FolderPicker.hxx" -#include "../folderpicker/FOPServiceInfo.hxx" -#include "../folderpicker/WinFOPImpl.hxx" - +using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::container; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::registry; using namespace ::cppu; using ::com::sun::star::ui::dialogs::XFilePicker2; +using ::com::sun::star::ui::dialogs::XFolderPicker2; static Reference< XInterface > createInstance( const Reference< XMultiServiceFactory >& rServiceManager ) { - Reference< XInterface > xDlg; - - xDlg.set(static_cast<XFilePicker2*>( - new ::fpicker::win32::vista::VistaFilePicker(rServiceManager))); - - return xDlg; + return Reference<ui::dialogs::XFilePicker2>( + new ::fpicker::win32::vista::VistaFilePicker(rServiceManager, false)); } static Reference< XInterface > createInstance_fop( const Reference< XMultiServiceFactory >& rServiceManager ) { - return Reference< XInterface >( static_cast< cppu::OWeakObject * >( new CFolderPicker( rServiceManager ) ) ); + return Reference<ui::dialogs::XFolderPicker2>( + new ::fpicker::win32::vista::VistaFilePicker(rServiceManager, true)); } extern "C" diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.cxx b/fpicker/source/win32/filepicker/VistaFilePicker.cxx index c0dde13bda80..17b6a566d8ce 100644 --- a/fpicker/source/win32/filepicker/VistaFilePicker.cxx +++ b/fpicker/source/win32/filepicker/VistaFilePicker.cxx @@ -20,6 +20,7 @@ #include "VistaFilePicker.hxx" #include "../misc/WinImplHelper.hxx" +#include "FPServiceInfo.hxx" #include "shared.hxx" #include <com/sun/star/awt/XWindow.hpp> @@ -46,20 +47,22 @@ namespace { css::uno::Sequence< OUString > VistaFilePicker_getSupportedServiceNames() { - css::uno::Sequence< OUString > aRet(2); + css::uno::Sequence< OUString > aRet(3); aRet[0] = "com.sun.star.ui.dialogs.FilePicker"; aRet[1] = "com.sun.star.ui.dialogs.SystemFilePicker"; + aRet[2] = "com.sun.star.ui.dialogs.SystemFolderPicker"; return aRet; } } -VistaFilePicker::VistaFilePicker(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) +VistaFilePicker::VistaFilePicker(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR, bool bFolderPicker) : TVistaFilePickerBase (m_aMutex ) , m_xSMGR (xSMGR ) , m_rDialog (new VistaFilePickerImpl()) , m_aAsyncExecute (m_rDialog ) , m_nFilePickerThreadId (0 ) , m_bInitialized (false ) + , m_bFolderPicker (bFolderPicker ) { } @@ -233,9 +236,24 @@ void VistaFilePicker::ensureInit() if ( !bInitialized ) { - css::uno::Sequence < css::uno::Any > aInitArguments(1); - aInitArguments[0] <<= css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE; - initialize(aInitArguments); + if (m_bFolderPicker) + { + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_CREATE_FOLDER_PICKER); + if ( ! m_aAsyncExecute.isRunning()) + m_aAsyncExecute.create(); + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); + { + osl::MutexGuard aGuard(m_aMutex); + m_bInitialized = true; + } + } + else + { + css::uno::Sequence < css::uno::Any > aInitArguments(1); + aInitArguments[0] <<= css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE; + initialize(aInitArguments); + } } } @@ -507,11 +525,27 @@ void SAL_CALL VistaFilePicker::cancel() { } +OUString SAL_CALL VistaFilePicker::getDirectory() +{ + ensureInit(); + css::uno::Sequence< OUString > aFileSeq = getSelectedFiles(); + assert(aFileSeq.getLength() <= 1); + return aFileSeq.getLength() ? aFileSeq[0] : OUString(); +} + +void SAL_CALL VistaFilePicker::setDescription( const OUString& aDescription ) +{ + setTitle(aDescription); +} + // XServiceInfo OUString SAL_CALL VistaFilePicker::getImplementationName() { - return OUString("com.sun.star.comp.fpicker.VistaFileDialog"); + if (m_bFolderPicker) + return OUString(FOLDER_PICKER_IMPL_NAME); + else + return OUString(FILE_PICKER_IMPL_NAME); } sal_Bool SAL_CALL VistaFilePicker::supportsService(const OUString& sServiceName) diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.hxx b/fpicker/source/win32/filepicker/VistaFilePicker.hxx index 8f36f5438698..8a138cc90f21 100644 --- a/fpicker/source/win32/filepicker/VistaFilePicker.hxx +++ b/fpicker/source/win32/filepicker/VistaFilePicker.hxx @@ -30,6 +30,7 @@ #include <com/sun/star/ui/dialogs/XFilePicker3.hpp> #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> #include <com/sun/star/ui/dialogs/XFilePreview.hpp> +#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp> #include <cppuhelper/compbase.hxx> #include <cppuhelper/basemutex.hxx> @@ -47,6 +48,7 @@ typedef ::cppu::WeakComponentImplHelper< css::ui::dialogs::XFilePicker3, css::ui::dialogs::XFilePickerControlAccess, css::ui::dialogs::XFilePreview, + css::ui::dialogs::XFolderPicker2, css::lang::XInitialization, css::lang::XServiceInfo > TVistaFilePickerBase; @@ -67,7 +69,7 @@ public: // ctor/dtor - explicit VistaFilePicker( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ); + explicit VistaFilePicker( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR, bool bFolderPicker ); virtual ~VistaFilePicker() override; @@ -187,22 +189,14 @@ public: virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; - /* - // FilePicker Event functions + // XFolderPicker functions - void SAL_CALL fileSelectionChanged(const css::ui::dialogs::FilePickerEvent& aEvent ); - void SAL_CALL directoryChanged(const css::ui::dialogs::FilePickerEvent& aEvent ); - OUString SAL_CALL helpRequested(const css::ui::dialogs::FilePickerEvent& aEvent ) const; - void SAL_CALL controlStateChanged(const css::ui::dialogs::FilePickerEvent& aEvent ); - void SAL_CALL dialogSizeChanged( ); + virtual OUString SAL_CALL getDirectory( ) override; + + virtual void SAL_CALL setDescription( const OUString& aDescription ) override; - bool startupEventNotification(bool bStartupSuspended); - void shutdownEventNotification(); - void suspendEventNotification(); - void resumeEventNotification(); - */ private: @@ -234,6 +228,7 @@ public: oslThreadIdentifier m_nFilePickerThreadId; bool m_bInitialized; + const bool m_bFolderPicker; }; } // namespace vista diff --git a/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx b/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx index dfc99a336187..598f42a6f58f 100644 --- a/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx +++ b/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx @@ -36,6 +36,7 @@ #include "../misc/WinImplHelper.hxx" #include <shlguid.h> +#include <shlobj.h> inline bool is_current_process_window(HWND hwnd) { @@ -94,28 +95,55 @@ static const GUID CLIENTID_FILEOPEN_LINK = {0x39AC4BAE, 0x7D2D, 0x46B OUString lcl_getURLFromShellItem (IShellItem* pItem) { - LPOLESTR pStr = nullptr; + LPWSTR pStr = nullptr; OUString sURL; + HRESULT hr; - SIGDN eConversion = SIGDN_FILESYSPATH; - HRESULT hr = pItem->GetDisplayName ( eConversion, &pStr ); - - if ( FAILED(hr) ) + hr = pItem->GetDisplayName ( SIGDN_FILESYSPATH, &pStr ); + if (SUCCEEDED(hr)) { - eConversion = SIGDN_URL; - hr = pItem->GetDisplayName ( eConversion, &pStr ); - - if ( FAILED(hr) ) - return OUString(); + ::osl::FileBase::getFileURLFromSystemPath( o3tl::toU(pStr), sURL ); + goto cleanup; + } + hr = pItem->GetDisplayName ( SIGDN_URL, &pStr ); + if (SUCCEEDED(hr)) + { sURL = o3tl::toU(pStr); + goto cleanup; } - else + + hr = pItem->GetDisplayName ( SIGDN_PARENTRELATIVEPARSING, &pStr ); + if (SUCCEEDED(hr)) { - ::osl::FileBase::getFileURLFromSystemPath( o3tl::toU(pStr), sURL ); + GUID known_folder_id; + std::wstring aStr = pStr; + CoTaskMemFree (pStr); + + if (0 == aStr.compare(0, 3, L"::{")) + aStr = aStr.substr(2); + hr = IIDFromString(aStr.c_str(), &known_folder_id); + if (SUCCEEDED(hr)) + { + hr = SHGetKnownFolderPath(known_folder_id, 0, NULL, &pStr); + if (SUCCEEDED(hr)) + { + ::osl::FileBase::getFileURLFromSystemPath(o3tl::toU(pStr), sURL); + goto cleanup; + } + } } + // Default fallback + hr = SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &pStr); + if (SUCCEEDED(hr)) + ::osl::FileBase::getFileURLFromSystemPath(o3tl::toU(pStr), sURL); + else // shouldn't happen... + goto bailout; + +cleanup: CoTaskMemFree (pStr); +bailout: return sURL; } @@ -143,6 +171,7 @@ OUString lcl_getURLFromShellItem (IShellItem* pItem) VistaFilePickerImpl::VistaFilePickerImpl() : m_iDialogOpen () , m_iDialogSave () + , m_iFolderPicker() , m_hLastResult () , m_lFilters () , m_iEventHandler(new VistaFilePickerEventHandler(this)) @@ -219,6 +248,10 @@ void VistaFilePickerImpl::doRequest(const RequestRef& rRequest) impl_sta_CreateSaveDialog(rRequest); break; + case E_CREATE_FOLDER_PICKER: + impl_sta_CreateFolderPicker(rRequest); + break; + case E_SET_MULTISELECTION_MODE : impl_sta_SetMultiSelectionMode(rRequest); break; @@ -399,56 +432,38 @@ void VistaFilePickerImpl::impl_sta_getCurrentFilter(const RequestRef& rRequest) } -void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest) +void VistaFilePickerImpl::impl_sta_CreateDialog(const RequestRef& rRequest, PickerDialog eType, DWORD nOrFlags) { // SYNCHRONIZED-> ::osl::ResettableMutexGuard aLock(m_aMutex); - m_hLastResult = m_iDialogOpen.create(); - if (FAILED(m_hLastResult)) - return; - TFileDialog iDialog; - m_iDialogOpen.query(&iDialog); - - TFileDialogEvents iHandler = m_iEventHandler; - - aLock.clear(); - // <- SYNCHRONIZED - DWORD nFlags = 0; - iDialog->GetOptions ( &nFlags ); - - nFlags &= ~FOS_FORCESHOWHIDDEN; - nFlags |= FOS_PATHMUSTEXIST; - nFlags |= FOS_FILEMUSTEXIST; - nFlags |= FOS_OVERWRITEPROMPT; - nFlags |= FOS_DONTADDTORECENT; - - iDialog->SetOptions ( nFlags ); - - ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, ::sal_Int32(0)); - ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, ::sal_Int32(0)); - impl_sta_enableFeatures(nFeatures, nTemplate); - - VistaFilePickerEventHandler* pHandlerImpl = static_cast<VistaFilePickerEventHandler*>(iHandler.get()); - if (pHandlerImpl) - pHandlerImpl->startListening(iDialog); -} - - -void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest) -{ - // SYNCHRONIZED-> - ::osl::ResettableMutexGuard aLock(m_aMutex); + switch (eType) + { + case PickerDialog::FileOpen: + m_hLastResult = m_iDialogOpen.create(); + if (FAILED(m_hLastResult)) + return; + m_iDialogOpen.query(&iDialog); + break; - m_hLastResult = m_iDialogSave.create(); - if (FAILED(m_hLastResult)) - return; + case PickerDialog::FileSave: + m_hLastResult = m_iDialogSave.create(); + if (FAILED(m_hLastResult)) + return; + m_iDialogSave.query(&iDialog); + break; + + case PickerDialog::Folder: + m_hLastResult = m_iFolderPicker.create(); + if (FAILED(m_hLastResult)) + return; + m_iFolderPicker.query(&iDialog); + break; + } - TFileDialogEvents iHandler = m_iEventHandler; - TFileDialog iDialog; - m_iDialogSave.query(&iDialog); + TFileDialogEvents iHandler = m_iEventHandler; aLock.clear(); // <- SYNCHRONIZED @@ -458,14 +473,11 @@ void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest) nFlags &= ~FOS_FORCESHOWHIDDEN; nFlags |= FOS_PATHMUSTEXIST; - nFlags |= FOS_FILEMUSTEXIST; - nFlags |= FOS_OVERWRITEPROMPT; nFlags |= FOS_DONTADDTORECENT; + nFlags |= nOrFlags; iDialog->SetOptions ( nFlags ); - ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, ::sal_Int32(0)); - ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, ::sal_Int32(0)); css::uno::Reference<css::awt::XWindow> xWindow = rRequest->getArgumentOrDefault(PROP_PARENT_WINDOW, css::uno::Reference<css::awt::XWindow>()); if(xWindow.is()) { @@ -481,6 +493,8 @@ void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest) } } + ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, ::sal_Int32(0)); + ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, ::sal_Int32(0)); impl_sta_enableFeatures(nFeatures, nTemplate); VistaFilePickerEventHandler* pHandlerImpl = static_cast<VistaFilePickerEventHandler*>(iHandler.get()); @@ -489,6 +503,35 @@ void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest) } +void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest) +{ + DWORD nFlags = 0; + nFlags |= FOS_FILEMUSTEXIST; + nFlags |= FOS_OVERWRITEPROMPT; + + impl_sta_CreateDialog(rRequest, PickerDialog::FileOpen, nFlags); +} + + +void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest) +{ + DWORD nFlags = 0; + nFlags |= FOS_FILEMUSTEXIST; + nFlags |= FOS_OVERWRITEPROMPT; + + impl_sta_CreateDialog(rRequest, PickerDialog::FileSave, nFlags); +} + + +void VistaFilePickerImpl::impl_sta_CreateFolderPicker(const RequestRef& rRequest) +{ + DWORD nFlags = 0; + nFlags |= FOS_PICKFOLDERS; + + impl_sta_CreateDialog(rRequest, PickerDialog::Folder, nFlags); +} + + static const ::sal_Int32 GROUP_VERSION = 1; static const ::sal_Int32 GROUP_TEMPLATE = 2; static const ::sal_Int32 GROUP_IMAGETEMPLATE = 3; @@ -822,6 +865,7 @@ void VistaFilePickerImpl::impl_sta_getSelectedFiles(const RequestRef& rRequest) TFileOpenDialog iOpen = m_iDialogOpen; TFileSaveDialog iSave = m_iDialogSave; + TFolderPickerDialog iPick = m_iFolderPicker; bool bInExecute = m_bInExecute; aLock.clear(); @@ -852,6 +896,15 @@ void VistaFilePickerImpl::impl_sta_getSelectedFiles(const RequestRef& rRequest) else hResult = iSave->GetResult(&iItem); } + else if (iPick.is()) + { + if (bInExecute) + hResult = iPick->GetCurrentSelection(&iItem); + else + { + hResult = iPick->GetResult(&iItem); + } + } if (FAILED(hResult)) return; @@ -898,6 +951,7 @@ void VistaFilePickerImpl::impl_sta_ShowDialogModal(const RequestRef& rRequest) TFileDialog iDialog = impl_getBaseDialogInterface(); TFileOpenDialog iOpen = m_iDialogOpen; TFileSaveDialog iSave = m_iDialogSave; + TFolderPickerDialog iPick = m_iFolderPicker; // it's important to know if we are showing the dialog. // Some dialog interface methods can't be called then or some @@ -977,6 +1031,9 @@ void VistaFilePickerImpl::impl_sta_ShowDialogModal(const RequestRef& rRequest) else if (iSave.is()) hResult = iSave->Show( m_hParentWindow ); // parent window needed + else + if (iPick.is()) + hResult = iPick->Show( m_hParentWindow ); // parent window needed } catch(...) {} @@ -1006,6 +1063,8 @@ TFileDialog VistaFilePickerImpl::impl_getBaseDialogInterface() m_iDialogOpen.query(&iDialog); if (m_iDialogSave.is()) m_iDialogSave.query(&iDialog); + if (m_iFolderPicker.is()) + m_iFolderPicker.query(&iDialog); return iDialog; } @@ -1022,6 +1081,8 @@ TFileDialogCustomize VistaFilePickerImpl::impl_getCustomizeInterface() m_iDialogOpen.query(&iCustom); else if (m_iDialogSave.is()) m_iDialogSave.query(&iCustom); + else if (m_iFolderPicker.is()) + m_iFolderPicker.query(&iCustom); return iCustom; } diff --git a/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx b/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx index 8f9314e990aa..cb7468c9f09b 100644 --- a/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx +++ b/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx @@ -109,6 +109,7 @@ class VistaFilePickerImpl : private ::cppu::BaseMutex E_GET_CURRENT_FILTER, E_CREATE_OPEN_DIALOG, E_CREATE_SAVE_DIALOG, + E_CREATE_FOLDER_PICKER, E_SET_MULTISELECTION_MODE, E_SET_TITLE, E_SET_FILENAME, @@ -182,6 +183,10 @@ class VistaFilePickerImpl : private ::cppu::BaseMutex void impl_sta_CreateSaveDialog(const RequestRef& rRequest); + /// implementation of request E_CREATE_FOLDER_PICKER + void impl_sta_CreateFolderPicker(const RequestRef& rRequest); + + /// implementation of request E_SET_MULTISELECTION_MODE void impl_sta_SetMultiSelectionMode(const RequestRef& rRequest); @@ -272,6 +277,14 @@ class VistaFilePickerImpl : private ::cppu::BaseMutex void impl_SetDefaultExtension( const OUString& currentFilter ); private: + enum class PickerDialog + { + FileOpen, + FileSave, + Folder, + }; + + void impl_sta_CreateDialog(const RequestRef& rRequest, PickerDialog eType, DWORD nOrFlags); /// COM object representing a file open dialog @@ -282,6 +295,10 @@ class VistaFilePickerImpl : private ::cppu::BaseMutex TFileSaveDialog m_iDialogSave; + /// COM object representing a folder picker dialog + TFolderPickerDialog m_iFolderPicker; + + /// knows the return state of the last COM call HRESULT m_hLastResult; diff --git a/fpicker/source/win32/filepicker/vistatypes.h b/fpicker/source/win32/filepicker/vistatypes.h index 727416e9f2a1..4271b0cea482 100644 --- a/fpicker/source/win32/filepicker/vistatypes.h +++ b/fpicker/source/win32/filepicker/vistatypes.h @@ -36,6 +36,7 @@ typedef ComPtr< IFileOpenDialog , IID_IFileOpenDialog , CLSID_FileOpenDialo typedef ComPtr< IFileSaveDialog , IID_IFileSaveDialog , CLSID_FileSaveDialog > TFileSaveDialog; typedef ComPtr< IFileDialogEvents , IID_IFileDialogEvents > TFileDialogEvents; typedef ComPtr< IFileDialogCustomize, IID_IFileDialogCustomize > TFileDialogCustomize; +typedef TFileOpenDialog TFolderPickerDialog; } // namespace vista } // namespace win32 |