this started out as a self contained patch just to merge two actions, but rapidly got out of hand ;)

* default to no config interface for containments
* merge the Appearance Settings and Configure actions for containments
* be even more careful with about-to-be-deleted widget (d->transient) including giving them a fake-but-valid scratchpad of a KConfigGroup if requested after deletd
* replace some method calls with direct access to the private members

svn path=/trunk/KDE/kdelibs/; revision=914890
This commit is contained in:
Aaron J. Seigo 2009-01-22 00:00:16 +00:00
parent c2aeb35b54
commit 72d632a234
3 changed files with 70 additions and 65 deletions

View File

@ -135,9 +135,7 @@ Applet::Applet(QObject *parentObject, const QVariantList &args)
Applet::~Applet() Applet::~Applet()
{ {
if (d->transient) { if (!d->transient && d->extender) {
d->resetConfigurationObject();
} else if (d->extender) {
//This would probably be nicer if it was located in extender. But in it's dtor, this won't //This would probably be nicer if it was located in extender. But in it's dtor, this won't
//work since when that get's called, the applet's config() isn't accessible anymore. (same //work since when that get's called, the applet's config() isn't accessible anymore. (same
//problem with calling saveState(). Doing this in saveState() might be a possibility, but //problem with calling saveState(). Doing this in saveState() might be a possibility, but
@ -343,12 +341,20 @@ void Applet::saveState(KConfigGroup &group) const
KConfigGroup Applet::config(const QString &group) const KConfigGroup Applet::config(const QString &group) const
{ {
if (d->transient) {
return KConfigGroup(KGlobal::config(), "PlasmaTransientsConfig");
}
KConfigGroup cg = config(); KConfigGroup cg = config();
return KConfigGroup(&cg, group); return KConfigGroup(&cg, group);
} }
KConfigGroup Applet::config() const KConfigGroup Applet::config() const
{ {
if (d->transient) {
return KConfigGroup(KGlobal::config(), "PlasmaTransientsConfig");
}
if (d->isContainment) { if (d->isContainment) {
return *(d->mainConfigGroup()); return *(d->mainConfigGroup());
} }
@ -383,16 +389,10 @@ void Applet::destroy()
if (isContainment()) { if (isContainment()) {
d->cleanUpAndDelete(); d->cleanUpAndDelete();
} else { } else {
d->resetConfigurationObject();
connect(Animator::self(), SIGNAL(animationFinished(QGraphicsItem*,Plasma::Animator::Animation)), connect(Animator::self(), SIGNAL(animationFinished(QGraphicsItem*,Plasma::Animator::Animation)),
this, SLOT(appletAnimationComplete(QGraphicsItem*,Plasma::Animator::Animation))); this, SLOT(appletAnimationComplete(QGraphicsItem*,Plasma::Animator::Animation)));
Animator::self()->animateItem(this, Animator::DisappearAnimation); Animator::self()->animateItem(this, Animator::DisappearAnimation);
} }
Corona * corona = qobject_cast<Corona*>(scene());
if (corona) {
corona->requireConfigSync();
}
} }
bool Applet::destroyed() const bool Applet::destroyed() const
@ -412,7 +412,7 @@ void AppletPrivate::appletAnimationComplete(QGraphicsItem *item, Plasma::Animato
void AppletPrivate::selectItemToDestroy() void AppletPrivate::selectItemToDestroy()
{ {
//FIXME: this will not work nicely with multiple screens and being zoomed out! //FIXME: this will not work nicely with multiple screens and being zoomed out!
if (q->isContainment()) { if (isContainment) {
QGraphicsView *view = q->view(); QGraphicsView *view = q->view();
if (view && view->transform().isScaling() && if (view && view->transform().isScaling() &&
q->scene()->focusItem() != q) { q->scene()->focusItem() != q) {
@ -439,12 +439,12 @@ void AppletPrivate::updateRect(const QRectF &rect)
void AppletPrivate::cleanUpAndDelete() void AppletPrivate::cleanUpAndDelete()
{ {
//kDebug() << "???????????????? DESTROYING APPLET" << name() << " ???????????????????????????"; //kDebug() << "???????????????? DESTROYING APPLET" << q->name() << q->scene() << " ???????????????????????????";
QGraphicsWidget *parent = dynamic_cast<QGraphicsWidget *>(q->parentItem()); QGraphicsWidget *parent = dynamic_cast<QGraphicsWidget *>(q->parentItem());
//it probably won't matter, but right now if there are applethandles, *they* are the parent. //it probably won't matter, but right now if there are applethandles, *they* are the parent.
//not the containment. //not the containment.
//is the applet in a containment and is the containment have a layout? //is the applet in a containment and does the containment have a layout?
//if yes, we remove the applet in the layout //if yes, we remove the applet in the layout
if (parent && parent->layout()) { if (parent && parent->layout()) {
QGraphicsLayout *l = parent->layout(); QGraphicsLayout *l = parent->layout();
@ -460,6 +460,8 @@ void AppletPrivate::cleanUpAndDelete()
configLoader->setDefaults(); configLoader->setDefaults();
} }
resetConfigurationObject();
q->scene()->removeItem(q); q->scene()->removeItem(q);
q->deleteLater(); q->deleteLater();
} }
@ -632,7 +634,7 @@ bool Applet::isBusy() const
QString Applet::name() const QString Applet::name() const
{ {
if (isContainment()) { if (d->isContainment) {
if (!d->appletDescription.isValid()) { if (!d->appletDescription.isValid()) {
return i18n("Unknown Activity"); return i18n("Unknown Activity");
} }
@ -910,7 +912,7 @@ void Applet::flushPendingConstraintsEvents()
closeApplet->setVisible(unlocked); closeApplet->setVisible(unlocked);
closeApplet->setShortcutContext(Qt::WidgetShortcut); //don't clash with other views closeApplet->setShortcutContext(Qt::WidgetShortcut); //don't clash with other views
closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", name())); closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", name()));
if (isContainment()) { if (d->isContainment) {
closeApplet->setShortcut(QKeySequence("alt+d,alt+r")); closeApplet->setShortcut(QKeySequence("alt+d,alt+r"));
} else { } else {
closeApplet->setShortcut(QKeySequence("alt+d,r")); closeApplet->setShortcut(QKeySequence("alt+d,r"));
@ -969,7 +971,7 @@ void Applet::flushPendingConstraintsEvents()
if (c & Plasma::FormFactorConstraint) { if (c & Plasma::FormFactorConstraint) {
FormFactor f = formFactor(); FormFactor f = formFactor();
if (!isContainment() && f != Vertical && f != Horizontal) { if (!d->isContainment && f != Vertical && f != Horizontal) {
setBackgroundHints(d->backgroundHints | StandardBackground); setBackgroundHints(d->backgroundHints | StandardBackground);
} else if(d->backgroundHints & StandardBackground) { } else if(d->backgroundHints & StandardBackground) {
setBackgroundHints(d->backgroundHints ^ StandardBackground); setBackgroundHints(d->backgroundHints ^ StandardBackground);
@ -1011,7 +1013,7 @@ void Applet::flushPendingConstraintsEvents()
// now take care of constraints in special subclasses: Contaiment and PopupApplet // now take care of constraints in special subclasses: Contaiment and PopupApplet
Containment* containment = qobject_cast<Plasma::Containment*>(this); Containment* containment = qobject_cast<Plasma::Containment*>(this);
if (isContainment() && containment) { if (d->isContainment && containment) {
containment->d->containmentConstraintsEvent(c); containment->d->containmentConstraintsEvent(c);
} }
@ -1057,7 +1059,7 @@ void Applet::addAction(QString name, QAction *action)
void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
if (!d->started) { if (!d->started) {
kDebug() << "not started"; //kDebug() << "not started";
return; return;
} }
@ -1074,7 +1076,7 @@ void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW
} }
if (d->failed) { if (d->failed) {
kDebug() << "failed!"; //kDebug() << "failed!";
return; return;
} }
@ -1083,7 +1085,7 @@ void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW
QRect contentsRect = QRectF(QPointF(0, 0), QRect contentsRect = QRectF(QPointF(0, 0),
boundingRect().size()).adjusted(left, top, -right, -bottom).toRect(); boundingRect().size()).adjusted(left, top, -right, -bottom).toRect();
if (widget && isContainment()) { if (widget && d->isContainment) {
// note that the widget we get is actually the viewport of the view, not the view itself // note that the widget we get is actually the viewport of the view, not the view itself
View* v = qobject_cast<Plasma::View*>(widget->parent()); View* v = qobject_cast<Plasma::View*>(widget->parent());
Containment* c = qobject_cast<Plasma::Containment*>(this); Containment* c = qobject_cast<Plasma::Containment*>(this);
@ -1146,7 +1148,7 @@ FormFactor Applet::formFactor() const
Containment *Applet::containment() const Containment *Applet::containment() const
{ {
if (isContainment()) { if (d->isContainment) {
Containment *c = qobject_cast<Containment*>(const_cast<Applet*>(this)); Containment *c = qobject_cast<Containment*>(const_cast<Applet*>(this));
if (c) { if (c) {
return c; return c;
@ -1158,7 +1160,7 @@ Containment *Applet::containment() const
while (parent) { while (parent) {
Containment *possibleC = dynamic_cast<Containment*>(parent); Containment *possibleC = dynamic_cast<Containment*>(parent);
if (possibleC && possibleC->isContainment()) { if (possibleC && possibleC->Applet::d->isContainment) {
c = possibleC; c = possibleC;
break; break;
} }
@ -1288,17 +1290,17 @@ void Applet::setHasConfigurationInterface(bool hasInterface)
bool canConfig = unlocked || KAuthorized::authorize("PlasmaAllowConfigureWhenLocked"); bool canConfig = unlocked || KAuthorized::authorize("PlasmaAllowConfigureWhenLocked");
configAction->setVisible(canConfig); configAction->setVisible(canConfig);
configAction->setEnabled(canConfig); configAction->setEnabled(canConfig);
if (isContainment()) { if (d->isContainment) {
//FIXME containments don't seem to use this action any more //FIXME containments don't seem to use this action any more
//configAction->setShortcut(QKeySequence("ctrl+shift+s")); //configAction->setShortcut(QKeySequence("ctrl+shift+s"));
connect(configAction, SIGNAL(triggered()), this, SLOT(requestConfiguration()));
} else { } else {
configAction->setShortcut(QKeySequence("alt+d,s")); configAction->setShortcut(QKeySequence("alt+d,s"));
connect(configAction, SIGNAL(triggered(bool)), this, SLOT(showConfigurationInterface()));
} }
connect(configAction, SIGNAL(triggered(bool)),
this, SLOT(showConfigurationInterface()));
d->actions.addAction("configure", configAction); d->actions.addAction("configure", configAction);
} }
} else { } else if (!d->isContainment || !qobject_cast<Plasma::Containment*>(this)) {
d->actions.removeAction(configAction); d->actions.removeAction(configAction);
} }
} }
@ -1393,7 +1395,6 @@ void Applet::showConfigurationInterface()
return; return;
} }
const QString dialogId = QString("%1settings%2").arg(id()).arg(name());
KConfigDialog *dlg = KConfigDialog::exists(d->configDialogId()); KConfigDialog *dlg = KConfigDialog::exists(d->configDialogId());
if (dlg) { if (dlg) {
@ -1409,7 +1410,7 @@ void Applet::showConfigurationInterface()
return; return;
} }
KConfigDialog *dialog = new KConfigDialog(0, dialogId, d->configLoader); KConfigDialog *dialog = new KConfigDialog(0, d->configDialogId(), d->configLoader);
dialog->setWindowTitle(d->configWindowTitle()); dialog->setWindowTitle(d->configWindowTitle());
dialog->setAttribute(Qt::WA_DeleteOnClose, true); dialog->setAttribute(Qt::WA_DeleteOnClose, true);
@ -1813,6 +1814,9 @@ void AppletPrivate::setIsContainment(bool nowIsContainment)
isContainment = nowIsContainment; isContainment = nowIsContainment;
delete mainConfig;
mainConfig = 0;
Containment *c = qobject_cast<Containment*>(q); Containment *c = qobject_cast<Containment*>(q);
if (c) { if (c) {
if (isContainment) { if (isContainment) {
@ -1823,6 +1827,20 @@ void AppletPrivate::setIsContainment(bool nowIsContainment)
c->d->toolBox = 0; c->d->toolBox = 0;
} }
} }
QAction *configAction = actions.action("configure");
if (configAction) {
QObject::disconnect(configAction, SIGNAL(triggered()), q, SLOT(requestConfiguration()));
QObject::disconnect(configAction, SIGNAL(triggered(bool)), q, SLOT(showConfigurationInterface()));
if (nowIsContainment) {
//kDebug() << "I am a containment";
configAction->setShortcut(QKeySequence("ctrl+shift+s"));
QObject::connect(configAction, SIGNAL(triggered()), q, SLOT(requestConfiguration()));
} else {
configAction->setShortcut(QKeySequence("ctrl+s"));
QObject::connect(configAction, SIGNAL(triggered(bool)), q, SLOT(showConfigurationInterface()));
}
}
} }
bool Applet::isContainment() const bool Applet::isContainment() const
@ -2057,7 +2075,7 @@ KConfigGroup *AppletPrivate::mainConfigGroup()
if (isContainment) { if (isContainment) {
Corona *corona = qobject_cast<Corona*>(q->scene()); Corona *corona = qobject_cast<Corona*>(q->scene());
KConfigGroup containmentConfig; KConfigGroup containmentConfig;
//kDebug() << "got a corona, baby?" << (QObject*)corona; //kDebug() << "got a corona, baby?" << (QObject*)corona << (QObject*)q;
if (corona) { if (corona) {
containmentConfig = KConfigGroup(corona->config(), "Containments"); containmentConfig = KConfigGroup(corona->config(), "Containments");
@ -2131,6 +2149,11 @@ void AppletPrivate::resetConfigurationObject()
mainConfig->deleteGroup(); mainConfig->deleteGroup();
delete mainConfig; delete mainConfig;
mainConfig = 0; mainConfig = 0;
Corona * corona = qobject_cast<Corona*>(q->scene());
if (corona) {
corona->requireConfigSync();
}
} }
uint AppletPrivate::s_maxAppletId = 0; uint AppletPrivate::s_maxAppletId = 0;

View File

@ -97,6 +97,7 @@ Containment::Containment(QGraphicsItem *parent,
setPos(0, 0); setPos(0, 0);
setBackgroundHints(NoBackground); setBackgroundHints(NoBackground);
setContainmentType(CustomContainment); setContainmentType(CustomContainment);
setHasConfigurationInterface(false);
} }
Containment::Containment(QObject *parent, const QVariantList &args) Containment::Containment(QObject *parent, const QVariantList &args)
@ -107,15 +108,11 @@ Containment::Containment(QObject *parent, const QVariantList &args)
// that requires a scene, which is not available at this point // that requires a scene, which is not available at this point
setPos(0, 0); setPos(0, 0);
setBackgroundHints(NoBackground); setBackgroundHints(NoBackground);
setHasConfigurationInterface(false);
} }
Containment::~Containment() Containment::~Containment()
{ {
if (Applet::d->transient) {
Applet::d->resetConfigurationObject();
Applet::d->transient = false;
}
delete d; delete d;
} }
@ -151,16 +148,6 @@ void Containment::init()
appletBrowserAction->setShortcut(QKeySequence("alt+d,a")); appletBrowserAction->setShortcut(QKeySequence("alt+d,a"));
d->actions().addAction("add widgets", appletBrowserAction); d->actions().addAction("add widgets", appletBrowserAction);
QAction *configureActivityAction = new QAction(i18n("Appearance Settings"), this);
configureActivityAction->setIcon(KIcon("configure"));
bool canConfig = unlocked || KAuthorized::authorize("PlasmaAllowConfigureWhenLocked");
configureActivityAction->setVisible(canConfig);
configureActivityAction->setEnabled(canConfig);
connect(configureActivityAction, SIGNAL(triggered()), this, SLOT(requestConfiguration()));
appletBrowserAction->setShortcutContext(Qt::WidgetShortcut);
configureActivityAction->setShortcut(QKeySequence("alt+d,alt+s"));
d->actions().addAction("activity settings", configureActivityAction);
QAction *action = new QAction(i18n("Next Widget"), this); QAction *action = new QAction(i18n("Next Widget"), this);
//no icon //no icon
connect(action, SIGNAL(triggered()), this, SLOT(focusNextApplet())); connect(action, SIGNAL(triggered()), this, SLOT(focusNextApplet()));
@ -226,13 +213,13 @@ void Containment::init()
if (immutability() != SystemImmutable) { if (immutability() != SystemImmutable) {
d->toolBox->addTool(this->action("lock widgets")); d->toolBox->addTool(this->action("lock widgets"));
} }
d->toolBox->addTool(this->action("activity settings"));
if (hasConfigurationInterface()) { //TODO: do we need some way to allow this be overridden?
// re-use the contianment's action. // it's always available because shells rely on this
// to offer their own custom configuration as well
QAction *configureContainment = this->action("configure"); QAction *configureContainment = this->action("configure");
if (configureContainment) { if (configureContainment) {
d->toolBox->addTool(this->action("configure")); d->toolBox->addTool(configureContainment);
}
} }
} }
@ -304,6 +291,10 @@ void Containment::restore(KConfigGroup &group)
void Containment::save(KConfigGroup &g) const void Containment::save(KConfigGroup &g) const
{ {
if (Applet::d->transient) {
return;
}
KConfigGroup group = g; KConfigGroup group = g;
if (!group.isValid()) { if (!group.isValid()) {
group = config(); group = config();
@ -496,6 +487,8 @@ void ContainmentPrivate::containmentActions(KMenu &desktopMenu)
//find the separator to insert the activity settings before it //find the separator to insert the activity settings before it
QAction *separatorAction = 0; QAction *separatorAction = 0;
//TODO: should a submenu be created if there are too many containment specific
// actions? see folderview containment
foreach (QAction *action, actions) { foreach (QAction *action, actions) {
if (action) { if (action) {
desktopMenu.addAction(action); desktopMenu.addAction(action);
@ -507,15 +500,10 @@ void ContainmentPrivate::containmentActions(KMenu &desktopMenu)
desktopMenu.addSeparator(); desktopMenu.addSeparator();
//TODO: should a submenu be created if there are too many containment specific
// actions? see folderview containment
if (q->containmentType() == Containment::DesktopContainment) { if (q->containmentType() == Containment::DesktopContainment) {
desktopMenu.insertAction(separatorAction, q->action("activity settings"));
if (q->hasConfigurationInterface()) {
desktopMenu.addAction(q->action("configure")); desktopMenu.addAction(q->action("configure"));
} }
} }
}
void ContainmentPrivate::appletActions(KMenu &desktopMenu, Applet *applet, bool includeApplet) void ContainmentPrivate::appletActions(KMenu &desktopMenu, Applet *applet, bool includeApplet)
{ {
@ -1605,15 +1593,6 @@ void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constra
action->setIcon(KIcon(unlocked ? "object-locked" : "object-unlocked")); action->setIcon(KIcon(unlocked ? "object-locked" : "object-unlocked"));
} }
bool canConfig = unlocked || KAuthorized::authorize("PlasmaAllowConfigureWhenLocked");
if (canConfig) {
action = actions().action("activity settings");
if (action) {
action->setVisible(canConfig);
action->setEnabled(canConfig);
}
}
// tell the applets too // tell the applets too
foreach (Applet *a, applets) { foreach (Applet *a, applets) {
a->updateConstraints(ImmutableConstraint); a->updateConstraints(ImmutableConstraint);

View File

@ -204,6 +204,9 @@ Corona::Corona(QObject *parent)
Corona::~Corona() Corona::~Corona()
{ {
KConfigGroup trans(KGlobal::config(), "PlasmaTransientsConfig");
trans.deleteGroup();
// FIXME: Same fix as in Plasma::View - make sure that when the focused widget is // FIXME: Same fix as in Plasma::View - make sure that when the focused widget is
// destroyed we don't try to transfer it to something that's already been // destroyed we don't try to transfer it to something that's already been
// deleted. // deleted.