From 2cfa0cc5141fbbbc7538cd5484c548bf793a6916 Mon Sep 17 00:00:00 2001 From: Gangphon Date: Fri, 21 Jul 2023 17:40:49 +0800 Subject: [PATCH] ledok --- LedOK/gutil/cu.cpp | 2 + LedOK/gutil/cu.h | 221 +++++++++++++++++++++++++++++++ LedOK/gutil/qgui.h | 38 +++--- LedOK/gutil/qjson.cpp | 183 +++++++++++++++++++++++++ LedOK/gutil/qjson.h | 177 +++++++++++++++++++++++++ LedOK/gutil/qnetwork.cpp | 6 +- LedOK/gutil/qnetwork.h | 46 +++++-- LedOK/program/sendprogthread.cpp | 2 +- LedOK/tools.cpp | 15 +-- 9 files changed, 644 insertions(+), 46 deletions(-) create mode 100644 LedOK/gutil/cu.cpp create mode 100644 LedOK/gutil/cu.h create mode 100644 LedOK/gutil/qjson.cpp create mode 100644 LedOK/gutil/qjson.h diff --git a/LedOK/gutil/cu.cpp b/LedOK/gutil/cu.cpp new file mode 100644 index 0000000..989710e --- /dev/null +++ b/LedOK/gutil/cu.cpp @@ -0,0 +1,2 @@ +//#include "cu.h" + diff --git a/LedOK/gutil/cu.h b/LedOK/gutil/cu.h new file mode 100644 index 0000000..0af412d --- /dev/null +++ b/LedOK/gutil/cu.h @@ -0,0 +1,221 @@ +#ifndef CU_H +#define CU_H + +#include +#include +#include + +inline long long steady_milli() { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); +} +inline long long system_milli() { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); +} +inline long long steady_micro() { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); +} +inline long long system_micro() { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); +} + + +template +struct SharedData { + T data; + uint64_t cnt{1}; +}; +template +class SharedPtr { +public: + SharedPtr(SharedData *ptr = 0) : ptr{ptr} {} + SharedPtr(const SharedPtr &other) : ptr{other.ptr} { + if(ptr) ptr->cnt++; + } + ~SharedPtr() { + if(ptr==0) return; + if(ptr->cnt > 1) ptr->cnt--; + else delete ptr; + } + + bool isNull() {return ptr==0;} + SharedPtr &operator=(const SharedPtr &other) { + this->~SharedPtr(); + new (this) SharedPtr(other); + return *this; + } + + T &operator*() { + if(ptr==0) ptr = new SharedData; + return ptr->data; + } + T *operator->() { + if(ptr==0) ptr = new SharedData; + return &ptr->data; + } + const T &operator*() const { + return ptr->data; + } + const T *operator->() const { + return &ptr->data; + } + SharedData *ptr{0}; +}; + + +template +class Vector : public SharedPtr> { +public: + using SharedPtr>::SharedPtr; + + using iterator = std::_Vector_iterator>>; + using const_iterator = std::_Vector_const_iterator>>; + + Vector(std::initializer_list _Ilist) { + this->ptr = new SharedData>{_Ilist, 1}; + } + + bool empty() const noexcept { + return this->ptr ? this->ptr->data.empty() : true; + } + uint64_t size() const noexcept { + return this->ptr ? this->ptr->data.size() : 0; + } + Vector &append(const V &val) { + (**this).push_back(val); + return *this; + } + V &operator[](const uint64_t pos) noexcept { + return (**this)[pos]; + } + const V &operator[](const uint64_t pos) const noexcept { + return this->ptr ? this->ptr->data[pos] : V(); + } + const const_iterator begin() const noexcept { + return this->ptr ? this->ptr->data.begin() : const_iterator(); + } + const const_iterator end() const noexcept { + return this->ptr ? this->ptr->data.end() : const_iterator(); + } +}; + + +struct NodeBase { + NodeBase *next{this}; + NodeBase *prev{this}; +}; +template +struct _Node : NodeBase { + V value; + ~_Node() { + if(next) delete (_Node*) next; + } +}; + +template +class LinkedMapIterator { +public: + LinkedMapIterator(_Node *node) : node(node) {} + bool operator==(const LinkedMapIterator& that) const { + return node == that.node; + } + bool operator!=(const LinkedMapIterator& that) const { + return node != that.node; + } + LinkedMapIterator& operator++() { + node = (_Node*) node->next; + return *this; + } + LinkedMapIterator& operator--() { + node = (_Node*) node->prev; + return *this; + } + V &operator*() const { + return node->value; + } + V *operator->() const { + return &node->value; + } + _Node *node{0}; +}; + +template +struct LinkedMapPri : NodeBase { + std::unordered_map>*> map; + uint64_t cnt{1}; + ~LinkedMapPri() { + if(prev) prev->next = 0; + if(next) delete (_Node>*) next; + } +}; +template +class LinkedMap { +public: + using Node = _Node>; + + using iterator = LinkedMapIterator>; + using const_iterator = LinkedMapIterator>; + + LinkedMap() {} + LinkedMap(std::initializer_list> pairs) : _pri{new LinkedMapPri} { + for(auto pair : pairs) insert(pair.first, pair.second); + } + LinkedMap(std::unordered_map &&map) : _pri{new LinkedMapPri{0, 0, map}} { + _pri->next = _pri->prev = _pri; + } + LinkedMap(const LinkedMap &other) : _pri{other._pri} { + if(_pri) _pri->cnt++; + } + ~LinkedMap() { + if(_pri==0) return; + if(_pri->cnt > 1) _pri->cnt--; + else delete _pri; + } + + LinkedMap &operator=(const LinkedMap &other) { + this->~LinkedMap(); + new (this) LinkedMap(other); + return *this; + } + const V operator[](const K &k) const { + if(_pri==0) return V(); + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return V(); + return it->second->value.second; + } + LinkedMap &insert(const K &k, const V &v) { + if(_pri==0) _pri = new LinkedMapPri; + auto pair = _pri->map.emplace(k, nullptr); + if(pair.second) { + auto node = new Node{_pri, _pri->prev, {k, v}}; + _pri->prev->next = node; + _pri->prev = node; + pair.first->second = node; + } else pair.first->second->value.second = v; + return *this; + } + void erase(const K& k) { + if(_pri==0) return; + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return; + auto node = it->second; + _pri->map.erase(it); + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + delete node; + } + inline bool empty() const { + return _pri==0 || _pri->map.empty(); + } + + const_iterator begin() const { + return const_iterator((Node*) (_pri ? _pri->next : 0)); + } + const_iterator end() const { + return const_iterator((Node*) _pri); + } + LinkedMapPri *_pri{0}; +}; + +#endif // CU_H diff --git a/LedOK/gutil/qgui.h b/LedOK/gutil/qgui.h index 4863247..d7f7978 100644 --- a/LedOK/gutil/qgui.h +++ b/LedOK/gutil/qgui.h @@ -62,17 +62,13 @@ public: inline VBox(QBoxLayout *parent) : QBoxLayout(TopToBottom) { parent->addLayout(this); }; - inline VBox(QStackedLayout *parent) : QBoxLayout(TopToBottom) { + inline VBox(QStackedLayout *stack) : QBoxLayout(TopToBottom, new QWidget) { + stack->addWidget(parentWidget()); setContentsMargins(0,0,0,0); - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); }; - inline VBox(QSplitter *parent) : QBoxLayout(TopToBottom) { + inline VBox(QSplitter *splitter) : QBoxLayout(TopToBottom, new QWidget) { + splitter->addWidget(parentWidget()); setContentsMargins(0,0,0,0); - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); }; inline QLabel *addLabel(const QString &text) { auto lb = new QLabel(text); @@ -86,17 +82,13 @@ public: inline HBox(QBoxLayout *parent) : QBoxLayout(LeftToRight) { parent->addLayout(this); }; - inline HBox(QStackedLayout *parent) : QBoxLayout(LeftToRight) { + inline HBox(QStackedLayout *stack) : QBoxLayout(LeftToRight, new QWidget) { + stack->addWidget(parentWidget()); setContentsMargins(0,0,0,0); - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); }; - inline HBox(QSplitter *parent) : QBoxLayout(LeftToRight) { + inline HBox(QSplitter *splitter) : QBoxLayout(LeftToRight, new QWidget) { + splitter->addWidget(parentWidget()); setContentsMargins(0,0,0,0); - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); }; inline QLabel *addLabel(const QString &text) { auto lb = new QLabel(text); @@ -110,11 +102,17 @@ public: inline Grid(QBoxLayout *parent) { parent->addLayout(this); }; - inline Grid(QStackedLayout *parent) { - auto wgt = new QWidget; - wgt->setLayout(this); - parent->addWidget(wgt); + inline Grid(QStackedLayout *stack) : QGridLayout(new QWidget) { + stack->addWidget(parentWidget()); }; + inline Grid(QSplitter *splitter) : QGridLayout(new QWidget) { + splitter->addWidget(parentWidget()); + }; + inline QLabel *addLabel(const QString &text) { + auto lb = new QLabel(text); + addWidget(lb); + return lb; + } }; class ListWgt : public QListWidget { diff --git a/LedOK/gutil/qjson.cpp b/LedOK/gutil/qjson.cpp new file mode 100644 index 0000000..a95075c --- /dev/null +++ b/LedOK/gutil/qjson.cpp @@ -0,0 +1,183 @@ +#include "qjson.h" + +inline QChar readOne(QTextStream &in) { + QChar ch; + in >> ch; + return ch; +} +JValue JParser::readValue() { + if(ch=='{') { + JObj obj; + while(true) { + do skipSpace(); //ch有三种可能 + while(ch==','); + if(ch=='}') return obj; + QString key; + if(ch == '"') key = readStr(); + else if(ch!='n' || in.read(3)!="ull") throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting double-quote to start field name or null"; + skipSpace(); + if(ch != ':') throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting a colon to separate field name and value"; + skipSpace(); + obj.insert(key, readValue()); + skipSpace(); //ch有两种可能 + if(ch=='}') return obj; + if(ch!=',') throw QString("Unexpected char ")+ch+"' (code "+ch+"): was expecting } to end Object or comma to separate Object entries"; + } + } + if(ch=='[') { + JArray list; + while(true) { + do skipSpace(); //ch有三种可能 + while(ch==','); + if(ch==']') return list; + list->push_back(readValue()); + skipSpace(); //ch有两种可能 + if(ch==']') return list; + if(ch!=',') throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting ] to end Array or comma to separate Array entries"; + } + } + if(ch=='"') return readStr(); + if((ch>='0' && ch<='9') || ch=='-') { + QString buf; + buf += ch; + bool isInt = true; + while(0 != (ch = readOne(in))) { + if((ch>'*' && ch<':' && ch!=',' && ch!='/') || ch=='e' || ch=='E') { + buf.append(ch); + if(isInt && ch=='.') isInt = false; + } else { + bk = ch; + break; + } + } + bool ok; + if(isInt) { + auto num = buf.toLongLong(&ok); + if(! ok) throw "Illegal number: "+buf; + return num; + } else { + auto num = buf.toDouble(&ok); + if(! ok) throw "Illegal number: "+buf; + return num; + } + } + if(ch=='n') { + if(in.read(3)=="ull") return JValue(); + else throw "Unexpected char n: expected null"; + } + if(ch=='t') { + if(in.read(3)=="rue") return true; + else throw "Unexpected char t: expected true"; + } + if(ch=='f') { + if(in.read(4)=="alse") return false; + else throw "Unexpected char f: expected false"; + } + throw QString("Unexpected char ")+ch+" (code "+ch+"): expected {}, [], \"string\", number, null, true or false"; +} +QString JParser::readStr() { + QString buf; + while((ch = readOne(in)) != '"') { + if(ch==0) throw "Unexpected end-of-input: was expecting closing quote for string"; + if(ch=='\\') { + in>>ch; + if(ch==0) throw "Unexpected end-of-input in char escape sequence"; + if(ch=='"' || ch=='\\' || ch=='/') buf.append(ch); + else if(ch=='n') buf.append('\n'); + else if(ch=='r') buf.append('\r'); + else if(ch=='t') buf.append('\t'); + else if(ch=='f') buf.append('\f'); + else if(ch=='b') buf.append('\b'); + else if(ch=='u') { + auto hex = in.read(4); + if(hex.size()<4) throw "Unexpected end-of-input in char escape sequence"; + bool ok; + buf.append(hex.toUShort(&ok, 16)); + if(! ok) throw "Illegal hex-digits in char escape sequence: \\u"+hex; + } else throw QString("Unrecognized char-escape ")+ch+" (code "+ch+")"; + } else buf.append(ch); + } + return buf; +} +void JParser::skipSpace() { + if(bk.unicode()) { + bk = QChar::Null; + if(! ch.isSpace()) return; + } + in.skipWhiteSpace(); + in >> ch; + if(ch==0) throw "Unexpected end-of-input"; +} + +void JOut::write(const JValue &value) { + if(value.type==JValue::Null) out << "null"; + else if(value.type==JValue::Str) writeStr(value.toStr()); + else if(value.type==JValue::Obj) writeMap(value.toObj()); + else if(value.type==JValue::Array) writeList(value.toArray()); + else out << value.toStr(); + out.flush(); +} +void JOut::writeStr(const QString &str) { + out << '"'; + QChar ch; + for(int i=0; i + +class JValue; +using JObj = LinkedMap; +using JArray = Vector; + +class JValue { +public: + int data[2]{0}; + enum Type { + Null, Bool, Int, Long, Double, Obj, Array, Str + }; + Type type{Null}; + + JValue(Type = Null) {} + JValue(bool b) : type(Bool) {data[0] = b;} + JValue(int n) : type(Int) {data[0] = n;} + JValue(qint64 n) : type(Long) {*(qint64*) data = n;} + JValue(double d) : type(Double) {*(double*) data = d;} + JValue(const JObj &o) : type(Obj) {new (data) JObj(o);} + JValue(const JArray &a) : type(Array) {new (data) JArray(a);} + JValue(const QString &s) : type(Str) {*(SharedData**) data = new SharedData{s, 1};} + JValue(const char *s) : JValue(QString::fromUtf8(s)) {} + JValue(const JValue &other) { + type = other.type; + if(type==Obj) new (data) JObj(*(JObj*) other.data); + else if(type==Array) new (data) JArray(*(JArray*) other.data); + else { + data[0] = other.data[0]; + data[1] = other.data[1]; + if(type==Str) (*(SharedData**) data)->cnt++; + } + } + ~JValue() { + if(type < Obj) return; + else if(type==Obj) ((JObj*) data)->~JObj(); + else if(type==Array) ((JArray*) data)->~JArray(); + else if(type==Str) { + auto ptr = *(SharedData**) data; + if(ptr->cnt > 1) ptr->cnt--; + else delete ptr; + } + } + + JValue &operator=(const JValue &other) { + this->~JValue(); + new (this) JValue(other); + return *this; + } + + bool isNull() const {return type==Null;} + bool isObj() const {return type==Obj;} + bool isArray() const {return type==Array;} + + bool toBool(bool def = false) const { + return type==Null ? def : data[0] || data[1]; + } + int toInt(int def = 0) const { + if(type==Bool || type==Int) return data[0]; + if(type==Long) return *(qint64*) data; + if(type==Double) return *(double*) data; + return def; + } + qint64 toLong(qint64 def = 0) const { + if(type==Bool || type==Int) return data[0]; + if(type==Long) return *(qint64*) data; + if(type==Double) return *(double*) data; + return def; + } + double toDouble(double def = 0) const { + if(type==Bool || type==Int) return data[0]; + if(type==Long) return *(qint64*) data; + if(type==Double) return *(double*) data; + return def; + } + QString toStr(const QString &def = "") const { + if(type==Bool) return data[0] ? "true" : "false"; + if(type==Int) return QString::number(data[0]); + if(type==Long) return QString::number(*(qint64*) data); + if(type==Double) return QString::number(*(double*) data); + if(type==Str) return (*(SharedData**) data)->data; + return def; + } + JObj toObj() const { + if(type==Obj) return *(JObj*) data; + return JObj(); + } + JArray toArray() const { + if(type==Array) return *(JArray*) data; + return JArray(); + } +private: + JValue(const void *) = delete; // avoid implicit conversions from char * to bool +}; + +class JParser { +public: + JParser(QTextStream &in) : in(in) {} + + inline JValue read() { + skipSpace(); + return readValue(); + } +protected: + JValue readValue(); + QString readStr(); + void skipSpace(); + + QTextStream ∈ + QChar ch{0}, bk{0}; +}; + +inline JValue JFrom(const QByteArray &json, QString *err = 0) { + QTextStream in(json); + try { + return JParser(in).read(); + } catch (QString anerr) { + if(err) *err = anerr; + } catch (const char *anerr) { + if(err) *err = anerr; + } catch (...) { + if(err) *err = "unknow error"; + } + return JValue(); +} +inline JValue JFrom(QIODevice *device, QString *err = 0) { + QTextStream in(device); + try { + return JParser(in).read(); + } catch (QString anerr) { + if(err) *err = anerr; + } catch (const char *anerr) { + if(err) *err = anerr; + } catch (...) { + if(err) *err = "unknow error"; + } + return JValue(); +} + +class JOut { +public: + JOut(QTextStream &out, QString indent = "") : out(out), indent(indent) {} + + void write(const JValue &obj); + void writeStr(const QString &str); + void writeMap(const JObj &map); + void writeList(const JArray &objs); +protected: + QTextStream &out; + QString indent; + int cnt{0}; +}; + +inline QString JToStr(const JValue &obj, QString indent = "") { + QString json; + QTextStream out(&json); + JOut(out, indent).write(obj); + return json; +} +inline QByteArray JToBytes(const JValue &obj, QString indent = "") { + QByteArray json; + QTextStream out(&json); + JOut(out, indent).write(obj); + return json; +} +inline QTextStream::Status JWrite(const JValue &obj, QIODevice *device, QString indent = "") { + QTextStream out(device); + JOut(out, indent).write(obj); + return out.status(); +} + +#endif // QJSON_H diff --git a/LedOK/gutil/qnetwork.cpp b/LedOK/gutil/qnetwork.cpp index d49ea90..65cef07 100644 --- a/LedOK/gutil/qnetwork.cpp +++ b/LedOK/gutil/qnetwork.cpp @@ -5,16 +5,16 @@ const char *const FormBoundary = "----GangphonQtBoundary_.oOo._"; -QNetworkAccessManager &netAccess() { +QNetworkAccessManager *netAccess() { static QNetworkAccessManager access; - return access; + return &access; }; QString errStr(QNetworkReply *reply) { reply->deleteLater(); auto error = reply->error(); if(error != QNetworkReply::NoError) { - if(error==QNetworkReply::OperationCanceledError) return QString(QMetaEnum::fromType().valueToKey(QNetworkReply::TimeoutError))+" ("+QString::number(QNetworkReply::TimeoutError)+") "+QCoreApplication::translate("Net","Connection Timeout"); + if(error==QNetworkReply::OperationCanceledError) return "TimeoutError ("+QString::number(QNetworkReply::TimeoutError)+") "+QCoreApplication::translate("Net","Connection Timeout"); auto errStr = reply->errorString(); if(error!=QNetworkReply::InternalServerError || ! errStr.endsWith("replied: Unknown")) return QString(QMetaEnum::fromType().valueToKey(error))+" ("+QString::number(error)+") "+errStr; } diff --git a/LedOK/gutil/qnetwork.h b/LedOK/gutil/qnetwork.h index 0bc2b6d..70386a7 100644 --- a/LedOK/gutil/qnetwork.h +++ b/LedOK/gutil/qnetwork.h @@ -8,19 +8,38 @@ extern const char *const FormBoundary; -QNetworkAccessManager &netAccess(); +QNetworkAccessManager *netAccess(); class NetReq : public QNetworkRequest { public: +#if(QT_VERSION_MAJOR > 5) + using QNetworkRequest::QNetworkRequest; + explicit NetReq(const QString &url) : QNetworkRequest{url} {}; + explicit NetReq(QNetworkAccessManager *access) : mAccess(access) {}; +#else NetReq() {init();}; - explicit NetReq(const QString &url) : QNetworkRequest{url} {init();}; + explicit NetReq(QNetworkAccessManager *access) : mAccess(access) {init();}; explicit NetReq(const QUrl &url) : QNetworkRequest{url} {init();}; - NetReq(const QNetworkRequest &other) : QNetworkRequest{other} {init();}; - inline void init() { -#if(QT_VERSION_MAJOR < 6) setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); + } #endif + using QNetworkRequest::url; + inline NetReq &url(const QUrl &url) { + setUrl(url); + return *this; + } + inline NetReq &access(QNetworkAccessManager *access) { + mAccess = access; + return *this; + } + inline NetReq &header(const QByteArray &headerName, const QByteArray &value) { + setRawHeader(headerName, value); + return *this; + } + inline NetReq &header(KnownHeaders header, const QVariant &value) { + setHeader(header, value); + return *this; } inline NetReq &type(const QByteArray &value) { @@ -37,14 +56,16 @@ public: } inline QNetworkReply *get() { - return netAccess().get(*this); + if(mAccess==0) mAccess = netAccess(); + return mAccess->get(*this); } inline QNetworkReply *post(const QByteArray &data) { - return netAccess().post(*this, data); + if(mAccess==0) mAccess = netAccess(); + return mAccess->post(*this, data); } inline QNetworkReply *post(const QJsonDocument &json) { setRawHeader("Content-Type", "application/json"); - return netAccess().post(*this, json.toJson(QJsonDocument::Compact)); + return post(json.toJson(QJsonDocument::Compact)); } inline QNetworkReply *post(const QJsonObject &json) { return post(QJsonDocument{json}); @@ -53,13 +74,20 @@ public: return post(QJsonDocument{json}); } inline QNetworkReply *post(QHttpMultiPart *multiPart) { - return netAccess().post(*this, multiPart); + if(mAccess==0) mAccess = netAccess(); + return mAccess->post(*this, multiPart); } + QNetworkAccessManager *mAccess{0}; }; QString errStr(QNetworkReply *); QString errStrWithData(QNetworkReply *, QJsonDocument * = 0); +inline int waitFinished(QNetworkReply *reply, bool excludeUser = false) { + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + return excludeUser ? loop.exec(QEventLoop::ExcludeUserInputEvents) : loop.exec(); +} inline void abortSilence(QNetworkReply *reply) { reply->blockSignals(true); reply->abort(); diff --git a/LedOK/program/sendprogthread.cpp b/LedOK/program/sendprogthread.cpp index 8f85987..516b5b4 100644 --- a/LedOK/program/sendprogthread.cpp +++ b/LedOK/program/sendprogthread.cpp @@ -143,7 +143,7 @@ void SendProgThread::run() { return; } while(remain > 0) { - auto readed = file->read(qMin(4096LL, remain)); + auto readed = file->read(qMin(4*4096LL, remain)); if(readed.isEmpty()) { emit emErr(tr("Read file failed")+" "+file->errorString()); tcp.close(); diff --git a/LedOK/tools.cpp b/LedOK/tools.cpp index 18b255c..95f9177 100644 --- a/LedOK/tools.cpp +++ b/LedOK/tools.cpp @@ -124,21 +124,10 @@ QBrush Tools::getBrush(const QColor& color) { } int Tools::color2Int(const QColor& color) { - int res = 0; - res |= (color.red() & 0xFF) << 24; - res |= (color.green() & 0xFF) << 16; - res |= (color.blue() & 0xFF) << 8; - res |= (color.alpha() & 0xFF); - return res; + return color.red() << 24 | color.green() << 16 | color.blue() << 8 | color.alpha(); } - QColor Tools::int2Color(int value) { - QColor res; - res.setRed ((value >> 24) & 0xFF); - res.setGreen((value >> 16) & 0xFF); - res.setBlue ((value >> 8) & 0xFF); - res.setAlpha((value ) & 0xFF); - return res; + return QColor((value >> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff); } QString Tools::selectStr(bool f, const QString &s0, const QString &s1) {