track QGraphicsWidgets in the offscreen layout as they get deleted; prevents a crash in the layout. QGraphicsLayout really ought to track this on its own, but it doesn't (problem is known upstream), so we work around it here.

thanks to asraniel for tracking down the culprit..

BUG:174411

svn path=/trunk/KDE/kdelibs/; revision=880873
This commit is contained in:
Aaron J. Seigo 2008-11-06 18:21:10 +00:00
parent 0cff180f7d
commit 0ebbab0cc1
2 changed files with 31 additions and 0 deletions

View File

@ -179,6 +179,8 @@ public:
return containment;
}
void offscreenWidgetDestroyed(QObject *);
Corona *q;
ImmutabilityType immutability;
QString mimetype;
@ -386,9 +388,35 @@ void Corona::addOffscreenWidget(QGraphicsWidget *widget)
d->offscreenLayout->addItem(widget, d->offscreenLayout->rowCount() + 1,
d->offscreenLayout->columnCount() + 1);
// this is lame: adding a widget to a layout and then deleting it
// doesn't automatically remove it from the layout, so we have to watch for that ourselves
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(offscreenWidgetDestroyed(QObject*)));
widget->update();
}
//FIXME: remove the offscreenWidgetDestroyed method when QGraphicsLayout no longer
// craps up when an item in the layout is deleted!
void CoronaPrivate::offscreenWidgetDestroyed(QObject *o)
{
if (!offscreenLayout) {
return;
}
// at this point, it's just a QObject, not a QGraphicsWidget, but we still need
// a pointer of the appropriate type.
// WARNING: DO NOT USE THE WIDGET POINTER FOR ANYTHING OTHER THAN POINTER COMPARISONS
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(o);
for (int i = 0; i < offscreenLayout->count(); i++) {
// we have to static_cast here as well, even though that's not overly correct
// or wonderful; but it's the best we can do as the item is no longer a
// QGraphicsWidget at this point, just a QObject
QGraphicsWidget *foundWidget = static_cast<QGraphicsWidget *>(offscreenLayout->itemAt(i));
if (foundWidget == widget) {
offscreenLayout->removeAt(i);
}
}
}
void Corona::removeOffscreenWidget(QGraphicsWidget *widget)
{
if (!d->offscreenLayout) {
@ -399,6 +427,8 @@ void Corona::removeOffscreenWidget(QGraphicsWidget *widget)
QGraphicsWidget *foundWidget = dynamic_cast<QGraphicsWidget*>(d->offscreenLayout->itemAt(i));
if (foundWidget == widget) {
d->offscreenLayout->removeAt(i);
disconnect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(offscreenWidgetDestroyed(QObject*)));
break;
}
}
}

View File

@ -250,6 +250,7 @@ private:
CoronaPrivate *const d;
Q_PRIVATE_SLOT(d, void containmentDestroyed(QObject*))
Q_PRIVATE_SLOT(d, void offscreenWidgetDestroyed(QObject *));
Q_PRIVATE_SLOT(d, void syncConfig())
friend class CoronaPrivate;