summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qmainwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qmainwindow.cpp')
-rw-r--r--src/widgets/widgets/qmainwindow.cpp201
1 files changed, 90 insertions, 111 deletions
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 411b482c11..4534058d45 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//#define QT_EXPERIMENTAL_CLIENT_DECORATIONS
@@ -61,40 +25,42 @@
#include <qstyle.h>
#include <qdebug.h>
#include <qpainter.h>
+#include <qmimedata.h>
#include <private/qwidget_p.h>
#if QT_CONFIG(toolbar)
#include "qtoolbar_p.h"
#endif
#include "qwidgetanimator_p.h"
-#ifdef Q_OS_OSX
-#include <qpa/qplatformnativeinterface.h>
-#endif
+#include <QtGui/qpa/qplatformwindow.h>
+#include <QtGui/qpa/qplatformwindow_p.h>
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
class QMainWindowPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QMainWindow)
public:
inline QMainWindowPrivate()
- : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly)
-#ifdef Q_OS_OSX
+ : layout(nullptr), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly)
+#ifdef Q_OS_MACOS
, useUnifiedToolBar(false)
#endif
{ }
- QMainWindowLayout *layout;
+ QPointer<QMainWindowLayout> layout;
QSize iconSize;
bool explicitIconSize;
Qt::ToolButtonStyle toolButtonStyle;
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
bool useUnifiedToolBar;
#endif
void init();
static inline QMainWindowLayout *mainWindowLayout(const QMainWindow *mainWindow)
{
- return mainWindow ? mainWindow->d_func()->layout : static_cast<QMainWindowLayout *>(0);
+ return mainWindow ? mainWindow->d_func()->layout.data() : static_cast<QMainWindowLayout *>(nullptr);
}
};
@@ -152,12 +118,13 @@ void QMainWindowPrivate::init()
topLayout->addItem(layout, 1, 1);
#else
- layout = new QMainWindowLayout(q, 0);
+ layout = new QMainWindowLayout(q, nullptr);
#endif
- const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
+ const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, nullptr, q);
iconSize = QSize(metric, metric);
q->setAttribute(Qt::WA_Hover);
+ q->setAcceptDrops(true);
}
/*
@@ -214,9 +181,6 @@ void QMainWindowPrivate::init()
\image mainwindowlayout.png
- \note Creating a main window without a central widget is not supported.
- You must have a central widget even if it is just a placeholder.
-
\section1 Creating Main Window Components
A central widget will typically be a standard Qt widget such
@@ -316,9 +280,7 @@ void QMainWindowPrivate::init()
is the position and size (relative to the size of the main window)
of the toolbars and dock widgets that are stored.
- \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Application
- Example}, {Dock Widgets Example}, {MDI Example}, {SDI Example},
- {Menus Example}
+ \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Menus Example}
*/
/*!
@@ -452,7 +414,7 @@ void QMainWindow::setIconSize(const QSize &iconSize)
Q_D(QMainWindow);
QSize sz = iconSize;
if (!sz.isValid()) {
- const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, this);
+ const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, nullptr, this);
sz = QSize(metric, metric);
}
if (d->iconSize != sz) {
@@ -523,10 +485,10 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
{
QLayout *topLayout = layout();
- if (topLayout->menuBar() && topLayout->menuBar() != menuBar) {
+ if (QWidget *existingMenuBar = topLayout->menuBar(); existingMenuBar && existingMenuBar != menuBar) {
// Reparent corner widgets before we delete the old menu bar.
- QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(topLayout->menuBar());
- if (menuBar) {
+ QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(existingMenuBar);
+ if (oldMenuBar && menuBar) {
// TopLeftCorner widget.
QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
if (cornerWidget)
@@ -536,9 +498,10 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar)
if (cornerWidget)
menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
}
- oldMenuBar->hide();
- oldMenuBar->setParent(nullptr);
- oldMenuBar->deleteLater();
+
+ existingMenuBar->hide();
+ existingMenuBar->setParent(nullptr);
+ existingMenuBar->deleteLater();
}
topLayout->setMenuBar(menuBar);
}
@@ -596,7 +559,7 @@ QStatusBar *QMainWindow::statusBar() const
/*!
Sets the status bar for the main window to \a statusbar.
- Setting the status bar to 0 will remove it from the main window.
+ Setting the status bar to \nullptr will remove it from the main window.
Note that QMainWindow takes ownership of the \a statusbar pointer
and deletes it at the appropriate time.
@@ -615,7 +578,7 @@ void QMainWindow::setStatusBar(QStatusBar *statusbar)
/*!
Returns the central widget for the main window. This function
- returns zero if the central widget has not been set.
+ returns \nullptr if the central widget has not been set.
\sa setCentralWidget()
*/
@@ -652,8 +615,8 @@ QWidget *QMainWindow::takeCentralWidget()
Q_D(QMainWindow);
QWidget *oldcentralwidget = d->layout->centralWidget();
if (oldcentralwidget) {
- oldcentralwidget->setParent(0);
- d->layout->setCentralWidget(0);
+ oldcentralwidget->setParent(nullptr);
+ d->layout->setCentralWidget(nullptr);
}
return oldcentralwidget;
}
@@ -762,7 +725,7 @@ void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
disconnect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
- if(toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
+ if (toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
//removing a toolbar which is dragging will cause crash
#if QT_CONFIG(dockwidget)
bool animated = isAnimated();
@@ -851,7 +814,7 @@ void QMainWindow::removeToolBar(QToolBar *toolbar)
\sa addToolBar(), addToolBarBreak(), Qt::ToolBarArea
*/
-Qt::ToolBarArea QMainWindow::toolBarArea(QToolBar *toolbar) const
+Qt::ToolBarArea QMainWindow::toolBarArea(const QToolBar *toolbar) const
{ return d_func()->layout->toolBarArea(toolbar); }
/*!
@@ -950,10 +913,10 @@ void QMainWindow::setDockNestingEnabled(bool enabled)
\since 4.2
If this property is set to false, dock areas containing tabbed dock widgets
- display horizontal tabs, simmilar to Visual Studio.
+ display horizontal tabs, similar to Visual Studio.
If this property is set to true, then the right and left dock areas display vertical
- tabs, simmilar to KDevelop.
+ tabs, similar to KDevelop.
This property should be set before any dock widgets are added to the main window.
*/
@@ -1134,6 +1097,7 @@ void QMainWindow::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
d_func()->layout->splitDockWidget(after, dockwidget, orientation);
}
+#if QT_CONFIG(tabbar)
/*!
\fn void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
@@ -1159,26 +1123,10 @@ void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
{
- QList<QDockWidget*> ret;
-#if !QT_CONFIG(tabbar)
- Q_UNUSED(dockwidget);
-#else
- const QDockAreaLayoutInfo *info = d_func()->layout->layoutState.dockAreaLayout.info(dockwidget);
- if (info && info->tabbed && info->tabBar) {
- for(int i = 0; i < info->item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = info->item_list.at(i);
- if (item.widgetItem) {
- if (QDockWidget *dock = qobject_cast<QDockWidget*>(item.widgetItem->widget())) {
- if (dock != dockwidget) {
- ret += dock;
- }
- }
- }
- }
- }
-#endif
- return ret;
+ Q_D(const QMainWindow);
+ return d->layout ? d->layout->tabifiedDockWidgets(dockwidget) : QList<QDockWidget *>();
}
+#endif // QT_CONFIG(tabbar)
/*!
@@ -1221,7 +1169,7 @@ Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
resized such that the yellowWidget is twice as big as the blueWidget
If some widgets are grouped in tabs, only one widget per group should be
- specified. Widgets not in the list might be changed to repect the constraints.
+ specified. Widgets not in the list might be changed to respect the constraints.
*/
void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks,
const QList<int> &sizes, Qt::Orientation orientation)
@@ -1258,6 +1206,7 @@ QByteArray QMainWindow::saveState(int version) const
{
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << QMainWindowLayout::VersionMarker;
stream << version;
d_func()->layout->saveState(stream);
@@ -1286,6 +1235,7 @@ bool QMainWindow::restoreState(const QByteArray &state, int version)
return false;
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
int marker, v;
stream >> marker;
stream >> v;
@@ -1309,6 +1259,7 @@ bool QMainWindow::event(QEvent *event)
#if QT_CONFIG(toolbar)
case QEvent::ToolBarChange: {
+ Q_ASSERT(d->layout);
d->layout->toggleToolBarsVisible();
return true;
}
@@ -1317,6 +1268,7 @@ bool QMainWindow::event(QEvent *event)
#if QT_CONFIG(statustip)
case QEvent::StatusTip:
#if QT_CONFIG(statusbar)
+ Q_ASSERT(d->layout);
if (QStatusBar *sb = d->layout->statusBar())
sb->showMessage(static_cast<QStatusTipEvent*>(event)->tip());
else
@@ -1327,11 +1279,34 @@ bool QMainWindow::event(QEvent *event)
case QEvent::StyleChange:
#if QT_CONFIG(dockwidget)
+ Q_ASSERT(d->layout);
d->layout->layoutState.dockAreaLayout.styleChangedEvent();
#endif
if (!d->explicitIconSize)
setIconSize(QSize());
break;
+#if QT_CONFIG(draganddrop)
+ case QEvent::DragEnter:
+ case QEvent::Drop:
+ if (!d->layout->draggingWidget)
+ break;
+ event->accept();
+ return true;
+ case QEvent::DragMove: {
+ if (!d->layout->draggingWidget)
+ break;
+ auto dragMoveEvent = static_cast<QDragMoveEvent *>(event);
+ d->layout->hover(d->layout->draggingWidget,
+ mapToGlobal(dragMoveEvent->position()).toPoint());
+ event->accept();
+ return true;
+ }
+ case QEvent::DragLeave:
+ if (!d->layout->draggingWidget)
+ break;
+ d->layout->hover(d->layout->draggingWidget, pos() - QPoint(-1, -1));
+ return true;
+#endif
default:
break;
}
@@ -1347,38 +1322,42 @@ bool QMainWindow::event(QEvent *event)
Note that the Qt 5 implementation has several limitations compared to Qt 4:
\list
- \li Use in windows with OpenGL content is not supported. This includes QGLWidget and QOpenGLWidget.
+ \li Use in windows with OpenGL content is not supported. This includes QOpenGLWidget.
\li Using dockable or movable toolbars may result in painting errors and is not recommended
\endlist
\since 5.2
*/
-void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
+void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool enabled)
{
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
+ if (!isWindow())
+ return;
+
Q_D(QMainWindow);
- if (isWindow()) {
- d->useUnifiedToolBar = set;
- createWinId();
-
- QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
- QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
- nativeInterface->nativeResourceFunctionForIntegration("setContentBorderEnabled");
- if (!function)
- return; // Not Cocoa platform plugin.
-
- typedef void (*SetContentBorderEnabledFunction)(QWindow *window, bool enable);
- (reinterpret_cast<SetContentBorderEnabledFunction>(function))(window()->windowHandle(), set);
- update();
- }
+ d->useUnifiedToolBar = enabled;
+
+ // The unified toolbar is drawn by the macOS style with a transparent background.
+ // To ensure a suitable surface format is used we need to first create backing
+ // QWindow so we have something to update the surface format on, and then let
+ // QWidget know about the translucency, which it will propagate to the surface.
+ setAttribute(Qt::WA_NativeWindow);
+ setAttribute(Qt::WA_TranslucentBackground, enabled);
+
+ d->create(); // Create first, before querying the platform window
+ using namespace QNativeInterface::Private;
+ if (auto *platformWindow = dynamic_cast<QCocoaWindow*>(window()->windowHandle()->handle()))
+ platformWindow->setContentBorderEnabled(enabled);
+
+ update();
#else
- Q_UNUSED(set)
+ Q_UNUSED(enabled);
#endif
}
bool QMainWindow::unifiedTitleAndToolBarOnMac() const
{
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
return d_func()->useUnifiedToolBar;
#endif
return false;
@@ -1460,8 +1439,8 @@ void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
#if QT_CONFIG(menu)
/*!
Returns a popup menu containing checkable entries for the toolbars and
- dock widgets present in the main window. If there are no toolbars and
- dock widgets present, this function returns a null pointer.
+ dock widgets present in the main window. If there are no toolbars and
+ dock widgets present, this function returns \nullptr.
By default, this function is called by the main window when the user
activates a context menu, typically by right-clicking on a toolbar or a dock
@@ -1476,7 +1455,7 @@ void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
QMenu *QMainWindow::createPopupMenu()
{
Q_D(QMainWindow);
- QMenu *menu = 0;
+ QMenu *menu = nullptr;
#if QT_CONFIG(dockwidget)
QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
if (dockwidgets.size()) {