diff --git a/LedOK/gutil/cpp.h b/LedOK/gutil/cpp.h index 2b333c0..2a36e87 100644 --- a/LedOK/gutil/cpp.h +++ b/LedOK/gutil/cpp.h @@ -2,19 +2,18 @@ #define CPP_H #include -#include #include -inline long long steady_milli() { +inline int64_t steady_milli() { return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); } -inline long long system_milli() { +inline int64_t system_milli() { return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); } -inline long long steady_micro() { +inline int64_t steady_micro() { return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); } -inline long long system_micro() { +inline int64_t system_micro() { return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); } @@ -195,7 +194,7 @@ public: LinkedMap() {} LinkedMap(std::initializer_list> pairs) : _pri{new LinkedMapPri} { - for(auto pair : pairs) insert(pair.first, pair.second); + 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; @@ -269,6 +268,20 @@ public: } else pair.first->second->value.second = v; return *this; } + V remove(const K& k) { + if(_pri==0) return V(); + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return V(); + auto node = it->second; + _pri->map.erase(it); + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + auto v = node->value.second; + delete node; + return v; + } void erase(const K& k) { if(_pri==0) return; auto it = _pri->map.find(k); diff --git a/LedOK/gutil/qcore.h b/LedOK/gutil/qcore.h index bf21dcc..385c6c5 100644 --- a/LedOK/gutil/qcore.h +++ b/LedOK/gutil/qcore.h @@ -27,10 +27,10 @@ inline QString gUrlSuffix(const QString &url, int size, bool withDot = false) { } inline QString byteSizeStr(double size) { - const char *units[]{"B", "KB", "MB", "GB", "TB", "PB"}; + const char *units[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"}; auto i = 0; - for(; size >= 1024 && i < 5; i++) size /= 1024; - return QString::number(size, 'g', 3)+" "+units[i]; + for(; size >= 1024 && i < 7; i++) size /= 1024; + return (size > 99 ? QString::number(size, 'f', 0) : QString::number(size, 'g', 3))+" "+units[i]; } inline void wait(int msec, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) { diff --git a/LedOK/gutil/qgui.cpp b/LedOK/gutil/qgui.cpp index 9d777e1..07f1ef1 100644 --- a/LedOK/gutil/qgui.cpp +++ b/LedOK/gutil/qgui.cpp @@ -36,12 +36,13 @@ bool TreeWidget::eventFilter(QObject *watched, QEvent *event) { if(event->type()==QEvent::Resize) { auto eve = (QResizeEvent *) event; if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0); + return true; } else if(isSectionResized && event->type()==QEvent::Leave) { isSectionResized = false; auto item = headerItem(); for(int cc=0; ccdata(cc, WidthRole).isValid()) item->setData(cc, WidthRole, header()->sectionSize(cc)); + return true; } - return true; } return QTreeWidget::eventFilter(watched, event); } @@ -214,12 +215,13 @@ bool TableWidget::eventFilter(QObject *watched, QEvent *event) { if(event->type()==QEvent::Resize) { auto eve = (QResizeEvent *) event; if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0); + return true; } else if(isSectionResized && event->type()==QEvent::Leave) { isSectionResized = false; QTableWidgetItem *item; for(int cc=0; ccdata(WidthRole).isValid()) item->setData(WidthRole, horizontalHeader()->sectionSize(cc)); + return true; } - return true; } return QTableWidget::eventFilter(watched, event); } diff --git a/LedOK/gutil/qgui.h b/LedOK/gutil/qgui.h index 62e8032..30e72ae 100644 --- a/LedOK/gutil/qgui.h +++ b/LedOK/gutil/qgui.h @@ -147,9 +147,9 @@ public: Grid(QSplitter *splitter) : QGridLayout(new QWidget) { splitter->addWidget(parentWidget()); }; - QLabel *addLabel(const QString& text) { + QLabel *addLabel(const QString& text, int row, int column, Qt::Alignment align = Qt::Alignment()) { auto lb = new QLabel(text); - addWidget(lb); + addWidget(lb, row, column, align); return lb; } }; @@ -274,6 +274,7 @@ public: int sizeHintForColumn(int column) const override { return QTreeWidget::sizeHintForColumn(column); } + bool adjSections(int index, int size); signals: void updGeos(); protected: @@ -285,7 +286,6 @@ protected: void rowsInserted(const QModelIndex &parent, int start, int end) override; void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const override; void onSectionResized(int logicalIndex, int oldSize, int newSize); - bool adjSections(int index, int size); bool noStretch = true; bool noMargin = true; bool isSectionResized = false; diff --git a/LedOK/gutil/qjson.cpp b/LedOK/gutil/qjson.cpp index ed6e8c4..574a13e 100644 --- a/LedOK/gutil/qjson.cpp +++ b/LedOK/gutil/qjson.cpp @@ -16,10 +16,10 @@ JValue JParser::readValue() { while(ch==','); if(ch=='}') return obj; QString key; - if(ch == '"') key = readStr(); + if(ch=='"') key = readStr(); else if(ch!='n' || readOne()!='u' || readOne()!='l' || readOne()!='l') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting double-quote to start field name or null"; skipSpace(); - if(ch != ':') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting a colon to separate field name and value"; + if(ch!=':') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting a colon to separate field name and value"; skipSpace(); obj.insert(key, readValue()); skipSpace(); //ch有两种可能 diff --git a/LedOK/gutil/qjson.h b/LedOK/gutil/qjson.h index be89662..08d49d8 100644 --- a/LedOK/gutil/qjson.h +++ b/LedOK/gutil/qjson.h @@ -5,6 +5,7 @@ #include "QtCore/qhashfunctions.h" #include #include + class JValue; using JObj = LinkedMap; using JArray = Vector; @@ -13,7 +14,7 @@ QDebug operator<<(QDebug debug, const JValue &val); class JValue { public: - long long data = 0; + int64_t data = 0; enum Type { Null, Long, Ulong, Double, Bool, Obj, Array, Str }; @@ -119,10 +120,17 @@ public: const JValue operator[](const QString &key) const { return type==Obj ? (*(const JObj*) &data)[key] : JValue(); } - const JValue operator[](int i) const { + const JValue operator[](uint64_t i) const { return type==Array ? (*(const JArray*) &data)[i] : JValue(); } + JValue &ref(const QString &key) { + return (*(JObj*) &data)[key]; + } + JValue &ref(uint64_t i) { + return (*(JArray*) &data)[i]; + } + JArray::iterator begin() const noexcept { return type==Array ? ((const JArray*) &data)->begin() : JArray::iterator(); } @@ -167,6 +175,7 @@ private: class JParser { public: JParser(QDataStream &in) : in(in) {} + JValue read() { in >> ch; if(ch==0) throw "Unexpected end-of-input"; @@ -182,6 +191,7 @@ protected: in >> ch; return ch; } + QDataStream ∈ unsigned char ch{0}, bk{0}; };