From 3a7eaae7a81e8002e482975179e15df6bbb91386 Mon Sep 17 00:00:00 2001 From: Gangphon Date: Mon, 23 Oct 2023 14:58:29 +0800 Subject: [PATCH] ledok --- LedOK/base/changepasswordform.cpp | 8 +- LedOK/base/loqtreewidget.cpp | 5 +- LedOK/player/eleanaclock.cpp | 5 +- LedOK/player/eleanaclock.h | 3 +- LedOK/player/elemultipng.cpp | 12 +- LedOK/player/elemultipng.h | 4 +- LedOK/player/elescroll.cpp | 53 +- LedOK/player/elescroll.h | 8 +- LedOK/player/eletimer.cpp | 13 +- LedOK/player/eletimer.h | 21 +- LedOK/player/playwin.cpp | 126 ++--- LedOK/player/playwin.h | 27 +- LedOK/progpanel.cpp | 61 +- LedOK/program/eaclock.cpp | 22 +- LedOK/program/eaclock.h | 4 +- LedOK/program/ebase.cpp | 38 +- LedOK/program/ebase.h | 7 +- LedOK/program/edclock.cpp | 12 +- LedOK/program/edclock.h | 4 +- LedOK/program/eenviron.cpp | 896 ++++++++++++++---------------- LedOK/program/eenviron.h | 67 +-- LedOK/program/egif.cpp | 11 +- LedOK/program/egif.h | 4 +- LedOK/program/emultiwin.cpp | 57 +- LedOK/program/emultiwin.h | 8 +- LedOK/program/ephoto.cpp | 23 +- LedOK/program/ephoto.h | 4 +- LedOK/program/etext.cpp | 45 +- LedOK/program/etext.h | 6 +- LedOK/program/etimer.cpp | 7 +- LedOK/program/etimer.h | 4 +- LedOK/program/evideo.cpp | 25 +- LedOK/program/evideo.h | 6 +- LedOK/program/eweb.cpp | 7 +- LedOK/program/eweb.h | 4 +- LedOK/program/gentmpthread.cpp | 200 ++++--- LedOK/program/gentmpthread.h | 20 +- LedOK/program/pagelistitem.cpp | 271 ++++++--- LedOK/program/pagelistitem.h | 24 +- 39 files changed, 1103 insertions(+), 1019 deletions(-) diff --git a/LedOK/base/changepasswordform.cpp b/LedOK/base/changepasswordform.cpp index 8ca83ad..c8137fe 100644 --- a/LedOK/base/changepasswordform.cpp +++ b/LedOK/base/changepasswordform.cpp @@ -53,16 +53,16 @@ ChangePasswordForm::ChangePasswordForm(QWidget *parent) : QDialog(parent) { return; } QSettings settings; - QString pwdRaw = settings.value("advUiPs").toString(); - QString pwd = pwdRaw.isEmpty() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdRaw.toLatin1())); + auto pwdRaw = settings.value("advUiPs"); + QString pwd = pwdRaw.isNull() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdRaw.toString().toLatin1())); if(pwd != pwdOld) { QMessageBox::critical(this, tr("Tip"), tr("Old password is wrong")); fdOld->setFocus(); return; } QString pwdNew = fdNew->text(); - if(pwdNew.length() < 6) { - QMessageBox::warning(this, tr("Tip"), tr("Please enter a password with more than 6 characters")); + if(pwdNew.length() < 3 && ! pwdNew.isEmpty()) { + QMessageBox::warning(this, tr("Tip"), tr("Please enter a password with more than 3 characters")); fdNew->setFocus(); return; } diff --git a/LedOK/base/loqtreewidget.cpp b/LedOK/base/loqtreewidget.cpp index 9444bc6..c970873 100644 --- a/LedOK/base/loqtreewidget.cpp +++ b/LedOK/base/loqtreewidget.cpp @@ -4,7 +4,10 @@ void LoQTreeWidget::addFd() { fdCheckAll = new QCheckBox(this); connect(fdCheckAll, &QCheckBox::stateChanged, this, [=](int state) { - if(state==Qt::PartiallyChecked) return; + if(state==Qt::PartiallyChecked) { + fdCheckAll->setCheckState(Qt::Checked); + return; + } int cnt = topLevelItemCount(); for(int rr=0; rrisHidden()) topLevelItem(rr)->setCheckState(1, (Qt::CheckState) state); emit selChanged(); diff --git a/LedOK/player/eleanaclock.cpp b/LedOK/player/eleanaclock.cpp index a3d37cb..5c45808 100644 --- a/LedOK/player/eleanaclock.cpp +++ b/LedOK/player/eleanaclock.cpp @@ -1,9 +1,8 @@ #include "eleanaclock.h" -#include #include -EleAnaClock::EleAnaClock(double w, double h, QString path, const QJsonObject &layer, QWidget *parent) : QWidget{parent} { - timeZone = QTimeZone(layer["timezone"].toString().toUtf8()); +EleAnaClock::EleAnaClock(double w, double h, QString path, const JValue &layer, QWidget *parent) : QWidget{parent} { + timeZone = QTimeZone(layer["timeZone"].toString().toUtf8()); img.load(path); pinHourColor = layer["pinHourColor"].toString(); pinMinColor = layer["pinMinColor"].toString(); diff --git a/LedOK/player/eleanaclock.h b/LedOK/player/eleanaclock.h index 71e94d2..06040e6 100644 --- a/LedOK/player/eleanaclock.h +++ b/LedOK/player/eleanaclock.h @@ -1,6 +1,7 @@ #ifndef ELEANACLOCK_H #define ELEANACLOCK_H +#include "gutil/qjson.h" #include #include #include @@ -8,7 +9,7 @@ class EleAnaClock : public QWidget { Q_OBJECT public: - explicit EleAnaClock(double w, double h, QString path, const QJsonObject &layer, QWidget *parent = nullptr); + explicit EleAnaClock(double w, double h, QString path, const JValue &layer, QWidget *parent); void cal(); QTimeZone timeZone; QPixmap img; diff --git a/LedOK/player/elemultipng.cpp b/LedOK/player/elemultipng.cpp index 2ca2bf6..6dd2069 100644 --- a/LedOK/player/elemultipng.cpp +++ b/LedOK/player/elemultipng.cpp @@ -1,17 +1,16 @@ #include "elemultipng.h" -#include -#include #include #include + const QChar effTypes[] = {'l', 't', 'r', 'b'}; -EleMultiPng::EleMultiPng(QString dirPre, QJsonArray maps, QWidget *parent) : QWidget{parent} { - QJsonObject map = maps[0].toObject(); +EleMultiPng::EleMultiPng(QString dirPre, const JValue &maps, QWidget *parent) : QWidget{parent} { + auto map = maps[0]; picDur = map["picDuration"].toInt()*1000; if(picDur==0) return; EffDur = map["effectSpeed"].toInt()*1000; - foreach(QJsonValue map, maps) imgs.append(QPixmap(dirPre+map["id"].toString())); - QString effStr = map["effect"].toString(); + for(auto &map : maps) imgs.append(dirPre+map["id"].toString()); + auto effStr = map["effect"].toString(); if(effStr.isEmpty() || effStr=="no") EffDur = 0; else if(effStr.endsWith("left")) effType = 'l'; else if(effStr.endsWith("top")) effType = 't'; @@ -94,6 +93,7 @@ void EleMultiPng::timerEvent(QTimerEvent *e) { killTimer(moveTimerId); moveTimerId = 0; } + imgc = 0; } } diff --git a/LedOK/player/elemultipng.h b/LedOK/player/elemultipng.h index 7c49466..2344c3f 100644 --- a/LedOK/player/elemultipng.h +++ b/LedOK/player/elemultipng.h @@ -1,13 +1,15 @@ #ifndef ELEMULTIPNG_H #define ELEMULTIPNG_H +#include "gutil/qjson.h" #include #include + class EleSplitPng; class EleMultiPng : public QWidget { Q_OBJECT public: - explicit EleMultiPng(QString, QJsonArray, QWidget *parent = nullptr); + explicit EleMultiPng(QString, const JValue &, QWidget *parent); void startMove(); QVector imgs; diff --git a/LedOK/player/elescroll.cpp b/LedOK/player/elescroll.cpp index b827bfb..6c17fdf 100644 --- a/LedOK/player/elescroll.cpp +++ b/LedOK/player/elescroll.cpp @@ -3,33 +3,39 @@ #include #include -EleScroll::EleScroll(QWidget *parent, QString dirPre, QJsonObject map) : QWidget{parent} { +EleScroll::EleScroll(QWidget *parent, QString dirPre, const JValue &map) : QWidget{parent} { img.load(dirPre + map["id"].toString()); - QString effStr = map["effect"].toString(); - if(effStr.isNull() || effStr=="no") return; + auto effStr = map["effect"].toString(); + if(effStr.isEmpty() || effStr=="no") return; double effDurD = map["effectSpeed"].toInt()/2; if(effDurD==0) return; + auto interva = round(effDurD / 16.666666666666666666); + if(interva==0) interva = 1; + interval = interva * 16.666666666666666666; + step = round(interval / effDurD); + if(step==0) step = 1; int idx = effStr.lastIndexOf(' '); if(idx > -1) { effect = effStr.at(idx+1).toLatin1(); - if(effect=='l') end = -(img.width()-1); - else if(effect=='r') end = img.width()-1; - else if(effect=='t') end = -(img.height()-1); - else if(effect=='b') end = img.height()-1; + if(effect=='l') end = -(img.width()-step); + else if(effect=='r') end = img.width()-step; + else if(effect=='t') end = -(img.height()-step); + else if(effect=='b') end = img.height()-step; } - interval = ceil(effDurD/16.666666)*16.666666; - curAdd = ceil(interval/effDurD); } EleScroll::EleScroll(QWidget *parent, QString imgPath, char effect, double effDur) : QWidget{parent}, effect(effect) { img.load(imgPath); if(effect==0) return; if(effDur==0) return; - if(effect=='l') end = -(img.width()-1); - else if(effect=='r') end = img.width()-1; - else if(effect=='t') end = -(img.height()-1); - else if(effect=='b') end = img.height()-1; - interval = ceil(effDur/16.666666)*16.666666; - curAdd = ceil(interval/effDur); + auto interva = round(effDur / 16.666666666666666666); + if(interva==0) interva = 1; + interval = interva * 16.666666666666666666; + step = round(interval / effDur); + if(step==0) step = 1; + if(effect=='l') end = -(img.width()-step); + else if(effect=='r') end = img.width()-step; + else if(effect=='t') end = -(img.height()-step); + else if(effect=='b') end = img.height()-step; } void EleScroll::paintEvent(QPaintEvent *) { @@ -37,10 +43,7 @@ void EleScroll::paintEvent(QPaintEvent *) { } void EleScroll::paint(QPaintDevice *that) { if(img.isNull()) return; - if(timerId==0 && effect!=0 && interval!=0) { - cur = 0; - timerId = startTimer(interval, Qt::PreciseTimer); - } + if(timerId==0 && effect!=0 && interval!=0) timerId = startTimer(round(interval), Qt::PreciseTimer); QPainter painter(that); painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); if(effect=='l') { @@ -61,17 +64,17 @@ void EleScroll::paint(QPaintDevice *that) { void EleScroll::timerEvent(QTimerEvent *) { if(isVisible()) { if(effect=='t' || effect=='l') { - if(cur <= end) cur = 0; - else cur-=curAdd; + if(cur <= end) cur -= end; + else cur -= step; } else if(effect=='b' || effect=='r') { - if(cur >= end) cur = 0; - else cur+=curAdd; + if(cur >= end) cur -= end; + else cur += step; } update(); - foreach(auto split, splits) split->update(); + for(auto split : splits) split->update(); } else if(timerId!=0) { killTimer(timerId); - timerId = 0; + timerId = cur = 0; } } diff --git a/LedOK/player/elescroll.h b/LedOK/player/elescroll.h index b1be9bf..f139855 100644 --- a/LedOK/player/elescroll.h +++ b/LedOK/player/elescroll.h @@ -1,17 +1,19 @@ #ifndef ELESCROLL_H #define ELESCROLL_H +#include "gutil/qjson.h" #include + class EleSplitScroll; class EleScroll : public QWidget { Q_OBJECT public: - explicit EleScroll(QWidget *, QString, QJsonObject); + explicit EleScroll(QWidget *, QString, const JValue &); explicit EleScroll(QWidget *, QString, char effect = 0, double effDur = 0.0); QPixmap img; char effect = 0; - int interval = 0, timerId = 0, cur = 0, end = 0, curAdd = 1; - QList splits; + int interval = 0, timerId = 0, cur = 0, end = 0, step = 1; + std::vector splits; void paint(QPaintDevice *); protected: void paintEvent(QPaintEvent *) override; diff --git a/LedOK/player/eletimer.cpp b/LedOK/player/eletimer.cpp index e496fa3..fcb9197 100644 --- a/LedOK/player/eletimer.cpp +++ b/LedOK/player/eletimer.cpp @@ -2,16 +2,15 @@ #include "tools.h" #include "globaldefine.h" #include -#include -EleTimer::EleTimer(const QJsonObject &json, QWidget *parent) : QWidget{parent} { +EleTimer::EleTimer(const JValue &json, QWidget *parent) : QWidget{parent} { isDown = json["isDown"].toBool(); targetTime = QDateTime::fromString(json["targetTime"].toString(), "yyyy-MM-dd HH:mm:ss"); hasDay = json["hasDay"].toBool(); hasHour = json["hasHour"].toBool(); hasMin = json["hasMin"].toBool(); hasSec = json["hasSec"].toBool(); - text = json["text"].toString(); + title = json["text"].toString(); isMultiline = json["isMultiline"].toBool(); font = QFont(json["font"].toString()); font.setPixelSize(json["fontSize"].toInt()); @@ -33,12 +32,8 @@ EleTimer::EleTimer(const QJsonObject &json, QWidget *parent) : QWidget{parent} { } void EleTimer::paintEvent(QPaintEvent *){ - QString text; - if(! this->text.isEmpty()) { - text += this->text; - if(isMultiline) text += '\n'; - else text += " "; - } + auto text = this->title; + if(! text.isEmpty()) text += isMultiline ? '\n' : ' '; int secs = this->secs; if(hasDay) { text.append(QString::number(secs/86400)).append(" ").append(tr("day")).append(" "); diff --git a/LedOK/player/eletimer.h b/LedOK/player/eletimer.h index 9711439..f4c2498 100644 --- a/LedOK/player/eletimer.h +++ b/LedOK/player/eletimer.h @@ -1,24 +1,25 @@ #ifndef ELETIMER_H #define ELETIMER_H +#include "gutil/qjson.h" #include #include class EleTimer : public QWidget { Q_OBJECT public: - explicit EleTimer(const QJsonObject&, QWidget *parent = 0); + explicit EleTimer(const JValue &, QWidget *parent = 0); QDateTime targetTime; - QString text; - QColor textColor; - QColor backColor; + QString title; + QColor textColor; + QColor backColor; QFont font; - bool isDown; - bool isMultiline; - bool hasDay; - bool hasHour; - bool hasMin; - bool hasSec; + bool isDown; + bool isMultiline; + bool hasDay; + bool hasHour; + bool hasMin; + bool hasSec; int secs = 0; protected: void paintEvent(QPaintEvent *) override; diff --git a/LedOK/player/playwin.cpp b/LedOK/player/playwin.cpp index da1ce49..7193c7d 100644 --- a/LedOK/player/playwin.cpp +++ b/LedOK/player/playwin.cpp @@ -1,17 +1,14 @@ #include "playwin.h" -#include "digiclock.h" +#include "eledigiclock.h" #include "eleanaclock.h" #include "eleborder.h" #include "elegif.h" -#include "eleimg.h" #include "elemultipng.h" #include "elescroll.h" #include "eletimer.h" #include "elevideo.h" #include "posdlg.h" #include -#include -#include #include #include #include @@ -26,12 +23,12 @@ Page::Page(QWidget *parent) : QWidget{parent} { } -PlayWin *PlayWin::newIns(int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) { +PlayWin *PlayWin::newIns(int width, int height, QString dir, const JValue &aprog, QWidget *parent) { if(! gPlayPos.isNull() && QGuiApplication::screenAt(QPoint(gPlayPos.x()+width/2, gPlayPos.y()+height/2))==0) gPlayPos = QPoint(); return new PlayWin(gPlayPos.x(), gPlayPos.y(), width, height, dir, aprog, parent); } -PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) : QWidget(parent) { +PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const JValue &aprog, QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_QuitOnClose, false); setWindowFlag(Qt::FramelessWindowHint); @@ -42,82 +39,86 @@ PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonOb setPalette(plt); connect(this, &PlayWin::sigSetVisible, this, &PlayWin::sltSetVisible); - const auto pageMaps = aprog["task"]["items"].toArray(); - int pageCnt = pageMaps.size(); + auto pageMaps = aprog["task"]["items"]; EleBase ele; Page *page; - for(int p=0; psetGeometry(0, 0, width, height); page->setVisible(false); - for(int ll=layers.size()-1; ll>=0; ll--) { - auto layer = layers[ll].toObject(); + for(int ll=(int)layers.size()-1; ll>=0; ll--) { + auto layer = layers[ll].toObj(); auto repeat = layer["repeat"].toBool(); - auto srcMaps = layer["sources"].toArray(); - QJsonValue border = layer["border"]; + auto sources = layer["sources"]; + auto border = layer["border"]; EleBorder *bdEle = 0; int bdWidth = 0, bdStart = 0xffff, bdEnd = 0; if(! border.isNull()) { bdEle = new EleBorder(dir+"/"+border["img"].toString(), border["eff"].toString(), border["speed"].toInt(), page); bdWidth = bdEle->img.height(); } - foreach(QJsonValue srcMap, srcMaps) { - ele.type = srcMap["_type"].toString(); + for(auto &source : sources) { + ele.type = source["_type"].toString(); if(ele.type.isEmpty()) continue; - auto timeSpan = srcMap["timeSpan"].toInt()*1000; + auto timeSpan = source["timeSpan"].toInt()*1000; if(timeSpan==0) continue; - ele.x = srcMap["left"].toInt()+bdWidth; - ele.y = srcMap["top"].toInt()+bdWidth; - ele.w = srcMap["width"].toInt()-bdWidth-bdWidth; - ele.h = srcMap["height"].toInt()-bdWidth-bdWidth; + ele.x = source["left"].toInt()+bdWidth; + ele.y = source["top"].toInt()+bdWidth; + ele.w = source["width"].toInt()-bdWidth-bdWidth; + ele.h = source["height"].toInt()-bdWidth-bdWidth; bool notAudio = ele.type!="Audio"; if((ele.w<=0 || ele.h<=0) && notAudio) continue; ele.repeat = repeat; - ele.startTime = srcMap["playTime"].toInt()*1000; + ele.startTime = source["playTime"].toInt()*1000; if(bdStart > ele.startTime) bdStart = ele.startTime; ele.endTime = ele.startTime + timeSpan; if(bdEnd < ele.endTime) bdEnd = ele.endTime; if(page->timeSpan < ele.endTime && notAudio) page->timeSpan = ele.endTime; - ele.id = srcMap["id"].toString(); + ele.id = source["id"].toString(); ele.wgt = 0; if(ele.type=="Image") { - if(srcMap["mime"].toString().endsWith("gif")) ele.wgt = new EleGif(dir+"/"+ele.id, page); - else ele.wgt = new EleImg(dir+"/"+ele.id, page); + if(source["mime"].toString().endsWith("gif")) ele.wgt = new EleGif(dir+"/"+ele.id, page); + else { + auto lb = new QLabel(page); + lb->setPixmap(QPixmap(dir+"/"+ele.id)); + lb->setScaledContents(true); + ele.wgt = lb; + } } else if(ele.type.startsWith("Environ")) { - QJsonValue arrayPics = srcMap["arrayPics"]; - for(int i=arrayPics.toArray().size()-1; i>=0; i--) if(arrayPics[i]["name"].toString() == "previewTmp") { - if(srcMap["bSingleScroll"].toBool()) ele.wgt = new EleScroll(page, dir+"/" + arrayPics[i]["id"].toString(), 'l', srcMap["iScrollSpeed"].toDouble()); + auto arrayPics = source["arrayPics"]; + for(int i=(int)arrayPics.size()-1; i>=0; i--) if(arrayPics[i]["name"].toString() == "previewTmp") { + if(source["bSingleScroll"].toBool()) ele.wgt = new EleScroll(page, dir+"/" + arrayPics[i]["id"].toString(), 'l', source["iScrollSpeed"].toDouble()); else ele.wgt = new EleScroll(page, dir+"/"+arrayPics[i]["id"].toString()); break; } } else if(ele.type=="MultiPng") { - QJsonArray imgs = srcMap["arrayPics"].toArray(); - if(imgs.isEmpty()) continue; - if(imgs.size()==1 && imgs.at(0)["picDuration"].toInt()==0) ele.wgt = new EleScroll(page, dir+"/", imgs[0].toObject()); + auto imgs = source["arrayPics"]; + if(imgs.empty()) continue; + if(imgs.size()==1 && imgs[0]["picDuration"].toInt()==0) ele.wgt = new EleScroll(page, dir+"/", imgs[0]); else ele.wgt = new EleMultiPng(dir+"/", imgs, page); } else if(ele.type=="SplitText") { - QJsonArray imgs = srcMap["arrayPics"].toArray(); - if(imgs.isEmpty()) continue; + auto imgs = source["arrayPics"]; + if(imgs.empty()) continue; ele.wgt = new QWidget(page); ele.wgt->setGeometry(0, 0, width, height); auto height = _program["height"].toInt(); - if(imgs.size()==1 && imgs.at(0)["picDuration"].toInt()==0) { - auto wgt = new EleScroll(ele.wgt, dir+"/", imgs[0].toObject()); + if(imgs.size()==1 && imgs[0]["picDuration"].toInt()==0) { + auto wgt = new EleScroll(ele.wgt, dir+"/", imgs[0]); wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); - for(int i=1; isetGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h); - wgt->splits.append(split); + wgt->splits.emplace_back(split); } } else { auto wgt = new EleMultiPng(dir+"/", imgs, ele.wgt); wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); - for(int i=1; iplayer->setVol(vol/100.0); ele.wgt = video; } else if(ele.type=="WebURL") { auto web = new QWebEngineView(page); - web->load(QUrl(srcMap["url"].toString())); + web->load(QUrl(source["url"].toString())); ele.wgt = web; } - else if(ele.type=="Timer") ele.wgt = new EleTimer(srcMap.toObject(), page); + else if(ele.type=="Timer") ele.wgt = new EleTimer(source, page); else continue; if(ele.wgt==0) continue; if(ele.startTime>0) ele.wgt->setVisible(false); if(ele.w) ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); - page->eles.append(ele); + page->eles.emplace_back(ele); } - if(bdEle && ! srcMaps.isEmpty()) { - QJsonArray geometry = border["geometry"].toArray(); + if(bdEle && ! sources.empty()) { + auto geometry = border["geometry"]; ele.x = geometry[0].toInt(); ele.y = geometry[1].toInt(); ele.w = geometry[2].toInt(); @@ -156,21 +157,17 @@ PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonOb ele.wgt = bdEle; if(ele.startTime>0) ele.wgt->setVisible(false); ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); - page->eles.append(ele); + page->eles.emplace_back(ele); } } if(page->timeSpan==0) continue; for(int i=0; ieles.size(); i++) if(page->eles[i].repeat) page->eles[i].endTime = page->timeSpan; - pages.append(page); + pages.emplace_back(page); } setVisible(true); - if(! pages.isEmpty()) { - Page* page0 = pages[0]; - EleBase* eleptr; - for(int ee=0; eeeles.size(); ee++) if((eleptr = &page0->eles[ee])->startTime > 0 || eleptr->endTime < page0->timeSpan) { - if(eleptr->startTime > 0) timerMap.insert(startTimer(eleptr->startTime), TimerValue(eleptr->wgt, true)); - timerMap.insert(startTimer(eleptr->endTime), TimerValue(eleptr->wgt, false)); - } + if(! pages.empty()) for(auto& ele : pages[0]->eles) if(ele.startTime > 0 || ele.endTime < pages[0]->timeSpan) { + if(ele.startTime > 0) timerMap.insert(startTimer(ele.startTime), TimerValue(ele.wgt, true)); + timerMap.insert(startTimer(ele.endTime), TimerValue(ele.wgt, false)); } menu = new QMenu(this); @@ -194,13 +191,12 @@ void PlayWin::sltNext() { pages[cur]->setVisible(false); if(cur+2 > pages.size()) cur = 0; else cur++; - Page* page = pages[cur]; + auto page = pages[cur]; if(timer) timer->inter = page->timeSpan; - EleBase* ele; - for(int ee=0; eeeles.size(); ee++) if((ele = &page->eles[ee])->startTime > 0 || ele->endTime < page->timeSpan) { - if(ele->startTime > 0) timerMap.insert(startTimer(ele->startTime), TimerValue(ele->wgt, true)); - else ele->wgt->setVisible(true); - timerMap.insert(startTimer(ele->endTime), TimerValue(ele->wgt, false)); + for(auto &ele : page->eles) if(ele.startTime > 0 || ele.endTime < page->timeSpan) { + if(ele.startTime > 0) timerMap.insert(startTimer(ele.startTime), TimerValue(ele.wgt, true)); + else ele.wgt->setVisible(true); + timerMap.insert(startTimer(ele.endTime), TimerValue(ele.wgt, false)); } page->setVisible(true); } else if(timer) { @@ -218,7 +214,7 @@ void PlayWin::timerEvent(QTimerEvent *e){ } } void PlayWin::paintEvent(QPaintEvent *e){ - if(timer==0 && isVisible() && ! pages.isEmpty()) { + if(timer==0 && isVisible() && ! pages.empty()) { if(cur!=0) { pages[cur]->setVisible(false); cur = 0; diff --git a/LedOK/player/playwin.h b/LedOK/player/playwin.h index 01296bf..c125375 100644 --- a/LedOK/player/playwin.h +++ b/LedOK/player/playwin.h @@ -1,17 +1,30 @@ #ifndef PLAYWIN_H #define PLAYWIN_H -#include "elebase.h" +#include "gutil/qjson.h" #include "synctimer.h" -#include #include -#include #include +class EleBase { +public: + QString id; + QString type; + int x; + int y; + int w; + int h; + int startTime; + int endTime; + bool repeat; + + QWidget *wgt{0}; +}; + class Page : public QWidget { public: explicit Page(QWidget *parent = nullptr); int timeSpan{0}; - QVector eles; + std::vector eles; }; class TimerValue{ @@ -25,12 +38,12 @@ class PlayWin : public QWidget { Q_OBJECT public: static PlayWin *self; - static PlayWin *newIns(int width, int height, QString dir, const QJsonObject &prog, QWidget *parent = nullptr); - PlayWin(int x, int y, int width, int height, QString dir, const QJsonObject &prog, QWidget *parent = nullptr); + static PlayWin *newIns(int width, int height, QString dir, const JValue &prog, QWidget *parent = nullptr); + PlayWin(int x, int y, int width, int height, QString dir, const JValue &prog, QWidget *parent = nullptr); SyncTimer* timer = 0; int cur = 0; - QVector pages; + std::vector pages; QMap timerMap; QPoint mPressRel; QMenu *menu; diff --git a/LedOK/progpanel.cpp b/LedOK/progpanel.cpp index 00d7ef7..9a9ca07 100644 --- a/LedOK/progpanel.cpp +++ b/LedOK/progpanel.cpp @@ -6,7 +6,6 @@ #include "program/progeditorwin.h" #include "program/copydirthread.h" #include -#include #include #include #include @@ -36,27 +35,35 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { ProgCreateDlg dlg("", 512, 256, "", "", this); if(dlg.exec() != QDialog::Accepted) return; if(checkIfNameRepeated(dlg.fdName->text())) return; - auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); - QList widths; int max = 0, ttl = 0; + QList widths; + int max = 0; auto width = dlg.fdWidth->value(); - foreach(auto splitWidth, splitWidths) { - int val = splitWidth.toInt(); - if(val==0) continue; - if(max < val) max = val; - widths.append(val); - ttl += val; - if(ttl>=width) break; - } - if(max) { - while(ttl < width) { - widths.append(max); - ttl += max; + if(dlg.fdIsUltraLong->isChecked()) { + auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); + int ttl = 0; + for(auto &splitWidth : splitWidths) { + int val = splitWidth.toInt(); + if(val==0) continue; + if(max < val) max = val; + widths.append(val); + ttl += val; + if(ttl>=width) break; + } + if(max) { + while(ttl < width) { + widths.append(max); + ttl += max; + } + if(ttl > width) widths.last() -= ttl - width; } - if(ttl > width) widths.last() -= ttl - width; } auto item = new ProgItem(mProgsDir, dlg.fdName->text(), width, dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, mProgTree); item->save();//保存pro.json - if(mProgTree->fdCheckAll->checkState()==Qt::Checked) mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked); + if(mProgTree->fdCheckAll->checkState()==Qt::Checked) { + mProgTree->fdCheckAll->blockSignals(true); + mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked); + mProgTree->fdCheckAll->blockSignals(false); + } auto editor = new ProgEditorWin(item, this); editor->show(); }); @@ -185,14 +192,14 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { int cnt = mProgTree->topLevelItemCount(); for(int i=0; iitem(i)->checkState("check") == Qt::Checked) { auto item = (ProgItem*) mProgTree->topLevelItem(i); - QString dir = mProgsDir+"/"+item->mName+"_tmp"; + auto dir = mProgsDir+"/"+item->mName+"_tmp"; QFile file(dir+"/program"); if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return; - QString value = file.readAll(); + auto value = file.readAll(); file.close(); - QJsonParseError jsErr; - QJsonObject prog = QJsonDocument::fromJson(value.toUtf8(), &jsErr).object(); - if(jsErr.error) return; + QString jsErr; + auto prog = JFrom(value, &jsErr); + if(! jsErr.isEmpty()) return; if(item->mSplitWidths.isEmpty()) PlayWin::self = PlayWin::newIns(item->mWidth, item->mHeight, dir, prog); else PlayWin::self = PlayWin::newIns(item->mMaxWidth, item->mHeight * item->mSplitWidths.size(), dir, prog); break; @@ -249,7 +256,6 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { if(!QFileInfo::exists(mProgsDir)) QDir(app_path).mkdir("NPrograms"); } - //connect(search, SIGNAL(triggered(bool)), this, SLOT(FilterProgram())); //查找根路径下的项目文件夹,查找文件夹下的节目pro.json信息,包括节目名称,大小,像素,备注等信息 if(!mProgsDir.isEmpty()) { QDir root_dir(mProgsDir); @@ -321,15 +327,18 @@ void ProgPanel::onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize re if(checkIfNameRepeated(name)) return; auto item = new ProgItem(mProgsDir, name, res.width(), res.height(), remarks, splitWidths, max, mProgTree); item->save();//保存pro.json - if(mProgTree->fdCheckAll->checkState()==Qt::Checked) mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked); + if(mProgTree->fdCheckAll->checkState()==Qt::Checked) { + mProgTree->fdCheckAll->blockSignals(true); + mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked); + mProgTree->fdCheckAll->blockSignals(false); + } auto editor = new ProgEditorWin(item, this); editor->show(); } 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); if(res == QMessageBox::Ok) { - int cnt = mProgTree->topLevelItemCount(); - for(int i=0; iitem(i)->checkState("check") == Qt::Checked) { + for(int i=0; itopLevelItemCount(); i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) { auto item = (ProgItem*) mProgTree->topLevelItem(i--); item->del(); delete item; diff --git a/LedOK/program/eaclock.cpp b/LedOK/program/eaclock.cpp index 534e092..d68d169 100644 --- a/LedOK/program/eaclock.cpp +++ b/LedOK/program/eaclock.cpp @@ -23,7 +23,7 @@ EAClock::EAClock(EBase *multiWin) : EBase(multiWin) { m_attr.textColor = Qt::red; } -EAClock::EAClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) { +EAClock::EAClock(const JObj &json, EBase *multiWin) : EBase(multiWin) { mType = EBase::AClock; setBaseAttr(json); auto widget = json["widget"]; @@ -31,19 +31,19 @@ EAClock::EAClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) { m_attr.hourMark = widget["hourMark"].toInt(); m_attr.hourMarkSize = widget["hourMarkSize"].toInt(); auto color = widget["hourMarkColor"]; - m_attr.hourMarkColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); + m_attr.hourMarkColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); m_attr.minMark = widget["minMark"].toInt(); m_attr.minMarkSize = widget["minMarkSize"].toInt(); color = widget["minMarkColor"]; - m_attr.minMarkColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); + m_attr.minMarkColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); color = widget["hourHandColor"]; - m_attr.hourHandColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); + m_attr.hourHandColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); color = widget["minHandColor"]; - m_attr.minHandColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); + m_attr.minHandColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); color = widget["secHandColor"]; - m_attr.secHandColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); + m_attr.secHandColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); color = widget["textColor"]; - m_attr.textColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); + m_attr.textColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt()); m_attr.text = widget["text"].toString(); m_attr.textFont = QFont(widget["textFontFamily"].toString()); m_attr.textFont.setPixelSize(widget["textFontSize"].toInt()); @@ -663,11 +663,11 @@ bool EAClock::save(const QString &pRoot){ img.save(pRoot+"/"+m_attr.selfCreateDialName, "PNG"); return true; } -QJsonObject EAClock::attrJson() const { - QJsonObject json; +JObj EAClock::attrJson() const { + JObj json; addBaseAttr(json); json["elementType"] = "AClock"; - QJsonObject widget; + JObj widget; widget["timeZone"] = QString::fromUtf8(m_attr.timeZone.id()); widget["hourMark"] = m_attr.hourMark; widget["hourMarkSize"] = m_attr.hourMarkSize; @@ -697,6 +697,6 @@ QJsonObject EAClock::attrJson() const { widget["selfCreateDialName"] = m_attr.selfCreateDialName; widget["bCustomDial"] = m_attr.hasDialImg; json["widget"] = widget; - json["play"] = QJsonObject{{"duration", m_attr.playDuration}}; + json["play"] = JObj{{"duration", m_attr.playDuration}}; return json; } diff --git a/LedOK/program/eaclock.h b/LedOK/program/eaclock.h index b1246af..3fe1e8f 100644 --- a/LedOK/program/eaclock.h +++ b/LedOK/program/eaclock.h @@ -36,13 +36,13 @@ public: }; explicit EAClock(EBase *multiWin = nullptr); - explicit EAClock(const QJsonObject &json, EBase *multiWin = nullptr); + explicit EAClock(const JObj &json, EBase *multiWin = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; int type() const override { return EBase::AClock; } QWidget* attrWgt() override; bool save(const QString &pRoot) override; - QJsonObject attrJson() const override; + JObj attrJson() const override; protected: void timerEvent(QTimerEvent *) override; diff --git a/LedOK/program/ebase.cpp b/LedOK/program/ebase.cpp index b99b6a0..365b503 100644 --- a/LedOK/program/ebase.cpp +++ b/LedOK/program/ebase.cpp @@ -41,35 +41,28 @@ EBase::EBase(EBase *multiWin) : mMultiWin(multiWin) { mSidePen.setDashPattern(QVector{1,3}); } -void EBase::setBaseAttr(const QJsonObject &json) { +void EBase::setBaseAttr(const JObj &json) { mStartTime = json["startTime"].toInt(); - auto geometry = json["geometry"].toObject(); + auto geometry = json["geometry"]; setPos(geometry["x"].toInt(), geometry["y"].toInt()); setSize(geometry["w"].toInt(), geometry["h"].toInt()); setZValue(geometry["order"].toInt()); - QString bdName = json["border"].toString(); + auto bdName = json["border"].toString(); if(! bdName.isEmpty()) { for(int i=0; ibdImgIdx > -1 ? borderImgs[ele->bdImgIdx].img.height() : 0; obj.insert("startTime", mStartTime); obj.insert("innerX", ((int)ele->x())+bdWidth); obj.insert("innerY", ((int)ele->y())+bdWidth); obj.insert("innerW", ((int)ele->mWidth)-bdWidth-bdWidth); obj.insert("innerH", ((int)ele->mHeight)-bdWidth-bdWidth); - QJsonObject geometry; + JObj geometry; geometry["order"] = zValue(); geometry["x"] = (int)ele->x(); geometry["y"] = (int)ele->y(); @@ -77,12 +70,9 @@ void EBase::addBaseAttr(QJsonObject &obj) const { geometry["h"] = (int)ele->mHeight; if(bdImgIdx>-1) { obj["border"] = borderImgs[bdImgIdx].name; - obj["borderSize"] = QJsonArray{borderImgs[bdImgIdx].img.width(), borderImgs[bdImgIdx].img.height()}; - obj["borderEff"] = bdEff.isEmpty() ? QJsonValue() : bdEff; + obj["borderSize"] = JArray{borderImgs[bdImgIdx].img.width(), borderImgs[bdImgIdx].img.height()}; + obj["borderEff"] = bdEff.isEmpty() ? JValue() : bdEff; obj["borderSpeed"] = bdSpeed; -// geometry["border"] = borderImgs[bdImgIdx].name; -// geometry["border_eff"] = bdEff.isEmpty() ? QJsonValue() : bdEff; -// geometry["border_speed"] = bdSpeed; } obj.insert("geometry", geometry); } @@ -538,7 +528,7 @@ void EBase::addBaseAttrWgt(QBoxLayout *vBox) { hBox->addWidget(new QLabel(tr("X")+": ")); auto fdX = new QSpinBox(); - fdX->setRange(0, 9999); + fdX->setRange(0, 999999); fdX->setValue(x()); connect(fdX, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdX](int value) { int max = gProgItem->mWidth - mWidth; @@ -556,7 +546,7 @@ void EBase::addBaseAttrWgt(QBoxLayout *vBox) { hBox->addWidget(new QLabel(tr("Y")+": ")); auto fdY = new QSpinBox(); - fdY->setRange(0, 9999); + fdY->setRange(0, 999999); fdY->setValue(y()); connect(fdY, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdY](int value) { int max = gProgItem->mHeight - mHeight; @@ -577,7 +567,7 @@ void EBase::addBaseAttrWgt(QBoxLayout *vBox) { hBox->addStretch(); hBox->addWidget(new QLabel(tr("W")+": ")); auto fdW = new QSpinBox(); - fdW->setRange(6, 9999); + fdW->setRange(6, 999999); fdW->setValue(mWidth); connect(fdW, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdW](int value) { int max = gProgItem->mWidth - x(); @@ -594,7 +584,7 @@ void EBase::addBaseAttrWgt(QBoxLayout *vBox) { hBox->addSpacing(10); hBox->addWidget(new QLabel(tr("H")+": ")); auto fdH = new QSpinBox(); - fdH->setRange(6, 9999); + fdH->setRange(6, 999999); fdH->setValue(mHeight); connect(fdH, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdH](int value) { int max = gProgItem->mHeight - y(); @@ -669,7 +659,7 @@ void EBase::addBaseAttrWgt(QBoxLayout *vBox) { borderEffFd->addItem(tr("Rotate"), "rotate"); borderEffFd->addItem(tr("Blink"), "blink"); borderEffFd->addItem(tr("None"), ""); - if(bdImgIdx>-1) setCurrentData(borderEffFd, bdEff); + if(bdImgIdx>-1) SetCurData(borderEffFd, bdEff); connect(borderEffFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderEffFd] { bdEff = borderEffFd->currentData().toString(); if(bdTimerId>0) { @@ -687,7 +677,7 @@ void EBase::addBaseAttrWgt(QBoxLayout *vBox) { borderSpeedFd->addItem(tr("Slow"), 1); borderSpeedFd->addItem(tr("Moderate"), 2); borderSpeedFd->addItem(tr("Fast"), 3); - if(bdImgIdx>-1) setCurrentData(borderSpeedFd, bdSpeed); + if(bdImgIdx>-1) SetCurData(borderSpeedFd, bdSpeed); connect(borderSpeedFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderSpeedFd] { bdSpeed = borderSpeedFd->currentData().toInt(); if(bdTimerId>0) { diff --git a/LedOK/program/ebase.h b/LedOK/program/ebase.h index 9d74eb3..1488eb4 100644 --- a/LedOK/program/ebase.h +++ b/LedOK/program/ebase.h @@ -2,6 +2,7 @@ #define EBASE_H #include +#include "gutil/qjson.h" #include #include #include @@ -19,13 +20,13 @@ public: explicit EBase(EBase *multiWin = nullptr); - void setBaseAttr(const QJsonObject &); - void addBaseAttr(QJsonObject &) const; + void setBaseAttr(const JObj &); + void addBaseAttr(JObj &) const; QRectF boundingRect() const override; void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override; - virtual QJsonObject attrJson() const = 0; + virtual JObj attrJson() const = 0; virtual void loadFiles() {} virtual void freeFiles() {} virtual bool save(const QString &) {return true;} diff --git a/LedOK/program/edclock.cpp b/LedOK/program/edclock.cpp index eede39f..8c3dc98 100644 --- a/LedOK/program/edclock.cpp +++ b/LedOK/program/edclock.cpp @@ -30,7 +30,7 @@ EDClock::EDClock(EBase *multiWin) : EBase(multiWin) { init(); } -EDClock::EDClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) { +EDClock::EDClock(const JObj &json, EBase *multiWin) : EBase(multiWin) { mType = EBase::DClock; setBaseAttr(json); auto widget = json["widget"]; @@ -452,8 +452,8 @@ QWidget* EDClock::attrWgt() { return wgtAttr; } -QJsonObject EDClock::attrJson() const{ - QJsonObject oWidget; +JObj EDClock::attrJson() const{ + JObj oWidget; oWidget["timeZone"] = QString::fromUtf8(m_attr.timeZoneId); oWidget["year"] = m_attr.year; oWidget["month"] = m_attr.month; @@ -468,7 +468,7 @@ QJsonObject EDClock::attrJson() const{ oWidget["dateStyle"] = m_attr.dateStyle; oWidget["timeStyle"] = m_attr.timeStyle; oWidget["multiline"] = m_attr.multiline; - oWidget["font"] = QJsonObject{ + oWidget["font"] = JObj{ {"family", m_attr.font.family()}, {"size", m_attr.font.pixelSize()}, {"bold", m_attr.font.bold()}, @@ -476,10 +476,10 @@ QJsonObject EDClock::attrJson() const{ {"underline", m_attr.font.underline()}, {"color", Tools::color2Int(m_attr.textColor)} }; - QJsonObject oRoot; + JObj oRoot; addBaseAttr(oRoot); oRoot["elementType"] = "DClock"; oRoot["widget"] = oWidget; - oRoot["play"] = QJsonObject{{"duration", m_attr.playDuration}}; + oRoot["play"] = JObj{{"duration", m_attr.playDuration}}; return oRoot; } diff --git a/LedOK/program/edclock.h b/LedOK/program/edclock.h index fbce201..1f66d26 100644 --- a/LedOK/program/edclock.h +++ b/LedOK/program/edclock.h @@ -33,12 +33,12 @@ public: }; explicit EDClock(EBase *multiWin = nullptr); - explicit EDClock(const QJsonObject &json, EBase *multiWin = nullptr); + explicit EDClock(const JObj &json, EBase *multiWin = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; int type() const override { return EBase::DClock; } QWidget* attrWgt() override; - QJsonObject attrJson() const override; + JObj attrJson() const override; private: void init(); diff --git a/LedOK/program/eenviron.cpp b/LedOK/program/eenviron.cpp index ee4b7d4..4a94bfa 100644 --- a/LedOK/program/eenviron.cpp +++ b/LedOK/program/eenviron.cpp @@ -2,7 +2,6 @@ #include "base/locolorselector.h" #include "globaldefine.h" #include "tools.h" -#include "gutil/qgui.h" #include #include #include @@ -15,204 +14,302 @@ #include #include -QJsonObject EEnviron::genProg(const QJsonObject &json, const QString &dstDir, const QString &srcPageDir) { - auto widget = json["widget"]; - QJsonObject oRes; - oRes["_type"] = "EnvironmentalMonitoring"; - oRes["name"] = "EnvironmentalMonitoring"; - oRes["id"] = ""; - oRes["timeSpan"] = json["play"]["duration"].toInt(); - oRes["alignType"] = widget["alignType"].toInt(); - oRes["bHumidity"] = widget["bHumidity"].toBool(); - oRes["bNoise"] = widget["bNoise"].toBool(); - oRes["bPM10"] = widget["bPM10"].toBool(); - oRes["bPM25"] = widget["bPM25"].toBool(); - oRes["bTemperature"] = widget["bTemperature"].toBool(); - auto title = widget["labelTitle"].toString(); - oRes["bTitle"] = ! title.isEmpty(); - oRes["bWindDirection"] = widget["bWindDirection"].toBool(); - oRes["bWindSpeed"] = widget["bWindSpeed"].toBool(); - oRes["temperatureCompensation"] = widget["temperatureCompensation"].toInt(); - oRes["temperatureStyle"] = widget["temperatureStyle"].toInt(); - oRes["bgColor"] = widget["cBackground"].toInt(); - oRes["bSingleScroll"] = widget["bPaomadeng"].toBool(); - oRes["iScrollSpeed"] = widget["scrollSpeed"].toInt(); +JObj EEnviron::genProg(const JObj &json, const QString &dstDir, const QString &srcPageDir) { + JObj res; + res["_type"] = "EnvironmentalMonitoring"; + res["name"] = "EnvironmentalMonitoring"; + res["id"] = ""; + const auto items = json["items"].toObj(); + if(! items.empty()) { + auto title = json["title"].toString(); + res["bTitle"] = ! title.isEmpty(); + res["bTemperature"] = items["temp"]["has"]; + res["temperatureCompensation"] = json["tempCompen"]; + res["temperatureStyle"] = json["useFahrenheit"].toInt(); + res["bHumidity"] = items["humidity"]["has"]; + res["bNoise"] = items["noise"]["has"]; + res["bWindSpeed"] = items["windSpeed"]["has"]; + res["bWindDirection"] = items["windDirection"]["has"]; + res["bPM25"] = items["PM2.5"]["has"]; + res["bPM10"] = items["PM10"]["has"]; + for(auto item = items.find("SO₂"); item!=items.end(); ++item) res["has"+item->first.left(1).toUpper()+item->first.mid(1)] = item->second["has"]; + res["backColor"] = json["backColor"]; + res["bgColor"] = Tools::color2Int(json["backColor"].toString()); + res["bSingleScroll"] = json["isSingleLine"]; + res["iScrollSpeed"] = json["scrollSpeed"]; + res["timeSpan"] = json["duration"]; + res["alignType"] = json["align"]; - auto textColor = Tools::int2Color(widget["textColor"].toInt()); - auto font = qfont(widget["fontFamily"].toString(), widget["fontSize"].toInt(), widget["fontBold"].toBool(), widget["fontItalics"].toBool()); - font.setUnderline(widget["fontUnderline"].toBool()); - font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); - QFontMetricsF metricF(font); - oRes["spaceWidth"] = metricF.horizontalAdvance(" "); - QFontMetrics metric(font); - QColor color(textColor); - QJsonArray imgs; - for(auto str : str0_9) Tools::saveImg2(dstDir, metric, font, color, imgs, str, str); - Tools::saveImg2(dstDir, metric, font, color, imgs, title, "labeltitle"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelTemperature"].toString(), "labeltemperature"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelHumidity"].toString(), "labelhumidity"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelNoise"].toString(), "labelnoise"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelWindSpeed"].toString(), "labelwindSpeed"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelWindDirection"].toString(), "labelwindDirection"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelPM25"].toString(), "labelpm25"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelPM10"].toString(), "labelpm10"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "℃", "unit_celsius"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "℉", "unit_fahrenheit"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "%", "unit_humidity"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "dB", "unit_noise"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "m/s", "unit_windspeed"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm10"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm25"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "minus_sign"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north"), "N"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("east")+tr("north"), "NNE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("north"), "NE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("north"), "ENE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east"), "E"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("south"), "ESE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("south"), "SE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("east")+tr("south"), "SSE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south"), "S"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("west")+tr("south"), "SSW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("south"), "SW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("south"), "WSW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west"), "W"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("north"), "WNW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("north"), "NW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("west")+tr("north"), "NNW"); + QColor textColor = json["textColor"].toString(); + auto font = qfont(json["fontFamily"].toString(), json["fontSize"].toInt(), json["fontBold"].toBool(), json["fontItalic"].toBool()); + font.setUnderline(json["fontUnderline"].toBool()); + font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); + QFontMetricsF metricF(font); + res["spaceWidth"] = metricF.horizontalAdvance(" "); + QFontMetrics metric(font); + QColor color(textColor); + JArray imgs; + for(auto str : str0_9) Tools::saveImg2(dstDir, metric, font, color, imgs, str, str); - QJsonObject arrayPic; - arrayPic["name"] = "previewTmp"; - QString srcFile = srcPageDir+"/previewTmp.png"; - QFile srcQFile(srcFile); - if(srcQFile.exists()) { - QString id = Tools::fileMd5(srcFile); - srcQFile.copy(dstDir+"/"+id); - arrayPic["id"] = id; + Tools::saveImg2(dstDir, metric, font, color, imgs, title, "labeltitle"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["temp"]["label"].toString(), "labeltemperature"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["humidity"]["label"].toString(), "labelhumidity"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["noise"]["label"].toString(), "labelnoise"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["windSpeed"]["label"].toString(), "labelwindSpeed"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["windDirection"]["label"].toString(), "labelwindDirection"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["PM2.5"]["label"].toString(), "labelpm25"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["PM10"]["label"].toString(), "labelpm10"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["SO₂"]["label"].toString(), "label_SO₂"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["NO₂"]["label"].toString(), "label_NO₂"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["CO"]["label"].toString(), "label_CO"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["O₃"]["label"].toString(), "label_O₃"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["pressure"]["label"].toString(), "label_pressure"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["rainfall"]["label"].toString(), "label_rainfall"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["radiation"]["label"].toString(), "label_radiation"); + Tools::saveImg2(dstDir, metric, font, color, imgs, items["beam"]["label"].toString(), "label_beam"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "℃", "unit_celsius"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "℉", "unit_fahrenheit"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "%", "unit_humidity"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "dB", "unit_noise"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "m/s", "unit_windspeed"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm25"); + auto img = imgs->back().toObj(); + img["name"] = "unit_pm10"; + imgs.append(img); + Tools::saveImg2(dstDir, metric, font, color, imgs, "ppb", "unit_ppb"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "hpa", "unit_hpa"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "mm", "unit_mm"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "W/m²", "unit_W/m²"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "lux", "unit_lux"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "minus_sign"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north"), "N"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("east")+tr("north"), "NNE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("north"), "NE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("north"), "ENE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east"), "E"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("south"), "ESE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("south"), "SE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("east")+tr("south"), "SSE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south"), "S"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("west")+tr("south"), "SSW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("south"), "SW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("south"), "WSW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west"), "W"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("north"), "WNW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("north"), "NW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("west")+tr("north"), "NNW"); + + JObj arrayPic; + arrayPic["name"] = "previewTmp"; + QString srcFile = srcPageDir+"/previewTmp.png"; + QFile srcQFile(srcFile); + if(srcQFile.exists()) { + QString id = Tools::fileMd5(srcFile); + srcQFile.copy(dstDir+"/"+id); + arrayPic["id"] = id; + } + imgs.append(arrayPic); + res["iPicCount"] = (int)imgs.size(); + res["arrayPics"] = imgs; + } else { + auto widget = json["widget"]; + res["timeSpan"] = json["play"]["duration"].toInt(); + res["alignType"] = widget["alignType"].toInt(); + res["bHumidity"] = widget["bHumidity"].toBool(); + res["bNoise"] = widget["bNoise"].toBool(); + res["bPM10"] = widget["bPM10"].toBool(); + res["bPM25"] = widget["bPM25"].toBool(); + res["bTemperature"] = widget["bTemperature"].toBool(); + auto title = widget["labelTitle"].toString(); + res["bTitle"] = ! title.isEmpty(); + res["bWindDirection"] = widget["bWindDirection"].toBool(); + res["bWindSpeed"] = widget["bWindSpeed"].toBool(); + res["temperatureCompensation"] = widget["temperatureCompensation"].toInt(); + res["temperatureStyle"] = widget["temperatureStyle"].toInt(); + res["bgColor"] = widget["cBackground"].toInt(); + res["bSingleScroll"] = widget["bPaomadeng"].toBool(); + res["iScrollSpeed"] = widget["scrollSpeed"].toInt(); + + auto textColor = Tools::int2Color(widget["textColor"].toInt()); + auto font = qfont(widget["fontFamily"].toString(), widget["fontSize"].toInt(), widget["fontBold"].toBool(), widget["fontItalics"].toBool()); + font.setUnderline(widget["fontUnderline"].toBool()); + font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); + QFontMetricsF metricF(font); + res["spaceWidth"] = metricF.horizontalAdvance(" "); + QFontMetrics metric(font); + QColor color(textColor); + JArray imgs; + for(auto str : str0_9) Tools::saveImg2(dstDir, metric, font, color, imgs, str, str); + + Tools::saveImg2(dstDir, metric, font, color, imgs, title, "labeltitle"); + Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelTemperature"].toString(), "labeltemperature"); + Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelHumidity"].toString(), "labelhumidity"); + Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelNoise"].toString(), "labelnoise"); + Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelWindSpeed"].toString(), "labelwindSpeed"); + Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelWindDirection"].toString(), "labelwindDirection"); + Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelPM25"].toString(), "labelpm25"); + Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelPM10"].toString(), "labelpm10"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "℃", "unit_celsius"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "℉", "unit_fahrenheit"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "%", "unit_humidity"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "dB", "unit_noise"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "m/s", "unit_windspeed"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm10"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm25"); + Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "minus_sign"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north"), "N"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("east")+tr("north"), "NNE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("north"), "NE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("north"), "ENE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east"), "E"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("south"), "ESE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("south"), "SE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("east")+tr("south"), "SSE"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south"), "S"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("west")+tr("south"), "SSW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("south"), "SW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("south"), "WSW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west"), "W"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("north"), "WNW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("north"), "NW"); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("west")+tr("north"), "NNW"); + JObj arrayPic; + arrayPic["name"] = "previewTmp"; + QString srcFile = srcPageDir+"/previewTmp.png"; + QFile srcQFile(srcFile); + if(srcQFile.exists()) { + QString id = Tools::fileMd5(srcFile); + srcQFile.copy(dstDir+"/"+id); + arrayPic["id"] = id; + } + imgs.append(arrayPic); + res["iPicCount"] = (int)imgs.size(); + res["arrayPics"] = imgs; } - imgs.append(arrayPic); - oRes["iPicCount"] = imgs.size(); - oRes["arrayPics"] = imgs; - return oRes; + return res; } EEnviron::EEnviron(EBase *multiWin): EBase(multiWin) { mType = EBase::Environ; - m_attr.labelTemp = tr("Temperature")+":"; - m_attr.labelHum = tr("Humidity")+":"; - m_attr.labelNoise = tr("Noise")+":"; - m_attr.labelWindSpeed = tr("Wind Speed")+":"; - m_attr.labelWindDirectiton = tr("Wind Direction")+":"; - m_attr.labelPm25 = "PM2.5:"; - m_attr.labelPm10 = "PM10:"; + for(auto &item : itemMap) item.second.label = item.second.text+": "; calAttr(); } -EEnviron::EEnviron(const QJsonObject &json, EBase *multiWin): EBase(multiWin){ +EEnviron::EEnviron(const JObj &json, EBase *multiWin): EBase(multiWin){ mType = EBase::Environ; setBaseAttr(json); - auto widget = json["widget"]; - m_attr.hasTemp = widget["bTemperature"].toBool(); - m_attr.compensation = widget["temperatureCompensation"].toInt(); - m_attr.tempType = widget["temperatureStyle"].toInt(); - m_attr.labelTemp = widget["labelTemperature"].toString(); - m_attr.title = widget["labelTitle"].toString(); - m_attr.hasHum = widget["bHumidity"].toBool(); - m_attr.labelHum = widget["labelHumidity"].toString(); - m_attr.hasNoise = widget["bNoise"].toBool(); - m_attr.labelNoise = widget["labelNoise"].toString(); - m_attr.hasWindSpeed = widget["bWindSpeed"].toBool(); - m_attr.labelWindSpeed = widget["labelWindSpeed"].toString(); - m_attr.hasWindDirection = widget["bWindDirection"].toBool(); - m_attr.labelWindDirectiton = widget["labelWindDirection"].toString(); - m_attr.hasPM25 = widget["bPM25"].toBool(); - m_attr.labelPm25 = widget["labelPM25"].toString(); - m_attr.hasPM10 = widget["bPM10"].toBool(); - m_attr.labelPm10 = widget["labelPM10"].toString(); - m_attr.isSingleLine = widget["bPaomadeng"].toBool(); - m_attr.scrollSpeed = widget["scrollSpeed"].toInt(); - m_attr.backColor = Tools::int2Color(widget["cBackground"].toInt()); - m_attr.align = widget["alignType"].toInt(); - m_attr.font = qfont(widget["fontFamily"].toString(), widget["fontSize"].toInt(), widget["fontBold"].toBool(), widget["fontItalics"].toBool()); - m_attr.font.setUnderline(widget["fontUnderline"].toBool()); - m_attr.textColor = Tools::int2Color(widget["textColor"].toInt()); - m_attr.playRefresh = json["play"]["refresh"].toInt(); - m_attr.playDuration = json["play"]["duration"].toInt(); + auto items = json["items"].toObj(); + if(! items.empty()) { + for(auto &jitem : items) { + auto iter = itemMap.find(jitem.first); + if(iter!=itemMap.end()) { + iter->second.label = jitem.second["label"].toString(); + iter->second.has = jitem.second["has"].toBool(); + } + } + duration = json["duration"].toInt(); + backColor = json["backColor"].toStr("#00000000"); + textColor = json["textColor"].toStr("#ff000000"); + tempCompen = json["tempCompen"].toInt(); + useFahrenheit = json["useFahrenheit"].toInt(); + title = json["title"].toStr(); + isSingleLine = json["isSingleLine"].toBool(); + scrollSpeed = json["scrollSpeed"].toInt(); + align = json["align"].toInt(); + font = qfont(json["fontFamily"].toStr(), json["fontSize"].toInt(), json["fontBold"].toBool(), json["fontItalic"].toBool()); + font.setUnderline(json["fontUnderline"].toBool()); + } else { + auto widget = json["widget"]; + auto &temp = itemMap["temp"]; + temp.label = widget["labelTemperature"].toStr(); + temp.has = widget["bTemperature"].toBool(); + auto &humidity = itemMap["humidity"]; + humidity.label = widget["labelHumidity"].toStr(); + humidity.has = widget["bHumidity"].toBool(); + auto &noise = itemMap["noise"]; + noise.label = widget["labelNoise"].toStr(); + noise.has = widget["bNoise"].toBool(); + auto &windSpeed = itemMap["windSpeed"]; + windSpeed.label = widget["labelWindSpeed"].toStr(); + windSpeed.has = widget["bWindSpeed"].toBool(); + auto &windDirection = itemMap["windDirection"]; + windDirection.label = widget["labelWindDirection"].toStr(); + windDirection.has = widget["bWindDirection"].toBool(); + auto &PM25 = itemMap["PM2.5"]; + PM25.label = widget["labelPM25"].toStr(); + PM25.has = widget["bPM25"].toBool(); + auto &PM10 = itemMap["PM10"]; + PM10.label = widget["labelPM10"].toStr(); + PM10.has = widget["bPM10"].toBool(); + for(auto item = itemMap.find("SO₂"); item!=itemMap.end(); ++item) { + item->second.label = item->second.text+": "; + item->second.has = false; + } + duration = json["play"]["duration"].toInt(); + backColor = Tools::int2Color(widget["cBackground"].toInt()); + textColor = Tools::int2Color(widget["textColor"].toInt()); + tempCompen = widget["temperatureCompensation"].toInt(); + useFahrenheit = widget["temperatureStyle"].toBool(); + title = widget["labelTitle"].toStr(); + isSingleLine = widget["bPaomadeng"].toBool(); + scrollSpeed = widget["scrollSpeed"].toInt(); + align = widget["alignType"].toInt(); + font = qfont(widget["fontFamily"].toStr(), widget["fontSize"].toInt(), widget["fontBold"].toBool(), widget["fontItalics"].toBool()); + font.setUnderline(widget["fontUnderline"].toBool()); + } calAttr(); } void EEnviron::calAttr() { item_cnt = 0; - if(! m_attr.title.isEmpty()) item_cnt++; - if(m_attr.hasTemp) item_cnt++; - if(m_attr.hasHum) item_cnt++; - if(m_attr.hasWindSpeed) item_cnt++; - if(m_attr.hasWindDirection) item_cnt++; - if(m_attr.hasNoise) item_cnt++; - if(m_attr.hasPM25) item_cnt++; - if(m_attr.hasPM10) item_cnt++; - m_attr.font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); - if(m_attr.isSingleLine) { + if(! title.isEmpty()) item_cnt++; + for(auto &item : itemMap) if(item.second.has) item_cnt++; + font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); + if(isSingleLine) { scroll_txt = ""; - if(! m_attr.title.isEmpty()) scroll_txt += m_attr.title + " "; - if(m_attr.hasTemp) scroll_txt += m_attr.labelTemp + QString::number(m_attr.compensation) + (m_attr.tempType==0 ? "℃" : "℉")+" "; - if(m_attr.hasHum) scroll_txt += m_attr.labelHum + "0% "; - if(m_attr.hasWindSpeed) scroll_txt += m_attr.labelWindSpeed + "0m/s "; - if(m_attr.hasWindDirection) scroll_txt += m_attr.labelWindDirectiton + "- "; - if(m_attr.hasNoise) scroll_txt += m_attr.labelNoise + "0dB "; - if(m_attr.hasPM25) scroll_txt += m_attr.labelPm25 + "0μg/m³ "; - if(m_attr.hasPM10) scroll_txt += m_attr.labelPm10 + "0μg/m³ "; - scroll_width = QFontMetrics(m_attr.font).horizontalAdvance(scroll_txt); + if(! title.isEmpty()) scroll_txt += title + " "; + for(auto &item : itemMap) if(item.second.has) { + scroll_txt += item.second.label; + if(item.first=="temp") scroll_txt += QString::number(tempCompen); + else if(item.first=="windDirection") scroll_txt += "--"; + else scroll_txt += "0"; + scroll_txt += item.second.unit + " "; + } + scroll_width = QFontMetrics(font).horizontalAdvance(scroll_txt); } } void EEnviron::drawText(QPainter *painter, QRectF& rect) { QTextOption opt(Qt::AlignLeft | Qt:: AlignVCenter); - painter->setFont(m_attr.font); - painter->setPen(m_attr.textColor); - if(m_attr.isSingleLine) { + painter->setFont(font); + painter->setPen(textColor); + if(isSingleLine) { opt.setWrapMode(QTextOption::NoWrap); painter->drawText(rect, scroll_txt, opt); } else { - if(m_attr.align==0) opt.setAlignment(Qt::AlignLeft|Qt::AlignVCenter); - else if(m_attr.align==1) opt.setAlignment(Qt::AlignCenter); - else if(m_attr.align==2) opt.setAlignment(Qt::AlignRight|Qt::AlignVCenter); + if(align==0) opt.setAlignment(Qt::AlignLeft|Qt::AlignVCenter); + else if(align==1) opt.setAlignment(Qt::AlignCenter); + else if(align==2) opt.setAlignment(Qt::AlignRight|Qt::AlignVCenter); if(item_cnt > 0) rect.setHeight(rect.height() / item_cnt); - if(! m_attr.title.isEmpty()) { - painter->drawText(rect, m_attr.title, opt); - rect.moveTop(rect.top() + rect.height()); + if(! title.isEmpty()) { + painter->drawText(rect, title, opt); + rect.translate(0, rect.height()); } - if(m_attr.hasTemp) { - painter->drawText(rect, m_attr.labelTemp + QString::number(m_attr.compensation) + (m_attr.tempType == 0 ? "℃" : "℉"), opt); - rect.moveTop(rect.top() + rect.height()); + for(auto &itemPair : itemMap) if(itemPair.second.has) { + auto text = itemPair.second.label; + if(itemPair.first=="temp") text += QString::number(tempCompen); + else if(itemPair.first=="windDirection") text += "--"; + else text += "0"; + text += itemPair.second.unit; + painter->drawText(rect, text, opt); + rect.translate(0, rect.height()); } - if(m_attr.hasHum) { - painter->drawText(rect, m_attr.labelHum + "0%", opt); - rect.moveTop(rect.top() + rect.height()); - } - if(m_attr.hasWindSpeed) { - painter->drawText(rect, m_attr.labelWindSpeed + "0m/s", opt); - rect.moveTop(rect.top() + rect.height()); - } - if(m_attr.hasWindDirection) { - painter->drawText(rect, m_attr.labelWindDirectiton + "-", opt); - rect.moveTop(rect.top() + rect.height()); - } - if(m_attr.hasNoise) { - painter->drawText(rect, m_attr.labelNoise + "0dB", opt); - rect.moveTop(rect.top() + rect.height()); - } - if(m_attr.hasPM25) { - painter->drawText(rect, m_attr.labelPm25 + "0μg/m³", opt); - rect.moveTop(rect.top() + rect.height()); - } - if(m_attr.hasPM10) painter->drawText(rect, m_attr.labelPm10 + "0μg/m³", opt); } } void EEnviron::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){ - if(m_attr.isSingleLine) { + if(isSingleLine) { if(timer_id==0) { scroll_off = innerRect().width(); - timer_id = startTimer(m_attr.scrollSpeed, Qt::PreciseTimer); + timer_id = startTimer(scrollSpeed, Qt::PreciseTimer); } } else { if(timer_id!=0) { @@ -221,9 +318,9 @@ void EEnviron::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, } } painter->setClipRect(0, 0, mWidth, mHeight); - painter->fillRect(0, 0, mWidth, mHeight, m_attr.backColor); + painter->fillRect(0, 0, mWidth, mHeight, backColor); auto inner = innerRect(); - if(m_attr.isSingleLine) { + if(isSingleLine) { inner.moveLeft(scroll_off); inner.setWidth(scroll_width); } @@ -246,13 +343,13 @@ void EEnviron::timerEvent(QTimerEvent *e) { QWidget* EEnviron::attrWgt() { auto wgtAttr = new QWidget; - auto vBox = new QVBoxLayout(wgtAttr); + auto vBox = new VBox(wgtAttr); vBox->setContentsMargins(6, 0, 6, 0); vBox->setSpacing(3); addBaseAttrWgt(vBox); - auto hBox = new QHBoxLayout; + auto hBox = new HBox(vBox); hBox->addWidget(new QLabel(tr("Basic Properties"))); auto line = new QFrame; @@ -260,273 +357,130 @@ QWidget* EEnviron::attrWgt() { line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout; + hBox = new HBox(vBox); hBox->addSpacing(6); - auto fdTitle = new QLineEdit(m_attr.title); + auto fdTitle = new QLineEdit(title); fdTitle->setPlaceholderText(tr("Title")); connect(fdTitle, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.title = text; + title = text; calAttr(); update(); }); hBox->addWidget(fdTitle); - vBox->addLayout(hBox); + for(auto &itemPair : itemMap) { + hBox = new HBox(vBox); + hBox->addSpacing(6); + auto *item = &itemPair.second; + bool isTemp = itemPair.first=="temp"; + auto text = item->text; + if(! item->unit.isEmpty()) text += " ("+item->unit+")"; + auto fd = new QCheckBox(text); + fd->setChecked(item->has); + connect(fd, &QCheckBox::toggled, wgtAttr, [=](bool checked) { + item->has = checked; + calAttr(); + update(); + }); + hBox->addWidget(fd); + hBox->addStretch(); - hBox = new QHBoxLayout(); - hBox->addSpacing(6); + if(isTemp) { + auto fdIsCelsius = new QRadioButton("℃"); + fdIsCelsius->setChecked(true); + hBox->addWidget(fdIsCelsius); - auto wTemp = new QCheckBox(tr("Temperature")); - wTemp->setChecked(m_attr.hasTemp); - connect(wTemp, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hasTemp = checked; - calAttr(); - update(); - }); - hBox->addWidget(wTemp); + auto fdIsFahrenheit = new QRadioButton("℉"); + connect(fdIsFahrenheit, &QRadioButton::toggled, this, [this](bool checked) { + useFahrenheit = checked; + calAttr(); + update(); + }); + hBox->addWidget(fdIsFahrenheit); + hBox->addStretch(); + + auto grp = new QButtonGroup(wgtAttr); + grp->addButton(fdIsCelsius); + grp->addButton(fdIsFahrenheit); + + if(useFahrenheit) fdIsFahrenheit->setChecked(true); + } + auto fdLabel = new QLineEdit(item->label); + fdLabel->setMaximumWidth(100); + connect(fdLabel, &QLineEdit::textChanged, this, [=](const QString &text) { + item->label = text; + calAttr(); + update(); + }); + hBox->addWidget(fdLabel); + + if(isTemp) { + hBox = new HBox(vBox); + hBox->addStretch(); + + hBox->addWidget(new QLabel(tr("Compensation"))); + + auto fdCompen = new QSpinBox; + fdCompen->setRange(-99, 999); + fdCompen->setValue(tempCompen); + connect(fdCompen, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { + tempCompen = value; + calAttr(); + update(); + }); + hBox->addWidget(fdCompen); + } + } + + auto wgtAlign = new QWidget; + vBox->addWidget(wgtAlign); + hBox = new HBox(wgtAlign); + hBox->setContentsMargins(6,0,0,0); hBox->addStretch(); - auto fdIsCelsius = new QRadioButton("℃"); - connect(fdIsCelsius, &QRadioButton::toggled, this, [this](bool checked) { - m_attr.tempType = checked ? 0 : 1; - calAttr(); - update(); - }); - hBox->addWidget(fdIsCelsius); - - auto fdIsFahrenheit = new QRadioButton("℉"); - hBox->addWidget(fdIsFahrenheit); - hBox->addStretch(); - - if(m_attr.tempType == 0) fdIsCelsius->setChecked(true); - else fdIsFahrenheit->setChecked(true); - auto gTempType = new QButtonGroup(wgtAttr); - gTempType->addButton(fdIsCelsius); - gTempType->addButton(fdIsFahrenheit); - - auto fdLabelTemp = new QLineEdit(m_attr.labelTemp); - fdLabelTemp->setMaximumWidth(100); - connect(fdLabelTemp, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.labelTemp = text; - calAttr(); - update(); - }); - hBox->addWidget(fdLabelTemp); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addStretch(); - - hBox->addWidget(new QLabel(tr("Compensation"))); - - auto fdComp = new QSpinBox(); - fdComp->setRange(-99, 999); - fdComp->setValue(m_attr.compensation); - connect(fdComp, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.compensation = value; - calAttr(); - update(); - }); - hBox->addWidget(fdComp); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - - auto fdHasHum = new QCheckBox(tr("Humidity")+" (%)"); - fdHasHum->setChecked(m_attr.hasHum); - connect(fdHasHum, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hasHum = checked; - calAttr(); - update(); - }); - hBox->addWidget(fdHasHum); - hBox->addStretch(); - - auto fdLabelHum = new QLineEdit(m_attr.labelHum); - fdLabelHum->setMaximumWidth(100); - connect(fdLabelHum, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.labelHum = text; - calAttr(); - update(); - }); - hBox->addWidget(fdLabelHum); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - - auto fdHasWindSpeed = new QCheckBox(tr("Wind speed")+" (m/s)"); - fdHasWindSpeed->setChecked(m_attr.hasWindSpeed); - connect(fdHasWindSpeed, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hasWindSpeed = checked; - calAttr(); - update(); - }); - hBox->addWidget(fdHasWindSpeed); - hBox->addStretch(); - - auto fdLabelWindSpeed = new QLineEdit(m_attr.labelWindSpeed); - fdLabelWindSpeed->setMaximumWidth(100); - connect(fdLabelWindSpeed, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.labelWindSpeed = text; - calAttr(); - update(); - }); - hBox->addWidget(fdLabelWindSpeed); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - - auto fdHasWindDirection = new QCheckBox(tr("Wind direction")); - fdHasWindDirection->setChecked(m_attr.hasWindDirection); - connect(fdHasWindDirection, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hasWindDirection = checked; - calAttr(); - update(); - }); - hBox->addWidget(fdHasWindDirection); - hBox->addStretch(); - - auto fdLabelWindDirection = new QLineEdit(m_attr.labelWindDirectiton); - fdLabelWindDirection->setMaximumWidth(100); - connect(fdLabelWindDirection, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.labelWindDirectiton = text; - calAttr(); - update(); - }); - hBox->addWidget(fdLabelWindDirection); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - - auto fdHasNoise = new QCheckBox(tr("Noise")+" (dB)"); - fdHasNoise->setChecked(m_attr.hasNoise); - connect(fdHasNoise, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hasNoise = checked; - calAttr(); - update(); - }); - hBox->addWidget(fdHasNoise); - hBox->addStretch(); - - auto fdLabelNoise = new QLineEdit(m_attr.labelNoise); - fdLabelNoise->setMaximumWidth(100); - connect(fdLabelNoise, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.labelNoise = text; - calAttr(); - update(); - }); - hBox->addWidget(fdLabelNoise); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - - auto fdHasPM25 = new QCheckBox("PM2.5 (μg/m³)"); - fdHasPM25->setChecked(m_attr.hasPM25); - connect(fdHasPM25, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hasPM25 = checked; - calAttr(); - update(); - }); - hBox->addWidget(fdHasPM25); - hBox->addStretch(); - - auto fdLabelPM25 = new QLineEdit(m_attr.labelPm25); - fdLabelPM25->setMaximumWidth(100); - connect(fdLabelPM25, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.labelPm25 = text; - calAttr(); - update(); - }); - hBox->addWidget(fdLabelPM25); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - - auto fdHasPM10 = new QCheckBox("PM10 (μg/m³)"); - fdHasPM10->setChecked(m_attr.hasPM10); - connect(fdHasPM10, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hasPM10 = checked; - calAttr(); - update(); - }); - hBox->addWidget(fdHasPM10); - hBox->addStretch(); - - auto fdLabelPM10 = new QLineEdit(m_attr.labelPm10); - fdLabelPM10->setMaximumWidth(100); - connect(fdLabelPM10, &QLineEdit::textChanged, this, [this](const QString &text) { - m_attr.labelPm10 = text; - calAttr(); - update(); - }); - hBox->addWidget(fdLabelPM10); - - vBox->addLayout(hBox); - - auto wgtAlign = new QWidget(); - auto hBoxAlign = new QHBoxLayout(wgtAlign); - hBoxAlign->setContentsMargins(6,0,0,0); - hBoxAlign->addStretch(); - auto fdLeft = new QRadioButton(tr("Left")); fdLeft->setChecked(true); connect(fdLeft, &QRadioButton::toggled, this, [this](bool checked) { if(! checked) return; - m_attr.align = 0; + align = 0; calAttr(); update(); }); - hBoxAlign->addWidget(fdLeft); + hBox->addWidget(fdLeft); auto fdCenter = new QRadioButton(tr("Center")); connect(fdCenter, &QRadioButton::toggled, this, [this](bool checked) { if(! checked) return; - m_attr.align = 1; + align = 1; calAttr(); update(); }); - hBoxAlign->addWidget(fdCenter); + hBox->addWidget(fdCenter); auto fdRight = new QRadioButton(tr("Right")); connect(fdRight, &QRadioButton::toggled, this, [this](bool checked) { if(! checked) return; - m_attr.align = 2; + align = 2; calAttr(); update(); }); - hBoxAlign->addWidget(fdRight); - hBoxAlign->addStretch(); + hBox->addWidget(fdRight); + hBox->addStretch(); - vBox->addWidget(wgtAlign); - if(m_attr.isSingleLine) wgtAlign->setVisible(false); - if(m_attr.align == 0) fdLeft->setChecked(true); - else if(m_attr.align == 1) fdCenter->setChecked(true); - else if(m_attr.align == 2) fdRight->setChecked(true); + if(isSingleLine) wgtAlign->setVisible(false); + if(align == 0) fdLeft->setChecked(true); + else if(align == 1) fdCenter->setChecked(true); + else if(align == 2) fdRight->setChecked(true); - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); auto fdIsScroll = new QCheckBox(tr("Single scroll")); - fdIsScroll->setChecked(m_attr.isSingleLine); + fdIsScroll->setChecked(isSingleLine); connect(fdIsScroll, &QCheckBox::toggled, this, [this, wgtAlign](bool checked) { - m_attr.isSingleLine = checked; + isSingleLine = checked; wgtAlign->setVisible(! checked); if(timer_id!=0) { killTimer(timer_id); @@ -536,16 +490,15 @@ QWidget* EEnviron::attrWgt() { update(); }); hBox->addWidget(fdIsScroll); - hBox->addStretch(); hBox->addWidget(new QLabel(tr("Speed"))); auto fdSpeed = new QSpinBox(); fdSpeed->setRange(1, 999); - fdSpeed->setValue(m_attr.scrollSpeed); + fdSpeed->setValue(scrollSpeed); connect(fdSpeed, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.scrollSpeed = value; + scrollSpeed = value; if(timer_id!=0) { killTimer(timer_id); timer_id = 0; @@ -558,23 +511,21 @@ QWidget* EEnviron::attrWgt() { hBox->addWidget(new QLabel(tr("ms/pixel"))); hBox->addStretch(); - vBox->addLayout(hBox); - - line = new QFrame(); + line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); vBox->addWidget(line); - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); auto fdFontFamily = new QFontComboBox(); fdFontFamily->setEditable(false); - fdFontFamily->setCurrentText(m_attr.font.family()); + fdFontFamily->setCurrentText(font.family()); connect(fdFontFamily, &QFontComboBox::currentFontChanged, this, [this](const QFont &f) { - auto font = qfont(f.family(), m_attr.font.pixelSize(), m_attr.font.bold(), m_attr.font.italic()); - font.setUnderline(m_attr.font.underline()); - m_attr.font = font; + auto ft = qfont(f.family(), font.pixelSize(), font.bold(), font.italic()); + ft.setUnderline(font.underline()); + font = ft; calAttr(); update(); }); @@ -582,27 +533,25 @@ QWidget* EEnviron::attrWgt() { auto fdFontSize = new QSpinBox(); fdFontSize->setRange(4, 9999); - fdFontSize->setValue(m_attr.font.pixelSize()); + fdFontSize->setValue(font.pixelSize()); connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.font.setPixelSize(value); + font.setPixelSize(value); calAttr(); update(); }); hBox->addWidget(fdFontSize); hBox->addStretch(); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); auto fdFontBold = new QPushButton("B"); fdFontBold->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-weight: bold;} QPushButton:checked{background: #29c; color: #fff;}"); fdFontBold->setFixedSize(30, 30); fdFontBold->setCheckable(true); - fdFontBold->setChecked(m_attr.font.bold()); + fdFontBold->setChecked(font.bold()); connect(fdFontBold, &QPushButton::toggled, this, [this](bool checked) { - m_attr.font.setBold(checked); + font.setBold(checked); calAttr(); update(); }); @@ -612,9 +561,9 @@ QWidget* EEnviron::attrWgt() { fdFontItalic->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-style: italic;} QPushButton:checked{background: #29c; color: #fff;}"); fdFontItalic->setFixedSize(30, 30); fdFontItalic->setCheckable(true); - fdFontItalic->setChecked(m_attr.font.italic()); + fdFontItalic->setChecked(font.italic()); connect(fdFontItalic, &QPushButton::toggled, this, [this](bool checked) { - m_attr.font.setItalic(checked); + font.setItalic(checked); calAttr(); update(); }); @@ -624,128 +573,91 @@ QWidget* EEnviron::attrWgt() { fdFontUnderline->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; text-decoration: underline;} QPushButton:checked{background: #29c; color: #fff;}"); fdFontUnderline->setFixedSize(30, 30); fdFontUnderline->setCheckable(true); - fdFontUnderline->setChecked(m_attr.font.underline()); + fdFontUnderline->setChecked(font.underline()); connect(fdFontUnderline, &QPushButton::toggled, this, [this](bool checked) { - m_attr.font.setUnderline(checked); + font.setUnderline(checked); calAttr(); update(); }); hBox->addWidget(fdFontUnderline); - auto fdColor = new LoColorSelector("T", m_attr.textColor); + auto fdColor = new LoColorSelector("T", textColor); fdColor->setFixedWidth(30); connect(fdColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) { - m_attr.textColor = color; + textColor = color; calAttr(); update(); }); hBox->addWidget(fdColor); - auto fdBack = new LoColorSelector(tr("Back Color"), m_attr.backColor); + auto fdBack = new LoColorSelector(tr("Back Color"), backColor); connect(fdBack, &LoColorSelector::sColorChanged, this, [this](const QColor &color) { - m_attr.backColor = color; + backColor = color; calAttr(); update(); }); hBox->addWidget(fdBack); hBox->addStretch(); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addWidget(new QLabel(tr("Play Properties"))); - line = new QFrame(); + line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Refresh Cycle"))); - - auto fdRefresh = new QSpinBox(); - fdRefresh->setRange(1, 999); - fdRefresh->setValue(m_attr.playRefresh); - connect(fdRefresh, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.playRefresh = value; - }); - hBox->addWidget(fdRefresh); - - hBox->addWidget(new QLabel(tr("min."))); - hBox->addStretch(); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Play Duration"))); auto fdDuration = new QSpinBox(); fdDuration->setRange(1, 99999); - fdDuration->setValue(m_attr.playDuration); - connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.playDuration = value; + fdDuration->setValue(duration); + connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { + duration = value; }); hBox->addWidget(fdDuration); hBox->addWidget(new QLabel(tr("s"))); hBox->addStretch(); - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; } -QJsonObject EEnviron::attrJson() const{ - QJsonObject oWidget; - oWidget["bTemperature"] = m_attr.hasTemp; - oWidget["temperatureCompensation"] = m_attr.compensation; - oWidget["temperatureStyle"] = m_attr.tempType; - oWidget["labelTemperature"] = m_attr.labelTemp; - oWidget["labelTitle"] = m_attr.title; - oWidget["bHumidity"] = m_attr.hasHum; - oWidget["labelHumidity"] = m_attr.labelHum; - oWidget["bNoise"] = m_attr.hasNoise; - oWidget["labelNoise"] = m_attr.labelNoise; - oWidget["bWindSpeed"] = m_attr.hasWindSpeed; - oWidget["labelWindSpeed"] = m_attr.labelWindSpeed; - oWidget["bWindDirection"] = m_attr.hasWindDirection; - oWidget["labelWindDirection"] = m_attr.labelWindDirectiton; - oWidget["bPM25"] = m_attr.hasPM25; - oWidget["labelPM25"] = m_attr.labelPm25; - oWidget["bPM10"] = m_attr.hasPM10; - oWidget["labelPM10"] = m_attr.labelPm10; - - oWidget["bPaomadeng"] = m_attr.isSingleLine; - oWidget["scrollSpeed"] = m_attr.scrollSpeed; - oWidget["alignType"] = m_attr.align; - oWidget["fontFamily"] = m_attr.font.family(); - oWidget["fontSize"] = m_attr.font.pixelSize(); - oWidget["fontBold"] = m_attr.font.bold(); - oWidget["fontItalics"] = m_attr.font.italic(); - oWidget["fontUnderline"] = m_attr.font.underline(); - oWidget["textColor"] = Tools::color2Int(m_attr.textColor); - oWidget["cBackground"] = Tools::color2Int(m_attr.backColor); - oWidget.insert("idDir", QString("env-%1-%2-%3-%4-%5").arg((int) zValue()).arg((int) x()).arg((int) y()).arg((int) mWidth).arg((int) mHeight)); - - QJsonObject oRoot; - addBaseAttr(oRoot); - oRoot["elementType"] = "Temp"; - oRoot["widget"] = oWidget; - oRoot["play"] = QJsonObject{ - {"refresh", m_attr.playRefresh}, - {"duration", m_attr.playDuration} +JObj EEnviron::attrJson() const{ + JObj json; + addBaseAttr(json); + json["elementType"] = "Temp"; + json["title"] = title; + JObj items; + for(auto &item : itemMap) items[item.first] = JObj{ + {"has", item.second.has}, + {"label", item.second.label} }; - return oRoot; + json["items"] = items; + json["tempCompen"] = tempCompen; + json["useFahrenheit"] = useFahrenheit; + json["isSingleLine"] = isSingleLine; + json["scrollSpeed"] = scrollSpeed; + json["align"] = align; + json["fontFamily"] = font.family(); + json["fontSize"] = font.pixelSize(); + json["fontBold"] = font.bold(); + json["fontItalic"] = font.italic(); + json["fontUnderline"] = font.underline(); + json["textColor"] = textColor.name(QColor::HexArgb); + json["backColor"] = backColor.name(QColor::HexArgb); + json["idDir"] = QString("env-%1-%2-%3-%4-%5").arg((int) zValue()).arg((int) x()).arg((int) y()).arg((int) mWidth).arg((int) mHeight); + json["duration"] = duration; + return json; } bool EEnviron::save(const QString &pageDir) { auto inner = innerRect(); - QPixmap img(m_attr.isSingleLine ? scroll_width : inner.width(), inner.height()); - img.fill(m_attr.backColor); + QPixmap img(isSingleLine ? scroll_width : inner.width(), inner.height()); + img.fill(backColor); QPainter painter(&img); QRectF arect(0, 0, img.width(), img.height()); drawText(&painter, arect); diff --git a/LedOK/program/eenviron.h b/LedOK/program/eenviron.h index 03ae1a7..83b71b2 100644 --- a/LedOK/program/eenviron.h +++ b/LedOK/program/eenviron.h @@ -3,55 +3,60 @@ #include "ebase.h" #include "gutil/qgui.h" +struct EnvironItem { + QString text; + QString unit; + QString label; + bool has = true; +}; + class EEnviron : public EBase { Q_OBJECT public: - struct Data { - QString title; - QString labelTemp; - QString labelHum; - QString labelNoise; - QString labelWindSpeed; - QString labelWindDirectiton; - QString labelPm25; - QString labelPm10; - int tempType = 0; - int compensation = 0; - - QFont font = qfont("Arial", 12); - QColor textColor = Qt::red; - QColor backColor = Qt::transparent; - int align = 0; - int playRefresh = 1; - int playDuration = 10; - int scrollSpeed = 33; - bool isSingleLine = false; - bool hasTemp = true; - bool hasHum = true; - bool hasNoise = true; - bool hasWindSpeed = true; - bool hasWindDirection = true; - bool hasPM25 = true; - bool hasPM10 = true; + LinkedMap itemMap { + {"temp", {tr("Temperature"), "℃"}}, + {"humidity", {tr("Humidity"), "%"}}, + {"noise", {tr("Noise"), "dB"}}, + {"windSpeed", {tr("Wind Speed"), "m/s"}}, + {"windDirection", {tr("Wind Direction")}}, + {"PM2.5", {"PM2.5", "μg/m³"}}, + {"PM10", {"PM10", "μg/m³"}}, + {"SO₂", {"SO₂", "ppb"}}, + {"NO₂", {"NO₂", "ppb"}}, + {"CO", {"CO", "ppb"}}, + {"O₃", {"O₃", "ppb"}}, + {"pressure", {tr("Pressure"), "hpa"}}, + {"rainfall", {tr("Rainfall"), "mm"}}, + {"radiation", {tr("Radiation"), "W/m²"}}, + {"beam", {tr("Beam"), "lux"}} }; + QString title; + QColor textColor = Qt::red; + QColor backColor = Qt::transparent; + QFont font = qfont("Arial", 12); + int tempCompen = 0; + int align = 0; + int duration = 10; + int scrollSpeed = 33; + bool useFahrenheit = false; + bool isSingleLine = false; - static QJsonObject genProg(const QJsonObject &, const QString &, const QString &); + static JObj genProg(const JObj &, const QString &, const QString &); explicit EEnviron(EBase *multiWin = nullptr); - explicit EEnviron(const QJsonObject &json, EBase *multiWin = nullptr); + explicit EEnviron(const JObj &json, EBase *multiWin = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; void timerEvent(QTimerEvent *) override; int type() const override { return EBase::Environ; } QWidget* attrWgt() override; bool save(const QString &pRoot) override; - QJsonObject attrJson() const override; + JObj attrJson() const override; private: void init(); void drawText(QPainter*, QRectF&); void calAttr(); - Data m_attr; int scroll_width; QString scroll_txt; int item_cnt = 0; diff --git a/LedOK/program/egif.cpp b/LedOK/program/egif.cpp index a5492f9..27cb995 100644 --- a/LedOK/program/egif.cpp +++ b/LedOK/program/egif.cpp @@ -1,6 +1,7 @@ #include "egif.h" #include "cfg.h" #include "tools.h" +#include "globaldefine.h" #include #include #include @@ -23,7 +24,7 @@ EGif *EGif::create(const QString &file, PageListItem *pageItem, EBase *multiWin) QFileInfo info(file); return new EGif(movie, info.absolutePath(), info.fileName(), pageItem, multiWin); } -EGif *EGif::create(const QJsonObject &json, PageListItem *pageItem, EBase *multiWin) { +EGif *EGif::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) { auto widget = json["widget"]; auto dir = widget["path"].toString(); auto name = widget["file"].toString(); @@ -197,15 +198,15 @@ bool EGif::save(const QString &pageDir) { return true; } -QJsonObject EGif::attrJson() const { - QJsonObject oRoot; +JObj EGif::attrJson() const { + JObj oRoot; addBaseAttr(oRoot); oRoot["elementType"] = "Gif"; - oRoot["widget"] = QJsonObject{ + oRoot["widget"] = JObj{ {"file", mName}, {"path", mDir} }; - oRoot["play"] = QJsonObject{ + oRoot["play"] = JObj{ {"playDuration", mDuration}, {"playTimes", mPlayTimes} }; diff --git a/LedOK/program/egif.h b/LedOK/program/egif.h index ffc24c6..280263d 100644 --- a/LedOK/program/egif.h +++ b/LedOK/program/egif.h @@ -9,7 +9,7 @@ class EGif : public EBase { public: static QString filters() { return "Gif(*.gif)"; } static EGif *create(const QString &file, PageListItem *pageItem, EBase *multiWin = nullptr); - static EGif *create(const QJsonObject &, PageListItem *pageItem, EBase *multiWin = nullptr); + static EGif *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr); explicit EGif(QMovie*, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin = nullptr); ~EGif(); @@ -17,7 +17,7 @@ public: void paint(QPainter*, const QStyleOptionGraphicsItem *, QWidget *) override; QWidget* attrWgt() override; bool save(const QString &pRoot) override; - QJsonObject attrJson() const override; + JObj attrJson() const override; void loadFiles() override; void freeFiles() override; diff --git a/LedOK/program/emultiwin.cpp b/LedOK/program/emultiwin.cpp index 46fed74..eebeb51 100644 --- a/LedOK/program/emultiwin.cpp +++ b/LedOK/program/emultiwin.cpp @@ -1,5 +1,5 @@ #include "emultiwin.h" -#include "tools.h" +#include "globaldefine.h" #include "base/extendedgroupbox.h" #include "ebase.h" #include "etext.h" @@ -16,36 +16,37 @@ #include #include #include +#include EMultiWin::EMultiWin(PageListItem *pageItem) : mPageItem(pageItem) { mType = EBase::Window; } -EMultiWin::EMultiWin(const QJsonObject &json, PageListItem *pageItem) : mPageItem(pageItem) { +EMultiWin::EMultiWin(const JObj &json, PageListItem *pageItem) : mPageItem(pageItem) { mType = EBase::Window; setBaseAttr(json); auto elements = json["elements"].toArray(); index = json["index"].toInt(); - foreach(QJsonValue element, elements) { + for(auto element : elements) { QString type = element["elementType"].toString(); EBase *inner = nullptr; - if(type=="Text") inner = new EText(element.toObject(), this); - else if(type=="Photo") inner = EPhoto::create(element.toObject(), pageItem, this); - else if(type=="Gif") inner = EGif::create(element.toObject(), pageItem, this); - else if(type=="Movie") inner = EVideo::create(element.toObject(), pageItem, this); - else if(type=="DClock") inner = new EDClock(element.toObject(), this); - else if(type=="AClock") inner = new EAClock(element.toObject(), this); - else if(type=="Temp") inner = new EEnviron(element.toObject(), this); - else if(type=="Web") inner = new EWeb(element.toObject(), this); - else if(type=="Timer") inner = new ETimer(element.toObject(), this); + if(type=="Text") inner = new EText(element.toObj(), this); + else if(type=="Photo") inner = EPhoto::create(element.toObj(), pageItem, this); + else if(type=="Gif") inner = EGif::create(element.toObj(), pageItem, this); + else if(type=="Movie") inner = EVideo::create(element.toObj(), pageItem, this); + else if(type=="DClock") inner = new EDClock(element.toObj(), this); + else if(type=="AClock") inner = new EAClock(element.toObj(), this); + else if(type=="Temp") inner = new EEnviron(element.toObj(), this); + else if(type=="Web") inner = new EWeb(element.toObj(), this); + else if(type=="Timer") inner = new ETimer(element.toObj(), this); if(inner==0) continue; inner->setPos(0, 0); inner->setFlag(QGraphicsItem::ItemStacksBehindParent); if(index != inners.size()) inner->freeFiles(); - inners.append(inner); + inners.emplace_back(inner); } - if(inners.isEmpty()) return; - if(index < 0 || index >= inners.size()) index = inners.size()-1; + if(inners.empty()) return; + if(index < 0 || index >= (int)inners.size()) index = (int)inners.size()-1; setCur(inners[index]); } EMultiWin::~EMultiWin() { @@ -53,7 +54,7 @@ EMultiWin::~EMultiWin() { } void EMultiWin::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { - if(inners.isEmpty()) { + if(inners.empty()) { QTextOption opt(Qt::AlignCenter); painter->save(); painter->fillRect(rect(),QColor(0, 0, 0)); @@ -70,10 +71,10 @@ bool EMultiWin::save(const QString &pageDir) { return true; } -QJsonObject EMultiWin::attrJson() const{ - QJsonArray eles; - foreach(auto inner, inners) eles.append(inner->attrJson()); - QJsonObject oRoot; +JObj EMultiWin::attrJson() const{ + JArray eles; + for(auto inner : inners) eles.append(inner->attrJson()); + JObj oRoot; addBaseAttr(oRoot); oRoot["elementType"] = "Window"; oRoot["index"] = index; @@ -145,7 +146,7 @@ QWidget* EMultiWin::attrWgt() { ePhoto->setSize(mWidth, mHeight); ePhoto->setZValue(order++); ePhoto->setFlag(QGraphicsItem::ItemStacksBehindParent); - inners.append(ePhoto); + inners.emplace_back(ePhoto); auto item = new QListWidgetItem(QIcon(":/res/program/Photo.png"), tr("Photo")+" "+ePhoto->mName); item->setData(Qt::UserRole, QVariant::fromValue((void*) ePhoto)); listWgt->addItem(item); @@ -162,7 +163,7 @@ QWidget* EMultiWin::attrWgt() { eGif->setSize(mWidth, mHeight); eGif->setZValue(order++); eGif->setFlag(QGraphicsItem::ItemStacksBehindParent); - inners.append(eGif); + inners.emplace_back(eGif); auto item = new QListWidgetItem(QIcon(":/res/program/Gif.png"), tr("Gif")+" "+eGif->mName); item->setData(Qt::UserRole, QVariant::fromValue((void*) eGif)); listWgt->addItem(item); @@ -200,7 +201,7 @@ QWidget* EMultiWin::attrWgt() { ele->setSize(mWidth, mHeight); ele->setZValue(order); ele->setFlag(QGraphicsItem::ItemStacksBehindParent); - inners.append(ele); + inners.emplace_back(ele); item->setData(Qt::UserRole, QVariant::fromValue((void*)ele)); listWgt->addItem(item); listWgt->setCurrentItem(item); @@ -219,7 +220,7 @@ QWidget* EMultiWin::attrWgt() { if(listWgt->count() > 0) listWgt->setCurrentRow(0); auto ele = static_cast(item->data(Qt::UserRole).value()); delete item; - inners.removeOne(ele); + for(auto i=inners.begin(); i < inners.end(); ++i) if(*i==ele) inners.erase(i); delete ele; int n = listWgt->count(); for(int i=0; i(listWgt->item(i)->data(Qt::UserRole).value())->setZValue(i); @@ -246,7 +247,9 @@ QWidget* EMultiWin::attrWgt() { listWgt->setCurrentRow(row-1); int n = listWgt->count(); for(int i=0; i(listWgt->item(i)->data(Qt::UserRole).value())->setZValue(i); - inners.swapItemsAt(row, row-1); + auto aaa = inners[row]; + inners[row] = inners[row-1]; + inners[row-1] = aaa; }); hBox->addWidget(btnGoUp); @@ -260,7 +263,9 @@ QWidget* EMultiWin::attrWgt() { listWgt->setCurrentRow(row+1); int n = listWgt->count(); for(int i=0; i(listWgt->item(i)->data(Qt::UserRole).value())->setZValue(i); - inners.swapItemsAt(row, row+1); + auto aaa = inners[row]; + inners[row] = inners[row+1]; + inners[row+1] = aaa; }); hBox->addWidget(btnGoDown); diff --git a/LedOK/program/emultiwin.h b/LedOK/program/emultiwin.h index f628943..3af957f 100644 --- a/LedOK/program/emultiwin.h +++ b/LedOK/program/emultiwin.h @@ -8,19 +8,19 @@ class EMultiWin : public EBase { Q_OBJECT public: explicit EMultiWin(PageListItem *pageItem); - explicit EMultiWin(const QJsonObject &json, PageListItem *pageItem); + explicit EMultiWin(const JObj &json, PageListItem *pageItem); ~EMultiWin(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; int type() const override { return EBase::Window; } QWidget* attrWgt() override; bool save(const QString &) override; - QJsonObject attrJson() const override; + JObj attrJson() const override; void setCur(EBase *); - PageListItem *mPageItem{nullptr}; - QList inners; + PageListItem *mPageItem = 0; + std::vector inners; int index{-1}; }; diff --git a/LedOK/program/ephoto.cpp b/LedOK/program/ephoto.cpp index ca3331a..617562a 100644 --- a/LedOK/program/ephoto.cpp +++ b/LedOK/program/ephoto.cpp @@ -1,6 +1,7 @@ #include "ephoto.h" #include "cfg.h" #include "tools.h" +#include "globaldefine.h" #include #include #include @@ -19,7 +20,7 @@ EPhoto *EPhoto::create(const QString &file, PageListItem *pageItem, EBase *multi QFileInfo info(file); return new EPhoto(img, info.absolutePath(), info.fileName(), pageItem, multiWin); } -EPhoto *EPhoto::create(const QJsonObject &json, PageListItem *pageItem, EBase *multiWin) { +EPhoto *EPhoto::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) { auto widget = json["widget"]; auto dir = widget["path"].toString(); auto name = widget["file"].toString(); @@ -48,15 +49,15 @@ EPhoto::EPhoto(const QImage &img, const QString &dir, const QString &name, PageL mType = EBase::Photo; scaleImgIfNeed(); } -QJsonObject EPhoto::attrJson() const { - QJsonObject oRoot; +JObj EPhoto::attrJson() const { + JObj oRoot; addBaseAttr(oRoot); oRoot["elementType"] = "Photo"; - oRoot["widget"] = QJsonObject{ + oRoot["widget"] = JObj{ {"path", mDir}, {"file", mName} }; - oRoot["play"] = QJsonObject{ + oRoot["play"] = JObj{ {"playDuration", mDuration}, {"playTimes", 1}, {"enterStyle", mEnterStyle}, @@ -174,16 +175,16 @@ QWidget* EPhoto::attrWgt() { auto wEnterStyle = new QComboBox(); wEnterStyle->addItem(tr("None")); - wEnterStyle->addItem(tr("Alpha_In")); + wEnterStyle->addItem(tr("Alpha In")); wEnterStyle->addItem(tr("Moving to left")); wEnterStyle->addItem(tr("Moving to right")); wEnterStyle->addItem(tr("Moving to top")); wEnterStyle->addItem(tr("Move to bottom")); - wEnterStyle->addItem(tr("Zoom in")); - wEnterStyle->addItem(tr("Zoom in to left_bottom")); - wEnterStyle->addItem(tr("Zoom in to left_top")); - wEnterStyle->addItem(tr("Zoom in to right_top")); - wEnterStyle->addItem(tr("Zoom in to right bottom")); + wEnterStyle->addItem(tr("Zoom In")); + wEnterStyle->addItem(tr("Zoom In to left_bottom")); + wEnterStyle->addItem(tr("Zoom In to left_top")); + wEnterStyle->addItem(tr("Zoom In to right_top")); + wEnterStyle->addItem(tr("Zoom In to right bottom")); wEnterStyle->addItem(tr("Rotate to right")); wEnterStyle->addItem(tr("Rotate to left")); wEnterStyle->setCurrentIndex(mEnterStyle); diff --git a/LedOK/program/ephoto.h b/LedOK/program/ephoto.h index b1d1341..b3142ef 100644 --- a/LedOK/program/ephoto.h +++ b/LedOK/program/ephoto.h @@ -19,7 +19,7 @@ public: public: static QString filters() { return tr("Images (*.png *.jpg *.jpeg *.bmp)"); } static EPhoto *create(const QString &file, PageListItem *pageItem, EBase *multiWin = nullptr); - static EPhoto *create(const QJsonObject &, PageListItem *pageItem, EBase *multiWin = nullptr); + static EPhoto *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr); explicit EPhoto(const QImage&, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin = nullptr); @@ -27,7 +27,7 @@ public: int type() const override { return EBase::Photo; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; - QJsonObject attrJson() const override; + JObj attrJson() const override; void freeFiles() override; void loadFiles() override; bool save(const QString &pageDir) override; diff --git a/LedOK/program/etext.cpp b/LedOK/program/etext.cpp index de3e0e0..2a8db57 100644 --- a/LedOK/program/etext.cpp +++ b/LedOK/program/etext.cpp @@ -11,7 +11,11 @@ #include #include #include +#if(QT_VERSION_MAJOR > 5) +#include +#else #include +#endif #include #include #include @@ -25,7 +29,7 @@ EText::EText(EBase *multiWin) : EBase(multiWin) { connect(this, &EText::sizeChanged, this, &EText::updImg); updImg(); } -EText::EText(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) { +EText::EText(const JObj &json, EBase *multiWin) : EBase(multiWin) { mType = EBase::Text; setBaseAttr(json); setElement(json, m_attr); @@ -33,12 +37,11 @@ EText::EText(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) { updImg(); } -void EText::setElement(const QJsonObject &json, Data &attr) { +void EText::setElement(const JObj &json, Data &attr) { auto widget = json["widget"]; attr.text = widget["text"].toString(); attr.align = static_cast(widget["align"].toInt()); - auto backColor = widget["backColor"].toString(); - attr.backColor = backColor.isEmpty() ? QColor(0,0,0,0) : QColor(backColor); + attr.backColor = widget["backColor"].toString("#00000000"); auto play = json["play"]; attr.playMode = play["style"].toInt(); auto turning = play["turning"]; @@ -328,6 +331,15 @@ QWidget* EText::attrWgt() { m_attr.text = fdText->toHtml(); updImg(); }); + connect(fdText, &QTextEdit::currentCharFormatChanged, this, [=](const QTextCharFormat &format) { + fdFontSize->blockSignals(true); + fdFontSize->setValue(format.font().pixelSize()); + fdFontSize->blockSignals(false); + auto foreground = format.foreground(); + fdTextColor->blockSignals(true); + fdTextColor->setColor(foreground.style()==Qt::NoBrush ? Qt::white : foreground.color()); + fdTextColor->blockSignals(false); + }); vBox->addWidget(fdText); hBox = new QHBoxLayout; @@ -368,9 +380,16 @@ QWidget* EText::attrWgt() { } auto data = qFile.readAll(); qFile.close(); +#if(QT_VERSION_MAJOR > 5) +#include + QStringDecoder decoder(QStringDecoder::Utf8); + QString text = decoder(data); + if(decoder.hasError()) text = QStringDecoder(QStringDecoder::System)(data); +#else QTextCodec::ConverterState state; - QString text = QTextCodec::codecForName("UTF-8")->toUnicode(data.constData(), data.size(), &state); + auto text = QTextCodec::codecForName("UTF-8")->toUnicode(data.constData(), data.size(), &state); if(state.invalidChars > 0) text = QString::fromLocal8Bit(data); +#endif fdText->setText(text); }); hBox->addWidget(btnImport); @@ -641,33 +660,33 @@ bool EText::save(const QString &pageDir) { for(int i=0; i #include #include -#include #include ETimer::ETimer(EBase *multiWin) : EBase(multiWin) { @@ -33,7 +32,7 @@ ETimer::ETimer(EBase *multiWin) : EBase(multiWin) { init(); } -ETimer::ETimer(const QJsonObject &json, EBase *multiWin) : EBase(multiWin){ +ETimer::ETimer(const JObj &json, EBase *multiWin) : EBase(multiWin){ mType = EBase::Timer; setBaseAttr(json); attr.isDown = json["isDown"].toBool(); @@ -326,8 +325,8 @@ QWidget* ETimer::attrWgt() { return wgtAttr; } -QJsonObject ETimer::attrJson() const { - QJsonObject obj; +JObj ETimer::attrJson() const { + JObj obj; addBaseAttr(obj); obj["elementType"] = "Timer"; obj["isDown"] = attr.isDown; diff --git a/LedOK/program/etimer.h b/LedOK/program/etimer.h index 3910e50..f705583 100644 --- a/LedOK/program/etimer.h +++ b/LedOK/program/etimer.h @@ -26,12 +26,12 @@ public: }; explicit ETimer(EBase *multiWin = nullptr); - explicit ETimer(const QJsonObject &json, EBase *multiWin = nullptr); + explicit ETimer(const JObj &json, EBase *multiWin = nullptr); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; int type() const override { return EBase::Timer; } QWidget* attrWgt() override; - QJsonObject attrJson() const override; + JObj attrJson() const override; Data attr; int secs = 0; diff --git a/LedOK/program/evideo.cpp b/LedOK/program/evideo.cpp index 5e8402c..f498486 100644 --- a/LedOK/program/evideo.cpp +++ b/LedOK/program/evideo.cpp @@ -1,7 +1,8 @@ #include "evideo.h" #include "cfg.h" #include "tools.h" -#include "base/waitingdlg.h" +#include "globaldefine.h" +#include "gutil/qwaitingdlg.h" #include "base/ffutil.h" #include "videosplitthread.h" #include @@ -29,7 +30,7 @@ EVideo *EVideo::create(const QString &file, PageListItem *pageItem, EBase *multi if(! outInfo.isFile() || outInfo.size()==0) return 0; return new EVideo(outInfo.absolutePath(), outInfo.fileName(), rawInfo.absolutePath(), rawName, img, dur/1000000, pageItem, multiWin); } -EVideo *EVideo::create(const QJsonObject &json, PageListItem *pageItem, EBase *multiWin) { +EVideo *EVideo::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) { auto widget = json["widget"]; auto dir = widget["path"].toString(); auto name = widget["file"].toString(); @@ -47,21 +48,21 @@ EVideo *EVideo::create(const QJsonObject &json, PageListItem *pageItem, EBase *m auto play = json["play"]; ins->playDuration = play["playDuration"].toInt(); ins->playTimes = play["playTimes"].toInt(); - if(ins->playDuration<10) ins->playDuration = dur/1000000; + if(ins->playDuration < 4) ins->playDuration = dur/1000000; return ins; } -QJsonObject EVideo::genProg(const QJsonObject &ele, const QString &dstDir, ProgItem *progItem) { +JObj EVideo::genProg(const JObj &ele, const QString &dstDir, ProgItem *progItem) { auto widget = ele["widget"]; auto path = widget["path"].toString(); auto name = widget["file"].toString(); if(progItem->mMaxWidth) name += "-square.mp4"; QString srcFile = path + "/" + name; QFileInfo srcInfo(srcFile); - if(! srcInfo.isFile()) return QJsonObject(); + if(! srcInfo.isFile()) return JObj(); QString id = Tools::fileMd5(srcFile); - if(id.isEmpty()) return QJsonObject(); + if(id.isEmpty()) return JObj(); QFile::copy(srcFile, dstDir+"/"+id); - QJsonObject oRes; + JObj oRes; oRes["_type"] = "Video"; oRes["id"] = id; oRes["md5"] = id; @@ -246,17 +247,17 @@ bool EVideo::save(const QString &pageDir) { return true; } -QJsonObject EVideo::attrJson() const { - QJsonObject oRoot; +JObj EVideo::attrJson() const { + JObj oRoot; addBaseAttr(oRoot); oRoot["elementType"] = "Movie"; - oRoot["widget"] = QJsonObject{ + oRoot["widget"] = JObj{ {"path", mDir}, {"file", mName}, {"pathRaw", mRawDir}, {"fileRaw", mRawName} }; - oRoot["play"] = QJsonObject{ + oRoot["play"] = JObj{ {"playDuration", playDuration}, {"playTimes", playTimes} }; @@ -323,7 +324,7 @@ QString EVideo::transcoding(QWidget *parent, QString rawFile, QString rawName, Q }); process.start("ffmpeg", {"-y", "-i", rawFile, "-vcodec", "h264", "-s", QString::number(w)+"x"+QString::number(h), "-profile:v", "main", "-b:v", QString::number(w*h/150)+"k", outFile}); msgBox.exec(); - if(err.rightRef(32).contains("Conversion failed!")) { + if(err.right(32).contains("Conversion failed!")) { QMessageBox::critical(parent, tr("Error"), err); return ""; } diff --git a/LedOK/program/evideo.h b/LedOK/program/evideo.h index 63da6ca..a25cbb5 100644 --- a/LedOK/program/evideo.h +++ b/LedOK/program/evideo.h @@ -20,8 +20,8 @@ public: } static QString transcoding(QWidget *parent, QString rawFile, QString rawName, QString dir, int rawW, int rawH, AVCodecID codec_id); static EVideo *create(const QString &file, PageListItem *pageItem, EBase *multiWin = nullptr); - static EVideo *create(const QJsonObject &, PageListItem *pageItem, EBase *multiWin = nullptr); - static QJsonObject genProg(const QJsonObject &, const QString &, ProgItem *mProgItem); + static EVideo *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr); + static JObj genProg(const JObj &, const QString &, ProgItem *mProgItem); explicit EVideo(const QString &, const QString &, const QString &, const QString &, QImage &img, int dur, PageListItem *pageItem, EBase *multiWin = nullptr); @@ -29,7 +29,7 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; QWidget* attrWgt() override; bool save(const QString &pRoot) override; - QJsonObject attrJson() const override; + JObj attrJson() const override; QString mDir; QString mName; diff --git a/LedOK/program/eweb.cpp b/LedOK/program/eweb.cpp index cafd0b2..eeb6b08 100644 --- a/LedOK/program/eweb.cpp +++ b/LedOK/program/eweb.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -10,7 +9,7 @@ EWeb::EWeb(EBase *multiWin) : EBase(multiWin) { mType = EBase::Web; duration = 10; } -EWeb::EWeb(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) { +EWeb::EWeb(const JObj &json, EBase *multiWin) : EBase(multiWin) { mType = EBase::Web; setBaseAttr(json); url = json["url"].toString(); @@ -79,8 +78,8 @@ QWidget* EWeb::attrWgt() { return wgtAttr; } -QJsonObject EWeb::attrJson() const { - QJsonObject oRoot; +JObj EWeb::attrJson() const { + JObj oRoot; addBaseAttr(oRoot); oRoot["elementType"] = "Web"; oRoot["url"] = url; diff --git a/LedOK/program/eweb.h b/LedOK/program/eweb.h index e4bc5bf..c104733 100644 --- a/LedOK/program/eweb.h +++ b/LedOK/program/eweb.h @@ -12,13 +12,13 @@ public: } explicit EWeb(EBase *multiWin = nullptr); - explicit EWeb(const QJsonObject &json, EBase *multiWin = nullptr); + explicit EWeb(const JObj &json, EBase *multiWin = nullptr); int type() const override {return EBase::Web;} void paint(QPainter*, const QStyleOptionGraphicsItem *, QWidget *) override; QWidget* attrWgt() override; bool save(const QString &) override {return true;}; - QJsonObject attrJson() const override; + JObj attrJson() const override; QString url; int duration = 10; diff --git a/LedOK/program/gentmpthread.cpp b/LedOK/program/gentmpthread.cpp index 2c87216..d210f49 100644 --- a/LedOK/program/gentmpthread.cpp +++ b/LedOK/program/gentmpthread.cpp @@ -6,7 +6,6 @@ #include "program/etext.h" #include "program/evideo.h" #include -#include #include #include #include @@ -38,10 +37,10 @@ void GenTmpThread::run() { } auto data = jsonFile.readAll(); jsonFile.close(); - QJsonParseError error; - auto proJson = QJsonDocument::fromJson(data, &error); - if(error.error != QJsonParseError::NoError) { - emit onErr("Parse "+srcDir+"/pro.json Error: "+error.errorString()); + QString error; + auto proJson = JFrom(data, &error).toObj(); + if(! error.isEmpty()) { + emit onErr("Parse "+srcDir+"/pro.json Error: "+error); return; } @@ -49,32 +48,30 @@ void GenTmpThread::run() { QStringList pageNames = QDir(srcDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); //查询 order 属性, 将最上层的放在转换后 layers 的最前面 //一个 page.json 对应节目任务中的一个 items 里的 program - QList pageJsons; - foreach(QString pageName, pageNames) { + std::vector pageJsons; + for(auto &pageName : pageNames) { QFile jsonFile(srcDir+"/"+pageName+"/page.json"); if(jsonFile.open(QIODevice::ReadOnly)) { auto data = jsonFile.readAll(); jsonFile.close(); - auto pageJson = QJsonDocument::fromJson(data, &error); - if(error.error == QJsonParseError::NoError) pageJsons.append(pageJson); + auto pageJson = JFrom(data, &error).toObj(); + if(error.isEmpty()) pageJsons.emplace_back(pageJson); } } - std::sort(pageJsons.begin(), pageJsons.end(), [](const QJsonDocument &a, const QJsonDocument &b) { + std::sort(pageJsons.begin(), pageJsons.end(), [](const JObj &a, const JObj &b) { return a["order"].toInt() < b["order"].toInt(); }); - - QJsonArray items; - foreach(QJsonDocument pageJson, pageJsons) { + JArray items; + for(auto pageJson : pageJsons) { srcPageDir = srcDir + "/" + pageJson["name"].toString(); items.append(cvtPage(pageJson, proJson)); } - - QJsonObject json; + JObj json; json["_type"] = "PlayXixunTask"; json["id"] = QUuid::createUuid().toString(QUuid::WithoutBraces); json["preDownloadURL"] = "http://192.168.8.202:23412/file/download?id="; json["notificationURL"] = "http://192.168.8.202:23412/test"; - json["task"] = QJsonObject{ + json["task"] = JObj{ {"_id", QUuid::createUuid().toString(QUuid::WithoutBraces)}, {"name", prog_name}, {"cmdId", QUuid::createUuid().toString(QUuid::WithoutBraces)}, @@ -82,7 +79,7 @@ void GenTmpThread::run() { }; QFile program(dstDir + "/program"); if(program.open(QFile::WriteOnly)) { - program.write(QJsonDocument(json).toJson()); + program.write(JToBytes(json, "\t")); program.close(); } @@ -105,12 +102,12 @@ void GenTmpThread::run() { } //此处需要把幻灯片中的元素按层顺序排序,再放入layers中,每个元素对一个layer。ewindow中的多个顺序元素为一个层上的时间轴上的素材 -QJsonObject GenTmpThread::cvtPage(const QJsonDocument &pageJson, const QJsonDocument &proJson) { - auto audios = pageJson["audios"].toArray(); +JObj GenTmpThread::cvtPage(const JObj &pageJson, const JObj &proJson) { + auto audios = pageJson("audios").toArray(); auto sourceRepeat = pageJson["loop"].toBool(); - QJsonArray sources; + JArray sources; int start = 0; - foreach(QJsonValue audio, audios) { + for(auto &audio : audios) { auto dur = audio["dur"].toInt(); if(dur==0) continue; auto name = audio["name"].toString(); @@ -121,7 +118,7 @@ QJsonObject GenTmpThread::cvtPage(const QJsonDocument &pageJson, const QJsonDocu QString id = Tools::fileMd5(file); if(id.isEmpty()) continue; QFile::copy(file, dstDir+"/"+id); - QJsonObject source; + JObj source; source.insert("_type", "Audio"); source["id"] = id; source["md5"] = id; @@ -139,29 +136,26 @@ QJsonObject GenTmpThread::cvtPage(const QJsonDocument &pageJson, const QJsonDocu sources.append(source); start += dur; } - QJsonArray layers; - if(! sources.isEmpty()) layers.append(QJsonObject{{"repeat", sourceRepeat}, {"sources", sources}}); + JArray layers; + if(! sources.empty()) layers.append(JObj{{"repeat", sourceRepeat}, {"sources", sources}}); auto elements = pageJson["elements"].toArray(); - foreach(auto ele, elements) { - QString type = ele["elementType"].toString(); + for(auto &ele : elements) { + auto type = ele["elementType"].toString(); auto geometry = ele["geometry"]; - QJsonArray sources; + JArray sources; if(type=="Window") { auto elements = ele["elements"].toArray(); auto left = geometry["x"]; auto top = geometry["y"]; auto width = geometry["w"]; auto height = geometry["h"]; - QList eles; - foreach(auto value, elements) eles.append(value.toObject()); - std::sort(eles.begin(), eles.end(), [](const QJsonObject &a, const QJsonObject &b) { - return a["geometry"]["order"].toInt() < b["geometry"]["order"].toInt(); - }); + QList eles; + for(auto &value : elements) eles.append(value.toObj()); int playTime = 0; - foreach(const auto ele, eles) { - QJsonObject source = cvtEle(ele["elementType"].toString(), ele); - if(source.isEmpty()) continue; + for(const auto &ele : eles) { + auto source = cvtEle(ele["elementType"].toString(), ele); + if(source.empty()) continue; source["left"] = left; source["top"] = top; source["width"] = width; @@ -171,8 +165,8 @@ QJsonObject GenTmpThread::cvtPage(const QJsonDocument &pageJson, const QJsonDocu sources.append(source); } } else { - QJsonObject source = cvtEle(type, ele.toObject()); - if(! source.isEmpty()) { + auto source = cvtEle(type, ele.toObj()); + if(! source.empty()) { if(mProgItem->mMaxWidth && (type=="Photo" || type=="Movie")) { source["left"] = 0; source["top"] = 0; @@ -188,48 +182,48 @@ QJsonObject GenTmpThread::cvtPage(const QJsonDocument &pageJson, const QJsonDocu sources.append(source); } } - if(! sources.isEmpty()) { - QJsonObject layer{{"repeat", sourceRepeat}, {"sources", sources}}; + if(! sources.empty()) { + JObj layer{{"repeat", sourceRepeat}, {"sources", sources}}; auto border = ele["border"].toString(); if(! border.isEmpty()) { QString bdSrc = "borders/"+border; QString id = Tools::fileMd5(bdSrc); QFile::copy(bdSrc, dstDir+"/"+id); auto borderSize = ele["borderSize"]; - if(borderSize.isUndefined() || borderSize.isNull()){ + if(borderSize.isNull()){ QImage img(bdSrc); - borderSize = QJsonArray{img.width(), img.height()}; + borderSize = JArray{img.width(), img.height()}; } - layer.insert("border", QJsonObject{ + layer["border"] = JObj{ {"img", id}, {"eff", ele["borderEff"]}, {"speed", ele["borderSpeed"]}, {"img_size", borderSize}, - {"geometry", QJsonArray{geometry["x"], geometry["y"], geometry["w"], geometry["h"]}} - }); + {"geometry", JArray{geometry["x"], geometry["y"], geometry["w"], geometry["h"]}} + }; } layers.append(layer); } } - QJsonArray schedules, plans = pageJson["plans"].toArray(); + JArray schedules, plans = pageJson["plans"].toArray(); auto validDate = pageJson["validDate"]; bool isValid = validDate["isValid"].toBool(); - if(plans.isEmpty()) { + if(plans.empty()) { if(isValid) { - QJsonObject schedule; + JObj schedule; schedule["dateType"] = "Range"; schedule["startDate"] = validDate["start"]; schedule["endDate"] = validDate["end"]; schedule["timeType"] = "All"; schedule["filterType"] = "None"; - schedule["monthFilter"] = QJsonArray(); - schedule["weekFilter"] = QJsonArray(); + schedule["monthFilter"] = JArray(); + schedule["weekFilter"] = JArray(); schedules.append(schedule); } } else { - foreach(QJsonValue plan, plans) { - QJsonObject schedule; + for(auto &plan : plans) { + JObj schedule; if(isValid) { schedule["dateType"] = "Range"; schedule["startDate"] = validDate["start"]; @@ -240,17 +234,17 @@ QJsonObject GenTmpThread::cvtPage(const QJsonDocument &pageJson, const QJsonDocu schedule["endTime"] = plan["end"]; auto weekly = plan["weekly"]; schedule["weekFilter"] = weekly; - schedule["filterType"] = weekly.toArray().isEmpty() ? "None" : "Week"; - schedule["monthFilter"] = QJsonArray(); + schedule["filterType"] = weekly.toArray().empty() ? "None" : "Week"; + schedule["monthFilter"] = JArray(); schedules.append(schedule); } } - return QJsonObject{ + return JObj{ {"_id", QUuid::createUuid().toString(QUuid::WithoutBraces)}, {"priority", 0}, {"version", 0}, {"schedules", schedules}, - {"_program", QJsonObject{ + {"_program", JObj{ {"_id", QUuid::createUuid().toString(QUuid::WithoutBraces)}, {"totalSize", 0}, {"name", pageJson["name"].toString()}, @@ -269,7 +263,7 @@ QJsonObject GenTmpThread::cvtPage(const QJsonDocument &pageJson, const QJsonDocu }; } -QJsonObject GenTmpThread::cvtEle(const QString &type, const QJsonObject &ele) { +JObj GenTmpThread::cvtEle(const QString &type, const JObj &ele) { if(type=="Text") return convertText(ele); else if(type=="Photo") return convertPhoto(ele); else if(type=="Movie") return EVideo::genProg(ele, dstDir, mProgItem); @@ -279,23 +273,43 @@ QJsonObject GenTmpThread::cvtEle(const QString &type, const QJsonObject &ele) { else if(type=="Temp") return EEnviron::genProg(ele, dstDir, srcPageDir); else if(type=="Web") return convertWeb(ele); else if(type=="Timer") return convertTimer(ele); - return QJsonObject(); + return JObj(); } -QJsonObject GenTmpThread::convertText(const QJsonObject &json) { +JObj GenTmpThread::convertText(const JObj &json) { EText::Data attr; EText::setElement(json, attr); - QJsonObject source; + JObj source; auto type = mProgItem->mMaxWidth ? "SplitText" : "MultiPng"; source["_type"] = type; source["name"] = type; source["id"] = res_id++; auto widget = json["widget"]; - QJsonArray srcFiles = widget["files"].toArray(); - source["iPicCount"] = srcFiles.size(); + + QTextEdit fdText; + auto ft = fdText.font(); + ft.setFamilies({"Arial","黑体"}); + ft.setPixelSize(16); + fdText.setFont(ft); + auto pal = fdText.palette(); + pal.setColor(QPalette::Base, Qt::black); + pal.setColor(QPalette::Text, Qt::white); + fdText.setPalette(pal); + fdText.setHtml(widget["text"].toStr()); + source["text"] = fdText.toPlainText(); + auto cursor = fdText.textCursor(); + cursor.movePosition(QTextCursor::End); + auto format = cursor.charFormat(); + source["fontSize"] = format.font().pixelSize(); + auto foreground = format.foreground(); + source["textColor"] = (foreground.style()==Qt::NoBrush ? Qt::white : foreground.color()).name(QColor::HexArgb); + source["backColor"] = widget["backColor"]; + + JArray srcFiles = widget["files"].toArray(); + source["iPicCount"] = (int)srcFiles.size(); if(attr.playMode==EText::Flip) { source["playMode"] = "Flip"; - source["timeSpan"] = attr.flip.pageDuration * srcFiles.size(); + source["timeSpan"] = attr.flip.pageDuration * (int)srcFiles.size(); if(attr.flip.effectDuration >= attr.flip.pageDuration) attr.flip.effectDuration = attr.flip.pageDuration / 2; } else if(attr.playMode==EText::Scroll) { source["playMode"] = "Scroll"; @@ -304,14 +318,14 @@ QJsonObject GenTmpThread::convertText(const QJsonObject &json) { source["playMode"] = "Static"; source["timeSpan"] = attr.duration; } - QJsonArray arrayPics; - QString filePrefix = srcPageDir+"/"+widget["idDir"].toString()+"/"; - for(int i=0; i +#include "gutil/qjson.h" + class ProgItem; class GenTmpThread : public QThread { Q_OBJECT @@ -12,15 +14,15 @@ public: protected: virtual void run() override; - QJsonObject cvtPage(const QJsonDocument &, const QJsonDocument &); - QJsonObject cvtEle(const QString &type, const QJsonObject &json); - QJsonObject convertText(const QJsonObject &json); - QJsonObject convertPhoto(const QJsonObject &json); - QJsonObject convertGif(const QJsonObject &json); - QJsonObject convertDClock(const QJsonObject &json); - QJsonObject convertAClock(const QJsonObject &json); - QJsonObject convertWeb(const QJsonObject &json); - QJsonObject convertTimer(const QJsonObject &json); + JObj cvtPage(const JObj &, const JObj &); + JObj cvtEle(const QString &type, const JObj &json); + JObj convertText(const JObj &json); + JObj convertPhoto(const JObj &json); + JObj convertGif(const JObj &json); + JObj convertDClock(const JObj &json); + JObj convertAClock(const JObj &json); + JObj convertWeb(const JObj &json); + JObj convertTimer(const JObj &json); signals: void onErr(QString); private: diff --git a/LedOK/program/pagelistitem.cpp b/LedOK/program/pagelistitem.cpp index afd261e..8b1f1aa 100644 --- a/LedOK/program/pagelistitem.cpp +++ b/LedOK/program/pagelistitem.cpp @@ -1,4 +1,5 @@ -#include "pagelistitem.h" +#include "pagelistitem.h" +#include "globaldefine.h" #include "gutil/qgui.h" #include "base/ffutil.h" #include "base/lodateselector.h" @@ -14,12 +15,10 @@ #include "program/etimer.h" #include "program/evideo.h" #include "program/eweb.h" -#include "program/wplanlist.h" #include "tools.h" #include #include #include -#include #include #include #include @@ -33,26 +32,26 @@ public: } }; -PageListItem::PageListItem(const QJsonObject &attr, const QString &pageDir) : mAttr(attr), mPageDir(pageDir) { +PageListItem::PageListItem(const JObj &attr, const QString &pageDir) : mAttr(attr), mPageDir(pageDir) { scale = qMin(128.0 / gProgItem->mWidth, 96.0 / gProgItem->mHeight); viewW = scale * gProgItem->mWidth; viewH = scale * gProgItem->mHeight; setSizeHint(QSize(0, viewH+20)); mScene = new PageScene(0, 0, gProgItem->mWidth, gProgItem->mHeight, this); auto elements = mAttr["elements"].toArray(); - foreach(auto ele, elements) { - QString type = ele["elementType"].toString(); + for(auto &ele : elements) { + auto type = ele["elementType"].toStr(); EBase *element = 0; - if(type=="Text") element = new EText(ele.toObject()); - else if(type=="Photo") element = EPhoto::create(ele.toObject(), this); - else if(type=="Gif") element = EGif::create(ele.toObject(), this); - else if(type=="Movie") element = EVideo::create(ele.toObject(), this); - else if(type=="DClock") element = new EDClock(ele.toObject()); - else if(type=="AClock") element = new EAClock(ele.toObject()); - else if(type=="Temp") element = new EEnviron(ele.toObject()); - else if(type=="Web") element = new EWeb(ele.toObject()); - else if(type=="Timer") element = new ETimer(ele.toObject()); - else if(type=="Window") element = new EMultiWin(ele.toObject(), this); + if(type=="Text") element = new EText(ele.toObj()); + else if(type=="Photo") element = EPhoto::create(ele.toObj(), this); + else if(type=="Gif") element = EGif::create(ele.toObj(), this); + else if(type=="Movie") element = EVideo::create(ele.toObj(), this); + else if(type=="DClock") element = new EDClock(ele.toObj()); + else if(type=="AClock") element = new EAClock(ele.toObj()); + else if(type=="Temp") element = new EEnviron(ele.toObj()); + else if(type=="Web") element = new EWeb(ele.toObj()); + else if(type=="Timer") element = new ETimer(ele.toObj()); + else if(type=="Window") element = new EMultiWin(ele.toObj(), this); if(element) mScene->addItem(element); } } @@ -60,58 +59,64 @@ PageListItem::PageListItem(const QJsonObject &attr, const QString &pageDir) : mA //更新页属性参数到page.json void PageListItem::updateJson() { if(mAttrWgt==0) return; //没有点开该页面进行编辑 - QJsonArray elements; + JArray elements; auto items = mScene->items(); - foreach(auto item, items) { - auto element = static_cast(item); - if(element->mMultiWin == nullptr) elements.append(element->attrJson()); + for(auto &item : items) { + auto element = (EBase*) item; + if(element->mMultiWin == 0) elements << element->attrJson(); } - mAttr.insert("elements", elements); + mAttr["elements"] = elements; - QJsonArray audios; auto cnt = mAudiosList->count(); - for(int i=0; iitem(i)->data(Qt::UserRole).value(); - audios.append(QJsonObject{ - {"dir", info.dir}, - {"name", info.name}, - {"dur", info.dur}, - {"vol", info.vol} - }); + if(cnt==0) mAttr.erase("audios"); + else { + JArray audios; + for(int i=0; iitem(i)->data(Qt::UserRole).value(); + audios << JObj{ + {"dir", info.dir}, + {"name", info.name}, + {"dur", info.dur}, + {"vol", info.vol} + }; + } + mAttr["audios"] = audios; } - mAttr.insert("audios", audios); } bool PageListItem::saveFiles() { mPageDir = gProgItem->mProgDir + "/" + mAttr["name"].toString(); QDir pageQDir(mPageDir); if(! pageQDir.exists() && ! pageQDir.mkpath(mPageDir)) return false; - QJsonArray elements; + JArray elements; auto items = mScene->items(); - foreach(auto item, items) { - auto element = static_cast(item); - if(element->mMultiWin == 0 && element->save(mPageDir)) elements.append(element->attrJson()); + for(auto &item : items) { + auto element = (EBase*) item; + if(element->mMultiWin == 0 && element->save(mPageDir)) elements << element->attrJson(); } - mAttr.insert("elements", elements); + mAttr["elements"] = elements; if(mAttrWgt) { - QJsonArray audios; auto cnt = mAudiosList->count(); - for(int i=0; iitem(i)->data(Qt::UserRole).value(); - QString oldFile = info.dir + PAGEDEL_SUFFIX + "/" + info.name; - if(QFileInfo::exists(oldFile)) ; - else if(QFileInfo::exists(oldFile = info.dir + "/" + info.name)) ; - else continue; - QFile::copy(oldFile, mPageDir + "/" + info.name); - info.dir = mPageDir; - audios.append(QJsonObject{ - {"dir", info.dir}, - {"name", info.name}, - {"dur", info.dur}, - {"vol", info.vol} - }); + if(cnt==0) mAttr.erase("audios"); + else { + JArray audios; + for(int i=0; iitem(i)->data(Qt::UserRole).value(); + QString oldFile = info.dir + PAGEDEL_SUFFIX + "/" + info.name; + if(QFileInfo::exists(oldFile)) ; + else if(QFileInfo::exists(oldFile = info.dir + "/" + info.name)) ; + else continue; + QFile::copy(oldFile, mPageDir + "/" + info.name); + info.dir = mPageDir; + audios << JObj{ + {"dir", info.dir}, + {"name", info.name}, + {"dur", info.dur}, + {"vol", info.vol} + }; + } + mAttr["audios"] = audios; } - mAttr.insert("audios", audios); } QFile file(mPageDir + "/page.json"); @@ -119,7 +124,7 @@ bool PageListItem::saveFiles() { QMessageBox::critical(listWidget(), "Write Error", mPageDir + "/page.json "+file.errorString()); return false; } - file.write(QJsonDocument(mAttr).toJson()); + file.write(JToBytes(mAttr, "\t")); file.close(); return true; } @@ -188,20 +193,8 @@ QPushButton#bnClearPlan { width: 24; height: 24; } -QPushButton#bnDel { - image: url(:/res/program/Delete.png); - width: 18; - height: 18; -} QPushButton#bnAddPlan:pressed, QPushButton#bnClearPlan:pressed, -QPushButton#bnDel:pressed { - margin-top: 1px; - margin-left: 1px; - margin-bottom: -1px; - margin-right: -1px; -} - QPushButton[ssName="weeklySelector"] { border: 1px solid #6A838F; width: 24; @@ -224,9 +217,8 @@ QPushButton[ssName="weeklySelector"]:checked { connect(fdPageName, &QLineEdit::textEdited, this, [this, fdPageName](const QString &text) { bool isDupli = false; auto listWgt = listWidget(); - if(nullptr != listWgt) { - int n = listWgt->count(); - for(int i=0; icount(); i++) { auto item = static_cast(listWgt->item(i)); if(text == item->mAttr["name"].toString()) { isDupli = true; @@ -270,7 +262,7 @@ QPushButton[ssName="weeklySelector"]:checked { vBox->addLayout(hBox); - auto line = new QFrame(); + auto line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); vBox->addWidget(line); @@ -362,9 +354,9 @@ QPushButton[ssName="weeklySelector"]:checked { mAudiosList->setIconSize(QSize(20, 20)); vBox->addWidget(mAudiosList, 1); - auto audios = mAttr["audios"].toArray(); + auto audios = mAttr("audios"); int durs = 0; - foreach(auto audio, audios) { + for(auto &audio : audios) { AudioInfo info{audio["dir"].toString(), audio["name"].toString(), audio["dur"].toInt(), audio["vol"].toInt()}; if(info.dir.isEmpty() || info.name.isEmpty() || info.dur==0) continue; auto item = new QListWidgetItem(QIcon(":/res/program/Audio.png"), info.name); @@ -427,7 +419,7 @@ QPushButton[ssName="weeklySelector"]:checked { line->setFrameShadow(QFrame::Sunken); vBox->addWidget(line); - QJsonValue validDate = mAttr["validDate"]; + auto validDate = mAttr["validDate"]; auto wValidDate = new QCheckBox(tr("Valid Date")); bool isDateValid = validDate["isValid"].toBool(); @@ -459,7 +451,7 @@ QPushButton[ssName="weeklySelector"]:checked { QMessageBox::warning(mAttrWgt, tr("Warning"), tr("Start Time can't be later than End Time")); fdStart->setDate(end); } - mAttr["validDate"] = QJsonObject{ + mAttr["validDate"] = JObj{ {"isValid", wValidDate->isChecked()}, {"start", fdStart->date().toString("yyyy-MM-dd")}, {"end", end.toString("yyyy-MM-dd")} @@ -471,7 +463,7 @@ QPushButton[ssName="weeklySelector"]:checked { QMessageBox::warning(mAttrWgt, tr("Warning"), tr("End Time can't be earlier than Start Time")); fdEnd->setDate(start); } - mAttr["validDate"] = QJsonObject{ + mAttr["validDate"] = JObj{ {"isValid", wValidDate->isChecked()}, {"start", start.toString("yyyy-MM-dd")}, {"end", fdEnd->date().toString("yyyy-MM-dd")} @@ -491,7 +483,7 @@ QPushButton[ssName="weeklySelector"]:checked { fdEnd->setEnabled(checked); bnDateStart->setEnabled(checked); bnDateEnd->setEnabled(checked); - mAttr["validDate"] = QJsonObject{ + mAttr["validDate"] = JObj{ {"isValid", checked}, {"start", fdStart->date().toString("yyyy-MM-dd")}, {"end", fdEnd->date().toString("yyyy-MM-dd")} @@ -515,26 +507,125 @@ QPushButton[ssName="weeklySelector"]:checked { bnAddPlan->setObjectName("bnAddPlan"); hBox->addWidget(bnAddPlan); - auto bnClearPlan = new QPushButton(); + auto bnClearPlan = new QPushButton; bnClearPlan->setObjectName("bnClearPlan"); hBox->addWidget(bnClearPlan); vBox->addLayout(hBox); - auto wPlans = new wPlanList(); - wPlans->setStyleSheet(R"rrr( -QListWidget::item { - height: 100; - border-top: 1px solid #6A838F; - margin-right: 9px; -})rrr"); - - wPlans->onRestorePlan(mAttr["plans"].toArray()); - connect(bnAddPlan, &QPushButton::clicked, wPlans, &wPlanList::onAddPlan); - connect(bnClearPlan, &QPushButton::clicked, wPlans, &wPlanList::clear); - connect(wPlans, &QListWidget::itemChanged, this, [this, wPlans] { - mAttr["plans"] = wPlans->plansJson(); + auto listPlan = new QListWidget; + connect(bnClearPlan, &QPushButton::clicked, listPlan, [=] { + listPlan->clear(); + mAttr.erase("plans"); }); - vBox->addWidget(wPlans, 2); + auto planChanged = [this, listPlan] { + if(listPlan->count()==0) mAttr.erase("plans"); + else { + JArray plans; + for(int i=0; icount(); i++) { + auto item = (PlanItemWgt*) listPlan->itemWidget(listPlan->item(i)); + JArray weekly; + for(int i=0; i<7; ++i) if(item->btnDays[i]->isChecked()) weekly.append(i+1); + plans.append(JObj{ + {"start", item->tStart->time().toString("hh:mm")}, + {"end", item->tEnd->time().toString("hh:mm")}, + {"weekly", weekly} + }); + } + mAttr["plans"] = plans; + } + }; + auto plans = mAttr("plans"); + for(int i=0; i<(int)plans.size(); i++) { + QListWidgetItem *item = new QListWidgetItem(listPlan); + item->setSizeHint({1, 80}); + item->setFlags(item->flags() & ~Qt::ItemIsSelectable); + auto json = plans[i].toObj(); + auto widget = new PlanItemWgt(item, &json); + connect(widget, &PlanItemWgt::sigItemChanged, listPlan, planChanged); + } + connect(bnAddPlan, &QPushButton::clicked, listPlan, [=] { + QListWidgetItem *item = new QListWidgetItem(listPlan); + item->setSizeHint({1, 80}); + item->setFlags(item->flags() & ~Qt::ItemIsSelectable); + auto widget = new PlanItemWgt(item); + connect(widget, &PlanItemWgt::sigItemChanged, listPlan, planChanged); + planChanged(); + }); + vBox->addWidget(listPlan, 2); return mAttrWgt; } + + +PlanItemWgt::PlanItemWgt(QListWidgetItem *item, const JObj *json) : m_item(item) { + auto vBox = new VBox(this); + vBox->setContentsMargins(6, 6, 6, 0); + auto hBox = new HBox(vBox); + + fdIdx = new QLabel; + fdIdx->setNum(item->listWidget()->count()); + hBox->addWidget(fdIdx); + hBox->addStretch(); + + tStart = new QTimeEdit; + tStart->setDisplayFormat("HH:mm"); + tStart->setMinimumWidth(80); + auto ft = tStart->font(); + ft.setPixelSize(14); + tStart->setFont(ft); + connect(tStart, &QTimeEdit::timeChanged, this, &PlanItemWgt::sigItemChanged); + hBox->addWidget(tStart); + hBox->addStretch(); + + tEnd = new QTimeEdit(QTime(23, 59)); + tEnd->setDisplayFormat("HH:mm"); + tEnd->setMinimumWidth(80); + tEnd->setFont(ft); + connect(tEnd, &QTimeEdit::timeChanged, this, &PlanItemWgt::sigItemChanged); + hBox->addWidget(tEnd); + hBox->addStretch(); + + bnDel = new QPushButton; + bnDel->setIcon(QIcon(":/res/program/Delete.png")); + bnDel->setFixedSize(24, 24); + bnDel->setObjectName("bnDel"); + connect(bnDel, &QPushButton::clicked, this, [=] { + auto listPlan = m_item->listWidget(); + listPlan->removeItemWidget(m_item); + delete m_item; + for(int i=0; icount(); i++) ((PlanItemWgt*) listPlan->itemWidget(listPlan->item(i)))->fdIdx->setNum(i+1); + emit sigItemChanged(); + }); + hBox->addWidget(bnDel); + + hBox = new HBox(vBox); + + QString strs[]{tr("M"), tr("Tu"), tr("W"), tr("Th"), tr("F"), tr("Sa"), tr("Su")}; + for(int i=0; i<7; ++i) { + btnDays[i] = new QPushButton(strs[i]); + btnDays[i]->setCheckable(true); + btnDays[i]->setProperty("ssName", "weeklySelector"); + hBox->addWidget(btnDays[i]); + hBox->addStretch(); + } + + if(json==0) for(int i=0; i<7; ++i) btnDays[i]->setChecked(true); + else { + tStart->setTime(QTime::fromString((*json)["start"].toString(), "hh:mm")); + tEnd->setTime(QTime::fromString((*json)["end"].toString(), "hh:mm")); + auto weekly = (*json)["weekly"].toArray(); + for(auto &day : weekly) { + auto i = day.toInt()-1; + if(i>=0 && i<7) btnDays[i]->setChecked(true); + } + } + for(int i=0; i<7; ++i) connect(btnDays[i], &QPushButton::toggled, this, &PlanItemWgt::sigItemChanged); + + vBox->addSpacing(6); + + auto line = new QFrame; + line->setFrameStyle(QFrame::HLine | QFrame::Sunken); + vBox->addWidget(line); + + item->listWidget()->setItemWidget(item, this); +} diff --git a/LedOK/program/pagelistitem.h b/LedOK/program/pagelistitem.h index b9d60cc..939ce6d 100644 --- a/LedOK/program/pagelistitem.h +++ b/LedOK/program/pagelistitem.h @@ -1,15 +1,17 @@ #ifndef PAGELISTITEM_H #define PAGELISTITEM_H +#include "gutil/qjson.h" #include -#include #include #include +#include +#include class PageListItem : public QObject, public QListWidgetItem { Q_OBJECT public: - explicit PageListItem(const QJsonObject &attr, const QString &pageDir); + explicit PageListItem(const JObj &attr, const QString &pageDir); ~PageListItem() { if(mAttrWgt) delete mAttrWgt; } @@ -19,7 +21,7 @@ public: QWidget *itemWgt(); QWidget *attrWgt(); - QJsonObject mAttr; + JObj mAttr; QString mPageDir; QWidget *mAttrWgt{0}; QListWidget *mAudiosList{0}; @@ -38,4 +40,20 @@ struct AudioInfo { }; Q_DECLARE_METATYPE(AudioInfo) +class PlanItemWgt : public QWidget { + Q_OBJECT +public: + explicit PlanItemWgt(QListWidgetItem *item, const JObj * = 0); + + QLabel *fdIdx; + QListWidgetItem *m_item; + + QTimeEdit *tStart; + QTimeEdit *tEnd; + QPushButton *bnDel; + QPushButton *btnDays[7]; +signals: + void sigItemChanged(); +}; + #endif // PAGELISTITEM_H