e weakpointers for the animated pages: avoids crashes when a tab gets removed and immeadiately added another one (happens when switching activity type for instance)

svn path=/trunk/KDE/kdelibs/; revision=1127865
This commit is contained in:
Marco Martin 2010-05-17 20:46:35 +00:00
parent 610b3c85df
commit 325d6a7c67

View File

@ -75,8 +75,6 @@ public:
tabProxy(0), tabProxy(0),
currentIndex(0), currentIndex(0),
tabWidgetMode(true), tabWidgetMode(true),
oldPage(0),
newPage(0),
oldPageAnimId(-1), oldPageAnimId(-1),
newPageAnimId(-1), newPageAnimId(-1),
customFont(false) customFont(false)
@ -103,8 +101,8 @@ public:
int currentIndex; int currentIndex;
bool tabWidgetMode; bool tabWidgetMode;
QGraphicsWidget *oldPage; QWeakPointer<QGraphicsWidget>oldPage;
QGraphicsWidget *newPage; QWeakPointer<QGraphicsWidget>newPage;
int oldPageAnimId; int oldPageAnimId;
int newPageAnimId; int newPageAnimId;
Animation *oldPageAnim; Animation *oldPageAnim;
@ -155,7 +153,9 @@ void TabBarPrivate::updateTabWidgetMode()
void TabBarPrivate::slidingNewPageCompleted() void TabBarPrivate::slidingNewPageCompleted()
{ {
tabWidgetLayout->addItem(newPage); if (newPage) {
tabWidgetLayout->addItem(newPage.data());
}
newPageAnimId = -1; newPageAnimId = -1;
mainLayout->invalidate(); mainLayout->invalidate();
emit q->currentChanged(currentIndex); emit q->currentChanged(currentIndex);
@ -366,16 +366,12 @@ void TabBar::setCurrentIndex(int index)
if (d->currentIndex >= 0) { if (d->currentIndex >= 0) {
d->oldPage = d->pages[d->currentIndex]; d->oldPage = d->pages[d->currentIndex];
} else {
d->oldPage = 0;
} }
d->tabWidgetLayout->removeItem(d->oldPage); d->tabWidgetLayout->removeItem(d->oldPage.data());
if (index >= 0) { if (index >= 0) {
d->newPage = d->pages[index]; d->newPage = d->pages[index];
} else {
d->newPage = 0;
} }
setFlags(QGraphicsItem::ItemClipsChildrenToShape); setFlags(QGraphicsItem::ItemClipsChildrenToShape);
@ -390,49 +386,49 @@ void TabBar::setCurrentIndex(int index)
} }
if (d->newPage) { if (d->newPage) {
d->newPage->show(); d->newPage.data()->show();
d->newPage->setEnabled(true); d->newPage.data()->setEnabled(true);
} }
if (d->oldPage) { if (d->oldPage) {
d->oldPage->show(); d->oldPage.data()->show();
d->oldPage->setEnabled(false); d->oldPage.data()->setEnabled(false);
} }
if (d->newPage && d->oldPage) { if (d->newPage && d->oldPage) {
//FIXME: it seems necessary to resiz the thing 2 times to have effect //FIXME: it seems necessary to resiz the thing 2 times to have effect
d->newPage->resize(1,1); d->newPage.data()->resize(1,1);
d->newPage->resize(d->oldPage->size()); d->newPage.data()->resize(d->oldPage.data()->size());
QRect beforeCurrentGeom(d->oldPage->geometry().toRect()); QRect beforeCurrentGeom(d->oldPage.data()->geometry().toRect());
beforeCurrentGeom.moveTopRight(beforeCurrentGeom.topLeft()); beforeCurrentGeom.moveTopRight(beforeCurrentGeom.topLeft());
if (index > d->currentIndex) { if (index > d->currentIndex) {
d->newPage->setPos(d->oldPage->geometry().topRight()); d->newPage.data()->setPos(d->oldPage.data()->geometry().topRight());
d->newPageAnim->setProperty("movementDirection", Animation::MoveAny); d->newPageAnim->setProperty("movementDirection", Animation::MoveAny);
d->newPageAnim->setProperty("distancePointF", d->oldPage->pos()); d->newPageAnim->setProperty("distancePointF", d->oldPage.data()->pos());
d->newPageAnim->setTargetWidget(d->newPage); d->newPageAnim->setTargetWidget(d->newPage.data());
d->oldPageAnim->setProperty("movementDirection", Animation::MoveAny); d->oldPageAnim->setProperty("movementDirection", Animation::MoveAny);
d->oldPageAnim->setProperty("distancePointF", beforeCurrentGeom.topLeft()); d->oldPageAnim->setProperty("distancePointF", beforeCurrentGeom.topLeft());
d->oldPageAnim->setTargetWidget(d->oldPage); d->oldPageAnim->setTargetWidget(d->oldPage.data());
d->animGroup->start(); d->animGroup->start();
} else { } else {
d->newPage->setPos(beforeCurrentGeom.topLeft()); d->newPage.data()->setPos(beforeCurrentGeom.topLeft());
d->newPageAnim->setProperty("movementDirection", Animation::MoveAny); d->newPageAnim->setProperty("movementDirection", Animation::MoveAny);
d->newPageAnim->setProperty("distancePointF", d->oldPage->pos()); d->newPageAnim->setProperty("distancePointF", d->oldPage.data()->pos());
d->newPageAnim->setTargetWidget(d->newPage); d->newPageAnim->setTargetWidget(d->newPage.data());
d->oldPageAnim->setProperty("movementDirection", Animation::MoveAny); d->oldPageAnim->setProperty("movementDirection", Animation::MoveAny);
d->oldPageAnim->setProperty("distancePointF", d->oldPageAnim->setProperty("distancePointF",
d->oldPage->geometry().topRight()); d->oldPage.data()->geometry().topRight());
d->oldPageAnim->setTargetWidget(d->oldPage); d->oldPageAnim->setTargetWidget(d->oldPage.data());
d->animGroup->start(); d->animGroup->start();
} }
} else { } else if (d->newPage) {
d->tabWidgetLayout->addItem(d->newPage); d->tabWidgetLayout->addItem(d->newPage.data());
} }
d->currentIndex = index; d->currentIndex = index;
@ -447,10 +443,13 @@ int TabBar::count() const
void TabBar::removeTab(int index) void TabBar::removeTab(int index)
{ {
if (index >= d->pages.count()) { if (index >= d->pages.count() || index < 0) {
return; return;
} }
d->newPageAnim->stop();
d->oldPageAnim->stop();
int oldCurrentIndex = d->tabProxy->native->currentIndex(); int oldCurrentIndex = d->tabProxy->native->currentIndex();
d->tabProxy->native->removeTab(index); d->tabProxy->native->removeTab(index);
QGraphicsWidget *page = d->pages.takeAt(index); QGraphicsWidget *page = d->pages.takeAt(index);