This commit is contained in:
Gangphon 2023-09-19 11:49:20 +08:00
parent a9b29230e8
commit 07f6adc278
87 changed files with 12869 additions and 15507 deletions

View File

@ -46,11 +46,10 @@ osx {
ICON = res/Logo-raw.png ICON = res/Logo-raw.png
} }
RESOURCES += res.qrc
copydir.files += AClock copydir.files += AClock
copydir.files += borders copydir.files += borders
copydir.files += translations
copydir.files += $$quote(y50 param) copydir.files += $$quote(y50 param)
copydir.files += $$quote(files) copydir.files += $$quote(files)
@ -93,6 +92,7 @@ qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target
RESOURCES += res.qrc
SOURCES += \ SOURCES += \
base/changepasswordform.cpp \ base/changepasswordform.cpp \
@ -103,7 +103,7 @@ SOURCES += \
base/lodateselector.cpp \ base/lodateselector.cpp \
base/loqtitlebar.cpp \ base/loqtitlebar.cpp \
base/loqtreewidget.cpp \ base/loqtreewidget.cpp \
base/waitingdlg.cpp \ gutil/qwaitingdlg.cpp \
basedlg.cpp \ basedlg.cpp \
basewin.cpp \ basewin.cpp \
cfg.cpp \ cfg.cpp \
@ -117,6 +117,7 @@ SOURCES += \
devicepanel.cpp \ devicepanel.cpp \
ffplayer.cpp \ ffplayer.cpp \
globaldefine.cpp \ globaldefine.cpp \
gutil/cpp.cpp \
gutil/qgui.cpp \ gutil/qgui.cpp \
gutil/qjson.cpp \ gutil/qjson.cpp \
gutil/qnetwork.cpp \ gutil/qnetwork.cpp \
@ -142,7 +143,6 @@ SOURCES += \
device/ctrlbrightpanel.cpp \ device/ctrlbrightpanel.cpp \
device/ctrlverifyclockpanel.cpp \ device/ctrlverifyclockpanel.cpp \
device/upgradeapkdialog.cpp \ device/upgradeapkdialog.cpp \
device/wupgradeapkitem.cpp \
program/copydirthread.cpp \ program/copydirthread.cpp \
program/eaclock.cpp \ program/eaclock.cpp \
program/ebase.cpp \ program/ebase.cpp \
@ -158,14 +158,11 @@ SOURCES += \
program/gentmpthread.cpp \ program/gentmpthread.cpp \
program/pageeditor.cpp \ program/pageeditor.cpp \
program/pagelistitem.cpp \ program/pagelistitem.cpp \
program/progcreatedlg.cpp \
program/progeditorwin.cpp \ program/progeditorwin.cpp \
program/progitem.cpp \ program/progitem.cpp \
program/sendprogramdialog.cpp \ program/sendprogramdialog.cpp \
program/sendprogthread.cpp \ program/sendprogthread.cpp \
program/videosplitthread.cpp \ program/videosplitthread.cpp \
program/wplanitem.cpp \
program/wplanlist.cpp \
HEADERS += \ HEADERS += \
base/changepasswordform.h \ base/changepasswordform.h \
@ -175,7 +172,7 @@ HEADERS += \
base/lodateselector.h \ base/lodateselector.h \
base/loqtitlebar.h \ base/loqtitlebar.h \
base/loqtreewidget.h \ base/loqtreewidget.h \
base/waitingdlg.h \ gutil/qwaitingdlg.h \
basedlg.h \ basedlg.h \
basewin.h \ basewin.h \
cfg.h \ cfg.h \
@ -189,6 +186,7 @@ HEADERS += \
devicepanel.h \ devicepanel.h \
ffplayer.h \ ffplayer.h \
globaldefine.h \ globaldefine.h \
gutil/cpp.h \
gutil/qgui.h \ gutil/qgui.h \
gutil/qjson.h \ gutil/qjson.h \
gutil/qnetwork.h \ gutil/qnetwork.h \
@ -213,7 +211,6 @@ HEADERS += \
device/ctrlbrightpanel.h \ device/ctrlbrightpanel.h \
device/ctrlverifyclockpanel.h \ device/ctrlverifyclockpanel.h \
device/upgradeapkdialog.h \ device/upgradeapkdialog.h \
device/wupgradeapkitem.h \
program/copydirthread.h \ program/copydirthread.h \
program/eaclock.h \ program/eaclock.h \
program/ebase.h \ program/ebase.h \
@ -229,25 +226,17 @@ HEADERS += \
program/gentmpthread.h \ program/gentmpthread.h \
program/pageeditor.h \ program/pageeditor.h \
program/pagelistitem.h \ program/pagelistitem.h \
program/progcreatedlg.h \
program/progeditorwin.h \ program/progeditorwin.h \
program/progitem.h \ program/progitem.h \
program/sendprogramdialog.h \ program/sendprogramdialog.h \
program/sendprogthread.h \ program/sendprogthread.h \
program/videosplitthread.h \ program/videosplitthread.h \
program/wplanitem.h \
program/wplanlist.h \
TRANSLATIONS += \ TRANSLATIONS += \
translations/app_zh_CN.ts \ ts/app_zh_CN.ts \
translations/app_zh_TW.ts \ ts/app_zh_TW.ts \
translations/app_ja.ts \ ts/app_en.ts \
translations/app_en.ts ts/app_ja.ts \
ts/app_pt.ts
EXTRA_TRANSLATIONS += \
translations/qt_zh_CN.ts \
translations/qt_zh_TW.ts \
translations/qt_ja.ts \
translations/qt_en.ts
include(./xlsx/qtxlsx.pri) include(./xlsx/qtxlsx.pri)

File diff suppressed because one or more lines are too long

View File

@ -1,65 +1,40 @@
#include "loqtreewidget.h" #include "loqtreewidget.h"
#include <QCheckBox> #include <QGuiApplication>
#include <QHeaderView>
class CheckableHeader : public QHeaderView { void LoQTreeWidget::addFd() {
public: fdCheckAll = new QCheckBox(this);
explicit CheckableHeader(Qt::Orientation orientation, QWidget *isSelAll) : QHeaderView(orientation), fdIsSelAll(isSelAll) { connect(fdCheckAll, &QCheckBox::stateChanged, this, [=](int state) {
fdIsSelAll->setParent(this); if(state==Qt::PartiallyChecked) return;
} int cnt = topLevelItemCount();
QWidget *fdIsSelAll; for(int rr=0; rr<cnt; rr++) if(! topLevelItem(rr)->isHidden()) topLevelItem(rr)->setCheckState(1, (Qt::CheckState) state);
protected: emit selChanged();
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const override {
QHeaderView::paintSection(painter, rect, logicalIndex);
if(logicalIndex == 0) fdIsSelAll->setGeometry(rect);
}
};
LoQTreeWidget::LoQTreeWidget(QWidget *parent) : QTreeWidget(parent), m_checkState(CheckNone) {
fdIsSelAll = new QCheckBox;
fdIsSelAll->setStyleSheet("QCheckBox{margin-left: 5px;}");
m_header = new CheckableHeader(Qt::Horizontal, fdIsSelAll);
setHeader(m_header);
setProperty("ssType", "topList");
connect(fdIsSelAll, SIGNAL(toggled(bool)), this, SLOT(onCheckAll(bool)));
connect(this, &LoQTreeWidget::itemClicked, this, [this](QTreeWidgetItem *item, int column) {
if(selectionMode()==QAbstractItemView::NoSelection) return;
if(column > 0) item->setCheckState(0, item->checkState(0) == Qt::Unchecked ? Qt::Checked : Qt::Unchecked);
adjustCheckState();
}); });
setFocusPolicy(Qt::NoFocus); auto cellClicked = [=](QTreeWidgetItem *item, int column) {
} if(column > 2) return;
void LoQTreeWidget::adjustCheckState() { if(! fdCheckAll->isVisible()) return;
bool isAllChecked = true; auto state = item->checkState(1)==Qt::Checked ? Qt::Unchecked : Qt::Checked;
int cnt = topLevelItemCount(); item->setCheckState(1, state);
if(cnt == 0) { int cnt = topLevelItemCount();
isAllChecked = false; fdCheckAll->blockSignals(true);
m_checkState = CheckNone; for(int rr=0; rr<cnt; rr++) if(! topLevelItem(rr)->isHidden() && topLevelItem(rr)->checkState(1)!=state) {
} else { fdCheckAll->setCheckState(Qt::PartiallyChecked);
int k = 0; goto end;
for(int i=0; i<cnt; i++) if(!this->isRowHidden(i,indexFromItem(topLevelItem(i)->parent()))) {
if(topLevelItem(i)->checkState(0) == Qt::Unchecked) isAllChecked = false;
else k++;
} }
if(k > 1) m_checkState = CheckMulti; fdCheckAll->setCheckState(state);
else if(k > 0) m_checkState = CheckOne; end:fdCheckAll->blockSignals(false);
else m_checkState = CheckNone; emit selChanged();
} };
fdIsSelAll->blockSignals(true); connect(this, &QTreeWidget::itemClicked, this, cellClicked);
fdIsSelAll->setChecked(isAllChecked); connect(this, &QTreeWidget::itemEntered, this, [=](QTreeWidgetItem *item, int column) {
fdIsSelAll->blockSignals(false); if(column > 2) return;
emit sigCheckStateChanged(m_checkState); if(! fdCheckAll->isVisible()) return;
if((QGuiApplication::mouseButtons() & Qt::LeftButton) == 0) return;
cellClicked(item, column);
});
} }
void LoQTreeWidget::onCheckAll(bool checked) { void LoQTreeWidget::updateGeometries() {
int cnt = topLevelItemCount(); QTreeWidget::updateGeometries();
for(int i=0; i<cnt; i++) { if(fdCheckAll==0) return;
if(checked) { fdCheckAll->move(columnWidth(0)+headerItem()->data(1, MarginRole).toInt()+4, 2);
if(this->isRowHidden(i,indexFromItem(topLevelItem(i)->parent()))) topLevelItem(i)->setCheckState(0, Qt::Unchecked);
else topLevelItem(i)->setCheckState(0, Qt::Checked);
}
else topLevelItem(i)->setCheckState(0, Qt::Unchecked);
}
adjustCheckState();
} }

View File

@ -1,34 +1,19 @@
#ifndef LOQTREEWIDGET_H #ifndef LOQTREEWIDGET_H
#define LOQTREEWIDGET_H #define LOQTREEWIDGET_H
#include "gutil/qgui.h"
#include <QCheckBox> #include <QCheckBox>
#include <QTreeWidgetItem>
class LoQTreeWidget : public QTreeWidget { class LoQTreeWidget : public TreeWidget {
Q_OBJECT Q_OBJECT
public: public:
enum CheckState { using TreeWidget::TreeWidget;
CheckNone, void addFd();
CheckOne, QCheckBox *fdCheckAll = 0;
CheckMulti
};
explicit LoQTreeWidget(QWidget *parent = nullptr);
void adjustCheckState();
QModelIndex indexFromItem(const QTreeWidgetItem *item, int column = 0) const {
return QTreeWidget::indexFromItem(item, column);
};
QCheckBox *fdIsSelAll;
signals: signals:
void sigCheckStateChanged(int); void selChanged();
protected:
public slots: void updateGeometries() override;
void onCheckAll(bool checked);
private:
QHeaderView *m_header;
int m_checkState;
}; };
#endif // LOQTREEWIDGET_H #endif // LOQTREEWIDGET_H

View File

