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:
Private(KService::Ptr service, int uniqueID)
: appletId(uniqueID),
globalConfig(0),
appletConfig(0),
appletDescription(service),
package(0),
background(0),
@ -170,7 +168,8 @@ public:
QString xmlPath = package->filePath("mainconfigxml");
if (!xmlPath.isEmpty()) {
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()) {
@ -303,17 +302,6 @@ public:
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()
{
if (!appletDescription.isValid()) {
@ -346,8 +334,6 @@ public:
//TODO: examine the usage of memory here; there's a pretty large
// number of members at this point.
uint appletId;
KSharedConfig::Ptr globalConfig;
KSharedConfig::Ptr appletConfig;
KPluginInfo appletDescription;
Package* package;
QList<QObject*> watchedForFocus;
@ -392,15 +378,6 @@ Applet::Applet(QObject* parentObject, const QVariantList& args)
Applet::~Applet()
{
needsFocus(false);
if (d->appletConfig) {
d->appletConfig->sync();
}
if (d->globalConfig) {
d->globalConfig->sync();
}
delete d;
}
@ -413,11 +390,6 @@ uint Applet::id() const
return d->appletId;
}
KConfigGroup Applet::config() const
{
return KConfigGroup(d->config(), "General");
}
void Applet::save(KConfigGroup* group) const
{
group->writeEntry("plugin", pluginName());
@ -436,12 +408,8 @@ void Applet::save(KConfigGroup* group) const
//group->writeEntry("transform", transformToString(transform()));
}
Containment* c = containment();
if (c) {
group->writeEntry("containment", c->id());
}
saveState(group);
KConfigGroup appletConfigGroup(group, "Configuration");
saveState(&appletConfigGroup);
}
void Applet::saveState(KConfigGroup* group) const
@ -452,17 +420,50 @@ void Applet::saveState(KConfigGroup* group) const
KConfigGroup Applet::config(const QString &group) const
{
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
{
if ( !d->globalConfig ) {
QString file = KStandardDirs::locateLocal( "config", "plasma_" + globalName() + "rc" );
d->globalConfig = KSharedConfig::openConfig( file );
KConfigGroup globalAppletConfig;
if (containment() && containment()->corona()) {
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()
@ -471,13 +472,7 @@ void Applet::destroy()
d->configXml->setDefaults();
}
if (d->appletConfig) {
foreach (const QString& group, d->appletConfig->groupList()) {
d->appletConfig->deleteGroup(group);
}
d->appletConfig = 0;
}
config().deleteGroup();
deleteLater();
}
@ -749,6 +744,7 @@ QSizeF Applet::sizeHint() const
int bottom = 0;
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;
@ -890,7 +886,7 @@ QSizeF Applet::contentSizeHint() const
return layout()->sizeHint();
}
return QSizeF(0, 0);
return contentSize();
}
QString Applet::globalName() const
@ -1179,6 +1175,8 @@ void Applet::setGeometry(const QRectF& geometry)
if (managingLayout()) {
managingLayout()->invalidate();
}
updateConstraints(Plasma::SizeConstraint);
}
setPos(geometry.topLeft());

View File

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

View File

@ -50,7 +50,9 @@ class Corona::Private
public:
Private()
: immutable(false),
mimetype("text/x-plasmoidservicename")
mimetype("text/x-plasmoidservicename"),
configName("plasma-appletsrc"),
config(0)
{
}
@ -65,6 +67,8 @@ public:
bool immutable;
QString mimetype;
QString configName;
KSharedConfigPtr config;
QList<Containment*> containments;
};
@ -117,18 +121,18 @@ QString Corona::appletMimeType()
void Corona::saveApplets(const QString &config) const
{
KConfig cg(config);
foreach (const QString& group, cg.groupList()) {
cg.deleteGroup(group);
}
d->configName = config;
QStringList containmentIds;
KConfigGroup containments(&cg, "Containments");
foreach (const Containment *containment, d->containments) {
QString cid = QString::number(containment->id());
KConfigGroup containmentConfig(&cg, cid.append("-containment"));
KConfigGroup containmentConfig(&containments, cid);
containment->saveConstraints(&containmentConfig);
containment->save(&containmentConfig);
KConfigGroup applets(&containmentConfig, "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);
}
}
@ -136,93 +140,75 @@ void Corona::saveApplets(const QString &config) const
void Corona::saveApplets() const
{
saveApplets("plasma-appletsrc");
saveApplets(d->configName);
}
void Corona::loadApplets(const QString& configname)
void Corona::loadApplets(const QString& configName)
{
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(),
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) {
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);
if (!c) {
kDebug() << "couldn't find containment " << cid << ", skipping this applet";
continue;
}
//kDebug() << "creating applet " << cg.name() << "in containment" << cid << "at geometry" << cg.readEntry("geometry", QRectF());
int appId = cg.name().left(cg.name().indexOf('-')).toUInt();
Applet *applet = c->addApplet(cg.readEntry("plugin", QString()), QVariantList(),
appId, cg.readEntry("geometry", QRectF()), true);
addItem(c);
c->loadConstraints(&containmentConfig);
//kDebug() << "Containment" << c->id() << "geometry is" << c->geometry().toRect() << "config'd with" << appletConfig.name();
KConfigGroup applets(&containmentConfig, "Applets");
foreach (const QString &appletGroup, applets.groupList()) {
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.
// find out why and then reenable this
/*
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]);
// FIXME: the transform does not stick; it gets set then almost immediately reset.
// find out why and then reenable this
//applet->setTransform(t);
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) {
loadDefaultSetup();
} else {
foreach (Containment* containment, d->containments) {
QString cid = QString::number(containment->id());
containment->init();
KConfigGroup containmentConfig(&containments, cid);
containment->setImmutable(containmentConfig.isImmutable());
foreach(Applet* applet, containment->applets()) {
applet->init();
}
}
}
foreach (Containment* containment, d->containments) {
// 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());
}
void Corona::loadApplets()
{
loadApplets("plasma-appletsrc");
loadApplets(d->configName);
}
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)
{
QString pluginName = name;
@ -344,6 +339,17 @@ Containment* Corona::addContainment(const QString& name, const QVariantList& arg
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)
{
if (d->containments.size() < 1) {

View File

@ -93,6 +93,11 @@ public:
*/
void clearApplets();
/**
* Returns the the config file used to store the configuration for this Corona
*/
KSharedConfig::Ptr config();
public Q_SLOTS:
/**
* Load applets from the default config file
@ -137,6 +142,11 @@ public Q_SLOTS:
Containment* addContainment(const QString& name, const QVariantList& args = QVariantList(),
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
*