completely change how we save and load containments and panels.

it all happens from one file now using nested groups. this has two major effects:

 - one file to rule them all for any given corona; this makes things even nicer for use in other apps, btw.
 - the ability to easily save, send/share and restore corona configuration layouts; something i've wanted from the start


svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=741158
This commit is contained in:
Aaron J. Seigo 2007-11-24 23:38:37 +00:00
parent 1e1b63b9fe
commit ed8c50e03f
5 changed files with 128 additions and 114 deletions

View File

@ -71,8 +71,6 @@ class Applet::Private
public: public:
Private(KService::Ptr service, int uniqueID) Private(KService::Ptr service, int uniqueID)
: appletId(uniqueID), : appletId(uniqueID),
globalConfig(0),
appletConfig(0),
appletDescription(service), appletDescription(service),
package(0), package(0),
background(0), background(0),
@ -170,7 +168,8 @@ public:
QString xmlPath = package->filePath("mainconfigxml"); QString xmlPath = package->filePath("mainconfigxml");
if (!xmlPath.isEmpty()) { if (!xmlPath.isEmpty()) {
QFile file(xmlPath); QFile file(xmlPath);
configXml = new ConfigXml(config(), &file); // FIXME: KConfigSkeleton doesn't play well with KConfigGroup =/
//configXml = new ConfigXml(applet->config(), &file);
} }
if (!package->filePath("mainconfigui").isEmpty()) { if (!package->filePath("mainconfigui").isEmpty()) {
@ -303,17 +302,6 @@ public:
return s_maxAppletId; return s_maxAppletId;
} }
KSharedConfig::Ptr config() {
if (!appletConfig) {
QString file = KStandardDirs::locateLocal("appdata",
"applets/" + instanceName() + "rc",
true);
appletConfig = KSharedConfig::openConfig(file);
}
return appletConfig;
}
QString instanceName() QString instanceName()
{ {
if (!appletDescription.isValid()) { if (!appletDescription.isValid()) {
@ -346,8 +334,6 @@ public:
//TODO: examine the usage of memory here; there's a pretty large //TODO: examine the usage of memory here; there's a pretty large
// number of members at this point. // number of members at this point.
uint appletId; uint appletId;
KSharedConfig::Ptr globalConfig;
KSharedConfig::Ptr appletConfig;
KPluginInfo appletDescription; KPluginInfo appletDescription;
Package* package; Package* package;
QList<QObject*> watchedForFocus; QList<QObject*> watchedForFocus;
@ -391,16 +377,7 @@ Applet::Applet(QObject* parentObject, const QVariantList& args)
Applet::~Applet() Applet::~Applet()
{ {
needsFocus( false ); needsFocus(false);
if (d->appletConfig) {
d->appletConfig->sync();
}
if (d->globalConfig) {
d->globalConfig->sync();
}
delete d; delete d;
} }
@ -413,11 +390,6 @@ uint Applet::id() const
return d->appletId; return d->appletId;
} }
KConfigGroup Applet::config() const
{
return KConfigGroup(d->config(), "General");
}
void Applet::save(KConfigGroup* group) const void Applet::save(KConfigGroup* group) const
{ {
group->writeEntry("plugin", pluginName()); group->writeEntry("plugin", pluginName());
@ -436,12 +408,8 @@ void Applet::save(KConfigGroup* group) const
//group->writeEntry("transform", transformToString(transform())); //group->writeEntry("transform", transformToString(transform()));
} }
Containment* c = containment(); KConfigGroup appletConfigGroup(group, "Configuration");
if (c) { saveState(&appletConfigGroup);
group->writeEntry("containment", c->id());
}
saveState(group);
} }
void Applet::saveState(KConfigGroup* group) const void Applet::saveState(KConfigGroup* group) const
@ -449,20 +417,53 @@ void Applet::saveState(KConfigGroup* group) const
Q_UNUSED(group) Q_UNUSED(group)
} }
KConfigGroup Applet::config(const QString& group) const KConfigGroup Applet::config(const QString &group) const
{ {
KConfigGroup cg = config(); KConfigGroup cg = config();
return KConfigGroup(cg.config(), instanceName() + '-' + group); return KConfigGroup(&cg, group);
}
KConfigGroup Applet::config() const
{
if (d->isContainment) {
const Containment *asContainment = qobject_cast<Containment*>(const_cast<Applet*>(this));
Q_ASSERT(asContainment);
KConfigGroup containmentConfig;
if (asContainment->corona()) {
containmentConfig = KConfigGroup(asContainment->corona()->config(), "Containments");
} else {
containmentConfig = KConfigGroup(KGlobal::config(), "Containments");
}
containmentConfig = KConfigGroup(&containmentConfig, QString::number(d->appletId));
return containmentConfig;
}
KConfigGroup appletConfig;
if (containment()) {
appletConfig = containment()->config();
appletConfig = KConfigGroup(&appletConfig, "Applets");
} else {
kWarning() << "requesting config for" << name() << "without a containment!";
appletConfig = KConfigGroup(KGlobal::config(), "Applets");
}
appletConfig = KConfigGroup(&appletConfig, QString::number(d->appletId));
return KConfigGroup(&appletConfig, "Configuration");
} }
KConfigGroup Applet::globalConfig() const KConfigGroup Applet::globalConfig() const
{ {
if ( !d->globalConfig ) { KConfigGroup globalAppletConfig;
QString file = KStandardDirs::locateLocal( "config", "plasma_" + globalName() + "rc" ); if (containment() && containment()->corona()) {
d->globalConfig = KSharedConfig::openConfig( file ); KSharedConfig::Ptr coronaConfig = containment()->corona()->config();
globalAppletConfig = KConfigGroup(coronaConfig, "AppletGlobals");
} else {
globalAppletConfig = KConfigGroup(KGlobal::config(), "AppletGlobals");
} }
return KConfigGroup(d->globalConfig, "General"); return KConfigGroup(&globalAppletConfig, globalName());
} }
void Applet::destroy() void Applet::destroy()
@ -471,13 +472,7 @@ void Applet::destroy()
d->configXml->setDefaults(); d->configXml->setDefaults();
} }
if (d->appletConfig) { config().deleteGroup();
foreach (const QString& group, d->appletConfig->groupList()) {
d->appletConfig->deleteGroup(group);
}
d->appletConfig = 0;
}
deleteLater(); deleteLater();
} }
@ -749,6 +744,7 @@ QSizeF Applet::sizeHint() const
int bottom = 0; int bottom = 0;
d->getBorderSize(left, top, right, bottom); d->getBorderSize(left, top, right, bottom);
QSizeF borderSize = QSizeF(left + right, top + bottom);
//kDebug() << "Applet content size hint: " << contentSizeHint() << "plus our borders" << left << right << top << bottom; //kDebug() << "Applet content size hint: " << contentSizeHint() << "plus our borders" << left << right << top << bottom;
@ -890,7 +886,7 @@ QSizeF Applet::contentSizeHint() const
return layout()->sizeHint(); return layout()->sizeHint();
} }
return QSizeF(0, 0); return contentSize();
} }
QString Applet::globalName() const QString Applet::globalName() const
@ -1179,6 +1175,8 @@ void Applet::setGeometry(const QRectF& geometry)
if (managingLayout()) { if (managingLayout()) {
managingLayout()->invalidate(); managingLayout()->invalidate();
} }
updateConstraints(Plasma::SizeConstraint);
} }
setPos(geometry.topLeft()); setPos(geometry.topLeft());

View File

@ -127,7 +127,7 @@ class PLASMA_EXPORT Applet : public Widget
* *
* @param group the name of the group to access * @param group the name of the group to access
**/ **/
KConfigGroup config(const QString& group) const; KConfigGroup config(const QString &group) const;
/** /**
* Saves state information about this applet. * Saves state information about this applet.

View File

@ -262,12 +262,12 @@ class PLASMA_EXPORT Containment : public Applet
*/ */
void setFormFactor(Plasma::FormFactor formFactor); void setFormFactor(Plasma::FormFactor formFactor);
protected:
/** /**
* Returns the Corona (if any) that this Containment is hosted by * Returns the Corona (if any) that this Containment is hosted by
*/ */
Corona* corona() const; Corona* corona() const;
protected:
void contextMenuEvent(QGraphicsSceneContextMenuEvent * event); void contextMenuEvent(QGraphicsSceneContextMenuEvent * event);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);

View File

@ -50,7 +50,9 @@ class Corona::Private
public: public:
Private() Private()
: immutable(false), : immutable(false),
mimetype("text/x-plasmoidservicename") mimetype("text/x-plasmoidservicename"),
configName("plasma-appletsrc"),
config(0)
{ {
} }
@ -65,6 +67,8 @@ public:
bool immutable; bool immutable;
QString mimetype; QString mimetype;
QString configName;
KSharedConfigPtr config;
QList<Containment*> containments; QList<Containment*> containments;
}; };
@ -117,18 +121,18 @@ QString Corona::appletMimeType()
void Corona::saveApplets(const QString &config) const void Corona::saveApplets(const QString &config) const
{ {
KConfig cg(config); KConfig cg(config);
foreach (const QString& group, cg.groupList()) { d->configName = config;
cg.deleteGroup(group);
}
QStringList containmentIds; QStringList containmentIds;
KConfigGroup containments(&cg, "Containments");
foreach (const Containment *containment, d->containments) { foreach (const Containment *containment, d->containments) {
QString cid = QString::number(containment->id()); QString cid = QString::number(containment->id());
KConfigGroup containmentConfig(&cg, cid.append("-containment")); KConfigGroup containmentConfig(&containments, cid);
containment->saveConstraints(&containmentConfig); containment->saveConstraints(&containmentConfig);
containment->save(&containmentConfig); containment->save(&containmentConfig);
KConfigGroup applets(&containmentConfig, "Applets");
foreach (const Applet* applet, containment->applets()) { foreach (const Applet* applet, containment->applets()) {
KConfigGroup appletConfig(&cg, QString::number(applet->id()).append("-applet")); KConfigGroup appletConfig(&applets, QString::number(applet->id()));
applet->save(&appletConfig); applet->save(&appletConfig);
} }
} }
@ -136,85 +140,67 @@ void Corona::saveApplets(const QString &config) const
void Corona::saveApplets() const void Corona::saveApplets() const
{ {
saveApplets("plasma-appletsrc"); saveApplets(d->configName);
} }
void Corona::loadApplets(const QString& configname) void Corona::loadApplets(const QString& configName)
{ {
clearApplets(); clearApplets();
d->configName = configName;
KConfig config(configname, KConfig::SimpleConfig); KConfig config(configName, KConfig::SimpleConfig);
KConfigGroup containments(&config, "Containments");
QList<KConfigGroup> applets;
QHash<int, Containment*> containments;
foreach (const QString& group, config.groupList()) {
KConfigGroup appletConfig(&config, group);
if (group.endsWith("containment")) {
int cid = group.left(group.indexOf('-')).toUInt();
Containment *c = addContainment(appletConfig.readEntry("plugin", QString()), QVariantList(),
cid, true);
if (c) {
addItem(c);
containments.insert(c->id(), c);
c->loadConstraints(&appletConfig);
//kDebug() << "Containment" << c->id() << "geometry is" << c->geometry().toRect() << "config'd with" << appletConfig.name();
}
} else {
// it's an applet, let's grab the containment association
//kDebug() << "insert multi" << group;
applets.append(appletConfig);
}
}
//int maxContainment = containments.size();
//kDebug() << "number of applets?" << applets.count();
foreach (KConfigGroup cg, applets) {
int cid = cg.readEntry("containment", 0);
//kDebug() << "trying to load applet " << cg.name() << " in containment " << cid;
Containment* c = containments.value(cid, 0);
foreach (const QString& group, containments.groupList()) {
KConfigGroup containmentConfig(&containments, group);
int cid = group.toUInt();
kDebug() << "got a containment in the config, trying to make a" << containmentConfig.readEntry("plugin", QString()) << "from" << group;
Containment *c = addContainment(containmentConfig.readEntry("plugin", QString()), QVariantList(),
cid, true);
if (!c) { if (!c) {
kDebug() << "couldn't find containment " << cid << ", skipping this applet";
continue; continue;
} }
//kDebug() << "creating applet " << cg.name() << "in containment" << cid << "at geometry" << cg.readEntry("geometry", QRectF()); addItem(c);
int appId = cg.name().left(cg.name().indexOf('-')).toUInt(); c->loadConstraints(&containmentConfig);
Applet *applet = c->addApplet(cg.readEntry("plugin", QString()), QVariantList(), //kDebug() << "Containment" << c->id() << "geometry is" << c->geometry().toRect() << "config'd with" << appletConfig.name();
appId, cg.readEntry("geometry", QRectF()), true); KConfigGroup applets(&containmentConfig, "Applets");
QList<qreal> m = cg.readEntry("transform", QList<qreal>());
if (m.count() == 9) { foreach (const QString &appletGroup, applets.groupList()) {
QTransform t(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]); kDebug() << "reading from applet group" << appletGroup;
int appId = appletGroup.toUInt();
KConfigGroup appletConfig(&applets, appletGroup);
kDebug() << "the name is" << appletConfig.name();
Applet *applet = c->addApplet(appletConfig.readEntry("plugin", QString()), QVariantList(),
appId, appletConfig.readEntry("geometry", QRectF()), true);
Q_UNUSED(applet)
// FIXME: the transform does not stick; it gets set then almost immediately reset. // FIXME: the transform does not stick; it gets set then almost immediately reset.
// find out why and then reenable this // find out why and then reenable this
//applet->setTransform(t); /*
QList<qreal> m = cg.readEntry("transform", QList<qreal>());
if (m.count() == 9) {
QTransform t(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
applet->setTransform(t);
}
*/
} }
} }
foreach (Containment* c, containments) {
QString cid = QString::number(c->id());
KConfigGroup containmentConfig(&config, cid.append("-containment"));
c->setImmutable(containmentConfig.isImmutable());
}
if (d->containments.count() < 1) { if (d->containments.count() < 1) {
loadDefaultSetup(); loadDefaultSetup();
} else { } else {
foreach (Containment* containment, d->containments) { foreach (Containment* containment, d->containments) {
QString cid = QString::number(containment->id());
containment->init(); containment->init();
KConfigGroup containmentConfig(&containments, cid);
containment->setImmutable(containmentConfig.isImmutable());
foreach(Applet* applet, containment->applets()) { foreach(Applet* applet, containment->applets()) {
applet->init(); applet->init();
} }
}
}
foreach (Containment* containment, d->containments) { containment->flushUpdatedConstraints();
// we need to manually flush the constraints changes }
// because we may not get back to the event loop before
// view set up
containment->flushUpdatedConstraints();
} }
setImmutable(config.isImmutable()); setImmutable(config.isImmutable());
@ -222,7 +208,7 @@ void Corona::loadApplets(const QString& configname)
void Corona::loadApplets() void Corona::loadApplets()
{ {
loadApplets("plasma-appletsrc"); loadApplets(d->configName);
} }
void Corona::loadDefaultSetup() void Corona::loadDefaultSetup()
@ -300,6 +286,15 @@ void Corona::clearApplets()
} }
} }
KSharedConfigPtr Corona::config()
{
if (!d->config) {
d->config = KSharedConfig::openConfig(d->configName);
}
return d->config;
}
Containment* Corona::addContainment(const QString& name, const QVariantList& args, uint id, bool delayedInit) Containment* Corona::addContainment(const QString& name, const QVariantList& args, uint id, bool delayedInit)
{ {
QString pluginName = name; QString pluginName = name;
@ -344,6 +339,17 @@ Containment* Corona::addContainment(const QString& name, const QVariantList& arg
return containment; return containment;
} }
void Corona::destroyContainment(Containment *c)
{
if (!d->containments.contains(c)) {
return;
}
d->containments.removeAll(c);
c->config().deleteGroup();
c->deleteLater();
}
Applet* Corona::addApplet(const QString& name, const QVariantList& args, uint id, const QRectF& geometry) Applet* Corona::addApplet(const QString& name, const QVariantList& args, uint id, const QRectF& geometry)
{ {
if (d->containments.size() < 1) { if (d->containments.size() < 1) {

View File

@ -93,6 +93,11 @@ public:
*/ */
void clearApplets(); void clearApplets();
/**
* Returns the the config file used to store the configuration for this Corona
*/
KSharedConfig::Ptr config();
public Q_SLOTS: public Q_SLOTS:
/** /**
* Load applets from the default config file * Load applets from the default config file
@ -137,6 +142,11 @@ public Q_SLOTS:
Containment* addContainment(const QString& name, const QVariantList& args = QVariantList(), Containment* addContainment(const QString& name, const QVariantList& args = QVariantList(),
uint id = 0, bool delayInit = false); uint id = 0, bool delayInit = false);
/**
* Removes a given containment from the corona
*/
void destroyContainment(Containment *containment);
/** /**
* Returns the Containment, if any, for a given physical screen * Returns the Containment, if any, for a given physical screen
* *