This commit is contained in:
Gangphon 2023-10-23 14:58:29 +08:00
parent bedfe3c2c7
commit 3a7eaae7a8
39 changed files with 1103 additions and 1019 deletions

View File

@ -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;
}

View File

@ -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; rr<cnt; rr++) if(! topLevelItem(rr)->isHidden()) topLevelItem(rr)->setCheckState(1, (Qt::CheckState) state);
emit selChanged();

View File

@ -1,9 +1,8 @@
#include "eleanaclock.h"
#include <QJsonObject>
#include <QPainter>
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();

View File

@ -1,6 +1,7 @@
#ifndef ELEANACLOCK_H
#define ELEANACLOCK_H
#include "gutil/qjson.h"
#include <QWidget>
#include <QTimeZone>
#include <QPen>
@ -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;

View File

@ -1,17 +1,16 @@
#include "elemultipng.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QPainter>
#include <QTimerEvent>
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;
}
}

View File

@ -1,13 +1,15 @@
#ifndef ELEMULTIPNG_H
#define ELEMULTIPNG_H
#include "gutil/qjson.h"
#include <QWidget>
#include <QRandomGenerator>
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<QPixmap> imgs;

View File

@ -3,33 +3,39 @@
#include <QPainter>
#include <complex>
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;
}
}

View File

@ -1,17 +1,19 @@
#ifndef ELESCROLL_H
#define ELESCROLL_H
#include "gutil/qjson.h"
#include <QWidget>
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<EleSplitScroll*> splits;
int interval = 0, timerId = 0, cur = 0, end = 0, step = 1;
std::vector<EleSplitScroll*> splits;
void paint(QPaintDevice *);
protected:
void paintEvent(QPaintEvent *) override;

View File

@ -2,16 +2,15 @@
#include "tools.h"
#include "globaldefine.h"
#include <QPainter>
#include <QJsonObject>
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(" ");

View File

@ -1,15 +1,16 @@
#ifndef ELETIMER_H
#define ELETIMER_H
#include "gutil/qjson.h"
#include <QWidget>
#include <QDateTime>
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;
QString title;
QColor textColor;
QColor backColor;
QFont font;

View File

