1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31
32#include <QtWidgets/qtwidgetsglobal.h>
33#if QT_CONFIG(dockwidget)
34#include <qdockwidget.h>
35#endif
36#include <qlayout.h>
37#include <qmainwindow.h>
38#include <qmenubar.h>
39#include <qstatusbar.h>
40#include <qstyle.h>
41#include <qtoolbar.h>
42#include <qpushbutton.h>
43#include <qlabel.h>
44#include <qtextedit.h>
45#include <qstylehints.h>
46#include <qscreen.h>
47#include <private/qmainwindowlayout_p.h>
48#include <private/qdockarealayout_p.h>
49
50#if QT_CONFIG(tabbar)
51#include <qtabbar.h>
52#endif
53
54static uchar restoreData41[] = { 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x1, 0x19, 0xfc, 0x2, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x30, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x34, 0x1, 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x38, 0x1, 0x0, 0x0, 0x0, 0x8d, 0x0, 0x0, 0x0, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x32, 0x1, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x1, 0x19, 0xfc, 0x2, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x35, 0x1, 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x39, 0x1, 0x0, 0x0, 0x0, 0x8d, 0x0, 0x0, 0x0, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x33, 0x1, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x89, 0x0, 0x0, 0x0, 0xe, 0xfc, 0x1, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x32, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x36, 0x1, 0x0, 0x0, 0x0, 0x63, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x30, 0x1, 0x0, 0x0, 0x0, 0xc8, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x34, 0x1, 0x0, 0x0, 0x1, 0x2a, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, 0x89, 0x0, 0x0, 0x0, 0xe, 0xfc, 0x1, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x33, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x37, 0x1, 0x0, 0x0, 0x0, 0x63, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x31, 0x1, 0x0, 0x0, 0x0, 0xc8, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x35, 0x1, 0x0, 0x0, 0x1, 0x2a, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x1, 0x19};
55static uchar restoreData42[] = { 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x0, 0x0, 0x2, 0x2b, 0xfc, 0x2, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x30, 0x1, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x34, 0x1, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x38, 0x1, 0x0, 0x0, 0x1, 0x42, 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x32, 0x1, 0x0, 0x0, 0x1, 0xcd, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x2, 0x2b, 0xfc, 0x2, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x1, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x35, 0x1, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x39, 0x1, 0x0, 0x0, 0x1, 0x42, 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x33, 0x1, 0x0, 0x0, 0x1, 0xcd, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x21, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x4, 0x4e, 0x0, 0x0, 0x0, 0x26, 0xfc, 0x1, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x32, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x12, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x36, 0x1, 0x0, 0x0, 0x1, 0x16, 0x0, 0x0, 0x1, 0xe, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x30, 0x1, 0x0, 0x0, 0x2, 0x28, 0x0, 0x0, 0x1, 0x14, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x34, 0x1, 0x0, 0x0, 0x3, 0x40, 0x0, 0x0, 0x1, 0xe, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x4, 0x4e, 0x0, 0x0, 0x0, 0x26, 0xfc, 0x1, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x33, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x12, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x37, 0x1, 0x0, 0x0, 0x1, 0x16, 0x0, 0x0, 0x1, 0xe, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x31, 0x1, 0x0, 0x0, 0x2, 0x28, 0x0, 0x0, 0x1, 0x14, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x35, 0x1, 0x0, 0x0, 0x3, 0x40, 0x0, 0x0, 0x1, 0xe, 0x0, 0x0, 0x0, 0xa, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x3, 0x8a, 0x0, 0x0, 0x2, 0x2b, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8};
56static uchar restoreData43[] = { 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0xa0, 0xfc, 0x2, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x30, 0x1, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x34, 0x1, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x38, 0x1, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x32, 0x1, 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0xa0, 0xfc, 0x2, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x1, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x35, 0x1, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x39, 0x1, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x33, 0x1, 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0xa8, 0x0, 0x0, 0x0, 0x26, 0xfc, 0x1, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x32, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x36, 0x1, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x30, 0x1, 0x0, 0x0, 0x0, 0xd6, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x34, 0x1, 0x0, 0x0, 0x1, 0x42, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, 0xa8, 0x0, 0x0, 0x0, 0x26, 0xfc, 0x1, 0x0, 0x0, 0x0, 0x4, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x33, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xc, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x37, 0x1, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x31, 0x1, 0x0, 0x0, 0x0, 0xd6, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x0, 0x64, 0x0, 0x6f, 0x0, 0x63, 0x0, 0x6b, 0x0, 0x20, 0x0, 0x31, 0x0, 0x35, 0x1, 0x0, 0x0, 0x1, 0x42, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x50, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0xb8, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0xfc, 0x0, 0x0, 0x0, 0x0};
57// Local scope class to simulate toolbar move.
58// For testcase void QTBUG21378_animationFinished();
59class CToolBarTimer : public QObject
60{
61 int m_timerId;
62 QToolBar *m_tb;
63public:
64 CToolBarTimer(QToolBar *tb) : m_tb(tb)
65 {
66 m_timerId = startTimer(interval: 200);
67 }
68 void timerEvent(QTimerEvent*)
69 {
70 QCoreApplication::postEvent(receiver: m_tb, event: new QMouseEvent(QEvent::MouseButtonPress, QPoint(6, 7), Qt::LeftButton, {}, {}));
71 QCoreApplication::postEvent(receiver: m_tb, event: new QMouseEvent(QEvent::MouseMove, QPoint(7, 8), Qt::LeftButton, Qt::LeftButton, {}));
72 QCoreApplication::postEvent(receiver: m_tb, event: new QMouseEvent(QEvent::MouseMove, QPoint(27, 23), Qt::LeftButton, Qt::LeftButton, {}));
73 QCoreApplication::postEvent(receiver: m_tb, event: new QMouseEvent(QEvent::MouseMove, QPoint(30, 27), Qt::LeftButton, Qt::LeftButton, {}));
74 QCoreApplication::postEvent(receiver: m_tb, event: new QMouseEvent(QEvent::MouseMove, QPoint(162, 109), Qt::LeftButton, Qt::LeftButton, {}));
75 QCoreApplication::postEvent(receiver: m_tb, event: new QMouseEvent(QEvent::MouseMove, QPoint(10, 4), Qt::LeftButton, Qt::LeftButton, {}));
76 QCoreApplication::postEvent(receiver: m_tb, event: new QMouseEvent(QEvent::MouseButtonRelease, QPoint(9, 4), Qt::LeftButton, {}, {}));
77 }
78};
79
80// Local class to simulate mousepress on main window.
81// For testcase void QTBUG21378_animationFinished();
82class CMainWindowTimer : public QObject
83{
84 int m_timerId;
85 QMainWindow *m_w;
86public:
87 CMainWindowTimer(QMainWindow *pmw) : m_w(pmw)
88 {
89 m_timerId = startTimer(interval: 100);
90 }
91
92 void timerEvent(QTimerEvent*)
93 {
94 QCoreApplication::postEvent(receiver: m_w, event: new QMouseEvent(QEvent::MouseButtonPress, QPoint(230, 370), Qt::LeftButton, {}, {}));
95 QCoreApplication::postEvent(receiver: m_w, event: new QMouseEvent(QEvent::MouseButtonRelease, QPoint(230, 370), Qt::LeftButton, {}, {}));
96 }
97};
98
99class tst_QMainWindow : public QObject
100{
101 Q_OBJECT
102
103public:
104 tst_QMainWindow();
105
106private slots:
107 void cleanup();
108 void getSetCheck();
109 void constructor();
110 void iconSize();
111 void toolButtonStyle();
112 void menuBar();
113 void centralWidget();
114 void takeCentralWidget();
115 void corner();
116 void addToolBarBreak();
117 void insertToolBarBreak();
118 void addToolBar();
119 void insertToolBar();
120 void removeToolBar();
121 void toolBarArea();
122 void addDockWidget();
123 void splitDockWidget();
124 void removeDockWidget();
125 void dockWidgetArea();
126 void restoreState();
127 void restoreStateFromPreviousVersion();
128 void createPopupMenu();
129 void hideBeforeLayout();
130#ifdef QT_BUILD_INTERNAL
131 void saveRestore();
132 void saveRestore_data();
133 void statusBar();
134#endif
135 void contentsMargins_data();
136 void contentsMargins();
137 void isSeparator();
138#ifndef QT_NO_CURSOR
139 void setCursor();
140#endif
141 void addToolbarAfterShow();
142 void centralWidgetSize();
143 void fixedSizeCentralWidget();
144 void dockWidgetSize();
145 void QTBUG2774_stylechange();
146 void QTBUG15080_restoreState();
147#ifdef Q_OS_MAC
148 void toggleUnifiedTitleAndToolBarOnMac();
149#endif
150 void QTBUG21378_animationFinished();
151 void resizeDocks();
152 void resizeDocks_data();
153#if QT_CONFIG(dockwidget) && QT_CONFIG(tabbar)
154 void QTBUG52175_tabifiedDockWidgetActivated();
155#endif
156};
157
158
159void tst_QMainWindow::cleanup()
160{
161 QVERIFY(QApplication::topLevelWidgets().isEmpty());
162}
163
164// Testing get/set functions
165void tst_QMainWindow::getSetCheck()
166{
167 QMainWindow obj1;
168 // QMenuBar * QMainWindow::menuBar()
169 // void QMainWindow::setMenuBar(QMenuBar *)
170 QPointer<QMenuBar> var1 = new QMenuBar;
171 obj1.setMenuBar(var1);
172 QCOMPARE(static_cast<QMenuBar *>(var1), obj1.menuBar());
173 obj1.setMenuBar((QMenuBar *)0);
174 QVERIFY(obj1.menuBar());
175 //we now call deleteLater on the previous menubar
176 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
177 QVERIFY(!var1);
178 // delete var1; // No delete, since QMainWindow takes ownership
179
180 // QStatusBar * QMainWindow::statusBar()
181 // void QMainWindow::setStatusBar(QStatusBar *)
182 QPointer<QStatusBar> var2 = new QStatusBar;
183 obj1.setStatusBar(var2);
184 QCOMPARE(static_cast<QStatusBar *>(var2), obj1.statusBar());
185 obj1.setStatusBar((QStatusBar *)0);
186 QVERIFY(obj1.statusBar());
187 //we now call deleteLater on the previous menubar
188 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
189 QVERIFY(!var2);
190 // delete var2; // No delete, since QMainWindow takes ownership
191
192 // QWidget * QMainWindow::centralWidget()
193 // void QMainWindow::setCentralWidget(QWidget *)
194 QWidget *var3 = new QWidget;
195 obj1.setCentralWidget(var3);
196 QCOMPARE(var3, obj1.centralWidget());
197 obj1.setCentralWidget((QWidget *)0);
198 QCOMPARE((QWidget *)0, obj1.centralWidget());
199 // delete var3; // No delete, since QMainWindow takes ownership
200
201 QWidget *var4 = new QWidget;
202 QPointer<QWidget> oldcentralwidget(var4);
203 obj1.setCentralWidget(var4);
204 obj1.setCentralWidget(new QWidget);
205 QCoreApplication::sendPostedEvents(receiver: var4, event_type: QEvent::DeferredDelete);
206 QVERIFY(oldcentralwidget.isNull());
207 QVERIFY(obj1.centralWidget()->parent());
208}
209
210tst_QMainWindow::tst_QMainWindow()
211{
212 qRegisterMetaType<Qt::ToolButtonStyle>(typeName: "Qt::ToolButtonStyle");
213}
214
215void tst_QMainWindow::constructor()
216{
217 QMainWindow mw;
218 QVERIFY(!mw.parentWidget());
219 QVERIFY(mw.isWindow());
220
221 QMainWindow mw2(&mw);
222 QCOMPARE(mw2.parentWidget(), &mw);
223 QVERIFY(mw2.isWindow());
224
225 QMainWindow mw3(&mw, Qt::FramelessWindowHint);
226 QCOMPARE(mw3.parentWidget(), &mw);
227 QVERIFY(mw3.isWindow());
228}
229
230void tst_QMainWindow::iconSize()
231{
232 {
233 QMainWindow mw;
234 QSignalSpy spy(&mw, SIGNAL(iconSizeChanged(QSize)));
235
236 // the default is determined by the style
237 const int metric = mw.style()->pixelMetric(metric: QStyle::PM_ToolBarIconSize);
238 const QSize defaultIconSize = QSize(metric, metric);
239 const QSize smallIconSize = QSize(metric / 2, metric / 2);
240 const QSize largeIconSize = QSize(metric * 2, metric * 2);
241
242 // no-op
243 QCOMPARE(mw.iconSize(), defaultIconSize);
244 mw.setIconSize(defaultIconSize);
245 QCOMPARE(mw.iconSize(), defaultIconSize);
246 QCOMPARE(spy.size(), 0);
247
248 mw.setIconSize(largeIconSize);
249 QCOMPARE(mw.iconSize(), largeIconSize);
250 QCOMPARE(spy.size(), 1);
251 QCOMPARE(spy.first().first().toSize(), largeIconSize);
252 spy.clear();
253
254 // no-op
255 QCOMPARE(mw.iconSize(), largeIconSize);
256 mw.setIconSize(largeIconSize);
257 QCOMPARE(mw.iconSize(), largeIconSize);
258 QCOMPARE(spy.size(), 0);
259
260 mw.setIconSize(smallIconSize);
261 QCOMPARE(mw.iconSize(), smallIconSize);
262 QCOMPARE(spy.size(), 1);
263 QCOMPARE(spy.first().first().toSize(), smallIconSize);
264 spy.clear();
265
266 // no-op
267 QCOMPARE(mw.iconSize(), smallIconSize);
268 mw.setIconSize(smallIconSize);
269 QCOMPARE(mw.iconSize(), smallIconSize);
270 QCOMPARE(spy.size(), 0);
271
272 // setting the icon size to an invalid QSize will reset the
273 // iconSize property to the default
274 mw.setIconSize(QSize());
275 QCOMPARE(mw.iconSize(), defaultIconSize);
276 QCOMPARE(spy.size(), 1);
277 QCOMPARE(spy.first().first().toSize(), defaultIconSize);
278 spy.clear();
279 }
280
281 {
282 // toolbars should follow the mainwindow's icon size
283 QMainWindow mw;
284 QToolBar tb;
285 mw.addToolBar(toolbar: &tb);
286
287 QSignalSpy mwSpy(&mw, SIGNAL(iconSizeChanged(QSize)));
288 QSignalSpy tbSpy(&tb, SIGNAL(iconSizeChanged(QSize)));
289
290 // the default is determined by the style
291 const int metric = mw.style()->pixelMetric(metric: QStyle::PM_ToolBarIconSize);
292 const QSize defaultIconSize = QSize(metric, metric);
293 const QSize smallIconSize = QSize(metric / 2, metric / 2);
294 const QSize largeIconSize = QSize(metric * 2, metric * 2);
295
296 // no-op
297 QCOMPARE(mw.iconSize(), defaultIconSize);
298 mw.setIconSize(defaultIconSize);
299 QCOMPARE(mw.iconSize(), defaultIconSize);
300 QCOMPARE(tb.iconSize(), defaultIconSize);
301 QCOMPARE(mwSpy.size(), 0);
302 QCOMPARE(tbSpy.size(), 0);
303
304 mw.setIconSize(largeIconSize);
305 QCOMPARE(mw.iconSize(), largeIconSize);
306 QCOMPARE(tb.iconSize(), largeIconSize);
307 QCOMPARE(mwSpy.size(), 1);
308 QCOMPARE(mwSpy.first().first().toSize(), largeIconSize);
309 QCOMPARE(tbSpy.size(), 1);
310 QCOMPARE(tbSpy.first().first().toSize(), largeIconSize);
311 mwSpy.clear();
312 tbSpy.clear();
313
314 // no-op
315 QCOMPARE(mw.iconSize(), largeIconSize);
316 mw.setIconSize(largeIconSize);
317 QCOMPARE(mw.iconSize(), largeIconSize);
318 QCOMPARE(tb.iconSize(), largeIconSize);
319 QCOMPARE(mwSpy.size(), 0);
320 QCOMPARE(tbSpy.size(), 0);
321
322 mw.setIconSize(smallIconSize);
323 QCOMPARE(mw.iconSize(), smallIconSize);
324 QCOMPARE(tb.iconSize(), smallIconSize);
325 QCOMPARE(mwSpy.size(), 1);
326 QCOMPARE(mwSpy.first().first().toSize(), smallIconSize);
327 QCOMPARE(tbSpy.size(), 1);
328 QCOMPARE(tbSpy.first().first().toSize(), smallIconSize);
329 mwSpy.clear();
330 tbSpy.clear();
331
332 // no-op
333 QCOMPARE(mw.iconSize(), smallIconSize);
334 mw.setIconSize(smallIconSize);
335 QCOMPARE(mw.iconSize(), smallIconSize);
336 QCOMPARE(tb.iconSize(), smallIconSize);
337 QCOMPARE(mwSpy.size(), 0);
338 QCOMPARE(tbSpy.size(), 0);
339
340 // setting the icon size to an invalid QSize will reset the
341 // iconSize property to the default
342 mw.setIconSize(QSize());
343 QCOMPARE(mw.iconSize(), defaultIconSize);
344 QCOMPARE(tb.iconSize(), defaultIconSize);
345 QCOMPARE(mwSpy.size(), 1);
346 QCOMPARE(mwSpy.first().first().toSize(), defaultIconSize);
347 QCOMPARE(tbSpy.size(), 1);
348 QCOMPARE(tbSpy.first().first().toSize(), defaultIconSize);
349 mwSpy.clear();
350 tbSpy.clear();
351 }
352
353 {
354 QMainWindow mw;
355 QSignalSpy mwSpy(&mw, SIGNAL(iconSizeChanged(QSize)));
356
357 // the default is determined by the style
358 const int metric = mw.style()->pixelMetric(metric: QStyle::PM_ToolBarIconSize);
359 const QSize smallIconSize = QSize(metric / 2, metric / 2);
360 const QSize largeIconSize = QSize(metric * 2, metric * 2);
361
362 mw.setIconSize(smallIconSize);
363 QCOMPARE(mw.iconSize(), smallIconSize);
364 QCOMPARE(mwSpy.size(), 1);
365 QCOMPARE(mwSpy.first().first().toSize(), smallIconSize);
366 mwSpy.clear();
367
368 QToolBar tb;
369 QSignalSpy tbSpy(&tb, SIGNAL(iconSizeChanged(QSize)));
370
371 mw.addToolBar(toolbar: &tb);
372
373 // newly added toolbars should also automatically pick up any
374 // size set on the main window
375 QCOMPARE(tb.iconSize(), smallIconSize);
376 QCOMPARE(tbSpy.size(), 1);
377 QCOMPARE(tbSpy.first().first().toSize(), smallIconSize);
378 tbSpy.clear();
379
380 mw.removeToolBar(toolbar: &tb);
381
382 // removed toolbars should keep their existing size and ignore
383 // mainwindow icon size changes
384 mw.setIconSize(largeIconSize);
385 QCOMPARE(mw.iconSize(), largeIconSize);
386 QCOMPARE(tb.iconSize(), smallIconSize);
387 QCOMPARE(mwSpy.size(), 1);
388 QCOMPARE(mwSpy.first().first().toSize(), largeIconSize);
389 QCOMPARE(tbSpy.size(), 0);
390 mwSpy.clear();
391 }
392}
393
394void tst_QMainWindow::toolButtonStyle()
395{
396 {
397 QMainWindow mw;
398
399 QSignalSpy spy(&mw, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)));
400
401 // no-op
402 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
403 mw.setToolButtonStyle(Qt::ToolButtonIconOnly);
404 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
405 QCOMPARE(spy.size(), 0);
406
407 mw.setToolButtonStyle(Qt::ToolButtonTextOnly);
408 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextOnly);
409 QCOMPARE(spy.size(), 1);
410 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(spy.first().first().constData()),
411 Qt::ToolButtonTextOnly);
412 spy.clear();
413
414 // no-op
415 mw.setToolButtonStyle(Qt::ToolButtonTextOnly);
416 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextOnly);
417 QCOMPARE(spy.size(), 0);
418
419 mw.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
420 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
421 QCOMPARE(spy.size(), 1);
422 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(spy.first().first().constData()),
423 Qt::ToolButtonTextBesideIcon);
424 spy.clear();
425
426 // no-op
427 mw.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
428 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
429 QCOMPARE(spy.size(), 0);
430
431 mw.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
432 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
433 QCOMPARE(spy.size(), 1);
434 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(spy.first().first().constData()),
435 Qt::ToolButtonTextUnderIcon);
436 spy.clear();
437
438 // no-op
439 mw.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
440 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
441 QCOMPARE(spy.size(), 0);
442
443 mw.setToolButtonStyle(Qt::ToolButtonIconOnly);
444 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
445 QCOMPARE(spy.size(), 1);
446 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(spy.first().first().constData()),
447 Qt::ToolButtonIconOnly);
448 spy.clear();
449
450 // no-op
451 mw.setToolButtonStyle(Qt::ToolButtonIconOnly);
452 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
453 QCOMPARE(spy.size(), 0);
454 }
455
456 {
457 // toolbars should follow the mainwindow's tool button style
458 QMainWindow mw;
459 QToolBar tb;
460 mw.addToolBar(toolbar: &tb);
461
462 QSignalSpy mwSpy(&mw, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)));
463 QSignalSpy tbSpy(&tb, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)));
464
465 // no-op
466 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
467 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
468 mw.setToolButtonStyle(Qt::ToolButtonIconOnly);
469 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
470 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
471 QCOMPARE(mwSpy.size(), 0);
472 QCOMPARE(tbSpy.size(), 0);
473
474 mw.setToolButtonStyle(Qt::ToolButtonTextOnly);
475 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextOnly);
476 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextOnly);
477 QCOMPARE(mwSpy.size(), 1);
478 QCOMPARE(tbSpy.size(), 1);
479 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(mwSpy.first().first().constData()),
480 Qt::ToolButtonTextOnly);
481 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(tbSpy.first().first().constData()),
482 Qt::ToolButtonTextOnly);
483 mwSpy.clear();
484 tbSpy.clear();
485
486 // no-op
487 mw.setToolButtonStyle(Qt::ToolButtonTextOnly);
488 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextOnly);
489 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextOnly);
490 QCOMPARE(mwSpy.size(), 0);
491 QCOMPARE(tbSpy.size(), 0);
492
493 mw.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
494 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
495 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
496 QCOMPARE(mwSpy.size(), 1);
497 QCOMPARE(tbSpy.size(), 1);
498 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(mwSpy.first().first().constData()),
499 Qt::ToolButtonTextBesideIcon);
500 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(tbSpy.first().first().constData()),
501 Qt::ToolButtonTextBesideIcon);
502 mwSpy.clear();
503 tbSpy.clear();
504
505 // no-op
506 mw.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
507 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
508 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
509 QCOMPARE(mwSpy.size(), 0);
510 QCOMPARE(tbSpy.size(), 0);
511
512 mw.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
513 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
514 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
515 QCOMPARE(mwSpy.size(), 1);
516 QCOMPARE(tbSpy.size(), 1);
517 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(mwSpy.first().first().constData()),
518 Qt::ToolButtonTextUnderIcon);
519 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(tbSpy.first().first().constData()),
520 Qt::ToolButtonTextUnderIcon);
521 mwSpy.clear();
522 tbSpy.clear();
523
524 // no-op
525 mw.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
526 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
527 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
528 QCOMPARE(mwSpy.size(), 0);
529 QCOMPARE(tbSpy.size(), 0);
530
531 mw.setToolButtonStyle(Qt::ToolButtonIconOnly);
532 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
533 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
534 QCOMPARE(mwSpy.size(), 1);
535 QCOMPARE(tbSpy.size(), 1);
536 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(mwSpy.first().first().constData()),
537 Qt::ToolButtonIconOnly);
538 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(tbSpy.first().first().constData()),
539 Qt::ToolButtonIconOnly);
540 mwSpy.clear();
541 tbSpy.clear();
542
543 // no-op
544 mw.setToolButtonStyle(Qt::ToolButtonIconOnly);
545 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonIconOnly);
546 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonIconOnly);
547 QCOMPARE(mwSpy.size(), 0);
548 QCOMPARE(tbSpy.size(), 0);
549 }
550
551 {
552 QMainWindow mw;
553 QSignalSpy mwSpy(&mw, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)));
554
555 mw.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
556 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
557 QCOMPARE(mwSpy.size(), 1);
558 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(mwSpy.first().first().constData()),
559 Qt::ToolButtonTextBesideIcon);
560 mwSpy.clear();
561
562 QToolBar tb;
563 QSignalSpy tbSpy(&tb, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)));
564
565 mw.addToolBar(toolbar: &tb);
566
567 // newly added toolbars should also automatically pick up any
568 // size set on the main window
569 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
570 QCOMPARE(tbSpy.size(), 1);
571 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(tbSpy.first().first().constData()),
572 Qt::ToolButtonTextBesideIcon);
573 tbSpy.clear();
574
575 mw.removeToolBar(toolbar: &tb);
576
577 // removed toolbars should keep their existing size and ignore
578 // mainwindow icon size changes
579 mw.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
580 QCOMPARE(mw.toolButtonStyle(), Qt::ToolButtonTextUnderIcon);
581 QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextBesideIcon);
582 QCOMPARE(mwSpy.size(), 1);
583 QCOMPARE(*static_cast<const Qt::ToolButtonStyle *>(mwSpy.first().first().constData()),
584 Qt::ToolButtonTextUnderIcon);
585 QCOMPARE(tbSpy.size(), 0);
586 mwSpy.clear();
587 }
588}
589
590void tst_QMainWindow::menuBar()
591{
592 {
593 QMainWindow mw;
594 QVERIFY(mw.menuBar() != 0);
595 }
596
597 {
598 QMainWindow mw;
599 QPointer<QMenuBar> mb1 = new QMenuBar;
600 QPointer<QMenuBar> mb2 = new QMenuBar;
601
602 mw.setMenuBar(mb1);
603 QVERIFY(mw.menuBar() != 0);
604 QCOMPARE(mw.menuBar(), (QMenuBar *)mb1);
605 QCOMPARE(mb1->parentWidget(), (QWidget *)&mw);
606
607 mw.setMenuBar(0);
608 QVERIFY(mw.menuBar() != 0);
609 //we now call deleteLater on the previous menubar
610 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
611 QVERIFY(mb1.isNull());
612
613 mw.setMenuBar(mb2);
614 QVERIFY(mw.menuBar() != 0);
615 QCOMPARE(mw.menuBar(), (QMenuBar *)mb2);
616 QCOMPARE(mb2->parentWidget(), (QWidget *)&mw);
617
618 mw.setMenuBar(0);
619 QVERIFY(mw.menuBar() != 0);
620 //we now call deleteLater on the previous menubar
621 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
622 QVERIFY(mb2.isNull());
623
624 mb1 = new QMenuBar;
625 mw.setMenuBar(mb1);
626 QVERIFY(mw.menuBar() != 0);
627 QCOMPARE(mw.menuBar(), (QMenuBar *)mb1);
628
629 mb2 = new QMenuBar;
630 mw.setMenuBar(mb2);
631 QVERIFY(mw.menuBar() != 0);
632 QCOMPARE(mw.menuBar(), (QMenuBar *)mb2);
633 //we now call deleteLater on the previous menubar
634 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
635 QVERIFY(mb1.isNull());
636
637 mb1 = new QMenuBar;
638 mw.setMenuBar(mb1);
639 QVERIFY(mw.menuBar() != 0);
640 QCOMPARE(mw.menuBar(), (QMenuBar *)mb1);
641 //we now call deleteLater on the previous menubar
642 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
643 QVERIFY(mb2.isNull());
644
645 QPointer<QWidget> topLeftCornerWidget = new QWidget;
646 mb1->setCornerWidget(w: topLeftCornerWidget, corner: Qt::TopLeftCorner);
647 QPointer<QWidget> topRightCornerWidget = new QWidget;
648 mb1->setCornerWidget(w: topRightCornerWidget, corner: Qt::TopRightCorner);
649
650 mb2 = new QMenuBar;
651 mw.setMenuBar(mb2);
652 QVERIFY(mw.menuBar() != 0);
653 QCOMPARE(mw.menuBar(), (QMenuBar *)mb2);
654 //we now call deleteLater on the previous menubar
655 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
656 QVERIFY(mb1.isNull());
657
658 QVERIFY(topLeftCornerWidget);
659 QCOMPARE(mb2->cornerWidget(Qt::TopLeftCorner), static_cast<QWidget *>(topLeftCornerWidget));
660 QVERIFY(topRightCornerWidget);
661 QCOMPARE(mb2->cornerWidget(Qt::TopRightCorner), static_cast<QWidget *>(topRightCornerWidget));
662
663 mw.setMenuBar(0);
664 QVERIFY(mw.menuBar() != 0);
665 //we now call deleteLater on the previous menubar
666 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
667
668 QVERIFY(mb2.isNull());
669 QVERIFY(!topLeftCornerWidget);
670 QVERIFY(!topRightCornerWidget);
671 }
672}
673
674#ifdef QT_BUILD_INTERNAL
675void tst_QMainWindow::statusBar()
676{
677 {
678 QMainWindow mw;
679 QVERIFY(mw.statusBar() != 0);
680 }
681
682 {
683 QMainWindow mw;
684 QPointer<QStatusBar> sb1 = new QStatusBar;
685 QPointer<QStatusBar> sb2 = new QStatusBar;
686
687 mw.setStatusBar(sb1);
688 QVERIFY(mw.statusBar() != 0);
689 QCOMPARE(mw.statusBar(), (QStatusBar *)sb1);
690 QCOMPARE(sb1->parentWidget(), (QWidget *)&mw);
691
692 mw.setStatusBar(0);
693 QVERIFY(mw.statusBar() != 0);
694 //we now call deleteLater on the previous statusbar
695 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
696 QVERIFY(sb1.isNull());
697
698 mw.setStatusBar(sb2);
699 QVERIFY(mw.statusBar() != 0);
700 QCOMPARE(mw.statusBar(), (QStatusBar *)sb2);
701 QCOMPARE(sb2->parentWidget(), (QWidget *)&mw);
702
703 mw.setStatusBar(0);
704 QVERIFY(mw.statusBar() != 0);
705 //we now call deleteLater on the previous statusbar
706 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
707 QVERIFY(sb2.isNull());
708
709 sb1 = new QStatusBar;
710 mw.setStatusBar(sb1);
711 QVERIFY(mw.statusBar() != 0);
712 QCOMPARE(mw.statusBar(), (QStatusBar *)sb1);
713 QCOMPARE(sb1->parentWidget(), (QWidget *)&mw);
714
715 sb2 = new QStatusBar;
716 mw.setStatusBar(sb2);
717 QVERIFY(mw.statusBar() != 0);
718 QCOMPARE(mw.statusBar(), (QStatusBar *)sb2);
719 QCOMPARE(sb2->parentWidget(), (QWidget *)&mw);
720 //we now call deleteLater on the previous statusbar
721 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
722 QVERIFY(sb1.isNull());
723
724 sb1 = new QStatusBar;
725 mw.setStatusBar(sb1);
726 QVERIFY(mw.statusBar() != 0);
727 QCOMPARE(mw.statusBar(), (QStatusBar *)sb1);
728 QCOMPARE(sb1->parentWidget(), (QWidget *)&mw);
729 //we now call deleteLater on the previous statusbar
730 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
731 QVERIFY(sb2.isNull());
732
733 sb2 = new QStatusBar;
734 mw.setStatusBar(sb2);
735 QVERIFY(mw.statusBar() != 0);
736 QCOMPARE(mw.statusBar(), (QStatusBar *)sb2);
737 QCOMPARE(sb2->parentWidget(), (QWidget *)&mw);
738 //we now call deleteLater on the previous statusbar
739 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
740 QVERIFY(sb1.isNull());
741 }
742
743 {
744 // deleting the status bar should remove it from the main window
745 QMainWindow mw;
746 QStatusBar *sb = mw.statusBar();
747 QMainWindowLayout *l = mw.findChild<QMainWindowLayout *>();
748 QVERIFY(l);
749 int indexOfSb = l->indexOf(sb);
750 QVERIFY(indexOfSb != -1);
751 delete sb;
752 indexOfSb = l->indexOf(sb);
753 QCOMPARE(indexOfSb, -1);
754 }
755}
756
757#endif
758
759void tst_QMainWindow::contentsMargins_data()
760{
761 QTest::addColumn<int>(name: "contentsMargin");
762 QTest::newRow(dataTag: "0") << 0;
763 QTest::newRow(dataTag: "10") << 10;
764}
765
766void tst_QMainWindow::contentsMargins()
767{
768 QFETCH(int, contentsMargin);
769
770 QMainWindow mw;
771 const QRect availGeometry = QGuiApplication::primaryScreen()->availableGeometry();
772 mw.menuBar()->addMenu(title: "File");
773 mw.setWindowTitle(QLatin1String(QTest::currentTestFunction())
774 + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag()));
775 mw.resize(availGeometry.size() / 4);
776 mw.move(ax: (availGeometry.width() - mw.width()) / 2,
777 ay: (availGeometry.height() - mw.height()) / 2);
778 mw.setContentsMargins(left: contentsMargin, top: contentsMargin, right: contentsMargin, bottom: contentsMargin);
779 mw.statusBar()->showMessage(text: "Hello");
780
781 mw.show();
782 QVERIFY(QTest::qWaitForWindowExposed(&mw));
783
784 QCOMPARE(mw.menuBar()->geometry().left(), contentsMargin);
785 QCOMPARE(mw.menuBar()->geometry().top(), contentsMargin);
786
787 QCOMPARE(mw.statusBar()->geometry().left(), contentsMargin);
788 QCOMPARE(mw.statusBar()->geometry().bottom() + 1, mw.height() - contentsMargin);
789}
790
791void tst_QMainWindow::centralWidget()
792{
793 {
794 QMainWindow mw;
795 QVERIFY(!mw.centralWidget());
796 }
797
798 {
799 QMainWindow mw;
800 QPointer<QWidget> w1 = new QWidget;
801 QPointer<QWidget> w2 = new QWidget;
802
803 QVERIFY(!mw.centralWidget());
804
805 mw.setCentralWidget(w1);
806 QVERIFY(mw.centralWidget() != 0);
807 QCOMPARE(mw.centralWidget(), (QWidget *)w1);
808 QCOMPARE(w1->parentWidget(), (QWidget *)&mw);
809
810 mw.setCentralWidget(w2);
811 QVERIFY(mw.centralWidget() != 0);
812 QCOMPARE(mw.centralWidget(), (QWidget *)w2);
813 QCOMPARE(w2->parentWidget(), (QWidget *)&mw);
814
815 mw.setCentralWidget(0);
816 QVERIFY(!mw.centralWidget());
817
818 //we now call deleteLater on the previous central widgets
819 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
820 QVERIFY(w1.isNull());
821 QVERIFY(w2.isNull());
822 }
823
824 {
825 // do it again, this time with the mainwindow shown, since
826 // this tends will activate the layout when setting the new
827 // central widget
828
829 QMainWindow mw;
830 mw.show();
831
832 QPointer<QWidget> w1 = new QWidget;
833 QPointer<QWidget> w2 = new QWidget;
834
835 QVERIFY(!mw.centralWidget());
836
837 mw.setCentralWidget(w1);
838 QVERIFY(mw.centralWidget() != 0);
839 QCOMPARE(mw.centralWidget(), (QWidget *)w1);
840 QCOMPARE(w1->parentWidget(), (QWidget *)&mw);
841
842 mw.setCentralWidget(w2);
843 QVERIFY(mw.centralWidget() != 0);
844 QCOMPARE(mw.centralWidget(), (QWidget *)w2);
845 QCOMPARE(w2->parentWidget(), (QWidget *)&mw);
846
847 mw.setCentralWidget(0);
848 QVERIFY(!mw.centralWidget());
849
850 //we now call deleteLater on the previous central widgets
851 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
852 QVERIFY(w1.isNull());
853 QVERIFY(w2.isNull());
854 }
855
856}
857
858void tst_QMainWindow::takeCentralWidget() {
859 // test if takeCentralWidget works
860 QMainWindow mw;
861
862 QPointer<QWidget> w1 = new QWidget;
863
864 QVERIFY(!mw.centralWidget());
865
866 // verify that we don't crash when trying to take a non-set
867 // central widget but just return a null pointer instead
868 QVERIFY(!mw.takeCentralWidget());
869
870 mw.setCentralWidget(w1);
871
872 QWidget *oldCentralWidget = mw.takeCentralWidget();
873 QCOMPARE(oldCentralWidget, w1.data());
874
875 // ensure that takeCentralWidget doesn't end up calling deleteLater
876 // on the central widget
877 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
878 QVERIFY(!mw.centralWidget());
879 QVERIFY(!w1.isNull());
880 QVERIFY(!w1->parent());
881
882 mw.setCentralWidget(w1);
883 // ensure that the deleteLater called by setCentralWidget
884 // gets executed
885 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
886 QCOMPARE(mw.centralWidget(), w1.data());
887
888 QPointer<QWidget> w2 = new QWidget;
889
890 mw.setCentralWidget(w2);
891 // ensure w2 gets deleted
892 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
893 QVERIFY(w1.isNull());
894
895 QCOMPARE(mw.centralWidget(), w2.data());
896
897 QWidget *hopefullyW2 = mw.takeCentralWidget();
898 QVERIFY(!mw.centralWidget());
899 // ensure that takeCentralWidget doesn't end up calling deleteLater
900 // on the central widget
901 QCoreApplication::sendPostedEvents(receiver: 0, event_type: QEvent::DeferredDelete);
902
903 QVERIFY(!w2.isNull());
904 QCOMPARE(w2.data(), hopefullyW2);
905 delete w2;
906}
907
908void tst_QMainWindow::corner()
909{
910 {
911 QMainWindow mw;
912
913 QCOMPARE(mw.corner(Qt::TopLeftCorner), Qt::TopDockWidgetArea);
914 QCOMPARE(mw.corner(Qt::TopRightCorner), Qt::TopDockWidgetArea);
915 QCOMPARE(mw.corner(Qt::BottomLeftCorner), Qt::BottomDockWidgetArea);
916 QCOMPARE(mw.corner(Qt::BottomRightCorner), Qt::BottomDockWidgetArea);
917 }
918
919 {
920 QMainWindow mw;
921
922 mw.setCorner(corner: Qt::TopLeftCorner, area: Qt::LeftDockWidgetArea);
923 QCOMPARE(mw.corner(Qt::TopLeftCorner), Qt::LeftDockWidgetArea);
924 mw.setCorner(corner: Qt::TopLeftCorner, area: Qt::TopDockWidgetArea);
925 QCOMPARE(mw.corner(Qt::TopLeftCorner), Qt::TopDockWidgetArea);
926
927 mw.setCorner(corner: Qt::TopRightCorner, area: Qt::RightDockWidgetArea);
928 QCOMPARE(mw.corner(Qt::TopRightCorner), Qt::RightDockWidgetArea);
929 mw.setCorner(corner: Qt::TopRightCorner, area: Qt::TopDockWidgetArea);
930 QCOMPARE(mw.corner(Qt::TopRightCorner), Qt::TopDockWidgetArea);
931
932 mw.setCorner(corner: Qt::BottomLeftCorner, area: Qt::LeftDockWidgetArea);
933 QCOMPARE(mw.corner(Qt::BottomLeftCorner), Qt::LeftDockWidgetArea);
934 mw.setCorner(corner: Qt::BottomLeftCorner, area: Qt::BottomDockWidgetArea);
935 QCOMPARE(mw.corner(Qt::BottomLeftCorner), Qt::BottomDockWidgetArea);
936
937 mw.setCorner(corner: Qt::BottomRightCorner, area: Qt::RightDockWidgetArea);
938 QCOMPARE(mw.corner(Qt::BottomRightCorner), Qt::RightDockWidgetArea);
939 mw.setCorner(corner: Qt::BottomRightCorner, area: Qt::BottomDockWidgetArea);
940 QCOMPARE(mw.corner(Qt::BottomRightCorner), Qt::BottomDockWidgetArea);
941 }
942}
943
944void tst_QMainWindow::addToolBarBreak()
945{
946 {
947 QMainWindow mw;
948 QToolBar tb1(&mw);
949 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb1);
950 mw.addToolBarBreak(area: Qt::TopToolBarArea);
951 QToolBar tb2(&mw);
952 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb2);
953 mw.addToolBarBreak(area: Qt::TopToolBarArea);
954 QToolBar tb3(&mw);
955 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb3);
956 mw.addToolBarBreak(area: Qt::TopToolBarArea);
957 QToolBar tb4(&mw);
958 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb4);
959
960 mw.layout()->invalidate();
961 mw.layout()->activate();
962
963 QCOMPARE(tb1.x(), 0);
964 QCOMPARE(tb1.y(), 0);
965 QCOMPARE(tb2.x(), 0);
966 QVERIFY(tb1.y() != tb2.y());
967 QCOMPARE(tb3.x(), 0);
968 QVERIFY(tb2.y() != tb3.y());
969 QCOMPARE(tb4.x(), 0);
970 QVERIFY(tb3.y() != tb4.y());
971 }
972
973 {
974 QMainWindow mw;
975 // should not crash, should get a warning instead
976 QTest::ignoreMessage(type: QtWarningMsg, message: "QMainWindow::addToolBarBreak: invalid 'area' argument");
977 mw.addToolBarBreak(area: Qt::NoToolBarArea);
978 }
979}
980
981void tst_QMainWindow::insertToolBarBreak()
982{
983 QMainWindow mw;
984 QToolBar tb1(&mw);
985 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb1);
986 QToolBar tb2(&mw);
987 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb2);
988 QToolBar tb3(&mw);
989 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb3);
990 QToolBar tb4(&mw);
991 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb4);
992
993 mw.insertToolBarBreak(before: &tb2);
994 mw.insertToolBarBreak(before: &tb3);
995 mw.insertToolBarBreak(before: &tb4);
996
997 mw.layout()->invalidate();
998 mw.layout()->activate();
999
1000 QCOMPARE(tb1.x(), 0);
1001 QCOMPARE(tb1.y(), 0);
1002 QCOMPARE(tb2.x(), 0);
1003 QVERIFY(tb1.y() != tb2.y());
1004 QCOMPARE(tb3.x(), 0);
1005 QVERIFY(tb2.y() != tb3.y());
1006 QCOMPARE(tb4.x(), 0);
1007 QVERIFY(tb3.y() != tb4.y());
1008
1009 QVERIFY(!mw.toolBarBreak(&tb1));
1010 QVERIFY(mw.toolBarBreak(&tb4));
1011 mw.removeToolBarBreak(before: &tb4);
1012 QVERIFY(!mw.toolBarBreak(&tb4));
1013
1014}
1015
1016static bool findWidgetRecursively(QLayoutItem *li, QWidget *w)
1017{
1018 QLayout *lay = li->layout();
1019 if (!lay)
1020 return false;
1021 int i = 0;
1022 QLayoutItem *child;
1023 while ((child = lay->itemAt(index: i))) {
1024 if (child->widget() == w) {
1025 return true;
1026 } else if (findWidgetRecursively(li: child, w)) {
1027 return true;
1028 } else {
1029 ++i;
1030 }
1031 }
1032 return false;
1033}
1034
1035void tst_QMainWindow::addToolBar()
1036{
1037 Qt::ToolBarArea areas[] = {
1038 Qt::LeftToolBarArea,
1039 Qt::RightToolBarArea,
1040 Qt::TopToolBarArea,
1041 Qt::BottomToolBarArea
1042 };
1043 const int areaCount = sizeof(areas) / sizeof(Qt::ToolBarArea);
1044
1045 for (int i = 0; i < areaCount; ++i) {
1046 Qt::ToolBarArea area = areas[i];
1047
1048 QMainWindow mw;
1049 QToolBar tb(&mw);
1050 QVERIFY(!findWidgetRecursively(mw.layout(), &tb));
1051 mw.addToolBar(area, toolbar: &tb);
1052 QVERIFY(findWidgetRecursively(mw.layout(), &tb));
1053 }
1054
1055 {
1056 // addToolBar() with no area, equivalent to top
1057 QMainWindow mw;
1058 QToolBar tb(&mw);
1059 QVERIFY(!findWidgetRecursively(mw.layout(), &tb));
1060 mw.addToolBar(toolbar: &tb);
1061 QVERIFY(findWidgetRecursively(mw.layout(), &tb));
1062 }
1063
1064 {
1065 QMainWindow mw;
1066 QToolBar tb(&mw);
1067 // should not crash, should get a warning instead
1068 QTest::ignoreMessage(type: QtWarningMsg, message: "QMainWindow::addToolBar: invalid 'area' argument");
1069 mw.addToolBar(area: Qt::NoToolBarArea, toolbar: &tb);
1070 }
1071}
1072
1073void tst_QMainWindow::insertToolBar()
1074{
1075 Qt::ToolBarArea areas[] = {
1076 Qt::LeftToolBarArea,
1077 Qt::RightToolBarArea,
1078 Qt::TopToolBarArea,
1079 Qt::BottomToolBarArea
1080 };
1081 const int areaCount = sizeof(areas) / sizeof(Qt::ToolBarArea);
1082
1083 for (int i = 0; i < areaCount; ++i) {
1084 Qt::ToolBarArea area = areas[i];
1085
1086 QMainWindow mw;
1087 QToolBar tb1(&mw);
1088 mw.addToolBar(area, toolbar: &tb1);
1089 QToolBar tb2(&mw);
1090 mw.insertToolBar(before: &tb1, toolbar: &tb2);
1091 QVERIFY(findWidgetRecursively(mw.layout(), &tb1));
1092 QVERIFY(findWidgetRecursively(mw.layout(), &tb2));
1093 }
1094
1095 {
1096 QMainWindow window;
1097 QToolBar *bar1 = new QToolBar(QObject::tr(s: "bar1"), &window);
1098 bar1->addWidget(widget: new QPushButton(QObject::tr(s: "bar1")));
1099 QToolBar *bar2 = new QToolBar(QLatin1String("bar2"));
1100 bar2->addWidget(widget: new QPushButton(QLatin1String("bar2")));
1101 QToolBar *bar3 = new QToolBar(QLatin1String("bar3"));
1102 bar3->addWidget(widget: new QPushButton(QLatin1String("bar3")));
1103
1104 window.addToolBar(toolbar: bar1);
1105 window.addToolBar(toolbar: bar3);
1106 window.insertToolBar(before: bar1,toolbar: bar2);
1107 window.insertToolBar(before: bar1, toolbar: bar3);
1108
1109 QVERIFY(!window.isVisible());
1110 QVERIFY(!bar1->isVisible());
1111 QVERIFY(!bar2->isVisible());
1112 QVERIFY(!bar3->isVisible());
1113
1114 window.show();
1115
1116 QVERIFY(window.isVisible());
1117 QVERIFY(bar1->isVisible());
1118 QVERIFY(bar2->isVisible());
1119 QVERIFY(bar3->isVisible());
1120 }
1121}
1122
1123void tst_QMainWindow::removeToolBar()
1124{
1125 Qt::ToolBarArea areas[] = {
1126 Qt::LeftToolBarArea,
1127 Qt::RightToolBarArea,
1128 Qt::TopToolBarArea,
1129 Qt::BottomToolBarArea
1130 };
1131 const int areaCount = sizeof(areas) / sizeof(Qt::ToolBarArea);
1132
1133 for (int i = 0; i < areaCount; ++i) {
1134 Qt::ToolBarArea area = areas[i];
1135
1136 QMainWindow mw;
1137 QToolBar tb1(&mw);
1138 mw.addToolBar(area, toolbar: &tb1);
1139 QToolBar tb2(&mw);
1140 mw.insertToolBar(before: &tb1, toolbar: &tb2);
1141 QVERIFY(findWidgetRecursively(mw.layout(), &tb1));
1142 QVERIFY(findWidgetRecursively(mw.layout(), &tb2));
1143
1144 mw.removeToolBar(toolbar: &tb1);
1145 QVERIFY(!findWidgetRecursively(mw.layout(), &tb1));
1146 QVERIFY(findWidgetRecursively(mw.layout(), &tb2));
1147
1148 mw.removeToolBar(toolbar: &tb2);
1149 QVERIFY(!findWidgetRecursively(mw.layout(), &tb1));
1150 QVERIFY(!findWidgetRecursively(mw.layout(), &tb2));
1151 }
1152}
1153
1154void tst_QMainWindow::toolBarArea()
1155{
1156 Qt::ToolBarArea areas[] = {
1157 Qt::LeftToolBarArea,
1158 Qt::RightToolBarArea,
1159 Qt::TopToolBarArea,
1160 Qt::BottomToolBarArea
1161 };
1162 const int areaCount = sizeof(areas) / sizeof(Qt::ToolBarArea);
1163
1164 for (int i = 0; i < areaCount; ++i) {
1165 Qt::ToolBarArea area = areas[i];
1166
1167 QMainWindow mw;
1168 QToolBar tb(&mw);
1169
1170 for (int j = 0; j < areaCount; ++j) {
1171 Qt::ToolBarArea otherArea = areas[j];
1172
1173 mw.addToolBar(area, toolbar: &tb);
1174 QCOMPARE(mw.toolBarArea(&tb), area);
1175 mw.addToolBar(area: otherArea, toolbar: &tb);
1176 QCOMPARE(mw.toolBarArea(&tb), otherArea);
1177 }
1178 }
1179
1180 {
1181 // addToolBar() with no area, equivalent to top
1182 QMainWindow mw;
1183 QToolBar tb(&mw);
1184
1185 for (int j = 0; j < areaCount; ++j) {
1186 Qt::ToolBarArea otherArea = areas[j];
1187
1188 mw.addToolBar(toolbar: &tb);
1189 QCOMPARE(mw.toolBarArea(&tb), Qt::TopToolBarArea);
1190 mw.addToolBar(area: otherArea, toolbar: &tb);
1191 QCOMPARE(mw.toolBarArea(&tb), otherArea);
1192 }
1193 }
1194}
1195
1196void tst_QMainWindow::addDockWidget()
1197{
1198 Qt::DockWidgetArea areas[] = {
1199 Qt::LeftDockWidgetArea,
1200 Qt::RightDockWidgetArea,
1201 Qt::TopDockWidgetArea,
1202 Qt::BottomDockWidgetArea
1203 };
1204 const int areaCount = sizeof(areas) / sizeof(Qt::DockWidgetArea);
1205
1206 for (int i = 0; i < areaCount; ++i) {
1207 Qt::DockWidgetArea area = areas[i];
1208
1209 QMainWindow mw;
1210 QDockWidget dw(&mw);
1211 QVERIFY(!findWidgetRecursively(mw.layout(), &dw));
1212 mw.addDockWidget(area, dockwidget: &dw);
1213 QVERIFY(findWidgetRecursively(mw.layout(), &dw));
1214 }
1215
1216 for (int i = 0; i < areaCount; ++i) {
1217 Qt::DockWidgetArea area = areas[i];
1218
1219 {
1220 QMainWindow mw;
1221 QDockWidget dw(&mw);
1222 QVERIFY(!findWidgetRecursively(mw.layout(), &dw));
1223 mw.addDockWidget(area, dockwidget: &dw, orientation: Qt::Horizontal);
1224 QVERIFY(findWidgetRecursively(mw.layout(), &dw));
1225 }
1226
1227 {
1228 QMainWindow mw;
1229 QDockWidget dw(&mw);
1230 QVERIFY(!findWidgetRecursively(mw.layout(), &dw));
1231 mw.addDockWidget(area, dockwidget: &dw, orientation: Qt::Vertical);
1232 QVERIFY(findWidgetRecursively(mw.layout(), &dw));
1233 }
1234 }
1235
1236 {
1237 QMainWindow mw;
1238 QDockWidget dw(&mw);
1239 // should not crash, should get a warning instead
1240 QTest::ignoreMessage(type: QtWarningMsg, message: "QMainWindow::addDockWidget: invalid 'area' argument");
1241 mw.addDockWidget(area: Qt::NoDockWidgetArea, dockwidget: &dw);
1242 }
1243}
1244
1245void tst_QMainWindow::splitDockWidget()
1246{
1247 Qt::DockWidgetArea areas[] = {
1248 Qt::LeftDockWidgetArea,
1249 Qt::RightDockWidgetArea,
1250 Qt::TopDockWidgetArea,
1251 Qt::BottomDockWidgetArea
1252 };
1253 const int areaCount = sizeof(areas) / sizeof(Qt::DockWidgetArea);
1254
1255 for (int i = 0; i < areaCount; ++i) {
1256 Qt::DockWidgetArea area = areas[i];
1257
1258 {
1259 QMainWindow mw;
1260 QDockWidget dw1(&mw);
1261 QVERIFY(!findWidgetRecursively(mw.layout(), &dw1));
1262 mw.addDockWidget(area, dockwidget: &dw1);
1263 QVERIFY(findWidgetRecursively(mw.layout(), &dw1));
1264 QDockWidget dw2(&mw);
1265 QVERIFY(!findWidgetRecursively(mw.layout(), &dw2));
1266 mw.splitDockWidget(after: &dw1, dockwidget: &dw2, orientation: Qt::Horizontal);
1267 QVERIFY(findWidgetRecursively(mw.layout(), &dw2));
1268 }
1269
1270 {
1271 QMainWindow mw;
1272 QDockWidget dw1(&mw);
1273 QVERIFY(!findWidgetRecursively(mw.layout(), &dw1));
1274 mw.addDockWidget(area, dockwidget: &dw1);
1275 QVERIFY(findWidgetRecursively(mw.layout(), &dw1));
1276 QDockWidget dw2(&mw);
1277 QVERIFY(!findWidgetRecursively(mw.layout(), &dw2));
1278 mw.splitDockWidget(after: &dw1, dockwidget: &dw2, orientation: Qt::Horizontal);
1279 QVERIFY(findWidgetRecursively(mw.layout(), &dw2));
1280 }
1281 }
1282}
1283
1284void tst_QMainWindow::removeDockWidget()
1285{
1286 Qt::DockWidgetArea areas[] = {
1287 Qt::LeftDockWidgetArea,
1288 Qt::RightDockWidgetArea,
1289 Qt::TopDockWidgetArea,
1290 Qt::BottomDockWidgetArea
1291 };
1292 const int areaCount = sizeof(areas) / sizeof(Qt::DockWidgetArea);
1293
1294 for (int i = 0; i < areaCount; ++i) {
1295 Qt::DockWidgetArea area = areas[i];
1296
1297 QMainWindow mw;
1298 QDockWidget dw1(&mw);
1299 mw.addDockWidget(area, dockwidget: &dw1);
1300 QDockWidget dw2(&mw);
1301 mw.addDockWidget(area, dockwidget: &dw2);
1302 QVERIFY(findWidgetRecursively(mw.layout(), &dw1));
1303 QVERIFY(findWidgetRecursively(mw.layout(), &dw2));
1304
1305 mw.removeDockWidget(dockwidget: &dw1);
1306 QVERIFY(!findWidgetRecursively(mw.layout(), &dw1));
1307 QVERIFY(findWidgetRecursively(mw.layout(), &dw2));
1308
1309 mw.removeDockWidget(dockwidget: &dw2);
1310 QVERIFY(!findWidgetRecursively(mw.layout(), &dw1));
1311 QVERIFY(!findWidgetRecursively(mw.layout(), &dw2));
1312 }
1313}
1314
1315void tst_QMainWindow::dockWidgetArea()
1316{
1317 Qt::DockWidgetArea areas[] = {
1318 Qt::LeftDockWidgetArea,
1319 Qt::RightDockWidgetArea,
1320 Qt::TopDockWidgetArea,
1321 Qt::BottomDockWidgetArea
1322 };
1323 const int areaCount = sizeof(areas) / sizeof(Qt::DockWidgetArea);
1324
1325 for (int i = 0; i < areaCount; ++i) {
1326 Qt::DockWidgetArea area = areas[i];
1327
1328 QMainWindow mw;
1329 QDockWidget dw(&mw);
1330
1331 for (int j = 0; j < areaCount; ++j) {
1332 Qt::DockWidgetArea otherArea = areas[i];
1333
1334 mw.addDockWidget(area, dockwidget: &dw);
1335 QCOMPARE(mw.dockWidgetArea(&dw), area);
1336 mw.addDockWidget(area: otherArea, dockwidget: &dw);
1337 QCOMPARE(mw.dockWidgetArea(&dw), otherArea);
1338 }
1339 }
1340}
1341
1342void tst_QMainWindow::restoreState()
1343{
1344 QMainWindow mw;
1345 QToolBar tb(&mw);
1346 tb.setObjectName(QLatin1String("toolBar"));
1347 mw.addToolBar(area: Qt::TopToolBarArea, toolbar: &tb);
1348 QDockWidget dw(&mw);
1349 dw.setObjectName(QLatin1String("dock"));
1350 mw.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: &dw);
1351
1352 QByteArray state;
1353
1354 state = mw.saveState();
1355 QVERIFY(mw.restoreState(state));
1356
1357 state = mw.saveState(version: 1);
1358 QVERIFY(!mw.restoreState(state));
1359 QVERIFY(mw.restoreState(state, 1));
1360}
1361
1362//tests the restoration of the previous versions of window settings
1363void tst_QMainWindow::restoreStateFromPreviousVersion()
1364{
1365 QList<QByteArray> restoreData;
1366 restoreData << QByteArray((char*)restoreData41, sizeof(restoreData41))
1367 << QByteArray((char*)restoreData42, sizeof(restoreData42))
1368 << QByteArray((char*)restoreData43, sizeof(restoreData43));
1369
1370 foreach(QByteArray ba, restoreData) {
1371
1372 QMainWindow win;
1373 win.setCentralWidget(new QTextEdit);
1374 QVector<QDockWidget*> docks;
1375
1376 for(int i = 0; i < 16; ++i) {
1377 const QString name = QStringLiteral("dock ") + QString::number(i);
1378 QDockWidget *dock = new QDockWidget(name);
1379 docks += dock;
1380 dock->setObjectName(name);
1381 win.addDockWidget(area: Qt::TopDockWidgetArea, dockwidget: dock);
1382 }
1383 win.show();
1384 QCOMPARE(win.restoreState(ba), true);
1385
1386 for( int i = 0; i < docks.size(); ++i) {
1387 QCOMPARE( win.dockWidgetArea(docks[i]), Qt::DockWidgetArea(1 << i%4));
1388 }
1389 }
1390
1391}
1392
1393
1394void tst_QMainWindow::createPopupMenu()
1395{
1396 {
1397 QMainWindow mainwindow;
1398 QVERIFY(!mainwindow.createPopupMenu());
1399
1400 QToolBar toolbar1(&mainwindow);
1401 toolbar1.setWindowTitle("toolbar1");
1402 QToolBar toolbar2(&mainwindow);
1403 toolbar2.setWindowTitle("toolbar2");
1404
1405 mainwindow.addToolBar(toolbar: &toolbar1);
1406 mainwindow.addToolBar(toolbar: &toolbar2);
1407
1408 QDockWidget dockwidget1(&mainwindow);
1409 dockwidget1.setWindowTitle("dockwidget1");
1410 QDockWidget dockwidget2(&mainwindow);
1411 dockwidget2.setWindowTitle("dockwidget2");
1412 QDockWidget dockwidget3(&mainwindow);
1413 dockwidget3.setWindowTitle("dockwidget3");
1414 QDockWidget dockwidget4(&mainwindow);
1415 dockwidget4.setWindowTitle("dockwidget4");
1416
1417 mainwindow.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: &dockwidget1);
1418 mainwindow.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: &dockwidget2);
1419 mainwindow.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: &dockwidget3);
1420 mainwindow.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: &dockwidget4);
1421
1422
1423 QMenu *menu = mainwindow.createPopupMenu();
1424 QVERIFY(menu != 0);
1425 QList<QAction *> actions = menu->actions();
1426 QCOMPARE(actions.size(), 7);
1427
1428 QCOMPARE(actions.at(0), dockwidget1.toggleViewAction());
1429 QCOMPARE(actions.at(1), dockwidget2.toggleViewAction());
1430 QCOMPARE(actions.at(2), dockwidget3.toggleViewAction());
1431 QCOMPARE(actions.at(3), dockwidget4.toggleViewAction());
1432 QVERIFY(actions.at(4)->isSeparator());
1433 QCOMPARE(actions.at(5), toolbar1.toggleViewAction());
1434 QCOMPARE(actions.at(6), toolbar2.toggleViewAction());
1435
1436 delete menu;
1437
1438 mainwindow.removeToolBar(toolbar: &toolbar1);
1439 mainwindow.removeDockWidget(dockwidget: &dockwidget1);
1440 mainwindow.removeDockWidget(dockwidget: &dockwidget4);
1441
1442 menu = mainwindow.createPopupMenu();
1443 QVERIFY(menu != 0);
1444 actions = menu->actions();
1445 QCOMPARE(actions.size(), 4);
1446
1447 QCOMPARE(actions.at(0), dockwidget2.toggleViewAction());
1448 QCOMPARE(actions.at(1), dockwidget3.toggleViewAction());
1449 QVERIFY(actions.at(2)->isSeparator());
1450 QCOMPARE(actions.at(3), toolbar2.toggleViewAction());
1451
1452 delete menu;
1453 }
1454}
1455
1456class MyDockWidget : public QDockWidget
1457{
1458public:
1459 MyDockWidget(QWidget * = 0) {
1460 create(); // otherwise hide() doesn't result in a hide event
1461 }
1462};
1463
1464class MyWidget : public QWidget
1465{
1466public:
1467 MyWidget(QWidget *parent = 0) : QWidget(parent)
1468 {
1469 }
1470
1471 QSize sizeHint() const
1472 {
1473 return QSize(200, 200);
1474 }
1475};
1476
1477void tst_QMainWindow::hideBeforeLayout()
1478{
1479 QMainWindow win;
1480 QDockWidget *dock = new MyDockWidget(&win);
1481 dock->setWidget(new QLabel("hello"));
1482 win.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: dock);
1483 dock->hide();
1484 win.resize(w: 300, h: 300);
1485 win.show();
1486 dock->show();
1487 QVERIFY(dock->geometry().bottomRight().x() >= 0);
1488}
1489
1490struct AddDockWidget
1491{
1492 enum Mode { AddMode, SplitMode, TabMode };
1493
1494 AddDockWidget() {}
1495 AddDockWidget(const QString &_name, Qt::DockWidgetArea _a)
1496 : name(_name), mode(AddMode), a(_a) {}
1497 AddDockWidget(const QString &_name, const QString &_other, Qt::Orientation _o)
1498 : name(_name), mode(SplitMode), o(_o), other(_other) {}
1499 AddDockWidget(const QString &_name, const QString &_other)
1500 : name(_name), mode(TabMode), other(_other) {}
1501
1502 QString name;
1503 Mode mode;
1504
1505 Qt::Orientation o;
1506 Qt::DockWidgetArea a;
1507 QString other;
1508
1509 void apply(QMainWindow *mw) const;
1510};
1511
1512typedef QList<AddDockWidget> AddList;
1513Q_DECLARE_METATYPE(AddList)
1514
1515void AddDockWidget::apply(QMainWindow *mw) const
1516{
1517 QDockWidget *dw = new QDockWidget();
1518 QWidget *w = new QWidget();
1519 w->setMinimumSize(minw: 100, minh: 50);
1520 dw->setWidget(w);
1521
1522 dw->setObjectName(name);
1523 dw->setWindowTitle(name);
1524
1525 QDockWidget *other = 0;
1526 if (mode == SplitMode || mode == TabMode) {
1527 other = mw->findChild<QDockWidget*>(aName: this->other);
1528 QVERIFY(other != 0);
1529 }
1530
1531 switch (mode) {
1532 case AddMode:
1533 mw->addDockWidget(area: a, dockwidget: dw);
1534 break;
1535 case SplitMode:
1536 mw->splitDockWidget(after: other, dockwidget: dw, orientation: o);
1537 break;
1538 case TabMode:
1539 mw->tabifyDockWidget(first: other, second: dw);
1540 break;
1541 }
1542}
1543
1544#ifdef QT_BUILD_INTERNAL
1545struct MoveSeparator
1546{
1547 MoveSeparator() {}
1548 MoveSeparator(int _delta, const QString &_name)
1549 : delta(_delta), name(_name) {}
1550 MoveSeparator(int _delta, int _area)
1551 : delta(_delta), area(_area) {}
1552
1553 int delta;
1554 int area;
1555 QString name;
1556
1557 void apply(QMainWindow *mw) const;
1558};
1559
1560typedef QList<MoveSeparator> MoveList;
1561Q_DECLARE_METATYPE(MoveList)
1562
1563void MoveSeparator::apply(QMainWindow *mw) const
1564{
1565 QMainWindowLayout *l = mw->findChild<QMainWindowLayout *>();
1566 QVERIFY(l);
1567
1568 QList<int> path;
1569 if (name.isEmpty()) {
1570 path << area;
1571 } else {
1572 QDockWidget *dw = mw->findChild<QDockWidget*>(aName: name);
1573 QVERIFY(dw != 0);
1574 path = l->layoutState.dockAreaLayout.indexOf(dockWidget: dw);
1575 }
1576 QVERIFY(!path.isEmpty());
1577
1578 // For QTBUG-15689:
1579 // Following commands is used to simulate user move action. A better way should
1580 // use QMainWindowLayout::startSeparatorMove/separatorMove/endSeparatorMove,
1581 // but then we will need real start/end position coordinates.
1582 l->layoutState.dockAreaLayout.fallbackToSizeHints = false;
1583 l->layoutState.dockAreaLayout.separatorMove(separator: path, origin: QPoint(0, 0), dest: QPoint(delta, delta));
1584}
1585#endif
1586
1587QMap<QString, QRect> dockWidgetGeometries(QMainWindow *mw)
1588{
1589 QMap<QString, QRect> result;
1590 QList<QDockWidget*> dockWidgets = mw->findChildren<QDockWidget*>();
1591 foreach (QDockWidget *dw, dockWidgets)
1592 result.insert(key: dw->objectName(), value: dw->geometry());
1593 return result;
1594}
1595
1596#define COMPARE_DOCK_WIDGET_GEOS(_oldGeos, _newGeos) \
1597{ \
1598 QMap<QString, QRect> __oldGeos = _oldGeos; \
1599 QMap<QString, QRect> __newGeos = _newGeos; \
1600 QCOMPARE(__newGeos.keys(), __oldGeos.keys()); \
1601 QStringList __keys = __newGeos.keys(); \
1602 foreach (const QString &key, __keys) { \
1603 QRect __r1 = __oldGeos[key]; \
1604 QRect __r2 = __newGeos[key]; \
1605 if (__r1 != __r2) \
1606 qWarning() << key << __r1 << __r2; \
1607 } \
1608 QCOMPARE(__newGeos, __oldGeos); \
1609}
1610
1611#ifdef QT_BUILD_INTERNAL
1612void tst_QMainWindow::saveRestore_data()
1613{
1614 QTest::addColumn<AddList >(name: "addList");
1615 QTest::addColumn<MoveList >(name: "moveList");
1616
1617 QTest::newRow(dataTag: "1") << (AddList()
1618 << AddDockWidget("left", Qt::LeftDockWidgetArea))
1619 << (MoveList()
1620 << MoveSeparator(100, QInternal::LeftDock));
1621
1622 QTest::newRow(dataTag: "2") << (AddList()
1623 << AddDockWidget("left", Qt::LeftDockWidgetArea)
1624 << AddDockWidget("right", Qt::RightDockWidgetArea))
1625 << (MoveList()
1626 << MoveSeparator(70, QInternal::LeftDock)
1627 << MoveSeparator(-40, QInternal::RightDock));
1628 QTest::newRow(dataTag: "3") << (AddList()
1629 << AddDockWidget("left", Qt::LeftDockWidgetArea)
1630 << AddDockWidget("right1", Qt::RightDockWidgetArea)
1631 << AddDockWidget("right2", Qt::RightDockWidgetArea))
1632 << (MoveList()
1633 << MoveSeparator(70, QInternal::LeftDock)
1634 << MoveSeparator(-40, QInternal::RightDock));
1635
1636 QTest::newRow(dataTag: "4") << (AddList()
1637 << AddDockWidget("left", Qt::LeftDockWidgetArea)
1638 << AddDockWidget("right1", Qt::RightDockWidgetArea)
1639 << AddDockWidget("right2a", Qt::RightDockWidgetArea)
1640 << AddDockWidget("right2b", "right2a", Qt::Horizontal)
1641 )
1642 << (MoveList()
1643 << MoveSeparator(70, QInternal::LeftDock)
1644 << MoveSeparator(-40, QInternal::RightDock)
1645 << MoveSeparator(-30, "right1")
1646 << MoveSeparator(30, "right2a")
1647 );
1648}
1649#endif
1650
1651#ifdef QT_BUILD_INTERNAL
1652void tst_QMainWindow::saveRestore()
1653{
1654 QFETCH(AddList, addList);
1655 QFETCH(MoveList, moveList);
1656
1657 QByteArray stateData;
1658 QMap<QString, QRect> dockWidgetGeos;
1659 QSize size;
1660
1661 {
1662 QMainWindow mainWindow;
1663 mainWindow.setDockNestingEnabled(true);
1664 QTextEdit centralWidget("The rain in Spain falls mainly on the plains");
1665 mainWindow.setCentralWidget(&centralWidget);
1666
1667 foreach (const AddDockWidget &adw, addList)
1668 adw.apply(mw: &mainWindow);
1669
1670 mainWindow.show();
1671
1672 foreach (const MoveSeparator &ms, moveList)
1673 ms.apply(mw: &mainWindow);
1674
1675 dockWidgetGeos = dockWidgetGeometries(mw: &mainWindow);
1676 size = mainWindow.size();
1677 stateData = mainWindow.saveState();
1678
1679 mainWindow.layout()->setGeometry(mainWindow.rect());
1680 COMPARE_DOCK_WIDGET_GEOS(dockWidgetGeos, dockWidgetGeometries(&mainWindow));
1681 }
1682
1683 // restoreState() after show
1684 {
1685 QMainWindow mainWindow;
1686 mainWindow.setDockNestingEnabled(true);
1687 QTextEdit centralWidget("The rain in Spain falls mainly on the plains");
1688 mainWindow.setCentralWidget(&centralWidget);
1689
1690 foreach (const AddDockWidget &adw, addList)
1691 adw.apply(mw: &mainWindow);
1692
1693 mainWindow.show();
1694 mainWindow.restoreState(state: stateData);
1695
1696 COMPARE_DOCK_WIDGET_GEOS(dockWidgetGeos, dockWidgetGeometries(&mainWindow));
1697 }
1698
1699 // restoreState() before show
1700 {
1701 QMainWindow mainWindow;
1702 mainWindow.setDockNestingEnabled(true);
1703 QTextEdit centralWidget("The rain in Spain falls mainly on the plains");
1704 mainWindow.setCentralWidget(&centralWidget);
1705
1706 foreach (const AddDockWidget &adw, addList)
1707 adw.apply(mw: &mainWindow);
1708 mainWindow.resize(size);
1709 mainWindow.restoreState(state: stateData);
1710
1711 mainWindow.show();
1712 COMPARE_DOCK_WIDGET_GEOS(dockWidgetGeos, dockWidgetGeometries(&mainWindow));
1713 }
1714}
1715#endif
1716
1717void tst_QMainWindow::isSeparator()
1718{
1719 QMainWindow mw;
1720 QDockWidget *dockw = new QDockWidget();
1721 mw.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: dockw);
1722 mw.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: new QDockWidget());
1723 dockw->resize(w: 10,h: 10);
1724 mw.show();
1725
1726 //In case the separator size is 1, we increase it to 3 inside the QMainWindow class
1727 const int margin = mw.style()->pixelMetric(metric: QStyle::PM_DockWidgetSeparatorExtent, option: 0, widget: &mw) == 1 ? 2 : 0;
1728 QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y())));
1729 QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() - 1 - margin)));
1730 QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height())));
1731 QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + margin)));
1732 QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 15)));
1733
1734}
1735
1736class MainWindow : public QMainWindow {
1737 public:
1738 using QMainWindow::event;
1739};
1740
1741#ifndef QT_NO_CURSOR
1742void tst_QMainWindow::setCursor()
1743{
1744 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
1745 QSKIP("Wayland: This fails. Figure out why.");
1746
1747 MainWindow mw;
1748 QCursor cur = Qt::WaitCursor;
1749 mw.setCursor(cur);
1750 QCOMPARE(cur.shape(), mw.cursor().shape());
1751 mw.resize(w: 200,h: 200);
1752 mw.show();
1753 QVERIFY(QTest::qWaitForWindowActive(&mw));
1754 QCOMPARE(cur.shape(), mw.cursor().shape());
1755
1756 QHoverEvent enterE(QEvent::HoverEnter, QPoint(10,10), QPoint());
1757 mw.event(event: &enterE);
1758 QCOMPARE(cur.shape(), mw.cursor().shape());
1759
1760 QHoverEvent leaveE(QEvent::HoverLeave, QPoint(), QPoint());
1761 mw.event(event: &leaveE);
1762 QCOMPARE(cur.shape(), mw.cursor().shape());
1763}
1764#endif
1765
1766void tst_QMainWindow::addToolbarAfterShow()
1767{
1768 //this is for task 243119
1769 QMainWindow mainWindow;
1770 mainWindow.show();
1771
1772 QToolBar toolBar;
1773 mainWindow.addToolBar(toolbar: &toolBar);
1774
1775 QTRY_VERIFY(!toolBar.isHidden());
1776}
1777
1778void tst_QMainWindow::centralWidgetSize()
1779{
1780 if (qGuiApp->styleHints()->showIsFullScreen())
1781 QSKIP("The platform is auto maximizing, so the test makes no sense");;
1782
1783 QMainWindow mainWindow;
1784 mainWindow.menuBar()->addMenu(title: "menu");
1785
1786 MyWidget widget;
1787 mainWindow.setCentralWidget(&widget);
1788
1789 mainWindow.show();
1790#ifdef Q_OS_WINRT
1791 QEXPECT_FAIL("", "Widgets are maximized by default on WinRT - QTBUG-68297", Abort);
1792#endif
1793 QTRY_COMPARE(widget.size(), widget.sizeHint());
1794}
1795
1796void tst_QMainWindow::fixedSizeCentralWidget()
1797{
1798 // QTBUG-40410: dock widgets does not get all the available space when
1799 // central widget is fixed size
1800 QMainWindow mainWindow;
1801 mainWindow.setCorner(corner: Qt::TopLeftCorner, area: Qt::LeftDockWidgetArea);
1802
1803 MyWidget widget;
1804 widget.setFixedSize(w: 100,h: 100);
1805 mainWindow.setCentralWidget(&widget);
1806
1807 QDockWidget dock("D1");
1808 QWidget *child = new MyWidget;
1809 dock.setWidget(child);
1810 mainWindow.addDockWidget(area: Qt::TopDockWidgetArea, dockwidget: &dock);
1811
1812 QDockWidget dock2("D2");
1813 dock2.setWidget(new MyWidget);
1814 mainWindow.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: &dock2);
1815
1816 QSize sizeH = mainWindow.sizeHint();
1817 QSize mwSize = QSize(sizeH.width(), sizeH.height() * 2);
1818 mainWindow.resize(mwSize);
1819 mainWindow.show();
1820 QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
1821 if (mainWindow.height() < mwSize.height())
1822 QSKIP("The screen is too small for this test");
1823
1824 // first, check that we get more than the size hint when we have more space
1825 QTRY_VERIFY(child->height() > child->sizeHint().height());
1826 int childHeight = child->height();
1827
1828 if (qGuiApp->styleHints()->showIsFullScreen())
1829 QSKIP("The platform is auto maximizing, so we cannot resize the window");
1830
1831 // then, check that we get nothing when there is no space
1832 mainWindow.resize(w: 100,h: 100);
1833 QTRY_COMPARE(child->height(), 0);
1834
1835 // finally verify that we get the space back when we resize to the old size
1836 mainWindow.resize(mwSize);
1837#ifdef Q_OS_WINRT
1838 QEXPECT_FAIL("", "QMainWindow::resize does not work on WinRT", Continue);
1839#endif
1840 QTRY_COMPARE(child->height(), childHeight);
1841}
1842
1843void tst_QMainWindow::dockWidgetSize()
1844{
1845 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
1846 QSKIP("Wayland: This fails. Figure out why.");
1847
1848 QMainWindow mainWindow;
1849 mainWindow.menuBar()->addMenu(title: "menu");
1850
1851 MyWidget widget;
1852 mainWindow.setCentralWidget(&widget);
1853
1854 QDockWidget dock;
1855 dock.setWidget(new MyWidget);
1856 mainWindow.addDockWidget(area: Qt::TopDockWidgetArea, dockwidget: &dock);
1857
1858 mainWindow.show();
1859 QVERIFY(QTest::qWaitForWindowActive(&mainWindow));
1860 if (mainWindow.size() == mainWindow.sizeHint()) {
1861 QCOMPARE(widget.size(), widget.sizeHint());
1862 QCOMPARE(dock.widget()->size(), dock.widget()->sizeHint());
1863 } else {
1864 //otherwise the screen is too small and the size are irrelevant
1865 }
1866}
1867
1868void tst_QMainWindow::QTBUG2774_stylechange()
1869{
1870
1871 QMainWindow mw;
1872 QDockWidget *dockw = new QDockWidget();
1873 mw.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: dockw);
1874 mw.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: new QDockWidget());
1875 QTextEdit *central = new QTextEdit(&mw);
1876 mw.setCentralWidget(central);
1877 dockw->resize(w: 10,h: 10);
1878 mw.show();
1879 QVERIFY(QTest::qWaitForWindowExposed(&mw));
1880 int centralOriginalWidth = central->width();
1881
1882 QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() - 3)));
1883 QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height())));
1884 QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 30)));
1885
1886
1887 {
1888 mw.setStyleSheet("QMainWindow::separator { width: 50px; height:50px; }");
1889 QTRY_VERIFY(central->width() < centralOriginalWidth);
1890 QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height())));
1891 QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 49)));
1892 }
1893
1894 {
1895 mw.setStyleSheet("QMainWindow::separator { width: 0px; height: 0px; }");
1896 QTRY_VERIFY(central->width() > centralOriginalWidth);
1897 QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height())));
1898 QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 1)));
1899 }
1900}
1901
1902void tst_QMainWindow::QTBUG15080_restoreState()
1903{
1904 QByteArray state;
1905
1906 //save state
1907 {
1908 QMainWindow mw1;
1909 QDockWidget * dw1 = new QDockWidget();
1910 dw1->setObjectName("Left DockWidget");
1911 mw1.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: dw1);
1912 mw1.setCentralWidget(new QTextEdit());
1913 mw1.show();
1914 QApplication::processEvents();
1915 dw1->setFixedWidth(101);
1916 QApplication::processEvents();
1917
1918 state = mw1.saveState();
1919 }
1920
1921 //restore state
1922
1923 QMainWindow mw2;
1924 QDockWidget * dw2 = new QDockWidget();
1925 dw2->setObjectName("Left DockWidget");
1926 mw2.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: dw2);
1927 mw2.setCentralWidget(new QTextEdit());
1928 mw2.restoreState(state);
1929 //QTBUG15080 caused by setStyleSheet
1930 mw2.setStyleSheet("color:red");
1931 mw2.show();
1932 QApplication::processEvents();
1933
1934 QCOMPARE(dw2->width(), 101);
1935}
1936
1937#ifdef Q_OS_MAC
1938void tst_QMainWindow::toggleUnifiedTitleAndToolBarOnMac()
1939{
1940 QMainWindow mw;
1941 QToolBar *tb = new QToolBar;
1942 tb->addAction("Test");
1943 mw.addToolBar(tb);
1944 mw.setUnifiedTitleAndToolBarOnMac(true);
1945 mw.show();
1946 QRect frameGeometry = mw.frameGeometry();
1947 mw.setUnifiedTitleAndToolBarOnMac(false);
1948 QCOMPARE(frameGeometry.topLeft(), mw.frameGeometry().topLeft());
1949 mw.setUnifiedTitleAndToolBarOnMac(true);
1950 QCOMPARE(frameGeometry.topLeft(), mw.frameGeometry().topLeft());
1951}
1952#endif
1953
1954void tst_QMainWindow::QTBUG21378_animationFinished()
1955{
1956 QMainWindow w;
1957 QToolBar *pToolBar = new QToolBar;
1958 pToolBar->setFloatable(false);
1959 w.addToolBar(toolbar: pToolBar);
1960 w.resize(w: 800, h: 600);
1961 w.show();
1962 CToolBarTimer *tbMoveTimer = new CToolBarTimer(pToolBar);
1963 CMainWindowTimer *mwClickTimer = new CMainWindowTimer(&w);
1964
1965 QTest::qWait(ms: 5000);
1966 delete tbMoveTimer;
1967 delete mwClickTimer;
1968 QVERIFY(true);
1969}
1970
1971Q_DECLARE_METATYPE(Qt::Orientation)
1972
1973void tst_QMainWindow::resizeDocks_data()
1974{
1975 QTest::addColumn<Qt::Orientation>(name: "orientation");
1976 QTest::addColumn<QStringList>(name: "docks");
1977 QTest::addColumn<QList<int> >(name: "sizes");
1978
1979 QTest::newRow(dataTag: "1") << Qt::Horizontal
1980 << (QStringList() << "blue" << "orange" << "green" << "gray")
1981 << (QList<int>() << 190 << 190 << 320 << 160);
1982
1983 QTest::newRow(dataTag: "2") << Qt::Vertical
1984 << (QStringList() << "yellow" << "orange")
1985 << (QList<int>() << 147 << 133 );
1986
1987
1988 QTest::newRow(dataTag: "3") << Qt::Horizontal
1989 << (QStringList() << "blue" << "yellow")
1990 << (QList<int>() << 190 << 600);
1991}
1992
1993void tst_QMainWindow::resizeDocks()
1994{
1995 AddList addList;
1996 addList
1997 << AddDockWidget("blue", Qt::LeftDockWidgetArea)
1998 << AddDockWidget("red", Qt::TopDockWidgetArea)
1999 << AddDockWidget("pink", "red")
2000 << AddDockWidget("yellow", Qt::RightDockWidgetArea)
2001 << AddDockWidget("orange", Qt::RightDockWidgetArea)
2002 << AddDockWidget("green", "orange", Qt::Horizontal)
2003 << AddDockWidget("gray", "orange", Qt::Horizontal);
2004 /*
2005 +--------------------------------+
2006 | red/pink |
2007 +------+-+-----------------------+
2008 | | | yellow |
2009 | blue + +--------+------+-------+
2010 | | | orange | gray | green |
2011 +------+-+--------+------+-------+
2012
2013 */
2014
2015 QMainWindow mw(0, Qt::BypassWindowManagerHint);
2016 mw.setDockNestingEnabled(true);
2017 mw.resize(w: 1800, h: 600);
2018
2019 foreach (const AddDockWidget &i, addList)
2020 i.apply(mw: &mw);
2021
2022 foreach (QDockWidget *dw, mw.findChildren<QDockWidget *>())
2023 dw->setStyleSheet( "* { background-color: " + dw->objectName() +" }");
2024
2025 mw.setCentralWidget(new QTextEdit);
2026
2027 mw.show();
2028 QVERIFY(QTest::qWaitForWindowExposed(&mw));
2029
2030 QFETCH(Qt::Orientation, orientation);
2031 QFETCH(QStringList, docks);
2032 QFETCH(QList<int>, sizes);
2033
2034 QList<QDockWidget *> list;
2035 foreach (const QString &name, docks) {
2036 QDockWidget *d = mw.findChild<QDockWidget *>(aName: name);
2037 QVERIFY(d);
2038 list << d;
2039 }
2040
2041 mw.resizeDocks(docks: list, sizes, orientation);
2042
2043 qApp->processEvents();
2044
2045 int totalFromList = 0;
2046 int actualTotal = 0;
2047 for (int i = 0; i < docks.count(); ++i) {
2048 totalFromList += sizes[i];
2049 QSize s = list[i]->size();
2050 actualTotal += (orientation == Qt::Horizontal) ? s.width() : s.height();
2051// qDebug() << list[i] << list[i]->size() << sizes[i];
2052 }
2053
2054 for (int i = 0; i < docks.count(); ++i) {
2055 QSize s = list[i]->size();
2056 int value = (orientation == Qt::Horizontal) ? s.width() : s.height();
2057 QCOMPARE(value, qRound(sizes[i]*actualTotal/double(totalFromList)));
2058 }
2059}
2060
2061#if QT_CONFIG(dockwidget) && QT_CONFIG(tabbar)
2062void tst_QMainWindow::QTBUG52175_tabifiedDockWidgetActivated()
2063{
2064 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
2065 QSKIP("Wayland: This fails. Figure out why.");
2066
2067 QMainWindow w;
2068
2069 QDockWidget *dwFirst = new QDockWidget(&w);
2070 dwFirst->setWidget(new QWidget(dwFirst));
2071 w.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: dwFirst);
2072
2073 QDockWidget *dwSecond = new QDockWidget(&w);
2074 dwSecond->setWidget(new QWidget(dwSecond));
2075 w.addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: dwSecond);
2076
2077 w.tabifyDockWidget(first: dwFirst, second: dwSecond);
2078 w.show();
2079 QVERIFY(QTest::qWaitForWindowActive(&w));
2080
2081 QTabBar *tabBar = w.findChild<QTabBar *>();
2082 QVERIFY(tabBar);
2083
2084 QDockWidget *activated = nullptr;
2085 connect(sender: &w, signal: &QMainWindow::tabifiedDockWidgetActivated, slot: [&activated](QDockWidget *dockWidget)
2086 {
2087 activated = dockWidget;
2088 });
2089
2090 w.hide();
2091 QCoreApplication::processEvents();
2092 QCOMPARE(activated, nullptr);
2093
2094 w.show();
2095 QCoreApplication::processEvents();
2096 QCOMPARE(activated, nullptr);
2097
2098 tabBar->setCurrentIndex(1);
2099 QCoreApplication::processEvents();
2100 QCOMPARE(activated, nullptr);
2101
2102 tabBar->setCurrentIndex(0);
2103 QTRY_COMPARE(activated, dwFirst);
2104 activated = nullptr;
2105
2106 tabBar->setCurrentIndex(1);
2107 QTRY_COMPARE(activated, dwSecond);
2108}
2109#endif
2110
2111QTEST_MAIN(tst_QMainWindow)
2112#include "tst_qmainwindow.moc"
2113

source code of qtbase/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp