Commit fd52a032 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Add hopefully temporary clone of the unexported kconfig classes

We want to be able to parse an io device, not a file on disk
to get the tags from a desktop file that can be in a zip file.
parent 2c4ba5f6
......@@ -13,10 +13,16 @@ set(kritaresources_LIB_SRCS
KisBundleStorage.cpp
KisFolderStorage.cpp
KisTagLoader.cpp
KoResource.cpp
KoMD5Generator.cpp
KoHashGeneratorProvider.cpp
KoResourcePaths.cpp
kconfigini.cpp
kconfigdata.cpp
kconfigbackend.cpp
)
qt5_add_resources(kritaresources_LIB_SRCS sql.qrc)
......
......@@ -39,8 +39,8 @@ public:
QDirIterator::Subdirectories));
}
bool hasNext() const override {return false; }
void next() const override {}
bool hasNext() const override { return m_dirIterator->hasNext(); }
void next() const override { m_dirIterator->next(); }
QString url() const override { return QString(); }
QString name() const override { return QString(); }
......
......@@ -19,7 +19,54 @@
#include "KisTagLoader.h"
#include <QIODevice>
#include <kconfigini_p.h>
class KisTagLoader::Private {
};
KisTagLoader::KisTagLoader()
{
}
QString KisTagLoader::name() const
{
return QString();
}
void KisTagLoader::setName(QString &name) const
{
}
QString KisTagLoader::url() const
{
return QString();
}
void KisTagLoader::setUrl(const QString &url) const
{
}
QString KisTagLoader::comment() const
{
return QString();
}
void KisTagLoader::setComment(const QString &comment) const
{
}
bool KisTagLoader::load(QIODevice &io)
{
return false;
}
bool KisTagLoader::save(QIODevice &io)
{
return false;
}
......@@ -20,6 +20,8 @@
#ifndef KISTAGLOADER_H
#define KISTAGLOADER_H
#include <QString>
#include <QScopedPointer>
/**
* @brief The KisTagLoader loads a tag from a .tag file.
* A .tag file is a .desktop file. The following fields
......@@ -28,11 +30,32 @@
* name: the name of the tag, which can be translated
* comment: a tooltip for the tag, which can be translagted
* url: the untranslated name of the tag
*
*/
class QIODevice;
class KisTagLoader
{
public:
KisTagLoader();
virtual ~KisTagLoader() {}
QString name() const;
void setName(QString &name) const;
QString url() const;
void setUrl(const QString &url) const;
QString comment() const;
void setComment(const QString &comment) const;
bool load(QIODevice &io);
bool save(QIODevice &io);
private:
class Private;
QScopedPointer<Private> d;
};
#endif // KISTAGLOADER_H
/*
This file is part of the KDE libraries
Copyright (c) 2008 Jakub Stachowski <qbast@go2.pl>
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 BUFFERFRAGMENT_H
#define BUFFERFRAGMENT_H
#include "kconfigini_p.h"
#define bf_isspace(str) ((str == ' ') || (str == '\t') || (str == '\r'))
// This class provides wrapper around fragment of existing buffer (array of bytes).
// If underlying buffer gets deleted, all BufferFragment objects referencing it become invalid.
// Use toByteArray() to make deep copy of the buffer fragment.
//
// API is designed to subset of QByteArray methods with some changes:
// - trim() is like QByteArray.trimmed(), but it modifies current object
// - truncateLeft() provides way to cut off beginning of the buffer
// - split() works more like strtok_r than QByteArray.split()
// - truncateLeft() and mid() require position argument to be valid
class KConfigIniBackend::BufferFragment
{
public:
BufferFragment() : d(nullptr), len(0)
{
}
BufferFragment(char *buf, int size) : d(buf), len(size)
{
}
int length() const
{
return len;
}
char at(unsigned int i) const
{
Q_ASSERT(i < len);
return d[i];
}
void clear()
{
len = 0;
}
const char *constData() const
{
return d;
}
char *data() const
{
return d;
}
void trim()
{
while (bf_isspace(*d) && len > 0) {
d++;
len--;
}
while (len > 0 && bf_isspace(d[len - 1])) {
len--;
}
}
// similar to strtok_r . On first call variable pointed by start should be set to 0.
// Each call will update *start to new starting position.
BufferFragment split(char c, unsigned int *start)
{
while (*start < len) {
int end = indexOf(c, *start);
if (end == -1) {
end = len;
}
BufferFragment line(d + (*start), end - (*start));
*start = end + 1;
return line;
}
return BufferFragment();
}
bool isEmpty() const
{
return !len;
}
BufferFragment left(unsigned int size) const
{
return BufferFragment(d, qMin(size, len));
}
void truncateLeft(unsigned int size)
{
Q_ASSERT(size <= len);
d += size;
len -= size;
}
void truncate(unsigned int pos)
{
if (pos < len) {
len = pos;
}
}
bool isNull() const
{
return !d;
}
BufferFragment mid(unsigned int pos, int length = -1) const
{
Q_ASSERT(pos < len);
int size = length;
if (length == -1 || (pos + length) > len) {
size = len - pos;
}
return BufferFragment(d + pos, size);
}
bool operator==(const QByteArray &other) const
{
return (other.size() == (int)len && memcmp(d, other.constData(), len) == 0);
}
bool operator!=(const QByteArray &other) const
{
return (other.size() != (int)len || memcmp(d, other.constData(), len) != 0);
}
bool operator==(const BufferFragment &other) const
{
return other.len == len && !memcmp(d, other.d, len);
}
int indexOf(char c, unsigned int from = 0) const
{
const char *cursor = d + from - 1;
const char *end = d + len;
while (++cursor < end)
if (*cursor == c) {
return cursor - d;
}
return -1;
}
int lastIndexOf(char c) const
{
int from = len - 1;
while (from >= 0)
if (d[from] == c) {
return from;
} else {
from--;
}
return -1;
}
QByteArray toByteArray() const
{
return QByteArray(d, len);
}
// this is faster than toByteArray, but returned QByteArray becomes invalid
// when buffer for this BufferFragment disappears
QByteArray toVolatileByteArray() const
{
return QByteArray::fromRawData(d, len);
}
private:
char *d;
unsigned int len;
};
uint qHash(const KConfigIniBackend::BufferFragment &fragment)
{
const uchar *p = reinterpret_cast<const uchar*>(fragment.constData());
const int len = fragment.length();
// This algorithm is copied from qhash.cpp (Qt5 version).
// Sadly this code is not accessible from the outside without going through abstraction
// layers. Even QByteArray::fromRawData would do an allocation internally...
uint h = 0;
for (int i = 0; i < len; ++i) {
h = 31 * h + p[i];
}
return h;
}
#endif
/*
This file is part of the KDE libraries
Copyright (c) 2006 Thomas Braxton <brax108@cox.net>
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
Copyright (c) 1997-1999 Matthias Kalle Dalheimer <kalle@kde.org>
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 "kconfigbackend_p.h"
#include <QDateTime>
#include <QStringList>
#include <QDir>
#include <QFileInfo>
#include <QHash>
#include <QDebug>
#include "kconfigini_p.h"
#include "kconfigdata.h"
typedef QExplicitlySharedDataPointer<KConfigBackend> BackendPtr;
class KConfigBackendPrivate
{
public:
QString localFileName;
static QString whatSystem(const QString & /*fileName*/)
{
return QStringLiteral("INI");
}
};
void KConfigBackend::registerMappings(const KEntryMap & /*entryMap*/)
{
}
BackendPtr KConfigBackend::create(const QString &file)
{
//qDebug() << "creating a backend for file" << file << "with system" << sys;
KConfigBackend *backend = nullptr;
//qDebug() << "default creation of the Ini backend";
backend = new KConfigIniBackend;
backend->setFilePath(file);
return BackendPtr(backend);
}
KConfigBackend::KConfigBackend()
: d(new KConfigBackendPrivate)
{
}
KConfigBackend::~KConfigBackend()
{
delete d;
}
QString KConfigBackend::filePath() const
{
return d->localFileName;
}
void KConfigBackend::setLocalFilePath(const QString &file)
{
d->localFileName = file;
}
/*
This file is part of the KDE libraries
Copyright (c) 2006, 2007 Thomas Braxton <kde.braxton@gmail.com>
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
Portions copyright (c) 1997 Matthias Kalle Dalheimer <kalle@kde.org>
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 KCONFIGBACKEND_H
#define KCONFIGBACKEND_H
#include <QObject>
#include <QString>
#include <QExplicitlySharedDataPointer>
#include <kconfigbase.h>
class KConfigBackendPrivate;
class KEntryMap;
class QFile;
class QByteArray;
/**
* \class KConfigBackend kconfigbackend_p.h <KConfigBackend>
*
* Provides the implementation for accessing configuration sources.
*
* KConfig only provides an INI backend, but this class can be used
* to create plugins that allow access to other file formats and
* configuration systems.
*
* \internal
*/
class KConfigBackend : public QObject, public QSharedData
{
Q_OBJECT
public:
/**
* Creates a new KConfig backend.
*
* If no @p system is given, or the given @p system is unknown, this method tries
* to determine the correct backend to use.
*
* @param fileName the absolute file name of the configuration file
* @param system the configuration system to use
* @return a KConfigBackend object to be used with KConfig
*/
static QExplicitlySharedDataPointer<KConfigBackend> create(const QString &fileName = QString());
/**
* Registers mappings from directories/files to configuration systems
*
* Allows you to tell KConfigBackend that create() should use a particular
* backend for a particular file or directory.
*
* @warning currently does nothing
*
* @param entryMap the KEntryMap to build the mappings from
*/
static void registerMappings(const KEntryMap &entryMap);
/** Destroys the backend */
virtual ~KConfigBackend();
/** Allows the behaviour of parseConfig() to be tuned */
enum ParseOption {
ParseGlobal = 1, /// entries should be marked as @em global
ParseDefaults = 2, /// entries should be marked as @em default
ParseExpansions = 4 /// entries are allowed to be marked as @em expandable
};
Q_FLAG(ParseOption)
/// @typedef typedef QFlags<ParseOption> ParseOptions
Q_DECLARE_FLAGS(ParseOptions, ParseOption)
/** Allows the behaviour of writeConfig() to be tuned */
enum WriteOption {
WriteGlobal = 1 /// only write entries marked as "global"
};
Q_FLAG(WriteOption)
/// @typedef typedef QFlags<WriteOption> WriteOptions
Q_DECLARE_FLAGS(WriteOptions, WriteOption)
/** Return value from parseConfig() */
enum ParseInfo {
ParseOk, /// the configuration was opened read/write
ParseImmutable, /// the configuration is @em immutable
ParseOpenError /// the configuration could not be opened
};
/**
* Read persistent storage
*
* @param locale the locale to read entries for (if the backend supports localized entries)
* @param pWriteBackMap the KEntryMap where the entries are placed
* @param options See ParseOptions
* @return See ParseInfo
*/
virtual ParseInfo parseConfig(const QByteArray &locale,
KEntryMap &pWriteBackMap,
ParseOptions options = ParseOptions()) = 0;
/**
* Write the @em dirty entries to permanent storage
*
* @param locale the locale to write entries for (if the backend supports localized entries)
* @param entryMap the KEntryMap containing the config object's entries.
* @param options See WriteOptions
*
* @return @c true if the write was successful, @c false if writing the configuration failed
*/
virtual bool writeConfig(const QByteArray &locale, KEntryMap &entryMap,
WriteOptions options) = 0;
/**
* If isWritable() returns false, writeConfig() will always fail.
*
* @return @c true if the configuration is writable, @c false if it is immutable
*/
virtual bool isWritable() const = 0;
/**
* When isWritable() returns @c false, return an error message to
* explain to the user why saving configuration will not work.
*
* The return value when isWritable() returns @c true is undefined.
*
* @returns a translated user-visible explanation for the configuration
* object not being writable
*/
virtual QString nonWritableErrorMessage() const = 0;
/**
* @return the read/write status of the configuration object
*
* @see KConfigBase::AccessMode
*/
virtual KConfigBase::AccessMode accessMode() const = 0;
/**
* Create the enclosing object of the configuration object
*
* For example, if the configuration object is a file, this should create
* the parent directory.
*/
virtual void createEnclosing() = 0;
/**
* Set the file path.
*
* @note @p path @b MUST be @em absolute.
*
* @param path the absolute file path
*/
virtual void setFilePath(const QString &path) = 0;
/**
* Lock the file
*/
virtual bool lock() = 0;
/**
* Release the lock on the file
*/
virtual void unlock() = 0;
/**
* @return @c true if the file is locked, @c false if it is not locked
*/
virtual bool isLocked() const = 0;
/** @return the absolute path to the object */
QString filePath() const;
protected:
KConfigBackend();
void setLocalFilePath(const QString &file);
private:
KConfigBackendPrivate *const d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KConfigBackend::ParseOptions)
Q_DECLARE_OPERATORS_FOR_FLAGS(KConfigBackend::WriteOptions)
#if 0 // TODO re-enable if the plugin loading code is re-enabled
/**
* Register a KConfig backend when it is contained in a loadable module
*/
#define K_EXPORT_KCONFIGBACKEND(libname, classname) \
K_PLUGIN_FACTORY(factory, registerPlugin<classname>();)
#endif
#endif // KCONFIGBACKEND_H
This diff is collapsed.
/*
This file is part of the KDE libraries
Copyright (c) 2006, 2007 Thomas Braxton <kde.braxton@gmail.com>
Copyright (c) 1999-2000 Preston Brown <pbrown@kde.org>
Copyright (C) 1996-2000 Matthias Kalle Dalheimer <kalle@kde.org>
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 KCONFIGDATA_H
#define KCONFIGDATA_H
#include <QByteArray>
#include <QString>
#include <QMap>
#include <QDebug>
/**
* map/dict/list config node entry.
* @internal
*/
struct KEntry {
/** Constructor. @internal */
KEntry()
: mValue(), bDirty(false),
bGlobal(false), bImmutable(false), bDeleted(false), bExpand(false), bReverted(false),
bLocalizedCountry(false) {}
/** @internal */
QByteArray mValue;
/**
* Must the entry be written back to disk?
*/
bool bDirty : 1;
/**
* Entry should be written to the global config file
*/
bool bGlobal: 1;
/**
* Entry can not be modified.
*/
bool bImmutable: 1;
/**
* Entry has been deleted.
*/
bool bDeleted: 1;
/**
* Whether to apply dollar expansion or not.
*/
bool bExpand: 1;
/**
* Entry has been reverted to its default value (from a more global file).
*/
bool bReverted: 1;
/**
* Entry is for a localized key. If @c false the value references just language e.g. "de",
* if @c true the value references language and country, e.g. "de_DE".
**/
bool bLocalizedCountry: 1;
};
// These operators are used to check whether an entry which is about
// to be written equals the previous value. As such, this intentionally
// omits the dirty flag from the comparison.
inline bool operator ==(const KEntry &k1, const KEntry &k2)
{
return k1.bGlobal == k2.bGlobal && k1.bImmutable == k2.bImmutable
&& k1.bDeleted == k2.bDeleted && k1.bExpand == k2.bExpand
&& k1.mValue == k2.mValue;
}
inline bool operator !=(const KEntry &k1, const KEntry &k2)
{
return !(k1 == k2);
}
/**
* key structure holding both the actual key and the group
* to which it belongs.
* @internal
*/
struct KEntryKey {
/** Constructor. @internal */
KEntryKey(const QByteArray &_group = QByteArray(),
const QByteArray &_key = QByteArray(), bool isLocalized = false, bool isDefault = false)
: mGroup(_group), mKey(_key), bLocal(isLocalized), bDefault(isDefault), bRaw(false)
{
;
}
/**
* The "group" to which this EntryKey belongs
*/
QByteArray mGroup;
/**
* The _actual_ key of the entry in question
*/
QByteArray mKey;
/**
* Entry is localised or not
*/
bool bLocal : 1;
/**
* Entry indicates if this is a default value.