diff options
author | Thorbjørn Lund Martsum <tmartsum@gmail.com> | 2012-09-03 06:35:39 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-21 23:17:55 +0200 |
commit | 42d681f9cfc984046a93b9efe19903d46ac68bb1 (patch) | |
tree | 0a93a177458dc661b9ceb200f8fa21250b6b601f /src/widgets/kernel | |
parent | e327ba191df56f3315a004d7650d5f1080f12acb (diff) |
Add widget replace function to QLayout
Sometimes it is nice to be able to replace a widget in a layout.
Change-Id: I23a6a65e417e94d53bc48639503db1a142bc3f10
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/qboxlayout.cpp | 16 | ||||
-rw-r--r-- | src/widgets/kernel/qformlayout.cpp | 27 | ||||
-rw-r--r-- | src/widgets/kernel/qgridlayout.cpp | 13 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.cpp | 48 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout_p.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qstackedlayout.cpp | 18 |
7 files changed, 125 insertions, 0 deletions
diff --git a/src/widgets/kernel/qboxlayout.cpp b/src/widgets/kernel/qboxlayout.cpp index d0e7a16999..67621ade23 100644 --- a/src/widgets/kernel/qboxlayout.cpp +++ b/src/widgets/kernel/qboxlayout.cpp @@ -140,6 +140,7 @@ public: void calcHfw(int); void effectiveMargins(int *left, int *top, int *right, int *bottom) const; + QLayoutItem* replaceAt(int index, QLayoutItem*) Q_DECL_OVERRIDE; }; QBoxLayoutPrivate::~QBoxLayoutPrivate() @@ -444,6 +445,21 @@ void QBoxLayoutPrivate::calcHfw(int w) hfwMinHeight = mh; } +QLayoutItem* QBoxLayoutPrivate::replaceAt(int index, QLayoutItem *item) +{ + Q_Q(QBoxLayout); + if (!item) + return 0; + QBoxLayoutItem *b = list.value(index); + if (!b) + return 0; + QLayoutItem *r = b->item; + + b->item = item; + q->invalidate(); + return r; +} + /*! \class QBoxLayout diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index fd6482d5af..e1376c754f 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -246,6 +246,7 @@ public: int hSpacing; int vSpacing; + QLayoutItem* replaceAt(int index, QLayoutItem*) Q_DECL_OVERRIDE; }; QFormLayoutPrivate::QFormLayoutPrivate() @@ -1001,6 +1002,32 @@ QStyle* QFormLayoutPrivate::getStyle() const return QApplication::style(); } +QLayoutItem* QFormLayoutPrivate::replaceAt(int index, QLayoutItem *newitem) +{ + Q_Q(QFormLayout); + if (!newitem) + return 0; + const int storageIndex = storageIndexFromLayoutItem(m_matrix, m_things.value(index)); + if (storageIndex == -1) { + // ### Qt6 - fix warning too when this class becomes public + qWarning("QFormLayoutPrivate::replaceAt: Invalid index %d", index); + return 0; + } + + int row, col; + QFormLayoutPrivate::ItemMatrix::storageIndexToPosition(storageIndex, &row, &col); + Q_ASSERT(m_matrix(row, col)); + + QFormLayoutItem *item = m_matrix(row, col); + Q_ASSERT(item); + + QLayoutItem *olditem = item->item; + item->item = newitem; + + q->invalidate(); + return olditem; +} + /*! \class QFormLayout \since 4.4 diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index 96820e3891..7da2104971 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -85,6 +85,7 @@ public: void setGeometry(const QRect &r) { item_->setGeometry(r); } Qt::Alignment alignment() const { return item_->alignment(); } QLayoutItem *item() { return item_; } + void setItem(QLayoutItem *newitem) { item_ = newitem; } QLayoutItem *takeItem() { QLayoutItem *i = item_; item_ = 0; return i; } int hStretch() { return item_->widget() ? @@ -171,6 +172,18 @@ public: } return 0; } + QLayoutItem* replaceAt(int index, QLayoutItem *newitem) Q_DECL_OVERRIDE + { + if (!newitem) + return 0; + QLayoutItem *item = 0; + QGridBox *b = things.value(index); + if (b) { + item = b->takeItem(); + b->setItem(newitem); + } + return item; + } void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) const { if (index < things.count()) { diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 8541dd984d..b79a6fe6c7 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -1109,6 +1109,54 @@ bool QLayout::activate() } /*! + \since 5.2 + + Searches for widget \a from and replaces it with widget \a to if found. + Returns the layout item that contains the widget \a from on success. Otherwise \c 0 is returned. + If \a recursive is \c true, sub-layouts are searched for doing the replacement. Notice that the returned item therefore might not belong to this layout, but to a sub-layout. + + The returned layout item is no longer owned by the layout and should be either deleted or inserted to another layout. The widget \a from is no longer managed by the layout and may need to be deleted or hidden. The parent of widget \a from is left unchanged. + + This function works for the built-in Qt layouts, but might not work for custom layouts. + + \sa indexOf() +*/ + +//### Qt 6 make this function virtual +QLayoutItem* QLayout::replaceWidget(QWidget *from, QWidget *to, bool recursive) +{ + Q_D(QLayout); + if (!from || !to) + return 0; + + int index = -1; + QLayoutItem *item = 0; + for (int u = 0; u < count(); ++u) { + item = itemAt(u); + if (item->widget() == from) { + index = u; + break; + } + if (item && item->layout() && recursive) { + QLayoutItem *r = item->layout()->replaceWidget(from, to, true); + if (r) + return r; + } + } + if (index == -1) + return 0; + + QLayoutItem *newitem = new QWidgetItem(to); + newitem->setAlignment(item->alignment()); + QLayoutItem *r = d->replaceAt(index, newitem); + if (!r) + delete newitem; + else + addChildWidget(to); + return r; +} + +/*! \fn QLayoutItem *QLayout::itemAt(int index) const Must be implemented in subclasses to return the layout item at \a diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index 6f43c2b28a..ca5f6d42ea 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -130,6 +130,7 @@ public: virtual int count() const = 0; bool isEmpty() const; QSizePolicy::ControlTypes controlTypes() const; + QLayoutItem* replaceWidget(QWidget *from, QWidget *to, bool recursive = true); int totalHeightForWidth(int w) const; QSize totalMinimumSize() const; diff --git a/src/widgets/kernel/qlayout_p.h b/src/widgets/kernel/qlayout_p.h index 9321bfc0dc..2100d86aba 100644 --- a/src/widgets/kernel/qlayout_p.h +++ b/src/widgets/kernel/qlayout_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QWidgetItem; class QSpacerItem; +class QLayoutItem; class Q_WIDGETS_EXPORT QLayoutPrivate : public QObjectPrivate { @@ -78,6 +79,7 @@ public: static QWidgetItem *createWidgetItem(const QLayout *layout, QWidget *widget); static QSpacerItem *createSpacerItem(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy = QSizePolicy::Minimum, QSizePolicy::Policy vPolicy = QSizePolicy::Minimum); + virtual QLayoutItem* replaceAt(int index, QLayoutItem *newitem) { Q_UNUSED(index); Q_UNUSED(newitem); return 0; } static QWidgetItemFactoryMethod widgetItemFactoryMethod; static QSpacerItemFactoryMethod spacerItemFactoryMethod; diff --git a/src/widgets/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp index 9514877e50..316103b097 100644 --- a/src/widgets/kernel/qstackedlayout.cpp +++ b/src/widgets/kernel/qstackedlayout.cpp @@ -53,11 +53,29 @@ class QStackedLayoutPrivate : public QLayoutPrivate Q_DECLARE_PUBLIC(QStackedLayout) public: QStackedLayoutPrivate() : index(-1), stackingMode(QStackedLayout::StackOne) {} + QLayoutItem* replaceAt(int index, QLayoutItem *newitem) Q_DECL_OVERRIDE; QList<QLayoutItem *> list; int index; QStackedLayout::StackingMode stackingMode; }; +QLayoutItem* QStackedLayoutPrivate::replaceAt(int idx, QLayoutItem *newitem) +{ + Q_Q(QStackedLayout); + if (idx < 0 || idx >= list.size() || !newitem) + return 0; + QWidget *wdg = newitem->widget(); + if (!wdg) { + qWarning("QStackedLayout::replaceAt: Only widgets can be added"); + return 0; + } + QLayoutItem *orgitem = list.at(idx); + list.replace(idx, newitem); + if (idx == index) + q->setCurrentIndex(index); + return orgitem; +} + /*! \class QStackedLayout |