summaryrefslogtreecommitdiff
path: root/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2018-09-07 13:00:38 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2018-09-08 23:07:06 +0200
commit2129753120d8101f0f484571b6a8cd8eb4d4629c (patch)
treee06a410cf94d9815f6bf0710172bab7b6a235331 /fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx
parent025abb05385a1dc6219d48390cd4b783988cb409 (diff)
tdf#119730 WIN switch to IFileDialog FOS_PICKFOLDERS
Citing SHBrowseForFolderW remarks: "For Windows Vista or later, it is recommended that you use IFileDialog with the FOS_PICKFOLDERS option rather than the SHBrowseForFolder function." Since the minimum required Windows version is already 7 and we already just provide the Vista file picker, this gets rid of the Windows XP compatible folder picker code. Change-Id: I85daae84d4eb36fc827cf20aa277ce6a2f63dd2c Reviewed-on: https://gerrit.libreoffice.org/60144 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx')
-rw-r--r--fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx177
1 files changed, 119 insertions, 58 deletions
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;
}