@ -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 <QFileInfo>
#include <QJsonArray>
#include <QJsonObject>
#include <QLabel>
#include <QMouseEvent>
#include <QMovie>
@ -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; p<pageCnt; p++) {
auto _program = pageMaps[p]["_program"].toObject();
auto layers = _program["layers"].toArray();
if(layers.isEmpty()) continue;
auto splitWidths = _program["splitWidths"].toArray();
for(auto &pageMap : pageMaps) {
auto _program = pageMap["_program"];
auto layers = _program["layers"];
if(layers.empty()) continue;
auto splitWidths = _program["splitWidths"];
page = new Page(this);
page->setGeometry(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; i<splitWidths.size(); i++) {
for(int i=1; i<(int)splitWidths.size(); i++) {
ele.x -= splitWidths[i-1].toInt();
ele.y += height;
auto split = new EleSplitScroll(ele.wgt, wgt);
split->setGeometry(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; i<splitWidths.size(); i++) {
for(int i=1; i<(int)splitWidths.size(); i++) {
ele.x -= splitWidths[i-1].toInt();
ele.y += height;
auto split = new EleSplitPng(wgt, ele.wgt);
@ -126,27 +127,27 @@ PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonOb
}
}
ele.w = 0;
} else if(ele.type=="DigitalClockNew") ele.wgt = new DigiClock(dir+"/", srcMap.toObject(), page);
else if(ele.type=="AnalogClock") ele.wgt = new EleAnaClock(ele.w, ele.h, dir+"/"+ele.id, srcMap.toObject(), page);
} else if(ele.type=="DigitalClockNew") ele.wgt = new EleDigiClock(dir+"/", source, page);
else if(ele.type=="AnalogClock") ele.wgt = new EleAnaClock(ele.w, ele.h, dir+"/"+ele.id, source, page);
else if(ele.type=="Video" || ele.type=="Audio") {
auto video = new EleVideo(dir+"/"+ele.id, page);
auto vol = srcMap["vol"].toInt(100);
auto vol = source["vol"].toInt(100);
if(vol<100) video->player->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; i<page->eles.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; ee<page0->eles.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; ee<page->eles.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;

View File

@ -1,17 +1,30 @@
#ifndef PLAYWIN_H
#define PLAYWIN_H
#include "elebase.h"
#include "gutil/qjson.h"
#include "synctimer.h"
#include <QWidget>
#include <QMenu>
#include <QVector>
#include <QMap>
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<EleBase> eles;
std::vector<EleBase> 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<Page*> pages;
std::vector<Page*> pages;
QMap<int,TimerValue> timerMap;
QPoint mPressRel;
QMenu *menu;

View File

@ -6,7 +6,6 @@
#include "program/progeditorwin.h"
#include "program/copydirthread.h"
#include <QApplication>
#include <QHeaderView>
#include <QMessageBox>
#include <QStandardPaths>
#include <QProgressBar>
@ -36,10 +35,13 @@ 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<int> widths; int max = 0, ttl = 0;
QList<int> widths;
int max = 0;
auto width = dlg.fdWidth->value();
foreach(auto splitWidth, splitWidths) {
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;
@ -54,9 +56,14 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
}
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; i<cnt; i++) if(mProgTree->item(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; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
for(int i=0; i<mProgTree->topLevelItemCount(); i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
auto item = (ProgItem*) mProgTree->topLevelItem(i--);
item->del();
delete item;

View File

@ -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;
}

View File

@ -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;

View File

@ -41,35 +41,28 @@ EBase::EBase(EBase *multiWin) : mMultiWin(multiWin) {
mSidePen.setDashPattern(QVector<qreal>{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; i<borderImgs.size(); i++) if(borderImgs[i].name==bdName) {bdImgIdx = i; break;}
bdEff = json["borderEff"].toString();
bdSpeed = json["borderSpeed"].toInt(2);
} else {
bdName = geometry["border"].toString();
if(! bdName.isEmpty()) {
for(int i=0; i<borderImgs.size(); i++) if(borderImgs[i].name==bdName) {bdImgIdx = i; break;}
bdEff = geometry["border_eff"].toString();
bdSpeed = geometry["border_speed"].toInt(2);
}
}
}
void EBase::addBaseAttr(QJsonObject &obj) const {
auto ele = mMultiWin!=nullptr ? mMultiWin : this;
void EBase::addBaseAttr(JObj &obj) const {
auto ele = mMultiWin ? mMultiWin : this;
int bdWidth = ele->bdImgIdx > -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) {

View File

@ -2,6 +2,7 @@
#define EBASE_H
#include <QGraphicsObject>
#include "gutil/qjson.h"
#include <QVBoxLayout>
#include <QPen>
#include <float.h>
@ -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;}

View File

@ -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;
}

View File

@ -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();

File diff suppressed because it is too large Load Diff

View File

@ -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 {
LinkedMap<QString, EnvironItem> 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;
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;
QFont font = qfont("Arial", 12);
int tempCompen = 0;
int align = 0;
int playRefresh = 1;
int playDuration = 10;
int duration = 10;
int scrollSpeed = 33;
bool useFahrenheit = false;
bool isSingleLine = false;
bool hasTemp = true;
bool hasHum = true;
bool hasNoise = true;
bool hasWindSpeed = true;
bool hasWindDirection = true;
bool hasPM25 = true;
bool hasPM10 = true;
};
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;

View File

@ -1,6 +1,7 @@
#include "egif.h"
#include "cfg.h"
#include "tools.h"
#include "globaldefine.h"
#include <QBoxLayout>
#include <QDir>
#include <QLabel>
@ -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}
};

View File

@ -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;

View File

@ -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 <QMenu>
#include <QMessageBox>
#include <QGraphicsScene>
#include <QFileDialog>
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<EBase*>(item->data(Qt::UserRole).value<void*>());
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<n; i++) static_cast<EBase*>(listWgt->item(i)->data(Qt::UserRole).value<void*>())->setZValue(i);
@ -246,7 +247,9 @@ QWidget* EMultiWin::attrWgt() {
listWgt->setCurrentRow(row-1);
int n = listWgt->count();
for(int i=0; i<n; i++) static_cast<EBase*>(listWgt->item(i)->data(Qt::UserRole).value<void*>())->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<n; i++) static_cast<EBase*>(listWgt->item(i)->data(Qt::UserRole).value<void*>())->setZValue(i);
inners.swapItemsAt(row, row+1);
auto aaa = inners[row];
inners[row] = inners[row+1];
inners[row+1] = aaa;
});
hBox->addWidget(btnGoDown);

