diff --git a/CMakeLists.txt b/CMakeLists.txt index 776e1e87a..e7f317517 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,15 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/workspace/li ########### next target ############### +set(plasmagik_SRCS + packagemetadata.cpp + packager.cpp + packagestructure.cpp + package.cpp + ) + set(plasma_LIB_SRCS + ${plasmagik_SRCS} abstractrunner.cpp animator.cpp applet.cpp @@ -27,6 +35,13 @@ set(plasma_LIB_SRCS widgets/vboxlayout.cpp ) +set(plasmagik_HEADERS + packagemetadata.h + packager.h + packagestructure.h + package.h + ) + kde4_automoc(${plasma_LIB_SRCS}) kde4_add_library(plasma SHARED ${plasma_LIB_SRCS}) @@ -39,6 +54,8 @@ install(TARGETS plasma DESTINATION ${LIB_INSTALL_DIR}) ########### install files ############### +install(FILES ${plasmagik_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/) + install(FILES abstractrunner.h animator.h diff --git a/package.cpp b/package.cpp new file mode 100644 index 000000000..f71238bdf --- /dev/null +++ b/package.cpp @@ -0,0 +1,203 @@ +/****************************************************************************** +* Copyright (C) 2007 by Aaron Seigo * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include //TODO: remove on monday +#include +#include + +#include "package.h" +#include "packagemetadata.h" +#include "packagestructure.h" + +namespace Plasma +{ + +class Package::Private +{ +public: + Private(const PackageStructure& st, const QString& p) + : structure(st), + basePath(p), + valid(QFile::exists(basePath)) + { + if (valid && basePath[basePath.length() - 1] != '/') { + basePath.append('/'); + } + } + + PackageStructure structure; + QString basePath; + bool valid; +}; + +Package::Package(const QString& packageRoot, const QString& package, + const PackageStructure& structure) + : d(new Private(structure, packageRoot + "/" + package)) +{ +} + +Package::~Package() +{ +} + +QString Package::filePath(const char* fileType, const QString& filename) +{ + if (!d->valid) { + return QString(); + } + + QString path = d->structure.path(fileType); + if (!path.isEmpty() && !filename.isEmpty()) { + path.prepend(d->basePath); + path.append("/").append(filename); + } + + if (QFile::exists(path)) { + return path; + } + + return QString(); +} + +QString Package::filePath(const char* fileType) +{ + return filePath(fileType, QString()); +} + +QStringList Package::entryList(const char* fileType) +{ + if (!d->valid) { + return QStringList(); + } + + QString path = d->structure.path(fileType); + if (path.isEmpty()) { + return QStringList(); + } + + QDir dir(d->basePath + path); + + if (!dir.exists()) { + return QStringList(); + } + + return dir.entryList(QDir::Files | QDir::Readable); +} + +//TODO: provide a version of this that allows one to ask for certain types of packages, etc? +QStringList Package::knownPackages(const QString& packageRoot) // static +{ + QDir dir(packageRoot); + + if (!dir.exists()) { + return QStringList(); + } + + QStringList packages; + + foreach (const QString& dir, dir.entryList(QDir::AllDirs | QDir::Readable)) { + QString metadata = packageRoot + "/" + dir + "/metadata.desktop"; + if (QFile::exists(metadata)) { + PackageMetadata m(metadata); + packages << m.name(); + } + } + + return packages; +} + +bool Package::installPackage(const QString& package, const QString& packageRoot) // static +{ + //TODO: report *what* failed if something does fail + QDir root(packageRoot); + + if (!root.exists()) { + KStandardDirs::makeDir(packageRoot); + if (!root.exists()) { + return false; + } + } + + if (!QFile::exists(package)) { + return false; + } + + KZip archive(package); + if (!archive.open(QIODevice::ReadOnly)) { + return false; + } + + const KArchiveDirectory* source = archive.directory(); + const KArchiveEntry* metadata = source->entry("metadata.desktop"); + + if (!metadata) { + return false; + } + + QFile f(package); + QString tempdir = packageRoot + "/" + f.fileName(); + if (QFile::exists(tempdir)) { + return false; + } + + source->copyTo(tempdir); + + QString metadataPath = tempdir + "/metadata.desktop"; + if (!QFile::exists(metadataPath)) { + KIO::SimpleJob* job = KIO::file_delete(tempdir); + job->exec(); + return false; + } + PackageMetadata meta(metadataPath); + QString targetName = meta.name(); + + if (targetName.isEmpty()) { + KIO::SimpleJob* job = KIO::file_delete(tempdir); + job->exec(); + return false; + } + + targetName = packageRoot + "/" + targetName; + if (QFile::exists(targetName)) { + KIO::SimpleJob* job = KIO::file_delete(tempdir); + job->exec(); + return false; + } + + KIO::FileCopyJob* job = KIO::file_move(tempdir, targetName); + + bool success = job->exec(); + + if (!success) { + KIO::SimpleJob* job = KIO::file_delete(tempdir); + job->exec(); + return false; + } + + return success; +} + +} // Namespace diff --git a/package.h b/package.h new file mode 100644 index 000000000..ff6107986 --- /dev/null +++ b/package.h @@ -0,0 +1,94 @@ +/****************************************************************************** +* Copyright (C) 2007 by Aaron Seigo * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +namespace Plasma +{ + +/** + * @brief object representing an installed Plasmagik package + **/ + +class PackageStructure; + +class Package +{ + public: + /** + * Default constructor + * + * @arg packageRoot path to the package installation root + * @arg package the name of the package + * @arg structure the package structure describing this package + **/ + Package(const QString& packageRoot, const QString& package, + const PackageStructure& structure); + ~Package(); + + /** + * Get the path to a given file. + * + * @arg fileType the type of file to look for, as defined in the + * package structure + * @arg filename the name of the file + * @return path to the file on disk. QString() if not found. + **/ + QString filePath(const char* fileType, const QString& filename); + + /** + * Get the path to a given file. + * + * @arg fileType the type of file to look for, as defined in the + * package structure. The type must refer to a file + * in the package structure and not a directory. + * @return path to the file on disk. QString() if not found + **/ + QString filePath(const char* fileType); + + /** + * Get the list of files of a given type. + * + * @arg fileType the type of file to look for, as defined in the + * package structure. + * @return list of files by name, suitable for passing to filePath + **/ + QStringList entryList(const char* fileType); + + /** + * + * + * @param packageRoot path to the directory where Plasmagik packages + * have been installed to + * @return a list of installed Plasmagik packages + **/ + static QStringList knownPackages(const QString& packageRoot); + + /** + * @param package path to the Plasmagik package + * @param packageRoot path to the directory where the package should be + * installed to + * @return true on successful installation, false otherwise + **/ + static bool installPackage(const QString& package, const QString& packageRoot); + + private: + class Private; + Private * const d; +}; + +} // Namespace diff --git a/packagemetadata.cpp b/packagemetadata.cpp new file mode 100644 index 000000000..2fe7ea9ac --- /dev/null +++ b/packagemetadata.cpp @@ -0,0 +1,265 @@ +/****************************************************************************** +* Copyright (C) 2007 by Riccardo Iaconelli * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#include + +#include + +#include +#include + +namespace Plasma +{ + +class PackageMetadata::Private +{ + public: + QString name; + QString description; + QString author; + QString email; + QString version; + QString website; + QString license; + QString mainFile; + QString app; + QString requiredVersion; + QString releaseNotes; + QString icon; + QString preview; + QString type; +}; + +PackageMetadata::PackageMetadata() + : d(new Private) +{ +} + +PackageMetadata::PackageMetadata(const QString& path) + : d(new Private) +{ + read(path); +} + +PackageMetadata::~PackageMetadata() +{ + delete d; +} + +bool PackageMetadata::isComplete() +{ + if (d->name.isEmpty() || +// d->description.isEmpty() || + d->author.isEmpty() || + d->version.isEmpty() || + d->license.isEmpty() || +// d->mainFile.isEmpty() || + d->app.isEmpty() || +// d->requiredVersion.isEmpty() || + d->type.isEmpty()) { + return false; + } else { + return true; + } +} + +void PackageMetadata::write(const QString& filename) +{ + KConfig cfg(filename); + KConfigGroup config(&cfg, "Desktop Entry"); + config.writeEntry("Encoding", "UTF-8"); + + //TODO: this will be a problem for localized names? + config.writeEntry("Name", d->name); + config.writeEntry("Description", d->description); + config.writeEntry("Icon", d->icon); + config.writeEntry("X-KDE-PluginInfo-Name", d->name); + config.writeEntry("X-KDE-PluginInfo-Author", d->author); + config.writeEntry("X-KDE-PluginInfo-Email", d->email); + config.writeEntry("X-KDE-PluginInfo-Version", d->version); + config.writeEntry("X-KDE-PluginInfo-Website", d->website); + config.writeEntry("X-KDE-PluginInfo-License", d->license); + config.writeEntry("X-KDE-PluginInfo-Category", d->type); + config.writeEntry("X-KDE-Plasmagik-MainFile", d->mainFile); + config.writeEntry("X-KDE-Plasmagik-ApplicationName", d->app); + config.writeEntry("X-KDE-Plasmagik-RequiredVersion", d->requiredVersion); +} + +void PackageMetadata::read(const QString& filename) +{ + KConfig cfg(filename); + KConfigGroup config(&cfg, "Desktop Entry"); + + //TODO: this will be a problem for localized names? + d->name = config.readEntry("X-KDE-PluginInfo-Name", d->name); + d->description = config.readEntry("Description", d->description); + d->icon = config.readEntry("Icon", d->icon); + d->author = config.readEntry("X-KDE-PluginInfo-Author", d->author); + d->email = config.readEntry("X-KDE-PluginInfo-Email", d->email); + d->version = config.readEntry("X-KDE-PluginInfo-Version", d->version); + d->website = config.readEntry("X-KDE-PluginInfo-Website", d->website); + d->license = config.readEntry("X-KDE-PluginInfo-License", d->license); + d->type = config.readEntry("X-KDE-PluginInfo-Category", d->type); + d->mainFile = config.readEntry("X-KDE-Plasmagik-MainFile", d->mainFile); + d->app = config.readEntry("X-KDE-Plasmagik-ApplicationName", d->app); + d->requiredVersion = config.readEntry("X-KDE-Plasmagik-RequiredVersion", d->requiredVersion); +} + +QString PackageMetadata::name() +{ + return d->name; +} + +QString PackageMetadata::description() +{ + return d->description; +} + +QString PackageMetadata::author() +{ + return d->author; +} + +QString PackageMetadata::email() +{ + return d->email; +} + +QString PackageMetadata::version() +{ + return d->version; +} + +QString PackageMetadata::website() +{ + return d->website; +} + +QString PackageMetadata::license() +{ + return d->license; +} + +QString PackageMetadata::mainFile() +{ + return d->mainFile; +} + +QString PackageMetadata::application() +{ + return d->app; +} + +QString PackageMetadata::requiredVersion() +{ + return d->requiredVersion; +} + +QString PackageMetadata::releaseNotes() +{ + return d->releaseNotes; +} + +QString PackageMetadata::icon() +{ + return d->icon; +} + +QString PackageMetadata::preview() +{ + return d->preview; +} + +QString PackageMetadata::type() +{ + return d->type; +} + +void PackageMetadata::setName(const QString &name) +{ + d->name = name; +} + +void PackageMetadata::setDescription(const QString &description) +{ + d->description = description; +} + +void PackageMetadata::setAuthor(const QString &author) +{ + d->author = author; +} + +void PackageMetadata::setEmail(const QString &email) +{ + d->email = email; +} + +void PackageMetadata::setVersion(const QString &version) +{ + d->version = version; +} + +void PackageMetadata::setWebsite(const QString &website) +{ + d->website = website; +} + +void PackageMetadata::setLicense(const QString &license) +{ + d->license = license; +} + +void PackageMetadata::setMainFile(const QString &mainFile) +{ + d->mainFile = mainFile; +} +void PackageMetadata::setApplication(const QString &application) +{ + d->app = application; +} + +void PackageMetadata::setRequiredVersion(const QString &requiredVersion) +{ + d->requiredVersion = requiredVersion; +} + +void PackageMetadata::setReleaseNotes(const QString &releaseNotes) +{ + d->releaseNotes = releaseNotes; +} + +void PackageMetadata::setIcon(const QString &icon) +{ + d->icon = icon; +} + +void PackageMetadata::setPreview(const QString& path) +{ + d->preview = path; +} + +void PackageMetadata::setType(const QString& type) +{ + d->type = type; +} + +} // namespace Plasma + + diff --git a/packagemetadata.h b/packagemetadata.h new file mode 100644 index 000000000..0d79771e5 --- /dev/null +++ b/packagemetadata.h @@ -0,0 +1,125 @@ +/****************************************************************************** +* Copyright (C) 2007 by Riccardo Iaconelli * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#ifndef PACKAGEMETADATA_H +#define PACKAGEMETADATA_H + +#include +#include + +namespace Plasma +{ + +class KDE_EXPORT PackageMetadata +{ +public: + /** + * Default constructor + **/ + PackageMetadata(); + + /** + * Constructs a metadata object using the values in the file at path + * + * @param path path to a metadata.desktop file + **/ + PackageMetadata(const QString& path); + ~PackageMetadata(); + + bool isComplete(); + + /** + * Writes out the metadata to filename, which should be a .desktop + * file. It writes out the information in a format that is compatible + * with KPluginInfo + * @see KPluginInfo + * + * @arg filename path to the file to write to + **/ + void write(const QString& filename); + + /** + * Reads in metadata from a file, which should be a .desktop + * file. It writes out the information in a format that is compatible + * with KPluginInfo + * @see KPluginInfo + * + * @arg filename path to the file to write to + **/ + void read(const QString& filename); + + QString name(); + QString description(); + QString author(); + QString email(); + QString version(); + QString website(); + QString license(); + QString mainFile(); + QString application(); + QString requiredVersion(); + QString releaseNotes(); + QString filenameToSave(); + // filename + QString icon(); + + /** + * Path to a PNG file containing a preview image. + * This might be a screenshot, for instance. + * + * @return path to a local image file, or QString() if no + * preview is available + **/ + QString preview(); + + QString type(); + + void setName(const QString &); + void setDescription(const QString &); + void setAuthor(const QString &); + void setEmail(const QString &); + void setVersion(const QString &); + void setWebsite(const QString &); + void setLicense(const QString &); + void setMainFile(const QString &); + void setApplication(const QString &); + void setRequiredVersion(const QString &); + void setReleaseNotes(const QString &); + void setFilenameToSave(const QString &); + // filename + void setIcon(const QString &); + + /** + * Sets the path for the file containing a preview image. + * This might be a screenshot, for instance. + * A PNG is expected. + * + * @args path path to the preview image file + **/ + void setPreview(const QString & path); + + void setType(const QString& type); + +private: + class Private; + Private * const d; +}; + +} +#endif diff --git a/packager.cpp b/packager.cpp new file mode 100644 index 000000000..d44eb65fc --- /dev/null +++ b/packager.cpp @@ -0,0 +1,109 @@ +/****************************************************************************** +* Copyright (C) 2007 by Riccardo Iaconelli * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Plasma +{ + +class Packager::Private +{ + public: + PackageMetadata* metadata; +}; + +Packager::Packager(PackageMetadata *metadata) + : d(new Private) +{ + d->metadata = metadata; +} + +Packager::~Packager() +{ + delete d; +} + +const PackageMetadata* Packager::metadata() +{ + return d->metadata; +} + +void Packager::setMetadata(PackageMetadata *metadata) +{ + d->metadata = metadata; +} + +bool Packager::createPackage(const QString& destination, const QString& source) +{ + if (!d->metadata->isComplete()) { + kWarning(550) << "Metadata file is not complete" << endl; + return false; + } + + KTemporaryFile metadataFile; + metadataFile.open(); + d->metadata->write(metadataFile.fileName()); + + KTemporaryFile releaseNotes; + //We just write the content of the QString containing the metadata in an + //empty temporary file that we will package with the name metadata.desktop + if (releaseNotes.open()) { + QTextStream out(&releaseNotes); + if (d->metadata->releaseNotes().isEmpty()) { + out << d->metadata->releaseNotes(); + } else { + out << "NO_RELEASE_NOTES"; + } + } + + //OK, we've got the temporary file with the metadata in it. + //Now we just need to put everything into a zip archive. + KZip creation(destination); + creation.setCompression(KZip::NoCompression); + + if (!creation.open(QIODevice::WriteOnly)) { + return false; + } + + creation.addLocalFile(metadataFile.fileName(), "metadata.desktop"); + creation.addLocalFile(releaseNotes.fileName(), "notes.txt"); + + if (!d->metadata->icon().isEmpty()) { + //TODO: just one icon? + creation.addLocalFile(d->metadata->icon(), "icon.png"); + } + + if (!d->metadata->preview().isEmpty()) { + //TODO: just one icon? + creation.addLocalFile(d->metadata->preview(), "preview.png"); + } + + creation.addLocalDirectory(source, "contents/"); + creation.close(); + return true; +} + +} // Plasma namespace diff --git a/packager.h b/packager.h new file mode 100644 index 000000000..bf0fcd467 --- /dev/null +++ b/packager.h @@ -0,0 +1,57 @@ +/****************************************************************************** +* Copyright (C) 2007 by Riccardo Iaconelli * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#ifndef PACKAGER_H +#define PACKAGER_H +#include + +class KTemporaryFile; + +namespace Plasma +{ +class PackageMetadata; +class PackagerPrivate; + +class KDE_EXPORT Packager +{ +public: + Packager(PackageMetadata *metadata); + ~Packager(); + + void setMetadata(PackageMetadata *metadata); + const PackageMetadata* metadata(); + + // If Metadata::isComplete() returns false, the packaging won't be done + // returns: true if successful, false otherwise + /** + * Creates a package of the contents + * + * @arg destination the path of the file to create the package as + * @arg source the directory containing the contents to package up + **/ + bool createPackage(const QString& destination, const QString& source); + +private: + KTemporaryFile* generateMetadata(); + class Private; + Private * const d; +}; + +} +#endif diff --git a/packagestructure.cpp b/packagestructure.cpp new file mode 100644 index 000000000..4a0cf988f --- /dev/null +++ b/packagestructure.cpp @@ -0,0 +1,188 @@ +/****************************************************************************** +* Copyright (C) 2007 by Aaron Seigo * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#include "packagestructure.h" + +#include + +namespace Plasma +{ + +class ContentStructure +{ + public: + ContentStructure() + : directory(false), + required(false) + { + } + + QString path; + QString name; + QStringList mimetypes; + bool directory; + bool required; +}; + +class PackageStructure::Private +{ + public: + QString type; + QHash contents; +}; + +PackageStructure::PackageStructure(const QString &type) + : d(new Private) +{ + d->type = type; +} + +PackageStructure::PackageStructure(const PackageStructure& rhs) + : d(new Private) +{ + *d = *rhs.d; +} + +PackageStructure::~PackageStructure() +{ + delete d; +} + +PackageStructure& PackageStructure::operator=(const PackageStructure& rhs) +{ + if (this == &rhs) { + return *this; + } + + *d = *rhs.d; + return *this; +} + +QString PackageStructure::type() +{ + return d->type; +} + +QStringList PackageStructure::directories() +{ + QStringList dirs; + QHash::const_iterator it = d->contents.constBegin(); + while (it != d->contents.constEnd()) { + if (it.value().directory) { + dirs << it.value().path; + } + ++it; + } + return dirs; +} + +QStringList PackageStructure::files() +{ + QStringList files; + QHash::const_iterator it = d->contents.constBegin(); + while (it != d->contents.constEnd()) { + if (!it.value().directory) { + files << it.value().path; + } + ++it; + } + return files; +} + +void PackageStructure::addDirectoryDefinition(const char* key, const QString& path, const QString& name) +{ + ContentStructure s; + s.name = name; + s.path = path; + + d->contents[key] = s; +} + +void PackageStructure::addFileDefinition(const char* key, const QString& path, const QString& name) +{ + ContentStructure s; + s.name = name; + s.path = path; + s.directory = false; + + d->contents[key] = s; +} + +QString PackageStructure::path(const char* key) +{ + QHash::const_iterator it = d->contents.find(key); + if (it == d->contents.constEnd()) { + return QString(); + } + + return it.value().path; +} + +QString PackageStructure::name(const char* key) +{ + QHash::const_iterator it = d->contents.find(key); + if (it == d->contents.constEnd()) { + return QString(); + } + + return it.value().name; +} + +void PackageStructure::setRequired(const char* key, bool required) +{ + QHash::iterator it = d->contents.find(key); + if (it == d->contents.end()) { + return; + } + + it.value().required = required; +} + +bool PackageStructure::required(const char* key) +{ + QHash::const_iterator it = d->contents.find(key); + if (it == d->contents.constEnd()) { + return false; + } + + return it.value().required; +} + +void PackageStructure::setMimetypes(const char* key, QStringList mimetypes) +{ + QHash::iterator it = d->contents.find(key); + if (it == d->contents.end()) { + return; + } + + it.value().mimetypes = mimetypes; +} + +QStringList PackageStructure::mimetypes(const char* key) +{ + QHash::const_iterator it = d->contents.find(key); + if (it == d->contents.constEnd()) { + return QStringList(); + } + + return it.value().mimetypes; +} + +} // Plasma namespace + diff --git a/packagestructure.h b/packagestructure.h new file mode 100644 index 000000000..5102984bc --- /dev/null +++ b/packagestructure.h @@ -0,0 +1,164 @@ +/****************************************************************************** +* Copyright (C) 2007 by Aaron Seigo * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#ifndef PACKAGESTRUCTURE_H +#define PACKAGESTRUCTURE_H + +#include + +#include + +namespace Plasma +{ + +/** + * @brief A description of the expected file structure of a given package type + * + * PackageStructure defines what is in a package. This information is used + * to create packages and provides a way to programatically refer to contents. + * + * An example usage of this class might be: + * + @code + PackageStructure structure; + + structure.addDirectoryDefinition("images", "pics/", i18n("Images"); + QStringList mimetypes; + mimetypes << "image/svg" << "image/png" << "image/jpeg"; + structure.setMimetypes("images", mimetypes); + + structure.addDirectoryDefinition("scripts", "code/", i18n("Executable Scripts")); + mimetypes.clear(); + mimetypes << "text/\*"; + structure.setMimetypes("scripts", mimetypes); + + structure.addFileDefinition("mainscript", "code/main.js", i18n("Main Script File")); + structure.setRequired("mainscript", true); + @endcode + * One may also choose to create a subclass of PackageStructure and include the setup + * in the constructor. + * + * Either way, PackageStructure creates a sort of "contract" between the packager and + * the application which is also self-documenting. + **/ +class KDE_EXPORT PackageStructure +{ +public: + /** + * Default constructor for a package structure definition + * + * @arg type the type of package. This is often application specific. + **/ + PackageStructure(const QString &type); + + /** + * Type of package this structure describes + **/ + QString type(); + + /** + * The directories defined for this package + **/ + QStringList directories(); + + /** + * The individual files defined for this package + **/ + QStringList files(); + + /** + * Adds a directory to the structure of the package. It is added as + * a not-required element with no associated mimetypes. + * + * @param key used as an internal label for this directory + * @param path the path within the the package for this directory + * @param name the user visible (translated) name for the directory + **/ + void addDirectoryDefinition(const char* key, const QString& path, const QString& name); + + /** + * Adds a file to the structure of the package. It is added as + * a not-required element with no associated mimetypes. + * + * @param key used as an internal label for this file + * @param path the path within the the package for this file + * @param name the user visible (translated) name for the file + **/ + void addFileDefinition(const char* key, const QString& path, const QString& name); + + /** + * @return path relative to the package root for the given entry + **/ + QString path(const char* key); + + /** + * @return user visible name for the given entry + **/ + QString name(const char* key); + + /** + * Sets whether or not a given part of the structure is required or not. + * The path must already have been added using addDirectoryDefinition + * or addFileDefinition. + * + * @param path the path of the entry within the package + */ + void setRequired(const char* key, bool required); + + /** + * @return true if the item at path exists and is required + **/ + bool required(const char* key); + + /** + * Define mimetypes for a given part of the structure + * The path must already have been added using addDirectoryDefinition + * or addFileDefinition. + * + * @param path the path of the entry within the package + **/ + void setMimetypes(const char* key, QStringList mimetypes); + + /** + * @return the mimetypes associated with the path, if any + **/ + QStringList mimetypes(const char* key); + + /** + * Copy constructor + **/ + PackageStructure(const PackageStructure& rhs); + + /** + * Destructor + **/ + virtual ~PackageStructure(); + + /** + * Assignment operator + **/ + PackageStructure& operator=(const PackageStructure& rhs); + +private: + class Private; + Private * const d; +}; + +} // Plasma namespace +#endif