aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/common
diff options
context:
space:
mode:
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/common')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp1
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/global.h2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.cpp37
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.h34
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/objectpool.h7
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/sortedhash.h4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/utils.cpp102
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/utils.h10
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp45
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/valuelocker.h44
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.cpp84
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.h31
12 files changed, 378 insertions, 23 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp
index 091121c..5f40521 100644
--- a/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/common/bistrhash.cpp
@@ -1,4 +1,5 @@
#include "bistrhash.h"
+#include <QStringList>
BiStrHash::BiStrHash(std::initializer_list<std::pair<QString, QString> > list)
{
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/global.h b/SQLiteStudio3/coreSQLiteStudio/common/global.h
index b1f4b01..cfd8dc0 100644
--- a/SQLiteStudio3/coreSQLiteStudio/common/global.h
+++ b/SQLiteStudio3/coreSQLiteStudio/common/global.h
@@ -12,7 +12,7 @@
#define DEEP_COPY_COLLECTION(T, F) \
T* _new##T; \
- foreach (T* _element, other.F) \
+ for (T* _element : other.F) \
{ \
_new##T = new T(*_element); \
_new##T->setParent(this); \
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.cpp b/SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.cpp
new file mode 100644
index 0000000..2c39f34
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.cpp
@@ -0,0 +1,37 @@
+#include "lazytrigger.h"
+#include <QTimer>
+
+LazyTrigger::LazyTrigger(int delay, QObject* parent, const char* slot) :
+ QObject(parent)
+{
+ timer = new QTimer(this);
+ timer->setSingleShot(true);
+ timer->setInterval(delay);
+ connect(timer, &QTimer::timeout, this, &LazyTrigger::triggered);
+ if (slot)
+ connect(timer, SIGNAL(timeout()), parent, slot);
+}
+
+LazyTrigger::LazyTrigger(int delay, LazyTrigger::Condition condition, QObject* parent, const char* slot) :
+ LazyTrigger(delay, parent, slot)
+{
+ this->condition = condition;
+}
+
+void LazyTrigger::setDelay(int delay)
+{
+ timer->setInterval(delay);
+}
+
+void LazyTrigger::schedule()
+{
+ timer->stop();
+
+ if (!condition || condition())
+ timer->start();
+}
+
+void LazyTrigger::cancel()
+{
+ timer->stop();
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.h b/SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.h
new file mode 100644
index 0000000..9c34395
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/common/lazytrigger.h
@@ -0,0 +1,34 @@
+#ifndef LAZYTRIGGER_H
+#define LAZYTRIGGER_H
+
+#include "coreSQLiteStudio_global.h"
+#include <QObject>
+#include <functional>
+
+class QTimer;
+
+class API_EXPORT LazyTrigger : public QObject
+{
+ Q_OBJECT
+
+ public:
+ typedef std::function<bool()> Condition;
+
+ LazyTrigger(int delay, QObject* parent = nullptr, const char* slot = nullptr);
+ LazyTrigger(int delay, Condition condition, QObject* parent = nullptr, const char* slot = nullptr);
+
+ void setDelay(int delay);
+
+ private:
+ QTimer* timer = nullptr;
+ Condition condition = nullptr;
+
+ public slots:
+ void schedule();
+ void cancel();
+
+ signals:
+ void triggered();
+};
+
+#endif // LAZYTRIGGER_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/objectpool.h b/SQLiteStudio3/coreSQLiteStudio/common/objectpool.h
index b9f6b9f..7330efc 100644
--- a/SQLiteStudio3/coreSQLiteStudio/common/objectpool.h
+++ b/SQLiteStudio3/coreSQLiteStudio/common/objectpool.h
@@ -24,7 +24,7 @@ class ObjectPool
};
template <class T>
-ObjectPool::ObjectPool(quint32 min, quint32 max)
+ObjectPool<T>::ObjectPool(quint32 min, quint32 max)
: min(min), max(max)
{
Q_ASSERT(min > 0);
@@ -36,7 +36,8 @@ ObjectPool::ObjectPool(quint32 min, quint32 max)
}
}
-T* ObjectPool::reserve()
+template <class T>
+T* ObjectPool<T>::reserve()
{
mutex.lock();
@@ -73,7 +74,7 @@ T* ObjectPool::reserve()
}
template <class T>
-void ObjectPool::release(T* obj)
+void ObjectPool<T>::release(T* obj)
{
mutex.lock();
pool[obj] = false;
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/sortedhash.h b/SQLiteStudio3/coreSQLiteStudio/common/sortedhash.h
index 9ca6ade..c0d44b6 100644
--- a/SQLiteStudio3/coreSQLiteStudio/common/sortedhash.h
+++ b/SQLiteStudio3/coreSQLiteStudio/common/sortedhash.h
@@ -74,7 +74,7 @@ class SortedHash : public QHash<Key, T>
QList<Key> keys(const T& value) const
{
QList<Key> results;
- foreach (const Key& k, sortedKeys)
+ for (const Key& k : sortedKeys)
if (value(k) == value)
results << k;
@@ -98,7 +98,7 @@ class SortedHash : public QHash<Key, T>
QList<T> values() const
{
QList<T> results;
- foreach (const Key& k, sortedKeys)
+ for (const Key& k : sortedKeys)
results << value(k);
return results;
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp
index e3d2e47..fd40355 100644
--- a/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.cpp
@@ -311,7 +311,7 @@ QStringList tokenizeArgs(const QString& str)
QStringList prefixEach(const QString& prefix, const QStringList& list)
{
QStringList result;
- foreach (const QString& item, list)
+ for (const QString& item : list)
result << (prefix + item);
return result;
@@ -385,7 +385,7 @@ QString longest(const QStringList& strList)
{
int max = 0;
QString result;
- foreach (const QString str, strList)
+ for (const QString str : strList)
{
if (str.size() > max)
{
@@ -400,7 +400,7 @@ QString shortest(const QStringList& strList)
{
int max = INT_MAX;
QString result;
- foreach (const QString str, strList)
+ for (const QString str : strList)
{
if (str.size() < max)
{
@@ -421,7 +421,7 @@ QString longestCommonPart(const QStringList& strList)
for (int i = 0; i < first.length(); i++)
{
common += first[i];
- foreach (const QString& str, strList)
+ for (const QString& str : strList)
{
if (!str.startsWith(common))
return common.left(i);
@@ -434,7 +434,7 @@ QStringList applyMargin(const QString& str, int margin)
{
QStringList lines;
QString line;
- foreach (QString word, str.split(" "))
+ for (QString word : str.split(" "))
{
if (((line + word).length() + 1) > margin)
{
@@ -694,9 +694,11 @@ QString getOsString()
case QSysInfo::WV_WINDOWS8_1:
os += " 8.1";
break;
+#if QT_VERSION >= 0x050500
case QSysInfo::WV_WINDOWS10:
os += " 10";
break;
+#endif
case QSysInfo::WV_32s:
case QSysInfo::WV_95:
case QSysInfo::WV_98:
@@ -710,7 +712,9 @@ QString getOsString()
case QSysInfo::WV_CE_5:
case QSysInfo::WV_CE_6:
case QSysInfo::WV_CE_based:
+#if QT_VERSION >= 0x050500
case QSysInfo::WV_None:
+#endif
break;
}
#elif defined(Q_OS_LINUX)
@@ -752,6 +756,9 @@ QString getOsString()
case QSysInfo::MV_10_11:
os += " 10.11 El Capitan";
break;
+ case QSysInfo::MV_10_12:
+ os += " 10.12 Sierra";
+ break;
case QSysInfo::MV_9:
case QSysInfo::MV_10_0:
case QSysInfo::MV_10_1:
@@ -816,6 +823,42 @@ bool isHex(const QString& str)
return ok;
}
+bool isHex(const QChar& c)
+{
+ return isHex(c.toLatin1());
+}
+
+bool isHex(const char c)
+{
+ switch (c)
+ {
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return true;
+ }
+ return false;
+}
+
QString formatVersion(int version)
{
int majorVer = version / 10000;
@@ -916,9 +959,18 @@ QStringList concat(const QList<QStringList>& list)
return result;
}
+
QString doubleToString(const QVariant& val)
{
- return val.toString();
+ QString str = val.toString();
+ if (str.contains("e"))
+ str = QString::number(val.toDouble(), 'f', 14).remove(QRegExp("0*$"));
+ else if (!str.contains('.'))
+ str += ".0";
+ else if (str.mid(str.indexOf('.') + 1).length() > 14)
+ str = QString::number(val.toDouble(), 'f', 14).remove(QRegExp("0*$"));
+
+ return str;
}
void sortWithReferenceList(QList<QString>& listToSort, const QList<QString>& referenceList, Qt::CaseSensitivity cs)
@@ -941,3 +993,41 @@ void sortWithReferenceList(QList<QString>& listToSort, const QList<QString>& ref
return (idx1 > idx2);
});
}
+
+QByteArray serializeToBytes(const QVariant& value)
+{
+ QByteArray bytes;
+ QDataStream stream(&bytes, QIODevice::WriteOnly);
+ stream << value;
+ return bytes;
+}
+
+QVariant deserializeFromBytes(const QByteArray& bytes)
+{
+ if (bytes.isNull())
+ return QVariant();
+
+ QVariant deserializedValue;
+ QDataStream stream(bytes);
+ stream >> deserializedValue;
+ return deserializedValue;
+}
+
+QString readFileContents(const QString& path, QString* err)
+{
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ if (err)
+ *err = QObject::tr("Could not open file '%1' for reading: %2").arg(path).arg(file.errorString());
+
+ return QString();
+ }
+
+ QTextStream stream(&file);
+ stream.setCodec("UTF-8");
+ QString contents = stream.readAll();
+ file.close();
+
+ return contents;
+}
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils.h b/SQLiteStudio3/coreSQLiteStudio/common/utils.h
index c56a4db..24ea150 100644
--- a/SQLiteStudio3/coreSQLiteStudio/common/utils.h
+++ b/SQLiteStudio3/coreSQLiteStudio/common/utils.h
@@ -9,6 +9,8 @@
#include <QStringList>
#include <QFileInfo>
#include <functional>
+#include <QVariant>
+#include <QDataStream>
class QTextCodec;
@@ -236,6 +238,8 @@ API_EXPORT int sum(const QList<int>& integers);
API_EXPORT QString getOsString();
API_EXPORT bool validateEmail(const QString& email);
API_EXPORT bool isHex(const QString& str);
+API_EXPORT bool isHex(const QChar& c);
+API_EXPORT bool isHex(const char c);
API_EXPORT QString formatVersion(int version);
API_EXPORT bool copyRecursively(const QString& src, const QString& dst);
API_EXPORT bool renameBetweenPartitions(const QString& src, const QString& dst);
@@ -289,6 +293,12 @@ void removeDuplicates(QList<T>& list)
}
}
+API_EXPORT QByteArray serializeToBytes(const QVariant& value);
+
+API_EXPORT QVariant deserializeFromBytes(const QByteArray& bytes);
+
+API_EXPORT QString readFileContents(const QString& path, QString* err);
+
Q_DECLARE_METATYPE(QList<int>)
#endif // UTILS_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp
index ad37ff0..b5642ec 100644
--- a/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/common/utils_sql.cpp
@@ -12,7 +12,8 @@
#include <QMetaType>
QString invalidIdCharacters = "[]()\"'@*.,+-=/%&|:; \t\n<>";
-QHash<NameWrapper,QPair<QChar,QChar> > wrapperChars;
+QHash<NameWrapper,QPair<QChar,QChar>> wrapperChars;
+QHash<NameWrapper,QPair<QChar,bool>> wrapperEscapedEnding;
QList<NameWrapper> sqlite3Wrappers;
QList<NameWrapper> sqlite2Wrappers;
@@ -23,6 +24,11 @@ void initUtilsSql()
wrapperChars[NameWrapper::BACK_QUOTE] = QPair<QChar,QChar>('`', '`');
wrapperChars[NameWrapper::DOUBLE_QUOTE] = QPair<QChar,QChar>('"', '"');
+ wrapperEscapedEnding[NameWrapper::BRACKET] = QPair<QChar,bool>(']', false);
+ wrapperEscapedEnding[NameWrapper::QUOTE] = QPair<QChar,bool>('\'', true);
+ wrapperEscapedEnding[NameWrapper::BACK_QUOTE] = QPair<QChar,bool>('`', true);
+ wrapperEscapedEnding[NameWrapper::DOUBLE_QUOTE] = QPair<QChar,bool>('"', true);
+
sqlite3Wrappers << NameWrapper::DOUBLE_QUOTE
<< NameWrapper::BRACKET
<< NameWrapper::QUOTE
@@ -129,7 +135,7 @@ QPair<QChar,QChar> getQuoteCharacter(QString& obj, Dialect dialect, NameWrapper
}
QPair<QChar,QChar> wrapChars;
- foreach (NameWrapper wrapper, wrappers)
+ for (NameWrapper wrapper : wrappers)
{
wrapChars = wrapperChars[wrapper];
if (obj.indexOf(wrapChars.first) > -1)
@@ -277,6 +283,23 @@ bool isObjWrapped(const QString& str, Dialect dialect)
return getObjWrapper(str, dialect) != NameWrapper::null;
}
+bool doesNotContainEndingWrapperChar(const QString& str, NameWrapper wrapper)
+{
+ QString innerPart = str.mid(1, str.length() - 2);
+ const QChar& endingChar = wrapperEscapedEnding[wrapper].first;
+ bool escapingAllowed = wrapperEscapedEnding[wrapper].second;
+ int idx = -1;
+ int lastIdx = innerPart.length() - 1;
+ while ((idx = innerPart.indexOf(endingChar, idx + 1)) > -1)
+ {
+ if (idx == lastIdx || !escapingAllowed || innerPart[idx + 1] != endingChar)
+ return false;
+
+ idx++; // we had occurrence, but it was escaped, so we need to skip the second (escape) char
+ }
+ return true;
+}
+
NameWrapper getObjWrapper(const QString& str, Dialect dialect)
{
if (str.isEmpty())
@@ -289,10 +312,10 @@ NameWrapper getObjWrapper(const QString& str, Dialect dialect)
else
wrappers = sqlite3Wrappers;
- foreach (NameWrapper wrapper, wrappers)
+ for (NameWrapper wrapper : wrappers)
{
QPair<QChar,QChar> chars = wrapperChars[wrapper];
- if (str[0] == chars.first && str[str.length()-1] == chars.second)
+ if (str[0] == chars.first && str[str.length()-1] == chars.second && doesNotContainEndingWrapperChar(str, wrapper))
return wrapper;
}
return NameWrapper::null;
@@ -306,7 +329,7 @@ bool isWrapperChar(const QChar& c, Dialect dialect)
else
wrappers = sqlite3Wrappers;
- foreach (NameWrapper wrapper, wrappers)
+ for (NameWrapper wrapper : wrappers)
{
QPair<QChar,QChar> chars = wrapperChars[wrapper];
if (c == chars.first || c == chars.second)
@@ -389,7 +412,7 @@ QList<TokenList> splitQueries(const TokenList& tokenizedQuery, bool* complete)
int createTriggerMeter = 0;
bool insideTrigger = false;
bool completeQuery = false;
- foreach (const TokenPtr& token, tokenizedQuery)
+ for (const TokenPtr& token : tokenizedQuery)
{
value = token->value.toUpper();
if (!token->isWhitespace())
@@ -556,7 +579,7 @@ QStringList splitQueries(const QString& sql, Dialect dialect, bool keepEmptyQuer
QString query;
QStringList queries;
- foreach (const TokenList& queryTokens, tokenizedQueries)
+ for (const TokenList& queryTokens : tokenizedQueries)
{
query = queryTokens.detokenize();
if (keepEmptyQueries || (!query.trimmed().isEmpty() && query.trimmed() != ";"))
@@ -627,10 +650,10 @@ QList<QueryWithParamNames> getQueriesWithParamNames(const QString& query, Dialec
QString queryStr;
QStringList paramNames;
- foreach (const TokenList& tokens, queries)
+ for (const TokenList& tokens : queries)
{
paramNames.clear();
- foreach (const TokenPtr& token, tokens.filter(Token::BIND_PARAM))
+ for (const TokenPtr& token : tokens.filter(Token::BIND_PARAM))
paramNames << token->value;
queryStr = tokens.detokenize().trimmed();
@@ -648,7 +671,7 @@ QList<QueryWithParamCount> getQueriesWithParamCount(const QString& query, Dialec
QList<TokenList> queries = splitQueries(allTokens);
QString queryStr;
- foreach (const TokenList& tokens, queries)
+ for (const TokenList& tokens : queries)
{
queryStr = tokens.detokenize().trimmed();
if (!queryStr.isEmpty())
@@ -663,7 +686,7 @@ QueryWithParamNames getQueryWithParamNames(const QString& query, Dialect dialect
TokenList allTokens = Lexer::tokenize(query, dialect);
QStringList paramNames;
- foreach (const TokenPtr& token, allTokens.filter(Token::BIND_PARAM))
+ for (const TokenPtr& token : allTokens.filter(Token::BIND_PARAM))
paramNames << token->value;
return QueryWithParamNames(query, paramNames);
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/valuelocker.h b/SQLiteStudio3/coreSQLiteStudio/common/valuelocker.h
new file mode 100644
index 0000000..a757506
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/common/valuelocker.h
@@ -0,0 +1,44 @@
+#ifndef VALUELOCKER_H
+#define VALUELOCKER_H
+
+/**
+ * ValueLocker is similar to QMutexLocker, but it's not intended for multithreaded locks.
+ * It's rather for event loop locking.
+ * It can be created as local scope variable with a pointer to member variable.
+ * It will set "unlockedValue" to that variable once the locker is destroyed (goes out of scope).
+ * Usually the variable used will be of boolean type, but it can be virtually any other type.
+ * You can also provide initial value for locked state. Otherwise you will need to set the locked
+ * by yourself before the lock is created.
+ */
+template <class T>
+class ValueLocker {
+ public:
+ ValueLocker(T* valueToLock, const T& lockedValue, const T& unlockedValue);
+ ValueLocker(T* valueToLock, const T& unlockedValue);
+ ~ValueLocker();
+
+ private:
+ T* valueToLock;
+ T unlockedValue;
+};
+
+template<class T>
+ValueLocker<T>::ValueLocker(T *valueToLock, const T &lockedValue, const T &unlockedValue) :
+ ValueLocker(valueToLock, unlockedValue)
+{
+ *valueToLock = lockedValue;
+}
+
+template<class T>
+ValueLocker<T>::ValueLocker(T *valueToLock, const T &unlockedValue) :
+ valueToLock(valueToLock), unlockedValue(unlockedValue)
+{
+}
+
+template<class T>
+ValueLocker<T>::~ValueLocker()
+{
+ *valueToLock = unlockedValue;
+}
+
+#endif // VALUELOCKER_H
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.cpp b/SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.cpp
new file mode 100644
index 0000000..7c86088
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.cpp
@@ -0,0 +1,84 @@
+/*#include "xmldeserializer.h"
+#include "unused.h"
+#include <QDebug>
+
+XmlDeserializer::XmlDeserializer()
+{
+}
+
+QHash<QString, QVariant> XmlDeserializer::deserialize(QIODevice *input)
+{
+ QXmlStreamReader reader(input);
+ return deserialize(reader);
+}
+
+QHash<QString, QVariant> XmlDeserializer::deserialize(const QString &input)
+{
+ QXmlStreamReader reader(input);
+ return deserialize(reader);
+}
+
+QHash<QString, QVariant> XmlDeserializer::deserialize(QXmlStreamReader &reader)
+{
+ ctxStack.clear();
+ output.clear();
+ ctx = &output;
+
+ QXmlStreamReader::TokenType tokenType;
+ while ((tokenType = reader.readNext()) != QXmlStreamReader::EndDocument)
+ handleTokenType(reader, tokenType);
+
+ return output;
+}
+
+void XmlDeserializer::handleTokenType(QXmlStreamReader& reader, QXmlStreamReader::TokenType tokenType)
+{
+ switch (tokenType)
+ {
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::EndDocument:
+ case QXmlStreamReader::DTD:
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::ProcessingInstruction:
+ case QXmlStreamReader::StartDocument:
+ case QXmlStreamReader::EntityReference:
+ break;
+ case QXmlStreamReader::Invalid:
+ qDebug() << "Invalid token while parsing XML:" << reader.errorString();
+ break;
+ case QXmlStreamReader::StartElement:
+ handleStartElement(reader);
+ break;
+ case QXmlStreamReader::Characters:
+ handleText(reader);
+ break;
+ case QXmlStreamReader::EndElement:
+ handleEndElement(reader);
+ break;
+ }
+}
+
+void XmlDeserializer::handleStartElement(QXmlStreamReader &reader)
+{
+ QString key = reader.name().toString();
+ QHash<QString, QVariant> newCtx;
+ ctx->insertMulti(key, newCtx);
+
+ for (const QXmlStreamAttribute& attr : reader.attributes())
+ ctx->insertMulti(attr.name().toString(), attr.value().toString());
+
+ ctxStack.push(ctx);
+ ctx = &((*ctx)[key]);
+}
+
+void XmlDeserializer::handleText(QXmlStreamReader &reader)
+{
+ ctx->insertMulti(QString(), reader.text().toString());
+}
+
+void XmlDeserializer::handleEndElement(QXmlStreamReader &reader)
+{
+ UNUSED(reader);
+ ctx = ctxStack.pop();
+}
+*/
diff --git a/SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.h b/SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.h
new file mode 100644
index 0000000..52761cf
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/common/xmldeserializer.h
@@ -0,0 +1,31 @@
+/*#ifndef XMLDESERIALIZER_H
+#define XMLDESERIALIZER_H
+
+#include "coreSQLiteStudio_global.h"
+#include <QTextStream>
+#include <QXmlStreamReader>
+#include <QStack>
+#include <QHash>
+
+class API_EXPORT XmlDeserializer
+{
+ public:
+ XmlDeserializer();
+
+ QHash<QString,QVariant> deserialize(QIODevice* input);
+ QHash<QString,QVariant> deserialize(const QString& input);
+
+ private:
+ QHash<QString,QVariant> deserialize(QXmlStreamReader& reader);
+ void handleTokenType(QXmlStreamReader& reader, QXmlStreamReader::TokenType tokenType);
+ void handleStartElement(QXmlStreamReader& reader);
+ void handleText(QXmlStreamReader& reader);
+ void handleEndElement(QXmlStreamReader& reader);
+
+ QHash<QString, QVariant> output;
+ QHash<QString, QVariant>* ctx;
+ QStack<QHash<QString, QVariant>*> ctxStack;
+};
+
+#endif // XMLDESERIALIZER_H
+*/