QDockWidget: add Q_PROPERTY dockWidgetArea
Implement dockLocation Q_PROPERTY. Use dockLocationChanged signal. Ensure the signal is only emitted on changes. Add and document getter and setter. Modify tst_QDockWidget::dockLocationChanged() to cover new API. [ChangeLog][QtWidgets][QDockWidget] Added dockLocation Q_PROPERTY with new dockLocation() and setDockLocation() API. Fixes: QTBUG-117834 Change-Id: I85cfb613ae932f9e0dd42f8e7b20fee91a4201e6 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
da61af8065
commit
cbd2f56c14
@ -1797,6 +1797,7 @@ QAction * QDockWidget::toggleViewAction() const
|
||||
dock \a area, or is moved to a different location in its current
|
||||
dock area. This happens when the dock widget is moved
|
||||
programmatically or is dragged to a new location by the user.
|
||||
\sa dockLocation(), setDockLocation()
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -1854,6 +1855,51 @@ void QDockWidget::setTitleBarWidget(QWidget *widget)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.9
|
||||
\brief QDockWidget::setDockLocation(): Assign dock widget to \a area.
|
||||
If docked at another dock location, it will move to \a area.
|
||||
If floating or part of floating tabs, the next call of setFloating(false)
|
||||
will dock it at \a area.
|
||||
|
||||
\note
|
||||
setDockLocation(Qt::NoDockLocation) is equivalent to setFloating(true).
|
||||
\sa dockLocation(), dockLocationChanged()
|
||||
*/
|
||||
void QDockWidget::setDockLocation(Qt::DockWidgetArea area)
|
||||
{
|
||||
if (area == Qt::NoDockWidgetArea && !isFloating()) {
|
||||
setFloating(true);
|
||||
return;
|
||||
}
|
||||
|
||||
auto *mainWindow = const_cast<QMainWindow *>(mainwindow_from_dock(this));
|
||||
Q_ASSERT(mainWindow);
|
||||
mainWindow->addDockWidget(area, this);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.9
|
||||
\brief QDockWidget::dockLocation()
|
||||
\return the current dock location, or Qt::NoDockLocation if it's floating
|
||||
and/or has no mainwindow parent.
|
||||
\sa setDockLocation(), dockLocationChanged()
|
||||
*/
|
||||
Qt::DockWidgetArea QDockWidget::dockLocation() const
|
||||
{
|
||||
// QDockWidgetPrivate::setWindowState() emits NoDockWidgetArea if
|
||||
// the dock widget becomes floating.
|
||||
// QMainWindowLayout::dockWidgetArea() always returns the area where
|
||||
// the dock widget's item_list is kept.
|
||||
if (isFloating())
|
||||
return Qt::NoDockWidgetArea;
|
||||
|
||||
auto *mainWindow = mainwindow_from_dock(this);
|
||||
Q_ASSERT(mainWindow);
|
||||
// FIXME in Qt 7: Make dockWidgetArea take a const QDockWidget* argument
|
||||
return mainWindow->dockWidgetArea(const_cast<QDockWidget *>(this));
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.3
|
||||
Returns the custom title bar widget set on the QDockWidget, or
|
||||
|
@ -25,6 +25,8 @@ class Q_WIDGETS_EXPORT QDockWidget : public QWidget
|
||||
Q_PROPERTY(Qt::DockWidgetAreas allowedAreas READ allowedAreas
|
||||
WRITE setAllowedAreas NOTIFY allowedAreasChanged)
|
||||
Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true)
|
||||
Q_PROPERTY(Qt::DockWidgetArea dockLocation READ dockLocation WRITE setDockLocation
|
||||
NOTIFY dockLocationChanged)
|
||||
|
||||
public:
|
||||
explicit QDockWidget(const QString &title, QWidget *parent = nullptr,
|
||||
@ -61,6 +63,9 @@ public:
|
||||
void setTitleBarWidget(QWidget *widget);
|
||||
QWidget *titleBarWidget() const;
|
||||
|
||||
void setDockLocation(Qt::DockWidgetArea area);
|
||||
Qt::DockWidgetArea dockLocation() const;
|
||||
|
||||
inline bool isAreaAllowed(Qt::DockWidgetArea area) const
|
||||
{ return (allowedAreas() & area) == area; }
|
||||
|
||||
|
@ -1037,8 +1037,11 @@ void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const Qt::DockWidgetArea oldArea = dockWidgetArea(dockwidget);
|
||||
d_func()->layout->removeWidget(dockwidget); // in case it was already in here
|
||||
addDockWidget(area, dockwidget, orientation);
|
||||
if (oldArea != area)
|
||||
emit dockwidget->dockLocationChanged(area);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1710,6 +1710,10 @@ QRect QMainWindowLayout::dockWidgetAreaRect(const Qt::DockWidgetArea area, DockW
|
||||
return (size == Maximum) ? dl.gapRect(dockPosition) : dl.docks[dockPosition].rect;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Add \a dockwidget to \a area in \a orientation.
|
||||
*/
|
||||
void QMainWindowLayout::addDockWidget(Qt::DockWidgetArea area,
|
||||
QDockWidget *dockwidget,
|
||||
Qt::Orientation orientation)
|
||||
@ -1722,7 +1726,6 @@ void QMainWindowLayout::addDockWidget(Qt::DockWidgetArea area,
|
||||
endSeparatorMove(movingSeparatorPos);
|
||||
|
||||
layoutState.dockAreaLayout.addDockWidget(toDockPos(area), dockwidget, orientation);
|
||||
emit dockwidget->dockLocationChanged(area);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
@ -756,6 +756,12 @@ void tst_QDockWidget::updateTabBarOnVisibilityChanged()
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::DockWidgetArea)
|
||||
|
||||
Qt::DockWidgetArea dockLocation(const QSignalSpy *spy)
|
||||
{
|
||||
Q_ASSERT(spy);
|
||||
return qvariant_cast<Qt::DockWidgetArea>(spy->at(0).at(0));
|
||||
}
|
||||
|
||||
void tst_QDockWidget::dockLocationChanged()
|
||||
{
|
||||
qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea");
|
||||
@ -763,61 +769,66 @@ void tst_QDockWidget::dockLocationChanged()
|
||||
QMainWindow mw;
|
||||
QDockWidget dw;
|
||||
dw.setObjectName("dock1");
|
||||
QSignalSpy spy(&dw, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)));
|
||||
QSignalSpy spy(&dw, &QDockWidget::dockLocationChanged);
|
||||
|
||||
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::LeftDockWidgetArea);
|
||||
QCOMPARE(dockLocation(&spy), Qt::LeftDockWidgetArea);
|
||||
|
||||
constexpr std::array<Qt::DockWidgetArea, 5> areas{Qt::LeftDockWidgetArea,
|
||||
Qt::TopDockWidgetArea,
|
||||
Qt::RightDockWidgetArea,
|
||||
Qt::BottomDockWidgetArea,
|
||||
Qt::NoDockWidgetArea};
|
||||
|
||||
for (const auto area : areas) {
|
||||
spy.clear();
|
||||
const int expectedCount = dw.dockLocation() == area ? 0 : 1;
|
||||
dw.setDockLocation(area);
|
||||
|
||||
// Ensure signal is only fired on changes
|
||||
QCOMPARE(spy.count(), expectedCount);
|
||||
if (expectedCount)
|
||||
QCOMPARE(dockLocation(&spy), area);
|
||||
|
||||
// Ensure getter reports correctly
|
||||
QTRY_COMPARE(dw.dockLocation(), area);
|
||||
|
||||
// Ensure setting NoDockWidgetArea floats the dock widget
|
||||
if (area == Qt::NoDockWidgetArea) {
|
||||
QCOMPARE(dw.isFloating(), true);
|
||||
dw.setFloating(false);
|
||||
}
|
||||
}
|
||||
|
||||
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::LeftDockWidgetArea);
|
||||
spy.clear();
|
||||
|
||||
mw.addDockWidget(Qt::RightDockWidgetArea, &dw);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::RightDockWidgetArea);
|
||||
spy.clear();
|
||||
|
||||
mw.removeDockWidget(&dw);
|
||||
QCOMPARE(spy.size(), 0);
|
||||
|
||||
QDockWidget dw2;
|
||||
dw2.setObjectName("dock2");
|
||||
mw.addDockWidget(Qt::TopDockWidgetArea, &dw2);
|
||||
mw.tabifyDockWidget(&dw2, &dw);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::TopDockWidgetArea);
|
||||
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||
spy.clear();
|
||||
|
||||
mw.splitDockWidget(&dw2, &dw, Qt::Horizontal);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::TopDockWidgetArea);
|
||||
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||
spy.clear();
|
||||
|
||||
dw.setFloating(true);
|
||||
QTRY_COMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::NoDockWidgetArea);
|
||||
QCOMPARE(dockLocation(&spy), Qt::NoDockWidgetArea);
|
||||
spy.clear();
|
||||
|
||||
dw.setFloating(false);
|
||||
QTRY_COMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::TopDockWidgetArea);
|
||||
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||
spy.clear();
|
||||
|
||||
QByteArray ba = mw.saveState();
|
||||
mw.restoreState(ba);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
||||
Qt::TopDockWidgetArea);
|
||||
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||
}
|
||||
|
||||
void tst_QDockWidget::setTitleBarWidget()
|
||||
|
Loading…
x
Reference in New Issue
Block a user