summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatarina Behrens <Katarina.Behrens@cib.de>2018-08-09 17:14:14 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2018-08-12 22:25:54 +0200
commit8d791a9d9657f6573ce27947c0289b36c6eba77c (patch)
tree0a5a788620f7c7ec4404a45f81e8f3b8c5722db2
parent20444972edb1dd49af13902a850a8e343d5a60ec (diff)
Set Qt5Widget to be a central widget of QMainWindow
this is meant to solve the problem of native menu bar overlapping w/ non-native, as well as the inability to place an object or select text dragging the mouse cursor w/ LMB pressed Change-Id: I29f590ebf79d1ecc7e17b402125384cf13774bf3 Reviewed-on: https://gerrit.libreoffice.org/58171 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rw-r--r--vcl/CustomTarget_qt5_moc.mk1
-rw-r--r--vcl/Library_vclplug_qt5.mk1
-rw-r--r--vcl/inc/qt5/Qt5Frame.hxx12
-rw-r--r--vcl/inc/qt5/Qt5MainWindow.hxx41
-rw-r--r--vcl/inc/qt5/Qt5Widget.hxx2
-rw-r--r--vcl/qt5/Qt5Frame.cxx92
-rw-r--r--vcl/qt5/Qt5MainWindow.cxx36
-rw-r--r--vcl/qt5/Qt5Menu.cxx4
-rw-r--r--vcl/qt5/Qt5Widget.cxx34
9 files changed, 172 insertions, 51 deletions
diff --git a/vcl/CustomTarget_qt5_moc.mk b/vcl/CustomTarget_qt5_moc.mk
index 3962a730d388..afce4d44fd2b 100644
--- a/vcl/CustomTarget_qt5_moc.mk
+++ b/vcl/CustomTarget_qt5_moc.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_CustomTarget_CustomTarget,vcl/qt5))
$(call gb_CustomTarget_get_target,vcl/qt5) : \
$(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5FilePicker.moc \
$(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5Instance.moc \
+ $(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5MainWindow.moc \
$(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5Menu.moc \
$(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5Timer.moc \
$(call gb_CustomTarget_get_workdir,vcl/qt5)/Qt5Widget.moc \
diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index 1ad01555ed3a..d66a82319ed2 100644
--- a/vcl/Library_vclplug_qt5.mk
+++ b/vcl/Library_vclplug_qt5.mk
@@ -92,6 +92,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\
vcl/qt5/Qt5Graphics_Text \
vcl/qt5/Qt5Instance \
vcl/qt5/Qt5Instance_Print \
+ vcl/qt5/Qt5MainWindow \
vcl/qt5/Qt5Menu \
vcl/qt5/Qt5Object \
vcl/qt5/Qt5Painter \
diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx
index 310298879e52..04ade0b38b2d 100644
--- a/vcl/inc/qt5/Qt5Frame.hxx
+++ b/vcl/inc/qt5/Qt5Frame.hxx
@@ -31,7 +31,9 @@ class Qt5Graphics;
class Qt5Instance;
class Qt5Menu;
class QWidget;
+class Qt5MainWindow;
class QPaintDevice;
+class QScreen;
class QImage;
class SvpSalGraphics;
@@ -39,7 +41,8 @@ class VCLPLUG_QT5_PUBLIC Qt5Frame : public SalFrame
{
friend class VclQtMixinBase;
- std::unique_ptr<QWidget> m_pQWidget;
+ QWidget* m_pQWidget;
+ Qt5MainWindow* m_pTopLevel;
const bool m_bUseCairo;
std::unique_ptr<QImage> m_pQImage;
@@ -76,6 +79,10 @@ class VCLPLUG_QT5_PUBLIC Qt5Frame : public SalFrame
return bool(m_nStyle & nMask);
}
+ bool isWindow();
+ QWindow* windowHandle();
+ QScreen* screen();
+
void TriggerPaintEvent();
void TriggerPaintEvent(QRect aRect);
@@ -83,7 +90,8 @@ public:
Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nSalFrameStyle, bool bUseCairo);
virtual ~Qt5Frame() override;
- QWidget* GetQWidget() const { return m_pQWidget.get(); }
+ QWidget* GetQWidget() const { return m_pQWidget; }
+ Qt5MainWindow* GetTopLevelWindow() const { return m_pTopLevel; }
void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
sal_Int32 nExtentsHeight) const;
diff --git a/vcl/inc/qt5/Qt5MainWindow.hxx b/vcl/inc/qt5/Qt5MainWindow.hxx
new file mode 100644
index 000000000000..caac2299c4bc
--- /dev/null
+++ b/vcl/inc/qt5/Qt5MainWindow.hxx
@@ -0,0 +1,41 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QMainWindow>
+
+#include "Qt5Frame.hxx"
+
+class Qt5MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+ Qt5Frame* m_pFrame;
+
+ virtual void closeEvent(QCloseEvent* pEvent) override;
+
+public:
+ Qt5MainWindow(Qt5Frame& rFrame, QWidget* parent = Q_NULLPTR,
+ Qt::WindowFlags f = Qt::WindowFlags());
+ virtual ~Qt5MainWindow() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/Qt5Widget.hxx b/vcl/inc/qt5/Qt5Widget.hxx
index efe71bd3f644..206b8b2d1d6e 100644
--- a/vcl/inc/qt5/Qt5Widget.hxx
+++ b/vcl/inc/qt5/Qt5Widget.hxx
@@ -25,6 +25,4 @@
QWidget* createQt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f);
-QWidget* createQMainWindow(Qt5Frame& rFrame, Qt::WindowFlags f);
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 1a66799d2548..ab8d51fdb336 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -23,6 +23,7 @@
#include <Qt5Instance.hxx>
#include <Qt5Graphics.hxx>
#include <Qt5Widget.hxx>
+#include <Qt5MainWindow.hxx>
#include <Qt5Data.hxx>
#include <Qt5Menu.hxx>
@@ -35,6 +36,7 @@
#include <QtWidgets/QToolTip>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QMainWindow>
#include <saldatabasic.hxx>
#include <window.h>
@@ -52,7 +54,9 @@ static void SvpDamageHandler(void* handle, sal_Int32 nExtentsX, sal_Int32 nExten
}
Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
- : m_bUseCairo(bUseCairo)
+ : m_pTopLevel(nullptr)
+ , m_bUseCairo(bUseCairo)
+ , m_pSvpGraphics(nullptr)
, m_bGraphicsInUse(false)
, m_ePointerStyle(PointerStyle::Arrow)
, m_bDefaultSize(true)
@@ -94,10 +98,14 @@ Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
aWinFlags |= Qt::Window;
}
- if (pParent)
- m_pQWidget.reset(createQt5Widget(*this, aWinFlags));
+ if (!pParent && (aWinFlags == Qt::Window))
+ {
+ m_pTopLevel = new Qt5MainWindow(*this, nullptr, aWinFlags);
+ m_pQWidget = createQt5Widget(*this, aWinFlags);
+ m_pTopLevel->setCentralWidget(m_pQWidget);
+ }
else
- m_pQWidget.reset(createQMainWindow(*this, aWinFlags));
+ m_pQWidget = createQt5Widget(*this, aWinFlags);
if (pParent && !(pParent->m_nStyle & SalFrameStyleFlags::PLUG))
{
@@ -110,7 +118,7 @@ Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
// fake an initial geometry, gets updated via configure event or SetPosSize
if (m_bDefaultPos || m_bDefaultSize)
{
- Size aDefSize = CalcDefaultSize();
+ Size aDefSize = Size(0, 0); // CalcDefaultSize();
maGeometry.nX = -1;
maGeometry.nY = -1;
maGeometry.nWidth = aDefSize.Width();
@@ -126,6 +134,10 @@ Qt5Frame::~Qt5Frame()
{
Qt5Instance* pInst = static_cast<Qt5Instance*>(GetSalData()->m_pInstance);
pInst->eraseFrame(this);
+ if (m_pTopLevel)
+ delete m_pTopLevel;
+ else
+ delete m_pQWidget;
}
void Qt5Frame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
@@ -149,8 +161,8 @@ void Qt5Frame::TriggerPaintEvent(QRect aRect)
void Qt5Frame::InitSvpSalGraphics(SvpSalGraphics* pSvpSalGraphics)
{
- int width = m_pQWidget->size().width();
- int height = m_pQWidget->size().height();
+ int width = 100;
+ int height = 100;
m_pSvpGraphics = pSvpSalGraphics;
m_pSurface.reset(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height));
m_pSvpGraphics->setSurface(m_pSurface.get(), basegfx::B2IVector(width, height));
@@ -205,6 +217,30 @@ bool Qt5Frame::PostEvent(ImplSVEvent* pData)
return true;
}
+bool Qt5Frame::isWindow()
+{
+ if (m_pTopLevel)
+ return m_pTopLevel->isWindow();
+ else
+ return m_pQWidget->isWindow();
+}
+
+QWindow* Qt5Frame::windowHandle()
+{
+ if (m_pTopLevel)
+ return m_pTopLevel->windowHandle();
+ else
+ return m_pQWidget->windowHandle();
+}
+
+QScreen* Qt5Frame::screen()
+{
+ if (m_pTopLevel)
+ return m_pTopLevel->windowHandle()->screen();
+ else
+ return m_pQWidget->windowHandle()->screen();
+}
+
void Qt5Frame::SetTitle(const OUString& rTitle)
{
m_pQWidget->window()->setWindowTitle(toQString(rTitle));
@@ -216,7 +252,7 @@ void Qt5Frame::SetIcon(sal_uInt16 nIcon)
& (SalFrameStyleFlags::PLUG | SalFrameStyleFlags::SYSTEMCHILD
| SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::INTRO
| SalFrameStyleFlags::OWNERDRAWDECORATION)
- || !m_pQWidget->isWindow())
+ || !isWindow())
return;
const char* appicon;
@@ -248,8 +284,11 @@ void Qt5Frame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) {}
void Qt5Frame::Show(bool bVisible, bool /*bNoActivate*/)
{
- assert(m_pQWidget.get());
- m_pQWidget->setVisible(bVisible);
+ assert(m_pQWidget);
+ if (m_pTopLevel)
+ m_pTopLevel->setVisible(bVisible);
+ else
+ m_pQWidget->setVisible(bVisible);
}
void Qt5Frame::SetMinClientSize(long nWidth, long nHeight)
@@ -276,8 +315,8 @@ void Qt5Frame::Center()
Size Qt5Frame::CalcDefaultSize()
{
- assert(m_pQWidget->isWindow());
- QScreen* pScreen = m_pQWidget->windowHandle()->screen();
+ assert(isWindow());
+ QScreen* pScreen = screen();
if (!pScreen)
return Size();
return bestmaxFrameSizeForScreenSize(toSize(pScreen->size()));
@@ -292,7 +331,7 @@ void Qt5Frame::SetDefaultSize()
void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags)
{
- if (!m_pQWidget->isWindow() || isChild(true, false))
+ if (!isWindow() || isChild(true, false))
return;
if ((nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
@@ -314,7 +353,12 @@ void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt1
{
if (m_pParent)
{
- QRect aRect = m_pParent->GetQWidget()->geometry();
+ QRect aRect;
+ if (m_pParent->GetTopLevelWindow())
+ aRect = m_pParent->GetTopLevelWindow()->geometry();
+ else
+ aRect = m_pParent->GetQWidget()->geometry();
+
nX += aRect.x();
nY += aRect.y();
}
@@ -339,9 +383,9 @@ void Qt5Frame::GetClientSize(long& rWidth, long& rHeight)
void Qt5Frame::GetWorkArea(tools::Rectangle& rRect)
{
- if (!m_pQWidget->isWindow())
+ if (!isWindow())
return;
- QScreen* pScreen = m_pQWidget->windowHandle()->screen();
+ QScreen* pScreen = screen();
if (!pScreen)
return;
@@ -353,19 +397,21 @@ SalFrame* Qt5Frame::GetParent() const { return m_pParent; }
void Qt5Frame::SetModal(bool bModal)
{
- if (m_pQWidget->isWindow())
+ if (isWindow())
{
+ if (m_pTopLevel)
+ m_pTopLevel->setVisible(true);
// modality change is only effective if the window is hidden
- m_pQWidget->windowHandle()->hide();
- m_pQWidget->windowHandle()->setModality(bModal ? Qt::WindowModal : Qt::NonModal);
+ windowHandle()->hide();
+ windowHandle()->setModality(bModal ? Qt::WindowModal : Qt::NonModal);
// and shown again
- m_pQWidget->windowHandle()->show();
+ windowHandle()->show();
}
}
void Qt5Frame::SetWindowState(const SalFrameState* pState)
{
- if (!m_pQWidget->isWindow() || !pState || isChild(true, false))
+ if (!isWindow() || !pState || isChild(true, false))
return;
const WindowStateMask nMaxGeometryMask
@@ -403,7 +449,7 @@ void Qt5Frame::SetWindowState(const SalFrameState* pState)
}
else if (pState->mnMask & WindowStateMask::State && !isChild())
{
- if ((pState->mnState & WindowStateState::Minimized) && m_pQWidget->isWindow())
+ if ((pState->mnState & WindowStateState::Minimized) && isWindow())
m_pQWidget->showMinimized();
else
m_pQWidget->showNormal();
@@ -422,7 +468,7 @@ bool Qt5Frame::GetWindowState(SalFrameState* pState)
}
else
{
- QRect rect = m_pQWidget->geometry();
+ QRect rect = m_pTopLevel ? m_pTopLevel->geometry() : m_pQWidget->geometry();
pState->mnX = rect.x();
pState->mnY = rect.y();
pState->mnWidth = rect.width();
diff --git a/vcl/qt5/Qt5MainWindow.cxx b/vcl/qt5/Qt5MainWindow.cxx
new file mode 100644
index 000000000000..56e296b4f97a
--- /dev/null
+++ b/vcl/qt5/Qt5MainWindow.cxx
@@ -0,0 +1,36 @@
+/* -*- 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/.
+ *
+ */
+
+#include "Qt5MainWindow.hxx"
+#include <Qt5MainWindow.moc>
+
+#include <QtGui/QCloseEvent>
+
+Qt5MainWindow::Qt5MainWindow(Qt5Frame& rFrame, QWidget* parent, Qt::WindowFlags f)
+ : QMainWindow(parent, f)
+ , m_pFrame(&rFrame)
+{
+}
+
+Qt5MainWindow::~Qt5MainWindow() {}
+
+void Qt5MainWindow::closeEvent(QCloseEvent* pEvent)
+{
+ bool bRet = false;
+ bRet = m_pFrame->CallCallback(SalEvent::Close, nullptr);
+
+ if (bRet)
+ pEvent->accept();
+ // SalEvent::Close returning false may mean that user has vetoed
+ // closing the frame ("you have unsaved changes" dialog for example)
+ // We shouldn't process the event in such case
+ else
+ pEvent->ignore();
+}
diff --git a/vcl/qt5/Qt5Menu.cxx b/vcl/qt5/Qt5Menu.cxx
index b594b8ad44c3..859f365aa3ea 100644
--- a/vcl/qt5/Qt5Menu.cxx
+++ b/vcl/qt5/Qt5Menu.cxx
@@ -8,6 +8,7 @@
*/
#include <Qt5Frame.hxx>
+#include <Qt5MainWindow.hxx>
#include <Qt5Menu.hxx>
#include <Qt5Menu.moc>
@@ -68,8 +69,7 @@ void Qt5Menu::SetFrame(const SalFrame* pFrame)
mpFrame->SetMenu(this);
- QWidget* pWidget = mpFrame->GetQWidget();
- QMainWindow* pMainWindow = dynamic_cast<QMainWindow*>(pWidget);
+ Qt5MainWindow* pMainWindow = mpFrame->GetTopLevelWindow();
if (pMainWindow)
mpQMenuBar = pMainWindow->menuBar();
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index 75f95b40310e..f4008ed8fb0a 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -86,11 +86,16 @@ void VclQtMixinBase::mixinResizeEvent(QResizeEvent*, QSize aSize)
{
int width = aSize.width();
int height = aSize.height();
- cairo_surface_t* pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
- cairo_surface_set_user_data(pSurface, SvpSalGraphics::getDamageKey(),
- &m_pFrame->m_aDamageHandler, nullptr);
- m_pFrame->m_pSvpGraphics->setSurface(pSurface, basegfx::B2IVector(width, height));
- m_pFrame->m_pSurface.reset(pSurface);
+
+ if (m_pFrame->m_pSvpGraphics)
+ {
+ cairo_surface_t* pSurface
+ = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cairo_surface_set_user_data(pSurface, SvpSalGraphics::getDamageKey(),
+ &m_pFrame->m_aDamageHandler, nullptr);
+ m_pFrame->m_pSvpGraphics->setSurface(pSurface, basegfx::B2IVector(width, height));
+ m_pFrame->m_pSurface.reset(pSurface);
+ }
}
else
{
@@ -199,18 +204,9 @@ void VclQtMixinBase::mixinShowEvent(QShowEvent*)
m_pFrame->CallCallback(SalEvent::Paint, &aPaintEvt);
}
-void VclQtMixinBase::mixinCloseEvent(QCloseEvent* pEvent)
+void VclQtMixinBase::mixinCloseEvent(QCloseEvent* /*pEvent*/)
{
- bool bRet = false;
- bRet = m_pFrame->CallCallback(SalEvent::Close, nullptr);
-
- if (bRet)
- pEvent->accept();
- // SalEvent::Close returning false may mean that user has vetoed
- // closing the frame ("you have unsaved changes" dialog for example)
- // We shouldn't process the event in such case
- else
- pEvent->ignore();
+ m_pFrame->CallCallback(SalEvent::Close, nullptr);
}
static sal_uInt16 GetKeyCode(int keyval)
@@ -470,7 +466,6 @@ public:
virtual ~Qt5Widget() override{};
friend QWidget* createQt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f);
- friend QWidget* createQMainWindow(Qt5Frame& rFrame, Qt::WindowFlags f);
};
QWidget* createQt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f)
@@ -478,9 +473,4 @@ QWidget* createQt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f)
return new Qt5Widget<QWidget>(rFrame, f);
}
-QWidget* createQMainWindow(Qt5Frame& rFrame, Qt::WindowFlags f)
-{
- return new Qt5Widget<QMainWindow>(rFrame, f);
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */