make Package use PackageStructure, remove all virtuals

also kills the read/write methods as precisely zero things were using it
This commit is contained in:
Aaron Seigo 2011-07-19 21:37:39 +02:00
parent d89eebe1be
commit fb3a64ba6c
2 changed files with 74 additions and 146 deletions

View File

@ -22,8 +22,8 @@
#include "package.h" #include "package.h"
#include <QDir>
#include <QFile> #include <QFile>
#include <QIODevice>
#include <QRegExp> #include <QRegExp>
#include <QtNetwork/QHostInfo> #include <QtNetwork/QHostInfo>
@ -46,6 +46,7 @@
#endif #endif
#include "config-plasma.h" #include "config-plasma.h"
#include "packagestructure.h"
#include "pluginloader.h" #include "pluginloader.h"
#include "private/package_p.h" #include "private/package_p.h"
#include "private/packages_p.h" #include "private/packages_p.h"
@ -117,12 +118,13 @@ bool removeFolder(QString folderPath)
Package Package::load(const QString &packageFormat, const QString &specialization) Package Package::load(const QString &packageFormat, const QString &specialization)
{ {
return PluginLoader::pluginLoader()->loadPackage(packageFormat, specialization); return PluginLoader::self()->loadPackage(packageFormat, specialization);
} }
Package::Package() Package::Package(PackageStructure *structure)
: d(new PackagePrivate()) : d(new PackagePrivate())
{ {
d->structure = structure;
} }
Package::Package(const Package &other) Package::Package(const Package &other)
@ -253,6 +255,10 @@ void Package::setAllowExternalPaths(bool allow)
KPluginInfo Package::metadata() const KPluginInfo Package::metadata() const
{ {
if (!d->metadata && !d->path.isEmpty()) { if (!d->metadata && !d->path.isEmpty()) {
const QString metadataPath = filePath("metadata");
if (!metadataPath.isEmpty()) {
d->createPackageMetadata(metadataPath);
} else {
QFileInfo fileInfo(d->path); QFileInfo fileInfo(d->path);
if (fileInfo.isDir()) { if (fileInfo.isDir()) {
@ -282,6 +288,7 @@ KPluginInfo Package::metadata() const
delete archive; delete archive;
} }
} }
}
if (!d->metadata) { if (!d->metadata) {
d->metadata = new KPluginInfo(); d->metadata = new KPluginInfo();
@ -475,7 +482,9 @@ const QString Package::path() const
void Package::pathChanged() void Package::pathChanged()
{ {
// default impl does nothing, this is a hook for subclasses. if (d->structure) {
d->structure.data()->pathChanged(this);
}
} }
QStringList Package::contentsPrefixPaths() const QStringList Package::contentsPrefixPaths() const
@ -647,65 +656,16 @@ QList<const char*> Package::requiredFiles() const
return files; return files;
} }
void Package::read(const KConfigBase *config)
{
d->contents.clear();
d->mimeTypes.clear();
KConfigGroup general(config, QString());
d->type = general.readEntry("Type", QString());
d->contentsPrefixPaths = general.readEntry("ContentsPrefixPaths", d->contentsPrefixPaths);
d->defaultPackageRoot = general.readEntry("DefaultPackageRoot", d->defaultPackageRoot);
d->externalPaths = general.readEntry("AllowExternalPaths", d->externalPaths);
QStringList groups = config->groupList();
foreach (const QString &group, groups) {
KConfigGroup entry(config, group);
QByteArray key = group.toAscii();
QString path = entry.readEntry("Path", QString());
QString name = entry.readEntry("Name", QString());
QStringList mimeTypes = entry.readEntry("Mimetypes", QStringList());
bool directory = entry.readEntry("Directory", false);
bool required = entry.readEntry("Required", false);
if (directory) {
addDirectoryDefinition(key, path, name);
} else {
addFileDefinition(key, path, name);
}
setMimeTypes(key, mimeTypes);
setRequired(key, required);
}
}
void Package::write(KConfigBase *config) const
{
KConfigGroup general = KConfigGroup(config, "");
general.writeEntry("ContentsPrefixPaths", d->contentsPrefixPaths);
general.writeEntry("DefaultPackageRoot", d->defaultPackageRoot);
general.writeEntry("AllowExternalPaths", d->externalPaths);
QMap<QByteArray, ContentStructure>::const_iterator it = d->contents.constBegin();
while (it != d->contents.constEnd()) {
KConfigGroup group = config->group(it.key());
group.writeEntry("Path", it.value().paths);
group.writeEntry("Name", it.value().name);
if (!it.value().mimeTypes.isEmpty()) {
group.writeEntry("Mimetypes", it.value().mimeTypes);
}
if (it.value().directory) {
group.writeEntry("Directory", true);
}
if (it.value().required) {
group.writeEntry("Required", true);
}
++it;
}
}
bool Package::installPackage(const QString &package, const QString &packageRoot) bool Package::installPackage(const QString &package, const QString &packageRoot)
{
if (d->structure) {
return d->structure.data()->installPackage(this, package, packageRoot);
}
return PackagePrivate::installPackage(package, packageRoot, d->servicePrefix);
}
bool PackagePrivate::installPackage(const QString &package, const QString &packageRoot, const QString &servicePrefix)
{ {
//TODO: report *what* failed if something does fail //TODO: report *what* failed if something does fail
QDir root(packageRoot); QDir root(packageRoot);
@ -838,7 +798,7 @@ bool Package::installPackage(const QString &package, const QString &packageRoot)
tempdir.setAutoRemove(false); tempdir.setAutoRemove(false);
} }
if (!d->servicePrefix.isEmpty()) { if (!servicePrefix.isEmpty()) {
// and now we register it as a service =) // and now we register it as a service =)
QString metaPath = targetName + "/metadata.desktop"; QString metaPath = targetName + "/metadata.desktop";
KDesktopFile df(metaPath); KDesktopFile df(metaPath);
@ -851,9 +811,9 @@ bool Package::installPackage(const QString &package, const QString &packageRoot)
//TODO: reduce code duplication with registerPackage below //TODO: reduce code duplication with registerPackage below
QString serviceName = d->servicePrefix + meta.pluginName(); const QString serviceName = servicePrefix + meta.pluginName() + ".desktop";
QString service = KStandardDirs::locateLocal("services", serviceName + ".desktop"); QString service = KStandardDirs::locateLocal("services", serviceName);
#ifndef PLASMA_NO_KIO #ifndef PLASMA_NO_KIO
KIO::FileCopyJob *job = KIO::file_copy(metaPath, service, -1, KIO::HideProgressInfo); KIO::FileCopyJob *job = KIO::file_copy(metaPath, service, -1, KIO::HideProgressInfo);
const bool ok = job->exec(); const bool ok = job->exec();
@ -881,6 +841,15 @@ bool Package::installPackage(const QString &package, const QString &packageRoot)
} }
bool Package::uninstallPackage(const QString &packageName, const QString &packageRoot) bool Package::uninstallPackage(const QString &packageName, const QString &packageRoot)
{
if (d->structure) {
return d->structure.data()->uninstallPackage(this, packageName, packageRoot);
}
return PackagePrivate::uninstallPackage(packageName, packageRoot, d->servicePrefix);
}
bool PackagePrivate::uninstallPackage(const QString &packageName, const QString &packageRoot, const QString &servicePrefix)
{ {
// We need to remove the package directory and its metadata file. // We need to remove the package directory and its metadata file.
const QString targetName = packageRoot + '/' + packageName; const QString targetName = packageRoot + '/' + packageName;
@ -890,9 +859,9 @@ bool Package::uninstallPackage(const QString &packageName, const QString &packag
return false; return false;
} }
QString serviceName = d->servicePrefix + packageName; const QString serviceName = servicePrefix + packageName + ".desktop";
QString service = KStandardDirs::locateLocal("services", serviceName + ".desktop"); QString service = KStandardDirs::locateLocal("services", serviceName);
kDebug() << "Removing service file " << service; kDebug() << "Removing service file " << service;
bool ok = QFile::remove(service); bool ok = QFile::remove(service);
@ -1015,15 +984,4 @@ void PackagePrivate::createPackageMetadata(const QString &path)
metadata = new KPluginInfo(metadataPath); metadata = new KPluginInfo(metadataPath);
} }
PackageFactory::PackageFactory(QObject *parent, const QVariantList &args)
: QObject(parent)
{
Q_UNUSED(args)
}
Package PackageFactory::package() const
{
return Package();
}
} // Namespace } // Namespace