View File

@ -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<EBase*> inners;
PageListItem *mPageItem = 0;
std::vector<EBase*> inners;
int index{-1};
};

View File

@ -1,6 +1,7 @@
#include "ephoto.h"
#include "cfg.h"
#include "tools.h"
#include "globaldefine.h"
#include <QComboBox>
#include <QFileDialog>
#include <QImageReader>
@ -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);

View File

@ -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;

View File

@ -11,7 +11,11 @@
#include <QSpinBox>
#include <QStackedLayout>
#include <QTextBlock>
#if(QT_VERSION_MAJOR > 5)
#include <QStringConverter>
#else
#include <QTextCodec>
#endif
#include <QTimeEdit>
#include <QToolButton>
#include <QPainter>
@ -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<Qt::Alignment>(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 <QStringConverter>
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<mImgs.count(); i++) mImgs[i].save(idDir + QString("/text%1.png").arg(i));
return true;
}
QJsonObject EText::attrJson() const {
QJsonArray files;
JObj EText::attrJson() const {
JArray files;
for(int i=0; i<mImgs.count(); i++) files.append(QString("text%1.png").arg(i)); //上下滚动,生成一张纵向长图
QJsonObject obj;
JObj obj;
addBaseAttr(obj);
obj["elementType"] = "Text";
obj["widget"] = QJsonObject{
obj["widget"] = JObj{
{"text", m_attr.text},
{"align", (int) m_attr.align},
{"backColor", m_attr.backColor.name(QColor::HexArgb)},
{"files", files},
{"idDir", QString("%1-%2-%3-%4-%5").arg(zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight)}
};
obj["play"] = QJsonObject{
obj["play"] = JObj{
{"style", m_attr.playMode},
{"turning", QJsonObject{
{"turning", JObj{
{"strEffect", m_attr.flip.effect},
{"iEffectTime", m_attr.flip.pageDuration},
{"iEffectSpeed", m_attr.flip.effectDuration}
}},
{"rolling", QJsonObject{
{"rolling", JObj{
{"rollingStyle", m_attr.scroll.effect},
{"rollingSpeed", m_attr.scroll.effectSpeed},
{"headTailSpacing", m_attr.scroll.headTailSpacing},
{"playDuration", m_attr.scroll.duration}
}},
{"static", QJsonObject{{"playDuration", m_attr.duration}}}
{"static", JObj{{"playDuration", m_attr.duration}}}
};
return obj;
}

View File

@ -28,16 +28,16 @@ public:
struct Scroll scroll;
};
static void setElement(const QJsonObject &json, Data &attr);
static void setElement(const JObj &json, Data &attr);
explicit EText(EBase *multiWin = nullptr);
explicit EText(const QJsonObject &json, EBase *multiWin = nullptr);
explicit EText(const JObj &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
int type() const override { return EBase::Text; }
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
QJsonObject attrJson() const override;
JObj attrJson() const override;
public slots:
void updImg();

View File

@ -14,7 +14,6 @@
#include <QSpinBox>
#include <QTextOption>
#include <QPainter>
#include <QJsonObject>
#include <QToolButton>
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;

View File

@ -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;

View File

@ -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 <QLineEdit>
@ -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 "";
}

View File

@ -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;

View File

@ -2,7 +2,6 @@
#include <QSpinBox>
#include <QBoxLayout>
#include <QLineEdit>
#include <QJsonObject>
#include <QPainter>
#include <QLabel>
@ -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;

View File

@ -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;

View File

@ -6,7 +6,6 @@
#include "program/etext.h"
#include "program/evideo.h"
#include <QBuffer>
#include <QJsonArray>
#include <QProcess>
#include <QMessageBox>
#include <QPainter>
@ -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<QJsonDocument> pageJsons;
foreach(QString pageName, pageNames) {
std::vector<JObj> 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<QJsonObject> 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<JObj> 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<srcFiles.size(); i++) {
QString srcFile = filePrefix + srcFiles[i].toString();
JArray arrayPics;
auto filePrefix = srcPageDir+"/"+widget["idDir"].toString()+"/";
for(int i=0; i<(int)srcFiles.size(); i++) {
auto srcFile = filePrefix + srcFiles[i].toString();
QFile srcQFile(srcFile);
if(! srcQFile.exists()) continue;
QJsonObject arrayPic;
QString id = Tools::fileMd5(srcFile);
JObj arrayPic;
auto id = Tools::fileMd5(srcFile);
srcQFile.copy(dstDir+"/"+id);
arrayPic["id"] = id;
arrayPic["mime"] = "image/png";
@ -337,12 +351,12 @@ QJsonObject GenTmpThread::convertText(const QJsonObject &json) {
return source;
}
//转换图片
QJsonObject GenTmpThread::convertPhoto(const QJsonObject &ele){
JObj GenTmpThread::convertPhoto(const JObj &ele){
auto widget = ele["widget"];
auto name = widget["file"].toString();
QString srcFile = widget["path"].toString() + "/" + name;
QFileInfo srcInfo(srcFile);
QJsonObject source;
JObj source;
if(! srcInfo.isFile()) return source;
QImage img(srcFile);
auto geometry = ele["geometry"];
@ -422,17 +436,17 @@ QJsonObject GenTmpThread::convertPhoto(const QJsonObject &ele){
return source;
}
//转换图片
QJsonObject GenTmpThread::convertGif(const QJsonObject &json) {
JObj GenTmpThread::convertGif(const JObj &json) {
auto widget = json["widget"];
auto path = widget["path"].toString();
auto name = widget["file"].toString();
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"] = "Image";
oRes["id"] = id;
oRes["md5"] = id;
@ -450,14 +464,15 @@ QJsonObject GenTmpThread::convertGif(const QJsonObject &json) {
oRes["exitEffectTimeSpan"] = 0;
return oRes;
}
QJsonObject GenTmpThread::convertDClock(const QJsonObject &json){
QJsonObject oRes;
JObj GenTmpThread::convertDClock(const JObj &json){
JObj oRes;
oRes["_type"] = "DigitalClockNew";
oRes["name"] = "DigitalClockNew";
oRes["id"] = "";
oRes["timeSpan"] = json["play"]["duration"];
oRes["timezone"] = 8;
auto widget = json["widget"];
oRes["timeZone"] = widget["timeZone"];
oRes["timezone"] = 8;//兼容旧播放器
oRes["year"] = widget["year"];
oRes["month"] = widget["month"];
oRes["day"] = widget["day"];
@ -490,7 +505,7 @@ QJsonObject GenTmpThread::convertDClock(const QJsonObject &json){
oRes["spaceWidth"] = metricF.horizontalAdvance(" ");
QFontMetrics metric(font);
QColor color(textColor);
QJsonArray imgs;
JArray imgs;
for(auto str : str0_9) Tools::saveImg2(dstDir, metric, font, color, imgs, str, str);
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("MON"), "MON");
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("TUE"), "TUE");
@ -507,18 +522,18 @@ QJsonObject GenTmpThread::convertDClock(const QJsonObject &json){
Tools::saveImg2(dstDir, metric, font, color, imgs, ":", "maohao");
Tools::saveImg2(dstDir, metric, font, color, imgs, "/", "xiegang");
Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "hengxian");
oRes["iPicCount"] = imgs.size();
oRes["iPicCount"] = (int)imgs.size();
oRes["arrayPics"] = imgs;
return oRes;
}
QJsonObject GenTmpThread::convertAClock(const QJsonObject &json) {
JObj GenTmpThread::convertAClock(const JObj &json) {
auto widget = json["widget"];
QString srcFile = srcPageDir + "/" + widget["selfCreateDialName"].toString();
QFile srcQFile(srcFile);
if(! srcQFile.exists()) return QJsonObject();
if(! srcQFile.exists()) return JObj();
QString id = Tools::fileMd5(srcFile);
srcQFile.copy(dstDir+"/"+id);
QJsonObject oRes;
JObj oRes;
oRes["_type"] = "AnalogClock";
oRes["id"] = id;
oRes["md5"] = id;
@ -531,15 +546,15 @@ QJsonObject GenTmpThread::convertAClock(const QJsonObject &json) {
oRes["bgColor"] = 0;
oRes["showHourScale"] = false;//是否显示时针
auto color = widget["hourMarkColor"];
oRes["scaleHourColor"] = color.isString() ? color : Tools::int2Color(color.toInt()).name();
oRes["scaleHourColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
color = widget["minMarkColor"];
oRes["scaleMinColor"] = color.isString() ? color : Tools::int2Color(color.toInt()).name();
oRes["scaleMinColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
color = widget["hourHandColor"];
oRes["pinHourColor"] = color.isString() ? color : Tools::int2Color(color.toInt()).name();
oRes["pinHourColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
color = widget["minHandColor"];
oRes["pinMinColor"] = color.isString() ? color : Tools::int2Color(color.toInt()).name();
oRes["pinMinColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
color = widget["secHandColor"];
oRes["pinSecColor"] = color.isString() ? color : Tools::int2Color(color.toInt()).name();
oRes["pinSecColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
oRes["pinHourLen"] = widget["hhLen"].toInt();
oRes["pinMinLen"] = widget["mhLen"].toInt();
oRes["pinSecLen"] = widget["shLen"].toInt();
@ -551,6 +566,7 @@ QJsonObject GenTmpThread::convertAClock(const QJsonObject &json) {
oRes["showScaleNum"] = false;
oRes["pinStyle"] = 1;
oRes["showSecond"] = widget["showSecHand"];
oRes["timeZone"] = widget["timeZone"];
//下同Video
oRes["entryEffect"] = "None";
oRes["exitEffect"] = "None";
@ -559,8 +575,8 @@ QJsonObject GenTmpThread::convertAClock(const QJsonObject &json) {
return oRes;
}
QJsonObject GenTmpThread::convertWeb(const QJsonObject &res) {
QJsonObject dst;
JObj GenTmpThread::convertWeb(const JObj &res) {
JObj dst;
dst["_type"] = "WebURL";
dst["id"] = "";
dst["name"] = "WebURL";
@ -568,8 +584,8 @@ QJsonObject GenTmpThread::convertWeb(const QJsonObject &res) {
dst["timeSpan"] = res["duration"];
return dst;
}
QJsonObject GenTmpThread::convertTimer(const QJsonObject &json) {
QJsonObject oRes;
JObj GenTmpThread::convertTimer(const JObj &json) {
JObj oRes;
oRes["_type"] = "Timer";
oRes["name"] = "Timer";
oRes["id"] = "";
@ -601,7 +617,7 @@ QJsonObject GenTmpThread::convertTimer(const QJsonObject &json) {
oRes["spaceWidth"] = metricF.horizontalAdvance(" ");
QFontMetrics metric(font);
QColor color(textColor);
QJsonObject imgs;
JObj imgs;
for(auto str : str0_9) Tools::saveImg(dstDir, metric, font, color, imgs, str, str);
Tools::saveImg(dstDir, metric, font, color, imgs, tr("day"), "day");
Tools::saveImg(dstDir, metric, font, color, imgs, tr("hour"), "hour");

View File

@ -2,6 +2,8 @@
#define GENTMPTHREAD_H
#include <QThread>
#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:

View File

@ -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 <QDateEdit>
#include <QDir>
#include <QGraphicsView>
#include <QJsonArray>
#include <QLineEdit>
#include <QMessageBox>
#include <QSpinBox>
@ -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,42 +59,47 @@ 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<EBase*>(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();
if(cnt==0) mAttr.erase("audios");
else {
JArray audios;
for(int i=0; i<cnt; i++) {
auto info = mAudiosList->item(i)->data(Qt::UserRole).value<AudioInfo>();
audios.append(QJsonObject{
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<EBase*>(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();
if(cnt==0) mAttr.erase("audios");
else {
JArray audios;
for(int i=0; i<cnt; i++) {
auto info = mAudiosList->item(i)->data(Qt::UserRole).value<AudioInfo>();
QString oldFile = info.dir + PAGEDEL_SUFFIX + "/" + info.name;
@ -104,14 +108,15 @@ bool PageListItem::saveFiles() {
else continue;
QFile::copy(oldFile, mPageDir + "/" + info.name);
info.dir = mPageDir;
audios.append(QJsonObject{
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; i<n; i++) {
if(listWgt) {
for(int i=0; i<listWgt->count(); i++) {
auto item = static_cast<PageListItem*>(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; i<listPlan->count(); 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; i<listPlan->count(); 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);
}

View File

@ -1,15 +1,17 @@
#ifndef PAGELISTITEM_H
#define PAGELISTITEM_H
#include "gutil/qjson.h"
#include <QGraphicsScene>
#include <QJsonObject>
#include <QLabel>
#include <QListWidget>
#include <QPushButton>
#include <QTimeEdit>
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