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()
{
if (d->transient) {
d->resetConfigurationObject();
} else if (d->extender) {
if (!d->transient && d->extender) {
//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
//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
{
if (d->transient) {
return KConfigGroup(KGlobal::config(), "PlasmaTransientsConfig");
}
KConfigGroup cg = config();
return KConfigGroup(&cg, group);
}
KConfigGroup Applet::config() const
{
if (d->transient) {
return KConfigGroup(KGlobal::config(), "PlasmaTransientsConfig");
}
if (d->isContainment) {
return *(d->mainConfigGroup());
}
@ -383,16 +389,10 @@ void Applet::destroy()
if (isContainment()) {
d->cleanUpAndDelete();
} else {
d->resetConfigurationObject();
connect(Animator::self(), SIGNAL(animationFinished(QGraphicsItem*,Plasma::Animator::Animation)),
this, SLOT(appletAnimationComplete(QGraphicsItem*,Plasma::Animator::Animation)));
Animator::self()->animateItem(this, Animator::DisappearAnimation);
}
Corona * corona = qobject_cast<Corona*>(scene());
if (corona) {
corona->requireConfigSync();
}
}
bool Applet::destroyed() const
@ -412,7 +412,7 @@ void AppletPrivate::appletAnimationComplete(QGraphicsItem *item, Plasma::Animato
void AppletPrivate::selectItemToDestroy()
{
//FIXME: this will not work nicely with multiple screens and being zoomed out!
if (q->isContainment()) {
if (isContainment) {
QGraphicsView *view = q->view();
if (view && view->transform().isScaling() &&
q->scene()->focusItem() != q) {
@ -439,12 +439,12 @@ void AppletPrivate::updateRect(const QRectF &rect)
void AppletPrivate::cleanUpAndDelete()
{
//kDebug() << "???????????????? DESTROYING APPLET" << name() << " ???????????????????????????";
//kDebug() << "???????????????? DESTROYING APPLET" << q->name() << q->scene() << " ???????????????????????????";
QGraphicsWidget *parent = dynamic_cast<QGraphicsWidget *>(q->parentItem());
//it probably won't matter, but right now if there are applethandles, *they* are the parent.
//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 (parent && parent->layout()) {
QGraphicsLayout *l = parent->layout();
@ -460,6 +460,8 @@ void AppletPrivate::cleanUpAndDelete()
configLoader->setDefaults();
}
resetConfigurationObject();
q->scene()->removeItem(q);
q->deleteLater();
}
@ -632,7 +634,7 @@ bool Applet::isBusy() const
QString Applet::name() const
{
if (isContainment()) {
if (d->isContainment) {
if (!d->appletDescription.isValid()) {
return i18n("Unknown Activity");
}
@ -910,7 +912,7 @@ void Applet::flushPendingConstraintsEvents()
closeApplet->setVisible(unlocked);
closeApplet->setShortcutContext(Qt::WidgetShortcut); //don't clash with other views
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"));
} else {
closeApplet->setShortcut(QKeySequence("alt+d,r"));
@ -969,7 +971,7 @@ void Applet::flushPendingConstraintsEvents()
if (c & Plasma::FormFactorConstraint) {
FormFactor f = formFactor();
if (!isContainment() && f != Vertical && f != Horizontal) {
if (!d->isContainment && f != Vertical && f != Horizontal) {
setBackgroundHints(d->backgroundHints | StandardBackground);
} else if(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
Containment* containment = qobject_cast<Plasma::Containment*>(this);
if (isContainment() && containment) {
if (d->isContainment && containment) {
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)
{
if (!d->started) {
kDebug() << "not started";
//kDebug() << "not started";
return;
}
@ -1074,7 +1076,7 @@ void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW
}
if (d->failed) {
kDebug() << "failed!";
//kDebug() << "failed!";
return;
}
@ -1083,7 +1085,7 @@ void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW
QRect contentsRect = QRectF(QPointF(0, 0),
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
View* v = qobject_cast<Plasma::View*>(widget->parent());
Containment* c = qobject_cast<Plasma::Containment*>(this);
@ -1146,7 +1148,7 @@ FormFactor Applet::formFactor() const
Containment *Applet::containment() const
{
if (isContainment()) {
if (d->isContainment) {
Containment *c = qobject_cast<Containment*>(const_cast<Applet*>(this));
if (c) {
return c;
@ -1158,7 +1160,7 @@ Containment *Applet::containment() const
while (parent) {
Containment *possibleC = dynamic_cast<Containment*>(parent);
if (possibleC && possibleC->isContainment()) {
if (possibleC && possibleC->Applet::d->isContainment) {
c = possibleC;
break;
}
@ -1288,17 +1290,17 @@ void Applet::setHasConfigurationInterface(bool hasInterface)
bool canConfig = unlocked || KAuthorized::authorize("PlasmaAllowConfigureWhenLocked");
configAction->setVisible(canConfig);
configAction->setEnabled(canConfig);
if (isContainment()) {
if (d->isContainment) {
//FIXME containments don't seem to use this action any more
//configAction->setShortcut(QKeySequence("ctrl+shift+s"));
connect(configAction, SIGNAL(triggered()), this, SLOT(requestConfiguration()));
} else {
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);
}
} else {
} else if (!d->isContainment || !qobject_cast<Plasma::Containment*>(this)) {
d->actions.removeAction(configAction);
}
}
@ -1393,7 +1395,6 @@ void Applet::showConfigurationInterface()
return;
}
const QString dialogId = QString("%1settings%2").arg(id()).arg(name());
KConfigDialog *dlg = KConfigDialog::exists(d->configDialogId());
if (dlg) {
@ -1409,7 +1410,7 @@ void Applet::showConfigurationInterface()
return;
}
KConfigDialog *dialog = new KConfigDialog(0, dialogId, d->configLoader);
KConfigDialog *dialog = new KConfigDialog(0, d->configDialogId(), d->configLoader);
dialog->setWindowTitle(d->configWindowTitle());
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
@ -1813,6 +1814,9 @@ void AppletPrivate::setIsContainment(bool nowIsContainment)
isContainment = nowIsContainment;
delete mainConfig;
mainConfig = 0;
Containment *c = qobject_cast<Containment*>(q);
if (c) {
if (isContainment) {
@ -1823,6 +1827,20 @@ void AppletPrivate::setIsContainment(bool nowIsContainment)
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
@ -2057,7 +2075,7 @@ KConfigGroup *AppletPrivate::mainConfigGroup()
if (isContainment) {
Corona *corona = qobject_cast<Corona*>(q->scene());
KConfigGroup containmentConfig;
//kDebug() << "got a corona, baby?" << (QObject*)corona;
//kDebug() << "got a corona, baby?" << (QObject*)corona << (QObject*)q;
if (corona) {
containmentConfig = KConfigGroup(corona->config(), "Containments");
@ -2131,6 +2149,11 @@ void AppletPrivate::resetConfigurationObject()
mainConfig->deleteGroup();
delete mainConfig;
mainConfig = 0;
Corona * corona = qobject_cast<Corona*>(q->scene());
if (corona) {
corona->requireConfigSync();
}
}
uint AppletPrivate::s_maxAppletId = 0;

View File

@ -97,6 +97,7 @@ Containment::Containment(QGraphicsItem *parent,
setPos(0, 0);
setBackgroundHints(NoBackground);
setContainmentType(CustomContainment);
setHasConfigurationInterface(false);
}
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
setPos(0, 0);
setBackgroundHints(NoBackground);
setHasConfigurationInterface(false);
}
Containment::~Containment()
{
if (Applet::d->transient) {
Applet::d->resetConfigurationObject();
Applet::d->transient = false;
}
delete d;
}
@ -151,16 +148,6 @@ void Containment::init()
appletBrowserAction->setShortcut(QKeySequence("alt+d,a"));
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);
//no icon
connect(action, SIGNAL(triggered()), this, SLOT(focusNextApplet()));
@ -226,13 +213,13 @@ void Containment::init()
if (immutability() != SystemImmutable) {
d->toolBox->addTool(this->action("lock widgets"));
}
d->toolBox->addTool(this->action("activity settings"));
if (hasConfigurationInterface()) {
// re-use the contianment's action.
//TODO: do we need some way to allow this be overridden?
// it's always available because shells rely on this
// to offer their own custom configuration as well
QAction *configureContainment = this->action("configure");
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
{
if (Applet::d->transient) {
return;
}
KConfigGroup group = g;
if (!group.isValid()) {
group = config();
@ -496,6 +487,8 @@ void ContainmentPrivate::containmentActions(KMenu &desktopMenu)
//find the separator to insert the activity settings before it
QAction *separatorAction = 0;
//TODO: should a submenu be created if there are too many containment specific
// actions? see folderview containment
foreach (QAction *action, actions) {
if (action) {
desktopMenu.addAction(action);
@ -507,14 +500,9 @@ void ContainmentPrivate::containmentActions(KMenu &desktopMenu)
desktopMenu.addSeparator();
//TODO: should a submenu be created if there are too many containment specific
// actions? see folderview containment
if (q->containmentType() == Containment::DesktopContainment) {
desktopMenu.insertAction(separatorAction, q->action("activity settings"));
if (q->hasConfigurationInterface()) {
desktopMenu.addAction(q->action("configure"));
}
}
}
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"));
}
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
foreach (Applet *a, applets) {
a->updateConstraints(ImmutableConstraint);

View File

@ -204,6 +204,9 @@ Corona::Corona(QObject *parent)
Corona::~Corona()
{
KConfigGroup trans(KGlobal::config(), "PlasmaTransientsConfig");
trans.deleteGroup();
// 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
// deleted.