KDb

KDbUtils.h
1/* This file is part of the KDE project
2 Copyright (C) 2003-2019 Jarosław Staniek <staniek@kde.org>
3
4 Portions of kstandarddirs.cpp:
5 Copyright (C) 1999 Sirtaj Singh Kang <taj@kde.org>
6 Copyright (C) 1999,2007 Stephan Kulow <coolo@kde.org>
7 Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
8 Copyright (C) 2009 David Faure <faure@kde.org>
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public License
21 along with this program; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24*/
25
26#ifndef KDB_TOOLS_UTILS_H
27#define KDB_TOOLS_UTILS_H
28
29#include "kdb_export.h"
30#include "config-kdb.h"
31
32#include <QObject>
33#include <QDateTime>
34#include <QMetaMethod>
35#include <QDebug>
36
37namespace KDbUtils
38{
39
40//! @return true if @a o has parent @a par (checks recursively)
41KDB_EXPORT bool hasParent(QObject* par, QObject* o);
42
43//! @return parent object of @a o that is of type @a type or @c nullptr if no such parent
44template<class type>
45inline type findParent(QObject* o, const char* className = nullptr)
46{
47 if (!o)
48 return nullptr;
49 while ((o = o->parent())) {
50 if (::qobject_cast< type >(o) && (!className || o->inherits(className)))
51 return ::qobject_cast< type >(o);
52 }
53 return nullptr;
54}
55
56/**
57 * Returns the time as a string using Qt::ISODateWithMs format
58 *
59 * If milliseconds is zero then they are not appended.
60 * Works also for Qt < 5.8 which does not offer QTime::toString(Qt::ISODateWithMs).
61 *
62 * @since 3.2
63 */
64KDB_EXPORT QString toISODateStringWithMs(const QTime &time);
65
66/**
67 * Returns the date/time as a string using Qt::ISODateWithMs format
68 *
69 * If milliseconds in time is zero then they are not appended.
70 * Works also for Qt < 5.8 which does not offer QDateTime::toString(Qt::ISODateWithMs).
71 *
72 * @since 3.2
73 */
74KDB_EXPORT QString toISODateStringWithMs(const QDateTime &dateTime);
75
76/**
77 * Returns the time represented by the string using the Qt::ISODateWithMs format
78 *
79 * Milliseconds are optional.
80 * Works also for Qt < 5.8 which does not offer QTime::fromString(QString, Qt::ISODateWithMs).
81 *
82 * @note Equal to QTime::fromString(string, Qt::ISODate) since the Qt::ISODate mode already
83 * supports milliseconds in case of fromString().
84 *
85 * @since 3.2
86 */
87KDB_EXPORT QTime timeFromISODateStringWithMs(const QString &string);
88
89/**
90 * Returns the date/time represented by the string using the Qt::ISODateWithMs format
91 *
92 * Milliseconds of time are optional.
93 * Works also for Qt < 5.8 which does not offer QDateTime::fromString(QString, Qt::ISODateWithMs).
94 *
95 * @note Equal to QDateTime::fromString(string, Qt::ISODate) since the Qt::ISODate mode already
96 * supports milliseconds in case of fromString().
97 *
98 * @since 3.2
99 */
100KDB_EXPORT QDateTime dateTimeFromISODateStringWithMs(const QString &string);
101
102//! QDateTime - a hack needed because QVariant(QTime) has broken isNull()
103KDB_EXPORT QDateTime stringToHackedQTime(const QString& s);
104
105/*! Serializes @a map to the array pointed by @a array.
106 KDbUtils::deserializeMap() can be used to deserialize this array back to map.
107 Does nothing if @a array is @c nullptr. */
108KDB_EXPORT void serializeMap(const QMap<QString, QString>& map, QByteArray *array);
109
110/*! Serializes @a map to the string pointed by @a string.
111 KDbUtils::deserializeMap() can be used to deserialize this array back to map.
112 Does nothing if @a string is @c nullptr. */
113KDB_EXPORT void serializeMap(const QMap<QString, QString>& map, QString *string);
114
115/*! @return a map deserialized from a byte array @a array.
116 @a array need to contain data previously serialized using KexiUtils::serializeMap(). */
117KDB_EXPORT QMap<QString, QString> deserializeMap(const QByteArray& array);
118
119/*! @return a map deserialized from @a string.
120 @a string need to contain data previously serialized using KexiUtils::serializeMap(). */
121KDB_EXPORT QMap<QString, QString> deserializeMap(const QString& string);
122
123/**
124 * Returns a valid filename converted from given string
125 *
126 * Following steps are performed:
127 * - replace \\, /, :, *, ?, ", <, >, |, \n \\t characters with a space,
128 * - simplify whitespace by removing redundant space characters using QString::simplified().
129 * - prepend '_' character if the first character is '.', so the file will not be considered hidden
130 * (since 3.2.0).
131 *
132 * @note Do not pass full paths here but only filename strings.
133 */
134KDB_EXPORT QString stringToFileName(const QString& string);
135
136/*! Performs a simple @a string encryption using rot47-like algorithm.
137 Each character's unicode value is increased by 47 + i (where i is index of the character).
138 The resulting string still contains readable characters but some of them can be non-ASCII.
139 Does nothing if @a string is @c nullptr.
140 @note Do not use this for data that can be accessed by attackers! */
141KDB_EXPORT void simpleCrypt(QString *string);
142
143/*! Performs a simple @a string decryption using rot47-like algorithm,
144 using opposite operations to KexiUtils::simpleCrypt().
145 @return true on success and false on failure. Failue means that one or more characters have unicode
146 numbers smaller than value of 47 + i. On failure @a string is not altered.
147 Does nothing and returns @c false if @a string is @c nullptr.
148*/
149KDB_EXPORT bool simpleDecrypt(QString *string);
150
151//! @internal
152KDB_EXPORT QString pointerToStringInternal(void* pointer, int size);
153//! @internal
154KDB_EXPORT void* stringToPointerInternal(const QString& string, int size);
155
156//! @return a pointer @a pointer safely serialized to string
157template<class type>
158QString pointerToString(type *pointer)
159{
160 return pointerToStringInternal(pointer, sizeof(type*));
161}
162
163//! @return a pointer of type @a type safely deserialized from @a string
164template<class type>
165type* stringToPointer(const QString& string)
166{
167 return static_cast<type*>(stringToPointerInternal(string, sizeof(type*)));
168}
169
170//! @return value converted to text, squeezed to reasonable length, useful for debugging
171//! If the value is not a byte array or string, or if it's not longer than 1024 characters,
172//! @a value is returned.
173//! @since 3.1
174KDB_EXPORT QVariant squeezedValue(const QVariant &value);
175
176//! @short Autodeleting hash
177template <class Key, class T>
178class AutodeletedHash : public QHash<Key, T>
179{
180public:
181 //! Creates autodeleting hash as a copy of @a other.
182 //! Auto-deletion is not enabled as it would cause double deletion for items.
183 //! If you enable auto-deletion on here, make sure you disable it in the @a other hash.
184 AutodeletedHash(const AutodeletedHash& other) : QHash<Key, T>(other), m_autoDelete(false) {}
185
186 //! Creates empty autodeleting hash.
187 //! Auto-deletion is enabled by default.
188 AutodeletedHash(bool autoDelete = true) : QHash<Key, T>(), m_autoDelete(autoDelete) {}
189
191 if (m_autoDelete) {
192 qDeleteAll(*this);
193 }
194 }
195 void setAutoDelete(bool set) {
196 m_autoDelete = set;
197 }
198 bool autoDelete() const {
199 return m_autoDelete;
200 }
201 void clear() {
202 if (m_autoDelete) {
203 qDeleteAll(*this);
204 }
206 }
207 typename QHash<Key, T>::iterator erase(typename QHash<Key, T>::iterator pos) {
209 if (m_autoDelete) {
210 delete it.value();
211 it.value() = 0;
212 return it;
213 }
214 }
215 typename QHash<Key, T>::iterator insert(const Key &key, const T &value) {
216 if (m_autoDelete) {
217 T &oldValue = QHash<Key, T>::operator[](key);
218 if (oldValue && oldValue != value) { // only delete if differs
219 delete oldValue;
220 }
221 }
223 }
224 int remove(const Key &key) {
225 if (m_autoDelete) {
227 const int result = QHash<Key, T>::remove(key);
228 for (T item : values) {
229 delete item;
230 }
231 return result;
232 } else {
234 }
235 }
236 // note: no need to override insertMulti(), unite(), take(), they do not replace items
237
238private:
239 bool m_autoDelete;
240};
241
242//! @short Autodeleting list
243template <typename T>
244class AutodeletedList : public QList<T>
245{
246public:
247 //! Creates autodeleting list as a copy of @a other.
248 //! Auto-deletion is not enabled as it would cause double deletion for items.
249 //! If you enable auto-deletion on here, make sure you disable it in the @a other list.
251 : QList<T>(other), m_autoDelete(false) {}
252
253 //! Creates empty autodeleting list.
254 //! Auto-deletion is enabled by default.
255 AutodeletedList(bool autoDelete = true) : QList<T>(), m_autoDelete(autoDelete) {}
256
258 if (m_autoDelete) qDeleteAll(*this);
259 }
260 void setAutoDelete(bool set) {
261 m_autoDelete = set;
262 }
263 bool autoDelete() const {
264 return m_autoDelete;
265 }
266 void removeAt(int i) {
267 T item = QList<T>::takeAt(i); if (m_autoDelete) delete item;
268 }
269 void removeFirst() {
270 T item = QList<T>::takeFirst(); if (m_autoDelete) delete item;
271 }
272 void removeLast() {
273 T item = QList<T>::takeLast(); if (m_autoDelete) delete item;
274 }
275 void replace(int i, const T& value) {
276 T item = QList<T>::takeAt(i); insert(i, value); if (m_autoDelete) delete item;
277 }
278 void insert(int i, const T& value) {
280 }
281 typename QList<T>::iterator erase(typename QList<T>::iterator pos) {
282 T item = *pos;
283 typename QList<T>::iterator res = QList<T>::erase(pos);
284 if (m_autoDelete)
285 delete item;
286 return res;
287 }
288 typename QList<T>::iterator erase(
289 typename QList<T>::iterator afirst,
290 typename QList<T>::iterator alast) {
291 if (!m_autoDelete)
292 return QList<T>::erase(afirst, alast);
293 while (afirst != alast) {
294 T item = *afirst;
295 afirst = QList<T>::erase(afirst);
296 delete item;
297 }
298 return alast;
299 }
300 void pop_back() {
301 removeLast();
302 }
303 void pop_front() {
304 removeFirst();
305 }
306 int removeAll(const T& value) {
307 if (!m_autoDelete)
309 typename QList<T>::iterator it(QList<T>::begin());
310 int removedCount = 0;
311 while (it != QList<T>::end()) {
312 if (*it == value) {
313 T item = *it;
314 it = QList<T>::erase(it);
315 delete item;
316 removedCount++;
317 } else
318 ++it;
319 }
320 return removedCount;
321 }
322 void clear() {
323 if (!m_autoDelete)
324 return QList<T>::clear();
325 while (!QList<T>::isEmpty()) {
326 T item = QList<T>::takeFirst();
327 delete item;
328 }
329 }
330
331private:
332 bool m_autoDelete;
333};
334
335//! @short Case insensitive hash container supporting QString or QByteArray keys.
336//! Keys are turned to lowercase before inserting.
337template <typename Key, typename T>
338class CaseInsensitiveHash : public QHash<Key, T>
339{
340public:
342 typename QHash<Key, T>::iterator find(const Key& key) const {
343 return QHash<Key, T>::find(key.toLower());
344 }
345 typename QHash<Key, T>::const_iterator constFind(const Key& key) const {
346 return QHash<Key, T>::constFind(key.toLower());
347 }
348 bool contains(const Key& key) const {
349 return QHash<Key, T>::contains(key.toLower());
350 }
351 int count(const Key& key) const {
352 return QHash<Key, T>::count(key.toLower());
353 }
354 typename QHash<Key, T>::iterator insert(const Key& key, const T& value) {
355 return QHash<Key, T>::insert(key.toLower(), value);
356 }
357 typename QHash<Key, T>::iterator insertMulti(const Key& key, const T& value) {
358 return QHash<Key, T>::insertMulti(key.toLower(), value);
359 }
360 const Key key(const T& value, const Key& defaultKey) const {
361 return QHash<Key, T>::key(value, defaultKey.toLower());
362 }
363 int remove(const Key& key) {
364 return QHash<Key, T>::remove(key.toLower());
365 }
366 const T take(const Key& key) {
367 return QHash<Key, T>::take(key.toLower());
368 }
369 const T value(const Key& key) const {
370 return QHash<Key, T>::value(key.toLower());
371 }
372 const T value(const Key& key, const T& defaultValue) const {
373 return QHash<Key, T>::value(key.toLower(), defaultValue);
374 }
375 QList<T> values(const Key& key) const {
376 return QHash<Key, T>::values(key.toLower());
377 }
378 T& operator[](const Key& key) {
379 return QHash<Key, T>::operator[](key.toLower());
380 }
381 const T operator[](const Key& key) const {
382 return QHash<Key, T>::operator[](key.toLower());
383 }
384};
385
386//! A set created from static (0-terminated) array of raw null-terminated strings.
387class KDB_EXPORT StaticSetOfStrings
388{
389public:
391 explicit StaticSetOfStrings(const char* const array[]);
393 void setStrings(const char* const array[]);
394 bool isEmpty() const;
395
396 //! @return true if @a string can be found within set, comparison is case sensitive
397 bool contains(const QByteArray& string) const;
398private:
399 class Private;
400 Private * const d;
401 Q_DISABLE_COPY(StaticSetOfStrings)
402};
403
404/*! @return debugging string for object @a object of type @a T */
405template <typename T>
406QString debugString(const T& object)
407{
408 QString result;
409 QDebug dbg(&result);
410 dbg << object;
411 return result;
412}
413
414//! Used by findExe().
415enum class FindExeOption {
416 //! No options
417 None = 0,
418 //! If set, the path returned may not have the executable bit set.
419 IgnoreExecBit = 1
420};
421Q_DECLARE_FLAGS(FindExeOptions, FindExeOption)
422
423/**
424 * Finds the executable in the system path.
425 *
426 * A valid executable must be a file and have its executable bit set.
427 *
428 * @param appname The name of the executable file for which to search.
429 * if this contains a path separator, it will be resolved
430 * according to the current working directory
431 * (shell-like behavior).
432 * @param path The path which will be searched. If this is
433 * null (default), the @c $PATH environment variable will
434 * be searched.
435 * @param options Options, see FindExeOption.
436 *
437 * @return The path of the executable. If it was not found, returns QString().
438 */
439QString findExe(const QString& appname,
440 const QString& path = QString(),
441 FindExeOptions options = FindExeOption::None);
442
443//! A single property
444//! @note This property is general-purpose and not related to Qt Properties.
445//! @see KDbUtils::PropertySet
446class KDB_EXPORT Property {
447public:
448 //! Constructs a null property
449 Property();
450
451 Property(const QVariant &aValue, const QString &aCaption);
452
453 Property(const Property &other);
454
455 ~Property();
456
457 bool operator==(const Property &other) const;
458
459 bool operator!=(const Property &other) const { return !operator==(other); }
460
461 bool isNull() const;
462
463 QVariant value() const;
464
465 void setValue(const QVariant &value);
466
467 QString caption() const;
468
469 void setCaption(const QString &caption);
470
471private:
472 class Private;
473 Private * const d;
474};
475
476//! A set of properties.
477//! @note These properties are general-purpose and not related to Qt Properties.
478//! @see KDbUtils::Property
479class KDB_EXPORT PropertySet
480{
481public:
482 PropertySet();
483
484 PropertySet(const PropertySet &other);
485
486 ~PropertySet();
487
488 //! Assigns @a other to this property set and returns a reference to this property set.
489 PropertySet& operator=(const PropertySet &other);
490
491 //! @return true if this property set has exactly the same properties as @a other
492 //! @since 3.1
493 bool operator==(const PropertySet &other) const;
494
495 //! @return true if this property differs in at least one property from @a other
496 //! @since 3.1
497 bool operator!=(const PropertySet &other) const { return !operator==(other); }
498
499 //! Inserts property with a given @a name, @a value and @a caption.
500 //! If @a caption is empty, caption from existing property is reused.
501 //! @a name must be a valid identifier (see KDb::isIdentifier()).
502 void insert(const QByteArray &name, const QVariant &value, const QString &caption = QString());
503
504 //! Sets caption for property @a name to @a caption.
505 //! If such property does not exist, does nothing.
506 //! @since 3.1
507 void setCaption(const QByteArray &name, const QString &caption);
508
509 //! Sets value for property @a name to @a value.
510 //! If such property does not exist, does nothing.
511 //! @since 3.1
512 void setValue(const QByteArray &name, const QVariant &value);
513
514 //! Removes property with a given @a name.
515 void remove(const QByteArray &name);
516
517 //! @return property with a given @a name.
518 //! If not found, a null Property is returned (Property::isNull).
519 Property property(const QByteArray &name) const;
520
521 //! @return a list of property names.
522 QList<QByteArray> names() const;
523
524private:
525 class Private;
526 Private * const d;
527};
528
529} // KDbUtils
530
531#endif //KDB_TOOLS_UTILS_H
Autodeleting hash.
Definition KDbUtils.h:179
AutodeletedHash(bool autoDelete=true)
Creates empty autodeleting hash.
Definition KDbUtils.h:188
AutodeletedHash(const AutodeletedHash &other)
Creates autodeleting hash as a copy of other.
Definition KDbUtils.h:184
Autodeleting list.
Definition KDbUtils.h:245
AutodeletedList(bool autoDelete=true)
Creates empty autodeleting list.
Definition KDbUtils.h:255
AutodeletedList(const AutodeletedList &other)
Creates autodeleting list as a copy of other.
Definition KDbUtils.h:250
Case insensitive hash container supporting QString or QByteArray keys.
Definition KDbUtils.h:339
A set of properties.
Definition KDbUtils.h:480
bool operator!=(const PropertySet &other) const
Definition KDbUtils.h:497
A single property.
Definition KDbUtils.h:446
A set created from static (0-terminated) array of raw null-terminated strings.
Definition KDbUtils.h:388
Type type(const QSqlDatabase &db)
void clear()
const_iterator constFind(const Key &key) const const
bool contains(const Key &key) const const
qsizetype count() const const
iterator erase(const_iterator pos)
iterator find(const Key &key)
iterator insert(const Key &key, const T &value)
Key key(const T &value) const const
T & operator[](const Key &key)
bool remove(const Key &key)
T take(const Key &key)
T value(const Key &key) const const
QList< T > values() const const
void clear()
iterator erase(const_iterator begin, const_iterator end)
iterator insert(const_iterator before, parameter_type value)
qsizetype removeAll(const AT &t)
T takeAt(qsizetype i)
value_type takeFirst()
value_type takeLast()
T value(qsizetype i) const const
bool inherits(const char *className) const const
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:59 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.