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.
Reviewed-on: https://gerrit.libreoffice.org/60144
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
(cherry picked from commit 2129753120d8101f0f484571b6a8cd8eb4d4629c)
Change-Id: I85daae84d4eb36fc827cf20aa277ce6a2f63dd2c
Reviewed-on: https://gerrit.libreoffice.org/63723
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
diff --git a/fpicker/Library_fps.mk b/fpicker/Library_fps.mk
index d6be222..cc08f47 100644
--- a/fpicker/Library_fps.mk
+++ b/fpicker/Library_fps.mk
@@ -67,9 +67,6 @@
fpicker/source/win32/filepicker/VistaFilePicker \
fpicker/source/win32/filepicker/VistaFilePickerEventHandler \
fpicker/source/win32/filepicker/VistaFilePickerImpl \
fpicker/source/win32/folderpicker/FolderPicker \
fpicker/source/win32/folderpicker/MtaFop \
fpicker/source/win32/folderpicker/WinFOPImpl \
fpicker/source/win32/misc/resourceprovider \
fpicker/source/win32/misc/WinImplHelper \
))
diff --git a/fpicker/source/win32/filepicker/FPServiceInfo.hxx b/fpicker/source/win32/filepicker/FPServiceInfo.hxx
index 36aadf4..edc350c 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 2166ba8..d62dda4 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 c0dde13..17b6a56 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 @@
{
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 @@
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 @@
{
}
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 8f36f54..8a138cc 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 @@
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 @@
// 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 @@
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;
bool startupEventNotification(bool bStartupSuspended);
void shutdownEventNotification();
void suspendEventNotification();
void resumeEventNotification();
*/
virtual void SAL_CALL setDescription( const OUString& aDescription ) override;
private:
@@ -234,6 +228,7 @@
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 dfc99a3..598f42a 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 @@
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) )
{
eConversion = SIGDN_URL;
hr = pItem->GetDisplayName ( eConversion, &pStr );
if ( FAILED(hr) )
return OUString();
sURL = o3tl::toU(pStr);
}
else
hr = pItem->GetDisplayName ( SIGDN_FILESYSPATH, &pStr );
if (SUCCEEDED(hr))
{
::osl::FileBase::getFileURLFromSystemPath( o3tl::toU(pStr), sURL );
goto cleanup;
}
hr = pItem->GetDisplayName ( SIGDN_URL, &pStr );
if (SUCCEEDED(hr))
{
sURL = o3tl::toU(pStr);
goto cleanup;
}
hr = pItem->GetDisplayName ( SIGDN_PARENTRELATIVEPARSING, &pStr );
if (SUCCEEDED(hr))
{
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 @@
VistaFilePickerImpl::VistaFilePickerImpl()
: m_iDialogOpen ()
, m_iDialogSave ()
, m_iFolderPicker()
, m_hLastResult ()
, m_lFilters ()
, m_iEventHandler(new VistaFilePickerEventHandler(this))
@@ -219,6 +248,10 @@
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,17 +432,36 @@
}
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);
switch (eType)
{
case PickerDialog::FileOpen:
m_hLastResult = m_iDialogOpen.create();
if (FAILED(m_hLastResult))
return;
m_iDialogOpen.query(&iDialog);
break;
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;
@@ -421,51 +473,11 @@
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));
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);
m_hLastResult = m_iDialogSave.create();
if (FAILED(m_hLastResult))
return;
TFileDialogEvents iHandler = m_iEventHandler;
TFileDialog iDialog;
m_iDialogSave.query(&iDialog);
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));
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 @@
}
}
::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_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 @@
TFileOpenDialog iOpen = m_iDialogOpen;
TFileSaveDialog iSave = m_iDialogSave;
TFolderPickerDialog iPick = m_iFolderPicker;
bool bInExecute = m_bInExecute;
aLock.clear();
@@ -852,6 +896,15 @@
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 @@
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 @@
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 @@
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 @@
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 8f9314e..cb7468c 100644
--- a/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx
+++ b/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx
@@ -109,6 +109,7 @@
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 @@
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 @@
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 @@
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 727416e9..4271b0c 100644
--- a/fpicker/source/win32/filepicker/vistatypes.h
+++ b/fpicker/source/win32/filepicker/vistatypes.h
@@ -36,6 +36,7 @@
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
diff --git a/fpicker/source/win32/folderpicker/FOPServiceInfo.hxx b/fpicker/source/win32/folderpicker/FOPServiceInfo.hxx
deleted file mode 100644
index d08586e..0000000
--- a/fpicker/source/win32/folderpicker/FOPServiceInfo.hxx
+++ /dev/null
@@ -1,35 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#ifndef INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_FOPSERVICEINFO_HXX
#define INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_FOPSERVICEINFO_HXX
// the service name is a description of a set of
// interfaces (is the same as component categories in COM)
// 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/folderpicker/FolderPicker.cxx b/fpicker/source/win32/folderpicker/FolderPicker.cxx
deleted file mode 100644
index 870ec7a..0000000
--- a/fpicker/source/win32/folderpicker/FolderPicker.cxx
+++ /dev/null
@@ -1,134 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include <memory>
#include <osl/diagnose.h>
#include "FolderPicker.hxx"
#include <cppuhelper/supportsservice.hxx>
#include "WinFOPImpl.hxx"
using com::sun::star::uno::Reference;
using com::sun::star::uno::RuntimeException;
using com::sun::star::uno::Sequence;
using com::sun::star::lang::XMultiServiceFactory;
using com::sun::star::lang::XServiceInfo;
using com::sun::star::lang::IllegalArgumentException;
using osl::MutexGuard;
using namespace cppu;
using namespace com::sun::star::ui::dialogs;
#define FOLDERPICKER_IMPL_NAME "com.sun.star.ui.dialogs.Win32FolderPicker"
namespace
{
Sequence< OUString > FolderPicker_getSupportedServiceNames()
{
Sequence< OUString > aRet { "com.sun.star.ui.dialogs.SystemFolderPicker" };
return aRet;
}
}
CFolderPicker::CFolderPicker( const Reference< XMultiServiceFactory >& xServiceMgr ) :
m_xServiceMgr( xServiceMgr )
{
m_pFolderPickerImpl = std::unique_ptr< CWinFolderPickerImpl > ( new CWinFolderPickerImpl( this ) );
}
void SAL_CALL CFolderPicker::setTitle( const OUString& aTitle )
{
OSL_ASSERT( m_pFolderPickerImpl.get( ) );
MutexGuard aGuard( m_aMutex );
m_pFolderPickerImpl->setTitle( aTitle );
}
void SAL_CALL CFolderPicker::setDisplayDirectory( const OUString& aDirectory )
{
OSL_ASSERT( m_pFolderPickerImpl.get( ) );
MutexGuard aGuard( m_aMutex );
m_pFolderPickerImpl->setDisplayDirectory( aDirectory );
}
OUString SAL_CALL CFolderPicker::getDisplayDirectory( )
{
OSL_ASSERT( m_pFolderPickerImpl.get( ) );
MutexGuard aGuard( m_aMutex );
return m_pFolderPickerImpl->getDisplayDirectory( );
}
OUString SAL_CALL CFolderPicker::getDirectory( )
{
OSL_ASSERT( m_pFolderPickerImpl.get( ) );
MutexGuard aGuard( m_aMutex );
return m_pFolderPickerImpl->getDirectory( );
}
void SAL_CALL CFolderPicker::setDescription( const OUString& aDescription )
{
OSL_ASSERT( m_pFolderPickerImpl.get( ) );
MutexGuard aGuard( m_aMutex );
m_pFolderPickerImpl->setDescription( aDescription );
}
sal_Int16 SAL_CALL CFolderPicker::execute( )
{
OSL_ASSERT( m_pFolderPickerImpl.get( ) );
// we should not block in this call else
// in the case of an event the client can'tgetPImplFromHandle( hWnd )
// call another function and we run into a
// deadlock !!!!!
return m_pFolderPickerImpl->execute( );
}
// XServiceInfo
OUString SAL_CALL CFolderPicker::getImplementationName( )
{
return OUString( FOLDERPICKER_IMPL_NAME );
}
sal_Bool SAL_CALL CFolderPicker::supportsService( const OUString& ServiceName )
{
return cppu::supportsService(this, ServiceName);
}
Sequence< OUString > SAL_CALL CFolderPicker::getSupportedServiceNames( )
{
return FolderPicker_getSupportedServiceNames();
}
// XCancellable
void SAL_CALL CFolderPicker::cancel( )
{
OSL_ASSERT( m_pFolderPickerImpl.get( ) );
MutexGuard aGuard( m_aMutex );
m_pFolderPickerImpl->cancel( );
}
// overwrite base class method, which is called
// by base class dispose function
void CFolderPicker::disposing()
{
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/FolderPicker.hxx b/fpicker/source/win32/folderpicker/FolderPicker.hxx
deleted file mode 100644
index 346a6bf..0000000
--- a/fpicker/source/win32/folderpicker/FolderPicker.hxx
+++ /dev/null
@@ -1,104 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#ifndef INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_FOLDERPICKER_HXX
#define INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_FOLDERPICKER_HXX
#include <cppuhelper/implbase.hxx>
#include <osl/mutex.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
#include <memory>
#include "WinFOPImpl.hxx"
// class declaration
class CFolderPicker :
public cppu::WeakImplHelper<
css::ui::dialogs::XFolderPicker2,
css::lang::XServiceInfo >
{
public:
// ctor/dtor
explicit CFolderPicker( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceMgr );
// XExecutableDialog
virtual void SAL_CALL setTitle( const OUString& aTitle ) override;
virtual sal_Int16 SAL_CALL execute( ) override;
// XFolderPicker functions
virtual void SAL_CALL setDisplayDirectory( const OUString& aDirectory ) override;
virtual OUString SAL_CALL getDisplayDirectory( ) override;
virtual OUString SAL_CALL getDirectory( ) override;
virtual void SAL_CALL setDescription( const OUString& aDescription ) override;
// XServiceInfo
virtual OUString SAL_CALL getImplementationName( ) override;
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
// XCancellable
virtual void SAL_CALL cancel( ) override;
// overwrite base class method, which is called
// by base class dispose function
virtual void disposing();
private:
css::uno::Reference< css::lang::XMultiServiceFactory > m_xServiceMgr;
std::unique_ptr< CWinFolderPickerImpl > m_pFolderPickerImpl;
osl::Mutex m_aMutex;
// prevent copy and assignment
private:
CFolderPicker( const CFolderPicker& );
CFolderPicker& operator=( const CFolderPicker& );
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/FopEvtDisp.hxx b/fpicker/source/win32/folderpicker/FopEvtDisp.hxx
deleted file mode 100644
index d070e82..0000000
--- a/fpicker/source/win32/folderpicker/FopEvtDisp.hxx
+++ /dev/null
@@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#ifndef INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_FOPEVTDISP_HXX
#define INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_FOPEVTDISP_HXX
#include <com/sun/star/lang/EventObject.hpp>
class CFOPEventDispatcher
{
public:
// dispatches a FilePickerEvent to wherever
virtual void helpRequested( css::lang::EventObject aEvent ) const = 0;
protected:
~CFOPEventDispatcher() {}
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/MtaFop.cxx b/fpicker/source/win32/folderpicker/MtaFop.cxx
deleted file mode 100644
index ba951039..0000000
--- a/fpicker/source/win32/folderpicker/MtaFop.cxx
+++ /dev/null
@@ -1,721 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include <osl/diagnose.h>
#include <osl/thread.h>
#include <o3tl/char16_t2wchar_t.hxx>
#include <vcl/svapp.hxx>
#include "MtaFop.hxx"
#include <wchar.h>
#include <process.h>
#include "../misc/resourceprovider.hxx"
#include <systools/win32/comtools.hxx>
const sal_uInt32 MSG_BROWSEFORFOLDER = WM_USER + 1;
const sal_uInt32 MSG_SHUTDOWN = WM_USER + 2;
const sal_uInt32 MAX_WAITTIME = 2000; // msec
const bool MANUAL_RESET = true;
const bool AUTO_RESET = false;
const bool INIT_NONSIGNALED = false;
#define FOLDERPICKER_TITLE 500
#define FOLDER_PICKER_DEF_DESCRIPTION 501
namespace
{
const wchar_t* const FOLDERPICKER_SRV_DLL_NAME = L"fps.dll";
const wchar_t g_szWndClsName[] = L"FopStaReqWnd###";
const wchar_t* const CURRENT_INSTANCE = L"CurrInst";
struct RequestContext
{
HANDLE hEvent;
bool bRet;
};
inline bool InitializeRequestContext( RequestContext* aRequestContext )
{
OSL_ASSERT( aRequestContext );
aRequestContext->hEvent = CreateEventW(
nullptr, AUTO_RESET, INIT_NONSIGNALED, nullptr );
aRequestContext->bRet = false;
return ( nullptr != aRequestContext->hEvent );
}
inline void DeinitializeRequestContext( RequestContext* aRequestContext )
{
OSL_ASSERT( aRequestContext && aRequestContext->hEvent );
CloseHandle( aRequestContext->hEvent );
}
}
// static member initialization
ATOM CMtaFolderPicker::s_ClassAtom = 0;
osl::Mutex CMtaFolderPicker::s_Mutex;
sal_Int32 CMtaFolderPicker::s_StaRequestWndRegisterCount = 0;
// ctor
CMtaFolderPicker::CMtaFolderPicker( sal_uInt32 Flags ) :
m_hStaThread( nullptr ),
m_uStaThreadId( 0 ),
m_hEvtThrdReady( nullptr ),
m_hwndStaRequestWnd( nullptr )
{
m_hInstance = GetModuleHandleW( FOLDERPICKER_SRV_DLL_NAME );
OSL_ENSURE( m_hInstance, "The name of the FolderPicker service dll must have changed" );
ZeroMemory( &m_bi, sizeof( m_bi ) );
// !!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!
// Remember: This HACK prevents you from stepping
// through your code in the debugger because if you
// set a break point in the ctor here the debugger
// may become the owner of the FolderBrowse dialog
// and so it seems that the Visual Studio and the
// office are hanging
m_bi.hwndOwner = GetForegroundWindow( );
/*
Flag Available
--------------------------------
BIF_EDITBOX Version 4.71
BIF_NEWDIALOGSTYLE Version 5.0
BIF_SHAREABLE Version 5.0
BIF_VALIDATE Version 4.71
Version 4.71 - Internet Explorer 4.0
Version 5.0 - Internet Explorer 5.0
Windows 2000
*/
m_bi.ulFlags = Flags;
m_bi.lpfn = CMtaFolderPicker::FolderPickerCallback;
m_bi.lParam = reinterpret_cast< LPARAM >( this );
m_dialogTitle = CResourceProvider::getResString(FOLDERPICKER_TITLE);
m_Description = CResourceProvider::getResString(FOLDER_PICKER_DEF_DESCRIPTION);
// signals that the thread was successfully set up
m_hEvtThrdReady = CreateEventW(
nullptr,
MANUAL_RESET,
INIT_NONSIGNALED,
nullptr );
if ( m_hEvtThrdReady )
{
// setup the sta thread
m_hStaThread = reinterpret_cast<HANDLE>(_beginthreadex(
nullptr,
0,
CMtaFolderPicker::StaThreadProc,
this,
0,
&m_uStaThreadId ));
OSL_ASSERT( m_hStaThread );
}
OSL_ASSERT( m_hEvtThrdReady );
}
// dtor
CMtaFolderPicker::~CMtaFolderPicker( )
{
// only if the is a valid event handle
// there may also be a thread a hidden
// target request window and so on
// see ctor
if ( m_hEvtThrdReady )
{
// block calling threads because we
// are about to shutdown
ResetEvent( m_hEvtThrdReady );
// force the destruction of the sta thread request window
// and the end of the thread
// remember: DestroyWindow may only be called from within
// the thread that created the window
if ( IsWindow( m_hwndStaRequestWnd ) )
{
SendMessageW( m_hwndStaRequestWnd, MSG_SHUTDOWN, 0, 0 );
// we place unregister class here because
// if we have a valid window we must have
// successfully registered a window class
// if the creation of the window itself
// failed after registering the window
// class we have unregistered it immediately
// in createStaRequestWindow below
UnregisterStaRequestWindowClass( );
}
if ( m_hStaThread )
{
// wait for thread shutdown
sal_uInt32 dwResult = WaitForSingleObject( m_hStaThread, MAX_WAITTIME );
OSL_ENSURE( dwResult == WAIT_OBJECT_0, "sta thread could not terminate" );
// terminate the thread if it
// doesn't shutdown itself
if ( WAIT_OBJECT_0 != dwResult )
TerminateThread(
m_hStaThread, sal::static_int_cast< DWORD >(-1) );
CloseHandle( m_hStaThread );
}
CloseHandle( m_hEvtThrdReady );
}
}
bool CMtaFolderPicker::browseForFolder( )
{
bool bRet = false;
OSL_ASSERT( m_hEvtThrdReady );
if ( WaitForSingleObject( m_hEvtThrdReady, MAX_WAITTIME ) != WAIT_OBJECT_0 )
{
OSL_FAIL( "sta thread not ready" );
return false;
}
RequestContext aReqCtx;
if ( !InitializeRequestContext( &aReqCtx ) )
{
OSL_ASSERT( false );
return false;
}
// marshall request into the sta thread
BOOL const ret = PostMessageW(
m_hwndStaRequestWnd,
MSG_BROWSEFORFOLDER,
0,
reinterpret_cast< LPARAM >( &aReqCtx ) );
SAL_WARN_IF(0 == ret, "fpicker", "ERROR: PostMessage() failed!");
// waiting for the event to be signaled or
// window messages so that we don't block
// our parent window
bool bContinue = true;
while ( bContinue )
{
DWORD dwResult = MsgWaitForMultipleObjects(
1, &aReqCtx.hEvent, false, INFINITE, QS_ALLEVENTS );
switch ( dwResult )
{
// the request context event is signaled
case WAIT_OBJECT_0:
bContinue = false;
break;
// a window message has arrived
case WAIT_OBJECT_0 + 1:
Application::Reschedule( true );
break;
// should not happen
default:
OSL_ASSERT( false );
}
}
/*sal_Bool*/ bRet = aReqCtx.bRet;
DeinitializeRequestContext( &aReqCtx );
return bRet;
}
void CMtaFolderPicker::setDisplayDirectory( const OUString& aDirectory )
{
m_displayDir = aDirectory;
}
OUString CMtaFolderPicker::getDisplayDirectory( )
{
return m_displayDir;
}
OUString CMtaFolderPicker::getDirectory( )
{
return m_SelectedDir;
}
void CMtaFolderPicker::setDescription( const OUString& aDescription )
{
m_Description = aDescription;
}
void CMtaFolderPicker::setTitle( const OUString& aTitle )
{
m_dialogTitle = aTitle;
}
OUString CMtaFolderPicker::getTitle( )
{
return m_dialogTitle;
}
// XCancellable
void CMtaFolderPicker::cancel( )
{
if ( IsWindow( m_hwnd ) )
{
// simulate a mouse click to the
// cancel button
BOOL const ret = PostMessageW(
m_hwnd,
WM_COMMAND,
MAKEWPARAM( IDCANCEL, BN_CLICKED ),
reinterpret_cast<LPARAM>(GetDlgItem( m_hwnd, IDCANCEL )) );
SAL_WARN_IF(0 == ret, "fpicker", "ERROR: PostMessage() failed!");
}
}
bool CMtaFolderPicker::onBrowseForFolder( )
{
bool bRet;
LPITEMIDLIST lpiid;
// pre SHBrowseFroFolder
m_bi.pidlRoot = nullptr;
m_bi.pszDisplayName = o3tl::toW(m_pathBuff);
if ( m_Description.getLength( ) )
m_bi.lpszTitle = o3tl::toW(m_Description.getStr( ));
lpiid = SHBrowseForFolderW( &m_bi );
bRet = ( nullptr != lpiid );
// post SHBrowseForFolder
m_SelectedDir = getPathFromItemIdList( lpiid );
releaseItemIdList( lpiid );
return bRet;
}
void CMtaFolderPicker::releaseItemIdList( LPITEMIDLIST lpItemIdList )
{
sal::systools::COMReference<IMalloc> pIMalloc;
SHGetMalloc(&pIMalloc);
if (pIMalloc.is())
{
pIMalloc->Free(lpItemIdList);
lpItemIdList = nullptr;
}
}
LPITEMIDLIST CMtaFolderPicker::getItemIdListFromPath( const OUString& aDirectory )
{
// parameter checking
if ( !aDirectory.getLength( ) )
return nullptr;
LPITEMIDLIST lpItemIdList(nullptr);
sal::systools::COMReference<IShellFolder> pIShellFolder;
SHGetDesktopFolder(&pIShellFolder);
if (pIShellFolder.is())
{
pIShellFolder->ParseDisplayName(
nullptr,
nullptr,
const_cast<LPWSTR>(o3tl::toW( aDirectory.getStr( ) )),
nullptr,
&lpItemIdList,
nullptr );
}
return lpItemIdList;
}
OUString CMtaFolderPicker::getPathFromItemIdList( LPCITEMIDLIST lpItemIdList )
{
OUString path;
if ( lpItemIdList )
{
bool bRet = SHGetPathFromIDListW( lpItemIdList, o3tl::toW(m_pathBuff) );
if ( bRet )
path = m_pathBuff;
}
return path;
}
void CMtaFolderPicker::enableOk( bool bEnable )
{
OSL_ASSERT( IsWindow( m_hwnd ) );
SendMessageW(
m_hwnd,
BFFM_ENABLEOK,
static_cast< WPARAM >( 0 ),
static_cast< LPARAM >( bEnable ) );
}
void CMtaFolderPicker::setSelection( const OUString& aDirectory )
{
OSL_ASSERT( IsWindow( m_hwnd ) );
SendMessageW(
m_hwnd,
BFFM_SETSELECTIONW,
static_cast< WPARAM >( true ),
reinterpret_cast< LPARAM >( aDirectory.getStr( ) ) );
}
void CMtaFolderPicker::setStatusText( const OUString& aStatusText )
{
OSL_ASSERT( IsWindow( m_hwnd ) );
SendMessageW(
m_hwnd,
BFFM_SETSTATUSTEXTW,
static_cast< WPARAM >( 0 ),
reinterpret_cast< LPARAM >( aStatusText.getStr( ) ) );
}
void CMtaFolderPicker::onInitialized( )
{
LPITEMIDLIST lpiidDisplayDir = getItemIdListFromPath( m_displayDir );
if ( lpiidDisplayDir )
{
SendMessageW(
m_hwnd,
BFFM_SETSELECTION,
WPARAM(false),
reinterpret_cast<LPARAM>(lpiidDisplayDir) );
releaseItemIdList( lpiidDisplayDir );
}
}
sal_uInt32 CMtaFolderPicker::onValidateFailed()
{
// to be overwritten by subclasses
return 1;
}
int CALLBACK CMtaFolderPicker::FolderPickerCallback( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
{
CMtaFolderPicker* pImpl = reinterpret_cast< CMtaFolderPicker* >( lpData );
OSL_ASSERT( pImpl );
int nRC = 0;
switch( uMsg )
{
case BFFM_INITIALIZED:
pImpl->m_hwnd = hwnd;
pImpl->onInitialized( );
SetWindowTextW( hwnd, o3tl::toW(pImpl->m_dialogTitle.getStr()) );
break;
case BFFM_SELCHANGED:
pImpl->m_hwnd = hwnd;
pImpl->onSelChanged(
pImpl->getPathFromItemIdList(
reinterpret_cast< LPITEMIDLIST >( lParam ) ) );
break;
case BFFM_VALIDATEFAILEDW:
nRC = CMtaFolderPicker::onValidateFailed();
break;
default:
OSL_ASSERT( false );
}
return nRC;
}
// the window proc
LRESULT CALLBACK CMtaFolderPicker::StaWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
LRESULT lResult = 0;
CMtaFolderPicker* pImpl = nullptr;
/*
we connect to the belonging class instance of this
window using SetProp, GetProp etc.
this may fail if somehow the class instance destroyed
before the window
*/
switch( uMsg )
{
case WM_CREATE:
{
LPCREATESTRUCTW lpcs =
reinterpret_cast< LPCREATESTRUCTW >( lParam );
OSL_ASSERT( lpcs->lpCreateParams );
// connect the instance handle to the window
SetPropW( hWnd, CURRENT_INSTANCE, lpcs->lpCreateParams );
}
break;
case WM_NCDESTROY:
// RemoveProp returns the saved value on success
pImpl = static_cast< CMtaFolderPicker* >(
RemovePropW( hWnd, CURRENT_INSTANCE ) );
OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) );
break;
case MSG_BROWSEFORFOLDER:
{
RequestContext* aReqCtx = reinterpret_cast< RequestContext* >( lParam );
OSL_ASSERT( aReqCtx );
pImpl = static_cast< CMtaFolderPicker* >(
GetPropW( hWnd, CURRENT_INSTANCE ) );
OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) );
aReqCtx->bRet = pImpl->onBrowseForFolder( );
SetEvent( aReqCtx->hEvent );
}
break;
case MSG_SHUTDOWN:
pImpl = static_cast< CMtaFolderPicker* >(
GetPropW( hWnd, CURRENT_INSTANCE ) );
OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) );
DestroyWindow( pImpl->m_hwndStaRequestWnd );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default:
lResult = DefWindowProcW( hWnd, uMsg, wParam, lParam );
break;
}
return lResult;
}
bool CMtaFolderPicker::createStaRequestWindow( )
{
bool bIsWnd = false;
if ( RegisterStaRequestWindowClass( ) )
{
m_hwndStaRequestWnd = CreateWindowW(
g_szWndClsName, nullptr,
0, 0, 0, 0, 0,
nullptr, nullptr, m_hInstance,
this // provide the instance of the class
);
bIsWnd = IsWindow( m_hwndStaRequestWnd );
// we do immediately unregister the window class
// if the creation of the window fails because we
// don't want to spoil the register class counter
if ( !bIsWnd )
UnregisterStaRequestWindowClass( );
OSL_ENSURE( bIsWnd, "sta request window creation failed" );
}
return bIsWnd;
}
unsigned int CMtaFolderPicker::run( )
{
OSL_ASSERT( m_hEvtThrdReady );
// setup an sta environment
HRESULT hr = CoInitialize( nullptr );
// if we can't setup an sta environment
// we stop here and return
if ( FAILED( hr ) )
{
OSL_FAIL( "CoInitialize failed" );
return sal::static_int_cast< unsigned int >(-1);
}
unsigned int nRet;
if ( createStaRequestWindow( ) )
{
SetEvent( m_hEvtThrdReady );
// pumping messages
MSG msg;
while( GetMessageW( &msg, nullptr, 0, 0 ) )
DispatchMessageW( &msg );
nRet = 0;
}
else
{
OSL_FAIL( "failed to create sta thread" );
nRet = sal::static_int_cast< unsigned int >(-1);
}
// shutdown sta environment
CoUninitialize( );
return nRet;
}
unsigned int WINAPI CMtaFolderPicker::StaThreadProc( LPVOID pParam )
{
osl_setThreadName("fpicker CMtaFolderPicker::run()");
CMtaFolderPicker* pInst =
static_cast<CMtaFolderPicker*>( pParam );
OSL_ASSERT( pInst );
HRESULT hr = OleInitialize( nullptr );
unsigned int result = pInst->run( );
if ( SUCCEEDED( hr ) )
OleUninitialize();
return result;
}
ATOM CMtaFolderPicker::RegisterStaRequestWindowClass( )
{
osl::MutexGuard aGuard( s_Mutex );
if ( 0 == s_ClassAtom )
{
WNDCLASSEXW wcex;
ZeroMemory( &wcex, sizeof( wcex ) );
wcex.cbSize = sizeof(wcex);
wcex.style = 0;
wcex.lpfnWndProc = CMtaFolderPicker::StaWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = m_hInstance;
wcex.hIcon = nullptr;
wcex.hCursor = nullptr;
wcex.hbrBackground = nullptr;
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = g_szWndClsName;
wcex.hIconSm = nullptr;
s_ClassAtom = RegisterClassExW( &wcex );
OSL_ASSERT( s_ClassAtom );
}
// increment the register class counter
// so that we keep track of the number
// of class registrations
if ( 0 != s_ClassAtom )
s_StaRequestWndRegisterCount++;
return s_ClassAtom;
}
void CMtaFolderPicker::UnregisterStaRequestWindowClass( )
{
osl::MutexGuard aGuard( s_Mutex );
OSL_ASSERT( 0 != s_ClassAtom );
// update the register class counter
// and unregister the window class if
// counter drops to zero
if ( 0 != s_ClassAtom )
{
s_StaRequestWndRegisterCount--;
OSL_ASSERT( s_StaRequestWndRegisterCount >= 0 );
}
if ( 0 == s_StaRequestWndRegisterCount )
{
UnregisterClass( MAKEINTATOM(s_ClassAtom), m_hInstance );
s_ClassAtom = 0;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/MtaFop.hxx b/fpicker/source/win32/folderpicker/MtaFop.hxx
deleted file mode 100644
index 5d7042e..0000000
--- a/fpicker/source/win32/folderpicker/MtaFop.hxx
+++ /dev/null
@@ -1,137 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#ifndef INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_MTAFOP_HXX
#define INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_MTAFOP_HXX
#include <sal/config.h>
#include <sal/log.hxx>
#include <sal/types.h>
#include <rtl/ustring.hxx>
#include <osl/diagnose.h>
#include <osl/mutex.hxx>
#include <utility>
#include <objidl.h>
#include <shlobj.h>
#include "../misc/WinImplHelper.hxx"
// the Mta-Ole clipboard class is for internal use only!
// only one instance of this class should be created, the
// user has to ensure this!
// the class is not thread-safe because it will be used
// only from within the clipboard service and the methods
// of the clipboard service are already synchronized
class CMtaFolderPicker
{
public:
explicit CMtaFolderPicker( sal_uInt32 Flags );
virtual ~CMtaFolderPicker( );
// shell functions
bool browseForFolder( );
virtual void setDisplayDirectory( const OUString& aDirectory );
virtual OUString getDisplayDirectory( );
virtual OUString getDirectory( );
virtual void setDescription( const OUString& aDescription );
virtual void setTitle( const OUString& aTitle );
OUString getTitle( );
// XCancellable
virtual void cancel( );
protected:
void enableOk( bool bEnable );
void setSelection( const OUString& aDirectory );
void setStatusText( const OUString& aStatusText );
virtual void onInitialized( );
virtual void onSelChanged( const OUString& aNewPath ) = 0;
private:
static sal_uInt32 onValidateFailed();
// helper functions
static LPITEMIDLIST getItemIdListFromPath( const OUString& aDirectory );
OUString getPathFromItemIdList( LPCITEMIDLIST lpItemIdList );
static void releaseItemIdList( LPITEMIDLIST lpItemIdList );
unsigned int run( );
// create a hidden windows which serves as an request
// target; so we guarantee synchronization
bool createStaRequestWindow( );
// message handler functions; remember these functions are called
// from a different thread context!
bool onBrowseForFolder( );
static LRESULT CALLBACK StaWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
static unsigned int WINAPI StaThreadProc( LPVOID pParam );
static int CALLBACK FolderPickerCallback( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData );
protected:
HWND m_hwnd;
private:
ATOM RegisterStaRequestWindowClass( );
void UnregisterStaRequestWindowClass( );
private:
HANDLE m_hStaThread;
unsigned m_uStaThreadId;
HANDLE m_hEvtThrdReady;
HWND m_hwndStaRequestWnd;
OUString m_dialogTitle;
OUString m_Description;
OUString m_displayDir;
OUString m_SelectedDir;
BROWSEINFOW m_bi;
sal_Unicode m_pathBuff[32000]; // max path length under Win2000
HINSTANCE m_hInstance;
// the request window class has to be registered only
// once per process, so multiple instance of this class
// share the registered window class
static ATOM s_ClassAtom;
static osl::Mutex s_Mutex;
static sal_Int32 s_StaRequestWndRegisterCount;
// prevent copy and assignment
private:
CMtaFolderPicker( const CMtaFolderPicker& );
CMtaFolderPicker& operator=( const CMtaFolderPicker& );
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/WinFOPImpl.cxx b/fpicker/source/win32/folderpicker/WinFOPImpl.cxx
deleted file mode 100644
index c649302..0000000
--- a/fpicker/source/win32/folderpicker/WinFOPImpl.cxx
+++ /dev/null
@@ -1,117 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include "WinFOPImpl.hxx"
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
#include "FopEvtDisp.hxx"
#include <osl/file.hxx>
#include "FolderPicker.hxx"
using com::sun::star::uno::RuntimeException;
using com::sun::star::lang::IllegalArgumentException;
using namespace com::sun::star::ui::dialogs;
using osl::FileBase;
const OUString BACKSLASH( "\\" );
CWinFolderPickerImpl::CWinFolderPickerImpl( CFolderPicker* aFolderPicker ) :
CMtaFolderPicker( BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_EDITBOX | BIF_VALIDATE ),
m_pFolderPicker( aFolderPicker ),
m_nLastDlgResult( css::ui::dialogs::ExecutableDialogResults::CANCEL )
{
}
// get directory in URL format, convert it to system format and set the
// member variable
// If the given URL for the directory is invalid the function throws an
// IllegalArgumentException
// If the specified path is well formed but invalid for the underlying
// OS the FolderPicker starts in the root of the file system hierarchy
void CWinFolderPickerImpl::setDisplayDirectory( const OUString& aDirectory )
{
OUString sysDir;
if( aDirectory.getLength( ) )
{
// assuming that this function succeeds after successful execution
// of getAbsolutePath
::osl::FileBase::RC rc =
::osl::FileBase::getSystemPathFromFileURL( aDirectory, sysDir );
if ( ::osl::FileBase::E_None != rc )
throw IllegalArgumentException(
"directory is not a valid file url",
static_cast< cppu::OWeakObject * >( m_pFolderPicker ),
1 );
// we ensure that there is a trailing '/' at the end of
// he given file url, because the windows functions only
// works correctly when providing "c:\" or an environment
// variable like "=c:=c:\.." etc. is set, else the
// FolderPicker would stand in the root of the shell
// hierarchy which is the desktop folder
if ( sysDir.lastIndexOf( BACKSLASH ) != (sysDir.getLength( ) - 1) )
sysDir += BACKSLASH;
}
// call base class method
CMtaFolderPicker::setDisplayDirectory( sysDir );
}
// we return the directory in URL format
OUString CWinFolderPickerImpl::getDisplayDirectory( )
{
// call base class method to get the directory in system format
OUString displayDirectory = CMtaFolderPicker::getDisplayDirectory( );
OUString displayDirectoryURL;
if ( displayDirectory.getLength( ) )
::osl::FileBase::getFileURLFromSystemPath( displayDirectory, displayDirectoryURL );
return displayDirectoryURL;
}
OUString CWinFolderPickerImpl::getDirectory( )
{
OUString sysDir = CMtaFolderPicker::getDirectory( );
OUString dirURL;
if ( sysDir.getLength( ) )
::osl::FileBase::getFileURLFromSystemPath( sysDir, dirURL );
return dirURL;
}
sal_Int16 CWinFolderPickerImpl::execute( )
{
return m_nLastDlgResult = CMtaFolderPicker::browseForFolder( ) ?
css::ui::dialogs::ExecutableDialogResults::OK :
css::ui::dialogs::ExecutableDialogResults::CANCEL;
}
void CWinFolderPickerImpl::onSelChanged( const OUString& aNewPath )
{
setStatusText( aNewPath );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/WinFOPImpl.hxx b/fpicker/source/win32/folderpicker/WinFOPImpl.hxx
deleted file mode 100644
index 98f52da..0000000
--- a/fpicker/source/win32/folderpicker/WinFOPImpl.hxx
+++ /dev/null
@@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#ifndef INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_WINFOPIMPL_HXX
#define INCLUDED_FPICKER_SOURCE_WIN32_FOLDERPICKER_WINFOPIMPL_HXX
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include "MtaFop.hxx"
// forward
class CFolderPicker;
class CWinFolderPickerImpl : public CMtaFolderPicker
{
public:
explicit CWinFolderPickerImpl( CFolderPicker* aFolderPicker );
// XExecutableDialog
/// @throws css::uno::RuntimeException
virtual sal_Int16 execute( );
// XFolderPicker
virtual void setDisplayDirectory( const OUString& aDirectory ) override;
virtual OUString getDisplayDirectory( ) override;
virtual OUString getDirectory( ) override;
protected:
virtual void onSelChanged( const OUString& aNewPath ) override;
private:
CFolderPicker* m_pFolderPicker;
sal_Int16 m_nLastDlgResult;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/workbench/Test_fops.cxx b/fpicker/source/win32/folderpicker/workbench/Test_fops.cxx
deleted file mode 100644
index 3c6e29d..0000000
--- a/fpicker/source/win32/folderpicker/workbench/Test_fops.cxx
+++ /dev/null
@@ -1,147 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <osl/file.hxx>
#include <cppuhelper/servicefactory.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <osl/diagnose.h>
#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
#include <stdio.h>
#include "..\FOPServiceInfo.hxx"
#define _WIN32_DCOM
#if !defined WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
// namespaces
using namespace ::cppu ;
using namespace ::com::sun::star::uno ;
using namespace ::com::sun::star::lang ;
using namespace ::com::sun::star::ui::dialogs;
using namespace std ;
#define RDB_SYSPATH "D:\\Projects\\gsl\\sysui\\wntmsci7\\bin\\applicat.rdb"
// global variables
Reference< XMultiServiceFactory > g_xFactory;
// main
int SAL_CALL main(int /*nArgc*/, char* /*Argv[]*/, char* /*Env[]*/ )
{
CoInitializeEx( NULL, COINIT_MULTITHREADED );
printf("Starting test of FolderPicker Service\n");
//CreateDeepDirectory( );
// get the global service-manager
// Get global factory for uno services.
Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( RDB_SYSPATH ) );
// Print a message if an error occurred.
if ( g_xFactory.is() == sal_False )
{
OSL_FAIL("Can't create RegistryServiceFactory");
return(-1);
}
printf("Creating RegistryServiceFactory successful\n");
// try to get an Interface to a XFilePicker Service
Reference< XFolderPicker2 > xFolderPicker( g_xFactory->createInstance( FOLDER_PICKER_SERVICE_NAME ), UNO_QUERY );
if ( xFolderPicker.is() == sal_False )
{
OSL_FAIL( "Error creating FolderPicker Service" );
return(-1);
}
try
{
xFolderPicker->setDisplayDirectory( L"file:///C|" );
xFolderPicker->setTitle( L"FolderBrowse Dialog" );
xFolderPicker->execute( );
OUString rootDir = xFolderPicker->getDisplayDirectory( );
OUString selectedDir = xFolderPicker->getDirectory( );
xFolderPicker->setDisplayDirectory( selectedDir );
xFolderPicker->execute( );
rootDir = xFolderPicker->getDisplayDirectory( );
selectedDir = xFolderPicker->getDirectory( );
}
catch( css::uno::Exception& )
{
MessageBox( NULL, "Exception caught!", "Error", MB_OK );
}
// shutdown
// Cast factory to XComponent
Reference< XComponent > xComponent( g_xFactory, UNO_QUERY );
// Print a message if an error occurred.
if ( xComponent.is() == sal_False )
{
OSL_FAIL("Error shuting down");
}
// Dispose and clear factory
xComponent->dispose();
g_xFactory.clear();
printf("Test successful\n");
CoUninitialize( );
return 0;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/win32/folderpicker/workbench/makefile.mk b/fpicker/source/win32/folderpicker/workbench/makefile.mk
deleted file mode 100644
index e3948ee..0000000
--- a/fpicker/source/win32/folderpicker/workbench/makefile.mk
+++ /dev/null
@@ -1,54 +0,0 @@
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This file incorporates work covered by the following license notice:
#
# 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 .
#
PRJ=..$/..$/..$/..
PRJNAME= sysui
TARGET= testfops
LIBTARGET= NO
TARGETTYPE= CUI
# --- Settings -----------------------------------------------------
.INCLUDE : settings.mk
.IF "$(COM)" == "MSC"
CFLAGS+=-GR -EHa
.ENDIF
# --- Files --------------------------------------------------------
OBJFILES= $(OBJ)$/test_fops.obj
APP1TARGET= test_fops
APP1OBJS= $(OBJ)$/test_fops.obj
APP1STDLIBS+= $(CPPULIB) \
$(CPPUHELPERLIB) \
$(SALLIB) \
$(USER32LIB)\
$(OLE32LIB)
APP1DEF= $(MISC)$/$(APP1TARGET).def
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk