diff --git a/src/tools/KDbUtils.h b/src/tools/KDbUtils.h index 670d51f8..533faf41 100644 --- a/src/tools/KDbUtils.h +++ b/src/tools/KDbUtils.h @@ -1,464 +1,464 @@ /* This file is part of the KDE project Copyright (C) 2003-2016 Jarosław Staniek Portions of kstandarddirs.cpp: Copyright (C) 1999 Sirtaj Singh Kang Copyright (C) 1999,2007 Stephan Kulow Copyright (C) 1999 Waldo Bastian Copyright (C) 2009 David Faure This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KDB_TOOLS_UTILS_H #define KDB_TOOLS_UTILS_H #include "kdb_export.h" #include "config-kdb.h" #include #include #include #include namespace KDbUtils { //! @return true if @a o has parent @a par (checks recursively) KDB_EXPORT bool hasParent(QObject* par, QObject* o); //! @return parent object of @a o that is of type @a type or @c nullptr if no such parent template inline type findParent(QObject* o, const char* className = nullptr) { if (!o) return nullptr; while ((o = o->parent())) { if (::qobject_cast< type >(o) && (!className || o->inherits(className))) return ::qobject_cast< type >(o); } return nullptr; } //! QDateTime - a hack needed because QVariant(QTime) has broken isNull() KDB_EXPORT QDateTime stringToHackedQTime(const QString& s); /*! Serializes @a map to the array pointed by @a array. KDbUtils::deserializeMap() can be used to deserialize this array back to map. Does nothing if @a array is @c nullptr. */ KDB_EXPORT void serializeMap(const QMap& map, QByteArray *array); /*! Serializes @a map to the string pointed by @a string. KDbUtils::deserializeMap() can be used to deserialize this array back to map. Does nothing if @a string is @c nullptr. */ KDB_EXPORT void serializeMap(const QMap& map, QString *string); /*! @return a map deserialized from a byte array @a array. @a array need to contain data previously serialized using KexiUtils::serializeMap(). */ KDB_EXPORT QMap deserializeMap(const QByteArray& array); /*! @return a map deserialized from @a string. @a string need to contain data previously serialized using KexiUtils::serializeMap(). */ KDB_EXPORT QMap deserializeMap(const QString& string); /*! @return a valid filename converted from @a string by: - replacing \\, /, :, *, ?, ", <, >, |, \n \\t characters with a space - simplifing whitespace by removing redundant space characters using QString::simplified() Do not pass full paths here, but only filename strings. */ KDB_EXPORT QString stringToFileName(const QString& string); /*! Performs a simple @a string encryption using rot47-like algorithm. Each character's unicode value is increased by 47 + i (where i is index of the character). The resulting string still contains readable characters but some of them can be non-ASCII. Does nothing if @a string is @c nullptr. @note Do not use this for data that can be accessed by attackers! */ KDB_EXPORT void simpleCrypt(QString *string); /*! Performs a simple @a string decryption using rot47-like algorithm, using opposite operations to KexiUtils::simpleCrypt(). @return true on success and false on failure. Failue means that one or more characters have unicode numbers smaller than value of 47 + i. On failure @a string is not altered. Does nothing and returns @c false if @a string is @c nullptr. */ KDB_EXPORT bool simpleDecrypt(QString *string); //! @internal KDB_EXPORT QString pointerToStringInternal(void* pointer, int size); //! @internal KDB_EXPORT void* stringToPointerInternal(const QString& string, int size); //! @return a pointer @a pointer safely serialized to string template QString pointerToString(type *pointer) { return pointerToStringInternal(pointer, sizeof(type*)); } //! @return a pointer of type @a type safely deserialized from @a string template type* stringToPointer(const QString& string) { return static_cast(stringToPointerInternal(string, sizeof(type*))); } //! @return value converted to text, squeezed to reasonable length, useful for debugging //! If the value is not a byte array or string, or if it's not longer than 1024 characters, //! @a value is returned. //! @since 3.1 KDB_EXPORT QVariant squeezedValue(const QVariant &value); //! @short Autodeleting hash template class AutodeletedHash : public QHash { public: //! Creates autodeleting hash as a copy of @a other. //! Auto-deletion is not enabled as it would cause double deletion for items. //! If you enable auto-deletion on here, make sure you disable it in the @a other hash. AutodeletedHash(const AutodeletedHash& other) : QHash(other), m_autoDelete(false) {} //! Creates empty autodeleting hash. //! Auto-deletion is enabled by default. AutodeletedHash(bool autoDelete = true) : QHash(), m_autoDelete(autoDelete) {} ~AutodeletedHash() { if (m_autoDelete) { qDeleteAll(*this); } } void setAutoDelete(bool set) { m_autoDelete = set; } bool autoDelete() const { return m_autoDelete; } void clear() { if (m_autoDelete) { qDeleteAll(*this); } QHash::clear(); } typename QHash::iterator erase(typename QHash::iterator pos) { typename QHash::iterator it = QHash::erase(pos); if (m_autoDelete) { delete it.value(); it.value() = 0; return it; } } typename QHash::iterator insert(const Key &key, const T &value) { if (m_autoDelete) { T &oldValue = QHash::operator[](key); if (oldValue && oldValue != value) { // only delete if differs delete oldValue; } } return QHash::insert(key, value); } - // note: no need to override insertMulti(), unite(), take(), they does not replace items + // note: no need to override insertMulti(), unite(), take(), they do not replace items private: bool m_autoDelete; }; //! @short Autodeleting list template class AutodeletedList : public QList { public: //! Creates autodeleting list as a copy of @a other. //! Auto-deletion is not enabled as it would cause double deletion for items. //! If you enable auto-deletion on here, make sure you disable it in the @a other list. AutodeletedList(const AutodeletedList& other) : QList(other), m_autoDelete(false) {} //! Creates empty autodeleting list. //! Auto-deletion is enabled by default. AutodeletedList(bool autoDelete = true) : QList(), m_autoDelete(autoDelete) {} ~AutodeletedList() { if (m_autoDelete) qDeleteAll(*this); } void setAutoDelete(bool set) { m_autoDelete = set; } bool autoDelete() const { return m_autoDelete; } void removeAt(int i) { T item = QList::takeAt(i); if (m_autoDelete) delete item; } void removeFirst() { T item = QList::takeFirst(); if (m_autoDelete) delete item; } void removeLast() { T item = QList::takeLast(); if (m_autoDelete) delete item; } void replace(int i, const T& value) { T item = QList::takeAt(i); insert(i, value); if (m_autoDelete) delete item; } void insert(int i, const T& value) { QList::insert(i, value); } typename QList::iterator erase(typename QList::iterator pos) { T item = *pos; typename QList::iterator res = QList::erase(pos); if (m_autoDelete) delete item; return res; } typename QList::iterator erase( typename QList::iterator afirst, typename QList::iterator alast) { if (!m_autoDelete) return QList::erase(afirst, alast); while (afirst != alast) { T item = *afirst; afirst = QList::erase(afirst); delete item; } return alast; } void pop_back() { removeLast(); } void pop_front() { removeFirst(); } int removeAll(const T& value) { if (!m_autoDelete) return QList::removeAll(value); typename QList::iterator it(QList::begin()); int removedCount = 0; while (it != QList::end()) { if (*it == value) { T item = *it; it = QList::erase(it); delete item; removedCount++; } else ++it; } return removedCount; } void clear() { if (!m_autoDelete) return QList::clear(); while (!QList::isEmpty()) { T item = QList::takeFirst(); delete item; } } private: bool m_autoDelete; }; //! @short Case insensitive hash container supporting QString or QByteArray keys. //! Keys are turned to lowercase before inserting. template class CaseInsensitiveHash : public QHash { public: CaseInsensitiveHash() : QHash() {} typename QHash::iterator find(const Key& key) const { return QHash::find(key.toLower()); } typename QHash::const_iterator constFind(const Key& key) const { return QHash::constFind(key.toLower()); } bool contains(const Key& key) const { return QHash::contains(key.toLower()); } int count(const Key& key) const { return QHash::count(key.toLower()); } typename QHash::iterator insert(const Key& key, const T& value) { return QHash::insert(key.toLower(), value); } typename QHash::iterator insertMulti(const Key& key, const T& value) { return QHash::insertMulti(key.toLower(), value); } const Key key(const T& value, const Key& defaultKey) const { return QHash::key(value, defaultKey.toLower()); } int remove(const Key& key) { return QHash::remove(key.toLower()); } const T take(const Key& key) { return QHash::take(key.toLower()); } const T value(const Key& key) const { return QHash::value(key.toLower()); } const T value(const Key& key, const T& defaultValue) const { return QHash::value(key.toLower(), defaultValue); } QList values(const Key& key) const { return QHash::values(key.toLower()); } T& operator[](const Key& key) { return QHash::operator[](key.toLower()); } const T operator[](const Key& key) const { return QHash::operator[](key.toLower()); } }; //! A set created from static (0-terminated) array of raw null-terminated strings. class KDB_EXPORT StaticSetOfStrings { public: StaticSetOfStrings(); explicit StaticSetOfStrings(const char* const array[]); ~StaticSetOfStrings(); void setStrings(const char* const array[]); bool isEmpty() const; //! @return true if @a string can be found within set, comparison is case sensitive bool contains(const QByteArray& string) const; private: class Private; Private * const d; Q_DISABLE_COPY(StaticSetOfStrings) }; /*! @return debugging string for object @a object of type @a T */ template QString debugString(const T& object) { QString result; QDebug dbg(&result); dbg << object; return result; } //! Used by findExe(). enum FindExeOption { NoFindExeOptions = 0, IgnoreExecBit = 1 }; Q_DECLARE_FLAGS(FindExeOptions, FindExeOption) /** * Finds the executable in the system path. * * A valid executable must be a file and have its executable bit set. * * @param appname The name of the executable file for which to search. * if this contains a path separator, it will be resolved * according to the current working directory * (shell-like behavior). * @param path The path which will be searched. If this is * null (default), the @c $PATH environment variable will * be searched. * @param options if the flags passed include IgnoreExecBit the path returned * may not have the executable bit set. * * @return The path of the executable. If it was not found, * it will return QString(). */ QString findExe(const QString& appname, const QString& path = QString(), FindExeOptions options = NoFindExeOptions); //! A single property //! @note This property is general-purpose and not related to Qt Properties. //! @see KDbUtils::PropertySet class KDB_EXPORT Property { public: //! Constructs a null property Property(); Property(const QVariant &aValue, const QString &aCaption); Property(const Property &other); ~Property(); bool operator==(const Property &other) const; bool operator!=(const Property &other) const { return !operator==(other); } bool isNull() const; QVariant value() const; void setValue(const QVariant &value); QString caption() const; void setCaption(const QString &caption); private: class Private; Private * const d; }; //! A set of properties. //! @note These properties are general-purpose and not related to Qt Properties. //! @see KDbUtils::Property class KDB_EXPORT PropertySet { public: PropertySet(); PropertySet(const PropertySet &other); ~PropertySet(); //! Assigns @a other to this property set and returns a reference to this property set. PropertySet& operator=(const PropertySet &other); //! @return true if this property set has exactly the same properties as @a other //! @since 3.1 bool operator==(const PropertySet &other) const; //! @return true if this property differs in at least one property from @a other //! @since 3.1 bool operator!=(const PropertySet &other) const { return !operator==(other); } //! Inserts property with a given @a name, @a value and @a caption. //! If @a caption is empty, caption from existing property is reused. //! @a name must be a valid identifier (see KDb::isIdentifier()). void insert(const QByteArray &name, const QVariant &value, const QString &caption = QString()); //! Sets caption for property @a name to @a caption. //! If such property does not exist, does nothing. //! @since 3.1 void setCaption(const QByteArray &name, const QString &caption); //! Sets value for property @a name to @a value. //! If such property does not exist, does nothing. //! @since 3.1 void setValue(const QByteArray &name, const QVariant &value); //! Removes property with a given @a name. void remove(const QByteArray &name); //! @return property with a given @a name. //! If not found, a null Property is returned (Property::isNull). Property property(const QByteArray &name) const; //! @return a list of property names. QList names() const; private: class Private; Private * const d; }; } // KDbUtils #endif //KDB_TOOLS_UTILS_H