FEATURE: fallback paths for the contents prefixes as well.
this is basically a merge of http://reviewboard.kde.org/r/5765/ with http://svn.reviewboard.kde.org/r/5763 svn path=/trunk/KDE/kdelibs/; revision=1193135
This commit is contained in:
parent
c09422cc8c
commit
5e9d88496a
80
package.cpp
80
package.cpp
@ -158,15 +158,23 @@ Package &Package::operator=(const Package &rhs)
|
||||
|
||||
bool Package::isValid() const
|
||||
{
|
||||
if (!d->valid) {
|
||||
if (!d->valid || d->structure->contentsPrefixPaths().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//search for the file in all prefixes and in all possible paths for each prefix
|
||||
//even if it's a big nested loop, usually there is one prefix and one location
|
||||
//so shouldn't cause too much disk access
|
||||
foreach (const char *dir, d->structure->requiredDirectories()) {
|
||||
bool failed = true;
|
||||
foreach (const QString &path, d->structure->searchPath(dir)) {
|
||||
if (QFile::exists(d->structure->path() + d->structure->contentsPrefix() + path)) {
|
||||
failed = false;
|
||||
foreach (const QString &prefix, d->structure->contentsPrefixPaths()) {
|
||||
if (QFile::exists(d->structure->path() + prefix + path)) {
|
||||
failed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!failed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -181,8 +189,13 @@ bool Package::isValid() const
|
||||
foreach (const char *file, d->structure->requiredFiles()) {
|
||||
bool failed = true;
|
||||
foreach (const QString &path, d->structure->searchPath(file)) {
|
||||
if (QFile::exists(d->structure->path() + d->structure->contentsPrefix() + path)) {
|
||||
failed = false;
|
||||
foreach (const QString &prefix, d->structure->contentsPrefixPaths()) {
|
||||
if (QFile::exists(d->structure->path() + prefix + path)) {
|
||||
failed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!failed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -213,28 +226,35 @@ QString Package::filePath(const char *fileType, const QString &filename) const
|
||||
//kDebug() << "no matching path came of it, while looking for" << fileType << filename;
|
||||
return QString();
|
||||
}
|
||||
//when filetype is empty paths is always empty, so try with an empty string
|
||||
} else {
|
||||
paths << QString();
|
||||
}
|
||||
|
||||
const QString prefix(d->structure->path() + d->structure->contentsPrefix());
|
||||
//Nested loop, but in the medium case resolves to just one iteration
|
||||
foreach (const QString &contentsPrefix, d->structure->contentsPrefixPaths()) {
|
||||
const QString prefix(d->structure->path() + contentsPrefix);
|
||||
|
||||
foreach (const QString &path, paths) {
|
||||
QString file = prefix + path;
|
||||
foreach (const QString &path, paths) {
|
||||
QString file = prefix + path;
|
||||
|
||||
if (!filename.isEmpty()) {
|
||||
file.append("/").append(filename);
|
||||
}
|
||||
|
||||
if (QFile::exists(file)) {
|
||||
if (d->structure->allowExternalPaths()) {
|
||||
return file;
|
||||
if (!filename.isEmpty()) {
|
||||
file.append("/").append(filename);
|
||||
}
|
||||
|
||||
// ensure that we don't return files outside of our base path
|
||||
// due to symlink or ../ games
|
||||
QDir dir(file);
|
||||
QString canonicalized = dir.canonicalPath() + QDir::separator();
|
||||
if (canonicalized.startsWith(d->structure->path())) {
|
||||
return file;
|
||||
if (QFile::exists(file)) {
|
||||
if (d->structure->allowExternalPaths()) {
|
||||
return file;
|
||||
}
|
||||
|
||||
// ensure that we don't return files outside of our base path
|
||||
// due to symlink or ../ games
|
||||
QDir dir(file);
|
||||
QString canonicalized = dir.canonicalPath() + QDir::separator();
|
||||
|
||||
if (canonicalized.startsWith(d->structure->path())) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -351,13 +371,6 @@ QString Package::contentsHash() const
|
||||
return QString();
|
||||
}
|
||||
|
||||
const QString basePath = d->structure->path() + d->structure->contentsPrefix();
|
||||
QDir dir(basePath);
|
||||
|
||||
if (!dir.exists()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QCA::Hash hash("sha1");
|
||||
QString metadataPath = d->structure->path() + "metadata.desktop";
|
||||
if (QFile::exists(metadataPath)) {
|
||||
@ -373,7 +386,16 @@ QString Package::contentsHash() const
|
||||
kWarning() << "no metadata at" << metadataPath;
|
||||
}
|
||||
|
||||
d->updateHash(basePath, QString(), dir, hash);
|
||||
foreach (QString prefix, d->structure->contentsPrefixPaths()) {
|
||||
const QString basePath = d->structure->path() + prefix;
|
||||
QDir dir(basePath);
|
||||
|
||||
if (!dir.exists()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
d->updateHash(basePath, QString(), dir, hash);
|
||||
}
|
||||
return QCA::arrayToHex(hash.final().toByteArray());
|
||||
#else
|
||||
// no QCA2!
|
||||
|
@ -75,12 +75,12 @@ class PackageStructurePrivate
|
||||
public:
|
||||
PackageStructurePrivate(const QString &t)
|
||||
: type(t),
|
||||
contentsPrefix("contents/"),
|
||||
packageRoot("plasma/plasmoids"),
|
||||
servicePrefix("plasma-applet-"),
|
||||
metadata(0),
|
||||
externalPaths(false)
|
||||
{
|
||||
contentsPrefixPaths << "contents/";
|
||||
}
|
||||
|
||||
~PackageStructurePrivate()
|
||||
@ -94,7 +94,7 @@ public:
|
||||
|
||||
QString type;
|
||||
QString path;
|
||||
QString contentsPrefix;
|
||||
QStringList contentsPrefixPaths;
|
||||
QString packageRoot;
|
||||
QString servicePrefix;
|
||||
QMap<QByteArray, ContentStructure> contents;
|
||||
@ -282,22 +282,25 @@ QStringList PackageStructure::entryList(const char *key)
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QDir dir(d->path + d->contentsPrefix + p);
|
||||
QStringList list;
|
||||
foreach (QString prefix, d->contentsPrefixPaths) {
|
||||
QDir dir(d->path + prefix + p);
|
||||
|
||||
if (dir.exists()) {
|
||||
if (d->externalPaths) {
|
||||
return dir.entryList(QDir::Files | QDir::Readable);
|
||||
}
|
||||
if (dir.exists()) {
|
||||
if (d->externalPaths) {
|
||||
return dir.entryList(QDir::Files | QDir::Readable);
|
||||
}
|
||||
|
||||
// ensure that we don't return files outside of our base path
|
||||
// due to symlink or ../ games
|
||||
QString canonicalized = dir.canonicalPath();
|
||||
if (canonicalized.startsWith(d->path)) {
|
||||
return dir.entryList(QDir::Files | QDir::Readable);
|
||||
// ensure that we don't return files outside of our base path
|
||||
// due to symlink or ../ games
|
||||
QString canonicalized = dir.canonicalPath();
|
||||
if (canonicalized.startsWith(d->path)) {
|
||||
list << dir.entryList(QDir::Files | QDir::Readable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QStringList();
|
||||
return list;
|
||||
}
|
||||
|
||||
void PackageStructure::addDirectoryDefinition(const char *key,
|
||||
@ -469,7 +472,7 @@ void PackageStructure::read(const KConfigBase *config)
|
||||
d->mimetypes.clear();
|
||||
KConfigGroup general(config, QString());
|
||||
d->type = general.readEntry("Type", QString());
|
||||
d->contentsPrefix = general.readEntry("ContentsPrefix", d->contentsPrefix);
|
||||
d->contentsPrefixPaths = general.readEntry("ContentsPrefixPaths", d->contentsPrefixPaths);
|
||||
d->packageRoot = general.readEntry("DefaultPackageRoot", d->packageRoot);
|
||||
d->externalPaths = general.readEntry("AllowExternalPaths", d->externalPaths);
|
||||
|
||||
@ -499,7 +502,7 @@ void PackageStructure::write(KConfigBase *config) const
|
||||
{
|
||||
KConfigGroup general = KConfigGroup(config, "");
|
||||
general.writeEntry("Type", type());
|
||||
general.writeEntry("ContentsPrefix", d->contentsPrefix);
|
||||
general.writeEntry("ContentsPrefixPaths", d->contentsPrefixPaths);
|
||||
general.writeEntry("DefaultPackageRoot", d->packageRoot);
|
||||
general.writeEntry("AllowExternalPaths", d->externalPaths);
|
||||
|
||||
@ -524,12 +527,23 @@ void PackageStructure::write(KConfigBase *config) const
|
||||
|
||||
QString PackageStructure::contentsPrefix() const
|
||||
{
|
||||
return d->contentsPrefix;
|
||||
return d->contentsPrefixPaths.first();
|
||||
}
|
||||
|
||||
void PackageStructure::setContentsPrefix(const QString &prefix)
|
||||
{
|
||||
d->contentsPrefix = prefix;
|
||||
d->contentsPrefixPaths.clear();
|
||||
d->contentsPrefixPaths << prefix;
|
||||
}
|
||||
|
||||
QStringList PackageStructure::contentsPrefixPaths() const
|
||||
{
|
||||
return d->contentsPrefixPaths;
|
||||
}
|
||||
|
||||
void PackageStructure::setContentsPrefixPaths(const QStringList &prefixPaths)
|
||||
{
|
||||
d->contentsPrefixPaths = prefixPaths;
|
||||
}
|
||||
|
||||
bool PackageStructure::installPackage(const QString &package, const QString &packageRoot)
|
||||
|
@ -169,7 +169,9 @@ public:
|
||||
QString path(const char *key) const;
|
||||
|
||||
/**
|
||||
* @return a list of paths relative to the package root for the given entry
|
||||
* @return a list of paths relative to the package root for the given entry.
|
||||
* They are orted by importance: when searching for a file the paths
|
||||
* will be searched in order
|
||||
* @since 4.6
|
||||
**/
|
||||
QStringList searchPath(const char *key) const;
|
||||
@ -284,8 +286,16 @@ public:
|
||||
|
||||
/**
|
||||
* @return the prefix inserted between the base path and content entries
|
||||
* @deprecated use contentsPrefixPaths() instead.
|
||||
*/
|
||||
QString contentsPrefix() const;
|
||||
KDE_DEPRECATED QString contentsPrefix() const;
|
||||
|
||||
/**
|
||||
* @return the prefix paths inserted between the base path and content entries, in order of priority.
|
||||
* When searching for a file, all paths will be tried in order.
|
||||
* @since 4.6
|
||||
*/
|
||||
QStringList contentsPrefixPaths() const;
|
||||
|
||||
/**
|
||||
* @return preferred package root. This defaults to plasma/plasmoids/
|
||||
@ -334,8 +344,22 @@ protected:
|
||||
* structure
|
||||
*
|
||||
* @arg prefix the directory prefix to use
|
||||
* @deprecated use setContentsPrefixPaths() instead.
|
||||
*/
|
||||
void setContentsPrefix(const QString &prefix);
|
||||
KDE_DEPRECATED void setContentsPrefix(const QString &prefix);
|
||||
|
||||
/**
|
||||
* Sets the prefixes that all the contents in this package should
|
||||
* appear under. This defaults to "contents/" and is added automatically
|
||||
* between the base path and the entries as defined by the package
|
||||
* structure. Multiple entries can be added.
|
||||
* In this case each file request will be searched in all prefixes in order,
|
||||
* and the first found will be returned.
|
||||
*
|
||||
* @arg prefix paths the directory prefix to use
|
||||
* @since 4.6
|
||||
*/
|
||||
void setContentsPrefixPaths(const QStringList &prefixPaths);
|
||||
|
||||
/**
|
||||
* Sets preferred package root.
|
||||
|
Loading…
x
Reference in New Issue
Block a user