From c300ff48bcba3140e0019fc748c3e41c85fb9f53 Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Mon, 28 May 2007 05:46:24 +0000 Subject: [PATCH] keep track of what layout we belong to so that we can remove ourselves from the layout when we exit; prevents crashes when items are added then deleted later. since we aren't guaranteed a QObject, we can't do the obvious thing (e.g. listen for the destroyed() signal) svn path=/trunk/KDE/kdebase/workspace/plasma/lib/; revision=668928 --- widgets/layoutitem.cpp | 35 ++++++++++++--- widgets/layoutitem.h | 37 +++++++++------- widgets/vboxlayout.cpp | 96 ++++++++++++++++++++++++------------------ widgets/vboxlayout.h | 1 + 4 files changed, 106 insertions(+), 63 deletions(-) diff --git a/widgets/layoutitem.cpp b/widgets/layoutitem.cpp index 05cb1f494..05356182a 100644 --- a/widgets/layoutitem.cpp +++ b/widgets/layoutitem.cpp @@ -17,26 +17,37 @@ */ #include "layoutitem.h" +#include "layout.h" namespace Plasma { class LayoutItem::Private { - public: - Private() {} - ~Private() {} + public: + Private() + : layout(0) + { + } + + ~Private() {} + + Layout* layout; }; LayoutItem::LayoutItem() - : d(new Private) + : d(new Private) { } LayoutItem::~LayoutItem() { - delete d; + if (d->layout) { + d->layout->removeItem(this); + } + + delete d; } bool LayoutItem::hasHeightForWidth() const @@ -59,4 +70,18 @@ qreal LayoutItem::widthForHeight(qreal h) const return 0.0; } +void LayoutItem::setLayout(Layout* layout) +{ + if (d->layout) { + d->layout->removeItem(this); + } + + d->layout = layout; +} + +Layout* LayoutItem::layout() +{ + return d->layout; +} + } diff --git a/widgets/layoutitem.h b/widgets/layoutitem.h index 4d4404b86..f8db42c06 100644 --- a/widgets/layoutitem.h +++ b/widgets/layoutitem.h @@ -27,34 +27,39 @@ namespace Plasma { +class Layout; + /** * Base class for Plasma layout-managed items */ class KDE_EXPORT LayoutItem { - public: - LayoutItem(); - virtual ~LayoutItem(); + public: + LayoutItem(); + virtual ~LayoutItem(); - virtual Qt::Orientations expandingDirections() const = 0; + virtual Qt::Orientations expandingDirections() const = 0; - virtual QSizeF minimumSize() const = 0; - virtual QSizeF maximumSize() const = 0; + virtual QSizeF minimumSize() const = 0; + virtual QSizeF maximumSize() const = 0; - virtual bool hasHeightForWidth() const; - virtual qreal heightForWidth(qreal w) const; + virtual bool hasHeightForWidth() const; + virtual qreal heightForWidth(qreal w) const; - virtual bool hasWidthForHeight() const; - virtual qreal widthForHeight(qreal h) const; + virtual bool hasWidthForHeight() const; + virtual qreal widthForHeight(qreal h) const; - virtual QRectF geometry() const = 0; - virtual void setGeometry(const QRectF& geometry) = 0; + virtual QRectF geometry() const = 0; + virtual void setGeometry(const QRectF& geometry) = 0; - virtual QSizeF sizeHint() const = 0; + virtual QSizeF sizeHint() const = 0; - private: - class Private; - Private *const d; + void setLayout(Layout* layout); + Layout* layout(); + + private: + class Private; + Private *const d; }; } diff --git a/widgets/vboxlayout.cpp b/widgets/vboxlayout.cpp index caac8abf5..bc125273a 100644 --- a/widgets/vboxlayout.cpp +++ b/widgets/vboxlayout.cpp @@ -20,6 +20,8 @@ #include +#include + namespace Plasma { @@ -76,57 +78,53 @@ QRectF VBoxLayout::geometry() const void VBoxLayout::setGeometry(const QRectF& geometry) { - if(!geometry.isValid() || geometry.isEmpty()) { - qDebug("Invalid Geometry!"); + if (!geometry.isValid() || geometry.isEmpty()) { + kDebug() << "Invalid Geometry!" << endl; + return; + } - return; - } + qDebug("Geometry %p : %f, %f by %f, %f", this, geometry.x(), geometry.y(), geometry.width(), geometry.height()); - qDebug("Geometry %p : %f, %f by %f, %f", this, geometry.x(), geometry.y(), geometry.width(), geometry.height()); + QList childs; + QList expandingChilds; + QList sizes; + QSizeF available = geometry.size() - QSizeF(2 * margin(), 2 * margin()); - QList childs; - QList expandingChilds; - QList sizes; - QSizeF available = geometry.size() - QSizeF(2 * margin(), 2 * margin()); + foreach (LayoutItem *l, d->childList) { + kDebug() << "testing layout item " << l << endl; + if (l->expandingDirections() & Qt::Vertical) { + expandingChilds += l; + } else { - foreach(LayoutItem *l, d->childList) { + childs += l; + } + } - if(l->expandingDirections() & Qt::Vertical) { + foreach (LayoutItem *l, childs) { + QSizeF hint = l->sizeHint(); + sizes.insert(indexOf(l), QSizeF(available.width(), hint.height())); + available -= QSizeF(0.0, hint.height() + spacing()); + } - expandingChilds += l; - } else { + qreal expandHeight = (available.height() - ((expandingChilds.count() - 1) * spacing())) / expandingChilds.count(); - childs += l; - } - } + foreach (LayoutItem *l, expandingChilds) { - foreach(LayoutItem *l, childs) { + sizes.insert(indexOf(l),QSizeF(available.width(), expandHeight)); + } - QSizeF hint = l->sizeHint(); + QPointF start = geometry.topLeft(); + start += QPointF(margin(), spacing()); - sizes.insert(indexOf(l), QSizeF(available.width(), hint.height())); - available -= QSizeF(0.0, hint.height() + spacing()); - } + for (int i = 0; i < sizes.size(); i++) { - qreal expandHeight = (available.height() - ((expandingChilds.count() - 1) * spacing())) / expandingChilds.count(); + LayoutItem *l = itemAt(i); - foreach(LayoutItem *l, expandingChilds) { + l->setGeometry(QRectF(start, sizes[i])); + start += QPointF(0.0, sizes[i].height() + spacing()); + } - sizes.insert(indexOf(l),QSizeF(available.width(), expandHeight)); - } - - QPointF start = geometry.topLeft(); - start += QPointF(margin(), spacing()); - - for(int i = 0; i < sizes.size(); i++) { - - LayoutItem *l = itemAt(i); - - l->setGeometry(QRectF(start, sizes[i])); - start += QPointF(0.0, sizes[i].height() + spacing()); - } - - d->geometry = geometry; + d->geometry = geometry; } QSizeF VBoxLayout::sizeHint() const @@ -155,13 +153,27 @@ bool VBoxLayout::isEmpty() const return count() == 0; } +void VBoxLayout::insertItem(int index, LayoutItem *l) +{ + if (!l) { + return; + } + + l->setLayout(this); + d->childList.insert(index, l); + setGeometry(geometry()); +} + void VBoxLayout::addItem(LayoutItem *l) { - d->childList.append(l); + if (!l) { + return; + } - qDebug("Added Child LayoutItem : %p", l); - - setGeometry(geometry()); + l->setLayout(this); + d->childList.append(l); + qDebug("Added Child LayoutItem : %p", l); + setGeometry(geometry()); } void VBoxLayout::removeItem(LayoutItem *l) diff --git a/widgets/vboxlayout.h b/widgets/vboxlayout.h index 0a92adbbb..bcd80ffe9 100644 --- a/widgets/vboxlayout.h +++ b/widgets/vboxlayout.h @@ -57,6 +57,7 @@ class KDE_EXPORT VBoxLayout : public Layout bool isEmpty() const; + void insertItem(int index, LayoutItem *l); void addItem(LayoutItem *l); void removeItem(LayoutItem *l);