summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Arve Saether <jan-arve.saether@digia.com>2013-04-23 15:04:26 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-25 14:51:42 +0200
commitc0688f4117304b4828796aa9489ca2c0d50c9886 (patch)
treee361146557931854c8e8d46a2e2f2cfffcc54dff
parent17f263905f00dfd0f01d9f5226ac06b07aa9d421 (diff)
Fixed QLayout::addChildLayout(QLayout *l) when l had a parent
Previously if l had a parent, addChildLayout would warn and skip the reparenting, but it would still add the sub layout to the layout. This caused some inconsistencies in the hierarchy which in worst case could cause crashes. Task-number: QTBUG-30758 (cherry-picked from qtbase commit 146658a10f290603470b800d71b778239e764312) Change-Id: Iee6ace3189620395d7670007a23783823ed616b9 Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
-rw-r--r--src/gui/kernel/qboxlayout.cpp3
-rw-r--r--src/gui/kernel/qformlayout.cpp4
-rw-r--r--src/gui/kernel/qgridlayout.cpp6
-rw-r--r--src/gui/kernel/qlayout.cpp10
-rw-r--r--src/gui/kernel/qlayout.h1
-rw-r--r--tests/auto/qboxlayout/tst_qboxlayout.cpp21
6 files changed, 40 insertions, 5 deletions
diff --git a/src/gui/kernel/qboxlayout.cpp b/src/gui/kernel/qboxlayout.cpp
index 91393ed7e0..444cea22aa 100644
--- a/src/gui/kernel/qboxlayout.cpp
+++ b/src/gui/kernel/qboxlayout.cpp
@@ -1001,7 +1001,8 @@ void QBoxLayout::insertSpacerItem(int index, QSpacerItem *spacerItem)
void QBoxLayout::insertLayout(int index, QLayout *layout, int stretch)
{
Q_D(QBoxLayout);
- addChildLayout(layout);
+ if (!adoptLayout(layout))
+ return;
if (index < 0) // append
index = d->list.count();
QBoxLayoutItem *it = new QBoxLayoutItem(layout, stretch);
diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp
index ba88211983..8f97d1cfb0 100644
--- a/src/gui/kernel/qformlayout.cpp
+++ b/src/gui/kernel/qformlayout.cpp
@@ -976,8 +976,8 @@ void QFormLayoutPrivate::setLayout(int row, QFormLayout::ItemRole role, QLayout
{
if (layout) {
Q_Q(QFormLayout);
- q->addChildLayout(layout);
- setItem(row, role, layout);
+ if (q->adoptLayout(layout))
+ setItem(row, role, layout);
}
}
diff --git a/src/gui/kernel/qgridlayout.cpp b/src/gui/kernel/qgridlayout.cpp
index c9550de7dc..731d5cd9fc 100644
--- a/src/gui/kernel/qgridlayout.cpp
+++ b/src/gui/kernel/qgridlayout.cpp
@@ -1609,7 +1609,8 @@ void QGridLayout::addWidget(QWidget *widget, int fromRow, int fromColumn,
void QGridLayout::addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment)
{
Q_D(QGridLayout);
- addChildLayout(layout);
+ if (!adoptLayout(layout))
+ return;
QGridBox *b = new QGridBox(layout);
b->setAlignment(alignment);
d->add(b, row, column);
@@ -1628,7 +1629,8 @@ void QGridLayout::addLayout(QLayout *layout, int row, int column,
int rowSpan, int columnSpan, Qt::Alignment alignment)
{
Q_D(QGridLayout);
- addChildLayout(layout);
+ if (!adoptLayout(layout))
+ return;
QGridBox *b = new QGridBox(layout);
b->setAlignment(alignment);
d->add(b, row, (rowSpan < 0) ? -1 : row + rowSpan - 1, column, (columnSpan < 0) ? -1 : column + columnSpan - 1);
diff --git a/src/gui/kernel/qlayout.cpp b/src/gui/kernel/qlayout.cpp
index 1f7b34c3b2..ce8322bca9 100644
--- a/src/gui/kernel/qlayout.cpp
+++ b/src/gui/kernel/qlayout.cpp
@@ -935,6 +935,16 @@ void QLayout::addChildLayout(QLayout *l)
}
+/*!
+ \internal
+ */
+bool QLayout::adoptLayout(QLayout *layout)
+{
+ const bool ok = !layout->parent();
+ addChildLayout(layout);
+ return ok;
+}
+
#ifdef QT_DEBUG
static bool layoutDebug()
{
diff --git a/src/gui/kernel/qlayout.h b/src/gui/kernel/qlayout.h
index d4a79d98d2..09f0e336d8 100644
--- a/src/gui/kernel/qlayout.h
+++ b/src/gui/kernel/qlayout.h
@@ -189,6 +189,7 @@ protected:
void childEvent(QChildEvent *e);
void addChildLayout(QLayout *l);
void addChildWidget(QWidget *w);
+ bool adoptLayout(QLayout *layout);
#ifdef QT3_SUPPORT
QT3_SUPPORT void deleteAllItems();
#endif
diff --git a/tests/auto/qboxlayout/tst_qboxlayout.cpp b/tests/auto/qboxlayout/tst_qboxlayout.cpp
index 0f9bbce2d8..466be31bf8 100644
--- a/tests/auto/qboxlayout/tst_qboxlayout.cpp
+++ b/tests/auto/qboxlayout/tst_qboxlayout.cpp
@@ -62,6 +62,7 @@ public slots:
private slots:
void insertSpacerItem();
+ void insertLayout();
void sizeHint();
void sizeConstraints();
void setGeometry();
@@ -160,6 +161,26 @@ void tst_QBoxLayout::insertSpacerItem()
window->show();
}
+void tst_QBoxLayout::insertLayout()
+{
+ QWidget *window = new QWidget;
+ QVBoxLayout *vbox = new QVBoxLayout(window);
+ QVBoxLayout *dummyParentLayout = new QVBoxLayout;
+ QHBoxLayout *subLayout = new QHBoxLayout;
+ dummyParentLayout->addLayout(subLayout);
+ QCOMPARE(subLayout->parent(), dummyParentLayout);
+ QCOMPARE(dummyParentLayout->count(), 1);
+
+ // add subLayout to another layout
+ QTest::ignoreMessage(QtWarningMsg, "QLayout::addChildLayout: layout \"\" already has a parent");
+ vbox->addLayout(subLayout);
+ QCOMPARE((subLayout->parent() == vbox), (vbox->count() == 1));
+
+ delete dummyParentLayout;
+ delete window;
+}
+
+
void tst_QBoxLayout::sizeHint()
{
QWidget *window = new QWidget;