View File

@ -55,14 +55,14 @@ namespace Plasma
package.addFileDefinition("mainscript", "code/main.js", i18n("Main Script File")); package.addFileDefinition("mainscript", "code/main.js", i18n("Main Script File"));
package.setRequired("mainscript", true); package.setRequired("mainscript", true);
@endcode @endcode
* One may also choose to create a subclass of Package and include the setup * One may also choose to create a subclass of PackageStructure and include the setup
* in the constructor. * in the constructor.
* *
* Either way, Package creates a self-documenting contract between the packager and * Either way, Package creates a self-documenting contract between the packager and
* the application without exposing package internals such as actual on-disk structure * the application without exposing package internals such as actual on-disk structure
* of the package or requiring that all contents be explicitly known ahead of time. * of the package or requiring that all contents be explicitly known ahead of time.
* *
* Subclassing Package does have provide a number of potential const benefits: * Subclassing PackageStructure does have provide a number of potential const benefits:
* * the package can be notified of path changes via the virtual pathChanged() method * * the package can be notified of path changes via the virtual pathChanged() method
* * the subclass may implement mechanisms to install and remove packages using the * * the subclass may implement mechanisms to install and remove packages using the
* virtual installPackage and uninstallPackage methods * virtual installPackage and uninstallPackage methods
@ -71,6 +71,7 @@ namespace Plasma
//TODO: write documentation on USING a package //TODO: write documentation on USING a package
class PackagePrivate; class PackagePrivate;
class PackageStructure;
class PLASMA_EXPORT Package class PLASMA_EXPORT Package
{ {
@ -86,10 +87,13 @@ public:
static Package load(const QString &format, const QString &specialization = QString()); static Package load(const QString &format, const QString &specialization = QString());
/** /**
* Default constructor that creates an invalid Package * Default constructor
*
* @arg structure if a NULL pointer is passed in, this will creates an empty (invalid) Package;
* otherwise the structure is allowed to set up the Package's initial layout
* @since 4.6 * @since 4.6
*/ */
explicit Package(); explicit Package(PackageStructure *structure = 0);
/** /**
* Copy constructore * Copy constructore
@ -97,7 +101,7 @@ public:
*/ */
Package(const Package &other); Package(const Package &other);
virtual ~Package(); ~Package();
/** /**
* Assignment operator * Assignment operator
@ -186,7 +190,7 @@ public:
/** /**
* @return the package metadata object. * @return the package metadata object.
*/ */
virtual KPluginInfo metadata() const; KPluginInfo metadata() const;
/** /**
* @return a SHA1 hash digest of the contents of the package in hexadecimal form * @return a SHA1 hash digest of the contents of the package in hexadecimal form
@ -290,7 +294,7 @@ public:
* Called whenever the path changes so that subclasses may take * Called whenever the path changes so that subclasses may take
* package specific actions. * package specific actions.
*/ */
virtual void pathChanged(); void pathChanged();
// Content structure description methods // Content structure description methods
/** /**
@ -313,16 +317,6 @@ public:
*/ */
QList<const char*> requiredFiles() const; QList<const char*> requiredFiles() const;
/**
* Read a package structure from a config file.
*/
void read(const KConfigBase *config);
/**
* Write this package structure to a config file.
*/
void write(KConfigBase *config) const;
/** /**
* Installs a package matching this package structure. By default installs a * Installs a package matching this package structure. By default installs a
* native Plasma::Package. * native Plasma::Package.
@ -332,7 +326,7 @@ public:
* installed to * installed to
* @return true on successful installation, false otherwise * @return true on successful installation, false otherwise
**/ **/
virtual bool installPackage(const QString &archivePath, const QString &packageRoot); bool installPackage(const QString &archivePath, const QString &packageRoot);
/** /**
* Uninstalls a package matching this package structure. * Uninstalls a package matching this package structure.
@ -341,37 +335,13 @@ public:
* @param packageRoot path to the directory where the package should be installed to * @param packageRoot path to the directory where the package should be installed to
* @return true on successful removal of the package, false otherwise * @return true on successful removal of the package, false otherwise
*/ */
virtual bool uninstallPackage(const QString &packageName, const QString &packageRoot); bool uninstallPackage(const QString &packageName, const QString &packageRoot);
private: private:
PackagePrivate * const d; PackagePrivate * const d;
}; };
class PackageFactory : public QObject }
{
Q_OBJECT
public:
PackageFactory(QObject *parent, const QVariantList &args);
virtual Package package() const;
};
} // Namespace
/**
* Register a Package class when it is contained in a loadable module
*/
#define K_EXPORT_PLASMA_PACKAGE(libname, classname) \
class classname "_Factory" : public Plasma::PackageFactory { \
Q_OBJECT \
public: \
classname "_PackageFactory"(QObject *parent, const QVariantList &args) \
: Plasma::PackageFactory(parent, args) {} \
Package package() const { return classname(); } \
}; \
K_PLUGIN_FACTORY(factory, registerPlugin<classname "_PackageFactory">();) \
K_EXPORT_PLUGIN(factory("plasma_package_" #libname)) \
K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION)
Q_DECLARE_METATYPE(Plasma::Package) Q_DECLARE_METATYPE(Plasma::Package)
#endif #endif