make PackageStructure a loadable plugin, so that there are now three methods to get a PackageStructure:

0. builtin
1. c++ plugin
2. config file

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=779415
This commit is contained in:
Aaron J. Seigo 2008-02-26 04:07:07 +00:00
parent 9b0fcfe714
commit 9c94c63dfe
6 changed files with 87 additions and 46 deletions

View File

@ -36,7 +36,6 @@
#include <KDebug> #include <KDebug>
#include "packagemetadata.h" #include "packagemetadata.h"
#include "packagestructure.h"
namespace Plasma namespace Plasma
{ {
@ -44,7 +43,7 @@ namespace Plasma
class Package::Private class Package::Private
{ {
public: public:
Private(const PackageStructure& st, const QString& p) Private(const PackageStructure::Ptr st, const QString& p)
: structure(st), : structure(st),
basePath(p), basePath(p),
valid(QFile::exists(basePath)), valid(QFile::exists(basePath)),
@ -60,20 +59,19 @@ public:
delete metadata; delete metadata;
} }
PackageStructure structure; const PackageStructure::Ptr structure;
QString basePath; QString basePath;
bool valid; bool valid;
PackageMetadata *metadata; PackageMetadata *metadata;
}; };
Package::Package(const QString& packageRoot, const QString& package, Package::Package(const QString& packageRoot, const QString& package,
const PackageStructure& structure) const PackageStructure::Ptr structure)
: d(new Private(structure, packageRoot + '/' + package)) : d(new Private(structure, packageRoot + '/' + package))
{ {
} }
Package::Package(const QString &packagePath, const PackageStructure &structure) Package::Package(const QString &packagePath, const PackageStructure::Ptr structure)
: d(new Private(structure, packagePath)) : d(new Private(structure, packagePath))
{ {
} }
@ -89,18 +87,18 @@ bool Package::isValid() const
return false; return false;
} }
foreach (const char *dir, d->structure.requiredDirectories()) { foreach (const char *dir, d->structure->requiredDirectories()) {
if (!QFile::exists(d->basePath + "contents/" + d->structure.path(dir))) { if (!QFile::exists(d->basePath + "contents/" + d->structure->path(dir))) {
kWarning(505) << "Could not find required directory" << dir; kWarning(505) << "Could not find required directory" << dir;
d->valid = false; d->valid = false;
return false; return false;
} }
} }
foreach (const char *file, d->structure.requiredFiles()) { foreach (const char *file, d->structure->requiredFiles()) {
if (!QFile::exists(d->basePath + "contents/" + d->structure.path(file))) { if (!QFile::exists(d->basePath + "contents/" + d->structure->path(file))) {
kWarning(505) << "Could not find required file" << file << ", look in" kWarning(505) << "Could not find required file" << file << ", look in"
<< d->basePath + "contents/" + d->structure.path(file) << endl; << d->basePath + "contents/" + d->structure->path(file) << endl;
d->valid = false; d->valid = false;
return false; return false;
} }
@ -115,7 +113,7 @@ QString Package::filePath(const char* fileType, const QString& filename) const
return QString(); return QString();
} }
QString path = d->structure.path(fileType); QString path = d->structure->path(fileType);
if (path.isEmpty()) { if (path.isEmpty()) {
return QString(); return QString();
@ -145,7 +143,7 @@ QStringList Package::entryList(const char* fileType) const
return QStringList(); return QStringList();
} }
QString path = d->structure.path(fileType); QString path = d->structure->path(fileType);
if (path.isEmpty()) { if (path.isEmpty()) {
return QStringList(); return QStringList();
} }
@ -159,7 +157,7 @@ QStringList Package::entryList(const char* fileType) const
return dir.entryList(QDir::Files | QDir::Readable); return dir.entryList(QDir::Files | QDir::Readable);
} }
const PackageMetadata *Package::metadata() const const PackageMetadata* Package::metadata() const
{ {
if (!d->metadata) { if (!d->metadata) {
d->metadata = new PackageMetadata(d->basePath + "metadata.desktop"); d->metadata = new PackageMetadata(d->basePath + "metadata.desktop");

View File

@ -24,6 +24,7 @@
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <plasma/plasma_export.h> #include <plasma/plasma_export.h>
#include <plasma/packagestructure.h>
namespace Plasma namespace Plasma
{ {
@ -33,7 +34,6 @@ namespace Plasma
**/ **/
class PackageMetadata; class PackageMetadata;
class PackageStructure;
class PLASMA_EXPORT Package class PLASMA_EXPORT Package
{ {
@ -46,7 +46,7 @@ class PLASMA_EXPORT Package
* @arg structure the package structure describing this package * @arg structure the package structure describing this package
**/ **/
Package(const QString& packageRoot, const QString& package, Package(const QString& packageRoot, const QString& package,
const PackageStructure& structure); const PackageStructure::Ptr structure);
/** /**
* Construct a Package object. * Construct a Package object.
@ -54,7 +54,7 @@ class PLASMA_EXPORT Package
* @arg packagePath full path to the package directory * @arg packagePath full path to the package directory
* @arg structure the package structure describing this package * @arg structure the package structure describing this package
*/ */
Package(const QString &packagePath, const PackageStructure &structure); Package(const QString &packagePath, const PackageStructure::Ptr structure);
//TODO for 4.1: be able to load an uninstalled/uncompressed file. //TODO for 4.1: be able to load an uninstalled/uncompressed file.

View File

@ -24,8 +24,8 @@
namespace Plasma namespace Plasma
{ {
PlasmoidPackage::PlasmoidPackage() PlasmoidPackage::PlasmoidPackage(QObject *parent)
: Plasma::PackageStructure(QString("Plasmoid")) : Plasma::PackageStructure(parent, QString("Plasmoid"))
{ {
addDirectoryDefinition("images", "images", i18n("Images")); addDirectoryDefinition("images", "images", i18n("Images"));
QStringList mimetypes; QStringList mimetypes;
@ -52,8 +52,8 @@ PlasmoidPackage::PlasmoidPackage()
setRequired("mainscript", true); setRequired("mainscript", true);
} }
ThemePackage::ThemePackage() ThemePackage::ThemePackage(QObject *parent)
: Plasma::PackageStructure(QString("Plasma Theme")) : Plasma::PackageStructure(parent, QString("Plasma Theme"))
{ {
addDirectoryDefinition("dialogs", "dialogs/", i18n("Images for dialogs")); addDirectoryDefinition("dialogs", "dialogs/", i18n("Images for dialogs"));
addFileDefinition("dialogs/background", "dialogs/background.svg", addFileDefinition("dialogs/background", "dialogs/background.svg",
@ -112,4 +112,5 @@ ThemePackage::ThemePackage()
} // namespace Plasma } // namespace Plasma
#include "packages_p.moc"

View File

@ -27,14 +27,16 @@ namespace Plasma
class PlasmoidPackage : public PackageStructure class PlasmoidPackage : public PackageStructure
{ {
Q_OBJECT
public: public:
explicit PlasmoidPackage(); explicit PlasmoidPackage(QObject *parent = 0);
}; };
class ThemePackage : public PackageStructure class ThemePackage : public PackageStructure
{ {
Q_OBJECT
public: public:
explicit ThemePackage(); explicit ThemePackage(QObject *parent = 0);
}; };
} // namespace Plasma } // namespace Plasma

View File

@ -23,6 +23,7 @@
#include <KConfigGroup> #include <KConfigGroup>
#include <KStandardDirs> #include <KStandardDirs>
#include <KServiceTypeTrader>
#include "packages_p.h" #include "packages_p.h"
@ -54,48 +55,71 @@ class ContentStructure
bool required; bool required;
}; };
class PackageStructure::Private class PackageStructure::Private
{ {
public: public:
QString type; QString type;
QMap<QByteArray, ContentStructure> contents; QMap<QByteArray, ContentStructure> contents;
QStringList mimetypes; QStringList mimetypes;
static QHash<QString, PackageStructure::Ptr> structures;
}; };
PackageStructure::PackageStructure(const QString &type) QHash<QString, PackageStructure::Ptr> PackageStructure::Private::structures;
: d(new Private)
PackageStructure::PackageStructure(QObject *parent, const QString &type)
: QObject(parent),
d(new Private)
{ {
d->type = type; d->type = type;
} }
PackageStructure::PackageStructure(const PackageStructure& rhs)
: d(new Private)
{
*d = *rhs.d;
}
PackageStructure::~PackageStructure() PackageStructure::~PackageStructure()
{ {
delete d; delete d;
} }
PackageStructure PackageStructure::load(const QString &packageFormat) PackageStructure::Ptr PackageStructure::load(const QString &packageFormat)
{ {
PackageStructure ps;
if (packageFormat.isEmpty()) { if (packageFormat.isEmpty()) {
return ps; return Ptr(new PackageStructure());
} }
PackageStructure::Ptr structure = Private::structures[packageFormat];
if (structure) {
return structure;
}
// first we check for plugins in sycoca
QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(packageFormat);
KService::List offers = KServiceTypeTrader::self()->query("Plasma/PackageStructure", constraint);
QVariantList args;
QString error;
foreach (const KService::Ptr &offer, offers) {
PackageStructure::Ptr structure(offer->createInstance<Plasma::PackageStructure>(0, args, &error));
if (structure) {
Private::structures[packageFormat] = structure;
return structure;
}
kDebug() << "Couldn't load PackageStructure for" << packageFormat << "! reason given: " << error;
}
// if that didn't give us any love, then we try to load from a config file
structure = new PackageStructure();
QString configPath("plasma/packageformats/%1rc"); QString configPath("plasma/packageformats/%1rc");
configPath = KStandardDirs::locate("data", configPath.arg(packageFormat)); configPath = KStandardDirs::locate("data", configPath.arg(packageFormat));
if (!configPath.isEmpty()) { if (!configPath.isEmpty()) {
KConfig config(configPath); KConfig config(configPath);
ps.read(&config); structure->read(&config);
} }
return ps; Private::structures[packageFormat] = structure;
return structure;
} }
PackageStructure& PackageStructure::operator=(const PackageStructure& rhs) PackageStructure& PackageStructure::operator=(const PackageStructure& rhs)
@ -308,3 +332,5 @@ void PackageStructure::write(KConfigBase *config) const
} // Plasma namespace } // Plasma namespace
#include "packagestructure.moc"

View File

@ -21,8 +21,11 @@
#define PACKAGESTRUCTURE_H #define PACKAGESTRUCTURE_H
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QSharedData>
#include <KGenericFactory>
#include <KLocale> #include <KLocale>
#include <KSharedPtr>
#include <plasma/plasma_export.h> #include <plasma/plasma_export.h>
@ -61,15 +64,19 @@ namespace Plasma
* Either way, PackageStructure creates a sort of "contract" between the packager and * Either way, PackageStructure creates a sort of "contract" between the packager and
* the application which is also self-documenting. * the application which is also self-documenting.
**/ **/
class PLASMA_EXPORT PackageStructure class PLASMA_EXPORT PackageStructure : public QObject, public QSharedData
{ {
Q_OBJECT
public: public:
typedef KSharedPtr<PackageStructure> Ptr;
/** /**
* Default constructor for a package structure definition * Default constructor for a package structure definition
* *
* @arg type the type of package. This is often application specific. * @arg type the type of package. This is often application specific.
**/ **/
explicit PackageStructure(const QString &type = i18n("Invalid")); explicit PackageStructure(QObject *parent = 0, const QString &type = i18n("Invalid"));
/** /**
* Copy constructor * Copy constructor
@ -94,7 +101,7 @@ public:
* @return a package that matches the format, if available. The caller * @return a package that matches the format, if available. The caller
* is responsible for deleting the object. * is responsible for deleting the object.
*/ */
static PackageStructure load(const QString &package); static PackageStructure::Ptr load(const QString &package);
/** /**
* Type of package this structure describes * Type of package this structure describes
@ -205,5 +212,12 @@ private:
Private * const d; Private * const d;
}; };
/**
* Register an applet when it is contained in a loadable module
*/
#define K_EXPORT_PLASMA_PACKAGESTRUCTURE(libname, classname) \
K_PLUGIN_FACTORY(factory, registerPlugin<classname>();) \
K_EXPORT_PLUGIN(factory("plasma_packagestructure_" #libname))
} // Plasma namespace } // Plasma namespace
#endif #endif