From 9c52d8f06798c2e52b2c4542453a421f1118559d Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Thu, 22 Nov 2007 05:11:06 +0000 Subject: [PATCH] actually make plasmoid removal work and harden the applet handle against the applet being removed from under it svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=739867 --- applethandle.cpp | 26 ++++++++++---- applethandle_p.h | 1 + containment.cpp | 92 +++++++++++++++++++++++++++++------------------- containment.h | 1 + 4 files changed, 77 insertions(+), 43 deletions(-) diff --git a/applethandle.cpp b/applethandle.cpp index b255a5298..3c0d7b925 100644 --- a/applethandle.cpp +++ b/applethandle.cpp @@ -77,12 +77,17 @@ AppletHandle::AppletHandle(Containment *parent, Applet *applet) } m_applet->setParentItem(this); + connect(m_applet, SIGNAL(destroyed(QObject*)), this, SLOT(appletDestroyed())); setAcceptsHoverEvents(true); startFading(FadeIn); } AppletHandle::~AppletHandle() { + if (!m_applet) { + return; + } + QRectF rect(m_applet->boundingRect()); QPointF center = rect.center(); @@ -162,7 +167,7 @@ void AppletHandle::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti break; } - if (m_applet->hasConfigurationInterface()) { + if (m_applet && m_applet->hasConfigurationInterface()) { painter->drawPixmap(point + shiftC, KIcon("configure").pixmap(ICON_SIZE, ICON_SIZE)); point += QPointF(0.0, ICON_SIZE + ICON_MARGIN); } @@ -187,7 +192,7 @@ AppletHandle::ButtonType AppletHandle::mapToButton(const QPointF &point) const QPolygonF activeArea = QPolygonF(QRectF(basePoint, QSizeF(ICON_SIZE, ICON_SIZE))); - if (m_applet->hasConfigurationInterface()) { + if (m_applet && m_applet->hasConfigurationInterface()) { if (activeArea.containsPoint(point, Qt::OddEvenFill)) { return ConfigureButton; } @@ -223,12 +228,12 @@ void AppletHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { ButtonType releasedAtButton = mapToButton(event->pos()); - if (event->button()==Qt::LeftButton && m_pressedButton==releasedAtButton) { - if (m_pressedButton==ConfigureButton) { + if (m_applet && event->button() == Qt::LeftButton && m_pressedButton==releasedAtButton) { + if (m_pressedButton == ConfigureButton) { //FIXME: Remove this call once the configuration management change was done m_containment->emitLaunchActivated(); m_applet->showConfigurationInterface(); - } else if (m_pressedButton==RemoveButton) { + } else if (m_pressedButton == RemoveButton) { Phase::self()->animateItem(m_applet, Phase::Disappear); forceDisappear(); } @@ -258,7 +263,10 @@ void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { static const qreal snapAngle = 3.14159 / 2.0; - if (m_pressedButton == MoveButton) { + if (!m_applet) { + QGraphicsItem::mouseMoveEvent(event); + } + else if (m_pressedButton == MoveButton) { QPointF delta = event->pos()-event->lastPos(); setPos(pos()+delta); } else if (m_pressedButton == RotateButton) { @@ -318,6 +326,12 @@ void AppletHandle::fadeAnimation(qreal progress) update(); } +void AppletHandle::appletDestroyed() +{ + m_applet = 0; + deleteLater(); +} + void AppletHandle::startFading(FadeType anim) { if (m_animId!=0) { diff --git a/applethandle_p.h b/applethandle_p.h index 4e2393e17..6e0021b8b 100644 --- a/applethandle_p.h +++ b/applethandle_p.h @@ -58,6 +58,7 @@ class AppletHandle : public QObject, public QGraphicsItem private Q_SLOTS: void fadeAnimation(qreal progress); + void appletDestroyed(); private: static const int HANDLE_WIDTH = 5; diff --git a/containment.cpp b/containment.cpp index 5cc823b9b..c4e842973 100644 --- a/containment.cpp +++ b/containment.cpp @@ -213,39 +213,39 @@ void Containment::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) desktopMenu.addAction(action); } } else { - bool hasEntries = false; - if (applet->hasConfigurationInterface()) { - QAction* configureApplet = new QAction(i18n("%1 Settings...", applet->name()), &desktopMenu); - connect(configureApplet, SIGNAL(triggered(bool)), - applet, SLOT(showConfigurationInterface())); - desktopMenu.addAction(configureApplet); - hasEntries = true; - } - - if (scene() && !static_cast(scene())->isImmutable()) { - QAction* closeApplet = new QAction(i18n("Remove this %1", applet->name()), &desktopMenu); - QVariant appletV; - appletV.setValue((QObject*)applet); - closeApplet->setData(appletV); - connect(closeApplet, SIGNAL(triggered(bool)), - this, SLOT(destroyApplet())); - desktopMenu.addAction(closeApplet); - hasEntries = true; - } - - QList actions = applet->contextActions(); - if (!actions.isEmpty()) { - desktopMenu.addSeparator(); - foreach(QAction* action, actions) { - desktopMenu.addAction(action); - } - hasEntries = true; - } - - if (!hasEntries) { - QGraphicsItem::contextMenuEvent(event); - kDebug() << "no entries"; - return; + bool hasEntries = false; + if (applet->hasConfigurationInterface()) { + QAction* configureApplet = new QAction(i18n("%1 Settings...", applet->name()), &desktopMenu); + connect(configureApplet, SIGNAL(triggered(bool)), + applet, SLOT(showConfigurationInterface())); + desktopMenu.addAction(configureApplet); + hasEntries = true; + } + + if (scene() && !static_cast(scene())->isImmutable()) { + QAction* closeApplet = new QAction(i18n("Remove this %1", applet->name()), &desktopMenu); + QVariant appletV; + appletV.setValue((QObject*)applet); + closeApplet->setData(appletV); + connect(closeApplet, SIGNAL(triggered(bool)), + this, SLOT(destroyApplet())); + desktopMenu.addAction(closeApplet); + hasEntries = true; + } + + QList actions = applet->contextActions(); + if (!actions.isEmpty()) { + desktopMenu.addSeparator(); + foreach(QAction* action, actions) { + desktopMenu.addAction(action); + } + hasEntries = true; + } + + if (!hasEntries) { + QGraphicsItem::contextMenuEvent(event); + kDebug() << "no entries"; + return; } } @@ -254,6 +254,18 @@ void Containment::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) desktopMenu.exec(event->screenPos()); } +void Containment::destroyApplet() +{ + QAction *action = qobject_cast(sender()); + + if (!action) { + return; + } + + Applet *applet = qobject_cast(action->data().value()); + Phase::self()->animateItem(applet, Phase::Disappear); +} + void Containment::setFormFactor(FormFactor formFactor) { if (d->formFactor == formFactor && layout()) { @@ -400,12 +412,18 @@ void Containment::appletDestroyed(QObject* object) void Containment::appletAnimationComplete(QGraphicsItem *item, Plasma::Phase::Animation anim) { if (anim == Phase::Disappear) { - if (item->parentItem() == this) { - Applet *applet = qgraphicsitem_cast(item); + QGraphicsItem *parent = item->parentItem(); - if (applet) { - applet->destroy(); + while (parent) { + if (parent == this) { + Applet *applet = qgraphicsitem_cast(item); + + if (applet) { + applet->destroy(); + } } + + parent = parent->parentItem(); } } else if (anim == Phase::Appear) { if (containmentType() == DesktopContainment) { diff --git a/containment.h b/containment.h index cb62ceb99..9f07846b5 100644 --- a/containment.h +++ b/containment.h @@ -283,6 +283,7 @@ class PLASMA_EXPORT Containment : public Applet private Q_SLOTS: void handleDisappeared(AppletHandle *handle); + void destroyApplet(); private: Q_DISABLE_COPY(Containment)