diff options
author | Katarina Behrens <Katarina.Behrens@cib.de> | 2018-08-09 17:14:14 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2018-08-12 22:25:54 +0200 |
commit | 8d791a9d9657f6573ce27947c0289b36c6eba77c (patch) | |
tree | 0a5a788620f7c7ec4404a45f81e8f3b8c5722db2 /vcl | |
parent | 20444972edb1dd49af13902a850a8e343d5a60ec (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>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/CustomTarget_qt5_moc.mk | 1 | ||||
-rw-r--r-- | vcl/Library_vclplug_qt5.mk | 1 | ||||
-rw-r--r-- | vcl/inc/qt5/Qt5Frame.hxx | 12 | ||||
-rw-r--r-- | vcl/inc/qt5/Qt5MainWindow.hxx | 41 | ||||
-rw-r--r-- | vcl/inc/qt5/Qt5Widget.hxx | 2 | ||||
-rw-r--r-- | vcl/qt5/Qt5Frame.cxx | 92 | ||||
-rw-r--r-- | vcl/qt5/Qt5MainWindow.cxx | 36 | ||||
-rw-r--r-- | vcl/qt5/Qt5Menu.cxx | 4 | ||||
-rw-r--r-- | vcl/qt5/Qt5Widget.cxx | 34 |
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: */ |