tests: Port some tests to QtQuick
15 to go
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
# include <QLineEdit>
|
||||
# include <QTextEdit>
|
||||
# include <QTabBar>
|
||||
# include <QMenuBar>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@@ -223,6 +224,8 @@ private Q_SLOTS:
|
||||
void tst_lastFloatingPositionIsRestored();
|
||||
void tst_negativeAnchorPositionWhenEmbedded();
|
||||
void tst_negativeAnchorPositionWhenEmbedded_data();
|
||||
void tst_floatingAction();
|
||||
void tst_raise();
|
||||
|
||||
#ifdef KDDOCKWIDGETS_QTWIDGETS
|
||||
// TODO: Port these to QtQuick
|
||||
@@ -233,6 +236,7 @@ private Q_SLOTS:
|
||||
void tst_dragByTabBar();
|
||||
void tst_dragBySingleTab();
|
||||
void tst_mainWindowAlwaysHasCentralWidget();
|
||||
void tst_dockableMainWindows();
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -5017,6 +5021,75 @@ void TestCommon::tst_mainWindowAlwaysHasCentralWidget()
|
||||
delete dock->window();
|
||||
}
|
||||
|
||||
void TestCommon::tst_dockableMainWindows()
|
||||
{
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
auto m1 = createMainWindow();
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("foo"));
|
||||
m1->addDockWidget(dock1, Location_OnTop);
|
||||
|
||||
auto m2 = new KDDockWidgets::MainWindow("mainwindow-dockable");
|
||||
auto m2Container = createDockWidget("mainwindow-dw", m2);
|
||||
auto menubar = m2->menuBar();
|
||||
menubar->addMenu("File");
|
||||
menubar->addMenu("View");
|
||||
menubar->addMenu("Help");
|
||||
m2Container->show();
|
||||
|
||||
auto dock21 = createDockWidget("dock21", new QPushButton("foo"));
|
||||
auto dock22 = createDockWidget("dock22", new QPushButton("foo"));
|
||||
m2->addDockWidget(dock21, Location_OnLeft);
|
||||
m2->addDockWidget(dock22, Location_OnRight);
|
||||
|
||||
auto fw = m2Container->floatingWindow();
|
||||
TitleBar *fwTitleBar = fw->titleBar();
|
||||
|
||||
QVERIFY(fw->hasSingleFrame());
|
||||
QVERIFY(fw->hasSingleDockWidget());
|
||||
|
||||
// Check that the inner-inner dock widgets have a visible title-bar
|
||||
QVERIFY(dock21->titleBar()->isVisible());
|
||||
QVERIFY(dock22->titleBar()->isVisible());
|
||||
QVERIFY(dock21->titleBar() != fwTitleBar);
|
||||
QVERIFY(dock22->titleBar() != fwTitleBar);
|
||||
|
||||
QTest::qWait(10); // the DND state machine needs the event loop to start, otherwise activeState() is nullptr. (for offscreen QPA)
|
||||
const QPoint startPoint = fwTitleBar->mapToGlobal(QPoint(5, 5));
|
||||
const QPoint destination = startPoint + QPoint(20, 20);
|
||||
|
||||
// Check that we don't get the "Refusing to itself" warning. not actually dropping anywhere
|
||||
drag(fwTitleBar, startPoint, destination);
|
||||
|
||||
// The FloatingWindow has a single DockWidget, so it shows the title bar, while the Frame doesn't
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
|
||||
// Now the FloatingWindow has two dock widgets, so our main window dock widget also shows the title bar
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
// Put it how it was, FloatingWindow is single dock again
|
||||
auto frame1 = dock1->frame();
|
||||
dock1->close();
|
||||
Testing::waitForDeleted(frame1);
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
// Repeat, but instead of closing dock1, we float it
|
||||
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(m2Container->frame()->titleBar()->isVisible());
|
||||
frame1 = dock1->frame();
|
||||
frame1->titleBar()->onFloatClicked();
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
|
||||
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void TestCommon::tst_negativeAnchorPositionWhenEmbedded_data()
|
||||
@@ -5058,4 +5131,292 @@ void TestCommon::tst_negativeAnchorPositionWhenEmbedded()
|
||||
delete m->window();
|
||||
}
|
||||
|
||||
void TestCommon::tst_floatingAction()
|
||||
{
|
||||
// Tests DockWidget::floatAction()
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
{
|
||||
// 1. Create a MainWindow with two docked dock-widgets, then float the first one.
|
||||
auto m = createMainWindow();
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
|
||||
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
|
||||
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
|
||||
|
||||
auto action = dock1->floatAction();
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));
|
||||
|
||||
action->toggle();
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Dock"));
|
||||
|
||||
auto fw = dock1->floatingWindow();
|
||||
QVERIFY(fw);
|
||||
|
||||
//2. Put it back, via setFloating(). It should return to its place.
|
||||
action->toggle();
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QVERIFY(!dock1->isTabbed());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));;
|
||||
|
||||
Testing::waitForDeleted(fw);
|
||||
}
|
||||
|
||||
{
|
||||
// 1. Create a MainWindow with one docked dock-widgets, and one floating.
|
||||
auto m = createMainWindow();
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
|
||||
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
|
||||
|
||||
//The floating window action should be disabled as it has no previous place
|
||||
auto action = dock2->floatAction();
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(action->isChecked());
|
||||
QVERIFY(!action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Dock"));
|
||||
|
||||
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
|
||||
|
||||
QVERIFY(!dock2->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));
|
||||
|
||||
action->toggle();
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Dock"));
|
||||
|
||||
auto fw = dock2->floatingWindow();
|
||||
QVERIFY(fw);
|
||||
|
||||
//2. Put it back, via setFloating(). It should return to its place.
|
||||
action->toggle();
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QVERIFY(!dock1->isTabbed());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));
|
||||
|
||||
Testing::waitForDeleted(fw);
|
||||
}
|
||||
{
|
||||
// 3. A floating window with two tabs
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
|
||||
|
||||
bool dock1IsFloating = dock1->floatAction()->isChecked();
|
||||
bool dock2IsFloating = dock2->floatAction()->isChecked();
|
||||
|
||||
connect(dock1->floatAction(), &QAction::toggled, [&dock1IsFloating] (bool t) {
|
||||
Q_ASSERT(dock1IsFloating != t);
|
||||
dock1IsFloating = t;
|
||||
});
|
||||
|
||||
connect(dock2->floatAction(), &QAction::toggled, [&dock2IsFloating] (bool t) {
|
||||
Q_ASSERT(dock2IsFloating != t);
|
||||
dock2IsFloating = t;
|
||||
});
|
||||
|
||||
auto fw2 = dock2->floatingWindow();
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
|
||||
dock1->addDockWidgetAsTab(dock2);
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
|
||||
dock2->setFloating(true);
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
|
||||
QVERIFY(dock1IsFloating);
|
||||
QVERIFY(dock2IsFloating);
|
||||
|
||||
delete fw2;
|
||||
delete dock1->window();
|
||||
delete dock2->window();
|
||||
}
|
||||
|
||||
{
|
||||
// If the dock widget is alone then it's floating, but we suddenly dock a widget side-by-side
|
||||
// to it, then both aren't floating anymore. This test tests if the signal was emitted
|
||||
|
||||
auto dock1 = createDockWidget("one", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("two", new QPushButton("two"));
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
auto oldFw2 = dock2->window();
|
||||
|
||||
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
|
||||
|
||||
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
|
||||
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
|
||||
|
||||
dock1->addDockWidgetToContainingWindow(dock2, Location_OnRight);
|
||||
|
||||
QCOMPARE(spy1.count(), 1);
|
||||
QCOMPARE(spy2.count(), 1);
|
||||
QCOMPARE(spy11.count(), 1);
|
||||
QCOMPARE(spy21.count(), 1);
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
|
||||
delete dock1->window();
|
||||
delete oldFw2->window();
|
||||
}
|
||||
|
||||
{
|
||||
// Like before, but now we use addMultiSplitter()
|
||||
|
||||
auto dock1 = createDockWidget("one", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("two", new QPushButton("two"));
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
auto oldFw2 = dock2->floatingWindow();
|
||||
|
||||
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
|
||||
|
||||
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
|
||||
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
|
||||
|
||||
auto dropArea1 = dock1->floatingWindow()->dropArea();
|
||||
dropArea1->drop(oldFw2, Location_OnRight, nullptr);
|
||||
|
||||
QCOMPARE(spy1.count(), 1);
|
||||
QCOMPARE(spy2.count(), 1);
|
||||
QCOMPARE(spy11.count(), 1);
|
||||
QCOMPARE(spy21.count(), 1);
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
|
||||
// Let's now remove dock1, dock2 should be floating
|
||||
dock1->setFloating(true);
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
|
||||
delete dock1->window();
|
||||
delete dock2->window();
|
||||
delete oldFw2->window();
|
||||
}
|
||||
|
||||
{
|
||||
// Same test as before, but now tab instead of side-by-side
|
||||
auto dock1 = createDockWidget("one", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("two", new QPushButton("two"));
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
auto oldFw2 = dock2->window();
|
||||
|
||||
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
|
||||
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
|
||||
dock1->addDockWidgetAsTab(dock2);
|
||||
|
||||
QCOMPARE(spy1.count(), 1);
|
||||
|
||||
// On earlier Qt versions this is flaky, but technically correct.
|
||||
// Windows can get hidden while being reparented and floating changes momentarily.
|
||||
QVERIFY(spy2.count() == 1 || spy2.count() == 3);
|
||||
QVERIFY(spy21.count() == 1 || spy21.count() == 3);
|
||||
QCOMPARE(spy11.count(), 1);
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
|
||||
delete dock1->window();
|
||||
delete oldFw2->window();
|
||||
}
|
||||
}
|
||||
|
||||
void TestCommon::tst_raise()
|
||||
{
|
||||
// Tests DockWidget::raise();
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
auto dock1 = createDockWidget("1");
|
||||
auto dock2 = createDockWidget("2");
|
||||
auto fw2 = Tests::make_qpointer(dock2->window());
|
||||
dock1->addDockWidgetAsTab(dock2);
|
||||
dock1->setAsCurrentTab();
|
||||
QVERIFY(dock1->isCurrentTab());
|
||||
QVERIFY(!dock2->isCurrentTab());
|
||||
dock2->raise();
|
||||
QVERIFY(!dock1->isCurrentTab());
|
||||
QVERIFY(dock2->isCurrentTab());
|
||||
|
||||
if (qApp->platformName() != QLatin1String("offscreen")) { // offscreen qpa doesn't seem to keep Window Z.
|
||||
auto dock3 = createDockWidget("3");
|
||||
dock3->window()->setGeometry(dock1->window()->geometry());
|
||||
dock3->window()->setObjectName("3");
|
||||
dock1->window()->setObjectName("1");
|
||||
dock3->raise();
|
||||
QTest::qWait(200);
|
||||
|
||||
if (qApp->QGuiApplication::topLevelAt(dock3->window()->geometry().topLeft() + QPoint(50, 50)) != dock3->windowHandle()) {
|
||||
qDebug() << "Failing before raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock3->window()
|
||||
<< dock1->window()->geometry() << dock3->window()->geometry();
|
||||
QVERIFY(false);
|
||||
}
|
||||
|
||||
dock1->raise();
|
||||
QTest::qWait(200);
|
||||
QVERIFY(dock1->isCurrentTab());
|
||||
|
||||
if (qApp->QGuiApplication::topLevelAt(dock3->window()->geometry().topLeft() + QPoint(50, 50)) != dock1->windowHandle()) {
|
||||
qDebug() << "Failing after raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock1->window()
|
||||
<< dock1->window()->geometry() << dock3->window()->geometry();
|
||||
QVERIFY(false);
|
||||
}
|
||||
|
||||
delete dock3->window();
|
||||
}
|
||||
|
||||
delete fw2;
|
||||
delete dock1->window();
|
||||
}
|
||||
|
||||
#include "tst_common.moc"
|
||||
|
||||
@@ -173,9 +173,6 @@ private Q_SLOTS:
|
||||
void tst_addingOptionHiddenTabbed();
|
||||
void tst_flagDoubleClick();
|
||||
void tst_floatingWindowDeleted();
|
||||
void tst_raise();
|
||||
void tst_floatingAction();
|
||||
void tst_dockableMainWindows();
|
||||
void tst_maxSizedHonouredAfterRemoved();
|
||||
void tst_maximumSizePolicy();
|
||||
|
||||
@@ -832,363 +829,6 @@ void TestDocks::tst_floatingWindowDeleted()
|
||||
MyMainWindow m;
|
||||
}
|
||||
|
||||
void TestDocks::tst_raise()
|
||||
{
|
||||
// Tests DockWidget::raise();
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
auto dock1 = createDockWidget("1", new QWidget());
|
||||
auto dock2 = createDockWidget("2", new QWidget());
|
||||
auto fw2 = Tests::make_qpointer(dock2->window());
|
||||
dock1->addDockWidgetAsTab(dock2);
|
||||
dock1->setAsCurrentTab();
|
||||
QVERIFY(dock1->isCurrentTab());
|
||||
QVERIFY(!dock2->isCurrentTab());
|
||||
dock2->raise();
|
||||
QVERIFY(!dock1->isCurrentTab());
|
||||
QVERIFY(dock2->isCurrentTab());
|
||||
|
||||
if (qApp->platformName() != QLatin1String("offscreen")) { // offscreen qpa doesn't seem to keep Window Z.
|
||||
auto dock3 = createDockWidget("3", new QWidget());
|
||||
dock3->window()->setGeometry(dock1->window()->geometry());
|
||||
dock3->window()->setObjectName("3");
|
||||
dock1->window()->setObjectName("1");
|
||||
dock3->raise();
|
||||
QTest::qWait(200);
|
||||
|
||||
if (qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() != dock3->window()) {
|
||||
qDebug() << "Failing before raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock3->window()
|
||||
<< dock1->window()->geometry() << dock3->window()->geometry();
|
||||
QVERIFY(false);
|
||||
}
|
||||
|
||||
dock1->raise();
|
||||
QTest::qWait(200);
|
||||
QVERIFY(dock1->isCurrentTab());
|
||||
|
||||
if (qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() != dock1->window()) {
|
||||
qDebug() << "Failing after raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock1->window()
|
||||
<< dock1->window()->geometry() << dock3->window()->geometry();
|
||||
QVERIFY(false);
|
||||
}
|
||||
|
||||
delete dock3->window();
|
||||
}
|
||||
|
||||
delete fw2;
|
||||
delete dock1->window();
|
||||
}
|
||||
|
||||
void TestDocks::tst_floatingAction()
|
||||
{
|
||||
// Tests DockWidget::floatAction()
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
{
|
||||
// 1. Create a MainWindow with two docked dock-widgets, then float the first one.
|
||||
auto m = createMainWindow();
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
|
||||
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
|
||||
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
|
||||
|
||||
auto action = dock1->floatAction();
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));
|
||||
|
||||
action->toggle();
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Dock"));
|
||||
|
||||
auto fw = dock1->floatingWindow();
|
||||
QVERIFY(fw);
|
||||
|
||||
//2. Put it back, via setFloating(). It should return to its place.
|
||||
action->toggle();
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QVERIFY(!dock1->isTabbed());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));;
|
||||
|
||||
Testing::waitForDeleted(fw);
|
||||
}
|
||||
|
||||
{
|
||||
// 1. Create a MainWindow with one docked dock-widgets, and one floating.
|
||||
auto m = createMainWindow();
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
|
||||
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
|
||||
|
||||
//The floating window action should be disabled as it has no previous place
|
||||
auto action = dock2->floatAction();
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(action->isChecked());
|
||||
QVERIFY(!action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Dock"));
|
||||
|
||||
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
|
||||
|
||||
QVERIFY(!dock2->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));
|
||||
|
||||
action->toggle();
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QCOMPARE(action->toolTip(), tr("Dock"));
|
||||
|
||||
auto fw = dock2->floatingWindow();
|
||||
QVERIFY(fw);
|
||||
|
||||
//2. Put it back, via setFloating(). It should return to its place.
|
||||
action->toggle();
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!action->isChecked());
|
||||
QVERIFY(action->isEnabled());
|
||||
QVERIFY(!dock1->isTabbed());
|
||||
QCOMPARE(action->toolTip(), tr("Detach"));
|
||||
|
||||
Testing::waitForDeleted(fw);
|
||||
}
|
||||
{
|
||||
// 3. A floating window with two tabs
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
|
||||
|
||||
bool dock1IsFloating = dock1->floatAction()->isChecked();
|
||||
bool dock2IsFloating = dock2->floatAction()->isChecked();
|
||||
|
||||
connect(dock1->floatAction(), &QAction::toggled, [&dock1IsFloating] (bool t) {
|
||||
Q_ASSERT(dock1IsFloating != t);
|
||||
dock1IsFloating = t;
|
||||
});
|
||||
|
||||
connect(dock2->floatAction(), &QAction::toggled, [&dock2IsFloating] (bool t) {
|
||||
Q_ASSERT(dock2IsFloating != t);
|
||||
dock2IsFloating = t;
|
||||
});
|
||||
|
||||
auto fw2 = dock2->floatingWindow();
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
|
||||
dock1->addDockWidgetAsTab(dock2);
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
|
||||
dock2->setFloating(true);
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
|
||||
QVERIFY(dock1IsFloating);
|
||||
QVERIFY(dock2IsFloating);
|
||||
|
||||
delete fw2;
|
||||
delete dock1->window();
|
||||
delete dock2->window();
|
||||
}
|
||||
|
||||
{
|
||||
// If the dock widget is alone then it's floating, but we suddenly dock a widget side-by-side
|
||||
// to it, then both aren't floating anymore. This test tests if the signal was emitted
|
||||
|
||||
auto dock1 = createDockWidget("one", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("two", new QPushButton("two"));
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
auto oldFw2 = dock2->window();
|
||||
|
||||
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
|
||||
|
||||
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
|
||||
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
|
||||
|
||||
dock1->addDockWidgetToContainingWindow(dock2, Location_OnRight);
|
||||
|
||||
QCOMPARE(spy1.count(), 1);
|
||||
QCOMPARE(spy2.count(), 1);
|
||||
QCOMPARE(spy11.count(), 1);
|
||||
QCOMPARE(spy21.count(), 1);
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
|
||||
delete dock1->window();
|
||||
delete oldFw2->window();
|
||||
}
|
||||
|
||||
{
|
||||
// Like before, but now we use addMultiSplitter()
|
||||
|
||||
auto dock1 = createDockWidget("one", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("two", new QPushButton("two"));
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
auto oldFw2 = dock2->floatingWindow();
|
||||
|
||||
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
|
||||
|
||||
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
|
||||
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
|
||||
|
||||
auto dropArea1 = dock1->floatingWindow()->dropArea();
|
||||
dropArea1->drop(oldFw2, Location_OnRight, nullptr);
|
||||
|
||||
QCOMPARE(spy1.count(), 1);
|
||||
QCOMPARE(spy2.count(), 1);
|
||||
QCOMPARE(spy11.count(), 1);
|
||||
QCOMPARE(spy21.count(), 1);
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
|
||||
// Let's now remove dock1, dock2 should be floating
|
||||
dock1->setFloating(true);
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
|
||||
delete dock1->window();
|
||||
delete dock2->window();
|
||||
delete oldFw2->window();
|
||||
}
|
||||
|
||||
{
|
||||
// Same test as before, but now tab instead of side-by-side
|
||||
auto dock1 = createDockWidget("one", new QPushButton("one"));
|
||||
auto dock2 = createDockWidget("two", new QPushButton("two"));
|
||||
|
||||
QVERIFY(dock1->isFloating());
|
||||
QVERIFY(dock2->isFloating());
|
||||
QVERIFY(dock1->floatAction()->isChecked());
|
||||
QVERIFY(dock2->floatAction()->isChecked());
|
||||
auto oldFw2 = dock2->window();
|
||||
|
||||
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
|
||||
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
|
||||
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
|
||||
dock1->addDockWidgetAsTab(dock2);
|
||||
|
||||
QCOMPARE(spy1.count(), 1);
|
||||
|
||||
// On earlier Qt versions this is flaky, but technically correct.
|
||||
// Windows can get hidden while being reparented and floating changes momentarily.
|
||||
QVERIFY(spy2.count() == 1 || spy2.count() == 3);
|
||||
QVERIFY(spy21.count() == 1 || spy21.count() == 3);
|
||||
QCOMPARE(spy11.count(), 1);
|
||||
|
||||
QVERIFY(!dock1->isFloating());
|
||||
QVERIFY(!dock2->isFloating());
|
||||
|
||||
QVERIFY(!dock2->floatAction()->isChecked());
|
||||
QVERIFY(!dock1->floatAction()->isChecked());
|
||||
|
||||
delete dock1->window();
|
||||
delete oldFw2->window();
|
||||
}
|
||||
}
|
||||
|
||||
void TestDocks::tst_dockableMainWindows()
|
||||
{
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
auto m1 = createMainWindow();
|
||||
auto dock1 = createDockWidget("dock1", new QPushButton("foo"));
|
||||
m1->addDockWidget(dock1, Location_OnTop);
|
||||
|
||||
auto m2 = new KDDockWidgets::MainWindow("mainwindow-dockable");
|
||||
auto m2Container = createDockWidget("mainwindow-dw", m2);
|
||||
auto menubar = m2->menuBar();
|
||||
menubar->addMenu("File");
|
||||
menubar->addMenu("View");
|
||||
menubar->addMenu("Help");
|
||||
m2Container->show();
|
||||
|
||||
auto dock21 = createDockWidget("dock21", new QPushButton("foo"));
|
||||
auto dock22 = createDockWidget("dock22", new QPushButton("foo"));
|
||||
m2->addDockWidget(dock21, Location_OnLeft);
|
||||
m2->addDockWidget(dock22, Location_OnRight);
|
||||
|
||||
auto fw = m2Container->floatingWindow();
|
||||
TitleBar *fwTitleBar = fw->titleBar();
|
||||
|
||||
QVERIFY(fw->hasSingleFrame());
|
||||
QVERIFY(fw->hasSingleDockWidget());
|
||||
|
||||
// Check that the inner-inner dock widgets have a visible title-bar
|
||||
QVERIFY(dock21->titleBar()->isVisible());
|
||||
QVERIFY(dock22->titleBar()->isVisible());
|
||||
QVERIFY(dock21->titleBar() != fwTitleBar);
|
||||
QVERIFY(dock22->titleBar() != fwTitleBar);
|
||||
|
||||
QTest::qWait(10); // the DND state machine needs the event loop to start, otherwise activeState() is nullptr. (for offscreen QPA)
|
||||
const QPoint startPoint = fwTitleBar->mapToGlobal(QPoint(5, 5));
|
||||
const QPoint destination = startPoint + QPoint(20, 20);
|
||||
|
||||
// Check that we don't get the "Refusing to itself" warning. not actually dropping anywhere
|
||||
drag(fwTitleBar, startPoint, destination);
|
||||
|
||||
// The FloatingWindow has a single DockWidget, so it shows the title bar, while the Frame doesn't
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
|
||||
// Now the FloatingWindow has two dock widgets, so our main window dock widget also shows the title bar
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
// Put it how it was, FloatingWindow is single dock again
|
||||
auto frame1 = dock1->frame();
|
||||
dock1->close();
|
||||
Testing::waitForDeleted(frame1);
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
// Repeat, but instead of closing dock1, we float it
|
||||
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
QVERIFY(m2Container->frame()->titleBar()->isVisible());
|
||||
frame1 = dock1->frame();
|
||||
frame1->titleBar()->onFloatClicked();
|
||||
QVERIFY(fwTitleBar->isVisible());
|
||||
|
||||
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
|
||||
|
||||
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
|
||||
}
|
||||
|
||||
void TestDocks::tst_maxSizedHonouredAfterRemoved()
|
||||
{
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
Reference in New Issue
Block a user