give folderpicker an optional parent
so, like a file picker, it can make its parent modal while its
operating. Otherwise its possible to interact with the parent dialog in
undesirable ways, e.g. file, export as, export as epub, the folder
picker of 'media directory'
Change-Id: Ib61f8e630e176b6d81e80798fd0d282d16e8c086
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117582
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx
index 482b214..b9750c1 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -785,7 +785,7 @@ ErrCode FileDialogHelper_Impl::getGraphic( Graphic& rGraphic ) const
return nRet;
}
static bool lcl_isSystemFilePicker( const uno::Reference< XFilePicker3 >& _rxFP )
static bool lcl_isSystemFilePicker( const uno::Reference< XExecutableDialog >& _rxFP )
{
try
{
@@ -1132,9 +1132,34 @@ FileDialogHelper_Impl::FileDialogHelper_Impl(
mxFileDlg->addFilePickerListener( this );
}
css::uno::Reference<css::ui::dialogs::XFolderPicker2> createFolderPicker(const css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Window* /*pPreferredParent*/)
css::uno::Reference<css::ui::dialogs::XFolderPicker2> createFolderPicker(const css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Window* pPreferredParent)
{
return css::ui::dialogs::FolderPicker::create(rContext);
auto xRet = css::ui::dialogs::FolderPicker::create(rContext);
// see FileDialogHelper_Impl::FileDialogHelper_Impl (above) for args to FilePicker
// reuse the same arguments for FolderPicker
if (pPreferredParent && lcl_isSystemFilePicker(xRet))
{
uno::Reference< XInitialization > xInit(xRet, UNO_QUERY);
if (xInit.is())
{
Sequence<Any> aInitArguments(2);
aInitArguments[0] <<= sal_Int32(0);
aInitArguments[1] <<= pPreferredParent->GetXWindow();
try
{
xInit->initialize(aInitArguments);
}
catch (const Exception&)
{
OSL_FAIL( "createFolderPicker: could not initialize the picker!" );
}
}
}
return xRet;
}
FileDialogHelper_Impl::~FileDialogHelper_Impl()
diff --git a/vcl/unx/gtk3/fpicker/SalGtkFilePicker.cxx b/vcl/unx/gtk3/fpicker/SalGtkFilePicker.cxx
index d2d5c6e..cb73a86 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkFilePicker.cxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkFilePicker.cxx
@@ -83,7 +83,6 @@ void SalGtkFilePicker::InitialMapping()
SalGtkFilePicker::SalGtkFilePicker( const uno::Reference< uno::XComponentContext >& xContext ) :
SalGtkPicker( xContext ),
SalGtkFilePicker_Base( m_rbHelperMtx ),
m_pParentWidget ( nullptr ),
m_pVBox ( nullptr ),
mnHID_FolderChange( 0 ),
mnHID_SelectionChange( 0 ),
@@ -1589,6 +1588,38 @@ sal_Bool SAL_CALL SalGtkFilePicker::getShowState()
return mbPreviewState;
}
GtkWidget* SalGtkPicker::GetParentWidget(const uno::Sequence<uno::Any>& rArguments)
{
GtkWidget* pParentWidget = nullptr;
css::uno::Reference<css::awt::XWindow> xParentWindow;
if (rArguments.getLength() > 1)
{
rArguments[1] >>= xParentWindow;
}
if (xParentWindow.is())
{
if (SalGtkXWindow* pGtkXWindow = dynamic_cast<SalGtkXWindow*>(xParentWindow.get()))
pParentWidget = pGtkXWindow->getGtkWidget();
else
{
css::uno::Reference<css::awt::XSystemDependentWindowPeer> xSysDepWin(xParentWindow, css::uno::UNO_QUERY);
if (xSysDepWin.is())
{
css::uno::Sequence<sal_Int8> aProcessIdent(16);
rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
uno::Any aAny = xSysDepWin->getWindowHandle(aProcessIdent, css::lang::SystemDependent::SYSTEM_XWINDOW);
css::awt::SystemDependentXWindow tmp;
aAny >>= tmp;
pParentWidget = GetGtkSalData()->GetGtkDisplay()->findGtkWidgetForNativeHandle(tmp.WindowHandle);
}
}
}
return pParentWidget;
}
// XInitialization
void SAL_CALL SalGtkFilePicker::initialize( const uno::Sequence<uno::Any>& aArguments )
@@ -1611,30 +1642,7 @@ void SAL_CALL SalGtkFilePicker::initialize( const uno::Sequence<uno::Any>& aArgu
sal_Int16 templateId = -1;
aAny >>= templateId;
css::uno::Reference<css::awt::XWindow> xParentWindow;
if (aArguments.getLength() > 1)
{
aArguments[1] >>= xParentWindow;
}
if (xParentWindow.is())
{
if (SalGtkXWindow* pGtkXWindow = dynamic_cast<SalGtkXWindow*>(xParentWindow.get()))
m_pParentWidget = pGtkXWindow->getGtkWidget();
else
{
css::uno::Reference<css::awt::XSystemDependentWindowPeer> xSysDepWin(xParentWindow, css::uno::UNO_QUERY);
if (xSysDepWin.is())
{
css::uno::Sequence<sal_Int8> aProcessIdent(16);
rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
aAny = xSysDepWin->getWindowHandle(aProcessIdent, css::lang::SystemDependent::SYSTEM_XWINDOW);
css::awt::SystemDependentXWindow tmp;
aAny >>= tmp;
m_pParentWidget = GetGtkSalData()->GetGtkDisplay()->findGtkWidgetForNativeHandle(tmp.WindowHandle);
}
}
}
m_pParentWidget = GetParentWidget(aArguments);
GtkFileChooserAction eAction = GTK_FILE_CHOOSER_ACTION_OPEN;
OString sOpen = getOpenText();
diff --git a/vcl/unx/gtk3/fpicker/SalGtkFilePicker.hxx b/vcl/unx/gtk3/fpicker/SalGtkFilePicker.hxx
index 5797a7a..4c07f1b 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkFilePicker.hxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkFilePicker.hxx
@@ -147,7 +147,6 @@ class SalGtkFilePicker : public SalGtkPicker, public SalGtkFilePicker_Base
css::uno::Reference< css::ui::dialogs::XFilePickerListener >
m_xListener;
std::unique_ptr<std::vector<FilterEntry>> m_pFilterVector;
GtkWidget *m_pParentWidget;
GtkWidget *m_pVBox;
GtkWidget *m_pFilterExpander;
GtkWidget *m_pFilterView;
diff --git a/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.cxx b/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.cxx
index 21ac1b5..ae617d5 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.cxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.cxx
@@ -156,8 +156,12 @@ sal_Int16 SAL_CALL SalGtkFolderPicker::execute()
uno::Reference<frame::XDesktop> xDesktop = frame::Desktop::create(m_xContext);
GtkWindow *pParent = RunDialog::GetTransientFor();
fprintf(stderr, "transient is %p\n", pParent);
GtkWindow *pParent = GTK_WINDOW(m_pParentWidget);
if (!pParent)
{
SAL_WARN( "vcl.gtk", "no parent widget set");
pParent = RunDialog::GetTransientFor();
}
if (pParent)
gtk_window_set_transient_for(GTK_WINDOW(m_pDialog), pParent);
rtl::Reference<RunDialog> pRunDialog = new RunDialog(m_pDialog, xToolkit, xDesktop);
@@ -179,6 +183,13 @@ sal_Int16 SAL_CALL SalGtkFolderPicker::execute()
return retVal;
}
// XInitialization
void SAL_CALL SalGtkFolderPicker::initialize(const uno::Sequence<uno::Any>& aArguments)
{
m_pParentWidget = GetParentWidget(aArguments);
}
// XCancellable
void SAL_CALL SalGtkFolderPicker::cancel()
diff --git a/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.hxx b/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.hxx
index a7425d6..5b1d8dc 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.hxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkFolderPicker.hxx
@@ -27,7 +27,7 @@
class SalGtkFolderPicker :
public SalGtkPicker,
public cppu::WeakImplHelper< css::ui::dialogs::XFolderPicker2 >
public cppu::WeakImplHelper<css::ui::dialogs::XFolderPicker2, css::lang::XInitialization>
{
public:
@@ -50,6 +50,10 @@ class SalGtkFolderPicker :
virtual void SAL_CALL setDescription( const OUString& rDescription ) override;
// XInitialization
virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
// XCancellable
virtual void SAL_CALL cancel( ) override;
diff --git a/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx b/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
index a14582b..6f7a927 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkPicker.cxx
@@ -226,7 +226,9 @@ IMPL_STATIC_LINK(RunDialog, TerminateDesktop, void*, p, void)
}
SalGtkPicker::SalGtkPicker( const uno::Reference<uno::XComponentContext>& xContext )
: m_pDialog( nullptr ), m_xContext( xContext )
: m_pParentWidget(nullptr)
, m_pDialog(nullptr)
, m_xContext(xContext)
{
}
diff --git a/vcl/unx/gtk3/fpicker/SalGtkPicker.hxx b/vcl/unx/gtk3/fpicker/SalGtkPicker.hxx
index 36cab84..8ebdcfd 100644
--- a/vcl/unx/gtk3/fpicker/SalGtkPicker.hxx
+++ b/vcl/unx/gtk3/fpicker/SalGtkPicker.hxx
@@ -55,6 +55,7 @@ class SalGtkPicker
virtual ~SalGtkPicker();
protected:
osl::Mutex m_rbHelperMtx;
GtkWidget *m_pParentWidget;
GtkWidget *m_pDialog;
protected:
/// @throws css::uno::RuntimeException
@@ -72,6 +73,8 @@ class SalGtkPicker
// to instantiate own services
css::uno::Reference< css::uno::XComponentContext > m_xContext;
static GtkWidget* GetParentWidget(const css::uno::Sequence<css::uno::Any>& rArguments);
static OUString getResString( sal_Int32 aId );
};