581 lines
23 KiB
C++
581 lines
23 KiB
C++
#include "gentmpthread.h"
|
||
#include "cfg.h"
|
||
#include "globaldefine.h"
|
||
#include "tools.h"
|
||
#include "program/eenviron.h"
|
||
#include "program/etext.h"
|
||
#include "program/evideo.h"
|
||
#include <QBuffer>
|
||
#include <QProcess>
|
||
#include <QMessageBox>
|
||
#include <QPainter>
|
||
|
||
GenTmpThread::GenTmpThread(ProgItem *progItem, const QString &prog_name, const QString &zip_file, const QString &password) : mProgItem(progItem), prog_name(prog_name), zip_file(zip_file), password(password) {
|
||
connect(this, &QThread::finished, this, &QThread::deleteLater);
|
||
}
|
||
|
||
void GenTmpThread::run() {
|
||
auto srcDir = programsDir() + "/" + prog_name;
|
||
dstDir = srcDir + "_tmp";
|
||
//清空目录
|
||
QDir progsDir(programsDir());
|
||
progsDir.remove(prog_name + "_tmp.zip");
|
||
QDir dstQDir(dstDir);
|
||
if(! dstQDir.exists() || dstQDir.removeRecursively()) {
|
||
int iReTryCount = 0;
|
||
while(!progsDir.mkdir(prog_name + "_tmp")) {
|
||
QThread::msleep(250);
|
||
iReTryCount++;
|
||
if(iReTryCount > 4) break;
|
||
}
|
||
}
|
||
|
||
QFile jsonFile(srcDir+"/pro.json");
|
||
if(! jsonFile.open(QIODevice::ReadOnly)) {
|
||
emit onErr("Can't open "+srcDir+"/pro.json");
|
||
return;
|
||
}
|
||
auto data = jsonFile.readAll();
|
||
jsonFile.close();
|
||
QString error;
|
||
auto proJson = JFrom(data, &error).toObj();
|
||
if(! error.isEmpty()) {
|
||
emit onErr("Parse "+srcDir+"/pro.json Error: "+error);
|
||
return;
|
||
}
|
||
|
||
//扫描节目, 返回多个节目数组
|
||
QStringList pageNames = QDir(srcDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||
//查询 order 属性, 将最上层的放在转换后 layers 的最前面
|
||
//一个 page.json 对应节目任务中的一个 items 里的 program
|
||
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 = JFrom(data, &error).toObj();
|
||
if(error.isEmpty()) pageJsons.emplace_back(pageJson);
|
||
}
|
||
}
|
||
std::sort(pageJsons.begin(), pageJsons.end(), [](const JObj &a, const JObj &b) {
|
||
return a["order"].toInt() < b["order"].toInt();
|
||
});
|
||
JArray items;
|
||
for(auto &pageJson : pageJsons) {
|
||
srcPageDir = srcDir + "/" + pageJson["name"].toString();
|
||
items.append(cvtPage(pageJson));
|
||
}
|
||
JObj json;
|
||
json["_type"] = "PlayXixunTask";
|
||
json["task"] = JObj{
|
||
{"name", prog_name},
|
||
{"width", proJson["resolution"]["w"]},
|
||
{"height", proJson["resolution"]["h"]},
|
||
{"partLengths", proJson["splitWidths"]},
|
||
{"isVertical", proJson["isVer"]},
|
||
{"items", items}
|
||
};
|
||
QFile program(dstDir + "/program");
|
||
if(program.open(QFile::WriteOnly)) {
|
||
program.write(JToBytes(json, "\t"));
|
||
program.close();
|
||
}
|
||
|
||
//如果是usb更新则生成压缩包,网络发送则不需要
|
||
if(! zip_file.isEmpty()) {
|
||
#ifdef Q_OS_WIN
|
||
QStringList args{"a", zip_file, dstDir+"/*"};
|
||
if(! password.isEmpty()) args << "-p"+password;
|
||
QProcess::execute("7z.exe", args);
|
||
#else
|
||
QStringList args{"-r", zip_file};
|
||
if(! password.isEmpty()) args << "-P" << password;
|
||
args += QDir(dstDir).entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
|
||
QProcess process;
|
||
process.setWorkingDirectory(dstDir);
|
||
process.start("zip", args);
|
||
process.waitForFinished();
|
||
#endif
|
||
}
|
||
}
|
||
|
||
//此处需要把幻灯片中的元素按层顺序排序,再放入layers中,每个元素对一个layer。ewindow中的多个顺序元素为一个层上的时间轴上的素材
|
||
JObj GenTmpThread::cvtPage(const JObj &pageJson) {
|
||
auto audios = pageJson("audios").toArray();
|
||
auto sourceRepeat = pageJson["loop"].toBool();
|
||
JArray sources;
|
||
int start = 0;
|
||
for(auto &audio : audios) {
|
||
auto dur = audio["dur"].toInt();
|
||
if(dur==0) continue;
|
||
auto name = audio["name"].toString();
|
||
if(name.isEmpty()) continue;
|
||
auto file = audio["dir"].toString()+"/"+name;
|
||
QFileInfo srcInfo(file);
|
||
if(! srcInfo.isFile()) continue;
|
||
auto id = Tools::fileMd5(file);
|
||
if(id.isEmpty()) continue;
|
||
QFile::copy(file, dstDir+"/"+id);
|
||
JObj source;
|
||
source.insert("_type", "Audio");
|
||
source["id"] = id;
|
||
source["md5"] = id;
|
||
source["timeSpan"] = dur;
|
||
source["playTime"] = start;
|
||
source["vol"] = audio["vol"].toInt();
|
||
source["left"] = -1;
|
||
source["top"] = -1;
|
||
source["width"] = 1;
|
||
source["height"] = 1;
|
||
sources.append(source);
|
||
start += dur;
|
||
}
|
||
JArray layers;
|
||
if(! sources.empty()) layers.append(JObj{{"repeat", sourceRepeat}, {"sources", sources}});
|
||
|
||
auto elements = pageJson["elements"].toArray();
|
||
for(const auto &ele : elements) {
|
||
auto type = ele["elementType"].toString();
|
||
auto geometry = ele["geometry"];
|
||
sources = type=="Window" ? genSources(QString(), ele["elements"].toArray(), geometry) : genSources(type, JArray{ele}, geometry);
|
||
if(! sources.empty()) {
|
||
JObj layer{{"repeat", sourceRepeat}, {"sources", sources}};
|
||
auto border = ele["border"].toString();
|
||
if(! border.isEmpty()) {
|
||
auto bdSrc = "borders/"+border;
|
||
auto id = Tools::fileMd5(bdSrc);
|
||
QFile::copy(bdSrc, dstDir+"/"+id);
|
||
auto borderSize = ele["borderSize"];
|
||
if(borderSize.isNull()){
|
||
QImage img(bdSrc);
|
||
borderSize = JArray{img.width(), img.height()};
|
||
}
|
||
layer["border"] = JObj{
|
||
{"img", id},
|
||
{"eff", ele["borderEff"]},
|
||
{"speed", ele["borderSpeed"]},
|
||
{"img_size", borderSize},
|
||
{"geometry", JArray{geometry["x"], geometry["y"], geometry["w"], geometry["h"]}}
|
||
};
|
||
}
|
||
layers.append(layer);
|
||
}
|
||
}
|
||
|
||
JArray schedules, plans = pageJson["plans"].toArray();
|
||
auto validDate = pageJson["validDate"];
|
||
bool isValid = validDate["isValid"].toBool();
|
||
if(plans.empty()) {
|
||
if(isValid) {
|
||
JObj schedule;
|
||
schedule["dateType"] = "Range";
|
||
schedule["startDate"] = validDate["start"];
|
||
schedule["endDate"] = validDate["end"];
|
||
schedule["timeType"] = "All";
|
||
schedule["filterType"] = "None";
|
||
schedule["weekFilter"] = JArray();
|
||
schedules.append(schedule);
|
||
}
|
||
} else {
|
||
for(auto &plan : plans) {
|
||
JObj schedule;
|
||
if(isValid) {
|
||
schedule["dateType"] = "Range";
|
||
schedule["startDate"] = validDate["start"];
|
||
schedule["endDate"] = validDate["end"];
|
||
} else schedule["dateType"] = "All";
|
||
schedule["timeType"] = "Range";
|
||
schedule["startTime"] = plan["start"];
|
||
schedule["endTime"] = plan["end"];
|
||
auto weekly = plan["weekly"];
|
||
schedule["weekFilter"] = weekly;
|
||
schedule["filterType"] = weekly.toArray().empty() ? "None" : "Week";
|
||
schedules.append(schedule);
|
||
}
|
||
}
|
||
return JObj{
|
||
{"repeatTimes", pageJson["repeat"]},
|
||
{"schedules", schedules},
|
||
{"_program", JObj{
|
||
{"name", pageJson["name"].toString()},
|
||
{"layers", layers}
|
||
}}
|
||
};
|
||
}
|
||
|
||
JArray GenTmpThread::genSources(QString type, const JArray &eles, const JValue &geometry) {
|
||
JArray sources;
|
||
auto needType = type.isEmpty();
|
||
for(const auto &ele : eles) {
|
||
JObj source;
|
||
if(needType) type = ele["elementType"].toString();
|
||
if(type=="Text") source = genText(ele, sources);
|
||
else if(type=="Image"||type=="Photo") source = genImage(ele);
|
||
else if(type=="Video"||type=="Movie") source = EVideo::genProg(ele, dstDir, mProgItem);
|
||
else if(type=="Gif") source = convertGif(ele);
|
||
else if(type=="DClock") source = convertDClock(ele);
|
||
else if(type=="AClock") source = convertAClock(ele);
|
||
else if(type=="Temp") source = EEnviron::genProg(ele, dstDir, srcPageDir);
|
||
else if(type=="Web") source = convertWeb(ele);
|
||
else if(type=="Timer") source = convertTimer(ele);
|
||
if(! source.empty()) {
|
||
if(source["timeSpan"].isNull()) source["timeSpan"] = ele["duration"];
|
||
source["entryEffect"] = ele["entryEffect"];
|
||
source["exitEffect"] = ele["exitEffect"];
|
||
if(source["entryEffect"].toStr().isEmpty()) source["entryEffect"] = "None"; //兼容旧播放器
|
||
if(source["exitEffect"].toStr().isEmpty()) source["exitEffect"] = "None"; //兼容旧播放器
|
||
source["entryEffectTimeSpan"] = ele["entryDur"];
|
||
source["exitEffectTimeSpan"] = ele["exitDur"];
|
||
sources.append(source);
|
||
}
|
||
}
|
||
auto startTime = needType ? 0 : eles[0]["startTime"].toInt();
|
||
for(auto &ss : sources) {
|
||
auto source = ss.toObj();
|
||
source["left"] = geometry["x"];
|
||
source["top"] = geometry["y"];
|
||
source["width"] = geometry["w"];
|
||
source["height"] = geometry["h"];
|
||
source["playTime"] = startTime;
|
||
startTime += source["timeSpan"].toInt();
|
||
}
|
||
return sources;
|
||
}
|
||
|
||
JObj GenTmpThread::genText(const JValue &ele, JArray &sources) {
|
||
auto widget = ele["widget"];
|
||
if(widget.isNull()) widget = ele;
|
||
auto play = ele["play"];
|
||
QString playMode, direction;
|
||
int speed;
|
||
if(play.isNull()) {
|
||
playMode = ele["playMode"].toString();
|
||
direction = ele["direction"].toString();
|
||
speed = ele["speed"].toInt();
|
||
} else {
|
||
QString playModes[]{"Flip", "Scroll", "Static"};
|
||
playMode = playModes[play["style"].toInt()];
|
||
auto rolling = play["rolling"];
|
||
QString ds[]{"left", "top", "right", "bottom"};
|
||
direction = ds[rolling["rollingStyle"].toInt()];
|
||
speed = 1000/rolling["rollingSpeed"].toInt(33);
|
||
}
|
||
auto filenames = widget["files"];
|
||
auto filePrefix = srcPageDir+"/"+widget["idDir"].toString()+"/";
|
||
|
||
auto isScroll = playMode=="Scroll";
|
||
if(isScroll) {
|
||
JObj source;
|
||
source["_type"] = "MultiPng";
|
||
source["playMode"] = playMode;
|
||
JArray arrayPics;
|
||
for(auto &filename : filenames) {
|
||
auto file = filePrefix + filename.toString();
|
||
QFile qFile(file);
|
||
if(! qFile.exists()) continue;
|
||
auto id = Tools::fileMd5(file);
|
||
qFile.copy(dstDir+"/"+id);
|
||
|
||
JObj arrayPic;
|
||
arrayPic["id"] = id;
|
||
if(direction=="left") arrayPic["effect"] = "right to left";
|
||
else if(direction=="top") arrayPic["effect"] = "bottom to top";
|
||
else if(direction=="right") arrayPic["effect"] = "left to right";
|
||
else if(direction=="bottom") arrayPic["effect"] = "top to bottom";
|
||
arrayPic["scrollSpeed"] = speed;
|
||
arrayPic["effectSpeed"] = 1000 / speed;
|
||
arrayPic["picDuration"] = 0;
|
||
arrayPics.append(arrayPic);
|
||
}
|
||
source["arrayPics"] = arrayPics;
|
||
return source;
|
||
} else {
|
||
auto duration = ele["duration"].toInt();
|
||
for(auto &filename : filenames) {
|
||
auto file = filePrefix + filename.toString();
|
||
QFile qFile(file);
|
||
if(! qFile.exists()) continue;
|
||
auto id = Tools::fileMd5(file);
|
||
qFile.copy(dstDir+"/"+id);
|
||
|
||
JObj source;
|
||
source["_type"] = "Image";
|
||
source["id"] = id;
|
||
source["md5"] = id;
|
||
source["timeSpan"] = duration;
|
||
source["entryEffect"] = ele["entryEffect"];
|
||
source["exitEffect"] = ele["exitEffect"];
|
||
if(source["entryEffect"].toStr().isEmpty()) source["entryEffect"] = "None"; //兼容旧播放器
|
||
if(source["exitEffect"].toStr().isEmpty()) source["exitEffect"] = "None"; //兼容旧播放器
|
||
source["entryEffectTimeSpan"] = ele["entryDur"];
|
||
source["exitEffectTimeSpan"] = ele["exitDur"];
|
||
sources.append(source);
|
||
}
|
||
return JObj();
|
||
}
|
||
}
|
||
//转换图片
|
||
JObj GenTmpThread::genImage(const JValue &ele) {
|
||
auto widget = ele["widget"];
|
||
auto name = widget.isNull() ? ele["name"].toString() : widget["file"].toString();
|
||
auto srcFile = (widget.isNull() ? ele["dir"] : widget["path"]).toString() + "/" + name;
|
||
QFileInfo srcInfo(srcFile);
|
||
JObj source;
|
||
if(! srcInfo.isFile()) return source;
|
||
QImage img(srcFile);
|
||
auto geometry = ele["geometry"];
|
||
auto width = geometry["w"].toInt();
|
||
auto height = geometry["h"].toInt();
|
||
/*if(mProgItem->maxLen) {
|
||
auto scaled = img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||
QImage square(gProgItem->isVer ? gProgItem->mWidth*gProgItem->partLens.size() : gProgItem->maxLen, gProgItem->isVer ? gProgItem->maxLen : gProgItem->mHeight*gProgItem->partLens.size(), QImage::Format_ARGB32);
|
||
square.fill(0);
|
||
QPainter painter(&square);
|
||
QPointF pos(x, y);
|
||
auto end = (int)gProgItem->partLens.size();
|
||
if(gProgItem->isVer) {
|
||
painter.drawImage(pos, scaled, QRectF(0, 0, width, gProgItem->partLens[0]-pos.y()));
|
||
for(int i=1; i<end; i++) {
|
||
pos.ry() -= gProgItem->partLens[i-1];
|
||
pos.rx() += gProgItem->mWidth;
|
||
painter.drawImage(pos, scaled, QRectF(0, 0, width, gProgItem->partLens[i]-pos.y()));
|
||
}
|
||
} else {
|
||
painter.drawImage(pos, scaled, QRectF(0, 0, gProgItem->partLens[0]-pos.x(), height));
|
||
for(int i=1; i<end; i++) {
|
||
pos.rx() -= gProgItem->partLens[i-1];
|
||
pos.ry() += gProgItem->mHeight;
|
||
painter.drawImage(pos, scaled, QRectF(0, 0, gProgItem->partLens[i]-pos.x(), height));
|
||
}
|
||
|
||
}
|
||
QBuffer buf;
|
||
square.save(&buf, "PNG");
|
||
QCryptographicHash cryptoHash(QCryptographicHash::Md5);
|
||
cryptoHash.addData(buf.data());
|
||
auto md5 = QString::fromLatin1(cryptoHash.result().toHex());
|
||
QFile file(dstDir+"/"+md5);
|
||
if(! file.open(QFile::WriteOnly)) return source;
|
||
file.write(buf.data());
|
||
file.close();
|
||
source["id"] = md5;
|
||
source["md5"] = md5;
|
||
} else */if(img.width() > width*2 && img.height() > height*2) {
|
||
QBuffer buf;
|
||
img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).save(&buf, "PNG");
|
||
QCryptographicHash cryptoHash(QCryptographicHash::Md5);
|
||
cryptoHash.addData(buf.data());
|
||
auto md5 = QString::fromLatin1(cryptoHash.result().toHex());
|
||
QFile file(dstDir+"/"+md5);
|
||
if(! file.open(QFile::WriteOnly)) return source;
|
||
file.write(buf.data());
|
||
file.close();
|
||
source["id"] = md5;
|
||
source["md5"] = md5;
|
||
} else {
|
||
auto md5 = Tools::fileMd5(srcFile);
|
||
if(md5.isEmpty()) return source;
|
||
QFile::copy(srcFile, dstDir+"/"+md5);
|
||
source["id"] = md5;
|
||
source["md5"] = md5;
|
||
}
|
||
source["_type"] = "Image";
|
||
auto play = ele["play"];
|
||
source["timeSpan"] = play.isNull() ? ele["duration"] : play["playDuration"];
|
||
return source;
|
||
}
|
||
//转换图片
|
||
JObj GenTmpThread::convertGif(const JValue &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 JObj();
|
||
QString id = Tools::fileMd5(srcFile);
|
||
if(id.isEmpty()) return JObj();
|
||
QFile::copy(srcFile, dstDir+"/"+id);
|
||
JObj oRes;
|
||
oRes["_type"] = "Image";
|
||
oRes["id"] = id;
|
||
oRes["md5"] = id;
|
||
oRes["fileExt"] = srcInfo.suffix().toLower();
|
||
auto play = json["play"];
|
||
oRes["timeSpan"] = (play.isNull() ? json["duration"] : play["playDuration"]).toInt() * play["playTimes"].toInt(1);
|
||
return oRes;
|
||
}
|
||
JObj GenTmpThread::convertDClock(const JValue &json){
|
||
JObj oRes;
|
||
oRes["_type"] = "DigitalClockNew";
|
||
oRes["name"] = "DigitalClockNew";
|
||
auto widget = json["widget"];
|
||
oRes["timeZone"] = widget["timeZone"];
|
||
oRes["timezone"] = 8;//兼容旧播放器
|
||
oRes["year"] = widget["year"];
|
||
oRes["month"] = widget["month"];
|
||
oRes["day"] = widget["day"];
|
||
oRes["hour"] = widget["hour"];
|
||
oRes["min"] = widget["min"];
|
||
oRes["sec"] = widget["sec"];
|
||
oRes["weekly"] = widget["weekly"];
|
||
oRes["fullYear"] = widget["fullYear"];
|
||
oRes["hour12"] = widget["12Hour"];
|
||
oRes["AmPm"] = widget["AmPm"];
|
||
oRes["dateStyle"] = widget["dateStyle"];
|
||
oRes["timeStyle"] = widget["timeStyle"];
|
||
oRes["multiline"] = widget["multiline"];
|
||
|
||
auto fontVal = widget["font"];
|
||
auto textColor = Tools::int2Color(fontVal["color"].toInt());
|
||
QFont font(fontVal["family"].toString());
|
||
font.setPixelSize(fontVal["size"].toInt());
|
||
font.setBold(fontVal["bold"].toBool());
|
||
font.setItalic(fontVal["italics"].toBool());
|
||
font.setUnderline(fontVal["underline"].toBool());
|
||
|
||
font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias);
|
||
QFontMetrics metric(font);
|
||
oRes["spaceWidth"] = metric.horizontalAdvance(" ");
|
||
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, tr("MON"), "MON");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("TUE"), "TUE");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("WED"), "WED");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("THU"), "THU");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("FRI"), "FRI");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("SAT"), "SAT");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("SUN"), "SUN");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("AM"), "AM");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, tr("PM"), "PM");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, "年", "YEAR");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, "月", "MONTH");
|
||
Tools::saveImg2(dstDir, metric, font, color, imgs, "日", "DAY");
|
||
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["arrayPics"] = imgs;
|
||
return oRes;
|
||
}
|
||
JObj GenTmpThread::convertAClock(const JValue &json) {
|
||
auto widget = json["widget"];
|
||
if(widget.isNull()) widget = json;
|
||
QString srcFile = srcPageDir + "/" + widget["selfCreateDialName"].toString();
|
||
QFile srcQFile(srcFile);
|
||
if(! srcQFile.exists()) return JObj();
|
||
QString id = Tools::fileMd5(srcFile);
|
||
srcQFile.copy(dstDir+"/"+id);
|
||
JObj oRes;
|
||
oRes["_type"] = "AnalogClock";
|
||
oRes["id"] = id;
|
||
oRes["md5"] = id;
|
||
oRes["shade"] = 0;//表盘形状
|
||
oRes["opacity"] = 1;//透明度
|
||
oRes["showBg"] = false;//是否显示背景色
|
||
oRes["bgColor"] = 0;
|
||
oRes["showHourScale"] = false;//是否显示时针
|
||
auto color = widget["hourMarkColor"];
|
||
oRes["scaleHourColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
|
||
color = widget["minMarkColor"];
|
||
oRes["scaleMinColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
|
||
color = widget["hourHandColor"];
|
||
oRes["pinHourColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
|
||
color = widget["minHandColor"];
|
||
oRes["pinMinColor"] = color.isStr() ? color : Tools::int2Color(color.toInt()).name();
|
||
color = widget["secHandColor"];
|
||
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();
|
||
oRes["pinHourWidth"] = widget["hhWidth"].toInt();
|
||
oRes["pinMinWidth"] = widget["mhWidth"].toInt();
|
||
oRes["pinSecWidth"] = widget["shWidth"].toInt();
|
||
oRes["showMinScale"] = false;
|
||
oRes["scaleStyle"] = 0;
|
||
oRes["showScaleNum"] = false;
|
||
oRes["pinStyle"] = 1;
|
||
oRes["showSecond"] = widget["showSecHand"];
|
||
oRes["timeZone"] = widget["timeZone"];
|
||
return oRes;
|
||
}
|
||
|
||
JObj GenTmpThread::convertWeb(const JValue &res) {
|
||
JObj dst;
|
||
dst["_type"] = "WebURL";
|
||
dst["name"] = "WebURL";
|
||
dst["url"] = res["url"];
|
||
return dst;
|
||
}
|
||
JObj GenTmpThread::convertTimer(const JValue &json) {
|
||
JObj oRes;
|
||
oRes["_type"] = "Timer";
|
||
oRes["name"] = "Timer";
|
||
oRes["targetTime"] = json["targetTime"];
|
||
oRes["isDown"] = json["isDown"];
|
||
oRes["hasDay"] = json["hasDay"];
|
||
oRes["hasHour"] = json["hasHour"];
|
||
oRes["hasMin"] = json["hasMin"];
|
||
oRes["hasSec"] = json["hasSec"];
|
||
auto isMultiline = json["isMultiline"].toBool();
|
||
oRes["isMultiline"] = isMultiline;
|
||
auto text = json["text"].toString();
|
||
oRes["text"] = text;
|
||
QFont font(json["font"].toString());
|
||
font.setPixelSize(json["fontSize"].toInt());
|
||
font.setBold(json["fontBold"].toBool());
|
||
font.setItalic(json["fontItalic"].toBool());
|
||
font.setUnderline(json["fontUnderline"].toBool());
|
||
oRes["font"] = font.family();
|
||
oRes["fontSize"] = font.pixelSize();
|
||
oRes["fontBold"] = font.bold();
|
||
oRes["fontItalic"] = font.italic();
|
||
oRes["fontUnderline"] = font.underline();
|
||
auto textColor = json["textColor"].toString();
|
||
oRes["textColor"] = textColor;
|
||
oRes["backColor"] = json["backColor"];
|
||
font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias);
|
||
QFontMetrics metric(font);
|
||
oRes["spaceWidth"] = metric.horizontalAdvance(" ");
|
||
QColor color(textColor);
|
||
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");
|
||
Tools::saveImg(dstDir, metric, font, color, imgs, tr("min"), "min");
|
||
Tools::saveImg(dstDir, metric, font, color, imgs, tr("sec"), "sec");
|
||
if(! text.isEmpty()) {
|
||
QSize size;
|
||
if(isMultiline) {
|
||
auto innerW = json["innerW"].toInt();
|
||
auto innerH = json["innerH"].toInt();
|
||
auto rect = metric.boundingRect(0, 0, innerW, innerH, Qt::AlignCenter | Qt::TextWordWrap, text);
|
||
size = {qMin(rect.width(), innerW), qMin(rect.height(), innerH)};
|
||
} else size = {metric.horizontalAdvance(text), metric.lineSpacing()};
|
||
QImage img(size, QImage::Format_ARGB32);
|
||
img.fill(Qt::transparent);
|
||
{
|
||
QPainter painter(&img);
|
||
painter.setFont(font);
|
||
painter.setPen(color);
|
||
painter.drawText(QRectF(0, 0, img.width(), img.height()), text, QTextOption(Qt::AlignCenter));
|
||
}
|
||
QByteArray data;
|
||
QBuffer buffer(&data);
|
||
buffer.open(QIODevice::WriteOnly);
|
||
if(img.save(&buffer, "PNG")) {
|
||
QCryptographicHash cryptoHash(QCryptographicHash::Md5);
|
||
cryptoHash.addData(data);
|
||
auto md5 = QString::fromLatin1(cryptoHash.result().toHex());
|
||
QFile file(dstDir+"/"+md5);
|
||
if(file.open(QFile::WriteOnly)) {
|
||
file.write(data);
|
||
file.close();
|
||
imgs.insert("text", md5);
|
||
} else emit onErr("convertTimer file.open false");
|
||
} else emit onErr("convertTimer img.save false");
|
||
}
|
||
oRes["imgs"] = imgs;
|
||
return oRes;
|
||
}
|