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 \a area, or is moved to a different location in its current
|
||||||
dock area. This happens when the dock widget is moved
|
dock area. This happens when the dock widget is moved
|
||||||
programmatically or is dragged to a new location by the user.
|
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
|
\since 4.3
|
||||||
Returns the custom title bar widget set on the QDockWidget, or
|
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
|
Q_PROPERTY(Qt::DockWidgetAreas allowedAreas READ allowedAreas
|
||||||
WRITE setAllowedAreas NOTIFY allowedAreasChanged)
|
WRITE setAllowedAreas NOTIFY allowedAreasChanged)
|
||||||
Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true)
|
Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true)
|
||||||
|
Q_PROPERTY(Qt::DockWidgetArea dockLocation READ dockLocation WRITE setDockLocation
|
||||||
|
NOTIFY dockLocationChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QDockWidget(const QString &title, QWidget *parent = nullptr,
|
explicit QDockWidget(const QString &title, QWidget *parent = nullptr,
|
||||||
@ -61,6 +63,9 @@ public:
|
|||||||
void setTitleBarWidget(QWidget *widget);
|
void setTitleBarWidget(QWidget *widget);
|
||||||
QWidget *titleBarWidget() const;
|
QWidget *titleBarWidget() const;
|
||||||
|
|
||||||
|
void setDockLocation(Qt::DockWidgetArea area);
|
||||||
|
Qt::DockWidgetArea dockLocation() const;
|
||||||
|
|
||||||
inline bool isAreaAllowed(Qt::DockWidgetArea area) const
|
inline bool isAreaAllowed(Qt::DockWidgetArea area) const
|
||||||
{ return (allowedAreas() & area) == area; }
|
{ return (allowedAreas() & area) == area; }
|
||||||
|
|
||||||
|
@ -1037,8 +1037,11 @@ void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
const Qt::DockWidgetArea oldArea = dockWidgetArea(dockwidget);
|
||||||
d_func()->layout->removeWidget(dockwidget); // in case it was already in here
|
d_func()->layout->removeWidget(dockwidget); // in case it was already in here
|
||||||
addDockWidget(area, dockwidget, orientation);
|
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;
|
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,
|
void QMainWindowLayout::addDockWidget(Qt::DockWidgetArea area,
|
||||||
QDockWidget *dockwidget,
|
QDockWidget *dockwidget,
|
||||||
Qt::Orientation orientation)
|
Qt::Orientation orientation)
|
||||||
@ -1722,7 +1726,6 @@ void QMainWindowLayout::addDockWidget(Qt::DockWidgetArea area,
|
|||||||
endSeparatorMove(movingSeparatorPos);
|
endSeparatorMove(movingSeparatorPos);
|
||||||
|
|
||||||
layoutState.dockAreaLayout.addDockWidget(toDockPos(area), dockwidget, orientation);
|
layoutState.dockAreaLayout.addDockWidget(toDockPos(area), dockwidget, orientation);
|
||||||
emit dockwidget->dockLocationChanged(area);
|
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,6 +756,12 @@ void tst_QDockWidget::updateTabBarOnVisibilityChanged()
|
|||||||
|
|
||||||
Q_DECLARE_METATYPE(Qt::DockWidgetArea)
|
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()
|
void tst_QDockWidget::dockLocationChanged()
|
||||||
{
|
{
|
||||||
qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea");
|
qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea");
|
||||||
@ -763,61 +769,66 @@ void tst_QDockWidget::dockLocationChanged()
|
|||||||
QMainWindow mw;
|
QMainWindow mw;
|
||||||
QDockWidget dw;
|
QDockWidget dw;
|
||||||
dw.setObjectName("dock1");
|
dw.setObjectName("dock1");
|
||||||
QSignalSpy spy(&dw, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)));
|
QSignalSpy spy(&dw, &QDockWidget::dockLocationChanged);
|
||||||
|
|
||||||
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
|
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(spy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
QCOMPARE(dockLocation(&spy), Qt::LeftDockWidgetArea);
|
||||||
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();
|
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();
|
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;
|
QDockWidget dw2;
|
||||||
dw2.setObjectName("dock2");
|
dw2.setObjectName("dock2");
|
||||||
mw.addDockWidget(Qt::TopDockWidgetArea, &dw2);
|
mw.addDockWidget(Qt::TopDockWidgetArea, &dw2);
|
||||||
mw.tabifyDockWidget(&dw2, &dw);
|
mw.tabifyDockWidget(&dw2, &dw);
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(spy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||||
Qt::TopDockWidgetArea);
|
|
||||||
spy.clear();
|
spy.clear();
|
||||||
|
|
||||||
mw.splitDockWidget(&dw2, &dw, Qt::Horizontal);
|
mw.splitDockWidget(&dw2, &dw, Qt::Horizontal);
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(spy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||||
Qt::TopDockWidgetArea);
|
|
||||||
spy.clear();
|
spy.clear();
|
||||||
|
|
||||||
dw.setFloating(true);
|
dw.setFloating(true);
|
||||||
QTRY_COMPARE(spy.size(), 1);
|
QTRY_COMPARE(spy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
QCOMPARE(dockLocation(&spy), Qt::NoDockWidgetArea);
|
||||||
Qt::NoDockWidgetArea);
|
|
||||||
spy.clear();
|
spy.clear();
|
||||||
|
|
||||||
dw.setFloating(false);
|
dw.setFloating(false);
|
||||||
QTRY_COMPARE(spy.size(), 1);
|
QTRY_COMPARE(spy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||||
Qt::TopDockWidgetArea);
|
|
||||||
spy.clear();
|
spy.clear();
|
||||||
|
|
||||||
QByteArray ba = mw.saveState();
|
QByteArray ba = mw.saveState();
|
||||||
mw.restoreState(ba);
|
mw.restoreState(ba);
|
||||||
QCOMPARE(spy.size(), 1);
|
QCOMPARE(spy.size(), 1);
|
||||||
QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)),
|
QCOMPARE(dockLocation(&spy), Qt::TopDockWidgetArea);
|
||||||
Qt::TopDockWidgetArea);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QDockWidget::setTitleBarWidget()
|
void tst_QDockWidget::setTitleBarWidget()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user