From eb5522104aa6913e633b023160af532c98a9c9b0 Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Sun, 17 Jun 2007 00:25:16 +0000 Subject: [PATCH] add the non-gui packaging files to libplasma svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=676505 --- CMakeLists.txt | 17 +++ package.cpp | 203 +++++++++++++++++++++++++++++++++ package.h | 94 +++++++++++++++ packagemetadata.cpp | 265 +++++++++++++++++++++++++++++++++++++++++++ packagemetadata.h | 125 ++++++++++++++++++++ packager.cpp | 109 ++++++++++++++++++ packager.h | 57 ++++++++++ packagestructure.cpp | 188 ++++++++++++++++++++++++++++++ packagestructure.h | 164 ++++++++++++++++++++++++++ 9 files changed, 1222 insertions(+) create mode 100644 package.cpp create mode 100644 package.h create mode 100644 packagemetadata.cpp create mode 100644 packagemetadata.h create mode 100644 packager.cpp create mode 100644 packager.h create mode 100644 packagestructure.cpp create mode 100644 packagestructure.h 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