summaryrefslogtreecommitdiff
path: root/vcl/qt5
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2019-06-05 14:04:24 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2019-12-09 15:32:17 +0100
commitd79a41a02cd46c50cab08ba1a5d5b213b6843251 (patch)
tree38f2d9efad66ab9d9b2e96763eedb6b34ac9656a /vcl/qt5
parent8ae03b548e4b98d4740ab986c41fc24279734128 (diff)
tdf#129071 Qt5 set file picker parent widget
If the XInitialization::initialize has a parent option, use that system window ID to find the parent Qt5Frame and set this as the parent of the file picker. This way the file picker doesn't show up as a separate window in the KDE task bar and get the proper icon. Just setting it transient to the parent is not enough. This also includes the terminate listener handling, so an open file picker won't prevent LO to shut down gracefully (which is handled independent from the document modified state). Change-Id: I62aef532e739e7fea9fe8a4b4e6c0e205faae1d9 Reviewed-on: https://gerrit.libreoffice.org/74544 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/qt5')
-rw-r--r--vcl/qt5/Qt5FilePicker.cxx89
1 files changed, 69 insertions, 20 deletions
diff --git a/vcl/qt5/Qt5FilePicker.cxx b/vcl/qt5/Qt5FilePicker.cxx
index 10c25052fd8a..d37c28b33c11 100644
--- a/vcl/qt5/Qt5FilePicker.cxx
+++ b/vcl/qt5/Qt5FilePicker.cxx
@@ -25,8 +25,15 @@
#include <Qt5Widget.hxx>
#include <Qt5Instance.hxx>
+#include <com/sun/star/awt/SystemDependentXWindow.hpp>
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/TerminationVetoException.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/ControlActions.hpp>
@@ -36,6 +43,7 @@
#include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp>
#include <cppuhelper/interfacecontainer.h>
#include <cppuhelper/supportsservice.hxx>
+#include <rtl/process.h>
#include <sal/log.hxx>
#include <QtCore/QDebug>
@@ -80,6 +88,7 @@ Qt5FilePicker::Qt5FilePicker(css::uno::Reference<css::uno::XComponentContext> co
: Qt5FilePicker_Base(m_aHelperMutex)
, m_context(context)
, m_bIsFolderPicker(eMode == QFileDialog::Directory)
+ , m_pParentWidget(nullptr)
, m_pFileDialog(new QFileDialog(nullptr, {}, QDir::homePath()))
, m_pExtraControls(new QWidget())
{
@@ -155,17 +164,16 @@ sal_Int16 SAL_CALL Qt5FilePicker::execute()
return ret;
}
- vcl::Window* pWindow = ::Application::GetActiveTopWindow();
- QWidget* pTransientParent = nullptr;
- QWindow* pTransientWindow = nullptr;
- if (pWindow)
+ QWidget* pTransientParent = m_pParentWidget;
+ if (!pTransientParent)
{
- Qt5Frame* pFrame = dynamic_cast<Qt5Frame*>(pWindow->ImplGetFrame());
- assert(pFrame);
- if (pFrame)
+ vcl::Window* pWindow = ::Application::GetActiveTopWindow();
+ if (pWindow)
{
- pTransientParent = pFrame->GetQWidget();
- pTransientWindow = pTransientParent->window()->windowHandle();
+ Qt5Frame* pFrame = dynamic_cast<Qt5Frame*>(pWindow->ImplGetFrame());
+ assert(pFrame);
+ if (pFrame)
+ pTransientParent = pFrame->asChild();
}
}
@@ -174,16 +182,19 @@ sal_Int16 SAL_CALL Qt5FilePicker::execute()
if (!m_aCurrentFilter.isEmpty())
m_pFileDialog->selectNameFilter(m_aCurrentFilter);
- if (pTransientParent)
- {
- m_pFileDialog->show();
- m_pFileDialog->window()->windowHandle()->setTransientParent(pTransientWindow);
- m_pFileDialog->setFocusProxy(pTransientParent);
- }
-
updateAutomaticFileExtension();
+ uno::Reference<css::frame::XDesktop> xDesktop(css::frame::Desktop::create(m_context),
+ UNO_QUERY_THROW);
+
+ // will hide the window, so do before show
+ m_pFileDialog->setParent(pTransientParent, m_pFileDialog->windowFlags());
+ m_pFileDialog->show();
+ xDesktop->addTerminateListener(this);
int result = m_pFileDialog->exec();
+ xDesktop->removeTerminateListener(this);
+ m_pFileDialog->setParent(nullptr, m_pFileDialog->windowFlags());
+
if (QFileDialog::Rejected == result)
return ExecutableDialogResults::CANCEL;
return ExecutableDialogResults::OK;
@@ -679,9 +690,7 @@ void SAL_CALL Qt5FilePicker::initialize(const uno::Sequence<uno::Any>& args)
// parameter checking
uno::Any arg;
if (args.getLength() == 0)
- {
throw lang::IllegalArgumentException("no arguments", static_cast<XFilePicker2*>(this), 1);
- }
arg = args[0];
@@ -805,11 +814,40 @@ void SAL_CALL Qt5FilePicker::initialize(const uno::Sequence<uno::Any>& args)
m_pFileDialog->setAcceptMode(acceptMode);
m_pFileDialog->setWindowTitle(getResString(resId));
+
+ css::uno::Reference<css::awt::XWindow> xParentWindow;
+ if (args.getLength() > 1)
+ args[1] >>= xParentWindow;
+ if (xParentWindow.is())
+ {
+ css::uno::Reference<css::awt::XSystemDependentWindowPeer> xSysWinPeer(xParentWindow,
+ css::uno::UNO_QUERY);
+ if (xSysWinPeer.is())
+ {
+ // the sal_*Int8 handling is strange, but it's public API - no way around
+ css::uno::Sequence<sal_Int8> aProcessIdent(16);
+ rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
+ uno::Any aAny = xSysWinPeer->getWindowHandle(
+ aProcessIdent, css::lang::SystemDependent::SYSTEM_XWINDOW);
+ css::awt::SystemDependentXWindow xSysWin;
+ aAny >>= xSysWin;
+
+ const auto& pFrames = pSalInst->getFrames();
+ const long aWindowHandle = xSysWin.WindowHandle;
+ const auto it = std::find_if(pFrames.begin(), pFrames.end(),
+ [&aWindowHandle](auto pFrame) -> bool {
+ const SystemEnvData* pData = pFrame->GetSystemData();
+ return pData && long(pData->aWindow) == aWindowHandle;
+ });
+ if (it != pFrames.end())
+ m_pParentWidget = static_cast<Qt5Frame*>(*it)->asChild();
+ }
+ }
}
-void SAL_CALL Qt5FilePicker::cancel() {}
+void SAL_CALL Qt5FilePicker::cancel() { m_pFileDialog->reject(); }
-void Qt5FilePicker::disposing(const lang::EventObject& rEvent)
+void SAL_CALL Qt5FilePicker::disposing(const lang::EventObject& rEvent)
{
uno::Reference<XFilePickerListener> xFilePickerListener(rEvent.Source, uno::UNO_QUERY);
@@ -819,6 +857,17 @@ void Qt5FilePicker::disposing(const lang::EventObject& rEvent)
}
}
+void SAL_CALL Qt5FilePicker::queryTermination(const css::lang::EventObject&)
+{
+ throw css::frame::TerminationVetoException();
+}
+
+void SAL_CALL Qt5FilePicker::notifyTermination(const css::lang::EventObject&)
+{
+ SolarMutexGuard aGuard;
+ m_pFileDialog->reject();
+}
+
OUString SAL_CALL Qt5FilePicker::getImplementationName()
{
return "com.sun.star.ui.dialogs.Qt5FilePicker";