@ -34,7 +34,7 @@ void BaseWin::paintEvent(QPaintEvent *e) {
painter.setPen(isActive ? penTitleAct : penTitleUnact); painter.setPen(isActive ? penTitleAct : penTitleUnact);
isMaximized() ? painter.drawText(titlePos.x()-8, titlePos.y()-8, title) : painter.drawText(titlePos, title); isMaximized() ? painter.drawText(titlePos.x()-8, titlePos.y()-8, title) : painter.drawText(titlePos, title);
} }
if(! icon.isNull()) isMaximized() ? painter.drawPixmap(iconPos.x()-8, iconPos.y()-8, icon) : painter.drawPixmap(iconPos, icon); if(! icon.isNull()) isMaximized() ? painter.drawPixmap(iconPos.x()-8, iconPos.y()-8, iconPos.width(), iconPos.height(), icon) : painter.drawPixmap(iconPos, icon, QRectF());
} }
void BaseWin::mousePressEvent(QMouseEvent *e) { void BaseWin::mousePressEvent(QMouseEvent *e) {

View File

@ -14,7 +14,7 @@ public:
qreal roundRadius{6.0}; qreal roundRadius{6.0};
QPointF titlePos{36, 26}; QPointF titlePos{36, 26};
QPixmap icon; QPixmap icon;
QPointF iconPos{13, 13}; QRectF iconPos{13, 13, 16, 16};
protected: protected:
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;
void mousePressEvent(QMouseEvent *) override; void mousePressEvent(QMouseEvent *) override;

View File

@ -1,10 +1,10 @@
Table {selection-background-color: #0ae;} QListWidget, QTreeWidget, TableWidget {selection-background-color: #4ae;}
QCheckBox::indicator, QTableWidget::indicator, QTreeWidget::indicator { QCheckBox::indicator, QTableWidget::indicator, QTreeWidget::indicator {
width: 1.15em; height: 1.15em; width: 1.15em; height: 1.15em;
} }
QLineEdit,QComboBox,QAbstractSpinBox { QLineEdit, QComboBox, QAbstractSpinBox {
border: 1px solid #aaa; border: 1px solid #aaa;
border-radius: 3px; border-radius: 3px;
padding: 2px; padding: 2px;
@ -70,10 +70,6 @@ QMenu::item:selected {
background-color: #8CD; background-color: #8CD;
} }
QListWidget {
selection-background-color: #0ae;
}
LoColorSelector { LoColorSelector {
border: 1px solid #aaa; border: 1px solid #aaa;
border-radius: 4px; border-radius: 4px;
@ -83,20 +79,6 @@ LoColorSelector {
font-size: 14px; font-size: 14px;
} }
QTreeWidget[ssType="topList"]::item {
border-right: 1px solid #ddd;
border-bottom: 1px solid #ddd;
height: 38px;
}
QTreeWidget[ssType="topList"]>QHeaderView::section {
height: 30px;
}
QTreeWidget[ssType="topList"]::item:hover {
background-color: #ddd;
}
QPushButton[ssType="progManageTool"] { QPushButton[ssType="progManageTool"] {
border-radius: 4px; border-radius: 4px;
background-color: #19c; background-color: #19c;
@ -115,7 +97,6 @@ QPushButton[ssType="progManageTool"]:disabled {
color: #777; color: #777;
} }
LoQTitleBar QPushButton { LoQTitleBar QPushButton {
border-radius: 4px; border-radius: 4px;
icon-size: 20px; icon-size: 20px;

View File

@ -8,11 +8,14 @@
#include <QMessageBox> #include <QMessageBox>
#include <QMetaEnum> #include <QMetaEnum>
QString gFileHome;
QString gApkHome;
QList<LedCard> gSelCards; QList<LedCard> gSelCards;
bool gVideoCompress = true; bool gVideoCompress = true;
bool gVideoTranscoding = true; bool gVideoTranscoding = true;
bool gTextAntialiasing = false; bool gTextAntialiasing = false;
bool gWidthSplit = false; bool gWidthSplit = false;
int gSendBatch = 5;
bool gHideDetect = false; bool gHideDetect = false;
bool gShowLora = false; bool gShowLora = false;

View File

@ -40,6 +40,8 @@ struct ST_ANSY_PROGRAM_PACKET {
unsigned char pDataBuffer[20]; unsigned char pDataBuffer[20];
}; };
extern QString gFileHome;
extern QString gApkHome;
class DevicePanel; class DevicePanel;
extern DevicePanel *gDevicePanel; extern DevicePanel *gDevicePanel;
extern QList<LedCard> gSelCards; extern QList<LedCard> gSelCards;
@ -47,6 +49,7 @@ extern bool gVideoCompress;
extern bool gVideoTranscoding; extern bool gVideoTranscoding;
extern bool gTextAntialiasing; extern bool gTextAntialiasing;
extern bool gWidthSplit; extern bool gWidthSplit;
extern int gSendBatch;
extern bool gHideDetect; extern bool gHideDetect;
extern bool gShowLora; extern bool gShowLora;
@ -69,7 +72,6 @@ enum _ENUM_CONTRL_WIDGET {
class DeviceItem; class DeviceItem;
extern DeviceItem *findItem(QString id); extern DeviceItem *findItem(QString id);
inline int verCompare(const QString& a, const QString& b) { inline int verCompare(const QString& a, const QString& b) {
auto aparts = a.split("."); auto aparts = a.split(".");
auto bparts = b.split("."); auto bparts = b.split(".");

2
LedOK/gutil/cpp.cpp Normal file
View File

@ -0,0 +1,2 @@
//#include "cpp.h"

View File

@ -1,5 +1,5 @@
#ifndef CU_H #ifndef CPP_H
#define CU_H #define CPP_H
#include <chrono> #include <chrono>
#include <memory> #include <memory>
@ -21,44 +21,64 @@ inline long long system_micro() {
template <class T> template <class T>
struct SharedData { struct SharedData {
size_t cnt{1};
T data; T data;
uint64_t cnt{1};
}; };
template <class T> template <class T>
class SharedPtr { class SharedPtr {
public: public:
SharedPtr(SharedData<T> *ptr = 0) : ptr{ptr} {} SharedPtr(SharedData<T> *ptr = 0) : ptr{ptr} {}
SharedPtr(const SharedPtr &other) : ptr{other.ptr} {
if(ptr) ptr->cnt++;
}
~SharedPtr() { ~SharedPtr() {
if(ptr==0) return; if(ptr==0) return;
if(ptr->cnt > 1) ptr->cnt--; if(ptr->cnt > 1) ptr->cnt--;
else delete ptr; else delete ptr;
} }
bool isNull() {return ptr==0;} SharedPtr(const SharedPtr &other) : ptr{other.ptr} {
if(ptr) ptr->cnt++;
}
SharedPtr &operator=(const SharedPtr &other) { SharedPtr &operator=(const SharedPtr &other) {
this->~SharedPtr(); this->~SharedPtr();
new (this) SharedPtr(other); new (this) SharedPtr(other);
return *this; return *this;
} }
SharedPtr(SharedPtr &&other) noexcept : ptr(other.ptr) {
other.ptr = 0;
}
SharedPtr &operator=(SharedPtr &&other) noexcept {
auto aaa = ptr;
ptr = other._pri;
other.ptr = aaa;
return *this;
}
T &operator*() { bool isNull() const noexcept {return ptr==0;}
bool empty() const noexcept {
return ptr ? ptr->data.empty() : true;
}
size_t size() const noexcept {
return ptr ? ptr->data.size() : 0;
}
T &operator*() const {
if(ptr==0) ptr = new SharedData<T>; if(ptr==0) ptr = new SharedData<T>;
return ptr->data; return ptr->data;
} }
T *operator->() { T *operator->() const {
if(ptr==0) ptr = new SharedData<T>; if(ptr==0) ptr = new SharedData<T>;
return &ptr->data; return &ptr->data;
} }
const T &operator*() const { bool operator==(const SharedPtr &other) const {
return ptr->data; if(ptr==other.ptr) return true;
auto siz = size();
if(siz!=other.size()) return false;
if(siz==0) return true;
return ptr->data==other.ptr->data;
} }
const T *operator->() const { bool operator!=(const SharedPtr &other) const {
return &ptr->data; return ! (*this==other);
} }
SharedData<T> *ptr{0}; mutable SharedData<T> *ptr = 0;
}; };
@ -71,30 +91,38 @@ public:
using const_iterator = std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<V>>>; using const_iterator = std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<V>>>;
Vector(std::initializer_list<V> _Ilist) { Vector(std::initializer_list<V> _Ilist) {
this->ptr = new SharedData<std::vector<V>>{_Ilist, 1}; this->ptr = new SharedData<std::vector<V>>{1, _Ilist};
} }
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) { Vector &append(const V &val) {
(**this).push_back(val); (*this)->push_back(val);
return *this; return *this;
} }
Vector &append(V&& val) {
(*this)->push_back(_STD move(val));
return *this;
}
Vector &operator<<(const V &val) {
(*this)->push_back(val);
return *this;
}
Vector &operator<<(V&& val) {
(*this)->push_back(_STD move(val));
return *this;
}
V &operator[](const uint64_t pos) noexcept { V &operator[](const uint64_t pos) noexcept {
return (**this)[pos]; return (**this)[pos];
} }
const V &operator[](const uint64_t pos) const noexcept { const V &operator[](const uint64_t pos) const noexcept {
return this->ptr ? this->ptr->data[pos] : V(); return (**this)[pos];
} }
const const_iterator begin() const noexcept {
return this->ptr ? this->ptr->data.begin() : const_iterator(); iterator begin() const noexcept {
return this->ptr ? this->ptr->data.begin() : iterator();
} }
const const_iterator end() const noexcept { iterator end() const noexcept {
return this->ptr ? this->ptr->data.end() : const_iterator(); return this->ptr ? this->ptr->data.end() : iterator();
} }
}; };
@ -103,45 +131,55 @@ struct NodeBase {
NodeBase *next{this}; NodeBase *next{this};
NodeBase *prev{this}; NodeBase *prev{this};
}; };
template <class V> template <class P>
struct _Node : NodeBase { struct _Node : NodeBase {
V value; P value;
~_Node() { ~_Node() {
if(next) delete (_Node<V>*) next; if(next) delete (_Node<P>*) next;
} }
}; };
template <class V> template <class P>
class LinkedMapIterator { class LinkedMapIterator {
public: public:
LinkedMapIterator(_Node<V> *node) : node(node) {} LinkedMapIterator(_Node<P> *node) : node(node) {}
bool operator==(const LinkedMapIterator& that) const { bool operator==(const LinkedMapIterator& other) const noexcept {
return node == that.node; return node == other.node;
} }
bool operator!=(const LinkedMapIterator& that) const { bool operator!=(const LinkedMapIterator& other) const noexcept {
return node != that.node; return node != other.node;
} }
LinkedMapIterator& operator++() { LinkedMapIterator& operator++() {
node = (_Node<V>*) node->next; node = (_Node<P>*) node->next;
return *this; return *this;
} }
LinkedMapIterator& operator--() { LinkedMapIterator& operator--() {
node = (_Node<V>*) node->prev; node = (_Node<P>*) node->prev;
return *this; return *this;
} }
V &operator*() const { const LinkedMapIterator operator++(int) {
auto rtn = *this;
node = (_Node<P>*) node->next;
return rtn;
}
const LinkedMapIterator operator--(int) {
auto rtn = *this;
node = (_Node<P>*) node->prev;
return rtn;
}
P &operator*() const noexcept {
return node->value; return node->value;
} }
V *operator->() const { P *operator->() const noexcept {
return &node->value; return &node->value;
} }
_Node<V> *node{0}; _Node<P> *node{0};
}; };
template <class K, class V> template <class K, class V>
struct LinkedMapPri : NodeBase { struct LinkedMapPri : NodeBase {
size_t cnt = 1;
std::unordered_map<K, _Node<std::pair<K, V>>*> map; std::unordered_map<K, _Node<std::pair<K, V>>*> map;
uint64_t cnt{1};
~LinkedMapPri() { ~LinkedMapPri() {
if(prev) prev->next = 0; if(prev) prev->next = 0;
if(next) delete (_Node<std::pair<K, V>>*) next; if(next) delete (_Node<std::pair<K, V>>*) next;
@ -162,26 +200,64 @@ public:
LinkedMap(std::unordered_map<K, Node*> &&map) : _pri{new LinkedMapPri<K, V>{0, 0, map}} { LinkedMap(std::unordered_map<K, Node*> &&map) : _pri{new LinkedMapPri<K, V>{0, 0, map}} {
_pri->next = _pri->prev = _pri; _pri->next = _pri->prev = _pri;
} }
LinkedMap(const LinkedMap &other) : _pri{other._pri} {
if(_pri) _pri->cnt++;
}
~LinkedMap() { ~LinkedMap() {
if(_pri==0) return; if(_pri==0) return;
if(_pri->cnt > 1) _pri->cnt--; if(_pri->cnt > 1) _pri->cnt--;
else delete _pri; else delete _pri;
} }
LinkedMap(const LinkedMap &other) : _pri{other._pri} {
if(_pri) _pri->cnt++;
}
LinkedMap &operator=(const LinkedMap &other) { LinkedMap &operator=(const LinkedMap &other) {
this->~LinkedMap(); this->~LinkedMap();
new (this) LinkedMap(other); new (this) LinkedMap(other);
return *this; return *this;
} }
LinkedMap(LinkedMap &&other) noexcept : _pri(other._pri) {
other._pri = 0;
}
LinkedMap &operator=(LinkedMap &&other) noexcept {
auto aaa = _pri;
_pri = other._pri;
other._pri = aaa;
return *this;
}
bool empty() const noexcept {
return _pri==0 || _pri->map.empty();
}
size_t size() const noexcept {
return _pri ? _pri->map.size() : 0;
}
iterator find(const K &k) const {
if(_pri==0) return iterator((Node*) _pri);
auto it = _pri->map.find(k);
if(it==_pri->map.end()) return iterator((Node*) _pri);
return iterator(it->second);
}
const V operator()(const K &k) const {
return (*this)[k];
}
const V operator[](const K &k) const { const V operator[](const K &k) const {
if(_pri==0) return V(); if(_pri==0) return V();
auto it = _pri->map.find(k); auto it = _pri->map.find(k);
if(it==_pri->map.end()) return V(); if(it==_pri->map.end()) return V();
return it->second->value.second; return it->second->value.second;
} }
V &operator[](const K &k) {
if(_pri==0) _pri = new LinkedMapPri<K, V>;
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;
}
return pair.first->second->value.second;
}
LinkedMap &insert(const K &k, const V &v) { LinkedMap &insert(const K &k, const V &v) {
if(_pri==0) _pri = new LinkedMapPri<K, V>; if(_pri==0) _pri = new LinkedMapPri<K, V>;
auto pair = _pri->map.emplace(k, nullptr); auto pair = _pri->map.emplace(k, nullptr);
@ -205,17 +281,32 @@ public:
node->prev = 0; node->prev = 0;
delete node; delete node;
} }
inline bool empty() const {
return _pri==0 || _pri->map.empty(); bool operator==(const LinkedMap &other) const {
if(_pri==other._pri) return true;
auto siz = size();
if(siz!=other.size()) return false;
if(siz==0) return true;
auto aaa = begin();
auto bbb = other.begin();
while(aaa!=end()) {
if(aaa->first != bbb->first || aaa->second != bbb->second) return false;
++aaa;
++bbb;
}
return true;
}
bool operator!=(const LinkedMap &other) const {
return ! (*this==other);
} }
const_iterator begin() const { iterator begin() const {
return const_iterator((Node*) (_pri ? _pri->next : 0)); return iterator((Node*) (_pri ? _pri->next : 0));
} }
const_iterator end() const { iterator end() const {
return const_iterator((Node*) _pri); return iterator((Node*) _pri);
} }
LinkedMapPri<K, V> *_pri{0}; LinkedMapPri<K, V> *_pri = 0;
}; };
#endif // CU_H #endif // CPP_H

View File

@ -1,2 +0,0 @@
//#include "cu.h"

View File

@ -1,6 +1,30 @@
#ifndef QCORE_H #ifndef QCORE_H
#define QCORE_H #define QCORE_H
#include <QThread> #include <QThread>
#include <QEventLoop>
#include <QTimer>
#define ToStr QString::number
inline QString toStr(int num, int base=10) {return QString::number(num, base);}
inline QString toStr(uint num, int base=10) {return QString::number(num, base);}
inline QString toStr(long num, int base=10) {return QString::number(num, base);}
inline QString toStr(ulong num, int base=10) {return QString::number(num, base);}
inline QString toStr(qlonglong num, int base=10) {return QString::number(num, base);}
inline QString toStr(qulonglong num, int base=10) {return QString::number(num, base);}
inline QString toStr(double num, char format='g', int precision=6) {return QString::number(num, format, precision);}
inline QString gUrlSuffix(const QString &url, int size, bool withDot = false) {
auto ss = url.lastIndexOf('/')+1;
if(ss==url.size()) return QString();
ss++;
auto ee = url.indexOf('?', ss);
if(ee==-1) ee = url.size();
int end = ee-size-1;
if(end<ss) end = ss;
for(int i=ee-1; i>=end; --i) if(url[i]=='.') return withDot ? url.mid(i, ee-i) : url.mid(i+1, ee-i-1);
return QString();
}
inline QString byteSizeStr(double size) { inline QString byteSizeStr(double size) {
const char *units[]{"B", "KB", "MB", "GB", "TB", "PB"}; const char *units[]{"B", "KB", "MB", "GB", "TB", "PB"};
@ -9,17 +33,13 @@ inline QString byteSizeStr(double size) {
return QString::number(size, 'g', 3)+" "+units[i]; return QString::number(size, 'g', 3)+" "+units[i];
} }
inline long long steady_milli() { inline void wait(int msec, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); QTimer timer;
} timer.setSingleShot(true);
inline long long system_milli() { QEventLoop loop;
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
} timer.start(msec);
inline long long steady_micro() { loop.exec(flags);
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
inline long long system_micro() {
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
} }
template <typename Func> template <typename Func>

View File

@ -1,44 +1,212 @@
#include "qgui.h" #include "qgui.h"
#include <QPainter>
#include <QResizeEvent> #include <QResizeEvent>
#include <QProxyStyle>
const int AlignRight = Qt::AlignRight | Qt::AlignVCenter; const Qt::Alignment AlignRight = Qt::AlignRight | Qt::AlignVCenter;
Table::Table(std::initializer_list<ColAttr> colAttrs, int rows, QWidget *parent) : QTableWidget{rows, (int)colAttrs.size(), parent} { ColItem TreeWidget::addCol(const QString& field, const QString& text, int width, QHeaderView::ResizeMode resizeMode) {
int i = 0; int i = fdmap.size();
for(typename std::initializer_list<ColAttr>::const_iterator it = colAttrs.begin(); it != colAttrs.end(); ++it) { auto item = headerItem();
auto item = horizontalHeaderItem(i); item->setText(i, text);
if(item==0) setHorizontalHeaderItem(i, item = new QTableWidgetItem()); item->setData(i, FieldRole, field);
item->setText(it->text); if(width > 0) {
if(it->width > 0) horizontalHeader()->resizeSection(i, it->width); blocked = true;
if(it->resizeMode != QHeaderView::Interactive) { if(header()->minimumSectionSize() > width) header()->setMinimumSectionSize(width);
if(it->resizeMode==QHeaderView::Stretch && it->width>0) { header()->resizeSection(i, width);
item->setData(0x99, it->width > 0 ? it->width : 100); blocked = false;
}
if(resizeMode != QHeaderView::Interactive) {
if(resizeMode==QHeaderView::Stretch && width > 0) {
item->setData(i, WidthRole, width);
if(noStretch) {
noStretch = false; noStretch = false;
} else horizontalHeader()->setSectionResizeMode(i, (QHeaderView::ResizeMode)it->resizeMode); connect(header(), &QHeaderView::sectionResized, this, &TreeWidget::onSectionResized);
header()->installEventFilter(this);
}
} else header()->setSectionResizeMode(i, resizeMode);
}
fdmap.emplace(field, i);
if(i==0) hasRowNum = field=="#";
return {item, i};
}
bool TreeWidget::eventFilter(QObject *watched, QEvent *event) {
if(watched==header()) {
if(event->type()==QEvent::Resize) {
auto eve = (QResizeEvent *) event;
if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0);
} else if(isSectionResized && event->type()==QEvent::Leave) {
isSectionResized = false;
auto item = headerItem();
for(int cc=0; cc<columnCount(); cc++) if(item->data(cc, WidthRole).isValid()) item->setData(cc, WidthRole, header()->sectionSize(cc));
}
return true;
}
return QTreeWidget::eventFilter(watched, event);
}
void TreeWidget::rowsInserted(const QModelIndex &parent, int start, int end) {
QTreeWidget::rowsInserted(parent, start, end);
if(parent.internalId()) return;
if(minRowHeight) for(int rr=start; rr<=end; rr++) {
auto item = topLevelItem(rr);
if(item->sizeHint(0).height() < minRowHeight) item->setSizeHint(0, {0, minRowHeight});
}
int align;
for(int cc=0; cc<columnCount(); cc++) if((align = headerItem()->data(cc, AlignRole).toInt())) for(int rr=start; rr<=end; rr++) topLevelItem(rr)->setTextAlignment(cc, (Qt::Alignment)align);
}
void TreeWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const {
QTreeWidget::drawRow(painter, options, index);
if(hasRowNum) {
QRect rect(columnViewportPosition(0), options.rect.top(), columnWidth(0), options.rect.height());
painter->fillRect(rect, header()->palette().button());
painter->drawText(rect, Qt::AlignCenter, QString::number(index.row()+1));
}
if(hasGrid) {
QBrush color({128, 128, 128, 128});
QRect rec(options.rect.left()-1-horizontalOffset(), options.rect.top(), 1, options.rect.height());
auto last = columnCount() - 1;
if(hasGrid > 1) for(int i=0; i<last; i++) {
rec.translate(columnWidth(header()->logicalIndex(i)), 0);
painter->fillRect(rec, color);
} else {
int ttlwidth = columnWidth(header()->logicalIndex(last));
for(int i=0; i<last; i++) {
auto width = columnWidth(header()->logicalIndex(i));
rec.translate(width, 0);
painter->fillRect(rec, color);
ttlwidth += width;
}
painter->fillRect(options.rect.left(), options.rect.bottom(), ttlwidth, 1, color);
} }
mFieldMap.emplace(it->field, i++);
} }
} }
void TreeWidget::onSectionResized(int logicalIndex, int oldSize, int newSize) {
void Table::resizeEvent(QResizeEvent *event) { if(blocked || newSize==0 || oldSize==0) return;
QTableWidget::resizeEvent(event); if(! headerItem()->data(logicalIndex, WidthRole).isValid()) return;
if(noStretch || event->size().width() == event->oldSize().width()) return; if(adjSections(logicalIndex, newSize)) isSectionResized = true;
resizeSec(); }
bool TreeWidget::adjSections(int index, int size) {
auto item = headerItem();
int remain = header()->width() - size, stretchWidth = 0, width;
for(int cc=0; cc<columnCount(); cc++) if(cc!=index && ! header()->isSectionHidden(cc)) {
width = item->data(cc, WidthRole)|-1;
if(width > -1) {
if(width==0) item->setData(cc, WidthRole, width = header()->sectionSize(cc));
stretchWidth += width;
} else remain -= header()->sectionSize(cc);
}
if(remain<=0 || stretchWidth==0) return false;
auto min = header()->minimumSectionSize();
blocked = true;
for(int cc=0; cc<columnCount(); cc++) if(cc!=index && ! header()->isSectionHidden(cc) && (width = item->data(cc, WidthRole)|-1) > -1) header()->resizeSection(cc, qMax(min, width * remain / stretchWidth));
blocked = false;
return true;
} }
void Table::resizeSec() { class TreeItemMarginStyle : public QProxyStyle {
auto header = horizontalHeader(); public:
int colCnt = columnCount(), remainWidth = header->width(), stretchWidth = 0, secWidth; using QProxyStyle::QProxyStyle;
TreeItemMarginStyle(QWidget *wgt) : QProxyStyle(wgt->style()), _wgt(wgt) {}
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override {
auto res = QProxyStyle::subElementRect(element, option, widget);
auto width = res.width();
if(width && option && option->type==QStyleOption::SO_ViewItem && widget==_wgt) {
if(element==SE_ItemViewItemText) {
auto index = ((QStyleOptionViewItem*)option)->index;
auto add = ((TreeWidget*)widget)->headerItem()->data(index.column(), MarginRole).toInt();
if(add) {
auto align = ((TreeWidget*)widget)->item(index.row())->textAlignment(index.column());
if(align & Qt::AlignRight) res.setWidth(width < add ? 0 : width - add);
else if((align & Qt::AlignHCenter)==0) {
if(((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator) add += add>>1;
res.setLeft(res.x() + add);
if(width < add) res.setWidth(0);
}
}
} else if(((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator) {
auto add = ((TreeWidget*)widget)->headerItem()->data(((QStyleOptionViewItem*)option)->index.column(), MarginRole).toInt();
if(add) {
add += add>>1;
res.setLeft(res.x() + add);
if(width < add) res.setWidth(0);
}
}
}
return res;
}
int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override {
auto res = QProxyStyle::pixelMetric(metric, option, widget);
if(metric==PM_FocusFrameHMargin && option && option->type==QStyleOption::SO_ViewItem && ((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator && widget==_wgt) res += ((TreeWidget*)widget)->headerItem()->data(((QStyleOptionViewItem*)option)->index.column(), MarginRole).toInt();
return res;
}
QWidget *_wgt = 0;
};
ColItem &ColItem::margin(int margin) {
item->setData(i, MarginRole, margin);
auto tree = (TreeWidget*) item->treeWidget();
if(tree->noMargin) {
tree->noMargin = false;
tree->setStyle(new TreeItemMarginStyle(tree));
}
return *this;
}
TableWidget::TableWidget(std::initializer_list<ColAttr> colAttrs, int rows, QWidget *parent) : QTableWidget{rows, (int)colAttrs.size(), parent} {
int i = 0;
for(auto attr = colAttrs.begin(); attr < colAttrs.end(); ++attr) {
auto item = horizontalHeaderItem(i);
if(item==0) setHorizontalHeaderItem(i, item = new QTableWidgetItem);
item->setText(attr->text);
item->setData(FieldRole, attr->field);
if(attr->width > 0) horizontalHeader()->resizeSection(i, attr->width);
if(attr->resizeMode != QHeaderView::Interactive) {
if(attr->resizeMode==QHeaderView::Stretch && attr->width > 0) {
item->setData(WidthRole, attr->width);
if(noStretch) {
noStretch = false;
connect(horizontalHeader(), &QHeaderView::sectionResized, this, &TableWidget::onSectionResized);
horizontalHeader()->installEventFilter(this);
}
} else horizontalHeader()->setSectionResizeMode(i, attr->resizeMode);
}
fdmap.emplace(attr->field, i++);
}
}
bool TableWidget::eventFilter(QObject *watched, QEvent *event) {
if(watched==horizontalHeader()) {
if(event->type()==QEvent::Resize) {
auto eve = (QResizeEvent *) event;
if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0);
} else if(isSectionResized && event->type()==QEvent::Leave) {
isSectionResized = false;
QTableWidgetItem *item;
for(int cc=0; cc<columnCount(); cc++) if((item = horizontalHeaderItem(cc)) && item->data(WidthRole).isValid()) item->setData(WidthRole, horizontalHeader()->sectionSize(cc));
}
return true;
}
return QTableWidget::eventFilter(watched, event);
}
void TableWidget::onSectionResized(int logicalIndex, int oldSize, int newSize) {
if(blocked || newSize==0 || oldSize==0) return;
if(! horizontalHeaderItem(logicalIndex)->data(WidthRole).isValid()) return;
if(adjSections(logicalIndex, newSize)) isSectionResized = true;
}
bool TableWidget::adjSections(int index, int size) {
QTableWidgetItem *item; QTableWidgetItem *item;
for(int cc=0; cc<colCnt; cc++) if((item = horizontalHeaderItem(cc))) { int remain = horizontalHeader()->width() - size, stretchWidth = 0, width;
if((secWidth = item->data(0x99).toInt()) > 0) stretchWidth += secWidth; for(int cc=0; cc<columnCount(); cc++) if(cc!=index && ! horizontalHeader()->isSectionHidden(cc) && (item = horizontalHeaderItem(cc))) {
else remainWidth -= header->sectionSize(cc); width = item->data(WidthRole)|-1;
if(width > -1) {
if(width==0) item->setData(WidthRole, width = horizontalHeader()->sectionSize(cc));
stretchWidth += width;
} else remain -= horizontalHeader()->sectionSize(cc);
} }
if(remainWidth<=0 || stretchWidth==0) return; if(remain<=0 || stretchWidth==0) return false;
for(int cc=0; cc<colCnt; cc++) if((item = horizontalHeaderItem(cc)) && (secWidth = item->data(0x99).toInt()) > 0) header->resizeSection(cc, secWidth * remainWidth / stretchWidth); auto min = horizontalHeader()->minimumSectionSize();
} blocked = true;
for(int cc=0; cc<columnCount(); cc++) if(cc!=index && ! horizontalHeader()->isSectionHidden(cc) && (item = horizontalHeaderItem(cc)) && (width = item->data(WidthRole)|-1) > -1) horizontalHeader()->resizeSection(cc, qMax(min, width * remain / stretchWidth));
void Table::updateGeometries() { blocked = false;
QTableWidget::updateGeometries(); return true;
emit updGeos();
} }

View File

@ -2,6 +2,8 @@
#define QGUI_H #define QGUI_H
#include <QComboBox> #include <QComboBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QHeaderView> #include <QHeaderView>
#include <QLabel> #include <QLabel>
#include <QListWidget> #include <QListWidget>
@ -9,6 +11,7 @@
#include <QStackedLayout> #include <QStackedLayout>
#include <QTableWidget> #include <QTableWidget>
#include <QTextEdit> #include <QTextEdit>
#include <QTreeWidget>
#define MainMust \ #define MainMust \
#if(QT_VERSION_MAJOR > 5) \ #if(QT_VERSION_MAJOR > 5) \
@ -19,8 +22,11 @@
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);\ QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);\
#endif #endif
extern const Qt::Alignment AlignRight;
extern const int AlignRight; inline int operator|(const QVariant &value, int def) {
return value.isValid() ? value.toInt() : def;
}
inline QWidget *parentWgt(QObject *obj) { inline QWidget *parentWgt(QObject *obj) {
while(obj && ! obj->isWidgetType()) obj = obj->parent(); while(obj && ! obj->isWidgetType()) obj = obj->parent();
@ -34,11 +40,16 @@ inline QWidget *parentWin(QObject *obj) {
return (QWidget*) obj; return (QWidget*) obj;
} }
inline int setCurrentData(QComboBox *combo, const QVariant &data) { inline int SetCurData(QComboBox *combo, const QVariant &data) {
auto idx = combo->findData(data); auto idx = combo->findData(data);
if(idx>-1) combo->setCurrentIndex(idx); if(idx>-1) combo->setCurrentIndex(idx);
return idx; return idx;
} }
inline int SetCurText(QComboBox *combo, const QString& text) {
auto idx = combo->findText(text);
if(idx>-1) combo->setCurrentIndex(idx);
return idx;
}
inline void gFont(QWidget *wgt, int size, bool bold = false, bool italic = false) { inline void gFont(QWidget *wgt, int size, bool bold = false, bool italic = false) {
auto ft = wgt->font(); auto ft = wgt->font();
ft.setPixelSize(size); ft.setPixelSize(size);
@ -46,7 +57,7 @@ inline void gFont(QWidget *wgt, int size, bool bold = false, bool italic = false
if(italic) ft.setItalic(true); if(italic) ft.setItalic(true);
wgt->setFont(ft); wgt->setFont(ft);
} }
inline void gFont(QWidget *wgt, const QString &family, int size = 0, bool bold = false, bool italic = false) { inline void gFont(QWidget *wgt, const QString& family, int size = 0, bool bold = false, bool italic = false) {
auto ft = wgt->font(); auto ft = wgt->font();
ft.setFamily(family); ft.setFamily(family);
if(size) ft.setPixelSize(size); if(size) ft.setPixelSize(size);
@ -54,14 +65,14 @@ inline void gFont(QWidget *wgt, const QString &family, int size = 0, bool bold =
if(italic) ft.setItalic(true); if(italic) ft.setItalic(true);
wgt->setFont(ft); wgt->setFont(ft);
} }
inline QFont qfont(const QString &family, int pixelSize, bool bold = false, bool italic = false) { inline QFont qfont(const QString& family, int pixelSize, bool bold = false, bool italic = false) {
QFont ft(family); QFont ft(family);
ft.setPixelSize(pixelSize); ft.setPixelSize(pixelSize);
if(bold) ft.setBold(true); if(bold) ft.setBold(true);
if(italic) ft.setItalic(true); if(italic) ft.setItalic(true);
return ft; return ft;
} }
inline void gAppendText(QTextEdit *wgt, const QString &text, const QColor &color) { inline void gAppendText(QTextEdit *wgt, const QString& text, const QColor &color) {
auto c0 = wgt->textColor(); auto c0 = wgt->textColor();
wgt->setTextColor(color); wgt->setTextColor(color);
wgt->append(text); wgt->append(text);
@ -70,39 +81,55 @@ inline void gAppendText(QTextEdit *wgt, const QString &text, const QColor &color
class VBox : public QBoxLayout { class VBox : public QBoxLayout {
public: public:
inline VBox(QWidget *parent=nullptr) : QBoxLayout(TopToBottom, parent) {} VBox(QWidget *parent=nullptr) : QBoxLayout(TopToBottom, parent) {}
inline VBox(QBoxLayout *parent) : QBoxLayout(TopToBottom) { VBox(QBoxLayout *parent) : QBoxLayout(TopToBottom) {
parent->addLayout(this); parent->addLayout(this);
}; };
inline VBox(QStackedLayout *stack) : QBoxLayout(TopToBottom, new QWidget) { VBox(QStackedLayout *stack) : QBoxLayout(TopToBottom, new QWidget) {
stack->addWidget(parentWidget()); stack->addWidget(parentWidget());
setContentsMargins(0,0,0,0); setContentsMargins(0,0,0,0);
}; };
inline VBox(QSplitter *splitter) : QBoxLayout(TopToBottom, new QWidget) { VBox(QSplitter *splitter) : QBoxLayout(TopToBottom, new QWidget) {
splitter->addWidget(parentWidget()); splitter->addWidget(parentWidget());
setContentsMargins(0,0,0,0); setContentsMargins(0,0,0,0);
}; };
inline QLabel *addLabel(const QString &text) { QLabel *addLabel() {
auto lb = new QLabel;
addWidget(lb);
return lb;
}
QLabel *addLabel(const QString& text) {
auto lb = new QLabel(text); auto lb = new QLabel(text);
addWidget(lb); addWidget(lb);
return lb; return lb;
} }
QDialogButtonBox *addBtnBox(QDialog *dlg = 0) {
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
if(dlg) connect(btnBox, &QDialogButtonBox::rejected, dlg, &QDialog::reject);
addWidget(btnBox);
return btnBox;
}
}; };
class HBox : public QBoxLayout { class HBox : public QBoxLayout {
public: public:
inline HBox(QWidget *parent=nullptr) : QBoxLayout(LeftToRight, parent) {} HBox(QWidget *parent=nullptr) : QBoxLayout(LeftToRight, parent) {}
inline HBox(QBoxLayout *parent) : QBoxLayout(LeftToRight) { HBox(QBoxLayout *parent) : QBoxLayout(LeftToRight) {
parent->addLayout(this); parent->addLayout(this);
}; };
inline HBox(QStackedLayout *stack) : QBoxLayout(LeftToRight, new QWidget) { HBox(QStackedLayout *stack) : QBoxLayout(LeftToRight, new QWidget) {
stack->addWidget(parentWidget()); stack->addWidget(parentWidget());
setContentsMargins(0,0,0,0); setContentsMargins(0,0,0,0);
}; };
inline HBox(QSplitter *splitter) : QBoxLayout(LeftToRight, new QWidget) { HBox(QSplitter *splitter) : QBoxLayout(LeftToRight, new QWidget) {
splitter->addWidget(parentWidget()); splitter->addWidget(parentWidget());
setContentsMargins(0,0,0,0); setContentsMargins(0,0,0,0);
}; };
inline QLabel *addLabel(const QString &text) { QLabel *addLabel() {
auto lb = new QLabel;
addWidget(lb);
return lb;
}
QLabel *addLabel(const QString& text) {
auto lb = new QLabel(text); auto lb = new QLabel(text);
addWidget(lb); addWidget(lb);
return lb; return lb;
@ -111,16 +138,16 @@ public:
class Grid : public QGridLayout { class Grid : public QGridLayout {
public: public:
using QGridLayout::QGridLayout; using QGridLayout::QGridLayout;
inline Grid(QBoxLayout *parent) { Grid(QBoxLayout *parent) {
parent->addLayout(this); parent->addLayout(this);
}; };
inline Grid(QStackedLayout *stack) : QGridLayout(new QWidget) { Grid(QStackedLayout *stack) : QGridLayout(new QWidget) {
stack->addWidget(parentWidget()); stack->addWidget(parentWidget());
}; };
inline Grid(QSplitter *splitter) : QGridLayout(new QWidget) { Grid(QSplitter *splitter) : QGridLayout(new QWidget) {
splitter->addWidget(parentWidget()); splitter->addWidget(parentWidget());
}; };
inline QLabel *addLabel(const QString &text) { QLabel *addLabel(const QString& text) {
auto lb = new QLabel(text); auto lb = new QLabel(text);
addWidget(lb); addWidget(lb);
return lb; return lb;
@ -132,7 +159,7 @@ public:
using QListWidget::QListWidget; using QListWidget::QListWidget;
using QListWidget::addItem; using QListWidget::addItem;
inline auto addItem(const QString &text, const QVariant &value) { auto addItem(const QString& text, const QVariant &value) {
auto item = new QListWidgetItem(text); auto item = new QListWidgetItem(text);
item->setData(Qt::UserRole, value); item->setData(Qt::UserRole, value);
insertItem(count(), item); insertItem(count(), item);
@ -141,172 +168,396 @@ public:
}; };
struct ColAttr { struct ColAttr {
ColAttr(QString field, QString text, int width=0, QHeaderView::ResizeMode resizeMode = QHeaderView::Interactive) : field(field), text(text), width(width), resizeMode(resizeMode) {} ColAttr(const QString& field, const QString& text, int width=0, QHeaderView::ResizeMode resizeMode = QHeaderView::Interactive) : field(field), text(text), width(width), resizeMode(resizeMode) {}
ColAttr(QString field, QString text, QHeaderView::ResizeMode resizeMode) : field(field), text(text), resizeMode(resizeMode) {} ColAttr(const QString& field, const QString& text, QHeaderView::ResizeMode resizeMode) : field(field), text(text), resizeMode(resizeMode) {}
QString field; QString field;
QString text; QString text;
int width{0}; int width = 0;
QHeaderView::ResizeMode resizeMode; QHeaderView::ResizeMode resizeMode;
}; };
class Table : public QTableWidget { enum ItemDataRole {
MarginRole = 0xfc,
AlignRole,
FieldRole,
WidthRole
};
struct ColItem {
QTreeWidgetItem *item;
int i;
auto &align(int align) {
item->setData(i, AlignRole, align);
return *this;
}
auto &alignC() {
return align(Qt::AlignCenter);
}
auto &alignR() {
return align(Qt::AlignVCenter | Qt::AlignRight);
}
ColItem &margin(int margin);
};
class TreeWidgetItem;
class TreeWidget : public QTreeWidget {
friend ColItem;
Q_OBJECT
public:
using QTreeWidget::QTreeWidget;
ColItem addCol(const QString& field, const QString& text, int width = 0, QHeaderView::ResizeMode resizeMode = QHeaderView::Interactive);
ColItem addCol(const QString& field, const QString& text, QHeaderView::ResizeMode resizeMode) {
return addCol(field, text, 0, resizeMode);
}
auto setDefs() {
if(! hasRowNum) setIndentation(0);
setAlternatingRowColors(true);
header()->setStretchLastSection(false);
return this;
}
auto setHeaderAlignC() {
auto item = headerItem();
for(int cc=0; cc<columnCount(); ++cc) item->setTextAlignment(cc, Qt::AlignCenter);
}
auto setColFit() {
header()->setSectionResizeMode(QHeaderView::ResizeToContents);
return this;
}
auto setColWidth(int value, QHeaderView::ResizeMode mode = QHeaderView::Interactive) {
header()->setDefaultSectionSize(value);
if(mode!=QHeaderView::Interactive) header()->setSectionResizeMode(mode);
return this;
}
auto setHeaderText(const QString& column, const QString& text) {
headerItem()->setText(fdmap.at(column), text);
return this;
}
using QTreeWidget::showColumn;
void showColumn(const QString& column) {
showColumn(fdmap.at(column));
}
using QTreeWidget::hideColumn;
void hideColumn(const QString& column) {
hideColumn(fdmap.at(column));
}
auto item(int idx) const {
return (TreeWidgetItem*) topLevelItem(idx);
}
auto selectedItem() const {
auto is = selectedItems();
return is.isEmpty() ? 0 : (TreeWidgetItem*) is.at(0);
}
auto curItem() const {
return (TreeWidgetItem*) currentItem();
}
QString field(int column) const {
return headerItem()->data(column, FieldRole).toString();
}
QString sortField() const {
return field(sortColumn());
}
using QTreeWidget::sortItems;
void sortItems(const QString& column, Qt::SortOrder order = Qt::AscendingOrder) {
sortItems(fdmap.at(column), order);
}
std::unordered_map<QString, int> fdmap;
int minRowHeight = 0;
char hasGrid = 1;
bool hasRowNum = false;
int sizeHintForColumn(int column) const override {
return QTreeWidget::sizeHintForColumn(column);
}
signals:
void updGeos();
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
void updateGeometries() override {
QTreeWidget::updateGeometries();
emit updGeos();
}
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;
bool blocked = false;
};
inline int operator*(const QString& key, QTreeView &table) {
if((size_t)&table==0) return 0;
return ((TreeWidget&)table).fdmap.at(key);
}
inline int operator*(const char *key, QTreeView &table) {
if((size_t)&table==0) return 0;
return ((TreeWidget&)table).fdmap.at(key);
}
class TreeWidgetItem : public QTreeWidgetItem {
public:
using QTreeWidgetItem::QTreeWidgetItem;
using QTreeWidgetItem::checkState;
auto checkState(const QString& column) const {
return checkState(column**treeWidget());
}
using QTreeWidgetItem::setCheckState;
auto setCheckState(const QString& column, Qt::CheckState state) {
setCheckState(column**treeWidget(), state);
return this;
}
using QTreeWidgetItem::text;
auto text(const QString& column) const {
return text(column**treeWidget());
}
using QTreeWidgetItem::setText;
auto setText(const QString& column, const QString& text) {
setText(column**treeWidget(), text);
return this;
}
auto setText(const QString& column, const QString& text, const QVariant &value) {
auto idx = column**treeWidget();
setText(idx, text);
setData(idx, Qt::UserRole, value);
return this;
}
auto setText(const QString& column, const QString& text, int alignment) {
auto idx = column**treeWidget();
setText(idx, text);
setTextAlignment(idx, (Qt::Alignment)alignment);
return this;
}
using QTreeWidgetItem::background;
auto background(const QString& column) const {
return background(column**treeWidget());
}
using QTreeWidgetItem::setBackground;
auto setBackground(const QString& column, const QBrush &brush) {
setBackground(column**treeWidget(), brush);
return this;
}
using QTreeWidgetItem::foreground;
auto foreground(const QString& column) const {
return foreground(column**treeWidget());
}
using QTreeWidgetItem::setForeground;
auto setForeground(const QString& column, const QBrush &brush) {
setForeground(column**treeWidget(), brush);
return this;
}
using QTreeWidgetItem::data;
auto data(int col) const {
return data(col, Qt::UserRole);
}
auto data(const QString& column, int role = Qt::UserRole) const {
return data(column**treeWidget(), role);
}
using QTreeWidgetItem::setData;
auto setData(int col, const QVariant &value) {
setData(col, Qt::UserRole, value);
return this;
}
auto setData(const QString& column, const QVariant &value) {
setData(column**treeWidget(), Qt::UserRole, value);
return this;
}
auto setData(const QString& column, int role, const QVariant &value) {
setData(column**treeWidget(), role, value);
return this;
}
auto cellWidget(int column) {
return treeWidget()->itemWidget(this, column);
}
auto cellWidget(const QString& column) {
return treeWidget()->itemWidget(this, column**treeWidget());
}
void setCellWidget(int column, QWidget *widget) {
treeWidget()->setItemWidget(this, column, widget);
}
void setCellWidget(const QString& column, QWidget *widget) {
treeWidget()->setItemWidget(this, column**treeWidget(), widget);
}
};
class TableWidget : public QTableWidget {
Q_OBJECT Q_OBJECT
public: public:
using QTableWidget::QTableWidget; using QTableWidget::QTableWidget;
Table() {} TableWidget() {}
Table(std::initializer_list<ColAttr> colAttrs, int rows = 0, QWidget *parent = 0); TableWidget(std::initializer_list<ColAttr> colAttrs, int rows = 0, QWidget *parent = 0);
inline auto setDefs() { auto setDefs() {
setSelectionBehavior(QTableWidget::SelectRows); setSelectionBehavior(QTableWidget::SelectRows);
setEditTriggers(QAbstractItemView::NoEditTriggers); setEditTriggers(QAbstractItemView::NoEditTriggers);
setAlternatingRowColors(true); setAlternatingRowColors(true);
return this; return this;
} }
inline auto setColStretch() { auto setColStretch() {
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
return this; return this;
} }
inline auto setRowStretch() { auto setRowStretch() {
verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
return this; return this;
} }
inline auto setColFit() { auto setColFit() {
horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
return this; return this;
} }
inline auto setRowFit() { auto setRowFit() {
verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
return this; return this;
} }
inline auto setColWidth(int value, QHeaderView::ResizeMode mode = QHeaderView::Interactive) {
auto header = horizontalHeader(); auto setColWidth(int value) {
header->setDefaultSectionSize(value); if(horizontalHeader()->minimumSectionSize() > value) horizontalHeader()->setMinimumSectionSize(value);
if(mode!=QHeaderView::Interactive) header->setSectionResizeMode(mode); horizontalHeader()->setDefaultSectionSize(value);
return this; return this;
} }
inline auto setRowHeight(int value, QHeaderView::ResizeMode mode = QHeaderView::Interactive) { auto setColResize(QHeaderView::ResizeMode mode) {
auto header = verticalHeader(); horizontalHeader()->setSectionResizeMode(mode);
header->setDefaultSectionSize(value); return this;
if(mode!=QHeaderView::Interactive) header->setSectionResizeMode(mode); }
auto setRowHeight(int value) {
if(verticalHeader()->minimumSectionSize() > value) verticalHeader()->setMinimumSectionSize(value);
verticalHeader()->setDefaultSectionSize(value);
return this;
}
auto setRowResize(QHeaderView::ResizeMode mode) {
verticalHeader()->setSectionResizeMode(mode);
return this; return this;
} }
inline auto setHeaderText(int col, QString text) { auto setHeaderText(int col, const QString& text) {
auto item = horizontalHeaderItem(col); auto item = horizontalHeaderItem(col);
if(item==0) setHorizontalHeaderItem(col, item = new QTableWidgetItem()); if(item==0) setHorizontalHeaderItem(col, item = new QTableWidgetItem());
item->setText(text); item->setText(text);
return item; return item;
} }
inline auto setHeaderText(QString column, QString text) { auto setHeaderText(const QString& column, const QString& text) {
auto col = mFieldMap[column]; return setHeaderText(fdmap.at(column), text);
return setHeaderText(col, text);
} }
inline auto setVHeaderText(int row, QString text) { auto setVHeaderText(int row, const QString& text) {
auto item = verticalHeaderItem(row); auto item = verticalHeaderItem(row);
if(item==0) setVerticalHeaderItem(row, item = new QTableWidgetItem()); if(item==0) setVerticalHeaderItem(row, item = new QTableWidgetItem());
item->setText(text); item->setText(text);
return item; return item;
} }
inline auto appendRow() { auto appendRow() {
auto value = rowCount(); auto value = rowCount();
setRowCount(value + 1); setRowCount(value + 1);
return value; return value;
} }
using QTableWidget::item; using QTableWidget::item;
inline auto item(int row, QString column) { auto item(int row, const QString& column) {
auto col = mFieldMap[column]; return item(row, fdmap.at(column));
return item(row, col);
} }
inline auto itemValid(int row, int col) { auto itemValid(int row, int col) {
auto anitem = item(row, col); auto itm = item(row, col);
if(anitem==0) setItem(row, col, anitem = new QTableWidgetItem); if(itm==0) setItem(row, col, itm = new QTableWidgetItem);
return anitem; return itm;
} }
inline auto itemValid(int row, QString column) { auto itemValid(int row, const QString& column) {
auto col = mFieldMap[column]; return itemValid(row, fdmap.at(column));
return itemValid(row, col);
} }
using QTableWidget::setItem; using QTableWidget::setItem;
inline void setItem(int row, QString column, QTableWidgetItem *item) { void setItem(int row, const QString& column, QTableWidgetItem *item) {
auto col = mFieldMap[column]; setItem(row, fdmap.at(column), item);
setItem(row, col, item);
} }
inline auto text(int row, int col) { auto text(int row, int col) {
auto itm = item(row, col); auto itm = item(row, col);
if(itm==0) return QString(); if(itm==0) return QString();
return itm->text(); return itm->text();
} }
inline auto text(int row, QString column) { auto text(int row, const QString& column) {
auto col = mFieldMap[column]; return text(row, fdmap.at(column));
return text(row, col);
} }
inline auto setText(int row, int col, const QString &text) { auto setText(int row, int col, const QString& text) {
auto itm = item(row, col); auto itm = item(row, col);
if(itm) itm->setText(text); if(itm) itm->setText(text);
else setItem(row, col, itm = new QTableWidgetItem(text)); else setItem(row, col, itm = new QTableWidgetItem(text));
return itm; return itm;
} }
inline auto setText(int row, QString column, const QString &text) { auto setText(int row, const QString& column, const QString& text) {
auto col = mFieldMap[column]; return setText(row, fdmap.at(column), text);
return setText(row, col, text); }
auto setText(int row, int col, const QString& text, const QVariant &value) {
auto itm = item(row, col);
if(itm) itm->setText(text);
else setItem(row, col, itm = new QTableWidgetItem(text));
itm->setData(Qt::UserRole, value);
return itm;
}
auto setText(int row, const QString& column, const QString& text, const QVariant &value) {
return setText(row, fdmap.at(column), text, value);
} }
inline auto data(int row, int col) { auto data(int row, int col) {
auto itm = item(row, col); auto itm = item(row, col);
if(itm==0) return QVariant(); if(itm==0) return QVariant();
return itm->data(Qt::UserRole); return itm->data(Qt::UserRole);
} }
inline auto data(int row, QString column) { auto data(int row, const QString& column) {
auto col = mFieldMap[column]; return data(row, fdmap.at(column));
return data(row, col);
} }
inline auto setData(int row, int col, const QVariant &value) { auto setData(int row, int col, const QVariant &value) {
auto itm = item(row, col); auto itm = item(row, col);
if(itm==0) setItem(row, col, itm = new QTableWidgetItem); if(itm==0) setItem(row, col, itm = new QTableWidgetItem);
itm->setData(Qt::UserRole, value); itm->setData(Qt::UserRole, value);
return itm; return itm;
} }
inline auto setData(int row, QString column, const QVariant &value) { auto setData(int row, const QString& column, const QVariant &value) {
auto col = mFieldMap[column]; return setData(row, fdmap.at(column), value);
return setData(row, col, value);
} }
using QTableWidget::cellWidget; using QTableWidget::cellWidget;
inline auto cellWidget(int row, QString column) { auto cellWidget(int row, const QString& column) {
auto col = mFieldMap[column]; return cellWidget(row, fdmap.at(column));
return cellWidget(row, col);
} }
using QTableWidget::setCellWidget; using QTableWidget::setCellWidget;
inline void setCellWidget(int row, QString column, QWidget *widget) { void setCellWidget(int row, const QString& column, QWidget *widget) {
auto col = mFieldMap[column]; setCellWidget(row, fdmap.at(column), widget);
setCellWidget(row, col, widget);
} }
std::map<QString, int> mFieldMap; using QTableWidget::sortItems;
void sortItems(const QString& column, Qt::SortOrder order) {
sortItems(fdmap.at(column), order);
}
std::unordered_map<QString, int> fdmap;
public Q_SLOTS: public Q_SLOTS:
inline void clearRows() {setRowCount(0);} void clearRows() {setRowCount(0);}
signals: signals:
void updGeos(); void updGeos();
protected: protected:
void resizeEvent(QResizeEvent *event) override; bool eventFilter(QObject *watched, QEvent *event) override;
void updateGeometries() override; void updateGeometries() override {
void resizeSec(); QTableWidget::updateGeometries();
bool noStretch{true}; emit updGeos();
}; };
void onSectionResized(int logicalIndex, int oldSize, int newSize);
class ResizeEmitedWgt : public QWidget { bool adjSections(int index, int size);
Q_OBJECT bool noStretch = true;
public: bool isSectionResized = false;
using QWidget::QWidget; bool blocked = false;
protected:
void resizeEvent(QResizeEvent *) override {emit resized();}
signals:
void resized();
}; };
@ -317,43 +568,43 @@ public:
Wrp(T *obj = nullptr){ Wrp(T *obj = nullptr){
this->obj = obj; this->obj = obj;
}; };
inline Wrp& operator()(T *obj){ Wrp& operator()(T *obj){
this->obj = obj; this->obj = obj;
return *this; return *this;
} }
inline Wrp& operator()(T *obj, QLayout *layout){ Wrp& operator()(T *obj, QLayout *layout){
this->obj = obj; this->obj = obj;
layout->addWidget(obj); layout->addWidget(obj);
return *this; return *this;
} }
inline Wrp& addTo(QLayout *layout){ Wrp& addTo(QLayout *layout){
layout->addWidget(obj); layout->addWidget(obj);
return *this; return *this;
} }
inline Wrp& margin(int a){ Wrp& margin(int a){
obj->setMargin(a); obj->setMargin(a);
return *this; return *this;
} }
inline Wrp& font(const QFont &font){ Wrp& font(const QFont &font){
obj->setFont(font); obj->setFont(font);
return *this; return *this;
} }
inline Wrp& font(int size){ Wrp& font(int size){
auto font = obj->font(); auto font = obj->font();
font.setPixelSize(size); font.setPixelSize(size);
obj->setFont(font); obj->setFont(font);
return *this; return *this;
} }
inline Wrp& width(int w){ Wrp& width(int w){
obj->setFixedWidth(w); obj->setFixedWidth(w);
return *this; return *this;
} }
inline Wrp& height(int h){ Wrp& height(int h){
obj->setFixedHeight(h); obj->setFixedHeight(h);
return *this; return *this;
} }
inline Wrp& padding(int wAdd, int hAdd, int minW = 32, int minH = 16){ Wrp& padding(int wAdd, int hAdd, int minW = 32, int minH = 16){
wAdd+=8; wAdd+=8;
hAdd+=8; hAdd+=8;
QSize size = obj->fontMetrics().size(Qt::TextShowMnemonic, obj->text()); QSize size = obj->fontMetrics().size(Qt::TextShowMnemonic, obj->text());
@ -367,11 +618,11 @@ public:
return *this; return *this;
} }
inline Wrp& alignC(){ Wrp& alignC(){
obj->setAlignment(Qt::AlignCenter); obj->setAlignment(Qt::AlignCenter);
return *this; return *this;
} }
inline Wrp& alignR(){ Wrp& alignR(){
obj->setAlignment(Qt::AlignRight); obj->setAlignment(Qt::AlignRight);
return *this; return *this;
} }

View File

@ -1,4 +1,12 @@
#include "qjson.h" #include "qjson.h"
#include "qdebug.h"
QDebug operator<<(QDebug debug, const JValue &val) {
auto old = debug.autoInsertSpaces();
debug.noquote().nospace() << JToBytes(val, "\t");
debug.setAutoInsertSpaces(old);
return debug;
}
inline QChar readOne(QTextStream &in) { inline QChar readOne(QTextStream &in) {
QChar ch; QChar ch;

View File

@ -1,7 +1,7 @@
#ifndef QJSON_H #ifndef QJSON_H
#define QJSON_H #define QJSON_H
#include "cu.h" #include "cpp.h"
#include "QtCore/qhashfunctions.h" #include "QtCore/qhashfunctions.h"
#include <QTextStream> #include <QTextStream>
@ -11,99 +11,154 @@ using JArray = Vector<JValue>;
class JValue { class JValue {
public: public:
int data[2]{0}; long long data = 0;
enum Type { enum Type {
Null, Bool, Int, Long, Double, Obj, Array, Str Null, Long, Ulong, Double, Bool, Obj, Array, Str
}; };
Type type{Null}; Type type = Null;
JValue(Type = Null) {} JValue(Type = Null) {}
JValue(bool b) : type(Bool) {data[0] = b;} JValue(bool b) : type(Bool) {data = b;}
JValue(int n) : type(Int) {data[0] = n;} JValue(int n) : type(Long) {data = n;}
JValue(qint64 n) : type(Long) {*(qint64*) data = n;} JValue(qint64 n) : type(Long) {data = n;}
JValue(double d) : type(Double) {*(double*) data = d;} JValue(quint64 n) : type(Ulong) {*(quint64*) &data = n;}
JValue(const JObj &o) : type(Obj) {new (data) JObj(o);} JValue(double d) : type(Double) {*(double*) &data = d;}
JValue(const JArray &a) : type(Array) {new (data) JArray(a);} JValue(const JObj &o) : type(Obj) {new (&data) JObj(o);}
JValue(const QString &s) : type(Str) {*(SharedData<QString>**) data = new SharedData<QString>{s, 1};} JValue(const JArray &a) : type(Array) {new (&data) JArray(a);}
JValue(JObj &&o) : type(Obj) {new (&data) JObj(std::move(o));}
JValue(JArray &&a) : type(Array) {new (&data) JArray(std::move(a));}
JValue(const QString &s) : type(Str) {*(SharedData<QString>**) &data = new SharedData<QString>{1, s};}
JValue(QString &&s) : type(Str) {*(SharedData<QString>**) &data = new SharedData<QString>{1, std::move(s)};}
JValue(const char *s) : JValue(QString::fromUtf8(s)) {} 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<QString>**) data)->cnt++;
}
}
~JValue() { ~JValue() {
if(type < Obj) return; if(type < Obj) return;
else if(type==Obj) ((JObj*) data)->~JObj(); else if(type==Obj) ((JObj*) &data)->~JObj();
else if(type==Array) ((JArray*) data)->~JArray(); else if(type==Array) ((JArray*) &data)->~JArray();
else if(type==Str) { else if(type==Str) {
auto ptr = *(SharedData<QString>**) data; auto ptr = *(SharedData<QString>**) &data;
if(ptr->cnt > 1) ptr->cnt--; if(ptr->cnt > 1) ptr->cnt--;
else delete ptr; else delete ptr;
} }
} }
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 = other.data;
if(type==Str) (*(SharedData<QString>**) &data)->cnt++;
}
}
JValue &operator=(const JValue &other) { JValue &operator=(const JValue &other) {
this->~JValue(); this->~JValue();
new (this) JValue(other); new (this) JValue(other);
return *this; return *this;
} }
JValue(JValue &&other) noexcept : data(other.data), type(other.type) {
other.data = 0;
other.type = Null;
}
JValue &operator=(JValue &&other) noexcept {
std::swap(data, other.data);
std::swap(type, other.type);
return *this;
}
bool isNull() const {return type==Null;} bool isNull() const {return type==Null;}
bool isStr() const {return type==Str;}
bool isObj() const {return type==Obj;} bool isObj() const {return type==Obj;}
bool isArray() const {return type==Array;} bool isArray() const {return type==Array;}
bool toBool(bool def = false) const { bool toBool(bool def = false) const {
return type==Null ? def : data[0] || data[1]; return type==Null ? def : data;
} }
int toInt(int def = 0) const { int toInt(int def = 0) const {
if(type==Bool || type==Int) return data[0]; return toLong(def);
if(type==Long) return *(qint64*) data;
if(type==Double) return *(double*) data;
return def;
} }
qint64 toLong(qint64 def = 0) const { qint64 toLong(qint64 def = 0) const {
if(type==Bool || type==Int) return data[0]; if(type==Long || type==Bool) return data;
if(type==Long) return *(qint64*) data; if(type==Double) return *(double*) &data;
if(type==Double) return *(double*) data; if(type==Ulong) return *(quint64*) &data;
return def;
}
quint64 toULong(quint64 def = 0) const {
if(type==Ulong) return *(quint64*) &data;
if(type==Long || type==Bool) return data;
if(type==Double) return *(double*) &data;
return def; return def;
} }
double toDouble(double def = 0) const { double toDouble(double def = 0) const {
if(type==Bool || type==Int) return data[0]; if(type==Double) return *(double*) &data;
if(type==Long) return *(qint64*) data; if(type==Long || type==Bool) return data;
if(type==Double) return *(double*) data; if(type==Ulong) return *(quint64*) &data;
return def; return def;
} }
QString toStr(const QString &def = "") const { QString toStr(const QString &def = "") const {
if(type==Bool) return data[0] ? "true" : "false"; if(type==Str) return (*(SharedData<QString>**) &data)->data;
if(type==Int) return QString::number(data[0]); if(type==Long) return QString::number(data);
if(type==Long) return QString::number(*(qint64*) data); if(type==Double) return QString::number(*(double*) &data);
if(type==Double) return QString::number(*(double*) data); if(type==Bool) return data ? "true" : "false";
if(type==Str) return (*(SharedData<QString>**) data)->data; if(type==Ulong) return QString::number(*(quint64*) &data);
return def; return def;
} }
QString toString(const QString &def = "") const {
return toStr(def);
}
JObj toObj() const { JObj toObj() const {
if(type==Obj) return *(JObj*) data; if(type==Obj) return *(JObj*) &data;
return JObj(); return JObj();
} }
JArray toArray() const { JArray toArray() const {
if(type==Array) return *(JArray*) data; if(type==Array) return *(JArray*) &data;
return JArray(); return JArray();
} }
const JValue operator[](const QString &key) const { const JValue operator[](const QString &key) const {
return type==Obj ? (*(JObj*) data)[key] : JValue(); return type==Obj ? (*(const JObj*) &data)[key] : JValue();
} }
const JValue operator[](int i) const { const JValue operator[](int i) const {
return type==Array ? (*(JArray*) data)[i] : JValue(); return type==Array ? (*(const JArray*) &data)[i] : JValue();
}
JArray::iterator begin() const noexcept {
return type==Array ? ((const JArray*) &data)->begin() : JArray::iterator();
}
JArray::iterator end() const noexcept {
return type==Array ? ((const JArray*) &data)->end() : JArray::iterator();
}
size_t size() const noexcept {
if(type==Array) return ((const JArray*) &data)->size();
else if(type==Obj) return ((const JObj*) &data)->size();
return 0;
}
bool operator==(const JValue &other) const {
if(type==other.type) {
if(data==other.data) return true;
if(type==Null) return true;
if(type<=Double) return false;
if(type==Bool) return ((bool)data)==(bool)other.data;
if(type==Str) return (*(SharedData<QString>**) &data)->data==(*(SharedData<QString>**) &other.data)->data;
if(type==Obj) return *(JObj*) &data == *(JObj*) &other.data;
if(type==Array) return *(JArray*) &data == *(JArray*) &other.data;
} else {
if(type>Double || other.type>Double || type==Null || other.type==Null) return false;
if(type==Double || other.type==Double) return toDouble()==other.toDouble();
if(type==Long) return data==other.toLong();
else return toLong()==other.data;
}
return false;
}
bool operator!=(const JValue &other) const {
return ! (*this==other);
} }
private: private:
JValue(const void *) = delete; // avoid implicit conversions from char * to bool JValue(const void *) = delete; // avoid implicit conversions from char * to bool
}; };
QDebug operator<<(QDebug debug, const JValue &val);
class JParser { class JParser {
public: public:
JParser(QTextStream &in) : in(in) { JParser(QTextStream &in) : in(in) {
@ -160,7 +215,7 @@ public:
#endif #endif
} }
void write(const JValue &obj); void write(const JValue &value);
void writeStr(const QString &str); void writeStr(const QString &str);
void writeMap(const JObj &map); void writeMap(const JObj &map);
void writeList(const JArray &objs); void writeList(const JArray &objs);
@ -170,21 +225,21 @@ protected:
int cnt{0}; int cnt{0};
}; };
inline QString JToStr(const JValue &obj, QString indent = "") { inline QString JToStr(const JValue &value, QString indent = "") {
QString json; QString json;
QTextStream out(&json); QTextStream out(&json);
JOut(out, indent).write(obj); JOut(out, indent).write(value);
return json; return json;
} }
inline QByteArray JToBytes(const JValue &obj, QString indent = "") { inline QByteArray JToBytes(const JValue &value, QString indent = "") {
QByteArray json; QByteArray json;
QTextStream out(&json); QTextStream out(&json);
JOut(out, indent).write(obj); JOut(out, indent).write(value);
return json; return json;
} }
inline QTextStream::Status JWrite(const JValue &obj, QIODevice *device, QString indent = "") { inline QTextStream::Status JWrite(const JValue &value, QIODevice *device, QString indent = "") {
QTextStream out(device); QTextStream out(device);
JOut(out, indent).write(obj); JOut(out, indent).write(value);
return out.status(); return out.status();
} }

View File

@ -57,11 +57,13 @@ bool TcpSocket::waitForDisconnected(int msecs) {
return connAndExec(msecs, &loop); return connAndExec(msecs, &loop);
} }
bool TcpSocket::waitForBytesWritten(int msecs) { bool TcpSocket::waitForBytesWritten(int msecs) {
if(bytesToWrite() == 0) return true;
QEventLoop loop; QEventLoop loop;
connect(this, &QTcpSocket::bytesWritten, &loop, &QEventLoop::quit); connect(this, &QTcpSocket::bytesWritten, &loop, &QEventLoop::quit);
return connAndExec(msecs, &loop); return connAndExec(msecs, &loop);
} }
bool TcpSocket::waitForReadyRead(int msecs) { bool TcpSocket::waitForReadyRead(int msecs) {
if(bytesAvailable()) return true;
QEventLoop loop; QEventLoop loop;
connect(this, &QTcpSocket::readyRead, &loop, &QEventLoop::quit); connect(this, &QTcpSocket::readyRead, &loop, &QEventLoop::quit);
return connAndExec(msecs, &loop); return connAndExec(msecs, &loop);

View File

@ -1,6 +1,7 @@
#ifndef QNETWORK_H #ifndef QNETWORK_H
#define QNETWORK_H #define QNETWORK_H
#include "qjson.h"
#include <QNetworkReply> #include <QNetworkReply>
#include <QJsonDocument> #include <QJsonDocument>
#include <QEventLoop> #include <QEventLoop>
@ -65,6 +66,15 @@ public:
if(mAccess==0) mAccess = netAccess(); if(mAccess==0) mAccess = netAccess();
return mAccess->post(*this, data); return mAccess->post(*this, data);
} }
inline QNetworkReply *post(const char *data) {
if(mAccess==0) mAccess = netAccess();
return mAccess->post(*this, data);
}
inline QNetworkReply *post(const JValue &json) {
setRawHeader("Content-Type", "application/json");
return post(JToBytes(json));
}
inline QNetworkReply *post(const QJsonDocument &json) { inline QNetworkReply *post(const QJsonDocument &json) {
setRawHeader("Content-Type", "application/json"); setRawHeader("Content-Type", "application/json");
return post(json.toJson(QJsonDocument::Compact)); return post(json.toJson(QJsonDocument::Compact));
@ -86,6 +96,7 @@ QString errStr(QNetworkReply *);
QString errStrWithData(QNetworkReply *, QJsonDocument * = 0); QString errStrWithData(QNetworkReply *, QJsonDocument * = 0);
inline int waitFinished(QNetworkReply *reply, bool excludeUser = false) { inline int waitFinished(QNetworkReply *reply, bool excludeUser = false) {
if(reply->isFinished()) return 0;
QEventLoop loop; QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
return excludeUser ? loop.exec(QEventLoop::ExcludeUserInputEvents) : loop.exec(); return excludeUser ? loop.exec(QEventLoop::ExcludeUserInputEvents) : loop.exec();

View File

@ -1,120 +1,120 @@
#include "waitingdlg.h" #include "qwaitingdlg.h"
#include "gutil/qgui.h" #include "qgui.h"
#include <QTimerEvent> #include <QTimerEvent>
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>
WaitingDlg::WaitingDlg(QWidget *parent, QString text, QString sucText) : QDialog{parent, Qt::Tool}, sucText(sucText) { WaitingDlg::WaitingDlg(QWidget *parent, QString text, QString sucText) : QDialog{parent, Qt::Tool}, sucText(sucText) {
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
setModal(true); setModal(true);
auto vBox = new VBox(this); auto vBox = new VBox(this);
mIndicator = new WaitingIndicator(this); mIndicator = new WaitingIndicator(this);
mIndicator->setFixedSize(120, 120); mIndicator->setFixedSize(100, 100);
vBox->addWidget(mIndicator, 0, Qt::AlignCenter); vBox->addWidget(mIndicator, 0, Qt::AlignCenter);
fdText = new QLabel(text); fdText = new QLabel(text);
fdText->setAlignment(Qt::AlignCenter); fdText->setAlignment(Qt::AlignCenter);
gFont(fdText, 18, true); gFont(fdText, 18, true);
vBox->addWidget(fdText); vBox->addWidget(fdText);
} }
void WaitingDlg::closeEvent(QCloseEvent *event) { void WaitingDlg::closeEvent(QCloseEvent *event) {
if(showTimerId) { if(showTimerId) {
killTimer(showTimerId); killTimer(showTimerId);
showTimerId = 0; showTimerId = 0;
} }
if(closeTimerId) { if(closeTimerId) {
killTimer(closeTimerId); killTimer(closeTimerId);
closeTimerId = 0; closeTimerId = 0;
} }
QDialog::closeEvent(event); QDialog::closeEvent(event);
} }
void WaitingDlg::timerEvent(QTimerEvent *event) { void WaitingDlg::timerEvent(QTimerEvent *event) {
if(showTimerId==event->timerId()) { if(showTimerId==event->timerId()) {
killTimer(showTimerId); killTimer(showTimerId);
showTimerId = 0; showTimerId = 0;
show(); show();
} else if(closeTimerId==event->timerId()) { } else if(closeTimerId==event->timerId()) {
killTimer(closeTimerId); killTimer(closeTimerId);
closeTimerId = 0; closeTimerId = 0;
close(); close();
} else QDialog::timerEvent(event); } else QDialog::timerEvent(event);
} }
void WaitingDlg::show() { void WaitingDlg::show() {
QDialog::show(); QDialog::show();
raise(); raise();
activateWindow(); activateWindow();
} }
void WaitingDlg::showLater() { void WaitingDlg::showLater() {
if(isVisible()) return; if(isVisible()) return;
if(showTimerId) killTimer(showTimerId); if(showTimerId) killTimer(showTimerId);
showTimerId = startTimer(200); showTimerId = startTimer(200);
} }
void WaitingDlg::success() { void WaitingDlg::success() {
fdText->setText(sucText.isEmpty() ? tr("Success") : sucText); fdText->setText(sucText.isEmpty() ? tr("Success") : sucText);
mIndicator->success(); mIndicator->success();
if(showTimerId) { if(showTimerId) {
killTimer(showTimerId); killTimer(showTimerId);
showTimerId = 0; showTimerId = 0;
} }
if(! isVisible()) show(); if(! isVisible()) show();
if(closeTimerId) killTimer(closeTimerId); if(closeTimerId) killTimer(closeTimerId);
closeTimerId = startTimer(1000); closeTimerId = startTimer(keepTime);
} }
void WaitingIndicator::success() { void WaitingIndicator::success() {
if(timerId > 0) killTimer(timerId); if(timerId > 0) killTimer(timerId);
timerId = -1; timerId = -1;
angle = 0; angle = 0;
update(); update();
} }
void WaitingIndicator::timerEvent(QTimerEvent *event) { void WaitingIndicator::timerEvent(QTimerEvent *event) {
if(timerId!=event->timerId()) QWidget::timerEvent(event); if(timerId!=event->timerId()) QWidget::timerEvent(event);
else if(isVisible()) { else if(isVisible()) {
angle += 30; angle += 30;
if(angle>=360) angle -= 360; if(angle>=360) angle -= 360;
update(); update();
} else if(timerId > 0) { } else if(timerId > 0) {
killTimer(timerId); killTimer(timerId);
timerId = 0; timerId = 0;
angle = 0; angle = 0;
} }
} }
void WaitingIndicator::paintEvent(QPaintEvent *) { void WaitingIndicator::paintEvent(QPaintEvent *) {
QPainter painter(this); QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::Antialiasing);
if(timerId > 0) { if(timerId > 0) {
int radius = qMin(width(), height()) * 0.33; int radius = qMin(width(), height()) * 0.33;
int innerRadius = radius >> 1; int innerRadius = radius >> 1;
QPen pen(mColor, radius / 6, Qt::SolidLine, Qt::RoundCap); QPen pen(mColor, radius / 6, Qt::SolidLine, Qt::RoundCap);
painter.translate(width()>>1, height()>>1); painter.translate(width()>>1, height()>>1);
auto color = mColor; auto color = mColor;
for(int i=0; i<12; ++i) { for(int i=0; i<12; ++i) {
if(i) { if(i) {
color.setAlphaF(1 - i/12.0); color.setAlphaF(1 - i/12.0);
pen.setColor(color); pen.setColor(color);
painter.rotate(-30); painter.rotate(-30);
} else if(angle) painter.rotate(angle); } else if(angle) painter.rotate(angle);
painter.setPen(pen); painter.setPen(pen);
painter.drawLine(0, innerRadius, 0, radius); painter.drawLine(0, innerRadius, 0, radius);
} }
} else if(timerId==0) timerId = startTimer(33); } else if(timerId==0) timerId = startTimer(33);
else { else {
int radius = qMin(width(), height()) >> 1; int radius = qMin(width(), height()) >> 1;
int lineWidth = radius / 8; int lineWidth = radius / 8;
radius -= lineWidth>>1; radius -= lineWidth>>1;
QPen pen(QColor(0x00aa00), lineWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QPen pen(QColor(0x00aa00), lineWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
painter.setPen(pen); painter.setPen(pen);
painter.translate(width()>>1, height()>>1); painter.translate(width()>>1, height()>>1);
painter.drawEllipse(QPoint(0, 0), radius, radius); painter.drawEllipse(QPoint(0, 0), radius, radius);
QPainterPath path({-0.8*radius, 0}); QPainterPath path({-0.8*radius, 0});
path.lineTo(-0.25*radius, 0.6*radius); path.lineTo(-0.25*radius, 0.6*radius);
path.lineTo(0.6*radius, -0.5*radius); path.lineTo(0.6*radius, -0.5*radius);
painter.drawPath(path); painter.drawPath(path);
} }
} }

View File

@ -1,50 +1,51 @@
#ifndef WAITINGDLG_H #ifndef QWAITINGDLG_H
#define WAITINGDLG_H #define QWAITINGDLG_H
#include <QLabel> #include <QLabel>
#include <QNetworkReply> #include <QNetworkReply>
#include <QDialog> #include <QDialog>
class WaitingIndicator : public QWidget { class WaitingIndicator : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
using QWidget::QWidget; using QWidget::QWidget;
QColor mColor{0x0088ff}; QColor mColor{0x0088ff};
public slots: public slots:
void success(); void success();
protected: protected:
void timerEvent(QTimerEvent * event) override; void timerEvent(QTimerEvent * event) override;
void paintEvent(QPaintEvent * event) override; void paintEvent(QPaintEvent * event) override;
int angle{0}; int angle{0};
int timerId{0}; int timerId{0};
}; };
class WaitingDlg : public QDialog { class WaitingDlg : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit WaitingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0); explicit WaitingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0);
inline void connAbort(QNetworkReply *reply) { inline void connAbort(QNetworkReply *reply) {
connect(this, &WaitingDlg::rejected, reply, [reply] { connect(this, &WaitingDlg::rejected, reply, [reply] {
reply->blockSignals(true); reply->blockSignals(true);
reply->abort(); reply->abort();
reply->blockSignals(false); reply->blockSignals(false);
reply->deleteLater(); reply->deleteLater();
}); });
} }
QLabel *fdText; QLabel *fdText;
QString sucText; QString sucText;
WaitingIndicator *mIndicator; WaitingIndicator *mIndicator;
public slots: int keepTime = 750;
void show(); public slots:
void showLater(); void show();
void success(); void showLater();
protected: void success();
void timerEvent(QTimerEvent *) override; protected:
void closeEvent(QCloseEvent *) override; void timerEvent(QTimerEvent *) override;
private: void closeEvent(QCloseEvent *) override;
int closeTimerId{0}, showTimerId{0}; private:
}; int closeTimerId{0}, showTimerId{0};
};
#endif // WAITINGDLG_H
#endif // QWAITINGDLG_H

View File

@ -1,6 +1,6 @@
#include "mainwindow.h" #include "mainwindow.h"
#include <QApplication> #include <QApplication>
#include <QStyleFactory> #include <QFile>
#include <QMessageBox> #include <QMessageBox>
#include <QSplashScreen> #include <QSplashScreen>
#include <QStandardPaths> #include <QStandardPaths>
@ -27,7 +27,6 @@ LONG WINAPI handleException(_EXCEPTION_POINTERS *excep) {
} }
#endif #endif
QString gFileHome;
QString css; QString css;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@ -36,8 +35,13 @@ int main(int argc, char *argv[]) {
QApplication::setOrganizationName("Shanghai Xixun Electronic Technology Co., Ltd."); QApplication::setOrganizationName("Shanghai Xixun Electronic Technology Co., Ltd.");
QApplication::setOrganizationDomain("www.ledok.cn"); QApplication::setOrganizationDomain("www.ledok.cn");
QApplication::setApplicationName("LedOK Express"); QApplication::setApplicationName("LedOK Express");
QApplication::setStyle("Fusion");
QApplication a(argc, argv); QApplication a(argc, argv);
QApplication::setStyle(QStyleFactory::create("Fusion"));
QSplashScreen splash(QPixmap(":/res/splash.png"));
splash.show();
splash.showMessage(QObject::tr("Setting up the LedOK Express..."), Qt::AlignRight | Qt::AlignTop, Qt::white);
QFile file(":/css.css"); QFile file(":/css.css");
if(file.exists() && file.open(QFile::ReadOnly)) { if(file.exists() && file.open(QFile::ReadOnly)) {
a.setStyleSheet(css = file.readAll()); a.setStyleSheet(css = file.readAll());
@ -46,11 +50,17 @@ int main(int argc, char *argv[]) {
QFont font; QFont font;
font.setFamilies(QStringList{"Arial","PingFang SC","Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei","sans-serif"}); font.setFamilies(QStringList{"Arial","PingFang SC","Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei","sans-serif"});
a.setFont(font); a.setFont(font);
auto plt = a.palette();
plt.setBrush(QPalette::AlternateBase, plt.brush(QPalette::Active, QPalette::Window));
plt.setBrush(QPalette::Inactive, QPalette::Highlight, plt.brush(QPalette::Active, QPalette::Highlight));
plt.setBrush(QPalette::Inactive, QPalette::HighlightedText, plt.brush(QPalette::Active, QPalette::HighlightedText));
a.setPalette(plt);
QTranslator qtTrans;
if(qtTrans.load(QLocale(), "qt", "_", "translations")) QCoreApplication::installTranslator(&qtTrans);
gFileHome = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); gFileHome = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
QSplashScreen splash(QPixmap(":/res/splash.png"));
splash.show();
splash.showMessage(QObject::tr("Setting up the LedOK Express..."), Qt::AlignRight | Qt::AlignTop, Qt::white);
#ifdef _MSC_VER #ifdef _MSC_VER
SetUnhandledExceptionFilter(handleException); SetUnhandledExceptionFilter(handleException);
#endif #endif

View File

@ -2,13 +2,11 @@
#include "gutil/qgui.h" #include "gutil/qgui.h"
#include "cfg.h" #include "cfg.h"
#include "globaldefine.h" #include "globaldefine.h"
#include "deviceitem.h"
#include "devicepanel.h" #include "devicepanel.h"
#include "gutil/qnetwork.h" #include "gutil/qnetwork.h"
#include "device/upgradeapkdialog.h" #include "device/upgradeapkdialog.h"
#include <QColorDialog> #include <QColorDialog>
#include <QDesktopServices> #include <QDesktopServices>
#include <QLabel>
#include <QMenu> #include <QMenu>
#include <QMessageBox> #include <QMessageBox>
#include <QProcess> #include <QProcess>
@ -18,7 +16,8 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QToolButton> #include <QToolButton>
#include <QApplication> #include <QDir>
#include <QCoreApplication>
extern QPoint gPlayPos; extern QPoint gPlayPos;
@ -81,16 +80,21 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
actJa->setObjectName("ja"); actJa->setObjectName("ja");
menuLang->addAction(actJa); menuLang->addAction(actJa);
auto actPt = new QAction("Português");
actPt->setCheckable(true);
actPt->setObjectName("pt");
menuLang->addAction(actPt);
langGrp = new QActionGroup(menuLang); langGrp = new QActionGroup(menuLang);
langGrp->addAction(actCN); langGrp->addAction(actCN);
langGrp->addAction(actTW); langGrp->addAction(actTW);
langGrp->addAction(actEn); langGrp->addAction(actEn);
langGrp->addAction(actJa); langGrp->addAction(actJa);
langGrp->addAction(actPt);
connect(menuLang, &QMenu::triggered, this, [this](QAction* action) { connect(menuLang, &QMenu::triggered, this, [this](QAction* action) {
auto lanName = action->objectName(); auto lanName = action->objectName();
translator.load("app_"+lanName, ":/i18n"); qInfo() << "load translators" << lanName << translator.load("app_"+lanName, ":/i18n");
transQt.load("qt_"+lanName, ":/i18n");
}); });
QSettings settings; QSettings settings;
@ -101,21 +105,20 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
else if(langName.endsWith("TW")) actLan = actTW; else if(langName.endsWith("TW")) actLan = actTW;
else if(langName.startsWith("en")) actLan = actEn; else if(langName.startsWith("en")) actLan = actEn;
else if(langName.startsWith("ja")) actLan = actJa; else if(langName.startsWith("ja")) actLan = actJa;
else if(langName.startsWith("pt")) actLan = actPt;
} }
if(actLan==0) { if(actLan==0) {
langName = QLocale().name(); langName = QLocale().name();
if(langName.endsWith("TW")) actLan = actTW; if(langName.endsWith("TW")) actLan = actTW;
else if(langName.startsWith("en")) actLan = actEn; else if(langName.startsWith("en")) actLan = actEn;
else if(langName.startsWith("ja")) actLan = actJa; else if(langName.startsWith("ja")) actLan = actJa;
else if(langName.startsWith("pt")) actLan = actPt;
else actLan = actCN; else actLan = actCN;
} }
actLan->setChecked(true); actLan->setChecked(true);
auto lanName = actLan->objectName(); emit menuLang->triggered(actLan);
translator.load("app_"+lanName, ":/i18n"); QCoreApplication::installTranslator(&translator);
transQt.load("qt_"+lanName, ":/i18n");
QApplication::installTranslator(&translator);
QApplication::installTranslator(&transQt);
auto geo = settings.value("MainGeo").toRect(); auto geo = settings.value("MainGeo").toRect();
if(geo.width()>=800 && geo.height()>=500 && geo.x()>=-600 && geo.x()<=1280 && geo.y()>=-200 && geo.y()<=800) setGeometry(geo); if(geo.width()>=800 && geo.height()>=500 && geo.x()>=-600 && geo.x()<=1280 && geo.y()>=-200 && geo.y()<=800) setGeometry(geo);
@ -127,7 +130,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
setWindowTitle("LedOK Express"); setWindowTitle("LedOK Express");
icon.load(":/res/Logo.png"); icon.load(":/res/Logo.png");
titlePos = QPointF(26, 80); titlePos = QPointF(26, 80);
iconPos = QPointF(38, 20); iconPos = QRectF(38, 20, 64, 64);
auto plt = palette(); auto plt = palette();
plt.setBrush(QPalette::Window, QColor(0xdddddd)); plt.setBrush(QPalette::Window, QColor(0xdddddd));
setPalette(plt); setPalette(plt);
@ -135,10 +138,10 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
//项目保存的文档路径 //项目保存的文档路径
QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
if(!doc_path.isEmpty()) { if(!doc_path.isEmpty()) {
QDir app_dir = QDir(doc_path + "/" + QApplication::applicationName()); QDir app_dir = QDir(doc_path + "/" + QCoreApplication::applicationName());
if(!app_dir.exists()) { if(!app_dir.exists()) {
QDir doc_dir(doc_path); QDir doc_dir(doc_path);
doc_dir.mkdir(QApplication::applicationName()); doc_dir.mkdir(QCoreApplication::applicationName());
} }
} }
@ -172,8 +175,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
actFirmware = new QAction(tr("firmware manager")); actFirmware = new QAction(tr("firmware manager"));
connect(actFirmware, &QAction::triggered, this, [this] { connect(actFirmware, &QAction::triggered, this, [this] {
UpgradeApkDialog dlg(this); new UpgradeApkDialog(this);
dlg.exec();
}); });
menu_setting->addAction(actFirmware); menu_setting->addAction(actFirmware);
@ -193,22 +195,30 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
fdTrans->setChecked(gVideoTranscoding); fdTrans->setChecked(gVideoTranscoding);
vBox->addWidget(fdTrans); vBox->addWidget(fdTrans);
auto hbox = new HBox(vBox); auto hBox = new HBox(vBox);
hbox->setContentsMargins(-1, 0, -1, -1); hBox->setContentsMargins(-1, 0, -1, -1);
auto fdAnti = new QCheckBox(tr("Text antialiasing")); auto fdAnti = new QCheckBox(tr("Text antialiasing"));
fdAnti->setChecked(gTextAntialiasing); fdAnti->setChecked(gTextAntialiasing);
hbox->addWidget(fdAnti, 0, Qt::AlignTop); hBox->addWidget(fdAnti, 0, Qt::AlignTop);
auto fdAntiTip = new QLabel(tr("TextAntilaTip")); auto fdAntiTip = new QLabel(tr("TextAntilaTip"));
fdAntiTip->setStyleSheet("QLabel{color: #f00;}"); fdAntiTip->setStyleSheet("QLabel{color: #f00;}");
fdAntiTip->setWordWrap(true); fdAntiTip->setWordWrap(true);
hbox->addWidget(fdAntiTip, 1); hBox->addWidget(fdAntiTip, 1);
auto fdWidthSplit = new QCheckBox(tr("Width Split")); auto fdWidthSplit = new QCheckBox(tr("Width Split"));
fdWidthSplit->setChecked(gWidthSplit); fdWidthSplit->setChecked(gWidthSplit);
vBox->addWidget(fdWidthSplit); vBox->addWidget(fdWidthSplit);
hBox = new HBox(vBox);
hBox->addLabel(tr("Program Send Batch"));
auto fdSendBatch = new QSpinBox;
fdSendBatch->setRange(1, 20);
fdSendBatch->setValue(gSendBatch);
hBox->addWidget(fdSendBatch);
hBox->addStretch();
auto fdHideDetect = new QCheckBox(tr("Hide Detect Button")); auto fdHideDetect = new QCheckBox(tr("Hide Detect Button"));
fdHideDetect->setChecked(gHideDetect); fdHideDetect->setChecked(gHideDetect);
vBox->addWidget(fdHideDetect); vBox->addWidget(fdHideDetect);
@ -226,6 +236,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
settings.setValue("VideoTranscoding", gVideoTranscoding = fdTrans->isChecked()); settings.setValue("VideoTranscoding", gVideoTranscoding = fdTrans->isChecked());
settings.setValue("TextAntialiasing", gTextAntialiasing = fdAnti->isChecked()); settings.setValue("TextAntialiasing", gTextAntialiasing = fdAnti->isChecked());
settings.setValue("WidthSplit", gWidthSplit = fdWidthSplit->isChecked()); settings.setValue("WidthSplit", gWidthSplit = fdWidthSplit->isChecked());
settings.setValue("SendBatch", gSendBatch = fdSendBatch->value());
settings.setValue("HideDetect", gHideDetect = fdHideDetect->isChecked()); settings.setValue("HideDetect", gHideDetect = fdHideDetect->isChecked());
settings.setValue("GuangYingPin", gShowLora = fdShowLora->isChecked()); settings.setValue("GuangYingPin", gShowLora = fdShowLora->isChecked());
dlg.accept(); dlg.accept();
@ -322,7 +333,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
auto res = msgBox.exec(); auto res = msgBox.exec();
qFile.close(); qFile.close();
if(res != QDialog::Accepted) return; if(res != QDialog::Accepted) return;
QApplication::quit(); QCoreApplication::quit();
QDesktopServices::openUrl(QUrl::fromLocalFile(filePath)); QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
}); });
menu_setting->addAction(act_update); menu_setting->addAction(act_update);
@ -457,24 +468,22 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
} }
mDevicePanel->mainPanelIdx = id; mDevicePanel->mainPanelIdx = id;
if(id==MainPage_DeviceManager) { //设备信息列表页面 if(id==MainPage_DeviceManager) { //设备信息列表页面
mDevicePanel->mDeviceTable->hideColumn(0); mDevicePanel->mDeviceTable->hideColumn("check");
mDevicePanel->mDeviceTable->fdIsSelAll->hide(); mDevicePanel->mDeviceTable->fdCheckAll->hide();
mDevicePanel->fdCardNumInfo->hide();
if(mDevicePanel->mDeviceCtrlPanel) { if(mDevicePanel->mDeviceCtrlPanel) {
for(int j=DeviceTable_ScreenSize;j<DeviceTable_End;j++) mDevicePanel->mDeviceTable->showColumn(j); for(int j="screenSize"**mDevicePanel->mDeviceTable; j<mDevicePanel->mDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->showColumn(j);
mDevicePanel->mDeviceTable->setMaximumWidth(0xffffff); mDevicePanel->mDeviceTable->setMaximumWidth(0xffffff);
mDevicePanel->mDeviceTable->setSelectionMode(QAbstractItemView::NoSelection);
mDevicePanel->mDeviceCtrlPanel->hide(); mDevicePanel->mDeviceCtrlPanel->hide();
mDevicePanel->fdCardNumInfo->hide();
} }
} else if(id==MainPage_Setting) { //终端控制页面 } else if(id==MainPage_Setting) { //终端控制页面
mDevicePanel->mDeviceTable->showColumn(0); mDevicePanel->mDeviceTable->showColumn("check");
mDevicePanel->mDeviceTable->fdIsSelAll->show(); mDevicePanel->mDeviceTable->fdCheckAll->show();
for(int j=DeviceTable_ScreenSize; j<DeviceTable_End; j++) mDevicePanel->mDeviceTable->hideColumn(j); mDevicePanel->fdCardNumInfo->show();
for(int j="screenSize"**mDevicePanel->mDeviceTable; j<mDevicePanel->mDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->hideColumn(j);
if(mDevicePanel->mDeviceCtrlPanel) mDevicePanel->mDeviceCtrlPanel->show(); if(mDevicePanel->mDeviceCtrlPanel) mDevicePanel->mDeviceCtrlPanel->show();
else mDevicePanel->newCtrl(); else mDevicePanel->newCtrl();
mDevicePanel->mDeviceTable->setMaximumWidth(340); mDevicePanel->mDeviceTable->setMaximumWidth(340);
mDevicePanel->mDeviceTable->setSelectionMode(QAbstractItemView::SingleSelection);
mDevicePanel->fdCardNumInfo->show();
} }
}); });
@ -522,12 +531,14 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
hBox->addWidget(fdDetectCard); hBox->addWidget(fdDetectCard);
hBox->addStretch(); hBox->addStretch();
hBox->addWidget(new QLabel("V" APP_VERSION" - " __DATE__)); hBox->addLabel("V" APP_VERSION" - " __DATE__);
gApkHome = settings.value("ApkHome").toString();
gVideoCompress = settings.value("VideoCompress", true).toBool(); gVideoCompress = settings.value("VideoCompress", true).toBool();
gVideoTranscoding = settings.value("VideoTranscoding", true).toBool(); gVideoTranscoding = settings.value("VideoTranscoding", true).toBool();
gTextAntialiasing = settings.value("TextAntialiasing", false).toBool(); gTextAntialiasing = settings.value("TextAntialiasing", false).toBool();
gWidthSplit = settings.value("WidthSplit", false).toBool(); gWidthSplit = settings.value("WidthSplit", false).toBool();
gSendBatch = settings.value("SendBatch", 5).toInt();
gHideDetect = settings.value("HideDetect", false).toBool(); gHideDetect = settings.value("HideDetect", false).toBool();
gShowLora = settings.value("GuangYingPin", false).toBool(); gShowLora = settings.value("GuangYingPin", false).toBool();
@ -574,7 +585,6 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
QColorDialog::setStandardColor(ci++, QColor(mids[i], lows[i], higs[i])); QColorDialog::setStandardColor(ci++, QColor(mids[i], lows[i], higs[i]));
} }
} }
MainWindow::~MainWindow() { MainWindow::~MainWindow() {
QSettings settings; QSettings settings;
auto act = langGrp->checkedAction(); auto act = langGrp->checkedAction();
@ -582,20 +592,18 @@ MainWindow::~MainWindow() {
settings.setValue("MainGeo", normalGeometry()); settings.setValue("MainGeo", normalGeometry());
settings.setValue("MainIsMax", isMaximized()); settings.setValue("MainIsMax", isMaximized());
settings.setValue("PlayPos", gPlayPos); settings.setValue("PlayPos", gPlayPos);
if(! gApkHome.isEmpty()) settings.setValue("ApkHome", gApkHome);
if(mDevicePanel->fdIP) { if(mDevicePanel->fdIP) {
auto ipstr = mDevicePanel->fdIP->toPlainText(); auto ipstr = mDevicePanel->fdIP->toPlainText();
if(! ipstr.isEmpty()) settings.setValue("SpecifyIP", ipstr); if(! ipstr.isEmpty()) settings.setValue("SpecifyIP", ipstr);
else settings.remove("SpecifyIP"); else settings.remove("SpecifyIP");
} }
if(m_pTimerSendResoreIpOneKey) {
if(m_pTimerSendResoreIpOneKey->isActive()) m_pTimerSendResoreIpOneKey->stop();
delete m_pTimerSendResoreIpOneKey;
}
if(mProgPanel) { if(mProgPanel) {
settings.setValue("ProgramListSortColumn", mProgPanel->mProgTree->sortColumn()); settings.setValue("ProgramListSortColumn", mProgPanel->mProgTree->sortColumn());
settings.setValue("ProgramListSortOrder", mProgPanel->mProgTree->header()->sortIndicatorOrder()); settings.setValue("ProgramListSortOrder", mProgPanel->mProgTree->header()->sortIndicatorOrder());
} }
} }
void MainWindow::changeEvent(QEvent *event) { void MainWindow::changeEvent(QEvent *event) {
BaseWin::changeEvent(event); BaseWin::changeEvent(event);
if(event->type() == QEvent::LanguageChange) transUi(); if(event->type() == QEvent::LanguageChange) transUi();

View File

@ -21,7 +21,6 @@ protected:
private: private:
QJsonObject updates; QJsonObject updates;
QTranslator translator; QTranslator translator;
QTranslator transQt;
LoQTitleBar *m_wTitle; LoQTitleBar *m_wTitle;
QActionGroup *langGrp; QActionGroup *langGrp;
QAction *act_lang; QAction *act_lang;
@ -38,7 +37,6 @@ private:
DevicePanel *mDevicePanel{0}; DevicePanel *mDevicePanel{0};
ProgPanel *mProgPanel{0}; ProgPanel *mProgPanel{0};
mGuangYingPinWidget *m_wGuangYingPinWidget{0}; mGuangYingPinWidget *m_wGuangYingPinWidget{0};
QTimer *m_pTimerSendResoreIpOneKey{0};
bool hasNewVer{false}; bool hasNewVer{false};
}; };

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,6 @@
#include "gutil/qgui.h" #include "gutil/qgui.h"
#include "cfg.h" #include "cfg.h"
#include "player/playwin.h" #include "player/playwin.h"
#include "program/progcreatedlg.h"
#include "program/progeditorwin.h" #include "program/progeditorwin.h"
#include "program/copydirthread.h" #include "program/copydirthread.h"
#include <QApplication> #include <QApplication>
@ -12,6 +11,7 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QProgressBar> #include <QProgressBar>
#include <QFileDialog> #include <QFileDialog>
#include <QLineEdit>
ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
@ -56,7 +56,7 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
} }
auto item = new ProgItem(mProgsDir, dlg.fdName->text(), width, dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, mProgTree); auto item = new ProgItem(mProgsDir, dlg.fdName->text(), width, dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, mProgTree);
item->save();//保存pro.json item->save();//保存pro.json
mProgTree->adjustCheckState(); if(mProgTree->fdCheckAll->checkState()==Qt::Checked) mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked);
auto editor = new ProgEditorWin(item, this); auto editor = new ProgEditorWin(item, this);
editor->show(); editor->show();
}); });
@ -140,7 +140,7 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
connect(bnExport, &QPushButton::clicked, this, [=] { connect(bnExport, &QPushButton::clicked, this, [=] {
int cnt = mProgTree->topLevelItemCount(); int cnt = mProgTree->topLevelItemCount();
QStringList progNames; QStringList progNames;
for(int i=0; i<cnt; i++) if(mProgTree->topLevelItem(i)->checkState(0) == Qt::Checked) progNames.append(static_cast<ProgItem*>(mProgTree->topLevelItem(i))->mName); for(int i=0; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) progNames.append(((ProgItem*) mProgTree->topLevelItem(i))->mName);
if(progNames.isEmpty()) return; if(progNames.isEmpty()) return;
ProgPortDlg dlg(this, tr("Export")); ProgPortDlg dlg(this, tr("Export"));
@ -183,8 +183,8 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
if(PlayWin::self) PlayWin::self->close(); if(PlayWin::self) PlayWin::self->close();
else { else {
int cnt = mProgTree->topLevelItemCount(); int cnt = mProgTree->topLevelItemCount();
for(int i=0; i<cnt; i++) if(mProgTree->topLevelItem(i)->checkState(0) == Qt::Checked) { for(int i=0; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
auto item = static_cast<ProgItem*>(mProgTree->topLevelItem(i)); auto item = (ProgItem*) mProgTree->topLevelItem(i);
QString dir = mProgsDir+"/"+item->mName+"_tmp"; QString dir = mProgsDir+"/"+item->mName+"_tmp";
QFile file(dir+"/program"); QFile file(dir+"/program");
if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return; if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
@ -202,65 +202,45 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
hBox->addStretch(); hBox->addStretch();
auto fdSearch = new QLineEdit;
auto txtSearch = new QLineEdit(this); fdSearch->setFixedWidth(200);
txtSearch->setFixedSize(QSize(240, 36)); auto search = new QAction;
QAction *search = new QAction(txtSearch);
search->setIcon(QIcon(":/res/program/bnSearch.png")); search->setIcon(QIcon(":/res/program/bnSearch.png"));
txtSearch->addAction(search, QLineEdit::LeadingPosition); fdSearch->addAction(search, QLineEdit::LeadingPosition);
txtSearch->setClearButtonEnabled(true); fdSearch->setClearButtonEnabled(true);
txtSearch->setStyleSheet("border: 2px solid #aaaaaa;"); fdSearch->setStyleSheet("border: 2px solid #aaa;");
hBox->addWidget(txtSearch); connect(fdSearch, &QLineEdit::textChanged, this, [this](const QString &text) {
connect(txtSearch,SIGNAL(textChanged(const QString &)),this,SLOT(FilterProgram(const QString &))); auto cnt = mProgTree->topLevelItemCount();
for(int i=0; i<cnt; i++) {
mProgTree = new LoQTreeWidget(); auto item = mProgTree->item(i);
mProgTree->setIndentation(6); item->setHidden(! (text.isEmpty() || item->text("name").contains(text) || item->text("resolution").contains(text)));
mProgTree->setSortingEnabled(true);
m_headerItem = new QTreeWidgetItem();
for(int i=1; i<ENUM_PROGRAMLISTHEADERITEM_END; i++) m_headerItem->setTextAlignment(i, Qt::AlignCenter);
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_CHECK, Qt::DisplayRole, "");
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_NAME, Qt::DisplayRole, tr("Name"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_RESOLUTION, Qt::DisplayRole, tr("Resolution"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, Qt::DisplayRole, tr("File Size"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_LASTTIME, Qt::DisplayRole, tr("Last Modify"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT, Qt::DisplayRole, tr("USB Update"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_SEND, Qt::DisplayRole, tr("Publish"));
mProgTree->setHeaderItem(m_headerItem);
mProgTree->header()->setSectionResizeMode(ENUM_PROGRAMLISTHEADERITEM_CHECK, QHeaderView::Fixed);
mProgTree->header()->setSectionResizeMode(ENUM_PROGRAMLISTHEADERITEM_NAME, QHeaderView::Stretch);
mProgTree->header()->setSectionResizeMode(ENUM_PROGRAMLISTHEADERITEM_RESOLUTION, QHeaderView::Stretch);
mProgTree->header()->setSectionResizeMode(ENUM_PROGRAMLISTHEADERITEM_SIZE, QHeaderView::Stretch);
mProgTree->header()->setSectionResizeMode(ENUM_PROGRAMLISTHEADERITEM_LASTTIME, QHeaderView::Stretch);
mProgTree->header()->setSectionResizeMode(ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT, QHeaderView::Fixed);
mProgTree->header()->setSectionResizeMode(ENUM_PROGRAMLISTHEADERITEM_SEND, QHeaderView::Fixed);
mProgTree->header()->setStretchLastSection(false);
mProgTree->setColumnWidth(ENUM_PROGRAMLISTHEADERITEM_CHECK, 66);
mProgTree->setColumnWidth(ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT, 100);
mProgTree->setColumnWidth(ENUM_PROGRAMLISTHEADERITEM_SEND, 72);
vBox->addWidget(mProgTree);
connect(mProgTree, &LoQTreeWidget::sigCheckStateChanged, this, [this](int f){
switch(f) {
case LoQTreeWidget::CheckNone:
bnEdit->setEnabled(false);
bnDelete->setEnabled(false);
bnExport->setEnabled(false);
bnSend->setEnabled(false);
break;
case LoQTreeWidget::CheckOne:
bnEdit ->setEnabled(true);
bnDelete->setEnabled(true);
bnExport->setEnabled(true);
bnSend ->setEnabled(true);
break;
case LoQTreeWidget::CheckMulti:
bnEdit ->setEnabled(false);
bnDelete->setEnabled(true);
bnExport->setEnabled(true);
bnSend ->setEnabled(true);
break;
default: break;
} }
}); });
hBox->addWidget(fdSearch);
auto table = new LoQTreeWidget;
table->addCol("#", "", 20);
table->addCol("check", "", 36).margin(6);
table->addCol("name", "", 300, QHeaderView::Stretch);
table->addCol("resolution", "", 150, QHeaderView::Stretch);
table->addCol("size", "", 100, QHeaderView::Stretch);
table->addCol("lasttime", "", 180);
table->addCol("usb", "", 80);
table->addCol("send", "", 80);
table->setDefs()->setHeaderAlignC();
table->addFd();
table->minRowHeight = 36;
table->setSelectionMode(QAbstractItemView::NoSelection);
table->setSortingEnabled(true);
connect(table, &LoQTreeWidget::selChanged, this, [=] {
auto en = table->fdCheckAll->checkState()!=Qt::Unchecked;
bnEdit->setEnabled(en);
bnDelete->setEnabled(en);
bnExport->setEnabled(en);
bnSend->setEnabled(en);
});
vBox->addWidget(mProgTree = table);
QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
if(!doc_path.isEmpty()) { if(!doc_path.isEmpty()) {
@ -289,27 +269,20 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
if(settings.value("ProgramListSortOrder").toInt()==0) mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::AscendingOrder); if(settings.value("ProgramListSortOrder").toInt()==0) mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::AscendingOrder);
else mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::DescendingOrder); else mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::DescendingOrder);
// ui->wProgramList->setSortingEnabled( false ); //不使能QT的自动排序 transUi();
// ui->wProgramList->header()->setSortIndicatorShown( true ); // 设置三角标识符可见
// ui->wProgramList->header()->setSectionsClickable( true ); // 设置标题栏单击响应使能
// connect( ui->wProgramList->header(), SIGNAL( sectionClicked(int) ), this, SLOT( OnClickColumn(int) ) );
} }
void ProgPanel::OnClickColumn(int iColumn) {
if(iColumn!=ENUM_PROGRAMLISTHEADERITEM_CHECK && iColumn!=ENUM_PROGRAMLISTHEADERITEM_SEND) mProgTree->sortByColumn(iColumn, mProgTree->header()->sortIndicatorOrder());
}
void ProgPanel::changeEvent(QEvent *event) { void ProgPanel::changeEvent(QEvent *event) {
QWidget::changeEvent(event); QWidget::changeEvent(event);
if(event->type() == QEvent::LanguageChange) transUi(); if(event->type() == QEvent::LanguageChange) transUi();
} }
void ProgPanel::transUi() { void ProgPanel::transUi() {
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_CHECK, 0, ""); mProgTree->headerItem()->setText("name"**mProgTree, tr("Name"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_NAME, 0, tr("Name")); mProgTree->headerItem()->setText("resolution"**mProgTree, tr("Resolution"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_RESOLUTION, 0, tr("Resolution")); mProgTree->headerItem()->setText("size"**mProgTree, tr("File Size"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, 0, tr("File Size")); mProgTree->headerItem()->setText("lasttime"**mProgTree, tr("Last Modify"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_LASTTIME, 0, tr("Last Modify")); mProgTree->headerItem()->setText("usb"**mProgTree, tr("USB Update"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT, 0, tr("USB Update")); mProgTree->headerItem()->setText("send"**mProgTree, tr("Publish"));
m_headerItem->setData(ENUM_PROGRAMLISTHEADERITEM_SEND, 0, tr("Publish"));
bnNew->setText(tr("New")); bnNew->setText(tr("New"));
bnEdit->setText(tr("Edit")); bnEdit->setText(tr("Edit"));
bnDelete->setText(tr("Delete")); bnDelete->setText(tr("Delete"));
@ -322,7 +295,7 @@ void ProgPanel::transUi() {
void ProgPanel::onEditClicked(bool){ void ProgPanel::onEditClicked(bool){
int cnt = mProgTree->topLevelItemCount(); int cnt = mProgTree->topLevelItemCount();
for(int i=0; i<cnt; i++) { for(int i=0; i<cnt; i++) {
if(mProgTree->topLevelItem(i)->checkState(0) == Qt::Checked) { if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
auto item = static_cast<ProgItem*>(mProgTree->topLevelItem(i)); auto item = static_cast<ProgItem*>(mProgTree->topLevelItem(i));
auto editor = new ProgEditorWin(item, this); auto editor = new ProgEditorWin(item, this);
editor->show(); editor->show();
@ -348,7 +321,7 @@ void ProgPanel::onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize re
if(checkIfNameRepeated(name)) return; if(checkIfNameRepeated(name)) return;
auto item = new ProgItem(mProgsDir, name, res.width(), res.height(), remarks, splitWidths, max, mProgTree); auto item = new ProgItem(mProgsDir, name, res.width(), res.height(), remarks, splitWidths, max, mProgTree);
item->save();//保存pro.json item->save();//保存pro.json
mProgTree->adjustCheckState(); if(mProgTree->fdCheckAll->checkState()==Qt::Checked) mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked);
auto editor = new ProgEditorWin(item, this); auto editor = new ProgEditorWin(item, this);
editor->show(); editor->show();
} }
@ -356,65 +329,18 @@ void ProgPanel::onDeleteClicked(bool){
auto res = QMessageBox::information(this, tr("Tip Info"), tr("You will delete the selected solution(s),are you sure?"), QMessageBox::Ok, QMessageBox::Cancel); auto res = QMessageBox::information(this, tr("Tip Info"), tr("You will delete the selected solution(s),are you sure?"), QMessageBox::Ok, QMessageBox::Cancel);
if(res == QMessageBox::Ok) { if(res == QMessageBox::Ok) {
int cnt = mProgTree->topLevelItemCount(); int cnt = mProgTree->topLevelItemCount();
QList<ProgItem*> list; for(int i=0; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
for(int i=0; i<cnt; i++) { auto item = (ProgItem*) mProgTree->topLevelItem(i--);
if(mProgTree->topLevelItem(i)->checkState(0) == Qt::Checked) {
auto item = static_cast<ProgItem*>(mProgTree->topLevelItem(i));
list.push_back(item);
}
}
while(!list.isEmpty()) {
auto item = list.takeFirst();
item->del(); item->del();
delete item; delete item;
} }
mProgTree->adjustCheckState(); mProgTree->fdCheckAll->blockSignals(true);
mProgTree->fdCheckAll->setCheckState(Qt::Unchecked);
mProgTree->fdCheckAll->blockSignals(false);
emit mProgTree->selChanged();
} }
} }
void ProgPanel::FilterProgram(const QString &strtemp){
if (strtemp.isEmpty()) //显示全部
{
for (int i = 0; i< mProgTree->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = mProgTree->topLevelItem(i);
mProgTree->setRowHidden(i,mProgTree->indexFromItem(topItem->parent()),false);
}
}
else
{
QList<QTreeWidgetItem*> resultList = mProgTree->findItems(strtemp, Qt::MatchContains,ENUM_PROGRAMLISTHEADERITEM_NAME); //搜索结果
if (resultList.size() > 0)
{
for (int i = 0; i< mProgTree->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = mProgTree->topLevelItem(i);
if (resultList.contains(topItem))
mProgTree->setRowHidden(i,mProgTree->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
mProgTree->setRowHidden(i,mProgTree->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList1 = mProgTree->findItems(strtemp, Qt::MatchContains,ENUM_PROGRAMLISTHEADERITEM_RESOLUTION); //搜索结果
if (resultList1.size() > 0){
for (int i = 0; i< mProgTree->topLevelItemCount(); ++i){
QTreeWidgetItem* topItem = mProgTree->topLevelItem(i);
if (resultList1.contains(topItem)) mProgTree->setRowHidden(i,mProgTree->indexFromItem(topItem->parent()),false); //显示匹配的结果
else mProgTree->setRowHidden(i,mProgTree->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
for (int i = 0; i< mProgTree->topLevelItemCount(); ++i){
QTreeWidgetItem* topItem = mProgTree->topLevelItem(i);
mProgTree->setRowHidden(i,mProgTree->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
}
}
}
ProgPortDlg::ProgPortDlg(QWidget *parent, QString title) : QDialog(parent) { ProgPortDlg::ProgPortDlg(QWidget *parent, QString title) : QDialog(parent) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
setWindowFlag(Qt::WindowContextHelpButtonHint, 0); setWindowFlag(Qt::WindowContextHelpButtonHint, 0);

View File

@ -13,7 +13,6 @@ class ProgPanel : public QWidget {
public: public:
explicit ProgPanel(QWidget *parent = nullptr); explicit ProgPanel(QWidget *parent = nullptr);
QTreeWidgetItem *m_headerItem{0};
LoQTreeWidget *mProgTree{0}; LoQTreeWidget *mProgTree{0};
protected: protected:
void changeEvent(QEvent *) override; void changeEvent(QEvent *) override;
@ -24,17 +23,13 @@ public slots:
void onEditClicked(bool f); void onEditClicked(bool f);
void onDeleteClicked(bool f); void onDeleteClicked(bool f);
void onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList<int> &, int); void onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList<int> &, int);
void FilterProgram(const QString &strtemp);
private slots:
void OnClickColumn(int iColumn);
private: private:
QString mProgsDir; QString mProgsDir;
QList<ProgItem *> m_pwPorgramItemList; QList<ProgItem *> m_pwPorgramItemList;
QPushButton *bnNew = nullptr; QPushButton *bnNew;
QPushButton *bnEdit = nullptr; QPushButton *bnEdit;
QPushButton *bnDelete = nullptr; QPushButton *bnDelete;
QPushButton *bnImport, *bnExport; QPushButton *bnImport, *bnExport;
QPushButton *bnSend, *btnPlay; QPushButton *bnSend, *btnPlay;
}; };

View File

@ -1,85 +0,0 @@
#include "progcreatedlg.h"
#include "gutil/qgui.h"
#include "globaldefine.h"
#include <QLabel>
#include <QPushButton>
#include <QDialogButtonBox>
ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remarks, QString widths, QWidget *parent) : QDialog(parent) {
#ifdef Q_OS_WIN
setWindowFlag(Qt::WindowContextHelpButtonHint, 0);
#endif
setWindowTitle(tr("Solution Information"));
auto vBox = new VBox(this);
auto hBox = new HBox(vBox);
auto label = new QLabel(tr("Solution Name"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
hBox->addSpacing(6);
fdName = new QLineEdit;
if(name.isEmpty()) name = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
else fdName->setDisabled(true);
fdName->setText(name);
hBox->addWidget(fdName);
hBox = new HBox(vBox);
hBox->setSpacing(12);
label = new QLabel(tr("Resolution"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
hBox->addSpacing(6);
auto label_4 = new QLabel(tr("Width"));
hBox->addWidget(label_4);
fdWidth = new QSpinBox;
fdWidth->setMaximum(99999);
fdWidth->setValue(width);
hBox->addWidget(fdWidth);
auto label_5 = new QLabel(tr("Height"));
hBox->addWidget(label_5);
fdHeight = new QSpinBox;
fdHeight->setMaximum(99999);
fdHeight->setValue(height);
hBox->addWidget(fdHeight);
hBox->addStretch();
hBox = new HBox(vBox);
label = new QLabel(tr("Remarks"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
hBox->addSpacing(6);
fdRemark = new QTextEdit(remarks);
fdRemark->setFixedSize(300, 80);
hBox->addWidget(fdRemark);
hBox = new HBox(vBox);
auto lbSplitWidth = new QLabel(tr("每段打折宽度 (用空格分隔)"));
hBox->addWidget(lbSplitWidth);
fdSplitWidths = new QLineEdit(widths);
fdSplitWidths->setPlaceholderText("256 256 256 ...");
hBox->addWidget(fdSplitWidths);
if(! gWidthSplit) {
lbSplitWidth->setVisible(false);
fdSplitWidths->setVisible(false);
}
vBox->addSpacing(6);
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
vBox->addWidget(btnBox);
}

View File

@ -1,20 +0,0 @@
#ifndef PROGCREATEDLG_H
#define PROGCREATEDLG_H
#include <QDialog>
#include <QLineEdit>
#include <QTextEdit>
#include <QSpinBox>
class ProgCreateDlg : public QDialog {
Q_OBJECT
public:
ProgCreateDlg(QString name, int width, int height, QString remarks, QString, QWidget *parent = nullptr);
QLineEdit *fdName;
QSpinBox *fdWidth;
QSpinBox *fdHeight;
QTextEdit *fdRemark;
QLineEdit *fdSplitWidths;
};
#endif // PROGCREATEDLG_H

View File

@ -5,7 +5,7 @@
#include "player/playwin.h" #include "player/playwin.h"
#include "tools.h" #include "tools.h"
#include "globaldefine.h" #include "globaldefine.h"
#include "base/waitingdlg.h" #include "gutil/qwaitingdlg.h"
#include "program/ebase.h" #include "program/ebase.h"
#include "program/etext.h" #include "program/etext.h"
#include "program/ephoto.h" #include "program/ephoto.h"
@ -19,7 +19,6 @@
#include "program/emultiwin.h" #include "program/emultiwin.h"
#include "program/gentmpthread.h" #include "program/gentmpthread.h"
#include "program/sendprogramdialog.h" #include "program/sendprogramdialog.h"
#include "progcreatedlg.h"
#include <QBoxLayout> #include <QBoxLayout>
#include <QCloseEvent> #include <QCloseEvent>
#include <QGraphicsDropShadowEffect> #include <QGraphicsDropShadowEffect>
@ -222,7 +221,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
QString value = file.readAll(); QString value = file.readAll();
file.close(); file.close();
QJsonParseError jsErr; QJsonParseError jsErr;
QJsonObject prog = QJsonDocument::fromJson(value.toUtf8(), &jsErr).object(); auto prog = QJsonDocument::fromJson(value.toUtf8(), &jsErr).object();
if(jsErr.error) return; if(jsErr.error) return;
int www = mProgItem->mWidth, hhh = mProgItem->mHeight; int www = mProgItem->mWidth, hhh = mProgItem->mHeight;
if(mProgItem->mMaxWidth) { if(mProgItem->mMaxWidth) {
@ -371,9 +370,10 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
if(listPage->count() > 0) { if(listPage->count() > 0) {
auto cur = (PageListItem*) listPage->currentItem(); auto cur = (PageListItem*) listPage->currentItem();
cur->updateJson(); cur->updateJson();
auto item = new PageListItem(cur->mAttr, cur->mPageDir); JObj attr;
for(auto &pair : cur->mAttr) attr.insert(pair.first, pair.second);
auto item = new PageListItem(attr, cur->mPageDir);
item->mAttr["name"] = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"); item->mAttr["name"] = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
item->mAttr["order"] = listPage->count();
listPage->addItem(item); listPage->addItem(item);
listPage->setItemWidget(item, item->itemWgt()); listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentItem(item); listPage->setCurrentItem(item);
@ -391,12 +391,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
if(res == QMessageBox::Ok) { if(res == QMessageBox::Ok) {
delete item; delete item;
if(listPage->count() > 0) listPage->setCurrentRow(0); if(listPage->count() > 0) listPage->setCurrentRow(0);
int cnt = listPage->count(); for(int i=0; i<listPage->count(); i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
for(int i=0; i<cnt; i++) {
auto item = (PageListItem*)listPage->item(i);
item->mAttr["order"] = i;
item->fdIdx->setNum(i+1);
}
} }
} }
}); });
@ -412,12 +407,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
listPage->setItemWidget(item, item->itemWgt()); listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentRow(index-1); listPage->setCurrentRow(index-1);
} }
int cnt = listPage->count(); for(int i=0; i<listPage->count(); i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
for(int i=0; i<cnt; i++) {
auto item = (PageListItem*)listPage->item(i);
item->mAttr["order"] = i;
item->fdIdx->setNum(i+1);
}
} }
}); });
toolBar->addAction(actMoveUp); toolBar->addAction(actMoveUp);
@ -432,12 +422,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
listPage->setItemWidget(item, item->itemWgt()); listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentRow(index+1); listPage->setCurrentRow(index+1);
} }
int cnt = listPage->count(); for(int i=0; i<listPage->count(); i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
for(int i=0; i<cnt; i++) {
auto item = (PageListItem*)listPage->item(i);
item->mAttr["order"] = i;
item->fdIdx->setNum(i+1);
}
} }
}); });
toolBar->addAction(actMoveDown); toolBar->addAction(actMoveDown);
@ -516,8 +501,8 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
QDir progQDir(mProgItem->mProgDir); QDir progQDir(mProgItem->mProgDir);
if(progQDir.exists()) { if(progQDir.exists()) {
QStringList pageNames = progQDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); auto pageNames = progQDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
foreach(QString pageName, pageNames) { for(QString &pageName : pageNames) {
if(pageName.endsWith(PAGEDEL_SUFFIX)) { if(pageName.endsWith(PAGEDEL_SUFFIX)) {
QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively(); QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively();
continue; continue;
@ -525,36 +510,40 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
QFile pageFile(mProgItem->mProgDir + "/" + pageName + "/page.json"); QFile pageFile(mProgItem->mProgDir + "/" + pageName + "/page.json");
if(pageFile.exists()) { if(pageFile.exists()) {
pageFile.open(QIODevice::ReadOnly); pageFile.open(QIODevice::ReadOnly);
mPageJsons.push_back(QJsonDocument::fromJson(pageFile.readAll()).object()); mPageJsons.emplace_back(JFrom(pageFile.readAll()).toObj());
pageFile.close(); pageFile.close();
} else QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively(); } else QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively();
} }
} std::sort(mPageJsons.begin(), mPageJsons.end(), [](const JObj &a, const JObj &b) {
if(mPageJsons.isEmpty()) onAddPage();
else {
std::sort(mPageJsons.begin(), mPageJsons.end(), [](const QJsonObject &a, const QJsonObject &b) {
return a["order"].toInt() < b["order"].toInt(); return a["order"].toInt() < b["order"].toInt();
}); });
foreach(QJsonObject pageJson, mPageJsons) { }
auto pageDir = mProgItem->mProgDir+"/"+pageJson["name"].toString(); if(mPageJsons.empty()) onAddPage();
QDir dir(pageDir); else for(JObj &pageJson : mPageJsons) {
if(! dir.exists() && ! dir.mkdir(pageDir)) continue; auto pageDir = mProgItem->mProgDir+"/"+pageJson["name"].toString();
auto item = new PageListItem(pageJson, pageDir); QDir dir(pageDir);
listPage->addItem(item); if(! dir.exists() && ! dir.mkdir(pageDir)) continue;
listPage->setItemWidget(item, item->itemWgt()); JObj attr;
auto cnt = listPage->count(); for(auto &pair : pageJson) attr.insert(pair.first, pair.second);
if(cnt==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1); auto item = new PageListItem(attr, pageDir);
} listPage->addItem(item);
listPage->setItemWidget(item, item->itemWgt());
auto cnt = listPage->count();
if(cnt==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
} }
listPage->setCurrentRow(0); listPage->setCurrentRow(0);
} }
bool ProgEditorWin::isProgChanged() { bool ProgEditorWin::isProgChanged() {
if(mPageJsons.size() != listPage->count()) return true; if(mPageJsons.size() != listPage->count()) return true;
for(int i=0; i<mPageJsons.count(); i++) { for(int i=0; i<(int)mPageJsons.size(); i++) {
auto page = static_cast<PageListItem*>(listPage->item(i)); auto page = (PageListItem*) listPage->item(i);
if(page->mAttrWgt==0) continue; if(page->mAttrWgt==0) continue;
page->updateJson(); page->updateJson();
if(page->mAttr != mPageJsons[i]) return true; if(page->mAttr != mPageJsons[i]) {
qDebug()<<page->mAttr;
qDebug()<<mPageJsons[i];
return true;
}
} }
return false; return false;
} }
@ -585,18 +574,21 @@ bool ProgEditorWin::save() {
QMessageBox::critical(this, tr("Error"), tr("Create Dir failed")+": "+mProgItem->mProgDir); QMessageBox::critical(this, tr("Error"), tr("Create Dir failed")+": "+mProgItem->mProgDir);
return 0; return 0;
} }
QStringList pageNames = progDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); auto pageNames = progDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
foreach(QString pageName, pageNames) { for(QString &pageName : pageNames) if(! progDir.rename(pageName, pageName + PAGEDEL_SUFFIX)) {
if(! progDir.rename(pageName, pageName + PAGEDEL_SUFFIX)) { rtn = 0;
rtn = 0; QMessageBox::critical(this, tr("Error"), tr("Rename fail when saving")+" "+pageName);
QMessageBox::critical(this, tr("Error"), tr("Rename fail when saving")+" "+pageName);
}
} }
//保存每个页面的元素和页面属性到page.json文档 //保存每个页面的元素和页面属性到page.json文档
mPageJsons.clear(); mPageJsons.clear();
for(int i=0; i<cnt; i++) { for(int i=0; i<cnt; i++) {
auto page = static_cast<PageListItem*>(listPage->item(i)); auto page = (PageListItem*) listPage->item(i);
if(page->saveFiles()) mPageJsons.append(page->mAttr); page->mAttr["order"] = i;
if(page->saveFiles()) {
JObj json;
for(auto &pair : page->mAttr) json.insert(pair.first, pair.second);
mPageJsons.emplace_back(json);
}
} }
pageNames = progDir.entryList(QStringList("*" PAGEDEL_SUFFIX)); pageNames = progDir.entryList(QStringList("*" PAGEDEL_SUFFIX));
foreach(QString pageName, pageNames) { foreach(QString pageName, pageNames) {
@ -624,43 +616,102 @@ void ProgEditorWin::onSave() {
mProgItem->onSetProgram(); mProgItem->onSetProgram();
} }
void ProgEditorWin::UdpSendJson(QJsonObject json) {
QUdpSocket *tempUdpSocket= new QUdpSocket(this);
if(!tempUdpSocket->bind(QHostAddress("127.0.0.1"))) {
QMessageBox::critical(this, tr("Warning"), "udp bind failed");
return;
}
QJsonDocument resultJson;
resultJson.setObject(json);
QByteArray byteArray=resultJson.toJson();
QHostAddress localAddress("127.0.0.1");
int iSendLength=tempUdpSocket->writeDatagram(byteArray.data(),byteArray.size(),localAddress,2000);
if(iSendLength != byteArray.size()) {
char *aa=byteArray.data();
tempUdpSocket->writeDatagram(&aa[iSendLength],byteArray.size()-iSendLength,localAddress,2000);
}
delete tempUdpSocket;
}
void ProgEditorWin::onAddPage() { void ProgEditorWin::onAddPage() {
QDateTime now = QDateTime::currentDateTime(); QDateTime now = QDateTime::currentDateTime();
auto name = now.toString("yyyyMMddhhmmsszzz"); auto name = now.toString("yyyyMMddhhmmsszzz");
auto pageDir = mProgItem->mProgDir+"/"+name; auto pageDir = mProgItem->mProgDir+"/"+name;
QDir dir(pageDir); QDir dir(pageDir);
if(! dir.exists() && ! dir.mkpath(pageDir)) return; if(! dir.exists() && ! dir.mkpath(pageDir)) return;
QJsonObject attr; JObj attr;
attr["name"] = name; attr["name"] = name;
attr["order"] = listPage->count();
attr["repeat"] = 1; attr["repeat"] = 1;
attr["validDate"] = QJsonObject{ attr["validDate"] = JObj{
{"isValid", false}, {"isValid", false},
{"start", now.date().toString("yyyy-MM-dd")}, {"start", now.date().toString("yyyy-MM-dd")},
{"end", now.addSecs(2678400).date().toString("yyyy-MM-dd")} {"end", now.addSecs(2678400).date().toString("yyyy-MM-dd")}
}; };
attr["plans"] = QJsonArray();
auto item = new PageListItem(attr, pageDir); auto item = new PageListItem(attr, pageDir);
listPage->addItem(item); listPage->addItem(item);
listPage->setItemWidget(item, item->itemWgt()); listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentItem(item); listPage->setCurrentItem(item);
if(listPage->count()==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1); if(listPage->count()==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
} }
ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remarks, QString widths, QWidget *parent) : QDialog(parent) {
#ifdef Q_OS_WIN
setWindowFlag(Qt::WindowContextHelpButtonHint, 0);
#endif
setWindowTitle(tr("Solution Information"));
auto vBox = new VBox(this);
auto hBox = new HBox(vBox);
auto label = new QLabel(tr("Solution Name"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
hBox->addSpacing(6);
fdName = new QLineEdit;
if(name.isEmpty()) name = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
else fdName->setDisabled(true);
fdName->setText(name);
hBox->addWidget(fdName);
hBox = new HBox(vBox);
hBox->setSpacing(12);
label = new QLabel(tr("Resolution"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
hBox->addSpacing(6);
auto label_4 = new QLabel(tr("Width"));
hBox->addWidget(label_4);
fdWidth = new QSpinBox;
fdWidth->setMaximum(99999);
fdWidth->setValue(width);
hBox->addWidget(fdWidth);
auto label_5 = new QLabel(tr("Height"));
hBox->addWidget(label_5);
fdHeight = new QSpinBox;
fdHeight->setMaximum(99999);
fdHeight->setValue(height);
hBox->addWidget(fdHeight);
hBox->addStretch();
hBox = new HBox(vBox);
label = new QLabel(tr("Remarks"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
hBox->addSpacing(6);
fdRemark = new QTextEdit(remarks);
fdRemark->setFixedSize(300, 80);
hBox->addWidget(fdRemark);
hBox = new HBox(vBox);
auto lbSplitWidth = new QLabel(tr("每段打折宽度 (用空格分隔)"));
hBox->addWidget(lbSplitWidth);
fdSplitWidths = new QLineEdit(widths);
fdSplitWidths->setPlaceholderText("256 256 256 ...");
hBox->addWidget(fdSplitWidths);
if(! gWidthSplit) {
lbSplitWidth->setVisible(false);
fdSplitWidths->setVisible(false);
}
vBox->addSpacing(6);
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
vBox->addWidget(btnBox);
}

View File

@ -1,8 +1,11 @@
#ifndef PROGEDITORWIN_H #ifndef PROGEDITORWIN_H
#define PROGEDITORWIN_H #define PROGEDITORWIN_H
#include "program/pageeditor.h" #include "program/pageeditor.h"
#include <QDialog>
#include <QSpinBox>
#include <QTextEdit>
#include <QListWidget> #include <QListWidget>
#include <QJsonObject> #include "gutil/qjson.h"
class ProgPanel; class ProgPanel;
class ProgItem; class ProgItem;
@ -18,16 +21,26 @@ protected:
private: private:
bool isProgChanged(); bool isProgChanged();
bool save(); bool save();
void UdpSendJson(QJsonObject json);
QListWidget *listPage; QListWidget *listPage;
PageListItem *mPageItem = nullptr; PageListItem *mPageItem = 0;
PageEditor *mPageEditor; PageEditor *mPageEditor;
QTabWidget *mTabsAttr; QTabWidget *mTabsAttr;
QList<QJsonObject> mPageJsons; std::vector<JObj> mPageJsons;
ProgItem *mProgItem; ProgItem *mProgItem;
int mNewEleX = 0; int mNewEleX = 0;
int mNewEleY = 0; int mNewEleY = 0;
}; };
class ProgCreateDlg : public QDialog {
Q_OBJECT
public:
ProgCreateDlg(QString name, int width, int height, QString remarks, QString, QWidget *parent = nullptr);
QLineEdit *fdName;
QSpinBox *fdWidth;
QSpinBox *fdHeight;
QTextEdit *fdRemark;
QLineEdit *fdSplitWidths;
};
#endif // PROGEDITORWIN_H #endif // PROGEDITORWIN_H

View File

@ -3,25 +3,25 @@
#include "QtWidgets/qlineedit.h" #include "QtWidgets/qlineedit.h"
#include "gutil/qcore.h" #include "gutil/qcore.h"
#include "gutil/qgui.h" #include "gutil/qgui.h"
#include "base/waitingdlg.h" #include "gutil/qwaitingdlg.h"
#include "progeditorwin.h" #include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "gentmpthread.h" #include "gentmpthread.h"
#include <globaldefine.h> #include <globaldefine.h>
#include "sendprogramdialog.h" #include "sendprogramdialog.h"
#include "program/progeditorwin.h"
#include <QJsonArray> #include <QJsonArray>
#include <QMessageBox> #include <QMessageBox>
#include <QStorageInfo> #include <QStorageInfo>
ProgItem::ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString &remarks, QList<int> &splitWidths, int maxWidth, LoQTreeWidget *tree) : QTreeWidgetItem(UserType), ProgItem::ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString &remarks, QList<int> &splitWidths, int maxWidth, LoQTreeWidget *tree) : TreeWidgetItem(tree),
mName(name), mWidth(w), mHeight(h), mRemark(remarks), mSplitWidths(splitWidths), mMaxWidth(maxWidth), mProgsDir(progsDir), mTree(tree) { mName(name), mWidth(w), mHeight(h), mRemark(remarks), mSplitWidths(splitWidths), mMaxWidth(maxWidth), mProgsDir(progsDir) {
m_last = QDateTime::currentDateTime(); m_last = QDateTime::currentDateTime();
mProgDir = progsDir + "/" + mName; mProgDir = progsDir + "/" + mName;
m_orgName = mName; m_orgName = mName;
init(); init();
} }
ProgItem::ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidget *tree) : QTreeWidgetItem(UserType), mProgsDir(progsDir), mTree(tree) { ProgItem::ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidget *tree) : TreeWidgetItem(tree), mProgsDir(progsDir) {
mName = json["name"].toString(); mName = json["name"].toString();
mWidth = json["resolution"]["w"].toInt(); mWidth = json["resolution"]["w"].toInt();
mHeight = json["resolution"]["h"].toInt(); mHeight = json["resolution"]["h"].toInt();
@ -40,41 +40,39 @@ ProgItem::ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidg
} }
void ProgItem::init() { void ProgItem::init() {
setFlags(flags() & ~Qt::ItemIsUserCheckable);
setCheckState("check", Qt::Unchecked);
auto ft = font(0); auto ft = font(0);
ft.setPixelSize(14); ft.setPixelSize(14);
for(int i=1; i<ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT; i++) setFont(i, ft); for(int i=1; i<treeWidget()->columnCount()-2; i++) {
setFont(i, ft);
setForeground(ENUM_PROGRAMLISTHEADERITEM_NAME, Qt::transparent); setTextAlignment(i, Qt::AlignCenter);
setText(ENUM_PROGRAMLISTHEADERITEM_NAME, mName); }
setData(ENUM_PROGRAMLISTHEADERITEM_RESOLUTION, 0, QString("%1 x %2").arg(mWidth).arg(mHeight)); setForeground("name"**treeWidget(), Qt::transparent);
if(m_fsize<=0) setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, 0, byteSizeStr((qint64)100)); setText("name", mName);
else setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, 0, byteSizeStr(m_fsize)); setText("resolution", QString("%1 x %2").arg(mWidth).arg(mHeight));
setData(ENUM_PROGRAMLISTHEADERITEM_LASTTIME, 0, m_last.toString("yyyy-MM-dd hh:mm:ss")); setText("size", m_fsize<=0 ? "100B" : byteSizeStr(m_fsize));
setTextAlignment(ENUM_PROGRAMLISTHEADERITEM_NAME, Qt::AlignLeft | Qt::AlignVCenter); setText("lasttime", m_last.toString("yyyy-MM-dd hh:mm:ss"));
for(int i=1; i<ENUM_PROGRAMLISTHEADERITEM_END; i++) setTextAlignment(i, Qt::AlignCenter);
setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
setCheckState(0, Qt::Unchecked);
mTree->insertTopLevelItem(0,this);
m_bnName = new QPushButton(mName); m_bnName = new QPushButton(mName);
m_bnName->setFont(ft); m_bnName->setFont(ft);
m_bnName->setCursor(QCursor(Qt::PointingHandCursor));
m_bnName->setStyleSheet(R"delimiter( m_bnName->setStyleSheet(R"delimiter(
QPushButton{border-radius: 4px;} QPushButton{border-radius: 4px;}
QPushButton:hover { QPushButton:hover {
background-color: #cccccc; background-color: #ccc;
text-decoration: underline; text-decoration: underline;
} }
)delimiter"); )delimiter");
QObject::connect(m_bnName, &QPushButton::clicked, treeWidget(), [=] {
m_bnName->setCursor(QCursor(Qt::PointingHandCursor)); auto editor = new ProgEditorWin(this, treeWidget()->parentWidget());
mTree->setItemWidget(this, ENUM_PROGRAMLISTHEADERITEM_NAME, m_bnName);
QObject::connect(m_bnName, &QPushButton::clicked, mTree, [this] {
auto editor = new ProgEditorWin(this, mTree->parentWidget());
editor->show(); editor->show();
}); });
m_bnExport = new QPushButton(); setCellWidget("name", m_bnName);
m_bnExport->setCursor(QCursor(Qt::PointingHandCursor));
m_bnExport->setStyleSheet(R"rrr( auto btnExport = new QPushButton;
btnExport->setCursor(QCursor(Qt::PointingHandCursor));
btnExport->setStyleSheet(R"rrr(
QPushButton { QPushButton {
border-radius: 4px; border-radius: 4px;
image: url(:/res/program/bnExport_u.png); image: url(:/res/program/bnExport_u.png);
@ -82,10 +80,8 @@ QPushButton {
QPushButton:pressed{image: url(:/res/program/bnExport_s.png);} QPushButton:pressed{image: url(:/res/program/bnExport_s.png);}
QPushButton:hover{background-color: #cccccc;} QPushButton:hover{background-color: #cccccc;}
)rrr"); )rrr");
QObject::connect(btnExport, &QPushButton::clicked, treeWidget(), [=] {
mTree->setItemWidget(this, ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT, m_bnExport); QDialog dlg(treeWidget());
QObject::connect(m_bnExport, &QPushButton::clicked, mTree, [this] {
QDialog dlg(mTree);
dlg.setWindowTitle(QObject::tr("USB Update Program")); dlg.setWindowTitle(QObject::tr("USB Update Program"));
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
dlg.setWindowFlag(Qt::WindowContextHelpButtonHint, 0); dlg.setWindowFlag(Qt::WindowContextHelpButtonHint, 0);
@ -132,14 +128,20 @@ QPushButton:hover{background-color: #cccccc;}
fdDrives->clear(); fdDrives->clear();
auto volumes = QStorageInfo::mountedVolumes(); auto volumes = QStorageInfo::mountedVolumes();
foreach(auto volume, volumes) fdDrives->addItem(volume.displayName(), volume.rootPath()); foreach(auto volume, volumes) {
auto text = volume.displayName();
auto rootPath = volume.rootPath();
if(text!=rootPath) text += " ("+rootPath+")";
fdDrives->addItem(text, rootPath);
}
dlg.exec(); dlg.exec();
}); });
setCellWidget("usb", btnExport);
m_bnSend = new QPushButton(); auto btnSend = new QPushButton;
m_bnSend->setCursor(QCursor(Qt::PointingHandCursor)); btnSend->setCursor(QCursor(Qt::PointingHandCursor));
m_bnSend->setStyleSheet(R"rrr( btnSend->setStyleSheet(R"rrr(
QPushButton{ QPushButton{
border-radius: 4px; border-radius: 4px;
image: url(:/res/program/bnSend_u.png); image: url(:/res/program/bnSend_u.png);
@ -147,20 +149,19 @@ QPushButton{
QPushButton:pressed{image: url(:/res/program/bnSend_s.png);} QPushButton:pressed{image: url(:/res/program/bnSend_s.png);}
QPushButton:hover{background-color: #cccccc;} QPushButton:hover{background-color: #cccccc;}
)rrr"); )rrr");
QObject::connect(btnSend, &QPushButton::clicked, treeWidget(), [this] {
mTree->setItemWidget(this, ENUM_PROGRAMLISTHEADERITEM_SEND, m_bnSend); auto waitingDlg = new WaitingDlg(treeWidget(), QObject::tr("Convertering")+" ...");
QObject::connect(m_bnSend, &QPushButton::clicked, mTree, [this] {
auto waitingDlg = new WaitingDlg(mTree, QObject::tr("Convertering")+" ...");
auto gen = new GenTmpThread(this, mName, "", ""); auto gen = new GenTmpThread(this, mName, "", "");
QObject::connect(gen, &GenTmpThread::onErr, mTree, [=](QString err) { QObject::connect(gen, &GenTmpThread::onErr, treeWidget(), [=](QString err) {
QMessageBox::warning(mTree, "GenTmpThread Error", err); QMessageBox::warning(treeWidget(), "GenTmpThread Error", err);
}); });
QObject::connect(gen, &QThread::finished, waitingDlg, &WaitingDlg::close); QObject::connect(gen, &QThread::finished, waitingDlg, &WaitingDlg::close);
gen->start(); gen->start();
waitingDlg->exec(); waitingDlg->exec();
SendProgramDialog dlg(mName, mTree); SendProgramDialog dlg(mName, treeWidget()->window());
dlg.exec(); dlg.exec();
}); });
setCellWidget("send", btnSend);
} }
void ProgItem::save() { void ProgItem::save() {
@ -177,7 +178,6 @@ void ProgItem::save() {
dRoot = QDir(mProgDir); dRoot = QDir(mProgDir);
if(dRoot.exists()) { if(dRoot.exists()) {
QJsonObject obj; QJsonObject obj;
QJsonObject oSize;
obj["name"] = mName; obj["name"] = mName;
obj["resolution"] = QJsonObject{{"w", mWidth}, {"h", mHeight}}; obj["resolution"] = QJsonObject{{"w", mWidth}, {"h", mHeight}};
obj["remarks"] = mRemark; obj["remarks"] = mRemark;
@ -186,10 +186,9 @@ void ProgItem::save() {
obj["splitWidths"] = splitWidths; obj["splitWidths"] = splitWidths;
obj["file_size"] = m_fsize; obj["file_size"] = m_fsize;
obj["last_edit"] = m_last.toString("yyyy-MM-dd hh:mm:ss"); obj["last_edit"] = m_last.toString("yyyy-MM-dd hh:mm:ss");
QJsonDocument json(obj);
QFile f(mProgDir + "/pro.json"); QFile f(mProgDir + "/pro.json");
f.open(QIODevice::WriteOnly); f.open(QIODevice::WriteOnly);
f.write(json.toJson()); f.write(QJsonDocument(obj).toJson());
f.close(); f.close();
} }
} }
@ -201,8 +200,8 @@ void ProgItem::del() {
//设置列表项的值 //设置列表项的值
void ProgItem::onSetProgram() { void ProgItem::onSetProgram() {
m_bnName->setText(mName); m_bnName->setText(mName);
setData(ENUM_PROGRAMLISTHEADERITEM_RESOLUTION, 0, QString("%1 x %2").arg(mWidth).arg(mHeight)); setText("resolution", QString("%1 x %2").arg(mWidth).arg(mHeight));
setData(ENUM_PROGRAMLISTHEADERITEM_SIZE, 0, byteSizeStr(m_fsize<=0 ? 100 : m_fsize)); setText("size", byteSizeStr(m_fsize<=0 ? 100 : m_fsize));
setData(ENUM_PROGRAMLISTHEADERITEM_LASTTIME, 0, m_last.toString("yyyy-MM-dd hh:mm:ss")); setText("lasttime", m_last.toString("yyyy-MM-dd hh:mm:ss"));
save(); save();
} }

View File

@ -1,23 +1,19 @@
#ifndef PROGITEM_H #ifndef PROGITEM_H
#define PROGITEM_H #define PROGITEM_H
#include <QTreeWidget> #include "base/loqtreewidget.h"
#include <QTreeWidgetItem>
#include <QDir>
#include <QDateTime>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument>
#include <QPushButton> #include <QPushButton>
#include <base/loqtreewidget.h>
class ProgPanel; class ProgPanel;
class ProgItem : public QTreeWidgetItem { class ProgItem : public TreeWidgetItem {
public: public:
explicit ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString & remarks, QList<int> &splitWidths, int, LoQTreeWidget *parent); explicit ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString & remarks, QList<int> &splitWidths, int, LoQTreeWidget *parent);
explicit ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidget *parent); explicit ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidget *parent);
void save(); void save();
void del(); void del();
void onSetProgram();
QString mName; QString mName;
int mWidth; int mWidth;
@ -30,25 +26,9 @@ public:
qint64 m_fsize{0}; qint64 m_fsize{0};
QDateTime m_last; QDateTime m_last;
QPushButton *m_bnName; QPushButton *m_bnName;
LoQTreeWidget *mTree;
void onSetProgram();
private: private:
void init(); void init();
QPushButton *m_bnExport; QString m_orgName;
QPushButton *m_bnSend;
QString m_orgName;
};
enum ENUM_PROGRAMLISTHEADERITEM {
ENUM_PROGRAMLISTHEADERITEM_CHECK=0,
ENUM_PROGRAMLISTHEADERITEM_NAME,
ENUM_PROGRAMLISTHEADERITEM_RESOLUTION,
ENUM_PROGRAMLISTHEADERITEM_SIZE,
ENUM_PROGRAMLISTHEADERITEM_LASTTIME,
ENUM_PROGRAMLISTHEADERITEM_USB_EXPORT,
ENUM_PROGRAMLISTHEADERITEM_SEND,
ENUM_PROGRAMLISTHEADERITEM_END
}; };
#endif // PROGITEM_H #endif // PROGITEM_H

View File

@ -4,7 +4,7 @@
#include "deviceitem.h" #include "deviceitem.h"
#include "devicepanel.h" #include "devicepanel.h"
#include "gutil/qnetwork.h" #include "gutil/qnetwork.h"
#include "base/waitingdlg.h" #include "gutil/qwaitingdlg.h"
#include <QAction> #include <QAction>
#include <QLineEdit> #include <QLineEdit>
#include <QHeaderView> #include <QHeaderView>
@ -18,20 +18,142 @@ SendProgramDialog::SendProgramDialog(QString progName, QWidget *parent) : QDialo
setWindowFlag(Qt::WindowMaximizeButtonHint); setWindowFlag(Qt::WindowMaximizeButtonHint);
#endif #endif
setWindowTitle(tr("Publish")+" "+mProgName); setWindowTitle(tr("Publish")+" "+mProgName);
resize(1024, 700); resize(1024, 720);
auto vBox = new VBox(this); auto vBox = new VBox(this);
vBox->setContentsMargins(6,0,6,9); vBox->setContentsMargins(6,0,6,0);
auto hBox = new HBox(vBox); auto hBox = new HBox(vBox);
label = new QLabel(tr("success info")); label = new QLabel(tr("success info"));
hBox->addWidget(label); hBox->addWidget(label);
hBox->addSpacing(20);
auto btnPublish = new QPushButton(tr("Publish"));
connect(btnPublish, &QPushButton::clicked, this, [=] {
if(mWaitCnt > 0) return;
int cnt = table->topLevelItemCount();
int sentCnt = 0;
SendProgramItem *item;
auto remarks = "remarks"**table;
for(int rr=0; rr<cnt; rr++) if(! (item = (SendProgramItem*) table->topLevelItem(rr))->isHidden() && item->checkState("id") == Qt::Checked && ! item->isSending) {
if(item->btnUnlock && item->isLocked) {
item->setResult(tr("This screen is encrypted"), Qt::red);
continue;
}
item->fdProgress->setValue(0);
if(sentCnt>=gSendBatch) {
item->setText(remarks, " "+tr("Waiting")+" ...");
item->setForeground(remarks, Qt::black);
mWaitCnt++;
continue;
}
item->isSending = true;
item->setText(remarks, "");
auto sendProg = new SendProgThread(programsDir()+"/"+mProgName+"_tmp", item->text("ip"), 3333);
connect(sendProg, &SendProgThread::emErr, item->fdProgress, [=](QString strTip) {
item->isSending = false;
if(strTip=="OK") {
item->setCheckState("id", Qt::Unchecked);
item->setText(remarks, "OK");
item->setForeground(remarks, Qt::darkGreen);
} else {
item->setText(remarks, strTip);
item->setForeground(remarks, Qt::red);
}
sendNext();
});
connect(sendProg, &SendProgThread::emProgress, item->fdProgress, &QProgressBar::setValue);
connect(this, &SendProgramDialog::stopAllThd, sendProg, &SendProgThread::stop);
sendProg->start();
sentCnt++;
}
});
hBox->addWidget(btnPublish);
hBox->addStretch(); hBox->addStretch();
auto btnRefresh = new QPushButton(tr("Refresh")); auto btnRefresh = new QPushButton(tr("Refresh"));
btnRefresh->setProperty("ssType", "progManageTool"); connect(btnRefresh, &QPushButton::clicked, this, [=] {
connect(btnRefresh, &QPushButton::clicked, this, &SendProgramDialog::refresh); int cnt = gDevicePanel->mDeviceTable->topLevelItemCount();
for(int i=0; i<cnt; i++) {
auto card = ((DeviceItem*)gDevicePanel->mDeviceTable->topLevelItem(i))->mCard;
int cnt = table->topLevelItemCount();
SendProgramItem *item;
for(int rr=0; rr<cnt; rr++) if((item = (SendProgramItem*) table->topLevelItem(rr))->text("id") == card.id) goto end;
item = new SendProgramItem(table);
item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
item->setCheckState("id", Qt::Unchecked);
item->setText("id", card.id);
{
item->fdOnline = new QLabel;
item->fdOnline->setScaledContents(true);
item->fdOnline->setFixedSize(24, 24);
auto wgt = new QWidget;
auto hhh = new HBox(wgt);
hhh->setContentsMargins(0,0,0,0);
hhh->addWidget(item->fdOnline);
item->setCellWidget("online", wgt);
}
item->fdProgress = new QProgressBar;
item->fdProgress->setAlignment(Qt::AlignCenter);
item->fdProgress->setStyleSheet("QProgressBar {margin-top: 6px; margin-bottom: 6px;}");
item->setCellWidget("progress", item->fdProgress);
end:
item->setText("ip", card.ip);
item->setText("alias", card.alias);
item->setText("size", QString("%1 x %2").arg(card.mWidth).arg(card.mHeight));
item->fdOnline->setPixmap({card.isOnline ? ":/res/online.png" : ":/res/offline.png"});
if(! card.hasPassword) {
item->isLocked = false;
item->setCellWidget("encrypt", item->btnUnlock = 0);
} else {
item->isLocked = card.isLocked;
if(item->btnUnlock==0) {
item->btnUnlock = new QPushButton;
item->btnUnlock->setMaximumHeight(36);
item->setCellWidget("encrypt", item->btnUnlock);
connect(item->btnUnlock, &QPushButton::clicked, item->btnUnlock, [=] {
if(! item->isLocked) return;
bool ok;
auto pwd = QInputDialog::getText(this, tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok);
if(! ok) return;
QJsonObject json;
json.insert("_id", "VerifyPassword");
json.insert("_type", "VerifyPassword");
json.insert("pwd", pwd);
auto waitingDlg = new WaitingDlg(this, tr("VerifyPassword")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, item->btnUnlock, [=] {
QJsonDocument json;
auto err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(this, QObject::tr("Error"), err);
return;
}
if(! json["result"].toBool()) {
waitingDlg->close();
QMessageBox::warning(this, tr("Tip Info"), tr("password is wrong"));
return;
}
waitingDlg->success();
item->isLocked = false;
item->btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
auto item = findItem(card.id);
if(item) {
item->mCard.isLocked = false;
item->btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
}
});
});
}
item->btnUnlock->setIcon(QIcon(card.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png")); //已验证显示绿色 没验证蓝色
}
}
label->setText(tr("All")+": "+QString::number(cnt));
});
hBox->addWidget(btnRefresh); hBox->addWidget(btnRefresh);
auto txtSearch = new QLineEdit; auto txtSearch = new QLineEdit;
@ -40,191 +162,35 @@ SendProgramDialog::SendProgramDialog(QString progName, QWidget *parent) : QDialo
txtSearch->setStyleSheet("QLineEdit{border: 2px solid #aaa; padding: 2px;}"); txtSearch->setStyleSheet("QLineEdit{border: 2px solid #aaa; padding: 2px;}");
txtSearch->addAction(new QAction(QIcon(":/res/program/bnSearch.png"), QString()), QLineEdit::LeadingPosition); txtSearch->addAction(new QAction(QIcon(":/res/program/bnSearch.png"), QString()), QLineEdit::LeadingPosition);
connect(txtSearch, &QLineEdit::textEdited, this, [=](const QString &text) { connect(txtSearch, &QLineEdit::textEdited, this, [=](const QString &text) {
auto cnt = table->rowCount(); auto cnt = table->topLevelItemCount();
for(int rr=0; rr<cnt; rr++) table->setRowHidden(rr, !(text.isEmpty() || table->text(rr, "id").contains(text) || table->text(rr, "ip").contains(text) || table->text(rr, "alias").contains(text) || table->text(rr, "size").contains(text))); for(int rr=0; rr<cnt; rr++) {
auto item = table->item(rr);
item->setHidden(! (text.isEmpty() || item->text("id").contains(text) || item->text("ip").contains(text) || item->text("alias").contains(text) || item->text("size").contains(text)));
}
}); });
hBox->addWidget(txtSearch); hBox->addWidget(txtSearch);
table = new Table{ table = new LoQTreeWidget;
{"id", "ID", 130}, table->addCol("#", "", 20);
{"online", tr("Online"), 40}, table->addCol("id", "ID", 130).margin(4);
{"ip", "IP", 100}, table->addCol("online", tr("Online"), 40);
{"size", tr("Screen Size"), 80}, table->addCol("ip", "IP", 100);
{"alias", tr("Alias"), 120}, table->addCol("size", tr("Screen Size"), 80).alignC(),
{"encrypt", tr("Security"), 40}, table->addCol("alias", tr("Alias"), 120);
{"progress", tr("Progress"), 120}, table->addCol("encrypt", tr("Security"), 40);
{"remarks", tr("Remarks"), QHeaderView::Stretch} table->addCol("progress", tr("Progress"), 120);
}; table->addCol("remarks", tr("Remarks"), QHeaderView::Stretch);
table->setDefs(); table->setDefs()->setHeaderAlignC();
auto colId = table->mFieldMap["id"]; table->addFd();
table->sortItems(colId); table->setSelectionMode(QAbstractItemView::NoSelection);
table->setSelectionMode(Table::NoSelection); table->setSortingEnabled(true);
table->setStyle(new ViewItemStyle);
vBox->addWidget(table); vBox->addWidget(table);
fdCheckAll = new QCheckBox(table); auto sortField = gDevicePanel->mDeviceTable->sortField();
connect(fdCheckAll, &QCheckBox::stateChanged, this, [=](int state) { if(sortField=="id" || sortField=="ip" || sortField=="alias") table->sortItems(sortField, gDevicePanel->mDeviceTable->header()->sortIndicatorOrder());
if(state==Qt::PartiallyChecked) return; else table->sortItems("id");
int cnt = table->rowCount();
for(int rr=0; rr<cnt; rr++) if(! table->isRowHidden(rr)) table->itemValid(rr, colId)->setCheckState((Qt::CheckState) state);
});
connect(table, &Table::updGeos, this, [=] {
fdCheckAll->move(table->verticalHeader()->size().width() + 8, 2);
});
auto cellClicked = [=](int row, int column) {
if(column!=colId) return;
auto item = table->itemValid(row, colId);
auto state = item->checkState()==Qt::Checked ? Qt::Unchecked : Qt::Checked;
item->setCheckState(state);
int cnt = table->rowCount();
fdCheckAll->blockSignals(true);
for(int rr=0; rr<cnt; rr++) if(! table->isRowHidden(rr) && table->itemValid(rr, colId)->checkState()!=state) {
fdCheckAll->setCheckState(Qt::PartiallyChecked);
goto end;
}
fdCheckAll->setCheckState(state);
end:fdCheckAll->blockSignals(false);
};
connect(table, &Table::cellClicked, table, cellClicked);
connect(table, &Table::cellEntered, table, [=](int row, int column) {
if(column!=colId) return;
if((QApplication::mouseButtons() & Qt::LeftButton) == 0) return;
cellClicked(row, column);
});
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); emit btnRefresh->clicked();
btnBox->button(QDialogButtonBox::Ok)->setText(tr("Publish"));
connect(btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(btnBox, &QDialogButtonBox::accepted, this, [=] {
if(mWaitCnt > 0) return;
int cnt = table->rowCount();
int sentCnt{0};
for(int rr=0; rr<cnt; rr++) if(! table->isRowHidden(rr)) {
auto fdId = table->itemValid(rr, colId);
if(fdId->checkState()!=Qt::Checked) continue;
if(fdId->data(isSending).toBool()) continue;
auto btnUnlock = (QPushButton*) table->cellWidget(rr, "encrypt");
auto fdRemarks = table->itemValid(rr, "remarks");
if(btnUnlock && btnUnlock->property("isLocked").toBool()) {
fdRemarks->setText(tr("This screen is encrypted"));
fdRemarks->setForeground(Qt::red);
continue;
}
auto fdProgress = (QProgressBar*) table->cellWidget(rr, "progress");
fdProgress->setValue(0);
if(sentCnt>=5) {
fdRemarks->setText(" "+tr("Waiting")+" ...");
fdRemarks->setForeground(Qt::black);
mWaitCnt++;
continue;
}
fdId->setData(isSending, true);
fdRemarks->setText("");
auto sendProg = new SendProgThread(programsDir()+"/"+mProgName+"_tmp", table->text(rr, "ip"), 3333);
connect(sendProg, &SendProgThread::emErr, fdProgress, [=](QString strTip) {
fdId->setData(isSending, false);
if(strTip=="OK") {
fdId->setCheckState(Qt::Unchecked);
fdRemarks->setText("OK");
fdRemarks->setForeground(Qt::darkGreen);
} else {
fdRemarks->setText(strTip);
fdRemarks->setForeground(Qt::red);
}
sendNext();
});
connect(sendProg, &SendProgThread::emProgress, fdProgress, &QProgressBar::setValue);
connect(this, &SendProgramDialog::stopAllThd, sendProg, &SendProgThread::stop);
sendProg->start();
sentCnt++;
}
});
vBox->addWidget(btnBox);
refresh();
auto timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &SendProgramDialog::refresh);
timer->start(60000);
}
void SendProgramDialog::addRow(LedCard card) {
int cnt = table->rowCount();
for(int rr=0; rr<cnt; rr++) if(table->text(rr, "id") == card.id) {
updRow(rr, card);
return;
}
table->setSortingEnabled(false);
table->setRowCount(cnt+1);
auto item = table->setText(cnt, "id", card.id);
item->setCheckState(Qt::Unchecked);
item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
auto fdOnline = new QLabel;
fdOnline->setAlignment(Qt::AlignCenter);
table->setCellWidget(cnt, "online", fdOnline);
auto fdProgress = new QProgressBar;
fdProgress->setAlignment(Qt::AlignCenter);
fdProgress->setStyleSheet("QProgressBar {margin-top: 6px; margin-bottom: 6px;}");
table->setCellWidget(cnt, "progress", fdProgress);
updRow(cnt, card);
table->setSortingEnabled(true);
}
void SendProgramDialog::updRow(int row, LedCard card) {
table->setText(row, "alias", card.alias);
table->setText(row, "ip", card.ip);
table->setText(row, "size", QString("%1 x %2").arg(card.mWidth).arg(card.mHeight))->setTextAlignment(Qt::AlignCenter);
((QLabel*) table->cellWidget(row, "online"))->setPixmap(QPixmap(card.isOnline ? ":/res/O_Online.png" : ":/res/O_Offline.png"));
if(! card.hasPassword) table->setCellWidget(row, "encrypt", 0);
else {
auto btnUnlock = (QPushButton*) table->cellWidget(row, "encrypt");
if(btnUnlock==0) {
btnUnlock = new QPushButton;
btnUnlock->setMaximumHeight(40);
btnUnlock->setProperty("isLocked", card.isLocked);
table->setCellWidget(row, "encrypt", btnUnlock);
connect(btnUnlock, &QPushButton::clicked, btnUnlock, [=] {
if(! btnUnlock->property("isLocked").toBool()) return;
bool ok;
auto pwd = QInputDialog::getText(this, tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok);
if(! ok) return;
QJsonObject json;
json.insert("_id", "VerifyPassword");
json.insert("_type", "VerifyPassword");
json.insert("pwd", pwd);
auto waitingDlg = new WaitingDlg(this, tr("VerifyPassword")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(60000).post(json);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, btnUnlock, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(this, QObject::tr("Error"), err);
return;
}
if(! json["result"].toBool()) {
waitingDlg->close();
QMessageBox::warning(this, tr("Tip Info"), tr("password is wrong"));
return;
}
waitingDlg->success();
btnUnlock->setProperty("isLocked", false);
btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
auto item = findItem(card.id);
if(item) {
item->mCard.isLocked = false;
item->btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
}
});
});
}
btnUnlock->setIcon(QIcon(card.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png")); //已验证显示绿色 没验证蓝色
}
} }
void SendProgramDialog::closeEvent(QCloseEvent *) { void SendProgramDialog::closeEvent(QCloseEvent *) {
@ -232,42 +198,30 @@ void SendProgramDialog::closeEvent(QCloseEvent *) {
} }
void SendProgramDialog::sendNext() { void SendProgramDialog::sendNext() {
if(mWaitCnt <= 0) return; if(mWaitCnt <= 0) return;
int cnt = table->rowCount(); int cnt = table->topLevelItemCount();
for(int rr=0; rr<cnt; rr++) if(! table->isRowHidden(rr)) { SendProgramItem *item;
auto fdId = table->itemValid(rr, "id"); auto remarks = "remarks"**table;
if(fdId->checkState()!=Qt::Checked) continue; for(int rr=0; rr<cnt; rr++) if(! (item = (SendProgramItem*) table->item(rr))->isHidden() && item->checkState("id") == Qt::Checked && ! item->isSending && ! item->isLocked && item->text(remarks).startsWith(" ")) {
if(fdId->data(isSending).toBool()) continue; item->setText(remarks, "");
auto btnUnlock = (QPushButton*) table->cellWidget(rr, "encrypt"); item->fdProgress->setValue(0);
if(btnUnlock && btnUnlock->property("isLocked").toBool()) continue; item->isSending = true;
auto fdRemarks = table->itemValid(rr, "remarks");
if(! fdRemarks->text().startsWith(" ")) continue;
fdRemarks->setText("");
auto fdProgress = (QProgressBar*) table->cellWidget(rr, "progress");
fdProgress->setValue(0);
fdId->setData(isSending, true);
mWaitCnt--; mWaitCnt--;
auto sendProg = new SendProgThread(programsDir()+"/"+mProgName+"_tmp", table->text(rr, "ip"), 3333); auto sendProg = new SendProgThread(programsDir()+"/"+mProgName+"_tmp", item->text("ip"), 3333);
connect(sendProg, &SendProgThread::emErr, fdProgress, [=](QString strTip) { connect(sendProg, &SendProgThread::emErr, item->fdProgress, [=](QString strTip) {
fdId->setData(isSending, false); item->isSending = false;
if(strTip=="OK") { if(strTip=="OK") {
fdId->setCheckState(Qt::Unchecked); item->setCheckState("id", Qt::Unchecked);
fdRemarks->setText("OK"); item->setText(remarks, "OK");
fdRemarks->setForeground(Qt::darkGreen); item->setForeground(remarks, Qt::darkGreen);
} else { } else {
fdRemarks->setText(strTip); item->setText(remarks, strTip);
fdRemarks->setForeground(Qt::red); item->setForeground(remarks, Qt::red);
} }
sendNext(); sendNext();
}); });
connect(sendProg, &SendProgThread::emProgress, fdProgress, &QProgressBar::setValue); connect(sendProg, &SendProgThread::emProgress, item->fdProgress, &QProgressBar::setValue);
connect(this, &SendProgramDialog::stopAllThd, sendProg, &SendProgThread::stop); connect(this, &SendProgramDialog::stopAllThd, sendProg, &SendProgThread::stop);
sendProg->start(); sendProg->start();
return; return;
} }
} }
void SendProgramDialog::refresh() {
int cnt = gDevicePanel->mDeviceTable->topLevelItemCount();
for(int rr=0; rr<cnt; rr++) addRow(((DeviceItem*)gDevicePanel->mDeviceTable->topLevelItem(rr))->mCard);
label->setText(tr("All")+": "+QString::number(cnt));
}

View File

@ -1,51 +1,44 @@
#ifndef SENDPROGRAMDIALOG_H #ifndef SENDPROGRAMDIALOG_H
#define SENDPROGRAMDIALOG_H #define SENDPROGRAMDIALOG_H
#include "globaldefine.h" #include "base/loqtreewidget.h"
#include "gutil/qgui.h"
#include <QDialog> #include <QDialog>
#include <QCheckBox> #include <QProgressBar>
#include <QProxyStyle>
#include <QApplication>
class SendProgramDialog : public QDialog { class SendProgramDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit SendProgramDialog(QString, QWidget *parent = nullptr); explicit SendProgramDialog(QString, QWidget *parent);
signals: signals:
void stopAllThd(); void stopAllThd();
protected slots:
void refresh();
protected: protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
void sendNext(); void sendNext();
void addRow(LedCard);
void updRow(int, LedCard);
Table *table; LoQTreeWidget *table;
QCheckBox *fdCheckAll;
int mWaitCnt{0}; int mWaitCnt{0};
QLabel *label; QLabel *label;
QString mProgName; QString mProgName;
QString m_strUrl; QString m_strUrl;
enum {isSending = Qt::UserRole};
}; };
class ViewItemStyle : public QProxyStyle { class SendProgramItem : public TreeWidgetItem {
public: public:
ViewItemStyle() : QProxyStyle(QApplication::style()) {} using TreeWidgetItem::TreeWidgetItem;
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override { void setResult(QString tip, QColor color) {
auto res = QProxyStyle::subElementRect(element, option, widget); auto remarks = "remarks"**treeWidget();
if(option && option->type==QStyleOption::SO_ViewItem && ((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator && ((QStyleOptionViewItem*)option)->index.internalId()==0) res.setLeft(res.x() + 6); setText(remarks, tip);
return res; setToolTip(remarks, tip);
} setForeground(remarks, color);
int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override {
auto res = QProxyStyle::pixelMetric(metric, option, widget);
if(metric==PM_FocusFrameHMargin && option && option->type==QStyleOption::SO_ViewItem && ((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator) res += 4;
return res;
} }
bool isSending = false;
bool isLocked = true;
QLabel *fdOnline;
QProgressBar *fdProgress;
QPushButton *btnUnlock = 0;
}; };
#endif // SENDPROGRAMDIALOG_H #endif // SENDPROGRAMDIALOG_H

View File

@ -1,125 +0,0 @@
#include "wplanitem.h"
#include "gutil/qgui.h"
#include <QJsonArray>
wPlanItem::wPlanItem(QListWidgetItem *item, const QJsonObject *json) : m_item(item) {
setAttribute(Qt::WA_DeleteOnClose);
auto vBox = new VBox(this);
vBox->setContentsMargins(6, 6, 0, 6);
auto hBox = new HBox(vBox);
fdIdx = new QLabel("1");
hBox->addWidget(fdIdx);
tStart = new QTimeEdit;
tStart->setDisplayFormat("HH:mm");
hBox->addWidget(tStart);
tEnd = new QTimeEdit;
tEnd->setDisplayFormat("HH:mm");
tEnd->setTime(QTime(23, 59, 59));
hBox->addWidget(tEnd);
bnDel = new QPushButton;
hBox->addWidget(bnDel);
hBox = new HBox(vBox);
sMon = new QPushButton(tr("M"));
sMon ->setCheckable(true);
sMon ->setProperty("ssName", "weeklySelector");
hBox->addWidget(sMon);
hBox->addStretch();
sTues = new QPushButton(tr("Tu"));
sTues->setCheckable(true);
sTues->setProperty("ssName", "weeklySelector");
hBox->addWidget(sTues);
hBox->addStretch();
sWed = new QPushButton(tr("W"));
sWed ->setCheckable(true);
sWed ->setProperty("ssName", "weeklySelector");
hBox->addWidget(sWed);
hBox->addStretch();
sThur = new QPushButton(tr("Th"));
sThur->setCheckable(true);
sThur->setProperty("ssName", "weeklySelector");
hBox->addWidget(sThur);
hBox->addStretch();
sFri = new QPushButton(tr("F"));
sFri ->setCheckable(true);
sFri ->setProperty("ssName", "weeklySelector");
hBox->addWidget(sFri);
hBox->addStretch();
sSat = new QPushButton(tr("Sa"));
sSat ->setCheckable(true);
sSat ->setProperty("ssName", "weeklySelector");
hBox->addWidget(sSat);
hBox->addStretch();
sSun = new QPushButton(tr("Su"));
sSun ->setCheckable(true);
sSun ->setProperty("ssName", "weeklySelector");
hBox->addWidget(sSun);
if(json==0) {
sMon ->setChecked(true);
sTues->setChecked(true);
sWed ->setChecked(true);
sThur->setChecked(true);
sFri ->setChecked(true);
sSat ->setChecked(true);
sSun ->setChecked(true);
} else {
tStart->setTime(QTime::fromString(json->value("start").toString(), "hh:mm"));
tEnd->setTime(QTime::fromString(json->value("end").toString(), "hh:mm"));
auto oWeekly = json->value("weekly").toArray();
sMon ->setChecked(oWeekly.contains(1));
sTues->setChecked(oWeekly.contains(2));
sWed ->setChecked(oWeekly.contains(3));
sThur->setChecked(oWeekly.contains(4));
sFri ->setChecked(oWeekly.contains(5));
sSat ->setChecked(oWeekly.contains(6));
sSun ->setChecked(oWeekly.contains(7));
}
connect(tStart, SIGNAL(timeChanged(const QTime&)), this, SLOT(onItemChanged()));
connect(tEnd, SIGNAL(timeChanged(const QTime&)), this, SLOT(onItemChanged()));
connect(sMon, SIGNAL(toggled(bool)), this, SLOT(onItemChanged()));
connect(sTues, SIGNAL(toggled(bool)), this, SLOT(onItemChanged()));
connect(sWed, SIGNAL(toggled(bool)), this, SLOT(onItemChanged()));
connect(sThur, SIGNAL(toggled(bool)), this, SLOT(onItemChanged()));
connect(sFri, SIGNAL(toggled(bool)), this, SLOT(onItemChanged()));
connect(sSat, SIGNAL(toggled(bool)), this, SLOT(onItemChanged()));
connect(sSun, SIGNAL(toggled(bool)), this, SLOT(onItemChanged()));
connect(bnDel, SIGNAL(clicked(bool)), this, SLOT(onDelete(bool)));
}
void wPlanItem::onItemChanged(){
emit sigItemChanged(m_item);
}
void wPlanItem::onDelete(bool){
emit sigDelete(m_item);
}
QJsonObject wPlanItem::planJson() const {
QJsonObject oRoot;
QJsonArray oWeekly;
if(sMon ->isChecked()) oWeekly.append(QJsonValue(1));
if(sTues->isChecked()) oWeekly.append(QJsonValue(2));
if(sWed ->isChecked()) oWeekly.append(QJsonValue(3));
if(sThur->isChecked()) oWeekly.append(QJsonValue(4));
if(sFri ->isChecked()) oWeekly.append(QJsonValue(5));
if(sSat ->isChecked()) oWeekly.append(QJsonValue(6));
if(sSun ->isChecked()) oWeekly.append(QJsonValue(7));
oRoot["start"] = tStart->time().toString("hh:mm");
oRoot["end"] = tEnd->time().toString("hh:mm");
oRoot["weekly"] = oWeekly;
return oRoot;
}

View File

@ -1,41 +0,0 @@
#ifndef WPLANITEM_H
#define WPLANITEM_H
#include <QPushButton>
#include <QListWidgetItem>
#include <QLabel>
#include <QTimeEdit>
#include <QJsonObject>
class wPlanItem : public QWidget {
Q_OBJECT
public:
explicit wPlanItem(QListWidgetItem *item, const QJsonObject * = 0);
QJsonObject planJson() const;
QLabel *fdIdx;
signals:
void sigItemChanged(QListWidgetItem *);
void sigDelete(QListWidgetItem *);
protected slots:
void onItemChanged();
void onDelete(bool);
private:
QListWidgetItem *m_item;
QTimeEdit *tStart;
QTimeEdit *tEnd;
QPushButton *bnDel;
QPushButton *sMon;
QPushButton *sTues;
QPushButton *sWed;
QPushButton *sThur;
QPushButton *sFri;
QPushButton *sSat;
QPushButton *sSun;
};
#endif // WPLANITEM_H

View File

@ -1,66 +0,0 @@
#include "wplanlist.h"
#include "wplanitem.h"
#include <QJsonArray>
wPlanList::wPlanList(QWidget *parent) : QListWidget(parent) {
setAttribute(Qt::WA_DeleteOnClose);
setFrameShape(QListWidget::NoFrame);
}
void wPlanList::adjustItemNum() {
int n = count();
for(int i=0; i<n; i++) static_cast<wPlanItem*>(itemWidget(item(i)))->fdIdx->setNum(i+1);
}
QJsonArray wPlanList::plansJson() {
QJsonArray oRoot;
int n = count();
for(int i=0; i<n; i++) {
wPlanItem *w = static_cast<wPlanItem*>(itemWidget(item(i)));
oRoot.append(w->planJson());
}
return oRoot;
}
//添加时间计划表
void wPlanList::onAddPlan()
{
QListWidgetItem *item = new QListWidgetItem();
item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
wPlanItem *widget = new wPlanItem(item);
addItem(item);
setItemWidget(item, widget);
setCurrentItem(item);
connect(widget, SIGNAL(sigItemChanged(QListWidgetItem*)), this, SIGNAL(itemChanged(QListWidgetItem*)));
connect(widget, SIGNAL(sigDelete(QListWidgetItem*)), this, SLOT(onDeletePlan(QListWidgetItem*)));
adjustItemNum();
emit itemChanged(item);
}
void wPlanList::onRestorePlan(const QJsonArray &jRoot)
{
clear();
int n = jRoot.count();
for(int i=0; i<n; i++) {
QListWidgetItem *item = new QListWidgetItem();
item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
auto json = jRoot.at(i).toObject();
wPlanItem *widget = new wPlanItem(item, &json);
addItem(item);
setItemWidget(item, widget);
setCurrentItem(item);
connect(widget, SIGNAL(sigItemChanged(QListWidgetItem*)), this, SIGNAL(itemChanged(QListWidgetItem*)));
connect(widget, SIGNAL(sigDelete(QListWidgetItem*)), this, SLOT(onDeletePlan(QListWidgetItem*)));
}
adjustItemNum();
}
void wPlanList::onDeletePlan(QListWidgetItem *item)
{
int index = row(item);
if(index >= 0) {
removeItemWidget(item);
delete item;
emit itemChanged(nullptr);
}
adjustItemNum();
}

View File

@ -1,24 +0,0 @@
#ifndef WPLANLIST_H
#define WPLANLIST_H
#include <QListWidget>
#include <QListWidgetItem>
class wPlanList : public QListWidget {
Q_OBJECT
public:
explicit wPlanList(QWidget *parent = nullptr);
QJsonArray plansJson();
protected:
void adjustItemNum();
signals:
public slots:
void onAddPlan();
void onRestorePlan(const QJsonArray &jRoot);
void onDeletePlan(QListWidgetItem *item);
};
#endif // WPLANLIST_H

View File

@ -17,10 +17,10 @@
<file>res/DeviceNum_All.png</file> <file>res/DeviceNum_All.png</file>
<file>res/FlashArrow.png</file> <file>res/FlashArrow.png</file>
<file>res/Lock.png</file> <file>res/Lock.png</file>
<file>res/O_Offline.png</file> <file>res/offline.png</file>
<file>res/O_Online.png</file> <file>res/online.png</file>
<file>res/UnLock.png</file> <file>res/UnLock.png</file>
<file>res/bnDetail.png</file> <file>res/info.png</file>
<file>res/deviceReadbackPic.png</file> <file>res/deviceReadbackPic.png</file>
<file>res/DeviceManager_s.png</file> <file>res/DeviceManager_s.png</file>
<file>res/DeviceManager_u.png</file> <file>res/DeviceManager_u.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

BIN
LedOK/res/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
LedOK/res/offline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

BIN
LedOK/res/online.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

View File

@ -58,7 +58,7 @@ void Tools::mergeFormat(QTextEdit *textEdit, const QTextCharFormat &fmt) {
if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor);
cursor.mergeCharFormat(fmt); cursor.mergeCharFormat(fmt);
} }
void Tools::saveImg(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, QJsonObject& imgs, const QString& str, const QString& name) { void Tools::saveImg(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, JObj& imgs, const QString& str, const QString& name) {
if(str.isEmpty()) return; if(str.isEmpty()) return;
QImage img(metric.horizontalAdvance(str), metric.lineSpacing(), QImage::Format_ARGB32); QImage img(metric.horizontalAdvance(str), metric.lineSpacing(), QImage::Format_ARGB32);
img.fill(Qt::transparent); img.fill(Qt::transparent);
@ -83,8 +83,8 @@ void Tools::saveImg(const QString& dir, const QFontMetrics& metric, const QFont&
file.close(); file.close();
imgs.insert(name, md5); imgs.insert(name, md5);
} }
void Tools::saveImg2(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, QJsonArray& imgs, const QString& str, const QString& name) { void Tools::saveImg2(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, JArray& imgs, const QString& str, const QString& name) {
QJsonObject obj{ JObj obj{
{"name", name}, {"name", name},
{"mime", "image/png"} {"mime", "image/png"}
}; };

View File

@ -2,6 +2,7 @@
#define TOOLS_H #define TOOLS_H
#include "program/progitem.h" #include "program/progitem.h"
#include "gutil/qjson.h"
#include <QApplication> #include <QApplication>
#include <QBrush> #include <QBrush>
#include <QColor> #include <QColor>
@ -14,7 +15,6 @@
const QString str0_9[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; const QString str0_9[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
extern QTextEdit *gFdResInfo; extern QTextEdit *gFdResInfo;
extern QString gFileHome;
extern ProgItem *gProgItem; extern ProgItem *gProgItem;
extern QString css; extern QString css;
@ -31,8 +31,8 @@ public:
static void mergeFormat(QTextEdit *textEdit, const QTextCharFormat &format); static void mergeFormat(QTextEdit *textEdit, const QTextCharFormat &format);
static QString readErrStr(QImageReader::ImageReaderError); static QString readErrStr(QImageReader::ImageReaderError);
static QString fileMd5(QString); static QString fileMd5(QString);
static void saveImg(const QString&, const QFontMetrics&, const QFont&, const QColor&, QJsonObject&, const QString&, const QString&); static void saveImg(const QString&, const QFontMetrics&, const QFont&, const QColor&, JObj&, const QString&, const QString&);
static void saveImg2(const QString&, const QFontMetrics&, const QFont&, const QColor&, QJsonArray&, const QString&, const QString&); static void saveImg2(const QString&, const QFontMetrics&, const QFont&, const QColor&, JArray&, const QString&, const QString&);
static QColor int2Color(int value); static QColor int2Color(int value);
static int color2Int(const QColor& color); static int color2Int(const QColor& color);
static QBrush getBrush(const QColor& color); static QBrush getBrush(const QColor& color);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
LedOK/translations/qt_ar.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_bg.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_ca.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_cs.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_da.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_de.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_en.qm Normal file

Binary file not shown.

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_TW">
</TS>

BIN
LedOK/translations/qt_es.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_fi.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_fr.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_gd.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_he.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_hu.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_it.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_ja.qm Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
LedOK/translations/qt_ko.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_lv.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_pl.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_pt.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_ru.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_sk.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_tr.qm Normal file

Binary file not shown.

BIN
LedOK/translations/qt_uk.qm Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6107
LedOK/ts/app_pt.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff