vcl/CustomTarget_qt5_moc.mk   |    1 
 vcl/Library_vclplug_qt5.mk    |    1 
 vcl/inc/qt5/Qt5Frame.hxx      |   12 ++++-
 vcl/inc/qt5/Qt5MainWindow.hxx |   41 ++++++++++++++++++
 vcl/inc/qt5/Qt5Widget.hxx     |    2 
 vcl/qt5/Qt5Frame.cxx          |   92 +++++++++++++++++++++++++++++++-----------
 vcl/qt5/Qt5MainWindow.cxx     |   36 ++++++++++++++++
 vcl/qt5/Qt5Menu.cxx           |    4 -
 vcl/qt5/Qt5Widget.cxx         |   34 +++++----------
 9 files changed, 172 insertions(+), 51 deletions(-)

New commits:
commit 8d791a9d9657f6573ce27947c0289b36c6eba77c
Author:     Katarina Behrens <katarina.behr...@cib.de>
AuthorDate: Thu Aug 9 17:14:14 2018 +0200
Commit:     Thorsten Behrens <thorsten.behr...@cib.de>
CommitDate: Sun Aug 12 22:25:54 2018 +0200

    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.behr...@cib.de>

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: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to